blob: d627034cf34999c6782281c297b473dc35081857 [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 Storchaka4a880412013-02-07 15:37:53 +0200394 def test_passing_values(self):
395 def passValue(value):
396 return self.interp.call('set', '_', value)
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200397
398 self.assertEqual(passValue(True), True if self.wantobjects else '1')
399 self.assertEqual(passValue(False), False if self.wantobjects else '0')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200400 self.assertEqual(passValue('string'), 'string')
401 self.assertEqual(passValue('string\xbd'), 'string\xbd')
402 self.assertEqual(passValue('string\xe2\x82\xac'), u'string\u20ac')
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200403 self.assertEqual(passValue(u'string'), u'string')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200404 self.assertEqual(passValue(u'string\xbd'), u'string\xbd')
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200405 self.assertEqual(passValue(u'string\u20ac'), u'string\u20ac')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200406 self.assertEqual(passValue('str\x00ing'), 'str\x00ing')
407 self.assertEqual(passValue('str\xc0\x80ing'), 'str\x00ing')
408 self.assertEqual(passValue(u'str\x00ing'), u'str\x00ing')
409 self.assertEqual(passValue(u'str\x00ing\xbd'), u'str\x00ing\xbd')
410 self.assertEqual(passValue(u'str\x00ing\u20ac'), u'str\x00ing\u20ac')
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200411 for i in (0, 1, -1, int(2**31-1), int(-2**31)):
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200412 self.assertEqual(passValue(i), i if self.wantobjects else str(i))
Ezio Melotti0a4a7e12013-02-23 08:19:00 +0200413 for f in (0.0, 1.0, -1.0, 1//3, 1/3.0,
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200414 sys.float_info.min, sys.float_info.max,
415 -sys.float_info.min, -sys.float_info.max):
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200416 if self.wantobjects:
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200417 self.assertEqual(passValue(f), f)
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200418 else:
419 self.assertEqual(float(passValue(f)), f)
420 if self.wantobjects:
421 f = passValue(float('nan'))
422 self.assertNotEqual(f, f)
423 self.assertEqual(passValue(float('inf')), float('inf'))
424 self.assertEqual(passValue(-float('inf')), -float('inf'))
425 else:
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200426 self.assertEqual(float(passValue(float('inf'))), float('inf'))
427 self.assertEqual(float(passValue(-float('inf'))), -float('inf'))
Serhiy Storchaka5fc570f2014-07-07 14:47:17 +0300428 # XXX NaN representation can be not parsable by float()
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200429 self.assertEqual(passValue((1, '2', (3.4,))),
430 (1, '2', (3.4,)) if self.wantobjects else '1 2 3.4')
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000431
Serhiy Storchaka77149a12014-07-30 10:58:34 +0300432 @unittest.skipIf(sys.platform.startswith("aix"), 'Issue #21951: crashes on AIX')
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200433 def test_user_command(self):
434 result = []
435 def testfunc(arg):
436 result.append(arg)
437 return arg
438 self.interp.createcommand('testfunc', testfunc)
Antoine Pitrouaa73ea02014-02-23 19:39:06 +0100439 self.addCleanup(self.interp.tk.deletecommand, 'testfunc')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300440 def check(value, expected=None, eq=self.assertEqual):
441 if expected is None:
442 expected = value
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200443 del result[:]
Serhiy Storchaka83515ec2014-01-23 11:03:02 +0200444 r = self.interp.call('testfunc', value)
445 self.assertEqual(len(result), 1)
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200446 self.assertIsInstance(result[0], (str, unicode))
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300447 eq(result[0], expected)
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200448 self.assertIsInstance(r, (str, unicode))
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300449 eq(r, expected)
Serhiy Storchakadc976672014-01-23 14:38:44 +0200450 def float_eq(actual, expected):
Serhiy Storchakaeb7ef942014-01-23 16:08:35 +0200451 self.assertAlmostEqual(float(actual), expected,
452 delta=abs(expected) * 1e-10)
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200453
454 check(True, '1')
455 check(False, '0')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300456 check('string')
457 check('string\xbd')
458 check('string\xe2\x82\xac', u'string\u20ac')
459 check(u'string')
460 check(u'string\xbd')
461 check(u'string\u20ac')
462 check('str\xc0\x80ing', u'str\x00ing')
463 check('str\xc0\x80ing\xe2\x82\xac', u'str\x00ing\u20ac')
464 check(u'str\x00ing')
465 check(u'str\x00ing\xbd')
466 check(u'str\x00ing\u20ac')
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200467 for i in (0, 1, -1, 2**31-1, -2**31):
468 check(i, str(i))
Serhiy Storchakadc976672014-01-23 14:38:44 +0200469 for f in (0.0, 1.0, -1.0):
470 check(f, repr(f))
471 for f in (1/3.0, sys.float_info.min, sys.float_info.max,
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200472 -sys.float_info.min, -sys.float_info.max):
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300473 check(f, eq=float_eq)
474 check(float('inf'), eq=float_eq)
475 check(-float('inf'), eq=float_eq)
Serhiy Storchaka5fc570f2014-07-07 14:47:17 +0300476 # XXX NaN representation can be not parsable by float()
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200477 check((), '')
478 check((1, (2,), (3, 4), '5 6', ()), '1 2 {3 4} {5 6} {}')
479
Serhiy Storchakafab65422013-07-11 20:32:48 +0300480 def test_splitlist(self):
481 splitlist = self.interp.tk.splitlist
482 call = self.interp.tk.call
483 self.assertRaises(TypeError, splitlist)
484 self.assertRaises(TypeError, splitlist, 'a', 'b')
485 self.assertRaises(TypeError, splitlist, 2)
486 testcases = [
487 ('2', ('2',)),
488 ('', ()),
489 ('{}', ('',)),
490 ('""', ('',)),
491 ('a\n b\t\r c\n ', ('a', 'b', 'c')),
492 (u'a\n b\t\r c\n ', ('a', 'b', 'c')),
493 ('a \xe2\x82\xac', ('a', '\xe2\x82\xac')),
494 (u'a \u20ac', ('a', '\xe2\x82\xac')),
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200495 ('a\xc0\x80b c\xc0\x80d', ('a\xc0\x80b', 'c\xc0\x80d')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300496 ('a {b c}', ('a', 'b c')),
497 (r'a b\ c', ('a', 'b c')),
498 (('a', 'b c'), ('a', 'b c')),
499 ('a 2', ('a', '2')),
500 (('a', 2), ('a', 2)),
501 ('a 3.4', ('a', '3.4')),
502 (('a', 3.4), ('a', 3.4)),
503 ((), ()),
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200504 (call('list', 1, '2', (3.4,)),
505 (1, '2', (3.4,)) if self.wantobjects else
506 ('1', '2', '3.4')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300507 ]
Serhiy Storchaka94025332013-09-08 20:32:56 +0300508 if tcl_version >= (8, 5):
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200509 if not self.wantobjects:
510 expected = ('12', '\xe2\x82\xac', '\xe2\x82\xac', '3.4')
511 elif get_tk_patchlevel() < (8, 5, 5):
512 # Before 8.5.5 dicts were converted to lists through string
513 expected = ('12', u'\u20ac', u'\u20ac', '3.4')
514 else:
515 expected = (12, u'\u20ac', u'\u20ac', (3.4,))
Serhiy Storchaka94025332013-09-08 20:32:56 +0300516 testcases += [
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200517 (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)),
518 expected),
Serhiy Storchaka94025332013-09-08 20:32:56 +0300519 ]
Serhiy Storchakafab65422013-07-11 20:32:48 +0300520 for arg, res in testcases:
521 self.assertEqual(splitlist(arg), res)
522 self.assertRaises(TclError, splitlist, '{')
523
524 def test_split(self):
525 split = self.interp.tk.split
526 call = self.interp.tk.call
527 self.assertRaises(TypeError, split)
528 self.assertRaises(TypeError, split, 'a', 'b')
529 self.assertRaises(TypeError, split, 2)
530 testcases = [
531 ('2', '2'),
532 ('', ''),
533 ('{}', ''),
534 ('""', ''),
535 ('{', '{'),
536 ('a\n b\t\r c\n ', ('a', 'b', 'c')),
537 (u'a\n b\t\r c\n ', ('a', 'b', 'c')),
538 ('a \xe2\x82\xac', ('a', '\xe2\x82\xac')),
539 (u'a \u20ac', ('a', '\xe2\x82\xac')),
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200540 ('a\xc0\x80b', 'a\xc0\x80b'),
541 ('a\xc0\x80b c\xc0\x80d', ('a\xc0\x80b', 'c\xc0\x80d')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300542 ('a {b c}', ('a', ('b', 'c'))),
543 (r'a b\ c', ('a', ('b', 'c'))),
544 (('a', 'b c'), ('a', ('b', 'c'))),
545 (('a', u'b c'), ('a', ('b', 'c'))),
546 ('a 2', ('a', '2')),
547 (('a', 2), ('a', 2)),
548 ('a 3.4', ('a', '3.4')),
549 (('a', 3.4), ('a', 3.4)),
550 (('a', (2, 3.4)), ('a', (2, 3.4))),
551 ((), ()),
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200552 (call('list', 1, '2', (3.4,)),
553 (1, '2', (3.4,)) if self.wantobjects else
554 ('1', '2', '3.4')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300555 ]
Serhiy Storchaka94025332013-09-08 20:32:56 +0300556 if tcl_version >= (8, 5):
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200557 if not self.wantobjects:
558 expected = ('12', '\xe2\x82\xac', '\xe2\x82\xac', '3.4')
559 elif get_tk_patchlevel() < (8, 5, 5):
560 # Before 8.5.5 dicts were converted to lists through string
561 expected = ('12', u'\u20ac', u'\u20ac', '3.4')
562 else:
563 expected = (12, u'\u20ac', u'\u20ac', (3.4,))
Serhiy Storchaka94025332013-09-08 20:32:56 +0300564 testcases += [
565 (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)),
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200566 expected),
Serhiy Storchaka94025332013-09-08 20:32:56 +0300567 ]
Serhiy Storchakafab65422013-07-11 20:32:48 +0300568 for arg, res in testcases:
569 self.assertEqual(split(arg), res)
570
Serhiy Storchakaceaf6822014-09-06 22:47:02 +0300571 def test_splitdict(self):
572 splitdict = tkinter._splitdict
573 tcl = self.interp.tk
574
575 arg = '-a {1 2 3} -something foo status {}'
576 self.assertEqual(splitdict(tcl, arg, False),
577 {'-a': '1 2 3', '-something': 'foo', 'status': ''})
578 self.assertEqual(splitdict(tcl, arg),
579 {'a': '1 2 3', 'something': 'foo', 'status': ''})
580
581 arg = ('-a', (1, 2, 3), '-something', 'foo', 'status', '{}')
582 self.assertEqual(splitdict(tcl, arg, False),
583 {'-a': (1, 2, 3), '-something': 'foo', 'status': '{}'})
584 self.assertEqual(splitdict(tcl, arg),
585 {'a': (1, 2, 3), 'something': 'foo', 'status': '{}'})
586
587 self.assertRaises(RuntimeError, splitdict, tcl, '-a b -c ')
588 self.assertRaises(RuntimeError, splitdict, tcl, ('-a', 'b', '-c'))
589
590 arg = tcl.call('list',
591 '-a', (1, 2, 3), '-something', 'foo', 'status', ())
592 self.assertEqual(splitdict(tcl, arg),
593 {'a': (1, 2, 3) if self.wantobjects else '1 2 3',
594 'something': 'foo', 'status': ''})
595
596 if tcl_version >= (8, 5):
597 arg = tcl.call('dict', 'create',
598 '-a', (1, 2, 3), '-something', 'foo', 'status', ())
599 if not self.wantobjects or get_tk_patchlevel() < (8, 5, 5):
600 # Before 8.5.5 dicts were converted to lists through string
601 expected = {'a': '1 2 3', 'something': 'foo', 'status': ''}
602 else:
603 expected = {'a': (1, 2, 3), 'something': 'foo', 'status': ''}
604 self.assertEqual(splitdict(tcl, arg), expected)
605
606
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300607character_size = 4 if sys.maxunicode > 0xFFFF else 2
Neal Norwitz63dfece2004-02-19 02:37:29 +0000608
Serhiy Storchaka42035702013-08-21 21:46:12 +0300609class BigmemTclTest(unittest.TestCase):
610
611 def setUp(self):
612 self.interp = Tcl()
613
Serhiy Storchaka76249ea2014-02-07 10:06:05 +0200614 @test_support.cpython_only
615 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
616 @test_support.precisionbigmemtest(size=INT_MAX + 1, memuse=5, dry_run=False)
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300617 def test_huge_string_call(self, size):
Serhiy Storchaka42035702013-08-21 21:46:12 +0300618 value = ' ' * size
619 self.assertRaises(OverflowError, self.interp.call, 'set', '_', value)
620
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300621 @test_support.cpython_only
622 @unittest.skipUnless(test_support.have_unicode, 'requires unicode support')
623 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
624 @test_support.precisionbigmemtest(size=INT_MAX + 1,
625 memuse=2*character_size + 2,
626 dry_run=False)
627 def test_huge_unicode_call(self, size):
628 value = unicode(' ') * size
629 self.assertRaises(OverflowError, self.interp.call, 'set', '_', value)
630
631
632 @test_support.cpython_only
633 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
634 @test_support.precisionbigmemtest(size=INT_MAX + 1, memuse=9, dry_run=False)
635 def test_huge_string_builtins(self, size):
636 value = '1' + ' ' * size
637 self.check_huge_string_builtins(value)
638
639 @test_support.cpython_only
640 @unittest.skipUnless(test_support.have_unicode, 'requires unicode support')
641 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
642 @test_support.precisionbigmemtest(size=INT_MAX + 1,
643 memuse=2*character_size + 7,
644 dry_run=False)
645 def test_huge_unicode_builtins(self, size):
646 value = unicode('1' + ' ' * size)
647 self.check_huge_string_builtins(value)
648
649 def check_huge_string_builtins(self, value):
650 self.assertRaises(OverflowError, self.interp.tk.getint, value)
651 self.assertRaises(OverflowError, self.interp.tk.getdouble, value)
652 self.assertRaises(OverflowError, self.interp.tk.getboolean, value)
653 self.assertRaises(OverflowError, self.interp.eval, value)
654 self.assertRaises(OverflowError, self.interp.evalfile, value)
655 self.assertRaises(OverflowError, self.interp.record, value)
656 self.assertRaises(OverflowError, self.interp.adderrorinfo, value)
657 self.assertRaises(OverflowError, self.interp.setvar, value, 'x', 'a')
658 self.assertRaises(OverflowError, self.interp.setvar, 'x', value, 'a')
659 self.assertRaises(OverflowError, self.interp.unsetvar, value)
660 self.assertRaises(OverflowError, self.interp.unsetvar, 'x', value)
661 self.assertRaises(OverflowError, self.interp.adderrorinfo, value)
662 self.assertRaises(OverflowError, self.interp.exprstring, value)
663 self.assertRaises(OverflowError, self.interp.exprlong, value)
664 self.assertRaises(OverflowError, self.interp.exprboolean, value)
665 self.assertRaises(OverflowError, self.interp.splitlist, value)
666 self.assertRaises(OverflowError, self.interp.split, value)
667 self.assertRaises(OverflowError, self.interp.createcommand, value, max)
668 self.assertRaises(OverflowError, self.interp.deletecommand, value)
669
Serhiy Storchaka42035702013-08-21 21:46:12 +0300670
Serhiy Storchaka78ecaba2013-11-20 17:44:38 +0200671def setUpModule():
672 if test_support.verbose:
673 tcl = Tcl()
674 print 'patchlevel =', tcl.call('info', 'patchlevel')
675
676
Neal Norwitz63dfece2004-02-19 02:37:29 +0000677def test_main():
Serhiy Storchaka42035702013-08-21 21:46:12 +0300678 test_support.run_unittest(TclTest, TkinterTest, BigmemTclTest)
Neal Norwitz63dfece2004-02-19 02:37:29 +0000679
David Aschere2b4b322004-02-18 05:59:53 +0000680if __name__ == "__main__":
Neal Norwitz63dfece2004-02-19 02:37:29 +0000681 test_main()