Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion macropy/case_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ def prep_initialization(init_fun, args, vararg, kwarg, defaults, all_args):
kws.update({
'kwonlyargs': [],
'kw_defaults': [],
'posonlyargs': [],
'args': [ast.arg('self', None)] + [ast.arg(id, None) for id
in args],
'vararg': ast.arg(vararg, None) if vararg is not None else None,
Expand Down Expand Up @@ -235,7 +236,14 @@ def case_transform(tree, gen_sym, parents):
tree.bases = parents
assign = ast.FunctionDef(
gen_sym("prepare_"+tree.name),
ast.arguments([], None, [], [], None, []),
ast.arguments(
posonlyargs=[],
args=[],
vararg=None,
kwonlyargs=[],
kw_defaults=[],
kwarg=None,
defaults=[]),
outer,
[hq[apply]],
None
Expand Down
2 changes: 1 addition & 1 deletion macropy/core/failure.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def clear_errors(tree, **kw):
tb = "".join(traceback.format_tb(tree.__traceback__))
msg = str(tree)
if type(tree) is not AssertionError or tree.args == ():
msg = ("".join(tree.args) + "\nCaused by Macro-Expansion Error:\n" +
msg = ("".join(map(str, tree.args)) + "\nCaused by Macro-Expansion Error:\n" +
tb)
return hq[raise_error(MacroExpansionError(msg))]
else:
Expand Down
12 changes: 10 additions & 2 deletions macropy/core/hquotes.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,16 @@ def hygienator(tree, stop, scope, **kw):
id, subtree = res
if 'unhygienic' == id:
stop()
tree.slice.value.ctx = None
return tree.slice.value
if isinstance(tree.slice, ast.Index):
# Python 3.8-
tree.slice.value.ctx = None
return tree.slice.value
elif isinstance(tree.slice, ast.expr):
# Python 3.9+
tree.slice.ctx = None
return tree.slice
else:
assert False, f'Wrong type: {type(tree.slice)}'


macros.expose_unhygienic(ast)
Expand Down
29 changes: 23 additions & 6 deletions macropy/core/macros.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,18 +105,26 @@ class Expr(MacroType):
brackets, like ``amacro[foo]``."""

def detect_macro(self, in_tree):
if (isinstance(in_tree, ast.Subscript) and
type(in_tree.slice) is ast.Index): # noqa: E129
body_tree = in_tree.slice.value
if isinstance(in_tree, ast.Subscript):
name, macro_tree, call_args = self.get_macro_details(in_tree.value)
if name is not None and name in self.registry:
if type(in_tree.slice) is ast.Index:
# Python 3.8-
body_tree = in_tree.slice.value
elif isinstance(in_tree.slice, ast.expr):
# Python 3.8+
body_tree = in_tree.slice
else:
assert False, f'Wrong type: {type(in_tree.slice)}'

new_tree = yield MacroData(self.registry[name], macro_tree,
body_tree, call_args, {}, name)
assert isinstance(new_tree, ast.expr), ('Wrong type %r' %
type(new_tree))
new_tree = ast.Expr(new_tree)



class Block(MacroType):
"""Handles block macros, defined by using a ``with`` statement, like:

Expand Down Expand Up @@ -614,8 +622,12 @@ def detect_macros(tree, from_fullname, from_package=None, from_module=None):
if name.name not in mod.macros.decorator.registry
]

# lineno and col_offset are required fields, so we set them to 0.
# If this causes issues we might consider setting them to the
# lineno following the last actual import, but this too might cause
# issues, since it might collide with existing code.
stmt.names.extend([
ast.alias(x, x) for x in
ast.alias(x, x, lineno=0, col_offset=0) for x in
mod.macros.expose_unhygienic.registry.keys()
])

Expand All @@ -624,6 +636,11 @@ def detect_macros(tree, from_fullname, from_package=None, from_module=None):

def check_annotated(tree):
"""Shorthand for checking if an AST is of the form something[...]."""
if (isinstance(tree, ast.Subscript) and type(tree.slice) is ast.Index and
type(tree.value) is ast.Name): # noqa: E129
if not isinstance(tree, ast.Subscript) or type(tree.value) is not ast.Name:
return None
if type(tree.slice) is ast.Index:
# Python 3.8-
return tree.value.id, tree.slice.value
elif isinstance(tree.slice, ast.expr):
# Python 3.9+
return tree.value.id, tree.slice