summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2015-02-22 15:22:53 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2015-02-22 15:22:53 (GMT)
commitcc49aa13818d0b638fbf1aed5dba12c4a6966a84 (patch)
tree780ef69343b389754d0d76fb7be67f17c573b8fc
parentb8285d96f40a635157b0394f7cf9e69d0e6492cf (diff)
downloadcpython-cc49aa13818d0b638fbf1aed5dba12c4a6966a84.zip
cpython-cc49aa13818d0b638fbf1aed5dba12c4a6966a84.tar.gz
cpython-cc49aa13818d0b638fbf1aed5dba12c4a6966a84.tar.bz2
Issue #6639: Module-level turtle functions no longer raise TclError after
closing the window.
-rwxr-xr-xDemo/turtle/turtleDemo.py4
-rw-r--r--Lib/lib-tk/turtle.py66
-rw-r--r--Misc/NEWS3
3 files changed, 39 insertions, 34 deletions
diff --git a/Demo/turtle/turtleDemo.py b/Demo/turtle/turtleDemo.py
index d284042..12b4355 100755
--- a/Demo/turtle/turtleDemo.py
+++ b/Demo/turtle/turtleDemo.py
@@ -231,6 +231,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:
@@ -257,7 +259,9 @@ class DemoWindow(object):
turtle.TurtleScreen._RUNNING = False
def _destroy(self):
+ turtle.TurtleScreen._RUNNING = False
self.root.destroy()
+ self.root = None
#sys.exit()
def main():
diff --git a/Lib/lib-tk/turtle.py b/Lib/lib-tk/turtle.py
index 75673a4..73a7590 100644
--- a/Lib/lib-tk/turtle.py
+++ b/Lib/lib-tk/turtle.py
@@ -1235,7 +1235,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
@@ -3644,7 +3644,7 @@ class _Screen(TurtleScreen):
Turtle._screen = None
_Screen._root = None
_Screen._canvas = None
- TurtleScreen._RUNNING = True
+ TurtleScreen._RUNNING = False
root.destroy()
def bye(self):
@@ -3685,7 +3685,6 @@ class _Screen(TurtleScreen):
except AttributeError:
exit(0)
-
class Turtle(RawTurtle):
"""RawTurtle auto-creating (scrolled) canvas.
@@ -3708,18 +3707,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.
@@ -3847,30 +3834,41 @@ 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__)
+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 in globals()
+ globals()[methodname].__doc__ = docrevise(method.__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__)
+_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 = TK.mainloop
-del pl1, pl2, defstr
if __name__ == "__main__":
def switchpen():
diff --git a/Misc/NEWS b/Misc/NEWS
index 7d8b7b9..b49d5dd 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -116,6 +116,9 @@ Documentation
Tools/Demos
-----------
+- Issue #6639: Module-level turtle functions no longer raise TclError after
+ closing the window.
+
- Issue #22314: pydoc now works when the LINES environment variable is set.
- Issue #18905: "pydoc -p 0" now outputs actually used port. Based on patch by