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