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 causing Mitogen to install itself at the end of the importer chain rather
than the front. 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 * `#349 <https://github.com/dw/mitogen/issues/349>`_: an incorrect format
string could cause large stack traces when attempting to import built-in string could cause large stack traces when attempting to import built-in
modules on Python 3. 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>`_, `Duane Zamrok <https://github.com/dewthefifth>`_,
`Eric Chang <https://github.com/changchichung>`_, `Eric Chang <https://github.com/changchichung>`_,
`Guy Knights <https://github.com/knightsg>`_, `Guy Knights <https://github.com/knightsg>`_,
`Jesse London <https://github.com/jesteria>`_,
`Jiří Vávra <https://github.com/Houbovo>`_, `Jiří Vávra <https://github.com/Houbovo>`_,
`Jonathan Rosser <https://github.com/jrosser>`_, `Jonathan Rosser <https://github.com/jrosser>`_,
`Johan Beisser <https://github.com/jbeisser>`_, `Johan Beisser <https://github.com/jbeisser>`_,

@ -453,8 +453,28 @@ class ModuleFinder(object):
return path, source, is_pkg 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_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): def get_module_source(self, fullname):
"""Given the name of a loaded module `fullname`, attempt to find its """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) 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): class ResolveRelPathTest(testlib.TestCase):
klass = mitogen.master.ModuleFinder klass = mitogen.master.ModuleFinder

Loading…
Cancel
Save