|
|
|
"""A fancy version of Python's builtin :func:`dir` function. |
|
""" |
|
|
|
|
|
|
|
|
|
import inspect |
|
import types |
|
|
|
|
|
def safe_hasattr(obj, attr): |
|
"""In recent versions of Python, hasattr() only catches AttributeError. |
|
This catches all errors. |
|
""" |
|
try: |
|
getattr(obj, attr) |
|
return True |
|
except: |
|
return False |
|
|
|
|
|
def dir2(obj): |
|
"""dir2(obj) -> list of strings |
|
|
|
Extended version of the Python builtin dir(), which does a few extra |
|
checks. |
|
|
|
This version is guaranteed to return only a list of true strings, whereas |
|
dir() returns anything that objects inject into themselves, even if they |
|
are later not really valid for attribute access (many extension libraries |
|
have such bugs). |
|
""" |
|
|
|
|
|
|
|
|
|
try: |
|
words = set(dir(obj)) |
|
except Exception: |
|
|
|
words = set() |
|
|
|
if safe_hasattr(obj, '__class__'): |
|
words |= set(dir(obj.__class__)) |
|
|
|
|
|
|
|
|
|
words = [w for w in words if isinstance(w, str)] |
|
return sorted(words) |
|
|
|
|
|
def get_real_method(obj, name): |
|
"""Like getattr, but with a few extra sanity checks: |
|
|
|
- If obj is a class, ignore everything except class methods |
|
- Check if obj is a proxy that claims to have all attributes |
|
- Catch attribute access failing with any exception |
|
- Check that the attribute is a callable object |
|
|
|
Returns the method or None. |
|
""" |
|
try: |
|
canary = getattr(obj, '_ipython_canary_method_should_not_exist_', None) |
|
except Exception: |
|
return None |
|
|
|
if canary is not None: |
|
|
|
return None |
|
|
|
try: |
|
m = getattr(obj, name, None) |
|
except Exception: |
|
return None |
|
|
|
if inspect.isclass(obj) and not isinstance(m, types.MethodType): |
|
return None |
|
|
|
if callable(m): |
|
return m |
|
|
|
return None |
|
|