blob: 53f0fba005d054d44170aa36463cc1f5e9a2fe58 [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)
398 self.assertEqual(result, expected)
399 self.assertIsInstance(result, int)
400 check('true', True)
401 check('yes', True)
402 check('on', True)
403 check('false', False)
404 check('no', False)
405 check('off', False)
406 check('1 < 2', True)
407 check('1 > 2', False)
408
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200409 def test_passing_values(self):
410 def passValue(value):
411 return self.interp.call('set', '_', value)
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200412
413 self.assertEqual(passValue(True), True if self.wantobjects else '1')
414 self.assertEqual(passValue(False), False if self.wantobjects else '0')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200415 self.assertEqual(passValue('string'), 'string')
416 self.assertEqual(passValue('string\xbd'), 'string\xbd')
417 self.assertEqual(passValue('string\xe2\x82\xac'), u'string\u20ac')
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200418 self.assertEqual(passValue(u'string'), u'string')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200419 self.assertEqual(passValue(u'string\xbd'), u'string\xbd')
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200420 self.assertEqual(passValue(u'string\u20ac'), u'string\u20ac')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200421 self.assertEqual(passValue('str\x00ing'), 'str\x00ing')
422 self.assertEqual(passValue('str\xc0\x80ing'), 'str\x00ing')
423 self.assertEqual(passValue(u'str\x00ing'), u'str\x00ing')
424 self.assertEqual(passValue(u'str\x00ing\xbd'), u'str\x00ing\xbd')
425 self.assertEqual(passValue(u'str\x00ing\u20ac'), u'str\x00ing\u20ac')
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200426 for i in (0, 1, -1, int(2**31-1), int(-2**31)):
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200427 self.assertEqual(passValue(i), i if self.wantobjects else str(i))
Ezio Melotti0a4a7e12013-02-23 08:19:00 +0200428 for f in (0.0, 1.0, -1.0, 1//3, 1/3.0,
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200429 sys.float_info.min, sys.float_info.max,
430 -sys.float_info.min, -sys.float_info.max):
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200431 if self.wantobjects:
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200432 self.assertEqual(passValue(f), f)
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200433 else:
434 self.assertEqual(float(passValue(f)), f)
435 if self.wantobjects:
436 f = passValue(float('nan'))
437 self.assertNotEqual(f, f)
438 self.assertEqual(passValue(float('inf')), float('inf'))
439 self.assertEqual(passValue(-float('inf')), -float('inf'))
440 else:
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200441 self.assertEqual(float(passValue(float('inf'))), float('inf'))
442 self.assertEqual(float(passValue(-float('inf'))), -float('inf'))
Serhiy Storchaka5fc570f2014-07-07 14:47:17 +0300443 # XXX NaN representation can be not parsable by float()
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200444 self.assertEqual(passValue((1, '2', (3.4,))),
445 (1, '2', (3.4,)) if self.wantobjects else '1 2 3.4')
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000446
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200447 def test_user_command(self):
448 result = []
449 def testfunc(arg):
450 result.append(arg)
451 return arg
452 self.interp.createcommand('testfunc', testfunc)
Antoine Pitrouaa73ea02014-02-23 19:39:06 +0100453 self.addCleanup(self.interp.tk.deletecommand, 'testfunc')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300454 def check(value, expected=None, eq=self.assertEqual):
455 if expected is None:
456 expected = value
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200457 del result[:]
Serhiy Storchaka83515ec2014-01-23 11:03:02 +0200458 r = self.interp.call('testfunc', value)
459 self.assertEqual(len(result), 1)
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200460 self.assertIsInstance(result[0], (str, unicode))
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300461 eq(result[0], expected)
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200462 self.assertIsInstance(r, (str, unicode))
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300463 eq(r, expected)
Serhiy Storchakadc976672014-01-23 14:38:44 +0200464 def float_eq(actual, expected):
Serhiy Storchakaeb7ef942014-01-23 16:08:35 +0200465 self.assertAlmostEqual(float(actual), expected,
466 delta=abs(expected) * 1e-10)
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200467
468 check(True, '1')
469 check(False, '0')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300470 check('string')
471 check('string\xbd')
472 check('string\xe2\x82\xac', u'string\u20ac')
Serhiy Storchaka17c01782014-09-11 10:56:59 +0300473 check('')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300474 check(u'string')
475 check(u'string\xbd')
476 check(u'string\u20ac')
Serhiy Storchaka17c01782014-09-11 10:56:59 +0300477 check(u'')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300478 check('str\xc0\x80ing', u'str\x00ing')
479 check('str\xc0\x80ing\xe2\x82\xac', u'str\x00ing\u20ac')
480 check(u'str\x00ing')
481 check(u'str\x00ing\xbd')
482 check(u'str\x00ing\u20ac')
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200483 for i in (0, 1, -1, 2**31-1, -2**31):
484 check(i, str(i))
Serhiy Storchakadc976672014-01-23 14:38:44 +0200485 for f in (0.0, 1.0, -1.0):
486 check(f, repr(f))
487 for f in (1/3.0, sys.float_info.min, sys.float_info.max,
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200488 -sys.float_info.min, -sys.float_info.max):
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300489 check(f, eq=float_eq)
490 check(float('inf'), eq=float_eq)
491 check(-float('inf'), eq=float_eq)
Serhiy Storchaka5fc570f2014-07-07 14:47:17 +0300492 # XXX NaN representation can be not parsable by float()
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200493 check((), '')
494 check((1, (2,), (3, 4), '5 6', ()), '1 2 {3 4} {5 6} {}')
495
Serhiy Storchakafab65422013-07-11 20:32:48 +0300496 def test_splitlist(self):
497 splitlist = self.interp.tk.splitlist
498 call = self.interp.tk.call
499 self.assertRaises(TypeError, splitlist)
500 self.assertRaises(TypeError, splitlist, 'a', 'b')
501 self.assertRaises(TypeError, splitlist, 2)
502 testcases = [
503 ('2', ('2',)),
504 ('', ()),
505 ('{}', ('',)),
506 ('""', ('',)),
507 ('a\n b\t\r c\n ', ('a', 'b', 'c')),
508 (u'a\n b\t\r c\n ', ('a', 'b', 'c')),
509 ('a \xe2\x82\xac', ('a', '\xe2\x82\xac')),
510 (u'a \u20ac', ('a', '\xe2\x82\xac')),
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200511 ('a\xc0\x80b c\xc0\x80d', ('a\xc0\x80b', 'c\xc0\x80d')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300512 ('a {b c}', ('a', 'b c')),
513 (r'a b\ c', ('a', 'b c')),
514 (('a', 'b c'), ('a', 'b c')),
515 ('a 2', ('a', '2')),
516 (('a', 2), ('a', 2)),
517 ('a 3.4', ('a', '3.4')),
518 (('a', 3.4), ('a', 3.4)),
519 ((), ()),
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200520 (call('list', 1, '2', (3.4,)),
521 (1, '2', (3.4,)) if self.wantobjects else
522 ('1', '2', '3.4')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300523 ]
Serhiy Storchaka94025332013-09-08 20:32:56 +0300524 if tcl_version >= (8, 5):
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200525 if not self.wantobjects:
526 expected = ('12', '\xe2\x82\xac', '\xe2\x82\xac', '3.4')
527 elif get_tk_patchlevel() < (8, 5, 5):
528 # Before 8.5.5 dicts were converted to lists through string
529 expected = ('12', u'\u20ac', u'\u20ac', '3.4')
530 else:
531 expected = (12, u'\u20ac', u'\u20ac', (3.4,))
Serhiy Storchaka94025332013-09-08 20:32:56 +0300532 testcases += [
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200533 (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)),
534 expected),
Serhiy Storchaka94025332013-09-08 20:32:56 +0300535 ]
Serhiy Storchakafab65422013-07-11 20:32:48 +0300536 for arg, res in testcases:
537 self.assertEqual(splitlist(arg), res)
538 self.assertRaises(TclError, splitlist, '{')
539
540 def test_split(self):
541 split = self.interp.tk.split
542 call = self.interp.tk.call
543 self.assertRaises(TypeError, split)
544 self.assertRaises(TypeError, split, 'a', 'b')
545 self.assertRaises(TypeError, split, 2)
546 testcases = [
547 ('2', '2'),
548 ('', ''),
549 ('{}', ''),
550 ('""', ''),
551 ('{', '{'),
552 ('a\n b\t\r c\n ', ('a', 'b', 'c')),
553 (u'a\n b\t\r c\n ', ('a', 'b', 'c')),
554 ('a \xe2\x82\xac', ('a', '\xe2\x82\xac')),
555 (u'a \u20ac', ('a', '\xe2\x82\xac')),
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200556 ('a\xc0\x80b', 'a\xc0\x80b'),
557 ('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', u'b c'), ('a', ('b', 'c'))),
562 ('a 2', ('a', '2')),
563 (('a', 2), ('a', 2)),
564 ('a 3.4', ('a', '3.4')),
565 (('a', 3.4), ('a', 3.4)),
566 (('a', (2, 3.4)), ('a', (2, 3.4))),
567 ((), ()),
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200568 (call('list', 1, '2', (3.4,)),
569 (1, '2', (3.4,)) if self.wantobjects else
570 ('1', '2', '3.4')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300571 ]
Serhiy Storchaka94025332013-09-08 20:32:56 +0300572 if tcl_version >= (8, 5):
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200573 if not self.wantobjects:
574 expected = ('12', '\xe2\x82\xac', '\xe2\x82\xac', '3.4')
575 elif get_tk_patchlevel() < (8, 5, 5):
576 # Before 8.5.5 dicts were converted to lists through string
577 expected = ('12', u'\u20ac', u'\u20ac', '3.4')
578 else:
579 expected = (12, u'\u20ac', u'\u20ac', (3.4,))
Serhiy Storchaka94025332013-09-08 20:32:56 +0300580 testcases += [
581 (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)),
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200582 expected),
Serhiy Storchaka94025332013-09-08 20:32:56 +0300583 ]
Serhiy Storchakafab65422013-07-11 20:32:48 +0300584 for arg, res in testcases:
585 self.assertEqual(split(arg), res)
586
Serhiy Storchakaceaf6822014-09-06 22:47:02 +0300587 def test_splitdict(self):
588 splitdict = tkinter._splitdict
589 tcl = self.interp.tk
590
591 arg = '-a {1 2 3} -something foo status {}'
592 self.assertEqual(splitdict(tcl, arg, False),
593 {'-a': '1 2 3', '-something': 'foo', 'status': ''})
594 self.assertEqual(splitdict(tcl, arg),
595 {'a': '1 2 3', 'something': 'foo', 'status': ''})
596
597 arg = ('-a', (1, 2, 3), '-something', 'foo', 'status', '{}')
598 self.assertEqual(splitdict(tcl, arg, False),
599 {'-a': (1, 2, 3), '-something': 'foo', 'status': '{}'})
600 self.assertEqual(splitdict(tcl, arg),
601 {'a': (1, 2, 3), 'something': 'foo', 'status': '{}'})
602
603 self.assertRaises(RuntimeError, splitdict, tcl, '-a b -c ')
604 self.assertRaises(RuntimeError, splitdict, tcl, ('-a', 'b', '-c'))
605
606 arg = tcl.call('list',
607 '-a', (1, 2, 3), '-something', 'foo', 'status', ())
608 self.assertEqual(splitdict(tcl, arg),
609 {'a': (1, 2, 3) if self.wantobjects else '1 2 3',
610 'something': 'foo', 'status': ''})
611
612 if tcl_version >= (8, 5):
613 arg = tcl.call('dict', 'create',
614 '-a', (1, 2, 3), '-something', 'foo', 'status', ())
615 if not self.wantobjects or get_tk_patchlevel() < (8, 5, 5):
616 # Before 8.5.5 dicts were converted to lists through string
617 expected = {'a': '1 2 3', 'something': 'foo', 'status': ''}
618 else:
619 expected = {'a': (1, 2, 3), 'something': 'foo', 'status': ''}
620 self.assertEqual(splitdict(tcl, arg), expected)
621
622
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300623character_size = 4 if sys.maxunicode > 0xFFFF else 2
Neal Norwitz63dfece2004-02-19 02:37:29 +0000624
Serhiy Storchaka42035702013-08-21 21:46:12 +0300625class BigmemTclTest(unittest.TestCase):
626
627 def setUp(self):
628 self.interp = Tcl()
629
Serhiy Storchaka76249ea2014-02-07 10:06:05 +0200630 @test_support.cpython_only
631 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
632 @test_support.precisionbigmemtest(size=INT_MAX + 1, memuse=5, dry_run=False)
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300633 def test_huge_string_call(self, size):
Serhiy Storchaka42035702013-08-21 21:46:12 +0300634 value = ' ' * size
635 self.assertRaises(OverflowError, self.interp.call, 'set', '_', value)
636
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300637 @test_support.cpython_only
638 @unittest.skipUnless(test_support.have_unicode, 'requires unicode support')
639 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
640 @test_support.precisionbigmemtest(size=INT_MAX + 1,
641 memuse=2*character_size + 2,
642 dry_run=False)
643 def test_huge_unicode_call(self, size):
644 value = unicode(' ') * size
645 self.assertRaises(OverflowError, self.interp.call, 'set', '_', value)
646
647
648 @test_support.cpython_only
649 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
650 @test_support.precisionbigmemtest(size=INT_MAX + 1, memuse=9, dry_run=False)
651 def test_huge_string_builtins(self, size):
652 value = '1' + ' ' * size
653 self.check_huge_string_builtins(value)
654
655 @test_support.cpython_only
656 @unittest.skipUnless(test_support.have_unicode, 'requires unicode support')
657 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
658 @test_support.precisionbigmemtest(size=INT_MAX + 1,
659 memuse=2*character_size + 7,
660 dry_run=False)
661 def test_huge_unicode_builtins(self, size):
662 value = unicode('1' + ' ' * size)
663 self.check_huge_string_builtins(value)
664
665 def check_huge_string_builtins(self, value):
666 self.assertRaises(OverflowError, self.interp.tk.getint, value)
667 self.assertRaises(OverflowError, self.interp.tk.getdouble, value)
668 self.assertRaises(OverflowError, self.interp.tk.getboolean, value)
669 self.assertRaises(OverflowError, self.interp.eval, value)
670 self.assertRaises(OverflowError, self.interp.evalfile, value)
671 self.assertRaises(OverflowError, self.interp.record, value)
672 self.assertRaises(OverflowError, self.interp.adderrorinfo, value)
673 self.assertRaises(OverflowError, self.interp.setvar, value, 'x', 'a')
674 self.assertRaises(OverflowError, self.interp.setvar, 'x', value, 'a')
675 self.assertRaises(OverflowError, self.interp.unsetvar, value)
676 self.assertRaises(OverflowError, self.interp.unsetvar, 'x', value)
677 self.assertRaises(OverflowError, self.interp.adderrorinfo, value)
678 self.assertRaises(OverflowError, self.interp.exprstring, value)
679 self.assertRaises(OverflowError, self.interp.exprlong, value)
680 self.assertRaises(OverflowError, self.interp.exprboolean, value)
681 self.assertRaises(OverflowError, self.interp.splitlist, value)
682 self.assertRaises(OverflowError, self.interp.split, value)
683 self.assertRaises(OverflowError, self.interp.createcommand, value, max)
684 self.assertRaises(OverflowError, self.interp.deletecommand, value)
685
Serhiy Storchaka42035702013-08-21 21:46:12 +0300686
Serhiy Storchaka78ecaba2013-11-20 17:44:38 +0200687def setUpModule():
688 if test_support.verbose:
689 tcl = Tcl()
690 print 'patchlevel =', tcl.call('info', 'patchlevel')
691
692
Neal Norwitz63dfece2004-02-19 02:37:29 +0000693def test_main():
Serhiy Storchaka42035702013-08-21 21:46:12 +0300694 test_support.run_unittest(TclTest, TkinterTest, BigmemTclTest)
Neal Norwitz63dfece2004-02-19 02:37:29 +0000695
David Aschere2b4b322004-02-18 05:59:53 +0000696if __name__ == "__main__":
Neal Norwitz63dfece2004-02-19 02:37:29 +0000697 test_main()