[Python-Dev] How far to go with user-friendliness

Paul Moore p.f.moore at gmail.com
Tue Jul 14 16:06:17 CEST 2015


On 14 July 2015 at 14:51, Florian Bruhin <me at the-compiler.org> wrote:
> * Steven D'Aprano <steve at pearwood.info> [2015-07-14 23:41:56 +1000]:
>> On Tue, Jul 14, 2015 at 02:06:14PM +0200, Dima Tisnek wrote:
>> > https://bugs.python.org/issue21238 introduces detection of
>> > missing/misspelt mock.assert_xxx() calls on getattr level in Python
>> > 3.5
>> >
>> > Michael and Kushal are of the opinion that "assret" is a common typo
>> > of "assert" and should be supported in a sense that it also triggers
>> > AttributeError and is not silently ignored like a mocked user
>> > attribute.
>> >
>> > I disagree
>>
>> I must admit I don't use mock so don't quite understand what is going on
>> in this bug report.
>
> Without using spec/autospec, a mock (by design) supports calling any
> method on itself, which returns another mock:
>
>     >>> m = mock.Mock()
>     >>> m.eggs()
>     <Mock name='mock.eggs()' id='140373912833384'>
>     >>> m.bacon()
>     <Mock name='mock.bacon()' id='140373910240616'>
>
> However, it also has some special methods to see if it has been
> called:
>
>     >>> m.assert_called_with()
>     [...]
>     AssertionError: Expected call: mock()
>     Not called
>
> Now because of that, if you do a typo, you won't notice in a test:
>
>     >>> m.assert_caled_with()
>     <Mock name='mock.assert_caled_with()' id='140373910240672'>
>
> With the patch, an AttributeError is raised if you call something
> starting with assert or assret instead.

In retrospect, this seems like a mistake in the design. Much like
namedtuple, mocks should carefully separate "actual" methods from
mocked ones (in the case of namedtuple, from tuple element names). If
Guido would let us use the time machine, I'd argue that maybe the
special methods should be _assert_called_with (or something similar).

Given that it's way too late to take that path, I can see the value of
trying to detect common errors. Particularly as the result of failing
to do so is an apparently-passing test.

In effect, this patch is "reserving" all attributes starting with
"assert" or "assret" as actual methods of the mock object, and not
mocked attributes.

Reserving "assert" seems fair.
Reserving "assret" seems odd, as people say why just this
mis-spelling? Is there any specific evidence that this typo happens
more often "in the wild" than any other? Given that the original issue
was raised by Michael Foord (the author of mock), I'd be inclined to
assume that he'd encountered evidence to that effect.

So ultimately I'm +1 on reserving "assert" (given that a more radical
fix isn't possible) and +0 on adding "assret" (simply on the basis
that someone more knowledgeable than me says it makes sense).

Paul


More information about the Python-Dev mailing list