Implement all remaining Path issues and use it instead of strings

This commit is contained in:
Dave Halter
2020-07-12 01:14:00 +02:00
parent db0e90763b
commit 480a464179
23 changed files with 131 additions and 97 deletions

View File

@@ -7,14 +7,14 @@ from contextlib import contextmanager
import os
import pytest
from os.path import abspath, dirname, join
from functools import partial, wraps
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)
root_dir = dirname(test_dir)
example_dir = join(test_dir, 'examples')
root_dir = test_dir.parent
example_dir = test_dir.joinpath('examples')
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):
return join(example_dir, *names)
return example_dir.joinpath(*names)
def cwd_at(path):
@@ -46,10 +46,10 @@ def cwd_at(path):
@contextmanager
def set_cwd(path, absolute_path=False):
repo_root = os.path.dirname(test_dir)
repo_root = test_dir.parent
oldcwd = os.getcwd()
os.chdir(os.path.join(repo_root, path))
oldcwd = Path.cwd()
os.chdir(repo_root.joinpath(path))
try:
yield
finally:

View File

@@ -22,7 +22,7 @@ def test_preload_modules():
# Filter the typeshed parser cache.
typeshed_cache_count = sum(
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)
assert len(grammar_cache) - typeshed_cache_count == len(modules) + 1
@@ -210,11 +210,11 @@ def test_goto_follow_imports(Script):
import inspect
inspect.isfunction""")
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)
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)
code = '''def param(p): pass\nparam(1)'''
@@ -245,11 +245,11 @@ def test_goto_module(Script):
assert module.module_path == expected
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, os.path.join(base_path, 'module.py'), follow_imports=True)
check(5, os.path.join(base_path, 'module2.py'))
check(1, base_path.joinpath('module.py'))
check(1, base_path.joinpath('module.py'), follow_imports=True)
check(5, base_path.joinpath('module2.py'))
def test_goto_definition_cursor(Script):

View File

@@ -3,7 +3,6 @@
from textwrap import dedent
from inspect import cleandoc
import os
import pytest
@@ -534,8 +533,8 @@ def test_execute(Script, code, description):
('from pkg import Foo; Foo().bar', 'bar', 'module.py'),
])
def test_inheritance_module_path(Script, goto, code, name, file_name):
base_path = os.path.join(get_example_dir('inheritance'), 'pkg')
whatever_path = os.path.join(base_path, 'NOT_EXISTING.py')
base_path = get_example_dir('inheritance', 'pkg')
whatever_path = base_path.joinpath('NOT_EXISTING.py')
script = Script(code, path=whatever_path)
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)
assert func.type == 'function'
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):

View File

@@ -221,8 +221,8 @@ current_dirname = os.path.basename(dirname(dirname(dirname(__file__))))
('example.py', 'rb"' + join('..', current_dirname, 'tes'), None, ['t' + s]),
# Absolute paths
(None, '"' + join(root_dir, '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")}', None, ['che.py"']),
(None, f'"{root_dir.joinpath("test", "test_ca")}"', len(str(root_dir)) + 14, ['che.py']),
# Longer quotes
('example.py', 'r"""test', None, [s]),

View File

@@ -41,7 +41,7 @@ def test_keyword_attributes(Script):
assert def_.line is def_.column is None
assert def_.in_builtin_module() is True
assert def_.module_name == 'builtins'
assert 'typeshed' in def_.module_path
assert 'typeshed' in def_.module_path.parts
assert def_.type == 'keyword'

View File

@@ -1,4 +1,5 @@
import os
from pathlib import Path
import pytest
@@ -21,13 +22,12 @@ def test_django_default_project(Script):
def test_django_default_project_of_file(Script):
project = get_default_project(__file__)
d = os.path.dirname
assert project._path == d(d(d(__file__)))
assert project._path == Path(__file__).parent.parent.parent
def test_interpreter_project_path():
# 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):
project = Interpreter('', [locals()])._inference_state.project
assert project._path == dir

View File

@@ -1,5 +1,6 @@
import os
from textwrap import dedent
from pathlib import Path
import pytest
@@ -10,22 +11,22 @@ import jedi
def dir_with_content(tmpdir):
with open(os.path.join(tmpdir.strpath, 'modx.py'), 'w', newline='') as f:
f.write('import modx\nfoo\n') # self reference
return tmpdir.strpath
return Path(tmpdir.strpath)
def test_rename_mod(Script, dir_with_content):
script = Script(
'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),
)
refactoring = script.rename(line=1, new_name='modr')
refactoring.apply()
p1 = os.path.join(dir_with_content, 'modx.py')
p2 = os.path.join(dir_with_content, 'modr.py')
p1 = dir_with_content.joinpath('modx.py')
p2 = dir_with_content.joinpath('modr.py')
expected_code = 'import modr\nfoo\n'
assert not os.path.exists(p1)
assert not p1.exists()
with open(p2, newline='') as f:
assert f.read() == expected_code

