472,144 Members | 1,892 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,144 software developers and data experts.

Tuple Unpacking in raise

Hello All,

Is this a bug? Why is this tuple getting unpacked by raise? Am I missing some
subtle logic? Why does print not work the same way as raise? Both are
statements. Why does raise need to be so special?

py> sometup = 1,2
py> print sometup
(1, 2)
py> print 1,2,3, sometup
1 2 3 (1, 2)
py> class MyErr(Exception):
.... def __init__(self, atup):
.... Exception.__init__(self, "Error with %s-%s" % atup)
....
py> raise MyErr, sometup
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: __init__() takes exactly 2 arguments (3 given)
py> e = MyErr(sometup)
py> print e
Error with 1-2

James

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
Jul 19 '05 #1
3 1763
James Stroud wrote:
Hello All,

Is this a bug? Why is this tuple getting unpacked by raise? Am I missing some
subtle logic? Why does print not work the same way as raise? Both are
statements. Why does raise need to be so special?

py> sometup = 1,2
py> print sometup
(1, 2)
py> print 1,2,3, sometup
1 2 3 (1, 2)
py> class MyErr(Exception):
... def __init__(self, atup):
... Exception.__init__(self, "Error with %s-%s" % atup)
...
py> raise MyErr, sometup
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: __init__() takes exactly 2 arguments (3 given)
py> e = MyErr(sometup)
py> print e
Error with 1-2


Well, it's not a bug, because that's what the documentation says it'll do:

"The second object is used to determine the exception value: If it is an
instance of the class, the instance becomes the exception value. If the
second object is a tuple, it is used as the argument list for the class
constructor; if it is None, an empty argument list is used, and any
other object is treated as a single argument to the constructor."[1]

In the example above (as well as almost all code), there's no need to
use the two argument version of raise. You can simply write:

raise MyErr(sometup)

If you need the three argument version of raise, I believe you can still
write it as:

raise MyErr(sometup), None, tb

Note that Guido has mentioned a few times that in Python 3.0, he wants
tracebacks to be attributes of the Exception objects so that all raise
statements are like the one argument version.

STeVe

P.S. If you insist on using the two argument version of raise, you can
do it like this:

py> class E(Exception):
.... def __init__(self, atup):
.... Exception.__init__(self, "Error with %s-%s" % atup)
....
py> raise E, ((1, 2),)
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
E: Error with 1-2

But that seems a lot less elegant than simply using the one argument
version.

[1] http://docs.python.org/ref/raise.html
Jul 19 '05 #2
On 6/21/05, Steven Bethard <st************@gmail.com> wrote:
James Stroud wrote:
P.S. If you insist on using the two argument version of raise, you can
do it like this:

py> class E(Exception):
... def __init__(self, atup):
... Exception.__init__(self, "Error with %s-%s" % atup)

But that seems a lot less elegant than simply using the one argument
version.


Another workaround would be to use __init__(self, *atup), but raising
an explicitly constructed exception is preferable (IMO).

- kv
Jul 19 '05 #3
Thank you Steven and Konstantin, that clears things up.

Sometimes I forget how incomplete my Python Essential Reference is.

James

On Monday 20 June 2005 05:40 pm, Steven Bethard wrote:
Well, it's not a bug, because that's what the documentation says it'll do:

"The second object is used to determine the exception value: If it is an
instance of the class, the instance becomes the exception value. If the
second object is a tuple, it is used as the argument list for the class
constructor; if it is None, an empty argument list is used, and any
other object is treated as a single argument to the constructor."[1]

In the example above (as well as almost all code), there's no need to
use the two argument version of raise. You can simply write:

raise MyErr(sometup)

If you need the three argument version of raise, I believe you can still
write it as:

raise MyErr(sometup), None, tb

Note that Guido has mentioned a few times that in Python 3.0, he wants
tracebacks to be attributes of the Exception objects so that all raise
statements are like the one argument version.

STeVe

P.S. If you insist on using the two argument version of raise, you can
do it like this:

py> class E(Exception):
... def __init__(self, atup):
... Exception.__init__(self, "Error with %s-%s" % atup)
...
py> raise E, ((1, 2),)
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
E: Error with 1-2

But that seems a lot less elegant than simply using the one argument
version.

[1] http://docs.python.org/ref/raise.html


--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
Jul 19 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

50 posts views Thread by Will McGugan | last post: by
8 posts views Thread by Paul McGuire | last post: by
12 posts views Thread by Kay Schluehr | last post: by
16 posts views Thread by flyaflya | last post: by
11 posts views Thread by harold | last post: by
43 posts views Thread by Tim Chase | last post: by
21 posts views Thread by Martin Geisler | last post: by
reply views Thread by Saiars | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.