python (3.11.7)

(root)/
lib/
python3.11/
test/
test_tcl.py
       1  import unittest
       2  import locale
       3  import re
       4  import subprocess
       5  import sys
       6  import os
       7  import warnings
       8  from test import support
       9  from test.support import import_helper
      10  from test.support import os_helper
      11  
      12  # Skip this test if the _tkinter module wasn't built.
      13  _tkinter = import_helper.import_module('_tkinter')
      14  
      15  import tkinter
      16  from tkinter import Tcl
      17  from _tkinter import TclError
      18  
      19  try:
      20      from _testcapi import INT_MAX, PY_SSIZE_T_MAX
      21  except ImportError:
      22      INT_MAX = PY_SSIZE_T_MAX = sys.maxsize
      23  
      24  tcl_version = tuple(map(int, _tkinter.TCL_VERSION.split('.')))
      25  
      26  
      27  class ESC[4;38;5;81mTkinterTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      28  
      29      def testFlattenLen(self):
      30          # Object without length.
      31          self.assertRaises(TypeError, _tkinter._flatten, True)
      32          # Object with length, but not sequence.
      33          self.assertRaises(TypeError, _tkinter._flatten, {})
      34          # Sequence or set, but not tuple or list.
      35          # (issue44608: there were leaks in the following cases)
      36          self.assertRaises(TypeError, _tkinter._flatten, 'string')
      37          self.assertRaises(TypeError, _tkinter._flatten, {'set'})
      38  
      39  
      40  class ESC[4;38;5;81mTclTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      41  
      42      def setUp(self):
      43          self.interp = Tcl()
      44          self.wantobjects = self.interp.tk.wantobjects()
      45  
      46      def testEval(self):
      47          tcl = self.interp
      48          tcl.eval('set a 1')
      49          self.assertEqual(tcl.eval('set a'),'1')
      50  
      51      def test_eval_null_in_result(self):
      52          tcl = self.interp
      53          self.assertEqual(tcl.eval('set a "a\\0b"'), 'a\x00b')
      54  
      55      def test_eval_surrogates_in_result(self):
      56          tcl = self.interp
      57          self.assertIn(tcl.eval(r'set a "<\ud83d\udcbb>"'), '<\U0001f4bb>')
      58  
      59      def testEvalException(self):
      60          tcl = self.interp
      61          self.assertRaises(TclError,tcl.eval,'set a')
      62  
      63      def testEvalException2(self):
      64          tcl = self.interp
      65          self.assertRaises(TclError,tcl.eval,'this is wrong')
      66  
      67      def testCall(self):
      68          tcl = self.interp
      69          tcl.call('set','a','1')
      70          self.assertEqual(tcl.call('set','a'),'1')
      71  
      72      def testCallException(self):
      73          tcl = self.interp
      74          self.assertRaises(TclError,tcl.call,'set','a')
      75  
      76      def testCallException2(self):
      77          tcl = self.interp
      78          self.assertRaises(TclError,tcl.call,'this','is','wrong')
      79  
      80      def testSetVar(self):
      81          tcl = self.interp
      82          tcl.setvar('a','1')
      83          self.assertEqual(tcl.eval('set a'),'1')
      84  
      85      def testSetVarArray(self):
      86          tcl = self.interp
      87          tcl.setvar('a(1)','1')
      88          self.assertEqual(tcl.eval('set a(1)'),'1')
      89  
      90      def testGetVar(self):
      91          tcl = self.interp
      92          tcl.eval('set a 1')
      93          self.assertEqual(tcl.getvar('a'),'1')
      94  
      95      def testGetVarArray(self):
      96          tcl = self.interp
      97          tcl.eval('set a(1) 1')
      98          self.assertEqual(tcl.getvar('a(1)'),'1')
      99  
     100      def testGetVarException(self):
     101          tcl = self.interp
     102          self.assertRaises(TclError,tcl.getvar,'a')
     103  
     104      def testGetVarArrayException(self):
     105          tcl = self.interp
     106          self.assertRaises(TclError,tcl.getvar,'a(1)')
     107  
     108      def testUnsetVar(self):
     109          tcl = self.interp
     110          tcl.setvar('a',1)
     111          self.assertEqual(tcl.eval('info exists a'),'1')
     112          tcl.unsetvar('a')
     113          self.assertEqual(tcl.eval('info exists a'),'0')
     114  
     115      def testUnsetVarArray(self):
     116          tcl = self.interp
     117          tcl.setvar('a(1)',1)
     118          tcl.setvar('a(2)',2)
     119          self.assertEqual(tcl.eval('info exists a(1)'),'1')
     120          self.assertEqual(tcl.eval('info exists a(2)'),'1')
     121          tcl.unsetvar('a(1)')
     122          self.assertEqual(tcl.eval('info exists a(1)'),'0')
     123          self.assertEqual(tcl.eval('info exists a(2)'),'1')
     124  
     125      def testUnsetVarException(self):
     126          tcl = self.interp
     127          self.assertRaises(TclError,tcl.unsetvar,'a')
     128  
     129      def get_integers(self):
     130          return (0, 1, -1,
     131                  2**31-1, -2**31, 2**31, -2**31-1,
     132                  2**63-1, -2**63, 2**63, -2**63-1,
     133                  2**1000, -2**1000)
     134  
     135      def test_getint(self):
     136          tcl = self.interp.tk
     137          for i in self.get_integers():
     138              self.assertEqual(tcl.getint(' %d ' % i), i)
     139              self.assertEqual(tcl.getint(' %#o ' % i), i)
     140              # Numbers starting with 0 are parsed as decimal in Tcl 9.0
     141              # and as octal in older versions.
     142              self.assertEqual(tcl.getint((' %#o ' % i).replace('o', '')),
     143                               i if tcl_version < (9, 0) else int('%o' % i))
     144              self.assertEqual(tcl.getint(' %#x ' % i), i)
     145          self.assertEqual(tcl.getint(42), 42)
     146          self.assertRaises(TypeError, tcl.getint)
     147          self.assertRaises(TypeError, tcl.getint, '42', '10')
     148          self.assertRaises(TypeError, tcl.getint, b'42')
     149          self.assertRaises(TypeError, tcl.getint, 42.0)
     150          self.assertRaises(TclError, tcl.getint, 'a')
     151          self.assertRaises((TypeError, ValueError, TclError),
     152                            tcl.getint, '42\0')
     153          self.assertRaises((UnicodeEncodeError, ValueError, TclError),
     154                            tcl.getint, '42\ud800')
     155  
     156      def test_getdouble(self):
     157          tcl = self.interp.tk
     158          self.assertEqual(tcl.getdouble(' 42 '), 42.0)
     159          self.assertEqual(tcl.getdouble(' 42.5 '), 42.5)
     160          self.assertEqual(tcl.getdouble(42.5), 42.5)
     161          self.assertEqual(tcl.getdouble(42), 42.0)
     162          self.assertRaises(TypeError, tcl.getdouble)
     163          self.assertRaises(TypeError, tcl.getdouble, '42.5', '10')
     164          self.assertRaises(TypeError, tcl.getdouble, b'42.5')
     165          self.assertRaises(TclError, tcl.getdouble, 'a')
     166          self.assertRaises((TypeError, ValueError, TclError),
     167                            tcl.getdouble, '42.5\0')
     168          self.assertRaises((UnicodeEncodeError, ValueError, TclError),
     169                            tcl.getdouble, '42.5\ud800')
     170  
     171      def test_getboolean(self):
     172          tcl = self.interp.tk
     173          self.assertIs(tcl.getboolean('on'), True)
     174          self.assertIs(tcl.getboolean('1'), True)
     175          self.assertIs(tcl.getboolean(42), True)
     176          self.assertIs(tcl.getboolean(0), False)
     177          self.assertRaises(TypeError, tcl.getboolean)
     178          self.assertRaises(TypeError, tcl.getboolean, 'on', '1')
     179          self.assertRaises(TypeError, tcl.getboolean, b'on')
     180          self.assertRaises(TypeError, tcl.getboolean, 1.0)
     181          self.assertRaises(TclError, tcl.getboolean, 'a')
     182          self.assertRaises((TypeError, ValueError, TclError),
     183                            tcl.getboolean, 'on\0')
     184          self.assertRaises((UnicodeEncodeError, ValueError, TclError),
     185                            tcl.getboolean, 'on\ud800')
     186  
     187      def testEvalFile(self):
     188          tcl = self.interp
     189          filename = os_helper.TESTFN_ASCII
     190          self.addCleanup(os_helper.unlink, filename)
     191          with open(filename, 'w') as f:
     192              f.write("""set a 1
     193              set b 2
     194              set c [ expr $a + $b ]
     195              """)
     196          tcl.evalfile(filename)
     197          self.assertEqual(tcl.eval('set a'),'1')
     198          self.assertEqual(tcl.eval('set b'),'2')
     199          self.assertEqual(tcl.eval('set c'),'3')
     200  
     201      def test_evalfile_null_in_result(self):
     202          tcl = self.interp
     203          filename = os_helper.TESTFN_ASCII
     204          self.addCleanup(os_helper.unlink, filename)
     205          with open(filename, 'w') as f:
     206              f.write("""
     207              set a "a\0b"
     208              set b "a\\0b"
     209              """)
     210          tcl.evalfile(filename)
     211          self.assertEqual(tcl.eval('set a'), 'a\x00b')
     212          self.assertEqual(tcl.eval('set b'), 'a\x00b')
     213  
     214      def test_evalfile_surrogates_in_result(self):
     215          tcl = self.interp
     216          encoding = tcl.call('encoding', 'system')
     217          self.addCleanup(tcl.call, 'encoding', 'system', encoding)
     218          tcl.call('encoding', 'system', 'utf-8')
     219  
     220          filename = os_helper.TESTFN_ASCII
     221          self.addCleanup(os_helper.unlink, filename)
     222          with open(filename, 'wb') as f:
     223              f.write(b"""
     224              set a "<\xed\xa0\xbd\xed\xb2\xbb>"
     225              set b "<\\ud83d\\udcbb>"
     226              """)
     227          tcl.evalfile(filename)
     228          self.assertEqual(tcl.eval('set a'), '<\U0001f4bb>')
     229          self.assertEqual(tcl.eval('set b'), '<\U0001f4bb>')
     230  
     231      def testEvalFileException(self):
     232          tcl = self.interp
     233          filename = "doesnotexists"
     234          try:
     235              os.remove(filename)
     236          except Exception as e:
     237              pass
     238          self.assertRaises(TclError,tcl.evalfile,filename)
     239  
     240      def testPackageRequireException(self):
     241          tcl = self.interp
     242          self.assertRaises(TclError,tcl.eval,'package require DNE')
     243  
     244      @unittest.skipUnless(sys.platform == 'win32', 'Requires Windows')
     245      def testLoadWithUNC(self):
     246          # Build a UNC path from the regular path.
     247          # Something like
     248          #   \\%COMPUTERNAME%\c$\python27\python.exe
     249  
     250          fullname = os.path.abspath(sys.executable)
     251          if fullname[1] != ':':
     252              raise unittest.SkipTest('Absolute path should have drive part')
     253          unc_name = r'\\%s\%s$\%s' % (os.environ['COMPUTERNAME'],
     254                                      fullname[0],
     255                                      fullname[3:])
     256          if not os.path.exists(unc_name):
     257              raise unittest.SkipTest('Cannot connect to UNC Path')
     258  
     259          with os_helper.EnvironmentVarGuard() as env:
     260              env.unset("TCL_LIBRARY")
     261              stdout = subprocess.check_output(
     262                      [unc_name, '-c', 'import tkinter; print(tkinter)'])
     263  
     264          self.assertIn(b'tkinter', stdout)
     265  
     266      def test_exprstring(self):
     267          tcl = self.interp
     268          tcl.call('set', 'a', 3)
     269          tcl.call('set', 'b', 6)
     270          def check(expr, expected):
     271              result = tcl.exprstring(expr)
     272              self.assertEqual(result, expected)
     273              self.assertIsInstance(result, str)
     274  
     275          self.assertRaises(TypeError, tcl.exprstring)
     276          self.assertRaises(TypeError, tcl.exprstring, '8.2', '+6')
     277          self.assertRaises(TypeError, tcl.exprstring, b'8.2 + 6')
     278          self.assertRaises(TclError, tcl.exprstring, 'spam')
     279          check('', '0')
     280          check('8.2 + 6', '14.2')
     281          check('3.1 + $a', '6.1')
     282          check('2 + "$a.$b"', '5.6')
     283          check('4*[llength "6 2"]', '8')
     284          check('{word one} < "word $a"', '0')
     285          check('4*2 < 7', '0')
     286          check('hypot($a, 4)', '5.0')
     287          check('5 / 4', '1')
     288          check('5 / 4.0', '1.25')
     289          check('5 / ( [string length "abcd"] + 0.0 )', '1.25')
     290          check('20.0/5.0', '4.0')
     291          check('"0x03" > "2"', '1')
     292          check('[string length "a\xbd\u20ac"]', '3')
     293          check(r'[string length "a\xbd\u20ac"]', '3')
     294          check('"abc"', 'abc')
     295          check('"a\xbd\u20ac"', 'a\xbd\u20ac')
     296          check(r'"a\xbd\u20ac"', 'a\xbd\u20ac')
     297          check(r'"a\0b"', 'a\x00b')
     298          check('2**64', str(2**64))
     299  
     300      def test_exprdouble(self):
     301          tcl = self.interp
     302          tcl.call('set', 'a', 3)
     303          tcl.call('set', 'b', 6)
     304          def check(expr, expected):
     305              result = tcl.exprdouble(expr)
     306              self.assertEqual(result, expected)
     307              self.assertIsInstance(result, float)
     308  
     309          self.assertRaises(TypeError, tcl.exprdouble)
     310          self.assertRaises(TypeError, tcl.exprdouble, '8.2', '+6')
     311          self.assertRaises(TypeError, tcl.exprdouble, b'8.2 + 6')
     312          self.assertRaises(TclError, tcl.exprdouble, 'spam')
     313          check('', 0.0)
     314          check('8.2 + 6', 14.2)
     315          check('3.1 + $a', 6.1)
     316          check('2 + "$a.$b"', 5.6)
     317          check('4*[llength "6 2"]', 8.0)
     318          check('{word one} < "word $a"', 0.0)
     319          check('4*2 < 7', 0.0)
     320          check('hypot($a, 4)', 5.0)
     321          check('5 / 4', 1.0)
     322          check('5 / 4.0', 1.25)
     323          check('5 / ( [string length "abcd"] + 0.0 )', 1.25)
     324          check('20.0/5.0', 4.0)
     325          check('"0x03" > "2"', 1.0)
     326          check('[string length "a\xbd\u20ac"]', 3.0)
     327          check(r'[string length "a\xbd\u20ac"]', 3.0)
     328          self.assertRaises(TclError, tcl.exprdouble, '"abc"')
     329          check('2**64', float(2**64))
     330  
     331      def test_exprlong(self):
     332          tcl = self.interp
     333          tcl.call('set', 'a', 3)
     334          tcl.call('set', 'b', 6)
     335          def check(expr, expected):
     336              result = tcl.exprlong(expr)
     337              self.assertEqual(result, expected)
     338              self.assertIsInstance(result, int)
     339  
     340          self.assertRaises(TypeError, tcl.exprlong)
     341          self.assertRaises(TypeError, tcl.exprlong, '8.2', '+6')
     342          self.assertRaises(TypeError, tcl.exprlong, b'8.2 + 6')
     343          self.assertRaises(TclError, tcl.exprlong, 'spam')
     344          check('', 0)
     345          check('8.2 + 6', 14)
     346          check('3.1 + $a', 6)
     347          check('2 + "$a.$b"', 5)
     348          check('4*[llength "6 2"]', 8)
     349          check('{word one} < "word $a"', 0)
     350          check('4*2 < 7', 0)
     351          check('hypot($a, 4)', 5)
     352          check('5 / 4', 1)
     353          check('5 / 4.0', 1)
     354          check('5 / ( [string length "abcd"] + 0.0 )', 1)
     355          check('20.0/5.0', 4)
     356          check('"0x03" > "2"', 1)
     357          check('[string length "a\xbd\u20ac"]', 3)
     358          check(r'[string length "a\xbd\u20ac"]', 3)
     359          self.assertRaises(TclError, tcl.exprlong, '"abc"')
     360          self.assertRaises(TclError, tcl.exprlong, '2**64')
     361  
     362      def test_exprboolean(self):
     363          tcl = self.interp
     364          tcl.call('set', 'a', 3)
     365          tcl.call('set', 'b', 6)
     366          def check(expr, expected):
     367              result = tcl.exprboolean(expr)
     368              self.assertEqual(result, expected)
     369              self.assertIsInstance(result, int)
     370              self.assertNotIsInstance(result, bool)
     371  
     372          self.assertRaises(TypeError, tcl.exprboolean)
     373          self.assertRaises(TypeError, tcl.exprboolean, '8.2', '+6')
     374          self.assertRaises(TypeError, tcl.exprboolean, b'8.2 + 6')
     375          self.assertRaises(TclError, tcl.exprboolean, 'spam')
     376          check('', False)
     377          for value in ('0', 'false', 'no', 'off'):
     378              check(value, False)
     379              check('"%s"' % value, False)
     380              check('{%s}' % value, False)
     381          for value in ('1', 'true', 'yes', 'on'):
     382              check(value, True)
     383              check('"%s"' % value, True)
     384              check('{%s}' % value, True)
     385          check('8.2 + 6', True)
     386          check('3.1 + $a', True)
     387          check('2 + "$a.$b"', True)
     388          check('4*[llength "6 2"]', True)
     389          check('{word one} < "word $a"', False)
     390          check('4*2 < 7', False)
     391          check('hypot($a, 4)', True)
     392          check('5 / 4', True)
     393          check('5 / 4.0', True)
     394          check('5 / ( [string length "abcd"] + 0.0 )', True)
     395          check('20.0/5.0', True)
     396          check('"0x03" > "2"', True)
     397          check('[string length "a\xbd\u20ac"]', True)
     398          check(r'[string length "a\xbd\u20ac"]', True)
     399          self.assertRaises(TclError, tcl.exprboolean, '"abc"')
     400          check('2**64', True)
     401  
     402      def test_booleans(self):
     403          tcl = self.interp
     404          def check(expr, expected):
     405              result = tcl.call('expr', expr)
     406              if tcl.wantobjects():
     407                  self.assertEqual(result, expected)
     408                  self.assertIsInstance(result, int)
     409              else:
     410                  self.assertIn(result, (expr, str(int(expected))))
     411                  self.assertIsInstance(result, str)
     412          check('true', True)
     413          check('yes', True)
     414          check('on', True)
     415          check('false', False)
     416          check('no', False)
     417          check('off', False)
     418          check('1 < 2', True)
     419          check('1 > 2', False)
     420  
     421      def test_expr_bignum(self):
     422          tcl = self.interp
     423          for i in self.get_integers():
     424              result = tcl.call('expr', str(i))
     425              if self.wantobjects:
     426                  self.assertEqual(result, i)
     427                  self.assertIsInstance(result, int)
     428              else:
     429                  self.assertEqual(result, str(i))
     430                  self.assertIsInstance(result, str)
     431  
     432      def test_passing_values(self):
     433          def passValue(value):
     434              return self.interp.call('set', '_', value)
     435  
     436          self.assertEqual(passValue(True), True if self.wantobjects else '1')
     437          self.assertEqual(passValue(False), False if self.wantobjects else '0')
     438          self.assertEqual(passValue('string'), 'string')
     439          self.assertEqual(passValue('string\u20ac'), 'string\u20ac')
     440          self.assertEqual(passValue('string\U0001f4bb'), 'string\U0001f4bb')
     441          self.assertEqual(passValue('str\x00ing'), 'str\x00ing')
     442          self.assertEqual(passValue('str\x00ing\xbd'), 'str\x00ing\xbd')
     443          self.assertEqual(passValue('str\x00ing\u20ac'), 'str\x00ing\u20ac')
     444          self.assertEqual(passValue('str\x00ing\U0001f4bb'),
     445                           'str\x00ing\U0001f4bb')
     446          if sys.platform != 'win32':
     447              self.assertEqual(passValue('<\udce2\udc82\udcac>'),
     448                               '<\u20ac>')
     449              self.assertEqual(passValue('<\udced\udca0\udcbd\udced\udcb2\udcbb>'),
     450                               '<\U0001f4bb>')
     451          self.assertEqual(passValue(b'str\x00ing'),
     452                           b'str\x00ing' if self.wantobjects else 'str\x00ing')
     453          self.assertEqual(passValue(b'str\xc0\x80ing'),
     454                           b'str\xc0\x80ing' if self.wantobjects else 'str\xc0\x80ing')
     455          self.assertEqual(passValue(b'str\xbding'),
     456                           b'str\xbding' if self.wantobjects else 'str\xbding')
     457          for i in self.get_integers():
     458              self.assertEqual(passValue(i), i if self.wantobjects else str(i))
     459          for f in (0.0, 1.0, -1.0, 1/3,
     460                    sys.float_info.min, sys.float_info.max,
     461                    -sys.float_info.min, -sys.float_info.max):
     462              if self.wantobjects:
     463                  self.assertEqual(passValue(f), f)
     464              else:
     465                  self.assertEqual(float(passValue(f)), f)
     466          if self.wantobjects:
     467              f = passValue(float('nan'))
     468              self.assertNotEqual(f, f)
     469              self.assertEqual(passValue(float('inf')), float('inf'))
     470              self.assertEqual(passValue(-float('inf')), -float('inf'))
     471          else:
     472              self.assertEqual(float(passValue(float('inf'))), float('inf'))
     473              self.assertEqual(float(passValue(-float('inf'))), -float('inf'))
     474              # XXX NaN representation can be not parsable by float()
     475          self.assertEqual(passValue((1, '2', (3.4,))),
     476                           (1, '2', (3.4,)) if self.wantobjects else '1 2 3.4')
     477          self.assertEqual(passValue(['a', ['b', 'c']]),
     478                           ('a', ('b', 'c')) if self.wantobjects else 'a {b c}')
     479  
     480      def test_user_command(self):
     481          result = None
     482          def testfunc(arg):
     483              nonlocal result
     484              result = arg
     485              return arg
     486          self.interp.createcommand('testfunc', testfunc)
     487          self.addCleanup(self.interp.tk.deletecommand, 'testfunc')
     488          def check(value, expected=None, *, eq=self.assertEqual):
     489              if expected is None:
     490                  expected = value
     491              nonlocal result
     492              result = None
     493              r = self.interp.call('testfunc', value)
     494              self.assertIsInstance(result, str)
     495              eq(result, expected)
     496              self.assertIsInstance(r, str)
     497              eq(r, expected)
     498          def float_eq(actual, expected):
     499              self.assertAlmostEqual(float(actual), expected,
     500                                     delta=abs(expected) * 1e-10)
     501  
     502          check(True, '1')
     503          check(False, '0')
     504          check('string')
     505          check('string\xbd')
     506          check('string\u20ac')
     507          check('string\U0001f4bb')
     508          if sys.platform != 'win32':
     509              check('<\udce2\udc82\udcac>', '<\u20ac>')
     510              check('<\udced\udca0\udcbd\udced\udcb2\udcbb>', '<\U0001f4bb>')
     511          check('')
     512          check(b'string', 'string')
     513          check(b'string\xe2\x82\xac', 'string\xe2\x82\xac')
     514          check(b'string\xbd', 'string\xbd')
     515          check(b'', '')
     516          check('str\x00ing')
     517          check('str\x00ing\xbd')
     518          check('str\x00ing\u20ac')
     519          check(b'str\x00ing', 'str\x00ing')
     520          check(b'str\xc0\x80ing', 'str\xc0\x80ing')
     521          check(b'str\xc0\x80ing\xe2\x82\xac', 'str\xc0\x80ing\xe2\x82\xac')
     522          for i in self.get_integers():
     523              check(i, str(i))
     524          for f in (0.0, 1.0, -1.0):
     525              check(f, repr(f))
     526          for f in (1/3.0, sys.float_info.min, sys.float_info.max,
     527                    -sys.float_info.min, -sys.float_info.max):
     528              check(f, eq=float_eq)
     529          check(float('inf'), eq=float_eq)
     530          check(-float('inf'), eq=float_eq)
     531          # XXX NaN representation can be not parsable by float()
     532          check((), '')
     533          check((1, (2,), (3, 4), '5 6', ()), '1 2 {3 4} {5 6} {}')
     534          check([1, [2,], [3, 4], '5 6', []], '1 2 {3 4} {5 6} {}')
     535  
     536      def test_splitlist(self):
     537          splitlist = self.interp.tk.splitlist
     538          call = self.interp.tk.call
     539          self.assertRaises(TypeError, splitlist)
     540          self.assertRaises(TypeError, splitlist, 'a', 'b')
     541          self.assertRaises(TypeError, splitlist, 2)
     542          testcases = [
     543              ('2', ('2',)),
     544              ('', ()),
     545              ('{}', ('',)),
     546              ('""', ('',)),
     547              ('a\n b\t\r c\n ', ('a', 'b', 'c')),
     548              (b'a\n b\t\r c\n ', ('a', 'b', 'c')),
     549              ('a \u20ac', ('a', '\u20ac')),
     550              ('a \U0001f4bb', ('a', '\U0001f4bb')),
     551              (b'a \xe2\x82\xac', ('a', '\u20ac')),
     552              (b'a \xf0\x9f\x92\xbb', ('a', '\U0001f4bb')),
     553              (b'a \xed\xa0\xbd\xed\xb2\xbb', ('a', '\U0001f4bb')),
     554              (b'a\xc0\x80b c\xc0\x80d', ('a\x00b', 'c\x00d')),
     555              ('a {b c}', ('a', 'b c')),
     556              (r'a b\ c', ('a', 'b c')),
     557              (('a', 'b c'), ('a', 'b c')),
     558              ('a 2', ('a', '2')),
     559              (('a', 2), ('a', 2)),
     560              ('a 3.4', ('a', '3.4')),
     561              (('a', 3.4), ('a', 3.4)),
     562              ((), ()),
     563              ([], ()),
     564              (['a', ['b', 'c']], ('a', ['b', 'c'])),
     565              (call('list', 1, '2', (3.4,)),
     566                  (1, '2', (3.4,)) if self.wantobjects else
     567                  ('1', '2', '3.4')),
     568          ]
     569          if not self.wantobjects:
     570              expected = ('12', '\u20ac', '\xe2\x82\xac', '3.4')
     571          else:
     572              expected = (12, '\u20ac', b'\xe2\x82\xac', (3.4,))
     573          testcases += [
     574              (call('dict', 'create', 12, '\u20ac', b'\xe2\x82\xac', (3.4,)),
     575                  expected),
     576          ]
     577          dbg_info = ('want objects? %s, Tcl version: %s, Tcl patchlevel: %s'
     578                      % (self.wantobjects, tcl_version, self.interp.info_patchlevel()))
     579          for arg, res in testcases:
     580              self.assertEqual(splitlist(arg), res,
     581                               'arg=%a, %s' % (arg, dbg_info))
     582          self.assertRaises(TclError, splitlist, '{')
     583  
     584      def test_splitdict(self):
     585          splitdict = tkinter._splitdict
     586          tcl = self.interp.tk
     587  
     588          arg = '-a {1 2 3} -something foo status {}'
     589          self.assertEqual(splitdict(tcl, arg, False),
     590              {'-a': '1 2 3', '-something': 'foo', 'status': ''})
     591          self.assertEqual(splitdict(tcl, arg),
     592              {'a': '1 2 3', 'something': 'foo', 'status': ''})
     593  
     594          arg = ('-a', (1, 2, 3), '-something', 'foo', 'status', '{}')
     595          self.assertEqual(splitdict(tcl, arg, False),
     596              {'-a': (1, 2, 3), '-something': 'foo', 'status': '{}'})
     597          self.assertEqual(splitdict(tcl, arg),
     598              {'a': (1, 2, 3), 'something': 'foo', 'status': '{}'})
     599  
     600          self.assertRaises(RuntimeError, splitdict, tcl, '-a b -c ')
     601          self.assertRaises(RuntimeError, splitdict, tcl, ('-a', 'b', '-c'))
     602  
     603          arg = tcl.call('list',
     604                          '-a', (1, 2, 3), '-something', 'foo', 'status', ())
     605          self.assertEqual(splitdict(tcl, arg),
     606              {'a': (1, 2, 3) if self.wantobjects else '1 2 3',
     607               'something': 'foo', 'status': ''})
     608  
     609          arg = tcl.call('dict', 'create',
     610                         '-a', (1, 2, 3), '-something', 'foo', 'status', ())
     611          if not self.wantobjects:
     612              expected = {'a': '1 2 3', 'something': 'foo', 'status': ''}
     613          else:
     614              expected = {'a': (1, 2, 3), 'something': 'foo', 'status': ''}
     615          self.assertEqual(splitdict(tcl, arg), expected)
     616  
     617      def test_join(self):
     618          join = tkinter._join
     619          tcl = self.interp.tk
     620          def unpack(s):
     621              return tcl.call('lindex', s, 0)
     622          def check(value):
     623              self.assertEqual(unpack(join([value])), value)
     624              self.assertEqual(unpack(join([value, 0])), value)
     625              self.assertEqual(unpack(unpack(join([[value]]))), value)
     626              self.assertEqual(unpack(unpack(join([[value, 0]]))), value)
     627              self.assertEqual(unpack(unpack(join([[value], 0]))), value)
     628              self.assertEqual(unpack(unpack(join([[value, 0], 0]))), value)
     629          check('')
     630          check('spam')
     631          check('sp am')
     632          check('sp\tam')
     633          check('sp\nam')
     634          check(' \t\n')
     635          check('{spam}')
     636          check('{sp am}')
     637          check('"spam"')
     638          check('"sp am"')
     639          check('{"spam"}')
     640          check('"{spam}"')
     641          check('sp\\am')
     642          check('"sp\\am"')
     643          check('"{}" "{}"')
     644          check('"\\')
     645          check('"{')
     646          check('"}')
     647          check('\n\\')
     648          check('\n{')
     649          check('\n}')
     650          check('\\\n')
     651          check('{\n')
     652          check('}\n')
     653  
     654      @support.cpython_only
     655      def test_new_tcl_obj(self):
     656          support.check_disallow_instantiation(self, _tkinter.Tcl_Obj)
     657          support.check_disallow_instantiation(self, _tkinter.TkttType)
     658          support.check_disallow_instantiation(self, _tkinter.TkappType)
     659  
     660  class ESC[4;38;5;81mBigmemTclTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     661  
     662      def setUp(self):
     663          self.interp = Tcl()
     664  
     665      @support.cpython_only
     666      @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
     667      @support.bigmemtest(size=INT_MAX + 1, memuse=5, dry_run=False)
     668      def test_huge_string_call(self, size):
     669          value = ' ' * size
     670          self.assertRaises(OverflowError, self.interp.call, 'string', 'index', value, 0)
     671  
     672      @support.cpython_only
     673      @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
     674      @support.bigmemtest(size=INT_MAX + 1, memuse=2, dry_run=False)
     675      def test_huge_string_builtins(self, size):
     676          tk = self.interp.tk
     677          value = '1' + ' ' * size
     678          self.assertRaises(OverflowError, tk.getint, value)
     679          self.assertRaises(OverflowError, tk.getdouble, value)
     680          self.assertRaises(OverflowError, tk.getboolean, value)
     681          self.assertRaises(OverflowError, tk.eval, value)
     682          self.assertRaises(OverflowError, tk.evalfile, value)
     683          self.assertRaises(OverflowError, tk.record, value)
     684          self.assertRaises(OverflowError, tk.adderrorinfo, value)
     685          self.assertRaises(OverflowError, tk.setvar, value, 'x', 'a')
     686          self.assertRaises(OverflowError, tk.setvar, 'x', value, 'a')
     687          self.assertRaises(OverflowError, tk.unsetvar, value)
     688          self.assertRaises(OverflowError, tk.unsetvar, 'x', value)
     689          self.assertRaises(OverflowError, tk.adderrorinfo, value)
     690          self.assertRaises(OverflowError, tk.exprstring, value)
     691          self.assertRaises(OverflowError, tk.exprlong, value)
     692          self.assertRaises(OverflowError, tk.exprboolean, value)
     693          self.assertRaises(OverflowError, tk.splitlist, value)
     694          self.assertRaises(OverflowError, tk.createcommand, value, max)
     695          self.assertRaises(OverflowError, tk.deletecommand, value)
     696  
     697      @support.cpython_only
     698      @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
     699      @support.bigmemtest(size=INT_MAX + 1, memuse=6, dry_run=False)
     700      def test_huge_string_builtins2(self, size):
     701          # These commands require larger memory for possible error messages
     702          tk = self.interp.tk
     703          value = '1' + ' ' * size
     704          self.assertRaises(OverflowError, tk.evalfile, value)
     705          self.assertRaises(OverflowError, tk.unsetvar, value)
     706          self.assertRaises(OverflowError, tk.unsetvar, 'x', value)
     707  
     708  
     709  def setUpModule():
     710      if support.verbose:
     711          tcl = Tcl()
     712          print('patchlevel =', tcl.call('info', 'patchlevel'), flush=True)
     713  
     714  
     715  if __name__ == "__main__":
     716      unittest.main()