On Jan 21, 2020, at 09:13, Christopher Barker <[email protected]> wrote:
>
> For (2) — see above— I want the relevant Python object, not just the string
> or bytes. A good example of this is the utilities (img2py I think) that come
> with wxPython: They bundle up a set of images into a Python module that
> creates wxImages on the fly. So you can import the module, and have a set of
> wxImages ready to go. That is pretty nice.
>
> I do think there could be some utilities to make that kind of thing easier,
> but making it easy, with a built in, to simply get the bytes or text from a
> file wouldn’t buy us much.
I just had a thought on this.
What if you had an importhooker module that allowed you to do this in your
top-level script or module:
from importhooker import hook
import json
from PIL import Image
import mything
@hook(text=True)
def json(f):
return json.load(f)
@hook(names="png jpg jpeg gif".split())
def image(f):
return Image.load(f)
hook(mything.import, text=True, names=["my”])
Note that the last one could actually be a custom Python dialect that adds some
new DSL or macro system or whatever; you’d still have to write the hard part of
the code that duplicates the normal py importer but adds in a
text/token/ast/bytecode transformer or whatever in the middle, but you’d get
all the boilerplate (the part that’s very hard to figure out how to write the
first time, and uninteresting after that) for free. But the other ones are the
real point; they make it trivial to load image resources, etc., because there
is no hard part beyond the boilerplate.
The import hook effectively does this pseudo code:
packagename, basename = split(name)
package = load_package(packagename)
for hook in registry:
filename = f"{basename}.{hook.ext}"
try:
f = importlib.resources.open_file(hook.text)
except ?:
continue
with f:
return hook.callback(f)
And now, in any of your other modules, you could do this:
# load cheese.png as a Pillow image named cheese
from spam.images import cheese
# load devconfig.json as a dict named config
from spam import devconfig as config
# load thing.my as a module named thing
from spam import thing
The API is just off the top of my head. You could add more arguments to control
encoding (otherwise it does the normal importlib thing of looking for a coding
declaration and falling back to UTF-8, which could be very wrong for some file
types), .pyc caching, sys.modules caching, etc.; I haven’t thought of what
might be useful and doable.
Anyway, this would still have all the limitations of import hooks. For example,
you can’t have a cheese.png and cheese.py or cheese.json in the same package.
And using it would have a performance cost (e.g., with all the hooks I added, a
failed import is going to take at least 3x as long to fail…). It just means
that you don’t have to write and install an import hook, figure out how to use
the normal machinery for the parts you’re not trying to change, worry about the
annoying error handling stuff (last I checked you have to manually construct
the ImportError out of the inner exception while doing some clunky stuff to
make it skip over irrelevant machinery in the callstack), etc.
Obviously you’d have to require importhooker off PyPI (and it would require
3.7+ or 3.4+ with a resources backport), which isn’t a problem for things
you’re distributing on PyPI or packaging up with py2exe or whatever but might
be limiting for people who want to create complicated packages and use them
right out of the build tree. But if this were useful enough, it could be added
into importlib in some future Python version.
Anyway, I think this would be a lot more useful than anything that just gives
you the raw bytes or text of a resource file. I’m not sure it’s useful enough
to be worth building. But it might be fun enough to try even if I can’t think
of a good use. :)
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/F6LGGQKHWRYTP4B2NRHR35YXGN47M5JL/
Code of Conduct: http://python.org/psf/codeofconduct/