File tree Expand file tree Collapse file tree 3 files changed +21
-3
lines changed Expand file tree Collapse file tree 3 files changed +21
-3
lines changed Original file line number Diff line number Diff line change @@ -1424,6 +1424,15 @@ def test_formatting_huge_precision(self):
14241424 with self .assertRaises (ValueError ):
14251425 result = format_string % 2.34
14261426
1427+ def test_issue28598_strsubclass_rhs (self ):
1428+ # A subclass of str with an __rmod__ method should be able to hook
1429+ # into the % operator
1430+ class SubclassedStr (str ):
1431+ def __rmod__ (self , other ):
1432+ return 'Success, self.__rmod__({!r}) was called' .format (other )
1433+ self .assertEqual ('lhs %% %r' % SubclassedStr ('rhs' ),
1434+ "Success, self.__rmod__('lhs %% %r') was called" )
1435+
14271436 @support .cpython_only
14281437 def test_formatting_huge_precision_c_limits (self ):
14291438 from _testcapi import INT_MAX
Original file line number Diff line number Diff line change @@ -10,6 +10,9 @@ Release date: XXXX-XX-XX
1010Core and Builtins
1111-----------------
1212
13+ - Issue #28598: Support __rmod__ for subclasses of str being called before
14+ str.__mod__. Patch by Martijn Pieters.
15+
1316- bpo-29602: Fix incorrect handling of signed zeros in complex constructor for
1417 complex subclasses and for inputs having a __complex__ method. Patch
1518 by Serhiy Storchaka.
Original file line number Diff line number Diff line change @@ -1545,9 +1545,15 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
15451545 TARGET (BINARY_MODULO ) {
15461546 PyObject * divisor = POP ();
15471547 PyObject * dividend = TOP ();
1548- PyObject * res = PyUnicode_CheckExact (dividend ) ?
1549- PyUnicode_Format (dividend , divisor ) :
1550- PyNumber_Remainder (dividend , divisor );
1548+ PyObject * res ;
1549+ if (PyUnicode_CheckExact (dividend ) && (
1550+ !PyUnicode_Check (divisor ) || PyUnicode_CheckExact (divisor ))) {
1551+ /* fast path; string formatting, but not if the RHS is a str subclass
1552+ (see issue28598) */
1553+ res = PyUnicode_Format (dividend , divisor );
1554+ } else {
1555+ res = PyNumber_Remainder (dividend , divisor );
1556+ }
15511557 Py_DECREF (divisor );
15521558 Py_DECREF (dividend );
15531559 SET_TOP (res );
You can’t perform that action at this time.
0 commit comments