From 4ae7fcc9bcd890c3cb121fa3315bdf05d9bbb928 Mon Sep 17 00:00:00 2001 From: Alex Willmer Date: Mon, 19 Feb 2018 20:53:41 +0000 Subject: [PATCH 1/7] tests: Rename FindRelatedImportsTest -> FindRelatedTest --- tests/module_finder_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/module_finder_test.py b/tests/module_finder_test.py index a3a41364..f8c2cc70 100644 --- a/tests/module_finder_test.py +++ b/tests/module_finder_test.py @@ -129,11 +129,11 @@ class ResolveRelPathTest(testlib.TestCase): self.assertEquals('', self.call('email.utils', 3)) -class FindRelatedImportsTest(testlib.TestCase): +class FindRelatedTest(testlib.TestCase): klass = mitogen.master.ModuleFinder def call(self, fullname): - return self.klass().find_related_imports(fullname) + return self.klass().find_related(fullname) def test_simple(self): import mitogen.fakessh From 81e22a12e9241196a497645c68c14d3c0d9db201 Mon Sep 17 00:00:00 2001 From: Alex Willmer Date: Mon, 19 Feb 2018 20:56:47 +0000 Subject: [PATCH 2/7] tests: Remove module under search from expected results This matches a tweak made in 8765f761c995c31c9bff6287d881f0e9b5d0cfc5 --- tests/module_finder_test.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/module_finder_test.py b/tests/module_finder_test.py index f8c2cc70..4ee28e58 100644 --- a/tests/module_finder_test.py +++ b/tests/module_finder_test.py @@ -148,7 +148,6 @@ class FindRelatedTest(testlib.TestCase): import django related = self.call('django') self.assertEquals(related, [ - 'django', 'django.utils', 'django.utils.lru_cache', 'django.utils.version', @@ -164,7 +163,6 @@ class FindRelatedTest(testlib.TestCase): 'django.core', 'django.core.exceptions', 'django.core.signals', - 'django.db', 'django.db.utils', 'django.dispatch', 'django.dispatch.dispatcher', @@ -220,7 +218,6 @@ class FindRelatedTest(testlib.TestCase): 'django.db', 'django.db.backends', 'django.db.backends.utils', - 'django.db.models', 'django.db.models.aggregates', 'django.db.models.base', 'django.db.models.constants', From a931113a2c891e0b9c6f270b97065fbbbc871d13 Mon Sep 17 00:00:00 2001 From: Alex Willmer Date: Mon, 19 Feb 2018 20:58:22 +0000 Subject: [PATCH 3/7] tests: Add new FindRelatedImportsTest --- tests/module_finder_test.py | 58 +++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/tests/module_finder_test.py b/tests/module_finder_test.py index 4ee28e58..15a4b78b 100644 --- a/tests/module_finder_test.py +++ b/tests/module_finder_test.py @@ -129,6 +129,64 @@ class ResolveRelPathTest(testlib.TestCase): self.assertEquals('', self.call('email.utils', 3)) +class FindRelatedImportsTest(testlib.TestCase): + klass = mitogen.master.ModuleFinder + + def call(self, fullname): + return self.klass().find_related_imports(fullname) + + def test_simple(self): + import mitogen.fakessh + related = self.call('mitogen.fakessh') + self.assertEquals(related, [ + 'mitogen', + 'mitogen.core', + 'mitogen.master', + 'mitogen.parent', + ]) + + def test_django_pkg(self): + import django + related = self.call('django') + self.assertEquals(related, [ + 'django.utils.version', + ]) + + def test_django_db(self): + import django.db + related = self.call('django.db') + self.assertEquals(related, [ + 'django', + 'django.core', + 'django.core.signals', + 'django.db.utils', + ]) + + def test_django_db_models(self): + import django.db.models + related = self.call('django.db.models') + self.maxDiff=None + self.assertEquals(related, [ + 'django', + 'django.core.exceptions', + 'django.db', + 'django.db.models', + 'django.db.models.aggregates', + 'django.db.models.base', + 'django.db.models.deletion', + 'django.db.models.expressions', + 'django.db.models.fields', + 'django.db.models.fields.files', + 'django.db.models.fields.proxy', + 'django.db.models.fields.related', + 'django.db.models.indexes', + 'django.db.models.lookups', + 'django.db.models.manager', + 'django.db.models.query', + 'django.db.models.signals', + ]) + + class FindRelatedTest(testlib.TestCase): klass = mitogen.master.ModuleFinder From 71c00789f0e5eb96bd431d60b742444ce60084f8 Mon Sep 17 00:00:00 2001 From: Alex Willmer Date: Mon, 19 Feb 2018 21:01:04 +0000 Subject: [PATCH 4/7] tests: Fix expected values FindRelatedTest for Django 1.11.4 --- tests/module_finder_test.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/module_finder_test.py b/tests/module_finder_test.py index 15a4b78b..d589013c 100644 --- a/tests/module_finder_test.py +++ b/tests/module_finder_test.py @@ -200,6 +200,7 @@ class FindRelatedTest(testlib.TestCase): 'mitogen', 'mitogen.core', 'mitogen.master', + 'mitogen.parent', ]) def test_django_pkg(self): @@ -243,6 +244,8 @@ class FindRelatedTest(testlib.TestCase): self.assertEquals(related, [ 'django', 'django.apps', + 'django.apps.config', + 'django.apps.registry', 'django.conf', 'django.conf.global_settings', 'django.core', @@ -255,7 +258,9 @@ class FindRelatedTest(testlib.TestCase): 'django.core.checks.compatibility.django_1_10', 'django.core.checks.compatibility.django_1_8_0', 'django.core.checks.database', + 'django.core.checks.messages', 'django.core.checks.model_checks', + 'django.core.checks.registry', 'django.core.checks.security', 'django.core.checks.security.base', 'django.core.checks.security.csrf', @@ -289,6 +294,8 @@ class FindRelatedTest(testlib.TestCase): 'django.db.models.fields.related_lookups', 'django.db.models.fields.reverse_related', 'django.db.models.functions', + 'django.db.models.functions.base', + 'django.db.models.functions.datetime', 'django.db.models.indexes', 'django.db.models.lookups', 'django.db.models.manager', From bd0a3cbe7cf96fff217e5124896df137482fe8c5 Mon Sep 17 00:00:00 2001 From: Alex Willmer Date: Mon, 19 Feb 2018 21:04:21 +0000 Subject: [PATCH 5/7] tests: Remove jinja2/markupsafe modules from FindRelatedTest Not sure how they got there, but Django doesn't use Jinja without explicit configuration. --- tests/module_finder_test.py | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/tests/module_finder_test.py b/tests/module_finder_test.py index d589013c..99a7c871 100644 --- a/tests/module_finder_test.py +++ b/tests/module_finder_test.py @@ -369,27 +369,6 @@ class FindRelatedTest(testlib.TestCase): 'django.utils.translation', 'django.utils.tree', 'django.utils.version', - 'jinja2', - 'jinja2._compat', - 'jinja2.bccache', - 'jinja2.compiler', - 'jinja2.defaults', - 'jinja2.environment', - 'jinja2.exceptions', - 'jinja2.filters', - 'jinja2.idtracking', - 'jinja2.lexer', - 'jinja2.loaders', - 'jinja2.nodes', - 'jinja2.optimizer', - 'jinja2.parser', - 'jinja2.runtime', - 'jinja2.tests', - 'jinja2.utils', - 'jinja2.visitor', - 'markupsafe', - 'markupsafe._compat', - 'markupsafe._speedups', 'pytz', 'pytz.exceptions', 'pytz.lazy', From 8bcff6c87cb48346560a2b6d6531d9615a6df198 Mon Sep 17 00:00:00 2001 From: Alex Willmer Date: Mon, 19 Feb 2018 21:05:00 +0000 Subject: [PATCH 6/7] tests: Fix typo in ResolveRelPathTest --- tests/module_finder_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/module_finder_test.py b/tests/module_finder_test.py index 99a7c871..0affa27d 100644 --- a/tests/module_finder_test.py +++ b/tests/module_finder_test.py @@ -120,7 +120,7 @@ class ResolveRelPathTest(testlib.TestCase): self.assertEquals('', self.call('email.utils', 0)) def test_rel1(self): - self.assertEquals('email.', self.call('email.utils', 1)) + self.assertEquals('email', self.call('email.utils', 1)) def test_rel2(self): self.assertEquals('', self.call('email.utils', 2)) From 36cb706698757fbc8b68ccfcb3cc009eb7475b50 Mon Sep 17 00:00:00 2001 From: Alex Willmer Date: Mon, 19 Feb 2018 21:06:41 +0000 Subject: [PATCH 7/7] master: Reword ModuleFinder.find_realted*() docstrings Hopefully these are correct, and clearerabout the behaviour/pre-conditions of these methods. --- mitogen/master.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/mitogen/master.py b/mitogen/master.py index fc29473e..59225ece 100644 --- a/mitogen/master.py +++ b/mitogen/master.py @@ -392,10 +392,15 @@ class ModuleFinder(object): def find_related_imports(self, fullname): """ - Given the `fullname` of a currently loaded module, and a copy of its - source code, examine :py:data:`sys.modules` to determine which of the - ``import`` statements from the source code caused a corresponding - module to be loaded that is not part of the standard library. + Return a list of non-stdlb modules that are directly imported by + `fullname`, plus their parents. + + The list is determined by retrieving the source code of + `fullname`, compiling it, and examining all IMPORT_NAME ops. + + :param fullname: Fully qualified name of an _already imported_ module + for which source code can be retrieved + :type fullname: str """ related = self._related_cache.get(fullname) if related is not None: @@ -434,6 +439,17 @@ class ModuleFinder(object): )) def find_related(self, fullname): + """ + Return a list of non-stdlib modules that are imported directly or + indirectly by `fullname`, plus their parents. + + This method is like :py:meth:`on_disconect`, but it also recursively + searches any modules which are imported by `fullname`. + + :param fullname: Fully qualified name of an _already imported_ module + for which source code can be retrieved + :type fullname: str + """ stack = [fullname] found = set()