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.inference.cache import inference_state_method_cache
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.type_var import TypeVar
from jedi.inference.helpers import is_string
@@ -350,7 +350,7 @@ def merge_pairwise_generics(annotation_value, annotated_argument_class):
type_var_dict = {}
if not isinstance(annotated_argument_class, DefineGenericBase):
if not isinstance(annotated_argument_class, (DefineGenericBase, BaseTypingInstance)):
return type_var_dict
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.value.klass import ClassFilter
from jedi.inference.value.klass import ClassMixin
from jedi.inference.value.instance import AbstractInstanceValue
from jedi.inference.utils import to_list
from jedi.inference.names import AbstractNameDefinition, ValueName
from jedi.inference.context import ClassContext
@@ -375,3 +376,27 @@ class BaseTypingValueWithGenerics(DefineGenericBase):
def __repr__(self):
return '%s(%s%s)' % (self.__class__.__name__, self._tree_name.value,
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.names import NameWrapper, ValueName
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.generics import LazyGenericManager, TupleGenericManager
@@ -129,6 +130,7 @@ class TypingValueWithIndex(BaseTypingValueWithGenerics):
cls = mapped[string_name]
return ValueSet([cls(
self.parent_context,
self,
self._tree_name,
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
# incoming classes to be able to use the normal code for type
# var inference.
value_set.execute_with_values(),
value_set.execute_annotation(),
)
elif annotation_name == 'Callable':
@@ -254,7 +256,7 @@ class TypeAlias(LazyValueWrapper):
return ValueSet([self._get_wrapped_value()])
class Callable(BaseTypingValueWithGenerics):
class Callable(BaseTypingInstance):
def py__call__(self, arguments):
"""
def x() -> Callable[[Callable[..., _T]], _T]: ...
@@ -271,7 +273,7 @@ class Callable(BaseTypingValueWithGenerics):
return infer_return_for_callable(arguments, param_values, result_values)
class Tuple(BaseTypingValueWithGenerics):
class Tuple(BaseTypingInstance):
def _is_homogenous(self):
# To specify a variable-length tuple of homogeneous type, Tuple[T, ...]
# is used.
@@ -307,6 +309,10 @@ class Tuple(BaseTypingValueWithGenerics):
.py__getattribute__('tuple').execute_annotation()
return tuple_
@property
def name(self):
return self._wrapped_value.name
def infer_type_vars(self, value_set):
# Circular
from jedi.inference.gradual.annotation import merge_pairwise_generics, merge_type_var_dicts
@@ -352,11 +358,11 @@ class Tuple(BaseTypingValueWithGenerics):
return type_var_dict
class Generic(BaseTypingValueWithGenerics):
class Generic(BaseTypingInstance):
pass
class Protocol(BaseTypingValueWithGenerics):
class Protocol(BaseTypingInstance):
pass

View File

@@ -10,6 +10,7 @@ from typing import (
Type,
TypeVar,
Union,
Sequence,
)
K = TypeVar('K')
@@ -165,6 +166,9 @@ some_str = NotImplemented # type: str
#? 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
def values(mapping: Mapping[int, T]) -> List[T]: