summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/lib-tk/Tkinter.py35
-rw-r--r--Lib/test/test_tcl.py159
2 files changed, 189 insertions, 5 deletions
diff --git a/Lib/lib-tk/Tkinter.py b/Lib/lib-tk/Tkinter.py
index 67e942e..5ad065d 100644
--- a/Lib/lib-tk/Tkinter.py
+++ b/Lib/lib-tk/Tkinter.py
@@ -1546,23 +1546,36 @@ class Tk(Misc, Wm):
"""Toplevel widget of Tk which represents mostly the main window
of an appliation. It has an associated Tcl interpreter."""
_w = '.'
- def __init__(self, screenName=None, baseName=None, className='Tk'):
+ def __init__(self, screenName=None, baseName=None, className='Tk', useTk=1):
"""Return a new Toplevel widget on screen SCREENNAME. A new Tcl interpreter will
be created. BASENAME will be used for the identification of the profile file (see
readprofile).
It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME
is the name of the widget class."""
- global _default_root
self.master = None
self.children = {}
+ self._tkloaded = 0
+ # to avoid recursions in the getattr code in case of failure, we
+ # ensure that self.tk is always _something_.
+ self.tk = None
if baseName is None:
import sys, os
baseName = os.path.basename(sys.argv[0])
baseName, ext = os.path.splitext(baseName)
if ext not in ('.py', '.pyc', '.pyo'):
baseName = baseName + ext
- self.tk = _tkinter.create(screenName, baseName, className)
- self.tk.wantobjects(wantobjects)
+ interactive = 0
+ self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk)
+ if useTk:
+ self._loadtk()
+ self.readprofile(baseName, className)
+ def loadtk(self):
+ if not self._tkloaded:
+ self.tk.loadtk()
+ self._loadtk()
+ def _loadtk(self):
+ self._tkloaded = 1
+ global _default_root
if _MacOS and hasattr(_MacOS, 'SchedParams'):
# Disable event scanning except for Command-Period
_MacOS.SchedParams(1, 0)
@@ -1587,7 +1600,6 @@ class Tk(Misc, Wm):
% str(TkVersion)
self.tk.createcommand('tkerror', _tkerror)
self.tk.createcommand('exit', _exit)
- self.readprofile(baseName, className)
if _support_default_root and not _default_root:
_default_root = self
self.protocol("WM_DELETE_WINDOW", self.destroy)
@@ -1629,6 +1641,15 @@ class Tk(Misc, Wm):
sys.last_value = val
sys.last_traceback = tb
traceback.print_exception(exc, val, tb)
+ def __getattr__(self, attr):
+ "Delegate attribute access to the interpreter object"
+ return getattr(self.tk, attr)
+ def __hasattr__(self, attr):
+ "Delegate attribute access to the interpreter object"
+ return hasattr(self.tk, attr)
+ def __delattr__(self, attr):
+ "Delegate attribute access to the interpreter object"
+ return delattr(self.tk, attr)
# Ideally, the classes Pack, Place and Grid disappear, the
# pack/place/grid methods are defined on the Widget class, and
@@ -1644,6 +1665,10 @@ class Tk(Misc, Wm):
# toplevel and interior widgets). Again, for compatibility, these are
# copied into the Pack, Place or Grid class.
+
+def Tcl(screenName=None, baseName=None, className='Tk', useTk=0):
+ return Tk(screenName, baseName, className, useTk)
+
class Pack:
"""Geometry manager Pack.
diff --git a/Lib/test/test_tcl.py b/Lib/test/test_tcl.py
new file mode 100644
index 0000000..3e0a781
--- /dev/null
+++ b/Lib/test/test_tcl.py
@@ -0,0 +1,159 @@
+#!/usr/bin/env python
+
+import unittest
+import os
+from Tkinter import Tcl
+from _tkinter import TclError
+
+class TclTest(unittest.TestCase):
+
+ def setUp(self):
+ self.interp = Tcl()
+
+ def testEval(self):
+ tcl = self.interp
+ tcl.eval('set a 1')
+ self.assertEqual(tcl.eval('set a'),'1')
+
+ def testEvalException(self):
+ tcl = self.interp
+ self.assertRaises(TclError,tcl.eval,'set a')
+
+ def testEvalException2(self):
+ tcl = self.interp
+ self.assertRaises(TclError,tcl.eval,'this is wrong')
+
+ def testCall(self):
+ tcl = self.interp
+ tcl.call('set','a','1')
+ self.assertEqual(tcl.call('set','a'),'1')
+
+ def testCallException(self):
+ tcl = self.interp
+ self.assertRaises(TclError,tcl.call,'set','a')
+
+ def testCallException2(self):
+ tcl = self.interp
+ self.assertRaises(TclError,tcl.call,'this','is','wrong')
+
+ def testSetVar(self):
+ tcl = self.interp
+ tcl.setvar('a','1')
+ self.assertEqual(tcl.eval('set a'),'1')
+
+ def testSetVarArray(self):
+ tcl = self.interp
+ tcl.setvar('a(1)','1')
+ self.assertEqual(tcl.eval('set a(1)'),'1')
+
+ def testGetVar(self):
+ tcl = self.interp
+ tcl.eval('set a 1')
+ self.assertEqual(tcl.getvar('a'),'1')
+
+ def testGetVarArray(self):
+ tcl = self.interp
+ tcl.eval('set a(1) 1')
+ self.assertEqual(tcl.getvar('a(1)'),'1')
+
+ def testGetVarException(self):
+ tcl = self.interp
+ self.assertRaises(TclError,tcl.getvar,'a')
+
+ def testGetVarArrayException(self):
+ tcl = self.interp
+ self.assertRaises(TclError,tcl.getvar,'a(1)')
+
+ def testUnsetVar(self):
+ tcl = self.interp
+ tcl.setvar('a',1)
+ self.assertEqual(tcl.eval('info exists a'),'1')
+ tcl.unsetvar('a')
+ self.assertEqual(tcl.eval('info exists a'),'0')
+
+ def testUnsetVarArray(self):
+ tcl = self.interp
+ tcl.setvar('a(1)',1)
+ tcl.setvar('a(2)',2)
+ self.assertEqual(tcl.eval('info exists a(1)'),'1')
+ self.assertEqual(tcl.eval('info exists a(2)'),'1')
+ tcl.unsetvar('a(1)')
+ self.assertEqual(tcl.eval('info exists a(1)'),'0')
+ self.assertEqual(tcl.eval('info exists a(2)'),'1')
+
+ def testUnsetVarException(self):
+ tcl = self.interp
+ self.assertRaises(TclError,tcl.unsetvar,'a')
+
+ def testEvalFile(self):
+ tcl = self.interp
+ filename = "testEvalFile.tcl"
+ fd = open(filename,'w')
+ script = """set a 1
+ set b 2
+ set c [ expr $a + $b ]
+ """
+ fd.write(script)
+ fd.close()
+ tcl.evalfile(filename)
+ self.assertEqual(tcl.eval('set a'),'1')
+ self.assertEqual(tcl.eval('set b'),'2')
+ self.assertEqual(tcl.eval('set c'),'3')
+
+ def testEvalFileException(self):
+ tcl = self.interp
+ filename = "doesnotexists"
+ try:
+ os.remove(filename)
+ except Exception,e:
+ pass
+ self.assertRaises(TclError,tcl.evalfile,filename)
+
+ def testPackageRequire(self):
+ tcl = self.interp
+ tcl.eval('package require Tclx')
+ tcl.eval('keylset a b.c 1')
+ self.assertEqual(tcl.eval('keylget a b.c'),'1')
+
+ def testPackageRequireException(self):
+ tcl = self.interp
+ self.assertRaises(TclError,tcl.eval,'package require DNE')
+
+ def testLoadTk(self):
+ import os
+ if 'DISPLAY' not in os.environ:
+ # skipping test of clean upgradeability
+ return
+ tcl = Tcl()
+ self.assertRaises(TclError,tcl.winfo_geometry)
+ tcl.loadtk()
+ self.assertEqual('1x1+0+0', tcl.winfo_geometry())
+
+ def testLoadTkFailure(self):
+ import os
+ old_display = None
+ import sys
+ if sys.platform.startswith('win'):
+ return # no failure possible on windows?
+ if 'DISPLAY' in os.environ:
+ old_display = os.environ['DISPLAY']
+ del os.environ['DISPLAY']
+ # on some platforms, deleting environment variables
+ # doesn't actually carry through to the process level
+ # because they don't support unsetenv
+ # If that's the case, abort.
+ display = os.popen('echo $DISPLAY').read().strip()
+ if display:
+ return
+ try:
+ tcl = Tcl()
+ self.assertRaises(TclError, tcl.winfo_geometry)
+ self.assertRaises(TclError, tcl.loadtk)
+ finally:
+ if old_display is not None:
+ os.environ['DISPLAY'] = old_display
+
+if __name__ == "__main__":
+ unittest.main()
+
+