1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
# -*- coding: utf-8 -*-
"""
sphinx.util.inspect
~~~~~~~~~~~~~~~~~~~
Helpers for inspecting Python modules.
:copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import sys
# this imports the standard library inspect module without resorting to
# relatively import this module
inspect = __import__('inspect')
from sphinx.util import force_decode
from sphinx.util.pycompat import bytes
if sys.version_info >= (2, 5):
from functools import partial
def getargspec(func):
"""Like inspect.getargspec but supports functools.partial as well."""
if inspect.ismethod(func):
func = func.im_func
parts = 0, ()
if type(func) is partial:
keywords = func.keywords
if keywords is None:
keywords = {}
parts = len(func.args), keywords.keys()
func = func.func
if not inspect.isfunction(func):
raise TypeError('%r is not a Python function' % func)
args, varargs, varkw = inspect.getargs(func.func_code)
func_defaults = func.func_defaults
if func_defaults is None:
func_defaults = []
else:
func_defaults = list(func_defaults)
if parts[0]:
args = args[parts[0]:]
if parts[1]:
for arg in parts[1]:
i = args.index(arg) - len(args)
del args[i]
try:
del func_defaults[i]
except IndexError:
pass
if sys.version_info >= (2, 6):
return inspect.ArgSpec(args, varargs, varkw, func_defaults)
else:
return (args, varargs, varkw, func_defaults)
else:
getargspec = inspect.getargspec
def isdescriptor(x):
"""Check if the object is some kind of descriptor."""
for item in '__get__', '__set__', '__delete__':
if hasattr(safe_getattr(x, item, None), '__call__'):
return True
return False
def safe_getattr(obj, name, *defargs):
"""A getattr() that turns all exceptions into AttributeErrors."""
try:
return getattr(obj, name, *defargs)
except Exception:
# this is a catch-all for all the weird things that some modules do
# with attribute access
if defargs:
return defargs[0]
raise AttributeError(name)
def safe_getmembers(object, predicate=None):
"""A version of inspect.getmembers() that uses safe_getattr()."""
results = []
for key in dir(object):
try:
value = safe_getattr(object, key, None)
except AttributeError:
continue
if not predicate or predicate(value):
results.append((key, value))
results.sort()
return results
def safe_repr(object):
"""A repr() implementation that returns text safe to use in reST context."""
try:
s = repr(object)
except Exception:
raise ValueError
if isinstance(s, bytes):
return force_decode(s, None).replace('\n', ' ')
return s.replace('\n', ' ')
|