1import os 2import sys 3import functools 4import operator 5import weakref 6import inspect 7 8PY2 = sys.version_info[0] == 2 9 10if PY2: 11 string_types = basestring, 12else: 13 string_types = str, 14 15def with_metaclass(meta, *bases): 16 """Create a base class with a metaclass.""" 17 return meta("NewBase", bases, {}) 18 19class _ObjectProxyMethods(object): 20 21 # We use properties to override the values of __module__ and 22 # __doc__. If we add these in ObjectProxy, the derived class 23 # __dict__ will still be setup to have string variants of these 24 # attributes and the rules of descriptors means that they appear to 25 # take precedence over the properties in the base class. To avoid 26 # that, we copy the properties into the derived class type itself 27 # via a meta class. In that way the properties will always take 28 # precedence. 29 30 @property 31 def __module__(self): 32 return self.__wrapped__.__module__ 33 34 @__module__.setter 35 def __module__(self, value): 36 self.__wrapped__.__module__ = value 37 38 @property 39 def __doc__(self): 40 return self.__wrapped__.__doc__ 41 42 @__doc__.setter 43 def __doc__(self, value): 44 self.__wrapped__.__doc__ = value 45 46 # We similar use a property for __dict__. We need __dict__ to be 47 # explicit to ensure that vars() works as expected. 48 49 @property 50 def __dict__(self): 51 return self.__wrapped__.__dict__ 52 53 # Need to also propagate the special __weakref__ attribute for case 54 # where decorating classes which will define this. If do not define 55 # it and use a function like inspect.getmembers() on a decorator 56 # class it will fail. This can't be in the derived classes. 57 58 @property 59 def __weakref__(self): 60 return self.__wrapped__.__weakref__ 61 62class _ObjectProxyMetaType(type): 63 def __new__(cls, name, bases, dictionary): 64 # Copy our special properties into the class so that they 65 # always take precedence over attributes of the same name added 66 # during construction of a derived class. This is to save 67 # duplicating the implementation for them in all derived classes. 68 69 dictionary.update(vars(_ObjectProxyMethods)) 70 71 return type.__new__(cls, name, bases, dictionary) 72 73class ObjectProxy(with_metaclass(_ObjectProxyMetaType)): 74 75 __slots__ = '__wrapped__' 76 77 def __init__(self, wrapped): 78 object.__setattr__(self, '__wrapped__', wrapped) 79 80 # Python 3.2+ has the __qualname__ attribute, but it does not 81 # allow it to be overridden using a property and it must instead 82 # be an actual string object instead. 83 84 try: 85 object.__setattr__(self, '__qualname__', wrapped.__qualname__) 86 except AttributeError: 87 pass 88 89 # Python 3.10 onwards also does not allow itself to be overridden 90 # using a properly and it must instead be set explicitly. 91 92 try: 93 object.__setattr__(self, '__annotations__', wrapped.__annotations__) 94 except AttributeError: 95 pass 96 97 @property 98 def __name__(self): 99 return self.__wrapped__.__name__ 100 101 @__name__.setter 102 def __name__(self, value): 103 self.__wrapped__.__name__ = value 104 105 @property 106 def __class__(self): 107 return self.__wrapped__.__class__ 108 109 @__class__.setter 110 def __class__(self, value): 111 self.__wrapped__.__class__ = value 112 113 def __dir__(self): 114 return dir(self.__wrapped__) 115 116 def __str__(self): 117 return str(self.__wrapped__) 118 119 if not PY2: 120 def __bytes__(self): 121 return bytes(self.__wrapped__) 122 123 def __repr__(self): 124 return '<{} at 0x{:x} for {} at 0x{:x}>'.format( 125 type(self).__name__, id(self), 126 type(self.__wrapped__).__name__, 127 id(self.__wrapped__)) 128 129 def __reversed__(self): 130 return reversed(self.__wrapped__) 131 132 if not PY2: 133 def __round__(self): 134 return round(self.__wrapped__) 135 136 if sys.hexversion >= 0x03070000: 137 def __mro_entries__(self, bases): 138 return (self.__wrapped__,) 139 140 def __lt__(self, other): 141 return self.__wrapped__ < other 142 143 def __le__(self, other): 144 return self.__wrapped__ <= other 145 146 def __eq__(self, other): 147 return self.__wrapped__ == other 148 149 def __ne__(self, other): 150 return self.__wrapped__ != other 151 152 def __gt__(self, other): 153 return self.__wrapped__ > other 154 155 def __ge__(self, other): 156 return self.__wrapped__ >= other 157 158 def __hash__(self): 159 return hash(self.__wrapped__) 160 161 def __nonzero__(self): 162 return bool(self.__wrapped__) 163 164 def __bool__(self): 165 return bool(self.__wrapped__) 166 167 def __setattr__(self, name, value): 168 if name.startswith('_self_'): 169 object.__setattr__(self, name, value) 170 171 elif name == '__wrapped__': 172 object.__setattr__(self, name, value) 173 try: 174 object.__delattr__(self, '__qualname__') 175 except AttributeError: 176 pass 177 try: 178 object.__setattr__(self, '__qualname__', value.__qualname__) 179 except AttributeError: 180 pass 181 try: 182 object.__delattr__(self, '__annotations__') 183 except AttributeError: 184 pass 185 try: 186 object.__setattr__(self, '__annotations__', value.__annotations__) 187 except AttributeError: 188 pass 189 190 elif name == '__qualname__': 191 setattr(self.__wrapped__, name, value) 192 object.__setattr__(self, name, value) 193 194 elif name == '__annotations__': 195 setattr(self.__wrapped__, name, value) 196 object.__setattr__(self, name, value) 197 198 elif hasattr(type(self), name): 199 object.__setattr__(self, name, value) 200 201 else: 202 setattr(self.__wrapped__, name, value) 203 204 def __getattr__(self, name): 205 # If we are being to lookup '__wrapped__' then the 206 # '__init__()' method cannot have been called. 207 208 if name == '__wrapped__': 209 raise ValueError('wrapper has not been initialised') 210 211 return getattr(self.__wrapped__, name) 212 213 def __delattr__(self, name): 214 if name.startswith('_self_'): 215 object.__delattr__(self, name) 216 217 elif name == '__wrapped__': 218 raise TypeError('__wrapped__ must be an object') 219 220 elif name == '__qualname__': 221 object.__delattr__(self, name) 222 delattr(self.__wrapped__, name) 223 224 elif hasattr(type(self), name): 225 object.__delattr__(self, name) 226 227 else: 228 delattr(self.__wrapped__, name) 229 230 def __add__(self, other): 231 return self.__wrapped__ + other 232 233 def __sub__(self, other): 234 return self.__wrapped__ - other 235 236 def __mul__(self, other): 237 return self.__wrapped__ * other 238 239 def __div__(self, other): 240 return operator.div(self.__wrapped__, other) 241 242 def __truediv__(self, other): 243 return operator.truediv(self.__wrapped__, other) 244 245 def __floordiv__(self, other): 246 return self.__wrapped__ // other 247 248 def __mod__(self, other): 249 return self.__wrapped__ % other 250 251 def __divmod__(self, other): 252 return divmod(self.__wrapped__, other) 253 254 def __pow__(self, other, *args): 255 return pow(self.__wrapped__, other, *args) 256 257 def __lshift__(self, other): 258 return self.__wrapped__ << other 259 260 def __rshift__(self, other): 261 return self.__wrapped__ >> other 262 263 def __and__(self, other): 264 return self.__wrapped__ & other 265 266 def __xor__(self, other): 267 return self.__wrapped__ ^ other 268 269 def __or__(self, other): 270 return self.__wrapped__ | other 271 272 def __radd__(self, other): 273 return other + self.__wrapped__ 274 275 def __rsub__(self, other): 276 return other - self.__wrapped__ 277 278 def __rmul__(self, other): 279 return other * self.__wrapped__ 280 281 def __rdiv__(self, other): 282 return operator.div(other, self.__wrapped__) 283 284 def __rtruediv__(self, other): 285 return operator.truediv(other, self.__wrapped__) 286 287 def __rfloordiv__(self, other): 288 return other // self.__wrapped__ 289 290 def __rmod__(self, other): 291 return other % self.__wrapped__ 292 293 def __rdivmod__(self, other): 294 return divmod(other, self.__wrapped__) 295 296 def __rpow__(self, other, *args): 297 return pow(other, self.__wrapped__, *args) 298 299 def __rlshift__(self, other): 300 return other << self.__wrapped__ 301 302 def __rrshift__(self, other): 303 return other >> self.__wrapped__ 304 305 def __rand__(self, other): 306 return other & self.__wrapped__ 307 308 def __rxor__(self, other): 309 return other ^ self.__wrapped__ 310 311 def __ror__(self, other): 312 return other | self.__wrapped__ 313 314 def __iadd__(self, other): 315 self.__wrapped__ += other 316 return self 317 318 def __isub__(self, other): 319 self.__wrapped__ -= other 320 return self 321 322 def __imul__(self, other): 323 self.__wrapped__ *= other 324 return self 325 326 def __idiv__(self, other): 327 self.__wrapped__ = operator.idiv(self.__wrapped__, other) 328 return self 329 330 def __itruediv__(self, other): 331 self.__wrapped__ = operator.itruediv(self.__wrapped__, other) 332 return self 333 334 def __ifloordiv__(self, other): 335 self.__wrapped__ //= other 336 return self 337 338 def __imod__(self, other): 339 self.__wrapped__ %= other 340 return self 341 342 def __ipow__(self, other): 343 self.__wrapped__ **= other 344 return self 345 346 def __ilshift__(self, other): 347 self.__wrapped__ <<= other 348 return self 349 350 def __irshift__(self, other): 351 self.__wrapped__ >>= other 352 return self 353 354 def __iand__(self, other): 355 self.__wrapped__ &= other 356 return self 357 358 def __ixor__(self, other): 359 self.__wrapped__ ^= other 360 return self 361 362 def __ior__(self, other): 363 self.__wrapped__ |= other 364 return self 365 366 def __neg__(self): 367 return -self.__wrapped__ 368 369 def __pos__(self): 370 return +self.__wrapped__ 371 372 def __abs__(self): 373 return abs(self.__wrapped__) 374 375 def __invert__(self): 376 return ~self.__wrapped__ 377 378 def __int__(self): 379 return int(self.__wrapped__) 380 381 def __long__(self): 382 return long(self.__wrapped__) 383 384 def __float__(self): 385 return float(self.__wrapped__) 386 387 def __complex__(self): 388 return complex(self.__wrapped__) 389 390 def __oct__(self): 391 return oct(self.__wrapped__) 392 393 def __hex__(self): 394 return hex(self.__wrapped__) 395 396 def __index__(self): 397 return operator.index(self.__wrapped__) 398 399 def __len__(self): 400 return len(self.__wrapped__) 401 402 def __contains__(self, value): 403 return value in self.__wrapped__ 404 405 def __getitem__(self, key): 406 return self.__wrapped__[key] 407 408 def __setitem__(self, key, value): 409 self.__wrapped__[key] = value 410 411 def __delitem__(self, key): 412 del self.__wrapped__[key] 413 414 def __getslice__(self, i, j): 415 return self.__wrapped__[i:j] 416 417 def __setslice__(self, i, j, value): 418 self.__wrapped__[i:j] = value 419 420 def __delslice__(self, i, j): 421 del self.__wrapped__[i:j] 422 423 def __enter__(self): 424 return self.__wrapped__.__enter__() 425 426 def __exit__(self, *args, **kwargs): 427 return self.__wrapped__.__exit__(*args, **kwargs) 428 429 def __iter__(self): 430 return iter(self.__wrapped__) 431 432 def __copy__(self): 433 raise NotImplementedError('object proxy must define __copy__()') 434 435 def __deepcopy__(self, memo): 436 raise NotImplementedError('object proxy must define __deepcopy__()') 437 438 def __reduce__(self): 439 raise NotImplementedError( 440 'object proxy must define __reduce_ex__()') 441 442 def __reduce_ex__(self, protocol): 443 raise NotImplementedError( 444 'object proxy must define __reduce_ex__()') 445 446class CallableObjectProxy(ObjectProxy): 447 448 def __call__(self, *args, **kwargs): 449 return self.__wrapped__(*args, **kwargs) 450 451class PartialCallableObjectProxy(ObjectProxy): 452 453 def __init__(self, *args, **kwargs): 454 if len(args) < 1: 455 raise TypeError('partial type takes at least one argument') 456 457 wrapped, args = args[0], args[1:] 458 459 if not callable(wrapped): 460 raise TypeError('the first argument must be callable') 461 462 super(PartialCallableObjectProxy, self).__init__(wrapped) 463 464 self._self_args = args 465 self._self_kwargs = kwargs 466 467 def __call__(self, *args, **kwargs): 468 _args = self._self_args + args 469 470 _kwargs = dict(self._self_kwargs) 471 _kwargs.update(kwargs) 472 473 return self.__wrapped__(*_args, **_kwargs) 474 475class _FunctionWrapperBase(ObjectProxy): 476 477 __slots__ = ('_self_instance', '_self_wrapper', '_self_enabled', 478 '_self_binding', '_self_parent') 479 480 def __init__(self, wrapped, instance, wrapper, enabled=None, 481 binding='function', parent=None): 482 483 super(_FunctionWrapperBase, self).__init__(wrapped) 484 485 object.__setattr__(self, '_self_instance', instance) 486 object.__setattr__(self, '_self_wrapper', wrapper) 487 object.__setattr__(self, '_self_enabled', enabled) 488 object.__setattr__(self, '_self_binding', binding) 489 object.__setattr__(self, '_self_parent', parent) 490 491 def __get__(self, instance, owner): 492 # This method is actually doing double duty for both unbound and 493 # bound derived wrapper classes. It should possibly be broken up 494 # and the distinct functionality moved into the derived classes. 495 # Can't do that straight away due to some legacy code which is 496 # relying on it being here in this base class. 497 # 498 # The distinguishing attribute which determines whether we are 499 # being called in an unbound or bound wrapper is the parent 500 # attribute. If binding has never occurred, then the parent will 501 # be None. 502 # 503 # First therefore, is if we are called in an unbound wrapper. In 504 # this case we perform the binding. 505 # 506 # We have one special case to worry about here. This is where we 507 # are decorating a nested class. In this case the wrapped class 508 # would not have a __get__() method to call. In that case we 509 # simply return self. 510 # 511 # Note that we otherwise still do binding even if instance is 512 # None and accessing an unbound instance method from a class. 513 # This is because we need to be able to later detect that 514 # specific case as we will need to extract the instance from the 515 # first argument of those passed in. 516 517 if self._self_parent is None: 518 if not inspect.isclass(self.__wrapped__): 519 descriptor = self.__wrapped__.__get__(instance, owner) 520 521 return self.__bound_function_wrapper__(descriptor, instance, 522 self._self_wrapper, self._self_enabled, 523 self._self_binding, self) 524 525 return self 526 527 # Now we have the case of binding occurring a second time on what 528 # was already a bound function. In this case we would usually 529 # return ourselves again. This mirrors what Python does. 530 # 531 # The special case this time is where we were originally bound 532 # with an instance of None and we were likely an instance 533 # method. In that case we rebind against the original wrapped 534 # function from the parent again. 535 536 if self._self_instance is None and self._self_binding == 'function': 537 descriptor = self._self_parent.__wrapped__.__get__( 538 instance, owner) 539 540 return self._self_parent.__bound_function_wrapper__( 541 descriptor, instance, self._self_wrapper, 542 self._self_enabled, self._self_binding, 543 self._self_parent) 544 545 return self 546 547 def __call__(self, *args, **kwargs): 548 # If enabled has been specified, then evaluate it at this point 549 # and if the wrapper is not to be executed, then simply return 550 # the bound function rather than a bound wrapper for the bound 551 # function. When evaluating enabled, if it is callable we call 552 # it, otherwise we evaluate it as a boolean. 553 554 if self._self_enabled is not None: 555 if callable(self._self_enabled): 556 if not self._self_enabled(): 557 return self.__wrapped__(*args, **kwargs) 558 elif not self._self_enabled: 559 return self.__wrapped__(*args, **kwargs) 560 561 # This can occur where initial function wrapper was applied to 562 # a function that was already bound to an instance. In that case 563 # we want to extract the instance from the function and use it. 564 565 if self._self_binding in ('function', 'classmethod'): 566 if self._self_instance is None: 567 instance = getattr(self.__wrapped__, '__self__', None) 568 if instance is not None: 569 return self._self_wrapper(self.__wrapped__, instance, 570 args, kwargs) 571 572 # This is generally invoked when the wrapped function is being 573 # called as a normal function and is not bound to a class as an 574 # instance method. This is also invoked in the case where the 575 # wrapped function was a method, but this wrapper was in turn 576 # wrapped using the staticmethod decorator. 577 578 return self._self_wrapper(self.__wrapped__, self._self_instance, 579 args, kwargs) 580 581 def __set_name__(self, owner, name): 582 # This is a special method use to supply information to 583 # descriptors about what the name of variable in a class 584 # definition is. Not wanting to add this to ObjectProxy as not 585 # sure of broader implications of doing that. Thus restrict to 586 # FunctionWrapper used by decorators. 587 588 if hasattr(self.__wrapped__, "__set_name__"): 589 self.__wrapped__.__set_name__(owner, name) 590 591 def __subclasscheck__(self, subclass): 592 # This is a special method used by issubclass() to make checks 593 # about inheritance of classes. We need to upwrap any object 594 # proxy. Not wanting to add this to ObjectProxy as not sure of 595 # broader implications of doing that. Thus restrict to 596 # FunctionWrapper used by decorators. 597 598 if hasattr(subclass, "__wrapped__"): 599 return issubclass(subclass.__wrapped__, self.__wrapped__) 600 else: 601 return issubclass(subclass, self.__wrapped__) 602 603class BoundFunctionWrapper(_FunctionWrapperBase): 604 605 def __call__(self, *args, **kwargs): 606 # If enabled has been specified, then evaluate it at this point 607 # and if the wrapper is not to be executed, then simply return 608 # the bound function rather than a bound wrapper for the bound 609 # function. When evaluating enabled, if it is callable we call 610 # it, otherwise we evaluate it as a boolean. 611 612 if self._self_enabled is not None: 613 if callable(self._self_enabled): 614 if not self._self_enabled(): 615 return self.__wrapped__(*args, **kwargs) 616 elif not self._self_enabled: 617 return self.__wrapped__(*args, **kwargs) 618 619 # We need to do things different depending on whether we are 620 # likely wrapping an instance method vs a static method or class 621 # method. 622 623 if self._self_binding == 'function': 624 if self._self_instance is None: 625 # This situation can occur where someone is calling the 626 # instancemethod via the class type and passing the instance 627 # as the first argument. We need to shift the args before 628 # making the call to the wrapper and effectively bind the 629 # instance to the wrapped function using a partial so the 630 # wrapper doesn't see anything as being different. 631 632 if not args: 633 raise TypeError('missing 1 required positional argument') 634 635 instance, args = args[0], args[1:] 636 wrapped = PartialCallableObjectProxy(self.__wrapped__, instance) 637 return self._self_wrapper(wrapped, instance, args, kwargs) 638 639 return self._self_wrapper(self.__wrapped__, self._self_instance, 640 args, kwargs) 641 642 else: 643 # As in this case we would be dealing with a classmethod or 644 # staticmethod, then _self_instance will only tell us whether 645 # when calling the classmethod or staticmethod they did it via an 646 # instance of the class it is bound to and not the case where 647 # done by the class type itself. We thus ignore _self_instance 648 # and use the __self__ attribute of the bound function instead. 649 # For a classmethod, this means instance will be the class type 650 # and for a staticmethod it will be None. This is probably the 651 # more useful thing we can pass through even though we loose 652 # knowledge of whether they were called on the instance vs the 653 # class type, as it reflects what they have available in the 654 # decoratored function. 655 656 instance = getattr(self.__wrapped__, '__self__', None) 657 658 return self._self_wrapper(self.__wrapped__, instance, args, 659 kwargs) 660 661class FunctionWrapper(_FunctionWrapperBase): 662 663 __bound_function_wrapper__ = BoundFunctionWrapper 664 665 def __init__(self, wrapped, wrapper, enabled=None): 666 # What it is we are wrapping here could be anything. We need to 667 # try and detect specific cases though. In particular, we need 668 # to detect when we are given something that is a method of a 669 # class. Further, we need to know when it is likely an instance 670 # method, as opposed to a class or static method. This can 671 # become problematic though as there isn't strictly a fool proof 672 # method of knowing. 673 # 674 # The situations we could encounter when wrapping a method are: 675 # 676 # 1. The wrapper is being applied as part of a decorator which 677 # is a part of the class definition. In this case what we are 678 # given is the raw unbound function, classmethod or staticmethod 679 # wrapper objects. 680 # 681 # The problem here is that we will not know we are being applied 682 # in the context of the class being set up. This becomes 683 # important later for the case of an instance method, because in 684 # that case we just see it as a raw function and can't 685 # distinguish it from wrapping a normal function outside of 686 # a class context. 687 # 688 # 2. The wrapper is being applied when performing monkey 689 # patching of the class type afterwards and the method to be 690 # wrapped was retrieved direct from the __dict__ of the class 691 # type. This is effectively the same as (1) above. 692 # 693 # 3. The wrapper is being applied when performing monkey 694 # patching of the class type afterwards and the method to be 695 # wrapped was retrieved from the class type. In this case 696 # binding will have been performed where the instance against 697 # which the method is bound will be None at that point. 698 # 699 # This case is a problem because we can no longer tell if the 700 # method was a static method, plus if using Python3, we cannot 701 # tell if it was an instance method as the concept of an 702 # unnbound method no longer exists. 703 # 704 # 4. The wrapper is being applied when performing monkey 705 # patching of an instance of a class. In this case binding will 706 # have been perfomed where the instance was not None. 707 # 708 # This case is a problem because we can no longer tell if the 709 # method was a static method. 710 # 711 # Overall, the best we can do is look at the original type of the 712 # object which was wrapped prior to any binding being done and 713 # see if it is an instance of classmethod or staticmethod. In 714 # the case where other decorators are between us and them, if 715 # they do not propagate the __class__ attribute so that the 716 # isinstance() checks works, then likely this will do the wrong 717 # thing where classmethod and staticmethod are used. 718 # 719 # Since it is likely to be very rare that anyone even puts 720 # decorators around classmethod and staticmethod, likelihood of 721 # that being an issue is very small, so we accept it and suggest 722 # that those other decorators be fixed. It is also only an issue 723 # if a decorator wants to actually do things with the arguments. 724 # 725 # As to not being able to identify static methods properly, we 726 # just hope that that isn't something people are going to want 727 # to wrap, or if they do suggest they do it the correct way by 728 # ensuring that it is decorated in the class definition itself, 729 # or patch it in the __dict__ of the class type. 730 # 731 # So to get the best outcome we can, whenever we aren't sure what 732 # it is, we label it as a 'function'. If it was already bound and 733 # that is rebound later, we assume that it will be an instance 734 # method and try an cope with the possibility that the 'self' 735 # argument it being passed as an explicit argument and shuffle 736 # the arguments around to extract 'self' for use as the instance. 737 738 if isinstance(wrapped, classmethod): 739 binding = 'classmethod' 740 741 elif isinstance(wrapped, staticmethod): 742 binding = 'staticmethod' 743 744 elif hasattr(wrapped, '__self__'): 745 if inspect.isclass(wrapped.__self__): 746 binding = 'classmethod' 747 else: 748 binding = 'function' 749 750 else: 751 binding = 'function' 752 753 super(FunctionWrapper, self).__init__(wrapped, None, wrapper, 754 enabled, binding) 755 756try: 757 if not os.environ.get('WRAPT_DISABLE_EXTENSIONS'): 758 from ._wrappers import (ObjectProxy, CallableObjectProxy, 759 PartialCallableObjectProxy, FunctionWrapper, 760 BoundFunctionWrapper, _FunctionWrapperBase) 761except ImportError: 762 pass 763 764# Helper functions for applying wrappers to existing functions. 765 766def resolve_path(module, name): 767 if isinstance(module, string_types): 768 __import__(module) 769 module = sys.modules[module] 770 771 parent = module 772 773 path = name.split('.') 774 attribute = path[0] 775 776 # We can't just always use getattr() because in doing 777 # that on a class it will cause binding to occur which 778 # will complicate things later and cause some things not 779 # to work. For the case of a class we therefore access 780 # the __dict__ directly. To cope though with the wrong 781 # class being given to us, or a method being moved into 782 # a base class, we need to walk the class hierarchy to 783 # work out exactly which __dict__ the method was defined 784 # in, as accessing it from __dict__ will fail if it was 785 # not actually on the class given. Fallback to using 786 # getattr() if we can't find it. If it truly doesn't 787 # exist, then that will fail. 788 789 def lookup_attribute(parent, attribute): 790 if inspect.isclass(parent): 791 for cls in inspect.getmro(parent): 792 if attribute in vars(cls): 793 return vars(cls)[attribute] 794 else: 795 return getattr(parent, attribute) 796 else: 797 return getattr(parent, attribute) 798 799 original = lookup_attribute(parent, attribute) 800 801 for attribute in path[1:]: 802 parent = original 803 original = lookup_attribute(parent, attribute) 804 805 return (parent, attribute, original) 806 807def apply_patch(parent, attribute, replacement): 808 setattr(parent, attribute, replacement) 809 810def wrap_object(module, name, factory, args=(), kwargs={}): 811 (parent, attribute, original) = resolve_path(module, name) 812 wrapper = factory(original, *args, **kwargs) 813 apply_patch(parent, attribute, wrapper) 814 return wrapper 815 816# Function for applying a proxy object to an attribute of a class 817# instance. The wrapper works by defining an attribute of the same name 818# on the class which is a descriptor and which intercepts access to the 819# instance attribute. Note that this cannot be used on attributes which 820# are themselves defined by a property object. 821 822class AttributeWrapper(object): 823 824 def __init__(self, attribute, factory, args, kwargs): 825 self.attribute = attribute 826 self.factory = factory 827 self.args = args 828 self.kwargs = kwargs 829 830 def __get__(self, instance, owner): 831 value = instance.__dict__[self.attribute] 832 return self.factory(value, *self.args, **self.kwargs) 833 834 def __set__(self, instance, value): 835 instance.__dict__[self.attribute] = value 836 837 def __delete__(self, instance): 838 del instance.__dict__[self.attribute] 839 840def wrap_object_attribute(module, name, factory, args=(), kwargs={}): 841 path, attribute = name.rsplit('.', 1) 842 parent = resolve_path(module, path)[2] 843 wrapper = AttributeWrapper(attribute, factory, args, kwargs) 844 apply_patch(parent, attribute, wrapper) 845 return wrapper 846 847# Functions for creating a simple decorator using a FunctionWrapper, 848# plus short cut functions for applying wrappers to functions. These are 849# for use when doing monkey patching. For a more featured way of 850# creating decorators see the decorator decorator instead. 851 852def function_wrapper(wrapper): 853 def _wrapper(wrapped, instance, args, kwargs): 854 target_wrapped = args[0] 855 if instance is None: 856 target_wrapper = wrapper 857 elif inspect.isclass(instance): 858 target_wrapper = wrapper.__get__(None, instance) 859 else: 860 target_wrapper = wrapper.__get__(instance, type(instance)) 861 return FunctionWrapper(target_wrapped, target_wrapper) 862 return FunctionWrapper(wrapper, _wrapper) 863 864def wrap_function_wrapper(module, name, wrapper): 865 return wrap_object(module, name, FunctionWrapper, (wrapper,)) 866 867def patch_function_wrapper(module, name): 868 def _wrapper(wrapper): 869 return wrap_object(module, name, FunctionWrapper, (wrapper,)) 870 return _wrapper 871 872def transient_function_wrapper(module, name): 873 def _decorator(wrapper): 874 def _wrapper(wrapped, instance, args, kwargs): 875 target_wrapped = args[0] 876 if instance is None: 877 target_wrapper = wrapper 878 elif inspect.isclass(instance): 879 target_wrapper = wrapper.__get__(None, instance) 880 else: 881 target_wrapper = wrapper.__get__(instance, type(instance)) 882 def _execute(wrapped, instance, args, kwargs): 883 (parent, attribute, original) = resolve_path(module, name) 884 replacement = FunctionWrapper(original, target_wrapper) 885 setattr(parent, attribute, replacement) 886 try: 887 return wrapped(*args, **kwargs) 888 finally: 889 setattr(parent, attribute, original) 890 return FunctionWrapper(target_wrapped, _execute) 891 return FunctionWrapper(wrapper, _wrapper) 892 return _decorator 893 894# A weak function proxy. This will work on instance methods, class 895# methods, static methods and regular functions. Special treatment is 896# needed for the method types because the bound method is effectively a 897# transient object and applying a weak reference to one will immediately 898# result in it being destroyed and the weakref callback called. The weak 899# reference is therefore applied to the instance the method is bound to 900# and the original function. The function is then rebound at the point 901# of a call via the weak function proxy. 902 903def _weak_function_proxy_callback(ref, proxy, callback): 904 if proxy._self_expired: 905 return 906 907 proxy._self_expired = True 908 909 # This could raise an exception. We let it propagate back and let 910 # the weakref.proxy() deal with it, at which point it generally 911 # prints out a short error message direct to stderr and keeps going. 912 913 if callback is not None: 914 callback(proxy) 915 916class WeakFunctionProxy(ObjectProxy): 917 918 __slots__ = ('_self_expired', '_self_instance') 919 920 def __init__(self, wrapped, callback=None): 921 # We need to determine if the wrapped function is actually a 922 # bound method. In the case of a bound method, we need to keep a 923 # reference to the original unbound function and the instance. 924 # This is necessary because if we hold a reference to the bound 925 # function, it will be the only reference and given it is a 926 # temporary object, it will almost immediately expire and 927 # the weakref callback triggered. So what is done is that we 928 # hold a reference to the instance and unbound function and 929 # when called bind the function to the instance once again and 930 # then call it. Note that we avoid using a nested function for 931 # the callback here so as not to cause any odd reference cycles. 932 933 _callback = callback and functools.partial( 934 _weak_function_proxy_callback, proxy=self, 935 callback=callback) 936 937 self._self_expired = False 938 939 if isinstance(wrapped, _FunctionWrapperBase): 940 self._self_instance = weakref.ref(wrapped._self_instance, 941 _callback) 942 943 if wrapped._self_parent is not None: 944 super(WeakFunctionProxy, self).__init__( 945 weakref.proxy(wrapped._self_parent, _callback)) 946 947 else: 948 super(WeakFunctionProxy, self).__init__( 949 weakref.proxy(wrapped, _callback)) 950 951 return 952 953 try: 954 self._self_instance = weakref.ref(wrapped.__self__, _callback) 955 956 super(WeakFunctionProxy, self).__init__( 957 weakref.proxy(wrapped.__func__, _callback)) 958 959 except AttributeError: 960 self._self_instance = None 961 962 super(WeakFunctionProxy, self).__init__( 963 weakref.proxy(wrapped, _callback)) 964 965 def __call__(self, *args, **kwargs): 966 # We perform a boolean check here on the instance and wrapped 967 # function as that will trigger the reference error prior to 968 # calling if the reference had expired. 969 970 instance = self._self_instance and self._self_instance() 971 function = self.__wrapped__ and self.__wrapped__ 972 973 # If the wrapped function was originally a bound function, for 974 # which we retained a reference to the instance and the unbound 975 # function we need to rebind the function and then call it. If 976 # not just called the wrapped function. 977 978 if instance is None: 979 return self.__wrapped__(*args, **kwargs) 980 981 return function.__get__(instance, type(instance))(*args, **kwargs) 982