Edit File by line
/home/barbar84/public_h.../wp-conte.../plugins/sujqvwi/ShExBy/shex_roo.../lib64/python3....
File: modulefinder.py
"""Find modules used by a script, using introspection."""
[0] Fix | Delete
[1] Fix | Delete
import dis
[2] Fix | Delete
import importlib._bootstrap_external
[3] Fix | Delete
import importlib.machinery
[4] Fix | Delete
import marshal
[5] Fix | Delete
import os
[6] Fix | Delete
import sys
[7] Fix | Delete
import types
[8] Fix | Delete
import struct
[9] Fix | Delete
import warnings
[10] Fix | Delete
with warnings.catch_warnings():
[11] Fix | Delete
warnings.simplefilter('ignore', DeprecationWarning)
[12] Fix | Delete
import imp
[13] Fix | Delete
[14] Fix | Delete
LOAD_CONST = dis.opmap['LOAD_CONST']
[15] Fix | Delete
IMPORT_NAME = dis.opmap['IMPORT_NAME']
[16] Fix | Delete
STORE_NAME = dis.opmap['STORE_NAME']
[17] Fix | Delete
STORE_GLOBAL = dis.opmap['STORE_GLOBAL']
[18] Fix | Delete
STORE_OPS = STORE_NAME, STORE_GLOBAL
[19] Fix | Delete
EXTENDED_ARG = dis.EXTENDED_ARG
[20] Fix | Delete
[21] Fix | Delete
# Modulefinder does a good job at simulating Python's, but it can not
[22] Fix | Delete
# handle __path__ modifications packages make at runtime. Therefore there
[23] Fix | Delete
# is a mechanism whereby you can register extra paths in this map for a
[24] Fix | Delete
# package, and it will be honored.
[25] Fix | Delete
[26] Fix | Delete
# Note this is a mapping is lists of paths.
[27] Fix | Delete
packagePathMap = {}
[28] Fix | Delete
[29] Fix | Delete
# A Public interface
[30] Fix | Delete
def AddPackagePath(packagename, path):
[31] Fix | Delete
packagePathMap.setdefault(packagename, []).append(path)
[32] Fix | Delete
[33] Fix | Delete
replacePackageMap = {}
[34] Fix | Delete
[35] Fix | Delete
# This ReplacePackage mechanism allows modulefinder to work around
[36] Fix | Delete
# situations in which a package injects itself under the name
[37] Fix | Delete
# of another package into sys.modules at runtime by calling
[38] Fix | Delete
# ReplacePackage("real_package_name", "faked_package_name")
[39] Fix | Delete
# before running ModuleFinder.
[40] Fix | Delete
[41] Fix | Delete
def ReplacePackage(oldname, newname):
[42] Fix | Delete
replacePackageMap[oldname] = newname
[43] Fix | Delete
[44] Fix | Delete
[45] Fix | Delete
class Module:
[46] Fix | Delete
[47] Fix | Delete
def __init__(self, name, file=None, path=None):
[48] Fix | Delete
self.__name__ = name
[49] Fix | Delete
self.__file__ = file
[50] Fix | Delete
self.__path__ = path
[51] Fix | Delete
self.__code__ = None
[52] Fix | Delete
# The set of global names that are assigned to in the module.
[53] Fix | Delete
# This includes those names imported through starimports of
[54] Fix | Delete
# Python modules.
[55] Fix | Delete
self.globalnames = {}
[56] Fix | Delete
# The set of starimports this module did that could not be
[57] Fix | Delete
# resolved, ie. a starimport from a non-Python module.
[58] Fix | Delete
self.starimports = {}
[59] Fix | Delete
[60] Fix | Delete
def __repr__(self):
[61] Fix | Delete
s = "Module(%r" % (self.__name__,)
[62] Fix | Delete
if self.__file__ is not None:
[63] Fix | Delete
s = s + ", %r" % (self.__file__,)
[64] Fix | Delete
if self.__path__ is not None:
[65] Fix | Delete
s = s + ", %r" % (self.__path__,)
[66] Fix | Delete
s = s + ")"
[67] Fix | Delete
return s
[68] Fix | Delete
[69] Fix | Delete
class ModuleFinder:
[70] Fix | Delete
[71] Fix | Delete
def __init__(self, path=None, debug=0, excludes=[], replace_paths=[]):
[72] Fix | Delete
if path is None:
[73] Fix | Delete
path = sys.path
[74] Fix | Delete
self.path = path
[75] Fix | Delete
self.modules = {}
[76] Fix | Delete
self.badmodules = {}
[77] Fix | Delete
self.debug = debug
[78] Fix | Delete
self.indent = 0
[79] Fix | Delete
self.excludes = excludes
[80] Fix | Delete
self.replace_paths = replace_paths
[81] Fix | Delete
self.processed_paths = [] # Used in debugging only
[82] Fix | Delete
[83] Fix | Delete
def msg(self, level, str, *args):
[84] Fix | Delete
if level <= self.debug:
[85] Fix | Delete
for i in range(self.indent):
[86] Fix | Delete
print(" ", end=' ')
[87] Fix | Delete
print(str, end=' ')
[88] Fix | Delete
for arg in args:
[89] Fix | Delete
print(repr(arg), end=' ')
[90] Fix | Delete
print()
[91] Fix | Delete
[92] Fix | Delete
def msgin(self, *args):
[93] Fix | Delete
level = args[0]
[94] Fix | Delete
if level <= self.debug:
[95] Fix | Delete
self.indent = self.indent + 1
[96] Fix | Delete
self.msg(*args)
[97] Fix | Delete
[98] Fix | Delete
def msgout(self, *args):
[99] Fix | Delete
level = args[0]
[100] Fix | Delete
if level <= self.debug:
[101] Fix | Delete
self.indent = self.indent - 1
[102] Fix | Delete
self.msg(*args)
[103] Fix | Delete
[104] Fix | Delete
def run_script(self, pathname):
[105] Fix | Delete
self.msg(2, "run_script", pathname)
[106] Fix | Delete
with open(pathname) as fp:
[107] Fix | Delete
stuff = ("", "r", imp.PY_SOURCE)
[108] Fix | Delete
self.load_module('__main__', fp, pathname, stuff)
[109] Fix | Delete
[110] Fix | Delete
def load_file(self, pathname):
[111] Fix | Delete
dir, name = os.path.split(pathname)
[112] Fix | Delete
name, ext = os.path.splitext(name)
[113] Fix | Delete
with open(pathname) as fp:
[114] Fix | Delete
stuff = (ext, "r", imp.PY_SOURCE)
[115] Fix | Delete
self.load_module(name, fp, pathname, stuff)
[116] Fix | Delete
[117] Fix | Delete
def import_hook(self, name, caller=None, fromlist=None, level=-1):
[118] Fix | Delete
self.msg(3, "import_hook", name, caller, fromlist, level)
[119] Fix | Delete
parent = self.determine_parent(caller, level=level)
[120] Fix | Delete
q, tail = self.find_head_package(parent, name)
[121] Fix | Delete
m = self.load_tail(q, tail)
[122] Fix | Delete
if not fromlist:
[123] Fix | Delete
return q
[124] Fix | Delete
if m.__path__:
[125] Fix | Delete
self.ensure_fromlist(m, fromlist)
[126] Fix | Delete
return None
[127] Fix | Delete
[128] Fix | Delete
def determine_parent(self, caller, level=-1):
[129] Fix | Delete
self.msgin(4, "determine_parent", caller, level)
[130] Fix | Delete
if not caller or level == 0:
[131] Fix | Delete
self.msgout(4, "determine_parent -> None")
[132] Fix | Delete
return None
[133] Fix | Delete
pname = caller.__name__
[134] Fix | Delete
if level >= 1: # relative import
[135] Fix | Delete
if caller.__path__:
[136] Fix | Delete
level -= 1
[137] Fix | Delete
if level == 0:
[138] Fix | Delete
parent = self.modules[pname]
[139] Fix | Delete
assert parent is caller
[140] Fix | Delete
self.msgout(4, "determine_parent ->", parent)
[141] Fix | Delete
return parent
[142] Fix | Delete
if pname.count(".") < level:
[143] Fix | Delete
raise ImportError("relative importpath too deep")
[144] Fix | Delete
pname = ".".join(pname.split(".")[:-level])
[145] Fix | Delete
parent = self.modules[pname]
[146] Fix | Delete
self.msgout(4, "determine_parent ->", parent)
[147] Fix | Delete
return parent
[148] Fix | Delete
if caller.__path__:
[149] Fix | Delete
parent = self.modules[pname]
[150] Fix | Delete
assert caller is parent
[151] Fix | Delete
self.msgout(4, "determine_parent ->", parent)
[152] Fix | Delete
return parent
[153] Fix | Delete
if '.' in pname:
[154] Fix | Delete
i = pname.rfind('.')
[155] Fix | Delete
pname = pname[:i]
[156] Fix | Delete
parent = self.modules[pname]
[157] Fix | Delete
assert parent.__name__ == pname
[158] Fix | Delete
self.msgout(4, "determine_parent ->", parent)
[159] Fix | Delete
return parent
[160] Fix | Delete
self.msgout(4, "determine_parent -> None")
[161] Fix | Delete
return None
[162] Fix | Delete
[163] Fix | Delete
def find_head_package(self, parent, name):
[164] Fix | Delete
self.msgin(4, "find_head_package", parent, name)
[165] Fix | Delete
if '.' in name:
[166] Fix | Delete
i = name.find('.')
[167] Fix | Delete
head = name[:i]
[168] Fix | Delete
tail = name[i+1:]
[169] Fix | Delete
else:
[170] Fix | Delete
head = name
[171] Fix | Delete
tail = ""
[172] Fix | Delete
if parent:
[173] Fix | Delete
qname = "%s.%s" % (parent.__name__, head)
[174] Fix | Delete
else:
[175] Fix | Delete
qname = head
[176] Fix | Delete
q = self.import_module(head, qname, parent)
[177] Fix | Delete
if q:
[178] Fix | Delete
self.msgout(4, "find_head_package ->", (q, tail))
[179] Fix | Delete
return q, tail
[180] Fix | Delete
if parent:
[181] Fix | Delete
qname = head
[182] Fix | Delete
parent = None
[183] Fix | Delete
q = self.import_module(head, qname, parent)
[184] Fix | Delete
if q:
[185] Fix | Delete
self.msgout(4, "find_head_package ->", (q, tail))
[186] Fix | Delete
return q, tail
[187] Fix | Delete
self.msgout(4, "raise ImportError: No module named", qname)
[188] Fix | Delete
raise ImportError("No module named " + qname)
[189] Fix | Delete
[190] Fix | Delete
def load_tail(self, q, tail):
[191] Fix | Delete
self.msgin(4, "load_tail", q, tail)
[192] Fix | Delete
m = q
[193] Fix | Delete
while tail:
[194] Fix | Delete
i = tail.find('.')
[195] Fix | Delete
if i < 0: i = len(tail)
[196] Fix | Delete
head, tail = tail[:i], tail[i+1:]
[197] Fix | Delete
mname = "%s.%s" % (m.__name__, head)
[198] Fix | Delete
m = self.import_module(head, mname, m)
[199] Fix | Delete
if not m:
[200] Fix | Delete
self.msgout(4, "raise ImportError: No module named", mname)
[201] Fix | Delete
raise ImportError("No module named " + mname)
[202] Fix | Delete
self.msgout(4, "load_tail ->", m)
[203] Fix | Delete
return m
[204] Fix | Delete
[205] Fix | Delete
def ensure_fromlist(self, m, fromlist, recursive=0):
[206] Fix | Delete
self.msg(4, "ensure_fromlist", m, fromlist, recursive)
[207] Fix | Delete
for sub in fromlist:
[208] Fix | Delete
if sub == "*":
[209] Fix | Delete
if not recursive:
[210] Fix | Delete
all = self.find_all_submodules(m)
[211] Fix | Delete
if all:
[212] Fix | Delete
self.ensure_fromlist(m, all, 1)
[213] Fix | Delete
elif not hasattr(m, sub):
[214] Fix | Delete
subname = "%s.%s" % (m.__name__, sub)
[215] Fix | Delete
submod = self.import_module(sub, subname, m)
[216] Fix | Delete
if not submod:
[217] Fix | Delete
raise ImportError("No module named " + subname)
[218] Fix | Delete
[219] Fix | Delete
def find_all_submodules(self, m):
[220] Fix | Delete
if not m.__path__:
[221] Fix | Delete
return
[222] Fix | Delete
modules = {}
[223] Fix | Delete
# 'suffixes' used to be a list hardcoded to [".py", ".pyc"].
[224] Fix | Delete
# But we must also collect Python extension modules - although
[225] Fix | Delete
# we cannot separate normal dlls from Python extensions.
[226] Fix | Delete
suffixes = []
[227] Fix | Delete
suffixes += importlib.machinery.EXTENSION_SUFFIXES[:]
[228] Fix | Delete
suffixes += importlib.machinery.SOURCE_SUFFIXES[:]
[229] Fix | Delete
suffixes += importlib.machinery.BYTECODE_SUFFIXES[:]
[230] Fix | Delete
for dir in m.__path__:
[231] Fix | Delete
try:
[232] Fix | Delete
names = os.listdir(dir)
[233] Fix | Delete
except OSError:
[234] Fix | Delete
self.msg(2, "can't list directory", dir)
[235] Fix | Delete
continue
[236] Fix | Delete
for name in names:
[237] Fix | Delete
mod = None
[238] Fix | Delete
for suff in suffixes:
[239] Fix | Delete
n = len(suff)
[240] Fix | Delete
if name[-n:] == suff:
[241] Fix | Delete
mod = name[:-n]
[242] Fix | Delete
break
[243] Fix | Delete
if mod and mod != "__init__":
[244] Fix | Delete
modules[mod] = mod
[245] Fix | Delete
return modules.keys()
[246] Fix | Delete
[247] Fix | Delete
def import_module(self, partname, fqname, parent):
[248] Fix | Delete
self.msgin(3, "import_module", partname, fqname, parent)
[249] Fix | Delete
try:
[250] Fix | Delete
m = self.modules[fqname]
[251] Fix | Delete
except KeyError:
[252] Fix | Delete
pass
[253] Fix | Delete
else:
[254] Fix | Delete
self.msgout(3, "import_module ->", m)
[255] Fix | Delete
return m
[256] Fix | Delete
if fqname in self.badmodules:
[257] Fix | Delete
self.msgout(3, "import_module -> None")
[258] Fix | Delete
return None
[259] Fix | Delete
if parent and parent.__path__ is None:
[260] Fix | Delete
self.msgout(3, "import_module -> None")
[261] Fix | Delete
return None
[262] Fix | Delete
try:
[263] Fix | Delete
fp, pathname, stuff = self.find_module(partname,
[264] Fix | Delete
parent and parent.__path__, parent)
[265] Fix | Delete
except ImportError:
[266] Fix | Delete
self.msgout(3, "import_module ->", None)
[267] Fix | Delete
return None
[268] Fix | Delete
try:
[269] Fix | Delete
m = self.load_module(fqname, fp, pathname, stuff)
[270] Fix | Delete
finally:
[271] Fix | Delete
if fp:
[272] Fix | Delete
fp.close()
[273] Fix | Delete
if parent:
[274] Fix | Delete
setattr(parent, partname, m)
[275] Fix | Delete
self.msgout(3, "import_module ->", m)
[276] Fix | Delete
return m
[277] Fix | Delete
[278] Fix | Delete
def load_module(self, fqname, fp, pathname, file_info):
[279] Fix | Delete
suffix, mode, type = file_info
[280] Fix | Delete
self.msgin(2, "load_module", fqname, fp and "fp", pathname)
[281] Fix | Delete
if type == imp.PKG_DIRECTORY:
[282] Fix | Delete
m = self.load_package(fqname, pathname)
[283] Fix | Delete
self.msgout(2, "load_module ->", m)
[284] Fix | Delete
return m
[285] Fix | Delete
if type == imp.PY_SOURCE:
[286] Fix | Delete
co = compile(fp.read()+'\n', pathname, 'exec')
[287] Fix | Delete
elif type == imp.PY_COMPILED:
[288] Fix | Delete
try:
[289] Fix | Delete
marshal_data = importlib._bootstrap_external._validate_bytecode_header(fp.read())
[290] Fix | Delete
except ImportError as exc:
[291] Fix | Delete
self.msgout(2, "raise ImportError: " + str(exc), pathname)
[292] Fix | Delete
raise
[293] Fix | Delete
co = marshal.loads(marshal_data)
[294] Fix | Delete
else:
[295] Fix | Delete
co = None
[296] Fix | Delete
m = self.add_module(fqname)
[297] Fix | Delete
m.__file__ = pathname
[298] Fix | Delete
if co:
[299] Fix | Delete
if self.replace_paths:
[300] Fix | Delete
co = self.replace_paths_in_code(co)
[301] Fix | Delete
m.__code__ = co
[302] Fix | Delete
self.scan_code(co, m)
[303] Fix | Delete
self.msgout(2, "load_module ->", m)
[304] Fix | Delete
return m
[305] Fix | Delete
[306] Fix | Delete
def _add_badmodule(self, name, caller):
[307] Fix | Delete
if name not in self.badmodules:
[308] Fix | Delete
self.badmodules[name] = {}
[309] Fix | Delete
if caller:
[310] Fix | Delete
self.badmodules[name][caller.__name__] = 1
[311] Fix | Delete
else:
[312] Fix | Delete
self.badmodules[name]["-"] = 1
[313] Fix | Delete
[314] Fix | Delete
def _safe_import_hook(self, name, caller, fromlist, level=-1):
[315] Fix | Delete
# wrapper for self.import_hook() that won't raise ImportError
[316] Fix | Delete
if name in self.badmodules:
[317] Fix | Delete
self._add_badmodule(name, caller)
[318] Fix | Delete
return
[319] Fix | Delete
try:
[320] Fix | Delete
self.import_hook(name, caller, level=level)
[321] Fix | Delete
except ImportError as msg:
[322] Fix | Delete
self.msg(2, "ImportError:", str(msg))
[323] Fix | Delete
self._add_badmodule(name, caller)
[324] Fix | Delete
else:
[325] Fix | Delete
if fromlist:
[326] Fix | Delete
for sub in fromlist:
[327] Fix | Delete
if sub in self.badmodules:
[328] Fix | Delete
self._add_badmodule(sub, caller)
[329] Fix | Delete
continue
[330] Fix | Delete
try:
[331] Fix | Delete
self.import_hook(name, caller, [sub], level=level)
[332] Fix | Delete
except ImportError as msg:
[333] Fix | Delete
self.msg(2, "ImportError:", str(msg))
[334] Fix | Delete
fullname = name + "." + sub
[335] Fix | Delete
self._add_badmodule(fullname, caller)
[336] Fix | Delete
[337] Fix | Delete
def scan_opcodes(self, co):
[338] Fix | Delete
# Scan the code, and yield 'interesting' opcode combinations
[339] Fix | Delete
code = co.co_code
[340] Fix | Delete
names = co.co_names
[341] Fix | Delete
consts = co.co_consts
[342] Fix | Delete
opargs = [(op, arg) for _, op, arg in dis._unpack_opargs(code)
[343] Fix | Delete
if op != EXTENDED_ARG]
[344] Fix | Delete
for i, (op, oparg) in enumerate(opargs):
[345] Fix | Delete
if op in STORE_OPS:
[346] Fix | Delete
yield "store", (names[oparg],)
[347] Fix | Delete
continue
[348] Fix | Delete
if (op == IMPORT_NAME and i >= 2
[349] Fix | Delete
and opargs[i-1][0] == opargs[i-2][0] == LOAD_CONST):
[350] Fix | Delete
level = consts[opargs[i-2][1]]
[351] Fix | Delete
fromlist = consts[opargs[i-1][1]]
[352] Fix | Delete
if level == 0: # absolute import
[353] Fix | Delete
yield "absolute_import", (fromlist, names[oparg])
[354] Fix | Delete
else: # relative import
[355] Fix | Delete
yield "relative_import", (level, fromlist, names[oparg])
[356] Fix | Delete
continue
[357] Fix | Delete
[358] Fix | Delete
def scan_code(self, co, m):
[359] Fix | Delete
code = co.co_code
[360] Fix | Delete
scanner = self.scan_opcodes
[361] Fix | Delete
for what, args in scanner(co):
[362] Fix | Delete
if what == "store":
[363] Fix | Delete
name, = args
[364] Fix | Delete
m.globalnames[name] = 1
[365] Fix | Delete
elif what == "absolute_import":
[366] Fix | Delete
fromlist, name = args
[367] Fix | Delete
have_star = 0
[368] Fix | Delete
if fromlist is not None:
[369] Fix | Delete
if "*" in fromlist:
[370] Fix | Delete
have_star = 1
[371] Fix | Delete
fromlist = [f for f in fromlist if f != "*"]
[372] Fix | Delete
self._safe_import_hook(name, m, fromlist, level=0)
[373] Fix | Delete
if have_star:
[374] Fix | Delete
# We've encountered an "import *". If it is a Python module,
[375] Fix | Delete
# the code has already been parsed and we can suck out the
[376] Fix | Delete
# global names.
[377] Fix | Delete
mm = None
[378] Fix | Delete
if m.__path__:
[379] Fix | Delete
# At this point we don't know whether 'name' is a
[380] Fix | Delete
# submodule of 'm' or a global module. Let's just try
[381] Fix | Delete
# the full name first.
[382] Fix | Delete
mm = self.modules.get(m.__name__ + "." + name)
[383] Fix | Delete
if mm is None:
[384] Fix | Delete
mm = self.modules.get(name)
[385] Fix | Delete
if mm is not None:
[386] Fix | Delete
m.globalnames.update(mm.globalnames)
[387] Fix | Delete
m.starimports.update(mm.starimports)
[388] Fix | Delete
if mm.__code__ is None:
[389] Fix | Delete
m.starimports[name] = 1
[390] Fix | Delete
else:
[391] Fix | Delete
m.starimports[name] = 1
[392] Fix | Delete
elif what == "relative_import":
[393] Fix | Delete
level, fromlist, name = args
[394] Fix | Delete
if name:
[395] Fix | Delete
self._safe_import_hook(name, m, fromlist, level=level)
[396] Fix | Delete
else:
[397] Fix | Delete
parent = self.determine_parent(m, level=level)
[398] Fix | Delete
self._safe_import_hook(parent.__name__, None, fromlist, level=0)
[399] Fix | Delete
else:
[400] Fix | Delete
# We don't expect anything else from the generator.
[401] Fix | Delete
raise RuntimeError(what)
[402] Fix | Delete
[403] Fix | Delete
for c in co.co_consts:
[404] Fix | Delete
if isinstance(c, type(co)):
[405] Fix | Delete
self.scan_code(c, m)
[406] Fix | Delete
[407] Fix | Delete
def load_package(self, fqname, pathname):
[408] Fix | Delete
self.msgin(2, "load_package", fqname, pathname)
[409] Fix | Delete
newname = replacePackageMap.get(fqname)
[410] Fix | Delete
if newname:
[411] Fix | Delete
fqname = newname
[412] Fix | Delete
m = self.add_module(fqname)
[413] Fix | Delete
m.__file__ = pathname
[414] Fix | Delete
m.__path__ = [pathname]
[415] Fix | Delete
[416] Fix | Delete
# As per comment at top of file, simulate runtime __path__ additions.
[417] Fix | Delete
m.__path__ = m.__path__ + packagePathMap.get(fqname, [])
[418] Fix | Delete
[419] Fix | Delete
fp, buf, stuff = self.find_module("__init__", m.__path__)
[420] Fix | Delete
try:
[421] Fix | Delete
self.load_module(fqname, fp, buf, stuff)
[422] Fix | Delete
self.msgout(2, "load_package ->", m)
[423] Fix | Delete
return m
[424] Fix | Delete
finally:
[425] Fix | Delete
if fp:
[426] Fix | Delete
fp.close()
[427] Fix | Delete
[428] Fix | Delete
def add_module(self, fqname):
[429] Fix | Delete
if fqname in self.modules:
[430] Fix | Delete
return self.modules[fqname]
[431] Fix | Delete
self.modules[fqname] = m = Module(fqname)
[432] Fix | Delete
return m
[433] Fix | Delete
[434] Fix | Delete
def find_module(self, name, path, parent=None):
[435] Fix | Delete
if parent is not None:
[436] Fix | Delete
# assert path is not None
[437] Fix | Delete
fullname = parent.__name__+'.'+name
[438] Fix | Delete
else:
[439] Fix | Delete
fullname = name
[440] Fix | Delete
if fullname in self.excludes:
[441] Fix | Delete
self.msgout(3, "find_module -> Excluded", fullname)
[442] Fix | Delete
raise ImportError(name)
[443] Fix | Delete
[444] Fix | Delete
if path is None:
[445] Fix | Delete
if name in sys.builtin_module_names:
[446] Fix | Delete
return (None, None, ("", "", imp.C_BUILTIN))
[447] Fix | Delete
[448] Fix | Delete
path = self.path
[449] Fix | Delete
return imp.find_module(name, path)
[450] Fix | Delete
[451] Fix | Delete
def report(self):
[452] Fix | Delete
"""Print a report to stdout, listing the found modules with their
[453] Fix | Delete
paths, as well as modules that are missing, or seem to be missing.
[454] Fix | Delete
"""
[455] Fix | Delete
print()
[456] Fix | Delete
print(" %-25s %s" % ("Name", "File"))
[457] Fix | Delete
print(" %-25s %s" % ("----", "----"))
[458] Fix | Delete
# Print modules found
[459] Fix | Delete
keys = sorted(self.modules.keys())
[460] Fix | Delete
for key in keys:
[461] Fix | Delete
m = self.modules[key]
[462] Fix | Delete
if m.__path__:
[463] Fix | Delete
print("P", end=' ')
[464] Fix | Delete
else:
[465] Fix | Delete
print("m", end=' ')
[466] Fix | Delete
print("%-25s" % key, m.__file__ or "")
[467] Fix | Delete
[468] Fix | Delete
# Print missing modules
[469] Fix | Delete
missing, maybe = self.any_missing_maybe()
[470] Fix | Delete
if missing:
[471] Fix | Delete
print()
[472] Fix | Delete
print("Missing modules:")
[473] Fix | Delete
for name in missing:
[474] Fix | Delete
mods = sorted(self.badmodules[name].keys())
[475] Fix | Delete
print("?", name, "imported from", ', '.join(mods))
[476] Fix | Delete
# Print modules that may be missing, but then again, maybe not...
[477] Fix | Delete
if maybe:
[478] Fix | Delete
print()
[479] Fix | Delete
print("Submodules that appear to be missing, but could also be", end=' ')
[480] Fix | Delete
print("global names in the parent package:")
[481] Fix | Delete
for name in maybe:
[482] Fix | Delete
mods = sorted(self.badmodules[name].keys())
[483] Fix | Delete
print("?", name, "imported from", ', '.join(mods))
[484] Fix | Delete
[485] Fix | Delete
def any_missing(self):
[486] Fix | Delete
"""Return a list of modules that appear to be missing. Use
[487] Fix | Delete
any_missing_maybe() if you want to know which modules are
[488] Fix | Delete
certain to be missing, and which *may* be missing.
[489] Fix | Delete
"""
[490] Fix | Delete
missing, maybe = self.any_missing_maybe()
[491] Fix | Delete
return missing + maybe
[492] Fix | Delete
[493] Fix | Delete
def any_missing_maybe(self):
[494] Fix | Delete
"""Return two lists, one with modules that are certainly missing
[495] Fix | Delete
and one with modules that *may* be missing. The latter names could
[496] Fix | Delete
either be submodules *or* just global names in the package.
[497] Fix | Delete
[498] Fix | Delete
The reason it can't always be determined is that it's impossible to
[499] Fix | Delete
12
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function