[Python-checkins] cpython (3.4): Issue #6639: Module-level turtle functions no longer raise TclError after

serhiy.storchaka python-checkins at python.org
Sun Feb 22 16:28:05 CET 2015


https://hg.python.org/cpython/rev/1628484c9408
changeset:   94723:1628484c9408
branch:      3.4
parent:      94716:e295ad9be16d
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Sun Feb 22 17:25:33 2015 +0200
summary:
  Issue #6639: Module-level turtle functions no longer raise TclError after
closing the window.

files:
  Lib/turtle.py              |  69 ++++++++++++-------------
  Lib/turtledemo/__main__.py |   4 +
  Misc/NEWS                  |   3 +
  3 files changed, 41 insertions(+), 35 deletions(-)


diff --git a/Lib/turtle.py b/Lib/turtle.py
--- a/Lib/turtle.py
+++ b/Lib/turtle.py
@@ -1288,7 +1288,7 @@
     def _incrementudc(self):
         """Increment update counter."""
         if not TurtleScreen._RUNNING:
-            TurtleScreen._RUNNNING = True
+            TurtleScreen._RUNNING = True
             raise Terminator
         if self._tracing > 0:
             self._updatecounter += 1
@@ -3754,7 +3754,7 @@
             Turtle._screen = None
             _Screen._root = None
             _Screen._canvas = None
-        TurtleScreen._RUNNING = True
+        TurtleScreen._RUNNING = False
         root.destroy()
 
     def bye(self):
@@ -3795,7 +3795,6 @@
         except AttributeError:
             exit(0)
 
-
 class Turtle(RawTurtle):
     """RawTurtle auto-creating (scrolled) canvas.
 
@@ -3818,18 +3817,6 @@
 
 Pen = Turtle
 
-def _getpen():
-    """Create the 'anonymous' turtle if not already present."""
-    if Turtle._pen is None:
-        Turtle._pen = Turtle()
-    return Turtle._pen
-
-def _getscreen():
-    """Create a TurtleScreen if not already present."""
-    if Turtle._screen is None:
-        Turtle._screen = Screen()
-    return Turtle._screen
-
 def write_docstringdict(filename="turtle_docstringdict"):
     """Create and write docstring-dictionary to file.
 
@@ -3952,26 +3939,38 @@
 ## as functions. So we can enhance, change, add, delete methods to these
 ## classes and do not need to change anything here.
 
-
-for methodname in _tg_screen_functions:
-    pl1, pl2 = getmethparlist(eval('_Screen.' + methodname))
-    if pl1 == "":
-        print(">>>>>>", pl1, pl2)
-        continue
-    defstr = ("def %(key)s%(pl1)s: return _getscreen().%(key)s%(pl2)s" %
-                                   {'key':methodname, 'pl1':pl1, 'pl2':pl2})
-    exec(defstr)
-    eval(methodname).__doc__ = _screen_docrevise(eval('_Screen.'+methodname).__doc__)
-
-for methodname in _tg_turtle_functions:
-    pl1, pl2 = getmethparlist(eval('Turtle.' + methodname))
-    if pl1 == "":
-        print(">>>>>>", pl1, pl2)
-        continue
-    defstr = ("def %(key)s%(pl1)s: return _getpen().%(key)s%(pl2)s" %
-                                   {'key':methodname, 'pl1':pl1, 'pl2':pl2})
-    exec(defstr)
-    eval(methodname).__doc__ = _turtle_docrevise(eval('Turtle.'+methodname).__doc__)
+__func_body = """\
+def {name}{paramslist}:
+    if {obj} is None:
+        if not TurtleScreen._RUNNING:
+            TurtleScreen._RUNNING = True
+            raise Terminator
+        {obj} = {init}
+    try:
+        return {obj}.{name}{argslist}
+    except TK.TclError:
+        if not TurtleScreen._RUNNING:
+            TurtleScreen._RUNNING = True
+            raise Terminator
+        raise
+"""
+
+def _make_global_funcs(functions, cls, obj, init, docrevise):
+    for methodname in functions:
+        method = getattr(cls, methodname)
+        pl1, pl2 = getmethparlist(method)
+        if pl1 == "":
+            print(">>>>>>", pl1, pl2)
+            continue
+        defstr = __func_body.format(obj=obj, init=init, name=methodname,
+                                    paramslist=pl1, argslist=pl2)
+        exec(defstr, globals())
+        globals()[methodname].__doc__ = docrevise(method.__doc__)
+
+_make_global_funcs(_tg_screen_functions, _Screen,
+                   'Turtle._screen', 'Screen()', _screen_docrevise)
+_make_global_funcs(_tg_turtle_functions, Turtle,
+                   'Turtle._pen', 'Turtle()', _turtle_docrevise)
 
 
 done = mainloop
diff --git a/Lib/turtledemo/__main__.py b/Lib/turtledemo/__main__.py
--- a/Lib/turtledemo/__main__.py
+++ b/Lib/turtledemo/__main__.py
@@ -344,6 +344,8 @@
             else:
                 self.state = DONE
         except turtle.Terminator:
+            if self.root is None:
+                return
             self.state = DONE
             result = "stopped!"
         if self.state == DONE:
@@ -369,7 +371,9 @@
         turtle.TurtleScreen._RUNNING = False
 
     def _destroy(self):
+        turtle.TurtleScreen._RUNNING = False
         self.root.destroy()
+        self.root = None
 
 
 def main():
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -13,6 +13,9 @@
 Library
 -------
 
+- Issue #6639: Module-level turtle functions no longer raise TclError after
+  closing the window.
+
 - Issues #814253, #9179: Warnings now are raised when group references and
   conditional group references are used in lookbehind assertions in regular
   expressions.

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list