mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-07 22:44:27 +08:00
Fix stub function inferrals
This commit is contained in:
@@ -283,7 +283,7 @@ class TreeInstance(AbstractInstanceContext):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
all_annotations = py__annotations__(execution.tree_node)
|
all_annotations = py__annotations__(execution.tree_node)
|
||||||
defined = self.class_context.define_generics(
|
defined, = self.class_context.define_generics(
|
||||||
infer_type_vars_for_execution(execution, all_annotations),
|
infer_type_vars_for_execution(execution, all_annotations),
|
||||||
)
|
)
|
||||||
debug.dbg('Inferred instance context as %s', defined, color='BLUE')
|
debug.dbg('Inferred instance context as %s', defined, color='BLUE')
|
||||||
|
|||||||
@@ -272,11 +272,11 @@ class ClassContext(use_metaclass(CachedMetaClass, ClassMixin, FunctionAndClassBa
|
|||||||
yield type_var_dict.get(type_var.py__name__(), NO_CONTEXTS)
|
yield type_var_dict.get(type_var.py__name__(), NO_CONTEXTS)
|
||||||
|
|
||||||
if type_var_dict:
|
if type_var_dict:
|
||||||
return GenericClass(
|
return ContextSet([GenericClass(
|
||||||
self,
|
self,
|
||||||
generics=tuple(remap_type_vars())
|
generics=tuple(remap_type_vars())
|
||||||
)
|
)])
|
||||||
return self
|
return ContextSet({self})
|
||||||
|
|
||||||
def get_signatures(self):
|
def get_signatures(self):
|
||||||
init_funcs = self.py__getattribute__('__init__')
|
init_funcs = self.py__getattribute__('__init__')
|
||||||
|
|||||||
@@ -203,9 +203,9 @@ def infer_return_types(function_execution_context):
|
|||||||
|
|
||||||
type_var_dict = infer_type_vars_for_execution(function_execution_context, all_annotations)
|
type_var_dict = infer_type_vars_for_execution(function_execution_context, all_annotations)
|
||||||
|
|
||||||
return ContextSet(
|
return ContextSet.from_sets(
|
||||||
ann.define_generics(type_var_dict)
|
ann.define_generics(type_var_dict)
|
||||||
if isinstance(ann, AbstractAnnotatedClass) else ann
|
if isinstance(ann, (AbstractAnnotatedClass, TypeVar)) else ann
|
||||||
for ann in annotation_contexts
|
for ann in annotation_contexts
|
||||||
).execute_annotation()
|
).execute_annotation()
|
||||||
|
|
||||||
|
|||||||
@@ -432,6 +432,16 @@ class TypeVar(_BaseTypingContext):
|
|||||||
lazy.infer() for lazy in self._constraints_lazy_contexts
|
lazy.infer() for lazy in self._constraints_lazy_contexts
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def define_generics(self, type_var_dict):
|
||||||
|
try:
|
||||||
|
found = type_var_dict[self.py__name__()]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if found:
|
||||||
|
return found
|
||||||
|
return self._get_classes() or ContextSet({self})
|
||||||
|
|
||||||
def execute_annotation(self):
|
def execute_annotation(self):
|
||||||
return self._get_classes().execute_annotation()
|
return self._get_classes().execute_annotation()
|
||||||
|
|
||||||
@@ -564,18 +574,11 @@ class AbstractAnnotatedClass(ClassMixin, ContextWrapper):
|
|||||||
for generic_set in self.get_generics():
|
for generic_set in self.get_generics():
|
||||||
contexts = NO_CONTEXTS
|
contexts = NO_CONTEXTS
|
||||||
for generic in generic_set:
|
for generic in generic_set:
|
||||||
if isinstance(generic, AbstractAnnotatedClass):
|
if isinstance(generic, (AbstractAnnotatedClass, TypeVar)):
|
||||||
new_generic = generic.define_generics(type_var_dict)
|
result = generic.define_generics(type_var_dict)
|
||||||
contexts |= ContextSet([new_generic])
|
contexts |= result
|
||||||
if new_generic != generic:
|
if result != ContextSet({generic}):
|
||||||
changed = True
|
changed = True
|
||||||
else:
|
|
||||||
if isinstance(generic, TypeVar):
|
|
||||||
try:
|
|
||||||
contexts |= type_var_dict[generic.py__name__()]
|
|
||||||
changed = True
|
|
||||||
except KeyError:
|
|
||||||
contexts |= ContextSet([generic])
|
|
||||||
else:
|
else:
|
||||||
contexts |= ContextSet([generic])
|
contexts |= ContextSet([generic])
|
||||||
new_generics.append(contexts)
|
new_generics.append(contexts)
|
||||||
@@ -584,12 +587,12 @@ class AbstractAnnotatedClass(ClassMixin, ContextWrapper):
|
|||||||
# There might not be any type vars that change. In that case just
|
# There might not be any type vars that change. In that case just
|
||||||
# return itself, because it does not make sense to potentially lose
|
# return itself, because it does not make sense to potentially lose
|
||||||
# cached results.
|
# cached results.
|
||||||
return self
|
return ContextSet([self])
|
||||||
|
|
||||||
return GenericClass(
|
return ContextSet([GenericClass(
|
||||||
self._wrapped_context,
|
self._wrapped_context,
|
||||||
generics=tuple(new_generics)
|
generics=tuple(new_generics)
|
||||||
)
|
)])
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<%s: %s%s>' % (
|
return '<%s: %s%s>' % (
|
||||||
|
|||||||
@@ -306,17 +306,21 @@ def union4(x: U[int, str]):
|
|||||||
#? int() str()
|
#? int() str()
|
||||||
x
|
x
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# Type Vars
|
||||||
|
# -------------------------
|
||||||
|
|
||||||
TYPE_VAR = typing.TypeVar('TYPE_VAR')
|
TYPE_VARX = typing.TypeVar('TYPE_VARX')
|
||||||
|
TYPE_VAR_CONSTRAINTSX = typing.TypeVar('TYPE_VAR_CONSTRAINTSX', str, int)
|
||||||
# TODO there should at least be some results.
|
# TODO there should at least be some results.
|
||||||
#? []
|
#? []
|
||||||
TYPE_VAR.
|
TYPE_VARX.
|
||||||
#! ["TYPE_VAR = typing.TypeVar('TYPE_VAR')"]
|
#! ["TYPE_VARX = typing.TypeVar('TYPE_VARX')"]
|
||||||
TYPE_VAR
|
TYPE_VARX
|
||||||
|
|
||||||
|
|
||||||
class WithTypeVar(typing.Generic[TYPE_VAR]):
|
class WithTypeVar(typing.Generic[TYPE_VARX]):
|
||||||
def lala(self) -> TYPE_VAR:
|
def lala(self) -> TYPE_VARX:
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
@@ -324,6 +328,33 @@ def maaan(p: WithTypeVar[int]):
|
|||||||
#? int()
|
#? int()
|
||||||
p.lala()
|
p.lala()
|
||||||
|
|
||||||
|
def in_out1(x: TYPE_VARX) -> TYPE_VARX: ...
|
||||||
|
|
||||||
|
#? int()
|
||||||
|
in_out1(1)
|
||||||
|
#? str()
|
||||||
|
in_out1("")
|
||||||
|
#? str()
|
||||||
|
in_out1(str())
|
||||||
|
#?
|
||||||
|
in_out1()
|
||||||
|
|
||||||
|
def in_out2(x: TYPE_VAR_CONSTRAINTSX) -> TYPE_VAR_CONSTRAINTSX: ...
|
||||||
|
|
||||||
|
#? int()
|
||||||
|
in_out2(1)
|
||||||
|
#? str()
|
||||||
|
in_out2("")
|
||||||
|
#? str()
|
||||||
|
in_out2(str())
|
||||||
|
#? str() int()
|
||||||
|
in_out2()
|
||||||
|
##? str() int()
|
||||||
|
in_out2(1.0)
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# TYPE_CHECKING
|
||||||
|
# -------------------------
|
||||||
|
|
||||||
if typing.TYPE_CHECKING:
|
if typing.TYPE_CHECKING:
|
||||||
with_type_checking = 1
|
with_type_checking = 1
|
||||||
@@ -352,6 +383,10 @@ def foo(a: typing.List, b: typing.Dict, c: typing.MutableMapping) -> typing.Type
|
|||||||
#? int
|
#? int
|
||||||
foo()
|
foo()
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# cast
|
||||||
|
# -------------------------
|
||||||
|
|
||||||
def cast_tests():
|
def cast_tests():
|
||||||
x = 3.0
|
x = 3.0
|
||||||
y = typing.cast(int, x)
|
y = typing.cast(int, x)
|
||||||
|
|||||||
Reference in New Issue
Block a user