summaryrefslogtreecommitdiff
path: root/Tools
diff options
context:
space:
mode:
Diffstat (limited to 'Tools')
-rw-r--r--Tools/jedi-typer.py87
1 files changed, 59 insertions, 28 deletions
diff --git a/Tools/jedi-typer.py b/Tools/jedi-typer.py
index 576511726..668449305 100644
--- a/Tools/jedi-typer.py
+++ b/Tools/jedi-typer.py
@@ -6,9 +6,18 @@ from __future__ import absolute_import
from io import open
from collections import defaultdict
-
-from jedi import Script
-from jedi.parser.representation import Function, Module, Import
+from itertools import chain
+import re
+
+import jedi
+if list(map(int, re.findall('[0-9]+', jedi.__version__ or '0'))) >= [0, 9, 0]:
+ __jedi_version__ = 9
+ from jedi.parser.tree import Module, Module as Import
+ from jedi.evaluate.representation import Function, Instance
+else:
+ __jedi_version__ = 8
+ from jedi import Script
+ from jedi.parser.representation import Function, Module, Import
from Cython.Utils import open_source_file
@@ -26,33 +35,54 @@ def analyse(source_path=None, code=None):
"""
if not source_path and code is None:
raise ValueError("Either 'source_path' or 'code' is required.")
- script = Script(source=code, path=source_path)
- evaluator = script._evaluator
scoped_names = {}
- for statements in script._parser.module().used_names.values():
- for statement in statements:
- scope = statement.parent
+ if __jedi_version__ == 8:
+ script = Script(source=code, path=source_path)
+ evaluator = script._evaluator
+ statement_iter = chain.from_iterable(script._parser.module().used_names.values())
+ else:
+ statement_iter = jedi.names(source=code, path=source_path, all_scopes=True)
+ for statement in statement_iter:
+ if __jedi_version__ == 8:
+ parent = scope = statement.parent
while not isinstance(scope, (Function, Module)):
- scope = scope.parent
+ parent = scope = scope.parent
# hack: work around current Jedi problem with global module variables
if not hasattr(scope, 'scope_names_generator'):
continue
statement_names = statement.get_defined_names()
if not statement_names:
continue
- key = (None if isinstance(scope, Module) else str(scope.name), scope.start_pos)
- try:
- names = scoped_names[key]
- except KeyError:
- names = scoped_names[key] = defaultdict(set)
- for name in statement_names:
- for name_type in evaluator.find_types(scope, name):
- if isinstance(name_type, Import):
+ else:
+ parent = statement.parent()
+ scope = parent._definition
+ evaluator = statement._evaluator
+ # original jedi-typer does not handle function definitions, so skip here as well
+ if isinstance(statement._definition, Function):
+ continue
+ statement_names = [statement.name]
+ key = (None if isinstance(scope, Module) else str(parent.name), scope.start_pos)
+ try:
+ names = scoped_names[key]
+ except KeyError:
+ names = scoped_names[key] = defaultdict(set)
+ for name in statement_names:
+ for name_type in evaluator.find_types(scope, name, search_global=True):
+ if isinstance(name_type, Import):
+ type_name = 'object'
+ else:
+ try:
+ if __jedi_version__ == 8:
+ type_name = name_type.name
+ else:
+ if isinstance(name_type, Instance):
+ type_name = name_type.base.obj.__name__
+ else:
+ type_name = type(name_type.obj).__name__
+ except AttributeError as error:
+ print(error)
type_name = 'object'
- else:
- type_name = name_type.name
- names[str(name)].add(type_name)
-
+ names[str(name)].add(type_name)
return scoped_names
@@ -72,13 +102,14 @@ def inject_types(source_path, types, type_map=default_type_map, mode='python'):
for line_no, line in enumerate(f, 1):
if line_no in col_and_types_by_line:
col, scope, types = col_and_types_by_line[line_no]
- types = ', '.join("%s='%s'" % (name, type_map.get(type_name, type_name))
- for name, type_name in types)
- if scope is None:
- type_decl = u'{indent}cython.declare({types})\n'
- else:
- type_decl = u'{indent}@cython.locals({types})\n'
- lines.append(type_decl.format(indent=' '*col, types=types))
+ if types:
+ types = ', '.join("%s='%s'" % (name, type_map.get(type_name, type_name))
+ for name, type_name in types)
+ if scope is None:
+ type_decl = u'{indent}cython.declare({types})\n'
+ else:
+ type_decl = u'{indent}@cython.locals({types})\n'
+ lines.append(type_decl.format(indent=' '*col, types=types))
lines.append(line)
return lines