Discussion:
[Python-3000-checkins] r66687 - in python/branches/py3k: Demo/turtle/turtleDemo.py Doc/library/turtle.rst Lib/turtle.py Misc/NEWS
martin.v.loewis
2008-09-29 22:19:08 UTC
Permalink
Author: martin.v.loewis
Date: Tue Sep 30 00:19:08 2008
New Revision: 66687

Log:
Merged revisions 66686 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/trunk

........
r66686 | martin.v.loewis | 2008-09-30 00:09:07 +0200 (Di, 30 Sep 2008) | 5 lines

Issue #3965: Allow repeated calls to turtle.Screen, by making it a
true singleton object.

Reviewed by Gregor Lingl.
........


Modified:
python/branches/py3k/ (props changed)
python/branches/py3k/Demo/turtle/turtleDemo.py
python/branches/py3k/Doc/library/turtle.rst
python/branches/py3k/Lib/turtle.py
python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Demo/turtle/turtleDemo.py
==============================================================================
--- python/branches/py3k/Demo/turtle/turtleDemo.py (original)
+++ python/branches/py3k/Demo/turtle/turtleDemo.py Tue Sep 30 00:19:08 2008
@@ -96,8 +96,8 @@
left_frame.pack(side=LEFT, fill=BOTH, expand=0)
self.graph_frame = g_frame = Frame(root)

- turtle.Screen._root = g_frame
- turtle.Screen._canvas = turtle.ScrolledCanvas(g_frame, 800, 600, 1000, 800)
+ turtle._Screen._root = g_frame
+ turtle._Screen._canvas = turtle.ScrolledCanvas(g_frame, 800, 600, 1000, 800)
#xturtle.Screen._canvas.pack(expand=1, fill="both")
self.screen = _s_ = turtle.Screen()
#####

Modified: python/branches/py3k/Doc/library/turtle.rst
==============================================================================
--- python/branches/py3k/Doc/library/turtle.rst (original)
+++ python/branches/py3k/Doc/library/turtle.rst Tue Sep 30 00:19:08 2008
@@ -40,10 +40,10 @@
:class:`ScrolledCanvas` as argument. It should be used when :mod:`turtle` is
used as part of some application.

- Derived from :class:`TurtleScreen` is the subclass :class:`Screen`. Screen
- is implemented as sort of singleton, so there can exist only one instance of
- Screen at a time. It should be used when :mod:`turtle` is used as a
- standalone tool for doing graphics.
+ The function :func:`Screen` returns a singleton object of a
+ :class:`TurtleScreen` subclass. This function should be used when
+ :mod:`turtle` is used as a standalone tool for doing graphics.
+ As a singleton object, inheriting from its class is not possible.

All methods of TurtleScreen/Screen also exist as functions, i.e. as part of
the procedure-oriented interface.

Modified: python/branches/py3k/Lib/turtle.py
==============================================================================
--- python/branches/py3k/Lib/turtle.py (original)
+++ python/branches/py3k/Lib/turtle.py Tue Sep 30 00:19:08 2008
@@ -2421,7 +2421,7 @@
shape=_CFG["shape"],
undobuffersize=_CFG["undobuffersize"],
visible=_CFG["visible"]):
- if isinstance(canvas, Screen):
+ if isinstance(canvas, _Screen):
self.screen = canvas
elif isinstance(canvas, TurtleScreen):
if canvas not in RawTurtle.screens:
@@ -3558,29 +3558,33 @@

RawPen = RawTurtle

-### Screen - Klasse ########################
+### Screen - Singleton ########################

-class Screen(TurtleScreen):
+def Screen():
+ """Return the singleton screen object.
+ If none exists at the moment, create a new one and return it,
+ else return the existing one."""
+ if Turtle._screen is None:
+ Turtle._screen = _Screen()
+ return Turtle._screen
+
+class _Screen(TurtleScreen):

_root = None
_canvas = None
_title = _CFG["title"]

- # Borg-Idiom
-
- _shared_state = {}
-
- def __new__(cls, *args, **kwargs):
- obj = object.__new__(cls, *args, **kwargs)
- obj.__dict__ = cls._shared_state
- return obj
-
def __init__(self):
- if Screen._root is None:
- Screen._root = self._root = _Root()
- self._root.title(Screen._title)
+ # XXX there is no need for this code to be conditional,
+ # as there will be only a single _Screen instance, anyway
+ # XXX actually, the turtle demo is injecting root window,
+ # so perhaps the conditional creation of a root should be
+ # preserved (perhaps by passing it as an optional parameter)
+ if _Screen._root is None:
+ _Screen._root = self._root = _Root()
+ self._root.title(_Screen._title)
self._root.ondestroy(self._destroy)
- if Screen._canvas is None:
+ if _Screen._canvas is None:
width = _CFG["width"]
height = _CFG["height"]
canvwidth = _CFG["canvwidth"]
@@ -3588,10 +3592,9 @@
leftright = _CFG["leftright"]
topbottom = _CFG["topbottom"]
self._root.setupcanvas(width, height, canvwidth, canvheight)
- Screen._canvas = self._root._getcanvas()
+ _Screen._canvas = self._root._getcanvas()
self.setup(width, height, leftright, topbottom)
- TurtleScreen.__init__(self, Screen._canvas)
- Turtle._screen = self
+ TurtleScreen.__init__(self, _Screen._canvas)

def setup(self, width=_CFG["width"], height=_CFG["height"],
startx=_CFG["leftright"], starty=_CFG["topbottom"]):
@@ -3645,17 +3648,17 @@
screen.title("Welcome to the turtle-zoo!")
"""
- if Screen._root is not None:
- Screen._root.title(titlestring)
- Screen._title = titlestring
+ if _Screen._root is not None:
+ _Screen._root.title(titlestring)
+ _Screen._title = titlestring

def _destroy(self):
root = self._root
- if root is Screen._root:
+ if root is _Screen._root:
Turtle._pen = None
Turtle._screen = None
- Screen._root = None
- Screen._canvas = None
+ _Screen._root = None
+ _Screen._canvas = None
TurtleScreen._RUNNING = True
root.destroy()

@@ -3747,7 +3750,7 @@
docsdict = {}

for methodname in _tg_screen_functions:
- key = "Screen."+methodname
+ key = "_Screen."+methodname
docsdict[key] = eval(key).__doc__
for methodname in _tg_turtle_functions:
key = "Turtle."+methodname
@@ -3862,7 +3865,7 @@


for methodname in _tg_screen_functions:
- pl1, pl2 = getmethparlist(eval('Screen.' + methodname))
+ pl1, pl2 = getmethparlist(eval('_Screen.' + methodname))
if pl1 == "":
print(">>>>>>", pl1, pl2)
continue
@@ -3870,7 +3873,7 @@
{'key':methodname, 'pl1':pl1, 'pl2':pl2})
## print("Screen:", defstr)
exec(defstr)
- eval(methodname).__doc__ = _screen_docrevise(eval('Screen.'+methodname).__doc__)
+ eval(methodname).__doc__ = _screen_docrevise(eval('_Screen.'+methodname).__doc__)

for methodname in _tg_turtle_functions:
pl1, pl2 = getmethparlist(eval('Turtle.' + methodname))

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Tue Sep 30 00:19:08 2008
@@ -22,6 +22,9 @@
Library
-------

+- Issue #3965: Allow repeated calls to turtle.Screen, by making it a
+ true singleton object.
+
- Issue #3911: ftplib.FTP.makeport() could give invalid port numbers.

- Issue #3929: When the database cannot be opened, dbm.open() would incorrectly
Loading...