Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def maybe_lookup_type_param(self, t, subst):
while isinstance(t, pytd.TypeParameter):
# We can only have type parameters in a class, and if so, we should have
# added them to the type parameter substitution map (subst) beforehand:
assert t in subst
if subst[t] is None:
# Function type parameter. Can be anything.
t = pytd.AnythingType()
else:
assert subst[t] != t, "Cyclic type parameter."
t = subst[t]
return t
# need to copy args tuple into list so can modify individual arg
# specfically we want to replace args with decorated variants
mod_args = []
# decorating all typed generators
cache_of_generators = {}
for i, actual in enumerate(args):
# first check actual is a generator
if isinstance(actual, types.GeneratorType):
# resolve the param signature at the formal position i
resolved_type = ConvertToType(module,
func_sig.params[i].type)
# Was the generator defined as generic-typed?
# TODO(raoulDoc): formal may be a union, so need to extract
# generator signature
if isinstance(resolved_type, pytd.HomogeneousContainerType):
# if yes replace generator with a decorated version
# we check if we already created a decorated version
# for cases such as foo(same_gen, same_gen)
if actual not in cache_of_generators:
new_gen = _WrapGenWithTypeCheck(func_name,
actual,
resolved_type.element_type)
cache_of_generators[actual] = new_gen
# get generator from cache
mod_args.append(cache_of_generators[actual])
else:
# here we have an untyped generator
mod_args.append(actual)
else:
mod_args.append(actual)
# type checking starts here
matcher: An instance of pytd.type_match.TypeMatch.
solver: An instance of pytd.booleq.Solver.
partial: The partial class to match. The class name needs to be prefixed
with "~" - the rest of the name is typically the same as complete.name.
complete: A complete class to match against. (E.g. a built-in or a user
defined class)
Returns:
An instance of pytd.booleq.BooleanTerm.
Raises:
FlawedQuery: If this call record is incompatible with the builtin.
"""
assert is_partial(partial)
assert is_complete(complete)
# Types recorded for type parameters in the partial builtin are meaningless,
# since we don't know which instance of the builtin used them when.
subst = {p.type_param: pytd.AnythingType() for p in complete.template}
formula = matcher.match_Class_against_Class(partial, complete, subst)
if formula is booleq.FALSE:
raise FlawedQuery("%s can never be %s" % (partial.name, complete.name))
solver.always_true(formula)
def new_alias_or_constant(self, name_and_value):
name, value = name_and_value
if name == "__slots__":
if not isinstance(value, list):
raise ParseError("__slots__ must be a list of strings")
return _SlotDecl(tuple(_handle_string_literal(s) for s in value))
elif value in [pytd.NamedType("True"), pytd.NamedType("False")]:
return pytd.Constant(name, pytd.NamedType("bool"))
else:
return pytd.Alias(name, value)
def make_param(param):
return pytd.Parameter(param, type=pytd.AnythingType(), kwonly=False,
optional=False, mutated_type=None)
sig = pytd.Signature(tuple(make_param(param) for param in params),
def VisitUnionType(self, union):
c = collections.Counter()
for t in set(union.type_list):
# TODO(rechen): How can we make this work with GenericType?
if isinstance(t, pytd.GENERIC_BASE_TYPE):
c += collections.Counter(self.hierarchy.ExpandSubClasses(str(t)))
# Below, c[str[t]] can be zero - that's the default for non-existent items
# in collections.Counter. It'll happen for types that are not
# instances of GENERIC_BASE_TYPE, like container types.
new_type_list = [t for t in union.type_list if c[str(t)] <= 1]
return pytd_utils.JoinTypes(new_type_list)
old_decorator = name_to_decorator[name]
check = _check_decorator_overload(name, old_decorator, decorator)
if check == _MERGE:
name_to_signatures[name].append(signature)
elif check == _REPLACE:
name_to_signatures[name] = [signature]
name_to_decorator[name] = decorator
_add_flag_overload(name_to_is_abstract, name, is_abstract, "abstractmethod")
_add_flag_overload(name_to_is_coroutine, name, is_coroutine, "coroutine")
methods = []
for name, sigs in name_to_signatures.items():
decorator = name_to_decorator[name]
is_abstract = name_to_is_abstract[name]
is_coroutine = name_to_is_coroutine[name]
if name == "__new__" or decorator == "staticmethod":
kind = pytd.STATICMETHOD
elif decorator == "classmethod":
kind = pytd.CLASSMETHOD
elif _is_property(name, decorator, sigs[0]):
kind = pytd.PROPERTY
# If we have only setters and/or deleters, replace them with a single
# method foo(...) -> Any, so that we infer a constant `foo: Any` even if
# the original method signatures are all `foo(...) -> None`. (If we have a
# getter we use its return type, but in the absence of a getter we want to
# fall back on Any since we cannot say anything about what the setter sets
# the type of foo to.)
if decorator.endswith(".setter") or decorator.endswith(".deleter"):
sigs = [sigs[0].Replace(return_type=pytd.AnythingType())]
else:
kind = pytd.METHOD
flags = 0
if is_abstract:
def new_union_type(self, types):
"""Return a new UnionType composed of the specified types."""
# UnionType flattens any contained UnionType's.
return pytd.UnionType(tuple(types))
A simplified pytd.Union.
"""
if not any(isinstance(t, pytd.GenericType) for t in union.type_list):
# Optimization: If we're not going to change anything, return original.
return union
union = pytd_utils.JoinTypes(union.type_list) # flatten
if not isinstance(union, pytd.UnionType):
union = pytd.UnionType((union,))
merge_tuples = self._should_merge(pytd.TupleType, union)
merge_callables = self._should_merge(pytd.CallableType, union)
if merge_tuples or merge_callables:
type_list = []
for t in union.type_list:
if merge_tuples and isinstance(t, pytd.TupleType):
t = pytd.GenericType(base_type=t.base_type,
parameters=(pytd.UnionType(t.parameters),))
elif merge_callables and isinstance(t, pytd.CallableType):
t = pytd.GenericType(base_type=t.base_type,
parameters=(pytd.AnythingType(), t.ret))
type_list.append(t)
union = union.Replace(type_list=tuple(type_list))
collect = {}
has_redundant_base_types = False
for t in union.type_list:
if isinstance(t, pytd.GenericType):
key = self._key(t)
if key in collect:
has_redundant_base_types = True
collect[key] = tuple(
pytd_utils.JoinTypes([p1, p2])
for p1, p2 in zip(collect[key], t.parameters))
else: