classification
Title: RHS not consulted in `str % subclass_of_str` case.
Type: behavior Stage: patch review
Components: Interpreter Core Versions: Python 3.7, Python 3.6, Python 3.5, Python 2.7
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: mjpieters, serhiy.storchaka, xiang.zhang
Priority: normal Keywords: patch

Created on 2016-11-03 13:36 by mjpieters, last changed 2017-02-23 13:32 by serhiy.storchaka.

Files
File name Uploaded Description Edit
issue28598.patch mjpieters, 2016-11-03 17:44 Proposed patch, v1 review
Pull Requests
URL Status Linked Edit
PR 51 merged serhiy.storchaka, 2017-02-23 13:32
Messages (3)
msg279993 - (view) Author: Martijn Pieters (mjpieters) * Date: 2016-11-03 13:36
The `BINARY_MODULO` operator hardcodes a test for `PyUnicode`:

        TARGET(BINARY_MODULO) {
            PyObject *divisor = POP();
            PyObject *dividend = TOP();
            PyObject *res = PyUnicode_CheckExact(dividend) ?
                PyUnicode_Format(dividend, divisor) :
                PyNumber_Remainder(dividend, divisor);

This means that a RHS subclass of str can't override the operator:

>>> class Foo(str):
...     def __rmod__(self, other):
...         return self % other
...
>>> "Bar: %s" % Foo("Foo: %s")
'Bar: Foo %s'

The expected output there is "Foo: Bar %s".

This works correctly for `bytes`:

>>> class FooBytes(bytes):
...     def __rmod__(self, other):
...         return self % other
...
>>> b"Bar: %s" % FooBytes(b"Foo: %s")
b'Foo: Bar: %s'

and for all other types where the RHS is a subclass.

Perhaps there should be a test to see if `divisor` is a subclass, and in that case take the slow path?
msg280001 - (view) Author: Martijn Pieters (mjpieters) * Date: 2016-11-03 17:44
Here's a proposed patch for tip; what versions would it be worth backporting this to?

(Note, there's no NEWS update in this patch).
msg287638 - (view) Author: Martijn Pieters (mjpieters) * Date: 2017-02-12 15:48
I'm not sure if issues are linked automatically yet. I put the patch up as a pull request on GitHub: https://github.com/python/cpython/pull/51
History
Date User Action Args
2017-02-23 13:32:10serhiy.storchakasetpull_requests: + pull_request218
2017-02-23 13:29:17serhiy.storchakasetpull_requests: - pull_request57
2017-02-14 09:04:39mjpieterssetpull_requests: + pull_request57
2017-02-12 17:14:32serhiy.storchakasetnosy: + serhiy.storchaka
stage: patch review

versions: + Python 3.7, - Python 3.3, Python 3.4
2017-02-12 15:48:31mjpieterssetmessages: + msg287638
2016-11-03 17:44:54mjpieterssetfiles: + issue28598.patch
keywords: + patch
messages: + msg280001
2016-11-03 15:45:02xiang.zhangsetnosy: + xiang.zhang
2016-11-03 13:36:04mjpieterscreate