473,406 Members | 2,281 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

Detecting an active exception

Hello everybody - my first post! And it may be the most monumentally
stupid question ever asked, but I just can't see an answer after several
hours experimenting, searching and reading.

It's simply this - how can a function determine whether or not it's
being called in handling of an exception (ie. there is an "active"
exception, and somewhere upstream on the stack there is an except: block
statement)?

Depending on what you read, sys.exc_info() is supposed to return
(None,None,None) when there is no active exception, but it seems that it
returns info about the last exception when there isn't one currently
active.

For example:

try:
a = a + 1
except:
pass

print sys.exc_info()

produces:
<class exceptions.NameError at 0x009648D0>, <exceptions.NameError
instance at 0x00B5E508>, <traceback object at 0x00B5E4E0>

Where the traceback object identifies the offending a=a+1 line (of course).

Is there another way of doing this? Note that I can't rely on using
sys.exc_clear() in any solution, unfortunately.

cheers

- John

Jun 1 '07 #1
5 1899
"NeBlackCat (lists)" <li***@asd-group.comwrote:
Depending on what you read, sys.exc_info() is supposed to return
(None,None,None) when there is no active exception, but it seems that
it returns info about the last exception when there isn't one
currently active.

For example:

try:
a = a + 1
except:
pass

print sys.exc_info()

produces:
<class exceptions.NameError at 0x009648D0>, <exceptions.NameError
instance at 0x00B5E508>, <traceback object at 0x00B5E4E0>

Where the traceback object identifies the offending a=a+1 line (of
course).

Is there another way of doing this? Note that I can't rely on using
sys.exc_clear() in any solution, unfortunately.
I think you have misunderstood the definition of when an exception is
'currently active'. When an exception is caught, it remains currently
active so long as you are in the same function, or in a function which it
calls (i.e. so long as the current scope is still active). When you return
from that function the exception is no longer active and the previous
exception becomes active (or None if there has not been one or you have
used sys.exc_clear()).

Try this:
--------- t.py -------------
import sys

def f():
try:
a = a + 1
except:
pass

g()
print "f", sys.exc_info()

def g():
print "g", sys.exc_info()

def h():
f()
print "h", sys.exc_info()

h()
----------------------------
The output is:

