test_tcl.py 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
  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. # Skip this test if the _tkinter module wasn't built.
  8. _tkinter = test_support.import_module('_tkinter')
  9. import Tkinter as tkinter
  10. from Tkinter import Tcl
  11. from _tkinter import TclError
  12. try:
  13. from _testcapi import INT_MAX, PY_SSIZE_T_MAX
  14. except ImportError:
  15. INT_MAX = PY_SSIZE_T_MAX = sys.maxsize
  16. tcl_version = tuple(map(int, _tkinter.TCL_VERSION.split('.')))
  17. _tk_patchlevel = None
  18. def get_tk_patchlevel():
  19. global _tk_patchlevel
  20. if _tk_patchlevel is None:
  21. tcl = Tcl()
  22. patchlevel = tcl.call('info', 'patchlevel')
  23. m = re.match(r'(\d+)\.(\d+)([ab.])(\d+)$', patchlevel)
  24. major, minor, releaselevel, serial = m.groups()
  25. major, minor, serial = int(major), int(minor), int(serial)
  26. releaselevel = {'a': 'alpha', 'b': 'beta', '.': 'final'}[releaselevel]
  27. if releaselevel == 'final':
  28. _tk_patchlevel = major, minor, serial, releaselevel, 0
  29. else:
  30. _tk_patchlevel = major, minor, 0, releaselevel, serial
  31. return _tk_patchlevel
  32. class TkinterTest(unittest.TestCase):
  33. def testFlattenLen(self):
  34. # flatten(<object with no length>)
  35. self.assertRaises(TypeError, _tkinter._flatten, True)
  36. class TclTest(unittest.TestCase):
  37. def setUp(self):
  38. self.interp = Tcl()
  39. self.wantobjects = self.interp.tk.wantobjects()
  40. def testEval(self):
  41. tcl = self.interp
  42. tcl.eval('set a 1')
  43. self.assertEqual(tcl.eval('set a'),'1')
  44. def testEvalException(self):
  45. tcl = self.interp
  46. self.assertRaises(TclError,tcl.eval,'set a')
  47. def testEvalException2(self):
  48. tcl = self.interp
  49. self.assertRaises(TclError,tcl.eval,'this is wrong')
  50. def testCall(self):
  51. tcl = self.interp
  52. tcl.call('set','a','1')
  53. self.assertEqual(tcl.call('set','a'),'1')
  54. def testCallException(self):
  55. tcl = self.interp
  56. self.assertRaises(TclError,tcl.call,'set','a')
  57. def testCallException2(self):
  58. tcl = self.interp
  59. self.assertRaises(TclError,tcl.call,'this','is','wrong')
  60. def testSetVar(self):
  61. tcl = self.interp
  62. tcl.setvar('a','1')
  63. self.assertEqual(tcl.eval('set a'),'1')
  64. def testSetVarArray(self):
  65. tcl = self.interp
  66. tcl.setvar('a(1)','1')
  67. self.assertEqual(tcl.eval('set a(1)'),'1')
  68. def testGetVar(self):
  69. tcl = self.interp
  70. tcl.eval('set a 1')
  71. self.assertEqual(tcl.getvar('a'),'1')
  72. def testGetVarArray(self):
  73. tcl = self.interp
  74. tcl.eval('set a(1) 1')
  75. self.assertEqual(tcl.getvar('a(1)'),'1')
  76. def testGetVarException(self):
  77. tcl = self.interp
  78. self.assertRaises(TclError,tcl.getvar,'a')
  79. def testGetVarArrayException(self):
  80. tcl = self.interp
  81. self.assertRaises(TclError,tcl.getvar,'a(1)')
  82. def testUnsetVar(self):
  83. tcl = self.interp
  84. tcl.setvar('a',1)
  85. self.assertEqual(tcl.eval('info exists a'),'1')
  86. tcl.unsetvar('a')
  87. self.assertEqual(tcl.eval('info exists a'),'0')
  88. def testUnsetVarArray(self):
  89. tcl = self.interp
  90. tcl.setvar('a(1)',1)
  91. tcl.setvar('a(2)',2)
  92. self.assertEqual(tcl.eval('info exists a(1)'),'1')
  93. self.assertEqual(tcl.eval('info exists a(2)'),'1')
  94. tcl.unsetvar('a(1)')
  95. self.assertEqual(tcl.eval('info exists a(1)'),'0')
  96. self.assertEqual(tcl.eval('info exists a(2)'),'1')
  97. def testUnsetVarException(self):
  98. tcl = self.interp
  99. self.assertRaises(TclError,tcl.unsetvar,'a')
  100. def get_integers(self):
  101. integers = (0, 1, -1, 2**31-1, -2**31)
  102. if tcl_version >= (8, 4): # wideInt was added in Tcl 8.4
  103. integers += (2**31, -2**31-1, 2**63-1, -2**63)
  104. # bignum was added in Tcl 8.5, but its support is able only since 8.5.8
  105. if (get_tk_patchlevel() >= (8, 6, 0, 'final') or
  106. (8, 5, 8) <= get_tk_patchlevel() < (8, 6)):
  107. integers += (2**63, -2**63-1, 2**1000, -2**1000)
  108. return integers
  109. def test_getint(self):
  110. tcl = self.interp.tk
  111. for i in self.get_integers():
  112. result = tcl.getint(' %d ' % i)
  113. self.assertEqual(result, i)
  114. self.assertIsInstance(result, type(int(result)))
  115. if tcl_version >= (8, 5):
  116. self.assertEqual(tcl.getint(' {:#o} '.format(i)), i)
  117. self.assertEqual(tcl.getint(' %#o ' % i), i)
  118. self.assertEqual(tcl.getint(' %#x ' % i), i)
  119. if tcl_version < (8, 5): # bignum was added in Tcl 8.5
  120. self.assertRaises(TclError, tcl.getint, str(2**1000))
  121. self.assertEqual(tcl.getint(42), 42)
  122. self.assertRaises(TypeError, tcl.getint)
  123. self.assertRaises(TypeError, tcl.getint, '42', '10')
  124. self.assertRaises(TypeError, tcl.getint, 42.0)
  125. self.assertRaises(TclError, tcl.getint, 'a')
  126. self.assertRaises((TypeError, ValueError, TclError),
  127. tcl.getint, '42\0')
  128. if test_support.have_unicode:
  129. self.assertEqual(tcl.getint(unicode('42')), 42)
  130. self.assertRaises((UnicodeEncodeError, ValueError, TclError),
  131. tcl.getint, '42' + unichr(0xd800))
  132. def test_getdouble(self):
  133. tcl = self.interp.tk
  134. self.assertEqual(tcl.getdouble(' 42 '), 42.0)
  135. self.assertEqual(tcl.getdouble(' 42.5 '), 42.5)
  136. self.assertEqual(tcl.getdouble(42.5), 42.5)
  137. self.assertRaises(TypeError, tcl.getdouble)
  138. self.assertRaises(TypeError, tcl.getdouble, '42.5', '10')
  139. self.assertRaises(TypeError, tcl.getdouble, 42)
  140. self.assertRaises(TclError, tcl.getdouble, 'a')
  141. self.assertRaises((TypeError, ValueError, TclError),
  142. tcl.getdouble, '42.5\0')
  143. if test_support.have_unicode:
  144. self.assertEqual(tcl.getdouble(unicode('42.5')), 42.5)
  145. self.assertRaises((UnicodeEncodeError, ValueError, TclError),
  146. tcl.getdouble, '42.5' + unichr(0xd800))
  147. def test_getboolean(self):
  148. tcl = self.interp.tk
  149. self.assertIs(tcl.getboolean('on'), True)
  150. self.assertIs(tcl.getboolean('1'), True)
  151. self.assertIs(tcl.getboolean(u'on'), True)
  152. self.assertIs(tcl.getboolean(u'1'), True)
  153. self.assertIs(tcl.getboolean(42), True)
  154. self.assertIs(tcl.getboolean(0), False)
  155. self.assertIs(tcl.getboolean(42L), True)
  156. self.assertIs(tcl.getboolean(0L), False)
  157. self.assertRaises(TypeError, tcl.getboolean)
  158. self.assertRaises(TypeError, tcl.getboolean, 'on', '1')
  159. self.assertRaises(TypeError, tcl.getboolean, 1.0)
  160. self.assertRaises(TclError, tcl.getboolean, 'a')
  161. self.assertRaises((TypeError, ValueError, TclError),
  162. tcl.getboolean, 'on\0')
  163. if test_support.have_unicode:
  164. self.assertIs(tcl.getboolean(unicode('on')), True)
  165. self.assertRaises((UnicodeEncodeError, ValueError, TclError),
  166. tcl.getboolean, 'on' + unichr(0xd800))
  167. def testEvalFile(self):
  168. tcl = self.interp
  169. filename = "testEvalFile.tcl"
  170. fd = open(filename,'w')
  171. script = """set a 1
  172. set b 2
  173. set c [ expr $a + $b ]
  174. """
  175. fd.write(script)
  176. fd.close()
  177. tcl.evalfile(filename)
  178. os.remove(filename)
  179. self.assertEqual(tcl.eval('set a'),'1')
  180. self.assertEqual(tcl.eval('set b'),'2')
  181. self.assertEqual(tcl.eval('set c'),'3')
  182. def test_evalfile_null_in_result(self):
  183. tcl = self.interp
  184. with open(test_support.TESTFN, 'wb') as f:
  185. self.addCleanup(test_support.unlink, test_support.TESTFN)
  186. f.write("""
  187. set a "a\0b"
  188. set b "a\\0b"
  189. """)
  190. tcl.evalfile(test_support.TESTFN)
  191. self.assertEqual(tcl.eval('set a'), 'a\xc0\x80b')
  192. self.assertEqual(tcl.eval('set b'), 'a\xc0\x80b')
  193. def testEvalFileException(self):
  194. tcl = self.interp
  195. filename = "doesnotexists"
  196. try:
  197. os.remove(filename)
  198. except Exception,e:
  199. pass
  200. self.assertRaises(TclError,tcl.evalfile,filename)
  201. def testPackageRequireException(self):
  202. tcl = self.interp
  203. self.assertRaises(TclError,tcl.eval,'package require DNE')
  204. @unittest.skipUnless(sys.platform == 'win32', "only applies to Windows")
  205. def testLoadWithUNC(self):
  206. # Build a UNC path from the regular path.
  207. # Something like
  208. # \\%COMPUTERNAME%\c$\python27\python.exe
  209. fullname = os.path.abspath(sys.executable)
  210. if fullname[1] != ':':
  211. self.skipTest('unusable path: %r' % fullname)
  212. unc_name = r'\\%s\%s$\%s' % (os.environ['COMPUTERNAME'],
  213. fullname[0],
  214. fullname[3:])
  215. with test_support.EnvironmentVarGuard() as env:
  216. env.unset("TCL_LIBRARY")
  217. cmd = '%s -c "import Tkinter; print Tkinter"' % (unc_name,)
  218. try:
  219. p = Popen(cmd, stdout=PIPE, stderr=PIPE)
  220. except WindowsError as e:
  221. if e.winerror == 5:
  222. self.skipTest('Not permitted to start the child process')
  223. else:
  224. raise
  225. out_data, err_data = p.communicate()
  226. msg = '\n\n'.join(['"Tkinter.py" not in output',
  227. 'Command:', cmd,
  228. 'stdout:', out_data,
  229. 'stderr:', err_data])
  230. self.assertIn('Tkinter.py', out_data, msg)
  231. self.assertEqual(p.wait(), 0, 'Non-zero exit code')
  232. def test_exprstring(self):
  233. tcl = self.interp
  234. tcl.call('set', 'a', 3)
  235. tcl.call('set', 'b', 6)
  236. def check(expr, expected):
  237. result = tcl.exprstring(expr)
  238. self.assertEqual(result, expected)
  239. self.assertIsInstance(result, str)
  240. self.assertRaises(TypeError, tcl.exprstring)
  241. self.assertRaises(TypeError, tcl.exprstring, '8.2', '+6')
  242. self.assertRaises(TclError, tcl.exprstring, 'spam')
  243. check('', '0')
  244. check('8.2 + 6', '14.2')
  245. check('3.1 + $a', '6.1')
  246. check('2 + "$a.$b"', '5.6')
  247. check('4*[llength "6 2"]', '8')
  248. check('{word one} < "word $a"', '0')
  249. check('4*2 < 7', '0')
  250. check('hypot($a, 4)', '5.0')
  251. check('5 / 4', '1')
  252. check('5 / 4.0', '1.25')
  253. check('5 / ( [string length "abcd"] + 0.0 )', '1.25')
  254. check('20.0/5.0', '4.0')
  255. check('"0x03" > "2"', '1')
  256. check('[string length "a\xc2\xbd\xe2\x82\xac"]', '3')
  257. check(r'[string length "a\xbd\u20ac"]', '3')
  258. check('"abc"', 'abc')
  259. check('"a\xc2\xbd\xe2\x82\xac"', 'a\xc2\xbd\xe2\x82\xac')
  260. check(r'"a\xbd\u20ac"', 'a\xc2\xbd\xe2\x82\xac')
  261. check(r'"a\0b"', 'a\xc0\x80b')
  262. if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
  263. check('2**64', str(2**64))
  264. def test_exprdouble(self):
  265. tcl = self.interp
  266. tcl.call('set', 'a', 3)
  267. tcl.call('set', 'b', 6)
  268. def check(expr, expected):
  269. result = tcl.exprdouble(expr)
  270. self.assertEqual(result, expected)
  271. self.assertIsInstance(result, float)
  272. self.assertRaises(TypeError, tcl.exprdouble)
  273. self.assertRaises(TypeError, tcl.exprdouble, '8.2', '+6')
  274. self.assertRaises(TclError, tcl.exprdouble, 'spam')
  275. check('', 0.0)
  276. check('8.2 + 6', 14.2)
  277. check('3.1 + $a', 6.1)
  278. check('2 + "$a.$b"', 5.6)
  279. check('4*[llength "6 2"]', 8.0)
  280. check('{word one} < "word $a"', 0.0)
  281. check('4*2 < 7', 0.0)
  282. check('hypot($a, 4)', 5.0)
  283. check('5 / 4', 1.0)
  284. check('5 / 4.0', 1.25)
  285. check('5 / ( [string length "abcd"] + 0.0 )', 1.25)
  286. check('20.0/5.0', 4.0)
  287. check('"0x03" > "2"', 1.0)
  288. check('[string length "a\xc2\xbd\xe2\x82\xac"]', 3.0)
  289. check(r'[string length "a\xbd\u20ac"]', 3.0)
  290. self.assertRaises(TclError, tcl.exprdouble, '"abc"')
  291. if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
  292. check('2**64', float(2**64))
  293. def test_exprlong(self):
  294. tcl = self.interp
  295. tcl.call('set', 'a', 3)
  296. tcl.call('set', 'b', 6)
  297. def check(expr, expected):
  298. result = tcl.exprlong(expr)
  299. self.assertEqual(result, expected)
  300. self.assertIsInstance(result, int)
  301. self.assertRaises(TypeError, tcl.exprlong)
  302. self.assertRaises(TypeError, tcl.exprlong, '8.2', '+6')
  303. self.assertRaises(TclError, tcl.exprlong, 'spam')
  304. check('', 0)
  305. check('8.2 + 6', 14)
  306. check('3.1 + $a', 6)
  307. check('2 + "$a.$b"', 5)
  308. check('4*[llength "6 2"]', 8)
  309. check('{word one} < "word $a"', 0)
  310. check('4*2 < 7', 0)
  311. check('hypot($a, 4)', 5)
  312. check('5 / 4', 1)
  313. check('5 / 4.0', 1)
  314. check('5 / ( [string length "abcd"] + 0.0 )', 1)
  315. check('20.0/5.0', 4)
  316. check('"0x03" > "2"', 1)
  317. check('[string length "a\xc2\xbd\xe2\x82\xac"]', 3)
  318. check(r'[string length "a\xbd\u20ac"]', 3)
  319. self.assertRaises(TclError, tcl.exprlong, '"abc"')
  320. if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
  321. self.assertRaises(TclError, tcl.exprlong, '2**64')
  322. def test_exprboolean(self):
  323. tcl = self.interp
  324. tcl.call('set', 'a', 3)
  325. tcl.call('set', 'b', 6)
  326. def check(expr, expected):
  327. result = tcl.exprboolean(expr)
  328. self.assertEqual(result, expected)
  329. self.assertIsInstance(result, int)
  330. self.assertNotIsInstance(result, bool)
  331. self.assertRaises(TypeError, tcl.exprboolean)
  332. self.assertRaises(TypeError, tcl.exprboolean, '8.2', '+6')
  333. self.assertRaises(TclError, tcl.exprboolean, 'spam')
  334. check('', False)
  335. for value in ('0', 'false', 'no', 'off'):
  336. check(value, False)
  337. check('"%s"' % value, False)
  338. check('{%s}' % value, False)
  339. for value in ('1', 'true', 'yes', 'on'):
  340. check(value, True)
  341. check('"%s"' % value, True)
  342. check('{%s}' % value, True)
  343. check('8.2 + 6', True)
  344. check('3.1 + $a', True)
  345. check('2 + "$a.$b"', True)
  346. check('4*[llength "6 2"]', True)
  347. check('{word one} < "word $a"', False)
  348. check('4*2 < 7', False)
  349. check('hypot($a, 4)', True)
  350. check('5 / 4', True)
  351. check('5 / 4.0', True)
  352. check('5 / ( [string length "abcd"] + 0.0 )', True)
  353. check('20.0/5.0', True)
  354. check('"0x03" > "2"', True)
  355. check('[string length "a\xc2\xbd\xe2\x82\xac"]', True)
  356. check(r'[string length "a\xbd\u20ac"]', True)
  357. self.assertRaises(TclError, tcl.exprboolean, '"abc"')
  358. if tcl_version >= (8, 5): # bignum was added in Tcl 8.5
  359. check('2**64', True)
  360. @unittest.skipUnless(tcl_version >= (8, 5), 'requires Tcl version >= 8.5')
  361. def test_booleans(self):
  362. tcl = self.interp
  363. def check(expr, expected):
  364. result = tcl.call('expr', expr)
  365. if tcl.wantobjects():
  366. self.assertEqual(result, expected)
  367. self.assertIsInstance(result, int)
  368. else:
  369. self.assertIn(result, (expr, str(int(expected))))
  370. self.assertIsInstance(result, str)
  371. check('true', True)
  372. check('yes', True)
  373. check('on', True)
  374. check('false', False)
  375. check('no', False)
  376. check('off', False)
  377. check('1 < 2', True)
  378. check('1 > 2', False)
  379. def test_expr_bignum(self):
  380. tcl = self.interp
  381. for i in self.get_integers():
  382. result = tcl.call('expr', str(i))
  383. if self.wantobjects:
  384. self.assertEqual(result, i)
  385. self.assertIsInstance(result, (int, long))
  386. if abs(result) < 2**31:
  387. self.assertIsInstance(result, int)
  388. else:
  389. self.assertEqual(result, str(i))
  390. self.assertIsInstance(result, str)
  391. if tcl_version < (8, 5): # bignum was added in Tcl 8.5
  392. self.assertRaises(TclError, tcl.call, 'expr', str(2**1000))
  393. def test_passing_values(self):
  394. def passValue(value):
  395. return self.interp.call('set', '_', value)
  396. self.assertEqual(passValue(True), True if self.wantobjects else '1')
  397. self.assertEqual(passValue(False), False if self.wantobjects else '0')
  398. self.assertEqual(passValue('string'), 'string')
  399. self.assertEqual(passValue('string\xbd'), 'string\xbd')
  400. self.assertEqual(passValue('string\xe2\x82\xac'), u'string\u20ac')
  401. self.assertEqual(passValue(u'string'), u'string')
  402. self.assertEqual(passValue(u'string\xbd'), u'string\xbd')
  403. self.assertEqual(passValue(u'string\u20ac'), u'string\u20ac')
  404. self.assertEqual(passValue('str\x00ing'), 'str\x00ing')
  405. self.assertEqual(passValue('str\xc0\x80ing'), 'str\x00ing')
  406. self.assertEqual(passValue(u'str\x00ing'), u'str\x00ing')
  407. self.assertEqual(passValue(u'str\x00ing\xbd'), u'str\x00ing\xbd')
  408. self.assertEqual(passValue(u'str\x00ing\u20ac'), u'str\x00ing\u20ac')
  409. for i in self.get_integers():
  410. self.assertEqual(passValue(i), i if self.wantobjects else str(i))
  411. if tcl_version < (8, 5): # bignum was added in Tcl 8.5
  412. self.assertEqual(passValue(2**1000), str(2**1000))
  413. for f in (0.0, 1.0, -1.0, 1//3, 1/3.0,
  414. sys.float_info.min, sys.float_info.max,
  415. -sys.float_info.min, -sys.float_info.max):
  416. if self.wantobjects:
  417. self.assertEqual(passValue(f), f)
  418. else:
  419. self.assertEqual(float(passValue(f)), f)
  420. if self.wantobjects:
  421. f = passValue(float('nan'))
  422. self.assertNotEqual(f, f)
  423. self.assertEqual(passValue(float('inf')), float('inf'))
  424. self.assertEqual(passValue(-float('inf')), -float('inf'))
  425. else:
  426. self.assertEqual(float(passValue(float('inf'))), float('inf'))
  427. self.assertEqual(float(passValue(-float('inf'))), -float('inf'))
  428. # XXX NaN representation can be not parsable by float()
  429. self.assertEqual(passValue((1, '2', (3.4,))),
  430. (1, '2', (3.4,)) if self.wantobjects else '1 2 3.4')
  431. def test_user_command(self):
  432. result = []
  433. def testfunc(arg):
  434. result.append(arg)
  435. return arg
  436. self.interp.createcommand('testfunc', testfunc)
  437. self.addCleanup(self.interp.tk.deletecommand, 'testfunc')
  438. def check(value, expected=None, eq=self.assertEqual):
  439. if expected is None:
  440. expected = value
  441. del result[:]
  442. r = self.interp.call('testfunc', value)
  443. self.assertEqual(len(result), 1)
  444. self.assertIsInstance(result[0], (str, unicode))
  445. eq(result[0], expected)
  446. self.assertIsInstance(r, (str, unicode))
  447. eq(r, expected)
  448. def float_eq(actual, expected):
  449. self.assertAlmostEqual(float(actual), expected,
  450. delta=abs(expected) * 1e-10)
  451. check(True, '1')
  452. check(False, '0')
  453. check('string')
  454. check('string\xbd')
  455. check('string\xe2\x82\xac', u'string\u20ac')
  456. check('')
  457. check(u'string')
  458. check(u'string\xbd')
  459. check(u'string\u20ac')
  460. check(u'')
  461. check('str\xc0\x80ing', u'str\x00ing')
  462. check('str\xc0\x80ing\xe2\x82\xac', u'str\x00ing\u20ac')
  463. check(u'str\x00ing')
  464. check(u'str\x00ing\xbd')
  465. check(u'str\x00ing\u20ac')
  466. for i in self.get_integers():
  467. check(i, str(i))
  468. if tcl_version < (8, 5): # bignum was added in Tcl 8.5
  469. check(2**1000, str(2**1000))
  470. for f in (0.0, 1.0, -1.0):
  471. check(f, repr(f))
  472. for f in (1/3.0, sys.float_info.min, sys.float_info.max,
  473. -sys.float_info.min, -sys.float_info.max):
  474. check(f, eq=float_eq)
  475. check(float('inf'), eq=float_eq)
  476. check(-float('inf'), eq=float_eq)
  477. # XXX NaN representation can be not parsable by float()
  478. check((), '')
  479. check((1, (2,), (3, 4), '5 6', ()), '1 2 {3 4} {5 6} {}')
  480. def test_splitlist(self):
  481. splitlist = self.interp.tk.splitlist
  482. call = self.interp.tk.call
  483. self.assertRaises(TypeError, splitlist)
  484. self.assertRaises(TypeError, splitlist, 'a', 'b')
  485. self.assertRaises(TypeError, splitlist, 2)
  486. testcases = [
  487. ('2', ('2',)),
  488. ('', ()),
  489. ('{}', ('',)),
  490. ('""', ('',)),
  491. ('a\n b\t\r c\n ', ('a', 'b', 'c')),
  492. (u'a\n b\t\r c\n ', ('a', 'b', 'c')),
  493. ('a \xe2\x82\xac', ('a', '\xe2\x82\xac')),
  494. (u'a \u20ac', ('a', '\xe2\x82\xac')),
  495. ('a\xc0\x80b c\xc0\x80d', ('a\xc0\x80b', 'c\xc0\x80d')),
  496. ('a {b c}', ('a', 'b c')),
  497. (r'a b\ c', ('a', 'b c')),
  498. (('a', 'b c'), ('a', 'b c')),
  499. ('a 2', ('a', '2')),
  500. (('a', 2), ('a', 2)),
  501. ('a 3.4', ('a', '3.4')),
  502. (('a', 3.4), ('a', 3.4)),
  503. ((), ()),
  504. (call('list', 1, '2', (3.4,)),
  505. (1, '2', (3.4,)) if self.wantobjects else
  506. ('1', '2', '3.4')),
  507. ]
  508. if tcl_version >= (8, 5):
  509. if not self.wantobjects:
  510. expected = ('12', '\xe2\x82\xac', '\xe2\x82\xac', '3.4')
  511. elif get_tk_patchlevel() < (8, 5, 5):
  512. # Before 8.5.5 dicts were converted to lists through string
  513. expected = ('12', u'\u20ac', u'\u20ac', '3.4')
  514. else:
  515. expected = (12, u'\u20ac', u'\u20ac', (3.4,))
  516. testcases += [
  517. (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)),
  518. expected),
  519. ]
  520. for arg, res in testcases:
  521. self.assertEqual(splitlist(arg), res)
  522. self.assertRaises(TclError, splitlist, '{')
  523. def test_split(self):
  524. split = self.interp.tk.split
  525. call = self.interp.tk.call
  526. self.assertRaises(TypeError, split)
  527. self.assertRaises(TypeError, split, 'a', 'b')
  528. self.assertRaises(TypeError, split, 2)
  529. testcases = [
  530. ('2', '2'),
  531. ('', ''),
  532. ('{}', ''),
  533. ('""', ''),
  534. ('{', '{'),
  535. ('a\n b\t\r c\n ', ('a', 'b', 'c')),
  536. (u'a\n b\t\r c\n ', ('a', 'b', 'c')),
  537. ('a \xe2\x82\xac', ('a', '\xe2\x82\xac')),
  538. (u'a \u20ac', ('a', '\xe2\x82\xac')),
  539. ('a\xc0\x80b', 'a\xc0\x80b'),
  540. ('a\xc0\x80b c\xc0\x80d', ('a\xc0\x80b', 'c\xc0\x80d')),
  541. ('a {b c}', ('a', ('b', 'c'))),
  542. (r'a b\ c', ('a', ('b', 'c'))),
  543. (('a', 'b c'), ('a', ('b', 'c'))),
  544. (('a', u'b c'), ('a', ('b', 'c'))),
  545. ('a 2', ('a', '2')),
  546. (('a', 2), ('a', 2)),
  547. ('a 3.4', ('a', '3.4')),
  548. (('a', 3.4), ('a', 3.4)),
  549. (('a', (2, 3.4)), ('a', (2, 3.4))),
  550. ((), ()),
  551. (call('list', 1, '2', (3.4,)),
  552. (1, '2', (3.4,)) if self.wantobjects else
  553. ('1', '2', '3.4')),
  554. ]
  555. if tcl_version >= (8, 5):
  556. if not self.wantobjects:
  557. expected = ('12', '\xe2\x82\xac', '\xe2\x82\xac', '3.4')
  558. elif get_tk_patchlevel() < (8, 5, 5):
  559. # Before 8.5.5 dicts were converted to lists through string
  560. expected = ('12', u'\u20ac', u'\u20ac', '3.4')
  561. else:
  562. expected = (12, u'\u20ac', u'\u20ac', (3.4,))
  563. testcases += [
  564. (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)),
  565. expected),
  566. ]
  567. for arg, res in testcases:
  568. self.assertEqual(split(arg), res)
  569. def test_splitdict(self):
  570. splitdict = tkinter._splitdict
  571. tcl = self.interp.tk
  572. arg = '-a {1 2 3} -something foo status {}'
  573. self.assertEqual(splitdict(tcl, arg, False),
  574. {'-a': '1 2 3', '-something': 'foo', 'status': ''})
  575. self.assertEqual(splitdict(tcl, arg),
  576. {'a': '1 2 3', 'something': 'foo', 'status': ''})
  577. arg = ('-a', (1, 2, 3), '-something', 'foo', 'status', '{}')
  578. self.assertEqual(splitdict(tcl, arg, False),
  579. {'-a': (1, 2, 3), '-something': 'foo', 'status': '{}'})
  580. self.assertEqual(splitdict(tcl, arg),
  581. {'a': (1, 2, 3), 'something': 'foo', 'status': '{}'})
  582. self.assertRaises(RuntimeError, splitdict, tcl, '-a b -c ')
  583. self.assertRaises(RuntimeError, splitdict, tcl, ('-a', 'b', '-c'))
  584. arg = tcl.call('list',
  585. '-a', (1, 2, 3), '-something', 'foo', 'status', ())
  586. self.assertEqual(splitdict(tcl, arg),
  587. {'a': (1, 2, 3) if self.wantobjects else '1 2 3',
  588. 'something': 'foo', 'status': ''})
  589. if tcl_version >= (8, 5):
  590. arg = tcl.call('dict', 'create',
  591. '-a', (1, 2, 3), '-something', 'foo', 'status', ())
  592. if not self.wantobjects or get_tk_patchlevel() < (8, 5, 5):
  593. # Before 8.5.5 dicts were converted to lists through string
  594. expected = {'a': '1 2 3', 'something': 'foo', 'status': ''}
  595. else:
  596. expected = {'a': (1, 2, 3), 'something': 'foo', 'status': ''}
  597. self.assertEqual(splitdict(tcl, arg), expected)
  598. character_size = 4 if sys.maxunicode > 0xFFFF else 2
  599. class BigmemTclTest(unittest.TestCase):
  600. def setUp(self):
  601. self.interp = Tcl()
  602. @test_support.cpython_only
  603. @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
  604. @test_support.precisionbigmemtest(size=INT_MAX + 1, memuse=5, dry_run=False)
  605. def test_huge_string_call(self, size):
  606. value = ' ' * size
  607. self.assertRaises(OverflowError, self.interp.call, 'set', '_', value)
  608. @test_support.cpython_only
  609. @unittest.skipUnless(test_support.have_unicode, 'requires unicode support')
  610. @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
  611. @test_support.precisionbigmemtest(size=INT_MAX + 1,
  612. memuse=2*character_size + 2,
  613. dry_run=False)
  614. def test_huge_unicode_call(self, size):
  615. value = unicode(' ') * size
  616. self.assertRaises(OverflowError, self.interp.call, 'set', '_', value)
  617. @test_support.cpython_only
  618. @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
  619. @test_support.precisionbigmemtest(size=INT_MAX + 1, memuse=9, dry_run=False)
  620. def test_huge_string_builtins(self, size):
  621. value = '1' + ' ' * size
  622. self.check_huge_string_builtins(value)
  623. @test_support.cpython_only
  624. @unittest.skipUnless(test_support.have_unicode, 'requires unicode support')
  625. @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
  626. @test_support.precisionbigmemtest(size=INT_MAX + 1,
  627. memuse=2*character_size + 7,
  628. dry_run=False)
  629. def test_huge_unicode_builtins(self, size):
  630. value = unicode('1' + ' ' * size)
  631. self.check_huge_string_builtins(value)
  632. def check_huge_string_builtins(self, value):
  633. self.assertRaises(OverflowError, self.interp.tk.getint, value)
  634. self.assertRaises(OverflowError, self.interp.tk.getdouble, value)
  635. self.assertRaises(OverflowError, self.interp.tk.getboolean, value)
  636. self.assertRaises(OverflowError, self.interp.eval, value)
  637. self.assertRaises(OverflowError, self.interp.evalfile, value)
  638. self.assertRaises(OverflowError, self.interp.record, value)
  639. self.assertRaises(OverflowError, self.interp.adderrorinfo, value)
  640. self.assertRaises(OverflowError, self.interp.setvar, value, 'x', 'a')
  641. self.assertRaises(OverflowError, self.interp.setvar, 'x', value, 'a')
  642. self.assertRaises(OverflowError, self.interp.unsetvar, value)
  643. self.assertRaises(OverflowError, self.interp.unsetvar, 'x', value)
  644. self.assertRaises(OverflowError, self.interp.adderrorinfo, value)
  645. self.assertRaises(OverflowError, self.interp.exprstring, value)
  646. self.assertRaises(OverflowError, self.interp.exprlong, value)
  647. self.assertRaises(OverflowError, self.interp.exprboolean, value)
  648. self.assertRaises(OverflowError, self.interp.splitlist, value)
  649. self.assertRaises(OverflowError, self.interp.split, value)
  650. self.assertRaises(OverflowError, self.interp.createcommand, value, max)
  651. self.assertRaises(OverflowError, self.interp.deletecommand, value)
  652. def setUpModule():
  653. if test_support.verbose:
  654. tcl = Tcl()
  655. print 'patchlevel =', tcl.call('info', 'patchlevel')
  656. def test_main():
  657. test_support.run_unittest(TclTest, TkinterTest, BigmemTclTest)
  658. if __name__ == "__main__":
  659. test_main()