On Sun, 23 Feb 2020 at 11:25, Michael Foord <[email protected]> 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 <[email protected]> > 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 <[email protected]> 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 <[email protected] >> > >> > 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 -- [email protected] >> To unsubscribe send an email to [email protected] >> https://mail.python.org/mailman3/lists/python-ideas.python.org/ >> Message archived at >> https://mail.python.org/archives/list/[email protected]/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 -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/[email protected]/message/3XVMOFY7UOBDCCRIC3RVF75YUAWVYAAV/ Code of Conduct: http://python.org/psf/codeofconduct/
