<br><font size=2 face="sans-serif">in the case of nested try/except code
generation, </font>
<br><font size=2 face="sans-serif">your suggestion could cause a problem:</font>
<br><font size=2><tt># 1) this is fine:</tt></font>
<br><font size=2><tt>doInitialStuff # With no exceptions<br>
excp = 0<br>
try:<br>
doLotsHere()<br>
except aParticularSetOfExceptions:<br>
excp = 1<br>
if excp:<br>
handleException()<br>
doLotsMoreStuff()</tt></font>
<br>
<br><font size=2><tt># 2) nested code generation has problem:</tt></font>
<br><font size=2><tt>doInitialStuff # With no exceptions<br>
excp = 0<br>
try:</tt></font>
<br><font size=2><tt><br>
doMOREInitialStuff # With no exceptions<br>
excp = 0<br>
try:<br>
doMORELotsHere()<br>
except aParticularSetOfExceptions:<br>
excp = 1 #### this causes the
problem<br>
if excp:<br>
handleException()<br>
doMORELotsMoreStuff()</tt></font>
<br>
<br><font size=2><tt> doLotsHere()<br>
except aParticularSetOfExceptions:<br>
excp = 1</tt></font>
<br><font size=2><tt>#### excp=1 from inner nested code generation<br>
if excp:<br>
handleException()<br>
doLotsMoreStuff()</tt></font>
<br>
<br><font size=2><tt># 3) Hence I return to my planned template code generation:</tt></font>
<br><font size=2><tt>excp = 0 #### Probaly need to do ONCE, to "bind"
variable ?</tt></font>
<br><font size=2><tt>doInitialStuff # With no exceptions<br>
try:</tt></font>
<br><font size=2><tt><br>
doMOREInitialStuff # With no exceptions<br>
try:<br>
doMORELotsHere()<br>
excp = 0 ##### always reset excp as
last action<br>
except aParticularSetOfExceptions:<br>
excp = 1<br>
if excp:<br>
handleException()<br>
doMORELotsMoreStuff()</tt></font>
<br>
<br><font size=2><tt> doLotsHere()<br>
excp = 0 ##### always reset excp as last action<br>
except aParticularSetOfExceptions:<br>
excp = 1</tt></font>
<br><font size=2><tt>if excp: #### should be fine<br>
handleException()<br>
doLotsMoreStuff()</tt></font>
<br>
<br><font size=2 face="sans-serif"><br>
Barry Searle, searle@ca.ibm.com, 905-413-4020 (TL:969-4020)<br>
Barry Searle/Toronto/IBM@IBMCA (D3/639/8200/MKM)<br>
"Architect, WebSphere Tools for WsAdmin Scripting and Automated Build
"<br>
<br>
</font>
<br>
<br>
<br>
<table width=100%>
<tr valign=top>
<td width=40%><font size=1 face="sans-serif"><b>Steve Holden <steve@holdenweb.com></b>
</font>
<p><font size=1 face="sans-serif">20/09/2005 04:11 PM</font>
<td width=59%>
<table width=100%>
<tr>
<td>
<div align=right><font size=1 face="sans-serif">To</font></div>
<td valign=top><font size=1 face="sans-serif">Barry Searle/Toronto/IBM@IBMCA</font>
<tr>
<td>
<div align=right><font size=1 face="sans-serif">cc</font></div>
<td valign=top><font size=1 face="sans-serif">python-list@python.org</font>
<tr>
<td>
<div align=right><font size=1 face="sans-serif">Subject</font></div>
<td valign=top><font size=1 face="sans-serif">Re: are variables local only
to try/except blocks?</font></table>
<br>
<table>
<tr valign=top>
<td>
<td></table>
<br></table>
<br>
<br>
<br><font size=2><tt>I am taking the liberty of copying my response to
your off-list reply <br>
back to the c.l.py community. (and I don't normally top-post except in
<br>
politeness to other top-posters :-)<br>
<br>
Seems to me you could avoid many of your problems by simply re-jigging
<br>
your template to read<br>
<br>
doInitialStuff # With presumably no exceptions<br>
excp = 0<br>
try:<br>
doLotsHere()<br>
except aParticularSetOfExceptions:<br>
excp = 1<br>
if excp:<br>
handleException()<br>
doLotsMoreStuff()<br>
<br>
If you have been experiencing problems with "unbound local variables"
<br>
this is almost certainly because, as you cast your template, there is <br>
the problem that if doLotsHere() raises an exception then the "excp"
<br>
variable will not be bound.<br>
<br>
The reason for this is that Python variables (technically names) are <br>
only "created" (technically, associated with a value) when they
are <br>
bound by the execution of an assignment. If the exception is raised <br>
before the assignment then the variable still (technically) doesn't <br>
exist in the current namespace (which your average Pythonista might <br>
describe by saying that the name hasn't been bound).<br>
<br>
There is *some* static analysis in Python to support name scoping, but
<br>
names must be bound by assignment in order to be referencable (?) <br>
without causing an AttributeError or NameError exception. That's a <br>
fundamental part of the way Python works.<br>
<br>
Hence my suggestion that you assign the zero before you do anything that
<br>
might raise exceptions. You will also note I suggest you check for <br>
specific exceptions (you can check for more that one by using a tuple <br>
rather than a single exception), as otherwise you may very well end up
<br>
treating unanticipated exceptions inappropriately and masking their <br>
occurrence.<br>
<br>
regards<br>
Steve<br>
<br>
Barry Searle wrote:<br>
> <br>
> Sorry, the quick sample was just to illustrate the problem and solution
<br>
> template.<br>
> The generic template would be:<br>
> doInitialStuff()<br>
> try:<br>
> doLotsHere()<br>
> excp = 0<br>
> except:<br>
> excp = 1<br>
> #endTry<br>
> if (excp): doExceptionHandling()<br>
> doLotsMoreStuff()<br>
> <br>
> The template will be used (is being used) for the automatic generation<br>
> of a bunch of Jython code, and I wanted to be sure there were not
scope<br>
> issues (i.e. that excp was not only defined within the try/except
blocks).<br>
> <br>
> Barry Searle, searle@ca.ibm.com, 905-413-4020 (TL:969-4020)<br>
> Barry Searle/Toronto/IBM@IBMCA (D3/639/8200/MKM)<br>
> "Architect, WebSphere Tools for WsAdmin Scripting and Automated
Build "<br>
> <br>
> <br>
> <br>
> *Steve Holden <steve@holdenweb.com>*<br>
> <br>
> 20/09/2005 11:55 AM<br>
> <br>
> <br>
> To<br>
> <br>
> cc<br>
> Barry
Searle/Toronto/IBM@IBMCA<br>
> Subject<br>
> Re:
are variables local only to try/except blocks?<br>
> <br>
> <br>
> <br>
> <br>
> <br>
> <br>
> <br>
> <br>
> BarrySearle wrote:<br>
> > # Is this valid (or is excp local to try/except)?<br>
> > try:<br>
> > try:<br>
> > doSomething1<br>
> > excp = 0<br>
> <br>
> This block is problematic because excp won;t be set if doSomething1<br>
> raises an exception.<br>
> <br>
> > except:<br>
> > excp = 1<br>
> > #endTry<br>
> > if (_excp_): doSomething1 # is excp defined
here?<br>
> <br>
> Presumably you are expecting doSomething1 to fail or succeed in some<br>
> non-deterministic way? Otherwise this will just raise the same exception<br>
> again!<br>
> <br>
> > excp = 0<br>
> > except:<br>
> > excp = 1<br>
> > #endTry<br>
> > if (excp): doSomething2 # is excp defined here?<br>
> ><br>
> ><br>
> > # valid, but more verbose (and maybe redundant?)<br>
> > excp = 0<br>
> > try:<br>
> > excp = 0<br>
> > try:<br>
> > doSomething1<br>
> > excp = 0 # reset incase
future inner block<br>
> > except:<br>
> > excp = 1<br>
> > #endTry<br>
> > if (_excp_): doSomething1<br>
> > excp = 0 # reset incase inner block
set excp=1<br>
> > except:<br>
> > excp = 1<br>
> > #endTry<br>
> > if (excp): doSomething2<br>
> ><br>
> > I am not so interested in what a particular version of
the<br>
> > Python/Jython interpreter does, but rather what is "right".<br>
> ><br>
> > Pls "CC" replies to searle@ca.ibm.com (as well
as newsgroup)<br>
> > Barry Searle, searle@ca.ibm.com<br>
> ><br>
> Your approach to exception handling is a little simplistic, resulting
on<br>
> code that reads about as well as a plate of spaghetti.<br>
> <br>
> What are you actually trying to *do*? What problem do you need to
solve?<br>
> <br>
> regards<br>
> Steve<br>
> -- <br>
> Steve Holden +44 150 684 7255 +1 800 494
3119<br>
> Holden Web LLC
www.holdenweb.com<br>
> PyCon TX 2006
www.pycon.org<br>
> <br>
<br>
<br>
-- <br>
Steve Holden +44 150 684 7255 +1 800 494 3119<br>
Holden Web LLC
www.holdenweb.com<br>
PyCon TX 2006
www.pycon.org<br>
</tt></font>
<br>