forked from VimPlug/jedi
Use unicode in way more cases
This commit is contained in:
@@ -324,9 +324,9 @@ class BaseDefinition(object):
|
|||||||
param_names = param_names[1:]
|
param_names = param_names[1:]
|
||||||
elif isinstance(context, (instance.AbstractInstanceContext, ClassContext)):
|
elif isinstance(context, (instance.AbstractInstanceContext, ClassContext)):
|
||||||
if isinstance(context, ClassContext):
|
if isinstance(context, ClassContext):
|
||||||
search = '__init__'
|
search = u'__init__'
|
||||||
else:
|
else:
|
||||||
search = '__call__'
|
search = u'__call__'
|
||||||
names = context.get_function_slot_names(search)
|
names = context.get_function_slot_names(search)
|
||||||
if not names:
|
if not names:
|
||||||
return []
|
return []
|
||||||
|
|||||||
@@ -117,8 +117,8 @@ def add_attribute_error(name_context, lookup_context, name):
|
|||||||
# instead of an error, if that happens.
|
# instead of an error, if that happens.
|
||||||
typ = Error
|
typ = Error
|
||||||
if isinstance(lookup_context, AbstractInstanceContext):
|
if isinstance(lookup_context, AbstractInstanceContext):
|
||||||
slot_names = lookup_context.get_function_slot_names('__getattr__') + \
|
slot_names = lookup_context.get_function_slot_names(u'__getattr__') + \
|
||||||
lookup_context.get_function_slot_names('__getattribute__')
|
lookup_context.get_function_slot_names(u'__getattribute__')
|
||||||
for n in slot_names:
|
for n in slot_names:
|
||||||
# TODO do we even get here?
|
# TODO do we even get here?
|
||||||
if isinstance(name, CompiledInstanceName) and \
|
if isinstance(name, CompiledInstanceName) and \
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class CheckAttribute(object):
|
|||||||
def __init__(self, func):
|
def __init__(self, func):
|
||||||
self.func = func
|
self.func = func
|
||||||
# Remove the py in front of e.g. py__call__.
|
# Remove the py in front of e.g. py__call__.
|
||||||
self.check_name = func.__name__[2:]
|
self.check_name = force_unicode(func.__name__[2:])
|
||||||
|
|
||||||
def __get__(self, instance, owner):
|
def __get__(self, instance, owner):
|
||||||
if instance is None:
|
if instance is None:
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import weakref
|
|||||||
import pickle
|
import pickle
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from jedi._compatibility import queue, is_py3
|
from jedi._compatibility import queue, is_py3, force_unicode
|
||||||
from jedi.cache import memoize_method
|
from jedi.cache import memoize_method
|
||||||
from jedi.evaluate.compiled.subprocess import functions
|
from jedi.evaluate.compiled.subprocess import functions
|
||||||
from jedi.evaluate.compiled.access import DirectObjectAccess, AccessPath, \
|
from jedi.evaluate.compiled.access import DirectObjectAccess, AccessPath, \
|
||||||
@@ -286,7 +286,7 @@ class AccessHandle(object):
|
|||||||
|
|
||||||
#if not is_py3: print >> sys.stderr, name
|
#if not is_py3: print >> sys.stderr, name
|
||||||
#print('getattr', name, file=sys.stderr)
|
#print('getattr', name, file=sys.stderr)
|
||||||
return partial(self._workaround, name)
|
return partial(self._workaround, force_unicode(name))
|
||||||
|
|
||||||
def _workaround(self, name, *args, **kwargs):
|
def _workaround(self, name, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
@@ -294,6 +294,9 @@ class AccessHandle(object):
|
|||||||
happen. They are also the only unhashable objects that we're passing
|
happen. They are also the only unhashable objects that we're passing
|
||||||
around.
|
around.
|
||||||
"""
|
"""
|
||||||
|
# Python 2 compatibility
|
||||||
|
kwargs = {force_unicode(key): value for key, value in kwargs.items()}
|
||||||
|
|
||||||
if args and isinstance(args[0], slice):
|
if args and isinstance(args[0], slice):
|
||||||
return self._subprocess.get_compiled_method_return(self.id, name, *args, **kwargs)
|
return self._subprocess.get_compiled_method_return(self.id, name, *args, **kwargs)
|
||||||
return self._cached_results(name, *args, **kwargs)
|
return self._cached_results(name, *args, **kwargs)
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class AbstractInstanceContext(Context):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def py__call__(self):
|
def py__call__(self):
|
||||||
names = self.get_function_slot_names('__call__')
|
names = self.get_function_slot_names(u'__call__')
|
||||||
if not names:
|
if not names:
|
||||||
# Means the Instance is not callable.
|
# Means the Instance is not callable.
|
||||||
raise AttributeError
|
raise AttributeError
|
||||||
@@ -89,7 +89,7 @@ class AbstractInstanceContext(Context):
|
|||||||
def py__get__(self, obj):
|
def py__get__(self, obj):
|
||||||
# Arguments in __get__ descriptors are obj, class.
|
# Arguments in __get__ descriptors are obj, class.
|
||||||
# `method` is the new parent of the array, don't know if that's good.
|
# `method` is the new parent of the array, don't know if that's good.
|
||||||
names = self.get_function_slot_names('__get__')
|
names = self.get_function_slot_names(u'__get__')
|
||||||
if names:
|
if names:
|
||||||
if isinstance(obj, AbstractInstanceContext):
|
if isinstance(obj, AbstractInstanceContext):
|
||||||
return self.execute_function_slots(names, obj, obj.class_context)
|
return self.execute_function_slots(names, obj, obj.class_context)
|
||||||
@@ -118,7 +118,7 @@ class AbstractInstanceContext(Context):
|
|||||||
|
|
||||||
def py__getitem__(self, index):
|
def py__getitem__(self, index):
|
||||||
try:
|
try:
|
||||||
names = self.get_function_slot_names('__getitem__')
|
names = self.get_function_slot_names(u'__getitem__')
|
||||||
except KeyError:
|
except KeyError:
|
||||||
debug.warning('No __getitem__, cannot access the array.')
|
debug.warning('No __getitem__, cannot access the array.')
|
||||||
return NO_CONTEXTS
|
return NO_CONTEXTS
|
||||||
@@ -127,7 +127,7 @@ class AbstractInstanceContext(Context):
|
|||||||
return self.execute_function_slots(names, index_obj)
|
return self.execute_function_slots(names, index_obj)
|
||||||
|
|
||||||
def py__iter__(self):
|
def py__iter__(self):
|
||||||
iter_slot_names = self.get_function_slot_names('__iter__')
|
iter_slot_names = self.get_function_slot_names(u'__iter__')
|
||||||
if not iter_slot_names:
|
if not iter_slot_names:
|
||||||
debug.warning('No __iter__ on %s.' % self)
|
debug.warning('No __iter__ on %s.' % self)
|
||||||
return
|
return
|
||||||
@@ -136,9 +136,9 @@ class AbstractInstanceContext(Context):
|
|||||||
if isinstance(generator, AbstractInstanceContext):
|
if isinstance(generator, AbstractInstanceContext):
|
||||||
# `__next__` logic.
|
# `__next__` logic.
|
||||||
if self.evaluator.environment.version_info.major == 2:
|
if self.evaluator.environment.version_info.major == 2:
|
||||||
name = 'next'
|
name = u'next'
|
||||||
else:
|
else:
|
||||||
name = '__next__'
|
name = u'__next__'
|
||||||
iter_slot_names = generator.get_function_slot_names(name)
|
iter_slot_names = generator.get_function_slot_names(name)
|
||||||
if iter_slot_names:
|
if iter_slot_names:
|
||||||
yield LazyKnownContexts(
|
yield LazyKnownContexts(
|
||||||
@@ -166,7 +166,7 @@ class AbstractInstanceContext(Context):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def create_init_executions(self):
|
def create_init_executions(self):
|
||||||
for name in self.get_function_slot_names('__init__'):
|
for name in self.get_function_slot_names(u'__init__'):
|
||||||
if isinstance(name, SelfName):
|
if isinstance(name, SelfName):
|
||||||
yield self._create_init_execution(name.class_context, name.tree_name.parent)
|
yield self._create_init_execution(name.class_context, name.tree_name.parent)
|
||||||
|
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ class ClassContext(use_metaclass(CachedMetaClass, TreeContext)):
|
|||||||
args = arguments.TreeArguments(self.evaluator, self, arglist)
|
args = arguments.TreeArguments(self.evaluator, self, arglist)
|
||||||
return [value for key, value in args.unpack() if key is None]
|
return [value for key, value in args.unpack() if key is None]
|
||||||
else:
|
else:
|
||||||
return [LazyKnownContext(compiled.builtin_from_name(self.evaluator, 'object'))]
|
return [LazyKnownContext(compiled.builtin_from_name(self.evaluator, u'object'))]
|
||||||
|
|
||||||
def py__call__(self, params):
|
def py__call__(self, params):
|
||||||
from jedi.evaluate.context import TreeInstance
|
from jedi.evaluate.context import TreeInstance
|
||||||
@@ -182,7 +182,7 @@ class ClassContext(use_metaclass(CachedMetaClass, TreeContext)):
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
def get_param_names(self):
|
def get_param_names(self):
|
||||||
for name in self.get_function_slot_names('__init__'):
|
for name in self.get_function_slot_names(u'__init__'):
|
||||||
for context_ in name.infer():
|
for context_ in name.infer():
|
||||||
try:
|
try:
|
||||||
method = context_.get_param_names
|
method = context_.get_param_names
|
||||||
|
|||||||
@@ -149,8 +149,8 @@ class NameFinder(object):
|
|||||||
# We are inversing this, because a hand-crafted `__getattribute__`
|
# We are inversing this, because a hand-crafted `__getattribute__`
|
||||||
# could still call another hand-crafted `__getattr__`, but not the
|
# could still call another hand-crafted `__getattr__`, but not the
|
||||||
# other way around.
|
# other way around.
|
||||||
names = (inst.get_function_slot_names('__getattr__') or
|
names = (inst.get_function_slot_names(u'__getattr__') or
|
||||||
inst.get_function_slot_names('__getattribute__'))
|
inst.get_function_slot_names(u'__getattribute__'))
|
||||||
return inst.execute_function_slots(names, name)
|
return inst.execute_function_slots(names, name)
|
||||||
|
|
||||||
def _names_to_types(self, names, attribute_lookup):
|
def _names_to_types(self, names, attribute_lookup):
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import copy
|
|||||||
|
|
||||||
from parso.python import tree
|
from parso.python import tree
|
||||||
|
|
||||||
|
from jedi._compatibility import force_unicode
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi import parser_utils
|
from jedi import parser_utils
|
||||||
from jedi.evaluate.base_context import ContextSet, NO_CONTEXTS, ContextualizedNode, \
|
from jedi.evaluate.base_context import ContextSet, NO_CONTEXTS, ContextualizedNode, \
|
||||||
@@ -367,40 +368,41 @@ def _bool_to_context(evaluator, bool_):
|
|||||||
def _eval_comparison_part(evaluator, context, left, operator, right):
|
def _eval_comparison_part(evaluator, context, left, operator, right):
|
||||||
l_is_num = is_number(left)
|
l_is_num = is_number(left)
|
||||||
r_is_num = is_number(right)
|
r_is_num = is_number(right)
|
||||||
if operator == '*':
|
str_operator = force_unicode(str(operator.value))
|
||||||
|
if str_operator == '*':
|
||||||
# for iterables, ignore * operations
|
# for iterables, ignore * operations
|
||||||
if isinstance(left, iterable.AbstractIterable) or is_string(left):
|
if isinstance(left, iterable.AbstractIterable) or is_string(left):
|
||||||
return ContextSet(left)
|
return ContextSet(left)
|
||||||
elif isinstance(right, iterable.AbstractIterable) or is_string(right):
|
elif isinstance(right, iterable.AbstractIterable) or is_string(right):
|
||||||
return ContextSet(right)
|
return ContextSet(right)
|
||||||
elif operator == '+':
|
elif str_operator == '+':
|
||||||
if l_is_num and r_is_num or is_string(left) and is_string(right):
|
if l_is_num and r_is_num or is_string(left) and is_string(right):
|
||||||
return ContextSet(left.execute_operation(right, operator))
|
return ContextSet(left.execute_operation(right, str_operator))
|
||||||
elif _is_tuple(left) and _is_tuple(right) or _is_list(left) and _is_list(right):
|
elif _is_tuple(left) and _is_tuple(right) or _is_list(left) and _is_list(right):
|
||||||
return ContextSet(iterable.MergedArray(evaluator, (left, right)))
|
return ContextSet(iterable.MergedArray(evaluator, (left, right)))
|
||||||
elif operator == '-':
|
elif str_operator == '-':
|
||||||
if l_is_num and r_is_num:
|
if l_is_num and r_is_num:
|
||||||
return ContextSet(left.execute_operation(right, operator))
|
return ContextSet(left.execute_operation(right, str_operator))
|
||||||
elif operator == '%':
|
elif str_operator == '%':
|
||||||
# With strings and numbers the left type typically remains. Except for
|
# With strings and numbers the left type typically remains. Except for
|
||||||
# `int() % float()`.
|
# `int() % float()`.
|
||||||
return ContextSet(left)
|
return ContextSet(left)
|
||||||
elif operator in COMPARISON_OPERATORS:
|
elif str_operator in COMPARISON_OPERATORS:
|
||||||
if is_compiled(left) and is_compiled(right):
|
if is_compiled(left) and is_compiled(right):
|
||||||
# Possible, because the return is not an option. Just compare.
|
# Possible, because the return is not an option. Just compare.
|
||||||
try:
|
try:
|
||||||
return ContextSet(left.execute_operation(right, operator))
|
return ContextSet(left.execute_operation(right, str_operator))
|
||||||
except TypeError:
|
except TypeError:
|
||||||
# Could be True or False.
|
# Could be True or False.
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
if operator in ('is', '!=', '==', 'is not'):
|
if str_operator in ('is', '!=', '==', 'is not'):
|
||||||
operation = COMPARISON_OPERATORS[operator]
|
operation = COMPARISON_OPERATORS[str_operator]
|
||||||
bool_ = operation(left, right)
|
bool_ = operation(left, right)
|
||||||
return ContextSet(_bool_to_context(evaluator, bool_))
|
return ContextSet(_bool_to_context(evaluator, bool_))
|
||||||
|
|
||||||
return ContextSet(_bool_to_context(evaluator, True), _bool_to_context(evaluator, False))
|
return ContextSet(_bool_to_context(evaluator, True), _bool_to_context(evaluator, False))
|
||||||
elif operator == 'in':
|
elif str_operator == 'in':
|
||||||
return NO_CONTEXTS
|
return NO_CONTEXTS
|
||||||
|
|
||||||
def check(obj):
|
def check(obj):
|
||||||
@@ -409,7 +411,7 @@ def _eval_comparison_part(evaluator, context, left, operator, right):
|
|||||||
obj.name.string_name in ('int', 'float')
|
obj.name.string_name in ('int', 'float')
|
||||||
|
|
||||||
# Static analysis, one is a number, the other one is not.
|
# Static analysis, one is a number, the other one is not.
|
||||||
if operator in ('+', '-') and l_is_num != r_is_num \
|
if str_operator in ('+', '-') and l_is_num != r_is_num \
|
||||||
and not (check(left) or check(right)):
|
and not (check(left) or check(right)):
|
||||||
message = "TypeError: unsupported operand type(s) for +: %s and %s"
|
message = "TypeError: unsupported operand type(s) for +: %s and %s"
|
||||||
analysis.add(context, 'type-error-operation', operator,
|
analysis.add(context, 'type-error-operation', operator,
|
||||||
|
|||||||
Reference in New Issue
Block a user