Potential Exceptions Using Builtin Str() Type In Python
Solution 1:
In summary: Is it generally safe to use
str()
without atry
/except
block even with unreliable input?
That depends on what kind of input we're talking about. You've tagged this question Python 3, so you don't need to worry about the UnicodeEncodeErrors you'd get with Python 2 and Unicode input, but the object you're receiving could do pretty much anything in its __str__
or __repr__
, raising pretty much any kind of exception. For example,
In [18]: import weakref
In [19]: class Foo(object): pass
In [20]: str(weakref.proxy(Foo()))
---------------------------------------------------------------------------
ReferenceError Traceback (most recent call last)
<ipython-input-20-396b2ab40052> in <module>()
----> 1str(weakref.proxy(Foo()))
ReferenceError: weakly-referenced object no longer exists
Solution 2:
There's a huge difference between str
and int
in this regard. int
can definitely raise TypeError
and ValueError
.
As far as I can think, the only exception that str
can raise for normal objects is UnicodeEncodeError
:
>>>s = u"a\xac\u1234\u20ac\U00008000">>>str(s)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-4: ordinal not in range(128)
And that only happens on python2.x.
Of course, I can easily make a class that fails with just about any exception imaginable:
>>>classMyError(Exception):...pass...>>>classFoo(object):...def__str__(self):...raise MyError...>>>f = Foo()>>>str(f)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __str__
__main__.MyError
For the most part, I would question some of the implicit assumptions that all exceptions need to be handled at this point. Generally, it's best to only handle exceptions that you know how to handle. In this case, exotic exceptions that happen because the user put junk into the function should probably be handled at the level where the junk is going in -- not within the function itself. Catching the error and returning some value which is likely nonsense isn't going to be super helpful for debugging issues, etc.
Solution 3:
Due to concerns you've raised, I'd do except Exception as e:
. Exception
is generic "catch-all" in Python 3 for "normal" exceptions (other than "system-level" exceptions resulting from process getting signals, KeyboardInterrupt
, etc).
If I were you I'd log the actual exception (e
in my example above) at the very least, to see what actually happen (your code silently drops actual exception object by doing except Exception:
).
Post a Comment for "Potential Exceptions Using Builtin Str() Type In Python"