mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-06 14:04:26 +08:00
Merge branch 'master' into deprecations
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
# For assignment expressions / named expressions / walrus operators / whatever
|
||||
# they are called.
|
||||
|
||||
# python >= 3.8
|
||||
b = (a:=1, a)
|
||||
|
||||
@@ -11,3 +14,39 @@ b = ('':=1,)
|
||||
|
||||
#? int()
|
||||
b[0]
|
||||
|
||||
def test_assignments():
|
||||
match = ''
|
||||
#? str()
|
||||
match
|
||||
#? 8 int()
|
||||
if match := 1:
|
||||
#? int()
|
||||
match
|
||||
#? int()
|
||||
match
|
||||
|
||||
def test_assignments2():
|
||||
class Foo:
|
||||
match = ''
|
||||
#? str()
|
||||
Foo.match
|
||||
#? 13 int()
|
||||
if Foo.match := 1:
|
||||
#? str()
|
||||
Foo.match
|
||||
#? str()
|
||||
Foo.match
|
||||
|
||||
#?
|
||||
y
|
||||
#? 16 str()
|
||||
if y := Foo.match:
|
||||
#? str()
|
||||
y
|
||||
#? str()
|
||||
y
|
||||
|
||||
#? 8 str()
|
||||
if z := Foo.match:
|
||||
pass
|
||||
|
||||
@@ -179,3 +179,22 @@ def argskwargs(*args: int, **kwargs: float):
|
||||
next(iter(kwargs.keys()))
|
||||
#? float()
|
||||
kwargs['']
|
||||
|
||||
|
||||
class NotCalledClass:
|
||||
def __init__(self, x):
|
||||
self.x: int = x
|
||||
self.y: int = ''
|
||||
#? int()
|
||||
self.x
|
||||
#? int()
|
||||
self.y
|
||||
#? int()
|
||||
self.y
|
||||
self.z: int
|
||||
self.z = ''
|
||||
#? str() int()
|
||||
self.z
|
||||
self.w: float
|
||||
#? float()
|
||||
self.w
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
from .cq import selectors
|
||||
1
test/examples/import-recursion/cadquery_simple/cq.py
Normal file
1
test/examples/import-recursion/cadquery_simple/cq.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import selectors
|
||||
3
test/examples/import-recursion/cq_example.py
Normal file
3
test/examples/import-recursion/cq_example.py
Normal file
@@ -0,0 +1,3 @@
|
||||
import cadquery_simple as cq
|
||||
|
||||
cq.
|
||||
@@ -15,7 +15,7 @@ from test.helpers import test_dir, get_example_dir
|
||||
|
||||
|
||||
def test_preload_modules():
|
||||
def check_loaded(*modules):
|
||||
def check_loaded(*module_names):
|
||||
for grammar_cache in cache.parser_cache.values():
|
||||
if None in grammar_cache:
|
||||
break
|
||||
@@ -25,9 +25,9 @@ def test_preload_modules():
|
||||
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
|
||||
for i in modules:
|
||||
assert [i in k for k in grammar_cache.keys() if k is not None]
|
||||
assert len(grammar_cache) - typeshed_cache_count == len(module_names) + 1
|
||||
for i in module_names:
|
||||
assert [i in str(k) for k in grammar_cache.keys() if k is not None]
|
||||
|
||||
old_cache = cache.parser_cache.copy()
|
||||
cache.parser_cache.clear()
|
||||
@@ -370,3 +370,35 @@ def test_multi_goto(Script):
|
||||
y, = script.goto(line=4)
|
||||
assert x.line == 1
|
||||
assert y.line == 2
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'code, column, expected', [
|
||||
('str() ', 3, 'str'),
|
||||
('str() ', 4, 'str'),
|
||||
('str() ', 5, 'str'),
|
||||
('str() ', 6, None),
|
||||
('str( ) ', 6, None),
|
||||
(' 1', 1, None),
|
||||
('str(1) ', 3, 'str'),
|
||||
('str(1) ', 4, 'int'),
|
||||
('str(1) ', 5, 'int'),
|
||||
('str(1) ', 6, 'str'),
|
||||
('str(1) ', 7, None),
|
||||
('str( 1) ', 4, 'str'),
|
||||
('str( 1) ', 5, 'int'),
|
||||
('str(+1) ', 4, 'str'),
|
||||
('str(+1) ', 5, 'int'),
|
||||
('str(1, 1.) ', 3, 'str'),
|
||||
('str(1, 1.) ', 4, 'int'),
|
||||
('str(1, 1.) ', 5, 'int'),
|
||||
('str(1, 1.) ', 6, None),
|
||||
('str(1, 1.) ', 7, 'float'),
|
||||
]
|
||||
)
|
||||
def test_infer_after_parentheses(Script, code, column, expected):
|
||||
completions = Script(code).infer(column=column)
|
||||
if expected is None:
|
||||
assert completions == []
|
||||
else:
|
||||
assert [c.name for c in completions] == [expected]
|
||||
|
||||
@@ -121,11 +121,8 @@ def test_multiple_signatures(Script):
|
||||
|
||||
|
||||
def test_get_signatures_whitespace(Script):
|
||||
s = dedent("""\
|
||||
abs(
|
||||
def x():
|
||||
pass
|
||||
""") # noqa
|
||||
# note: trailing space after 'abs'
|
||||
s = 'abs( \ndef x():\n pass\n'
|
||||
assert_signature(Script, s, 'abs', 0, line=1, column=5)
|
||||
|
||||
|
||||
|
||||
@@ -513,10 +513,14 @@ def test_added_equals_to_params(Script):
|
||||
|
||||
assert run('foo(bar').name_with_symbols == 'bar='
|
||||
assert run('foo(bar').complete == '='
|
||||
assert run('foo(bar').get_completion_prefix_length() == 3
|
||||
assert run('foo(bar, baz').complete == '='
|
||||
assert run('foo(bar, baz').get_completion_prefix_length() == 3
|
||||
assert run(' bar').name_with_symbols == 'bar'
|
||||
assert run(' bar').complete == ''
|
||||
assert run(' bar').get_completion_prefix_length() == 3
|
||||
x = run('foo(bar=isins').name_with_symbols
|
||||
assert run('foo(bar=isins').get_completion_prefix_length() == 5
|
||||
assert x == 'isinstance'
|
||||
|
||||
|
||||
|
||||
@@ -621,7 +621,8 @@ def bar():
|
||||
|
||||
# typing is available via globals.
|
||||
({'return': 'typing.Union[str, int]'}, ['int', 'str'], ''),
|
||||
({'return': 'typing.Union["str", int]'}, ['int'], ''),
|
||||
({'return': 'typing.Union["str", int]'},
|
||||
['int', 'str'] if sys.version_info >= (3, 9) else ['int'], ''),
|
||||
({'return': 'typing.Union["str", 1]'}, [], ''),
|
||||
({'return': 'typing.Optional[str]'}, ['NoneType', 'str'], ''),
|
||||
({'return': 'typing.Optional[str, int]'}, [], ''), # Takes only one arg
|
||||
|
||||
@@ -6,6 +6,7 @@ import pytest
|
||||
from ..helpers import get_example_dir, set_cwd, root_dir, test_dir
|
||||
from jedi import Interpreter
|
||||
from jedi.api import Project, get_default_project
|
||||
from jedi.api.project import _is_potential_project, _CONTAINS_POTENTIAL_PROJECT
|
||||
|
||||
|
||||
def test_django_default_project(Script):
|
||||
@@ -17,7 +18,12 @@ def test_django_default_project(Script):
|
||||
)
|
||||
c, = script.complete()
|
||||
assert c.name == "SomeModel"
|
||||
assert script._inference_state.project._django is True
|
||||
|
||||
project = script._inference_state.project
|
||||
assert project._django is True
|
||||
assert project.sys_path is None
|
||||
assert project.smart_sys_path is True
|
||||
assert project.load_unsafe_extensions is False
|
||||
|
||||
|
||||
def test_django_default_project_of_file(Script):
|
||||
@@ -155,3 +161,21 @@ def test_complete_search(Script, string, completions, all_scopes):
|
||||
project = Project(test_dir)
|
||||
defs = project.complete_search(string, all_scopes=all_scopes)
|
||||
assert [d.complete for d in defs] == completions
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'path,expected', [
|
||||
(Path(__file__).parents[2], True), # The path of the project
|
||||
(Path(__file__).parents[1], False), # The path of the tests, not a project
|
||||
(Path.home(), None)
|
||||
]
|
||||
)
|
||||
def test_is_potential_project(path, expected):
|
||||
|
||||
if expected is None:
|
||||
try:
|
||||
expected = _CONTAINS_POTENTIAL_PROJECT in os.listdir(path)
|
||||
except OSError:
|
||||
expected = False
|
||||
|
||||
assert _is_potential_project(path) == expected
|
||||
|
||||
@@ -206,6 +206,24 @@ def test_numpydoc_parameters_set_of_values():
|
||||
assert 'capitalize' in names
|
||||
assert 'numerator' in names
|
||||
|
||||
@pytest.mark.skipif(numpydoc_unavailable,
|
||||
reason='numpydoc module is unavailable')
|
||||
def test_numpydoc_parameters_set_single_value():
|
||||
"""
|
||||
This is found in numpy masked-array I'm not too sure what this means but should not crash
|
||||
"""
|
||||
s = dedent('''
|
||||
def foobar(x, y):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
x : {var}, optional
|
||||
"""
|
||||
x.''')
|
||||
names = [c.name for c in jedi.Script(s).complete()]
|
||||
# just don't crash
|
||||
assert names == []
|
||||
|
||||
|
||||
@pytest.mark.skipif(numpydoc_unavailable,
|
||||
reason='numpydoc module is unavailable')
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
from parso.cache import parser_cache
|
||||
|
||||
from test.helpers import root_dir
|
||||
from jedi.api.project import Project
|
||||
@@ -64,6 +65,17 @@ def test_goto_import(Script):
|
||||
assert not d.is_stub()
|
||||
|
||||
|
||||
def test_stub_get_line_code(Script):
|
||||
code = 'from abc import ABC; ABC'
|
||||
script = Script(code)
|
||||
d, = script.goto(only_stubs=True)
|
||||
assert d.get_line_code() == 'class ABC(metaclass=ABCMeta): ...\n'
|
||||
del parser_cache[script._inference_state.latest_grammar._hashed][d.module_path]
|
||||
d, = Script(path=d.module_path).goto(d.line, d.column, only_stubs=True)
|
||||
assert d.is_stub()
|
||||
assert d.get_line_code() == 'class ABC(metaclass=ABCMeta): ...\n'
|
||||
|
||||
|
||||
def test_os_stat_result(Script):
|
||||
d, = Script('import os; os.stat_result').goto()
|
||||
assert d.is_stub()
|
||||
|
||||
@@ -29,13 +29,13 @@ def test_find_module_basic():
|
||||
|
||||
def test_find_module_package():
|
||||
file_io, is_package = _find_module('json')
|
||||
assert file_io.path.endswith(os.path.join('json', '__init__.py'))
|
||||
assert file_io.path.parts[-2:] == ('json', '__init__.py')
|
||||
assert is_package is True
|
||||
|
||||
|
||||
def test_find_module_not_package():
|
||||
file_io, is_package = _find_module('io')
|
||||
assert file_io.path.endswith('io.py')
|
||||
assert file_io.path.name == 'io.py'
|
||||
assert is_package is False
|
||||
|
||||
|
||||
@@ -55,8 +55,8 @@ def test_find_module_package_zipped(Script, inference_state, environment):
|
||||
full_name='pkg'
|
||||
)
|
||||
assert file_io is not None
|
||||
assert file_io.path.endswith(os.path.join('pkg.zip', 'pkg', '__init__.py'))
|
||||
assert file_io._zip_path.endswith('pkg.zip')
|
||||
assert file_io.path.parts[-3:] == ('pkg.zip', 'pkg', '__init__.py')
|
||||
assert file_io._zip_path.name == 'pkg.zip'
|
||||
assert is_package is True
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ def test_find_module_not_package_zipped(Script, inference_state, environment):
|
||||
string='not_pkg',
|
||||
full_name='not_pkg'
|
||||
)
|
||||
assert file_io.path.endswith(os.path.join('not_pkg.zip', 'not_pkg.py'))
|
||||
assert file_io.path.parts[-2:] == ('not_pkg.zip', 'not_pkg.py')
|
||||
assert is_package is False
|
||||
|
||||
|
||||
@@ -468,3 +468,9 @@ def test_relative_import_star(Script):
|
||||
script = Script(source, path='export.py')
|
||||
|
||||
assert script.complete(3, len("furl.c"))
|
||||
|
||||
|
||||
def test_import_recursion(Script):
|
||||
path = get_example_dir('import-recursion', "cq_example.py")
|
||||
for c in Script(path=path).complete(3, 3):
|
||||
c.docstring()
|
||||
|
||||
@@ -340,3 +340,20 @@ def test_overload(Script, code):
|
||||
x1, x2 = Script(code, path=os.path.join(dir_, 'foo.py')).get_signatures()
|
||||
assert x1.to_string() == 'with_overload(x: int, y: int) -> float'
|
||||
assert x2.to_string() == 'with_overload(x: str, y: list) -> float'
|
||||
|
||||
|
||||
def test_enum(Script):
|
||||
script = Script('''\
|
||||
from enum import Enum
|
||||
|
||||
class Planet(Enum):
|
||||
MERCURY = (3.303e+23, 2.4397e6)
|
||||
VENUS = (4.869e+24, 6.0518e6)
|
||||
|
||||
def __init__(self, mass, radius):
|
||||
self.mass = mass # in kilograms
|
||||
self.radius = radius # in meters
|
||||
|
||||
Planet.MERCURY''')
|
||||
completion, = script.complete()
|
||||
assert not completion.get_signatures()
|
||||
|
||||
Reference in New Issue
Block a user