Is it possible to overwrite str's % behaviour using __rmod__?
Note: I submitted patches for Python 2.7, and 3.5 and up. These have landed and are part of 2.7.14, 3.5.4, 3.6.1 and 3.7, where the OP example now works as expected. For older versions, see below.
Unfortunately, this is not currently possible in Python. The behaviour is hardcoded in the evaluation loop:
TARGET(BINARY_MODULO) {
PyObject *divisor = POP();
PyObject *dividend = TOP();
PyObject *res = PyUnicode_CheckExact(dividend) ?
PyUnicode_Format(dividend, divisor) :
PyNumber_Remainder(dividend, divisor);
(From the Python 3.5 source code, where PyUnicode
is the Python str
type).
This is unfortunate, because for every other type you can prevent the LHS.__mod__
method to be invoked by using a subclass for the right-hand operand; from the documentation:
Note: If the right operand’s type is a subclass of the left operand’s type and that subclass provides the reflected method for the operation, this method will be called before the left operand’s non-reflected method. This behavior allows subclasses to override their ancestors’ operations.
This would have been the only option here, str % other
never returns NotImplemented
, all RHS types are accepted (the actual str.__mod__
method only accepts str
objects for the RHS, but is not called in this case).
I consider this a bug in Python, filed as issue #28598.