RE: [Idle-dev] Forward progress with full backward compatibility

[Peter Funk]
... 2. What should the new Interpreter do, if he sees a source file without a pragma defining the language level?
Python has tens of thousands of users now -- if it doesn't default to "Python 1.5.2" (however that's spelled), approximately 79.681% of them will scream. Had the language done this earlier, it would have been much more sellable to default to the current version. However, a default is *just* "a default", and platform-appropriate config mechanism (from Windows registry to cmdline flag) could be introduced to change the default. That is, 1.7 comes out and all my code runs fine without changing a thing. Then I set a global config option to "pretend every module that doesn't say otherwise has a 1.7 pragma in it", and run things again to see what breaks. As part of the process of editing the files that need to be fixed, I can take that natural opportunity to dump in a 1.7 pragma in the modules I've changed, or a 1.6 pragma in the broken modules I can't (for whatever reason) alter just yet. Two pleasant minutes <wink> later, I'll have 6,834 .py files all saying "1.7" at the top. Hmm! So when 1.8 comes out, not a one of them will use any incompatible 1.8 features. So I'll also need a global config option that says "pretend every module has a 1.8 pragma in it, *regardless* of whether it has some other pragma in it already". But that will also screw up the one .py file I forgot that had a 1.5.2 pragma in it. Iterate this process a half dozen times, and I'm afraid the end result is intractable. Seems it would be much more tractable over the long haul to default to the current version. Then every incompatible change will require changing every file that relied on the old behavior (to dump in a "no, I can't use the current version's semantics" pragma) -- but that's the situation today too. The difference is that the minimal change required to get unstuck would be trivial. A nice user (like me <wink>) would devote their life to keeping up with incompatible changes, so would never ever have a version pragma in any file. So I vote "default to current version" -- but, *wow*, that's going to be hard to sell. Tech note: Python's front end is not structured today in such a way that it's feasible to have the parser deal with a change in the set of keywords keying off a pragma -- any given identifier today is either always or never a keyword, and that choice is hardwired into the generated parse tables. Not a reason to avoid starting this process with 1.6, just a reason to avoid adding new keywords in 1.6 (it will take some real work to overcome the front end's limitations here). go-for-it!-ly y'rs - tim

Language pragmas are all fine and good, BUT ... Here in the Real World(TM) we have to deal with version in compatibilities out the wazoo. I am currently writing a java application that has to run on JDK 1.1, and 1.2, and microsoft's half-way JDK 1.1+1/2 thingy. Python comes installed on many major linux distributions, and the installed base is likely to be even larger than it is now by the time Python 1.6 is ready for the big time. I'd like to tell people who still have RedHat 6.2 installed in six months that they can just download a 40k script and not a 5M interpreter source tarball (which will be incompatible with their previous python installation, which they need for other stuff) when I deploy an end-user application. (Sorry, I can't think of another way to say that, I'm still recovering from java-isms...) :-) What I'm saying is that it would be great if you could write an app that would still function with existing versions of the interpreter, but would be missing certain features that were easier to implement with the new language symantics or required a new core library feature. Backward compatibility is as important to me as forward compatibility, and I'd prefer not to achieve it by writing exclusively to python 1.5.2 for the rest of my life. The way I would like to see this happen is NOT with language pragmas ('global' strikes me as particularly inappropriate, since that already means something else...) but with file-extensions. For example, if you have a python file which uses 1.6 features, I call it 'foo.1_6.py'. I also have a version that will work with 1.5, albeit slightly slower/less featureful: so I call it 'foo.py'. 'import foo' will work correctly. Or, if I only have 'foo.1_6.py' it will break, which I gather would be the desired behavior. As long as we're talking about versioning issues, could we perhaps introduce a slightly more robust introspective facility than assert(sys.version[:3])=='1.5' ? And finally, I appreciate that some physics students may find it confusing that 1/2 yeilds 0 instead of 0.5, but I think it would be easier to just teach them to do 1./2 rather than changing the symantics of integer constants completely ... I use python to do a lot of GUI work right now (and it's BEAUTIFUL for interfacing with Gtk/Tk/Qt, so I'm looking forward to doing more of it) and when I divide *1* by *2*, that's what I mean. I want integers, because I'm talking about pixels. It would be a real drag to go through all of my code and insert int(1/2) because there's no way to do integer math in python anymore... (Besides, what about 100000000000000000000L/200000000000000000000L, which I believe will shortly be lacking the Ls...?) Maybe language features that are like this could be handled by a pseudo-module? I.E. import syntax syntax.floating_point_division() or somesuch ... I'm not sure how you'd implement this so it would be automatic in certain contexts (merging it into your 'site' module maybe? that has obvious problems though), but considering that such features may be NOT the behavior desired by everyone, it seems strange to move the language in that direction unilaterally. ______ __ __ _____ _ _ | ____ | \_/ |_____] |_____| |_____| |_____ | | | | @ t w i s t e d m a t r i x . c o m http://www.twistedmatrix.com/~glyph/

"GL" == Glyph Lefkowitz <glyph@twistedmatrix.com> writes:
GL> As long as we're talking about versioning issues, could we GL> perhaps introduce a slightly more robust introspective GL> facility than GL> assert(sys.version[:3])=='1.5' sys.hexversion? Python 1.6a2 (#26, Apr 12 2000, 13:53:57) [GCC 2.8.1] on sunos5 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
import sys sys.hexversion 17170593 hex(sys.hexversion) '0x10600a1'

sys.hexversion?
Python 1.6a2 (#26, Apr 12 2000, 13:53:57) [GCC 2.8.1] on sunos5 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
import sys sys.hexversion 17170593 hex(sys.hexversion) '0x10600a1'
bitmasks!? (ouch. python is definitely not what it used to be. wonder if the right answer to this is "wouldn't a tuple be much more python-like?" or "I'm outta here...") </F>

"FL" == Fredrik Lundh <effbot@telia.com> writes:
FL> (ouch. python is definitely not what it used to be. wonder FL> if the right answer to this is "wouldn't a tuple be much more FL> python-like?" or "I'm outta here...") Yeah, pulling the micro version number out of sys.hexversion is ugly and undocumented, hence my subsequent message. The basically idea is pretty cool though, and I've adopted it to Mailman. It allows me to do this: previous_version = last_hex_version() this_version = mm_cfg.HEX_VERSION if previous_version < this_version: # I'm upgrading -Barry

The basically idea is pretty cool though, and I've adopted it to Mailman. It allows me to do this:
previous_version = last_hex_version() this_version = mm_cfg.HEX_VERSION
if previous_version < this_version: # I'm upgrading
Why can't you do that with tuples? --david

"DA" == David Ascher <DavidA@ActiveState.com> writes:
>> The basically idea is pretty cool though, and I've adopted it >> to Mailman. It allows me to do this: previous_version = >> last_hex_version() this_version = mm_cfg.HEX_VERSION if >> previous_version < this_version: # I'm upgrading DA> Why can't you do that with tuples? How do you know they aren't tuples? :) (no, Moshe, you do not need to answer :) -Barry

hex(sys.hexversion) '0x10600a1'
bitmasks!?
Nah - a comparable number :-) if sys.hexversion >= 0x01060100: # Require Python 1.6 or later! Seems perfectly reasonable and understandable to me. And much cleaner than a tuple: if tuple_version[0] > 1 or tuple_version[0] == 1 and tuple_version[6] >= 1: etc Unless Im missing the point - but I can't see any case other than version comparisons in which hexversion is useful - so it seems perfect to me.
(ouch. python is definitely not what it used to be. wonder if the right answer to this is "wouldn't a tuple be much more python-like?" or "I'm outta here...")
Be sure to let us know. Mark.

On Wed, 12 Apr 2000, Barry A. Warsaw wrote:
sys.hexversion?
Thank you! I stand corrected (and embarrassed) but perhaps this could be a bit better documented? a search of Google comes up with only one hit for this on the entire web: http://www.python.org/1.5/NEWS-152b2.txt ...

"GL" == Glyph Lefkowitz <glyph@twistedmatrix.com> writes:
BAW> sys.hexversion? GL> Thank you! GL> I stand corrected (and embarrassed) but perhaps this could be GL> a bit better documented? a search of Google comes up with GL> only one hit for this on the entire web: GL> http://www.python.org/1.5/NEWS-152b2.txt ... Yup, it looks like it's missing from Fred's 1.6 doc tree too. Do python-devers think we also need to make the other patchlevel.h constants available through sys? If so, and because sys.hexversion is currently undocumented, I'd propose making sys.hexversion a tuple of (PY_VERSION_HEX, PY_MAJOR_VERSION, PY_MINOR_VERSION, PY_MICRO_VERSION, PY_RELEASE_LEVEL, PY_RELEASE_SERIAL) or leaving sys.hexversion as is and crafting a new sys variable which is the [1:] of the tuple above. Prolly need to expose PY_RELEASE_LEVEL_{ALPHA,BETA,GAMMA,FINAL} as constants too. -Barry

If so, and because sys.hexversion is currently undocumented, I'd propose making sys.hexversion a tuple of
(PY_VERSION_HEX, PY_MAJOR_VERSION, PY_MINOR_VERSION, PY_MICRO_VERSION, PY_RELEASE_LEVEL, PY_RELEASE_SERIAL)
thanks. I feel better now ;-) but wouldn't something like (1, 6, 0, "a1") be easier to understand and use? </F>

Fredrik Lundh writes:
but wouldn't something like (1, 6, 0, "a1") be easier to understand and use?
Yes! (But you knew that....) -Fred -- Fred L. Drake, Jr. <fdrake at acm.org> Corporation for National Research Initiatives

"FL" == Fredrik Lundh <effbot@telia.com> writes:
FL> but wouldn't something like (1, 6, 0, "a1") be easier FL> to understand and use? I wasn't planning on splitting PY_VERSION, just in exposing the other #define ints in patchlevel.h -Barry

Barry wrote:
"FL" == Fredrik Lundh <effbot@telia.com> writes:
FL> but wouldn't something like (1, 6, 0, "a1") be easier FL> to understand and use?
I wasn't planning on splitting PY_VERSION, just in exposing the other #define ints in patchlevel.h
neither was I. I just want Python to return those values in a form suitable for a Python programmer, not a C preprocessor. in other words: char release[2+1]; sprintf(release, "%c%c", PY_RELEASE_LEVEL - 0x0A + 'a', PY_RELEASE_SERIAL + '0'); sys.longversion = BuildTuple("iiis", PY_MAJOR_VERSION, PY_MINOR_VERSION, PY_MICRO_VERSION, release) (this assumes that the release serial will never exceed 9, but I think that's a reasonable restriction...) </F>

Do python-devers think we also need to make the other patchlevel.h constants available through sys?
Can't see why, but also can't see why not!
If so, and because sys.hexversion is currently undocumented,
Since when has that ever stopped anyone :-)
I'd propose making sys.hexversion a tuple of
(PY_VERSION_HEX, PY_MAJOR_VERSION, PY_MINOR_VERSION, PY_MICRO_VERSION, PY_RELEASE_LEVEL, PY_RELEASE_SERIAL)
or leaving sys.hexversion as is and crafting a new sys variable which is the [1:] of the tuple above.
My code already uses sys.hexversion to differentiate between 1.5 and 1.6, so if we do anything I would vote for a new name. Personally however, I think the hexversion gives all the information you need - ie, you either want a printable version - sys.version - or a machine comparable version - sys.hexversion. Can't really think of a reason you would want the other attributes... Mark.

Mark Hammond quoted Barry Warsaw:
I'd propose making sys.hexversion a tuple of (PY_VERSION_HEX, PY_MAJOR_VERSION, PY_MINOR_VERSION, PY_MICRO_VERSION, PY_RELEASE_LEVEL, PY_RELEASE_SERIAL)
If it's a tuple, the name "hexversion" makes absolutely no sense. Call it version_tuple or something like that. --amk
participants (9)
-
Andrew Kuchling
-
Barry A. Warsaw
-
bwarsaw@cnri.reston.va.us
-
David Ascher
-
Fred L. Drake, Jr.
-
Fredrik Lundh
-
Glyph Lefkowitz
-
Mark Hammond
-
Tim Peters