Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def compile_import_or_require(self, expr, root, entries):
ret = Result()
for entry in entries:
assignments = "ALL"
prefix = ""
if isinstance(entry, HySymbol):
# e.g., (import foo)
module, prefix = entry, entry
elif isinstance(entry, HyList) and isinstance(entry[1], HySymbol):
# e.g., (import [foo :as bar])
module, prefix = entry
else:
# e.g., (import [foo [bar baz :as MyBaz bing]])
# or (import [foo [*]])
module, kids = entry
kids = kids[0]
def imports_as_stmts(self, expr):
"""Convert the Result's imports to statements"""
ret = Result()
for module, names in self.imports.items():
if None in names:
ret += self.compile(mkexpr('import', module).replace(expr))
names = sorted(name for name in names if name)
if names:
ret += self.compile(mkexpr('import',
mklist(module, mklist(*names))))
self.imports = defaultdict(set)
return ret.stmts
body += asty.Assign(expr, targets=[name], value=body.force_expr)
# Initialize the tempvar to None in case the `with` exits
# early with an exception.
initial_assign = asty.Assign(
expr, targets=[name], value=asty.Name(
expr, id=ast_str("None"), ctx=ast.Load()))
node = asty.With if root == "with*" else asty.AsyncWith
the_with = node(expr,
context_expr=ctx.force_expr,
optional_vars=thing,
body=body.stmts,
items=[ast.withitem(context_expr=ctx.force_expr,
optional_vars=thing)])
ret = Result(stmts=[initial_assign]) + ctx + the_with
# And make our expression context our temp variable
expr_name = asty.Name(expr, id=ast_str(var), ctx=ast.Load())
ret += Result(expr=expr_name)
# We don't give the Result any temp_vars because we don't want
# Result.rename to touch `name`. Otherwise, initial_assign will
# clobber any preexisting value of the renamed-to variable.
return ret
def _compile_branch(self, exprs):
"""Make a branch out of an iterable of Result objects
This generates a Result from the given sequence of Results, forcing each
expression context as a statement before the next result is used.
We keep the expression context of the last argument for the returned Result
"""
ret = Result()
for x in map(self.compile, exprs[:-1]):
ret += x
ret += x.expr_as_stmt()
if exprs:
ret += self.compile(exprs[-1])
return ret
def _compile_collect(self, exprs, with_kwargs=False, dict_display=False):
"""Collect the expression contexts from a list of compiled expression.
This returns a list of the expression contexts, and the sum of the
Result objects passed as arguments.
"""
compiled_exprs = []
ret = Result()
keywords = []
exprs_iter = iter(exprs)
for expr in exprs_iter:
if is_unpack("mapping", expr):
ret += self.compile(expr[1])
if dict_display:
compiled_exprs.append(None)
compiled_exprs.append(ret.force_expr)
elif with_kwargs:
keywords.append(asty.keyword(
expr, arg=None, value=ret.force_expr))
elif with_kwargs and isinstance(expr, HyKeyword):
try:
def __add__(self, other):
# If we add an ast statement, convert it first
if isinstance(other, ast.stmt):
return self + Result(stmts=[other])
# If we add an ast expression, clobber the expression context
if isinstance(other, ast.expr):
return self + Result(expr=other)
if isinstance(other, ast.excepthandler):
return self + Result(stmts=[other])
if not isinstance(other, Result):
raise TypeError("Can't add %r with non-compiler result %r" % (
self, other))
# Check for expression context clobbering
if self.expr and not self.__used_expr:
traceback.print_stack()
print("Bad boy clobbered expr %s with %s" % (
ast.dump(self.expr),
ast.dump(other.expr)))
# Fairly obvious addition
result = Result()
result.imports = other.imports
result.stmts = self.stmts + other.stmts
result.expr = other.expr
result.temp_variables = other.temp_variables
def f(parts):
# This function is called recursively to construct
# the nested loop.
if not parts:
if is_for:
if body:
bd = self._compile_branch(body)
return bd + bd.expr_as_stmt()
return Result(stmts=[asty.Pass(expr)])
if node_class is asty.DictComp:
ret = key + elt
val = asty.Tuple(
key, ctx=ast.Load(),
elts=[key.force_expr, elt.force_expr])
else:
ret = elt
val = elt.force_expr
return ret + asty.Expr(
elt, value=asty.Yield(elt, value=val))
(tagname, v), parts = parts[0], parts[1:]
if tagname in ("for", "afor"):
orelse = orel and orel.pop().stmts
node = asty.AsyncFor if tagname == "afor" else asty.For
return v[1] + node(
v[1], target=v[0], iter=v[1].force_expr, body=f(parts).stmts,
def compile(self, tree):
if tree is None:
return Result()
try:
ret = self.compile_atom(tree)
self.update_imports(ret)
return ret
except HyCompileError:
# compile calls compile, so we're going to have multiple raise
# nested; so let's re-raise this exception, let's not wrap it in
# another HyCompileError!
raise
except HyLanguageError as e:
# These are expected errors that should be passed to the user.
reraise(type(e), e, sys.exc_info()[2])
except Exception as e:
# These are unexpected errors that will--hopefully--never be seen
# by the user.
f_exc = traceback.format_exc()
def compile_atom(self, atom):
# Compilation methods may mutate the atom, so copy it first.
atom = copy.copy(atom)
return Result() + _model_compilers[type(atom)](self, atom)
def compile_def_expression(self, expr, root, pairs):
if not pairs:
return asty.Name(expr, id='None', ctx=ast.Load())
result = Result()
for pair in pairs:
result += self._compile_assign(root, *pair)
return result