Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(6)

Delta Between Two Patch Sets: Lib/inspect.py

Issue 1764286: inspect.getsource does not work with decorated functions
Left Patch Set: Created 9 years, 4 months ago
Right Patch Set: Created 6 years, 5 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | Lib/test/inspect_fodder2.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 # -*- coding: iso-8859-1 -*-
2 """Get useful information from live Python objects. 1 """Get useful information from live Python objects.
3 2
4 This module encapsulates the interface provided by the internal special 3 This module encapsulates the interface provided by the internal special
5 attributes (func_*, co_*, im_*, tb_*, etc.) in a friendlier fashion. 4 attributes (co_*, im_*, tb_*, etc.) in a friendlier fashion.
6 It also provides some help for examining source code and class layout. 5 It also provides some help for examining source code and class layout.
7 6
8 Here are some of the useful functions provided by this module: 7 Here are some of the useful functions provided by this module:
9 8
10 ismodule(), isclass(), ismethod(), isfunction(), istraceback(), 9 ismodule(), isclass(), ismethod(), isfunction(), isgeneratorfunction(),
11 isframe(), iscode(), isbuiltin(), isroutine() - check object types 10 isgenerator(), istraceback(), isframe(), iscode(), isbuiltin(),
11 isroutine() - check object types
12 getmembers() - get members of an object that satisfy a given condition 12 getmembers() - get members of an object that satisfy a given condition
13 13
14 getfile(), getsourcefile(), getsource() - find an object's source code 14 getfile(), getsourcefile(), getsource() - find an object's source code
15 getdoc(), getcomments() - get documentation on an object 15 getdoc(), getcomments() - get documentation on an object
16 getmodule() - determine the module that an object came from 16 getmodule() - determine the module that an object came from
17 getclasstree() - arrange classes so as to represent their hierarchy 17 getclasstree() - arrange classes so as to represent their hierarchy
18 18
19 getargspec(), getargvalues() - get info about function arguments 19 getargspec(), getargvalues(), getcallargs() - get info about function argume nts
20 getfullargspec() - same, with support for Python-3000 features
20 formatargspec(), formatargvalues() - format an argument spec 21 formatargspec(), formatargvalues() - format an argument spec
21 getouterframes(), getinnerframes() - get info about frames 22 getouterframes(), getinnerframes() - get info about frames
22 currentframe() - get the current stack frame 23 currentframe() - get the current stack frame
23 stack(), trace() - get info about frames on the stack or in a traceback 24 stack(), trace() - get info about frames on the stack or in a traceback
25
26 signature() - get a Signature object for the callable
24 """ 27 """
25 28
26 # This module is in the public domain. No warranties. 29 # This module is in the public domain. No warranties.
27 30
28 __author__ = 'Ka-Ping Yee <ping@lfw.org>' 31 __author__ = ('Ka-Ping Yee <ping@lfw.org>',
29 __date__ = '1 Jan 2001' 32 'Yury Selivanov <yselivanov@sprymix.com>')
30 33
31 import sys, os, types, string, re, dis, imp, tokenize, linecache 34 import importlib.machinery
35 import itertools
36 import linecache
37 import os
38 import re
39 import sys
40 import tokenize
41 import types
42 import warnings
43 import functools
44 import builtins
32 from operator import attrgetter 45 from operator import attrgetter
33 from collections import namedtuple 46 from collections import namedtuple, OrderedDict
47
48 # Create constants for the compiler flags in Include/code.h
49 # We try to get them from dis to avoid duplication, but fall
50 # back to hardcoding so the dependency is optional
51 try:
52 from dis import COMPILER_FLAG_NAMES as _flag_names
53 except ImportError:
54 CO_OPTIMIZED, CO_NEWLOCALS = 0x1, 0x2
55 CO_VARARGS, CO_VARKEYWORDS = 0x4, 0x8
56 CO_NESTED, CO_GENERATOR, CO_NOFREE = 0x10, 0x20, 0x40
57 else:
58 mod_dict = globals()
59 for k, v in _flag_names.items():
60 mod_dict["CO_" + v] = k
61
62 # See Include/object.h
63 TPFLAGS_IS_ABSTRACT = 1 << 20
34 64
35 # ----------------------------------------------------------- type-checking 65 # ----------------------------------------------------------- type-checking
36 def ismodule(object): 66 def ismodule(object):
37 """Return true if the object is a module. 67 """Return true if the object is a module.
38 68
39 Module objects provide these attributes: 69 Module objects provide these attributes:
70 __cached__ pathname to byte compiled file
40 __doc__ documentation string 71 __doc__ documentation string
41 __file__ filename (missing for built-in modules)""" 72 __file__ filename (missing for built-in modules)"""
42 return isinstance(object, types.ModuleType) 73 return isinstance(object, types.ModuleType)
43 74
44 def isclass(object): 75 def isclass(object):
45 """Return true if the object is a class. 76 """Return true if the object is a class.
46 77
47 Class objects provide these attributes: 78 Class objects provide these attributes:
48 __doc__ documentation string 79 __doc__ documentation string
49 __module__ name of module in which this class was defined""" 80 __module__ name of module in which this class was defined"""
50 return isinstance(object, types.ClassType) or hasattr(object, '__bases__') 81 return isinstance(object, type)
51 82
52 def ismethod(object): 83 def ismethod(object):
53 """Return true if the object is an instance method. 84 """Return true if the object is an instance method.
54 85
55 Instance method objects provide these attributes: 86 Instance method objects provide these attributes:
56 __doc__ documentation string 87 __doc__ documentation string
57 __name__ name with which this method was defined 88 __name__ name with which this method was defined
58 im_class class object in which this method belongs 89 __func__ function object containing implementation of method
59 im_func function object containing implementation of method 90 __self__ instance to which this method is bound"""
60 im_self instance to which this method is bound, or None"""
61 return isinstance(object, types.MethodType) 91 return isinstance(object, types.MethodType)
62 92
63 def ismethoddescriptor(object): 93 def ismethoddescriptor(object):
64 """Return true if the object is a method descriptor. 94 """Return true if the object is a method descriptor.
65 95
66 But not if ismethod() or isclass() or isfunction() are true. 96 But not if ismethod() or isclass() or isfunction() are true.
67 97
68 This is new in Python 2.2, and, for example, is true of int.__add__. 98 This is new in Python 2.2, and, for example, is true of int.__add__.
69 An object passing this test has a __get__ attribute but not a __set__ 99 An object passing this test has a __get__ attribute but not a __set__
70 attribute, but beyond that the set of attributes varies. __name__ is 100 attribute, but beyond that the set of attributes varies. __name__ is
71 usually sensible, and __doc__ often is. 101 usually sensible, and __doc__ often is.
72 102
73 Methods implemented via descriptors that also pass one of the other 103 Methods implemented via descriptors that also pass one of the other
74 tests return false from the ismethoddescriptor() test, simply because 104 tests return false from the ismethoddescriptor() test, simply because
75 the other tests promise more -- you can, e.g., count on having the 105 the other tests promise more -- you can, e.g., count on having the
76 im_func attribute (etc) when an object passes ismethod().""" 106 __func__ attribute (etc) when an object passes ismethod()."""
77 return (hasattr(object, "__get__") 107 if isclass(object) or ismethod(object) or isfunction(object):
78 and not hasattr(object, "__set__") # else it's a data descriptor 108 # mutual exclusion
79 and not ismethod(object) # mutual exclusion 109 return False
80 and not isfunction(object) 110 tp = type(object)
81 and not isclass(object)) 111 return hasattr(tp, "__get__") and not hasattr(tp, "__set__")
82 112
83 def isdatadescriptor(object): 113 def isdatadescriptor(object):
84 """Return true if the object is a data descriptor. 114 """Return true if the object is a data descriptor.
85 115
86 Data descriptors have both a __get__ and a __set__ attribute. Examples are 116 Data descriptors have both a __get__ and a __set__ attribute. Examples are
87 properties (defined in Python) and getsets and members (defined in C). 117 properties (defined in Python) and getsets and members (defined in C).
88 Typically, data descriptors will also have __name__ and __doc__ attributes 118 Typically, data descriptors will also have __name__ and __doc__ attributes
89 (properties, getsets, and members have both of these attributes), but this 119 (properties, getsets, and members have both of these attributes), but this
90 is not guaranteed.""" 120 is not guaranteed."""
91 return (hasattr(object, "__set__") and hasattr(object, "__get__")) 121 if isclass(object) or ismethod(object) or isfunction(object):
122 # mutual exclusion
123 return False
124 tp = type(object)
125 return hasattr(tp, "__set__") and hasattr(tp, "__get__")
92 126
93 if hasattr(types, 'MemberDescriptorType'): 127 if hasattr(types, 'MemberDescriptorType'):
94 # CPython and equivalent 128 # CPython and equivalent
95 def ismemberdescriptor(object): 129 def ismemberdescriptor(object):
96 """Return true if the object is a member descriptor. 130 """Return true if the object is a member descriptor.
97 131
98 Member descriptors are specialized descriptors defined in extension 132 Member descriptors are specialized descriptors defined in extension
99 modules.""" 133 modules."""
100 return isinstance(object, types.MemberDescriptorType) 134 return isinstance(object, types.MemberDescriptorType)
101 else: 135 else:
(...skipping 21 matching lines...) Expand all
123 getset descriptors are specialized descriptors defined in extension 157 getset descriptors are specialized descriptors defined in extension
124 modules.""" 158 modules."""
125 return False 159 return False
126 160
127 def isfunction(object): 161 def isfunction(object):
128 """Return true if the object is a user-defined function. 162 """Return true if the object is a user-defined function.
129 163
130 Function objects provide these attributes: 164 Function objects provide these attributes:
131 __doc__ documentation string 165 __doc__ documentation string
132 __name__ name with which this function was defined 166 __name__ name with which this function was defined
133 func_code code object containing compiled function bytecode 167 __code__ code object containing compiled function bytecode
134 func_defaults tuple of any default values for arguments 168 __defaults__ tuple of any default values for arguments
135 func_doc (same as __doc__) 169 __globals__ global namespace in which this function was defined
136 func_globals global namespace in which this function was defined 170 __annotations__ dict of parameter annotations
137 func_name (same as __name__)""" 171 __kwdefaults__ dict of keyword only parameters with defaults"""
138 return isinstance(object, types.FunctionType) 172 return isinstance(object, types.FunctionType)
173
174 def isgeneratorfunction(object):
175 """Return true if the object is a user-defined generator function.
176
177 Generator function objects provides same attributes as functions.
178
179 See help(isfunction) for attributes listing."""
180 return bool((isfunction(object) or ismethod(object)) and
181 object.__code__.co_flags & CO_GENERATOR)
182
183 def isgenerator(object):
184 """Return true if the object is a generator.
185
186 Generator objects provide these attributes:
187 __iter__ defined to support iteration over container
188 close raises a new GeneratorExit exception inside the
189 generator to terminate the iteration
190 gi_code code object
191 gi_frame frame object or possibly None once the generator has
192 been exhausted
193 gi_running set to 1 when generator is executing, 0 otherwise
194 next return the next item from the container
195 send resumes the generator and "sends" a value that becomes
196 the result of the current yield-expression
197 throw used to raise an exception inside the generator"""
198 return isinstance(object, types.GeneratorType)
139 199
140 def istraceback(object): 200 def istraceback(object):
141 """Return true if the object is a traceback. 201 """Return true if the object is a traceback.
142 202
143 Traceback objects provide these attributes: 203 Traceback objects provide these attributes:
144 tb_frame frame object at this level 204 tb_frame frame object at this level
145 tb_lasti index of last attempted instruction in bytecode 205 tb_lasti index of last attempted instruction in bytecode
146 tb_lineno current line number in Python source code 206 tb_lineno current line number in Python source code
147 tb_next next inner traceback object (called by this level)""" 207 tb_next next inner traceback object (called by this level)"""
148 return isinstance(object, types.TracebackType) 208 return isinstance(object, types.TracebackType)
149 209
150 def isframe(object): 210 def isframe(object):
151 """Return true if the object is a frame object. 211 """Return true if the object is a frame object.
152 212
153 Frame objects provide these attributes: 213 Frame objects provide these attributes:
154 f_back next outer frame object (this frame's caller) 214 f_back next outer frame object (this frame's caller)
155 f_builtins built-in namespace seen by this frame 215 f_builtins built-in namespace seen by this frame
156 f_code code object being executed in this frame 216 f_code code object being executed in this frame
157 f_exc_traceback traceback if raised in this frame, or None
158 f_exc_type exception type if raised in this frame, or None
159 f_exc_value exception value if raised in this frame, or None
160 f_globals global namespace seen by this frame 217 f_globals global namespace seen by this frame
161 f_lasti index of last attempted instruction in bytecode 218 f_lasti index of last attempted instruction in bytecode
162 f_lineno current line number in Python source code 219 f_lineno current line number in Python source code
163 f_locals local namespace seen by this frame 220 f_locals local namespace seen by this frame
164 f_restricted 0 or 1 if frame is in restricted execution mode
165 f_trace tracing function for this frame, or None""" 221 f_trace tracing function for this frame, or None"""
166 return isinstance(object, types.FrameType) 222 return isinstance(object, types.FrameType)
167 223
168 def iscode(object): 224 def iscode(object):
169 """Return true if the object is a code object. 225 """Return true if the object is a code object.
170 226
171 Code objects provide these attributes: 227 Code objects provide these attributes:
172 co_argcount number of arguments (not including * or ** args) 228 co_argcount number of arguments (not including * or ** args)
173 co_code string of raw compiled bytecode 229 co_code string of raw compiled bytecode
174 co_consts tuple of constants used in the bytecode 230 co_consts tuple of constants used in the bytecode
(...skipping 17 matching lines...) Expand all
192 __self__ instance to which a method is bound, or None""" 248 __self__ instance to which a method is bound, or None"""
193 return isinstance(object, types.BuiltinFunctionType) 249 return isinstance(object, types.BuiltinFunctionType)
194 250
195 def isroutine(object): 251 def isroutine(object):
196 """Return true if the object is any kind of function or method.""" 252 """Return true if the object is any kind of function or method."""
197 return (isbuiltin(object) 253 return (isbuiltin(object)
198 or isfunction(object) 254 or isfunction(object)
199 or ismethod(object) 255 or ismethod(object)
200 or ismethoddescriptor(object)) 256 or ismethoddescriptor(object))
201 257
258 def isabstract(object):
259 """Return true if the object is an abstract base class (ABC)."""
260 return bool(isinstance(object, type) and object.__flags__ & TPFLAGS_IS_ABSTR ACT)
261
202 def getmembers(object, predicate=None): 262 def getmembers(object, predicate=None):
203 """Return all members of an object as (name, value) pairs sorted by name. 263 """Return all members of an object as (name, value) pairs sorted by name.
204 Optionally, only return members that satisfy a given predicate.""" 264 Optionally, only return members that satisfy a given predicate."""
265 if isclass(object):
266 mro = (object,) + getmro(object)
267 else:
268 mro = ()
205 results = [] 269 results = []
206 for key in dir(object): 270 processed = set()
207 value = getattr(object, key) 271 names = dir(object)
272 # add any virtual attributes to the list of names if object is a class
273 # this may result in duplicate entries if, for example, a virtual
274 # attribute with the same name as a member property exists
275 try:
276 for base in object.__bases__:
277 for k, v in base.__dict__.items():
278 if isinstance(v, types.DynamicClassAttribute):
279 names.append(k)
280 except AttributeError:
281 pass
282 for key in names:
283 # First try to get the value via __dict__. Some descriptors don't
284 # like calling their __get__ (see bug #1785).
285 for base in mro:
286 if key in base.__dict__ and key not in processed:
287 # handle the normal case first; if duplicate entries exist
288 # they will be handled second
289 value = base.__dict__[key]
290 break
291 else:
292 try:
293 value = getattr(object, key)
294 except AttributeError:
295 continue
208 if not predicate or predicate(value): 296 if not predicate or predicate(value):
209 results.append((key, value)) 297 results.append((key, value))
210 results.sort() 298 processed.add(key)
299 results.sort(key=lambda pair: pair[0])
211 return results 300 return results
212 301
213 Attribute = namedtuple('Attribute', 'name kind defining_class object') 302 Attribute = namedtuple('Attribute', 'name kind defining_class object')
214 303
215 def classify_class_attrs(cls): 304 def classify_class_attrs(cls):
216 """Return list of attribute-descriptor tuples. 305 """Return list of attribute-descriptor tuples.
217 306
218 For each name in dir(cls), the return list contains a 4-tuple 307 For each name in dir(cls), the return list contains a 4-tuple
219 with these elements: 308 with these elements:
220 309
221 0. The name (a string). 310 0. The name (a string).
222 311
223 1. The kind of attribute this is, one of these strings: 312 1. The kind of attribute this is, one of these strings:
224 'class method' created via classmethod() 313 'class method' created via classmethod()
225 'static method' created via staticmethod() 314 'static method' created via staticmethod()
226 'property' created via property() 315 'property' created via property()
227 'method' any other flavor of method 316 'method' any other flavor of method or descriptor
228 'data' not a method 317 'data' not a method
229 318
230 2. The class which defined this attribute (a class). 319 2. The class which defined this attribute (a class).
231 320
232 3. The object as obtained directly from the defining class's 321 3. The object as obtained by calling getattr; if this fails, or if the
233 __dict__, not via getattr. This is especially important for 322 resulting object does not live anywhere in the class' mro (including
234 data attributes: C.data is just a data object, but 323 metaclasses) then the object is looked up in the defining class's
235 C.__dict__['data'] may be a data descriptor with additional 324 dict (found by walking the mro).
236 info, like a __doc__ string. 325
326 If one of the items in dir(cls) is stored in the metaclass it will now
327 be discovered and not have None be listed as the class in which it was
328 defined.
237 """ 329 """
238 330
239 mro = getmro(cls) 331 mro = getmro(cls)
332 metamro = getmro(type(cls)) # for attributes stored in the metaclass
333 metamro = tuple([cls for cls in metamro if cls not in (type, object)])
334 possible_bases = (cls,) + mro + metamro
240 names = dir(cls) 335 names = dir(cls)
336 # add any virtual attributes to the list of names
337 # this may result in duplicate entries if, for example, a virtual
338 # attribute with the same name as a member property exists
339 for base in cls.__bases__:
340 for k, v in base.__dict__.items():
341 if isinstance(v, types.DynamicClassAttribute):
342 names.append(k)
241 result = [] 343 result = []
344 processed = set()
345 sentinel = object()
242 for name in names: 346 for name in names:
243 # Get the object associated with the name. 347 # Get the object associated with the name, and where it was defined.
348 # Normal objects will be looked up with both getattr and directly in
349 # its class' dict (in case getattr fails [bug #1785], and also to look
350 # for a docstring).
351 # For VirtualAttributes on the second pass we only look in the
352 # class's dict.
353 #
244 # Getting an obj from the __dict__ sometimes reveals more than 354 # Getting an obj from the __dict__ sometimes reveals more than
245 # using getattr. Static and class methods are dramatic examples. 355 # using getattr. Static and class methods are dramatic examples.
246 if name in cls.__dict__: 356 homecls = None
247 obj = cls.__dict__[name] 357 get_obj = sentinel
358 dict_obj = sentinel
359
360
361 if name not in processed:
362 try:
363 get_obj = getattr(cls, name)
364 except Exception as exc:
365 pass
366 else:
367 homecls = getattr(get_obj, "__class__")
368 homecls = getattr(get_obj, "__objclass__", homecls)
369 if homecls not in possible_bases:
370 # if the resulting object does not live somewhere in the
371 # mro, drop it and go with the dict_obj version only
372 homecls = None
373 get_obj = sentinel
374
375 for base in possible_bases:
376 if name in base.__dict__:
377 dict_obj = base.__dict__[name]
378 homecls = homecls or base
379 break
380
381 # Classify the object or its descriptor.
382 if get_obj is not sentinel:
383 obj = get_obj
248 else: 384 else:
249 obj = getattr(cls, name) 385 obj = dict_obj
250
251 # Figure out where it was defined.
252 homecls = getattr(obj, "__objclass__", None)
253 if homecls is None:
254 # search the dicts.
255 for base in mro:
256 if name in base.__dict__:
257 homecls = base
258 break
259
260 # Get the object again, in order to get it from the defining
261 # __dict__ instead of via getattr (if possible).
262 if homecls is not None and name in homecls.__dict__:
263 obj = homecls.__dict__[name]
264
265 # Also get the object via getattr.
266 obj_via_getattr = getattr(cls, name)
267
268 # Classify the object.
269 if isinstance(obj, staticmethod): 386 if isinstance(obj, staticmethod):
270 kind = "static method" 387 kind = "static method"
271 elif isinstance(obj, classmethod): 388 elif isinstance(obj, classmethod):
272 kind = "class method" 389 kind = "class method"
273 elif isinstance(obj, property): 390 elif isinstance(obj, property):
274 kind = "property" 391 kind = "property"
275 elif (ismethod(obj_via_getattr) or 392 elif isfunction(obj) or ismethoddescriptor(obj):
276 ismethoddescriptor(obj_via_getattr)):
277 kind = "method" 393 kind = "method"
278 else: 394 else:
279 kind = "data" 395 kind = "data"
280 396
281 result.append(Attribute(name, kind, homecls, obj)) 397 result.append(Attribute(name, kind, homecls, obj))
398 processed.add(name)
282 399
283 return result 400 return result
284 401
285 # ----------------------------------------------------------- class helpers 402 # ----------------------------------------------------------- class helpers
286 def _searchbases(cls, accum):
287 # Simulate the "classic class" search order.
288 if cls in accum:
289 return
290 accum.append(cls)
291 for base in cls.__bases__:
292 _searchbases(base, accum)
293 403
294 def getmro(cls): 404 def getmro(cls):
295 "Return tuple of base classes (including cls) in method resolution order." 405 "Return tuple of base classes (including cls) in method resolution order."
296 if hasattr(cls, "__mro__"): 406 return cls.__mro__
297 return cls.__mro__ 407
408 # -------------------------------------------------------- function helpers
409
410 def unwrap(func, *, stop=None):
411 """Get the object wrapped by *func*.
412
413 Follows the chain of :attr:`__wrapped__` attributes returning the last
414 object in the chain.
415
416 *stop* is an optional callback accepting an object in the wrapper chain
417 as its sole argument that allows the unwrapping to be terminated early if
418 the callback returns a true value. If the callback never returns a true
419 value, the last object in the chain is returned as usual. For example,
420 :func:`signature` uses this to stop unwrapping if any object in the
421 chain has a ``__signature__`` attribute defined.
422
423 :exc:`ValueError` is raised if a cycle is encountered.
424
425 """
426 if stop is None:
427 def _is_wrapper(f):
428 return hasattr(f, '__wrapped__')
298 else: 429 else:
299 result = [] 430 def _is_wrapper(f):
300 _searchbases(cls, result) 431 return hasattr(f, '__wrapped__') and not stop(f)
301 return tuple(result) 432 f = func # remember the original func for error reporting
433 memo = {id(f)} # Memoise by id to tolerate non-hashable objects
434 while _is_wrapper(func):
435 func = func.__wrapped__
436 id_func = id(func)
437 if id_func in memo:
438 raise ValueError('wrapper loop when unwrapping {!r}'.format(f))
439 memo.add(id_func)
440 return func
302 441
303 # -------------------------------------------------- source code extraction 442 # -------------------------------------------------- source code extraction
304 def indentsize(line): 443 def indentsize(line):
305 """Return the indent size, in spaces, at the start of a line of text.""" 444 """Return the indent size, in spaces, at the start of a line of text."""
306 expline = string.expandtabs(line) 445 expline = line.expandtabs()
307 return len(expline) - len(string.lstrip(expline)) 446 return len(expline) - len(expline.lstrip())
308 447
309 def getdoc(object): 448 def getdoc(object):
310 """Get the documentation string for an object. 449 """Get the documentation string for an object.
311 450
312 All tabs are expanded to spaces. To clean up docstrings that are 451 All tabs are expanded to spaces. To clean up docstrings that are
313 indented to line up with blocks of code, any whitespace than can be 452 indented to line up with blocks of code, any whitespace than can be
314 uniformly removed from the second line onwards is removed.""" 453 uniformly removed from the second line onwards is removed."""
315 try: 454 try:
316 doc = object.__doc__ 455 doc = object.__doc__
317 except AttributeError: 456 except AttributeError:
318 return None 457 return None
319 if not isinstance(doc, types.StringTypes): 458 if not isinstance(doc, str):
320 return None 459 return None
460 return cleandoc(doc)
461
462 def cleandoc(doc):
463 """Clean up indentation from docstrings.
464
465 Any whitespace that can be uniformly removed from the second line
466 onwards is removed."""
321 try: 467 try:
322 lines = string.split(string.expandtabs(doc), '\n') 468 lines = doc.expandtabs().split('\n')
323 except UnicodeError: 469 except UnicodeError:
324 return None 470 return None
325 else: 471 else:
326 # Find minimum indentation of any non-blank lines after first line. 472 # Find minimum indentation of any non-blank lines after first line.
327 margin = sys.maxint 473 margin = sys.maxsize
328 for line in lines[1:]: 474 for line in lines[1:]:
329 content = len(string.lstrip(line)) 475 content = len(line.lstrip())
330 if content: 476 if content:
331 indent = len(line) - content 477 indent = len(line) - content
332 margin = min(margin, indent) 478 margin = min(margin, indent)
333 # Remove indentation. 479 # Remove indentation.
334 if lines: 480 if lines:
335 lines[0] = lines[0].lstrip() 481 lines[0] = lines[0].lstrip()
336 if margin < sys.maxint: 482 if margin < sys.maxsize:
337 for i in range(1, len(lines)): lines[i] = lines[i][margin:] 483 for i in range(1, len(lines)): lines[i] = lines[i][margin:]
338 # Remove any trailing or leading blank lines. 484 # Remove any trailing or leading blank lines.
339 while lines and not lines[-1]: 485 while lines and not lines[-1]:
340 lines.pop() 486 lines.pop()
341 while lines and not lines[0]: 487 while lines and not lines[0]:
342 lines.pop(0) 488 lines.pop(0)
343 return string.join(lines, '\n') 489 return '\n'.join(lines)
344 490
345 def getfile(object): 491 def getfile(object):
346 """Work out which source or compiled file an object was defined in.""" 492 """Work out which source or compiled file an object was defined in."""
347 if ismodule(object): 493 if ismodule(object):
348 if hasattr(object, '__file__'): 494 if hasattr(object, '__file__'):
349 return object.__file__ 495 return object.__file__
350 raise TypeError('arg is a built-in module') 496 raise TypeError('{!r} is a built-in module'.format(object))
351 if isclass(object): 497 if isclass(object):
352 object = sys.modules.get(object.__module__) 498 object = sys.modules.get(object.__module__)
353 if hasattr(object, '__file__'): 499 if hasattr(object, '__file__'):
354 return object.__file__ 500 return object.__file__
355 raise TypeError('arg is a built-in class') 501 raise TypeError('{!r} is a built-in class'.format(object))
356 if ismethod(object): 502 if ismethod(object):
357 object = object.im_func 503 object = object.__func__
358 if isfunction(object): 504 if isfunction(object):
359 object = object.func_code 505 object = object.__code__
360 if istraceback(object): 506 if istraceback(object):
361 object = object.tb_frame 507 object = object.tb_frame
362 if isframe(object): 508 if isframe(object):
363 object = object.f_code 509 object = object.f_code
364 if iscode(object): 510 if iscode(object):
365 return object.co_filename 511 return object.co_filename
366 raise TypeError('arg is not a module, class, method, ' 512 raise TypeError('{!r} is not a module, class, method, '
367 'function, traceback, frame, or code object') 513 'function, traceback, frame, or code object'.format(object))
368 514
369 ModuleInfo = namedtuple('ModuleInfo', 'name suffix mode module_type') 515 ModuleInfo = namedtuple('ModuleInfo', 'name suffix mode module_type')
370 516
371 def getmoduleinfo(path): 517 def getmoduleinfo(path):
372 """Get the module name, suffix, mode, and module type for a given file.""" 518 """Get the module name, suffix, mode, and module type for a given file."""
519 warnings.warn('inspect.getmoduleinfo() is deprecated', DeprecationWarning,
520 2)
521 with warnings.catch_warnings():
522 warnings.simplefilter('ignore', PendingDeprecationWarning)
523 import imp
373 filename = os.path.basename(path) 524 filename = os.path.basename(path)
374 suffixes = map(lambda (suffix, mode, mtype): 525 suffixes = [(-len(suffix), suffix, mode, mtype)
375 (-len(suffix), suffix, mode, mtype), imp.get_suffixes()) 526 for suffix, mode, mtype in imp.get_suffixes()]
376 suffixes.sort() # try longest suffixes first, in case they overlap 527 suffixes.sort() # try longest suffixes first, in case they overlap
377 for neglen, suffix, mode, mtype in suffixes: 528 for neglen, suffix, mode, mtype in suffixes:
378 if filename[neglen:] == suffix: 529 if filename[neglen:] == suffix:
379 return ModuleInfo(filename[:neglen], suffix, mode, mtype) 530 return ModuleInfo(filename[:neglen], suffix, mode, mtype)
380 531
381 def getmodulename(path): 532 def getmodulename(path):
382 """Return the module name for a given file, or None.""" 533 """Return the module name for a given file, or None."""
383 info = getmoduleinfo(path) 534 fname = os.path.basename(path)
384 if info: return info[0] 535 # Check for paths that look like an actual module file
536 suffixes = [(-len(suffix), suffix)
537 for suffix in importlib.machinery.all_suffixes()]
538 suffixes.sort() # try longest suffixes first, in case they overlap
539 for neglen, suffix in suffixes:
540 if fname.endswith(suffix):
541 return fname[:neglen]
542 return None
385 543
386 def getsourcefile(object): 544 def getsourcefile(object):
387 """Return the Python source file an object was defined in, if it exists.""" 545 """Return the filename that can be used to locate an object's source.
546 Return None if no way can be identified to get the source.
547 """
388 filename = getfile(object) 548 filename = getfile(object)
389 if string.lower(filename[-4:]) in ('.pyc', '.pyo'): 549 all_bytecode_suffixes = importlib.machinery.DEBUG_BYTECODE_SUFFIXES[:]
390 filename = filename[:-4] + '.py' 550 all_bytecode_suffixes += importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES[:]
391 for suffix, mode, kind in imp.get_suffixes(): 551 if any(filename.endswith(s) for s in all_bytecode_suffixes):
392 if 'b' in mode and string.lower(filename[-len(suffix):]) == suffix: 552 filename = (os.path.splitext(filename)[0] +
393 # Looks like a binary file. We want to only return a text file. 553 importlib.machinery.SOURCE_SUFFIXES[0])
394 return None 554 elif any(filename.endswith(s) for s in
555 importlib.machinery.EXTENSION_SUFFIXES):
556 return None
395 if os.path.exists(filename): 557 if os.path.exists(filename):
396 return filename 558 return filename
397 # only return a non-existent filename if the module has a PEP 302 loader 559 # only return a non-existent filename if the module has a PEP 302 loader
398 if hasattr(getmodule(object, filename), '__loader__'): 560 if getattr(getmodule(object, filename), '__loader__', None) is not None:
561 return filename
562 # or it is in the linecache
563 if filename in linecache.cache:
399 return filename 564 return filename
400 565
401 def getabsfile(object, _filename=None): 566 def getabsfile(object, _filename=None):
402 """Return an absolute path to the source or compiled file for an object. 567 """Return an absolute path to the source or compiled file for an object.
403 568
404 The idea is for each object to have a unique origin, so this routine 569 The idea is for each object to have a unique origin, so this routine
405 normalizes the result as much as possible.""" 570 normalizes the result as much as possible."""
406 if _filename is None: 571 if _filename is None:
407 _filename = getsourcefile(object) or getfile(object) 572 _filename = getsourcefile(object) or getfile(object)
408 return os.path.normcase(os.path.abspath(_filename)) 573 return os.path.normcase(os.path.abspath(_filename))
(...skipping 12 matching lines...) Expand all
421 return sys.modules.get(modulesbyfile[_filename]) 586 return sys.modules.get(modulesbyfile[_filename])
422 # Try the cache again with the absolute file name 587 # Try the cache again with the absolute file name
423 try: 588 try:
424 file = getabsfile(object, _filename) 589 file = getabsfile(object, _filename)
425 except TypeError: 590 except TypeError:
426 return None 591 return None
427 if file in modulesbyfile: 592 if file in modulesbyfile:
428 return sys.modules.get(modulesbyfile[file]) 593 return sys.modules.get(modulesbyfile[file])
429 # Update the filename to module name cache and check yet again 594 # Update the filename to module name cache and check yet again
430 # Copy sys.modules in order to cope with changes while iterating 595 # Copy sys.modules in order to cope with changes while iterating
431 for modname, module in sys.modules.items(): 596 for modname, module in list(sys.modules.items()):
432 if ismodule(module) and hasattr(module, '__file__'): 597 if ismodule(module) and hasattr(module, '__file__'):
433 f = module.__file__ 598 f = module.__file__
434 if f == _filesbymodname.get(modname, None): 599 if f == _filesbymodname.get(modname, None):
435 # Have already mapped this module, so skip it 600 # Have already mapped this module, so skip it
436 continue 601 continue
437 _filesbymodname[modname] = f 602 _filesbymodname[modname] = f
438 f = getabsfile(module) 603 f = getabsfile(module)
439 # Always map to the name the module knows itself by 604 # Always map to the name the module knows itself by
440 modulesbyfile[f] = modulesbyfile[ 605 modulesbyfile[f] = modulesbyfile[
441 os.path.realpath(f)] = module.__name__ 606 os.path.realpath(f)] = module.__name__
442 if file in modulesbyfile: 607 if file in modulesbyfile:
443 return sys.modules.get(modulesbyfile[file]) 608 return sys.modules.get(modulesbyfile[file])
444 # Check the main module 609 # Check the main module
445 main = sys.modules['__main__'] 610 main = sys.modules['__main__']
446 if not hasattr(object, '__name__'): 611 if not hasattr(object, '__name__'):
447 return None 612 return None
448 if hasattr(main, object.__name__): 613 if hasattr(main, object.__name__):
449 mainobject = getattr(main, object.__name__) 614 mainobject = getattr(main, object.__name__)
450 if mainobject is object: 615 if mainobject is object:
451 return main 616 return main
452 # Check builtins 617 # Check builtins
453 builtin = sys.modules['__builtin__'] 618 builtin = sys.modules['builtins']
454 if hasattr(builtin, object.__name__): 619 if hasattr(builtin, object.__name__):
455 builtinobject = getattr(builtin, object.__name__) 620 builtinobject = getattr(builtin, object.__name__)
456 if builtinobject is object: 621 if builtinobject is object:
457 return builtin 622 return builtin
458 623
459 def findsource(object): 624 def findsource(object):
460 """Return the entire source file and starting line number for an object. 625 """Return the entire source file and starting line number for an object.
461 626
462 The argument may be a module, class, method, function, traceback, frame, 627 The argument may be a module, class, method, function, traceback, frame,
463 or code object. The source code is returned as a list of all the lines 628 or code object. The source code is returned as a list of all the lines
464 in the file and the line number indexes a line in that list. An IOError 629 in the file and the line number indexes a line in that list. An OSError
465 is raised if the source code cannot be retrieved.""" 630 is raised if the source code cannot be retrieved."""
466 file = getsourcefile(object) or getfile(object) 631
632 file = getfile(object)
633 sourcefile = getsourcefile(object)
634 if not sourcefile and file[:1] + file[-1:] != '<>':
635 raise OSError('source code not available')
636 file = sourcefile if sourcefile else file
637
467 module = getmodule(object, file) 638 module = getmodule(object, file)
468 if module: 639 if module:
469 lines = linecache.getlines(file, module.__dict__) 640 lines = linecache.getlines(file, module.__dict__)
470 else: 641 else:
471 lines = linecache.getlines(file) 642 lines = linecache.getlines(file)
472 if not lines: 643 if not lines:
473 raise IOError('could not get source code') 644 raise OSError('could not get source code')
474 645
475 if ismodule(object): 646 if ismodule(object):
476 return lines, 0 647 return lines, 0
477 648
478 if isclass(object): 649 if isclass(object):
479 name = object.__name__ 650 name = object.__name__
480 pat = re.compile(r'^(\s*)class\s*' + name + r'\b') 651 pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
481 # make some effort to find the best matching class definition: 652 # make some effort to find the best matching class definition:
482 # use the one with the least indentation, which is the one 653 # use the one with the least indentation, which is the one
483 # that's most probably not inside a function definition. 654 # that's most probably not inside a function definition.
484 candidates = [] 655 candidates = []
485 for i in range(len(lines)): 656 for i in range(len(lines)):
486 match = pat.match(lines[i]) 657 match = pat.match(lines[i])
487 if match: 658 if match:
488 # if it's at toplevel, it's already the best one 659 # if it's at toplevel, it's already the best one
489 if lines[i][0] == 'c': 660 if lines[i][0] == 'c':
490 return lines, i 661 return lines, i
491 # else add whitespace to candidate list 662 # else add whitespace to candidate list
492 candidates.append((match.group(1), i)) 663 candidates.append((match.group(1), i))
493 if candidates: 664 if candidates:
494 # this will sort by whitespace, and by line number, 665 # this will sort by whitespace, and by line number,
495 # less whitespace first 666 # less whitespace first
496 candidates.sort() 667 candidates.sort()
497 return lines, candidates[0][1] 668 return lines, candidates[0][1]
498 else: 669 else:
499 raise IOError('could not find class definition') 670 raise OSError('could not find class definition')
500 671
501 if hasattr(object, 'func_closure') and object.func_closure:
502 object = object.func_closure[0].cell_contents
503 if ismethod(object): 672 if ismethod(object):
504 object = object.im_func 673 object = object.__func__
505 if isfunction(object): 674 if isfunction(object):
506 object = object.func_code 675 object = object.__code__
507 if istraceback(object): 676 if istraceback(object):
508 object = object.tb_frame 677 object = object.tb_frame
509 if isframe(object): 678 if isframe(object):
510 object = object.f_code 679 object = object.f_code
511 if iscode(object): 680 if iscode(object):
512 if not hasattr(object, 'co_firstlineno'): 681 if not hasattr(object, 'co_firstlineno'):
513 raise IOError('could not find function definition') 682 raise OSError('could not find function definition')
514 lnum = object.co_firstlineno - 1 683 lnum = object.co_firstlineno - 1
515 pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)') 684 pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
516 while lnum > 0: 685 while lnum > 0:
517 if pat.match(lines[lnum]): 686 if pat.match(lines[lnum]): break
518 break
519 lnum = lnum - 1 687 lnum = lnum - 1
520 return lines, lnum 688 return lines, lnum
521 raise IOError('could not find code object') 689 raise OSError('could not find code object')
522 690
523 def getcomments(object): 691 def getcomments(object):
524 """Get lines of comments immediately preceding an object's source code. 692 """Get lines of comments immediately preceding an object's source code.
525 693
526 Returns None when source can't be found. 694 Returns None when source can't be found.
527 """ 695 """
528 try: 696 try:
529 lines, lnum = findsource(object) 697 lines, lnum = findsource(object)
530 except (IOError, TypeError): 698 except (OSError, TypeError):
531 return None 699 return None
532 700
533 if ismodule(object): 701 if ismodule(object):
534 # Look for a comment block at the top of the file. 702 # Look for a comment block at the top of the file.
535 start = 0 703 start = 0
536 if lines and lines[0][:2] == '#!': start = 1 704 if lines and lines[0][:2] == '#!': start = 1
537 while start < len(lines) and string.strip(lines[start]) in ('', '#'): 705 while start < len(lines) and lines[start].strip() in ('', '#'):
538 start = start + 1 706 start = start + 1
539 if start < len(lines) and lines[start][:1] == '#': 707 if start < len(lines) and lines[start][:1] == '#':
540 comments = [] 708 comments = []
541 end = start 709 end = start
542 while end < len(lines) and lines[end][:1] == '#': 710 while end < len(lines) and lines[end][:1] == '#':
543 comments.append(string.expandtabs(lines[end])) 711 comments.append(lines[end].expandtabs())
544 end = end + 1 712 end = end + 1
545 return string.join(comments, '') 713 return ''.join(comments)
546 714
547 # Look for a preceding block of comments at the same indentation. 715 # Look for a preceding block of comments at the same indentation.
548 elif lnum > 0: 716 elif lnum > 0:
549 indent = indentsize(lines[lnum]) 717 indent = indentsize(lines[lnum])
550 end = lnum - 1 718 end = lnum - 1
551 if end >= 0 and string.lstrip(lines[end])[:1] == '#' and \ 719 if end >= 0 and lines[end].lstrip()[:1] == '#' and \
552 indentsize(lines[end]) == indent: 720 indentsize(lines[end]) == indent:
553 comments = [string.lstrip(string.expandtabs(lines[end]))] 721 comments = [lines[end].expandtabs().lstrip()]
554 if end > 0: 722 if end > 0:
555 end = end - 1 723 end = end - 1
556 comment = string.lstrip(string.expandtabs(lines[end])) 724 comment = lines[end].expandtabs().lstrip()
557 while comment[:1] == '#' and indentsize(lines[end]) == indent: 725 while comment[:1] == '#' and indentsize(lines[end]) == indent:
558 comments[:0] = [comment] 726 comments[:0] = [comment]
559 end = end - 1 727 end = end - 1
560 if end < 0: break 728 if end < 0: break
561 comment = string.lstrip(string.expandtabs(lines[end])) 729 comment = lines[end].expandtabs().lstrip()
562 while comments and string.strip(comments[0]) == '#': 730 while comments and comments[0].strip() == '#':
563 comments[:1] = [] 731 comments[:1] = []
564 while comments and string.strip(comments[-1]) == '#': 732 while comments and comments[-1].strip() == '#':
565 comments[-1:] = [] 733 comments[-1:] = []
566 return string.join(comments, '') 734 return ''.join(comments)
567 735
568 class EndOfBlock(Exception): pass 736 class EndOfBlock(Exception): pass
569 737
570 class BlockFinder: 738 class BlockFinder:
571 """Provide a tokeneater() method to detect the end of a code block.""" 739 """Provide a tokeneater() method to detect the end of a code block."""
572 def __init__(self): 740 def __init__(self):
573 self.indent = 0 741 self.indent = 0
574 self.islambda = False 742 self.islambda = False
575 self.started = False 743 self.started = False
576 self.passline = False 744 self.passline = False
577 self.last = 1 745 self.last = 1
578 746
579 def tokeneater(self, type, token, (srow, scol), (erow, ecol), line): 747 def tokeneater(self, type, token, srowcol, erowcol, line):
580 if not self.started: 748 if not self.started:
581 # look for the first "def", "class" or "lambda" 749 # look for the first "def", "class" or "lambda"
582 if token in ("def", "class", "lambda"): 750 if token in ("def", "class", "lambda"):
583 if token == "lambda": 751 if token == "lambda":
584 self.islambda = True 752 self.islambda = True
585 self.started = True 753 self.started = True
586 self.passline = True # skip to the end of the line 754 self.passline = True # skip to the end of the line
587 elif type == tokenize.NEWLINE: 755 elif type == tokenize.NEWLINE:
588 self.passline = False # stop skipping when a NEWLINE is seen 756 self.passline = False # stop skipping when a NEWLINE is seen
589 self.last = srow 757 self.last = srowcol[0]
590 if self.islambda: # lambdas always end at the first NEWLINE 758 if self.islambda: # lambdas always end at the first NEWLINE
591 raise EndOfBlock 759 raise EndOfBlock
592 elif self.passline: 760 elif self.passline:
593 pass 761 pass
594 elif type == tokenize.INDENT: 762 elif type == tokenize.INDENT:
595 self.indent = self.indent + 1 763 self.indent = self.indent + 1
596 self.passline = True 764 self.passline = True
597 elif type == tokenize.DEDENT: 765 elif type == tokenize.DEDENT:
598 self.indent = self.indent - 1 766 self.indent = self.indent - 1
599 # the end of matching indent/dedent pairs end a block 767 # the end of matching indent/dedent pairs end a block
600 # (note that this only works for "def"/"class" blocks, 768 # (note that this only works for "def"/"class" blocks,
601 # not e.g. for "if: else:" or "try: finally:" blocks) 769 # not e.g. for "if: else:" or "try: finally:" blocks)
602 if self.indent <= 0: 770 if self.indent <= 0:
603 raise EndOfBlock 771 raise EndOfBlock
604 elif self.indent == 0 and type not in (tokenize.COMMENT, tokenize.NL): 772 elif self.indent == 0 and type not in (tokenize.COMMENT, tokenize.NL):
605 # any other token on the same indentation level end the previous 773 # any other token on the same indentation level end the previous
606 # block as well, except the pseudo-tokens COMMENT and NL. 774 # block as well, except the pseudo-tokens COMMENT and NL.
607 raise EndOfBlock 775 raise EndOfBlock
608 776
609 def getblock(lines): 777 def getblock(lines):
610 """Extract the block of code at the top of the given list of lines.""" 778 """Extract the block of code at the top of the given list of lines."""
611 blockfinder = BlockFinder() 779 blockfinder = BlockFinder()
612 try: 780 try:
613 tokenize.tokenize(iter(lines).next, blockfinder.tokeneater) 781 tokens = tokenize.generate_tokens(iter(lines).__next__)
782 for _token in tokens:
783 blockfinder.tokeneater(*_token)
614 except (EndOfBlock, IndentationError): 784 except (EndOfBlock, IndentationError):
615 pass 785 pass
616 return lines[:blockfinder.last] 786 return lines[:blockfinder.last]
617 787
618 def getsourcelines(object): 788 def getsourcelines(object):
619 """Return a list of source lines and starting line number for an object. 789 """Return a list of source lines and starting line number for an object.
620 790
621 The argument may be a module, class, method, function, traceback, frame, 791 The argument may be a module, class, method, function, traceback, frame,
622 or code object. The source code is returned as a list of the lines 792 or code object. The source code is returned as a list of the lines
623 corresponding to the object and the line number indicates where in the 793 corresponding to the object and the line number indicates where in the
624 original source file the first line of code was found. An IOError is 794 original source file the first line of code was found. An OSError is
625 raised if the source code cannot be retrieved.""" 795 raised if the source code cannot be retrieved."""
796 object = unwrap(object)
626 lines, lnum = findsource(object) 797 lines, lnum = findsource(object)
627 798
628 if ismodule(object): return lines, 0 799 if ismodule(object): return lines, 0
629 else: return getblock(lines[lnum:]), lnum + 1 800 else: return getblock(lines[lnum:]), lnum + 1
630 801
631 def getsource(object): 802 def getsource(object):
632 """Return the text of the source code for an object. 803 """Return the text of the source code for an object.
633 804
634 The argument may be a module, class, method, function, traceback, frame, 805 The argument may be a module, class, method, function, traceback, frame,
635 or code object. The source code is returned as a single string. An 806 or code object. The source code is returned as a single string. An
636 IOError is raised if the source code cannot be retrieved.""" 807 OSError is raised if the source code cannot be retrieved."""
637 lines, lnum = getsourcelines(object) 808 lines, lnum = getsourcelines(object)
638 return string.join(lines, '') 809 return ''.join(lines)
639 810
640 # --------------------------------------------------- class tree extraction 811 # --------------------------------------------------- class tree extraction
641 def walktree(classes, children, parent): 812 def walktree(classes, children, parent):
642 """Recursive helper function for getclasstree().""" 813 """Recursive helper function for getclasstree()."""
643 results = [] 814 results = []
644 classes.sort(key=attrgetter('__module__', '__name__')) 815 classes.sort(key=attrgetter('__module__', '__name__'))
645 for c in classes: 816 for c in classes:
646 results.append((c, c.__bases__)) 817 results.append((c, c.__bases__))
647 if c in children: 818 if c in children:
648 results.append(walktree(children[c], children, c)) 819 results.append(walktree(children[c], children, c))
649 return results 820 return results
650 821
651 def getclasstree(classes, unique=0): 822 def getclasstree(classes, unique=False):
652 """Arrange the given list of classes into a hierarchy of nested lists. 823 """Arrange the given list of classes into a hierarchy of nested lists.
653 824
654 Where a nested list appears, it contains classes derived from the class 825 Where a nested list appears, it contains classes derived from the class
655 whose entry immediately precedes the list. Each entry is a 2-tuple 826 whose entry immediately precedes the list. Each entry is a 2-tuple
656 containing a class and a tuple of its base classes. If the 'unique' 827 containing a class and a tuple of its base classes. If the 'unique'
657 argument is true, exactly one entry appears in the returned structure 828 argument is true, exactly one entry appears in the returned structure
658 for each class in the given list. Otherwise, classes using multiple 829 for each class in the given list. Otherwise, classes using multiple
659 inheritance and their descendants will appear multiple times.""" 830 inheritance and their descendants will appear multiple times."""
660 children = {} 831 children = {}
661 roots = [] 832 roots = []
662 for c in classes: 833 for c in classes:
663 if c.__bases__: 834 if c.__bases__:
664 for parent in c.__bases__: 835 for parent in c.__bases__:
665 if not parent in children: 836 if not parent in children:
666 children[parent] = [] 837 children[parent] = []
667 children[parent].append(c) 838 if c not in children[parent]:
839 children[parent].append(c)
668 if unique and parent in classes: break 840 if unique and parent in classes: break
669 elif c not in roots: 841 elif c not in roots:
670 roots.append(c) 842 roots.append(c)
671 for parent in children: 843 for parent in children:
672 if parent not in classes: 844 if parent not in classes:
673 roots.append(parent) 845 roots.append(parent)
674 return walktree(roots, children, None) 846 return walktree(roots, children, None)
675 847
676 # ------------------------------------------------ argument list extraction 848 # ------------------------------------------------ argument list extraction
677 # These constants are from Python's compile.h. 849 Arguments = namedtuple('Arguments', 'args, varargs, varkw')
678 CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 1, 2, 4, 8
679
680 Arguments = namedtuple('Arguments', 'args varargs keywords')
681 850
682 def getargs(co): 851 def getargs(co):
683 """Get information about the arguments accepted by a code object. 852 """Get information about the arguments accepted by a code object.
684 853
685 Three things are returned: (args, varargs, varkw), where 'args' is 854 Three things are returned: (args, varargs, varkw), where
686 a list of argument names (possibly containing nested lists), and 855 'args' is the list of argument names. Keyword-only arguments are
687 'varargs' and 'varkw' are the names of the * and ** arguments or None.""" 856 appended. 'varargs' and 'varkw' are the names of the * and **
857 arguments or None."""
858 args, varargs, kwonlyargs, varkw = _getfullargs(co)
859 return Arguments(args + kwonlyargs, varargs, varkw)
860
861 def _getfullargs(co):
862 """Get information about the arguments accepted by a code object.
863
864 Four things are returned: (args, varargs, kwonlyargs, varkw), where
865 'args' and 'kwonlyargs' are lists of argument names, and 'varargs'
866 and 'varkw' are the names of the * and ** arguments or None."""
688 867
689 if not iscode(co): 868 if not iscode(co):
690 raise TypeError('arg is not a code object') 869 raise TypeError('{!r} is not a code object'.format(co))
691 870
692 nargs = co.co_argcount 871 nargs = co.co_argcount
693 names = co.co_varnames 872 names = co.co_varnames
873 nkwargs = co.co_kwonlyargcount
694 args = list(names[:nargs]) 874 args = list(names[:nargs])
875 kwonlyargs = list(names[nargs:nargs+nkwargs])
695 step = 0 876 step = 0
696 877
697 # The following acrobatics are for anonymous (tuple) arguments. 878 nargs += nkwargs
698 for i in range(nargs):
699 if args[i][:1] in ('', '.'):
700 stack, remain, count = [], [], []
701 while step < len(co.co_code):
702 op = ord(co.co_code[step])
703 step = step + 1
704 if op >= dis.HAVE_ARGUMENT:
705 opname = dis.opname[op]
706 value = ord(co.co_code[step]) + ord(co.co_code[step+1])*256
707 step = step + 2
708 if opname in ('UNPACK_TUPLE', 'UNPACK_SEQUENCE'):
709 remain.append(value)
710 count.append(value)
711 elif opname == 'STORE_FAST':
712 stack.append(names[value])
713
714 # Special case for sublists of length 1: def foo((bar))
715 # doesn't generate the UNPACK_TUPLE bytecode, so if
716 # `remain` is empty here, we have such a sublist.
717 if not remain:
718 stack[0] = [stack[0]]
719 break
720 else:
721 remain[-1] = remain[-1] - 1
722 while remain[-1] == 0:
723 remain.pop()
724 size = count.pop()
725 stack[-size:] = [stack[-size:]]
726 if not remain: break
727 remain[-1] = remain[-1] - 1
728 if not remain: break
729 args[i] = stack[0]
730
731 varargs = None 879 varargs = None
732 if co.co_flags & CO_VARARGS: 880 if co.co_flags & CO_VARARGS:
733 varargs = co.co_varnames[nargs] 881 varargs = co.co_varnames[nargs]
734 nargs = nargs + 1 882 nargs = nargs + 1
735 varkw = None 883 varkw = None
736 if co.co_flags & CO_VARKEYWORDS: 884 if co.co_flags & CO_VARKEYWORDS:
737 varkw = co.co_varnames[nargs] 885 varkw = co.co_varnames[nargs]
738 return Arguments(args, varargs, varkw) 886 return args, varargs, kwonlyargs, varkw
887
739 888
740 ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults') 889 ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults')
741 890
742 def getargspec(func): 891 def getargspec(func):
743 """Get the names and default values of a function's arguments. 892 """Get the names and default values of a function's arguments.
744 893
745 A tuple of four things is returned: (args, varargs, varkw, defaults). 894 A tuple of four things is returned: (args, varargs, varkw, defaults).
746 'args' is a list of the argument names (it may contain nested lists). 895 'args' is a list of the argument names.
896 'args' will include keyword-only argument names.
747 'varargs' and 'varkw' are the names of the * and ** arguments or None. 897 'varargs' and 'varkw' are the names of the * and ** arguments or None.
748 'defaults' is an n-tuple of the default values of the last n arguments. 898 'defaults' is an n-tuple of the default values of the last n arguments.
899
900 Use the getfullargspec() API for Python-3000 code, as annotations
901 and keyword arguments are supported. getargspec() will raise ValueError
902 if the func has either annotations or keyword arguments.
749 """ 903 """
750 904
905 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
906 getfullargspec(func)
907 if kwonlyargs or ann:
908 raise ValueError("Function has keyword-only arguments or annotations"
909 ", use getfullargspec() API which can support them")
910 return ArgSpec(args, varargs, varkw, defaults)
911
912 FullArgSpec = namedtuple('FullArgSpec',
913 'args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations')
914
915 def getfullargspec(func):
916 """Get the names and default values of a function's arguments.
917
918 A tuple of seven things is returned:
919 (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults annotations).
920 'args' is a list of the argument names.
921 'varargs' and 'varkw' are the names of the * and ** arguments or None.
922 'defaults' is an n-tuple of the default values of the last n arguments.
923 'kwonlyargs' is a list of keyword-only argument names.
924 'kwonlydefaults' is a dictionary mapping names from kwonlyargs to defaults.
925 'annotations' is a dictionary mapping argument names to annotations.
926
927 The first four items in the tuple correspond to getargspec().
928 """
929
751 if ismethod(func): 930 if ismethod(func):
752 func = func.im_func 931 func = func.__func__
753 if not isfunction(func): 932 if not isfunction(func):
754 raise TypeError('arg is not a Python function') 933 raise TypeError('{!r} is not a Python function'.format(func))
755 args, varargs, varkw = getargs(func.func_code) 934 args, varargs, kwonlyargs, varkw = _getfullargs(func.__code__)
756 return ArgSpec(args, varargs, varkw, func.func_defaults) 935 return FullArgSpec(args, varargs, varkw, func.__defaults__,
936 kwonlyargs, func.__kwdefaults__, func.__annotations__)
757 937
758 ArgInfo = namedtuple('ArgInfo', 'args varargs keywords locals') 938 ArgInfo = namedtuple('ArgInfo', 'args varargs keywords locals')
759 939
760 def getargvalues(frame): 940 def getargvalues(frame):
761 """Get information about arguments passed into a particular frame. 941 """Get information about arguments passed into a particular frame.
762 942
763 A tuple of four things is returned: (args, varargs, varkw, locals). 943 A tuple of four things is returned: (args, varargs, varkw, locals).
764 'args' is a list of the argument names (it may contain nested lists). 944 'args' is a list of the argument names.
765 'varargs' and 'varkw' are the names of the * and ** arguments or None. 945 'varargs' and 'varkw' are the names of the * and ** arguments or None.
766 'locals' is the locals dictionary of the given frame.""" 946 'locals' is the locals dictionary of the given frame."""
767 args, varargs, varkw = getargs(frame.f_code) 947 args, varargs, varkw = getargs(frame.f_code)
768 return args, varargs, varkw, frame.f_locals 948 return ArgInfo(args, varargs, varkw, frame.f_locals)
769 949
770 def joinseq(seq): 950 def formatannotation(annotation, base_module=None):
771 if len(seq) == 1: 951 if isinstance(annotation, type):
772 return '(' + seq[0] + ',)' 952 if annotation.__module__ in ('builtins', base_module):
773 else: 953 return annotation.__name__
774 return '(' + string.join(seq, ', ') + ')' 954 return annotation.__module__+'.'+annotation.__name__
775 955 return repr(annotation)
776 def strseq(object, convert, join=joinseq): 956
777 """Recursively walk a sequence, stringifying each element.""" 957 def formatannotationrelativeto(object):
778 if type(object) in (list, tuple): 958 module = getattr(object, '__module__', None)
779 return join(map(lambda o, c=convert, j=join: strseq(o, c, j), object)) 959 def _formatannotation(annotation):
780 else: 960 return formatannotation(annotation, module)
781 return convert(object) 961 return _formatannotation
782 962
783 def formatargspec(args, varargs=None, varkw=None, defaults=None, 963 def formatargspec(args, varargs=None, varkw=None, defaults=None,
964 kwonlyargs=(), kwonlydefaults={}, annotations={},
784 formatarg=str, 965 formatarg=str,
785 formatvarargs=lambda name: '*' + name, 966 formatvarargs=lambda name: '*' + name,
786 formatvarkw=lambda name: '**' + name, 967 formatvarkw=lambda name: '**' + name,
787 formatvalue=lambda value: '=' + repr(value), 968 formatvalue=lambda value: '=' + repr(value),
788 join=joinseq): 969 formatreturns=lambda text: ' -> ' + text,
789 """Format an argument spec from the 4 values returned by getargspec. 970 formatannotation=formatannotation):
790 971 """Format an argument spec from the values returned by getargspec
791 The first four arguments are (args, varargs, varkw, defaults). The 972 or getfullargspec.
792 other four arguments are the corresponding optional formatting functions 973
793 that are called to turn names and values into strings. The ninth 974 The first seven arguments are (args, varargs, varkw, defaults,
794 argument is an optional function to format the sequence of arguments.""" 975 kwonlyargs, kwonlydefaults, annotations). The other five arguments
976 are the corresponding optional formatting functions that are called to
977 turn names and values into strings. The last argument is an optional
978 function to format the sequence of arguments."""
979 def formatargandannotation(arg):
980 result = formatarg(arg)
981 if arg in annotations:
982 result += ': ' + formatannotation(annotations[arg])
983 return result
795 specs = [] 984 specs = []
796 if defaults: 985 if defaults:
797 firstdefault = len(args) - len(defaults) 986 firstdefault = len(args) - len(defaults)
798 for i in range(len(args)): 987 for i, arg in enumerate(args):
799 spec = strseq(args[i], formatarg, join) 988 spec = formatargandannotation(arg)
800 if defaults and i >= firstdefault: 989 if defaults and i >= firstdefault:
801 spec = spec + formatvalue(defaults[i - firstdefault]) 990 spec = spec + formatvalue(defaults[i - firstdefault])
802 specs.append(spec) 991 specs.append(spec)
803 if varargs is not None: 992 if varargs is not None:
804 specs.append(formatvarargs(varargs)) 993 specs.append(formatvarargs(formatargandannotation(varargs)))
994 else:
995 if kwonlyargs:
996 specs.append('*')
997 if kwonlyargs:
998 for kwonlyarg in kwonlyargs:
999 spec = formatargandannotation(kwonlyarg)
1000 if kwonlydefaults and kwonlyarg in kwonlydefaults:
1001 spec += formatvalue(kwonlydefaults[kwonlyarg])
1002 specs.append(spec)
805 if varkw is not None: 1003 if varkw is not None:
806 specs.append(formatvarkw(varkw)) 1004 specs.append(formatvarkw(formatargandannotation(varkw)))
807 return '(' + string.join(specs, ', ') + ')' 1005 result = '(' + ', '.join(specs) + ')'
1006 if 'return' in annotations:
1007 result += formatreturns(formatannotation(annotations['return']))
1008 return result
808 1009
809 def formatargvalues(args, varargs, varkw, locals, 1010 def formatargvalues(args, varargs, varkw, locals,
810 formatarg=str, 1011 formatarg=str,
811 formatvarargs=lambda name: '*' + name, 1012 formatvarargs=lambda name: '*' + name,
812 formatvarkw=lambda name: '**' + name, 1013 formatvarkw=lambda name: '**' + name,
813 formatvalue=lambda value: '=' + repr(value), 1014 formatvalue=lambda value: '=' + repr(value)):
814 join=joinseq):
815 """Format an argument spec from the 4 values returned by getargvalues. 1015 """Format an argument spec from the 4 values returned by getargvalues.
816 1016
817 The first four arguments are (args, varargs, varkw, locals). The 1017 The first four arguments are (args, varargs, varkw, locals). The
818 next four arguments are the corresponding optional formatting functions 1018 next four arguments are the corresponding optional formatting functions
819 that are called to turn names and values into strings. The ninth 1019 that are called to turn names and values into strings. The ninth
820 argument is an optional function to format the sequence of arguments.""" 1020 argument is an optional function to format the sequence of arguments."""
821 def convert(name, locals=locals, 1021 def convert(name, locals=locals,
822 formatarg=formatarg, formatvalue=formatvalue): 1022 formatarg=formatarg, formatvalue=formatvalue):
823 return formatarg(name) + formatvalue(locals[name]) 1023 return formatarg(name) + formatvalue(locals[name])
824 specs = [] 1024 specs = []
825 for i in range(len(args)): 1025 for i in range(len(args)):
826 specs.append(strseq(args[i], convert, join)) 1026 specs.append(convert(args[i]))
827 if varargs: 1027 if varargs:
828 specs.append(formatvarargs(varargs) + formatvalue(locals[varargs])) 1028 specs.append(formatvarargs(varargs) + formatvalue(locals[varargs]))
829 if varkw: 1029 if varkw:
830 specs.append(formatvarkw(varkw) + formatvalue(locals[varkw])) 1030 specs.append(formatvarkw(varkw) + formatvalue(locals[varkw]))
831 return '(' + string.join(specs, ', ') + ')' 1031 return '(' + ', '.join(specs) + ')'
1032
1033 def _missing_arguments(f_name, argnames, pos, values):
1034 names = [repr(name) for name in argnames if name not in values]
1035 missing = len(names)
1036 if missing == 1:
1037 s = names[0]
1038 elif missing == 2:
1039 s = "{} and {}".format(*names)
1040 else:
1041 tail = ", {} and {}".format(names[-2:])
1042 del names[-2:]
1043 s = ", ".join(names) + tail
1044 raise TypeError("%s() missing %i required %s argument%s: %s" %
1045 (f_name, missing,
1046 "positional" if pos else "keyword-only",
1047 "" if missing == 1 else "s", s))
1048
1049 def _too_many(f_name, args, kwonly, varargs, defcount, given, values):
1050 atleast = len(args) - defcount
1051 kwonly_given = len([arg for arg in kwonly if arg in values])
1052 if varargs:
1053 plural = atleast != 1
1054 sig = "at least %d" % (atleast,)
1055 elif defcount:
1056 plural = True
1057 sig = "from %d to %d" % (atleast, len(args))
1058 else:
1059 plural = len(args) != 1
1060 sig = str(len(args))
1061 kwonly_sig = ""
1062 if kwonly_given:
1063 msg = " positional argument%s (and %d keyword-only argument%s)"
1064 kwonly_sig = (msg % ("s" if given != 1 else "", kwonly_given,
1065 "s" if kwonly_given != 1 else ""))
1066 raise TypeError("%s() takes %s positional argument%s but %d%s %s given" %
1067 (f_name, sig, "s" if plural else "", given, kwonly_sig,
1068 "was" if given == 1 and not kwonly_given else "were"))
1069
1070 def getcallargs(func, *positional, **named):
1071 """Get the mapping of arguments to values.
1072
1073 A dict is returned, with keys the function argument names (including the
1074 names of the * and ** arguments, if any), and values the respective bound
1075 values from 'positional' and 'named'."""
1076 spec = getfullargspec(func)
1077 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = spec
1078 f_name = func.__name__
1079 arg2value = {}
1080
1081
1082 if ismethod(func) and func.__self__ is not None:
1083 # implicit 'self' (or 'cls' for classmethods) argument
1084 positional = (func.__self__,) + positional
1085 num_pos = len(positional)
1086 num_args = len(args)
1087 num_defaults = len(defaults) if defaults else 0
1088
1089 n = min(num_pos, num_args)
1090 for i in range(n):
1091 arg2value[args[i]] = positional[i]
1092 if varargs:
1093 arg2value[varargs] = tuple(positional[n:])
1094 possible_kwargs = set(args + kwonlyargs)
1095 if varkw:
1096 arg2value[varkw] = {}
1097 for kw, value in named.items():
1098 if kw not in possible_kwargs:
1099 if not varkw:
1100 raise TypeError("%s() got an unexpected keyword argument %r" %
1101 (f_name, kw))
1102 arg2value[varkw][kw] = value
1103 continue
1104 if kw in arg2value:
1105 raise TypeError("%s() got multiple values for argument %r" %
1106 (f_name, kw))
1107 arg2value[kw] = value
1108 if num_pos > num_args and not varargs:
1109 _too_many(f_name, args, kwonlyargs, varargs, num_defaults,
1110 num_pos, arg2value)
1111 if num_pos < num_args:
1112 req = args[:num_args - num_defaults]
1113 for arg in req:
1114 if arg not in arg2value:
1115 _missing_arguments(f_name, req, True, arg2value)
1116 for i, arg in enumerate(args[num_args - num_defaults:]):
1117 if arg not in arg2value:
1118 arg2value[arg] = defaults[i]
1119 missing = 0
1120 for kwarg in kwonlyargs:
1121 if kwarg not in arg2value:
1122 if kwarg in kwonlydefaults:
1123 arg2value[kwarg] = kwonlydefaults[kwarg]
1124 else:
1125 missing += 1
1126 if missing:
1127 _missing_arguments(f_name, kwonlyargs, False, arg2value)
1128 return arg2value
1129
1130 ClosureVars = namedtuple('ClosureVars', 'nonlocals globals builtins unbound')
1131
1132 def getclosurevars(func):
1133 """
1134 Get the mapping of free variables to their current values.
1135
1136 Returns a named tuple of dicts mapping the current nonlocal, global
1137 and builtin references as seen by the body of the function. A final
1138 set of unbound names that could not be resolved is also provided.
1139 """
1140
1141 if ismethod(func):
1142 func = func.__func__
1143
1144 if not isfunction(func):
1145 raise TypeError("'{!r}' is not a Python function".format(func))
1146
1147 code = func.__code__
1148 # Nonlocal references are named in co_freevars and resolved
1149 # by looking them up in __closure__ by positional index
1150 if func.__closure__ is None:
1151 nonlocal_vars = {}
1152 else:
1153 nonlocal_vars = {
1154 var : cell.cell_contents
1155 for var, cell in zip(code.co_freevars, func.__closure__)
1156 }
1157
1158 # Global and builtin references are named in co_names and resolved
1159 # by looking them up in __globals__ or __builtins__
1160 global_ns = func.__globals__
1161 builtin_ns = global_ns.get("__builtins__", builtins.__dict__)
1162 if ismodule(builtin_ns):
1163 builtin_ns = builtin_ns.__dict__
1164 global_vars = {}
1165 builtin_vars = {}
1166 unbound_names = set()
1167 for name in code.co_names:
1168 if name in ("None", "True", "False"):
1169 # Because these used to be builtins instead of keywords, they
1170 # may still show up as name references. We ignore them.
1171 continue
1172 try:
1173 global_vars[name] = global_ns[name]
1174 except KeyError:
1175 try:
1176 builtin_vars[name] = builtin_ns[name]
1177 except KeyError:
1178 unbound_names.add(name)
1179
1180 return ClosureVars(nonlocal_vars, global_vars,
1181 builtin_vars, unbound_names)
832 1182
833 # -------------------------------------------------- stack frame extraction 1183 # -------------------------------------------------- stack frame extraction
834 1184
835 Traceback = namedtuple('Traceback', 'filename lineno function code_context index ') 1185 Traceback = namedtuple('Traceback', 'filename lineno function code_context index ')
836 1186
837 def getframeinfo(frame, context=1): 1187 def getframeinfo(frame, context=1):
838 """Get information about a frame or traceback object. 1188 """Get information about a frame or traceback object.
839 1189
840 A tuple of five things is returned: the filename, the line number of 1190 A tuple of five things is returned: the filename, the line number of
841 the current line, the function name, a list of lines of context from 1191 the current line, the function name, a list of lines of context from
842 the source code, and the index of the current line within that list. 1192 the source code, and the index of the current line within that list.
843 The optional second argument specifies the number of lines of context 1193 The optional second argument specifies the number of lines of context
844 to return, which are centered around the current line.""" 1194 to return, which are centered around the current line."""
845 if istraceback(frame): 1195 if istraceback(frame):
846 lineno = frame.tb_lineno 1196 lineno = frame.tb_lineno
847 frame = frame.tb_frame 1197 frame = frame.tb_frame
848 else: 1198 else:
849 lineno = frame.f_lineno 1199 lineno = frame.f_lineno
850 if not isframe(frame): 1200 if not isframe(frame):
851 raise TypeError('arg is not a frame or traceback object') 1201 raise TypeError('{!r} is not a frame or traceback object'.format(frame))
852 1202
853 filename = getsourcefile(frame) or getfile(frame) 1203 filename = getsourcefile(frame) or getfile(frame)
854 if context > 0: 1204 if context > 0:
855 start = lineno - 1 - context//2 1205 start = lineno - 1 - context//2
856 try: 1206 try:
857 lines, lnum = findsource(frame) 1207 lines, lnum = findsource(frame)
858 except IOError: 1208 except OSError:
859 lines = index = None 1209 lines = index = None
860 else: 1210 else:
861 start = max(start, 1) 1211 start = max(start, 1)
862 start = max(0, min(start, len(lines) - context)) 1212 start = max(0, min(start, len(lines) - context))
863 lines = lines[start:start+context] 1213 lines = lines[start:start+context]
864 index = lineno - 1 - start 1214 index = lineno - 1 - start
865 else: 1215 else:
866 lines = index = None 1216 lines = index = None
867 1217
868 return Traceback(filename, lineno, frame.f_code.co_name, lines, index) 1218 return Traceback(filename, lineno, frame.f_code.co_name, lines, index)
(...skipping 18 matching lines...) Expand all
887 """Get a list of records for a traceback's frame and all lower frames. 1237 """Get a list of records for a traceback's frame and all lower frames.
888 1238
889 Each record contains a frame object, filename, line number, function 1239 Each record contains a frame object, filename, line number, function
890 name, a list of lines of context, and index within the context.""" 1240 name, a list of lines of context, and index within the context."""
891 framelist = [] 1241 framelist = []
892 while tb: 1242 while tb:
893 framelist.append((tb.tb_frame,) + getframeinfo(tb, context)) 1243 framelist.append((tb.tb_frame,) + getframeinfo(tb, context))
894 tb = tb.tb_next 1244 tb = tb.tb_next
895 return framelist 1245 return framelist
896 1246
897 currentframe = sys._getframe 1247 def currentframe():
1248 """Return the frame of the caller or None if this is not possible."""
1249 return sys._getframe(1) if hasattr(sys, "_getframe") else None
898 1250
899 def stack(context=1): 1251 def stack(context=1):
900 """Return a list of records for the stack above the caller's frame.""" 1252 """Return a list of records for the stack above the caller's frame."""
901 return getouterframes(sys._getframe(1), context) 1253 return getouterframes(sys._getframe(1), context)
902 1254
903 def trace(context=1): 1255 def trace(context=1):
904 """Return a list of records for the stack below the current exception.""" 1256 """Return a list of records for the stack below the current exception."""
905 return getinnerframes(sys.exc_info()[2], context) 1257 return getinnerframes(sys.exc_info()[2], context)
1258
1259
1260 # ------------------------------------------------ static version of getattr
1261
1262 _sentinel = object()
1263
1264 def _static_getmro(klass):
1265 return type.__dict__['__mro__'].__get__(klass)
1266
1267 def _check_instance(obj, attr):
1268 instance_dict = {}
1269 try:
1270 instance_dict = object.__getattribute__(obj, "__dict__")
1271 except AttributeError:
1272 pass
1273 return dict.get(instance_dict, attr, _sentinel)
1274
1275
1276 def _check_class(klass, attr):
1277 for entry in _static_getmro(klass):
1278 if _shadowed_dict(type(entry)) is _sentinel:
1279 try:
1280 return entry.__dict__[attr]
1281 except KeyError:
1282 pass
1283 return _sentinel
1284
1285 def _is_type(obj):
1286 try:
1287 _static_getmro(obj)
1288 except TypeError:
1289 return False
1290 return True
1291
1292 def _shadowed_dict(klass):
1293 dict_attr = type.__dict__["__dict__"]
1294 for entry in _static_getmro(klass):
1295 try:
1296 class_dict = dict_attr.__get__(entry)["__dict__"]
1297 except KeyError:
1298 pass
1299 else:
1300 if not (type(class_dict) is types.GetSetDescriptorType and
1301 class_dict.__name__ == "__dict__" and
1302 class_dict.__objclass__ is entry):
1303 return class_dict
1304 return _sentinel
1305
1306 def getattr_static(obj, attr, default=_sentinel):
1307 """Retrieve attributes without triggering dynamic lookup via the
1308 descriptor protocol, __getattr__ or __getattribute__.
1309
1310 Note: this function may not be able to retrieve all attributes
1311 that getattr can fetch (like dynamically created attributes)
1312 and may find attributes that getattr can't (like descriptors
1313 that raise AttributeError). It can also return descriptor objects
1314 instead of instance members in some cases. See the
1315 documentation for details.
1316 """
1317 instance_result = _sentinel
1318 if not _is_type(obj):
1319 klass = type(obj)
1320 dict_attr = _shadowed_dict(klass)
1321 if (dict_attr is _sentinel or
1322 type(dict_attr) is types.MemberDescriptorType):
1323 instance_result = _check_instance(obj, attr)
1324 else:
1325 klass = obj
1326
1327 klass_result = _check_class(klass, attr)
1328
1329 if instance_result is not _sentinel and klass_result is not _sentinel:
1330 if (_check_class(type(klass_result), '__get__') is not _sentinel and
1331 _check_class(type(klass_result), '__set__') is not _sentinel):
1332 return klass_result
1333
1334 if instance_result is not _sentinel:
1335 return instance_result
1336 if klass_result is not _sentinel:
1337 return klass_result
1338
1339 if obj is klass:
1340 # for types we check the metaclass too
1341 for entry in _static_getmro(type(klass)):
1342 if _shadowed_dict(type(entry)) is _sentinel:
1343 try:
1344 return entry.__dict__[attr]
1345 except KeyError:
1346 pass
1347 if default is not _sentinel:
1348 return default
1349 raise AttributeError(attr)
1350
1351
1352 # ------------------------------------------------ generator introspection
1353
1354 GEN_CREATED = 'GEN_CREATED'
1355 GEN_RUNNING = 'GEN_RUNNING'
1356 GEN_SUSPENDED = 'GEN_SUSPENDED'
1357 GEN_CLOSED = 'GEN_CLOSED'
1358
1359 def getgeneratorstate(generator):
1360 """Get current state of a generator-iterator.
1361
1362 Possible states are:
1363 GEN_CREATED: Waiting to start execution.
1364 GEN_RUNNING: Currently being executed by the interpreter.
1365 GEN_SUSPENDED: Currently suspended at a yield expression.
1366 GEN_CLOSED: Execution has completed.
1367 """
1368 if generator.gi_running:
1369 return GEN_RUNNING
1370 if generator.gi_frame is None:
1371 return GEN_CLOSED
1372 if generator.gi_frame.f_lasti == -1:
1373 return GEN_CREATED
1374 return GEN_SUSPENDED
1375
1376
1377 def getgeneratorlocals(generator):
1378 """
1379 Get the mapping of generator local variables to their current values.
1380
1381 A dict is returned, with the keys the local variable names and values the
1382 bound values."""
1383
1384 if not isgenerator(generator):
1385 raise TypeError("'{!r}' is not a Python generator".format(generator))
1386
1387 frame = getattr(generator, "gi_frame", None)
1388 if frame is not None:
1389 return generator.gi_frame.f_locals
1390 else:
1391 return {}
1392
1393 ###############################################################################
1394 ### Function Signature Object (PEP 362)
1395 ###############################################################################
1396
1397
1398 _WrapperDescriptor = type(type.__call__)
1399 _MethodWrapper = type(all.__call__)
1400
1401 _NonUserDefinedCallables = (_WrapperDescriptor,
1402 _MethodWrapper,
1403 types.BuiltinFunctionType)
1404
1405
1406 def _get_user_defined_method(cls, method_name):
1407 try:
1408 meth = getattr(cls, method_name)
1409 except AttributeError:
1410 return
1411 else:
1412 if not isinstance(meth, _NonUserDefinedCallables):
1413 # Once '__signature__' will be added to 'C'-level
1414 # callables, this check won't be necessary
1415 return meth
1416
1417
1418 def signature(obj):
1419 '''Get a signature object for the passed callable.'''
1420
1421 if not callable(obj):
1422 raise TypeError('{!r} is not a callable object'.format(obj))
1423
1424 if isinstance(obj, types.MethodType):
1425 # In this case we skip the first parameter of the underlying
1426 # function (usually `self` or `cls`).
1427 sig = signature(obj.__func__)
1428 return sig.replace(parameters=tuple(sig.parameters.values())[1:])
1429
1430 # Was this function wrapped by a decorator?
1431 obj = unwrap(obj, stop=(lambda f: hasattr(f, "__signature__")))
1432
1433 try:
1434 sig = obj.__signature__
1435 except AttributeError:
1436 pass
1437 else:
1438 if sig is not None:
1439 return sig
1440
1441
1442 if isinstance(obj, types.FunctionType):
1443 return Signature.from_function(obj)
1444
1445 if isinstance(obj, functools.partial):
1446 sig = signature(obj.func)
1447
1448 new_params = OrderedDict(sig.parameters.items())
1449
1450 partial_args = obj.args or ()
1451 partial_keywords = obj.keywords or {}
1452 try:
1453 ba = sig.bind_partial(*partial_args, **partial_keywords)
1454 except TypeError as ex:
1455 msg = 'partial object {!r} has incorrect arguments'.format(obj)
1456 raise ValueError(msg) from ex
1457
1458 for arg_name, arg_value in ba.arguments.items():
1459 param = new_params[arg_name]
1460 if arg_name in partial_keywords:
1461 # We set a new default value, because the following code
1462 # is correct:
1463 #
1464 # >>> def foo(a): print(a)
1465 # >>> print(partial(partial(foo, a=10), a=20)())
1466 # 20
1467 # >>> print(partial(partial(foo, a=10), a=20)(a=30))
1468 # 30
1469 #
1470 # So, with 'partial' objects, passing a keyword argument is
1471 # like setting a new default value for the corresponding
1472 # parameter
1473 #
1474 # We also mark this parameter with '_partial_kwarg'
1475 # flag. Later, in '_bind', the 'default' value of this
1476 # parameter will be added to 'kwargs', to simulate
1477 # the 'functools.partial' real call.
1478 new_params[arg_name] = param.replace(default=arg_value,
1479 _partial_kwarg=True)
1480
1481 elif (param.kind not in (_VAR_KEYWORD, _VAR_POSITIONAL) and
1482 not param._partial_kwarg):
1483 new_params.pop(arg_name)
1484
1485 return sig.replace(parameters=new_params.values())
1486
1487 sig = None
1488 if isinstance(obj, type):
1489 # obj is a class or a metaclass
1490
1491 # First, let's see if it has an overloaded __call__ defined
1492 # in its metaclass
1493 call = _get_user_defined_method(type(obj), '__call__')
1494 if call is not None:
1495 sig = signature(call)
1496 else:
1497 # Now we check if the 'obj' class has a '__new__' method
1498 new = _get_user_defined_method(obj, '__new__')
1499 if new is not None:
1500 sig = signature(new)
1501 else:
1502 # Finally, we should have at least __init__ implemented
1503 init = _get_user_defined_method(obj, '__init__')
1504 if init is not None:
1505 sig = signature(init)
1506 elif not isinstance(obj, _NonUserDefinedCallables):
1507 # An object with __call__
1508 # We also check that the 'obj' is not an instance of
1509 # _WrapperDescriptor or _MethodWrapper to avoid
1510 # infinite recursion (and even potential segfault)
1511 call = _get_user_defined_method(type(obj), '__call__')
1512 if call is not None:
1513 sig = signature(call)
1514
1515 if sig is not None:
1516 # For classes and objects we skip the first parameter of their
1517 # __call__, __new__, or __init__ methods
1518 return sig.replace(parameters=tuple(sig.parameters.values())[1:])
1519
1520 if isinstance(obj, types.BuiltinFunctionType):
1521 # Raise a nicer error message for builtins
1522 msg = 'no signature found for builtin function {!r}'.format(obj)
1523 raise ValueError(msg)
1524
1525 raise ValueError('callable {!r} is not supported by signature'.format(obj))
1526
1527
1528 class _void:
1529 '''A private marker - used in Parameter & Signature'''
1530
1531
1532 class _empty:
1533 pass
1534
1535
1536 class _ParameterKind(int):
1537 def __new__(self, *args, name):
1538 obj = int.__new__(self, *args)
1539 obj._name = name
1540 return obj
1541
1542 def __str__(self):
1543 return self._name
1544
1545 def __repr__(self):
1546 return '<_ParameterKind: {!r}>'.format(self._name)
1547
1548
1549 _POSITIONAL_ONLY = _ParameterKind(0, name='POSITIONAL_ONLY')
1550 _POSITIONAL_OR_KEYWORD = _ParameterKind(1, name='POSITIONAL_OR_KEYWORD')
1551 _VAR_POSITIONAL = _ParameterKind(2, name='VAR_POSITIONAL')
1552 _KEYWORD_ONLY = _ParameterKind(3, name='KEYWORD_ONLY')
1553 _VAR_KEYWORD = _ParameterKind(4, name='VAR_KEYWORD')
1554
1555
1556 class Parameter:
1557 '''Represents a parameter in a function signature.
1558
1559 Has the following public attributes:
1560
1561 * name : str
1562 The name of the parameter as a string.
1563 * default : object
1564 The default value for the parameter if specified. If the
1565 parameter has no default value, this attribute is not set.
1566 * annotation
1567 The annotation for the parameter if specified. If the
1568 parameter has no annotation, this attribute is not set.
1569 * kind : str
1570 Describes how argument values are bound to the parameter.
1571 Possible values: `Parameter.POSITIONAL_ONLY`,
1572 `Parameter.POSITIONAL_OR_KEYWORD`, `Parameter.VAR_POSITIONAL`,
1573 `Parameter.KEYWORD_ONLY`, `Parameter.VAR_KEYWORD`.
1574 '''
1575
1576 __slots__ = ('_name', '_kind', '_default', '_annotation', '_partial_kwarg')
1577
1578 POSITIONAL_ONLY = _POSITIONAL_ONLY
1579 POSITIONAL_OR_KEYWORD = _POSITIONAL_OR_KEYWORD
1580 VAR_POSITIONAL = _VAR_POSITIONAL
1581 KEYWORD_ONLY = _KEYWORD_ONLY
1582 VAR_KEYWORD = _VAR_KEYWORD
1583
1584 empty = _empty
1585
1586 def __init__(self, name, kind, *, default=_empty, annotation=_empty,
1587 _partial_kwarg=False):
1588
1589 if kind not in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD,
1590 _VAR_POSITIONAL, _KEYWORD_ONLY, _VAR_KEYWORD):
1591 raise ValueError("invalid value for 'Parameter.kind' attribute")
1592 self._kind = kind
1593
1594 if default is not _empty:
1595 if kind in (_VAR_POSITIONAL, _VAR_KEYWORD):
1596 msg = '{} parameters cannot have default values'.format(kind)
1597 raise ValueError(msg)
1598 self._default = default
1599 self._annotation = annotation
1600
1601 if name is None:
1602 if kind != _POSITIONAL_ONLY:
1603 raise ValueError("None is not a valid name for a "
1604 "non-positional-only parameter")
1605 self._name = name
1606 else:
1607 name = str(name)
1608 if kind != _POSITIONAL_ONLY and not name.isidentifier():
1609 msg = '{!r} is not a valid parameter name'.format(name)
1610 raise ValueError(msg)
1611 self._name = name
1612
1613 self._partial_kwarg = _partial_kwarg
1614
1615 @property
1616 def name(self):
1617 return self._name
1618
1619 @property
1620 def default(self):
1621 return self._default
1622
1623 @property
1624 def annotation(self):
1625 return self._annotation
1626
1627 @property
1628 def kind(self):
1629 return self._kind
1630
1631 def replace(self, *, name=_void, kind=_void, annotation=_void,
1632 default=_void, _partial_kwarg=_void):
1633 '''Creates a customized copy of the Parameter.'''
1634
1635 if name is _void:
1636 name = self._name
1637
1638 if kind is _void:
1639 kind = self._kind
1640
1641 if annotation is _void:
1642 annotation = self._annotation
1643
1644 if default is _void:
1645 default = self._default
1646
1647 if _partial_kwarg is _void:
1648 _partial_kwarg = self._partial_kwarg
1649
1650 return type(self)(name, kind, default=default, annotation=annotation,
1651 _partial_kwarg=_partial_kwarg)
1652
1653 def __str__(self):
1654 kind = self.kind
1655
1656 formatted = self._name
1657 if kind == _POSITIONAL_ONLY:
1658 if formatted is None:
1659 formatted = ''
1660 formatted = '<{}>'.format(formatted)
1661
1662 # Add annotation and default value
1663 if self._annotation is not _empty:
1664 formatted = '{}:{}'.format(formatted,
1665 formatannotation(self._annotation))
1666
1667 if self._default is not _empty:
1668 formatted = '{}={}'.format(formatted, repr(self._default))
1669
1670 if kind == _VAR_POSITIONAL:
1671 formatted = '*' + formatted
1672 elif kind == _VAR_KEYWORD:
1673 formatted = '**' + formatted
1674
1675 return formatted
1676
1677 def __repr__(self):
1678 return '<{} at {:#x} {!r}>'.format(self.__class__.__name__,
1679 id(self), self.name)
1680
1681 def __eq__(self, other):
1682 return (issubclass(other.__class__, Parameter) and
1683 self._name == other._name and
1684 self._kind == other._kind and
1685 self._default == other._default and
1686 self._annotation == other._annotation)
1687
1688 def __ne__(self, other):
1689 return not self.__eq__(other)
1690
1691
1692 class BoundArguments:
1693 '''Result of `Signature.bind` call. Holds the mapping of arguments
1694 to the function's parameters.
1695
1696 Has the following public attributes:
1697
1698 * arguments : OrderedDict
1699 An ordered mutable mapping of parameters' names to arguments' values.
1700 Does not contain arguments' default values.
1701 * signature : Signature
1702 The Signature object that created this instance.
1703 * args : tuple
1704 Tuple of positional arguments values.
1705 * kwargs : dict
1706 Dict of keyword arguments values.
1707 '''
1708
1709 def __init__(self, signature, arguments):
1710 self.arguments = arguments
1711 self._signature = signature
1712
1713 @property
1714 def signature(self):
1715 return self._signature
1716
1717 @property
1718 def args(self):
1719 args = []
1720 for param_name, param in self._signature.parameters.items():
1721 if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or
1722 param._partial_kwarg):
1723 # Keyword arguments mapped by 'functools.partial'
1724 # (Parameter._partial_kwarg is True) are mapped
1725 # in 'BoundArguments.kwargs', along with VAR_KEYWORD &
1726 # KEYWORD_ONLY
1727 break
1728
1729 try:
1730 arg = self.arguments[param_name]
1731 except KeyError:
1732 # We're done here. Other arguments
1733 # will be mapped in 'BoundArguments.kwargs'
1734 break
1735 else:
1736 if param.kind == _VAR_POSITIONAL:
1737 # *args
1738 args.extend(arg)
1739 else:
1740 # plain argument
1741 args.append(arg)
1742
1743 return tuple(args)
1744
1745 @property
1746 def kwargs(self):
1747 kwargs = {}
1748 kwargs_started = False
1749 for param_name, param in self._signature.parameters.items():
1750 if not kwargs_started:
1751 if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or
1752 param._partial_kwarg):
1753 kwargs_started = True
1754 else:
1755 if param_name not in self.arguments:
1756 kwargs_started = True
1757 continue
1758
1759 if not kwargs_started:
1760 continue
1761
1762 try:
1763 arg = self.arguments[param_name]
1764 except KeyError:
1765 pass
1766 else:
1767 if param.kind == _VAR_KEYWORD:
1768 # **kwargs
1769 kwargs.update(arg)
1770 else:
1771 # plain keyword argument
1772 kwargs[param_name] = arg
1773
1774 return kwargs
1775
1776 def __eq__(self, other):
1777 return (issubclass(other.__class__, BoundArguments) and
1778 self.signature == other.signature and
1779 self.arguments == other.arguments)
1780
1781 def __ne__(self, other):
1782 return not self.__eq__(other)
1783
1784
1785 class Signature:
1786 '''A Signature object represents the overall signature of a function.
1787 It stores a Parameter object for each parameter accepted by the
1788 function, as well as information specific to the function itself.
1789
1790 A Signature object has the following public attributes and methods:
1791
1792 * parameters : OrderedDict
1793 An ordered mapping of parameters' names to the corresponding
1794 Parameter objects (keyword-only arguments are in the same order
1795 as listed in `code.co_varnames`).
1796 * return_annotation : object
1797 The annotation for the return type of the function if specified.
1798 If the function has no annotation for its return type, this
1799 attribute is not set.
1800 * bind(*args, **kwargs) -> BoundArguments
1801 Creates a mapping from positional and keyword arguments to
1802 parameters.
1803 * bind_partial(*args, **kwargs) -> BoundArguments
1804 Creates a partial mapping from positional and keyword arguments
1805 to parameters (simulating 'functools.partial' behavior.)
1806 '''
1807
1808 __slots__ = ('_return_annotation', '_parameters')
1809
1810 _parameter_cls = Parameter
1811 _bound_arguments_cls = BoundArguments
1812
1813 empty = _empty
1814
1815 def __init__(self, parameters=None, *, return_annotation=_empty,
1816 __validate_parameters__=True):
1817 '''Constructs Signature from the given list of Parameter
1818 objects and 'return_annotation'. All arguments are optional.
1819 '''
1820
1821 if parameters is None:
1822 params = OrderedDict()
1823 else:
1824 if __validate_parameters__:
1825 params = OrderedDict()
1826 top_kind = _POSITIONAL_ONLY
1827
1828 for idx, param in enumerate(parameters):
1829 kind = param.kind
1830 if kind < top_kind:
1831 msg = 'wrong parameter order: {} before {}'
1832 msg = msg.format(top_kind, param.kind)
1833 raise ValueError(msg)
1834 else:
1835 top_kind = kind
1836
1837 name = param.name
1838 if name is None:
1839 name = str(idx)
1840 param = param.replace(name=name)
1841
1842 if name in params:
1843 msg = 'duplicate parameter name: {!r}'.format(name)
1844 raise ValueError(msg)
1845 params[name] = param
1846 else:
1847 params = OrderedDict(((param.name, param)
1848 for param in parameters))
1849
1850 self._parameters = types.MappingProxyType(params)
1851 self._return_annotation = return_annotation
1852
1853 @classmethod
1854 def from_function(cls, func):
1855 '''Constructs Signature for the given python function'''
1856
1857 if not isinstance(func, types.FunctionType):
1858 raise TypeError('{!r} is not a Python function'.format(func))
1859
1860 Parameter = cls._parameter_cls
1861
1862 # Parameter information.
1863 func_code = func.__code__
1864 pos_count = func_code.co_argcount
1865 arg_names = func_code.co_varnames
1866 positional = tuple(arg_names[:pos_count])
1867 keyword_only_count = func_code.co_kwonlyargcount
1868 keyword_only = arg_names[pos_count:(pos_count + keyword_only_count)]
1869 annotations = func.__annotations__
1870 defaults = func.__defaults__
1871 kwdefaults = func.__kwdefaults__
1872
1873 if defaults:
1874 pos_default_count = len(defaults)
1875 else:
1876 pos_default_count = 0
1877
1878 parameters = []
1879
1880 # Non-keyword-only parameters w/o defaults.
1881 non_default_count = pos_count - pos_default_count
1882 for name in positional[:non_default_count]:
1883 annotation = annotations.get(name, _empty)
1884 parameters.append(Parameter(name, annotation=annotation,
1885 kind=_POSITIONAL_OR_KEYWORD))
1886
1887 # ... w/ defaults.
1888 for offset, name in enumerate(positional[non_default_count:]):
1889 annotation = annotations.get(name, _empty)
1890 parameters.append(Parameter(name, annotation=annotation,
1891 kind=_POSITIONAL_OR_KEYWORD,
1892 default=defaults[offset]))
1893
1894 # *args
1895 if func_code.co_flags & 0x04:
1896 name = arg_names[pos_count + keyword_only_count]
1897 annotation = annotations.get(name, _empty)
1898 parameters.append(Parameter(name, annotation=annotation,
1899 kind=_VAR_POSITIONAL))
1900
1901 # Keyword-only parameters.
1902 for name in keyword_only:
1903 default = _empty
1904 if kwdefaults is not None:
1905 default = kwdefaults.get(name, _empty)
1906
1907 annotation = annotations.get(name, _empty)
1908 parameters.append(Parameter(name, annotation=annotation,
1909 kind=_KEYWORD_ONLY,
1910 default=default))
1911 # **kwargs
1912 if func_code.co_flags & 0x08:
1913 index = pos_count + keyword_only_count
1914 if func_code.co_flags & 0x04:
1915 index += 1
1916
1917 name = arg_names[index]
1918 annotation = annotations.get(name, _empty)
1919 parameters.append(Parameter(name, annotation=annotation,
1920 kind=_VAR_KEYWORD))
1921
1922 return cls(parameters,
1923 return_annotation=annotations.get('return', _empty),
1924 __validate_parameters__=False)
1925
1926 @property
1927 def parameters(self):
1928 return self._parameters
1929
1930 @property
1931 def return_annotation(self):
1932 return self._return_annotation
1933
1934 def replace(self, *, parameters=_void, return_annotation=_void):
1935 '''Creates a customized copy of the Signature.
1936 Pass 'parameters' and/or 'return_annotation' arguments
1937 to override them in the new copy.
1938 '''
1939
1940 if parameters is _void:
1941 parameters = self.parameters.values()
1942
1943 if return_annotation is _void:
1944 return_annotation = self._return_annotation
1945
1946 return type(self)(parameters,
1947 return_annotation=return_annotation)
1948
1949 def __eq__(self, other):
1950 if (not issubclass(type(other), Signature) or
1951 self.return_annotation != other.return_annotation or
1952 len(self.parameters) != len(other.parameters)):
1953 return False
1954
1955 other_positions = {param: idx
1956 for idx, param in enumerate(other.parameters.keys())}
1957
1958 for idx, (param_name, param) in enumerate(self.parameters.items()):
1959 if param.kind == _KEYWORD_ONLY:
1960 try:
1961 other_param = other.parameters[param_name]
1962 except KeyError:
1963 return False
1964 else:
1965 if param != other_param:
1966 return False
1967 else:
1968 try:
1969 other_idx = other_positions[param_name]
1970 except KeyError:
1971 return False
1972 else:
1973 if (idx != other_idx or
1974 param != other.parameters[param_name]):
1975 return False
1976
1977 return True
1978
1979 def __ne__(self, other):
1980 return not self.__eq__(other)
1981
1982 def _bind(self, args, kwargs, *, partial=False):
1983 '''Private method. Don't use directly.'''
1984
1985 arguments = OrderedDict()
1986
1987 parameters = iter(self.parameters.values())
1988 parameters_ex = ()
1989 arg_vals = iter(args)
1990
1991 if partial:
1992 # Support for binding arguments to 'functools.partial' objects.
1993 # See 'functools.partial' case in 'signature()' implementation
1994 # for details.
1995 for param_name, param in self.parameters.items():
1996 if (param._partial_kwarg and param_name not in kwargs):
1997 # Simulating 'functools.partial' behavior
1998 kwargs[param_name] = param.default
1999
2000 while True:
2001 # Let's iterate through the positional arguments and corresponding
2002 # parameters
2003 try:
2004 arg_val = next(arg_vals)
2005 except StopIteration:
2006 # No more positional arguments
2007 try:
2008 param = next(parameters)
2009 except StopIteration:
2010 # No more parameters. That's it. Just need to check that
2011 # we have no `kwargs` after this while loop
2012 break
2013 else:
2014 if param.kind == _VAR_POSITIONAL:
2015 # That's OK, just empty *args. Let's start parsing
2016 # kwargs
2017 break
2018 elif param.name in kwargs:
2019 if param.kind == _POSITIONAL_ONLY:
2020 msg = '{arg!r} parameter is positional only, ' \
2021 'but was passed as a keyword'
2022 msg = msg.format(arg=param.name)
2023 raise TypeError(msg) from None
2024 parameters_ex = (param,)
2025 break
2026 elif (param.kind == _VAR_KEYWORD or
2027 param.default is not _empty):
2028 # That's fine too - we have a default value for this
2029 # parameter. So, lets start parsing `kwargs`, starting
2030 # with the current parameter
2031 parameters_ex = (param,)
2032 break
2033 else:
2034 if partial:
2035 parameters_ex = (param,)
2036 break
2037 else:
2038 msg = '{arg!r} parameter lacking default value'
2039 msg = msg.format(arg=param.name)
2040 raise TypeError(msg) from None
2041 else:
2042 # We have a positional argument to process
2043 try:
2044 param = next(parameters)
2045 except StopIteration:
2046 raise TypeError('too many positional arguments') from None
2047 else:
2048 if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
2049 # Looks like we have no parameter for this positional
2050 # argument
2051 raise TypeError('too many positional arguments')
2052
2053 if param.kind == _VAR_POSITIONAL:
2054 # We have an '*args'-like argument, let's fill it with
2055 # all positional arguments we have left and move on to
2056 # the next phase
2057 values = [arg_val]
2058 values.extend(arg_vals)
2059 arguments[param.name] = tuple(values)
2060 break
2061
2062 if param.name in kwargs:
2063 raise TypeError('multiple values for argument '
2064 '{arg!r}'.format(arg=param.name))
2065
2066 arguments[param.name] = arg_val
2067
2068 # Now, we iterate through the remaining parameters to process
2069 # keyword arguments
2070 kwargs_param = None
2071 for param in itertools.chain(parameters_ex, parameters):
2072 if param.kind == _POSITIONAL_ONLY:
2073 # This should never happen in case of a properly built
2074 # Signature object (but let's have this check here
2075 # to ensure correct behaviour just in case)
2076 raise TypeError('{arg!r} parameter is positional only, '
2077 'but was passed as a keyword'. \
2078 format(arg=param.name))
2079
2080 if param.kind == _VAR_KEYWORD:
2081 # Memorize that we have a '**kwargs'-like parameter
2082 kwargs_param = param
2083 continue
2084
2085 param_name = param.name
2086 try:
2087 arg_val = kwargs.pop(param_name)
2088 except KeyError:
2089 # We have no value for this parameter. It's fine though,
2090 # if it has a default value, or it is an '*args'-like
2091 # parameter, left alone by the processing of positional
2092 # arguments.
2093 if (not partial and param.kind != _VAR_POSITIONAL and
2094 param.default is _empty):
2095 raise TypeError('{arg!r} parameter lacking default value'. \
2096 format(arg=param_name)) from None
2097
2098 else:
2099 arguments[param_name] = arg_val
2100
2101 if kwargs:
2102 if kwargs_param is not None:
2103 # Process our '**kwargs'-like parameter
2104 arguments[kwargs_param.name] = kwargs
2105 else:
2106 raise TypeError('too many keyword arguments')
2107
2108 return self._bound_arguments_cls(self, arguments)
2109
2110 def bind(__bind_self, *args, **kwargs):
2111 '''Get a BoundArguments object, that maps the passed `args`
2112 and `kwargs` to the function's signature. Raises `TypeError`
2113 if the passed arguments can not be bound.
2114 '''
2115 return __bind_self._bind(args, kwargs)
2116
2117 def bind_partial(__bind_self, *args, **kwargs):
2118 '''Get a BoundArguments object, that partially maps the
2119 passed `args` and `kwargs` to the function's signature.
2120 Raises `TypeError` if the passed arguments can not be bound.
2121 '''
2122 return __bind_self._bind(args, kwargs, partial=True)
2123
2124 def __str__(self):
2125 result = []
2126 render_kw_only_separator = True
2127 for idx, param in enumerate(self.parameters.values()):
2128 formatted = str(param)
2129
2130 kind = param.kind
2131 if kind == _VAR_POSITIONAL:
2132 # OK, we have an '*args'-like parameter, so we won't need
2133 # a '*' to separate keyword-only arguments
2134 render_kw_only_separator = False
2135 elif kind == _KEYWORD_ONLY and render_kw_only_separator:
2136 # We have a keyword-only parameter to render and we haven't
2137 # rendered an '*args'-like parameter before, so add a '*'
2138 # separator to the parameters list ("foo(arg1, *, arg2)" case)
2139 result.append('*')
2140 # This condition should be only triggered once, so
2141 # reset the flag
2142 render_kw_only_separator = False
2143
2144 result.append(formatted)
2145
2146 rendered = '({})'.format(', '.join(result))
2147
2148 if self.return_annotation is not _empty:
2149 anno = formatannotation(self.return_annotation)
2150 rendered += ' -> {}'.format(anno)
2151
2152 return rendered
2153
2154 def _main():
2155 """ Logic for inspecting an object given at command line """
2156 import argparse
2157 import importlib
2158
2159 parser = argparse.ArgumentParser()
2160 parser.add_argument(
2161 'object',
2162 help="The object to be analysed. "
2163 "It supports the 'module:qualname' syntax")
2164 parser.add_argument(
2165 '-d', '--details', action='store_true',
2166 help='Display info about the module rather than its source code')
2167
2168 args = parser.parse_args()
2169
2170 target = args.object
2171 mod_name, has_attrs, attrs = target.partition(":")
2172 try:
2173 obj = module = importlib.import_module(mod_name)
2174 except Exception as exc:
2175 msg = "Failed to import {} ({}: {})".format(mod_name,
2176 type(exc).__name__,
2177 exc)
2178 print(msg, file=sys.stderr)
2179 exit(2)
2180
2181 if has_attrs:
2182 parts = attrs.split(".")
2183 obj = module
2184 for part in parts:
2185 obj = getattr(obj, part)
2186
2187 if module.__name__ in sys.builtin_module_names:
2188 print("Can't get info for builtin modules.", file=sys.stderr)
2189 exit(1)
2190
2191 if args.details:
2192 print('Target: {}'.format(target))
2193 print('Origin: {}'.format(getsourcefile(module)))
2194 print('Cached: {}'.format(module.__cached__))
2195 if obj is module:
2196 print('Loader: {}'.format(repr(module.__loader__)))
2197 if hasattr(module, '__path__'):
2198 print('Submodule search path: {}'.format(module.__path__))
2199 else:
2200 try:
2201 __, lineno = findsource(obj)
2202 except Exception:
2203 pass
2204 else:
2205 print('Line: {}'.format(lineno))
2206
2207 print('\n')
2208 else:
2209 print(getsource(obj))
2210
2211
2212 if __name__ == "__main__":
2213 _main()
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+