diff --git a/jedi/api/__init__.py b/jedi/api/__init__.py index ba8b5ed6..75502259 100644 --- a/jedi/api/__init__.py +++ b/jedi/api/__init__.py @@ -444,7 +444,7 @@ class Script(object): import_name = user_stmt.get_defined_names() # imports have only one name if not user_stmt.star \ - and name_part == import_name[0].names[-1]: + and unicode(name_part) == unicode(import_name[0].names[-1]): definitions.append(import_name[0]) else: stmt = self._get_under_cursor_stmt(goto_path) @@ -458,7 +458,7 @@ class Script(object): for name in user_stmt.get_defined_names(): if name.start_pos <= self._pos <= name.end_pos \ and len(name.names) == 1: - return name, name.names[-1] + return name, unicode(name.names[-1]) return None, None lhs, search_name = test_lhs() @@ -474,7 +474,8 @@ class Script(object): else: call_path = [call] - defs, search_name = self._evaluator.goto(stmt, call_path) + defs, search_name_part = self._evaluator.goto(stmt, call_path) + search_name = unicode(search_name_part) definitions = follow_inexistent_imports(defs) else: definitions = [lhs] @@ -519,7 +520,7 @@ class Script(object): for d in set(definitions): if isinstance(d, (pr.Module, compiled.CompiledObject)): - names.append(usages.Usage(self._evaluator, d, d)) + names.append(usages.Usage(self._evaluator, d)) elif isinstance(d, er.Instance): # Instances can be ignored, because they have been created by # ``__getattr__``. diff --git a/jedi/api/usages.py b/jedi/api/usages.py index d93e247f..cfeb7710 100644 --- a/jedi/api/usages.py +++ b/jedi/api/usages.py @@ -1,3 +1,4 @@ +from jedi._compatibility import unicode from jedi import common from jedi.api import classes from jedi.parser import representation as pr @@ -7,17 +8,9 @@ from jedi.evaluate import helpers class Usage(classes.Definition): """TODO: document this""" - def __init__(self, evaluator, name_part, scope): + def __init__(self, evaluator, name_part, scope=None): super(Usage, self).__init__(evaluator, name_part) self._start_pos = name_part.start_pos - #self.end_pos = name_part.end_pos - - def __eq__(self, other): - return self._start_pos == other._start_pos \ - and self.module_path == other.module_path - - def __hash__(self): - return hash((self._start_pos, self.module_path)) def usages(evaluator, definitions, search_name, mods): @@ -47,7 +40,7 @@ def usages(evaluator, definitions, search_name, mods): call_path = list(call.generate_call_path()) for i, name in enumerate(call_path): # name is `pr.NamePart`. - if name == search_name: + if unicode(name) == search_name: follow.append(call_path[:i + 1]) for call_path in follow: @@ -74,7 +67,7 @@ def usages(evaluator, definitions, search_name, mods): compare_definitions = compare_array(definitions) mods |= set([d.get_parent_until() for d in definitions]) names = [] - for m in imports.get_modules_containing_name(mods, str(search_name)): + for m in imports.get_modules_containing_name(mods, search_name): try: stmts = m.used_names[search_name] except KeyError: @@ -86,7 +79,7 @@ def usages(evaluator, definitions, search_name, mods): for i in stmt.get_all_import_names(): for name_part in i.names: count += 1 - if name_part == search_name: + if unicode(name_part) == search_name: imps.append((count, name_part)) for used_count, name_part in imps: diff --git a/jedi/evaluate/__init__.py b/jedi/evaluate/__init__.py index 4713253a..3feb4491 100644 --- a/jedi/evaluate/__init__.py +++ b/jedi/evaluate/__init__.py @@ -334,7 +334,7 @@ class Evaluator(object): def goto(self, stmt, call_path): scope = stmt.get_parent_until(pr.IsScope) pos = stmt.start_pos - call_path, search = call_path[:-1], call_path[-1] + call_path, search_name_part = call_path[:-1], call_path[-1] if call_path: scopes = self.eval_call_path(iter(call_path), scope, pos) @@ -346,9 +346,9 @@ class Evaluator(object): search_global = True follow_res = [] for s in scopes: - follow_res += self.find_types(s, search, pos, + follow_res += self.find_types(s, search_name_part, pos, search_global=search_global, is_goto=True) - return follow_res, search + return follow_res, search_name_part def filter_private_variable(scope, call_scope, var_name): diff --git a/jedi/evaluate/dynamic.py b/jedi/evaluate/dynamic.py index 48cba7f3..74c59563 100644 --- a/jedi/evaluate/dynamic.py +++ b/jedi/evaluate/dynamic.py @@ -17,6 +17,7 @@ It works as follows: - execute these calls and check the input. This work with a ``ParamListener``. """ +from jedi._compatibility import unicode from jedi.parser import representation as pr from jedi import settings from jedi.evaluate import helpers @@ -86,9 +87,11 @@ def search_params(evaluator, param): # Need to take right index, because there could be a # func usage before. - i = listRightIndex(call_path, func_name) + call_path_simple = [unicode(d) if isinstance(d, pr.NamePart) + else d for d in call_path] + i = listRightIndex(call_path_simple, func_name) first, last = call_path[:i], call_path[i + 1:] - if not last and not call_path.index(func_name) != i: + if not last and not call_path_simple.index(func_name) != i: continue scopes = [scope] if first: @@ -119,10 +122,10 @@ def search_params(evaluator, param): func = param.get_parent_until(pr.Function) current_module = param.get_parent_until() - func_name = str(func.name) + func_name = unicode(func.name) compare = func if func_name == '__init__' and isinstance(func.parent, pr.Class): - func_name = str(func.parent.name) + func_name = unicode(func.parent.name) compare = func.parent # get the param name diff --git a/jedi/evaluate/finder.py b/jedi/evaluate/finder.py index 8bafe44f..1fdb1cf1 100644 --- a/jedi/evaluate/finder.py +++ b/jedi/evaluate/finder.py @@ -69,7 +69,7 @@ class NameFinder(object): # reference. name_list = sorted(name_list, key=lambda n: n.start_pos, reverse=True) for name in name_list: - if self.name_str != name.get_code(): + if unicode(self.name_str) != name.get_code(): continue parpar = name.parent.parent @@ -297,7 +297,7 @@ class NameFinder(object): return result -def check_flow_information(evaluator, flow, search_name, pos): +def check_flow_information(evaluator, flow, search_name_part, pos): """ Try to find out the type of a variable just with the information that is given by the flows: e.g. It is also responsible for assert checks.:: @@ -314,17 +314,17 @@ def check_flow_information(evaluator, flow, search_name, pos): for ass in reversed(flow.asserts): if pos is None or ass.start_pos > pos: continue - result = _check_isinstance_type(evaluator, ass, search_name) + result = _check_isinstance_type(evaluator, ass, search_name_part) if result: break if isinstance(flow, pr.Flow) and not result: if flow.command in ['if', 'while'] and len(flow.inputs) == 1: - result = _check_isinstance_type(evaluator, flow.inputs[0], search_name) + result = _check_isinstance_type(evaluator, flow.inputs[0], search_name_part) return result -def _check_isinstance_type(evaluator, stmt, search_name): +def _check_isinstance_type(evaluator, stmt, search_name_part): try: expression_list = stmt.expression_list() # this might be removed if we analyze and, etc @@ -342,7 +342,7 @@ def _check_isinstance_type(evaluator, stmt, search_name): assert isinstance(obj[0], pr.Call) # names fit? - assert str(obj[0].name) == search_name + assert unicode(obj[0].name) == unicode(search_name_part) assert isinstance(classes[0], pr.StatementElement) # can be type or tuple except AssertionError: return [] @@ -530,7 +530,7 @@ def find_assignments(lhs, results, seek_name): """ if isinstance(lhs, pr.Array): return _assign_tuples(lhs, results, seek_name) - elif lhs.name.names[-1] == seek_name: + elif unicode(lhs.name.names[-1]) == unicode(seek_name): return results else: return [] diff --git a/jedi/evaluate/helpers.py b/jedi/evaluate/helpers.py index 05361cb9..de1db1e0 100644 --- a/jedi/evaluate/helpers.py +++ b/jedi/evaluate/helpers.py @@ -148,7 +148,8 @@ def scan_statement_for_calls(stmt, search_name, assignment_details=False): s_new = c while s_new is not None: n = s_new.name - if isinstance(n, pr.Name) and search_name in n.names: + if isinstance(n, pr.Name) \ + and search_name in [str(x) for x in n.names]: result.append(c) if s_new.execution is not None: diff --git a/jedi/evaluate/iterable.py b/jedi/evaluate/iterable.py index 75a03b9b..0861e953 100644 --- a/jedi/evaluate/iterable.py +++ b/jedi/evaluate/iterable.py @@ -276,8 +276,10 @@ def _check_array_additions(evaluator, compare_array, module, is_list): result = [] for c in calls: call_path = list(c.generate_call_path()) - separate_index = call_path.index(add_name) - if add_name == call_path[-1] or separate_index == 0: + call_path_simple = [unicode(n) if isinstance(n, pr.NamePart) else n + for n in call_path] + separate_index = call_path_simple.index(add_name) + if add_name == call_path_simple[-1] or separate_index == 0: # this means that there is no execution -> [].append # or the keyword is at the start -> append() continue diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index f1961cb3..93445e76 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -113,7 +113,7 @@ class Instance(use_metaclass(CachedMetaClass, Executable)): # Only names with the selfname are being added. # It is also important, that they have a len() of 2, # because otherwise, they are just something else - if n.names[0] == self_name and len(n.names) == 2: + if unicode(n.names[0]) == self_name and len(n.names) == 2: add_self_dot_name(n) if not isinstance(self.base, compiled.CompiledObject): @@ -278,7 +278,7 @@ class Class(use_metaclass(CachedMetaClass, pr.IsScope)): for i in iterable: # Only the last name is important, because these names have a # maximal length of 2, with the first one being `self`. - if i.names[-1] == name.names[-1]: + if unicode(i.names[-1]) == unicode(name.names[-1]): return True return False diff --git a/jedi/evaluate/sys_path.py b/jedi/evaluate/sys_path.py index 48a9fbf0..2390fd1b 100644 --- a/jedi/evaluate/sys_path.py +++ b/jedi/evaluate/sys_path.py @@ -1,7 +1,7 @@ import os import sys -from jedi._compatibility import exec_function +from jedi._compatibility import exec_function, unicode from jedi.parser import representation as pr from jedi import debug from jedi import common @@ -59,9 +59,9 @@ def sys_path_with_modifications(module): n = call.name if not isinstance(n, pr.Name) or len(n.names) != 3: continue - if n.names[:2] != ('sys', 'path'): + if [unicode(x) for x in n.names[:2]] != ['sys', 'path']: continue - array_cmd = n.names[2] + array_cmd = unicode(n.names[2]) if call.execution is None: continue exe = call.execution diff --git a/jedi/parser/__init__.py b/jedi/parser/__init__.py index ee5de4e7..111abc1c 100644 --- a/jedi/parser/__init__.py +++ b/jedi/parser/__init__.py @@ -17,7 +17,7 @@ complexity of the ``Parser`` (there's another parser sitting inside """ import keyword -from jedi._compatibility import next +from jedi._compatibility import next, unicode from jedi import debug from jedi import common from jedi.parser import representation as pr @@ -480,7 +480,7 @@ class Parser(object): self._gen.push_last_back() names = self._parse_import_list() for count, (name, alias, defunct2) in enumerate(names): - star = name is not None and name.names[0] == '*' + star = name is not None and unicode(name.names[0]) == '*' if star: name = None e = (alias or name or self._gen.previous).end_pos diff --git a/jedi/parser/representation.py b/jedi/parser/representation.py index d12b42fb..80000b11 100644 --- a/jedi/parser/representation.py +++ b/jedi/parser/representation.py @@ -429,7 +429,7 @@ class SubModule(Scope, Module): continue namespace, feature = imp.from_ns.names[0], imp.namespace.names[0] - if namespace == "__future__" and feature == "absolute_import": + if unicode(namespace) == "__future__" and unicode(feature) == "absolute_import": return True return False @@ -476,7 +476,7 @@ class Class(Scope): if self._doc_token is not None: docstr = self.raw_doc for sub in self.subscopes: - if sub.name.names[-1] == '__init__': + if unicode(sub.name.names[-1]) == '__init__': return '%s\n\n%s' % ( sub.get_call_signature(funcname=self.name.names[-1]), docstr) return docstr @@ -760,7 +760,7 @@ class Import(Simple): return [self.alias] if len(self.namespace) > 1: o = self.namespace - n = Name(self._sub_module, [(o.names[0].string, o.start_pos)], + n = Name(self._sub_module, [(unicode(o.names[0]), o.start_pos)], o.start_pos, o.end_pos, parent=o.parent) return [n] else: @@ -1383,18 +1383,12 @@ class NamePart(object): def __str__(self): return self.string + def __unicode__(self): + return self.string + def __repr__(self): return "<%s: %s>" % (type(self).__name__, self.string) - def __eq__(self, other): - return self.string == other - - def __ne__(self, other): - return not self.__eq__(other) - - def __hash__(self): - return hash(self.string) - def get_parent_until(self, *args, **kwargs): return self.parent.get_parent_until(*args, **kwargs)