blob: 38a960cb024a489ce7c33a8b9f51b7172909e4d2 [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))
Serhiy Storchaka4507b812015-04-10 21:12:18 +0300443 if abs(result) < 2**31:
444 self.assertIsInstance(result, int)
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300445 else:
446 self.assertEqual(result, str(i))
447 self.assertIsInstance(result, str)
448 if tcl_version < (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka61ad42e2015-04-02 20:06:48 +0300449 self.assertRaises(TclError, tcl.call, 'expr', str(2**1000))
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300450
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200451 def test_passing_values(self):
452 def passValue(value):
453 return self.interp.call('set', '_', value)
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200454
455 self.assertEqual(passValue(True), True if self.wantobjects else '1')
456 self.assertEqual(passValue(False), False if self.wantobjects else '0')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200457 self.assertEqual(passValue('string'), 'string')
458 self.assertEqual(passValue('string\xbd'), 'string\xbd')
459 self.assertEqual(passValue('string\xe2\x82\xac'), u'string\u20ac')
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200460 self.assertEqual(passValue(u'string'), u'string')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200461 self.assertEqual(passValue(u'string\xbd'), u'string\xbd')
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200462 self.assertEqual(passValue(u'string\u20ac'), u'string\u20ac')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200463 self.assertEqual(passValue('str\x00ing'), 'str\x00ing')
464 self.assertEqual(passValue('str\xc0\x80ing'), 'str\x00ing')
465 self.assertEqual(passValue(u'str\x00ing'), u'str\x00ing')
466 self.assertEqual(passValue(u'str\x00ing\xbd'), u'str\x00ing\xbd')
467 self.assertEqual(passValue(u'str\x00ing\u20ac'), u'str\x00ing\u20ac')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300468 for i in self.get_integers():
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200469 self.assertEqual(passValue(i), i if self.wantobjects else str(i))
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300470 if tcl_version < (8, 5): # bignum was added in Tcl 8.5
471 self.assertEqual(passValue(2**1000), str(2**1000))
Ezio Melotti0a4a7e12013-02-23 08:19:00 +0200472 for f in (0.0, 1.0, -1.0, 1//3, 1/3.0,
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200473 sys.float_info.min, sys.float_info.max,
474 -sys.float_info.min, -sys.float_info.max):
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200475 if self.wantobjects:
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200476 self.assertEqual(passValue(f), f)
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200477 else:
478 self.assertEqual(float(passValue(f)), f)
479 if self.wantobjects:
480 f = passValue(float('nan'))
481 self.assertNotEqual(f, f)
482 self.assertEqual(passValue(float('inf')), float('inf'))
483 self.assertEqual(passValue(-float('inf')), -float('inf'))
484 else:
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200485 self.assertEqual(float(passValue(float('inf'))), float('inf'))
486 self.assertEqual(float(passValue(-float('inf'))), -float('inf'))
Serhiy Storchaka5fc570f2014-07-07 14:47:17 +0300487 # XXX NaN representation can be not parsable by float()
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200488 self.assertEqual(passValue((1, '2', (3.4,))),
489 (1, '2', (3.4,)) if self.wantobjects else '1 2 3.4')
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000490
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200491 def test_user_command(self):
492 result = []
493 def testfunc(arg):
494 result.append(arg)
495 return arg
496 self.interp.createcommand('testfunc', testfunc)
Antoine Pitrouaa73ea02014-02-23 19:39:06 +0100497 self.addCleanup(self.interp.tk.deletecommand, 'testfunc')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300498 def check(value, expected=None, eq=self.assertEqual):
499 if expected is None:
500 expected = value
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200501 del result[:]
Serhiy Storchaka83515ec2014-01-23 11:03:02 +0200502 r = self.interp.call('testfunc', value)
503 self.assertEqual(len(result), 1)
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200504 self.assertIsInstance(result[0], (str, unicode))
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300505 eq(result[0], expected)
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200506 self.assertIsInstance(r, (str, unicode))
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300507 eq(r, expected)
Serhiy Storchakadc976672014-01-23 14:38:44 +0200508 def float_eq(actual, expected):
Serhiy Storchakaeb7ef942014-01-23 16:08:35 +0200509 self.assertAlmostEqual(float(actual), expected,
510 delta=abs(expected) * 1e-10)
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200511
512 check(True, '1')
513 check(False, '0')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300514 check('string')
515 check('string\xbd')
516 check('string\xe2\x82\xac', u'string\u20ac')
Serhiy Storchaka17c01782014-09-11 10:56:59 +0300517 check('')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300518 check(u'string')
519 check(u'string\xbd')
520 check(u'string\u20ac')
Serhiy Storchaka17c01782014-09-11 10:56:59 +0300521 check(u'')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300522 check('str\xc0\x80ing', u'str\x00ing')
523 check('str\xc0\x80ing\xe2\x82\xac', u'str\x00ing\u20ac')
524 check(u'str\x00ing')
525 check(u'str\x00ing\xbd')
526 check(u'str\x00ing\u20ac')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300527 for i in self.get_integers():
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200528 check(i, str(i))
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300529 if tcl_version < (8, 5): # bignum was added in Tcl 8.5
530 check(2**1000, str(2**1000))
Serhiy Storchakadc976672014-01-23 14:38:44 +0200531 for f in (0.0, 1.0, -1.0):
532 check(f, repr(f))
533 for f in (1/3.0, sys.float_info.min, sys.float_info.max,
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200534 -sys.float_info.min, -sys.float_info.max):
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300535 check(f, eq=float_eq)
536 check(float('inf'), eq=float_eq)
537 check(-float('inf'), eq=float_eq)
Serhiy Storchaka5fc570f2014-07-07 14:47:17 +0300538 # XXX NaN representation can be not parsable by float()
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200539 check((), '')
540 check((1, (2,), (3, 4), '5 6', ()), '1 2 {3 4} {5 6} {}')
541
Serhiy Storchakafab65422013-07-11 20:32:48 +0300542 def test_splitlist(self):
543 splitlist = self.interp.tk.splitlist
544 call = self.interp.tk.call
545 self.assertRaises(TypeError, splitlist)
546 self.assertRaises(TypeError, splitlist, 'a', 'b')
547 self.assertRaises(TypeError, splitlist, 2)
548 testcases = [
549 ('2', ('2',)),
550 ('', ()),
551 ('{}', ('',)),
552 ('""', ('',)),
553 ('a\n b\t\r c\n ', ('a', 'b', 'c')),
554 (u'a\n b\t\r c\n ', ('a', 'b', 'c')),
555 ('a \xe2\x82\xac', ('a', '\xe2\x82\xac')),
556 (u'a \u20ac', ('a', '\xe2\x82\xac')),
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200557 ('a\xc0\x80b c\xc0\x80d', ('a\xc0\x80b', 'c\xc0\x80d')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300558 ('a {b c}', ('a', 'b c')),
559 (r'a b\ c', ('a', 'b c')),
560 (('a', 'b c'), ('a', 'b c')),
561 ('a 2', ('a', '2')),
562 (('a', 2), ('a', 2)),
563 ('a 3.4', ('a', '3.4')),
564 (('a', 3.4), ('a', 3.4)),
565 ((), ()),
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200566 (call('list', 1, '2', (3.4,)),
567 (1, '2', (3.4,)) if self.wantobjects else
568 ('1', '2', '3.4')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300569 ]
Serhiy Storchaka94025332013-09-08 20:32:56 +0300570 if tcl_version >= (8, 5):
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200571 if not self.wantobjects:
572 expected = ('12', '\xe2\x82\xac', '\xe2\x82\xac', '3.4')
573 elif get_tk_patchlevel() < (8, 5, 5):
574 # Before 8.5.5 dicts were converted to lists through string
575 expected = ('12', u'\u20ac', u'\u20ac', '3.4')
576 else:
577 expected = (12, u'\u20ac', u'\u20ac', (3.4,))
Serhiy Storchaka94025332013-09-08 20:32:56 +0300578 testcases += [
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200579 (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)),
580 expected),
Serhiy Storchaka94025332013-09-08 20:32:56 +0300581 ]
Serhiy Storchakafab65422013-07-11 20:32:48 +0300582 for arg, res in testcases:
583 self.assertEqual(splitlist(arg), res)
584 self.assertRaises(TclError, splitlist, '{')
585
586 def test_split(self):
587 split = self.interp.tk.split
588 call = self.interp.tk.call
589 self.assertRaises(TypeError, split)
590 self.assertRaises(TypeError, split, 'a', 'b')
591 self.assertRaises(TypeError, split, 2)
592 testcases = [
593 ('2', '2'),
594 ('', ''),
595 ('{}', ''),
596 ('""', ''),
597 ('{', '{'),
598 ('a\n b\t\r c\n ', ('a', 'b', 'c')),
599 (u'a\n b\t\r c\n ', ('a', 'b', 'c')),
600 ('a \xe2\x82\xac', ('a', '\xe2\x82\xac')),
601 (u'a \u20ac', ('a', '\xe2\x82\xac')),
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200602 ('a\xc0\x80b', 'a\xc0\x80b'),
603 ('a\xc0\x80b c\xc0\x80d', ('a\xc0\x80b', 'c\xc0\x80d')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300604 ('a {b c}', ('a', ('b', 'c'))),
605 (r'a b\ c', ('a', ('b', 'c'))),
606 (('a', 'b c'), ('a', ('b', 'c'))),
607 (('a', u'b c'), ('a', ('b', 'c'))),
608 ('a 2', ('a', '2')),
609 (('a', 2), ('a', 2)),
610 ('a 3.4', ('a', '3.4')),
611 (('a', 3.4), ('a', 3.4)),
612 (('a', (2, 3.4)), ('a', (2, 3.4))),
613 ((), ()),
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200614 (call('list', 1, '2', (3.4,)),
615 (1, '2', (3.4,)) if self.wantobjects else
616 ('1', '2', '3.4')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300617 ]
Serhiy Storchaka94025332013-09-08 20:32:56 +0300618 if tcl_version >= (8, 5):
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200619 if not self.wantobjects:
620 expected = ('12', '\xe2\x82\xac', '\xe2\x82\xac', '3.4')
621 elif get_tk_patchlevel() < (8, 5, 5):
622 # Before 8.5.5 dicts were converted to lists through string
623 expected = ('12', u'\u20ac', u'\u20ac', '3.4')
624 else:
625 expected = (12, u'\u20ac', u'\u20ac', (3.4,))
Serhiy Storchaka94025332013-09-08 20:32:56 +0300626 testcases += [
627 (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)),
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200628 expected),
Serhiy Storchaka94025332013-09-08 20:32:56 +0300629 ]
Serhiy Storchakafab65422013-07-11 20:32:48 +0300630 for arg, res in testcases:
631 self.assertEqual(split(arg), res)
632
Serhiy Storchakaceaf6822014-09-06 22:47:02 +0300633 def test_splitdict(self):
634 splitdict = tkinter._splitdict
635 tcl = self.interp.tk
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 arg = ('-a', (1, 2, 3), '-something', 'foo', 'status', '{}')
644 self.assertEqual(splitdict(tcl, arg, False),
645 {'-a': (1, 2, 3), '-something': 'foo', 'status': '{}'})
646 self.assertEqual(splitdict(tcl, arg),
647 {'a': (1, 2, 3), 'something': 'foo', 'status': '{}'})
648
649 self.assertRaises(RuntimeError, splitdict, tcl, '-a b -c ')
650 self.assertRaises(RuntimeError, splitdict, tcl, ('-a', 'b', '-c'))
651
652 arg = tcl.call('list',
653 '-a', (1, 2, 3), '-something', 'foo', 'status', ())
654 self.assertEqual(splitdict(tcl, arg),
655 {'a': (1, 2, 3) if self.wantobjects else '1 2 3',
656 'something': 'foo', 'status': ''})
657
658 if tcl_version >= (8, 5):
659 arg = tcl.call('dict', 'create',
660 '-a', (1, 2, 3), '-something', 'foo', 'status', ())
661 if not self.wantobjects or get_tk_patchlevel() < (8, 5, 5):
662 # Before 8.5.5 dicts were converted to lists through string
663 expected = {'a': '1 2 3', 'something': 'foo', 'status': ''}
664 else:
665 expected = {'a': (1, 2, 3), 'something': 'foo', 'status': ''}
666 self.assertEqual(splitdict(tcl, arg), expected)
667
668
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300669character_size = 4 if sys.maxunicode > 0xFFFF else 2
Neal Norwitz63dfece2004-02-19 02:37:29 +0000670
Serhiy Storchaka42035702013-08-21 21:46:12 +0300671class BigmemTclTest(unittest.TestCase):
672
673 def setUp(self):
674 self.interp = Tcl()
675
Serhiy Storchaka76249ea2014-02-07 10:06:05 +0200676 @test_support.cpython_only
677 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
678 @test_support.precisionbigmemtest(size=INT_MAX + 1, memuse=5, dry_run=False)
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300679 def test_huge_string_call(self, size):
Serhiy Storchaka42035702013-08-21 21:46:12 +0300680 value = ' ' * size
681 self.assertRaises(OverflowError, self.interp.call, 'set', '_', value)
682
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300683 @test_support.cpython_only
684 @unittest.skipUnless(test_support.have_unicode, 'requires unicode support')
685 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
686 @test_support.precisionbigmemtest(size=INT_MAX + 1,
687 memuse=2*character_size + 2,
688 dry_run=False)
689 def test_huge_unicode_call(self, size):
690 value = unicode(' ') * size
691 self.assertRaises(OverflowError, self.interp.call, 'set', '_', value)
692
693
694 @test_support.cpython_only
695 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
696 @test_support.precisionbigmemtest(size=INT_MAX + 1, memuse=9, dry_run=False)
697 def test_huge_string_builtins(self, size):
698 value = '1' + ' ' * size
699 self.check_huge_string_builtins(value)
700
701 @test_support.cpython_only
702 @unittest.skipUnless(test_support.have_unicode, 'requires unicode support')
703 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
704 @test_support.precisionbigmemtest(size=INT_MAX + 1,
705 memuse=2*character_size + 7,
706 dry_run=False)
707 def test_huge_unicode_builtins(self, size):
708 value = unicode('1' + ' ' * size)
709 self.check_huge_string_builtins(value)
710
711 def check_huge_string_builtins(self, value):
712 self.assertRaises(OverflowError, self.interp.tk.getint, value)
713 self.assertRaises(OverflowError, self.interp.tk.getdouble, value)
714 self.assertRaises(OverflowError, self.interp.tk.getboolean, value)
715 self.assertRaises(OverflowError, self.interp.eval, value)
716 self.assertRaises(OverflowError, self.interp.evalfile, value)
717 self.assertRaises(OverflowError, self.interp.record, value)
718 self.assertRaises(OverflowError, self.interp.adderrorinfo, value)
719 self.assertRaises(OverflowError, self.interp.setvar, value, 'x', 'a')
720 self.assertRaises(OverflowError, self.interp.setvar, 'x', value, 'a')
721 self.assertRaises(OverflowError, self.interp.unsetvar, value)
722 self.assertRaises(OverflowError, self.interp.unsetvar, 'x', value)
723 self.assertRaises(OverflowError, self.interp.adderrorinfo, value)
724 self.assertRaises(OverflowError, self.interp.exprstring, value)
725 self.assertRaises(OverflowError, self.interp.exprlong, value)
726 self.assertRaises(OverflowError, self.interp.exprboolean, value)
727 self.assertRaises(OverflowError, self.interp.splitlist, value)
728 self.assertRaises(OverflowError, self.interp.split, value)
729 self.assertRaises(OverflowError, self.interp.createcommand, value, max)
730 self.assertRaises(OverflowError, self.interp.deletecommand, value)
731
Serhiy Storchaka42035702013-08-21 21:46:12 +0300732
Serhiy Storchaka78ecaba2013-11-20 17:44:38 +0200733def setUpModule():
734 if test_support.verbose:
735 tcl = Tcl()
736 print 'patchlevel =', tcl.call('info', 'patchlevel')
737
738
Neal Norwitz63dfece2004-02-19 02:37:29 +0000739def test_main():
Serhiy Storchaka42035702013-08-21 21:46:12 +0300740 test_support.run_unittest(TclTest, TkinterTest, BigmemTclTest)
Neal Norwitz63dfece2004-02-19 02:37:29 +0000741
David Aschere2b4b322004-02-18 05:59:53 +0000742if __name__ == "__main__":
Neal Norwitz63dfece2004-02-19 02:37:29 +0000743 test_main()