1
0
forked from VimPlug/jedi

Listing modules is no longer done by a subprocess

This commit is contained in:
Dave Halter
2020-03-07 20:24:20 +01:00
parent f147cb1133
commit 6bddca011c
4 changed files with 19 additions and 88 deletions

View File

@@ -11,7 +11,6 @@ import os
import re
import pkgutil
import warnings
import inspect
import subprocess
import weakref
try:
@@ -219,65 +218,6 @@ if the module is contained in a package.
"""
def _iter_modules(paths, prefix=''):
# Copy of pkgutil.iter_modules adapted to work with namespaces
for path in paths:
importer = pkgutil.get_importer(path)
if not isinstance(importer, importlib.machinery.FileFinder):
# We're only modifying the case for FileFinder. All the other cases
# still need to be checked (like zip-importing). Do this by just
# calling the pkgutil version.
for mod_info in pkgutil.iter_modules([path], prefix):
yield mod_info
continue
# START COPY OF pkutils._iter_file_finder_modules.
if importer.path is None or not os.path.isdir(importer.path):
return
yielded = {}
try:
filenames = os.listdir(importer.path)
except OSError:
# ignore unreadable directories like import does
filenames = []
filenames.sort() # handle packages before same-named modules
for fn in filenames:
modname = inspect.getmodulename(fn)
if modname == '__init__' or modname in yielded:
continue
# jedi addition: Avoid traversing special directories
if fn.startswith('.') or fn == '__pycache__':
continue
path = os.path.join(importer.path, fn)
ispkg = False
if not modname and os.path.isdir(path) and '.' not in fn:
modname = fn
# A few jedi modifications: Don't check if there's an
# __init__.py
try:
os.listdir(path)
except OSError:
# ignore unreadable directories like import does
continue
ispkg = True
if modname and '.' not in modname:
yielded[modname] = 1
yield importer, prefix + modname, ispkg
# END COPY
iter_modules = _iter_modules if py_version >= 35 else pkgutil.iter_modules
class ImplicitNSInfo(object):
"""Stores information returned from an implicit namespace spec"""
def __init__(self, name, paths):

View File

@@ -3,7 +3,7 @@ import sys
import os
from jedi._compatibility import find_module, cast_path, force_unicode, \
iter_modules, all_suffixes
all_suffixes
from jedi.inference.compiled import access
from jedi import parser_utils
@@ -40,13 +40,6 @@ def get_module_info(inference_state, sys_path=None, full_name=None, **kwargs):
sys.path = temp
def list_module_names(inference_state, search_path):
return [
force_unicode(name)
for module_loader, name, is_pkg in iter_modules(search_path)
]
def get_builtin_module_names(inference_state):
return list(map(force_unicode, sys.builtin_module_names))

View File

@@ -1,6 +1,7 @@
import re
import os
from jedi._compatibility import scandir
from jedi import debug
from jedi.inference.cache import inference_state_method_cache
from jedi.inference.names import AbstractNameDefinition, ModuleName
@@ -39,26 +40,28 @@ class _ModuleAttributeName(AbstractNameDefinition):
def iter_module_names(inference_state, paths):
# Python modules/packages
for n in inference_state.compiled_subprocess.list_module_names(paths):
yield n
for path in paths:
try:
dirs = os.listdir(path)
dirs = scandir(path)
except OSError:
# The file might not exist or reading it might lead to an error.
debug.warning("Not possible to list directory: %s", path)
continue
for name in dirs:
# Namespaces
if os.path.isdir(os.path.join(path, name)):
for dir_entry in dirs:
name = dir_entry.name
# First Namespaces then modules/stubs
if dir_entry.is_dir():
# pycache is obviously not an interestin namespace. Also the
# name must be a valid identifier.
# TODO use str.isidentifier, once Python 2 is removed
if name != '__pycache__' and not re.search(r'\W|^\d', name):
yield name
else:
if name.endswith('.py'):
if name != '__init__.py':
yield name[:-3]
# Stub files
if name.endswith('.pyi'):
elif name.endswith('.pyi'):
if name != '__init__.pyi':
yield name[:-4]

View File

@@ -76,21 +76,16 @@ def test_load_save_project(tmpdir):
# With namespace
('implicit_namespace_package.ns1.pkg',
['test_inference.implicit_namespace_package.ns1.pkg',
'examples.implicit_namespace_package.ns1.pkg'], {}),
['examples.implicit_namespace_package.ns1.pkg'], {}),
('implicit_namespace_package.ns1.pkg.ns1_file',
['test_inference.implicit_namespace_package.ns1.pkg.ns1_file',
'examples.implicit_namespace_package.ns1.pkg.ns1_file'], {}),
['examples.implicit_namespace_package.ns1.pkg.ns1_file'], {}),
('examples.implicit_namespace_package.ns1.pkg.ns1_file',
['examples.implicit_namespace_package.ns1.pkg.ns1_file'], {}),
('implicit_namespace_package.ns1.pkg.',
['test_inference.implicit_namespace_package.ns1.pkg.ns1_file',
'examples.implicit_namespace_package.ns1.pkg.ns1_file'],
['examples.implicit_namespace_package.ns1.pkg.ns1_file'],
dict(complete=True)),
('implicit_namespace_package.',
['test_inference.implicit_namespace_package.ns1',
'test_inference.implicit_namespace_package.ns2',
'examples.implicit_namespace_package.ns1',
['examples.implicit_namespace_package.ns1',
'examples.implicit_namespace_package.ns2'],
dict(complete=True)),