Python Warning control - python

I would like some kind of warning to be raisen as errors, but only the first occurrence. How to do that?
I read http://docs.python.org/library/warnings.html and I dont know how to combine this two types of behaviour.

Looking at the code to warnings.py, you can't assign more than one filter action to a warning, and you can't (easily) define your own actions, like 'raise_once'.
However, if you want to raise a warning as an exception, but just once, that means that you are catching the exception. Why not put a line in your except clause that sets an 'ignore' action on that particular warning?
#!/usr/bin/python
import warnings
warnings.filterwarnings('error','Test')
for i in range(2):
try:
warnings.warn('Test');
except UserWarning, e:
print "Error caught"
warnings.filterwarnings('ignore','Test')

Related

How to generate a python exception with full stacktrace / details?

I want to capture and log (not print) an exception, my current approach is to raise and catch at the same time:
try:
raise MyException("Ops!")
except MyException as e:
do_stuff(e)
The reason why I am not simply calling do_stuff(MyException("...")) is because I need a full stacktrace associated with when it happened.
Is there a more "pythonic" way to do that like do_stuff(raised MyException("..."))?
Extra examples:
# #Bloodbee (comments) -- this will not work, no stacktrace
e = Exception("Ops")
logger.exception(e)
--
I did my searching around but my results are around generating a stacktrace by itself (using traceback) or preserving stacktraces (raise ... from ...), both are not what I am looking for.
Thank you.

Is there a simple way to comment out or diable a python try statement without re-indenting

