From f1009b75021e07fc88203ca1c6ee80ba6152e6b0 Mon Sep 17 00:00:00 2001 From: David Wilson Date: Mon, 12 Mar 2018 20:45:36 +0545 Subject: [PATCH] issue #121: fix breakage caused by a9c6c13 This actually addresses multiple problems: * Single-file programs were broken, since the fix introduced in 6931cc10c4a1e08161a58cf4b6b555b71cdc62b5 caused builtin_find_module() to start indicating __main__ can always be loaded locally. That's broken, and there might be more cases where the same problem will crop up. Since it was indicated __main__ could be loaded locally, the built-in import machinery was allowed to attempt that (since we remove __main__ from sys.modules during bootstrap), which caused a safety check to fire in the bowels of Python: "Cannot re-init internal module %.200s" * The check for presence of the whitelist was totally broken, since the whitelist is never an empty list. Therefore 'self' was being returned for every module, including extension modules like 'termios'. I have hand-verified this does not break the fix for issue #113. I looked at writing a test for that, but it requires a Docker container (or similar) with an ancient version of Ansible installed. Will open a separate ticket tracking this. --- mitogen/core.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/mitogen/core.py b/mitogen/core.py index d2c11034..ec58a11d 100644 --- a/mitogen/core.py +++ b/mitogen/core.py @@ -453,11 +453,18 @@ class Importer(object): return 'Importer()' def builtin_find_module(self, fullname): + # imp.find_module() will always succeed for __main__, because it is a + # built-in module. That means it exists on a special linked list deep + # within the bowels of the interpreter. We must special case it. + if fullname == '__main__': + raise ImportError() + parent, _, modname = fullname.rpartition('.') if parent: path = sys.modules[parent].__path__ else: path = None + fp, pathname, description = imp.find_module(modname, path) if fp: fp.close() @@ -484,8 +491,9 @@ class Importer(object): # #114: explicitly whitelisted prefixes override any # system-installed package. - if self.whitelist and not is_blacklisted_import(self, fullname): - return self + if self.whitelist != ['']: + if any(fullname.startswith(s) for s in self.whitelist): + return self try: self.builtin_find_module(fullname)