[Python-bugs-list] [ python-Bugs-518846 ] exception cannot be new-style class

noreply@sourceforge.net noreply@sourceforge.net
Thu, 11 Jul 2002 13:12:12 -0700


Bugs item #518846, was opened at 2002-02-17 20:09
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=518846&group_id=5470

Category: Type/class unification
Group: Python 2.2
Status: Open
Resolution: None
Priority: 5
Submitted By: Magnus Heino (magnusheino)
Assigned to: Martin v. Löwis (loewis)
Summary: exception cannot be new-style class

Initial Comment:
[magnus@gills magnus]$ python2.2
Python 2.2 (#1, Jan 26 2002, 14:27:24)
[GCC 2.96 20000731 (Red Hat Linux 7.1 2.96-98)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class foo(object):
...     pass
...
>>> raise foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: exceptions must be strings, classes, or instances, not foo
>>>


----------------------------------------------------------------------

Comment By: Phillip J. Eby (pje)
Date: 2002-07-11 20:12

Message:
Logged In: YES 
user_id=56214

Just to make things even more interesting, the current
'raise' code *will* let you raise a new-style instance that
derives from 'tuple'...  of course, what it actually raises
is the first element of said tuple-like thing.

It seems to me that the very first thing that should be
checked is whether the first argument to 'raise' is an
instance of Exception, and if so, take its type and go from
there.  This would support both old and new-style instances
of Exception subclasses, and I believe is the recommended
approach to using 'raise'.  (I.e., raise an instance of
something that subclasses Exception.)  All the other items
like strings, tuples, etc., should be checked *after* a
check for the "standard" approach, yes?


----------------------------------------------------------------------

Comment By: Walter Dörwald (doerwalter)
Date: 2002-07-11 17:07

Message:
Logged In: YES 
user_id=89016

test.py is a little script that executes various test cases.

----------------------------------------------------------------------

Comment By: Walter Dörwald (doerwalter)
Date: 2002-07-11 16:12

Message:
Logged In: YES 
user_id=89016

What about the following patch (diff.txt):

It allows new style objects as exceptions and makes catching
exceptions by basetype possible:
    class newint(int):
        pass
    try:
        raise newint(42)
    except int, exc:
        print exc

With this patch subinstances of str become raisable and will
be caught be type not identity. This could be changed to
explicitely forbid str subinstances.

And
  raise type(None), None
becomes ambiguous: It is interpreted as
  raise type(None)
i.e. it raises the type(None) object as an exception, not
the object None (which is of type type(None))

As soon as Exception is a new style class we could limit the
allowed objects to (sub)instances of Exception.

----------------------------------------------------------------------

Comment By: Guido van Rossum (gvanrossum)
Date: 2002-04-06 00:07

Message:
Logged In: YES 
user_id=6380

Sorry, HEAPTYPE is not the proper way to check for a
new-style class; it would exclude any new-style classes
defined by C code.  I also think that if you want to do this
it should done properly, and allow "raise C, C()" as well.

At best there's agreement that it's not worth trying to fix
Python to allow new-style classes as exceptions when we're
also trying to encourage that exceptions derive from
Exception.

If your module declares its exceptions as deriving from
Exception, a __metaclass__ = type should not have any effect
on the exceptions you declare.  So I'm not sure what your
problem is?

Here's another idea for a patch: a new-style class is
allowed as long as it also inherits from Exception.  (This
is possible!)

----------------------------------------------------------------------

Comment By: Jeremy Hylton (jhylton)
Date: 2002-04-05 23:49

Message:
Logged In: YES 
user_id=31392

I don't realize there was agreement on this.  (I didn't 
follow the discussion closely.)  I don't understand why 
exceptions need to pass an isinstance() test on Exception.  
It didn't used to be this way, and it makes it hard to 
convert a module using __metaclass__ = type.


----------------------------------------------------------------------

Comment By: Martin v. Löwis (loewis)
Date: 2002-04-05 23:44

Message:
Logged In: YES 
user_id=21627

I thought the agreement was that this is not a bug: You
cannot really expect exceptions to work unless you inherit
from Exception.

----------------------------------------------------------------------

Comment By: Jeremy Hylton (jhylton)
Date: 2002-04-05 23:38

Message:
Logged In: YES 
user_id=31392

Martin, I think the attached patch is sufficient.  It checks
object type's for Py_TPFLAGS_HEAPTYPE.  I believe this is
the current way to spell "new-style class" although the
spelling is odd if that's the meaning <0.2 wink>.

If this patch makes sense to you, I'll flesh it out with
some test cases and check it in.


----------------------------------------------------------------------

Comment By: Martin v. Löwis (loewis)
Date: 2002-02-17 23:44

Message:
Logged In: YES 
user_id=21627

Interesting. I think we need to deprecate, then remove
string exception before allowing arbitrary objects as
exceptions. Or we could allow strings to be caught either by
__builtin__.str, or by an identical string.

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=518846&group_id=5470