blob: ff1568b6071ed9fbf8a8e9f96371fd8e52f64da5 [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)
185 self.assertEqual(tcl.getboolean(42), 42)
186 self.assertRaises(TypeError, tcl.getboolean)
187 self.assertRaises(TypeError, tcl.getboolean, 'on', '1')
188 self.assertRaises(TypeError, tcl.getboolean, 1.0)
189 self.assertRaises(TclError, tcl.getboolean, 'a')
190 self.assertRaises((TypeError, ValueError, TclError),
191 tcl.getboolean, 'on\0')
192 if test_support.have_unicode:
193 self.assertIs(tcl.getboolean(unicode('on')), True)
194 self.assertRaises((UnicodeEncodeError, ValueError, TclError),
195 tcl.getboolean, 'on' + unichr(0xd800))
196
David Aschere2b4b322004-02-18 05:59:53 +0000197 def testEvalFile(self):
198 tcl = self.interp
199 filename = "testEvalFile.tcl"
200 fd = open(filename,'w')
201 script = """set a 1
202 set b 2
203 set c [ expr $a + $b ]
204 """
205 fd.write(script)
206 fd.close()
207 tcl.evalfile(filename)
Neal Norwitz9a8d55e2004-02-29 15:37:50 +0000208 os.remove(filename)
David Aschere2b4b322004-02-18 05:59:53 +0000209 self.assertEqual(tcl.eval('set a'),'1')
210 self.assertEqual(tcl.eval('set b'),'2')
211 self.assertEqual(tcl.eval('set c'),'3')
212
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200213 def test_evalfile_null_in_result(self):
214 tcl = self.interp
215 with open(test_support.TESTFN, 'wb') as f:
216 self.addCleanup(test_support.unlink, test_support.TESTFN)
217 f.write("""
218 set a "a\0b"
219 set b "a\\0b"
220 """)
221 tcl.evalfile(test_support.TESTFN)
222 self.assertEqual(tcl.eval('set a'), 'a\xc0\x80b')
223 self.assertEqual(tcl.eval('set b'), 'a\xc0\x80b')
224
David Aschere2b4b322004-02-18 05:59:53 +0000225 def testEvalFileException(self):
226 tcl = self.interp
227 filename = "doesnotexists"
228 try:
229 os.remove(filename)
230 except Exception,e:
231 pass
232 self.assertRaises(TclError,tcl.evalfile,filename)
233
David Aschere2b4b322004-02-18 05:59:53 +0000234 def testPackageRequireException(self):
235 tcl = self.interp
236 self.assertRaises(TclError,tcl.eval,'package require DNE')
237
Zachary Ware57d35c62013-11-03 22:51:25 -0600238 @unittest.skipUnless(sys.platform == 'win32', "only applies to Windows")
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000239 def testLoadWithUNC(self):
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000240 # Build a UNC path from the regular path.
241 # Something like
242 # \\%COMPUTERNAME%\c$\python27\python.exe
243
244 fullname = os.path.abspath(sys.executable)
245 if fullname[1] != ':':
Zachary Ware57d35c62013-11-03 22:51:25 -0600246 self.skipTest('unusable path: %r' % fullname)
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000247 unc_name = r'\\%s\%s$\%s' % (os.environ['COMPUTERNAME'],
248 fullname[0],
249 fullname[3:])
250
251 with test_support.EnvironmentVarGuard() as env:
252 env.unset("TCL_LIBRARY")
Ezio Melotti794e5572013-05-07 09:34:49 +0300253 cmd = '%s -c "import Tkinter; print Tkinter"' % (unc_name,)
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000254
Zachary Ware57d35c62013-11-03 22:51:25 -0600255 try:
256 p = Popen(cmd, stdout=PIPE, stderr=PIPE)
257 except WindowsError as e:
258 if e.winerror == 5:
259 self.skipTest('Not permitted to start the child process')
260 else:
261 raise
262
Ezio Melotti794e5572013-05-07 09:34:49 +0300263 out_data, err_data = p.communicate()
264
265 msg = '\n\n'.join(['"Tkinter.py" not in output',
266 'Command:', cmd,
267 'stdout:', out_data,
268 'stderr:', err_data])
269
270 self.assertIn('Tkinter.py', out_data, msg)
271
272 self.assertEqual(p.wait(), 0, 'Non-zero exit code')
273
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000274
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200275 def test_exprstring(self):
276 tcl = self.interp
277 tcl.call('set', 'a', 3)
278 tcl.call('set', 'b', 6)
279 def check(expr, expected):
280 result = tcl.exprstring(expr)
281 self.assertEqual(result, expected)
282 self.assertIsInstance(result, str)
283
284 self.assertRaises(TypeError, tcl.exprstring)
285 self.assertRaises(TypeError, tcl.exprstring, '8.2', '+6')
286 self.assertRaises(TclError, tcl.exprstring, 'spam')
287 check('', '0')
288 check('8.2 + 6', '14.2')
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200289 check('3.1 + $a', '6.1')
290 check('2 + "$a.$b"', '5.6')
291 check('4*[llength "6 2"]', '8')
292 check('{word one} < "word $a"', '0')
293 check('4*2 < 7', '0')
294 check('hypot($a, 4)', '5.0')
295 check('5 / 4', '1')
296 check('5 / 4.0', '1.25')
297 check('5 / ( [string length "abcd"] + 0.0 )', '1.25')
298 check('20.0/5.0', '4.0')
299 check('"0x03" > "2"', '1')
300 check('[string length "a\xc2\xbd\xe2\x82\xac"]', '3')
301 check(r'[string length "a\xbd\u20ac"]', '3')
302 check('"abc"', 'abc')
303 check('"a\xc2\xbd\xe2\x82\xac"', 'a\xc2\xbd\xe2\x82\xac')
304 check(r'"a\xbd\u20ac"', 'a\xc2\xbd\xe2\x82\xac')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200305 check(r'"a\0b"', 'a\xc0\x80b')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300306 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200307 check('2**64', str(2**64))
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200308
309 def test_exprdouble(self):
310 tcl = self.interp
311 tcl.call('set', 'a', 3)
312 tcl.call('set', 'b', 6)
313 def check(expr, expected):
314 result = tcl.exprdouble(expr)
315 self.assertEqual(result, expected)
316 self.assertIsInstance(result, float)
317
318 self.assertRaises(TypeError, tcl.exprdouble)
319 self.assertRaises(TypeError, tcl.exprdouble, '8.2', '+6')
320 self.assertRaises(TclError, tcl.exprdouble, 'spam')
321 check('', 0.0)
322 check('8.2 + 6', 14.2)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200323 check('3.1 + $a', 6.1)
324 check('2 + "$a.$b"', 5.6)
325 check('4*[llength "6 2"]', 8.0)
326 check('{word one} < "word $a"', 0.0)
327 check('4*2 < 7', 0.0)
328 check('hypot($a, 4)', 5.0)
329 check('5 / 4', 1.0)
330 check('5 / 4.0', 1.25)
331 check('5 / ( [string length "abcd"] + 0.0 )', 1.25)
332 check('20.0/5.0', 4.0)
333 check('"0x03" > "2"', 1.0)
334 check('[string length "a\xc2\xbd\xe2\x82\xac"]', 3.0)
335 check(r'[string length "a\xbd\u20ac"]', 3.0)
336 self.assertRaises(TclError, tcl.exprdouble, '"abc"')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300337 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200338 check('2**64', float(2**64))
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200339
340 def test_exprlong(self):
341 tcl = self.interp
342 tcl.call('set', 'a', 3)
343 tcl.call('set', 'b', 6)
344 def check(expr, expected):
345 result = tcl.exprlong(expr)
346 self.assertEqual(result, expected)
347 self.assertIsInstance(result, int)
348
349 self.assertRaises(TypeError, tcl.exprlong)
350 self.assertRaises(TypeError, tcl.exprlong, '8.2', '+6')
351 self.assertRaises(TclError, tcl.exprlong, 'spam')
352 check('', 0)
353 check('8.2 + 6', 14)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200354 check('3.1 + $a', 6)
355 check('2 + "$a.$b"', 5)
356 check('4*[llength "6 2"]', 8)
357 check('{word one} < "word $a"', 0)
358 check('4*2 < 7', 0)
359 check('hypot($a, 4)', 5)
360 check('5 / 4', 1)
361 check('5 / 4.0', 1)
362 check('5 / ( [string length "abcd"] + 0.0 )', 1)
363 check('20.0/5.0', 4)
364 check('"0x03" > "2"', 1)
365 check('[string length "a\xc2\xbd\xe2\x82\xac"]', 3)
366 check(r'[string length "a\xbd\u20ac"]', 3)
367 self.assertRaises(TclError, tcl.exprlong, '"abc"')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300368 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200369 self.assertRaises(TclError, tcl.exprlong, '2**64')
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200370
371 def test_exprboolean(self):
372 tcl = self.interp
373 tcl.call('set', 'a', 3)
374 tcl.call('set', 'b', 6)
375 def check(expr, expected):
376 result = tcl.exprboolean(expr)
377 self.assertEqual(result, expected)
378 self.assertIsInstance(result, int)
379 self.assertNotIsInstance(result, bool)
380
381 self.assertRaises(TypeError, tcl.exprboolean)
382 self.assertRaises(TypeError, tcl.exprboolean, '8.2', '+6')
383 self.assertRaises(TclError, tcl.exprboolean, 'spam')
384 check('', False)
385 for value in ('0', 'false', 'no', 'off'):
386 check(value, False)
387 check('"%s"' % value, False)
388 check('{%s}' % value, False)
389 for value in ('1', 'true', 'yes', 'on'):
390 check(value, True)
391 check('"%s"' % value, True)
392 check('{%s}' % value, True)
393 check('8.2 + 6', True)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200394 check('3.1 + $a', True)
395 check('2 + "$a.$b"', True)
396 check('4*[llength "6 2"]', True)
397 check('{word one} < "word $a"', False)
398 check('4*2 < 7', False)
399 check('hypot($a, 4)', True)
400 check('5 / 4', True)
401 check('5 / 4.0', True)
402 check('5 / ( [string length "abcd"] + 0.0 )', True)
403 check('20.0/5.0', True)
404 check('"0x03" > "2"', True)
405 check('[string length "a\xc2\xbd\xe2\x82\xac"]', True)
406 check(r'[string length "a\xbd\u20ac"]', True)
407 self.assertRaises(TclError, tcl.exprboolean, '"abc"')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300408 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200409 check('2**64', True)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200410
Serhiy Storchakae8ae0472015-04-02 19:57:52 +0300411 @unittest.skipUnless(tcl_version >= (8, 5), 'requires Tcl version >= 8.5')
Serhiy Storchakacba6b5d2015-04-02 10:35:57 +0300412 def test_booleans(self):
413 tcl = self.interp
414 def check(expr, expected):
415 result = tcl.call('expr', expr)
Serhiy Storchaka91398f82015-04-02 11:46:07 +0300416 if tcl.wantobjects():
417 self.assertEqual(result, expected)
418 self.assertIsInstance(result, int)
419 else:
420 self.assertIn(result, (expr, str(int(expected))))
421 self.assertIsInstance(result, str)
Serhiy Storchakacba6b5d2015-04-02 10:35:57 +0300422 check('true', True)
423 check('yes', True)
424 check('on', True)
425 check('false', False)
426 check('no', False)
427 check('off', False)
428 check('1 < 2', True)
429 check('1 > 2', False)
430
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300431 def test_expr_bignum(self):
432 tcl = self.interp
433 for i in self.get_integers():
434 result = tcl.call('expr', str(i))
435 if self.wantobjects:
436 self.assertEqual(result, i)
437 self.assertIsInstance(result, (int, long))
438 self.assertIsInstance(result, type(int(result)))
439 else:
440 self.assertEqual(result, str(i))
441 self.assertIsInstance(result, str)
442 if tcl_version < (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka61ad42e2015-04-02 20:06:48 +0300443 self.assertRaises(TclError, tcl.call, 'expr', str(2**1000))
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300444
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()