]> granicus.if.org Git - python/commitdiff
Issue #6639: Module-level turtle functions no longer raise TclError after
authorSerhiy Storchaka <storchaka@gmail.com>
Sun, 22 Feb 2015 15:25:33 +0000 (17:25 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Sun, 22 Feb 2015 15:25:33 +0000 (17:25 +0200)
closing the window.

Lib/turtle.py
Lib/turtledemo/__main__.py
Misc/NEWS

index f4400c90fd7345d3311f1663c704b0efbdb74880..cbd4f47df9de81dd60d60b2b214b11c613d58341 100644 (file)
@@ -1288,7 +1288,7 @@ class TurtleScreen(TurtleScreenBase):
     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 @@ class _Screen(TurtleScreen):
             Turtle._screen = None
             _Screen._root = None
             _Screen._canvas = None
-        TurtleScreen._RUNNING = True
+        TurtleScreen._RUNNING = False
         root.destroy()
 
     def bye(self):
@@ -3795,7 +3795,6 @@ class _Screen(TurtleScreen):
         except AttributeError:
             exit(0)
 
-
 class Turtle(RawTurtle):
     """RawTurtle auto-creating (scrolled) canvas.
 
@@ -3818,18 +3817,6 @@ class Turtle(RawTurtle):
 
 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 @@ def _screen_docrevise(docstr):
 ## as functions. So we can enhance, change, add, delete methods to these
 ## classes and do not need to change anything here.
 
+__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
+"""
 
-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__)
+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
index 6280c8497b61d44fb0c47b27315b57e001d98be7..106d058808993a7580d4fd1c794932dd94d7ae37 100755 (executable)
@@ -344,6 +344,8 @@ class DemoWindow(object):
             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 @@ class DemoWindow(object):
         turtle.TurtleScreen._RUNNING = False
 
     def _destroy(self):
+        turtle.TurtleScreen._RUNNING = False
         self.root.destroy()
+        self.root = None
 
 
 def main():
index 37ff72ea1338bdf418e0abdde23b7d754bc67048..826eab109d565c74cb1e6d3ff5ecb0d63069fbc9 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -13,6 +13,9 @@ Core and Builtins
 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.