forked from VimPlug/jedi
Implement all remaining Path issues and use it instead of strings
This commit is contained in:
@@ -20,7 +20,7 @@ def cast_path(string):
|
|||||||
"""
|
"""
|
||||||
if isinstance(string, bytes):
|
if isinstance(string, bytes):
|
||||||
return str(string, encoding='UTF-8', errors='replace')
|
return str(string, encoding='UTF-8', errors='replace')
|
||||||
return string
|
return str(string)
|
||||||
|
|
||||||
|
|
||||||
def pickle_load(file):
|
def pickle_load(file):
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ class Script(object):
|
|||||||
|
|
||||||
if project is None:
|
if project is None:
|
||||||
# Load the Python grammar of the current interpreter.
|
# Load the Python grammar of the current interpreter.
|
||||||
project = get_default_project(self.path)
|
project = get_default_project(None if self.path is None else self.path.parent)
|
||||||
# TODO deprecate and remove sys_path from the Script API.
|
# TODO deprecate and remove sys_path from the Script API.
|
||||||
if sys_path is not None:
|
if sys_path is not None:
|
||||||
project._sys_path = sys_path
|
project._sys_path = sys_path
|
||||||
@@ -192,7 +192,7 @@ class Script(object):
|
|||||||
file_io = None
|
file_io = None
|
||||||
else:
|
else:
|
||||||
file_io = KnownContentFileIO(cast_path(self.path), self._code)
|
file_io = KnownContentFileIO(cast_path(self.path), self._code)
|
||||||
if self.path is not None and self.path.suffix == 'pyi':
|
if self.path is not None and self.path.suffix == '.pyi':
|
||||||
# We are in a stub file. Try to load the stub properly.
|
# We are in a stub file. Try to load the stub properly.
|
||||||
stub_module = load_proper_stub_module(
|
stub_module = load_proper_stub_module(
|
||||||
self._inference_state,
|
self._inference_state,
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ the interesting information about all operations.
|
|||||||
"""
|
"""
|
||||||
import re
|
import re
|
||||||
import warnings
|
import warnings
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from parso.python.tree import search_ancestor
|
from parso.python.tree import search_ancestor
|
||||||
|
|
||||||
@@ -92,7 +93,7 @@ class BaseName(object):
|
|||||||
return self._name.get_root_context()
|
return self._name.get_root_context()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def module_path(self):
|
def module_path(self) -> Optional[str]:
|
||||||
"""
|
"""
|
||||||
Shows the file path of a module. e.g. ``/usr/lib/python3.9/os.py``
|
Shows the file path of a module. e.g. ``/usr/lib/python3.9/os.py``
|
||||||
|
|
||||||
@@ -102,7 +103,9 @@ class BaseName(object):
|
|||||||
if module.is_stub() or not module.is_compiled():
|
if module.is_stub() or not module.is_compiled():
|
||||||
# Compiled modules should not return a module path even if they
|
# Compiled modules should not return a module path even if they
|
||||||
# have one.
|
# have one.
|
||||||
return self._get_module_context().py__file__()
|
path = self._get_module_context().py__file__()
|
||||||
|
if path is not None:
|
||||||
|
return path
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ def match(string, like_name, fuzzy=False):
|
|||||||
|
|
||||||
def sorted_definitions(defs):
|
def sorted_definitions(defs):
|
||||||
# Note: `or ''` below is required because `module_path` could be
|
# Note: `or ''` below is required because `module_path` could be
|
||||||
return sorted(defs, key=lambda x: (str(x.module_path) or '',
|
return sorted(defs, key=lambda x: (str(x.module_path or ''),
|
||||||
x.line or 0,
|
x.line or 0,
|
||||||
x.column or 0,
|
x.column or 0,
|
||||||
x.name))
|
x.name))
|
||||||
|
|||||||
@@ -80,6 +80,8 @@ class Project(object):
|
|||||||
|
|
||||||
:param path: The path of the directory you want to use as a project.
|
:param path: The path of the directory you want to use as a project.
|
||||||
"""
|
"""
|
||||||
|
if isinstance(path, str):
|
||||||
|
path = Path(path)
|
||||||
with open(cls._get_json_path(path)) as f:
|
with open(cls._get_json_path(path)) as f:
|
||||||
version, data = json.load(f)
|
version, data = json.load(f)
|
||||||
|
|
||||||
@@ -98,8 +100,9 @@ class Project(object):
|
|||||||
data.pop('_environment', None)
|
data.pop('_environment', None)
|
||||||
data.pop('_django', None) # TODO make django setting public?
|
data.pop('_django', None) # TODO make django setting public?
|
||||||
data = {k.lstrip('_'): v for k, v in data.items()}
|
data = {k.lstrip('_'): v for k, v in data.items()}
|
||||||
|
data['path'] = str(data['path'])
|
||||||
|
|
||||||
self._path.mkdir(parents=True, exist_ok=True)
|
self._get_config_folder_path(self._path).mkdir(parents=True, exist_ok=True)
|
||||||
with open(self._get_json_path(self._path), 'w') as f:
|
with open(self._get_json_path(self._path), 'w') as f:
|
||||||
return json.dump((_SERIALIZER_VERSION, data), f)
|
return json.dump((_SERIALIZER_VERSION, data), f)
|
||||||
|
|
||||||
@@ -129,11 +132,15 @@ class Project(object):
|
|||||||
self._path = path
|
self._path = path
|
||||||
|
|
||||||
self._environment_path = environment_path
|
self._environment_path = environment_path
|
||||||
|
if sys_path is not None:
|
||||||
|
# Remap potential pathlib.Path entries
|
||||||
|
sys_path = list(map(str, sys_path))
|
||||||
self._sys_path = sys_path
|
self._sys_path = sys_path
|
||||||
self._smart_sys_path = smart_sys_path
|
self._smart_sys_path = smart_sys_path
|
||||||
self._load_unsafe_extensions = load_unsafe_extensions
|
self._load_unsafe_extensions = load_unsafe_extensions
|
||||||
self._django = False
|
self._django = False
|
||||||
self.added_sys_path = list(added_sys_path)
|
# Remap potential pathlib.Path entries
|
||||||
|
self.added_sys_path = list(map(str, added_sys_path))
|
||||||
"""The sys path that is going to be added at the end of the """
|
"""The sys path that is going to be added at the end of the """
|
||||||
|
|
||||||
py2_comp(path, **kwargs)
|
py2_comp(path, **kwargs)
|
||||||
@@ -173,10 +180,10 @@ class Project(object):
|
|||||||
prefixed.append(str(self._path))
|
prefixed.append(str(self._path))
|
||||||
|
|
||||||
if inference_state.script_path is not None:
|
if inference_state.script_path is not None:
|
||||||
suffixed += discover_buildout_paths(
|
suffixed += map(str, discover_buildout_paths(
|
||||||
inference_state,
|
inference_state,
|
||||||
inference_state.script_path
|
inference_state.script_path
|
||||||
)
|
))
|
||||||
|
|
||||||
if add_parent_paths:
|
if add_parent_paths:
|
||||||
# Collect directories in upward search by:
|
# Collect directories in upward search by:
|
||||||
@@ -362,6 +369,8 @@ def get_default_project(path=None):
|
|||||||
"""
|
"""
|
||||||
if path is None:
|
if path is None:
|
||||||
path = Path.cwd()
|
path = Path.cwd()
|
||||||
|
elif isinstance(path, str):
|
||||||
|
path = Path(path)
|
||||||
|
|
||||||
check = path.absolute()
|
check = path.absolute()
|
||||||
probable_path = None
|
probable_path = None
|
||||||
@@ -379,7 +388,7 @@ def get_default_project(path=None):
|
|||||||
# In the case that a __init__.py exists, it's in 99% just a
|
# In the case that a __init__.py exists, it's in 99% just a
|
||||||
# Python package and the project sits at least one level above.
|
# Python package and the project sits at least one level above.
|
||||||
continue
|
continue
|
||||||
else:
|
elif not dir.is_file():
|
||||||
first_no_init_file = dir
|
first_no_init_file = dir
|
||||||
|
|
||||||
if _is_django_path(dir):
|
if _is_django_path(dir):
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import difflib
|
import difflib
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Dict
|
||||||
|
|
||||||
from parso import split_lines
|
from parso import split_lines
|
||||||
|
|
||||||
@@ -47,8 +49,8 @@ class ChangedFile(object):
|
|||||||
to_p = self._to_path.relative_to(project_path)
|
to_p = self._to_path.relative_to(project_path)
|
||||||
diff = difflib.unified_diff(
|
diff = difflib.unified_diff(
|
||||||
old_lines, new_lines,
|
old_lines, new_lines,
|
||||||
fromfile=from_p,
|
fromfile=str(from_p),
|
||||||
tofile=to_p,
|
tofile=str(to_p),
|
||||||
)
|
)
|
||||||
# Apparently there's a space at the end of the diff - for whatever
|
# Apparently there's a space at the end of the diff - for whatever
|
||||||
# reason.
|
# reason.
|
||||||
@@ -76,17 +78,15 @@ class Refactoring(object):
|
|||||||
self._renames = renames
|
self._renames = renames
|
||||||
self._file_to_node_changes = file_to_node_changes
|
self._file_to_node_changes = file_to_node_changes
|
||||||
|
|
||||||
def get_changed_files(self):
|
def get_changed_files(self) -> Dict[Path, ChangedFile]:
|
||||||
"""
|
|
||||||
Returns a path to ``ChangedFile`` map.
|
|
||||||
"""
|
|
||||||
def calculate_to_path(p):
|
def calculate_to_path(p):
|
||||||
if p is None:
|
if p is None:
|
||||||
return p
|
return p
|
||||||
|
p = str(p)
|
||||||
for from_, to in renames:
|
for from_, to in renames:
|
||||||
if p.startswith(from_):
|
if p.startswith(str(from_)):
|
||||||
p = to + p[len(from_):]
|
p = str(to) + p[len(str(from_)):]
|
||||||
return p
|
return Path(p)
|
||||||
|
|
||||||
renames = self.get_renames()
|
renames = self.get_renames()
|
||||||
return {
|
return {
|
||||||
@@ -144,7 +144,8 @@ def rename(inference_state, definitions, new_name):
|
|||||||
for d in definitions:
|
for d in definitions:
|
||||||
tree_name = d._name.tree_name
|
tree_name = d._name.tree_name
|
||||||
if d.type == 'module' and tree_name is None:
|
if d.type == 'module' and tree_name is None:
|
||||||
file_renames.add(_calculate_rename(d.module_path, new_name))
|
p = None if d.module_path is None else Path(d.module_path)
|
||||||
|
file_renames.add(_calculate_rename(p, new_name))
|
||||||
else:
|
else:
|
||||||
# This private access is ok in a way. It's not public to
|
# This private access is ok in a way. It's not public to
|
||||||
# protect Jedi users from seeing it.
|
# protect Jedi users from seeing it.
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ Imitate the parser representation.
|
|||||||
import re
|
import re
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from inspect import Parameter
|
from inspect import Parameter
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi.inference.utils import to_list
|
from jedi.inference.utils import to_list
|
||||||
@@ -312,7 +313,10 @@ class CompiledModule(CompiledValue):
|
|||||||
return tuple(name.split('.'))
|
return tuple(name.split('.'))
|
||||||
|
|
||||||
def py__file__(self):
|
def py__file__(self):
|
||||||
return cast_path(self.access_handle.py__file__())
|
path = cast_path(self.access_handle.py__file__())
|
||||||
|
if path is None:
|
||||||
|
return None
|
||||||
|
return Path(path)
|
||||||
|
|
||||||
|
|
||||||
class CompiledName(AbstractNameDefinition):
|
class CompiledName(AbstractNameDefinition):
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import os
|
|||||||
import re
|
import re
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from jedi import settings
|
from jedi import settings
|
||||||
from jedi.file_io import FileIO
|
from jedi.file_io import FileIO
|
||||||
@@ -11,10 +12,10 @@ from jedi.inference.base_value import ValueSet, NO_VALUES
|
|||||||
from jedi.inference.gradual.stub_value import TypingModuleWrapper, StubModuleValue
|
from jedi.inference.gradual.stub_value import TypingModuleWrapper, StubModuleValue
|
||||||
from jedi.inference.value import ModuleValue
|
from jedi.inference.value import ModuleValue
|
||||||
|
|
||||||
_jedi_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
_jedi_path = Path(__file__).parent.parent.parent
|
||||||
TYPESHED_PATH = os.path.join(_jedi_path, 'third_party', 'typeshed')
|
TYPESHED_PATH = _jedi_path.joinpath('third_party', 'typeshed')
|
||||||
DJANGO_INIT_PATH = os.path.join(_jedi_path, 'third_party', 'django-stubs',
|
DJANGO_INIT_PATH = _jedi_path.joinpath('third_party', 'django-stubs',
|
||||||
'django-stubs', '__init__.pyi')
|
'django-stubs', '__init__.pyi')
|
||||||
|
|
||||||
_IMPORT_MAP = dict(
|
_IMPORT_MAP = dict(
|
||||||
_collections='collections',
|
_collections='collections',
|
||||||
@@ -60,7 +61,7 @@ def _create_stub_map(directory_path_info):
|
|||||||
def _get_typeshed_directories(version_info):
|
def _get_typeshed_directories(version_info):
|
||||||
check_version_list = ['2and3', '3']
|
check_version_list = ['2and3', '3']
|
||||||
for base in ['stdlib', 'third_party']:
|
for base in ['stdlib', 'third_party']:
|
||||||
base_path = os.path.join(TYPESHED_PATH, base)
|
base_path = TYPESHED_PATH.joinpath(base)
|
||||||
base_list = os.listdir(base_path)
|
base_list = os.listdir(base_path)
|
||||||
for base_list_entry in base_list:
|
for base_list_entry in base_list:
|
||||||
match = re.match(r'(\d+)\.(\d+)$', base_list_entry)
|
match = re.match(r'(\d+)\.(\d+)$', base_list_entry)
|
||||||
@@ -70,7 +71,7 @@ def _get_typeshed_directories(version_info):
|
|||||||
|
|
||||||
for check_version in check_version_list:
|
for check_version in check_version_list:
|
||||||
is_third_party = base != 'stdlib'
|
is_third_party = base != 'stdlib'
|
||||||
yield PathInfo(os.path.join(base_path, check_version), is_third_party)
|
yield PathInfo(str(base_path.joinpath(check_version)), is_third_party)
|
||||||
|
|
||||||
|
|
||||||
_version_cache = {}
|
_version_cache = {}
|
||||||
@@ -181,7 +182,7 @@ def _try_to_load_stub(inference_state, import_names, python_value_set,
|
|||||||
return _try_to_load_stub_from_file(
|
return _try_to_load_stub_from_file(
|
||||||
inference_state,
|
inference_state,
|
||||||
python_value_set,
|
python_value_set,
|
||||||
file_io=FileIO(DJANGO_INIT_PATH),
|
file_io=FileIO(str(DJANGO_INIT_PATH)),
|
||||||
import_names=import_names,
|
import_names=import_names,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from jedi.inference.gradual.typeshed import TYPESHED_PATH, create_stub_module
|
from jedi.inference.gradual.typeshed import TYPESHED_PATH, create_stub_module
|
||||||
|
|
||||||
@@ -9,14 +10,18 @@ def load_proper_stub_module(inference_state, file_io, import_names, module_node)
|
|||||||
module.
|
module.
|
||||||
"""
|
"""
|
||||||
path = file_io.path
|
path = file_io.path
|
||||||
assert path.endswith('.pyi')
|
path = Path(path)
|
||||||
if path.startswith(TYPESHED_PATH):
|
assert path.suffix == '.pyi'
|
||||||
# /foo/stdlib/3/os/__init__.pyi -> stdlib/3/os/__init__
|
try:
|
||||||
rest = path[len(TYPESHED_PATH) + 1: -4]
|
relative_path = path.relative_to(TYPESHED_PATH)
|
||||||
split_paths = tuple(rest.split(os.path.sep))
|
except ValueError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# /[...]/stdlib/3/os/__init__.pyi -> stdlib/3/os/__init__
|
||||||
|
rest = relative_path.with_suffix('')
|
||||||
# Remove the stdlib/3 or third_party/3.6 part
|
# Remove the stdlib/3 or third_party/3.6 part
|
||||||
import_names = split_paths[2:]
|
import_names = rest.parts[2:]
|
||||||
if import_names[-1] == '__init__':
|
if rest.name == '__init__':
|
||||||
import_names = import_names[:-1]
|
import_names = import_names[:-1]
|
||||||
|
|
||||||
if import_names is not None:
|
if import_names is not None:
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ def discover_buildout_paths(inference_state, script_path):
|
|||||||
|
|
||||||
|
|
||||||
def _get_paths_from_buildout_script(inference_state, buildout_script_path):
|
def _get_paths_from_buildout_script(inference_state, buildout_script_path):
|
||||||
file_io = FileIO(buildout_script_path)
|
file_io = FileIO(str(buildout_script_path))
|
||||||
try:
|
try:
|
||||||
module_node = inference_state.parse(
|
module_node = inference_state.parse(
|
||||||
file_io=file_io,
|
file_io=file_io,
|
||||||
@@ -164,7 +164,7 @@ def _get_paths_from_buildout_script(inference_state, buildout_script_path):
|
|||||||
inference_state, module_node,
|
inference_state, module_node,
|
||||||
file_io=file_io,
|
file_io=file_io,
|
||||||
string_names=None,
|
string_names=None,
|
||||||
code_lines=get_cached_code_lines(inference_state.grammar, buildout_script_path),
|
code_lines=get_cached_code_lines(inference_state.grammar, str(buildout_script_path)),
|
||||||
).as_context()
|
).as_context()
|
||||||
for path in check_sys_path_modifications(module_context):
|
for path in check_sys_path_modifications(module_context):
|
||||||
yield path
|
yield path
|
||||||
@@ -228,6 +228,8 @@ def transform_path_to_dotted(sys_path, module_path):
|
|||||||
"""
|
"""
|
||||||
# First remove the suffix.
|
# First remove the suffix.
|
||||||
module_path = remove_python_path_suffix(module_path)
|
module_path = remove_python_path_suffix(module_path)
|
||||||
|
if module_path.name.startswith('.'):
|
||||||
|
return None, False
|
||||||
|
|
||||||
# Once the suffix was removed we are using the files as we know them. This
|
# Once the suffix was removed we are using the files as we know them. This
|
||||||
# means that if someone uses an ending like .vim for a Python file, .vim
|
# means that if someone uses an ending like .vim for a Python file, .vim
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from parso.python.tree import search_ancestor
|
from parso.python.tree import search_ancestor
|
||||||
from jedi.inference.cache import inference_state_method_cache
|
from jedi.inference.cache import inference_state_method_cache
|
||||||
from jedi.inference.imports import load_module_from_path
|
from jedi.inference.imports import load_module_from_path
|
||||||
@@ -128,7 +130,7 @@ def _iter_pytest_modules(module_context, skip_own_module=False):
|
|||||||
sys_path = module_context.inference_state.get_sys_path()
|
sys_path = module_context.inference_state.get_sys_path()
|
||||||
while any(folder.path.startswith(p) for p in sys_path):
|
while any(folder.path.startswith(p) for p in sys_path):
|
||||||
file_io = folder.get_file_io('conftest.py')
|
file_io = folder.get_file_io('conftest.py')
|
||||||
if file_io.path != module_context.py__file__():
|
if Path(file_io.path) != module_context.py__file__():
|
||||||
try:
|
try:
|
||||||
m = load_module_from_path(module_context.inference_state, file_io)
|
m = load_module_from_path(module_context.inference_state, file_io)
|
||||||
yield m.as_context()
|
yield m.as_context()
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ from contextlib import contextmanager
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import pytest
|
import pytest
|
||||||
from os.path import abspath, dirname, join
|
|
||||||
from functools import partial, wraps
|
from functools import partial, wraps
|
||||||
from jedi import Project
|
from jedi import Project
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
test_dir = dirname(abspath(__file__))
|
test_dir = Path(__file__).absolute().parent
|
||||||
test_dir_project = Project(test_dir)
|
test_dir_project = Project(test_dir)
|
||||||
root_dir = dirname(test_dir)
|
root_dir = test_dir.parent
|
||||||
example_dir = join(test_dir, 'examples')
|
example_dir = test_dir.joinpath('examples')
|
||||||
|
|
||||||
sample_int = 1 # This is used in completion/imports.py
|
sample_int = 1 # This is used in completion/imports.py
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ skip_if_not_windows = partial(pytest.param,
|
|||||||
|
|
||||||
|
|
||||||
def get_example_dir(*names):
|
def get_example_dir(*names):
|
||||||
return join(example_dir, *names)
|
return example_dir.joinpath(*names)
|
||||||
|
|
||||||
|
|
||||||
def cwd_at(path):
|
def cwd_at(path):
|
||||||
@@ -46,10 +46,10 @@ def cwd_at(path):
|
|||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def set_cwd(path, absolute_path=False):
|
def set_cwd(path, absolute_path=False):
|
||||||
repo_root = os.path.dirname(test_dir)
|
repo_root = test_dir.parent
|
||||||
|
|
||||||
oldcwd = os.getcwd()
|
oldcwd = Path.cwd()
|
||||||
os.chdir(os.path.join(repo_root, path))
|
os.chdir(repo_root.joinpath(path))
|
||||||
try:
|
try:
|
||||||
yield
|
yield
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ def test_preload_modules():
|
|||||||
# Filter the typeshed parser cache.
|
# Filter the typeshed parser cache.
|
||||||
typeshed_cache_count = sum(
|
typeshed_cache_count = sum(
|
||||||
1 for path in grammar_cache
|
1 for path in grammar_cache
|
||||||
if path is not None and path.startswith(typeshed.TYPESHED_PATH)
|
if path is not None and str(path).startswith(str(typeshed.TYPESHED_PATH))
|
||||||
)
|
)
|
||||||
# +1 for None module (currently used)
|
# +1 for None module (currently used)
|
||||||
assert len(grammar_cache) - typeshed_cache_count == len(modules) + 1
|
assert len(grammar_cache) - typeshed_cache_count == len(modules) + 1
|
||||||
@@ -210,11 +210,11 @@ def test_goto_follow_imports(Script):
|
|||||||
import inspect
|
import inspect
|
||||||
inspect.isfunction""")
|
inspect.isfunction""")
|
||||||
definition, = Script(code).goto(column=0, follow_imports=True)
|
definition, = Script(code).goto(column=0, follow_imports=True)
|
||||||
assert 'inspect.py' in definition.module_path
|
assert definition.module_path.name == 'inspect.py'
|
||||||
assert (definition.line, definition.column) == (1, 0)
|
assert (definition.line, definition.column) == (1, 0)
|
||||||
|
|
||||||
definition, = Script(code).goto(follow_imports=True)
|
definition, = Script(code).goto(follow_imports=True)
|
||||||
assert 'inspect.py' in definition.module_path
|
assert definition.module_path.name == 'inspect.py'
|
||||||
assert (definition.line, definition.column) > (1, 0)
|
assert (definition.line, definition.column) > (1, 0)
|
||||||
|
|
||||||
code = '''def param(p): pass\nparam(1)'''
|
code = '''def param(p): pass\nparam(1)'''
|
||||||
@@ -245,11 +245,11 @@ def test_goto_module(Script):
|
|||||||
assert module.module_path == expected
|
assert module.module_path == expected
|
||||||
|
|
||||||
base_path = get_example_dir('simple_import')
|
base_path = get_example_dir('simple_import')
|
||||||
path = os.path.join(base_path, '__init__.py')
|
path = base_path.joinpath('__init__.py')
|
||||||
|
|
||||||
check(1, os.path.join(base_path, 'module.py'))
|
check(1, base_path.joinpath('module.py'))
|
||||||
check(1, os.path.join(base_path, 'module.py'), follow_imports=True)
|
check(1, base_path.joinpath('module.py'), follow_imports=True)
|
||||||
check(5, os.path.join(base_path, 'module2.py'))
|
check(5, base_path.joinpath('module2.py'))
|
||||||
|
|
||||||
|
|
||||||
def test_goto_definition_cursor(Script):
|
def test_goto_definition_cursor(Script):
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
from textwrap import dedent
|
from textwrap import dedent
|
||||||
from inspect import cleandoc
|
from inspect import cleandoc
|
||||||
import os
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -534,8 +533,8 @@ def test_execute(Script, code, description):
|
|||||||
('from pkg import Foo; Foo().bar', 'bar', 'module.py'),
|
('from pkg import Foo; Foo().bar', 'bar', 'module.py'),
|
||||||
])
|
])
|
||||||
def test_inheritance_module_path(Script, goto, code, name, file_name):
|
def test_inheritance_module_path(Script, goto, code, name, file_name):
|
||||||
base_path = os.path.join(get_example_dir('inheritance'), 'pkg')
|
base_path = get_example_dir('inheritance', 'pkg')
|
||||||
whatever_path = os.path.join(base_path, 'NOT_EXISTING.py')
|
whatever_path = base_path.joinpath('NOT_EXISTING.py')
|
||||||
|
|
||||||
script = Script(code, path=whatever_path)
|
script = Script(code, path=whatever_path)
|
||||||
if goto is None:
|
if goto is None:
|
||||||
@@ -544,7 +543,7 @@ def test_inheritance_module_path(Script, goto, code, name, file_name):
|
|||||||
func, = script.goto(follow_imports=goto)
|
func, = script.goto(follow_imports=goto)
|
||||||
assert func.type == 'function'
|
assert func.type == 'function'
|
||||||
assert func.name == name
|
assert func.name == name
|
||||||
assert func.module_path == os.path.join(base_path, file_name)
|
assert func.module_path == base_path.joinpath(file_name)
|
||||||
|
|
||||||
|
|
||||||
def test_definition_goto_follow_imports(Script):
|
def test_definition_goto_follow_imports(Script):
|
||||||
|
|||||||
@@ -221,8 +221,8 @@ current_dirname = os.path.basename(dirname(dirname(dirname(__file__))))
|
|||||||
('example.py', 'rb"' + join('..', current_dirname, 'tes'), None, ['t' + s]),
|
('example.py', 'rb"' + join('..', current_dirname, 'tes'), None, ['t' + s]),
|
||||||
|
|
||||||
# Absolute paths
|
# Absolute paths
|
||||||
(None, '"' + join(root_dir, 'test', 'test_ca'), None, ['che.py"']),
|
(None, f'"{root_dir.joinpath("test", "test_ca")}', None, ['che.py"']),
|
||||||
(None, '"%s"' % join(root_dir, 'test', 'test_ca'), len(root_dir) + 14, ['che.py']),
|
(None, f'"{root_dir.joinpath("test", "test_ca")}"', len(str(root_dir)) + 14, ['che.py']),
|
||||||
|
|
||||||
# Longer quotes
|
# Longer quotes
|
||||||
('example.py', 'r"""test', None, [s]),
|
('example.py', 'r"""test', None, [s]),
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ def test_keyword_attributes(Script):
|
|||||||
assert def_.line is def_.column is None
|
assert def_.line is def_.column is None
|
||||||
assert def_.in_builtin_module() is True
|
assert def_.in_builtin_module() is True
|
||||||
assert def_.module_name == 'builtins'
|
assert def_.module_name == 'builtins'
|
||||||
assert 'typeshed' in def_.module_path
|
assert 'typeshed' in def_.module_path.parts
|
||||||
assert def_.type == 'keyword'
|
assert def_.type == 'keyword'
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -21,13 +22,12 @@ def test_django_default_project(Script):
|
|||||||
|
|
||||||
def test_django_default_project_of_file(Script):
|
def test_django_default_project_of_file(Script):
|
||||||
project = get_default_project(__file__)
|
project = get_default_project(__file__)
|
||||||
d = os.path.dirname
|
assert project._path == Path(__file__).parent.parent.parent
|
||||||
assert project._path == d(d(d(__file__)))
|
|
||||||
|
|
||||||
|
|
||||||
def test_interpreter_project_path():
|
def test_interpreter_project_path():
|
||||||
# Run from anywhere it should be the cwd.
|
# Run from anywhere it should be the cwd.
|
||||||
dir = os.path.join(root_dir, 'test')
|
dir = Path(root_dir).joinpath('test')
|
||||||
with set_cwd(dir):
|
with set_cwd(dir):
|
||||||
project = Interpreter('', [locals()])._inference_state.project
|
project = Interpreter('', [locals()])._inference_state.project
|
||||||
assert project._path == dir
|
assert project._path == dir
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
from textwrap import dedent
|
from textwrap import dedent
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -10,22 +11,22 @@ import jedi
|
|||||||
def dir_with_content(tmpdir):
|
def dir_with_content(tmpdir):
|
||||||
with open(os.path.join(tmpdir.strpath, 'modx.py'), 'w', newline='') as f:
|
with open(os.path.join(tmpdir.strpath, 'modx.py'), 'w', newline='') as f:
|
||||||
f.write('import modx\nfoo\n') # self reference
|
f.write('import modx\nfoo\n') # self reference
|
||||||
return tmpdir.strpath
|
return Path(tmpdir.strpath)
|
||||||
|
|
||||||
|
|
||||||
def test_rename_mod(Script, dir_with_content):
|
def test_rename_mod(Script, dir_with_content):
|
||||||
script = Script(
|
script = Script(
|
||||||
'import modx; modx\n',
|
'import modx; modx\n',
|
||||||
path=os.path.join(dir_with_content, 'some_script.py'),
|
path=dir_with_content.joinpath('some_script.py'),
|
||||||
project=jedi.Project(dir_with_content),
|
project=jedi.Project(dir_with_content),
|
||||||
)
|
)
|
||||||
refactoring = script.rename(line=1, new_name='modr')
|
refactoring = script.rename(line=1, new_name='modr')
|
||||||
refactoring.apply()
|
refactoring.apply()
|
||||||
|
|
||||||
p1 = os.path.join(dir_with_content, 'modx.py')
|
p1 = dir_with_content.joinpath('modx.py')
|
||||||
p2 = os.path.join(dir_with_content, 'modr.py')
|
p2 = dir_with_content.joinpath('modr.py')
|
||||||
expected_code = 'import modr\nfoo\n'
|
expected_code = 'import modr\nfoo\n'
|
||||||
assert not os.path.exists(p1)
|
assert not p1.exists()
|
||||||
with open(p2, newline='') as f:
|
with open(p2, newline='') as f:
|
||||||
assert f.read() == expected_code
|
assert f.read() == expected_code
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
from textwrap import dedent
|
from textwrap import dedent
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from jedi.inference.sys_path import _get_parent_dir_with_file, \
|
from jedi.inference.sys_path import _get_parent_dir_with_file, \
|
||||||
_get_buildout_script_paths, check_sys_path_modifications
|
_get_buildout_script_paths, check_sys_path_modifications
|
||||||
@@ -13,18 +14,18 @@ def check_module_test(Script, code):
|
|||||||
|
|
||||||
|
|
||||||
def test_parent_dir_with_file(Script):
|
def test_parent_dir_with_file(Script):
|
||||||
path = get_example_dir('buildout_project', 'src', 'proj_name')
|
path = Path(get_example_dir('buildout_project', 'src', 'proj_name'))
|
||||||
parent = _get_parent_dir_with_file(path, 'buildout.cfg')
|
parent = _get_parent_dir_with_file(path, 'buildout.cfg')
|
||||||
assert parent is not None
|
assert parent is not None
|
||||||
assert parent.endswith(os.path.join('test', 'examples', 'buildout_project'))
|
assert str(parent).endswith(os.path.join('test', 'examples', 'buildout_project'))
|
||||||
|
|
||||||
|
|
||||||
def test_buildout_detection(Script):
|
def test_buildout_detection(Script):
|
||||||
path = get_example_dir('buildout_project', 'src', 'proj_name')
|
path = Path(get_example_dir('buildout_project', 'src', 'proj_name'))
|
||||||
scripts = list(_get_buildout_script_paths(os.path.join(path, 'module_name.py')))
|
paths = list(_get_buildout_script_paths(path.joinpath('module_name.py')))
|
||||||
assert len(scripts) == 1
|
assert len(paths) == 1
|
||||||
appdir_path = os.path.normpath(os.path.join(path, '../../bin/app'))
|
appdir_path = os.path.normpath(os.path.join(path, '../../bin/app'))
|
||||||
assert scripts[0] == appdir_path
|
assert str(paths[0]) == appdir_path
|
||||||
|
|
||||||
|
|
||||||
def test_append_on_non_sys_path(Script):
|
def test_append_on_non_sys_path(Script):
|
||||||
@@ -79,4 +80,4 @@ def test_path_from_sys_path_assignment(Script):
|
|||||||
|
|
||||||
paths = check_module_test(Script, code)
|
paths = check_module_test(Script, code)
|
||||||
assert 1 not in paths
|
assert 1 not in paths
|
||||||
assert '/home/test/.buildout/eggs/important_package.egg' in paths
|
assert '/home/test/.buildout/eggs/important_package.egg' in map(str, paths)
|
||||||
|
|||||||
@@ -87,4 +87,4 @@ def test_infer_and_goto(Script, code, full_name, has_stub, has_python, way,
|
|||||||
assert has_python == (not d.is_stub())
|
assert has_python == (not d.is_stub())
|
||||||
assert d.full_name == full_name
|
assert d.full_name == full_name
|
||||||
|
|
||||||
assert d.is_stub() == d.module_path.endswith('.pyi')
|
assert d.is_stub() == (d.module_path.suffix == '.pyi')
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ TYPESHED_PYTHON3 = os.path.join(typeshed.TYPESHED_PATH, 'stdlib', '3')
|
|||||||
def test_get_typeshed_directories():
|
def test_get_typeshed_directories():
|
||||||
def get_dirs(version_info):
|
def get_dirs(version_info):
|
||||||
return {
|
return {
|
||||||
p.path.replace(typeshed.TYPESHED_PATH, '').lstrip(os.path.sep)
|
p.path.replace(str(typeshed.TYPESHED_PATH), '').lstrip(os.path.sep)
|
||||||
for p in typeshed._get_typeshed_directories(version_info)
|
for p in typeshed._get_typeshed_directories(version_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ def test_keywords_variable(Script):
|
|||||||
assert seq.name == 'Sequence'
|
assert seq.name == 'Sequence'
|
||||||
# This points towards the typeshed implementation
|
# This points towards the typeshed implementation
|
||||||
stub_seq, = seq.goto(only_stubs=True)
|
stub_seq, = seq.goto(only_stubs=True)
|
||||||
assert typeshed.TYPESHED_PATH in stub_seq.module_path
|
assert str(stub_seq.module_path).startswith(str(typeshed.TYPESHED_PATH))
|
||||||
|
|
||||||
|
|
||||||
def test_class(Script):
|
def test_class(Script):
|
||||||
@@ -91,8 +91,12 @@ def test_sys_exc_info(Script):
|
|||||||
none, def_ = Script(code + '[1]').infer()
|
none, def_ = Script(code + '[1]').infer()
|
||||||
# It's an optional.
|
# It's an optional.
|
||||||
assert def_.name == 'BaseException'
|
assert def_.name == 'BaseException'
|
||||||
|
assert def_.module_path == typeshed.TYPESHED_PATH.joinpath(
|
||||||
|
'stdlib', '2and3', 'builtins.pyi'
|
||||||
|
)
|
||||||
assert def_.type == 'instance'
|
assert def_.type == 'instance'
|
||||||
assert none.name == 'NoneType'
|
assert none.name == 'NoneType'
|
||||||
|
assert none.module_path is None
|
||||||
|
|
||||||
none, def_ = Script(code + '[0]').infer()
|
none, def_ = Script(code + '[0]').infer()
|
||||||
assert def_.name == 'BaseException'
|
assert def_.name == 'BaseException'
|
||||||
@@ -111,7 +115,7 @@ def test_sys_hexversion(Script):
|
|||||||
script = Script('import sys; sys.hexversion')
|
script = Script('import sys; sys.hexversion')
|
||||||
def_, = script.complete()
|
def_, = script.complete()
|
||||||
assert isinstance(def_._name, StubName), def_._name
|
assert isinstance(def_._name, StubName), def_._name
|
||||||
assert typeshed.TYPESHED_PATH in def_.module_path
|
assert str(def_.module_path).startswith(str(typeshed.TYPESHED_PATH))
|
||||||
def_, = script.infer()
|
def_, = script.infer()
|
||||||
assert def_.name == 'int'
|
assert def_.name == 'int'
|
||||||
|
|
||||||
@@ -138,14 +142,14 @@ def test_type_var(Script):
|
|||||||
def test_math_is_stub(Script, code, full_name):
|
def test_math_is_stub(Script, code, full_name):
|
||||||
s = Script(code)
|
s = Script(code)
|
||||||
cos, = s.infer()
|
cos, = s.infer()
|
||||||
wanted = os.path.join('typeshed', 'stdlib', '2and3', 'math.pyi')
|
wanted = ('typeshed', 'stdlib', '2and3', 'math.pyi')
|
||||||
assert cos.module_path.endswith(wanted)
|
assert cos.module_path.parts[-4:] == wanted
|
||||||
assert cos.is_stub() is True
|
assert cos.is_stub() is True
|
||||||
assert cos.goto(only_stubs=True) == [cos]
|
assert cos.goto(only_stubs=True) == [cos]
|
||||||
assert cos.full_name == full_name
|
assert cos.full_name == full_name
|
||||||
|
|
||||||
cos, = s.goto()
|
cos, = s.goto()
|
||||||
assert cos.module_path.endswith(wanted)
|
assert cos.module_path.parts[-4:] == wanted
|
||||||
assert cos.goto(only_stubs=True) == [cos]
|
assert cos.goto(only_stubs=True) == [cos]
|
||||||
assert cos.is_stub() is True
|
assert cos.is_stub() is True
|
||||||
assert cos.full_name == full_name
|
assert cos.full_name == full_name
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ Tests".
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -38,11 +39,11 @@ def test_find_module_not_package():
|
|||||||
assert is_package is False
|
assert is_package is False
|
||||||
|
|
||||||
|
|
||||||
pkg_zip_path = get_example_dir('zipped_imports', 'pkg.zip')
|
pkg_zip_path = Path(get_example_dir('zipped_imports', 'pkg.zip'))
|
||||||
|
|
||||||
|
|
||||||
def test_find_module_package_zipped(Script, inference_state, environment):
|
def test_find_module_package_zipped(Script, inference_state, environment):
|
||||||
sys_path = environment.get_sys_path() + [pkg_zip_path]
|
sys_path = environment.get_sys_path() + [str(pkg_zip_path)]
|
||||||
|
|
||||||
project = Project('.', sys_path=sys_path)
|
project = Project('.', sys_path=sys_path)
|
||||||
script = Script('import pkg; pkg.mod', project=project)
|
script = Script('import pkg; pkg.mod', project=project)
|
||||||
@@ -86,14 +87,14 @@ def test_find_module_package_zipped(Script, inference_state, environment):
|
|||||||
)
|
)
|
||||||
def test_correct_zip_package_behavior(Script, inference_state, environment, code,
|
def test_correct_zip_package_behavior(Script, inference_state, environment, code,
|
||||||
file, package, path):
|
file, package, path):
|
||||||
sys_path = environment.get_sys_path() + [pkg_zip_path]
|
sys_path = environment.get_sys_path() + [str(pkg_zip_path)]
|
||||||
pkg, = Script(code, project=Project('.', sys_path=sys_path)).infer()
|
pkg, = Script(code, project=Project('.', sys_path=sys_path)).infer()
|
||||||
value, = pkg._name.infer()
|
value, = pkg._name.infer()
|
||||||
assert value.py__file__() == os.path.join(pkg_zip_path, 'pkg', file)
|
assert value.py__file__() == pkg_zip_path.joinpath('pkg', file)
|
||||||
assert '.'.join(value.py__package__()) == package
|
assert '.'.join(value.py__package__()) == package
|
||||||
assert value.is_package() is (path is not None)
|
assert value.is_package() is (path is not None)
|
||||||
if path is not None:
|
if path is not None:
|
||||||
assert value.py__path__() == [os.path.join(pkg_zip_path, path)]
|
assert value.py__path__() == [str(pkg_zip_path.joinpath(path))]
|
||||||
|
|
||||||
|
|
||||||
def test_find_module_not_package_zipped(Script, inference_state, environment):
|
def test_find_module_not_package_zipped(Script, inference_state, environment):
|
||||||
@@ -103,7 +104,7 @@ def test_find_module_not_package_zipped(Script, inference_state, environment):
|
|||||||
assert len(script.complete()) == 1
|
assert len(script.complete()) == 1
|
||||||
|
|
||||||
file_io, is_package = inference_state.compiled_subprocess.get_module_info(
|
file_io, is_package = inference_state.compiled_subprocess.get_module_info(
|
||||||
sys_path=sys_path,
|
sys_path=map(str, sys_path),
|
||||||
string='not_pkg',
|
string='not_pkg',
|
||||||
full_name='not_pkg'
|
full_name='not_pkg'
|
||||||
)
|
)
|
||||||
@@ -435,8 +436,8 @@ def test_pre_defined_imports_module(Script, environment, name):
|
|||||||
module = Script('', path=path)._get_module_context()
|
module = Script('', path=path)._get_module_context()
|
||||||
assert module.string_names == (name,)
|
assert module.string_names == (name,)
|
||||||
|
|
||||||
assert module.inference_state.builtins_module.py__file__() != path
|
assert str(module.inference_state.builtins_module.py__file__()) != path
|
||||||
assert module.inference_state.typing_module.py__file__() != path
|
assert str(module.inference_state.typing_module.py__file__()) != path
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('name', ('builtins', 'typing'))
|
@pytest.mark.parametrize('name', ('builtins', 'typing'))
|
||||||
@@ -449,8 +450,8 @@ def test_import_needed_modules_by_jedi(Script, environment, tmpdir, name):
|
|||||||
project=Project('.', sys_path=[tmpdir.strpath] + environment.get_sys_path()),
|
project=Project('.', sys_path=[tmpdir.strpath] + environment.get_sys_path()),
|
||||||
)
|
)
|
||||||
module, = script.infer()
|
module, = script.infer()
|
||||||
assert module._inference_state.builtins_module.py__file__() != module_path
|
assert str(module._inference_state.builtins_module.py__file__()) != module_path
|
||||||
assert module._inference_state.typing_module.py__file__() != module_path
|
assert str(module._inference_state.typing_module.py__file__()) != module_path
|
||||||
|
|
||||||
|
|
||||||
def test_import_with_semicolon(Script):
|
def test_import_with_semicolon(Script):
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import os
|
|||||||
from glob import glob
|
from glob import glob
|
||||||
import sys
|
import sys
|
||||||
import shutil
|
import shutil
|
||||||
|
from pathlib import Path, PurePath
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -17,9 +18,9 @@ def test_paths_from_assignment(Script):
|
|||||||
return set(sys_path._paths_from_assignment(script._get_module_context(), expr_stmt))
|
return set(sys_path._paths_from_assignment(script._get_module_context(), expr_stmt))
|
||||||
|
|
||||||
# Normalize paths for Windows.
|
# Normalize paths for Windows.
|
||||||
path_a = os.path.abspath('/foo/a')
|
path_a = PurePath('/foo/a')
|
||||||
path_b = os.path.abspath('/foo/b')
|
path_b = PurePath('/foo/b')
|
||||||
path_c = os.path.abspath('/foo/c')
|
path_c = PurePath('/foo/c')
|
||||||
|
|
||||||
assert paths('sys.path[0:0] = ["a"]') == {path_a}
|
assert paths('sys.path[0:0] = ["a"]') == {path_a}
|
||||||
assert paths('sys.path = ["b", 1, x + 3, y, "c"]') == {path_b, path_c}
|
assert paths('sys.path = ["b", 1, x + 3, y, "c"]') == {path_b, path_c}
|
||||||
@@ -105,5 +106,5 @@ def test_transform_path_to_dotted(sys_path_, module_path, expected, is_package):
|
|||||||
# transform_path_to_dotted expects normalized absolute paths.
|
# transform_path_to_dotted expects normalized absolute paths.
|
||||||
sys_path_ = [os.path.abspath(path) for path in sys_path_]
|
sys_path_ = [os.path.abspath(path) for path in sys_path_]
|
||||||
module_path = os.path.abspath(module_path)
|
module_path = os.path.abspath(module_path)
|
||||||
assert sys_path.transform_path_to_dotted(sys_path_, module_path) \
|
assert sys_path.transform_path_to_dotted(sys_path_, Path(module_path)) \
|
||||||
== (expected, is_package)
|
== (expected, is_package)
|
||||||
|
|||||||
Reference in New Issue
Block a user