1
0
forked from VimPlug/jedi

Document rethrow_uncaught/reraise

This commit is contained in:
Takafumi Arakaki
2013-03-13 23:49:51 +01:00
parent 2b89dda5a6
commit 93bd00bba4
2 changed files with 31 additions and 2 deletions

View File

@@ -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

View File

@@ -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: