From c38e4fce70fe26fdce14227ee38d93be7c702f00 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Fri, 29 Nov 2019 14:57:32 +0100 Subject: [PATCH] Make sure py__get__ is defined on all values Also define matches_signature on all signatures, there's definitely cases where that might be called --- jedi/inference/base_value.py | 4 ++++ jedi/inference/signature.py | 3 +++ jedi/inference/value/instance.py | 15 ++++++++------- jedi/inference/value/klass.py | 14 +------------- jedi/plugins/stdlib.py | 2 +- 5 files changed, 17 insertions(+), 21 deletions(-) diff --git a/jedi/inference/base_value.py b/jedi/inference/base_value.py index 2395dcb5..60971e4d 100644 --- a/jedi/inference/base_value.py +++ b/jedi/inference/base_value.py @@ -239,6 +239,10 @@ class Value(HelperValueMixin, BaseValue): """ return NO_VALUES + def py__get__(self, instance, class_value): + debug.warning("No __get__ defined on %s", self) + return ValueSet([self]) + def get_qualified_names(self): # Returns Optional[Tuple[str, ...]] return None diff --git a/jedi/inference/signature.py b/jedi/inference/signature.py index 852122d0..ecf43862 100644 --- a/jedi/inference/signature.py +++ b/jedi/inference/signature.py @@ -56,6 +56,9 @@ class AbstractSignature(_SignatureMixin): def bind(self, value): raise NotImplementedError + def matches_signature(self, arguments): + return True + def __repr__(self): if self.value is self._function_value: return '<%s: %s>' % (self.__class__.__name__, self.value) diff --git a/jedi/inference/value/instance.py b/jedi/inference/value/instance.py index bad9f56b..b05a3380 100644 --- a/jedi/inference/value/instance.py +++ b/jedi/inference/value/instance.py @@ -17,7 +17,7 @@ from jedi.inference.arguments import ValuesArguments, TreeArgumentsWrapper from jedi.inference.value.function import \ FunctionValue, FunctionMixin, OverloadedFunctionValue, \ BaseFunctionExecutionContext, FunctionExecutionContext -from jedi.inference.value.klass import apply_py__get__, ClassFilter +from jedi.inference.value.klass import ClassFilter from jedi.inference.value.dynamic_arrays import get_dynamic_array_instance @@ -263,7 +263,7 @@ class _BaseTreeInstance(AbstractInstanceValue): return ValueSet.from_sets(name.infer().execute(arguments) for name in names) - def py__get__(self, obj, class_value): + def py__get__(self, instance, class_value): """ obj may be None. """ @@ -271,9 +271,9 @@ class _BaseTreeInstance(AbstractInstanceValue): # `method` is the new parent of the array, don't know if that's good. names = self.get_function_slot_names(u'__get__') if names: - if obj is None: - obj = compiled.builtin_from_name(self.inference_state, u'None') - return self.execute_function_slots(names, obj, class_value) + if instance is None: + instance = compiled.builtin_from_name(self.inference_state, u'None') + return self.execute_function_slots(names, instance, class_value) else: return ValueSet([self]) @@ -320,7 +320,8 @@ class TreeInstance(_BaseTreeInstance): for signature in self.class_value.py__getattribute__('__init__').get_signatures(): # Just take the first result, it should always be one, because we # control the typeshed code. - if not signature.matches_signature(args): + if not signature.matches_signature(args) \ + or signature.value.tree_node is None: # First check if the signature even matches, if not we don't # need to infer anything. continue @@ -481,7 +482,7 @@ class LazyInstanceClassName(object): @iterator_to_value_set def infer(self): for result_value in self._class_member_name.infer(): - for c in apply_py__get__(result_value, self._instance, self._instance.py__class__()): + for c in result_value.py__get__(self._instance, self._instance.py__class__()): yield c def __getattr__(self, name): diff --git a/jedi/inference/value/klass.py b/jedi/inference/value/klass.py index 3ab4c57e..7c1c3aab 100644 --- a/jedi/inference/value/klass.py +++ b/jedi/inference/value/klass.py @@ -53,16 +53,6 @@ from jedi.inference.value.function import FunctionAndClassBase from jedi.plugins import plugin_manager -def apply_py__get__(value, instance, class_value): - try: - method = value.py__get__ - except AttributeError: - yield value - else: - for descriptor_value in method(instance, class_value): - yield descriptor_value - - class ClassName(TreeNameDefinition): def __init__(self, class_value, tree_name, name_context, apply_decorators): super(ClassName, self).__init__(class_value.as_context(), tree_name) @@ -79,9 +69,7 @@ class ClassName(TreeNameDefinition): for result_value in inferred: if self._apply_decorators: - for c in apply_py__get__(result_value, - instance=None, - class_value=self._class_value): + for c in result_value.py__get__(instance=None, class_value=self._class_value): yield c else: yield result_value diff --git a/jedi/plugins/stdlib.py b/jedi/plugins/stdlib.py index b9dba270..7321a683 100644 --- a/jedi/plugins/stdlib.py +++ b/jedi/plugins/stdlib.py @@ -335,7 +335,7 @@ def builtins_isinstance(objects, types, arguments, inference_state): class StaticMethodObject(ValueWrapper): - def py__get__(self, instance, klass): + def py__get__(self, instance, class_value): return ValueSet([self._wrapped_value])