Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/wrapt/wrappers.py: 31%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

611 statements  

1"""Core object proxy and function wrapper implementations.""" 

2 

3import functools 

4import inspect 

5import math 

6import operator 

7import sys 

8import types 

9 

10from .exceptions import WrapperNotInitializedError 

11 

12 

13class _ObjectProxyMethods: 

14 

15 # We use properties to override the values of __module__ and 

16 # __doc__. If we add these in ObjectProxy, the derived class 

17 # __dict__ will still be setup to have string variants of these 

18 # attributes and the rules of descriptors means that they appear to 

19 # take precedence over the properties in the base class. To avoid 

20 # that, we copy the properties into the derived class type itself 

21 # via a meta class. In that way the properties will always take 

22 # precedence. 

23 # 

24 # Note that because these properties end up in the class __dict__, 

25 # type-level access (e.g. ObjectProxy.__module__) would return the 

26 # property object rather than a string, since CPython's 

27 # type.__module__ getter does a raw dict lookup without invoking the 

28 # descriptor protocol. The metaclass has its own __module__ and 

29 # __doc__ properties to handle type-level access correctly. 

30 

31 @property 

32 def __module__(self): 

33 return self.__wrapped__.__module__ 

34 

35 @__module__.setter 

36 def __module__(self, value): 

37 self.__wrapped__.__module__ = value 

38 

39 @__module__.deleter 

40 def __module__(self): 

41 del self.__wrapped__.__module__ 

42 

43 @property 

44 def __doc__(self): 

45 return self.__wrapped__.__doc__ 

46 

47 @__doc__.setter 

48 def __doc__(self, value): 

49 self.__wrapped__.__doc__ = value 

50 

51 @__doc__.deleter 

52 def __doc__(self): 

53 del self.__wrapped__.__doc__ 

54 

55 # We similar use a property for __dict__. We need __dict__ to be 

56 # explicit to ensure that vars() works as expected. 

57 

58 @property 

59 def __dict__(self): 

60 return self.__wrapped__.__dict__ 

61 

62 # Need to also propagate the special __weakref__ attribute for case 

63 # where decorating classes which will define this. If do not define 

64 # it and use a function like inspect.getmembers() on a decorator 

65 # class it will fail. This can't be in the derived classes. 

66 

67 @property 

68 def __weakref__(self): 

69 return self.__wrapped__.__weakref__ 

70 

71 

72class _ObjectProxyDictBase: 

73 """Base class whose sole purpose is to provide a ``getset_descriptor`` 

74 for ``__dict__`` that is valid for all ``ObjectProxy`` subclasses. 

75 The metaclass installs this descriptor as ``__self_dict__`` so that 

76 the real instance dictionary of the proxy can always be accessed, 

77 even though ``ObjectProxy`` replaces ``__dict__`` with a property 

78 that delegates to the wrapped object.""" 

79 

80 pass 

81 

82 

83_REAL_DICT_DESCRIPTOR = type.__dict__["__dict__"].__get__(_ObjectProxyDictBase)[ 

84 "__dict__" 

85] 

86 

87 

88def _get_self_dict(self): 

89 return _REAL_DICT_DESCRIPTOR.__get__(self) 

90 

91 

92# Wrapping the descriptor in a read-only property ensures that 

93# ``proxy.__self_dict__ = value`` raises AttributeError rather than 

94# replacing the real instance dictionary (which would break the proxy). 

95 

96_SELF_DICT_PROPERTY = property(_get_self_dict) 

97 

98# The default __doc__ property which delegates to the wrapped object. A 

99# derived class may define its own __doc__ descriptor in its class body 

100# to take control of what __doc__ reports for its instances, and that is 

101# preserved by the metaclass in place of this default. 

102 

103_DEFAULT_DOC_PROPERTY = vars(_ObjectProxyMethods)["__doc__"] 

104 

105 

106def _is_doc_descriptor(entry): 

107 # Every class carries a __doc__ entry in its dict, being the docstring 

108 # or None when there is none. Only a descriptor is taken to be a 

109 # deliberate override of the instance level __doc__ property. 

110 

111 if entry is None or isinstance(entry, str): 

112 return False 

113 return hasattr(type(entry), "__get__") 

114 

115 

116def _inherited_doc_descriptor(bases): 

117 # Find a custom __doc__ descriptor inherited from a base class. The 

118 # search stops at the first class which holds the default delegating 

119 # property, since a derived class of that should delegate as well. The 

120 # C extension performs the equivalent walk of the MRO at the time 

121 # __doc__ is accessed. 

122 

123 for base in bases: 

124 for klass in base.__mro__: 

125 entry = vars(klass).get("__doc__") 

126 if entry is _DEFAULT_DOC_PROPERTY: 

127 return None 

128 if _is_doc_descriptor(entry): 

129 return entry 

130 return None 

131 

132 

133class _ObjectProxyMetaType(type): 

134 # Properties on the metaclass control type-level access to __module__ 

135 # and __doc__ (e.g. ObjectProxy.__module__). Without these, the 

136 # instance-level properties copied from _ObjectProxyMethods into each 

137 # class dict would shadow the string values that type.__new__ sets, 

138 # causing type.__module__ to return a property object instead of a 

139 # string. The metaclass properties read from internal keys where the 

140 # real values are saved. 

141 

142 @property 

143 def __module__(cls): 

144 return cls.__dict__.get("_cls_real_module", "builtins") 

145 

146 @__module__.setter 

147 def __module__(cls, value): 

148 type.__setattr__(cls, "_cls_real_module", value) 

149 

150 @property 

151 def __doc__(cls): 

152 return cls.__dict__.get("_cls_real_doc") 

153 

154 @__doc__.setter 

155 def __doc__(cls, value): 

156 type.__setattr__(cls, "_cls_real_doc", value) 

157 

158 def __new__(cls, name, bases, dictionary): 

159 # Copy our special properties into the class so that they 

160 # always take precedence over attributes of the same name added 

