29

I want to keep & use the error value of an exception in both Python 2.5, 2.7 and 3.2.

In Python 2.5 and 2.7 (but not 3.x), this works:

try:
    print(10 * (1/0))
except ZeroDivisionError,  error:       # old skool
    print("Yep, error caught:", error)

In Python 2.7 and 3.2 (but not in 2.5), this works:

try:
    print(10 * (1/0))
except (ZeroDivisionError) as error:    # 'as' is needed by Python 3
    print("Yep, error caught:", error)

Is there any code for this purpose that works in both 2.5, 2.7 and 3.2?

Thanks

Lion
  • 18,105
  • 22
  • 78
  • 106
superkoning
  • 884
  • 2
  • 8
  • 11
  • Can you not upgrade your 2.5 code to at least 2.7 and preferably 3? – Ben Jul 01 '12 at 20:35
  • `except (ZeroDivisionError) as error: ` works fine in python 2.7 http://ideone.com/KfHBs – Ashwini Chaudhary Jul 01 '12 at 20:35
  • 2
    Python 3 is expressly not backwards compatible. Why restrict yourself to a limited subset of syntax that both languages support? – Cameron Jul 01 '12 at 20:40
  • @Ben (and Cameron) The code is used on appliances (often with Python 2.5) and on Linux installation (with Python 3.x on the horizon). Therefore both 2.5 and 3.x should work .... *If* I must choose, it will be 2.x code; that will work on on all installations: appliances *and* Linux installations. – superkoning Jul 01 '12 at 20:48
  • 2
    @AshwiniChaudhary Indeed. That's what I already said in my post. Python 2.7 looks like a fine hybrid: accepting both 2.x and 3.x style python code. It's about 2.5 versus 3.x ... – superkoning Jul 01 '12 at 20:49
  • It is impossible at large. Python 3 is not backwards compatible with respect to lots of various operation. If you cannot upgrade appliances, you should have python 2.5 running on Linux. If you use Linux installation for testing, it really *should* run the same python line as the appliance. – Piotr Kalinowski Jul 01 '12 at 20:51

1 Answers1

39

You can use one code base on Pythons 2.5 through 3.2, but it isn't easy. You can take a look at coverage.py, which runs on 2.3 through 3.3 with a single code base.

The way to catch an exception and get a reference to the exception that works in all of them is this:

except ValueError:
    _, err, _ = sys.exc_info()
    #.. use err...

This is equivalent to:

except ValueError as err:
    #.. use err...
Ned Batchelder
  • 345,440
  • 70
  • 544
  • 649
  • 1
    Granted it works, but maybe the cure is worse (uglier) than the problem. Another way would be using "as" and a code conversion script when packaging code for 2.5. YMMV. – Jürgen Strobel Sep 13 '12 at 10:04
  • The problem is that python does significant and unnecesary changes to its syntax between versions. Imagine this in C: from version x.y you use "@" instead of "{" :) This is plain stupid and the cure is much better - after all we all want it to just work! – Terminus Sep 11 '14 at 12:34
  • 1
    @Terminus Think of changes from Python 2 to Python 3 as analogous to the [change in syntax of function declarations](http://stackoverflow.com/a/22516/2738262) from first edition K&R C to ANSI C. C89/C90 accepts both syntaxes, as Python 2.7 does. – Damian Yerrick Jan 11 '15 at 15:34
  • 1
    The difference is that no one uses K&R now and no one used it shortly after introduction of ANSI. Python 3 was introduced years and years ago and people still use 2.7. So, the solution presented here is excellent - it supports all commonly used versions. And if it's ugly? That's not my problem, i want it to WORK. – Terminus Feb 26 '15 at 11:44
  • Is there any reason to prefer `_, err, _` over just `err = sys.exc_info()[1]` ? – Peter Gibson Jan 05 '17 at 03:51
  • No, just preference. – Ned Batchelder Jan 05 '17 at 12:07
  • Unfortunately for the purposes of this answer, the coverage.py link has since been updated to python2.6 and later syntax. This is a link to an older commit: https://bitbucket.org/ned/coveragepy/src/d6065d90c0a0a6100e30f7573d83b792d245fede/coverage/execfile.py?at=default&fileviewer=file-view-default – Robert Boehne Dec 12 '17 at 16:54