g (<type 'exceptions.UnboundLocalError'>, UnboundLocalError("local variable
'a' referenced before assignment",), <traceback object at 0x00A8B300>)
f (<type 'exceptions.UnboundLocalError'>, UnboundLocalError("local variable
'a' referenced before assignment",), <traceback object at 0x00A8B300>)
h (None, None, None)

As you can see the exception remains 'currently active' only until the
function in which it was caught returns.
Jun 1 '07 #2
Thanks Duncan - that does clear things up for me on how sys.exc_info()
it actually works!

But it does seem that there is no way to test "am I currently running in
the scope of handling of an exception", which is what I need. If there
was, I could then rely on sys.exc_info() to examine the exception. I'm
implementing something which has to do one thing if called during
exception handling, and another otherwise (and there's no way to
explicitly pass a flag to indicate the situation).

I'm surprised by there apparently not being such a test, I wonder if I
should do a PEP to ask for this feature.

If anyone does know a way to do it in the current implementation, even
by stack examining, I'd love to hear it! :-)

Cheers
- John

Duncan Booth wrote:
"NeBlackCat (lists)" <li***@asd-group.comwrote:

>Depending on what you read, sys.exc_info() is supposed to return
(None,None,None) when there is no active exception, but it seems that
it returns info about the last exception when there isn't one
currently active.

For example:

try:
a = a + 1
except:
pass

print sys.exc_info()

produces:
<class exceptions.NameError at 0x009648D0>, <exceptions.NameError
instance at 0x00B5E508>, <traceback object at 0x00B5E4E0>

Where the traceback object identifies the offending a=a+1 line (of
course).

Is there another way of doing this? Note that I can't rely on using
sys.exc_clear() in any solution, unfortunately.

I think you have misunderstood the definition of when an exception is
'currently active'. When an exception is caught, it remains currently
active so long as you are in the same function, or in a function which it
calls (i.e. so long as the current scope is still active). When you return
from that function the exception is no longer active and the previous
exception becomes active (or None if there has not been one or you have
used sys.exc_clear()).

Try this:
--------- t.py -------------
import sys

def f():
try:
a = a + 1
except:
pass

g()
print "f", sys.exc_info()

def g():
print "g", sys.exc_info()

def h():
f()
print "h", sys.exc_info()

h()
----------------------------
The output is:

g (<type 'exceptions.UnboundLocalError'>, UnboundLocalError("local variable
'a' referenced before assignment",), <traceback object at 0x00A8B300>)
f (<type 'exceptions.UnboundLocalError'>, UnboundLocalError("local variable
'a' referenced before assignment",), <traceback object at 0x00A8B300>)
h (None, None, None)

As you can see the exception remains 'currently active' only until the
function in which it was caught returns.
Jun 2 '07 #3
I've now also looked at this from a traceback and stack frame walking
perspective as well and it seems impossible, ie. it see,s impossible to
create a function AmIHandlingAnException() which would behave as follows:

try:
a=a+1
except:
pass

try:
AmIHandlingAnException() # returns FALSE
b = b + 1
except:
AmIHandlingAnException() # returns TRUE
try:
AmIHandlingAnException() # returns TRUE
except:
pass

AmIHandlingAnException() # returns FALSE

The only way I can see to do it is to use something like the 'inspect'
module to walk up the stack and, for each frame, walk lines of code
backwards to determine whether or not you're in an except: block. Of
course that would be horribly inefficient.

I'm rather stunned by this (this was the 'easy' bit that I left to
last!). I can't see a solution unless a) a traceback object is provided
for the exception handling path as well as (per sys.exc_info()) the
exception creating path, or b) exception handlers are internally treated
as new frames (ie. internally, entering an except: clause creates a
pseudo-function call to the first handling line).

- John

Duncan Booth wrote:
"NeBlackCat (lists)" <li***@asd-group.comwrote:

>Depending on what you read, sys.exc_info() is supposed to return
(None,None,None) when there is no active exception, but it seems that
it returns info about the last exception when there isn't one
currently active.

For example:

try:
a = a + 1
except:
pass

print sys.exc_info()

produces:
<class exceptions.NameError at 0x009648D0>, <exceptions.NameError
instance at 0x00B5E508>, <traceback object at 0x00B5E4E0>

Where the traceback object identifies the offending a=a+1 line (of
course).

Is there another way of doing this? Note that I can't rely on using
sys.exc_clear() in any solution, unfortunately.

I think you have misunderstood the definition of when an exception is
'currently active'. When an exception is caught, it remains currently
active so long as you are in the same function, or in a function which it
calls (i.e. so long as the current scope is still active). When you return
from that function the exception is no longer active and the previous
exception becomes active (or None if there has not been one or you have
used sys.exc_clear()).

Try this:
--------- t.py -------------
import sys

def f():
try:
a = a + 1
except:
pass

g()
print "f", sys.exc_info()

def g():
print "g", sys.exc_info()

def h():
f()
print "h", sys.exc_info()

h()
----------------------------
The output is:

g (<type 'exceptions.UnboundLocalError'>, UnboundLocalError("local variable
'a' referenced before assignment",), <traceback object at 0x00A8B300>)
f (<type 'exceptions.UnboundLocalError'>, UnboundLocalError("local variable
'a' referenced before assignment",), <traceback object at 0x00A8B300>)
h (None, None, None)

As you can see the exception remains 'currently active' only until the
function in which it was caught returns.
Jun 2 '07 #4
Duncan Booth wrote:
"NeBlackCat (lists)" <li***@asd-group.comwrote:
>Depending on what you read, sys.exc_info() is supposed to return
(None,None,None) when there is no active exception, but it seems that
it returns info about the last exception when there isn't one
currently active.

For example:

try:
a = a + 1
except:
pass

print sys.exc_info()

produces:
<class exceptions.NameError at 0x009648D0>, <exceptions.NameError
instance at 0x00B5E508>, <traceback object at 0x00B5E4E0>

Where the traceback object identifies the offending a=a+1 line (of
course).

Is there another way of doing this? Note that I can't rely on using
sys.exc_clear() in any solution, unfortunately.

I think you have misunderstood the definition of when an exception is
'currently active'. When an exception is caught, it remains currently
active so long as you are in the same function, or in a function which it
calls (i.e. so long as the current scope is still active). When you return
from that function the exception is no longer active and the previous
exception becomes active (or None if there has not been one or you have
used sys.exc_clear()).

Try this:
--------- t.py -------------
import sys

def f():
try:
a = a + 1
except:
pass

g()
print "f", sys.exc_info()

def g():
print "g", sys.exc_info()

def h():
f()
print "h", sys.exc_info()

h()
----------------------------
The output is:

g (<type 'exceptions.UnboundLocalError'>, UnboundLocalError("local variable
'a' referenced before assignment",), <traceback object at 0x00A8B300>)
f (<type 'exceptions.UnboundLocalError'>, UnboundLocalError("local variable
'a' referenced before assignment",), <traceback object at 0x00A8B300>)
h (None, None, None)

As you can see the exception remains 'currently active' only until the
function in which it was caught returns.
Duncan, that's a great description that should go in the docs (I suspect
you aren't just quoting from them here). Kristján V. Jónsson has also
raised some great points about this issue in a multi-threaded
multi-processing application architecture both simplified and
complicated by the presence of Stackless, though I can't lay my hands on
any summary of his findings right now.

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
------------------ Asciimercial ---------------------
Get on the web: Blog, lens and tag your way to fame!!
holdenweb.blogspot.com squidoo.com/pythonology
tagged items: del.icio.us/steve.holden/python
All these services currently offer free registration!
-------------- Thank You for Reading ----------------

Jun 2 '07 #5
NeBlackCat <li***@asd-group.comwrote:
I've now also looked at this from a traceback and stack frame walking
perspective as well and it seems impossible, ie. it see,s impossible to
create a function AmIHandlingAnException() which would behave as follows:

try:
a=a+1
except:
pass

try:
AmIHandlingAnException() # returns FALSE
b = b + 1
except:
AmIHandlingAnException() # returns TRUE
try:
AmIHandlingAnException() # returns TRUE
except:
pass

AmIHandlingAnException() # returns FALSE

The only way I can see to do it is to use something like the 'inspect'
module to walk up the stack and, for each frame, walk lines of code
backwards to determine whether or not you're in an except: block. Of
course that would be horribly inefficient.

I'm rather stunned by this (this was the 'easy' bit that I left to
last!).
Why don't you tell us what you are actually trying to achieve and we
can see if we can come up with a more pythonic solution? The fact
that you are running into limits of the language like this as a new
python programmer probably means you aren't thinking in python yet.

--
Nick Craig-Wood <ni**@craig-wood.com-- http://www.craig-wood.com/nick
Jun 3 '07 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: David C. Barber | last post by:
I'm having a problem knowing what is the current active window using VB6. Yes I can use the ActiveWindow property to determine what is my VB active window, HOWEVER, if the active window is some...
0
by: microsoft | last post by:
Hi People, when I try to modify an active directory user programatically, I receive the following exception: The server is unwilling to process the request Reading the microsoft web site, I...
9
by: Mario Rodriguez | last post by:
Hi people. I have a problem adding users to Win2003 active directory programatically. When I execute my app throws the following exception: .................The specified directory service...
10
by: huzz | last post by:
I have web application that quaries the Active Directory to get user details.. everything works fine but someday I'll get System.Runtime.InteropServices.COMExection and if I restart the client...
0
by: Si | last post by:
Hi there. I am developing a shopping cart that writes shopping basket contents to a temp DB with a temp reference of the sessionID to identify the 'owner' of the basket. My question is, when...
5
by: guischarf | last post by:
I have the following code on files "a.php" and "b.php" ----------------------------- FILE a.php ----------------------------- <form action="a.php" method="post"> <input type="hidden"...
1
by: tangus via DotNetMonster.com | last post by:
Hello all, I'm really struggling with getting some Active Directory code to work in ASP.NET. Can you please provide assistance? I am executing the following code: Dim enTry As DirectoryEntry =...
10
by: Hriday | last post by:
Hi there, Please help me..It is urgent This is Hriday, working on windows authentication with Active Directory... My requirment is when a user sends a request to my web Applicatoin I want to...
1
by: Hans Fehlow | last post by:
Hi All; This may be a very simple question, but for the life of me, don't know the answer. If I have 5 datagrids on a page but only a specific one, through coding, is active at one time. I...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.