Refactor so typing uses BaseTypingValueWithGenerics

This makes it finally possible to use type vars with Callable and some other classes.
Fixes #1413
This commit is contained in:
Dave Halter
2019-12-08 23:50:46 +01:00
parent 7319f8bf2c
commit 5acbb06315
3 changed files with 81 additions and 60 deletions

View File

@@ -10,43 +10,6 @@ from jedi.inference.context import ClassContext
from jedi.inference.gradual.generics import TupleGenericManager from jedi.inference.gradual.generics import TupleGenericManager
class BaseTypingValue(Value):
def __init__(self, inference_state, parent_context, tree_name):
super(BaseTypingValue, self).__init__(inference_state, parent_context)
self._tree_name = tree_name
@property
def tree_node(self):
return self._tree_name
def get_filters(self, *args, **kwargs):
# TODO this is obviously wrong. Is it though?
class EmptyFilter(ClassFilter):
def __init__(self):
pass
def get(self, name, **kwargs):
return []
def values(self, **kwargs):
return []
yield EmptyFilter()
def py__class__(self):
# TODO this is obviously not correct, but at least gives us a class if
# we have none. Some of these objects don't really have a base class in
# typeshed.
return builtin_from_name(self.inference_state, u'object')
@property
def name(self):
return ValueName(self, self._tree_name)
def __repr__(self):
return '%s(%s)' % (self.__class__.__name__, self._tree_name.value)
class _BoundTypeVarName(AbstractNameDefinition): class _BoundTypeVarName(AbstractNameDefinition):
""" """
This type var was bound to a certain type, e.g. int. This type var was bound to a certain type, e.g. int.
@@ -264,3 +227,68 @@ class _GenericInstanceWrapper(ValueWrapper):
elif cls.py__name__() == 'Iterator': elif cls.py__name__() == 'Iterator':
return ValueSet([builtin_from_name(self.inference_state, u'None')]) return ValueSet([builtin_from_name(self.inference_state, u'None')])
return self._wrapped_value.py__stop_iteration_returns() return self._wrapped_value.py__stop_iteration_returns()
class _PseudoTreeNameClass(Value):
def __init__(self, parent_context, tree_name):
super(_PseudoTreeNameClass, self).__init__(
parent_context.inference_state,
parent_context
)
self._tree_name = tree_name
@property
def tree_node(self):
return self._tree_name
def get_filters(self, *args, **kwargs):
# TODO this is obviously wrong. Is it though?
class EmptyFilter(ClassFilter):
def __init__(self):
pass
def get(self, name, **kwargs):
return []
def values(self, **kwargs):
return []
yield EmptyFilter()
def py__class__(self):
# TODO this is obviously not correct, but at least gives us a class if
# we have none. Some of these objects don't really have a base class in
# typeshed.
return builtin_from_name(self.inference_state, u'object')
@property
def name(self):
return ValueName(self, self._tree_name)
def __repr__(self):
return '%s(%s)' % (self.__class__.__name__, self._tree_name.value)
class BaseTypingValue(LazyValueWrapper):
def __init__(self, parent_context, tree_name):
self.inference_state = parent_context.inference_state
self.parent_context = parent_context
self._tree_name = tree_name
@property
def name(self):
return ValueName(self, self._tree_name)
def _get_wrapped_value(self):
return _PseudoTreeNameClass(self.parent_context, self._tree_name)
class BaseTypingValueWithGenerics(DefineGenericBase):
def __init__(self, parent_context, tree_name, generics_manager):
super(BaseTypingValueWithGenerics, self).__init__(generics_manager)
self.inference_state = parent_context.inference_state
self.parent_context = parent_context
self._tree_name = tree_name
def _get_wrapped_value(self):
return _PseudoTreeNameClass(self.parent_context, self._tree_name)

View File

@@ -49,8 +49,8 @@ class TypeVarClass(BaseTypingValue):
class TypeVar(BaseTypingValue): class TypeVar(BaseTypingValue):
def __init__(self, inference_state, parent_context, tree_name, var_name, unpacked_args): def __init__(self, parent_context, tree_name, var_name, unpacked_args):
super(TypeVar, self).__init__(inference_state, parent_context, tree_name) super(TypeVar, self).__init__(parent_context, tree_name)
self._var_name = var_name self._var_name = var_name
self._constraints_lazy_values = [] self._constraints_lazy_values = []

View File

@@ -15,7 +15,7 @@ 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 from jedi.inference.gradual.base import BaseTypingValue, BaseTypingValueWithGenerics
from jedi.inference.gradual.type_var import TypeVarClass from jedi.inference.gradual.type_var import TypeVarClass
from jedi.inference.gradual.generics import LazyGenericManager from jedi.inference.gradual.generics import LazyGenericManager
@@ -97,20 +97,7 @@ class TypingModuleFilterWrapper(FilterWrapper):
name_wrapper_class = TypingModuleName name_wrapper_class = TypingModuleName
class _WithIndexBase(BaseTypingValue): class TypingValueWithIndex(BaseTypingValueWithGenerics):
def __init__(self, inference_state, parent_context, name, generics_manager):
super(_WithIndexBase, self).__init__(inference_state, parent_context, name)
self._generics_manager = generics_manager
def __repr__(self):
return '<%s: %s[%s]>' % (
self.__class__.__name__,
self._tree_name.value,
self._generics_manager,
)
class TypingValueWithIndex(_WithIndexBase):
def execute_annotation(self): def execute_annotation(self):
string_name = self._tree_name.value string_name = self._tree_name.value
@@ -132,7 +119,6 @@ class TypingValueWithIndex(_WithIndexBase):
cls = globals()[string_name] cls = globals()[string_name]
return ValueSet([cls( return ValueSet([cls(
self.inference_state,
self.parent_context, self.parent_context,
self._tree_name, self._tree_name,
generics_manager=self._generics_manager, generics_manager=self._generics_manager,
@@ -141,6 +127,13 @@ class TypingValueWithIndex(_WithIndexBase):
def gather_annotation_classes(self): def gather_annotation_classes(self):
return ValueSet.from_sets(self._generics_manager.to_tuple()) return ValueSet.from_sets(self._generics_manager.to_tuple())
def _create_instance_with_generics(self, generics_manager):
return TypingValueWithIndex(
self.parent_context,
self._tree_name,
generics_manager
)
class ProxyTypingValue(BaseTypingValue): class ProxyTypingValue(BaseTypingValue):
index_class = TypingValueWithIndex index_class = TypingValueWithIndex
@@ -219,15 +212,15 @@ class TypeAlias(LazyValueWrapper):
return cls return cls
class Callable(_WithIndexBase): class Callable(BaseTypingValueWithGenerics):
def py__call__(self, arguments): def py__call__(self, arguments):
# The 0th index are the arguments. # The 0th index are the arguments.
return self._generics_manager.get_index_and_execute(1) return self._generics_manager.get_index_and_execute(1)
class Tuple(LazyValueWrapper): class Tuple(LazyValueWrapper):
def __init__(self, inference_state, parent_context, name, generics_manager): def __init__(self, parent_context, name, generics_manager):
self.inference_state = inference_state self.inference_state = parent_context.inference_state
self.parent_context = parent_context self.parent_context = parent_context
self._generics_manager = generics_manager self._generics_manager = generics_manager
@@ -267,11 +260,11 @@ class Tuple(LazyValueWrapper):
return tuple_ return tuple_
class Generic(_WithIndexBase): class Generic(BaseTypingValueWithGenerics):
pass pass
class Protocol(_WithIndexBase): class Protocol(BaseTypingValueWithGenerics):
pass pass