blob: 887a3424057b6e1f383764567cb2be7ed19758e4 [file] [log] [blame]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001"""Get useful information from live Python objects.
2
3This module encapsulates the interface provided by the internal special
Neal Norwitz221085d2007-02-25 20:55:47 +00004attributes (co_*, im_*, tb_*, etc.) in a friendlier fashion.
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00005It also provides some help for examining source code and class layout.
6
7Here are some of the useful functions provided by this module:
8
Christian Heimes7131fd92008-02-19 14:21:46 +00009 ismodule(), isclass(), ismethod(), isfunction(), isgeneratorfunction(),
10 isgenerator(), istraceback(), isframe(), iscode(), isbuiltin(),
11 isroutine() - check object types
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000012 getmembers() - get members of an object that satisfy a given condition
13
14 getfile(), getsourcefile(), getsource() - find an object's source code
15 getdoc(), getcomments() - get documentation on an object
16 getmodule() - determine the module that an object came from
17 getclasstree() - arrange classes so as to represent their hierarchy
18
Berker Peksagfa3922c2015-07-31 04:11:29 +030019 getargvalues(), getcallargs() - get info about function arguments
Yury Selivanov0cf3ed62014-04-01 10:17:08 -040020 getfullargspec() - same, with support for Python 3 features
Matthias Bussonnier46c5cd02018-06-11 22:08:16 +020021 formatargvalues() - format an argument spec
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000022 getouterframes(), getinnerframes() - get info about frames
23 currentframe() - get the current stack frame
24 stack(), trace() - get info about frames on the stack or in a traceback
Larry Hastings7c7cbfc2012-06-22 15:19:35 -070025
26 signature() - get a Signature object for the callable
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000027"""
28
29# This module is in the public domain. No warranties.
30
Larry Hastings7c7cbfc2012-06-22 15:19:35 -070031__author__ = ('Ka-Ping Yee <ping@lfw.org>',
32 'Yury Selivanov <yselivanov@sprymix.com>')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000033
Natefcfe80e2017-04-24 10:06:15 -070034import abc
Karthikeyan Singaravelan696136b2020-04-18 21:49:32 +053035import ast
Antoine Pitroua8723a02015-04-15 00:41:29 +020036import dis
Yury Selivanov75445082015-05-11 22:57:16 -040037import collections.abc
Yury Selivanov21e83a52014-03-27 11:23:13 -040038import enum
Brett Cannoncb66eb02012-05-11 12:58:42 -040039import importlib.machinery
40import itertools
Christian Heimes7131fd92008-02-19 14:21:46 +000041import linecache
Brett Cannoncb66eb02012-05-11 12:58:42 -040042import os
43import re
44import sys
45import tokenize
Larry Hastings2623c8c2014-02-08 22:15:29 -080046import token
Brett Cannoncb66eb02012-05-11 12:58:42 -040047import types
Brett Cannon2b88fcf2012-06-02 22:28:42 -040048import warnings
Larry Hastings7c7cbfc2012-06-22 15:19:35 -070049import functools
Nick Coghlan2f92e542012-06-23 19:39:55 +100050import builtins
Raymond Hettingera1a992c2005-03-11 06:46:45 +000051from operator import attrgetter
Inada Naoki21105512020-03-02 18:54:49 +090052from collections import namedtuple, OrderedDict
Nick Coghlan09c81232010-08-17 10:18:16 +000053
54# Create constants for the compiler flags in Include/code.h
Antoine Pitroua8723a02015-04-15 00:41:29 +020055# We try to get them from dis to avoid duplication
56mod_dict = globals()
57for k, v in dis.COMPILER_FLAG_NAMES.items():
58 mod_dict["CO_" + v] = k
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000059
Christian Heimesbe5b30b2008-03-03 19:18:51 +000060# See Include/object.h
61TPFLAGS_IS_ABSTRACT = 1 << 20
62
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000063# ----------------------------------------------------------- type-checking
64def ismodule(object):
65 """Return true if the object is a module.
66
67 Module objects provide these attributes:
Barry Warsaw28a691b2010-04-17 00:19:56 +000068 __cached__ pathname to byte compiled file
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000069 __doc__ documentation string
70 __file__ filename (missing for built-in modules)"""
Tim Peters28bc59f2001-09-16 08:40:16 +000071 return isinstance(object, types.ModuleType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000072
73def isclass(object):
74 """Return true if the object is a class.
75
76 Class objects provide these attributes:
77 __doc__ documentation string
78 __module__ name of module in which this class was defined"""
Benjamin Petersonc4656002009-01-17 22:41:18 +000079 return isinstance(object, type)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000080
81def ismethod(object):
82 """Return true if the object is an instance method.
83
84 Instance method objects provide these attributes:
85 __doc__ documentation string
86 __name__ name with which this method was defined
Christian Heimesff737952007-11-27 10:40:20 +000087 __func__ function object containing implementation of method
88 __self__ instance to which this method is bound"""
Tim Peters28bc59f2001-09-16 08:40:16 +000089 return isinstance(object, types.MethodType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000090
Tim Peters536d2262001-09-20 05:13:38 +000091def ismethoddescriptor(object):
Tim Petersf1d90b92001-09-20 05:47:55 +000092 """Return true if the object is a method descriptor.
93
94 But not if ismethod() or isclass() or isfunction() are true.
Tim Peters536d2262001-09-20 05:13:38 +000095
96 This is new in Python 2.2, and, for example, is true of int.__add__.
97 An object passing this test has a __get__ attribute but not a __set__
98 attribute, but beyond that the set of attributes varies. __name__ is
99 usually sensible, and __doc__ often is.
100
Tim Petersf1d90b92001-09-20 05:47:55 +0000101 Methods implemented via descriptors that also pass one of the other
102 tests return false from the ismethoddescriptor() test, simply because
103 the other tests promise more -- you can, e.g., count on having the
Christian Heimesff737952007-11-27 10:40:20 +0000104 __func__ attribute (etc) when an object passes ismethod()."""
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100105 if isclass(object) or ismethod(object) or isfunction(object):
106 # mutual exclusion
107 return False
108 tp = type(object)
109 return hasattr(tp, "__get__") and not hasattr(tp, "__set__")
Tim Peters536d2262001-09-20 05:13:38 +0000110
Martin v. Löwise59e2ba2003-05-03 09:09:02 +0000111def isdatadescriptor(object):
112 """Return true if the object is a data descriptor.
113
Aaron Hall, MBA4054b172018-05-20 19:46:42 -0400114 Data descriptors have a __set__ or a __delete__ attribute. Examples are
Martin v. Löwise59e2ba2003-05-03 09:09:02 +0000115 properties (defined in Python) and getsets and members (defined in C).
116 Typically, data descriptors will also have __name__ and __doc__ attributes
117 (properties, getsets, and members have both of these attributes), but this
118 is not guaranteed."""
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100119 if isclass(object) or ismethod(object) or isfunction(object):
120 # mutual exclusion
121 return False
122 tp = type(object)
Aaron Hall, MBA4054b172018-05-20 19:46:42 -0400123 return hasattr(tp, "__set__") or hasattr(tp, "__delete__")
Martin v. Löwise59e2ba2003-05-03 09:09:02 +0000124
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000125if hasattr(types, 'MemberDescriptorType'):
126 # CPython and equivalent
127 def ismemberdescriptor(object):
128 """Return true if the object is a member descriptor.
129
130 Member descriptors are specialized descriptors defined in extension
131 modules."""
132 return isinstance(object, types.MemberDescriptorType)
133else:
134 # Other implementations
135 def ismemberdescriptor(object):
136 """Return true if the object is a member descriptor.
137
138 Member descriptors are specialized descriptors defined in extension
139 modules."""
140 return False
141
142if hasattr(types, 'GetSetDescriptorType'):
143 # CPython and equivalent
144 def isgetsetdescriptor(object):
145 """Return true if the object is a getset descriptor.
146
147 getset descriptors are specialized descriptors defined in extension
148 modules."""
149 return isinstance(object, types.GetSetDescriptorType)
150else:
151 # Other implementations
152 def isgetsetdescriptor(object):
153 """Return true if the object is a getset descriptor.
154
155 getset descriptors are specialized descriptors defined in extension
156 modules."""
157 return False
158
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000159def isfunction(object):
160 """Return true if the object is a user-defined function.
161
162 Function objects provide these attributes:
163 __doc__ documentation string
164 __name__ name with which this function was defined
Neal Norwitz221085d2007-02-25 20:55:47 +0000165 __code__ code object containing compiled function bytecode
166 __defaults__ tuple of any default values for arguments
167 __globals__ global namespace in which this function was defined
168 __annotations__ dict of parameter annotations
169 __kwdefaults__ dict of keyword only parameters with defaults"""
Tim Peters28bc59f2001-09-16 08:40:16 +0000170 return isinstance(object, types.FunctionType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000171
Jeroen Demeyerfcef60f2019-04-02 16:03:42 +0200172def _has_code_flag(f, flag):
173 """Return true if ``f`` is a function (or a method or functools.partial
174 wrapper wrapping a function) whose code object has the given ``flag``
175 set in its flags."""
176 while ismethod(f):
177 f = f.__func__
178 f = functools._unwrap_partial(f)
179 if not isfunction(f):
180 return False
181 return bool(f.__code__.co_flags & flag)
182
Pablo Galindo7cd25432018-10-26 12:19:14 +0100183def isgeneratorfunction(obj):
Christian Heimes7131fd92008-02-19 14:21:46 +0000184 """Return true if the object is a user-defined generator function.
185
Martin Panter0f0eac42016-09-07 11:04:41 +0000186 Generator function objects provide the same attributes as functions.
187 See help(isfunction) for a list of attributes."""
Jeroen Demeyerfcef60f2019-04-02 16:03:42 +0200188 return _has_code_flag(obj, CO_GENERATOR)
Yury Selivanov75445082015-05-11 22:57:16 -0400189
Pablo Galindo7cd25432018-10-26 12:19:14 +0100190def iscoroutinefunction(obj):
Yury Selivanov75445082015-05-11 22:57:16 -0400191 """Return true if the object is a coroutine function.
192
Yury Selivanov4778e132016-11-08 12:23:09 -0500193 Coroutine functions are defined with "async def" syntax.
Yury Selivanov75445082015-05-11 22:57:16 -0400194 """
Jeroen Demeyerfcef60f2019-04-02 16:03:42 +0200195 return _has_code_flag(obj, CO_COROUTINE)
Yury Selivanov75445082015-05-11 22:57:16 -0400196
Pablo Galindo7cd25432018-10-26 12:19:14 +0100197def isasyncgenfunction(obj):
Yury Selivanov4778e132016-11-08 12:23:09 -0500198 """Return true if the object is an asynchronous generator function.
199
200 Asynchronous generator functions are defined with "async def"
201 syntax and have "yield" expressions in their body.
202 """
Jeroen Demeyerfcef60f2019-04-02 16:03:42 +0200203 return _has_code_flag(obj, CO_ASYNC_GENERATOR)
Yury Selivanoveb636452016-09-08 22:01:51 -0700204
205def isasyncgen(object):
Yury Selivanov4778e132016-11-08 12:23:09 -0500206 """Return true if the object is an asynchronous generator."""
Yury Selivanoveb636452016-09-08 22:01:51 -0700207 return isinstance(object, types.AsyncGeneratorType)
208
Christian Heimes7131fd92008-02-19 14:21:46 +0000209def isgenerator(object):
210 """Return true if the object is a generator.
211
212 Generator objects provide these attributes:
Ezio Melotti30b9d5d2013-08-17 15:50:46 +0300213 __iter__ defined to support iteration over container
Christian Heimes7131fd92008-02-19 14:21:46 +0000214 close raises a new GeneratorExit exception inside the
215 generator to terminate the iteration
216 gi_code code object
217 gi_frame frame object or possibly None once the generator has
218 been exhausted
219 gi_running set to 1 when generator is executing, 0 otherwise
220 next return the next item from the container
221 send resumes the generator and "sends" a value that becomes
222 the result of the current yield-expression
223 throw used to raise an exception inside the generator"""
Yury Selivanov5376ba92015-06-22 12:19:30 -0400224 return isinstance(object, types.GeneratorType)
Yury Selivanov75445082015-05-11 22:57:16 -0400225
226def iscoroutine(object):
227 """Return true if the object is a coroutine."""
Yury Selivanov5376ba92015-06-22 12:19:30 -0400228 return isinstance(object, types.CoroutineType)
Christian Heimes7131fd92008-02-19 14:21:46 +0000229
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400230def isawaitable(object):
Yury Selivanovc0215df2016-11-08 19:57:44 -0500231 """Return true if object can be passed to an ``await`` expression."""
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400232 return (isinstance(object, types.CoroutineType) or
233 isinstance(object, types.GeneratorType) and
Yury Selivanovc0215df2016-11-08 19:57:44 -0500234 bool(object.gi_code.co_flags & CO_ITERABLE_COROUTINE) or
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400235 isinstance(object, collections.abc.Awaitable))
236
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000237def istraceback(object):
238 """Return true if the object is a traceback.
239
240 Traceback objects provide these attributes:
241 tb_frame frame object at this level
242 tb_lasti index of last attempted instruction in bytecode
243 tb_lineno current line number in Python source code
244 tb_next next inner traceback object (called by this level)"""
Tim Peters28bc59f2001-09-16 08:40:16 +0000245 return isinstance(object, types.TracebackType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000246
247def isframe(object):
248 """Return true if the object is a frame object.
249
250 Frame objects provide these attributes:
251 f_back next outer frame object (this frame's caller)
252 f_builtins built-in namespace seen by this frame
253 f_code code object being executed in this frame
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000254 f_globals global namespace seen by this frame
255 f_lasti index of last attempted instruction in bytecode
256 f_lineno current line number in Python source code
257 f_locals local namespace seen by this frame
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000258 f_trace tracing function for this frame, or None"""
Tim Peters28bc59f2001-09-16 08:40:16 +0000259 return isinstance(object, types.FrameType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000260
261def iscode(object):
262 """Return true if the object is a code object.
263
264 Code objects provide these attributes:
Xiang Zhanga6902e62017-04-13 10:38:28 +0800265 co_argcount number of arguments (not including *, ** args
266 or keyword only arguments)
267 co_code string of raw compiled bytecode
268 co_cellvars tuple of names of cell variables
269 co_consts tuple of constants used in the bytecode
270 co_filename name of file in which this code object was created
271 co_firstlineno number of first line in Python source code
272 co_flags bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg
273 | 16=nested | 32=generator | 64=nofree | 128=coroutine
274 | 256=iterable_coroutine | 512=async_generator
275 co_freevars tuple of names of free variables
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100276 co_posonlyargcount number of positional only arguments
Xiang Zhanga6902e62017-04-13 10:38:28 +0800277 co_kwonlyargcount number of keyword only arguments (not including ** arg)
278 co_lnotab encoded mapping of line numbers to bytecode indices
279 co_name name with which this code object was defined
280 co_names tuple of names of local variables
281 co_nlocals number of local variables
282 co_stacksize virtual machine stack space required
283 co_varnames tuple of names of arguments and local variables"""
Tim Peters28bc59f2001-09-16 08:40:16 +0000284 return isinstance(object, types.CodeType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000285
286def isbuiltin(object):
287 """Return true if the object is a built-in function or method.
288
289 Built-in functions and methods provide these attributes:
290 __doc__ documentation string
291 __name__ original name of this function or method
292 __self__ instance to which a method is bound, or None"""
Tim Peters28bc59f2001-09-16 08:40:16 +0000293 return isinstance(object, types.BuiltinFunctionType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000294
295def isroutine(object):
296 """Return true if the object is any kind of function or method."""
Tim Peters536d2262001-09-20 05:13:38 +0000297 return (isbuiltin(object)
298 or isfunction(object)
299 or ismethod(object)
300 or ismethoddescriptor(object))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000301
Christian Heimesbe5b30b2008-03-03 19:18:51 +0000302def isabstract(object):
303 """Return true if the object is an abstract base class (ABC)."""
Natefcfe80e2017-04-24 10:06:15 -0700304 if not isinstance(object, type):
305 return False
306 if object.__flags__ & TPFLAGS_IS_ABSTRACT:
307 return True
308 if not issubclass(type(object), abc.ABCMeta):
309 return False
310 if hasattr(object, '__abstractmethods__'):
311 # It looks like ABCMeta.__new__ has finished running;
312 # TPFLAGS_IS_ABSTRACT should have been accurate.
313 return False
314 # It looks like ABCMeta.__new__ has not finished running yet; we're
315 # probably in __init_subclass__. We'll look for abstractmethods manually.
316 for name, value in object.__dict__.items():
317 if getattr(value, "__isabstractmethod__", False):
318 return True
319 for base in object.__bases__:
320 for name in getattr(base, "__abstractmethods__", ()):
321 value = getattr(object, name, None)
322 if getattr(value, "__isabstractmethod__", False):
323 return True
324 return False
Christian Heimesbe5b30b2008-03-03 19:18:51 +0000325
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000326def getmembers(object, predicate=None):
327 """Return all members of an object as (name, value) pairs sorted by name.
328 Optionally, only return members that satisfy a given predicate."""
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100329 if isclass(object):
330 mro = (object,) + getmro(object)
331 else:
332 mro = ()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000333 results = []
Ethan Furmane03ea372013-09-25 07:14:41 -0700334 processed = set()
335 names = dir(object)
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700336 # :dd any DynamicClassAttributes to the list of names if object is a class;
Ethan Furmane03ea372013-09-25 07:14:41 -0700337 # this may result in duplicate entries if, for example, a virtual
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700338 # attribute with the same name as a DynamicClassAttribute exists
Ethan Furmane03ea372013-09-25 07:14:41 -0700339 try:
340 for base in object.__bases__:
341 for k, v in base.__dict__.items():
342 if isinstance(v, types.DynamicClassAttribute):
343 names.append(k)
344 except AttributeError:
345 pass
346 for key in names:
Ethan Furman63c141c2013-10-18 00:27:39 -0700347 # First try to get the value via getattr. Some descriptors don't
348 # like calling their __get__ (see bug #1785), so fall back to
349 # looking in the __dict__.
350 try:
351 value = getattr(object, key)
352 # handle the duplicate key
353 if key in processed:
354 raise AttributeError
355 except AttributeError:
356 for base in mro:
357 if key in base.__dict__:
358 value = base.__dict__[key]
359 break
360 else:
361 # could be a (currently) missing slot member, or a buggy
362 # __dir__; discard and move on
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100363 continue
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000364 if not predicate or predicate(value):
365 results.append((key, value))
Ethan Furmane03ea372013-09-25 07:14:41 -0700366 processed.add(key)
367 results.sort(key=lambda pair: pair[0])
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000368 return results
369
Christian Heimes25bb7832008-01-11 16:17:00 +0000370Attribute = namedtuple('Attribute', 'name kind defining_class object')
371
Tim Peters13b49d32001-09-23 02:00:29 +0000372def classify_class_attrs(cls):
373 """Return list of attribute-descriptor tuples.
374
375 For each name in dir(cls), the return list contains a 4-tuple
376 with these elements:
377
378 0. The name (a string).
379
380 1. The kind of attribute this is, one of these strings:
381 'class method' created via classmethod()
382 'static method' created via staticmethod()
383 'property' created via property()
Ethan Furmane03ea372013-09-25 07:14:41 -0700384 'method' any other flavor of method or descriptor
Tim Peters13b49d32001-09-23 02:00:29 +0000385 'data' not a method
386
387 2. The class which defined this attribute (a class).
388
Ethan Furmane03ea372013-09-25 07:14:41 -0700389 3. The object as obtained by calling getattr; if this fails, or if the
390 resulting object does not live anywhere in the class' mro (including
391 metaclasses) then the object is looked up in the defining class's
392 dict (found by walking the mro).
Ethan Furman668dede2013-09-14 18:53:26 -0700393
394 If one of the items in dir(cls) is stored in the metaclass it will now
395 be discovered and not have None be listed as the class in which it was
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700396 defined. Any items whose home class cannot be discovered are skipped.
Tim Peters13b49d32001-09-23 02:00:29 +0000397 """
398
399 mro = getmro(cls)
Ethan Furman668dede2013-09-14 18:53:26 -0700400 metamro = getmro(type(cls)) # for attributes stored in the metaclass
Jon Dufresne39726282017-05-18 07:35:54 -0700401 metamro = tuple(cls for cls in metamro if cls not in (type, object))
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700402 class_bases = (cls,) + mro
403 all_bases = class_bases + metamro
Tim Peters13b49d32001-09-23 02:00:29 +0000404 names = dir(cls)
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700405 # :dd any DynamicClassAttributes to the list of names;
Ethan Furmane03ea372013-09-25 07:14:41 -0700406 # this may result in duplicate entries if, for example, a virtual
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700407 # attribute with the same name as a DynamicClassAttribute exists.
Ethan Furman63c141c2013-10-18 00:27:39 -0700408 for base in mro:
Ethan Furmane03ea372013-09-25 07:14:41 -0700409 for k, v in base.__dict__.items():
410 if isinstance(v, types.DynamicClassAttribute):
411 names.append(k)
Tim Peters13b49d32001-09-23 02:00:29 +0000412 result = []
Ethan Furmane03ea372013-09-25 07:14:41 -0700413 processed = set()
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700414
Tim Peters13b49d32001-09-23 02:00:29 +0000415 for name in names:
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100416 # Get the object associated with the name, and where it was defined.
Ethan Furmane03ea372013-09-25 07:14:41 -0700417 # Normal objects will be looked up with both getattr and directly in
418 # its class' dict (in case getattr fails [bug #1785], and also to look
419 # for a docstring).
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700420 # For DynamicClassAttributes on the second pass we only look in the
Ethan Furmane03ea372013-09-25 07:14:41 -0700421 # class's dict.
422 #
Tim Peters13b49d32001-09-23 02:00:29 +0000423 # Getting an obj from the __dict__ sometimes reveals more than
424 # using getattr. Static and class methods are dramatic examples.
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100425 homecls = None
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700426 get_obj = None
427 dict_obj = None
Ethan Furmane03ea372013-09-25 07:14:41 -0700428 if name not in processed:
429 try:
Ethan Furmana8b07072013-10-18 01:22:08 -0700430 if name == '__dict__':
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700431 raise Exception("__dict__ is special, don't want the proxy")
Ethan Furmane03ea372013-09-25 07:14:41 -0700432 get_obj = getattr(cls, name)
433 except Exception as exc:
434 pass
435 else:
Ethan Furmane03ea372013-09-25 07:14:41 -0700436 homecls = getattr(get_obj, "__objclass__", homecls)
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700437 if homecls not in class_bases:
Ethan Furmane03ea372013-09-25 07:14:41 -0700438 # if the resulting object does not live somewhere in the
Ethan Furman63c141c2013-10-18 00:27:39 -0700439 # mro, drop it and search the mro manually
Ethan Furmane03ea372013-09-25 07:14:41 -0700440 homecls = None
Ethan Furman63c141c2013-10-18 00:27:39 -0700441 last_cls = None
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700442 # first look in the classes
443 for srch_cls in class_bases:
Ethan Furman63c141c2013-10-18 00:27:39 -0700444 srch_obj = getattr(srch_cls, name, None)
Yury Selivanovbf341fb2015-05-21 15:41:57 -0400445 if srch_obj is get_obj:
Ethan Furman63c141c2013-10-18 00:27:39 -0700446 last_cls = srch_cls
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700447 # then check the metaclasses
448 for srch_cls in metamro:
449 try:
450 srch_obj = srch_cls.__getattr__(cls, name)
451 except AttributeError:
452 continue
Yury Selivanovbf341fb2015-05-21 15:41:57 -0400453 if srch_obj is get_obj:
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700454 last_cls = srch_cls
Ethan Furman63c141c2013-10-18 00:27:39 -0700455 if last_cls is not None:
456 homecls = last_cls
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700457 for base in all_bases:
Ethan Furmane03ea372013-09-25 07:14:41 -0700458 if name in base.__dict__:
459 dict_obj = base.__dict__[name]
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700460 if homecls not in metamro:
461 homecls = base
Ethan Furmane03ea372013-09-25 07:14:41 -0700462 break
Ethan Furman63c141c2013-10-18 00:27:39 -0700463 if homecls is None:
464 # unable to locate the attribute anywhere, most likely due to
465 # buggy custom __dir__; discard and move on
466 continue
Yury Selivanovbf341fb2015-05-21 15:41:57 -0400467 obj = get_obj if get_obj is not None else dict_obj
Ethan Furmane03ea372013-09-25 07:14:41 -0700468 # Classify the object or its descriptor.
Serhiy Storchaka3327a2d2017-12-15 14:13:41 +0200469 if isinstance(dict_obj, (staticmethod, types.BuiltinMethodType)):
Tim Peters13b49d32001-09-23 02:00:29 +0000470 kind = "static method"
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700471 obj = dict_obj
Serhiy Storchaka3327a2d2017-12-15 14:13:41 +0200472 elif isinstance(dict_obj, (classmethod, types.ClassMethodDescriptorType)):
Tim Peters13b49d32001-09-23 02:00:29 +0000473 kind = "class method"
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700474 obj = dict_obj
475 elif isinstance(dict_obj, property):
Tim Peters13b49d32001-09-23 02:00:29 +0000476 kind = "property"
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700477 obj = dict_obj
Yury Selivanov0860a0b2014-01-31 14:28:44 -0500478 elif isroutine(obj):
Tim Peters13b49d32001-09-23 02:00:29 +0000479 kind = "method"
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100480 else:
Ethan Furmane03ea372013-09-25 07:14:41 -0700481 kind = "data"
Christian Heimes25bb7832008-01-11 16:17:00 +0000482 result.append(Attribute(name, kind, homecls, obj))
Ethan Furmane03ea372013-09-25 07:14:41 -0700483 processed.add(name)
Tim Peters13b49d32001-09-23 02:00:29 +0000484 return result
485
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000486# ----------------------------------------------------------- class helpers
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000487
488def getmro(cls):
489 "Return tuple of base classes (including cls) in method resolution order."
Benjamin Petersonb82c8e52010-11-04 00:38:49 +0000490 return cls.__mro__
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000491
Nick Coghlane8c45d62013-07-28 20:00:01 +1000492# -------------------------------------------------------- function helpers
493
494def unwrap(func, *, stop=None):
495 """Get the object wrapped by *func*.
496
497 Follows the chain of :attr:`__wrapped__` attributes returning the last
498 object in the chain.
499
500 *stop* is an optional callback accepting an object in the wrapper chain
501 as its sole argument that allows the unwrapping to be terminated early if
502 the callback returns a true value. If the callback never returns a true
503 value, the last object in the chain is returned as usual. For example,
504 :func:`signature` uses this to stop unwrapping if any object in the
505 chain has a ``__signature__`` attribute defined.
506
507 :exc:`ValueError` is raised if a cycle is encountered.
508
509 """
510 if stop is None:
511 def _is_wrapper(f):
512 return hasattr(f, '__wrapped__')
513 else:
514 def _is_wrapper(f):
515 return hasattr(f, '__wrapped__') and not stop(f)
516 f = func # remember the original func for error reporting
Thomas Kluyverf9169ce2017-05-23 04:27:52 +0100517 # Memoise by id to tolerate non-hashable objects, but store objects to
518 # ensure they aren't destroyed, which would allow their IDs to be reused.
519 memo = {id(f): f}
520 recursion_limit = sys.getrecursionlimit()
Nick Coghlane8c45d62013-07-28 20:00:01 +1000521 while _is_wrapper(func):
522 func = func.__wrapped__
523 id_func = id(func)
Thomas Kluyverf9169ce2017-05-23 04:27:52 +0100524 if (id_func in memo) or (len(memo) >= recursion_limit):
Nick Coghlane8c45d62013-07-28 20:00:01 +1000525 raise ValueError('wrapper loop when unwrapping {!r}'.format(f))
Thomas Kluyverf9169ce2017-05-23 04:27:52 +0100526 memo[id_func] = func
Nick Coghlane8c45d62013-07-28 20:00:01 +1000527 return func
528
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000529# -------------------------------------------------- source code extraction
530def indentsize(line):
531 """Return the indent size, in spaces, at the start of a line of text."""
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000532 expline = line.expandtabs()
533 return len(expline) - len(expline.lstrip())
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000534
Serhiy Storchaka5cf2b722015-04-03 22:38:53 +0300535def _findclass(func):
536 cls = sys.modules.get(func.__module__)
537 if cls is None:
538 return None
539 for name in func.__qualname__.split('.')[:-1]:
540 cls = getattr(cls, name)
541 if not isclass(cls):
542 return None
543 return cls
544
545def _finddoc(obj):
Serhiy Storchaka08b47c32020-05-18 20:25:07 +0300546 if isclass(obj):
547 for base in obj.__mro__:
548 if base is not object:
549 try:
550 doc = base.__doc__
551 except AttributeError:
552 continue
553 if doc is not None:
554 return doc
555 return None
556
Serhiy Storchaka5cf2b722015-04-03 22:38:53 +0300557 if ismethod(obj):
558 name = obj.__func__.__name__
559 self = obj.__self__
560 if (isclass(self) and
561 getattr(getattr(self, name, None), '__func__') is obj.__func__):
562 # classmethod
563 cls = self
564 else:
565 cls = self.__class__
566 elif isfunction(obj):
567 name = obj.__name__
568 cls = _findclass(obj)
569 if cls is None or getattr(cls, name) is not obj:
570 return None
571 elif isbuiltin(obj):
572 name = obj.__name__
573 self = obj.__self__
574 if (isclass(self) and
575 self.__qualname__ + '.' + name == obj.__qualname__):
576 # classmethod
577 cls = self
578 else:
579 cls = self.__class__
Serhiy Storchakaac4bdcc2015-10-29 08:15:50 +0200580 # Should be tested before isdatadescriptor().
581 elif isinstance(obj, property):
582 func = obj.fget
583 name = func.__name__
584 cls = _findclass(func)
585 if cls is None or getattr(cls, name) is not obj:
586 return None
Serhiy Storchaka5cf2b722015-04-03 22:38:53 +0300587 elif ismethoddescriptor(obj) or isdatadescriptor(obj):
588 name = obj.__name__
589 cls = obj.__objclass__
590 if getattr(cls, name) is not obj:
591 return None
Raymond Hettingerd1e768a2019-03-25 13:01:13 -0700592 if ismemberdescriptor(obj):
593 slots = getattr(cls, '__slots__', None)
594 if isinstance(slots, dict) and name in slots:
595 return slots[name]
Serhiy Storchaka5cf2b722015-04-03 22:38:53 +0300596 else:
597 return None
Serhiy Storchaka5cf2b722015-04-03 22:38:53 +0300598 for base in cls.__mro__:
599 try:
Serhiy Storchaka08b47c32020-05-18 20:25:07 +0300600 doc = getattr(base, name).__doc__
Serhiy Storchaka5cf2b722015-04-03 22:38:53 +0300601 except AttributeError:
602 continue
603 if doc is not None:
604 return doc
605 return None
606
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000607def getdoc(object):
608 """Get the documentation string for an object.
609
610 All tabs are expanded to spaces. To clean up docstrings that are
611 indented to line up with blocks of code, any whitespace than can be
612 uniformly removed from the second line onwards is removed."""
Serhiy Storchaka08b47c32020-05-18 20:25:07 +0300613 try:
614 doc = object.__doc__
615 except AttributeError:
616 return None
Serhiy Storchaka5cf2b722015-04-03 22:38:53 +0300617 if doc is None:
618 try:
619 doc = _finddoc(object)
620 except (AttributeError, TypeError):
621 return None
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000622 if not isinstance(doc, str):
Tim Peters24008312002-03-17 18:56:20 +0000623 return None
Georg Brandl0c77a822008-06-10 16:37:50 +0000624 return cleandoc(doc)
625
626def cleandoc(doc):
627 """Clean up indentation from docstrings.
628
629 Any whitespace that can be uniformly removed from the second line
630 onwards is removed."""
Tim Peters24008312002-03-17 18:56:20 +0000631 try:
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000632 lines = doc.expandtabs().split('\n')
Tim Peters24008312002-03-17 18:56:20 +0000633 except UnicodeError:
634 return None
635 else:
Ka-Ping Yeea59ef7b2002-11-30 03:53:15 +0000636 # Find minimum indentation of any non-blank lines after first line.
Christian Heimesa37d4c62007-12-04 23:02:19 +0000637 margin = sys.maxsize
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000638 for line in lines[1:]:
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000639 content = len(line.lstrip())
Ka-Ping Yeea59ef7b2002-11-30 03:53:15 +0000640 if content:
641 indent = len(line) - content
642 margin = min(margin, indent)
643 # Remove indentation.
644 if lines:
645 lines[0] = lines[0].lstrip()
Christian Heimesa37d4c62007-12-04 23:02:19 +0000646 if margin < sys.maxsize:
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000647 for i in range(1, len(lines)): lines[i] = lines[i][margin:]
Ka-Ping Yeea59ef7b2002-11-30 03:53:15 +0000648 # Remove any trailing or leading blank lines.
649 while lines and not lines[-1]:
650 lines.pop()
651 while lines and not lines[0]:
652 lines.pop(0)
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000653 return '\n'.join(lines)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000654
655def getfile(object):
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000656 """Work out which source or compiled file an object was defined in."""
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000657 if ismodule(object):
Jason R. Coombsb9650a02018-03-05 18:29:08 -0500658 if getattr(object, '__file__', None):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000659 return object.__file__
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000660 raise TypeError('{!r} is a built-in module'.format(object))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000661 if isclass(object):
Yury Selivanov2eed8b72014-01-27 13:24:56 -0500662 if hasattr(object, '__module__'):
Philipp Ad407d2a2019-06-08 14:05:46 +0200663 module = sys.modules.get(object.__module__)
664 if getattr(module, '__file__', None):
665 return module.__file__
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000666 raise TypeError('{!r} is a built-in class'.format(object))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000667 if ismethod(object):
Christian Heimesff737952007-11-27 10:40:20 +0000668 object = object.__func__
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000669 if isfunction(object):
Neal Norwitz221085d2007-02-25 20:55:47 +0000670 object = object.__code__
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000671 if istraceback(object):
672 object = object.tb_frame
673 if isframe(object):
674 object = object.f_code
675 if iscode(object):
676 return object.co_filename
Thomas Kluyvere968bc732017-10-24 13:42:36 +0100677 raise TypeError('module, class, method, function, traceback, frame, or '
678 'code object was expected, got {}'.format(
679 type(object).__name__))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000680
Ka-Ping Yee4d6fc7f2001-04-10 11:43:00 +0000681def getmodulename(path):
682 """Return the module name for a given file, or None."""
Nick Coghlan76e07702012-07-18 23:14:57 +1000683 fname = os.path.basename(path)
684 # Check for paths that look like an actual module file
685 suffixes = [(-len(suffix), suffix)
686 for suffix in importlib.machinery.all_suffixes()]
687 suffixes.sort() # try longest suffixes first, in case they overlap
688 for neglen, suffix in suffixes:
689 if fname.endswith(suffix):
690 return fname[:neglen]
691 return None
Ka-Ping Yee4d6fc7f2001-04-10 11:43:00 +0000692
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000693def getsourcefile(object):
R. David Murraya1b37402010-06-17 02:04:29 +0000694 """Return the filename that can be used to locate an object's source.
695 Return None if no way can be identified to get the source.
696 """
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000697 filename = getfile(object)
Brett Cannoncb66eb02012-05-11 12:58:42 -0400698 all_bytecode_suffixes = importlib.machinery.DEBUG_BYTECODE_SUFFIXES[:]
699 all_bytecode_suffixes += importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES[:]
700 if any(filename.endswith(s) for s in all_bytecode_suffixes):
701 filename = (os.path.splitext(filename)[0] +
702 importlib.machinery.SOURCE_SUFFIXES[0])
703 elif any(filename.endswith(s) for s in
704 importlib.machinery.EXTENSION_SUFFIXES):
705 return None
Thomas Wouters477c8d52006-05-27 19:21:47 +0000706 if os.path.exists(filename):
707 return filename
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000708 # only return a non-existent filename if the module has a PEP 302 loader
Brett Cannon4c14b5d2013-05-04 13:56:58 -0400709 if getattr(getmodule(object, filename), '__loader__', None) is not None:
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000710 return filename
R. David Murraya1b37402010-06-17 02:04:29 +0000711 # or it is in the linecache
712 if filename in linecache.cache:
713 return filename
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000714
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000715def getabsfile(object, _filename=None):
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000716 """Return an absolute path to the source or compiled file for an object.
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000717
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000718 The idea is for each object to have a unique origin, so this routine
719 normalizes the result as much as possible."""
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000720 if _filename is None:
721 _filename = getsourcefile(object) or getfile(object)
722 return os.path.normcase(os.path.abspath(_filename))
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000723
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000724modulesbyfile = {}
Thomas Wouters89f507f2006-12-13 04:49:30 +0000725_filesbymodname = {}
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000726
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000727def getmodule(object, _filename=None):
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000728 """Return the module an object was defined in, or None if not found."""
Ka-Ping Yee202c99b2001-04-13 09:15:08 +0000729 if ismodule(object):
730 return object
Johannes Gijsbers93245262004-09-11 15:53:22 +0000731 if hasattr(object, '__module__'):
Ka-Ping Yee8b58b842001-03-01 13:56:16 +0000732 return sys.modules.get(object.__module__)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000733 # Try the filename to modulename cache
734 if _filename is not None and _filename in modulesbyfile:
735 return sys.modules.get(modulesbyfile[_filename])
736 # Try the cache again with the absolute file name
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000737 try:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000738 file = getabsfile(object, _filename)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000739 except TypeError:
740 return None
Raymond Hettinger54f02222002-06-01 14:18:47 +0000741 if file in modulesbyfile:
Ka-Ping Yeeb38bbbd2003-03-28 16:29:50 +0000742 return sys.modules.get(modulesbyfile[file])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000743 # Update the filename to module name cache and check yet again
744 # Copy sys.modules in order to cope with changes while iterating
Gregory P. Smith85cf1d52020-03-04 16:45:22 -0800745 for modname, module in sys.modules.copy().items():
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000746 if ismodule(module) and hasattr(module, '__file__'):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000747 f = module.__file__
748 if f == _filesbymodname.get(modname, None):
749 # Have already mapped this module, so skip it
750 continue
751 _filesbymodname[modname] = f
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000752 f = getabsfile(module)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000753 # Always map to the name the module knows itself by
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000754 modulesbyfile[f] = modulesbyfile[
755 os.path.realpath(f)] = module.__name__
Raymond Hettinger54f02222002-06-01 14:18:47 +0000756 if file in modulesbyfile:
Ka-Ping Yeeb38bbbd2003-03-28 16:29:50 +0000757 return sys.modules.get(modulesbyfile[file])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000758 # Check the main module
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000759 main = sys.modules['__main__']
Brett Cannon4a671fe2003-06-15 22:33:28 +0000760 if not hasattr(object, '__name__'):
761 return None
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000762 if hasattr(main, object.__name__):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000763 mainobject = getattr(main, object.__name__)
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000764 if mainobject is object:
765 return main
Thomas Wouters89f507f2006-12-13 04:49:30 +0000766 # Check builtins
Georg Brandl1a3284e2007-12-02 09:40:06 +0000767 builtin = sys.modules['builtins']
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000768 if hasattr(builtin, object.__name__):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000769 builtinobject = getattr(builtin, object.__name__)
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000770 if builtinobject is object:
771 return builtin
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000772
Karthikeyan Singaravelan696136b2020-04-18 21:49:32 +0530773
774class ClassFoundException(Exception):
775 pass
776
777
778class _ClassFinder(ast.NodeVisitor):
779
780 def __init__(self, qualname):
781 self.stack = []
782 self.qualname = qualname
783
784 def visit_FunctionDef(self, node):
785 self.stack.append(node.name)
786 self.stack.append('<locals>')
787 self.generic_visit(node)
788 self.stack.pop()
789 self.stack.pop()
790
791 visit_AsyncFunctionDef = visit_FunctionDef
792
793 def visit_ClassDef(self, node):
794 self.stack.append(node.name)
795 if self.qualname == '.'.join(self.stack):
796 # Return the decorator for the class if present
797 if node.decorator_list:
798 line_number = node.decorator_list[0].lineno
799 else:
800 line_number = node.lineno
801
802 # decrement by one since lines starts with indexing by zero
803 line_number -= 1
804 raise ClassFoundException(line_number)
805 self.generic_visit(node)
806 self.stack.pop()
807
808
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000809def findsource(object):
810 """Return the entire source file and starting line number for an object.
811
812 The argument may be a module, class, method, function, traceback, frame,
813 or code object. The source code is returned as a list of all the lines
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200814 in the file and the line number indexes a line in that list. An OSError
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000815 is raised if the source code cannot be retrieved."""
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500816
Yury Selivanovef1e7502014-12-08 16:05:34 -0500817 file = getsourcefile(object)
818 if file:
819 # Invalidate cache if needed.
820 linecache.checkcache(file)
821 else:
822 file = getfile(object)
823 # Allow filenames in form of "<something>" to pass through.
824 # `doctest` monkeypatches `linecache` module to enable
825 # inspection, so let `linecache.getlines` to be called.
826 if not (file.startswith('<') and file.endswith('>')):
827 raise OSError('source code not available')
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500828
Thomas Wouters89f507f2006-12-13 04:49:30 +0000829 module = getmodule(object, file)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000830 if module:
831 lines = linecache.getlines(file, module.__dict__)
832 else:
833 lines = linecache.getlines(file)
Neil Schemenauerf06f8532002-03-23 23:51:04 +0000834 if not lines:
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200835 raise OSError('could not get source code')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000836
837 if ismodule(object):
838 return lines, 0
839
840 if isclass(object):
Karthikeyan Singaravelan696136b2020-04-18 21:49:32 +0530841 qualname = object.__qualname__
842 source = ''.join(lines)
843 tree = ast.parse(source)
844 class_finder = _ClassFinder(qualname)
845 try:
846 class_finder.visit(tree)
847 except ClassFoundException as e:
848 line_number = e.args[0]
849 return lines, line_number
Jeremy Hyltonab919022003-06-27 18:41:20 +0000850 else:
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200851 raise OSError('could not find class definition')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000852
853 if ismethod(object):
Christian Heimesff737952007-11-27 10:40:20 +0000854 object = object.__func__
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000855 if isfunction(object):
Neal Norwitz221085d2007-02-25 20:55:47 +0000856 object = object.__code__
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000857 if istraceback(object):
858 object = object.tb_frame
859 if isframe(object):
860 object = object.f_code
861 if iscode(object):
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000862 if not hasattr(object, 'co_firstlineno'):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200863 raise OSError('could not find function definition')
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000864 lnum = object.co_firstlineno - 1
Yury Selivanove4e811d2015-07-21 19:01:52 +0300865 pat = re.compile(r'^(\s*def\s)|(\s*async\s+def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000866 while lnum > 0:
Ka-Ping Yeea6e59712001-03-10 09:31:55 +0000867 if pat.match(lines[lnum]): break
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000868 lnum = lnum - 1
869 return lines, lnum
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200870 raise OSError('could not find code object')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000871
872def getcomments(object):
Jeremy Hyltonb4c17c82002-03-28 23:01:56 +0000873 """Get lines of comments immediately preceding an object's source code.
874
875 Returns None when source can't be found.
876 """
877 try:
878 lines, lnum = findsource(object)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200879 except (OSError, TypeError):
Jeremy Hyltonb4c17c82002-03-28 23:01:56 +0000880 return None
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000881
882 if ismodule(object):
883 # Look for a comment block at the top of the file.
884 start = 0
Ka-Ping Yeeb910efe2001-04-12 13:17:17 +0000885 if lines and lines[0][:2] == '#!': start = 1
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000886 while start < len(lines) and lines[start].strip() in ('', '#'):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000887 start = start + 1
Ka-Ping Yeeb910efe2001-04-12 13:17:17 +0000888 if start < len(lines) and lines[start][:1] == '#':
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000889 comments = []
890 end = start
891 while end < len(lines) and lines[end][:1] == '#':
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000892 comments.append(lines[end].expandtabs())
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000893 end = end + 1
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000894 return ''.join(comments)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000895
896 # Look for a preceding block of comments at the same indentation.
897 elif lnum > 0:
898 indent = indentsize(lines[lnum])
899 end = lnum - 1
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000900 if end >= 0 and lines[end].lstrip()[:1] == '#' and \
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000901 indentsize(lines[end]) == indent:
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000902 comments = [lines[end].expandtabs().lstrip()]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000903 if end > 0:
904 end = end - 1
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000905 comment = lines[end].expandtabs().lstrip()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000906 while comment[:1] == '#' and indentsize(lines[end]) == indent:
907 comments[:0] = [comment]
908 end = end - 1
909 if end < 0: break
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000910 comment = lines[end].expandtabs().lstrip()
911 while comments and comments[0].strip() == '#':
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000912 comments[:1] = []
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000913 while comments and comments[-1].strip() == '#':
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000914 comments[-1:] = []
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000915 return ''.join(comments)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000916
Tim Peters4efb6e92001-06-29 23:51:08 +0000917class EndOfBlock(Exception): pass
918
919class BlockFinder:
920 """Provide a tokeneater() method to detect the end of a code block."""
921 def __init__(self):
922 self.indent = 0
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000923 self.islambda = False
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000924 self.started = False
925 self.passline = False
Meador Inge5b718d72015-07-23 22:49:37 -0500926 self.indecorator = False
927 self.decoratorhasargs = False
Armin Rigodd5c0232005-09-25 11:45:45 +0000928 self.last = 1
Tim Peters4efb6e92001-06-29 23:51:08 +0000929
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000930 def tokeneater(self, type, token, srowcol, erowcol, line):
Meador Inge5b718d72015-07-23 22:49:37 -0500931 if not self.started and not self.indecorator:
932 # skip any decorators
933 if token == "@":
934 self.indecorator = True
Armin Rigodd5c0232005-09-25 11:45:45 +0000935 # look for the first "def", "class" or "lambda"
Meador Inge5b718d72015-07-23 22:49:37 -0500936 elif token in ("def", "class", "lambda"):
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000937 if token == "lambda":
938 self.islambda = True
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000939 self.started = True
Armin Rigodd5c0232005-09-25 11:45:45 +0000940 self.passline = True # skip to the end of the line
Meador Inge5b718d72015-07-23 22:49:37 -0500941 elif token == "(":
942 if self.indecorator:
943 self.decoratorhasargs = True
944 elif token == ")":
945 if self.indecorator:
946 self.indecorator = False
947 self.decoratorhasargs = False
Tim Peters4efb6e92001-06-29 23:51:08 +0000948 elif type == tokenize.NEWLINE:
Armin Rigodd5c0232005-09-25 11:45:45 +0000949 self.passline = False # stop skipping when a NEWLINE is seen
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000950 self.last = srowcol[0]
Armin Rigodd5c0232005-09-25 11:45:45 +0000951 if self.islambda: # lambdas always end at the first NEWLINE
952 raise EndOfBlock
Meador Inge5b718d72015-07-23 22:49:37 -0500953 # hitting a NEWLINE when in a decorator without args
954 # ends the decorator
955 if self.indecorator and not self.decoratorhasargs:
956 self.indecorator = False
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000957 elif self.passline:
958 pass
Tim Peters4efb6e92001-06-29 23:51:08 +0000959 elif type == tokenize.INDENT:
960 self.indent = self.indent + 1
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000961 self.passline = True
Tim Peters4efb6e92001-06-29 23:51:08 +0000962 elif type == tokenize.DEDENT:
963 self.indent = self.indent - 1
Armin Rigodd5c0232005-09-25 11:45:45 +0000964 # the end of matching indent/dedent pairs end a block
965 # (note that this only works for "def"/"class" blocks,
966 # not e.g. for "if: else:" or "try: finally:" blocks)
967 if self.indent <= 0:
968 raise EndOfBlock
969 elif self.indent == 0 and type not in (tokenize.COMMENT, tokenize.NL):
970 # any other token on the same indentation level end the previous
971 # block as well, except the pseudo-tokens COMMENT and NL.
972 raise EndOfBlock
Tim Peters4efb6e92001-06-29 23:51:08 +0000973
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000974def getblock(lines):
975 """Extract the block of code at the top of the given list of lines."""
Armin Rigodd5c0232005-09-25 11:45:45 +0000976 blockfinder = BlockFinder()
Tim Peters4efb6e92001-06-29 23:51:08 +0000977 try:
Trent Nelson428de652008-03-18 22:41:35 +0000978 tokens = tokenize.generate_tokens(iter(lines).__next__)
979 for _token in tokens:
980 blockfinder.tokeneater(*_token)
Armin Rigodd5c0232005-09-25 11:45:45 +0000981 except (EndOfBlock, IndentationError):
982 pass
983 return lines[:blockfinder.last]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000984
985def getsourcelines(object):
986 """Return a list of source lines and starting line number for an object.
987
988 The argument may be a module, class, method, function, traceback, frame,
989 or code object. The source code is returned as a list of the lines
990 corresponding to the object and the line number indicates where in the
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200991 original source file the first line of code was found. An OSError is
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000992 raised if the source code cannot be retrieved."""
Yury Selivanov081bbf62014-09-26 17:34:54 -0400993 object = unwrap(object)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000994 lines, lnum = findsource(object)
995
Vladimir Matveev91cb2982018-08-24 07:18:00 -0700996 if istraceback(object):
997 object = object.tb_frame
998
999 # for module or frame that corresponds to module, return all source lines
1000 if (ismodule(object) or
1001 (isframe(object) and object.f_code.co_name == "<module>")):
Meador Inge5b718d72015-07-23 22:49:37 -05001002 return lines, 0
1003 else:
1004 return getblock(lines[lnum:]), lnum + 1
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001005
1006def getsource(object):
1007 """Return the text of the source code for an object.
1008
1009 The argument may be a module, class, method, function, traceback, frame,
1010 or code object. The source code is returned as a single string. An
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02001011 OSError is raised if the source code cannot be retrieved."""
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001012 lines, lnum = getsourcelines(object)
Neal Norwitz9d72bb42007-04-17 08:48:32 +00001013 return ''.join(lines)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001014
1015# --------------------------------------------------- class tree extraction
1016def walktree(classes, children, parent):
1017 """Recursive helper function for getclasstree()."""
1018 results = []
Raymond Hettingera1a992c2005-03-11 06:46:45 +00001019 classes.sort(key=attrgetter('__module__', '__name__'))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001020 for c in classes:
1021 results.append((c, c.__bases__))
Raymond Hettinger54f02222002-06-01 14:18:47 +00001022 if c in children:
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001023 results.append(walktree(children[c], children, c))
1024 return results
1025
Georg Brandl5ce83a02009-06-01 17:23:51 +00001026def getclasstree(classes, unique=False):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001027 """Arrange the given list of classes into a hierarchy of nested lists.
1028
1029 Where a nested list appears, it contains classes derived from the class
1030 whose entry immediately precedes the list. Each entry is a 2-tuple
1031 containing a class and a tuple of its base classes. If the 'unique'
1032 argument is true, exactly one entry appears in the returned structure
1033 for each class in the given list. Otherwise, classes using multiple
1034 inheritance and their descendants will appear multiple times."""
1035 children = {}
1036 roots = []
1037 for c in classes:
1038 if c.__bases__:
1039 for parent in c.__bases__:
Srinivas Reddy Thatiparthy (శ్రీనివాస్ రెడ్డి తాటిపర్తి)feaefc72018-02-09 15:29:19 +05301040 if parent not in children:
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001041 children[parent] = []
Serhiy Storchaka362c1b52013-09-05 17:14:32 +03001042 if c not in children[parent]:
1043 children[parent].append(c)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001044 if unique and parent in classes: break
1045 elif c not in roots:
1046 roots.append(c)
Raymond Hettingere0d49722002-06-02 18:55:56 +00001047 for parent in children:
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001048 if parent not in classes:
1049 roots.append(parent)
1050 return walktree(roots, children, None)
1051
1052# ------------------------------------------------ argument list extraction
Christian Heimes25bb7832008-01-11 16:17:00 +00001053Arguments = namedtuple('Arguments', 'args, varargs, varkw')
1054
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001055def getargs(co):
1056 """Get information about the arguments accepted by a code object.
1057
Guido van Rossum2e65f892007-02-28 22:03:49 +00001058 Three things are returned: (args, varargs, varkw), where
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001059 'args' is the list of argument names. Keyword-only arguments are
1060 appended. 'varargs' and 'varkw' are the names of the * and **
1061 arguments or None."""
Jeremy Hylton64967882003-06-27 18:14:39 +00001062 if not iscode(co):
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +00001063 raise TypeError('{!r} is not a code object'.format(co))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001064
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001065 names = co.co_varnames
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001066 nargs = co.co_argcount
Guido van Rossum2e65f892007-02-28 22:03:49 +00001067 nkwargs = co.co_kwonlyargcount
Pablo Galindocd74e662019-06-01 18:08:04 +01001068 args = list(names[:nargs])
1069 kwonlyargs = list(names[nargs:nargs+nkwargs])
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001070 step = 0
1071
Guido van Rossum2e65f892007-02-28 22:03:49 +00001072 nargs += nkwargs
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001073 varargs = None
1074 if co.co_flags & CO_VARARGS:
1075 varargs = co.co_varnames[nargs]
1076 nargs = nargs + 1
1077 varkw = None
1078 if co.co_flags & CO_VARKEYWORDS:
1079 varkw = co.co_varnames[nargs]
Pablo Galindocd74e662019-06-01 18:08:04 +01001080 return Arguments(args + kwonlyargs, varargs, varkw)
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001081
1082ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults')
1083
1084def getargspec(func):
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001085 """Get the names and default values of a function's parameters.
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001086
1087 A tuple of four things is returned: (args, varargs, keywords, defaults).
1088 'args' is a list of the argument names, including keyword-only argument names.
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001089 'varargs' and 'keywords' are the names of the * and ** parameters or None.
1090 'defaults' is an n-tuple of the default values of the last n parameters.
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001091
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001092 This function is deprecated, as it does not support annotations or
1093 keyword-only parameters and will raise ValueError if either is present
1094 on the supplied callable.
1095
1096 For a more structured introspection API, use inspect.signature() instead.
1097
1098 Alternatively, use getfullargspec() for an API with a similar namedtuple
1099 based interface, but full support for annotations and keyword-only
1100 parameters.
Matthias Bussonnierded87d82018-10-19 16:40:45 -07001101
1102 Deprecated since Python 3.5, use `inspect.getfullargspec()`.
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001103 """
Matthias Bussonnierded87d82018-10-19 16:40:45 -07001104 warnings.warn("inspect.getargspec() is deprecated since Python 3.0, "
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001105 "use inspect.signature() or inspect.getfullargspec()",
1106 DeprecationWarning, stacklevel=2)
Pablo Galindod5d2b452019-04-30 02:01:14 +01001107 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
1108 getfullargspec(func)
1109 if kwonlyargs or ann:
1110 raise ValueError("Function has keyword-only parameters or annotations"
1111 ", use inspect.signature() API which can support them")
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001112 return ArgSpec(args, varargs, varkw, defaults)
1113
Christian Heimes25bb7832008-01-11 16:17:00 +00001114FullArgSpec = namedtuple('FullArgSpec',
Pablo Galindod5d2b452019-04-30 02:01:14 +01001115 'args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations')
Guido van Rossum2e65f892007-02-28 22:03:49 +00001116
1117def getfullargspec(func):
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001118 """Get the names and default values of a callable object's parameters.
Guido van Rossum2e65f892007-02-28 22:03:49 +00001119
Brett Cannon504d8852007-09-07 02:12:14 +00001120 A tuple of seven things is returned:
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001121 (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations).
1122 'args' is a list of the parameter names.
1123 'varargs' and 'varkw' are the names of the * and ** parameters or None.
1124 'defaults' is an n-tuple of the default values of the last n parameters.
1125 'kwonlyargs' is a list of keyword-only parameter names.
Guido van Rossum2e65f892007-02-28 22:03:49 +00001126 'kwonlydefaults' is a dictionary mapping names from kwonlyargs to defaults.
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001127 'annotations' is a dictionary mapping parameter names to annotations.
Guido van Rossuma8add0e2007-05-14 22:03:55 +00001128
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001129 Notable differences from inspect.signature():
1130 - the "self" parameter is always reported, even for bound methods
1131 - wrapper chains defined by __wrapped__ *not* unwrapped automatically
Jeremy Hylton64967882003-06-27 18:14:39 +00001132 """
Yury Selivanov57d240e2014-02-19 16:27:23 -05001133 try:
1134 # Re: `skip_bound_arg=False`
1135 #
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001136 # There is a notable difference in behaviour between getfullargspec
1137 # and Signature: the former always returns 'self' parameter for bound
1138 # methods, whereas the Signature always shows the actual calling
1139 # signature of the passed object.
1140 #
1141 # To simulate this behaviour, we "unbind" bound methods, to trick
1142 # inspect.signature to always return their first parameter ("self",
1143 # usually)
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001144
Yury Selivanov57d240e2014-02-19 16:27:23 -05001145 # Re: `follow_wrapper_chains=False`
1146 #
1147 # getfullargspec() historically ignored __wrapped__ attributes,
1148 # so we ensure that remains the case in 3.3+
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001149
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001150 sig = _signature_from_callable(func,
1151 follow_wrapper_chains=False,
1152 skip_bound_arg=False,
1153 sigcls=Signature)
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001154 except Exception as ex:
1155 # Most of the times 'signature' will raise ValueError.
1156 # But, it can also raise AttributeError, and, maybe something
1157 # else. So to be fully backwards compatible, we catch all
1158 # possible exceptions here, and reraise a TypeError.
1159 raise TypeError('unsupported callable') from ex
1160
1161 args = []
1162 varargs = None
1163 varkw = None
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001164 posonlyargs = []
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001165 kwonlyargs = []
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001166 annotations = {}
1167 defaults = ()
1168 kwdefaults = {}
1169
1170 if sig.return_annotation is not sig.empty:
1171 annotations['return'] = sig.return_annotation
1172
1173 for param in sig.parameters.values():
1174 kind = param.kind
1175 name = param.name
1176
1177 if kind is _POSITIONAL_ONLY:
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001178 posonlyargs.append(name)
1179 if param.default is not param.empty:
1180 defaults += (param.default,)
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001181 elif kind is _POSITIONAL_OR_KEYWORD:
1182 args.append(name)
1183 if param.default is not param.empty:
1184 defaults += (param.default,)
1185 elif kind is _VAR_POSITIONAL:
1186 varargs = name
1187 elif kind is _KEYWORD_ONLY:
1188 kwonlyargs.append(name)
1189 if param.default is not param.empty:
1190 kwdefaults[name] = param.default
1191 elif kind is _VAR_KEYWORD:
1192 varkw = name
1193
1194 if param.annotation is not param.empty:
1195 annotations[name] = param.annotation
1196
1197 if not kwdefaults:
1198 # compatibility with 'func.__kwdefaults__'
1199 kwdefaults = None
1200
1201 if not defaults:
1202 # compatibility with 'func.__defaults__'
1203 defaults = None
1204
Pablo Galindod5d2b452019-04-30 02:01:14 +01001205 return FullArgSpec(posonlyargs + args, varargs, varkw, defaults,
1206 kwonlyargs, kwdefaults, annotations)
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001207
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001208
Christian Heimes25bb7832008-01-11 16:17:00 +00001209ArgInfo = namedtuple('ArgInfo', 'args varargs keywords locals')
1210
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001211def getargvalues(frame):
1212 """Get information about arguments passed into a particular frame.
1213
1214 A tuple of four things is returned: (args, varargs, varkw, locals).
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001215 'args' is a list of the argument names.
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001216 'varargs' and 'varkw' are the names of the * and ** arguments or None.
1217 'locals' is the locals dictionary of the given frame."""
1218 args, varargs, varkw = getargs(frame.f_code)
Benjamin Peterson1a6e0d02008-10-25 15:49:17 +00001219 return ArgInfo(args, varargs, varkw, frame.f_locals)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001220
Guido van Rossum2e65f892007-02-28 22:03:49 +00001221def formatannotation(annotation, base_module=None):
Guido van Rossum52e50042016-10-22 07:55:18 -07001222 if getattr(annotation, '__module__', None) == 'typing':
1223 return repr(annotation).replace('typing.', '')
Guido van Rossum2e65f892007-02-28 22:03:49 +00001224 if isinstance(annotation, type):
Georg Brandl1a3284e2007-12-02 09:40:06 +00001225 if annotation.__module__ in ('builtins', base_module):
Serhiy Storchaka521e5862014-07-22 15:00:37 +03001226 return annotation.__qualname__
1227 return annotation.__module__+'.'+annotation.__qualname__
Guido van Rossum2e65f892007-02-28 22:03:49 +00001228 return repr(annotation)
Guido van Rossuma8add0e2007-05-14 22:03:55 +00001229
Guido van Rossum2e65f892007-02-28 22:03:49 +00001230def formatannotationrelativeto(object):
Guido van Rossuma8add0e2007-05-14 22:03:55 +00001231 module = getattr(object, '__module__', None)
1232 def _formatannotation(annotation):
1233 return formatannotation(annotation, module)
1234 return _formatannotation
Guido van Rossum2e65f892007-02-28 22:03:49 +00001235
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001236def formatargspec(args, varargs=None, varkw=None, defaults=None,
Pablo Galindod5d2b452019-04-30 02:01:14 +01001237 kwonlyargs=(), kwonlydefaults={}, annotations={},
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001238 formatarg=str,
1239 formatvarargs=lambda name: '*' + name,
1240 formatvarkw=lambda name: '**' + name,
1241 formatvalue=lambda value: '=' + repr(value),
Guido van Rossum2e65f892007-02-28 22:03:49 +00001242 formatreturns=lambda text: ' -> ' + text,
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001243 formatannotation=formatannotation):
Berker Peksagfa3922c2015-07-31 04:11:29 +03001244 """Format an argument spec from the values returned by getfullargspec.
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001245
Guido van Rossum2e65f892007-02-28 22:03:49 +00001246 The first seven arguments are (args, varargs, varkw, defaults,
1247 kwonlyargs, kwonlydefaults, annotations). The other five arguments
1248 are the corresponding optional formatting functions that are called to
1249 turn names and values into strings. The last argument is an optional
Matthias Bussonnier46c5cd02018-06-11 22:08:16 +02001250 function to format the sequence of arguments.
1251
1252 Deprecated since Python 3.5: use the `signature` function and `Signature`
1253 objects.
1254 """
1255
1256 from warnings import warn
1257
1258 warn("`formatargspec` is deprecated since Python 3.5. Use `signature` and "
Zackery Spytz41254eb2018-06-11 21:16:18 -06001259 "the `Signature` object directly",
Matthias Bussonnier46c5cd02018-06-11 22:08:16 +02001260 DeprecationWarning,
1261 stacklevel=2)
1262
Guido van Rossum2e65f892007-02-28 22:03:49 +00001263 def formatargandannotation(arg):
1264 result = formatarg(arg)
1265 if arg in annotations:
1266 result += ': ' + formatannotation(annotations[arg])
1267 return result
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001268 specs = []
1269 if defaults:
Pablo Galindod5d2b452019-04-30 02:01:14 +01001270 firstdefault = len(args) - len(defaults)
1271 for i, arg in enumerate(args):
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001272 spec = formatargandannotation(arg)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001273 if defaults and i >= firstdefault:
1274 spec = spec + formatvalue(defaults[i - firstdefault])
1275 specs.append(spec)
Raymond Hettinger936654b2002-06-01 03:06:31 +00001276 if varargs is not None:
Guido van Rossum2e65f892007-02-28 22:03:49 +00001277 specs.append(formatvarargs(formatargandannotation(varargs)))
1278 else:
1279 if kwonlyargs:
1280 specs.append('*')
1281 if kwonlyargs:
1282 for kwonlyarg in kwonlyargs:
1283 spec = formatargandannotation(kwonlyarg)
Benjamin Peterson9953a8d2009-01-17 04:15:01 +00001284 if kwonlydefaults and kwonlyarg in kwonlydefaults:
Guido van Rossum2e65f892007-02-28 22:03:49 +00001285 spec += formatvalue(kwonlydefaults[kwonlyarg])
1286 specs.append(spec)
Raymond Hettinger936654b2002-06-01 03:06:31 +00001287 if varkw is not None:
Guido van Rossum2e65f892007-02-28 22:03:49 +00001288 specs.append(formatvarkw(formatargandannotation(varkw)))
Neal Norwitz9d72bb42007-04-17 08:48:32 +00001289 result = '(' + ', '.join(specs) + ')'
Guido van Rossum2e65f892007-02-28 22:03:49 +00001290 if 'return' in annotations:
1291 result += formatreturns(formatannotation(annotations['return']))
1292 return result
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001293
1294def formatargvalues(args, varargs, varkw, locals,
1295 formatarg=str,
1296 formatvarargs=lambda name: '*' + name,
1297 formatvarkw=lambda name: '**' + name,
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001298 formatvalue=lambda value: '=' + repr(value)):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001299 """Format an argument spec from the 4 values returned by getargvalues.
1300
1301 The first four arguments are (args, varargs, varkw, locals). The
1302 next four arguments are the corresponding optional formatting functions
1303 that are called to turn names and values into strings. The ninth
1304 argument is an optional function to format the sequence of arguments."""
1305 def convert(name, locals=locals,
1306 formatarg=formatarg, formatvalue=formatvalue):
1307 return formatarg(name) + formatvalue(locals[name])
1308 specs = []
1309 for i in range(len(args)):
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001310 specs.append(convert(args[i]))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001311 if varargs:
1312 specs.append(formatvarargs(varargs) + formatvalue(locals[varargs]))
1313 if varkw:
1314 specs.append(formatvarkw(varkw) + formatvalue(locals[varkw]))
Neal Norwitz9d72bb42007-04-17 08:48:32 +00001315 return '(' + ', '.join(specs) + ')'
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001316
Benjamin Petersone109c702011-06-24 09:37:26 -05001317def _missing_arguments(f_name, argnames, pos, values):
1318 names = [repr(name) for name in argnames if name not in values]
1319 missing = len(names)
1320 if missing == 1:
1321 s = names[0]
1322 elif missing == 2:
1323 s = "{} and {}".format(*names)
1324 else:
Yury Selivanovdccfa132014-03-27 18:42:52 -04001325 tail = ", {} and {}".format(*names[-2:])
Benjamin Petersone109c702011-06-24 09:37:26 -05001326 del names[-2:]
1327 s = ", ".join(names) + tail
1328 raise TypeError("%s() missing %i required %s argument%s: %s" %
1329 (f_name, missing,
1330 "positional" if pos else "keyword-only",
1331 "" if missing == 1 else "s", s))
1332
1333def _too_many(f_name, args, kwonly, varargs, defcount, given, values):
Benjamin Petersonb204a422011-06-05 22:04:07 -05001334 atleast = len(args) - defcount
Benjamin Petersonb204a422011-06-05 22:04:07 -05001335 kwonly_given = len([arg for arg in kwonly if arg in values])
1336 if varargs:
1337 plural = atleast != 1
1338 sig = "at least %d" % (atleast,)
1339 elif defcount:
1340 plural = True
1341 sig = "from %d to %d" % (atleast, len(args))
1342 else:
1343 plural = len(args) != 1
1344 sig = str(len(args))
1345 kwonly_sig = ""
1346 if kwonly_given:
1347 msg = " positional argument%s (and %d keyword-only argument%s)"
1348 kwonly_sig = (msg % ("s" if given != 1 else "", kwonly_given,
1349 "s" if kwonly_given != 1 else ""))
1350 raise TypeError("%s() takes %s positional argument%s but %d%s %s given" %
1351 (f_name, sig, "s" if plural else "", given, kwonly_sig,
1352 "was" if given == 1 and not kwonly_given else "were"))
1353
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03001354def getcallargs(func, /, *positional, **named):
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001355 """Get the mapping of arguments to values.
1356
1357 A dict is returned, with keys the function argument names (including the
1358 names of the * and ** arguments, if any), and values the respective bound
1359 values from 'positional' and 'named'."""
1360 spec = getfullargspec(func)
Pablo Galindod5d2b452019-04-30 02:01:14 +01001361 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = spec
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001362 f_name = func.__name__
1363 arg2value = {}
1364
Benjamin Petersonb204a422011-06-05 22:04:07 -05001365
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001366 if ismethod(func) and func.__self__ is not None:
1367 # implicit 'self' (or 'cls' for classmethods) argument
1368 positional = (func.__self__,) + positional
1369 num_pos = len(positional)
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001370 num_args = len(args)
1371 num_defaults = len(defaults) if defaults else 0
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001372
Benjamin Petersonb204a422011-06-05 22:04:07 -05001373 n = min(num_pos, num_args)
1374 for i in range(n):
Pablo Galindod5d2b452019-04-30 02:01:14 +01001375 arg2value[args[i]] = positional[i]
Benjamin Petersonb204a422011-06-05 22:04:07 -05001376 if varargs:
1377 arg2value[varargs] = tuple(positional[n:])
1378 possible_kwargs = set(args + kwonlyargs)
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001379 if varkw:
Benjamin Petersonb204a422011-06-05 22:04:07 -05001380 arg2value[varkw] = {}
1381 for kw, value in named.items():
1382 if kw not in possible_kwargs:
1383 if not varkw:
1384 raise TypeError("%s() got an unexpected keyword argument %r" %
1385 (f_name, kw))
1386 arg2value[varkw][kw] = value
1387 continue
1388 if kw in arg2value:
1389 raise TypeError("%s() got multiple values for argument %r" %
1390 (f_name, kw))
1391 arg2value[kw] = value
1392 if num_pos > num_args and not varargs:
Benjamin Petersone109c702011-06-24 09:37:26 -05001393 _too_many(f_name, args, kwonlyargs, varargs, num_defaults,
1394 num_pos, arg2value)
Benjamin Petersonb204a422011-06-05 22:04:07 -05001395 if num_pos < num_args:
Benjamin Petersone109c702011-06-24 09:37:26 -05001396 req = args[:num_args - num_defaults]
1397 for arg in req:
Benjamin Petersonb204a422011-06-05 22:04:07 -05001398 if arg not in arg2value:
Benjamin Petersone109c702011-06-24 09:37:26 -05001399 _missing_arguments(f_name, req, True, arg2value)
Benjamin Petersonb204a422011-06-05 22:04:07 -05001400 for i, arg in enumerate(args[num_args - num_defaults:]):
1401 if arg not in arg2value:
1402 arg2value[arg] = defaults[i]
Benjamin Petersone109c702011-06-24 09:37:26 -05001403 missing = 0
Benjamin Petersonb204a422011-06-05 22:04:07 -05001404 for kwarg in kwonlyargs:
1405 if kwarg not in arg2value:
Yury Selivanov875df202014-03-27 18:23:03 -04001406 if kwonlydefaults and kwarg in kwonlydefaults:
Benjamin Petersone109c702011-06-24 09:37:26 -05001407 arg2value[kwarg] = kwonlydefaults[kwarg]
1408 else:
1409 missing += 1
1410 if missing:
1411 _missing_arguments(f_name, kwonlyargs, False, arg2value)
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001412 return arg2value
1413
Nick Coghlan2f92e542012-06-23 19:39:55 +10001414ClosureVars = namedtuple('ClosureVars', 'nonlocals globals builtins unbound')
1415
1416def getclosurevars(func):
1417 """
1418 Get the mapping of free variables to their current values.
1419
Meador Inge8fda3592012-07-19 21:33:21 -05001420 Returns a named tuple of dicts mapping the current nonlocal, global
Nick Coghlan2f92e542012-06-23 19:39:55 +10001421 and builtin references as seen by the body of the function. A final
1422 set of unbound names that could not be resolved is also provided.
1423 """
1424
1425 if ismethod(func):
1426 func = func.__func__
1427
1428 if not isfunction(func):
Serhiy Storchakaa4a30202017-11-28 22:54:42 +02001429 raise TypeError("{!r} is not a Python function".format(func))
Nick Coghlan2f92e542012-06-23 19:39:55 +10001430
1431 code = func.__code__
1432 # Nonlocal references are named in co_freevars and resolved
1433 # by looking them up in __closure__ by positional index
1434 if func.__closure__ is None:
1435 nonlocal_vars = {}
1436 else:
1437 nonlocal_vars = {
1438 var : cell.cell_contents
1439 for var, cell in zip(code.co_freevars, func.__closure__)
1440 }
1441
1442 # Global and builtin references are named in co_names and resolved
1443 # by looking them up in __globals__ or __builtins__
1444 global_ns = func.__globals__
1445 builtin_ns = global_ns.get("__builtins__", builtins.__dict__)
1446 if ismodule(builtin_ns):
1447 builtin_ns = builtin_ns.__dict__
1448 global_vars = {}
1449 builtin_vars = {}
1450 unbound_names = set()
1451 for name in code.co_names:
1452 if name in ("None", "True", "False"):
1453 # Because these used to be builtins instead of keywords, they
1454 # may still show up as name references. We ignore them.
1455 continue
1456 try:
1457 global_vars[name] = global_ns[name]
1458 except KeyError:
1459 try:
1460 builtin_vars[name] = builtin_ns[name]
1461 except KeyError:
1462 unbound_names.add(name)
1463
1464 return ClosureVars(nonlocal_vars, global_vars,
1465 builtin_vars, unbound_names)
1466
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001467# -------------------------------------------------- stack frame extraction
Christian Heimes25bb7832008-01-11 16:17:00 +00001468
1469Traceback = namedtuple('Traceback', 'filename lineno function code_context index')
1470
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001471def getframeinfo(frame, context=1):
1472 """Get information about a frame or traceback object.
1473
1474 A tuple of five things is returned: the filename, the line number of
1475 the current line, the function name, a list of lines of context from
1476 the source code, and the index of the current line within that list.
1477 The optional second argument specifies the number of lines of context
1478 to return, which are centered around the current line."""
1479 if istraceback(frame):
Andrew M. Kuchlingba8b6bc2004-06-05 14:11:59 +00001480 lineno = frame.tb_lineno
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001481 frame = frame.tb_frame
Andrew M. Kuchlingba8b6bc2004-06-05 14:11:59 +00001482 else:
1483 lineno = frame.f_lineno
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001484 if not isframe(frame):
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +00001485 raise TypeError('{!r} is not a frame or traceback object'.format(frame))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001486
Neil Schemenauerf06f8532002-03-23 23:51:04 +00001487 filename = getsourcefile(frame) or getfile(frame)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001488 if context > 0:
Guido van Rossum54e54c62001-09-04 19:14:14 +00001489 start = lineno - 1 - context//2
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001490 try:
1491 lines, lnum = findsource(frame)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02001492 except OSError:
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +00001493 lines = index = None
1494 else:
Raymond Hettingera0501712004-06-15 11:22:53 +00001495 start = max(0, min(start, len(lines) - context))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001496 lines = lines[start:start+context]
Ka-Ping Yee59ade082001-03-01 03:55:35 +00001497 index = lineno - 1 - start
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001498 else:
1499 lines = index = None
1500
Christian Heimes25bb7832008-01-11 16:17:00 +00001501 return Traceback(filename, lineno, frame.f_code.co_name, lines, index)
Ka-Ping Yee59ade082001-03-01 03:55:35 +00001502
1503def getlineno(frame):
1504 """Get the line number from a frame object, allowing for optimization."""
Michael W. Hudsondd32a912002-08-15 14:59:02 +00001505 # FrameType.f_lineno is now a descriptor that grovels co_lnotab
1506 return frame.f_lineno
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001507
Antoine Pitroucdcafb72014-08-24 10:50:28 -04001508FrameInfo = namedtuple('FrameInfo', ('frame',) + Traceback._fields)
1509
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001510def getouterframes(frame, context=1):
1511 """Get a list of records for a frame and all higher (calling) frames.
1512
1513 Each record contains a frame object, filename, line number, function
1514 name, a list of lines of context, and index within the context."""
1515 framelist = []
1516 while frame:
Antoine Pitroucdcafb72014-08-24 10:50:28 -04001517 frameinfo = (frame,) + getframeinfo(frame, context)
1518 framelist.append(FrameInfo(*frameinfo))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001519 frame = frame.f_back
1520 return framelist
1521
1522def getinnerframes(tb, context=1):
1523 """Get a list of records for a traceback's frame and all lower frames.
1524
1525 Each record contains a frame object, filename, line number, function
1526 name, a list of lines of context, and index within the context."""
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001527 framelist = []
1528 while tb:
Antoine Pitroucdcafb72014-08-24 10:50:28 -04001529 frameinfo = (tb.tb_frame,) + getframeinfo(tb, context)
1530 framelist.append(FrameInfo(*frameinfo))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001531 tb = tb.tb_next
1532 return framelist
1533
Benjamin Peterson42ac4752010-08-09 13:05:35 +00001534def currentframe():
Benjamin Petersona3a3fc62010-08-09 15:49:56 +00001535 """Return the frame of the caller or None if this is not possible."""
Benjamin Peterson42ac4752010-08-09 13:05:35 +00001536 return sys._getframe(1) if hasattr(sys, "_getframe") else None
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001537
1538def stack(context=1):
1539 """Return a list of records for the stack above the caller's frame."""
Jeremy Hyltonab919022003-06-27 18:41:20 +00001540 return getouterframes(sys._getframe(1), context)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001541
1542def trace(context=1):
Tim Peters85ba6732001-02-28 08:26:44 +00001543 """Return a list of records for the stack below the current exception."""
Fred Draked451ec12002-04-26 02:29:55 +00001544 return getinnerframes(sys.exc_info()[2], context)
Michael Foord95fc51d2010-11-20 15:07:30 +00001545
1546
1547# ------------------------------------------------ static version of getattr
1548
1549_sentinel = object()
1550
Michael Foorde5162652010-11-20 16:40:44 +00001551def _static_getmro(klass):
1552 return type.__dict__['__mro__'].__get__(klass)
1553
Michael Foord95fc51d2010-11-20 15:07:30 +00001554def _check_instance(obj, attr):
1555 instance_dict = {}
1556 try:
1557 instance_dict = object.__getattribute__(obj, "__dict__")
1558 except AttributeError:
1559 pass
Michael Foorddcebe0f2011-03-15 19:20:44 -04001560 return dict.get(instance_dict, attr, _sentinel)
Michael Foord95fc51d2010-11-20 15:07:30 +00001561
1562
1563def _check_class(klass, attr):
Michael Foorde5162652010-11-20 16:40:44 +00001564 for entry in _static_getmro(klass):
Michael Foorda51623b2011-12-18 22:01:40 +00001565 if _shadowed_dict(type(entry)) is _sentinel:
Michael Foorddcebe0f2011-03-15 19:20:44 -04001566 try:
1567 return entry.__dict__[attr]
1568 except KeyError:
1569 pass
Michael Foord95fc51d2010-11-20 15:07:30 +00001570 return _sentinel
1571
Michael Foord35184ed2010-11-20 16:58:30 +00001572def _is_type(obj):
1573 try:
1574 _static_getmro(obj)
1575 except TypeError:
1576 return False
1577 return True
1578
Michael Foorddcebe0f2011-03-15 19:20:44 -04001579def _shadowed_dict(klass):
1580 dict_attr = type.__dict__["__dict__"]
1581 for entry in _static_getmro(klass):
1582 try:
1583 class_dict = dict_attr.__get__(entry)["__dict__"]
1584 except KeyError:
1585 pass
1586 else:
Inada Naoki8f9cc872019-09-05 13:07:08 +09001587 if not (type(class_dict) is types.GetSetDescriptorType and
Michael Foorddcebe0f2011-03-15 19:20:44 -04001588 class_dict.__name__ == "__dict__" and
1589 class_dict.__objclass__ is entry):
Michael Foorda51623b2011-12-18 22:01:40 +00001590 return class_dict
1591 return _sentinel
Michael Foord95fc51d2010-11-20 15:07:30 +00001592
1593def getattr_static(obj, attr, default=_sentinel):
1594 """Retrieve attributes without triggering dynamic lookup via the
1595 descriptor protocol, __getattr__ or __getattribute__.
1596
1597 Note: this function may not be able to retrieve all attributes
1598 that getattr can fetch (like dynamically created attributes)
1599 and may find attributes that getattr can't (like descriptors
1600 that raise AttributeError). It can also return descriptor objects
1601 instead of instance members in some cases. See the
1602 documentation for details.
1603 """
1604 instance_result = _sentinel
Michael Foord35184ed2010-11-20 16:58:30 +00001605 if not _is_type(obj):
Michael Foordcc7ebb82010-11-20 16:20:16 +00001606 klass = type(obj)
Michael Foorda51623b2011-12-18 22:01:40 +00001607 dict_attr = _shadowed_dict(klass)
1608 if (dict_attr is _sentinel or
Inada Naoki8f9cc872019-09-05 13:07:08 +09001609 type(dict_attr) is types.MemberDescriptorType):
Michael Foorddcebe0f2011-03-15 19:20:44 -04001610 instance_result = _check_instance(obj, attr)
Michael Foord95fc51d2010-11-20 15:07:30 +00001611 else:
1612 klass = obj
1613
1614 klass_result = _check_class(klass, attr)
1615
1616 if instance_result is not _sentinel and klass_result is not _sentinel:
1617 if (_check_class(type(klass_result), '__get__') is not _sentinel and
1618 _check_class(type(klass_result), '__set__') is not _sentinel):
1619 return klass_result
1620
1621 if instance_result is not _sentinel:
1622 return instance_result
1623 if klass_result is not _sentinel:
1624 return klass_result
1625
1626 if obj is klass:
1627 # for types we check the metaclass too
Michael Foorde5162652010-11-20 16:40:44 +00001628 for entry in _static_getmro(type(klass)):
Michael Foord3ba95f82011-12-22 01:13:37 +00001629 if _shadowed_dict(type(entry)) is _sentinel:
1630 try:
1631 return entry.__dict__[attr]
1632 except KeyError:
1633 pass
Michael Foord95fc51d2010-11-20 15:07:30 +00001634 if default is not _sentinel:
1635 return default
1636 raise AttributeError(attr)
Nick Coghlane0f04652010-11-21 03:44:04 +00001637
1638
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001639# ------------------------------------------------ generator introspection
1640
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001641GEN_CREATED = 'GEN_CREATED'
1642GEN_RUNNING = 'GEN_RUNNING'
1643GEN_SUSPENDED = 'GEN_SUSPENDED'
1644GEN_CLOSED = 'GEN_CLOSED'
Nick Coghlane0f04652010-11-21 03:44:04 +00001645
1646def getgeneratorstate(generator):
1647 """Get current state of a generator-iterator.
1648
1649 Possible states are:
1650 GEN_CREATED: Waiting to start execution.
1651 GEN_RUNNING: Currently being executed by the interpreter.
1652 GEN_SUSPENDED: Currently suspended at a yield expression.
1653 GEN_CLOSED: Execution has completed.
1654 """
1655 if generator.gi_running:
1656 return GEN_RUNNING
1657 if generator.gi_frame is None:
1658 return GEN_CLOSED
1659 if generator.gi_frame.f_lasti == -1:
1660 return GEN_CREATED
1661 return GEN_SUSPENDED
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001662
1663
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001664def getgeneratorlocals(generator):
1665 """
1666 Get the mapping of generator local variables to their current values.
1667
1668 A dict is returned, with the keys the local variable names and values the
1669 bound values."""
1670
1671 if not isgenerator(generator):
Serhiy Storchakaa4a30202017-11-28 22:54:42 +02001672 raise TypeError("{!r} is not a Python generator".format(generator))
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001673
1674 frame = getattr(generator, "gi_frame", None)
1675 if frame is not None:
1676 return generator.gi_frame.f_locals
1677 else:
1678 return {}
1679
Yury Selivanov5376ba92015-06-22 12:19:30 -04001680
1681# ------------------------------------------------ coroutine introspection
1682
1683CORO_CREATED = 'CORO_CREATED'
1684CORO_RUNNING = 'CORO_RUNNING'
1685CORO_SUSPENDED = 'CORO_SUSPENDED'
1686CORO_CLOSED = 'CORO_CLOSED'
1687
1688def getcoroutinestate(coroutine):
1689 """Get current state of a coroutine object.
1690
1691 Possible states are:
1692 CORO_CREATED: Waiting to start execution.
1693 CORO_RUNNING: Currently being executed by the interpreter.
1694 CORO_SUSPENDED: Currently suspended at an await expression.
1695 CORO_CLOSED: Execution has completed.
1696 """
1697 if coroutine.cr_running:
1698 return CORO_RUNNING
1699 if coroutine.cr_frame is None:
1700 return CORO_CLOSED
1701 if coroutine.cr_frame.f_lasti == -1:
1702 return CORO_CREATED
1703 return CORO_SUSPENDED
1704
1705
1706def getcoroutinelocals(coroutine):
1707 """
1708 Get the mapping of coroutine local variables to their current values.
1709
1710 A dict is returned, with the keys the local variable names and values the
1711 bound values."""
1712 frame = getattr(coroutine, "cr_frame", None)
1713 if frame is not None:
1714 return frame.f_locals
1715 else:
1716 return {}
1717
1718
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001719###############################################################################
1720### Function Signature Object (PEP 362)
1721###############################################################################
1722
1723
1724_WrapperDescriptor = type(type.__call__)
1725_MethodWrapper = type(all.__call__)
Larry Hastings5c661892014-01-24 06:17:25 -08001726_ClassMethodWrapper = type(int.__dict__['from_bytes'])
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001727
1728_NonUserDefinedCallables = (_WrapperDescriptor,
1729 _MethodWrapper,
Larry Hastings5c661892014-01-24 06:17:25 -08001730 _ClassMethodWrapper,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001731 types.BuiltinFunctionType)
1732
1733
Yury Selivanov421f0c72014-01-29 12:05:40 -05001734def _signature_get_user_defined_method(cls, method_name):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001735 """Private helper. Checks if ``cls`` has an attribute
1736 named ``method_name`` and returns it only if it is a
1737 pure python function.
1738 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001739 try:
1740 meth = getattr(cls, method_name)
1741 except AttributeError:
1742 return
1743 else:
1744 if not isinstance(meth, _NonUserDefinedCallables):
1745 # Once '__signature__' will be added to 'C'-level
1746 # callables, this check won't be necessary
1747 return meth
1748
1749
Yury Selivanov62560fb2014-01-28 12:26:24 -05001750def _signature_get_partial(wrapped_sig, partial, extra_args=()):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001751 """Private helper to calculate how 'wrapped_sig' signature will
1752 look like after applying a 'functools.partial' object (or alike)
1753 on it.
1754 """
Yury Selivanov62560fb2014-01-28 12:26:24 -05001755
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001756 old_params = wrapped_sig.parameters
Inada Naoki21105512020-03-02 18:54:49 +09001757 new_params = OrderedDict(old_params.items())
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05001758
1759 partial_args = partial.args or ()
1760 partial_keywords = partial.keywords or {}
1761
1762 if extra_args:
1763 partial_args = extra_args + partial_args
1764
1765 try:
1766 ba = wrapped_sig.bind_partial(*partial_args, **partial_keywords)
1767 except TypeError as ex:
1768 msg = 'partial object {!r} has incorrect arguments'.format(partial)
1769 raise ValueError(msg) from ex
1770
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05001771
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001772 transform_to_kwonly = False
1773 for param_name, param in old_params.items():
1774 try:
1775 arg_value = ba.arguments[param_name]
1776 except KeyError:
1777 pass
1778 else:
1779 if param.kind is _POSITIONAL_ONLY:
1780 # If positional-only parameter is bound by partial,
1781 # it effectively disappears from the signature
Inada Naoki21105512020-03-02 18:54:49 +09001782 new_params.pop(param_name)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001783 continue
1784
1785 if param.kind is _POSITIONAL_OR_KEYWORD:
1786 if param_name in partial_keywords:
1787 # This means that this parameter, and all parameters
1788 # after it should be keyword-only (and var-positional
1789 # should be removed). Here's why. Consider the following
1790 # function:
1791 # foo(a, b, *args, c):
1792 # pass
1793 #
1794 # "partial(foo, a='spam')" will have the following
1795 # signature: "(*, a='spam', b, c)". Because attempting
1796 # to call that partial with "(10, 20)" arguments will
1797 # raise a TypeError, saying that "a" argument received
1798 # multiple values.
1799 transform_to_kwonly = True
1800 # Set the new default value
Inada Naoki21105512020-03-02 18:54:49 +09001801 new_params[param_name] = param.replace(default=arg_value)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001802 else:
1803 # was passed as a positional argument
Inada Naoki21105512020-03-02 18:54:49 +09001804 new_params.pop(param.name)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001805 continue
1806
1807 if param.kind is _KEYWORD_ONLY:
1808 # Set the new default value
Inada Naoki21105512020-03-02 18:54:49 +09001809 new_params[param_name] = param.replace(default=arg_value)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001810
1811 if transform_to_kwonly:
1812 assert param.kind is not _POSITIONAL_ONLY
1813
1814 if param.kind is _POSITIONAL_OR_KEYWORD:
Inada Naoki21105512020-03-02 18:54:49 +09001815 new_param = new_params[param_name].replace(kind=_KEYWORD_ONLY)
1816 new_params[param_name] = new_param
1817 new_params.move_to_end(param_name)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001818 elif param.kind in (_KEYWORD_ONLY, _VAR_KEYWORD):
Inada Naoki21105512020-03-02 18:54:49 +09001819 new_params.move_to_end(param_name)
1820 elif param.kind is _VAR_POSITIONAL:
1821 new_params.pop(param.name)
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05001822
1823 return wrapped_sig.replace(parameters=new_params.values())
1824
1825
Yury Selivanov62560fb2014-01-28 12:26:24 -05001826def _signature_bound_method(sig):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001827 """Private helper to transform signatures for unbound
1828 functions to bound methods.
1829 """
Yury Selivanov62560fb2014-01-28 12:26:24 -05001830
1831 params = tuple(sig.parameters.values())
1832
1833 if not params or params[0].kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
1834 raise ValueError('invalid method signature')
1835
1836 kind = params[0].kind
1837 if kind in (_POSITIONAL_OR_KEYWORD, _POSITIONAL_ONLY):
1838 # Drop first parameter:
1839 # '(p1, p2[, ...])' -> '(p2[, ...])'
1840 params = params[1:]
1841 else:
1842 if kind is not _VAR_POSITIONAL:
1843 # Unless we add a new parameter type we never
1844 # get here
1845 raise ValueError('invalid argument type')
1846 # It's a var-positional parameter.
1847 # Do nothing. '(*args[, ...])' -> '(*args[, ...])'
1848
1849 return sig.replace(parameters=params)
1850
1851
Yury Selivanovb77511d2014-01-29 10:46:14 -05001852def _signature_is_builtin(obj):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001853 """Private helper to test if `obj` is a callable that might
1854 support Argument Clinic's __text_signature__ protocol.
1855 """
Yury Selivanov1d241832014-02-02 12:51:20 -05001856 return (isbuiltin(obj) or
Yury Selivanovb77511d2014-01-29 10:46:14 -05001857 ismethoddescriptor(obj) or
Yury Selivanov1d241832014-02-02 12:51:20 -05001858 isinstance(obj, _NonUserDefinedCallables) or
Yury Selivanovb77511d2014-01-29 10:46:14 -05001859 # Can't test 'isinstance(type)' here, as it would
1860 # also be True for regular python classes
1861 obj in (type, object))
1862
1863
Yury Selivanov63da7c72014-01-31 14:48:37 -05001864def _signature_is_functionlike(obj):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001865 """Private helper to test if `obj` is a duck type of FunctionType.
1866 A good example of such objects are functions compiled with
1867 Cython, which have all attributes that a pure Python function
1868 would have, but have their code statically compiled.
1869 """
Yury Selivanov63da7c72014-01-31 14:48:37 -05001870
1871 if not callable(obj) or isclass(obj):
1872 # All function-like objects are obviously callables,
1873 # and not classes.
1874 return False
1875
1876 name = getattr(obj, '__name__', None)
1877 code = getattr(obj, '__code__', None)
1878 defaults = getattr(obj, '__defaults__', _void) # Important to use _void ...
1879 kwdefaults = getattr(obj, '__kwdefaults__', _void) # ... and not None here
1880 annotations = getattr(obj, '__annotations__', None)
1881
1882 return (isinstance(code, types.CodeType) and
1883 isinstance(name, str) and
1884 (defaults is None or isinstance(defaults, tuple)) and
1885 (kwdefaults is None or isinstance(kwdefaults, dict)) and
1886 isinstance(annotations, dict))
1887
1888
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001889def _signature_get_bound_param(spec):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001890 """ Private helper to get first parameter name from a
1891 __text_signature__ of a builtin method, which should
1892 be in the following format: '($param1, ...)'.
1893 Assumptions are that the first argument won't have
1894 a default value or an annotation.
1895 """
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001896
1897 assert spec.startswith('($')
1898
1899 pos = spec.find(',')
1900 if pos == -1:
1901 pos = spec.find(')')
1902
1903 cpos = spec.find(':')
1904 assert cpos == -1 or cpos > pos
1905
1906 cpos = spec.find('=')
1907 assert cpos == -1 or cpos > pos
1908
1909 return spec[2:pos]
1910
1911
Larry Hastings2623c8c2014-02-08 22:15:29 -08001912def _signature_strip_non_python_syntax(signature):
1913 """
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001914 Private helper function. Takes a signature in Argument Clinic's
1915 extended signature format.
1916
Larry Hastings2623c8c2014-02-08 22:15:29 -08001917 Returns a tuple of three things:
1918 * that signature re-rendered in standard Python syntax,
1919 * the index of the "self" parameter (generally 0), or None if
1920 the function does not have a "self" parameter, and
1921 * the index of the last "positional only" parameter,
1922 or None if the signature has no positional-only parameters.
1923 """
1924
1925 if not signature:
1926 return signature, None, None
1927
1928 self_parameter = None
1929 last_positional_only = None
1930
1931 lines = [l.encode('ascii') for l in signature.split('\n')]
1932 generator = iter(lines).__next__
1933 token_stream = tokenize.tokenize(generator)
1934
1935 delayed_comma = False
1936 skip_next_comma = False
1937 text = []
1938 add = text.append
1939
1940 current_parameter = 0
1941 OP = token.OP
1942 ERRORTOKEN = token.ERRORTOKEN
1943
1944 # token stream always starts with ENCODING token, skip it
1945 t = next(token_stream)
1946 assert t.type == tokenize.ENCODING
1947
1948 for t in token_stream:
1949 type, string = t.type, t.string
1950
1951 if type == OP:
1952 if string == ',':
1953 if skip_next_comma:
1954 skip_next_comma = False
1955 else:
1956 assert not delayed_comma
1957 delayed_comma = True
1958 current_parameter += 1
1959 continue
1960
1961 if string == '/':
1962 assert not skip_next_comma
1963 assert last_positional_only is None
1964 skip_next_comma = True
1965 last_positional_only = current_parameter - 1
1966 continue
1967
1968 if (type == ERRORTOKEN) and (string == '$'):
1969 assert self_parameter is None
1970 self_parameter = current_parameter
1971 continue
1972
1973 if delayed_comma:
1974 delayed_comma = False
1975 if not ((type == OP) and (string == ')')):
1976 add(', ')
1977 add(string)
1978 if (string == ','):
1979 add(' ')
1980 clean_signature = ''.join(text)
1981 return clean_signature, self_parameter, last_positional_only
1982
1983
Yury Selivanov57d240e2014-02-19 16:27:23 -05001984def _signature_fromstr(cls, obj, s, skip_bound_arg=True):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001985 """Private helper to parse content of '__text_signature__'
1986 and return a Signature based on it.
1987 """
INADA Naoki37420de2018-01-27 10:10:06 +09001988 # Lazy import ast because it's relatively heavy and
1989 # it's not used for other than this function.
1990 import ast
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001991
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05001992 Parameter = cls._parameter_cls
1993
Larry Hastings2623c8c2014-02-08 22:15:29 -08001994 clean_signature, self_parameter, last_positional_only = \
1995 _signature_strip_non_python_syntax(s)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05001996
Larry Hastings2623c8c2014-02-08 22:15:29 -08001997 program = "def foo" + clean_signature + ": pass"
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05001998
1999 try:
Larry Hastings2623c8c2014-02-08 22:15:29 -08002000 module = ast.parse(program)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002001 except SyntaxError:
2002 module = None
2003
2004 if not isinstance(module, ast.Module):
2005 raise ValueError("{!r} builtin has invalid signature".format(obj))
2006
2007 f = module.body[0]
2008
2009 parameters = []
2010 empty = Parameter.empty
2011 invalid = object()
2012
2013 module = None
2014 module_dict = {}
2015 module_name = getattr(obj, '__module__', None)
2016 if module_name:
2017 module = sys.modules.get(module_name, None)
2018 if module:
2019 module_dict = module.__dict__
INADA Naoki6f85b822018-10-05 01:47:09 +09002020 sys_module_dict = sys.modules.copy()
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002021
2022 def parse_name(node):
2023 assert isinstance(node, ast.arg)
Srinivas Reddy Thatiparthy (శ్రీనివాస్ రెడ్డి తాటిపర్తి)feaefc72018-02-09 15:29:19 +05302024 if node.annotation is not None:
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002025 raise ValueError("Annotations are not currently supported")
2026 return node.arg
2027
2028 def wrap_value(s):
2029 try:
2030 value = eval(s, module_dict)
2031 except NameError:
2032 try:
2033 value = eval(s, sys_module_dict)
2034 except NameError:
2035 raise RuntimeError()
2036
Serhiy Storchaka3f228112018-09-27 17:42:37 +03002037 if isinstance(value, (str, int, float, bytes, bool, type(None))):
2038 return ast.Constant(value)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002039 raise RuntimeError()
2040
2041 class RewriteSymbolics(ast.NodeTransformer):
2042 def visit_Attribute(self, node):
2043 a = []
2044 n = node
2045 while isinstance(n, ast.Attribute):
2046 a.append(n.attr)
2047 n = n.value
2048 if not isinstance(n, ast.Name):
2049 raise RuntimeError()
2050 a.append(n.id)
2051 value = ".".join(reversed(a))
2052 return wrap_value(value)
2053
2054 def visit_Name(self, node):
2055 if not isinstance(node.ctx, ast.Load):
2056 raise ValueError()
2057 return wrap_value(node.id)
2058
2059 def p(name_node, default_node, default=empty):
2060 name = parse_name(name_node)
2061 if name is invalid:
2062 return None
2063 if default_node and default_node is not _empty:
2064 try:
2065 default_node = RewriteSymbolics().visit(default_node)
2066 o = ast.literal_eval(default_node)
2067 except ValueError:
2068 o = invalid
2069 if o is invalid:
2070 return None
2071 default = o if o is not invalid else default
2072 parameters.append(Parameter(name, kind, default=default, annotation=empty))
2073
2074 # non-keyword-only parameters
2075 args = reversed(f.args.args)
2076 defaults = reversed(f.args.defaults)
2077 iter = itertools.zip_longest(args, defaults, fillvalue=None)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002078 if last_positional_only is not None:
2079 kind = Parameter.POSITIONAL_ONLY
2080 else:
2081 kind = Parameter.POSITIONAL_OR_KEYWORD
2082 for i, (name, default) in enumerate(reversed(list(iter))):
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002083 p(name, default)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002084 if i == last_positional_only:
2085 kind = Parameter.POSITIONAL_OR_KEYWORD
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002086
2087 # *args
2088 if f.args.vararg:
2089 kind = Parameter.VAR_POSITIONAL
2090 p(f.args.vararg, empty)
2091
2092 # keyword-only arguments
2093 kind = Parameter.KEYWORD_ONLY
2094 for name, default in zip(f.args.kwonlyargs, f.args.kw_defaults):
2095 p(name, default)
2096
2097 # **kwargs
2098 if f.args.kwarg:
2099 kind = Parameter.VAR_KEYWORD
2100 p(f.args.kwarg, empty)
2101
Larry Hastings2623c8c2014-02-08 22:15:29 -08002102 if self_parameter is not None:
Yury Selivanov8c185ee2014-02-21 01:32:42 -05002103 # Possibly strip the bound argument:
2104 # - We *always* strip first bound argument if
2105 # it is a module.
2106 # - We don't strip first bound argument if
2107 # skip_bound_arg is False.
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002108 assert parameters
Yury Selivanov8c185ee2014-02-21 01:32:42 -05002109 _self = getattr(obj, '__self__', None)
2110 self_isbound = _self is not None
2111 self_ismodule = ismodule(_self)
2112 if self_isbound and (self_ismodule or skip_bound_arg):
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002113 parameters.pop(0)
2114 else:
2115 # for builtins, self parameter is always positional-only!
2116 p = parameters[0].replace(kind=Parameter.POSITIONAL_ONLY)
2117 parameters[0] = p
2118
2119 return cls(parameters, return_annotation=cls.empty)
2120
2121
Yury Selivanov57d240e2014-02-19 16:27:23 -05002122def _signature_from_builtin(cls, func, skip_bound_arg=True):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002123 """Private helper function to get signature for
2124 builtin callables.
2125 """
2126
Yury Selivanov57d240e2014-02-19 16:27:23 -05002127 if not _signature_is_builtin(func):
2128 raise TypeError("{!r} is not a Python builtin "
2129 "function".format(func))
2130
2131 s = getattr(func, "__text_signature__", None)
2132 if not s:
2133 raise ValueError("no signature found for builtin {!r}".format(func))
2134
2135 return _signature_fromstr(cls, func, s, skip_bound_arg)
2136
2137
Serhiy Storchakad53cf992019-05-06 22:40:27 +03002138def _signature_from_function(cls, func, skip_bound_arg=True):
Yury Selivanovcf45f022015-05-20 14:38:50 -04002139 """Private helper: constructs Signature for the given python function."""
2140
2141 is_duck_function = False
2142 if not isfunction(func):
2143 if _signature_is_functionlike(func):
2144 is_duck_function = True
2145 else:
2146 # If it's not a pure Python function, and not a duck type
2147 # of pure function:
2148 raise TypeError('{!r} is not a Python function'.format(func))
2149
Serhiy Storchakad53cf992019-05-06 22:40:27 +03002150 s = getattr(func, "__text_signature__", None)
2151 if s:
2152 return _signature_fromstr(cls, func, s, skip_bound_arg)
2153
Yury Selivanovcf45f022015-05-20 14:38:50 -04002154 Parameter = cls._parameter_cls
2155
2156 # Parameter information.
2157 func_code = func.__code__
2158 pos_count = func_code.co_argcount
2159 arg_names = func_code.co_varnames
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002160 posonly_count = func_code.co_posonlyargcount
Pablo Galindocd74e662019-06-01 18:08:04 +01002161 positional = arg_names[:pos_count]
Yury Selivanovcf45f022015-05-20 14:38:50 -04002162 keyword_only_count = func_code.co_kwonlyargcount
Pablo Galindocd74e662019-06-01 18:08:04 +01002163 keyword_only = arg_names[pos_count:pos_count + keyword_only_count]
Yury Selivanovcf45f022015-05-20 14:38:50 -04002164 annotations = func.__annotations__
2165 defaults = func.__defaults__
2166 kwdefaults = func.__kwdefaults__
2167
2168 if defaults:
2169 pos_default_count = len(defaults)
2170 else:
2171 pos_default_count = 0
2172
2173 parameters = []
2174
Pablo Galindocd74e662019-06-01 18:08:04 +01002175 non_default_count = pos_count - pos_default_count
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002176 posonly_left = posonly_count
2177
Yury Selivanovcf45f022015-05-20 14:38:50 -04002178 # Non-keyword-only parameters w/o defaults.
Pablo Galindocd74e662019-06-01 18:08:04 +01002179 for name in positional[:non_default_count]:
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002180 kind = _POSITIONAL_ONLY if posonly_left else _POSITIONAL_OR_KEYWORD
Yury Selivanovcf45f022015-05-20 14:38:50 -04002181 annotation = annotations.get(name, _empty)
2182 parameters.append(Parameter(name, annotation=annotation,
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002183 kind=kind))
2184 if posonly_left:
2185 posonly_left -= 1
Yury Selivanovcf45f022015-05-20 14:38:50 -04002186
2187 # ... w/ defaults.
Pablo Galindocd74e662019-06-01 18:08:04 +01002188 for offset, name in enumerate(positional[non_default_count:]):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002189 kind = _POSITIONAL_ONLY if posonly_left else _POSITIONAL_OR_KEYWORD
Yury Selivanovcf45f022015-05-20 14:38:50 -04002190 annotation = annotations.get(name, _empty)
2191 parameters.append(Parameter(name, annotation=annotation,
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002192 kind=kind,
Yury Selivanovcf45f022015-05-20 14:38:50 -04002193 default=defaults[offset]))
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002194 if posonly_left:
2195 posonly_left -= 1
Yury Selivanovcf45f022015-05-20 14:38:50 -04002196
2197 # *args
2198 if func_code.co_flags & CO_VARARGS:
Pablo Galindocd74e662019-06-01 18:08:04 +01002199 name = arg_names[pos_count + keyword_only_count]
Yury Selivanovcf45f022015-05-20 14:38:50 -04002200 annotation = annotations.get(name, _empty)
2201 parameters.append(Parameter(name, annotation=annotation,
2202 kind=_VAR_POSITIONAL))
2203
2204 # Keyword-only parameters.
2205 for name in keyword_only:
2206 default = _empty
2207 if kwdefaults is not None:
2208 default = kwdefaults.get(name, _empty)
2209
2210 annotation = annotations.get(name, _empty)
2211 parameters.append(Parameter(name, annotation=annotation,
2212 kind=_KEYWORD_ONLY,
2213 default=default))
2214 # **kwargs
2215 if func_code.co_flags & CO_VARKEYWORDS:
Pablo Galindocd74e662019-06-01 18:08:04 +01002216 index = pos_count + keyword_only_count
Yury Selivanovcf45f022015-05-20 14:38:50 -04002217 if func_code.co_flags & CO_VARARGS:
2218 index += 1
2219
2220 name = arg_names[index]
2221 annotation = annotations.get(name, _empty)
2222 parameters.append(Parameter(name, annotation=annotation,
2223 kind=_VAR_KEYWORD))
2224
2225 # Is 'func' is a pure Python function - don't validate the
2226 # parameters list (for correct order and defaults), it should be OK.
2227 return cls(parameters,
2228 return_annotation=annotations.get('return', _empty),
2229 __validate_parameters__=is_duck_function)
2230
2231
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002232def _signature_from_callable(obj, *,
2233 follow_wrapper_chains=True,
2234 skip_bound_arg=True,
2235 sigcls):
2236
2237 """Private helper function to get signature for arbitrary
2238 callable objects.
2239 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002240
2241 if not callable(obj):
2242 raise TypeError('{!r} is not a callable object'.format(obj))
2243
2244 if isinstance(obj, types.MethodType):
2245 # In this case we skip the first parameter of the underlying
2246 # function (usually `self` or `cls`).
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002247 sig = _signature_from_callable(
Yury Selivanovda396452014-03-27 12:09:24 -04002248 obj.__func__,
2249 follow_wrapper_chains=follow_wrapper_chains,
2250 skip_bound_arg=skip_bound_arg,
2251 sigcls=sigcls)
2252
Yury Selivanov57d240e2014-02-19 16:27:23 -05002253 if skip_bound_arg:
2254 return _signature_bound_method(sig)
2255 else:
2256 return sig
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002257
Nick Coghlane8c45d62013-07-28 20:00:01 +10002258 # Was this function wrapped by a decorator?
Yury Selivanov57d240e2014-02-19 16:27:23 -05002259 if follow_wrapper_chains:
2260 obj = unwrap(obj, stop=(lambda f: hasattr(f, "__signature__")))
Yury Selivanov46c759d2015-05-27 21:56:53 -04002261 if isinstance(obj, types.MethodType):
2262 # If the unwrapped object is a *method*, we might want to
2263 # skip its first parameter (self).
2264 # See test_signature_wrapped_bound_method for details.
Yury Selivanov507cd3c2015-05-27 21:59:03 -04002265 return _signature_from_callable(
Yury Selivanov46c759d2015-05-27 21:56:53 -04002266 obj,
2267 follow_wrapper_chains=follow_wrapper_chains,
Yury Selivanov507cd3c2015-05-27 21:59:03 -04002268 skip_bound_arg=skip_bound_arg,
2269 sigcls=sigcls)
Nick Coghlane8c45d62013-07-28 20:00:01 +10002270
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002271 try:
2272 sig = obj.__signature__
2273 except AttributeError:
2274 pass
2275 else:
2276 if sig is not None:
Yury Selivanov42407ab2014-06-23 10:23:50 -07002277 if not isinstance(sig, Signature):
2278 raise TypeError(
2279 'unexpected object {!r} in __signature__ '
2280 'attribute'.format(sig))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002281 return sig
2282
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002283 try:
2284 partialmethod = obj._partialmethod
2285 except AttributeError:
2286 pass
2287 else:
Yury Selivanov0486f812014-01-29 12:18:59 -05002288 if isinstance(partialmethod, functools.partialmethod):
2289 # Unbound partialmethod (see functools.partialmethod)
2290 # This means, that we need to calculate the signature
2291 # as if it's a regular partial object, but taking into
2292 # account that the first positional argument
2293 # (usually `self`, or `cls`) will not be passed
2294 # automatically (as for boundmethods)
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002295
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002296 wrapped_sig = _signature_from_callable(
Yury Selivanovda396452014-03-27 12:09:24 -04002297 partialmethod.func,
2298 follow_wrapper_chains=follow_wrapper_chains,
2299 skip_bound_arg=skip_bound_arg,
2300 sigcls=sigcls)
2301
Yury Selivanov0486f812014-01-29 12:18:59 -05002302 sig = _signature_get_partial(wrapped_sig, partialmethod, (None,))
Yury Selivanov0486f812014-01-29 12:18:59 -05002303 first_wrapped_param = tuple(wrapped_sig.parameters.values())[0]
Dong-hee Na378d7062017-05-18 04:00:51 +09002304 if first_wrapped_param.kind is Parameter.VAR_POSITIONAL:
2305 # First argument of the wrapped callable is `*args`, as in
2306 # `partialmethod(lambda *args)`.
2307 return sig
2308 else:
2309 sig_params = tuple(sig.parameters.values())
Yury Selivanov8a387212018-03-06 12:59:45 -05002310 assert (not sig_params or
2311 first_wrapped_param is not sig_params[0])
Dong-hee Na378d7062017-05-18 04:00:51 +09002312 new_params = (first_wrapped_param,) + sig_params
2313 return sig.replace(parameters=new_params)
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002314
Yury Selivanov63da7c72014-01-31 14:48:37 -05002315 if isfunction(obj) or _signature_is_functionlike(obj):
2316 # If it's a pure Python function, or an object that is duck type
2317 # of a Python function (Cython functions, for instance), then:
Serhiy Storchakad53cf992019-05-06 22:40:27 +03002318 return _signature_from_function(sigcls, obj,
2319 skip_bound_arg=skip_bound_arg)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002320
Yury Selivanova773de02014-02-21 18:30:53 -05002321 if _signature_is_builtin(obj):
Yury Selivanovda396452014-03-27 12:09:24 -04002322 return _signature_from_builtin(sigcls, obj,
Yury Selivanova773de02014-02-21 18:30:53 -05002323 skip_bound_arg=skip_bound_arg)
2324
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002325 if isinstance(obj, functools.partial):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002326 wrapped_sig = _signature_from_callable(
Yury Selivanovda396452014-03-27 12:09:24 -04002327 obj.func,
2328 follow_wrapper_chains=follow_wrapper_chains,
2329 skip_bound_arg=skip_bound_arg,
2330 sigcls=sigcls)
Yury Selivanov62560fb2014-01-28 12:26:24 -05002331 return _signature_get_partial(wrapped_sig, obj)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002332
2333 sig = None
2334 if isinstance(obj, type):
2335 # obj is a class or a metaclass
2336
2337 # First, let's see if it has an overloaded __call__ defined
2338 # in its metaclass
Yury Selivanov421f0c72014-01-29 12:05:40 -05002339 call = _signature_get_user_defined_method(type(obj), '__call__')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002340 if call is not None:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002341 sig = _signature_from_callable(
Yury Selivanovda396452014-03-27 12:09:24 -04002342 call,
2343 follow_wrapper_chains=follow_wrapper_chains,
2344 skip_bound_arg=skip_bound_arg,
2345 sigcls=sigcls)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002346 else:
2347 # Now we check if the 'obj' class has a '__new__' method
Yury Selivanov421f0c72014-01-29 12:05:40 -05002348 new = _signature_get_user_defined_method(obj, '__new__')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002349 if new is not None:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002350 sig = _signature_from_callable(
Yury Selivanovda396452014-03-27 12:09:24 -04002351 new,
2352 follow_wrapper_chains=follow_wrapper_chains,
2353 skip_bound_arg=skip_bound_arg,
2354 sigcls=sigcls)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002355 else:
2356 # Finally, we should have at least __init__ implemented
Yury Selivanov421f0c72014-01-29 12:05:40 -05002357 init = _signature_get_user_defined_method(obj, '__init__')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002358 if init is not None:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002359 sig = _signature_from_callable(
Yury Selivanovda396452014-03-27 12:09:24 -04002360 init,
2361 follow_wrapper_chains=follow_wrapper_chains,
2362 skip_bound_arg=skip_bound_arg,
2363 sigcls=sigcls)
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002364
2365 if sig is None:
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002366 # At this point we know, that `obj` is a class, with no user-
2367 # defined '__init__', '__new__', or class-level '__call__'
2368
Larry Hastings2623c8c2014-02-08 22:15:29 -08002369 for base in obj.__mro__[:-1]:
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002370 # Since '__text_signature__' is implemented as a
2371 # descriptor that extracts text signature from the
2372 # class docstring, if 'obj' is derived from a builtin
2373 # class, its own '__text_signature__' may be 'None'.
Larry Hastings2623c8c2014-02-08 22:15:29 -08002374 # Therefore, we go through the MRO (except the last
2375 # class in there, which is 'object') to find the first
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002376 # class with non-empty text signature.
2377 try:
2378 text_sig = base.__text_signature__
2379 except AttributeError:
2380 pass
2381 else:
2382 if text_sig:
2383 # If 'obj' class has a __text_signature__ attribute:
2384 # return a signature based on it
Yury Selivanovda396452014-03-27 12:09:24 -04002385 return _signature_fromstr(sigcls, obj, text_sig)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002386
2387 # No '__text_signature__' was found for the 'obj' class.
2388 # Last option is to check if its '__init__' is
2389 # object.__init__ or type.__init__.
Larry Hastings2623c8c2014-02-08 22:15:29 -08002390 if type not in obj.__mro__:
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002391 # We have a class (not metaclass), but no user-defined
2392 # __init__ or __new__ for it
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002393 if (obj.__init__ is object.__init__ and
2394 obj.__new__ is object.__new__):
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002395 # Return a signature of 'object' builtin.
Gregory P. Smith5b9ff7a2019-09-13 17:13:51 +01002396 return sigcls.from_callable(object)
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002397 else:
2398 raise ValueError(
2399 'no signature found for builtin type {!r}'.format(obj))
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002400
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002401 elif not isinstance(obj, _NonUserDefinedCallables):
2402 # An object with __call__
2403 # We also check that the 'obj' is not an instance of
2404 # _WrapperDescriptor or _MethodWrapper to avoid
2405 # infinite recursion (and even potential segfault)
Yury Selivanov421f0c72014-01-29 12:05:40 -05002406 call = _signature_get_user_defined_method(type(obj), '__call__')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002407 if call is not None:
Larry Hastings2623c8c2014-02-08 22:15:29 -08002408 try:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002409 sig = _signature_from_callable(
Yury Selivanovda396452014-03-27 12:09:24 -04002410 call,
2411 follow_wrapper_chains=follow_wrapper_chains,
2412 skip_bound_arg=skip_bound_arg,
2413 sigcls=sigcls)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002414 except ValueError as ex:
2415 msg = 'no signature found for {!r}'.format(obj)
2416 raise ValueError(msg) from ex
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002417
2418 if sig is not None:
2419 # For classes and objects we skip the first parameter of their
2420 # __call__, __new__, or __init__ methods
Yury Selivanov57d240e2014-02-19 16:27:23 -05002421 if skip_bound_arg:
2422 return _signature_bound_method(sig)
2423 else:
2424 return sig
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002425
2426 if isinstance(obj, types.BuiltinFunctionType):
2427 # Raise a nicer error message for builtins
2428 msg = 'no signature found for builtin function {!r}'.format(obj)
2429 raise ValueError(msg)
2430
2431 raise ValueError('callable {!r} is not supported by signature'.format(obj))
2432
2433
2434class _void:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002435 """A private marker - used in Parameter & Signature."""
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002436
2437
2438class _empty:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002439 """Marker object for Signature.empty and Parameter.empty."""
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002440
2441
Yury Selivanov21e83a52014-03-27 11:23:13 -04002442class _ParameterKind(enum.IntEnum):
2443 POSITIONAL_ONLY = 0
2444 POSITIONAL_OR_KEYWORD = 1
2445 VAR_POSITIONAL = 2
2446 KEYWORD_ONLY = 3
2447 VAR_KEYWORD = 4
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002448
2449 def __str__(self):
Yury Selivanov21e83a52014-03-27 11:23:13 -04002450 return self._name_
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002451
Dong-hee Na4aa30062018-06-08 12:46:31 +09002452 @property
2453 def description(self):
2454 return _PARAM_NAME_MAPPING[self]
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002455
Yury Selivanov21e83a52014-03-27 11:23:13 -04002456_POSITIONAL_ONLY = _ParameterKind.POSITIONAL_ONLY
2457_POSITIONAL_OR_KEYWORD = _ParameterKind.POSITIONAL_OR_KEYWORD
2458_VAR_POSITIONAL = _ParameterKind.VAR_POSITIONAL
2459_KEYWORD_ONLY = _ParameterKind.KEYWORD_ONLY
2460_VAR_KEYWORD = _ParameterKind.VAR_KEYWORD
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002461
Dong-hee Naa9cab432018-05-30 00:04:08 +09002462_PARAM_NAME_MAPPING = {
2463 _POSITIONAL_ONLY: 'positional-only',
2464 _POSITIONAL_OR_KEYWORD: 'positional or keyword',
2465 _VAR_POSITIONAL: 'variadic positional',
2466 _KEYWORD_ONLY: 'keyword-only',
2467 _VAR_KEYWORD: 'variadic keyword'
2468}
2469
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002470
2471class Parameter:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002472 """Represents a parameter in a function signature.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002473
2474 Has the following public attributes:
2475
2476 * name : str
2477 The name of the parameter as a string.
2478 * default : object
2479 The default value for the parameter if specified. If the
Yury Selivanov8757ead2014-01-28 16:39:25 -05002480 parameter has no default value, this attribute is set to
2481 `Parameter.empty`.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002482 * annotation
2483 The annotation for the parameter if specified. If the
Yury Selivanov8757ead2014-01-28 16:39:25 -05002484 parameter has no annotation, this attribute is set to
2485 `Parameter.empty`.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002486 * kind : str
2487 Describes how argument values are bound to the parameter.
2488 Possible values: `Parameter.POSITIONAL_ONLY`,
2489 `Parameter.POSITIONAL_OR_KEYWORD`, `Parameter.VAR_POSITIONAL`,
2490 `Parameter.KEYWORD_ONLY`, `Parameter.VAR_KEYWORD`.
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002491 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002492
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002493 __slots__ = ('_name', '_kind', '_default', '_annotation')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002494
2495 POSITIONAL_ONLY = _POSITIONAL_ONLY
2496 POSITIONAL_OR_KEYWORD = _POSITIONAL_OR_KEYWORD
2497 VAR_POSITIONAL = _VAR_POSITIONAL
2498 KEYWORD_ONLY = _KEYWORD_ONLY
2499 VAR_KEYWORD = _VAR_KEYWORD
2500
2501 empty = _empty
2502
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002503 def __init__(self, name, kind, *, default=_empty, annotation=_empty):
Dong-hee Naa9cab432018-05-30 00:04:08 +09002504 try:
2505 self._kind = _ParameterKind(kind)
2506 except ValueError:
2507 raise ValueError(f'value {kind!r} is not a valid Parameter.kind')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002508 if default is not _empty:
Dong-hee Naa9cab432018-05-30 00:04:08 +09002509 if self._kind in (_VAR_POSITIONAL, _VAR_KEYWORD):
2510 msg = '{} parameters cannot have default values'
Dong-hee Na4aa30062018-06-08 12:46:31 +09002511 msg = msg.format(self._kind.description)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002512 raise ValueError(msg)
2513 self._default = default
2514 self._annotation = annotation
2515
Yury Selivanov2393dca2014-01-27 15:07:58 -05002516 if name is _empty:
2517 raise ValueError('name is a required attribute for Parameter')
2518
2519 if not isinstance(name, str):
Dong-hee Naa9cab432018-05-30 00:04:08 +09002520 msg = 'name must be a str, not a {}'.format(type(name).__name__)
2521 raise TypeError(msg)
Yury Selivanov2393dca2014-01-27 15:07:58 -05002522
Nick Coghlanb4b966e2016-06-04 14:40:03 -07002523 if name[0] == '.' and name[1:].isdigit():
2524 # These are implicit arguments generated by comprehensions. In
2525 # order to provide a friendlier interface to users, we recast
2526 # their name as "implicitN" and treat them as positional-only.
2527 # See issue 19611.
Dong-hee Naa9cab432018-05-30 00:04:08 +09002528 if self._kind != _POSITIONAL_OR_KEYWORD:
2529 msg = (
2530 'implicit arguments must be passed as '
2531 'positional or keyword arguments, not {}'
Nick Coghlanb4b966e2016-06-04 14:40:03 -07002532 )
Dong-hee Na4aa30062018-06-08 12:46:31 +09002533 msg = msg.format(self._kind.description)
Dong-hee Naa9cab432018-05-30 00:04:08 +09002534 raise ValueError(msg)
Nick Coghlanb4b966e2016-06-04 14:40:03 -07002535 self._kind = _POSITIONAL_ONLY
2536 name = 'implicit{}'.format(name[1:])
2537
Yury Selivanov2393dca2014-01-27 15:07:58 -05002538 if not name.isidentifier():
2539 raise ValueError('{!r} is not a valid parameter name'.format(name))
2540
2541 self._name = name
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002542
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002543 def __reduce__(self):
2544 return (type(self),
2545 (self._name, self._kind),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002546 {'_default': self._default,
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002547 '_annotation': self._annotation})
2548
2549 def __setstate__(self, state):
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002550 self._default = state['_default']
2551 self._annotation = state['_annotation']
2552
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002553 @property
2554 def name(self):
2555 return self._name
2556
2557 @property
2558 def default(self):
2559 return self._default
2560
2561 @property
2562 def annotation(self):
2563 return self._annotation
2564
2565 @property
2566 def kind(self):
2567 return self._kind
2568
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002569 def replace(self, *, name=_void, kind=_void,
2570 annotation=_void, default=_void):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002571 """Creates a customized copy of the Parameter."""
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002572
2573 if name is _void:
2574 name = self._name
2575
2576 if kind is _void:
2577 kind = self._kind
2578
2579 if annotation is _void:
2580 annotation = self._annotation
2581
2582 if default is _void:
2583 default = self._default
2584
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002585 return type(self)(name, kind, default=default, annotation=annotation)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002586
2587 def __str__(self):
2588 kind = self.kind
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002589 formatted = self._name
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002590
2591 # Add annotation and default value
2592 if self._annotation is not _empty:
Dong-hee Na762b9572017-11-16 03:30:59 +09002593 formatted = '{}: {}'.format(formatted,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002594 formatannotation(self._annotation))
2595
2596 if self._default is not _empty:
Dong-hee Na762b9572017-11-16 03:30:59 +09002597 if self._annotation is not _empty:
2598 formatted = '{} = {}'.format(formatted, repr(self._default))
2599 else:
2600 formatted = '{}={}'.format(formatted, repr(self._default))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002601
2602 if kind == _VAR_POSITIONAL:
2603 formatted = '*' + formatted
2604 elif kind == _VAR_KEYWORD:
2605 formatted = '**' + formatted
2606
2607 return formatted
2608
2609 def __repr__(self):
Yury Selivanovf229bc52015-05-15 12:53:56 -04002610 return '<{} "{}">'.format(self.__class__.__name__, self)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002611
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002612 def __hash__(self):
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002613 return hash((self.name, self.kind, self.annotation, self.default))
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002614
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002615 def __eq__(self, other):
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03002616 if self is other:
2617 return True
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002618 if not isinstance(other, Parameter):
2619 return NotImplemented
2620 return (self._name == other._name and
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002621 self._kind == other._kind and
2622 self._default == other._default and
2623 self._annotation == other._annotation)
2624
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002625
2626class BoundArguments:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002627 """Result of `Signature.bind` call. Holds the mapping of arguments
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002628 to the function's parameters.
2629
2630 Has the following public attributes:
2631
Rémi Lapeyre2cca8ef2020-01-28 13:47:03 +01002632 * arguments : dict
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002633 An ordered mutable mapping of parameters' names to arguments' values.
2634 Does not contain arguments' default values.
2635 * signature : Signature
2636 The Signature object that created this instance.
2637 * args : tuple
2638 Tuple of positional arguments values.
2639 * kwargs : dict
2640 Dict of keyword arguments values.
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002641 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002642
Yury Selivanov6abe0322015-05-13 17:18:41 -04002643 __slots__ = ('arguments', '_signature', '__weakref__')
2644
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002645 def __init__(self, signature, arguments):
2646 self.arguments = arguments
2647 self._signature = signature
2648
2649 @property
2650 def signature(self):
2651 return self._signature
2652
2653 @property
2654 def args(self):
2655 args = []
2656 for param_name, param in self._signature.parameters.items():
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002657 if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002658 break
2659
2660 try:
2661 arg = self.arguments[param_name]
2662 except KeyError:
2663 # We're done here. Other arguments
2664 # will be mapped in 'BoundArguments.kwargs'
2665 break
2666 else:
2667 if param.kind == _VAR_POSITIONAL:
2668 # *args
2669 args.extend(arg)
2670 else:
2671 # plain argument
2672 args.append(arg)
2673
2674 return tuple(args)
2675
2676 @property
2677 def kwargs(self):
2678 kwargs = {}
2679 kwargs_started = False
2680 for param_name, param in self._signature.parameters.items():
2681 if not kwargs_started:
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002682 if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002683 kwargs_started = True
2684 else:
2685 if param_name not in self.arguments:
2686 kwargs_started = True
2687 continue
2688
2689 if not kwargs_started:
2690 continue
2691
2692 try:
2693 arg = self.arguments[param_name]
2694 except KeyError:
2695 pass
2696 else:
2697 if param.kind == _VAR_KEYWORD:
2698 # **kwargs
2699 kwargs.update(arg)
2700 else:
2701 # plain keyword argument
2702 kwargs[param_name] = arg
2703
2704 return kwargs
2705
Yury Selivanovb907a512015-05-16 13:45:09 -04002706 def apply_defaults(self):
2707 """Set default values for missing arguments.
2708
2709 For variable-positional arguments (*args) the default is an
2710 empty tuple.
2711
2712 For variable-keyword arguments (**kwargs) the default is an
2713 empty dict.
2714 """
2715 arguments = self.arguments
Yury Selivanovb907a512015-05-16 13:45:09 -04002716 new_arguments = []
2717 for name, param in self._signature.parameters.items():
2718 try:
2719 new_arguments.append((name, arguments[name]))
2720 except KeyError:
2721 if param.default is not _empty:
2722 val = param.default
2723 elif param.kind is _VAR_POSITIONAL:
2724 val = ()
2725 elif param.kind is _VAR_KEYWORD:
2726 val = {}
2727 else:
2728 # This BoundArguments was likely produced by
2729 # Signature.bind_partial().
2730 continue
2731 new_arguments.append((name, val))
Rémi Lapeyre2cca8ef2020-01-28 13:47:03 +01002732 self.arguments = dict(new_arguments)
Yury Selivanovb907a512015-05-16 13:45:09 -04002733
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002734 def __eq__(self, other):
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03002735 if self is other:
2736 return True
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002737 if not isinstance(other, BoundArguments):
2738 return NotImplemented
2739 return (self.signature == other.signature and
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002740 self.arguments == other.arguments)
2741
Yury Selivanov6abe0322015-05-13 17:18:41 -04002742 def __setstate__(self, state):
2743 self._signature = state['_signature']
2744 self.arguments = state['arguments']
2745
2746 def __getstate__(self):
2747 return {'_signature': self._signature, 'arguments': self.arguments}
2748
Yury Selivanov3f6538f2015-05-14 18:47:17 -04002749 def __repr__(self):
2750 args = []
2751 for arg, value in self.arguments.items():
2752 args.append('{}={!r}'.format(arg, value))
Yury Selivanovf229bc52015-05-15 12:53:56 -04002753 return '<{} ({})>'.format(self.__class__.__name__, ', '.join(args))
Yury Selivanov3f6538f2015-05-14 18:47:17 -04002754
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002755
2756class Signature:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002757 """A Signature object represents the overall signature of a function.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002758 It stores a Parameter object for each parameter accepted by the
2759 function, as well as information specific to the function itself.
2760
2761 A Signature object has the following public attributes and methods:
2762
Jens Reidel611836a2020-03-18 03:22:46 +01002763 * parameters : OrderedDict
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002764 An ordered mapping of parameters' names to the corresponding
2765 Parameter objects (keyword-only arguments are in the same order
2766 as listed in `code.co_varnames`).
2767 * return_annotation : object
2768 The annotation for the return type of the function if specified.
2769 If the function has no annotation for its return type, this
Yury Selivanov8757ead2014-01-28 16:39:25 -05002770 attribute is set to `Signature.empty`.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002771 * bind(*args, **kwargs) -> BoundArguments
2772 Creates a mapping from positional and keyword arguments to
2773 parameters.
2774 * bind_partial(*args, **kwargs) -> BoundArguments
2775 Creates a partial mapping from positional and keyword arguments
2776 to parameters (simulating 'functools.partial' behavior.)
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002777 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002778
2779 __slots__ = ('_return_annotation', '_parameters')
2780
2781 _parameter_cls = Parameter
2782 _bound_arguments_cls = BoundArguments
2783
2784 empty = _empty
2785
2786 def __init__(self, parameters=None, *, return_annotation=_empty,
2787 __validate_parameters__=True):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002788 """Constructs Signature from the given list of Parameter
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002789 objects and 'return_annotation'. All arguments are optional.
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002790 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002791
2792 if parameters is None:
Jens Reidel611836a2020-03-18 03:22:46 +01002793 params = OrderedDict()
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002794 else:
2795 if __validate_parameters__:
Jens Reidel611836a2020-03-18 03:22:46 +01002796 params = OrderedDict()
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002797 top_kind = _POSITIONAL_ONLY
Yury Selivanov07a9e452014-01-29 10:58:16 -05002798 kind_defaults = False
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002799
Rémi Lapeyre2cca8ef2020-01-28 13:47:03 +01002800 for param in parameters:
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002801 kind = param.kind
Yury Selivanov2393dca2014-01-27 15:07:58 -05002802 name = param.name
2803
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002804 if kind < top_kind:
Dong-hee Naa9cab432018-05-30 00:04:08 +09002805 msg = (
2806 'wrong parameter order: {} parameter before {} '
2807 'parameter'
2808 )
Dong-hee Na4aa30062018-06-08 12:46:31 +09002809 msg = msg.format(top_kind.description,
2810 kind.description)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002811 raise ValueError(msg)
Yury Selivanov07a9e452014-01-29 10:58:16 -05002812 elif kind > top_kind:
2813 kind_defaults = False
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002814 top_kind = kind
2815
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002816 if kind in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD):
Yury Selivanov07a9e452014-01-29 10:58:16 -05002817 if param.default is _empty:
2818 if kind_defaults:
2819 # No default for this parameter, but the
2820 # previous parameter of the same kind had
2821 # a default
2822 msg = 'non-default argument follows default ' \
2823 'argument'
2824 raise ValueError(msg)
2825 else:
2826 # There is a default for this parameter.
2827 kind_defaults = True
2828
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002829 if name in params:
2830 msg = 'duplicate parameter name: {!r}'.format(name)
2831 raise ValueError(msg)
Yury Selivanov2393dca2014-01-27 15:07:58 -05002832
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002833 params[name] = param
2834 else:
Jens Reidel611836a2020-03-18 03:22:46 +01002835 params = OrderedDict((param.name, param) for param in parameters)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002836
2837 self._parameters = types.MappingProxyType(params)
2838 self._return_annotation = return_annotation
2839
2840 @classmethod
2841 def from_function(cls, func):
Matthias Bussonnierded87d82018-10-19 16:40:45 -07002842 """Constructs Signature for the given python function.
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002843
Matthias Bussonnierded87d82018-10-19 16:40:45 -07002844 Deprecated since Python 3.5, use `Signature.from_callable()`.
2845 """
2846
2847 warnings.warn("inspect.Signature.from_function() is deprecated since "
2848 "Python 3.5, use Signature.from_callable()",
Berker Peksagb5601582015-05-21 23:40:54 +03002849 DeprecationWarning, stacklevel=2)
Yury Selivanovcf45f022015-05-20 14:38:50 -04002850 return _signature_from_function(cls, func)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002851
Larry Hastings44e2eaa2013-11-23 15:37:55 -08002852 @classmethod
2853 def from_builtin(cls, func):
Matthias Bussonnierded87d82018-10-19 16:40:45 -07002854 """Constructs Signature for the given builtin function.
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002855
Matthias Bussonnierded87d82018-10-19 16:40:45 -07002856 Deprecated since Python 3.5, use `Signature.from_callable()`.
2857 """
2858
2859 warnings.warn("inspect.Signature.from_builtin() is deprecated since "
2860 "Python 3.5, use Signature.from_callable()",
Berker Peksagb5601582015-05-21 23:40:54 +03002861 DeprecationWarning, stacklevel=2)
Yury Selivanov57d240e2014-02-19 16:27:23 -05002862 return _signature_from_builtin(cls, func)
Larry Hastings44e2eaa2013-11-23 15:37:55 -08002863
Yury Selivanovda396452014-03-27 12:09:24 -04002864 @classmethod
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002865 def from_callable(cls, obj, *, follow_wrapped=True):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002866 """Constructs Signature for the given callable object."""
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002867 return _signature_from_callable(obj, sigcls=cls,
2868 follow_wrapper_chains=follow_wrapped)
Yury Selivanovda396452014-03-27 12:09:24 -04002869
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002870 @property
2871 def parameters(self):
2872 return self._parameters
2873
2874 @property
2875 def return_annotation(self):
2876 return self._return_annotation
2877
2878 def replace(self, *, parameters=_void, return_annotation=_void):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002879 """Creates a customized copy of the Signature.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002880 Pass 'parameters' and/or 'return_annotation' arguments
2881 to override them in the new copy.
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002882 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002883
2884 if parameters is _void:
2885 parameters = self.parameters.values()
2886
2887 if return_annotation is _void:
2888 return_annotation = self._return_annotation
2889
2890 return type(self)(parameters,
2891 return_annotation=return_annotation)
2892
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002893 def _hash_basis(self):
2894 params = tuple(param for param in self.parameters.values()
2895 if param.kind != _KEYWORD_ONLY)
2896
2897 kwo_params = {param.name: param for param in self.parameters.values()
2898 if param.kind == _KEYWORD_ONLY}
2899
2900 return params, kwo_params, self.return_annotation
2901
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002902 def __hash__(self):
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002903 params, kwo_params, return_annotation = self._hash_basis()
2904 kwo_params = frozenset(kwo_params.values())
2905 return hash((params, kwo_params, return_annotation))
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002906
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002907 def __eq__(self, other):
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03002908 if self is other:
2909 return True
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002910 if not isinstance(other, Signature):
2911 return NotImplemented
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03002912 return self._hash_basis() == other._hash_basis()
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002913
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002914 def _bind(self, args, kwargs, *, partial=False):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002915 """Private method. Don't use directly."""
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002916
Rémi Lapeyre2cca8ef2020-01-28 13:47:03 +01002917 arguments = {}
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002918
2919 parameters = iter(self.parameters.values())
2920 parameters_ex = ()
2921 arg_vals = iter(args)
2922
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002923 while True:
2924 # Let's iterate through the positional arguments and corresponding
2925 # parameters
2926 try:
2927 arg_val = next(arg_vals)
2928 except StopIteration:
2929 # No more positional arguments
2930 try:
2931 param = next(parameters)
2932 except StopIteration:
2933 # No more parameters. That's it. Just need to check that
2934 # we have no `kwargs` after this while loop
2935 break
2936 else:
2937 if param.kind == _VAR_POSITIONAL:
2938 # That's OK, just empty *args. Let's start parsing
2939 # kwargs
2940 break
2941 elif param.name in kwargs:
2942 if param.kind == _POSITIONAL_ONLY:
2943 msg = '{arg!r} parameter is positional only, ' \
2944 'but was passed as a keyword'
2945 msg = msg.format(arg=param.name)
2946 raise TypeError(msg) from None
2947 parameters_ex = (param,)
2948 break
2949 elif (param.kind == _VAR_KEYWORD or
2950 param.default is not _empty):
2951 # That's fine too - we have a default value for this
2952 # parameter. So, lets start parsing `kwargs`, starting
2953 # with the current parameter
2954 parameters_ex = (param,)
2955 break
2956 else:
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05002957 # No default, not VAR_KEYWORD, not VAR_POSITIONAL,
2958 # not in `kwargs`
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002959 if partial:
2960 parameters_ex = (param,)
2961 break
2962 else:
Yury Selivanov86872752015-05-19 00:27:49 -04002963 msg = 'missing a required argument: {arg!r}'
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002964 msg = msg.format(arg=param.name)
2965 raise TypeError(msg) from None
2966 else:
2967 # We have a positional argument to process
2968 try:
2969 param = next(parameters)
2970 except StopIteration:
2971 raise TypeError('too many positional arguments') from None
2972 else:
2973 if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
2974 # Looks like we have no parameter for this positional
2975 # argument
Yury Selivanov86872752015-05-19 00:27:49 -04002976 raise TypeError(
2977 'too many positional arguments') from None
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002978
2979 if param.kind == _VAR_POSITIONAL:
2980 # We have an '*args'-like argument, let's fill it with
2981 # all positional arguments we have left and move on to
2982 # the next phase
2983 values = [arg_val]
2984 values.extend(arg_vals)
2985 arguments[param.name] = tuple(values)
2986 break
2987
Pablo Galindof3ef06a2019-10-15 12:40:02 +01002988 if param.name in kwargs and param.kind != _POSITIONAL_ONLY:
Yury Selivanov86872752015-05-19 00:27:49 -04002989 raise TypeError(
2990 'multiple values for argument {arg!r}'.format(
2991 arg=param.name)) from None
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002992
2993 arguments[param.name] = arg_val
2994
2995 # Now, we iterate through the remaining parameters to process
2996 # keyword arguments
2997 kwargs_param = None
2998 for param in itertools.chain(parameters_ex, parameters):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002999 if param.kind == _VAR_KEYWORD:
3000 # Memorize that we have a '**kwargs'-like parameter
3001 kwargs_param = param
3002 continue
3003
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003004 if param.kind == _VAR_POSITIONAL:
3005 # Named arguments don't refer to '*args'-like parameters.
3006 # We only arrive here if the positional arguments ended
3007 # before reaching the last parameter before *args.
3008 continue
3009
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003010 param_name = param.name
3011 try:
3012 arg_val = kwargs.pop(param_name)
3013 except KeyError:
3014 # We have no value for this parameter. It's fine though,
3015 # if it has a default value, or it is an '*args'-like
3016 # parameter, left alone by the processing of positional
3017 # arguments.
3018 if (not partial and param.kind != _VAR_POSITIONAL and
3019 param.default is _empty):
Yury Selivanov86872752015-05-19 00:27:49 -04003020 raise TypeError('missing a required argument: {arg!r}'. \
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003021 format(arg=param_name)) from None
3022
3023 else:
Yury Selivanov9b9ac952014-01-28 20:54:28 -05003024 if param.kind == _POSITIONAL_ONLY:
3025 # This should never happen in case of a properly built
3026 # Signature object (but let's have this check here
3027 # to ensure correct behaviour just in case)
3028 raise TypeError('{arg!r} parameter is positional only, '
3029 'but was passed as a keyword'. \
3030 format(arg=param.name))
3031
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003032 arguments[param_name] = arg_val
3033
3034 if kwargs:
3035 if kwargs_param is not None:
3036 # Process our '**kwargs'-like parameter
3037 arguments[kwargs_param.name] = kwargs
3038 else:
Yury Selivanov86872752015-05-19 00:27:49 -04003039 raise TypeError(
3040 'got an unexpected keyword argument {arg!r}'.format(
3041 arg=next(iter(kwargs))))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003042
3043 return self._bound_arguments_cls(self, arguments)
3044
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03003045 def bind(self, /, *args, **kwargs):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04003046 """Get a BoundArguments object, that maps the passed `args`
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003047 and `kwargs` to the function's signature. Raises `TypeError`
3048 if the passed arguments can not be bound.
Yury Selivanov5a23bd02014-03-29 13:47:11 -04003049 """
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03003050 return self._bind(args, kwargs)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003051
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03003052 def bind_partial(self, /, *args, **kwargs):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04003053 """Get a BoundArguments object, that partially maps the
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003054 passed `args` and `kwargs` to the function's signature.
3055 Raises `TypeError` if the passed arguments can not be bound.
Yury Selivanov5a23bd02014-03-29 13:47:11 -04003056 """
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03003057 return self._bind(args, kwargs, partial=True)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003058
Yury Selivanova5d63dd2014-03-27 11:31:43 -04003059 def __reduce__(self):
3060 return (type(self),
3061 (tuple(self._parameters.values()),),
3062 {'_return_annotation': self._return_annotation})
3063
3064 def __setstate__(self, state):
3065 self._return_annotation = state['_return_annotation']
3066
Yury Selivanov374375d2014-03-27 12:41:53 -04003067 def __repr__(self):
Yury Selivanovf229bc52015-05-15 12:53:56 -04003068 return '<{} {}>'.format(self.__class__.__name__, self)
Yury Selivanov374375d2014-03-27 12:41:53 -04003069
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003070 def __str__(self):
3071 result = []
Yury Selivanov2393dca2014-01-27 15:07:58 -05003072 render_pos_only_separator = False
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003073 render_kw_only_separator = True
Yury Selivanov2393dca2014-01-27 15:07:58 -05003074 for param in self.parameters.values():
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003075 formatted = str(param)
3076
3077 kind = param.kind
Yury Selivanov2393dca2014-01-27 15:07:58 -05003078
3079 if kind == _POSITIONAL_ONLY:
3080 render_pos_only_separator = True
3081 elif render_pos_only_separator:
3082 # It's not a positional-only parameter, and the flag
3083 # is set to 'True' (there were pos-only params before.)
3084 result.append('/')
3085 render_pos_only_separator = False
3086
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003087 if kind == _VAR_POSITIONAL:
3088 # OK, we have an '*args'-like parameter, so we won't need
3089 # a '*' to separate keyword-only arguments
3090 render_kw_only_separator = False
3091 elif kind == _KEYWORD_ONLY and render_kw_only_separator:
3092 # We have a keyword-only parameter to render and we haven't
3093 # rendered an '*args'-like parameter before, so add a '*'
3094 # separator to the parameters list ("foo(arg1, *, arg2)" case)
3095 result.append('*')
3096 # This condition should be only triggered once, so
3097 # reset the flag
3098 render_kw_only_separator = False
3099
3100 result.append(formatted)
3101
Yury Selivanov2393dca2014-01-27 15:07:58 -05003102 if render_pos_only_separator:
3103 # There were only positional-only parameters, hence the
3104 # flag was not reset to 'False'
3105 result.append('/')
3106
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003107 rendered = '({})'.format(', '.join(result))
3108
3109 if self.return_annotation is not _empty:
3110 anno = formatannotation(self.return_annotation)
3111 rendered += ' -> {}'.format(anno)
3112
3113 return rendered
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003114
Yury Selivanovda396452014-03-27 12:09:24 -04003115
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04003116def signature(obj, *, follow_wrapped=True):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04003117 """Get a signature object for the passed callable."""
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04003118 return Signature.from_callable(obj, follow_wrapped=follow_wrapped)
Yury Selivanovda396452014-03-27 12:09:24 -04003119
3120
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003121def _main():
3122 """ Logic for inspecting an object given at command line """
3123 import argparse
3124 import importlib
3125
3126 parser = argparse.ArgumentParser()
3127 parser.add_argument(
3128 'object',
3129 help="The object to be analysed. "
3130 "It supports the 'module:qualname' syntax")
3131 parser.add_argument(
3132 '-d', '--details', action='store_true',
3133 help='Display info about the module rather than its source code')
3134
3135 args = parser.parse_args()
3136
3137 target = args.object
3138 mod_name, has_attrs, attrs = target.partition(":")
3139 try:
3140 obj = module = importlib.import_module(mod_name)
3141 except Exception as exc:
3142 msg = "Failed to import {} ({}: {})".format(mod_name,
3143 type(exc).__name__,
3144 exc)
3145 print(msg, file=sys.stderr)
Alan Yeee3c59a72019-09-09 07:15:43 -07003146 sys.exit(2)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003147
3148 if has_attrs:
3149 parts = attrs.split(".")
3150 obj = module
3151 for part in parts:
3152 obj = getattr(obj, part)
3153
3154 if module.__name__ in sys.builtin_module_names:
3155 print("Can't get info for builtin modules.", file=sys.stderr)
Alan Yeee3c59a72019-09-09 07:15:43 -07003156 sys.exit(1)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003157
3158 if args.details:
3159 print('Target: {}'.format(target))
3160 print('Origin: {}'.format(getsourcefile(module)))
3161 print('Cached: {}'.format(module.__cached__))
3162 if obj is module:
3163 print('Loader: {}'.format(repr(module.__loader__)))
3164 if hasattr(module, '__path__'):
3165 print('Submodule search path: {}'.format(module.__path__))
3166 else:
3167 try:
3168 __, lineno = findsource(obj)
3169 except Exception:
3170 pass
3171 else:
3172 print('Line: {}'.format(lineno))
3173
3174 print('\n')
3175 else:
3176 print(getsource(obj))
3177
3178
3179if __name__ == "__main__":
3180 _main()