blob: 9f8cc01310f10e323f2ef3b1301816308a5d2f40 [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
larryhastings74613a42021-04-29 21:16:28 -070027
28 get_annotations() - safely compute an object's annotations
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000029"""
30
31# This module is in the public domain. No warranties.
32
Larry Hastings7c7cbfc2012-06-22 15:19:35 -070033__author__ = ('Ka-Ping Yee <ping@lfw.org>',
34 'Yury Selivanov <yselivanov@sprymix.com>')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000035
Natefcfe80e2017-04-24 10:06:15 -070036import abc
Karthikeyan Singaravelan696136b2020-04-18 21:49:32 +053037import ast
Antoine Pitroua8723a02015-04-15 00:41:29 +020038import dis
Yury Selivanov75445082015-05-11 22:57:16 -040039import collections.abc
Yury Selivanov21e83a52014-03-27 11:23:13 -040040import enum
Brett Cannoncb66eb02012-05-11 12:58:42 -040041import importlib.machinery
42import itertools
Christian Heimes7131fd92008-02-19 14:21:46 +000043import linecache
Brett Cannoncb66eb02012-05-11 12:58:42 -040044import os
45import re
46import sys
47import tokenize
Larry Hastings2623c8c2014-02-08 22:15:29 -080048import token
Brett Cannoncb66eb02012-05-11 12:58:42 -040049import types
Brett Cannon2b88fcf2012-06-02 22:28:42 -040050import warnings
Larry Hastings7c7cbfc2012-06-22 15:19:35 -070051import functools
Nick Coghlan2f92e542012-06-23 19:39:55 +100052import builtins
Raymond Hettingera1a992c2005-03-11 06:46:45 +000053from operator import attrgetter
Inada Naoki21105512020-03-02 18:54:49 +090054from collections import namedtuple, OrderedDict
Nick Coghlan09c81232010-08-17 10:18:16 +000055
56# Create constants for the compiler flags in Include/code.h
Antoine Pitroua8723a02015-04-15 00:41:29 +020057# We try to get them from dis to avoid duplication
58mod_dict = globals()
59for k, v in dis.COMPILER_FLAG_NAMES.items():
60 mod_dict["CO_" + v] = k
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +000061
Christian Heimesbe5b30b2008-03-03 19:18:51 +000062# See Include/object.h
63TPFLAGS_IS_ABSTRACT = 1 << 20
64
larryhastings74613a42021-04-29 21:16:28 -070065
66def get_annotations(obj, *, globals=None, locals=None, eval_str=False):
67 """Compute the annotations dict for an object.
68
69 obj may be a callable, class, or module.
70 Passing in an object of any other type raises TypeError.
71
72 Returns a dict. get_annotations() returns a new dict every time
73 it's called; calling it twice on the same object will return two
74 different but equivalent dicts.
75
76 This function handles several details for you:
77
78 * If eval_str is true, values of type str will
79 be un-stringized using eval(). This is intended
80 for use with stringized annotations
81 ("from __future__ import annotations").
82 * If obj doesn't have an annotations dict, returns an
83 empty dict. (Functions and methods always have an
84 annotations dict; classes, modules, and other types of
85 callables may not.)
86 * Ignores inherited annotations on classes. If a class
87 doesn't have its own annotations dict, returns an empty dict.
88 * All accesses to object members and dict values are done
89 using getattr() and dict.get() for safety.
90 * Always, always, always returns a freshly-created dict.
91
92 eval_str controls whether or not values of type str are replaced
93 with the result of calling eval() on those values:
94
95 * If eval_str is true, eval() is called on values of type str.
96 * If eval_str is false (the default), values of type str are unchanged.
97
98 globals and locals are passed in to eval(); see the documentation
99 for eval() for more information. If either globals or locals is
100 None, this function may replace that value with a context-specific
101 default, contingent on type(obj):
102
103 * If obj is a module, globals defaults to obj.__dict__.
104 * If obj is a class, globals defaults to
105 sys.modules[obj.__module__].__dict__ and locals
106 defaults to the obj class namespace.
107 * If obj is a callable, globals defaults to obj.__globals__,
108 although if obj is a wrapped function (using
109 functools.update_wrapper()) it is first unwrapped.
110 """
111 if isinstance(obj, type):
112 # class
113 obj_dict = getattr(obj, '__dict__', None)
114 if obj_dict and hasattr(obj_dict, 'get'):
115 ann = obj_dict.get('__annotations__', None)
116 if isinstance(ann, types.GetSetDescriptorType):
117 ann = None
118 else:
119 ann = None
120
121 obj_globals = None
122 module_name = getattr(obj, '__module__', None)
123 if module_name:
124 module = sys.modules.get(module_name, None)
125 if module:
126 obj_globals = getattr(module, '__dict__', None)
127 obj_locals = dict(vars(obj))
128 unwrap = obj
129 elif isinstance(obj, types.ModuleType):
130 # module
131 ann = getattr(obj, '__annotations__', None)
132 obj_globals = getattr(obj, '__dict__')
133 obj_locals = None
134 unwrap = None
135 elif callable(obj):
136 # this includes types.Function, types.BuiltinFunctionType,
137 # types.BuiltinMethodType, functools.partial, functools.singledispatch,
138 # "class funclike" from Lib/test/test_inspect... on and on it goes.
139 ann = getattr(obj, '__annotations__', None)
140 obj_globals = getattr(obj, '__globals__', None)
141 obj_locals = None
142 unwrap = obj
143 else:
144 raise TypeError(f"{obj!r} is not a module, class, or callable.")
145
146 if ann is None:
147 return {}
148
149 if not isinstance(ann, dict):
150 raise ValueError(f"{obj!r}.__annotations__ is neither a dict nor None")
151
152 if not ann:
153 return {}
154
155 if not eval_str:
156 return dict(ann)
157
158 if unwrap is not None:
159 while True:
160 if hasattr(unwrap, '__wrapped__'):
161 unwrap = unwrap.__wrapped__
162 continue
163 if isinstance(unwrap, functools.partial):
164 unwrap = unwrap.func
165 continue
166 break
167 if hasattr(unwrap, "__globals__"):
168 obj_globals = unwrap.__globals__
169
170 if globals is None:
171 globals = obj_globals
172 if locals is None:
173 locals = obj_locals
174
175 return_value = {key:
176 value if not isinstance(value, str) else eval(value, globals, locals)
177 for key, value in ann.items() }
178 return return_value
179
180
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000181# ----------------------------------------------------------- type-checking
182def ismodule(object):
183 """Return true if the object is a module.
184
185 Module objects provide these attributes:
Barry Warsaw28a691b2010-04-17 00:19:56 +0000186 __cached__ pathname to byte compiled file
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000187 __doc__ documentation string
188 __file__ filename (missing for built-in modules)"""
Tim Peters28bc59f2001-09-16 08:40:16 +0000189 return isinstance(object, types.ModuleType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000190
191def isclass(object):
192 """Return true if the object is a class.
193
194 Class objects provide these attributes:
195 __doc__ documentation string
196 __module__ name of module in which this class was defined"""
Benjamin Petersonc4656002009-01-17 22:41:18 +0000197 return isinstance(object, type)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000198
199def ismethod(object):
200 """Return true if the object is an instance method.
201
202 Instance method objects provide these attributes:
203 __doc__ documentation string
204 __name__ name with which this method was defined
Christian Heimesff737952007-11-27 10:40:20 +0000205 __func__ function object containing implementation of method
206 __self__ instance to which this method is bound"""
Tim Peters28bc59f2001-09-16 08:40:16 +0000207 return isinstance(object, types.MethodType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000208
Tim Peters536d2262001-09-20 05:13:38 +0000209def ismethoddescriptor(object):
Tim Petersf1d90b92001-09-20 05:47:55 +0000210 """Return true if the object is a method descriptor.
211
212 But not if ismethod() or isclass() or isfunction() are true.
Tim Peters536d2262001-09-20 05:13:38 +0000213
214 This is new in Python 2.2, and, for example, is true of int.__add__.
215 An object passing this test has a __get__ attribute but not a __set__
216 attribute, but beyond that the set of attributes varies. __name__ is
217 usually sensible, and __doc__ often is.
218
Tim Petersf1d90b92001-09-20 05:47:55 +0000219 Methods implemented via descriptors that also pass one of the other
220 tests return false from the ismethoddescriptor() test, simply because
221 the other tests promise more -- you can, e.g., count on having the
Christian Heimesff737952007-11-27 10:40:20 +0000222 __func__ attribute (etc) when an object passes ismethod()."""
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100223 if isclass(object) or ismethod(object) or isfunction(object):
224 # mutual exclusion
225 return False
226 tp = type(object)
227 return hasattr(tp, "__get__") and not hasattr(tp, "__set__")
Tim Peters536d2262001-09-20 05:13:38 +0000228
Martin v. Löwise59e2ba2003-05-03 09:09:02 +0000229def isdatadescriptor(object):
230 """Return true if the object is a data descriptor.
231
Aaron Hall, MBA4054b172018-05-20 19:46:42 -0400232 Data descriptors have a __set__ or a __delete__ attribute. Examples are
Martin v. Löwise59e2ba2003-05-03 09:09:02 +0000233 properties (defined in Python) and getsets and members (defined in C).
234 Typically, data descriptors will also have __name__ and __doc__ attributes
235 (properties, getsets, and members have both of these attributes), but this
236 is not guaranteed."""
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100237 if isclass(object) or ismethod(object) or isfunction(object):
238 # mutual exclusion
239 return False
240 tp = type(object)
Aaron Hall, MBA4054b172018-05-20 19:46:42 -0400241 return hasattr(tp, "__set__") or hasattr(tp, "__delete__")
Martin v. Löwise59e2ba2003-05-03 09:09:02 +0000242
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000243if hasattr(types, 'MemberDescriptorType'):
244 # CPython and equivalent
245 def ismemberdescriptor(object):
246 """Return true if the object is a member descriptor.
247
248 Member descriptors are specialized descriptors defined in extension
249 modules."""
250 return isinstance(object, types.MemberDescriptorType)
251else:
252 # Other implementations
253 def ismemberdescriptor(object):
254 """Return true if the object is a member descriptor.
255
256 Member descriptors are specialized descriptors defined in extension
257 modules."""
258 return False
259
260if hasattr(types, 'GetSetDescriptorType'):
261 # CPython and equivalent
262 def isgetsetdescriptor(object):
263 """Return true if the object is a getset descriptor.
264
265 getset descriptors are specialized descriptors defined in extension
266 modules."""
267 return isinstance(object, types.GetSetDescriptorType)
268else:
269 # Other implementations
270 def isgetsetdescriptor(object):
271 """Return true if the object is a getset descriptor.
272
273 getset descriptors are specialized descriptors defined in extension
274 modules."""
275 return False
276
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000277def isfunction(object):
278 """Return true if the object is a user-defined function.
279
280 Function objects provide these attributes:
281 __doc__ documentation string
282 __name__ name with which this function was defined
Neal Norwitz221085d2007-02-25 20:55:47 +0000283 __code__ code object containing compiled function bytecode
284 __defaults__ tuple of any default values for arguments
285 __globals__ global namespace in which this function was defined
286 __annotations__ dict of parameter annotations
287 __kwdefaults__ dict of keyword only parameters with defaults"""
Tim Peters28bc59f2001-09-16 08:40:16 +0000288 return isinstance(object, types.FunctionType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000289
Jeroen Demeyerfcef60f2019-04-02 16:03:42 +0200290def _has_code_flag(f, flag):
291 """Return true if ``f`` is a function (or a method or functools.partial
292 wrapper wrapping a function) whose code object has the given ``flag``
293 set in its flags."""
294 while ismethod(f):
295 f = f.__func__
296 f = functools._unwrap_partial(f)
297 if not isfunction(f):
298 return False
299 return bool(f.__code__.co_flags & flag)
300
Pablo Galindo7cd25432018-10-26 12:19:14 +0100301def isgeneratorfunction(obj):
Christian Heimes7131fd92008-02-19 14:21:46 +0000302 """Return true if the object is a user-defined generator function.
303
Martin Panter0f0eac42016-09-07 11:04:41 +0000304 Generator function objects provide the same attributes as functions.
305 See help(isfunction) for a list of attributes."""
Jeroen Demeyerfcef60f2019-04-02 16:03:42 +0200306 return _has_code_flag(obj, CO_GENERATOR)
Yury Selivanov75445082015-05-11 22:57:16 -0400307
Pablo Galindo7cd25432018-10-26 12:19:14 +0100308def iscoroutinefunction(obj):
Yury Selivanov75445082015-05-11 22:57:16 -0400309 """Return true if the object is a coroutine function.
310
Yury Selivanov4778e132016-11-08 12:23:09 -0500311 Coroutine functions are defined with "async def" syntax.
Yury Selivanov75445082015-05-11 22:57:16 -0400312 """
Jeroen Demeyerfcef60f2019-04-02 16:03:42 +0200313 return _has_code_flag(obj, CO_COROUTINE)
Yury Selivanov75445082015-05-11 22:57:16 -0400314
Pablo Galindo7cd25432018-10-26 12:19:14 +0100315def isasyncgenfunction(obj):
Yury Selivanov4778e132016-11-08 12:23:09 -0500316 """Return true if the object is an asynchronous generator function.
317
318 Asynchronous generator functions are defined with "async def"
319 syntax and have "yield" expressions in their body.
320 """
Jeroen Demeyerfcef60f2019-04-02 16:03:42 +0200321 return _has_code_flag(obj, CO_ASYNC_GENERATOR)
Yury Selivanoveb636452016-09-08 22:01:51 -0700322
323def isasyncgen(object):
Yury Selivanov4778e132016-11-08 12:23:09 -0500324 """Return true if the object is an asynchronous generator."""
Yury Selivanoveb636452016-09-08 22:01:51 -0700325 return isinstance(object, types.AsyncGeneratorType)
326
Christian Heimes7131fd92008-02-19 14:21:46 +0000327def isgenerator(object):
328 """Return true if the object is a generator.
329
330 Generator objects provide these attributes:
Ezio Melotti30b9d5d2013-08-17 15:50:46 +0300331 __iter__ defined to support iteration over container
Christian Heimes7131fd92008-02-19 14:21:46 +0000332 close raises a new GeneratorExit exception inside the
333 generator to terminate the iteration
334 gi_code code object
335 gi_frame frame object or possibly None once the generator has
336 been exhausted
337 gi_running set to 1 when generator is executing, 0 otherwise
338 next return the next item from the container
339 send resumes the generator and "sends" a value that becomes
340 the result of the current yield-expression
341 throw used to raise an exception inside the generator"""
Yury Selivanov5376ba92015-06-22 12:19:30 -0400342 return isinstance(object, types.GeneratorType)
Yury Selivanov75445082015-05-11 22:57:16 -0400343
344def iscoroutine(object):
345 """Return true if the object is a coroutine."""
Yury Selivanov5376ba92015-06-22 12:19:30 -0400346 return isinstance(object, types.CoroutineType)
Christian Heimes7131fd92008-02-19 14:21:46 +0000347
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400348def isawaitable(object):
Yury Selivanovc0215df2016-11-08 19:57:44 -0500349 """Return true if object can be passed to an ``await`` expression."""
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400350 return (isinstance(object, types.CoroutineType) or
351 isinstance(object, types.GeneratorType) and
Yury Selivanovc0215df2016-11-08 19:57:44 -0500352 bool(object.gi_code.co_flags & CO_ITERABLE_COROUTINE) or
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400353 isinstance(object, collections.abc.Awaitable))
354
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000355def istraceback(object):
356 """Return true if the object is a traceback.
357
358 Traceback objects provide these attributes:
359 tb_frame frame object at this level
360 tb_lasti index of last attempted instruction in bytecode
361 tb_lineno current line number in Python source code
362 tb_next next inner traceback object (called by this level)"""
Tim Peters28bc59f2001-09-16 08:40:16 +0000363 return isinstance(object, types.TracebackType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000364
365def isframe(object):
366 """Return true if the object is a frame object.
367
368 Frame objects provide these attributes:
369 f_back next outer frame object (this frame's caller)
370 f_builtins built-in namespace seen by this frame
371 f_code code object being executed in this frame
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000372 f_globals global namespace seen by this frame
373 f_lasti index of last attempted instruction in bytecode
374 f_lineno current line number in Python source code
375 f_locals local namespace seen by this frame
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000376 f_trace tracing function for this frame, or None"""
Tim Peters28bc59f2001-09-16 08:40:16 +0000377 return isinstance(object, types.FrameType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000378
379def iscode(object):
380 """Return true if the object is a code object.
381
382 Code objects provide these attributes:
Xiang Zhanga6902e62017-04-13 10:38:28 +0800383 co_argcount number of arguments (not including *, ** args
384 or keyword only arguments)
385 co_code string of raw compiled bytecode
386 co_cellvars tuple of names of cell variables
387 co_consts tuple of constants used in the bytecode
388 co_filename name of file in which this code object was created
389 co_firstlineno number of first line in Python source code
390 co_flags bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg
391 | 16=nested | 32=generator | 64=nofree | 128=coroutine
392 | 256=iterable_coroutine | 512=async_generator
393 co_freevars tuple of names of free variables
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100394 co_posonlyargcount number of positional only arguments
Xiang Zhanga6902e62017-04-13 10:38:28 +0800395 co_kwonlyargcount number of keyword only arguments (not including ** arg)
396 co_lnotab encoded mapping of line numbers to bytecode indices
397 co_name name with which this code object was defined
398 co_names tuple of names of local variables
399 co_nlocals number of local variables
400 co_stacksize virtual machine stack space required
401 co_varnames tuple of names of arguments and local variables"""
Tim Peters28bc59f2001-09-16 08:40:16 +0000402 return isinstance(object, types.CodeType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000403
404def isbuiltin(object):
405 """Return true if the object is a built-in function or method.
406
407 Built-in functions and methods provide these attributes:
408 __doc__ documentation string
409 __name__ original name of this function or method
410 __self__ instance to which a method is bound, or None"""
Tim Peters28bc59f2001-09-16 08:40:16 +0000411 return isinstance(object, types.BuiltinFunctionType)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000412
413def isroutine(object):
414 """Return true if the object is any kind of function or method."""
Tim Peters536d2262001-09-20 05:13:38 +0000415 return (isbuiltin(object)
416 or isfunction(object)
417 or ismethod(object)
418 or ismethoddescriptor(object))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000419
Christian Heimesbe5b30b2008-03-03 19:18:51 +0000420def isabstract(object):
421 """Return true if the object is an abstract base class (ABC)."""
Natefcfe80e2017-04-24 10:06:15 -0700422 if not isinstance(object, type):
423 return False
424 if object.__flags__ & TPFLAGS_IS_ABSTRACT:
425 return True
426 if not issubclass(type(object), abc.ABCMeta):
427 return False
428 if hasattr(object, '__abstractmethods__'):
429 # It looks like ABCMeta.__new__ has finished running;
430 # TPFLAGS_IS_ABSTRACT should have been accurate.
431 return False
432 # It looks like ABCMeta.__new__ has not finished running yet; we're
433 # probably in __init_subclass__. We'll look for abstractmethods manually.
434 for name, value in object.__dict__.items():
435 if getattr(value, "__isabstractmethod__", False):
436 return True
437 for base in object.__bases__:
438 for name in getattr(base, "__abstractmethods__", ()):
439 value = getattr(object, name, None)
440 if getattr(value, "__isabstractmethod__", False):
441 return True
442 return False
Christian Heimesbe5b30b2008-03-03 19:18:51 +0000443
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000444def getmembers(object, predicate=None):
445 """Return all members of an object as (name, value) pairs sorted by name.
446 Optionally, only return members that satisfy a given predicate."""
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100447 if isclass(object):
448 mro = (object,) + getmro(object)
449 else:
450 mro = ()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000451 results = []
Ethan Furmane03ea372013-09-25 07:14:41 -0700452 processed = set()
453 names = dir(object)
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700454 # :dd any DynamicClassAttributes to the list of names if object is a class;
Ethan Furmane03ea372013-09-25 07:14:41 -0700455 # this may result in duplicate entries if, for example, a virtual
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700456 # attribute with the same name as a DynamicClassAttribute exists
Ethan Furmane03ea372013-09-25 07:14:41 -0700457 try:
458 for base in object.__bases__:
459 for k, v in base.__dict__.items():
460 if isinstance(v, types.DynamicClassAttribute):
461 names.append(k)
462 except AttributeError:
463 pass
464 for key in names:
Ethan Furman63c141c2013-10-18 00:27:39 -0700465 # First try to get the value via getattr. Some descriptors don't
466 # like calling their __get__ (see bug #1785), so fall back to
467 # looking in the __dict__.
468 try:
469 value = getattr(object, key)
470 # handle the duplicate key
471 if key in processed:
472 raise AttributeError
473 except AttributeError:
474 for base in mro:
475 if key in base.__dict__:
476 value = base.__dict__[key]
477 break
478 else:
479 # could be a (currently) missing slot member, or a buggy
480 # __dir__; discard and move on
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100481 continue
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000482 if not predicate or predicate(value):
483 results.append((key, value))
Ethan Furmane03ea372013-09-25 07:14:41 -0700484 processed.add(key)
485 results.sort(key=lambda pair: pair[0])
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000486 return results
487
Christian Heimes25bb7832008-01-11 16:17:00 +0000488Attribute = namedtuple('Attribute', 'name kind defining_class object')
489
Tim Peters13b49d32001-09-23 02:00:29 +0000490def classify_class_attrs(cls):
491 """Return list of attribute-descriptor tuples.
492
493 For each name in dir(cls), the return list contains a 4-tuple
494 with these elements:
495
496 0. The name (a string).
497
498 1. The kind of attribute this is, one of these strings:
499 'class method' created via classmethod()
500 'static method' created via staticmethod()
501 'property' created via property()
Ethan Furmane03ea372013-09-25 07:14:41 -0700502 'method' any other flavor of method or descriptor
Tim Peters13b49d32001-09-23 02:00:29 +0000503 'data' not a method
504
505 2. The class which defined this attribute (a class).
506
Ethan Furmane03ea372013-09-25 07:14:41 -0700507 3. The object as obtained by calling getattr; if this fails, or if the
508 resulting object does not live anywhere in the class' mro (including
509 metaclasses) then the object is looked up in the defining class's
510 dict (found by walking the mro).
Ethan Furman668dede2013-09-14 18:53:26 -0700511
512 If one of the items in dir(cls) is stored in the metaclass it will now
513 be discovered and not have None be listed as the class in which it was
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700514 defined. Any items whose home class cannot be discovered are skipped.
Tim Peters13b49d32001-09-23 02:00:29 +0000515 """
516
517 mro = getmro(cls)
Ethan Furman668dede2013-09-14 18:53:26 -0700518 metamro = getmro(type(cls)) # for attributes stored in the metaclass
Jon Dufresne39726282017-05-18 07:35:54 -0700519 metamro = tuple(cls for cls in metamro if cls not in (type, object))
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700520 class_bases = (cls,) + mro
521 all_bases = class_bases + metamro
Tim Peters13b49d32001-09-23 02:00:29 +0000522 names = dir(cls)
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700523 # :dd any DynamicClassAttributes to the list of names;
Ethan Furmane03ea372013-09-25 07:14:41 -0700524 # this may result in duplicate entries if, for example, a virtual
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700525 # attribute with the same name as a DynamicClassAttribute exists.
Ethan Furman63c141c2013-10-18 00:27:39 -0700526 for base in mro:
Ethan Furmane03ea372013-09-25 07:14:41 -0700527 for k, v in base.__dict__.items():
Ethan Furmanc314e602021-01-12 23:47:57 -0800528 if isinstance(v, types.DynamicClassAttribute) and v.fget is not None:
Ethan Furmane03ea372013-09-25 07:14:41 -0700529 names.append(k)
Tim Peters13b49d32001-09-23 02:00:29 +0000530 result = []
Ethan Furmane03ea372013-09-25 07:14:41 -0700531 processed = set()
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700532
Tim Peters13b49d32001-09-23 02:00:29 +0000533 for name in names:
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100534 # Get the object associated with the name, and where it was defined.
Ethan Furmane03ea372013-09-25 07:14:41 -0700535 # Normal objects will be looked up with both getattr and directly in
536 # its class' dict (in case getattr fails [bug #1785], and also to look
537 # for a docstring).
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700538 # For DynamicClassAttributes on the second pass we only look in the
Ethan Furmane03ea372013-09-25 07:14:41 -0700539 # class's dict.
540 #
Tim Peters13b49d32001-09-23 02:00:29 +0000541 # Getting an obj from the __dict__ sometimes reveals more than
542 # using getattr. Static and class methods are dramatic examples.
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100543 homecls = None
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700544 get_obj = None
545 dict_obj = None
Ethan Furmane03ea372013-09-25 07:14:41 -0700546 if name not in processed:
547 try:
Ethan Furmana8b07072013-10-18 01:22:08 -0700548 if name == '__dict__':
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700549 raise Exception("__dict__ is special, don't want the proxy")
Ethan Furmane03ea372013-09-25 07:14:41 -0700550 get_obj = getattr(cls, name)
551 except Exception as exc:
552 pass
553 else:
Ethan Furmane03ea372013-09-25 07:14:41 -0700554 homecls = getattr(get_obj, "__objclass__", homecls)
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700555 if homecls not in class_bases:
Ethan Furmane03ea372013-09-25 07:14:41 -0700556 # if the resulting object does not live somewhere in the
Ethan Furman63c141c2013-10-18 00:27:39 -0700557 # mro, drop it and search the mro manually
Ethan Furmane03ea372013-09-25 07:14:41 -0700558 homecls = None
Ethan Furman63c141c2013-10-18 00:27:39 -0700559 last_cls = None
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700560 # first look in the classes
561 for srch_cls in class_bases:
Ethan Furman63c141c2013-10-18 00:27:39 -0700562 srch_obj = getattr(srch_cls, name, None)
Yury Selivanovbf341fb2015-05-21 15:41:57 -0400563 if srch_obj is get_obj:
Ethan Furman63c141c2013-10-18 00:27:39 -0700564 last_cls = srch_cls
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700565 # then check the metaclasses
566 for srch_cls in metamro:
567 try:
568 srch_obj = srch_cls.__getattr__(cls, name)
569 except AttributeError:
570 continue
Yury Selivanovbf341fb2015-05-21 15:41:57 -0400571 if srch_obj is get_obj:
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700572 last_cls = srch_cls
Ethan Furman63c141c2013-10-18 00:27:39 -0700573 if last_cls is not None:
574 homecls = last_cls
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700575 for base in all_bases:
Ethan Furmane03ea372013-09-25 07:14:41 -0700576 if name in base.__dict__:
577 dict_obj = base.__dict__[name]
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700578 if homecls not in metamro:
579 homecls = base
Ethan Furmane03ea372013-09-25 07:14:41 -0700580 break
Ethan Furman63c141c2013-10-18 00:27:39 -0700581 if homecls is None:
582 # unable to locate the attribute anywhere, most likely due to
583 # buggy custom __dir__; discard and move on
584 continue
Yury Selivanovbf341fb2015-05-21 15:41:57 -0400585 obj = get_obj if get_obj is not None else dict_obj
Ethan Furmane03ea372013-09-25 07:14:41 -0700586 # Classify the object or its descriptor.
Serhiy Storchaka3327a2d2017-12-15 14:13:41 +0200587 if isinstance(dict_obj, (staticmethod, types.BuiltinMethodType)):
Tim Peters13b49d32001-09-23 02:00:29 +0000588 kind = "static method"
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700589 obj = dict_obj
Serhiy Storchaka3327a2d2017-12-15 14:13:41 +0200590 elif isinstance(dict_obj, (classmethod, types.ClassMethodDescriptorType)):
Tim Peters13b49d32001-09-23 02:00:29 +0000591 kind = "class method"
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700592 obj = dict_obj
593 elif isinstance(dict_obj, property):
Tim Peters13b49d32001-09-23 02:00:29 +0000594 kind = "property"
Ethan Furmanb0c84cd2013-10-20 22:37:39 -0700595 obj = dict_obj
Yury Selivanov0860a0b2014-01-31 14:28:44 -0500596 elif isroutine(obj):
Tim Peters13b49d32001-09-23 02:00:29 +0000597 kind = "method"
Antoine Pitrou86a8a9a2011-12-21 09:57:40 +0100598 else:
Ethan Furmane03ea372013-09-25 07:14:41 -0700599 kind = "data"
Christian Heimes25bb7832008-01-11 16:17:00 +0000600 result.append(Attribute(name, kind, homecls, obj))
Ethan Furmane03ea372013-09-25 07:14:41 -0700601 processed.add(name)
Tim Peters13b49d32001-09-23 02:00:29 +0000602 return result
603
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000604# ----------------------------------------------------------- class helpers
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000605
606def getmro(cls):
607 "Return tuple of base classes (including cls) in method resolution order."
Benjamin Petersonb82c8e52010-11-04 00:38:49 +0000608 return cls.__mro__
Tim Peterse0b2d7a2001-09-22 06:10:55 +0000609
Nick Coghlane8c45d62013-07-28 20:00:01 +1000610# -------------------------------------------------------- function helpers
611
612def unwrap(func, *, stop=None):
613 """Get the object wrapped by *func*.
614
615 Follows the chain of :attr:`__wrapped__` attributes returning the last
616 object in the chain.
617
618 *stop* is an optional callback accepting an object in the wrapper chain
619 as its sole argument that allows the unwrapping to be terminated early if
620 the callback returns a true value. If the callback never returns a true
621 value, the last object in the chain is returned as usual. For example,
622 :func:`signature` uses this to stop unwrapping if any object in the
623 chain has a ``__signature__`` attribute defined.
624
625 :exc:`ValueError` is raised if a cycle is encountered.
626
627 """
628 if stop is None:
629 def _is_wrapper(f):
630 return hasattr(f, '__wrapped__')
631 else:
632 def _is_wrapper(f):
633 return hasattr(f, '__wrapped__') and not stop(f)
634 f = func # remember the original func for error reporting
Thomas Kluyverf9169ce2017-05-23 04:27:52 +0100635 # Memoise by id to tolerate non-hashable objects, but store objects to
636 # ensure they aren't destroyed, which would allow their IDs to be reused.
637 memo = {id(f): f}
638 recursion_limit = sys.getrecursionlimit()
Nick Coghlane8c45d62013-07-28 20:00:01 +1000639 while _is_wrapper(func):
640 func = func.__wrapped__
641 id_func = id(func)
Thomas Kluyverf9169ce2017-05-23 04:27:52 +0100642 if (id_func in memo) or (len(memo) >= recursion_limit):
Nick Coghlane8c45d62013-07-28 20:00:01 +1000643 raise ValueError('wrapper loop when unwrapping {!r}'.format(f))
Thomas Kluyverf9169ce2017-05-23 04:27:52 +0100644 memo[id_func] = func
Nick Coghlane8c45d62013-07-28 20:00:01 +1000645 return func
646
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000647# -------------------------------------------------- source code extraction
648def indentsize(line):
649 """Return the indent size, in spaces, at the start of a line of text."""
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000650 expline = line.expandtabs()
651 return len(expline) - len(expline.lstrip())
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000652
Serhiy Storchaka5cf2b7252015-04-03 22:38:53 +0300653def _findclass(func):
654 cls = sys.modules.get(func.__module__)
655 if cls is None:
656 return None
657 for name in func.__qualname__.split('.')[:-1]:
658 cls = getattr(cls, name)
659 if not isclass(cls):
660 return None
661 return cls
662
663def _finddoc(obj):
Serhiy Storchaka08b47c32020-05-18 20:25:07 +0300664 if isclass(obj):
665 for base in obj.__mro__:
666 if base is not object:
667 try:
668 doc = base.__doc__
669 except AttributeError:
670 continue
671 if doc is not None:
672 return doc
673 return None
674
Serhiy Storchaka5cf2b7252015-04-03 22:38:53 +0300675 if ismethod(obj):
676 name = obj.__func__.__name__
677 self = obj.__self__
678 if (isclass(self) and
679 getattr(getattr(self, name, None), '__func__') is obj.__func__):
680 # classmethod
681 cls = self
682 else:
683 cls = self.__class__
684 elif isfunction(obj):
685 name = obj.__name__
686 cls = _findclass(obj)
687 if cls is None or getattr(cls, name) is not obj:
688 return None
689 elif isbuiltin(obj):
690 name = obj.__name__
691 self = obj.__self__
692 if (isclass(self) and
693 self.__qualname__ + '.' + name == obj.__qualname__):
694 # classmethod
695 cls = self
696 else:
697 cls = self.__class__
Serhiy Storchakaac4bdcc2015-10-29 08:15:50 +0200698 # Should be tested before isdatadescriptor().
699 elif isinstance(obj, property):
700 func = obj.fget
701 name = func.__name__
702 cls = _findclass(func)
703 if cls is None or getattr(cls, name) is not obj:
704 return None
Serhiy Storchaka5cf2b7252015-04-03 22:38:53 +0300705 elif ismethoddescriptor(obj) or isdatadescriptor(obj):
706 name = obj.__name__
707 cls = obj.__objclass__
708 if getattr(cls, name) is not obj:
709 return None
Raymond Hettingerd1e768a2019-03-25 13:01:13 -0700710 if ismemberdescriptor(obj):
711 slots = getattr(cls, '__slots__', None)
712 if isinstance(slots, dict) and name in slots:
713 return slots[name]
Serhiy Storchaka5cf2b7252015-04-03 22:38:53 +0300714 else:
715 return None
Serhiy Storchaka5cf2b7252015-04-03 22:38:53 +0300716 for base in cls.__mro__:
717 try:
Serhiy Storchaka08b47c32020-05-18 20:25:07 +0300718 doc = getattr(base, name).__doc__
Serhiy Storchaka5cf2b7252015-04-03 22:38:53 +0300719 except AttributeError:
720 continue
721 if doc is not None:
722 return doc
723 return None
724
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000725def getdoc(object):
726 """Get the documentation string for an object.
727
728 All tabs are expanded to spaces. To clean up docstrings that are
729 indented to line up with blocks of code, any whitespace than can be
730 uniformly removed from the second line onwards is removed."""
Serhiy Storchaka08b47c32020-05-18 20:25:07 +0300731 try:
732 doc = object.__doc__
733 except AttributeError:
734 return None
Serhiy Storchaka5cf2b7252015-04-03 22:38:53 +0300735 if doc is None:
736 try:
737 doc = _finddoc(object)
738 except (AttributeError, TypeError):
739 return None
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000740 if not isinstance(doc, str):
Tim Peters24008312002-03-17 18:56:20 +0000741 return None
Georg Brandl0c77a822008-06-10 16:37:50 +0000742 return cleandoc(doc)
743
744def cleandoc(doc):
745 """Clean up indentation from docstrings.
746
747 Any whitespace that can be uniformly removed from the second line
748 onwards is removed."""
Tim Peters24008312002-03-17 18:56:20 +0000749 try:
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000750 lines = doc.expandtabs().split('\n')
Tim Peters24008312002-03-17 18:56:20 +0000751 except UnicodeError:
752 return None
753 else:
Ka-Ping Yeea59ef7b2002-11-30 03:53:15 +0000754 # Find minimum indentation of any non-blank lines after first line.
Christian Heimesa37d4c62007-12-04 23:02:19 +0000755 margin = sys.maxsize
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000756 for line in lines[1:]:
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000757 content = len(line.lstrip())
Ka-Ping Yeea59ef7b2002-11-30 03:53:15 +0000758 if content:
759 indent = len(line) - content
760 margin = min(margin, indent)
761 # Remove indentation.
762 if lines:
763 lines[0] = lines[0].lstrip()
Christian Heimesa37d4c62007-12-04 23:02:19 +0000764 if margin < sys.maxsize:
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000765 for i in range(1, len(lines)): lines[i] = lines[i][margin:]
Ka-Ping Yeea59ef7b2002-11-30 03:53:15 +0000766 # Remove any trailing or leading blank lines.
767 while lines and not lines[-1]:
768 lines.pop()
769 while lines and not lines[0]:
770 lines.pop(0)
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000771 return '\n'.join(lines)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000772
773def getfile(object):
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000774 """Work out which source or compiled file an object was defined in."""
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000775 if ismodule(object):
Jason R. Coombsb9650a02018-03-05 18:29:08 -0500776 if getattr(object, '__file__', None):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000777 return object.__file__
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000778 raise TypeError('{!r} is a built-in module'.format(object))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000779 if isclass(object):
Yury Selivanov2eed8b72014-01-27 13:24:56 -0500780 if hasattr(object, '__module__'):
Philipp Ad407d2a2019-06-08 14:05:46 +0200781 module = sys.modules.get(object.__module__)
782 if getattr(module, '__file__', None):
783 return module.__file__
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000784 raise TypeError('{!r} is a built-in class'.format(object))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000785 if ismethod(object):
Christian Heimesff737952007-11-27 10:40:20 +0000786 object = object.__func__
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000787 if isfunction(object):
Neal Norwitz221085d2007-02-25 20:55:47 +0000788 object = object.__code__
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000789 if istraceback(object):
790 object = object.tb_frame
791 if isframe(object):
792 object = object.f_code
793 if iscode(object):
794 return object.co_filename
Thomas Kluyvere968bc732017-10-24 13:42:36 +0100795 raise TypeError('module, class, method, function, traceback, frame, or '
796 'code object was expected, got {}'.format(
797 type(object).__name__))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000798
Ka-Ping Yee4d6fc7f2001-04-10 11:43:00 +0000799def getmodulename(path):
800 """Return the module name for a given file, or None."""
Nick Coghlan76e07702012-07-18 23:14:57 +1000801 fname = os.path.basename(path)
802 # Check for paths that look like an actual module file
803 suffixes = [(-len(suffix), suffix)
804 for suffix in importlib.machinery.all_suffixes()]
805 suffixes.sort() # try longest suffixes first, in case they overlap
806 for neglen, suffix in suffixes:
807 if fname.endswith(suffix):
808 return fname[:neglen]
809 return None
Ka-Ping Yee4d6fc7f2001-04-10 11:43:00 +0000810
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000811def getsourcefile(object):
R. David Murraya1b37402010-06-17 02:04:29 +0000812 """Return the filename that can be used to locate an object's source.
813 Return None if no way can be identified to get the source.
814 """
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000815 filename = getfile(object)
Brett Cannoncb66eb02012-05-11 12:58:42 -0400816 all_bytecode_suffixes = importlib.machinery.DEBUG_BYTECODE_SUFFIXES[:]
817 all_bytecode_suffixes += importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES[:]
818 if any(filename.endswith(s) for s in all_bytecode_suffixes):
819 filename = (os.path.splitext(filename)[0] +
820 importlib.machinery.SOURCE_SUFFIXES[0])
821 elif any(filename.endswith(s) for s in
822 importlib.machinery.EXTENSION_SUFFIXES):
823 return None
Thomas Wouters477c8d52006-05-27 19:21:47 +0000824 if os.path.exists(filename):
825 return filename
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000826 # only return a non-existent filename if the module has a PEP 302 loader
Brett Cannon825ac382020-11-06 18:45:56 -0800827 module = getmodule(object, filename)
828 if getattr(module, '__loader__', None) is not None:
829 return filename
830 elif getattr(getattr(module, "__spec__", None), "loader", None) is not None:
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000831 return filename
R. David Murraya1b37402010-06-17 02:04:29 +0000832 # or it is in the linecache
Brett Cannon825ac382020-11-06 18:45:56 -0800833 elif filename in linecache.cache:
R. David Murraya1b37402010-06-17 02:04:29 +0000834 return filename
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000835
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000836def getabsfile(object, _filename=None):
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000837 """Return an absolute path to the source or compiled file for an object.
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000838
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000839 The idea is for each object to have a unique origin, so this routine
840 normalizes the result as much as possible."""
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000841 if _filename is None:
842 _filename = getsourcefile(object) or getfile(object)
843 return os.path.normcase(os.path.abspath(_filename))
Ka-Ping Yeec113c242001-03-02 02:08:53 +0000844
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000845modulesbyfile = {}
Thomas Wouters89f507f2006-12-13 04:49:30 +0000846_filesbymodname = {}
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000847
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000848def getmodule(object, _filename=None):
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000849 """Return the module an object was defined in, or None if not found."""
Ka-Ping Yee202c99b2001-04-13 09:15:08 +0000850 if ismodule(object):
851 return object
Johannes Gijsbers93245262004-09-11 15:53:22 +0000852 if hasattr(object, '__module__'):
Ka-Ping Yee8b58b842001-03-01 13:56:16 +0000853 return sys.modules.get(object.__module__)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000854 # Try the filename to modulename cache
855 if _filename is not None and _filename in modulesbyfile:
856 return sys.modules.get(modulesbyfile[_filename])
857 # Try the cache again with the absolute file name
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000858 try:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000859 file = getabsfile(object, _filename)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000860 except TypeError:
861 return None
Raymond Hettinger54f02222002-06-01 14:18:47 +0000862 if file in modulesbyfile:
Ka-Ping Yeeb38bbbd2003-03-28 16:29:50 +0000863 return sys.modules.get(modulesbyfile[file])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000864 # Update the filename to module name cache and check yet again
865 # Copy sys.modules in order to cope with changes while iterating
Gregory P. Smith85cf1d52020-03-04 16:45:22 -0800866 for modname, module in sys.modules.copy().items():
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000867 if ismodule(module) and hasattr(module, '__file__'):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000868 f = module.__file__
869 if f == _filesbymodname.get(modname, None):
870 # Have already mapped this module, so skip it
871 continue
872 _filesbymodname[modname] = f
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000873 f = getabsfile(module)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000874 # Always map to the name the module knows itself by
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000875 modulesbyfile[f] = modulesbyfile[
876 os.path.realpath(f)] = module.__name__
Raymond Hettinger54f02222002-06-01 14:18:47 +0000877 if file in modulesbyfile:
Ka-Ping Yeeb38bbbd2003-03-28 16:29:50 +0000878 return sys.modules.get(modulesbyfile[file])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000879 # Check the main module
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000880 main = sys.modules['__main__']
Brett Cannon4a671fe2003-06-15 22:33:28 +0000881 if not hasattr(object, '__name__'):
882 return None
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000883 if hasattr(main, object.__name__):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000884 mainobject = getattr(main, object.__name__)
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000885 if mainobject is object:
886 return main
Thomas Wouters89f507f2006-12-13 04:49:30 +0000887 # Check builtins
Georg Brandl1a3284e2007-12-02 09:40:06 +0000888 builtin = sys.modules['builtins']
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000889 if hasattr(builtin, object.__name__):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000890 builtinobject = getattr(builtin, object.__name__)
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000891 if builtinobject is object:
892 return builtin
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000893
Karthikeyan Singaravelan696136b2020-04-18 21:49:32 +0530894
895class ClassFoundException(Exception):
896 pass
897
898
899class _ClassFinder(ast.NodeVisitor):
900
901 def __init__(self, qualname):
902 self.stack = []
903 self.qualname = qualname
904
905 def visit_FunctionDef(self, node):
906 self.stack.append(node.name)
907 self.stack.append('<locals>')
908 self.generic_visit(node)
909 self.stack.pop()
910 self.stack.pop()
911
912 visit_AsyncFunctionDef = visit_FunctionDef
913
914 def visit_ClassDef(self, node):
915 self.stack.append(node.name)
916 if self.qualname == '.'.join(self.stack):
917 # Return the decorator for the class if present
918 if node.decorator_list:
919 line_number = node.decorator_list[0].lineno
920 else:
921 line_number = node.lineno
922
923 # decrement by one since lines starts with indexing by zero
924 line_number -= 1
925 raise ClassFoundException(line_number)
926 self.generic_visit(node)
927 self.stack.pop()
928
929
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000930def findsource(object):
931 """Return the entire source file and starting line number for an object.
932
933 The argument may be a module, class, method, function, traceback, frame,
934 or code object. The source code is returned as a list of all the lines
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200935 in the file and the line number indexes a line in that list. An OSError
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000936 is raised if the source code cannot be retrieved."""
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500937
Yury Selivanovef1e7502014-12-08 16:05:34 -0500938 file = getsourcefile(object)
939 if file:
940 # Invalidate cache if needed.
941 linecache.checkcache(file)
942 else:
943 file = getfile(object)
944 # Allow filenames in form of "<something>" to pass through.
945 # `doctest` monkeypatches `linecache` module to enable
946 # inspection, so let `linecache.getlines` to be called.
947 if not (file.startswith('<') and file.endswith('>')):
948 raise OSError('source code not available')
Benjamin Peterson9620cc02011-06-11 15:53:11 -0500949
Thomas Wouters89f507f2006-12-13 04:49:30 +0000950 module = getmodule(object, file)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000951 if module:
952 lines = linecache.getlines(file, module.__dict__)
953 else:
954 lines = linecache.getlines(file)
Neil Schemenauerf06f8532002-03-23 23:51:04 +0000955 if not lines:
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200956 raise OSError('could not get source code')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000957
958 if ismodule(object):
959 return lines, 0
960
961 if isclass(object):
Karthikeyan Singaravelan696136b2020-04-18 21:49:32 +0530962 qualname = object.__qualname__
963 source = ''.join(lines)
964 tree = ast.parse(source)
965 class_finder = _ClassFinder(qualname)
966 try:
967 class_finder.visit(tree)
968 except ClassFoundException as e:
969 line_number = e.args[0]
970 return lines, line_number
Jeremy Hyltonab919022003-06-27 18:41:20 +0000971 else:
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200972 raise OSError('could not find class definition')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000973
974 if ismethod(object):
Christian Heimesff737952007-11-27 10:40:20 +0000975 object = object.__func__
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000976 if isfunction(object):
Neal Norwitz221085d2007-02-25 20:55:47 +0000977 object = object.__code__
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000978 if istraceback(object):
979 object = object.tb_frame
980 if isframe(object):
981 object = object.f_code
982 if iscode(object):
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000983 if not hasattr(object, 'co_firstlineno'):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200984 raise OSError('could not find function definition')
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000985 lnum = object.co_firstlineno - 1
Yury Selivanove4e811d2015-07-21 19:01:52 +0300986 pat = re.compile(r'^(\s*def\s)|(\s*async\s+def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000987 while lnum > 0:
Irit Katriel2e0760b2020-12-04 21:22:03 +0000988 try:
989 line = lines[lnum]
990 except IndexError:
991 raise OSError('lineno is out of bounds')
992 if pat.match(line):
993 break
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +0000994 lnum = lnum - 1
995 return lines, lnum
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200996 raise OSError('could not find code object')
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +0000997
998def getcomments(object):
Jeremy Hyltonb4c17c82002-03-28 23:01:56 +0000999 """Get lines of comments immediately preceding an object's source code.
1000
1001 Returns None when source can't be found.
1002 """
1003 try:
1004 lines, lnum = findsource(object)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02001005 except (OSError, TypeError):
Jeremy Hyltonb4c17c82002-03-28 23:01:56 +00001006 return None
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001007
1008 if ismodule(object):
1009 # Look for a comment block at the top of the file.
1010 start = 0
Ka-Ping Yeeb910efe2001-04-12 13:17:17 +00001011 if lines and lines[0][:2] == '#!': start = 1
Neal Norwitz9d72bb42007-04-17 08:48:32 +00001012 while start < len(lines) and lines[start].strip() in ('', '#'):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001013 start = start + 1
Ka-Ping Yeeb910efe2001-04-12 13:17:17 +00001014 if start < len(lines) and lines[start][:1] == '#':
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001015 comments = []
1016 end = start
1017 while end < len(lines) and lines[end][:1] == '#':
Neal Norwitz9d72bb42007-04-17 08:48:32 +00001018 comments.append(lines[end].expandtabs())
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001019 end = end + 1
Neal Norwitz9d72bb42007-04-17 08:48:32 +00001020 return ''.join(comments)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001021
1022 # Look for a preceding block of comments at the same indentation.
1023 elif lnum > 0:
1024 indent = indentsize(lines[lnum])
1025 end = lnum - 1
Neal Norwitz9d72bb42007-04-17 08:48:32 +00001026 if end >= 0 and lines[end].lstrip()[:1] == '#' and \
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001027 indentsize(lines[end]) == indent:
Neal Norwitz9d72bb42007-04-17 08:48:32 +00001028 comments = [lines[end].expandtabs().lstrip()]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001029 if end > 0:
1030 end = end - 1
Neal Norwitz9d72bb42007-04-17 08:48:32 +00001031 comment = lines[end].expandtabs().lstrip()
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001032 while comment[:1] == '#' and indentsize(lines[end]) == indent:
1033 comments[:0] = [comment]
1034 end = end - 1
1035 if end < 0: break
Neal Norwitz9d72bb42007-04-17 08:48:32 +00001036 comment = lines[end].expandtabs().lstrip()
1037 while comments and comments[0].strip() == '#':
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001038 comments[:1] = []
Neal Norwitz9d72bb42007-04-17 08:48:32 +00001039 while comments and comments[-1].strip() == '#':
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001040 comments[-1:] = []
Neal Norwitz9d72bb42007-04-17 08:48:32 +00001041 return ''.join(comments)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001042
Tim Peters4efb6e92001-06-29 23:51:08 +00001043class EndOfBlock(Exception): pass
1044
1045class BlockFinder:
1046 """Provide a tokeneater() method to detect the end of a code block."""
1047 def __init__(self):
1048 self.indent = 0
Johannes Gijsbersa5855d52005-03-12 16:37:11 +00001049 self.islambda = False
Johannes Gijsbers1542f342004-12-12 16:46:28 +00001050 self.started = False
1051 self.passline = False
Meador Inge5b718d72015-07-23 22:49:37 -05001052 self.indecorator = False
1053 self.decoratorhasargs = False
Armin Rigodd5c0232005-09-25 11:45:45 +00001054 self.last = 1
Irit Katriel6e1eec72020-12-04 16:45:38 +00001055 self.body_col0 = None
Tim Peters4efb6e92001-06-29 23:51:08 +00001056
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001057 def tokeneater(self, type, token, srowcol, erowcol, line):
Meador Inge5b718d72015-07-23 22:49:37 -05001058 if not self.started and not self.indecorator:
1059 # skip any decorators
1060 if token == "@":
1061 self.indecorator = True
Armin Rigodd5c0232005-09-25 11:45:45 +00001062 # look for the first "def", "class" or "lambda"
Meador Inge5b718d72015-07-23 22:49:37 -05001063 elif token in ("def", "class", "lambda"):
Johannes Gijsbersa5855d52005-03-12 16:37:11 +00001064 if token == "lambda":
1065 self.islambda = True
Johannes Gijsbers1542f342004-12-12 16:46:28 +00001066 self.started = True
Armin Rigodd5c0232005-09-25 11:45:45 +00001067 self.passline = True # skip to the end of the line
Meador Inge5b718d72015-07-23 22:49:37 -05001068 elif token == "(":
1069 if self.indecorator:
1070 self.decoratorhasargs = True
1071 elif token == ")":
1072 if self.indecorator:
1073 self.indecorator = False
1074 self.decoratorhasargs = False
Tim Peters4efb6e92001-06-29 23:51:08 +00001075 elif type == tokenize.NEWLINE:
Armin Rigodd5c0232005-09-25 11:45:45 +00001076 self.passline = False # stop skipping when a NEWLINE is seen
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001077 self.last = srowcol[0]
Armin Rigodd5c0232005-09-25 11:45:45 +00001078 if self.islambda: # lambdas always end at the first NEWLINE
1079 raise EndOfBlock
Meador Inge5b718d72015-07-23 22:49:37 -05001080 # hitting a NEWLINE when in a decorator without args
1081 # ends the decorator
1082 if self.indecorator and not self.decoratorhasargs:
1083 self.indecorator = False
Johannes Gijsbers1542f342004-12-12 16:46:28 +00001084 elif self.passline:
1085 pass
Tim Peters4efb6e92001-06-29 23:51:08 +00001086 elif type == tokenize.INDENT:
Irit Katriel6e1eec72020-12-04 16:45:38 +00001087 if self.body_col0 is None and self.started:
1088 self.body_col0 = erowcol[1]
Tim Peters4efb6e92001-06-29 23:51:08 +00001089 self.indent = self.indent + 1
Johannes Gijsbers1542f342004-12-12 16:46:28 +00001090 self.passline = True
Tim Peters4efb6e92001-06-29 23:51:08 +00001091 elif type == tokenize.DEDENT:
1092 self.indent = self.indent - 1
Armin Rigodd5c0232005-09-25 11:45:45 +00001093 # the end of matching indent/dedent pairs end a block
1094 # (note that this only works for "def"/"class" blocks,
1095 # not e.g. for "if: else:" or "try: finally:" blocks)
1096 if self.indent <= 0:
1097 raise EndOfBlock
Irit Katriel6e1eec72020-12-04 16:45:38 +00001098 elif type == tokenize.COMMENT:
1099 if self.body_col0 is not None and srowcol[1] >= self.body_col0:
1100 # Include comments if indented at least as much as the block
1101 self.last = srowcol[0]
Armin Rigodd5c0232005-09-25 11:45:45 +00001102 elif self.indent == 0 and type not in (tokenize.COMMENT, tokenize.NL):
1103 # any other token on the same indentation level end the previous
1104 # block as well, except the pseudo-tokens COMMENT and NL.
1105 raise EndOfBlock
Tim Peters4efb6e92001-06-29 23:51:08 +00001106
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001107def getblock(lines):
1108 """Extract the block of code at the top of the given list of lines."""
Armin Rigodd5c0232005-09-25 11:45:45 +00001109 blockfinder = BlockFinder()
Tim Peters4efb6e92001-06-29 23:51:08 +00001110 try:
Trent Nelson428de652008-03-18 22:41:35 +00001111 tokens = tokenize.generate_tokens(iter(lines).__next__)
1112 for _token in tokens:
1113 blockfinder.tokeneater(*_token)
Armin Rigodd5c0232005-09-25 11:45:45 +00001114 except (EndOfBlock, IndentationError):
1115 pass
1116 return lines[:blockfinder.last]
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001117
1118def getsourcelines(object):
1119 """Return a list of source lines and starting line number for an object.
1120
1121 The argument may be a module, class, method, function, traceback, frame,
1122 or code object. The source code is returned as a list of the lines
1123 corresponding to the object and the line number indicates where in the
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02001124 original source file the first line of code was found. An OSError is
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001125 raised if the source code cannot be retrieved."""
Yury Selivanov081bbf62014-09-26 17:34:54 -04001126 object = unwrap(object)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001127 lines, lnum = findsource(object)
1128
Vladimir Matveev91cb2982018-08-24 07:18:00 -07001129 if istraceback(object):
1130 object = object.tb_frame
1131
1132 # for module or frame that corresponds to module, return all source lines
1133 if (ismodule(object) or
1134 (isframe(object) and object.f_code.co_name == "<module>")):
Meador Inge5b718d72015-07-23 22:49:37 -05001135 return lines, 0
1136 else:
1137 return getblock(lines[lnum:]), lnum + 1
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001138
1139def getsource(object):
1140 """Return the text of the source code for an object.
1141
1142 The argument may be a module, class, method, function, traceback, frame,
1143 or code object. The source code is returned as a single string. An
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02001144 OSError is raised if the source code cannot be retrieved."""
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001145 lines, lnum = getsourcelines(object)
Neal Norwitz9d72bb42007-04-17 08:48:32 +00001146 return ''.join(lines)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001147
1148# --------------------------------------------------- class tree extraction
1149def walktree(classes, children, parent):
1150 """Recursive helper function for getclasstree()."""
1151 results = []
Raymond Hettingera1a992c2005-03-11 06:46:45 +00001152 classes.sort(key=attrgetter('__module__', '__name__'))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001153 for c in classes:
1154 results.append((c, c.__bases__))
Raymond Hettinger54f02222002-06-01 14:18:47 +00001155 if c in children:
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001156 results.append(walktree(children[c], children, c))
1157 return results
1158
Georg Brandl5ce83a02009-06-01 17:23:51 +00001159def getclasstree(classes, unique=False):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001160 """Arrange the given list of classes into a hierarchy of nested lists.
1161
1162 Where a nested list appears, it contains classes derived from the class
1163 whose entry immediately precedes the list. Each entry is a 2-tuple
1164 containing a class and a tuple of its base classes. If the 'unique'
1165 argument is true, exactly one entry appears in the returned structure
1166 for each class in the given list. Otherwise, classes using multiple
1167 inheritance and their descendants will appear multiple times."""
1168 children = {}
1169 roots = []
1170 for c in classes:
1171 if c.__bases__:
1172 for parent in c.__bases__:
Srinivas Reddy Thatiparthy (శ్రీనివాస్ రెడ్డి తాటిపర్తి)feaefc72018-02-09 15:29:19 +05301173 if parent not in children:
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001174 children[parent] = []
Serhiy Storchaka362c1b52013-09-05 17:14:32 +03001175 if c not in children[parent]:
1176 children[parent].append(c)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001177 if unique and parent in classes: break
1178 elif c not in roots:
1179 roots.append(c)
Raymond Hettingere0d49722002-06-02 18:55:56 +00001180 for parent in children:
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001181 if parent not in classes:
1182 roots.append(parent)
1183 return walktree(roots, children, None)
1184
1185# ------------------------------------------------ argument list extraction
Christian Heimes25bb7832008-01-11 16:17:00 +00001186Arguments = namedtuple('Arguments', 'args, varargs, varkw')
1187
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001188def getargs(co):
1189 """Get information about the arguments accepted by a code object.
1190
Guido van Rossum2e65f892007-02-28 22:03:49 +00001191 Three things are returned: (args, varargs, varkw), where
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001192 'args' is the list of argument names. Keyword-only arguments are
1193 appended. 'varargs' and 'varkw' are the names of the * and **
1194 arguments or None."""
Jeremy Hylton64967882003-06-27 18:14:39 +00001195 if not iscode(co):
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +00001196 raise TypeError('{!r} is not a code object'.format(co))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001197
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001198 names = co.co_varnames
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001199 nargs = co.co_argcount
Guido van Rossum2e65f892007-02-28 22:03:49 +00001200 nkwargs = co.co_kwonlyargcount
Pablo Galindocd74e662019-06-01 18:08:04 +01001201 args = list(names[:nargs])
1202 kwonlyargs = list(names[nargs:nargs+nkwargs])
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001203 step = 0
1204
Guido van Rossum2e65f892007-02-28 22:03:49 +00001205 nargs += nkwargs
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001206 varargs = None
1207 if co.co_flags & CO_VARARGS:
1208 varargs = co.co_varnames[nargs]
1209 nargs = nargs + 1
1210 varkw = None
1211 if co.co_flags & CO_VARKEYWORDS:
1212 varkw = co.co_varnames[nargs]
Pablo Galindocd74e662019-06-01 18:08:04 +01001213 return Arguments(args + kwonlyargs, varargs, varkw)
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001214
1215ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults')
1216
1217def getargspec(func):
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001218 """Get the names and default values of a function's parameters.
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001219
1220 A tuple of four things is returned: (args, varargs, keywords, defaults).
1221 'args' is a list of the argument names, including keyword-only argument names.
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001222 'varargs' and 'keywords' are the names of the * and ** parameters or None.
1223 'defaults' is an n-tuple of the default values of the last n parameters.
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001224
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001225 This function is deprecated, as it does not support annotations or
1226 keyword-only parameters and will raise ValueError if either is present
1227 on the supplied callable.
1228
1229 For a more structured introspection API, use inspect.signature() instead.
1230
1231 Alternatively, use getfullargspec() for an API with a similar namedtuple
1232 based interface, but full support for annotations and keyword-only
1233 parameters.
Matthias Bussonnierded87d82018-10-19 16:40:45 -07001234
1235 Deprecated since Python 3.5, use `inspect.getfullargspec()`.
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001236 """
Matthias Bussonnierded87d82018-10-19 16:40:45 -07001237 warnings.warn("inspect.getargspec() is deprecated since Python 3.0, "
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001238 "use inspect.signature() or inspect.getfullargspec()",
1239 DeprecationWarning, stacklevel=2)
Pablo Galindod5d2b452019-04-30 02:01:14 +01001240 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
1241 getfullargspec(func)
1242 if kwonlyargs or ann:
1243 raise ValueError("Function has keyword-only parameters or annotations"
1244 ", use inspect.signature() API which can support them")
Yury Selivanov37dc2b22016-01-11 15:15:01 -05001245 return ArgSpec(args, varargs, varkw, defaults)
1246
Christian Heimes25bb7832008-01-11 16:17:00 +00001247FullArgSpec = namedtuple('FullArgSpec',
Pablo Galindod5d2b452019-04-30 02:01:14 +01001248 'args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations')
Guido van Rossum2e65f892007-02-28 22:03:49 +00001249
1250def getfullargspec(func):
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001251 """Get the names and default values of a callable object's parameters.
Guido van Rossum2e65f892007-02-28 22:03:49 +00001252
Brett Cannon504d8852007-09-07 02:12:14 +00001253 A tuple of seven things is returned:
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001254 (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations).
1255 'args' is a list of the parameter names.
1256 'varargs' and 'varkw' are the names of the * and ** parameters or None.
1257 'defaults' is an n-tuple of the default values of the last n parameters.
1258 'kwonlyargs' is a list of keyword-only parameter names.
Guido van Rossum2e65f892007-02-28 22:03:49 +00001259 'kwonlydefaults' is a dictionary mapping names from kwonlyargs to defaults.
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001260 'annotations' is a dictionary mapping parameter names to annotations.
Guido van Rossuma8add0e2007-05-14 22:03:55 +00001261
Nick Coghlan3c35fdb2016-12-02 20:29:57 +10001262 Notable differences from inspect.signature():
1263 - the "self" parameter is always reported, even for bound methods
1264 - wrapper chains defined by __wrapped__ *not* unwrapped automatically
Jeremy Hylton64967882003-06-27 18:14:39 +00001265 """
Yury Selivanov57d240e2014-02-19 16:27:23 -05001266 try:
1267 # Re: `skip_bound_arg=False`
1268 #
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001269 # There is a notable difference in behaviour between getfullargspec
1270 # and Signature: the former always returns 'self' parameter for bound
1271 # methods, whereas the Signature always shows the actual calling
1272 # signature of the passed object.
1273 #
1274 # To simulate this behaviour, we "unbind" bound methods, to trick
1275 # inspect.signature to always return their first parameter ("self",
1276 # usually)
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001277
Yury Selivanov57d240e2014-02-19 16:27:23 -05001278 # Re: `follow_wrapper_chains=False`
1279 #
1280 # getfullargspec() historically ignored __wrapped__ attributes,
1281 # so we ensure that remains the case in 3.3+
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001282
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001283 sig = _signature_from_callable(func,
1284 follow_wrapper_chains=False,
1285 skip_bound_arg=False,
larryhastings74613a42021-04-29 21:16:28 -07001286 sigcls=Signature,
1287 eval_str=False)
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001288 except Exception as ex:
1289 # Most of the times 'signature' will raise ValueError.
1290 # But, it can also raise AttributeError, and, maybe something
1291 # else. So to be fully backwards compatible, we catch all
1292 # possible exceptions here, and reraise a TypeError.
1293 raise TypeError('unsupported callable') from ex
1294
1295 args = []
1296 varargs = None
1297 varkw = None
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001298 posonlyargs = []
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001299 kwonlyargs = []
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001300 annotations = {}
1301 defaults = ()
1302 kwdefaults = {}
1303
1304 if sig.return_annotation is not sig.empty:
1305 annotations['return'] = sig.return_annotation
1306
1307 for param in sig.parameters.values():
1308 kind = param.kind
1309 name = param.name
1310
1311 if kind is _POSITIONAL_ONLY:
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001312 posonlyargs.append(name)
1313 if param.default is not param.empty:
1314 defaults += (param.default,)
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001315 elif kind is _POSITIONAL_OR_KEYWORD:
1316 args.append(name)
1317 if param.default is not param.empty:
1318 defaults += (param.default,)
1319 elif kind is _VAR_POSITIONAL:
1320 varargs = name
1321 elif kind is _KEYWORD_ONLY:
1322 kwonlyargs.append(name)
1323 if param.default is not param.empty:
1324 kwdefaults[name] = param.default
1325 elif kind is _VAR_KEYWORD:
1326 varkw = name
1327
1328 if param.annotation is not param.empty:
1329 annotations[name] = param.annotation
1330
1331 if not kwdefaults:
1332 # compatibility with 'func.__kwdefaults__'
1333 kwdefaults = None
1334
1335 if not defaults:
1336 # compatibility with 'func.__defaults__'
1337 defaults = None
1338
Pablo Galindod5d2b452019-04-30 02:01:14 +01001339 return FullArgSpec(posonlyargs + args, varargs, varkw, defaults,
1340 kwonlyargs, kwdefaults, annotations)
Yury Selivanovd82eddc2014-01-29 11:24:39 -05001341
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001342
Christian Heimes25bb7832008-01-11 16:17:00 +00001343ArgInfo = namedtuple('ArgInfo', 'args varargs keywords locals')
1344
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001345def getargvalues(frame):
1346 """Get information about arguments passed into a particular frame.
1347
1348 A tuple of four things is returned: (args, varargs, varkw, locals).
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001349 'args' is a list of the argument names.
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001350 'varargs' and 'varkw' are the names of the * and ** arguments or None.
1351 'locals' is the locals dictionary of the given frame."""
1352 args, varargs, varkw = getargs(frame.f_code)
Benjamin Peterson1a6e0d02008-10-25 15:49:17 +00001353 return ArgInfo(args, varargs, varkw, frame.f_locals)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001354
Guido van Rossum2e65f892007-02-28 22:03:49 +00001355def formatannotation(annotation, base_module=None):
Guido van Rossum52e50042016-10-22 07:55:18 -07001356 if getattr(annotation, '__module__', None) == 'typing':
1357 return repr(annotation).replace('typing.', '')
Guido van Rossum2e65f892007-02-28 22:03:49 +00001358 if isinstance(annotation, type):
Georg Brandl1a3284e2007-12-02 09:40:06 +00001359 if annotation.__module__ in ('builtins', base_module):
Serhiy Storchaka521e5862014-07-22 15:00:37 +03001360 return annotation.__qualname__
1361 return annotation.__module__+'.'+annotation.__qualname__
Guido van Rossum2e65f892007-02-28 22:03:49 +00001362 return repr(annotation)
Guido van Rossuma8add0e2007-05-14 22:03:55 +00001363
Guido van Rossum2e65f892007-02-28 22:03:49 +00001364def formatannotationrelativeto(object):
Guido van Rossuma8add0e2007-05-14 22:03:55 +00001365 module = getattr(object, '__module__', None)
1366 def _formatannotation(annotation):
1367 return formatannotation(annotation, module)
1368 return _formatannotation
Guido van Rossum2e65f892007-02-28 22:03:49 +00001369
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001370def formatargspec(args, varargs=None, varkw=None, defaults=None,
Pablo Galindod5d2b452019-04-30 02:01:14 +01001371 kwonlyargs=(), kwonlydefaults={}, annotations={},
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001372 formatarg=str,
1373 formatvarargs=lambda name: '*' + name,
1374 formatvarkw=lambda name: '**' + name,
1375 formatvalue=lambda value: '=' + repr(value),
Guido van Rossum2e65f892007-02-28 22:03:49 +00001376 formatreturns=lambda text: ' -> ' + text,
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001377 formatannotation=formatannotation):
Berker Peksagfa3922c2015-07-31 04:11:29 +03001378 """Format an argument spec from the values returned by getfullargspec.
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001379
Guido van Rossum2e65f892007-02-28 22:03:49 +00001380 The first seven arguments are (args, varargs, varkw, defaults,
1381 kwonlyargs, kwonlydefaults, annotations). The other five arguments
1382 are the corresponding optional formatting functions that are called to
1383 turn names and values into strings. The last argument is an optional
Matthias Bussonnier46c5cd02018-06-11 22:08:16 +02001384 function to format the sequence of arguments.
1385
1386 Deprecated since Python 3.5: use the `signature` function and `Signature`
1387 objects.
1388 """
1389
1390 from warnings import warn
1391
1392 warn("`formatargspec` is deprecated since Python 3.5. Use `signature` and "
Zackery Spytz41254eb2018-06-11 21:16:18 -06001393 "the `Signature` object directly",
Matthias Bussonnier46c5cd02018-06-11 22:08:16 +02001394 DeprecationWarning,
1395 stacklevel=2)
1396
Guido van Rossum2e65f892007-02-28 22:03:49 +00001397 def formatargandannotation(arg):
1398 result = formatarg(arg)
1399 if arg in annotations:
1400 result += ': ' + formatannotation(annotations[arg])
1401 return result
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001402 specs = []
1403 if defaults:
Pablo Galindod5d2b452019-04-30 02:01:14 +01001404 firstdefault = len(args) - len(defaults)
1405 for i, arg in enumerate(args):
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001406 spec = formatargandannotation(arg)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001407 if defaults and i >= firstdefault:
1408 spec = spec + formatvalue(defaults[i - firstdefault])
1409 specs.append(spec)
Raymond Hettinger936654b2002-06-01 03:06:31 +00001410 if varargs is not None:
Guido van Rossum2e65f892007-02-28 22:03:49 +00001411 specs.append(formatvarargs(formatargandannotation(varargs)))
1412 else:
1413 if kwonlyargs:
1414 specs.append('*')
1415 if kwonlyargs:
1416 for kwonlyarg in kwonlyargs:
1417 spec = formatargandannotation(kwonlyarg)
Benjamin Peterson9953a8d2009-01-17 04:15:01 +00001418 if kwonlydefaults and kwonlyarg in kwonlydefaults:
Guido van Rossum2e65f892007-02-28 22:03:49 +00001419 spec += formatvalue(kwonlydefaults[kwonlyarg])
1420 specs.append(spec)
Raymond Hettinger936654b2002-06-01 03:06:31 +00001421 if varkw is not None:
Guido van Rossum2e65f892007-02-28 22:03:49 +00001422 specs.append(formatvarkw(formatargandannotation(varkw)))
Neal Norwitz9d72bb42007-04-17 08:48:32 +00001423 result = '(' + ', '.join(specs) + ')'
Guido van Rossum2e65f892007-02-28 22:03:49 +00001424 if 'return' in annotations:
1425 result += formatreturns(formatannotation(annotations['return']))
1426 return result
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001427
1428def formatargvalues(args, varargs, varkw, locals,
1429 formatarg=str,
1430 formatvarargs=lambda name: '*' + name,
1431 formatvarkw=lambda name: '**' + name,
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001432 formatvalue=lambda value: '=' + repr(value)):
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001433 """Format an argument spec from the 4 values returned by getargvalues.
1434
1435 The first four arguments are (args, varargs, varkw, locals). The
1436 next four arguments are the corresponding optional formatting functions
1437 that are called to turn names and values into strings. The ninth
1438 argument is an optional function to format the sequence of arguments."""
1439 def convert(name, locals=locals,
1440 formatarg=formatarg, formatvalue=formatvalue):
1441 return formatarg(name) + formatvalue(locals[name])
1442 specs = []
1443 for i in range(len(args)):
Georg Brandlc1c4bf82010-10-15 16:07:41 +00001444 specs.append(convert(args[i]))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001445 if varargs:
1446 specs.append(formatvarargs(varargs) + formatvalue(locals[varargs]))
1447 if varkw:
1448 specs.append(formatvarkw(varkw) + formatvalue(locals[varkw]))
Neal Norwitz9d72bb42007-04-17 08:48:32 +00001449 return '(' + ', '.join(specs) + ')'
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001450
Benjamin Petersone109c702011-06-24 09:37:26 -05001451def _missing_arguments(f_name, argnames, pos, values):
1452 names = [repr(name) for name in argnames if name not in values]
1453 missing = len(names)
1454 if missing == 1:
1455 s = names[0]
1456 elif missing == 2:
1457 s = "{} and {}".format(*names)
1458 else:
Yury Selivanovdccfa132014-03-27 18:42:52 -04001459 tail = ", {} and {}".format(*names[-2:])
Benjamin Petersone109c702011-06-24 09:37:26 -05001460 del names[-2:]
1461 s = ", ".join(names) + tail
1462 raise TypeError("%s() missing %i required %s argument%s: %s" %
1463 (f_name, missing,
1464 "positional" if pos else "keyword-only",
1465 "" if missing == 1 else "s", s))
1466
1467def _too_many(f_name, args, kwonly, varargs, defcount, given, values):
Benjamin Petersonb204a422011-06-05 22:04:07 -05001468 atleast = len(args) - defcount
Benjamin Petersonb204a422011-06-05 22:04:07 -05001469 kwonly_given = len([arg for arg in kwonly if arg in values])
1470 if varargs:
1471 plural = atleast != 1
1472 sig = "at least %d" % (atleast,)
1473 elif defcount:
1474 plural = True
1475 sig = "from %d to %d" % (atleast, len(args))
1476 else:
1477 plural = len(args) != 1
1478 sig = str(len(args))
1479 kwonly_sig = ""
1480 if kwonly_given:
1481 msg = " positional argument%s (and %d keyword-only argument%s)"
1482 kwonly_sig = (msg % ("s" if given != 1 else "", kwonly_given,
1483 "s" if kwonly_given != 1 else ""))
1484 raise TypeError("%s() takes %s positional argument%s but %d%s %s given" %
1485 (f_name, sig, "s" if plural else "", given, kwonly_sig,
1486 "was" if given == 1 and not kwonly_given else "were"))
1487
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03001488def getcallargs(func, /, *positional, **named):
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001489 """Get the mapping of arguments to values.
1490
1491 A dict is returned, with keys the function argument names (including the
1492 names of the * and ** arguments, if any), and values the respective bound
1493 values from 'positional' and 'named'."""
1494 spec = getfullargspec(func)
Pablo Galindod5d2b452019-04-30 02:01:14 +01001495 args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = spec
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001496 f_name = func.__name__
1497 arg2value = {}
1498
Benjamin Petersonb204a422011-06-05 22:04:07 -05001499
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001500 if ismethod(func) and func.__self__ is not None:
1501 # implicit 'self' (or 'cls' for classmethods) argument
1502 positional = (func.__self__,) + positional
1503 num_pos = len(positional)
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001504 num_args = len(args)
1505 num_defaults = len(defaults) if defaults else 0
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001506
Benjamin Petersonb204a422011-06-05 22:04:07 -05001507 n = min(num_pos, num_args)
1508 for i in range(n):
Pablo Galindod5d2b452019-04-30 02:01:14 +01001509 arg2value[args[i]] = positional[i]
Benjamin Petersonb204a422011-06-05 22:04:07 -05001510 if varargs:
1511 arg2value[varargs] = tuple(positional[n:])
1512 possible_kwargs = set(args + kwonlyargs)
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001513 if varkw:
Benjamin Petersonb204a422011-06-05 22:04:07 -05001514 arg2value[varkw] = {}
1515 for kw, value in named.items():
1516 if kw not in possible_kwargs:
1517 if not varkw:
1518 raise TypeError("%s() got an unexpected keyword argument %r" %
1519 (f_name, kw))
1520 arg2value[varkw][kw] = value
1521 continue
1522 if kw in arg2value:
1523 raise TypeError("%s() got multiple values for argument %r" %
1524 (f_name, kw))
1525 arg2value[kw] = value
1526 if num_pos > num_args and not varargs:
Benjamin Petersone109c702011-06-24 09:37:26 -05001527 _too_many(f_name, args, kwonlyargs, varargs, num_defaults,
1528 num_pos, arg2value)
Benjamin Petersonb204a422011-06-05 22:04:07 -05001529 if num_pos < num_args:
Benjamin Petersone109c702011-06-24 09:37:26 -05001530 req = args[:num_args - num_defaults]
1531 for arg in req:
Benjamin Petersonb204a422011-06-05 22:04:07 -05001532 if arg not in arg2value:
Benjamin Petersone109c702011-06-24 09:37:26 -05001533 _missing_arguments(f_name, req, True, arg2value)
Benjamin Petersonb204a422011-06-05 22:04:07 -05001534 for i, arg in enumerate(args[num_args - num_defaults:]):
1535 if arg not in arg2value:
1536 arg2value[arg] = defaults[i]
Benjamin Petersone109c702011-06-24 09:37:26 -05001537 missing = 0
Benjamin Petersonb204a422011-06-05 22:04:07 -05001538 for kwarg in kwonlyargs:
1539 if kwarg not in arg2value:
Yury Selivanov875df202014-03-27 18:23:03 -04001540 if kwonlydefaults and kwarg in kwonlydefaults:
Benjamin Petersone109c702011-06-24 09:37:26 -05001541 arg2value[kwarg] = kwonlydefaults[kwarg]
1542 else:
1543 missing += 1
1544 if missing:
1545 _missing_arguments(f_name, kwonlyargs, False, arg2value)
Benjamin Peterson25cd7eb2010-03-30 18:42:32 +00001546 return arg2value
1547
Nick Coghlan2f92e542012-06-23 19:39:55 +10001548ClosureVars = namedtuple('ClosureVars', 'nonlocals globals builtins unbound')
1549
1550def getclosurevars(func):
1551 """
1552 Get the mapping of free variables to their current values.
1553
Meador Inge8fda3592012-07-19 21:33:21 -05001554 Returns a named tuple of dicts mapping the current nonlocal, global
Nick Coghlan2f92e542012-06-23 19:39:55 +10001555 and builtin references as seen by the body of the function. A final
1556 set of unbound names that could not be resolved is also provided.
1557 """
1558
1559 if ismethod(func):
1560 func = func.__func__
1561
1562 if not isfunction(func):
Serhiy Storchakaa4a30202017-11-28 22:54:42 +02001563 raise TypeError("{!r} is not a Python function".format(func))
Nick Coghlan2f92e542012-06-23 19:39:55 +10001564
1565 code = func.__code__
1566 # Nonlocal references are named in co_freevars and resolved
1567 # by looking them up in __closure__ by positional index
1568 if func.__closure__ is None:
1569 nonlocal_vars = {}
1570 else:
1571 nonlocal_vars = {
1572 var : cell.cell_contents
1573 for var, cell in zip(code.co_freevars, func.__closure__)
1574 }
1575
1576 # Global and builtin references are named in co_names and resolved
1577 # by looking them up in __globals__ or __builtins__
1578 global_ns = func.__globals__
1579 builtin_ns = global_ns.get("__builtins__", builtins.__dict__)
1580 if ismodule(builtin_ns):
1581 builtin_ns = builtin_ns.__dict__
1582 global_vars = {}
1583 builtin_vars = {}
1584 unbound_names = set()
1585 for name in code.co_names:
1586 if name in ("None", "True", "False"):
1587 # Because these used to be builtins instead of keywords, they
1588 # may still show up as name references. We ignore them.
1589 continue
1590 try:
1591 global_vars[name] = global_ns[name]
1592 except KeyError:
1593 try:
1594 builtin_vars[name] = builtin_ns[name]
1595 except KeyError:
1596 unbound_names.add(name)
1597
1598 return ClosureVars(nonlocal_vars, global_vars,
1599 builtin_vars, unbound_names)
1600
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001601# -------------------------------------------------- stack frame extraction
Christian Heimes25bb7832008-01-11 16:17:00 +00001602
1603Traceback = namedtuple('Traceback', 'filename lineno function code_context index')
1604
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001605def getframeinfo(frame, context=1):
1606 """Get information about a frame or traceback object.
1607
1608 A tuple of five things is returned: the filename, the line number of
1609 the current line, the function name, a list of lines of context from
1610 the source code, and the index of the current line within that list.
1611 The optional second argument specifies the number of lines of context
1612 to return, which are centered around the current line."""
1613 if istraceback(frame):
Andrew M. Kuchlingba8b6bc2004-06-05 14:11:59 +00001614 lineno = frame.tb_lineno
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001615 frame = frame.tb_frame
Andrew M. Kuchlingba8b6bc2004-06-05 14:11:59 +00001616 else:
1617 lineno = frame.f_lineno
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001618 if not isframe(frame):
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +00001619 raise TypeError('{!r} is not a frame or traceback object'.format(frame))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001620
Neil Schemenauerf06f8532002-03-23 23:51:04 +00001621 filename = getsourcefile(frame) or getfile(frame)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001622 if context > 0:
Guido van Rossum54e54c62001-09-04 19:14:14 +00001623 start = lineno - 1 - context//2
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001624 try:
1625 lines, lnum = findsource(frame)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02001626 except OSError:
Ka-Ping Yee4eb0c002001-03-02 05:50:34 +00001627 lines = index = None
1628 else:
Raymond Hettingera0501712004-06-15 11:22:53 +00001629 start = max(0, min(start, len(lines) - context))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001630 lines = lines[start:start+context]
Ka-Ping Yee59ade082001-03-01 03:55:35 +00001631 index = lineno - 1 - start
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001632 else:
1633 lines = index = None
1634
Christian Heimes25bb7832008-01-11 16:17:00 +00001635 return Traceback(filename, lineno, frame.f_code.co_name, lines, index)
Ka-Ping Yee59ade082001-03-01 03:55:35 +00001636
1637def getlineno(frame):
1638 """Get the line number from a frame object, allowing for optimization."""
Michael W. Hudsondd32a912002-08-15 14:59:02 +00001639 # FrameType.f_lineno is now a descriptor that grovels co_lnotab
1640 return frame.f_lineno
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001641
Antoine Pitroucdcafb72014-08-24 10:50:28 -04001642FrameInfo = namedtuple('FrameInfo', ('frame',) + Traceback._fields)
1643
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001644def getouterframes(frame, context=1):
1645 """Get a list of records for a frame and all higher (calling) frames.
1646
1647 Each record contains a frame object, filename, line number, function
1648 name, a list of lines of context, and index within the context."""
1649 framelist = []
1650 while frame:
Antoine Pitroucdcafb72014-08-24 10:50:28 -04001651 frameinfo = (frame,) + getframeinfo(frame, context)
1652 framelist.append(FrameInfo(*frameinfo))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001653 frame = frame.f_back
1654 return framelist
1655
1656def getinnerframes(tb, context=1):
1657 """Get a list of records for a traceback's frame and all lower frames.
1658
1659 Each record contains a frame object, filename, line number, function
1660 name, a list of lines of context, and index within the context."""
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001661 framelist = []
1662 while tb:
Antoine Pitroucdcafb72014-08-24 10:50:28 -04001663 frameinfo = (tb.tb_frame,) + getframeinfo(tb, context)
1664 framelist.append(FrameInfo(*frameinfo))
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001665 tb = tb.tb_next
1666 return framelist
1667
Benjamin Peterson42ac4752010-08-09 13:05:35 +00001668def currentframe():
Benjamin Petersona3a3fc62010-08-09 15:49:56 +00001669 """Return the frame of the caller or None if this is not possible."""
Benjamin Peterson42ac4752010-08-09 13:05:35 +00001670 return sys._getframe(1) if hasattr(sys, "_getframe") else None
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001671
1672def stack(context=1):
1673 """Return a list of records for the stack above the caller's frame."""
Jeremy Hyltonab919022003-06-27 18:41:20 +00001674 return getouterframes(sys._getframe(1), context)
Ka-Ping Yee6397c7c2001-02-27 14:43:21 +00001675
1676def trace(context=1):
Tim Peters85ba6732001-02-28 08:26:44 +00001677 """Return a list of records for the stack below the current exception."""
Fred Draked451ec12002-04-26 02:29:55 +00001678 return getinnerframes(sys.exc_info()[2], context)
Michael Foord95fc51d2010-11-20 15:07:30 +00001679
1680
1681# ------------------------------------------------ static version of getattr
1682
1683_sentinel = object()
1684
Michael Foorde5162652010-11-20 16:40:44 +00001685def _static_getmro(klass):
1686 return type.__dict__['__mro__'].__get__(klass)
1687
Michael Foord95fc51d2010-11-20 15:07:30 +00001688def _check_instance(obj, attr):
1689 instance_dict = {}
1690 try:
1691 instance_dict = object.__getattribute__(obj, "__dict__")
1692 except AttributeError:
1693 pass
Michael Foorddcebe0f2011-03-15 19:20:44 -04001694 return dict.get(instance_dict, attr, _sentinel)
Michael Foord95fc51d2010-11-20 15:07:30 +00001695
1696
1697def _check_class(klass, attr):
Michael Foorde5162652010-11-20 16:40:44 +00001698 for entry in _static_getmro(klass):
Michael Foorda51623b2011-12-18 22:01:40 +00001699 if _shadowed_dict(type(entry)) is _sentinel:
Michael Foorddcebe0f2011-03-15 19:20:44 -04001700 try:
1701 return entry.__dict__[attr]
1702 except KeyError:
1703 pass
Michael Foord95fc51d2010-11-20 15:07:30 +00001704 return _sentinel
1705
Michael Foord35184ed2010-11-20 16:58:30 +00001706def _is_type(obj):
1707 try:
1708 _static_getmro(obj)
1709 except TypeError:
1710 return False
1711 return True
1712
Michael Foorddcebe0f2011-03-15 19:20:44 -04001713def _shadowed_dict(klass):
1714 dict_attr = type.__dict__["__dict__"]
1715 for entry in _static_getmro(klass):
1716 try:
1717 class_dict = dict_attr.__get__(entry)["__dict__"]
1718 except KeyError:
1719 pass
1720 else:
Inada Naoki8f9cc872019-09-05 13:07:08 +09001721 if not (type(class_dict) is types.GetSetDescriptorType and
Michael Foorddcebe0f2011-03-15 19:20:44 -04001722 class_dict.__name__ == "__dict__" and
1723 class_dict.__objclass__ is entry):
Michael Foorda51623b2011-12-18 22:01:40 +00001724 return class_dict
1725 return _sentinel
Michael Foord95fc51d2010-11-20 15:07:30 +00001726
1727def getattr_static(obj, attr, default=_sentinel):
1728 """Retrieve attributes without triggering dynamic lookup via the
1729 descriptor protocol, __getattr__ or __getattribute__.
1730
1731 Note: this function may not be able to retrieve all attributes
1732 that getattr can fetch (like dynamically created attributes)
1733 and may find attributes that getattr can't (like descriptors
1734 that raise AttributeError). It can also return descriptor objects
1735 instead of instance members in some cases. See the
1736 documentation for details.
1737 """
1738 instance_result = _sentinel
Michael Foord35184ed2010-11-20 16:58:30 +00001739 if not _is_type(obj):
Michael Foordcc7ebb82010-11-20 16:20:16 +00001740 klass = type(obj)
Michael Foorda51623b2011-12-18 22:01:40 +00001741 dict_attr = _shadowed_dict(klass)
1742 if (dict_attr is _sentinel or
Inada Naoki8f9cc872019-09-05 13:07:08 +09001743 type(dict_attr) is types.MemberDescriptorType):
Michael Foorddcebe0f2011-03-15 19:20:44 -04001744 instance_result = _check_instance(obj, attr)
Michael Foord95fc51d2010-11-20 15:07:30 +00001745 else:
1746 klass = obj
1747
1748 klass_result = _check_class(klass, attr)
1749
1750 if instance_result is not _sentinel and klass_result is not _sentinel:
1751 if (_check_class(type(klass_result), '__get__') is not _sentinel and
1752 _check_class(type(klass_result), '__set__') is not _sentinel):
1753 return klass_result
1754
1755 if instance_result is not _sentinel:
1756 return instance_result
1757 if klass_result is not _sentinel:
1758 return klass_result
1759
1760 if obj is klass:
1761 # for types we check the metaclass too
Michael Foorde5162652010-11-20 16:40:44 +00001762 for entry in _static_getmro(type(klass)):
Michael Foord3ba95f82011-12-22 01:13:37 +00001763 if _shadowed_dict(type(entry)) is _sentinel:
1764 try:
1765 return entry.__dict__[attr]
1766 except KeyError:
1767 pass
Michael Foord95fc51d2010-11-20 15:07:30 +00001768 if default is not _sentinel:
1769 return default
1770 raise AttributeError(attr)
Nick Coghlane0f04652010-11-21 03:44:04 +00001771
1772
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001773# ------------------------------------------------ generator introspection
1774
Nick Coghlan7921b9f2010-11-30 06:36:04 +00001775GEN_CREATED = 'GEN_CREATED'
1776GEN_RUNNING = 'GEN_RUNNING'
1777GEN_SUSPENDED = 'GEN_SUSPENDED'
1778GEN_CLOSED = 'GEN_CLOSED'
Nick Coghlane0f04652010-11-21 03:44:04 +00001779
1780def getgeneratorstate(generator):
1781 """Get current state of a generator-iterator.
1782
1783 Possible states are:
1784 GEN_CREATED: Waiting to start execution.
1785 GEN_RUNNING: Currently being executed by the interpreter.
1786 GEN_SUSPENDED: Currently suspended at a yield expression.
1787 GEN_CLOSED: Execution has completed.
1788 """
1789 if generator.gi_running:
1790 return GEN_RUNNING
1791 if generator.gi_frame is None:
1792 return GEN_CLOSED
1793 if generator.gi_frame.f_lasti == -1:
1794 return GEN_CREATED
1795 return GEN_SUSPENDED
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001796
1797
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001798def getgeneratorlocals(generator):
1799 """
1800 Get the mapping of generator local variables to their current values.
1801
1802 A dict is returned, with the keys the local variable names and values the
1803 bound values."""
1804
1805 if not isgenerator(generator):
Serhiy Storchakaa4a30202017-11-28 22:54:42 +02001806 raise TypeError("{!r} is not a Python generator".format(generator))
Nick Coghlan04e2e3f2012-06-23 19:52:05 +10001807
1808 frame = getattr(generator, "gi_frame", None)
1809 if frame is not None:
1810 return generator.gi_frame.f_locals
1811 else:
1812 return {}
1813
Yury Selivanov5376ba92015-06-22 12:19:30 -04001814
1815# ------------------------------------------------ coroutine introspection
1816
1817CORO_CREATED = 'CORO_CREATED'
1818CORO_RUNNING = 'CORO_RUNNING'
1819CORO_SUSPENDED = 'CORO_SUSPENDED'
1820CORO_CLOSED = 'CORO_CLOSED'
1821
1822def getcoroutinestate(coroutine):
1823 """Get current state of a coroutine object.
1824
1825 Possible states are:
1826 CORO_CREATED: Waiting to start execution.
1827 CORO_RUNNING: Currently being executed by the interpreter.
1828 CORO_SUSPENDED: Currently suspended at an await expression.
1829 CORO_CLOSED: Execution has completed.
1830 """
1831 if coroutine.cr_running:
1832 return CORO_RUNNING
1833 if coroutine.cr_frame is None:
1834 return CORO_CLOSED
1835 if coroutine.cr_frame.f_lasti == -1:
1836 return CORO_CREATED
1837 return CORO_SUSPENDED
1838
1839
1840def getcoroutinelocals(coroutine):
1841 """
1842 Get the mapping of coroutine local variables to their current values.
1843
1844 A dict is returned, with the keys the local variable names and values the
1845 bound values."""
1846 frame = getattr(coroutine, "cr_frame", None)
1847 if frame is not None:
1848 return frame.f_locals
1849 else:
1850 return {}
1851
1852
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001853###############################################################################
1854### Function Signature Object (PEP 362)
1855###############################################################################
1856
1857
1858_WrapperDescriptor = type(type.__call__)
1859_MethodWrapper = type(all.__call__)
Larry Hastings5c661892014-01-24 06:17:25 -08001860_ClassMethodWrapper = type(int.__dict__['from_bytes'])
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001861
1862_NonUserDefinedCallables = (_WrapperDescriptor,
1863 _MethodWrapper,
Larry Hastings5c661892014-01-24 06:17:25 -08001864 _ClassMethodWrapper,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001865 types.BuiltinFunctionType)
1866
1867
Yury Selivanov421f0c72014-01-29 12:05:40 -05001868def _signature_get_user_defined_method(cls, method_name):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001869 """Private helper. Checks if ``cls`` has an attribute
1870 named ``method_name`` and returns it only if it is a
1871 pure python function.
1872 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07001873 try:
1874 meth = getattr(cls, method_name)
1875 except AttributeError:
1876 return
1877 else:
1878 if not isinstance(meth, _NonUserDefinedCallables):
1879 # Once '__signature__' will be added to 'C'-level
1880 # callables, this check won't be necessary
1881 return meth
1882
1883
Yury Selivanov62560fb2014-01-28 12:26:24 -05001884def _signature_get_partial(wrapped_sig, partial, extra_args=()):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001885 """Private helper to calculate how 'wrapped_sig' signature will
1886 look like after applying a 'functools.partial' object (or alike)
1887 on it.
1888 """
Yury Selivanov62560fb2014-01-28 12:26:24 -05001889
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001890 old_params = wrapped_sig.parameters
Inada Naoki21105512020-03-02 18:54:49 +09001891 new_params = OrderedDict(old_params.items())
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05001892
1893 partial_args = partial.args or ()
1894 partial_keywords = partial.keywords or {}
1895
1896 if extra_args:
1897 partial_args = extra_args + partial_args
1898
1899 try:
1900 ba = wrapped_sig.bind_partial(*partial_args, **partial_keywords)
1901 except TypeError as ex:
1902 msg = 'partial object {!r} has incorrect arguments'.format(partial)
1903 raise ValueError(msg) from ex
1904
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05001905
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001906 transform_to_kwonly = False
1907 for param_name, param in old_params.items():
1908 try:
1909 arg_value = ba.arguments[param_name]
1910 except KeyError:
1911 pass
1912 else:
1913 if param.kind is _POSITIONAL_ONLY:
1914 # If positional-only parameter is bound by partial,
1915 # it effectively disappears from the signature
Inada Naoki21105512020-03-02 18:54:49 +09001916 new_params.pop(param_name)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001917 continue
1918
1919 if param.kind is _POSITIONAL_OR_KEYWORD:
1920 if param_name in partial_keywords:
1921 # This means that this parameter, and all parameters
1922 # after it should be keyword-only (and var-positional
1923 # should be removed). Here's why. Consider the following
1924 # function:
1925 # foo(a, b, *args, c):
1926 # pass
1927 #
1928 # "partial(foo, a='spam')" will have the following
1929 # signature: "(*, a='spam', b, c)". Because attempting
1930 # to call that partial with "(10, 20)" arguments will
1931 # raise a TypeError, saying that "a" argument received
1932 # multiple values.
1933 transform_to_kwonly = True
1934 # Set the new default value
Inada Naoki21105512020-03-02 18:54:49 +09001935 new_params[param_name] = param.replace(default=arg_value)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001936 else:
1937 # was passed as a positional argument
Inada Naoki21105512020-03-02 18:54:49 +09001938 new_params.pop(param.name)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001939 continue
1940
1941 if param.kind is _KEYWORD_ONLY:
1942 # Set the new default value
Inada Naoki21105512020-03-02 18:54:49 +09001943 new_params[param_name] = param.replace(default=arg_value)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001944
1945 if transform_to_kwonly:
1946 assert param.kind is not _POSITIONAL_ONLY
1947
1948 if param.kind is _POSITIONAL_OR_KEYWORD:
Inada Naoki21105512020-03-02 18:54:49 +09001949 new_param = new_params[param_name].replace(kind=_KEYWORD_ONLY)
1950 new_params[param_name] = new_param
1951 new_params.move_to_end(param_name)
Yury Selivanov3f73ca22014-04-08 11:30:45 -04001952 elif param.kind in (_KEYWORD_ONLY, _VAR_KEYWORD):
Inada Naoki21105512020-03-02 18:54:49 +09001953 new_params.move_to_end(param_name)
1954 elif param.kind is _VAR_POSITIONAL:
1955 new_params.pop(param.name)
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05001956
1957 return wrapped_sig.replace(parameters=new_params.values())
1958
1959
Yury Selivanov62560fb2014-01-28 12:26:24 -05001960def _signature_bound_method(sig):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001961 """Private helper to transform signatures for unbound
1962 functions to bound methods.
1963 """
Yury Selivanov62560fb2014-01-28 12:26:24 -05001964
1965 params = tuple(sig.parameters.values())
1966
1967 if not params or params[0].kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
1968 raise ValueError('invalid method signature')
1969
1970 kind = params[0].kind
1971 if kind in (_POSITIONAL_OR_KEYWORD, _POSITIONAL_ONLY):
1972 # Drop first parameter:
1973 # '(p1, p2[, ...])' -> '(p2[, ...])'
1974 params = params[1:]
1975 else:
1976 if kind is not _VAR_POSITIONAL:
1977 # Unless we add a new parameter type we never
1978 # get here
1979 raise ValueError('invalid argument type')
1980 # It's a var-positional parameter.
1981 # Do nothing. '(*args[, ...])' -> '(*args[, ...])'
1982
1983 return sig.replace(parameters=params)
1984
1985
Yury Selivanovb77511d2014-01-29 10:46:14 -05001986def _signature_is_builtin(obj):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001987 """Private helper to test if `obj` is a callable that might
1988 support Argument Clinic's __text_signature__ protocol.
1989 """
Yury Selivanov1d241832014-02-02 12:51:20 -05001990 return (isbuiltin(obj) or
Yury Selivanovb77511d2014-01-29 10:46:14 -05001991 ismethoddescriptor(obj) or
Yury Selivanov1d241832014-02-02 12:51:20 -05001992 isinstance(obj, _NonUserDefinedCallables) or
Yury Selivanovb77511d2014-01-29 10:46:14 -05001993 # Can't test 'isinstance(type)' here, as it would
1994 # also be True for regular python classes
1995 obj in (type, object))
1996
1997
Yury Selivanov63da7c72014-01-31 14:48:37 -05001998def _signature_is_functionlike(obj):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04001999 """Private helper to test if `obj` is a duck type of FunctionType.
2000 A good example of such objects are functions compiled with
2001 Cython, which have all attributes that a pure Python function
2002 would have, but have their code statically compiled.
2003 """
Yury Selivanov63da7c72014-01-31 14:48:37 -05002004
2005 if not callable(obj) or isclass(obj):
2006 # All function-like objects are obviously callables,
2007 # and not classes.
2008 return False
2009
2010 name = getattr(obj, '__name__', None)
2011 code = getattr(obj, '__code__', None)
2012 defaults = getattr(obj, '__defaults__', _void) # Important to use _void ...
2013 kwdefaults = getattr(obj, '__kwdefaults__', _void) # ... and not None here
Pablo Galindob0544ba2021-04-21 12:41:19 +01002014 annotations = getattr(obj, '__annotations__', None)
Yury Selivanov63da7c72014-01-31 14:48:37 -05002015
2016 return (isinstance(code, types.CodeType) and
2017 isinstance(name, str) and
2018 (defaults is None or isinstance(defaults, tuple)) and
2019 (kwdefaults is None or isinstance(kwdefaults, dict)) and
larryhastings74613a42021-04-29 21:16:28 -07002020 (isinstance(annotations, (dict)) or annotations is None) )
Yury Selivanov63da7c72014-01-31 14:48:37 -05002021
2022
Yury Selivanovd82eddc2014-01-29 11:24:39 -05002023def _signature_get_bound_param(spec):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002024 """ Private helper to get first parameter name from a
2025 __text_signature__ of a builtin method, which should
2026 be in the following format: '($param1, ...)'.
2027 Assumptions are that the first argument won't have
2028 a default value or an annotation.
2029 """
Yury Selivanovd82eddc2014-01-29 11:24:39 -05002030
2031 assert spec.startswith('($')
2032
2033 pos = spec.find(',')
2034 if pos == -1:
2035 pos = spec.find(')')
2036
2037 cpos = spec.find(':')
2038 assert cpos == -1 or cpos > pos
2039
2040 cpos = spec.find('=')
2041 assert cpos == -1 or cpos > pos
2042
2043 return spec[2:pos]
2044
2045
Larry Hastings2623c8c2014-02-08 22:15:29 -08002046def _signature_strip_non_python_syntax(signature):
2047 """
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002048 Private helper function. Takes a signature in Argument Clinic's
2049 extended signature format.
2050
Larry Hastings2623c8c2014-02-08 22:15:29 -08002051 Returns a tuple of three things:
2052 * that signature re-rendered in standard Python syntax,
2053 * the index of the "self" parameter (generally 0), or None if
2054 the function does not have a "self" parameter, and
2055 * the index of the last "positional only" parameter,
2056 or None if the signature has no positional-only parameters.
2057 """
2058
2059 if not signature:
2060 return signature, None, None
2061
2062 self_parameter = None
2063 last_positional_only = None
2064
2065 lines = [l.encode('ascii') for l in signature.split('\n')]
2066 generator = iter(lines).__next__
2067 token_stream = tokenize.tokenize(generator)
2068
2069 delayed_comma = False
2070 skip_next_comma = False
2071 text = []
2072 add = text.append
2073
2074 current_parameter = 0
2075 OP = token.OP
2076 ERRORTOKEN = token.ERRORTOKEN
2077
2078 # token stream always starts with ENCODING token, skip it
2079 t = next(token_stream)
2080 assert t.type == tokenize.ENCODING
2081
2082 for t in token_stream:
2083 type, string = t.type, t.string
2084
2085 if type == OP:
2086 if string == ',':
2087 if skip_next_comma:
2088 skip_next_comma = False
2089 else:
2090 assert not delayed_comma
2091 delayed_comma = True
2092 current_parameter += 1
2093 continue
2094
2095 if string == '/':
2096 assert not skip_next_comma
2097 assert last_positional_only is None
2098 skip_next_comma = True
2099 last_positional_only = current_parameter - 1
2100 continue
2101
2102 if (type == ERRORTOKEN) and (string == '$'):
2103 assert self_parameter is None
2104 self_parameter = current_parameter
2105 continue
2106
2107 if delayed_comma:
2108 delayed_comma = False
2109 if not ((type == OP) and (string == ')')):
2110 add(', ')
2111 add(string)
2112 if (string == ','):
2113 add(' ')
2114 clean_signature = ''.join(text)
2115 return clean_signature, self_parameter, last_positional_only
2116
2117
Yury Selivanov57d240e2014-02-19 16:27:23 -05002118def _signature_fromstr(cls, obj, s, skip_bound_arg=True):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002119 """Private helper to parse content of '__text_signature__'
2120 and return a Signature based on it.
2121 """
INADA Naoki37420de2018-01-27 10:10:06 +09002122 # Lazy import ast because it's relatively heavy and
2123 # it's not used for other than this function.
2124 import ast
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002125
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002126 Parameter = cls._parameter_cls
2127
Larry Hastings2623c8c2014-02-08 22:15:29 -08002128 clean_signature, self_parameter, last_positional_only = \
2129 _signature_strip_non_python_syntax(s)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002130
Larry Hastings2623c8c2014-02-08 22:15:29 -08002131 program = "def foo" + clean_signature + ": pass"
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002132
2133 try:
Larry Hastings2623c8c2014-02-08 22:15:29 -08002134 module = ast.parse(program)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002135 except SyntaxError:
2136 module = None
2137
2138 if not isinstance(module, ast.Module):
2139 raise ValueError("{!r} builtin has invalid signature".format(obj))
2140
2141 f = module.body[0]
2142
2143 parameters = []
2144 empty = Parameter.empty
2145 invalid = object()
2146
2147 module = None
2148 module_dict = {}
2149 module_name = getattr(obj, '__module__', None)
2150 if module_name:
2151 module = sys.modules.get(module_name, None)
2152 if module:
2153 module_dict = module.__dict__
INADA Naoki6f85b822018-10-05 01:47:09 +09002154 sys_module_dict = sys.modules.copy()
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002155
2156 def parse_name(node):
2157 assert isinstance(node, ast.arg)
Srinivas Reddy Thatiparthy (శ్రీనివాస్ రెడ్డి తాటిపర్తి)feaefc72018-02-09 15:29:19 +05302158 if node.annotation is not None:
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002159 raise ValueError("Annotations are not currently supported")
2160 return node.arg
2161
2162 def wrap_value(s):
2163 try:
2164 value = eval(s, module_dict)
2165 except NameError:
2166 try:
2167 value = eval(s, sys_module_dict)
2168 except NameError:
2169 raise RuntimeError()
2170
Serhiy Storchaka3f228112018-09-27 17:42:37 +03002171 if isinstance(value, (str, int, float, bytes, bool, type(None))):
2172 return ast.Constant(value)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002173 raise RuntimeError()
2174
2175 class RewriteSymbolics(ast.NodeTransformer):
2176 def visit_Attribute(self, node):
2177 a = []
2178 n = node
2179 while isinstance(n, ast.Attribute):
2180 a.append(n.attr)
2181 n = n.value
2182 if not isinstance(n, ast.Name):
2183 raise RuntimeError()
2184 a.append(n.id)
2185 value = ".".join(reversed(a))
2186 return wrap_value(value)
2187
2188 def visit_Name(self, node):
2189 if not isinstance(node.ctx, ast.Load):
2190 raise ValueError()
2191 return wrap_value(node.id)
2192
2193 def p(name_node, default_node, default=empty):
2194 name = parse_name(name_node)
2195 if name is invalid:
2196 return None
2197 if default_node and default_node is not _empty:
2198 try:
2199 default_node = RewriteSymbolics().visit(default_node)
2200 o = ast.literal_eval(default_node)
2201 except ValueError:
2202 o = invalid
2203 if o is invalid:
2204 return None
2205 default = o if o is not invalid else default
2206 parameters.append(Parameter(name, kind, default=default, annotation=empty))
2207
2208 # non-keyword-only parameters
2209 args = reversed(f.args.args)
2210 defaults = reversed(f.args.defaults)
2211 iter = itertools.zip_longest(args, defaults, fillvalue=None)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002212 if last_positional_only is not None:
2213 kind = Parameter.POSITIONAL_ONLY
2214 else:
2215 kind = Parameter.POSITIONAL_OR_KEYWORD
2216 for i, (name, default) in enumerate(reversed(list(iter))):
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002217 p(name, default)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002218 if i == last_positional_only:
2219 kind = Parameter.POSITIONAL_OR_KEYWORD
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002220
2221 # *args
2222 if f.args.vararg:
2223 kind = Parameter.VAR_POSITIONAL
2224 p(f.args.vararg, empty)
2225
2226 # keyword-only arguments
2227 kind = Parameter.KEYWORD_ONLY
2228 for name, default in zip(f.args.kwonlyargs, f.args.kw_defaults):
2229 p(name, default)
2230
2231 # **kwargs
2232 if f.args.kwarg:
2233 kind = Parameter.VAR_KEYWORD
2234 p(f.args.kwarg, empty)
2235
Larry Hastings2623c8c2014-02-08 22:15:29 -08002236 if self_parameter is not None:
Yury Selivanov8c185ee2014-02-21 01:32:42 -05002237 # Possibly strip the bound argument:
2238 # - We *always* strip first bound argument if
2239 # it is a module.
2240 # - We don't strip first bound argument if
2241 # skip_bound_arg is False.
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002242 assert parameters
Yury Selivanov8c185ee2014-02-21 01:32:42 -05002243 _self = getattr(obj, '__self__', None)
2244 self_isbound = _self is not None
2245 self_ismodule = ismodule(_self)
2246 if self_isbound and (self_ismodule or skip_bound_arg):
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002247 parameters.pop(0)
2248 else:
2249 # for builtins, self parameter is always positional-only!
2250 p = parameters[0].replace(kind=Parameter.POSITIONAL_ONLY)
2251 parameters[0] = p
2252
2253 return cls(parameters, return_annotation=cls.empty)
2254
2255
Yury Selivanov57d240e2014-02-19 16:27:23 -05002256def _signature_from_builtin(cls, func, skip_bound_arg=True):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002257 """Private helper function to get signature for
2258 builtin callables.
2259 """
2260
Yury Selivanov57d240e2014-02-19 16:27:23 -05002261 if not _signature_is_builtin(func):
2262 raise TypeError("{!r} is not a Python builtin "
2263 "function".format(func))
2264
2265 s = getattr(func, "__text_signature__", None)
2266 if not s:
2267 raise ValueError("no signature found for builtin {!r}".format(func))
2268
2269 return _signature_fromstr(cls, func, s, skip_bound_arg)
2270
2271
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002272def _signature_from_function(cls, func, skip_bound_arg=True,
larryhastings74613a42021-04-29 21:16:28 -07002273 globals=None, locals=None, eval_str=False):
Yury Selivanovcf45f022015-05-20 14:38:50 -04002274 """Private helper: constructs Signature for the given python function."""
2275
2276 is_duck_function = False
2277 if not isfunction(func):
2278 if _signature_is_functionlike(func):
2279 is_duck_function = True
2280 else:
2281 # If it's not a pure Python function, and not a duck type
2282 # of pure function:
2283 raise TypeError('{!r} is not a Python function'.format(func))
2284
Serhiy Storchakad53cf992019-05-06 22:40:27 +03002285 s = getattr(func, "__text_signature__", None)
2286 if s:
2287 return _signature_fromstr(cls, func, s, skip_bound_arg)
2288
Yury Selivanovcf45f022015-05-20 14:38:50 -04002289 Parameter = cls._parameter_cls
2290
2291 # Parameter information.
2292 func_code = func.__code__
2293 pos_count = func_code.co_argcount
2294 arg_names = func_code.co_varnames
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002295 posonly_count = func_code.co_posonlyargcount
Pablo Galindocd74e662019-06-01 18:08:04 +01002296 positional = arg_names[:pos_count]
Yury Selivanovcf45f022015-05-20 14:38:50 -04002297 keyword_only_count = func_code.co_kwonlyargcount
Pablo Galindocd74e662019-06-01 18:08:04 +01002298 keyword_only = arg_names[pos_count:pos_count + keyword_only_count]
larryhastings74613a42021-04-29 21:16:28 -07002299 annotations = get_annotations(func, globals=globals, locals=locals, eval_str=eval_str)
Yury Selivanovcf45f022015-05-20 14:38:50 -04002300 defaults = func.__defaults__
2301 kwdefaults = func.__kwdefaults__
2302
2303 if defaults:
2304 pos_default_count = len(defaults)
2305 else:
2306 pos_default_count = 0
2307
2308 parameters = []
2309
Pablo Galindocd74e662019-06-01 18:08:04 +01002310 non_default_count = pos_count - pos_default_count
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002311 posonly_left = posonly_count
2312
Yury Selivanovcf45f022015-05-20 14:38:50 -04002313 # Non-keyword-only parameters w/o defaults.
Pablo Galindocd74e662019-06-01 18:08:04 +01002314 for name in positional[:non_default_count]:
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002315 kind = _POSITIONAL_ONLY if posonly_left else _POSITIONAL_OR_KEYWORD
Yury Selivanovcf45f022015-05-20 14:38:50 -04002316 annotation = annotations.get(name, _empty)
2317 parameters.append(Parameter(name, annotation=annotation,
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002318 kind=kind))
2319 if posonly_left:
2320 posonly_left -= 1
Yury Selivanovcf45f022015-05-20 14:38:50 -04002321
2322 # ... w/ defaults.
Pablo Galindocd74e662019-06-01 18:08:04 +01002323 for offset, name in enumerate(positional[non_default_count:]):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002324 kind = _POSITIONAL_ONLY if posonly_left else _POSITIONAL_OR_KEYWORD
Yury Selivanovcf45f022015-05-20 14:38:50 -04002325 annotation = annotations.get(name, _empty)
2326 parameters.append(Parameter(name, annotation=annotation,
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002327 kind=kind,
Yury Selivanovcf45f022015-05-20 14:38:50 -04002328 default=defaults[offset]))
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01002329 if posonly_left:
2330 posonly_left -= 1
Yury Selivanovcf45f022015-05-20 14:38:50 -04002331
2332 # *args
2333 if func_code.co_flags & CO_VARARGS:
Pablo Galindocd74e662019-06-01 18:08:04 +01002334 name = arg_names[pos_count + keyword_only_count]
Yury Selivanovcf45f022015-05-20 14:38:50 -04002335 annotation = annotations.get(name, _empty)
2336 parameters.append(Parameter(name, annotation=annotation,
2337 kind=_VAR_POSITIONAL))
2338
2339 # Keyword-only parameters.
2340 for name in keyword_only:
2341 default = _empty
2342 if kwdefaults is not None:
2343 default = kwdefaults.get(name, _empty)
2344
2345 annotation = annotations.get(name, _empty)
2346 parameters.append(Parameter(name, annotation=annotation,
2347 kind=_KEYWORD_ONLY,
2348 default=default))
2349 # **kwargs
2350 if func_code.co_flags & CO_VARKEYWORDS:
Pablo Galindocd74e662019-06-01 18:08:04 +01002351 index = pos_count + keyword_only_count
Yury Selivanovcf45f022015-05-20 14:38:50 -04002352 if func_code.co_flags & CO_VARARGS:
2353 index += 1
2354
2355 name = arg_names[index]
2356 annotation = annotations.get(name, _empty)
2357 parameters.append(Parameter(name, annotation=annotation,
2358 kind=_VAR_KEYWORD))
2359
2360 # Is 'func' is a pure Python function - don't validate the
2361 # parameters list (for correct order and defaults), it should be OK.
2362 return cls(parameters,
2363 return_annotation=annotations.get('return', _empty),
2364 __validate_parameters__=is_duck_function)
2365
2366
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002367def _signature_from_callable(obj, *,
2368 follow_wrapper_chains=True,
2369 skip_bound_arg=True,
larryhastings74613a42021-04-29 21:16:28 -07002370 globals=None,
2371 locals=None,
2372 eval_str=False,
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002373 sigcls):
2374
2375 """Private helper function to get signature for arbitrary
2376 callable objects.
2377 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002378
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002379 _get_signature_of = functools.partial(_signature_from_callable,
2380 follow_wrapper_chains=follow_wrapper_chains,
2381 skip_bound_arg=skip_bound_arg,
larryhastings74613a42021-04-29 21:16:28 -07002382 globals=globals,
2383 locals=locals,
2384 sigcls=sigcls,
2385 eval_str=eval_str)
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002386
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002387 if not callable(obj):
2388 raise TypeError('{!r} is not a callable object'.format(obj))
2389
2390 if isinstance(obj, types.MethodType):
2391 # In this case we skip the first parameter of the underlying
2392 # function (usually `self` or `cls`).
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002393 sig = _get_signature_of(obj.__func__)
Yury Selivanovda396452014-03-27 12:09:24 -04002394
Yury Selivanov57d240e2014-02-19 16:27:23 -05002395 if skip_bound_arg:
2396 return _signature_bound_method(sig)
2397 else:
2398 return sig
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002399
Nick Coghlane8c45d62013-07-28 20:00:01 +10002400 # Was this function wrapped by a decorator?
Yury Selivanov57d240e2014-02-19 16:27:23 -05002401 if follow_wrapper_chains:
2402 obj = unwrap(obj, stop=(lambda f: hasattr(f, "__signature__")))
Yury Selivanov46c759d2015-05-27 21:56:53 -04002403 if isinstance(obj, types.MethodType):
2404 # If the unwrapped object is a *method*, we might want to
2405 # skip its first parameter (self).
2406 # See test_signature_wrapped_bound_method for details.
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002407 return _get_signature_of(obj)
Nick Coghlane8c45d62013-07-28 20:00:01 +10002408
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002409 try:
2410 sig = obj.__signature__
2411 except AttributeError:
2412 pass
2413 else:
2414 if sig is not None:
Yury Selivanov42407ab2014-06-23 10:23:50 -07002415 if not isinstance(sig, Signature):
2416 raise TypeError(
2417 'unexpected object {!r} in __signature__ '
2418 'attribute'.format(sig))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002419 return sig
2420
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002421 try:
2422 partialmethod = obj._partialmethod
2423 except AttributeError:
2424 pass
2425 else:
Yury Selivanov0486f812014-01-29 12:18:59 -05002426 if isinstance(partialmethod, functools.partialmethod):
2427 # Unbound partialmethod (see functools.partialmethod)
2428 # This means, that we need to calculate the signature
2429 # as if it's a regular partial object, but taking into
2430 # account that the first positional argument
2431 # (usually `self`, or `cls`) will not be passed
2432 # automatically (as for boundmethods)
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002433
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002434 wrapped_sig = _get_signature_of(partialmethod.func)
Yury Selivanovda396452014-03-27 12:09:24 -04002435
Yury Selivanov0486f812014-01-29 12:18:59 -05002436 sig = _signature_get_partial(wrapped_sig, partialmethod, (None,))
Yury Selivanov0486f812014-01-29 12:18:59 -05002437 first_wrapped_param = tuple(wrapped_sig.parameters.values())[0]
Dong-hee Na378d7062017-05-18 04:00:51 +09002438 if first_wrapped_param.kind is Parameter.VAR_POSITIONAL:
2439 # First argument of the wrapped callable is `*args`, as in
2440 # `partialmethod(lambda *args)`.
2441 return sig
2442 else:
2443 sig_params = tuple(sig.parameters.values())
Yury Selivanov8a387212018-03-06 12:59:45 -05002444 assert (not sig_params or
2445 first_wrapped_param is not sig_params[0])
Dong-hee Na378d7062017-05-18 04:00:51 +09002446 new_params = (first_wrapped_param,) + sig_params
2447 return sig.replace(parameters=new_params)
Yury Selivanovda5fe4f2014-01-27 17:28:37 -05002448
Yury Selivanov63da7c72014-01-31 14:48:37 -05002449 if isfunction(obj) or _signature_is_functionlike(obj):
2450 # If it's a pure Python function, or an object that is duck type
2451 # of a Python function (Cython functions, for instance), then:
Serhiy Storchakad53cf992019-05-06 22:40:27 +03002452 return _signature_from_function(sigcls, obj,
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002453 skip_bound_arg=skip_bound_arg,
larryhastings74613a42021-04-29 21:16:28 -07002454 globals=globals, locals=locals, eval_str=eval_str)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002455
Yury Selivanova773de02014-02-21 18:30:53 -05002456 if _signature_is_builtin(obj):
Yury Selivanovda396452014-03-27 12:09:24 -04002457 return _signature_from_builtin(sigcls, obj,
Yury Selivanova773de02014-02-21 18:30:53 -05002458 skip_bound_arg=skip_bound_arg)
2459
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002460 if isinstance(obj, functools.partial):
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002461 wrapped_sig = _get_signature_of(obj.func)
Yury Selivanov62560fb2014-01-28 12:26:24 -05002462 return _signature_get_partial(wrapped_sig, obj)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002463
2464 sig = None
2465 if isinstance(obj, type):
2466 # obj is a class or a metaclass
2467
2468 # First, let's see if it has an overloaded __call__ defined
2469 # in its metaclass
Yury Selivanov421f0c72014-01-29 12:05:40 -05002470 call = _signature_get_user_defined_method(type(obj), '__call__')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002471 if call is not None:
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002472 sig = _get_signature_of(call)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002473 else:
2474 # Now we check if the 'obj' class has a '__new__' method
Yury Selivanov421f0c72014-01-29 12:05:40 -05002475 new = _signature_get_user_defined_method(obj, '__new__')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002476 if new is not None:
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002477 sig = _get_signature_of(new)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002478 else:
2479 # Finally, we should have at least __init__ implemented
Yury Selivanov421f0c72014-01-29 12:05:40 -05002480 init = _signature_get_user_defined_method(obj, '__init__')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002481 if init is not None:
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002482 sig = _get_signature_of(init)
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002483
2484 if sig is None:
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002485 # At this point we know, that `obj` is a class, with no user-
2486 # defined '__init__', '__new__', or class-level '__call__'
2487
Larry Hastings2623c8c2014-02-08 22:15:29 -08002488 for base in obj.__mro__[:-1]:
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002489 # Since '__text_signature__' is implemented as a
2490 # descriptor that extracts text signature from the
2491 # class docstring, if 'obj' is derived from a builtin
2492 # class, its own '__text_signature__' may be 'None'.
Larry Hastings2623c8c2014-02-08 22:15:29 -08002493 # Therefore, we go through the MRO (except the last
2494 # class in there, which is 'object') to find the first
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002495 # class with non-empty text signature.
2496 try:
2497 text_sig = base.__text_signature__
2498 except AttributeError:
2499 pass
2500 else:
2501 if text_sig:
2502 # If 'obj' class has a __text_signature__ attribute:
2503 # return a signature based on it
Yury Selivanovda396452014-03-27 12:09:24 -04002504 return _signature_fromstr(sigcls, obj, text_sig)
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002505
2506 # No '__text_signature__' was found for the 'obj' class.
2507 # Last option is to check if its '__init__' is
2508 # object.__init__ or type.__init__.
Larry Hastings2623c8c2014-02-08 22:15:29 -08002509 if type not in obj.__mro__:
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002510 # We have a class (not metaclass), but no user-defined
2511 # __init__ or __new__ for it
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002512 if (obj.__init__ is object.__init__ and
2513 obj.__new__ is object.__new__):
Yury Selivanov7d2bfed2014-02-03 02:46:07 -05002514 # Return a signature of 'object' builtin.
Gregory P. Smith5b9ff7a2019-09-13 17:13:51 +01002515 return sigcls.from_callable(object)
Yury Selivanovbf304fc2015-05-30 17:08:36 -04002516 else:
2517 raise ValueError(
2518 'no signature found for builtin type {!r}'.format(obj))
Yury Selivanove7dcc5e2014-01-27 19:29:45 -05002519
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002520 elif not isinstance(obj, _NonUserDefinedCallables):
2521 # An object with __call__
2522 # We also check that the 'obj' is not an instance of
2523 # _WrapperDescriptor or _MethodWrapper to avoid
2524 # infinite recursion (and even potential segfault)
Yury Selivanov421f0c72014-01-29 12:05:40 -05002525 call = _signature_get_user_defined_method(type(obj), '__call__')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002526 if call is not None:
Larry Hastings2623c8c2014-02-08 22:15:29 -08002527 try:
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002528 sig = _get_signature_of(call)
Larry Hastings2623c8c2014-02-08 22:15:29 -08002529 except ValueError as ex:
2530 msg = 'no signature found for {!r}'.format(obj)
2531 raise ValueError(msg) from ex
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002532
2533 if sig is not None:
2534 # For classes and objects we skip the first parameter of their
2535 # __call__, __new__, or __init__ methods
Yury Selivanov57d240e2014-02-19 16:27:23 -05002536 if skip_bound_arg:
2537 return _signature_bound_method(sig)
2538 else:
2539 return sig
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002540
2541 if isinstance(obj, types.BuiltinFunctionType):
2542 # Raise a nicer error message for builtins
2543 msg = 'no signature found for builtin function {!r}'.format(obj)
2544 raise ValueError(msg)
2545
2546 raise ValueError('callable {!r} is not supported by signature'.format(obj))
2547
2548
2549class _void:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002550 """A private marker - used in Parameter & Signature."""
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002551
2552
2553class _empty:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002554 """Marker object for Signature.empty and Parameter.empty."""
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002555
2556
Yury Selivanov21e83a52014-03-27 11:23:13 -04002557class _ParameterKind(enum.IntEnum):
2558 POSITIONAL_ONLY = 0
2559 POSITIONAL_OR_KEYWORD = 1
2560 VAR_POSITIONAL = 2
2561 KEYWORD_ONLY = 3
2562 VAR_KEYWORD = 4
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002563
Dong-hee Na4aa30062018-06-08 12:46:31 +09002564 @property
2565 def description(self):
2566 return _PARAM_NAME_MAPPING[self]
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002567
Yury Selivanov21e83a52014-03-27 11:23:13 -04002568_POSITIONAL_ONLY = _ParameterKind.POSITIONAL_ONLY
2569_POSITIONAL_OR_KEYWORD = _ParameterKind.POSITIONAL_OR_KEYWORD
2570_VAR_POSITIONAL = _ParameterKind.VAR_POSITIONAL
2571_KEYWORD_ONLY = _ParameterKind.KEYWORD_ONLY
2572_VAR_KEYWORD = _ParameterKind.VAR_KEYWORD
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002573
Dong-hee Naa9cab432018-05-30 00:04:08 +09002574_PARAM_NAME_MAPPING = {
2575 _POSITIONAL_ONLY: 'positional-only',
2576 _POSITIONAL_OR_KEYWORD: 'positional or keyword',
2577 _VAR_POSITIONAL: 'variadic positional',
2578 _KEYWORD_ONLY: 'keyword-only',
2579 _VAR_KEYWORD: 'variadic keyword'
2580}
2581
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002582
2583class Parameter:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002584 """Represents a parameter in a function signature.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002585
2586 Has the following public attributes:
2587
2588 * name : str
2589 The name of the parameter as a string.
2590 * default : object
2591 The default value for the parameter if specified. If the
Yury Selivanov8757ead2014-01-28 16:39:25 -05002592 parameter has no default value, this attribute is set to
2593 `Parameter.empty`.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002594 * annotation
2595 The annotation for the parameter if specified. If the
Yury Selivanov8757ead2014-01-28 16:39:25 -05002596 parameter has no annotation, this attribute is set to
2597 `Parameter.empty`.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002598 * kind : str
2599 Describes how argument values are bound to the parameter.
2600 Possible values: `Parameter.POSITIONAL_ONLY`,
2601 `Parameter.POSITIONAL_OR_KEYWORD`, `Parameter.VAR_POSITIONAL`,
2602 `Parameter.KEYWORD_ONLY`, `Parameter.VAR_KEYWORD`.
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002603 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002604
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002605 __slots__ = ('_name', '_kind', '_default', '_annotation')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002606
2607 POSITIONAL_ONLY = _POSITIONAL_ONLY
2608 POSITIONAL_OR_KEYWORD = _POSITIONAL_OR_KEYWORD
2609 VAR_POSITIONAL = _VAR_POSITIONAL
2610 KEYWORD_ONLY = _KEYWORD_ONLY
2611 VAR_KEYWORD = _VAR_KEYWORD
2612
2613 empty = _empty
2614
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002615 def __init__(self, name, kind, *, default=_empty, annotation=_empty):
Dong-hee Naa9cab432018-05-30 00:04:08 +09002616 try:
2617 self._kind = _ParameterKind(kind)
2618 except ValueError:
2619 raise ValueError(f'value {kind!r} is not a valid Parameter.kind')
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002620 if default is not _empty:
Dong-hee Naa9cab432018-05-30 00:04:08 +09002621 if self._kind in (_VAR_POSITIONAL, _VAR_KEYWORD):
2622 msg = '{} parameters cannot have default values'
Dong-hee Na4aa30062018-06-08 12:46:31 +09002623 msg = msg.format(self._kind.description)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002624 raise ValueError(msg)
2625 self._default = default
2626 self._annotation = annotation
2627
Yury Selivanov2393dca2014-01-27 15:07:58 -05002628 if name is _empty:
2629 raise ValueError('name is a required attribute for Parameter')
2630
2631 if not isinstance(name, str):
Dong-hee Naa9cab432018-05-30 00:04:08 +09002632 msg = 'name must be a str, not a {}'.format(type(name).__name__)
2633 raise TypeError(msg)
Yury Selivanov2393dca2014-01-27 15:07:58 -05002634
Nick Coghlanb4b966e2016-06-04 14:40:03 -07002635 if name[0] == '.' and name[1:].isdigit():
2636 # These are implicit arguments generated by comprehensions. In
2637 # order to provide a friendlier interface to users, we recast
2638 # their name as "implicitN" and treat them as positional-only.
2639 # See issue 19611.
Dong-hee Naa9cab432018-05-30 00:04:08 +09002640 if self._kind != _POSITIONAL_OR_KEYWORD:
2641 msg = (
2642 'implicit arguments must be passed as '
2643 'positional or keyword arguments, not {}'
Nick Coghlanb4b966e2016-06-04 14:40:03 -07002644 )
Dong-hee Na4aa30062018-06-08 12:46:31 +09002645 msg = msg.format(self._kind.description)
Dong-hee Naa9cab432018-05-30 00:04:08 +09002646 raise ValueError(msg)
Nick Coghlanb4b966e2016-06-04 14:40:03 -07002647 self._kind = _POSITIONAL_ONLY
2648 name = 'implicit{}'.format(name[1:])
2649
Yury Selivanov2393dca2014-01-27 15:07:58 -05002650 if not name.isidentifier():
2651 raise ValueError('{!r} is not a valid parameter name'.format(name))
2652
2653 self._name = name
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002654
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002655 def __reduce__(self):
2656 return (type(self),
2657 (self._name, self._kind),
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002658 {'_default': self._default,
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002659 '_annotation': self._annotation})
2660
2661 def __setstate__(self, state):
Yury Selivanova5d63dd2014-03-27 11:31:43 -04002662 self._default = state['_default']
2663 self._annotation = state['_annotation']
2664
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002665 @property
2666 def name(self):
2667 return self._name
2668
2669 @property
2670 def default(self):
2671 return self._default
2672
2673 @property
2674 def annotation(self):
2675 return self._annotation
2676
2677 @property
2678 def kind(self):
2679 return self._kind
2680
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002681 def replace(self, *, name=_void, kind=_void,
2682 annotation=_void, default=_void):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002683 """Creates a customized copy of the Parameter."""
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002684
2685 if name is _void:
2686 name = self._name
2687
2688 if kind is _void:
2689 kind = self._kind
2690
2691 if annotation is _void:
2692 annotation = self._annotation
2693
2694 if default is _void:
2695 default = self._default
2696
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002697 return type(self)(name, kind, default=default, annotation=annotation)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002698
2699 def __str__(self):
2700 kind = self.kind
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002701 formatted = self._name
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002702
2703 # Add annotation and default value
2704 if self._annotation is not _empty:
Dong-hee Na762b9572017-11-16 03:30:59 +09002705 formatted = '{}: {}'.format(formatted,
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002706 formatannotation(self._annotation))
2707
2708 if self._default is not _empty:
Dong-hee Na762b9572017-11-16 03:30:59 +09002709 if self._annotation is not _empty:
2710 formatted = '{} = {}'.format(formatted, repr(self._default))
2711 else:
2712 formatted = '{}={}'.format(formatted, repr(self._default))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002713
2714 if kind == _VAR_POSITIONAL:
2715 formatted = '*' + formatted
2716 elif kind == _VAR_KEYWORD:
2717 formatted = '**' + formatted
2718
2719 return formatted
2720
2721 def __repr__(self):
Yury Selivanovf229bc52015-05-15 12:53:56 -04002722 return '<{} "{}">'.format(self.__class__.__name__, self)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002723
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002724 def __hash__(self):
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04002725 return hash((self.name, self.kind, self.annotation, self.default))
Yury Selivanov67ae50e2014-04-08 11:46:50 -04002726
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002727 def __eq__(self, other):
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03002728 if self is other:
2729 return True
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002730 if not isinstance(other, Parameter):
2731 return NotImplemented
2732 return (self._name == other._name and
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002733 self._kind == other._kind and
2734 self._default == other._default and
2735 self._annotation == other._annotation)
2736
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002737
2738class BoundArguments:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002739 """Result of `Signature.bind` call. Holds the mapping of arguments
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002740 to the function's parameters.
2741
2742 Has the following public attributes:
2743
Rémi Lapeyre2cca8ef2020-01-28 13:47:03 +01002744 * arguments : dict
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002745 An ordered mutable mapping of parameters' names to arguments' values.
2746 Does not contain arguments' default values.
2747 * signature : Signature
2748 The Signature object that created this instance.
2749 * args : tuple
2750 Tuple of positional arguments values.
2751 * kwargs : dict
2752 Dict of keyword arguments values.
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002753 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002754
Yury Selivanov6abe0322015-05-13 17:18:41 -04002755 __slots__ = ('arguments', '_signature', '__weakref__')
2756
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002757 def __init__(self, signature, arguments):
2758 self.arguments = arguments
2759 self._signature = signature
2760
2761 @property
2762 def signature(self):
2763 return self._signature
2764
2765 @property
2766 def args(self):
2767 args = []
2768 for param_name, param in self._signature.parameters.items():
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002769 if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002770 break
2771
2772 try:
2773 arg = self.arguments[param_name]
2774 except KeyError:
2775 # We're done here. Other arguments
2776 # will be mapped in 'BoundArguments.kwargs'
2777 break
2778 else:
2779 if param.kind == _VAR_POSITIONAL:
2780 # *args
2781 args.extend(arg)
2782 else:
2783 # plain argument
2784 args.append(arg)
2785
2786 return tuple(args)
2787
2788 @property
2789 def kwargs(self):
2790 kwargs = {}
2791 kwargs_started = False
2792 for param_name, param in self._signature.parameters.items():
2793 if not kwargs_started:
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002794 if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002795 kwargs_started = True
2796 else:
2797 if param_name not in self.arguments:
2798 kwargs_started = True
2799 continue
2800
2801 if not kwargs_started:
2802 continue
2803
2804 try:
2805 arg = self.arguments[param_name]
2806 except KeyError:
2807 pass
2808 else:
2809 if param.kind == _VAR_KEYWORD:
2810 # **kwargs
2811 kwargs.update(arg)
2812 else:
2813 # plain keyword argument
2814 kwargs[param_name] = arg
2815
2816 return kwargs
2817
Yury Selivanovb907a512015-05-16 13:45:09 -04002818 def apply_defaults(self):
2819 """Set default values for missing arguments.
2820
2821 For variable-positional arguments (*args) the default is an
2822 empty tuple.
2823
2824 For variable-keyword arguments (**kwargs) the default is an
2825 empty dict.
2826 """
2827 arguments = self.arguments
Yury Selivanovb907a512015-05-16 13:45:09 -04002828 new_arguments = []
2829 for name, param in self._signature.parameters.items():
2830 try:
2831 new_arguments.append((name, arguments[name]))
2832 except KeyError:
2833 if param.default is not _empty:
2834 val = param.default
2835 elif param.kind is _VAR_POSITIONAL:
2836 val = ()
2837 elif param.kind is _VAR_KEYWORD:
2838 val = {}
2839 else:
2840 # This BoundArguments was likely produced by
2841 # Signature.bind_partial().
2842 continue
2843 new_arguments.append((name, val))
Rémi Lapeyre2cca8ef2020-01-28 13:47:03 +01002844 self.arguments = dict(new_arguments)
Yury Selivanovb907a512015-05-16 13:45:09 -04002845
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002846 def __eq__(self, other):
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03002847 if self is other:
2848 return True
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03002849 if not isinstance(other, BoundArguments):
2850 return NotImplemented
2851 return (self.signature == other.signature and
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002852 self.arguments == other.arguments)
2853
Yury Selivanov6abe0322015-05-13 17:18:41 -04002854 def __setstate__(self, state):
2855 self._signature = state['_signature']
2856 self.arguments = state['arguments']
2857
2858 def __getstate__(self):
2859 return {'_signature': self._signature, 'arguments': self.arguments}
2860
Yury Selivanov3f6538f2015-05-14 18:47:17 -04002861 def __repr__(self):
2862 args = []
2863 for arg, value in self.arguments.items():
2864 args.append('{}={!r}'.format(arg, value))
Yury Selivanovf229bc52015-05-15 12:53:56 -04002865 return '<{} ({})>'.format(self.__class__.__name__, ', '.join(args))
Yury Selivanov3f6538f2015-05-14 18:47:17 -04002866
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002867
2868class Signature:
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002869 """A Signature object represents the overall signature of a function.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002870 It stores a Parameter object for each parameter accepted by the
2871 function, as well as information specific to the function itself.
2872
2873 A Signature object has the following public attributes and methods:
2874
Jens Reidel611836a2020-03-18 03:22:46 +01002875 * parameters : OrderedDict
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002876 An ordered mapping of parameters' names to the corresponding
2877 Parameter objects (keyword-only arguments are in the same order
2878 as listed in `code.co_varnames`).
2879 * return_annotation : object
2880 The annotation for the return type of the function if specified.
2881 If the function has no annotation for its return type, this
Yury Selivanov8757ead2014-01-28 16:39:25 -05002882 attribute is set to `Signature.empty`.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002883 * bind(*args, **kwargs) -> BoundArguments
2884 Creates a mapping from positional and keyword arguments to
2885 parameters.
2886 * bind_partial(*args, **kwargs) -> BoundArguments
2887 Creates a partial mapping from positional and keyword arguments
2888 to parameters (simulating 'functools.partial' behavior.)
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002889 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002890
2891 __slots__ = ('_return_annotation', '_parameters')
2892
2893 _parameter_cls = Parameter
2894 _bound_arguments_cls = BoundArguments
2895
2896 empty = _empty
2897
2898 def __init__(self, parameters=None, *, return_annotation=_empty,
2899 __validate_parameters__=True):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002900 """Constructs Signature from the given list of Parameter
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002901 objects and 'return_annotation'. All arguments are optional.
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002902 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002903
2904 if parameters is None:
Jens Reidel611836a2020-03-18 03:22:46 +01002905 params = OrderedDict()
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002906 else:
2907 if __validate_parameters__:
Jens Reidel611836a2020-03-18 03:22:46 +01002908 params = OrderedDict()
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002909 top_kind = _POSITIONAL_ONLY
Yury Selivanov07a9e452014-01-29 10:58:16 -05002910 kind_defaults = False
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002911
Rémi Lapeyre2cca8ef2020-01-28 13:47:03 +01002912 for param in parameters:
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002913 kind = param.kind
Yury Selivanov2393dca2014-01-27 15:07:58 -05002914 name = param.name
2915
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002916 if kind < top_kind:
Dong-hee Naa9cab432018-05-30 00:04:08 +09002917 msg = (
2918 'wrong parameter order: {} parameter before {} '
2919 'parameter'
2920 )
Dong-hee Na4aa30062018-06-08 12:46:31 +09002921 msg = msg.format(top_kind.description,
2922 kind.description)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002923 raise ValueError(msg)
Yury Selivanov07a9e452014-01-29 10:58:16 -05002924 elif kind > top_kind:
2925 kind_defaults = False
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002926 top_kind = kind
2927
Yury Selivanov3f73ca22014-04-08 11:30:45 -04002928 if kind in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD):
Yury Selivanov07a9e452014-01-29 10:58:16 -05002929 if param.default is _empty:
2930 if kind_defaults:
2931 # No default for this parameter, but the
2932 # previous parameter of the same kind had
2933 # a default
2934 msg = 'non-default argument follows default ' \
2935 'argument'
2936 raise ValueError(msg)
2937 else:
2938 # There is a default for this parameter.
2939 kind_defaults = True
2940
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002941 if name in params:
2942 msg = 'duplicate parameter name: {!r}'.format(name)
2943 raise ValueError(msg)
Yury Selivanov2393dca2014-01-27 15:07:58 -05002944
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002945 params[name] = param
2946 else:
Jens Reidel611836a2020-03-18 03:22:46 +01002947 params = OrderedDict((param.name, param) for param in parameters)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002948
2949 self._parameters = types.MappingProxyType(params)
2950 self._return_annotation = return_annotation
2951
2952 @classmethod
2953 def from_function(cls, func):
Matthias Bussonnierded87d82018-10-19 16:40:45 -07002954 """Constructs Signature for the given python function.
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002955
Matthias Bussonnierded87d82018-10-19 16:40:45 -07002956 Deprecated since Python 3.5, use `Signature.from_callable()`.
2957 """
2958
2959 warnings.warn("inspect.Signature.from_function() is deprecated since "
2960 "Python 3.5, use Signature.from_callable()",
Berker Peksagb5601582015-05-21 23:40:54 +03002961 DeprecationWarning, stacklevel=2)
Yury Selivanovcf45f022015-05-20 14:38:50 -04002962 return _signature_from_function(cls, func)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002963
Larry Hastings44e2eaa2013-11-23 15:37:55 -08002964 @classmethod
2965 def from_builtin(cls, func):
Matthias Bussonnierded87d82018-10-19 16:40:45 -07002966 """Constructs Signature for the given builtin function.
Yury Selivanov57c74fc2015-05-20 23:07:02 -04002967
Matthias Bussonnierded87d82018-10-19 16:40:45 -07002968 Deprecated since Python 3.5, use `Signature.from_callable()`.
2969 """
2970
2971 warnings.warn("inspect.Signature.from_builtin() is deprecated since "
2972 "Python 3.5, use Signature.from_callable()",
Berker Peksagb5601582015-05-21 23:40:54 +03002973 DeprecationWarning, stacklevel=2)
Yury Selivanov57d240e2014-02-19 16:27:23 -05002974 return _signature_from_builtin(cls, func)
Larry Hastings44e2eaa2013-11-23 15:37:55 -08002975
Yury Selivanovda396452014-03-27 12:09:24 -04002976 @classmethod
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002977 def from_callable(cls, obj, *,
larryhastings74613a42021-04-29 21:16:28 -07002978 follow_wrapped=True, globals=None, locals=None, eval_str=False):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002979 """Constructs Signature for the given callable object."""
Yury Selivanovbcd4fc12015-05-20 14:30:08 -04002980 return _signature_from_callable(obj, sigcls=cls,
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03002981 follow_wrapper_chains=follow_wrapped,
larryhastings74613a42021-04-29 21:16:28 -07002982 globals=globals, locals=locals, eval_str=eval_str)
Yury Selivanovda396452014-03-27 12:09:24 -04002983
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002984 @property
2985 def parameters(self):
2986 return self._parameters
2987
2988 @property
2989 def return_annotation(self):
2990 return self._return_annotation
2991
2992 def replace(self, *, parameters=_void, return_annotation=_void):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002993 """Creates a customized copy of the Signature.
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002994 Pass 'parameters' and/or 'return_annotation' arguments
2995 to override them in the new copy.
Yury Selivanov5a23bd02014-03-29 13:47:11 -04002996 """
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07002997
2998 if parameters is _void:
2999 parameters = self.parameters.values()
3000
3001 if return_annotation is _void:
3002 return_annotation = self._return_annotation
3003
3004 return type(self)(parameters,
3005 return_annotation=return_annotation)
3006
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003007 def _hash_basis(self):
3008 params = tuple(param for param in self.parameters.values()
3009 if param.kind != _KEYWORD_ONLY)
3010
3011 kwo_params = {param.name: param for param in self.parameters.values()
3012 if param.kind == _KEYWORD_ONLY}
3013
3014 return params, kwo_params, self.return_annotation
3015
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003016 def __hash__(self):
Yury Selivanov08d4a4f2014-09-12 15:48:02 -04003017 params, kwo_params, return_annotation = self._hash_basis()
3018 kwo_params = frozenset(kwo_params.values())
3019 return hash((params, kwo_params, return_annotation))
Yury Selivanov67ae50e2014-04-08 11:46:50 -04003020
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003021 def __eq__(self, other):
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03003022 if self is other:
3023 return True
Serhiy Storchaka3018cc42015-07-18 23:19:05 +03003024 if not isinstance(other, Signature):
3025 return NotImplemented
Serhiy Storchaka2489bd52015-07-18 23:20:50 +03003026 return self._hash_basis() == other._hash_basis()
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003027
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003028 def _bind(self, args, kwargs, *, partial=False):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04003029 """Private method. Don't use directly."""
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003030
Rémi Lapeyre2cca8ef2020-01-28 13:47:03 +01003031 arguments = {}
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003032
3033 parameters = iter(self.parameters.values())
3034 parameters_ex = ()
3035 arg_vals = iter(args)
3036
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003037 while True:
3038 # Let's iterate through the positional arguments and corresponding
3039 # parameters
3040 try:
3041 arg_val = next(arg_vals)
3042 except StopIteration:
3043 # No more positional arguments
3044 try:
3045 param = next(parameters)
3046 except StopIteration:
3047 # No more parameters. That's it. Just need to check that
3048 # we have no `kwargs` after this while loop
3049 break
3050 else:
3051 if param.kind == _VAR_POSITIONAL:
3052 # That's OK, just empty *args. Let's start parsing
3053 # kwargs
3054 break
3055 elif param.name in kwargs:
3056 if param.kind == _POSITIONAL_ONLY:
3057 msg = '{arg!r} parameter is positional only, ' \
3058 'but was passed as a keyword'
3059 msg = msg.format(arg=param.name)
3060 raise TypeError(msg) from None
3061 parameters_ex = (param,)
3062 break
3063 elif (param.kind == _VAR_KEYWORD or
3064 param.default is not _empty):
3065 # That's fine too - we have a default value for this
3066 # parameter. So, lets start parsing `kwargs`, starting
3067 # with the current parameter
3068 parameters_ex = (param,)
3069 break
3070 else:
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003071 # No default, not VAR_KEYWORD, not VAR_POSITIONAL,
3072 # not in `kwargs`
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003073 if partial:
3074 parameters_ex = (param,)
3075 break
3076 else:
Yury Selivanov86872752015-05-19 00:27:49 -04003077 msg = 'missing a required argument: {arg!r}'
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003078 msg = msg.format(arg=param.name)
3079 raise TypeError(msg) from None
3080 else:
3081 # We have a positional argument to process
3082 try:
3083 param = next(parameters)
3084 except StopIteration:
3085 raise TypeError('too many positional arguments') from None
3086 else:
3087 if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
3088 # Looks like we have no parameter for this positional
3089 # argument
Yury Selivanov86872752015-05-19 00:27:49 -04003090 raise TypeError(
3091 'too many positional arguments') from None
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003092
3093 if param.kind == _VAR_POSITIONAL:
3094 # We have an '*args'-like argument, let's fill it with
3095 # all positional arguments we have left and move on to
3096 # the next phase
3097 values = [arg_val]
3098 values.extend(arg_vals)
3099 arguments[param.name] = tuple(values)
3100 break
3101
Pablo Galindof3ef06a2019-10-15 12:40:02 +01003102 if param.name in kwargs and param.kind != _POSITIONAL_ONLY:
Yury Selivanov86872752015-05-19 00:27:49 -04003103 raise TypeError(
3104 'multiple values for argument {arg!r}'.format(
3105 arg=param.name)) from None
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003106
3107 arguments[param.name] = arg_val
3108
3109 # Now, we iterate through the remaining parameters to process
3110 # keyword arguments
3111 kwargs_param = None
3112 for param in itertools.chain(parameters_ex, parameters):
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003113 if param.kind == _VAR_KEYWORD:
3114 # Memorize that we have a '**kwargs'-like parameter
3115 kwargs_param = param
3116 continue
3117
Yury Selivanov38b0d5a2014-01-28 17:27:39 -05003118 if param.kind == _VAR_POSITIONAL:
3119 # Named arguments don't refer to '*args'-like parameters.
3120 # We only arrive here if the positional arguments ended
3121 # before reaching the last parameter before *args.
3122 continue
3123
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003124 param_name = param.name
3125 try:
3126 arg_val = kwargs.pop(param_name)
3127 except KeyError:
3128 # We have no value for this parameter. It's fine though,
3129 # if it has a default value, or it is an '*args'-like
3130 # parameter, left alone by the processing of positional
3131 # arguments.
3132 if (not partial and param.kind != _VAR_POSITIONAL and
3133 param.default is _empty):
Yury Selivanov86872752015-05-19 00:27:49 -04003134 raise TypeError('missing a required argument: {arg!r}'. \
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003135 format(arg=param_name)) from None
3136
3137 else:
Yury Selivanov9b9ac952014-01-28 20:54:28 -05003138 if param.kind == _POSITIONAL_ONLY:
3139 # This should never happen in case of a properly built
3140 # Signature object (but let's have this check here
3141 # to ensure correct behaviour just in case)
3142 raise TypeError('{arg!r} parameter is positional only, '
3143 'but was passed as a keyword'. \
3144 format(arg=param.name))
3145
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003146 arguments[param_name] = arg_val
3147
3148 if kwargs:
3149 if kwargs_param is not None:
3150 # Process our '**kwargs'-like parameter
3151 arguments[kwargs_param.name] = kwargs
3152 else:
Yury Selivanov86872752015-05-19 00:27:49 -04003153 raise TypeError(
3154 'got an unexpected keyword argument {arg!r}'.format(
3155 arg=next(iter(kwargs))))
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003156
3157 return self._bound_arguments_cls(self, arguments)
3158
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03003159 def bind(self, /, *args, **kwargs):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04003160 """Get a BoundArguments object, that maps the passed `args`
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003161 and `kwargs` to the function's signature. Raises `TypeError`
3162 if the passed arguments can not be bound.
Yury Selivanov5a23bd02014-03-29 13:47:11 -04003163 """
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03003164 return self._bind(args, kwargs)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003165
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03003166 def bind_partial(self, /, *args, **kwargs):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04003167 """Get a BoundArguments object, that partially maps the
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003168 passed `args` and `kwargs` to the function's signature.
3169 Raises `TypeError` if the passed arguments can not be bound.
Yury Selivanov5a23bd02014-03-29 13:47:11 -04003170 """
Serhiy Storchaka2085bd02019-06-01 11:00:15 +03003171 return self._bind(args, kwargs, partial=True)
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003172
Yury Selivanova5d63dd2014-03-27 11:31:43 -04003173 def __reduce__(self):
3174 return (type(self),
3175 (tuple(self._parameters.values()),),
3176 {'_return_annotation': self._return_annotation})
3177
3178 def __setstate__(self, state):
3179 self._return_annotation = state['_return_annotation']
3180
Yury Selivanov374375d2014-03-27 12:41:53 -04003181 def __repr__(self):
Yury Selivanovf229bc52015-05-15 12:53:56 -04003182 return '<{} {}>'.format(self.__class__.__name__, self)
Yury Selivanov374375d2014-03-27 12:41:53 -04003183
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003184 def __str__(self):
3185 result = []
Yury Selivanov2393dca2014-01-27 15:07:58 -05003186 render_pos_only_separator = False
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003187 render_kw_only_separator = True
Yury Selivanov2393dca2014-01-27 15:07:58 -05003188 for param in self.parameters.values():
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003189 formatted = str(param)
3190
3191 kind = param.kind
Yury Selivanov2393dca2014-01-27 15:07:58 -05003192
3193 if kind == _POSITIONAL_ONLY:
3194 render_pos_only_separator = True
3195 elif render_pos_only_separator:
3196 # It's not a positional-only parameter, and the flag
3197 # is set to 'True' (there were pos-only params before.)
3198 result.append('/')
3199 render_pos_only_separator = False
3200
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003201 if kind == _VAR_POSITIONAL:
3202 # OK, we have an '*args'-like parameter, so we won't need
3203 # a '*' to separate keyword-only arguments
3204 render_kw_only_separator = False
3205 elif kind == _KEYWORD_ONLY and render_kw_only_separator:
3206 # We have a keyword-only parameter to render and we haven't
3207 # rendered an '*args'-like parameter before, so add a '*'
3208 # separator to the parameters list ("foo(arg1, *, arg2)" case)
3209 result.append('*')
3210 # This condition should be only triggered once, so
3211 # reset the flag
3212 render_kw_only_separator = False
3213
3214 result.append(formatted)
3215
Yury Selivanov2393dca2014-01-27 15:07:58 -05003216 if render_pos_only_separator:
3217 # There were only positional-only parameters, hence the
3218 # flag was not reset to 'False'
3219 result.append('/')
3220
Larry Hastings7c7cbfc2012-06-22 15:19:35 -07003221 rendered = '({})'.format(', '.join(result))
3222
3223 if self.return_annotation is not _empty:
3224 anno = formatannotation(self.return_annotation)
3225 rendered += ' -> {}'.format(anno)
3226
3227 return rendered
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003228
Yury Selivanovda396452014-03-27 12:09:24 -04003229
larryhastings74613a42021-04-29 21:16:28 -07003230def signature(obj, *, follow_wrapped=True, globals=None, locals=None, eval_str=False):
Yury Selivanov5a23bd02014-03-29 13:47:11 -04003231 """Get a signature object for the passed callable."""
Batuhan Taskayaeee1c772020-12-24 01:45:13 +03003232 return Signature.from_callable(obj, follow_wrapped=follow_wrapped,
larryhastings74613a42021-04-29 21:16:28 -07003233 globals=globals, locals=locals, eval_str=eval_str)
Yury Selivanovda396452014-03-27 12:09:24 -04003234
3235
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003236def _main():
3237 """ Logic for inspecting an object given at command line """
3238 import argparse
3239 import importlib
3240
3241 parser = argparse.ArgumentParser()
3242 parser.add_argument(
3243 'object',
3244 help="The object to be analysed. "
3245 "It supports the 'module:qualname' syntax")
3246 parser.add_argument(
3247 '-d', '--details', action='store_true',
3248 help='Display info about the module rather than its source code')
3249
3250 args = parser.parse_args()
3251
3252 target = args.object
3253 mod_name, has_attrs, attrs = target.partition(":")
3254 try:
3255 obj = module = importlib.import_module(mod_name)
3256 except Exception as exc:
3257 msg = "Failed to import {} ({}: {})".format(mod_name,
3258 type(exc).__name__,
3259 exc)
3260 print(msg, file=sys.stderr)
Alan Yeee3c59a72019-09-09 07:15:43 -07003261 sys.exit(2)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003262
3263 if has_attrs:
3264 parts = attrs.split(".")
3265 obj = module
3266 for part in parts:
3267 obj = getattr(obj, part)
3268
3269 if module.__name__ in sys.builtin_module_names:
3270 print("Can't get info for builtin modules.", file=sys.stderr)
Alan Yeee3c59a72019-09-09 07:15:43 -07003271 sys.exit(1)
Nick Coghlanf94a16b2013-09-22 22:46:49 +10003272
3273 if args.details:
3274 print('Target: {}'.format(target))
3275 print('Origin: {}'.format(getsourcefile(module)))
3276 print('Cached: {}'.format(module.__cached__))
3277 if obj is module:
3278 print('Loader: {}'.format(repr(module.__loader__)))
3279 if hasattr(module, '__path__'):
3280 print('Submodule search path: {}'.format(module.__path__))
3281 else:
3282 try:
3283 __, lineno = findsource(obj)
3284 except Exception:
3285 pass
3286 else:
3287 print('Line: {}'.format(lineno))
3288
3289 print('\n')
3290 else:
3291 print(getsource(obj))
3292
3293
3294if __name__ == "__main__":
3295 _main()