blob: 1de8435788fbca2247782c25b23650cfcb763629 [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 Storchakad11e8b62014-05-30 14:07:20 +0300133 def test_getint(self):
134 tcl = self.interp.tk
135 self.assertEqual(tcl.getint(' 42 '), 42)
136 self.assertEqual(tcl.getint(42), 42)
137 self.assertRaises(TypeError, tcl.getint)
138 self.assertRaises(TypeError, tcl.getint, '42', '10')
139 self.assertRaises(TypeError, tcl.getint, 42.0)
140 self.assertRaises(TclError, tcl.getint, 'a')
141 self.assertRaises((TypeError, ValueError, TclError),
142 tcl.getint, '42\0')
143 if test_support.have_unicode:
144 self.assertEqual(tcl.getint(unicode('42')), 42)
145 self.assertRaises((UnicodeEncodeError, ValueError, TclError),
146 tcl.getint, '42' + unichr(0xd800))
147
148 def test_getdouble(self):
149 tcl = self.interp.tk
150 self.assertEqual(tcl.getdouble(' 42 '), 42.0)
151 self.assertEqual(tcl.getdouble(' 42.5 '), 42.5)
152 self.assertEqual(tcl.getdouble(42.5), 42.5)
153 self.assertRaises(TypeError, tcl.getdouble)
154 self.assertRaises(TypeError, tcl.getdouble, '42.5', '10')
155 self.assertRaises(TypeError, tcl.getdouble, 42)
156 self.assertRaises(TclError, tcl.getdouble, 'a')
157 self.assertRaises((TypeError, ValueError, TclError),
158 tcl.getdouble, '42.5\0')
159 if test_support.have_unicode:
160 self.assertEqual(tcl.getdouble(unicode('42.5')), 42.5)
161 self.assertRaises((UnicodeEncodeError, ValueError, TclError),
162 tcl.getdouble, '42.5' + unichr(0xd800))
163
164 def test_getboolean(self):
165 tcl = self.interp.tk
166 self.assertIs(tcl.getboolean('on'), True)
167 self.assertIs(tcl.getboolean('1'), True)
168 self.assertEqual(tcl.getboolean(42), 42)
169 self.assertRaises(TypeError, tcl.getboolean)
170 self.assertRaises(TypeError, tcl.getboolean, 'on', '1')
171 self.assertRaises(TypeError, tcl.getboolean, 1.0)
172 self.assertRaises(TclError, tcl.getboolean, 'a')
173 self.assertRaises((TypeError, ValueError, TclError),
174 tcl.getboolean, 'on\0')
175 if test_support.have_unicode:
176 self.assertIs(tcl.getboolean(unicode('on')), True)
177 self.assertRaises((UnicodeEncodeError, ValueError, TclError),
178 tcl.getboolean, 'on' + unichr(0xd800))
179
David Aschere2b4b322004-02-18 05:59:53 +0000180 def testEvalFile(self):
181 tcl = self.interp
182 filename = "testEvalFile.tcl"
183 fd = open(filename,'w')
184 script = """set a 1
185 set b 2
186 set c [ expr $a + $b ]
187 """
188 fd.write(script)
189 fd.close()
190 tcl.evalfile(filename)
Neal Norwitz9a8d55e2004-02-29 15:37:50 +0000191 os.remove(filename)
David Aschere2b4b322004-02-18 05:59:53 +0000192 self.assertEqual(tcl.eval('set a'),'1')
193 self.assertEqual(tcl.eval('set b'),'2')
194 self.assertEqual(tcl.eval('set c'),'3')
195
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200196 def test_evalfile_null_in_result(self):
197 tcl = self.interp
198 with open(test_support.TESTFN, 'wb') as f:
199 self.addCleanup(test_support.unlink, test_support.TESTFN)
200 f.write("""
201 set a "a\0b"
202 set b "a\\0b"
203 """)
204 tcl.evalfile(test_support.TESTFN)
205 self.assertEqual(tcl.eval('set a'), 'a\xc0\x80b')
206 self.assertEqual(tcl.eval('set b'), 'a\xc0\x80b')
207
David Aschere2b4b322004-02-18 05:59:53 +0000208 def testEvalFileException(self):
209 tcl = self.interp
210 filename = "doesnotexists"
211 try:
212 os.remove(filename)
213 except Exception,e:
214 pass
215 self.assertRaises(TclError,tcl.evalfile,filename)
216
David Aschere2b4b322004-02-18 05:59:53 +0000217 def testPackageRequireException(self):
218 tcl = self.interp
219 self.assertRaises(TclError,tcl.eval,'package require DNE')
220
Zachary Ware57d35c62013-11-03 22:51:25 -0600221 @unittest.skipUnless(sys.platform == 'win32', "only applies to Windows")
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000222 def testLoadWithUNC(self):
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000223 # Build a UNC path from the regular path.
224 # Something like
225 # \\%COMPUTERNAME%\c$\python27\python.exe
226
227 fullname = os.path.abspath(sys.executable)
228 if fullname[1] != ':':
Zachary Ware57d35c62013-11-03 22:51:25 -0600229 self.skipTest('unusable path: %r' % fullname)
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000230 unc_name = r'\\%s\%s$\%s' % (os.environ['COMPUTERNAME'],
231 fullname[0],
232 fullname[3:])
233
234 with test_support.EnvironmentVarGuard() as env:
235 env.unset("TCL_LIBRARY")
Ezio Melotti794e5572013-05-07 09:34:49 +0300236 cmd = '%s -c "import Tkinter; print Tkinter"' % (unc_name,)
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000237
Zachary Ware57d35c62013-11-03 22:51:25 -0600238 try:
239 p = Popen(cmd, stdout=PIPE, stderr=PIPE)
240 except WindowsError as e:
241 if e.winerror == 5:
242 self.skipTest('Not permitted to start the child process')
243 else:
244 raise
245
Ezio Melotti794e5572013-05-07 09:34:49 +0300246 out_data, err_data = p.communicate()
247
248 msg = '\n\n'.join(['"Tkinter.py" not in output',
249 'Command:', cmd,
250 'stdout:', out_data,
251 'stderr:', err_data])
252
253 self.assertIn('Tkinter.py', out_data, msg)
254
255 self.assertEqual(p.wait(), 0, 'Non-zero exit code')
256
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000257
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200258 def test_exprstring(self):
259 tcl = self.interp
260 tcl.call('set', 'a', 3)
261 tcl.call('set', 'b', 6)
262 def check(expr, expected):
263 result = tcl.exprstring(expr)
264 self.assertEqual(result, expected)
265 self.assertIsInstance(result, str)
266
267 self.assertRaises(TypeError, tcl.exprstring)
268 self.assertRaises(TypeError, tcl.exprstring, '8.2', '+6')
269 self.assertRaises(TclError, tcl.exprstring, 'spam')
270 check('', '0')
271 check('8.2 + 6', '14.2')
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200272 check('3.1 + $a', '6.1')
273 check('2 + "$a.$b"', '5.6')
274 check('4*[llength "6 2"]', '8')
275 check('{word one} < "word $a"', '0')
276 check('4*2 < 7', '0')
277 check('hypot($a, 4)', '5.0')
278 check('5 / 4', '1')
279 check('5 / 4.0', '1.25')
280 check('5 / ( [string length "abcd"] + 0.0 )', '1.25')
281 check('20.0/5.0', '4.0')
282 check('"0x03" > "2"', '1')
283 check('[string length "a\xc2\xbd\xe2\x82\xac"]', '3')
284 check(r'[string length "a\xbd\u20ac"]', '3')
285 check('"abc"', 'abc')
286 check('"a\xc2\xbd\xe2\x82\xac"', 'a\xc2\xbd\xe2\x82\xac')
287 check(r'"a\xbd\u20ac"', 'a\xc2\xbd\xe2\x82\xac')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200288 check(r'"a\0b"', 'a\xc0\x80b')
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200289 if tcl_version >= (8, 5):
290 check('2**64', str(2**64))
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200291
292 def test_exprdouble(self):
293 tcl = self.interp
294 tcl.call('set', 'a', 3)
295 tcl.call('set', 'b', 6)
296 def check(expr, expected):
297 result = tcl.exprdouble(expr)
298 self.assertEqual(result, expected)
299 self.assertIsInstance(result, float)
300
301 self.assertRaises(TypeError, tcl.exprdouble)
302 self.assertRaises(TypeError, tcl.exprdouble, '8.2', '+6')
303 self.assertRaises(TclError, tcl.exprdouble, 'spam')
304 check('', 0.0)
305 check('8.2 + 6', 14.2)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200306 check('3.1 + $a', 6.1)
307 check('2 + "$a.$b"', 5.6)
308 check('4*[llength "6 2"]', 8.0)
309 check('{word one} < "word $a"', 0.0)
310 check('4*2 < 7', 0.0)
311 check('hypot($a, 4)', 5.0)
312 check('5 / 4', 1.0)
313 check('5 / 4.0', 1.25)
314 check('5 / ( [string length "abcd"] + 0.0 )', 1.25)
315 check('20.0/5.0', 4.0)
316 check('"0x03" > "2"', 1.0)
317 check('[string length "a\xc2\xbd\xe2\x82\xac"]', 3.0)
318 check(r'[string length "a\xbd\u20ac"]', 3.0)
319 self.assertRaises(TclError, tcl.exprdouble, '"abc"')
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200320 if tcl_version >= (8, 5):
321 check('2**64', float(2**64))
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200322
323 def test_exprlong(self):
324 tcl = self.interp
325 tcl.call('set', 'a', 3)
326 tcl.call('set', 'b', 6)
327 def check(expr, expected):
328 result = tcl.exprlong(expr)
329 self.assertEqual(result, expected)
330 self.assertIsInstance(result, int)
331
332 self.assertRaises(TypeError, tcl.exprlong)
333 self.assertRaises(TypeError, tcl.exprlong, '8.2', '+6')
334 self.assertRaises(TclError, tcl.exprlong, 'spam')
335 check('', 0)
336 check('8.2 + 6', 14)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200337 check('3.1 + $a', 6)
338 check('2 + "$a.$b"', 5)
339 check('4*[llength "6 2"]', 8)
340 check('{word one} < "word $a"', 0)
341 check('4*2 < 7', 0)
342 check('hypot($a, 4)', 5)
343 check('5 / 4', 1)
344 check('5 / 4.0', 1)
345 check('5 / ( [string length "abcd"] + 0.0 )', 1)
346 check('20.0/5.0', 4)
347 check('"0x03" > "2"', 1)
348 check('[string length "a\xc2\xbd\xe2\x82\xac"]', 3)
349 check(r'[string length "a\xbd\u20ac"]', 3)
350 self.assertRaises(TclError, tcl.exprlong, '"abc"')
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200351 if tcl_version >= (8, 5):
352 self.assertRaises(TclError, tcl.exprlong, '2**64')
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200353
354 def test_exprboolean(self):
355 tcl = self.interp
356 tcl.call('set', 'a', 3)
357 tcl.call('set', 'b', 6)
358 def check(expr, expected):
359 result = tcl.exprboolean(expr)
360 self.assertEqual(result, expected)
361 self.assertIsInstance(result, int)
362 self.assertNotIsInstance(result, bool)
363
364 self.assertRaises(TypeError, tcl.exprboolean)
365 self.assertRaises(TypeError, tcl.exprboolean, '8.2', '+6')
366 self.assertRaises(TclError, tcl.exprboolean, 'spam')
367 check('', False)
368 for value in ('0', 'false', 'no', 'off'):
369 check(value, False)
370 check('"%s"' % value, False)
371 check('{%s}' % value, False)
372 for value in ('1', 'true', 'yes', 'on'):
373 check(value, True)
374 check('"%s"' % value, True)
375 check('{%s}' % value, True)
376 check('8.2 + 6', True)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200377 check('3.1 + $a', True)
378 check('2 + "$a.$b"', True)
379 check('4*[llength "6 2"]', True)
380 check('{word one} < "word $a"', False)
381 check('4*2 < 7', False)
382 check('hypot($a, 4)', True)
383 check('5 / 4', True)
384 check('5 / 4.0', True)
385 check('5 / ( [string length "abcd"] + 0.0 )', True)
386 check('20.0/5.0', True)
387 check('"0x03" > "2"', True)
388 check('[string length "a\xc2\xbd\xe2\x82\xac"]', True)
389 check(r'[string length "a\xbd\u20ac"]', True)
390 self.assertRaises(TclError, tcl.exprboolean, '"abc"')
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200391 if tcl_version >= (8, 5):
392 check('2**64', True)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200393
Serhiy Storchakacba6b5d2015-04-02 10:35:57 +0300394 def test_booleans(self):
395 tcl = self.interp
396 def check(expr, expected):
397 result = tcl.call('expr', expr)
Serhiy Storchaka91398f82015-04-02 11:46:07 +0300398 if tcl.wantobjects():
399 self.assertEqual(result, expected)
400 self.assertIsInstance(result, int)
401 else:
402 self.assertIn(result, (expr, str(int(expected))))
403 self.assertIsInstance(result, str)
Serhiy Storchakacba6b5d2015-04-02 10:35:57 +0300404 check('true', True)
405 check('yes', True)
406 check('on', True)
407 check('false', False)
408 check('no', False)
409 check('off', False)
410 check('1 < 2', True)
411 check('1 > 2', False)
412
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200413 def test_passing_values(self):
414 def passValue(value):
415 return self.interp.call('set', '_', value)
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200416
417 self.assertEqual(passValue(True), True if self.wantobjects else '1')
418 self.assertEqual(passValue(False), False if self.wantobjects else '0')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200419 self.assertEqual(passValue('string'), 'string')
420 self.assertEqual(passValue('string\xbd'), 'string\xbd')
421 self.assertEqual(passValue('string\xe2\x82\xac'), u'string\u20ac')
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200422 self.assertEqual(passValue(u'string'), u'string')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200423 self.assertEqual(passValue(u'string\xbd'), u'string\xbd')
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200424 self.assertEqual(passValue(u'string\u20ac'), u'string\u20ac')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200425 self.assertEqual(passValue('str\x00ing'), 'str\x00ing')
426 self.assertEqual(passValue('str\xc0\x80ing'), 'str\x00ing')
427 self.assertEqual(passValue(u'str\x00ing'), u'str\x00ing')
428 self.assertEqual(passValue(u'str\x00ing\xbd'), u'str\x00ing\xbd')
429 self.assertEqual(passValue(u'str\x00ing\u20ac'), u'str\x00ing\u20ac')
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200430 for i in (0, 1, -1, int(2**31-1), int(-2**31)):
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200431 self.assertEqual(passValue(i), i if self.wantobjects else str(i))
Ezio Melotti0a4a7e12013-02-23 08:19:00 +0200432 for f in (0.0, 1.0, -1.0, 1//3, 1/3.0,
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200433 sys.float_info.min, sys.float_info.max,
434 -sys.float_info.min, -sys.float_info.max):
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200435 if self.wantobjects:
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200436 self.assertEqual(passValue(f), f)
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200437 else:
438 self.assertEqual(float(passValue(f)), f)
439 if self.wantobjects:
440 f = passValue(float('nan'))
441 self.assertNotEqual(f, f)
442 self.assertEqual(passValue(float('inf')), float('inf'))
443 self.assertEqual(passValue(-float('inf')), -float('inf'))
444 else:
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200445 self.assertEqual(float(passValue(float('inf'))), float('inf'))
446 self.assertEqual(float(passValue(-float('inf'))), -float('inf'))
Serhiy Storchaka5fc570f2014-07-07 14:47:17 +0300447 # XXX NaN representation can be not parsable by float()
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200448 self.assertEqual(passValue((1, '2', (3.4,))),
449 (1, '2', (3.4,)) if self.wantobjects else '1 2 3.4')
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000450
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200451 def test_user_command(self):
452 result = []
453 def testfunc(arg):
454 result.append(arg)
455 return arg
456 self.interp.createcommand('testfunc', testfunc)
Antoine Pitrouaa73ea02014-02-23 19:39:06 +0100457 self.addCleanup(self.interp.tk.deletecommand, 'testfunc')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300458 def check(value, expected=None, eq=self.assertEqual):
459 if expected is None:
460 expected = value
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200461 del result[:]
Serhiy Storchaka83515ec2014-01-23 11:03:02 +0200462 r = self.interp.call('testfunc', value)
463 self.assertEqual(len(result), 1)
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200464 self.assertIsInstance(result[0], (str, unicode))
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300465 eq(result[0], expected)
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200466 self.assertIsInstance(r, (str, unicode))
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300467 eq(r, expected)
Serhiy Storchakadc976672014-01-23 14:38:44 +0200468 def float_eq(actual, expected):
Serhiy Storchakaeb7ef942014-01-23 16:08:35 +0200469 self.assertAlmostEqual(float(actual), expected,
470 delta=abs(expected) * 1e-10)
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200471
472 check(True, '1')
473 check(False, '0')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300474 check('string')
475 check('string\xbd')
476 check('string\xe2\x82\xac', u'string\u20ac')
Serhiy Storchaka17c01782014-09-11 10:56:59 +0300477 check('')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300478 check(u'string')
479 check(u'string\xbd')
480 check(u'string\u20ac')
Serhiy Storchaka17c01782014-09-11 10:56:59 +0300481 check(u'')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300482 check('str\xc0\x80ing', u'str\x00ing')
483 check('str\xc0\x80ing\xe2\x82\xac', u'str\x00ing\u20ac')
484 check(u'str\x00ing')
485 check(u'str\x00ing\xbd')
486 check(u'str\x00ing\u20ac')
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200487 for i in (0, 1, -1, 2**31-1, -2**31):
488 check(i, str(i))
Serhiy Storchakadc976672014-01-23 14:38:44 +0200489 for f in (0.0, 1.0, -1.0):
490 check(f, repr(f))
491 for f in (1/3.0, sys.float_info.min, sys.float_info.max,
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200492 -sys.float_info.min, -sys.float_info.max):
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300493 check(f, eq=float_eq)
494 check(float('inf'), eq=float_eq)
495 check(-float('inf'), eq=float_eq)
Serhiy Storchaka5fc570f2014-07-07 14:47:17 +0300496 # XXX NaN representation can be not parsable by float()
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200497 check((), '')
498 check((1, (2,), (3, 4), '5 6', ()), '1 2 {3 4} {5 6} {}')
499
Serhiy Storchakafab65422013-07-11 20:32:48 +0300500 def test_splitlist(self):
501 splitlist = self.interp.tk.splitlist
502 call = self.interp.tk.call
503 self.assertRaises(TypeError, splitlist)
504 self.assertRaises(TypeError, splitlist, 'a', 'b')
505 self.assertRaises(TypeError, splitlist, 2)
506 testcases = [
507 ('2', ('2',)),
508 ('', ()),
509 ('{}', ('',)),
510 ('""', ('',)),
511 ('a\n b\t\r c\n ', ('a', 'b', 'c')),
512 (u'a\n b\t\r c\n ', ('a', 'b', 'c')),
513 ('a \xe2\x82\xac', ('a', '\xe2\x82\xac')),
514 (u'a \u20ac', ('a', '\xe2\x82\xac')),
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200515 ('a\xc0\x80b c\xc0\x80d', ('a\xc0\x80b', 'c\xc0\x80d')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300516 ('a {b c}', ('a', 'b c')),
517 (r'a b\ c', ('a', 'b c')),
518 (('a', 'b c'), ('a', 'b c')),
519 ('a 2', ('a', '2')),
520 (('a', 2), ('a', 2)),
521 ('a 3.4', ('a', '3.4')),
522 (('a', 3.4), ('a', 3.4)),
523 ((), ()),
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200524 (call('list', 1, '2', (3.4,)),
525 (1, '2', (3.4,)) if self.wantobjects else
526 ('1', '2', '3.4')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300527 ]
Serhiy Storchaka94025332013-09-08 20:32:56 +0300528 if tcl_version >= (8, 5):
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200529 if not self.wantobjects:
530 expected = ('12', '\xe2\x82\xac', '\xe2\x82\xac', '3.4')
531 elif get_tk_patchlevel() < (8, 5, 5):
532 # Before 8.5.5 dicts were converted to lists through string
533 expected = ('12', u'\u20ac', u'\u20ac', '3.4')
534 else:
535 expected = (12, u'\u20ac', u'\u20ac', (3.4,))
Serhiy Storchaka94025332013-09-08 20:32:56 +0300536 testcases += [
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200537 (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)),
538 expected),
Serhiy Storchaka94025332013-09-08 20:32:56 +0300539 ]
Serhiy Storchakafab65422013-07-11 20:32:48 +0300540 for arg, res in testcases:
541 self.assertEqual(splitlist(arg), res)
542 self.assertRaises(TclError, splitlist, '{')
543
544 def test_split(self):
545 split = self.interp.tk.split
546 call = self.interp.tk.call
547 self.assertRaises(TypeError, split)
548 self.assertRaises(TypeError, split, 'a', 'b')
549 self.assertRaises(TypeError, split, 2)
550 testcases = [
551 ('2', '2'),
552 ('', ''),
553 ('{}', ''),
554 ('""', ''),
555 ('{', '{'),
556 ('a\n b\t\r c\n ', ('a', 'b', 'c')),
557 (u'a\n b\t\r c\n ', ('a', 'b', 'c')),
558 ('a \xe2\x82\xac', ('a', '\xe2\x82\xac')),
559 (u'a \u20ac', ('a', '\xe2\x82\xac')),
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200560 ('a\xc0\x80b', 'a\xc0\x80b'),
561 ('a\xc0\x80b c\xc0\x80d', ('a\xc0\x80b', 'c\xc0\x80d')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300562 ('a {b c}', ('a', ('b', 'c'))),
563 (r'a b\ c', ('a', ('b', 'c'))),
564 (('a', 'b c'), ('a', ('b', 'c'))),
565 (('a', u'b c'), ('a', ('b', 'c'))),
566 ('a 2', ('a', '2')),
567 (('a', 2), ('a', 2)),
568 ('a 3.4', ('a', '3.4')),
569 (('a', 3.4), ('a', 3.4)),
570 (('a', (2, 3.4)), ('a', (2, 3.4))),
571 ((), ()),
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200572 (call('list', 1, '2', (3.4,)),
573 (1, '2', (3.4,)) if self.wantobjects else
574 ('1', '2', '3.4')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300575 ]
Serhiy Storchaka94025332013-09-08 20:32:56 +0300576 if tcl_version >= (8, 5):
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200577 if not self.wantobjects:
578 expected = ('12', '\xe2\x82\xac', '\xe2\x82\xac', '3.4')
579 elif get_tk_patchlevel() < (8, 5, 5):
580 # Before 8.5.5 dicts were converted to lists through string
581 expected = ('12', u'\u20ac', u'\u20ac', '3.4')
582 else:
583 expected = (12, u'\u20ac', u'\u20ac', (3.4,))
Serhiy Storchaka94025332013-09-08 20:32:56 +0300584 testcases += [
585 (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)),
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200586 expected),
Serhiy Storchaka94025332013-09-08 20:32:56 +0300587 ]
Serhiy Storchakafab65422013-07-11 20:32:48 +0300588 for arg, res in testcases:
589 self.assertEqual(split(arg), res)
590
Serhiy Storchakaceaf6822014-09-06 22:47:02 +0300591 def test_splitdict(self):
592 splitdict = tkinter._splitdict
593 tcl = self.interp.tk
594
595 arg = '-a {1 2 3} -something foo status {}'
596 self.assertEqual(splitdict(tcl, arg, False),
597 {'-a': '1 2 3', '-something': 'foo', 'status': ''})
598 self.assertEqual(splitdict(tcl, arg),
599 {'a': '1 2 3', 'something': 'foo', 'status': ''})
600
601 arg = ('-a', (1, 2, 3), '-something', 'foo', 'status', '{}')
602 self.assertEqual(splitdict(tcl, arg, False),
603 {'-a': (1, 2, 3), '-something': 'foo', 'status': '{}'})
604 self.assertEqual(splitdict(tcl, arg),
605 {'a': (1, 2, 3), 'something': 'foo', 'status': '{}'})
606
607 self.assertRaises(RuntimeError, splitdict, tcl, '-a b -c ')
608 self.assertRaises(RuntimeError, splitdict, tcl, ('-a', 'b', '-c'))
609
610 arg = tcl.call('list',
611 '-a', (1, 2, 3), '-something', 'foo', 'status', ())
612 self.assertEqual(splitdict(tcl, arg),
613 {'a': (1, 2, 3) if self.wantobjects else '1 2 3',
614 'something': 'foo', 'status': ''})
615
616 if tcl_version >= (8, 5):
617 arg = tcl.call('dict', 'create',
618 '-a', (1, 2, 3), '-something', 'foo', 'status', ())
619 if not self.wantobjects or get_tk_patchlevel() < (8, 5, 5):
620 # Before 8.5.5 dicts were converted to lists through string
621 expected = {'a': '1 2 3', 'something': 'foo', 'status': ''}
622 else:
623 expected = {'a': (1, 2, 3), 'something': 'foo', 'status': ''}
624 self.assertEqual(splitdict(tcl, arg), expected)
625
626
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300627character_size = 4 if sys.maxunicode > 0xFFFF else 2
Neal Norwitz63dfece2004-02-19 02:37:29 +0000628
Serhiy Storchaka42035702013-08-21 21:46:12 +0300629class BigmemTclTest(unittest.TestCase):
630
631 def setUp(self):
632 self.interp = Tcl()
633
Serhiy Storchaka76249ea2014-02-07 10:06:05 +0200634 @test_support.cpython_only
635 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
636 @test_support.precisionbigmemtest(size=INT_MAX + 1, memuse=5, dry_run=False)
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300637 def test_huge_string_call(self, size):
Serhiy Storchaka42035702013-08-21 21:46:12 +0300638 value = ' ' * size
639 self.assertRaises(OverflowError, self.interp.call, 'set', '_', value)
640
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300641 @test_support.cpython_only
642 @unittest.skipUnless(test_support.have_unicode, 'requires unicode support')
643 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
644 @test_support.precisionbigmemtest(size=INT_MAX + 1,
645 memuse=2*character_size + 2,
646 dry_run=False)
647 def test_huge_unicode_call(self, size):
648 value = unicode(' ') * size
649 self.assertRaises(OverflowError, self.interp.call, 'set', '_', value)
650
651
652 @test_support.cpython_only
653 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
654 @test_support.precisionbigmemtest(size=INT_MAX + 1, memuse=9, dry_run=False)
655 def test_huge_string_builtins(self, size):
656 value = '1' + ' ' * size
657 self.check_huge_string_builtins(value)
658
659 @test_support.cpython_only
660 @unittest.skipUnless(test_support.have_unicode, 'requires unicode support')
661 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
662 @test_support.precisionbigmemtest(size=INT_MAX + 1,
663 memuse=2*character_size + 7,
664 dry_run=False)
665 def test_huge_unicode_builtins(self, size):
666 value = unicode('1' + ' ' * size)
667 self.check_huge_string_builtins(value)
668
669 def check_huge_string_builtins(self, value):
670 self.assertRaises(OverflowError, self.interp.tk.getint, value)
671 self.assertRaises(OverflowError, self.interp.tk.getdouble, value)
672 self.assertRaises(OverflowError, self.interp.tk.getboolean, value)
673 self.assertRaises(OverflowError, self.interp.eval, value)
674 self.assertRaises(OverflowError, self.interp.evalfile, value)
675 self.assertRaises(OverflowError, self.interp.record, value)
676 self.assertRaises(OverflowError, self.interp.adderrorinfo, value)
677 self.assertRaises(OverflowError, self.interp.setvar, value, 'x', 'a')
678 self.assertRaises(OverflowError, self.interp.setvar, 'x', value, 'a')
679 self.assertRaises(OverflowError, self.interp.unsetvar, value)
680 self.assertRaises(OverflowError, self.interp.unsetvar, 'x', value)
681 self.assertRaises(OverflowError, self.interp.adderrorinfo, value)
682 self.assertRaises(OverflowError, self.interp.exprstring, value)
683 self.assertRaises(OverflowError, self.interp.exprlong, value)
684 self.assertRaises(OverflowError, self.interp.exprboolean, value)
685 self.assertRaises(OverflowError, self.interp.splitlist, value)
686 self.assertRaises(OverflowError, self.interp.split, value)
687 self.assertRaises(OverflowError, self.interp.createcommand, value, max)
688 self.assertRaises(OverflowError, self.interp.deletecommand, value)
689
Serhiy Storchaka42035702013-08-21 21:46:12 +0300690
Serhiy Storchaka78ecaba2013-11-20 17:44:38 +0200691def setUpModule():
692 if test_support.verbose:
693 tcl = Tcl()
694 print 'patchlevel =', tcl.call('info', 'patchlevel')
695
696
Neal Norwitz63dfece2004-02-19 02:37:29 +0000697def test_main():
Serhiy Storchaka42035702013-08-21 21:46:12 +0300698 test_support.run_unittest(TclTest, TkinterTest, BigmemTclTest)
Neal Norwitz63dfece2004-02-19 02:37:29 +0000699
David Aschere2b4b322004-02-18 05:59:53 +0000700if __name__ == "__main__":
Neal Norwitz63dfece2004-02-19 02:37:29 +0000701 test_main()