Make sure that Tuple/Callable instances have the correct py__class__

This commit is contained in:
Dave Halter
2020-05-10 01:05:55 +02:00
parent f362932ec5
commit c2d1da09cb
4 changed files with 43 additions and 8 deletions

View File

@@ -12,7 +12,7 @@ from parso import ParserSyntaxError, parse
from jedi._compatibility import force_unicode, Parameter from jedi._compatibility import force_unicode, Parameter
from jedi.inference.cache import inference_state_method_cache from jedi.inference.cache import inference_state_method_cache
from jedi.inference.base_value import ValueSet, NO_VALUES from jedi.inference.base_value import ValueSet, NO_VALUES
from jedi.inference.gradual.base import DefineGenericBase, GenericClass from jedi.inference.gradual.base import DefineGenericBase, GenericClass, BaseTypingInstance
from jedi.inference.gradual.generics import TupleGenericManager from jedi.inference.gradual.generics import TupleGenericManager
from jedi.inference.gradual.type_var import TypeVar from jedi.inference.gradual.type_var import TypeVar
from jedi.inference.helpers import is_string from jedi.inference.helpers import is_string
@@ -350,7 +350,7 @@ def merge_pairwise_generics(annotation_value, annotated_argument_class):
type_var_dict = {} type_var_dict = {}
if not isinstance(annotated_argument_class, DefineGenericBase): if not isinstance(annotated_argument_class, (DefineGenericBase, BaseTypingInstance)):
return type_var_dict return type_var_dict
annotation_generics = annotation_value.get_generics() annotation_generics = annotation_value.get_generics()

View File

@@ -4,6 +4,7 @@ from jedi.inference.base_value import ValueSet, NO_VALUES, Value, \
from jedi.inference.compiled import builtin_from_name from jedi.inference.compiled import builtin_from_name
from jedi.inference.value.klass import ClassFilter from jedi.inference.value.klass import ClassFilter
from jedi.inference.value.klass import ClassMixin from jedi.inference.value.klass import ClassMixin
from jedi.inference.value.instance import AbstractInstanceValue
from jedi.inference.utils import to_list from jedi.inference.utils import to_list
from jedi.inference.names import AbstractNameDefinition, ValueName from jedi.inference.names import AbstractNameDefinition, ValueName
from jedi.inference.context import ClassContext from jedi.inference.context import ClassContext
@@ -375,3 +376,27 @@ class BaseTypingValueWithGenerics(DefineGenericBase):
def __repr__(self): def __repr__(self):
return '%s(%s%s)' % (self.__class__.__name__, self._tree_name.value, return '%s(%s%s)' % (self.__class__.__name__, self._tree_name.value,
self._generics_manager) self._generics_manager)
class BaseTypingInstance(LazyValueWrapper):
def __init__(self, parent_context, class_value, tree_name, generics_manager):
self.inference_state = class_value.inference_state
self.parent_context = parent_context
self._class_value = class_value
self._tree_name = tree_name
self._generics_manager = generics_manager
def py__class__(self):
return self._class_value
@property
def name(self):
return ValueName(self, self._tree_name)
@inference_state_method_cache()
def get_generics(self):
return self._generics_manager.to_tuple()
def _get_wrapped_value(self):
object_, = builtin_from_name(self.inference_state, u'object').execute_annotation()
return object_

View File

