blob: 9c9afde3c2a22c6c9bbab5b8bb247c1918eec386 [file] [log] [blame]
David Aschere2b4b322004-02-18 05:59:53 +00001import unittest
Serhiy Storchakadcb12f42015-04-22 08:35:53 +03002import re
Serhiy Storchaka4a880412013-02-07 15:37:53 +02003import sys
David Aschere2b4b322004-02-18 05:59:53 +00004import os
Neal Norwitz63dfece2004-02-19 02:37:29 +00005from test import test_support
Ezio Melotti794e5572013-05-07 09:34:49 +03006from subprocess import Popen, PIPE
R. David Murray597ebab2009-03-31 18:32:17 +00007
8# Skip this test if the _tkinter module wasn't built.
9_tkinter = test_support.import_module('_tkinter')
10
Serhiy Storchakaceaf6822014-09-06 22:47:02 +030011# Make sure tkinter._fix runs to set up the environment
12tkinter = test_support.import_fresh_module('Tkinter')
13
Guilherme Polo8e5e4382009-02-07 02:20:29 +000014from Tkinter import Tcl
David Aschere2b4b322004-02-18 05:59:53 +000015from _tkinter import TclError
16
Serhiy Storchaka76249ea2014-02-07 10:06:05 +020017try:
18 from _testcapi import INT_MAX, PY_SSIZE_T_MAX
19except ImportError:
20 INT_MAX = PY_SSIZE_T_MAX = sys.maxsize
21
Serhiy Storchakadcb12f42015-04-22 08:35:53 +030022tcl_version = tuple(map(int, _tkinter.TCL_VERSION.split('.')))
Serhiy Storchaka94025332013-09-08 20:32:56 +030023
Serhiy Storchaka15b67d72014-02-02 23:04:06 +020024_tk_patchlevel = None
25def get_tk_patchlevel():
26 global _tk_patchlevel
27 if _tk_patchlevel is None:
28 tcl = Tcl()
Serhiy Storchakadcb12f42015-04-22 08:35:53 +030029 patchlevel = tcl.call('info', 'patchlevel')
30 m = re.match(r'(\d+)\.(\d+)([ab.])(\d+)$', patchlevel)
31 major, minor, releaselevel, serial = m.groups()
32 major, minor, serial = int(major), int(minor), int(serial)
33 releaselevel = {'a': 'alpha', 'b': 'beta', '.': 'final'}[releaselevel]
34 if releaselevel == 'final':
35 _tk_patchlevel = major, minor, serial, releaselevel, 0
36 else:
37 _tk_patchlevel = major, minor, 0, releaselevel, serial
Serhiy Storchaka15b67d72014-02-02 23:04:06 +020038 return _tk_patchlevel
39
Benjamin Petersonb3619be2009-01-30 02:24:39 +000040
41class TkinterTest(unittest.TestCase):
42
43 def testFlattenLen(self):
44 # flatten(<object with no length>)
45 self.assertRaises(TypeError, _tkinter._flatten, True)
46
47
David Aschere2b4b322004-02-18 05:59:53 +000048class TclTest(unittest.TestCase):
49
50 def setUp(self):
51 self.interp = Tcl()
Serhiy Storchaka5542b152013-12-25 17:28:50 +020052 self.wantobjects = self.interp.tk.wantobjects()
David Aschere2b4b322004-02-18 05:59:53 +000053
54 def testEval(self):
55 tcl = self.interp
56 tcl.eval('set a 1')
57 self.assertEqual(tcl.eval('set a'),'1')
58
59 def testEvalException(self):
60 tcl = self.interp
61 self.assertRaises(TclError,tcl.eval,'set a')
62
63 def testEvalException2(self):
64 tcl = self.interp
65 self.assertRaises(TclError,tcl.eval,'this is wrong')
66
67 def testCall(self):
68 tcl = self.interp
69 tcl.call('set','a','1')
70 self.assertEqual(tcl.call('set','a'),'1')
71
72 def testCallException(self):
73 tcl = self.interp
74 self.assertRaises(TclError,tcl.call,'set','a')
75
76 def testCallException2(self):
77 tcl = self.interp
78 self.assertRaises(TclError,tcl.call,'this','is','wrong')
79
80 def testSetVar(self):
81 tcl = self.interp
82 tcl.setvar('a','1')
83 self.assertEqual(tcl.eval('set a'),'1')
84
85 def testSetVarArray(self):
86 tcl = self.interp
87 tcl.setvar('a(1)','1')
88 self.assertEqual(tcl.eval('set a(1)'),'1')
89
90 def testGetVar(self):
91 tcl = self.interp
92 tcl.eval('set a 1')
93 self.assertEqual(tcl.getvar('a'),'1')
94
95 def testGetVarArray(self):
96 tcl = self.interp
97 tcl.eval('set a(1) 1')
98 self.assertEqual(tcl.getvar('a(1)'),'1')
99
100 def testGetVarException(self):
101 tcl = self.interp
102 self.assertRaises(TclError,tcl.getvar,'a')
103
104 def testGetVarArrayException(self):
105 tcl = self.interp
106 self.assertRaises(TclError,tcl.getvar,'a(1)')
107
108 def testUnsetVar(self):
109 tcl = self.interp
110 tcl.setvar('a',1)
111 self.assertEqual(tcl.eval('info exists a'),'1')
112 tcl.unsetvar('a')
113 self.assertEqual(tcl.eval('info exists a'),'0')
114
115 def testUnsetVarArray(self):
116 tcl = self.interp
117 tcl.setvar('a(1)',1)
118 tcl.setvar('a(2)',2)
119 self.assertEqual(tcl.eval('info exists a(1)'),'1')
120 self.assertEqual(tcl.eval('info exists a(2)'),'1')
121 tcl.unsetvar('a(1)')
122 self.assertEqual(tcl.eval('info exists a(1)'),'0')
123 self.assertEqual(tcl.eval('info exists a(2)'),'1')
124
125 def testUnsetVarException(self):
126 tcl = self.interp
127 self.assertRaises(TclError,tcl.unsetvar,'a')
Tim Peters27f88362004-07-08 04:22:35 +0000128
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300129 def get_integers(self):
130 integers = (0, 1, -1, 2**31-1, -2**31)
131 if tcl_version >= (8, 4): # wideInt was added in Tcl 8.4
132 integers += (2**31, -2**31-1, 2**63-1, -2**63)
Serhiy Storchaka6294d9f2015-04-22 10:51:49 +0300133 # bignum was added in Tcl 8.5, but its support is able only since 8.5.8
134 if (get_tk_patchlevel() >= (8, 6, 0, 'final') or
135 (8, 5, 8) <= get_tk_patchlevel() < (8, 6)):
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300136 integers += (2**63, -2**63-1, 2**1000, -2**1000)
137 return integers
138
Serhiy Storchakad11e8b62014-05-30 14:07:20 +0300139 def test_getint(self):
140 tcl = self.interp.tk
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300141 for i in self.get_integers():
142 result = tcl.getint(' %d ' % i)
143 self.assertEqual(result, i)
144 self.assertIsInstance(result, type(int(result)))
Serhiy Storchaka61ad42e2015-04-02 20:06:48 +0300145 if tcl_version >= (8, 5):
146 self.assertEqual(tcl.getint(' {:#o} '.format(i)), i)
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300147 self.assertEqual(tcl.getint(' %#o ' % i), i)
148 self.assertEqual(tcl.getint(' %#x ' % i), i)
149 if tcl_version < (8, 5): # bignum was added in Tcl 8.5
150 self.assertRaises(TclError, tcl.getint, str(2**1000))
Serhiy Storchakad11e8b62014-05-30 14:07:20 +0300151 self.assertEqual(tcl.getint(42), 42)
152 self.assertRaises(TypeError, tcl.getint)
153 self.assertRaises(TypeError, tcl.getint, '42', '10')
154 self.assertRaises(TypeError, tcl.getint, 42.0)
155 self.assertRaises(TclError, tcl.getint, 'a')
156 self.assertRaises((TypeError, ValueError, TclError),
157 tcl.getint, '42\0')
158 if test_support.have_unicode:
159 self.assertEqual(tcl.getint(unicode('42')), 42)
160 self.assertRaises((UnicodeEncodeError, ValueError, TclError),
161 tcl.getint, '42' + unichr(0xd800))
162
163 def test_getdouble(self):
164 tcl = self.interp.tk
165 self.assertEqual(tcl.getdouble(' 42 '), 42.0)
166 self.assertEqual(tcl.getdouble(' 42.5 '), 42.5)
167 self.assertEqual(tcl.getdouble(42.5), 42.5)
168 self.assertRaises(TypeError, tcl.getdouble)
169 self.assertRaises(TypeError, tcl.getdouble, '42.5', '10')
170 self.assertRaises(TypeError, tcl.getdouble, 42)
171 self.assertRaises(TclError, tcl.getdouble, 'a')
172 self.assertRaises((TypeError, ValueError, TclError),
173 tcl.getdouble, '42.5\0')
174 if test_support.have_unicode:
175 self.assertEqual(tcl.getdouble(unicode('42.5')), 42.5)
176 self.assertRaises((UnicodeEncodeError, ValueError, TclError),
177 tcl.getdouble, '42.5' + unichr(0xd800))
178
179 def test_getboolean(self):
180 tcl = self.interp.tk
181 self.assertIs(tcl.getboolean('on'), True)
182 self.assertIs(tcl.getboolean('1'), True)
Serhiy Storchakaf29bc702015-04-04 12:42:25 +0300183 self.assertIs(tcl.getboolean(u'on'), True)
184 self.assertIs(tcl.getboolean(u'1'), True)
185 self.assertIs(tcl.getboolean(42), True)
186 self.assertIs(tcl.getboolean(0), False)
187 self.assertIs(tcl.getboolean(42L), True)
188 self.assertIs(tcl.getboolean(0L), False)
Serhiy Storchakad11e8b62014-05-30 14:07:20 +0300189 self.assertRaises(TypeError, tcl.getboolean)
190 self.assertRaises(TypeError, tcl.getboolean, 'on', '1')
191 self.assertRaises(TypeError, tcl.getboolean, 1.0)
192 self.assertRaises(TclError, tcl.getboolean, 'a')
193 self.assertRaises((TypeError, ValueError, TclError),
194 tcl.getboolean, 'on\0')
195 if test_support.have_unicode:
196 self.assertIs(tcl.getboolean(unicode('on')), True)
197 self.assertRaises((UnicodeEncodeError, ValueError, TclError),
198 tcl.getboolean, 'on' + unichr(0xd800))
199
David Aschere2b4b322004-02-18 05:59:53 +0000200 def testEvalFile(self):
201 tcl = self.interp
202 filename = "testEvalFile.tcl"
203 fd = open(filename,'w')
204 script = """set a 1
205 set b 2
206 set c [ expr $a + $b ]
207 """
208 fd.write(script)
209 fd.close()
210 tcl.evalfile(filename)
Neal Norwitz9a8d55e2004-02-29 15:37:50 +0000211 os.remove(filename)
David Aschere2b4b322004-02-18 05:59:53 +0000212 self.assertEqual(tcl.eval('set a'),'1')
213 self.assertEqual(tcl.eval('set b'),'2')
214 self.assertEqual(tcl.eval('set c'),'3')
215
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200216 def test_evalfile_null_in_result(self):
217 tcl = self.interp
218 with open(test_support.TESTFN, 'wb') as f:
219 self.addCleanup(test_support.unlink, test_support.TESTFN)
220 f.write("""
221 set a "a\0b"
222 set b "a\\0b"
223 """)
224 tcl.evalfile(test_support.TESTFN)
225 self.assertEqual(tcl.eval('set a'), 'a\xc0\x80b')
226 self.assertEqual(tcl.eval('set b'), 'a\xc0\x80b')
227
David Aschere2b4b322004-02-18 05:59:53 +0000228 def testEvalFileException(self):
229 tcl = self.interp
230 filename = "doesnotexists"
231 try:
232 os.remove(filename)
233 except Exception,e:
234 pass
235 self.assertRaises(TclError,tcl.evalfile,filename)
236
David Aschere2b4b322004-02-18 05:59:53 +0000237 def testPackageRequireException(self):
238 tcl = self.interp
239 self.assertRaises(TclError,tcl.eval,'package require DNE')
240
Zachary Ware57d35c62013-11-03 22:51:25 -0600241 @unittest.skipUnless(sys.platform == 'win32', "only applies to Windows")
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000242 def testLoadWithUNC(self):
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000243 # Build a UNC path from the regular path.
244 # Something like
245 # \\%COMPUTERNAME%\c$\python27\python.exe
246
247 fullname = os.path.abspath(sys.executable)
248 if fullname[1] != ':':
Zachary Ware57d35c62013-11-03 22:51:25 -0600249 self.skipTest('unusable path: %r' % fullname)
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000250 unc_name = r'\\%s\%s$\%s' % (os.environ['COMPUTERNAME'],
251 fullname[0],
252 fullname[3:])
253
254 with test_support.EnvironmentVarGuard() as env:
255 env.unset("TCL_LIBRARY")
Ezio Melotti794e5572013-05-07 09:34:49 +0300256 cmd = '%s -c "import Tkinter; print Tkinter"' % (unc_name,)
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000257
Zachary Ware57d35c62013-11-03 22:51:25 -0600258 try:
259 p = Popen(cmd, stdout=PIPE, stderr=PIPE)
260 except WindowsError as e:
261 if e.winerror == 5:
262 self.skipTest('Not permitted to start the child process')
263 else:
264 raise
265
Ezio Melotti794e5572013-05-07 09:34:49 +0300266 out_data, err_data = p.communicate()
267
268 msg = '\n\n'.join(['"Tkinter.py" not in output',
269 'Command:', cmd,
270 'stdout:', out_data,
271 'stderr:', err_data])
272
273 self.assertIn('Tkinter.py', out_data, msg)
274
275 self.assertEqual(p.wait(), 0, 'Non-zero exit code')
276
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000277
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200278 def test_exprstring(self):
279 tcl = self.interp
280 tcl.call('set', 'a', 3)
281 tcl.call('set', 'b', 6)
282 def check(expr, expected):
283 result = tcl.exprstring(expr)
284 self.assertEqual(result, expected)
285 self.assertIsInstance(result, str)
286
287 self.assertRaises(TypeError, tcl.exprstring)
288 self.assertRaises(TypeError, tcl.exprstring, '8.2', '+6')
289 self.assertRaises(TclError, tcl.exprstring, 'spam')
290 check('', '0')
291 check('8.2 + 6', '14.2')
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200292 check('3.1 + $a', '6.1')
293 check('2 + "$a.$b"', '5.6')
294 check('4*[llength "6 2"]', '8')
295 check('{word one} < "word $a"', '0')
296 check('4*2 < 7', '0')
297 check('hypot($a, 4)', '5.0')
298 check('5 / 4', '1')
299 check('5 / 4.0', '1.25')
300 check('5 / ( [string length "abcd"] + 0.0 )', '1.25')
301 check('20.0/5.0', '4.0')
302 check('"0x03" > "2"', '1')
303 check('[string length "a\xc2\xbd\xe2\x82\xac"]', '3')
304 check(r'[string length "a\xbd\u20ac"]', '3')
305 check('"abc"', 'abc')
306 check('"a\xc2\xbd\xe2\x82\xac"', 'a\xc2\xbd\xe2\x82\xac')
307 check(r'"a\xbd\u20ac"', 'a\xc2\xbd\xe2\x82\xac')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200308 check(r'"a\0b"', 'a\xc0\x80b')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300309 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200310 check('2**64', str(2**64))
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200311
312 def test_exprdouble(self):
313 tcl = self.interp
314 tcl.call('set', 'a', 3)
315 tcl.call('set', 'b', 6)
316 def check(expr, expected):
317 result = tcl.exprdouble(expr)
318 self.assertEqual(result, expected)
319 self.assertIsInstance(result, float)
320
321 self.assertRaises(TypeError, tcl.exprdouble)
322 self.assertRaises(TypeError, tcl.exprdouble, '8.2', '+6')
323 self.assertRaises(TclError, tcl.exprdouble, 'spam')
324 check('', 0.0)
325 check('8.2 + 6', 14.2)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200326 check('3.1 + $a', 6.1)
327 check('2 + "$a.$b"', 5.6)
328 check('4*[llength "6 2"]', 8.0)
329 check('{word one} < "word $a"', 0.0)
330 check('4*2 < 7', 0.0)
331 check('hypot($a, 4)', 5.0)
332 check('5 / 4', 1.0)
333 check('5 / 4.0', 1.25)
334 check('5 / ( [string length "abcd"] + 0.0 )', 1.25)
335 check('20.0/5.0', 4.0)
336 check('"0x03" > "2"', 1.0)
337 check('[string length "a\xc2\xbd\xe2\x82\xac"]', 3.0)
338 check(r'[string length "a\xbd\u20ac"]', 3.0)
339 self.assertRaises(TclError, tcl.exprdouble, '"abc"')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300340 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200341 check('2**64', float(2**64))
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200342
343 def test_exprlong(self):
344 tcl = self.interp
345 tcl.call('set', 'a', 3)
346 tcl.call('set', 'b', 6)
347 def check(expr, expected):
348 result = tcl.exprlong(expr)
349 self.assertEqual(result, expected)
350 self.assertIsInstance(result, int)
351
352 self.assertRaises(TypeError, tcl.exprlong)
353 self.assertRaises(TypeError, tcl.exprlong, '8.2', '+6')
354 self.assertRaises(TclError, tcl.exprlong, 'spam')
355 check('', 0)
356 check('8.2 + 6', 14)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200357 check('3.1 + $a', 6)
358 check('2 + "$a.$b"', 5)
359 check('4*[llength "6 2"]', 8)
360 check('{word one} < "word $a"', 0)
361 check('4*2 < 7', 0)
362 check('hypot($a, 4)', 5)
363 check('5 / 4', 1)
364 check('5 / 4.0', 1)
365 check('5 / ( [string length "abcd"] + 0.0 )', 1)
366 check('20.0/5.0', 4)
367 check('"0x03" > "2"', 1)
368 check('[string length "a\xc2\xbd\xe2\x82\xac"]', 3)
369 check(r'[string length "a\xbd\u20ac"]', 3)
370 self.assertRaises(TclError, tcl.exprlong, '"abc"')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300371 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200372 self.assertRaises(TclError, tcl.exprlong, '2**64')
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200373
374 def test_exprboolean(self):
375 tcl = self.interp
376 tcl.call('set', 'a', 3)
377 tcl.call('set', 'b', 6)
378 def check(expr, expected):
379 result = tcl.exprboolean(expr)
380 self.assertEqual(result, expected)
381 self.assertIsInstance(result, int)
382 self.assertNotIsInstance(result, bool)
383
384 self.assertRaises(TypeError, tcl.exprboolean)
385 self.assertRaises(TypeError, tcl.exprboolean, '8.2', '+6')
386 self.assertRaises(TclError, tcl.exprboolean, 'spam')
387 check('', False)
388 for value in ('0', 'false', 'no', 'off'):
389 check(value, False)
390 check('"%s"' % value, False)
391 check('{%s}' % value, False)
392 for value in ('1', 'true', 'yes', 'on'):
393 check(value, True)
394 check('"%s"' % value, True)
395 check('{%s}' % value, True)
396 check('8.2 + 6', True)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200397 check('3.1 + $a', True)
398 check('2 + "$a.$b"', True)
399 check('4*[llength "6 2"]', True)
400 check('{word one} < "word $a"', False)
401 check('4*2 < 7', False)
402 check('hypot($a, 4)', True)
403 check('5 / 4', True)
404 check('5 / 4.0', True)
405 check('5 / ( [string length "abcd"] + 0.0 )', True)
406 check('20.0/5.0', True)
407 check('"0x03" > "2"', True)
408 check('[string length "a\xc2\xbd\xe2\x82\xac"]', True)
409 check(r'[string length "a\xbd\u20ac"]', True)
410 self.assertRaises(TclError, tcl.exprboolean, '"abc"')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300411 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200412 check('2**64', True)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200413
Serhiy Storchakae8ae0472015-04-02 19:57:52 +0300414 @unittest.skipUnless(tcl_version >= (8, 5), 'requires Tcl version >= 8.5')
Serhiy Storchakacba6b5d2015-04-02 10:35:57 +0300415 def test_booleans(self):
416 tcl = self.interp
417 def check(expr, expected):
418 result = tcl.call('expr', expr)
Serhiy Storchaka91398f82015-04-02 11:46:07 +0300419 if tcl.wantobjects():
420 self.assertEqual(result, expected)
421 self.assertIsInstance(result, int)
422 else:
423 self.assertIn(result, (expr, str(int(expected))))
424 self.assertIsInstance(result, str)
Serhiy Storchakacba6b5d2015-04-02 10:35:57 +0300425 check('true', True)
426 check('yes', True)
427 check('on', True)
428 check('false', False)
429 check('no', False)
430 check('off', False)
431 check('1 < 2', True)
432 check('1 > 2', False)
433
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300434 def test_expr_bignum(self):
435 tcl = self.interp
436 for i in self.get_integers():
437 result = tcl.call('expr', str(i))
438 if self.wantobjects:
439 self.assertEqual(result, i)
440 self.assertIsInstance(result, (int, long))
Serhiy Storchaka4507b812015-04-10 21:12:18 +0300441 if abs(result) < 2**31:
442 self.assertIsInstance(result, int)
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300443 else:
444 self.assertEqual(result, str(i))
445 self.assertIsInstance(result, str)
446 if tcl_version < (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka61ad42e2015-04-02 20:06:48 +0300447 self.assertRaises(TclError, tcl.call, 'expr', str(2**1000))
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300448
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200449 def test_passing_values(self):
450 def passValue(value):
451 return self.interp.call('set', '_', value)
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200452
453 self.assertEqual(passValue(True), True if self.wantobjects else '1')
454 self.assertEqual(passValue(False), False if self.wantobjects else '0')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200455 self.assertEqual(passValue('string'), 'string')
456 self.assertEqual(passValue('string\xbd'), 'string\xbd')
457 self.assertEqual(passValue('string\xe2\x82\xac'), u'string\u20ac')
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200458 self.assertEqual(passValue(u'string'), u'string')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200459 self.assertEqual(passValue(u'string\xbd'), u'string\xbd')
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200460 self.assertEqual(passValue(u'string\u20ac'), u'string\u20ac')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200461 self.assertEqual(passValue('str\x00ing'), 'str\x00ing')
462 self.assertEqual(passValue('str\xc0\x80ing'), 'str\x00ing')
463 self.assertEqual(passValue(u'str\x00ing'), u'str\x00ing')
464 self.assertEqual(passValue(u'str\x00ing\xbd'), u'str\x00ing\xbd')
465 self.assertEqual(passValue(u'str\x00ing\u20ac'), u'str\x00ing\u20ac')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300466 for i in self.get_integers():
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200467 self.assertEqual(passValue(i), i if self.wantobjects else str(i))
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300468 if tcl_version < (8, 5): # bignum was added in Tcl 8.5
469 self.assertEqual(passValue(2**1000), str(2**1000))
Ezio Melotti0a4a7e12013-02-23 08:19:00 +0200470 for f in (0.0, 1.0, -1.0, 1//3, 1/3.0,
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200471 sys.float_info.min, sys.float_info.max,
472 -sys.float_info.min, -sys.float_info.max):
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200473 if self.wantobjects:
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200474 self.assertEqual(passValue(f), f)
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200475 else:
476 self.assertEqual(float(passValue(f)), f)
477 if self.wantobjects:
478 f = passValue(float('nan'))
479 self.assertNotEqual(f, f)
480 self.assertEqual(passValue(float('inf')), float('inf'))
481 self.assertEqual(passValue(-float('inf')), -float('inf'))
482 else:
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200483 self.assertEqual(float(passValue(float('inf'))), float('inf'))
484 self.assertEqual(float(passValue(-float('inf'))), -float('inf'))
Serhiy Storchaka5fc570f2014-07-07 14:47:17 +0300485 # XXX NaN representation can be not parsable by float()
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200486 self.assertEqual(passValue((1, '2', (3.4,))),
487 (1, '2', (3.4,)) if self.wantobjects else '1 2 3.4')
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000488
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200489 def test_user_command(self):
490 result = []
491 def testfunc(arg):
492 result.append(arg)
493 return arg
494 self.interp.createcommand('testfunc', testfunc)
Antoine Pitrouaa73ea02014-02-23 19:39:06 +0100495 self.addCleanup(self.interp.tk.deletecommand, 'testfunc')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300496 def check(value, expected=None, eq=self.assertEqual):
497 if expected is None:
498 expected = value
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200499 del result[:]
Serhiy Storchaka83515ec2014-01-23 11:03:02 +0200500 r = self.interp.call('testfunc', value)
501 self.assertEqual(len(result), 1)
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200502 self.assertIsInstance(result[0], (str, unicode))
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300503 eq(result[0], expected)
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200504 self.assertIsInstance(r, (str, unicode))
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300505 eq(r, expected)
Serhiy Storchakadc976672014-01-23 14:38:44 +0200506 def float_eq(actual, expected):
Serhiy Storchakaeb7ef942014-01-23 16:08:35 +0200507 self.assertAlmostEqual(float(actual), expected,
508 delta=abs(expected) * 1e-10)
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200509
510 check(True, '1')
511 check(False, '0')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300512 check('string')
513 check('string\xbd')
514 check('string\xe2\x82\xac', u'string\u20ac')
Serhiy Storchaka17c01782014-09-11 10:56:59 +0300515 check('')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300516 check(u'string')
517 check(u'string\xbd')
518 check(u'string\u20ac')
Serhiy Storchaka17c01782014-09-11 10:56:59 +0300519 check(u'')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300520 check('str\xc0\x80ing', u'str\x00ing')
521 check('str\xc0\x80ing\xe2\x82\xac', u'str\x00ing\u20ac')
522 check(u'str\x00ing')
523 check(u'str\x00ing\xbd')
524 check(u'str\x00ing\u20ac')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300525 for i in self.get_integers():
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200526 check(i, str(i))
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300527 if tcl_version < (8, 5): # bignum was added in Tcl 8.5
528 check(2**1000, str(2**1000))
Serhiy Storchakadc976672014-01-23 14:38:44 +0200529 for f in (0.0, 1.0, -1.0):
530 check(f, repr(f))
531 for f in (1/3.0, sys.float_info.min, sys.float_info.max,
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200532 -sys.float_info.min, -sys.float_info.max):
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300533 check(f, eq=float_eq)
534 check(float('inf'), eq=float_eq)
535 check(-float('inf'), eq=float_eq)
Serhiy Storchaka5fc570f2014-07-07 14:47:17 +0300536 # XXX NaN representation can be not parsable by float()
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200537 check((), '')
538 check((1, (2,), (3, 4), '5 6', ()), '1 2 {3 4} {5 6} {}')
539
Serhiy Storchakafab65422013-07-11 20:32:48 +0300540 def test_splitlist(self):
541 splitlist = self.interp.tk.splitlist
542 call = self.interp.tk.call
543 self.assertRaises(TypeError, splitlist)
544 self.assertRaises(TypeError, splitlist, 'a', 'b')
545 self.assertRaises(TypeError, splitlist, 2)
546 testcases = [
547 ('2', ('2',)),
548 ('', ()),
549 ('{}', ('',)),
550 ('""', ('',)),
551 ('a\n b\t\r c\n ', ('a', 'b', 'c')),
552 (u'a\n b\t\r c\n ', ('a', 'b', 'c')),
553 ('a \xe2\x82\xac', ('a', '\xe2\x82\xac')),
554 (u'a \u20ac', ('a', '\xe2\x82\xac')),
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200555 ('a\xc0\x80b c\xc0\x80d', ('a\xc0\x80b', 'c\xc0\x80d')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300556 ('a {b c}', ('a', 'b c')),
557 (r'a b\ c', ('a', 'b c')),
558 (('a', 'b c'), ('a', 'b c')),
559 ('a 2', ('a', '2')),
560 (('a', 2), ('a', 2)),
561 ('a 3.4', ('a', '3.4')),
562 (('a', 3.4), ('a', 3.4)),
563 ((), ()),
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200564 (call('list', 1, '2', (3.4,)),
565 (1, '2', (3.4,)) if self.wantobjects else
566 ('1', '2', '3.4')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300567 ]
Serhiy Storchaka94025332013-09-08 20:32:56 +0300568 if tcl_version >= (8, 5):
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200569 if not self.wantobjects:
570 expected = ('12', '\xe2\x82\xac', '\xe2\x82\xac', '3.4')
571 elif get_tk_patchlevel() < (8, 5, 5):
572 # Before 8.5.5 dicts were converted to lists through string
573 expected = ('12', u'\u20ac', u'\u20ac', '3.4')
574 else:
575 expected = (12, u'\u20ac', u'\u20ac', (3.4,))
Serhiy Storchaka94025332013-09-08 20:32:56 +0300576 testcases += [
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200577 (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)),
578 expected),
Serhiy Storchaka94025332013-09-08 20:32:56 +0300579 ]
Serhiy Storchakafab65422013-07-11 20:32:48 +0300580 for arg, res in testcases:
581 self.assertEqual(splitlist(arg), res)
582 self.assertRaises(TclError, splitlist, '{')
583
584 def test_split(self):
585 split = self.interp.tk.split
586 call = self.interp.tk.call
587 self.assertRaises(TypeError, split)
588 self.assertRaises(TypeError, split, 'a', 'b')
589 self.assertRaises(TypeError, split, 2)
590 testcases = [
591 ('2', '2'),
592 ('', ''),
593 ('{}', ''),
594 ('""', ''),
595 ('{', '{'),
596 ('a\n b\t\r c\n ', ('a', 'b', 'c')),
597 (u'a\n b\t\r c\n ', ('a', 'b', 'c')),
598 ('a \xe2\x82\xac', ('a', '\xe2\x82\xac')),
599 (u'a \u20ac', ('a', '\xe2\x82\xac')),
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200600 ('a\xc0\x80b', 'a\xc0\x80b'),
601 ('a\xc0\x80b c\xc0\x80d', ('a\xc0\x80b', 'c\xc0\x80d')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300602 ('a {b c}', ('a', ('b', 'c'))),
603 (r'a b\ c', ('a', ('b', 'c'))),
604 (('a', 'b c'), ('a', ('b', 'c'))),
605 (('a', u'b c'), ('a', ('b', 'c'))),
606 ('a 2', ('a', '2')),
607 (('a', 2), ('a', 2)),
608 ('a 3.4', ('a', '3.4')),
609 (('a', 3.4), ('a', 3.4)),
610 (('a', (2, 3.4)), ('a', (2, 3.4))),
611 ((), ()),
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200612 (call('list', 1, '2', (3.4,)),
613 (1, '2', (3.4,)) if self.wantobjects else
614 ('1', '2', '3.4')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300615 ]
Serhiy Storchaka94025332013-09-08 20:32:56 +0300616 if tcl_version >= (8, 5):
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200617 if not self.wantobjects:
618 expected = ('12', '\xe2\x82\xac', '\xe2\x82\xac', '3.4')
619 elif get_tk_patchlevel() < (8, 5, 5):
620 # Before 8.5.5 dicts were converted to lists through string
621 expected = ('12', u'\u20ac', u'\u20ac', '3.4')
622 else:
623 expected = (12, u'\u20ac', u'\u20ac', (3.4,))
Serhiy Storchaka94025332013-09-08 20:32:56 +0300624 testcases += [
625 (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)),
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200626 expected),
Serhiy Storchaka94025332013-09-08 20:32:56 +0300627 ]
Serhiy Storchakafab65422013-07-11 20:32:48 +0300628 for arg, res in testcases:
629 self.assertEqual(split(arg), res)
630
Serhiy Storchakaceaf6822014-09-06 22:47:02 +0300631 def test_splitdict(self):
632 splitdict = tkinter._splitdict
633 tcl = self.interp.tk
634
635 arg = '-a {1 2 3} -something foo status {}'
636 self.assertEqual(splitdict(tcl, arg, False),
637 {'-a': '1 2 3', '-something': 'foo', 'status': ''})
638 self.assertEqual(splitdict(tcl, arg),
639 {'a': '1 2 3', 'something': 'foo', 'status': ''})
640
641 arg = ('-a', (1, 2, 3), '-something', 'foo', 'status', '{}')
642 self.assertEqual(splitdict(tcl, arg, False),
643 {'-a': (1, 2, 3), '-something': 'foo', 'status': '{}'})
644 self.assertEqual(splitdict(tcl, arg),
645 {'a': (1, 2, 3), 'something': 'foo', 'status': '{}'})
646
647 self.assertRaises(RuntimeError, splitdict, tcl, '-a b -c ')
648 self.assertRaises(RuntimeError, splitdict, tcl, ('-a', 'b', '-c'))
649
650 arg = tcl.call('list',
651 '-a', (1, 2, 3), '-something', 'foo', 'status', ())
652 self.assertEqual(splitdict(tcl, arg),
653 {'a': (1, 2, 3) if self.wantobjects else '1 2 3',
654 'something': 'foo', 'status': ''})
655
656 if tcl_version >= (8, 5):
657 arg = tcl.call('dict', 'create',
658 '-a', (1, 2, 3), '-something', 'foo', 'status', ())
659 if not self.wantobjects or get_tk_patchlevel() < (8, 5, 5):
660 # Before 8.5.5 dicts were converted to lists through string
661 expected = {'a': '1 2 3', 'something': 'foo', 'status': ''}
662 else:
663 expected = {'a': (1, 2, 3), 'something': 'foo', 'status': ''}
664 self.assertEqual(splitdict(tcl, arg), expected)
665
666
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300667character_size = 4 if sys.maxunicode > 0xFFFF else 2
Neal Norwitz63dfece2004-02-19 02:37:29 +0000668
Serhiy Storchaka42035702013-08-21 21:46:12 +0300669class BigmemTclTest(unittest.TestCase):
670
671 def setUp(self):
672 self.interp = Tcl()
673
Serhiy Storchaka76249ea2014-02-07 10:06:05 +0200674 @test_support.cpython_only
675 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
676 @test_support.precisionbigmemtest(size=INT_MAX + 1, memuse=5, dry_run=False)
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300677 def test_huge_string_call(self, size):
Serhiy Storchaka42035702013-08-21 21:46:12 +0300678 value = ' ' * size
679 self.assertRaises(OverflowError, self.interp.call, 'set', '_', value)
680
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300681 @test_support.cpython_only
682 @unittest.skipUnless(test_support.have_unicode, 'requires unicode support')
683 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
684 @test_support.precisionbigmemtest(size=INT_MAX + 1,
685 memuse=2*character_size + 2,
686 dry_run=False)
687 def test_huge_unicode_call(self, size):
688 value = unicode(' ') * size
689 self.assertRaises(OverflowError, self.interp.call, 'set', '_', value)
690
691
692 @test_support.cpython_only
693 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
694 @test_support.precisionbigmemtest(size=INT_MAX + 1, memuse=9, dry_run=False)
695 def test_huge_string_builtins(self, size):
696 value = '1' + ' ' * size
697 self.check_huge_string_builtins(value)
698
699 @test_support.cpython_only
700 @unittest.skipUnless(test_support.have_unicode, 'requires unicode support')
701 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
702 @test_support.precisionbigmemtest(size=INT_MAX + 1,
703 memuse=2*character_size + 7,
704 dry_run=False)
705 def test_huge_unicode_builtins(self, size):
706 value = unicode('1' + ' ' * size)
707 self.check_huge_string_builtins(value)
708
709 def check_huge_string_builtins(self, value):
710 self.assertRaises(OverflowError, self.interp.tk.getint, value)
711 self.assertRaises(OverflowError, self.interp.tk.getdouble, value)
712 self.assertRaises(OverflowError, self.interp.tk.getboolean, value)
713 self.assertRaises(OverflowError, self.interp.eval, value)
714 self.assertRaises(OverflowError, self.interp.evalfile, value)
715 self.assertRaises(OverflowError, self.interp.record, value)
716 self.assertRaises(OverflowError, self.interp.adderrorinfo, value)
717 self.assertRaises(OverflowError, self.interp.setvar, value, 'x', 'a')
718 self.assertRaises(OverflowError, self.interp.setvar, 'x', value, 'a')
719 self.assertRaises(OverflowError, self.interp.unsetvar, value)
720 self.assertRaises(OverflowError, self.interp.unsetvar, 'x', value)
721 self.assertRaises(OverflowError, self.interp.adderrorinfo, value)
722 self.assertRaises(OverflowError, self.interp.exprstring, value)
723 self.assertRaises(OverflowError, self.interp.exprlong, value)
724 self.assertRaises(OverflowError, self.interp.exprboolean, value)
725 self.assertRaises(OverflowError, self.interp.splitlist, value)
726 self.assertRaises(OverflowError, self.interp.split, value)
727 self.assertRaises(OverflowError, self.interp.createcommand, value, max)
728 self.assertRaises(OverflowError, self.interp.deletecommand, value)
729
Serhiy Storchaka42035702013-08-21 21:46:12 +0300730
Serhiy Storchaka78ecaba2013-11-20 17:44:38 +0200731def setUpModule():
732 if test_support.verbose:
733 tcl = Tcl()
734 print 'patchlevel =', tcl.call('info', 'patchlevel')
735
736
Neal Norwitz63dfece2004-02-19 02:37:29 +0000737def test_main():
Serhiy Storchaka42035702013-08-21 21:46:12 +0300738 test_support.run_unittest(TclTest, TkinterTest, BigmemTclTest)
Neal Norwitz63dfece2004-02-19 02:37:29 +0000739
David Aschere2b4b322004-02-18 05:59:53 +0000740if __name__ == "__main__":
Neal Norwitz63dfece2004-02-19 02:37:29 +0000741 test_main()