Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 80a1803

Browse files
Issue #6639: Module-level turtle functions no longer raise TclError after
closing the window.
1 parent a3369a5 commit 80a1803

3 files changed

Lines changed: 40 additions & 34 deletions

File tree

Lib/turtle.py

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,7 +1288,7 @@ def delay(self, delay=None):
12881288
def _incrementudc(self):
12891289
"""Increment update counter."""
12901290
if not TurtleScreen._RUNNING:
1291-
TurtleScreen._RUNNNING = True
1291+
TurtleScreen._RUNNING = True
12921292
raise Terminator
12931293
if self._tracing > 0:
12941294
self._updatecounter += 1
@@ -3754,7 +3754,7 @@ def _destroy(self):
37543754
Turtle._screen = None
37553755
_Screen._root = None
37563756
_Screen._canvas = None
3757-
TurtleScreen._RUNNING = True
3757+
TurtleScreen._RUNNING = False
37583758
root.destroy()
37593759

37603760
def bye(self):
@@ -3795,7 +3795,6 @@ def exitGracefully(x, y):
37953795
except AttributeError:
37963796
exit(0)
37973797

3798-
37993798
class Turtle(RawTurtle):
38003799
"""RawTurtle auto-creating (scrolled) canvas.
38013800
@@ -3818,18 +3817,6 @@ def __init__(self,
38183817

38193818
Pen = Turtle
38203819

3821-
def _getpen():
3822-
"""Create the 'anonymous' turtle if not already present."""
3823-
if Turtle._pen is None:
3824-
Turtle._pen = Turtle()
3825-
return Turtle._pen
3826-
3827-
def _getscreen():
3828-
"""Create a TurtleScreen if not already present."""
3829-
if Turtle._screen is None:
3830-
Turtle._screen = Screen()
3831-
return Turtle._screen
3832-
38333820
def write_docstringdict(filename="turtle_docstringdict"):
38343821
"""Create and write docstring-dictionary to file.
38353822
@@ -3952,26 +3939,38 @@ def _screen_docrevise(docstr):
39523939
## as functions. So we can enhance, change, add, delete methods to these
39533940
## classes and do not need to change anything here.
39543941

3942+
__func_body = """\
3943+
def {name}{paramslist}:
3944+
if {obj} is None:
3945+
if not TurtleScreen._RUNNING:
3946+
TurtleScreen._RUNNING = True
3947+
raise Terminator
3948+
{obj} = {init}
3949+
try:
3950+
return {obj}.{name}{argslist}
3951+
except TK.TclError:
3952+
if not TurtleScreen._RUNNING:
3953+
TurtleScreen._RUNNING = True
3954+
raise Terminator
3955+
raise
3956+
"""
39553957

3956-
for methodname in _tg_screen_functions:
3957-
pl1, pl2 = getmethparlist(eval('_Screen.' + methodname))
3958-
if pl1 == "":
3959-
print(">>>>>>", pl1, pl2)
3960-
continue
3961-
defstr = ("def %(key)s%(pl1)s: return _getscreen().%(key)s%(pl2)s" %
3962-
{'key':methodname, 'pl1':pl1, 'pl2':pl2})
3963-
exec(defstr)
3964-
eval(methodname).__doc__ = _screen_docrevise(eval('_Screen.'+methodname).__doc__)
3965-
3966-
for methodname in _tg_turtle_functions:
3967-
pl1, pl2 = getmethparlist(eval('Turtle.' + methodname))
3968-
if pl1 == "":
3969-
print(">>>>>>", pl1, pl2)
3970-
continue
3971-
defstr = ("def %(key)s%(pl1)s: return _getpen().%(key)s%(pl2)s" %
3972-
{'key':methodname, 'pl1':pl1, 'pl2':pl2})
3973-
exec(defstr)
3974-
eval(methodname).__doc__ = _turtle_docrevise(eval('Turtle.'+methodname).__doc__)
3958+
def _make_global_funcs(functions, cls, obj, init, docrevise):
3959+
for methodname in functions:
3960+
method = getattr(cls, methodname)
3961+
pl1, pl2 = getmethparlist(method)
3962+
if pl1 == "":
3963+
print(">>>>>>", pl1, pl2)
3964+
continue
3965+
defstr = __func_body.format(obj=obj, init=init, name=methodname,
3966+
paramslist=pl1, argslist=pl2)
3967+
exec(defstr, globals())
3968+
globals()[methodname].__doc__ = docrevise(method.__doc__)
3969+
3970+
_make_global_funcs(_tg_screen_functions, _Screen,
3971+
'Turtle._screen', 'Screen()', _screen_docrevise)
3972+
_make_global_funcs(_tg_turtle_functions, Turtle,
3973+
'Turtle._pen', 'Turtle()', _turtle_docrevise)
39753974

39763975

39773976
done = mainloop

Lib/turtledemo/__main__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,8 @@ def startDemo(self):
344344
else:
345345
self.state = DONE
346346
except turtle.Terminator:
347+
if self.root is None:
348+
return
347349
self.state = DONE
348350
result = "stopped!"
349351
if self.state == DONE:
@@ -369,7 +371,9 @@ def stopIt(self):
369371
turtle.TurtleScreen._RUNNING = False
370372

371373
def _destroy(self):
374+
turtle.TurtleScreen._RUNNING = False
372375
self.root.destroy()
376+
self.root = None
373377

374378

375379
def main():

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ Core and Builtins
1313
Library
1414
-------
1515

16+
- Issue #6639: Module-level turtle functions no longer raise TclError after
17+
closing the window.
18+
1619
- Issues #814253, #9179: Warnings now are raised when group references and
1720
conditional group references are used in lookbehind assertions in regular
1821
expressions.

0 commit comments

Comments
 (0)