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