161 # during construction of a derived class. This is to save 

162 # duplicating the implementation for them in all derived classes. 

163 # 

164 # Because this overwrites the __module__ and __doc__ strings 

165 # that would normally be in the class dict with property objects, 

166 # we save the original values first and store them under internal 

167 # keys. The metaclass properties above read from these keys to 

168 # ensure type-level access (e.g. MyProxy.__module__) returns a 

169 # string rather than a property object. 

170 

171 real_module = dictionary.get("__module__") 

172 real_doc = dictionary.get("__doc__") 

173 

174 # If the subclass defines its own __dict__ property, preserve it 

175 # rather than overwriting it with the default delegating property 

176 # from _ObjectProxyMethods. When __dict__ is not explicitly 

177 # defined in the class body, it will not be present in the 

178 # dictionary at this point. 

179 

180 custom_dict = dictionary.get("__dict__") 

181 

182 # Similarly, if the subclass defines __doc__ as a descriptor rather 

183 # than as a docstring, preserve it so the subclass controls what 

184 # __doc__ reports for its instances. Such a descriptor is not the 

185 # class docstring, so it is not recorded as one. A descriptor 

186 # defined by a base class is inherited, as it would be for any 

187 # class not using this metaclass, by copying it into the class 

188 # dictionary where it takes precedence over the None or docstring 

189 # entry the class body provides. 

190 

191 if _is_doc_descriptor(real_doc): 

192 custom_doc = real_doc 

193 real_doc = None 

194 else: 

195 custom_doc = _inherited_doc_descriptor(bases) 

196 

197 dictionary.update(vars(_ObjectProxyMethods)) 

198 

199 if custom_dict is not None: 

200 dictionary["__dict__"] = custom_dict 

201 

202 if custom_doc is not None: 

203 dictionary["__doc__"] = custom_doc 

204 

205 dictionary.setdefault("__self_dict__", _SELF_DICT_PROPERTY) 

206 

207 klass = type.__new__(cls, name, bases, dictionary) 

208 

209 if real_module is not None: 

210 type.__setattr__(klass, "_cls_real_module", real_module) 

211 if real_doc is not None: 

212 type.__setattr__(klass, "_cls_real_doc", real_doc) 

213 

214 return klass 

215 

216 

217def _unwrap_operand(other): 

218 # When the other operand of a binary operator is itself a proxy, apply 

219 # the operator to the two wrapped objects rather than passing the proxy 

220 # through to the wrapped object's own operator method. This mirrors 

221 # wrapt_unwrap_operand() in the C extension. Without it, a wrapped 

222 # type which raises TypeError for an unrecognised operand, rather 

223 # than returning NotImplemented, would never give the proxy on the 

224 # right hand side the chance to unwrap itself via the reflected 

225 # method, and Python would not see the real types of the operands 

226 # when deciding whether the reflected method of a subclass on the 

227 # right hand side takes priority. The real type is checked, and not 

228 # __class__, which the proxy reports as that of the wrapped object. 

229 

230 if issubclass(type(other), ObjectProxy): 

231 return other.__wrapped__ 

232 return other 

233 

234 

235class ObjectProxy(_ObjectProxyDictBase, metaclass=_ObjectProxyMetaType): 

236 """A transparent object proxy that delegates attribute access to a 

237 wrapped object.""" 

238 

239 @classmethod 

240 def __class_getitem__(cls, item, /): 

241 return types.GenericAlias(cls, item) 

242 

243 def __new__(cls, *args, **kwargs): 

244 # Accept and ignore any arguments. A derived class which adds 

245 # arguments to __init__() has the same arguments passed to 

246 # __new__(), and a derived class which overrides __new__() may 

247 # pass through whatever it was given, as it must when deriving 

248 # from AutoObjectProxy which needs the wrapped object in __new__(). 

249 # Without this, once __new__() is overridden anywhere in the class 

250 # hierarchy, the call falls through to object.__new__() which 

251 # rejects extra arguments. The C extension already ignores the 

252 # arguments in its tp_new slot, so this keeps the two consistent. 

253 

254 return super().__new__(cls) 

255 

256 def __init__(self, wrapped): 

257 """Create an object proxy around the given object.""" 

258 

259 if wrapped is None: 

260 try: 

261 callback = object.__getattribute__(self, "__wrapped_factory__") 

262 except AttributeError: 

263 callback = None 

264 

265 if callback is not None: 

266 # If wrapped is none and class has a __wrapped_factory__ 

267 # method, then we don't set __wrapped__ yet and instead will 

268 # defer creation of the wrapped object until it is first 

269 # needed. 

270 

271 pass 

272 

273 else: 

274 object.__setattr__(self, "__wrapped__", wrapped) 

275 else: 

276 object.__setattr__(self, "__wrapped__", wrapped) 

277 

278 object.__setattr__(self, "__init_called__", True) 

279 

280 # Python 3.2+ has the __qualname__ attribute, but it does not 

281 # allow it to be overridden using a property and it must instead 

282 # be an actual string object instead. 

283 

284 try: 

285 object.__setattr__(self, "__qualname__", wrapped.__qualname__) 

286 except AttributeError: 

287 pass 

288 

289 # Python 3.10 onwards also does not allow itself to be overridden 

290 # using a property and it must instead be set explicitly. Python 

291 # 3.14 onwards uses deferred evaluation of annotations via the 

292 # __annotate__ attribute, so we copy that instead to avoid 

293 # triggering eager evaluation which can fail if names referenced 

294 # in annotations have been shadowed. 

295 

296 if sys.version_info >= (3, 14): 

297 try: 

298 object.__setattr__(self, "__annotate__", wrapped.__annotate__) 

299 except AttributeError: 

300 pass 

301 else: 

302 try: 

303 object.__setattr__(self, "__annotations__", wrapped.__annotations__) 

304 except AttributeError: 

305 pass 

306 

307 @property 

308 def __object_proxy__(self): 

309 return ObjectProxy 

