Eric Snow <ericsnowcurren...@gmail.com> added the comment:

The current behavior is an implicit "-p .", which causes all sorts of 
hard-to-figure-out problems, most of which PEP 395 is rightly trying to fix.  
I'm suggesting that the next step would be to make "--nopath0" the default 
(rendering the flag unnecessary).  Since this changes the status quo, I'll try 
to make the case here that it's worth it.

---

First of all, the current implicit sys.path[0] initialization for scripts has 
been around since forever.  Why would we change it now?  The inspiration is 
three-fold: we _said_ we got rid of implicit relative imports already, PEP 395 
already has made a case for changing the status quo (though not to this 
degree), and a "-p" flag provides a simple mechanism to get the current 
behavior explicitly.

Like Nick says in PEP 395, "PEP 328 eliminated implicit relative imports from 
imported modules. This PEP proposes that the de facto implicit relative imports 
from main modules that are provided by the current initialisation behaviour for 
sys.path[0] also be eliminated."

I'm just saying we should go all the way, and that the "-p" flag would allow 
that.  As far as I can tell, there are two meaningful use cases for the 
currently implicit sys.path[0]:  When you are first _learning_ Python (not 
actually using it)...  When you are working on a new project...  Let's look at 
both, first relative to the currently implicit "-p .", then to the explicit 
site.

1. (current behavior) implicit sys.path[0] initialization

When a beginner is first learning Python, they learn at the interactive prompt 
or by running a single script.  Pretty quickly they learn about writing their 
own modules and using import to load them.

Where do the modules live?  In the CWD from which they are calling the Python 
executable.  The current implicit "-p ." means they can import their modules 
right there, and not have to learn yet about sys.path.  That's nice since they 
can concentrate their focus.

But later they _will_ run into hard-to-figure-out problems when they start 
relying on what are effectively implicit relative imports.  Or they will run 
into one of the problems that PEP 395 explains, which are likewise 
head-scratchers.  All of this can be pretty frustrating when you still don't 
know about things like the import machinery.

Consider how that beginner uses the implicit sys.path[0] behavior on a project, 
once they have some experience (hopefully I don't misrepresent something Nick 
explained to me).  The src/ directory of the project won't be under sys.path 
yet.  So to quickly test out their script, they change to src/ and run their 
script from there (something PEP 395 rightfully proposes fine-tuning).  They 
conveniently don't have to manually fiddle with sys.path.  That's a pretty neat 
trick.

The problem I have with this is that there's no difference between the sys.path 
workaround for the script and it's expected normal usage.  If you aren't aware 
of what's going on behind-the-scenes, you may end up with some confusing import 
exceptions later on.

2. explicit sys.path[0] initialization

With a -p flag, it's really easy to say "-p ." and get the previous implicit 
behavior.  Consider the impact on our beginner.  The try to run their script 
that imports modules in their CWD, but end up with an ImportError because we no 
longer have an implicit "-p .".

How is this an improvement?  No more mysterious default behavior.  There's only 
one way it will fail and it will fail the same way every time.  They'll learn 
pretty quickly (if not taught already) you have to use the -p flag if you want 
to import modules that aren't in the "standard" places.  The ImportError 
message, special-cased for imports in __main__, could help in that regard.

<aside>
As an aside, implicit or explicit "--nopath0", the path to the file for the 
failed import can really help in related situations.  Including it as an 
attribute on the ImportError, and especially in the error message, would rock.  
See issue1559549.
</aside>

For the "src/" use-case, the developer won't be able to rely on the implicit 
behavior anymore.  A simple, explicit "-p ." fills the gap and makes it clear 
that they are doing something unusual.  On top of that, they can use -p with 
the path to the "src/" directory from anywhere and not have to change their 
directory.  All the better if -p takes advantage of the proposals in PEP 395.


In the end, this boils down to opt-in vs. opt-out.  Either you opt-in to the 
sys.path[0] initialization by using -p, or you opt-out of the default implicit 
"-p ." by passing "--nopath0".  It's a case of "explicit is better than 
implicit" without a clear reason, to me, that the status quo is worth the 
exception anymore in the face of the alternative.

My only concern would be backwards compatibility.  How much do scripts out 
there rely on the implicit sys.path[0] initialization that aren't already 
broken by the removal of implicit relative imports?  I simply don't know.

However, I do know that having the -p flag that Nick has recommended would be 
awesome.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue13475>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to