Fix cases where dicts are passed to dicts and generics were not properly applied

This commit is contained in:
Dave Halter
2019-08-27 20:41:46 +02:00
parent 18ecb5a746
commit 066b189bfa
5 changed files with 22 additions and 14 deletions

View File

@@ -4,6 +4,7 @@ from parso.python import tree
from jedi._compatibility import zip_longest from jedi._compatibility import zip_longest
from jedi import debug from jedi import debug
from jedi.cache import memoize_method
from jedi.inference.utils import PushBackIterator from jedi.inference.utils import PushBackIterator
from jedi.inference import analysis from jedi.inference import analysis
from jedi.inference.lazy_value import LazyKnownValue, LazyKnownValues, \ from jedi.inference.lazy_value import LazyKnownValue, LazyKnownValues, \
@@ -158,6 +159,7 @@ class AbstractArguments(_AbstractArgumentsMixin):
class AnonymousArguments(AbstractArguments): class AnonymousArguments(AbstractArguments):
@memoize_method
def get_executed_param_names_and_issues(self, execution_context): def get_executed_param_names_and_issues(self, execution_context):
from jedi.inference.dynamic_params import search_param_names from jedi.inference.dynamic_params import search_param_names
return search_param_names( return search_param_names(

View File

@@ -13,7 +13,7 @@ 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.typing import TypeVar, LazyGenericClass, \ from jedi.inference.gradual.typing import TypeVar, LazyGenericClass, \
AbstractAnnotatedClass AbstractAnnotatedClass, TypingClassValueWithIndex
from jedi.inference.gradual.typing import GenericClass from jedi.inference.gradual.typing import GenericClass
from jedi.inference.helpers import is_string from jedi.inference.helpers import is_string
from jedi.inference.compiled import builtin_from_name from jedi.inference.compiled import builtin_from_name
@@ -275,10 +275,11 @@ def infer_type_vars_for_execution(execution_context, annotation_dict):
def _merge_type_var_dicts(base_dict, new_dict): def _merge_type_var_dicts(base_dict, new_dict):
for type_var_name, values in new_dict.items(): for type_var_name, values in new_dict.items():
try: if values:
base_dict[type_var_name] |= values try:
except KeyError: base_dict[type_var_name] |= values
base_dict[type_var_name] = values except KeyError:
base_dict[type_var_name] = values
def _infer_type_vars(annotation_value, value_set): def _infer_type_vars(annotation_value, value_set):

View File

@@ -285,7 +285,6 @@ class FunctionExecutionContext(ValueContext, TreeContextMixin):
until_position=until_position, until_position=until_position,
origin_scope=origin_scope) origin_scope=origin_scope)
@inference_state_method_cache()
def get_executed_param_names_and_issues(self): def get_executed_param_names_and_issues(self):
return self.var_args.get_executed_param_names_and_issues(self) return self.var_args.get_executed_param_names_and_issues(self)

View File

@@ -195,6 +195,7 @@ class AbstractInstanceValue(Value):
name.tree_name.parent name.tree_name.parent
) )
bound_method = BoundMethod(self, function) bound_method = BoundMethod(self, function)
yield bound_method.as_context(self.var_args) yield bound_method.as_context(self.var_args)
@inference_state_method_cache() @inference_state_method_cache()
@@ -288,22 +289,24 @@ class TreeInstance(AbstractInstanceValue):
from jedi.inference.gradual.annotation import py__annotations__, \ from jedi.inference.gradual.annotation import py__annotations__, \
infer_type_vars_for_execution infer_type_vars_for_execution
for func in self._get_annotation_init_functions(): for signature in self.class_value.py__getattribute__('__init__').get_signatures():
# Just take the first result, it should always be one, because we # Just take the first result, it should always be one, because we
# control the typeshed code. # control the typeshed code.
bound = BoundMethod(self, func) bound_method = BoundMethod(self, signature.value)
execution = bound.as_context(self.var_args) execution = bound_method.as_context(self.var_args)
if not execution.matches_signature(): if not execution.matches_signature():
# First check if the signature even matches, if not we don't # First check if the signature even matches, if not we don't
# need to infer anything. # need to infer anything.
continue continue
all_annotations = py__annotations__(execution.tree_node) all_annotations = py__annotations__(execution.tree_node)
defined, = self.class_value.define_generics( type_var_dict = infer_type_vars_for_execution(execution, all_annotations)
infer_type_vars_for_execution(execution, all_annotations), if type_var_dict:
) defined, = self.class_value.define_generics(
debug.dbg('Inferred instance value as %s', defined, color='BLUE') infer_type_vars_for_execution(execution, all_annotations),
return defined )
debug.dbg('Inferred instance value as %s', defined, color='BLUE')
return defined
return None return None
def get_annotated_class_object(self): def get_annotated_class_object(self):

View File

@@ -261,6 +261,9 @@ def y(a):
#? #?
y(**d) y(**d)
#? str()
d['a']
# problem with more complicated casts # problem with more complicated casts
dic = {str(key): ''} dic = {str(key): ''}
#? str() #? str()