@@ -17,7 +17,8 @@ from jedi.inference.arguments import repack_with_argument_clinic
from jedi.inference.filters import FilterWrapper from jedi.inference.filters import FilterWrapper
from jedi.inference.names import NameWrapper, ValueName from jedi.inference.names import NameWrapper, ValueName
from jedi.inference.value.klass import ClassMixin from jedi.inference.value.klass import ClassMixin
from jedi.inference.gradual.base import BaseTypingValue, BaseTypingValueWithGenerics from jedi.inference.gradual.base import BaseTypingValue, \
BaseTypingValueWithGenerics, BaseTypingInstance
from jedi.inference.gradual.type_var import TypeVarClass from jedi.inference.gradual.type_var import TypeVarClass
from jedi.inference.gradual.generics import LazyGenericManager, TupleGenericManager from jedi.inference.gradual.generics import LazyGenericManager, TupleGenericManager
@@ -129,6 +130,7 @@ class TypingValueWithIndex(BaseTypingValueWithGenerics):
cls = mapped[string_name] cls = mapped[string_name]
return ValueSet([cls( return ValueSet([cls(
self.parent_context, self.parent_context,
self,
self._tree_name, self._tree_name,
generics_manager=self._generics_manager, generics_manager=self._generics_manager,
)]) )])
@@ -197,7 +199,7 @@ class TypingClassValueWithIndex(_TypingClassMixin, TypingValueWithIndex):
# This is basically a trick to avoid extra code: We execute the # This is basically a trick to avoid extra code: We execute the
# incoming classes to be able to use the normal code for type # incoming classes to be able to use the normal code for type
# var inference. # var inference.
value_set.execute_with_values(), value_set.execute_annotation(),
) )
elif annotation_name == 'Callable': elif annotation_name == 'Callable':
@@ -254,7 +256,7 @@ class TypeAlias(LazyValueWrapper):
return ValueSet([self._get_wrapped_value()]) return ValueSet([self._get_wrapped_value()])
class Callable(BaseTypingValueWithGenerics): class Callable(BaseTypingInstance):
def py__call__(self, arguments): def py__call__(self, arguments):
""" """
def x() -> Callable[[Callable[..., _T]], _T]: ... def x() -> Callable[[Callable[..., _T]], _T]: ...
@@ -271,7 +273,7 @@ class Callable(BaseTypingValueWithGenerics):
return infer_return_for_callable(arguments, param_values, result_values) return infer_return_for_callable(arguments, param_values, result_values)
class Tuple(BaseTypingValueWithGenerics): class Tuple(BaseTypingInstance):
def _is_homogenous(self): def _is_homogenous(self):
# To specify a variable-length tuple of homogeneous type, Tuple[T, ...] # To specify a variable-length tuple of homogeneous type, Tuple[T, ...]
# is used. # is used.
@@ -307,6 +309,10 @@ class Tuple(BaseTypingValueWithGenerics):
.py__getattribute__('tuple').execute_annotation() .py__getattribute__('tuple').execute_annotation()
return tuple_ return tuple_
@property
def name(self):
return self._wrapped_value.name
def infer_type_vars(self, value_set): def infer_type_vars(self, value_set):
# Circular # Circular
from jedi.inference.gradual.annotation import merge_pairwise_generics, merge_type_var_dicts from jedi.inference.gradual.annotation import merge_pairwise_generics, merge_type_var_dicts
@@ -352,11 +358,11 @@ class Tuple(BaseTypingValueWithGenerics):
return type_var_dict return type_var_dict
class Generic(BaseTypingValueWithGenerics): class Generic(BaseTypingInstance):
pass pass
class Protocol(BaseTypingValueWithGenerics): class Protocol(BaseTypingInstance):
pass pass

View File

@@ -10,6 +10,7 @@ from typing import (
Type, Type,
TypeVar, TypeVar,
Union, Union,
Sequence,
) )
K = TypeVar('K') K = TypeVar('K')
@@ -165,6 +166,9 @@ some_str = NotImplemented # type: str
#? str() #? str()
first(some_str) first(some_str)
annotated = [len] # type: List[ Callable[[Sequence[float]], int] ]
#? int()
first(annotated)()
# Test that the right type is chosen when a partially realised mapping is expected # Test that the right type is chosen when a partially realised mapping is expected
def values(mapping: Mapping[int, T]) -> List[T]: def values(mapping: Mapping[int, T]) -> List[T]: