From 37c77f410322ac18fbfed06b96b9a0437d084fe2 Mon Sep 17 00:00:00 2001 From: Brent Yi Date: Mon, 24 May 2021 07:07:34 -0700 Subject: [PATCH 1/5] Add support for generic dataclass inheritance --- AUTHORS.txt | 1 + jedi/plugins/stdlib.py | 9 ++++++++- test/test_inference/test_signature.py | 9 +++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/AUTHORS.txt b/AUTHORS.txt index b8b10a9374..5ce113b74d 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -62,6 +62,7 @@ Code Contributors - Andrii Kolomoiets (@muffinmad) - Leo Ryu (@Leo-Ryu) - Joseph Birkner (@josephbirkner) +- Brent Yi (@brentyi) And a few more "anonymous" contributors. diff --git a/jedi/plugins/stdlib.py b/jedi/plugins/stdlib.py index 17f1df3bcf..33c94831c9 100644 --- a/jedi/plugins/stdlib.py +++ b/jedi/plugins/stdlib.py @@ -24,6 +24,7 @@ AnonymousMethodExecutionContext, MethodExecutionContext from jedi.inference.base_value import ContextualizedNode, \ NO_VALUES, ValueSet, ValueWrapper, LazyValueWrapper +from jedi.inference.gradual.base import GenericClass from jedi.inference.value import ClassValue, ModuleValue from jedi.inference.value.klass import ClassMixin from jedi.inference.value.function import FunctionMixin @@ -603,7 +604,13 @@ class DataclassWrapper(ValueWrapper, ClassMixin): def get_signatures(self): param_names = [] for cls in reversed(list(self.py__mro__())): - if isinstance(cls, DataclassWrapper): + if ( + isinstance(cls, DataclassWrapper) + or ( + isinstance(cls, GenericClass) + and isinstance(cls._get_wrapped_value(), DataclassWrapper) + ) + ): filter_ = cls.as_context().get_global_filter() # .values ordering is not guaranteed, at least not in # Python < 3.6, when dicts where not ordered, which is an diff --git a/test/test_inference/test_signature.py b/test/test_inference/test_signature.py index 85adaff7ad..dd3c57d7bb 100644 --- a/test/test_inference/test_signature.py +++ b/test/test_inference/test_signature.py @@ -315,6 +315,15 @@ class Y(): z = 5 @dataclass class X(Y):'''), ['y']], + [dedent(''' + from typing import Generic, TypeVar + T = TypeVar("T") + @dataclass + class Y(Generic[T]): + y: T + z = 5 + @dataclass + class X(Y[int]):'''), ['y']], ] ) def test_dataclass_signature(Script, skip_pre_python37, start, start_params): From 62d702931d8e85d710d09aaabac4bbc94ba71130 Mon Sep 17 00:00:00 2001 From: Brent Yi Date: Mon, 24 May 2021 07:50:03 -0700 Subject: [PATCH 2/5] Add (failing!) test with more complex inheritance --- test/test_inference/test_signature.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/test_inference/test_signature.py b/test/test_inference/test_signature.py index dd3c57d7bb..8c736d3a9c 100644 --- a/test/test_inference/test_signature.py +++ b/test/test_inference/test_signature.py @@ -324,6 +324,17 @@ class Y(Generic[T]): z = 5 @dataclass class X(Y[int]):'''), ['y']], + [dedent(''' + from typing import Generic, TypeVar + T = TypeVar("T") + @dataclass + class Z: + z: int + @dataclass + class Y(Z, Generic[T]): + y: T + @dataclass + class X(Y[int]):'''), ['z', 'y']], ] ) def test_dataclass_signature(Script, skip_pre_python37, start, start_params): From d9e7a1a826a15970e52470eb3a5f10314d790e12 Mon Sep 17 00:00:00 2001 From: Brent Yi Date: Wed, 26 May 2021 06:59:54 -0700 Subject: [PATCH 3/5] Hack to get things working locally :clown_face: --- jedi/plugins/stdlib.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/jedi/plugins/stdlib.py b/jedi/plugins/stdlib.py index 33c94831c9..f3b723cbab 100644 --- a/jedi/plugins/stdlib.py +++ b/jedi/plugins/stdlib.py @@ -604,13 +604,8 @@ class DataclassWrapper(ValueWrapper, ClassMixin): def get_signatures(self): param_names = [] for cls in reversed(list(self.py__mro__())): - if ( - isinstance(cls, DataclassWrapper) - or ( - isinstance(cls, GenericClass) - and isinstance(cls._get_wrapped_value(), DataclassWrapper) - ) - ): + if "DataclassWrapper" in str(cls): + # if isinstance(cls, DataclassWrapper): filter_ = cls.as_context().get_global_filter() # .values ordering is not guaranteed, at least not in # Python < 3.6, when dicts where not ordered, which is an From e397d083e3823d1e5db32343e95c2fa9461b627b Mon Sep 17 00:00:00 2001 From: Brent Yi Date: Wed, 26 May 2021 07:14:31 -0700 Subject: [PATCH 4/5] Less hacky DataclassWrapper check --- jedi/plugins/stdlib.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/jedi/plugins/stdlib.py b/jedi/plugins/stdlib.py index f3b723cbab..e0c01c3e3c 100644 --- a/jedi/plugins/stdlib.py +++ b/jedi/plugins/stdlib.py @@ -604,8 +604,18 @@ class DataclassWrapper(ValueWrapper, ClassMixin): def get_signatures(self): param_names = [] for cls in reversed(list(self.py__mro__())): - if "DataclassWrapper" in str(cls): - # if isinstance(cls, DataclassWrapper): + + # Handle cases where DataclassWrapper objects are nested inside of + # Decoratee, GenericClass, etc -- these are all subclasses of ValueWrapper + # or LazyValueWrapper. + is_dataclass = False + while isinstance(cls, (ValueWrapper, LazyValueWrapper)): + if isinstance(cls, DataclassWrapper): + is_dataclass = True + break + cls = cls._wrapped_value + + if is_dataclass: filter_ = cls.as_context().get_global_filter() # .values ordering is not guaranteed, at least not in # Python < 3.6, when dicts where not ordered, which is an From 2d5e73982e177f2ba5e1d1cfcc32a344ccdf0138 Mon Sep 17 00:00:00 2001 From: Brent Yi Date: Thu, 29 Jul 2021 00:48:07 -0700 Subject: [PATCH 5/5] Update stdlib.py --- jedi/plugins/stdlib.py | 1 - 1 file changed, 1 deletion(-) diff --git a/jedi/plugins/stdlib.py b/jedi/plugins/stdlib.py index e0c01c3e3c..db583fc05e 100644 --- a/jedi/plugins/stdlib.py +++ b/jedi/plugins/stdlib.py @@ -24,7 +24,6 @@ AnonymousMethodExecutionContext, MethodExecutionContext from jedi.inference.base_value import ContextualizedNode, \ NO_VALUES, ValueSet, ValueWrapper, LazyValueWrapper -from jedi.inference.gradual.base import GenericClass from jedi.inference.value import ClassValue, ModuleValue from jedi.inference.value.klass import ClassMixin from jedi.inference.value.function import FunctionMixin