Skip to content

Commit 91d935b

Browse files
[3.12] gh-104496: Use correct Tcl or Tk version in Tkinter tests (GH-107688) (#107709)
gh-104496: Use correct Tcl or Tk version in Tkinter tests (GH-107688) In future Tcl and Tk versions can be desynchronized. (cherry picked from commit 3c8e8f3) Co-authored-by: Serhiy Storchaka <[email protected]>
1 parent 220d7e3 commit 91d935b

File tree

7 files changed

+30
-39
lines changed

7 files changed

+30
-39
lines changed

Lib/test/test_tcl.py

+2-11
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,6 @@
2020

2121
tcl_version = tuple(map(int, _tkinter.TCL_VERSION.split('.')))
2222

23-
_tk_patchlevel = None
24-
def get_tk_patchlevel():
25-
global _tk_patchlevel
26-
if _tk_patchlevel is None:
27-
tcl = Tcl()
28-
_tk_patchlevel = tcl.info_patchlevel()
29-
return _tk_patchlevel
30-
3123

3224
class TkinterTest(unittest.TestCase):
3325

@@ -571,7 +563,6 @@ def test_splitlist(self):
571563
(1, '2', (3.4,)) if self.wantobjects else
572564
('1', '2', '3.4')),
573565
]
574-
tk_patchlevel = get_tk_patchlevel()
575566
if not self.wantobjects:
576567
expected = ('12', '\u20ac', '\xe2\x82\xac', '3.4')
577568
else:
@@ -580,8 +571,8 @@ def test_splitlist(self):
580571
(call('dict', 'create', 12, '\u20ac', b'\xe2\x82\xac', (3.4,)),
581572
expected),
582573
]
583-
dbg_info = ('want objects? %s, Tcl version: %s, Tk patchlevel: %s'
584-
% (self.wantobjects, tcl_version, tk_patchlevel))
574+
dbg_info = ('want objects? %s, Tcl version: %s, Tcl patchlevel: %s'
575+
% (self.wantobjects, tcl_version, self.interp.info_patchlevel()))
585576
for arg, res in testcases:
586577
self.assertEqual(splitlist(arg), res,
587578
'arg=%a, %s' % (arg, dbg_info))

Lib/test/test_tkinter/support.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -79,28 +79,28 @@ def simulate_mouse_click(widget, x, y):
7979

8080
import _tkinter
8181
tcl_version = tuple(map(int, _tkinter.TCL_VERSION.split('.')))
82+
tk_version = tuple(map(int, _tkinter.TK_VERSION.split('.')))
8283

83-
def requires_tcl(*version):
84-
if len(version) <= 2:
85-
return unittest.skipUnless(tcl_version >= version,
86-
'requires Tcl version >= ' + '.'.join(map(str, version)))
84+
def requires_tk(*version):
85+
if len(version) <= 2 and tk_version >= version:
86+
return lambda test: test
8787

