master: handle crazy non-modules in sys.modules again; closes #310.

issue510
David Wilson 6 years ago
parent c1980aac6b
commit 6af1a64cce

@ -246,6 +246,11 @@ Core Library
causing Mitogen to install itself at the end of the importer chain rather
than the front.
* `#310 <https://github.com/dw/mitogen/issues/310>`_: support has returned for
trying to figure out the real source of non-module objects installed in
:data:`sys.modules`, so they can be imported. This is needed to handle syntax
sugar used by packages like :mod:`plumbum`.
* `#349 <https://github.com/dw/mitogen/issues/349>`_: an incorrect format
string could cause large stack traces when attempting to import built-in
modules on Python 3.
@ -387,6 +392,7 @@ bug reports, testing, features and fixes in this release contributed by
`Duane Zamrok <https://github.com/dewthefifth>`_,
`Eric Chang <https://github.com/changchichung>`_,
`Guy Knights <https://github.com/knightsg>`_,
`Jesse London <https://github.com/jesteria>`_,
`Jiří Vávra <https://github.com/Houbovo>`_,
`Jonathan Rosser <https://github.com/jrosser>`_,
`Johan Beisser <https://github.com/jbeisser>`_,

@ -453,8 +453,28 @@ class ModuleFinder(object):
return path, source, is_pkg
def _get_module_via_parent_enumeration(self, fullname):
"""
Attempt to fetch source code by examining the module's (hopefully less
insane) parent package. Required for older versions of
ansible.compat.six and plumbum.colors.
"""
pkgname, _, modname = fullname.rpartition('.')
pkg = sys.modules.get(pkgname)
if pkg is None or not hasattr(pkg, '__file__'):
return
pkg_path = os.path.dirname(pkg.__file__)
try:
fp, path, ext = imp.find_module(modname, [pkg_path])
return path, fp.read().encode('utf-8'), False
except ImportError:
e = sys.exc_info()[1]
LOG.debug('imp.find_module(%r, %r) -> %s', modname, [pkg_path], e)
get_module_methods = [_get_module_via_pkgutil,
_get_module_via_sys_modules]
_get_module_via_sys_modules,
_get_module_via_parent_enumeration]
def get_module_source(self, fullname):
"""Given the name of a loaded module `fullname`, attempt to find its

@ -0,0 +1,11 @@
import sys
class EvilObject(object):
"""
Wild cackles! I have come to confuse perplex your importer with rainbows!
"""
sys.modules[__name__] = EvilObject()

@ -105,6 +105,39 @@ class GetModuleViaSysModulesTest(testlib.TestCase):
self.assertIsNone(tup)
class GetModuleViaParentEnumerationTest(testlib.TestCase):
klass = mitogen.master.ModuleFinder
def call(self, fullname):
return self.klass()._get_module_via_parent_enumeration(fullname)
def test_main_fails(self):
import __main__
self.assertIsNone(self.call('__main__'))
def test_dylib_fails(self):
# _socket comes from a .so
import _socket
tup = self.call('_socket')
self.assertIsNone(tup)
def test_builtin_fails(self):
# sys is built-in
tup = self.call('sys')
self.assertIsNone(tup)
def test_plumbum_colors_like_pkg_succeeds(self):
# plumbum has been eating too many rainbow-colored pills
import pkg_like_plumbum.colors
path, src, is_pkg = self.call('pkg_like_plumbum.colors')
self.assertEquals(path,
testlib.data_path('pkg_like_plumbum/colors.py'))
s = open(testlib.data_path('pkg_like_plumbum/colors.py')).read()
self.assertEquals(mitogen.core.to_text(src), s)
self.assertFalse(is_pkg)
class ResolveRelPathTest(testlib.TestCase):
klass = mitogen.master.ModuleFinder

Loading…
Cancel
Save