File tree Expand file tree Collapse file tree 3 files changed +18
-2
lines changed Expand file tree Collapse file tree 3 files changed +18
-2
lines changed Original file line number Diff line number Diff line change @@ -465,6 +465,15 @@ def test_startswith_endswith_errors(self):
465
465
self .assertIn ('str' , exc )
466
466
self .assertIn ('tuple' , exc )
467
467
468
+ def test_issue28598_strsubclass_rhs (self ):
469
+ # A subclass of str with an __rmod__ method should be able to hook
470
+ # into the % operator
471
+ class SubclassedStr (str ):
472
+ def __rmod__ (self , other ):
473
+ return 'Success, self.__rmod__({!r}) was called' .format (other )
474
+ self .assertEqual ('lhs %% %r' % SubclassedStr ('rhs' ),
475
+ "Success, self.__rmod__('lhs %% %r') was called" )
476
+
468
477
def test_main ():
469
478
test_support .run_unittest (StrTest )
470
479
Original file line number Diff line number Diff line change @@ -10,6 +10,9 @@ What's New in Python 2.7.14?
10
10
Core and Builtins
11
11
-----------------
12
12
13
+ - bpo-28598: Support __rmod__ for subclasses of str being called before
14
+ str.__mod__. Patch by Martijn Pieters.
15
+
13
16
- bpo-29602: Fix incorrect handling of signed zeros in complex constructor for
14
17
complex subclasses and for inputs having a __complex__ method. Patch
15
18
by Serhiy Storchaka.
Original file line number Diff line number Diff line change @@ -1446,10 +1446,14 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
1446
1446
{
1447
1447
w = POP ();
1448
1448
v = TOP ();
1449
- if (PyString_CheckExact (v ))
1449
+ if (PyString_CheckExact (v )
1450
+ && (!PyString_Check (w ) || PyString_CheckExact (w ))) {
1451
+ /* fast path; string formatting, but not if the RHS is a str subclass
1452
+ (see issue28598) */
1450
1453
x = PyString_Format (v , w );
1451
- else
1454
+ } else {
1452
1455
x = PyNumber_Remainder (v , w );
1456
+ }
1453
1457
Py_DECREF (v );
1454
1458
Py_DECREF (w );
1455
1459
SET_TOP (x );
You can’t perform that action at this time.
0 commit comments