| 553 | |
| 554 | |
| 555 | class _patching: |
| 556 | |
| 557 | def __init__(self, monkeypatch, request): |
| 558 | self.monkeypatch = monkeypatch |
| 559 | self.request = request |
| 560 | |
| 561 | def __getattr__(self, name): |
| 562 | return getattr(self.monkeypatch, name) |
| 563 | |
| 564 | def __call__(self, path, value=SENTINEL, name=None, |
| 565 | new=MagicMock, **kwargs): |
| 566 | value = self._value_or_mock(value, new, name, path, **kwargs) |
| 567 | self.monkeypatch.setattr(path, value) |
| 568 | return value |
| 569 | |
| 570 | def object(self, target, attribute, *args, **kwargs): |
| 571 | return _wrap_context( |
| 572 | patch.object(target, attribute, *args, **kwargs), |
| 573 | self.request) |
| 574 | |
| 575 | def _value_or_mock(self, value, new, name, path, **kwargs): |
| 576 | if value is SENTINEL: |
| 577 | value = new(name=name or path.rpartition('.')[2]) |
| 578 | for k, v in kwargs.items(): |
| 579 | setattr(value, k, v) |
| 580 | return value |
| 581 | |
| 582 | def setattr(self, target, name=SENTINEL, value=SENTINEL, **kwargs): |
| 583 | # alias to __call__ with the interface of pytest.monkeypatch.setattr |
| 584 | if value is SENTINEL: |
| 585 | value, name = name, None |
| 586 | return self(target, value, name=name) |
| 587 | |
| 588 | def setitem(self, dic, name, value=SENTINEL, new=MagicMock, **kwargs): |
| 589 | # same as pytest.monkeypatch.setattr but default value is MagicMock |
| 590 | value = self._value_or_mock(value, new, name, dic, **kwargs) |
| 591 | self.monkeypatch.setitem(dic, name, value) |
| 592 | return value |
| 593 | |
| 594 | def modules(self, *mods): |
| 595 | modules = [] |
| 596 | for mod in mods: |
| 597 | mod = mod.split('.') |
| 598 | modules.extend(reversed([ |
| 599 | '.'.join(mod[:-i] if i else mod) for i in range(len(mod)) |
| 600 | ])) |
| 601 | modules = sorted(set(modules)) |
| 602 | return _wrap_context(module_context_manager(*modules), self.request) |
| 603 | |
| 604 | |
| 605 | def _wrap_context(context, request): |