Closed timrid closed 2 years ago
I experimented a bit more and think that the error has nothing to do with the contextmanager directly, but with the processing of the decorator.
For this I simplified the example code a bit, so that less dependencies are used:
code = """\
from typing import Callable
class ClassA: ...
class ClassB:
def do_something(self): ...
def convert_a_to_b(func: Callable[..., ClassA]) -> Callable[..., ClassB]: ...
# code_working ########################################################
@convert_a_to_b
def get_object() -> ClassA: ...
class_b1 = get_object()
class_b1.do_something() # this is line 15, col 14 is between letter s and o
# code_not_working #####################################################
class SomeClass:
@convert_a_to_b
def get_object(self) -> ClassA: ...
some_class = SomeClass()
class_b2 = some_class.get_object()
class_b2.do_something() # this is line 24, col 14 is between letter s and o
"""
import jedi
jedi.set_debug_function()
print("########## WORKING ####################################################################################################")
script_working = jedi.Script(code=code, path="")
print(f"{script_working.complete(line=15, column=14)=}")
print("")
print("########## NOT WORKING ################################################################################################")
script_not_working = jedi.Script(code=code, path="")
print(f"{script_not_working.complete(line=24, column=14)=}")
The following output is generated:
########## WORKING ####################################################################################################
dbg: Start environment subprocess '.......\\.venv\\Scripts\\python.exe'
speed: init 0.20604562759399414
speed: parsed 0.20804643630981445
dbg: Start: complete
dbg: infer_node <Name: class_b1@15,0>@(15, 0) in ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)
dbg: context.goto <Name: class_b1@15,0> in (ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)): [<TreeNameDefinition: string_name=class_b1 start_pos=(14, 0)>]
dbg: global search_module 'builtins': <CompiledModule: <module 'builtins' (built-in)>>
dbg: infer_expr_stmt <ExprStmt: class_b1 = get_object()@14,0> (<Name: class_b1@14,0>)
dbg: infer_node PythonNode(atom_expr, [<Name: get_object@14,11>, PythonNode(trailer, [<Operator: (>, <Operator: )>])])@(14, 11) in ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)
dbg: infer_node <Name: get_object@14,11>@(14, 11) in ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)
dbg: context.goto <Name: get_object@14,11> in (ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)): [<TreeNameDefinition: string_name=get_object start_pos=(12, 4)>]
dbg: decorator: <Decorator: # code_working ######################################################## @convert_a_to_b@11,0> S{<FunctionValue: <Function: get_object@12-13>>}
dbg: infer_node <Name: convert_a_to_b@11,1>@(11, 1) in ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)
dbg: context.goto <Name: convert_a_to_b@11,1> in (ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)): [<TreeNameDefinition: string_name=convert_a_to_b start_pos=(8, 4)>]
dbg: context.names_to_types: [<TreeNameDefinition: string_name=convert_a_to_b start_pos=(8, 4)>] -> S{<FunctionValue: <Function: convert_a_to_b@8-9>>}
dbg: execute: <FunctionValue: <Function: convert_a_to_b@8-9>> <ValuesArguments: [S{<FunctionValue: <Function: get_object@12-13>>}]>
dbg: infer_node <Operator: ...>@(8, 60) in ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)
dbg: infer_node <Name: ellipsis@1260,10>@(1260, 10) in StubModuleContext(<StubModuleValue: builtins@1-1388 is_stub=True>)
dbg: context.goto <Name: ellipsis@1260,10> in (StubModuleContext(<StubModuleValue: builtins@1-1388 is_stub=True>)): [<TreeNameDefinition: string_name=ellipsis start_pos=(1258, 6)>]
dbg: context.names_to_types: [<TreeNameDefinition: string_name=ellipsis start_pos=(1258, 6)>] -> S{<ClassValue: <Class: ellipsis@1258-1259>>}
dbg: execute: <ClassValue: <Class: ellipsis@1258-1259>> <ValuesArguments: []>
dbg: context.goto 'object' in (<StubModuleValue: builtins@1-1388 is_stub=True>): [<StubName: string_name=object start_pos=(83, 6)>]
dbg: context.names_to_types: [<StubName: string_name=object start_pos=(83, 6)>] -> S{<ClassValue: <Class: object@83-109>>}
dbg: execute result: S{<TreeInstance of <ClassValue: <Class: ellipsis@1258-1259>>(<ValuesArguments: []>)>} in <ClassValue: <Class: ellipsis@1258-1259>>
dbg: infer_node <Name: ClassB@8,65>@(8, 65) in ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)
dbg: context.goto <Name: ClassB@8,65> in (ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)): [<TreeNameDefinition: string_name=ClassB start_pos=(5, 6)>]
dbg: context.names_to_types: [<TreeNameDefinition: string_name=ClassB start_pos=(5, 6)>] -> S{<ClassValue: <Class: ClassB@5-7>>}
dbg: infer_node PythonNode(atom_expr, [<Name: Callable@8,51>, PythonNode(trailer, [<Operator: [>, PythonNode(subscriptlist, [<Operator: ...>, <Operator: ,>, <Name: ClassB@8,65>]), <Operator: ]>])])@(8, 51) in ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)
dbg: infer_node <Name: Callable@8,51>@(8, 51) in ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)
dbg: context.goto <Name: Callable@8,51> in (ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)): [<TreeNameDefinition: string_name=Callable start_pos=(1, 19)>]
speed: import (<Name: typing@1,5>,) ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>) 0.09102058410644531
dbg: global search_module 'typing': <ModuleValue: typing@1-2011 is_stub=False>
dbg: context.goto <Name: Callable@1,19> in (<TypingModuleWrapper: typing@1-688 is_stub=True>): [TypingModuleName(<StubName: string_name=Callable start_pos=(44, 0)>)]
dbg: context.names_to_types: [TypingModuleName(<StubName: string_name=Callable start_pos=(44, 0)>)] -> S{ProxyTypingClassValue(Callable)}
dbg: after import: S{ProxyTypingClassValue(Callable)}
dbg: context.names_to_types: [<TreeNameDefinition: string_name=Callable start_pos=(1, 19)>] -> S{ProxyTypingClassValue(Callable)}
dbg: py__getitem__ result: S{TypingClassWithGenerics(Callable<LazyG>[S{<TreeInstance of <ClassValue: <Class: ellipsis@1258-1259>>(<ValuesArguments: []>)>}, S{<ClassValue: <Class: ClassB@5-7>>}])}
dbg: Start: Resolve lazy value wrapper
dbg: End: Resolve lazy value wrapper
dbg: execute result: S{<Callable: <LazyG>[S{<TreeInstance of <ClassValue: <Class: ellipsis@1258-1259>>(<ValuesArguments: []>)>}, S{<ClassValue: <Class: ClassB@5-7>>}]>} in <FunctionValue: <Function: convert_a_to_b@8-9>>
dbg: decorator end S{<Callable: <LazyG>[S{<TreeInstance of <ClassValue: <Class: ellipsis@1258-1259>>(<ValuesArguments: []>)>}, S{<ClassValue: <Class: ClassB@5-7>>}]>}
dbg: context.names_to_types: [<TreeNameDefinition: string_name=get_object start_pos=(12, 4)>] -> S{Decoratee(<Callable: <LazyG>[S{<TreeInstance of <ClassValue: <Class: ellipsis@1258-1259>>(<ValuesArguments: []>)>}, S{<ClassValue: <Class: ClassB@5-7>>}]>)}
dbg: infer_trailer: PythonNode(trailer, [<Operator: (>, <Operator: )>]) in S{Decoratee(<Callable: <LazyG>[S{<TreeInstance of <ClassValue: <Class: ellipsis@1258-1259>>(<ValuesArguments: []>)>}, S{<ClassValue: <Class: ClassB@5-7>>}]>)}
dbg: Start: Resolve lazy value wrapper
dbg: execute: <ClassValue: <Class: object@83-109>> <ValuesArguments: []>
dbg: execute result: S{<TreeInstance of <ClassValue: <Class: object@83-109>>(<ValuesArguments: []>)>} in <ClassValue: <Class: object@83-109>>
dbg: End: Resolve lazy value wrapper
dbg: execute: Decoratee(<Callable: <LazyG>[S{<TreeInstance of <ClassValue: <Class: ellipsis@1258-1259>>(<ValuesArguments: []>)>}, S{<ClassValue: <Class: ClassB@5-7>>}]>) <TreeArguments: None>
dbg: execute: <ClassValue: <Class: ClassB@5-7>> <ValuesArguments: []>
dbg: context.goto 'object' in (<StubModuleValue: builtins@1-1388 is_stub=True>): [<StubName: string_name=object start_pos=(83, 6)>]
dbg: context.names_to_types: [<StubName: string_name=object start_pos=(83, 6)>] -> S{<ClassValue: <Class: object@83-109>>}
dbg: execute result: S{<TreeInstance of <ClassValue: <Class: ClassB@5-7>>(<ValuesArguments: []>)>} in <ClassValue: <Class: ClassB@5-7>>
dbg: execute result: S{<TreeInstance of <ClassValue: <Class: ClassB@5-7>>(<ValuesArguments: []>)>} in Decoratee(<Callable: <LazyG>[S{<TreeInstance of <ClassValue: <Class: ellipsis@1258-1259>>(<ValuesArguments: []>)>}, S{<ClassValue: <Class: ClassB@5-7>>}]>)
dbg: infer_expr_stmt result S{<TreeInstance of <ClassValue: <Class: ClassB@5-7>>(<ValuesArguments: []>)>}
dbg: context.names_to_types: [<TreeNameDefinition: string_name=class_b1 start_pos=(14, 0)>] -> S{<TreeInstance of <ClassValue: <Class: ClassB@5-7>>(<ValuesArguments: []>)>}
dbg: trailer completion values: S{<TreeInstance of <ClassValue: <Class: ClassB@5-7>>(<ValuesArguments: []>)>}
dbg: context.goto '__init__' in (<ClassValue: <Class: ClassB@5-7>>): [<ClassName: string_name=__init__ start_pos=(93, 8)>]
dbg: context.names_to_types: [<ClassName: string_name=__init__ start_pos=(93, 8)>] -> S{<MethodValue: <Function: __init__@93-94>>}
dbg: Overloading match: '__init__(self) -> None'@93 (<InstanceArguments: <ValuesArguments: []>>)
dbg: Start: convert values
dbg: End: convert values
dbg: End: complete
script_working.complete(line=15, column=14)=[<Completion: do_something>]
########## NOT WORKING ################################################################################################
speed: init 0.14403128623962402
speed: parsed 0.14403128623962402
dbg: Start: complete
dbg: infer_node <Name: class_b2@24,0>@(24, 0) in ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)
dbg: context.goto <Name: class_b2@24,0> in (ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)): [<TreeNameDefinition: string_name=class_b2 start_pos=(23, 0)>]
dbg: global search_module 'builtins': <CompiledModule: <module 'builtins' (built-in)>>
dbg: infer_expr_stmt <ExprStmt: class_b2 = some_class.get_object()@23,0> (<Name: class_b2@23,0>)
dbg: infer_node PythonNode(atom_expr, [<Name: some_class@23,11>, PythonNode(trailer, [<Operator: .>, <Name: get_object@23,22>]), PythonNode(trailer, [<Operator: (>, <Operator: )>])])@(23, 11) in ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)
dbg: infer_node <Name: some_class@23,11>@(23, 11) in ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)
dbg: context.goto <Name: some_class@23,11> in (ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)): [<TreeNameDefinition: string_name=some_class start_pos=(22, 0)>]
dbg: infer_expr_stmt <ExprStmt: some_class = SomeClass()@22,0> (<Name: some_class@22,0>)
dbg: infer_node PythonNode(atom_expr, [<Name: SomeClass@22,13>, PythonNode(trailer, [<Operator: (>, <Operator: )>])])@(22, 13) in ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)
dbg: infer_node <Name: SomeClass@22,13>@(22, 13) in ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)
dbg: context.goto <Name: SomeClass@22,13> in (ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)): [<TreeNameDefinition: string_name=SomeClass start_pos=(18, 6)>]
dbg: context.names_to_types: [<TreeNameDefinition: string_name=SomeClass start_pos=(18, 6)>] -> S{<ClassValue: <Class: SomeClass@18-21>>}
dbg: infer_trailer: PythonNode(trailer, [<Operator: (>, <Operator: )>]) in S{<ClassValue: <Class: SomeClass@18-21>>}
dbg: execute: <ClassValue: <Class: SomeClass@18-21>> <TreeArguments: None>
dbg: context.goto 'object' in (<StubModuleValue: builtins@1-1388 is_stub=True>): [<StubName: string_name=object start_pos=(83, 6)>]
dbg: context.names_to_types: [<StubName: string_name=object start_pos=(83, 6)>] -> S{<ClassValue: <Class: object@83-109>>}
dbg: execute result: S{<TreeInstance of <ClassValue: <Class: SomeClass@18-21>>(<TreeArguments: None>)>} in <ClassValue: <Class: SomeClass@18-21>>
dbg: infer_expr_stmt result S{<TreeInstance of <ClassValue: <Class: SomeClass@18-21>>(<TreeArguments: None>)>}
dbg: context.names_to_types: [<TreeNameDefinition: string_name=some_class start_pos=(22, 0)>] -> S{<TreeInstance of <ClassValue: <Class: SomeClass@18-21>>(<TreeArguments: None>)>}
dbg: infer_trailer: PythonNode(trailer, [<Operator: .>, <Name: get_object@23,22>]) in S{<TreeInstance of <ClassValue: <Class: SomeClass@18-21>>(<TreeArguments: None>)>}
dbg: context.goto '__init__' in (<ClassValue: <Class: SomeClass@18-21>>): [<ClassName: string_name=__init__ start_pos=(93, 8)>]
dbg: context.names_to_types: [<ClassName: string_name=__init__ start_pos=(93, 8)>] -> S{<MethodValue: <Function: __init__@93-94>>}
dbg: Overloading match: '__init__(self) -> None'@93 (<InstanceArguments: <TreeArguments: None>>)
dbg: context.goto <Name: get_object@23,22> in (<TreeInstance of <ClassValue: <Class: SomeClass@18-21>>(<TreeArguments: None>)>): [LazyInstanceClassName(<ClassName: string_name=get_object start_pos=(20, 8)>)]
dbg: decorator: <Decorator: @convert_a_to_b@19,4> S{<MethodValue: <Function: get_object@20-21>>}
dbg: infer_node <Name: convert_a_to_b@19,5>@(19, 5) in ClassContext(<ClassValue: <Class: SomeClass@18-21>>)
dbg: context.goto <Name: convert_a_to_b@19,5> in (ClassContext(<ClassValue: <Class: SomeClass@18-21>>)): [<TreeNameDefinition: string_name=convert_a_to_b start_pos=(8, 4)>]
dbg: context.names_to_types: [<TreeNameDefinition: string_name=convert_a_to_b start_pos=(8, 4)>] -> S{<FunctionValue: <Function: convert_a_to_b@8-9>>}
dbg: execute: <FunctionValue: <Function: convert_a_to_b@8-9>> <ValuesArguments: [S{<MethodValue: <Function: get_object@20-21>>}]>
dbg: infer_node <Operator: ...>@(8, 60) in ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)
dbg: infer_node <Name: ellipsis@1260,10>@(1260, 10) in StubModuleContext(<StubModuleValue: builtins@1-1388 is_stub=True>)
dbg: context.goto <Name: ellipsis@1260,10> in (StubModuleContext(<StubModuleValue: builtins@1-1388 is_stub=True>)): [<TreeNameDefinition: string_name=ellipsis start_pos=(1258, 6)>]
dbg: context.names_to_types: [<TreeNameDefinition: string_name=ellipsis start_pos=(1258, 6)>] -> S{<ClassValue: <Class: ellipsis@1258-1259>>}
dbg: execute: <ClassValue: <Class: ellipsis@1258-1259>> <ValuesArguments: []>
dbg: context.goto 'object' in (<StubModuleValue: builtins@1-1388 is_stub=True>): [<StubName: string_name=object start_pos=(83, 6)>]
dbg: context.names_to_types: [<StubName: string_name=object start_pos=(83, 6)>] -> S{<ClassValue: <Class: object@83-109>>}
dbg: execute result: S{<TreeInstance of <ClassValue: <Class: ellipsis@1258-1259>>(<ValuesArguments: []>)>} in <ClassValue: <Class: ellipsis@1258-1259>>
dbg: infer_node <Name: ClassB@8,65>@(8, 65) in ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)
dbg: context.goto <Name: ClassB@8,65> in (ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)): [<TreeNameDefinition: string_name=ClassB start_pos=(5, 6)>]
dbg: context.names_to_types: [<TreeNameDefinition: string_name=ClassB start_pos=(5, 6)>] -> S{<ClassValue: <Class: ClassB@5-7>>}
dbg: infer_node PythonNode(atom_expr, [<Name: Callable@8,51>, PythonNode(trailer, [<Operator: [>, PythonNode(subscriptlist, [<Operator: ...>, <Operator: ,>, <Name: ClassB@8,65>]), <Operator: ]>])])@(8, 51) in ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)
dbg: infer_node <Name: Callable@8,51>@(8, 51) in ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)
dbg: context.goto <Name: Callable@8,51> in (ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>)): [<TreeNameDefinition: string_name=Callable start_pos=(1, 19)>]
speed: import (<Name: typing@1,5>,) ModuleContext(<ModuleValue: whcomm-pkg@1-25 is_stub=False>) 0.010002851486206055
dbg: global search_module 'typing': <ModuleValue: typing@1-2011 is_stub=False>
dbg: context.goto <Name: Callable@1,19> in (<TypingModuleWrapper: typing@1-688 is_stub=True>): [TypingModuleName(<StubName: string_name=Callable start_pos=(44, 0)>)]
dbg: context.names_to_types: [TypingModuleName(<StubName: string_name=Callable start_pos=(44, 0)>)] -> S{ProxyTypingClassValue(Callable)}
dbg: after import: S{ProxyTypingClassValue(Callable)}
dbg: context.names_to_types: [<TreeNameDefinition: string_name=Callable start_pos=(1, 19)>] -> S{ProxyTypingClassValue(Callable)}
dbg: py__getitem__ result: S{TypingClassWithGenerics(Callable<LazyG>[S{<TreeInstance of <ClassValue: <Class: ellipsis@1258-1259>>(<ValuesArguments: []>)>}, S{<ClassValue: <Class: ClassB@5-7>>}])}
dbg: Start: Resolve lazy value wrapper
dbg: End: Resolve lazy value wrapper
dbg: execute result: S{<Callable: <LazyG>[S{<TreeInstance of <ClassValue: <Class: ellipsis@1258-1259>>(<ValuesArguments: []>)>}, S{<ClassValue: <Class: ClassB@5-7>>}]>} in <FunctionValue: <Function: convert_a_to_b@8-9>>
dbg: decorator end S{<Callable: <LazyG>[S{<TreeInstance of <ClassValue: <Class: ellipsis@1258-1259>>(<ValuesArguments: []>)>}, S{<ClassValue: <Class: ClassB@5-7>>}]>}
dbg: Start: Resolve lazy value wrapper
dbg: execute: <ClassValue: <Class: object@83-109>> <ValuesArguments: []>
dbg: execute result: S{<TreeInstance of <ClassValue: <Class: object@83-109>>(<ValuesArguments: []>)>} in <ClassValue: <Class: object@83-109>>
dbg: End: Resolve lazy value wrapper
dbg: context.goto '__init__' in (<ClassValue: <Class: object@83-109>>): [<ClassName: string_name=__init__ start_pos=(93, 8)>]
dbg: context.names_to_types: [<ClassName: string_name=__init__ start_pos=(93, 8)>] -> S{<MethodValue: <Function: __init__@93-94>>}
dbg: Overloading match: '__init__(self) -> None'@93 (<InstanceArguments: <ValuesArguments: []>>)
dbg: context.names_to_types: [LazyInstanceClassName(<ClassName: string_name=get_object start_pos=(20, 8)>)] -> S{Decoratee(<TreeInstance of <ClassValue: <Class: object@83-109>>(<ValuesArguments: []>)>)}
dbg: infer_trailer: PythonNode(trailer, [<Operator: (>, <Operator: )>]) in S{Decoratee(<TreeInstance of <ClassValue: <Class: object@83-109>>(<ValuesArguments: []>)>)}
dbg: execute: Decoratee(<TreeInstance of <ClassValue: <Class: object@83-109>>(<ValuesArguments: []>)>) <TreeArguments: None>
warning: no execution possible <TreeInstance of <ClassValue: <Class: object@83-109>>(<ValuesArguments: []>)>
dbg: execute result: S{} in Decoratee(<TreeInstance of <ClassValue: <Class: object@83-109>>(<ValuesArguments: []>)>)
dbg: infer_expr_stmt result S{}
dbg: context.names_to_types: [<TreeNameDefinition: string_name=class_b2 start_pos=(23, 0)>] -> S{}
dbg: trailer completion values: S{}
dbg: Start: convert values
dbg: End: convert values
dbg: End: complete
script_not_working.complete(line=24, column=14)=[]
I think it has something to do with the warning: no execution possible
. But even after intensive research in the jedi documentation and repository I still don't really understand where exactly the problem is. I hope you can help me a bit more on which place I should look further.
My setup now:
Win 10
Python 3.8.6 (the standard Python installation)
Jedi 0.18.1
Parso 0.8.3
It also looks like this is specific to decorators which have type annotations:
from typing import Callable
def decorator(func):
def wrapper(*a, **k):
return str(func(*a, **k))
return wrapper
def typed_decorator(func: Callable[..., int]) -> Callable[..., str]:
...
class X:
@decorator
def plain(self) -> int:
return 4
@typed_decorator
def typed(self) -> int:
return 4
inst = X()
x = inst.plain()
x. # works
y = inst.typed()
y. # doesn't work
I've had a go at fixing this: https://github.com/davidhalter/jedi/pull/1826
Perfect, works like a charm. Thanks for fixing this so quickly. I would have never found this... I hope the PR is merged quickly :)
Hi.
I tried to get an auto completion of a contextmanager. It works for an normal function but not for an class method. What could be the reason for this?
Here is an example for a working version (normal function) and a not working version (class method).
The output is
My Setup: