blob: 4167588e627f997a5e403f1b12d1fa1a98b5af2b [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)))
Serhiy Storchaka61ad42e2015-04-02 20:06:48 +0300147 if tcl_version >= (8, 5):
148 self.assertEqual(tcl.getint(' {:#o} '.format(i)), i)
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300149 self.assertEqual(tcl.getint(' %#o ' % i), i)
150 self.assertEqual(tcl.getint(' %#x ' % i), i)
151 if tcl_version < (8, 5): # bignum was added in Tcl 8.5
152 self.assertRaises(TclError, tcl.getint, str(2**1000))
Serhiy Storchakad11e8b62014-05-30 14:07:20 +0300153 self.assertEqual(tcl.getint(42), 42)
154 self.assertRaises(TypeError, tcl.getint)
155 self.assertRaises(TypeError, tcl.getint, '42', '10')
156 self.assertRaises(TypeError, tcl.getint, 42.0)
157 self.assertRaises(TclError, tcl.getint, 'a')
158 self.assertRaises((TypeError, ValueError, TclError),
159 tcl.getint, '42\0')
160 if test_support.have_unicode:
161 self.assertEqual(tcl.getint(unicode('42')), 42)
162 self.assertRaises((UnicodeEncodeError, ValueError, TclError),
163 tcl.getint, '42' + unichr(0xd800))
164
165 def test_getdouble(self):
166 tcl = self.interp.tk
167 self.assertEqual(tcl.getdouble(' 42 '), 42.0)
168 self.assertEqual(tcl.getdouble(' 42.5 '), 42.5)
169 self.assertEqual(tcl.getdouble(42.5), 42.5)
170 self.assertRaises(TypeError, tcl.getdouble)
171 self.assertRaises(TypeError, tcl.getdouble, '42.5', '10')
172 self.assertRaises(TypeError, tcl.getdouble, 42)
173 self.assertRaises(TclError, tcl.getdouble, 'a')
174 self.assertRaises((TypeError, ValueError, TclError),
175 tcl.getdouble, '42.5\0')
176 if test_support.have_unicode:
177 self.assertEqual(tcl.getdouble(unicode('42.5')), 42.5)
178 self.assertRaises((UnicodeEncodeError, ValueError, TclError),
179 tcl.getdouble, '42.5' + unichr(0xd800))
180
181 def test_getboolean(self):
182 tcl = self.interp.tk
183 self.assertIs(tcl.getboolean('on'), True)
184 self.assertIs(tcl.getboolean('1'), True)
Serhiy Storchakaf29bc702015-04-04 12:42:25 +0300185 self.assertIs(tcl.getboolean(u'on'), True)
186 self.assertIs(tcl.getboolean(u'1'), True)
187 self.assertIs(tcl.getboolean(42), True)
188 self.assertIs(tcl.getboolean(0), False)
189 self.assertIs(tcl.getboolean(42L), True)
190 self.assertIs(tcl.getboolean(0L), False)
Serhiy Storchakad11e8b62014-05-30 14:07:20 +0300191 self.assertRaises(TypeError, tcl.getboolean)
192 self.assertRaises(TypeError, tcl.getboolean, 'on', '1')
193 self.assertRaises(TypeError, tcl.getboolean, 1.0)
194 self.assertRaises(TclError, tcl.getboolean, 'a')
195 self.assertRaises((TypeError, ValueError, TclError),
196 tcl.getboolean, 'on\0')
197 if test_support.have_unicode:
198 self.assertIs(tcl.getboolean(unicode('on')), True)
199 self.assertRaises((UnicodeEncodeError, ValueError, TclError),
200 tcl.getboolean, 'on' + unichr(0xd800))
201
David Aschere2b4b322004-02-18 05:59:53 +0000202 def testEvalFile(self):
203 tcl = self.interp
204 filename = "testEvalFile.tcl"
205 fd = open(filename,'w')
206 script = """set a 1
207 set b 2
208 set c [ expr $a + $b ]
209 """
210 fd.write(script)
211 fd.close()
212 tcl.evalfile(filename)
Neal Norwitz9a8d55e2004-02-29 15:37:50 +0000213 os.remove(filename)
David Aschere2b4b322004-02-18 05:59:53 +0000214 self.assertEqual(tcl.eval('set a'),'1')
215 self.assertEqual(tcl.eval('set b'),'2')
216 self.assertEqual(tcl.eval('set c'),'3')
217
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200218 def test_evalfile_null_in_result(self):
219 tcl = self.interp
220 with open(test_support.TESTFN, 'wb') as f:
221 self.addCleanup(test_support.unlink, test_support.TESTFN)
222 f.write("""
223 set a "a\0b"
224 set b "a\\0b"
225 """)
226 tcl.evalfile(test_support.TESTFN)
227 self.assertEqual(tcl.eval('set a'), 'a\xc0\x80b')
228 self.assertEqual(tcl.eval('set b'), 'a\xc0\x80b')
229
David Aschere2b4b322004-02-18 05:59:53 +0000230 def testEvalFileException(self):
231 tcl = self.interp
232 filename = "doesnotexists"
233 try:
234 os.remove(filename)
235 except Exception,e:
236 pass
237 self.assertRaises(TclError,tcl.evalfile,filename)
238
David Aschere2b4b322004-02-18 05:59:53 +0000239 def testPackageRequireException(self):
240 tcl = self.interp
241 self.assertRaises(TclError,tcl.eval,'package require DNE')
242
Zachary Ware57d35c62013-11-03 22:51:25 -0600243 @unittest.skipUnless(sys.platform == 'win32', "only applies to Windows")
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000244 def testLoadWithUNC(self):
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000245 # Build a UNC path from the regular path.
246 # Something like
247 # \\%COMPUTERNAME%\c$\python27\python.exe
248
249 fullname = os.path.abspath(sys.executable)
250 if fullname[1] != ':':
Zachary Ware57d35c62013-11-03 22:51:25 -0600251 self.skipTest('unusable path: %r' % fullname)
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000252 unc_name = r'\\%s\%s$\%s' % (os.environ['COMPUTERNAME'],
253 fullname[0],
254 fullname[3:])
255
256 with test_support.EnvironmentVarGuard() as env:
257 env.unset("TCL_LIBRARY")
Ezio Melotti794e5572013-05-07 09:34:49 +0300258 cmd = '%s -c "import Tkinter; print Tkinter"' % (unc_name,)
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000259
Zachary Ware57d35c62013-11-03 22:51:25 -0600260 try:
261 p = Popen(cmd, stdout=PIPE, stderr=PIPE)
262 except WindowsError as e:
263 if e.winerror == 5:
264 self.skipTest('Not permitted to start the child process')
265 else:
266 raise
267
Ezio Melotti794e5572013-05-07 09:34:49 +0300268 out_data, err_data = p.communicate()
269
270 msg = '\n\n'.join(['"Tkinter.py" not in output',
271 'Command:', cmd,
272 'stdout:', out_data,
273 'stderr:', err_data])
274
275 self.assertIn('Tkinter.py', out_data, msg)
276
277 self.assertEqual(p.wait(), 0, 'Non-zero exit code')
278
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000279
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200280 def test_exprstring(self):
281 tcl = self.interp
282 tcl.call('set', 'a', 3)
283 tcl.call('set', 'b', 6)
284 def check(expr, expected):
285 result = tcl.exprstring(expr)
286 self.assertEqual(result, expected)
287 self.assertIsInstance(result, str)
288
289 self.assertRaises(TypeError, tcl.exprstring)
290 self.assertRaises(TypeError, tcl.exprstring, '8.2', '+6')
291 self.assertRaises(TclError, tcl.exprstring, 'spam')
292 check('', '0')
293 check('8.2 + 6', '14.2')
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200294 check('3.1 + $a', '6.1')
295 check('2 + "$a.$b"', '5.6')
296 check('4*[llength "6 2"]', '8')
297 check('{word one} < "word $a"', '0')
298 check('4*2 < 7', '0')
299 check('hypot($a, 4)', '5.0')
300 check('5 / 4', '1')
301 check('5 / 4.0', '1.25')
302 check('5 / ( [string length "abcd"] + 0.0 )', '1.25')
303 check('20.0/5.0', '4.0')
304 check('"0x03" > "2"', '1')
305 check('[string length "a\xc2\xbd\xe2\x82\xac"]', '3')
306 check(r'[string length "a\xbd\u20ac"]', '3')
307 check('"abc"', 'abc')
308 check('"a\xc2\xbd\xe2\x82\xac"', 'a\xc2\xbd\xe2\x82\xac')
309 check(r'"a\xbd\u20ac"', 'a\xc2\xbd\xe2\x82\xac')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200310 check(r'"a\0b"', 'a\xc0\x80b')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300311 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200312 check('2**64', str(2**64))
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200313
314 def test_exprdouble(self):
315 tcl = self.interp
316 tcl.call('set', 'a', 3)
317 tcl.call('set', 'b', 6)
318 def check(expr, expected):
319 result = tcl.exprdouble(expr)
320 self.assertEqual(result, expected)
321 self.assertIsInstance(result, float)
322
323 self.assertRaises(TypeError, tcl.exprdouble)
324 self.assertRaises(TypeError, tcl.exprdouble, '8.2', '+6')
325 self.assertRaises(TclError, tcl.exprdouble, 'spam')
326 check('', 0.0)
327 check('8.2 + 6', 14.2)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200328 check('3.1 + $a', 6.1)
329 check('2 + "$a.$b"', 5.6)
330 check('4*[llength "6 2"]', 8.0)
331 check('{word one} < "word $a"', 0.0)
332 check('4*2 < 7', 0.0)
333 check('hypot($a, 4)', 5.0)
334 check('5 / 4', 1.0)
335 check('5 / 4.0', 1.25)
336 check('5 / ( [string length "abcd"] + 0.0 )', 1.25)
337 check('20.0/5.0', 4.0)
338 check('"0x03" > "2"', 1.0)
339 check('[string length "a\xc2\xbd\xe2\x82\xac"]', 3.0)
340 check(r'[string length "a\xbd\u20ac"]', 3.0)
341 self.assertRaises(TclError, tcl.exprdouble, '"abc"')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300342 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200343 check('2**64', float(2**64))
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200344
345 def test_exprlong(self):
346 tcl = self.interp
347 tcl.call('set', 'a', 3)
348 tcl.call('set', 'b', 6)
349 def check(expr, expected):
350 result = tcl.exprlong(expr)
351 self.assertEqual(result, expected)
352 self.assertIsInstance(result, int)
353
354 self.assertRaises(TypeError, tcl.exprlong)
355 self.assertRaises(TypeError, tcl.exprlong, '8.2', '+6')
356 self.assertRaises(TclError, tcl.exprlong, 'spam')
357 check('', 0)
358 check('8.2 + 6', 14)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200359 check('3.1 + $a', 6)
360 check('2 + "$a.$b"', 5)
361 check('4*[llength "6 2"]', 8)
362 check('{word one} < "word $a"', 0)
363 check('4*2 < 7', 0)
364 check('hypot($a, 4)', 5)
365 check('5 / 4', 1)
366 check('5 / 4.0', 1)
367 check('5 / ( [string length "abcd"] + 0.0 )', 1)
368 check('20.0/5.0', 4)
369 check('"0x03" > "2"', 1)
370 check('[string length "a\xc2\xbd\xe2\x82\xac"]', 3)
371 check(r'[string length "a\xbd\u20ac"]', 3)
372 self.assertRaises(TclError, tcl.exprlong, '"abc"')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300373 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200374 self.assertRaises(TclError, tcl.exprlong, '2**64')
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200375
376 def test_exprboolean(self):
377 tcl = self.interp
378 tcl.call('set', 'a', 3)
379 tcl.call('set', 'b', 6)
380 def check(expr, expected):
381 result = tcl.exprboolean(expr)
382 self.assertEqual(result, expected)
383 self.assertIsInstance(result, int)
384 self.assertNotIsInstance(result, bool)
385
386 self.assertRaises(TypeError, tcl.exprboolean)
387 self.assertRaises(TypeError, tcl.exprboolean, '8.2', '+6')
388 self.assertRaises(TclError, tcl.exprboolean, 'spam')
389 check('', False)
390 for value in ('0', 'false', 'no', 'off'):
391 check(value, False)
392 check('"%s"' % value, False)
393 check('{%s}' % value, False)
394 for value in ('1', 'true', 'yes', 'on'):
395 check(value, True)
396 check('"%s"' % value, True)
397 check('{%s}' % value, True)
398 check('8.2 + 6', True)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200399 check('3.1 + $a', True)
400 check('2 + "$a.$b"', True)
401 check('4*[llength "6 2"]', True)
402 check('{word one} < "word $a"', False)
403 check('4*2 < 7', False)
404 check('hypot($a, 4)', True)
405 check('5 / 4', True)
406 check('5 / 4.0', True)
407 check('5 / ( [string length "abcd"] + 0.0 )', True)
408 check('20.0/5.0', True)
409 check('"0x03" > "2"', True)
410 check('[string length "a\xc2\xbd\xe2\x82\xac"]', True)
411 check(r'[string length "a\xbd\u20ac"]', True)
412 self.assertRaises(TclError, tcl.exprboolean, '"abc"')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300413 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200414 check('2**64', True)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200415
Serhiy Storchakae8ae0472015-04-02 19:57:52 +0300416 @unittest.skipUnless(tcl_version >= (8, 5), 'requires Tcl version >= 8.5')
Serhiy Storchakacba6b5d2015-04-02 10:35:57 +0300417 def test_booleans(self):
418 tcl = self.interp
419 def check(expr, expected):
420 result = tcl.call('expr', expr)
Serhiy Storchaka91398f82015-04-02 11:46:07 +0300421 if tcl.wantobjects():
422 self.assertEqual(result, expected)
423 self.assertIsInstance(result, int)
424 else:
425 self.assertIn(result, (expr, str(int(expected))))
426 self.assertIsInstance(result, str)
Serhiy Storchakacba6b5d2015-04-02 10:35:57 +0300427 check('true', True)
428 check('yes', True)
429 check('on', True)
430 check('false', False)
431 check('no', False)
432 check('off', False)
433 check('1 < 2', True)
434 check('1 > 2', False)
435
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300436 def test_expr_bignum(self):
437 tcl = self.interp
438 for i in self.get_integers():
439 result = tcl.call('expr', str(i))
440 if self.wantobjects:
441 self.assertEqual(result, i)
442 self.assertIsInstance(result, (int, long))
443 self.assertIsInstance(result, type(int(result)))
444 else:
445 self.assertEqual(result, str(i))
446 self.assertIsInstance(result, str)
447 if tcl_version < (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka61ad42e2015-04-02 20:06:48 +0300448 self.assertRaises(TclError, tcl.call, 'expr', str(2**1000))
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300449
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200450 def test_passing_values(self):
451 def passValue(value):
452 return self.interp.call('set', '_', value)
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200453
454 self.assertEqual(passValue(True), True if self.wantobjects else '1')
455 self.assertEqual(passValue(False), False if self.wantobjects else '0')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200456 self.assertEqual(passValue('string'), 'string')
457 self.assertEqual(passValue('string\xbd'), 'string\xbd')
458 self.assertEqual(passValue('string\xe2\x82\xac'), u'string\u20ac')
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200459 self.assertEqual(passValue(u'string'), u'string')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200460 self.assertEqual(passValue(u'string\xbd'), u'string\xbd')
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200461 self.assertEqual(passValue(u'string\u20ac'), u'string\u20ac')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200462 self.assertEqual(passValue('str\x00ing'), 'str\x00ing')
463 self.assertEqual(passValue('str\xc0\x80ing'), 'str\x00ing')
464 self.assertEqual(passValue(u'str\x00ing'), u'str\x00ing')
465 self.assertEqual(passValue(u'str\x00ing\xbd'), u'str\x00ing\xbd')
466 self.assertEqual(passValue(u'str\x00ing\u20ac'), u'str\x00ing\u20ac')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300467 for i in self.get_integers():
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200468 self.assertEqual(passValue(i), i if self.wantobjects else str(i))
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300469 if tcl_version < (8, 5): # bignum was added in Tcl 8.5
470 self.assertEqual(passValue(2**1000), str(2**1000))
Ezio Melotti0a4a7e12013-02-23 08:19:00 +0200471 for f in (0.0, 1.0, -1.0, 1//3, 1/3.0,
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200472 sys.float_info.min, sys.float_info.max,
473 -sys.float_info.min, -sys.float_info.max):
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200474 if self.wantobjects:
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200475 self.assertEqual(passValue(f), f)
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200476 else:
477 self.assertEqual(float(passValue(f)), f)
478 if self.wantobjects:
479 f = passValue(float('nan'))
480 self.assertNotEqual(f, f)
481 self.assertEqual(passValue(float('inf')), float('inf'))
482 self.assertEqual(passValue(-float('inf')), -float('inf'))
483 else:
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200484 self.assertEqual(float(passValue(float('inf'))), float('inf'))
485 self.assertEqual(float(passValue(-float('inf'))), -float('inf'))
Serhiy Storchaka5fc570f2014-07-07 14:47:17 +0300486 # XXX NaN representation can be not parsable by float()
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200487 self.assertEqual(passValue((1, '2', (3.4,))),
488 (1, '2', (3.4,)) if self.wantobjects else '1 2 3.4')
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000489
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200490 def test_user_command(self):
491 result = []
492 def testfunc(arg):
493 result.append(arg)
494 return arg
495 self.interp.createcommand('testfunc', testfunc)
Antoine Pitrouaa73ea02014-02-23 19:39:06 +0100496 self.addCleanup(self.interp.tk.deletecommand, 'testfunc')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300497 def check(value, expected=None, eq=self.assertEqual):
498 if expected is None:
499 expected = value
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200500 del result[:]
Serhiy Storchaka83515ec2014-01-23 11:03:02 +0200501 r = self.interp.call('testfunc', value)
502 self.assertEqual(len(result), 1)
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200503 self.assertIsInstance(result[0], (str, unicode))
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300504 eq(result[0], expected)
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200505 self.assertIsInstance(r, (str, unicode))
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300506 eq(r, expected)
Serhiy Storchakadc976672014-01-23 14:38:44 +0200507 def float_eq(actual, expected):
Serhiy Storchakaeb7ef942014-01-23 16:08:35 +0200508 self.assertAlmostEqual(float(actual), expected,
509 delta=abs(expected) * 1e-10)
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200510
511 check(True, '1')
512 check(False, '0')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300513 check('string')
514 check('string\xbd')
515 check('string\xe2\x82\xac', u'string\u20ac')
Serhiy Storchaka17c01782014-09-11 10:56:59 +0300516 check('')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300517 check(u'string')
518 check(u'string\xbd')
519 check(u'string\u20ac')
Serhiy Storchaka17c01782014-09-11 10:56:59 +0300520 check(u'')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300521 check('str\xc0\x80ing', u'str\x00ing')
522 check('str\xc0\x80ing\xe2\x82\xac', u'str\x00ing\u20ac')
523 check(u'str\x00ing')
524 check(u'str\x00ing\xbd')
525 check(u'str\x00ing\u20ac')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300526 for i in self.get_integers():
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200527 check(i, str(i))
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300528 if tcl_version < (8, 5): # bignum was added in Tcl 8.5
529 check(2**1000, str(2**1000))
Serhiy Storchakadc976672014-01-23 14:38:44 +0200530 for f in (0.0, 1.0, -1.0):
531 check(f, repr(f))
532 for f in (1/3.0, sys.float_info.min, sys.float_info.max,
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200533 -sys.float_info.min, -sys.float_info.max):
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300534 check(f, eq=float_eq)
535 check(float('inf'), eq=float_eq)
536 check(-float('inf'), eq=float_eq)
Serhiy Storchaka5fc570f2014-07-07 14:47:17 +0300537 # XXX NaN representation can be not parsable by float()
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200538 check((), '')
539 check((1, (2,), (3, 4), '5 6', ()), '1 2 {3 4} {5 6} {}')
540
Serhiy Storchakafab65422013-07-11 20:32:48 +0300541 def test_splitlist(self):
542 splitlist = self.interp.tk.splitlist
543 call = self.interp.tk.call
544 self.assertRaises(TypeError, splitlist)
545 self.assertRaises(TypeError, splitlist, 'a', 'b')
546 self.assertRaises(TypeError, splitlist, 2)
547 testcases = [
548 ('2', ('2',)),
549 ('', ()),
550 ('{}', ('',)),
551 ('""', ('',)),
552 ('a\n b\t\r c\n ', ('a', 'b', 'c')),
553 (u'a\n b\t\r c\n ', ('a', 'b', 'c')),
554 ('a \xe2\x82\xac', ('a', '\xe2\x82\xac')),
555 (u'a \u20ac', ('a', '\xe2\x82\xac')),
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200556 ('a\xc0\x80b c\xc0\x80d', ('a\xc0\x80b', 'c\xc0\x80d')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300557 ('a {b c}', ('a', 'b c')),
558 (r'a b\ c', ('a', 'b c')),
559 (('a', 'b c'), ('a', 'b c')),
560 ('a 2', ('a', '2')),
561 (('a', 2), ('a', 2)),
562 ('a 3.4', ('a', '3.4')),
563 (('a', 3.4), ('a', 3.4)),
564 ((), ()),
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200565 (call('list', 1, '2', (3.4,)),
566 (1, '2', (3.4,)) if self.wantobjects else
567 ('1', '2', '3.4')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300568 ]
Serhiy Storchaka94025332013-09-08 20:32:56 +0300569 if tcl_version >= (8, 5):
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200570 if not self.wantobjects:
571 expected = ('12', '\xe2\x82\xac', '\xe2\x82\xac', '3.4')
572 elif get_tk_patchlevel() < (8, 5, 5):
573 # Before 8.5.5 dicts were converted to lists through string
574 expected = ('12', u'\u20ac', u'\u20ac', '3.4')
575 else:
576 expected = (12, u'\u20ac', u'\u20ac', (3.4,))
Serhiy Storchaka94025332013-09-08 20:32:56 +0300577 testcases += [
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200578 (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)),
579 expected),
Serhiy Storchaka94025332013-09-08 20:32:56 +0300580 ]
Serhiy Storchakafab65422013-07-11 20:32:48 +0300581 for arg, res in testcases:
582 self.assertEqual(splitlist(arg), res)
583 self.assertRaises(TclError, splitlist, '{')
584
585 def test_split(self):
586 split = self.interp.tk.split
587 call = self.interp.tk.call
588 self.assertRaises(TypeError, split)
589 self.assertRaises(TypeError, split, 'a', 'b')
590 self.assertRaises(TypeError, split, 2)
591 testcases = [
592 ('2', '2'),
593 ('', ''),
594 ('{}', ''),
595 ('""', ''),
596 ('{', '{'),
597 ('a\n b\t\r c\n ', ('a', 'b', 'c')),
598 (u'a\n b\t\r c\n ', ('a', 'b', 'c')),
599 ('a \xe2\x82\xac', ('a', '\xe2\x82\xac')),
600 (u'a \u20ac', ('a', '\xe2\x82\xac')),
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200601 ('a\xc0\x80b', 'a\xc0\x80b'),
602 ('a\xc0\x80b c\xc0\x80d', ('a\xc0\x80b', 'c\xc0\x80d')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300603 ('a {b c}', ('a', ('b', 'c'))),
604 (r'a b\ c', ('a', ('b', 'c'))),
605 (('a', 'b c'), ('a', ('b', 'c'))),
606 (('a', u'b c'), ('a', ('b', 'c'))),
607 ('a 2', ('a', '2')),
608 (('a', 2), ('a', 2)),
609 ('a 3.4', ('a', '3.4')),
610 (('a', 3.4), ('a', 3.4)),
611 (('a', (2, 3.4)), ('a', (2, 3.4))),
612 ((), ()),
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200613 (call('list', 1, '2', (3.4,)),
614 (1, '2', (3.4,)) if self.wantobjects else
615 ('1', '2', '3.4')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300616 ]
Serhiy Storchaka94025332013-09-08 20:32:56 +0300617 if tcl_version >= (8, 5):
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200618 if not self.wantobjects:
619 expected = ('12', '\xe2\x82\xac', '\xe2\x82\xac', '3.4')
620 elif get_tk_patchlevel() < (8, 5, 5):
621 # Before 8.5.5 dicts were converted to lists through string
622 expected = ('12', u'\u20ac', u'\u20ac', '3.4')
623 else:
624 expected = (12, u'\u20ac', u'\u20ac', (3.4,))
Serhiy Storchaka94025332013-09-08 20:32:56 +0300625 testcases += [
626 (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)),
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200627 expected),
Serhiy Storchaka94025332013-09-08 20:32:56 +0300628 ]
Serhiy Storchakafab65422013-07-11 20:32:48 +0300629 for arg, res in testcases:
630 self.assertEqual(split(arg), res)
631
Serhiy Storchakaceaf6822014-09-06 22:47:02 +0300632 def test_splitdict(self):
633 splitdict = tkinter._splitdict
634 tcl = self.interp.tk
635
636 arg = '-a {1 2 3} -something foo status {}'
637 self.assertEqual(splitdict(tcl, arg, False),
638 {'-a': '1 2 3', '-something': 'foo', 'status': ''})
639 self.assertEqual(splitdict(tcl, arg),
640 {'a': '1 2 3', 'something': 'foo', 'status': ''})
641
642 arg = ('-a', (1, 2, 3), '-something', 'foo', 'status', '{}')
643 self.assertEqual(splitdict(tcl, arg, False),
644 {'-a': (1, 2, 3), '-something': 'foo', 'status': '{}'})
645 self.assertEqual(splitdict(tcl, arg),
646 {'a': (1, 2, 3), 'something': 'foo', 'status': '{}'})
647
648 self.assertRaises(RuntimeError, splitdict, tcl, '-a b -c ')
649 self.assertRaises(RuntimeError, splitdict, tcl, ('-a', 'b', '-c'))
650
651 arg = tcl.call('list',
652 '-a', (1, 2, 3), '-something', 'foo', 'status', ())
653 self.assertEqual(splitdict(tcl, arg),
654 {'a': (1, 2, 3) if self.wantobjects else '1 2 3',
655 'something': 'foo', 'status': ''})
656
657 if tcl_version >= (8, 5):
658 arg = tcl.call('dict', 'create',
659 '-a', (1, 2, 3), '-something', 'foo', 'status', ())
660 if not self.wantobjects or get_tk_patchlevel() < (8, 5, 5):
661 # Before 8.5.5 dicts were converted to lists through string
662 expected = {'a': '1 2 3', 'something': 'foo', 'status': ''}
663 else:
664 expected = {'a': (1, 2, 3), 'something': 'foo', 'status': ''}
665 self.assertEqual(splitdict(tcl, arg), expected)
666
667
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300668character_size = 4 if sys.maxunicode > 0xFFFF else 2
Neal Norwitz63dfece2004-02-19 02:37:29 +0000669
Serhiy Storchaka42035702013-08-21 21:46:12 +0300670class BigmemTclTest(unittest.TestCase):
671
672 def setUp(self):
673 self.interp = Tcl()
674
Serhiy Storchaka76249ea2014-02-07 10:06:05 +0200675 @test_support.cpython_only
676 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
677 @test_support.precisionbigmemtest(size=INT_MAX + 1, memuse=5, dry_run=False)
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300678 def test_huge_string_call(self, size):
Serhiy Storchaka42035702013-08-21 21:46:12 +0300679 value = ' ' * size
680 self.assertRaises(OverflowError, self.interp.call, 'set', '_', value)
681
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300682 @test_support.cpython_only
683 @unittest.skipUnless(test_support.have_unicode, 'requires unicode support')
684 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
685 @test_support.precisionbigmemtest(size=INT_MAX + 1,
686 memuse=2*character_size + 2,
687 dry_run=False)
688 def test_huge_unicode_call(self, size):
689 value = unicode(' ') * size
690 self.assertRaises(OverflowError, self.interp.call, 'set', '_', value)
691
692
693 @test_support.cpython_only
694 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
695 @test_support.precisionbigmemtest(size=INT_MAX + 1, memuse=9, dry_run=False)
696 def test_huge_string_builtins(self, size):
697 value = '1' + ' ' * size
698 self.check_huge_string_builtins(value)
699
700 @test_support.cpython_only
701 @unittest.skipUnless(test_support.have_unicode, 'requires unicode support')
702 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
703 @test_support.precisionbigmemtest(size=INT_MAX + 1,
704 memuse=2*character_size + 7,
705 dry_run=False)
706 def test_huge_unicode_builtins(self, size):
707 value = unicode('1' + ' ' * size)
708 self.check_huge_string_builtins(value)
709
710 def check_huge_string_builtins(self, value):
711 self.assertRaises(OverflowError, self.interp.tk.getint, value)
712 self.assertRaises(OverflowError, self.interp.tk.getdouble, value)
713 self.assertRaises(OverflowError, self.interp.tk.getboolean, value)
714 self.assertRaises(OverflowError, self.interp.eval, value)
715 self.assertRaises(OverflowError, self.interp.evalfile, value)
716 self.assertRaises(OverflowError, self.interp.record, value)
717 self.assertRaises(OverflowError, self.interp.adderrorinfo, value)
718 self.assertRaises(OverflowError, self.interp.setvar, value, 'x', 'a')
719 self.assertRaises(OverflowError, self.interp.setvar, 'x', value, 'a')
720 self.assertRaises(OverflowError, self.interp.unsetvar, value)
721 self.assertRaises(OverflowError, self.interp.unsetvar, 'x', value)
722 self.assertRaises(OverflowError, self.interp.adderrorinfo, value)
723 self.assertRaises(OverflowError, self.interp.exprstring, value)
724 self.assertRaises(OverflowError, self.interp.exprlong, value)
725 self.assertRaises(OverflowError, self.interp.exprboolean, value)
726 self.assertRaises(OverflowError, self.interp.splitlist, value)
727 self.assertRaises(OverflowError, self.interp.split, value)
728 self.assertRaises(OverflowError, self.interp.createcommand, value, max)
729 self.assertRaises(OverflowError, self.interp.deletecommand, value)
730
Serhiy Storchaka42035702013-08-21 21:46:12 +0300731
Serhiy Storchaka78ecaba2013-11-20 17:44:38 +0200732def setUpModule():
733 if test_support.verbose:
734 tcl = Tcl()
735 print 'patchlevel =', tcl.call('info', 'patchlevel')
736
737
Neal Norwitz63dfece2004-02-19 02:37:29 +0000738def test_main():
Serhiy Storchaka42035702013-08-21 21:46:12 +0300739 test_support.run_unittest(TclTest, TkinterTest, BigmemTclTest)
Neal Norwitz63dfece2004-02-19 02:37:29 +0000740
David Aschere2b4b322004-02-18 05:59:53 +0000741if __name__ == "__main__":
Neal Norwitz63dfece2004-02-19 02:37:29 +0000742 test_main()