mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-07 14:34:31 +08:00
string literal handling
This commit is contained in:
@@ -1,5 +1,9 @@
|
|||||||
|
"""
|
||||||
# python2.5 compatibility
|
This is a compatibility module, to make it possible to use jedi also with older
|
||||||
|
python versions.
|
||||||
|
"""
|
||||||
|
# next was defined in python 2.6, in python 3 obj.next won't be possible
|
||||||
|
# anymore
|
||||||
try:
|
try:
|
||||||
next = next
|
next = next
|
||||||
except NameError:
|
except NameError:
|
||||||
@@ -14,3 +18,9 @@ except NameError:
|
|||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
return default
|
return default
|
||||||
|
|
||||||
|
# ast module was defined in python 2.6
|
||||||
|
try:
|
||||||
|
from ast import literal_eval
|
||||||
|
except ImportError:
|
||||||
|
literal_eval = eval
|
||||||
|
|||||||
31
evaluate.py
31
evaluate.py
@@ -11,7 +11,7 @@ TODO list comprehensions, priority?
|
|||||||
TODO care for *args **kwargs
|
TODO care for *args **kwargs
|
||||||
TODO annotations
|
TODO annotations
|
||||||
"""
|
"""
|
||||||
from _compatibility import next
|
from _compatibility import next, literal_eval
|
||||||
|
|
||||||
import itertools
|
import itertools
|
||||||
import copy
|
import copy
|
||||||
@@ -401,16 +401,35 @@ class Array(object):
|
|||||||
if index is not None:
|
if index is not None:
|
||||||
# This is indexing only one element, with a fixed index number,
|
# This is indexing only one element, with a fixed index number,
|
||||||
# otherwise it just ignores the index (e.g. [1+1])
|
# otherwise it just ignores the index (e.g. [1+1])
|
||||||
|
i = index.get_only_subelement().name
|
||||||
try:
|
try:
|
||||||
index_nr = int(index.get_only_subelement().name)
|
print 'index', i
|
||||||
values = [self._array[index_nr]]
|
return self.get_exact_index_types(i)
|
||||||
except:
|
except (IndexError, KeyError):
|
||||||
pass
|
pass
|
||||||
scope = self._array.parent_stmt.parent
|
return self.follow_values(values)
|
||||||
return follow_call_list(scope, values)
|
|
||||||
|
|
||||||
def get_exact_index_types(self, index):
|
def get_exact_index_types(self, index):
|
||||||
|
if self._array.type == parsing.Array.DICT:
|
||||||
|
old_index = index
|
||||||
|
index = None
|
||||||
|
for key_elements in self._array.keys:
|
||||||
|
# because we only want the key to be a string
|
||||||
|
if len(key_elements) == 1:
|
||||||
|
try:
|
||||||
|
str_key = key_elements[0].name
|
||||||
|
if old_index == str_key:
|
||||||
|
index = str_key.name
|
||||||
|
break
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
if index is None:
|
||||||
|
raise KeyError('No key found in dictionary')
|
||||||
values = [self._array[index]]
|
values = [self._array[index]]
|
||||||
|
return self.follow_values(values)
|
||||||
|
|
||||||
|
def follow_values(self, values):
|
||||||
|
""" helper function for the index getters """
|
||||||
scope = self._array.parent_stmt.parent
|
scope = self._array.parent_stmt.parent
|
||||||
return follow_call_list(scope, values)
|
return follow_call_list(scope, values)
|
||||||
|
|
||||||
|
|||||||
10
parsetest.py
10
parsetest.py
@@ -167,14 +167,16 @@ class C(object):
|
|||||||
test = [1,2]
|
test = [1,2]
|
||||||
|
|
||||||
|
|
||||||
def args_func(arg1, arg2=1, *args, **kwargs):
|
def fu(a=1, b="", *args, **kwargs):
|
||||||
return arg1, arg2, args, kwargs
|
return a, b, args, kwargs
|
||||||
|
|
||||||
exe = args_func(arg2=1,arg1=set)
|
exe = fu(arg2=1,arg1=set)
|
||||||
|
exe = fu(list, 1, "", c=set)
|
||||||
args_func() #1,"", a=list)[0].
|
args_func() #1,"", a=list)[0].
|
||||||
args_func(arg1=0, *test + [3], *[4,5], **{'a': 'b'}).
|
args_func(arg1=0, *test + [3], *[4,5], **{'a': 'b'}).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
exe[2][0].
|
||||||
|
exe[3]['c'].union
|
||||||
exe[0].
|
exe[0].
|
||||||
|
|||||||
18
parsing.py
18
parsing.py
@@ -31,7 +31,7 @@ Ignored statements:
|
|||||||
TODO take special care for future imports
|
TODO take special care for future imports
|
||||||
TODO check meta classes
|
TODO check meta classes
|
||||||
"""
|
"""
|
||||||
from _compatibility import next
|
from _compatibility import next, literal_eval
|
||||||
|
|
||||||
import tokenize
|
import tokenize
|
||||||
import cStringIO
|
import cStringIO
|
||||||
@@ -326,7 +326,7 @@ class Function(Scope):
|
|||||||
def get_set_vars(self):
|
def get_set_vars(self):
|
||||||
n = super(Function, self).get_set_vars()
|
n = super(Function, self).get_set_vars()
|
||||||
if self.param_cb:
|
if self.param_cb:
|
||||||
# this is the really ugly part, where the functional style of this
|
# This is the really ugly part, where the functional style of this
|
||||||
# get methods is broken, it executes a callback.
|
# get methods is broken, it executes a callback.
|
||||||
# This is important, because something has to inject the params
|
# This is important, because something has to inject the params
|
||||||
# into the functions, with the right values.
|
# into the functions, with the right values.
|
||||||
@@ -614,13 +614,15 @@ class Statement(Simple):
|
|||||||
is_call = lambda: result.__class__ == Call
|
is_call = lambda: result.__class__ == Call
|
||||||
is_call_or_close = lambda: is_call() or close_brackets
|
is_call_or_close = lambda: is_call() or close_brackets
|
||||||
|
|
||||||
if isinstance(tok, Name) or token_type in [tokenize.STRING,
|
is_literal = token_type in [tokenize.STRING, tokenize.NUMBER]
|
||||||
tokenize.NUMBER]: # names
|
if isinstance(tok, Name) or is_literal:
|
||||||
c_type = Call.NAME
|
c_type = Call.NAME
|
||||||
if token_type == tokenize.STRING:
|
if is_literal:
|
||||||
c_type = Call.STRING
|
tok = literal_eval(tok)
|
||||||
elif token_type == tokenize.NUMBER:
|
if token_type == tokenize.STRING:
|
||||||
c_type = Call.NUMBER
|
c_type = Call.STRING
|
||||||
|
elif token_type == tokenize.NUMBER:
|
||||||
|
c_type = Call.NUMBER
|
||||||
|
|
||||||
if is_chain:
|
if is_chain:
|
||||||
call = Call(tok, c_type, self, result)
|
call = Call(tok, c_type, self, result)
|
||||||
|
|||||||
@@ -119,6 +119,12 @@ g1.
|
|||||||
# -----------------
|
# -----------------
|
||||||
# dicts
|
# dicts
|
||||||
# -----------------
|
# -----------------
|
||||||
dic2 = {'asdf': 3}
|
dic2 = {'asdf': 3, 'b': 'str'}
|
||||||
#? ['real']
|
#? ['real']
|
||||||
dic2['asdf'].real
|
dic2['asdf'].real
|
||||||
|
#? []
|
||||||
|
dic2['asdf'].upper
|
||||||
|
#? ['real']
|
||||||
|
dic2[r'asdf'].real
|
||||||
|
#? []
|
||||||
|
dic2[r'asdf'].upper
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ exe.items
|
|||||||
# -----------------
|
# -----------------
|
||||||
|
|
||||||
def fu(a=1, b="", *args, **kwargs):
|
def fu(a=1, b="", *args, **kwargs):
|
||||||
return a,b,args,kwargs
|
return a, b, args, kwargs
|
||||||
|
|
||||||
exe = fu(list, 1, "", c=set)
|
exe = fu(list, 1, "", c=set)
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ def completion_test(source):
|
|||||||
try:
|
try:
|
||||||
completions = functions.complete(source, line_nr, 999,
|
completions = functions.complete(source, line_nr, 999,
|
||||||
completion_test_dir)
|
completion_test_dir)
|
||||||
except:
|
except Exception:
|
||||||
print 'test @%s: %s' % (line_nr-1, line)
|
print 'test @%s: %s' % (line_nr-1, line)
|
||||||
print traceback.format_exc()
|
print traceback.format_exc()
|
||||||
fails += 1
|
fails += 1
|
||||||
|
|||||||
Reference in New Issue
Block a user