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

Created on 2016-11-03 13:36 by mjpieters, last changed 2017-03-31 16:36 by dstufft. This issue is now closed.

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
PR 94 merged mjpieters, 2017-02-27 14:21
PR 95 merged mjpieters, 2017-02-27 16:08
PR 366 merged xiang.zhang, 2017-03-01 04:18
PR 382 closed mjpieters, 2017-03-01 16:45
PR 703 larry, 2017-03-17 21:00
PR 552 closed dstufft, 2017-03-31 16:36
Messages (9)
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
msg288695 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-02-28 06:19
Is 2.7 free from this bug?
msg288717 - (view) Author: Martijn Pieters (mjpieters) * Date: 2017-02-28 14:30
> Is 2.7 free from this bug?

No, 2.7 is affected too:

>>> class SubclassedStr(str):
...     def __rmod__(self, other):
...         return 'Success, self.__rmod__({!r}) was called'.format(other)
...
>>> 'lhs %% %r' % SubclassedStr('rhs')
"lhs % 'rhs'"

Expected output is "Success, self.__rmod__('lhs %% %r') was called"

On the plus side, unicode is not affected:

>>> class SubclassedUnicode(unicode):
...     def __rmod__(self, other):
...         return u'Success, self.__rmod__({!r}) was called'.format(other)
...
>>> u'lhs %% %r' % SubclassedUnicode(u'rhs')
u"Success, self.__rmod__(u'lhs %% %r') was called"
msg290356 - (view) Author: Xiang Zhang (xiang.zhang) * (Python committer) Date: 2017-03-24 23:32
New changeset b4f0e980b6084e9a994e3f069269fac2471e0d78 by Xiang Zhang in branch '2.7':
bpo-28598: Support __rmod__ for RHS subclasses of str in % string formatting operations (GH-366)
https://github.com/python/cpython/commit/b4f0e980b6084e9a994e3f069269fac2471e0d78
msg290364 - (view) Author: Berker Peksag (berker.peksag) * (Python committer) Date: 2017-03-24 23:36
New changeset bc144f0abff2b36595171377ee847c0266596ab2 by Berker Peksag (Martijn Pieters) in branch '3.5':
bpo-28598: Support __rmod__ for RHS subclasses of str in % string formatting operations (#94)
https://github.com/python/cpython/commit/bc144f0abff2b36595171377ee847c0266596ab2
msg290365 - (view) Author: Berker Peksag (berker.peksag) * (Python committer) Date: 2017-03-24 23:36
New changeset 53039ad3814a8918c5311f37bd654428b9843fcc by Berker Peksag (Martijn Pieters) in branch '3.6':
bpo-28598: Support __rmod__ for RHS subclasses of str in % string formatting operations (#95)
https://github.com/python/cpython/commit/53039ad3814a8918c5311f37bd654428b9843fcc
msg290428 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-03-24 23:51
New changeset d7e64337ef45085792b382a09f5b3a45d3687c8c by Serhiy Storchaka (Martijn Pieters) in branch 'master':
bpo-28598: Support __rmod__ for RHS subclasses of str in % string formatting operations (#51)
https://github.com/python/cpython/commit/d7e64337ef45085792b382a09f5b3a45d3687c8c
History
Date User Action Args
2017-03-31 16:36:38dstufftsetpull_requests: + pull_request1103
2017-03-24 23:51:29serhiy.storchakasetmessages: + msg290428
2017-03-24 23:36:54berker.peksagsetmessages: + msg290365
2017-03-24 23:36:46berker.peksagsetnosy: + berker.peksag
messages: + msg290364
2017-03-24 23:32:37xiang.zhangsetmessages: + msg290356
2017-03-17 21:00:35larrysetpull_requests: + pull_request619
2017-03-01 16:45:56mjpieterssetpull_requests: + pull_request318
2017-03-01 06:29:40xiang.zhangsetstatus: open -> closed
resolution: fixed
stage: needs patch -> resolved
2017-03-01 04:18:11xiang.zhangsetpull_requests: + pull_request310
2017-02-28 14:42:25serhiy.storchakasetstatus: closed -> open
stage: resolved -> needs patch
resolution: fixed -> (no value)
versions: + Python 2.7, - Python 3.5, Python 3.6, Python 3.7
2017-02-28 14:30:44mjpieterssetmessages: + msg288717
2017-02-28 06:19:03serhiy.storchakasetmessages: + msg288695
2017-02-27 16:08:46berker.peksagsetversions: - Python 2.7
2017-02-27 16:08:37berker.peksagsetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2017-02-27 16:08:03mjpieterssetpull_requests: + pull_request299
2017-02-27 14:21:40mjpieterssetpull_requests: + pull_request294
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