View File

@@ -1,5 +1,6 @@
import os
from textwrap import dedent
from pathlib import Path
from jedi.inference.sys_path import _get_parent_dir_with_file, \
_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):
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')
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):
path = get_example_dir('buildout_project', 'src', 'proj_name')
scripts = list(_get_buildout_script_paths(os.path.join(path, 'module_name.py')))
assert len(scripts) == 1
path = Path(get_example_dir('buildout_project', 'src', 'proj_name'))
paths = list(_get_buildout_script_paths(path.joinpath('module_name.py')))
assert len(paths) == 1
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):
@@ -79,4 +80,4 @@ def test_path_from_sys_path_assignment(Script):
paths = check_module_test(Script, code)
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)

View File

@@ -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 d.full_name == full_name
assert d.is_stub() == d.module_path.endswith('.pyi')
assert d.is_stub() == (d.module_path.suffix == '.pyi')

View File

@@ -14,7 +14,7 @@ TYPESHED_PYTHON3 = os.path.join(typeshed.TYPESHED_PATH, 'stdlib', '3')
def test_get_typeshed_directories():
def get_dirs(version_info):
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)
}
@@ -52,7 +52,7 @@ def test_keywords_variable(Script):
assert seq.name == 'Sequence'
# This points towards the typeshed implementation
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):
@@ -91,8 +91,12 @@ def test_sys_exc_info(Script):
none, def_ = Script(code + '[1]').infer()
# It's an optional.
assert def_.name == 'BaseException'
assert def_.module_path == typeshed.TYPESHED_PATH.joinpath(
'stdlib', '2and3', 'builtins.pyi'
)
assert def_.type == 'instance'
assert none.name == 'NoneType'
assert none.module_path is None
none, def_ = Script(code + '[0]').infer()
assert def_.name == 'BaseException'
@@ -111,7 +115,7 @@ def test_sys_hexversion(Script):
script = Script('import sys; sys.hexversion')
def_, = script.complete()
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()
assert def_.name == 'int'
@@ -138,14 +142,14 @@ def test_type_var(Script):
def test_math_is_stub(Script, code, full_name):
s = Script(code)
cos, = s.infer()
wanted = os.path.join('typeshed', 'stdlib', '2and3', 'math.pyi')
assert cos.module_path.endswith(wanted)
wanted = ('typeshed', 'stdlib', '2and3', 'math.pyi')
assert cos.module_path.parts[-4:] == wanted
assert cos.is_stub() is True
assert cos.goto(only_stubs=True) == [cos]
assert cos.full_name == full_name
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.is_stub() is True
assert cos.full_name == full_name

View File

@@ -4,6 +4,7 @@ Tests".
"""
import os
from pathlib import Path
import pytest
@@ -38,11 +39,11 @@ def test_find_module_not_package():
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):
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)
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,
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()
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 value.is_package() is (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):
@@ -103,7 +104,7 @@ def test_find_module_not_package_zipped(Script, inference_state, environment):
assert len(script.complete()) == 1
file_io, is_package = inference_state.compiled_subprocess.get_module_info(
sys_path=sys_path,
sys_path=map(str, sys_path),
string='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()
assert module.string_names == (name,)
assert module.inference_state.builtins_module.py__file__() != path
assert module.inference_state.typing_module.py__file__() != path
assert str(module.inference_state.builtins_module.py__file__()) != path
assert str(module.inference_state.typing_module.py__file__()) != path
@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()),
)
module, = script.infer()
assert module._inference_state.builtins_module.py__file__() != module_path
assert module._inference_state.typing_module.py__file__() != module_path
assert str(module._inference_state.builtins_module.py__file__()) != module_path
assert str(module._inference_state.typing_module.py__file__()) != module_path
def test_import_with_semicolon(Script):

View File

@@ -2,6 +2,7 @@ import os
from glob import glob
import sys
import shutil
from pathlib import Path, PurePath
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))
# Normalize paths for Windows.
path_a = os.path.abspath('/foo/a')
path_b = os.path.abspath('/foo/b')
path_c = os.path.abspath('/foo/c')
path_a = PurePath('/foo/a')
path_b = PurePath('/foo/b')
path_c = PurePath('/foo/c')
assert paths('sys.path[0:0] = ["a"]') == {path_a}
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.
sys_path_ = [os.path.abspath(path) for path in sys_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)