blob: 1f2cdebd899f80774e2a7a63462bb5cba0e456ef [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
Batuhan Taskaya044a1042020-10-06 23:03:02 +030048import typing
Brett Cannon2b88fcf2012-06-02 22:28:42 -040049import warnings
Larry Hastings7c7cbfc2012-06-22 15:19:35 -070050import functools
Nick Coghlan2f92e542012-06-23 19:39:55 +100051import builtins
Raymond Hettingera1a992c2005-03-11 06:46:45 +000052from operator import attrgetter
Inada Naoki21105512020-03-02 18:54:49 +090053from collections import namedtuple, OrderedDict
Nick Coghlan09c81232010-08-17 10:18:16 +000054
55# Create constants for the compiler flags in Include/code.h
Antoine Pitroua8723a02015-04-15 00:41:29 +020056# We try to get them from dis to avoid duplication
57mod_dict = globals()
58for k, v in dis.COMPILER_FLAG_NAMES.items():
59 mod_dict["CO_" + v] = k
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000060
Christian Heimesbe5b30b2008-03-03 19:18:51 +000061# See Include/object.h
62TPFLAGS_IS_ABSTRACT = 1 << 20
63
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000064# ----------------------------------------------------------- type-checking
65def ismodule(object):
66 """Return true if the object is a module.
67
68 Module objects provide these attributes:
Barry Warsaw28a691b2010-04-17 00:19:56 +000069 __cached__ pathname to byte compiled file
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000070 __doc__ documentation string
71 __file__ filename (missing for built-in modules)"""
Tim Peters28bc59f2001-09-16 08:40:16 +000072 return isinstance(object, types.ModuleType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000073
74def isclass(object):
75 """Return true if the object is a class.
76
77 Class objects provide these attributes:
78 __doc__ documentation string
79 __module__ name of module in which this class was defined"""
Benjamin Petersonc4656002009-01-17 22:41:18 +000080 return isinstance(object, type)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000081
82def ismethod(object):
83 """Return true if the object is an instance method.
84
85 Instance method objects provide these attributes:
86 __doc__ documentation string
87 __name__ name with which this method was defined
Christian Heimesff737952007-11-27 10:40:20 +000088 __func__ function object containing implementation of method
89 __self__ instance to which this method is bound"""
Tim Peters28bc59f2001-09-16 08:40:16 +000090 return isinstance(object, types.MethodType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000091
Tim Peters536d2262001-09-20 05:13:38 +000092def ismethoddescriptor(object):
Tim Petersf1d90b92001-09-20 05:47:55 +000093 """Return true if the object is a method descriptor.
94
95 But not if ismethod() or isclass() or isfunction() are true.
Tim Peters536d2262001-09-20 05:13:38 +000096
97 This is new in Python 2.2, and, for example, is true of int.__add__.
98 An object passing this test has a __get__ attribute but not a __set__
99 attribute, but beyond that the set of attributes varies. __name__ is
100 usually sensible, and __doc__ often is.
101
Tim Petersf1d90b92001-09-20 05:47:55 +0000102 Methods implemented via descriptors that also pass one of the other
103 tests return false from the ismethoddescriptor() test, simply because
104 the other tests promise more -- you can, e.g., count on having the
Christian Heimesff737952007-11-27 10:40:20 +0000105 __func__ attribute (etc) when an object passes ismethod()."""
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100106 if isclass(object) or ismethod(object) or isfunction(object):
107 # mutual exclusion
108 return False
109 tp = type(object)
110 return hasattr(tp, "__get__") and not hasattr(tp, "__set__")
Tim Peters536d2262001-09-20 05:13:38 +0000111
Martin v. Löwise59e2ba2003-05-03 09:09:02 +0000112def isdatadescriptor(object):
113 """Return true if the object is a data descriptor.
114
Aaron Hall, MBA4054b172018-05-20 19:46:42 -0400115 Data descriptors have a __set__ or a __delete__ attribute. Examples are
Martin v. Löwise59e2ba2003-05-03 09:09:02 +0000116 properties (defined in Python) and getsets and members (defined in C).
117 Typically, data descriptors will also have __name__ and __doc__ attributes
118 (properties, getsets, and members have both of these attributes), but this
119 is not guaranteed."""
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100120 if isclass(object) or ismethod(object) or isfunction(object):
121 # mutual exclusion
122 return False
123 tp = type(object)
Aaron Hall, MBA4054b172018-05-20 19:46:42 -0400124 return hasattr(tp, "__set__") or hasattr(tp, "__delete__")
Martin v. Löwise59e2ba2003-05-03 09:09:02 +0000125
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000126if hasattr(types, 'MemberDescriptorType'):
127 # CPython and equivalent
128 def ismemberdescriptor(object):
129 """Return true if the object is a member descriptor.
130
131 Member descriptors are specialized descriptors defined in extension
132 modules."""
133 return isinstance(object, types.MemberDescriptorType)
134else:
135 # Other implementations
136 def ismemberdescriptor(object):
137 """Return true if the object is a member descriptor.
138
139 Member descriptors are specialized descriptors defined in extension
140 modules."""
141 return False
142
143if hasattr(types, 'GetSetDescriptorType'):
144 # CPython and equivalent
145 def isgetsetdescriptor(object):
146 """Return true if the object is a getset descriptor.
147
148 getset descriptors are specialized descriptors defined in extension
149 modules."""
150 return isinstance(object, types.GetSetDescriptorType)
151else:
152 # Other implementations
153 def isgetsetdescriptor(object):
154 """Return true if the object is a getset descriptor.
155
156 getset descriptors are specialized descriptors defined in extension
157 modules."""
158 return False
159
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000160def isfunction(object):
161 """Return true if the object is a user-defined function.
162
163 Function objects provide these attributes:
164 __doc__ documentation string
165 __name__ name with which this function was defined
Neal Norwitz221085d2007-02-25 20:55:47 +0000166 __code__ code object containing compiled function bytecode
167 __defaults__ tuple of any default values for arguments
168 __globals__ global namespace in which this function was defined
169 __annotations__ dict of parameter annotations
170 __kwdefaults__ dict of keyword only parameters with defaults"""
Tim Peters28bc59f2001-09-16 08:40:16 +0000171 return isinstance(object, types.FunctionType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000172
Jeroen Demeyerfcef60f2019-04-02 16:03:42 +0200173def _has_code_flag(f, flag):
174 """Return true if ``f`` is a function (or a method or functools.partial
175 wrapper wrapping a function) whose code object has the given ``flag``
176 set in its flags."""
177 while ismethod(f):
178 f = f.__func__
179 f = functools._unwrap_partial(f)
180 if not isfunction(f):
181 return False
182 return bool(f.__code__.co_flags & flag)
183
Pablo Galindo7cd25432018-10-26 12:19:14 +0100184def isgeneratorfunction(obj):
Christian Heimes7131fd92008-02-19 14:21:46 +0000185 """Return true if the object is a user-defined generator function.
186
Martin Panter0f0eac42016-09-07 11:04:41 +0000187 Generator function objects provide the same attributes as functions.
188 See help(isfunction) for a list of attributes."""
Jeroen Demeyerfcef60f2019-04-02 16:03:42 +0200189 return _has_code_flag(obj, CO_GENERATOR)
Yury Selivanov75445082015-05-11 22:57:16 -0400190
Pablo Galindo7cd25432018-10-26 12:19:14 +0100191def iscoroutinefunction(obj):
Yury Selivanov75445082015-05-11 22:57:16 -0400192 """Return true if the object is a coroutine function.
193
Yury Selivanov4778e132016-11-08 12:23:09 -0500194 Coroutine functions are defined with "async def" syntax.
Yury Selivanov75445082015-05-11 22:57:16 -0400195 """
Jeroen Demeyerfcef60f2019-04-02 16:03:42 +0200196 return _has_code_flag(obj, CO_COROUTINE)
Yury Selivanov75445082015-05-11 22:57:16 -0400197
Pablo Galindo7cd25432018-10-26 12:19:14 +0100198def isasyncgenfunction(obj):
Yury Selivanov4778e132016-11-08 12:23:09 -0500199 """Return true if the object is an asynchronous generator function.
200
201 Asynchronous generator functions are defined with "async def"
202 syntax and have "yield" expressions in their body.
203 """
Jeroen Demeyerfcef60f2019-04-02 16:03:42 +0200204 return _has_code_flag(obj, CO_ASYNC_GENERATOR)
Yury Selivanoveb636452016-09-08 22:01:51 -0700205
206def isasyncgen(object):
Yury Selivanov4778e132016-11-08 12:23:09 -0500207 """Return true if the object is an asynchronous generator."""
Yury Selivanoveb636452016-09-08 22:01:51 -0700208 return isinstance(object, types.AsyncGeneratorType)
209
Christian Heimes7131fd92008-02-19 14:21:46 +0000210def isgenerator(object):
211 """Return true if the object is a generator.
212
213 Generator objects provide these attributes:
Ezio Melotti30b9d5d2013-08-17 15:50:46 +0300214 __iter__ defined to support iteration over container
Christian Heimes7131fd92008-02-19 14:21:46 +0000215 close raises a new GeneratorExit exception inside the
216 generator to terminate the iteration
217 gi_code code object
218 gi_frame frame object or possibly None once the generator has
219 been exhausted
220 gi_running set to 1 when generator is executing, 0 otherwise
221 next return the next item from the container
222 send resumes the generator and "sends" a value that becomes
223 the result of the current yield-expression
224 throw used to raise an exception inside the generator"""
Yury Selivanov5376ba92015-06-22 12:19:30 -0400225 return isinstance(object, types.GeneratorType)
Yury Selivanov75445082015-05-11 22:57:16 -0400226
227def iscoroutine(object):
228 """Return true if the object is a coroutine."""
Yury Selivanov5376ba92015-06-22 12:19:30 -0400229 return isinstance(object, types.CoroutineType)
Christian Heimes7131fd92008-02-19 14:21:46 +0000230
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400231def isawaitable(object):
Yury Selivanovc0215df2016-11-08 19:57:44 -0500232 """Return true if object can be passed to an ``await`` expression."""
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400233 return (isinstance(object, types.CoroutineType) or
234 isinstance(object, types.GeneratorType) and
Yury Selivanovc0215df2016-11-08 19:57:44 -0500235 bool(object.gi_code.co_flags & CO_ITERABLE_COROUTINE) or
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400236 isinstance(object, collections.abc.Awaitable))
237
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000238def istraceback(object):
239 """Return true if the object is a traceback.
240
241 Traceback objects provide these attributes:
242 tb_frame frame object at this level
243 tb_lasti index of last attempted instruction in bytecode
244 tb_lineno current line number in Python source code
245 tb_next next inner traceback object (called by this level)"""
Tim Peters28bc59f2001-09-16 08:40:16 +0000246 return isinstance(object, types.TracebackType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000247
248def isframe(object):
249 """Return true if the object is a frame object.
250
251 Frame objects provide these attributes:
252 f_back next outer frame object (this frame's caller)
253 f_builtins built-in namespace seen by this frame
254 f_code code object being executed in this frame
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000255 f_globals global namespace seen by this frame
256 f_lasti index of last attempted instruction in bytecode
257 f_lineno current line number in Python source code
258 f_locals local namespace seen by this frame
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000259 f_trace tracing function for this frame, or None"""
Tim Peters28bc59f2001-09-16 08:40:16 +0000260 return isinstance(object, types.FrameType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000261
262def iscode(object):
263 """Return true if the object is a code object.
264
265 Code objects provide these attributes:
Xiang Zhanga6902e62017-04-13 10:38:28 +0800266 co_argcount number of arguments (not including *, ** args
267 or keyword only arguments)
268 co_code string of raw compiled bytecode
269 co_cellvars tuple of names of cell variables
270 co_consts tuple of constants used in the bytecode
271 co_filename name of file in which this code object was created
272 co_firstlineno number of first line in Python source code
273 co_flags bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg
274 | 16=nested | 32=generator | 64=nofree | 128=coroutine
275 | 256=iterable_coroutine | 512=async_generator
276 co_freevars tuple of names of free variables
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100277 co_posonlyargcount number of positional only arguments
Xiang Zhanga6902e62017-04-13 10:38:28 +0800278 co_kwonlyargcount number of keyword only arguments (not including ** arg)
279 co_lnotab encoded mapping of line numbers to bytecode indices
280 co_name name with which this code object was defined
281 co_names tuple of names of local variables
282 co_nlocals number of local variables
283 co_stacksize virtual machine stack space required
284 co_varnames tuple of names of arguments and local variables"""
Tim Peters28bc59f2001-09-16 08:40:16 +0000285 return isinstance(object, types.CodeType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000286
287def isbuiltin(object):
288 """Return true if the object is a built-in function or method.
289
290 Built-in functions and methods provide these attributes:
291 __doc__ documentation string
292 __name__ original name of this function or method
293 __self__ instance to which a method is bound, or None"""
Tim Peters28bc59f2001-09-16 08:40:16 +0000294 return isinstance(object, types.BuiltinFunctionType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000295
296def isroutine(object):
297 """Return true if the object is any kind of function or method."""
Tim Peters536d2262001-09-20 05:13:38 +0000298 return (isbuiltin(object)
299 or isfunction(object)
300 or ismethod(object)
301 or ismethoddescriptor(object))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000302
Christian Heimesbe5b30b2008-03-03 19:18:51 +0000303def isabstract(object):
304 """Return true if the object is an abstract base class (ABC)."""
Natefcfe80e2017-04-24 10:06:15 -0700305 if not isinstance(object, type):
306 return False
307 if object.__flags__ & TPFLAGS_IS_ABSTRACT:
308 return True
309 if not issubclass(type(object), abc.ABCMeta):
310 return False
311 if hasattr(object, '__abstractmethods__'):
312 # It looks like ABCMeta.__new__ has finished running;
313 # TPFLAGS_IS_ABSTRACT should have been accurate.
314 return False
315 # It looks like ABCMeta.__new__ has not finished running yet; we're
316 # probably in __init_subclass__. We'll look for abstractmethods manually.
317 for name, value in object.__dict__.items():
318 if getattr(value, "__isabstractmethod__", False):
319 return True
320 for base in object.__bases__:
321 for name in getattr(base, "__abstractmethods__", ()):
322 value = getattr(object, name, None)
323 if getattr(value, "__isabstractmethod__", False):
324 return True
325 return False
Christian Heimesbe5b30b2008-03-03 19:18:51 +0000326
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000327def getmembers(object, predicate=None):
328 """Return all members of an object as (name, value) pairs sorted by name.
329 Optionally, only return members that satisfy a given predicate."""
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100330 if isclass(object):
331 mro = (object,) + getmro(object)
332 else:
333 mro = ()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000334 results = []
Ethan Furmane03ea372013-09-25 07:14:41 -0700335 processed = set()
336 names = dir(object)
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700337 # :dd any DynamicClassAttributes to the list of names if object is a class;
Ethan Furmane03ea372013-09-25 07:14:41 -0700338 # this may result in duplicate entries if, for example, a virtual
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700339 # attribute with the same name as a DynamicClassAttribute exists
Ethan Furmane03ea372013-09-25 07:14:41 -0700340 try:
341 for base in object.__bases__:
342 for k, v in base.__dict__.items():
343 if isinstance(v, types.DynamicClassAttribute):
344 names.append(k)
345 except AttributeError:
346 pass
347 for key in names:
Ethan Furman63c141c2013-10-18 00:27:39 -0700348 # First try to get the value via getattr. Some descriptors don't
349 # like calling their __get__ (see bug #1785), so fall back to
350 # looking in the __dict__.
351 try:
352 value = getattr(object, key)
353 # handle the duplicate key
354 if key in processed:
355 raise AttributeError
356 except AttributeError:
357 for base in mro:
358 if key in base.__dict__:
359 value = base.__dict__[key]
360 break
361 else:
362 # could be a (currently) missing slot member, or a buggy
363 # __dir__; discard and move on
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100364 continue
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000365 if not predicate or predicate(value):
366 results.append((key, value))
Ethan Furmane03ea372013-09-25 07:14:41 -0700367 processed.add(key)
368 results.sort(key=lambda pair: pair[0])
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000369 return results
370
Christian Heimes25bb7832008-01-11 16:17:00 +0000371Attribute = namedtuple('Attribute', 'name kind defining_class object')
372
Tim Peters13b49d32001-09-23 02:00:29 +0000373def classify_class_attrs(cls):
374 """Return list of attribute-descriptor tuples.
375
376 For each name in dir(cls), the return list contains a 4-tuple
377 with these elements:
378
379 0. The name (a string).
380
381 1. The kind of attribute this is, one of these strings:
382 'class method' created via classmethod()
383 'static method' created via staticmethod()
384 'property' created via property()
Ethan Furmane03ea372013-09-25 07:14:41 -0700385 'method' any other flavor of method or descriptor
Tim Peters13b49d32001-09-23 02:00:29 +0000386 'data' not a method
387
388 2. The class which defined this attribute (a class).
389
Ethan Furmane03ea372013-09-25 07:14:41 -0700390 3. The object as obtained by calling getattr; if this fails, or if the
391 resulting object does not live anywhere in the class' mro (including
392 metaclasses) then the object is looked up in the defining class's
393 dict (found by walking the mro).
Ethan Furman668dede2013-09-14 18:53:26 -0700394
395 If one of the items in dir(cls) is stored in the metaclass it will now
396 be discovered and not have None be listed as the class in which it was
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700397 defined. Any items whose home class cannot be discovered are skipped.
Tim Peters13b49d32001-09-23 02:00:29 +0000398 """
399
400 mro = getmro(cls)
Ethan Furman668dede2013-09-14 18:53:26 -0700401 metamro = getmro(type(cls)) # for attributes stored in the metaclass
Jon Dufresne39726282017-05-18 07:35:54 -0700402 metamro = tuple(cls for cls in metamro if cls not in (type, object))
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700403 class_bases = (cls,) + mro
404 all_bases = class_bases + metamro
Tim Peters13b49d32001-09-23 02:00:29 +0000405 names = dir(cls)
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700406 # :dd any DynamicClassAttributes to the list of names;
Ethan Furmane03ea372013-09-25 07:14:41 -0700407 # this may result in duplicate entries if, for example, a virtual
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700408 # attribute with the same name as a DynamicClassAttribute exists.
Ethan Furman63c141c2013-10-18 00:27:39 -0700409 for base in mro:
Ethan Furmane03ea372013-09-25 07:14:41 -0700410 for k, v in base.__dict__.items():
Ethan Furmanc314e602021-01-12 23:47:57 -0800411 if isinstance(v, types.DynamicClassAttribute) and v.fget is not None:
Ethan Furmane03ea372013-09-25 07:14:41 -0700412 names.append(k)
Tim Peters13b49d32001-09-23 02:00:29 +0000413 result = []
Ethan Furmane03ea372013-09-25 07:14:41 -0700414 processed = set()
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700415
Tim Peters13b49d32001-09-23 02:00:29 +0000416 for name in names:
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100417 # Get the object associated with the name, and where it was defined.
Ethan Furmane03ea372013-09-25 07:14:41 -0700418 # Normal objects will be looked up with both getattr and directly in
419 # its class' dict (in case getattr fails [bug #1785], and also to look
420 # for a docstring).
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700421 # For DynamicClassAttributes on the second pass we only look in the
Ethan Furmane03ea372013-09-25 07:14:41 -0700422 # class's dict.
423 #
Tim Peters13b49d32001-09-23 02:00:29 +0000424 # Getting an obj from the __dict__ sometimes reveals more than
425 # using getattr. Static and class methods are dramatic examples.
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100426 homecls = None
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700427 get_obj = None
428 dict_obj = None
Ethan Furmane03ea372013-09-25 07:14:41 -0700429 if name not in processed:
430 try:
Ethan Furmana8b07072013-10-18 01:22:08 -0700431 if name == '__dict__':
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700432 raise Exception("__dict__ is special, don't want the proxy")
Ethan Furmane03ea372013-09-25 07:14:41 -0700433 get_obj = getattr(cls, name)
434 except Exception as exc:
435 pass
436 else:
Ethan Furmane03ea372013-09-25 07:14:41 -0700437 homecls = getattr(get_obj, "__objclass__", homecls)
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700438 if homecls not in class_bases:
Ethan Furmane03ea372013-09-25 07:14:41 -0700439 # if the resulting object does not live somewhere in the
Ethan Furman63c141c2013-10-18 00:27:39 -0700440 # mro, drop it and search the mro manually
Ethan Furmane03ea372013-09-25 07:14:41 -0700441 homecls = None
Ethan Furman63c141c2013-10-18 00:27:39 -0700442 last_cls = None
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700443 # first look in the classes
444 for srch_cls in class_bases:
Ethan Furman63c141c2013-10-18 00:27:39 -0700445 srch_obj = getattr(srch_cls, name, None)
Yury Selivanovbf341fb2015-05-21 15:41:57 -0400446 if srch_obj is get_obj:
Ethan Furman63c141c2013-10-18 00:27:39 -0700447 last_cls = srch_cls
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700448 # then check the metaclasses
449 for srch_cls in metamro:
450 try:
451 srch_obj = srch_cls.__getattr__(cls, name)
452 except AttributeError:
453 continue
Yury Selivanovbf341fb2015-05-21 15:41:57 -0400454 if srch_obj is get_obj:
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700455 last_cls = srch_cls
Ethan Furman63c141c2013-10-18 00:27:39 -0700456 if last_cls is not None:
457 homecls = last_cls
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700458 for base in all_bases:
Ethan Furmane03ea372013-09-25 07:14:41 -0700459 if name in base.__dict__:
460 dict_obj = base.__dict__[name]
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700461 if homecls not in metamro:
462 homecls = base
Ethan Furmane03ea372013-09-25 07:14:41 -0700463 break
Ethan Furman63c141c2013-10-18 00:27:39 -0700464 if homecls is None:
465 # unable to locate the attribute anywhere, most likely due to
466 # buggy custom __dir__; discard and move on
467 continue
Yury Selivanovbf341fb2015-05-21 15:41:57 -0400468 obj = get_obj if get_obj is not None else dict_obj
Ethan Furmane03ea372013-09-25 07:14:41 -0700469 # Classify the object or its descriptor.
Serhiy Storchaka3327a2d2017-12-15 14:13:41 +0200470 if isinstance(dict_obj, (staticmethod, types.BuiltinMethodType)):
Tim Peters13b49d32001-09-23 02:00:29 +0000471 kind = "static method"
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700472 obj = dict_obj
Serhiy Storchaka3327a2d2017-12-15 14:13:41 +0200473 elif isinstance(dict_obj, (classmethod, types.ClassMethodDescriptorType)):
Tim Peters13b49d32001-09-23 02:00:29 +0000474 kind = "class method"
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700475 obj = dict_obj
476 elif isinstance(dict_obj, property):
Tim Peters13b49d32001-09-23 02:00:29 +0000477 kind = "property"
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700478 obj = dict_obj
Yury Selivanov0860a0b2014-01-31 14:28:44 -0500479 elif isroutine(obj):
Tim Peters13b49d32001-09-23 02:00:29 +0000480 kind = "method"
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100481 else:
Ethan Furmane03ea372013-09-25 07:14:41 -0700482 kind = "data"
Christian Heimes25bb7832008-01-11 16:17:00 +0000483 result.append(Attribute(name, kind, homecls, obj))
Ethan Furmane03ea372013-09-25 07:14:41 -0700484 processed.add(name)
Tim Peters13b49d32001-09-23 02:00:29 +0000485 return result
486
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000487# ----------------------------------------------------------- class helpers
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000488
489def getmro(cls):
490 "Return tuple of base classes (including cls) in method resolution order."
Benjamin Petersonb82c8e52010-11-04 00:38:49 +0000491 return cls.__mro__
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000492
Nick Coghlane8c45d62013-07-28 20:00:01 +1000493# -------------------------------------------------------- function helpers
494
495def unwrap(func, *, stop=None):
496 """Get the object wrapped by *func*.
497
498 Follows the chain of :attr:`__wrapped__` attributes returning the last
499 object in the chain.
500
501 *stop* is an optional callback accepting an object in the wrapper chain
502 as its sole argument that allows the unwrapping to be terminated early if
503 the callback returns a true value. If the callback never returns a true
504 value, the last object in the chain is returned as usual. For example,
505 :func:`signature` uses this to stop unwrapping if any object in the
506 chain has a ``__signature__`` attribute defined.
507
508 :exc:`ValueError` is raised if a cycle is encountered.
509
510 """
511 if stop is None:
512 def _is_wrapper(f):
513 return hasattr(f, '__wrapped__')
514 else:
515 def _is_wrapper(f):
516 return hasattr(f, '__wrapped__') and not stop(f)
517 f = func # remember the original func for error reporting
Thomas Kluyverf9169ce2017-05-23 04:27:52 +0100518 # Memoise by id to tolerate non-hashable objects, but store objects to
519 # ensure they aren't destroyed, which would allow their IDs to be reused.
520 memo = {id(f): f}
521 recursion_limit = sys.getrecursionlimit()
Nick Coghlane8c45d62013-07-28 20:00:01 +1000522 while _is_wrapper(func):
523 func = func.__wrapped__
524 id_func = id(func)
Thomas Kluyverf9169ce2017-05-23 04:27:52 +0100525 if (id_func in memo) or (len(memo) >= recursion_limit):
Nick Coghlane8c45d62013-07-28 20:00:01 +1000526 raise ValueError('wrapper loop when unwrapping {!r}'.format(f))
Thomas Kluyverf9169ce2017-05-23 04:27:52 +0100527 memo[id_func] = func
Nick Coghlane8c45d62013-07-28 20:00:01 +1000528 return func
529
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000530# -------------------------------------------------- source code extraction
531def indentsize(line):
532 """Return the indent size, in spaces, at the start of a line of text."""
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000533 expline = line.expandtabs()
534 return len(expline) - len(expline.lstrip())
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000535
Serhiy Storchaka5cf2b722015-04-03 22:38:53 +0300536def _findclass(func):
537 cls = sys.modules.get(func.__module__)
538 if cls is None:
539 return None
540 for name in func.__qualname__.split('.')[:-1]:
541 cls = getattr(cls, name)
542 if not isclass(cls):
543 return None
544 return cls
545
546def _finddoc(obj):
Serhiy Storchaka08b47c32020-05-18 20:25:07 +0300547 if isclass(obj):
548 for base in obj.__mro__:
549 if base is not object:
550 try:
551 doc = base.__doc__
552 except AttributeError:
553 continue
554 if doc is not None:
555 return doc
556 return None
557
Serhiy Storchaka5cf2b722015-04-03 22:38:53 +0300558 if ismethod(obj):
559 name = obj.__func__.__name__
560 self = obj.__self__
561 if (isclass(self) and
562 getattr(getattr(self, name, None), '__func__') is obj.__func__):
563 # classmethod
564 cls = self
565 else:
566 cls = self.__class__
567 elif isfunction(obj):
568 name = obj.__name__
569 cls = _findclass(obj)
570 if cls is None or getattr(cls, name) is not obj:
571 return None
572 elif isbuiltin(obj):
573 name = obj.__name__
574 self = obj.__self__
575 if (isclass(self) and
576 self.__qualname__ + '.' + name == obj.__qualname__):
577 # classmethod
578 cls = self
579 else:
580 cls = self.__class__
Serhiy Storchakaac4bdcc2015-10-29 08:15:50 +0200581 # Should be tested before isdatadescriptor().
582 elif isinstance(obj, property):
583 func = obj.fget
584 name = func.__name__
585 cls = _findclass(func)
586 if cls is None or getattr(cls, name) is not obj:
587 return None
Serhiy Storchaka5cf2b722015-04-03 22:38:53 +0300588 elif ismethoddescriptor(obj) or isdatadescriptor(obj):
589 name = obj.__name__
590 cls = obj.__objclass__
591 if getattr(cls, name) is not obj:
592 return None
Raymond Hettingerd1e768a2019-03-25 13:01:13 -0700593 if ismemberdescriptor(obj):
594 slots = getattr(cls, '__slots__', None)
595 if isinstance(slots, dict) and name in slots:
596 return slots[name]
Serhiy Storchaka5cf2b722015-04-03 22:38:53 +0300597 else:
598 return None
Serhiy Storchaka5cf2b722015-04-03 22:38:53 +0300599 for base in cls.__mro__:
600 try:
Serhiy Storchaka08b47c32020-05-18 20:25:07 +0300601 doc = getattr(base, name).__doc__
Serhiy Storchaka5cf2b722015-04-03 22:38:53 +0300602 except AttributeError:
603 continue
604 if doc is not None:
605 return doc
606 return None
607
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000608def getdoc(object):
609 """Get the documentation string for an object.
610
611 All tabs are expanded to spaces. To clean up docstrings that are
612 indented to line up with blocks of code, any whitespace than can be
613 uniformly removed from the second line onwards is removed."""
Serhiy Storchaka08b47c32020-05-18 20:25:07 +0300614 try:
615 doc = object.__doc__
616 except AttributeError:
617 return None
Serhiy Storchaka5cf2b722015-04-03 22:38:53 +0300618 if doc is None:
619 try:
620 doc = _finddoc(object)
621 except (AttributeError, TypeError):
622 return None
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000623 if not isinstance(doc, str):
Tim Peters24008312002-03-17 18:56:20 +0000624 return None
Georg Brandl0c77a822008-06-10 16:37:50 +0000625 return cleandoc(doc)
626
627def cleandoc(doc):
628 """Clean up indentation from docstrings.
629
630 Any whitespace that can be uniformly removed from the second line
631 onwards is removed."""
Tim Peters24008312002-03-17 18:56:20 +0000632 try:
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000633 lines = doc.expandtabs().split('\n')
Tim Peters24008312002-03-17 18:56:20 +0000634 except UnicodeError:
635 return None
636 else:
Ka-Ping Yeea59ef7b2002-11-30 03:53:15 +0000637 # Find minimum indentation of any non-blank lines after first line.
Christian Heimesa37d4c62007-12-04 23:02:19 +0000638 margin = sys.maxsize
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000639 for line in lines[1:]:
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000640 content = len(line.lstrip())
Ka-Ping Yeea59ef7b2002-11-30 03:53:15 +0000641 if content:
642 indent = len(line) - content
643 margin = min(margin, indent)
644 # Remove indentation.
645 if lines:
646 lines[0] = lines[0].lstrip()
Christian Heimesa37d4c62007-12-04 23:02:19 +0000647 if margin < sys.maxsize:
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000648 for i in range(1, len(lines)): lines[i] = lines[i][margin:]
Ka-Ping Yeea59ef7b2002-11-30 03:53:15 +0000649 # Remove any trailing or leading blank lines.
650 while lines and not lines[-1]:
651 lines.pop()
652 while lines and not lines[0]:
653 lines.pop(0)
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000654 return '\n'.join(lines)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000655
656def getfile(object):
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000657 """Work out which source or compiled file an object was defined in."""
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000658 if ismodule(object):
Jason R. Coombsb9650a02018-03-05 18:29:08 -0500659 if getattr(object, '__file__', None):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000660 return object.__file__
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000661 raise TypeError('{!r} is a built-in module'.format(object))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000662 if isclass(object):
Yury Selivanov2eed8b72014-01-27 13:24:56 -0500663 if hasattr(object, '__module__'):
Philipp Ad407d2a2019-06-08 14:05:46 +0200664 module = sys.modules.get(object.__module__)
665 if getattr(module, '__file__', None):
666 return module.__file__
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000667 raise TypeError('{!r} is a built-in class'.format(object))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000668 if ismethod(object):
Christian Heimesff737952007-11-27 10:40:20 +0000669 object = object.__func__
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000670 if isfunction(object):
Neal Norwitz221085d2007-02-25 20:55:47 +0000671 object = object.__code__
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000672 if istraceback(object):
673 object = object.tb_frame
674 if isframe(object):
675 object = object.f_code
676 if iscode(object):
677 return object.co_filename
Thomas Kluyvere968bc732017-10-24 13:42:36 +0100678 raise TypeError('module, class, method, function, traceback, frame, or '
679 'code object was expected, got {}'.format(
680 type(object).__name__))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000681
Ka-Ping Yee4d6fc7f2001-04-10 11:43:00 +0000682def getmodulename(path):
683 """Return the module name for a given file, or None."""
Nick Coghlan76e07702012-07-18 23:14:57 +1000684 fname = os.path.basename(path)
685 # Check for paths that look like an actual module file
686 suffixes = [(-len(suffix), suffix)
687 for suffix in importlib.machinery.all_suffixes()]
688 suffixes.sort() # try longest suffixes first, in case they overlap
689 for neglen, suffix in suffixes:
690 if fname.endswith(suffix):
691 return fname[:neglen]
692 return None
Ka-Ping Yee4d6fc7f2001-04-10 11:43:00 +0000693
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000694def getsourcefile(object):
R. David Murraya1b37402010-06-17 02:04:29 +0000695 """Return the filename that can be used to locate an object's source.
696 Return None if no way can be identified to get the source.
697 """
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000698 filename = getfile(object)
Brett Cannoncb66eb02012-05-11 12:58:42 -0400699 all_bytecode_suffixes = importlib.machinery.DEBUG_BYTECODE_SUFFIXES[:]
700 all_bytecode_suffixes += importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES[:]
701 if any(filename.endswith(s) for s in all_bytecode_suffixes):
702 filename = (os.path.splitext(filename)[0] +
703 importlib.machinery.SOURCE_SUFFIXES[0])
704 elif any(filename.endswith(s) for s in
705 importlib.machinery.EXTENSION_SUFFIXES):
706 return None
Thomas Wouters477c8d52006-05-27 19:21:47 +0000707 if os.path.exists(filename):
708 return filename
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000709 # only return a non-existent filename if the module has a PEP 302 loader
Brett Cannon825ac382020-11-06 18:45:56 -0800710 module = getmodule(object, filename)
711 if getattr(module, '__loader__', None) is not None:
712 return filename
713 elif getattr(getattr(module, "__spec__", None), "loader", None) is not None:
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000714 return filename
R. David Murraya1b37402010-06-17 02:04:29 +0000715 # or it is in the linecache
Brett Cannon825ac382020-11-06 18:45:56 -0800716 elif filename in linecache.cache:
R. David Murraya1b37402010-06-17 02:04:29 +0000717 return filename
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000718
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000719def getabsfile(object, _filename=None):
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000720 """Return an absolute path to the source or compiled file for an object.
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000721
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000722 The idea is for each object to have a unique origin, so this routine
723 normalizes the result as much as possible."""
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000724 if _filename is None:
725 _filename = getsourcefile(object) or getfile(object)
726 return os.path.normcase(os.path.abspath(_filename))
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000727
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000728modulesbyfile = {}
Thomas Wouters89f507f2006-12-13 04:49:30 +0000729_filesbymodname = {}
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000730
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000731def getmodule(object, _filename=None):
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000732 """Return the module an object was defined in, or None if not found."""
Ka-Ping Yee202c99b2001-04-13 09:15:08 +0000733 if ismodule(object):
734 return object
Johannes Gijsbers93245262004-09-11 15:53:22 +0000735 if hasattr(object, '__module__'):
Ka-Ping Yee8b58b842001-03-01 13:56:16 +0000736 return sys.modules.get(object.__module__)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000737 # Try the filename to modulename cache
738 if _filename is not None and _filename in modulesbyfile:
739 return sys.modules.get(modulesbyfile[_filename])
740 # Try the cache again with the absolute file name
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000741 try:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000742 file = getabsfile(object, _filename)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000743 except TypeError:
744 return None
Raymond Hettinger54f02222002-06-01 14:18:47 +0000745 if file in modulesbyfile:
Ka-Ping Yeeb38bbbd2003-03-28 16:29:50 +0000746 return sys.modules.get(modulesbyfile[file])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000747 # Update the filename to module name cache and check yet again
748 # Copy sys.modules in order to cope with changes while iterating
Gregory P. Smith85cf1d52020-03-04 16:45:22 -0800749 for modname, module in sys.modules.copy().items():
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000750 if ismodule(module) and hasattr(module, '__file__'):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000751 f = module.__file__
752 if f == _filesbymodname.get(modname, None):
753 # Have already mapped this module, so skip it
754 continue
755 _filesbymodname[modname] = f
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000756 f = getabsfile(module)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000757 # Always map to the name the module knows itself by
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000758 modulesbyfile[f] = modulesbyfile[
759 os.path.realpath(f)] = module.__name__
Raymond Hettinger54f02222002-06-01 14:18:47 +0000760 if file in modulesbyfile:
Ka-Ping Yeeb38bbbd2003-03-28 16:29:50 +0000761 return sys.modules.get(modulesbyfile[file])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000762 # Check the main module
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000763 main = sys.modules['__main__']
Brett Cannon4a671fe2003-06-15 22:33:28 +0000764 if not hasattr(object, '__name__'):
765 return None
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000766 if hasattr(main, object.__name__):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000767 mainobject = getattr(main, object.__name__)
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000768 if mainobject is object:
769 return main
Thomas Wouters89f507f2006-12-13 04:49:30 +0000770 # Check builtins
Georg Brandl1a3284e2007-12-02 09:40:06 +0000771 builtin = sys.modules['builtins']
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000772 if hasattr(builtin, object.__name__):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000773 builtinobject = getattr(builtin, object.__name__)
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000774 if builtinobject is object:
775 return builtin
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000776
Karthikeyan Singaravelan696136b2020-04-18 21:49:32 +0530777
778class ClassFoundException(Exception):
779 pass
780
781
782class _ClassFinder(ast.NodeVisitor):
783
784 def __init__(self, qualname):
785 self.stack = []
786 self.qualname = qualname
787
788 def visit_FunctionDef(self, node):
789 self.stack.append(node.name)
790 self.stack.append('<locals>')
791 self.generic_visit(node)
792 self.stack.pop()
793 self.stack.pop()
794
795 visit_AsyncFunctionDef = visit_FunctionDef
796
797 def visit_ClassDef(self, node):
798 self.stack.append(node.name)
799 if self.qualname == '.'.join(self.stack):
800 # Return the decorator for the class if present
801 if node.decorator_list:
802 line_number = node.decorator_list[0].lineno
803 else:
804 line_number = node.lineno
805
806 # decrement by one since lines starts with indexing by zero
807 line_number -= 1
808 raise ClassFoundException(line_number)
809 self.generic_visit(node)
810 self.stack.pop()
811
812
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000813def findsource(object):
814 """Return the entire source file and starting line number for an object.
815
816 The argument may be a module, class, method, function, traceback, frame,
817 or code object. The source code is returned as a list of all the lines
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200818 in the file and the line number indexes a line in that list. An OSError
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000819 is raised if the source code cannot be retrieved."""
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500820
Yury Selivanovef1e7502014-12-08 16:05:34 -0500821 file = getsourcefile(object)
822 if file:
823 # Invalidate cache if needed.
824 linecache.checkcache(file)
825 else:
826 file = getfile(object)
827 # Allow filenames in form of "<something>" to pass through.
828 # `doctest` monkeypatches `linecache` module to enable
829 # inspection, so let `linecache.getlines` to be called.
830 if not (file.startswith('<') and file.endswith('>')):
831 raise OSError('source code not available')
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500832
Thomas Wouters89f507f2006-12-13 04:49:30 +0000833 module = getmodule(object, file)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000834 if module:
835 lines = linecache.getlines(file, module.__dict__)
836 else:
837 lines = linecache.getlines(file)
Neil Schemenauerf06f8532002-03-23 23:51:04 +0000838 if not lines:
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200839 raise OSError('could not get source code')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000840
841 if ismodule(object):
842 return lines, 0
843
844 if isclass(object):
Karthikeyan Singaravelan696136b2020-04-18 21:49:32 +0530845 qualname = object.__qualname__
846 source = ''.join(lines)
847 tree = ast.parse(source)
848 class_finder = _ClassFinder(qualname)
849 try:
850 class_finder.visit(tree)
851 except ClassFoundException as e:
852 line_number = e.args[0]
853 return lines, line_number
Jeremy Hyltonab919022003-06-27 18:41:20 +0000854 else:
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200855 raise OSError('could not find class definition')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000856
857 if ismethod(object):
Christian Heimesff737952007-11-27 10:40:20 +0000858 object = object.__func__
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000859 if isfunction(object):
Neal Norwitz221085d2007-02-25 20:55:47 +0000860 object = object.__code__
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000861 if istraceback(object):
862 object = object.tb_frame
863 if isframe(object):
864 object = object.f_code
865 if iscode(object):
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000866 if not hasattr(object, 'co_firstlineno'):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200867 raise OSError('could not find function definition')
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000868 lnum = object.co_firstlineno - 1
Yury Selivanove4e811d2015-07-21 19:01:52 +0300869 pat = re.compile(r'^(\s*def\s)|(\s*async\s+def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000870 while lnum > 0:
Irit Katriel2e0760b2020-12-04 21:22:03 +0000871 try:
872 line = lines[lnum]
873 except IndexError:
874 raise OSError('lineno is out of bounds')
875 if pat.match(line):
876 break
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000877 lnum = lnum - 1
878 return lines, lnum
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200879 raise OSError('could not find code object')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000880
881def getcomments(object):
Jeremy Hyltonb4c17c82002-03-28 23:01:56 +0000882 """Get lines of comments immediately preceding an object's source code.
883
884 Returns None when source can't be found.
885 """
886 try:
887 lines, lnum = findsource(object)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200888 except (OSError, TypeError):
Jeremy Hyltonb4c17c82002-03-28 23:01:56 +0000889 return None
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000890
891 if ismodule(object):
892 # Look for a comment block at the top of the file.
893 start = 0
Ka-Ping Yeeb910efe2001-04-12 13:17:17 +0000894 if lines and lines[0][:2] == '#!': start = 1
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000895 while start < len(lines) and lines[start].strip() in ('', '#'):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000896 start = start + 1
Ka-Ping Yeeb910efe2001-04-12 13:17:17 +0000897 if start < len(lines) and lines[start][:1] == '#':
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000898 comments = []
899 end = start
900 while end < len(lines) and lines[end][:1] == '#':
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000901 comments.append(lines[end].expandtabs())
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000902 end = end + 1
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000903 return ''.join(comments)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000904
905 # Look for a preceding block of comments at the same indentation.
906 elif lnum > 0:
907 indent = indentsize(lines[lnum])
908 end = lnum - 1
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000909 if end >= 0 and lines[end].lstrip()[:1] == '#' and \
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000910 indentsize(lines[end]) == indent:
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000911 comments = [lines[end].expandtabs().lstrip()]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000912 if end > 0:
913 end = end - 1
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000914 comment = lines[end].expandtabs().lstrip()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000915 while comment[:1] == '#' and indentsize(lines[end]) == indent:
916 comments[:0] = [comment]
917 end = end - 1
918 if end < 0: break
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000919 comment = lines[end].expandtabs().lstrip()
920 while comments and comments[0].strip() == '#':
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000921 comments[:1] = []
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000922 while comments and comments[-1].strip() == '#':
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000923 comments[-1:] = []
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000924 return ''.join(comments)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000925
Tim Peters4efb6e92001-06-29 23:51:08 +0000926class EndOfBlock(Exception): pass
927
928class BlockFinder:
929 """Provide a tokeneater() method to detect the end of a code block."""
930 def __init__(self):
931 self.indent = 0
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000932 self.islambda = False
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000933 self.started = False
934 self.passline = False
Meador Inge5b718d72015-07-23 22:49:37 -0500935 self.indecorator = False
936 self.decoratorhasargs = False
Armin Rigodd5c0232005-09-25 11:45:45 +0000937 self.last = 1
Irit Katriel6e1eec72020-12-04 16:45:38 +0000938 self.body_col0 = None
Tim Peters4efb6e92001-06-29 23:51:08 +0000939
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000940 def tokeneater(self, type, token, srowcol, erowcol, line):
Meador Inge5b718d72015-07-23 22:49:37 -0500941 if not self.started and not self.indecorator:
942 # skip any decorators
943 if token == "@":
944 self.indecorator = True
Armin Rigodd5c0232005-09-25 11:45:45 +0000945 # look for the first "def", "class" or "lambda"
Meador Inge5b718d72015-07-23 22:49:37 -0500946 elif token in ("def", "class", "lambda"):
Johannes Gijsbersa5855d52005-03-12 16:37:11 +0000947 if token == "lambda":
948 self.islambda = True
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000949 self.started = True
Armin Rigodd5c0232005-09-25 11:45:45 +0000950 self.passline = True # skip to the end of the line
Meador Inge5b718d72015-07-23 22:49:37 -0500951 elif token == "(":
952 if self.indecorator:
953 self.decoratorhasargs = True
954 elif token == ")":
955 if self.indecorator:
956 self.indecorator = False
957 self.decoratorhasargs = False
Tim Peters4efb6e92001-06-29 23:51:08 +0000958 elif type == tokenize.NEWLINE:
Armin Rigodd5c0232005-09-25 11:45:45 +0000959 self.passline = False # stop skipping when a NEWLINE is seen
Guido van Rossum1bc535d2007-05-15 18:46:22 +0000960 self.last = srowcol[0]
Armin Rigodd5c0232005-09-25 11:45:45 +0000961 if self.islambda: # lambdas always end at the first NEWLINE
962 raise EndOfBlock
Meador Inge5b718d72015-07-23 22:49:37 -0500963 # hitting a NEWLINE when in a decorator without args
964 # ends the decorator
965 if self.indecorator and not self.decoratorhasargs:
966 self.indecorator = False
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000967 elif self.passline:
968 pass
Tim Peters4efb6e92001-06-29 23:51:08 +0000969 elif type == tokenize.INDENT:
Irit Katriel6e1eec72020-12-04 16:45:38 +0000970 if self.body_col0 is None and self.started:
971 self.body_col0 = erowcol[1]
Tim Peters4efb6e92001-06-29 23:51:08 +0000972 self.indent = self.indent + 1
Johannes Gijsbers1542f342004-12-12 16:46:28 +0000973 self.passline = True
Tim Peters4efb6e92001-06-29 23:51:08 +0000974 elif type == tokenize.DEDENT:
975 self.indent = self.indent - 1
Armin Rigodd5c0232005-09-25 11:45:45 +0000976 # the end of matching indent/dedent pairs end a block
977 # (note that this only works for "def"/"class" blocks,
978 # not e.g. for "if: else:" or "try: finally:" blocks)
979 if self.indent <= 0:
980 raise EndOfBlock
Irit Katriel6e1eec72020-12-04 16:45:38 +0000981 elif type == tokenize.COMMENT:
982 if self.body_col0 is not None and srowcol[1] >= self.body_col0:
983 # Include comments if indented at least as much as the block
984 self.last = srowcol[0]
Armin Rigodd5c0232005-09-25 11:45:45 +0000985 elif self.indent == 0 and type not in (tokenize.COMMENT, tokenize.NL):
986 # any other token on the same indentation level end the previous
987 # block as well, except the pseudo-tokens COMMENT and NL.
988 raise EndOfBlock
Tim Peters4efb6e92001-06-29 23:51:08 +0000989
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000990def getblock(lines):
991 """Extract the block of code at the top of the given list of lines."""
Armin Rigodd5c0232005-09-25 11:45:45 +0000992 blockfinder = BlockFinder()
Tim Peters4efb6e92001-06-29 23:51:08 +0000993 try:
Trent Nelson428de652008-03-18 22:41:35 +0000994 tokens = tokenize.generate_tokens(iter(lines).__next__)
995 for _token in tokens:
996 blockfinder.tokeneater(*_token)
Armin Rigodd5c0232005-09-25 11:45:45 +0000997 except (EndOfBlock, IndentationError):
998 pass
999 return lines[:blockfinder.last]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001000
1001def getsourcelines(object):
1002 """Return a list of source lines and starting line number for an object.
1003
1004 The argument may be a module, class, method, function, traceback, frame,
1005 or code object. The source code is returned as a list of the lines
1006 corresponding to the object and the line number indicates where in the
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02001007 original source file the first line of code was found. An OSError is
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001008 raised if the source code cannot be retrieved."""
Yury Selivanov081bbf62014-09-26 17:34:54 -04001009 object = unwrap(object)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001010 lines, lnum = findsource(object)
1011
Vladimir Matveev91cb2982018-08-24 07:18:00 -07001012 if istraceback(object):
1013 object = object.tb_frame
1014
1015 # for module or frame that corresponds to module, return all source lines
1016 if (ismodule(object) or
1017 (isframe(object) and object.f_code.co_name == "<module>")):
Meador Inge5b718d72015-07-23 22:49:37 -05001018 return lines, 0
1019 else:
1020 return getblock(lines[lnum:]), lnum + 1
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001021
1022def getsource(object):
1023 """Return the text of the source code for an object.
1024
1025 The argument may be a module, class, method, function, traceback, frame,
1026 or code object. The source code is returned as a single string. An
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02001027 OSError is raised if the source code cannot be retrieved."""
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001028 lines, lnum = getsourcelines(object)
Neal Norwitz9d72bb42007-04-17 08:48:32 +00001029 return ''.join(lines)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001030
1031# --------------------------------------------------- class tree extraction
1032def walktree(classes, children, parent):
1033 """Recursive helper function for getclasstree()."""
1034 results = []
Raymond Hettingera1a992c2005-03-11 06:46:45 +00001035 classes.sort(key=attrgetter('__module__', '__name__'))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001036 for c in classes:
1037 results.append((c, c.__bases__))
Raymond Hettinger54f02222002-06-01 14:18:47 +00001038 if c in children:
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001039 results.append(walktree(children[c], children, c))
1040 return results
1041
Georg Brandl5ce83a02009-06-01 17:23:51 +00001042def getclasstree(classes, unique=False):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001043 """Arrange the given list of classes into a hierarchy of nested lists.
1044
1045 Where a nested list appears, it contains classes derived from the class
1046 whose entry immediately precedes the list. Each entry is a 2-tuple
1047 containing a class and a tuple of its base classes. If the 'unique'
1048 argument is true, exactly one entry appears in the returned structure
1049 for each class in the given list. Otherwise, classes using multiple
1050 inheritance and their descendants will appear multiple times."""
1051 children = {}
1052 roots = []
1053 for c in classes:
1054 if c.__bases__:
1055 for parent in c.__bases__:
Srinivas Reddy Thatiparthy (శ్రీనివాస్ రెడ్డి తాటిపర్తి)feaefc72018-02-09 15:29:19 +05301056 if parent not in children:
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001057 children[parent] = []
Serhiy Storchaka362c1b52013-09-05 17:14:32 +03001058 if c not in children[parent]:
1059 children[parent].append(c)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001060 if unique and parent in classes: break
1061 elif c not in roots:
1062 roots.append(c)
Raymond Hettingere0d49722002-06-02 18:55:56 +00001063 for parent in children:
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001064 if parent not in classes:
1065 roots.append(parent)
1066 return walktree(roots, children, None)
1067
1068# ------------------------------------------------ argument list extraction
Christian Heimes25bb7832008-01-11 16:17:00 +00001069Arguments = namedtuple('Arguments', 'args, varargs, varkw')
1070
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001071def getargs(co):
1072 """Get information about the arguments accepted by a code object.
1073
Guido van Rossum2e65f892007-02-28 22:03:49 +00001074 Three things are returned: (args, varargs, varkw), where
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001075 'args' is the list of argument names. Keyword-only arguments are
1076 appended. 'varargs' and 'varkw' are the names of the * and **
1077 arguments or None."""
Jeremy Hylton64967882003-06-27 18:14:39 +00001078 if not iscode(co):
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +00001079 raise TypeError('{!r} is not a code object'.format(co))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001080
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001081 names = co.co_varnames
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001082 nargs = co.co_argcount
Guido van Rossum2e65f892007-02-28 22:03:49 +00001083 nkwargs = co.co_kwonlyargcount
Pablo Galindocd74e662019-06-01 18:08:04 +01001084 args = list(names[:nargs])
1085 kwonlyargs = list(names[nargs:nargs+nkwargs])
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001086 step = 0
1087
Guido van Rossum2e65f892007-02-28 22:03:49 +00001088 nargs += nkwargs
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001089 varargs = None
1090 if co.co_flags & CO_VARARGS:
1091 varargs = co.co_varnames[nargs]
1092 nargs = nargs + 1
1093 varkw = None
1094 if co.co_flags & CO_VARKEYWORDS:
1095 varkw = co.co_varnames[nargs]
Pablo Galindocd74e662019-06-01 18:08:04 +01001096 return Arguments(args + kwonlyargs, varargs, varkw)
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001097
1098ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults')
1099
1100def getargspec(func):
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001101 """Get the names and default values of a function's parameters.
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001102
1103 A tuple of four things is returned: (args, varargs, keywords, defaults).
1104 'args' is a list of the argument names, including keyword-only argument names.
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001105 'varargs' and 'keywords' are the names of the * and ** parameters or None.
1106 'defaults' is an n-tuple of the default values of the last n parameters.
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001107
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001108 This function is deprecated, as it does not support annotations or
1109 keyword-only parameters and will raise ValueError if either is present
1110 on the supplied callable.
1111
1112 For a more structured introspection API, use inspect.signature() instead.
1113
1114 Alternatively, use getfullargspec() for an API with a similar namedtuple
1115 based interface, but full support for annotations and keyword-only
1116 parameters.
Matthias Bussonnierded87d82018-10-19 16:40:45 -07001117
1118 Deprecated since Python 3.5, use `inspect.getfullargspec()`.
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001119 """
Matthias Bussonnierded87d82018-10-19 16:40:45 -07001120 warnings.warn("inspect.getargspec() is deprecated since Python 3.0, "
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001121 "use inspect.signature() or inspect.getfullargspec()",
1122 DeprecationWarning, stacklevel=2)
Pablo Galindod5d2b452019-04-30 02:01:14 +01001123 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
1124 getfullargspec(func)
1125 if kwonlyargs or ann:
1126 raise ValueError("Function has keyword-only parameters or annotations"
1127 ", use inspect.signature() API which can support them")
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001128 return ArgSpec(args, varargs, varkw, defaults)
1129
Christian Heimes25bb7832008-01-11 16:17:00 +00001130FullArgSpec = namedtuple('FullArgSpec',
Pablo Galindod5d2b452019-04-30 02:01:14 +01001131 'args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations')
Guido van Rossum2e65f892007-02-28 22:03:49 +00001132
1133def getfullargspec(func):
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001134 """Get the names and default values of a callable object's parameters.
Guido van Rossum2e65f892007-02-28 22:03:49 +00001135
Brett Cannon504d8852007-09-07 02:12:14 +00001136 A tuple of seven things is returned:
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001137 (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations).
1138 'args' is a list of the parameter names.
1139 'varargs' and 'varkw' are the names of the * and ** parameters or None.
1140 'defaults' is an n-tuple of the default values of the last n parameters.
1141 'kwonlyargs' is a list of keyword-only parameter names.
Guido van Rossum2e65f892007-02-28 22:03:49 +00001142 'kwonlydefaults' is a dictionary mapping names from kwonlyargs to defaults.
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001143 'annotations' is a dictionary mapping parameter names to annotations.
Guido van Rossuma8add0e2007-05-14 22:03:55 +00001144
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001145 Notable differences from inspect.signature():
1146 - the "self" parameter is always reported, even for bound methods
1147 - wrapper chains defined by __wrapped__ *not* unwrapped automatically
Jeremy Hylton64967882003-06-27 18:14:39 +00001148 """
Yury Selivanov57d240e2014-02-19 16:27:23 -05001149 try:
1150 # Re: `skip_bound_arg=False`
1151 #
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001152 # There is a notable difference in behaviour between getfullargspec
1153 # and Signature: the former always returns 'self' parameter for bound
1154 # methods, whereas the Signature always shows the actual calling
1155 # signature of the passed object.
1156 #
1157 # To simulate this behaviour, we "unbind" bound methods, to trick
1158 # inspect.signature to always return their first parameter ("self",
1159 # usually)
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001160
Yury Selivanov57d240e2014-02-19 16:27:23 -05001161 # Re: `follow_wrapper_chains=False`
1162 #
1163 # getfullargspec() historically ignored __wrapped__ attributes,
1164 # so we ensure that remains the case in 3.3+
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001165
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001166 sig = _signature_from_callable(func,
1167 follow_wrapper_chains=False,
1168 skip_bound_arg=False,
1169 sigcls=Signature)
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001170 except Exception as ex:
1171 # Most of the times 'signature' will raise ValueError.
1172 # But, it can also raise AttributeError, and, maybe something
1173 # else. So to be fully backwards compatible, we catch all
1174 # possible exceptions here, and reraise a TypeError.
1175 raise TypeError('unsupported callable') from ex
1176
1177 args = []
1178 varargs = None
1179 varkw = None
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001180 posonlyargs = []
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001181 kwonlyargs = []
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001182 annotations = {}
1183 defaults = ()
1184 kwdefaults = {}
1185
1186 if sig.return_annotation is not sig.empty:
1187 annotations['return'] = sig.return_annotation
1188
1189 for param in sig.parameters.values():
1190 kind = param.kind
1191 name = param.name
1192
1193 if kind is _POSITIONAL_ONLY:
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001194 posonlyargs.append(name)
1195 if param.default is not param.empty:
1196 defaults += (param.default,)
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001197 elif kind is _POSITIONAL_OR_KEYWORD:
1198 args.append(name)
1199 if param.default is not param.empty:
1200 defaults += (param.default,)
1201 elif kind is _VAR_POSITIONAL:
1202 varargs = name
1203 elif kind is _KEYWORD_ONLY:
1204 kwonlyargs.append(name)
1205 if param.default is not param.empty:
1206 kwdefaults[name] = param.default
1207 elif kind is _VAR_KEYWORD:
1208 varkw = name
1209
1210 if param.annotation is not param.empty:
1211 annotations[name] = param.annotation
1212
1213 if not kwdefaults:
1214 # compatibility with 'func.__kwdefaults__'
1215 kwdefaults = None
1216
1217 if not defaults:
1218 # compatibility with 'func.__defaults__'
1219 defaults = None
1220
Pablo Galindod5d2b452019-04-30 02:01:14 +01001221 return FullArgSpec(posonlyargs + args, varargs, varkw, defaults,
1222 kwonlyargs, kwdefaults, annotations)
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001223
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001224
Christian Heimes25bb7832008-01-11 16:17:00 +00001225ArgInfo = namedtuple('ArgInfo', 'args varargs keywords locals')
1226
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001227def getargvalues(frame):
1228 """Get information about arguments passed into a particular frame.
1229
1230 A tuple of four things is returned: (args, varargs, varkw, locals).
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001231 'args' is a list of the argument names.
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001232 'varargs' and 'varkw' are the names of the * and ** arguments or None.
1233 'locals' is the locals dictionary of the given frame."""
1234 args, varargs, varkw = getargs(frame.f_code)
Benjamin Peterson1a6e0d02008-10-25 15:49:17 +00001235 return ArgInfo(args, varargs, varkw, frame.f_locals)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001236
Guido van Rossum2e65f892007-02-28 22:03:49 +00001237def formatannotation(annotation, base_module=None):
Guido van Rossum52e50042016-10-22 07:55:18 -07001238 if getattr(annotation, '__module__', None) == 'typing':
1239 return repr(annotation).replace('typing.', '')
Guido van Rossum2e65f892007-02-28 22:03:49 +00001240 if isinstance(annotation, type):
Georg Brandl1a3284e2007-12-02 09:40:06 +00001241 if annotation.__module__ in ('builtins', base_module):
Serhiy Storchaka521e5862014-07-22 15:00:37 +03001242 return annotation.__qualname__
1243 return annotation.__module__+'.'+annotation.__qualname__
Guido van Rossum2e65f892007-02-28 22:03:49 +00001244 return repr(annotation)
Guido van Rossuma8add0e2007-05-14 22:03:55 +00001245
Guido van Rossum2e65f892007-02-28 22:03:49 +00001246def formatannotationrelativeto(object):
Guido van Rossuma8add0e2007-05-14 22:03:55 +00001247 module = getattr(object, '__module__', None)
1248 def _formatannotation(annotation):
1249 return formatannotation(annotation, module)
1250 return _formatannotation
Guido van Rossum2e65f892007-02-28 22:03:49 +00001251
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001252def formatargspec(args, varargs=None, varkw=None, defaults=None,
Pablo Galindod5d2b452019-04-30 02:01:14 +01001253 kwonlyargs=(), kwonlydefaults={}, annotations={},
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001254 formatarg=str,
1255 formatvarargs=lambda name: '*' + name,
1256 formatvarkw=lambda name: '**' + name,
1257 formatvalue=lambda value: '=' + repr(value),
Guido van Rossum2e65f892007-02-28 22:03:49 +00001258 formatreturns=lambda text: ' -> ' + text,
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001259 formatannotation=formatannotation):
Berker Peksagfa3922c2015-07-31 04:11:29 +03001260 """Format an argument spec from the values returned by getfullargspec.
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001261
Guido van Rossum2e65f892007-02-28 22:03:49 +00001262 The first seven arguments are (args, varargs, varkw, defaults,
1263 kwonlyargs, kwonlydefaults, annotations). The other five arguments
1264 are the corresponding optional formatting functions that are called to
1265 turn names and values into strings. The last argument is an optional
Matthias Bussonnier46c5cd02018-06-11 22:08:16 +02001266 function to format the sequence of arguments.
1267
1268 Deprecated since Python 3.5: use the `signature` function and `Signature`
1269 objects.
1270 """
1271
1272 from warnings import warn
1273
1274 warn("`formatargspec` is deprecated since Python 3.5. Use `signature` and "
Zackery Spytz41254eb2018-06-11 21:16:18 -06001275 "the `Signature` object directly",
Matthias Bussonnier46c5cd02018-06-11 22:08:16 +02001276 DeprecationWarning,
1277 stacklevel=2)
1278
Guido van Rossum2e65f892007-02-28 22:03:49 +00001279 def formatargandannotation(arg):
1280 result = formatarg(arg)
1281 if arg in annotations:
1282 result += ': ' + formatannotation(annotations[arg])
1283 return result
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001284 specs = []
1285 if defaults:
Pablo Galindod5d2b452019-04-30 02:01:14 +01001286 firstdefault = len(args) - len(defaults)
1287 for i, arg in enumerate(args):
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001288 spec = formatargandannotation(arg)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001289 if defaults and i >= firstdefault:
1290 spec = spec + formatvalue(defaults[i - firstdefault])
1291 specs.append(spec)
Raymond Hettinger936654b2002-06-01 03:06:31 +00001292 if varargs is not None:
Guido van Rossum2e65f892007-02-28 22:03:49 +00001293 specs.append(formatvarargs(formatargandannotation(varargs)))
1294 else:
1295 if kwonlyargs:
1296 specs.append('*')
1297 if kwonlyargs:
1298 for kwonlyarg in kwonlyargs:
1299 spec = formatargandannotation(kwonlyarg)
Benjamin Peterson9953a8d2009-01-17 04:15:01 +00001300 if kwonlydefaults and kwonlyarg in kwonlydefaults:
Guido van Rossum2e65f892007-02-28 22:03:49 +00001301 spec += formatvalue(kwonlydefaults[kwonlyarg])
1302 specs.append(spec)
Raymond Hettinger936654b2002-06-01 03:06:31 +00001303 if varkw is not None:
Guido van Rossum2e65f892007-02-28 22:03:49 +00001304 specs.append(formatvarkw(formatargandannotation(varkw)))
Neal Norwitz9d72bb42007-04-17 08:48:32 +00001305 result = '(' + ', '.join(specs) + ')'
Guido van Rossum2e65f892007-02-28 22:03:49 +00001306 if 'return' in annotations:
1307 result += formatreturns(formatannotation(annotations['return']))
1308 return result
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001309
1310def formatargvalues(args, varargs, varkw, locals,
1311 formatarg=str,
1312 formatvarargs=lambda name: '*' + name,
1313 formatvarkw=lambda name: '**' + name,
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001314 formatvalue=lambda value: '=' + repr(value)):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001315 """Format an argument spec from the 4 values returned by getargvalues.
1316
1317 The first four arguments are (args, varargs, varkw, locals). The
1318 next four arguments are the corresponding optional formatting functions
1319 that are called to turn names and values into strings. The ninth
1320 argument is an optional function to format the sequence of arguments."""
1321 def convert(name, locals=locals,
1322 formatarg=formatarg, formatvalue=formatvalue):
1323 return formatarg(name) + formatvalue(locals[name])
1324 specs = []
1325 for i in range(len(args)):
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001326 specs.append(convert(args[i]))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001327 if varargs:
1328 specs.append(formatvarargs(varargs) + formatvalue(locals[varargs]))
1329 if varkw:
1330 specs.append(formatvarkw(varkw) + formatvalue(locals[varkw]))
Neal Norwitz9d72bb42007-04-17 08:48:32 +00001331 return '(' + ', '.join(specs) + ')'
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001332
Benjamin Petersone109c702011-06-24 09:37:26 -05001333def _missing_arguments(f_name, argnames, pos, values):
1334 names = [repr(name) for name in argnames if name not in values]
1335 missing = len(names)
1336 if missing == 1:
1337 s = names[0]
1338 elif missing == 2:
1339 s = "{} and {}".format(*names)
1340 else:
Yury Selivanovdccfa132014-03-27 18:42:52 -04001341 tail = ", {} and {}".format(*names[-2:])
Benjamin Petersone109c702011-06-24 09:37:26 -05001342 del names[-2:]
1343 s = ", ".join(names) + tail
1344 raise TypeError("%s() missing %i required %s argument%s: %s" %
1345 (f_name, missing,
1346 "positional" if pos else "keyword-only",
1347 "" if missing == 1 else "s", s))
1348
1349def _too_many(f_name, args, kwonly, varargs, defcount, given, values):
Benjamin Petersonb204a422011-06-05 22:04:07 -05001350 atleast = len(args) - defcount
Benjamin Petersonb204a422011-06-05 22:04:07 -05001351 kwonly_given = len([arg for arg in kwonly if arg in values])
1352 if varargs:
1353 plural = atleast != 1
1354 sig = "at least %d" % (atleast,)
1355 elif defcount:
1356 plural = True
1357 sig = "from %d to %d" % (atleast, len(args))
1358 else:
1359 plural = len(args) != 1
1360 sig = str(len(args))
1361 kwonly_sig = ""
1362 if kwonly_given:
1363 msg = " positional argument%s (and %d keyword-only argument%s)"
1364 kwonly_sig = (msg % ("s" if given != 1 else "", kwonly_given,
1365 "s" if kwonly_given != 1 else ""))
1366 raise TypeError("%s() takes %s positional argument%s but %d%s %s given" %
1367 (f_name, sig, "s" if plural else "", given, kwonly_sig,
1368 "was" if given == 1 and not kwonly_given else "were"))
1369
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03001370def getcallargs(func, /, *positional, **named):
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001371 """Get the mapping of arguments to values.
1372
1373 A dict is returned, with keys the function argument names (including the
1374 names of the * and ** arguments, if any), and values the respective bound
1375 values from 'positional' and 'named'."""
1376 spec = getfullargspec(func)
Pablo Galindod5d2b452019-04-30 02:01:14 +01001377 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = spec
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001378 f_name = func.__name__
1379 arg2value = {}
1380
Benjamin Petersonb204a422011-06-05 22:04:07 -05001381
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001382 if ismethod(func) and func.__self__ is not None:
1383 # implicit 'self' (or 'cls' for classmethods) argument
1384 positional = (func.__self__,) + positional
1385 num_pos = len(positional)
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001386 num_args = len(args)
1387 num_defaults = len(defaults) if defaults else 0
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001388
Benjamin Petersonb204a422011-06-05 22:04:07 -05001389 n = min(num_pos, num_args)
1390 for i in range(n):
Pablo Galindod5d2b452019-04-30 02:01:14 +01001391 arg2value[args[i]] = positional[i]
Benjamin Petersonb204a422011-06-05 22:04:07 -05001392 if varargs:
1393 arg2value[varargs] = tuple(positional[n:])
1394 possible_kwargs = set(args + kwonlyargs)
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001395 if varkw:
Benjamin Petersonb204a422011-06-05 22:04:07 -05001396 arg2value[varkw] = {}
1397 for kw, value in named.items():
1398 if kw not in possible_kwargs:
1399 if not varkw:
1400 raise TypeError("%s() got an unexpected keyword argument %r" %
1401 (f_name, kw))
1402 arg2value[varkw][kw] = value
1403 continue
1404 if kw in arg2value:
1405 raise TypeError("%s() got multiple values for argument %r" %
1406 (f_name, kw))
1407 arg2value[kw] = value
1408 if num_pos > num_args and not varargs:
Benjamin Petersone109c702011-06-24 09:37:26 -05001409 _too_many(f_name, args, kwonlyargs, varargs, num_defaults,
1410 num_pos, arg2value)
Benjamin Petersonb204a422011-06-05 22:04:07 -05001411 if num_pos < num_args:
Benjamin Petersone109c702011-06-24 09:37:26 -05001412 req = args[:num_args - num_defaults]
1413 for arg in req:
Benjamin Petersonb204a422011-06-05 22:04:07 -05001414 if arg not in arg2value:
Benjamin Petersone109c702011-06-24 09:37:26 -05001415 _missing_arguments(f_name, req, True, arg2value)
Benjamin Petersonb204a422011-06-05 22:04:07 -05001416 for i, arg in enumerate(args[num_args - num_defaults:]):
1417 if arg not in arg2value:
1418 arg2value[arg] = defaults[i]
Benjamin Petersone109c702011-06-24 09:37:26 -05001419 missing = 0
Benjamin Petersonb204a422011-06-05 22:04:07 -05001420 for kwarg in kwonlyargs:
1421 if kwarg not in arg2value:
Yury Selivanov875df202014-03-27 18:23:03 -04001422 if kwonlydefaults and kwarg in kwonlydefaults:
Benjamin Petersone109c702011-06-24 09:37:26 -05001423 arg2value[kwarg] = kwonlydefaults[kwarg]
1424 else:
1425 missing += 1
1426 if missing:
1427 _missing_arguments(f_name, kwonlyargs, False, arg2value)
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001428 return arg2value
1429
Nick Coghlan2f92e542012-06-23 19:39:55 +10001430ClosureVars = namedtuple('ClosureVars', 'nonlocals globals builtins unbound')
1431
1432def getclosurevars(func):
1433 """
1434 Get the mapping of free variables to their current values.
1435
Meador Inge8fda3592012-07-19 21:33:21 -05001436 Returns a named tuple of dicts mapping the current nonlocal, global
Nick Coghlan2f92e542012-06-23 19:39:55 +10001437 and builtin references as seen by the body of the function. A final
1438 set of unbound names that could not be resolved is also provided.
1439 """
1440
1441 if ismethod(func):
1442 func = func.__func__
1443
1444 if not isfunction(func):
Serhiy Storchakaa4a30202017-11-28 22:54:42 +02001445 raise TypeError("{!r} is not a Python function".format(func))
Nick Coghlan2f92e542012-06-23 19:39:55 +10001446
1447 code = func.__code__
1448 # Nonlocal references are named in co_freevars and resolved
1449 # by looking them up in __closure__ by positional index
1450 if func.__closure__ is None:
1451 nonlocal_vars = {}
1452 else:
1453 nonlocal_vars = {
1454 var : cell.cell_contents
1455 for var, cell in zip(code.co_freevars, func.__closure__)
1456 }
1457
1458 # Global and builtin references are named in co_names and resolved
1459 # by looking them up in __globals__ or __builtins__
1460 global_ns = func.__globals__
1461 builtin_ns = global_ns.get("__builtins__", builtins.__dict__)
1462 if ismodule(builtin_ns):
1463 builtin_ns = builtin_ns.__dict__
1464 global_vars = {}
1465 builtin_vars = {}
1466 unbound_names = set()
1467 for name in code.co_names:
1468 if name in ("None", "True", "False"):
1469 # Because these used to be builtins instead of keywords, they
1470 # may still show up as name references. We ignore them.
1471 continue
1472 try:
1473 global_vars[name] = global_ns[name]
1474 except KeyError:
1475 try:
1476 builtin_vars[name] = builtin_ns[name]
1477 except KeyError:
1478 unbound_names.add(name)
1479
1480 return ClosureVars(nonlocal_vars, global_vars,
1481 builtin_vars, unbound_names)
1482
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001483# -------------------------------------------------- stack frame extraction
Christian Heimes25bb7832008-01-11 16:17:00 +00001484
1485Traceback = namedtuple('Traceback', 'filename lineno function code_context index')
1486
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001487def getframeinfo(frame, context=1):
1488 """Get information about a frame or traceback object.
1489
1490 A tuple of five things is returned: the filename, the line number of
1491 the current line, the function name, a list of lines of context from
1492 the source code, and the index of the current line within that list.
1493 The optional second argument specifies the number of lines of context
1494 to return, which are centered around the current line."""
1495 if istraceback(frame):
Andrew M. Kuchlingba8b6bc2004-06-05 14:11:59 +00001496 lineno = frame.tb_lineno
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001497 frame = frame.tb_frame
Andrew M. Kuchlingba8b6bc2004-06-05 14:11:59 +00001498 else:
1499 lineno = frame.f_lineno
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001500 if not isframe(frame):
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +00001501 raise TypeError('{!r} is not a frame or traceback object'.format(frame))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001502
Neil Schemenauerf06f8532002-03-23 23:51:04 +00001503 filename = getsourcefile(frame) or getfile(frame)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001504 if context > 0:
Guido van Rossum54e54c62001-09-04 19:14:14 +00001505 start = lineno - 1 - context//2
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001506 try:
1507 lines, lnum = findsource(frame)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02001508 except OSError:
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +00001509 lines = index = None
1510 else:
Raymond Hettingera0501712004-06-15 11:22:53 +00001511 start = max(0, min(start, len(lines) - context))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001512 lines = lines[start:start+context]
Ka-Ping Yee59ade082001-03-01 03:55:35 +00001513 index = lineno - 1 - start
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001514 else:
1515 lines = index = None
1516
Christian Heimes25bb7832008-01-11 16:17:00 +00001517 return Traceback(filename, lineno, frame.f_code.co_name, lines, index)
Ka-Ping Yee59ade082001-03-01 03:55:35 +00001518
1519def getlineno(frame):
1520 """Get the line number from a frame object, allowing for optimization."""
Michael W. Hudsondd32a912002-08-15 14:59:02 +00001521 # FrameType.f_lineno is now a descriptor that grovels co_lnotab
1522 return frame.f_lineno
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001523
Antoine Pitroucdcafb72014-08-24 10:50:28 -04001524FrameInfo = namedtuple('FrameInfo', ('frame',) + Traceback._fields)
1525
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001526def getouterframes(frame, context=1):
1527 """Get a list of records for a frame and all higher (calling) frames.
1528
1529 Each record contains a frame object, filename, line number, function
1530 name, a list of lines of context, and index within the context."""
1531 framelist = []
1532 while frame:
Antoine Pitroucdcafb72014-08-24 10:50:28 -04001533 frameinfo = (frame,) + getframeinfo(frame, context)
1534 framelist.append(FrameInfo(*frameinfo))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001535 frame = frame.f_back
1536 return framelist
1537
1538def getinnerframes(tb, context=1):
1539 """Get a list of records for a traceback's frame and all lower frames.
1540
1541 Each record contains a frame object, filename, line number, function
1542 name, a list of lines of context, and index within the context."""
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001543 framelist = []
1544 while tb:
Antoine Pitroucdcafb72014-08-24 10:50:28 -04001545 frameinfo = (tb.tb_frame,) + getframeinfo(tb, context)
1546 framelist.append(FrameInfo(*frameinfo))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001547 tb = tb.tb_next
1548 return framelist
1549
Benjamin Peterson42ac4752010-08-09 13:05:35 +00001550def currentframe():
Benjamin Petersona3a3fc62010-08-09 15:49:56 +00001551 """Return the frame of the caller or None if this is not possible."""
Benjamin Peterson42ac4752010-08-09 13:05:35 +00001552 return sys._getframe(1) if hasattr(sys, "_getframe") else None
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001553
1554def stack(context=1):
1555 """Return a list of records for the stack above the caller's frame."""
Jeremy Hyltonab919022003-06-27 18:41:20 +00001556 return getouterframes(sys._getframe(1), context)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001557
1558def trace(context=1):
Tim Peters85ba6732001-02-28 08:26:44 +00001559 """Return a list of records for the stack below the current exception."""
Fred Draked451ec12002-04-26 02:29:55 +00001560 return getinnerframes(sys.exc_info()[2], context)
Michael Foord95fc51d2010-11-20 15:07:30 +00001561
1562
1563# ------------------------------------------------ static version of getattr
1564
1565_sentinel = object()
1566
Michael Foorde5162652010-11-20 16:40:44 +00001567def _static_getmro(klass):
1568 return type.__dict__['__mro__'].__get__(klass)
1569
Michael Foord95fc51d2010-11-20 15:07:30 +00001570def _check_instance(obj, attr):
1571 instance_dict = {}
1572 try:
1573 instance_dict = object.__getattribute__(obj, "__dict__")
1574 except AttributeError:
1575 pass
Michael Foorddcebe0f2011-03-15 19:20:44 -04001576 return dict.get(instance_dict, attr, _sentinel)
Michael Foord95fc51d2010-11-20 15:07:30 +00001577
1578
1579def _check_class(klass, attr):
Michael Foorde5162652010-11-20 16:40:44 +00001580 for entry in _static_getmro(klass):
Michael Foorda51623b2011-12-18 22:01:40 +00001581 if _shadowed_dict(type(entry)) is _sentinel:
Michael Foorddcebe0f2011-03-15 19:20:44 -04001582 try:
1583 return entry.__dict__[attr]
1584 except KeyError:
1585 pass
Michael Foord95fc51d2010-11-20 15:07:30 +00001586 return _sentinel
1587
Michael Foord35184ed2010-11-20 16:58:30 +00001588def _is_type(obj):
1589 try:
1590 _static_getmro(obj)
1591 except TypeError:
1592 return False
1593 return True
1594
Michael Foorddcebe0f2011-03-15 19:20:44 -04001595def _shadowed_dict(klass):
1596 dict_attr = type.__dict__["__dict__"]
1597 for entry in _static_getmro(klass):
1598 try:
1599 class_dict = dict_attr.__get__(entry)["__dict__"]
1600 except KeyError:
1601 pass
1602 else:
Inada Naoki8f9cc872019-09-05 13:07:08 +09001603 if not (type(class_dict) is types.GetSetDescriptorType and
Michael Foorddcebe0f2011-03-15 19:20:44 -04001604 class_dict.__name__ == "__dict__" and
1605 class_dict.__objclass__ is entry):
Michael Foorda51623b2011-12-18 22:01:40 +00001606 return class_dict
1607 return _sentinel
Michael Foord95fc51d2010-11-20 15:07:30 +00001608
1609def getattr_static(obj, attr, default=_sentinel):
1610 """Retrieve attributes without triggering dynamic lookup via the
1611 descriptor protocol, __getattr__ or __getattribute__.
1612
1613 Note: this function may not be able to retrieve all attributes
1614 that getattr can fetch (like dynamically created attributes)
1615 and may find attributes that getattr can't (like descriptors
1616 that raise AttributeError). It can also return descriptor objects
1617 instead of instance members in some cases. See the
1618 documentation for details.
1619 """
1620 instance_result = _sentinel
Michael Foord35184ed2010-11-20 16:58:30 +00001621 if not _is_type(obj):
Michael Foordcc7ebb82010-11-20 16:20:16 +00001622 klass = type(obj)
Michael Foorda51623b2011-12-18 22:01:40 +00001623 dict_attr = _shadowed_dict(klass)
1624 if (dict_attr is _sentinel or
Inada Naoki8f9cc872019-09-05 13:07:08 +09001625 type(dict_attr) is types.MemberDescriptorType):
Michael Foorddcebe0f2011-03-15 19:20:44 -04001626 instance_result = _check_instance(obj, attr)
Michael Foord95fc51d2010-11-20 15:07:30 +00001627 else:
1628 klass = obj
1629
1630 klass_result = _check_class(klass, attr)
1631
1632 if instance_result is not _sentinel and klass_result is not _sentinel:
1633 if (_check_class(type(klass_result), '__get__') is not _sentinel and
1634 _check_class(type(klass_result), '__set__') is not _sentinel):
1635 return klass_result
1636
1637 if instance_result is not _sentinel:
1638 return instance_result
1639 if klass_result is not _sentinel:
1640 return klass_result
1641
1642 if obj is klass:
1643 # for types we check the metaclass too
Michael Foorde5162652010-11-20 16:40:44 +00001644 for entry in _static_getmro(type(klass)):
Michael Foord3ba95f82011-12-22 01:13:37 +00001645 if _shadowed_dict(type(entry)) is _sentinel:
1646 try:
1647 return entry.__dict__[attr]
1648 except KeyError:
1649 pass
Michael Foord95fc51d2010-11-20 15:07:30 +00001650 if default is not _sentinel:
1651 return default
1652 raise AttributeError(attr)
Nick Coghlane0f04652010-11-21 03:44:04 +00001653
1654
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001655# ------------------------------------------------ generator introspection
1656
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001657GEN_CREATED = 'GEN_CREATED'
1658GEN_RUNNING = 'GEN_RUNNING'
1659GEN_SUSPENDED = 'GEN_SUSPENDED'
1660GEN_CLOSED = 'GEN_CLOSED'
Nick Coghlane0f04652010-11-21 03:44:04 +00001661
1662def getgeneratorstate(generator):
1663 """Get current state of a generator-iterator.
1664
1665 Possible states are:
1666 GEN_CREATED: Waiting to start execution.
1667 GEN_RUNNING: Currently being executed by the interpreter.
1668 GEN_SUSPENDED: Currently suspended at a yield expression.
1669 GEN_CLOSED: Execution has completed.
1670 """
1671 if generator.gi_running:
1672 return GEN_RUNNING
1673 if generator.gi_frame is None:
1674 return GEN_CLOSED
1675 if generator.gi_frame.f_lasti == -1:
1676 return GEN_CREATED
1677 return GEN_SUSPENDED
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001678
1679
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001680def getgeneratorlocals(generator):
1681 """
1682 Get the mapping of generator local variables to their current values.
1683
1684 A dict is returned, with the keys the local variable names and values the
1685 bound values."""
1686
1687 if not isgenerator(generator):
Serhiy Storchakaa4a30202017-11-28 22:54:42 +02001688 raise TypeError("{!r} is not a Python generator".format(generator))
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001689
1690 frame = getattr(generator, "gi_frame", None)
1691 if frame is not None:
1692 return generator.gi_frame.f_locals
1693 else:
1694 return {}
1695
Yury Selivanov5376ba92015-06-22 12:19:30 -04001696
1697# ------------------------------------------------ coroutine introspection
1698
1699CORO_CREATED = 'CORO_CREATED'
1700CORO_RUNNING = 'CORO_RUNNING'
1701CORO_SUSPENDED = 'CORO_SUSPENDED'
1702CORO_CLOSED = 'CORO_CLOSED'
1703
1704def getcoroutinestate(coroutine):
1705 """Get current state of a coroutine object.
1706
1707 Possible states are:
1708 CORO_CREATED: Waiting to start execution.
1709 CORO_RUNNING: Currently being executed by the interpreter.
1710 CORO_SUSPENDED: Currently suspended at an await expression.
1711 CORO_CLOSED: Execution has completed.
1712 """
1713 if coroutine.cr_running:
1714 return CORO_RUNNING
1715 if coroutine.cr_frame is None:
1716 return CORO_CLOSED
1717 if coroutine.cr_frame.f_lasti == -1:
1718 return CORO_CREATED
1719 return CORO_SUSPENDED
1720
1721
1722def getcoroutinelocals(coroutine):
1723 """
1724 Get the mapping of coroutine local variables to their current values.
1725
1726 A dict is returned, with the keys the local variable names and values the
1727 bound values."""
1728 frame = getattr(coroutine, "cr_frame", None)
1729 if frame is not None:
1730 return frame.f_locals
1731 else:
1732 return {}
1733
1734
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001735###############################################################################
1736### Function Signature Object (PEP 362)
1737###############################################################################
1738
1739
1740_WrapperDescriptor = type(type.__call__)
1741_MethodWrapper = type(all.__call__)
Larry Hastings5c661892014-01-24 06:17:25 -08001742_ClassMethodWrapper = type(int.__dict__['from_bytes'])
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001743
1744_NonUserDefinedCallables = (_WrapperDescriptor,
1745 _MethodWrapper,
Larry Hastings5c661892014-01-24 06:17:25 -08001746 _ClassMethodWrapper,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001747 types.BuiltinFunctionType)
1748
1749
Yury Selivanov421f0c72014-01-29 12:05:40 -05001750def _signature_get_user_defined_method(cls, method_name):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001751 """Private helper. Checks if ``cls`` has an attribute
1752 named ``method_name`` and returns it only if it is a
1753 pure python function.
1754 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001755 try:
1756 meth = getattr(cls, method_name)
1757 except AttributeError:
1758 return
1759 else:
1760 if not isinstance(meth, _NonUserDefinedCallables):
1761 # Once '__signature__' will be added to 'C'-level
1762 # callables, this check won't be necessary
1763 return meth
1764
1765
Yury Selivanov62560fb2014-01-28 12:26:24 -05001766def _signature_get_partial(wrapped_sig, partial, extra_args=()):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001767 """Private helper to calculate how 'wrapped_sig' signature will
1768 look like after applying a 'functools.partial' object (or alike)
1769 on it.
1770 """
Yury Selivanov62560fb2014-01-28 12:26:24 -05001771
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001772 old_params = wrapped_sig.parameters
Inada Naoki21105512020-03-02 18:54:49 +09001773 new_params = OrderedDict(old_params.items())
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05001774
1775 partial_args = partial.args or ()
1776 partial_keywords = partial.keywords or {}
1777
1778 if extra_args:
1779 partial_args = extra_args + partial_args
1780
1781 try:
1782 ba = wrapped_sig.bind_partial(*partial_args, **partial_keywords)
1783 except TypeError as ex:
1784 msg = 'partial object {!r} has incorrect arguments'.format(partial)
1785 raise ValueError(msg) from ex
1786
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05001787
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001788 transform_to_kwonly = False
1789 for param_name, param in old_params.items():
1790 try:
1791 arg_value = ba.arguments[param_name]
1792 except KeyError:
1793 pass
1794 else:
1795 if param.kind is _POSITIONAL_ONLY:
1796 # If positional-only parameter is bound by partial,
1797 # it effectively disappears from the signature
Inada Naoki21105512020-03-02 18:54:49 +09001798 new_params.pop(param_name)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001799 continue
1800
1801 if param.kind is _POSITIONAL_OR_KEYWORD:
1802 if param_name in partial_keywords:
1803 # This means that this parameter, and all parameters
1804 # after it should be keyword-only (and var-positional
1805 # should be removed). Here's why. Consider the following
1806 # function:
1807 # foo(a, b, *args, c):
1808 # pass
1809 #
1810 # "partial(foo, a='spam')" will have the following
1811 # signature: "(*, a='spam', b, c)". Because attempting
1812 # to call that partial with "(10, 20)" arguments will
1813 # raise a TypeError, saying that "a" argument received
1814 # multiple values.
1815 transform_to_kwonly = True
1816 # Set the new default value
Inada Naoki21105512020-03-02 18:54:49 +09001817 new_params[param_name] = param.replace(default=arg_value)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001818 else:
1819 # was passed as a positional argument
Inada Naoki21105512020-03-02 18:54:49 +09001820 new_params.pop(param.name)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001821 continue
1822
1823 if param.kind is _KEYWORD_ONLY:
1824 # Set the new default value
Inada Naoki21105512020-03-02 18:54:49 +09001825 new_params[param_name] = param.replace(default=arg_value)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001826
1827 if transform_to_kwonly:
1828 assert param.kind is not _POSITIONAL_ONLY
1829
1830 if param.kind is _POSITIONAL_OR_KEYWORD:
Inada Naoki21105512020-03-02 18:54:49 +09001831 new_param = new_params[param_name].replace(kind=_KEYWORD_ONLY)
1832 new_params[param_name] = new_param
1833 new_params.move_to_end(param_name)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001834 elif param.kind in (_KEYWORD_ONLY, _VAR_KEYWORD):
Inada Naoki21105512020-03-02 18:54:49 +09001835 new_params.move_to_end(param_name)
1836 elif param.kind is _VAR_POSITIONAL:
1837 new_params.pop(param.name)
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05001838
1839 return wrapped_sig.replace(parameters=new_params.values())
1840
1841
Yury Selivanov62560fb2014-01-28 12:26:24 -05001842def _signature_bound_method(sig):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001843 """Private helper to transform signatures for unbound
1844 functions to bound methods.
1845 """
Yury Selivanov62560fb2014-01-28 12:26:24 -05001846
1847 params = tuple(sig.parameters.values())
1848
1849 if not params or params[0].kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
1850 raise ValueError('invalid method signature')
1851
1852 kind = params[0].kind
1853 if kind in (_POSITIONAL_OR_KEYWORD, _POSITIONAL_ONLY):
1854 # Drop first parameter:
1855 # '(p1, p2[, ...])' -> '(p2[, ...])'
1856 params = params[1:]
1857 else:
1858 if kind is not _VAR_POSITIONAL:
1859 # Unless we add a new parameter type we never
1860 # get here
1861 raise ValueError('invalid argument type')
1862 # It's a var-positional parameter.
1863 # Do nothing. '(*args[, ...])' -> '(*args[, ...])'
1864
1865 return sig.replace(parameters=params)
1866
1867
Yury Selivanovb77511d2014-01-29 10:46:14 -05001868def _signature_is_builtin(obj):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001869 """Private helper to test if `obj` is a callable that might
1870 support Argument Clinic's __text_signature__ protocol.
1871 """
Yury Selivanov1d241832014-02-02 12:51:20 -05001872 return (isbuiltin(obj) or
Yury Selivanovb77511d2014-01-29 10:46:14 -05001873 ismethoddescriptor(obj) or
Yury Selivanov1d241832014-02-02 12:51:20 -05001874 isinstance(obj, _NonUserDefinedCallables) or
Yury Selivanovb77511d2014-01-29 10:46:14 -05001875 # Can't test 'isinstance(type)' here, as it would
1876 # also be True for regular python classes
1877 obj in (type, object))
1878
1879
Yury Selivanov63da7c72014-01-31 14:48:37 -05001880def _signature_is_functionlike(obj):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001881 """Private helper to test if `obj` is a duck type of FunctionType.
1882 A good example of such objects are functions compiled with
1883 Cython, which have all attributes that a pure Python function
1884 would have, but have their code statically compiled.
1885 """
Yury Selivanov63da7c72014-01-31 14:48:37 -05001886
1887 if not callable(obj) or isclass(obj):
1888 # All function-like objects are obviously callables,
1889 # and not classes.
1890 return False
1891
1892 name = getattr(obj, '__name__', None)
1893 code = getattr(obj, '__code__', None)
1894 defaults = getattr(obj, '__defaults__', _void) # Important to use _void ...
1895 kwdefaults = getattr(obj, '__kwdefaults__', _void) # ... and not None here
Batuhan Taskaya044a1042020-10-06 23:03:02 +03001896 try:
1897 annotations = _get_type_hints(obj)
1898 except AttributeError:
1899 annotations = None
Yury Selivanov63da7c72014-01-31 14:48:37 -05001900
1901 return (isinstance(code, types.CodeType) and
1902 isinstance(name, str) and
1903 (defaults is None or isinstance(defaults, tuple)) and
1904 (kwdefaults is None or isinstance(kwdefaults, dict)) and
1905 isinstance(annotations, dict))
1906
1907
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001908def _signature_get_bound_param(spec):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001909 """ Private helper to get first parameter name from a
1910 __text_signature__ of a builtin method, which should
1911 be in the following format: '($param1, ...)'.
1912 Assumptions are that the first argument won't have
1913 a default value or an annotation.
1914 """
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001915
1916 assert spec.startswith('($')
1917
1918 pos = spec.find(',')
1919 if pos == -1:
1920 pos = spec.find(')')
1921
1922 cpos = spec.find(':')
1923 assert cpos == -1 or cpos > pos
1924
1925 cpos = spec.find('=')
1926 assert cpos == -1 or cpos > pos
1927
1928 return spec[2:pos]
1929
1930
Larry Hastings2623c8c2014-02-08 22:15:29 -08001931def _signature_strip_non_python_syntax(signature):
1932 """
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001933 Private helper function. Takes a signature in Argument Clinic's
1934 extended signature format.
1935
Larry Hastings2623c8c2014-02-08 22:15:29 -08001936 Returns a tuple of three things:
1937 * that signature re-rendered in standard Python syntax,
1938 * the index of the "self" parameter (generally 0), or None if
1939 the function does not have a "self" parameter, and
1940 * the index of the last "positional only" parameter,
1941 or None if the signature has no positional-only parameters.
1942 """
1943
1944 if not signature:
1945 return signature, None, None
1946
1947 self_parameter = None
1948 last_positional_only = None
1949
1950 lines = [l.encode('ascii') for l in signature.split('\n')]
1951 generator = iter(lines).__next__
1952 token_stream = tokenize.tokenize(generator)
1953
1954 delayed_comma = False
1955 skip_next_comma = False
1956 text = []
1957 add = text.append
1958
1959 current_parameter = 0
1960 OP = token.OP
1961 ERRORTOKEN = token.ERRORTOKEN
1962
1963 # token stream always starts with ENCODING token, skip it
1964 t = next(token_stream)
1965 assert t.type == tokenize.ENCODING
1966
1967 for t in token_stream:
1968 type, string = t.type, t.string
1969
1970 if type == OP:
1971 if string == ',':
1972 if skip_next_comma:
1973 skip_next_comma = False
1974 else:
1975 assert not delayed_comma
1976 delayed_comma = True
1977 current_parameter += 1
1978 continue
1979
1980 if string == '/':
1981 assert not skip_next_comma
1982 assert last_positional_only is None
1983 skip_next_comma = True
1984 last_positional_only = current_parameter - 1
1985 continue
1986
1987 if (type == ERRORTOKEN) and (string == '$'):
1988 assert self_parameter is None
1989 self_parameter = current_parameter
1990 continue
1991
1992 if delayed_comma:
1993 delayed_comma = False
1994 if not ((type == OP) and (string == ')')):
1995 add(', ')
1996 add(string)
1997 if (string == ','):
1998 add(' ')
1999 clean_signature = ''.join(text)
2000 return clean_signature, self_parameter, last_positional_only
2001
2002
Yury Selivanov57d240e2014-02-19 16:27:23 -05002003def _signature_fromstr(cls, obj, s, skip_bound_arg=True):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002004 """Private helper to parse content of '__text_signature__'
2005 and return a Signature based on it.
2006 """
INADA Naoki37420de2018-01-27 10:10:06 +09002007 # Lazy import ast because it's relatively heavy and
2008 # it's not used for other than this function.
2009 import ast
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002010
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002011 Parameter = cls._parameter_cls
2012
Larry Hastings2623c8c2014-02-08 22:15:29 -08002013 clean_signature, self_parameter, last_positional_only = \
2014 _signature_strip_non_python_syntax(s)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002015
Larry Hastings2623c8c2014-02-08 22:15:29 -08002016 program = "def foo" + clean_signature + ": pass"
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002017
2018 try:
Larry Hastings2623c8c2014-02-08 22:15:29 -08002019 module = ast.parse(program)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002020 except SyntaxError:
2021 module = None
2022
2023 if not isinstance(module, ast.Module):
2024 raise ValueError("{!r} builtin has invalid signature".format(obj))
2025
2026 f = module.body[0]
2027
2028 parameters = []
2029 empty = Parameter.empty
2030 invalid = object()
2031
2032 module = None
2033 module_dict = {}
2034 module_name = getattr(obj, '__module__', None)
2035 if module_name:
2036 module = sys.modules.get(module_name, None)
2037 if module:
2038 module_dict = module.__dict__
INADA Naoki6f85b822018-10-05 01:47:09 +09002039 sys_module_dict = sys.modules.copy()
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002040
2041 def parse_name(node):
2042 assert isinstance(node, ast.arg)
Srinivas Reddy Thatiparthy (శ్రీనివాస్ రెడ్డి తాటిపర్తి)feaefc72018-02-09 15:29:19 +05302043 if node.annotation is not None:
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002044 raise ValueError("Annotations are not currently supported")
2045 return node.arg
2046
2047 def wrap_value(s):
2048 try:
2049 value = eval(s, module_dict)
2050 except NameError:
2051 try:
2052 value = eval(s, sys_module_dict)
2053 except NameError:
2054 raise RuntimeError()
2055
Serhiy Storchaka3f228112018-09-27 17:42:37 +03002056 if isinstance(value, (str, int, float, bytes, bool, type(None))):
2057 return ast.Constant(value)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002058 raise RuntimeError()
2059
2060 class RewriteSymbolics(ast.NodeTransformer):
2061 def visit_Attribute(self, node):
2062 a = []
2063 n = node
2064 while isinstance(n, ast.Attribute):
2065 a.append(n.attr)
2066 n = n.value
2067 if not isinstance(n, ast.Name):
2068 raise RuntimeError()
2069 a.append(n.id)
2070 value = ".".join(reversed(a))
2071 return wrap_value(value)
2072
2073 def visit_Name(self, node):
2074 if not isinstance(node.ctx, ast.Load):
2075 raise ValueError()
2076 return wrap_value(node.id)
2077
2078 def p(name_node, default_node, default=empty):
2079 name = parse_name(name_node)
2080 if name is invalid:
2081 return None
2082 if default_node and default_node is not _empty:
2083 try:
2084 default_node = RewriteSymbolics().visit(default_node)
2085 o = ast.literal_eval(default_node)
2086 except ValueError:
2087 o = invalid
2088 if o is invalid:
2089 return None
2090 default = o if o is not invalid else default
2091 parameters.append(Parameter(name, kind, default=default, annotation=empty))
2092
2093 # non-keyword-only parameters
2094 args = reversed(f.args.args)
2095 defaults = reversed(f.args.defaults)
2096 iter = itertools.zip_longest(args, defaults, fillvalue=None)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002097 if last_positional_only is not None:
2098 kind = Parameter.POSITIONAL_ONLY
2099 else:
2100 kind = Parameter.POSITIONAL_OR_KEYWORD
2101 for i, (name, default) in enumerate(reversed(list(iter))):
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002102 p(name, default)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002103 if i == last_positional_only:
2104 kind = Parameter.POSITIONAL_OR_KEYWORD
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002105
2106 # *args
2107 if f.args.vararg:
2108 kind = Parameter.VAR_POSITIONAL
2109 p(f.args.vararg, empty)
2110
2111 # keyword-only arguments
2112 kind = Parameter.KEYWORD_ONLY
2113 for name, default in zip(f.args.kwonlyargs, f.args.kw_defaults):
2114 p(name, default)
2115
2116 # **kwargs
2117 if f.args.kwarg:
2118 kind = Parameter.VAR_KEYWORD
2119 p(f.args.kwarg, empty)
2120
Larry Hastings2623c8c2014-02-08 22:15:29 -08002121 if self_parameter is not None:
Yury Selivanov8c185ee2014-02-21 01:32:42 -05002122 # Possibly strip the bound argument:
2123 # - We *always* strip first bound argument if
2124 # it is a module.
2125 # - We don't strip first bound argument if
2126 # skip_bound_arg is False.
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002127 assert parameters
Yury Selivanov8c185ee2014-02-21 01:32:42 -05002128 _self = getattr(obj, '__self__', None)
2129 self_isbound = _self is not None
2130 self_ismodule = ismodule(_self)
2131 if self_isbound and (self_ismodule or skip_bound_arg):
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002132 parameters.pop(0)
2133 else:
2134 # for builtins, self parameter is always positional-only!
2135 p = parameters[0].replace(kind=Parameter.POSITIONAL_ONLY)
2136 parameters[0] = p
2137
2138 return cls(parameters, return_annotation=cls.empty)
2139
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002140def _get_type_hints(func, **kwargs):
Batuhan Taskaya044a1042020-10-06 23:03:02 +03002141 try:
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002142 return typing.get_type_hints(func, **kwargs)
Batuhan Taskaya044a1042020-10-06 23:03:02 +03002143 except Exception:
2144 # First, try to use the get_type_hints to resolve
2145 # annotations. But for keeping the behavior intact
2146 # if there was a problem with that (like the namespace
2147 # can't resolve some annotation) continue to use
2148 # string annotations
2149 return func.__annotations__
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002150
Yury Selivanov57d240e2014-02-19 16:27:23 -05002151def _signature_from_builtin(cls, func, skip_bound_arg=True):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002152 """Private helper function to get signature for
2153 builtin callables.
2154 """
2155
Yury Selivanov57d240e2014-02-19 16:27:23 -05002156 if not _signature_is_builtin(func):
2157 raise TypeError("{!r} is not a Python builtin "
2158 "function".format(func))
2159
2160 s = getattr(func, "__text_signature__", None)
2161 if not s:
2162 raise ValueError("no signature found for builtin {!r}".format(func))
2163
2164 return _signature_fromstr(cls, func, s, skip_bound_arg)
2165
2166
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002167def _signature_from_function(cls, func, skip_bound_arg=True,
2168 globalns=None, localns=None):
Yury Selivanovcf45f022015-05-20 14:38:50 -04002169 """Private helper: constructs Signature for the given python function."""
2170
2171 is_duck_function = False
2172 if not isfunction(func):
2173 if _signature_is_functionlike(func):
2174 is_duck_function = True
2175 else:
2176 # If it's not a pure Python function, and not a duck type
2177 # of pure function:
2178 raise TypeError('{!r} is not a Python function'.format(func))
2179
Serhiy Storchakad53cf992019-05-06 22:40:27 +03002180 s = getattr(func, "__text_signature__", None)
2181 if s:
2182 return _signature_fromstr(cls, func, s, skip_bound_arg)
2183
Yury Selivanovcf45f022015-05-20 14:38:50 -04002184 Parameter = cls._parameter_cls
2185
2186 # Parameter information.
2187 func_code = func.__code__
2188 pos_count = func_code.co_argcount
2189 arg_names = func_code.co_varnames
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002190 posonly_count = func_code.co_posonlyargcount
Pablo Galindocd74e662019-06-01 18:08:04 +01002191 positional = arg_names[:pos_count]
Yury Selivanovcf45f022015-05-20 14:38:50 -04002192 keyword_only_count = func_code.co_kwonlyargcount
Pablo Galindocd74e662019-06-01 18:08:04 +01002193 keyword_only = arg_names[pos_count:pos_count + keyword_only_count]
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002194 annotations = _get_type_hints(func, globalns=globalns, localns=localns)
Batuhan Taskaya044a1042020-10-06 23:03:02 +03002195
Yury Selivanovcf45f022015-05-20 14:38:50 -04002196 defaults = func.__defaults__
2197 kwdefaults = func.__kwdefaults__
2198
2199 if defaults:
2200 pos_default_count = len(defaults)
2201 else:
2202 pos_default_count = 0
2203
2204 parameters = []
2205
Pablo Galindocd74e662019-06-01 18:08:04 +01002206 non_default_count = pos_count - pos_default_count
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002207 posonly_left = posonly_count
2208
Yury Selivanovcf45f022015-05-20 14:38:50 -04002209 # Non-keyword-only parameters w/o defaults.
Pablo Galindocd74e662019-06-01 18:08:04 +01002210 for name in positional[:non_default_count]:
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002211 kind = _POSITIONAL_ONLY if posonly_left else _POSITIONAL_OR_KEYWORD
Yury Selivanovcf45f022015-05-20 14:38:50 -04002212 annotation = annotations.get(name, _empty)
2213 parameters.append(Parameter(name, annotation=annotation,
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002214 kind=kind))
2215 if posonly_left:
2216 posonly_left -= 1
Yury Selivanovcf45f022015-05-20 14:38:50 -04002217
2218 # ... w/ defaults.
Pablo Galindocd74e662019-06-01 18:08:04 +01002219 for offset, name in enumerate(positional[non_default_count:]):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002220 kind = _POSITIONAL_ONLY if posonly_left else _POSITIONAL_OR_KEYWORD
Yury Selivanovcf45f022015-05-20 14:38:50 -04002221 annotation = annotations.get(name, _empty)
2222 parameters.append(Parameter(name, annotation=annotation,
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002223 kind=kind,
Yury Selivanovcf45f022015-05-20 14:38:50 -04002224 default=defaults[offset]))
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002225 if posonly_left:
2226 posonly_left -= 1
Yury Selivanovcf45f022015-05-20 14:38:50 -04002227
2228 # *args
2229 if func_code.co_flags & CO_VARARGS:
Pablo Galindocd74e662019-06-01 18:08:04 +01002230 name = arg_names[pos_count + keyword_only_count]
Yury Selivanovcf45f022015-05-20 14:38:50 -04002231 annotation = annotations.get(name, _empty)
2232 parameters.append(Parameter(name, annotation=annotation,
2233 kind=_VAR_POSITIONAL))
2234
2235 # Keyword-only parameters.
2236 for name in keyword_only:
2237 default = _empty
2238 if kwdefaults is not None:
2239 default = kwdefaults.get(name, _empty)
2240
2241 annotation = annotations.get(name, _empty)
2242 parameters.append(Parameter(name, annotation=annotation,
2243 kind=_KEYWORD_ONLY,
2244 default=default))
2245 # **kwargs
2246 if func_code.co_flags & CO_VARKEYWORDS:
Pablo Galindocd74e662019-06-01 18:08:04 +01002247 index = pos_count + keyword_only_count
Yury Selivanovcf45f022015-05-20 14:38:50 -04002248 if func_code.co_flags & CO_VARARGS:
2249 index += 1
2250
2251 name = arg_names[index]
2252 annotation = annotations.get(name, _empty)
2253 parameters.append(Parameter(name, annotation=annotation,
2254 kind=_VAR_KEYWORD))
2255
2256 # Is 'func' is a pure Python function - don't validate the
2257 # parameters list (for correct order and defaults), it should be OK.
2258 return cls(parameters,
2259 return_annotation=annotations.get('return', _empty),
2260 __validate_parameters__=is_duck_function)
2261
2262
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002263def _signature_from_callable(obj, *,
2264 follow_wrapper_chains=True,
2265 skip_bound_arg=True,
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002266 globalns=None,
2267 localns=None,
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002268 sigcls):
2269
2270 """Private helper function to get signature for arbitrary
2271 callable objects.
2272 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002273
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002274 _get_signature_of = functools.partial(_signature_from_callable,
2275 follow_wrapper_chains=follow_wrapper_chains,
2276 skip_bound_arg=skip_bound_arg,
2277 globalns=globalns,
2278 localns=localns,
2279 sigcls=sigcls)
2280
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002281 if not callable(obj):
2282 raise TypeError('{!r} is not a callable object'.format(obj))
2283
2284 if isinstance(obj, types.MethodType):
2285 # In this case we skip the first parameter of the underlying
2286 # function (usually `self` or `cls`).
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002287 sig = _get_signature_of(obj.__func__)
Yury Selivanovda396452014-03-27 12:09:24 -04002288
Yury Selivanov57d240e2014-02-19 16:27:23 -05002289 if skip_bound_arg:
2290 return _signature_bound_method(sig)
2291 else:
2292 return sig
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002293
Nick Coghlane8c45d62013-07-28 20:00:01 +10002294 # Was this function wrapped by a decorator?
Yury Selivanov57d240e2014-02-19 16:27:23 -05002295 if follow_wrapper_chains:
2296 obj = unwrap(obj, stop=(lambda f: hasattr(f, "__signature__")))
Yury Selivanov46c759d2015-05-27 21:56:53 -04002297 if isinstance(obj, types.MethodType):
2298 # If the unwrapped object is a *method*, we might want to
2299 # skip its first parameter (self).
2300 # See test_signature_wrapped_bound_method for details.
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002301 return _get_signature_of(obj)
Nick Coghlane8c45d62013-07-28 20:00:01 +10002302
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002303 try:
2304 sig = obj.__signature__
2305 except AttributeError:
2306 pass
2307 else:
2308 if sig is not None:
Yury Selivanov42407ab2014-06-23 10:23:50 -07002309 if not isinstance(sig, Signature):
2310 raise TypeError(
2311 'unexpected object {!r} in __signature__ '
2312 'attribute'.format(sig))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002313 return sig
2314
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002315 try:
2316 partialmethod = obj._partialmethod
2317 except AttributeError:
2318 pass
2319 else:
Yury Selivanov0486f812014-01-29 12:18:59 -05002320 if isinstance(partialmethod, functools.partialmethod):
2321 # Unbound partialmethod (see functools.partialmethod)
2322 # This means, that we need to calculate the signature
2323 # as if it's a regular partial object, but taking into
2324 # account that the first positional argument
2325 # (usually `self`, or `cls`) will not be passed
2326 # automatically (as for boundmethods)
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002327
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002328 wrapped_sig = _get_signature_of(partialmethod.func)
Yury Selivanovda396452014-03-27 12:09:24 -04002329
Yury Selivanov0486f812014-01-29 12:18:59 -05002330 sig = _signature_get_partial(wrapped_sig, partialmethod, (None,))
Yury Selivanov0486f812014-01-29 12:18:59 -05002331 first_wrapped_param = tuple(wrapped_sig.parameters.values())[0]
Dong-hee Na378d7062017-05-18 04:00:51 +09002332 if first_wrapped_param.kind is Parameter.VAR_POSITIONAL:
2333 # First argument of the wrapped callable is `*args`, as in
2334 # `partialmethod(lambda *args)`.
2335 return sig
2336 else:
2337 sig_params = tuple(sig.parameters.values())
Yury Selivanov8a387212018-03-06 12:59:45 -05002338 assert (not sig_params or
2339 first_wrapped_param is not sig_params[0])
Dong-hee Na378d7062017-05-18 04:00:51 +09002340 new_params = (first_wrapped_param,) + sig_params
2341 return sig.replace(parameters=new_params)
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002342
Yury Selivanov63da7c72014-01-31 14:48:37 -05002343 if isfunction(obj) or _signature_is_functionlike(obj):
2344 # If it's a pure Python function, or an object that is duck type
2345 # of a Python function (Cython functions, for instance), then:
Serhiy Storchakad53cf992019-05-06 22:40:27 +03002346 return _signature_from_function(sigcls, obj,
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002347 skip_bound_arg=skip_bound_arg,
2348 globalns=globalns, localns=localns)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002349
Yury Selivanova773de02014-02-21 18:30:53 -05002350 if _signature_is_builtin(obj):
Yury Selivanovda396452014-03-27 12:09:24 -04002351 return _signature_from_builtin(sigcls, obj,
Yury Selivanova773de02014-02-21 18:30:53 -05002352 skip_bound_arg=skip_bound_arg)
2353
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002354 if isinstance(obj, functools.partial):
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002355 wrapped_sig = _get_signature_of(obj.func)
Yury Selivanov62560fb2014-01-28 12:26:24 -05002356 return _signature_get_partial(wrapped_sig, obj)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002357
2358 sig = None
2359 if isinstance(obj, type):
2360 # obj is a class or a metaclass
2361
2362 # First, let's see if it has an overloaded __call__ defined
2363 # in its metaclass
Yury Selivanov421f0c72014-01-29 12:05:40 -05002364 call = _signature_get_user_defined_method(type(obj), '__call__')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002365 if call is not None:
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002366 sig = _get_signature_of(call)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002367 else:
2368 # Now we check if the 'obj' class has a '__new__' method
Yury Selivanov421f0c72014-01-29 12:05:40 -05002369 new = _signature_get_user_defined_method(obj, '__new__')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002370 if new is not None:
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002371 sig = _get_signature_of(new)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002372 else:
2373 # Finally, we should have at least __init__ implemented
Yury Selivanov421f0c72014-01-29 12:05:40 -05002374 init = _signature_get_user_defined_method(obj, '__init__')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002375 if init is not None:
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002376 sig = _get_signature_of(init)
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002377
2378 if sig is None:
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002379 # At this point we know, that `obj` is a class, with no user-
2380 # defined '__init__', '__new__', or class-level '__call__'
2381
Larry Hastings2623c8c2014-02-08 22:15:29 -08002382 for base in obj.__mro__[:-1]:
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002383 # Since '__text_signature__' is implemented as a
2384 # descriptor that extracts text signature from the
2385 # class docstring, if 'obj' is derived from a builtin
2386 # class, its own '__text_signature__' may be 'None'.
Larry Hastings2623c8c2014-02-08 22:15:29 -08002387 # Therefore, we go through the MRO (except the last
2388 # class in there, which is 'object') to find the first
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002389 # class with non-empty text signature.
2390 try:
2391 text_sig = base.__text_signature__
2392 except AttributeError:
2393 pass
2394 else:
2395 if text_sig:
2396 # If 'obj' class has a __text_signature__ attribute:
2397 # return a signature based on it
Yury Selivanovda396452014-03-27 12:09:24 -04002398 return _signature_fromstr(sigcls, obj, text_sig)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002399
2400 # No '__text_signature__' was found for the 'obj' class.
2401 # Last option is to check if its '__init__' is
2402 # object.__init__ or type.__init__.
Larry Hastings2623c8c2014-02-08 22:15:29 -08002403 if type not in obj.__mro__:
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002404 # We have a class (not metaclass), but no user-defined
2405 # __init__ or __new__ for it
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002406 if (obj.__init__ is object.__init__ and
2407 obj.__new__ is object.__new__):
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002408 # Return a signature of 'object' builtin.
Gregory P. Smith5b9ff7a2019-09-13 17:13:51 +01002409 return sigcls.from_callable(object)
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002410 else:
2411 raise ValueError(
2412 'no signature found for builtin type {!r}'.format(obj))
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002413
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002414 elif not isinstance(obj, _NonUserDefinedCallables):
2415 # An object with __call__
2416 # We also check that the 'obj' is not an instance of
2417 # _WrapperDescriptor or _MethodWrapper to avoid
2418 # infinite recursion (and even potential segfault)
Yury Selivanov421f0c72014-01-29 12:05:40 -05002419 call = _signature_get_user_defined_method(type(obj), '__call__')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002420 if call is not None:
Larry Hastings2623c8c2014-02-08 22:15:29 -08002421 try:
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002422 sig = _get_signature_of(call)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002423 except ValueError as ex:
2424 msg = 'no signature found for {!r}'.format(obj)
2425 raise ValueError(msg) from ex
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002426
2427 if sig is not None:
2428 # For classes and objects we skip the first parameter of their
2429 # __call__, __new__, or __init__ methods
Yury Selivanov57d240e2014-02-19 16:27:23 -05002430 if skip_bound_arg:
2431 return _signature_bound_method(sig)
2432 else:
2433 return sig
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002434
2435 if isinstance(obj, types.BuiltinFunctionType):
2436 # Raise a nicer error message for builtins
2437 msg = 'no signature found for builtin function {!r}'.format(obj)
2438 raise ValueError(msg)
2439
2440 raise ValueError('callable {!r} is not supported by signature'.format(obj))
2441
2442
2443class _void:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002444 """A private marker - used in Parameter & Signature."""
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002445
2446
2447class _empty:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002448 """Marker object for Signature.empty and Parameter.empty."""
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002449
2450
Yury Selivanov21e83a52014-03-27 11:23:13 -04002451class _ParameterKind(enum.IntEnum):
2452 POSITIONAL_ONLY = 0
2453 POSITIONAL_OR_KEYWORD = 1
2454 VAR_POSITIONAL = 2
2455 KEYWORD_ONLY = 3
2456 VAR_KEYWORD = 4
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002457
2458 def __str__(self):
Yury Selivanov21e83a52014-03-27 11:23:13 -04002459 return self._name_
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002460
Dong-hee Na4aa30062018-06-08 12:46:31 +09002461 @property
2462 def description(self):
2463 return _PARAM_NAME_MAPPING[self]
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002464
Yury Selivanov21e83a52014-03-27 11:23:13 -04002465_POSITIONAL_ONLY = _ParameterKind.POSITIONAL_ONLY
2466_POSITIONAL_OR_KEYWORD = _ParameterKind.POSITIONAL_OR_KEYWORD
2467_VAR_POSITIONAL = _ParameterKind.VAR_POSITIONAL
2468_KEYWORD_ONLY = _ParameterKind.KEYWORD_ONLY
2469_VAR_KEYWORD = _ParameterKind.VAR_KEYWORD
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002470
Dong-hee Naa9cab432018-05-30 00:04:08 +09002471_PARAM_NAME_MAPPING = {
2472 _POSITIONAL_ONLY: 'positional-only',
2473 _POSITIONAL_OR_KEYWORD: 'positional or keyword',
2474 _VAR_POSITIONAL: 'variadic positional',
2475 _KEYWORD_ONLY: 'keyword-only',
2476 _VAR_KEYWORD: 'variadic keyword'
2477}
2478
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002479
2480class Parameter:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002481 """Represents a parameter in a function signature.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002482
2483 Has the following public attributes:
2484
2485 * name : str
2486 The name of the parameter as a string.
2487 * default : object
2488 The default value for the parameter if specified. If the
Yury Selivanov8757ead2014-01-28 16:39:25 -05002489 parameter has no default value, this attribute is set to
2490 `Parameter.empty`.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002491 * annotation
2492 The annotation for the parameter if specified. If the
Yury Selivanov8757ead2014-01-28 16:39:25 -05002493 parameter has no annotation, this attribute is set to
2494 `Parameter.empty`.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002495 * kind : str
2496 Describes how argument values are bound to the parameter.
2497 Possible values: `Parameter.POSITIONAL_ONLY`,
2498 `Parameter.POSITIONAL_OR_KEYWORD`, `Parameter.VAR_POSITIONAL`,
2499 `Parameter.KEYWORD_ONLY`, `Parameter.VAR_KEYWORD`.
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002500 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002501
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002502 __slots__ = ('_name', '_kind', '_default', '_annotation')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002503
2504 POSITIONAL_ONLY = _POSITIONAL_ONLY
2505 POSITIONAL_OR_KEYWORD = _POSITIONAL_OR_KEYWORD
2506 VAR_POSITIONAL = _VAR_POSITIONAL
2507 KEYWORD_ONLY = _KEYWORD_ONLY
2508 VAR_KEYWORD = _VAR_KEYWORD
2509
2510 empty = _empty
2511
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002512 def __init__(self, name, kind, *, default=_empty, annotation=_empty):
Dong-hee Naa9cab432018-05-30 00:04:08 +09002513 try:
2514 self._kind = _ParameterKind(kind)
2515 except ValueError:
2516 raise ValueError(f'value {kind!r} is not a valid Parameter.kind')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002517 if default is not _empty:
Dong-hee Naa9cab432018-05-30 00:04:08 +09002518 if self._kind in (_VAR_POSITIONAL, _VAR_KEYWORD):
2519 msg = '{} parameters cannot have default values'
Dong-hee Na4aa30062018-06-08 12:46:31 +09002520 msg = msg.format(self._kind.description)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002521 raise ValueError(msg)
2522 self._default = default
2523 self._annotation = annotation
2524
Yury Selivanov2393dca2014-01-27 15:07:58 -05002525 if name is _empty:
2526 raise ValueError('name is a required attribute for Parameter')
2527
2528 if not isinstance(name, str):
Dong-hee Naa9cab432018-05-30 00:04:08 +09002529 msg = 'name must be a str, not a {}'.format(type(name).__name__)
2530 raise TypeError(msg)
Yury Selivanov2393dca2014-01-27 15:07:58 -05002531
Nick Coghlanb4b966e2016-06-04 14:40:03 -07002532 if name[0] == '.' and name[1:].isdigit():
2533 # These are implicit arguments generated by comprehensions. In
2534 # order to provide a friendlier interface to users, we recast
2535 # their name as "implicitN" and treat them as positional-only.
2536 # See issue 19611.
Dong-hee Naa9cab432018-05-30 00:04:08 +09002537 if self._kind != _POSITIONAL_OR_KEYWORD:
2538 msg = (
2539 'implicit arguments must be passed as '
2540 'positional or keyword arguments, not {}'
Nick Coghlanb4b966e2016-06-04 14:40:03 -07002541 )
Dong-hee Na4aa30062018-06-08 12:46:31 +09002542 msg = msg.format(self._kind.description)
Dong-hee Naa9cab432018-05-30 00:04:08 +09002543 raise ValueError(msg)
Nick Coghlanb4b966e2016-06-04 14:40:03 -07002544 self._kind = _POSITIONAL_ONLY
2545 name = 'implicit{}'.format(name[1:])
2546
Yury Selivanov2393dca2014-01-27 15:07:58 -05002547 if not name.isidentifier():
2548 raise ValueError('{!r} is not a valid parameter name'.format(name))
2549
2550 self._name = name
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002551
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002552 def __reduce__(self):
2553 return (type(self),
2554 (self._name, self._kind),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002555 {'_default': self._default,
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002556 '_annotation': self._annotation})
2557
2558 def __setstate__(self, state):
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002559 self._default = state['_default']
2560 self._annotation = state['_annotation']
2561
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002562 @property
2563 def name(self):
2564 return self._name
2565
2566 @property
2567 def default(self):
2568 return self._default
2569
2570 @property
2571 def annotation(self):
2572 return self._annotation
2573
2574 @property
2575 def kind(self):
2576 return self._kind
2577
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002578 def replace(self, *, name=_void, kind=_void,
2579 annotation=_void, default=_void):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002580 """Creates a customized copy of the Parameter."""
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002581
2582 if name is _void:
2583 name = self._name
2584
2585 if kind is _void:
2586 kind = self._kind
2587
2588 if annotation is _void:
2589 annotation = self._annotation
2590
2591 if default is _void:
2592 default = self._default
2593
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002594 return type(self)(name, kind, default=default, annotation=annotation)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002595
2596 def __str__(self):
2597 kind = self.kind
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002598 formatted = self._name
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002599
2600 # Add annotation and default value
2601 if self._annotation is not _empty:
Dong-hee Na762b9572017-11-16 03:30:59 +09002602 formatted = '{}: {}'.format(formatted,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002603 formatannotation(self._annotation))
2604
2605 if self._default is not _empty:
Dong-hee Na762b9572017-11-16 03:30:59 +09002606 if self._annotation is not _empty:
2607 formatted = '{} = {}'.format(formatted, repr(self._default))
2608 else:
2609 formatted = '{}={}'.format(formatted, repr(self._default))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002610
2611 if kind == _VAR_POSITIONAL:
2612 formatted = '*' + formatted
2613 elif kind == _VAR_KEYWORD:
2614 formatted = '**' + formatted
2615
2616 return formatted
2617
2618 def __repr__(self):
Yury Selivanovf229bc52015-05-15 12:53:56 -04002619 return '<{} "{}">'.format(self.__class__.__name__, self)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002620
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002621 def __hash__(self):
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002622 return hash((self.name, self.kind, self.annotation, self.default))
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002623
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002624 def __eq__(self, other):
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03002625 if self is other:
2626 return True
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002627 if not isinstance(other, Parameter):
2628 return NotImplemented
2629 return (self._name == other._name and
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002630 self._kind == other._kind and
2631 self._default == other._default and
2632 self._annotation == other._annotation)
2633
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002634
2635class BoundArguments:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002636 """Result of `Signature.bind` call. Holds the mapping of arguments
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002637 to the function's parameters.
2638
2639 Has the following public attributes:
2640
RĂ©mi Lapeyre2cca8ef2020-01-28 13:47:03 +01002641 * arguments : dict
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002642 An ordered mutable mapping of parameters' names to arguments' values.
2643 Does not contain arguments' default values.
2644 * signature : Signature
2645 The Signature object that created this instance.
2646 * args : tuple
2647 Tuple of positional arguments values.
2648 * kwargs : dict
2649 Dict of keyword arguments values.
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002650 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002651
Yury Selivanov6abe0322015-05-13 17:18:41 -04002652 __slots__ = ('arguments', '_signature', '__weakref__')
2653
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002654 def __init__(self, signature, arguments):
2655 self.arguments = arguments
2656 self._signature = signature
2657
2658 @property
2659 def signature(self):
2660 return self._signature
2661
2662 @property
2663 def args(self):
2664 args = []
2665 for param_name, param in self._signature.parameters.items():
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002666 if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002667 break
2668
2669 try:
2670 arg = self.arguments[param_name]
2671 except KeyError:
2672 # We're done here. Other arguments
2673 # will be mapped in 'BoundArguments.kwargs'
2674 break
2675 else:
2676 if param.kind == _VAR_POSITIONAL:
2677 # *args
2678 args.extend(arg)
2679 else:
2680 # plain argument
2681 args.append(arg)
2682
2683 return tuple(args)
2684
2685 @property
2686 def kwargs(self):
2687 kwargs = {}
2688 kwargs_started = False
2689 for param_name, param in self._signature.parameters.items():
2690 if not kwargs_started:
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002691 if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002692 kwargs_started = True
2693 else:
2694 if param_name not in self.arguments:
2695 kwargs_started = True
2696 continue
2697
2698 if not kwargs_started:
2699 continue
2700
2701 try:
2702 arg = self.arguments[param_name]
2703 except KeyError:
2704 pass
2705 else:
2706 if param.kind == _VAR_KEYWORD:
2707 # **kwargs
2708 kwargs.update(arg)
2709 else:
2710 # plain keyword argument
2711 kwargs[param_name] = arg
2712
2713 return kwargs
2714
Yury Selivanovb907a512015-05-16 13:45:09 -04002715 def apply_defaults(self):
2716 """Set default values for missing arguments.
2717
2718 For variable-positional arguments (*args) the default is an
2719 empty tuple.
2720
2721 For variable-keyword arguments (**kwargs) the default is an
2722 empty dict.
2723 """
2724 arguments = self.arguments
Yury Selivanovb907a512015-05-16 13:45:09 -04002725 new_arguments = []
2726 for name, param in self._signature.parameters.items():
2727 try:
2728 new_arguments.append((name, arguments[name]))
2729 except KeyError:
2730 if param.default is not _empty:
2731 val = param.default
2732 elif param.kind is _VAR_POSITIONAL:
2733 val = ()
2734 elif param.kind is _VAR_KEYWORD:
2735 val = {}
2736 else:
2737 # This BoundArguments was likely produced by
2738 # Signature.bind_partial().
2739 continue
2740 new_arguments.append((name, val))
RĂ©mi Lapeyre2cca8ef2020-01-28 13:47:03 +01002741 self.arguments = dict(new_arguments)
Yury Selivanovb907a512015-05-16 13:45:09 -04002742
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002743 def __eq__(self, other):
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03002744 if self is other:
2745 return True
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002746 if not isinstance(other, BoundArguments):
2747 return NotImplemented
2748 return (self.signature == other.signature and
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002749 self.arguments == other.arguments)
2750
Yury Selivanov6abe0322015-05-13 17:18:41 -04002751 def __setstate__(self, state):
2752 self._signature = state['_signature']
2753 self.arguments = state['arguments']
2754
2755 def __getstate__(self):
2756 return {'_signature': self._signature, 'arguments': self.arguments}
2757
Yury Selivanov3f6538f2015-05-14 18:47:17 -04002758 def __repr__(self):
2759 args = []
2760 for arg, value in self.arguments.items():
2761 args.append('{}={!r}'.format(arg, value))
Yury Selivanovf229bc52015-05-15 12:53:56 -04002762 return '<{} ({})>'.format(self.__class__.__name__, ', '.join(args))
Yury Selivanov3f6538f2015-05-14 18:47:17 -04002763
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002764
2765class Signature:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002766 """A Signature object represents the overall signature of a function.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002767 It stores a Parameter object for each parameter accepted by the
2768 function, as well as information specific to the function itself.
2769
2770 A Signature object has the following public attributes and methods:
2771
Jens Reidel611836a2020-03-18 03:22:46 +01002772 * parameters : OrderedDict
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002773 An ordered mapping of parameters' names to the corresponding
2774 Parameter objects (keyword-only arguments are in the same order
2775 as listed in `code.co_varnames`).
2776 * return_annotation : object
2777 The annotation for the return type of the function if specified.
2778 If the function has no annotation for its return type, this
Yury Selivanov8757ead2014-01-28 16:39:25 -05002779 attribute is set to `Signature.empty`.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002780 * bind(*args, **kwargs) -> BoundArguments
2781 Creates a mapping from positional and keyword arguments to
2782 parameters.
2783 * bind_partial(*args, **kwargs) -> BoundArguments
2784 Creates a partial mapping from positional and keyword arguments
2785 to parameters (simulating 'functools.partial' behavior.)
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002786 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002787
2788 __slots__ = ('_return_annotation', '_parameters')
2789
2790 _parameter_cls = Parameter
2791 _bound_arguments_cls = BoundArguments
2792
2793 empty = _empty
2794
2795 def __init__(self, parameters=None, *, return_annotation=_empty,
2796 __validate_parameters__=True):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002797 """Constructs Signature from the given list of Parameter
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002798 objects and 'return_annotation'. All arguments are optional.
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002799 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002800
2801 if parameters is None:
Jens Reidel611836a2020-03-18 03:22:46 +01002802 params = OrderedDict()
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002803 else:
2804 if __validate_parameters__:
Jens Reidel611836a2020-03-18 03:22:46 +01002805 params = OrderedDict()
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002806 top_kind = _POSITIONAL_ONLY
Yury Selivanov07a9e452014-01-29 10:58:16 -05002807 kind_defaults = False
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002808
RĂ©mi Lapeyre2cca8ef2020-01-28 13:47:03 +01002809 for param in parameters:
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002810 kind = param.kind
Yury Selivanov2393dca2014-01-27 15:07:58 -05002811 name = param.name
2812
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002813 if kind < top_kind:
Dong-hee Naa9cab432018-05-30 00:04:08 +09002814 msg = (
2815 'wrong parameter order: {} parameter before {} '
2816 'parameter'
2817 )
Dong-hee Na4aa30062018-06-08 12:46:31 +09002818 msg = msg.format(top_kind.description,
2819 kind.description)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002820 raise ValueError(msg)
Yury Selivanov07a9e452014-01-29 10:58:16 -05002821 elif kind > top_kind:
2822 kind_defaults = False
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002823 top_kind = kind
2824
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002825 if kind in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD):
Yury Selivanov07a9e452014-01-29 10:58:16 -05002826 if param.default is _empty:
2827 if kind_defaults:
2828 # No default for this parameter, but the
2829 # previous parameter of the same kind had
2830 # a default
2831 msg = 'non-default argument follows default ' \
2832 'argument'
2833 raise ValueError(msg)
2834 else:
2835 # There is a default for this parameter.
2836 kind_defaults = True
2837
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002838 if name in params:
2839 msg = 'duplicate parameter name: {!r}'.format(name)
2840 raise ValueError(msg)
Yury Selivanov2393dca2014-01-27 15:07:58 -05002841
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002842 params[name] = param
2843 else:
Jens Reidel611836a2020-03-18 03:22:46 +01002844 params = OrderedDict((param.name, param) for param in parameters)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002845
2846 self._parameters = types.MappingProxyType(params)
2847 self._return_annotation = return_annotation
2848
2849 @classmethod
2850 def from_function(cls, func):
Matthias Bussonnierded87d82018-10-19 16:40:45 -07002851 """Constructs Signature for the given python function.
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002852
Matthias Bussonnierded87d82018-10-19 16:40:45 -07002853 Deprecated since Python 3.5, use `Signature.from_callable()`.
2854 """
2855
2856 warnings.warn("inspect.Signature.from_function() is deprecated since "
2857 "Python 3.5, use Signature.from_callable()",
Berker Peksagb5601582015-05-21 23:40:54 +03002858 DeprecationWarning, stacklevel=2)
Yury Selivanovcf45f022015-05-20 14:38:50 -04002859 return _signature_from_function(cls, func)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002860
Larry Hastings44e2eaa2013-11-23 15:37:55 -08002861 @classmethod
2862 def from_builtin(cls, func):
Matthias Bussonnierded87d82018-10-19 16:40:45 -07002863 """Constructs Signature for the given builtin function.
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002864
Matthias Bussonnierded87d82018-10-19 16:40:45 -07002865 Deprecated since Python 3.5, use `Signature.from_callable()`.
2866 """
2867
2868 warnings.warn("inspect.Signature.from_builtin() is deprecated since "
2869 "Python 3.5, use Signature.from_callable()",
Berker Peksagb5601582015-05-21 23:40:54 +03002870 DeprecationWarning, stacklevel=2)
Yury Selivanov57d240e2014-02-19 16:27:23 -05002871 return _signature_from_builtin(cls, func)
Larry Hastings44e2eaa2013-11-23 15:37:55 -08002872
Yury Selivanovda396452014-03-27 12:09:24 -04002873 @classmethod
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002874 def from_callable(cls, obj, *,
2875 follow_wrapped=True, globalns=None, localns=None):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002876 """Constructs Signature for the given callable object."""
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002877 return _signature_from_callable(obj, sigcls=cls,
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002878 follow_wrapper_chains=follow_wrapped,
2879 globalns=globalns, localns=localns)
Yury Selivanovda396452014-03-27 12:09:24 -04002880
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002881 @property
2882 def parameters(self):
2883 return self._parameters
2884
2885 @property
2886 def return_annotation(self):
2887 return self._return_annotation
2888
2889 def replace(self, *, parameters=_void, return_annotation=_void):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002890 """Creates a customized copy of the Signature.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002891 Pass 'parameters' and/or 'return_annotation' arguments
2892 to override them in the new copy.
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002893 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002894
2895 if parameters is _void:
2896 parameters = self.parameters.values()
2897
2898 if return_annotation is _void:
2899 return_annotation = self._return_annotation
2900
2901 return type(self)(parameters,
2902 return_annotation=return_annotation)
2903
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002904 def _hash_basis(self):
2905 params = tuple(param for param in self.parameters.values()
2906 if param.kind != _KEYWORD_ONLY)
2907
2908 kwo_params = {param.name: param for param in self.parameters.values()
2909 if param.kind == _KEYWORD_ONLY}
2910
2911 return params, kwo_params, self.return_annotation
2912
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002913 def __hash__(self):
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002914 params, kwo_params, return_annotation = self._hash_basis()
2915 kwo_params = frozenset(kwo_params.values())
2916 return hash((params, kwo_params, return_annotation))
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002917
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002918 def __eq__(self, other):
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03002919 if self is other:
2920 return True
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002921 if not isinstance(other, Signature):
2922 return NotImplemented
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03002923 return self._hash_basis() == other._hash_basis()
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002924
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002925 def _bind(self, args, kwargs, *, partial=False):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002926 """Private method. Don't use directly."""
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002927
RĂ©mi Lapeyre2cca8ef2020-01-28 13:47:03 +01002928 arguments = {}
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002929
2930 parameters = iter(self.parameters.values())
2931 parameters_ex = ()
2932 arg_vals = iter(args)
2933
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002934 while True:
2935 # Let's iterate through the positional arguments and corresponding
2936 # parameters
2937 try:
2938 arg_val = next(arg_vals)
2939 except StopIteration:
2940 # No more positional arguments
2941 try:
2942 param = next(parameters)
2943 except StopIteration:
2944 # No more parameters. That's it. Just need to check that
2945 # we have no `kwargs` after this while loop
2946 break
2947 else:
2948 if param.kind == _VAR_POSITIONAL:
2949 # That's OK, just empty *args. Let's start parsing
2950 # kwargs
2951 break
2952 elif param.name in kwargs:
2953 if param.kind == _POSITIONAL_ONLY:
2954 msg = '{arg!r} parameter is positional only, ' \
2955 'but was passed as a keyword'
2956 msg = msg.format(arg=param.name)
2957 raise TypeError(msg) from None
2958 parameters_ex = (param,)
2959 break
2960 elif (param.kind == _VAR_KEYWORD or
2961 param.default is not _empty):
2962 # That's fine too - we have a default value for this
2963 # parameter. So, lets start parsing `kwargs`, starting
2964 # with the current parameter
2965 parameters_ex = (param,)
2966 break
2967 else:
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05002968 # No default, not VAR_KEYWORD, not VAR_POSITIONAL,
2969 # not in `kwargs`
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002970 if partial:
2971 parameters_ex = (param,)
2972 break
2973 else:
Yury Selivanov86872752015-05-19 00:27:49 -04002974 msg = 'missing a required argument: {arg!r}'
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002975 msg = msg.format(arg=param.name)
2976 raise TypeError(msg) from None
2977 else:
2978 # We have a positional argument to process
2979 try:
2980 param = next(parameters)
2981 except StopIteration:
2982 raise TypeError('too many positional arguments') from None
2983 else:
2984 if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
2985 # Looks like we have no parameter for this positional
2986 # argument
Yury Selivanov86872752015-05-19 00:27:49 -04002987 raise TypeError(
2988 'too many positional arguments') from None
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002989
2990 if param.kind == _VAR_POSITIONAL:
2991 # We have an '*args'-like argument, let's fill it with
2992 # all positional arguments we have left and move on to
2993 # the next phase
2994 values = [arg_val]
2995 values.extend(arg_vals)
2996 arguments[param.name] = tuple(values)
2997 break
2998
Pablo Galindof3ef06a2019-10-15 12:40:02 +01002999 if param.name in kwargs and param.kind != _POSITIONAL_ONLY:
Yury Selivanov86872752015-05-19 00:27:49 -04003000 raise TypeError(
3001 'multiple values for argument {arg!r}'.format(
3002 arg=param.name)) from None
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003003
3004 arguments[param.name] = arg_val
3005
3006 # Now, we iterate through the remaining parameters to process
3007 # keyword arguments
3008 kwargs_param = None
3009 for param in itertools.chain(parameters_ex, parameters):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003010 if param.kind == _VAR_KEYWORD:
3011 # Memorize that we have a '**kwargs'-like parameter
3012 kwargs_param = param
3013 continue
3014
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003015 if param.kind == _VAR_POSITIONAL:
3016 # Named arguments don't refer to '*args'-like parameters.
3017 # We only arrive here if the positional arguments ended
3018 # before reaching the last parameter before *args.
3019 continue
3020
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003021 param_name = param.name
3022 try:
3023 arg_val = kwargs.pop(param_name)
3024 except KeyError:
3025 # We have no value for this parameter. It's fine though,
3026 # if it has a default value, or it is an '*args'-like
3027 # parameter, left alone by the processing of positional
3028 # arguments.
3029 if (not partial and param.kind != _VAR_POSITIONAL and
3030 param.default is _empty):
Yury Selivanov86872752015-05-19 00:27:49 -04003031 raise TypeError('missing a required argument: {arg!r}'. \
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003032 format(arg=param_name)) from None
3033
3034 else:
Yury Selivanov9b9ac952014-01-28 20:54:28 -05003035 if param.kind == _POSITIONAL_ONLY:
3036 # This should never happen in case of a properly built
3037 # Signature object (but let's have this check here
3038 # to ensure correct behaviour just in case)
3039 raise TypeError('{arg!r} parameter is positional only, '
3040 'but was passed as a keyword'. \
3041 format(arg=param.name))
3042
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003043 arguments[param_name] = arg_val
3044
3045 if kwargs:
3046 if kwargs_param is not None:
3047 # Process our '**kwargs'-like parameter
3048 arguments[kwargs_param.name] = kwargs
3049 else:
Yury Selivanov86872752015-05-19 00:27:49 -04003050 raise TypeError(
3051 'got an unexpected keyword argument {arg!r}'.format(
3052 arg=next(iter(kwargs))))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003053
3054 return self._bound_arguments_cls(self, arguments)
3055
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03003056 def bind(self, /, *args, **kwargs):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04003057 """Get a BoundArguments object, that maps the passed `args`
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003058 and `kwargs` to the function's signature. Raises `TypeError`
3059 if the passed arguments can not be bound.
Yury Selivanov5a23bd02014-03-29 13:47:11 -04003060 """
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03003061 return self._bind(args, kwargs)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003062
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03003063 def bind_partial(self, /, *args, **kwargs):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04003064 """Get a BoundArguments object, that partially maps the
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003065 passed `args` and `kwargs` to the function's signature.
3066 Raises `TypeError` if the passed arguments can not be bound.
Yury Selivanov5a23bd02014-03-29 13:47:11 -04003067 """
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03003068 return self._bind(args, kwargs, partial=True)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003069
Yury Selivanova5d63dd2014-03-27 11:31:43 -04003070 def __reduce__(self):
3071 return (type(self),
3072 (tuple(self._parameters.values()),),
3073 {'_return_annotation': self._return_annotation})
3074
3075 def __setstate__(self, state):
3076 self._return_annotation = state['_return_annotation']
3077
Yury Selivanov374375d2014-03-27 12:41:53 -04003078 def __repr__(self):
Yury Selivanovf229bc52015-05-15 12:53:56 -04003079 return '<{} {}>'.format(self.__class__.__name__, self)
Yury Selivanov374375d2014-03-27 12:41:53 -04003080
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003081 def __str__(self):
3082 result = []
Yury Selivanov2393dca2014-01-27 15:07:58 -05003083 render_pos_only_separator = False
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003084 render_kw_only_separator = True
Yury Selivanov2393dca2014-01-27 15:07:58 -05003085 for param in self.parameters.values():
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003086 formatted = str(param)
3087
3088 kind = param.kind
Yury Selivanov2393dca2014-01-27 15:07:58 -05003089
3090 if kind == _POSITIONAL_ONLY:
3091 render_pos_only_separator = True
3092 elif render_pos_only_separator:
3093 # It's not a positional-only parameter, and the flag
3094 # is set to 'True' (there were pos-only params before.)
3095 result.append('/')
3096 render_pos_only_separator = False
3097
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003098 if kind == _VAR_POSITIONAL:
3099 # OK, we have an '*args'-like parameter, so we won't need
3100 # a '*' to separate keyword-only arguments
3101 render_kw_only_separator = False
3102 elif kind == _KEYWORD_ONLY and render_kw_only_separator:
3103 # We have a keyword-only parameter to render and we haven't
3104 # rendered an '*args'-like parameter before, so add a '*'
3105 # separator to the parameters list ("foo(arg1, *, arg2)" case)
3106 result.append('*')
3107 # This condition should be only triggered once, so
3108 # reset the flag
3109 render_kw_only_separator = False
3110
3111 result.append(formatted)
3112
Yury Selivanov2393dca2014-01-27 15:07:58 -05003113 if render_pos_only_separator:
3114 # There were only positional-only parameters, hence the
3115 # flag was not reset to 'False'
3116 result.append('/')
3117
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003118 rendered = '({})'.format(', '.join(result))
3119
3120 if self.return_annotation is not _empty:
3121 anno = formatannotation(self.return_annotation)
3122 rendered += ' -> {}'.format(anno)
3123
3124 return rendered
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003125
Yury Selivanovda396452014-03-27 12:09:24 -04003126
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03003127def signature(obj, *, follow_wrapped=True, globalns=None, localns=None):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04003128 """Get a signature object for the passed callable."""
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03003129 return Signature.from_callable(obj, follow_wrapped=follow_wrapped,
3130 globalns=globalns, localns=localns)
Yury Selivanovda396452014-03-27 12:09:24 -04003131
3132
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003133def _main():
3134 """ Logic for inspecting an object given at command line """
3135 import argparse
3136 import importlib
3137
3138 parser = argparse.ArgumentParser()
3139 parser.add_argument(
3140 'object',
3141 help="The object to be analysed. "
3142 "It supports the 'module:qualname' syntax")
3143 parser.add_argument(
3144 '-d', '--details', action='store_true',
3145 help='Display info about the module rather than its source code')
3146
3147 args = parser.parse_args()
3148
3149 target = args.object
3150 mod_name, has_attrs, attrs = target.partition(":")
3151 try:
3152 obj = module = importlib.import_module(mod_name)
3153 except Exception as exc:
3154 msg = "Failed to import {} ({}: {})".format(mod_name,
3155 type(exc).__name__,
3156 exc)
3157 print(msg, file=sys.stderr)
Alan Yeee3c59a72019-09-09 07:15:43 -07003158 sys.exit(2)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003159
3160 if has_attrs:
3161 parts = attrs.split(".")
3162 obj = module
3163 for part in parts:
3164 obj = getattr(obj, part)
3165
3166 if module.__name__ in sys.builtin_module_names:
3167 print("Can't get info for builtin modules.", file=sys.stderr)
Alan Yeee3c59a72019-09-09 07:15:43 -07003168 sys.exit(1)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003169
3170 if args.details:
3171 print('Target: {}'.format(target))
3172 print('Origin: {}'.format(getsourcefile(module)))
3173 print('Cached: {}'.format(module.__cached__))
3174 if obj is module:
3175 print('Loader: {}'.format(repr(module.__loader__)))
3176 if hasattr(module, '__path__'):
3177 print('Submodule search path: {}'.format(module.__path__))
3178 else:
3179 try:
3180 __, lineno = findsource(obj)
3181 except Exception:
3182 pass
3183 else:
3184 print('Line: {}'.format(lineno))
3185
3186 print('\n')
3187 else:
3188 print(getsource(obj))
3189
3190
3191if __name__ == "__main__":
3192 _main()