Refactor TypeVar a bit so it's more resistant

This commit is contained in:
Dave Halter
2018-08-30 09:58:18 +02:00
parent 10383de959
commit f5f9fc1955
2 changed files with 18 additions and 18 deletions

View File

@@ -343,6 +343,9 @@ class BoundMethod(AbstractFunction):
return self._function.get_function_execution(arguments) return self._function.get_function_execution(arguments)
def get_default_param_context(self):
return self._class
def py__call__(self, arguments): def py__call__(self, arguments):
if isinstance(self._function, OverloadedFunctionContext): if isinstance(self._function, OverloadedFunctionContext):
return self._function.py__call__(self._get_arguments(arguments)) return self._function.py__call__(self._get_arguments(arguments))

View File

@@ -65,7 +65,7 @@ class _BaseTypingContext(Context):
@property @property
def name(self): def name(self):
return TypingName(self, self._name) return ContextName(self, self._name)
def __repr__(self): def __repr__(self):
return '%s(%s)' % (self.__class__.__name__, self._name.string_name) return '%s(%s)' % (self.__class__.__name__, self._name.string_name)
@@ -96,7 +96,7 @@ class TypingModuleName(NameWrapper):
# have any effects there (because it's never executed). # have any effects there (because it's never executed).
return return
elif name == 'TypeVar': elif name == 'TypeVar':
yield TypeVarClass(evaluator) yield TypeVarClass(self)
elif name == 'Any': elif name == 'Any':
yield Any(self) yield Any(self)
elif name == 'TYPE_CHECKING': elif name == 'TYPE_CHECKING':
@@ -157,7 +157,6 @@ class TypingContextWithIndex(_WithIndexBase):
elif string_name == 'Optional': elif string_name == 'Optional':
# Optional is basically just saying it's either None or the actual # Optional is basically just saying it's either None or the actual
# type. # type.
# TODO raise a warning if multiple params are given
return self._execute_annotations_for_all_indexes() \ return self._execute_annotations_for_all_indexes() \
| ContextSet(builtin_from_name(self.evaluator, u'None')) | ContextSet(builtin_from_name(self.evaluator, u'None'))
elif string_name == 'Type': elif string_name == 'Type':
@@ -335,18 +334,18 @@ class GenericClass(object):
return '%s(%s)' % (self.__class__.__name__, self._class_context) return '%s(%s)' % (self.__class__.__name__, self._class_context)
class TypeVarClass(Context): class TypeVarClass(_BaseTypingContext):
def py__call__(self, arguments): def py__call__(self, arguments):
unpacked = arguments.unpack() unpacked = arguments.unpack()
key, lazy_context = next(unpacked, (None, None)) key, lazy_context = next(unpacked, (None, None))
string_name = self._find_string_name(lazy_context) var_name = self._find_string_name(lazy_context)
# The name must be given, otherwise it's useless. # The name must be given, otherwise it's useless.
if string_name is None or key is not None: if var_name is None or key is not None:
debug.warning('Found a variable without a name %s', arguments) debug.warning('Found a variable without a name %s', arguments)
return NO_CONTEXTS return NO_CONTEXTS
return ContextSet(TypeVar(self.evaluator, string_name, unpacked)) return ContextSet(TypeVar(self._name, var_name, unpacked))
def _find_string_name(self, lazy_context): def _find_string_name(self, lazy_context):
if lazy_context is None: if lazy_context is None:
@@ -364,12 +363,10 @@ class TypeVarClass(Context):
return None return None
class TypeVar(Context): class TypeVar(_BaseTypingContext):
# TODO add parent_context def __init__(self, class_name, var_name, unpacked_args):
# TODO add name super(TypeVar, self).__init__(class_name)
def __init__(self, evaluator, string_name, unpacked_args): self.var_name = var_name
super(TypeVar, self).__init__(evaluator)
self.string_name = string_name
self._constraints_lazy_contexts = [] self._constraints_lazy_contexts = []
self._bound_lazy_context = None self._bound_lazy_context = None
@@ -398,7 +395,7 @@ class TypeVar(Context):
return NO_CONTEXTS return NO_CONTEXTS
def __repr__(self): def __repr__(self):
return '<%s: %s>' % (self.__class__.__name__, self.string_name) return '<%s: %s>' % (self.__class__.__name__, self.var_name)
class OverloadFunction(_BaseTypingContext): class OverloadFunction(_BaseTypingContext):
@@ -415,14 +412,14 @@ class BoundTypeVarName(AbstractNameDefinition):
def __init__(self, type_var, context_set): def __init__(self, type_var, context_set):
self._type_var = type_var self._type_var = type_var
self.parent_context = type_var.parent_context self.parent_context = type_var.parent_context
self.string_name = self._type_var.string_name self.var_name = self._type_var.var_name
self._context_set = context_set self._context_set = context_set
def infer(self): def infer(self):
return self._context_set return self._context_set
def __repr__(self): def __repr__(self):
return '<%s %s -> %s>' % (self.__class__.__name__, self.string_name, self._context_set) return '<%s %s -> %s>' % (self.__class__.__name__, self.var_name, self._context_set)
class TypeVarFilter(object): class TypeVarFilter(object):
@@ -442,7 +439,7 @@ class TypeVarFilter(object):
def get(self, name): def get(self, name):
for i, type_var in enumerate(self._type_vars): for i, type_var in enumerate(self._type_vars):
if type_var.string_name == name: if type_var.var_name == name:
try: try:
return [BoundTypeVarName(type_var, self._given_types[i])] return [BoundTypeVarName(type_var, self._given_types[i])]
except IndexError: except IndexError:
@@ -559,7 +556,7 @@ class LazyAnnotatedBaseClass(object):
new = ContextSet() new = ContextSet()
for type_var in type_var_set: for type_var in type_var_set:
if isinstance(type_var, TypeVar): if isinstance(type_var, TypeVar):
names = filter.get(type_var.string_name) names = filter.get(type_var.var_name)
new |= ContextSet.from_sets( new |= ContextSet.from_sets(
name.infer() for name in names name.infer() for name in names
) )