import sys
def checkarg():
try:
filename=str(sys.argv[1])
if filename=="-mycommand":
print "SPECIFIC_TEXT"
sys.exit()
else:
return filename
except:
print "ERROR"
sys.exit()
Hello all...i have a problem with the code above. When i call the 'checkarg' function, if i did not pass any parameter on the command line i have the "ERROR" output and sys exit, just as expected.
But, if i provide a parameter on the command line (like "-mycommand") it prints the "SPECIFIC_TEXT" and then prints "ERROR" message from the EXCEPT block too.
The TRY block will only run when I provide a parameter, if I don't, then EXCEPT will get the turn. But, it is running the TRY and EXCEPT blocks together.
Does anybody knows the reason of this behavior?? Any mistake on my code? Tks for all !
I think I understand your question...
sys.exit() exits by raising a SystemExit exception, which your except statement is catching.
Answer found here: http://docs.python.org/library/sys.html
sys.exit([arg])
Exit from Python. This is implemented by raising the SystemExit exception, so cleanup actions specified by finally clauses of try statements are honored, and it is possible to intercept the exit attempt at an outer level.
sys.exit works by raising an exception. That's why your except block executes.
You really shouldn't be using try/except for situations where you can check the state using control flow logic.
Instead, in this case, check for if len(sys.argv) > 1.
Another reason never to use specifically a blank except: You will catch even system exceptions like SystemExit or KeyboardInterrupt, making it potentially impossible to terminate your program short of a messy kill.
I know you've already accepted an answer, but I think the root of the problem is that your try block contains code in which you do not necessarily wish to catch exceptions; rather, you merely wish these statements to be executed after the code in which you wish to catch exceptions if no exception occurs.
To address this, your try block should contain only filename=str(sys.argv[1]) and the rest of the code now in your try block should be moved to an else block, which will be executed only if no exception occurs. In other words:
try:
filename=str(sys.argv[1])
except:
print "ERROR"
sys.exit()
else:
if filename=="-mycommand":
print "SPECIFIC_TEXT"
sys.exit()
else:
return filename
Or in this case, since you exit the script entirely in the case of an exception, you don't actually need the else:
try:
filename=str(sys.argv[1])
except:
print "ERROR"
sys.exit()
if filename=="-mycommand":
print "SPECIFIC_TEXT"
sys.exit()
else:
return filename
The fact that you're catching every exception with your bare except is bad style and changing that would also avoid the problem, but to me, it's secondary. You do not wish to catch exceptions in your if/else code, so it should not be in the try block to begin with. IMHO, most admonitions against bare except would be moot if this guideline were followed more closely.
Related
If I have a try except block in my python code, and the first line of my try statement raises an exception will it automatically move on to exception or will it finish the try block first?
try:
int(string)
string = "This was a mistake, can't int string"
except:
pass
Here is it checking if it can int(string), which it can't, and then it immediately moves onto except, or does it do the string assignment first?
When I run it, it seems like it stops right away, but I want to know if that's happening for sure or something else.
Thanks
Let's try it.
try:
1/0
print("what?")
except:
print("nope")
Output:
nope
>>>
When an exception is raised it moves on to the except.
From the python docs, I found this,
"The try statement works as follows.
First, the try clause (the statement(s) between the try and except keywords) is executed.
If no exception occurs, the except clause is skipped and execution of the try statement is finished.
If an exception occurs during execution of the try clause, the rest of the clause is skipped. Then if its type matches the exception named after the except keyword, the except clause is executed, and then execution continues after the try statement.
If an exception occurs which does not match the exception named in the except clause, it is passed on to outer try statements; if no handler is found, it is an unhandled exception and execution stops with a message as shown above."
Cheers!
Hope it helps!
#the try block is to run the process
try:
string = "This was a mistake, can't int string"
#you are parsing the string into an int
int(string)
#this block is to capture the exception when it is raised
except:
#here I am just printing the exception
print('Exception')
#the pass is to pass the execution and follow the remaining process.
pass
Output:
Exception
>>>
Well, that the whole point of an error handler. When an error occurs in out program, it crashes, it won't simply skip the error line.
try:
int(string)
string = "This was a mistake, can't int string"
except:
pass
So if the try block finishes even after an error occurred in the middle, then the error handler'd seem a bit pointless.
There seem to be some issue with your program and maybe your understanding of the try except block.
First of all, from the block of code you have provided, it seems to me like string isn't even defined yet when you try to pass int(string).
Secondly, the string variable which you seem to be defining under seems to me like is something you are trying to print to the console once the program spits out an error and passes to the except block. If this is what you are trying to do, then your code should look something like this:
try:
int(string)
except:
print("This was a mistake, can't int string")
If you were to run the code provided above, you would indeed confirm that the try except statement is working as it would print "This was a mistake, can't int string" into the console instead of giving an error. Hope this was somewhat helpful and understandable. You got this chief, keep grinding!
These days I am learning Python's Exception handling features deeply. I encountered exception SystemExit. While reading about this from official Python Docs I got question in mind that what exactly would have happen when I terminate Python script by pressing Ctrl+c?
lets take this sample code:
def func1(a,b):
print "func1: "+str(a/b)
#some more functions
def func2(a,b):
print "func2: "+str(a/b)
#some more functions
if __name__=="__main__":
import random
count=0
for i in range(1000000):
count=count+1
print "count: "+str(count)
try:
func1(random.randint(-2,3),random.randint(-2,3))
except KeyboardInterrupt:
raise
except:
print "error in func1"
try:
func2(random.randint(-2,3),random.randint(-2,3))
except KeyboardInterrupt:
raise
except:
print "error in func2"
print "\n"
In this sample code I am catching KeyboardInterrupt so I can stop my script by pressing Ctrl+c. Should I catch SystemExit too to make this code more mature? if yes then why? actually this question is source of my main question which appear on title. so don't consider that I am asking two different question in one post.
You usually not need to catch SystemExit as it is what makes exit() and sys.exit() functions work:
sys.exit([arg])
Exit from Python. This is implemented by raising the SystemExit exception, so cleanup actions specified by finally clauses of try statements are honored, and it is possible to intercept the exit attempt at an outer level.
Example:
try:
exit()
except SystemExit:
print "caught"
Therefore, you usually don't want to catch all exceptions in the first place (by using an empty except: clause). The best approach is generally to make your exception handlers as specific as possible. It otherwise makes debugging your application exceptionally hard, as it either hides errors entirely or at least makes it hard to diagnose the details.
The only exception your functions can raise is a ZeroDivisionError, so you should only catch that one:
import random
if __name__ == "__main__":
for count in range(1000000):
print "count:", count
try:
func1(random.randint(-2, 3),random.randint(-2, 3))
except ZeroDivisionError:
print "error in func1"
try:
func2(random.randint(-2, 3),random.randint(-2, 3))
except ZeroDivisionError:
print "error in func2"
print "\n"
Your title says something different than the body of your question.
To the title:
What happens internally is that python captures the SIGINT and raises a KeyboardInterrupt exception from it.
To the text:
You don't want to do except:.
Instead, you want
if __name__=="__main__":
try:
import random
count=0
for i in range(1000000):
count=count+1
print "count: "+str(count)
try:
func1(random.randint(-2,3),random.randint(-2,3))
except Exception, e:
print "error in func1", e # or something...
try:
func2(random.randint(-2,3),random.randint(-2,3))
except Exception, e:
print "error in func2", e # or something...
print "\n"
except Exception:
raise # any other "normal" exception.
except: # Here it is ok, as you handle most exceptions above.
pass
Most "normal" exception which should normally be handled derive from Exception. Those which have an internal meaning and should normally not be caught (except on global level) don't derive from Exception.
These are KeyboardInterrupt, SystemExit and GeneratorExit.
If you're uncertain what exceptions the code you're calling throws to indicate errors then you should (in order of preference):
Find out what it is documented to throw and only catch that
catch Exception, not everything.
Neither KeyboardInterrupt nor SystemExit is a subclass of Exception, but all of the standard Python exceptions used to indicate errors are.
I have a piece of code which is not in a function, say
x = 5
y = 10
if x > 5:
print("stopping")
What can I put after the print statement to stop the code from running further? Sys.exit() works, but raises an error that I don't want in the program. I want it to quietly stop the code as if it had reached the end of the main loop. Thanks.
As JBernardo pointed out, sys.exit() raises an exception. This exception is SystemExit. When it is not handled by the user code, the interpreter exits cleanly (a debugger debugging the program can catch it and keep control of the program, thanks to this mechanism, for instance)—as opposed to os._exit(), which is an unconditional abortion of the program.
This exception is not caught by except Exception:, because SystemExit does not inherit from Exception. However, it is caught by a naked except: clause.
So, if your program sees an exception, you may want to catch fewer exceptions by using except Exception: instead of except:. That said, catching all exceptions is discouraged, because this might hide real problems, so avoid it if you can, by making the except clause (if any) more specific.
My understanding of why this SystemExit exception mechanism is useful is that the user code goes through any finally clause after a sys.exit() found in an except clause: files can be closed cleanly, etc.; then the interpreter catches any SystemExit that was not caught by the user and exits for good (a debugger would instead catch it so as to keep the interpreter running and obtain information about the program that exited).
You can do what you're looking for by doing this:
import os
os._exit(1)
sys.exit() which is equivalent to sys.exit(0) means exit with success. sys.exit(1) or sys.exit("Some message") means exit with failure. Both cases raise a SystemExit exception. In fact when your program exists normally it is exactly like sys.exit(0) has been called.
When I ran across this thread, I was looking for a way to exit the program without an error, without an exception, have the code show as 'PASSED', and continue running other tests files. The solution, for me, was to use the return statement.
.
.
.
if re.match("^[\s\S]*gdm-simple-slave[\s\S]*$", driver.find_element_by_css_selector("BODY").text) == None:
print "Identifiers object gdm-simple-slave not listed in table"
return
else:
driver.find_element_by_xpath("//input[#value='gdm-simple-slave']").click()
.
.
.
That allowed me to run multiple programs while keeping the debugger running...
test_logsIdentifiersApache2EventWindow.py#16::test_LogsIdentifiersApache2EventWi
ndow **PASSED**
test_logsIdentifiersAudispdEventWindow.py#16::test_LogsIdentifiersAudispdEventWi
ndow **PASSED**
test_logsIdentifiersGdmSimpleSlaveEventWindow.py#16::test_LogsIdentifiersGdmSimp
leSlaveEventWindow Identifiers object gdm-simple-slave not listed in table
**PASSED**
test_logsIdentifiersAuditdEventWindow.py#16::test_LogsIdentifiersAuditdEventWind
ow **PASSED**
Use try-except statements.
a = [1, 2, 3, 4, 5]
for x in xrange(0,5):
try:
print a[x+1] #this is a faulty statement for test purposes
except:
exit()
print "This is the end of the program."
Output:
> python test.py
2
3
4
5
No errors printed, despite the error raised.
Some programmers use sys.exit, others use SystemExit.
What is the difference?
When do I need to use SystemExit or sys.exit inside a function?
Example:
ref = osgeo.ogr.Open(reference)
if ref is None:
raise SystemExit('Unable to open %s' % reference)
or:
ref = osgeo.ogr.Open(reference)
if ref is None:
print('Unable to open %s' % reference)
sys.exit(-1)
No practical difference, but there's another difference in your example code - print goes to standard out, but the exception text goes to standard error (which is probably what you want).
sys.exit(s) is just shorthand for raise SystemExit(s), as described in the former's docstring; try help(sys.exit). So, instead of either one of your example programs, you can do
sys.exit('Unable to open %s' % reference)
There are 3 exit functions, in addition to raising SystemExit.
The underlying one is os._exit, which requires 1 int argument, and exits immediately with no cleanup. It's unlikely you'll ever want to touch this one, but it is there.
sys.exit is defined in sysmodule.c and just runs PyErr_SetObject(PyExc_SystemExit, exit_code);, which is effectively the same as directly raising SystemExit. In fine detail, raising SystemExit is probably faster, since sys.exit requires an LOAD_ATTR and CALL_FUNCTION vs RAISE_VARARGS opcalls. Also, raise SystemExit produces slightly smaller bytecode (4bytes less), (1 byte extra if you use from sys import exit since sys.exit is expected to return None, so includes an extra POP_TOP).
The last exit function is defined in site.py, and aliased to exit or quit in the REPL. It's actually an instance of the Quitter class (so it can have a custom __repr__, so is probably the slowest running. Also, it closes sys.stdin prior to raising SystemExit, so it's recommended for use only in the REPL.
As for how SystemExit is handled, it eventually causes the VM to call os._exit, but before that, it does some cleanup. It also runs atexit._run_exitfuncs() which runs any callbacks registered via the atexit module. Calling os._exit directly bypasses the atexit step.
My personal preference is that at the very least SystemExit is raised (or even better - a more meaningful and well documented custom exception) and then caught as close to the "main" function as possible, which can then have a last chance to deem it a valid exit or not. Libraries/deeply embedded functions that have sys.exit is just plain nasty from a design point of view. (Generally, exiting should be "as high up" as possible)
According to documentation sys.exit(s) effectively does raise SystemExit(s), so it's pretty much the same thing.
While the difference has been answered by many answers, Cameron Simpson makes an interesting point in https://mail.python.org/pipermail/python-list/2016-April/857869.html:
TL;DR: It's better to just raise a "normal" exception, and use SystemExit or sys.exit only at the top levels of a script.
I m on python 2.7 and Linux , I have a simple code need suggestion if I
I could replace sys.exit(1) with raise SystemExit .
==Actual code==
def main():
try:
create_logdir()
create_dataset()
unittest.main()
except Exception as e:
logging.exception(e)
sys.exit(EXIT_STATUS_ERROR)
if __name__ == '__main__': main()
==Changed Code==
def main():
try:
create_logdir()
create_dataset()
unittest.main()
except Exception as e:
logging.exception(e)
raise SystemExit
if __name__ == '__main__':
main()
I am against both of these personally. My preferred pattern is like
this:
def main(argv):
try:
...
except Exception as e:
logging.exception(e)
return 1
if __name__ == '__main__':
sys.exit(main(sys.argv))
Notice that main() is back to being a normal function with normal
returns.
Also, most of us would avoid the "except Exception" and just let a top
level except bubble out: that way you get a stack backtrace for
debugging. I agree it prevents logging the exception and makes for
uglier console output, but I think it is a win. And if you do want
to log the exception there is always this:
try:
... except Exception as e:
logging.exception(e)
raise
to recite the exception into the log and still let it bubble out
normally.
The problem with the "except Exception" pattern is that it catches and
hides
every exception, not merely the narrow set of specific exceptions that you understand.
Finally, it is frowned upon to raise a bare Exception class. In
python 3 I believe it is actually forbidden, so it is nonportable
anyway. But even In Python to it is best to supply an Exception
instance, not the class:
raise SystemExit(1)
All the functions in try block have exception bubbled out using raise
Example for create_logdir() here is the function definition
def create_logdir():
try:
os.makedirs(LOG_DIR)
except OSError as e:
sys.stderr.write("Failed to create log directory...Exiting !!!")
raise
print "log file: " + corrupt_log
return True
def main():
try:
create_logdir()
except Exception as e:
logging.exception(e)
raise SystemExit
(a) In case if create_logdir() fails we will get the below error ,is
this fine or do I need to improve this code.
Failed to create log directory...Exiting !!!ERROR:root:[Errno 17] File
exists: '/var/log/dummy'
Traceback (most recent call last):
File "corrupt_test.py", line 245, in main
create_logdir()
File "corrupt_test.py", line 53, in create_logdir
os.makedirs(LOG_DIR)
File "/usr/local/lib/python2.7/os.py", line 157, in makedirs
OSError: [Errno 17] File exists: '/var/log/dummy'
I prefer the bubble out approach, perhap with a log or warning
messages as you have done, eg:
logging.exception("create_logdir failed: makedirs(%r): %s" %
(LOG_DIR, e)) raise
(Also not that that log message records more context: context is very
useful when debugging problems.)
For very small scripts sys.stderr.write is ok, but in general any of
your functions that turned out to be generally useful might migrate
into a library in order to be reused; consider that stderr is not
always the place for messages; instead reading for the logging module
with error() or wanr() or exception() as appropriate. There is more
scope for configuring where the output goes that way without wiring
it into your inner functions.
Can I have just raise , instead of SystemExit or sys.exit(1) . This
looks wrong to me
def main():
try:
create_logdir()
except Exception as e
logging.exception(e)
raise
This is what I would do, myself.
Think: has the exception been "handled", meaning has the situation
been dealt with because it was expected? If not, let the exception
bubble out so that the user knows that something not understood by
the program has occurred.
Finally, it is generally bad to SystemExit or sys.exit() from inside
anything other than the outermost main() function. And I resist it
even there; the main function, if written well, may often be called
from somewhere else usefully, and that makes it effectively a library
function (it has been reused). Such a function should not
unilaterally abort the program. How rude! Instead, let the exception
bubble out: perhaps the caller of main() expects it and can handle
it. By aborting and not "raise"ing, you have deprived the caller of
the chance to do something appropriate, even though you yourself
(i.e. "main") do not know enough context to handle the exception.
So I am for "raise" myself. And then only because you want to log the
error. If you didn't want to log the exception you could avoid the
try/except entirely and have simpler code: let the caller worry
about unhandled exceptions!
SystemExit is an exception, which basically means that your progam had a behavior such that you want to stop it and raise an error. sys.exit is the function that you can call to exit from your program, possibily giving a return code to the system.
EDIT: they are indeed the same thing, so the only difference is in the logic behind in your program. An exception is some kind of "unwanted" behaviour, whether a call to a function is, from a programmer point of view, more of a "standard" action.
I know that is a weird question, and probably there is not an answer.
I'm trying to execute the rest of the try block after an exception was caught and the except block was executed.
Example:
[...]
try:
do.this()
do.that()
[...]
except:
foo.bar()
[...]
do.this() raise an exception managed by foo.bar(), then I would like to execute the code from do.that(). I know that there is not a GOTO statement, but maybe some kind of hack or workaround!
Thanks!
A try... except... block catches one exception. That's what it's for. It executes the code inside the try, and if an exception is raised, handles it in the except. You can't raise multiple exceptions inside the try.
This is deliberate: the point of the construction is that you need explicitly to handle the exceptions that occur. Returning to the end of the try violates this, because then the except statement handles more than one thing.
You should do:
try:
do.this()
except FailError:
clean.up()
try:
do.that()
except FailError:
clean.up()
so that any exception you raise is handled explicitly.
Use a finally block? Am I missing something?
[...]
try:
do.this()
except:
foo.bar()
[...]
finally:
do.that()
[...]
If you always need to execute foo.bar() why not just move it after the try/except block? Or maybe even to a finally: block.
One possibility is to write a code in such a way that you can re-execute it all when the error condition has been solved, e.g.:
while 1:
try:
complex_operation()
except X:
solve_problem()
continue
break
fcts = [do.this, do.that]
for fct in fcts:
try:
fct()
except:
foo.bar()
You need two try blocks, one for each statement in your current try block.
This doesn't scale up well, but for smaller blocks of code you could use a classic finite-state-machine:
states = [do.this, do.that]
state = 0
while state < len(states):
try:
states[state]()
except:
foo.bar()
state += 1
Here's another alternative. Handle the error condition with a callback, so that after fixing the problem you can continue. The callback would basically contain exactly the same code you would put in the except block.
As a silly example, let's say that the exception you want to handle is a missing file, and that you have a way to deal with that problem (a default file or whatever). fileRetriever is the callback that knows how to deal with the problem. Then you would write:
def myOp(fileRetriever):
f = acquireFile()
if not f:
f = fileRetriever()
# continue with your stuff...
f2 = acquireAnotherFile()
if not f2:
f2 = fileRetriever()
# more stuff...
myOp(magicalCallback)
Note: I've never seen this design used in practice, but in specific situations I guess it might be usable.