From aacce81011615d93be8b74897a710fee811192d6 Mon Sep 17 00:00:00 2001 From: William Chargin Date: Thu, 3 Sep 2020 13:38:38 -0700 Subject: [PATCH] bpo-41706: Fix dunder operator invocation docs The expression `x + y` is evaluated using `type(x).__add__`, which may differ from `x.__add__` if the `__add__` attribute has been directly assigned on the instance. Demonstration: ```python class C: def __add__(self, other): return "from class" c = C() print(c + c) # prints "from class" c.__add__ = lambda other: "from instance" print(c.__add__(c)) # prints "from instance" print(type(c).__add__(c, c)) # prints "from class" print(c + c) # prints "from class"! ``` wchargin-branch: dunder-op-invocation-docs wchargin-source: 543786396ecba124a332357c771cfd6b20493abe --- Doc/reference/datamodel.rst | 7 ++++--- .../Documentation/2020-09-03-13-37-19.bpo-41706._zXWOR.rst | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2020-09-03-13-37-19.bpo-41706._zXWOR.rst diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index a817408c3b1ef5..924f90db6c04e0 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -2330,7 +2330,7 @@ left undefined. (``+``, ``-``, ``*``, ``@``, ``/``, ``//``, ``%``, :func:`divmod`, :func:`pow`, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For instance, to evaluate the expression ``x + y``, where *x* is an instance of a class that - has an :meth:`__add__` method, ``x.__add__(y)`` is called. The + has an :meth:`__add__` method, ``type(x).__add__(x, y)`` is called. The :meth:`__divmod__` method should be the equivalent to using :meth:`__floordiv__` and :meth:`__mod__`; it should not be related to :meth:`__truediv__`. Note that :meth:`__pow__` should be defined to accept @@ -2366,8 +2366,9 @@ left undefined. (swapped) operands. These functions are only called if the left operand does not support the corresponding operation [#]_ and the operands are of different types. [#]_ For instance, to evaluate the expression ``x - y``, where *y* is - an instance of a class that has an :meth:`__rsub__` method, ``y.__rsub__(x)`` - is called if ``x.__sub__(y)`` returns *NotImplemented*. + an instance of a class that has an :meth:`__rsub__` method, + ``type(y).__rsub__(y, x)`` is called if ``type(x).__sub__(x, y)`` returns + *NotImplemented*. .. index:: builtin: pow diff --git a/Misc/NEWS.d/next/Documentation/2020-09-03-13-37-19.bpo-41706._zXWOR.rst b/Misc/NEWS.d/next/Documentation/2020-09-03-13-37-19.bpo-41706._zXWOR.rst new file mode 100644 index 00000000000000..6406494ec03c7b --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-09-03-13-37-19.bpo-41706._zXWOR.rst @@ -0,0 +1,2 @@ +Fix docs about how methods like ``__add__`` are invoked when evaluating +operator expressions.