blob: d0251aa339c584bd204092c159e5ededc036b836 [file] [log] [blame]
David Aschere2b4b322004-02-18 05:59:53 +00001import unittest
Hirokazu Yamamotodda7fdf2010-09-23 15:28:35 +00002import sys
David Aschere2b4b322004-02-18 05:59:53 +00003import os
Benjamin Petersonee8712c2008-05-20 21:35:26 +00004from test import support
R. David Murraya21e4ca2009-03-31 23:16:50 +00005
6# Skip this test if the _tkinter module wasn't built.
7_tkinter = support.import_module('_tkinter')
8
Terry Jan Reedy743c85a2013-03-16 02:37:06 -04009# Make sure tkinter._fix runs to set up the environment
Serhiy Storchaka8f0a1d02014-09-06 22:47:58 +030010tkinter = support.import_fresh_module('tkinter')
Terry Jan Reedy743c85a2013-03-16 02:37:06 -040011
Guilherme Polofa8fba92009-02-07 02:33:47 +000012from tkinter import Tcl
David Aschere2b4b322004-02-18 05:59:53 +000013from _tkinter import TclError
14
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +020015try:
16 from _testcapi import INT_MAX, PY_SSIZE_T_MAX
17except ImportError:
18 INT_MAX = PY_SSIZE_T_MAX = sys.maxsize
19
Serhiy Storchakadfa689b2013-09-08 20:29:37 +030020tcl_version = _tkinter.TCL_VERSION.split('.')
21try:
22 for i in range(len(tcl_version)):
23 tcl_version[i] = int(tcl_version[i])
24except ValueError:
25 pass
26tcl_version = tuple(tcl_version)
27
Serhiy Storchaka92af06b2014-02-02 23:04:24 +020028_tk_patchlevel = None
29def get_tk_patchlevel():
30 global _tk_patchlevel
31 if _tk_patchlevel is None:
32 tcl = Tcl()
33 patchlevel = []
34 for x in tcl.call('info', 'patchlevel').split('.'):
35 try:
36 x = int(x, 10)
37 except ValueError:
38 x = -1
39 patchlevel.append(x)
40 _tk_patchlevel = tuple(patchlevel)
41 return _tk_patchlevel
42
Benjamin Petersonc4bbc8d2009-01-30 03:39:35 +000043
44class TkinterTest(unittest.TestCase):
45
46 def testFlattenLen(self):
47 # flatten(<object with no length>)
48 self.assertRaises(TypeError, _tkinter._flatten, True)
49
50
David Aschere2b4b322004-02-18 05:59:53 +000051class TclTest(unittest.TestCase):
52
53 def setUp(self):
54 self.interp = Tcl()
Serhiy Storchakacc4290b2013-12-25 17:29:01 +020055 self.wantobjects = self.interp.tk.wantobjects()
David Aschere2b4b322004-02-18 05:59:53 +000056
57 def testEval(self):
58 tcl = self.interp
59 tcl.eval('set a 1')
60 self.assertEqual(tcl.eval('set a'),'1')
61
Serhiy Storchaka1317e142014-02-03 21:24:07 +020062 def test_eval_null_in_result(self):
63 tcl = self.interp
64 self.assertEqual(tcl.eval('set a "a\\0b"'), 'a\x00b')
65
David Aschere2b4b322004-02-18 05:59:53 +000066 def testEvalException(self):
67 tcl = self.interp
68 self.assertRaises(TclError,tcl.eval,'set a')
69
70 def testEvalException2(self):
71 tcl = self.interp
72 self.assertRaises(TclError,tcl.eval,'this is wrong')
73
74 def testCall(self):
75 tcl = self.interp
76 tcl.call('set','a','1')
77 self.assertEqual(tcl.call('set','a'),'1')
78
79 def testCallException(self):
80 tcl = self.interp
81 self.assertRaises(TclError,tcl.call,'set','a')
82
83 def testCallException2(self):
84 tcl = self.interp
85 self.assertRaises(TclError,tcl.call,'this','is','wrong')
86
87 def testSetVar(self):
88 tcl = self.interp
89 tcl.setvar('a','1')
90 self.assertEqual(tcl.eval('set a'),'1')
91
92 def testSetVarArray(self):
93 tcl = self.interp
94 tcl.setvar('a(1)','1')
95 self.assertEqual(tcl.eval('set a(1)'),'1')
96
97 def testGetVar(self):
98 tcl = self.interp
99 tcl.eval('set a 1')
100 self.assertEqual(tcl.getvar('a'),'1')
101
102 def testGetVarArray(self):
103 tcl = self.interp
104 tcl.eval('set a(1) 1')
105 self.assertEqual(tcl.getvar('a(1)'),'1')
106
107 def testGetVarException(self):
108 tcl = self.interp
109 self.assertRaises(TclError,tcl.getvar,'a')
110
111 def testGetVarArrayException(self):
112 tcl = self.interp
113 self.assertRaises(TclError,tcl.getvar,'a(1)')
114
115 def testUnsetVar(self):
116 tcl = self.interp
117 tcl.setvar('a',1)
118 self.assertEqual(tcl.eval('info exists a'),'1')
119 tcl.unsetvar('a')
120 self.assertEqual(tcl.eval('info exists a'),'0')
121
122 def testUnsetVarArray(self):
123 tcl = self.interp
124 tcl.setvar('a(1)',1)
125 tcl.setvar('a(2)',2)
126 self.assertEqual(tcl.eval('info exists a(1)'),'1')
127 self.assertEqual(tcl.eval('info exists a(2)'),'1')
128 tcl.unsetvar('a(1)')
129 self.assertEqual(tcl.eval('info exists a(1)'),'0')
130 self.assertEqual(tcl.eval('info exists a(2)'),'1')
131
132 def testUnsetVarException(self):
133 tcl = self.interp
134 self.assertRaises(TclError,tcl.unsetvar,'a')
Tim Peters27f88362004-07-08 04:22:35 +0000135
Serhiy Storchaka9f1f4f42014-05-30 14:07:38 +0300136 def test_getint(self):
137 tcl = self.interp.tk
138 self.assertEqual(tcl.getint(' 42 '), 42)
139 self.assertEqual(tcl.getint(42), 42)
140 self.assertRaises(TypeError, tcl.getint)
141 self.assertRaises(TypeError, tcl.getint, '42', '10')
142 self.assertRaises(TypeError, tcl.getint, b'42')
143 self.assertRaises(TypeError, tcl.getint, 42.0)
144 self.assertRaises(TclError, tcl.getint, 'a')
145 self.assertRaises((TypeError, ValueError, TclError),
146 tcl.getint, '42\0')
147 self.assertRaises((UnicodeEncodeError, ValueError, TclError),
148 tcl.getint, '42\ud800')
149
150 def test_getdouble(self):
151 tcl = self.interp.tk
152 self.assertEqual(tcl.getdouble(' 42 '), 42.0)
153 self.assertEqual(tcl.getdouble(' 42.5 '), 42.5)
154 self.assertEqual(tcl.getdouble(42.5), 42.5)
155 self.assertRaises(TypeError, tcl.getdouble)
156 self.assertRaises(TypeError, tcl.getdouble, '42.5', '10')
157 self.assertRaises(TypeError, tcl.getdouble, b'42.5')
158 self.assertRaises(TypeError, tcl.getdouble, 42)
159 self.assertRaises(TclError, tcl.getdouble, 'a')
160 self.assertRaises((TypeError, ValueError, TclError),
161 tcl.getdouble, '42.5\0')
162 self.assertRaises((UnicodeEncodeError, ValueError, TclError),
163 tcl.getdouble, '42.5\ud800')
164
165 def test_getboolean(self):
166 tcl = self.interp.tk
167 self.assertIs(tcl.getboolean('on'), True)
168 self.assertIs(tcl.getboolean('1'), True)
169 self.assertEqual(tcl.getboolean(42), 42)
170 self.assertRaises(TypeError, tcl.getboolean)
171 self.assertRaises(TypeError, tcl.getboolean, 'on', '1')
172 self.assertRaises(TypeError, tcl.getboolean, b'on')
173 self.assertRaises(TypeError, tcl.getboolean, 1.0)
174 self.assertRaises(TclError, tcl.getboolean, 'a')
175 self.assertRaises((TypeError, ValueError, TclError),
176 tcl.getboolean, 'on\0')
177 self.assertRaises((UnicodeEncodeError, ValueError, TclError),
178 tcl.getboolean, 'on\ud800')
179
David Aschere2b4b322004-02-18 05:59:53 +0000180 def testEvalFile(self):
181 tcl = self.interp
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200182 with open(support.TESTFN, 'w') as f:
183 self.addCleanup(support.unlink, support.TESTFN)
184 f.write("""set a 1
185 set b 2
186 set c [ expr $a + $b ]
187 """)
188 tcl.evalfile(support.TESTFN)
David Aschere2b4b322004-02-18 05:59:53 +0000189 self.assertEqual(tcl.eval('set a'),'1')
190 self.assertEqual(tcl.eval('set b'),'2')
191 self.assertEqual(tcl.eval('set c'),'3')
192
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200193 def test_evalfile_null_in_result(self):
194 tcl = self.interp
195 with open(support.TESTFN, 'w') as f:
196 self.addCleanup(support.unlink, support.TESTFN)
197 f.write("""
198 set a "a\0b"
199 set b "a\\0b"
200 """)
201 tcl.evalfile(support.TESTFN)
202 self.assertEqual(tcl.eval('set a'), 'a\x00b')
203 self.assertEqual(tcl.eval('set b'), 'a\x00b')
204
David Aschere2b4b322004-02-18 05:59:53 +0000205 def testEvalFileException(self):
206 tcl = self.interp
207 filename = "doesnotexists"
208 try:
209 os.remove(filename)
Guido van Rossumb940e112007-01-10 16:19:56 +0000210 except Exception as e:
David Aschere2b4b322004-02-18 05:59:53 +0000211 pass
212 self.assertRaises(TclError,tcl.evalfile,filename)
213
David Aschere2b4b322004-02-18 05:59:53 +0000214 def testPackageRequireException(self):
215 tcl = self.interp
216 self.assertRaises(TclError,tcl.eval,'package require DNE')
217
Hirokazu Yamamotodda7fdf2010-09-23 15:28:35 +0000218 @unittest.skipUnless(sys.platform == 'win32', 'Requires Windows')
Martin v. Löwis2d5157e2010-06-04 19:50:26 +0000219 def testLoadWithUNC(self):
Martin v. Löwis2d5157e2010-06-04 19:50:26 +0000220 # Build a UNC path from the regular path.
221 # Something like
222 # \\%COMPUTERNAME%\c$\python27\python.exe
223
224 fullname = os.path.abspath(sys.executable)
225 if fullname[1] != ':':
Hirokazu Yamamotodda7fdf2010-09-23 15:28:35 +0000226 raise unittest.SkipTest('Absolute path should have drive part')
Martin v. Löwis2d5157e2010-06-04 19:50:26 +0000227 unc_name = r'\\%s\%s$\%s' % (os.environ['COMPUTERNAME'],
228 fullname[0],
229 fullname[3:])
Hirokazu Yamamotodda7fdf2010-09-23 15:28:35 +0000230 if not os.path.exists(unc_name):
231 raise unittest.SkipTest('Cannot connect to UNC Path')
Martin v. Löwis2d5157e2010-06-04 19:50:26 +0000232
Georg Brandlec5ae3b2010-07-31 19:17:11 +0000233 with support.EnvironmentVarGuard() as env:
Martin v. Löwis2d5157e2010-06-04 19:50:26 +0000234 env.unset("TCL_LIBRARY")
Hirokazu Yamamotof2dec8d2010-09-18 04:42:41 +0000235 f = os.popen('%s -c "import tkinter; print(tkinter)"' % (unc_name,))
Martin v. Löwis2d5157e2010-06-04 19:50:26 +0000236
Hirokazu Yamamotof2dec8d2010-09-18 04:42:41 +0000237 self.assertIn('tkinter', f.read())
Martin v. Löwis2d5157e2010-06-04 19:50:26 +0000238 # exit code must be zero
239 self.assertEqual(f.close(), None)
240
Serhiy Storchakafc055252014-02-03 20:41:34 +0200241 def test_exprstring(self):
242 tcl = self.interp
243 tcl.call('set', 'a', 3)
244 tcl.call('set', 'b', 6)
245 def check(expr, expected):
246 result = tcl.exprstring(expr)
247 self.assertEqual(result, expected)
248 self.assertIsInstance(result, str)
249
250 self.assertRaises(TypeError, tcl.exprstring)
251 self.assertRaises(TypeError, tcl.exprstring, '8.2', '+6')
252 self.assertRaises(TypeError, tcl.exprstring, b'8.2 + 6')
253 self.assertRaises(TclError, tcl.exprstring, 'spam')
254 check('', '0')
255 check('8.2 + 6', '14.2')
Serhiy Storchakafc055252014-02-03 20:41:34 +0200256 check('3.1 + $a', '6.1')
257 check('2 + "$a.$b"', '5.6')
258 check('4*[llength "6 2"]', '8')
259 check('{word one} < "word $a"', '0')
260 check('4*2 < 7', '0')
261 check('hypot($a, 4)', '5.0')
262 check('5 / 4', '1')
263 check('5 / 4.0', '1.25')
264 check('5 / ( [string length "abcd"] + 0.0 )', '1.25')
265 check('20.0/5.0', '4.0')
266 check('"0x03" > "2"', '1')
267 check('[string length "a\xbd\u20ac"]', '3')
268 check(r'[string length "a\xbd\u20ac"]', '3')
269 check('"abc"', 'abc')
270 check('"a\xbd\u20ac"', 'a\xbd\u20ac')
271 check(r'"a\xbd\u20ac"', 'a\xbd\u20ac')
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200272 check(r'"a\0b"', 'a\x00b')
Serhiy Storchaka160f8922014-02-03 22:31:09 +0200273 if tcl_version >= (8, 5):
274 check('2**64', str(2**64))
Serhiy Storchakafc055252014-02-03 20:41:34 +0200275
276 def test_exprdouble(self):
277 tcl = self.interp
278 tcl.call('set', 'a', 3)
279 tcl.call('set', 'b', 6)
280 def check(expr, expected):
281 result = tcl.exprdouble(expr)
282 self.assertEqual(result, expected)
283 self.assertIsInstance(result, float)
284
285 self.assertRaises(TypeError, tcl.exprdouble)
286 self.assertRaises(TypeError, tcl.exprdouble, '8.2', '+6')
287 self.assertRaises(TypeError, tcl.exprdouble, b'8.2 + 6')
288 self.assertRaises(TclError, tcl.exprdouble, 'spam')
289 check('', 0.0)
290 check('8.2 + 6', 14.2)
Serhiy Storchakafc055252014-02-03 20:41:34 +0200291 check('3.1 + $a', 6.1)
292 check('2 + "$a.$b"', 5.6)
293 check('4*[llength "6 2"]', 8.0)
294 check('{word one} < "word $a"', 0.0)
295 check('4*2 < 7', 0.0)
296 check('hypot($a, 4)', 5.0)
297 check('5 / 4', 1.0)
298 check('5 / 4.0', 1.25)
299 check('5 / ( [string length "abcd"] + 0.0 )', 1.25)
300 check('20.0/5.0', 4.0)
301 check('"0x03" > "2"', 1.0)
302 check('[string length "a\xbd\u20ac"]', 3.0)
303 check(r'[string length "a\xbd\u20ac"]', 3.0)
304 self.assertRaises(TclError, tcl.exprdouble, '"abc"')
Serhiy Storchaka160f8922014-02-03 22:31:09 +0200305 if tcl_version >= (8, 5):
306 check('2**64', float(2**64))
Serhiy Storchakafc055252014-02-03 20:41:34 +0200307
308 def test_exprlong(self):
309 tcl = self.interp
310 tcl.call('set', 'a', 3)
311 tcl.call('set', 'b', 6)
312 def check(expr, expected):
313 result = tcl.exprlong(expr)
314 self.assertEqual(result, expected)
315 self.assertIsInstance(result, int)
316
317 self.assertRaises(TypeError, tcl.exprlong)
318 self.assertRaises(TypeError, tcl.exprlong, '8.2', '+6')
319 self.assertRaises(TypeError, tcl.exprlong, b'8.2 + 6')
320 self.assertRaises(TclError, tcl.exprlong, 'spam')
321 check('', 0)
322 check('8.2 + 6', 14)
Serhiy Storchakafc055252014-02-03 20:41:34 +0200323 check('3.1 + $a', 6)
324 check('2 + "$a.$b"', 5)
325 check('4*[llength "6 2"]', 8)
326 check('{word one} < "word $a"', 0)
327 check('4*2 < 7', 0)
328 check('hypot($a, 4)', 5)
329 check('5 / 4', 1)
330 check('5 / 4.0', 1)
331 check('5 / ( [string length "abcd"] + 0.0 )', 1)
332 check('20.0/5.0', 4)
333 check('"0x03" > "2"', 1)
334 check('[string length "a\xbd\u20ac"]', 3)
335 check(r'[string length "a\xbd\u20ac"]', 3)
336 self.assertRaises(TclError, tcl.exprlong, '"abc"')
Serhiy Storchaka160f8922014-02-03 22:31:09 +0200337 if tcl_version >= (8, 5):
338 self.assertRaises(TclError, tcl.exprlong, '2**64')
Serhiy Storchakafc055252014-02-03 20:41:34 +0200339
340 def test_exprboolean(self):
341 tcl = self.interp
342 tcl.call('set', 'a', 3)
343 tcl.call('set', 'b', 6)
344 def check(expr, expected):
345 result = tcl.exprboolean(expr)
346 self.assertEqual(result, expected)
347 self.assertIsInstance(result, int)
348 self.assertNotIsInstance(result, bool)
349
350 self.assertRaises(TypeError, tcl.exprboolean)
351 self.assertRaises(TypeError, tcl.exprboolean, '8.2', '+6')
352 self.assertRaises(TypeError, tcl.exprboolean, b'8.2 + 6')
353 self.assertRaises(TclError, tcl.exprboolean, 'spam')
354 check('', False)
355 for value in ('0', 'false', 'no', 'off'):
356 check(value, False)
357 check('"%s"' % value, False)
358 check('{%s}' % value, False)
359 for value in ('1', 'true', 'yes', 'on'):
360 check(value, True)
361 check('"%s"' % value, True)
362 check('{%s}' % value, True)
363 check('8.2 + 6', True)
Serhiy Storchakafc055252014-02-03 20:41:34 +0200364 check('3.1 + $a', True)
365 check('2 + "$a.$b"', True)
366 check('4*[llength "6 2"]', True)
367 check('{word one} < "word $a"', False)
368 check('4*2 < 7', False)
369 check('hypot($a, 4)', True)
370 check('5 / 4', True)
371 check('5 / 4.0', True)
372 check('5 / ( [string length "abcd"] + 0.0 )', True)
373 check('20.0/5.0', True)
374 check('"0x03" > "2"', True)
375 check('[string length "a\xbd\u20ac"]', True)
376 check(r'[string length "a\xbd\u20ac"]', True)
377 self.assertRaises(TclError, tcl.exprboolean, '"abc"')
Serhiy Storchaka160f8922014-02-03 22:31:09 +0200378 if tcl_version >= (8, 5):
379 check('2**64', True)
Serhiy Storchakafc055252014-02-03 20:41:34 +0200380
Serhiy Storchakadf4bb462013-02-07 15:40:03 +0200381 def test_passing_values(self):
382 def passValue(value):
383 return self.interp.call('set', '_', value)
384
Serhiy Storchakacc4290b2013-12-25 17:29:01 +0200385 self.assertEqual(passValue(True), True if self.wantobjects else '1')
386 self.assertEqual(passValue(False), False if self.wantobjects else '0')
Serhiy Storchakadf4bb462013-02-07 15:40:03 +0200387 self.assertEqual(passValue('string'), 'string')
388 self.assertEqual(passValue('string\u20ac'), 'string\u20ac')
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200389 self.assertEqual(passValue('str\x00ing'), 'str\x00ing')
390 self.assertEqual(passValue('str\x00ing\xbd'), 'str\x00ing\xbd')
391 self.assertEqual(passValue('str\x00ing\u20ac'), 'str\x00ing\u20ac')
Serhiy Storchaka74596a82014-07-30 18:33:13 +0300392 self.assertEqual(passValue(b'str\x00ing'),
393 b'str\x00ing' if self.wantobjects else 'str\x00ing')
394 self.assertEqual(passValue(b'str\xc0\x80ing'),
395 b'str\xc0\x80ing' if self.wantobjects else 'str\xc0\x80ing')
396 self.assertEqual(passValue(b'str\xbding'),
397 b'str\xbding' if self.wantobjects else 'str\xbding')
Serhiy Storchakadf4bb462013-02-07 15:40:03 +0200398 for i in (0, 1, -1, 2**31-1, -2**31):
Serhiy Storchakacc4290b2013-12-25 17:29:01 +0200399 self.assertEqual(passValue(i), i if self.wantobjects else str(i))
Serhiy Storchakadf4bb462013-02-07 15:40:03 +0200400 for f in (0.0, 1.0, -1.0, 1/3,
401 sys.float_info.min, sys.float_info.max,
402 -sys.float_info.min, -sys.float_info.max):
Serhiy Storchakacc4290b2013-12-25 17:29:01 +0200403 if self.wantobjects:
Serhiy Storchakadf4bb462013-02-07 15:40:03 +0200404 self.assertEqual(passValue(f), f)
Serhiy Storchakacc4290b2013-12-25 17:29:01 +0200405 else:
406 self.assertEqual(float(passValue(f)), f)
407 if self.wantobjects:
408 f = passValue(float('nan'))
409 self.assertNotEqual(f, f)
410 self.assertEqual(passValue(float('inf')), float('inf'))
411 self.assertEqual(passValue(-float('inf')), -float('inf'))
412 else:
Serhiy Storchakacc4290b2013-12-25 17:29:01 +0200413 self.assertEqual(float(passValue(float('inf'))), float('inf'))
414 self.assertEqual(float(passValue(-float('inf'))), -float('inf'))
Serhiy Storchaka6f1435c2014-07-07 14:57:08 +0300415 # XXX NaN representation can be not parsable by float()
Serhiy Storchakacc4290b2013-12-25 17:29:01 +0200416 self.assertEqual(passValue((1, '2', (3.4,))),
417 (1, '2', (3.4,)) if self.wantobjects else '1 2 3.4')
Serhiy Storchaka2b00c492014-05-21 17:12:21 +0300418 self.assertEqual(passValue(['a', ['b', 'c']]),
419 ('a', ('b', 'c')) if self.wantobjects else 'a {b c}')
Martin v. Löwis2d5157e2010-06-04 19:50:26 +0000420
Serhiy Storchaka4b730162014-01-23 09:44:05 +0200421 def test_user_command(self):
422 result = None
423 def testfunc(arg):
424 nonlocal result
425 result = arg
426 return arg
427 self.interp.createcommand('testfunc', testfunc)
Antoine Pitrou220cc212014-02-23 19:39:06 +0100428 self.addCleanup(self.interp.tk.deletecommand, 'testfunc')
Serhiy Storchakad6ec3092014-08-18 17:47:29 +0300429 def check(value, expected=None, *, eq=self.assertEqual):
430 if expected is None:
431 expected = value
432 nonlocal result
433 result = None
Serhiy Storchakabdf0cb52014-01-23 16:48:44 +0200434 r = self.interp.call('testfunc', value)
435 self.assertIsInstance(result, str)
436 eq(result, expected)
437 self.assertIsInstance(r, str)
438 eq(r, expected)
439 def float_eq(actual, expected):
Serhiy Storchakabdf0cb52014-01-23 16:48:44 +0200440 self.assertAlmostEqual(float(actual), expected,
441 delta=abs(expected) * 1e-10)
Serhiy Storchaka4b730162014-01-23 09:44:05 +0200442
443 check(True, '1')
444 check(False, '0')
Serhiy Storchakad6ec3092014-08-18 17:47:29 +0300445 check('string')
446 check('string\xbd')
447 check('string\u20ac')
Serhiy Storchakaabf68ce2014-09-11 10:57:13 +0300448 check('')
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200449 check(b'string', 'string')
Serhiy Storchaka74596a82014-07-30 18:33:13 +0300450 check(b'string\xe2\x82\xac', 'string\xe2\x82\xac')
451 check(b'string\xbd', 'string\xbd')
Serhiy Storchakaabf68ce2014-09-11 10:57:13 +0300452 check(b'', '')
Serhiy Storchakad6ec3092014-08-18 17:47:29 +0300453 check('str\x00ing')
454 check('str\x00ing\xbd')
455 check('str\x00ing\u20ac')
Serhiy Storchaka74596a82014-07-30 18:33:13 +0300456 check(b'str\x00ing', 'str\x00ing')
457 check(b'str\xc0\x80ing', 'str\xc0\x80ing')
458 check(b'str\xc0\x80ing\xe2\x82\xac', 'str\xc0\x80ing\xe2\x82\xac')
Serhiy Storchaka4b730162014-01-23 09:44:05 +0200459 for i in (0, 1, -1, 2**31-1, -2**31):
460 check(i, str(i))
Serhiy Storchakabdf0cb52014-01-23 16:48:44 +0200461 for f in (0.0, 1.0, -1.0):
462 check(f, repr(f))
463 for f in (1/3.0, sys.float_info.min, sys.float_info.max,
Serhiy Storchaka4b730162014-01-23 09:44:05 +0200464 -sys.float_info.min, -sys.float_info.max):
Serhiy Storchakad6ec3092014-08-18 17:47:29 +0300465 check(f, eq=float_eq)
466 check(float('inf'), eq=float_eq)
467 check(-float('inf'), eq=float_eq)
Serhiy Storchaka6f1435c2014-07-07 14:57:08 +0300468 # XXX NaN representation can be not parsable by float()
Serhiy Storchaka4b730162014-01-23 09:44:05 +0200469 check((), '')
470 check((1, (2,), (3, 4), '5 6', ()), '1 2 {3 4} {5 6} {}')
Serhiy Storchaka2b00c492014-05-21 17:12:21 +0300471 check([1, [2,], [3, 4], '5 6', []], '1 2 {3 4} {5 6} {}')
Serhiy Storchaka4b730162014-01-23 09:44:05 +0200472
Serhiy Storchaka275d5fd2013-07-11 20:34:47 +0300473 def test_splitlist(self):
474 splitlist = self.interp.tk.splitlist
475 call = self.interp.tk.call
476 self.assertRaises(TypeError, splitlist)
477 self.assertRaises(TypeError, splitlist, 'a', 'b')
478 self.assertRaises(TypeError, splitlist, 2)
479 testcases = [
480 ('2', ('2',)),
481 ('', ()),
482 ('{}', ('',)),
483 ('""', ('',)),
484 ('a\n b\t\r c\n ', ('a', 'b', 'c')),
485 (b'a\n b\t\r c\n ', ('a', 'b', 'c')),
486 ('a \u20ac', ('a', '\u20ac')),
487 (b'a \xe2\x82\xac', ('a', '\u20ac')),
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200488 (b'a\xc0\x80b c\xc0\x80d', ('a\x00b', 'c\x00d')),
Serhiy Storchaka275d5fd2013-07-11 20:34:47 +0300489 ('a {b c}', ('a', 'b c')),
490 (r'a b\ c', ('a', 'b c')),
491 (('a', 'b c'), ('a', 'b c')),
492 ('a 2', ('a', '2')),
493 (('a', 2), ('a', 2)),
494 ('a 3.4', ('a', '3.4')),
495 (('a', 3.4), ('a', 3.4)),
496 ((), ()),
Serhiy Storchaka2b00c492014-05-21 17:12:21 +0300497 ([], ()),
498 (['a', ['b', 'c']], ('a', ['b', 'c'])),
Serhiy Storchakacc4290b2013-12-25 17:29:01 +0200499 (call('list', 1, '2', (3.4,)),
500 (1, '2', (3.4,)) if self.wantobjects else
501 ('1', '2', '3.4')),
Serhiy Storchaka275d5fd2013-07-11 20:34:47 +0300502 ]
Victor Stinnerece38d92014-09-04 09:53:16 +0200503 tk_patchlevel = get_tk_patchlevel()
Serhiy Storchakadfa689b2013-09-08 20:29:37 +0300504 if tcl_version >= (8, 5):
Victor Stinnerece38d92014-09-04 09:53:16 +0200505 if not self.wantobjects or tk_patchlevel < (8, 5, 5):
Serhiy Storchaka92af06b2014-02-02 23:04:24 +0200506 # Before 8.5.5 dicts were converted to lists through string
Serhiy Storchaka74596a82014-07-30 18:33:13 +0300507 expected = ('12', '\u20ac', '\xe2\x82\xac', '3.4')
Serhiy Storchaka92af06b2014-02-02 23:04:24 +0200508 else:
Serhiy Storchaka74596a82014-07-30 18:33:13 +0300509 expected = (12, '\u20ac', b'\xe2\x82\xac', (3.4,))
Serhiy Storchakadfa689b2013-09-08 20:29:37 +0300510 testcases += [
Serhiy Storchaka92af06b2014-02-02 23:04:24 +0200511 (call('dict', 'create', 12, '\u20ac', b'\xe2\x82\xac', (3.4,)),
512 expected),
Serhiy Storchakadfa689b2013-09-08 20:29:37 +0300513 ]
Victor Stinnerece38d92014-09-04 09:53:16 +0200514 dbg_info = ('want objects? %s, Tcl version: %s, Tk patchlevel: %s'
515 % (self.wantobjects, tcl_version, tk_patchlevel))
Serhiy Storchaka275d5fd2013-07-11 20:34:47 +0300516 for arg, res in testcases:
Victor Stinnerece38d92014-09-04 09:53:16 +0200517 self.assertEqual(splitlist(arg), res,
518 'arg=%a, %s' % (arg, dbg_info))
Serhiy Storchaka275d5fd2013-07-11 20:34:47 +0300519 self.assertRaises(TclError, splitlist, '{')
520
521 def test_split(self):
522 split = self.interp.tk.split
523 call = self.interp.tk.call
524 self.assertRaises(TypeError, split)
525 self.assertRaises(TypeError, split, 'a', 'b')
526 self.assertRaises(TypeError, split, 2)
527 testcases = [
528 ('2', '2'),
529 ('', ''),
530 ('{}', ''),
531 ('""', ''),
532 ('{', '{'),
533 ('a\n b\t\r c\n ', ('a', 'b', 'c')),
534 (b'a\n b\t\r c\n ', ('a', 'b', 'c')),
535 ('a \u20ac', ('a', '\u20ac')),
536 (b'a \xe2\x82\xac', ('a', '\u20ac')),
Serhiy Storchaka1317e142014-02-03 21:24:07 +0200537 (b'a\xc0\x80b', 'a\x00b'),
538 (b'a\xc0\x80b c\xc0\x80d', ('a\x00b', 'c\x00d')),
539 (b'{a\xc0\x80b c\xc0\x80d', '{a\x00b c\x00d'),
Serhiy Storchaka275d5fd2013-07-11 20:34:47 +0300540 ('a {b c}', ('a', ('b', 'c'))),
541 (r'a b\ c', ('a', ('b', 'c'))),
542 (('a', b'b c'), ('a', ('b', 'c'))),
543 (('a', 'b c'), ('a', ('b', 'c'))),
544 ('a 2', ('a', '2')),
545 (('a', 2), ('a', 2)),
546 ('a 3.4', ('a', '3.4')),
547 (('a', 3.4), ('a', 3.4)),
548 (('a', (2, 3.4)), ('a', (2, 3.4))),
549 ((), ()),
Serhiy Storchaka2b00c492014-05-21 17:12:21 +0300550 ([], ()),
551 (['a', 'b c'], ('a', ('b', 'c'))),
552 (['a', ['b', 'c']], ('a', ('b', 'c'))),
Serhiy Storchakacc4290b2013-12-25 17:29:01 +0200553 (call('list', 1, '2', (3.4,)),
554 (1, '2', (3.4,)) if self.wantobjects else
555 ('1', '2', '3.4')),
Serhiy Storchaka275d5fd2013-07-11 20:34:47 +0300556 ]
Serhiy Storchakadfa689b2013-09-08 20:29:37 +0300557 if tcl_version >= (8, 5):
Serhiy Storchaka92af06b2014-02-02 23:04:24 +0200558 if not self.wantobjects or get_tk_patchlevel() < (8, 5, 5):
559 # Before 8.5.5 dicts were converted to lists through string
Serhiy Storchaka74596a82014-07-30 18:33:13 +0300560 expected = ('12', '\u20ac', '\xe2\x82\xac', '3.4')
Serhiy Storchaka92af06b2014-02-02 23:04:24 +0200561 else:
Serhiy Storchaka74596a82014-07-30 18:33:13 +0300562 expected = (12, '\u20ac', b'\xe2\x82\xac', (3.4,))
Serhiy Storchakadfa689b2013-09-08 20:29:37 +0300563 testcases += [
564 (call('dict', 'create', 12, '\u20ac', b'\xe2\x82\xac', (3.4,)),
Serhiy Storchaka92af06b2014-02-02 23:04:24 +0200565 expected),
Serhiy Storchakadfa689b2013-09-08 20:29:37 +0300566 ]
Serhiy Storchaka275d5fd2013-07-11 20:34:47 +0300567 for arg, res in testcases:
568 self.assertEqual(split(arg), res, msg=arg)
569
Serhiy Storchaka8f0a1d02014-09-06 22:47:58 +0300570 def test_splitdict(self):
571 splitdict = tkinter._splitdict
572 tcl = self.interp.tk
573
574 arg = '-a {1 2 3} -something foo status {}'
575 self.assertEqual(splitdict(tcl, arg, False),
576 {'-a': '1 2 3', '-something': 'foo', 'status': ''})
577 self.assertEqual(splitdict(tcl, arg),
578 {'a': '1 2 3', 'something': 'foo', 'status': ''})
579
580 arg = ('-a', (1, 2, 3), '-something', 'foo', 'status', '{}')
581 self.assertEqual(splitdict(tcl, arg, False),
582 {'-a': (1, 2, 3), '-something': 'foo', 'status': '{}'})
583 self.assertEqual(splitdict(tcl, arg),
584 {'a': (1, 2, 3), 'something': 'foo', 'status': '{}'})
585
586 self.assertRaises(RuntimeError, splitdict, tcl, '-a b -c ')
587 self.assertRaises(RuntimeError, splitdict, tcl, ('-a', 'b', '-c'))
588
589 arg = tcl.call('list',
590 '-a', (1, 2, 3), '-something', 'foo', 'status', ())
591 self.assertEqual(splitdict(tcl, arg),
592 {'a': (1, 2, 3) if self.wantobjects else '1 2 3',
593 'something': 'foo', 'status': ''})
594
595 if tcl_version >= (8, 5):
596 arg = tcl.call('dict', 'create',
597 '-a', (1, 2, 3), '-something', 'foo', 'status', ())
598 if not self.wantobjects or get_tk_patchlevel() < (8, 5, 5):
599 # Before 8.5.5 dicts were converted to lists through string
600 expected = {'a': '1 2 3', 'something': 'foo', 'status': ''}
601 else:
602 expected = {'a': (1, 2, 3), 'something': 'foo', 'status': ''}
603 self.assertEqual(splitdict(tcl, arg), expected)
604
Neal Norwitz63dfece2004-02-19 02:37:29 +0000605
Serhiy Storchaka9e6b9752013-08-21 21:38:21 +0300606class BigmemTclTest(unittest.TestCase):
607
608 def setUp(self):
609 self.interp = Tcl()
610
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200611 @support.cpython_only
612 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
613 @support.bigmemtest(size=INT_MAX + 1, memuse=5, dry_run=False)
Serhiy Storchaka79851d72014-05-30 14:24:03 +0300614 def test_huge_string_call(self, size):
Serhiy Storchaka9e6b9752013-08-21 21:38:21 +0300615 value = ' ' * size
616 self.assertRaises(OverflowError, self.interp.call, 'set', '_', value)
617
Serhiy Storchaka79851d72014-05-30 14:24:03 +0300618 @support.cpython_only
619 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
620 @support.bigmemtest(size=INT_MAX + 1, memuse=9, dry_run=False)
621 def test_huge_string_builtins(self, size):
622 value = '1' + ' ' * size
Serhiy Storchakaaecfa9e2014-05-30 15:54:35 +0300623 self.assertRaises(OverflowError, self.interp.tk.getint, value)
624 self.assertRaises(OverflowError, self.interp.tk.getdouble, value)
625 self.assertRaises(OverflowError, self.interp.tk.getboolean, value)
Serhiy Storchaka79851d72014-05-30 14:24:03 +0300626 self.assertRaises(OverflowError, self.interp.eval, value)
627 self.assertRaises(OverflowError, self.interp.evalfile, value)
628 self.assertRaises(OverflowError, self.interp.record, value)
629 self.assertRaises(OverflowError, self.interp.adderrorinfo, value)
630 self.assertRaises(OverflowError, self.interp.setvar, value, 'x', 'a')
631 self.assertRaises(OverflowError, self.interp.setvar, 'x', value, 'a')
632 self.assertRaises(OverflowError, self.interp.unsetvar, value)
633 self.assertRaises(OverflowError, self.interp.unsetvar, 'x', value)
634 self.assertRaises(OverflowError, self.interp.adderrorinfo, value)
635 self.assertRaises(OverflowError, self.interp.exprstring, value)
636 self.assertRaises(OverflowError, self.interp.exprlong, value)
637 self.assertRaises(OverflowError, self.interp.exprboolean, value)
638 self.assertRaises(OverflowError, self.interp.splitlist, value)
639 self.assertRaises(OverflowError, self.interp.split, value)
640 self.assertRaises(OverflowError, self.interp.createcommand, value, max)
641 self.assertRaises(OverflowError, self.interp.deletecommand, value)
642
Serhiy Storchaka9e6b9752013-08-21 21:38:21 +0300643
Serhiy Storchaka8db18232013-11-20 17:43:49 +0200644def setUpModule():
645 if support.verbose:
646 tcl = Tcl()
647 print('patchlevel =', tcl.call('info', 'patchlevel'))
648
649
Neal Norwitz63dfece2004-02-19 02:37:29 +0000650def test_main():
Serhiy Storchaka9e6b9752013-08-21 21:38:21 +0300651 support.run_unittest(TclTest, TkinterTest, BigmemTclTest)
Neal Norwitz63dfece2004-02-19 02:37:29 +0000652
David Aschere2b4b322004-02-18 05:59:53 +0000653if __name__ == "__main__":
Neal Norwitz63dfece2004-02-19 02:37:29 +0000654 test_main()