davidhalter / jedi

Awesome autocompletion, static analysis and refactoring library for python
http://jedi.readthedocs.io
Other
5.77k stars 508 forks source link

No completion found for a contextmanager decorating a class method #1801

Closed timrid closed 2 years ago

timrid commented 3 years ago

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).

code_not_working = """\
import contextlib
from typing import Iterator

class DatabaseConnection:
    def read(self) -> bytes:
        ...

class Database:
    @contextlib.contextmanager
    def connect(self, *args, **kwargs) -> Iterator[DatabaseConnection]:
        ...

db = Database()
with db.connect() as dbcon:
    dbcon.read()  # this is line 15, col 13 is between letter e and a
"""

code_working = """\
import contextlib
from typing import Iterator

class DatabaseConnection:
    def read(self) -> bytes:
        ...

@contextlib.contextmanager
def db_connect(*args, **kwargs) -> Iterator[DatabaseConnection]:
    ...

with db_connect() as dbcon:
    dbcon.read()  # this is line 13, col 13 is between letter e and a
"""

import jedi

script_not_working = jedi.Script(code=code_not_working, path="")
print(f"{script_not_working.complete(line=15, column=13)=}")

script_working = jedi.Script(code=code_working, path="")
print(f"{script_working.complete(line=13, column=13)=}")

The output is

script_not_working.complete(line=15, column=13)=[]
script_working.complete(line=13, column=13)=[<Completion: read>]

My Setup:

Win 10
Python 3.8.10 (the standard Python installation)
Jedi 0.18.0
Parso 0.8.2
timrid commented 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
PeterJCLaw commented 2 years ago

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

timrid commented 2 years ago

Perfect, works like a charm. Thanks for fixing this so quickly. I would have never found this... I hope the PR is merged quickly :)