(self, name)
| 690 | |
| 691 | |
| 692 | def __getattr__(self, name): |
| 693 | if name in {'_mock_methods', '_mock_unsafe'}: |
| 694 | raise AttributeError(name) |
| 695 | elif self._mock_methods is not None: |
| 696 | if name not in self._mock_methods or name in _all_magics: |
| 697 | raise AttributeError("Mock object has no attribute %r" % name) |
| 698 | elif _is_magic(name): |
| 699 | raise AttributeError(name) |
| 700 | if not self._mock_unsafe and (not self._mock_methods or name not in self._mock_methods): |
| 701 | if name.startswith(('assert', 'assret', 'asert', 'aseert', 'assrt')) or name in _ATTRIB_DENY_LIST: |
| 702 | raise AttributeError( |
| 703 | f"{name!r} is not a valid assertion. Use a spec " |
| 704 | f"for the mock if {name!r} is meant to be an attribute") |
| 705 | |
| 706 | with NonCallableMock._lock: |
| 707 | result = self._mock_children.get(name) |
| 708 | if result is _deleted: |
| 709 | raise AttributeError(name) |
| 710 | elif result is None: |
| 711 | wraps = None |
| 712 | if self._mock_wraps is not None: |
| 713 | # XXXX should we get the attribute without triggering code |
| 714 | # execution? |
| 715 | wraps = getattr(self._mock_wraps, name) |
| 716 | |
| 717 | result = self._get_child_mock( |
| 718 | parent=self, name=name, wraps=wraps, _new_name=name, |
| 719 | _new_parent=self |
| 720 | ) |
| 721 | self._mock_children[name] = result |
| 722 | |
| 723 | elif isinstance(result, _SpecState): |
| 724 | try: |
| 725 | result = create_autospec( |
| 726 | result.spec, result.spec_set, result.instance, |
| 727 | result.parent, result.name |
| 728 | ) |
| 729 | except InvalidSpecError: |
| 730 | target_name = self.__dict__['_mock_name'] or self |
| 731 | raise InvalidSpecError( |
| 732 | f'Cannot autospec attr {name!r} from target ' |
| 733 | f'{target_name!r} as it has already been mocked out. ' |
| 734 | f'[target={self!r}, attr={result.spec!r}]') |
| 735 | self._mock_children[name] = result |
| 736 | |
| 737 | return result |
| 738 | |
| 739 | |
| 740 | def _extract_mock_name(self): |
nothing calls this directly
no test coverage detected