def testPackagedImplies(self): root = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'testpkg-relimport') # First check that 'syslog' isn't accidently in the graph: mg = modulegraph.ModuleGraph(path=[root] + sys.path) mg.run_script(os.path.join(root, 'script.py')) node = mg.findNode('mod') self.assertIsInstance(node, modulegraph.SourceModule) node = mg.findNode('syslog') self.assertEqual(node, None) # Now check that adding an implied dependency actually adds # 'syslog' to the graph: mg = modulegraph.ModuleGraph(path=[root] + sys.path, implies={'pkg.relative': ['syslog']}) node = mg.findNode('syslog') self.assertEqual(node, None) mg.run_script(os.path.join(root, 'script.py')) node = mg.findNode('pkg.relative') self.assertIsInstance(node, modulegraph.SourceModule) node = mg.findNode('syslog') self.assertIsInstance(node, modulegraph.Extension) # Check that the edges are correct: self.assertTrue(mg.findNode('pkg.relative') in mg.get_edges(node)[1]) self.assertTrue(node in mg.get_edges(mg.findNode('pkg.relative'))[0])
def test_constructor(self): o = modulegraph.ModuleGraph() self.assertTrue(o.path is sys.path) self.assertEqual(o.lazynodes, {}) self.assertEqual(o.replace_paths, ()) self.assertEqual(o.debug, 0) # Stricter tests would be nice, but that requires # better control over what's on sys.path self.assertIsInstance(o.nspackages, dict) g = Graph.Graph() o = modulegraph.ModuleGraph(['a', 'b', 'c'], ['modA'], [('fromA', 'toB'), ('fromC', 'toD')], { 'modA': ['modB', 'modC'], 'modC': ['modE', 'modF'], }, g, 1) self.assertEqual(o.path, ['a', 'b', 'c']) self.assertEqual(o.lazynodes, { 'modA': None, 'modC': ['modE', 'modF'], }) self.assertEqual(o.replace_paths, [('fromA', 'toB'), ('fromC', 'toD')]) self.assertEqual(o.nspackages, {}) self.assertTrue(o.graph is g) self.assertEqual(o.debug, 1)
def test_scan_code(self): mod = modulegraph.Node('root') graph = modulegraph.ModuleGraph() code = compile('', '<test>', 'exec', 0, False) graph.scan_code(code, mod) self.assertEqual(list(graph.nodes()), []) node_map = {} def _safe_import(name, mod, fromlist, level): if name in node_map: node = node_map[name] else: node = modulegraph.Node(name) node_map[name] = node return [node] graph = modulegraph.ModuleGraph() graph._safe_import_hook = _safe_import code = compile( textwrap.dedent('''\ import sys import os.path def testfunc(): import shutil '''), '<test>', 'exec', 0, False) graph.scan_code(code, mod) modules = [node.identifier for node in graph.nodes()] self.assertEqual(set(node_map), set(['sys', 'os.path', 'shutil'])) # from module import a, b, c # from module import * # both: # -> with/without globals # -> with/without modules in globals (e.g, # from os import * adds dependency to os.path) # from .module import a # from ..module import a # -> check levels # import name # import a.b # -> should add dependency to a # try to build case where commented out # code would behave different than current code # (Carbon.SomeMod contains 'import Sibling' seems # to cause difference in real code) self.fail("actual test needed")
def make_module_graph(filenames): modules = {file: anutils.get_module_name(file) for file in filenames} paths = [file[:file.rfind('/')] for file in filenames] modg = modulegraph.ModuleGraph(paths) for file in filenames: modg.run_script(file) pass graph = nx.DiGraph() for edge in list(modg.graph.edges.values()): try: importer = str(modules[edge[0]] if edge[0] in modules else edge[0]) if importer == '<ModuleGraph>': continue imported = edge[1] if edge[1][0:2] == '..': imported = imported[2:] if '.' in importer: ns = importer[:importer.rfind('.')] if '.' in ns: ns = ns[:ns.rfind('.') + 1] imported = ns + imported if edge[1][0] == '.': imported = imported[1:] if '.' in importer: imported = importer[:importer.rfind('.') + 1] + imported graph.add_edge(importer, imported) except KeyError: print('Unknown module: ' + str(edge[0])) return graph
def test_graphreport(self): def my_iter(flatpackages="packages"): yield "line1\n" yield str(flatpackages) + "\n" yield "line2\n" graph = modulegraph.ModuleGraph() graph.itergraphreport = my_iter fp = StringIO() graph.graphreport(fp) self.assertEqual(fp.getvalue(), "line1\n()\nline2\n") fp = StringIO() graph.graphreport(fp, "deps") self.assertEqual(fp.getvalue(), "line1\ndeps\nline2\n") saved_stdout = sys.stdout try: sys.stdout = fp = StringIO() graph.graphreport() self.assertEqual(fp.getvalue(), "line1\n()\nline2\n") finally: sys.stdout = saved_stdout
def find_modules( scripts=(), includes=(), packages=(), excludes=(), path=None, debug=0): """ High-level interface, takes iterables for: scripts, includes, packages, excludes And returns a :class:`modulegraph.modulegraph.ModuleGraph` instance, python_files, and extensions python_files is a list of pure python dependencies as modulegraph.Module objects, extensions is a list of platform-specific C extension dependencies as modulegraph.Module objects """ scripts = set(scripts) includes = set(includes) packages = set(packages) excludes = set(excludes) plat_prepare(includes, packages, excludes) mf = modulegraph.ModuleGraph( path=path, excludes=(excludes - includes), implies=get_implies(), debug=debug, ) find_needed_modules(mf, scripts, includes, packages) return mf
def testMissingPathEntry(self): root = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'nosuchdirectory') try: mf = modulegraph.ModuleGraph(path=[root] + sys.path) except os.error: self.fail('modulegraph initialiser raises os.error')
def setUp(self): root = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'testpkg-relimport') self.mf = modulegraph.ModuleGraph(path=[root] + sys.path) #self.mf.debug = 999 self.script_name = os.path.join(root, 'script.py') self.mf.run_script(self.script_name)
def test_calc_setuptools_nspackages(self): stdlib = [ fn for fn in sys.path if fn.startswith(sys.prefix) and 'site-packages' not in fn ] for subdir in [nm for nm in os.listdir(TESTDATA) if nm != 'src']: graph = modulegraph.ModuleGraph(path=[ os.path.join(TESTDATA, subdir, "parent"), os.path.join(TESTDATA, subdir, "child"), ] + stdlib) pkgs = graph.nspackages self.assertTrue('namedpkg' in pkgs) self.assertEqual( set(pkgs['namedpkg']), set([ os.path.join(TESTDATA, subdir, "parent", "namedpkg"), os.path.join(TESTDATA, subdir, "child", "namedpkg"), ])) self.assertFalse( os.path.exists( os.path.join(TESTDATA, subdir, "parent", "namedpkg", "__init__.py"))) self.assertFalse( os.path.exists( os.path.join(TESTDATA, subdir, "child", "namedpkg", "__init__.py")))
def testImpliedReference(self): graph = modulegraph.ModuleGraph() record = [] def import_hook(*args): record.append(('import_hook', ) + args) return [graph.createNode(modulegraph.Node, args[0])] def _safe_import_hook(*args): record.append(('_safe_import_hook', ) + args) return [graph.createNode(modulegraph.Node, args[0])] graph.import_hook = import_hook graph._safe_import_hook = _safe_import_hook n1 = graph.createNode(modulegraph.Node, 'n1') n2 = graph.createNode(modulegraph.Node, 'n2') graph.implyNodeReference(n1, n2) outs, ins = map(list, graph.get_edges(n1)) self.assertEqual(outs, [n2]) self.assertEqual(ins, []) self.assertEqual(record, []) graph.implyNodeReference(n2, "n3") n3 = graph.findNode('n3') outs, ins = map(list, graph.get_edges(n2)) self.assertEqual(outs, [n3]) self.assertEqual(ins, [n1]) self.assertEqual(record, [('_safe_import_hook', 'n3', n2, None)])
def test_determine_parent(self): graph = modulegraph.ModuleGraph() graph.import_hook('os.path', None) graph.import_hook('idlelib', None) graph.import_hook('xml.dom', None) for node in graph.nodes(): if isinstance(node, modulegraph.Package): break else: self.fail("No package located, should have at least 'os'") self.assertIsInstance(node, modulegraph.Package) parent = graph._determine_parent(node) self.assertEqual(parent.identifier, node.identifier) self.assertEqual(parent, graph.findNode(node.identifier)) self.assertTrue(isinstance(parent, modulegraph.Package)) # XXX: Might be a usecase for some odd code in determine_parent... #node = modulegraph.Package('encodings') #node.packagepath = parent.packagepath #m = graph._determine_parent(node) #self.assertTrue(m is parent) m = graph.findNode('xml') self.assertEqual(graph._determine_parent(m), m) m = graph.findNode('xml.dom') self.assertEqual(graph._determine_parent(m), graph.findNode('xml.dom'))
def testCompiledModules(self): mf = modulegraph.ModuleGraph(path=[self.compiled_dir] + sys.path) #self.mf.debug = 999 mf.run_script(os.path.join(self.compiled_dir, 'script.py')) o = mf.findNode('mod1') self.assertIsInstance(o, modulegraph.CompiledModule) self.assertEqual(o.globalnames, {'mod2', 'mod3', 'foo'}) self.assertEqual(o.starimports, set()) o = mf.findNode('mod2') self.assertIsInstance(o, modulegraph.CompiledModule) self.assertEqual(o.globalnames, {'mod1', 'sys', 'testme', 'bar'}) self.assertEqual(o.starimports, set()) o = mf.findNode('mod3') self.assertIsInstance(o, modulegraph.CompiledModule) self.assertEqual(o.globalnames, {'os', 'path'}) self.assertEqual(o.starimports, set()) o = mf.findNode('mod4') other = mf.findNode('zipfile') self.assertIsInstance(o, modulegraph.CompiledModule) self.assertEqual(o.globalnames, other.globalnames) self.assertEqual(o.starimports, {'math'}) o = mf.findNode('mod5') self.assertIs(o, None)
def testNone(self): mg = modulegraph.ModuleGraph() # empty packagepath m = DummyModule(None) sub_ms = [] for sm in mg._find_all_submodules(m): sub_ms.append(sm) self.assertEqual(sub_ms, [])
def find_needed_modules(mf=None, scripts=(), includes=(), packages=(), warn=warnings.warn): if mf is None: mf = modulegraph.ModuleGraph() # feed Modulefinder with everything, and return it. for path in scripts: mf.run_script(path) for mod in includes: try: if mod[-2:] == '.*': mf.import_hook(mod[:-2], None, ['*']) else: mf.import_hook(mod) except ImportError: warn("No module named %s" % (mod, )) for f in packages: # If modulegraph has seen a reference to the package, then # we prefer to believe that (imp_find_module doesn't seem to locate # sub-packages) m = mf.findNode(f) if m is not None: path = m.packagepath[0] else: # Find path of package # TODO: use imp_find_module_or_importer try: path = imp_find_module(f, mf.path)[1] except ImportError: warn("No package named %s" % f) continue # walk the path to find subdirs containing __init__.py files # scan the results (directory of __init__.py files) # first trim the path (of the head package), # then convert directory name in package name, # finally push into modulegraph. # FIXME: # 1) Needs to be adjusted for namespace packages in python 3.3 # 2) Code is fairly dodgy and needs better tests for (dirpath, dirnames, filenames) in os.walk(path): if '__init__.py' in filenames and dirpath.startswith(path): package = f + '.' + dirpath[len(path) + 1:].replace( os.sep, '.') if package.endswith('.'): package = package[:-1] m = mf.import_hook(package, None, ["*"]) else: # Exclude subtrees that aren't packages dirnames[:] = [] return mf
def testSlashes(self): # a string does not break anything although it is split into its characters # BUG: "/xyz" will read "/" so this one already triggers missing itertools mg = modulegraph.ModuleGraph() m = DummyModule("/xyz") sub_ms = [] for sm in mg._find_all_submodules(m): sub_ms.append(sm) self.assertEqual(sub_ms, [])
def testSimple(self): mg = modulegraph.ModuleGraph() # a string does not break anything although it is split into its characters # BUG: "/hi/there" will read "/" m = DummyModule("xyz") sub_ms = [] for sm in mg._find_all_submodules(m): sub_ms.append(sm) self.assertEqual(sub_ms, [])
def test_multi_import(self): root = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'testpkg-edgedata') mf = modulegraph.ModuleGraph(path=[root] + sys.path) script_name = os.path.join(root, 'script_multi_import.py') mf.run_script(script_name) script_node = mf.findNode(script_name) self.assertIsInstance(script_node, modulegraph.Script) node = mf.findNode('os.path') ed = mf.edgeData(script_node, node) self.assertIsInstance(ed, modulegraph.DependencyInfo) self.assertEqual( ed, modulegraph.DependencyInfo(conditional=False, function=False, tryexcept=True, fromlist=False)) node = mf.findNode('os') ed = mf.edgeData(script_node, node) self.assertIsInstance(ed, modulegraph.DependencyInfo) self.assertEqual( ed, modulegraph.DependencyInfo(conditional=False, function=False, tryexcept=False, fromlist=False)) node = mf.findNode('sys') ed = mf.edgeData(script_node, node) self.assertEqual( ed, modulegraph.DependencyInfo(conditional=True, function=True, tryexcept=False, fromlist=False)) node = mf.findNode('platform') ed = mf.edgeData(script_node, node) self.assertEqual( ed, modulegraph.DependencyInfo(conditional=True, function=True, tryexcept=False, fromlist=False)) node = mf.findNode('email') ed = mf.edgeData(script_node, node) self.assertEqual( ed, modulegraph.DependencyInfo(conditional=False, function=False, tryexcept=False, fromlist=False))
def setUp(self): test_dir = os.path.join(gRootDir, 'test.dir') if os.path.exists(test_dir): shutil.rmtree(test_dir) os.mkdir(test_dir) exit = install_testpkg(test_dir) self.assertEqual(exit, 0) self.mf = modulegraph.ModuleGraph(path=[test_dir] + sys.path)
def test_find_module(self): record = [] def mock_finder(name, path): record.append((name, path)) return saved_finder(name, path) saved_finder = modulegraph.find_module try: modulegraph.find_module = mock_finder graph = modulegraph.ModuleGraph() m = graph._find_module('sys', None) self.assertEqual(record, []) self.assertEqual(m, (None, None, ("", "", imp.C_BUILTIN))) modulegraph.find_module = saved_finder xml = graph.import_hook("xml")[0] self.assertEqual(xml.identifier, 'xml') modulegraph.find_module = mock_finder self.assertRaises(ImportError, graph._find_module, 'xml', None) self.assertEqual(record, []) m = graph._find_module('shutil', None) self.assertEqual(record, [ ('shutil', graph.path), ]) self.assertTrue(isinstance(m, tuple)) self.assertEqual(len(m), 3) self.assertTrue(hasattr(m[0], 'read')) self.assertIsInstance(m[0].read(), str) srcfn = shutil.__file__ if srcfn.endswith('.pyc'): srcfn = srcfn[:-1] self.assertEqual(os.path.realpath(m[1]), os.path.realpath(srcfn)) self.assertEqual(m[2], ('.py', 'rU', imp.PY_SOURCE)) m[0].close() m2 = graph._find_module('shutil', None) self.assertEqual(m[1:], m2[1:]) m2[0].close() record[:] = [] m = graph._find_module('sax', xml.packagepath, xml) self.assertEqual( m, (None, os.path.join(os.path.dirname(xml.filename), 'sax'), ('', '', imp.PKG_DIRECTORY))) self.assertEqual(record, [ ('sax', xml.packagepath), ]) if m[0] is not None: m[0].close() finally: modulegraph.find_module = saved_finder
def GetGraph(): """Build the graph object.""" python_path = sys.path[:] graph = modulegraph.ModuleGraph(python_path) for root, unused_dirs, files in itertools.chain( os.walk(six.text_type(_PathHelper.googlecloudsdk_root)), os.walk(six.text_type(_PathHelper.googlecloudsdk_tests_root))): for f in files: _ImportPath(graph, root, f) return graph
def test_run_script(self): script = os.path.join(os.path.dirname(TESTDATA), 'script') graph = modulegraph.ModuleGraph() master = graph.createNode(modulegraph.Node, 'root') m = graph.run_script(script, master) self.assertEqual(list(graph.get_edges(master)[0])[0], m) self.assertEqual(set(graph.get_edges(m)[0]), { graph.findNode('sys'), graph.findNode('os'), })
def FindPythonDependencies(module_path): logging.info('Finding Python dependencies of %s', module_path) if modulegraph is None: raise import_error prefixes = [sys.prefix] if hasattr(sys, 'real_prefix'): prefixes.append(sys.real_prefix) logging.info('Excluding Prefixes: %r', prefixes) sys_path = sys.path sys.path = list(sys_path) try: # Load the module to inherit its sys.path modifications. sys.path.insert(0, os.path.abspath(os.path.dirname(module_path))) imp.load_source( os.path.splitext(os.path.basename(module_path))[0], module_path) # Analyze the module for its imports. graph = modulegraph.ModuleGraph() graph.run_script(module_path) # Filter for only imports in Chromium. for node in graph.nodes(): if not node.filename: continue module_path = os.path.realpath(node.filename) _, incoming_edges = graph.get_edges(node) message = 'Discovered %s (Imported by: %s)' % ( node.filename, ', '.join( d.filename for d in incoming_edges if d is not None and d.filename is not None)) logging.info(message) # This check is done after the logging/printing above to make sure that # we also print out the dependency edges that include python packages # that are not in chromium. if not path.IsSubpath(module_path, path_util.GetChromiumSrcDir()): continue # Exclude any dependencies which exist in the python installation. if any(path.IsSubpath(module_path, pfx) for pfx in prefixes): continue yield module_path if node.packagepath is not None: for p in node.packagepath: yield p finally: sys.path = sys_path
def test_load_tail(self): graph = modulegraph.ModuleGraph() record = [] def import_module(partname, fqname, parent): record.append((partname, fqname, parent)) if partname == 'raises': return None return modulegraph.Node(fqname) graph.import_module = import_module record = [] root = modulegraph.Node('root') m = graph.load_tail(root, '') self.assertTrue(m is root) self.assertEqual(record, []) record = [] root = modulegraph.Node('root') m = graph.load_tail(root, 'sub') self.assertFalse(m is root) self.assertEqual(record, [ ('sub', 'root.sub', root), ]) record = [] root = modulegraph.Node('root') m = graph.load_tail(root, 'sub.sub1') self.assertFalse(m is root) node = modulegraph.Node('root.sub') self.assertEqual(record, [ ('sub', 'root.sub', root), ('sub1', 'root.sub.sub1', node), ]) record = [] root = modulegraph.Node('root') m = graph.load_tail(root, 'sub.sub1.sub2') self.assertFalse(m is root) node = modulegraph.Node('root.sub') node2 = modulegraph.Node('root.sub.sub1') self.assertEqual(record, [ ('sub', 'root.sub', root), ('sub1', 'root.sub.sub1', node), ('sub2', 'root.sub.sub1.sub2', node2), ]) self.assertRaises(ImportError, graph.load_tail, root, 'raises') self.assertRaises(ImportError, graph.load_tail, root, 'sub.raises') self.assertRaises(ImportError, graph.load_tail, root, 'sub.raises.sub')
def test_relative_import_too_far(self): # pkg.mod tries to import "..sys" (outside of the package...) root = os.path.join( os.path.dirname(os.path.abspath(__file__)), 'testpkg-regr7') mf = modulegraph.ModuleGraph(path=[ root ] + sys.path) mf.run_script(os.path.join(root, 'script.py')) m = mf.findNode('') self.assertIs(m, None) m = mf.findNode('pkg.mod') self.assertIsInstance(m, modulegraph.SourceModule) imported = list(mf.get_edges(m)[0]) self.assertEqual(len(imported), 5) im = imported[0] self.assertIsInstance(im, modulegraph.InvalidRelativeImport) self.assertEqual(im.relative_path, '..') self.assertEqual(im.from_name, 'sys') self.assertEqual(im.identifier, '..sys') im1 = imported[1] im2 = imported[2] if im1.identifier == '...xml': # Order of modules imported in a single 'from .. import a, b' list # is unspecified, ensure a fixed order for this test. im2, im1 = im1, im2 self.assertIsInstance(im1, modulegraph.InvalidRelativeImport) self.assertEqual(im1.relative_path, '...') self.assertEqual(im1.from_name, 'os') self.assertEqual(im1.identifier, '...os') im = imported[2] self.assertIsInstance(im2, modulegraph.InvalidRelativeImport) self.assertEqual(im2.relative_path, '...') self.assertEqual(im2.from_name, 'xml') self.assertEqual(im2.identifier, '...xml') im = imported[3] self.assertIsInstance(im, modulegraph.InvalidRelativeImport) self.assertEqual(im.relative_path, '..foo') self.assertEqual(im.from_name, 'bar') self.assertEqual(im.identifier, '..foo.bar') im = imported[4] self.assertIs(im, mf.findNode('pkg'))
def test_replace_paths_in_code(self): graph = modulegraph.ModuleGraph(replace_paths=[ ('path1', 'path2'), (os.path.join('path3', 'path5'), 'path4'), ]) co = compile( textwrap.dedent(""" [x for x in range(4)] """), os.path.join("path4", "index.py"), 'exec', 0, 1) co = graph._replace_paths_in_code(co) self.assertEqual(co.co_filename, os.path.join('path4', 'index.py')) co = compile( textwrap.dedent(""" [x for x in range(4)] (x for x in range(4)) """), os.path.join("path1", "index.py"), 'exec', 0, 1) self.assertEqual(co.co_filename, os.path.join('path1', 'index.py')) co = graph._replace_paths_in_code(co) self.assertEqual(co.co_filename, os.path.join('path2', 'index.py')) for c in co.co_consts: if isinstance(c, type(co)): self.assertEqual(c.co_filename, os.path.join('path2', 'index.py')) co = compile( textwrap.dedent(""" [x for x in range(4)] """), os.path.join("path3", "path4", "index.py"), 'exec', 0, 1) co = graph._replace_paths_in_code(co) self.assertEqual(co.co_filename, os.path.join('path3', 'path4', 'index.py')) co = compile( textwrap.dedent(""" [x for x in range(4)] """), os.path.join("path3", "path5.py"), 'exec', 0, 1) co = graph._replace_paths_in_code(co) self.assertEqual(co.co_filename, os.path.join('path3', 'path5.py')) co = compile( textwrap.dedent(""" [x for x in range(4)] """), os.path.join("path3", "path5", "index.py"), 'exec', 0, 1) co = graph._replace_paths_in_code(co) self.assertEqual(co.co_filename, os.path.join('path4', 'index.py'))
def test_itergraphreport(self): # XXX: This test is far from optimal, it just ensures # that all code is exercised to catch small bugs and # py3k issues without verifying that the code actually # works.... graph = modulegraph.ModuleGraph() if __file__.endswith('.py'): graph.run_script(__file__) else: graph.run_script(__file__[:-1]) graph.import_hook('os') graph.import_hook('xml.etree') graph.import_hook('unittest') graph.import_hook('distutils.command.build') fp = StringIO() list(graph.itergraphreport())
def test_report(self): graph = modulegraph.ModuleGraph() saved_stdout = sys.stdout try: fp = sys.stdout = StringIO() graph.report() lines = fp.getvalue().splitlines() fp.close() self.assertEqual(len(lines), 3) self.assertEqual(lines[0], '') self.assertEqual(lines[1], 'Class Name File') self.assertEqual(lines[2], '----- ---- ----') fp = sys.stdout = StringIO() graph._safe_import_hook('os', None, ()) graph._safe_import_hook('sys', None, ()) graph._safe_import_hook('nomod', None, ()) graph.report() lines = fp.getvalue().splitlines() fp.close() self.assertEqual(lines[0], '') self.assertEqual(lines[1], 'Class Name File') self.assertEqual(lines[2], '----- ---- ----') expected = [] for n in graph.flatten(): if n.filename: expected.append( [type(n).__name__, n.identifier, n.filename]) else: expected.append([type(n).__name__, n.identifier]) expected.sort() actual = [item.split() for item in lines[3:]] actual.sort() self.assertEqual(expected, actual) finally: sys.stdout = saved_stdout
def test_replace_paths_in_code(self): graph = modulegraph.ModuleGraph(replace_paths=[ ('path1', 'path2'), ('path3/path5', 'path4'), ]) co = compile( textwrap.dedent(""" [x for x in range(4)] """), "path4/index.py", 'exec', 0, 1) co = graph._replace_paths_in_code(co) self.assertEqual(co.co_filename, 'path4/index.py') co = compile( textwrap.dedent(""" [x for x in range(4)] (x for x in range(4)) """), "path1/index.py", 'exec', 0, 1) self.assertEqual(co.co_filename, 'path1/index.py') co = graph._replace_paths_in_code(co) self.assertEqual(co.co_filename, 'path2/index.py') for c in co.co_consts: if isinstance(c, type(co)): self.assertEqual(c.co_filename, 'path2/index.py') co = compile( textwrap.dedent(""" [x for x in range(4)] """), "path3/path4/index.py", 'exec', 0, 1) co = graph._replace_paths_in_code(co) self.assertEqual(co.co_filename, 'path3/path4/index.py') co = compile( textwrap.dedent(""" [x for x in range(4)] """), "path3/path5.py", 'exec', 0, 1) co = graph._replace_paths_in_code(co) self.assertEqual(co.co_filename, 'path3/path5.py') co = compile( textwrap.dedent(""" [x for x in range(4)] """), "path3/path5/index.py", 'exec', 0, 1) co = graph._replace_paths_in_code(co) self.assertEqual(co.co_filename, 'path4/index.py')
def test_createReference(self): graph = modulegraph.ModuleGraph() n1 = modulegraph.Node('n1') n2 = modulegraph.Node('n2') graph.addNode(n1) graph.addNode(n2) graph.createReference(n1, n2) outs, ins = map(list, graph.get_edges(n1)) self.assertEqual(outs, [n2]) self.assertEqual(ins, []) outs, ins = map(list, graph.get_edges(n2)) self.assertEqual(outs, []) self.assertEqual(ins, [n1]) e = graph.graph.edge_by_node('n1', 'n2') self.assertIsInstance(e, int) self.assertEqual(graph.graph.edge_data(e), 'direct')
def test_invalid_async_function(self): # In python 3.5 the following function is invalid: # # async def foo(): # yield 1 # # This is a syntax error that's reported when compiling the AST # to bytecode, which caused an error in modulegraph. # # In python 3.6 this is valid code (and in earlier versions async # versions didn't exist) root = os.path.join( os.path.dirname(os.path.abspath(__file__)), 'testpkg-regr8') mf = modulegraph.ModuleGraph(path=[ root ] + sys.path) mf.run_script(os.path.join(root, 'script.py')) n = mf.findNode('mod') self.assertIsInstance(n, modulegraph.InvalidSourceModule)