blob: 927b0e3c90fdf65b2eb66fcb6bc6149e11d6ab92 [file] [log] [blame]
David Aschere2b4b322004-02-18 05:59:53 +00001import unittest
Serhiy Storchaka4a880412013-02-07 15:37:53 +02002import sys
David Aschere2b4b322004-02-18 05:59:53 +00003import os
Neal Norwitz63dfece2004-02-19 02:37:29 +00004from test import test_support
Ezio Melotti794e5572013-05-07 09:34:49 +03005from subprocess import Popen, PIPE
R. David Murray597ebab2009-03-31 18:32:17 +00006
7# Skip this test if the _tkinter module wasn't built.
8_tkinter = test_support.import_module('_tkinter')
9
Serhiy Storchakaceaf6822014-09-06 22:47:02 +030010# Make sure tkinter._fix runs to set up the environment
11tkinter = test_support.import_fresh_module('Tkinter')
12
Guilherme Polo8e5e4382009-02-07 02:20:29 +000013from Tkinter import Tcl
David Aschere2b4b322004-02-18 05:59:53 +000014from _tkinter import TclError
15
Serhiy Storchaka76249ea2014-02-07 10:06:05 +020016try:
17 from _testcapi import INT_MAX, PY_SSIZE_T_MAX
18except ImportError:
19 INT_MAX = PY_SSIZE_T_MAX = sys.maxsize
20
Serhiy Storchaka94025332013-09-08 20:32:56 +030021tcl_version = _tkinter.TCL_VERSION.split('.')
22try:
23 for i in range(len(tcl_version)):
24 tcl_version[i] = int(tcl_version[i])
25except ValueError:
26 pass
27tcl_version = tuple(tcl_version)
28
Serhiy Storchaka15b67d72014-02-02 23:04:06 +020029_tk_patchlevel = None
30def get_tk_patchlevel():
31 global _tk_patchlevel
32 if _tk_patchlevel is None:
33 tcl = Tcl()
34 patchlevel = []
35 for x in tcl.call('info', 'patchlevel').split('.'):
36 try:
37 x = int(x, 10)
38 except ValueError:
39 x = -1
40 patchlevel.append(x)
41 _tk_patchlevel = tuple(patchlevel)
42 return _tk_patchlevel
43
Benjamin Petersonb3619be2009-01-30 02:24:39 +000044
45class TkinterTest(unittest.TestCase):
46
47 def testFlattenLen(self):
48 # flatten(<object with no length>)
49 self.assertRaises(TypeError, _tkinter._flatten, True)
50
51
David Aschere2b4b322004-02-18 05:59:53 +000052class TclTest(unittest.TestCase):
53
54 def setUp(self):
55 self.interp = Tcl()
Serhiy Storchaka5542b152013-12-25 17:28:50 +020056 self.wantobjects = self.interp.tk.wantobjects()
David Aschere2b4b322004-02-18 05:59:53 +000057
58 def testEval(self):
59 tcl = self.interp
60 tcl.eval('set a 1')
61 self.assertEqual(tcl.eval('set a'),'1')
62
63 def testEvalException(self):
64 tcl = self.interp
65 self.assertRaises(TclError,tcl.eval,'set a')
66
67 def testEvalException2(self):
68 tcl = self.interp
69 self.assertRaises(TclError,tcl.eval,'this is wrong')
70
71 def testCall(self):
72 tcl = self.interp
73 tcl.call('set','a','1')
74 self.assertEqual(tcl.call('set','a'),'1')
75
76 def testCallException(self):
77 tcl = self.interp
78 self.assertRaises(TclError,tcl.call,'set','a')
79
80 def testCallException2(self):
81 tcl = self.interp
82 self.assertRaises(TclError,tcl.call,'this','is','wrong')
83
84 def testSetVar(self):
85 tcl = self.interp
86 tcl.setvar('a','1')
87 self.assertEqual(tcl.eval('set a'),'1')
88
89 def testSetVarArray(self):
90 tcl = self.interp
91 tcl.setvar('a(1)','1')
92 self.assertEqual(tcl.eval('set a(1)'),'1')
93
94 def testGetVar(self):
95 tcl = self.interp
96 tcl.eval('set a 1')
97 self.assertEqual(tcl.getvar('a'),'1')
98
99 def testGetVarArray(self):
100 tcl = self.interp
101 tcl.eval('set a(1) 1')
102 self.assertEqual(tcl.getvar('a(1)'),'1')
103
104 def testGetVarException(self):
105 tcl = self.interp
106 self.assertRaises(TclError,tcl.getvar,'a')
107
108 def testGetVarArrayException(self):
109 tcl = self.interp
110 self.assertRaises(TclError,tcl.getvar,'a(1)')
111
112 def testUnsetVar(self):
113 tcl = self.interp
114 tcl.setvar('a',1)
115 self.assertEqual(tcl.eval('info exists a'),'1')
116 tcl.unsetvar('a')
117 self.assertEqual(tcl.eval('info exists a'),'0')
118
119 def testUnsetVarArray(self):
120 tcl = self.interp
121 tcl.setvar('a(1)',1)
122 tcl.setvar('a(2)',2)
123 self.assertEqual(tcl.eval('info exists a(1)'),'1')
124 self.assertEqual(tcl.eval('info exists a(2)'),'1')
125 tcl.unsetvar('a(1)')
126 self.assertEqual(tcl.eval('info exists a(1)'),'0')
127 self.assertEqual(tcl.eval('info exists a(2)'),'1')
128
129 def testUnsetVarException(self):
130 tcl = self.interp
131 self.assertRaises(TclError,tcl.unsetvar,'a')
Tim Peters27f88362004-07-08 04:22:35 +0000132
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300133 def get_integers(self):
134 integers = (0, 1, -1, 2**31-1, -2**31)
135 if tcl_version >= (8, 4): # wideInt was added in Tcl 8.4
136 integers += (2**31, -2**31-1, 2**63-1, -2**63)
137 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
138 integers += (2**63, -2**63-1, 2**1000, -2**1000)
139 return integers
140
Serhiy Storchakad11e8b62014-05-30 14:07:20 +0300141 def test_getint(self):
142 tcl = self.interp.tk
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300143 for i in self.get_integers():
144 result = tcl.getint(' %d ' % i)
145 self.assertEqual(result, i)
146 self.assertIsInstance(result, type(int(result)))
147 self.assertEqual(tcl.getint(' %#o ' % i), i)
148 self.assertEqual(tcl.getint(' %#x ' % i), i)
149 if tcl_version < (8, 5): # bignum was added in Tcl 8.5
150 self.assertRaises(TclError, tcl.getint, str(2**1000))
Serhiy Storchakad11e8b62014-05-30 14:07:20 +0300151 self.assertEqual(tcl.getint(42), 42)
152 self.assertRaises(TypeError, tcl.getint)
153 self.assertRaises(TypeError, tcl.getint, '42', '10')
154 self.assertRaises(TypeError, tcl.getint, 42.0)
155 self.assertRaises(TclError, tcl.getint, 'a')
156 self.assertRaises((TypeError, ValueError, TclError),
157 tcl.getint, '42\0')
158 if test_support.have_unicode:
159 self.assertEqual(tcl.getint(unicode('42')), 42)
160 self.assertRaises((UnicodeEncodeError, ValueError, TclError),
161 tcl.getint, '42' + unichr(0xd800))
162
163 def test_getdouble(self):
164 tcl = self.interp.tk
165 self.assertEqual(tcl.getdouble(' 42 '), 42.0)
166 self.assertEqual(tcl.getdouble(' 42.5 '), 42.5)
167 self.assertEqual(tcl.getdouble(42.5), 42.5)
168 self.assertRaises(TypeError, tcl.getdouble)
169 self.assertRaises(TypeError, tcl.getdouble, '42.5', '10')
170 self.assertRaises(TypeError, tcl.getdouble, 42)
171 self.assertRaises(TclError, tcl.getdouble, 'a')
172 self.assertRaises((TypeError, ValueError, TclError),
173 tcl.getdouble, '42.5\0')
174 if test_support.have_unicode:
175 self.assertEqual(tcl.getdouble(unicode('42.5')), 42.5)
176 self.assertRaises((UnicodeEncodeError, ValueError, TclError),
177 tcl.getdouble, '42.5' + unichr(0xd800))
178
179 def test_getboolean(self):
180 tcl = self.interp.tk
181 self.assertIs(tcl.getboolean('on'), True)
182 self.assertIs(tcl.getboolean('1'), True)
183 self.assertEqual(tcl.getboolean(42), 42)
184 self.assertRaises(TypeError, tcl.getboolean)
185 self.assertRaises(TypeError, tcl.getboolean, 'on', '1')
186 self.assertRaises(TypeError, tcl.getboolean, 1.0)
187 self.assertRaises(TclError, tcl.getboolean, 'a')
188 self.assertRaises((TypeError, ValueError, TclError),
189 tcl.getboolean, 'on\0')
190 if test_support.have_unicode:
191 self.assertIs(tcl.getboolean(unicode('on')), True)
192 self.assertRaises((UnicodeEncodeError, ValueError, TclError),
193 tcl.getboolean, 'on' + unichr(0xd800))
194
David Aschere2b4b322004-02-18 05:59:53 +0000195 def testEvalFile(self):
196 tcl = self.interp
197 filename = "testEvalFile.tcl"
198 fd = open(filename,'w')
199 script = """set a 1
200 set b 2
201 set c [ expr $a + $b ]
202 """
203 fd.write(script)
204 fd.close()
205 tcl.evalfile(filename)
Neal Norwitz9a8d55e2004-02-29 15:37:50 +0000206 os.remove(filename)
David Aschere2b4b322004-02-18 05:59:53 +0000207 self.assertEqual(tcl.eval('set a'),'1')
208 self.assertEqual(tcl.eval('set b'),'2')
209 self.assertEqual(tcl.eval('set c'),'3')
210
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200211 def test_evalfile_null_in_result(self):
212 tcl = self.interp
213 with open(test_support.TESTFN, 'wb') as f:
214 self.addCleanup(test_support.unlink, test_support.TESTFN)
215 f.write("""
216 set a "a\0b"
217 set b "a\\0b"
218 """)
219 tcl.evalfile(test_support.TESTFN)
220 self.assertEqual(tcl.eval('set a'), 'a\xc0\x80b')
221 self.assertEqual(tcl.eval('set b'), 'a\xc0\x80b')
222
David Aschere2b4b322004-02-18 05:59:53 +0000223 def testEvalFileException(self):
224 tcl = self.interp
225 filename = "doesnotexists"
226 try:
227 os.remove(filename)
228 except Exception,e:
229 pass
230 self.assertRaises(TclError,tcl.evalfile,filename)
231
David Aschere2b4b322004-02-18 05:59:53 +0000232 def testPackageRequireException(self):
233 tcl = self.interp
234 self.assertRaises(TclError,tcl.eval,'package require DNE')
235
Zachary Ware57d35c62013-11-03 22:51:25 -0600236 @unittest.skipUnless(sys.platform == 'win32', "only applies to Windows")
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000237 def testLoadWithUNC(self):
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000238 # Build a UNC path from the regular path.
239 # Something like
240 # \\%COMPUTERNAME%\c$\python27\python.exe
241
242 fullname = os.path.abspath(sys.executable)
243 if fullname[1] != ':':
Zachary Ware57d35c62013-11-03 22:51:25 -0600244 self.skipTest('unusable path: %r' % fullname)
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000245 unc_name = r'\\%s\%s$\%s' % (os.environ['COMPUTERNAME'],
246 fullname[0],
247 fullname[3:])
248
249 with test_support.EnvironmentVarGuard() as env:
250 env.unset("TCL_LIBRARY")
Ezio Melotti794e5572013-05-07 09:34:49 +0300251 cmd = '%s -c "import Tkinter; print Tkinter"' % (unc_name,)
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000252
Zachary Ware57d35c62013-11-03 22:51:25 -0600253 try:
254 p = Popen(cmd, stdout=PIPE, stderr=PIPE)
255 except WindowsError as e:
256 if e.winerror == 5:
257 self.skipTest('Not permitted to start the child process')
258 else:
259 raise
260
Ezio Melotti794e5572013-05-07 09:34:49 +0300261 out_data, err_data = p.communicate()
262
263 msg = '\n\n'.join(['"Tkinter.py" not in output',
264 'Command:', cmd,
265 'stdout:', out_data,
266 'stderr:', err_data])
267
268 self.assertIn('Tkinter.py', out_data, msg)
269
270 self.assertEqual(p.wait(), 0, 'Non-zero exit code')
271
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000272
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200273 def test_exprstring(self):
274 tcl = self.interp
275 tcl.call('set', 'a', 3)
276 tcl.call('set', 'b', 6)
277 def check(expr, expected):
278 result = tcl.exprstring(expr)
279 self.assertEqual(result, expected)
280 self.assertIsInstance(result, str)
281
282 self.assertRaises(TypeError, tcl.exprstring)
283 self.assertRaises(TypeError, tcl.exprstring, '8.2', '+6')
284 self.assertRaises(TclError, tcl.exprstring, 'spam')
285 check('', '0')
286 check('8.2 + 6', '14.2')
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200287 check('3.1 + $a', '6.1')
288 check('2 + "$a.$b"', '5.6')
289 check('4*[llength "6 2"]', '8')
290 check('{word one} < "word $a"', '0')
291 check('4*2 < 7', '0')
292 check('hypot($a, 4)', '5.0')
293 check('5 / 4', '1')
294 check('5 / 4.0', '1.25')
295 check('5 / ( [string length "abcd"] + 0.0 )', '1.25')
296 check('20.0/5.0', '4.0')
297 check('"0x03" > "2"', '1')
298 check('[string length "a\xc2\xbd\xe2\x82\xac"]', '3')
299 check(r'[string length "a\xbd\u20ac"]', '3')
300 check('"abc"', 'abc')
301 check('"a\xc2\xbd\xe2\x82\xac"', 'a\xc2\xbd\xe2\x82\xac')
302 check(r'"a\xbd\u20ac"', 'a\xc2\xbd\xe2\x82\xac')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200303 check(r'"a\0b"', 'a\xc0\x80b')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300304 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200305 check('2**64', str(2**64))
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200306
307 def test_exprdouble(self):
308 tcl = self.interp
309 tcl.call('set', 'a', 3)
310 tcl.call('set', 'b', 6)
311 def check(expr, expected):
312 result = tcl.exprdouble(expr)
313 self.assertEqual(result, expected)
314 self.assertIsInstance(result, float)
315
316 self.assertRaises(TypeError, tcl.exprdouble)
317 self.assertRaises(TypeError, tcl.exprdouble, '8.2', '+6')
318 self.assertRaises(TclError, tcl.exprdouble, 'spam')
319 check('', 0.0)
320 check('8.2 + 6', 14.2)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200321 check('3.1 + $a', 6.1)
322 check('2 + "$a.$b"', 5.6)
323 check('4*[llength "6 2"]', 8.0)
324 check('{word one} < "word $a"', 0.0)
325 check('4*2 < 7', 0.0)
326 check('hypot($a, 4)', 5.0)
327 check('5 / 4', 1.0)
328 check('5 / 4.0', 1.25)
329 check('5 / ( [string length "abcd"] + 0.0 )', 1.25)
330 check('20.0/5.0', 4.0)
331 check('"0x03" > "2"', 1.0)
332 check('[string length "a\xc2\xbd\xe2\x82\xac"]', 3.0)
333 check(r'[string length "a\xbd\u20ac"]', 3.0)
334 self.assertRaises(TclError, tcl.exprdouble, '"abc"')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300335 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200336 check('2**64', float(2**64))
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200337
338 def test_exprlong(self):
339 tcl = self.interp
340 tcl.call('set', 'a', 3)
341 tcl.call('set', 'b', 6)
342 def check(expr, expected):
343 result = tcl.exprlong(expr)
344 self.assertEqual(result, expected)
345 self.assertIsInstance(result, int)
346
347 self.assertRaises(TypeError, tcl.exprlong)
348 self.assertRaises(TypeError, tcl.exprlong, '8.2', '+6')
349 self.assertRaises(TclError, tcl.exprlong, 'spam')
350 check('', 0)
351 check('8.2 + 6', 14)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200352 check('3.1 + $a', 6)
353 check('2 + "$a.$b"', 5)
354 check('4*[llength "6 2"]', 8)
355 check('{word one} < "word $a"', 0)
356 check('4*2 < 7', 0)
357 check('hypot($a, 4)', 5)
358 check('5 / 4', 1)
359 check('5 / 4.0', 1)
360 check('5 / ( [string length "abcd"] + 0.0 )', 1)
361 check('20.0/5.0', 4)
362 check('"0x03" > "2"', 1)
363 check('[string length "a\xc2\xbd\xe2\x82\xac"]', 3)
364 check(r'[string length "a\xbd\u20ac"]', 3)
365 self.assertRaises(TclError, tcl.exprlong, '"abc"')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300366 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200367 self.assertRaises(TclError, tcl.exprlong, '2**64')
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200368
369 def test_exprboolean(self):
370 tcl = self.interp
371 tcl.call('set', 'a', 3)
372 tcl.call('set', 'b', 6)
373 def check(expr, expected):
374 result = tcl.exprboolean(expr)
375 self.assertEqual(result, expected)
376 self.assertIsInstance(result, int)
377 self.assertNotIsInstance(result, bool)
378
379 self.assertRaises(TypeError, tcl.exprboolean)
380 self.assertRaises(TypeError, tcl.exprboolean, '8.2', '+6')
381 self.assertRaises(TclError, tcl.exprboolean, 'spam')
382 check('', False)
383 for value in ('0', 'false', 'no', 'off'):
384 check(value, False)
385 check('"%s"' % value, False)
386 check('{%s}' % value, False)
387 for value in ('1', 'true', 'yes', 'on'):
388 check(value, True)
389 check('"%s"' % value, True)
390 check('{%s}' % value, True)
391 check('8.2 + 6', True)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200392 check('3.1 + $a', True)
393 check('2 + "$a.$b"', True)
394 check('4*[llength "6 2"]', True)
395 check('{word one} < "word $a"', False)
396 check('4*2 < 7', False)
397 check('hypot($a, 4)', True)
398 check('5 / 4', True)
399 check('5 / 4.0', True)
400 check('5 / ( [string length "abcd"] + 0.0 )', True)
401 check('20.0/5.0', True)
402 check('"0x03" > "2"', True)
403 check('[string length "a\xc2\xbd\xe2\x82\xac"]', True)
404 check(r'[string length "a\xbd\u20ac"]', True)
405 self.assertRaises(TclError, tcl.exprboolean, '"abc"')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300406 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200407 check('2**64', True)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200408
Serhiy Storchakae8ae0472015-04-02 19:57:52 +0300409 @unittest.skipUnless(tcl_version >= (8, 5), 'requires Tcl version >= 8.5')
Serhiy Storchakacba6b5d2015-04-02 10:35:57 +0300410 def test_booleans(self):
411 tcl = self.interp
412 def check(expr, expected):
413 result = tcl.call('expr', expr)
Serhiy Storchaka91398f82015-04-02 11:46:07 +0300414 if tcl.wantobjects():
415 self.assertEqual(result, expected)
416 self.assertIsInstance(result, int)
417 else:
418 self.assertIn(result, (expr, str(int(expected))))
419 self.assertIsInstance(result, str)
Serhiy Storchakacba6b5d2015-04-02 10:35:57 +0300420 check('true', True)
421 check('yes', True)
422 check('on', True)
423 check('false', False)
424 check('no', False)
425 check('off', False)
426 check('1 < 2', True)
427 check('1 > 2', False)
428
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300429 def test_expr_bignum(self):
430 tcl = self.interp
431 for i in self.get_integers():
432 result = tcl.call('expr', str(i))
433 if self.wantobjects:
434 self.assertEqual(result, i)
435 self.assertIsInstance(result, (int, long))
436 self.assertIsInstance(result, type(int(result)))
437 else:
438 self.assertEqual(result, str(i))
439 self.assertIsInstance(result, str)
440 if tcl_version < (8, 5): # bignum was added in Tcl 8.5
441 result = tcl.call('expr', str(2**1000))
442 self.assertEqual(result, str(2**1000))
443 self.assertIsInstance(result, str)
444
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200445 def test_passing_values(self):
446 def passValue(value):
447 return self.interp.call('set', '_', value)
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200448
449 self.assertEqual(passValue(True), True if self.wantobjects else '1')
450 self.assertEqual(passValue(False), False if self.wantobjects else '0')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200451 self.assertEqual(passValue('string'), 'string')
452 self.assertEqual(passValue('string\xbd'), 'string\xbd')
453 self.assertEqual(passValue('string\xe2\x82\xac'), u'string\u20ac')
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200454 self.assertEqual(passValue(u'string'), u'string')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200455 self.assertEqual(passValue(u'string\xbd'), u'string\xbd')
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200456 self.assertEqual(passValue(u'string\u20ac'), u'string\u20ac')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200457 self.assertEqual(passValue('str\x00ing'), 'str\x00ing')
458 self.assertEqual(passValue('str\xc0\x80ing'), 'str\x00ing')
459 self.assertEqual(passValue(u'str\x00ing'), u'str\x00ing')
460 self.assertEqual(passValue(u'str\x00ing\xbd'), u'str\x00ing\xbd')
461 self.assertEqual(passValue(u'str\x00ing\u20ac'), u'str\x00ing\u20ac')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300462 for i in self.get_integers():
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200463 self.assertEqual(passValue(i), i if self.wantobjects else str(i))
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300464 if tcl_version < (8, 5): # bignum was added in Tcl 8.5
465 self.assertEqual(passValue(2**1000), str(2**1000))
Ezio Melotti0a4a7e12013-02-23 08:19:00 +0200466 for f in (0.0, 1.0, -1.0, 1//3, 1/3.0,
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200467 sys.float_info.min, sys.float_info.max,
468 -sys.float_info.min, -sys.float_info.max):
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200469 if self.wantobjects:
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200470 self.assertEqual(passValue(f), f)
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200471 else:
472 self.assertEqual(float(passValue(f)), f)
473 if self.wantobjects:
474 f = passValue(float('nan'))
475 self.assertNotEqual(f, f)
476 self.assertEqual(passValue(float('inf')), float('inf'))
477 self.assertEqual(passValue(-float('inf')), -float('inf'))
478 else:
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200479 self.assertEqual(float(passValue(float('inf'))), float('inf'))
480 self.assertEqual(float(passValue(-float('inf'))), -float('inf'))
Serhiy Storchaka5fc570f2014-07-07 14:47:17 +0300481 # XXX NaN representation can be not parsable by float()
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200482 self.assertEqual(passValue((1, '2', (3.4,))),
483 (1, '2', (3.4,)) if self.wantobjects else '1 2 3.4')
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000484
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200485 def test_user_command(self):
486 result = []
487 def testfunc(arg):
488 result.append(arg)
489 return arg
490 self.interp.createcommand('testfunc', testfunc)
Antoine Pitrouaa73ea02014-02-23 19:39:06 +0100491 self.addCleanup(self.interp.tk.deletecommand, 'testfunc')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300492 def check(value, expected=None, eq=self.assertEqual):
493 if expected is None:
494 expected = value
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200495 del result[:]
Serhiy Storchaka83515ec2014-01-23 11:03:02 +0200496 r = self.interp.call('testfunc', value)
497 self.assertEqual(len(result), 1)
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200498 self.assertIsInstance(result[0], (str, unicode))
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300499 eq(result[0], expected)
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200500 self.assertIsInstance(r, (str, unicode))
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300501 eq(r, expected)
Serhiy Storchakadc976672014-01-23 14:38:44 +0200502 def float_eq(actual, expected):
Serhiy Storchakaeb7ef942014-01-23 16:08:35 +0200503 self.assertAlmostEqual(float(actual), expected,
504 delta=abs(expected) * 1e-10)
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200505
506 check(True, '1')
507 check(False, '0')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300508 check('string')
509 check('string\xbd')
510 check('string\xe2\x82\xac', u'string\u20ac')
Serhiy Storchaka17c01782014-09-11 10:56:59 +0300511 check('')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300512 check(u'string')
513 check(u'string\xbd')
514 check(u'string\u20ac')
Serhiy Storchaka17c01782014-09-11 10:56:59 +0300515 check(u'')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300516 check('str\xc0\x80ing', u'str\x00ing')
517 check('str\xc0\x80ing\xe2\x82\xac', u'str\x00ing\u20ac')
518 check(u'str\x00ing')
519 check(u'str\x00ing\xbd')
520 check(u'str\x00ing\u20ac')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300521 for i in self.get_integers():
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200522 check(i, str(i))
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300523 if tcl_version < (8, 5): # bignum was added in Tcl 8.5
524 check(2**1000, str(2**1000))
Serhiy Storchakadc976672014-01-23 14:38:44 +0200525 for f in (0.0, 1.0, -1.0):
526 check(f, repr(f))
527 for f in (1/3.0, sys.float_info.min, sys.float_info.max,
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200528 -sys.float_info.min, -sys.float_info.max):
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300529 check(f, eq=float_eq)
530 check(float('inf'), eq=float_eq)
531 check(-float('inf'), eq=float_eq)
Serhiy Storchaka5fc570f2014-07-07 14:47:17 +0300532 # XXX NaN representation can be not parsable by float()
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200533 check((), '')
534 check((1, (2,), (3, 4), '5 6', ()), '1 2 {3 4} {5 6} {}')
535
Serhiy Storchakafab65422013-07-11 20:32:48 +0300536 def test_splitlist(self):
537 splitlist = self.interp.tk.splitlist
538 call = self.interp.tk.call
539 self.assertRaises(TypeError, splitlist)
540 self.assertRaises(TypeError, splitlist, 'a', 'b')
541 self.assertRaises(TypeError, splitlist, 2)
542 testcases = [
543 ('2', ('2',)),
544 ('', ()),
545 ('{}', ('',)),
546 ('""', ('',)),
547 ('a\n b\t\r c\n ', ('a', 'b', 'c')),
548 (u'a\n b\t\r c\n ', ('a', 'b', 'c')),
549 ('a \xe2\x82\xac', ('a', '\xe2\x82\xac')),
550 (u'a \u20ac', ('a', '\xe2\x82\xac')),
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200551 ('a\xc0\x80b c\xc0\x80d', ('a\xc0\x80b', 'c\xc0\x80d')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300552 ('a {b c}', ('a', 'b c')),
553 (r'a b\ c', ('a', 'b c')),
554 (('a', 'b c'), ('a', 'b c')),
555 ('a 2', ('a', '2')),
556 (('a', 2), ('a', 2)),
557 ('a 3.4', ('a', '3.4')),
558 (('a', 3.4), ('a', 3.4)),
559 ((), ()),
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200560 (call('list', 1, '2', (3.4,)),
561 (1, '2', (3.4,)) if self.wantobjects else
562 ('1', '2', '3.4')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300563 ]
Serhiy Storchaka94025332013-09-08 20:32:56 +0300564 if tcl_version >= (8, 5):
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200565 if not self.wantobjects:
566 expected = ('12', '\xe2\x82\xac', '\xe2\x82\xac', '3.4')
567 elif get_tk_patchlevel() < (8, 5, 5):
568 # Before 8.5.5 dicts were converted to lists through string
569 expected = ('12', u'\u20ac', u'\u20ac', '3.4')
570 else:
571 expected = (12, u'\u20ac', u'\u20ac', (3.4,))
Serhiy Storchaka94025332013-09-08 20:32:56 +0300572 testcases += [
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200573 (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)),
574 expected),
Serhiy Storchaka94025332013-09-08 20:32:56 +0300575 ]
Serhiy Storchakafab65422013-07-11 20:32:48 +0300576 for arg, res in testcases:
577 self.assertEqual(splitlist(arg), res)
578 self.assertRaises(TclError, splitlist, '{')
579
580 def test_split(self):
581 split = self.interp.tk.split
582 call = self.interp.tk.call
583 self.assertRaises(TypeError, split)
584 self.assertRaises(TypeError, split, 'a', 'b')
585 self.assertRaises(TypeError, split, 2)
586 testcases = [
587 ('2', '2'),
588 ('', ''),
589 ('{}', ''),
590 ('""', ''),
591 ('{', '{'),
592 ('a\n b\t\r c\n ', ('a', 'b', 'c')),
593 (u'a\n b\t\r c\n ', ('a', 'b', 'c')),
594 ('a \xe2\x82\xac', ('a', '\xe2\x82\xac')),
595 (u'a \u20ac', ('a', '\xe2\x82\xac')),
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200596 ('a\xc0\x80b', 'a\xc0\x80b'),
597 ('a\xc0\x80b c\xc0\x80d', ('a\xc0\x80b', 'c\xc0\x80d')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300598 ('a {b c}', ('a', ('b', 'c'))),
599 (r'a b\ c', ('a', ('b', 'c'))),
600 (('a', 'b c'), ('a', ('b', 'c'))),
601 (('a', u'b c'), ('a', ('b', 'c'))),
602 ('a 2', ('a', '2')),
603 (('a', 2), ('a', 2)),
604 ('a 3.4', ('a', '3.4')),
605 (('a', 3.4), ('a', 3.4)),
606 (('a', (2, 3.4)), ('a', (2, 3.4))),
607 ((), ()),
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200608 (call('list', 1, '2', (3.4,)),
609 (1, '2', (3.4,)) if self.wantobjects else
610 ('1', '2', '3.4')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300611 ]
Serhiy Storchaka94025332013-09-08 20:32:56 +0300612 if tcl_version >= (8, 5):
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200613 if not self.wantobjects:
614 expected = ('12', '\xe2\x82\xac', '\xe2\x82\xac', '3.4')
615 elif get_tk_patchlevel() < (8, 5, 5):
616 # Before 8.5.5 dicts were converted to lists through string
617 expected = ('12', u'\u20ac', u'\u20ac', '3.4')
618 else:
619 expected = (12, u'\u20ac', u'\u20ac', (3.4,))
Serhiy Storchaka94025332013-09-08 20:32:56 +0300620 testcases += [
621 (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)),
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200622 expected),
Serhiy Storchaka94025332013-09-08 20:32:56 +0300623 ]
Serhiy Storchakafab65422013-07-11 20:32:48 +0300624 for arg, res in testcases:
625 self.assertEqual(split(arg), res)
626
Serhiy Storchakaceaf6822014-09-06 22:47:02 +0300627 def test_splitdict(self):
628 splitdict = tkinter._splitdict
629 tcl = self.interp.tk
630
631 arg = '-a {1 2 3} -something foo status {}'
632 self.assertEqual(splitdict(tcl, arg, False),
633 {'-a': '1 2 3', '-something': 'foo', 'status': ''})
634 self.assertEqual(splitdict(tcl, arg),
635 {'a': '1 2 3', 'something': 'foo', 'status': ''})
636
637 arg = ('-a', (1, 2, 3), '-something', 'foo', 'status', '{}')
638 self.assertEqual(splitdict(tcl, arg, False),
639 {'-a': (1, 2, 3), '-something': 'foo', 'status': '{}'})
640 self.assertEqual(splitdict(tcl, arg),
641 {'a': (1, 2, 3), 'something': 'foo', 'status': '{}'})
642
643 self.assertRaises(RuntimeError, splitdict, tcl, '-a b -c ')
644 self.assertRaises(RuntimeError, splitdict, tcl, ('-a', 'b', '-c'))
645
646 arg = tcl.call('list',
647 '-a', (1, 2, 3), '-something', 'foo', 'status', ())
648 self.assertEqual(splitdict(tcl, arg),
649 {'a': (1, 2, 3) if self.wantobjects else '1 2 3',
650 'something': 'foo', 'status': ''})
651
652 if tcl_version >= (8, 5):
653 arg = tcl.call('dict', 'create',
654 '-a', (1, 2, 3), '-something', 'foo', 'status', ())
655 if not self.wantobjects or get_tk_patchlevel() < (8, 5, 5):
656 # Before 8.5.5 dicts were converted to lists through string
657 expected = {'a': '1 2 3', 'something': 'foo', 'status': ''}
658 else:
659 expected = {'a': (1, 2, 3), 'something': 'foo', 'status': ''}
660 self.assertEqual(splitdict(tcl, arg), expected)
661
662
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300663character_size = 4 if sys.maxunicode > 0xFFFF else 2
Neal Norwitz63dfece2004-02-19 02:37:29 +0000664
Serhiy Storchaka42035702013-08-21 21:46:12 +0300665class BigmemTclTest(unittest.TestCase):
666
667 def setUp(self):
668 self.interp = Tcl()
669
Serhiy Storchaka76249ea2014-02-07 10:06:05 +0200670 @test_support.cpython_only
671 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
672 @test_support.precisionbigmemtest(size=INT_MAX + 1, memuse=5, dry_run=False)
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300673 def test_huge_string_call(self, size):
Serhiy Storchaka42035702013-08-21 21:46:12 +0300674 value = ' ' * size
675 self.assertRaises(OverflowError, self.interp.call, 'set', '_', value)
676
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300677 @test_support.cpython_only
678 @unittest.skipUnless(test_support.have_unicode, 'requires unicode support')
679 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
680 @test_support.precisionbigmemtest(size=INT_MAX + 1,
681 memuse=2*character_size + 2,
682 dry_run=False)
683 def test_huge_unicode_call(self, size):
684 value = unicode(' ') * size
685 self.assertRaises(OverflowError, self.interp.call, 'set', '_', value)
686
687
688 @test_support.cpython_only
689 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
690 @test_support.precisionbigmemtest(size=INT_MAX + 1, memuse=9, dry_run=False)
691 def test_huge_string_builtins(self, size):
692 value = '1' + ' ' * size
693 self.check_huge_string_builtins(value)
694
695 @test_support.cpython_only
696 @unittest.skipUnless(test_support.have_unicode, 'requires unicode support')
697 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
698 @test_support.precisionbigmemtest(size=INT_MAX + 1,
699 memuse=2*character_size + 7,
700 dry_run=False)
701 def test_huge_unicode_builtins(self, size):
702 value = unicode('1' + ' ' * size)
703 self.check_huge_string_builtins(value)
704
705 def check_huge_string_builtins(self, value):
706 self.assertRaises(OverflowError, self.interp.tk.getint, value)
707 self.assertRaises(OverflowError, self.interp.tk.getdouble, value)
708 self.assertRaises(OverflowError, self.interp.tk.getboolean, value)
709 self.assertRaises(OverflowError, self.interp.eval, value)
710 self.assertRaises(OverflowError, self.interp.evalfile, value)
711 self.assertRaises(OverflowError, self.interp.record, value)
712 self.assertRaises(OverflowError, self.interp.adderrorinfo, value)
713 self.assertRaises(OverflowError, self.interp.setvar, value, 'x', 'a')
714 self.assertRaises(OverflowError, self.interp.setvar, 'x', value, 'a')
715 self.assertRaises(OverflowError, self.interp.unsetvar, value)
716 self.assertRaises(OverflowError, self.interp.unsetvar, 'x', value)
717 self.assertRaises(OverflowError, self.interp.adderrorinfo, value)
718 self.assertRaises(OverflowError, self.interp.exprstring, value)
719 self.assertRaises(OverflowError, self.interp.exprlong, value)
720 self.assertRaises(OverflowError, self.interp.exprboolean, value)
721 self.assertRaises(OverflowError, self.interp.splitlist, value)
722 self.assertRaises(OverflowError, self.interp.split, value)
723 self.assertRaises(OverflowError, self.interp.createcommand, value, max)
724 self.assertRaises(OverflowError, self.interp.deletecommand, value)
725
Serhiy Storchaka42035702013-08-21 21:46:12 +0300726
Serhiy Storchaka78ecaba2013-11-20 17:44:38 +0200727def setUpModule():
728 if test_support.verbose:
729 tcl = Tcl()
730 print 'patchlevel =', tcl.call('info', 'patchlevel')
731
732
Neal Norwitz63dfece2004-02-19 02:37:29 +0000733def test_main():
Serhiy Storchaka42035702013-08-21 21:46:12 +0300734 test_support.run_unittest(TclTest, TkinterTest, BigmemTclTest)
Neal Norwitz63dfece2004-02-19 02:37:29 +0000735
David Aschere2b4b322004-02-18 05:59:53 +0000736if __name__ == "__main__":
Neal Norwitz63dfece2004-02-19 02:37:29 +0000737 test_main()