File tree 3 files changed +21
-3
lines changed
3 files changed +21
-3
lines changed Original file line number Diff line number Diff line change @@ -1448,6 +1448,15 @@ def test_formatting_huge_precision(self):
1448
1448
with self .assertRaises (ValueError ):
1449
1449
result = format_string % 2.34
1450
1450
1451
+ def test_issue28598_strsubclass_rhs (self ):
1452
+ # A subclass of str with an __rmod__ method should be able to hook
1453
+ # into the % operator
1454
+ class SubclassedStr (str ):
1455
+ def __rmod__ (self , other ):
1456
+ return 'Success, self.__rmod__({!r}) was called' .format (other )
1457
+ self .assertEqual ('lhs %% %r' % SubclassedStr ('rhs' ),
1458
+ "Success, self.__rmod__('lhs %% %r') was called" )
1459
+
1451
1460
@support .cpython_only
1452
1461
def test_formatting_huge_precision_c_limits (self ):
1453
1462
from _testcapi import INT_MAX
Original file line number Diff line number Diff line change @@ -10,6 +10,9 @@ What's New in Python 3.6.1 release candidate 1?
10
10
Core and Builtins
11
11
-----------------
12
12
13
+ - Issue #28598: Support __rmod__ for subclasses of str being called before
14
+ str.__mod__. Patch by Martijn Pieters.
15
+
13
16
- bpo-29607: Fix stack_effect computation for CALL_FUNCTION_EX.
14
17
Patch by Matthieu Dartiailh.
15
18
Original file line number Diff line number Diff line change @@ -1409,9 +1409,15 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
1409
1409
TARGET (BINARY_MODULO ) {
1410
1410
PyObject * divisor = POP ();
1411
1411
PyObject * dividend = TOP ();
1412
- PyObject * res = PyUnicode_CheckExact (dividend ) ?
1413
- PyUnicode_Format (dividend , divisor ) :
1414
- PyNumber_Remainder (dividend , divisor );
1412
+ PyObject * res ;
1413
+ if (PyUnicode_CheckExact (dividend ) && (
1414
+ !PyUnicode_Check (divisor ) || PyUnicode_CheckExact (divisor ))) {
1415
+ // fast path; string formatting, but not if the RHS is a str subclass
1416
+ // (see issue28598)
1417
+ res = PyUnicode_Format (dividend , divisor );
1418
+ } else {
1419
+ res = PyNumber_Remainder (dividend , divisor );
1420
+ }
1415
1421
Py_DECREF (divisor );
1416
1422
Py_DECREF (dividend );
1417
1423
SET_TOP (res );
You can’t perform that action at this time.
0 commit comments