Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def AssertSourceEquals(self, src_or_tree_1, src_or_tree_2):
# Strip leading "\n"s for convenience
ast1 = self.ToAST(src_or_tree_1)
ast2 = self.ToAST(src_or_tree_2)
src1 = pytd_utils.Print(ast1).strip() + "\n"
src2 = pytd_utils.Print(ast2).strip() + "\n"
# Verify printed versions are the same and ASTs are the same.
ast1 = ast1.Visit(visitors.ClassTypeToNamedType())
ast2 = ast2.Visit(visitors.ClassTypeToNamedType())
if src1 != src2 or not pytd_utils.ASTeq(ast1, ast2):
# Due to differing opinions on the form of debug output, allow an
# environment variable to control what output you want. Set
# PY_UNITTEST_DIFF to get diff output.
if os.getenv("PY_UNITTEST_DIFF"):
self.maxDiff = None # for better diff output (assertMultiLineEqual) # pylint: disable=invalid-name
self.assertMultiLineEqual(src1, src2)
else:
sys.stdout.flush()
sys.stderr.flush()
print("Source files or ASTs differ:", file=sys.stderr)
print("-" * 36, " Actual ", "-" * 36, file=sys.stderr)
python_version=python_version)
except parser.ParseError as e:
sys.stderr.write(str(e))
sys.exit(1)
if opts.optimize:
parsed = optimize.Optimize(parsed,
builtins.GetBuiltinsPyTD(python_version),
lossy=opts.lossy,
use_abcs=opts.use_abcs,
max_union=opts.max_union,
remove_mutable=opts.remove_mutable,
can_do_lookup=False)
if opts.output is not None:
out_text = pytd_utils.Print(parsed, opts.multiline_args)
if opts.output == "-":
sys.stdout.write(out_text)
else:
with open(opts.output, "w") as out:
out.write(out_text)
d = option.to_pytd_def(self.exitpoint, name) # Deep definition
except NotImplementedError:
d = option.to_type(self.exitpoint) # Type only
if isinstance(d, pytd.NothingType):
if isinstance(option, abstract.Empty):
d = pytd.AnythingType()
else:
assert isinstance(option, typing_overlay.NoReturn)
if isinstance(d, pytd.Type) and not isinstance(d, pytd.TypeParameter):
data.append(pytd.Constant(name, d))
else:
data.append(d)
else:
log.error("No visible options for %s", name)
data.append(pytd.Constant(name, pytd.AnythingType()))
return pytd_utils.WrapTypeDeclUnit("inferred", data)
def _parse_predefined(self, pytd_subdir, module, as_package=False):
"""Parse a pyi/pytd file in the pytype source tree."""
try:
filename, src = pytd_utils.GetPredefinedFile(pytd_subdir, module,
as_package=as_package)
except IOError:
return None
ast = parser.parse_string(src, filename=filename, name=module,
python_version=self.python_version)
assert ast.name == module
return ast
if self._is_literal_base_type(base_type):
literal_parameters = []
for p in parameters:
if self._is_none(p):
literal_parameters.append(p)
elif isinstance(p, pytd.NamedType) and p.name not in ("True", "False"):
# TODO(b/123775699): support enums.
literal_parameters.append(pytd.AnythingType())
else:
literal_parameters.append(pytd.Literal(p))
return pytd_utils.JoinTypes(literal_parameters)
elif any(isinstance(p, (int, str)) for p in parameters):
parameters = ", ".join(
str(p) if isinstance(p, (int, str)) else "_" for p in parameters)
raise ParseError(
"%s[%s] not supported" % (pytd_utils.Print(base_type), parameters))
elif self._is_any(base_type):
return pytd.AnythingType()
elif len(parameters) == 2 and parameters[-1] is self.ELLIPSIS and (
not self._is_callable_base_type(base_type)):
element_type = parameters[0]
if element_type is self.ELLIPSIS:
raise ParseError("[..., ...] not supported")
return pytd.GenericType(base_type=base_type, parameters=(element_type,))
else:
parameters = tuple(pytd.AnythingType() if p is self.ELLIPSIS else p
for p in parameters)
if self._is_tuple_base_type(base_type):
return self._heterogeneous_tuple(base_type, parameters)
elif (self._is_callable_base_type(base_type) and
self._is_heterogeneous_tuple(parameters[0])):
if len(parameters) > 2:
def save_to_pickle(self, filename):
"""Save to a pickle. See PickledPyiLoader.load_from_pickle for reverse."""
# We assume that the Loader is in a consistent state here. In particular, we
# assume that for every module in _modules, all the transitive dependencies
# have been loaded.
items = tuple((name, serialize_ast.StoreAst(module.ast))
for name, module in sorted(self._modules.items()))
# Preparing an ast for pickling clears its class pointers, making it
# unsuitable for reuse, so we have to discard the builtins cache.
builtins.InvalidateCache(self.python_version)
# Now pickle the pickles. We keep the "inner" modules as pickles as a
# performance optimization - unpickling is slow.
pytd_utils.SavePickle(items, filename, compress=True)
def unwrap_type(typ):
if isinstance(typ, (pytd.ClassType, pytd.NamedType)):
typ_name = typ.name
elif isinstance(typ, pytd.UnionType):
typ_name = 'Union[' + ', '.join(unwrap_type(t) for t in typ.type_list) + ']'
elif isinstance(typ, pytd.AnythingType):
typ_name = 'typing.Any'
else:
typ_name = pytd_utils.Print(typ)
return unknown_to_any(typ_name)
def convert_string_type(string_type, unknown, mapping, global_lookup, depth=0):
"""Convert a string representing a type back to a pytd type."""
try:
# Check whether this is a type declared in a pytd.
cls = global_lookup.Lookup(string_type)
base_type = pytd_utils.NamedOrClassType(cls.name, cls)
except KeyError:
# If we don't have a pytd for this type, it can't be a template.
cls = None
base_type = pytd_utils.NamedOrClassType(string_type, cls)
if cls and cls.template:
parameters = []
for t in cls.template:
type_param_name = unknown + "." + string_type + "." + t.name
if type_param_name in mapping and depth < MAX_DEPTH:
string_type_params = mapping[type_param_name]
parameters.append(convert_string_type_list(
string_type_params, unknown, mapping, global_lookup, depth + 1))
else:
parameters.append(pytd.AnythingType())
return pytd.GenericType(base_type, tuple(parameters))
def _call_traces_to_function(call_traces, name_transform=lambda x: x):
funcs = collections.defaultdict(pytd_utils.OrderedSet)
for node, func, sigs, args, kws, retvar in call_traces:
# The lengths may be different in the presence of optional and kw args.
arg_names = max((sig.get_positional_names() for sig in sigs), key=len)
for i in range(len(arg_names)):
if not isinstance(func.data, abstract.BoundFunction) or i > 0:
arg_names[i] = function.argname(i)
arg_types = (a.data.to_type(node) for a in args)
ret = pytd_utils.JoinTypes(t.to_type(node) for t in retvar.data)
# TODO(kramm): Record these:
starargs = None
starstarargs = None
funcs[func.data.name].add(pytd.Signature(
tuple(pytd.Parameter(n, t, False, False, None)
for n, t in zip(arg_names, arg_types)) +
tuple(pytd.Parameter(name, a.data.to_type(node), False, False, None)
for name, a in kws),