On Tue, Feb 2, 2010 at 6:13 AM, kj <span dir="ltr"><no.email@please.post></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im">In <<a href="mailto:pan.2010.02.02.03.28.54@REMOVE.THIS.cybersource.com.au">pan.2010.02.02.03.28.54@REMOVE.THIS.cybersource.com.au</a>> Steven D'Aprano <<a href="mailto:steven@REMOVE.THIS.cybersource.com.au">steven@REMOVE.THIS.cybersource.com.au</a>> writes:<br>
<br>
>As for fixing it, unfortunately it's not quite so simple to fix without<br>
>breaking backwards-compatibility. The opportunity to do so for Python 3.0<br>
>was missed.<br>
<br>
</div>This last point is to me the most befuddling of all. Does anyone<br>
know why this opportunity was missed for 3.0? Anyone out there<br>
with the inside scoop on this? Was the fixing of this problem<br>
discussed in some PEP or some mailing list thread? (I've tried<br>
Googling this but did not hit on the right keywords to bring up<br>
the deliberations I'm looking for.)<br></blockquote><div><br></div><div>The problem with "fixing" the import system is that touching it in any way potentially breaks *vast* volumes of code that works just right, right now in any version of Python. It's not even something you can easily test: there's a lot of edge-cases supporting various features that have been added over the years. A pure-python import mechanism with a set of test-cases to "prove" it reliably mimic'd the existing mechanism wasn't even complete by the time Python3 came out, without that, any changes to "fix" Python3+'s import system would just be a shot in the dark.</div>
<div><br></div><div>And there'd be no telling just /what/ it would break if you start changing these very old import semantics. </div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
P.S. Yes, I see the backwards-compatibility problem, but that's<br>
what rolling out a whole new versions is good for; it's a bit of<br>
a fresh start. I remember hearing GvR's Google Talk on the coming<br>
Python 3, which was still in the works then, and being struck by<br>
the sheer *modesty* of the proposed changes (while the developers<br>
of the mythical Perl6 seemed to be on a quest for transcendence to<br>
a Higher Plane of Programming, as they still are). </blockquote><div><br></div><div>Yes, it was a relatively modest upgrade, thankfully so. We actually have our fixed language, and Perl6 is coming on some point on the horizon. Python3 allowed backwards incompatible changes, but they still needed to have a justification to them: and more importantly, they usually needed to change from one well-defined state to a new, 'cleaner' well-defined state, so they could be automatically corrected or at least easily found. The Bytes/Unicode situation is one case where there wasn't a well-defined state you can convert from, and so with Python3, every single string you really need to look at and decide, "Should this have been bytes, or characters?".</div>
<div><br></div><div>Having to ask that question for every string is a significant burden, to expect someone to have to ask the same sort of question for every single import is asking -way- too much for people porting to Python 3.</div>
<div><br></div><div>Py3k's adoption is a slow, uphill process-- no one expected (from my reading at least)-- it to take less then years and multiple 3.x iterations before people would /really/ significantly start using it. There's too many third party modules people depend on and they have to slowly be converted. They're being converted, and IMHO there's steadily growing momentum on this (albeit not huge momentum), but had they messed with the import semantics-- this would be /way/ more difficult, and you might end up with a DOA project.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">In particular<br>
the business with print -> print() seemed truly bizarre to me: this<br>
is a change that will break a *huge* volume of code, and yet,<br>
judging by the rationale given for it, the change solves what are,<br>
IMHO, a relatively minor annoyances. Python's old print statement<br>
is, I think, at most a tiny little zit invisible to all but those<br>
obsessed with absolute perfection. </blockquote><div><br></div><div>You have a very strange perception of huge. For one thing, every single use of print() can be converted -automatically-: the rules of this change are very clear. The print statement was a bizarre sort of wart (look at >>!) and fixing it is easy. Further, *huge* volume of code-- /really/?! In my experience, print isn't really all /that/ common after you get out of the tutorial and start doing real code. If you're doing lots of shell scripting maybe that's not the case: but for any sort of server-daemon-process sort of apps, print is utterly unacceptable. I use the logging module. For GUI apps, same.</div>
<div><br></div><div>But for those times when you use print.. its /really easy/ to fix.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">And I can't imagine that whatever<br>
would be required to fix Python's import system could break more<br>
code than redefining the rules for a workhorse like print.<br></blockquote><div><br></div><div>Your imagination is lacking here then: virtually every single bit of Python code uses import, and messing with it can have wide implications that you can't even /define/ ahead of time. As such you can't write a guide, a 2to3 fixer, or a HOWTO to tell people: hey, this is how you used to do things in Python2, this is how you do them in Python3. Having them mess with the import machinery would be throwing every Py3 developer under the bus, saying, "Well, just run it. Fix whatever errors happen."</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">In contrast, the Python import problem is a ticking bomb potentially<br>
affecting all code that imports other modules. All that needs to<br>
happen is that, in a future release of Python, some new standard<br>
module emerges (like numbers.py emerged in 2.6), and this module<br>
is imported by some module your code imports. Boom! Note that it<br>
was only coincidental that the bug I reported in this thread occurred<br>
in a script I wrote recently. I could have written both scripts<br>
before 2.6 was released, and the new numbers.py along with it;<br>
barring the uncanny clairvoyance of some responders, there would<br>
have been, at the time, absolutely no plausible reason for not<br>
naming one of the two scripts numbers.py.<br></blockquote><div><br></div><div>This is drifting into hyperbole; yes, Python's flat import namespace isn't ideal, yes, it can mean that when a new version is released you may shadow something you didn't before, yes, that can cause code to break. Its really, really, really not anything like as bad as you're making it out to be.</div>
<div><br></div><div>Your bomb can be averted via:</div><div><br></div><div> - Don't use relative imports.</div><div><br></div><div> - Don't structure your code and environment such that your libs and/or scripts end up living in the global namespace if you want to be future-proof.</div>
<div><br></div><div> - If you didn't future-proof your code, then check What's New on new versions of Python. </div><div><br></div><div>There, time bomb disarmed.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
To the argument that the import system can't be easily fixed because<br>
it breaks existing code, one can reply that the *current* import<br>
system already breaks existing code, as illustrated by the example<br>
I've given in this thread: this could have easily been old pre-2.6<br>
code that got broken just because Python decided to add numbers.py<br>
to the distribution. </blockquote><div><br></div><div>Yes, one can make that argument, but it would be specious. Messing with the import system -would- have broken code, and done so in a way which can not be easily or clearly identified by looking at code directly, as you wouldn't know "break" until you somehow took the /entire/ layout of the system into account, which is infeasible. </div>
<div><br></div><div>The current import system -may- break code, if someone writes their code in such a way, structures their code in such a way, and Python happens to add a new item to its standard library which causes that code to now shadow a standard module.</div>
<div><br></div><div>The former case, 'change the import system', requires someone look at every single import, evaluate that import in the full context of the environment, and determine if its working as intended or not. </div>
<div><br></div><div>The latter case, 'leave the non-ideal import system in place', requires someone look at imports of top-level modules, and ensure that they don't shadow built-ins. You don't need to know where all the sys.path items are, you don't need to know if you're importing from a zip file, or anything like that. You just need to see if your top-level / relative import is shadowing a new standard library module or not.</div>
<div><br></div><div>Yes, the latter case means that if you are supporting new Python versions that come out, you'll have to make that evaluation with each one if you decide not to code and structure your code in such a way that it is future-proof.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">(Yes, Python can't guarantee that the names<br>
of new standard modules won't clash with the names of existing<br>
local modules, but this is true for Perl as well, and due to Perl's<br>
module import scheme (and naming conventions), a scenario like the<br>
one I presented in this thread would have been astronomically<br>
improbable. The Perl example shows that the design of the module<br>
import scheme and naming conventions for standard modules can go<br>
a long way to minimize the consequences of this unavoidable potential<br>
for future name clashes.)<br></blockquote><div><br></div><div>Again: It is very, very avoidable. </div><div><br></div><div>I know, cuz I've sorta been avoiding it easily and successfully for years now :P</div><div><br>
</div><div>--S</div></div>