On Sun, Jan 19, 2020 at 08:09:32PM -0300, Soni L. wrote:

> We have importlib. We have importlib.resources. We can import modules. 
> We cannot (yet) import resources using the same-ish module import machinery.

Actually we can, using importlib.resources, which you already mentioned. 
The machinery is right there, although the documentation lacks a good 
tutorial or How To. Nevertheless, I got it to work correctly the first 
time after less than a minute's reading of the docs:

* create a package in the PYTHONPATH

    spam/
    +-- __init__.py

* add a text file "config" under the spam directory

* run:

    import importlib.resources
    import spam
    rsrc = importlib.resources.read_text(spam, "config")

and it Just Works.

What we can't (easily) do is import resources using the import *syntax*.

I am lead to believe that there is such as thing as "import hooks" that 
let you customize how and what gets imported. I have no idea how these 
hooks work, perhaps there's a good How To or guide somewhere? But as I 
understand it, you could right a hook which allows you to use the import 
syntax to load any thing you want from anywhere you want, so long as it 
fits into the existing import syntax.



> from foo.bar import resources "foo.txt" as foo, "bar.txt" as bar

The downsides of this proposal include:

(1) It requires a new keyword, one which I'm sure will clash with about 
a thousand bazillion modules that already use "resources" as a variable.

(2) It requires a change to the syntax of import statements to allow 
quoted file names, or else it requires you to name your data files with 
names which are legal identifiers. E.g. "foo" rather than "foo.txt".

I don't think this functionality is important enough or common enough to 
warrant not one but two new pieces of syntax, not when it is so easy to 
get the same functionality using the functional syntax

    rsrc = importlib.resources.read_text(spam, "config")

But perhaps you can start with an import hook that lets you write:

    import spam.config as rsrc

and leave the functional syntax for file names which aren't valid 
identifiers.



> or maybe:
> 
> foo = f"{from foo.bar import 'foo.txt'}"

An f-string is a disguised eval expression that returns a string. Using 
the same f-string syntax as a disguised import statement is a great 
example of the "Golden Hammer" anti-pattern applied to language design. 
"F-strings are cool, so we should make completely unrelated things like 
loading resources look like an f-string!".

https://en.wikipedia.org/wiki/Law_of_the_instrument

This likewise has a disadvantage that it requires new syntax. F-strings 
are expressions and they requires all the evaluated terms to be 
expressions, not statements:

    py> f'{import math}'
    File "<fstring>", line 1
        (import math)
         ^
    SyntaxError: invalid syntax

so your proposal would require f-strings to:

* accept import and from...import statements as a special case;

* rather than eval these terms, exec them, while still eval'ing
  everything else;

* but using a special, implicit, version of import which calls 
  importlib.resources.read_text rather than the standard import;

* leading to confusion when people try things like

    f'{from math import pi}'

  and get a surprising TypeError that math is not a package.



-- 
Steven
_______________________________________________
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/QZ5SW5HE3A3AVBOI2KMNCOJQ2YFLLCCD/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to