310 

311 def __self_setattr__(self, name, value): 

312 object.__setattr__(self, name, value) 

313 

314 @property 

315 def __name__(self): 

316 return self.__wrapped__.__name__ 

317 

318 @__name__.setter 

319 def __name__(self, value): 

320 self.__wrapped__.__name__ = value 

321 

322 @property 

323 def __class__(self): 

324 return self.__wrapped__.__class__ 

325 

326 @__class__.setter 

327 def __class__(self, value): 

328 self.__wrapped__.__class__ = value 

329 

330 def __dir__(self): 

331 return dir(self.__wrapped__) 

332 

333 def __str__(self): 

334 return str(self.__wrapped__) 

335 

336 def __bytes__(self): 

337 return bytes(self.__wrapped__) 

338 

339 def __repr__(self): 

340 return f"<{type(self).__name__} at 0x{id(self):x} for {type(self.__wrapped__).__name__} at 0x{id(self.__wrapped__):x}>" 

341 

342 def __format__(self, format_spec): 

343 return format(self.__wrapped__, format_spec) 

344 

345 def __reversed__(self): 

346 return reversed(self.__wrapped__) 

347 

348 def __round__(self, ndigits=None): 

349 return round(self.__wrapped__, ndigits) 

350 

351 def __trunc__(self): 

352 return math.trunc(self.__wrapped__) 

353 

354 def __floor__(self): 

355 return math.floor(self.__wrapped__) 

356 

357 def __ceil__(self): 

358 return math.ceil(self.__wrapped__) 

359 

360 def __mro_entries__(self, bases): 

361 if not isinstance(self.__wrapped__, type) and hasattr( 

362 self.__wrapped__, "__mro_entries__" 

363 ): 

364 return self.__wrapped__.__mro_entries__(bases) 

365 return (self.__wrapped__,) 

366 

367 def __lt__(self, other): 

368 return self.__wrapped__ < other 

369 

370 def __le__(self, other): 

371 return self.__wrapped__ <= other 

372 

373 def __eq__(self, other): 

374 return self.__wrapped__ == other 

375 

376 def __ne__(self, other): 

377 return self.__wrapped__ != other 

378 

379 def __gt__(self, other): 

380 return self.__wrapped__ > other 

381 

382 def __ge__(self, other): 

383 return self.__wrapped__ >= other 

384 

385 def __hash__(self): 

386 return hash(self.__wrapped__) 

387 

388 def __bool__(self): 

389 return bool(self.__wrapped__) 

390 

391 def __setattr__(self, name, value): 

392 if name.startswith("_self_"): 

393 object.__setattr__(self, name, value) 

394 

395 elif name == "__wrapped__": 

396 object.__setattr__(self, name, value) 

397 

398 try: 

399 object.__delattr__(self, "__qualname__") 

400 except AttributeError: 

401 pass 

402 try: 

403 object.__setattr__(self, "__qualname__", value.__qualname__) 

404 except AttributeError: 

405 pass 

406 if sys.version_info >= (3, 14): 

407 try: 

408 object.__delattr__(self, "__annotate__") 

409 except AttributeError: 

410 pass 

411 try: 

412 object.__setattr__(self, "__annotate__", value.__annotate__) 

413 except AttributeError: 

414 pass 

415 else: 

416 try: 

417 object.__delattr__(self, "__annotations__") 

418 except AttributeError: 

419 pass 

420 try: 

421 object.__setattr__(self, "__annotations__", value.__annotations__) 

422 except AttributeError: 

423 pass 

424 

425 __wrapped_setattr_fixups__ = getattr( 

426 self, "__wrapped_setattr_fixups__", None 

427 ) 

428 

429 if __wrapped_setattr_fixups__ is not None: 

430 __wrapped_setattr_fixups__() 

431 

432 elif name == "__qualname__": 

433 setattr(self.__wrapped__, name, value) 

434 object.__setattr__(self, name, value) 

435 

436 elif name == "__annotations__": 

437 setattr(self.__wrapped__, name, value) 

438 object.__setattr__(self, name, value) 

439 

440 elif name == "__annotate__": 

441 setattr(self.__wrapped__, name, value) 

442 object.__setattr__(self, name, value) 

443 

444 elif hasattr(type(self), name): 

445 object.__setattr__(self, name, value) 

446 

447 else: 

448 setattr(self.__wrapped__, name, value) 

449 

450 def __getattr__(self, name): 

451 # If we need to lookup `__wrapped__` then the `__init__()` method 

452 # cannot have been called, or this is a lazy object proxy which is 

453 # deferring creation of the wrapped object until it is first needed. 

454 

455 if name == "__wrapped__": 

456 # Note that we use existance of `__wrapped_factory__` to gate whether 

457 # we can attempt to initialize the wrapped object lazily, but it is 

458 # `__wrapped_get__` that we actually call to do the initialization. 

459 # This is so that we can handle multithreading correctly by having 

460 # `__wrapped_get__` use a lock to protect against multiple threads 

461 # trying to initialize the wrapped object at the same time. 

462 

463 try: 

464 object.__getattribute__(self, "__wrapped_factory__") 

465 except AttributeError: 

466 pass 

467 else: 

468 return object.__getattribute__(self, "__wrapped_get__")() 

469 

470 # If __init__ was called but __wrapped__ is not set, the wrapper 

471 # is in an inconsistent state. Raise WrapperNotInitializedError 

472 # (a ValueError, not AttributeError) so it is not silently 

473 # swallowed by hasattr/getattr patterns. 

474 

475 try: 

476 object.__getattribute__(self, "__init_called__") 

477 except AttributeError: 

478 raise AttributeError( 

479 f"'{type(self).__name__}' object has no attribute " f"'__wrapped__'" 

480 ) 

481 

482 raise WrapperNotInitializedError( 

483 "wrapper is in an inconsistent state: __wrapped__ is not set" 

484 ) 

485 

486 return getattr(self.__wrapped__, name) 

