ยปCore Development>Code coverage>Lib/inspect.py

Python code coverage for Lib/inspect.py

#countcontent
1n/a"""Get useful information from live Python objects.
2n/a
3n/aThis module encapsulates the interface provided by the internal special
4n/aattributes (co_*, im_*, tb_*, etc.) in a friendlier fashion.
5n/aIt also provides some help for examining source code and class layout.
6n/a
7n/aHere are some of the useful functions provided by this module:
8n/a
9n/a ismodule(), isclass(), ismethod(), isfunction(), isgeneratorfunction(),
10n/a isgenerator(), istraceback(), isframe(), iscode(), isbuiltin(),
11n/a isroutine() - check object types
12n/a getmembers() - get members of an object that satisfy a given condition
13n/a
14n/a getfile(), getsourcefile(), getsource() - find an object's source code
15n/a getdoc(), getcomments() - get documentation on an object
16n/a getmodule() - determine the module that an object came from
17n/a getclasstree() - arrange classes so as to represent their hierarchy
18n/a
19n/a getargvalues(), getcallargs() - get info about function arguments
20n/a getfullargspec() - same, with support for Python 3 features
21n/a formatargspec(), formatargvalues() - format an argument spec
22n/a getouterframes(), getinnerframes() - get info about frames
23n/a currentframe() - get the current stack frame
24n/a stack(), trace() - get info about frames on the stack or in a traceback
25n/a
26n/a signature() - get a Signature object for the callable
27n/a"""
28n/a
29n/a# This module is in the public domain. No warranties.
30n/a
31n/a__author__ = ('Ka-Ping Yee <ping@lfw.org>',
32n/a 'Yury Selivanov <yselivanov@sprymix.com>')
33n/a
34n/aimport ast
35n/aimport dis
36n/aimport collections.abc
37n/aimport enum
38n/aimport importlib.machinery
39n/aimport itertools
40n/aimport linecache
41n/aimport os
42n/aimport re
43n/aimport sys
44n/aimport tokenize
45n/aimport token
46n/aimport types
47n/aimport warnings
48n/aimport functools
49n/aimport builtins
50n/afrom operator import attrgetter
51n/afrom collections import namedtuple, OrderedDict
52n/a
53n/a# Create constants for the compiler flags in Include/code.h
54n/a# We try to get them from dis to avoid duplication
55n/amod_dict = globals()
56n/afor k, v in dis.COMPILER_FLAG_NAMES.items():
57n/a mod_dict["CO_" + v] = k
58n/a
59n/a# See Include/object.h
60n/aTPFLAGS_IS_ABSTRACT = 1 << 20
61n/a
62n/a# ----------------------------------------------------------- type-checking
63n/adef ismodule(object):
64n/a """Return true if the object is a module.
65n/a
66n/a Module objects provide these attributes:
67n/a __cached__ pathname to byte compiled file
68n/a __doc__ documentation string
69n/a __file__ filename (missing for built-in modules)"""
70n/a return isinstance(object, types.ModuleType)
71n/a
72n/adef isclass(object):
73n/a """Return true if the object is a class.
74n/a
75n/a Class objects provide these attributes:
76n/a __doc__ documentation string
77n/a __module__ name of module in which this class was defined"""
78n/a return isinstance(object, type)
79n/a
80n/adef ismethod(object):
81n/a """Return true if the object is an instance method.
82n/a
83n/a Instance method objects provide these attributes:
84n/a __doc__ documentation string
85n/a __name__ name with which this method was defined
86n/a __func__ function object containing implementation of method
87n/a __self__ instance to which this method is bound"""
88n/a return isinstance(object, types.MethodType)
89n/a
90n/adef ismethoddescriptor(object):
91n/a """Return true if the object is a method descriptor.
92n/a
93n/a But not if ismethod() or isclass() or isfunction() are true.
94n/a
95n/a This is new in Python 2.2, and, for example, is true of int.__add__.
96n/a An object passing this test has a __get__ attribute but not a __set__
97n/a attribute, but beyond that the set of attributes varies. __name__ is
98n/a usually sensible, and __doc__ often is.
99n/a
100n/a Methods implemented via descriptors that also pass one of the other
101n/a tests return false from the ismethoddescriptor() test, simply because
102n/a the other tests promise more -- you can, e.g., count on having the
103n/a __func__ attribute (etc) when an object passes ismethod()."""
104n/a if isclass(object) or ismethod(object) or isfunction(object):
105n/a # mutual exclusion
106n/a return False
107n/a tp = type(object)
108n/a return hasattr(tp, "__get__") and not hasattr(tp, "__set__")
109n/a
110n/adef isdatadescriptor(object):
111n/a """Return true if the object is a data descriptor.
112n/a
113n/a Data descriptors have both a __get__ and a __set__ attribute. Examples are
114n/a properties (defined in Python) and getsets and members (defined in C).
115n/a Typically, data descriptors will also have __name__ and __doc__ attributes
116n/a (properties, getsets, and members have both of these attributes), but this
117n/a is not guaranteed."""
118n/a if isclass(object) or ismethod(object) or isfunction(object):
119n/a # mutual exclusion
120n/a return False
121n/a tp = type(object)
122n/a return hasattr(tp, "__set__") and hasattr(tp, "__get__")
123n/a
124n/aif hasattr(types, 'MemberDescriptorType'):
125n/a # CPython and equivalent
126n/a def ismemberdescriptor(object):
127n/a """Return true if the object is a member descriptor.
128n/a
129n/a Member descriptors are specialized descriptors defined in extension
130n/a modules."""
131n/a return isinstance(object, types.MemberDescriptorType)
132n/aelse:
133n/a # Other implementations
134n/a def ismemberdescriptor(object):
135n/a """Return true if the object is a member descriptor.
136n/a
137n/a Member descriptors are specialized descriptors defined in extension
138n/a modules."""
139n/a return False
140n/a
141n/aif hasattr(types, 'GetSetDescriptorType'):
142n/a # CPython and equivalent
143n/a def isgetsetdescriptor(object):
144n/a """Return true if the object is a getset descriptor.
145n/a
146n/a getset descriptors are specialized descriptors defined in extension
147n/a modules."""
148n/a return isinstance(object, types.GetSetDescriptorType)
149n/aelse:
150n/a # Other implementations
151n/a def isgetsetdescriptor(object):
152n/a """Return true if the object is a getset descriptor.
153n/a
154n/a getset descriptors are specialized descriptors defined in extension
155n/a modules."""
156n/a return False
157n/a
158n/adef isfunction(object):
159n/a """Return true if the object is a user-defined function.
160n/a
161n/a Function objects provide these attributes:
162n/a __doc__ documentation string
163n/a __name__ name with which this function was defined
164n/a __code__ code object containing compiled function bytecode
165n/a __defaults__ tuple of any default values for arguments
166n/a __globals__ global namespace in which this function was defined
167n/a __annotations__ dict of parameter annotations
168n/a __kwdefaults__ dict of keyword only parameters with defaults"""
169n/a return isinstance(object, types.FunctionType)
170n/a
171n/adef isgeneratorfunction(object):
172n/a """Return true if the object is a user-defined generator function.
173n/a
174n/a Generator function objects provide the same attributes as functions.
175n/a See help(isfunction) for a list of attributes."""
176n/a return bool((isfunction(object) or ismethod(object)) and
177n/a object.__code__.co_flags & CO_GENERATOR)
178n/a
179n/adef iscoroutinefunction(object):
180n/a """Return true if the object is a coroutine function.
181n/a
182n/a Coroutine functions are defined with "async def" syntax.
183n/a """
184n/a return bool((isfunction(object) or ismethod(object)) and
185n/a object.__code__.co_flags & CO_COROUTINE)
186n/a
187n/adef isasyncgenfunction(object):
188n/a """Return true if the object is an asynchronous generator function.
189n/a
190n/a Asynchronous generator functions are defined with "async def"
191n/a syntax and have "yield" expressions in their body.
192n/a """
193n/a return bool((isfunction(object) or ismethod(object)) and
194n/a object.__code__.co_flags & CO_ASYNC_GENERATOR)
195n/a
196n/adef isasyncgen(object):
197n/a """Return true if the object is an asynchronous generator."""
198n/a return isinstance(object, types.AsyncGeneratorType)
199n/a
200n/adef isgenerator(object):
201n/a """Return true if the object is a generator.
202n/a
203n/a Generator objects provide these attributes:
204n/a __iter__ defined to support iteration over container
205n/a close raises a new GeneratorExit exception inside the
206n/a generator to terminate the iteration
207n/a gi_code code object
208n/a gi_frame frame object or possibly None once the generator has
209n/a been exhausted
210n/a gi_running set to 1 when generator is executing, 0 otherwise
211n/a next return the next item from the container
212n/a send resumes the generator and "sends" a value that becomes
213n/a the result of the current yield-expression
214n/a throw used to raise an exception inside the generator"""
215n/a return isinstance(object, types.GeneratorType)
216n/a
217n/adef iscoroutine(object):
218n/a """Return true if the object is a coroutine."""
219n/a return isinstance(object, types.CoroutineType)
220n/a
221n/adef isawaitable(object):
222n/a """Return true if object can be passed to an ``await`` expression."""
223n/a return (isinstance(object, types.CoroutineType) or
224n/a isinstance(object, types.GeneratorType) and
225n/a bool(object.gi_code.co_flags & CO_ITERABLE_COROUTINE) or
226n/a isinstance(object, collections.abc.Awaitable))
227n/a
228n/adef istraceback(object):
229n/a """Return true if the object is a traceback.
230n/a
231n/a Traceback objects provide these attributes:
232n/a tb_frame frame object at this level
233n/a tb_lasti index of last attempted instruction in bytecode
234n/a tb_lineno current line number in Python source code
235n/a tb_next next inner traceback object (called by this level)"""
236n/a return isinstance(object, types.TracebackType)
237n/a
238n/adef isframe(object):
239n/a """Return true if the object is a frame object.
240n/a
241n/a Frame objects provide these attributes:
242n/a f_back next outer frame object (this frame's caller)
243n/a f_builtins built-in namespace seen by this frame
244n/a f_code code object being executed in this frame
245n/a f_globals global namespace seen by this frame
246n/a f_lasti index of last attempted instruction in bytecode
247n/a f_lineno current line number in Python source code
248n/a f_locals local namespace seen by this frame
249n/a f_trace tracing function for this frame, or None"""
250n/a return isinstance(object, types.FrameType)
251n/a
252n/adef iscode(object):
253n/a """Return true if the object is a code object.
254n/a
255n/a Code objects provide these attributes:
256n/a co_argcount number of arguments (not including * or ** args)
257n/a co_code string of raw compiled bytecode
258n/a co_consts tuple of constants used in the bytecode
259n/a co_filename name of file in which this code object was created
260n/a co_firstlineno number of first line in Python source code
261n/a co_flags bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg
262n/a co_lnotab encoded mapping of line numbers to bytecode indices
263n/a co_name name with which this code object was defined
264n/a co_names tuple of names of local variables
265n/a co_nlocals number of local variables
266n/a co_stacksize virtual machine stack space required
267n/a co_varnames tuple of names of arguments and local variables"""
268n/a return isinstance(object, types.CodeType)
269n/a
270n/adef isbuiltin(object):
271n/a """Return true if the object is a built-in function or method.
272n/a
273n/a Built-in functions and methods provide these attributes:
274n/a __doc__ documentation string
275n/a __name__ original name of this function or method
276n/a __self__ instance to which a method is bound, or None"""
277n/a return isinstance(object, types.BuiltinFunctionType)
278n/a
279n/adef isroutine(object):
280n/a """Return true if the object is any kind of function or method."""
281n/a return (isbuiltin(object)
282n/a or isfunction(object)
283n/a or ismethod(object)
284n/a or ismethoddescriptor(object))
285n/a
286n/adef isabstract(object):
287n/a """Return true if the object is an abstract base class (ABC)."""
288n/a return bool(isinstance(object, type) and object.__flags__ & TPFLAGS_IS_ABSTRACT)
289n/a
290n/adef getmembers(object, predicate=None):
291n/a """Return all members of an object as (name, value) pairs sorted by name.
292n/a Optionally, only return members that satisfy a given predicate."""
293n/a if isclass(object):
294n/a mro = (object,) + getmro(object)
295n/a else:
296n/a mro = ()
297n/a results = []
298n/a processed = set()
299n/a names = dir(object)
300n/a # :dd any DynamicClassAttributes to the list of names if object is a class;
301n/a # this may result in duplicate entries if, for example, a virtual
302n/a # attribute with the same name as a DynamicClassAttribute exists
303n/a try:
304n/a for base in object.__bases__:
305n/a for k, v in base.__dict__.items():
306n/a if isinstance(v, types.DynamicClassAttribute):
307n/a names.append(k)
308n/a except AttributeError:
309n/a pass
310n/a for key in names:
311n/a # First try to get the value via getattr. Some descriptors don't
312n/a # like calling their __get__ (see bug #1785), so fall back to
313n/a # looking in the __dict__.
314n/a try:
315n/a value = getattr(object, key)
316n/a # handle the duplicate key
317n/a if key in processed:
318n/a raise AttributeError
319n/a except AttributeError:
320n/a for base in mro:
321n/a if key in base.__dict__:
322n/a value = base.__dict__[key]
323n/a break
324n/a else:
325n/a # could be a (currently) missing slot member, or a buggy
326n/a # __dir__; discard and move on
327n/a continue
328n/a if not predicate or predicate(value):
329n/a results.append((key, value))
330n/a processed.add(key)
331n/a results.sort(key=lambda pair: pair[0])
332n/a return results
333n/a
334n/aAttribute = namedtuple('Attribute', 'name kind defining_class object')
335n/a
336n/adef classify_class_attrs(cls):
337n/a """Return list of attribute-descriptor tuples.
338n/a
339n/a For each name in dir(cls), the return list contains a 4-tuple
340n/a with these elements:
341n/a
342n/a 0. The name (a string).
343n/a
344n/a 1. The kind of attribute this is, one of these strings:
345n/a 'class method' created via classmethod()
346n/a 'static method' created via staticmethod()
347n/a 'property' created via property()
348n/a 'method' any other flavor of method or descriptor
349n/a 'data' not a method
350n/a
351n/a 2. The class which defined this attribute (a class).
352n/a
353n/a 3. The object as obtained by calling getattr; if this fails, or if the
354n/a resulting object does not live anywhere in the class' mro (including
355n/a metaclasses) then the object is looked up in the defining class's
356n/a dict (found by walking the mro).
357n/a
358n/a If one of the items in dir(cls) is stored in the metaclass it will now
359n/a be discovered and not have None be listed as the class in which it was
360n/a defined. Any items whose home class cannot be discovered are skipped.
361n/a """
362n/a
363n/a mro = getmro(cls)
364n/a metamro = getmro(type(cls)) # for attributes stored in the metaclass
365n/a metamro = tuple([cls for cls in metamro if cls not in (type, object)])
366n/a class_bases = (cls,) + mro
367n/a all_bases = class_bases + metamro
368n/a names = dir(cls)
369n/a # :dd any DynamicClassAttributes to the list of names;
370n/a # this may result in duplicate entries if, for example, a virtual
371n/a # attribute with the same name as a DynamicClassAttribute exists.
372n/a for base in mro:
373n/a for k, v in base.__dict__.items():
374n/a if isinstance(v, types.DynamicClassAttribute):
375n/a names.append(k)
376n/a result = []
377n/a processed = set()
378n/a
379n/a for name in names:
380n/a # Get the object associated with the name, and where it was defined.
381n/a # Normal objects will be looked up with both getattr and directly in
382n/a # its class' dict (in case getattr fails [bug #1785], and also to look
383n/a # for a docstring).
384n/a # For DynamicClassAttributes on the second pass we only look in the
385n/a # class's dict.
386n/a #
387n/a # Getting an obj from the __dict__ sometimes reveals more than
388n/a # using getattr. Static and class methods are dramatic examples.
389n/a homecls = None
390n/a get_obj = None
391n/a dict_obj = None
392n/a if name not in processed:
393n/a try:
394n/a if name == '__dict__':
395n/a raise Exception("__dict__ is special, don't want the proxy")
396n/a get_obj = getattr(cls, name)
397n/a except Exception as exc:
398n/a pass
399n/a else:
400n/a homecls = getattr(get_obj, "__objclass__", homecls)
401n/a if homecls not in class_bases:
402n/a # if the resulting object does not live somewhere in the
403n/a # mro, drop it and search the mro manually
404n/a homecls = None
405n/a last_cls = None
406n/a # first look in the classes
407n/a for srch_cls in class_bases:
408n/a srch_obj = getattr(srch_cls, name, None)
409n/a if srch_obj is get_obj:
410n/a last_cls = srch_cls
411n/a # then check the metaclasses
412n/a for srch_cls in metamro:
413n/a try:
414n/a srch_obj = srch_cls.__getattr__(cls, name)
415n/a except AttributeError:
416n/a continue
417n/a if srch_obj is get_obj:
418n/a last_cls = srch_cls
419n/a if last_cls is not None:
420n/a homecls = last_cls
421n/a for base in all_bases:
422n/a if name in base.__dict__:
423n/a dict_obj = base.__dict__[name]
424n/a if homecls not in metamro:
425n/a homecls = base
426n/a break
427n/a if homecls is None:
428n/a # unable to locate the attribute anywhere, most likely due to
429n/a # buggy custom __dir__; discard and move on
430n/a continue
431n/a obj = get_obj if get_obj is not None else dict_obj
432n/a # Classify the object or its descriptor.
433n/a if isinstance(dict_obj, staticmethod):
434n/a kind = "static method"
435n/a obj = dict_obj
436n/a elif isinstance(dict_obj, classmethod):
437n/a kind = "class method"
438n/a obj = dict_obj
439n/a elif isinstance(dict_obj, property):
440n/a kind = "property"
441n/a obj = dict_obj
442n/a elif isroutine(obj):
443n/a kind = "method"
444n/a else:
445n/a kind = "data"
446n/a result.append(Attribute(name, kind, homecls, obj))
447n/a processed.add(name)
448n/a return result
449n/a
450n/a# ----------------------------------------------------------- class helpers
451n/a
452n/adef getmro(cls):
453n/a "Return tuple of base classes (including cls) in method resolution order."
454n/a return cls.__mro__
455n/a
456n/a# -------------------------------------------------------- function helpers
457n/a
458n/adef unwrap(func, *, stop=None):
459n/a """Get the object wrapped by *func*.
460n/a
461n/a Follows the chain of :attr:`__wrapped__` attributes returning the last
462n/a object in the chain.
463n/a
464n/a *stop* is an optional callback accepting an object in the wrapper chain
465n/a as its sole argument that allows the unwrapping to be terminated early if
466n/a the callback returns a true value. If the callback never returns a true
467n/a value, the last object in the chain is returned as usual. For example,
468n/a :func:`signature` uses this to stop unwrapping if any object in the
469n/a chain has a ``__signature__`` attribute defined.
470n/a
471n/a :exc:`ValueError` is raised if a cycle is encountered.
472n/a
473n/a """
474n/a if stop is None:
475n/a def _is_wrapper(f):
476n/a return hasattr(f, '__wrapped__')
477n/a else:
478n/a def _is_wrapper(f):
479n/a return hasattr(f, '__wrapped__') and not stop(f)
480n/a f = func # remember the original func for error reporting
481n/a memo = {id(f)} # Memoise by id to tolerate non-hashable objects
482n/a while _is_wrapper(func):
483n/a func = func.__wrapped__
484n/a id_func = id(func)
485n/a if id_func in memo:
486n/a raise ValueError('wrapper loop when unwrapping {!r}'.format(f))
487n/a memo.add(id_func)
488n/a return func
489n/a
490n/a# -------------------------------------------------- source code extraction
491n/adef indentsize(line):
492n/a """Return the indent size, in spaces, at the start of a line of text."""
493n/a expline = line.expandtabs()
494n/a return len(expline) - len(expline.lstrip())
495n/a
496n/adef _findclass(func):
497n/a cls = sys.modules.get(func.__module__)
498n/a if cls is None:
499n/a return None
500n/a for name in func.__qualname__.split('.')[:-1]:
501n/a cls = getattr(cls, name)
502n/a if not isclass(cls):
503n/a return None
504n/a return cls
505n/a
506n/adef _finddoc(obj):
507n/a if isclass(obj):
508n/a for base in obj.__mro__:
509n/a if base is not object:
510n/a try:
511n/a doc = base.__doc__
512n/a except AttributeError:
513n/a continue
514n/a if doc is not None:
515n/a return doc
516n/a return None
517n/a
518n/a if ismethod(obj):
519n/a name = obj.__func__.__name__
520n/a self = obj.__self__
521n/a if (isclass(self) and
522n/a getattr(getattr(self, name, None), '__func__') is obj.__func__):
523n/a # classmethod
524n/a cls = self
525n/a else:
526n/a cls = self.__class__
527n/a elif isfunction(obj):
528n/a name = obj.__name__
529n/a cls = _findclass(obj)
530n/a if cls is None or getattr(cls, name) is not obj:
531n/a return None
532n/a elif isbuiltin(obj):
533n/a name = obj.__name__
534n/a self = obj.__self__
535n/a if (isclass(self) and
536n/a self.__qualname__ + '.' + name == obj.__qualname__):
537n/a # classmethod
538n/a cls = self
539n/a else:
540n/a cls = self.__class__
541n/a # Should be tested before isdatadescriptor().
542n/a elif isinstance(obj, property):
543n/a func = obj.fget
544n/a name = func.__name__
545n/a cls = _findclass(func)
546n/a if cls is None or getattr(cls, name) is not obj:
547n/a return None
548n/a elif ismethoddescriptor(obj) or isdatadescriptor(obj):
549n/a name = obj.__name__
550n/a cls = obj.__objclass__
551n/a if getattr(cls, name) is not obj:
552n/a return None
553n/a else:
554n/a return None
555n/a
556n/a for base in cls.__mro__:
557n/a try:
558n/a doc = getattr(base, name).__doc__
559n/a except AttributeError:
560n/a continue
561n/a if doc is not None:
562n/a return doc
563n/a return None
564n/a
565n/adef getdoc(object):
566n/a """Get the documentation string for an object.
567n/a
568n/a All tabs are expanded to spaces. To clean up docstrings that are
569n/a indented to line up with blocks of code, any whitespace than can be
570n/a uniformly removed from the second line onwards is removed."""
571n/a try:
572n/a doc = object.__doc__
573n/a except AttributeError:
574n/a return None
575n/a if doc is None:
576n/a try:
577n/a doc = _finddoc(object)
578n/a except (AttributeError, TypeError):
579n/a return None
580n/a if not isinstance(doc, str):
581n/a return None
582n/a return cleandoc(doc)
583n/a
584n/adef cleandoc(doc):
585n/a """Clean up indentation from docstrings.
586n/a
587n/a Any whitespace that can be uniformly removed from the second line
588n/a onwards is removed."""
589n/a try:
590n/a lines = doc.expandtabs().split('\n')
591n/a except UnicodeError:
592n/a return None
593n/a else:
594n/a # Find minimum indentation of any non-blank lines after first line.
595n/a margin = sys.maxsize
596n/a for line in lines[1:]:
597n/a content = len(line.lstrip())
598n/a if content:
599n/a indent = len(line) - content
600n/a margin = min(margin, indent)
601n/a # Remove indentation.
602n/a if lines:
603n/a lines[0] = lines[0].lstrip()
604n/a if margin < sys.maxsize:
605n/a for i in range(1, len(lines)): lines[i] = lines[i][margin:]
606n/a # Remove any trailing or leading blank lines.
607n/a while lines and not lines[-1]:
608n/a lines.pop()
609n/a while lines and not lines[0]:
610n/a lines.pop(0)
611n/a return '\n'.join(lines)
612n/a
613n/adef getfile(object):
614n/a """Work out which source or compiled file an object was defined in."""
615n/a if ismodule(object):
616n/a if hasattr(object, '__file__'):
617n/a return object.__file__
618n/a raise TypeError('{!r} is a built-in module'.format(object))
619n/a if isclass(object):
620n/a if hasattr(object, '__module__'):
621n/a object = sys.modules.get(object.__module__)
622n/a if hasattr(object, '__file__'):
623n/a return object.__file__
624n/a raise TypeError('{!r} is a built-in class'.format(object))
625n/a if ismethod(object):
626n/a object = object.__func__
627n/a if isfunction(object):
628n/a object = object.__code__
629n/a if istraceback(object):
630n/a object = object.tb_frame
631n/a if isframe(object):
632n/a object = object.f_code
633n/a if iscode(object):
634n/a return object.co_filename
635n/a raise TypeError('{!r} is not a module, class, method, '
636n/a 'function, traceback, frame, or code object'.format(object))
637n/a
638n/adef getmodulename(path):
639n/a """Return the module name for a given file, or None."""
640n/a fname = os.path.basename(path)
641n/a # Check for paths that look like an actual module file
642n/a suffixes = [(-len(suffix), suffix)
643n/a for suffix in importlib.machinery.all_suffixes()]
644n/a suffixes.sort() # try longest suffixes first, in case they overlap
645n/a for neglen, suffix in suffixes:
646n/a if fname.endswith(suffix):
647n/a return fname[:neglen]
648n/a return None
649n/a
650n/adef getsourcefile(object):
651n/a """Return the filename that can be used to locate an object's source.
652n/a Return None if no way can be identified to get the source.
653n/a """
654n/a filename = getfile(object)
655n/a all_bytecode_suffixes = importlib.machinery.DEBUG_BYTECODE_SUFFIXES[:]
656n/a all_bytecode_suffixes += importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES[:]
657n/a if any(filename.endswith(s) for s in all_bytecode_suffixes):
658n/a filename = (os.path.splitext(filename)[0] +
659n/a importlib.machinery.SOURCE_SUFFIXES[0])
660n/a elif any(filename.endswith(s) for s in
661n/a importlib.machinery.EXTENSION_SUFFIXES):
662n/a return None
663n/a if os.path.exists(filename):
664n/a return filename
665n/a # only return a non-existent filename if the module has a PEP 302 loader
666n/a if getattr(getmodule(object, filename), '__loader__', None) is not None:
667n/a return filename
668n/a # or it is in the linecache
669n/a if filename in linecache.cache:
670n/a return filename
671n/a
672n/adef getabsfile(object, _filename=None):
673n/a """Return an absolute path to the source or compiled file for an object.
674n/a
675n/a The idea is for each object to have a unique origin, so this routine
676n/a normalizes the result as much as possible."""
677n/a if _filename is None:
678n/a _filename = getsourcefile(object) or getfile(object)
679n/a return os.path.normcase(os.path.abspath(_filename))
680n/a
681n/amodulesbyfile = {}
682n/a_filesbymodname = {}
683n/a
684n/adef getmodule(object, _filename=None):
685n/a """Return the module an object was defined in, or None if not found."""
686n/a if ismodule(object):
687n/a return object
688n/a if hasattr(object, '__module__'):
689n/a return sys.modules.get(object.__module__)
690n/a # Try the filename to modulename cache
691n/a if _filename is not None and _filename in modulesbyfile:
692n/a return sys.modules.get(modulesbyfile[_filename])
693n/a # Try the cache again with the absolute file name
694n/a try:
695n/a file = getabsfile(object, _filename)
696n/a except TypeError:
697n/a return None
698n/a if file in modulesbyfile:
699n/a return sys.modules.get(modulesbyfile[file])
700n/a # Update the filename to module name cache and check yet again
701n/a # Copy sys.modules in order to cope with changes while iterating
702n/a for modname, module in list(sys.modules.items()):
703n/a if ismodule(module) and hasattr(module, '__file__'):
704n/a f = module.__file__
705n/a if f == _filesbymodname.get(modname, None):
706n/a # Have already mapped this module, so skip it
707n/a continue
708n/a _filesbymodname[modname] = f
709n/a f = getabsfile(module)
710n/a # Always map to the name the module knows itself by
711n/a modulesbyfile[f] = modulesbyfile[
712n/a os.path.realpath(f)] = module.__name__
713n/a if file in modulesbyfile:
714n/a return sys.modules.get(modulesbyfile[file])
715n/a # Check the main module
716n/a main = sys.modules['__main__']
717n/a if not hasattr(object, '__name__'):
718n/a return None
719n/a if hasattr(main, object.__name__):
720n/a mainobject = getattr(main, object.__name__)
721n/a if mainobject is object:
722n/a return main
723n/a # Check builtins
724n/a builtin = sys.modules['builtins']
725n/a if hasattr(builtin, object.__name__):
726n/a builtinobject = getattr(builtin, object.__name__)
727n/a if builtinobject is object:
728n/a return builtin
729n/a
730n/adef findsource(object):
731n/a """Return the entire source file and starting line number for an object.
732n/a
733n/a The argument may be a module, class, method, function, traceback, frame,
734n/a or code object. The source code is returned as a list of all the lines
735n/a in the file and the line number indexes a line in that list. An OSError
736n/a is raised if the source code cannot be retrieved."""
737n/a
738n/a file = getsourcefile(object)
739n/a if file:
740n/a # Invalidate cache if needed.
741n/a linecache.checkcache(file)
742n/a else:
743n/a file = getfile(object)
744n/a # Allow filenames in form of "<something>" to pass through.
745n/a # `doctest` monkeypatches `linecache` module to enable
746n/a # inspection, so let `linecache.getlines` to be called.
747n/a if not (file.startswith('<') and file.endswith('>')):
748n/a raise OSError('source code not available')
749n/a
750n/a module = getmodule(object, file)
751n/a if module:
752n/a lines = linecache.getlines(file, module.__dict__)
753n/a else:
754n/a lines = linecache.getlines(file)
755n/a if not lines:
756n/a raise OSError('could not get source code')
757n/a
758n/a if ismodule(object):
759n/a return lines, 0
760n/a
761n/a if isclass(object):
762n/a name = object.__name__
763n/a pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
764n/a # make some effort to find the best matching class definition:
765n/a # use the one with the least indentation, which is the one
766n/a # that's most probably not inside a function definition.
767n/a candidates = []
768n/a for i in range(len(lines)):
769n/a match = pat.match(lines[i])
770n/a if match:
771n/a # if it's at toplevel, it's already the best one
772n/a if lines[i][0] == 'c':
773n/a return lines, i
774n/a # else add whitespace to candidate list
775n/a candidates.append((match.group(1), i))
776n/a if candidates:
777n/a # this will sort by whitespace, and by line number,
778n/a # less whitespace first
779n/a candidates.sort()
780n/a return lines, candidates[0][1]
781n/a else:
782n/a raise OSError('could not find class definition')
783n/a
784n/a if ismethod(object):
785n/a object = object.__func__
786n/a if isfunction(object):
787n/a object = object.__code__
788n/a if istraceback(object):
789n/a object = object.tb_frame
790n/a if isframe(object):
791n/a object = object.f_code
792n/a if iscode(object):
793n/a if not hasattr(object, 'co_firstlineno'):
794n/a raise OSError('could not find function definition')
795n/a lnum = object.co_firstlineno - 1
796n/a pat = re.compile(r'^(\s*def\s)|(\s*async\s+def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
797n/a while lnum > 0:
798n/a if pat.match(lines[lnum]): break
799n/a lnum = lnum - 1
800n/a return lines, lnum
801n/a raise OSError('could not find code object')
802n/a
803n/adef getcomments(object):
804n/a """Get lines of comments immediately preceding an object's source code.
805n/a
806n/a Returns None when source can't be found.
807n/a """
808n/a try:
809n/a lines, lnum = findsource(object)
810n/a except (OSError, TypeError):
811n/a return None
812n/a
813n/a if ismodule(object):
814n/a # Look for a comment block at the top of the file.
815n/a start = 0
816n/a if lines and lines[0][:2] == '#!': start = 1
817n/a while start < len(lines) and lines[start].strip() in ('', '#'):
818n/a start = start + 1
819n/a if start < len(lines) and lines[start][:1] == '#':
820n/a comments = []
821n/a end = start
822n/a while end < len(lines) and lines[end][:1] == '#':
823n/a comments.append(lines[end].expandtabs())
824n/a end = end + 1
825n/a return ''.join(comments)
826n/a
827n/a # Look for a preceding block of comments at the same indentation.
828n/a elif lnum > 0:
829n/a indent = indentsize(lines[lnum])
830n/a end = lnum - 1
831n/a if end >= 0 and lines[end].lstrip()[:1] == '#' and \
832n/a indentsize(lines[end]) == indent:
833n/a comments = [lines[end].expandtabs().lstrip()]
834n/a if end > 0:
835n/a end = end - 1
836n/a comment = lines[end].expandtabs().lstrip()
837n/a while comment[:1] == '#' and indentsize(lines[end]) == indent:
838n/a comments[:0] = [comment]
839n/a end = end - 1
840n/a if end < 0: break
841n/a comment = lines[end].expandtabs().lstrip()
842n/a while comments and comments[0].strip() == '#':
843n/a comments[:1] = []
844n/a while comments and comments[-1].strip() == '#':
845n/a comments[-1:] = []
846n/a return ''.join(comments)
847n/a
848n/aclass EndOfBlock(Exception): pass
849n/a
850n/aclass BlockFinder:
851n/a """Provide a tokeneater() method to detect the end of a code block."""
852n/a def __init__(self):
853n/a self.indent = 0
854n/a self.islambda = False
855n/a self.started = False
856n/a self.passline = False
857n/a self.indecorator = False
858n/a self.decoratorhasargs = False
859n/a self.last = 1
860n/a
861n/a def tokeneater(self, type, token, srowcol, erowcol, line):
862n/a if not self.started and not self.indecorator:
863n/a # skip any decorators
864n/a if token == "@":
865n/a self.indecorator = True
866n/a # look for the first "def", "class" or "lambda"
867n/a elif token in ("def", "class", "lambda"):
868n/a if token == "lambda":
869n/a self.islambda = True
870n/a self.started = True
871n/a self.passline = True # skip to the end of the line
872n/a elif token == "(":
873n/a if self.indecorator:
874n/a self.decoratorhasargs = True
875n/a elif token == ")":
876n/a if self.indecorator:
877n/a self.indecorator = False
878n/a self.decoratorhasargs = False
879n/a elif type == tokenize.NEWLINE:
880n/a self.passline = False # stop skipping when a NEWLINE is seen
881n/a self.last = srowcol[0]
882n/a if self.islambda: # lambdas always end at the first NEWLINE
883n/a raise EndOfBlock
884n/a # hitting a NEWLINE when in a decorator without args
885n/a # ends the decorator
886n/a if self.indecorator and not self.decoratorhasargs:
887n/a self.indecorator = False
888n/a elif self.passline:
889n/a pass
890n/a elif type == tokenize.INDENT:
891n/a self.indent = self.indent + 1
892n/a self.passline = True
893n/a elif type == tokenize.DEDENT:
894n/a self.indent = self.indent - 1
895n/a # the end of matching indent/dedent pairs end a block
896n/a # (note that this only works for "def"/"class" blocks,
897n/a # not e.g. for "if: else:" or "try: finally:" blocks)
898n/a if self.indent <= 0:
899n/a raise EndOfBlock
900n/a elif self.indent == 0 and type not in (tokenize.COMMENT, tokenize.NL):
901n/a # any other token on the same indentation level end the previous
902n/a # block as well, except the pseudo-tokens COMMENT and NL.
903n/a raise EndOfBlock
904n/a
905n/adef getblock(lines):
906n/a """Extract the block of code at the top of the given list of lines."""
907n/a blockfinder = BlockFinder()
908n/a try:
909n/a tokens = tokenize.generate_tokens(iter(lines).__next__)
910n/a for _token in tokens:
911n/a blockfinder.tokeneater(*_token)
912n/a except (EndOfBlock, IndentationError):
913n/a pass
914n/a return lines[:blockfinder.last]
915n/a
916n/adef getsourcelines(object):
917n/a """Return a list of source lines and starting line number for an object.
918n/a
919n/a The argument may be a module, class, method, function, traceback, frame,
920n/a or code object. The source code is returned as a list of the lines
921n/a corresponding to the object and the line number indicates where in the
922n/a original source file the first line of code was found. An OSError is
923n/a raised if the source code cannot be retrieved."""
924n/a object = unwrap(object)
925n/a lines, lnum = findsource(object)
926n/a
927n/a if ismodule(object):
928n/a return lines, 0
929n/a else:
930n/a return getblock(lines[lnum:]), lnum + 1
931n/a
932n/adef getsource(object):
933n/a """Return the text of the source code for an object.
934n/a
935n/a The argument may be a module, class, method, function, traceback, frame,
936n/a or code object. The source code is returned as a single string. An
937n/a OSError is raised if the source code cannot be retrieved."""
938n/a lines, lnum = getsourcelines(object)
939n/a return ''.join(lines)
940n/a
941n/a# --------------------------------------------------- class tree extraction
942n/adef walktree(classes, children, parent):
943n/a """Recursive helper function for getclasstree()."""
944n/a results = []
945n/a classes.sort(key=attrgetter('__module__', '__name__'))
946n/a for c in classes:
947n/a results.append((c, c.__bases__))
948n/a if c in children:
949n/a results.append(walktree(children[c], children, c))
950n/a return results
951n/a
952n/adef getclasstree(classes, unique=False):
953n/a """Arrange the given list of classes into a hierarchy of nested lists.
954n/a
955n/a Where a nested list appears, it contains classes derived from the class
956n/a whose entry immediately precedes the list. Each entry is a 2-tuple
957n/a containing a class and a tuple of its base classes. If the 'unique'
958n/a argument is true, exactly one entry appears in the returned structure
959n/a for each class in the given list. Otherwise, classes using multiple
960n/a inheritance and their descendants will appear multiple times."""
961n/a children = {}
962n/a roots = []
963n/a for c in classes:
964n/a if c.__bases__:
965n/a for parent in c.__bases__:
966n/a if not parent in children:
967n/a children[parent] = []
968n/a if c not in children[parent]:
969n/a children[parent].append(c)
970n/a if unique and parent in classes: break
971n/a elif c not in roots:
972n/a roots.append(c)
973n/a for parent in children:
974n/a if parent not in classes:
975n/a roots.append(parent)
976n/a return walktree(roots, children, None)
977n/a
978n/a# ------------------------------------------------ argument list extraction
979n/aArguments = namedtuple('Arguments', 'args, varargs, varkw')
980n/a
981n/adef getargs(co):
982n/a """Get information about the arguments accepted by a code object.
983n/a
984n/a Three things are returned: (args, varargs, varkw), where
985n/a 'args' is the list of argument names. Keyword-only arguments are
986n/a appended. 'varargs' and 'varkw' are the names of the * and **
987n/a arguments or None."""
988n/a args, varargs, kwonlyargs, varkw = _getfullargs(co)
989n/a return Arguments(args + kwonlyargs, varargs, varkw)
990n/a
991n/adef _getfullargs(co):
992n/a """Get information about the arguments accepted by a code object.
993n/a
994n/a Four things are returned: (args, varargs, kwonlyargs, varkw), where
995n/a 'args' and 'kwonlyargs' are lists of argument names, and 'varargs'
996n/a and 'varkw' are the names of the * and ** arguments or None."""
997n/a
998n/a if not iscode(co):
999n/a raise TypeError('{!r} is not a code object'.format(co))
1000n/a
1001n/a nargs = co.co_argcount
1002n/a names = co.co_varnames
1003n/a nkwargs = co.co_kwonlyargcount
1004n/a args = list(names[:nargs])
1005n/a kwonlyargs = list(names[nargs:nargs+nkwargs])
1006n/a step = 0
1007n/a
1008n/a nargs += nkwargs
1009n/a varargs = None
1010n/a if co.co_flags & CO_VARARGS:
1011n/a varargs = co.co_varnames[nargs]
1012n/a nargs = nargs + 1
1013n/a varkw = None
1014n/a if co.co_flags & CO_VARKEYWORDS:
1015n/a varkw = co.co_varnames[nargs]
1016n/a return args, varargs, kwonlyargs, varkw
1017n/a
1018n/a
1019n/aArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults')
1020n/a
1021n/adef getargspec(func):
1022n/a """Get the names and default values of a function's parameters.
1023n/a
1024n/a A tuple of four things is returned: (args, varargs, keywords, defaults).
1025n/a 'args' is a list of the argument names, including keyword-only argument names.
1026n/a 'varargs' and 'keywords' are the names of the * and ** parameters or None.
1027n/a 'defaults' is an n-tuple of the default values of the last n parameters.
1028n/a
1029n/a This function is deprecated, as it does not support annotations or
1030n/a keyword-only parameters and will raise ValueError if either is present
1031n/a on the supplied callable.
1032n/a
1033n/a For a more structured introspection API, use inspect.signature() instead.
1034n/a
1035n/a Alternatively, use getfullargspec() for an API with a similar namedtuple
1036n/a based interface, but full support for annotations and keyword-only
1037n/a parameters.
1038n/a """
1039n/a warnings.warn("inspect.getargspec() is deprecated, "
1040n/a "use inspect.signature() or inspect.getfullargspec()",
1041n/a DeprecationWarning, stacklevel=2)
1042n/a args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
1043n/a getfullargspec(func)
1044n/a if kwonlyargs or ann:
1045n/a raise ValueError("Function has keyword-only parameters or annotations"
1046n/a ", use getfullargspec() API which can support them")
1047n/a return ArgSpec(args, varargs, varkw, defaults)
1048n/a
1049n/aFullArgSpec = namedtuple('FullArgSpec',
1050n/a 'args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations')
1051n/a
1052n/adef getfullargspec(func):
1053n/a """Get the names and default values of a callable object's parameters.
1054n/a
1055n/a A tuple of seven things is returned:
1056n/a (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations).
1057n/a 'args' is a list of the parameter names.
1058n/a 'varargs' and 'varkw' are the names of the * and ** parameters or None.
1059n/a 'defaults' is an n-tuple of the default values of the last n parameters.
1060n/a 'kwonlyargs' is a list of keyword-only parameter names.
1061n/a 'kwonlydefaults' is a dictionary mapping names from kwonlyargs to defaults.
1062n/a 'annotations' is a dictionary mapping parameter names to annotations.
1063n/a
1064n/a Notable differences from inspect.signature():
1065n/a - the "self" parameter is always reported, even for bound methods
1066n/a - wrapper chains defined by __wrapped__ *not* unwrapped automatically
1067n/a """
1068n/a
1069n/a try:
1070n/a # Re: `skip_bound_arg=False`
1071n/a #
1072n/a # There is a notable difference in behaviour between getfullargspec
1073n/a # and Signature: the former always returns 'self' parameter for bound
1074n/a # methods, whereas the Signature always shows the actual calling
1075n/a # signature of the passed object.
1076n/a #
1077n/a # To simulate this behaviour, we "unbind" bound methods, to trick
1078n/a # inspect.signature to always return their first parameter ("self",
1079n/a # usually)
1080n/a
1081n/a # Re: `follow_wrapper_chains=False`
1082n/a #
1083n/a # getfullargspec() historically ignored __wrapped__ attributes,
1084n/a # so we ensure that remains the case in 3.3+
1085n/a
1086n/a sig = _signature_from_callable(func,
1087n/a follow_wrapper_chains=False,
1088n/a skip_bound_arg=False,
1089n/a sigcls=Signature)
1090n/a except Exception as ex:
1091n/a # Most of the times 'signature' will raise ValueError.
1092n/a # But, it can also raise AttributeError, and, maybe something
1093n/a # else. So to be fully backwards compatible, we catch all
1094n/a # possible exceptions here, and reraise a TypeError.
1095n/a raise TypeError('unsupported callable') from ex
1096n/a
1097n/a args = []
1098n/a varargs = None
1099n/a varkw = None
1100n/a kwonlyargs = []
1101n/a defaults = ()
1102n/a annotations = {}
1103n/a defaults = ()
1104n/a kwdefaults = {}
1105n/a
1106n/a if sig.return_annotation is not sig.empty:
1107n/a annotations['return'] = sig.return_annotation
1108n/a
1109n/a for param in sig.parameters.values():
1110n/a kind = param.kind
1111n/a name = param.name
1112n/a
1113n/a if kind is _POSITIONAL_ONLY:
1114n/a args.append(name)
1115n/a elif kind is _POSITIONAL_OR_KEYWORD:
1116n/a args.append(name)
1117n/a if param.default is not param.empty:
1118n/a defaults += (param.default,)
1119n/a elif kind is _VAR_POSITIONAL:
1120n/a varargs = name
1121n/a elif kind is _KEYWORD_ONLY:
1122n/a kwonlyargs.append(name)
1123n/a if param.default is not param.empty:
1124n/a kwdefaults[name] = param.default
1125n/a elif kind is _VAR_KEYWORD:
1126n/a varkw = name
1127n/a
1128n/a if param.annotation is not param.empty:
1129n/a annotations[name] = param.annotation
1130n/a
1131n/a if not kwdefaults:
1132n/a # compatibility with 'func.__kwdefaults__'
1133n/a kwdefaults = None
1134n/a
1135n/a if not defaults:
1136n/a # compatibility with 'func.__defaults__'
1137n/a defaults = None
1138n/a
1139n/a return FullArgSpec(args, varargs, varkw, defaults,
1140n/a kwonlyargs, kwdefaults, annotations)
1141n/a
1142n/a
1143n/aArgInfo = namedtuple('ArgInfo', 'args varargs keywords locals')
1144n/a
1145n/adef getargvalues(frame):
1146n/a """Get information about arguments passed into a particular frame.
1147n/a
1148n/a A tuple of four things is returned: (args, varargs, varkw, locals).
1149n/a 'args' is a list of the argument names.
1150n/a 'varargs' and 'varkw' are the names of the * and ** arguments or None.
1151n/a 'locals' is the locals dictionary of the given frame."""
1152n/a args, varargs, varkw = getargs(frame.f_code)
1153n/a return ArgInfo(args, varargs, varkw, frame.f_locals)
1154n/a
1155n/adef formatannotation(annotation, base_module=None):
1156n/a if getattr(annotation, '__module__', None) == 'typing':
1157n/a return repr(annotation).replace('typing.', '')
1158n/a if isinstance(annotation, type):
1159n/a if annotation.__module__ in ('builtins', base_module):
1160n/a return annotation.__qualname__
1161n/a return annotation.__module__+'.'+annotation.__qualname__
1162n/a return repr(annotation)
1163n/a
1164n/adef formatannotationrelativeto(object):
1165n/a module = getattr(object, '__module__', None)
1166n/a def _formatannotation(annotation):
1167n/a return formatannotation(annotation, module)
1168n/a return _formatannotation
1169n/a
1170n/adef formatargspec(args, varargs=None, varkw=None, defaults=None,
1171n/a kwonlyargs=(), kwonlydefaults={}, annotations={},
1172n/a formatarg=str,
1173n/a formatvarargs=lambda name: '*' + name,
1174n/a formatvarkw=lambda name: '**' + name,
1175n/a formatvalue=lambda value: '=' + repr(value),
1176n/a formatreturns=lambda text: ' -> ' + text,
1177n/a formatannotation=formatannotation):
1178n/a """Format an argument spec from the values returned by getfullargspec.
1179n/a
1180n/a The first seven arguments are (args, varargs, varkw, defaults,
1181n/a kwonlyargs, kwonlydefaults, annotations). The other five arguments
1182n/a are the corresponding optional formatting functions that are called to
1183n/a turn names and values into strings. The last argument is an optional
1184n/a function to format the sequence of arguments."""
1185n/a def formatargandannotation(arg):
1186n/a result = formatarg(arg)
1187n/a if arg in annotations:
1188n/a result += ': ' + formatannotation(annotations[arg])
1189n/a return result
1190n/a specs = []
1191n/a if defaults:
1192n/a firstdefault = len(args) - len(defaults)
1193n/a for i, arg in enumerate(args):
1194n/a spec = formatargandannotation(arg)
1195n/a if defaults and i >= firstdefault:
1196n/a spec = spec + formatvalue(defaults[i - firstdefault])
1197n/a specs.append(spec)
1198n/a if varargs is not None:
1199n/a specs.append(formatvarargs(formatargandannotation(varargs)))
1200n/a else:
1201n/a if kwonlyargs:
1202n/a specs.append('*')
1203n/a if kwonlyargs:
1204n/a for kwonlyarg in kwonlyargs:
1205n/a spec = formatargandannotation(kwonlyarg)
1206n/a if kwonlydefaults and kwonlyarg in kwonlydefaults:
1207n/a spec += formatvalue(kwonlydefaults[kwonlyarg])
1208n/a specs.append(spec)
1209n/a if varkw is not None:
1210n/a specs.append(formatvarkw(formatargandannotation(varkw)))
1211n/a result = '(' + ', '.join(specs) + ')'
1212n/a if 'return' in annotations:
1213n/a result += formatreturns(formatannotation(annotations['return']))
1214n/a return result
1215n/a
1216n/adef formatargvalues(args, varargs, varkw, locals,
1217n/a formatarg=str,
1218n/a formatvarargs=lambda name: '*' + name,
1219n/a formatvarkw=lambda name: '**' + name,
1220n/a formatvalue=lambda value: '=' + repr(value)):
1221n/a """Format an argument spec from the 4 values returned by getargvalues.
1222n/a
1223n/a The first four arguments are (args, varargs, varkw, locals). The
1224n/a next four arguments are the corresponding optional formatting functions
1225n/a that are called to turn names and values into strings. The ninth
1226n/a argument is an optional function to format the sequence of arguments."""
1227n/a def convert(name, locals=locals,
1228n/a formatarg=formatarg, formatvalue=formatvalue):
1229n/a return formatarg(name) + formatvalue(locals[name])
1230n/a specs = []
1231n/a for i in range(len(args)):
1232n/a specs.append(convert(args[i]))
1233n/a if varargs:
1234n/a specs.append(formatvarargs(varargs) + formatvalue(locals[varargs]))
1235n/a if varkw:
1236n/a specs.append(formatvarkw(varkw) + formatvalue(locals[varkw]))
1237n/a return '(' + ', '.join(specs) + ')'
1238n/a
1239n/adef _missing_arguments(f_name, argnames, pos, values):
1240n/a names = [repr(name) for name in argnames if name not in values]
1241n/a missing = len(names)
1242n/a if missing == 1:
1243n/a s = names[0]
1244n/a elif missing == 2:
1245n/a s = "{} and {}".format(*names)
1246n/a else:
1247n/a tail = ", {} and {}".format(*names[-2:])
1248n/a del names[-2:]
1249n/a s = ", ".join(names) + tail
1250n/a raise TypeError("%s() missing %i required %s argument%s: %s" %
1251n/a (f_name, missing,
1252n/a "positional" if pos else "keyword-only",
1253n/a "" if missing == 1 else "s", s))
1254n/a
1255n/adef _too_many(f_name, args, kwonly, varargs, defcount, given, values):
1256n/a atleast = len(args) - defcount
1257n/a kwonly_given = len([arg for arg in kwonly if arg in values])
1258n/a if varargs:
1259n/a plural = atleast != 1
1260n/a sig = "at least %d" % (atleast,)
1261n/a elif defcount:
1262n/a plural = True
1263n/a sig = "from %d to %d" % (atleast, len(args))
1264n/a else:
1265n/a plural = len(args) != 1
1266n/a sig = str(len(args))
1267n/a kwonly_sig = ""
1268n/a if kwonly_given:
1269n/a msg = " positional argument%s (and %d keyword-only argument%s)"
1270n/a kwonly_sig = (msg % ("s" if given != 1 else "", kwonly_given,
1271n/a "s" if kwonly_given != 1 else ""))
1272n/a raise TypeError("%s() takes %s positional argument%s but %d%s %s given" %
1273n/a (f_name, sig, "s" if plural else "", given, kwonly_sig,
1274n/a "was" if given == 1 and not kwonly_given else "were"))
1275n/a
1276n/adef getcallargs(*func_and_positional, **named):
1277n/a """Get the mapping of arguments to values.
1278n/a
1279n/a A dict is returned, with keys the function argument names (including the
1280n/a names of the * and ** arguments, if any), and values the respective bound
1281n/a values from 'positional' and 'named'."""
1282n/a func = func_and_positional[0]
1283n/a positional = func_and_positional[1:]
1284n/a spec = getfullargspec(func)
1285n/a args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = spec
1286n/a f_name = func.__name__
1287n/a arg2value = {}
1288n/a
1289n/a
1290n/a if ismethod(func) and func.__self__ is not None:
1291n/a # implicit 'self' (or 'cls' for classmethods) argument
1292n/a positional = (func.__self__,) + positional
1293n/a num_pos = len(positional)
1294n/a num_args = len(args)
1295n/a num_defaults = len(defaults) if defaults else 0
1296n/a
1297n/a n = min(num_pos, num_args)
1298n/a for i in range(n):
1299n/a arg2value[args[i]] = positional[i]
1300n/a if varargs:
1301n/a arg2value[varargs] = tuple(positional[n:])
1302n/a possible_kwargs = set(args + kwonlyargs)
1303n/a if varkw:
1304n/a arg2value[varkw] = {}
1305n/a for kw, value in named.items():
1306n/a if kw not in possible_kwargs:
1307n/a if not varkw:
1308n/a raise TypeError("%s() got an unexpected keyword argument %r" %
1309n/a (f_name, kw))
1310n/a arg2value[varkw][kw] = value
1311n/a continue
1312n/a if kw in arg2value:
1313n/a raise TypeError("%s() got multiple values for argument %r" %
1314n/a (f_name, kw))
1315n/a arg2value[kw] = value
1316n/a if num_pos > num_args and not varargs:
1317n/a _too_many(f_name, args, kwonlyargs, varargs, num_defaults,
1318n/a num_pos, arg2value)
1319n/a if num_pos < num_args:
1320n/a req = args[:num_args - num_defaults]
1321n/a for arg in req:
1322n/a if arg not in arg2value:
1323n/a _missing_arguments(f_name, req, True, arg2value)
1324n/a for i, arg in enumerate(args[num_args - num_defaults:]):
1325n/a if arg not in arg2value:
1326n/a arg2value[arg] = defaults[i]
1327n/a missing = 0
1328n/a for kwarg in kwonlyargs:
1329n/a if kwarg not in arg2value:
1330n/a if kwonlydefaults and kwarg in kwonlydefaults:
1331n/a arg2value[kwarg] = kwonlydefaults[kwarg]
1332n/a else:
1333n/a missing += 1
1334n/a if missing:
1335n/a _missing_arguments(f_name, kwonlyargs, False, arg2value)
1336n/a return arg2value
1337n/a
1338n/aClosureVars = namedtuple('ClosureVars', 'nonlocals globals builtins unbound')
1339n/a
1340n/adef getclosurevars(func):
1341n/a """
1342n/a Get the mapping of free variables to their current values.
1343n/a
1344n/a Returns a named tuple of dicts mapping the current nonlocal, global
1345n/a and builtin references as seen by the body of the function. A final
1346n/a set of unbound names that could not be resolved is also provided.
1347n/a """
1348n/a
1349n/a if ismethod(func):
1350n/a func = func.__func__
1351n/a
1352n/a if not isfunction(func):
1353n/a raise TypeError("'{!r}' is not a Python function".format(func))
1354n/a
1355n/a code = func.__code__
1356n/a # Nonlocal references are named in co_freevars and resolved
1357n/a # by looking them up in __closure__ by positional index
1358n/a if func.__closure__ is None:
1359n/a nonlocal_vars = {}
1360n/a else:
1361n/a nonlocal_vars = {
1362n/a var : cell.cell_contents
1363n/a for var, cell in zip(code.co_freevars, func.__closure__)
1364n/a }
1365n/a
1366n/a # Global and builtin references are named in co_names and resolved
1367n/a # by looking them up in __globals__ or __builtins__
1368n/a global_ns = func.__globals__
1369n/a builtin_ns = global_ns.get("__builtins__", builtins.__dict__)
1370n/a if ismodule(builtin_ns):
1371n/a builtin_ns = builtin_ns.__dict__
1372n/a global_vars = {}
1373n/a builtin_vars = {}
1374n/a unbound_names = set()
1375n/a for name in code.co_names:
1376n/a if name in ("None", "True", "False"):
1377n/a # Because these used to be builtins instead of keywords, they
1378n/a # may still show up as name references. We ignore them.
1379n/a continue
1380n/a try:
1381n/a global_vars[name] = global_ns[name]
1382n/a except KeyError:
1383n/a try:
1384n/a builtin_vars[name] = builtin_ns[name]
1385n/a except KeyError:
1386n/a unbound_names.add(name)
1387n/a
1388n/a return ClosureVars(nonlocal_vars, global_vars,
1389n/a builtin_vars, unbound_names)
1390n/a
1391n/a# -------------------------------------------------- stack frame extraction
1392n/a
1393n/aTraceback = namedtuple('Traceback', 'filename lineno function code_context index')
1394n/a
1395n/adef getframeinfo(frame, context=1):
1396n/a """Get information about a frame or traceback object.
1397n/a
1398n/a A tuple of five things is returned: the filename, the line number of
1399n/a the current line, the function name, a list of lines of context from
1400n/a the source code, and the index of the current line within that list.
1401n/a The optional second argument specifies the number of lines of context
1402n/a to return, which are centered around the current line."""
1403n/a if istraceback(frame):
1404n/a lineno = frame.tb_lineno
1405n/a frame = frame.tb_frame
1406n/a else:
1407n/a lineno = frame.f_lineno
1408n/a if not isframe(frame):
1409n/a raise TypeError('{!r} is not a frame or traceback object'.format(frame))
1410n/a
1411n/a filename = getsourcefile(frame) or getfile(frame)
1412n/a if context > 0:
1413n/a start = lineno - 1 - context//2
1414n/a try:
1415n/a lines, lnum = findsource(frame)
1416n/a except OSError:
1417n/a lines = index = None
1418n/a else:
1419n/a start = max(0, min(start, len(lines) - context))
1420n/a lines = lines[start:start+context]
1421n/a index = lineno - 1 - start
1422n/a else:
1423n/a lines = index = None
1424n/a
1425n/a return Traceback(filename, lineno, frame.f_code.co_name, lines, index)
1426n/a
1427n/adef getlineno(frame):
1428n/a """Get the line number from a frame object, allowing for optimization."""
1429n/a # FrameType.f_lineno is now a descriptor that grovels co_lnotab
1430n/a return frame.f_lineno
1431n/a
1432n/aFrameInfo = namedtuple('FrameInfo', ('frame',) + Traceback._fields)
1433n/a
1434n/adef getouterframes(frame, context=1):
1435n/a """Get a list of records for a frame and all higher (calling) frames.
1436n/a
1437n/a Each record contains a frame object, filename, line number, function
1438n/a name, a list of lines of context, and index within the context."""
1439n/a framelist = []
1440n/a while frame:
1441n/a frameinfo = (frame,) + getframeinfo(frame, context)
1442n/a framelist.append(FrameInfo(*frameinfo))
1443n/a frame = frame.f_back
1444n/a return framelist
1445n/a
1446n/adef getinnerframes(tb, context=1):
1447n/a """Get a list of records for a traceback's frame and all lower frames.
1448n/a
1449n/a Each record contains a frame object, filename, line number, function
1450n/a name, a list of lines of context, and index within the context."""
1451n/a framelist = []
1452n/a while tb:
1453n/a frameinfo = (tb.tb_frame,) + getframeinfo(tb, context)
1454n/a framelist.append(FrameInfo(*frameinfo))
1455n/a tb = tb.tb_next
1456n/a return framelist
1457n/a
1458n/adef currentframe():
1459n/a """Return the frame of the caller or None if this is not possible."""
1460n/a return sys._getframe(1) if hasattr(sys, "_getframe") else None
1461n/a
1462n/adef stack(context=1):
1463n/a """Return a list of records for the stack above the caller's frame."""
1464n/a return getouterframes(sys._getframe(1), context)
1465n/a
1466n/adef trace(context=1):
1467n/a """Return a list of records for the stack below the current exception."""
1468n/a return getinnerframes(sys.exc_info()[2], context)
1469n/a
1470n/a
1471n/a# ------------------------------------------------ static version of getattr
1472n/a
1473n/a_sentinel = object()
1474n/a
1475n/adef _static_getmro(klass):
1476n/a return type.__dict__['__mro__'].__get__(klass)
1477n/a
1478n/adef _check_instance(obj, attr):
1479n/a instance_dict = {}
1480n/a try:
1481n/a instance_dict = object.__getattribute__(obj, "__dict__")
1482n/a except AttributeError:
1483n/a pass
1484n/a return dict.get(instance_dict, attr, _sentinel)
1485n/a
1486n/a
1487n/adef _check_class(klass, attr):
1488n/a for entry in _static_getmro(klass):
1489n/a if _shadowed_dict(type(entry)) is _sentinel:
1490n/a try:
1491n/a return entry.__dict__[attr]
1492n/a except KeyError:
1493n/a pass
1494n/a return _sentinel
1495n/a
1496n/adef _is_type(obj):
1497n/a try:
1498n/a _static_getmro(obj)
1499n/a except TypeError:
1500n/a return False
1501n/a return True
1502n/a
1503n/adef _shadowed_dict(klass):
1504n/a dict_attr = type.__dict__["__dict__"]
1505n/a for entry in _static_getmro(klass):
1506n/a try:
1507n/a class_dict = dict_attr.__get__(entry)["__dict__"]
1508n/a except KeyError:
1509n/a pass
1510n/a else:
1511n/a if not (type(class_dict) is types.GetSetDescriptorType and
1512n/a class_dict.__name__ == "__dict__" and
1513n/a class_dict.__objclass__ is entry):
1514n/a return class_dict
1515n/a return _sentinel
1516n/a
1517n/adef getattr_static(obj, attr, default=_sentinel):
1518n/a """Retrieve attributes without triggering dynamic lookup via the
1519n/a descriptor protocol, __getattr__ or __getattribute__.
1520n/a
1521n/a Note: this function may not be able to retrieve all attributes
1522n/a that getattr can fetch (like dynamically created attributes)
1523n/a and may find attributes that getattr can't (like descriptors
1524n/a that raise AttributeError). It can also return descriptor objects
1525n/a instead of instance members in some cases. See the
1526n/a documentation for details.
1527n/a """
1528n/a instance_result = _sentinel
1529n/a if not _is_type(obj):
1530n/a klass = type(obj)
1531n/a dict_attr = _shadowed_dict(klass)
1532n/a if (dict_attr is _sentinel or
1533n/a type(dict_attr) is types.MemberDescriptorType):
1534n/a instance_result = _check_instance(obj, attr)
1535n/a else:
1536n/a klass = obj
1537n/a
1538n/a klass_result = _check_class(klass, attr)
1539n/a
1540n/a if instance_result is not _sentinel and klass_result is not _sentinel:
1541n/a if (_check_class(type(klass_result), '__get__') is not _sentinel and
1542n/a _check_class(type(klass_result), '__set__') is not _sentinel):
1543n/a return klass_result
1544n/a
1545n/a if instance_result is not _sentinel:
1546n/a return instance_result
1547n/a if klass_result is not _sentinel:
1548n/a return klass_result
1549n/a
1550n/a if obj is klass:
1551n/a # for types we check the metaclass too
1552n/a for entry in _static_getmro(type(klass)):
1553n/a if _shadowed_dict(type(entry)) is _sentinel:
1554n/a try:
1555n/a return entry.__dict__[attr]
1556n/a except KeyError:
1557n/a pass
1558n/a if default is not _sentinel:
1559n/a return default
1560n/a raise AttributeError(attr)
1561n/a
1562n/a
1563n/a# ------------------------------------------------ generator introspection
1564n/a
1565n/aGEN_CREATED = 'GEN_CREATED'
1566n/aGEN_RUNNING = 'GEN_RUNNING'
1567n/aGEN_SUSPENDED = 'GEN_SUSPENDED'
1568n/aGEN_CLOSED = 'GEN_CLOSED'
1569n/a
1570n/adef getgeneratorstate(generator):
1571n/a """Get current state of a generator-iterator.
1572n/a
1573n/a Possible states are:
1574n/a GEN_CREATED: Waiting to start execution.
1575n/a GEN_RUNNING: Currently being executed by the interpreter.
1576n/a GEN_SUSPENDED: Currently suspended at a yield expression.
1577n/a GEN_CLOSED: Execution has completed.
1578n/a """
1579n/a if generator.gi_running:
1580n/a return GEN_RUNNING
1581n/a if generator.gi_frame is None:
1582n/a return GEN_CLOSED
1583n/a if generator.gi_frame.f_lasti == -1:
1584n/a return GEN_CREATED
1585n/a return GEN_SUSPENDED
1586n/a
1587n/a
1588n/adef getgeneratorlocals(generator):
1589n/a """
1590n/a Get the mapping of generator local variables to their current values.
1591n/a
1592n/a A dict is returned, with the keys the local variable names and values the
1593n/a bound values."""
1594n/a
1595n/a if not isgenerator(generator):
1596n/a raise TypeError("'{!r}' is not a Python generator".format(generator))
1597n/a
1598n/a frame = getattr(generator, "gi_frame", None)
1599n/a if frame is not None:
1600n/a return generator.gi_frame.f_locals
1601n/a else:
1602n/a return {}
1603n/a
1604n/a
1605n/a# ------------------------------------------------ coroutine introspection
1606n/a
1607n/aCORO_CREATED = 'CORO_CREATED'
1608n/aCORO_RUNNING = 'CORO_RUNNING'
1609n/aCORO_SUSPENDED = 'CORO_SUSPENDED'
1610n/aCORO_CLOSED = 'CORO_CLOSED'
1611n/a
1612n/adef getcoroutinestate(coroutine):
1613n/a """Get current state of a coroutine object.
1614n/a
1615n/a Possible states are:
1616n/a CORO_CREATED: Waiting to start execution.
1617n/a CORO_RUNNING: Currently being executed by the interpreter.
1618n/a CORO_SUSPENDED: Currently suspended at an await expression.
1619n/a CORO_CLOSED: Execution has completed.
1620n/a """
1621n/a if coroutine.cr_running:
1622n/a return CORO_RUNNING
1623n/a if coroutine.cr_frame is None:
1624n/a return CORO_CLOSED
1625n/a if coroutine.cr_frame.f_lasti == -1:
1626n/a return CORO_CREATED
1627n/a return CORO_SUSPENDED
1628n/a
1629n/a
1630n/adef getcoroutinelocals(coroutine):
1631n/a """
1632n/a Get the mapping of coroutine local variables to their current values.
1633n/a
1634n/a A dict is returned, with the keys the local variable names and values the
1635n/a bound values."""
1636n/a frame = getattr(coroutine, "cr_frame", None)
1637n/a if frame is not None:
1638n/a return frame.f_locals
1639n/a else:
1640n/a return {}
1641n/a
1642n/a
1643n/a###############################################################################
1644n/a### Function Signature Object (PEP 362)
1645n/a###############################################################################
1646n/a
1647n/a
1648n/a_WrapperDescriptor = type(type.__call__)
1649n/a_MethodWrapper = type(all.__call__)
1650n/a_ClassMethodWrapper = type(int.__dict__['from_bytes'])
1651n/a
1652n/a_NonUserDefinedCallables = (_WrapperDescriptor,
1653n/a _MethodWrapper,
1654n/a _ClassMethodWrapper,
1655n/a types.BuiltinFunctionType)
1656n/a
1657n/a
1658n/adef _signature_get_user_defined_method(cls, method_name):
1659n/a """Private helper. Checks if ``cls`` has an attribute
1660n/a named ``method_name`` and returns it only if it is a
1661n/a pure python function.
1662n/a """
1663n/a try:
1664n/a meth = getattr(cls, method_name)
1665n/a except AttributeError:
1666n/a return
1667n/a else:
1668n/a if not isinstance(meth, _NonUserDefinedCallables):
1669n/a # Once '__signature__' will be added to 'C'-level
1670n/a # callables, this check won't be necessary
1671n/a return meth
1672n/a
1673n/a
1674n/adef _signature_get_partial(wrapped_sig, partial, extra_args=()):
1675n/a """Private helper to calculate how 'wrapped_sig' signature will
1676n/a look like after applying a 'functools.partial' object (or alike)
1677n/a on it.
1678n/a """
1679n/a
1680n/a old_params = wrapped_sig.parameters
1681n/a new_params = OrderedDict(old_params.items())
1682n/a
1683n/a partial_args = partial.args or ()
1684n/a partial_keywords = partial.keywords or {}
1685n/a
1686n/a if extra_args:
1687n/a partial_args = extra_args + partial_args
1688n/a
1689n/a try:
1690n/a ba = wrapped_sig.bind_partial(*partial_args, **partial_keywords)
1691n/a except TypeError as ex:
1692n/a msg = 'partial object {!r} has incorrect arguments'.format(partial)
1693n/a raise ValueError(msg) from ex
1694n/a
1695n/a
1696n/a transform_to_kwonly = False
1697n/a for param_name, param in old_params.items():
1698n/a try:
1699n/a arg_value = ba.arguments[param_name]
1700n/a except KeyError:
1701n/a pass
1702n/a else:
1703n/a if param.kind is _POSITIONAL_ONLY:
1704n/a # If positional-only parameter is bound by partial,
1705n/a # it effectively disappears from the signature
1706n/a new_params.pop(param_name)
1707n/a continue
1708n/a
1709n/a if param.kind is _POSITIONAL_OR_KEYWORD:
1710n/a if param_name in partial_keywords:
1711n/a # This means that this parameter, and all parameters
1712n/a # after it should be keyword-only (and var-positional
1713n/a # should be removed). Here's why. Consider the following
1714n/a # function:
1715n/a # foo(a, b, *args, c):
1716n/a # pass
1717n/a #
1718n/a # "partial(foo, a='spam')" will have the following
1719n/a # signature: "(*, a='spam', b, c)". Because attempting
1720n/a # to call that partial with "(10, 20)" arguments will
1721n/a # raise a TypeError, saying that "a" argument received
1722n/a # multiple values.
1723n/a transform_to_kwonly = True
1724n/a # Set the new default value
1725n/a new_params[param_name] = param.replace(default=arg_value)
1726n/a else:
1727n/a # was passed as a positional argument
1728n/a new_params.pop(param.name)
1729n/a continue
1730n/a
1731n/a if param.kind is _KEYWORD_ONLY:
1732n/a # Set the new default value
1733n/a new_params[param_name] = param.replace(default=arg_value)
1734n/a
1735n/a if transform_to_kwonly:
1736n/a assert param.kind is not _POSITIONAL_ONLY
1737n/a
1738n/a if param.kind is _POSITIONAL_OR_KEYWORD:
1739n/a new_param = new_params[param_name].replace(kind=_KEYWORD_ONLY)
1740n/a new_params[param_name] = new_param
1741n/a new_params.move_to_end(param_name)
1742n/a elif param.kind in (_KEYWORD_ONLY, _VAR_KEYWORD):
1743n/a new_params.move_to_end(param_name)
1744n/a elif param.kind is _VAR_POSITIONAL:
1745n/a new_params.pop(param.name)
1746n/a
1747n/a return wrapped_sig.replace(parameters=new_params.values())
1748n/a
1749n/a
1750n/adef _signature_bound_method(sig):
1751n/a """Private helper to transform signatures for unbound
1752n/a functions to bound methods.
1753n/a """
1754n/a
1755n/a params = tuple(sig.parameters.values())
1756n/a
1757n/a if not params or params[0].kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
1758n/a raise ValueError('invalid method signature')
1759n/a
1760n/a kind = params[0].kind
1761n/a if kind in (_POSITIONAL_OR_KEYWORD, _POSITIONAL_ONLY):
1762n/a # Drop first parameter:
1763n/a # '(p1, p2[, ...])' -> '(p2[, ...])'
1764n/a params = params[1:]
1765n/a else:
1766n/a if kind is not _VAR_POSITIONAL:
1767n/a # Unless we add a new parameter type we never
1768n/a # get here
1769n/a raise ValueError('invalid argument type')
1770n/a # It's a var-positional parameter.
1771n/a # Do nothing. '(*args[, ...])' -> '(*args[, ...])'
1772n/a
1773n/a return sig.replace(parameters=params)
1774n/a
1775n/a
1776n/adef _signature_is_builtin(obj):
1777n/a """Private helper to test if `obj` is a callable that might
1778n/a support Argument Clinic's __text_signature__ protocol.
1779n/a """
1780n/a return (isbuiltin(obj) or
1781n/a ismethoddescriptor(obj) or
1782n/a isinstance(obj, _NonUserDefinedCallables) or
1783n/a # Can't test 'isinstance(type)' here, as it would
1784n/a # also be True for regular python classes
1785n/a obj in (type, object))
1786n/a
1787n/a
1788n/adef _signature_is_functionlike(obj):
1789n/a """Private helper to test if `obj` is a duck type of FunctionType.
1790n/a A good example of such objects are functions compiled with
1791n/a Cython, which have all attributes that a pure Python function
1792n/a would have, but have their code statically compiled.
1793n/a """
1794n/a
1795n/a if not callable(obj) or isclass(obj):
1796n/a # All function-like objects are obviously callables,
1797n/a # and not classes.
1798n/a return False
1799n/a
1800n/a name = getattr(obj, '__name__', None)
1801n/a code = getattr(obj, '__code__', None)
1802n/a defaults = getattr(obj, '__defaults__', _void) # Important to use _void ...
1803n/a kwdefaults = getattr(obj, '__kwdefaults__', _void) # ... and not None here
1804n/a annotations = getattr(obj, '__annotations__', None)
1805n/a
1806n/a return (isinstance(code, types.CodeType) and
1807n/a isinstance(name, str) and
1808n/a (defaults is None or isinstance(defaults, tuple)) and
1809n/a (kwdefaults is None or isinstance(kwdefaults, dict)) and
1810n/a isinstance(annotations, dict))
1811n/a
1812n/a
1813n/adef _signature_get_bound_param(spec):
1814n/a """ Private helper to get first parameter name from a
1815n/a __text_signature__ of a builtin method, which should
1816n/a be in the following format: '($param1, ...)'.
1817n/a Assumptions are that the first argument won't have
1818n/a a default value or an annotation.
1819n/a """
1820n/a
1821n/a assert spec.startswith('($')
1822n/a
1823n/a pos = spec.find(',')
1824n/a if pos == -1:
1825n/a pos = spec.find(')')
1826n/a
1827n/a cpos = spec.find(':')
1828n/a assert cpos == -1 or cpos > pos
1829n/a
1830n/a cpos = spec.find('=')
1831n/a assert cpos == -1 or cpos > pos
1832n/a
1833n/a return spec[2:pos]
1834n/a
1835n/a
1836n/adef _signature_strip_non_python_syntax(signature):
1837n/a """
1838n/a Private helper function. Takes a signature in Argument Clinic's
1839n/a extended signature format.
1840n/a
1841n/a Returns a tuple of three things:
1842n/a * that signature re-rendered in standard Python syntax,
1843n/a * the index of the "self" parameter (generally 0), or None if
1844n/a the function does not have a "self" parameter, and
1845n/a * the index of the last "positional only" parameter,
1846n/a or None if the signature has no positional-only parameters.
1847n/a """
1848n/a
1849n/a if not signature:
1850n/a return signature, None, None
1851n/a
1852n/a self_parameter = None
1853n/a last_positional_only = None
1854n/a
1855n/a lines = [l.encode('ascii') for l in signature.split('\n')]
1856n/a generator = iter(lines).__next__
1857n/a token_stream = tokenize.tokenize(generator)
1858n/a
1859n/a delayed_comma = False
1860n/a skip_next_comma = False
1861n/a text = []
1862n/a add = text.append
1863n/a
1864n/a current_parameter = 0
1865n/a OP = token.OP
1866n/a ERRORTOKEN = token.ERRORTOKEN
1867n/a
1868n/a # token stream always starts with ENCODING token, skip it
1869n/a t = next(token_stream)
1870n/a assert t.type == tokenize.ENCODING
1871n/a
1872n/a for t in token_stream:
1873n/a type, string = t.type, t.string
1874n/a
1875n/a if type == OP:
1876n/a if string == ',':
1877n/a if skip_next_comma:
1878n/a skip_next_comma = False
1879n/a else:
1880n/a assert not delayed_comma
1881n/a delayed_comma = True
1882n/a current_parameter += 1
1883n/a continue
1884n/a
1885n/a if string == '/':
1886n/a assert not skip_next_comma
1887n/a assert last_positional_only is None
1888n/a skip_next_comma = True
1889n/a last_positional_only = current_parameter - 1
1890n/a continue
1891n/a
1892n/a if (type == ERRORTOKEN) and (string == '$'):
1893n/a assert self_parameter is None
1894n/a self_parameter = current_parameter
1895n/a continue
1896n/a
1897n/a if delayed_comma:
1898n/a delayed_comma = False
1899n/a if not ((type == OP) and (string == ')')):
1900n/a add(', ')
1901n/a add(string)
1902n/a if (string == ','):
1903n/a add(' ')
1904n/a clean_signature = ''.join(text)
1905n/a return clean_signature, self_parameter, last_positional_only
1906n/a
1907n/a
1908n/adef _signature_fromstr(cls, obj, s, skip_bound_arg=True):
1909n/a """Private helper to parse content of '__text_signature__'
1910n/a and return a Signature based on it.
1911n/a """
1912n/a
1913n/a Parameter = cls._parameter_cls
1914n/a
1915n/a clean_signature, self_parameter, last_positional_only = \
1916n/a _signature_strip_non_python_syntax(s)
1917n/a
1918n/a program = "def foo" + clean_signature + ": pass"
1919n/a
1920n/a try:
1921n/a module = ast.parse(program)
1922n/a except SyntaxError:
1923n/a module = None
1924n/a
1925n/a if not isinstance(module, ast.Module):
1926n/a raise ValueError("{!r} builtin has invalid signature".format(obj))
1927n/a
1928n/a f = module.body[0]
1929n/a
1930n/a parameters = []
1931n/a empty = Parameter.empty
1932n/a invalid = object()
1933n/a
1934n/a module = None
1935n/a module_dict = {}
1936n/a module_name = getattr(obj, '__module__', None)
1937n/a if module_name:
1938n/a module = sys.modules.get(module_name, None)
1939n/a if module:
1940n/a module_dict = module.__dict__
1941n/a sys_module_dict = sys.modules
1942n/a
1943n/a def parse_name(node):
1944n/a assert isinstance(node, ast.arg)
1945n/a if node.annotation != None:
1946n/a raise ValueError("Annotations are not currently supported")
1947n/a return node.arg
1948n/a
1949n/a def wrap_value(s):
1950n/a try:
1951n/a value = eval(s, module_dict)
1952n/a except NameError:
1953n/a try:
1954n/a value = eval(s, sys_module_dict)
1955n/a except NameError:
1956n/a raise RuntimeError()
1957n/a
1958n/a if isinstance(value, str):
1959n/a return ast.Str(value)
1960n/a if isinstance(value, (int, float)):
1961n/a return ast.Num(value)
1962n/a if isinstance(value, bytes):
1963n/a return ast.Bytes(value)
1964n/a if value in (True, False, None):
1965n/a return ast.NameConstant(value)
1966n/a raise RuntimeError()
1967n/a
1968n/a class RewriteSymbolics(ast.NodeTransformer):
1969n/a def visit_Attribute(self, node):
1970n/a a = []
1971n/a n = node
1972n/a while isinstance(n, ast.Attribute):
1973n/a a.append(n.attr)
1974n/a n = n.value
1975n/a if not isinstance(n, ast.Name):
1976n/a raise RuntimeError()
1977n/a a.append(n.id)
1978n/a value = ".".join(reversed(a))
1979n/a return wrap_value(value)
1980n/a
1981n/a def visit_Name(self, node):
1982n/a if not isinstance(node.ctx, ast.Load):
1983n/a raise ValueError()
1984n/a return wrap_value(node.id)
1985n/a
1986n/a def p(name_node, default_node, default=empty):
1987n/a name = parse_name(name_node)
1988n/a if name is invalid:
1989n/a return None
1990n/a if default_node and default_node is not _empty:
1991n/a try:
1992n/a default_node = RewriteSymbolics().visit(default_node)
1993n/a o = ast.literal_eval(default_node)
1994n/a except ValueError:
1995n/a o = invalid
1996n/a if o is invalid:
1997n/a return None
1998n/a default = o if o is not invalid else default
1999n/a parameters.append(Parameter(name, kind, default=default, annotation=empty))
2000n/a
2001n/a # non-keyword-only parameters
2002n/a args = reversed(f.args.args)
2003n/a defaults = reversed(f.args.defaults)
2004n/a iter = itertools.zip_longest(args, defaults, fillvalue=None)
2005n/a if last_positional_only is not None:
2006n/a kind = Parameter.POSITIONAL_ONLY
2007n/a else:
2008n/a kind = Parameter.POSITIONAL_OR_KEYWORD
2009n/a for i, (name, default) in enumerate(reversed(list(iter))):
2010n/a p(name, default)
2011n/a if i == last_positional_only:
2012n/a kind = Parameter.POSITIONAL_OR_KEYWORD
2013n/a
2014n/a # *args
2015n/a if f.args.vararg:
2016n/a kind = Parameter.VAR_POSITIONAL
2017n/a p(f.args.vararg, empty)
2018n/a
2019n/a # keyword-only arguments
2020n/a kind = Parameter.KEYWORD_ONLY
2021n/a for name, default in zip(f.args.kwonlyargs, f.args.kw_defaults):
2022n/a p(name, default)
2023n/a
2024n/a # **kwargs
2025n/a if f.args.kwarg:
2026n/a kind = Parameter.VAR_KEYWORD
2027n/a p(f.args.kwarg, empty)
2028n/a
2029n/a if self_parameter is not None:
2030n/a # Possibly strip the bound argument:
2031n/a # - We *always* strip first bound argument if
2032n/a # it is a module.
2033n/a # - We don't strip first bound argument if
2034n/a # skip_bound_arg is False.
2035n/a assert parameters
2036n/a _self = getattr(obj, '__self__', None)
2037n/a self_isbound = _self is not None
2038n/a self_ismodule = ismodule(_self)
2039n/a if self_isbound and (self_ismodule or skip_bound_arg):
2040n/a parameters.pop(0)
2041n/a else:
2042n/a # for builtins, self parameter is always positional-only!
2043n/a p = parameters[0].replace(kind=Parameter.POSITIONAL_ONLY)
2044n/a parameters[0] = p
2045n/a
2046n/a return cls(parameters, return_annotation=cls.empty)
2047n/a
2048n/a
2049n/adef _signature_from_builtin(cls, func, skip_bound_arg=True):
2050n/a """Private helper function to get signature for
2051n/a builtin callables.
2052n/a """
2053n/a
2054n/a if not _signature_is_builtin(func):
2055n/a raise TypeError("{!r} is not a Python builtin "
2056n/a "function".format(func))
2057n/a
2058n/a s = getattr(func, "__text_signature__", None)
2059n/a if not s:
2060n/a raise ValueError("no signature found for builtin {!r}".format(func))
2061n/a
2062n/a return _signature_fromstr(cls, func, s, skip_bound_arg)
2063n/a
2064n/a
2065n/adef _signature_from_function(cls, func):
2066n/a """Private helper: constructs Signature for the given python function."""
2067n/a
2068n/a is_duck_function = False
2069n/a if not isfunction(func):
2070n/a if _signature_is_functionlike(func):
2071n/a is_duck_function = True
2072n/a else:
2073n/a # If it's not a pure Python function, and not a duck type
2074n/a # of pure function:
2075n/a raise TypeError('{!r} is not a Python function'.format(func))
2076n/a
2077n/a Parameter = cls._parameter_cls
2078n/a
2079n/a # Parameter information.
2080n/a func_code = func.__code__
2081n/a pos_count = func_code.co_argcount
2082n/a arg_names = func_code.co_varnames
2083n/a positional = tuple(arg_names[:pos_count])
2084n/a keyword_only_count = func_code.co_kwonlyargcount
2085n/a keyword_only = arg_names[pos_count:(pos_count + keyword_only_count)]
2086n/a annotations = func.__annotations__
2087n/a defaults = func.__defaults__
2088n/a kwdefaults = func.__kwdefaults__
2089n/a
2090n/a if defaults:
2091n/a pos_default_count = len(defaults)
2092n/a else:
2093n/a pos_default_count = 0
2094n/a
2095n/a parameters = []
2096n/a
2097n/a # Non-keyword-only parameters w/o defaults.
2098n/a non_default_count = pos_count - pos_default_count
2099n/a for name in positional[:non_default_count]:
2100n/a annotation = annotations.get(name, _empty)
2101n/a parameters.append(Parameter(name, annotation=annotation,
2102n/a kind=_POSITIONAL_OR_KEYWORD))
2103n/a
2104n/a # ... w/ defaults.
2105n/a for offset, name in enumerate(positional[non_default_count:]):
2106n/a annotation = annotations.get(name, _empty)
2107n/a parameters.append(Parameter(name, annotation=annotation,
2108n/a kind=_POSITIONAL_OR_KEYWORD,
2109n/a default=defaults[offset]))
2110n/a
2111n/a # *args
2112n/a if func_code.co_flags & CO_VARARGS:
2113n/a name = arg_names[pos_count + keyword_only_count]
2114n/a annotation = annotations.get(name, _empty)
2115n/a parameters.append(Parameter(name, annotation=annotation,
2116n/a kind=_VAR_POSITIONAL))
2117n/a
2118n/a # Keyword-only parameters.
2119n/a for name in keyword_only:
2120n/a default = _empty
2121n/a if kwdefaults is not None:
2122n/a default = kwdefaults.get(name, _empty)
2123n/a
2124n/a annotation = annotations.get(name, _empty)
2125n/a parameters.append(Parameter(name, annotation=annotation,
2126n/a kind=_KEYWORD_ONLY,
2127n/a default=default))
2128n/a # **kwargs
2129n/a if func_code.co_flags & CO_VARKEYWORDS:
2130n/a index = pos_count + keyword_only_count
2131n/a if func_code.co_flags & CO_VARARGS:
2132n/a index += 1
2133n/a
2134n/a name = arg_names[index]
2135n/a annotation = annotations.get(name, _empty)
2136n/a parameters.append(Parameter(name, annotation=annotation,
2137n/a kind=_VAR_KEYWORD))
2138n/a
2139n/a # Is 'func' is a pure Python function - don't validate the
2140n/a # parameters list (for correct order and defaults), it should be OK.
2141n/a return cls(parameters,
2142n/a return_annotation=annotations.get('return', _empty),
2143n/a __validate_parameters__=is_duck_function)
2144n/a
2145n/a
2146n/adef _signature_from_callable(obj, *,
2147n/a follow_wrapper_chains=True,
2148n/a skip_bound_arg=True,
2149n/a sigcls):
2150n/a
2151n/a """Private helper function to get signature for arbitrary
2152n/a callable objects.
2153n/a """
2154n/a
2155n/a if not callable(obj):
2156n/a raise TypeError('{!r} is not a callable object'.format(obj))
2157n/a
2158n/a if isinstance(obj, types.MethodType):
2159n/a # In this case we skip the first parameter of the underlying
2160n/a # function (usually `self` or `cls`).
2161n/a sig = _signature_from_callable(
2162n/a obj.__func__,
2163n/a follow_wrapper_chains=follow_wrapper_chains,
2164n/a skip_bound_arg=skip_bound_arg,
2165n/a sigcls=sigcls)
2166n/a
2167n/a if skip_bound_arg:
2168n/a return _signature_bound_method(sig)
2169n/a else:
2170n/a return sig
2171n/a
2172n/a # Was this function wrapped by a decorator?
2173n/a if follow_wrapper_chains:
2174n/a obj = unwrap(obj, stop=(lambda f: hasattr(f, "__signature__")))
2175n/a if isinstance(obj, types.MethodType):
2176n/a # If the unwrapped object is a *method*, we might want to
2177n/a # skip its first parameter (self).
2178n/a # See test_signature_wrapped_bound_method for details.
2179n/a return _signature_from_callable(
2180n/a obj,
2181n/a follow_wrapper_chains=follow_wrapper_chains,
2182n/a skip_bound_arg=skip_bound_arg,
2183n/a sigcls=sigcls)
2184n/a
2185n/a try:
2186n/a sig = obj.__signature__
2187n/a except AttributeError:
2188n/a pass
2189n/a else:
2190n/a if sig is not None:
2191n/a if not isinstance(sig, Signature):
2192n/a raise TypeError(
2193n/a 'unexpected object {!r} in __signature__ '
2194n/a 'attribute'.format(sig))
2195n/a return sig
2196n/a
2197n/a try:
2198n/a partialmethod = obj._partialmethod
2199n/a except AttributeError:
2200n/a pass
2201n/a else:
2202n/a if isinstance(partialmethod, functools.partialmethod):
2203n/a # Unbound partialmethod (see functools.partialmethod)
2204n/a # This means, that we need to calculate the signature
2205n/a # as if it's a regular partial object, but taking into
2206n/a # account that the first positional argument
2207n/a # (usually `self`, or `cls`) will not be passed
2208n/a # automatically (as for boundmethods)
2209n/a
2210n/a wrapped_sig = _signature_from_callable(
2211n/a partialmethod.func,
2212n/a follow_wrapper_chains=follow_wrapper_chains,
2213n/a skip_bound_arg=skip_bound_arg,
2214n/a sigcls=sigcls)
2215n/a
2216n/a sig = _signature_get_partial(wrapped_sig, partialmethod, (None,))
2217n/a
2218n/a first_wrapped_param = tuple(wrapped_sig.parameters.values())[0]
2219n/a new_params = (first_wrapped_param,) + tuple(sig.parameters.values())
2220n/a
2221n/a return sig.replace(parameters=new_params)
2222n/a
2223n/a if isfunction(obj) or _signature_is_functionlike(obj):
2224n/a # If it's a pure Python function, or an object that is duck type
2225n/a # of a Python function (Cython functions, for instance), then:
2226n/a return _signature_from_function(sigcls, obj)
2227n/a
2228n/a if _signature_is_builtin(obj):
2229n/a return _signature_from_builtin(sigcls, obj,
2230n/a skip_bound_arg=skip_bound_arg)
2231n/a
2232n/a if isinstance(obj, functools.partial):
2233n/a wrapped_sig = _signature_from_callable(
2234n/a obj.func,
2235n/a follow_wrapper_chains=follow_wrapper_chains,
2236n/a skip_bound_arg=skip_bound_arg,
2237n/a sigcls=sigcls)
2238n/a return _signature_get_partial(wrapped_sig, obj)
2239n/a
2240n/a sig = None
2241n/a if isinstance(obj, type):
2242n/a # obj is a class or a metaclass
2243n/a
2244n/a # First, let's see if it has an overloaded __call__ defined
2245n/a # in its metaclass
2246n/a call = _signature_get_user_defined_method(type(obj), '__call__')
2247n/a if call is not None:
2248n/a sig = _signature_from_callable(
2249n/a call,
2250n/a follow_wrapper_chains=follow_wrapper_chains,
2251n/a skip_bound_arg=skip_bound_arg,
2252n/a sigcls=sigcls)
2253n/a else:
2254n/a # Now we check if the 'obj' class has a '__new__' method
2255n/a new = _signature_get_user_defined_method(obj, '__new__')
2256n/a if new is not None:
2257n/a sig = _signature_from_callable(
2258n/a new,
2259n/a follow_wrapper_chains=follow_wrapper_chains,
2260n/a skip_bound_arg=skip_bound_arg,
2261n/a sigcls=sigcls)
2262n/a else:
2263n/a # Finally, we should have at least __init__ implemented
2264n/a init = _signature_get_user_defined_method(obj, '__init__')
2265n/a if init is not None:
2266n/a sig = _signature_from_callable(
2267n/a init,
2268n/a follow_wrapper_chains=follow_wrapper_chains,
2269n/a skip_bound_arg=skip_bound_arg,
2270n/a sigcls=sigcls)
2271n/a
2272n/a if sig is None:
2273n/a # At this point we know, that `obj` is a class, with no user-
2274n/a # defined '__init__', '__new__', or class-level '__call__'
2275n/a
2276n/a for base in obj.__mro__[:-1]:
2277n/a # Since '__text_signature__' is implemented as a
2278n/a # descriptor that extracts text signature from the
2279n/a # class docstring, if 'obj' is derived from a builtin
2280n/a # class, its own '__text_signature__' may be 'None'.
2281n/a # Therefore, we go through the MRO (except the last
2282n/a # class in there, which is 'object') to find the first
2283n/a # class with non-empty text signature.
2284n/a try:
2285n/a text_sig = base.__text_signature__
2286n/a except AttributeError:
2287n/a pass
2288n/a else:
2289n/a if text_sig:
2290n/a # If 'obj' class has a __text_signature__ attribute:
2291n/a # return a signature based on it
2292n/a return _signature_fromstr(sigcls, obj, text_sig)
2293n/a
2294n/a # No '__text_signature__' was found for the 'obj' class.
2295n/a # Last option is to check if its '__init__' is
2296n/a # object.__init__ or type.__init__.
2297n/a if type not in obj.__mro__:
2298n/a # We have a class (not metaclass), but no user-defined
2299n/a # __init__ or __new__ for it
2300n/a if (obj.__init__ is object.__init__ and
2301n/a obj.__new__ is object.__new__):
2302n/a # Return a signature of 'object' builtin.
2303n/a return signature(object)
2304n/a else:
2305n/a raise ValueError(
2306n/a 'no signature found for builtin type {!r}'.format(obj))
2307n/a
2308n/a elif not isinstance(obj, _NonUserDefinedCallables):
2309n/a # An object with __call__
2310n/a # We also check that the 'obj' is not an instance of
2311n/a # _WrapperDescriptor or _MethodWrapper to avoid
2312n/a # infinite recursion (and even potential segfault)
2313n/a call = _signature_get_user_defined_method(type(obj), '__call__')
2314n/a if call is not None:
2315n/a try:
2316n/a sig = _signature_from_callable(
2317n/a call,
2318n/a follow_wrapper_chains=follow_wrapper_chains,
2319n/a skip_bound_arg=skip_bound_arg,
2320n/a sigcls=sigcls)
2321n/a except ValueError as ex:
2322n/a msg = 'no signature found for {!r}'.format(obj)
2323n/a raise ValueError(msg) from ex
2324n/a
2325n/a if sig is not None:
2326n/a # For classes and objects we skip the first parameter of their
2327n/a # __call__, __new__, or __init__ methods
2328n/a if skip_bound_arg:
2329n/a return _signature_bound_method(sig)
2330n/a else:
2331n/a return sig
2332n/a
2333n/a if isinstance(obj, types.BuiltinFunctionType):
2334n/a # Raise a nicer error message for builtins
2335n/a msg = 'no signature found for builtin function {!r}'.format(obj)
2336n/a raise ValueError(msg)
2337n/a
2338n/a raise ValueError('callable {!r} is not supported by signature'.format(obj))
2339n/a
2340n/a
2341n/aclass _void:
2342n/a """A private marker - used in Parameter & Signature."""
2343n/a
2344n/a
2345n/aclass _empty:
2346n/a """Marker object for Signature.empty and Parameter.empty."""
2347n/a
2348n/a
2349n/aclass _ParameterKind(enum.IntEnum):
2350n/a POSITIONAL_ONLY = 0
2351n/a POSITIONAL_OR_KEYWORD = 1
2352n/a VAR_POSITIONAL = 2
2353n/a KEYWORD_ONLY = 3
2354n/a VAR_KEYWORD = 4
2355n/a
2356n/a def __str__(self):
2357n/a return self._name_
2358n/a
2359n/a
2360n/a_POSITIONAL_ONLY = _ParameterKind.POSITIONAL_ONLY
2361n/a_POSITIONAL_OR_KEYWORD = _ParameterKind.POSITIONAL_OR_KEYWORD
2362n/a_VAR_POSITIONAL = _ParameterKind.VAR_POSITIONAL
2363n/a_KEYWORD_ONLY = _ParameterKind.KEYWORD_ONLY
2364n/a_VAR_KEYWORD = _ParameterKind.VAR_KEYWORD
2365n/a
2366n/a
2367n/aclass Parameter:
2368n/a """Represents a parameter in a function signature.
2369n/a
2370n/a Has the following public attributes:
2371n/a
2372n/a * name : str
2373n/a The name of the parameter as a string.
2374n/a * default : object
2375n/a The default value for the parameter if specified. If the
2376n/a parameter has no default value, this attribute is set to
2377n/a `Parameter.empty`.
2378n/a * annotation
2379n/a The annotation for the parameter if specified. If the
2380n/a parameter has no annotation, this attribute is set to
2381n/a `Parameter.empty`.
2382n/a * kind : str
2383n/a Describes how argument values are bound to the parameter.
2384n/a Possible values: `Parameter.POSITIONAL_ONLY`,
2385n/a `Parameter.POSITIONAL_OR_KEYWORD`, `Parameter.VAR_POSITIONAL`,
2386n/a `Parameter.KEYWORD_ONLY`, `Parameter.VAR_KEYWORD`.
2387n/a """
2388n/a
2389n/a __slots__ = ('_name', '_kind', '_default', '_annotation')
2390n/a
2391n/a POSITIONAL_ONLY = _POSITIONAL_ONLY
2392n/a POSITIONAL_OR_KEYWORD = _POSITIONAL_OR_KEYWORD
2393n/a VAR_POSITIONAL = _VAR_POSITIONAL
2394n/a KEYWORD_ONLY = _KEYWORD_ONLY
2395n/a VAR_KEYWORD = _VAR_KEYWORD
2396n/a
2397n/a empty = _empty
2398n/a
2399n/a def __init__(self, name, kind, *, default=_empty, annotation=_empty):
2400n/a
2401n/a if kind not in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD,
2402n/a _VAR_POSITIONAL, _KEYWORD_ONLY, _VAR_KEYWORD):
2403n/a raise ValueError("invalid value for 'Parameter.kind' attribute")
2404n/a self._kind = kind
2405n/a
2406n/a if default is not _empty:
2407n/a if kind in (_VAR_POSITIONAL, _VAR_KEYWORD):
2408n/a msg = '{} parameters cannot have default values'.format(kind)
2409n/a raise ValueError(msg)
2410n/a self._default = default
2411n/a self._annotation = annotation
2412n/a
2413n/a if name is _empty:
2414n/a raise ValueError('name is a required attribute for Parameter')
2415n/a
2416n/a if not isinstance(name, str):
2417n/a raise TypeError("name must be a str, not a {!r}".format(name))
2418n/a
2419n/a if name[0] == '.' and name[1:].isdigit():
2420n/a # These are implicit arguments generated by comprehensions. In
2421n/a # order to provide a friendlier interface to users, we recast
2422n/a # their name as "implicitN" and treat them as positional-only.
2423n/a # See issue 19611.
2424n/a if kind != _POSITIONAL_OR_KEYWORD:
2425n/a raise ValueError(
2426n/a 'implicit arguments must be passed in as {}'.format(
2427n/a _POSITIONAL_OR_KEYWORD
2428n/a )
2429n/a )
2430n/a self._kind = _POSITIONAL_ONLY
2431n/a name = 'implicit{}'.format(name[1:])
2432n/a
2433n/a if not name.isidentifier():
2434n/a raise ValueError('{!r} is not a valid parameter name'.format(name))
2435n/a
2436n/a self._name = name
2437n/a
2438n/a def __reduce__(self):
2439n/a return (type(self),
2440n/a (self._name, self._kind),
2441n/a {'_default': self._default,
2442n/a '_annotation': self._annotation})
2443n/a
2444n/a def __setstate__(self, state):
2445n/a self._default = state['_default']
2446n/a self._annotation = state['_annotation']
2447n/a
2448n/a @property
2449n/a def name(self):
2450n/a return self._name
2451n/a
2452n/a @property
2453n/a def default(self):
2454n/a return self._default
2455n/a
2456n/a @property
2457n/a def annotation(self):
2458n/a return self._annotation
2459n/a
2460n/a @property
2461n/a def kind(self):
2462n/a return self._kind
2463n/a
2464n/a def replace(self, *, name=_void, kind=_void,
2465n/a annotation=_void, default=_void):
2466n/a """Creates a customized copy of the Parameter."""
2467n/a
2468n/a if name is _void:
2469n/a name = self._name
2470n/a
2471n/a if kind is _void:
2472n/a kind = self._kind
2473n/a
2474n/a if annotation is _void:
2475n/a annotation = self._annotation
2476n/a
2477n/a if default is _void:
2478n/a default = self._default
2479n/a
2480n/a return type(self)(name, kind, default=default, annotation=annotation)
2481n/a
2482n/a def __str__(self):
2483n/a kind = self.kind
2484n/a formatted = self._name
2485n/a
2486n/a # Add annotation and default value
2487n/a if self._annotation is not _empty:
2488n/a formatted = '{}:{}'.format(formatted,
2489n/a formatannotation(self._annotation))
2490n/a
2491n/a if self._default is not _empty:
2492n/a formatted = '{}={}'.format(formatted, repr(self._default))
2493n/a
2494n/a if kind == _VAR_POSITIONAL:
2495n/a formatted = '*' + formatted
2496n/a elif kind == _VAR_KEYWORD:
2497n/a formatted = '**' + formatted
2498n/a
2499n/a return formatted
2500n/a
2501n/a def __repr__(self):
2502n/a return '<{} "{}">'.format(self.__class__.__name__, self)
2503n/a
2504n/a def __hash__(self):
2505n/a return hash((self.name, self.kind, self.annotation, self.default))
2506n/a
2507n/a def __eq__(self, other):
2508n/a if self is other:
2509n/a return True
2510n/a if not isinstance(other, Parameter):
2511n/a return NotImplemented
2512n/a return (self._name == other._name and
2513n/a self._kind == other._kind and
2514n/a self._default == other._default and
2515n/a self._annotation == other._annotation)
2516n/a
2517n/a
2518n/aclass BoundArguments:
2519n/a """Result of `Signature.bind` call. Holds the mapping of arguments
2520n/a to the function's parameters.
2521n/a
2522n/a Has the following public attributes:
2523n/a
2524n/a * arguments : OrderedDict
2525n/a An ordered mutable mapping of parameters' names to arguments' values.
2526n/a Does not contain arguments' default values.
2527n/a * signature : Signature
2528n/a The Signature object that created this instance.
2529n/a * args : tuple
2530n/a Tuple of positional arguments values.
2531n/a * kwargs : dict
2532n/a Dict of keyword arguments values.
2533n/a """
2534n/a
2535n/a __slots__ = ('arguments', '_signature', '__weakref__')
2536n/a
2537n/a def __init__(self, signature, arguments):
2538n/a self.arguments = arguments
2539n/a self._signature = signature
2540n/a
2541n/a @property
2542n/a def signature(self):
2543n/a return self._signature
2544n/a
2545n/a @property
2546n/a def args(self):
2547n/a args = []
2548n/a for param_name, param in self._signature.parameters.items():
2549n/a if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
2550n/a break
2551n/a
2552n/a try:
2553n/a arg = self.arguments[param_name]
2554n/a except KeyError:
2555n/a # We're done here. Other arguments
2556n/a # will be mapped in 'BoundArguments.kwargs'
2557n/a break
2558n/a else:
2559n/a if param.kind == _VAR_POSITIONAL:
2560n/a # *args
2561n/a args.extend(arg)
2562n/a else:
2563n/a # plain argument
2564n/a args.append(arg)
2565n/a
2566n/a return tuple(args)
2567n/a
2568n/a @property
2569n/a def kwargs(self):
2570n/a kwargs = {}
2571n/a kwargs_started = False
2572n/a for param_name, param in self._signature.parameters.items():
2573n/a if not kwargs_started:
2574n/a if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
2575n/a kwargs_started = True
2576n/a else:
2577n/a if param_name not in self.arguments:
2578n/a kwargs_started = True
2579n/a continue
2580n/a
2581n/a if not kwargs_started:
2582n/a continue
2583n/a
2584n/a try:
2585n/a arg = self.arguments[param_name]
2586n/a except KeyError:
2587n/a pass
2588n/a else:
2589n/a if param.kind == _VAR_KEYWORD:
2590n/a # **kwargs
2591n/a kwargs.update(arg)
2592n/a else:
2593n/a # plain keyword argument
2594n/a kwargs[param_name] = arg
2595n/a
2596n/a return kwargs
2597n/a
2598n/a def apply_defaults(self):
2599n/a """Set default values for missing arguments.
2600n/a
2601n/a For variable-positional arguments (*args) the default is an
2602n/a empty tuple.
2603n/a
2604n/a For variable-keyword arguments (**kwargs) the default is an
2605n/a empty dict.
2606n/a """
2607n/a arguments = self.arguments
2608n/a new_arguments = []
2609n/a for name, param in self._signature.parameters.items():
2610n/a try:
2611n/a new_arguments.append((name, arguments[name]))
2612n/a except KeyError:
2613n/a if param.default is not _empty:
2614n/a val = param.default
2615n/a elif param.kind is _VAR_POSITIONAL:
2616n/a val = ()
2617n/a elif param.kind is _VAR_KEYWORD:
2618n/a val = {}
2619n/a else:
2620n/a # This BoundArguments was likely produced by
2621n/a # Signature.bind_partial().
2622n/a continue
2623n/a new_arguments.append((name, val))
2624n/a self.arguments = OrderedDict(new_arguments)
2625n/a
2626n/a def __eq__(self, other):
2627n/a if self is other:
2628n/a return True
2629n/a if not isinstance(other, BoundArguments):
2630n/a return NotImplemented
2631n/a return (self.signature == other.signature and
2632n/a self.arguments == other.arguments)
2633n/a
2634n/a def __setstate__(self, state):
2635n/a self._signature = state['_signature']
2636n/a self.arguments = state['arguments']
2637n/a
2638n/a def __getstate__(self):
2639n/a return {'_signature': self._signature, 'arguments': self.arguments}
2640n/a
2641n/a def __repr__(self):
2642n/a args = []
2643n/a for arg, value in self.arguments.items():
2644n/a args.append('{}={!r}'.format(arg, value))
2645n/a return '<{} ({})>'.format(self.__class__.__name__, ', '.join(args))
2646n/a
2647n/a
2648n/aclass Signature:
2649n/a """A Signature object represents the overall signature of a function.
2650n/a It stores a Parameter object for each parameter accepted by the
2651n/a function, as well as information specific to the function itself.
2652n/a
2653n/a A Signature object has the following public attributes and methods:
2654n/a
2655n/a * parameters : OrderedDict
2656n/a An ordered mapping of parameters' names to the corresponding
2657n/a Parameter objects (keyword-only arguments are in the same order
2658n/a as listed in `code.co_varnames`).
2659n/a * return_annotation : object
2660n/a The annotation for the return type of the function if specified.
2661n/a If the function has no annotation for its return type, this
2662n/a attribute is set to `Signature.empty`.
2663n/a * bind(*args, **kwargs) -> BoundArguments
2664n/a Creates a mapping from positional and keyword arguments to
2665n/a parameters.
2666n/a * bind_partial(*args, **kwargs) -> BoundArguments
2667n/a Creates a partial mapping from positional and keyword arguments
2668n/a to parameters (simulating 'functools.partial' behavior.)
2669n/a """
2670n/a
2671n/a __slots__ = ('_return_annotation', '_parameters')
2672n/a
2673n/a _parameter_cls = Parameter
2674n/a _bound_arguments_cls = BoundArguments
2675n/a
2676n/a empty = _empty
2677n/a
2678n/a def __init__(self, parameters=None, *, return_annotation=_empty,
2679n/a __validate_parameters__=True):
2680n/a """Constructs Signature from the given list of Parameter
2681n/a objects and 'return_annotation'. All arguments are optional.
2682n/a """
2683n/a
2684n/a if parameters is None:
2685n/a params = OrderedDict()
2686n/a else:
2687n/a if __validate_parameters__:
2688n/a params = OrderedDict()
2689n/a top_kind = _POSITIONAL_ONLY
2690n/a kind_defaults = False
2691n/a
2692n/a for idx, param in enumerate(parameters):
2693n/a kind = param.kind
2694n/a name = param.name
2695n/a
2696n/a if kind < top_kind:
2697n/a msg = 'wrong parameter order: {!r} before {!r}'
2698n/a msg = msg.format(top_kind, kind)
2699n/a raise ValueError(msg)
2700n/a elif kind > top_kind:
2701n/a kind_defaults = False
2702n/a top_kind = kind
2703n/a
2704n/a if kind in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD):
2705n/a if param.default is _empty:
2706n/a if kind_defaults:
2707n/a # No default for this parameter, but the
2708n/a # previous parameter of the same kind had
2709n/a # a default
2710n/a msg = 'non-default argument follows default ' \
2711n/a 'argument'
2712n/a raise ValueError(msg)
2713n/a else:
2714n/a # There is a default for this parameter.
2715n/a kind_defaults = True
2716n/a
2717n/a if name in params:
2718n/a msg = 'duplicate parameter name: {!r}'.format(name)
2719n/a raise ValueError(msg)
2720n/a
2721n/a params[name] = param
2722n/a else:
2723n/a params = OrderedDict(((param.name, param)
2724n/a for param in parameters))
2725n/a
2726n/a self._parameters = types.MappingProxyType(params)
2727n/a self._return_annotation = return_annotation
2728n/a
2729n/a @classmethod
2730n/a def from_function(cls, func):
2731n/a """Constructs Signature for the given python function."""
2732n/a
2733n/a warnings.warn("inspect.Signature.from_function() is deprecated, "
2734n/a "use Signature.from_callable()",
2735n/a DeprecationWarning, stacklevel=2)
2736n/a return _signature_from_function(cls, func)
2737n/a
2738n/a @classmethod
2739n/a def from_builtin(cls, func):
2740n/a """Constructs Signature for the given builtin function."""
2741n/a
2742n/a warnings.warn("inspect.Signature.from_builtin() is deprecated, "
2743n/a "use Signature.from_callable()",
2744n/a DeprecationWarning, stacklevel=2)
2745n/a return _signature_from_builtin(cls, func)
2746n/a
2747n/a @classmethod
2748n/a def from_callable(cls, obj, *, follow_wrapped=True):
2749n/a """Constructs Signature for the given callable object."""
2750n/a return _signature_from_callable(obj, sigcls=cls,
2751n/a follow_wrapper_chains=follow_wrapped)
2752n/a
2753n/a @property
2754n/a def parameters(self):
2755n/a return self._parameters
2756n/a
2757n/a @property
2758n/a def return_annotation(self):
2759n/a return self._return_annotation
2760n/a
2761n/a def replace(self, *, parameters=_void, return_annotation=_void):
2762n/a """Creates a customized copy of the Signature.
2763n/a Pass 'parameters' and/or 'return_annotation' arguments
2764n/a to override them in the new copy.
2765n/a """
2766n/a
2767n/a if parameters is _void:
2768n/a parameters = self.parameters.values()
2769n/a
2770n/a if return_annotation is _void:
2771n/a return_annotation = self._return_annotation
2772n/a
2773n/a return type(self)(parameters,
2774n/a return_annotation=return_annotation)
2775n/a
2776n/a def _hash_basis(self):
2777n/a params = tuple(param for param in self.parameters.values()
2778n/a if param.kind != _KEYWORD_ONLY)
2779n/a
2780n/a kwo_params = {param.name: param for param in self.parameters.values()
2781n/a if param.kind == _KEYWORD_ONLY}
2782n/a
2783n/a return params, kwo_params, self.return_annotation
2784n/a
2785n/a def __hash__(self):
2786n/a params, kwo_params, return_annotation = self._hash_basis()
2787n/a kwo_params = frozenset(kwo_params.values())
2788n/a return hash((params, kwo_params, return_annotation))
2789n/a
2790n/a def __eq__(self, other):
2791n/a if self is other:
2792n/a return True
2793n/a if not isinstance(other, Signature):
2794n/a return NotImplemented
2795n/a return self._hash_basis() == other._hash_basis()
2796n/a
2797n/a def _bind(self, args, kwargs, *, partial=False):
2798n/a """Private method. Don't use directly."""
2799n/a
2800n/a arguments = OrderedDict()
2801n/a
2802n/a parameters = iter(self.parameters.values())
2803n/a parameters_ex = ()
2804n/a arg_vals = iter(args)
2805n/a
2806n/a while True:
2807n/a # Let's iterate through the positional arguments and corresponding
2808n/a # parameters
2809n/a try:
2810n/a arg_val = next(arg_vals)
2811n/a except StopIteration:
2812n/a # No more positional arguments
2813n/a try:
2814n/a param = next(parameters)
2815n/a except StopIteration:
2816n/a # No more parameters. That's it. Just need to check that
2817n/a # we have no `kwargs` after this while loop
2818n/a break
2819n/a else:
2820n/a if param.kind == _VAR_POSITIONAL:
2821n/a # That's OK, just empty *args. Let's start parsing
2822n/a # kwargs
2823n/a break
2824n/a elif param.name in kwargs:
2825n/a if param.kind == _POSITIONAL_ONLY:
2826n/a msg = '{arg!r} parameter is positional only, ' \
2827n/a 'but was passed as a keyword'
2828n/a msg = msg.format(arg=param.name)
2829n/a raise TypeError(msg) from None
2830n/a parameters_ex = (param,)
2831n/a break
2832n/a elif (param.kind == _VAR_KEYWORD or
2833n/a param.default is not _empty):
2834n/a # That's fine too - we have a default value for this
2835n/a # parameter. So, lets start parsing `kwargs`, starting
2836n/a # with the current parameter
2837n/a parameters_ex = (param,)
2838n/a break
2839n/a else:
2840n/a # No default, not VAR_KEYWORD, not VAR_POSITIONAL,
2841n/a # not in `kwargs`
2842n/a if partial:
2843n/a parameters_ex = (param,)
2844n/a break
2845n/a else:
2846n/a msg = 'missing a required argument: {arg!r}'
2847n/a msg = msg.format(arg=param.name)
2848n/a raise TypeError(msg) from None
2849n/a else:
2850n/a # We have a positional argument to process
2851n/a try:
2852n/a param = next(parameters)
2853n/a except StopIteration:
2854n/a raise TypeError('too many positional arguments') from None
2855n/a else:
2856n/a if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
2857n/a # Looks like we have no parameter for this positional
2858n/a # argument
2859n/a raise TypeError(
2860n/a 'too many positional arguments') from None
2861n/a
2862n/a if param.kind == _VAR_POSITIONAL:
2863n/a # We have an '*args'-like argument, let's fill it with
2864n/a # all positional arguments we have left and move on to
2865n/a # the next phase
2866n/a values = [arg_val]
2867n/a values.extend(arg_vals)
2868n/a arguments[param.name] = tuple(values)
2869n/a break
2870n/a
2871n/a if param.name in kwargs:
2872n/a raise TypeError(
2873n/a 'multiple values for argument {arg!r}'.format(
2874n/a arg=param.name)) from None
2875n/a
2876n/a arguments[param.name] = arg_val
2877n/a
2878n/a # Now, we iterate through the remaining parameters to process
2879n/a # keyword arguments
2880n/a kwargs_param = None
2881n/a for param in itertools.chain(parameters_ex, parameters):
2882n/a if param.kind == _VAR_KEYWORD:
2883n/a # Memorize that we have a '**kwargs'-like parameter
2884n/a kwargs_param = param
2885n/a continue
2886n/a
2887n/a if param.kind == _VAR_POSITIONAL:
2888n/a # Named arguments don't refer to '*args'-like parameters.
2889n/a # We only arrive here if the positional arguments ended
2890n/a # before reaching the last parameter before *args.
2891n/a continue
2892n/a
2893n/a param_name = param.name
2894n/a try:
2895n/a arg_val = kwargs.pop(param_name)
2896n/a except KeyError:
2897n/a # We have no value for this parameter. It's fine though,
2898n/a # if it has a default value, or it is an '*args'-like
2899n/a # parameter, left alone by the processing of positional
2900n/a # arguments.
2901n/a if (not partial and param.kind != _VAR_POSITIONAL and
2902n/a param.default is _empty):
2903n/a raise TypeError('missing a required argument: {arg!r}'. \
2904n/a format(arg=param_name)) from None
2905n/a
2906n/a else:
2907n/a if param.kind == _POSITIONAL_ONLY:
2908n/a # This should never happen in case of a properly built
2909n/a # Signature object (but let's have this check here
2910n/a # to ensure correct behaviour just in case)
2911n/a raise TypeError('{arg!r} parameter is positional only, '
2912n/a 'but was passed as a keyword'. \
2913n/a format(arg=param.name))
2914n/a
2915n/a arguments[param_name] = arg_val
2916n/a
2917n/a if kwargs:
2918n/a if kwargs_param is not None:
2919n/a # Process our '**kwargs'-like parameter
2920n/a arguments[kwargs_param.name] = kwargs
2921n/a else:
2922n/a raise TypeError(
2923n/a 'got an unexpected keyword argument {arg!r}'.format(
2924n/a arg=next(iter(kwargs))))
2925n/a
2926n/a return self._bound_arguments_cls(self, arguments)
2927n/a
2928n/a def bind(*args, **kwargs):
2929n/a """Get a BoundArguments object, that maps the passed `args`
2930n/a and `kwargs` to the function's signature. Raises `TypeError`
2931n/a if the passed arguments can not be bound.
2932n/a """
2933n/a return args[0]._bind(args[1:], kwargs)
2934n/a
2935n/a def bind_partial(*args, **kwargs):
2936n/a """Get a BoundArguments object, that partially maps the
2937n/a passed `args` and `kwargs` to the function's signature.
2938n/a Raises `TypeError` if the passed arguments can not be bound.
2939n/a """
2940n/a return args[0]._bind(args[1:], kwargs, partial=True)
2941n/a
2942n/a def __reduce__(self):
2943n/a return (type(self),
2944n/a (tuple(self._parameters.values()),),
2945n/a {'_return_annotation': self._return_annotation})
2946n/a
2947n/a def __setstate__(self, state):
2948n/a self._return_annotation = state['_return_annotation']
2949n/a
2950n/a def __repr__(self):
2951n/a return '<{} {}>'.format(self.__class__.__name__, self)
2952n/a
2953n/a def __str__(self):
2954n/a result = []
2955n/a render_pos_only_separator = False
2956n/a render_kw_only_separator = True
2957n/a for param in self.parameters.values():
2958n/a formatted = str(param)
2959n/a
2960n/a kind = param.kind
2961n/a
2962n/a if kind == _POSITIONAL_ONLY:
2963n/a render_pos_only_separator = True
2964n/a elif render_pos_only_separator:
2965n/a # It's not a positional-only parameter, and the flag
2966n/a # is set to 'True' (there were pos-only params before.)
2967n/a result.append('/')
2968n/a render_pos_only_separator = False
2969n/a
2970n/a if kind == _VAR_POSITIONAL:
2971n/a # OK, we have an '*args'-like parameter, so we won't need
2972n/a # a '*' to separate keyword-only arguments
2973n/a render_kw_only_separator = False
2974n/a elif kind == _KEYWORD_ONLY and render_kw_only_separator:
2975n/a # We have a keyword-only parameter to render and we haven't
2976n/a # rendered an '*args'-like parameter before, so add a '*'
2977n/a # separator to the parameters list ("foo(arg1, *, arg2)" case)
2978n/a result.append('*')
2979n/a # This condition should be only triggered once, so
2980n/a # reset the flag
2981n/a render_kw_only_separator = False
2982n/a
2983n/a result.append(formatted)
2984n/a
2985n/a if render_pos_only_separator:
2986n/a # There were only positional-only parameters, hence the
2987n/a # flag was not reset to 'False'
2988n/a result.append('/')
2989n/a
2990n/a rendered = '({})'.format(', '.join(result))
2991n/a
2992n/a if self.return_annotation is not _empty:
2993n/a anno = formatannotation(self.return_annotation)
2994n/a rendered += ' -> {}'.format(anno)
2995n/a
2996n/a return rendered
2997n/a
2998n/a
2999n/adef signature(obj, *, follow_wrapped=True):
3000n/a """Get a signature object for the passed callable."""
3001n/a return Signature.from_callable(obj, follow_wrapped=follow_wrapped)
3002n/a
3003n/a
3004n/adef _main():
3005n/a """ Logic for inspecting an object given at command line """
3006n/a import argparse
3007n/a import importlib
3008n/a
3009n/a parser = argparse.ArgumentParser()
3010n/a parser.add_argument(
3011n/a 'object',
3012n/a help="The object to be analysed. "
3013n/a "It supports the 'module:qualname' syntax")
3014n/a parser.add_argument(
3015n/a '-d', '--details', action='store_true',
3016n/a help='Display info about the module rather than its source code')
3017n/a
3018n/a args = parser.parse_args()
3019n/a
3020n/a target = args.object
3021n/a mod_name, has_attrs, attrs = target.partition(":")
3022n/a try:
3023n/a obj = module = importlib.import_module(mod_name)
3024n/a except Exception as exc:
3025n/a msg = "Failed to import {} ({}: {})".format(mod_name,
3026n/a type(exc).__name__,
3027n/a exc)
3028n/a print(msg, file=sys.stderr)
3029n/a exit(2)
3030n/a
3031n/a if has_attrs:
3032n/a parts = attrs.split(".")
3033n/a obj = module
3034n/a for part in parts:
3035n/a obj = getattr(obj, part)
3036n/a
3037n/a if module.__name__ in sys.builtin_module_names:
3038n/a print("Can't get info for builtin modules.", file=sys.stderr)
3039n/a exit(1)
3040n/a
3041n/a if args.details:
3042n/a print('Target: {}'.format(target))
3043n/a print('Origin: {}'.format(getsourcefile(module)))
3044n/a print('Cached: {}'.format(module.__cached__))
3045n/a if obj is module:
3046n/a print('Loader: {}'.format(repr(module.__loader__)))
3047n/a if hasattr(module, '__path__'):
3048n/a print('Submodule search path: {}'.format(module.__path__))
3049n/a else:
3050n/a try:
3051n/a __, lineno = findsource(obj)
3052n/a except Exception:
3053n/a pass
3054n/a else:
3055n/a print('Line: {}'.format(lineno))
3056n/a
3057n/a print('\n')
3058n/a else:
3059n/a print(getsource(obj))
3060n/a
3061n/a
3062n/aif __name__ == "__main__":
3063n/a _main()