Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
bpo-1284670: Allow to restrict ModuleFinder to get "direct" dependencies
- Loading branch information
Showing
with
201 additions
and 8 deletions.
- +9 −6 Lib/modulefinder.py
- +21 −2 Lib/test/test_modulefinder.py
- +171 −0 issue1284670.patch
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,171 @@ | ||
--- a/Lib/modulefinder.py | ||
+++ b/Lib/modulefinder.py | ||
@@ -1,6 +1,5 @@ | ||
"""Find modules used by a script, using introspection.""" | ||
|
||
-from __future__ import generators | ||
import dis | ||
import imp | ||
import marshal | ||
@@ -9,8 +8,6 @@ import sys | ||
import types | ||
import struct | ||
|
||
-READ_MODE = "rU" | ||
- | ||
# XXX Clean up once str8's cstor matches bytes. | ||
LOAD_CONST = bytes([dis.opname.index('LOAD_CONST')]) | ||
IMPORT_NAME = bytes([dis.opname.index('IMPORT_NAME')]) | ||
@@ -29,8 +26,7 @@ packagePathMap = {} | ||
|
||
# A Public interface | ||
def AddPackagePath(packagename, path): | ||
- paths = packagePathMap.get(packagename, []) | ||
- paths.append(path) | ||
+ paths = packagePathMap.setdefault(packagename, []).append(path) | ||
packagePathMap[packagename] = paths | ||
|
||
replacePackageMap = {} | ||
@@ -106,14 +102,14 @@ class ModuleFinder: | ||
|
||
def run_script(self, pathname): | ||
self.msg(2, "run_script", pathname) | ||
- with open(pathname, READ_MODE) as fp: | ||
+ with open(pathname) as fp: | ||
stuff = ("", "r", imp.PY_SOURCE) | ||
self.load_module('__main__', fp, pathname, stuff) | ||
|
||
def load_file(self, pathname): | ||
dir, name = os.path.split(pathname) | ||
name, ext = os.path.splitext(name) | ||
- with open(pathname, READ_MODE) as fp: | ||
+ with open(pathname) as fp: | ||
stuff = (ext, "r", imp.PY_SOURCE) | ||
self.load_module(name, fp, pathname, stuff) | ||
|
||
@@ -270,7 +266,8 @@ class ModuleFinder: | ||
try: | ||
m = self.load_module(fqname, fp, pathname, stuff) | ||
finally: | ||
- if fp: fp.close() | ||
+ if fp: | ||
+ fp.close() | ||
if parent: | ||
setattr(parent, partname, m) | ||
self.msgout(3, "import_module ->", m) | ||
@@ -662,4 +659,4 @@ if __name__ == '__main__': | ||
try: | ||
mf = test() | ||
except KeyboardInterrupt: | ||
- print("\n[interrupt]") | ||
+ print("\n[interrupted]") | ||
--- a/Lib/test/test_modulefinder.py | ||
+++ b/Lib/test/test_modulefinder.py | ||
@@ -1,7 +1,7 @@ | ||
-import __future__ | ||
import os | ||
+import errno | ||
+import shutil | ||
import unittest | ||
-import distutils.dir_util | ||
import tempfile | ||
|
||
from test import support | ||
@@ -9,7 +9,7 @@ from test import support | ||
import modulefinder | ||
|
||
TEST_DIR = tempfile.mkdtemp() | ||
-TEST_PATH = [TEST_DIR, os.path.dirname(__future__.__file__)] | ||
+TEST_PATH = [TEST_DIR, os.path.dirname(tempfile.__file__)] | ||
|
||
# Each test description is a list of 5 items: | ||
# | ||
@@ -196,12 +196,17 @@ a/module.py | ||
from . import bar | ||
"""] | ||
|
||
+ | ||
def open_file(path): | ||
- ##print "#", os.path.abspath(path) | ||
dirname = os.path.dirname(path) | ||
- distutils.dir_util.mkpath(dirname) | ||
+ try: | ||
+ os.makedirs(dirname) | ||
+ except OSError as e: | ||
+ if e.errno != errno.EEXIST: | ||
+ raise | ||
return open(path, "w") | ||
|
||
+ | ||
def create_package(source): | ||
ofi = None | ||
try: | ||
@@ -216,6 +221,7 @@ def create_package(source): | ||
if ofi: | ||
ofi.close() | ||
|
||
+ | ||
class ModuleFinderTest(unittest.TestCase): | ||
def _do_test(self, info, report=False): | ||
import_this, modules, missing, maybe_missing, source = info | ||
@@ -234,19 +240,17 @@ class ModuleFinderTest(unittest.TestCase | ||
## import traceback; traceback.print_exc() | ||
## sys.path = opath | ||
## return | ||
- modules = set(modules) | ||
- found = set(mf.modules.keys()) | ||
- more = list(found - modules) | ||
- less = list(modules - found) | ||
+ modules = sorted(set(modules)) | ||
+ found = sorted(mf.modules) | ||
# check if we found what we expected, not more, not less | ||
- self.assertEqual((more, less), ([], [])) | ||
+ self.assertEqual(found, modules) | ||
|
||
# check for missing and maybe missing modules | ||
bad, maybe = mf.any_missing_maybe() | ||
self.assertEqual(bad, missing) | ||
self.assertEqual(maybe, maybe_missing) | ||
finally: | ||
- distutils.dir_util.remove_tree(TEST_DIR) | ||
+ shutil.rmtree(TEST_DIR) | ||
|
||
def test_package(self): | ||
self._do_test(package_test) | ||
@@ -254,25 +258,23 @@ class ModuleFinderTest(unittest.TestCase | ||
def test_maybe(self): | ||
self._do_test(maybe_test) | ||
|
||
- if getattr(__future__, "absolute_import", None): | ||
+ def test_maybe_new(self): | ||
+ self._do_test(maybe_test_new) | ||
|
||
- def test_maybe_new(self): | ||
- self._do_test(maybe_test_new) | ||
- | ||
- def test_absolute_imports(self): | ||
- self._do_test(absolute_import_test) | ||
+ def test_absolute_imports(self): | ||
+ self._do_test(absolute_import_test) | ||
|
||
- def test_relative_imports(self): | ||
- self._do_test(relative_import_test) | ||
+ def test_relative_imports(self): | ||
+ self._do_test(relative_import_test) | ||
|
||
- def test_relative_imports_2(self): | ||
- self._do_test(relative_import_test_2) | ||
+ def test_relative_imports_2(self): | ||
+ self._do_test(relative_import_test_2) | ||
|
||
- def test_relative_imports_3(self): | ||
- self._do_test(relative_import_test_3) | ||
+ def test_relative_imports_3(self): | ||
+ self._do_test(relative_import_test_3) | ||
+ | ||
|
||
def test_main(): | ||
- distutils.log.set_threshold(distutils.log.WARN) | ||
support.run_unittest(ModuleFinderTest) | ||
|
||
if __name__ == "__main__": |
You’re not receiving notifications from this thread.