487 

488 def __delattr__(self, name): 

489 if name.startswith("_self_"): 

490 object.__delattr__(self, name) 

491 

492 elif name == "__wrapped__": 

493 raise TypeError("can't delete __wrapped__ attribute") 

494 

495 elif name == "__qualname__": 

496 object.__delattr__(self, name) 

497 delattr(self.__wrapped__, name) 

498 

499 elif name == "__annotations__": 

500 try: 

501 object.__delattr__(self, name) 

502 except AttributeError: 

503 pass 

504 delattr(self.__wrapped__, name) 

505 

506 elif name == "__annotate__": 

507 try: 

508 object.__delattr__(self, name) 

509 except AttributeError: 

510 pass 

511 delattr(self.__wrapped__, name) 

512 

513 elif hasattr(type(self), name): 

514 object.__delattr__(self, name) 

515 

516 else: 

517 delattr(self.__wrapped__, name) 

518 

519 def __add__(self, other): 

520 other = _unwrap_operand(other) 

521 return self.__wrapped__ + other 

522 

523 def __sub__(self, other): 

524 other = _unwrap_operand(other) 

525 return self.__wrapped__ - other 

526 

527 def __mul__(self, other): 

528 other = _unwrap_operand(other) 

529 return self.__wrapped__ * other 

530 

531 def __truediv__(self, other): 

532 other = _unwrap_operand(other) 

533 return operator.truediv(self.__wrapped__, other) 

534 

535 def __floordiv__(self, other): 

536 other = _unwrap_operand(other) 

537 return self.__wrapped__ // other 

538 

539 def __mod__(self, other): 

540 other = _unwrap_operand(other) 

541 return self.__wrapped__ % other 

542 

543 def __divmod__(self, other): 

544 other = _unwrap_operand(other) 

545 return divmod(self.__wrapped__, other) 

546 

547 def __pow__(self, other, *args): 

548 other = _unwrap_operand(other) 

549 return pow(self.__wrapped__, other, *args) 

550 

551 def __lshift__(self, other): 

552 other = _unwrap_operand(other) 

553 return self.__wrapped__ << other 

554 

555 def __rshift__(self, other): 

556 other = _unwrap_operand(other) 

557 return self.__wrapped__ >> other 

558 

559 def __and__(self, other): 

560 other = _unwrap_operand(other) 

561 return self.__wrapped__ & other 

562 

563 def __xor__(self, other): 

564 other = _unwrap_operand(other) 

565 return self.__wrapped__ ^ other 

566 

567 def __or__(self, other): 

568 other = _unwrap_operand(other) 

569 return self.__wrapped__ | other 

570 

571 def __radd__(self, other): 

572 other = _unwrap_operand(other) 

573 return other + self.__wrapped__ 

574 

575 def __rsub__(self, other): 

576 other = _unwrap_operand(other) 

577 return other - self.__wrapped__ 

578 

579 def __rmul__(self, other): 

580 other = _unwrap_operand(other) 

581 return other * self.__wrapped__ 

582 

583 def __rtruediv__(self, other): 

584 other = _unwrap_operand(other) 

585 return operator.truediv(other, self.__wrapped__) 

586 

587 def __rfloordiv__(self, other): 

588 other = _unwrap_operand(other) 

589 return other // self.__wrapped__ 

590 

591 def __rmod__(self, other): 

592 other = _unwrap_operand(other) 

593 return other % self.__wrapped__ 

594 

595 def __rdivmod__(self, other): 

596 other = _unwrap_operand(other) 

597 return divmod(other, self.__wrapped__) 

598 

599 def __rpow__(self, other, *args): 

600 other = _unwrap_operand(other) 

601 return pow(other, self.__wrapped__, *args) 

602 

603 def __rlshift__(self, other): 

604 other = _unwrap_operand(other) 

605 return other << self.__wrapped__ 

606 

607 def __rrshift__(self, other): 

608 other = _unwrap_operand(other) 

609 return other >> self.__wrapped__ 

610 

611 def __rand__(self, other): 

612 other = _unwrap_operand(other) 

613 return other & self.__wrapped__ 

614 

615 def __rxor__(self, other): 

616 other = _unwrap_operand(other) 

617 return other ^ self.__wrapped__ 

618 

619 def __ror__(self, other): 

620 other = _unwrap_operand(other) 

621 return other | self.__wrapped__ 

622 

623 def __iadd__(self, other): 

624 other = _unwrap_operand(other) 

625 if hasattr(self.__wrapped__, "__iadd__"): 

626 self.__wrapped__ += other 

627 return self 

628 else: 

629 return self.__object_proxy__(self.__wrapped__ + other) 

630 

631 def __isub__(self, other): 

632 other = _unwrap_operand(other) 

633 if hasattr(self.__wrapped__, "__isub__"): 

634 self.__wrapped__ -= other 

635 return self 

636 else: 

637 return self.__object_proxy__(self.__wrapped__ - other) 

638 

639 def __imul__(self, other): 

640 other = _unwrap_operand(other) 

641 if hasattr(self.__wrapped__, "__imul__"): 

642 self.__wrapped__ *= other 

643 return self 

644 else: 

645 return self.__object_proxy__(self.__wrapped__ * other) 

646 

647 def __itruediv__(self, other): 

648 other = _unwrap_operand(other) 

649 if hasattr(self.__wrapped__, "__itruediv__"): 

650 self.__wrapped__ /= other 

651 return self 

652 else: 

653 return self.__object_proxy__(self.__wrapped__ / other) 

654 

655 def __ifloordiv__(self, other): 

656 other = _unwrap_operand(other) 

657 if hasattr(self.__wrapped__, "__ifloordiv__"): 

658 self.__wrapped__ //= other 

659 return self 

660 else: 

