]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.8] bpo-42759: Fix equality comparison of Variable and Font in Tkinter (GH-23968...
authorSerhiy Storchaka <storchaka@gmail.com>
Fri, 1 Jan 2021 17:39:36 +0000 (19:39 +0200)
committerGitHub <noreply@github.com>
Fri, 1 Jan 2021 17:39:36 +0000 (19:39 +0200)
Objects which belong to different Tcl interpreters are now always
different, even if they have the same name.
(cherry picked from commit 1df56bc0597a051c13d53514e120e9b6764185f8)

Lib/tkinter/__init__.py
Lib/tkinter/font.py
Lib/tkinter/test/test_tkinter/test_font.py
Lib/tkinter/test/test_tkinter/test_variables.py
Misc/NEWS.d/next/Library/2020-12-27-22-19-26.bpo-42759.lGi_03.rst [new file with mode: 0644]

index f9ece257841a96f6f60f7e005528277d9d2335ae..91a6d56480e630815fab8bf76a449cefdc180310 100644 (file)
@@ -491,13 +491,11 @@ class Variable:
             self._tk.call("trace", "vinfo", self._name))]
 
     def __eq__(self, other):
-        """Comparison for equality (==).
-
-        Note: if the Variable's master matters to behavior
-        also compare self._master == other._master
-        """
-        return self.__class__.__name__ == other.__class__.__name__ \
-            and self._name == other._name
+        if not isinstance(other, Variable):
+            return NotImplemented
+        return (self._name == other._name
+                and self.__class__.__name__ == other.__class__.__name__
+                and self._tk == other._tk)
 
 
 class StringVar(Variable):
index 31d9afd8f866ca294906f3e465bd9ed3eef87d0f..225ec6d34def96b6948875e8ed4abc864ec6e841 100644 (file)
@@ -100,7 +100,9 @@ class Font:
         return self.name
 
     def __eq__(self, other):
-        return isinstance(other, Font) and self.name == other.name
+        if not isinstance(other, Font):
+            return NotImplemented
+        return self.name == other.name and self._tk == other._tk
 
     def __getitem__(self, key):
         return self.cget(key)
index 2ea59f1748342349b6698153a785d3858d3ad753..5c6f048512850addd614c5ab6af8cae900724e1a 100644 (file)
@@ -63,14 +63,21 @@ class FontTest(AbstractTkTest, unittest.TestCase):
         self.assertEqual(self.font.name, fontname)
         self.assertEqual(str(self.font), fontname)
 
-    def test_eq(self):
+    def test_equality(self):
         font1 = font.Font(root=self.root, name=fontname, exists=True)
         font2 = font.Font(root=self.root, name=fontname, exists=True)
         self.assertIsNot(font1, font2)
         self.assertEqual(font1, font2)
         self.assertNotEqual(font1, font1.copy())
+
         self.assertNotEqual(font1, 0)
 
+        root2 = tkinter.Tk()
+        self.addCleanup(root2.destroy)
+        font3 = font.Font(root=root2, name=fontname, exists=True)
+        self.assertEqual(str(font1), str(font3))
+        self.assertNotEqual(font1, font3)
+
     def test_measure(self):
         self.assertIsInstance(self.font.measure('abc'), int)
 
index e7b24a818f1501e96656754cb287eab4b70a368a..cccec62941353fde1f781192a1a30b2515b4ba01 100644 (file)
@@ -1,6 +1,7 @@
 import unittest
 import gc
 import tkinter
+from test.support import ALWAYS_EQ
 from tkinter import (Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl,
                      TclError)
 from tkinter.test.support import AbstractDefaultRootTest
@@ -57,15 +58,30 @@ class TestVariable(TestBase):
         del v2
         self.assertFalse(self.info_exists("name"))
 
-    def test___eq__(self):
+    def test_equality(self):
         # values doesn't matter, only class and name are checked
         v1 = Variable(self.root, name="abc")
         v2 = Variable(self.root, name="abc")
         self.assertEqual(v1, v2)
 
-        v3 = Variable(self.root, name="abc")
+        v3 = Variable(self.root, name="cba")
+        self.assertNotEqual(v1, v3)
+
         v4 = StringVar(self.root, name="abc")
-        self.assertNotEqual(v3, v4)
+        self.assertEqual(str(v1), str(v4))
+        self.assertNotEqual(v1, v4)
+
+        V = type('Variable', (), {})
+        self.assertNotEqual(v1, V())
+
+        self.assertNotEqual(v1, object())
+        self.assertEqual(v1, ALWAYS_EQ)
+
+        root2 = tkinter.Tk()
+        self.addCleanup(root2.destroy)
+        v5 = Variable(root2, name="abc")
+        self.assertEqual(str(v1), str(v5))
+        self.assertNotEqual(v1, v5)
 
     def test_invalid_name(self):
         with self.assertRaises(TypeError):
diff --git a/Misc/NEWS.d/next/Library/2020-12-27-22-19-26.bpo-42759.lGi_03.rst b/Misc/NEWS.d/next/Library/2020-12-27-22-19-26.bpo-42759.lGi_03.rst
new file mode 100644 (file)
index 0000000..a5ec7d5
--- /dev/null
@@ -0,0 +1,3 @@
+Fixed equality comparison of :class:`tkinter.Variable` and
+:class:`tkinter.font.Font`. Objects which belong to different Tcl
+interpreters are now always different, even if they have the same name.