On Sun, 23 Feb 2020 at 11:25, Michael Foord <fuzzy...@gmail.com> wrote:

> In unittest.mock.MagicMock I solve this problem by having __new__ create a
> new subclass for every instantiation. Setting any magic method on the
> instance is promoted to the type via __setattr__. That way every instance
> can have unique magic methods without affecting other instances.
>


The other little bit of trickery is that MagicMock gets all the magic
methods by default and they're all MagicMock objects. To avoid
instantiating MagicMock recursively creating MagicMocks forever the magic
methods are descriptors that put a new MagicMock instance onto the subclass
on first access via an instance. I could probably have saved a lot of
effort by overriding __getattribute__ (which can intercept magic method
lookups unlike __getatttr__) instead of the descriptor solution. At the
time I didn't know that. There's still a bunch of jiggery-pokery to set
valid default return values on a bunch of the methods (some are type
checked on the return value and some aren't *sigh*), so maybe it's
unavoidable.

I had fun getting mock to work.

Michael


>
> Michael
>
> On Sun, 23 Feb 2020 at 04:21, Jérôme Carretero <cj-pyt...@zougloub.eu>
> wrote:
>
>> Thanks Josh for your prompt reply. All clear.
>>
>>
>> Regards,
>>
>> --
>> Jérôme
>>
>> PS: Somehow I had never encountered a situation exacerbating the
>> subtleties of implicit invocations of special methods, and hadn't read
>> or integrated that section of the documentation, then when encountering
>> the “problem” I didn't make my way to the docs.
>> And now I also see that right when opening § 3.3. Special method
>> names ¶ 1 it's stated that “`x[i]` is roughly equivalent to
>> `type(x).__getitem__(x, i)`”. I'll be more careful next time!
>>
>>
>> On Sun, 23 Feb 2020 02:35:24 +0000
>> Josh Rosenberg <shadowranger+pythonid...@gmail.com> wrote:
>>
>> > This is explained in "Special Method Lookup":
>> >
>> https://docs.python.org/3/reference/datamodel.html#special-method-lookup
>> >
>> > Short version: For both correctness and performance, special methods
>> (those
>> > that begin and end with double underscores) are typically looked up on
>> the
>> > class, not the instance. If you want to override on a per-instance
>> level,
>> > have a non-special method that __str__ invokes, that can be overridden
>> on a
>> > per-instance basis.
>> >
>> > On Sun, Feb 23, 2020 at 2:30 AM Jérôme Carretero <cj-pyt...@zougloub.eu
>> >
>> > wrote:
>> >
>> > > Hello,
>> > >
>> > >
>> > > I just noticed that calling `str(x)` is actually doing (in CPython
>> > > `PyObject_Str`) `type(x).__str__(x)` rather than `x.__str__()`.
>> > >
>> > > Context: I wanted to override __str__ for certain objects in order to
>> > > “see them better”.
>> > >
>> > > I'm wondering why not do `x.__str__()`
>> > >
>> > >
>> > > Best regards,
>> > >
>> > > --
>> > > Jérôme
>> _______________________________________________
>> Python-ideas mailing list -- python-ideas@python.org
>> To unsubscribe send an email to python-ideas-le...@python.org
>> https://mail.python.org/mailman3/lists/python-ideas.python.org/
>> Message archived at
>> https://mail.python.org/archives/list/python-ideas@python.org/message/G3MW5GD534GNYLE4ARZGE42NHGSSNLGL/
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
>
>
> --
>
> Michael Foord
>
> Python Consultant, Contractor and Trainer
>
> https://agileabstractions.com/
>
>

-- 

Michael Foord

Python Consultant, Contractor and Trainer

https://agileabstractions.com/
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/3XVMOFY7UOBDCCRIC3RVF75YUAWVYAAV/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to