summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2021-07-16 08:34:56 (GMT)
committerGitHub <noreply@github.com>2021-07-16 08:34:56 (GMT)
commitaeaa553d650786afc6e68df1f4813ae1a5b71d05 (patch)
treede8f5af334a132649dc3f7898b012b8a200c9259
parent919ad537510fdc2c750109e0bc4eceea234324b2 (diff)
downloadcpython-aeaa553d650786afc6e68df1f4813ae1a5b71d05.zip
cpython-aeaa553d650786afc6e68df1f4813ae1a5b71d05.tar.gz
cpython-aeaa553d650786afc6e68df1f4813ae1a5b71d05.tar.bz2
bpo-44646: Fix the hash of the union type. (#27179)
It no longer depends on the order of arguments. hash(int | str) == hash(str | int) Co-authored-by: Jack DeVries <58614260+jdevries3133@users.noreply.github.com>
-rw-r--r--Lib/test/test_types.py4
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2021-07-16-09-59-13.bpo-44646.Yb6s05.rst2
-rw-r--r--Objects/unionobject.c10
3 files changed, 12 insertions, 4 deletions
diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py
index 8f529a0..b355558 100644
--- a/Lib/test/test_types.py
+++ b/Lib/test/test_types.py
@@ -663,6 +663,10 @@ class TypesTests(unittest.TestCase):
x.__args__ = [str, int]
(int | str ) == x
+ def test_hash(self):
+ self.assertEqual(hash(int | str), hash(str | int))
+ self.assertEqual(hash(int | str), hash(typing.Union[int, str]))
+
def test_instancecheck(self):
x = int | str
self.assertIsInstance(1, x)
diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-07-16-09-59-13.bpo-44646.Yb6s05.rst b/Misc/NEWS.d/next/Core and Builtins/2021-07-16-09-59-13.bpo-44646.Yb6s05.rst
new file mode 100644
index 0000000..0e28eac
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2021-07-16-09-59-13.bpo-44646.Yb6s05.rst
@@ -0,0 +1,2 @@
+Fix the hash of the union type: it no longer depends on the order of
+arguments.
diff --git a/Objects/unionobject.c b/Objects/unionobject.c
index 8818cc2..85092e6 100644
--- a/Objects/unionobject.c
+++ b/Objects/unionobject.c
@@ -36,11 +36,13 @@ static Py_hash_t
union_hash(PyObject *self)
{
unionobject *alias = (unionobject *)self;
- Py_hash_t h1 = PyObject_Hash(alias->args);
- if (h1 == -1) {
- return -1;
+ PyObject *args = PyFrozenSet_New(alias->args);
+ if (args == NULL) {
+ return (Py_hash_t)-1;
}
- return h1;
+ Py_hash_t hash = PyObject_Hash(args);
+ Py_DECREF(args);
+ return hash;
}
static int