From: Benjamin Peterson Date: Fri, 4 Mar 2016 06:05:36 +0000 (-0800) Subject: properly use PyObject_CallMethod in dictview binary operations (closes #26478) X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4ddb44a1d00cc513e27e43b4145c60d55c33b1a0;p=python properly use PyObject_CallMethod in dictview binary operations (closes #26478) --- diff --git a/Lib/test/test_dictviews.py b/Lib/test/test_dictviews.py index 71f1af733f..b585bdd902 100644 --- a/Lib/test/test_dictviews.py +++ b/Lib/test/test_dictviews.py @@ -98,6 +98,7 @@ class DictSetTest(unittest.TestCase): self.assertEqual(d1.viewkeys() & set(d1.viewkeys()), {'a', 'b'}) self.assertEqual(d1.viewkeys() & set(d2.viewkeys()), {'b'}) self.assertEqual(d1.viewkeys() & set(d3.viewkeys()), set()) + self.assertEqual(d1.viewkeys() & tuple(d1.viewkeys()), {'a', 'b'}) self.assertEqual(d1.viewkeys() | d1.viewkeys(), {'a', 'b'}) self.assertEqual(d1.viewkeys() | d2.viewkeys(), {'a', 'b', 'c'}) @@ -106,6 +107,7 @@ class DictSetTest(unittest.TestCase): self.assertEqual(d1.viewkeys() | set(d2.viewkeys()), {'a', 'b', 'c'}) self.assertEqual(d1.viewkeys() | set(d3.viewkeys()), {'a', 'b', 'd', 'e'}) + self.assertEqual(d1.viewkeys() | (1, 2), {'a', 'b', 1, 2}) self.assertEqual(d1.viewkeys() ^ d1.viewkeys(), set()) self.assertEqual(d1.viewkeys() ^ d2.viewkeys(), {'a', 'c'}) @@ -114,6 +116,7 @@ class DictSetTest(unittest.TestCase): self.assertEqual(d1.viewkeys() ^ set(d2.viewkeys()), {'a', 'c'}) self.assertEqual(d1.viewkeys() ^ set(d3.viewkeys()), {'a', 'b', 'd', 'e'}) + self.assertEqual(d1.viewkeys() ^ tuple(d2.keys()), {'a', 'c'}) self.assertEqual(d1.viewkeys() - d1.viewkeys(), set()) self.assertEqual(d1.viewkeys() - d2.viewkeys(), {'a'}) @@ -121,6 +124,7 @@ class DictSetTest(unittest.TestCase): self.assertEqual(d1.viewkeys() - set(d1.viewkeys()), set()) self.assertEqual(d1.viewkeys() - set(d2.viewkeys()), {'a'}) self.assertEqual(d1.viewkeys() - set(d3.viewkeys()), {'a', 'b'}) + self.assertEqual(d1.viewkeys() - (0, 1), {'a', 'b'}) def test_items_set_operations(self): d1 = {'a': 1, 'b': 2} diff --git a/Misc/NEWS b/Misc/NEWS index a89afa1737..61379836ea 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -49,6 +49,9 @@ Core and Builtins __str__, __trunc__, and __float__ returning instances of subclasses of str, long, and float to subclasses of str, long, and float correspondingly. +- Issue #26478: Fix semantic bugs when using binary operators with dictionary + views and tuples. + - Issue #26171: Fix possible integer overflow and heap corruption in zipimporter.get_data(). diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 3e1c5830ec..fe19356de2 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2998,7 +2998,8 @@ dictviews_sub(PyObject* self, PyObject *other) if (result == NULL) return NULL; - tmp = PyObject_CallMethod(result, "difference_update", "O", other); + + tmp = PyObject_CallMethod(result, "difference_update", "(O)", other); if (tmp == NULL) { Py_DECREF(result); return NULL; @@ -3016,7 +3017,7 @@ dictviews_and(PyObject* self, PyObject *other) if (result == NULL) return NULL; - tmp = PyObject_CallMethod(result, "intersection_update", "O", other); + tmp = PyObject_CallMethod(result, "intersection_update", "(O)", other); if (tmp == NULL) { Py_DECREF(result); return NULL; @@ -3034,7 +3035,7 @@ dictviews_or(PyObject* self, PyObject *other) if (result == NULL) return NULL; - tmp = PyObject_CallMethod(result, "update", "O", other); + tmp = PyObject_CallMethod(result, "update", "(O)", other); if (tmp == NULL) { Py_DECREF(result); return NULL; @@ -3052,8 +3053,7 @@ dictviews_xor(PyObject* self, PyObject *other) if (result == NULL) return NULL; - tmp = PyObject_CallMethod(result, "symmetric_difference_update", "O", - other); + tmp = PyObject_CallMethod(result, "symmetric_difference_update", "(O)", other); if (tmp == NULL) { Py_DECREF(result); return NULL;