661 return self.__object_proxy__(self.__wrapped__ // other) 

662 

663 def __imod__(self, other): 

664 other = _unwrap_operand(other) 

665 if hasattr(self.__wrapped__, "__imod__"): 

666 self.__wrapped__ %= other 

667 return self 

668 else: 

669 return self.__object_proxy__(self.__wrapped__ % other) 

670 

671 def __ipow__(self, other): # type: ignore[misc] 

672 other = _unwrap_operand(other) 

673 if hasattr(self.__wrapped__, "__ipow__"): 

674 self.__wrapped__ **= other 

675 return self 

676 else: 

677 return self.__object_proxy__(self.__wrapped__**other) 

678 

679 def __ilshift__(self, other): 

680 other = _unwrap_operand(other) 

681 if hasattr(self.__wrapped__, "__ilshift__"): 

682 self.__wrapped__ <<= other 

683 return self 

684 else: 

685 return self.__object_proxy__(self.__wrapped__ << other) 

686 

687 def __irshift__(self, other): 

688 other = _unwrap_operand(other) 

689 if hasattr(self.__wrapped__, "__irshift__"): 

690 self.__wrapped__ >>= other 

691 return self 

692 else: 

693 return self.__object_proxy__(self.__wrapped__ >> other) 

694 

695 def __iand__(self, other): 

696 other = _unwrap_operand(other) 

697 if hasattr(self.__wrapped__, "__iand__"): 

698 self.__wrapped__ &= other 

699 return self 

700 else: 

701 return self.__object_proxy__(self.__wrapped__ & other) 

702 

703 def __ixor__(self, other): 

704 other = _unwrap_operand(other) 

705 if hasattr(self.__wrapped__, "__ixor__"): 

706 self.__wrapped__ ^= other 

707 return self 

708 else: 

709 return self.__object_proxy__(self.__wrapped__ ^ other) 

710 

711 def __ior__(self, other): 

712 other = _unwrap_operand(other) 

713 if hasattr(self.__wrapped__, "__ior__"): 

714 self.__wrapped__ |= other 

715 return self 

716 else: 

717 return self.__object_proxy__(self.__wrapped__ | other) 

718 

719 def __neg__(self): 

720 return -self.__wrapped__ 

721 

722 def __pos__(self): 

723 return +self.__wrapped__ 

724 

725 def __abs__(self): 

726 return abs(self.__wrapped__) 

727 

728 def __invert__(self): 

729 return ~self.__wrapped__ 

730 

731 def __int__(self): 

732 return int(self.__wrapped__) 

733 

734 def __float__(self): 

735 return float(self.__wrapped__) 

736 

737 def __complex__(self): 

738 return complex(self.__wrapped__) 

739 

740 def __index__(self): 

741 return operator.index(self.__wrapped__) 

742 

743 def __matmul__(self, other): 

744 other = _unwrap_operand(other) 

745 return self.__wrapped__ @ other 

746 

747 def __rmatmul__(self, other): 

748 other = _unwrap_operand(other) 

749 return other @ self.__wrapped__ 

750 

751 def __imatmul__(self, other): 

752 other = _unwrap_operand(other) 

753 if hasattr(self.__wrapped__, "__imatmul__"): 

754 self.__wrapped__ @= other 

755 return self 

756 else: 

757 return self.__object_proxy__(self.__wrapped__ @ other) 

758 

759 def __len__(self): 

760 return len(self.__wrapped__) 

761 

762 def __contains__(self, value): 

763 return value in self.__wrapped__ 

764 

765 def __getitem__(self, key): 

766 return self.__wrapped__[key] 

767 

768 def __setitem__(self, key, value): 

769 self.__wrapped__[key] = value 

770 

771 def __delitem__(self, key): 

772 del self.__wrapped__[key] 

773 

774 def __enter__(self): 

775 return self.__wrapped__.__enter__() 

776 

777 def __exit__(self, *args, **kwargs): 

778 return self.__wrapped__.__exit__(*args, **kwargs) 

779 

780 def __aenter__(self): 

781 return self.__wrapped__.__aenter__() 

782 

783 def __aexit__(self, *args, **kwargs): 

784 return self.__wrapped__.__aexit__(*args, **kwargs) 

785 

786 def __copy__(self): 

787 raise NotImplementedError("object proxy must define __copy__()") 

788 

789 def __deepcopy__(self, memo): 

790 raise NotImplementedError("object proxy must define __deepcopy__()") 

791 

792 def __reduce__(self): 

793 raise NotImplementedError("object proxy must define __reduce__()") 

794 

795 def __instancecheck__(self, instance): 

796 return isinstance(instance, self.__wrapped__) 

797 

798 def __subclasscheck__(self, subclass): 

799 if hasattr(subclass, "__wrapped__"): 

800 return issubclass(subclass.__wrapped__, self.__wrapped__) 

801 else: 

802 return issubclass(subclass, self.__wrapped__) 

803 

804 

805class CallableObjectProxy(ObjectProxy): 

806 """An object proxy for callable objects that also forwards calls.""" 

807 

808 def __call__(*args, **kwargs): 

809 def _unpack_self(self, *args): 

810 return self, args 

811 

812 self, args = _unpack_self(*args) 

813 

814 return self.__wrapped__(*args, **kwargs) 

815 

816 

817class _PartialSignatureDescriptor: 

818 """Descriptor providing the ``__signature__`` attribute of instances of 

819 ``PartialCallableObjectProxy``. 

820 

821 The signature reported is that of the wrapped callable with the bound 

822 positional and keyword arguments removed, matching what ``inspect`` 

823 reports for ``functools.partial``. It must be defined on the proxy type 

824 itself, since attribute lookup on the proxy would otherwise be forwarded 

825 to the wrapped callable, and ``inspect.signature()`` stops following 

826 ``__wrapped__`` at the first object which has a ``__signature__`` 

827 attribute. 

828 

829 A plain property cannot be used because it would also be visible when 

830 accessed on the class, and ``inspect.signature()`` applied to the class 

831 itself would then fail on finding a property object rather than a 

832 ``Signature``. Raising ``AttributeError`` on class access leaves the 

833 signature of the class unchanged. 

834 """ 

835 

836 def __get__(self, instance, owner=None): 

837 if instance is None: 

838 raise AttributeError("__signature__") 

839 

840 partial = functools.partial( 

841 instance.__wrapped__, *instance._self_args, **instance._self_kwargs 

842 ) 

843 

844 return inspect.signature(partial) 

845 

846 

847class PartialCallableObjectProxy(ObjectProxy): 

848 """A callable object proxy that supports partial application of arguments 

849 and keywords. 

850 """ 

851 

852 __signature__ = _PartialSignatureDescriptor() 

853 

854 def __init__(*args, **kwargs): 

855 """Create a callable object proxy with partial application of the given 

856 arguments and keywords. This behaves the same as `functools.partial`, but 

857 implemented using the `ObjectProxy` class to provide better support for 

858 introspection. 

859 """ 

860 

861 def _unpack_self(self, *args): 

862 return self, args 

863 

864 self, args = _unpack_self(*args) 

865 

866 if len(args) < 1: 

867 raise TypeError("partial type takes at least one argument") 

868 

869 wrapped, args = args[0], args[1:] 

870 

871 if not callable(wrapped): 

872 raise TypeError("the first argument must be callable") 

873 

874 # Explicit class in super() is used because the proxy overrides 

875 # __class__ and MRO-related methods to delegate to the wrapped 

876 # object, which can interfere with bare super(). 

877 super(PartialCallableObjectProxy, self).__init__(wrapped) 

878 

879 self._self_args = args 

880 self._self_kwargs = kwargs 

881 

882 def __call__(*args, **kwargs): 

883 def _unpack_self(self, *args): 

884 return self, args 

885 

886 self, args = _unpack_self(*args) 

887 

888 _args = self._self_args + args 

889 

890 _kwargs = dict(self._self_kwargs) 

891 _kwargs.update(kwargs) 

892 

893 return self.__wrapped__(*_args, **_kwargs) 

894 

895 

896class _FunctionWrapperBase(ObjectProxy): 

897 

898 def __init__( 

899 self, 

900 wrapped, 

901 instance, 

902 wrapper, 

903 enabled=None, 

904 binding="callable", 

905 parent=None, 

906 owner=None, 

907 ): 

908 

909 # Explicit class in super() is used because the proxy overrides 

910 # __class__ and MRO-related methods to delegate to the wrapped 

911 # object, which can interfere with bare super(). 

912 super(_FunctionWrapperBase, self).__init__(wrapped) 

913 

914 object.__setattr__(self, "_self_instance", instance) 

915 object.__setattr__(self, "_self_wrapper", wrapper) 

916 object.__setattr__(self, "_self_enabled", enabled) 

917 object.__setattr__(self, "_self_binding", binding) 

918 object.__setattr__(self, "_self_parent", parent) 

919 object.__setattr__(self, "_self_owner", owner) 

920 

921 def __get__(self, instance, owner=None): 

922 # This method handles both unbound and bound derived wrapper classes. 

923 # It is kept in the base class as the amount of common code makes it 

924 # impractical to split into the derived classes. 

925 # 

926 # The distinguishing attribute which determines whether we are being 

927 # called in an unbound or bound wrapper is the parent attribute. If 

928 # binding has never occurred, then the parent will be None. 

929 # 

930 # First therefore, is if we are called in an unbound wrapper. In this 

931 # case we perform the binding. 

932 # 

933 # We have two special cases to worry about here. These are where we are 

934 # decorating a class or builtin function as neither provide a __get__() 

935 # method to call. In this case we simply return self. 

936 # 

937 # Note that we otherwise still do binding even if instance is None and 

938 # accessing an unbound instance method from a class. This is because we 

939 # need to be able to later detect that specific case as we will need to 

940 # extract the instance from the first argument of those passed in. 

941 

942 if self._self_parent is None: 

943 # Technically can probably just check for existence of __get__ on 

944 # the wrapped object, but this is more explicit. 

945 

946 if self._self_binding == "builtin": 

947 return self 

948 

949 if self._self_binding == "class": 

950 return self 

951 

952 binder = getattr(self.__wrapped__, "__get__", None) 

953 

954 if binder is None: 

955 return self 

956 

957 descriptor = binder(instance, owner) 

958 

959 return self.__bound_function_wrapper__( 

960 descriptor, 

961 instance, 

962 self._self_wrapper, 

963 self._self_enabled, 

964 self._self_binding, 

965 self, 

966 owner, 

967 ) 

968 

969 # Now we have the case of binding occurring a second time on what was 

970 # already a bound function. In this case we would usually return 

971 # ourselves again. This mirrors what Python does. 

972 # 

973 # The special case this time is where we were originally bound with an 

974 # instance of None and we were likely an instance method. In that case 

975 # we rebind against the original wrapped function from the parent again. 

976 

977 if self._self_instance is None and self._self_binding in ( 

978 "function", 

979 "instancemethod", 

980 "callable", 

981 ): 

982 descriptor = self._self_parent.__wrapped__.__get__(instance, owner) 

983 

984 return self._self_parent.__bound_function_wrapper__( 

985 descriptor, 

986 instance, 

987 self._self_wrapper, 

988 self._self_enabled, 

989 self._self_binding, 

990 self._self_parent, 

991 owner, 

992 ) 

993 

994 return self 

995 

996 def __call__(*args, **kwargs): 

997 def _unpack_self(self, *args): 

998 return self, args 

999 

1000 self, args = _unpack_self(*args) 

1001 

1002 # If enabled has been specified, then evaluate it at this point 

1003 # and if the wrapper is not to be executed, then simply return 

1004 # the bound function rather than a bound wrapper for the bound 

1005 # function. When evaluating enabled, if it is callable we call 

1006 # it, otherwise we evaluate it as a boolean. 

1007 

1008 if self._self_enabled is not None: 

1009 if callable(self._self_enabled): 

1010 if not self._self_enabled(): 

1011 return self.__wrapped__(*args, **kwargs) 

1012 elif not self._self_enabled: 

1013 return self.__wrapped__(*args, **kwargs) 

1014 

1015 # This can occur where initial function wrapper was applied to 

1016 # a function that was already bound to an instance. In that case 

1017 # we want to extract the instance from the function and use it. 

1018 

1019 if self._self_binding in ( 

1020 "function", 

1021 "instancemethod", 

1022 "classmethod", 

1023 "callable", 

1024 ): 

1025 if self._self_instance is None: 

1026 instance = getattr(self.__wrapped__, "__self__", None) 

1027 if instance is not None: 

1028 return self._self_wrapper(self.__wrapped__, instance, args, kwargs) 

1029 

1030 # This is generally invoked when the wrapped function is being 

1031 # called as a normal function and is not bound to a class as an 

1032 # instance method. This is also invoked in the case where the 

1033 # wrapped function was a method, but this wrapper was in turn 

1034 # wrapped using the staticmethod decorator. 

1035 

1036 return self._self_wrapper(self.__wrapped__, self._self_instance, args, kwargs) 

1037 

1038 def __set_name__(self, owner, name): 

1039 # This is a special method use to supply information to 

1040 # descriptors about what the name of variable in a class 

1041 # definition is. Not wanting to add this to ObjectProxy as not 

1042 # sure of broader implications of doing that. Thus restrict to 

1043 # FunctionWrapper used by decorators. 

1044 

1045 if hasattr(self.__wrapped__, "__set_name__"): 

1046 self.__wrapped__.__set_name__(owner, name) 

1047 

1048 

1049_FUNCTION_WRAPPER_SLOTS = frozenset( 

1050 ( 

1051 "_self_instance", 

1052 "_self_wrapper", 

1053 "_self_enabled", 

1054 "_self_binding", 

1055 "_self_parent", 

1056 "_self_owner", 

1057 ) 

1058) 

1059 

1060 

1061class BoundFunctionWrapper(_FunctionWrapperBase): 

1062 """A wrapper for bound methods, classmethods, and staticmethods.""" 

1063 

1064 def __setattr__(self, name, value): 

1065 if name.startswith("_self_") and name not in _FUNCTION_WRAPPER_SLOTS: 

1066 if self._self_parent is not None: 

1067 object.__setattr__(self._self_parent, name, value) 

1068 return 

1069 super().__setattr__(name, value) 

1070 

1071 def __getattr__(self, name): 

1072 # This is only reached for _self_parent when that attribute was 

1073 # never set, which means __init__() was not called. It has to fail 

1074 # here, as the lookup of it below would otherwise come straight 

1075 # back in and recurse without end. 

1076 

1077 if name == "_self_parent": 

1078 raise AttributeError( 

1079 f"'{type(self).__name__}' object has no attribute '{name}'" 

1080 ) 

1081 

1082 if self._self_parent is not None: 

1083 try: 

1084 return getattr(self._self_parent, name) 

1085 except AttributeError: 

1086 pass 

1087 return super().__getattr__(name) 

1088 

1089 def __call__(*args, **kwargs): 

1090 def _unpack_self(self, *args): 

1091 return self, args 

1092 

1093 self, args = _unpack_self(*args) 

1094 

1095 # If enabled has been specified, then evaluate it at this point and if 

1096 # the wrapper is not to be executed, then simply return the bound 

1097 # function rather than a bound wrapper for the bound function. When 

1098 # evaluating enabled, if it is callable we call it, otherwise we 

1099 # evaluate it as a boolean. 

1100 

1101 if self._self_enabled is not None: 

1102 if callable(self._self_enabled): 

1103 if not self._self_enabled(): 

1104 return self.__wrapped__(*args, **kwargs) 

1105 elif not self._self_enabled: 

1106 return self.__wrapped__(*args, **kwargs) 

1107 

1108 # We need to do things different depending on whether we are likely 

1109 # wrapping an instance method vs a static method or class method. 

1110 

1111 if self._self_binding == "function": 

1112 if self._self_instance is None and args: 

1113 instance, newargs = args[0], args[1:] 

1114 if isinstance(instance, self._self_owner): 

1115 wrapped = PartialCallableObjectProxy(self.__wrapped__, instance) 

1116 return self._self_wrapper(wrapped, instance, newargs, kwargs) 

1117 

1118 return self._self_wrapper( 

1119 self.__wrapped__, self._self_instance, args, kwargs 

1120 ) 

1121 

1122 elif self._self_binding == "callable": 

1123 if self._self_instance is None and args: 

1124 # This situation can occur where someone is calling the 

1125 # instancemethod via the class type and passing the instance as 

1126 # the first argument. We need to shift the args before making 

1127 # the call to the wrapper and effectively bind the instance to 

1128 # the wrapped function using a partial so the wrapper doesn't 

1129 # see anything as being different. 

1130 

1131 instance, newargs = args[0], args[1:] 

1132 if isinstance(instance, self._self_owner): 

1133 wrapped = PartialCallableObjectProxy(self.__wrapped__, instance) 

1134 return self._self_wrapper(wrapped, instance, newargs, kwargs) 

1135 

1136 return self._self_wrapper( 

1137 self.__wrapped__, self._self_instance, args, kwargs 

1138 ) 

1139 

1140 else: 

1141 # As in this case we would be dealing with a classmethod or 

1142 # staticmethod, then _self_instance will only tell us whether 

1143 # when calling the classmethod or staticmethod they did it via an 

1144 # instance of the class it is bound to and not the case where 

1145 # done by the class type itself. We thus ignore _self_instance 

1146 # and use the __self__ attribute of the bound function instead. 

1147 # For a classmethod, this means instance will be the class type 

1148 # and for a staticmethod it will be None. This is probably the 

1149 # more useful thing we can pass through even though we loose 

1150 # knowledge of whether they were called on the instance vs the 

1151 # class type, as it reflects what they have available in the 

1152 # decoratored function. 

1153 

1154 instance = getattr(self.__wrapped__, "__self__", None) 

1155 

1156 return self._self_wrapper(self.__wrapped__, instance, args, kwargs) 

1157 

1158 

1159class FunctionWrapper(_FunctionWrapperBase): 

1160 """ 

1161 A wrapper for callable objects that can be used to apply decorators to 

1162 functions, methods, classmethods, and staticmethods, or any other callable. 

1163 It handles binding and unbinding of methods, and allows for the wrapper to 

1164 be enabled or disabled. 

1165 """ 

1166 

1167 __bound_function_wrapper__ = BoundFunctionWrapper 

1168 

1169 def __init__(self, wrapped, wrapper, enabled=None): 

1170 """ 

1171 Initialize the `FunctionWrapper` with the `wrapped` callable, the 

1172 `wrapper` function, and an optional `enabled` argument. The `enabled` 

1173 argument can be a boolean or a callable that returns a boolean. When a 

1174 callable is provided, it will be called each time the wrapper is 

1175 invoked to determine if the wrapper function should be executed or 

1176 whether the wrapped function should be called directly. If `enabled` 

1177 is not provided, the wrapper is enabled by default. 

1178 """ 

1179 

1180 # What it is we are wrapping here could be anything. We need to 

1181 # try and detect specific cases though. In particular, we need 

1182 # to detect when we are given something that is a method of a 

1183 # class. Further, we need to know when it is likely an instance 

1184 # method, as opposed to a class or static method. This can 

1185 # become problematic though as there isn't strictly a fool proof 

1186 # method of knowing. 

1187 # 

1188 # The situations we could encounter when wrapping a method are: 

1189 # 

1190 # 1. The wrapper is being applied as part of a decorator which 

1191 # is a part of the class definition. In this case what we are 

1192 # given is the raw unbound function, classmethod or staticmethod 

1193 # wrapper objects. 

1194 # 

1195 # The problem here is that we will not know we are being applied 

1196 # in the context of the class being set up. This becomes 

1197 # important later for the case of an instance method, because in 

1198 # that case we just see it as a raw function and can't 

1199 # distinguish it from wrapping a normal function outside of 

1200 # a class context. 

1201 # 

1202 # 2. The wrapper is being applied when performing monkey 

1203 # patching of the class type afterwards and the method to be 

1204 # wrapped was retrieved direct from the __dict__ of the class 

1205 # type. This is effectively the same as (1) above. 

1206 # 

1207 # 3. The wrapper is being applied when performing monkey 

1208 # patching of the class type afterwards and the method to be 

1209 # wrapped was retrieved from the class type. In this case 

1210 # binding will have been performed where the instance against 

1211 # which the method is bound will be None at that point. 

1212 # 

1213 # This case is a problem because we can no longer tell if the 

1214 # method was a static method, plus if using Python3, we cannot 

1215 # tell if it was an instance method as the concept of an 

1216 # unnbound method no longer exists. 

1217 # 

1218 # 4. The wrapper is being applied when performing monkey 

1219 # patching of an instance of a class. In this case binding will 

1220 # have been performed where the instance was not None. 

1221 # 

1222 # This case is a problem because we can no longer tell if the 

1223 # method was a static method. 

1224 # 

1225 # Overall, the best we can do is look at the original type of the 

1226 # object which was wrapped prior to any binding being done and 

1227 # see if it is an instance of classmethod or staticmethod. In 

1228 # the case where other decorators are between us and them, if 

1229 # they do not propagate the __class__ attribute so that the 

1230 # isinstance() checks works, then likely this will do the wrong 

1231 # thing where classmethod and staticmethod are used. 

1232 # 

1233 # Since it is likely to be very rare that anyone even puts 

1234 # decorators around classmethod and staticmethod, likelihood of 

1235 # that being an issue is very small, so we accept it and suggest 

1236 # that those other decorators be fixed. It is also only an issue 

1237 # if a decorator wants to actually do things with the arguments. 

1238 # 

1239 # As to not being able to identify static methods properly, we 

1240 # just hope that that isn't something people are going to want 

1241 # to wrap, or if they do suggest they do it the correct way by 

1242 # ensuring that it is decorated in the class definition itself, 

1243 # or patch it in the __dict__ of the class type. 

1244 # 

1245 # So to get the best outcome we can, whenever we aren't sure what 

1246 # it is, we label it as a 'callable'. If it was already bound and 

1247 # that is rebound later, we assume that it will be an instance 

1248 # method and try and cope with the possibility that the 'self' 

1249 # argument it being passed as an explicit argument and shuffle 

1250 # the arguments around to extract 'self' for use as the instance. 

1251 

1252 binding = None 

1253 

1254 if isinstance(wrapped, _FunctionWrapperBase): 

1255 binding = wrapped._self_binding 

1256 

1257 if not binding: 

1258 if inspect.isbuiltin(wrapped): 

1259 binding = "builtin" 

1260 

1261 elif inspect.isfunction(wrapped): 

1262 binding = "function" 

1263 

1264 elif inspect.isclass(wrapped): 

1265 binding = "class" 

1266 

1267 elif isinstance(wrapped, classmethod): 

1268 binding = "classmethod" 

1269 

1270 elif isinstance(wrapped, staticmethod): 

1271 binding = "staticmethod" 

1272 

1273 elif hasattr(wrapped, "__self__"): 

1274 if inspect.isclass(wrapped.__self__): 

1275 binding = "classmethod" 

1276 elif inspect.ismethod(wrapped): 

1277 binding = "instancemethod" 

1278 else: 

1279 binding = "callable" 

1280 

1281 else: 

1282 binding = "callable" 

1283 

1284 # Explicit class in super() is used because the proxy overrides 

1285 # __class__ and MRO-related methods to delegate to the wrapped 

1286 # object, which can interfere with bare super(). 

1287 super(FunctionWrapper, self).__init__(wrapped, None, wrapper, enabled, binding)