forked from VimPlug/jedi
Move load_module a bit around
This commit is contained in:
@@ -1,20 +1,9 @@
|
|||||||
import types
|
import types
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
|
|
||||||
from jedi._compatibility import builtins as _builtins
|
from jedi._compatibility import builtins as _builtins
|
||||||
from jedi.evaluate.compiled.context import CompiledObject, CompiledName, \
|
from jedi.evaluate.compiled.context import CompiledObject, CompiledName, \
|
||||||
CompiledObjectFilter, CompiledContextName, create_from_access_path
|
CompiledObjectFilter, CompiledContextName, create_from_access_path
|
||||||
from jedi.evaluate.compiled.access import create_access_path
|
from jedi.evaluate.compiled import access
|
||||||
from jedi import debug
|
|
||||||
|
|
||||||
|
|
||||||
_sep = os.path.sep
|
|
||||||
if os.path.altsep is not None:
|
|
||||||
_sep += os.path.altsep
|
|
||||||
_path_re = re.compile('(?:\.[^{0}]+|[{0}]__init__\.py)$'.format(re.escape(_sep)))
|
|
||||||
del _sep
|
|
||||||
|
|
||||||
|
|
||||||
def builtin_from_name(evaluator, string):
|
def builtin_from_name(evaluator, string):
|
||||||
@@ -33,7 +22,7 @@ def create_simple_object(evaluator, obj):
|
|||||||
|
|
||||||
def create(evaluator, obj):
|
def create(evaluator, obj):
|
||||||
return create_from_access_path(
|
return create_from_access_path(
|
||||||
evaluator, create_access_path(evaluator, obj)
|
evaluator, access.create_access_path(evaluator, obj)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -58,66 +47,7 @@ def get_special_object(evaluator, identifier):
|
|||||||
|
|
||||||
|
|
||||||
def load_module(evaluator, path=None, name=None):
|
def load_module(evaluator, path=None, name=None):
|
||||||
sys_path = list(evaluator.project.sys_path)
|
return create_from_access_path(
|
||||||
if path is not None:
|
evaluator,
|
||||||
dotted_path = dotted_from_fs_path(path, sys_path=sys_path)
|
access.load_module(evaluator, path=path, name=name)
|
||||||
else:
|
)
|
||||||
dotted_path = name
|
|
||||||
|
|
||||||
temp, sys.path = sys.path, sys_path
|
|
||||||
try:
|
|
||||||
__import__(dotted_path)
|
|
||||||
except RuntimeError:
|
|
||||||
if 'PySide' in dotted_path or 'PyQt' in dotted_path:
|
|
||||||
# RuntimeError: the PyQt4.QtCore and PyQt5.QtCore modules both wrap
|
|
||||||
# the QObject class.
|
|
||||||
# See https://github.com/davidhalter/jedi/pull/483
|
|
||||||
return None
|
|
||||||
raise
|
|
||||||
except ImportError:
|
|
||||||
# If a module is "corrupt" or not really a Python module or whatever.
|
|
||||||
debug.warning('Module %s not importable in path %s.', dotted_path, path)
|
|
||||||
return None
|
|
||||||
finally:
|
|
||||||
sys.path = temp
|
|
||||||
|
|
||||||
# Just access the cache after import, because of #59 as well as the very
|
|
||||||
# complicated import structure of Python.
|
|
||||||
module = sys.modules[dotted_path]
|
|
||||||
|
|
||||||
return create(evaluator, module)
|
|
||||||
|
|
||||||
|
|
||||||
def dotted_from_fs_path(fs_path, sys_path):
|
|
||||||
"""
|
|
||||||
Changes `/usr/lib/python3.4/email/utils.py` to `email.utils`. I.e.
|
|
||||||
compares the path with sys.path and then returns the dotted_path. If the
|
|
||||||
path is not in the sys.path, just returns None.
|
|
||||||
"""
|
|
||||||
if os.path.basename(fs_path).startswith('__init__.'):
|
|
||||||
# We are calculating the path. __init__ files are not interesting.
|
|
||||||
fs_path = os.path.dirname(fs_path)
|
|
||||||
|
|
||||||
# prefer
|
|
||||||
# - UNIX
|
|
||||||
# /path/to/pythonX.Y/lib-dynload
|
|
||||||
# /path/to/pythonX.Y/site-packages
|
|
||||||
# - Windows
|
|
||||||
# C:\path\to\DLLs
|
|
||||||
# C:\path\to\Lib\site-packages
|
|
||||||
# over
|
|
||||||
# - UNIX
|
|
||||||
# /path/to/pythonX.Y
|
|
||||||
# - Windows
|
|
||||||
# C:\path\to\Lib
|
|
||||||
path = ''
|
|
||||||
for s in sys_path:
|
|
||||||
if (fs_path.startswith(s) and len(path) < len(s)):
|
|
||||||
path = s
|
|
||||||
|
|
||||||
# - Window
|
|
||||||
# X:\path\to\lib-dynload/datetime.pyd => datetime
|
|
||||||
module_path = fs_path[len(path):].lstrip(os.path.sep).lstrip('/')
|
|
||||||
# - Window
|
|
||||||
# Replace like X:\path\to\something/foo/bar.py
|
|
||||||
return _path_re.sub('', module_path).replace(os.path.sep, '.').replace('/', '.')
|
|
||||||
|
|||||||
@@ -4,8 +4,10 @@ import sys
|
|||||||
import operator as op
|
import operator as op
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
|
from jedi import debug
|
||||||
from jedi._compatibility import unicode, is_py3, is_py34, builtins, py_version
|
from jedi._compatibility import unicode, is_py3, is_py34, builtins, py_version
|
||||||
from jedi.evaluate.compiled.getattr_static import getattr_static
|
from jedi.evaluate.compiled.getattr_static import getattr_static
|
||||||
|
from jedi.evaluate.utils import dotted_from_fs_path
|
||||||
|
|
||||||
|
|
||||||
MethodDescriptorType = type(str.replace)
|
MethodDescriptorType = type(str.replace)
|
||||||
@@ -110,6 +112,36 @@ def create_access(evaluator, obj):
|
|||||||
return DirectObjectAccess(evaluator, obj)
|
return DirectObjectAccess(evaluator, obj)
|
||||||
|
|
||||||
|
|
||||||
|
def load_module(evaluator, path=None, name=None):
|
||||||
|
sys_path = list(evaluator.project.sys_path)
|
||||||
|
if path is not None:
|
||||||
|
dotted_path = dotted_from_fs_path(path, sys_path=sys_path)
|
||||||
|
else:
|
||||||
|
dotted_path = name
|
||||||
|
|
||||||
|
temp, sys.path = sys.path, sys_path
|
||||||
|
try:
|
||||||
|
__import__(dotted_path)
|
||||||
|
except RuntimeError:
|
||||||
|
if 'PySide' in dotted_path or 'PyQt' in dotted_path:
|
||||||
|
# RuntimeError: the PyQt4.QtCore and PyQt5.QtCore modules both wrap
|
||||||
|
# the QObject class.
|
||||||
|
# See https://github.com/davidhalter/jedi/pull/483
|
||||||
|
return None
|
||||||
|
raise
|
||||||
|
except ImportError:
|
||||||
|
# If a module is "corrupt" or not really a Python module or whatever.
|
||||||
|
debug.warning('Module %s not importable in path %s.', dotted_path, path)
|
||||||
|
return None
|
||||||
|
finally:
|
||||||
|
sys.path = temp
|
||||||
|
|
||||||
|
# Just access the cache after import, because of #59 as well as the very
|
||||||
|
# complicated import structure of Python.
|
||||||
|
module = sys.modules[dotted_path]
|
||||||
|
return create_access_path(evaluator, module)
|
||||||
|
|
||||||
|
|
||||||
class AccessPath(object):
|
class AccessPath(object):
|
||||||
def __init__(self, accesses):
|
def __init__(self, accesses):
|
||||||
self.accesses = accesses
|
self.accesses = accesses
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ from jedi.evaluate import sys_path
|
|||||||
from jedi.evaluate import helpers
|
from jedi.evaluate import helpers
|
||||||
from jedi.evaluate import compiled
|
from jedi.evaluate import compiled
|
||||||
from jedi.evaluate import analysis
|
from jedi.evaluate import analysis
|
||||||
from jedi.evaluate.utils import unite
|
from jedi.evaluate.utils import unite, dotted_from_fs_path
|
||||||
from jedi.evaluate.cache import evaluator_method_cache
|
from jedi.evaluate.cache import evaluator_method_cache
|
||||||
from jedi.evaluate.filters import AbstractNameDefinition
|
from jedi.evaluate.filters import AbstractNameDefinition
|
||||||
from jedi.evaluate.base_context import ContextSet, NO_CONTEXTS
|
from jedi.evaluate.base_context import ContextSet, NO_CONTEXTS
|
||||||
@@ -481,7 +481,7 @@ def _load_module(evaluator, path=None, code=None, sys_path=None, parent_module=N
|
|||||||
if sys_path is None:
|
if sys_path is None:
|
||||||
sys_path = evaluator.project.sys_path
|
sys_path = evaluator.project.sys_path
|
||||||
|
|
||||||
dotted_path = path and compiled.dotted_from_fs_path(path, sys_path)
|
dotted_path = path and dotted_from_fs_path(path, sys_path)
|
||||||
if path is not None and path.endswith(('.py', '.zip', '.egg')) \
|
if path is not None and path.endswith(('.py', '.zip', '.egg')) \
|
||||||
and dotted_path not in settings.auto_import_modules:
|
and dotted_path not in settings.auto_import_modules:
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,19 @@
|
|||||||
import sys
|
import sys
|
||||||
import contextlib
|
import contextlib
|
||||||
import functools
|
import functools
|
||||||
|
import re
|
||||||
|
import os
|
||||||
|
|
||||||
from jedi._compatibility import reraise
|
from jedi._compatibility import reraise
|
||||||
|
|
||||||
|
|
||||||
|
_sep = os.path.sep
|
||||||
|
if os.path.altsep is not None:
|
||||||
|
_sep += os.path.altsep
|
||||||
|
_path_re = re.compile('(?:\.[^{0}]+|[{0}]__init__\.py)$'.format(re.escape(_sep)))
|
||||||
|
del _sep
|
||||||
|
|
||||||
|
|
||||||
def to_list(func):
|
def to_list(func):
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
return list(func(*args, **kwargs))
|
return list(func(*args, **kwargs))
|
||||||
@@ -108,3 +117,38 @@ def indent_block(text, indention=' '):
|
|||||||
text = text[:-1]
|
text = text[:-1]
|
||||||
lines = text.split('\n')
|
lines = text.split('\n')
|
||||||
return '\n'.join(map(lambda s: indention + s, lines)) + temp
|
return '\n'.join(map(lambda s: indention + s, lines)) + temp
|
||||||
|
|
||||||
|
|
||||||
|
def dotted_from_fs_path(fs_path, sys_path):
|
||||||
|
"""
|
||||||
|
Changes `/usr/lib/python3.4/email/utils.py` to `email.utils`. I.e.
|
||||||
|
compares the path with sys.path and then returns the dotted_path. If the
|
||||||
|
path is not in the sys.path, just returns None.
|
||||||
|
"""
|
||||||
|
if os.path.basename(fs_path).startswith('__init__.'):
|
||||||
|
# We are calculating the path. __init__ files are not interesting.
|
||||||
|
fs_path = os.path.dirname(fs_path)
|
||||||
|
|
||||||
|
# prefer
|
||||||
|
# - UNIX
|
||||||
|
# /path/to/pythonX.Y/lib-dynload
|
||||||
|
# /path/to/pythonX.Y/site-packages
|
||||||
|
# - Windows
|
||||||
|
# C:\path\to\DLLs
|
||||||
|
# C:\path\to\Lib\site-packages
|
||||||
|
# over
|
||||||
|
# - UNIX
|
||||||
|
# /path/to/pythonX.Y
|
||||||
|
# - Windows
|
||||||
|
# C:\path\to\Lib
|
||||||
|
path = ''
|
||||||
|
for s in sys_path:
|
||||||
|
if (fs_path.startswith(s) and len(path) < len(s)):
|
||||||
|
path = s
|
||||||
|
|
||||||
|
# - Window
|
||||||
|
# X:\path\to\lib-dynload/datetime.pyd => datetime
|
||||||
|
module_path = fs_path[len(path):].lstrip(os.path.sep).lstrip('/')
|
||||||
|
# - Window
|
||||||
|
# Replace like X:\path\to\something/foo/bar.py
|
||||||
|
return _path_re.sub('', module_path).replace(os.path.sep, '.').replace('/', '.')
|
||||||
|
|||||||
Reference in New Issue
Block a user