Order of Exception evaluations - python

In python exceptions, does the TypeError check occur before doing the ValueError check? For example:
>>> chr(123)
'{'
>>> chr('x')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: an integer is required (got type str)
>>> chr(18293939)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: chr() arg not in range(0x110000)
>>> chr(1829393993939393)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: signed integer is greater than maximum
Or what is the order in which the various errors are checked? Is there documentation on the order of operations/evaluations for the difference Exception types?

None of this is documented (i.e., guaranteed). That said, it would be impossible to raise a sensible ValueError if there was no value of the correct type to compare. The difference between ValueError and OverflowError is surely an implementation detail entirely, since anything that overflows the target type would of course be out of any restricted range for that type.

Related

Catching SyntaxError from ast.literal_eval

I have the following code to evaluate some configuration values stored in a file:
from ast import literal_eval
for key, value in dict_read_from_file.items():
try:
cfg[key] = literal_eval(value)
except ValueError:
cfg[key] = value
However, with certain inputs literal_eval raises a SyntaxError, rather than a ValueError:
>>> literal_eval('asdf')
Traceback (most recent call last):
[...]
ValueError: malformed node or string on line 1: <ast.Name object at 0x000001A065B69AE0>
>>> literal_eval('123 4')
Traceback (most recent call last):
[...]
File "ast.py", line 50, in parse
return compile(source, filename, mode, flags,
File "<unknown>", line 1
123 4
^
SyntaxError: invalid syntax
But Python doesn't seem to let me catch the SyntaxError:
>>> try:
... literal_eval('123 4')
... except ValueError | SyntaxError:
... print("Fixing")
...
Traceback (most recent call last):
[...]
SyntaxError: invalid syntax
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
TypeError: catching classes that do not inherit from BaseException is not allowed
How do I catch and properly handle this SyntaxError?

Splitting strings unhashable type

I have never split strings in Python before so I am not too sure what is going wrong here.
import pyowm
owm = pyowm.OWM('####################')
location = owm.weather_at_place('Leicester, uk')
weather = location.get_weather()
weather.get_temperature('celsius')
temperature = weather.get_temperature('celsius')
print(temperature[5:10])
Error received
sudo python weather.py
Traceback (most recent call last):
File "weather.py", line 10, in <module>
print(temperature[5:10])
TypeError: unhashable type
get_temperature returns a dictionary, which you're then trying to index with a slice object, which is not hashable. e.g.
>>> hash(slice(5, 10))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type
To get the temperature, you need to get it from the dictionary like this:
temperature['temp']

how to use python help to file functions

If I want to see the str.replace() function: help(str.replace)
the result is:
Help on method_descriptor:
replace(...)
S.replace(old, new[, count]) -> str
Return a copy of S with all occurrences of substring
old replaced by new. If the optional argument count is
given, only the first count occurrences are replaced.
(END)
but how use help file.read or readlines?
for example, help(file.read) and help(read) are both errors:
>>> help(file)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'file' is not defined
>>> help(file.read)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'file' is not defined
>>> help(read)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'read' is not defined
How can I use help see file functions?
The file type has been removed from Python 3. Look at the io module instead:
>>> import io
>>> help(io.TextIOBase.read)
Help on method_descriptor:
read(...)
Read at most n characters from stream.
Read from underlying buffer until we have n characters or we hit EOF.
If n is negative or omitted, read until EOF.

"argument 1 has unexpected type 'str'"

I'm trying to use PyKDE, PyKDE.kdecore.KStandardDirs to be precise. This method is called with two strings according to the documentation and according to the PyQt4 documentation, I can use standard Python strs instead of QString.
This doesn't work:
>> KStandardDirs.locate()("socket", "foo")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: KStandardDirs.locate(): not enough arguments
>>> KStandardDirs.locate("socket", "foo")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: KStandardDirs.locate(): argument 1 has unexpected type 'str'
I can't use QString either because it doesn't seem to exist:
>>> from PyQt4.QtCore import QString
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: cannot import name QString
>>> from PyQt4.QtCore import *
>>> QString
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'QString' is not defined
What am I doing wrong?
I suspect that PyKDE is not yet Python 3 ready, at least as far as that error message is concerned; try passing in a bytestring instead:
KStandardDirs.locate(b"socket", "foo")

Which exception to raise if a given string does not match some format?

This is a follow up to an older question.
Given a ISBN number, e.g. 3-528-03851-5 which exception type should I raise if the passed in string doesn't match the format X-XXX-XXXXX-X?
Raise a ValueError.
It's pretty much the standard way of saying "you've given me a value that doesn't make sense". For example:
>>> int("a")
Traceback (most recent call last):
File "", line 1, in
ValueError: invalid literal for int() with base 10: 'a'
>>> import shlex; shlex.split("'")
Traceback (most recent call last):
...
ValueError: No closing quotation
Contrast this with a TypeError, which is raised when a type is incorrect:
>>> d = {}
>>> d[{}]
Traceback (most recent call last):
File "", line 1, in
TypeError: unhashable type: 'dict'
I think I'd make an exception class to raise in this instance since its a very specific type of exception. You can extend the ValueError class pretty easily:
class ISBNFormatException(ValueError):
"""Raised when an invalid ISBN format is found"""
pass
The ValueError might be the most appropriate choice. According to its docs, it's when a value has the correct type but an inappropriate value.
http://docs.python.org/library/exceptions.html#exceptions.ValueError

Categories