This is an automated email from the ASF dual-hosted git repository.

dianfu pushed a commit to branch release-2.3
in repository https://gitbox.apache.org/repos/asf/flink.git


The following commit(s) were added to refs/heads/release-2.3 by this push:
     new 43450c9edd6 [FLINK-40986][python] Make named Row hashing consistent 
with equality (#29472)
43450c9edd6 is described below

commit 43450c9edd6ac5f3c5c3732a2a208ee55a5f2580
Author: Biao Geng <[email protected]>
AuthorDate: Wed Oct 14 13:20:38 2026 +0800

    [FLINK-40986][python] Make named Row hashing consistent with equality 
(#29472)
---
 flink-python/pyflink/common/tests/test_types.py | 71 +++++++++++++++++++++++++
 flink-python/pyflink/common/types.py            |  2 +
 2 files changed, 73 insertions(+)

diff --git a/flink-python/pyflink/common/tests/test_types.py 
b/flink-python/pyflink/common/tests/test_types.py
new file mode 100644
index 00000000000..50d462d8986
--- /dev/null
+++ b/flink-python/pyflink/common/tests/test_types.py
@@ -0,0 +1,71 @@
+################################################################################
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+# limitations under the License.
+################################################################################
+
+import unittest
+
+from pyflink.common import Row, RowKind
+
+
+class RowTests(unittest.TestCase):
+
+    def test_named_row_hash(self):
+        for row_kind in RowKind:
+            for other in [Row(b=2, a=1), Row('b', 'a')(2, 1)]:
+                with self.subTest(row_kind=row_kind, other=other):
+                    row = Row(a=1, b=2)
+                    row.set_row_kind(row_kind)
+                    other.set_row_kind(row_kind)
+                    self.assertEqual(row, other)
+                    self.assertEqual(hash(row), hash(other))
+                    self.assertEqual(tuple(other), (2, 1))
+                    self.assertEqual(list(other.as_dict()), ['b', 'a'])
+
+    def test_named_row_set(self):
+        self.assertEqual(len({Row(a=1, b=2), Row(b=2, a=1)}), 1)
+
+    def test_named_row_dict(self):
+        values = {Row(a=1, b=2): 'value'}
+        self.assertEqual(values[Row(b=2, a=1)], 'value')
+        values[Row(b=2, a=1)] = 'updated'
+        self.assertEqual(len(values), 1)
+        self.assertEqual(values[Row(a=1, b=2)], 'updated')
+
+    def test_positional_row_hash(self):
+        for values in [(), (1, 2), (2, 1)]:
+            with self.subTest(values=values):
+                self.assertEqual(hash(Row(*values)), hash(values))
+                self.assertEqual(len({Row(*values), Row(*values)}), 1)
+        self.assertEqual(len({Row(1, 2), Row(2, 1)}), 2)
+
+    def test_nested_row_hash(self):
+        row = Row(a=Row(x=1, y=2), b=3)
+        other = Row(b=3, a=Row(y=2, x=1))
+        self.assertEqual(row, other)
+        self.assertEqual(hash(row), hash(other))
+        self.assertEqual(len({row, other}), 1)
+
+    def test_unhashable_row_fields(self):
+        for value in [[1, 2], {'a': 1}]:
+            for row in [Row(value), Row(a=value)]:
+                with self.subTest(row=row):
+                    with self.assertRaises(TypeError):
+                        hash(row)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/flink-python/pyflink/common/types.py 
b/flink-python/pyflink/common/types.py
index 894a4e89cd2..2547266581a 100644
--- a/flink-python/pyflink/common/types.py
+++ b/flink-python/pyflink/common/types.py
@@ -278,6 +278,8 @@ class Row(object):
                     self._values == other._values)
 
     def __hash__(self):
+        if hasattr(self, "_fields"):
+            return hash(frozenset(zip(self._fields, self._values)))
         return tuple(self).__hash__()
 
     def __iter__(self):

Reply via email to