lost reference to source file name fixed. Test suit updated

This commit is contained in:
hkm 2019-12-15 20:28:02 +03:00
parent da5cf1b66e
commit fa5cf6fcdc
3 changed files with 15 additions and 15 deletions

View File

@ -63,10 +63,10 @@ class ModuleAnalyzer:
return entry return entry
try: try:
type, source = get_module_source(modname) filename, source = get_module_source(modname)
if type == 'string': if source is not None:
obj = cls.for_string(source, modname) obj = cls.for_string(source, modname, filename if filename is not None else '<string>')
else: elif filename is not None:
obj = cls.for_file(source, modname) obj = cls.for_file(source, modname)
except PycodeError as err: except PycodeError as err:
cls.cache['module', modname] = err cls.cache['module', modname] = err

View File

@ -25,7 +25,7 @@ from hashlib import md5
from importlib import import_module from importlib import import_module
from os import path from os import path
from time import mktime, strptime from time import mktime, strptime
from typing import Any, Callable, Dict, IO, Iterable, Iterator, List, Pattern, Set, Tuple from typing import Any, Callable, Dict, IO, Iterable, Iterator, List, Pattern, Set, Tuple, Optional
from urllib.parse import urlsplit, urlunsplit, quote_plus, parse_qsl, urlencode from urllib.parse import urlsplit, urlunsplit, quote_plus, parse_qsl, urlencode
from docutils.utils import relative_path from docutils.utils import relative_path
@ -265,27 +265,27 @@ def save_traceback(app: "Sphinx") -> str:
return path return path
def get_module_source(modname: str) -> Tuple[str, str]: def get_module_source(modname: str) -> Tuple[Optional[str], Optional[str]]:
"""Try to find the source code for a module. """Try to find the source code for a module.
Can return ('file', 'filename') in which case the source is in the given Returns ('filename', 'source'). One of it can be None if
file, or ('string', 'source') which which case the source is the string. no filename or source found
""" """
try: try:
mod = import_module(modname) mod = import_module(modname)
except Exception as err: except Exception as err:
raise PycodeError('error importing %r' % modname, err) raise PycodeError('error importing %r' % modname, err)
loader = getattr(mod, '__loader__', None) loader = getattr(mod, '__loader__', None)
filename = getattr(mod, '__file__', None)
if loader and getattr(loader, 'get_source', None): if loader and getattr(loader, 'get_source', None):
# prefer Native loader, as it respects #coding directive # prefer Native loader, as it respects #coding directive
try: try:
filename = loader.get_source(modname) source = loader.get_source(modname)
if filename: if source:
# no exception and not None - it must be module source # no exception and not None - it must be module source
return 'string', filename return filename, source
except ImportError as err: except ImportError as err:
pass # Try other "source-mining" methods pass # Try other "source-mining" methods
filename = getattr(mod, '__file__', None)
if filename is None and loader and getattr(loader, 'get_filename', None): if filename is None and loader and getattr(loader, 'get_filename', None):
# have loader, but no filename # have loader, but no filename
try: try:
@ -307,11 +307,11 @@ def get_module_source(modname: str) -> Tuple[str, str]:
pat = '(?<=\\.egg)' + re.escape(os.path.sep) pat = '(?<=\\.egg)' + re.escape(os.path.sep)
eggpath, _ = re.split(pat, filename, 1) eggpath, _ = re.split(pat, filename, 1)
if path.isfile(eggpath): if path.isfile(eggpath):
return 'file', filename return filename, None
if not path.isfile(filename): if not path.isfile(filename):
raise PycodeError('source file is not present: %r' % filename) raise PycodeError('source file is not present: %r' % filename)
return 'file', filename return filename, None
def get_full_modname(modname: str, attribute: str) -> str: def get_full_modname(modname: str, attribute: str) -> str:

View File

@ -62,7 +62,7 @@ def test_display_chunk():
def test_get_module_source(): def test_get_module_source():
assert get_module_source('sphinx') == ('file', sphinx.__file__) assert get_module_source('sphinx') == (sphinx.__file__, sphinx.__loader__.get_source('sphinx'))
# failed to obtain source information from builtin modules # failed to obtain source information from builtin modules
with pytest.raises(PycodeError): with pytest.raises(PycodeError):