Create a mock object using another object as a spec. Attributes on the mock will use the corresponding attribute on the `spec` object as their spec. Functions or methods being mocked will have their arguments checked to check that they are called with the correct signature. If
(spec, spec_set=False, instance=False, _parent=None,
_name=None, *, unsafe=False, **kwargs)
| 2746 | |
| 2747 | |
| 2748 | def create_autospec(spec, spec_set=False, instance=False, _parent=None, |
| 2749 | _name=None, *, unsafe=False, **kwargs): |
| 2750 | """Create a mock object using another object as a spec. Attributes on the |
| 2751 | mock will use the corresponding attribute on the `spec` object as their |
| 2752 | spec. |
| 2753 | |
| 2754 | Functions or methods being mocked will have their arguments checked |
| 2755 | to check that they are called with the correct signature. |
| 2756 | |
| 2757 | If `spec_set` is True then attempting to set attributes that don't exist |
| 2758 | on the spec object will raise an `AttributeError`. |
| 2759 | |
| 2760 | If a class is used as a spec then the return value of the mock (the |
| 2761 | instance of the class) will have the same spec. You can use a class as the |
| 2762 | spec for an instance object by passing `instance=True`. The returned mock |
| 2763 | will only be callable if instances of the mock are callable. |
| 2764 | |
| 2765 | `create_autospec` will raise a `RuntimeError` if passed some common |
| 2766 | misspellings of the arguments autospec and spec_set. Pass the argument |
| 2767 | `unsafe` with the value True to disable that check. |
| 2768 | |
| 2769 | `create_autospec` also takes arbitrary keyword arguments that are passed to |
| 2770 | the constructor of the created mock.""" |
| 2771 | if _is_list(spec): |
| 2772 | # can't pass a list instance to the mock constructor as it will be |
| 2773 | # interpreted as a list of strings |
| 2774 | spec = type(spec) |
| 2775 | |
| 2776 | is_type = isinstance(spec, type) |
| 2777 | if _is_instance_mock(spec): |
| 2778 | raise InvalidSpecError(f'Cannot autospec a Mock object. ' |
| 2779 | f'[object={spec!r}]') |
| 2780 | is_async_func = _is_async_func(spec) |
| 2781 | _kwargs = {'spec': spec} |
| 2782 | |
| 2783 | entries = [(entry, _missing) for entry in dir(spec)] |
| 2784 | if is_type and instance and is_dataclass(spec): |
| 2785 | is_dataclass_spec = True |
| 2786 | dataclass_fields = fields(spec) |
| 2787 | entries.extend((f.name, f.type) for f in dataclass_fields) |
| 2788 | dataclass_spec_list = [f.name for f in dataclass_fields] |
| 2789 | else: |
| 2790 | is_dataclass_spec = False |
| 2791 | |
| 2792 | if spec_set: |
| 2793 | _kwargs = {'spec_set': spec} |
| 2794 | elif spec is None: |
| 2795 | # None we mock with a normal mock without a spec |
| 2796 | _kwargs = {} |
| 2797 | if _kwargs and instance: |
| 2798 | _kwargs['_spec_as_instance'] = True |
| 2799 | if not unsafe: |
| 2800 | _check_spec_arg_typos(kwargs) |
| 2801 | |
| 2802 | _name = kwargs.pop('name', _name) |
| 2803 | _new_name = _name |
| 2804 | if _parent is None: |
| 2805 | # for a top level object no _new_name should be set |
searching dependent graphs…