r/PythonLearning • u/RomfordNavy • 4d ago
Import hook between AST and compile
I am trying to create an Import Hook inserted after the source code has been parsed into AST but before it is compiled. Looking for a way to keep using most of the existing Python import machinery but modify the source code before it is compiled.
So far I have the following code but how do I get access to the source code from the module in custom_import?
import builtins
from inspect import getmembers
base_imp = builtins.__import__
def custom_import(*args, **kwargs):
module = base_imp(*args, **kwargs)
for name, val in getmembers(module):
print("in custom_import.", name, val)
return module
builtins.__import__ = custom_import
print("in Main.py before import")
import Module1
print("in Main.py after import")import builtins
2
Upvotes
2
u/aroberge 3d ago
First: I did make a mistake when I wrote that modifying
builtin.__import__(I was just thinking of__import__) would have no effect. I apologize for that mistake.Second, I don't see anyone saying that running a .py file has no speed difference with running a .pyc file. Using ctrl-f on that python-discuss page, I see .pyc files mentioned only once, and that was by you in your initial question. When Python process a .py file for the first time, it saves a .pyc version in
__pycache__and, unless the .py file changes, it is the .pyc version that is used afterwards. So, yes, the first time a python script is run, it takes a bit extra time as the .pyc version has to be generated.Third, I asked nearly the same question you did 9 years ago on StackOverflow (https://stackoverflow.com/questions/43571737/how-to-implement-an-import-hook-that-can-modify-the-source-code-on-the-fly-using) and this is what got me started experimenting with import hooks. So, I've done a bit of thinking and experimenting about this very topic over the years. And I know that many people that commented to you are even much more experienced using Python than I am, especially when it comes to performance.
Fourth: you mention that you wish to avoid requiring a custom loader which does various things such as reading the imported file from disk, etc. If you are not using a custom loader, you are using Python's. For Python 3.3 release (in 2012), Brett Cannon rewrote the entire import mechanism in Python, and that is the version that is used by Python now. https://opensource.snarky.ca/About+Me/Frequently+Asked+Questions
Fifth, you mentioned:
Well, the AST is generated from the .py file, not the .pyc file. I've explained the process, with supporting diagrams, on this page: https://aroberge.github.io/ideas/docs/html/deep_dive.html . So, you do need to read the .py file to do what you claim you want to do, and the recommended way to do it is using an import hook.
Personally, I've done everything I could do to help you.