Handling exceptions without try block in Python's interactive shell - python

See the title of this question. I want to play with the exception raised in the last command. _ didn't help me. Is there anything like that?

Do this:
import sys
sys.exc_info()
It will give you information about the exception. It's a tuple containing the exception type, the exception instance and a traceback object.

If your 'interactive' happens within Jupyter, check this > Jupyter magic to handle notebook exceptions
It is just beautiful.
If you want to add a sound > Jupyter / Colab : Play sound with any error in any cell + Play sound after completing long running cells

Related

How to make Python "not recognized as an internal or external command" an exception

I have this block of code:
path = askdirectory(title='Choose folder')
os.chdir(path)
try:
os.system('currency.py')
except:
#Error message
ctypes.windll.user32.MessageBoxW(0, u"Error", u"Error", 0)
What I want to accomplish is that when the user chooses the wrong folder (the one in which the 'currency.py' file is not in), it throws this little Error message box.
Instead, when I purposely choose the wrong folder, it says:
"currency.py "is not recognized as an internal or external command
But it doesn't show me the error window. Is there a way to make python recognize this error as an exception? Thank you!
It appears you are using Python to run a Python file using the operating system shell.
You can run the file by importing it and (if needed) instantiating it.
try:
# import the python file
import currency.py
# instantiate the class/function if required
except ImportError:
ctypes.windll.user32.MessageBoxW(0, u"Error", u"Error", 0)
Nevertheless you can avoid using the try/catch scenario by seeing if the file exists, if not, display your error message:
if os.path.isfile(file_path):
os.system('currency.py')
else:
ctypes.windll.user32.MessageBoxW(0, u"Error", u"Error", 0)
You could try listening for the %ErrorLevel% code for anything different than 0 (successful) and, if it matches, then raise Exception.
It would work like this, for example:
if os.system('currency.py'):
raise Exception

How to automatically execute next cell even if an error occurs in the current cell in Jupyter?

I am running a cell in Jupyter notebook where an error is bound to occur after some time(usually hours). But even after this error occurs, I want the compiler to just move on to the next cell and run the remaining cells that I put in the queue to be run after this cell finishes.
I know exceptions might be able to do this, but I wanted to know if there was any other way specific to Python or Jupyter notebook that might do the trick.
Cell 1: Some code running
# Error will occur here and stop the execution
Cell 2,3...,n: Some code
# Code should still run after the error occurs in Cell 1
Thanks for any solutions. The help is appreciated.
There's a Jupyter Notebook nbextensions extension called Runtools which allows you to run all cells and ignore errors with the shortcut Alt + F. See Installing jupyter_contrib_nbextensions on how to install nbextensions and enable extensions like Runtools.
There's no need to install any extension, at least not since notebook 5.1.
After activating tags with View > Cell Toolbar > Tags, you can add raises-exception.
Jupyter will not stop the execution after this cell, even if an exception is raised. It will also keep on running if the tag is set and no exception is raised.
Here's a Jupyter example after launching Kernel > Restart & Run All:
One way through creating a custom magic method in jupyter notebook, (adapted from this answer here):
from IPython.core.magic import register_cell_magic
#register_cell_magic('handle')
def handle(line, cell):
try:
# exec(cell) # doesn't return the cell output though
return eval(cell)
except Exception as exc:
print(f"\033[1;31m{exc.__class__.__name__} : \033[1;31;47m{exc}\033[0m")
# raise # if you want the full trace-back in the notebook
Now we can add the magic command %%handle at the beginning of any cell in jupyter notebook and it will ensure that the script doesn't stop due to any error arising in that cell.
%%handle
1/0
%%handle
1/1

Python 3.3.2 doesn't allow me to use 'raise SystemExit'

name = input('name? ')
if len(name) == 0:
print('error.\n')
raise SystemExit
I receive an error when using python 3.3.2 (which is the version is school sadly) but it works fine on other versions e.g. 2.7.10 and 3.5
This is the error
Looking at the screenshot I can see Python prompt at the bottom:
This means the script is run in an interactive session (IDLE on Windows I guess). I haven't found any documentation, but other users have discovered that raising SystemExit in an interactive session does print the traceback.
So you should check and ensure that you are not launching the script in an interactive session.
Old answer:
Looks like it's a bug (or a particularity) in Python 3.3.2. According to this blog post:
If nothing catches the exception, then the python interpreter catches
it at the end, does not print a stack trace, and then calls exit.
I tried to raise SystemExit('asd') and the program just printed asd, so looks like it's true.
Either upgrade Python or try os._exit(1).
Not sure if this is what you want, but if you wanna exit use this:
import sys
name = raw_input('name? ')
if len(name) == 0:
print('error.\n')
sys.exit()
This exits the interpreter by raising SystemExit.
Why don't you use sys.exit()?
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.
You probably have an handler set for excepthook:
https://docs.python.org/3/library/sys.html#sys.excepthook
You should be able to reset it by doing
sys.excepthook = sys.__excepthook__
Nevermind, the hook works correctly for BaseException, but weirdly enough not for SystemExit (which is a subclass of BaseException).
You're probably executing your program with
python3 -i whatever.py
This gives me the same behavior you witnessed:
dario#feynman ~> python3 -i /tmp/a.py
Traceback (most recent call last):
File "/tmp/a.py", line 11, in <module>
raise SystemExit()
SystemExit
>>>
Note the >>> at the end.
Just remove the -i flag, from whatever is executing your program
Alternatively, it's bad practice, but you can also use os._exit(1)

