Adding new stuff
This commit is contained in:
parent
9ef8a96f9a
commit
0b3d063cb3
1580 changed files with 0 additions and 0 deletions
0
vim-plugins/bundle/jedi-vim/jedi/test/__init__.py
Normal file
0
vim-plugins/bundle/jedi-vim/jedi/test/__init__.py
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
# todo probably remove test_integration_keyword
|
||||
|
||||
def test_keyword_doc():
|
||||
r = list(Script("or", 1, 1).goto_definitions())
|
||||
assert len(r) == 1
|
||||
assert len(r[0].doc) > 100
|
||||
|
||||
r = list(Script("asfdasfd", 1, 1).goto_definitions())
|
||||
assert len(r) == 0
|
||||
|
||||
k = Script("fro").completions()[0]
|
||||
imp_start = '\nThe ``import'
|
||||
assert k.raw_doc.startswith(imp_start)
|
||||
assert k.doc.startswith(imp_start)
|
||||
|
||||
|
||||
def test_blablabla():
|
||||
defs = Script("import").goto_definitions()
|
||||
assert len(defs) == 1 and [1 for d in defs if d.doc]
|
||||
# unrelated to #44
|
||||
|
||||
|
||||
def test_operator_doc(self):
|
||||
r = list(Script("a == b", 1, 3).goto_definitions())
|
||||
assert len(r) == 1
|
||||
assert len(r[0].doc) > 100
|
||||
|
||||
def test_lambda():
|
||||
defs = Script('lambda x: x', column=0).goto_definitions()
|
||||
assert [d.type for d in defs] == ['keyword']
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
""" needed for some modules to test against packages. """
|
||||
|
||||
some_variable = 1
|
||||
430
vim-plugins/bundle/jedi-vim/jedi/test/completion/arrays.py
Normal file
430
vim-plugins/bundle/jedi-vim/jedi/test/completion/arrays.py
Normal file
|
|
@ -0,0 +1,430 @@
|
|||
# -----------------
|
||||
# basic array lookups
|
||||
# -----------------
|
||||
|
||||
|
||||
#? int()
|
||||
[1,""][0]
|
||||
#? str()
|
||||
[1,""][1]
|
||||
#? int() str()
|
||||
[1,""][2]
|
||||
#? int() str()
|
||||
[1,""][20]
|
||||
#? int() str()
|
||||
[1,""][str(hello)]
|
||||
|
||||
a = list()
|
||||
#? list()
|
||||
[a][0]
|
||||
|
||||
#? list()
|
||||
[[a,a,a]][2][100]
|
||||
|
||||
c = [[a,""]]
|
||||
#? str()
|
||||
c[0][1]
|
||||
|
||||
b = [6,7]
|
||||
|
||||
#? int()
|
||||
b[8-7]
|
||||
|
||||
# -----------------
|
||||
# Slices
|
||||
# -----------------
|
||||
#? list()
|
||||
b[8:]
|
||||
|
||||
#? list()
|
||||
b[int():]
|
||||
|
||||
#? list()
|
||||
b[:]
|
||||
|
||||
|
||||
class _StrangeSlice():
|
||||
def __getitem__(self, sliced):
|
||||
return sliced
|
||||
|
||||
# Should not result in an error, just because the slice itself is returned.
|
||||
#? slice()
|
||||
_StrangeSlice()[1:2]
|
||||
|
||||
|
||||
# -----------------
|
||||
# iterable multiplication
|
||||
# -----------------
|
||||
a = ['']*2
|
||||
#? list()
|
||||
a
|
||||
|
||||
# -----------------
|
||||
# tuple assignments
|
||||
# -----------------
|
||||
a1, b1 = (1, "")
|
||||
#? int()
|
||||
a1
|
||||
#? str()
|
||||
b1
|
||||
|
||||
(a2, b2) = (1, "")
|
||||
#? int()
|
||||
a2
|
||||
#? str()
|
||||
b2
|
||||
|
||||
# list assignment
|
||||
[list1, list2] = (1, "")
|
||||
#? int()
|
||||
list1
|
||||
#? str()
|
||||
list2
|
||||
|
||||
[list3, list4] = [1, ""]
|
||||
#? int()
|
||||
list3
|
||||
#? str()
|
||||
list4
|
||||
|
||||
# -----------------
|
||||
# subtuple assignment
|
||||
# -----------------
|
||||
(a3, (b3, c3)) = (1, ("", list))
|
||||
#? list
|
||||
c3
|
||||
|
||||
a4, (b4, c4) = (1, ("", list))
|
||||
#? list
|
||||
c4
|
||||
#? int()
|
||||
a4
|
||||
#? str()
|
||||
b4
|
||||
|
||||
|
||||
# -----------------
|
||||
# multiple assignments
|
||||
# -----------------
|
||||
a = b = 1
|
||||
#? int()
|
||||
a
|
||||
#? int()
|
||||
b
|
||||
|
||||
(a, b) = (c, (e, f)) = ('2', (3, 4))
|
||||
#? str()
|
||||
a
|
||||
#? tuple()
|
||||
b
|
||||
#? str()
|
||||
c
|
||||
#? int()
|
||||
e
|
||||
#? int()
|
||||
f
|
||||
|
||||
|
||||
# -----------------
|
||||
# unnessecary braces
|
||||
# -----------------
|
||||
a = (1)
|
||||
#? int()
|
||||
a
|
||||
#? int()
|
||||
(1)
|
||||
#? int()
|
||||
((1))
|
||||
#? int()
|
||||
((1)+1)
|
||||
|
||||
u, v = 1, ""
|
||||
#? int()
|
||||
u
|
||||
|
||||
((u1, v1)) = 1, ""
|
||||
#? int()
|
||||
u1
|
||||
#? int()
|
||||
(u1)
|
||||
|
||||
(a), b = 1, ''
|
||||
#? int()
|
||||
a
|
||||
|
||||
def a(): return ''
|
||||
#? str()
|
||||
(a)()
|
||||
#? str()
|
||||
(a)().replace()
|
||||
#? int()
|
||||
(tuple).index()
|
||||
#? int()
|
||||
(tuple)().index()
|
||||
|
||||
class C():
|
||||
def __init__(self):
|
||||
self.a = (str()).upper()
|
||||
|
||||
#? str()
|
||||
C().a
|
||||
|
||||
# -----------------
|
||||
# imbalanced sides
|
||||
# -----------------
|
||||
(f, g) = (1,)
|
||||
#? int()
|
||||
f
|
||||
#? []
|
||||
g.
|
||||
|
||||
(f, g, h) = (1,'')
|
||||
#? int()
|
||||
f
|
||||
#? str()
|
||||
g
|
||||
#? []
|
||||
h.
|
||||
|
||||
(f1, g1) = 1
|
||||
#? []
|
||||
f1.
|
||||
#? []
|
||||
g1.
|
||||
|
||||
(f, g) = (1,'',1.0)
|
||||
#? int()
|
||||
f
|
||||
#? str()
|
||||
g
|
||||
|
||||
# -----------------
|
||||
# dicts
|
||||
# -----------------
|
||||
dic2 = {'asdf': 3, 'b': 'str'}
|
||||
#? int()
|
||||
dic2['asdf']
|
||||
|
||||
# string literal
|
||||
#? int()
|
||||
dic2[r'asdf']
|
||||
#? int()
|
||||
dic2[r'asdf']
|
||||
#? int()
|
||||
dic2[r'as' 'd' u'f']
|
||||
#? int() str()
|
||||
dic2['just_something']
|
||||
|
||||
# unpacking
|
||||
a, b = dic2
|
||||
#? str()
|
||||
a
|
||||
a, b = {1: 'x', 2.0: 1j}
|
||||
#? int() float()
|
||||
a
|
||||
#? int() float()
|
||||
b
|
||||
|
||||
|
||||
def f():
|
||||
""" github #83 """
|
||||
r = {}
|
||||
r['status'] = (200, 'ok')
|
||||
return r
|
||||
|
||||
#? dict()
|
||||
f()
|
||||
|
||||
# completion within dicts
|
||||
#? 9 ['str']
|
||||
{str: str}
|
||||
|
||||
# iteration problem (detected with sith)
|
||||
d = dict({'a':''})
|
||||
def y(a):
|
||||
return a
|
||||
#?
|
||||
y(**d)
|
||||
|
||||
# problem with more complicated casts
|
||||
dic = {str(key): ''}
|
||||
#? str()
|
||||
dic['']
|
||||
|
||||
|
||||
for x in {1: 3.0, '': 1j}:
|
||||
#? int() str()
|
||||
x
|
||||
|
||||
# -----------------
|
||||
# with variable as index
|
||||
# -----------------
|
||||
a = (1, "")
|
||||
index = 1
|
||||
#? str()
|
||||
a[index]
|
||||
|
||||
# these should just ouput the whole array
|
||||
index = int
|
||||
#? int() str()
|
||||
a[index]
|
||||
index = int()
|
||||
#? int() str()
|
||||
a[index]
|
||||
|
||||
# dicts
|
||||
index = 'asdf'
|
||||
|
||||
dic2 = {'asdf': 3, 'b': 'str'}
|
||||
#? int()
|
||||
dic2[index]
|
||||
|
||||
# -----------------
|
||||
# __getitem__
|
||||
# -----------------
|
||||
|
||||
class GetItem():
|
||||
def __getitem__(self, index):
|
||||
return 1.0
|
||||
|
||||
#? float()
|
||||
GetItem()[0]
|
||||
|
||||
class GetItem():
|
||||
def __init__(self, el):
|
||||
self.el = el
|
||||
|
||||
def __getitem__(self, index):
|
||||
return self.el
|
||||
|
||||
#? str()
|
||||
GetItem("")[1]
|
||||
|
||||
class GetItemWithList():
|
||||
def __getitem__(self, index):
|
||||
return [1, 1.0, 's'][index]
|
||||
|
||||
#? float()
|
||||
GetItemWithList()[1]
|
||||
|
||||
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
|
||||
# -----------------
|
||||
|
||||
a = [1, ""]
|
||||
#? int() str()
|
||||
list(a)[1]
|
||||
|
||||
#? int() str()
|
||||
list(a)[0]
|
||||
#?
|
||||
set(a)[0]
|
||||
|
||||
#? int() str()
|
||||
list(set(a))[1]
|
||||
#? int() str()
|
||||
list(list(set(a)))[1]
|
||||
|
||||
# does not yet work, because the recursion catching is not good enough (catches # to much)
|
||||
#? int() str()
|
||||
list(set(list(set(a))))[1]
|
||||
#? int() str()
|
||||
list(set(set(a)))[1]
|
||||
|
||||
# frozenset
|
||||
#? int() str()
|
||||
list(frozenset(a))[1]
|
||||
#? int() str()
|
||||
list(set(frozenset(a)))[1]
|
||||
|
||||
# iter
|
||||
#? int() str()
|
||||
list(iter(a))[1]
|
||||
#? int() str()
|
||||
list(iter(list(set(a))))[1]
|
||||
|
||||
# tuple
|
||||
#? int() str()
|
||||
tuple(a)[1]
|
||||
#? int() str()
|
||||
tuple(list(set(a)))[1]
|
||||
|
||||
#? int()
|
||||
tuple({1})[0]
|
||||
#? int()
|
||||
tuple((1,))[0]
|
||||
|
||||
# implementation detail for lists, should not be visible
|
||||
#? []
|
||||
list().__iterable
|
||||
|
||||
# With a list comprehension.
|
||||
for i in set(a for a in [1]):
|
||||
#? int()
|
||||
i
|
||||
|
||||
|
||||
# -----------------
|
||||
# Merged Arrays
|
||||
# -----------------
|
||||
|
||||
for x in [1] + ['']:
|
||||
#? int() str()
|
||||
x
|
||||
|
||||
# -----------------
|
||||
# For loops with attribute assignment.
|
||||
# -----------------
|
||||
def test_func():
|
||||
x = 'asdf'
|
||||
for x.something in [6,7,8]:
|
||||
pass
|
||||
#? str()
|
||||
x
|
||||
|
||||
for x.something, b in [[6, 6.0]]:
|
||||
pass
|
||||
#? str()
|
||||
x
|
||||
|
||||
|
||||
# -----------------
|
||||
# PEP 3132 Extended Iterable Unpacking (star unpacking)
|
||||
# -----------------
|
||||
|
||||
a, *b, c = [1, 'b', list, dict]
|
||||
#? int()
|
||||
a
|
||||
#? str()
|
||||
b
|
||||
#? list
|
||||
c
|
||||
|
||||
# Not valid syntax
|
||||
a, *b, *c = [1, 'd', list]
|
||||
#? int()
|
||||
a
|
||||
#? str()
|
||||
b
|
||||
#? list
|
||||
c
|
||||
|
||||
lc = [x for a, *x in [(1, '', 1.0)]]
|
||||
|
||||
#?
|
||||
lc[0][0]
|
||||
293
vim-plugins/bundle/jedi-vim/jedi/test/completion/basic.py
Normal file
293
vim-plugins/bundle/jedi-vim/jedi/test/completion/basic.py
Normal file
|
|
@ -0,0 +1,293 @@
|
|||
# -----------------
|
||||
# cursor position
|
||||
# -----------------
|
||||
#? 0 int
|
||||
int()
|
||||
#? 3 int
|
||||
int()
|
||||
#? 4 str
|
||||
int(str)
|
||||
|
||||
|
||||
# -----------------
|
||||
# should not complete
|
||||
# -----------------
|
||||
#? []
|
||||
.
|
||||
#? []
|
||||
str..
|
||||
#? []
|
||||
a(0):.
|
||||
|
||||
# -----------------
|
||||
# if/else/elif
|
||||
# -----------------
|
||||
|
||||
if (random.choice([0, 1])):
|
||||
1
|
||||
elif(random.choice([0, 1])):
|
||||
a = 3
|
||||
else:
|
||||
a = ''
|
||||
#? int() str()
|
||||
a
|
||||
def func():
|
||||
if random.choice([0, 1]):
|
||||
1
|
||||
elif(random.choice([0, 1])):
|
||||
a = 3
|
||||
else:
|
||||
a = ''
|
||||
#? int() str()
|
||||
return a
|
||||
#? int() str()
|
||||
func()
|
||||
|
||||
# -----------------
|
||||
# keywords
|
||||
# -----------------
|
||||
|
||||
#? list()
|
||||
assert []
|
||||
|
||||
def focus_return():
|
||||
#? list()
|
||||
return []
|
||||
|
||||
|
||||
# -----------------
|
||||
# for loops
|
||||
# -----------------
|
||||
|
||||
for a in [1,2]:
|
||||
#? int()
|
||||
a
|
||||
|
||||
for a1 in 1,"":
|
||||
#? int() str()
|
||||
a1
|
||||
|
||||
for a3, b3 in (1,""), (1,""), (1,""):
|
||||
#? int()
|
||||
a3
|
||||
#? str()
|
||||
b3
|
||||
|
||||
for a4, (b4, c4) in (1,("", list)), (1,("", list)):
|
||||
#? int()
|
||||
a4
|
||||
#? str()
|
||||
b4
|
||||
#? list
|
||||
c4
|
||||
|
||||
a = []
|
||||
for i in [1,'']:
|
||||
#? int() str()
|
||||
i
|
||||
a += [i]
|
||||
|
||||
#? int() str()
|
||||
a[0]
|
||||
|
||||
for i in list([1,'']):
|
||||
#? int() str()
|
||||
i
|
||||
|
||||
#? int() str()
|
||||
for x in [1,'']: x
|
||||
|
||||
a = []
|
||||
b = [1.0,'']
|
||||
for i in b:
|
||||
a += [i]
|
||||
|
||||
#? float() str()
|
||||
a[0]
|
||||
|
||||
for i in [1,2,3]:
|
||||
#? int()
|
||||
i
|
||||
else:
|
||||
i
|
||||
|
||||
|
||||
# -----------------
|
||||
# range()
|
||||
# -----------------
|
||||
for i in range(10):
|
||||
#? int()
|
||||
i
|
||||
|
||||
# -----------------
|
||||
# ternary operator
|
||||
# -----------------
|
||||
|
||||
a = 3
|
||||
b = '' if a else set()
|
||||
#? str() set()
|
||||
b
|
||||
|
||||
def ret(a):
|
||||
return ['' if a else set()]
|
||||
|
||||
#? str() set()
|
||||
ret(1)[0]
|
||||
#? str() set()
|
||||
ret()[0]
|
||||
|
||||
# -----------------
|
||||
# with statements
|
||||
# -----------------
|
||||
|
||||
with open('') as f:
|
||||
#? ['closed']
|
||||
f.closed
|
||||
for line in f:
|
||||
#? str()
|
||||
line
|
||||
|
||||
with open('') as f1, open('') as f2:
|
||||
#? ['closed']
|
||||
f1.closed
|
||||
#? ['closed']
|
||||
f2.closed
|
||||
|
||||
|
||||
# -----------------
|
||||
# global vars
|
||||
# -----------------
|
||||
|
||||
def global_define():
|
||||
global global_var_in_func
|
||||
global_var_in_func = 3
|
||||
|
||||
#? int()
|
||||
global_var_in_func
|
||||
|
||||
|
||||
def funct1():
|
||||
# From issue #610
|
||||
global global_dict_var
|
||||
global_dict_var = dict()
|
||||
def funct2():
|
||||
global global_dict_var
|
||||
#? dict()
|
||||
global_dict_var
|
||||
|
||||
|
||||
# -----------------
|
||||
# within docstrs
|
||||
# -----------------
|
||||
|
||||
def a():
|
||||
"""
|
||||
#? ['global_define']
|
||||
global_define
|
||||
"""
|
||||
pass
|
||||
|
||||
#?
|
||||
# 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
|
||||
# -----------------
|
||||
|
||||
class A(object): pass
|
||||
class B(): pass
|
||||
|
||||
#? ['__init__']
|
||||
A.__init__
|
||||
#? ['__init__']
|
||||
B.__init__
|
||||
|
||||
#? ['__init__']
|
||||
int().__init__
|
||||
|
||||
# -----------------
|
||||
# comments
|
||||
# -----------------
|
||||
|
||||
class A():
|
||||
def __init__(self):
|
||||
self.hello = {} # comment shouldn't be a string
|
||||
#? dict()
|
||||
A().hello
|
||||
|
||||
# -----------------
|
||||
# unicode
|
||||
# -----------------
|
||||
a = 'smörbröd'
|
||||
#? str()
|
||||
a
|
||||
xyz = 'smörbröd.py'
|
||||
if 1:
|
||||
#? str()
|
||||
xyz
|
||||
|
||||
#?
|
||||
¹.
|
||||
|
||||
# -----------------
|
||||
# exceptions
|
||||
# -----------------
|
||||
try:
|
||||
import math
|
||||
except ImportError as i_a:
|
||||
#? ['i_a']
|
||||
i_a
|
||||
#? ImportError()
|
||||
i_a
|
||||
try:
|
||||
import math
|
||||
except ImportError, i_b:
|
||||
# TODO check this only in Python2
|
||||
##? ['i_b']
|
||||
i_b
|
||||
##? ImportError()
|
||||
i_b
|
||||
|
||||
|
||||
class MyException(Exception):
|
||||
def __init__(self, my_attr):
|
||||
self.my_attr = my_attr
|
||||
|
||||
try:
|
||||
raise MyException(1)
|
||||
except MyException as e:
|
||||
#? ['my_attr']
|
||||
e.my_attr
|
||||
#? 22 ['my_attr']
|
||||
for x in e.my_attr:
|
||||
pass
|
||||
|
||||
|
||||
# -----------------
|
||||
# continuations
|
||||
# -----------------
|
||||
|
||||
foo = \
|
||||
1
|
||||
#? int()
|
||||
foo
|
||||
|
||||
# -----------------
|
||||
# module attributes
|
||||
# -----------------
|
||||
|
||||
# Don't move this to imports.py, because there's a star import.
|
||||
#? str()
|
||||
__file__
|
||||
#? ['__file__']
|
||||
__file__
|
||||
470
vim-plugins/bundle/jedi-vim/jedi/test/completion/classes.py
Normal file
470
vim-plugins/bundle/jedi-vim/jedi/test/completion/classes.py
Normal file
|
|
@ -0,0 +1,470 @@
|
|||
def find_class():
|
||||
""" This scope is special, because its in front of TestClass """
|
||||
#? ['ret']
|
||||
TestClass.ret
|
||||
if 1:
|
||||
#? ['ret']
|
||||
TestClass.ret
|
||||
|
||||
class FindClass():
|
||||
#? []
|
||||
TestClass.ret
|
||||
if a:
|
||||
#? []
|
||||
TestClass.ret
|
||||
|
||||
def find_class(self):
|
||||
#? ['ret']
|
||||
TestClass.ret
|
||||
if 1:
|
||||
#? ['ret']
|
||||
TestClass.ret
|
||||
|
||||
#? []
|
||||
FindClass().find_class.self
|
||||
#? []
|
||||
FindClass().find_class.self.find_class
|
||||
|
||||
# set variables, which should not be included, because they don't belong to the
|
||||
# class
|
||||
second = 1
|
||||
second = ""
|
||||
class TestClass(object):
|
||||
var_class = TestClass(1)
|
||||
|
||||
def __init__(self2, first_param, second_param, third=1.0):
|
||||
self2.var_inst = first_param
|
||||
self2.second = second_param
|
||||
self2.first = first_param
|
||||
a = 3
|
||||
|
||||
def var_func(self):
|
||||
return 1
|
||||
|
||||
def get_first(self):
|
||||
# traversal
|
||||
self.second_new = self.second
|
||||
return self.var_inst
|
||||
|
||||
def values(self):
|
||||
self.var_local = 3
|
||||
#? ['var_class', 'var_func', 'var_inst', 'var_local']
|
||||
self.var_
|
||||
|
||||
def ret(self, a1):
|
||||
# should not know any class functions!
|
||||
#? []
|
||||
values
|
||||
#? ['return']
|
||||
ret
|
||||
return a1
|
||||
|
||||
# should not work
|
||||
#? []
|
||||
var_local
|
||||
#? []
|
||||
var_inst
|
||||
#? []
|
||||
var_func
|
||||
|
||||
# instance
|
||||
inst = TestClass(1)
|
||||
|
||||
#? ['var_class', 'var_func', 'var_inst', 'var_local']
|
||||
inst.var
|
||||
|
||||
#? ['var_class', 'var_func']
|
||||
TestClass.var
|
||||
|
||||
#? int()
|
||||
inst.var_local
|
||||
#? []
|
||||
TestClass.var_local.
|
||||
|
||||
#? int()
|
||||
TestClass().ret(1)
|
||||
# Should not return int(), because we want the type before `.ret(1)`.
|
||||
#? 11 TestClass()
|
||||
TestClass().ret(1)
|
||||
#? int()
|
||||
inst.ret(1)
|
||||
|
||||
myclass = TestClass(1, '', 3.0)
|
||||
#? int()
|
||||
myclass.get_first()
|
||||
#? []
|
||||
myclass.get_first.real
|
||||
|
||||
# too many params
|
||||
#? int()
|
||||
TestClass(1,1,1).var_inst
|
||||
|
||||
# too few params
|
||||
#? int()
|
||||
TestClass(1).first
|
||||
#? []
|
||||
TestClass(1).second.
|
||||
|
||||
# complicated variable settings in class
|
||||
#? str()
|
||||
myclass.second
|
||||
#? str()
|
||||
myclass.second_new
|
||||
|
||||
# multiple classes / ordering
|
||||
ints = TestClass(1, 1.0)
|
||||
strs = TestClass("", '')
|
||||
#? float()
|
||||
ints.second
|
||||
#? str()
|
||||
strs.second
|
||||
|
||||
#? ['var_class']
|
||||
TestClass.var_class.var_class.var_class.var_class
|
||||
|
||||
# operations (+, *, etc) shouldn't be InstanceElements - #246
|
||||
class A():
|
||||
def __init__(self):
|
||||
self.addition = 1 + 2
|
||||
#? int()
|
||||
A().addition
|
||||
|
||||
# should also work before `=`
|
||||
#? 8 int()
|
||||
A().addition = None
|
||||
#? 8 int()
|
||||
A(1).addition = None
|
||||
#? 1 A
|
||||
A(1).addition = None
|
||||
a = A()
|
||||
#? 8 int()
|
||||
a.addition = None
|
||||
|
||||
|
||||
# -----------------
|
||||
# inheritance
|
||||
# -----------------
|
||||
|
||||
class Base(object):
|
||||
def method_base(self):
|
||||
return 1
|
||||
|
||||
class SuperClass(Base):
|
||||
class_super = 3
|
||||
def __init__(self):
|
||||
self.var_super = ''
|
||||
def method_super(self):
|
||||
self.var2_super = list
|
||||
|
||||
class Mixin(SuperClass):
|
||||
def method_mixin(self):
|
||||
return int
|
||||
|
||||
#? 20 SuperClass
|
||||
class SubClass(SuperClass):
|
||||
class_sub = 3
|
||||
def __init__(self):
|
||||
self.var_sub = ''
|
||||
def method_sub(self):
|
||||
self.var_sub = list
|
||||
return tuple
|
||||
|
||||
instance = SubClass()
|
||||
|
||||
#? ['method_base', 'method_sub', 'method_super']
|
||||
instance.method_
|
||||
#? ['var2_super', 'var_sub', 'var_super']
|
||||
instance.var
|
||||
#? ['class_sub', 'class_super']
|
||||
instance.class_
|
||||
|
||||
#? ['method_base', 'method_sub', 'method_super']
|
||||
SubClass.method_
|
||||
#? []
|
||||
SubClass.var
|
||||
#? ['class_sub', 'class_super']
|
||||
SubClass.class_
|
||||
|
||||
# -----------------
|
||||
# inheritance of builtins
|
||||
# -----------------
|
||||
|
||||
class Base(str):
|
||||
pass
|
||||
|
||||
#? ['upper']
|
||||
Base.upper
|
||||
#? ['upper']
|
||||
Base().upper
|
||||
|
||||
# -----------------
|
||||
# dynamic inheritance
|
||||
# -----------------
|
||||
|
||||
class Angry(object):
|
||||
def shout(self):
|
||||
return 'THIS IS MALARKEY!'
|
||||
|
||||
def classgetter():
|
||||
return Angry
|
||||
|
||||
class Dude(classgetter()):
|
||||
def react(self):
|
||||
#? ['shout']
|
||||
self.s
|
||||
|
||||
# -----------------
|
||||
# __call__
|
||||
# -----------------
|
||||
|
||||
class CallClass():
|
||||
def __call__(self):
|
||||
return 1
|
||||
|
||||
#? int()
|
||||
CallClass()()
|
||||
|
||||
# -----------------
|
||||
# variable assignments
|
||||
# -----------------
|
||||
|
||||
class V:
|
||||
def __init__(self, a):
|
||||
self.a = a
|
||||
|
||||
def ret(self):
|
||||
return self.a
|
||||
|
||||
d = b
|
||||
b = ret
|
||||
if 1:
|
||||
c = b
|
||||
|
||||
#? int()
|
||||
V(1).b()
|
||||
#? int()
|
||||
V(1).c()
|
||||
#?
|
||||
V(1).d()
|
||||
# Only keywords should be possible to complete.
|
||||
#? ['is', 'in', 'not', 'and', 'or', 'if']
|
||||
V(1).d()
|
||||
|
||||
|
||||
# -----------------
|
||||
# ordering
|
||||
# -----------------
|
||||
class A():
|
||||
def b(self):
|
||||
#? int()
|
||||
a_func()
|
||||
#? str()
|
||||
self.a_func()
|
||||
return a_func()
|
||||
|
||||
def a_func(self):
|
||||
return ""
|
||||
|
||||
def a_func():
|
||||
return 1
|
||||
|
||||
#? int()
|
||||
A().b()
|
||||
#? str()
|
||||
A().a_func()
|
||||
|
||||
# -----------------
|
||||
# nested classes
|
||||
# -----------------
|
||||
class A():
|
||||
class B():
|
||||
pass
|
||||
def b(self):
|
||||
return 1.0
|
||||
|
||||
#? float()
|
||||
A().b()
|
||||
|
||||
class A():
|
||||
def b(self):
|
||||
class B():
|
||||
def b(self):
|
||||
return []
|
||||
return B().b()
|
||||
|
||||
#? list()
|
||||
A().b()
|
||||
|
||||
# -----------------
|
||||
# ducktyping
|
||||
# -----------------
|
||||
|
||||
def meth(self):
|
||||
return self.a, self.b
|
||||
|
||||
class WithoutMethod():
|
||||
a = 1
|
||||
def __init__(self):
|
||||
self.b = 1.0
|
||||
def blub(self):
|
||||
return self.b
|
||||
m = meth
|
||||
|
||||
class B():
|
||||
b = ''
|
||||
|
||||
a = WithoutMethod().m()
|
||||
#? int()
|
||||
a[0]
|
||||
#? float()
|
||||
a[1]
|
||||
|
||||
#? float()
|
||||
WithoutMethod.blub(WithoutMethod())
|
||||
#? str()
|
||||
WithoutMethod.blub(B())
|
||||
|
||||
# -----------------
|
||||
# __getattr__ / getattr() / __getattribute__
|
||||
# -----------------
|
||||
|
||||
#? str().upper
|
||||
getattr(str(), 'upper')
|
||||
#? str.upper
|
||||
getattr(str, 'upper')
|
||||
|
||||
# some strange getattr calls
|
||||
#?
|
||||
getattr(str, 1)
|
||||
#?
|
||||
getattr()
|
||||
#?
|
||||
getattr(str)
|
||||
#?
|
||||
getattr(getattr, 1)
|
||||
#?
|
||||
getattr(str, [])
|
||||
|
||||
|
||||
class Base():
|
||||
def ret(self, b):
|
||||
return b
|
||||
|
||||
class Wrapper():
|
||||
def __init__(self, obj):
|
||||
self.obj = obj
|
||||
|
||||
def __getattr__(self, name):
|
||||
return getattr(self.obj, name)
|
||||
|
||||
class Wrapper2():
|
||||
def __getattribute__(self, name):
|
||||
return getattr(Base(), name)
|
||||
|
||||
#? int()
|
||||
Wrapper(Base()).ret(3)
|
||||
|
||||
#? int()
|
||||
Wrapper2(Base()).ret(3)
|
||||
|
||||
class GetattrArray():
|
||||
def __getattr__(self, name):
|
||||
return [1]
|
||||
|
||||
#? int()
|
||||
GetattrArray().something[0]
|
||||
|
||||
|
||||
# -----------------
|
||||
# private vars
|
||||
# -----------------
|
||||
class PrivateVar():
|
||||
def __init__(self):
|
||||
self.__var = 1
|
||||
#? int()
|
||||
self.__var
|
||||
#? ['__var']
|
||||
self.__var
|
||||
#? []
|
||||
PrivateVar().__var
|
||||
#?
|
||||
PrivateVar().__var
|
||||
|
||||
# -----------------
|
||||
# super
|
||||
# -----------------
|
||||
class Super(object):
|
||||
a = 3
|
||||
def return_sup(self):
|
||||
return 1
|
||||
|
||||
class TestSuper(Super):
|
||||
#?
|
||||
super()
|
||||
def test(self):
|
||||
#? Super()
|
||||
super()
|
||||
#? ['a']
|
||||
super().a
|
||||
if 1:
|
||||
#? Super()
|
||||
super()
|
||||
def a():
|
||||
#?
|
||||
super()
|
||||
|
||||
def return_sup(self):
|
||||
#? int()
|
||||
return super().return_sup()
|
||||
|
||||
#? int()
|
||||
TestSuper().return_sup()
|
||||
|
||||
|
||||
# -----------------
|
||||
# if flow at class level
|
||||
# -----------------
|
||||
class TestX(object):
|
||||
def normal_method(self):
|
||||
return 1
|
||||
|
||||
if True:
|
||||
def conditional_method(self):
|
||||
var = self.normal_method()
|
||||
#? int()
|
||||
var
|
||||
return 2
|
||||
|
||||
def other_method(self):
|
||||
var = self.conditional_method()
|
||||
#? int()
|
||||
var
|
||||
|
||||
# -----------------
|
||||
# mro method
|
||||
# -----------------
|
||||
|
||||
class A(object):
|
||||
a = 3
|
||||
|
||||
#? ['mro']
|
||||
A.mro
|
||||
#? []
|
||||
A().mro
|
||||
|
||||
|
||||
# -----------------
|
||||
# mro resolution
|
||||
# -----------------
|
||||
|
||||
class B(A()):
|
||||
b = 3
|
||||
|
||||
#?
|
||||
B.a
|
||||
#?
|
||||
B().a
|
||||
#? int()
|
||||
B.b
|
||||
#? int()
|
||||
B().b
|
||||
|
|
@ -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
|
||||
14
vim-plugins/bundle/jedi-vim/jedi/test/completion/complex.py
Normal file
14
vim-plugins/bundle/jedi-vim/jedi/test/completion/complex.py
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
""" Mostly for stupid error reports of @dbrgn. :-) """
|
||||
|
||||
import time
|
||||
|
||||
class Foo(object):
|
||||
global time
|
||||
asdf = time
|
||||
|
||||
def asdfy():
|
||||
return Foo
|
||||
|
||||
xorz = getattr(asdfy()(), 'asdf')
|
||||
#? time
|
||||
xorz
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
# -----------------
|
||||
# list comprehensions
|
||||
# -----------------
|
||||
|
||||
# basics:
|
||||
|
||||
a = ['' for a in [1]]
|
||||
#? str()
|
||||
a[0]
|
||||
#? ['insert']
|
||||
a.insert
|
||||
|
||||
a = [a for a in [1]]
|
||||
#? int()
|
||||
a[0]
|
||||
|
||||
y = 1.0
|
||||
# Should not leak.
|
||||
[y for y in [3]]
|
||||
#? float()
|
||||
y
|
||||
|
||||
a = [a for a in (1, 2)]
|
||||
#? int()
|
||||
a[0]
|
||||
|
||||
a = [a for a,b in [(1,'')]]
|
||||
#? int()
|
||||
a[0]
|
||||
|
||||
arr = [1,'']
|
||||
a = [a for a in arr]
|
||||
#? int()
|
||||
a[0]
|
||||
#? str()
|
||||
a[1]
|
||||
#? int() str()
|
||||
a[2]
|
||||
|
||||
a = [a if 1.0 else '' for a in [1] if [1.0]]
|
||||
#? int() str()
|
||||
a[0]
|
||||
|
||||
# name resolve should be correct
|
||||
left, right = 'a', 'b'
|
||||
left, right = [x for x in (left, right)]
|
||||
#? str()
|
||||
left
|
||||
|
||||
# with a dict literal
|
||||
#? int()
|
||||
[a for a in {1:'x'}][0]
|
||||
|
||||
# list comprehensions should also work in combination with functions
|
||||
def listen(arg):
|
||||
for x in arg:
|
||||
#? str()
|
||||
x
|
||||
|
||||
listen(['' for x in [1]])
|
||||
#?
|
||||
([str for x in []])[0]
|
||||
|
||||
# with a set literal
|
||||
#? int()
|
||||
[a for a in {1, 2, 3}][0]
|
||||
|
||||
# -----------------
|
||||
# nested list comprehensions
|
||||
# -----------------
|
||||
|
||||
b = [a for arr in [[1]] for a in arr]
|
||||
#? int()
|
||||
b[0]
|
||||
|
||||
b = [a for arr in [[1]] if '' for a in arr if '']
|
||||
#? int()
|
||||
b[0]
|
||||
|
||||
b = [b for arr in [[[1.0]]] for a in arr for b in a]
|
||||
#? float()
|
||||
b[0]
|
||||
|
||||
# jedi issue #26
|
||||
#? list()
|
||||
a = [[int(v) for v in line.strip().split() if v] for line in ["123", "123", "123"] if line]
|
||||
#? list()
|
||||
a[0]
|
||||
#? int()
|
||||
a[0][0]
|
||||
|
||||
# -----------------
|
||||
# generator comprehensions
|
||||
# -----------------
|
||||
|
||||
left, right = (i for i in (1, ''))
|
||||
|
||||
#? int()
|
||||
left
|
||||
#? str()
|
||||
right
|
||||
|
||||
gen = (i for i in (1,))
|
||||
|
||||
#? int()
|
||||
next(gen)
|
||||
#?
|
||||
gen[0]
|
||||
|
||||
gen = (a for arr in [[1.0]] for a in arr)
|
||||
#? float()
|
||||
next(gen)
|
||||
|
||||
#? int()
|
||||
(i for i in (1,)).send()
|
||||
|
||||
# issues with different formats
|
||||
left, right = (i for i in
|
||||
('1', 2))
|
||||
#? str()
|
||||
left
|
||||
#? int()
|
||||
right
|
||||
|
||||
# -----------------
|
||||
# dict comprehensions
|
||||
# -----------------
|
||||
|
||||
#? int()
|
||||
list({a - 1: 3 for a in [1]})[0]
|
||||
|
||||
d = {a - 1: b for a, b in {1: 'a', 3: 1.0}.items()}
|
||||
#? int()
|
||||
list(d)[0]
|
||||
#? str() float()
|
||||
d.values()[0]
|
||||
#? str()
|
||||
d[0]
|
||||
#? float() str()
|
||||
d[1]
|
||||
#? float()
|
||||
d[2]
|
||||
|
||||
# -----------------
|
||||
# set comprehensions
|
||||
# -----------------
|
||||
|
||||
#? set()
|
||||
{a - 1 for a in [1]}
|
||||
|
||||
#? set()
|
||||
{a for a in range(10)}
|
||||
|
||||
#? int()
|
||||
[x for x in {a for a in range(10)}][0]
|
||||
|
||||
#? int()
|
||||
{a for a in range(10)}.pop()
|
||||
#? float() str()
|
||||
{b for a in [[3.0], ['']] for b in a}.pop()
|
||||
|
||||
#? int()
|
||||
next(iter({a for a in range(10)}))
|
||||
|
||||
|
||||
# -----------------
|
||||
# name resolution in comprehensions.
|
||||
# -----------------
|
||||
|
||||
def x():
|
||||
"""Should not try to resolve to the if hio, which was a bug."""
|
||||
#? 22
|
||||
[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()
|
||||
32
vim-plugins/bundle/jedi-vim/jedi/test/completion/context.py
Normal file
32
vim-plugins/bundle/jedi-vim/jedi/test/completion/context.py
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
class Base():
|
||||
myfoobar = 3
|
||||
|
||||
|
||||
class X(Base):
|
||||
def func(self, foo):
|
||||
pass
|
||||
|
||||
|
||||
class Y(X):
|
||||
def actual_function(self):
|
||||
pass
|
||||
|
||||
#? []
|
||||
def actual_function
|
||||
#? ['func']
|
||||
def f
|
||||
|
||||
#? []
|
||||
def __class__
|
||||
|
||||
#? ['__repr__']
|
||||
def __repr__
|
||||
|
||||
#? []
|
||||
def mro
|
||||
|
||||
#? ['myfoobar']
|
||||
myfoobar
|
||||
|
||||
#? []
|
||||
myfoobar
|
||||
306
vim-plugins/bundle/jedi-vim/jedi/test/completion/decorators.py
Normal file
306
vim-plugins/bundle/jedi-vim/jedi/test/completion/decorators.py
Normal file
|
|
@ -0,0 +1,306 @@
|
|||
# -----------------
|
||||
# normal decorators
|
||||
# -----------------
|
||||
|
||||
def decorator(func):
|
||||
def wrapper(*args):
|
||||
return func(1, *args)
|
||||
return wrapper
|
||||
|
||||
@decorator
|
||||
def decorated(a,b):
|
||||
return a,b
|
||||
|
||||
exe = decorated(set, '')
|
||||
|
||||
#? set
|
||||
exe[1]
|
||||
|
||||
#? int()
|
||||
exe[0]
|
||||
|
||||
# more complicated with args/kwargs
|
||||
def dec(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
return func(*args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
@dec
|
||||
def fu(a, b, c, *args, **kwargs):
|
||||
return a, b, c, args, kwargs
|
||||
|
||||
exe = fu(list, c=set, b=3, d='')
|
||||
|
||||
#? list
|
||||
exe[0]
|
||||
#? int()
|
||||
exe[1]
|
||||
#? set
|
||||
exe[2]
|
||||
#? []
|
||||
exe[3][0].
|
||||
#? str()
|
||||
exe[4]['d']
|
||||
|
||||
|
||||
exe = fu(list, set, 3, '', d='')
|
||||
|
||||
#? str()
|
||||
exe[3][0]
|
||||
|
||||
# -----------------
|
||||
# multiple decorators
|
||||
# -----------------
|
||||
def dec2(func2):
|
||||
def wrapper2(first_arg, *args2, **kwargs2):
|
||||
return func2(first_arg, *args2, **kwargs2)
|
||||
return wrapper2
|
||||
|
||||
@dec2
|
||||
@dec
|
||||
def fu2(a, b, c, *args, **kwargs):
|
||||
return a, b, c, args, kwargs
|
||||
|
||||
exe = fu2(list, c=set, b=3, d='str')
|
||||
|
||||
#? list
|
||||
exe[0]
|
||||
#? int()
|
||||
exe[1]
|
||||
#? set
|
||||
exe[2]
|
||||
#? []
|
||||
exe[3][0].
|
||||
#? str()
|
||||
exe[4]['d']
|
||||
|
||||
|
||||
# -----------------
|
||||
# Decorator is a class
|
||||
# -----------------
|
||||
def same_func(func):
|
||||
return func
|
||||
|
||||
class Decorator(object):
|
||||
def __init__(self, func):
|
||||
self.func = func
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
return self.func(1, *args, **kwargs)
|
||||
|
||||
@Decorator
|
||||
def nothing(a,b,c):
|
||||
return a,b,c
|
||||
|
||||
#? int()
|
||||
nothing("")[0]
|
||||
#? str()
|
||||
nothing("")[1]
|
||||
|
||||
|
||||
@same_func
|
||||
@Decorator
|
||||
def nothing(a,b,c):
|
||||
return a,b,c
|
||||
|
||||
#? int()
|
||||
nothing("")[0]
|
||||
|
||||
class MethodDecoratorAsClass():
|
||||
class_var = 3
|
||||
@Decorator
|
||||
def func_without_self(arg, arg2):
|
||||
return arg, arg2
|
||||
|
||||
@Decorator
|
||||
def func_with_self(self, arg):
|
||||
return self.class_var
|
||||
|
||||
#? int()
|
||||
MethodDecoratorAsClass().func_without_self('')[0]
|
||||
#? str()
|
||||
MethodDecoratorAsClass().func_without_self('')[1]
|
||||
#?
|
||||
MethodDecoratorAsClass().func_with_self(1)
|
||||
|
||||
|
||||
class SelfVars():
|
||||
"""Init decorator problem as an instance, #247"""
|
||||
@Decorator
|
||||
def __init__(self):
|
||||
"""
|
||||
__init__ decorators should be ignored when looking up variables in the
|
||||
class.
|
||||
"""
|
||||
self.c = list
|
||||
|
||||
@Decorator
|
||||
def shouldnt_expose_var(not_self):
|
||||
"""
|
||||
Even though in real Python this shouldn't expose the variable, in this
|
||||
case Jedi exposes the variable, because these kind of decorators are
|
||||
normally descriptors, which SHOULD be exposed (at least 90%).
|
||||
"""
|
||||
not_self.b = 1.0
|
||||
|
||||
def other_method(self):
|
||||
#? float()
|
||||
self.b
|
||||
#? list
|
||||
self.c
|
||||
|
||||
# -----------------
|
||||
# not found decorators (are just ignored)
|
||||
# -----------------
|
||||
@not_found_decorator
|
||||
def just_a_func():
|
||||
return 1
|
||||
|
||||
#? int()
|
||||
just_a_func()
|
||||
|
||||
#? ['__closure__']
|
||||
just_a_func.__closure__
|
||||
|
||||
|
||||
class JustAClass:
|
||||
@not_found_decorator2
|
||||
def a(self):
|
||||
return 1
|
||||
|
||||
#? ['__call__']
|
||||
JustAClass().a.__call__
|
||||
#? int()
|
||||
JustAClass().a()
|
||||
#? ['__call__']
|
||||
JustAClass.a.__call__
|
||||
#? int()
|
||||
JustAClass.a()
|
||||
|
||||
# -----------------
|
||||
# illegal decorators
|
||||
# -----------------
|
||||
|
||||
class DecoratorWithoutCall():
|
||||
def __init__(self, func):
|
||||
self.func = func
|
||||
|
||||
@DecoratorWithoutCall
|
||||
def f():
|
||||
return 1
|
||||
|
||||
# cannot be resolved - should be ignored
|
||||
@DecoratorWithoutCall(None)
|
||||
def g():
|
||||
return 1
|
||||
|
||||
#?
|
||||
f()
|
||||
#? int()
|
||||
g()
|
||||
|
||||
|
||||
class X():
|
||||
@str
|
||||
def x(self):
|
||||
pass
|
||||
|
||||
def y(self):
|
||||
#? str()
|
||||
self.x
|
||||
#?
|
||||
self.x()
|
||||
|
||||
# -----------------
|
||||
# method decorators
|
||||
# -----------------
|
||||
|
||||
def dec(f):
|
||||
def wrapper(s):
|
||||
return f(s)
|
||||
return wrapper
|
||||
|
||||
class MethodDecorators():
|
||||
_class_var = 1
|
||||
def __init__(self):
|
||||
self._method_var = ''
|
||||
|
||||
@dec
|
||||
def constant(self):
|
||||
return 1.0
|
||||
|
||||
@dec
|
||||
def class_var(self):
|
||||
return self._class_var
|
||||
|
||||
@dec
|
||||
def method_var(self):
|
||||
return self._method_var
|
||||
|
||||
#? float()
|
||||
MethodDecorators().constant()
|
||||
#? int()
|
||||
MethodDecorators().class_var()
|
||||
#? str()
|
||||
MethodDecorators().method_var()
|
||||
|
||||
|
||||
class Base():
|
||||
@not_existing
|
||||
def __init__(self):
|
||||
pass
|
||||
@not_existing
|
||||
def b(self):
|
||||
return ''
|
||||
@dec
|
||||
def c(self):
|
||||
return 1
|
||||
|
||||
class MethodDecoratorDoesntExist(Base):
|
||||
"""#272 github: combination of method decorators and super()"""
|
||||
def a(self):
|
||||
#?
|
||||
super().__init__()
|
||||
#? str()
|
||||
super().b()
|
||||
#? int()
|
||||
super().c()
|
||||
#? float()
|
||||
self.d()
|
||||
|
||||
@doesnt_exist
|
||||
def d(self):
|
||||
return 1.0
|
||||
|
||||
# -----------------
|
||||
# others
|
||||
# -----------------
|
||||
def memoize(function):
|
||||
def wrapper(*args):
|
||||
if random.choice([0, 1]):
|
||||
pass
|
||||
else:
|
||||
rv = function(*args)
|
||||
return rv
|
||||
return wrapper
|
||||
|
||||
@memoize
|
||||
def follow_statement(stmt):
|
||||
return stmt
|
||||
|
||||
# here we had problems with the else clause, because the parent was not right.
|
||||
#? int()
|
||||
follow_statement(1)
|
||||
|
||||
# -----------------
|
||||
# class decorators
|
||||
# -----------------
|
||||
|
||||
# class decorators should just be ignored
|
||||
@should_ignore
|
||||
class A():
|
||||
def ret(self):
|
||||
return 1
|
||||
|
||||
#? int()
|
||||
A().ret()
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
"""
|
||||
Fallback to callee definition when definition not found.
|
||||
- https://github.com/davidhalter/jedi/issues/131
|
||||
- https://github.com/davidhalter/jedi/pull/149
|
||||
"""
|
||||
|
||||
"""Parenthesis closed at next line."""
|
||||
|
||||
# Ignore these definitions for a little while, not sure if we really want them.
|
||||
# python <= 2.5
|
||||
|
||||
#? isinstance
|
||||
isinstance(
|
||||
)
|
||||
|
||||
#? isinstance
|
||||
isinstance(
|
||||
)
|
||||
|
||||
#? isinstance
|
||||
isinstance(None,
|
||||
)
|
||||
|
||||
#? isinstance
|
||||
isinstance(None,
|
||||
)
|
||||
|
||||
"""Parenthesis closed at same line."""
|
||||
|
||||
# Note: len('isinstance(') == 11
|
||||
#? 11 isinstance
|
||||
isinstance()
|
||||
|
||||
# Note: len('isinstance(None,') == 16
|
||||
##? 16 isinstance
|
||||
isinstance(None,)
|
||||
|
||||
# Note: len('isinstance(None,') == 16
|
||||
##? 16 isinstance
|
||||
isinstance(None, )
|
||||
|
||||
# Note: len('isinstance(None, ') == 17
|
||||
##? 17 isinstance
|
||||
isinstance(None, )
|
||||
|
||||
# Note: len('isinstance( ') == 12
|
||||
##? 12 isinstance
|
||||
isinstance( )
|
||||
|
||||
"""Unclosed parenthesis."""
|
||||
|
||||
#? isinstance
|
||||
isinstance(
|
||||
|
||||
def x(): pass # acts like EOF
|
||||
|
||||
##? isinstance
|
||||
isinstance(
|
||||
|
||||
def x(): pass # acts like EOF
|
||||
|
||||
#? isinstance
|
||||
isinstance(None,
|
||||
|
||||
def x(): pass # acts like EOF
|
||||
|
||||
##? isinstance
|
||||
isinstance(None,
|
||||
219
vim-plugins/bundle/jedi-vim/jedi/test/completion/descriptors.py
Normal file
219
vim-plugins/bundle/jedi-vim/jedi/test/completion/descriptors.py
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
class RevealAccess(object):
|
||||
"""
|
||||
A data descriptor that sets and returns values
|
||||
normally and prints a message logging their access.
|
||||
"""
|
||||
def __init__(self, initval=None, name='var'):
|
||||
self.val = initval
|
||||
self.name = name
|
||||
|
||||
def __get__(self, obj, objtype):
|
||||
print('Retrieving', self.name)
|
||||
return self.val
|
||||
|
||||
def __set__(self, obj, val):
|
||||
print('Updating', self.name)
|
||||
self.val = val
|
||||
|
||||
def just_a_method(self):
|
||||
pass
|
||||
|
||||
class C(object):
|
||||
x = RevealAccess(10, 'var "x"')
|
||||
#? RevealAccess()
|
||||
x
|
||||
#? ['just_a_method']
|
||||
x.just_a_method
|
||||
y = 5.0
|
||||
def __init__(self):
|
||||
#? int()
|
||||
self.x
|
||||
|
||||
#? []
|
||||
self.just_a_method
|
||||
#? []
|
||||
C.just_a_method
|
||||
|
||||
m = C()
|
||||
#? int()
|
||||
m.x
|
||||
#? float()
|
||||
m.y
|
||||
#? int()
|
||||
C.x
|
||||
|
||||
#? []
|
||||
m.just_a_method
|
||||
#? []
|
||||
C.just_a_method
|
||||
|
||||
# -----------------
|
||||
# properties
|
||||
# -----------------
|
||||
class B():
|
||||
@property
|
||||
def r(self):
|
||||
return 1
|
||||
@r.setter
|
||||
def r(self, value):
|
||||
return ''
|
||||
def t(self):
|
||||
return ''
|
||||
p = property(t)
|
||||
|
||||
#? []
|
||||
B().r().
|
||||
#? int()
|
||||
B().r
|
||||
|
||||
#? str()
|
||||
B().p
|
||||
#? []
|
||||
B().p().
|
||||
|
||||
class PropClass():
|
||||
def __init__(self, a):
|
||||
self.a = a
|
||||
@property
|
||||
def ret(self):
|
||||
return self.a
|
||||
|
||||
@ret.setter
|
||||
def ret(self, value):
|
||||
return 1.0
|
||||
|
||||
def ret2(self):
|
||||
return self.a
|
||||
ret2 = property(ret2)
|
||||
|
||||
@property
|
||||
def nested(self):
|
||||
""" causes recusions in properties, should work """
|
||||
return self.ret
|
||||
|
||||
@property
|
||||
def nested2(self):
|
||||
""" causes recusions in properties, should not work """
|
||||
return self.nested2
|
||||
|
||||
@property
|
||||
def join1(self):
|
||||
""" mutual recusion """
|
||||
return self.join2
|
||||
|
||||
@property
|
||||
def join2(self):
|
||||
""" mutual recusion """
|
||||
return self.join1
|
||||
|
||||
#? str()
|
||||
PropClass("").ret
|
||||
#? []
|
||||
PropClass().ret.
|
||||
|
||||
#? str()
|
||||
PropClass("").ret2
|
||||
#?
|
||||
PropClass().ret2
|
||||
|
||||
#? int()
|
||||
PropClass(1).nested
|
||||
#? []
|
||||
PropClass().nested.
|
||||
|
||||
#?
|
||||
PropClass(1).nested2
|
||||
#? []
|
||||
PropClass().nested2.
|
||||
|
||||
#?
|
||||
PropClass(1).join1
|
||||
# -----------------
|
||||
# staticmethod/classmethod
|
||||
# -----------------
|
||||
|
||||
class E(object):
|
||||
a = ''
|
||||
def __init__(self, a):
|
||||
self.a = a
|
||||
|
||||
def f(x):
|
||||
return x
|
||||
f = staticmethod(f)
|
||||
|
||||
@staticmethod
|
||||
def g(x):
|
||||
return x
|
||||
|
||||
def s(cls, x):
|
||||
return x
|
||||
s = classmethod(s)
|
||||
|
||||
@classmethod
|
||||
def t(cls, x):
|
||||
return x
|
||||
|
||||
@classmethod
|
||||
def u(cls, x):
|
||||
return cls.a
|
||||
|
||||
e = E(1)
|
||||
#? int()
|
||||
e.f(1)
|
||||
#? int()
|
||||
E.f(1)
|
||||
#? int()
|
||||
e.g(1)
|
||||
#? int()
|
||||
E.g(1)
|
||||
|
||||
#? int()
|
||||
e.s(1)
|
||||
#? int()
|
||||
E.s(1)
|
||||
#? int()
|
||||
e.t(1)
|
||||
#? int()
|
||||
E.t(1)
|
||||
|
||||
#? str()
|
||||
e.u(1)
|
||||
#? str()
|
||||
E.u(1)
|
||||
|
||||
# -----------------
|
||||
# Conditions
|
||||
# -----------------
|
||||
|
||||
from functools import partial
|
||||
|
||||
|
||||
class Memoize():
|
||||
def __init__(self, func):
|
||||
self.func = func
|
||||
|
||||
def __get__(self, obj, objtype):
|
||||
if obj is None:
|
||||
return self.func
|
||||
|
||||
return partial(self, obj)
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
# We don't do caching here, but that's what would normally happen.
|
||||
return self.func(*args, **kwargs)
|
||||
|
||||
|
||||
class MemoizeTest():
|
||||
def __init__(self, x):
|
||||
self.x = x
|
||||
|
||||
@Memoize
|
||||
def some_func(self):
|
||||
return self.x
|
||||
|
||||
|
||||
#? int()
|
||||
MemoizeTest(10).some_func()
|
||||
# Now also call the same function over the class (see if clause above).
|
||||
#? float()
|
||||
MemoizeTest.some_func(MemoizeTest(10.0))
|
||||
235
vim-plugins/bundle/jedi-vim/jedi/test/completion/docstring.py
Normal file
235
vim-plugins/bundle/jedi-vim/jedi/test/completion/docstring.py
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
""" Test docstrings in functions and classes, which are used to infer types """
|
||||
|
||||
# -----------------
|
||||
# sphinx style
|
||||
# -----------------
|
||||
def sphinxy(a, b, c, d, x):
|
||||
""" asdfasdf
|
||||
:param a: blablabla
|
||||
:type a: str
|
||||
:type b: (str, int)
|
||||
:type c: random.Random
|
||||
:type d: :class:`random.Random`
|
||||
:param str x: blablabla
|
||||
:rtype: dict
|
||||
"""
|
||||
#? str()
|
||||
a
|
||||
#? str()
|
||||
b[0]
|
||||
#? int()
|
||||
b[1]
|
||||
#? ['seed']
|
||||
c.seed
|
||||
#? ['seed']
|
||||
d.seed
|
||||
#? ['lower']
|
||||
x.lower
|
||||
|
||||
#? dict()
|
||||
sphinxy()
|
||||
|
||||
# wrong declarations
|
||||
def sphinxy2(a, b, x):
|
||||
"""
|
||||
:param a: Forgot type declaration
|
||||
:type a:
|
||||
:param b: Just something
|
||||
:type b: ``
|
||||
:param x: Just something without type
|
||||
:rtype:
|
||||
"""
|
||||
#?
|
||||
a
|
||||
#?
|
||||
b
|
||||
#?
|
||||
x
|
||||
|
||||
#?
|
||||
sphinxy2()
|
||||
|
||||
# local classes -> github #370
|
||||
class ProgramNode():
|
||||
pass
|
||||
|
||||
def local_classes(node, node2):
|
||||
"""
|
||||
:type node: ProgramNode
|
||||
... and the class definition after this func definition:
|
||||
:type node2: ProgramNode2
|
||||
"""
|
||||
#? ProgramNode()
|
||||
node
|
||||
#? ProgramNode2()
|
||||
node2
|
||||
|
||||
class ProgramNode2():
|
||||
pass
|
||||
|
||||
|
||||
def list_with_non_imports(lst):
|
||||
"""
|
||||
Should be able to work with tuples and lists and still import stuff.
|
||||
|
||||
:type lst: (random.Random, [collections.defaultdict, ...])
|
||||
"""
|
||||
#? ['seed']
|
||||
lst[0].seed
|
||||
|
||||
import collections as col
|
||||
# use some weird index
|
||||
#? col.defaultdict()
|
||||
lst[1][10]
|
||||
|
||||
|
||||
def two_dots(a):
|
||||
"""
|
||||
:type a: json.decoder.JSONDecoder
|
||||
"""
|
||||
#? ['raw_decode']
|
||||
a.raw_decode
|
||||
|
||||
|
||||
# sphinx returns
|
||||
def return_module_object():
|
||||
"""
|
||||
:rtype: :class:`random.Random`
|
||||
"""
|
||||
|
||||
#? ['seed']
|
||||
return_module_object().seed
|
||||
|
||||
|
||||
# -----------------
|
||||
# epydoc style
|
||||
# -----------------
|
||||
def epydoc(a, b):
|
||||
""" asdfasdf
|
||||
@type a: str
|
||||
@param a: blablabla
|
||||
@type b: (str, int)
|
||||
@param b: blablah
|
||||
@rtype: list
|
||||
"""
|
||||
#? str()
|
||||
a
|
||||
#? str()
|
||||
b[0]
|
||||
|
||||
#? int()
|
||||
b[1]
|
||||
|
||||
#? list()
|
||||
epydoc()
|
||||
|
||||
|
||||
# Returns with param type only
|
||||
def rparam(a,b):
|
||||
"""
|
||||
@type a: str
|
||||
"""
|
||||
return a
|
||||
|
||||
#? str()
|
||||
rparam()
|
||||
|
||||
|
||||
# Composite types
|
||||
def composite():
|
||||
"""
|
||||
@rtype: (str, int, dict)
|
||||
"""
|
||||
|
||||
x, y, z = composite()
|
||||
#? str()
|
||||
x
|
||||
#? int()
|
||||
y
|
||||
#? dict()
|
||||
z
|
||||
|
||||
|
||||
# Both docstring and calculated return type
|
||||
def both():
|
||||
"""
|
||||
@rtype: str
|
||||
"""
|
||||
return 23
|
||||
|
||||
#? str() int()
|
||||
both()
|
||||
|
||||
class Test(object):
|
||||
def __init__(self):
|
||||
self.teststr = ""
|
||||
"""
|
||||
# jedi issue #210
|
||||
"""
|
||||
def test(self):
|
||||
#? ['teststr']
|
||||
self.teststr
|
||||
|
||||
# -----------------
|
||||
# statement docstrings
|
||||
# -----------------
|
||||
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
|
||||
|
||||
|
||||
# -----------------
|
||||
# Renamed imports (#507)
|
||||
# -----------------
|
||||
|
||||
import datetime
|
||||
from datetime import datetime as datetime_imported
|
||||
|
||||
def import_issues(foo):
|
||||
"""
|
||||
@type foo: datetime_imported
|
||||
"""
|
||||
#? datetime.datetime()
|
||||
foo
|
||||
|
|
@ -0,0 +1,306 @@
|
|||
"""
|
||||
Checking for ``list.append`` and all the other possible array modifications.
|
||||
"""
|
||||
# -----------------
|
||||
# list.append
|
||||
# -----------------
|
||||
arr = []
|
||||
for a in [1,2]:
|
||||
arr.append(a);
|
||||
|
||||
arr.append # should not cause an exception
|
||||
arr.append() # should not cause an exception
|
||||
|
||||
#? int()
|
||||
arr[10]
|
||||
|
||||
arr = [tuple()]
|
||||
for a in [1,2]:
|
||||
arr.append(a);
|
||||
|
||||
#? int() tuple()
|
||||
arr[10]
|
||||
#? int()
|
||||
arr[10].index()
|
||||
|
||||
arr = list([])
|
||||
arr.append(1)
|
||||
#? int()
|
||||
arr[0]
|
||||
|
||||
# -----------------
|
||||
# list.insert
|
||||
# -----------------
|
||||
arr = [""]
|
||||
arr.insert(0, 1.0)
|
||||
|
||||
# on exception due to this, please!
|
||||
arr.insert(0)
|
||||
arr.insert()
|
||||
|
||||
#? float() str()
|
||||
arr[10]
|
||||
|
||||
for a in arr:
|
||||
#? float() str()
|
||||
a
|
||||
|
||||
#? float() str()
|
||||
list(arr)[10]
|
||||
|
||||
# -----------------
|
||||
# set.add
|
||||
# -----------------
|
||||
st = {1.0}
|
||||
for a in [1,2]:
|
||||
st.add(a)
|
||||
|
||||
st.append('') # lists should not have an influence
|
||||
|
||||
st.add # should not cause an exception
|
||||
st.add()
|
||||
|
||||
# -----------------
|
||||
# list.extend / set.update
|
||||
# -----------------
|
||||
|
||||
arr = [1.0]
|
||||
arr.extend([1,2,3])
|
||||
arr.extend([])
|
||||
arr.extend("") # should ignore
|
||||
|
||||
#? float() int()
|
||||
arr[100]
|
||||
|
||||
a = set(arr)
|
||||
a.update(list(["", 1]))
|
||||
|
||||
#? float() int() str()
|
||||
list(a)[0]
|
||||
# -----------------
|
||||
# set/list initialized as functions
|
||||
# -----------------
|
||||
|
||||
st = set()
|
||||
st.add(1)
|
||||
|
||||
#? int()
|
||||
for s in st: s
|
||||
|
||||
lst = list()
|
||||
lst.append(1)
|
||||
|
||||
#? int()
|
||||
for i in lst: i
|
||||
|
||||
# -----------------
|
||||
# renames / type changes
|
||||
# -----------------
|
||||
arr = []
|
||||
arr2 = arr
|
||||
arr2.append('')
|
||||
#? str()
|
||||
arr2[0]
|
||||
|
||||
|
||||
st = {1.0}
|
||||
st.add(1)
|
||||
lst = list(st)
|
||||
|
||||
lst.append('')
|
||||
|
||||
#? float() int() str()
|
||||
lst[0]
|
||||
|
||||
lst = [1]
|
||||
lst.append(1.0)
|
||||
s = set(lst)
|
||||
s.add("")
|
||||
lst = list(s)
|
||||
lst.append({})
|
||||
|
||||
#? dict() int() float() str()
|
||||
lst[0]
|
||||
|
||||
# should work with tuple conversion, too.
|
||||
#? dict() int() float() str()
|
||||
tuple(lst)[0]
|
||||
|
||||
# but not with an iterator
|
||||
#?
|
||||
iter(lst)[0]
|
||||
|
||||
# -----------------
|
||||
# complex including +=
|
||||
# -----------------
|
||||
class C(): pass
|
||||
class D(): pass
|
||||
class E(): pass
|
||||
lst = [1]
|
||||
lst.append(1.0)
|
||||
lst += [C]
|
||||
s = set(lst)
|
||||
s.add("")
|
||||
s += [D]
|
||||
lst = list(s)
|
||||
lst.append({})
|
||||
lst += [E]
|
||||
|
||||
##? dict() int() float() str() C D E
|
||||
lst[0]
|
||||
|
||||
# -----------------
|
||||
# functions
|
||||
# -----------------
|
||||
|
||||
def arr_append(arr4, a):
|
||||
arr4.append(a)
|
||||
|
||||
def add_to_arr(arr2, a):
|
||||
arr2.append(a)
|
||||
return arr2
|
||||
|
||||
def app(a):
|
||||
arr3.append(a)
|
||||
|
||||
arr3 = [1.0]
|
||||
res = add_to_arr(arr3, 1)
|
||||
arr_append(arr3, 'str')
|
||||
app(set())
|
||||
|
||||
#? float() str() int() set()
|
||||
arr3[10]
|
||||
|
||||
#? float() str() int() set()
|
||||
res[10]
|
||||
|
||||
# -----------------
|
||||
# returns, special because the module dicts are not correct here.
|
||||
# -----------------
|
||||
def blub():
|
||||
a = []
|
||||
a.append(1.0)
|
||||
#? float()
|
||||
a[0]
|
||||
return a
|
||||
|
||||
#? float()
|
||||
blub()[0]
|
||||
|
||||
# list with default
|
||||
def blub():
|
||||
a = list([1])
|
||||
a.append(1.0)
|
||||
return a
|
||||
|
||||
#? int() float()
|
||||
blub()[0]
|
||||
|
||||
# empty list
|
||||
def blub():
|
||||
a = list()
|
||||
a.append(1.0)
|
||||
return a
|
||||
#? float()
|
||||
blub()[0]
|
||||
|
||||
# with if
|
||||
def blub():
|
||||
if 1:
|
||||
a = []
|
||||
a.append(1.0)
|
||||
return a
|
||||
|
||||
#? float()
|
||||
blub()[0]
|
||||
|
||||
# with else clause
|
||||
def blub():
|
||||
if random.choice([0, 1]):
|
||||
1
|
||||
else:
|
||||
a = []
|
||||
a.append(1)
|
||||
return a
|
||||
|
||||
#? int()
|
||||
blub()[0]
|
||||
# -----------------
|
||||
# returns, the same for classes
|
||||
# -----------------
|
||||
class C():
|
||||
def blub(self, b):
|
||||
if 1:
|
||||
a = []
|
||||
a.append(b)
|
||||
return a
|
||||
|
||||
def blub2(self):
|
||||
""" mapper function """
|
||||
a = self.blub(1.0)
|
||||
#? float()
|
||||
a[0]
|
||||
return a
|
||||
|
||||
def literal_arr(self, el):
|
||||
self.a = []
|
||||
self.a.append(el)
|
||||
#? int()
|
||||
self.a[0]
|
||||
return self.a
|
||||
|
||||
def list_arr(self, el):
|
||||
self.b = list([])
|
||||
self.b.append(el)
|
||||
#? float()
|
||||
self.b[0]
|
||||
return self.b
|
||||
|
||||
#? int()
|
||||
C().blub(1)[0]
|
||||
#? float()
|
||||
C().blub2(1)[0]
|
||||
|
||||
#? int()
|
||||
C().a[0]
|
||||
#? int()
|
||||
C().literal_arr(1)[0]
|
||||
|
||||
#? float()
|
||||
C().b[0]
|
||||
#? float()
|
||||
C().list_arr(1.0)[0]
|
||||
|
||||
# -----------------
|
||||
# array recursions
|
||||
# -----------------
|
||||
|
||||
a = set([1.0])
|
||||
a.update(a)
|
||||
a.update([1])
|
||||
|
||||
#? float() int()
|
||||
list(a)[0]
|
||||
|
||||
def first(a):
|
||||
b = []
|
||||
b.append(a)
|
||||
b.extend(second(a))
|
||||
return list(b)
|
||||
|
||||
def second(a):
|
||||
b = []
|
||||
b.extend(first(a))
|
||||
return list(b)
|
||||
|
||||
#? float()
|
||||
first(1.0)[0]
|
||||
|
||||
def third():
|
||||
b = []
|
||||
b.extend
|
||||
extend()
|
||||
b.extend(first())
|
||||
return list(b)
|
||||
#?
|
||||
third()[0]
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
"""
|
||||
This is used for dynamic object completion.
|
||||
Jedi tries to guess param types with a backtracking approach.
|
||||
"""
|
||||
def func(a, default_arg=2):
|
||||
#? int()
|
||||
default_arg
|
||||
#? int() str()
|
||||
return a
|
||||
|
||||
#? int()
|
||||
func(1)
|
||||
|
||||
func
|
||||
|
||||
int(1) + (int(2))+ func('')
|
||||
|
||||
# Again the same function, but with another call.
|
||||
def func(a):
|
||||
#? float()
|
||||
return a
|
||||
|
||||
func(1.0)
|
||||
|
||||
# Again the same function, but with no call.
|
||||
def func(a):
|
||||
#?
|
||||
return a
|
||||
|
||||
def func(a):
|
||||
#? float()
|
||||
return a
|
||||
str(func(1.0))
|
||||
|
||||
# -----------------
|
||||
# *args, **args
|
||||
# -----------------
|
||||
def arg(*args):
|
||||
#? tuple()
|
||||
args
|
||||
#? int()
|
||||
args[0]
|
||||
|
||||
arg(1,"")
|
||||
# -----------------
|
||||
# decorators
|
||||
# -----------------
|
||||
def def_func(f):
|
||||
def wrapper(*args, **kwargs):
|
||||
return f(*args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
@def_func
|
||||
def func(c):
|
||||
#? str()
|
||||
return c
|
||||
|
||||
#? str()
|
||||
func("str")
|
||||
|
||||
@def_func
|
||||
def func(c=1):
|
||||
#? int() float()
|
||||
return c
|
||||
|
||||
func(1.0)
|
||||
|
||||
def tricky_decorator(func):
|
||||
def wrapper(*args):
|
||||
return func(1, *args)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
@tricky_decorator
|
||||
def func(a, b):
|
||||
#? int()
|
||||
a
|
||||
#? float()
|
||||
b
|
||||
|
||||
func(1.0)
|
||||
|
||||
# Needs to be here, because in this case func is an import -> shouldn't lead to
|
||||
# exceptions.
|
||||
import sys as func
|
||||
func.sys
|
||||
|
||||
# -----------------
|
||||
# classes
|
||||
# -----------------
|
||||
|
||||
class A():
|
||||
def __init__(self, a):
|
||||
#? str()
|
||||
a
|
||||
|
||||
A("s")
|
||||
|
||||
class A():
|
||||
def __init__(self, a):
|
||||
#? int()
|
||||
a
|
||||
self.a = a
|
||||
|
||||
def test(self, a):
|
||||
#? float()
|
||||
a
|
||||
self.c = self.test2()
|
||||
|
||||
def test2(self):
|
||||
#? int()
|
||||
return self.a
|
||||
|
||||
def test3(self):
|
||||
#? int()
|
||||
self.test2()
|
||||
#? int()
|
||||
self.c
|
||||
|
||||
A(3).test(2.0)
|
||||
A(3).test2()
|
||||
|
||||
|
||||
# -----------------
|
||||
# list comprehensions
|
||||
# -----------------
|
||||
|
||||
def from_comprehension(foo):
|
||||
#? int() float()
|
||||
return foo
|
||||
|
||||
[from_comprehension(1.0) for n in (1,)]
|
||||
[from_comprehension(n) for n in (1,)]
|
||||
|
|
@ -0,0 +1,257 @@
|
|||
def foo(x):
|
||||
if 1.0:
|
||||
return 1
|
||||
else:
|
||||
return ''
|
||||
|
||||
#? int()
|
||||
foo(1)
|
||||
|
||||
|
||||
# Exceptions are not analyzed. So check both if branches
|
||||
def try_except(x):
|
||||
try:
|
||||
if 0:
|
||||
return 1
|
||||
else:
|
||||
return ''
|
||||
except AttributeError:
|
||||
return 1.0
|
||||
|
||||
#? float() str()
|
||||
try_except(1)
|
||||
|
||||
|
||||
# Exceptions are not analyzed. So check both if branches
|
||||
def try_except(x):
|
||||
try:
|
||||
if 0:
|
||||
return 1
|
||||
else:
|
||||
return ''
|
||||
except AttributeError:
|
||||
return 1.0
|
||||
|
||||
#? float() str()
|
||||
try_except(1)
|
||||
|
||||
|
||||
# -----------------
|
||||
# elif
|
||||
# -----------------
|
||||
|
||||
def elif_flows1(x):
|
||||
if False:
|
||||
return 1
|
||||
elif True:
|
||||
return 1.0
|
||||
else:
|
||||
return ''
|
||||
|
||||
#? float()
|
||||
elif_flows1(1)
|
||||
|
||||
|
||||
def elif_flows2(x):
|
||||
try:
|
||||
if False:
|
||||
return 1
|
||||
elif 0:
|
||||
return 1.0
|
||||
else:
|
||||
return ''
|
||||
except ValueError:
|
||||
return set
|
||||
|
||||
#? str() set
|
||||
elif_flows2(1)
|
||||
|
||||
|
||||
def elif_flows3(x):
|
||||
try:
|
||||
if True:
|
||||
return 1
|
||||
elif 0:
|
||||
return 1.0
|
||||
else:
|
||||
return ''
|
||||
except ValueError:
|
||||
return set
|
||||
|
||||
#? int() set
|
||||
elif_flows3(1)
|
||||
|
||||
# -----------------
|
||||
# mid-difficulty if statements
|
||||
# -----------------
|
||||
def check(a):
|
||||
if a is None:
|
||||
return 1
|
||||
return ''
|
||||
return set
|
||||
|
||||
#? int()
|
||||
check(None)
|
||||
#? str()
|
||||
check('asb')
|
||||
|
||||
a = list
|
||||
if 2 == True:
|
||||
a = set
|
||||
elif 1 == True:
|
||||
a = 0
|
||||
|
||||
#? int()
|
||||
a
|
||||
if check != 1:
|
||||
a = ''
|
||||
#? str()
|
||||
a
|
||||
if check == check:
|
||||
a = list
|
||||
#? list
|
||||
a
|
||||
if check != check:
|
||||
a = set
|
||||
else:
|
||||
a = dict
|
||||
#? dict
|
||||
a
|
||||
if not (check is not check):
|
||||
a = 1
|
||||
#? int()
|
||||
a
|
||||
|
||||
|
||||
# -----------------
|
||||
# name resolution
|
||||
# -----------------
|
||||
|
||||
a = list
|
||||
def elif_name(x):
|
||||
try:
|
||||
if True:
|
||||
a = 1
|
||||
elif 0:
|
||||
a = 1.0
|
||||
else:
|
||||
return ''
|
||||
except ValueError:
|
||||
a = x
|
||||
return a
|
||||
|
||||
#? int() set
|
||||
elif_name(set)
|
||||
|
||||
if 0:
|
||||
a = ''
|
||||
else:
|
||||
a = int
|
||||
|
||||
#? int
|
||||
a
|
||||
|
||||
# -----------------
|
||||
# isinstance
|
||||
# -----------------
|
||||
|
||||
class A(): pass
|
||||
|
||||
def isinst(x):
|
||||
if isinstance(x, A):
|
||||
return dict
|
||||
elif isinstance(x, int) and x == 1 or x is True:
|
||||
return set
|
||||
elif isinstance(x, (float, reversed)):
|
||||
return list
|
||||
elif not isinstance(x, str):
|
||||
return tuple
|
||||
return 1
|
||||
|
||||
#? dict
|
||||
isinst(A())
|
||||
#? set
|
||||
isinst(True)
|
||||
#? set
|
||||
isinst(1)
|
||||
#? tuple
|
||||
isinst(2)
|
||||
#? list
|
||||
isinst(1.0)
|
||||
#? tuple
|
||||
isinst(False)
|
||||
#? int()
|
||||
isinst('')
|
||||
|
||||
# -----------------
|
||||
# flows that are not reachable should be able to access parent scopes.
|
||||
# -----------------
|
||||
|
||||
foobar = ''
|
||||
|
||||
if 0:
|
||||
within_flow = 1.0
|
||||
#? float()
|
||||
within_flow
|
||||
#? str()
|
||||
foobar
|
||||
if 0:
|
||||
nested = 1
|
||||
#? int()
|
||||
nested
|
||||
#? float()
|
||||
within_flow
|
||||
#? str()
|
||||
foobar
|
||||
#?
|
||||
nested
|
||||
|
||||
# -----------------
|
||||
# True objects like modules
|
||||
# -----------------
|
||||
|
||||
class X():
|
||||
pass
|
||||
if X:
|
||||
a = 1
|
||||
else:
|
||||
a = ''
|
||||
#? int()
|
||||
a
|
||||
|
||||
|
||||
# -----------------
|
||||
# Recursion issues
|
||||
# -----------------
|
||||
|
||||
def possible_recursion_error(filename):
|
||||
if filename == 'a':
|
||||
return filename
|
||||
# It seems like without the brackets there wouldn't be a RecursionError.
|
||||
elif type(filename) == str:
|
||||
return filename
|
||||
|
||||
|
||||
if NOT_DEFINED:
|
||||
s = str()
|
||||
else:
|
||||
s = str()
|
||||
#? str()
|
||||
possible_recursion_error(s)
|
||||
|
||||
|
||||
# -----------------
|
||||
# In combination with imports
|
||||
# -----------------
|
||||
|
||||
from import_tree import flow_import
|
||||
|
||||
if 1 == flow_import.env:
|
||||
a = 1
|
||||
elif 2 == flow_import.env:
|
||||
a = ''
|
||||
elif 3 == flow_import.env:
|
||||
a = 1.0
|
||||
|
||||
#? int() str()
|
||||
a
|
||||
475
vim-plugins/bundle/jedi-vim/jedi/test/completion/functions.py
Normal file
475
vim-plugins/bundle/jedi-vim/jedi/test/completion/functions.py
Normal file
|
|
@ -0,0 +1,475 @@
|
|||
def array(first_param):
|
||||
#? ['first_param']
|
||||
first_param
|
||||
return list()
|
||||
|
||||
#? []
|
||||
array.first_param
|
||||
#? []
|
||||
array.first_param.
|
||||
func = array
|
||||
#? []
|
||||
func.first_param
|
||||
|
||||
#? list()
|
||||
array()
|
||||
|
||||
#? ['array']
|
||||
arr
|
||||
|
||||
|
||||
def inputs(param):
|
||||
return param
|
||||
|
||||
#? list
|
||||
inputs(list)
|
||||
|
||||
def variable_middle():
|
||||
var = 3
|
||||
return var
|
||||
|
||||
#? int()
|
||||
variable_middle()
|
||||
|
||||
def variable_rename(param):
|
||||
var = param
|
||||
return var
|
||||
|
||||
#? int()
|
||||
variable_rename(1)
|
||||
|
||||
def multi_line_func(a, # comment blabla
|
||||
|
||||
b):
|
||||
return b
|
||||
|
||||
#? str()
|
||||
multi_line_func(1,'')
|
||||
|
||||
def multi_line_call(b):
|
||||
return b
|
||||
|
||||
|
||||
multi_line_call(
|
||||
#? int()
|
||||
b=1)
|
||||
|
||||
|
||||
# nothing after comma
|
||||
def asdf(a):
|
||||
return a
|
||||
|
||||
x = asdf(a=1,
|
||||
)
|
||||
#? int()
|
||||
x
|
||||
|
||||
# -----------------
|
||||
# double execution
|
||||
# -----------------
|
||||
def double_exe(param):
|
||||
return param
|
||||
|
||||
#? str()
|
||||
variable_rename(double_exe)("")
|
||||
|
||||
# -> shouldn't work (and throw no error)
|
||||
#? []
|
||||
variable_rename(list())().
|
||||
#? []
|
||||
variable_rename(1)().
|
||||
|
||||
# -----------------
|
||||
# recursions (should ignore)
|
||||
# -----------------
|
||||
def recursion(a, b):
|
||||
if a:
|
||||
return b
|
||||
else:
|
||||
return recursion(a+".", b+1)
|
||||
|
||||
# Does not also return int anymore, because we now support operators in simple cases.
|
||||
#? float()
|
||||
recursion("a", 1.0)
|
||||
|
||||
def other(a):
|
||||
return recursion2(a)
|
||||
|
||||
def recursion2(a):
|
||||
if random.choice([0, 1]):
|
||||
return other(a)
|
||||
else:
|
||||
if random.choice([0, 1]):
|
||||
return recursion2("")
|
||||
else:
|
||||
return a
|
||||
|
||||
#? int() str()
|
||||
recursion2(1)
|
||||
|
||||
# -----------------
|
||||
# ordering
|
||||
# -----------------
|
||||
|
||||
def a():
|
||||
#? int()
|
||||
b()
|
||||
return b()
|
||||
|
||||
def b():
|
||||
return 1
|
||||
|
||||
#? int()
|
||||
a()
|
||||
|
||||
# -----------------
|
||||
# keyword arguments
|
||||
# -----------------
|
||||
|
||||
def func(a=1, b=''):
|
||||
return a, b
|
||||
|
||||
exe = func(b=list, a=tuple)
|
||||
#? tuple
|
||||
exe[0]
|
||||
|
||||
#? list
|
||||
exe[1]
|
||||
|
||||
# -----------------
|
||||
# default arguments
|
||||
# -----------------
|
||||
|
||||
#? int()
|
||||
func()[0]
|
||||
#? str()
|
||||
func()[1]
|
||||
#? float()
|
||||
func(1.0)[0]
|
||||
#? str()
|
||||
func(1.0)[1]
|
||||
|
||||
|
||||
#? float()
|
||||
func(a=1.0)[0]
|
||||
#? str()
|
||||
func(a=1.0)[1]
|
||||
#? int()
|
||||
func(b=1.0)[0]
|
||||
#? float()
|
||||
func(b=1.0)[1]
|
||||
#? list
|
||||
func(a=list, b=set)[0]
|
||||
#? set
|
||||
func(a=list, b=set)[1]
|
||||
|
||||
|
||||
def func_default(a, b=1):
|
||||
return a, b
|
||||
|
||||
|
||||
def nested_default(**kwargs):
|
||||
return func_default(**kwargs)
|
||||
|
||||
#? float()
|
||||
nested_default(a=1.0)[0]
|
||||
#? int()
|
||||
nested_default(a=1.0)[1]
|
||||
#? str()
|
||||
nested_default(a=1.0, b='')[1]
|
||||
|
||||
# Defaults should only work if they are defined before - not after.
|
||||
def default_function(a=default):
|
||||
#?
|
||||
return a
|
||||
|
||||
#?
|
||||
default_function()
|
||||
|
||||
default = int()
|
||||
|
||||
def default_function(a=default):
|
||||
#? int()
|
||||
return a
|
||||
|
||||
#? int()
|
||||
default_function()
|
||||
|
||||
|
||||
# -----------------
|
||||
# closures
|
||||
# -----------------
|
||||
def a():
|
||||
l = 3
|
||||
def func_b():
|
||||
l = ''
|
||||
#? str()
|
||||
l
|
||||
#? ['func_b']
|
||||
func_b
|
||||
#? int()
|
||||
l
|
||||
|
||||
# -----------------
|
||||
# *args
|
||||
# -----------------
|
||||
|
||||
def args_func(*args):
|
||||
#? tuple()
|
||||
return args
|
||||
|
||||
exe = args_func(1, "")
|
||||
#? int()
|
||||
exe[0]
|
||||
#? str()
|
||||
exe[1]
|
||||
|
||||
# illegal args (TypeError)
|
||||
#?
|
||||
args_func(*1)[0]
|
||||
# iterator
|
||||
#? int()
|
||||
args_func(*iter([1]))[0]
|
||||
|
||||
# different types
|
||||
e = args_func(*[1+"", {}])
|
||||
#? int() str()
|
||||
e[0]
|
||||
#? dict()
|
||||
e[1]
|
||||
|
||||
_list = [1,""]
|
||||
exe2 = args_func(_list)[0]
|
||||
|
||||
#? str()
|
||||
exe2[1]
|
||||
|
||||
exe3 = args_func([1,""])[0]
|
||||
|
||||
#? str()
|
||||
exe3[1]
|
||||
|
||||
def args_func(arg1, *args):
|
||||
return arg1, args
|
||||
|
||||
exe = args_func(1, "", list)
|
||||
#? int()
|
||||
exe[0]
|
||||
#? tuple()
|
||||
exe[1]
|
||||
#? list
|
||||
exe[1][1]
|
||||
|
||||
|
||||
# In a dynamic search, both inputs should be given.
|
||||
def simple(a):
|
||||
#? int() str()
|
||||
return a
|
||||
def xargs(*args):
|
||||
return simple(*args)
|
||||
|
||||
xargs(1)
|
||||
xargs('')
|
||||
|
||||
|
||||
# *args without a self symbol
|
||||
def memoize(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
return func(*args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
|
||||
class Something():
|
||||
@memoize
|
||||
def x(self, a, b=1):
|
||||
return a
|
||||
|
||||
#? int()
|
||||
Something().x(1)
|
||||
|
||||
|
||||
# -----------------
|
||||
# ** kwargs
|
||||
# -----------------
|
||||
def kwargs_func(**kwargs):
|
||||
#? ['keys']
|
||||
kwargs.keys
|
||||
#? dict()
|
||||
return kwargs
|
||||
|
||||
exe = kwargs_func(a=3,b=4.0)
|
||||
#? dict()
|
||||
exe
|
||||
#? int()
|
||||
exe['a']
|
||||
#? float()
|
||||
exe['b']
|
||||
#? int() float()
|
||||
exe['c']
|
||||
|
||||
a = 'a'
|
||||
exe2 = kwargs_func(**{a:3,
|
||||
'b':4.0})
|
||||
#? int()
|
||||
exe2['a']
|
||||
#? float()
|
||||
exe2['b']
|
||||
#? int() float()
|
||||
exe2['c']
|
||||
|
||||
# -----------------
|
||||
# *args / ** kwargs
|
||||
# -----------------
|
||||
|
||||
def func_without_call(*args, **kwargs):
|
||||
#? tuple()
|
||||
args
|
||||
#? dict()
|
||||
kwargs
|
||||
|
||||
def fu(a=1, b="", *args, **kwargs):
|
||||
return a, b, args, kwargs
|
||||
|
||||
exe = fu(list, 1, "", c=set, d="")
|
||||
|
||||
#? list
|
||||
exe[0]
|
||||
#? int()
|
||||
exe[1]
|
||||
#? tuple()
|
||||
exe[2]
|
||||
#? str()
|
||||
exe[2][0]
|
||||
#? dict()
|
||||
exe[3]
|
||||
#? set
|
||||
exe[3]['c']
|
||||
|
||||
|
||||
def kwargs_iteration(**kwargs):
|
||||
return kwargs
|
||||
|
||||
for x in kwargs_iteration(d=3):
|
||||
#? float()
|
||||
{'d': 1.0, 'c': '1'}[x]
|
||||
|
||||
|
||||
# -----------------
|
||||
# nested *args
|
||||
# -----------------
|
||||
def function_args(a, b, c):
|
||||
return b
|
||||
|
||||
def nested_args(*args):
|
||||
return function_args(*args)
|
||||
|
||||
def nested_args2(*args, **kwargs):
|
||||
return nested_args(*args)
|
||||
|
||||
#? int()
|
||||
nested_args('', 1, 1.0, list)
|
||||
#? []
|
||||
nested_args('').
|
||||
|
||||
#? int()
|
||||
nested_args2('', 1, 1.0)
|
||||
#? []
|
||||
nested_args2('').
|
||||
|
||||
# -----------------
|
||||
# nested **kwargs
|
||||
# -----------------
|
||||
def nested_kw(**kwargs1):
|
||||
return function_args(**kwargs1)
|
||||
|
||||
def nested_kw2(**kwargs2):
|
||||
return nested_kw(**kwargs2)
|
||||
|
||||
# invalid command, doesn't need to return anything
|
||||
#?
|
||||
nested_kw(b=1, c=1.0, list)
|
||||
#? int()
|
||||
nested_kw(b=1)
|
||||
# invalid command, doesn't need to return anything
|
||||
#?
|
||||
nested_kw(d=1.0, b=1, list)
|
||||
#? int()
|
||||
nested_kw(a=3.0, b=1)
|
||||
#? int()
|
||||
nested_kw(b=1, a=r"")
|
||||
#? []
|
||||
nested_kw(1, '').
|
||||
#? []
|
||||
nested_kw(a='').
|
||||
|
||||
#? int()
|
||||
nested_kw2(b=1)
|
||||
#? int()
|
||||
nested_kw2(b=1, c=1.0)
|
||||
#? int()
|
||||
nested_kw2(c=1.0, b=1)
|
||||
#? []
|
||||
nested_kw2('').
|
||||
#? []
|
||||
nested_kw2(a='').
|
||||
#? []
|
||||
nested_kw2('', b=1).
|
||||
|
||||
# -----------------
|
||||
# nested *args/**kwargs
|
||||
# -----------------
|
||||
def nested_both(*args, **kwargs):
|
||||
return function_args(*args, **kwargs)
|
||||
|
||||
def nested_both2(*args, **kwargs):
|
||||
return nested_both(*args, **kwargs)
|
||||
|
||||
# invalid commands, may return whatever.
|
||||
#? list
|
||||
nested_both('', b=1, c=1.0, list)
|
||||
#? list
|
||||
nested_both('', c=1.0, b=1, list)
|
||||
|
||||
#? []
|
||||
nested_both('').
|
||||
|
||||
#? int()
|
||||
nested_both2('', b=1, c=1.0)
|
||||
#? int()
|
||||
nested_both2('', c=1.0, b=1)
|
||||
#? []
|
||||
nested_both2('').
|
||||
|
||||
# -----------------
|
||||
# nested *args/**kwargs with a default arg
|
||||
# -----------------
|
||||
def function_def(a, b, c):
|
||||
return a, b
|
||||
|
||||
def nested_def(a, *args, **kwargs):
|
||||
return function_def(a, *args, **kwargs)
|
||||
|
||||
def nested_def2(*args, **kwargs):
|
||||
return nested_def(*args, **kwargs)
|
||||
|
||||
#? str()
|
||||
nested_def2('', 1, 1.0)[0]
|
||||
#? str()
|
||||
nested_def2('', b=1, c=1.0)[0]
|
||||
#? str()
|
||||
nested_def2('', c=1.0, b=1)[0]
|
||||
#? int()
|
||||
nested_def2('', 1, 1.0)[1]
|
||||
#? int()
|
||||
nested_def2('', b=1, c=1.0)[1]
|
||||
#? int()
|
||||
nested_def2('', c=1.0, b=1)[1]
|
||||
#? []
|
||||
nested_def2('')[1].
|
||||
|
||||
# -----------------
|
||||
# magic methods
|
||||
# -----------------
|
||||
def a(): pass
|
||||
#? ['__closure__']
|
||||
a.__closure__
|
||||
199
vim-plugins/bundle/jedi-vim/jedi/test/completion/generators.py
Normal file
199
vim-plugins/bundle/jedi-vim/jedi/test/completion/generators.py
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
# -----------------
|
||||
# yield statement
|
||||
# -----------------
|
||||
def gen():
|
||||
if random.choice([0, 1]):
|
||||
yield 1
|
||||
else:
|
||||
yield ""
|
||||
|
||||
gen_exe = gen()
|
||||
#? int() str()
|
||||
next(gen_exe)
|
||||
|
||||
#? int() str() list
|
||||
next(gen_exe, list)
|
||||
|
||||
|
||||
def gen_ret(value):
|
||||
yield value
|
||||
|
||||
#? int()
|
||||
next(gen_ret(1))
|
||||
|
||||
#? []
|
||||
next(gen_ret()).
|
||||
|
||||
# generators evaluate to true if cast by bool.
|
||||
a = ''
|
||||
if gen_ret():
|
||||
a = 3
|
||||
#? int()
|
||||
a
|
||||
|
||||
|
||||
# -----------------
|
||||
# generators should not be indexable
|
||||
# -----------------
|
||||
def get(param):
|
||||
if random.choice([0, 1]):
|
||||
yield 1
|
||||
else:
|
||||
yield ""
|
||||
|
||||
#? []
|
||||
get()[0].
|
||||
|
||||
# -----------------
|
||||
# __iter__
|
||||
# -----------------
|
||||
for a in get():
|
||||
#? int() str()
|
||||
a
|
||||
|
||||
|
||||
class Get():
|
||||
def __iter__(self):
|
||||
if random.choice([0, 1]):
|
||||
yield 1
|
||||
else:
|
||||
yield ""
|
||||
|
||||
b = []
|
||||
for a in Get():
|
||||
#? int() str()
|
||||
a
|
||||
b += [a]
|
||||
|
||||
#? list()
|
||||
b
|
||||
#? int() str()
|
||||
b[0]
|
||||
|
||||
g = iter(Get())
|
||||
#? int() str()
|
||||
next(g)
|
||||
|
||||
g = iter([1.0])
|
||||
#? float()
|
||||
next(g)
|
||||
|
||||
|
||||
# -----------------
|
||||
# __next__
|
||||
# -----------------
|
||||
class Counter:
|
||||
def __init__(self, low, high):
|
||||
self.current = low
|
||||
self.high = high
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def next(self):
|
||||
""" need to have both __next__ and next, because of py2/3 testing """
|
||||
return self.__next__()
|
||||
|
||||
def __next__(self):
|
||||
if self.current > self.high:
|
||||
raise StopIteration
|
||||
else:
|
||||
self.current += 1
|
||||
return self.current - 1
|
||||
|
||||
|
||||
for c in Counter(3, 8):
|
||||
#? int()
|
||||
print c
|
||||
|
||||
|
||||
# -----------------
|
||||
# tuples
|
||||
# -----------------
|
||||
def gen():
|
||||
if random.choice([0,1]):
|
||||
yield 1, ""
|
||||
else:
|
||||
yield 2, 1.0
|
||||
|
||||
|
||||
a, b = next(gen())
|
||||
#? int()
|
||||
a
|
||||
#? str() float()
|
||||
b
|
||||
|
||||
|
||||
def simple():
|
||||
if random.choice([0, 1]):
|
||||
yield 1
|
||||
else:
|
||||
yield ""
|
||||
|
||||
a, b = simple()
|
||||
#? int() str()
|
||||
a
|
||||
# For now this is ok.
|
||||
#?
|
||||
b
|
||||
|
||||
|
||||
def simple2():
|
||||
yield 1
|
||||
yield ""
|
||||
|
||||
a, b = simple2()
|
||||
#? int()
|
||||
a
|
||||
#? str()
|
||||
b
|
||||
|
||||
|
||||
# -----------------
|
||||
# More complicated access
|
||||
# -----------------
|
||||
|
||||
# `close` is a method wrapper.
|
||||
#? ['__call__']
|
||||
gen().close.__call__
|
||||
|
||||
#?
|
||||
gen().throw()
|
||||
|
||||
#? ['co_consts']
|
||||
gen().gi_code.co_consts
|
||||
|
||||
#? []
|
||||
gen.gi_code.co_consts
|
||||
|
||||
# `send` is also a method wrapper.
|
||||
#? ['__call__']
|
||||
gen().send.__call__
|
||||
|
||||
#? tuple()
|
||||
gen().send()
|
||||
|
||||
#?
|
||||
gen()()
|
||||
|
||||
# -----------------
|
||||
# yield from
|
||||
# -----------------
|
||||
|
||||
# python >= 3.3
|
||||
|
||||
def yield_from():
|
||||
yield from iter([1])
|
||||
|
||||
#? int()
|
||||
next(yield_from())
|
||||
|
||||
def yield_from_multiple():
|
||||
yield from iter([1])
|
||||
yield str()
|
||||
|
||||
x, y = yield_from_multiple()
|
||||
#? int()
|
||||
x
|
||||
#? str()
|
||||
y
|
||||
231
vim-plugins/bundle/jedi-vim/jedi/test/completion/goto.py
Normal file
231
vim-plugins/bundle/jedi-vim/jedi/test/completion/goto.py
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
# goto_assignments command tests are different in syntax
|
||||
|
||||
definition = 3
|
||||
#! 0 ['a = definition']
|
||||
a = definition
|
||||
|
||||
#! []
|
||||
b
|
||||
#! ['a = definition']
|
||||
a
|
||||
|
||||
b = a
|
||||
c = b
|
||||
#! ['c = b']
|
||||
c
|
||||
|
||||
cd = 1
|
||||
#! 1 ['cd = c']
|
||||
cd = c
|
||||
#! 0 ['cd = e']
|
||||
cd = e
|
||||
|
||||
#! ['module math']
|
||||
import math
|
||||
#! ['import math']
|
||||
math
|
||||
|
||||
#! ['import math']
|
||||
b = math
|
||||
#! ['b = math']
|
||||
b
|
||||
|
||||
#! 18 ['foo = 10']
|
||||
foo = 10;print(foo)
|
||||
|
||||
# -----------------
|
||||
# classes
|
||||
# -----------------
|
||||
class C(object):
|
||||
def b(self):
|
||||
#! ['b = math']
|
||||
b
|
||||
#! ['def b']
|
||||
self.b
|
||||
#! 14 ['def b']
|
||||
self.b()
|
||||
#! 11 ['self']
|
||||
self.b
|
||||
return 1
|
||||
|
||||
#! ['def b']
|
||||
b
|
||||
|
||||
#! ['b = math']
|
||||
b
|
||||
|
||||
#! ['def b']
|
||||
C.b
|
||||
#! ['def b']
|
||||
C().b
|
||||
#! 0 ['class C']
|
||||
C().b
|
||||
#! 0 ['class C']
|
||||
C().b
|
||||
|
||||
D = C
|
||||
#! ['def b']
|
||||
D.b
|
||||
#! ['def b']
|
||||
D().b
|
||||
|
||||
#! 0 ['D = C']
|
||||
D().b
|
||||
#! 0 ['D = C']
|
||||
D().b
|
||||
|
||||
def c():
|
||||
return ''
|
||||
|
||||
#! ['def c']
|
||||
c
|
||||
#! 0 ['def c']
|
||||
c()
|
||||
|
||||
|
||||
class ClassVar():
|
||||
x = 3
|
||||
|
||||
#! ['x = 3']
|
||||
ClassVar.x
|
||||
#! ['x = 3']
|
||||
ClassVar().x
|
||||
|
||||
# before assignments
|
||||
#! 10 ['x = 3']
|
||||
ClassVar.x = ''
|
||||
#! 12 ['x = 3']
|
||||
ClassVar().x = ''
|
||||
|
||||
# Recurring use of the same var name, github #315
|
||||
def f(t=None):
|
||||
#! 9 ['t=None']
|
||||
t = t or 1
|
||||
|
||||
|
||||
class X():
|
||||
pass
|
||||
|
||||
#! 3 []
|
||||
X(foo=x)
|
||||
|
||||
# -----------------
|
||||
# imports
|
||||
# -----------------
|
||||
|
||||
#! ['module import_tree']
|
||||
import import_tree
|
||||
#! ["a = ''"]
|
||||
import_tree.a
|
||||
|
||||
#! ['module mod1']
|
||||
import import_tree.mod1
|
||||
#! ['a = 1']
|
||||
import_tree.mod1.a
|
||||
|
||||
#! ['module pkg']
|
||||
import import_tree.pkg
|
||||
#! ['a = list']
|
||||
import_tree.pkg.a
|
||||
|
||||
#! ['module mod1']
|
||||
import import_tree.pkg.mod1
|
||||
#! ['a = 1.0']
|
||||
import_tree.pkg.mod1.a
|
||||
#! ["a = ''"]
|
||||
import_tree.a
|
||||
|
||||
#! ['module mod1']
|
||||
from import_tree.pkg import mod1
|
||||
#! ['a = 1.0']
|
||||
mod1.a
|
||||
|
||||
#! ['module mod1']
|
||||
from import_tree import mod1
|
||||
#! ['a = 1']
|
||||
mod1.a
|
||||
|
||||
#! ['a = 1.0']
|
||||
from import_tree.pkg.mod1 import a
|
||||
|
||||
#! ['import os']
|
||||
from .imports import os
|
||||
|
||||
#! ['some_variable = 1']
|
||||
from . import some_variable
|
||||
|
||||
# -----------------
|
||||
# anonymous classes
|
||||
# -----------------
|
||||
def func():
|
||||
class A():
|
||||
def b(self):
|
||||
return 1
|
||||
return A()
|
||||
|
||||
#! 8 ['def b']
|
||||
func().b()
|
||||
|
||||
# -----------------
|
||||
# on itself
|
||||
# -----------------
|
||||
|
||||
#! 7 ['class ClassDef']
|
||||
class ClassDef():
|
||||
""" abc """
|
||||
pass
|
||||
|
||||
# -----------------
|
||||
# params
|
||||
# -----------------
|
||||
|
||||
param = ClassDef
|
||||
#! 8 ['param']
|
||||
def ab1(param): pass
|
||||
#! 9 ['param']
|
||||
def ab2(param): pass
|
||||
#! 11 ['param = ClassDef']
|
||||
def ab3(a=param): pass
|
||||
|
||||
ab1(ClassDef);ab2(ClassDef);ab3(ClassDef)
|
||||
|
||||
# -----------------
|
||||
# for loops
|
||||
# -----------------
|
||||
|
||||
for i in range(1):
|
||||
#! ['for i in range(1): i']
|
||||
i
|
||||
|
||||
for key, value in [(1,2)]:
|
||||
#! ['for key, value in [(1,2)]: key']
|
||||
key
|
||||
|
||||
for i in []:
|
||||
#! ['for i in []: i']
|
||||
i
|
||||
|
||||
# -----------------
|
||||
# decorator
|
||||
# -----------------
|
||||
def dec(dec_param=3):
|
||||
pass
|
||||
|
||||
#! 8 ['dec_param=3']
|
||||
@dec(dec_param=5)
|
||||
def y():
|
||||
pass
|
||||
|
||||
class ClassDec():
|
||||
def class_func(func):
|
||||
return func
|
||||
|
||||
#! 14 ['def class_func']
|
||||
@ClassDec.class_func
|
||||
def x():
|
||||
pass
|
||||
|
||||
#! 2 ['class ClassDec']
|
||||
@ClassDec.class_func
|
||||
def z():
|
||||
pass
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
a = ''
|
||||
|
||||
from . import invisible_pkg
|
||||
|
||||
the_pkg = invisible_pkg
|
||||
|
||||
invisible_pkg = 1
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
if name:
|
||||
env = 1
|
||||
else:
|
||||
env = 2
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
"""
|
||||
It should not be possible to import this pkg except for the import_tree itself,
|
||||
because it is overwritten there. (It would be possible with a sys.path
|
||||
modification, though).
|
||||
"""
|
||||
|
||||
foo = 1.0
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
a = 1
|
||||
from import_tree.random import a as c
|
||||
|
||||
foobarbaz = 3.0
|
||||
|
|
@ -0,0 +1 @@
|
|||
from . import mod1 as fake
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
a = list
|
||||
|
||||
from math import *
|
||||
|
|
@ -0,0 +1 @@
|
|||
a = 1.0
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
"""
|
||||
Here because random is also a builtin module.
|
||||
"""
|
||||
a = set
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import recurse_class2
|
||||
|
||||
class C(recurse_class2.C):
|
||||
def a(self):
|
||||
pass
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
import recurse_class1
|
||||
|
||||
class C(recurse_class1.C):
|
||||
pass
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
""" used for renaming tests """
|
||||
|
||||
abc = 3
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
""" used for renaming tests """
|
||||
|
||||
|
||||
from rename1 import abc
|
||||
|
||||
abc
|
||||
285
vim-plugins/bundle/jedi-vim/jedi/test/completion/imports.py
Normal file
285
vim-plugins/bundle/jedi-vim/jedi/test/completion/imports.py
Normal file
|
|
@ -0,0 +1,285 @@
|
|||
# -----------------
|
||||
# own structure
|
||||
# -----------------
|
||||
|
||||
# do separate scopes
|
||||
def scope_basic():
|
||||
from import_tree import mod1
|
||||
|
||||
#? int()
|
||||
mod1.a
|
||||
|
||||
#? []
|
||||
import_tree.a
|
||||
|
||||
#? []
|
||||
import_tree.mod1
|
||||
|
||||
import import_tree
|
||||
#? str()
|
||||
import_tree.a
|
||||
|
||||
|
||||
def scope_pkg():
|
||||
import import_tree.mod1
|
||||
|
||||
#? str()
|
||||
import_tree.a
|
||||
|
||||
#? ['mod1']
|
||||
import_tree.mod1
|
||||
|
||||
#? int()
|
||||
import_tree.mod1.a
|
||||
|
||||
def scope_nested():
|
||||
import import_tree.pkg.mod1
|
||||
|
||||
#? str()
|
||||
import_tree.a
|
||||
|
||||
#? list
|
||||
import_tree.pkg.a
|
||||
|
||||
#? ['sqrt']
|
||||
import_tree.pkg.sqrt
|
||||
|
||||
#? ['pkg']
|
||||
import_tree.p
|
||||
|
||||
#? float()
|
||||
import_tree.pkg.mod1.a
|
||||
#? ['a', '__name__', '__package__', '__file__', '__doc__']
|
||||
a = import_tree.pkg.mod1.
|
||||
|
||||
import import_tree.random
|
||||
#? set
|
||||
import_tree.random.a
|
||||
|
||||
def scope_nested2():
|
||||
"""Multiple modules should be indexable, if imported"""
|
||||
import import_tree.mod1
|
||||
import import_tree.pkg
|
||||
#? ['mod1']
|
||||
import_tree.mod1
|
||||
#? ['pkg']
|
||||
import_tree.pkg
|
||||
|
||||
# With the latest changes this completion also works, because submodules
|
||||
# are always included (some nested import structures lead to this,
|
||||
# typically).
|
||||
#? ['rename1']
|
||||
import_tree.rename1
|
||||
|
||||
def scope_from_import_variable():
|
||||
"""
|
||||
All of them shouldn't work, because "fake" imports don't work in python
|
||||
without the use of ``sys.modules`` modifications (e.g. ``os.path`` see also
|
||||
github issue #213 for clarification.
|
||||
"""
|
||||
a = 3
|
||||
#?
|
||||
from import_tree.mod2.fake import a
|
||||
#?
|
||||
from import_tree.mod2.fake import c
|
||||
|
||||
#?
|
||||
a
|
||||
#?
|
||||
c
|
||||
|
||||
def scope_from_import_variable_with_parenthesis():
|
||||
from import_tree.mod2.fake import (
|
||||
a, foobarbaz
|
||||
)
|
||||
|
||||
#?
|
||||
a
|
||||
#?
|
||||
foobarbaz
|
||||
# shouldn't complete, should still list the name though.
|
||||
#? ['foobarbaz']
|
||||
foobarbaz
|
||||
|
||||
|
||||
def as_imports():
|
||||
from import_tree.mod1 import a as xyz
|
||||
#? int()
|
||||
xyz
|
||||
import not_existant, import_tree.mod1 as foo
|
||||
#? int()
|
||||
foo.a
|
||||
import import_tree.mod1 as bar
|
||||
#? int()
|
||||
bar.a
|
||||
|
||||
|
||||
def test_import_priorities():
|
||||
"""
|
||||
It's possible to overwrite import paths in an ``__init__.py`` file, by
|
||||
just assigining something there.
|
||||
|
||||
See also #536.
|
||||
"""
|
||||
from import_tree import the_pkg, invisible_pkg
|
||||
#? int()
|
||||
invisible_pkg
|
||||
# In real Python, this would be the module, but it's not, because Jedi
|
||||
# doesn't care about most stateful issues such as __dict__, which it would
|
||||
# need to, to do this in a correct way.
|
||||
#? int()
|
||||
the_pkg
|
||||
# Importing foo is still possible, even though inivisible_pkg got changed.
|
||||
#? float()
|
||||
from import_tree.invisible_pkg import foo
|
||||
|
||||
|
||||
# -----------------
|
||||
# std lib modules
|
||||
# -----------------
|
||||
import tokenize
|
||||
#? ['tok_name']
|
||||
tokenize.tok_name
|
||||
|
||||
from pyclbr import *
|
||||
|
||||
#? ['readmodule_ex']
|
||||
readmodule_ex
|
||||
import os
|
||||
|
||||
#? ['dirname']
|
||||
os.path.dirname
|
||||
|
||||
from os.path import (
|
||||
expanduser
|
||||
)
|
||||
|
||||
#? os.path.expanduser
|
||||
expanduser
|
||||
|
||||
from itertools import (tee,
|
||||
islice)
|
||||
#? ['islice']
|
||||
islice
|
||||
|
||||
from functools import (partial, wraps)
|
||||
#? ['wraps']
|
||||
wraps
|
||||
|
||||
from keyword import kwlist, \
|
||||
iskeyword
|
||||
#? ['kwlist']
|
||||
kwlist
|
||||
|
||||
#? []
|
||||
from keyword import not_existing1, not_existing2
|
||||
|
||||
from tokenize import io
|
||||
tokenize.generate_tokens
|
||||
|
||||
# -----------------
|
||||
# builtins
|
||||
# -----------------
|
||||
|
||||
import sys
|
||||
#? ['prefix']
|
||||
sys.prefix
|
||||
|
||||
#? ['append']
|
||||
sys.path.append
|
||||
|
||||
from math import *
|
||||
#? ['cos', 'cosh']
|
||||
cos
|
||||
|
||||
def func_with_import():
|
||||
import time
|
||||
return time
|
||||
|
||||
#? ['sleep']
|
||||
func_with_import().sleep
|
||||
|
||||
# -----------------
|
||||
# relative imports
|
||||
# -----------------
|
||||
|
||||
from .import_tree import mod1
|
||||
#? int()
|
||||
mod1.a
|
||||
|
||||
from ..import_tree import mod1
|
||||
#?
|
||||
mod1.a
|
||||
|
||||
from .......import_tree import mod1
|
||||
#?
|
||||
mod1.a
|
||||
|
||||
from .. import helpers
|
||||
#? int()
|
||||
helpers.sample_int
|
||||
|
||||
from ..helpers import sample_int as f
|
||||
#? int()
|
||||
f
|
||||
|
||||
from . import run
|
||||
#? []
|
||||
run.
|
||||
|
||||
from . import import_tree as imp_tree
|
||||
#? str()
|
||||
imp_tree.a
|
||||
|
||||
from . import datetime as mod1
|
||||
#? []
|
||||
mod1.
|
||||
|
||||
# self import
|
||||
# this can cause recursions
|
||||
from imports import *
|
||||
|
||||
# -----------------
|
||||
# packages
|
||||
# -----------------
|
||||
|
||||
from import_tree.mod1 import c
|
||||
#? set
|
||||
c
|
||||
|
||||
from import_tree import recurse_class1
|
||||
|
||||
#? ['a']
|
||||
recurse_class1.C.a
|
||||
# github #239 RecursionError
|
||||
#? ['a']
|
||||
recurse_class1.C().a
|
||||
|
||||
# -----------------
|
||||
# Jedi debugging
|
||||
# -----------------
|
||||
|
||||
# memoizing issues (check git history for the fix)
|
||||
import not_existing_import
|
||||
|
||||
if not_existing_import:
|
||||
a = not_existing_import
|
||||
else:
|
||||
a = not_existing_import
|
||||
#?
|
||||
a
|
||||
|
||||
# -----------------
|
||||
# module underscore descriptors
|
||||
# -----------------
|
||||
|
||||
def underscore():
|
||||
import keyword
|
||||
#? ['__file__']
|
||||
keyword.__file__
|
||||
#? str()
|
||||
keyword.__file__
|
||||
|
||||
# Does that also work for the our own module?
|
||||
#? ['__file__']
|
||||
__file__
|
||||
214
vim-plugins/bundle/jedi-vim/jedi/test/completion/invalid.py
Normal file
214
vim-plugins/bundle/jedi-vim/jedi/test/completion/invalid.py
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
"""
|
||||
This file is less about the results and much more about the fact, that no
|
||||
exception should be thrown.
|
||||
|
||||
Basically this file could change depending on the current implementation. But
|
||||
there should never be any errors.
|
||||
"""
|
||||
|
||||
# wait until keywords are out of definitions (pydoc function).
|
||||
##? 5
|
||||
's'()
|
||||
|
||||
#? []
|
||||
str()).upper
|
||||
|
||||
# -----------------
|
||||
# funcs
|
||||
# -----------------
|
||||
def asdf(a or b): # multiple param names
|
||||
return a
|
||||
|
||||
#?
|
||||
asdf(2)
|
||||
|
||||
asdf = ''
|
||||
|
||||
from a import (b
|
||||
def blub():
|
||||
return 0
|
||||
def wrong_indents():
|
||||
asdf = 3
|
||||
asdf
|
||||
asdf(
|
||||
# TODO this seems to be wrong now?
|
||||
##? int()
|
||||
asdf
|
||||
def openbrace():
|
||||
asdf = 3
|
||||
asdf(
|
||||
#? int()
|
||||
asdf
|
||||
return 1
|
||||
|
||||
#? int()
|
||||
openbrace()
|
||||
|
||||
blub([
|
||||
#? int()
|
||||
openbrace()
|
||||
|
||||
def indentfault():
|
||||
asd(
|
||||
indentback
|
||||
|
||||
#? []
|
||||
indentfault().
|
||||
|
||||
def openbrace2():
|
||||
asd(
|
||||
def normalfunc():
|
||||
return 1
|
||||
|
||||
#? int()
|
||||
normalfunc()
|
||||
|
||||
# dots in param
|
||||
def f(seq1...=None):
|
||||
return seq1
|
||||
#?
|
||||
f(1)
|
||||
|
||||
@
|
||||
def test_empty_decorator():
|
||||
return 1
|
||||
|
||||
#? int()
|
||||
test_empty_decorator()
|
||||
|
||||
def invalid_param(param=):
|
||||
#?
|
||||
param
|
||||
# -----------------
|
||||
# flows
|
||||
# -----------------
|
||||
|
||||
# first part not complete (raised errors)
|
||||
if a
|
||||
a
|
||||
else:
|
||||
#? ['AttributeError']
|
||||
AttributeError
|
||||
|
||||
try
|
||||
#? ['AttributeError']
|
||||
except AttributeError
|
||||
pass
|
||||
finally:
|
||||
pass
|
||||
|
||||
#? ['isinstance']
|
||||
if isi
|
||||
try:
|
||||
except TypeError:
|
||||
#? str()
|
||||
str()
|
||||
|
||||
def break(): pass
|
||||
# wrong ternary expression
|
||||
a = ''
|
||||
a = 1 if
|
||||
#? str()
|
||||
a
|
||||
|
||||
# No completions for for loops without the right syntax
|
||||
for for_local in :
|
||||
for_local
|
||||
#? []
|
||||
for_local
|
||||
#?
|
||||
for_local
|
||||
|
||||
|
||||
# -----------------
|
||||
# list comprehensions
|
||||
# -----------------
|
||||
|
||||
a2 = [for a2 in [0]]
|
||||
#?
|
||||
a2[0]
|
||||
|
||||
a3 = [for xyz in]
|
||||
#?
|
||||
a3[0]
|
||||
|
||||
a3 = [a4 for in 'b']
|
||||
#?
|
||||
a3[0]
|
||||
|
||||
a3 = [a4 for a in for x in y]
|
||||
#?
|
||||
a3[0]
|
||||
|
||||
a = [for a in
|
||||
def break(): pass
|
||||
|
||||
#?
|
||||
a[0]
|
||||
|
||||
a = [a for a in [1,2]
|
||||
def break(): pass
|
||||
#?
|
||||
a[0]
|
||||
|
||||
#? []
|
||||
int()).real
|
||||
|
||||
# -----------------
|
||||
# keywords
|
||||
# -----------------
|
||||
|
||||
#! []
|
||||
as
|
||||
|
||||
def empty_assert():
|
||||
x = 3
|
||||
assert
|
||||
#? int()
|
||||
x
|
||||
|
||||
import datetime as
|
||||
|
||||
|
||||
# -----------------
|
||||
# statements
|
||||
# -----------------
|
||||
|
||||
call = ''
|
||||
invalid = .call
|
||||
#?
|
||||
invalid
|
||||
|
||||
invalid = call?.call
|
||||
#? str()
|
||||
invalid
|
||||
|
||||
# comma
|
||||
invalid = ,call
|
||||
#? str()
|
||||
invalid
|
||||
|
||||
|
||||
# -----------------
|
||||
# classes
|
||||
# -----------------
|
||||
|
||||
class BrokenPartsOfClass():
|
||||
def foo(self):
|
||||
# This construct contains two places where Jedi with Python 3 can fail.
|
||||
# It should just ignore those constructs and still execute `bar`.
|
||||
pass
|
||||
if 2:
|
||||
try:
|
||||
pass
|
||||
except ValueError, e:
|
||||
raise TypeError, e
|
||||
else:
|
||||
pass
|
||||
|
||||
def bar(self):
|
||||
self.x = 3
|
||||
return ''
|
||||
|
||||
#? str()
|
||||
BrokenPartsOfClass().bar()
|
||||
100
vim-plugins/bundle/jedi-vim/jedi/test/completion/isinstance.py
Normal file
100
vim-plugins/bundle/jedi-vim/jedi/test/completion/isinstance.py
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
if isinstance(i, str):
|
||||
#? str()
|
||||
i
|
||||
|
||||
if isinstance(j, (str, int)):
|
||||
#? str() int()
|
||||
j
|
||||
|
||||
while isinstance(k, (str, int)):
|
||||
#? str() int()
|
||||
k
|
||||
|
||||
if not isinstance(k, (str, int)):
|
||||
#?
|
||||
k
|
||||
|
||||
while not isinstance(k, (str, int)):
|
||||
#?
|
||||
k
|
||||
|
||||
assert isinstance(ass, int)
|
||||
#? int()
|
||||
ass
|
||||
|
||||
assert isinstance(ass, str)
|
||||
assert not isinstance(ass, int)
|
||||
|
||||
if 2:
|
||||
#? str()
|
||||
ass
|
||||
|
||||
# -----------------
|
||||
# invalid arguments
|
||||
# -----------------
|
||||
|
||||
if isinstance(wrong, str()):
|
||||
#?
|
||||
wrong
|
||||
|
||||
# -----------------
|
||||
# in functions
|
||||
# -----------------
|
||||
|
||||
import datetime
|
||||
|
||||
|
||||
def fooooo(obj):
|
||||
if isinstance(obj, datetime.datetime):
|
||||
#? datetime.datetime()
|
||||
obj
|
||||
|
||||
|
||||
def fooooo2(obj):
|
||||
if isinstance(obj, datetime.date):
|
||||
return obj
|
||||
else:
|
||||
return 1
|
||||
|
||||
a
|
||||
# In earlier versions of Jedi, this returned both datetime and int, but now
|
||||
# Jedi does flow checks and realizes that the top return isn't executed.
|
||||
#? int()
|
||||
fooooo2('')
|
||||
|
||||
|
||||
def isinstance_func(arr):
|
||||
for value in arr:
|
||||
if isinstance(value, dict):
|
||||
# Shouldn't fail, even with the dot.
|
||||
#? 17 dict()
|
||||
value.
|
||||
elif isinstance(value, int):
|
||||
x = value
|
||||
#? int()
|
||||
x
|
||||
|
||||
# -----------------
|
||||
# Names with multiple indices.
|
||||
# -----------------
|
||||
|
||||
class Test():
|
||||
def __init__(self, testing):
|
||||
if isinstance(testing, str):
|
||||
self.testing = testing
|
||||
else:
|
||||
self.testing = 10
|
||||
|
||||
def boo(self):
|
||||
if isinstance(self.testing, str):
|
||||
#? str()
|
||||
self.testing
|
||||
#? Test()
|
||||
self
|
||||
|
||||
# -----------------
|
||||
# Syntax
|
||||
# -----------------
|
||||
|
||||
#?
|
||||
isinstance(1, int())
|
||||
59
vim-plugins/bundle/jedi-vim/jedi/test/completion/keywords.py
Normal file
59
vim-plugins/bundle/jedi-vim/jedi/test/completion/keywords.py
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
|
||||
#? ['raise']
|
||||
raise
|
||||
|
||||
#? ['Exception']
|
||||
except
|
||||
|
||||
#? []
|
||||
b + continu
|
||||
|
||||
#? []
|
||||
b + continue
|
||||
|
||||
#? ['continue']
|
||||
b; continue
|
||||
|
||||
#? ['continue']
|
||||
b; continu
|
||||
|
||||
#? []
|
||||
c + brea
|
||||
|
||||
#? []
|
||||
a + break
|
||||
|
||||
#? ['break']
|
||||
b; break
|
||||
|
||||
# -----------------
|
||||
# Keywords should not appear everywhere.
|
||||
# -----------------
|
||||
|
||||
#? []
|
||||
with open() as f
|
||||
#? []
|
||||
def i
|
||||
#? []
|
||||
class i
|
||||
|
||||
#? []
|
||||
continue i
|
||||
|
||||
# More syntax details, e.g. while only after newline, but not after semicolon,
|
||||
# continue also after semicolon
|
||||
#? ['while']
|
||||
while
|
||||
#? []
|
||||
x while
|
||||
#? []
|
||||
x; while
|
||||
#? ['continue']
|
||||
x; continue
|
||||
|
||||
#? []
|
||||
and
|
||||
#? ['and']
|
||||
x and
|
||||
#? []
|
||||
x * and
|
||||
106
vim-plugins/bundle/jedi-vim/jedi/test/completion/lambdas.py
Normal file
106
vim-plugins/bundle/jedi-vim/jedi/test/completion/lambdas.py
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
# -----------------
|
||||
# lambdas
|
||||
# -----------------
|
||||
a = lambda: 3
|
||||
#? int()
|
||||
a()
|
||||
|
||||
x = []
|
||||
a = lambda x: x
|
||||
#? int()
|
||||
a(0)
|
||||
|
||||
#? float()
|
||||
(lambda x: x)(3.0)
|
||||
|
||||
arg_l = lambda x, y: y, x
|
||||
#? float()
|
||||
arg_l[0]('', 1.0)
|
||||
#? list()
|
||||
arg_l[1]
|
||||
|
||||
arg_l = lambda x, y: (y, x)
|
||||
args = 1,""
|
||||
result = arg_l(*args)
|
||||
#? tuple()
|
||||
result
|
||||
#? str()
|
||||
result[0]
|
||||
#? int()
|
||||
result[1]
|
||||
|
||||
def with_lambda(callable_lambda, *args, **kwargs):
|
||||
return callable_lambda(1, *args, **kwargs)
|
||||
|
||||
#? int()
|
||||
with_lambda(arg_l, 1.0)[1]
|
||||
#? float()
|
||||
with_lambda(arg_l, 1.0)[0]
|
||||
#? float()
|
||||
with_lambda(arg_l, y=1.0)[0]
|
||||
#? int()
|
||||
with_lambda(lambda x: x)
|
||||
#? float()
|
||||
with_lambda(lambda x, y: y, y=1.0)
|
||||
|
||||
arg_func = lambda *args, **kwargs: (args[0], kwargs['a'])
|
||||
#? int()
|
||||
arg_func(1, 2, a='', b=10)[0]
|
||||
#? list()
|
||||
arg_func(1, 2, a=[], b=10)[1]
|
||||
|
||||
# magic method
|
||||
a = lambda: 3
|
||||
#? ['__closure__']
|
||||
a.__closure__
|
||||
|
||||
class C():
|
||||
def __init__(self, foo=1.0):
|
||||
self.a = lambda: 1
|
||||
self.foo = foo
|
||||
|
||||
def ret(self):
|
||||
return lambda: self.foo
|
||||
|
||||
def with_param(self):
|
||||
return lambda x: x + self.a()
|
||||
|
||||
#? int()
|
||||
C().a()
|
||||
|
||||
#? str()
|
||||
C('foo').ret()()
|
||||
|
||||
index = C().with_param()(1)
|
||||
#? float()
|
||||
['', 1, 1.0][index]
|
||||
|
||||
|
||||
def xy(param):
|
||||
def ret(a, b):
|
||||
return a + b
|
||||
|
||||
return lambda b: ret(param, b)
|
||||
|
||||
#? int()
|
||||
xy(1)(2)
|
||||
|
||||
# -----------------
|
||||
# lambda param (#379)
|
||||
# -----------------
|
||||
class Test(object):
|
||||
def __init__(self, pred=lambda a, b: a):
|
||||
self.a = 1
|
||||
#? int()
|
||||
self.a
|
||||
#? float()
|
||||
pred(1.0, 2)
|
||||
|
||||
# -----------------
|
||||
# test_nocond in grammar (happens in list comprehensions with `if`)
|
||||
# -----------------
|
||||
# Doesn't need to do anything yet. It should just not raise an error. These
|
||||
# nocond lambdas make no sense at all.
|
||||
|
||||
#? int()
|
||||
[a for a in [1,2] if lambda: 3][0]
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
"""
|
||||
Named Params:
|
||||
>>> def a(abc): pass
|
||||
...
|
||||
>>> a(abc=3) # <- this stuff (abc)
|
||||
"""
|
||||
|
||||
def a(abc):
|
||||
pass
|
||||
|
||||
#? 5 ['abc']
|
||||
a(abc)
|
||||
|
||||
|
||||
def a(*some_args, **some_kwargs):
|
||||
pass
|
||||
|
||||
#? 11 []
|
||||
a(some_args)
|
||||
|
||||
#? 13 []
|
||||
a(some_kwargs)
|
||||
|
||||
def multiple(foo, bar):
|
||||
pass
|
||||
|
||||
#? 17 ['bar']
|
||||
multiple(foo, bar)
|
||||
|
||||
#? ['bar']
|
||||
multiple(foo, bar
|
||||
|
||||
my_lambda = lambda lambda_param: lambda_param + 1
|
||||
#? 22 ['lambda_param']
|
||||
my_lambda(lambda_param)
|
||||
|
||||
# __call__
|
||||
class Test(object):
|
||||
def __init__(self, hello_other):
|
||||
pass
|
||||
|
||||
def __call__(self, hello):
|
||||
pass
|
||||
|
||||
#? 12 ['hello']
|
||||
Test()(hello=)
|
||||
#? 11 []
|
||||
Test()(self=)
|
||||
108
vim-plugins/bundle/jedi-vim/jedi/test/completion/on_import.py
Normal file
108
vim-plugins/bundle/jedi-vim/jedi/test/completion/on_import.py
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
def from_names():
|
||||
#? ['mod1']
|
||||
from import_tree.pkg.
|
||||
#? ['path']
|
||||
from os.
|
||||
|
||||
def from_names_goto():
|
||||
from import_tree import pkg
|
||||
#? pkg
|
||||
from import_tree.pkg
|
||||
|
||||
def builtin_test():
|
||||
#? ['math']
|
||||
import math
|
||||
|
||||
# -----------------
|
||||
# completions within imports
|
||||
# -----------------
|
||||
|
||||
#? ['sqlite3']
|
||||
import sqlite3
|
||||
|
||||
#? ['classes']
|
||||
import classes
|
||||
|
||||
#? ['timedelta']
|
||||
from datetime import timedel
|
||||
#? 21 []
|
||||
from datetime.timedel import timedel
|
||||
|
||||
# should not be possible, because names can only be looked up 1 level deep.
|
||||
#? []
|
||||
from datetime.timedelta import resolution
|
||||
#? []
|
||||
from datetime.timedelta import
|
||||
|
||||
#? ['Cursor']
|
||||
from sqlite3 import Cursor
|
||||
|
||||
#? ['some_variable']
|
||||
from . import some_variable
|
||||
#? ['arrays']
|
||||
from . import arrays
|
||||
#? []
|
||||
from . import import_tree as ren
|
||||
|
||||
import os
|
||||
#? os.path.join
|
||||
from os.path import join
|
||||
|
||||
# -----------------
|
||||
# special positions -> edge cases
|
||||
# -----------------
|
||||
import datetime
|
||||
|
||||
#? 6 datetime
|
||||
from datetime.time import time
|
||||
|
||||
#? []
|
||||
import datetime.
|
||||
#? []
|
||||
import datetime.date
|
||||
|
||||
#? 21 ['import']
|
||||
from import_tree.pkg import pkg
|
||||
#? 49 ['a', '__name__', '__doc__', '__file__', '__package__']
|
||||
from import_tree.pkg.mod1 import not_existant, # whitespace before
|
||||
#? ['a', '__name__', '__doc__', '__file__', '__package__']
|
||||
from import_tree.pkg.mod1 import not_existant,
|
||||
#? 22 ['mod1']
|
||||
from import_tree.pkg. import mod1
|
||||
#? 17 ['mod1', 'mod2', 'random', 'pkg', 'rename1', 'rename2', 'recurse_class1', 'recurse_class2', 'invisible_pkg', 'flow_import']
|
||||
from import_tree. import pkg
|
||||
|
||||
#? 18 ['pkg']
|
||||
from import_tree.p import pkg
|
||||
|
||||
#? 17 ['import_tree']
|
||||
from .import_tree import
|
||||
#? 10 ['run']
|
||||
from ..run import
|
||||
#? ['run']
|
||||
from ..run
|
||||
#? 10 ['run']
|
||||
from ..run.
|
||||
#? []
|
||||
from ..run.
|
||||
|
||||
#? ['run']
|
||||
from .. import run
|
||||
|
||||
#? []
|
||||
from not_a_module import
|
||||
|
||||
|
||||
#137
|
||||
import json
|
||||
#? 23 json.dump
|
||||
from json import load, dump
|
||||
#? 17 json.load
|
||||
from json import load, dump
|
||||
# without the from clause:
|
||||
import json, datetime
|
||||
#? 7 json
|
||||
import json, datetime
|
||||
#? 13 datetime
|
||||
import json, datetime
|
||||
|
||||
195
vim-plugins/bundle/jedi-vim/jedi/test/completion/ordering.py
Normal file
195
vim-plugins/bundle/jedi-vim/jedi/test/completion/ordering.py
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
# -----------------
|
||||
# normal
|
||||
# -----------------
|
||||
a = ""
|
||||
a = 1
|
||||
|
||||
#? int()
|
||||
a
|
||||
#? []
|
||||
a.append
|
||||
|
||||
a = list
|
||||
|
||||
b = 1; b = ""
|
||||
#? str()
|
||||
b
|
||||
|
||||
# temp should not be accessible before definition
|
||||
#? []
|
||||
temp
|
||||
|
||||
a = 1
|
||||
temp = b;
|
||||
b = a
|
||||
a = temp
|
||||
#? int()
|
||||
b
|
||||
#? int()
|
||||
b
|
||||
#? str()
|
||||
a
|
||||
|
||||
a = tuple
|
||||
if 1:
|
||||
a = list
|
||||
|
||||
#? ['append']
|
||||
a.append
|
||||
#? ['index']
|
||||
a.index
|
||||
|
||||
# -----------------
|
||||
# tuples exchanges
|
||||
# -----------------
|
||||
a, b = 1, ""
|
||||
#? int()
|
||||
a
|
||||
#? str()
|
||||
b
|
||||
|
||||
b, a = a, b
|
||||
#? int()
|
||||
b
|
||||
#? str()
|
||||
a
|
||||
|
||||
b, a = a, b
|
||||
#? int()
|
||||
a
|
||||
#? str()
|
||||
b
|
||||
|
||||
# -----------------
|
||||
# function
|
||||
# -----------------
|
||||
def a(a=3):
|
||||
#? int()
|
||||
a
|
||||
#? []
|
||||
a.func
|
||||
return a
|
||||
|
||||
#? int()
|
||||
a(2)
|
||||
#? []
|
||||
a(2).func
|
||||
|
||||
a_param = 3
|
||||
def func(a_param):
|
||||
# should not be int
|
||||
#? []
|
||||
a_param.
|
||||
|
||||
from os import path
|
||||
|
||||
|
||||
# should not return a function, because `a` is a function above
|
||||
def f(b, a): return a
|
||||
#? []
|
||||
f(b=3).
|
||||
|
||||
# -----------------
|
||||
# closure
|
||||
# -----------------
|
||||
|
||||
def x():
|
||||
a = 0
|
||||
|
||||
def x():
|
||||
return a
|
||||
|
||||
a = 3.0
|
||||
return x()
|
||||
|
||||
#? float()
|
||||
x()
|
||||
|
||||
# -----------------
|
||||
# class
|
||||
# -----------------
|
||||
class A(object):
|
||||
a = ""
|
||||
a = 3
|
||||
#? int()
|
||||
a
|
||||
a = list()
|
||||
def __init__(self):
|
||||
self.b = ""
|
||||
|
||||
def before(self):
|
||||
self.b = 3
|
||||
# TODO should this be so? include entries after cursor?
|
||||
#? int() str() list
|
||||
self.b
|
||||
self.b = list
|
||||
|
||||
self.a = 1
|
||||
#? str() int()
|
||||
self.a
|
||||
|
||||
#? ['after']
|
||||
self.after
|
||||
|
||||
self.c = 3
|
||||
#? int()
|
||||
self.c
|
||||
|
||||
def after(self):
|
||||
self.a = ''
|
||||
|
||||
c = set()
|
||||
|
||||
#? list()
|
||||
A.a
|
||||
|
||||
a = A()
|
||||
#? ['after']
|
||||
a.after
|
||||
#? []
|
||||
a.upper
|
||||
#? []
|
||||
a.append
|
||||
#? []
|
||||
a.real
|
||||
|
||||
#? str() int()
|
||||
a.a
|
||||
|
||||
a = 3
|
||||
class a():
|
||||
def __init__(self, a):
|
||||
self.a = a
|
||||
|
||||
#? float()
|
||||
a(1.0).a
|
||||
#?
|
||||
a().a
|
||||
|
||||
# -----------------
|
||||
# imports
|
||||
# -----------------
|
||||
|
||||
math = 3
|
||||
import math
|
||||
#? ['cosh']
|
||||
math.cosh
|
||||
#? []
|
||||
math.real
|
||||
|
||||
math = 3
|
||||
#? int()
|
||||
math
|
||||
#? []
|
||||
math.cos
|
||||
|
||||
# do the same for star imports
|
||||
cosh = 3
|
||||
from math import *
|
||||
# cosh doesn't work, but that's not a problem, star imports should be at the
|
||||
# start of EVERY script!
|
||||
cosh.real
|
||||
|
||||
cosh = 3
|
||||
#? int()
|
||||
cosh
|
||||
43
vim-plugins/bundle/jedi-vim/jedi/test/completion/parser.py
Normal file
43
vim-plugins/bundle/jedi-vim/jedi/test/completion/parser.py
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
"""
|
||||
Issues with the parser and not the type inference should be part of this file.
|
||||
"""
|
||||
|
||||
class IndentIssues():
|
||||
"""
|
||||
issue jedi-vim#288
|
||||
Which is really a fast parser issue. It used to start a new block at the
|
||||
parentheses, because it had problems with the indentation.
|
||||
"""
|
||||
def one_param(
|
||||
self,
|
||||
):
|
||||
return 1
|
||||
|
||||
def with_param(
|
||||
self,
|
||||
y):
|
||||
return y
|
||||
|
||||
|
||||
|
||||
#? int()
|
||||
IndentIssues().one_param()
|
||||
|
||||
#? str()
|
||||
IndentIssues().with_param('')
|
||||
|
||||
|
||||
"""
|
||||
Just because there's a def keyword, doesn't mean it should not be able to
|
||||
complete to definition.
|
||||
"""
|
||||
definition = 0
|
||||
#? ['definition']
|
||||
str(def
|
||||
|
||||
|
||||
# It might be hard to determine the context
|
||||
class Foo(object):
|
||||
@property
|
||||
#? ['str']
|
||||
def bar(str
|
||||
160
vim-plugins/bundle/jedi-vim/jedi/test/completion/pep0484.py
Normal file
160
vim-plugins/bundle/jedi-vim/jedi/test/completion/pep0484.py
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
""" Pep-0484 type hinting """
|
||||
|
||||
# python >= 3.2
|
||||
|
||||
|
||||
class A():
|
||||
pass
|
||||
|
||||
|
||||
def function_parameters(a: A, b, c: str, d: int, e: str, f: str, g: int=4):
|
||||
"""
|
||||
:param e: if docstring and annotation agree, only one should be returned
|
||||
:type e: str
|
||||
:param f: if docstring and annotation disagree, both should be returned
|
||||
:type f: int
|
||||
"""
|
||||
#? A()
|
||||
a
|
||||
#?
|
||||
b
|
||||
#? str()
|
||||
c
|
||||
#? int()
|
||||
d
|
||||
#? str()
|
||||
e
|
||||
#? int() str()
|
||||
f
|
||||
# int()
|
||||
g
|
||||
|
||||
|
||||
def return_unspecified():
|
||||
pass
|
||||
|
||||
#?
|
||||
return_unspecified()
|
||||
|
||||
|
||||
def return_none() -> None:
|
||||
"""
|
||||
Return type None means the same as no return type as far as jedi
|
||||
is concerned
|
||||
"""
|
||||
pass
|
||||
|
||||
#?
|
||||
return_none()
|
||||
|
||||
|
||||
def return_str() -> str:
|
||||
pass
|
||||
|
||||
#? str()
|
||||
return_str()
|
||||
|
||||
|
||||
def return_custom_class() -> A:
|
||||
pass
|
||||
|
||||
#? A()
|
||||
return_custom_class()
|
||||
|
||||
|
||||
def return_annotation_and_docstring() -> str:
|
||||
"""
|
||||
:rtype: int
|
||||
"""
|
||||
pass
|
||||
|
||||
#? str() int()
|
||||
return_annotation_and_docstring()
|
||||
|
||||
|
||||
def return_annotation_and_docstring_different() -> str:
|
||||
"""
|
||||
:rtype: str
|
||||
"""
|
||||
pass
|
||||
|
||||
#? str()
|
||||
return_annotation_and_docstring_different()
|
||||
|
||||
|
||||
def annotation_forward_reference(b: "B") -> "B":
|
||||
#? B()
|
||||
b
|
||||
|
||||
#? ["test_element"]
|
||||
annotation_forward_reference(1).t
|
||||
|
||||
class B:
|
||||
test_element = 1
|
||||
pass
|
||||
|
||||
#? B()
|
||||
annotation_forward_reference(1)
|
||||
|
||||
|
||||
class SelfReference:
|
||||
test_element = 1
|
||||
def test_method(self, x: "SelfReference") -> "SelfReference":
|
||||
#? SelfReference()
|
||||
x
|
||||
#? ["test_element", "test_method"]
|
||||
self.t
|
||||
#? ["test_element", "test_method"]
|
||||
x.t
|
||||
#? ["test_element", "test_method"]
|
||||
self.test_method(1).t
|
||||
|
||||
#? SelfReference()
|
||||
SelfReference().test_method()
|
||||
|
||||
def function_with_non_pep_0484_annotation(
|
||||
x: "I can put anything here",
|
||||
xx: "",
|
||||
yy: "\r\n\0;+*&^564835(---^&*34",
|
||||
y: 3 + 3,
|
||||
zz: float) -> int("42"):
|
||||
# infers int from function call
|
||||
#? int()
|
||||
x
|
||||
# infers int from function call
|
||||
#? int()
|
||||
xx
|
||||
# infers int from function call
|
||||
#? int()
|
||||
yy
|
||||
# infers str from function call
|
||||
#? str()
|
||||
y
|
||||
#? float()
|
||||
zz
|
||||
#?
|
||||
function_with_non_pep_0484_annotation(1, 2, 3, "force string")
|
||||
|
||||
def function_forward_reference_dynamic(
|
||||
x: return_str_type(),
|
||||
y: "return_str_type()") -> None:
|
||||
#?
|
||||
x
|
||||
#? str()
|
||||
y
|
||||
|
||||
def return_str_type():
|
||||
return str
|
||||
|
||||
|
||||
X = str
|
||||
def function_with_assined_class_in_reference(x: X, y: "Y"):
|
||||
#? str()
|
||||
x
|
||||
#? int()
|
||||
y
|
||||
Y = int
|
||||
|
||||
def just_because_we_can(x: "flo" + "at"):
|
||||
#? float()
|
||||
x
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
a = 3 # type: str
|
||||
#? str()
|
||||
a
|
||||
|
||||
b = 3 # type: str but I write more
|
||||
#? int()
|
||||
b
|
||||
|
||||
c = 3 # type: str # I comment more
|
||||
#? str()
|
||||
c
|
||||
|
||||
d = "It should not read comments from the next line"
|
||||
# type: int
|
||||
#? str()
|
||||
d
|
||||
|
||||
# type: int
|
||||
e = "It should not read comments from the previous line"
|
||||
#? str()
|
||||
e
|
||||
|
||||
class BB: pass
|
||||
|
||||
def test(a, b):
|
||||
a = a # type: BB
|
||||
c = a # type: str
|
||||
d = a
|
||||
# type: str
|
||||
e = a # type: str # Should ignore long whitespace
|
||||
|
||||
#? BB()
|
||||
a
|
||||
#? str()
|
||||
c
|
||||
#? BB()
|
||||
d
|
||||
#? str()
|
||||
e
|
||||
|
||||
a,b = 1, 2 # type: str, float
|
||||
#? str()
|
||||
a
|
||||
#? float()
|
||||
b
|
||||
|
||||
class Employee:
|
||||
pass
|
||||
|
||||
# The typing library is not installable for Python 2.6, therefore ignore the
|
||||
# following tests.
|
||||
# python >= 2.7
|
||||
|
||||
from typing import List
|
||||
x = [] # type: List[Employee]
|
||||
#? Employee()
|
||||
x[1]
|
||||
x, y, z = [], [], [] # type: List[int], List[int], List[str]
|
||||
#? int()
|
||||
y[2]
|
||||
x, y, z = [], [], [] # type: (List[float], List[float], List[BB])
|
||||
for zi in z:
|
||||
#? BB()
|
||||
zi
|
||||
|
||||
x = [
|
||||
1,
|
||||
2,
|
||||
] # type: List[str]
|
||||
|
||||
#? str()
|
||||
x[1]
|
||||
|
||||
|
||||
for bar in foo(): # type: str
|
||||
#? str()
|
||||
bar
|
||||
|
||||
for bar, baz in foo(): # type: int, float
|
||||
#? int()
|
||||
bar
|
||||
#? float()
|
||||
baz
|
||||
|
||||
for bar, baz in foo():
|
||||
# type: str, str
|
||||
""" type hinting on next line should not work """
|
||||
#?
|
||||
bar
|
||||
#?
|
||||
baz
|
||||
|
||||
with foo(): # type: int
|
||||
...
|
||||
|
||||
with foo() as f: # type: str
|
||||
#? str()
|
||||
f
|
||||
|
||||
with foo() as f:
|
||||
# type: str
|
||||
""" type hinting on next line should not work """
|
||||
#?
|
||||
f
|
||||
|
||||
aaa = some_extremely_long_function_name_that_doesnt_leave_room_for_hints() \
|
||||
# type: float # We should be able to put hints on the next line with a \
|
||||
#? float()
|
||||
aaa
|
||||
|
|
@ -0,0 +1,263 @@
|
|||
"""
|
||||
Test the typing library, with docstrings. This is needed since annotations
|
||||
are not supported in python 2.7 else then annotating by comment (and this is
|
||||
still TODO at 2016-01-23)
|
||||
"""
|
||||
# There's no Python 2.6 typing module.
|
||||
# python >= 2.7
|
||||
import typing
|
||||
class B:
|
||||
pass
|
||||
|
||||
def we_can_has_sequence(p, q, r, s, t, u):
|
||||
"""
|
||||
:type p: typing.Sequence[int]
|
||||
:type q: typing.Sequence[B]
|
||||
:type r: typing.Sequence[int]
|
||||
:type s: typing.Sequence["int"]
|
||||
:type t: typing.MutableSequence[dict]
|
||||
:type u: typing.List[float]
|
||||
"""
|
||||
#? ["count"]
|
||||
p.c
|
||||
#? int()
|
||||
p[1]
|
||||
#? ["count"]
|
||||
q.c
|
||||
#? B()
|
||||
q[1]
|
||||
#? ["count"]
|
||||
r.c
|
||||
#? int()
|
||||
r[1]
|
||||
#? ["count"]
|
||||
s.c
|
||||
#? int()
|
||||
s[1]
|
||||
#? []
|
||||
s.a
|
||||
#? ["append"]
|
||||
t.a
|
||||
#? dict()
|
||||
t[1]
|
||||
#? ["append"]
|
||||
u.a
|
||||
#? float()
|
||||
u[1]
|
||||
|
||||
def iterators(ps, qs, rs, ts):
|
||||
"""
|
||||
:type ps: typing.Iterable[int]
|
||||
:type qs: typing.Iterator[str]
|
||||
:type rs: typing.Sequence["ForwardReference"]
|
||||
:type ts: typing.AbstractSet["float"]
|
||||
"""
|
||||
for p in ps:
|
||||
#? int()
|
||||
p
|
||||
#?
|
||||
next(ps)
|
||||
a, b = ps
|
||||
#? int()
|
||||
a
|
||||
##? int() --- TODO fix support for tuple assignment
|
||||
# https://github.com/davidhalter/jedi/pull/663#issuecomment-172317854
|
||||
# test below is just to make sure that in case it gets fixed by accident
|
||||
# these tests will be fixed as well the way they should be
|
||||
#?
|
||||
b
|
||||
|
||||
for q in qs:
|
||||
#? str()
|
||||
q
|
||||
#? str()
|
||||
next(qs)
|
||||
for r in rs:
|
||||
#? ForwardReference()
|
||||
r
|
||||
#?
|
||||
next(rs)
|
||||
for t in ts:
|
||||
#? float()
|
||||
t
|
||||
|
||||
def sets(p, q):
|
||||
"""
|
||||
:type p: typing.AbstractSet[int]
|
||||
:type q: typing.MutableSet[float]
|
||||
"""
|
||||
#? []
|
||||
p.a
|
||||
#? ["add"]
|
||||
q.a
|
||||
|
||||
def tuple(p, q, r):
|
||||
"""
|
||||
:type p: typing.Tuple[int]
|
||||
:type q: typing.Tuple[int, str, float]
|
||||
:type r: typing.Tuple[B, ...]
|
||||
"""
|
||||
#? int()
|
||||
p[0]
|
||||
#? int()
|
||||
q[0]
|
||||
#? str()
|
||||
q[1]
|
||||
#? float()
|
||||
q[2]
|
||||
#? B()
|
||||
r[0]
|
||||
#? B()
|
||||
r[1]
|
||||
#? B()
|
||||
r[2]
|
||||
#? B()
|
||||
r[10000]
|
||||
i, s, f = q
|
||||
#? int()
|
||||
i
|
||||
##? str() --- TODO fix support for tuple assignment
|
||||
# https://github.com/davidhalter/jedi/pull/663#issuecomment-172317854
|
||||
#?
|
||||
s
|
||||
##? float() --- TODO fix support for tuple assignment
|
||||
# https://github.com/davidhalter/jedi/pull/663#issuecomment-172317854
|
||||
#?
|
||||
f
|
||||
|
||||
class Key:
|
||||
pass
|
||||
|
||||
class Value:
|
||||
pass
|
||||
|
||||
def mapping(p, q, d, r, s, t):
|
||||
"""
|
||||
:type p: typing.Mapping[Key, Value]
|
||||
:type q: typing.MutableMapping[Key, Value]
|
||||
:type d: typing.Dict[Key, Value]
|
||||
:type r: typing.KeysView[Key]
|
||||
:type s: typing.ValuesView[Value]
|
||||
:type t: typing.ItemsView[Key, Value]
|
||||
"""
|
||||
#? []
|
||||
p.setd
|
||||
#? ["setdefault"]
|
||||
q.setd
|
||||
#? ["setdefault"]
|
||||
d.setd
|
||||
#? Value()
|
||||
p[1]
|
||||
for key in p:
|
||||
#? Key()
|
||||
key
|
||||
for key in p.keys():
|
||||
#? Key()
|
||||
key
|
||||
for value in p.values():
|
||||
#? Value()
|
||||
value
|
||||
for item in p.items():
|
||||
#? Key()
|
||||
item[0]
|
||||
#? Value()
|
||||
item[1]
|
||||
(key, value) = item
|
||||
#? Key()
|
||||
key
|
||||
#? Value()
|
||||
value
|
||||
for key, value in p.items():
|
||||
#? Key()
|
||||
key
|
||||
#? Value()
|
||||
value
|
||||
for key in r:
|
||||
#? Key()
|
||||
key
|
||||
for value in s:
|
||||
#? Value()
|
||||
value
|
||||
for key, value in t:
|
||||
#? Key()
|
||||
key
|
||||
#? Value()
|
||||
value
|
||||
|
||||
def union(p, q, r, s, t):
|
||||
"""
|
||||
:type p: typing.Union[int]
|
||||
:type q: typing.Union[int, int]
|
||||
:type r: typing.Union[int, str, "int"]
|
||||
:type s: typing.Union[int, typing.Union[str, "typing.Union['float', 'dict']"]]
|
||||
:type t: typing.Union[int, None]
|
||||
"""
|
||||
#? int()
|
||||
p
|
||||
#? int()
|
||||
q
|
||||
#? int() str()
|
||||
r
|
||||
#? int() str() float() dict()
|
||||
s
|
||||
#? int()
|
||||
t
|
||||
|
||||
def optional(p):
|
||||
"""
|
||||
:type p: typing.Optional[int]
|
||||
Optional does not do anything special. However it should be recognised
|
||||
as being of that type. Jedi doesn't do anything with the extra into that
|
||||
it can be None as well
|
||||
"""
|
||||
#? int()
|
||||
p
|
||||
|
||||
class ForwardReference:
|
||||
pass
|
||||
|
||||
class TestDict(typing.Dict[str, int]):
|
||||
def setdud(self):
|
||||
pass
|
||||
|
||||
def testdict(x):
|
||||
"""
|
||||
:type x: TestDict
|
||||
"""
|
||||
#? ["setdud", "setdefault"]
|
||||
x.setd
|
||||
for key in x.keys():
|
||||
#? str()
|
||||
key
|
||||
for value in x.values():
|
||||
#? int()
|
||||
value
|
||||
|
||||
x = TestDict()
|
||||
#? ["setdud", "setdefault"]
|
||||
x.setd
|
||||
for key in x.keys():
|
||||
#? str()
|
||||
key
|
||||
for value in x.values():
|
||||
#? int()
|
||||
value
|
||||
# python >= 3.2
|
||||
"""
|
||||
docstrings have some auto-import, annotations can use all of Python's
|
||||
import logic
|
||||
"""
|
||||
import typing as t
|
||||
def union2(x: t.Union[int, str]):
|
||||
#? int() str()
|
||||
x
|
||||
|
||||
from typing import Union
|
||||
def union3(x: Union[int, str]):
|
||||
#? int() str()
|
||||
x
|
||||
|
||||
from typing import Union as U
|
||||
def union4(x: U[int, str]):
|
||||
#? int() str()
|
||||
x
|
||||
138
vim-plugins/bundle/jedi-vim/jedi/test/completion/precedence.py
Normal file
138
vim-plugins/bundle/jedi-vim/jedi/test/completion/precedence.py
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
"""
|
||||
Test Jedi's operation understanding. Jedi should understand simple additions,
|
||||
multiplications, etc.
|
||||
"""
|
||||
# -----------------
|
||||
# numbers
|
||||
# -----------------
|
||||
x = [1, 'a', 1.0]
|
||||
|
||||
#? int() str() float()
|
||||
x[12]
|
||||
|
||||
#? float()
|
||||
x[1 + 1]
|
||||
|
||||
index = 0 + 1
|
||||
|
||||
#? str()
|
||||
x[index]
|
||||
|
||||
#? int()
|
||||
x[1 + (-1)]
|
||||
|
||||
def calculate(number):
|
||||
return number + constant
|
||||
|
||||
constant = 1
|
||||
|
||||
#? float()
|
||||
x[calculate(1)]
|
||||
|
||||
def calculate(number):
|
||||
return number + constant
|
||||
|
||||
# -----------------
|
||||
# strings
|
||||
# -----------------
|
||||
|
||||
x = 'upp' + 'e'
|
||||
|
||||
#? str.upper
|
||||
getattr(str, x + 'r')
|
||||
|
||||
a = "a"*3
|
||||
#? str()
|
||||
a
|
||||
a = 3 * "a"
|
||||
#? str()
|
||||
a
|
||||
|
||||
a = 3 * "a"
|
||||
#? str()
|
||||
a
|
||||
|
||||
#? int()
|
||||
(3 ** 3)
|
||||
#? int() str()
|
||||
(3 ** 'a')
|
||||
|
||||
# -----------------
|
||||
# assignments
|
||||
# -----------------
|
||||
|
||||
x = [1, 'a', 1.0]
|
||||
|
||||
i = 0
|
||||
i += 1
|
||||
i += 1
|
||||
#? float()
|
||||
x[i]
|
||||
|
||||
i = 1
|
||||
i += 1
|
||||
i -= 3
|
||||
i += 1
|
||||
#? int()
|
||||
x[i]
|
||||
|
||||
# -----------------
|
||||
# in
|
||||
# -----------------
|
||||
|
||||
if 'X' in 'Y':
|
||||
a = 3
|
||||
else:
|
||||
a = ''
|
||||
# For now don't really check for truth values. So in should return both
|
||||
# results.
|
||||
#? str() int()
|
||||
a
|
||||
|
||||
# -----------------
|
||||
# for flow assignments
|
||||
# -----------------
|
||||
|
||||
class FooBar(object):
|
||||
fuu = 0.1
|
||||
raboof = 'fourtytwo'
|
||||
|
||||
# targets should be working
|
||||
target = ''
|
||||
for char in ['f', 'u', 'u']:
|
||||
target += char
|
||||
#? float()
|
||||
getattr(FooBar, target)
|
||||
|
||||
# github #24
|
||||
target = u''
|
||||
for char in reversed(['f', 'o', 'o', 'b', 'a', 'r']):
|
||||
target += char
|
||||
|
||||
#? str()
|
||||
getattr(FooBar, target)
|
||||
|
||||
|
||||
# -----------------
|
||||
# repetition problems -> could be very slow and memory expensive - shouldn't
|
||||
# be.
|
||||
# -----------------
|
||||
|
||||
b = [str(1)]
|
||||
l = list
|
||||
for x in [l(0), l(1), l(2), l(3), l(4), l(5), l(6), l(7), l(8), l(9), l(10),
|
||||
l(11), l(12), l(13), l(14), l(15), l(16), l(17), l(18), l(19), l(20),
|
||||
l(21), l(22), l(23), l(24), l(25), l(26), l(27), l(28), l(29)]:
|
||||
b += x
|
||||
|
||||
#? str()
|
||||
b[1]
|
||||
|
||||
|
||||
# -----------------
|
||||
# undefined names
|
||||
# -----------------
|
||||
a = foobarbaz + 'hello'
|
||||
|
||||
#? int() float()
|
||||
{'hello': 1, 'bar': 1.0}[a]
|
||||
|
|
@ -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]
|
||||
224
vim-plugins/bundle/jedi-vim/jedi/test/completion/stdlib.py
Normal file
224
vim-plugins/bundle/jedi-vim/jedi/test/completion/stdlib.py
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
"""
|
||||
std library stuff
|
||||
"""
|
||||
|
||||
# -----------------
|
||||
# builtins
|
||||
# -----------------
|
||||
arr = ['']
|
||||
|
||||
#? str()
|
||||
sorted(arr)[0]
|
||||
|
||||
#? str()
|
||||
next(reversed(arr))
|
||||
next(reversed(arr))
|
||||
|
||||
# should not fail if there's no return value.
|
||||
def yielder():
|
||||
yield None
|
||||
|
||||
#? None
|
||||
next(reversed(yielder()))
|
||||
|
||||
# empty reversed should not raise an error
|
||||
#?
|
||||
next(reversed())
|
||||
|
||||
#? str()
|
||||
next(open(''))
|
||||
|
||||
#? int()
|
||||
{'a':2}.setdefault('a', 3)
|
||||
|
||||
# Compiled classes should have the meta class attributes.
|
||||
#? ['__itemsize__']
|
||||
tuple.__itemsize__
|
||||
|
||||
# -----------------
|
||||
# type() calls with one parameter
|
||||
# -----------------
|
||||
#? int
|
||||
type(1)
|
||||
#? int
|
||||
type(int())
|
||||
#? type
|
||||
type(int)
|
||||
#? type
|
||||
type(type)
|
||||
#? list
|
||||
type([])
|
||||
|
||||
def x():
|
||||
yield 1
|
||||
generator = type(x())
|
||||
#? generator
|
||||
type(x for x in [])
|
||||
#? type(x)
|
||||
type(lambda: x)
|
||||
|
||||
import math
|
||||
import os
|
||||
#? type(os)
|
||||
type(math)
|
||||
class X(): pass
|
||||
#? type
|
||||
type(X)
|
||||
|
||||
# -----------------
|
||||
# enumerate
|
||||
# -----------------
|
||||
for i, j in enumerate(["as", "ad"]):
|
||||
#? int()
|
||||
i
|
||||
#? str()
|
||||
j
|
||||
|
||||
# -----------------
|
||||
# re
|
||||
# -----------------
|
||||
import re
|
||||
c = re.compile(r'a')
|
||||
# re.compile should not return str -> issue #68
|
||||
#? []
|
||||
c.startswith
|
||||
#? int()
|
||||
c.match().start()
|
||||
|
||||
#? int()
|
||||
re.match(r'a', 'a').start()
|
||||
|
||||
for a in re.finditer('a', 'a'):
|
||||
#? int()
|
||||
a.start()
|
||||
|
||||
#? str()
|
||||
re.sub('a', 'a')
|
||||
|
||||
# -----------------
|
||||
# ref
|
||||
# -----------------
|
||||
import weakref
|
||||
|
||||
#? int()
|
||||
weakref.proxy(1)
|
||||
|
||||
#? weakref.ref()
|
||||
weakref.ref(1)
|
||||
#? int()
|
||||
weakref.ref(1)()
|
||||
|
||||
# -----------------
|
||||
# functools
|
||||
# -----------------
|
||||
import functools
|
||||
|
||||
basetwo = functools.partial(int, base=2)
|
||||
#? int()
|
||||
basetwo()
|
||||
|
||||
def function(a, b):
|
||||
return a, b
|
||||
a = functools.partial(function, 0)
|
||||
|
||||
#? int()
|
||||
a('')[0]
|
||||
#? str()
|
||||
a('')[1]
|
||||
|
||||
kw = functools.partial(function, b=1.0)
|
||||
tup = kw(1)
|
||||
#? int()
|
||||
tup[0]
|
||||
#? float()
|
||||
tup[1]
|
||||
|
||||
def my_decorator(f):
|
||||
@functools.wraps(f)
|
||||
def wrapper(*args, **kwds):
|
||||
return f(*args, **kwds)
|
||||
return wrapper
|
||||
|
||||
@my_decorator
|
||||
def example(a):
|
||||
return a
|
||||
|
||||
#? str()
|
||||
example('')
|
||||
|
||||
|
||||
# -----------------
|
||||
# sqlite3 (#84)
|
||||
# -----------------
|
||||
|
||||
import sqlite3
|
||||
#? sqlite3.Connection()
|
||||
con = sqlite3.connect()
|
||||
#? sqlite3.Cursor()
|
||||
c = con.cursor()
|
||||
#? sqlite3.Row()
|
||||
row = c.fetchall()[0]
|
||||
#? str()
|
||||
row.keys()[0]
|
||||
|
||||
def huhu(db):
|
||||
"""
|
||||
:type db: sqlite3.Connection
|
||||
:param db: the db connection
|
||||
"""
|
||||
#? sqlite3.Connection()
|
||||
db
|
||||
|
||||
# -----------------
|
||||
# hashlib
|
||||
# -----------------
|
||||
|
||||
import hashlib
|
||||
|
||||
#? ['md5']
|
||||
hashlib.md5
|
||||
|
||||
# -----------------
|
||||
# copy
|
||||
# -----------------
|
||||
|
||||
import copy
|
||||
#? int()
|
||||
copy.deepcopy(1)
|
||||
|
||||
#?
|
||||
copy.copy()
|
||||
|
||||
# -----------------
|
||||
# json
|
||||
# -----------------
|
||||
|
||||
# We don't want any results for json, because it depends on IO.
|
||||
import json
|
||||
#?
|
||||
json.load('asdf')
|
||||
#?
|
||||
json.loads('[1]')
|
||||
|
||||
# -----------------
|
||||
# random
|
||||
# -----------------
|
||||
|
||||
import random
|
||||
class A(object):
|
||||
def say(self): pass
|
||||
class B(object):
|
||||
def shout(self): pass
|
||||
cls = random.choice([A, B])
|
||||
#? ['say', 'shout']
|
||||
cls().s
|
||||
|
||||
# -----------------
|
||||
# random
|
||||
# -----------------
|
||||
|
||||
import zipfile
|
||||
z = zipfile.ZipFile("foo")
|
||||
# It's too slow. So we don't run it at the moment.
|
||||
##? ['upper']
|
||||
z.read('name').upper
|
||||
25
vim-plugins/bundle/jedi-vim/jedi/test/completion/sys_path.py
Normal file
25
vim-plugins/bundle/jedi-vim/jedi/test/completion/sys_path.py
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
import sys
|
||||
import os
|
||||
from os import dirname
|
||||
|
||||
sys.path.insert(0, '../../jedi')
|
||||
sys.path.append(dirname(os.path.abspath('thirdparty' + os.path.sep + 'asdf')))
|
||||
|
||||
# modifications, that should fail:
|
||||
# because of sys module
|
||||
sys.path.append(sys.path[1] + '/thirdparty')
|
||||
# syntax err
|
||||
sys.path.append('a' +* '/thirdparty')
|
||||
|
||||
#? ['evaluate']
|
||||
import evaluate
|
||||
|
||||
#? ['Evaluator']
|
||||
evaluate.Evaluator
|
||||
|
||||
#? ['jedi_']
|
||||
import jedi_
|
||||
|
||||
#? ['el']
|
||||
jedi_.el
|
||||
19
vim-plugins/bundle/jedi-vim/jedi/test/completion/thirdparty/PyQt4_.py
vendored
Normal file
19
vim-plugins/bundle/jedi-vim/jedi/test/completion/thirdparty/PyQt4_.py
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
from PyQt4.QtCore import *
|
||||
from PyQt4.QtGui import *
|
||||
|
||||
#? ['QActionGroup']
|
||||
QActionGroup
|
||||
|
||||
#? ['currentText']
|
||||
QStyleOptionComboBox().currentText
|
||||
|
||||
#? []
|
||||
QStyleOptionComboBox().currentText.
|
||||
|
||||
from PyQt4 import QtGui
|
||||
|
||||
#? ['currentText']
|
||||
QtGui.QStyleOptionComboBox().currentText
|
||||
|
||||
#? []
|
||||
QtGui.QStyleOptionComboBox().currentText.
|
||||
11
vim-plugins/bundle/jedi-vim/jedi/test/completion/thirdparty/django_.py
vendored
Normal file
11
vim-plugins/bundle/jedi-vim/jedi/test/completion/thirdparty/django_.py
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#! ['class ObjectDoesNotExist']
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
import django
|
||||
|
||||
#? ['get_version']
|
||||
django.get_version
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
#? ['configured']
|
||||
settings.configured
|
||||
52
vim-plugins/bundle/jedi-vim/jedi/test/completion/thirdparty/jedi_.py
vendored
Normal file
52
vim-plugins/bundle/jedi-vim/jedi/test/completion/thirdparty/jedi_.py
vendored
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
|
||||
from jedi import functions, evaluate, parsing
|
||||
|
||||
el = functions.completions()[0]
|
||||
#? ['description']
|
||||
el.description
|
||||
|
||||
#? str()
|
||||
el.description
|
||||
|
||||
|
||||
scopes, path, dot, like = \
|
||||
api._prepare_goto(source, row, column, path, True)
|
||||
|
||||
# has problems with that (sometimes) very deep nesting.
|
||||
#? set()
|
||||
el = scopes
|
||||
|
||||
# get_names_for_scope is also recursion stuff
|
||||
#? tuple()
|
||||
el = list(evaluate.get_names_for_scope())[0]
|
||||
|
||||
#? int() parsing.Module()
|
||||
el = list(evaluate.get_names_for_scope(1))[0][0]
|
||||
#? parsing.Module()
|
||||
el = list(evaluate.get_names_for_scope())[0][0]
|
||||
|
||||
#? list()
|
||||
el = list(evaluate.get_names_for_scope(1))[0][1]
|
||||
#? list()
|
||||
el = list(evaluate.get_names_for_scope())[0][1]
|
||||
|
||||
#? list()
|
||||
parsing.Scope((0,0)).get_set_vars()
|
||||
#? parsing.Import() parsing.Name()
|
||||
parsing.Scope((0,0)).get_set_vars()[0]
|
||||
# TODO access parent is not possible, because that is not set in the class
|
||||
## parsing.Class()
|
||||
parsing.Scope((0,0)).get_set_vars()[0].parent
|
||||
|
||||
#? parsing.Import() parsing.Name()
|
||||
el = list(evaluate.get_names_for_scope())[0][1][0]
|
||||
|
||||
#? evaluate.Array() evaluate.Class() evaluate.Function() evaluate.Instance()
|
||||
list(evaluate.follow_call())[0]
|
||||
|
||||
# With the right recursion settings, this should be possible (and maybe more):
|
||||
# Array Class Function Generator Instance Module
|
||||
# However, this was produced with the recursion settings 10/350/10000, and
|
||||
# lasted 18.5 seconds. So we just have to be content with the results.
|
||||
#? evaluate.Class() evaluate.Function()
|
||||
evaluate.get_scopes_for_name()[0]
|
||||
11
vim-plugins/bundle/jedi-vim/jedi/test/completion/thirdparty/psycopg2_.py
vendored
Normal file
11
vim-plugins/bundle/jedi-vim/jedi/test/completion/thirdparty/psycopg2_.py
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import psycopg2
|
||||
|
||||
conn = psycopg2.connect('dbname=test')
|
||||
|
||||
#? ['cursor']
|
||||
conn.cursor
|
||||
|
||||
cur = conn.cursor()
|
||||
|
||||
#? ['fetchall']
|
||||
cur.fetchall
|
||||
36
vim-plugins/bundle/jedi-vim/jedi/test/completion/thirdparty/pylab_.py
vendored
Normal file
36
vim-plugins/bundle/jedi-vim/jedi/test/completion/thirdparty/pylab_.py
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
import pylab
|
||||
|
||||
# two gotos
|
||||
#! ['module numpy']
|
||||
import numpy
|
||||
|
||||
#! ['module random']
|
||||
import numpy.random
|
||||
|
||||
#? ['array2string']
|
||||
numpy.array2string
|
||||
|
||||
#? ['shape']
|
||||
numpy.matrix().shape
|
||||
|
||||
#? ['random_integers']
|
||||
pylab.random_integers
|
||||
|
||||
#? []
|
||||
numpy.random_integers
|
||||
|
||||
#? ['random_integers']
|
||||
numpy.random.random_integers
|
||||
#? ['sample']
|
||||
numpy.random.sample
|
||||
|
||||
import numpy
|
||||
na = numpy.array([1,2])
|
||||
#? ['shape']
|
||||
na.shape
|
||||
|
||||
# shouldn't raise an error #29, jedi-vim
|
||||
# doesn't return something, because matplotlib uses __import__
|
||||
fig = pylab.figure()
|
||||
#?
|
||||
fig.add_subplot
|
||||
127
vim-plugins/bundle/jedi-vim/jedi/test/completion/types.py
Normal file
127
vim-plugins/bundle/jedi-vim/jedi/test/completion/types.py
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
# -----------------
|
||||
# non array
|
||||
# -----------------
|
||||
|
||||
#? ['imag']
|
||||
int.imag
|
||||
|
||||
#? []
|
||||
int.is_integer
|
||||
|
||||
#? ['is_integer']
|
||||
float.is_int
|
||||
|
||||
#? ['is_integer']
|
||||
1.0.is_integer
|
||||
|
||||
#? ['upper']
|
||||
"".upper
|
||||
|
||||
#? ['upper']
|
||||
r"".upper
|
||||
|
||||
# strangely this didn't work, because the = is used for assignments
|
||||
#? ['upper']
|
||||
"=".upper
|
||||
a = "="
|
||||
#? ['upper']
|
||||
a.upper
|
||||
|
||||
|
||||
# -----------------
|
||||
# lists
|
||||
# -----------------
|
||||
arr = []
|
||||
#? ['append']
|
||||
arr.app
|
||||
|
||||
#? ['append']
|
||||
list().app
|
||||
#? ['append']
|
||||
[].append
|
||||
|
||||
arr2 = [1,2,3]
|
||||
#? ['append']
|
||||
arr2.app
|
||||
|
||||
#? int()
|
||||
arr.count(1)
|
||||
|
||||
x = []
|
||||
#?
|
||||
x.pop()
|
||||
x = [3]
|
||||
#? int()
|
||||
x.pop()
|
||||
x = []
|
||||
x.append(1.0)
|
||||
#? float()
|
||||
x.pop()
|
||||
|
||||
# -----------------
|
||||
# dicts
|
||||
# -----------------
|
||||
dic = {}
|
||||
|
||||
#? ['copy', 'clear']
|
||||
dic.c
|
||||
|
||||
dic2 = dict(a=1, b=2)
|
||||
#? ['pop', 'popitem']
|
||||
dic2.p
|
||||
#? ['popitem']
|
||||
{}.popitem
|
||||
|
||||
dic2 = {'asdf': 3}
|
||||
#? ['popitem']
|
||||
dic2.popitem
|
||||
|
||||
#? int()
|
||||
dic2['asdf']
|
||||
|
||||
d = {'a': 3, 1.0: list}
|
||||
|
||||
#? int() list
|
||||
d.values()[0]
|
||||
##? int() list
|
||||
dict(d).values()[0]
|
||||
|
||||
#? str()
|
||||
d.items()[0][0]
|
||||
#? int()
|
||||
d.items()[0][1]
|
||||
|
||||
# -----------------
|
||||
# set
|
||||
# -----------------
|
||||
set_t = {1,2}
|
||||
|
||||
#? ['clear', 'copy']
|
||||
set_t.c
|
||||
|
||||
set_t2 = set()
|
||||
|
||||
#? ['clear', 'copy']
|
||||
set_t2.c
|
||||
|
||||
# -----------------
|
||||
# tuples
|
||||
# -----------------
|
||||
tup = ('',2)
|
||||
|
||||
#? ['count']
|
||||
tup.c
|
||||
|
||||
tup2 = tuple()
|
||||
#? ['index']
|
||||
tup2.i
|
||||
#? ['index']
|
||||
().i
|
||||
|
||||
tup3 = 1,""
|
||||
#? ['index']
|
||||
tup3.index
|
||||
|
||||
tup4 = 1,""
|
||||
#? ['index']
|
||||
tup4.index
|
||||
275
vim-plugins/bundle/jedi-vim/jedi/test/completion/usages.py
Normal file
275
vim-plugins/bundle/jedi-vim/jedi/test/completion/usages.py
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
"""
|
||||
Renaming tests. This means search for usages.
|
||||
I always leave a little bit of space to add room for additions, because the
|
||||
results always contain position informations.
|
||||
"""
|
||||
#< 4 (0,4), (3,0), (5,0), (17,0), (12,4), (14,5), (15,0)
|
||||
def abc(): pass
|
||||
|
||||
#< 0 (-3,4), (0,0), (2,0), (14,0), (9,4), (11,5), (12,0)
|
||||
abc.d.a.bsaasd.abc.d
|
||||
|
||||
abc
|
||||
# unicode chars shouldn't be a problem.
|
||||
x['smörbröd'].abc
|
||||
|
||||
# With the new parser these statements are not recognized as stateents, because
|
||||
# they are not valid Python.
|
||||
if 1:
|
||||
abc =
|
||||
else:
|
||||
(abc) =
|
||||
abc =
|
||||
#< (-17,4), (-14,0), (-12,0), (0,0), (-2,0), (-3,5), (-5,4)
|
||||
abc
|
||||
|
||||
abc = 5
|
||||
|
||||
|
||||
Abc = 3
|
||||
|
||||
#< 6 (0,6), (2,4), (5,8), (17,0)
|
||||
class Abc():
|
||||
#< (-2,6), (0,4), (3,8), (15,0)
|
||||
Abc
|
||||
|
||||
def Abc(self):
|
||||
Abc; self.c = 3
|
||||
|
||||
#< 17 (0,16), (2,8)
|
||||
def a(self, Abc):
|
||||
#< 10 (-2,16), (0,8)
|
||||
Abc
|
||||
|
||||
#< 19 (0,18), (2,8)
|
||||
def self_test(self):
|
||||
#< 12 (-2,18), (0,8)
|
||||
self.b
|
||||
|
||||
Abc.d.Abc
|
||||
|
||||
|
||||
#< 4 (0,4), (5,1)
|
||||
def blubi():
|
||||
pass
|
||||
|
||||
|
||||
#< (-5,4), (0,1)
|
||||
@blubi
|
||||
def a(): pass
|
||||
|
||||
|
||||
#< 0 (0,0), (1,0)
|
||||
set_object_var = object()
|
||||
set_object_var.var = 1
|
||||
|
||||
|
||||
response = 5
|
||||
#< 0 (0,0), (1,0), (2,0), (4,0)
|
||||
response = HttpResponse(mimetype='application/pdf')
|
||||
response['Content-Disposition'] = 'attachment; filename=%s.pdf' % id
|
||||
response.write(pdf)
|
||||
#< (-4,0), (-3,0), (-2,0), (0,0)
|
||||
response
|
||||
|
||||
|
||||
# -----------------
|
||||
# imports
|
||||
# -----------------
|
||||
#< (0,7), (3,0)
|
||||
import module_not_exists
|
||||
|
||||
#< (-3,7), (0,0)
|
||||
module_not_exists
|
||||
|
||||
|
||||
#< ('rename1', 1,0), (0,24), (3,0), (6,17), ('rename2', 4,5), (10,17), (13,17), ('imports', 72, 16)
|
||||
from import_tree import rename1
|
||||
|
||||
#< (0,8), ('rename1',3,0), ('rename2',4,20), ('rename2',6,0), (3,32), (7,32), (4,0)
|
||||
rename1.abc
|
||||
|
||||
#< (-3,8), ('rename1', 3,0), ('rename2', 4,20), ('rename2', 6,0), (0,32), (4,32), (1,0)
|
||||
from import_tree.rename1 import abc
|
||||
abc
|
||||
|
||||
#< 20 ('rename1', 1,0), ('rename2', 4,5), (-10,24), (-7,0), (-4,17), (0,17), (3,17), ('imports', 72, 16)
|
||||
from import_tree.rename1 import abc
|
||||
|
||||
#< (0, 32),
|
||||
from import_tree.rename1 import not_existing
|
||||
|
||||
# Shouldn't raise an error or do anything weird.
|
||||
from not_existing import *
|
||||
|
||||
# -----------------
|
||||
# classes
|
||||
# -----------------
|
||||
|
||||
class TestMethods(object):
|
||||
#< 8 (0,8), (2,13)
|
||||
def a_method(self):
|
||||
#< 13 (-2,8), (0,13)
|
||||
self.a_method()
|
||||
#< 13 (2,8), (0,13), (3,13)
|
||||
self.b_method()
|
||||
|
||||
def b_method(self):
|
||||
self.b_method
|
||||
|
||||
|
||||
class TestClassVar(object):
|
||||
#< 4 (0,4), (5,13), (7,21)
|
||||
class_v = 1
|
||||
def a(self):
|
||||
class_v = 1
|
||||
|
||||
#< (-5,4), (0,13), (2,21)
|
||||
self.class_v
|
||||
#< (-7,4), (-2,13), (0,21)
|
||||
TestClassVar.class_v
|
||||
#< (0,8), (-7, 8)
|
||||
class_v
|
||||
|
||||
class TestInstanceVar():
|
||||
def a(self):
|
||||
#< 13 (4,13), (0,13)
|
||||
self._instance_var = 3
|
||||
|
||||
def b(self):
|
||||
#< (-4,13), (0,13)
|
||||
self._instance_var
|
||||
# A call to self used to trigger an error, because it's also a trailer
|
||||
# with two children.
|
||||
self()
|
||||
|
||||
|
||||
class NestedClass():
|
||||
def __getattr__(self, name):
|
||||
return self
|
||||
|
||||
# Shouldn't find a definition, because there's other `instance`.
|
||||
# TODO reenable that test
|
||||
##< (0, 14),
|
||||
NestedClass().instance
|
||||
|
||||
|
||||
# -----------------
|
||||
# inheritance
|
||||
# -----------------
|
||||
class Super(object):
|
||||
#< 4 (0,4), (23,18), (25,13)
|
||||
base_class = 1
|
||||
#< 4 (0,4),
|
||||
class_var = 1
|
||||
|
||||
#< 8 (0,8),
|
||||
def base_method(self):
|
||||
#< 13 (0,13), (20,13)
|
||||
self.base_var = 1
|
||||
#< 13 (0,13),
|
||||
self.instance_var = 1
|
||||
|
||||
#< 8 (0,8),
|
||||
def just_a_method(self): pass
|
||||
|
||||
|
||||
#< 20 (0,16), (-18,6)
|
||||
class TestClass(Super):
|
||||
#< 4 (0,4),
|
||||
class_var = 1
|
||||
|
||||
def x_method(self):
|
||||
|
||||
#< (0,18), (2,13), (-23,4)
|
||||
TestClass.base_class
|
||||
#< (-2,18), (0,13), (-25,4)
|
||||
self.base_class
|
||||
#< (-20,13), (0,13)
|
||||
self.base_var
|
||||
#<
|
||||
TestClass.base_var
|
||||
|
||||
|
||||
#< 13 (5,13), (0,13)
|
||||
self.instance_var = 3
|
||||
|
||||
#< 9 (0,8),
|
||||
def just_a_method(self):
|
||||
#< (-5,13), (0,13)
|
||||
self.instance_var
|
||||
|
||||
|
||||
# -----------------
|
||||
# properties
|
||||
# -----------------
|
||||
class TestProperty:
|
||||
|
||||
@property
|
||||
#< 10 (0,8), (5,13)
|
||||
def prop(self):
|
||||
return 1
|
||||
|
||||
def a(self):
|
||||
#< 13 (-5,8), (0,13)
|
||||
self.prop
|
||||
|
||||
@property
|
||||
#< 13 (0,8), (4,5)
|
||||
def rw_prop(self):
|
||||
return self._rw_prop
|
||||
|
||||
#< 8 (-4,8), (0,5)
|
||||
@rw_prop.setter
|
||||
#< 8 (0,8), (5,13)
|
||||
def rw_prop(self, value):
|
||||
self._rw_prop = value
|
||||
|
||||
def b(self):
|
||||
#< 13 (-5,8), (0,13)
|
||||
self.rw_prop
|
||||
|
||||
# -----------------
|
||||
# *args, **kwargs
|
||||
# -----------------
|
||||
#< 11 (1,11), (0,8)
|
||||
def f(**kwargs):
|
||||
return kwargs
|
||||
|
||||
|
||||
# -----------------
|
||||
# No result
|
||||
# -----------------
|
||||
if isinstance(j, int):
|
||||
#<
|
||||
j
|
||||
|
||||
# -----------------
|
||||
# Dynamic Param Search
|
||||
# -----------------
|
||||
|
||||
class DynamicParam():
|
||||
def foo(self):
|
||||
return
|
||||
|
||||
def check(instance):
|
||||
#< 13 (-5,8), (0,13)
|
||||
instance.foo()
|
||||
|
||||
check(DynamicParam())
|
||||
|
||||
# -----------------
|
||||
# Compiled Objects
|
||||
# -----------------
|
||||
|
||||
import _sre
|
||||
|
||||
#< 0 (-3,7), (0,0), ('_sre', None, None)
|
||||
_sre
|
||||
|
||||
# -----------------
|
||||
# on syntax
|
||||
# -----------------
|
||||
|
||||
#< 0
|
||||
import undefined
|
||||
130
vim-plugins/bundle/jedi-vim/jedi/test/conftest.py
Normal file
130
vim-plugins/bundle/jedi-vim/jedi/test/conftest.py
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
import os
|
||||
import re
|
||||
|
||||
import pytest
|
||||
|
||||
from . import helpers
|
||||
from . import run
|
||||
from . import refactor
|
||||
|
||||
import jedi
|
||||
from jedi.evaluate.analysis import Warning
|
||||
from jedi import settings
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
parser.addoption(
|
||||
"--integration-case-dir",
|
||||
default=os.path.join(helpers.test_dir, 'completion'),
|
||||
help="Directory in which integration test case files locate.")
|
||||
parser.addoption(
|
||||
"--refactor-case-dir",
|
||||
default=os.path.join(helpers.test_dir, 'refactor'),
|
||||
help="Directory in which refactoring test case files locate.")
|
||||
parser.addoption(
|
||||
"--test-files", "-T", default=[], action='append',
|
||||
help=(
|
||||
"Specify test files using FILE_NAME[:LINE[,LINE[,...]]]. "
|
||||
"For example: -T generators.py:10,13,19. "
|
||||
"Note that you can use -m to specify the test case by id."))
|
||||
parser.addoption(
|
||||
"--thirdparty", action='store_true',
|
||||
help="Include integration tests that requires third party modules.")
|
||||
|
||||
|
||||
def parse_test_files_option(opt):
|
||||
"""
|
||||
Parse option passed to --test-files into a key-value pair.
|
||||
|
||||
>>> parse_test_files_option('generators.py:10,13,19')
|
||||
('generators.py', [10, 13, 19])
|
||||
"""
|
||||
opt = str(opt)
|
||||
if ':' in opt:
|
||||
(f_name, rest) = opt.split(':', 1)
|
||||
return (f_name, list(map(int, rest.split(','))))
|
||||
else:
|
||||
return (opt, [])
|
||||
|
||||
|
||||
def pytest_generate_tests(metafunc):
|
||||
"""
|
||||
:type metafunc: _pytest.python.Metafunc
|
||||
"""
|
||||
test_files = dict(map(parse_test_files_option,
|
||||
metafunc.config.option.test_files))
|
||||
if 'case' in metafunc.fixturenames:
|
||||
base_dir = metafunc.config.option.integration_case_dir
|
||||
thirdparty = metafunc.config.option.thirdparty
|
||||
cases = list(run.collect_dir_tests(base_dir, test_files))
|
||||
if thirdparty:
|
||||
cases.extend(run.collect_dir_tests(
|
||||
os.path.join(base_dir, 'thirdparty'), test_files, True))
|
||||
ids = ["%s:%s" % (c.module_name, c.line_nr_test) for c in cases]
|
||||
metafunc.parametrize('case', cases, ids=ids)
|
||||
|
||||
if 'refactor_case' in metafunc.fixturenames:
|
||||
base_dir = metafunc.config.option.refactor_case_dir
|
||||
metafunc.parametrize(
|
||||
'refactor_case',
|
||||
refactor.collect_dir_tests(base_dir, test_files))
|
||||
|
||||
if 'static_analysis_case' in metafunc.fixturenames:
|
||||
base_dir = os.path.join(os.path.dirname(__file__), 'static_analysis')
|
||||
metafunc.parametrize(
|
||||
'static_analysis_case',
|
||||
collect_static_analysis_tests(base_dir, test_files))
|
||||
|
||||
|
||||
def collect_static_analysis_tests(base_dir, test_files):
|
||||
for f_name in os.listdir(base_dir):
|
||||
files_to_execute = [a for a in test_files.items() if a[0] in f_name]
|
||||
if f_name.endswith(".py") and (not test_files or files_to_execute):
|
||||
path = os.path.join(base_dir, f_name)
|
||||
yield StaticAnalysisCase(path)
|
||||
|
||||
|
||||
class StaticAnalysisCase(object):
|
||||
"""
|
||||
Static Analysis cases lie in the static_analysis folder.
|
||||
The tests also start with `#!`, like the goto_definition tests.
|
||||
"""
|
||||
def __init__(self, path):
|
||||
self._path = path
|
||||
with open(path) as f:
|
||||
self._source = f.read()
|
||||
|
||||
self.skip = False
|
||||
for line in self._source.splitlines():
|
||||
self.skip = self.skip or run.skip_python_version(line)
|
||||
|
||||
|
||||
def collect_comparison(self):
|
||||
cases = []
|
||||
for line_nr, line in enumerate(self._source.splitlines(), 1):
|
||||
match = re.match(r'(\s*)#! (\d+ )?(.*)$', line)
|
||||
if match is not None:
|
||||
column = int(match.group(2) or 0) + len(match.group(1))
|
||||
cases.append((line_nr + 1, column, match.group(3)))
|
||||
return cases
|
||||
|
||||
def run(self, compare_cb):
|
||||
analysis = jedi.Script(self._source, path=self._path)._analysis()
|
||||
typ_str = lambda inst: 'warning ' if isinstance(inst, Warning) else ''
|
||||
analysis = [(r.line, r.column, typ_str(r) + r.name)
|
||||
for r in analysis]
|
||||
compare_cb(self, analysis, self.collect_comparison())
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s: %s>" % (self.__class__.__name__, os.path.basename(self._path))
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def isolated_jedi_cache(monkeypatch, tmpdir):
|
||||
"""
|
||||
Set `jedi.settings.cache_directory` to a temporary directory during test.
|
||||
|
||||
Same as `clean_jedi_cache`, but create the temporary directory for
|
||||
each test case (scope='function').
|
||||
"""
|
||||
monkeypatch.setattr(settings, 'cache_directory', str(tmpdir))
|
||||
40
vim-plugins/bundle/jedi-vim/jedi/test/helpers.py
Normal file
40
vim-plugins/bundle/jedi-vim/jedi/test/helpers.py
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
"""
|
||||
A helper module for testing, improves compatibility for testing (as
|
||||
``jedi._compatibility``) as well as introducing helper functions.
|
||||
"""
|
||||
|
||||
import sys
|
||||
if sys.hexversion < 0x02070000:
|
||||
import unittest2 as unittest
|
||||
else:
|
||||
import unittest
|
||||
TestCase = unittest.TestCase
|
||||
|
||||
import os
|
||||
from os.path import abspath, dirname
|
||||
import functools
|
||||
|
||||
test_dir = dirname(abspath(__file__))
|
||||
root_dir = dirname(test_dir)
|
||||
|
||||
sample_int = 1 # This is used in completion/imports.py
|
||||
|
||||
def cwd_at(path):
|
||||
"""
|
||||
Decorator to run function at `path`.
|
||||
|
||||
:type path: str
|
||||
:arg path: relative path from repository root (e.g., ``'jedi'``).
|
||||
"""
|
||||
def decorator(func):
|
||||
@functools.wraps(func)
|
||||
def wrapper(*args, **kwds):
|
||||
try:
|
||||
oldcwd = os.getcwd()
|
||||
repo_root = os.path.dirname(test_dir)
|
||||
os.chdir(os.path.join(repo_root, path))
|
||||
return func(*args, **kwds)
|
||||
finally:
|
||||
os.chdir(oldcwd)
|
||||
return wrapper
|
||||
return decorator
|
||||
99
vim-plugins/bundle/jedi-vim/jedi/test/refactor.py
Executable file
99
vim-plugins/bundle/jedi-vim/jedi/test/refactor.py
Executable file
|
|
@ -0,0 +1,99 @@
|
|||
#!/usr/bin/env python
|
||||
"""
|
||||
Refactoring tests work a little bit similar to Black Box tests. But the idea is
|
||||
here to compare two versions of code. **Note: Refactoring is currently not in
|
||||
active development (and was never stable), the tests are therefore not really
|
||||
valuable - just ignore them.**
|
||||
"""
|
||||
from __future__ import with_statement
|
||||
import os
|
||||
import re
|
||||
|
||||
from functools import reduce
|
||||
import jedi
|
||||
from jedi import refactoring
|
||||
|
||||
|
||||
class RefactoringCase(object):
|
||||
|
||||
def __init__(self, name, source, line_nr, index, path,
|
||||
new_name, start_line_test, desired):
|
||||
self.name = name
|
||||
self.source = source
|
||||
self.line_nr = line_nr
|
||||
self.index = index
|
||||
self.path = path
|
||||
self.new_name = new_name
|
||||
self.start_line_test = start_line_test
|
||||
self.desired = desired
|
||||
|
||||
def refactor(self):
|
||||
script = jedi.Script(self.source, self.line_nr, self.index, self.path)
|
||||
f_name = os.path.basename(self.path)
|
||||
refactor_func = getattr(refactoring, f_name.replace('.py', ''))
|
||||
args = (self.new_name,) if self.new_name else ()
|
||||
return refactor_func(script, *args)
|
||||
|
||||
def run(self):
|
||||
refactor_object = self.refactor()
|
||||
|
||||
# try to get the right excerpt of the newfile
|
||||
f = refactor_object.new_files()[self.path]
|
||||
lines = f.splitlines()[self.start_line_test:]
|
||||
|
||||
end = self.start_line_test + len(lines)
|
||||
pop_start = None
|
||||
for i, l in enumerate(lines):
|
||||
if l.startswith('# +++'):
|
||||
end = i
|
||||
break
|
||||
elif '#? ' in l:
|
||||
pop_start = i
|
||||
lines.pop(pop_start)
|
||||
self.result = '\n'.join(lines[:end - 1]).strip()
|
||||
return self.result
|
||||
|
||||
def check(self):
|
||||
return self.run() == self.desired
|
||||
|
||||
def __repr__(self):
|
||||
return '<%s: %s:%s>' % (self.__class__.__name__,
|
||||
self.name, self.line_nr - 1)
|
||||
|
||||
|
||||
def collect_file_tests(source, path, lines_to_execute):
|
||||
r = r'^# --- ?([^\n]*)\n((?:(?!\n# \+\+\+).)*)' \
|
||||
r'\n# \+\+\+((?:(?!\n# ---).)*)'
|
||||
for match in re.finditer(r, source, re.DOTALL | re.MULTILINE):
|
||||
name = match.group(1).strip()
|
||||
first = match.group(2).strip()
|
||||
second = match.group(3).strip()
|
||||
start_line_test = source[:match.start()].count('\n') + 1
|
||||
|
||||
# get the line with the position of the operation
|
||||
p = re.match(r'((?:(?!#\?).)*)#\? (\d*) ?([^\n]*)', first, re.DOTALL)
|
||||
if p is None:
|
||||
print("Please add a test start.")
|
||||
continue
|
||||
until = p.group(1)
|
||||
index = int(p.group(2))
|
||||
new_name = p.group(3)
|
||||
|
||||
line_nr = start_line_test + until.count('\n') + 2
|
||||
if lines_to_execute and line_nr - 1 not in lines_to_execute:
|
||||
continue
|
||||
|
||||
yield RefactoringCase(name, source, line_nr, index, path,
|
||||
new_name, start_line_test, second)
|
||||
|
||||
|
||||
def collect_dir_tests(base_dir, test_files):
|
||||
for f_name in os.listdir(base_dir):
|
||||
files_to_execute = [a for a in test_files.items() if a[0] in f_name]
|
||||
lines_to_execute = reduce(lambda x, y: x + y[1], files_to_execute, [])
|
||||
if f_name.endswith(".py") and (not test_files or files_to_execute):
|
||||
path = os.path.join(base_dir, f_name)
|
||||
with open(path) as f:
|
||||
source = f.read()
|
||||
for case in collect_file_tests(source, path, lines_to_execute):
|
||||
yield case
|
||||
47
vim-plugins/bundle/jedi-vim/jedi/test/refactor/extract.py
Normal file
47
vim-plugins/bundle/jedi-vim/jedi/test/refactor/extract.py
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
# --- simple
|
||||
def test():
|
||||
#? 35 a
|
||||
return test(100, (30 + b, c) + 1)
|
||||
|
||||
# +++
|
||||
def test():
|
||||
a = (30 + b, c) + 1
|
||||
return test(100, a)
|
||||
|
||||
|
||||
# --- simple #2
|
||||
def test():
|
||||
#? 25 a
|
||||
return test(100, (30 + b, c) + 1)
|
||||
|
||||
# +++
|
||||
def test():
|
||||
a = 30 + b
|
||||
return test(100, (a, c) + 1)
|
||||
|
||||
|
||||
# --- multiline
|
||||
def test():
|
||||
#? 30 x
|
||||
return test(1, (30 + b, c)
|
||||
+ 1)
|
||||
# +++
|
||||
def test():
|
||||
x = ((30 + b, c)
|
||||
+ 1)
|
||||
return test(1, x
|
||||
)
|
||||
|
||||
|
||||
# --- multiline #2
|
||||
def test():
|
||||
#? 25 x
|
||||
return test(1, (30 + b, c)
|
||||
+ 1)
|
||||
# +++
|
||||
def test():
|
||||
x = 30 + b
|
||||
return test(1, (x, c)
|
||||
+ 1)
|
||||
|
||||
|
||||
18
vim-plugins/bundle/jedi-vim/jedi/test/refactor/inline.py
Normal file
18
vim-plugins/bundle/jedi-vim/jedi/test/refactor/inline.py
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# --- simple
|
||||
def test():
|
||||
#? 4
|
||||
a = (30 + b, c) + 1
|
||||
return test(100, a)
|
||||
# +++
|
||||
def test():
|
||||
return test(100, (30 + b, c) + 1)
|
||||
|
||||
|
||||
# --- simple
|
||||
if 1:
|
||||
#? 4
|
||||
a = 1, 2
|
||||
return test(100, a)
|
||||
# +++
|
||||
if 1:
|
||||
return test(100, (1, 2))
|
||||
17
vim-plugins/bundle/jedi-vim/jedi/test/refactor/rename.py
Normal file
17
vim-plugins/bundle/jedi-vim/jedi/test/refactor/rename.py
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
"""
|
||||
Test coverage for renaming is mostly being done by testing
|
||||
`Script.usages`.
|
||||
"""
|
||||
|
||||
# --- simple
|
||||
def test1():
|
||||
#? 7 blabla
|
||||
test1()
|
||||
AssertionError
|
||||
return test1, test1.not_existing
|
||||
# +++
|
||||
def blabla():
|
||||
blabla()
|
||||
AssertionError
|
||||
return blabla, blabla.not_existing
|
||||
|
||||
444
vim-plugins/bundle/jedi-vim/jedi/test/run.py
Executable file
444
vim-plugins/bundle/jedi-vim/jedi/test/run.py
Executable file
|
|
@ -0,0 +1,444 @@
|
|||
#!/usr/bin/env python
|
||||
"""
|
||||
|jedi| is mostly being tested by what I would call "Blackbox Tests". These
|
||||
tests are just testing the interface and do input/output testing. This makes a
|
||||
lot of sense for |jedi|. Jedi supports so many different code structures, that
|
||||
it is just stupid to write 200'000 unittests in the manner of
|
||||
``regression.py``. Also, it is impossible to do doctests/unittests on most of
|
||||
the internal data structures. That's why |jedi| uses mostly these kind of
|
||||
tests.
|
||||
|
||||
There are different kind of tests:
|
||||
|
||||
- completions / goto_definitions ``#?``
|
||||
- goto_assignments: ``#!``
|
||||
- usages: ``#<``
|
||||
|
||||
How to run tests?
|
||||
+++++++++++++++++
|
||||
|
||||
Jedi uses pytest_ to run unit and integration tests. To run tests,
|
||||
simply run ``py.test``. You can also use tox_ to run tests for
|
||||
multiple Python versions.
|
||||
|
||||
.. _pytest: http://pytest.org
|
||||
.. _tox: http://testrun.org/tox
|
||||
|
||||
Integration test cases are located in ``test/completion`` directory
|
||||
and each test case is indicated by either the comment ``#?`` (completions /
|
||||
definitions), ``#!`` (assignments), or ``#<`` (usages).
|
||||
There is also support for third party libraries. In a normal test run they are
|
||||
not being executed, you have to provide a ``--thirdparty`` option.
|
||||
|
||||
In addition to standard `-k` and `-m` options in py.test, you can use
|
||||
`-T` (`--test-files`) option to specify integration test cases to run.
|
||||
It takes the format of ``FILE_NAME[:LINE[,LINE[,...]]]`` where
|
||||
``FILE_NAME`` is a file in ``test/completion`` and ``LINE`` is a line
|
||||
number of the test comment. Here is some recipes:
|
||||
|
||||
Run tests only in ``basic.py`` and ``imports.py``::
|
||||
|
||||
py.test test/test_integration.py -T basic.py -T imports.py
|
||||
|
||||
Run test at line 4, 6, and 8 in ``basic.py``::
|
||||
|
||||
py.test test/test_integration.py -T basic.py:4,6,8
|
||||
|
||||
See ``py.test --help`` for more information.
|
||||
|
||||
If you want to debug a test, just use the ``--pdb`` option.
|
||||
|
||||
Alternate Test Runner
|
||||
+++++++++++++++++++++
|
||||
|
||||
If you don't like the output of ``py.test``, there's an alternate test runner
|
||||
that you can start by running ``./run.py``. The above example could be run by::
|
||||
|
||||
./run.py basic 4 6 8 50-80
|
||||
|
||||
The advantage of this runner is simplicity and more customized error reports.
|
||||
Using both runners will help you to have a quicker overview of what's
|
||||
happening.
|
||||
|
||||
|
||||
Auto-Completion
|
||||
+++++++++++++++
|
||||
|
||||
Uses comments to specify a test in the next line. The comment says which
|
||||
results are expected. The comment always begins with `#?`. The last row
|
||||
symbolizes the cursor.
|
||||
|
||||
For example::
|
||||
|
||||
#? ['real']
|
||||
a = 3; a.rea
|
||||
|
||||
Because it follows ``a.rea`` and a is an ``int``, which has a ``real``
|
||||
property.
|
||||
|
||||
Goto Definitions
|
||||
++++++++++++++++
|
||||
|
||||
Definition tests use the same symbols like completion tests. This is
|
||||
possible because the completion tests are defined with a list::
|
||||
|
||||
#? int()
|
||||
ab = 3; ab
|
||||
|
||||
Goto Assignments
|
||||
++++++++++++++++
|
||||
|
||||
Tests look like this::
|
||||
|
||||
abc = 1
|
||||
#! ['abc=1']
|
||||
abc
|
||||
|
||||
Additionally it is possible to specify the column by adding a number, which
|
||||
describes the position of the test (otherwise it's just the end of line)::
|
||||
|
||||
#! 2 ['abc=1']
|
||||
abc
|
||||
|
||||
Usages
|
||||
++++++
|
||||
|
||||
Tests look like this::
|
||||
|
||||
abc = 1
|
||||
#< abc@1,0 abc@3,0
|
||||
abc
|
||||
"""
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import operator
|
||||
from ast import literal_eval
|
||||
from io import StringIO
|
||||
from functools import reduce
|
||||
|
||||
import jedi
|
||||
from jedi._compatibility import unicode, is_py3
|
||||
from jedi.parser import Parser, load_grammar
|
||||
from jedi.api.classes import Definition
|
||||
|
||||
|
||||
TEST_COMPLETIONS = 0
|
||||
TEST_DEFINITIONS = 1
|
||||
TEST_ASSIGNMENTS = 2
|
||||
TEST_USAGES = 3
|
||||
|
||||
|
||||
class IntegrationTestCase(object):
|
||||
def __init__(self, test_type, correct, line_nr, column, start, line,
|
||||
path=None, skip=None):
|
||||
self.test_type = test_type
|
||||
self.correct = correct
|
||||
self.line_nr = line_nr
|
||||
self.column = column
|
||||
self.start = start
|
||||
self.line = line
|
||||
self.path = path
|
||||
self.skip = skip
|
||||
|
||||
@property
|
||||
def module_name(self):
|
||||
return os.path.splitext(os.path.basename(self.path))[0]
|
||||
|
||||
@property
|
||||
def line_nr_test(self):
|
||||
"""The test is always defined on the line before."""
|
||||
return self.line_nr - 1
|
||||
|
||||
def __repr__(self):
|
||||
return '<%s: %s:%s:%s>' % (self.__class__.__name__, self.module_name,
|
||||
self.line_nr_test, self.line.rstrip())
|
||||
|
||||
def script(self):
|
||||
return jedi.Script(self.source, self.line_nr, self.column, self.path)
|
||||
|
||||
def run(self, compare_cb):
|
||||
testers = {
|
||||
TEST_COMPLETIONS: self.run_completion,
|
||||
TEST_DEFINITIONS: self.run_goto_definitions,
|
||||
TEST_ASSIGNMENTS: self.run_goto_assignments,
|
||||
TEST_USAGES: self.run_usages,
|
||||
}
|
||||
return testers[self.test_type](compare_cb)
|
||||
|
||||
def run_completion(self, compare_cb):
|
||||
completions = self.script().completions()
|
||||
#import cProfile; cProfile.run('script.completions()')
|
||||
|
||||
comp_str = set([c.name for c in completions])
|
||||
return compare_cb(self, comp_str, set(literal_eval(self.correct)))
|
||||
|
||||
def run_goto_definitions(self, compare_cb):
|
||||
script = self.script()
|
||||
evaluator = script._evaluator
|
||||
|
||||
def comparison(definition):
|
||||
suffix = '()' if definition.type == 'instance' else ''
|
||||
return definition.desc_with_module + suffix
|
||||
|
||||
def definition(correct, correct_start, path):
|
||||
should_be = set()
|
||||
for match in re.finditer('(?:[^ ]+)', correct):
|
||||
string = match.group(0)
|
||||
parser = Parser(load_grammar(), string, start_symbol='eval_input')
|
||||
parser.position_modifier.line = self.line_nr
|
||||
element = parser.get_parsed_node()
|
||||
element.parent = jedi.api.completion.get_user_scope(
|
||||
script._get_module(),
|
||||
(self.line_nr, self.column)
|
||||
)
|
||||
results = evaluator.eval_element(element)
|
||||
if not results:
|
||||
raise Exception('Could not resolve %s on line %s'
|
||||
% (match.string, self.line_nr - 1))
|
||||
|
||||
should_be |= set(Definition(evaluator, r) for r in results)
|
||||
|
||||
# Because the objects have different ids, `repr`, then compare.
|
||||
should = set(comparison(r) for r in should_be)
|
||||
return should
|
||||
|
||||
should = definition(self.correct, self.start, script.path)
|
||||
result = script.goto_definitions()
|
||||
is_str = set(comparison(r) for r in result)
|
||||
return compare_cb(self, is_str, should)
|
||||
|
||||
def run_goto_assignments(self, compare_cb):
|
||||
result = self.script().goto_assignments()
|
||||
comp_str = str(sorted(str(r.description) for r in result))
|
||||
return compare_cb(self, comp_str, self.correct)
|
||||
|
||||
def run_usages(self, compare_cb):
|
||||
result = self.script().usages()
|
||||
self.correct = self.correct.strip()
|
||||
compare = sorted((r.module_name, r.line, r.column) for r in result)
|
||||
wanted = []
|
||||
if not self.correct:
|
||||
positions = []
|
||||
else:
|
||||
positions = literal_eval(self.correct)
|
||||
for pos_tup in positions:
|
||||
if type(pos_tup[0]) == str:
|
||||
# this means that there is a module specified
|
||||
wanted.append(pos_tup)
|
||||
else:
|
||||
line = pos_tup[0]
|
||||
if pos_tup[0] is not None:
|
||||
line += self.line_nr
|
||||
wanted.append((self.module_name, line, pos_tup[1]))
|
||||
|
||||
return compare_cb(self, compare, sorted(wanted))
|
||||
|
||||
|
||||
def skip_python_version(line):
|
||||
comp_map = {
|
||||
'==': 'eq',
|
||||
'<=': 'le',
|
||||
'>=': 'ge',
|
||||
'<': 'lt',
|
||||
'>': 'gt',
|
||||
}
|
||||
# check for python minimal version number
|
||||
match = re.match(r" *# *python *([<>]=?|==) *(\d+(?:\.\d+)?)$", line)
|
||||
if match:
|
||||
minimal_python_version = tuple(
|
||||
map(int, match.group(2).split(".")))
|
||||
operation = getattr(operator, comp_map[match.group(1)])
|
||||
if not operation(sys.version_info, minimal_python_version):
|
||||
return "Minimal python version %s %s" % (match.group(1), match.group(2))
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def collect_file_tests(path, lines, lines_to_execute):
|
||||
def makecase(t):
|
||||
return IntegrationTestCase(t, correct, line_nr, column,
|
||||
start, line, path=path, skip=skip)
|
||||
|
||||
start = None
|
||||
correct = None
|
||||
test_type = None
|
||||
skip = None
|
||||
for line_nr, line in enumerate(lines, 1):
|
||||
if correct is not None:
|
||||
r = re.match('^(\d+)\s*(.*)$', correct)
|
||||
if r:
|
||||
column = int(r.group(1))
|
||||
correct = r.group(2)
|
||||
start += r.regs[2][0] # second group, start index
|
||||
else:
|
||||
column = len(line) - 1 # -1 for the \n
|
||||
if test_type == '!':
|
||||
yield makecase(TEST_ASSIGNMENTS)
|
||||
elif test_type == '<':
|
||||
yield makecase(TEST_USAGES)
|
||||
elif correct.startswith('['):
|
||||
yield makecase(TEST_COMPLETIONS)
|
||||
else:
|
||||
yield makecase(TEST_DEFINITIONS)
|
||||
correct = None
|
||||
else:
|
||||
skip = skip or skip_python_version(line)
|
||||
try:
|
||||
r = re.search(r'(?:^|(?<=\s))#([?!<])\s*([^\n]*)', line)
|
||||
# test_type is ? for completion and ! for goto_assignments
|
||||
test_type = r.group(1)
|
||||
correct = r.group(2)
|
||||
# Quick hack to make everything work (not quite a bloody unicorn hack though).
|
||||
if correct == '':
|
||||
correct = ' '
|
||||
start = r.start()
|
||||
except AttributeError:
|
||||
correct = None
|
||||
else:
|
||||
# Skip the test, if this is not specified test.
|
||||
for l in lines_to_execute:
|
||||
if isinstance(l, tuple) and l[0] <= line_nr <= l[1] \
|
||||
or line_nr == l:
|
||||
break
|
||||
else:
|
||||
if lines_to_execute:
|
||||
correct = None
|
||||
|
||||
|
||||
def collect_dir_tests(base_dir, test_files, check_thirdparty=False):
|
||||
for f_name in os.listdir(base_dir):
|
||||
files_to_execute = [a for a in test_files.items() if f_name.startswith(a[0])]
|
||||
lines_to_execute = reduce(lambda x, y: x + y[1], files_to_execute, [])
|
||||
if f_name.endswith(".py") and (not test_files or files_to_execute):
|
||||
skip = None
|
||||
if check_thirdparty:
|
||||
lib = f_name.replace('_.py', '')
|
||||
try:
|
||||
# there is always an underline at the end.
|
||||
# It looks like: completion/thirdparty/pylab_.py
|
||||
__import__(lib)
|
||||
except ImportError:
|
||||
skip = 'Thirdparty-Library %s not found.' % lib
|
||||
|
||||
path = os.path.join(base_dir, f_name)
|
||||
|
||||
if is_py3:
|
||||
source = open(path, encoding='utf-8').read()
|
||||
else:
|
||||
source = unicode(open(path).read(), 'UTF-8')
|
||||
|
||||
for case in collect_file_tests(path, StringIO(source),
|
||||
lines_to_execute):
|
||||
case.source = source
|
||||
if skip:
|
||||
case.skip = skip
|
||||
yield case
|
||||
|
||||
|
||||
docoptstr = """
|
||||
Using run.py to make debugging easier with integration tests.
|
||||
|
||||
An alternative testing format, which is much more hacky, but very nice to
|
||||
work with.
|
||||
|
||||
Usage:
|
||||
run.py [--pdb] [--debug] [--thirdparty] [<rest>...]
|
||||
run.py --help
|
||||
|
||||
Options:
|
||||
-h --help Show this screen.
|
||||
--pdb Enable pdb debugging on fail.
|
||||
-d, --debug Enable text output debugging (please install ``colorama``).
|
||||
--thirdparty Also run thirdparty tests (in ``completion/thirdparty``).
|
||||
"""
|
||||
if __name__ == '__main__':
|
||||
import docopt
|
||||
arguments = docopt.docopt(docoptstr)
|
||||
|
||||
import time
|
||||
t_start = time.time()
|
||||
# Sorry I didn't use argparse here. It's because argparse is not in the
|
||||
# stdlib in 2.5.
|
||||
import sys
|
||||
|
||||
if arguments['--debug']:
|
||||
jedi.set_debug_function()
|
||||
|
||||
# get test list, that should be executed
|
||||
test_files = {}
|
||||
last = None
|
||||
for arg in arguments['<rest>']:
|
||||
match = re.match('(\d+)-(\d+)', arg)
|
||||
if match:
|
||||
start, end = match.groups()
|
||||
test_files[last].append((int(start), int(end)))
|
||||
elif arg.isdigit():
|
||||
if last is None:
|
||||
continue
|
||||
test_files[last].append(int(arg))
|
||||
else:
|
||||
test_files[arg] = []
|
||||
last = arg
|
||||
|
||||
# completion tests:
|
||||
dir_ = os.path.dirname(os.path.realpath(__file__))
|
||||
completion_test_dir = os.path.join(dir_, '../test/completion')
|
||||
completion_test_dir = os.path.abspath(completion_test_dir)
|
||||
summary = []
|
||||
tests_fail = 0
|
||||
|
||||
# execute tests
|
||||
cases = list(collect_dir_tests(completion_test_dir, test_files))
|
||||
if test_files or arguments['--thirdparty']:
|
||||
completion_test_dir += '/thirdparty'
|
||||
cases += collect_dir_tests(completion_test_dir, test_files, True)
|
||||
|
||||
def file_change(current, tests, fails):
|
||||
if current is not None:
|
||||
current = os.path.basename(current)
|
||||
print('%s \t\t %s tests and %s fails.' % (current, tests, fails))
|
||||
|
||||
def report(case, actual, desired):
|
||||
if actual == desired:
|
||||
return 0
|
||||
else:
|
||||
print("\ttest fail @%d, actual = %s, desired = %s"
|
||||
% (case.line_nr - 1, actual, desired))
|
||||
return 1
|
||||
|
||||
import traceback
|
||||
current = cases[0].path if cases else None
|
||||
count = fails = 0
|
||||
for c in cases:
|
||||
if c.skip:
|
||||
continue
|
||||
if current != c.path:
|
||||
file_change(current, count, fails)
|
||||
current = c.path
|
||||
count = fails = 0
|
||||
|
||||
try:
|
||||
if c.run(report):
|
||||
tests_fail += 1
|
||||
fails += 1
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
print("\ttest fail @%d" % (c.line_nr - 1))
|
||||
tests_fail += 1
|
||||
fails += 1
|
||||
if arguments['--pdb']:
|
||||
import pdb
|
||||
pdb.post_mortem()
|
||||
|
||||
count += 1
|
||||
|
||||
file_change(current, count, fails)
|
||||
|
||||
print('\nSummary: (%s fails of %s tests) in %.3fs'
|
||||
% (tests_fail, len(cases), time.time() - t_start))
|
||||
for s in summary:
|
||||
print(s)
|
||||
|
||||
exit_code = 1 if tests_fail else 0
|
||||
sys.exit(exit_code)
|
||||
37
vim-plugins/bundle/jedi-vim/jedi/test/speed/precedence.py
Normal file
37
vim-plugins/bundle/jedi-vim/jedi/test/speed/precedence.py
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
def marks(code):
|
||||
if '.' in code:
|
||||
another(code[:code.index(',') - 1] + '!')
|
||||
else:
|
||||
another(code + '.')
|
||||
|
||||
|
||||
def another(code2):
|
||||
call(numbers(code2 + 'haha'))
|
||||
|
||||
marks('start1 ')
|
||||
marks('start2 ')
|
||||
|
||||
|
||||
def alphabet(code4):
|
||||
if 1:
|
||||
if 2:
|
||||
return code4 + 'a'
|
||||
else:
|
||||
return code4 + 'b'
|
||||
else:
|
||||
if 2:
|
||||
return code4 + 'c'
|
||||
else:
|
||||
return code4 + 'd'
|
||||
|
||||
|
||||
def numbers(code5):
|
||||
if 2:
|
||||
return alphabet(code5 + '1')
|
||||
else:
|
||||
return alphabet(code5 + '2')
|
||||
|
||||
|
||||
def call(code3):
|
||||
code3 = numbers(numbers('end')) + numbers(code3)
|
||||
code3.partition
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
# -----------------
|
||||
# normal arguments (no keywords)
|
||||
# -----------------
|
||||
|
||||
|
||||
def simple(a):
|
||||
return a
|
||||
|
||||
simple(1)
|
||||
#! 6 type-error-too-few-arguments
|
||||
simple()
|
||||
#! 10 type-error-too-many-arguments
|
||||
simple(1, 2)
|
||||
|
||||
|
||||
#! 10 type-error-too-many-arguments
|
||||
simple(1, 2, 3)
|
||||
|
||||
# -----------------
|
||||
# keyword arguments
|
||||
# -----------------
|
||||
|
||||
simple(a=1)
|
||||
#! 7 type-error-keyword-argument
|
||||
simple(b=1)
|
||||
#! 10 type-error-too-many-arguments
|
||||
simple(1, a=1)
|
||||
|
||||
|
||||
def two_params(x, y):
|
||||
return y
|
||||
|
||||
|
||||
two_params(y=2, x=1)
|
||||
two_params(1, y=2)
|
||||
|
||||
#! 11 type-error-multiple-values
|
||||
two_params(1, x=2)
|
||||
#! 17 type-error-too-many-arguments
|
||||
two_params(1, 2, y=3)
|
||||
|
||||
# -----------------
|
||||
# default arguments
|
||||
# -----------------
|
||||
|
||||
def default(x, y=1, z=2):
|
||||
return x
|
||||
|
||||
#! 7 type-error-too-few-arguments
|
||||
default()
|
||||
default(1)
|
||||
default(1, 2)
|
||||
default(1, 2, 3)
|
||||
#! 17 type-error-too-many-arguments
|
||||
default(1, 2, 3, 4)
|
||||
|
||||
default(x=1)
|
||||
|
||||
# -----------------
|
||||
# class arguments
|
||||
# -----------------
|
||||
|
||||
class Instance():
|
||||
def __init__(self, foo):
|
||||
self.foo = foo
|
||||
|
||||
Instance(1).foo
|
||||
Instance(foo=1).foo
|
||||
|
||||
#! 12 type-error-too-many-arguments
|
||||
Instance(1, 2).foo
|
||||
#! 8 type-error-too-few-arguments
|
||||
Instance().foo
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
class Cls():
|
||||
class_attr = ''
|
||||
def __init__(self, input):
|
||||
self.instance_attr = 3
|
||||
self.input = input
|
||||
|
||||
def f(self):
|
||||
#! 12 attribute-error
|
||||
return self.not_existing
|
||||
|
||||
def undefined_object(self, obj):
|
||||
"""
|
||||
Uses an arbitrary object and performs an operation on it, shouldn't
|
||||
be a problem.
|
||||
"""
|
||||
obj.arbitrary_lookup
|
||||
|
||||
def defined_lookup(self, obj):
|
||||
"""
|
||||
`obj` is defined by a call into this function.
|
||||
"""
|
||||
obj.upper
|
||||
#! 4 attribute-error
|
||||
obj.arbitrary_lookup
|
||||
|
||||
#! 13 name-error
|
||||
class_attr = a
|
||||
|
||||
Cls(1).defined_lookup('')
|
||||
|
||||
c = Cls(1)
|
||||
c.class_attr
|
||||
Cls.class_attr
|
||||
#! 4 attribute-error
|
||||
Cls.class_attr_error
|
||||
c.instance_attr
|
||||
#! 2 attribute-error
|
||||
c.instance_attr_error
|
||||
|
||||
|
||||
c.something = None
|
||||
|
||||
#! 12 name-error
|
||||
something = a
|
||||
something
|
||||
|
||||
# -----------------
|
||||
# Unused array variables should still raise attribute errors.
|
||||
# -----------------
|
||||
|
||||
# should not raise anything.
|
||||
for loop_variable in [1, 2]:
|
||||
#! 4 name-error
|
||||
x = undefined
|
||||
loop_variable
|
||||
|
||||
#! 28 name-error
|
||||
for loop_variable in [1, 2, undefined]:
|
||||
pass
|
||||
|
||||
#! 7 attribute-error
|
||||
[1, ''.undefined_attr]
|
||||
|
||||
|
||||
def return_one(something):
|
||||
return 1
|
||||
|
||||
#! 14 attribute-error
|
||||
return_one(''.undefined_attribute)
|
||||
|
||||
#! 12 name-error
|
||||
[r for r in undefined]
|
||||
|
||||
#! 1 name-error
|
||||
[undefined for r in [1, 2]]
|
||||
|
||||
[r for r in [1, 2]]
|
||||
|
||||
# some random error that showed up
|
||||
class NotCalled():
|
||||
def match_something(self, param):
|
||||
seems_to_need_an_assignment = param
|
||||
return [value.match_something() for value in []]
|
||||
|
||||
# -----------------
|
||||
# decorators
|
||||
# -----------------
|
||||
|
||||
#! 1 name-error
|
||||
@undefined_decorator
|
||||
def func():
|
||||
return 1
|
||||
|
||||
# -----------------
|
||||
# operators
|
||||
# -----------------
|
||||
|
||||
string = '%s %s' % (1, 2)
|
||||
|
||||
# Shouldn't raise an error, because `string` is really just a string, not an
|
||||
# array or something.
|
||||
string.upper
|
||||
|
||||
# -----------------
|
||||
# imports
|
||||
# -----------------
|
||||
|
||||
# Star imports and the like in modules should not cause attribute errors in
|
||||
# this module.
|
||||
import import_tree
|
||||
|
||||
import_tree.a
|
||||
import_tree.b
|
||||
|
||||
# This is something that raised an error, because it was using a complex
|
||||
# mixture of Jedi fakes and compiled objects.
|
||||
import _sre
|
||||
#! 15 attribute-error
|
||||
_sre.compile().not_existing
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
"""
|
||||
Jedi issues warnings for possible errors if ``__getattr__``,
|
||||
``__getattribute__`` or ``setattr`` are used.
|
||||
"""
|
||||
|
||||
# -----------------
|
||||
# __getattr*__
|
||||
# -----------------
|
||||
|
||||
|
||||
class Cls():
|
||||
def __getattr__(self, name):
|
||||
return getattr(str, name)
|
||||
|
||||
|
||||
Cls().upper
|
||||
|
||||
#! 6 warning attribute-error
|
||||
Cls().undefined
|
||||
|
||||
|
||||
class Inherited(Cls):
|
||||
pass
|
||||
|
||||
Inherited().upper
|
||||
|
||||
#! 12 warning attribute-error
|
||||
Inherited().undefined
|
||||
|
||||
# -----------------
|
||||
# setattr
|
||||
# -----------------
|
||||
|
||||
|
||||
class SetattrCls():
|
||||
def __init__(self, dct):
|
||||
# Jedi doesn't even try to understand such code
|
||||
for k, v in dct.items():
|
||||
setattr(self, k, v)
|
||||
|
||||
self.defined = 3
|
||||
|
||||
c = SetattrCls({'a': 'b'})
|
||||
c.defined
|
||||
#! 2 warning attribute-error
|
||||
c.undefined
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
# -----------------
|
||||
# Simple tests
|
||||
# -----------------
|
||||
|
||||
import random
|
||||
|
||||
if random.choice([0, 1]):
|
||||
x = ''
|
||||
else:
|
||||
x = 1
|
||||
if random.choice([0, 1]):
|
||||
y = ''
|
||||
else:
|
||||
y = 1
|
||||
|
||||
# A simple test
|
||||
if x != 1:
|
||||
x.upper()
|
||||
else:
|
||||
#! 2 attribute-error
|
||||
x.upper()
|
||||
pass
|
||||
|
||||
# This operation is wrong, because the types could be different.
|
||||
#! 6 type-error-operation
|
||||
z = x + y
|
||||
# However, here we have correct types.
|
||||
if x == y:
|
||||
z = x + y
|
||||
else:
|
||||
#! 6 type-error-operation
|
||||
z = x + y
|
||||
|
||||
# -----------------
|
||||
# With a function
|
||||
# -----------------
|
||||
|
||||
def addition(a, b):
|
||||
if type(a) == type(b):
|
||||
return a + b
|
||||
else:
|
||||
#! 9 type-error-operation
|
||||
return a + b
|
||||
|
||||
addition(1, 1)
|
||||
addition(1.0, '')
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
# ----------
|
||||
# isinstance
|
||||
# ----------
|
||||
|
||||
isinstance(1, int)
|
||||
isinstance(1, (int, str))
|
||||
|
||||
#! 14 type-error-isinstance
|
||||
isinstance(1, 1)
|
||||
#! 14 type-error-isinstance
|
||||
isinstance(1, [int, str])
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
class Base(object):
|
||||
class Nested():
|
||||
def foo():
|
||||
pass
|
||||
|
||||
|
||||
class X(Base.Nested):
|
||||
pass
|
||||
|
||||
|
||||
X().foo()
|
||||
#! 4 attribute-error
|
||||
X().bar()
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
[a + 1 for a in [1, 2]]
|
||||
|
||||
#! 3 type-error-operation
|
||||
[a + '' for a in [1, 2]]
|
||||
#! 3 type-error-operation
|
||||
(a + '' for a in [1, 2])
|
||||
|
||||
#! 12 type-error-not-iterable
|
||||
[a for a in 1]
|
||||
|
||||
tuple(str(a) for a in [1])
|
||||
|
||||
#! 8 type-error-operation
|
||||
tuple(a + 3 for a in [''])
|
||||
|
||||
# ----------
|
||||
# Some variables within are not defined
|
||||
# ----------
|
||||
|
||||
#! 12 name-error
|
||||
[1 for a in NOT_DEFINFED for b in a if 1]
|
||||
|
||||
#! 25 name-error
|
||||
[1 for a in [1] for b in NOT_DEFINED if 1]
|
||||
|
||||
#! 12 name-error
|
||||
[1 for a in NOT_DEFINFED for b in [1] if 1]
|
||||
|
||||
#! 19 name-error
|
||||
(1 for a in [1] if NOT_DEFINED)
|
||||
|
||||
# ----------
|
||||
# unbalanced sides.
|
||||
# ----------
|
||||
|
||||
# ok
|
||||
(1 for a, b in [(1, 2)])
|
||||
#! 13 value-error-too-few-values
|
||||
(1 for a, b, c in [(1, 2)])
|
||||
#! 10 value-error-too-many-values
|
||||
(1 for a, b in [(1, 2, 3)])
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# classmethod
|
||||
class TarFile():
|
||||
@classmethod
|
||||
def open(cls, name, **kwargs):
|
||||
return cls.taropen(name, **kwargs)
|
||||
|
||||
@classmethod
|
||||
def taropen(cls, name, **kwargs):
|
||||
return name
|
||||
|
||||
|
||||
# should just work
|
||||
TarFile.open('hallo')
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
def generator():
|
||||
yield 1
|
||||
|
||||
#! 11 type-error-not-subscriptable
|
||||
generator()[0]
|
||||
|
||||
list(generator())[0]
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
"""
|
||||
Another import tree, this time not for completion, but static analysis.
|
||||
"""
|
||||
|
||||
from .a import *
|
||||
|
|
@ -0,0 +1 @@
|
|||
from . import b
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
#! 7 import-error
|
||||
import not_existing
|
||||
|
||||
import os
|
||||
|
||||
from os.path import abspath
|
||||
#! 20 import-error
|
||||
from os.path import not_existing
|
||||
|
||||
from datetime import date
|
||||
date.today
|
||||
|
||||
#! 5 attribute-error
|
||||
date.not_existing_attribute
|
||||
|
||||
#! 14 import-error
|
||||
from datetime.date import today
|
||||
|
||||
#! 16 import-error
|
||||
import datetime.date
|
||||
#! 7 import-error
|
||||
import not_existing_nested.date
|
||||
|
||||
import os.path
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
a, b = {'asdf': 3, 'b': 'str'}
|
||||
a
|
||||
|
||||
x = [1]
|
||||
x[0], b = {'a': 1, 'b': '2'}
|
||||
|
||||
dct = {3: ''}
|
||||
for x in dct:
|
||||
pass
|
||||
|
||||
#! 4 type-error-not-iterable
|
||||
for x, y in dct:
|
||||
pass
|
||||
|
||||
# Shouldn't cause issues, because if there are no types (or we don't know what
|
||||
# the types are, we should just ignore it.
|
||||
#! 0 value-error-too-few-values
|
||||
a, b = []
|
||||
#! 7 name-error
|
||||
a, b = NOT_DEFINED
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
def raises():
|
||||
raise KeyError()
|
||||
|
||||
|
||||
def wrong_name():
|
||||
#! 6 name-error
|
||||
raise NotExistingException()
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
-1 + 1
|
||||
1 + 1.0
|
||||
#! 2 type-error-operation
|
||||
1 + '1'
|
||||
#! 2 type-error-operation
|
||||
1 - '1'
|
||||
|
||||
-1 - - 1
|
||||
-1 - int()
|
||||
int() - float()
|
||||
float() - 3.0
|
||||
|
||||
a = 3
|
||||
b = ''
|
||||
#! 2 type-error-operation
|
||||
a + b
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
"""
|
||||
Some special cases of Python 2.
|
||||
"""
|
||||
# python <= 2.7
|
||||
|
||||
# print is syntax:
|
||||
print 1
|
||||
print(1)
|
||||
|
||||
#! 6 name-error
|
||||
print NOT_DEFINED
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
# -----------------
|
||||
# *args
|
||||
# -----------------
|
||||
|
||||
|
||||
def simple(a):
|
||||
return a
|
||||
|
||||
|
||||
def nested(*args):
|
||||
return simple(*args)
|
||||
|
||||
nested(1)
|
||||
#! 6 type-error-too-few-arguments
|
||||
nested()
|
||||
|
||||
|
||||
def nested_no_call_to_function(*args):
|
||||
return simple(1, *args)
|
||||
|
||||
|
||||
def simple2(a, b, c):
|
||||
return b
|
||||
def nested(*args):
|
||||
return simple2(1, *args)
|
||||
def nested_twice(*args1):
|
||||
return nested(*args1)
|
||||
|
||||
nested_twice(2, 3)
|
||||
#! 13 type-error-too-few-arguments
|
||||
nested_twice(2)
|
||||
#! 19 type-error-too-many-arguments
|
||||
nested_twice(2, 3, 4)
|
||||
|
||||
|
||||
# A named argument can be located before *args.
|
||||
def star_args_with_named(*args):
|
||||
return simple2(c='', *args)
|
||||
|
||||
star_args_with_named(1, 2)
|
||||
# -----------------
|
||||
# **kwargs
|
||||
# -----------------
|
||||
|
||||
|
||||
def kwargs_test(**kwargs):
|
||||
return simple2(1, **kwargs)
|
||||
|
||||
kwargs_test(c=3, b=2)
|
||||
#! 12 type-error-too-few-arguments
|
||||
kwargs_test(c=3)
|
||||
#! 12 type-error-too-few-arguments
|
||||
kwargs_test(b=2)
|
||||
#! 22 type-error-keyword-argument
|
||||
kwargs_test(b=2, c=3, d=4)
|
||||
#! 12 type-error-multiple-values
|
||||
kwargs_test(b=2, c=3, a=4)
|
||||
|
||||
|
||||
def kwargs_nested(**kwargs):
|
||||
return kwargs_test(b=2, **kwargs)
|
||||
|
||||
kwargs_nested(c=3)
|
||||
#! 13 type-error-too-few-arguments
|
||||
kwargs_nested()
|
||||
#! 19 type-error-keyword-argument
|
||||
kwargs_nested(c=2, d=4)
|
||||
#! 14 type-error-multiple-values
|
||||
kwargs_nested(c=2, a=4)
|
||||
# TODO reenable
|
||||
##! 14 type-error-multiple-values
|
||||
#kwargs_nested(b=3, c=2)
|
||||
|
||||
# -----------------
|
||||
# mixed *args/**kwargs
|
||||
# -----------------
|
||||
|
||||
def simple_mixed(a, b, c):
|
||||
return b
|
||||
|
||||
def mixed(*args, **kwargs):
|
||||
return simple_mixed(1, *args, **kwargs)
|
||||
|
||||
mixed(1, 2)
|
||||
mixed(1, c=2)
|
||||
mixed(b=2, c=3)
|
||||
mixed(c=4, b='')
|
||||
|
||||
# need separate functions, otherwise these might swallow the errors
|
||||
def mixed2(*args, **kwargs):
|
||||
return simple_mixed(1, *args, **kwargs)
|
||||
|
||||
|
||||
#! 7 type-error-too-few-arguments
|
||||
mixed2(c=2)
|
||||
#! 7 type-error-too-few-arguments
|
||||
mixed2(3)
|
||||
#! 13 type-error-too-many-arguments
|
||||
mixed2(3, 4, 5)
|
||||
# TODO reenable
|
||||
##! 13 type-error-too-many-arguments
|
||||
#mixed2(3, 4, c=5)
|
||||
#! 7 type-error-multiple-values
|
||||
mixed2(3, b=5)
|
||||
|
||||
# -----------------
|
||||
# plain wrong arguments
|
||||
# -----------------
|
||||
|
||||
#! 12 type-error-star-star
|
||||
simple(1, **[])
|
||||
#! 12 type-error-star-star
|
||||
simple(1, **1)
|
||||
class A(): pass
|
||||
#! 12 type-error-star-star
|
||||
simple(1, **A())
|
||||
|
||||
#! 11 type-error-star
|
||||
simple(1, *1)
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
try:
|
||||
#! 4 attribute-error
|
||||
str.not_existing
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
try:
|
||||
str.not_existing
|
||||
except AttributeError:
|
||||
#! 4 attribute-error
|
||||
str.not_existing
|
||||
pass
|
||||
|
||||
try:
|
||||
import not_existing_import
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
#! 7 import-error
|
||||
import not_existing_import
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
# -----------------
|
||||
# multi except
|
||||
# -----------------
|
||||
try:
|
||||
str.not_existing
|
||||
except (TypeError, AttributeError): pass
|
||||
|
||||
try:
|
||||
str.not_existing
|
||||
except ImportError:
|
||||
pass
|
||||
except (NotImplementedError, AttributeError): pass
|
||||
|
||||
try:
|
||||
#! 4 attribute-error
|
||||
str.not_existing
|
||||
except (TypeError, NotImplementedError): pass
|
||||
|
||||
# -----------------
|
||||
# detailed except
|
||||
# -----------------
|
||||
try:
|
||||
str.not_existing
|
||||
except ((AttributeError)): pass
|
||||
try:
|
||||
#! 4 attribute-error
|
||||
str.not_existing
|
||||
except [AttributeError]: pass
|
||||
|
||||
# Should be able to detect errors in except statement as well.
|
||||
try:
|
||||
pass
|
||||
#! 7 name-error
|
||||
except Undefined:
|
||||
pass
|
||||
|
||||
# -----------------
|
||||
# inheritance
|
||||
# -----------------
|
||||
|
||||
try:
|
||||
undefined
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# should catch everything
|
||||
try:
|
||||
undefined
|
||||
except:
|
||||
pass
|
||||
|
||||
# -----------------
|
||||
# kind of similar: hasattr
|
||||
# -----------------
|
||||
|
||||
if hasattr(str, 'undefined'):
|
||||
str.undefined
|
||||
str.upper
|
||||
#! 4 attribute-error
|
||||
str.undefined2
|
||||
#! 4 attribute-error
|
||||
int.undefined
|
||||
else:
|
||||
str.upper
|
||||
#! 4 attribute-error
|
||||
str.undefined
|
||||
179
vim-plugins/bundle/jedi-vim/jedi/test/test_api/test_api.py
Normal file
179
vim-plugins/bundle/jedi-vim/jedi/test/test_api/test_api.py
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
"""
|
||||
Test all things related to the ``jedi.api`` module.
|
||||
"""
|
||||
|
||||
from textwrap import dedent
|
||||
|
||||
from jedi import api
|
||||
from jedi._compatibility import is_py3
|
||||
from pytest import raises
|
||||
from jedi.parser import utils
|
||||
|
||||
|
||||
def test_preload_modules():
|
||||
def check_loaded(*modules):
|
||||
# +1 for None module (currently used)
|
||||
assert len(parser_cache) == len(modules) + 1
|
||||
for i in modules:
|
||||
assert [i in k for k in parser_cache.keys() if k is not None]
|
||||
|
||||
temp_cache, utils.parser_cache = utils.parser_cache, {}
|
||||
parser_cache = utils.parser_cache
|
||||
|
||||
api.preload_module('sys')
|
||||
check_loaded() # compiled (c_builtin) modules shouldn't be in the cache.
|
||||
api.preload_module('json', 'token')
|
||||
check_loaded('json', 'token')
|
||||
|
||||
utils.parser_cache = temp_cache
|
||||
|
||||
|
||||
def test_empty_script():
|
||||
assert api.Script('')
|
||||
|
||||
|
||||
def test_line_number_errors():
|
||||
"""
|
||||
Script should raise a ValueError if line/column numbers are not in a
|
||||
valid range.
|
||||
"""
|
||||
s = 'hello'
|
||||
# lines
|
||||
with raises(ValueError):
|
||||
api.Script(s, 2, 0)
|
||||
with raises(ValueError):
|
||||
api.Script(s, 0, 0)
|
||||
|
||||
# columns
|
||||
with raises(ValueError):
|
||||
api.Script(s, 1, len(s) + 1)
|
||||
with raises(ValueError):
|
||||
api.Script(s, 1, -1)
|
||||
|
||||
# ok
|
||||
api.Script(s, 1, 0)
|
||||
api.Script(s, 1, len(s))
|
||||
|
||||
|
||||
def _check_number(source, result='float'):
|
||||
completions = api.Script(source).completions()
|
||||
assert completions[0].parent().name == result
|
||||
|
||||
|
||||
def test_completion_on_number_literals():
|
||||
# No completions on an int literal (is a float).
|
||||
assert [c.name for c in api.Script('1.').completions()] \
|
||||
== ['and', 'if', 'in', 'is', 'not', 'or']
|
||||
|
||||
# Multiple points after an int literal basically mean that there's a float
|
||||
# and a call after that.
|
||||
_check_number('1..')
|
||||
_check_number('1.0.')
|
||||
|
||||
# power notation
|
||||
_check_number('1.e14.')
|
||||
_check_number('1.e-3.')
|
||||
_check_number('9e3.')
|
||||
assert api.Script('1.e3..').completions() == []
|
||||
assert api.Script('1.e-13..').completions() == []
|
||||
|
||||
|
||||
def test_completion_on_hex_literals():
|
||||
assert api.Script('0x1..').completions() == []
|
||||
_check_number('0x1.', 'int') # hexdecimal
|
||||
# Completing binary literals doesn't work if they are not actually binary
|
||||
# (invalid statements).
|
||||
assert api.Script('0b2.b').completions() == []
|
||||
_check_number('0b1.', 'int') # binary
|
||||
|
||||
_check_number('0x2e.', 'int')
|
||||
_check_number('0xE7.', 'int')
|
||||
_check_number('0xEa.', 'int')
|
||||
# theoretically, but people can just check for syntax errors:
|
||||
#assert api.Script('0x.').completions() == []
|
||||
|
||||
|
||||
def test_completion_on_complex_literals():
|
||||
assert api.Script('1j..').completions() == []
|
||||
_check_number('1j.', 'complex')
|
||||
_check_number('44.j.', 'complex')
|
||||
_check_number('4.0j.', 'complex')
|
||||
# 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():
|
||||
assert api.Script('for').goto_assignments() == []
|
||||
|
||||
assert api.Script('assert').goto_assignments() == []
|
||||
if is_py3:
|
||||
assert api.Script('True').goto_assignments() == []
|
||||
else:
|
||||
# In Python 2.7 True is still a name.
|
||||
assert api.Script('True').goto_assignments()[0].description == 'class bool'
|
||||
|
||||
|
||||
def test_goto_definitions_on_non_name():
|
||||
assert api.Script('import x', column=0).goto_definitions() == []
|
||||
|
||||
|
||||
def test_goto_definition_not_multiple():
|
||||
"""
|
||||
There should be only one Definition result if it leads back to the same
|
||||
origin (e.g. instance method)
|
||||
"""
|
||||
|
||||
s = dedent('''\
|
||||
import random
|
||||
class A():
|
||||
def __init__(self, a):
|
||||
self.a = 3
|
||||
|
||||
def foo(self):
|
||||
pass
|
||||
|
||||
if random.randint(0, 1):
|
||||
a = A(2)
|
||||
else:
|
||||
a = A(1)
|
||||
a''')
|
||||
assert len(api.Script(s).goto_definitions()) == 1
|
||||
|
||||
|
||||
def test_usage_description():
|
||||
descs = [u.description for u in api.Script("foo = ''; foo").usages()]
|
||||
assert set(descs) == set(["foo = ''", 'foo'])
|
||||
|
||||
|
||||
def test_get_line_code():
|
||||
def get_line_code(source, line=None, **kwargs):
|
||||
return api.Script(source, line=line).completions()[0].get_line_code(**kwargs)
|
||||
|
||||
# On builtin
|
||||
assert get_line_code('') == ''
|
||||
|
||||
# On custom code
|
||||
line = ' foo'
|
||||
assert get_line_code('def foo():\n%s' % line) == line
|
||||
|
||||
# With before/after
|
||||
line = ' foo'
|
||||
source = 'def foo():\n%s\nother_line' % line
|
||||
assert get_line_code(source, line=2) == line
|
||||
assert get_line_code(source, line=2, after=1) == line + '\nother_line'
|
||||
assert get_line_code(source, line=2, after=1, before=1) == source
|
||||
|
||||
|
||||
def test_goto_assignments_follow_imports():
|
||||
code = dedent("""
|
||||
import inspect
|
||||
inspect.isfunction""")
|
||||
definition, = api.Script(code, column=0).goto_assignments(follow_imports=True)
|
||||
assert 'inspect.py' in definition.module_path
|
||||
assert definition.start_pos == (1, 0)
|
||||
|
||||
definition, = api.Script(code).goto_assignments(follow_imports=True)
|
||||
assert 'inspect.py' in definition.module_path
|
||||
assert definition.start_pos > (1, 0)
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
from itertools import chain
|
||||
|
||||
import jedi
|
||||
from ..helpers import cwd_at
|
||||
|
||||
|
||||
def test_import_empty():
|
||||
""" github #340, return the full word. """
|
||||
completion = jedi.Script("import ").completions()[0]
|
||||
definition = completion.follow_definition()[0]
|
||||
assert definition
|
||||
|
||||
|
||||
def check_follow_definition_types(source):
|
||||
# nested import
|
||||
completions = jedi.Script(source, path='some_path.py').completions()
|
||||
defs = chain.from_iterable(c.follow_definition() for c in completions)
|
||||
return [d.type for d in defs]
|
||||
|
||||
|
||||
def test_follow_import_incomplete():
|
||||
"""
|
||||
Completion on incomplete imports should always take the full completion
|
||||
to do any evaluation.
|
||||
"""
|
||||
datetime = check_follow_definition_types("import itertool")
|
||||
assert datetime == ['module']
|
||||
|
||||
# empty `from * import` parts
|
||||
itert = jedi.Script("from itertools import ").completions()
|
||||
definitions = [d for d in itert if d.name == 'chain']
|
||||
assert len(definitions) == 1
|
||||
assert [d.type for d in definitions[0].follow_definition()] == ['class']
|
||||
|
||||
# incomplete `from * import` part
|
||||
datetime = check_follow_definition_types("from datetime import datetim")
|
||||
assert set(datetime) == set(['class', 'instance']) # py33: builtin and pure py version
|
||||
|
||||
# os.path check
|
||||
ospath = check_follow_definition_types("from os.path import abspat")
|
||||
assert ospath == ['function']
|
||||
|
||||
# alias
|
||||
alias = check_follow_definition_types("import io as abcd; abcd")
|
||||
assert alias == ['module']
|
||||
|
||||
|
||||
@cwd_at('test/completion/import_tree')
|
||||
def test_follow_definition_nested_import():
|
||||
types = check_follow_definition_types("import pkg.mod1; pkg")
|
||||
assert types == ['module']
|
||||
|
||||
types = check_follow_definition_types("import pkg.mod1; pkg.mod1")
|
||||
assert types == ['module']
|
||||
|
||||
types = check_follow_definition_types("import pkg.mod1; pkg.mod1.a")
|
||||
assert types == ['instance']
|
||||
|
||||
|
||||
def test_follow_definition_land_on_import():
|
||||
types = check_follow_definition_types("import datetime; datetim")
|
||||
assert types == ['module']
|
||||
|
|
@ -0,0 +1,389 @@
|
|||
from textwrap import dedent
|
||||
import inspect
|
||||
|
||||
from ..helpers import TestCase
|
||||
from jedi import Script
|
||||
from jedi import cache
|
||||
from jedi._compatibility import is_py33
|
||||
|
||||
|
||||
def assert_signature(source, expected_name, expected_index=0, line=None, column=None):
|
||||
signatures = Script(source, line, column).call_signatures()
|
||||
|
||||
assert len(signatures) <= 1
|
||||
|
||||
if not signatures:
|
||||
assert expected_name is None, \
|
||||
'There are no signatures, but `%s` expected.' % expected_name
|
||||
else:
|
||||
assert signatures[0].name == expected_name
|
||||
assert signatures[0].index == expected_index
|
||||
return signatures[0]
|
||||
|
||||
|
||||
class TestCallSignatures(TestCase):
|
||||
def _run_simple(self, source, name, index=0, column=None, line=1):
|
||||
assert_signature(source, name, index, line, column)
|
||||
|
||||
def test_valid_call(self):
|
||||
assert_signature('str()', 'str', column=4)
|
||||
|
||||
def test_simple(self):
|
||||
run = self._run_simple
|
||||
|
||||
# simple
|
||||
s1 = "sorted(a, str("
|
||||
run(s1, 'sorted', 0, 7)
|
||||
run(s1, 'sorted', 1, 9)
|
||||
run(s1, 'sorted', 1, 10)
|
||||
run(s1, 'sorted', 1, 11)
|
||||
run(s1, 'str', 0, 14)
|
||||
|
||||
s2 = "abs(), "
|
||||
run(s2, 'abs', 0, 4)
|
||||
run(s2, None, column=5)
|
||||
run(s2, None)
|
||||
|
||||
s3 = "abs()."
|
||||
run(s3, None, column=5)
|
||||
run(s3, None)
|
||||
|
||||
def test_more_complicated(self):
|
||||
run = self._run_simple
|
||||
'''
|
||||
s4 = 'abs(zip(), , set,'
|
||||
run(s4, None, column=3)
|
||||
run(s4, 'abs', 0, 4)
|
||||
run(s4, 'zip', 0, 8)
|
||||
run(s4, 'abs', 0, 9)
|
||||
#run(s4, 'abs', 1, 10)
|
||||
'''
|
||||
|
||||
s5 = "sorted(1,\nif 2:\n def a():"
|
||||
run(s5, 'sorted', 0, 7)
|
||||
run(s5, 'sorted', 1, 9)
|
||||
|
||||
s6 = "str().center("
|
||||
run(s6, 'center', 0)
|
||||
run(s6, 'str', 0, 4)
|
||||
|
||||
s7 = "str().upper().center("
|
||||
s8 = "str(int[zip("
|
||||
run(s7, 'center', 0)
|
||||
run(s8, 'zip', 0)
|
||||
run(s8, 'str', 0, 8)
|
||||
|
||||
run("import time; abc = time; abc.sleep(", 'sleep', 0)
|
||||
|
||||
def test_issue_57(self):
|
||||
# jedi #57
|
||||
s = "def func(alpha, beta): pass\n" \
|
||||
"func(alpha='101',"
|
||||
self._run_simple(s, 'func', 0, column=13, line=2)
|
||||
|
||||
def test_flows(self):
|
||||
# jedi-vim #9
|
||||
self._run_simple("with open(", 'open', 0)
|
||||
|
||||
# jedi-vim #11
|
||||
self._run_simple("for sorted(", 'sorted', 0)
|
||||
self._run_simple("for s in sorted(", 'sorted', 0)
|
||||
|
||||
def test_complex(self):
|
||||
s = """
|
||||
def abc(a,b):
|
||||
pass
|
||||
|
||||
def a(self):
|
||||
abc(
|
||||
|
||||
if 1:
|
||||
pass
|
||||
"""
|
||||
assert_signature(s, 'abc', 0, line=6, column=24)
|
||||
s = """
|
||||
import re
|
||||
def huhu(it):
|
||||
re.compile(
|
||||
return it * 2
|
||||
"""
|
||||
assert_signature(s, 'compile', 0, line=4, column=31)
|
||||
|
||||
# jedi-vim #70
|
||||
s = """def foo("""
|
||||
assert Script(s).call_signatures() == []
|
||||
|
||||
# jedi-vim #116
|
||||
s = """import itertools; test = getattr(itertools, 'chain'); test("""
|
||||
assert_signature(s, 'chain', 0)
|
||||
|
||||
def test_call_signature_on_module(self):
|
||||
"""github issue #240"""
|
||||
s = 'import datetime; datetime('
|
||||
# just don't throw an exception (if numpy doesn't exist, just ignore it)
|
||||
assert Script(s).call_signatures() == []
|
||||
|
||||
def test_call_signatures_empty_parentheses_pre_space(self):
|
||||
s = dedent("""\
|
||||
def f(a, b):
|
||||
pass
|
||||
f( )""")
|
||||
assert_signature(s, 'f', 0, line=3, column=3)
|
||||
|
||||
def test_multiple_signatures(self):
|
||||
s = dedent("""\
|
||||
if x:
|
||||
def f(a, b):
|
||||
pass
|
||||
else:
|
||||
def f(a, b):
|
||||
pass
|
||||
f(""")
|
||||
assert len(Script(s).call_signatures()) == 2
|
||||
|
||||
def test_call_signatures_whitespace(self):
|
||||
s = dedent("""\
|
||||
abs(
|
||||
def x():
|
||||
pass
|
||||
""")
|
||||
assert_signature(s, 'abs', 0, line=1, column=5)
|
||||
|
||||
def test_decorator_in_class(self):
|
||||
"""
|
||||
There's still an implicit param, with a decorator.
|
||||
Github issue #319.
|
||||
"""
|
||||
s = dedent("""\
|
||||
def static(func):
|
||||
def wrapped(obj, *args):
|
||||
return f(type(obj), *args)
|
||||
return wrapped
|
||||
|
||||
class C(object):
|
||||
@static
|
||||
def test(cls):
|
||||
return 10
|
||||
|
||||
C().test(""")
|
||||
|
||||
signatures = Script(s).call_signatures()
|
||||
assert len(signatures) == 1
|
||||
x = [p.description for p in signatures[0].params]
|
||||
assert x == ['*args']
|
||||
|
||||
def test_additional_brackets(self):
|
||||
assert_signature('str((', 'str', 0)
|
||||
|
||||
def test_unterminated_strings(self):
|
||||
assert_signature('str(";', 'str', 0)
|
||||
|
||||
def test_whitespace_before_bracket(self):
|
||||
assert_signature('str (', 'str', 0)
|
||||
assert_signature('str (";', 'str', 0)
|
||||
assert_signature('str\n(', None)
|
||||
|
||||
def test_brackets_in_string_literals(self):
|
||||
assert_signature('str (" (', 'str', 0)
|
||||
assert_signature('str (" )', 'str', 0)
|
||||
|
||||
def test_function_definitions_should_break(self):
|
||||
"""
|
||||
Function definitions (and other tokens that cannot exist within call
|
||||
signatures) should break and not be able to return a call signature.
|
||||
"""
|
||||
assert_signature('str(\ndef x', 'str', 0)
|
||||
assert not Script('str(\ndef x(): pass').call_signatures()
|
||||
|
||||
def test_flow_call(self):
|
||||
assert not Script('if (1').call_signatures()
|
||||
|
||||
def test_chained_calls(self):
|
||||
source = dedent('''
|
||||
class B():
|
||||
def test2(self, arg):
|
||||
pass
|
||||
|
||||
class A():
|
||||
def test1(self):
|
||||
return B()
|
||||
|
||||
A().test1().test2(''')
|
||||
|
||||
assert_signature(source, 'test2', 0)
|
||||
|
||||
def test_return(self):
|
||||
source = dedent('''
|
||||
def foo():
|
||||
return '.'.join()''')
|
||||
|
||||
assert_signature(source, 'join', 0, column=len(" return '.'.join("))
|
||||
|
||||
|
||||
class TestParams(TestCase):
|
||||
def params(self, source, line=None, column=None):
|
||||
signatures = Script(source, line, column).call_signatures()
|
||||
assert len(signatures) == 1
|
||||
return signatures[0].params
|
||||
|
||||
def test_param_name(self):
|
||||
if not is_py33:
|
||||
p = self.params('''int(''')
|
||||
# int is defined as: `int(x[, base])`
|
||||
assert p[0].name == 'x'
|
||||
# `int` docstring has been redefined:
|
||||
# http://bugs.python.org/issue14783
|
||||
# TODO have multiple call signatures for int (like in the docstr)
|
||||
#assert p[1].name == 'base'
|
||||
|
||||
p = self.params('''open(something,''')
|
||||
assert p[0].name in ['file', 'name']
|
||||
assert p[1].name == 'mode'
|
||||
|
||||
def test_builtins(self):
|
||||
"""
|
||||
The self keyword should be visible even for builtins, if not
|
||||
instantiated.
|
||||
"""
|
||||
p = self.params('str.endswith(')
|
||||
assert p[0].name == 'self'
|
||||
assert p[1].name == 'suffix'
|
||||
p = self.params('str().endswith(')
|
||||
assert p[0].name == 'suffix'
|
||||
|
||||
|
||||
def test_signature_is_definition():
|
||||
"""
|
||||
Through inheritance, a call signature is a sub class of Definition.
|
||||
Check if the attributes match.
|
||||
"""
|
||||
s = """class Spam(): pass\nSpam"""
|
||||
signature = Script(s + '(').call_signatures()[0]
|
||||
definition = Script(s + '(', column=0).goto_definitions()[0]
|
||||
signature.line == 1
|
||||
signature.column == 6
|
||||
|
||||
# Now compare all the attributes that a CallSignature must also have.
|
||||
for attr_name in dir(definition):
|
||||
dont_scan = ['defined_names', 'line_nr', 'start_pos', 'documentation',
|
||||
'doc', 'parent', 'goto_assignments']
|
||||
if attr_name.startswith('_') or attr_name in dont_scan:
|
||||
continue
|
||||
attribute = getattr(definition, attr_name)
|
||||
signature_attribute = getattr(signature, attr_name)
|
||||
if inspect.ismethod(attribute):
|
||||
assert attribute() == signature_attribute()
|
||||
else:
|
||||
assert attribute == signature_attribute
|
||||
|
||||
|
||||
def test_no_signature():
|
||||
# str doesn't have a __call__ method
|
||||
assert Script('str()(').call_signatures() == []
|
||||
|
||||
s = dedent("""\
|
||||
class X():
|
||||
pass
|
||||
X()(""")
|
||||
assert Script(s).call_signatures() == []
|
||||
assert len(Script(s, column=2).call_signatures()) == 1
|
||||
|
||||
|
||||
def test_dict_literal_in_incomplete_call():
|
||||
source = """\
|
||||
import json
|
||||
|
||||
def foo():
|
||||
json.loads(
|
||||
|
||||
json.load.return_value = {'foo': [],
|
||||
'bar': True}
|
||||
|
||||
c = Foo()
|
||||
"""
|
||||
|
||||
script = Script(dedent(source), line=4, column=15)
|
||||
assert script.call_signatures()
|
||||
|
||||
|
||||
def test_completion_interference():
|
||||
"""Seems to cause problems, see also #396."""
|
||||
cache.parser_cache.pop(None, None)
|
||||
assert Script('open(').call_signatures()
|
||||
|
||||
# complete something usual, before doing the same call_signatures again.
|
||||
assert Script('from datetime import ').completions()
|
||||
|
||||
assert Script('open(').call_signatures()
|
||||
|
||||
|
||||
def test_keyword_argument_index():
|
||||
def get(source, column=None):
|
||||
return Script(source, column=column).call_signatures()[0]
|
||||
|
||||
assert get('sorted([], key=a').index == 2
|
||||
assert get('sorted([], key=').index == 2
|
||||
assert get('sorted([], no_key=a').index is None
|
||||
|
||||
kw_func = 'def foo(a, b): pass\nfoo(b=3, a=4)'
|
||||
assert get(kw_func, column=len('foo(b')).index == 0
|
||||
assert get(kw_func, column=len('foo(b=')).index == 1
|
||||
assert get(kw_func, column=len('foo(b=3, a=')).index == 0
|
||||
|
||||
kw_func_simple = 'def foo(a, b): pass\nfoo(b=4)'
|
||||
assert get(kw_func_simple, column=len('foo(b')).index == 0
|
||||
assert get(kw_func_simple, column=len('foo(b=')).index == 1
|
||||
|
||||
args_func = 'def foo(*kwargs): pass\n'
|
||||
assert get(args_func + 'foo(a').index == 0
|
||||
assert get(args_func + 'foo(a, b').index == 0
|
||||
|
||||
kwargs_func = 'def foo(**kwargs): pass\n'
|
||||
assert get(kwargs_func + 'foo(a=2').index == 0
|
||||
assert get(kwargs_func + 'foo(a=2, b=2').index == 0
|
||||
|
||||
both = 'def foo(*args, **kwargs): pass\n'
|
||||
assert get(both + 'foo(a=2').index == 1
|
||||
assert get(both + 'foo(a=2, b=2').index == 1
|
||||
assert get(both + 'foo(a=2, b=2)', column=len('foo(b=2, a=2')).index == 1
|
||||
assert get(both + 'foo(a, b, c').index == 0
|
||||
|
||||
|
||||
def test_bracket_start():
|
||||
def bracket_start(src):
|
||||
signatures = Script(src).call_signatures()
|
||||
assert len(signatures) == 1
|
||||
return signatures[0].bracket_start
|
||||
|
||||
assert bracket_start('str(') == (1, 3)
|
||||
|
||||
|
||||
def test_different_caller():
|
||||
"""
|
||||
It's possible to not use names, but another function result or an array
|
||||
index and then get the call signature of it.
|
||||
"""
|
||||
|
||||
assert_signature('[str][0](', 'str', 0)
|
||||
assert_signature('[str][0]()', 'str', 0, column=len('[str][0]('))
|
||||
|
||||
assert_signature('(str)(', 'str', 0)
|
||||
assert_signature('(str)()', 'str', 0, column=len('(str)('))
|
||||
|
||||
|
||||
def test_in_function():
|
||||
code = dedent('''\
|
||||
class X():
|
||||
@property
|
||||
def func(''')
|
||||
assert not Script(code).call_signatures()
|
||||
|
||||
|
||||
def test_lambda_params():
|
||||
code = dedent('''\
|
||||
my_lambda = lambda x: x+1
|
||||
my_lambda(1)''')
|
||||
sig, = Script(code, column=11).call_signatures()
|
||||
assert sig.index == 0
|
||||
assert sig.name == '<lambda>'
|
||||
assert [p.name for p in sig.params] == ['x']
|
||||
354
vim-plugins/bundle/jedi-vim/jedi/test/test_api/test_classes.py
Normal file
354
vim-plugins/bundle/jedi-vim/jedi/test/test_api/test_classes.py
Normal file
|
|
@ -0,0 +1,354 @@
|
|||
""" Test all things related to the ``jedi.api_classes`` module.
|
||||
"""
|
||||
|
||||
from textwrap import dedent
|
||||
from inspect import cleandoc
|
||||
|
||||
import pytest
|
||||
|
||||
from jedi import Script, defined_names, __doc__ as jedi_doc, names
|
||||
from ..helpers import cwd_at
|
||||
from ..helpers import TestCase
|
||||
|
||||
|
||||
def test_is_keyword():
|
||||
#results = Script('import ', 1, 1, None).goto_definitions()
|
||||
#assert len(results) == 1 and results[0].is_keyword is True
|
||||
results = Script('str', 1, 1, None).goto_definitions()
|
||||
assert len(results) == 1 and results[0].is_keyword is False
|
||||
|
||||
|
||||
def make_definitions():
|
||||
"""
|
||||
Return a list of definitions for parametrized tests.
|
||||
|
||||
:rtype: [jedi.api_classes.BaseDefinition]
|
||||
"""
|
||||
source = dedent("""
|
||||
import sys
|
||||
|
||||
class C:
|
||||
pass
|
||||
|
||||
x = C()
|
||||
|
||||
def f():
|
||||
pass
|
||||
|
||||
def g():
|
||||
yield
|
||||
|
||||
h = lambda: None
|
||||
""")
|
||||
|
||||
definitions = []
|
||||
definitions += defined_names(source)
|
||||
|
||||
source += dedent("""
|
||||
variable = sys or C or x or f or g or g() or h""")
|
||||
lines = source.splitlines()
|
||||
script = Script(source, len(lines), len('variable'), None)
|
||||
definitions += script.goto_definitions()
|
||||
|
||||
script2 = Script(source, 4, len('class C'), None)
|
||||
definitions += script2.usages()
|
||||
|
||||
source_param = "def f(a): return a"
|
||||
script_param = Script(source_param, 1, len(source_param), None)
|
||||
definitions += script_param.goto_assignments()
|
||||
|
||||
return definitions
|
||||
|
||||
|
||||
@pytest.mark.parametrize('definition', make_definitions())
|
||||
def test_basedefinition_type(definition):
|
||||
assert definition.type in ('module', 'class', 'instance', 'function',
|
||||
'generator', 'statement', 'import', 'param')
|
||||
|
||||
|
||||
def test_basedefinition_type_import():
|
||||
def get_types(source, **kwargs):
|
||||
return set([t.type for t in Script(source, **kwargs).completions()])
|
||||
|
||||
# import one level
|
||||
assert get_types('import t') == set(['module'])
|
||||
assert get_types('import ') == set(['module'])
|
||||
assert get_types('import datetime; datetime') == set(['module'])
|
||||
|
||||
# from
|
||||
assert get_types('from datetime import timedelta') == set(['class'])
|
||||
assert get_types('from datetime import timedelta; timedelta') == set(['class'])
|
||||
assert get_types('from json import tool') == set(['module'])
|
||||
assert get_types('from json import tool; tool') == set(['module'])
|
||||
|
||||
# import two levels
|
||||
assert get_types('import json.tool; json') == set(['module'])
|
||||
assert get_types('import json.tool; json.tool') == set(['module'])
|
||||
assert get_types('import json.tool; json.tool.main') == set(['function'])
|
||||
assert get_types('import json.tool') == set(['module'])
|
||||
assert get_types('import json.tool', column=9) == set(['module'])
|
||||
|
||||
|
||||
def test_function_call_signature_in_doc():
|
||||
defs = Script("""
|
||||
def f(x, y=1, z='a'):
|
||||
pass
|
||||
f""").goto_definitions()
|
||||
doc = defs[0].doc
|
||||
assert "f(x, y=1, z='a')" in str(doc)
|
||||
|
||||
|
||||
def test_class_call_signature():
|
||||
defs = Script("""
|
||||
class Foo:
|
||||
def __init__(self, x, y=1, z='a'):
|
||||
pass
|
||||
Foo""").goto_definitions()
|
||||
doc = defs[0].doc
|
||||
assert "Foo(self, x, y=1, z='a')" in str(doc)
|
||||
|
||||
|
||||
def test_position_none_if_builtin():
|
||||
gotos = Script('import sys; sys.path').goto_assignments()
|
||||
assert gotos[0].line is None
|
||||
assert gotos[0].column is None
|
||||
|
||||
|
||||
@cwd_at('.')
|
||||
def test_completion_docstring():
|
||||
"""
|
||||
Jedi should follow imports in certain conditions
|
||||
"""
|
||||
def docstr(src, result):
|
||||
c = Script(src).completions()[0]
|
||||
assert c.docstring(raw=True, fast=False) == cleandoc(result)
|
||||
|
||||
c = Script('import jedi\njed').completions()[0]
|
||||
assert c.docstring(fast=False) == cleandoc(jedi_doc)
|
||||
|
||||
docstr('import jedi\njedi.Scr', cleandoc(Script.__doc__))
|
||||
|
||||
docstr('abcd=3;abcd', '')
|
||||
docstr('"hello"\nabcd=3\nabcd', 'hello')
|
||||
# It works with a ; as well.
|
||||
docstr('"hello"\nabcd=3;abcd', 'hello')
|
||||
# Shouldn't work with a tuple.
|
||||
docstr('"hello",0\nabcd=3\nabcd', '')
|
||||
|
||||
|
||||
def test_completion_params():
|
||||
c = Script('import string; string.capwords').completions()[0]
|
||||
assert [p.name for p in c.params] == ['s', 'sep']
|
||||
|
||||
|
||||
def test_signature_params():
|
||||
def check(defs):
|
||||
params = defs[0].params
|
||||
assert len(params) == 1
|
||||
assert params[0].name == 'bar'
|
||||
|
||||
s = dedent('''
|
||||
def foo(bar):
|
||||
pass
|
||||
foo''')
|
||||
|
||||
check(Script(s).goto_definitions())
|
||||
|
||||
check(Script(s).goto_assignments())
|
||||
check(Script(s + '\nbar=foo\nbar').goto_assignments())
|
||||
|
||||
|
||||
def test_param_endings():
|
||||
"""
|
||||
Params should be represented without the comma and whitespace they have
|
||||
around them.
|
||||
"""
|
||||
sig = Script('def x(a, b=5, c=""): pass\n x(').call_signatures()[0]
|
||||
assert [p.description for p in sig.params] == ['a', 'b=5', 'c=""']
|
||||
|
||||
|
||||
class TestIsDefinition(TestCase):
|
||||
def _def(self, source, index=-1):
|
||||
return names(dedent(source), references=True, all_scopes=True)[index]
|
||||
|
||||
def _bool_is_definitions(self, source):
|
||||
ns = names(dedent(source), references=True, all_scopes=True)
|
||||
# Assure that names are definitely sorted.
|
||||
ns = sorted(ns, key=lambda name: (name.line, name.column))
|
||||
return [name.is_definition() for name in ns]
|
||||
|
||||
def test_name(self):
|
||||
d = self._def('name')
|
||||
assert d.name == 'name'
|
||||
assert not d.is_definition()
|
||||
|
||||
def test_stmt(self):
|
||||
src = 'a = f(x)'
|
||||
d = self._def(src, 0)
|
||||
assert d.name == 'a'
|
||||
assert d.is_definition()
|
||||
d = self._def(src, 1)
|
||||
assert d.name == 'f'
|
||||
assert not d.is_definition()
|
||||
d = self._def(src)
|
||||
assert d.name == 'x'
|
||||
assert not d.is_definition()
|
||||
|
||||
def test_import(self):
|
||||
assert self._bool_is_definitions('import x as a') == [False, True]
|
||||
assert self._bool_is_definitions('from x import y') == [False, True]
|
||||
assert self._bool_is_definitions('from x.z import y') == [False, False, True]
|
||||
|
||||
|
||||
class TestParent(TestCase):
|
||||
def _parent(self, source, line=None, column=None):
|
||||
defs = Script(dedent(source), line, column).goto_assignments()
|
||||
assert len(defs) == 1
|
||||
return defs[0].parent()
|
||||
|
||||
def test_parent(self):
|
||||
parent = self._parent('foo=1\nfoo')
|
||||
assert parent.type == 'module'
|
||||
|
||||
parent = self._parent('''
|
||||
def spam():
|
||||
if 1:
|
||||
y=1
|
||||
y''')
|
||||
assert parent.name == 'spam'
|
||||
assert parent.parent().type == 'module'
|
||||
|
||||
def test_on_function(self):
|
||||
parent = self._parent('''\
|
||||
def spam():
|
||||
pass''', 1, len('def spam'))
|
||||
assert parent.name == ''
|
||||
assert parent.type == 'module'
|
||||
|
||||
def test_parent_on_completion(self):
|
||||
parent = Script(dedent('''\
|
||||
class Foo():
|
||||
def bar(): pass
|
||||
Foo().bar''')).completions()[0].parent()
|
||||
assert parent.name == 'Foo'
|
||||
assert parent.type == 'instance'
|
||||
|
||||
parent = Script('str.join').completions()[0].parent()
|
||||
assert parent.name == 'str'
|
||||
assert parent.type == 'class'
|
||||
|
||||
|
||||
def test_type():
|
||||
"""
|
||||
Github issue #397, type should never raise an error.
|
||||
"""
|
||||
for c in Script('import os; os.path.').completions():
|
||||
assert c.type
|
||||
|
||||
|
||||
class TestGotoAssignments(TestCase):
|
||||
"""
|
||||
This tests the BaseDefinition.goto_assignments function, not the jedi
|
||||
function. They are not really different in functionality, but really
|
||||
different as an implementation.
|
||||
"""
|
||||
def test_repetition(self):
|
||||
defs = names('a = 1; a', references=True, definitions=False)
|
||||
# Repeat on the same variable. Shouldn't change once we're on a
|
||||
# definition.
|
||||
for _ in range(3):
|
||||
assert len(defs) == 1
|
||||
ass = defs[0].goto_assignments()
|
||||
assert ass[0].description == 'a = 1'
|
||||
|
||||
def test_named_params(self):
|
||||
src = """\
|
||||
def foo(a=1, bar=2):
|
||||
pass
|
||||
foo(bar=1)
|
||||
"""
|
||||
bar = names(dedent(src), references=True)[-1]
|
||||
param = bar.goto_assignments()[0]
|
||||
assert param.start_pos == (1, 13)
|
||||
assert param.type == 'param'
|
||||
|
||||
def test_class_call(self):
|
||||
src = 'from threading import Thread; Thread(group=1)'
|
||||
n = names(src, references=True)[-1]
|
||||
assert n.name == 'group'
|
||||
param_def = n.goto_assignments()[0]
|
||||
assert param_def.name == 'group'
|
||||
assert param_def.type == 'param'
|
||||
|
||||
def test_parentheses(self):
|
||||
n = names('("").upper', references=True)[-1]
|
||||
assert n.goto_assignments()[0].name == 'upper'
|
||||
|
||||
def test_import(self):
|
||||
nms = names('from json import load', references=True)
|
||||
assert nms[0].name == 'json'
|
||||
assert nms[0].type == 'import'
|
||||
n = nms[0].goto_assignments()[0]
|
||||
assert n.name == 'json'
|
||||
assert n.type == 'module'
|
||||
|
||||
assert nms[1].name == 'load'
|
||||
assert nms[1].type == 'import'
|
||||
n = nms[1].goto_assignments()[0]
|
||||
assert n.name == 'load'
|
||||
assert n.type == 'function'
|
||||
|
||||
nms = names('import os; os.path', references=True)
|
||||
assert nms[0].name == 'os'
|
||||
assert nms[0].type == 'import'
|
||||
n = nms[0].goto_assignments()[0]
|
||||
assert n.name == 'os'
|
||||
assert n.type == 'module'
|
||||
|
||||
n = nms[2].goto_assignments()[0]
|
||||
assert n.name == 'path'
|
||||
assert n.type == 'import'
|
||||
|
||||
nms = names('import os.path', references=True)
|
||||
n = nms[0].goto_assignments()[0]
|
||||
assert n.name == 'os'
|
||||
assert n.type == 'module'
|
||||
n = nms[1].goto_assignments()[0]
|
||||
# This is very special, normally the name doesn't chance, but since
|
||||
# os.path is a sys.modules hack, it does.
|
||||
assert n.name in ('ntpath', 'posixpath', 'os2emxpath')
|
||||
assert n.type == 'module'
|
||||
|
||||
def test_import_alias(self):
|
||||
nms = names('import json as foo', references=True)
|
||||
assert nms[0].name == 'json'
|
||||
assert nms[0].type == 'import'
|
||||
n = nms[0].goto_assignments()[0]
|
||||
assert n.name == 'json'
|
||||
assert n.type == 'module'
|
||||
|
||||
assert nms[1].name == 'foo'
|
||||
assert nms[1].type == 'import'
|
||||
ass = nms[1].goto_assignments()
|
||||
assert len(ass) == 1
|
||||
assert ass[0].name == 'json'
|
||||
assert ass[0].type == 'module'
|
||||
|
||||
|
||||
def test_added_equals_to_params():
|
||||
def run(rest_source):
|
||||
source = dedent("""
|
||||
def foo(bar, baz):
|
||||
pass
|
||||
""")
|
||||
results = Script(source + rest_source).completions()
|
||||
assert len(results) == 1
|
||||
return results[0]
|
||||
|
||||
assert run('foo(bar').name_with_symbols == 'bar='
|
||||
assert run('foo(bar').complete == '='
|
||||
assert run('foo(bar, baz').complete == '='
|
||||
assert run(' bar').name_with_symbols == 'bar'
|
||||
assert run(' bar').complete == ''
|
||||
x = run('foo(bar=isins').name_with_symbols
|
||||
assert x == 'isinstance'
|
||||
|
|
@ -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,0 +1,92 @@
|
|||
"""
|
||||
Tests for `api.defined_names`.
|
||||
"""
|
||||
|
||||
from textwrap import dedent
|
||||
|
||||
from jedi import defined_names, names
|
||||
from ..helpers import TestCase
|
||||
|
||||
|
||||
class TestDefinedNames(TestCase):
|
||||
def assert_definition_names(self, definitions, names_):
|
||||
assert [d.name for d in definitions] == names_
|
||||
|
||||
def check_defined_names(self, source, names_):
|
||||
definitions = names(dedent(source))
|
||||
self.assert_definition_names(definitions, names_)
|
||||
return definitions
|
||||
|
||||
def test_get_definitions_flat(self):
|
||||
self.check_defined_names("""
|
||||
import module
|
||||
class Class:
|
||||
pass
|
||||
def func():
|
||||
pass
|
||||
data = None
|
||||
""", ['module', 'Class', 'func', 'data'])
|
||||
|
||||
def test_dotted_assignment(self):
|
||||
self.check_defined_names("""
|
||||
x = Class()
|
||||
x.y.z = None
|
||||
""", ['x', 'z']) # TODO is this behavior what we want?
|
||||
|
||||
def test_multiple_assignment(self):
|
||||
self.check_defined_names("""
|
||||
x = y = None
|
||||
""", ['x', 'y'])
|
||||
|
||||
def test_multiple_imports(self):
|
||||
self.check_defined_names("""
|
||||
from module import a, b
|
||||
from another_module import *
|
||||
""", ['a', 'b'])
|
||||
|
||||
def test_nested_definitions(self):
|
||||
definitions = self.check_defined_names("""
|
||||
class Class:
|
||||
def f():
|
||||
pass
|
||||
def g():
|
||||
pass
|
||||
""", ['Class'])
|
||||
subdefinitions = definitions[0].defined_names()
|
||||
self.assert_definition_names(subdefinitions, ['f', 'g'])
|
||||
self.assertEqual([d.full_name for d in subdefinitions],
|
||||
['Class.f', 'Class.g'])
|
||||
|
||||
def test_nested_class(self):
|
||||
definitions = self.check_defined_names("""
|
||||
class L1:
|
||||
class L2:
|
||||
class L3:
|
||||
def f(): pass
|
||||
def f(): pass
|
||||
def f(): pass
|
||||
def f(): pass
|
||||
""", ['L1', 'f'])
|
||||
subdefs = definitions[0].defined_names()
|
||||
subsubdefs = subdefs[0].defined_names()
|
||||
self.assert_definition_names(subdefs, ['L2', 'f'])
|
||||
self.assert_definition_names(subsubdefs, ['L3', 'f'])
|
||||
self.assert_definition_names(subsubdefs[0].defined_names(), ['f'])
|
||||
|
||||
|
||||
def test_follow_imports():
|
||||
# github issue #344
|
||||
imp = defined_names('import datetime')[0]
|
||||
assert imp.name == 'datetime'
|
||||
datetime_names = [str(d.name) for d in imp.defined_names()]
|
||||
assert 'timedelta' in datetime_names
|
||||
|
||||
|
||||
def test_names_twice():
|
||||
source = dedent('''
|
||||
def lol():
|
||||
pass
|
||||
''')
|
||||
|
||||
defs = names(source=source)
|
||||
assert defs[0].defined_names() == []
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
"""
|
||||
Tests for :attr:`.BaseDefinition.full_name`.
|
||||
|
||||
There are three kinds of test:
|
||||
|
||||
#. Test classes derived from :class:`MixinTestFullName`.
|
||||
Child class defines :attr:`.operation` to alter how
|
||||
the api definition instance is created.
|
||||
|
||||
#. :class:`TestFullDefinedName` is to test combination of
|
||||
``obj.full_name`` and ``jedi.defined_names``.
|
||||
|
||||
#. Misc single-function tests.
|
||||
"""
|
||||
|
||||
import textwrap
|
||||
|
||||
import pytest
|
||||
|
||||
import jedi
|
||||
from ..helpers import TestCase
|
||||
|
||||
|
||||
class MixinTestFullName(object):
|
||||
operation = None
|
||||
|
||||
def check(self, source, desired):
|
||||
script = jedi.Script(textwrap.dedent(source))
|
||||
definitions = getattr(script, type(self).operation)()
|
||||
for d in definitions:
|
||||
self.assertEqual(d.full_name, desired)
|
||||
|
||||
def test_os_path_join(self):
|
||||
self.check('import os; os.path.join', 'os.path.join')
|
||||
|
||||
def test_builtin(self):
|
||||
self.check('TypeError', 'TypeError')
|
||||
|
||||
|
||||
class TestFullNameWithGotoDefinitions(MixinTestFullName, TestCase):
|
||||
operation = 'goto_definitions'
|
||||
|
||||
@pytest.mark.skipif('sys.version_info[0] < 3', reason='Python 2 also yields None.')
|
||||
def test_tuple_mapping(self):
|
||||
self.check("""
|
||||
import re
|
||||
any_re = re.compile('.*')
|
||||
any_re""", '_sre.compile.SRE_Pattern')
|
||||
|
||||
def test_from_import(self):
|
||||
self.check('from os import path', 'os.path')
|
||||
|
||||
|
||||
class TestFullNameWithCompletions(MixinTestFullName, TestCase):
|
||||
operation = 'completions'
|
||||
|
||||
|
||||
class TestFullDefinedName(TestCase):
|
||||
"""
|
||||
Test combination of ``obj.full_name`` and ``jedi.defined_names``.
|
||||
"""
|
||||
|
||||
def check(self, source, desired):
|
||||
definitions = jedi.defined_names(textwrap.dedent(source))
|
||||
full_names = [d.full_name for d in definitions]
|
||||
self.assertEqual(full_names, desired)
|
||||
|
||||
def test_local_names(self):
|
||||
self.check("""
|
||||
def f(): pass
|
||||
class C: pass
|
||||
""", ['f', 'C'])
|
||||
|
||||
def test_imports(self):
|
||||
self.check("""
|
||||
import os
|
||||
from os import path
|
||||
from os.path import join
|
||||
from os import path as opath
|
||||
""", ['os', 'os.path', 'os.path.join', 'os.path'])
|
||||
|
||||
|
||||
def test_sub_module():
|
||||
"""
|
||||
``full_name needs to check sys.path to actually find it's real path module
|
||||
path.
|
||||
"""
|
||||
defs = jedi.Script('from jedi.api import classes; classes').goto_definitions()
|
||||
assert [d.full_name for d in defs] == ['jedi.api.classes']
|
||||
defs = jedi.Script('import jedi.api; jedi.api').goto_definitions()
|
||||
assert [d.full_name for d in defs] == ['jedi.api']
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
"""
|
||||
Tests of ``jedi.api.Interpreter``.
|
||||
"""
|
||||
|
||||
from ..helpers import TestCase
|
||||
import jedi
|
||||
from jedi._compatibility import is_py33
|
||||
from jedi.evaluate.compiled import mixed
|
||||
|
||||
class _GlobalNameSpace():
|
||||
class SideEffectContainer():
|
||||
pass
|
||||
|
||||
|
||||
def get_completion(source, namespace):
|
||||
i = jedi.Interpreter(source, [namespace])
|
||||
completions = i.completions()
|
||||
assert len(completions) == 1
|
||||
return completions[0]
|
||||
|
||||
|
||||
def test_builtin_details():
|
||||
import keyword
|
||||
|
||||
class EmptyClass:
|
||||
pass
|
||||
|
||||
variable = EmptyClass()
|
||||
|
||||
def func():
|
||||
pass
|
||||
|
||||
cls = get_completion('EmptyClass', locals())
|
||||
var = get_completion('variable', locals())
|
||||
f = get_completion('func', locals())
|
||||
m = get_completion('keyword', locals())
|
||||
assert cls.type == 'class'
|
||||
assert var.type == 'instance'
|
||||
assert f.type == 'function'
|
||||
assert m.type == 'module'
|
||||
|
||||
|
||||
def test_nested_resolve():
|
||||
class XX():
|
||||
def x():
|
||||
pass
|
||||
|
||||
cls = get_completion('XX', locals())
|
||||
func = get_completion('XX.x', locals())
|
||||
assert func.start_pos == (cls.start_pos[0] + 1, 12)
|
||||
|
||||
|
||||
def test_side_effect_completion():
|
||||
"""
|
||||
In the repl it's possible to cause side effects that are not documented in
|
||||
Python code, however we want references to Python code as well. Therefore
|
||||
we need some mixed kind of magic for tests.
|
||||
"""
|
||||
_GlobalNameSpace.SideEffectContainer.foo = 1
|
||||
side_effect = get_completion('SideEffectContainer', _GlobalNameSpace.__dict__)
|
||||
|
||||
# It's a class that contains MixedObject.
|
||||
assert isinstance(side_effect._definition.base, mixed.MixedObject)
|
||||
foo = get_completion('SideEffectContainer.foo', _GlobalNameSpace.__dict__)
|
||||
assert foo.name == 'foo'
|
||||
|
||||
|
||||
class TestInterpreterAPI(TestCase):
|
||||
def check_interpreter_complete(self, source, namespace, completions,
|
||||
**kwds):
|
||||
script = jedi.Interpreter(source, [namespace], **kwds)
|
||||
cs = script.completions()
|
||||
actual = [c.name for c in cs]
|
||||
self.assertEqual(sorted(actual), sorted(completions))
|
||||
|
||||
def test_complete_raw_function(self):
|
||||
from os.path import join
|
||||
self.check_interpreter_complete('join("").up',
|
||||
locals(),
|
||||
['upper'])
|
||||
|
||||
def test_complete_raw_function_different_name(self):
|
||||
from os.path import join as pjoin
|
||||
self.check_interpreter_complete('pjoin("").up',
|
||||
locals(),
|
||||
['upper'])
|
||||
|
||||
def test_complete_raw_module(self):
|
||||
import os
|
||||
self.check_interpreter_complete('os.path.join("a").up',
|
||||
locals(),
|
||||
['upper'])
|
||||
|
||||
def test_complete_raw_instance(self):
|
||||
import datetime
|
||||
dt = datetime.datetime(2013, 1, 1)
|
||||
completions = ['time', 'timetz', 'timetuple']
|
||||
if is_py33:
|
||||
completions += ['timestamp']
|
||||
self.check_interpreter_complete('(dt - dt).ti',
|
||||
locals(),
|
||||
completions)
|
||||
|
||||
def test_list(self):
|
||||
array = ['haha', 1]
|
||||
self.check_interpreter_complete('array[0].uppe',
|
||||
locals(),
|
||||
['upper'])
|
||||
self.check_interpreter_complete('array[0].real',
|
||||
locals(),
|
||||
[])
|
||||
|
||||
# something different, no index given, still just return the right
|
||||
self.check_interpreter_complete('array[int].real',
|
||||
locals(),
|
||||
['real'])
|
||||
self.check_interpreter_complete('array[int()].real',
|
||||
locals(),
|
||||
['real'])
|
||||
# inexistent index
|
||||
self.check_interpreter_complete('array[2].upper',
|
||||
locals(),
|
||||
['upper'])
|
||||
|
||||
def test_slice(self):
|
||||
class Foo():
|
||||
bar = []
|
||||
baz = 'xbarx'
|
||||
self.check_interpreter_complete('getattr(Foo, baz[1:-1]).append',
|
||||
locals(),
|
||||
['append'])
|
||||
|
||||
def test_getitem_side_effects(self):
|
||||
class Foo():
|
||||
def __getitem__(self, index):
|
||||
# possible side effects here, should therefore not call this.
|
||||
return index
|
||||
|
||||
foo = Foo()
|
||||
self.check_interpreter_complete('foo[0].', locals(), [])
|
||||
|
||||
def test_property_error(self):
|
||||
class Foo():
|
||||
@property
|
||||
def bar(self):
|
||||
raise ValueError
|
||||
|
||||
foo = Foo()
|
||||
self.check_interpreter_complete('foo.bar', locals(), ['bar'])
|
||||
self.check_interpreter_complete('foo.bar.baz', locals(), [])
|
||||
|
||||
def test_param_completion(self):
|
||||
def foo(bar):
|
||||
pass
|
||||
|
||||
lambd = lambda xyz: 3
|
||||
|
||||
self.check_interpreter_complete('foo(bar', locals(), ['bar'])
|
||||
# TODO we're not yet using the Python3.5 inspect.signature, yet.
|
||||
assert not jedi.Interpreter('lambd(xyz', [locals()]).completions()
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
All character set and unicode related tests.
|
||||
"""
|
||||
from jedi import Script
|
||||
from jedi._compatibility import u, unicode
|
||||
|
||||
|
||||
def test_unicode_script():
|
||||
""" normally no unicode objects are being used. (<=2.7) """
|
||||
s = unicode("import datetime; datetime.timedelta")
|
||||
completions = Script(s).completions()
|
||||
assert len(completions)
|
||||
assert type(completions[0].description) is unicode
|
||||
|
||||
s = u("author='öä'; author")
|
||||
completions = Script(s).completions()
|
||||
x = completions[0].description
|
||||
assert type(x) is unicode
|
||||
|
||||
s = u("#-*- coding: iso-8859-1 -*-\nauthor='öä'; author")
|
||||
s = s.encode('latin-1')
|
||||
completions = Script(s).completions()
|
||||
assert type(completions[0].description) is unicode
|
||||
|
||||
|
||||
def test_unicode_attribute():
|
||||
""" github jedi-vim issue #94 """
|
||||
s1 = u('#-*- coding: utf-8 -*-\nclass Person():\n'
|
||||
' name = "e"\n\nPerson().name.')
|
||||
completions1 = Script(s1).completions()
|
||||
assert 'strip' in [c.name for c in completions1]
|
||||
s2 = u('#-*- coding: utf-8 -*-\nclass Person():\n'
|
||||
' name = "é"\n\nPerson().name.')
|
||||
completions2 = Script(s2).completions()
|
||||
assert 'strip' in [c.name for c in completions2]
|
||||
|
||||
|
||||
def test_multibyte_script():
|
||||
""" `jedi.Script` must accept multi-byte string source. """
|
||||
try:
|
||||
code = u("import datetime; datetime.d")
|
||||
comment = u("# multi-byte comment あいうえおä")
|
||||
s = (u('%s\n%s') % (code, comment)).encode('utf-8')
|
||||
except NameError:
|
||||
pass # python 3 has no unicode method
|
||||
else:
|
||||
assert len(Script(s, 1, len(code)).completions())
|
||||
|
||||
|
||||
def test_goto_definition_at_zero():
|
||||
"""At zero usually sometimes raises unicode issues."""
|
||||
assert Script("a", 1, 1).goto_definitions() == []
|
||||
s = Script("str", 1, 1).goto_definitions()
|
||||
assert len(s) == 1
|
||||
assert list(s)[0].description == 'class str'
|
||||
assert Script("", 1, 0).goto_definitions() == []
|
||||
|
||||
|
||||
def test_complete_at_zero():
|
||||
s = Script("str", 1, 3).completions()
|
||||
assert len(s) == 1
|
||||
assert list(s)[0].name == 'str'
|
||||
|
||||
s = Script("", 1, 0).completions()
|
||||
assert len(s) > 0
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
import jedi
|
||||
|
||||
|
||||
def test_import_usage():
|
||||
s = jedi.Script("from .. import foo", line=1, column=18, path="foo.py")
|
||||
assert [usage.line for usage in s.usages()] == [1]
|
||||
109
vim-plugins/bundle/jedi-vim/jedi/test/test_cache.py
Normal file
109
vim-plugins/bundle/jedi-vim/jedi/test/test_cache.py
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
"""
|
||||
Test all things related to the ``jedi.cache`` module.
|
||||
"""
|
||||
|
||||
import time
|
||||
|
||||
import pytest
|
||||
|
||||
import jedi
|
||||
from jedi import settings, cache
|
||||
from jedi.parser.utils import ParserCacheItem, ParserPickling
|
||||
|
||||
|
||||
ParserPicklingCls = type(ParserPickling)
|
||||
ParserPickling = ParserPicklingCls()
|
||||
|
||||
|
||||
def test_modulepickling_change_cache_dir(monkeypatch, tmpdir):
|
||||
"""
|
||||
ParserPickling should not save old cache when cache_directory is changed.
|
||||
|
||||
See: `#168 <https://github.com/davidhalter/jedi/pull/168>`_
|
||||
"""
|
||||
dir_1 = str(tmpdir.mkdir('first'))
|
||||
dir_2 = str(tmpdir.mkdir('second'))
|
||||
|
||||
item_1 = ParserCacheItem('fake parser 1')
|
||||
item_2 = ParserCacheItem('fake parser 2')
|
||||
path_1 = 'fake path 1'
|
||||
path_2 = 'fake path 2'
|
||||
|
||||
monkeypatch.setattr(settings, 'cache_directory', dir_1)
|
||||
ParserPickling.save_parser(path_1, item_1)
|
||||
cached = load_stored_item(ParserPickling, path_1, item_1)
|
||||
assert cached == item_1.parser
|
||||
|
||||
monkeypatch.setattr(settings, 'cache_directory', dir_2)
|
||||
ParserPickling.save_parser(path_2, item_2)
|
||||
cached = load_stored_item(ParserPickling, path_1, item_1)
|
||||
assert cached is None
|
||||
|
||||
|
||||
def load_stored_item(cache, path, item):
|
||||
"""Load `item` stored at `path` in `cache`."""
|
||||
return cache.load_parser(path, item.change_time - 1)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("isolated_jedi_cache")
|
||||
def test_modulepickling_delete_incompatible_cache():
|
||||
item = ParserCacheItem('fake parser')
|
||||
path = 'fake path'
|
||||
|
||||
cache1 = ParserPicklingCls()
|
||||
cache1.version = 1
|
||||
cache1.save_parser(path, item)
|
||||
cached1 = load_stored_item(cache1, path, item)
|
||||
assert cached1 == item.parser
|
||||
|
||||
cache2 = ParserPicklingCls()
|
||||
cache2.version = 2
|
||||
cached2 = load_stored_item(cache2, path, item)
|
||||
assert cached2 is None
|
||||
|
||||
|
||||
@pytest.mark.skipif('True', message='Currently the star import cache is not enabled.')
|
||||
def test_star_import_cache_duration():
|
||||
new = 0.01
|
||||
old, jedi.settings.star_import_cache_validity = \
|
||||
jedi.settings.star_import_cache_validity, new
|
||||
|
||||
dct = cache._time_caches['star_import_cache_validity']
|
||||
old_dct = dict(dct)
|
||||
dct.clear() # first empty...
|
||||
# path needs to be not-None (otherwise caching effects are not visible)
|
||||
jedi.Script('', 1, 0, '').completions()
|
||||
time.sleep(2 * new)
|
||||
jedi.Script('', 1, 0, '').completions()
|
||||
|
||||
# reset values
|
||||
jedi.settings.star_import_cache_validity = old
|
||||
assert len(dct) == 1
|
||||
dct = old_dct
|
||||
cache._star_import_cache = {}
|
||||
|
||||
|
||||
def test_cache_call_signatures():
|
||||
"""
|
||||
See github issue #390.
|
||||
"""
|
||||
def check(column, call_name, path=None):
|
||||
assert jedi.Script(s, 1, column, path).call_signatures()[0].name == call_name
|
||||
|
||||
s = 'str(int())'
|
||||
|
||||
for i in range(3):
|
||||
check(8, 'int')
|
||||
check(4, 'str')
|
||||
# Can keep doing these calls and always get the right result.
|
||||
|
||||
# Now lets specify a source_path of boo and alternate these calls, it
|
||||
# should still work.
|
||||
for i in range(3):
|
||||
check(8, 'int', 'boo')
|
||||
check(4, 'str', 'boo')
|
||||
|
||||
|
||||
def test_cache_line_split_issues():
|
||||
"""Should still work even if there's a newline."""
|
||||
assert jedi.Script('int(\n').call_signatures()[0].name == 'int'
|
||||
9
vim-plugins/bundle/jedi-vim/jedi/test/test_debug.py
Normal file
9
vim-plugins/bundle/jedi-vim/jedi/test/test_debug.py
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import jedi
|
||||
from jedi import debug
|
||||
|
||||
def test_simple():
|
||||
jedi.set_debug_function()
|
||||
debug.speed('foo')
|
||||
debug.dbg('bar')
|
||||
debug.warning('baz')
|
||||
jedi.set_debug_function(None, False, False, False)
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
"""
|
||||
This is a module that imports the *standard library* unittest,
|
||||
despite there being a local "unittest" module. It specifies that it
|
||||
wants the stdlib one with the ``absolute_import`` __future__ import.
|
||||
|
||||
The twisted equivalent of this module is ``twisted.trial._synctest``.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class Assertions(unittest.TestCase):
|
||||
pass
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
"""
|
||||
This is a module that shadows a builtin (intentionally).
|
||||
|
||||
It imports a local module, which in turn imports stdlib unittest (the
|
||||
name shadowed by this module). If that is properly resolved, there's
|
||||
no problem. However, if jedi doesn't understand absolute_imports, it
|
||||
will get this module again, causing infinite recursion.
|
||||
"""
|
||||
from local_module import Assertions
|
||||
|
||||
|
||||
class TestCase(Assertions):
|
||||
def test(self):
|
||||
self.assertT
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
sys.path[0:0] = [
|
||||
'/usr/lib/python3.4/site-packages',
|
||||
'/tmp/.buildout/eggs/important_package.egg'
|
||||
]
|
||||
|
||||
import important_package
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(important_package.main())
|
||||
|
|
@ -0,0 +1 @@
|
|||
‰PNG
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue