[Tutor] 2.x and 3.x in one code base [was Re: PYTHONHASHSEED, -R]
Albert-Jan Roskam
fomcl at yahoo.com
Mon Jul 29 23:08:08 CEST 2013
----- Original Message -----
> From: Steven D'Aprano <steve at pearwood.info>
> To: tutor at python.org
> Cc:
> Sent: Monday, July 29, 2013 7:51 PM
> Subject: [Tutor] 2.x and 3.x in one code base [was Re: PYTHONHASHSEED, -R]
>
> On 29/07/13 19:29, Albert-Jan Roskam wrote:
>> The following question is almost new-thread-worthy, but: if I would like to
> make my app work for 2.x and 3.x, what is the best approach:
>> (a) use "if sys.version_info.major...." throughout the code
>> (b) use 2to3, hope for the best and fix manually whatever can't be
> fixed
>
> It depends on many factors. How many things that you need have changed? Do you
> need new features that exist in Python 3 but not 2? But generally I prefer a
> single code base.
Hi Steven, That seems most attractive to me too. I wouldn't really know how much stuff I'd need to change. This article made me shudder a little though: http://python3porting.com/problems.html. Worst-case-scenario would be that I'd gradually make fixes throughout the code only to find out the things have become one big convoluted messy bunch of spaghetti. Unicode and (for me) doctest seem two painspots.
> In most of my code, making it run in both is relatively simple. I usually
> support everything from 2.4 through 3.3 (and believe me, I can't wait to
> drop support for 2.4 -- on the other hand, I'm really grateful I don't
> need to support 2.3!), so I basically write code that mostly relies on 2.4
> features. Then I add any extra, or changed, features in, at the top of the
> module.
All the way back to Python 2.4? It seems frustrating not to be able not to use all the nice goodies added in later versions.
2.x vs 3.x is a different story, but why not stay up-to-date? (this is just my personal annoyance with our software in the office which is always emm, not quite up to date).
> I prefer to use the feature if Python already has it, and only fall back on my
> own back-ported version if I have to, e.g.:
>
>
<snip>
>
> Notice that I always test for the feature, not for the version number. This is
> defensive programming -- maybe some day my code will be running on an
> almost-but-not-quite compatible version of Python, and version checks will give
> the wrong idea. E.g. "AmazingPython 1.1" might have the same
> functionality of Python 3.3, but I'd never know it if I just check the
> version number.
Good point:
Python 2.7.2 (1.9+dfsg-1, Jun 19 2012, 23:23:45)
[PyPy 1.9.0 with GCC 4.7.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
And now for something completely different: ``why did you guys have to make the
builtin fortune more interesting than actual work? i just catched myself
restarting pypy 20 times''
>>>> import sys
>>>> sys.version
'2.7.2 (1.9+dfsg-1, Jun 19 2012, 23:23:45)\n[PyPy 1.9.0 with GCC 4.7.0]'
There are probably situations where Python 2.x and pypy are not quite the same. So just using "if sys.version == '2' " is indeed not a good idea. E.g., yesterday I used pypy to run tests (using nosetests) and one test failed. Sliiight difference in ordering and layout of the actual result.
> About the most complex such test I have is this one, to pre-define a couple of
> named constants for special numeric values:
>
>
>
> # Include special values. Prior to Python 2.6, this was messy, platform-
> # dependent, and not guaranteed to work.
> try:
> INF = float('inf')
> NAN = float('nan')
> except ValueError:
> # Possibly Windows prior to Python 2.6.
> try:
> INF = float('1.#INF')
> NAN = float('1.#IND') # Indeterminate.
> except ValueError:
> # Desperate times require desperate measures...
> try:
> INF = 1e3000 # Hopefully, this should overflow to INF.
> NAN = INF-INF # And this hopefully will give a NaN.
> except (ValueError, OverflowError):
> # Just give up.
> print('*** warning: unable to define INF and/or NAN floats
> ***')
>
>
> Very occasionally, I end up with *three* modules for some piece of functionality
> that uses completely different syntax, or is otherwise too hard to write as a
> single cross-version implementation. A trivial example:
>
>
> # === printer2.py module ===
> import sys
> def do_print(obj, file=sys.stdout):
> print >>>file, obj
>
>
> # === printer3.py module ===
> def do_print(obj, file=sys.stdout):
> print(obj, file=file)
>
>
> # === printer.py module ===
> try:
> from printer2 import do_print
> except SyntaxError:
> from printer3 import do_print
>
>
>
> Then in the rest of my project, I just:
>
> import printer
>
> printer.do_print("something")
>
>
>
> --
> Steven
> _______________________________________________
> Tutor maillist - Tutor at python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>
More information about the Tutor
mailing list