8888
def deco(test):
8989
@functools.wraps(test)
9090
def newtest(self):
91-
if get_tk_patchlevel() < version:
92-
self.skipTest('requires Tcl version >= ' +
91+
root = getattr(self, 'root', None)
92+
if get_tk_patchlevel(root) < version:
93+
self.skipTest('requires Tk version >= ' +
9394
'.'.join(map(str, version)))
9495
test(self)
9596
return newtest
9697
return deco
9798

9899
_tk_patchlevel = None
99-
def get_tk_patchlevel():
100+
def get_tk_patchlevel(root):
100101
global _tk_patchlevel
101102
if _tk_patchlevel is None:
102-
tcl = tkinter.Tcl()
103-
_tk_patchlevel = tcl.info_patchlevel()
103+
_tk_patchlevel = tkinter._parse_version(root.tk.globalgetvar('tk_patchLevel'))
104104
return _tk_patchlevel
105105

106106
units = {

Lib/test/test_tkinter/test_images.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import tkinter
33
from test import support
44
from test.support import os_helper
5-
from test.test_tkinter.support import AbstractTkTest, AbstractDefaultRootTest, requires_tcl
5+
from test.test_tkinter.support import AbstractTkTest, AbstractDefaultRootTest, requires_tk
66

77
support.requires('gui')
88

@@ -221,11 +221,11 @@ def test_create_from_gif_file(self):
221221
def test_create_from_gif_data(self):
222222
self.check_create_from_data('gif')
223223

224-
@requires_tcl(8, 6)
224+
@requires_tk(8, 6)
225225
def test_create_from_png_file(self):
226226
self.check_create_from_file('png')
227227

228-
@requires_tcl(8, 6)
228+
@requires_tk(8, 6)
229229
def test_create_from_png_data(self):
230230
self.check_create_from_data('png')
231231

Lib/test/test_tkinter/test_widgets.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import os
55
from test.support import requires
66

7-
from test.test_tkinter.support import (requires_tcl,
7+
from test.test_tkinter.support import (requires_tk,
88
get_tk_patchlevel, widget_eq,
99
AbstractDefaultRootTest)
1010
from test.test_tkinter.widget_tests import (
@@ -613,7 +613,7 @@ def test_configure_inactiveselectbackground(self):
613613
widget = self.create()
614614
self.checkColorParam(widget, 'inactiveselectbackground')
615615

616-
@requires_tcl(8, 6)
616+
@requires_tk(8, 6)
617617
def test_configure_insertunfocussed(self):
618618
widget = self.create()
619619
self.checkEnumParam(widget, 'insertunfocussed',
@@ -924,7 +924,7 @@ def test_coords(self):
924924
for i in range(4):
925925
self.assertIsInstance(coords[i], float)
926926

927-
@requires_tcl(8, 6)
927+
@requires_tk(8, 6)
928928
def test_moveto(self):
929929
widget = self.create()
930930
i1 = widget.create_rectangle(1, 1, 20, 20, tags='group')
@@ -969,7 +969,7 @@ def test_configure_activestyle(self):
969969
self.checkEnumParam(widget, 'activestyle',
970970
'dotbox', 'none', 'underline')
971971

972-
test_configure_justify = requires_tcl(8, 6, 5)(StandardOptionsTests.test_configure_justify)
972+
test_configure_justify = requires_tk(8, 6, 5)(StandardOptionsTests.test_configure_justify)
973973

974974
def test_configure_listvariable(self):
975975
widget = self.create()
@@ -1108,7 +1108,7 @@ def test_configure_digits(self):
11081108

11091109
def test_configure_from(self):
11101110
widget = self.create()
1111-
conv = float if get_tk_patchlevel() >= (8, 6, 10) else float_round
1111+
conv = float if get_tk_patchlevel(self.root) >= (8, 6, 10) else float_round
11121112
self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=conv)
11131113

11141114
def test_configure_label(self):
@@ -1235,19 +1235,19 @@ def test_configure_opaqueresize(self):
12351235
widget = self.create()
12361236
self.checkBooleanParam(widget, 'opaqueresize')
12371237

1238-
@requires_tcl(8, 6, 5)
1238+
@requires_tk(8, 6, 5)
12391239
def test_configure_proxybackground(self):
12401240
widget = self.create()
12411241
self.checkColorParam(widget, 'proxybackground')
12421242

1243-
@requires_tcl(8, 6, 5)
1243+
@requires_tk(8, 6, 5)
12441244
def test_configure_proxyborderwidth(self):
12451245
widget = self.create()
12461246
self.checkPixelsParam(widget, 'proxyborderwidth',
12471247
0, 1.3, 2.9, 6, -2, '10p',
12481248
conv=False)
12491249

1250-
@requires_tcl(8, 6, 5)
1250+
@requires_tk(8, 6, 5)
12511251
def test_configure_proxyrelief(self):
12521252
widget = self.create()
12531253
self.checkReliefParam(widget, 'proxyrelief')

Lib/test/test_tkinter/widget_tests.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Common tests for test_tkinter/test_widgets.py and test_ttk/test_widgets.py
22

33
import tkinter
4-
from test.test_tkinter.support import (AbstractTkTest, tcl_version,
4+
from test.test_tkinter.support import (AbstractTkTest, tk_version,
55
pixels_conv, tcl_obj_eq)
66
import test.support
77

@@ -22,7 +22,7 @@ def scaling(self):
2222
return self._scaling
2323

2424
def _str(self, value):
25-
if not self._stringify and self.wantobjects and tcl_version >= (8, 6):
25+
if not self._stringify and self.wantobjects and tk_version >= (8, 6):
2626
return value
2727
if isinstance(value, tuple):
2828
return ' '.join(map(self._str, value))
@@ -156,7 +156,7 @@ def checkReliefParam(self, widget, name):
156156
'flat', 'groove', 'raised', 'ridge', 'solid', 'sunken')
157157
errmsg='bad relief "spam": must be '\
158158
'flat, groove, raised, ridge, solid, or sunken'
159-
if tcl_version < (8, 6):
159+
if tk_version < (8, 6):
160160
errmsg = None
161161
self.checkInvalidParam(widget, name, 'spam',
162162
errmsg=errmsg)

Lib/test/test_ttk/test_style.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ def test_map_custom_copy(self):
170170
newname = f'C.{name}'
171171
self.assertEqual(style.map(newname), {})
172172
style.map(newname, **default)
173-
if theme == 'alt' and name == '.' and get_tk_patchlevel() < (8, 6, 1):
173+
if theme == 'alt' and name == '.' and get_tk_patchlevel(self.root) < (8, 6, 1):
174174
default['embossed'] = [('disabled', '1')]
175175
self.assertEqual(style.map(newname), default)
176176
for key, value in default.items():

Lib/test/test_ttk/test_widgets.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import sys
66

77
from test.test_ttk_textonly import MockTclObj
8-
from test.test_tkinter.support import (AbstractTkTest, tcl_version, get_tk_patchlevel,
8+
from test.test_tkinter.support import (AbstractTkTest, tk_version, get_tk_patchlevel,
99
simulate_mouse_click, AbstractDefaultRootTest)
1010
from test.test_tkinter.widget_tests import (add_standard_options,
1111
AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests)
@@ -19,7 +19,7 @@ def test_configure_class(self):
1919
widget = self.create()
2020
self.assertEqual(widget['class'], '')
2121
errmsg='attempt to change read-only option'
22-
if get_tk_patchlevel() < (8, 6, 0, 'beta', 3):
22+
if get_tk_patchlevel(self.root) < (8, 6, 0, 'beta', 3):
2323
errmsg='Attempt to change read-only option'
2424
self.checkInvalidParam(widget, 'class', 'Foo', errmsg=errmsg)
2525
widget2 = self.create(class_='Foo')
@@ -560,7 +560,7 @@ def test_configure_orient(self):
560560
widget = self.create()
561561
self.assertEqual(str(widget['orient']), 'vertical')
562562
errmsg='attempt to change read-only option'
563-
if get_tk_patchlevel() < (8, 6, 0, 'beta', 3):
563+
if get_tk_patchlevel(self.root) < (8, 6, 0, 'beta', 3):
564564
errmsg='Attempt to change read-only option'
565565
self.checkInvalidParam(widget, 'orient', 'horizontal',
566566
errmsg=errmsg)
@@ -1526,7 +1526,7 @@ def test_heading(self):
15261526

15271527
def test_heading_callback(self):
15281528
def simulate_heading_click(x, y):
1529-
if tcl_version >= (8, 6):
1529+
if tk_version >= (8, 6):
15301530
self.assertEqual(self.tv.identify_column(x), '#0')
15311531
self.assertEqual(self.tv.identify_region(x, y), 'heading')
15321532
simulate_mouse_click(self.tv, x, y)

0 commit comments

Comments
 (0)