Which Python exception should I throw?

I'm writing some code to manipulate the Windows clipboard. The first thing I do is to try and open the clipboard with OpenClipboard() function from the Windows API:
if OpenClipboard(None):
# Access the clipboard here
else:
# Handle failure
This function can fail. So if it does, I would like to raise an exception. My question is, which of the standard Python exceptions should I raise? I'm thinking WindowsError would be the right one, but not sure. Could someone please give me a suggestion?
It is better to avoid raising standard exceptions directly. Create your own exception class, inherit it from the most appropriate one (WindowsError is ok) and raise it. This way you'll avoid confusion between your own errors and system errors.
Raise the windows error and give it some extra infomation, for example
raise WindowsError("Clipboard can't be opened")
Then when its being debugged they can tell what your windows error means rather than just a random windowserror over nothing.
WindowsError seems a reasonable choice, and it will record extra error information for you. From the docs:
exception WindowsError
Raised when a Windows-specific error occurs or when the error number does not correspond to an errno value. The winerror and strerror values are created from the return values of the GetLastError() and FormatMessage() functions from the Windows Platform API. The errno value maps the winerror value to corresponding errno.h values. ...

Really weird issue with shelve (python)

I create a file called foo_module.py containing the following code:
import shelve, whichdb, os
from foo_package.g import g
g.shelf = shelve.open("foo_path")
g.shelf.close()
print whichdb.whichdb("foo_path") # => dbhash
os.remove("foo_path")
Next to that file I create a directory called foo_package than contains an empty __init__.py file and a file called g.py that just contains:
class g:
pass
Now when I run foo_module.py I get a weird error message:
Exception TypeError: "'NoneType' object is not callable" in ignored
But then, if I rename the directory from foo_package to foo, and change the import line in foo_module.py, I don't get any error. Wtf is going on here?
Running Python 2.6.4 on WinXP.
I think you've hit a minor bug in 2.6.4's code related to the cleanup at end of program. If you run python -v you can see exactly at what point of the cleanup the error comes:
# cleanup[1] foo_package.g
Exception TypeError: "'NoneType' object is not callable" in ignored
Python sets references to None during the cleanup at the end of program, and it looks like it's getting confused about the status of g.shelf. As a workaround you could set g.shelf = None after the close. I would also recommend opening a bug in Python's bug tracker!
After days of hair loss, I finally had success using an atexit function:
import atexit
...
cache = shelve.open(path)
atexit.register(cache.close)
It's most appropriate to register right after opening. This works with multiple concurrent shelves.
(python 2.6.5 on lucid)
This is indeed a Python bug, and I've posted a patch to the tracker issue you opened (thanks for doing that).
The problem is that shelve's del method calls its close method, but if the shelve module has already been through cleanup, the close method fails with the message you see.
You can avoid the message in your code by adding 'del g.shelf' after g.shelf.close. As long as g.shelf is the only reference to the shelf, this will result in CPython calling the shelve's del method right away, before the interpreter cleanup phase, and thus avoid the error message.
It seems to be an exception in a shutdown function registered by the shelve module. The "ignored" part is from the shutdown system, and might get its wording improved sometime, per Issue 6294. I'm still hoping for an answer on how to eliminate the exception itself, though...
for me a simple shelve.close() on an unclosed one did the job.
shelve.open('somefile') returns a "persistent dictionary for reading and writing" object which i used throughout the app's runtime.
when I terminated the app I received the "TypeError" Exception as mentioned.
I plased a 'close()' call in my termination sequence and that seemed to fix the problem.
e.g.
shelveObj = shelve.open('fileName')
...
shelveObj.close()
OverByThere commented on Jul 17, 2018
This seems to be fixable.
In short open /usr/lib/python3.5/weakref.py and change line 109 to:
def remove(wr, selfref=ref(self), _atomic_removal=_remove_dead_weakref):
And line 117 to:
_atomic_removal(d, wr.key)
Note you need to do this with spaces, not tabs as this will cause other errors.

Categories