Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

exception cannot be new-style class #36116

Closed
magnusheino mannequin opened this issue Feb 17, 2002 · 16 comments
Closed

exception cannot be new-style class #36116

magnusheino mannequin opened this issue Feb 17, 2002 · 16 comments
Assignees
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs)

Comments

@magnusheino
Copy link
Mannequin

magnusheino mannequin commented Feb 17, 2002

BPO 518846
Nosy @gvanrossum, @loewis, @doerwalter, @brettcannon, @facundobatista, @pjeby
Files
  • raise-patch
  • diff.txt: Another patch enabling new style exceptions
  • test.py
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/gvanrossum'
    closed_at = <Date 2006-03-01.04:34:49.000>
    created_at = <Date 2002-02-17.20:09:57.000>
    labels = ['interpreter-core']
    title = 'exception cannot be new-style class'
    updated_at = <Date 2006-03-01.04:34:49.000>
    user = 'https://bugs.python.org/magnusheino'

    bugs.python.org fields:

    activity = <Date 2006-03-01.04:34:49.000>
    actor = 'brett.cannon'
    assignee = 'gvanrossum'
    closed = True
    closed_date = None
    closer = None
    components = ['Interpreter Core']
    creation = <Date 2002-02-17.20:09:57.000>
    creator = 'magnusheino'
    dependencies = []
    files = ['336', '337', '338']
    hgrepos = []
    issue_num = 518846
    keywords = []
    message_count = 16.0
    messages = ['9293', '9294', '9295', '9296', '9297', '9298', '9299', '9300', '9301', '9302', '9303', '9304', '9305', '9306', '9307', '9308']
    nosy_count = 9.0
    nosy_names = ['gvanrossum', 'loewis', 'jhylton', 'doerwalter', 'brett.cannon', 'facundobatista', 'magnusheino', 'pje', 'robey1']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = None
    status = 'closed'
    superseder = None
    type = None
    url = 'https://bugs.python.org/issue518846'
    versions = ['Python 2.5']

    @magnusheino
    Copy link
    Mannequin Author

    magnusheino mannequin commented Feb 17, 2002

    [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
    >>>

    @magnusheino magnusheino mannequin closed this as completed Feb 17, 2002
    @magnusheino magnusheino mannequin assigned gvanrossum Feb 17, 2002
    @magnusheino magnusheino mannequin added the interpreter-core (Objects, Python, Grammar, and Parser dirs) label Feb 17, 2002
    @magnusheino magnusheino mannequin closed this as completed Feb 17, 2002
    @magnusheino magnusheino mannequin assigned gvanrossum Feb 17, 2002
    @magnusheino magnusheino mannequin added the interpreter-core (Objects, Python, Grammar, and Parser dirs) label Feb 17, 2002
    @loewis
    Copy link
    Mannequin

    loewis mannequin commented Feb 17, 2002

    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.

    @jhylton
    Copy link
    Mannequin

    jhylton mannequin commented Apr 5, 2002

    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.

    @loewis
    Copy link
    Mannequin

    loewis mannequin commented Apr 5, 2002

    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.

    @jhylton
    Copy link
    Mannequin

    jhylton mannequin commented Apr 5, 2002

    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.

    @gvanrossum
    Copy link
    Member

    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!)

    @doerwalter
    Copy link
    Contributor

    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.

    @doerwalter
    Copy link
    Contributor

    Logged In: YES
    user_id=89016

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

    @pjeby
    Copy link
    Mannequin

    pjeby mannequin commented Jul 11, 2002

    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?

    @facundobatista
    Copy link
    Member

    Logged In: YES
    user_id=752496

    Reproduced the bug in Py2.3. I think that this is a bug, at
    least because we "encourage" users to derive exceptions from
    Exception, so they should be able to not do it.

    The moment we say that they "must" derive from Exception,
    this can be closed (of course, this is my *very* personal
    opinion, ;)

    @robey1
    Copy link
    Mannequin

    robey1 mannequin commented Dec 15, 2004

    Logged In: YES
    user_id=1179122

    This caused me an hour of debugging a few nights ago. When
    using unified types, it's very confusing to find that not
    only does Exception not follow new-style object semantics,
    but it *can't*. Doing the obvious hack:

    class MyException (Exception, object):
        pass

    does not work! The interpreter (2.3) refuses to let you
    raise a unified-type object. And if you subclass
    exclusively from Exception, type(obj) returns 'instance'
    instead of the class (due to being an old-style object).

    Please fix this for 2.4!

    @loewis
    Copy link
    Mannequin

    loewis mannequin commented Dec 15, 2004

    Logged In: YES
    user_id=21627

    Whatever the solution to this problem, it is for sure that
    2.4.x won't see it, because it will be a new feature.

    @robey1
    Copy link
    Mannequin

    robey1 mannequin commented Dec 15, 2004

    Logged In: YES
    user_id=1179122

    Let me try to rephrase the problem so that it's obvious that
    this is a bug, and not a feature:

    'type(e)' on an exception will not work in 2.3, and cannot
    be made to work from within python code. There's no way to
    throw an exception (ie an object with Exception in its
    ancestor list) that 'type(e)' will work on. :(

    @loewis
    Copy link
    Mannequin

    loewis mannequin commented Dec 16, 2004

    Logged In: YES
    user_id=21627

    This statement, as literally made, is incorrect:

    >>> class X(Exception):
    ...   pass
    ...
    >>> e=X()
    >>> type(e)
    <type 'instance'>
    >>> raise e
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    __main__.X: <__main__.X instance at 0x401f2b4c>

    In this example, type(e) works, and x is an object which has
    Exception among its base classes. Still, I can throw x,
    despite your claim that I cannot.

    Even if I interpret your statement more literally (i.e. that
    you are talking about objects for which type(e) is a
    new-style class): Why do you think this statement explains
    there is a bug?

    As for why it is a new feature: it currently doesn't work,
    and anybody trying it will quickly find out that it doesn't
    work. The language reference says it doesn't work. The
    TypeError you get says it doesn't work. So that it doesn't
    work is clearly intentional; changing it will be a new feature.

    Notice that it is very difficult to implement this feature,
    as something needs to happen with strings and subtypes of
    str. Currently, string exceptions are caught by identity. If
    arbitrary objects can be used as exceptions, then strings
    should also be caught by type, not by identity; this is a
    backwards-incompatible change.

    A clean solution would be to deprecate string exceptions in
    2.5, completely ban them in 2.6, and allow arbitrary objects
    to act as exceptions in 2.7.

    Please do read the entire thread of this RFE.

    @robey1
    Copy link
    Mannequin

    robey1 mannequin commented Dec 17, 2004

    Logged In: YES
    user_id=1179122

    (I wish we could do this in email instead of cluttering up
    an already-messy bug...)

    Forget about throwing non-Exception-based objects: it's a
    red herring. The bug to focus on is the title: "exception
    cannot be new-style class".

    Bottom line: This subclass of Exception can not be raised
    in python 2.3:

    class MyException (Exception, object): pass

    pje's comment below from (2002-07-11 13:12) is a nice
    summary of how to solve it.

    @brettcannon
    Copy link
    Member

    Logged In: YES
    user_id=357491

    rev. 42711 (PEP-352 implementation) made built-in exceptions
    new-style.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 9, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    interpreter-core (Objects, Python, Grammar, and Parser dirs)
    Projects
    None yet
    Development

    No branches or pull requests

    4 participants