On Tue, May 17, 2022 at 1:46 PM Greg Werbin <outth...@me.gregwerbin.com>
wrote:

>   1) Allow a directory to be a resource in and of itself, and provide APIs
> for working with "directory-type" resources.
>

I'm still confused here -- what would a "directory be a resource" even
mean? A directory is not a file, it is a "container" of files. I still have
no idea what people mean when they say a directory could be a resource.

If we go back to the OPs point, they were saying that they didn't like that
you have to put an __init__.py in a dir in order to put resources in it.
And I get that idea, but that wouldn't be making a dir a resource, it would
be allowing a directory structure inside a package in which to put
resources.

Remember that the directory that holds a package (has an __init__.py file)
is not itself a package, if anything, the __init__.py file is the resource
here.


>   2) Allow resources with "/" in the name, and provide APIs to interact
> with such resources as if the were filesystem directories, remaining
> agnostic as to whether they actually are filesystem directories, to the
> best extent possible. This is similar to how cloud storage providers like
> Amazon S3 handle slashes in names. This would mean that you can put
> resources in subdirectories of package directories that are not themselves
> subpackages.
>

Sure, this could make sense -- but a point here:

The whole "resource" thing in import lib is, well, part of the import
system. IIUC, it is provided so that the existing system built for loading
modules can be used for things other than Python modules. It was not
designed to be general purpose.

No one seems to mind that with the following file structure:

pkg/
    __init__.py
   a_module.py
   a_subdir/
        something.py

you can't do:

from pkg.a_subdir import something
or
from pkg import a_subdir/something

I think one reason a dir has to have a __init__.py to be a package (and to
hold other modules/packages) is that a dir is NOT a file, i.e. not a
resource, i.e. has no way to hold any information. The __init__.py is
needed so that when you import a package, there's a way to put some names
in that namespace.

That is -- the directory itself can not be a package -- it doesn't have a
"binary blob" at all.


>   3) Provide APIs for working with resources within packages in a fashion
> that more closely resembles directory and subdirectory relationships. I am
> not sure exactly what this would entail.
>

Isn't that the same as (2) ?

As discussed above, (1) is a significant deviation from the existing model
> of "resources" as described in the docs and implemented in
> importlib.resources, so it's probably not a viable option.
>

Exactly -- if you want a more rich resource handling system, maybe look to
a third party package. How does setuptools' pkg_resources handle all this
for instance?


> (2) seems like a useful feature, if only because it seems more natural to
> write "assets/images/foo.png" in resource "my_app.data", as opposed to
> "foo.png" in resource "my_app.data.assets.images".


I'm confused again -- in this case, foo.png is a resource, my_app.data is
not a resource, and nor is, or will be, assets/images.

>
I think the way it works now is that you'd get the resource something like
this:

>
To get the path to a actual file:

>
files(my_app.data.assets.images).joinpath('foo.png')

>
(or my prefered syntax:)

files(my_app.data.assets.images) / ('foo.png')

To get the binary data (which I think is the whole point to this):

>
foo_img = resource_bytes('my_app.data.assets.images', 'foo.png')

>
of course, you can first do:

from my_app.data.assets import images

and then:

foo_img =  resource_bytes(images, 'foo.png')

In order for that to work, the data, assets, and images dirs all need to
have an __init__.py file, because the first argument to resource_bytes has
to be a package. Again, is that really such a heavy lift ?

But I'm a bit confused as to what's being proposed here. If dirs with only
non-python module resources didn't need a __init__.py, would you be able to
access them the same way? or are we thinking it would be:

foo_img = resource_bytes('my_app.data','assets/images/foo.png')

which probably wouldn't work today (untested). However, if you only want to
support actual files on disk, this would work:

foo_img = open(files(my_app.data) / 'assets/images/foo.png', 'b').read()

It might take some machinations to get your build system to copy those
files in the right place, but it should work just fine.

By the way:

In [5]: resources.is_resource?
Signature: resources.is_resource(package: Union[str, module], name: str) ->
bool
Docstring:
True if 'name' is a resource inside 'package'.

Directories are *not* resources.

And check this out:

In [6]: resources.is_resource('importlib','__init__.py')
Out[6]: True

So the __init__.py file is a resource. and:

In [9]: resources.is_resource('importlib','metadata')
Out[9]: False

metadata is a sub-package inside importlib, it has an __init__.py, but it
is not a resource itself.

-CHB


-- 
Christopher Barker, PhD (Chris)

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/H4MIMLQXHVUKD5IIBAYE6446FQW63P62/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to