forked from VimPlug/jedi
Document rethrow_uncaught/reraise
This commit is contained in:
@@ -91,6 +91,15 @@ def reraise(exception, traceback):
|
|||||||
raise exception, None, traceback
|
raise exception, None, traceback
|
||||||
""", 'blub', 'exec'))
|
""", 'blub', 'exec'))
|
||||||
|
|
||||||
|
reraise.__doc__ = """
|
||||||
|
Re-raise `exception` with a `traceback` object.
|
||||||
|
|
||||||
|
Usage::
|
||||||
|
|
||||||
|
reraise(Exception, sys.exc_info()[2])
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
# StringIO (Python 2.5 has no io module), so use io only for py3k
|
# StringIO (Python 2.5 has no io module), so use io only for py3k
|
||||||
try:
|
try:
|
||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
|
|||||||
@@ -21,8 +21,9 @@ class UncaughtAttributeError(Exception):
|
|||||||
Important, because `__getattr__` and `hasattr` catch AttributeErrors
|
Important, because `__getattr__` and `hasattr` catch AttributeErrors
|
||||||
implicitly. This is really evil (mainly because of `__getattr__`).
|
implicitly. This is really evil (mainly because of `__getattr__`).
|
||||||
`hasattr` in Python 2 is even more evil, because it catches ALL exceptions.
|
`hasattr` in Python 2 is even more evil, because it catches ALL exceptions.
|
||||||
Therefore this class has to be a `BaseException` and not an `Exception`.
|
Therefore this class originally had to be derived from `BaseException`
|
||||||
But because I rewrote hasattr, we can now switch back to `Exception`.
|
instead of `Exception`. But because I removed relevant `hasattr` from
|
||||||
|
the code base, we can now switch back to `Exception`.
|
||||||
|
|
||||||
:param base: return values of sys.exc_info().
|
:param base: return values of sys.exc_info().
|
||||||
"""
|
"""
|
||||||
@@ -36,6 +37,25 @@ class UncaughtAttributeError(Exception):
|
|||||||
|
|
||||||
|
|
||||||
def rethrow_uncaught(func):
|
def rethrow_uncaught(func):
|
||||||
|
"""
|
||||||
|
Re-throw uncaught `AttributeError`.
|
||||||
|
|
||||||
|
Usage: Put ``@rethrow_uncaught`` in front of the function
|
||||||
|
which does **not** suppose to raise `AttributeError`.
|
||||||
|
|
||||||
|
AttributeError is easily get caught by `hasattr` and another
|
||||||
|
``except AttributeError`` clause. This becomes problem when you use
|
||||||
|
a lot of "dynamic" attributes (e.g., using ``@property``) because you
|
||||||
|
can't distinguish if the property does not exist for real or some code
|
||||||
|
inside of the "dynamic" attribute through that error. In a well
|
||||||
|
written code, such error should not exist but getting there is very
|
||||||
|
difficult. This decorator is to help us getting there by changing
|
||||||
|
`AttributeError` to `UncaughtAttributeError` to avoid unexpected catch.
|
||||||
|
This helps us noticing bugs earlier and facilitates debugging.
|
||||||
|
|
||||||
|
.. note:: Treating StopIteration here is easy.
|
||||||
|
Add that feature when needed.
|
||||||
|
"""
|
||||||
@functools.wraps(func)
|
@functools.wraps(func)
|
||||||
def wrapper(*args, **kwds):
|
def wrapper(*args, **kwds):
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user