Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
if len(signatures) == 1:
val = self.signature_to_callable(signatures[0], self.vm)
if (not isinstance(v, abstract.PYTD_FUNCTION_TYPES) or
not self.vm.annotations_util.get_type_parameters(val)):
# This is a workaround to make sure we don't put unexpected type
# parameters in call traces.
return self.value_instance_to_pytd_type(node, val, None, seen, view)
return pytd.NamedType("typing.Callable")
elif isinstance(v, (abstract.ClassMethod, abstract.StaticMethod)):
return self.value_to_pytd_type(node, v.method, seen, view)
elif isinstance(v, (special_builtins.IsInstance,
special_builtins.ClassMethodCallable)):
return pytd.NamedType("typing.Callable")
elif isinstance(v, mixin.Class):
param = self.value_instance_to_pytd_type(node, v, None, seen, view)
return pytd.GenericType(base_type=pytd.NamedType("__builtin__.type"),
parameters=(param,))
elif isinstance(v, abstract.Module):
return pytd.NamedType("__builtin__.module")
elif isinstance(v, abstract.SimpleAbstractValue):
if v.cls:
ret = self.value_instance_to_pytd_type(
node, v.cls, v, seen=seen, view=view)
ret.Visit(visitors.FillInLocalPointers(
{"__builtin__": self.vm.loader.builtins}))
return ret
else:
# We don't know this type's __class__, so return AnythingType to
# indicate that we don't know anything about what this is.
# This happens e.g. for locals / globals, which are returned from the
# code in class declarations.
log.info("Using ? for %s", v.name)
def p_funcdef(self, p):
"""funcdef : decorators DEF NAME LPAREN params RPAREN return raises signature maybe_body"""
_, decorators, _, name, _, params, _, return_type, raises, _, body = p
# TODO(kramm): Output a warning if we already encountered a signature
# with these types (but potentially different argument names)
if name == "__init__" and isinstance(return_type, pytd.AnythingType):
ret = pytd.NamedType("NoneType")
else:
ret = return_type
signature = pytd.Signature(params=tuple(params.required), return_type=ret,
starargs=params.starargs,
starstarargs=params.starstarargs,
exceptions=tuple(raises), template=())
for mutator in body:
try:
signature = signature.Visit(mutator)
except NotImplementedError as e:
make_syntax_error(self, e.message, p)
if not mutator.successful:
make_syntax_error(self, "No parameter named %s" % mutator.name, p)
# TODO(acaceres): if not inside a class, any decorator should be an error
def VisitClassType(self, node):
return pytd.NamedType(RenameBuiltinsPrefixInName(node.name))
param_list: List of parameters, where a paremeter is either a tuple
(name, type, default) or the ELLIPSIS special object. See
_validate_params for a more detailed description of allowed parameters.
return_type: A pytd type object.
body: ?
Returns:
A _NameAndSig object.
Raises:
ParseError: if any validity checks fail.
"""
if name == "__init__" and isinstance(return_type, pytd.AnythingType):
ret = pytd.NamedType("NoneType")
elif is_async:
base = pytd.NamedType("typing.Coroutine")
params = (pytd.NamedType("typing.Any"),
pytd.NamedType("typing.Any"),
return_type)
ret = pytd.GenericType(base, params)
else:
ret = return_type
params = _validate_params(param_list)
exceptions = []
mutators = []
for stmt in body:
if isinstance(stmt, pytd.Type):
exceptions.append(stmt) # raise stmt
continue
assert isinstance(stmt, tuple) and len(stmt) == 2, stmt
mutators.append(_Mutator(stmt[0], stmt[1]))
def VisitClassType(self, node):
return pytd.NamedType(node.name)
kind=v.kind,
flags=pytd.Function.abstract_flag(v.is_abstract))
elif isinstance(v, abstract.InterpreterFunction):
return self._function_to_def(node, v, name)
elif isinstance(v, abstract.SimpleFunction):
return self._simple_func_to_def(node, v, name)
elif isinstance(v, abstract.ParameterizedClass):
return pytd.Alias(name, v.get_instance_type(node))
elif isinstance(v, abstract.PyTDClass) and v.module:
# This happens if a module does e.g. "from x import y as z", i.e., copies
# something from another module to the local namespace. We *could*
# reproduce the entire class, but we choose a more dense representation.
return v.to_type(node)
elif isinstance(v, abstract.PyTDClass): # a namedtuple instance
assert name != v.name
return pytd.Alias(name, pytd.NamedType(v.name))
elif isinstance(v, abstract.InterpreterClass):
if v.official_name is None or name == v.official_name:
return self._class_to_def(node, v, name)
else:
return pytd.Alias(name, pytd.NamedType(v.official_name))
elif isinstance(v, abstract.TypeParameter):
return self._typeparam_to_def(node, v, name)
elif isinstance(v, abstract.Unsolvable):
return pytd.Constant(name, v.to_type(node))
else:
raise NotImplementedError(v.__class__.__name__)
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)
return self._simple_func_to_def(node, v, name)
elif isinstance(v, abstract.ParameterizedClass):
return pytd.Alias(name, v.get_instance_type(node))
elif isinstance(v, abstract.PyTDClass) and v.module:
# This happens if a module does e.g. "from x import y as z", i.e., copies
# something from another module to the local namespace. We *could*
# reproduce the entire class, but we choose a more dense representation.
return v.to_type(node)
elif isinstance(v, abstract.PyTDClass): # a namedtuple instance
assert name != v.name
return pytd.Alias(name, pytd.NamedType(v.name))
elif isinstance(v, abstract.InterpreterClass):
if v.official_name is None or name == v.official_name:
return self._class_to_def(node, v, name)
else:
return pytd.Alias(name, pytd.NamedType(v.official_name))
elif isinstance(v, abstract.TypeParameter):
return self._typeparam_to_def(node, v, name)
elif isinstance(v, abstract.Unsolvable):
return pytd.Constant(name, v.to_type(node))
else:
raise NotImplementedError(v.__class__.__name__)
return self.match_Generic_against_Unknown(t1, t2, subst)
elif isinstance(t1, pytd.GenericType) and isinstance(t2, pytd.GenericType):
return self.match_Generic_against_Generic(t1, t2, subst)
elif isinstance(t1, pytd.GenericType):
# E.g. list[...] matches against list, or even object.
return self.match_type_against_type(t1.base_type, t2, subst)
elif isinstance(t2, pytd.GenericType):
if self.any_also_is_bottom:
# E.g. list (a.k.a. list[Any]) matches against list[str]
return self.match_type_against_type(t1, t2.base_type, subst)
else:
return booleq.FALSE
elif is_unknown(t1) and is_unknown(t2):
return booleq.Eq(t1.name, t2.name)
elif (isinstance(t1, (pytd.NamedType, StrictType)) and
isinstance(t2, (pytd.NamedType, StrictType))):
if is_complete(t1) and is_complete(t2) and t1.name != t2.name:
# Optimization: If we know these two can never be equal, just return
# false right away.
return booleq.FALSE
else:
return booleq.Eq(t1.name, t2.name)
elif isinstance(t1, pytd.LateType) or isinstance(t2, pytd.LateType):
# Unresolved types never match against anything.
return booleq.FALSE
else:
raise AssertionError("Don't know how to match %s against %s" % (
type(t1), type(t2)))
def p_alias_or_constant(self, p):
"""alias_or_constant : NAME ASSIGN type"""
# Other special cases of constant definitions are handled in constantdef,
# e.g. p_constantdef_int (for "name = 0")
if p[3] in [pytd.NamedType("True"), pytd.NamedType("False")]:
# See https://github.com/google/pytype/issues/14
p[0] = pytd.Constant(p[1], pytd.NamedType("bool"))
else:
self.aliases[p[1]] = p[3]
p[0] = pytd.Alias(p[1], p[3])