This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: typo in documentation for create_autospec
Type: enhancement Stage:
Components: Documentation Versions: Python 3.6
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: docs@python Nosy List: Erik Byström, cheryl.sabella, docs@python, mariocj89, xtreak
Priority: normal Keywords:

Created on 2017-06-02 09:06 by Erik Byström, last changed 2022-04-11 14:58 by admin.

Messages (4)
msg294993 - (view) Author: Erik Byström (Erik Byström) Date: 2017-06-02 09:06
"a class" should most probably be replaced by "an instance" in the documentation for create_autospec.

"You can use a class as the spec for an instance object by passing instance=True. The returned mock will only be callable if instances of the mock are callable."

https://docs.python.org/3/library/unittest.mock.html#unittest.mock.create_autospec
msg305609 - (view) Author: Mario Corchero (mariocj89) * (Python triager) Date: 2017-11-05 19:07
I've always understood instance as a way to say "I am passing this class but I want to force the autospec on the instance"

For example, given

```
class X:
    def __init__(self):
        raise
```

You can do `unittest.mock.create_autospec(X, instance=True)` to set a spec of the instance rather than the class.

Also quite often you do autospec on a class but you want the interface of the instance. This parameter allows you to do so.

Basically, `unittest.mock.create_autospec(X, instance=True)` will produce a non callable mock.

I think the docs are correct, maybe misleading
msg334361 - (view) Author: Cheryl Sabella (cheryl.sabella) * (Python committer) Date: 2019-01-25 13:45
Mario is right that this isn't a typo.  Here's a code example to illustrate what he said:

>>> class MyClass:
...     a = 3
...     def foo(self): pass
...
>>> mock_class = create_autospec(MyClass)
>>> mock_class
<MagicMock spec='MyClass' id='16678696'>
>>> mock_class()
<NonCallableMagicMock name='mock()' spec='MyClass' id='16752016'>
>>> mock_class.foo
<MagicMock name='mock.foo' spec='function' id='16751032'>

>>> mock_instance = create_autospec(MyClass, instance=True)
>>> mock_instance
<NonCallableMagicMock spec='MyClass' id='16757832'>
>>> mock_instance()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'NonCallableMagicMock' object is not callable
>>> mock_instance.foo
<MagicMock name='mock.foo' spec='function' id='16750024'>

As per the docs, the instance object uses the class as the spec and it isn't callable, whereas the mock class is.  Would adding this example to the docs help or would a different code example help make this less misleading?
msg355697 - (view) Author: Erik Byström (Erik Byström) Date: 2019-10-30 08:35
Yes, you're right. I do think the docs are a bit misleading.

Maybe something like this would make it more clear?

"If a class is used as a spec then the returned object will be a mock of that class. When the constructor of the returned mock class is invoked an instance object is returned that has the same spec as a normal instance object would have. By passing instance=True you can directly create a mock instance of the class."

If not, feel free to close this issue.
History
Date User Action Args
2022-04-11 14:58:47adminsetgithub: 74733
2019-10-30 08:35:30Erik Byströmsetmessages: + msg355697
2019-10-29 15:45:28xtreaksetnosy: + xtreak
2019-01-25 13:45:00cheryl.sabellasetnosy: + cheryl.sabella
messages: + msg334361
2017-11-05 19:07:21mariocj89setnosy: + mariocj89
messages: + msg305609
2017-06-02 09:06:21Erik Byströmcreate