Problem:
Sometimes it is nice to be able to remove or apply a try statement temporarily. Is there a convenient way to disable the try statement without re-indenting?
For example, if there was a python block statement equivalent called "goForIt:" one could edit the word "try:" to "goForIt:" and it would just execute the block as though it were not wrapped in a "try" and ignore the "except" line too.
The problem I'm trying to solve is that while I want the try statement in production I want to be able to remove it temporarily while debugging to see the error traceback rather than have it trap and process the exception.
Currently I work around this by commenting out the "try" then re-indent the code in the block. Then comment out the entire "except" block. This seems clumsy.
Instead of removing the try, you could make the except re-raise the exception:
try:
raise ValueError('whoops')
except ValueError as e:
raise # <-- just put this here
print('caught')
This will raise the error, just as if it were not caught:
ValueError Traceback (most recent call last)
<ipython-input-146-a6be6779c161> in <module>
1 try:
----> 2 raise ValueError('whoops')
3 except ValueError as e:
4 raise
5 print('caught')
ValueError: whoops
I do not believe there is a way to fix this.
Is it adequate to catch the exception, print it out and, if wanted, end the program?
try:
# code
except Exception as e:
print(e)
# end program if wanted
If you want a none code solution you need to use an IDE or a good text editor.
I am using Visual Studio code where I can indent with a keyboard shortcut (Ctrl + ` in my case)
(This is not my answer, but the answer from Alani's comment. If credits, find the original comment under the question.)
The solution is good because it allows global replacement:
try: --> if 1: # try:
except --> if 0: # except
The 2nd one is a little unsure. Exact and full word match should be used, or replace twice (for except<space> and except:). Or you can fix error fast by hand if there is any.
The replacement back is sure.
I need now such solution to debug error in strawberry which is only printed. So I think I need deactivate all try/except structures in 3 libraries (strawberry + 2 libs for django).

Python catching errors from package, finding out which sublibrary exception belongs in

I've encountered several times now that I want to catch an exception that was raised by some library, but that it takes some time to actually find where that exception resides.
Example
Suppose I want to read some csv-file, except the seperator can be one of 2 values. I'd use:
import pandas
try:
mydf=pandas.read_csv('Somefile.csv', sep=';')
if not someValidityChecks(mydf): raise myExc.NotValidError
except:
mydf=pandas.read_csv('Somefile.csv', sep=',')
Now this code catches any and all exceptions, which is not really what I want (it's not Zen).
What I actually want, is to catch NotValidError, and the exception that is thrown by pandas if it encounters some invalid csv: ParserError.
But except myExc.NotValidError, ParserError won't work, because ParserError is not defined in my context. Instead, it should be pandas.errors.ParserError.
The question
Is there some quick way to find out where an exception is defined?
That there is a ParserError that I should catch, is easy enough to find out by simply letting it be thrown, the errormessage clearly shows that. Yet to find out where that error comes from, I have to dig into the stacktrace, and look at all the imports where it could be defined.
Now pandas doesn't have the most complicated structure, and guessing that the error could be in pandas.errors isn't that hard, but it still takes some time checking. Other libraries might have defined their exceptions at some more unexpected place, or spread all around. It should be easy enough to find out what actual error (including package) was thrown, right?
Environment
I'm working with Anaconda/Spyder 3.3.2, with Python 3.7
The quick way to do this is to print the module of the exception and it's qualified name:
try:
# thing that generates exception
raise pd.errors.ParserError
except Exception as e:
print(type(e).__module__, type(e).__qualname__)
pandas.errors ParserError

How to handle exception with parameters in Python

In Python 3.x, what is the correct syntax to handle exceptions that have parameters.
I'm specifically trying to handle WriteError documented on this page.
I'm writing the code to handle it as:
except pymongo.errors.WriteError(err, code, dtls):
logging.error("DB Write Error. err={}; code={}; dtls={}".format(err, code, dtls))
This is not working.
I even had a look at the Erros and Exceptions documentation. But could not find it there.
Can you please tell me the correct way to handle these sort of exceptions?
You catch the error first, then examine its attributes (reraising the exception if it isn't one you want to handle). There is no pattern matching on the contents of the exception.
except pymongo.errors.WriteError as exc:
logging.error("DB WriteError. err={}; code={}; dtls={}".format(exc.err, exc.code, exc.dtls))
The except block just needs the exception's type. Within the block you could, of course, use its attributes if you wish:
except pymongo.errors.WriteError as e:
logging.error("DB Write Error. err={}; code={}; dtls={}".format(e.err, e.code, e.dtls))

Any way to save a traceback object in Python

I was looking to possibly try and save a traceback object and somehow pickle it to a file that I can access. An example of a use case for this is if I am submitting some python code to a farm computer to run and it fails, it would be nice to be able to open a session and access that traceback to debug the problem rather than just seeing a log of the traceback. I do not know if there is any sort of way to do this but thought it would be worth asking why it couldn't if so.
okay so you can use traceback.print_exception(type, value, traceback[, limit[, file]]) and save it in a text or json or you can refer to docs
if you find it helpful please mark it correct or upvote thanx..:)
Depending on how you've written your code, the try statement is probably your best answer. Since any error is just a class that inherits Python's builtin Exception, you can raise custom errors everywhere you need more information about a thrown error. You just need to rename your errors or pass in an appropriate string as the first argument. If you then try your code and use the except statement except CustomError as e, you can pull all the information you want out of e in the except statement as a regular instance. Example:
Your code would be:
def script():
try: codeblock
except Exception as e: raise Error1('You hit %s error in the first block'% e)
try: codeblock 2
except Exception as e: raise Error2('You hit %s error in the second block' % e)
try: script()
except Exception as e:
with open('path\to\file.txt','w') as outFile:
outFile.write(e)
The last part is really nothing more than creating your own log file, but you have to write it down somewhere, right?
As for using the traceback module mentioned above, you can get error information out of that. Any of the commands here can get you a list of tracebacks:
http://docs.python.org/2/library/traceback.html
On the otherhand, if you're trying to avoid looking at log files, the traceback module is only going to give you the same thing a log file would, in a different format. Adding your own error statements in your code gives you more information than a cryptic ValueError about what actually happened. If you print the traceback to your special error, it might give you still more information on your issue.

Categories

Resources