Nothing + string literal should not result in string literal but in a string type (because we don't know how the string literal could have looked like

This commit is contained in:
Dave Halter
2014-04-22 15:16:48 +02:00
parent 77d505e251
commit b685101efb
2 changed files with 30 additions and 12 deletions

View File

@@ -6,7 +6,7 @@ from jedi._compatibility import unicode
from jedi.parser import representation as pr from jedi.parser import representation as pr
from jedi import debug from jedi import debug
from jedi.common import PushBackIterator from jedi.common import PushBackIterator
from jedi.evaluate.compiled import CompiledObject, create from jedi.evaluate.compiled import CompiledObject, create, builtin
class PythonGrammar(object): class PythonGrammar(object):
@@ -184,11 +184,19 @@ def calculate(evaluator, left_result, operator, right_result):
else: else:
if not left_result or not right_result: if not left_result or not right_result:
# illegal slices e.g. cause left/right_result to be None # illegal slices e.g. cause left/right_result to be None
return (left_result or []) + (right_result or []) result = (left_result or []) + (right_result or [])
for i, r in enumerate(result):
for left in left_result: if _is_number(r) or _is_string(r):
for right in right_result: print r, left_result, right_result
result += _element_calculate(evaluator, left, operator, right) # Literals are only valid as long as the operations are
# correct. Otherwise add a value-free instance.
cls = CompiledObject(type(r.obj), builtin)
from jedi.evaluate import representation as er
result[i] = er.Instance(evaluator, cls)
else:
for left in left_result:
for right in right_result:
result += _element_calculate(evaluator, left, operator, right)
return list(set(result)) return list(set(result))
@@ -204,18 +212,19 @@ def _is_number(obj):
and isinstance(obj.obj, (int, float)) and isinstance(obj.obj, (int, float))
def _element_calculate(evaluator, left, operator, right): def _is_string(obj):
def is_string(obj): return isinstance(obj, CompiledObject) \
return isinstance(obj, CompiledObject) \ and isinstance(obj.obj, (str, unicode))
and isinstance(obj.obj, (str, unicode))
def _element_calculate(evaluator, left, operator, right):
if operator == '*': if operator == '*':
# for iterables, ignore * operations # for iterables, ignore * operations
from jedi.evaluate import iterable from jedi.evaluate import iterable
if isinstance(left, iterable.Array) or is_string(left): if isinstance(left, iterable.Array) or _is_string(left):
return [left] return [left]
elif operator == '+': elif operator == '+':
if _is_number(left) and _is_number(right) or is_string(left) and is_string(right): if _is_number(left) and _is_number(right) or _is_string(left) and _is_string(right):
return [create(evaluator, left.obj + right.obj)] return [create(evaluator, left.obj + right.obj)]
elif operator == '-': elif operator == '-':
if _is_number(left) and _is_number(right): if _is_number(left) and _is_number(right):

View File

@@ -108,3 +108,12 @@ b[1]
z = sorted([1], key = lambda x : x): z = sorted([1], key = lambda x : x):
#? int() #? int()
z[0] z[0]
# -----------------
# undefined names
# -----------------
a = foobarbaz + 'hello'
#? int() float()
{'hello': 1, 'bar': 1.0}[a]