forked from VimPlug/jedi
Merge branch 'dev' into bugfix/performances_degradation
# Conflicts: # test/test_regression.py
This commit is contained in:
@@ -311,6 +311,17 @@ for i in 0, 2:
|
||||
#? int() str()
|
||||
GetItemWithList()[i]
|
||||
|
||||
|
||||
# With super
|
||||
class SuperYeah(list):
|
||||
def __getitem__(self, index):
|
||||
return super()[index]
|
||||
|
||||
#?
|
||||
SuperYeah([1])[0]
|
||||
#?
|
||||
SuperYeah()[0]
|
||||
|
||||
# -----------------
|
||||
# conversions
|
||||
# -----------------
|
||||
@@ -368,20 +379,6 @@ for i in set(a for a in [1]):
|
||||
i
|
||||
|
||||
|
||||
# -----------------
|
||||
# Recursions
|
||||
# -----------------
|
||||
|
||||
def to_list(iterable):
|
||||
return list(set(iterable))
|
||||
|
||||
|
||||
def recursion1(foo):
|
||||
return to_list(to_list(foo)) + recursion1(foo)
|
||||
|
||||
#? int()
|
||||
recursion1([1,2])[0]
|
||||
|
||||
# -----------------
|
||||
# Merged Arrays
|
||||
# -----------------
|
||||
|
||||
@@ -190,6 +190,16 @@ def a():
|
||||
#?
|
||||
# str literals in comment """ upper
|
||||
|
||||
def completion_in_comment():
|
||||
#? ['Exception']
|
||||
# might fail because the comment is not a leaf: Exception
|
||||
pass
|
||||
|
||||
some_word
|
||||
#? ['Exception']
|
||||
# Very simple comment completion: Exception
|
||||
# Commment after it
|
||||
|
||||
# -----------------
|
||||
# magic methods
|
||||
# -----------------
|
||||
|
||||
@@ -294,20 +294,6 @@ class A():
|
||||
#? list()
|
||||
A().b()
|
||||
|
||||
# -----------------
|
||||
# recursions
|
||||
# -----------------
|
||||
def Recursion():
|
||||
def recurse(self):
|
||||
self.a = self.a
|
||||
self.b = self.b.recurse()
|
||||
|
||||
#?
|
||||
Recursion().a
|
||||
|
||||
#?
|
||||
Recursion().b
|
||||
|
||||
# -----------------
|
||||
# ducktyping
|
||||
# -----------------
|
||||
|
||||
26
test/completion/completion.py
Normal file
26
test/completion/completion.py
Normal file
@@ -0,0 +1,26 @@
|
||||
"""
|
||||
Special cases of completions (typically special positions that caused issues
|
||||
with context parsing.
|
||||
"""
|
||||
|
||||
def pass_decorator(func):
|
||||
return func
|
||||
|
||||
|
||||
def x():
|
||||
return (
|
||||
1,
|
||||
#? ["tuple"]
|
||||
tuple
|
||||
)
|
||||
|
||||
# Comment just somewhere
|
||||
|
||||
|
||||
class MyClass:
|
||||
@pass_decorator
|
||||
def x(foo,
|
||||
#? 5 ["tuple"]
|
||||
tuple,
|
||||
):
|
||||
return 1
|
||||
@@ -173,4 +173,28 @@ def x():
|
||||
[a for a in h if hio]
|
||||
if hio: pass
|
||||
|
||||
# -----------------
|
||||
# slices
|
||||
# -----------------
|
||||
|
||||
#? list()
|
||||
foo = [x for x in [1, '']][:1]
|
||||
#? int()
|
||||
foo[0]
|
||||
|
||||
# -----------------
|
||||
# In class
|
||||
# -----------------
|
||||
|
||||
class X():
|
||||
def __init__(self, bar):
|
||||
self.bar = bar
|
||||
|
||||
def foo(self):
|
||||
x = [a for a in self.bar][0]
|
||||
#? int()
|
||||
x
|
||||
return x
|
||||
|
||||
#? int()
|
||||
X([1]).foo()
|
||||
|
||||
@@ -177,3 +177,44 @@ d = ''
|
||||
""" bsdf """
|
||||
#? str()
|
||||
d.upper()
|
||||
|
||||
# -----------------
|
||||
# class docstrings
|
||||
# -----------------
|
||||
|
||||
class InInit():
|
||||
def __init__(self, foo):
|
||||
"""
|
||||
:type foo: str
|
||||
"""
|
||||
#? str()
|
||||
foo
|
||||
|
||||
|
||||
class InClass():
|
||||
"""
|
||||
:type foo: str
|
||||
"""
|
||||
def __init__(self, foo):
|
||||
#? str()
|
||||
foo
|
||||
|
||||
|
||||
class InBoth():
|
||||
"""
|
||||
:type foo: str
|
||||
"""
|
||||
def __init__(self, foo):
|
||||
"""
|
||||
:type foo: int
|
||||
"""
|
||||
#? str() int()
|
||||
foo
|
||||
|
||||
|
||||
def __init__(foo):
|
||||
"""
|
||||
:type foo: str
|
||||
"""
|
||||
#? str()
|
||||
foo
|
||||
|
||||
@@ -102,6 +102,13 @@ def f(t=None):
|
||||
#! 9 ['t=None']
|
||||
t = t or 1
|
||||
|
||||
|
||||
class X():
|
||||
pass
|
||||
|
||||
#! 3 []
|
||||
X(foo=x)
|
||||
|
||||
# -----------------
|
||||
# imports
|
||||
# -----------------
|
||||
|
||||
51
test/completion/recursion.py
Normal file
51
test/completion/recursion.py
Normal file
@@ -0,0 +1,51 @@
|
||||
"""
|
||||
Code that might cause recursion issues (or has caused in the past).
|
||||
"""
|
||||
|
||||
def Recursion():
|
||||
def recurse(self):
|
||||
self.a = self.a
|
||||
self.b = self.b.recurse()
|
||||
|
||||
#?
|
||||
Recursion().a
|
||||
|
||||
#?
|
||||
Recursion().b
|
||||
|
||||
|
||||
class X():
|
||||
def __init__(self):
|
||||
self.recursive = [1, 3]
|
||||
|
||||
def annoying(self):
|
||||
self.recursive = [self.recursive[0]]
|
||||
|
||||
def recurse(self):
|
||||
self.recursive = [self.recursive[1]]
|
||||
|
||||
#? int()
|
||||
X().recursive[0]
|
||||
|
||||
|
||||
def to_list(iterable):
|
||||
return list(set(iterable))
|
||||
|
||||
|
||||
def recursion1(foo):
|
||||
return to_list(to_list(foo)) + recursion1(foo)
|
||||
|
||||
#? int()
|
||||
recursion1([1,2])[0]
|
||||
|
||||
|
||||
class FooListComp():
|
||||
def __init__(self):
|
||||
self.recursive = [1]
|
||||
|
||||
def annoying(self):
|
||||
self.recursive = [x for x in self.recursive]
|
||||
|
||||
|
||||
#? int()
|
||||
FooListComp().recursive[0]
|
||||
@@ -83,7 +83,7 @@ def test_completion_on_hex_literals():
|
||||
_check_number('0x1.', 'int') # hexdecimal
|
||||
# Completing binary literals doesn't work if they are not actually binary
|
||||
# (invalid statements).
|
||||
assert api.Script('0b2.').completions() == []
|
||||
assert api.Script('0b2.b').completions() == []
|
||||
_check_number('0b1.', 'int') # binary
|
||||
|
||||
_check_number('0x2e.', 'int')
|
||||
@@ -98,8 +98,10 @@ def test_completion_on_complex_literals():
|
||||
_check_number('1j.', 'complex')
|
||||
_check_number('44.j.', 'complex')
|
||||
_check_number('4.0j.', 'complex')
|
||||
# No dot no completion
|
||||
assert api.Script('4j').completions() == []
|
||||
# No dot no completion - I thought, but 4j is actually a literall after
|
||||
# which a keyword like or is allowed. Good times, haha!
|
||||
assert (set([c.name for c in api.Script('4j').completions()]) ==
|
||||
set(['if', 'and', 'in', 'is', 'not', 'or']))
|
||||
|
||||
|
||||
def test_goto_assignments_on_non_name():
|
||||
|
||||
9
test/test_api/test_completion_context.py
Normal file
9
test/test_api/test_completion_context.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from textwrap import dedent
|
||||
from jedi import Script
|
||||
|
||||
|
||||
def test_in_whitespace():
|
||||
code = dedent('''
|
||||
def x():
|
||||
pass''')
|
||||
assert len(Script(code, column=2).completions()) > 20
|
||||
0
test/test_evaluate/nested_namespaces/__init__.py
Normal file
0
test/test_evaluate/nested_namespaces/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
try:
|
||||
__import__('pkg_resources').declare_namespace(__name__)
|
||||
except ImportError:
|
||||
pass
|
||||
@@ -0,0 +1 @@
|
||||
CONST = 1
|
||||
@@ -4,7 +4,7 @@ import sys
|
||||
import pytest
|
||||
|
||||
import jedi
|
||||
from jedi._compatibility import find_module_py33
|
||||
from jedi._compatibility import find_module_py33, find_module
|
||||
from ..helpers import cwd_at
|
||||
|
||||
|
||||
@@ -14,6 +14,44 @@ def test_find_module_py33():
|
||||
assert find_module_py33('_io') == (None, '_io', False)
|
||||
|
||||
|
||||
def test_find_module_package():
|
||||
file, path, is_package = find_module('json')
|
||||
assert file is None
|
||||
assert path.endswith('json')
|
||||
assert is_package is True
|
||||
|
||||
|
||||
def test_find_module_not_package():
|
||||
file, path, is_package = find_module('io')
|
||||
assert file is not None
|
||||
assert path.endswith('io.py')
|
||||
assert is_package is False
|
||||
|
||||
|
||||
def test_find_module_package_zipped():
|
||||
if 'zipped_imports/pkg.zip' not in sys.path:
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__),
|
||||
'zipped_imports/pkg.zip'))
|
||||
file, path, is_package = find_module('pkg')
|
||||
assert file is not None
|
||||
assert path.endswith('pkg.zip')
|
||||
assert is_package is True
|
||||
assert len(jedi.Script('import pkg; pkg.mod', 1, 19).completions()) == 1
|
||||
|
||||
|
||||
@pytest.mark.skipif('sys.version_info < (2,7)')
|
||||
def test_find_module_not_package_zipped():
|
||||
if 'zipped_imports/not_pkg.zip' not in sys.path:
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__),
|
||||
'zipped_imports/not_pkg.zip'))
|
||||
file, path, is_package = find_module('not_pkg')
|
||||
assert file is not None
|
||||
assert path.endswith('not_pkg.zip')
|
||||
assert is_package is False
|
||||
assert len(
|
||||
jedi.Script('import not_pkg; not_pkg.val', 1, 27).completions()) == 1
|
||||
|
||||
|
||||
@cwd_at('test/test_evaluate/not_in_sys_path/pkg')
|
||||
def test_import_not_in_sys_path():
|
||||
"""
|
||||
|
||||
@@ -51,3 +51,15 @@ def test_namespace_package():
|
||||
completion = c
|
||||
solution = "statement: foo = '%s'" % solution
|
||||
assert completion.description == solution
|
||||
|
||||
|
||||
def test_nested_namespace_package():
|
||||
CODE = 'from nested_namespaces.namespace.pkg import CONST'
|
||||
|
||||
sys_path = [dirname(__file__)]
|
||||
|
||||
script = jedi.Script(sys_path=sys_path, source=CODE, line=1, column=45)
|
||||
|
||||
result = script.goto_definitions()
|
||||
|
||||
assert len(result) == 1
|
||||
|
||||
BIN
test/test_evaluate/zipped_imports/not_pkg.zip
Normal file
BIN
test/test_evaluate/zipped_imports/not_pkg.zip
Normal file
Binary file not shown.
BIN
test/test_evaluate/zipped_imports/pkg.zip
Normal file
BIN
test/test_evaluate/zipped_imports/pkg.zip
Normal file
Binary file not shown.
@@ -14,6 +14,7 @@ import jedi
|
||||
from jedi._compatibility import u
|
||||
from jedi import Script
|
||||
from jedi import api
|
||||
from jedi import common
|
||||
from jedi.evaluate import imports
|
||||
from jedi.parser import ParserWithRecovery, load_grammar
|
||||
|
||||
@@ -179,6 +180,15 @@ class TestRegression(TestCase):
|
||||
else:
|
||||
assert n == limit
|
||||
|
||||
def test_source_to_unicode_unicode_text(self):
|
||||
source = (
|
||||
b"# vim: fileencoding=utf-8\n"
|
||||
b"# \xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88\xe3\x81\x8a\n"
|
||||
)
|
||||
actual = common.source_to_unicode(source)
|
||||
expected = source.decode('utf-8')
|
||||
assert actual == expected
|
||||
|
||||
|
||||
def test_loading_unicode_files_with_bad_global_charset(monkeypatch, tmpdir):
|
||||
dirname = str(tmpdir.mkdir('jedi-test'))
|
||||
|
||||
Reference in New Issue
Block a user