Re: Loading Resources From a Python Module/Package

Brett Cannon <[email protected]> Sat, 31 Jan 2015 16:31:41 +0000
Newsgroups gmane.comp.python.import
Message-ID <CAP1=2W4jg1E6LO6MnEKcsXxnV29eCSWiCNbRHzG7H1MPM33ayg@mail.gmail.com>
On Sat Jan 31 2015 at 10:54:22 AM Paul Moore <[email protected]> wrote:

> On 31 January 2015 at 15:47, Donald Stufft <[email protected]> wrote:
> >> It's certainly possible to add a new API that loads resources based on
> >> a relative name, but you'd have to specify relative to *what*.
> >> get_data explicitly ducks out of making that decision.
> >
> > data = __loader__.get_bytes(__name__, “logo.gif”)
>
> Quite possibly. It needs a bit of fleshing out to make sure it doesn't
> prohibit sharing of loaders, etc, in the way Brett mentions.


By specifying the package anchor point I don't think it does.


> Also, the
> fact that it needs __name__ in there feels wrong - a bit like the old
> version of super() needing to be told which class it was being called
> from.


You can't avoid that. This is the entire reason why loader reuse is a pain;
you **have** to specify what to work off of, else its ambiguous and a
specific feature of a specific loader.

But this is only an issue when you are trying to access a file relative to
the package/module you're in. Otherwise you're going to be specifying a
string constant like 'foo.bar'.


> But in principle I don't object to finding a suitable form of
> this.
>
> And I like the name get_bytes - much more explicit in these Python 3
> days of explicit str/bytes distinctions :-)


One unfortunate side-effect from having a new method to return bytes from a
data file is that it makes get_data() somewhat redundant. If we make it
get_data_filename(package_name, path) then it can return an absolute path
which can then be passed to get_data() to read the actual bytes. If we
create importlib.resources as Donald has suggested then all of this can be
hidden  behind a function and users don't have to care about any of this,
e.g. importlib.resources.read_data(module_anchor, path).

One thing to consider is do we want to allow anything other than filenames
for the path part? Thanks to namespace packages every directory is
essentially a package, so we could say that the package anchor has to
encapsulate the directory and the path bit can only be a filename. That
gets us even farther away from having the concept of file paths being
manipulated in relation to import-related APIs.

And just so I don't forget it, I keep wanting to pass an actual module in
so the code can extract the name that way, but that prevents the __name__
trick as you would have to import yourself or grab the module from
sys.modules.

_______________________________________________
Import-SIG mailing list
[email protected]
https://mail.python.org/mailman/listinfo/import-sig