From 4ea4e2059804d471b82c538ad8b6a8ed2a3e8387 Mon Sep 17 00:00:00 2001 From: Martijn Pieters Date: Tue, 14 Feb 2017 08:33:07 +0000 Subject: [PATCH 1/2] [backport to 3.5] bpo-28598: Support __rmod__ for RHS subclasses of str in % string formatting operations --- Lib/test/test_unicode.py | 9 +++++++++ Misc/NEWS | 3 +++ Python/ceval.c | 12 +++++++++--- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py index 3136ea1a1bad3e..9dbded2d99c530 100644 --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -1424,6 +1424,15 @@ def test_formatting_huge_precision(self): with self.assertRaises(ValueError): result = format_string % 2.34 + def test_issue28598_strsubclass_rhs(self): + # A subclass of str with an __rmod__ method should be able to hook + # into the % operator + class SubclassedStr(str): + def __rmod__(self, other): + return 'Success, self.__rmod__({!r}) was called'.format(other) + self.assertEqual('lhs %% %r' % SubclassedStr('rhs'), + "Success, self.__rmod__('lhs %% %r') was called") + @support.cpython_only def test_formatting_huge_precision_c_limits(self): from _testcapi import INT_MAX diff --git a/Misc/NEWS b/Misc/NEWS index fe50135c01615c..7dc66808178c05 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Release date: XXXX-XX-XX Core and Builtins ----------------- +- Issue #28598: Support __rmod__ for subclasses of str being called before + str.__mod__. Patch by Martijn Pieters. + - bpo-29438: Fixed use-after-free problem in key sharing dict. - Issue #29319: Prevent RunMainFromImporter overwriting sys.path[0]. diff --git a/Python/ceval.c b/Python/ceval.c index 7b405188d38c66..ff44f541c7a5e1 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1545,9 +1545,15 @@ PyEval_EvalFrameEx(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); From b2e718b23ddfaab093c9b0026814bd833be0b3ae Mon Sep 17 00:00:00 2001 From: Martijn Pieters Date: Mon, 27 Feb 2017 14:39:16 +0000 Subject: [PATCH 2/2] Use C89-compatible comments --- Python/ceval.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index ff44f541c7a5e1..d3239089284c48 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1548,8 +1548,8 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) 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) + /* 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); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy