mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
gh-140481: Improve error message when trying to iterate a Tk widget, image or font (GH-140501)
This commit is contained in:
parent
ad0a3f733b
commit
09b1f10ef7
6 changed files with 59 additions and 22 deletions
|
|
@ -1,3 +1,4 @@
|
|||
import collections.abc
|
||||
import unittest
|
||||
import tkinter
|
||||
from tkinter import font
|
||||
|
|
@ -118,6 +119,16 @@ def test_repr(self):
|
|||
repr(self.font), f'<tkinter.font.Font object {fontname!r}>'
|
||||
)
|
||||
|
||||
def test_iterable_protocol(self):
|
||||
self.assertNotIsSubclass(font.Font, collections.abc.Iterable)
|
||||
self.assertNotIsSubclass(font.Font, collections.abc.Container)
|
||||
self.assertNotIsInstance(self.font, collections.abc.Iterable)
|
||||
self.assertNotIsInstance(self.font, collections.abc.Container)
|
||||
with self.assertRaisesRegex(TypeError, 'is not iterable'):
|
||||
iter(self.font)
|
||||
with self.assertRaisesRegex(TypeError, 'is not a container or iterable'):
|
||||
self.font in self.font
|
||||
|
||||
|
||||
class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import collections.abc
|
||||
import unittest
|
||||
import tkinter
|
||||
from test import support
|
||||
|
|
@ -61,7 +62,33 @@ def test_image_create_photo(self):
|
|||
self.assertRaises(RuntimeError, tkinter.PhotoImage)
|
||||
|
||||
|
||||
class BitmapImageTest(AbstractTkTest, unittest.TestCase):
|
||||
class BaseImageTest:
|
||||
def create(self):
|
||||
return self.image_class('::img::test', master=self.root,
|
||||
file=self.testfile)
|
||||
|
||||
def test_bug_100814(self):
|
||||
# gh-100814: Passing a callable option value causes AttributeError.
|
||||
with self.assertRaises(tkinter.TclError):
|
||||
self.image_class('::img::test', master=self.root, spam=print)
|
||||
image = self.image_class('::img::test', master=self.root)
|
||||
with self.assertRaises(tkinter.TclError):
|
||||
image.configure(spam=print)
|
||||
|
||||
def test_iterable_protocol(self):
|
||||
image = self.create()
|
||||
self.assertNotIsSubclass(self.image_class, collections.abc.Iterable)
|
||||
self.assertNotIsSubclass(self.image_class, collections.abc.Container)
|
||||
self.assertNotIsInstance(image, collections.abc.Iterable)
|
||||
self.assertNotIsInstance(image, collections.abc.Container)
|
||||
with self.assertRaisesRegex(TypeError, 'is not iterable'):
|
||||
iter(image)
|
||||
with self.assertRaisesRegex(TypeError, 'is not a container or iterable'):
|
||||
image in image
|
||||
|
||||
|
||||
class BitmapImageTest(BaseImageTest, AbstractTkTest, unittest.TestCase):
|
||||
image_class = tkinter.BitmapImage
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
|
|
@ -144,26 +171,15 @@ def test_configure_foreground(self):
|
|||
self.assertEqual(image['foreground'],
|
||||
'-foreground {} {} #000000 yellow')
|
||||
|
||||
def test_bug_100814(self):
|
||||
# gh-100814: Passing a callable option value causes AttributeError.
|
||||
with self.assertRaises(tkinter.TclError):
|
||||
tkinter.BitmapImage('::img::test', master=self.root, spam=print)
|
||||
image = tkinter.BitmapImage('::img::test', master=self.root)
|
||||
with self.assertRaises(tkinter.TclError):
|
||||
image.configure(spam=print)
|
||||
|
||||
|
||||
class PhotoImageTest(AbstractTkTest, unittest.TestCase):
|
||||
class PhotoImageTest(BaseImageTest, AbstractTkTest, unittest.TestCase):
|
||||
image_class = tkinter.PhotoImage
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
AbstractTkTest.setUpClass.__func__(cls)
|
||||
cls.testfile = support.findfile('python.gif', subdir='tkinterdata')
|
||||
|
||||
def create(self):
|
||||
return tkinter.PhotoImage('::img::test', master=self.root,
|
||||
file=self.testfile)
|
||||
|
||||
def colorlist(self, *args):
|
||||
if tkinter.TkVersion >= 8.6 and self.wantobjects:
|
||||
return args
|
||||
|
|
@ -282,14 +298,6 @@ def test_configure_palette(self):
|
|||
image.configure(palette='3/4/2')
|
||||
self.assertEqual(image['palette'], '3/4/2')
|
||||
|
||||
def test_bug_100814(self):
|
||||
# gh-100814: Passing a callable option value causes AttributeError.
|
||||
with self.assertRaises(tkinter.TclError):
|
||||
tkinter.PhotoImage('::img::test', master=self.root, spam=print)
|
||||
image = tkinter.PhotoImage('::img::test', master=self.root)
|
||||
with self.assertRaises(tkinter.TclError):
|
||||
image.configure(spam=print)
|
||||
|
||||
def test_blank(self):
|
||||
image = self.create()
|
||||
image.blank()
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import collections.abc
|
||||
import functools
|
||||
import unittest
|
||||
import tkinter
|
||||
|
|
@ -508,6 +509,17 @@ def test_embedded_null(self):
|
|||
widget.selection_range(0, 'end')
|
||||
self.assertEqual(widget.selection_get(), '\u20ac\0abc\x00def')
|
||||
|
||||
def test_iterable_protocol(self):
|
||||
widget = tkinter.Entry(self.root)
|
||||
self.assertNotIsSubclass(tkinter.Entry, collections.abc.Iterable)
|
||||
self.assertNotIsSubclass(tkinter.Entry, collections.abc.Container)
|
||||
self.assertNotIsInstance(widget, collections.abc.Iterable)
|
||||
self.assertNotIsInstance(widget, collections.abc.Container)
|
||||
with self.assertRaisesRegex(TypeError, 'is not iterable'):
|
||||
iter(widget)
|
||||
with self.assertRaisesRegex(TypeError, 'is not a container or iterable'):
|
||||
widget in widget
|
||||
|
||||
|
||||
class WmTest(AbstractTkTest, unittest.TestCase):
|
||||
|
||||
|
|
|
|||
|
|
@ -1848,6 +1848,7 @@ def cget(self, key):
|
|||
return self.tk.call(self._w, 'cget', '-' + key)
|
||||
|
||||
__getitem__ = cget
|
||||
__iter__ = None # prevent using __getitem__ for iteration
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
self.configure({key: value})
|
||||
|
|
@ -4280,6 +4281,8 @@ def __setitem__(self, key, value):
|
|||
def __getitem__(self, key):
|
||||
return self.tk.call(self.name, 'configure', '-'+key)
|
||||
|
||||
__iter__ = None # prevent using __getitem__ for iteration
|
||||
|
||||
def configure(self, **kw):
|
||||
"""Configure the image."""
|
||||
res = ()
|
||||
|
|
|
|||
|
|
@ -114,6 +114,8 @@ def __getitem__(self, key):
|
|||
def __setitem__(self, key, value):
|
||||
self.configure(**{key: value})
|
||||
|
||||
__iter__ = None # prevent using __getitem__ for iteration
|
||||
|
||||
def __del__(self):
|
||||
try:
|
||||
if self.delete_font:
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
Improve error message when trying to iterate a Tk widget, image or font.
|
||||
Loading…
Add table
Add a link
Reference in a new issue