1 import unittest 2 import re 3 import sys 4 import os 5 from test import test_support 6 from subprocess import Popen, PIPE 7 8 # Skip this test if the _tkinter module wasn't built. 9 _tkinter = test_support.import_module('_tkinter') 10 11 import Tkinter as tkinter 12 from Tkinter import Tcl 13 from _tkinter import TclError 14 15 try: 16 from _testcapi import INT_MAX, PY_SSIZE_T_MAX 17 except ImportError: 18 INT_MAX = PY_SSIZE_T_MAX = sys.maxsize 19 20 tcl_version = tuple(map(int, _tkinter.TCL_VERSION.split('.'))) 21 22 _tk_patchlevel = None 23 def get_tk_patchlevel(): 24 global _tk_patchlevel 25 if _tk_patchlevel is None: 26 tcl = Tcl() 27 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 36 return _tk_patchlevel 37 38 39 class TkinterTest(unittest.TestCase): 40 41 def testFlattenLen(self): 42 # flatten(<object with no length>) 43 self.assertRaises(TypeError, _tkinter._flatten, True) 44 45 46 class TclTest(unittest.TestCase): 47 48 def setUp(self): 49 self.interp = Tcl() 50 self.wantobjects = self.interp.tk.wantobjects() 51 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') 126 127 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) 131 # 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)): 134 integers += (2**63, -2**63-1, 2**1000, -2**1000) 135 return integers 136 137 def test_getint(self): 138 tcl = self.interp.tk 139 for i in self.get_integers(): 140 result = tcl.getint(' %d ' % i) 141 self.assertEqual(result, i) 142 self.assertIsInstance(result, type(int(result))) 143 if tcl_version >= (8, 5): 144 self.assertEqual(tcl.getint(' {:#o} '.format(i)), i) 145 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)) 149 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) 181 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) 187 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 198 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) 209 os.remove(filename) 210 self.assertEqual(tcl.eval('set a'),'1') 211 self.assertEqual(tcl.eval('set b'),'2') 212 self.assertEqual(tcl.eval('set c'),'3') 213 214 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 226 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 235 def testPackageRequireException(self): 236 tcl = self.interp 237 self.assertRaises(TclError,tcl.eval,'package require DNE') 238 239 @unittest.skipUnless(sys.platform == 'win32', "only applies to Windows") 240 def testLoadWithUNC(self): 241 # 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] != ':': 247 self.skipTest('unusable path: %r' % fullname) 248 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") 254 cmd = '%s -c "import Tkinter; print Tkinter"' % (unc_name,) 255 256 try: 257 p = Popen(cmd, stdout=PIPE, stderr=PIPE) 258 except WindowsError as e: 259 if e.winerror == 5 or e.winerror == 2: 260 self.skipTest('Not permitted to start the child process') 261 else: 262 raise 263 264 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 275 276 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') 290 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') 306 check(r'"a\0b"', 'a\xc0\x80b') 307 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5 308 check('2**64', str(2**64)) 309 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) 324 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"') 338 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5 339 check('2**64', float(2**64)) 340 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) 355 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"') 369 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5 370 self.assertRaises(TclError, tcl.exprlong, '2**64') 371 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) 395 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"') 409 if tcl_version >= (8, 5): # bignum was added in Tcl 8.5 410 check('2**64', True) 411 412 @unittest.skipUnless(tcl_version >= (8, 5), 'requires Tcl version >= 8.5') 413 def test_booleans(self): 414 tcl = self.interp 415 def check(expr, expected): 416 result = tcl.call('expr', expr) 417 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) 423 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 432 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)) 439 if abs(result) < 2**31: 440 self.assertIsInstance(result, int) 441 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 445 self.assertRaises(TclError, tcl.call, 'expr', str(2**1000)) 446 447 def test_passing_values(self): 448 def passValue(value): 449 return self.interp.call('set', '_', value) 450 451 self.assertEqual(passValue(True), True if self.wantobjects else '1') 452 self.assertEqual(passValue(False), False if self.wantobjects else '0') 453 self.assertEqual(passValue('string'), 'string') 454 self.assertEqual(passValue('string\xbd'), 'string\xbd') 455 self.assertEqual(passValue('string\xe2\x82\xac'), u'string\u20ac') 456 self.assertEqual(passValue(u'string'), u'string') 457 self.assertEqual(passValue(u'string\xbd'), u'string\xbd') 458 self.assertEqual(passValue(u'string\u20ac'), u'string\u20ac') 459 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') 464 for i in self.get_integers(): 465 self.assertEqual(passValue(i), i if self.wantobjects else str(i)) 466 if tcl_version < (8, 5): # bignum was added in Tcl 8.5 467 self.assertEqual(passValue(2**1000), str(2**1000)) 468 for f in (0.0, 1.0, -1.0, 1//3, 1/3.0, 469 sys.float_info.min, sys.float_info.max, 470 -sys.float_info.min, -sys.float_info.max): 471 if self.wantobjects: 472 self.assertEqual(passValue(f), f) 473 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: 481 self.assertEqual(float(passValue(float('inf'))), float('inf')) 482 self.assertEqual(float(passValue(-float('inf'))), -float('inf')) 483 # XXX NaN representation can be not parsable by float() 484 self.assertEqual(passValue((1, '2', (3.4,))), 485 (1, '2', (3.4,)) if self.wantobjects else '1 2 3.4') 486 487 def test_user_command(self): 488 result = [] 489 def testfunc(arg): 490 result.append(arg) 491 return arg 492 self.interp.createcommand('testfunc', testfunc) 493 self.addCleanup(self.interp.tk.deletecommand, 'testfunc') 494 def check(value, expected=None, eq=self.assertEqual): 495 if expected is None: 496 expected = value 497 del result[:] 498 r = self.interp.call('testfunc', value) 499 self.assertEqual(len(result), 1) 500 self.assertIsInstance(result[0], (str, unicode)) 501 eq(result[0], expected) 502 self.assertIsInstance(r, (str, unicode)) 503 eq(r, expected) 504 def float_eq(actual, expected): 505 self.assertAlmostEqual(float(actual), expected, 506 delta=abs(expected) * 1e-10) 507 508 check(True, '1') 509 check(False, '0') 510 check('string') 511 check('string\xbd') 512 check('string\xe2\x82\xac', u'string\u20ac') 513 check('') 514 check(u'string') 515 check(u'string\xbd') 516 check(u'string\u20ac') 517 check(u'') 518 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') 523 for i in self.get_integers(): 524 check(i, str(i)) 525 if tcl_version < (8, 5): # bignum was added in Tcl 8.5 526 check(2**1000, str(2**1000)) 527 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, 530 -sys.float_info.min, -sys.float_info.max): 531 check(f, eq=float_eq) 532 check(float('inf'), eq=float_eq) 533 check(-float('inf'), eq=float_eq) 534 # XXX NaN representation can be not parsable by float() 535 check((), '') 536 check((1, (2,), (3, 4), '5 6', ()), '1 2 {3 4} {5 6} {}') 537 538 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')), 553 ('a\xc0\x80b c\xc0\x80d', ('a\xc0\x80b', 'c\xc0\x80d')), 554 ('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 ((), ()), 562 (call('list', 1, '2', (3.4,)), 563 (1, '2', (3.4,)) if self.wantobjects else 564 ('1', '2', '3.4')), 565 ] 566 if tcl_version >= (8, 5): 567 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,)) 574 testcases += [ 575 (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)), 576 expected), 577 ] 578 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')), 598 ('a\xc0\x80b', 'a\xc0\x80b'), 599 ('a\xc0\x80b c\xc0\x80d', ('a\xc0\x80b', 'c\xc0\x80d')), 600 ('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 ((), ()), 610 (call('list', 1, '2', (3.4,)), 611 (1, '2', (3.4,)) if self.wantobjects else 612 ('1', '2', '3.4')), 613 ] 614 if tcl_version >= (8, 5): 615 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,)) 622 testcases += [ 623 (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)), 624 expected), 625 ] 626 for arg, res in testcases: 627 self.assertEqual(split(arg), res) 628 629 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 def test_join(self): 665 join = tkinter._join 666 tcl = self.interp.tk 667 def unpack(s): 668 return tcl.call('lindex', s, 0) 669 def check(value): 670 self.assertEqual(unpack(join([value])), value) 671 self.assertEqual(unpack(join([value, 0])), value) 672 self.assertEqual(unpack(unpack(join([[value]]))), value) 673 self.assertEqual(unpack(unpack(join([[value, 0]]))), value) 674 self.assertEqual(unpack(unpack(join([[value], 0]))), value) 675 self.assertEqual(unpack(unpack(join([[value, 0], 0]))), value) 676 check('') 677 check('spam') 678 check('sp am') 679 check('sp\tam') 680 check('sp\nam') 681 check(' \t\n') 682 check('{spam}') 683 check('{sp am}') 684 check('"spam"') 685 check('"sp am"') 686 check('{"spam"}') 687 check('"{spam}"') 688 check('sp\\am') 689 check('"sp\\am"') 690 check('"{}" "{}"') 691 check('"\\') 692 check('"{') 693 check('"}') 694 check('\n\\') 695 check('\n{') 696 check('\n}') 697 check('\\\n') 698 check('{\n') 699 check('}\n') 700 701 702 character_size = 4 if sys.maxunicode > 0xFFFF else 2 703 704 class BigmemTclTest(unittest.TestCase): 705 706 def setUp(self): 707 self.interp = Tcl() 708 709 @test_support.cpython_only 710 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX") 711 @test_support.precisionbigmemtest(size=INT_MAX + 1, memuse=5, dry_run=False) 712 def test_huge_string_call(self, size): 713 value = ' ' * size 714 self.assertRaises(OverflowError, self.interp.call, 'set', '_', value) 715 716 @test_support.cpython_only 717 @unittest.skipUnless(test_support.have_unicode, 'requires unicode support') 718 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX") 719 @test_support.precisionbigmemtest(size=INT_MAX + 1, 720 memuse=2*character_size + 2, 721 dry_run=False) 722 def test_huge_unicode_call(self, size): 723 value = unicode(' ') * size 724 self.assertRaises(OverflowError, self.interp.call, 'set', '_', value) 725 726 727 @test_support.cpython_only 728 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX") 729 @test_support.precisionbigmemtest(size=INT_MAX + 1, memuse=9, dry_run=False) 730 def test_huge_string_builtins(self, size): 731 value = '1' + ' ' * size 732 self.check_huge_string_builtins(value) 733 734 @test_support.cpython_only 735 @unittest.skipUnless(test_support.have_unicode, 'requires unicode support') 736 @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX") 737 @test_support.precisionbigmemtest(size=INT_MAX + 1, 738 memuse=2*character_size + 7, 739 dry_run=False) 740 def test_huge_unicode_builtins(self, size): 741 value = unicode('1' + ' ' * size) 742 self.check_huge_string_builtins(value) 743 744 def check_huge_string_builtins(self, value): 745 tk = self.interp.tk 746 self.assertRaises(OverflowError, tk.getint, value) 747 self.assertRaises(OverflowError, tk.getdouble, value) 748 self.assertRaises(OverflowError, tk.getboolean, value) 749 self.assertRaises(OverflowError, tk.eval, value) 750 self.assertRaises(OverflowError, tk.evalfile, value) 751 self.assertRaises(OverflowError, tk.record, value) 752 self.assertRaises(OverflowError, tk.adderrorinfo, value) 753 self.assertRaises(OverflowError, tk.setvar, value, 'x', 'a') 754 self.assertRaises(OverflowError, tk.setvar, 'x', value, 'a') 755 self.assertRaises(OverflowError, tk.unsetvar, value) 756 self.assertRaises(OverflowError, tk.unsetvar, 'x', value) 757 self.assertRaises(OverflowError, tk.exprstring, value) 758 self.assertRaises(OverflowError, tk.exprlong, value) 759 self.assertRaises(OverflowError, tk.exprboolean, value) 760 self.assertRaises(OverflowError, tk.splitlist, value) 761 self.assertRaises(OverflowError, tk.split, value) 762 self.assertRaises(OverflowError, tk.createcommand, value, max) 763 self.assertRaises(OverflowError, tk.deletecommand, value) 764 765 766 def setUpModule(): 767 if test_support.verbose: 768 tcl = Tcl() 769 print 'patchlevel =', tcl.call('info', 'patchlevel') 770 771 772 def test_main(): 773 test_support.run_unittest(TclTest, TkinterTest, BigmemTclTest) 774 775 if __name__ == "__main__": 776 test_main() 777