From d7e64337ef45085792b382a09f5b3a45d3687c8c Mon Sep 17 00:00:00 2001 From: Martijn Pieters Date: Thu, 23 Feb 2017 13:38:04 +0000 Subject: bpo-28598: Support __rmod__ for RHS subclasses of str in % string formatting operations (#51) When you use `'%s' % SubClassOfStr()`, where `SubClassOfStr.__rmod__` exists, the reverse operation is ignored as normally such string formatting operations use the `PyUnicode_Format()` fast path. This patch tests for subclasses of `str` first and picks the slow path in that case. Patch by Martijn Pieters. --- Python/ceval.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'Python/ceval.c') diff --git a/Python/ceval.c b/Python/ceval.c index 81c89dfadf..0a82965c51 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1354,9 +1354,15 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) TARGET(BINARY_MODULO) { PyObject *divisor = POP(); PyObject *dividend = TOP(); - PyObject *res = PyUnicode_CheckExact(dividend) ? - PyUnicode_Format(dividend, divisor) : - PyNumber_Remainder(dividend, divisor); + PyObject *res; + if (PyUnicode_CheckExact(dividend) && ( + !PyUnicode_Check(divisor) || PyUnicode_CheckExact(divisor))) { + // fast path; string formatting, but not if the RHS is a str subclass + // (see issue28598) + res = PyUnicode_Format(dividend, divisor); + } else { + res = PyNumber_Remainder(dividend, divisor); + } Py_DECREF(divisor); Py_DECREF(dividend); SET_TOP(res); -- cgit v1.2.1