From a0094449087744edd86020b022d635eec5f27acf Mon Sep 17 00:00:00 2001 From: Daw-Ran Liou Date: Wed, 24 May 2017 14:47:53 -0700 Subject: [PATCH 1/3] Fix the return type of escape to Markup This patch fixes the return type of escape to always be Markup. It addresses the issue with custom class that implements the __html__ method - see issue #68. A new test case, test_escape_return_type, is added to test the behavior. --- markupsafe/_native.py | 2 +- markupsafe/_speedups.c | 5 ++++- tests.py | 8 ++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/markupsafe/_native.py b/markupsafe/_native.py index 5e83f10a..2c54a2de 100644 --- a/markupsafe/_native.py +++ b/markupsafe/_native.py @@ -18,7 +18,7 @@ def escape(s): such characters in HTML. Marks return value as markup string. """ if hasattr(s, '__html__'): - return s.__html__() + return Markup(s.__html__()) return Markup(text_type(s) .replace('&', '&') .replace('>', '>') diff --git a/markupsafe/_speedups.c b/markupsafe/_speedups.c index d779a68c..afe34254 100644 --- a/markupsafe/_speedups.c +++ b/markupsafe/_speedups.c @@ -131,8 +131,11 @@ escape(PyObject *self, PyObject *text) /* if the object has an __html__ method that performs the escaping */ html = PyObject_GetAttrString(text, "__html__"); if (html) { - rv = PyObject_CallObject(html, NULL); + s = PyObject_CallObject(html, NULL); Py_DECREF(html); + /* Convert to Markup object */ + rv = PyObject_CallFunctionObjArgs(markup, (PyObject*)s, NULL); + Py_DECREF(s); return rv; } diff --git a/tests.py b/tests.py index 7ec2acbc..11d91f3c 100755 --- a/tests.py +++ b/tests.py @@ -173,6 +173,14 @@ def test_splitting(self): def test_mul(self): self.assertEqual(Markup('a') * 3, Markup('aaa')) + def test_escape_return_type(self): + self.assertIsInstance(escape('a'), Markup) + self.assertIsInstance(escape(Markup('a')), Markup) + class Foo: + def __html__(self): + return 'Foo' + self.assertIsInstance(escape(Foo()), Markup) + class MarkupLeakTestCase(unittest.TestCase): From 870fef8f49278dad2ddc12d873a805e7ef8fc3a6 Mon Sep 17 00:00:00 2001 From: Daw-Ran Liou Date: Wed, 24 May 2017 15:08:53 -0700 Subject: [PATCH 2/3] Change test API for python 2.6 --- tests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests.py b/tests.py index 11d91f3c..ba5d30c0 100755 --- a/tests.py +++ b/tests.py @@ -174,12 +174,12 @@ def test_mul(self): self.assertEqual(Markup('a') * 3, Markup('aaa')) def test_escape_return_type(self): - self.assertIsInstance(escape('a'), Markup) - self.assertIsInstance(escape(Markup('a')), Markup) + self.assertTrue(isinstance(escape('a'), Markup)) + self.assertTrue(isinstance(escape(Markup('a')), Markup)) class Foo: def __html__(self): return 'Foo' - self.assertIsInstance(escape(Foo()), Markup) + self.assertTrue(isinstance(escape(Foo()), Markup)) class MarkupLeakTestCase(unittest.TestCase): From 674a969c2342dfad20e12bb4c3d9310c9d0fd8f7 Mon Sep 17 00:00:00 2001 From: David Lord Date: Wed, 24 May 2017 15:23:34 -0700 Subject: [PATCH 3/3] add changelog [ci skip] --- CHANGES | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGES b/CHANGES index 706a230c..ef0d8018 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,16 @@ MarkupSafe Changelog ==================== +Version 1.1 +----------- + +unreleased + +- ``escape`` wraps ``__html__`` result in ``Markup``, consistent with + documented behavior. (`#69`_) + +.. _#69: https://github.com/pallets/markupsafe/pull/69 + Version 1.0 -----------