[newbie] Confused with raise w/o args

Discussion in 'Python' started by Fredrik Lundh, Feb 14, 2005.

  1. "jfj" <> wrote:

    > Wait! second that. We would like to


    hmm. are you seconding yourself, and refering to you and yourself as we?

    > here is another confusing case:
    >
    > ###################
    > import sys
    >
    > class A:
    > pass
    >
    > class B:
    > pass
    >
    > def foo ():
    > try:
    > raise B
    > except:
    > pass
    > raise
    >
    > def b1():
    > try:
    > raise A
    > except:
    > foo()
    >
    > try:
    > b1 ()
    > except:
    > print sys.exc_info()[0]
    > ##################
    >
    > This reports that __main__.B is raised but wouldn't it be better
    > to raise an 'A' since this is the currently handled exception?


    no. your foo() function raises B, and is called from the exception
    handler in b1. exception handlers are free to raise new exceptions
    at any time.

    maybe you should take a deep breath, and try to figure out exactly
    what's confusing to you before posting more examples.

    (btw, using traceback.print_exc() instead of print sys.exc_info may
    give you more clues about what's really going on.)

    </F>
     
    Fredrik Lundh, Feb 14, 2005
    #1
    1. Advertising

  2. Fredrik Lundh

    jfj Guest

    Hello.

    I am a bit confused with 'raise' without any arguments.
    Suppose the testcase below (i hope it's correct!):

    ##################################
    import sys

    class A:
    pass

    class B:
    pass

    def foo():
    try:
    raise B
    except:
    pass

    def b1 ():
    try:
    raise A
    except:
    foo ()
    raise # raises A

    def b2 ():
    try:
    raise A
    except:
    try:
    raise B
    except:
    pass
    raise # raises B

    def b3 ():
    foo ()
    raise # raises B

    def b4 ():
    try:
    raise A
    except:
    pass
    foo ()
    raise # raises A

    #
    try:
    b1 ()
    except:
    print sys.exc_info()

    try:
    b2 ()
    except:
    print sys.exc_info()

    try:
    b3 ()
    except:
    print sys.exc_info()

    try:
    b4 ()
    except:
    print sys.exc_info()
    ################################

    The semantics of raise without arguments are that the exceptions
    of the current scope have a higer priority. That can be seen
    in functions b1() and b2(), where although an exception of type
    'B' was the last handled by python, b1() raises 'A'.

    Although, b3() shows that the exceptions from other scopes *are*
    available.

    The b4() case demonstrates the confusion better.

    IMHO, a more clean operation of raise would be either:
    1) raise w/o args allowed *only* inside an except clause to
    re-raise the exception being handled by the clause.
    2) always re-raise the last exception no matter the scope.

    It appears to me that this behaviour is a bit weird and I would
    like to ask: Are the semantics of 'raise w/o args' a result of
    python's implementation? If python was re-designed, would that
    be different? In python 3000, would you consider changing this
    and if yes, to what semantics? May this be changed in 2.5?


    Thanks

    jfj
    -----------------
    # don't hold back
     
    jfj, Feb 14, 2005
    #2
    1. Advertising

  3. Fredrik Lundh

    jfj Guest

    jfj wrote:
    > IMHO, a more clean operation of raise would be either:
    > 1) raise w/o args allowed *only* inside an except clause to
    > re-raise the exception being handled by the clause.


    Wait! second that. We would like to

    ###############
    def bar():
    raise

    def b5():
    try:
    raise A
    except:
    bar ()
    #################

    So, restricting raise into except clauses only, is not good.
    Change the proposal to:
    > 1) raise w/o args re-raises the exception being handled
    > or UnhandledException.


    here is another confusing case:

    ###################
    import sys

    class A:
    pass

    class B:
    pass

    def foo ():
    try:
    raise B
    except:
    pass
    raise


    def b1():
    try:
    raise A
    except:
    foo()

    try:
    b1 ()
    except:
    print sys.exc_info()[0]
    ##################

    This reports that __main__.B is raised but wouldn't it be better
    to raise an 'A' since this is the currently handled exception?

    jf
     
    jfj, Feb 14, 2005
    #3
  4. Fredrik Lundh

    jfj Guest

    Fredrik Lundh wrote:

    > "jfj" <> wrote:
    >
    >
    >>Wait! second that. We would like to

    >
    >
    > hmm. are you seconding yourself, and refering to you and yourself as we?
    >


    :)
    "we" refers to all python users.

    > no. your foo() function raises B, and is called from the exception
    > handler in b1. exception handlers are free to raise new exceptions
    > at any time.


    Yes but 'B' has been handled while the handler of 'A' has not finished yet.
    Here is a better example:
    ##################
    # comment out one of the two
    # raise statements to test this
    import traceback
    def foo():
    raise # this raises an 'A'
    try:
    raise B
    except:
    pass
    raise # this raises a 'B'. I find this peculiar

    try:
    try:
    raise A
    except:
    foo()
    except:
    traceback.print_exc()
    ##################


    It seems that there are no uses of this "feature".
    I guess that's the easy way to implement re-raise in CPython.

    I quickly grepped through the sources (;)) and it seems that
    perhaps it would be possible to introduce a new opcode
    JUMP_FORWARD_CLEANUP_EXC which would be used to leave except clauses.
    Then, RAISE_VARARGS would push exceptions on to an "exception stack"
    and JUMP_FORWARD_CLEANUP_EXC would pop them.
    The bottom element in such an exception stack would be the
    UnhandledException. 're-raise' would use the stack-top exception.

    However, there are no bytecode changes until AST is merged, so this
    will have to wait..


    jfj
     
    jfj, Feb 15, 2005
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ken Varn
    Replies:
    2
    Views:
    635
    Ken Varn
    Jun 22, 2005
  2. Jacol

    raise or not to raise [Newbie]

    Jacol, Feb 3, 2007, in forum: Python
    Replies:
    5
    Views:
    409
    Gabriel Genellina
    Feb 5, 2007
  3. ernest
    Replies:
    2
    Views:
    294
    Roy Smith
    Nov 14, 2010
  4. Jack Bates
    Replies:
    0
    Views:
    281
    Jack Bates
    May 2, 2011
  5. bvdp

    Raise X or Raise X()?

    bvdp, Mar 11, 2012, in forum: Python
    Replies:
    10
    Views:
    371
    Stefan Behnel
    Mar 12, 2012
Loading...

Share This Page