blob: 4c2e8d5200c480c71d3d232139b311827f562baf [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
Zachary Ware47343722015-07-16 00:24:48 -050011import Tkinter as tkinter
Guilherme Polo8e5e4382009-02-07 02:20:29 +000012from Tkinter import Tcl
David Aschere2b4b322004-02-18 05:59:53 +000013from _tkinter import TclError
14
Serhiy Storchaka76249ea2014-02-07 10:06:05 +020015try:
16 from _testcapi import INT_MAX, PY_SSIZE_T_MAX
17except ImportError:
18 INT_MAX = PY_SSIZE_T_MAX = sys.maxsize
19
Serhiy Storchakadcb12f42015-04-22 08:35:53 +030020tcl_version = tuple(map(int, _tkinter.TCL_VERSION.split('.')))
Serhiy Storchaka94025332013-09-08 20:32:56 +030021
Serhiy Storchaka15b67d72014-02-02 23:04:06 +020022_tk_patchlevel = None
23def get_tk_patchlevel():
24 global _tk_patchlevel
25 if _tk_patchlevel is None:
26 tcl = Tcl()
Serhiy Storchakadcb12f42015-04-22 08:35:53 +030027 patchlevel = tcl.call('info', 'patchlevel')
28 m = re.match(r'(\d+)\.(\d+)([ab.])(\d+)$', patchlevel)
29 major, minor, releaselevel, serial = m.groups()
30 major, minor, serial = int(major), int(minor), int(serial)
31 releaselevel = {'a': 'alpha', 'b': 'beta', '.': 'final'}[releaselevel]
32 if releaselevel == 'final':
33 _tk_patchlevel = major, minor, serial, releaselevel, 0
34 else:
35 _tk_patchlevel = major, minor, 0, releaselevel, serial
Serhiy Storchaka15b67d72014-02-02 23:04:06 +020036 return _tk_patchlevel
37
Benjamin Petersonb3619be2009-01-30 02:24:39 +000038
39class TkinterTest(unittest.TestCase):
40
41 def testFlattenLen(self):
42 # flatten(<object with no length>)
43 self.assertRaises(TypeError, _tkinter._flatten, True)
44
45
David Aschere2b4b322004-02-18 05:59:53 +000046class TclTest(unittest.TestCase):
47
48 def setUp(self):
49 self.interp = Tcl()
Serhiy Storchaka5542b152013-12-25 17:28:50 +020050 self.wantobjects = self.interp.tk.wantobjects()
David Aschere2b4b322004-02-18 05:59:53 +000051
52 def testEval(self):
53 tcl = self.interp
54 tcl.eval('set a 1')
55 self.assertEqual(tcl.eval('set a'),'1')
56
57 def testEvalException(self):
58 tcl = self.interp
59 self.assertRaises(TclError,tcl.eval,'set a')
60
61 def testEvalException2(self):
62 tcl = self.interp
63 self.assertRaises(TclError,tcl.eval,'this is wrong')
64
65 def testCall(self):
66 tcl = self.interp
67 tcl.call('set','a','1')
68 self.assertEqual(tcl.call('set','a'),'1')
69
70 def testCallException(self):
71 tcl = self.interp
72 self.assertRaises(TclError,tcl.call,'set','a')
73
74 def testCallException2(self):
75 tcl = self.interp
76 self.assertRaises(TclError,tcl.call,'this','is','wrong')
77
78 def testSetVar(self):
79 tcl = self.interp
80 tcl.setvar('a','1')
81 self.assertEqual(tcl.eval('set a'),'1')
82
83 def testSetVarArray(self):
84 tcl = self.interp
85 tcl.setvar('a(1)','1')
86 self.assertEqual(tcl.eval('set a(1)'),'1')
87
88 def testGetVar(self):
89 tcl = self.interp
90 tcl.eval('set a 1')
91 self.assertEqual(tcl.getvar('a'),'1')
92
93 def testGetVarArray(self):
94 tcl = self.interp
95 tcl.eval('set a(1) 1')
96 self.assertEqual(tcl.getvar('a(1)'),'1')
97
98 def testGetVarException(self):
99 tcl = self.interp
100 self.assertRaises(TclError,tcl.getvar,'a')
101
102 def testGetVarArrayException(self):
103 tcl = self.interp
104 self.assertRaises(TclError,tcl.getvar,'a(1)')
105
106 def testUnsetVar(self):
107 tcl = self.interp
108 tcl.setvar('a',1)
109 self.assertEqual(tcl.eval('info exists a'),'1')
110 tcl.unsetvar('a')
111 self.assertEqual(tcl.eval('info exists a'),'0')
112
113 def testUnsetVarArray(self):
114 tcl = self.interp
115 tcl.setvar('a(1)',1)
116 tcl.setvar('a(2)',2)
117 self.assertEqual(tcl.eval('info exists a(1)'),'1')
118 self.assertEqual(tcl.eval('info exists a(2)'),'1')
119 tcl.unsetvar('a(1)')
120 self.assertEqual(tcl.eval('info exists a(1)'),'0')
121 self.assertEqual(tcl.eval('info exists a(2)'),'1')
122
123 def testUnsetVarException(self):
124 tcl = self.interp
125 self.assertRaises(TclError,tcl.unsetvar,'a')
Tim Peters27f88362004-07-08 04:22:35 +0000126
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300127 def get_integers(self):
128 integers = (0, 1, -1, 2**31-1, -2**31)
129 if tcl_version >= (8, 4): # wideInt was added in Tcl 8.4
130 integers += (2**31, -2**31-1, 2**63-1, -2**63)
Serhiy Storchaka6294d9f2015-04-22 10:51:49 +0300131 # bignum was added in Tcl 8.5, but its support is able only since 8.5.8
132 if (get_tk_patchlevel() >= (8, 6, 0, 'final') or
133 (8, 5, 8) <= get_tk_patchlevel() < (8, 6)):
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300134 integers += (2**63, -2**63-1, 2**1000, -2**1000)
135 return integers
136
Serhiy Storchakad11e8b62014-05-30 14:07:20 +0300137 def test_getint(self):
138 tcl = self.interp.tk
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300139 for i in self.get_integers():
140 result = tcl.getint(' %d ' % i)
141 self.assertEqual(result, i)
142 self.assertIsInstance(result, type(int(result)))
Serhiy Storchaka61ad42e2015-04-02 20:06:48 +0300143 if tcl_version >= (8, 5):
144 self.assertEqual(tcl.getint(' {:#o} '.format(i)), i)
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300145 self.assertEqual(tcl.getint(' %#o ' % i), i)
146 self.assertEqual(tcl.getint(' %#x ' % i), i)
147 if tcl_version < (8, 5): # bignum was added in Tcl 8.5
148 self.assertRaises(TclError, tcl.getint, str(2**1000))
Serhiy Storchakad11e8b62014-05-30 14:07:20 +0300149 self.assertEqual(tcl.getint(42), 42)
150 self.assertRaises(TypeError, tcl.getint)
151 self.assertRaises(TypeError, tcl.getint, '42', '10')
152 self.assertRaises(TypeError, tcl.getint, 42.0)
153 self.assertRaises(TclError, tcl.getint, 'a')
154 self.assertRaises((TypeError, ValueError, TclError),
155 tcl.getint, '42\0')
156 if test_support.have_unicode:
157 self.assertEqual(tcl.getint(unicode('42')), 42)
158 self.assertRaises((UnicodeEncodeError, ValueError, TclError),
159 tcl.getint, '42' + unichr(0xd800))
160
161 def test_getdouble(self):
162 tcl = self.interp.tk
163 self.assertEqual(tcl.getdouble(' 42 '), 42.0)
164 self.assertEqual(tcl.getdouble(' 42.5 '), 42.5)
165 self.assertEqual(tcl.getdouble(42.5), 42.5)
166 self.assertRaises(TypeError, tcl.getdouble)
167 self.assertRaises(TypeError, tcl.getdouble, '42.5', '10')
168 self.assertRaises(TypeError, tcl.getdouble, 42)
169 self.assertRaises(TclError, tcl.getdouble, 'a')
170 self.assertRaises((TypeError, ValueError, TclError),
171 tcl.getdouble, '42.5\0')
172 if test_support.have_unicode:
173 self.assertEqual(tcl.getdouble(unicode('42.5')), 42.5)
174 self.assertRaises((UnicodeEncodeError, ValueError, TclError),
175 tcl.getdouble, '42.5' + unichr(0xd800))
176
177 def test_getboolean(self):
178 tcl = self.interp.tk
179 self.assertIs(tcl.getboolean('on'), True)
180 self.assertIs(tcl.getboolean('1'), True)
Serhiy Storchakaf29bc702015-04-04 12:42:25 +0300181 self.assertIs(tcl.getboolean(u'on'), True)
182 self.assertIs(tcl.getboolean(u'1'), True)
183 self.assertIs(tcl.getboolean(42), True)
184 self.assertIs(tcl.getboolean(0), False)
185 self.assertIs(tcl.getboolean(42L), True)
186 self.assertIs(tcl.getboolean(0L), False)
Serhiy Storchakad11e8b62014-05-30 14:07:20 +0300187 self.assertRaises(TypeError, tcl.getboolean)
188 self.assertRaises(TypeError, tcl.getboolean, 'on', '1')
189 self.assertRaises(TypeError, tcl.getboolean, 1.0)
190 self.assertRaises(TclError, tcl.getboolean, 'a')
191 self.assertRaises((TypeError, ValueError, TclError),
192 tcl.getboolean, 'on\0')
193 if test_support.have_unicode:
194 self.assertIs(tcl.getboolean(unicode('on')), True)
195 self.assertRaises((UnicodeEncodeError, ValueError, TclError),
196 tcl.getboolean, 'on' + unichr(0xd800))
197
David Aschere2b4b322004-02-18 05:59:53 +0000198 def testEvalFile(self):
199 tcl = self.interp
200 filename = "testEvalFile.tcl"
201 fd = open(filename,'w')
202 script = """set a 1
203 set b 2
204 set c [ expr $a + $b ]
205 """
206 fd.write(script)
207 fd.close()
208 tcl.evalfile(filename)
Neal Norwitz9a8d55e2004-02-29 15:37:50 +0000209 os.remove(filename)
David Aschere2b4b322004-02-18 05:59:53 +0000210 self.assertEqual(tcl.eval('set a'),'1')
211 self.assertEqual(tcl.eval('set b'),'2')
212 self.assertEqual(tcl.eval('set c'),'3')
213
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200214 def test_evalfile_null_in_result(self):
215 tcl = self.interp
216 with open(test_support.TESTFN, 'wb') as f:
217 self.addCleanup(test_support.unlink, test_support.TESTFN)
218 f.write("""
219 set a "a\0b"
220 set b "a\\0b"
221 """)
222 tcl.evalfile(test_support.TESTFN)
223 self.assertEqual(tcl.eval('set a'), 'a\xc0\x80b')
224 self.assertEqual(tcl.eval('set b'), 'a\xc0\x80b')
225
David Aschere2b4b322004-02-18 05:59:53 +0000226 def testEvalFileException(self):
227 tcl = self.interp
228 filename = "doesnotexists"
229 try:
230 os.remove(filename)
231 except Exception,e:
232 pass
233 self.assertRaises(TclError,tcl.evalfile,filename)
234
David Aschere2b4b322004-02-18 05:59:53 +0000235 def testPackageRequireException(self):
236 tcl = self.interp
237 self.assertRaises(TclError,tcl.eval,'package require DNE')
238
Zachary Ware57d35c62013-11-03 22:51:25 -0600239 @unittest.skipUnless(sys.platform == 'win32', "only applies to Windows")
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000240 def testLoadWithUNC(self):
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000241 # Build a UNC path from the regular path.
242 # Something like
243 # \\%COMPUTERNAME%\c$\python27\python.exe
244
245 fullname = os.path.abspath(sys.executable)
246 if fullname[1] != ':':
Zachary Ware57d35c62013-11-03 22:51:25 -0600247 self.skipTest('unusable path: %r' % fullname)
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000248 unc_name = r'\\%s\%s$\%s' % (os.environ['COMPUTERNAME'],
249 fullname[0],
250 fullname[3:])
251
252 with test_support.EnvironmentVarGuard() as env:
253 env.unset("TCL_LIBRARY")
Ezio Melotti794e5572013-05-07 09:34:49 +0300254 cmd = '%s -c "import Tkinter; print Tkinter"' % (unc_name,)
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000255
Zachary Ware57d35c62013-11-03 22:51:25 -0600256 try:
257 p = Popen(cmd, stdout=PIPE, stderr=PIPE)
258 except WindowsError as e:
259 if e.winerror == 5:
260 self.skipTest('Not permitted to start the child process')
261 else:
262 raise
263
Ezio Melotti794e5572013-05-07 09:34:49 +0300264 out_data, err_data = p.communicate()
265
266 msg = '\n\n'.join(['"Tkinter.py" not in output',
267 'Command:', cmd,
268 'stdout:', out_data,
269 'stderr:', err_data])
270
271 self.assertIn('Tkinter.py', out_data, msg)
272
273 self.assertEqual(p.wait(), 0, 'Non-zero exit code')
274
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000275
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200276 def test_exprstring(self):
277 tcl = self.interp
278 tcl.call('set', 'a', 3)
279 tcl.call('set', 'b', 6)
280 def check(expr, expected):
281 result = tcl.exprstring(expr)
282 self.assertEqual(result, expected)
283 self.assertIsInstance(result, str)
284
285 self.assertRaises(TypeError, tcl.exprstring)
286 self.assertRaises(TypeError, tcl.exprstring, '8.2', '+6')
287 self.assertRaises(TclError, tcl.exprstring, 'spam')
288 check('', '0')
289 check('8.2 + 6', '14.2')
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200290 check('3.1 + $a', '6.1')
291 check('2 + "$a.$b"', '5.6')
292 check('4*[llength "6 2"]', '8')
293 check('{word one} < "word $a"', '0')
294 check('4*2 < 7', '0')
295 check('hypot($a, 4)', '5.0')
296 check('5 / 4', '1')
297 check('5 / 4.0', '1.25')
298 check('5 / ( [string length "abcd"] + 0.0 )', '1.25')
299 check('20.0/5.0', '4.0')
300 check('"0x03" > "2"', '1')
301 check('[string length "a\xc2\xbd\xe2\x82\xac"]', '3')
302 check(r'[string length "a\xbd\u20ac"]', '3')
303 check('"abc"', 'abc')
304 check('"a\xc2\xbd\xe2\x82\xac"', 'a\xc2\xbd\xe2\x82\xac')
305 check(r'"a\xbd\u20ac"', 'a\xc2\xbd\xe2\x82\xac')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200306 check(r'"a\0b"', 'a\xc0\x80b')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300307 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200308 check('2**64', str(2**64))
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200309
310 def test_exprdouble(self):
311 tcl = self.interp
312 tcl.call('set', 'a', 3)
313 tcl.call('set', 'b', 6)
314 def check(expr, expected):
315 result = tcl.exprdouble(expr)
316 self.assertEqual(result, expected)
317 self.assertIsInstance(result, float)
318
319 self.assertRaises(TypeError, tcl.exprdouble)
320 self.assertRaises(TypeError, tcl.exprdouble, '8.2', '+6')
321 self.assertRaises(TclError, tcl.exprdouble, 'spam')
322 check('', 0.0)
323 check('8.2 + 6', 14.2)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200324 check('3.1 + $a', 6.1)
325 check('2 + "$a.$b"', 5.6)
326 check('4*[llength "6 2"]', 8.0)
327 check('{word one} < "word $a"', 0.0)
328 check('4*2 < 7', 0.0)
329 check('hypot($a, 4)', 5.0)
330 check('5 / 4', 1.0)
331 check('5 / 4.0', 1.25)
332 check('5 / ( [string length "abcd"] + 0.0 )', 1.25)
333 check('20.0/5.0', 4.0)
334 check('"0x03" > "2"', 1.0)
335 check('[string length "a\xc2\xbd\xe2\x82\xac"]', 3.0)
336 check(r'[string length "a\xbd\u20ac"]', 3.0)
337 self.assertRaises(TclError, tcl.exprdouble, '"abc"')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300338 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200339 check('2**64', float(2**64))
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200340
341 def test_exprlong(self):
342 tcl = self.interp
343 tcl.call('set', 'a', 3)
344 tcl.call('set', 'b', 6)
345 def check(expr, expected):
346 result = tcl.exprlong(expr)
347 self.assertEqual(result, expected)
348 self.assertIsInstance(result, int)
349
350 self.assertRaises(TypeError, tcl.exprlong)
351 self.assertRaises(TypeError, tcl.exprlong, '8.2', '+6')
352 self.assertRaises(TclError, tcl.exprlong, 'spam')
353 check('', 0)
354 check('8.2 + 6', 14)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200355 check('3.1 + $a', 6)
356 check('2 + "$a.$b"', 5)
357 check('4*[llength "6 2"]', 8)
358 check('{word one} < "word $a"', 0)
359 check('4*2 < 7', 0)
360 check('hypot($a, 4)', 5)
361 check('5 / 4', 1)
362 check('5 / 4.0', 1)
363 check('5 / ( [string length "abcd"] + 0.0 )', 1)
364 check('20.0/5.0', 4)
365 check('"0x03" > "2"', 1)
366 check('[string length "a\xc2\xbd\xe2\x82\xac"]', 3)
367 check(r'[string length "a\xbd\u20ac"]', 3)
368 self.assertRaises(TclError, tcl.exprlong, '"abc"')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300369 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200370 self.assertRaises(TclError, tcl.exprlong, '2**64')
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200371
372 def test_exprboolean(self):
373 tcl = self.interp
374 tcl.call('set', 'a', 3)
375 tcl.call('set', 'b', 6)
376 def check(expr, expected):
377 result = tcl.exprboolean(expr)
378 self.assertEqual(result, expected)
379 self.assertIsInstance(result, int)
380 self.assertNotIsInstance(result, bool)
381
382 self.assertRaises(TypeError, tcl.exprboolean)
383 self.assertRaises(TypeError, tcl.exprboolean, '8.2', '+6')
384 self.assertRaises(TclError, tcl.exprboolean, 'spam')
385 check('', False)
386 for value in ('0', 'false', 'no', 'off'):
387 check(value, False)
388 check('"%s"' % value, False)
389 check('{%s}' % value, False)
390 for value in ('1', 'true', 'yes', 'on'):
391 check(value, True)
392 check('"%s"' % value, True)
393 check('{%s}' % value, True)
394 check('8.2 + 6', True)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200395 check('3.1 + $a', True)
396 check('2 + "$a.$b"', True)
397 check('4*[llength "6 2"]', True)
398 check('{word one} < "word $a"', False)
399 check('4*2 < 7', False)
400 check('hypot($a, 4)', True)
401 check('5 / 4', True)
402 check('5 / 4.0', True)
403 check('5 / ( [string length "abcd"] + 0.0 )', True)
404 check('20.0/5.0', True)
405 check('"0x03" > "2"', True)
406 check('[string length "a\xc2\xbd\xe2\x82\xac"]', True)
407 check(r'[string length "a\xbd\u20ac"]', True)
408 self.assertRaises(TclError, tcl.exprboolean, '"abc"')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300409 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka90ecc002014-02-03 22:30:22 +0200410 check('2**64', True)
Serhiy Storchakad2eff232014-02-03 20:41:04 +0200411
Serhiy Storchakae8ae0472015-04-02 19:57:52 +0300412 @unittest.skipUnless(tcl_version >= (8, 5), 'requires Tcl version >= 8.5')
Serhiy Storchakacba6b5d2015-04-02 10:35:57 +0300413 def test_booleans(self):
414 tcl = self.interp
415 def check(expr, expected):
416 result = tcl.call('expr', expr)
Serhiy Storchaka91398f82015-04-02 11:46:07 +0300417 if tcl.wantobjects():
418 self.assertEqual(result, expected)
419 self.assertIsInstance(result, int)
420 else:
421 self.assertIn(result, (expr, str(int(expected))))
422 self.assertIsInstance(result, str)
Serhiy Storchakacba6b5d2015-04-02 10:35:57 +0300423 check('true', True)
424 check('yes', True)
425 check('on', True)
426 check('false', False)
427 check('no', False)
428 check('off', False)
429 check('1 < 2', True)
430 check('1 > 2', False)
431
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300432 def test_expr_bignum(self):
433 tcl = self.interp
434 for i in self.get_integers():
435 result = tcl.call('expr', str(i))
436 if self.wantobjects:
437 self.assertEqual(result, i)
438 self.assertIsInstance(result, (int, long))
Serhiy Storchaka4507b812015-04-10 21:12:18 +0300439 if abs(result) < 2**31:
440 self.assertIsInstance(result, int)
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300441 else:
442 self.assertEqual(result, str(i))
443 self.assertIsInstance(result, str)
444 if tcl_version < (8, 5): # bignum was added in Tcl 8.5
Serhiy Storchaka61ad42e2015-04-02 20:06:48 +0300445 self.assertRaises(TclError, tcl.call, 'expr', str(2**1000))
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300446
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200447 def test_passing_values(self):
448 def passValue(value):
449 return self.interp.call('set', '_', value)
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200450
451 self.assertEqual(passValue(True), True if self.wantobjects else '1')
452 self.assertEqual(passValue(False), False if self.wantobjects else '0')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200453 self.assertEqual(passValue('string'), 'string')
454 self.assertEqual(passValue('string\xbd'), 'string\xbd')
455 self.assertEqual(passValue('string\xe2\x82\xac'), u'string\u20ac')
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200456 self.assertEqual(passValue(u'string'), u'string')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200457 self.assertEqual(passValue(u'string\xbd'), u'string\xbd')
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200458 self.assertEqual(passValue(u'string\u20ac'), u'string\u20ac')
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200459 self.assertEqual(passValue('str\x00ing'), 'str\x00ing')
460 self.assertEqual(passValue('str\xc0\x80ing'), 'str\x00ing')
461 self.assertEqual(passValue(u'str\x00ing'), u'str\x00ing')
462 self.assertEqual(passValue(u'str\x00ing\xbd'), u'str\x00ing\xbd')
463 self.assertEqual(passValue(u'str\x00ing\u20ac'), u'str\x00ing\u20ac')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300464 for i in self.get_integers():
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200465 self.assertEqual(passValue(i), i if self.wantobjects else str(i))
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300466 if tcl_version < (8, 5): # bignum was added in Tcl 8.5
467 self.assertEqual(passValue(2**1000), str(2**1000))
Ezio Melotti0a4a7e12013-02-23 08:19:00 +0200468 for f in (0.0, 1.0, -1.0, 1//3, 1/3.0,
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200469 sys.float_info.min, sys.float_info.max,
470 -sys.float_info.min, -sys.float_info.max):
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200471 if self.wantobjects:
Serhiy Storchaka4a880412013-02-07 15:37:53 +0200472 self.assertEqual(passValue(f), f)
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200473 else:
474 self.assertEqual(float(passValue(f)), f)
475 if self.wantobjects:
476 f = passValue(float('nan'))
477 self.assertNotEqual(f, f)
478 self.assertEqual(passValue(float('inf')), float('inf'))
479 self.assertEqual(passValue(-float('inf')), -float('inf'))
480 else:
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200481 self.assertEqual(float(passValue(float('inf'))), float('inf'))
482 self.assertEqual(float(passValue(-float('inf'))), -float('inf'))
Serhiy Storchaka5fc570f2014-07-07 14:47:17 +0300483 # XXX NaN representation can be not parsable by float()
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200484 self.assertEqual(passValue((1, '2', (3.4,))),
485 (1, '2', (3.4,)) if self.wantobjects else '1 2 3.4')
Martin v. Löwiseba67c02010-06-04 19:39:07 +0000486
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200487 def test_user_command(self):
488 result = []
489 def testfunc(arg):
490 result.append(arg)
491 return arg
492 self.interp.createcommand('testfunc', testfunc)
Antoine Pitrouaa73ea02014-02-23 19:39:06 +0100493 self.addCleanup(self.interp.tk.deletecommand, 'testfunc')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300494 def check(value, expected=None, eq=self.assertEqual):
495 if expected is None:
496 expected = value
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200497 del result[:]
Serhiy Storchaka83515ec2014-01-23 11:03:02 +0200498 r = self.interp.call('testfunc', value)
499 self.assertEqual(len(result), 1)
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200500 self.assertIsInstance(result[0], (str, unicode))
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300501 eq(result[0], expected)
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200502 self.assertIsInstance(r, (str, unicode))
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300503 eq(r, expected)
Serhiy Storchakadc976672014-01-23 14:38:44 +0200504 def float_eq(actual, expected):
Serhiy Storchakaeb7ef942014-01-23 16:08:35 +0200505 self.assertAlmostEqual(float(actual), expected,
506 delta=abs(expected) * 1e-10)
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200507
508 check(True, '1')
509 check(False, '0')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300510 check('string')
511 check('string\xbd')
512 check('string\xe2\x82\xac', u'string\u20ac')
Serhiy Storchaka17c01782014-09-11 10:56:59 +0300513 check('')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300514 check(u'string')
515 check(u'string\xbd')
516 check(u'string\u20ac')
Serhiy Storchaka17c01782014-09-11 10:56:59 +0300517 check(u'')
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300518 check('str\xc0\x80ing', u'str\x00ing')
519 check('str\xc0\x80ing\xe2\x82\xac', u'str\x00ing\u20ac')
520 check(u'str\x00ing')
521 check(u'str\x00ing\xbd')
522 check(u'str\x00ing\u20ac')
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300523 for i in self.get_integers():
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200524 check(i, str(i))
Serhiy Storchakac77c5b52015-04-02 18:46:30 +0300525 if tcl_version < (8, 5): # bignum was added in Tcl 8.5
526 check(2**1000, str(2**1000))
Serhiy Storchakadc976672014-01-23 14:38:44 +0200527 for f in (0.0, 1.0, -1.0):
528 check(f, repr(f))
529 for f in (1/3.0, sys.float_info.min, sys.float_info.max,
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200530 -sys.float_info.min, -sys.float_info.max):
Serhiy Storchakaede745a2014-08-18 17:46:34 +0300531 check(f, eq=float_eq)
532 check(float('inf'), eq=float_eq)
533 check(-float('inf'), eq=float_eq)
Serhiy Storchaka5fc570f2014-07-07 14:47:17 +0300534 # XXX NaN representation can be not parsable by float()
Serhiy Storchaka29d8e852014-01-23 09:42:46 +0200535 check((), '')
536 check((1, (2,), (3, 4), '5 6', ()), '1 2 {3 4} {5 6} {}')
537
Serhiy Storchakafab65422013-07-11 20:32:48 +0300538 def test_splitlist(self):
539 splitlist = self.interp.tk.splitlist
540 call = self.interp.tk.call
541 self.assertRaises(TypeError, splitlist)
542 self.assertRaises(TypeError, splitlist, 'a', 'b')
543 self.assertRaises(TypeError, splitlist, 2)
544 testcases = [
545 ('2', ('2',)),
546 ('', ()),
547 ('{}', ('',)),
548 ('""', ('',)),
549 ('a\n b\t\r c\n ', ('a', 'b', 'c')),
550 (u'a\n b\t\r c\n ', ('a', 'b', 'c')),
551 ('a \xe2\x82\xac', ('a', '\xe2\x82\xac')),
552 (u'a \u20ac', ('a', '\xe2\x82\xac')),
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200553 ('a\xc0\x80b c\xc0\x80d', ('a\xc0\x80b', 'c\xc0\x80d')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300554 ('a {b c}', ('a', 'b c')),
555 (r'a b\ c', ('a', 'b c')),
556 (('a', 'b c'), ('a', 'b c')),
557 ('a 2', ('a', '2')),
558 (('a', 2), ('a', 2)),
559 ('a 3.4', ('a', '3.4')),
560 (('a', 3.4), ('a', 3.4)),
561 ((), ()),
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200562 (call('list', 1, '2', (3.4,)),
563 (1, '2', (3.4,)) if self.wantobjects else
564 ('1', '2', '3.4')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300565 ]
Serhiy Storchaka94025332013-09-08 20:32:56 +0300566 if tcl_version >= (8, 5):
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200567 if not self.wantobjects:
568 expected = ('12', '\xe2\x82\xac', '\xe2\x82\xac', '3.4')
569 elif get_tk_patchlevel() < (8, 5, 5):
570 # Before 8.5.5 dicts were converted to lists through string
571 expected = ('12', u'\u20ac', u'\u20ac', '3.4')
572 else:
573 expected = (12, u'\u20ac', u'\u20ac', (3.4,))
Serhiy Storchaka94025332013-09-08 20:32:56 +0300574 testcases += [
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200575 (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)),
576 expected),
Serhiy Storchaka94025332013-09-08 20:32:56 +0300577 ]
Serhiy Storchakafab65422013-07-11 20:32:48 +0300578 for arg, res in testcases:
579 self.assertEqual(splitlist(arg), res)
580 self.assertRaises(TclError, splitlist, '{')
581
582 def test_split(self):
583 split = self.interp.tk.split
584 call = self.interp.tk.call
585 self.assertRaises(TypeError, split)
586 self.assertRaises(TypeError, split, 'a', 'b')
587 self.assertRaises(TypeError, split, 2)
588 testcases = [
589 ('2', '2'),
590 ('', ''),
591 ('{}', ''),
592 ('""', ''),
593 ('{', '{'),
594 ('a\n b\t\r c\n ', ('a', 'b', 'c')),
595 (u'a\n b\t\r c\n ', ('a', 'b', 'c')),
596 ('a \xe2\x82\xac', ('a', '\xe2\x82\xac')),
597 (u'a \u20ac', ('a', '\xe2\x82\xac')),
Serhiy Storchakaccffb252014-02-03 21:23:46 +0200598 ('a\xc0\x80b', 'a\xc0\x80b'),
599 ('a\xc0\x80b c\xc0\x80d', ('a\xc0\x80b', 'c\xc0\x80d')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300600 ('a {b c}', ('a', ('b', 'c'))),
601 (r'a b\ c', ('a', ('b', 'c'))),
602 (('a', 'b c'), ('a', ('b', 'c'))),
603 (('a', u'b c'), ('a', ('b', 'c'))),
604 ('a 2', ('a', '2')),
605 (('a', 2), ('a', 2)),
606 ('a 3.4', ('a', '3.4')),
607 (('a', 3.4), ('a', 3.4)),
608 (('a', (2, 3.4)), ('a', (2, 3.4))),
609 ((), ()),
Serhiy Storchaka5542b152013-12-25 17:28:50 +0200610 (call('list', 1, '2', (3.4,)),
611 (1, '2', (3.4,)) if self.wantobjects else
612 ('1', '2', '3.4')),
Serhiy Storchakafab65422013-07-11 20:32:48 +0300613 ]
Serhiy Storchaka94025332013-09-08 20:32:56 +0300614 if tcl_version >= (8, 5):
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200615 if not self.wantobjects:
616 expected = ('12', '\xe2\x82\xac', '\xe2\x82\xac', '3.4')
617 elif get_tk_patchlevel() < (8, 5, 5):
618 # Before 8.5.5 dicts were converted to lists through string
619 expected = ('12', u'\u20ac', u'\u20ac', '3.4')
620 else:
621 expected = (12, u'\u20ac', u'\u20ac', (3.4,))
Serhiy Storchaka94025332013-09-08 20:32:56 +0300622 testcases += [
623 (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)),
Serhiy Storchaka15b67d72014-02-02 23:04:06 +0200624 expected),
Serhiy Storchaka94025332013-09-08 20:32:56 +0300625 ]
Serhiy Storchakafab65422013-07-11 20:32:48 +0300626 for arg, res in testcases:
627 self.assertEqual(split(arg), res)
628
Serhiy Storchakaceaf6822014-09-06 22:47:02 +0300629 def test_splitdict(self):
630 splitdict = tkinter._splitdict
631 tcl = self.interp.tk
632
633 arg = '-a {1 2 3} -something foo status {}'
634 self.assertEqual(splitdict(tcl, arg, False),
635 {'-a': '1 2 3', '-something': 'foo', 'status': ''})
636 self.assertEqual(splitdict(tcl, arg),
637 {'a': '1 2 3', 'something': 'foo', 'status': ''})
638
639 arg = ('-a', (1, 2, 3), '-something', 'foo', 'status', '{}')
640 self.assertEqual(splitdict(tcl, arg, False),
641 {'-a': (1, 2, 3), '-something': 'foo', 'status': '{}'})
642 self.assertEqual(splitdict(tcl, arg),
643 {'a': (1, 2, 3), 'something': 'foo', 'status': '{}'})
644
645 self.assertRaises(RuntimeError, splitdict, tcl, '-a b -c ')
646 self.assertRaises(RuntimeError, splitdict, tcl, ('-a', 'b', '-c'))
647
648 arg = tcl.call('list',
649 '-a', (1, 2, 3), '-something', 'foo', 'status', ())
650 self.assertEqual(splitdict(tcl, arg),
651 {'a': (1, 2, 3) if self.wantobjects else '1 2 3',
652 'something': 'foo', 'status': ''})
653
654 if tcl_version >= (8, 5):
655 arg = tcl.call('dict', 'create',
656 '-a', (1, 2, 3), '-something', 'foo', 'status', ())
657 if not self.wantobjects or get_tk_patchlevel() < (8, 5, 5):
658 # Before 8.5.5 dicts were converted to lists through string
659 expected = {'a': '1 2 3', 'something': 'foo', 'status': ''}
660 else:
661 expected = {'a': (1, 2, 3), 'something': 'foo', 'status': ''}
662 self.assertEqual(splitdict(tcl, arg), expected)
663
664
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300665character_size = 4 if sys.maxunicode > 0xFFFF else 2
Neal Norwitz63dfece2004-02-19 02:37:29 +0000666
Serhiy Storchaka42035702013-08-21 21:46:12 +0300667class BigmemTclTest(unittest.TestCase):
668
669 def setUp(self):
670 self.interp = Tcl()
671
Serhiy Storchaka76249ea2014-02-07 10:06:05 +0200672 @test_support.cpython_only
673 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
674 @test_support.precisionbigmemtest(size=INT_MAX + 1, memuse=5, dry_run=False)
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300675 def test_huge_string_call(self, size):
Serhiy Storchaka42035702013-08-21 21:46:12 +0300676 value = ' ' * size
677 self.assertRaises(OverflowError, self.interp.call, 'set', '_', value)
678
Serhiy Storchaka2a0220b2014-05-30 14:23:52 +0300679 @test_support.cpython_only
680 @unittest.skipUnless(test_support.have_unicode, 'requires unicode support')
681 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
682 @test_support.precisionbigmemtest(size=INT_MAX + 1,
683 memuse=2*character_size + 2,
684 dry_run=False)
685 def test_huge_unicode_call(self, size):
686 value = unicode(' ') * size
687 self.assertRaises(OverflowError, self.interp.call, 'set', '_', value)
688
689
690 @test_support.cpython_only
691 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
692 @test_support.precisionbigmemtest(size=INT_MAX + 1, memuse=9, dry_run=False)
693 def test_huge_string_builtins(self, size):
694 value = '1' + ' ' * size
695 self.check_huge_string_builtins(value)
696
697 @test_support.cpython_only
698 @unittest.skipUnless(test_support.have_unicode, 'requires unicode support')
699 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
700 @test_support.precisionbigmemtest(size=INT_MAX + 1,
701 memuse=2*character_size + 7,
702 dry_run=False)
703 def test_huge_unicode_builtins(self, size):
704 value = unicode('1' + ' ' * size)
705 self.check_huge_string_builtins(value)
706
707 def check_huge_string_builtins(self, value):
708 self.assertRaises(OverflowError, self.interp.tk.getint, value)
709 self.assertRaises(OverflowError, self.interp.tk.getdouble, value)
710 self.assertRaises(OverflowError, self.interp.tk.getboolean, value)
711 self.assertRaises(OverflowError, self.interp.eval, value)
712 self.assertRaises(OverflowError, self.interp.evalfile, value)
713 self.assertRaises(OverflowError, self.interp.record, value)
714 self.assertRaises(OverflowError, self.interp.adderrorinfo, value)
715 self.assertRaises(OverflowError, self.interp.setvar, value, 'x', 'a')
716 self.assertRaises(OverflowError, self.interp.setvar, 'x', value, 'a')
717 self.assertRaises(OverflowError, self.interp.unsetvar, value)
718 self.assertRaises(OverflowError, self.interp.unsetvar, 'x', value)
719 self.assertRaises(OverflowError, self.interp.adderrorinfo, value)
720 self.assertRaises(OverflowError, self.interp.exprstring, value)
721 self.assertRaises(OverflowError, self.interp.exprlong, value)
722 self.assertRaises(OverflowError, self.interp.exprboolean, value)
723 self.assertRaises(OverflowError, self.interp.splitlist, value)
724 self.assertRaises(OverflowError, self.interp.split, value)
725 self.assertRaises(OverflowError, self.interp.createcommand, value, max)
726 self.assertRaises(OverflowError, self.interp.deletecommand, value)
727
Serhiy Storchaka42035702013-08-21 21:46:12 +0300728
Serhiy Storchaka78ecaba2013-11-20 17:44:38 +0200729def setUpModule():
730 if test_support.verbose:
731 tcl = Tcl()
732 print 'patchlevel =', tcl.call('info', 'patchlevel')
733
734
Neal Norwitz63dfece2004-02-19 02:37:29 +0000735def test_main():
Serhiy Storchaka42035702013-08-21 21:46:12 +0300736 test_support.run_unittest(TclTest, TkinterTest, BigmemTclTest)
Neal Norwitz63dfece2004-02-19 02:37:29 +0000737
David Aschere2b4b322004-02-18 05:59:53 +0000738if __name__ == "__main__":
Neal Norwitz63dfece2004-02-19 02:37:29 +0000739 test_main()