-
Notifications
You must be signed in to change notification settings - Fork 177
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove restriction on macros in __main__ #92
Comments
Another way to achieve the same goal is to use the SaveExporter as step in the testing/packaging of your sources, thus removing the need for macro expansion at runtime, have you tried that? This has the effect of launching the application/script in lesser time and at same time if the need to for debugging emerges you can follow the code like in any normal python script. |
Oh, that looks useful actually. I must have missed that when I skimmed the docs the first time. The resulting pre-expanded files should have perfect compatibility with all the other Python tools. But unless I'm actively debugging the macro itself, I would actually prefer to work with the unexpanded source that uses the macros if possible, even when debugging. It's generally more readable than the sometimes-complex expansion, for the same reason that it's preferable to work with source instead of assembly. My approach seems to work fine if I add a SaveExporter does not really address my primary motivating use case for this issue: one-file scripts. It adds an extra layer of complexity (a compile step and output directory) for what could have been a single seamless import at the top of the script. CPython doesn't actually save a |
Improved version import ast, importlib, inspect, sys
from macropy.core.macros import ModuleExpansionContext, detect_macros
__main__ = sys.modules["__main__"]
source = inspect.getsource(__main__)
if "import macros\n" in source:
tree = ast.parse(source)
exec(
compile(
source=ast.Module(
ModuleExpansionContext(
tree,
source,
bindings=[
(importlib.import_module(mod), bind)
for mod, bind in detect_macros(tree, "__main__")
],
)
.expand_macros()
.body
),
filename=__main__.__file__,
mode="exec",
dont_inherit=True,
),
__main__.__dict__,
)
raise SystemExit Turns out that we don't need the frame to get the source or the globals. Adding the |
You could also use the
within the script, which will get Python to decode the source file through macropy. For direct use, you will need to copy the codec to the Python encoder directory. See the See this example on how to do it. |
https://macropy3.readthedocs.io/en/latest/overview.html says,
Sometimes I use Python for big projects, but sometimes I just need a one-page script and just want to import my macros and run it directly. It's a pain to have to write a new launcher to import it every time just so I can have macros.
Writing a
macropy
launcher aliased to replacepython
altogether would help some, but it messes up theif __name__ == '__main__':
pattern I need to use sometimes. Then I'd have to remember to launch with normalpython
instead, but only if I didn't use macros...Anyway, I think we can do better.
macros/__init__.py
macros/macros_in_main.py
main.py
This is just a proof of concept. I'm probably missing some edge cases and interactions, but it proves that it's at least possible to have syntactic macros, even in a file that is run "directly".
Maybe there's an easier way to do this, but I didn't see any kind of
exec_with_macros()
in the library.Something like the above could perhaps replace the
import macropy.activate
to allow a script to be both imported and run on its own (the usual use case for theif __name__ == '__main__':
construct).The text was updated successfully, but these errors were encountered: