[Python-ideas] Pseudo-package for current directory
Steven D'Aprano
steve at pearwood.info
Mon Mar 7 19:49:24 EST 2016
On Tue, Mar 08, 2016 at 06:34:11AM +1100, Chris Angelico wrote:
[...]
> >> So the solution is to treat the current directory as a pseudo-package.
> >> It'd be a backward-incompatible change, so it would need to be
> >> explicitly invoked. Something like:
> >>
> >> python3 -p somefile.py
> >>
> >> which would pretend to create an __init__.py in the current directory,
> >> change to the parent, and "from dirname import somefile".
[...]
> > Even if it works, it relies on the user being knowledgeable enough to
> > run `python3 -p script` instead of `python3 script`, which means the
> > people who most need this new feature are the least likely to use it. I
> > think that's the fatal objection to this: if the user knows enough to
> > run -p, she knows enough to diagnose an accidental shadowing.
>
> Right, this is a concern. But I don't want to break backward
> compatibility. Otherwise, the common situation of having multiple .py
> files in the same directory and having them import each other would be
> broken.
Only if they shadow something in the std lib. However we fix this,
whatever the mechanism, it is going to break backwards compatibility for
those shadowing the stdlib, which is of course the whole point of the
exercise.
I don't think it's worth trying to gradually introduce this: those
affected will either want this change or be able to work around it
easily. The work around doesn't involve going through your entire code
base changing (potentially) thousands of lines of code. It likely
involves changing the name of one or two files, or explicitly adding "."
to the front of your path. So even though it is a technical break of
backwards compatibility, I think it is (1) minor enough and (2)
important enough to warrant just doing it.
There are three cases where people would notice a difference:
(1) Deliberate shadowing of the std lib. In this case, if you are
intentionally shadowing a module, I think you are probably capable of
coming up with a work-around for the change. E.g. you might explicitly
add '.' to your PYTHONPATH environment variable to force it to the
front, so as to get the current behaviour.
I think that's a rare case and changing the default behaviour here is
acceptible.
(2) Accidental shadowing of the std lib where they currently experience
mysterious breakage. E.g.:
[steve at ando tmp]$ touch time.py
[steve at ando tmp]$ idle
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/local/lib/python2.7/idlelib/run.py", line 7, in <module>
import threading
File "/usr/local/lib/python2.7/threading.py", line 13, in <module>
from time import time as _time, sleep as _sleep
ImportError: cannot import name time
This will be fixed, which is the whole purpose of the exercise.
(3) Accidental shadowing where they *don't* currently experience
breakage, but will after the change.
E.g. suppose I have a main script "spam.py" and a file called "code.py"
in the same directory, and spam.py imports code. Currently, that shadows
the stdlib code.py, but harmlessly since few (if any) things depend on
the code module. After the change, the stdlib code.py will now shadow
the custom one, causing breakage.
I suspect that this will be rare in well-established or professional
code, where the devs are more familiar with the std lib, but a bit more
common in the case of beginners. This is unfortunate, but the fix is
simple: rename your file and change a few imports: `import code` becomes
`import mycode as code`.
--
Steve
More information about the Python-ideas
mailing list