blob: b8e247ec252bb97eef07fb373cd50941e1a4c543 [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():
Ethan Furmanc314e602021-01-12 23:47:57 -0800410 if isinstance(v, types.DynamicClassAttribute) and v.fget is not None:
Ethan Furmane03ea372013-09-25 07:14:41 -0700411 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 Cannon825ac382020-11-06 18:45:56 -0800709 module = getmodule(object, filename)
710 if getattr(module, '__loader__', None) is not None:
711 return filename
712 elif getattr(getattr(module, "__spec__", None), "loader", None) is not None:
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000713 return filename
R. David Murraya1b37402010-06-17 02:04:29 +0000714 # or it is in the linecache
Brett Cannon825ac382020-11-06 18:45:56 -0800715 elif filename in linecache.cache:
R. David Murraya1b37402010-06-17 02:04:29 +0000716 return filename
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000717
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000718def getabsfile(object, _filename=None):
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000719 """Return an absolute path to the source or compiled file for an object.
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000720
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000721 The idea is for each object to have a unique origin, so this routine
722 normalizes the result as much as possible."""
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000723 if _filename is None:
724 _filename = getsourcefile(object) or getfile(object)
725 return os.path.normcase(os.path.abspath(_filename))
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000726
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000727modulesbyfile = {}
Thomas Wouters89f507f2006-12-13 04:49:30 +0000728_filesbymodname = {}
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000729
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000730def getmodule(object, _filename=None):
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000731 """Return the module an object was defined in, or None if not found."""
Ka-Ping Yee202c99b2001-04-13 09:15:08 +0000732 if ismodule(object):
733 return object
Johannes Gijsbers93245262004-09-11 15:53:22 +0000734 if hasattr(object, '__module__'):
Ka-Ping Yee8b58b842001-03-01 13:56:16 +0000735 return sys.modules.get(object.__module__)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000736 # Try the filename to modulename cache
737 if _filename is not None and _filename in modulesbyfile:
738 return sys.modules.get(modulesbyfile[_filename])
739 # Try the cache again with the absolute file name
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000740 try:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000741 file = getabsfile(object, _filename)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000742 except TypeError:
743 return None
Raymond Hettinger54f02222002-06-01 14:18:47 +0000744 if file in modulesbyfile:
Ka-Ping Yeeb38bbbd2003-03-28 16:29:50 +0000745 return sys.modules.get(modulesbyfile[file])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000746 # Update the filename to module name cache and check yet again
747 # Copy sys.modules in order to cope with changes while iterating
Gregory P. Smith85cf1d52020-03-04 16:45:22 -0800748 for modname, module in sys.modules.copy().items():
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000749 if ismodule(module) and hasattr(module, '__file__'):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000750 f = module.__file__
751 if f == _filesbymodname.get(modname, None):
752 # Have already mapped this module, so skip it
753 continue
754 _filesbymodname[modname] = f
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000755 f = getabsfile(module)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000756 # Always map to the name the module knows itself by
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000757 modulesbyfile[f] = modulesbyfile[
758 os.path.realpath(f)] = module.__name__
Raymond Hettinger54f02222002-06-01 14:18:47 +0000759 if file in modulesbyfile:
Ka-Ping Yeeb38bbbd2003-03-28 16:29:50 +0000760 return sys.modules.get(modulesbyfile[file])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000761 # Check the main module
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000762 main = sys.modules['__main__']
Brett Cannon4a671fe2003-06-15 22:33:28 +0000763 if not hasattr(object, '__name__'):
764 return None
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000765 if hasattr(main, object.__name__):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000766 mainobject = getattr(main, object.__name__)
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000767 if mainobject is object:
768 return main
Thomas Wouters89f507f2006-12-13 04:49:30 +0000769 # Check builtins
Georg Brandl1a3284e2007-12-02 09:40:06 +0000770 builtin = sys.modules['builtins']
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000771 if hasattr(builtin, object.__name__):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000772 builtinobject = getattr(builtin, object.__name__)
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000773 if builtinobject is object:
774 return builtin
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000775
Karthikeyan Singaravelan696136b2020-04-18 21:49:32 +0530776
777class ClassFoundException(Exception):
778 pass
779
780
781class _ClassFinder(ast.NodeVisitor):
782
783 def __init__(self, qualname):
784 self.stack = []
785 self.qualname = qualname
786
787 def visit_FunctionDef(self, node):
788 self.stack.append(node.name)
789 self.stack.append('<locals>')
790 self.generic_visit(node)
791 self.stack.pop()
792 self.stack.pop()
793
794 visit_AsyncFunctionDef = visit_FunctionDef
795
796 def visit_ClassDef(self, node):
797 self.stack.append(node.name)
798 if self.qualname == '.'.join(self.stack):
799 # Return the decorator for the class if present
800 if node.decorator_list:
801 line_number = node.decorator_list[0].lineno
802 else:
803 line_number = node.lineno
804
805 # decrement by one since lines starts with indexing by zero
806 line_number -= 1
807 raise ClassFoundException(line_number)
808 self.generic_visit(node)
809 self.stack.pop()
810
811
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000812def findsource(object):
813 """Return the entire source file and starting line number for an object.
814
815 The argument may be a module, class, method, function, traceback, frame,
816 or code object. The source code is returned as a list of all the lines
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200817 in the file and the line number indexes a line in that list. An OSError
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000818 is raised if the source code cannot be retrieved."""
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500819
Yury Selivanovef1e7502014-12-08 16:05:34 -0500820 file = getsourcefile(object)
821 if file:
822 # Invalidate cache if needed.
823 linecache.checkcache(file)
824 else:
825 file = getfile(object)
826 # Allow filenames in form of "<something>" to pass through.
827 # `doctest` monkeypatches `linecache` module to enable
828 # inspection, so let `linecache.getlines` to be called.
829 if not (file.startswith('<') and file.endswith('>')):
830 raise OSError('source code not available')
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500831
Thomas Wouters89f507f2006-12-13 04:49:30 +0000832 module = getmodule(object, file)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000833 if module:
834 lines = linecache.getlines(file, module.__dict__)
835 else:
836 lines = linecache.getlines(file)
Neil Schemenauerf06f8532002-03-23 23:51:04 +0000837 if not lines:
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200838 raise OSError('could not get source code')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000839
840 if ismodule(object):
841 return lines, 0
842
843 if isclass(object):
Karthikeyan Singaravelan696136b2020-04-18 21:49:32 +0530844 qualname = object.__qualname__
845 source = ''.join(lines)
846 tree = ast.parse(source)
847 class_finder = _ClassFinder(qualname)
848 try:
849 class_finder.visit(tree)
850 except ClassFoundException as e:
851 line_number = e.args[0]
852 return lines, line_number
Jeremy Hyltonab919022003-06-27 18:41:20 +0000853 else:
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200854 raise OSError('could not find class definition')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000855
856 if ismethod(object):
Christian Heimesff737952007-11-27 10:40:20 +0000857 object = object.__func__
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000858 if isfunction(object):
Neal Norwitz221085d2007-02-25 20:55:47 +0000859 object = object.__code__
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000860 if istraceback(object):
861 object = object.tb_frame
862 if isframe(object):
863 object = object.f_code
864 if iscode(object):
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000865 if not hasattr(object, 'co_firstlineno'):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200866 raise OSError('could not find function definition')
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000867 lnum = object.co_firstlineno - 1
Yury Selivanove4e811d2015-07-21 19:01:52 +0300868 pat = re.compile(r'^(\s*def\s)|(\s*async\s+def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000869 while lnum > 0:
Irit Katriel2e0760b2020-12-04 21:22:03 +0000870 try:
871 line = lines[lnum]
872 except IndexError:
873 raise OSError('lineno is out of bounds')
874 if pat.match(line):
875 break
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000876 lnum = lnum - 1
877 return lines, lnum
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200878 raise OSError('could not find code object')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000879
880def getcomments(object):
Jeremy Hyltonb4c17c82002-03-28 23:01:56 +0000881 """Get lines of comments immediately preceding an object's source code.
882
883 Returns None when source can't be found.
884 """
885 try:
886 lines, lnum = findsource(object)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200887 except (OSError, TypeError):
Jeremy Hyltonb4c17c82002-03-28 23:01:56 +0000888 return None
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000889
890 if ismodule(object):
891 # Look for a comment block at the top of the file.
892 start = 0
Ka-Ping Yeeb910efe2001-04-12 13:17:17 +0000893 if lines and lines[0][:2] == '#!': start = 1
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000894 while start < len(lines) and lines[start].strip() in ('', '#'):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000895 start = start + 1
Ka-Ping Yeeb910efe2001-04-12 13:17:17 +0000896 if start < len(lines) and lines[start][:1] == '#':
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000897 comments = []
898 end = start
899 while end < len(lines) and lines[end][:1] == '#':
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000900 comments.append(lines[end].expandtabs())
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000901 end = end + 1
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000902 return ''.join(comments)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000903
904 # Look for a preceding block of comments at the same indentation.
905 elif lnum > 0:
906 indent = indentsize(lines[lnum])
907 end = lnum - 1
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000908 if end >= 0 and lines[end].lstrip()[:1] == '#' and \
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000909 indentsize(lines[end]) == indent:
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000910 comments = [lines[end].expandtabs().lstrip()]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000911 if end > 0:
912 end = end - 1
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000913 comment = lines[end].expandtabs().lstrip()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000914 while comment[:1] == '#' and indentsize(lines[end]) == indent:
915 comments[:0] = [comment]
916 end = end - 1
917 if end < 0: break
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000918 comment = lines[end].expandtabs().lstrip()
919 while comments and comments[0].strip() == '#':
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000920 comments[:1] = []
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000921 while comments and comments[-1].strip() == '#':
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000922 comments[-1:] = []
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000923 return ''.join(comments)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000924
Tim Peters4efb6e92001-06-29 23:51:08 +0000925class EndOfBlock(Exception): pass
926
927class BlockFinder:
928 """Provide a tokeneater() method to detect the end of a code block."""
929 def __init__(self):
930 self.indent = 0
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000931 self.islambda = False
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000932 self.started = False
933 self.passline = False
Meador Inge5b718d72015-07-23 22:49:37 -0500934 self.indecorator = False
935 self.decoratorhasargs = False
Armin Rigodd5c0232005-09-25 11:45:45 +0000936 self.last = 1
Irit Katriel6e1eec72020-12-04 16:45:38 +0000937 self.body_col0 = None
Tim Peters4efb6e92001-06-29 23:51:08 +0000938
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000939 def tokeneater(self, type, token, srowcol, erowcol, line):
Meador Inge5b718d72015-07-23 22:49:37 -0500940 if not self.started and not self.indecorator:
941 # skip any decorators
942 if token == "@":
943 self.indecorator = True
Armin Rigodd5c0232005-09-25 11:45:45 +0000944 # look for the first "def", "class" or "lambda"
Meador Inge5b718d72015-07-23 22:49:37 -0500945 elif token in ("def", "class", "lambda"):
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000946 if token == "lambda":
947 self.islambda = True
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000948 self.started = True
Armin Rigodd5c0232005-09-25 11:45:45 +0000949 self.passline = True # skip to the end of the line
Meador Inge5b718d72015-07-23 22:49:37 -0500950 elif token == "(":
951 if self.indecorator:
952 self.decoratorhasargs = True
953 elif token == ")":
954 if self.indecorator:
955 self.indecorator = False
956 self.decoratorhasargs = False
Tim Peters4efb6e92001-06-29 23:51:08 +0000957 elif type == tokenize.NEWLINE:
Armin Rigodd5c0232005-09-25 11:45:45 +0000958 self.passline = False # stop skipping when a NEWLINE is seen
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000959 self.last = srowcol[0]
Armin Rigodd5c0232005-09-25 11:45:45 +0000960 if self.islambda: # lambdas always end at the first NEWLINE
961 raise EndOfBlock
Meador Inge5b718d72015-07-23 22:49:37 -0500962 # hitting a NEWLINE when in a decorator without args
963 # ends the decorator
964 if self.indecorator and not self.decoratorhasargs:
965 self.indecorator = False
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000966 elif self.passline:
967 pass
Tim Peters4efb6e92001-06-29 23:51:08 +0000968 elif type == tokenize.INDENT:
Irit Katriel6e1eec72020-12-04 16:45:38 +0000969 if self.body_col0 is None and self.started:
970 self.body_col0 = erowcol[1]
Tim Peters4efb6e92001-06-29 23:51:08 +0000971 self.indent = self.indent + 1
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000972 self.passline = True
Tim Peters4efb6e92001-06-29 23:51:08 +0000973 elif type == tokenize.DEDENT:
974 self.indent = self.indent - 1
Armin Rigodd5c0232005-09-25 11:45:45 +0000975 # the end of matching indent/dedent pairs end a block
976 # (note that this only works for "def"/"class" blocks,
977 # not e.g. for "if: else:" or "try: finally:" blocks)
978 if self.indent <= 0:
979 raise EndOfBlock
Irit Katriel6e1eec72020-12-04 16:45:38 +0000980 elif type == tokenize.COMMENT:
981 if self.body_col0 is not None and srowcol[1] >= self.body_col0:
982 # Include comments if indented at least as much as the block
983 self.last = srowcol[0]
Armin Rigodd5c0232005-09-25 11:45:45 +0000984 elif self.indent == 0 and type not in (tokenize.COMMENT, tokenize.NL):
985 # any other token on the same indentation level end the previous
986 # block as well, except the pseudo-tokens COMMENT and NL.
987 raise EndOfBlock
Tim Peters4efb6e92001-06-29 23:51:08 +0000988
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000989def getblock(lines):
990 """Extract the block of code at the top of the given list of lines."""
Armin Rigodd5c0232005-09-25 11:45:45 +0000991 blockfinder = BlockFinder()
Tim Peters4efb6e92001-06-29 23:51:08 +0000992 try:
Trent Nelson428de652008-03-18 22:41:35 +0000993 tokens = tokenize.generate_tokens(iter(lines).__next__)
994 for _token in tokens:
995 blockfinder.tokeneater(*_token)
Armin Rigodd5c0232005-09-25 11:45:45 +0000996 except (EndOfBlock, IndentationError):
997 pass
998 return lines[:blockfinder.last]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000999
1000def getsourcelines(object):
1001 """Return a list of source lines and starting line number for an object.
1002
1003 The argument may be a module, class, method, function, traceback, frame,
1004 or code object. The source code is returned as a list of the lines
1005 corresponding to the object and the line number indicates where in the
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02001006 original source file the first line of code was found. An OSError is
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001007 raised if the source code cannot be retrieved."""
Yury Selivanov081bbf62014-09-26 17:34:54 -04001008 object = unwrap(object)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001009 lines, lnum = findsource(object)
1010
Vladimir Matveev91cb2982018-08-24 07:18:00 -07001011 if istraceback(object):
1012 object = object.tb_frame
1013
1014 # for module or frame that corresponds to module, return all source lines
1015 if (ismodule(object) or
1016 (isframe(object) and object.f_code.co_name == "<module>")):
Meador Inge5b718d72015-07-23 22:49:37 -05001017 return lines, 0
1018 else:
1019 return getblock(lines[lnum:]), lnum + 1
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001020
1021def getsource(object):
1022 """Return the text of the source code for an object.
1023
1024 The argument may be a module, class, method, function, traceback, frame,
1025 or code object. The source code is returned as a single string. An
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02001026 OSError is raised if the source code cannot be retrieved."""
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001027 lines, lnum = getsourcelines(object)
Neal Norwitz9d72bb42007-04-17 08:48:32 +00001028 return ''.join(lines)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001029
1030# --------------------------------------------------- class tree extraction
1031def walktree(classes, children, parent):
1032 """Recursive helper function for getclasstree()."""
1033 results = []
Raymond Hettingera1a992c2005-03-11 06:46:45 +00001034 classes.sort(key=attrgetter('__module__', '__name__'))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001035 for c in classes:
1036 results.append((c, c.__bases__))
Raymond Hettinger54f02222002-06-01 14:18:47 +00001037 if c in children:
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001038 results.append(walktree(children[c], children, c))
1039 return results
1040
Georg Brandl5ce83a02009-06-01 17:23:51 +00001041def getclasstree(classes, unique=False):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001042 """Arrange the given list of classes into a hierarchy of nested lists.
1043
1044 Where a nested list appears, it contains classes derived from the class
1045 whose entry immediately precedes the list. Each entry is a 2-tuple
1046 containing a class and a tuple of its base classes. If the 'unique'
1047 argument is true, exactly one entry appears in the returned structure
1048 for each class in the given list. Otherwise, classes using multiple
1049 inheritance and their descendants will appear multiple times."""
1050 children = {}
1051 roots = []
1052 for c in classes:
1053 if c.__bases__:
1054 for parent in c.__bases__:
Srinivas Reddy Thatiparthy (శ్రీనివాస్ రెడ్డి తాటిపర్తి)feaefc72018-02-09 15:29:19 +05301055 if parent not in children:
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001056 children[parent] = []
Serhiy Storchaka362c1b52013-09-05 17:14:32 +03001057 if c not in children[parent]:
1058 children[parent].append(c)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001059 if unique and parent in classes: break
1060 elif c not in roots:
1061 roots.append(c)
Raymond Hettingere0d49722002-06-02 18:55:56 +00001062 for parent in children:
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001063 if parent not in classes:
1064 roots.append(parent)
1065 return walktree(roots, children, None)
1066
1067# ------------------------------------------------ argument list extraction
Christian Heimes25bb7832008-01-11 16:17:00 +00001068Arguments = namedtuple('Arguments', 'args, varargs, varkw')
1069
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001070def getargs(co):
1071 """Get information about the arguments accepted by a code object.
1072
Guido van Rossum2e65f892007-02-28 22:03:49 +00001073 Three things are returned: (args, varargs, varkw), where
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001074 'args' is the list of argument names. Keyword-only arguments are
1075 appended. 'varargs' and 'varkw' are the names of the * and **
1076 arguments or None."""
Jeremy Hylton64967882003-06-27 18:14:39 +00001077 if not iscode(co):
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +00001078 raise TypeError('{!r} is not a code object'.format(co))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001079
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001080 names = co.co_varnames
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001081 nargs = co.co_argcount
Guido van Rossum2e65f892007-02-28 22:03:49 +00001082 nkwargs = co.co_kwonlyargcount
Pablo Galindocd74e662019-06-01 18:08:04 +01001083 args = list(names[:nargs])
1084 kwonlyargs = list(names[nargs:nargs+nkwargs])
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001085 step = 0
1086
Guido van Rossum2e65f892007-02-28 22:03:49 +00001087 nargs += nkwargs
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001088 varargs = None
1089 if co.co_flags & CO_VARARGS:
1090 varargs = co.co_varnames[nargs]
1091 nargs = nargs + 1
1092 varkw = None
1093 if co.co_flags & CO_VARKEYWORDS:
1094 varkw = co.co_varnames[nargs]
Pablo Galindocd74e662019-06-01 18:08:04 +01001095 return Arguments(args + kwonlyargs, varargs, varkw)
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001096
1097ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults')
1098
1099def getargspec(func):
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001100 """Get the names and default values of a function's parameters.
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001101
1102 A tuple of four things is returned: (args, varargs, keywords, defaults).
1103 'args' is a list of the argument names, including keyword-only argument names.
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001104 'varargs' and 'keywords' are the names of the * and ** parameters or None.
1105 'defaults' is an n-tuple of the default values of the last n parameters.
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001106
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001107 This function is deprecated, as it does not support annotations or
1108 keyword-only parameters and will raise ValueError if either is present
1109 on the supplied callable.
1110
1111 For a more structured introspection API, use inspect.signature() instead.
1112
1113 Alternatively, use getfullargspec() for an API with a similar namedtuple
1114 based interface, but full support for annotations and keyword-only
1115 parameters.
Matthias Bussonnierded87d82018-10-19 16:40:45 -07001116
1117 Deprecated since Python 3.5, use `inspect.getfullargspec()`.
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001118 """
Matthias Bussonnierded87d82018-10-19 16:40:45 -07001119 warnings.warn("inspect.getargspec() is deprecated since Python 3.0, "
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001120 "use inspect.signature() or inspect.getfullargspec()",
1121 DeprecationWarning, stacklevel=2)
Pablo Galindod5d2b452019-04-30 02:01:14 +01001122 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
1123 getfullargspec(func)
1124 if kwonlyargs or ann:
1125 raise ValueError("Function has keyword-only parameters or annotations"
1126 ", use inspect.signature() API which can support them")
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001127 return ArgSpec(args, varargs, varkw, defaults)
1128
Christian Heimes25bb7832008-01-11 16:17:00 +00001129FullArgSpec = namedtuple('FullArgSpec',
Pablo Galindod5d2b452019-04-30 02:01:14 +01001130 'args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations')
Guido van Rossum2e65f892007-02-28 22:03:49 +00001131
1132def getfullargspec(func):
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001133 """Get the names and default values of a callable object's parameters.
Guido van Rossum2e65f892007-02-28 22:03:49 +00001134
Brett Cannon504d8852007-09-07 02:12:14 +00001135 A tuple of seven things is returned:
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001136 (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations).
1137 'args' is a list of the parameter names.
1138 'varargs' and 'varkw' are the names of the * and ** parameters or None.
1139 'defaults' is an n-tuple of the default values of the last n parameters.
1140 'kwonlyargs' is a list of keyword-only parameter names.
Guido van Rossum2e65f892007-02-28 22:03:49 +00001141 'kwonlydefaults' is a dictionary mapping names from kwonlyargs to defaults.
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001142 'annotations' is a dictionary mapping parameter names to annotations.
Guido van Rossuma8add0e2007-05-14 22:03:55 +00001143
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001144 Notable differences from inspect.signature():
1145 - the "self" parameter is always reported, even for bound methods
1146 - wrapper chains defined by __wrapped__ *not* unwrapped automatically
Jeremy Hylton64967882003-06-27 18:14:39 +00001147 """
Yury Selivanov57d240e2014-02-19 16:27:23 -05001148 try:
1149 # Re: `skip_bound_arg=False`
1150 #
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001151 # There is a notable difference in behaviour between getfullargspec
1152 # and Signature: the former always returns 'self' parameter for bound
1153 # methods, whereas the Signature always shows the actual calling
1154 # signature of the passed object.
1155 #
1156 # To simulate this behaviour, we "unbind" bound methods, to trick
1157 # inspect.signature to always return their first parameter ("self",
1158 # usually)
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001159
Yury Selivanov57d240e2014-02-19 16:27:23 -05001160 # Re: `follow_wrapper_chains=False`
1161 #
1162 # getfullargspec() historically ignored __wrapped__ attributes,
1163 # so we ensure that remains the case in 3.3+
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001164
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001165 sig = _signature_from_callable(func,
1166 follow_wrapper_chains=False,
1167 skip_bound_arg=False,
1168 sigcls=Signature)
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001169 except Exception as ex:
1170 # Most of the times 'signature' will raise ValueError.
1171 # But, it can also raise AttributeError, and, maybe something
1172 # else. So to be fully backwards compatible, we catch all
1173 # possible exceptions here, and reraise a TypeError.
1174 raise TypeError('unsupported callable') from ex
1175
1176 args = []
1177 varargs = None
1178 varkw = None
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001179 posonlyargs = []
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001180 kwonlyargs = []
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001181 annotations = {}
1182 defaults = ()
1183 kwdefaults = {}
1184
1185 if sig.return_annotation is not sig.empty:
1186 annotations['return'] = sig.return_annotation
1187
1188 for param in sig.parameters.values():
1189 kind = param.kind
1190 name = param.name
1191
1192 if kind is _POSITIONAL_ONLY:
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001193 posonlyargs.append(name)
1194 if param.default is not param.empty:
1195 defaults += (param.default,)
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001196 elif kind is _POSITIONAL_OR_KEYWORD:
1197 args.append(name)
1198 if param.default is not param.empty:
1199 defaults += (param.default,)
1200 elif kind is _VAR_POSITIONAL:
1201 varargs = name
1202 elif kind is _KEYWORD_ONLY:
1203 kwonlyargs.append(name)
1204 if param.default is not param.empty:
1205 kwdefaults[name] = param.default
1206 elif kind is _VAR_KEYWORD:
1207 varkw = name
1208
1209 if param.annotation is not param.empty:
1210 annotations[name] = param.annotation
1211
1212 if not kwdefaults:
1213 # compatibility with 'func.__kwdefaults__'
1214 kwdefaults = None
1215
1216 if not defaults:
1217 # compatibility with 'func.__defaults__'
1218 defaults = None
1219
Pablo Galindod5d2b452019-04-30 02:01:14 +01001220 return FullArgSpec(posonlyargs + args, varargs, varkw, defaults,
1221 kwonlyargs, kwdefaults, annotations)
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001222
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001223
Christian Heimes25bb7832008-01-11 16:17:00 +00001224ArgInfo = namedtuple('ArgInfo', 'args varargs keywords locals')
1225
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001226def getargvalues(frame):
1227 """Get information about arguments passed into a particular frame.
1228
1229 A tuple of four things is returned: (args, varargs, varkw, locals).
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001230 'args' is a list of the argument names.
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001231 'varargs' and 'varkw' are the names of the * and ** arguments or None.
1232 'locals' is the locals dictionary of the given frame."""
1233 args, varargs, varkw = getargs(frame.f_code)
Benjamin Peterson1a6e0d02008-10-25 15:49:17 +00001234 return ArgInfo(args, varargs, varkw, frame.f_locals)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001235
Guido van Rossum2e65f892007-02-28 22:03:49 +00001236def formatannotation(annotation, base_module=None):
Guido van Rossum52e50042016-10-22 07:55:18 -07001237 if getattr(annotation, '__module__', None) == 'typing':
1238 return repr(annotation).replace('typing.', '')
Guido van Rossum2e65f892007-02-28 22:03:49 +00001239 if isinstance(annotation, type):
Georg Brandl1a3284e2007-12-02 09:40:06 +00001240 if annotation.__module__ in ('builtins', base_module):
Serhiy Storchaka521e5862014-07-22 15:00:37 +03001241 return annotation.__qualname__
1242 return annotation.__module__+'.'+annotation.__qualname__
Guido van Rossum2e65f892007-02-28 22:03:49 +00001243 return repr(annotation)
Guido van Rossuma8add0e2007-05-14 22:03:55 +00001244
Guido van Rossum2e65f892007-02-28 22:03:49 +00001245def formatannotationrelativeto(object):
Guido van Rossuma8add0e2007-05-14 22:03:55 +00001246 module = getattr(object, '__module__', None)
1247 def _formatannotation(annotation):
1248 return formatannotation(annotation, module)
1249 return _formatannotation
Guido van Rossum2e65f892007-02-28 22:03:49 +00001250
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001251def formatargspec(args, varargs=None, varkw=None, defaults=None,
Pablo Galindod5d2b452019-04-30 02:01:14 +01001252 kwonlyargs=(), kwonlydefaults={}, annotations={},
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001253 formatarg=str,
1254 formatvarargs=lambda name: '*' + name,
1255 formatvarkw=lambda name: '**' + name,
1256 formatvalue=lambda value: '=' + repr(value),
Guido van Rossum2e65f892007-02-28 22:03:49 +00001257 formatreturns=lambda text: ' -> ' + text,
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001258 formatannotation=formatannotation):
Berker Peksagfa3922c2015-07-31 04:11:29 +03001259 """Format an argument spec from the values returned by getfullargspec.
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001260
Guido van Rossum2e65f892007-02-28 22:03:49 +00001261 The first seven arguments are (args, varargs, varkw, defaults,
1262 kwonlyargs, kwonlydefaults, annotations). The other five arguments
1263 are the corresponding optional formatting functions that are called to
1264 turn names and values into strings. The last argument is an optional
Matthias Bussonnier46c5cd02018-06-11 22:08:16 +02001265 function to format the sequence of arguments.
1266
1267 Deprecated since Python 3.5: use the `signature` function and `Signature`
1268 objects.
1269 """
1270
1271 from warnings import warn
1272
1273 warn("`formatargspec` is deprecated since Python 3.5. Use `signature` and "
Zackery Spytz41254eb2018-06-11 21:16:18 -06001274 "the `Signature` object directly",
Matthias Bussonnier46c5cd02018-06-11 22:08:16 +02001275 DeprecationWarning,
1276 stacklevel=2)
1277
Guido van Rossum2e65f892007-02-28 22:03:49 +00001278 def formatargandannotation(arg):
1279 result = formatarg(arg)
1280 if arg in annotations:
1281 result += ': ' + formatannotation(annotations[arg])
1282 return result
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001283 specs = []
1284 if defaults:
Pablo Galindod5d2b452019-04-30 02:01:14 +01001285 firstdefault = len(args) - len(defaults)
1286 for i, arg in enumerate(args):
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001287 spec = formatargandannotation(arg)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001288 if defaults and i >= firstdefault:
1289 spec = spec + formatvalue(defaults[i - firstdefault])
1290 specs.append(spec)
Raymond Hettinger936654b2002-06-01 03:06:31 +00001291 if varargs is not None:
Guido van Rossum2e65f892007-02-28 22:03:49 +00001292 specs.append(formatvarargs(formatargandannotation(varargs)))
1293 else:
1294 if kwonlyargs:
1295 specs.append('*')
1296 if kwonlyargs:
1297 for kwonlyarg in kwonlyargs:
1298 spec = formatargandannotation(kwonlyarg)
Benjamin Peterson9953a8d2009-01-17 04:15:01 +00001299 if kwonlydefaults and kwonlyarg in kwonlydefaults:
Guido van Rossum2e65f892007-02-28 22:03:49 +00001300 spec += formatvalue(kwonlydefaults[kwonlyarg])
1301 specs.append(spec)
Raymond Hettinger936654b2002-06-01 03:06:31 +00001302 if varkw is not None:
Guido van Rossum2e65f892007-02-28 22:03:49 +00001303 specs.append(formatvarkw(formatargandannotation(varkw)))
Neal Norwitz9d72bb42007-04-17 08:48:32 +00001304 result = '(' + ', '.join(specs) + ')'
Guido van Rossum2e65f892007-02-28 22:03:49 +00001305 if 'return' in annotations:
1306 result += formatreturns(formatannotation(annotations['return']))
1307 return result
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001308
1309def formatargvalues(args, varargs, varkw, locals,
1310 formatarg=str,
1311 formatvarargs=lambda name: '*' + name,
1312 formatvarkw=lambda name: '**' + name,
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001313 formatvalue=lambda value: '=' + repr(value)):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001314 """Format an argument spec from the 4 values returned by getargvalues.
1315
1316 The first four arguments are (args, varargs, varkw, locals). The
1317 next four arguments are the corresponding optional formatting functions
1318 that are called to turn names and values into strings. The ninth
1319 argument is an optional function to format the sequence of arguments."""
1320 def convert(name, locals=locals,
1321 formatarg=formatarg, formatvalue=formatvalue):
1322 return formatarg(name) + formatvalue(locals[name])
1323 specs = []
1324 for i in range(len(args)):
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001325 specs.append(convert(args[i]))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001326 if varargs:
1327 specs.append(formatvarargs(varargs) + formatvalue(locals[varargs]))
1328 if varkw:
1329 specs.append(formatvarkw(varkw) + formatvalue(locals[varkw]))
Neal Norwitz9d72bb42007-04-17 08:48:32 +00001330 return '(' + ', '.join(specs) + ')'
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001331
Benjamin Petersone109c702011-06-24 09:37:26 -05001332def _missing_arguments(f_name, argnames, pos, values):
1333 names = [repr(name) for name in argnames if name not in values]
1334 missing = len(names)
1335 if missing == 1:
1336 s = names[0]
1337 elif missing == 2:
1338 s = "{} and {}".format(*names)
1339 else:
Yury Selivanovdccfa132014-03-27 18:42:52 -04001340 tail = ", {} and {}".format(*names[-2:])
Benjamin Petersone109c702011-06-24 09:37:26 -05001341 del names[-2:]
1342 s = ", ".join(names) + tail
1343 raise TypeError("%s() missing %i required %s argument%s: %s" %
1344 (f_name, missing,
1345 "positional" if pos else "keyword-only",
1346 "" if missing == 1 else "s", s))
1347
1348def _too_many(f_name, args, kwonly, varargs, defcount, given, values):
Benjamin Petersonb204a422011-06-05 22:04:07 -05001349 atleast = len(args) - defcount
Benjamin Petersonb204a422011-06-05 22:04:07 -05001350 kwonly_given = len([arg for arg in kwonly if arg in values])
1351 if varargs:
1352 plural = atleast != 1
1353 sig = "at least %d" % (atleast,)
1354 elif defcount:
1355 plural = True
1356 sig = "from %d to %d" % (atleast, len(args))
1357 else:
1358 plural = len(args) != 1
1359 sig = str(len(args))
1360 kwonly_sig = ""
1361 if kwonly_given:
1362 msg = " positional argument%s (and %d keyword-only argument%s)"
1363 kwonly_sig = (msg % ("s" if given != 1 else "", kwonly_given,
1364 "s" if kwonly_given != 1 else ""))
1365 raise TypeError("%s() takes %s positional argument%s but %d%s %s given" %
1366 (f_name, sig, "s" if plural else "", given, kwonly_sig,
1367 "was" if given == 1 and not kwonly_given else "were"))
1368
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03001369def getcallargs(func, /, *positional, **named):
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001370 """Get the mapping of arguments to values.
1371
1372 A dict is returned, with keys the function argument names (including the
1373 names of the * and ** arguments, if any), and values the respective bound
1374 values from 'positional' and 'named'."""
1375 spec = getfullargspec(func)
Pablo Galindod5d2b452019-04-30 02:01:14 +01001376 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = spec
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001377 f_name = func.__name__
1378 arg2value = {}
1379
Benjamin Petersonb204a422011-06-05 22:04:07 -05001380
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001381 if ismethod(func) and func.__self__ is not None:
1382 # implicit 'self' (or 'cls' for classmethods) argument
1383 positional = (func.__self__,) + positional
1384 num_pos = len(positional)
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001385 num_args = len(args)
1386 num_defaults = len(defaults) if defaults else 0
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001387
Benjamin Petersonb204a422011-06-05 22:04:07 -05001388 n = min(num_pos, num_args)
1389 for i in range(n):
Pablo Galindod5d2b452019-04-30 02:01:14 +01001390 arg2value[args[i]] = positional[i]
Benjamin Petersonb204a422011-06-05 22:04:07 -05001391 if varargs:
1392 arg2value[varargs] = tuple(positional[n:])
1393 possible_kwargs = set(args + kwonlyargs)
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001394 if varkw:
Benjamin Petersonb204a422011-06-05 22:04:07 -05001395 arg2value[varkw] = {}
1396 for kw, value in named.items():
1397 if kw not in possible_kwargs:
1398 if not varkw:
1399 raise TypeError("%s() got an unexpected keyword argument %r" %
1400 (f_name, kw))
1401 arg2value[varkw][kw] = value
1402 continue
1403 if kw in arg2value:
1404 raise TypeError("%s() got multiple values for argument %r" %
1405 (f_name, kw))
1406 arg2value[kw] = value
1407 if num_pos > num_args and not varargs:
Benjamin Petersone109c702011-06-24 09:37:26 -05001408 _too_many(f_name, args, kwonlyargs, varargs, num_defaults,
1409 num_pos, arg2value)
Benjamin Petersonb204a422011-06-05 22:04:07 -05001410 if num_pos < num_args:
Benjamin Petersone109c702011-06-24 09:37:26 -05001411 req = args[:num_args - num_defaults]
1412 for arg in req:
Benjamin Petersonb204a422011-06-05 22:04:07 -05001413 if arg not in arg2value:
Benjamin Petersone109c702011-06-24 09:37:26 -05001414 _missing_arguments(f_name, req, True, arg2value)
Benjamin Petersonb204a422011-06-05 22:04:07 -05001415 for i, arg in enumerate(args[num_args - num_defaults:]):
1416 if arg not in arg2value:
1417 arg2value[arg] = defaults[i]
Benjamin Petersone109c702011-06-24 09:37:26 -05001418 missing = 0
Benjamin Petersonb204a422011-06-05 22:04:07 -05001419 for kwarg in kwonlyargs:
1420 if kwarg not in arg2value:
Yury Selivanov875df202014-03-27 18:23:03 -04001421 if kwonlydefaults and kwarg in kwonlydefaults:
Benjamin Petersone109c702011-06-24 09:37:26 -05001422 arg2value[kwarg] = kwonlydefaults[kwarg]
1423 else:
1424 missing += 1
1425 if missing:
1426 _missing_arguments(f_name, kwonlyargs, False, arg2value)
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001427 return arg2value
1428
Nick Coghlan2f92e542012-06-23 19:39:55 +10001429ClosureVars = namedtuple('ClosureVars', 'nonlocals globals builtins unbound')
1430
1431def getclosurevars(func):
1432 """
1433 Get the mapping of free variables to their current values.
1434
Meador Inge8fda3592012-07-19 21:33:21 -05001435 Returns a named tuple of dicts mapping the current nonlocal, global
Nick Coghlan2f92e542012-06-23 19:39:55 +10001436 and builtin references as seen by the body of the function. A final
1437 set of unbound names that could not be resolved is also provided.
1438 """
1439
1440 if ismethod(func):
1441 func = func.__func__
1442
1443 if not isfunction(func):
Serhiy Storchakaa4a30202017-11-28 22:54:42 +02001444 raise TypeError("{!r} is not a Python function".format(func))
Nick Coghlan2f92e542012-06-23 19:39:55 +10001445
1446 code = func.__code__
1447 # Nonlocal references are named in co_freevars and resolved
1448 # by looking them up in __closure__ by positional index
1449 if func.__closure__ is None:
1450 nonlocal_vars = {}
1451 else:
1452 nonlocal_vars = {
1453 var : cell.cell_contents
1454 for var, cell in zip(code.co_freevars, func.__closure__)
1455 }
1456
1457 # Global and builtin references are named in co_names and resolved
1458 # by looking them up in __globals__ or __builtins__
1459 global_ns = func.__globals__
1460 builtin_ns = global_ns.get("__builtins__", builtins.__dict__)
1461 if ismodule(builtin_ns):
1462 builtin_ns = builtin_ns.__dict__
1463 global_vars = {}
1464 builtin_vars = {}
1465 unbound_names = set()
1466 for name in code.co_names:
1467 if name in ("None", "True", "False"):
1468 # Because these used to be builtins instead of keywords, they
1469 # may still show up as name references. We ignore them.
1470 continue
1471 try:
1472 global_vars[name] = global_ns[name]
1473 except KeyError:
1474 try:
1475 builtin_vars[name] = builtin_ns[name]
1476 except KeyError:
1477 unbound_names.add(name)
1478
1479 return ClosureVars(nonlocal_vars, global_vars,
1480 builtin_vars, unbound_names)
1481
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001482# -------------------------------------------------- stack frame extraction
Christian Heimes25bb7832008-01-11 16:17:00 +00001483
1484Traceback = namedtuple('Traceback', 'filename lineno function code_context index')
1485
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001486def getframeinfo(frame, context=1):
1487 """Get information about a frame or traceback object.
1488
1489 A tuple of five things is returned: the filename, the line number of
1490 the current line, the function name, a list of lines of context from
1491 the source code, and the index of the current line within that list.
1492 The optional second argument specifies the number of lines of context
1493 to return, which are centered around the current line."""
1494 if istraceback(frame):
Andrew M. Kuchlingba8b6bc2004-06-05 14:11:59 +00001495 lineno = frame.tb_lineno
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001496 frame = frame.tb_frame
Andrew M. Kuchlingba8b6bc2004-06-05 14:11:59 +00001497 else:
1498 lineno = frame.f_lineno
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001499 if not isframe(frame):
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +00001500 raise TypeError('{!r} is not a frame or traceback object'.format(frame))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001501
Neil Schemenauerf06f8532002-03-23 23:51:04 +00001502 filename = getsourcefile(frame) or getfile(frame)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001503 if context > 0:
Guido van Rossum54e54c62001-09-04 19:14:14 +00001504 start = lineno - 1 - context//2
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001505 try:
1506 lines, lnum = findsource(frame)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02001507 except OSError:
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +00001508 lines = index = None
1509 else:
Raymond Hettingera0501712004-06-15 11:22:53 +00001510 start = max(0, min(start, len(lines) - context))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001511 lines = lines[start:start+context]
Ka-Ping Yee59ade082001-03-01 03:55:35 +00001512 index = lineno - 1 - start
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001513 else:
1514 lines = index = None
1515
Christian Heimes25bb7832008-01-11 16:17:00 +00001516 return Traceback(filename, lineno, frame.f_code.co_name, lines, index)
Ka-Ping Yee59ade082001-03-01 03:55:35 +00001517
1518def getlineno(frame):
1519 """Get the line number from a frame object, allowing for optimization."""
Michael W. Hudsondd32a912002-08-15 14:59:02 +00001520 # FrameType.f_lineno is now a descriptor that grovels co_lnotab
1521 return frame.f_lineno
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001522
Antoine Pitroucdcafb72014-08-24 10:50:28 -04001523FrameInfo = namedtuple('FrameInfo', ('frame',) + Traceback._fields)
1524
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001525def getouterframes(frame, context=1):
1526 """Get a list of records for a frame and all higher (calling) frames.
1527
1528 Each record contains a frame object, filename, line number, function
1529 name, a list of lines of context, and index within the context."""
1530 framelist = []
1531 while frame:
Antoine Pitroucdcafb72014-08-24 10:50:28 -04001532 frameinfo = (frame,) + getframeinfo(frame, context)
1533 framelist.append(FrameInfo(*frameinfo))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001534 frame = frame.f_back
1535 return framelist
1536
1537def getinnerframes(tb, context=1):
1538 """Get a list of records for a traceback's frame and all lower frames.
1539
1540 Each record contains a frame object, filename, line number, function
1541 name, a list of lines of context, and index within the context."""
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001542 framelist = []
1543 while tb:
Antoine Pitroucdcafb72014-08-24 10:50:28 -04001544 frameinfo = (tb.tb_frame,) + getframeinfo(tb, context)
1545 framelist.append(FrameInfo(*frameinfo))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001546 tb = tb.tb_next
1547 return framelist
1548
Benjamin Peterson42ac4752010-08-09 13:05:35 +00001549def currentframe():
Benjamin Petersona3a3fc62010-08-09 15:49:56 +00001550 """Return the frame of the caller or None if this is not possible."""
Benjamin Peterson42ac4752010-08-09 13:05:35 +00001551 return sys._getframe(1) if hasattr(sys, "_getframe") else None
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001552
1553def stack(context=1):
1554 """Return a list of records for the stack above the caller's frame."""
Jeremy Hyltonab919022003-06-27 18:41:20 +00001555 return getouterframes(sys._getframe(1), context)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001556
1557def trace(context=1):
Tim Peters85ba6732001-02-28 08:26:44 +00001558 """Return a list of records for the stack below the current exception."""
Fred Draked451ec12002-04-26 02:29:55 +00001559 return getinnerframes(sys.exc_info()[2], context)
Michael Foord95fc51d2010-11-20 15:07:30 +00001560
1561
1562# ------------------------------------------------ static version of getattr
1563
1564_sentinel = object()
1565
Michael Foorde5162652010-11-20 16:40:44 +00001566def _static_getmro(klass):
1567 return type.__dict__['__mro__'].__get__(klass)
1568
Michael Foord95fc51d2010-11-20 15:07:30 +00001569def _check_instance(obj, attr):
1570 instance_dict = {}
1571 try:
1572 instance_dict = object.__getattribute__(obj, "__dict__")
1573 except AttributeError:
1574 pass
Michael Foorddcebe0f2011-03-15 19:20:44 -04001575 return dict.get(instance_dict, attr, _sentinel)
Michael Foord95fc51d2010-11-20 15:07:30 +00001576
1577
1578def _check_class(klass, attr):
Michael Foorde5162652010-11-20 16:40:44 +00001579 for entry in _static_getmro(klass):
Michael Foorda51623b2011-12-18 22:01:40 +00001580 if _shadowed_dict(type(entry)) is _sentinel:
Michael Foorddcebe0f2011-03-15 19:20:44 -04001581 try:
1582 return entry.__dict__[attr]
1583 except KeyError:
1584 pass
Michael Foord95fc51d2010-11-20 15:07:30 +00001585 return _sentinel
1586
Michael Foord35184ed2010-11-20 16:58:30 +00001587def _is_type(obj):
1588 try:
1589 _static_getmro(obj)
1590 except TypeError:
1591 return False
1592 return True
1593
Michael Foorddcebe0f2011-03-15 19:20:44 -04001594def _shadowed_dict(klass):
1595 dict_attr = type.__dict__["__dict__"]
1596 for entry in _static_getmro(klass):
1597 try:
1598 class_dict = dict_attr.__get__(entry)["__dict__"]
1599 except KeyError:
1600 pass
1601 else:
Inada Naoki8f9cc872019-09-05 13:07:08 +09001602 if not (type(class_dict) is types.GetSetDescriptorType and
Michael Foorddcebe0f2011-03-15 19:20:44 -04001603 class_dict.__name__ == "__dict__" and
1604 class_dict.__objclass__ is entry):
Michael Foorda51623b2011-12-18 22:01:40 +00001605 return class_dict
1606 return _sentinel
Michael Foord95fc51d2010-11-20 15:07:30 +00001607
1608def getattr_static(obj, attr, default=_sentinel):
1609 """Retrieve attributes without triggering dynamic lookup via the
1610 descriptor protocol, __getattr__ or __getattribute__.
1611
1612 Note: this function may not be able to retrieve all attributes
1613 that getattr can fetch (like dynamically created attributes)
1614 and may find attributes that getattr can't (like descriptors
1615 that raise AttributeError). It can also return descriptor objects
1616 instead of instance members in some cases. See the
1617 documentation for details.
1618 """
1619 instance_result = _sentinel
Michael Foord35184ed2010-11-20 16:58:30 +00001620 if not _is_type(obj):
Michael Foordcc7ebb82010-11-20 16:20:16 +00001621 klass = type(obj)
Michael Foorda51623b2011-12-18 22:01:40 +00001622 dict_attr = _shadowed_dict(klass)
1623 if (dict_attr is _sentinel or
Inada Naoki8f9cc872019-09-05 13:07:08 +09001624 type(dict_attr) is types.MemberDescriptorType):
Michael Foorddcebe0f2011-03-15 19:20:44 -04001625 instance_result = _check_instance(obj, attr)
Michael Foord95fc51d2010-11-20 15:07:30 +00001626 else:
1627 klass = obj
1628
1629 klass_result = _check_class(klass, attr)
1630
1631 if instance_result is not _sentinel and klass_result is not _sentinel:
1632 if (_check_class(type(klass_result), '__get__') is not _sentinel and
1633 _check_class(type(klass_result), '__set__') is not _sentinel):
1634 return klass_result
1635
1636 if instance_result is not _sentinel:
1637 return instance_result
1638 if klass_result is not _sentinel:
1639 return klass_result
1640
1641 if obj is klass:
1642 # for types we check the metaclass too
Michael Foorde5162652010-11-20 16:40:44 +00001643 for entry in _static_getmro(type(klass)):
Michael Foord3ba95f82011-12-22 01:13:37 +00001644 if _shadowed_dict(type(entry)) is _sentinel:
1645 try:
1646 return entry.__dict__[attr]
1647 except KeyError:
1648 pass
Michael Foord95fc51d2010-11-20 15:07:30 +00001649 if default is not _sentinel:
1650 return default
1651 raise AttributeError(attr)
Nick Coghlane0f04652010-11-21 03:44:04 +00001652
1653
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001654# ------------------------------------------------ generator introspection
1655
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001656GEN_CREATED = 'GEN_CREATED'
1657GEN_RUNNING = 'GEN_RUNNING'
1658GEN_SUSPENDED = 'GEN_SUSPENDED'
1659GEN_CLOSED = 'GEN_CLOSED'
Nick Coghlane0f04652010-11-21 03:44:04 +00001660
1661def getgeneratorstate(generator):
1662 """Get current state of a generator-iterator.
1663
1664 Possible states are:
1665 GEN_CREATED: Waiting to start execution.
1666 GEN_RUNNING: Currently being executed by the interpreter.
1667 GEN_SUSPENDED: Currently suspended at a yield expression.
1668 GEN_CLOSED: Execution has completed.
1669 """
1670 if generator.gi_running:
1671 return GEN_RUNNING
1672 if generator.gi_frame is None:
1673 return GEN_CLOSED
1674 if generator.gi_frame.f_lasti == -1:
1675 return GEN_CREATED
1676 return GEN_SUSPENDED
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001677
1678
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001679def getgeneratorlocals(generator):
1680 """
1681 Get the mapping of generator local variables to their current values.
1682
1683 A dict is returned, with the keys the local variable names and values the
1684 bound values."""
1685
1686 if not isgenerator(generator):
Serhiy Storchakaa4a30202017-11-28 22:54:42 +02001687 raise TypeError("{!r} is not a Python generator".format(generator))
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001688
1689 frame = getattr(generator, "gi_frame", None)
1690 if frame is not None:
1691 return generator.gi_frame.f_locals
1692 else:
1693 return {}
1694
Yury Selivanov5376ba92015-06-22 12:19:30 -04001695
1696# ------------------------------------------------ coroutine introspection
1697
1698CORO_CREATED = 'CORO_CREATED'
1699CORO_RUNNING = 'CORO_RUNNING'
1700CORO_SUSPENDED = 'CORO_SUSPENDED'
1701CORO_CLOSED = 'CORO_CLOSED'
1702
1703def getcoroutinestate(coroutine):
1704 """Get current state of a coroutine object.
1705
1706 Possible states are:
1707 CORO_CREATED: Waiting to start execution.
1708 CORO_RUNNING: Currently being executed by the interpreter.
1709 CORO_SUSPENDED: Currently suspended at an await expression.
1710 CORO_CLOSED: Execution has completed.
1711 """
1712 if coroutine.cr_running:
1713 return CORO_RUNNING
1714 if coroutine.cr_frame is None:
1715 return CORO_CLOSED
1716 if coroutine.cr_frame.f_lasti == -1:
1717 return CORO_CREATED
1718 return CORO_SUSPENDED
1719
1720
1721def getcoroutinelocals(coroutine):
1722 """
1723 Get the mapping of coroutine local variables to their current values.
1724
1725 A dict is returned, with the keys the local variable names and values the
1726 bound values."""
1727 frame = getattr(coroutine, "cr_frame", None)
1728 if frame is not None:
1729 return frame.f_locals
1730 else:
1731 return {}
1732
1733
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001734###############################################################################
1735### Function Signature Object (PEP 362)
1736###############################################################################
1737
1738
1739_WrapperDescriptor = type(type.__call__)
1740_MethodWrapper = type(all.__call__)
Larry Hastings5c661892014-01-24 06:17:25 -08001741_ClassMethodWrapper = type(int.__dict__['from_bytes'])
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001742
1743_NonUserDefinedCallables = (_WrapperDescriptor,
1744 _MethodWrapper,
Larry Hastings5c661892014-01-24 06:17:25 -08001745 _ClassMethodWrapper,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001746 types.BuiltinFunctionType)
1747
1748
Yury Selivanov421f0c72014-01-29 12:05:40 -05001749def _signature_get_user_defined_method(cls, method_name):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001750 """Private helper. Checks if ``cls`` has an attribute
1751 named ``method_name`` and returns it only if it is a
1752 pure python function.
1753 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001754 try:
1755 meth = getattr(cls, method_name)
1756 except AttributeError:
1757 return
1758 else:
1759 if not isinstance(meth, _NonUserDefinedCallables):
1760 # Once '__signature__' will be added to 'C'-level
1761 # callables, this check won't be necessary
1762 return meth
1763
1764
Yury Selivanov62560fb2014-01-28 12:26:24 -05001765def _signature_get_partial(wrapped_sig, partial, extra_args=()):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001766 """Private helper to calculate how 'wrapped_sig' signature will
1767 look like after applying a 'functools.partial' object (or alike)
1768 on it.
1769 """
Yury Selivanov62560fb2014-01-28 12:26:24 -05001770
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001771 old_params = wrapped_sig.parameters
Inada Naoki21105512020-03-02 18:54:49 +09001772 new_params = OrderedDict(old_params.items())
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05001773
1774 partial_args = partial.args or ()
1775 partial_keywords = partial.keywords or {}
1776
1777 if extra_args:
1778 partial_args = extra_args + partial_args
1779
1780 try:
1781 ba = wrapped_sig.bind_partial(*partial_args, **partial_keywords)
1782 except TypeError as ex:
1783 msg = 'partial object {!r} has incorrect arguments'.format(partial)
1784 raise ValueError(msg) from ex
1785
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05001786
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001787 transform_to_kwonly = False
1788 for param_name, param in old_params.items():
1789 try:
1790 arg_value = ba.arguments[param_name]
1791 except KeyError:
1792 pass
1793 else:
1794 if param.kind is _POSITIONAL_ONLY:
1795 # If positional-only parameter is bound by partial,
1796 # it effectively disappears from the signature
Inada Naoki21105512020-03-02 18:54:49 +09001797 new_params.pop(param_name)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001798 continue
1799
1800 if param.kind is _POSITIONAL_OR_KEYWORD:
1801 if param_name in partial_keywords:
1802 # This means that this parameter, and all parameters
1803 # after it should be keyword-only (and var-positional
1804 # should be removed). Here's why. Consider the following
1805 # function:
1806 # foo(a, b, *args, c):
1807 # pass
1808 #
1809 # "partial(foo, a='spam')" will have the following
1810 # signature: "(*, a='spam', b, c)". Because attempting
1811 # to call that partial with "(10, 20)" arguments will
1812 # raise a TypeError, saying that "a" argument received
1813 # multiple values.
1814 transform_to_kwonly = True
1815 # Set the new default value
Inada Naoki21105512020-03-02 18:54:49 +09001816 new_params[param_name] = param.replace(default=arg_value)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001817 else:
1818 # was passed as a positional argument
Inada Naoki21105512020-03-02 18:54:49 +09001819 new_params.pop(param.name)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001820 continue
1821
1822 if param.kind is _KEYWORD_ONLY:
1823 # Set the new default value
Inada Naoki21105512020-03-02 18:54:49 +09001824 new_params[param_name] = param.replace(default=arg_value)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001825
1826 if transform_to_kwonly:
1827 assert param.kind is not _POSITIONAL_ONLY
1828
1829 if param.kind is _POSITIONAL_OR_KEYWORD:
Inada Naoki21105512020-03-02 18:54:49 +09001830 new_param = new_params[param_name].replace(kind=_KEYWORD_ONLY)
1831 new_params[param_name] = new_param
1832 new_params.move_to_end(param_name)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001833 elif param.kind in (_KEYWORD_ONLY, _VAR_KEYWORD):
Inada Naoki21105512020-03-02 18:54:49 +09001834 new_params.move_to_end(param_name)
1835 elif param.kind is _VAR_POSITIONAL:
1836 new_params.pop(param.name)
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05001837
1838 return wrapped_sig.replace(parameters=new_params.values())
1839
1840
Yury Selivanov62560fb2014-01-28 12:26:24 -05001841def _signature_bound_method(sig):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001842 """Private helper to transform signatures for unbound
1843 functions to bound methods.
1844 """
Yury Selivanov62560fb2014-01-28 12:26:24 -05001845
1846 params = tuple(sig.parameters.values())
1847
1848 if not params or params[0].kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
1849 raise ValueError('invalid method signature')
1850
1851 kind = params[0].kind
1852 if kind in (_POSITIONAL_OR_KEYWORD, _POSITIONAL_ONLY):
1853 # Drop first parameter:
1854 # '(p1, p2[, ...])' -> '(p2[, ...])'
1855 params = params[1:]
1856 else:
1857 if kind is not _VAR_POSITIONAL:
1858 # Unless we add a new parameter type we never
1859 # get here
1860 raise ValueError('invalid argument type')
1861 # It's a var-positional parameter.
1862 # Do nothing. '(*args[, ...])' -> '(*args[, ...])'
1863
1864 return sig.replace(parameters=params)
1865
1866
Yury Selivanovb77511d2014-01-29 10:46:14 -05001867def _signature_is_builtin(obj):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001868 """Private helper to test if `obj` is a callable that might
1869 support Argument Clinic's __text_signature__ protocol.
1870 """
Yury Selivanov1d241832014-02-02 12:51:20 -05001871 return (isbuiltin(obj) or
Yury Selivanovb77511d2014-01-29 10:46:14 -05001872 ismethoddescriptor(obj) or
Yury Selivanov1d241832014-02-02 12:51:20 -05001873 isinstance(obj, _NonUserDefinedCallables) or
Yury Selivanovb77511d2014-01-29 10:46:14 -05001874 # Can't test 'isinstance(type)' here, as it would
1875 # also be True for regular python classes
1876 obj in (type, object))
1877
1878
Yury Selivanov63da7c72014-01-31 14:48:37 -05001879def _signature_is_functionlike(obj):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001880 """Private helper to test if `obj` is a duck type of FunctionType.
1881 A good example of such objects are functions compiled with
1882 Cython, which have all attributes that a pure Python function
1883 would have, but have their code statically compiled.
1884 """
Yury Selivanov63da7c72014-01-31 14:48:37 -05001885
1886 if not callable(obj) or isclass(obj):
1887 # All function-like objects are obviously callables,
1888 # and not classes.
1889 return False
1890
1891 name = getattr(obj, '__name__', None)
1892 code = getattr(obj, '__code__', None)
1893 defaults = getattr(obj, '__defaults__', _void) # Important to use _void ...
1894 kwdefaults = getattr(obj, '__kwdefaults__', _void) # ... and not None here
Pablo Galindob0544ba2021-04-21 12:41:19 +01001895 annotations = getattr(obj, '__annotations__', None)
Yury Selivanov63da7c72014-01-31 14:48:37 -05001896
1897 return (isinstance(code, types.CodeType) and
1898 isinstance(name, str) and
1899 (defaults is None or isinstance(defaults, tuple)) and
1900 (kwdefaults is None or isinstance(kwdefaults, dict)) and
1901 isinstance(annotations, dict))
1902
1903
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001904def _signature_get_bound_param(spec):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001905 """ Private helper to get first parameter name from a
1906 __text_signature__ of a builtin method, which should
1907 be in the following format: '($param1, ...)'.
1908 Assumptions are that the first argument won't have
1909 a default value or an annotation.
1910 """
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001911
1912 assert spec.startswith('($')
1913
1914 pos = spec.find(',')
1915 if pos == -1:
1916 pos = spec.find(')')
1917
1918 cpos = spec.find(':')
1919 assert cpos == -1 or cpos > pos
1920
1921 cpos = spec.find('=')
1922 assert cpos == -1 or cpos > pos
1923
1924 return spec[2:pos]
1925
1926
Larry Hastings2623c8c2014-02-08 22:15:29 -08001927def _signature_strip_non_python_syntax(signature):
1928 """
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001929 Private helper function. Takes a signature in Argument Clinic's
1930 extended signature format.
1931
Larry Hastings2623c8c2014-02-08 22:15:29 -08001932 Returns a tuple of three things:
1933 * that signature re-rendered in standard Python syntax,
1934 * the index of the "self" parameter (generally 0), or None if
1935 the function does not have a "self" parameter, and
1936 * the index of the last "positional only" parameter,
1937 or None if the signature has no positional-only parameters.
1938 """
1939
1940 if not signature:
1941 return signature, None, None
1942
1943 self_parameter = None
1944 last_positional_only = None
1945
1946 lines = [l.encode('ascii') for l in signature.split('\n')]
1947 generator = iter(lines).__next__
1948 token_stream = tokenize.tokenize(generator)
1949
1950 delayed_comma = False
1951 skip_next_comma = False
1952 text = []
1953 add = text.append
1954
1955 current_parameter = 0
1956 OP = token.OP
1957 ERRORTOKEN = token.ERRORTOKEN
1958
1959 # token stream always starts with ENCODING token, skip it
1960 t = next(token_stream)
1961 assert t.type == tokenize.ENCODING
1962
1963 for t in token_stream:
1964 type, string = t.type, t.string
1965
1966 if type == OP:
1967 if string == ',':
1968 if skip_next_comma:
1969 skip_next_comma = False
1970 else:
1971 assert not delayed_comma
1972 delayed_comma = True
1973 current_parameter += 1
1974 continue
1975
1976 if string == '/':
1977 assert not skip_next_comma
1978 assert last_positional_only is None
1979 skip_next_comma = True
1980 last_positional_only = current_parameter - 1
1981 continue
1982
1983 if (type == ERRORTOKEN) and (string == '$'):
1984 assert self_parameter is None
1985 self_parameter = current_parameter
1986 continue
1987
1988 if delayed_comma:
1989 delayed_comma = False
1990 if not ((type == OP) and (string == ')')):
1991 add(', ')
1992 add(string)
1993 if (string == ','):
1994 add(' ')
1995 clean_signature = ''.join(text)
1996 return clean_signature, self_parameter, last_positional_only
1997
1998
Yury Selivanov57d240e2014-02-19 16:27:23 -05001999def _signature_fromstr(cls, obj, s, skip_bound_arg=True):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002000 """Private helper to parse content of '__text_signature__'
2001 and return a Signature based on it.
2002 """
INADA Naoki37420de2018-01-27 10:10:06 +09002003 # Lazy import ast because it's relatively heavy and
2004 # it's not used for other than this function.
2005 import ast
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002006
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002007 Parameter = cls._parameter_cls
2008
Larry Hastings2623c8c2014-02-08 22:15:29 -08002009 clean_signature, self_parameter, last_positional_only = \
2010 _signature_strip_non_python_syntax(s)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002011
Larry Hastings2623c8c2014-02-08 22:15:29 -08002012 program = "def foo" + clean_signature + ": pass"
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002013
2014 try:
Larry Hastings2623c8c2014-02-08 22:15:29 -08002015 module = ast.parse(program)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002016 except SyntaxError:
2017 module = None
2018
2019 if not isinstance(module, ast.Module):
2020 raise ValueError("{!r} builtin has invalid signature".format(obj))
2021
2022 f = module.body[0]
2023
2024 parameters = []
2025 empty = Parameter.empty
2026 invalid = object()
2027
2028 module = None
2029 module_dict = {}
2030 module_name = getattr(obj, '__module__', None)
2031 if module_name:
2032 module = sys.modules.get(module_name, None)
2033 if module:
2034 module_dict = module.__dict__
INADA Naoki6f85b822018-10-05 01:47:09 +09002035 sys_module_dict = sys.modules.copy()
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002036
2037 def parse_name(node):
2038 assert isinstance(node, ast.arg)
Srinivas Reddy Thatiparthy (శ్రీనివాస్ రెడ్డి తాటిపర్తి)feaefc72018-02-09 15:29:19 +05302039 if node.annotation is not None:
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002040 raise ValueError("Annotations are not currently supported")
2041 return node.arg
2042
2043 def wrap_value(s):
2044 try:
2045 value = eval(s, module_dict)
2046 except NameError:
2047 try:
2048 value = eval(s, sys_module_dict)
2049 except NameError:
2050 raise RuntimeError()
2051
Serhiy Storchaka3f228112018-09-27 17:42:37 +03002052 if isinstance(value, (str, int, float, bytes, bool, type(None))):
2053 return ast.Constant(value)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002054 raise RuntimeError()
2055
2056 class RewriteSymbolics(ast.NodeTransformer):
2057 def visit_Attribute(self, node):
2058 a = []
2059 n = node
2060 while isinstance(n, ast.Attribute):
2061 a.append(n.attr)
2062 n = n.value
2063 if not isinstance(n, ast.Name):
2064 raise RuntimeError()
2065 a.append(n.id)
2066 value = ".".join(reversed(a))
2067 return wrap_value(value)
2068
2069 def visit_Name(self, node):
2070 if not isinstance(node.ctx, ast.Load):
2071 raise ValueError()
2072 return wrap_value(node.id)
2073
2074 def p(name_node, default_node, default=empty):
2075 name = parse_name(name_node)
2076 if name is invalid:
2077 return None
2078 if default_node and default_node is not _empty:
2079 try:
2080 default_node = RewriteSymbolics().visit(default_node)
2081 o = ast.literal_eval(default_node)
2082 except ValueError:
2083 o = invalid
2084 if o is invalid:
2085 return None
2086 default = o if o is not invalid else default
2087 parameters.append(Parameter(name, kind, default=default, annotation=empty))
2088
2089 # non-keyword-only parameters
2090 args = reversed(f.args.args)
2091 defaults = reversed(f.args.defaults)
2092 iter = itertools.zip_longest(args, defaults, fillvalue=None)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002093 if last_positional_only is not None:
2094 kind = Parameter.POSITIONAL_ONLY
2095 else:
2096 kind = Parameter.POSITIONAL_OR_KEYWORD
2097 for i, (name, default) in enumerate(reversed(list(iter))):
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002098 p(name, default)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002099 if i == last_positional_only:
2100 kind = Parameter.POSITIONAL_OR_KEYWORD
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002101
2102 # *args
2103 if f.args.vararg:
2104 kind = Parameter.VAR_POSITIONAL
2105 p(f.args.vararg, empty)
2106
2107 # keyword-only arguments
2108 kind = Parameter.KEYWORD_ONLY
2109 for name, default in zip(f.args.kwonlyargs, f.args.kw_defaults):
2110 p(name, default)
2111
2112 # **kwargs
2113 if f.args.kwarg:
2114 kind = Parameter.VAR_KEYWORD
2115 p(f.args.kwarg, empty)
2116
Larry Hastings2623c8c2014-02-08 22:15:29 -08002117 if self_parameter is not None:
Yury Selivanov8c185ee2014-02-21 01:32:42 -05002118 # Possibly strip the bound argument:
2119 # - We *always* strip first bound argument if
2120 # it is a module.
2121 # - We don't strip first bound argument if
2122 # skip_bound_arg is False.
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002123 assert parameters
Yury Selivanov8c185ee2014-02-21 01:32:42 -05002124 _self = getattr(obj, '__self__', None)
2125 self_isbound = _self is not None
2126 self_ismodule = ismodule(_self)
2127 if self_isbound and (self_ismodule or skip_bound_arg):
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002128 parameters.pop(0)
2129 else:
2130 # for builtins, self parameter is always positional-only!
2131 p = parameters[0].replace(kind=Parameter.POSITIONAL_ONLY)
2132 parameters[0] = p
2133
2134 return cls(parameters, return_annotation=cls.empty)
2135
2136
Yury Selivanov57d240e2014-02-19 16:27:23 -05002137def _signature_from_builtin(cls, func, skip_bound_arg=True):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002138 """Private helper function to get signature for
2139 builtin callables.
2140 """
2141
Yury Selivanov57d240e2014-02-19 16:27:23 -05002142 if not _signature_is_builtin(func):
2143 raise TypeError("{!r} is not a Python builtin "
2144 "function".format(func))
2145
2146 s = getattr(func, "__text_signature__", None)
2147 if not s:
2148 raise ValueError("no signature found for builtin {!r}".format(func))
2149
2150 return _signature_fromstr(cls, func, s, skip_bound_arg)
2151
2152
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002153def _signature_from_function(cls, func, skip_bound_arg=True,
2154 globalns=None, localns=None):
Yury Selivanovcf45f022015-05-20 14:38:50 -04002155 """Private helper: constructs Signature for the given python function."""
2156
2157 is_duck_function = False
2158 if not isfunction(func):
2159 if _signature_is_functionlike(func):
2160 is_duck_function = True
2161 else:
2162 # If it's not a pure Python function, and not a duck type
2163 # of pure function:
2164 raise TypeError('{!r} is not a Python function'.format(func))
2165
Serhiy Storchakad53cf992019-05-06 22:40:27 +03002166 s = getattr(func, "__text_signature__", None)
2167 if s:
2168 return _signature_fromstr(cls, func, s, skip_bound_arg)
2169
Yury Selivanovcf45f022015-05-20 14:38:50 -04002170 Parameter = cls._parameter_cls
2171
2172 # Parameter information.
2173 func_code = func.__code__
2174 pos_count = func_code.co_argcount
2175 arg_names = func_code.co_varnames
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002176 posonly_count = func_code.co_posonlyargcount
Pablo Galindocd74e662019-06-01 18:08:04 +01002177 positional = arg_names[:pos_count]
Yury Selivanovcf45f022015-05-20 14:38:50 -04002178 keyword_only_count = func_code.co_kwonlyargcount
Pablo Galindocd74e662019-06-01 18:08:04 +01002179 keyword_only = arg_names[pos_count:pos_count + keyword_only_count]
Pablo Galindob0544ba2021-04-21 12:41:19 +01002180 annotations = func.__annotations__
Yury Selivanovcf45f022015-05-20 14:38:50 -04002181 defaults = func.__defaults__
2182 kwdefaults = func.__kwdefaults__
2183
2184 if defaults:
2185 pos_default_count = len(defaults)
2186 else:
2187 pos_default_count = 0
2188
2189 parameters = []
2190
Pablo Galindocd74e662019-06-01 18:08:04 +01002191 non_default_count = pos_count - pos_default_count
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002192 posonly_left = posonly_count
2193
Yury Selivanovcf45f022015-05-20 14:38:50 -04002194 # Non-keyword-only parameters w/o defaults.
Pablo Galindocd74e662019-06-01 18:08:04 +01002195 for name in positional[:non_default_count]:
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002196 kind = _POSITIONAL_ONLY if posonly_left else _POSITIONAL_OR_KEYWORD
Yury Selivanovcf45f022015-05-20 14:38:50 -04002197 annotation = annotations.get(name, _empty)
2198 parameters.append(Parameter(name, annotation=annotation,
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002199 kind=kind))
2200 if posonly_left:
2201 posonly_left -= 1
Yury Selivanovcf45f022015-05-20 14:38:50 -04002202
2203 # ... w/ defaults.
Pablo Galindocd74e662019-06-01 18:08:04 +01002204 for offset, name in enumerate(positional[non_default_count:]):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002205 kind = _POSITIONAL_ONLY if posonly_left else _POSITIONAL_OR_KEYWORD
Yury Selivanovcf45f022015-05-20 14:38:50 -04002206 annotation = annotations.get(name, _empty)
2207 parameters.append(Parameter(name, annotation=annotation,
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002208 kind=kind,
Yury Selivanovcf45f022015-05-20 14:38:50 -04002209 default=defaults[offset]))
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002210 if posonly_left:
2211 posonly_left -= 1
Yury Selivanovcf45f022015-05-20 14:38:50 -04002212
2213 # *args
2214 if func_code.co_flags & CO_VARARGS:
Pablo Galindocd74e662019-06-01 18:08:04 +01002215 name = arg_names[pos_count + keyword_only_count]
Yury Selivanovcf45f022015-05-20 14:38:50 -04002216 annotation = annotations.get(name, _empty)
2217 parameters.append(Parameter(name, annotation=annotation,
2218 kind=_VAR_POSITIONAL))
2219
2220 # Keyword-only parameters.
2221 for name in keyword_only:
2222 default = _empty
2223 if kwdefaults is not None:
2224 default = kwdefaults.get(name, _empty)
2225
2226 annotation = annotations.get(name, _empty)
2227 parameters.append(Parameter(name, annotation=annotation,
2228 kind=_KEYWORD_ONLY,
2229 default=default))
2230 # **kwargs
2231 if func_code.co_flags & CO_VARKEYWORDS:
Pablo Galindocd74e662019-06-01 18:08:04 +01002232 index = pos_count + keyword_only_count
Yury Selivanovcf45f022015-05-20 14:38:50 -04002233 if func_code.co_flags & CO_VARARGS:
2234 index += 1
2235
2236 name = arg_names[index]
2237 annotation = annotations.get(name, _empty)
2238 parameters.append(Parameter(name, annotation=annotation,
2239 kind=_VAR_KEYWORD))
2240
2241 # Is 'func' is a pure Python function - don't validate the
2242 # parameters list (for correct order and defaults), it should be OK.
2243 return cls(parameters,
2244 return_annotation=annotations.get('return', _empty),
2245 __validate_parameters__=is_duck_function)
2246
2247
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002248def _signature_from_callable(obj, *,
2249 follow_wrapper_chains=True,
2250 skip_bound_arg=True,
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002251 globalns=None,
2252 localns=None,
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002253 sigcls):
2254
2255 """Private helper function to get signature for arbitrary
2256 callable objects.
2257 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002258
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002259 _get_signature_of = functools.partial(_signature_from_callable,
2260 follow_wrapper_chains=follow_wrapper_chains,
2261 skip_bound_arg=skip_bound_arg,
2262 globalns=globalns,
2263 localns=localns,
2264 sigcls=sigcls)
2265
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002266 if not callable(obj):
2267 raise TypeError('{!r} is not a callable object'.format(obj))
2268
2269 if isinstance(obj, types.MethodType):
2270 # In this case we skip the first parameter of the underlying
2271 # function (usually `self` or `cls`).
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002272 sig = _get_signature_of(obj.__func__)
Yury Selivanovda396452014-03-27 12:09:24 -04002273
Yury Selivanov57d240e2014-02-19 16:27:23 -05002274 if skip_bound_arg:
2275 return _signature_bound_method(sig)
2276 else:
2277 return sig
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002278
Nick Coghlane8c45d62013-07-28 20:00:01 +10002279 # Was this function wrapped by a decorator?
Yury Selivanov57d240e2014-02-19 16:27:23 -05002280 if follow_wrapper_chains:
2281 obj = unwrap(obj, stop=(lambda f: hasattr(f, "__signature__")))
Yury Selivanov46c759d2015-05-27 21:56:53 -04002282 if isinstance(obj, types.MethodType):
2283 # If the unwrapped object is a *method*, we might want to
2284 # skip its first parameter (self).
2285 # See test_signature_wrapped_bound_method for details.
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002286 return _get_signature_of(obj)
Nick Coghlane8c45d62013-07-28 20:00:01 +10002287
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002288 try:
2289 sig = obj.__signature__
2290 except AttributeError:
2291 pass
2292 else:
2293 if sig is not None:
Yury Selivanov42407ab2014-06-23 10:23:50 -07002294 if not isinstance(sig, Signature):
2295 raise TypeError(
2296 'unexpected object {!r} in __signature__ '
2297 'attribute'.format(sig))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002298 return sig
2299
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002300 try:
2301 partialmethod = obj._partialmethod
2302 except AttributeError:
2303 pass
2304 else:
Yury Selivanov0486f812014-01-29 12:18:59 -05002305 if isinstance(partialmethod, functools.partialmethod):
2306 # Unbound partialmethod (see functools.partialmethod)
2307 # This means, that we need to calculate the signature
2308 # as if it's a regular partial object, but taking into
2309 # account that the first positional argument
2310 # (usually `self`, or `cls`) will not be passed
2311 # automatically (as for boundmethods)
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002312
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002313 wrapped_sig = _get_signature_of(partialmethod.func)
Yury Selivanovda396452014-03-27 12:09:24 -04002314
Yury Selivanov0486f812014-01-29 12:18:59 -05002315 sig = _signature_get_partial(wrapped_sig, partialmethod, (None,))
Yury Selivanov0486f812014-01-29 12:18:59 -05002316 first_wrapped_param = tuple(wrapped_sig.parameters.values())[0]
Dong-hee Na378d7062017-05-18 04:00:51 +09002317 if first_wrapped_param.kind is Parameter.VAR_POSITIONAL:
2318 # First argument of the wrapped callable is `*args`, as in
2319 # `partialmethod(lambda *args)`.
2320 return sig
2321 else:
2322 sig_params = tuple(sig.parameters.values())
Yury Selivanov8a387212018-03-06 12:59:45 -05002323 assert (not sig_params or
2324 first_wrapped_param is not sig_params[0])
Dong-hee Na378d7062017-05-18 04:00:51 +09002325 new_params = (first_wrapped_param,) + sig_params
2326 return sig.replace(parameters=new_params)
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002327
Yury Selivanov63da7c72014-01-31 14:48:37 -05002328 if isfunction(obj) or _signature_is_functionlike(obj):
2329 # If it's a pure Python function, or an object that is duck type
2330 # of a Python function (Cython functions, for instance), then:
Serhiy Storchakad53cf992019-05-06 22:40:27 +03002331 return _signature_from_function(sigcls, obj,
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002332 skip_bound_arg=skip_bound_arg,
2333 globalns=globalns, localns=localns)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002334
Yury Selivanova773de02014-02-21 18:30:53 -05002335 if _signature_is_builtin(obj):
Yury Selivanovda396452014-03-27 12:09:24 -04002336 return _signature_from_builtin(sigcls, obj,
Yury Selivanova773de02014-02-21 18:30:53 -05002337 skip_bound_arg=skip_bound_arg)
2338
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002339 if isinstance(obj, functools.partial):
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002340 wrapped_sig = _get_signature_of(obj.func)
Yury Selivanov62560fb2014-01-28 12:26:24 -05002341 return _signature_get_partial(wrapped_sig, obj)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002342
2343 sig = None
2344 if isinstance(obj, type):
2345 # obj is a class or a metaclass
2346
2347 # First, let's see if it has an overloaded __call__ defined
2348 # in its metaclass
Yury Selivanov421f0c72014-01-29 12:05:40 -05002349 call = _signature_get_user_defined_method(type(obj), '__call__')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002350 if call is not None:
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002351 sig = _get_signature_of(call)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002352 else:
2353 # Now we check if the 'obj' class has a '__new__' method
Yury Selivanov421f0c72014-01-29 12:05:40 -05002354 new = _signature_get_user_defined_method(obj, '__new__')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002355 if new is not None:
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002356 sig = _get_signature_of(new)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002357 else:
2358 # Finally, we should have at least __init__ implemented
Yury Selivanov421f0c72014-01-29 12:05:40 -05002359 init = _signature_get_user_defined_method(obj, '__init__')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002360 if init is not None:
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002361 sig = _get_signature_of(init)
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002362
2363 if sig is None:
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002364 # At this point we know, that `obj` is a class, with no user-
2365 # defined '__init__', '__new__', or class-level '__call__'
2366
Larry Hastings2623c8c2014-02-08 22:15:29 -08002367 for base in obj.__mro__[:-1]:
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002368 # Since '__text_signature__' is implemented as a
2369 # descriptor that extracts text signature from the
2370 # class docstring, if 'obj' is derived from a builtin
2371 # class, its own '__text_signature__' may be 'None'.
Larry Hastings2623c8c2014-02-08 22:15:29 -08002372 # Therefore, we go through the MRO (except the last
2373 # class in there, which is 'object') to find the first
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002374 # class with non-empty text signature.
2375 try:
2376 text_sig = base.__text_signature__
2377 except AttributeError:
2378 pass
2379 else:
2380 if text_sig:
2381 # If 'obj' class has a __text_signature__ attribute:
2382 # return a signature based on it
Yury Selivanovda396452014-03-27 12:09:24 -04002383 return _signature_fromstr(sigcls, obj, text_sig)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002384
2385 # No '__text_signature__' was found for the 'obj' class.
2386 # Last option is to check if its '__init__' is
2387 # object.__init__ or type.__init__.
Larry Hastings2623c8c2014-02-08 22:15:29 -08002388 if type not in obj.__mro__:
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002389 # We have a class (not metaclass), but no user-defined
2390 # __init__ or __new__ for it
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002391 if (obj.__init__ is object.__init__ and
2392 obj.__new__ is object.__new__):
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002393 # Return a signature of 'object' builtin.
Gregory P. Smith5b9ff7a2019-09-13 17:13:51 +01002394 return sigcls.from_callable(object)
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002395 else:
2396 raise ValueError(
2397 'no signature found for builtin type {!r}'.format(obj))
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002398
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002399 elif not isinstance(obj, _NonUserDefinedCallables):
2400 # An object with __call__
2401 # We also check that the 'obj' is not an instance of
2402 # _WrapperDescriptor or _MethodWrapper to avoid
2403 # infinite recursion (and even potential segfault)
Yury Selivanov421f0c72014-01-29 12:05:40 -05002404 call = _signature_get_user_defined_method(type(obj), '__call__')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002405 if call is not None:
Larry Hastings2623c8c2014-02-08 22:15:29 -08002406 try:
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002407 sig = _get_signature_of(call)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002408 except ValueError as ex:
2409 msg = 'no signature found for {!r}'.format(obj)
2410 raise ValueError(msg) from ex
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002411
2412 if sig is not None:
2413 # For classes and objects we skip the first parameter of their
2414 # __call__, __new__, or __init__ methods
Yury Selivanov57d240e2014-02-19 16:27:23 -05002415 if skip_bound_arg:
2416 return _signature_bound_method(sig)
2417 else:
2418 return sig
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002419
2420 if isinstance(obj, types.BuiltinFunctionType):
2421 # Raise a nicer error message for builtins
2422 msg = 'no signature found for builtin function {!r}'.format(obj)
2423 raise ValueError(msg)
2424
2425 raise ValueError('callable {!r} is not supported by signature'.format(obj))
2426
2427
2428class _void:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002429 """A private marker - used in Parameter & Signature."""
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002430
2431
2432class _empty:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002433 """Marker object for Signature.empty and Parameter.empty."""
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002434
2435
Yury Selivanov21e83a52014-03-27 11:23:13 -04002436class _ParameterKind(enum.IntEnum):
2437 POSITIONAL_ONLY = 0
2438 POSITIONAL_OR_KEYWORD = 1
2439 VAR_POSITIONAL = 2
2440 KEYWORD_ONLY = 3
2441 VAR_KEYWORD = 4
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002442
Dong-hee Na4aa30062018-06-08 12:46:31 +09002443 @property
2444 def description(self):
2445 return _PARAM_NAME_MAPPING[self]
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002446
Yury Selivanov21e83a52014-03-27 11:23:13 -04002447_POSITIONAL_ONLY = _ParameterKind.POSITIONAL_ONLY
2448_POSITIONAL_OR_KEYWORD = _ParameterKind.POSITIONAL_OR_KEYWORD
2449_VAR_POSITIONAL = _ParameterKind.VAR_POSITIONAL
2450_KEYWORD_ONLY = _ParameterKind.KEYWORD_ONLY
2451_VAR_KEYWORD = _ParameterKind.VAR_KEYWORD
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002452
Dong-hee Naa9cab432018-05-30 00:04:08 +09002453_PARAM_NAME_MAPPING = {
2454 _POSITIONAL_ONLY: 'positional-only',
2455 _POSITIONAL_OR_KEYWORD: 'positional or keyword',
2456 _VAR_POSITIONAL: 'variadic positional',
2457 _KEYWORD_ONLY: 'keyword-only',
2458 _VAR_KEYWORD: 'variadic keyword'
2459}
2460
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002461
2462class Parameter:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002463 """Represents a parameter in a function signature.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002464
2465 Has the following public attributes:
2466
2467 * name : str
2468 The name of the parameter as a string.
2469 * default : object
2470 The default value for the parameter if specified. If the
Yury Selivanov8757ead2014-01-28 16:39:25 -05002471 parameter has no default value, this attribute is set to
2472 `Parameter.empty`.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002473 * annotation
2474 The annotation for the parameter if specified. If the
Yury Selivanov8757ead2014-01-28 16:39:25 -05002475 parameter has no annotation, this attribute is set to
2476 `Parameter.empty`.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002477 * kind : str
2478 Describes how argument values are bound to the parameter.
2479 Possible values: `Parameter.POSITIONAL_ONLY`,
2480 `Parameter.POSITIONAL_OR_KEYWORD`, `Parameter.VAR_POSITIONAL`,
2481 `Parameter.KEYWORD_ONLY`, `Parameter.VAR_KEYWORD`.
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002482 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002483
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002484 __slots__ = ('_name', '_kind', '_default', '_annotation')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002485
2486 POSITIONAL_ONLY = _POSITIONAL_ONLY
2487 POSITIONAL_OR_KEYWORD = _POSITIONAL_OR_KEYWORD
2488 VAR_POSITIONAL = _VAR_POSITIONAL
2489 KEYWORD_ONLY = _KEYWORD_ONLY
2490 VAR_KEYWORD = _VAR_KEYWORD
2491
2492 empty = _empty
2493
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002494 def __init__(self, name, kind, *, default=_empty, annotation=_empty):
Dong-hee Naa9cab432018-05-30 00:04:08 +09002495 try:
2496 self._kind = _ParameterKind(kind)
2497 except ValueError:
2498 raise ValueError(f'value {kind!r} is not a valid Parameter.kind')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002499 if default is not _empty:
Dong-hee Naa9cab432018-05-30 00:04:08 +09002500 if self._kind in (_VAR_POSITIONAL, _VAR_KEYWORD):
2501 msg = '{} parameters cannot have default values'
Dong-hee Na4aa30062018-06-08 12:46:31 +09002502 msg = msg.format(self._kind.description)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002503 raise ValueError(msg)
2504 self._default = default
2505 self._annotation = annotation
2506
Yury Selivanov2393dca2014-01-27 15:07:58 -05002507 if name is _empty:
2508 raise ValueError('name is a required attribute for Parameter')
2509
2510 if not isinstance(name, str):
Dong-hee Naa9cab432018-05-30 00:04:08 +09002511 msg = 'name must be a str, not a {}'.format(type(name).__name__)
2512 raise TypeError(msg)
Yury Selivanov2393dca2014-01-27 15:07:58 -05002513
Nick Coghlanb4b966e2016-06-04 14:40:03 -07002514 if name[0] == '.' and name[1:].isdigit():
2515 # These are implicit arguments generated by comprehensions. In
2516 # order to provide a friendlier interface to users, we recast
2517 # their name as "implicitN" and treat them as positional-only.
2518 # See issue 19611.
Dong-hee Naa9cab432018-05-30 00:04:08 +09002519 if self._kind != _POSITIONAL_OR_KEYWORD:
2520 msg = (
2521 'implicit arguments must be passed as '
2522 'positional or keyword arguments, not {}'
Nick Coghlanb4b966e2016-06-04 14:40:03 -07002523 )
Dong-hee Na4aa30062018-06-08 12:46:31 +09002524 msg = msg.format(self._kind.description)
Dong-hee Naa9cab432018-05-30 00:04:08 +09002525 raise ValueError(msg)
Nick Coghlanb4b966e2016-06-04 14:40:03 -07002526 self._kind = _POSITIONAL_ONLY
2527 name = 'implicit{}'.format(name[1:])
2528
Yury Selivanov2393dca2014-01-27 15:07:58 -05002529 if not name.isidentifier():
2530 raise ValueError('{!r} is not a valid parameter name'.format(name))
2531
2532 self._name = name
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002533
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002534 def __reduce__(self):
2535 return (type(self),
2536 (self._name, self._kind),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002537 {'_default': self._default,
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002538 '_annotation': self._annotation})
2539
2540 def __setstate__(self, state):
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002541 self._default = state['_default']
2542 self._annotation = state['_annotation']
2543
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002544 @property
2545 def name(self):
2546 return self._name
2547
2548 @property
2549 def default(self):
2550 return self._default
2551
2552 @property
2553 def annotation(self):
2554 return self._annotation
2555
2556 @property
2557 def kind(self):
2558 return self._kind
2559
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002560 def replace(self, *, name=_void, kind=_void,
2561 annotation=_void, default=_void):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002562 """Creates a customized copy of the Parameter."""
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002563
2564 if name is _void:
2565 name = self._name
2566
2567 if kind is _void:
2568 kind = self._kind
2569
2570 if annotation is _void:
2571 annotation = self._annotation
2572
2573 if default is _void:
2574 default = self._default
2575
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002576 return type(self)(name, kind, default=default, annotation=annotation)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002577
2578 def __str__(self):
2579 kind = self.kind
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002580 formatted = self._name
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002581
2582 # Add annotation and default value
2583 if self._annotation is not _empty:
Dong-hee Na762b9572017-11-16 03:30:59 +09002584 formatted = '{}: {}'.format(formatted,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002585 formatannotation(self._annotation))
2586
2587 if self._default is not _empty:
Dong-hee Na762b9572017-11-16 03:30:59 +09002588 if self._annotation is not _empty:
2589 formatted = '{} = {}'.format(formatted, repr(self._default))
2590 else:
2591 formatted = '{}={}'.format(formatted, repr(self._default))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002592
2593 if kind == _VAR_POSITIONAL:
2594 formatted = '*' + formatted
2595 elif kind == _VAR_KEYWORD:
2596 formatted = '**' + formatted
2597
2598 return formatted
2599
2600 def __repr__(self):
Yury Selivanovf229bc52015-05-15 12:53:56 -04002601 return '<{} "{}">'.format(self.__class__.__name__, self)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002602
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002603 def __hash__(self):
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002604 return hash((self.name, self.kind, self.annotation, self.default))
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002605
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002606 def __eq__(self, other):
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03002607 if self is other:
2608 return True
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002609 if not isinstance(other, Parameter):
2610 return NotImplemented
2611 return (self._name == other._name and
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002612 self._kind == other._kind and
2613 self._default == other._default and
2614 self._annotation == other._annotation)
2615
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002616
2617class BoundArguments:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002618 """Result of `Signature.bind` call. Holds the mapping of arguments
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002619 to the function's parameters.
2620
2621 Has the following public attributes:
2622
Rémi Lapeyre2cca8ef2020-01-28 13:47:03 +01002623 * arguments : dict
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002624 An ordered mutable mapping of parameters' names to arguments' values.
2625 Does not contain arguments' default values.
2626 * signature : Signature
2627 The Signature object that created this instance.
2628 * args : tuple
2629 Tuple of positional arguments values.
2630 * kwargs : dict
2631 Dict of keyword arguments values.
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002632 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002633
Yury Selivanov6abe0322015-05-13 17:18:41 -04002634 __slots__ = ('arguments', '_signature', '__weakref__')
2635
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002636 def __init__(self, signature, arguments):
2637 self.arguments = arguments
2638 self._signature = signature
2639
2640 @property
2641 def signature(self):
2642 return self._signature
2643
2644 @property
2645 def args(self):
2646 args = []
2647 for param_name, param in self._signature.parameters.items():
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002648 if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002649 break
2650
2651 try:
2652 arg = self.arguments[param_name]
2653 except KeyError:
2654 # We're done here. Other arguments
2655 # will be mapped in 'BoundArguments.kwargs'
2656 break
2657 else:
2658 if param.kind == _VAR_POSITIONAL:
2659 # *args
2660 args.extend(arg)
2661 else:
2662 # plain argument
2663 args.append(arg)
2664
2665 return tuple(args)
2666
2667 @property
2668 def kwargs(self):
2669 kwargs = {}
2670 kwargs_started = False
2671 for param_name, param in self._signature.parameters.items():
2672 if not kwargs_started:
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002673 if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002674 kwargs_started = True
2675 else:
2676 if param_name not in self.arguments:
2677 kwargs_started = True
2678 continue
2679
2680 if not kwargs_started:
2681 continue
2682
2683 try:
2684 arg = self.arguments[param_name]
2685 except KeyError:
2686 pass
2687 else:
2688 if param.kind == _VAR_KEYWORD:
2689 # **kwargs
2690 kwargs.update(arg)
2691 else:
2692 # plain keyword argument
2693 kwargs[param_name] = arg
2694
2695 return kwargs
2696
Yury Selivanovb907a512015-05-16 13:45:09 -04002697 def apply_defaults(self):
2698 """Set default values for missing arguments.
2699
2700 For variable-positional arguments (*args) the default is an
2701 empty tuple.
2702
2703 For variable-keyword arguments (**kwargs) the default is an
2704 empty dict.
2705 """
2706 arguments = self.arguments
Yury Selivanovb907a512015-05-16 13:45:09 -04002707 new_arguments = []
2708 for name, param in self._signature.parameters.items():
2709 try:
2710 new_arguments.append((name, arguments[name]))
2711 except KeyError:
2712 if param.default is not _empty:
2713 val = param.default
2714 elif param.kind is _VAR_POSITIONAL:
2715 val = ()
2716 elif param.kind is _VAR_KEYWORD:
2717 val = {}
2718 else:
2719 # This BoundArguments was likely produced by
2720 # Signature.bind_partial().
2721 continue
2722 new_arguments.append((name, val))
Rémi Lapeyre2cca8ef2020-01-28 13:47:03 +01002723 self.arguments = dict(new_arguments)
Yury Selivanovb907a512015-05-16 13:45:09 -04002724
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002725 def __eq__(self, other):
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03002726 if self is other:
2727 return True
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002728 if not isinstance(other, BoundArguments):
2729 return NotImplemented
2730 return (self.signature == other.signature and
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002731 self.arguments == other.arguments)
2732
Yury Selivanov6abe0322015-05-13 17:18:41 -04002733 def __setstate__(self, state):
2734 self._signature = state['_signature']
2735 self.arguments = state['arguments']
2736
2737 def __getstate__(self):
2738 return {'_signature': self._signature, 'arguments': self.arguments}
2739
Yury Selivanov3f6538f2015-05-14 18:47:17 -04002740 def __repr__(self):
2741 args = []
2742 for arg, value in self.arguments.items():
2743 args.append('{}={!r}'.format(arg, value))
Yury Selivanovf229bc52015-05-15 12:53:56 -04002744 return '<{} ({})>'.format(self.__class__.__name__, ', '.join(args))
Yury Selivanov3f6538f2015-05-14 18:47:17 -04002745
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002746
2747class Signature:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002748 """A Signature object represents the overall signature of a function.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002749 It stores a Parameter object for each parameter accepted by the
2750 function, as well as information specific to the function itself.
2751
2752 A Signature object has the following public attributes and methods:
2753
Jens Reidel611836a2020-03-18 03:22:46 +01002754 * parameters : OrderedDict
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002755 An ordered mapping of parameters' names to the corresponding
2756 Parameter objects (keyword-only arguments are in the same order
2757 as listed in `code.co_varnames`).
2758 * return_annotation : object
2759 The annotation for the return type of the function if specified.
2760 If the function has no annotation for its return type, this
Yury Selivanov8757ead2014-01-28 16:39:25 -05002761 attribute is set to `Signature.empty`.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002762 * bind(*args, **kwargs) -> BoundArguments
2763 Creates a mapping from positional and keyword arguments to
2764 parameters.
2765 * bind_partial(*args, **kwargs) -> BoundArguments
2766 Creates a partial mapping from positional and keyword arguments
2767 to parameters (simulating 'functools.partial' behavior.)
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002768 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002769
2770 __slots__ = ('_return_annotation', '_parameters')
2771
2772 _parameter_cls = Parameter
2773 _bound_arguments_cls = BoundArguments
2774
2775 empty = _empty
2776
2777 def __init__(self, parameters=None, *, return_annotation=_empty,
2778 __validate_parameters__=True):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002779 """Constructs Signature from the given list of Parameter
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002780 objects and 'return_annotation'. All arguments are optional.
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002781 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002782
2783 if parameters is None:
Jens Reidel611836a2020-03-18 03:22:46 +01002784 params = OrderedDict()
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002785 else:
2786 if __validate_parameters__:
Jens Reidel611836a2020-03-18 03:22:46 +01002787 params = OrderedDict()
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002788 top_kind = _POSITIONAL_ONLY
Yury Selivanov07a9e452014-01-29 10:58:16 -05002789 kind_defaults = False
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002790
Rémi Lapeyre2cca8ef2020-01-28 13:47:03 +01002791 for param in parameters:
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002792 kind = param.kind
Yury Selivanov2393dca2014-01-27 15:07:58 -05002793 name = param.name
2794
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002795 if kind < top_kind:
Dong-hee Naa9cab432018-05-30 00:04:08 +09002796 msg = (
2797 'wrong parameter order: {} parameter before {} '
2798 'parameter'
2799 )
Dong-hee Na4aa30062018-06-08 12:46:31 +09002800 msg = msg.format(top_kind.description,
2801 kind.description)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002802 raise ValueError(msg)
Yury Selivanov07a9e452014-01-29 10:58:16 -05002803 elif kind > top_kind:
2804 kind_defaults = False
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002805 top_kind = kind
2806
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002807 if kind in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD):
Yury Selivanov07a9e452014-01-29 10:58:16 -05002808 if param.default is _empty:
2809 if kind_defaults:
2810 # No default for this parameter, but the
2811 # previous parameter of the same kind had
2812 # a default
2813 msg = 'non-default argument follows default ' \
2814 'argument'
2815 raise ValueError(msg)
2816 else:
2817 # There is a default for this parameter.
2818 kind_defaults = True
2819
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002820 if name in params:
2821 msg = 'duplicate parameter name: {!r}'.format(name)
2822 raise ValueError(msg)
Yury Selivanov2393dca2014-01-27 15:07:58 -05002823
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002824 params[name] = param
2825 else:
Jens Reidel611836a2020-03-18 03:22:46 +01002826 params = OrderedDict((param.name, param) for param in parameters)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002827
2828 self._parameters = types.MappingProxyType(params)
2829 self._return_annotation = return_annotation
2830
2831 @classmethod
2832 def from_function(cls, func):
Matthias Bussonnierded87d82018-10-19 16:40:45 -07002833 """Constructs Signature for the given python function.
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002834
Matthias Bussonnierded87d82018-10-19 16:40:45 -07002835 Deprecated since Python 3.5, use `Signature.from_callable()`.
2836 """
2837
2838 warnings.warn("inspect.Signature.from_function() is deprecated since "
2839 "Python 3.5, use Signature.from_callable()",
Berker Peksagb5601582015-05-21 23:40:54 +03002840 DeprecationWarning, stacklevel=2)
Yury Selivanovcf45f022015-05-20 14:38:50 -04002841 return _signature_from_function(cls, func)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002842
Larry Hastings44e2eaa2013-11-23 15:37:55 -08002843 @classmethod
2844 def from_builtin(cls, func):
Matthias Bussonnierded87d82018-10-19 16:40:45 -07002845 """Constructs Signature for the given builtin function.
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002846
Matthias Bussonnierded87d82018-10-19 16:40:45 -07002847 Deprecated since Python 3.5, use `Signature.from_callable()`.
2848 """
2849
2850 warnings.warn("inspect.Signature.from_builtin() is deprecated since "
2851 "Python 3.5, use Signature.from_callable()",
Berker Peksagb5601582015-05-21 23:40:54 +03002852 DeprecationWarning, stacklevel=2)
Yury Selivanov57d240e2014-02-19 16:27:23 -05002853 return _signature_from_builtin(cls, func)
Larry Hastings44e2eaa2013-11-23 15:37:55 -08002854
Yury Selivanovda396452014-03-27 12:09:24 -04002855 @classmethod
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002856 def from_callable(cls, obj, *,
2857 follow_wrapped=True, globalns=None, localns=None):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002858 """Constructs Signature for the given callable object."""
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002859 return _signature_from_callable(obj, sigcls=cls,
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002860 follow_wrapper_chains=follow_wrapped,
2861 globalns=globalns, localns=localns)
Yury Selivanovda396452014-03-27 12:09:24 -04002862
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002863 @property
2864 def parameters(self):
2865 return self._parameters
2866
2867 @property
2868 def return_annotation(self):
2869 return self._return_annotation
2870
2871 def replace(self, *, parameters=_void, return_annotation=_void):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002872 """Creates a customized copy of the Signature.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002873 Pass 'parameters' and/or 'return_annotation' arguments
2874 to override them in the new copy.
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002875 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002876
2877 if parameters is _void:
2878 parameters = self.parameters.values()
2879
2880 if return_annotation is _void:
2881 return_annotation = self._return_annotation
2882
2883 return type(self)(parameters,
2884 return_annotation=return_annotation)
2885
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002886 def _hash_basis(self):
2887 params = tuple(param for param in self.parameters.values()
2888 if param.kind != _KEYWORD_ONLY)
2889
2890 kwo_params = {param.name: param for param in self.parameters.values()
2891 if param.kind == _KEYWORD_ONLY}
2892
2893 return params, kwo_params, self.return_annotation
2894
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002895 def __hash__(self):
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002896 params, kwo_params, return_annotation = self._hash_basis()
2897 kwo_params = frozenset(kwo_params.values())
2898 return hash((params, kwo_params, return_annotation))
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002899
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002900 def __eq__(self, other):
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03002901 if self is other:
2902 return True
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002903 if not isinstance(other, Signature):
2904 return NotImplemented
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03002905 return self._hash_basis() == other._hash_basis()
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002906
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002907 def _bind(self, args, kwargs, *, partial=False):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002908 """Private method. Don't use directly."""
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002909
Rémi Lapeyre2cca8ef2020-01-28 13:47:03 +01002910 arguments = {}
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002911
2912 parameters = iter(self.parameters.values())
2913 parameters_ex = ()
2914 arg_vals = iter(args)
2915
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002916 while True:
2917 # Let's iterate through the positional arguments and corresponding
2918 # parameters
2919 try:
2920 arg_val = next(arg_vals)
2921 except StopIteration:
2922 # No more positional arguments
2923 try:
2924 param = next(parameters)
2925 except StopIteration:
2926 # No more parameters. That's it. Just need to check that
2927 # we have no `kwargs` after this while loop
2928 break
2929 else:
2930 if param.kind == _VAR_POSITIONAL:
2931 # That's OK, just empty *args. Let's start parsing
2932 # kwargs
2933 break
2934 elif param.name in kwargs:
2935 if param.kind == _POSITIONAL_ONLY:
2936 msg = '{arg!r} parameter is positional only, ' \
2937 'but was passed as a keyword'
2938 msg = msg.format(arg=param.name)
2939 raise TypeError(msg) from None
2940 parameters_ex = (param,)
2941 break
2942 elif (param.kind == _VAR_KEYWORD or
2943 param.default is not _empty):
2944 # That's fine too - we have a default value for this
2945 # parameter. So, lets start parsing `kwargs`, starting
2946 # with the current parameter
2947 parameters_ex = (param,)
2948 break
2949 else:
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05002950 # No default, not VAR_KEYWORD, not VAR_POSITIONAL,
2951 # not in `kwargs`
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002952 if partial:
2953 parameters_ex = (param,)
2954 break
2955 else:
Yury Selivanov86872752015-05-19 00:27:49 -04002956 msg = 'missing a required argument: {arg!r}'
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002957 msg = msg.format(arg=param.name)
2958 raise TypeError(msg) from None
2959 else:
2960 # We have a positional argument to process
2961 try:
2962 param = next(parameters)
2963 except StopIteration:
2964 raise TypeError('too many positional arguments') from None
2965 else:
2966 if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
2967 # Looks like we have no parameter for this positional
2968 # argument
Yury Selivanov86872752015-05-19 00:27:49 -04002969 raise TypeError(
2970 'too many positional arguments') from None
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002971
2972 if param.kind == _VAR_POSITIONAL:
2973 # We have an '*args'-like argument, let's fill it with
2974 # all positional arguments we have left and move on to
2975 # the next phase
2976 values = [arg_val]
2977 values.extend(arg_vals)
2978 arguments[param.name] = tuple(values)
2979 break
2980
Pablo Galindof3ef06a2019-10-15 12:40:02 +01002981 if param.name in kwargs and param.kind != _POSITIONAL_ONLY:
Yury Selivanov86872752015-05-19 00:27:49 -04002982 raise TypeError(
2983 'multiple values for argument {arg!r}'.format(
2984 arg=param.name)) from None
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002985
2986 arguments[param.name] = arg_val
2987
2988 # Now, we iterate through the remaining parameters to process
2989 # keyword arguments
2990 kwargs_param = None
2991 for param in itertools.chain(parameters_ex, parameters):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002992 if param.kind == _VAR_KEYWORD:
2993 # Memorize that we have a '**kwargs'-like parameter
2994 kwargs_param = param
2995 continue
2996
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05002997 if param.kind == _VAR_POSITIONAL:
2998 # Named arguments don't refer to '*args'-like parameters.
2999 # We only arrive here if the positional arguments ended
3000 # before reaching the last parameter before *args.
3001 continue
3002
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003003 param_name = param.name
3004 try:
3005 arg_val = kwargs.pop(param_name)
3006 except KeyError:
3007 # We have no value for this parameter. It's fine though,
3008 # if it has a default value, or it is an '*args'-like
3009 # parameter, left alone by the processing of positional
3010 # arguments.
3011 if (not partial and param.kind != _VAR_POSITIONAL and
3012 param.default is _empty):
Yury Selivanov86872752015-05-19 00:27:49 -04003013 raise TypeError('missing a required argument: {arg!r}'. \
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003014 format(arg=param_name)) from None
3015
3016 else:
Yury Selivanov9b9ac952014-01-28 20:54:28 -05003017 if param.kind == _POSITIONAL_ONLY:
3018 # This should never happen in case of a properly built
3019 # Signature object (but let's have this check here
3020 # to ensure correct behaviour just in case)
3021 raise TypeError('{arg!r} parameter is positional only, '
3022 'but was passed as a keyword'. \
3023 format(arg=param.name))
3024
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003025 arguments[param_name] = arg_val
3026
3027 if kwargs:
3028 if kwargs_param is not None:
3029 # Process our '**kwargs'-like parameter
3030 arguments[kwargs_param.name] = kwargs
3031 else:
Yury Selivanov86872752015-05-19 00:27:49 -04003032 raise TypeError(
3033 'got an unexpected keyword argument {arg!r}'.format(
3034 arg=next(iter(kwargs))))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003035
3036 return self._bound_arguments_cls(self, arguments)
3037
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03003038 def bind(self, /, *args, **kwargs):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04003039 """Get a BoundArguments object, that maps the passed `args`
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003040 and `kwargs` to the function's signature. Raises `TypeError`
3041 if the passed arguments can not be bound.
Yury Selivanov5a23bd02014-03-29 13:47:11 -04003042 """
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03003043 return self._bind(args, kwargs)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003044
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03003045 def bind_partial(self, /, *args, **kwargs):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04003046 """Get a BoundArguments object, that partially maps the
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003047 passed `args` and `kwargs` to the function's signature.
3048 Raises `TypeError` 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, partial=True)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003051
Yury Selivanova5d63dd2014-03-27 11:31:43 -04003052 def __reduce__(self):
3053 return (type(self),
3054 (tuple(self._parameters.values()),),
3055 {'_return_annotation': self._return_annotation})
3056
3057 def __setstate__(self, state):
3058 self._return_annotation = state['_return_annotation']
3059
Yury Selivanov374375d2014-03-27 12:41:53 -04003060 def __repr__(self):
Yury Selivanovf229bc52015-05-15 12:53:56 -04003061 return '<{} {}>'.format(self.__class__.__name__, self)
Yury Selivanov374375d2014-03-27 12:41:53 -04003062
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003063 def __str__(self):
3064 result = []
Yury Selivanov2393dca2014-01-27 15:07:58 -05003065 render_pos_only_separator = False
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003066 render_kw_only_separator = True
Yury Selivanov2393dca2014-01-27 15:07:58 -05003067 for param in self.parameters.values():
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003068 formatted = str(param)
3069
3070 kind = param.kind
Yury Selivanov2393dca2014-01-27 15:07:58 -05003071
3072 if kind == _POSITIONAL_ONLY:
3073 render_pos_only_separator = True
3074 elif render_pos_only_separator:
3075 # It's not a positional-only parameter, and the flag
3076 # is set to 'True' (there were pos-only params before.)
3077 result.append('/')
3078 render_pos_only_separator = False
3079
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003080 if kind == _VAR_POSITIONAL:
3081 # OK, we have an '*args'-like parameter, so we won't need
3082 # a '*' to separate keyword-only arguments
3083 render_kw_only_separator = False
3084 elif kind == _KEYWORD_ONLY and render_kw_only_separator:
3085 # We have a keyword-only parameter to render and we haven't
3086 # rendered an '*args'-like parameter before, so add a '*'
3087 # separator to the parameters list ("foo(arg1, *, arg2)" case)
3088 result.append('*')
3089 # This condition should be only triggered once, so
3090 # reset the flag
3091 render_kw_only_separator = False
3092
3093 result.append(formatted)
3094
Yury Selivanov2393dca2014-01-27 15:07:58 -05003095 if render_pos_only_separator:
3096 # There were only positional-only parameters, hence the
3097 # flag was not reset to 'False'
3098 result.append('/')
3099
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003100 rendered = '({})'.format(', '.join(result))
3101
3102 if self.return_annotation is not _empty:
3103 anno = formatannotation(self.return_annotation)
3104 rendered += ' -> {}'.format(anno)
3105
3106 return rendered
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003107
Yury Selivanovda396452014-03-27 12:09:24 -04003108
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03003109def signature(obj, *, follow_wrapped=True, globalns=None, localns=None):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04003110 """Get a signature object for the passed callable."""
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03003111 return Signature.from_callable(obj, follow_wrapped=follow_wrapped,
3112 globalns=globalns, localns=localns)
Yury Selivanovda396452014-03-27 12:09:24 -04003113
3114
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003115def _main():
3116 """ Logic for inspecting an object given at command line """
3117 import argparse
3118 import importlib
3119
3120 parser = argparse.ArgumentParser()
3121 parser.add_argument(
3122 'object',
3123 help="The object to be analysed. "
3124 "It supports the 'module:qualname' syntax")
3125 parser.add_argument(
3126 '-d', '--details', action='store_true',
3127 help='Display info about the module rather than its source code')
3128
3129 args = parser.parse_args()
3130
3131 target = args.object
3132 mod_name, has_attrs, attrs = target.partition(":")
3133 try:
3134 obj = module = importlib.import_module(mod_name)
3135 except Exception as exc:
3136 msg = "Failed to import {} ({}: {})".format(mod_name,
3137 type(exc).__name__,
3138 exc)
3139 print(msg, file=sys.stderr)
Alan Yeee3c59a72019-09-09 07:15:43 -07003140 sys.exit(2)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003141
3142 if has_attrs:
3143 parts = attrs.split(".")
3144 obj = module
3145 for part in parts:
3146 obj = getattr(obj, part)
3147
3148 if module.__name__ in sys.builtin_module_names:
3149 print("Can't get info for builtin modules.", file=sys.stderr)
Alan Yeee3c59a72019-09-09 07:15:43 -07003150 sys.exit(1)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003151
3152 if args.details:
3153 print('Target: {}'.format(target))
3154 print('Origin: {}'.format(getsourcefile(module)))
3155 print('Cached: {}'.format(module.__cached__))
3156 if obj is module:
3157 print('Loader: {}'.format(repr(module.__loader__)))
3158 if hasattr(module, '__path__'):
3159 print('Submodule search path: {}'.format(module.__path__))
3160 else:
3161 try:
3162 __, lineno = findsource(obj)
3163 except Exception:
3164 pass
3165 else:
3166 print('Line: {}'.format(lineno))
3167
3168 print('\n')
3169 else:
3170 print(getsource(obj))
3171
3172
3173if __name__ == "__main__":
3174 _main()