Home | History | Annotate | Download | only in test
      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