1
0
forked from VimPlug/jedi

I feel this is a nicer solution. Forward Reference busting should be part of the annotation resolving. It doesn not have anything to do with the typing module (and should indeed also happen if someone writes his own types outside of the typing module)

This commit is contained in:
Claude
2015-12-30 23:05:01 +01:00
parent 5948c63cf9
commit 10f5e15325
2 changed files with 28 additions and 26 deletions

View File

@@ -30,33 +30,45 @@ from jedi import debug
def _evaluate_for_annotation(evaluator, annotation): def _evaluate_for_annotation(evaluator, annotation):
if annotation is not None: if annotation is not None:
definitions = set() dereferenced_annotation = _fix_forward_reference(evaluator, annotation)
module = annotation.get_parent_until() definitions = evaluator.eval_element(dereferenced_annotation)
for definition in evaluator.eval_element(annotation):
definitions |= \
_fix_forward_reference(evaluator, definition, module)
return list(chain.from_iterable( return list(chain.from_iterable(
evaluator.execute(d) for d in definitions)) evaluator.execute(d) for d in definitions))
else: else:
return [] return []
def _fix_forward_reference(evaluator, item, module): def _fix_forward_reference(evaluator, item):
if (isinstance(item, compiled.CompiledObject) and """
isinstance(item.obj, str)): Gets something from the parse tree, and replaces any string literal
in there with the result of evaluating that string at the bottom of the
module
"""
if isinstance(item, tree.String):
compiledobjects = evaluator.eval_element(item)
assert len(compiledobjects) == 1
compiledobject = list(compiledobjects)[0]
try: try:
p = Parser( p = Parser(load_grammar(), compiledobject.obj, start='eval_input')
load_grammar(), item.obj, start='eval_input')
element = p.get_parsed_node() element = p.get_parsed_node()
except ParseError: except ParseError:
debug.warning('Annotation not parsed: %s' % item.obj) debug.warning('Annotation not parsed: %s' % compiledobject.obj)
return set() return item
else: else:
module = item.get_parent_until()
p.position_modifier.line = module.end_pos[0] p.position_modifier.line = module.end_pos[0]
element.parent = module element.parent = module
return evaluator.eval_element(element) dereferenced = _fix_forward_reference(evaluator, element)
else: return dereferenced
return set([item]) if isinstance(item, tree.Node):
newnode = tree.Node(item.type, [])
for child in item.children:
newchild = _fix_forward_reference(evaluator, child)
newchild.parent = newnode
newnode.children.append(newchild)
newnode.parent = item.parent
return newnode
return item
@memoize_default(None, evaluator_is_first_arg=True) @memoize_default(None, evaluator_is_first_arg=True)
@@ -97,12 +109,6 @@ def get_types_for_typing_module(evaluator, typ, trailer):
if not isinstance(indextypes, set): if not isinstance(indextypes, set):
indextypes = set([indextypes]) indextypes = set([indextypes])
module = trailer.get_parent_until()
dereferencedindextypes = set()
for indextyp in indextypes:
dereferencedindextypes |= \
_fix_forward_reference(evaluator, indextyp, module)
typing = _get_typing_replacement_module() typing = _get_typing_replacement_module()
factories = evaluator.find_types(typing, "factory") factories = evaluator.find_types(typing, "factory")
assert len(factories) == 1 assert len(factories) == 1
@@ -117,7 +123,7 @@ def get_types_for_typing_module(evaluator, typ, trailer):
compiled_classname = compiled.create(evaluator, typ.name.value) compiled_classname = compiled.create(evaluator, typ.name.value)
result = set() result = set()
for indextyp in dereferencedindextypes: for indextyp in indextypes:
result |= \ result |= \
evaluator.execute_evaluated(factory, compiled_classname, indextyp) evaluator.execute_evaluated(factory, compiled_classname, indextyp)
for singleresult in result: for singleresult in result:

View File

@@ -153,7 +153,3 @@ def function_with_assined_class_in_reference(x: X, y: "Y"):
#? int() #? int()
y y
Y = int Y = int
def just_because_we_can(x: "flo" + "at"):
#? float()
x