diff options
Diffstat (limited to 'sphinx/pycode/__init__.py')
-rw-r--r-- | sphinx/pycode/__init__.py | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/sphinx/pycode/__init__.py b/sphinx/pycode/__init__.py index c4c055bf5..a97903a27 100644 --- a/sphinx/pycode/__init__.py +++ b/sphinx/pycode/__init__.py @@ -10,6 +10,9 @@ """ from __future__ import print_function +import re +from zipfile import ZipFile + from six import iteritems, BytesIO, StringIO from sphinx.errors import PycodeError @@ -42,10 +45,24 @@ class ModuleAnalyzer(object): obj = cls(f, modname, filename) # type: ignore cls.cache['file', filename] = obj except Exception as err: - raise PycodeError('error opening %r' % filename, err) + if '.egg/' in filename: + obj = cls.cache['file', filename] = cls.for_egg(filename, modname) + else: + raise PycodeError('error opening %r' % filename, err) return obj @classmethod + def for_egg(cls, filename, modname): + # type: (unicode, unicode) -> ModuleAnalyzer + eggpath, relpath = re.split('(?<=\\.egg)/', filename) + try: + with ZipFile(eggpath) as egg: + code = egg.read(relpath).decode('utf-8') + return cls.for_string(code, modname, filename) + except Exception as exc: + raise PycodeError('error opening %r' % filename, exc) + + @classmethod def for_module(cls, modname): # type: (str) -> ModuleAnalyzer if ('module', modname) in cls.cache: |