[Python-checkins] r63957 - in python/branches/tlee-ast-optimize: Demo/turtle Doc/library/macos.rst Doc/library/turtle.rst Include/Python.h Include/pymacconfig.h Include/pymactoolbox.h Lib/distutils/sysconfig.py Lib/distutils/unixccompiler.py Lib/distutils/util.py Lib/lib-tk/Tkinter.py Lib/lib-tk/turtle.py Lib/test/test_complex.py Lib/test/test_macos.py Mac/IDLE/Makefile.in Mac/IDLE/idlemain.py Mac/Makefile.in Mac/Modules/ColorPickermodule.c Mac/Modules/MacOS.c Mac/Modules/Nav.c Mac/Modules/OSATerminology.c Mac/Modules/ae/_AEmodule.c Mac/Modules/app/_Appmodule.c Mac/Modules/carbonevt/_CarbonEvtmodule.c Mac/Modules/cg/_CGmodule.c Mac/Modules/cm/_Cmmodule.c Mac/Modules/ctl/_Ctlmodule.c Mac/Modules/dlg/_Dlgmodule.c Mac/Modules/drag/_Dragmodule.c Mac/Modules/evt/_Evtmodule.c Mac/Modules/file/_Filemodule.c Mac/Modules/file/filesupport.py Mac/Modules/fm/_Fmmodule.c Mac/Modules/folder/_Foldermodule.c Mac/Modules/help/_Helpmodule.c Mac/Modules/ibcarbon/_IBCarbon.c Mac/Modules/icn/_Icnmodule.c Mac/Modules/launch/_Launchmodule.c Mac/Modules/list/_Listmodule.c Mac/Modules/menu/_Menumodule.c Mac/Modules/mlte/_Mltemodule.c Mac/Modules/qd/_Qdmodule.c Mac/Modules/qdoffs/_Qdoffsmodule.c Mac/Modules/qt/_Qtmodule.c Mac/Modules/res/_Resmodule.c Mac/Modules/scrap/_Scrapmodule.c Mac/Modules/snd/_Sndmodule.c Mac/Modules/te/_TEmodule.c Mac/Modules/win/_Winmodule.c Makefile.pre.in Misc/ACKS Misc/NEWS Modules/_ctypes/cfield.c Modules/_ctypes/libffi_osx/x86/x86-darwin.S Objects/complexobject.c Python/bltinmodule.c Python/mactoolboxglue.c configure configure.in pyconfig.h.in setup.py
thomas.lee
python-checkins at python.org
Thu Jun 5 17:42:14 CEST 2008
Author: thomas.lee
Date: Thu Jun 5 17:42:10 2008
New Revision: 63957
Log:
Merged revisions 63912-63956 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r63914 | georg.brandl | 2008-06-03 20:23:15 +1000 (Tue, 03 Jun 2008) | 2 lines
Fix Tkinter sequence passing. #2906.
........
r63929 | martin.v.loewis | 2008-06-04 16:29:55 +1000 (Wed, 04 Jun 2008) | 2 lines
Patch #1513695: New turtle module, with demos.
........
r63932 | georg.brandl | 2008-06-04 21:17:26 +1000 (Wed, 04 Jun 2008) | 2 lines
Complete revision of new turtle module's docs.
........
r63942 | thomas.heller | 2008-06-05 04:59:03 +1000 (Thu, 05 Jun 2008) | 42 lines
Issue #1798: Add ctypes calling convention that allows safe access to
errno (and LastError, on Windows).
ctypes maintains a module-global, but thread-local, variable that
contains an error number; called 'ctypes_errno' for this discussion.
This variable is a private copy of the systems 'errno' value; the copy
is swapped with the 'errno' variable on several occasions.
Foreign functions created with CDLL(..., use_errno=True), when called,
swap the values just before the actual function call, and swapped
again immediately afterwards. The 'use_errno' parameter defaults to
False, in this case 'ctypes_errno' is not touched.
The values are also swapped immeditately before and after ctypes
callback functions are called, if the callbacks are constructed using
the new optional use_errno parameter set to True: CFUNCTYPE(..., use_errno=TRUE)
or WINFUNCTYPE(..., use_errno=True).
Two new ctypes functions are provided to access the 'ctypes_errno'
value from Python:
- ctypes.set_errno(value) sets ctypes_errno to 'value', the previous
ctypes_errno value is returned.
- ctypes.get_errno() returns the current ctypes_errno value.
---
On Windows, the same scheme is implemented for the error value which
is managed by the GetLastError() and SetLastError() windows api calls.
The ctypes functions are 'ctypes.set_last_error(value)' and
'ctypes.get_last_error()', the CDLL and WinDLL optional parameter is
named 'use_last_error', defaults to False.
---
On Windows, TlsSetValue and TlsGetValue calls are used to provide
thread local storage for the variables; ctypes compiled with __GNUC__
uses __thread variables.
........
r63943 | thomas.heller | 2008-06-05 05:19:00 +1000 (Thu, 05 Jun 2008) | 1 line
Fix ctypes.set_errno for gcc.
........
r63945 | thomas.heller | 2008-06-05 06:22:05 +1000 (Thu, 05 Jun 2008) | 7 lines
Revert revisions 63943 and 63942 (Issue #1798: Add ctypes calling
convention that allows safe access to errno)
This code does not yet work on OS X (__thread storage specifier not
available), so i needs a configure check plus a more portable
solution.
........
r63948 | alexandre.vassalotti | 2008-06-05 06:41:44 +1000 (Thu, 05 Jun 2008) | 2 lines
Fixed complex.__getnewargs__() to not emit another complex object.
........
r63955 | ronald.oussoren | 2008-06-05 22:58:24 +1000 (Thu, 05 Jun 2008) | 20 lines
MacOS X: Enable 4-way universal builds
This patch adds a new configure argument on OSX:
--with-universal-archs=[32-bit|64-bit|all]
When used with the --enable-universalsdk option this controls which
CPU architectures are includes in the framework. The default is 32-bit,
meaning i386 and ppc. The most useful alternative is 'all', which includes
all 4 CPU architectures supported by MacOS X (i386, ppc, x86_64 and ppc64).
This includes limited support for the Carbon bindings in 64-bit mode as well,
limited because (a) I haven't done extensive testing and (b) a large portion
of the Carbon API's aren't available in 64-bit mode anyway.
I've also duplicated a feature of Apple's build of python: setting the
environment variable 'ARCHFLAGS' controls the '-arch' flags used for building
extensions using distutils.
........
Added:
python/branches/tlee-ast-optimize/Demo/turtle/
- copied from r63955, /python/trunk/Demo/turtle/
python/branches/tlee-ast-optimize/Include/pymacconfig.h
- copied unchanged from r63955, /python/trunk/Include/pymacconfig.h
python/branches/tlee-ast-optimize/Lib/test/test_macos.py
- copied unchanged from r63955, /python/trunk/Lib/test/test_macos.py
Modified:
python/branches/tlee-ast-optimize/ (props changed)
python/branches/tlee-ast-optimize/Doc/library/macos.rst
python/branches/tlee-ast-optimize/Doc/library/turtle.rst
python/branches/tlee-ast-optimize/Include/Python.h
python/branches/tlee-ast-optimize/Include/pymactoolbox.h
python/branches/tlee-ast-optimize/Lib/distutils/sysconfig.py
python/branches/tlee-ast-optimize/Lib/distutils/unixccompiler.py
python/branches/tlee-ast-optimize/Lib/distutils/util.py
python/branches/tlee-ast-optimize/Lib/lib-tk/Tkinter.py
python/branches/tlee-ast-optimize/Lib/lib-tk/turtle.py
python/branches/tlee-ast-optimize/Lib/test/test_complex.py
python/branches/tlee-ast-optimize/Mac/IDLE/Makefile.in
python/branches/tlee-ast-optimize/Mac/IDLE/idlemain.py
python/branches/tlee-ast-optimize/Mac/Makefile.in
python/branches/tlee-ast-optimize/Mac/Modules/ColorPickermodule.c
python/branches/tlee-ast-optimize/Mac/Modules/MacOS.c
python/branches/tlee-ast-optimize/Mac/Modules/Nav.c
python/branches/tlee-ast-optimize/Mac/Modules/OSATerminology.c
python/branches/tlee-ast-optimize/Mac/Modules/ae/_AEmodule.c
python/branches/tlee-ast-optimize/Mac/Modules/app/_Appmodule.c
python/branches/tlee-ast-optimize/Mac/Modules/carbonevt/_CarbonEvtmodule.c
python/branches/tlee-ast-optimize/Mac/Modules/cg/_CGmodule.c
python/branches/tlee-ast-optimize/Mac/Modules/cm/_Cmmodule.c
python/branches/tlee-ast-optimize/Mac/Modules/ctl/_Ctlmodule.c
python/branches/tlee-ast-optimize/Mac/Modules/dlg/_Dlgmodule.c
python/branches/tlee-ast-optimize/Mac/Modules/drag/_Dragmodule.c
python/branches/tlee-ast-optimize/Mac/Modules/evt/_Evtmodule.c
python/branches/tlee-ast-optimize/Mac/Modules/file/_Filemodule.c
python/branches/tlee-ast-optimize/Mac/Modules/file/filesupport.py
python/branches/tlee-ast-optimize/Mac/Modules/fm/_Fmmodule.c
python/branches/tlee-ast-optimize/Mac/Modules/folder/_Foldermodule.c
python/branches/tlee-ast-optimize/Mac/Modules/help/_Helpmodule.c
python/branches/tlee-ast-optimize/Mac/Modules/ibcarbon/_IBCarbon.c
python/branches/tlee-ast-optimize/Mac/Modules/icn/_Icnmodule.c
python/branches/tlee-ast-optimize/Mac/Modules/launch/_Launchmodule.c
python/branches/tlee-ast-optimize/Mac/Modules/list/_Listmodule.c
python/branches/tlee-ast-optimize/Mac/Modules/menu/_Menumodule.c
python/branches/tlee-ast-optimize/Mac/Modules/mlte/_Mltemodule.c
python/branches/tlee-ast-optimize/Mac/Modules/qd/_Qdmodule.c
python/branches/tlee-ast-optimize/Mac/Modules/qdoffs/_Qdoffsmodule.c
python/branches/tlee-ast-optimize/Mac/Modules/qt/_Qtmodule.c
python/branches/tlee-ast-optimize/Mac/Modules/res/_Resmodule.c
python/branches/tlee-ast-optimize/Mac/Modules/scrap/_Scrapmodule.c
python/branches/tlee-ast-optimize/Mac/Modules/snd/_Sndmodule.c
python/branches/tlee-ast-optimize/Mac/Modules/te/_TEmodule.c
python/branches/tlee-ast-optimize/Mac/Modules/win/_Winmodule.c
python/branches/tlee-ast-optimize/Makefile.pre.in
python/branches/tlee-ast-optimize/Misc/ACKS
python/branches/tlee-ast-optimize/Misc/NEWS
python/branches/tlee-ast-optimize/Modules/_ctypes/cfield.c
python/branches/tlee-ast-optimize/Modules/_ctypes/libffi_osx/x86/x86-darwin.S
python/branches/tlee-ast-optimize/Objects/complexobject.c
python/branches/tlee-ast-optimize/Python/bltinmodule.c
python/branches/tlee-ast-optimize/Python/mactoolboxglue.c
python/branches/tlee-ast-optimize/configure
python/branches/tlee-ast-optimize/configure.in
python/branches/tlee-ast-optimize/pyconfig.h.in
python/branches/tlee-ast-optimize/setup.py
Modified: python/branches/tlee-ast-optimize/Doc/library/macos.rst
==============================================================================
--- python/branches/tlee-ast-optimize/Doc/library/macos.rst (original)
+++ python/branches/tlee-ast-optimize/Doc/library/macos.rst Thu Jun 5 17:42:10 2008
@@ -58,11 +58,19 @@
elaborate functionality was available), but it provides a convenient location to
attach a breakpoint in a low-level debugger like :program:`gdb`.
+ .. note::
+
+ Not available in 64-bit mode.
+
.. function:: SysBeep()
Ring the bell.
+ .. note::
+
+ Not available in 64-bit mode.
+
.. function:: GetTicks()
@@ -74,6 +82,10 @@
Return the file creator and file type as two four-character strings. The *file*
parameter can be a pathname or an ``FSSpec`` or ``FSRef`` object.
+ .. note::
+
+ It is not possible to use an ``FSSpec`` in 64-bit mode.
+
.. function:: SetCreatorAndType(file, creator, type)
@@ -81,6 +93,9 @@
``FSSpec`` or ``FSRef`` object. *creator* and *type* must be four character
strings.
+ .. note::
+
+ It is not possible to use an ``FSSpec`` in 64-bit mode.
.. function:: openrf(name [, mode])
@@ -98,3 +113,12 @@
from an application bundle either when it has been started with
:program:`pythonw` instead of :program:`python` or when running as an applet.
+.. function:: splash([resourceid])
+
+ Opens a splash screen by resource id. Use resourceid ``0`` to close
+ the splash screen.
+
+ .. note::
+
+ Not available in 64-bit mode.
+
Modified: python/branches/tlee-ast-optimize/Doc/library/turtle.rst
==============================================================================
--- python/branches/tlee-ast-optimize/Doc/library/turtle.rst (original)
+++ python/branches/tlee-ast-optimize/Doc/library/turtle.rst Thu Jun 5 17:42:10 2008
@@ -1,312 +1,1888 @@
-
+========================================
:mod:`turtle` --- Turtle graphics for Tk
========================================
-.. module:: turtle
- :platform: Tk
- :synopsis: An environment for turtle graphics.
-.. moduleauthor:: Guido van Rossum <guido at python.org>
+Introduction
+============
+Turtle graphics is a popular way for introducing programming to kids. It was
+part of the original Logo programming language developed by Wally Feurzig and
+Seymour Papert in 1966.
+
+Imagine a robotic turtle starting at (0, 0) in the x-y plane. Give it the
+command ``turtle.forward(15)``, and it moves (on-screen!) 15 pixels in the
+direction it is facing, drawing a line as it moves. Give it the command
+``turtle.left(25)``, and it rotates in-place 25 degrees clockwise.
+
+By combining together these and similar commands, intricate shapes and pictures
+can easily be drawn.
+
+The :mod:`turtle` module is an extended reimplementation of the same-named
+module from the Python standard distribution up to version Python 2.5.
+
+It tries to keep the merits of the old turtle module and to be (nearly) 100%
+compatible with it. This means in the first place to enable the learning
+programmer to use all the commands, classes and methods interactively when using
+the module from within IDLE run with the ``-n`` switch.
+
+The turtle module provides turtle graphics primitives, in both object-oriented
+and procedure-oriented ways. Because it uses :mod:`Tkinter` for the underlying
+graphics, it needs a version of python installed with Tk support.
+
+The object-oriented interface uses essentially two+two classes:
+
+1. The :class:`TurtleScreen` class defines graphics windows as a playground for
+ the drawing turtles. Its constructor needs a :class:`Tkinter.Canvas` or a
+ :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.
+
+ All methods of TurtleScreen/Screen also exist as functions, i.e. as part of
+ the procedure-oriented interface.
+
+2. :class:`RawTurtle` (alias: :class:`RawPen`) defines Turtle objects which draw
+ on a :class:`TurtleScreen`. Its constructor needs a Canvas, ScrolledCanvas
+ or TurtleScreen as argument, so the RawTurtle objects know where to draw.
+
+ Derived from RawTurtle is the subclass :class:`Turtle` (alias: :class:`Pen`),
+ which draws on "the" :class:`Screen` - instance which is automatically
+ created, if not already present.
+
+ All methods of RawTurtle/Turtle also exist as functions, i.e. part of the
+ procedure-oriented interface.
+
+The procedural interface provides functions which are derived from the methods
+of the classes :class:`Screen` and :class:`Turtle`. They have the same names as
+the corresponding methods. A screen object is automativally created whenever a
+function derived from a Screen method is called. An (unnamed) turtle object is
+automatically created whenever any of the functions derived from a Turtle method
+is called.
+
+To use multiple turtles an a screen one has to use the object-oriented interface.
+
+.. note::
+ In the following documentation the argument list for functions is given.
+ Methods, of course, have the additional first argument *self* which is
+ omitted here.
+
+
+Overview over available Turtle and Screen methods
+=================================================
+
+Turtle methods
+--------------
+
+Turtle motion
+ Move and draw
+ | :func:`forward` | :func:`fd`
+ | :func:`backward` | :func:`bk` | :func:`back`
+ | :func:`right` | :func:`rt`
+ | :func:`left` | :func:`lt`
+ | :func:`goto` | :func:`setpos` | :func:`setposition`
+ | :func:`setx`
+ | :func:`sety`
+ | :func:`setheading` | :func:`seth`
+ | :func:`home`
+ | :func:`circle`
+ | :func:`dot`
+ | :func:`stamp`
+ | :func:`clearstamp`
+ | :func:`clearstamps`
+ | :func:`undo`
+ | :func:`speed`
+
+ Tell Turtle's state
+ | :func:`position` | :func:`pos`
+ | :func:`towards`
+ | :func:`xcor`
+ | :func:`ycor`
+ | :func:`heading`
+ | :func:`distance`
+
+ Setting and measurement
+ | :func:`degrees`
+ | :func:`radians`
+
+Pen control
+ Drawing state
+ | :func:`pendown` | :func:`pd` | :func:`down`
+ | :func:`penup` | :func:`pu` | :func:`up`
+ | :func:`pensize` | :func:`width`
+ | :func:`pen`
+ | :func:`isdown`
+
+ Color control
+ | :func:`color`
+ | :func:`pencolor`
+ | :func:`fillcolor`
+
+ Filling
+ | :func:`fill`
+ | :func:`begin_fill`
+ | :func:`end_fill`
+
+ More drawing control
+ | :func:`reset`
+ | :func:`clear`
+ | :func:`write`
+
+Turtle state
+ Visibility
+ | :func:`showturtle` | :func:`st`
+ | :func:`hideturtle` | :func:`ht`
+ | :func:`isvisible`
+
+ Appearance
+ | :func:`shape`
+ | :func:`resizemode`
+ | :func:`shapesize` | :func:`turtlesize`
+ | :func:`settiltangle`
+ | :func:`tiltangle`
+ | :func:`tilt`
+
+Using events
+ | :func:`onclick`
+ | :func:`onrelease`
+ | :func:`ondrag`
+
+Special Turtle methods
+ | :func:`begin_poly`
+ | :func:`end_poly`
+ | :func:`get_poly`
+ | :func:`clone`
+ | :func:`getturtle` | :func:`getpen`
+ | :func:`getscreen`
+ | :func:`setundobuffer`
+ | :func:`undobufferentries`
+ | :func:`tracer`
+ | :func:`window_width`
+ | :func:`window_height`
-.. sectionauthor:: Moshe Zadka <moshez at zadka.site.co.il>
+Methods of TurtleScreen/Screen
+------------------------------
-The :mod:`turtle` module provides turtle graphics primitives, in both an
-object-oriented and procedure-oriented ways. Because it uses :mod:`Tkinter` for
-the underlying graphics, it needs a version of python installed with Tk support.
+Window control
+ | :func:`bgcolor`
+ | :func:`bgpic`
+ | :func:`clear` | :func:`clearscreen`
+ | :func:`reset` | :func:`resetscreen`
+ | :func:`screensize`
+ | :func:`setworldcoordinates`
+
+Animation control
+ | :func:`delay`
+ | :func:`tracer`
+ | :func:`update`
+
+Using screen events
+ | :func:`listen`
+ | :func:`onkey`
+ | :func:`onclick` | :func:`onscreenclick`
+ | :func:`ontimer`
+
+Settings and special methods
+ | :func:`mode`
+ | :func:`colormode`
+ | :func:`getcanvas`
+ | :func:`getshapes`
+ | :func:`register_shape` | :func:`addshape`
+ | :func:`turtles`
+ | :func:`window_height`
+ | :func:`window_width`
+
+Methods specific to Screen
+ | :func:`bye`
+ | :func:`exitonclick`
+ | :func:`setup`
+ | :func:`title`
-The procedural interface uses a pen and a canvas which are automagically created
-when any of the functions are called.
-The :mod:`turtle` module defines the following functions:
+Methods of RawTurtle/Turtle and corresponding functions
+=======================================================
+Most of the examples in this section refer to a Turtle instance called
+``turtle``.
-.. function:: degrees()
+Turtle motion
+-------------
- Set angle measurement units to degrees.
+.. function:: forward(distance)
+ fd(distance)
+ :param distance: a number (integer or float)
-.. function:: radians()
+ Move the turtle forward by the specified *distance*, in the direction the
+ turtle is headed.
- Set angle measurement units to radians.
+ >>> turtle.position()
+ (0.00, 0.00)
+ >>> turtle.forward(25)
+ >>> turtle.position()
+ (25.00,0.00)
+ >>> turtle.forward(-75)
+ >>> turtle.position()
+ (-50.00,0.00)
-.. function:: setup(**kwargs)
+.. function:: back(distance)
+ bk(distance)
+ backward(distance)
- Sets the size and position of the main window. Keywords are:
+ :param distance: a number
- * ``width``: either a size in pixels or a fraction of the screen. The default is
- 50% of the screen.
+ Move the turtle backward by *distance*, opposite to the direction the
+ turtle is headed. Do not change the turtle's heading.
- * ``height``: either a size in pixels or a fraction of the screen. The default
- is 50% of the screen.
+ >>> turtle.position()
+ (0.00, 0.00)
+ >>> turtle.backward(30)
+ >>> turtle.position()
+ (-30.00, 0.00)
- * ``startx``: starting position in pixels from the left edge of the screen.
- ``None`` is the default value and centers the window horizontally on screen.
- * ``starty``: starting position in pixels from the top edge of the screen.
- ``None`` is the default value and centers the window vertically on screen.
+.. function:: right(angle)
+ rt(angle)
- Examples::
+ :param angle: a number (integer or float)
- # Uses default geometry: 50% x 50% of screen, centered.
- setup()
+ Turn turtle right by *angle* units. (Units are by default degrees, but
+ can be set via the :func:`degrees` and :func:`radians` functions.) Angle
+ orientation depends on the turtle mode, see :func:`mode`.
+
+ >>> turtle.heading()
+ 22.0
+ >>> turtle.right(45)
+ >>> turtle.heading()
+ 337.0
- # Sets window to 200x200 pixels, in upper left of screen
- setup (width=200, height=200, startx=0, starty=0)
- # Sets window to 75% of screen by 50% of screen, and centers it.
- setup(width=.75, height=0.5, startx=None, starty=None)
+.. function:: left(angle)
+ lt(angle)
+ :param angle: a number (integer or float)
-.. function:: title(title_str)
+ Turn turtle left by *angle* units. (Units are by default degrees, but
+ can be set via the :func:`degrees` and :func:`radians` functions.) Angle
+ orientation depends on the turtle mode, see :func:`mode`.
+
+ >>> turtle.heading()
+ 22.0
+ >>> turtle.left(45)
+ >>> turtle.heading()
+ 67.0
+
+.. function:: goto(x, y=None)
+ setpos(x, y=None)
+ setposition(x, y=None)
+
+ :param x: a number or a pair/vector of numbers
+ :param y: a number or ``None``
+
+ If *y* is ``None``, *x* must be a pair of coordinates or a :class:`Vec2D`
+ (e.g. as returned by :func:`pos`).
+
+ Move turtle to an absolute position. If the pen is down, draw line. Do
+ not change the turtle's orientation.
+
+ >>> tp = turtle.pos()
+ >>> tp
+ (0.00, 0.00)
+ >>> turtle.setpos(60,30)
+ >>> turtle.pos()
+ (60.00,30.00)
+ >>> turtle.setpos((20,80))
+ >>> turtle.pos()
+ (20.00,80.00)
+ >>> turtle.setpos(tp)
+ >>> turtle.pos()
+ (0.00,0.00)
- Set the window's title to *title*.
+.. function:: setx(x)
-.. function:: done()
+ :param x: a number (integer or float)
- Enters the Tk main loop. The window will continue to be displayed until the
- user closes it or the process is killed.
+ Set the turtle's first coordinate to *x*, leave second coordinate
+ unchanged.
+ >>> turtle.position()
+ (0.00, 240.00)
+ >>> turtle.setx(10)
+ >>> turtle.position()
+ (10.00, 240.00)
-.. function:: reset()
- Clear the screen, re-center the pen, and set variables to the default values.
+.. function:: sety(y)
+ :param y: a number (integer or float)
-.. function:: clear()
+ Set the turtle's first coordinate to *y*, leave second coordinate
+ unchanged.
- Clear the screen.
+ >>> turtle.position()
+ (0.00, 40.00)
+ >>> turtle.sety(-10)
+ >>> turtle.position()
+ (0.00, -10.00)
-.. function:: tracer(flag)
+.. function:: setheading(to_angle)
+ seth(to_angle)
- Set tracing on/off (according to whether flag is true or not). Tracing means
- line are drawn more slowly, with an animation of an arrow along the line.
+ :param to_angle: a number (integer or float)
+ Set the orientation of the turtle to *to_angle*. Here are some common
+ directions in degrees:
-.. function:: speed(speed)
+ =================== ====================
+ standard mode logo mode
+ =================== ====================
+ 0 - east 0 - north
+ 90 - north 90 - east
+ 180 - west 180 - south
+ 270 - south 270 - west
+ =================== ====================
- Set the speed of the turtle. Valid values for the parameter *speed* are
- ``'fastest'`` (no delay), ``'fast'``, (delay 5ms), ``'normal'`` (delay 10ms),
- ``'slow'`` (delay 15ms), and ``'slowest'`` (delay 20ms).
+ >>> turtle.setheading(90)
+ >>> turtle.heading()
+ 90
- .. versionadded:: 2.5
+.. function:: home()
-.. function:: delay(delay)
+ Move turtle to the origin -- coordinates (0,0) -- and set its heading to
+ its start-orientation (which depends on the mode, see :func:`mode`).
- Set the speed of the turtle to *delay*, which is given in ms.
- .. versionadded:: 2.5
+.. function:: circle(radius, extent=None, steps=None)
+ :param radius: a number
+ :param extent: a number (or ``None``)
+ :param steps: an integer (or ``None``)
-.. function:: forward(distance)
+ Draw a circle with given *radius*. The center is *radius* units left of
+ the turtle; *extent* -- an angle -- determines which part of the circle
+ is drawn. If *extent* is not given, draw the entire circle. If *extent*
+ is not a full circle, one endpoint of the arc is the current pen
+ position. Draw the arc in counterclockwise direction if *radius* is
+ positive, otherwise in clockwise direction. Finally the direction of the
+ turtle is changed by the amount of *extent*.
- Go forward *distance* steps.
+ As the circle is approximated by an inscribed regular polygon, *steps*
+ determines the number of steps to use. If not given, it will be
+ calculated automatically. May be used to draw regular polygons.
+ >>> turtle.circle(50)
+ >>> turtle.circle(120, 180) # draw a semicircle
-.. function:: backward(distance)
- Go backward *distance* steps.
+.. function:: dot(size=None, *color)
+ :param size: an integer >= 1 (if given)
+ :param color: a colorstring or a numeric color tuple
-.. function:: left(angle)
+ Draw a circular dot with diameter *size*, using *color*. If *size* is
+ not given, the maximum of pensize+4 and 2*pensize is used.
- Turn left *angle* units. Units are by default degrees, but can be set via the
- :func:`degrees` and :func:`radians` functions.
+ >>> turtle.dot()
+ >>> turtle.fd(50); turtle.dot(20, "blue"); turtle.fd(50)
-.. function:: right(angle)
+.. function:: stamp()
+
+ Stamp a copy of the turtle shape onto the canvas at the current turtle
+ position. Return a stamp_id for that stamp, which can be used to delete
+ it by calling ``clearstamp(stamp_id)``.
+
+ >>> turtle.color("blue")
+ >>> turtle.stamp()
+ 13
+ >>> turtle.fd(50)
+
+
+.. function:: clearstamp(stampid)
+
+ :param stampid: an integer, must be return value of previous
+ :func:`stamp` call
+
+ Delete stamp with given *stampid*.
+
+ >>> turtle.color("blue")
+ >>> astamp = turtle.stamp()
+ >>> turtle.fd(50)
+ >>> turtle.clearstamp(astamp)
+
+
+.. function:: clearstamps(n=None)
+
+ :param n: an integer (or ``None``)
+
+ Delete all or first/last *n* of turtle's stamps. If *n* is None, delete
+ all stamps, if *n* > 0 delete first *n* stamps, else if *n* < 0 delete
+ last *n* stamps.
+
+ >>> for i in range(8):
+ ... turtle.stamp(); turtle.fd(30)
+ >>> turtle.clearstamps(2)
+ >>> turtle.clearstamps(-2)
+ >>> turtle.clearstamps()
+
+
+.. function:: undo()
+
+ Undo (repeatedly) the last turtle action(s). Number of available
+ undo actions is determined by the size of the undobuffer.
+
+ >>> for i in range(4):
+ ... turtle.fd(50); turtle.lt(80)
+ ...
+ >>> for i in range(8):
+ ... turtle.undo()
+
+
+.. function:: speed(speed=None)
+
+ :param speed: an integer in the range 0..10 or a speedstring (see below)
+
+ Set the turtle's speed to an integer value in the range 0..10. If no
+ argument is given, return current speed.
+
+ If input is a number greater than 10 or smaller than 0.5, speed is set
+ to 0. Speedstrings are mapped to speedvalues as follows:
+
+ * "fastest": 0
+ * "fast": 10
+ * "normal": 6
+ * "slow": 3
+ * "slowest": 1
+
+ Speeds from 1 to 10 enforce increasingly faster animation of line drawing
+ and turtle turning.
+
+ Attention: *speed* = 0 means that *no* animation takes
+ place. forward/back makes turtle jump and likewise left/right make the
+ turtle turn instantly.
+
+ >>> turtle.speed(3)
+
+
+Tell Turtle's state
+-------------------
+
+.. function:: position()
+ pos()
+
+ Return the turtle's current location (x,y) (as a :class:`Vec2D` vector).
+
+ >>> turtle.pos()
+ (0.00, 240.00)
+
+
+.. function:: towards(x, y=None)
+
+ :param x: a number or a pair/vector of numbers or a turtle instance
+ :param y: a number if *x* is a number, else ``None``
+
+ Return the angle between the line from turtle position to position specified
+ by (x,y), the vector or the other turtle. This depends on the turtle's start
+ orientation which depends on the mode - "standard"/"world" or "logo").
+
+ >>> turtle.pos()
+ (10.00, 10.00)
+ >>> turtle.towards(0,0)
+ 225.0
+
+
+.. function:: xcor()
+
+ Return the turtle's x coordinate.
+
+ >>> reset()
+ >>> turtle.left(60)
+ >>> turtle.forward(100)
+ >>> print turtle.xcor()
+ 50.0
+
+
+.. function:: ycor()
+
+ Return the turtle's y coordinate.
+
+ >>> reset()
+ >>> turtle.left(60)
+ >>> turtle.forward(100)
+ >>> print turtle.ycor()
+ 86.6025403784
+
+
+.. function:: heading()
+
+ Return the turtle's current heading (value depends on the turtle mode, see
+ :func:`mode`).
+
+ >>> turtle.left(67)
+ >>> turtle.heading()
+ 67.0
+
+
+.. function:: distance(x, y=None)
+
+ :param x: a number or a pair/vector of numbers or a turtle instance
+ :param y: a number if *x* is a number, else ``None``
+
+ Return the distance from the turtle to (x,y), the given vector, or the given
+ other turtle, in turtle step units.
+
+ >>> turtle.pos()
+ (0.00, 0.00)
+ >>> turtle.distance(30,40)
+ 50.0
+ >>> joe = Turtle()
+ >>> joe.forward(77)
+ >>> turtle.distance(joe)
+ 77.0
+
+
+Settings for measurement
+------------------------
+
+.. function:: degrees(fullcircle=360.0)
+
+ :param fullcircle: a number
+
+ Set angle measurement units, i.e. set number of "degrees" for a full circle.
+ Default value is 360 degrees.
+
+ >>> turtle.left(90)
+ >>> turtle.heading()
+ 90
+ >>> turtle.degrees(400.0) # angle measurement in gon
+ >>> turtle.heading()
+ 100
+
+
+.. function:: radians()
+
+ Set the angle measurement units to radians. Equivalent to
+ ``degrees(2*math.pi)``.
+
+ >>> turtle.heading()
+ 90
+ >>> turtle.radians()
+ >>> turtle.heading()
+ 1.5707963267948966
+
+
+Pen control
+-----------
+
+Drawing state
+~~~~~~~~~~~~~
+
+.. function:: pendown()
+ pd()
+ down()
+
+ Pull the pen down -- drawing when moving.
+
- Turn right *angle* units. Units are by default degrees, but can be set via the
- :func:`degrees` and :func:`radians` functions.
+.. function:: penup()
+ pu()
+ up()
+ Pull the pen up -- no drawing when moving.
-.. function:: up()
- Move the pen up --- stop drawing.
+.. function:: pensize(width=None)
+ width(width=None)
+ :param width: a positive number
-.. function:: down()
+ Set the line thickness to *width* or return it. If resizemode is set to
+ "auto" and turtleshape is a polygon, that polygon is drawn with the same line
+ thickness. If no argument is given, the current pensize is returned.
- Move the pen down --- draw when moving.
+ >>> turtle.pensize()
+ 1
+ >>> turtle.pensize(10) # from here on lines of width 10 are drawn
-.. function:: width(width)
+.. function:: pen(pen=None, **pendict)
- Set the line width to *width*.
+ :param pen: a dictionary with some or all of the below listed keys
+ :param pendict: one or more keyword-arguments with the below listed keys as keywords
+ Return or set the pen's attributes in a "pen-dictionary" with the following
+ key/value pairs:
-.. function:: color(s)
- color((r, g, b))
- color(r, g, b)
+ * "shown": True/False
+ * "pendown": True/False
+ * "pencolor": color-string or color-tuple
+ * "fillcolor": color-string or color-tuple
+ * "pensize": positive number
+ * "speed": number in range 0..10
+ * "resizemode": "auto" or "user" or "noresize"
+ * "stretchfactor": (positive number, positive number)
+ * "outline": positive number
+ * "tilt": number
- Set the pen color. In the first form, the color is specified as a Tk color
- specification as a string. The second form specifies the color as a tuple of
- the RGB values, each in the range [0..1]. For the third form, the color is
- specified giving the RGB values as three separate parameters (each in the range
- [0..1]).
+ This dicionary can be used as argument for a subsequent call to :func:`pen`
+ to restore the former pen-state. Moreover one or more of these attributes
+ can be provided as keyword-arguments. This can be used to set several pen
+ attributes in one statement.
+ >>> turtle.pen(fillcolor="black", pencolor="red", pensize=10)
+ >>> turtle.pen()
+ {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+ 'pencolor': 'red', 'pendown': True, 'fillcolor': 'black',
+ 'stretchfactor': (1,1), 'speed': 3}
+ >>> penstate=turtle.pen()
+ >>> turtle.color("yellow","")
+ >>> turtle.penup()
+ >>> turtle.pen()
+ {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+ 'pencolor': 'yellow', 'pendown': False, 'fillcolor': '',
+ 'stretchfactor': (1,1), 'speed': 3}
+ >>> p.pen(penstate, fillcolor="green")
+ >>> p.pen()
+ {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+ 'pencolor': 'red', 'pendown': True, 'fillcolor': 'green',
+ 'stretchfactor': (1,1), 'speed': 3}
-.. function:: write(text[, move])
- Write *text* at the current pen position. If *move* is true, the pen is moved to
- the bottom-right corner of the text. By default, *move* is false.
+.. function:: isdown()
+ Return ``True`` if pen is down, ``False`` if it's up.
+
+ >>> turtle.penup()
+ >>> turtle.isdown()
+ False
+ >>> turtle.pendown()
+ >>> turtle.isdown()
+ True
+
+
+Color control
+~~~~~~~~~~~~~
+
+.. function:: pencolor(*args)
+
+ Return or set the pencolor.
+
+ Four input formats are allowed:
+
+ ``pencolor()``
+ Return the current pencolor as color specification string, possibly in
+ hex-number format (see example). May be used as input to another
+ color/pencolor/fillcolor call.
+
+ ``pencolor(colorstring)``
+ Set pencolor to *colorstring*, which is a Tk color specification string,
+ such as ``"red"``, ``"yellow"``, or ``"#33cc8c"``.
+
+ ``pencolor((r, g, b))``
+ Set pencolor to the RGB color represented by the tuple of *r*, *g*, and
+ *b*. Each of *r*, *g*, and *b* must be in the range 0..colormode, where
+ colormode is either 1.0 or 255 (see :func:`colormode`).
+
+ ``pencolor(r, g, b)``
+ Set pencolor to the RGB color represented by *r*, *g*, and *b*. Each of
+ *r*, *g*, and *b* must be in the range 0..colormode.
+
+ If turtleshape is a polygon, the outline of that polygon is drawn with the
+ newly set pencolor.
+
+ >>> turtle.pencolor("brown")
+ >>> tup = (0.2, 0.8, 0.55)
+ >>> turtle.pencolor(tup)
+ >>> turtle.pencolor()
+ "#33cc8c"
+
+
+.. function:: fillcolor(*args)
+
+ Return or set the fillcolor.
+
+ Four input formats are allowed:
+
+ ``fillcolor()``
+ Return the current fillcolor as color specification string, possibly in
+ hex-number format (see example). May be used as input to another
+ color/pencolor/fillcolor call.
+
+ ``fillcolor(colorstring)``
+ Set fillcolor to *colorstring*, which is a Tk color specification string,
+ such as ``"red"``, ``"yellow"``, or ``"#33cc8c"``.
+
+ ``fillcolor((r, g, b))``
+ Set fillcolor to the RGB color represented by the tuple of *r*, *g*, and
+ *b*. Each of *r*, *g*, and *b* must be in the range 0..colormode, where
+ colormode is either 1.0 or 255 (see :func:`colormode`).
+
+ ``fillcolor(r, g, b)``
+ Set fillcolor to the RGB color represented by *r*, *g*, and *b*. Each of
+ *r*, *g*, and *b* must be in the range 0..colormode.
+
+ If turtleshape is a polygon, the interior of that polygon is drawn
+ with the newly set fillcolor.
+
+ >>> turtle.fillcolor("violet")
+ >>> col = turtle.pencolor()
+ >>> turtle.fillcolor(col)
+ >>> turtle.fillcolor(0, .5, 0)
+
+
+.. function:: color(*args)
+
+ Return or set pencolor and fillcolor.
+
+ Several input formats are allowed. They use 0 to 3 arguments as
+ follows:
+
+ ``color()``
+ Return the current pencolor and the current fillcolor as a pair of color
+ specification strings as returned by :func:`pencolor` and
+ :func:`fillcolor`.
+
+ ``color(colorstring)``, ``color((r,g,b))``, ``color(r,g,b)``
+ Inputs as in :func:`pencolor`, set both, fillcolor and pencolor, to the
+ given value.
+
+ ``color(colorstring1, colorstring2)``, ``color((r1,g1,b1), (r2,g2,b2))``
+ Equivalent to ``pencolor(colorstring1)`` and ``fillcolor(colorstring2)``
+ and analogously if the other input format is used.
+
+ If turtleshape is a polygon, outline and interior of that polygon is drawn
+ with the newly set colors.
+
+ >>> turtle.color("red", "green")
+ >>> turtle.color()
+ ("red", "green")
+ >>> colormode(255)
+ >>> color((40, 80, 120), (160, 200, 240))
+ >>> color()
+ ("#285078", "#a0c8f0")
+
+
+See also: Screen method :func:`colormode`.
+
+
+Filling
+~~~~~~~
.. function:: fill(flag)
- The complete specifications are rather complex, but the recommended usage is:
- call ``fill(1)`` before drawing a path you want to fill, and call ``fill(0)``
- when you finish to draw the path.
+ :param flag: True/False (or 1/0 respectively)
+
+ Call ``fill(True)`` before drawing the shape you want to fill, and
+ ``fill(False)`` when done. When used without argument: return fillstate
+ (``True`` if filling, ``False`` else).
+
+ >>> turtle.fill(True)
+ >>> for _ in range(3):
+ ... turtle.forward(100)
+ ... turtle.left(120)
+ ...
+ >>> turtle.fill(False)
.. function:: begin_fill()
- Switch turtle into filling mode; Must eventually be followed by a corresponding
- end_fill() call. Otherwise it will be ignored.
+ Call just before drawing a shape to be filled. Equivalent to ``fill(True)``.
- .. versionadded:: 2.5
+ >>> turtle.color("black", "red")
+ >>> turtle.begin_fill()
+ >>> turtle.circle(60)
+ >>> turtle.end_fill()
.. function:: end_fill()
- End filling mode, and fill the shape; equivalent to ``fill(0)``.
+ Fill the shape drawn after the last call to :func:`begin_fill`. Equivalent
+ to ``fill(False)``.
- .. versionadded:: 2.5
+More drawing control
+~~~~~~~~~~~~~~~~~~~~
+
+.. function:: reset()
-.. function:: circle(radius[, extent])
+ Delete the turtle's drawings from the screen, re-center the turtle and set
+ variables to the default values.
- Draw a circle with radius *radius* whose center-point is *radius* units left of
- the turtle. *extent* determines which part of a circle is drawn: if not given it
- defaults to a full circle.
+ >>> turtle.position()
+ (0.00,-22.00)
+ >>> turtle.heading()
+ 100.0
+ >>> turtle.reset()
+ >>> turtle.position()
+ (0.00,0.00)
+ >>> turtle.heading()
+ 0.0
- If *extent* is not a full circle, one endpoint of the arc is the current pen
- position. The arc is drawn in a counter clockwise direction if *radius* is
- positive, otherwise in a clockwise direction. In the process, the direction of
- the turtle is changed by the amount of the *extent*.
+.. function:: clear()
-.. function:: goto(x, y)
- goto((x, y))
+ Delete the turtle's drawings from the screen. Do not move turtle. State and
+ position of the turtle as well as drawings of other turtles are not affected.
- Go to co-ordinates *x*, *y*. The co-ordinates may be specified either as two
- separate arguments or as a 2-tuple.
+.. function:: write(arg, move=False, align="left", font=("Arial", 8, "normal"))
-.. function:: towards(x, y)
+ :param arg: object to be written to the TurtleScreen
+ :param move: True/False
+ :param align: one of the strings "left", "center" or right"
+ :param font: a triple (fontname, fontsize, fonttype)
- Return the angle of the line from the turtle's position to the point *x*, *y*.
- The co-ordinates may be specified either as two separate arguments, as a
- 2-tuple, or as another pen object.
+ Write text - the string representation of *arg* - at the current turtle
+ position according to *align* ("left", "center" or right") and with the given
+ font. If *move* is True, the pen is moved to the bottom-right corner of the
+ text. By default, *move* is False.
- .. versionadded:: 2.5
+ >>> turtle.write("Home = ", True, align="center")
+ >>> turtle.write((0,0), True)
-.. function:: heading()
+Turtle state
+------------
- Return the current orientation of the turtle.
+Visibility
+~~~~~~~~~~
- .. versionadded:: 2.3
+.. function:: showturtle()
+ st()
+ Make the turtle visible.
-.. function:: setheading(angle)
+ >>> turtle.hideturtle()
+ >>> turtle.showturtle()
- Set the orientation of the turtle to *angle*.
- .. versionadded:: 2.3
+.. function:: hideturtle()
+ ht()
+ Make the turtle invisible. It's a good idea to do this while you're in the
+ middle of doing some complex drawing, because hiding the turtle speeds up the
+ drawing observably.
-.. function:: position()
+ >>> turtle.hideturtle()
- Return the current location of the turtle as an ``(x,y)`` pair.
- .. versionadded:: 2.3
+.. function:: isvisible()
+ Return True if the Turtle is shown, False if it's hidden.
-.. function:: setx(x)
+ >>> turtle.hideturtle()
+ >>> print turtle.isvisible():
+ False
- Set the x coordinate of the turtle to *x*.
- .. versionadded:: 2.3
+Appearance
+~~~~~~~~~~
+.. function:: shape(name=None)
-.. function:: sety(y)
+ :param name: a string which is a valid shapename
+
+ Set turtle shape to shape with given *name* or, if name is not given, return
+ name of current shape. Shape with *name* must exist in the TurtleScreen's
+ shape dictionary. Initially there are the following polygon shapes: "arrow",
+ "turtle", "circle", "square", "triangle", "classic". To learn about how to
+ deal with shapes see Screen method :func:`register_shape`.
+
+ >>> turtle.shape()
+ "arrow"
+ >>> turtle.shape("turtle")
+ >>> turtle.shape()
+ "turtle"
+
+
+.. function:: resizemode(rmode=None)
+
+ :param rmode: one of the strings "auto", "user", "noresize"
+
+ Set resizemode to one of the values: "auto", "user", "noresize". If *rmode*
+ is not given, return current resizemode. Different resizemodes have the
+ following effects:
+
+ - "auto": adapts the appearance of the turtle corresponding to the value of pensize.
+ - "user": adapts the appearance of the turtle according to the values of
+ stretchfactor and outlinewidth (outline), which are set by
+ :func:`shapesize`.
+ - "noresize": no adaption of the turtle's appearance takes place.
+
+ resizemode("user") is called by :func:`shapesize` when used with arguments.
+
+ >>> turtle.resizemode("noresize")
+ >>> turtle.resizemode()
+ "noresize"
+
+
+.. function:: shapesize(stretch_wid=None, stretch_len=None, outline=None)
+
+ :param stretch_wid: positive number
+ :param stretch_len: positive number
+ :param outline: positive number
+
+ Return or set the pen's attributes x/y-stretchfactors and/or outline. Set
+ resizemode to "user". If and only if resizemode is set to "user", the turtle
+ will be displayed stretched according to its stretchfactors: *stretch_wid* is
+ stretchfactor perpendicular to its orientation, *stretch_len* is
+ stretchfactor in direction of its orientation, *outline* determines the width
+ of the shapes's outline.
+
+ >>> turtle.resizemode("user")
+ >>> turtle.shapesize(5, 5, 12)
+ >>> turtle.shapesize(outline=8)
+
+
+.. function:: tilt(angle)
+
+ :param angle: a number
+
+ Rotate the turtleshape by *angle* from its current tilt-angle, but do *not*
+ change the turtle's heading (direction of movement).
+
+ >>> turtle.shape("circle")
+ >>> turtle.shapesize(5,2)
+ >>> turtle.tilt(30)
+ >>> turtle.fd(50)
+ >>> turtle.tilt(30)
+ >>> turtle.fd(50)
+
+
+.. function:: settiltangle(angle)
+
+ :param angle: a number
+
+ Rotate the turtleshape to point in the direction specified by *angle*,
+ regardless of its current tilt-angle. *Do not* change the turtle's heading
+ (direction of movement).
+
+ >>> turtle.shape("circle")
+ >>> turtle.shapesize(5,2)
+ >>> turtle.settiltangle(45)
+ >>> stamp()
+ >>> turtle.fd(50)
+ >>> turtle.settiltangle(-45)
+ >>> stamp()
+ >>> turtle.fd(50)
+
+
+.. function:: tiltangle()
+
+ Return the current tilt-angle, i.e. the angle between the orientation of the
+ turtleshape and the heading of the turtle (its direction of movement).
+
+ >>> turtle.shape("circle")
+ >>> turtle.shapesize(5,2)
+ >>> turtle.tilt(45)
+ >>> turtle.tiltangle()
+ 45
+
+
+Using events
+------------
+
+.. function:: onclick(fun, btn=1, add=None)
+
+ :param fun: a function with two arguments which will be called with the
+ coordinates of the clicked point on the canvas
+ :param num: number of the mouse-button, defaults to 1 (left mouse button)
+ :param add: ``True`` or ``False`` -- if ``True``, a new binding will be
+ added, otherwise it will replace a former binding
+
+ Bind *fun* to mouse-click events on this turtle. If *fun* is ``None``,
+ existing bindings are removed. Example for the anonymous turtle, i.e. the
+ procedural way:
+
+ >>> def turn(x, y):
+ ... left(180)
+ ...
+ >>> onclick(turn) # Now clicking into the turtle will turn it.
+ >>> onclick(None) # event-binding will be removed
+
+
+.. function:: onrelease(fun, btn=1, add=None)
+
+ :param fun: a function with two arguments which will be called with the
+ coordinates of the clicked point on the canvas
+ :param num: number of the mouse-button, defaults to 1 (left mouse button)
+ :param add: ``True`` or ``False`` -- if ``True``, a new binding will be
+ added, otherwise it will replace a former binding
+
+ Bind *fun* to mouse-button-release events on this turtle. If *fun* is
+ ``None``, existing bindings are removed.
+
+ >>> class MyTurtle(Turtle):
+ ... def glow(self,x,y):
+ ... self.fillcolor("red")
+ ... def unglow(self,x,y):
+ ... self.fillcolor("")
+ ...
+ >>> turtle = MyTurtle()
+ >>> turtle.onclick(turtle.glow) # clicking on turtle turns fillcolor red,
+ >>> turtle.onrelease(turtle.unglow) # releasing turns it to transparent.
+
+
+.. function:: ondrag(fun, btn=1, add=None)
+
+ :param fun: a function with two arguments which will be called with the
+ coordinates of the clicked point on the canvas
+ :param num: number of the mouse-button, defaults to 1 (left mouse button)
+ :param add: ``True`` or ``False`` -- if ``True``, a new binding will be
+ added, otherwise it will replace a former binding
- Set the y coordinate of the turtle to *y*.
+ Bind *fun* to mouse-move events on this turtle. If *fun* is ``None``,
+ existing bindings are removed.
- .. versionadded:: 2.3
+ Remark: Every sequence of mouse-move-events on a turtle is preceded by a
+ mouse-click event on that turtle.
+
+ >>> turtle.ondrag(turtle.goto)
+ # Subsequently, clicking and dragging the Turtle will move it across
+ # the screen thereby producing handdrawings (if pen is down).
+
+
+Special Turtle methods
+----------------------
+
+.. function:: begin_poly()
+
+ Start recording the vertices of a polygon. Current turtle position is first
+ vertex of polygon.
+
+
+.. function:: end_poly()
+
+ Stop recording the vertices of a polygon. Current turtle position is last
+ vertex of polygon. This will be connected with the first vertex.
+
+
+.. function:: get_poly()
+
+ Return the last recorded polygon.
+
+ >>> p = turtle.get_poly()
+ >>> turtle.register_shape("myFavouriteShape", p)
+
+
+.. function:: clone()
+
+ Create and return a clone of the turtle with same position, heading and
+ turtle properties.
+
+ >>> mick = Turtle()
+ >>> joe = mick.clone()
+
+
+.. function:: getturtle()
+
+ Return the Turtle object itself. Only reasonable use: as a function to
+ return the "anonymous turtle":
+
+ >>> pet = getturtle()
+ >>> pet.fd(50)
+ >>> pet
+ <turtle.Turtle object at 0x01417350>
+ >>> turtles()
+ [<turtle.Turtle object at 0x01417350>]
+
+
+.. function:: getscreen()
+
+ Return the :class:`TurtleScreen` object the turtle is drawing on.
+ TurtleScreen methods can then be called for that object.
+
+ >>> ts = turtle.getscreen()
+ >>> ts
+ <turtle.Screen object at 0x01417710>
+ >>> ts.bgcolor("pink")
+
+
+.. function:: setundobuffer(size)
+
+ :param size: an integer or ``None``
+
+ Set or disable undobuffer. If *size* is an integer an empty undobuffer of
+ given size is installed. *size* gives the maximum number of turtle actions
+ that can be undone by the :func:`undo` method/function. If *size* is
+ ``None``, the undobuffer is disabled.
+
+ >>> turtle.setundobuffer(42)
+
+
+.. function:: undobufferentries()
+
+ Return number of entries in the undobuffer.
+
+ >>> while undobufferentries():
+ ... undo()
+
+
+.. function:: tracer(flag=None, delay=None)
+
+ A replica of the corresponding TurtleScreen method.
+
+ .. deprecated:: 2.6
.. function:: window_width()
+ window_height()
+
+ Both are replicas of the corresponding TurtleScreen methods.
+
+ .. deprecated:: 2.6
+
+
+.. _compoundshapes:
+
+Excursus about the use of compound shapes
+-----------------------------------------
+
+To use compound turtle shapes, which consist of several polygons of different
+color, you must use the helper class :class:`Shape` explicitly as described
+below:
+
+1. Create an empty Shape object of type "compound".
+2. Add as many components to this object as desired, using the
+ :meth:`addcomponent` method.
+
+ For example:
+
+ >>> s = Shape("compound")
+ >>> poly1 = ((0,0),(10,-5),(0,10),(-10,-5))
+ >>> s.addcomponent(poly1, "red", "blue")
+ >>> poly2 = ((0,0),(10,-5),(-10,-5))
+ >>> s.addcomponent(poly2, "blue", "red")
+
+3. Now add the Shape to the Screen's shapelist and use it:
+
+ >>> register_shape("myshape", s)
+ >>> shape("myshape")
+
+
+.. note::
+
+ The :class:`Shape` class is used internally by the :func:`register_shape`
+ method in different ways. The application programmer has to deal with the
+ Shape class *only* when using compound shapes like shown above!
+
+
+Methods of TurtleScreen/Screen and corresponding functions
+==========================================================
+
+Most of the examples in this section refer to a TurtleScreen instance called
+``screen``.
+
+
+Window control
+--------------
+
+.. function:: bgcolor(*args)
+
+ :param args: a color string or three numbers in the range 0..colormode or a
+ 3-tuple of such numbers
+
+ Set or return background color of the TurtleScreen.
+
+ >>> screen.bgcolor("orange")
+ >>> screen.bgcolor()
+ "orange"
+ >>> screen.bgcolor(0.5,0,0.5)
+ >>> screen.bgcolor()
+ "#800080"
+
+
+.. function:: bgpic(picname=None)
+
+ :param picname: a string, name of a gif-file or ``"nopic"``, or ``None``
+
+ Set background image or return name of current backgroundimage. If *picname*
+ is a filename, set the corresponding image as background. If *picname* is
+ ``"nopic"``, delete background image, if present. If *picname* is ``None``,
+ return the filename of the current backgroundimage.
+
+ >>> screen.bgpic()
+ "nopic"
+ >>> screen.bgpic("landscape.gif")
+ >>> screen.bgpic()
+ "landscape.gif"
+
+
+.. function:: clear()
+ clearscreen()
+
+ Delete all drawings and all turtles from the TurtleScreen. Reset the now
+ empty TurtleScreen to its initial state: white background, no background
+ image, no event bindings and tracing on.
+
+ .. note::
+ This TurtleScreen method is available as a global function only under the
+ name ``clearscreen``. The global function ``clear`` is another one
+ derived from the Turtle method ``clear``.
+
+
+.. function:: reset()
+ resetscreen()
+
+ Reset all Turtles on the Screen to their initial state.
+
+ .. note::
+ This TurtleScreen method is available as a global function only under the
+ name ``resetscreen``. The global function ``reset`` is another one
+ derived from the Turtle method ``reset``.
+
+
+.. function:: screensize(canvwidth=None, canvheight=None, bg=None)
+
+ :param canvwidth: positive integer, new width of canvas in pixels
+ :param canvheight: positive integer, new height of canvas in pixels
+ :param bg: colorstring or color-tupel, new background color
+
+ If no arguments are given, return current (canvaswidth, canvasheight). Else
+ resize the canvas the turtles are drawing on. Do not alter the drawing
+ window. To observe hidden parts of the canvas, use the scrollbars. With this
+ method, one can make visible those parts of a drawing which were outside the
+ canvas before.
+
+ >>> turtle.screensize(2000,1500)
+ # e.g. to search for an erroneously escaped turtle ;-)
+
+
+.. function:: setworldcoordinates(llx, lly, urx, ury)
+
+ :param llx: a number, x-coordinate of lower left corner of canvas
+ :param lly: a number, y-coordinate of lower left corner of canvas
+ :param urx: a number, x-coordinate of upper right corner of canvas
+ :param ury: a number, y-coordinate of upper right corner of canvas
+
+ Set up user-defined coordinate system and switch to mode "world" if
+ necessary. This performs a ``screen.reset()``. If mode "world" is already
+ active, all drawings are redrawn according to the new coordinates.
+
+ **ATTENTION**: in user-defined coordinate systems angles may appear
+ distorted.
+
+ >>> screen.reset()
+ >>> screen.setworldcoordinates(-50,-7.5,50,7.5)
+ >>> for _ in range(72):
+ ... left(10)
+ ...
+ >>> for _ in range(8):
+ ... left(45); fd(2) # a regular octogon
- Return the width of the canvas window.
- .. versionadded:: 2.3
+Animation control
+-----------------
+
+.. function:: delay(delay=None)
+
+ :param delay: positive integer
+
+ Set or return the drawing *delay* in milliseconds. (This is approximately
+ the time interval between two consecutived canvas updates.) The longer the
+ drawing delay, the slower the animation.
+
+ Optional argument:
+
+ >>> screen.delay(15)
+ >>> screen.delay()
+ 15
+
+
+.. function:: tracer(n=None, delay=None)
+
+ :param n: nonnegative integer
+ :param delay: nonnegative integer
+
+ Turn turtle animation on/off and set delay for update drawings. If *n* is
+ given, only each n-th regular screen update is really performed. (Can be
+ used to accelerate the drawing of complex graphics.) Second argument sets
+ delay value (see :func:`delay`).
+
+ >>> screen.tracer(8, 25)
+ >>> dist = 2
+ >>> for i in range(200):
+ ... fd(dist)
+ ... rt(90)
+ ... dist += 2
+
+
+.. function:: update()
+
+ Perform a TurtleScreen update. To be used when tracer is turned off.
+
+See also the RawTurtle/Turtle method :func:`speed`.
+
+
+Using screen events
+-------------------
+
+.. function:: listen(xdummy=None, ydummy=None)
+
+ Set focus on TurtleScreen (in order to collect key-events). Dummy arguments
+ are provided in order to be able to pass :func:`listen` to the onclick method.
+
+
+.. function:: onkey(fun, key)
+
+ :param fun: a function with no arguments or ``None``
+ :param key: a string: key (e.g. "a") or key-symbol (e.g. "space")
+
+ Bind *fun* to key-release event of key. If *fun* is ``None``, event bindings
+ are removed. Remark: in order to be able to register key-events, TurtleScreen
+ must have the focus. (See method :func:`listen`.)
+
+ >>> def f():
+ ... fd(50)
+ ... lt(60)
+ ...
+ >>> screen.onkey(f, "Up")
+ >>> screen.listen()
+
+
+.. function:: onclick(fun, btn=1, add=None)
+ onscreenclick(fun, btn=1, add=None)
+
+ :param fun: a function with two arguments which will be called with the
+ coordinates of the clicked point on the canvas
+ :param num: number of the mouse-button, defaults to 1 (left mouse button)
+ :param add: ``True`` or ``False`` -- if ``True``, a new binding will be
+ added, otherwise it will replace a former binding
+
+ Bind *fun* to mouse-click events on this screen. If *fun* is ``None``,
+ existing bindings are removed.
+
+ Example for a TurtleScreen instance named ``screen`` and a Turtle instance
+ named turtle:
+
+ >>> screen.onclick(turtle.goto)
+ # Subsequently clicking into the TurtleScreen will
+ # make the turtle move to the clicked point.
+ >>> screen.onclick(None) # remove event binding again
+
+ .. note::
+ This TurtleScreen method is available as a global function only under the
+ name ``onscreenclick``. The global function ``onclick`` is another one
+ derived from the Turtle method ``onclick``.
+
+
+.. function:: ontimer(fun, t=0)
+
+ :param fun: a function with no arguments
+ :param t: a number >= 0
+
+ Install a timer that calls *fun* after *t* milliseconds.
+
+ >>> running = True
+ >>> def f():
+ if running:
+ fd(50)
+ lt(60)
+ screen.ontimer(f, 250)
+ >>> f() ### makes the turtle marching around
+ >>> running = False
+
+
+Settings and special methods
+----------------------------
+
+.. function:: mode(mode=None)
+
+ :param mode: one of the strings "standard", "logo" or "world"
+
+ Set turtle mode ("standard", "logo" or "world") and perform reset. If mode
+ is not given, current mode is returned.
+
+ Mode "standard" is compatible with old :mod:`turtle`. Mode "logo" is
+ compatible with most Logo turtle graphics. Mode "world" uses user-defined
+ "world coordinates". **Attention**: in this mode angles appear distorted if
+ ``x/y`` unit-ratio doesn't equal 1.
+
+ ============ ========================= ===================
+ Mode Initial turtle heading positive angles
+ ============ ========================= ===================
+ "standard" to the right (east) counterclockwise
+ "logo" upward (north) clockwise
+ ============ ========================= ===================
+
+ >>> mode("logo") # resets turtle heading to north
+ >>> mode()
+ "logo"
+
+
+.. function:: colormode(cmode=None)
+
+ :param cmode: one of the values 1.0 or 255
+
+ Return the colormode or set it to 1.0 or 255. Subsequently *r*, *g*, *b*
+ values of color triples have to be in the range 0..\ *cmode*.
+
+ >>> screen.colormode()
+ 1.0
+ >>> screen.colormode(255)
+ >>> turtle.pencolor(240,160,80)
+
+
+.. function:: getcanvas()
+
+ Return the Canvas of this TurtleScreen. Useful for insiders who know what to
+ do with a Tkinter Canvas.
+
+ >>> cv = screen.getcanvas()
+ >>> cv
+ <turtle.ScrolledCanvas instance at 0x010742D8>
+
+
+.. function:: getshapes()
+
+ Return a list of names of all currently available turtle shapes.
+
+ >>> screen.getshapes()
+ ["arrow", "blank", "circle", ..., "turtle"]
+
+
+.. function:: register_shape(name, shape=None)
+ addshape(name, shape=None)
+
+ There are three different ways to call this function:
+
+ (1) *name* is the name of a gif-file and *shape* is ``None``: Install the
+ corresponding image shape.
+
+ .. note::
+ Image shapes *do not* rotate when turning the turtle, so they do not
+ display the heading of the turtle!
+
+ (2) *name* is an arbitrary string and *shape* is a tuple of pairs of
+ coordinates: Install the corresponding polygon shape.
+
+ (3) *name* is an arbitrary string and shape is a (compound) :class:`Shape`
+ object: Install the corresponding compound shape.
+
+ Add a turtle shape to TurtleScreen's shapelist. Only thusly registered
+ shapes can be used by issuing the command ``shape(shapename)``.
+
+ >>> screen.register_shape("turtle.gif")
+ >>> screen.register_shape("triangle", ((5,-3), (0,5), (-5,-3)))
+
+
+.. function:: turtles()
+
+ Return the list of turtles on the screen.
+
+ >>> for turtle in screen.turtles()
+ ... turtle.color("red")
.. function:: window_height()
- Return the height of the canvas window.
+ Return the height of the turtle window.
- .. versionadded:: 2.3
+ >>> screen.window_height()
+ 480
-This module also does ``from math import *``, so see the documentation for the
-:mod:`math` module for additional constants and functions useful for turtle
-graphics.
+.. function:: window_width()
-.. function:: demo()
+ Return the width of the turtle window.
- Exercise the module a bit.
+ >>> screen.window_width()
+ 640
-.. exception:: Error
+.. _screenspecific:
- Exception raised on any error caught by this module.
+Methods specific to Screen, not inherited from TurtleScreen
+-----------------------------------------------------------
-For examples, see the code of the :func:`demo` function.
+.. function:: bye()
-This module defines the following classes:
+ Shut the turtlegraphics window.
-.. class:: Pen()
+.. function:: exitonclick()
- Define a pen. All above functions can be called as a methods on the given pen.
- The constructor automatically creates a canvas do be drawn on.
+ Bind bye() method to mouse clicks on the Screen.
-.. class:: Turtle()
+ If the value "using_IDLE" in the configuration dictionary is ``False``
+ (default value), also enter mainloop. Remark: If IDLE with the ``-n`` switch
+ (no subprocess) is used, this value should be set to ``True`` in
+ :file:`turtle.cfg`. In this case IDLE's own mainloop is active also for the
+ client script.
- Define a pen. This is essentially a synonym for ``Pen()``; :class:`Turtle` is an
- empty subclass of :class:`Pen`.
+.. function:: setup(width=_CFG["width"], height=_CFG["height"], startx=_CFG["leftright"], starty=_CFG["topbottom"])
-.. class:: RawPen(canvas)
+ Set the size and position of the main window. Default values of arguments
+ are stored in the configuration dicionary and can be changed via a
+ :file:`turtle.cfg` file.
- Define a pen which draws on a canvas *canvas*. This is useful if you want to
- use the module to create graphics in a "real" program.
+ :param width: if an integer, a size in pixels, if a float, a fraction of the
+ screen; default is 50% of screen
+ :param height: if an integer, the height in pixels, if a float, a fraction of
+ the screen; default is 75% of screen
+ :param startx: if positive, starting position in pixels from the left
+ edge of the screen, if negative from the right edge, if None,
+ center window horizontally
+ :param startx: if positive, starting position in pixels from the top
+ edge of the screen, if negative from the bottom edge, if None,
+ center window vertically
+ >>> screen.setup (width=200, height=200, startx=0, starty=0)
+ # sets window to 200x200 pixels, in upper left of screen
+ >>> screen.setup(width=.75, height=0.5, startx=None, starty=None)
+ # sets window to 75% of screen by 50% of screen and centers
-.. _pen-rawpen-objects:
-Turtle, Pen and RawPen Objects
-------------------------------
+.. function:: title(titlestring)
+
+ :param titlestring: a string that is shown in the titlebar of the turtle
+ graphics window
+
+ Set title of turtle window to *titlestring*.
+
+ >>> screen.title("Welcome to the turtle zoo!")
+
+
+The public classes of the module :mod:`turtle`
+==============================================
+
+
+.. class:: RawTurtle(canvas)
+ RawPen(canvas)
+
+ :param canvas: a :class:`Tkinter.Canvas`, a :class:`ScrolledCanvas` or a
+ :class:`TurtleScreen`
+
+ Create a turtle. The turtle has all methods described above as "methods of
+ Turtle/RawTurtle".
+
+
+.. class:: Turtle()
-Most of the global functions available in the module are also available as
-methods of the :class:`Turtle`, :class:`Pen` and :class:`RawPen` classes,
-affecting only the state of the given pen.
+ Subclass of RawTurtle, has the same interface but draws on a default
+ :class:`Screen` object created automatically when needed for the first time.
-The only method which is more powerful as a method is :func:`degrees`, which
-takes an optional argument letting you specify the number of units
-corresponding to a full circle:
+.. class:: TurtleScreen(cv)
-.. method:: Turtle.degrees([fullcircle])
+ :param cv: a :class:`Tkinter.Canvas`
- *fullcircle* is by default 360. This can cause the pen to have any angular units
- whatever: give *fullcircle* ``2*pi`` for radians, or 400 for gradians.
+ Provides screen oriented methods like :func:`setbg` etc. that are described
+ above.
+
+.. class:: Screen()
+
+ Subclass of TurtleScreen, with :ref:`four methods added <screenspecific>`.
+
+
+.. class:: ScrolledCavas(master)
+
+ :param master: some Tkinter widget to contain the ScrolledCanvas, i.e.
+ a Tkinter-canvas with scrollbars added
+
+ Used by class Screen, which thus automatically provides a ScrolledCanvas as
+ playground for the turtles.
+
+.. class:: Shape(type_, data)
+
+ :param type\_: one of the strings "polygon", "image", "compound"
+
+ Data structure modeling shapes. The pair ``(type_, data)`` must follow this
+ specification:
+
+
+ =========== ===========
+ *type_* *data*
+ =========== ===========
+ "polygon" a polygon-tuple, i.e. a tuple of pairs of coordinates
+ "image" an image (in this form only used internally!)
+ "compound" ``None`` (a compund shape has to be constructed using the
+ :meth:`addcomponent` method)
+ =========== ===========
+
+ .. method:: addcomponent(poly, fill, outline=None)
+
+ :param poly: a polygon, i.e. a tuple of pairs of numbers
+ :param fill: a color the *poly* will be filled with
+ :param outline: a color for the poly's outline (if given)
+
+ Example:
+
+ >>> poly = ((0,0),(10,-5),(0,10),(-10,-5))
+ >>> s = Shape("compound")
+ >>> s.addcomponent(poly, "red", "blue")
+ # .. add more components and then use register_shape()
+
+ See :ref:`compoundshapes`.
+
+
+.. class:: Vec2D(x, y)
+
+ A two-dimensional vector class, used as a helper class for implementing
+ turtle graphics. May be useful for turtle graphics programs too. Derived
+ from tuple, so a vector is a tuple!
+
+ Provides (for *a*, *b* vectors, *k* number):
+
+ * ``a + b`` vector addition
+ * ``a - b`` vector subtraction
+ * ``a * b`` inner product
+ * ``k * a`` and ``a * k`` multiplication with scalar
+ * ``abs(a)`` absolute value of a
+ * ``a.rotate(angle)`` rotation
+
+
+Help and configuration
+======================
+
+How to use help
+---------------
+
+The public methods of the Screen and Turtle classes are documented extensively
+via docstrings. So these can be used as online-help via the Python help
+facilities:
+
+- When using IDLE, tooltips show the signatures and first lines of the
+ docstrings of typed in function-/method calls.
+
+- Calling :func:`help` on methods or functions displays the docstrings::
+
+ >>> help(Screen.bgcolor)
+ Help on method bgcolor in module turtle:
+
+ bgcolor(self, *args) unbound turtle.Screen method
+ Set or return backgroundcolor of the TurtleScreen.
+
+ Arguments (if given): a color string or three numbers
+ in the range 0..colormode or a 3-tuple of such numbers.
+
+
+ >>> screen.bgcolor("orange")
+ >>> screen.bgcolor()
+ "orange"
+ >>> screen.bgcolor(0.5,0,0.5)
+ >>> screen.bgcolor()
+ "#800080"
+
+ >>> help(Turtle.penup)
+ Help on method penup in module turtle:
+
+ penup(self) unbound turtle.Turtle method
+ Pull the pen up -- no drawing when moving.
+
+ Aliases: penup | pu | up
+
+ No argument
+
+ >>> turtle.penup()
+
+- The docstrings of the functions which are derived from methods have a modified
+ form::
+
+ >>> help(bgcolor)
+ Help on function bgcolor in module turtle:
+
+ bgcolor(*args)
+ Set or return backgroundcolor of the TurtleScreen.
+
+ Arguments (if given): a color string or three numbers
+ in the range 0..colormode or a 3-tuple of such numbers.
+
+ Example::
+
+ >>> bgcolor("orange")
+ >>> bgcolor()
+ "orange"
+ >>> bgcolor(0.5,0,0.5)
+ >>> bgcolor()
+ "#800080"
+
+ >>> help(penup)
+ Help on function penup in module turtle:
+
+ penup()
+ Pull the pen up -- no drawing when moving.
+
+ Aliases: penup | pu | up
+
+ No argument
+
+ Example:
+ >>> penup()
+
+These modified docstrings are created automatically together with the function
+definitions that are derived from the methods at import time.
+
+
+Translation of docstrings into different languages
+--------------------------------------------------
+
+There is a utility to create a dictionary the keys of which are the method names
+and the values of which are the docstrings of the public methods of the classes
+Screen and Turtle.
+
+.. function:: write_docstringdict(filename="turtle_docstringdict")
+
+ :param filename: a string, used as filename
+
+ Create and write docstring-dictionary to a Python script with the given
+ filename. This function has to be called explicitly (it is not used by the
+ turtle graphics classes). The docstring dictionary will be written to the
+ Python script :file:`{filename}.py`. It is intended to serve as a template
+ for translation of the docstrings into different languages.
+
+If you (or your students) want to use :mod:`turtle` with online help in your
+native language, you have to translate the docstrings and save the resulting
+file as e.g. :file:`turtle_docstringdict_german.py`.
+
+If you have an appropriate entry in your :file:`turtle.cfg` file this dictionary
+will be read in at import time and will replace the original English docstrings.
+
+At the time of this writing there are docstring dictionaries in German and in
+Italian. (Requests please to glingl at aon.at.)
+
+
+
+How to configure Screen and Turtles
+-----------------------------------
+
+The built-in default configuration mimics the appearance and behaviour of the
+old turtle module in order to retain best possible compatibility with it.
+
+If you want to use a different configuration which better reflects the features
+of this module or which better fits to your needs, e.g. for use in a classroom,
+you can prepare a configuration file ``turtle.cfg`` which will be read at import
+time and modify the configuration according to its settings.
+
+The built in configuration would correspond to the following turtle.cfg::
+
+ width = 0.5
+ height = 0.75
+ leftright = None
+ topbottom = None
+ canvwidth = 400
+ canvheight = 300
+ mode = standard
+ colormode = 1.0
+ delay = 10
+ undobuffersize = 1000
+ shape = classic
+ pencolor = black
+ fillcolor = black
+ resizemode = noresize
+ visible = True
+ language = english
+ exampleturtle = turtle
+ examplescreen = screen
+ title = Python Turtle Graphics
+ using_IDLE = False
+
+Short explanation of selected entries:
+
+- The first four lines correspond to the arguments of the :meth:`Screen.setup`
+ method.
+- Line 5 and 6 correspond to the arguments of the method
+ :meth:`Screen.screensize`.
+- *shape* can be any of the built-in shapes, e.g: arrow, turtle, etc. For more
+ info try ``help(shape)``.
+- If you want to use no fillcolor (i.e. make the turtle transparent), you have
+ to write ``fillcolor = ""`` (but all nonempty strings must not have quotes in
+ the cfg-file).
+- If you want to reflect the turtle its state, you have to use ``resizemode =
+ auto``.
+- If you set e.g. ``language = italian`` the docstringdict
+ :file:`turtle_docstringdict_italian.py` will be loaded at import time (if
+ present on the import path, e.g. in the same directory as :mod:`turtle`.
+- The entries *exampleturtle* and *examplescreen* define the names of these
+ objects as they occur in the docstrings. The transformation of
+ method-docstrings to function-docstrings will delete these names from the
+ docstrings.
+- *using_IDLE*: Set this to ``True`` if you regularly work with IDLE and its -n
+ switch ("no subprocess"). This will prevent :func:`exitonclick` to enter the
+ mainloop.
+
+There can be a :file:`turtle.cfg` file in the directory where :mod:`turtle` is
+stored and an additional one in the current working directory. The latter will
+override the settings of the first one.
+
+The :file:`Demo/turtle` directory contains a :file:`turtle.cfg` file. You can
+study it as an example and see its effects when running the demos (preferably
+not from within the demo-viewer).
+
+
+Demo scripts
+============
+
+There is a set of demo scripts in the turtledemo directory located in the
+:file:`Demo/turtle` directory in the source distribution.
+
+It contains:
+
+- a set of 15 demo scripts demonstrating differet features of the new module
+ :mod:`turtle`
+- a demo viewer :file:`turtleDemo.py` which can be used to view the sourcecode
+ of the scripts and run them at the same time. 14 of the examples can be
+ accessed via the Examples menu; all of them can also be run standalone.
+- The example :file:`turtledemo_two_canvases.py` demonstrates the simultaneous
+ use of two canvases with the turtle module. Therefore it only can be run
+ standalone.
+- There is a :file:`turtle.cfg` file in this directory, which also serves as an
+ example for how to write and use such files.
+
+The demoscripts are:
+
++----------------+------------------------------+-----------------------+
+| Name | Description | Features |
++----------------+------------------------------+-----------------------+
+| bytedesign | complex classical | :func:`tracer`, delay,|
+| | turtlegraphics pattern | :func:`update` |
++----------------+------------------------------+-----------------------+
+| chaos | graphs verhust dynamics, | world coordinates |
+| | proves that you must not | |
+| | trust computers' computations| |
++----------------+------------------------------+-----------------------+
+| clock | analog clock showing time | turtles as clock's |
+| | of your computer | hands, ontimer |
++----------------+------------------------------+-----------------------+
+| colormixer | experiment with r, g, b | :func:`ondrag` |
++----------------+------------------------------+-----------------------+
+| fractalcurves | Hilbert & Koch curves | recursion |
++----------------+------------------------------+-----------------------+
+| lindenmayer | ethnomathematics | L-System |
+| | (indian kolams) | |
++----------------+------------------------------+-----------------------+
+| minimal_hanoi | Towers of Hanoi | Rectangular Turtles |
+| | | as Hanoi discs |
+| | | (shape, shapesize) |
++----------------+------------------------------+-----------------------+
+| paint | super minimalistic | :func:`onclick` |
+| | drawing program | |
++----------------+------------------------------+-----------------------+
+| peace | elementary | turtle: appearance |
+| | | and animation |
++----------------+------------------------------+-----------------------+
+| penrose | aperiodic tiling with | :func:`stamp` |
+| | kites and darts | |
++----------------+------------------------------+-----------------------+
+| planet_and_moon| simulation of | compound shapes, |
+| | gravitational system | :class:`Vec2D` |
++----------------+------------------------------+-----------------------+
+| tree | a (graphical) breadth | :func:`clone` |
+| | first tree (using generators)| |
++----------------+------------------------------+-----------------------+
+| wikipedia | a pattern from the wikipedia | :func:`clone`, |
+| | article on turtle graphics | :func:`undo` |
++----------------+------------------------------+-----------------------+
+| yingyang | another elementary example | :func:`circle` |
++----------------+------------------------------+-----------------------+
+Have fun!
Modified: python/branches/tlee-ast-optimize/Include/Python.h
==============================================================================
--- python/branches/tlee-ast-optimize/Include/Python.h (original)
+++ python/branches/tlee-ast-optimize/Include/Python.h Thu Jun 5 17:42:10 2008
@@ -1,11 +1,11 @@
-#ifndef Py_PYTHON_H
-#define Py_PYTHON_H
+#ifndef Py_PYTHON_H #define Py_PYTHON_H
/* Since this is a "meta-include" file, no #ifdef __cplusplus / extern "C" { */
/* Include nearly all Python header files */
#include "patchlevel.h"
#include "pyconfig.h"
+#include "pymacconfig.h"
/* Cyclic gc is always enabled, starting with release 2.3a1. Supply the
* old symbol for the benefit of extension modules written before then
Modified: python/branches/tlee-ast-optimize/Include/pymactoolbox.h
==============================================================================
--- python/branches/tlee-ast-optimize/Include/pymactoolbox.h (original)
+++ python/branches/tlee-ast-optimize/Include/pymactoolbox.h Thu Jun 5 17:42:10 2008
@@ -8,7 +8,10 @@
#endif
#include <Carbon/Carbon.h>
+
+#ifndef __LP64__
#include <QuickTime/QuickTime.h>
+#endif /* !__LP64__ */
/*
** Helper routines for error codes and such.
@@ -18,8 +21,11 @@
PyObject *PyMac_GetOSErrException(void); /* Initialize & return it */
PyObject *PyErr_Mac(PyObject *, int); /* Exception with a mac error */
PyObject *PyMac_Error(OSErr); /* Uses PyMac_GetOSErrException */
+#ifndef __LP64__
extern OSErr PyMac_GetFullPathname(FSSpec *, char *, int); /* convert
fsspec->path */
+#endif /* __LP64__ */
+
/*
** These conversion routines are defined in mactoolboxglue.c itself.
*/
@@ -83,8 +89,10 @@
#endif /* USE_TOOLBOX_OBJECT_GLUE */
/* macfs exports */
+#ifndef __LP64__
int PyMac_GetFSSpec(PyObject *, FSSpec *); /* argument parser for FSSpec */
PyObject *PyMac_BuildFSSpec(FSSpec *); /* Convert FSSpec to PyObject */
+#endif /* !__LP64__ */
int PyMac_GetFSRef(PyObject *, FSRef *); /* argument parser for FSRef */
PyObject *PyMac_BuildFSRef(FSRef *); /* Convert FSRef to PyObject */
@@ -101,39 +109,54 @@
extern int CmpInstObj_Convert(PyObject *, ComponentInstance *);
/* Ctl exports */
+#ifndef __LP64__
extern PyObject *CtlObj_New(ControlHandle);
extern int CtlObj_Convert(PyObject *, ControlHandle *);
+#endif /* !__LP64__ */
/* Dlg exports */
+#ifndef __LP64__
extern PyObject *DlgObj_New(DialogPtr);
extern int DlgObj_Convert(PyObject *, DialogPtr *);
extern PyObject *DlgObj_WhichDialog(DialogPtr);
+#endif /* !__LP64__ */
/* Drag exports */
+#ifndef __LP64__
extern PyObject *DragObj_New(DragReference);
extern int DragObj_Convert(PyObject *, DragReference *);
+#endif /* !__LP64__ */
/* List exports */
+#ifndef __LP64__
extern PyObject *ListObj_New(ListHandle);
extern int ListObj_Convert(PyObject *, ListHandle *);
+#endif /* !__LP64__ */
/* Menu exports */
+#ifndef __LP64__
extern PyObject *MenuObj_New(MenuHandle);
extern int MenuObj_Convert(PyObject *, MenuHandle *);
+#endif /* !__LP64__ */
/* Qd exports */
+#ifndef __LP64__
extern PyObject *GrafObj_New(GrafPtr);
extern int GrafObj_Convert(PyObject *, GrafPtr *);
extern PyObject *BMObj_New(BitMapPtr);
extern int BMObj_Convert(PyObject *, BitMapPtr *);
extern PyObject *QdRGB_New(RGBColor *);
extern int QdRGB_Convert(PyObject *, RGBColor *);
+#endif /* !__LP64__ */
/* Qdoffs exports */
+#ifndef __LP64__
extern PyObject *GWorldObj_New(GWorldPtr);
extern int GWorldObj_Convert(PyObject *, GWorldPtr *);
+#endif /* !__LP64__ */
/* Qt exports */
+#ifndef __LP64__
extern PyObject *TrackObj_New(Track);
extern int TrackObj_Convert(PyObject *, Track *);
extern PyObject *MovieObj_New(Movie);
@@ -146,6 +169,7 @@
extern int UserDataObj_Convert(PyObject *, UserData *);
extern PyObject *MediaObj_New(Media);
extern int MediaObj_Convert(PyObject *, Media *);
+#endif /* !__LP64__ */
/* Res exports */
extern PyObject *ResObj_New(Handle);
@@ -154,13 +178,17 @@
extern int OptResObj_Convert(PyObject *, Handle *);
/* TE exports */
+#ifndef __LP64__
extern PyObject *TEObj_New(TEHandle);
extern int TEObj_Convert(PyObject *, TEHandle *);
+#endif /* !__LP64__ */
/* Win exports */
+#ifndef __LP64__
extern PyObject *WinObj_New(WindowPtr);
extern int WinObj_Convert(PyObject *, WindowPtr *);
extern PyObject *WinObj_WhichWindow(WindowPtr);
+#endif /* !__LP64__ */
/* CF exports */
extern PyObject *CFObj_New(CFTypeRef);
Modified: python/branches/tlee-ast-optimize/Lib/distutils/sysconfig.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/distutils/sysconfig.py (original)
+++ python/branches/tlee-ast-optimize/Lib/distutils/sysconfig.py Thu Jun 5 17:42:10 2008
@@ -539,6 +539,26 @@
flags = re.sub('-isysroot [^ \t]*', ' ', flags)
_config_vars[key] = flags
+ else:
+
+ # Allow the user to override the architecture flags using
+ # an environment variable.
+ # NOTE: This name was introduced by Apple in OSX 10.5 and
+ # is used by several scripting languages distributed with
+ # that OS release.
+
+ if 'ARCHFLAGS' in os.environ:
+ arch = os.environ['ARCHFLAGS']
+ for key in ('LDFLAGS', 'BASECFLAGS',
+ # a number of derived variables. These need to be
+ # patched up as well.
+ 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
+
+ flags = _config_vars[key]
+ flags = re.sub('-arch\s+\w+\s', ' ', flags)
+ flags = flags + ' ' + arch
+ _config_vars[key] = flags
+
if args:
vals = []
for name in args:
Modified: python/branches/tlee-ast-optimize/Lib/distutils/unixccompiler.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/distutils/unixccompiler.py (original)
+++ python/branches/tlee-ast-optimize/Lib/distutils/unixccompiler.py Thu Jun 5 17:42:10 2008
@@ -64,7 +64,7 @@
stripArch = '-arch' in cc_args
stripSysroot = '-isysroot' in cc_args
- if stripArch:
+ if stripArch or 'ARCHFLAGS' in os.environ:
while 1:
try:
index = compiler_so.index('-arch')
@@ -73,6 +73,12 @@
except ValueError:
break
+ if 'ARCHFLAGS' in os.environ and not stripArch:
+ # User specified different -arch flags in the environ,
+ # see also distutils.sysconfig
+ compiler_so = compiler_so + ' ' + os.environ['ARCHFLAGS']
+
+
if stripSysroot:
try:
index = compiler_so.index('-isysroot')
Modified: python/branches/tlee-ast-optimize/Lib/distutils/util.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/distutils/util.py (original)
+++ python/branches/tlee-ast-optimize/Lib/distutils/util.py Thu Jun 5 17:42:10 2008
@@ -125,12 +125,19 @@
osname = "macosx"
- if (release + '.') < '10.4.' and \
- get_config_vars().get('UNIVERSALSDK', '').strip():
+ if (release + '.') >= '10.4.' and \
+ '-arch' in get_config_vars().get('CFLAGS', '').strip():
# The universal build will build fat binaries, but not on
# systems before 10.4
+ #
+ # Try to detect 4-way universal builds, those have machine-type
+ # 'universal' instead of 'fat'.
+
machine = 'fat'
+ if '-arch x86_64' in get_config_vars().get('CFLAGS'):
+ machine = 'universal'
+
elif machine in ('PowerPC', 'Power_Macintosh'):
# Pick a sane name for the PPC architecture.
machine = 'ppc'
Modified: python/branches/tlee-ast-optimize/Lib/lib-tk/Tkinter.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/lib-tk/Tkinter.py (original)
+++ python/branches/tlee-ast-optimize/Lib/lib-tk/Tkinter.py Thu Jun 5 17:42:10 2008
@@ -30,7 +30,7 @@
tk.mainloop()
"""
-__version__ = "$Revision: 63501 $"
+__version__ = "$Revision$"
import sys
if sys.platform == "win32":
@@ -1054,11 +1054,17 @@
if callable(v):
v = self._register(v)
elif isinstance(v, (tuple, list)):
+ nv = []
for item in v:
if not isinstance(item, (basestring, int)):
break
+ elif isinstance(item, int):
+ nv.append('%d' % item)
+ else:
+ # format it to proper Tcl code if it contains space
+ nv.append(('{%s}' if ' ' in item else '%s') % item)
else:
- v = ' '.join(map(str, v))
+ v = ' '.join(nv)
res = res + ('-'+k, v)
return res
def nametowidget(self, name):
Modified: python/branches/tlee-ast-optimize/Lib/lib-tk/turtle.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/lib-tk/turtle.py (original)
+++ python/branches/tlee-ast-optimize/Lib/lib-tk/turtle.py Thu Jun 5 17:42:10 2008
@@ -1,294 +1,3142 @@
-# LogoMation-like turtle graphics
+#
+# turtle.py: a Tkinter based turtle graphics module for Python
+# Version 1.0b1 - 31. 5. 2008
+#
+# Copyright (C) 2006 - 2008 Gregor Lingl
+# email: glingl at aon.at
+#
+# This software is provided 'as-is', without any express or implied
+# warranty. In no event will the authors be held liable for any damages
+# arising from the use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not
+# claim that you wrote the original software. If you use this software
+# in a product, an acknowledgment in the product documentation would be
+# appreciated but is not required.
+# 2. Altered source versions must be plainly marked as such, and must not be
+# misrepresented as being the original software.
+# 3. This notice may not be removed or altered from any source distribution.
+
"""
Turtle graphics is a popular way for introducing programming to
kids. It was part of the original Logo programming language developed
-by Wally Feurzeig and Seymour Papert in 1966.
+by Wally Feurzig and Seymour Papert in 1966.
Imagine a robotic turtle starting at (0, 0) in the x-y plane. Give it
the command turtle.forward(15), and it moves (on-screen!) 15 pixels in
the direction it is facing, drawing a line as it moves. Give it the
command turtle.left(25), and it rotates in-place 25 degrees clockwise.
-By combining together these and similar commands, intricate shapes and
-pictures can easily be drawn.
-"""
+By combining together these and similar commands, intricate shapes and
+pictures can easily be drawn.
+
+----- turtle.py
+
+This module is an extended reimplementation of turtle.py from the
+Python standard distribution up to Python 2.5. (See: http:\\www.python.org)
+
+It tries to keep the merits of turtle.py and to be (nearly) 100%
+compatible with it. This means in the first place to enable the
+learning programmer to use all the commands, classes and methods
+interactively when using the module from within IDLE run with
+the -n switch.
+
+Roughly it has the following features added:
+
+- Better animation of the turtle movements, especially of turning the
+ turtle. So the turtles can more easily be used as a visual feedback
+ instrument by the (beginning) programmer.
+
+- Different turtle shapes, gif-images as turtle shapes, user defined
+ and user controllable turtle shapes, among them compound
+ (multicolored) shapes. Turtle shapes can be stgretched and tilted, which
+ makes turtles zu very versatile geometrical objects.
+
+- Fine control over turtle movement and screen updates via delay(),
+ and enhanced tracer() and speed() methods.
+
+- Aliases for the most commonly used commands, like fd for forward etc.,
+ following the early Logo traditions. This reduces the boring work of
+ typing long sequences of commands, which often occur in a natural way
+ when kids try to program fancy pictures on their first encounter with
+ turtle graphcis.
+
+- Turtles now have an undo()-method with configurable undo-buffer.
+
+- Some simple commands/methods for creating event driven programs
+ (mouse-, key-, timer-events). Especially useful for programming games.
+
+- A scrollable Canvas class. The default scrollable Canvas can be
+ extended interactively as needed while playing around with the turtle(s).
+
+- A TurtleScreen class with methods controlling background color or
+ background image, window and canvas size and other properties of the
+ TurtleScreen.
+
+- There is a method, setworldcoordinates(), to install a user defined
+ coordinate-system for the TurtleScreen.
+
+- The implementation uses a 2-vector class named Vec2D, derived from tuple.
+ This class is public, so it can be imported by the application programmer,
+ which makes certain types of computations very natural and compact.
+
+- Appearance of the TurtleScreen and the Turtles at startup/import can be
+ configured by means of a turtle.cfg configuration file.
+ The default configuration mimics the appearance of the old turtle module.
+
+- If configured appropriately the module reads in docstrings from a docstring
+ dictionary in some different language, supplied separately and replaces
+ the english ones by those read in. There is a utility function
+ write_docstringdict() to write a dictionary with the original (english)
+ docstrings to disc, so it can serve as a template for translations.
+
+Behind the scenes there are some features included with possible
+extensionsin in mind. These will be commented and documented elsewhere.
+
+"""
+
+_ver = "turtle 1.0b1 - for Python 2.6 - 30. 5. 2008, 18:08"
+
+#print _ver
+
+import Tkinter as TK
+import types
+import math
+import time
+import os
+
+from os.path import isfile, split, join
+from copy import deepcopy
+
+from math import * ## for compatibility with old turtle module
+
+_tg_classes = ['ScrolledCanvas', 'TurtleScreen', 'Screen',
+ 'RawTurtle', 'Turtle', 'RawPen', 'Pen', 'Shape', 'Vec2D']
+_tg_screen_functions = ['addshape', 'bgcolor', 'bgpic', 'bye',
+ 'clearscreen', 'colormode', 'delay', 'exitonclick', 'getcanvas',
+ 'getshapes', 'listen', 'mode', 'onkey', 'onscreenclick', 'ontimer',
+ 'register_shape', 'resetscreen', 'screensize', 'setup',
+ 'setworldcoordinates', 'title', 'tracer', 'turtles', 'update',
+ 'window_height', 'window_width']
+_tg_turtle_functions = ['back', 'backward', 'begin_fill', 'begin_poly', 'bk',
+ 'circle', 'clear', 'clearstamp', 'clearstamps', 'clone', 'color',
+ 'degrees', 'distance', 'dot', 'down', 'end_fill', 'end_poly', 'fd',
+ 'fill', 'fillcolor', 'forward', 'get_poly', 'getpen', 'getscreen',
+ 'getturtle', 'goto', 'heading', 'hideturtle', 'home', 'ht', 'isdown',
+ 'isvisible', 'left', 'lt', 'onclick', 'ondrag', 'onrelease', 'pd',
+ 'pen', 'pencolor', 'pendown', 'pensize', 'penup', 'pos', 'position',
+ 'pu', 'radians', 'right', 'reset', 'resizemode', 'rt',
+ 'seth', 'setheading', 'setpos', 'setposition', 'settiltangle',
+ 'setundobuffer', 'setx', 'sety', 'shape', 'shapesize', 'showturtle',
+ 'speed', 'st', 'stamp', 'tilt', 'tiltangle', 'towards', 'tracer',
+ 'turtlesize', 'undo', 'undobufferentries', 'up', 'width',
+ 'window_height', 'window_width', 'write', 'xcor', 'ycor']
+_tg_utilities = ['write_docstringdict', 'done', 'mainloop']
+_math_functions = ['acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh',
+ 'e', 'exp', 'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log',
+ 'log10', 'modf', 'pi', 'pow', 'sin', 'sinh', 'sqrt', 'tan', 'tanh']
+
+__all__ = (_tg_classes + _tg_screen_functions + _tg_turtle_functions +
+ _tg_utilities + _math_functions)
+
+_alias_list = ['addshape', 'backward', 'bk', 'fd', 'ht', 'lt', 'pd', 'pos',
+ 'pu', 'rt', 'seth', 'setpos', 'setposition', 'st',
+ 'turtlesize', 'up', 'width']
+
+_CFG = {"width" : 0.5, # Screen
+ "height" : 0.75,
+ "canvwidth" : 400,
+ "canvheight": 300,
+ "leftright": None,
+ "topbottom": None,
+ "mode": "standard", # TurtleScreen
+ "colormode": 1.0,
+ "delay": 10,
+ "undobuffersize": 1000, # RawTurtle
+ "shape": "classic",
+ "pencolor" : "black",
+ "fillcolor" : "black",
+ "resizemode" : "noresize",
+ "visible" : True,
+ "language": "english", # docstrings
+ "exampleturtle": "turtle",
+ "examplescreen": "screen",
+ "title": "Python Turtle Graphics",
+ "using_IDLE": False
+ }
+
+##print "cwd:", os.getcwd()
+##print "__file__:", __file__
+##
+##def show(dictionary):
+## print "=========================="
+## for key in sorted(dictionary.keys()):
+## print key, ":", dictionary[key]
+## print "=========================="
+## print
+
+def config_dict(filename):
+ """Convert content of config-file into dictionary."""
+ f = open(filename, "r")
+ cfglines = f.readlines()
+ f.close()
+ cfgdict = {}
+ for line in cfglines:
+ line = line.strip()
+ if not line or line.startswith("#"):
+ continue
+ try:
+ key, value = line.split("=")
+ except:
+ print "Bad line in config-file %s:\n%s" % (filename,line)
+ continue
+ key = key.strip()
+ value = value.strip()
+ if value in ["True", "False", "None", "''", '""']:
+ value = eval(value)
+ else:
+ try:
+ if "." in value:
+ value = float(value)
+ else:
+ value = int(value)
+ except:
+ pass # value need not be converted
+ cfgdict[key] = value
+ return cfgdict
+
+def readconfig(cfgdict):
+ """Read config-files, change configuration-dict accordingly.
+
+ If there is a turtle.cfg file in the current working directory,
+ read it from there. If this contains an importconfig-value,
+ say 'myway', construct filename turtle_mayway.cfg else use
+ turtle.cfg and read it from the import-directory, where
+ turtle.py is located.
+ Update configuration dictionary first according to config-file,
+ in the import directory, then according to config-file in the
+ current working directory.
+ If no config-file is found, the default configuration is used.
+ """
+ default_cfg = "turtle.cfg"
+ cfgdict1 = {}
+ cfgdict2 = {}
+ if isfile(default_cfg):
+ cfgdict1 = config_dict(default_cfg)
+ #print "1. Loading config-file %s from: %s" % (default_cfg, os.getcwd())
+ if "importconfig" in cfgdict1:
+ default_cfg = "turtle_%s.cfg" % cfgdict1["importconfig"]
+ try:
+ head, tail = split(__file__)
+ cfg_file2 = join(head, default_cfg)
+ except:
+ cfg_file2 = ""
+ if isfile(cfg_file2):
+ #print "2. Loading config-file %s:" % cfg_file2
+ cfgdict2 = config_dict(cfg_file2)
+## show(_CFG)
+## show(cfgdict2)
+ _CFG.update(cfgdict2)
+## show(_CFG)
+## show(cfgdict1)
+ _CFG.update(cfgdict1)
+## show(_CFG)
+
+try:
+ readconfig(_CFG)
+except:
+ print "No configfile read, reason unknown"
+
+
+class Vec2D(tuple):
+ """A 2 dimensional vector class, used as a helper class
+ for implementing turtle graphics.
+ May be useful for turtle graphics programs also.
+ Derived from tuple, so a vector is a tuple!
+
+ Provides (for a, b vectors, k number):
+ a+b vector addition
+ a-b vector subtraction
+ a*b inner product
+ k*a and a*k multiplication with scalar
+ |a| absolute value of a
+ a.rotate(angle) rotation
+ """
+ def __new__(cls, x, y):
+ return tuple.__new__(cls, (x, y))
+ def __add__(self, other):
+ return Vec2D(self[0]+other[0], self[1]+other[1])
+ def __mul__(self, other):
+ if isinstance(other, Vec2D):
+ return self[0]*other[0]+self[1]*other[1]
+ return Vec2D(self[0]*other, self[1]*other)
+ def __rmul__(self, other):
+ if isinstance(other, int) or isinstance(other, float):
+ return Vec2D(self[0]*other, self[1]*other)
+ def __sub__(self, other):
+ return Vec2D(self[0]-other[0], self[1]-other[1])
+ def __neg__(self):
+ return Vec2D(-self[0], -self[1])
+ def __abs__(self):
+ return (self[0]**2 + self[1]**2)**0.5
+ def rotate(self, angle):
+ """rotate self counterclockwise by angle
+ """
+ perp = Vec2D(-self[1], self[0])
+ angle = angle * math.pi / 180.0
+ c, s = math.cos(angle), math.sin(angle)
+ return Vec2D(self[0]*c+perp[0]*s, self[1]*c+perp[1]*s)
+ def __getnewargs__(self):
+ return (self[0], self[1])
+ def __repr__(self):
+ return "(%.2f,%.2f)" % self
+
+
+##############################################################################
+### From here up to line : Tkinter - Interface for turtle.py ###
+### May be replaced by an interface to some different graphcis-toolkit ###
+##############################################################################
+
+## helper functions for Scrolled Canvas, to forward Canvas-methods
+## to ScrolledCanvas class
+
+def __methodDict(cls, _dict):
+ """helper function for Scrolled Canvas"""
+ baseList = list(cls.__bases__)
+ baseList.reverse()
+ for _super in baseList:
+ __methodDict(_super, _dict)
+ for key, value in cls.__dict__.items():
+ if type(value) == types.FunctionType:
+ _dict[key] = value
+
+def __methods(cls):
+ """helper function for Scrolled Canvas"""
+ _dict = {}
+ __methodDict(cls, _dict)
+ return _dict.keys()
+
+__stringBody = (
+ 'def %(method)s(self, *args, **kw): return ' +
+ 'self.%(attribute)s.%(method)s(*args, **kw)')
+
+def __forwardmethods(fromClass, toClass, toPart, exclude = ()):
+ """Helper functions for Scrolled Canvas, used to forward
+ ScrolledCanvas-methods to Tkinter.Canvas class.
+ """
+ _dict = {}
+ __methodDict(toClass, _dict)
+ for ex in _dict.keys():
+ if ex[:1] == '_' or ex[-1:] == '_':
+ del _dict[ex]
+ for ex in exclude:
+ if _dict.has_key(ex):
+ del _dict[ex]
+ for ex in __methods(fromClass):
+ if _dict.has_key(ex):
+ del _dict[ex]
+
+ for method, func in _dict.items():
+ d = {'method': method, 'func': func}
+ if type(toPart) == types.StringType:
+ execString = \
+ __stringBody % {'method' : method, 'attribute' : toPart}
+ exec execString in d
+ fromClass.__dict__[method] = d[method]
+
+
+class ScrolledCanvas(TK.Frame):
+ """Modeled after the scrolled canvas class from Grayons's Tkinter book.
+
+ Used as the default canvas, which pops up automatically when
+ using turtle graphics functions or the Turtle class.
+ """
+ def __init__(self, master, width=500, height=350,
+ canvwidth=600, canvheight=500):
+ TK.Frame.__init__(self, master, width=width, height=height)
+ self._root = self.winfo_toplevel()
+ self.width, self.height = width, height
+ self.canvwidth, self.canvheight = canvwidth, canvheight
+ self.bg = "white"
+ self._canvas = TK.Canvas(master, width=width, height=height,
+ bg=self.bg, relief=TK.SUNKEN, borderwidth=2)
+ self.hscroll = TK.Scrollbar(master, command=self._canvas.xview,
+ orient=TK.HORIZONTAL)
+ self.vscroll = TK.Scrollbar(master, command=self._canvas.yview)
+ self._canvas.configure(xscrollcommand=self.hscroll.set,
+ yscrollcommand=self.vscroll.set)
+ self.rowconfigure(0, weight=1, minsize=0)
+ self.columnconfigure(0, weight=1, minsize=0)
+ self._canvas.grid(padx=1, in_ = self, pady=1, row=0,
+ column=0, rowspan=1, columnspan=1, sticky='news')
+ self.vscroll.grid(padx=1, in_ = self, pady=1, row=0,
+ column=1, rowspan=1, columnspan=1, sticky='news')
+ self.hscroll.grid(padx=1, in_ = self, pady=1, row=1,
+ column=0, rowspan=1, columnspan=1, sticky='news')
+ self.reset()
+ self._root.bind('<Configure>', self.onResize)
+
+ def reset(self, canvwidth=None, canvheight=None, bg = None):
+ """Ajust canvas and scrollbars according to given canvas size."""
+ if canvwidth:
+ self.canvwidth = canvwidth
+ if canvheight:
+ self.canvheight = canvheight
+ if bg:
+ self.bg = bg
+ self._canvas.config(bg=bg,
+ scrollregion=(-self.canvwidth//2, -self.canvheight//2,
+ self.canvwidth//2, self.canvheight//2))
+ self._canvas.xview_moveto(0.5*(self.canvwidth - self.width + 30) /
+ self.canvwidth)
+ self._canvas.yview_moveto(0.5*(self.canvheight- self.height + 30) /
+ self.canvheight)
+ self.adjustScrolls()
+
+
+ def adjustScrolls(self):
+ """ Adjust scrollbars according to window- and canvas-size.
+ """
+ cwidth = self._canvas.winfo_width()
+ cheight = self._canvas.winfo_height()
+ self._canvas.xview_moveto(0.5*(self.canvwidth-cwidth)/self.canvwidth)
+ self._canvas.yview_moveto(0.5*(self.canvheight-cheight)/self.canvheight)
+ if cwidth < self.canvwidth or cheight < self.canvheight:
+ self.hscroll.grid(padx=1, in_ = self, pady=1, row=1,
+ column=0, rowspan=1, columnspan=1, sticky='news')
+ self.vscroll.grid(padx=1, in_ = self, pady=1, row=0,
+ column=1, rowspan=1, columnspan=1, sticky='news')
+ else:
+ self.hscroll.grid_forget()
+ self.vscroll.grid_forget()
+
+ def onResize(self, event):
+ """self-explanatory"""
+ self.adjustScrolls()
+
+ def bbox(self, *args):
+ """ 'forward' method, which canvas itself has inherited...
+ """
+ return self._canvas.bbox(*args)
+
+ def cget(self, *args, **kwargs):
+ """ 'forward' method, which canvas itself has inherited...
+ """
+ return self._canvas.cget(*args, **kwargs)
+
+ def config(self, *args, **kwargs):
+ """ 'forward' method, which canvas itself has inherited...
+ """
+ self._canvas.config(*args, **kwargs)
+
+ def bind(self, *args, **kwargs):
+ """ 'forward' method, which canvas itself has inherited...
+ """
+ self._canvas.bind(*args, **kwargs)
+
+ def unbind(self, *args, **kwargs):
+ """ 'forward' method, which canvas itself has inherited...
+ """
+ self._canvas.unbind(*args, **kwargs)
+
+ def focus_force(self):
+ """ 'forward' method, which canvas itself has inherited...
+ """
+ self._canvas.focus_force()
+
+__forwardmethods(ScrolledCanvas, TK.Canvas, '_canvas')
+
+
+class _Root(TK.Tk):
+ """Root class for Screen based on Tkinter."""
+ def __init__(self):
+ TK.Tk.__init__(self)
+
+ def setupcanvas(self, width, height, cwidth, cheight):
+ self._canvas = ScrolledCanvas(self, width, height, cwidth, cheight)
+ self._canvas.pack(expand=1, fill="both")
+
+ def _getcanvas(self):
+ return self._canvas
+
+ def set_geometry(self, width, height, startx, starty):
+ self.geometry("%dx%d%+d%+d"%(width, height, startx, starty))
+
+ def ondestroy(self, destroy):
+ self.wm_protocol("WM_DELETE_WINDOW", destroy)
+
+ def win_width(self):
+ return self.winfo_screenwidth()
+
+ def win_height(self):
+ return self.winfo_screenheight()
+
+Canvas = TK.Canvas
+
+
+class TurtleScreenBase(object):
+ """Provide the basic graphics functionality.
+ Interface between Tkinter and turtle.py.
+
+ To port turtle.py to some different graphics toolkit
+ a corresponding TurtleScreenBase class has to be implemented.
+ """
+
+ @staticmethod
+ def _blankimage():
+ """return a blank image object
+ """
+ img = TK.PhotoImage(width=1, height=1)
+ img.blank()
+ return img
+
+ @staticmethod
+ def _image(filename):
+ """return an image object containing the
+ imagedata from a gif-file named filename.
+ """
+ return TK.PhotoImage(file=filename)
+
+ def __init__(self, cv):
+ self.cv = cv
+ if isinstance(cv, ScrolledCanvas):
+ w = self.cv.canvwidth
+ h = self.cv.canvheight
+ else: # expected: ordinary TK.Canvas
+ w = int(self.cv.cget("width"))
+ h = int(self.cv.cget("height"))
+ self.cv.config(scrollregion = (-w//2, -h//2, w//2, h//2 ))
+ self.canvwidth = w
+ self.canvheight = h
+ self.xscale = self.yscale = 1.0
+
+ def _createpoly(self):
+ """Create an invisible polygon item on canvas self.cv)
+ """
+ return self.cv.create_polygon((0, 0, 0, 0, 0, 0), fill="", outline="")
+
+ def _drawpoly(self, polyitem, coordlist, fill=None,
+ outline=None, width=None, top=False):
+ """Configure polygonitem polyitem according to provided
+ arguments:
+ coordlist is sequence of coordinates
+ fill is filling color
+ outline is outline color
+ top is a boolean value, which specifies if polyitem
+ will be put on top of the canvas' displaylist so it
+ will not be covered by other items.
+ """
+ cl = []
+ for x, y in coordlist:
+ cl.append(x * self.xscale)
+ cl.append(-y * self.yscale)
+ self.cv.coords(polyitem, *cl)
+ if fill is not None:
+ self.cv.itemconfigure(polyitem, fill=fill)
+ if outline is not None:
+ self.cv.itemconfigure(polyitem, outline=outline)
+ if width is not None:
+ self.cv.itemconfigure(polyitem, width=width)
+ if top:
+ self.cv.tag_raise(polyitem)
+
+ def _createline(self):
+ """Create an invisible line item on canvas self.cv)
+ """
+ return self.cv.create_line(0, 0, 0, 0, fill="", width=2,
+ capstyle = TK.ROUND)
+
+ def _drawline(self, lineitem, coordlist=None,
+ fill=None, width=None, top=False):
+ """Configure lineitem according to provided arguments:
+ coordlist is sequence of coordinates
+ fill is drawing color
+ width is width of drawn line.
+ top is a boolean value, which specifies if polyitem
+ will be put on top of the canvas' displaylist so it
+ will not be covered by other items.
+ """
+ if coordlist is not None:
+ cl = []
+ for x, y in coordlist:
+ cl.append(x * self.xscale)
+ cl.append(-y * self.yscale)
+ self.cv.coords(lineitem, *cl)
+ if fill is not None:
+ self.cv.itemconfigure(lineitem, fill=fill)
+ if width is not None:
+ self.cv.itemconfigure(lineitem, width=width)
+ if top:
+ self.cv.tag_raise(lineitem)
+
+ def _delete(self, item):
+ """Delete graphics item from canvas.
+ If item is"all" delete all graphics items.
+ """
+ self.cv.delete(item)
+
+ def _update(self):
+ """Redraw graphics items on canvas
+ """
+ self.cv.update()
+
+ def _delay(self, delay):
+ """Delay subsequent canvas actions for delay ms."""
+ self.cv.after(delay)
+
+ def _iscolorstring(self, color):
+ """Check if the string color is a legal Tkinter color string.
+ """
+ try:
+ rgb = self.cv.winfo_rgb(color)
+ ok = True
+ except TK.TclError:
+ ok = False
+ return ok
+
+ def _bgcolor(self, color=None):
+ """Set canvas' backgroundcolor if color is not None,
+ else return backgroundcolor."""
+ if color is not None:
+ self.cv.config(bg = color)
+ self._update()
+ else:
+ return self.cv.cget("bg")
+
+ def _write(self, pos, txt, align, font, pencolor):
+ """Write txt at pos in canvas with specified font
+ and color.
+ Return text item and x-coord of right bottom corner
+ of text's bounding box."""
+ x, y = pos
+ x = x * self.xscale
+ y = y * self.yscale
+ anchor = {"left":"sw", "center":"s", "right":"se" }
+ item = self.cv.create_text(x-1, -y, text = txt, anchor = anchor[align],
+ fill = pencolor, font = font)
+ x0, y0, x1, y1 = self.cv.bbox(item)
+ self.cv.update()
+ return item, x1-1
+
+## def _dot(self, pos, size, color):
+## """may be implemented for some other graphics toolkit"""
+
+ def _onclick(self, item, fun, num=1, add=None):
+ """Bind fun to mouse-click event on turtle.
+ fun must be a function with two arguments, the coordinates
+ of the clicked point on the canvas.
+ num, the number of the mouse-button defaults to 1
+ """
+ if fun is None:
+ self.cv.tag_unbind(item, "<Button-%s>" % num)
+ else:
+ def eventfun(event):
+ x, y = (self.cv.canvasx(event.x)/self.xscale,
+ -self.cv.canvasy(event.y)/self.yscale)
+ fun(x, y)
+ self.cv.tag_bind(item, "<Button-%s>" % num, eventfun, add)
+
+ def _onrelease(self, item, fun, num=1, add=None):
+ """Bind fun to mouse-button-release event on turtle.
+ fun must be a function with two arguments, the coordinates
+ of the point on the canvas where mouse button is released.
+ num, the number of the mouse-button defaults to 1
+
+ If a turtle is clicked, first _onclick-event will be performed,
+ then _onscreensclick-event.
+ """
+ if fun is None:
+ self.cv.tag_unbind(item, "<Button%s-ButtonRelease>" % num)
+ else:
+ def eventfun(event):
+ x, y = (self.cv.canvasx(event.x)/self.xscale,
+ -self.cv.canvasy(event.y)/self.yscale)
+ fun(x, y)
+ self.cv.tag_bind(item, "<Button%s-ButtonRelease>" % num,
+ eventfun, add)
+
+ def _ondrag(self, item, fun, num=1, add=None):
+ """Bind fun to mouse-move-event (with pressed mouse button) on turtle.
+ fun must be a function with two arguments, the coordinates of the
+ actual mouse position on the canvas.
+ num, the number of the mouse-button defaults to 1
+
+ Every sequence of mouse-move-events on a turtle is preceded by a
+ mouse-click event on that turtle.
+ """
+ if fun is None:
+ self.cv.tag_unbind(item, "<Button%s-Motion>" % num)
+ else:
+ def eventfun(event):
+ try:
+ x, y = (self.cv.canvasx(event.x)/self.xscale,
+ -self.cv.canvasy(event.y)/self.yscale)
+ fun(x, y)
+ except:
+ pass
+ self.cv.tag_bind(item, "<Button%s-Motion>" % num, eventfun, add)
+
+ def _onscreenclick(self, fun, num=1, add=None):
+ """Bind fun to mouse-click event on canvas.
+ fun must be a function with two arguments, the coordinates
+ of the clicked point on the canvas.
+ num, the number of the mouse-button defaults to 1
+
+ If a turtle is clicked, first _onclick-event will be performed,
+ then _onscreensclick-event.
+ """
+ if fun is None:
+ self.cv.unbind("<Button-%s>" % num)
+ else:
+ def eventfun(event):
+ x, y = (self.cv.canvasx(event.x)/self.xscale,
+ -self.cv.canvasy(event.y)/self.yscale)
+ fun(x, y)
+ self.cv.bind("<Button-%s>" % num, eventfun, add)
+
+ def _onkey(self, fun, key):
+ """Bind fun to key-release event of key.
+ Canvas must have focus. See method listen
+ """
+ if fun is None:
+ self.cv.unbind("<KeyRelease-%s>" % key, None)
+ else:
+ def eventfun(event):
+ fun()
+ self.cv.bind("<KeyRelease-%s>" % key, eventfun)
+
+ def _listen(self):
+ """Set focus on canvas (in order to collect key-events)
+ """
+ self.cv.focus_force()
+
+ def _ontimer(self, fun, t):
+ """Install a timer, which calls fun after t milliseconds.
+ """
+ if t == 0:
+ self.cv.after_idle(fun)
+ else:
+ self.cv.after(t, fun)
+
+ def _createimage(self, image):
+ """Create and return image item on canvas.
+ """
+ return self.cv.create_image(0, 0, image=image)
+
+ def _drawimage(self, item, (x, y), image):
+ """Configure image item as to draw image object
+ at position (x,y) on canvas)
+ """
+ self.cv.coords(item, (x, -y))
+ self.cv.itemconfig(item, image=image)
+
+ def _setbgpic(self, item, image):
+ """Configure image item as to draw image object
+ at center of canvas. Set item to the first item
+ in the displaylist, so it will be drawn below
+ any other item ."""
+ self.cv.itemconfig(item, image=image)
+ self.cv.tag_lower(item)
+
+ def _type(self, item):
+ """Return 'line' or 'polygon' or 'image' depending on
+ type of item.
+ """
+ return self.cv.type(item)
+
+ def _pointlist(self, item):
+ """returns list of coordinate-pairs of points of item
+ Example (for insiders):
+ >>> from turtle import *
+ >>> getscreen()._pointlist(getturtle().turtle._item)
+ [(0.0, 9.9999999999999982), (0.0, -9.9999999999999982),
+ (9.9999999999999982, 0.0)]
+ >>> """
+ cl = self.cv.coords(item)
+ pl = [(cl[i], -cl[i+1]) for i in range(0, len(cl), 2)]
+ return pl
+
+ def _setscrollregion(self, srx1, sry1, srx2, sry2):
+ self.cv.config(scrollregion=(srx1, sry1, srx2, sry2))
+
+ def _rescale(self, xscalefactor, yscalefactor):
+ items = self.cv.find_all()
+ for item in items:
+ coordinates = self.cv.coords(item)
+ newcoordlist = []
+ while coordinates:
+ x, y = coordinates[:2]
+ newcoordlist.append(x * xscalefactor)
+ newcoordlist.append(y * yscalefactor)
+ coordinates = coordinates[2:]
+ self.cv.coords(item, *newcoordlist)
+
+ def _resize(self, canvwidth=None, canvheight=None, bg=None):
+ """Resize the canvas, the turtles are drawing on. Does
+ not alter the drawing window.
+ """
+ # needs amendment
+ if not isinstance(self.cv, ScrolledCanvas):
+ return self.canvwidth, self.canvheight
+ if canvwidth is None and canvheight is None and bg is None:
+ return self.cv.canvwidth, self.cv.canvheight
+ if canvwidth is not None:
+ self.canvwidth = canvwidth
+ if canvheight is not None:
+ self.canvheight = canvheight
+ self.cv.reset(canvwidth, canvheight, bg)
+
+ def _window_size(self):
+ """ Return the width and height of the turtle window.
+ """
+ width = self.cv.winfo_width()
+ if width <= 1: # the window isn't managed by a geometry manager
+ width = self.cv['width']
+ height = self.cv.winfo_height()
+ if height <= 1: # the window isn't managed by a geometry manager
+ height = self.cv['height']
+ return width, height
+
+
+##############################################################################
+### End of Tkinter - interface ###
+##############################################################################
+
+
+class Terminator (Exception):
+ """Will be raised in TurtleScreen.update, if _RUNNING becomes False.
+
+ Thus stops execution of turtle graphics script. Main purpose: use in
+ in the Demo-Viewer turtle.Demo.py.
+ """
+ pass
+
+
+class TurtleGraphicsError(Exception):
+ """Some TurtleGraphics Error
+ """
+
+
+class Shape(object):
+ """Data structure modeling shapes.
+
+ attribute _type is one of "polygon", "image", "compound"
+ attribute _data is - depending on _type a poygon-tuple,
+ an image or a list constructed using the addcomponent method.
+ """
+ def __init__(self, type_, data=None):
+ self._type = type_
+ if type_ == "polygon":
+ if isinstance(data, list):
+ data = tuple(data)
+ elif type_ == "image":
+ if isinstance(data, str):
+ if data.lower().endswith(".gif") and isfile(data):
+ data = TurtleScreen._image(data)
+ # else data assumed to be Photoimage
+ elif type_ == "compound":
+ data = []
+ else:
+ raise TurtleGraphicsError("There is no shape type %s" % type_)
+ self._data = data
+
+ def addcomponent(self, poly, fill, outline=None):
+ """Add component to a shape of type compound.
+
+ Arguments: poly is a polygon, i. e. a tuple of number pairs.
+ fill is the fillcolor of the component,
+ outline is the outline color of the component.
+
+ call (for a Shapeobject namend s):
+ -- s.addcomponent(((0,0), (10,10), (-10,10)), "red", "blue")
+
+ Example:
+ >>> poly = ((0,0),(10,-5),(0,10),(-10,-5))
+ >>> s = Shape("compound")
+ >>> s.addcomponent(poly, "red", "blue")
+ ### .. add more components and then use register_shape()
+ """
+ if self._type != "compound":
+ raise TurtleGraphicsError("Cannot add component to %s Shape"
+ % self._type)
+ if outline is None:
+ outline = fill
+ self._data.append([poly, fill, outline])
+
+
+class Tbuffer(object):
+ """Ring buffer used as undobuffer for RawTurtle objects."""
+ def __init__(self, bufsize=10):
+ self.bufsize = bufsize
+ self.buffer = [[None]] * bufsize
+ self.ptr = -1
+ self.cumulate = False
+ def reset(self, bufsize=None):
+ if bufsize is None:
+ for i in range(self.bufsize):
+ self.buffer[i] = [None]
+ else:
+ self.bufsize = bufsize
+ self.buffer = [[None]] * bufsize
+ self.ptr = -1
+ def push(self, item):
+ if self.bufsize > 0:
+ if not self.cumulate:
+ self.ptr = (self.ptr + 1) % self.bufsize
+ self.buffer[self.ptr] = item
+ else:
+ self.buffer[self.ptr].append(item)
+ def pop(self):
+ if self.bufsize > 0:
+ item = self.buffer[self.ptr]
+ if item is None:
+ return None
+ else:
+ self.buffer[self.ptr] = [None]
+ self.ptr = (self.ptr - 1) % self.bufsize
+ return (item)
+ def nr_of_items(self):
+ return self.bufsize - self.buffer.count([None])
+ def __repr__(self):
+ return str(self.buffer) + " " + str(self.ptr)
+
+
+
+class TurtleScreen(TurtleScreenBase):
+ """Provides screen oriented methods like setbg etc.
+
+ Only relies upon the methods of TurtleScreenBase and NOT
+ upon components of the underlying graphics toolkit -
+ which is Tkinter in this case.
+ """
+# _STANDARD_DELAY = 5
+ _RUNNING = True
+
+ def __init__(self, cv, mode=_CFG["mode"],
+ colormode=_CFG["colormode"], delay=_CFG["delay"]):
+ self._shapes = {
+ "arrow" : Shape("polygon", ((-10,0), (10,0), (0,10))),
+ "turtle" : Shape("polygon", ((0,16), (-2,14), (-1,10), (-4,7),
+ (-7,9), (-9,8), (-6,5), (-7,1), (-5,-3), (-8,-6),
+ (-6,-8), (-4,-5), (0,-7), (4,-5), (6,-8), (8,-6),
+ (5,-3), (7,1), (6,5), (9,8), (7,9), (4,7), (1,10),
+ (2,14))),
+ "circle" : Shape("polygon", ((10,0), (9.51,3.09), (8.09,5.88),
+ (5.88,8.09), (3.09,9.51), (0,10), (-3.09,9.51),
+ (-5.88,8.09), (-8.09,5.88), (-9.51,3.09), (-10,0),
+ (-9.51,-3.09), (-8.09,-5.88), (-5.88,-8.09),
+ (-3.09,-9.51), (-0.00,-10.00), (3.09,-9.51),
+ (5.88,-8.09), (8.09,-5.88), (9.51,-3.09))),
+ "square" : Shape("polygon", ((10,-10), (10,10), (-10,10),
+ (-10,-10))),
+ "triangle" : Shape("polygon", ((10,-5.77), (0,11.55),
+ (-10,-5.77))),
+ "classic": Shape("polygon", ((0,0),(-5,-9),(0,-7),(5,-9))),
+ "blank" : Shape("image", self._blankimage())
+ }
+
+ self._bgpics = {"nopic" : ""}
+
+ TurtleScreenBase.__init__(self, cv)
+ self._mode = mode
+ self._delayvalue = delay
+ self._colormode = _CFG["colormode"]
+ self._keys = []
+ self.clear()
+
+ def clear(self):
+ """Delete all drawings and all turtles from the TurtleScreen.
+
+ Reset empty TurtleScreen to it's initial state: white background,
+ no backgroundimage, no eventbindings and tracing on.
+
+ No argument.
+
+ Example (for a TurtleScreen instance named screen):
+ screen.clear()
+
+ Note: this method is not available as function.
+ """
+ self._delayvalue = _CFG["delay"]
+ self._colormode = _CFG["colormode"]
+ self._delete("all")
+ self._bgpic = self._createimage("")
+ self._bgpicname = "nopic"
+ self._tracing = 1
+ self._updatecounter = 0
+ self._turtles = []
+ self.bgcolor("white")
+ for btn in 1, 2, 3:
+ self.onclick(None, btn)
+ for key in self._keys[:]:
+ self.onkey(None, key)
+ Turtle._pen = None
+
+ def mode(self, mode=None):
+ """Set turtle-mode ('standard', 'logo' or 'world') and perform reset.
+
+ Optional argument:
+ mode -- on of the strings 'standard', 'logo' or 'world'
+
+ Mode 'standard' is compatible with turtle.py.
+ Mode 'logo' is compatible with most Logo-Turtle-Graphics.
+ Mode 'world' uses userdefined 'worldcoordinates'. *Attention*: in
+ this mode angles appear distorted if x/y unit-ratio doesn't equal 1.
+ If mode is not given, return the current mode.
+
+ Mode Initial turtle heading positive angles
+ ------------|-------------------------|-------------------
+ 'standard' to the right (east) counterclockwise
+ 'logo' upward (north) clockwise
+
+ Examples:
+ >>> mode('logo') # resets turtle heading to north
+ >>> mode()
+ 'logo'
+ """
+ if mode == None:
+ return self._mode
+ mode = mode.lower()
+ if mode not in ["standard", "logo", "world"]:
+ raise TurtleGraphicsError("No turtle-graphics-mode %s" % mode)
+ self._mode = mode
+ if mode in ["standard", "logo"]:
+ self._setscrollregion(-self.canvwidth//2, -self.canvheight//2,
+ self.canvwidth//2, self.canvheight//2)
+ self.xscale = self.yscale = 1.0
+ self.reset()
+
+ def setworldcoordinates(self, llx, lly, urx, ury):
+ """Set up a user defined coordinate-system.
+
+ Arguments:
+ llx -- a number, x-coordinate of lower left corner of canvas
+ lly -- a number, y-coordinate of lower left corner of canvas
+ urx -- a number, x-coordinate of upper right corner of canvas
+ ury -- a number, y-coordinate of upper right corner of canvas
+
+ Set up user coodinat-system and switch to mode 'world' if necessary.
+ This performs a screen.reset. If mode 'world' is already active,
+ all drawings are redrawn according to the new coordinates.
+
+ But ATTENTION: in user-defined coordinatesystems angles may appear
+ distorted. (see Screen.mode())
+
+ Example (for a TurtleScreen instance named screen):
+ >>> screen.setworldcoordinates(-10,-0.5,50,1.5)
+ >>> for _ in range(36):
+ left(10)
+ forward(0.5)
+ """
+ if self.mode() != "world":
+ self.mode("world")
+ xspan = float(urx - llx)
+ yspan = float(ury - lly)
+ wx, wy = self._window_size()
+ self.screensize(wx-20, wy-20)
+ oldxscale, oldyscale = self.xscale, self.yscale
+ self.xscale = self.canvwidth / xspan
+ self.yscale = self.canvheight / yspan
+ srx1 = llx * self.xscale
+ sry1 = -ury * self.yscale
+ srx2 = self.canvwidth + srx1
+ sry2 = self.canvheight + sry1
+ self._setscrollregion(srx1, sry1, srx2, sry2)
+ self._rescale(self.xscale/oldxscale, self.yscale/oldyscale)
+ self.update()
+
+ def register_shape(self, name, shape=None):
+ """Adds a turtle shape to TurtleScreen's shapelist.
+
+ Arguments:
+ (1) name is the name of a gif-file and shape is None.
+ Installs the corresponding image shape.
+ !! Image-shapes DO NOT rotate when turning the turtle,
+ !! so they do not display the heading of the turtle!
+ (2) name is an arbitrary string and shape is a tuple
+ of pairs of coordinates. Installs the corresponding
+ polygon shape
+ (3) name is an arbitrary string and shape is a
+ (compound) Shape object. Installs the corresponding
+ compound shape.
+ To use a shape, you have to issue the command shape(shapename).
+
+ call: register_shape("turtle.gif")
+ --or: register_shape("tri", ((0,0), (10,10), (-10,10)))
+
+ Example (for a TurtleScreen instance named screen):
+ >>> screen.register_shape("triangle", ((5,-3),(0,5),(-5,-3)))
+
+ """
+ if shape is None:
+ # image
+ if name.lower().endswith(".gif"):
+ shape = Shape("image", self._image(name))
+ else:
+ raise TurtleGraphicsError("Bad arguments for register_shape.\n"
+ + "Use help(register_shape)" )
+ elif isinstance(shape, tuple):
+ shape = Shape("polygon", shape)
+ ## else shape assumed to be Shape-instance
+ self._shapes[name] = shape
+ # print "shape added:" , self._shapes
+
+ def _colorstr(self, color):
+ """Return color string corresponding to args.
+
+ Argument may be a string or a tuple of three
+ numbers corresponding to actual colormode,
+ i.e. in the range 0<=n<=colormode.
+
+ If the argument doesn't represent a color,
+ an error is raised.
+ """
+ if len(color) == 1:
+ color = color[0]
+ if isinstance(color, str):
+ if self._iscolorstring(color) or color == "":
+ return color
+ else:
+ raise TurtleGraphicsError("bad color string: %s" % str(color))
+ try:
+ r, g, b = color
+ except:
+ raise TurtleGraphicsError("bad color arguments: %s" % str(color))
+ if self._colormode == 1.0:
+ r, g, b = [round(255.0*x) for x in (r, g, b)]
+ if not ((0 <= r <= 255) and (0 <= g <= 255) and (0 <= b <= 255)):
+ raise TurtleGraphicsError("bad color sequence: %s" % str(color))
+ return "#%02x%02x%02x" % (r, g, b)
+
+ def _color(self, cstr):
+ if not cstr.startswith("#"):
+ return cstr
+ if len(cstr) == 7:
+ cl = [int(cstr[i:i+2], 16) for i in (1, 3, 5)]
+ elif len(cstr) == 4:
+ cl = [16*int(cstr[h], 16) for h in cstr[1:]]
+ else:
+ raise TurtleGraphicsError("bad colorstring: %s" % cstr)
+ return tuple([c * self._colormode/255 for c in cl])
+
+ def colormode(self, cmode=None):
+ """Return the colormode or set it to 1.0 or 255.
+
+ Optional argument:
+ cmode -- one of the values 1.0 or 255
+
+ r, g, b values of colortriples have to be in range 0..cmode.
+
+ Example (for a TurtleScreen instance named screen):
+ >>> screen.colormode()
+ 1.0
+ >>> screen.colormode(255)
+ >>> turtle.pencolor(240,160,80)
+ """
+ if cmode is None:
+ return self._colormode
+ if cmode == 1.0:
+ self._colormode = float(cmode)
+ elif cmode == 255:
+ self._colormode = int(cmode)
+
+ def reset(self):
+ """Reset all Turtles on the Screen to their initial state.
+
+ No argument.
+
+ Example (for a TurtleScreen instance named screen):
+ >>> screen.reset()
+ """
+ for turtle in self._turtles:
+ turtle._setmode(self._mode)
+ turtle.reset()
+
+ def turtles(self):
+ """Return the list of turtles on the screen.
+
+ Example (for a TurtleScreen instance named screen):
+ >>> screen.turtles()
+ [<turtle.Turtle object at 0x00E11FB0>]
+ """
+ return self._turtles
+
+ def bgcolor(self, *args):
+ """Set or return backgroundcolor of the TurtleScreen.
+
+ Arguments (if given): a color string or three numbers
+ in the range 0..colormode or a 3-tuple of such numbers.
+
+ Example (for a TurtleScreen instance named screen):
+ >>> screen.bgcolor("orange")
+ >>> screen.bgcolor()
+ 'orange'
+ >>> screen.bgcolor(0.5,0,0.5)
+ >>> screen.bgcolor()
+ '#800080'
+ """
+ if args:
+ color = self._colorstr(args)
+ else:
+ color = None
+ color = self._bgcolor(color)
+ if color is not None:
+ color = self._color(color)
+ return color
+
+ def tracer(self, n=None, delay=None):
+ """Turns turtle animation on/off and set delay for update drawings.
+
+ Optional arguments:
+ n -- nonnegative integer
+ delay -- nonnegative integer
+
+ If n is given, only each n-th regular screen update is really performed.
+ (Can be used to accelerate the drawing of complex graphics.)
+ Second arguments sets delay value (see RawTurtle.delay())
+
+ Example (for a TurtleScreen instance named screen):
+ >>> screen.tracer(8, 25)
+ >>> dist = 2
+ >>> for i in range(200):
+ fd(dist)
+ rt(90)
+ dist += 2
+ """
+ if n is None:
+ return self._tracing
+ self._tracing = int(n)
+ self._updatecounter = 0
+ if delay is not None:
+ self._delayvalue = int(delay)
+ if self._tracing:
+ self.update()
+
+ def delay(self, delay=None):
+ """ Return or set the drawing delay in milliseconds.
+
+ Optional argument:
+ delay -- positive integer
+
+ Example (for a TurtleScreen instance named screen):
+ >>> screen.delay(15)
+ >>> screen.delay()
+ 15
+ """
+ if delay is None:
+ return self._delayvalue
+ self._delayvalue = int(delay)
+
+ def _incrementudc(self):
+ "Increment upadate counter."""
+ if not TurtleScreen._RUNNING:
+ TurtleScreen._RUNNNING = True
+ raise Terminator
+ if self._tracing > 0:
+ self._updatecounter += 1
+ self._updatecounter %= self._tracing
+
+ def update(self):
+ """Perform a TurtleScreen update.
+ """
+ for t in self.turtles():
+ t._update_data()
+ t._drawturtle()
+ self._update()
+
+ def window_width(self):
+ """ Return the width of the turtle window.
+
+ Example (for a TurtleScreen instance named screen):
+ >>> screen.window_width()
+ 640
+ """
+ return self._window_size()[0]
+
+ def window_height(self):
+ """ Return the height of the turtle window.
+
+ Example (for a TurtleScreen instance named screen):
+ >>> screen.window_height()
+ 480
+ """
+ return self._window_size()[1]
+
+ def getcanvas(self):
+ """Return the Canvas of this TurtleScreen.
+
+ No argument.
+
+ Example (for a Screen instance named screen):
+ >>> cv = screen.getcanvas()
+ >>> cv
+ <turtle.ScrolledCanvas instance at 0x010742D8>
+ """
+ return self.cv
+
+ def getshapes(self):
+ """Return a list of names of all currently available turtle shapes.
+
+ No argument.
+
+ Example (for a TurtleScreen instance named screen):
+ >>> screen.getshapes()
+ ['arrow', 'blank', 'circle', ... , 'turtle']
+ """
+ return sorted(self._shapes.keys())
+
+ def onclick(self, fun, btn=1, add=None):
+ """Bind fun to mouse-click event on canvas.
+
+ Arguments:
+ fun -- a function with two arguments, the coordinates of the
+ clicked point on the canvas.
+ num -- the number of the mouse-button, defaults to 1
+
+ Example (for a TurtleScreen instance named screen
+ and a Turtle instance named turtle):
+
+ >>> screen.onclick(turtle.goto)
+
+ ### Subsequently clicking into the TurtleScreen will
+ ### make the turtle move to the clicked point.
+ >>> screen.onclick(None)
+
+ ### event-binding will be removed
+ """
+ self._onscreenclick(fun, btn, add)
+
+ def onkey(self, fun, key):
+ """Bind fun to key-release event of key.
+
+ Arguments:
+ fun -- a function with no arguments
+ key -- a string: key (e.g. "a") or key-symbol (e.g. "space")
+
+ In order ro be able to register key-events, TurtleScreen
+ must have focus. (See method listen.)
+
+ Example (for a TurtleScreen instance named screen
+ and a Turtle instance named turtle):
+
+ >>> def f():
+ fd(50)
+ lt(60)
+
+
+ >>> screen.onkey(f, "Up")
+ >>> screen.listen()
+
+ ### Subsequently the turtle can be moved by
+ ### repeatedly pressing the up-arrow key,
+ ### consequently drawing a hexagon
+ """
+ if fun == None:
+ self._keys.remove(key)
+ elif key not in self._keys:
+ self._keys.append(key)
+ self._onkey(fun, key)
+
+ def listen(self, xdummy=None, ydummy=None):
+ """Set focus on TurtleScreen (in order to collect key-events)
+
+ No arguments.
+ Dummy arguments are provided in order
+ to be able to pass listen to the onclick method.
+
+ Example (for a TurtleScreen instance named screen):
+ >>> screen.listen()
+ """
+ self._listen()
+
+ def ontimer(self, fun, t=0):
+ """Install a timer, which calls fun after t milliseconds.
+
+ Arguments:
+ fun -- a function with no arguments.
+ t -- a number >= 0
+
+ Example (for a TurtleScreen instance named screen):
+
+ >>> running = True
+ >>> def f():
+ if running:
+ fd(50)
+ lt(60)
+ screen.ontimer(f, 250)
+
+ >>> f() ### makes the turtle marching around
+ >>> running = False
+ """
+ self._ontimer(fun, t)
+
+ def bgpic(self, picname=None):
+ """Set background image or return name of current backgroundimage.
+
+ Optional argument:
+ picname -- a string, name of a gif-file or "nopic".
+
+ If picname is a filename, set the corresponing image as background.
+ If picname is "nopic", delete backgroundimage, if present.
+ If picname is None, return the filename of the current backgroundimage.
+
+ Example (for a TurtleScreen instance named screen):
+ >>> screen.bgpic()
+ 'nopic'
+ >>> screen.bgpic("landscape.gif")
+ >>> screen.bgpic()
+ 'landscape.gif'
+ """
+ if picname is None:
+ return self._bgpicname
+ if picname not in self._bgpics:
+ self._bgpics[picname] = self._image(picname)
+ self._setbgpic(self._bgpic, self._bgpics[picname])
+ self._bgpicname = picname
+
+ def screensize(self, canvwidth=None, canvheight=None, bg=None):
+ """Resize the canvas, the turtles are drawing on.
+
+ Optional arguments:
+ canvwidth -- positive integer, new width of canvas in pixels
+ canvheight -- positive integer, new height of canvas in pixels
+ bg -- colorstring or color-tupel, new backgroundcolor
+ If no arguments are given, return current (canvaswidth, canvasheight)
+
+ Do not alter the drawing window. To observe hidden parts of
+ the canvas use the scrollbars. (Can make visible those parts
+ of a drawing, which were outside the canvas before!)
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.screensize(2000,1500)
+ ### e. g. to search for an erroneously escaped turtle ;-)
+ """
+ return self._resize(canvwidth, canvheight, bg)
+
+ onscreenclick = onclick
+ resetscreen = reset
+ clearscreen = clear
+ addshape = register_shape
+
+class TNavigator(object):
+ """Navigation part of the RawTurtle.
+ Implements methods for turtle movement.
+ """
+ START_ORIENTATION = {
+ "standard": Vec2D(1.0, 0.0),
+ "world" : Vec2D(1.0, 0.0),
+ "logo" : Vec2D(0.0, 1.0) }
+ DEFAULT_MODE = "standard"
+ DEFAULT_ANGLEOFFSET = 0
+ DEFAULT_ANGLEORIENT = 1
+
+ def __init__(self, mode=DEFAULT_MODE):
+ self._angleOffset = self.DEFAULT_ANGLEOFFSET
+ self._angleOrient = self.DEFAULT_ANGLEORIENT
+ self._mode = mode
+ self.undobuffer = None
+ self.degrees()
+ self._mode = None
+ self._setmode(mode)
+ TNavigator.reset(self)
+
+ def reset(self):
+ """reset turtle to its initial values
+
+ Will be overwritten by parent class
+ """
+ self._position = Vec2D(0.0, 0.0)
+ self._orient = TNavigator.START_ORIENTATION[self._mode]
+
+ def _setmode(self, mode=None):
+ """Set turtle-mode to 'standard', 'world' or 'logo'.
+ """
+ if mode == None:
+ return self._mode
+ if mode not in ["standard", "logo", "world"]:
+ return
+ self._mode = mode
+ if mode in ["standard", "world"]:
+ self._angleOffset = 0
+ self._angleOrient = 1
+ else: # mode == "logo":
+ self._angleOffset = self._fullcircle/4.
+ self._angleOrient = -1
+
+ def _setDegreesPerAU(self, fullcircle):
+ """Helper function for degrees() and radians()"""
+ self._fullcircle = fullcircle
+ self._degreesPerAU = 360/fullcircle
+ if self._mode == "standard":
+ self._angleOffset = 0
+ else:
+ self._angleOffset = fullcircle/4.
+
+ def degrees(self, fullcircle=360.0):
+ """ Set angle measurement units to degrees.
+
+ Optional argument:
+ fullcircle - a number
+
+ Set angle measurement units, i. e. set number
+ of 'degrees' for a full circle. Dafault value is
+ 360 degrees.
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.left(90)
+ >>> turtle.heading()
+ 90
+ >>> turtle.degrees(400.0) # angle measurement in gon
+ >>> turtle.heading()
+ 100
+
+ """
+ self._setDegreesPerAU(fullcircle)
+
+ def radians(self):
+ """ Set the angle measurement units to radians.
+
+ No arguments.
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.heading()
+ 90
+ >>> turtle.radians()
+ >>> turtle.heading()
+ 1.5707963267948966
+ """
+ self._setDegreesPerAU(2*math.pi)
+
+ def _go(self, distance):
+ """move turtle forward by specified distance"""
+ ende = self._position + self._orient * distance
+ self._goto(ende)
+
+ def _rotate(self, angle):
+ """Turn turtle counterclockwise by specified angle if angle > 0."""
+ angle *= self._degreesPerAU
+ self._orient = self._orient.rotate(angle)
+
+ def _goto(self, end):
+ """move turtle to position end."""
+ self._position = end
+
+ def forward(self, distance):
+ """Move the turtle forward by the specified distance.
+
+ Aliases: forward | fd
+
+ Argument:
+ distance -- a number (integer or float)
+
+ Move the turtle forward by the specified distance, in the direction
+ the turtle is headed.
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.position()
+ (0.00, 0.00)
+ >>> turtle.forward(25)
+ >>> turtle.position()
+ (25.00,0.00)
+ >>> turtle.forward(-75)
+ >>> turtle.position()
+ (-50.00,0.00)
+ """
+ self._go(distance)
+
+ def back(self, distance):
+ """Move the turtle backward by distance.
+
+ Aliases: back | backward | bk
+
+ Argument:
+ distance -- a number
+
+ Move the turtle backward by distance ,opposite to the direction the
+ turtle is headed. Do not change the turtle's heading.
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.position()
+ (0.00, 0.00)
+ >>> turtle.backward(30)
+ >>> turtle.position()
+ (-30.00, 0.00)
+ """
+ self._go(-distance)
+
+ def right(self, angle):
+ """Turn turtle right by angle units.
+
+ Aliases: right | rt
+
+ Argument:
+ angle -- a number (integer or float)
+
+ Turn turtle right by angle units. (Units are by default degrees,
+ but can be set via the degrees() and radians() functions.)
+ Angle orientation depends on mode. (See this.)
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.heading()
+ 22.0
+ >>> turtle.right(45)
+ >>> turtle.heading()
+ 337.0
+ """
+ self._rotate(-angle)
+
+ def left(self, angle):
+ """Turn turtle left by angle units.
+
+ Aliases: left | lt
+
+ Argument:
+ angle -- a number (integer or float)
+
+ Turn turtle left by angle units. (Units are by default degrees,
+ but can be set via the degrees() and radians() functions.)
+ Angle orientation depends on mode. (See this.)
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.heading()
+ 22.0
+ >>> turtle.left(45)
+ >>> turtle.heading()
+ 67.0
+ """
+ self._rotate(angle)
+
+ def pos(self):
+ """Return the turtle's current location (x,y), as a Vec2D-vector.
+
+ Aliases: pos | position
+
+ No arguments.
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.pos()
+ (0.00, 240.00)
+ """
+ return self._position
+
+ def xcor(self):
+ """ Return the turtle's x coordinate.
+
+ No arguments.
+
+ Example (for a Turtle instance named turtle):
+ >>> reset()
+ >>> turtle.left(60)
+ >>> turtle.forward(100)
+ >>> print turtle.xcor()
+ 50.0
+ """
+ return self._position[0]
+
+ def ycor(self):
+ """ Return the turtle's y coordinate
+ ---
+ No arguments.
+
+ Example (for a Turtle instance named turtle):
+ >>> reset()
+ >>> turtle.left(60)
+ >>> turtle.forward(100)
+ >>> print turtle.ycor()
+ 86.6025403784
+ """
+ return self._position[1]
+
+
+ def goto(self, x, y=None):
+ """Move turtle to an absolute position.
+
+ Aliases: setpos | setposition | goto:
+
+ Arguments:
+ x -- a number or a pair/vector of numbers
+ y -- a number None
+
+ call: goto(x, y) # two coordinates
+ --or: goto((x, y)) # a pair (tuple) of coordinates
+ --or: goto(vec) # e.g. as returned by pos()
+
+ Move turtle to an absolute position. If the pen is down,
+ a line will be drawn. The turtle's orientation does not change.
+
+ Example (for a Turtle instance named turtle):
+ >>> tp = turtle.pos()
+ >>> tp
+ (0.00, 0.00)
+ >>> turtle.setpos(60,30)
+ >>> turtle.pos()
+ (60.00,30.00)
+ >>> turtle.setpos((20,80))
+ >>> turtle.pos()
+ (20.00,80.00)
+ >>> turtle.setpos(tp)
+ >>> turtle.pos()
+ (0.00,0.00)
+ """
+ if y is None:
+ self._goto(Vec2D(*x))
+ else:
+ self._goto(Vec2D(x, y))
+
+ def home(self):
+ """Move turtle to the origin - coordinates (0,0).
+
+ No arguments.
+
+ Move turtle to the origin - coordinates (0,0) and set it's
+ heading to it's start-orientation (which depends on mode).
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.home()
+ """
+ self.goto(0, 0)
+ self.setheading(0)
+
+ def setx(self, x):
+ """Set the turtle's first coordinate to x
+
+ Argument:
+ x -- a number (integer or float)
+
+ Set the turtle's first coordinate to x, leave second coordinate
+ unchanged.
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.position()
+ (0.00, 240.00)
+ >>> turtle.setx(10)
+ >>> turtle.position()
+ (10.00, 240.00)
+ """
+ self._goto(Vec2D(x, self._position[1]))
+
+ def sety(self, y):
+ """Set the turtle's second coordinate to y
+
+ Argument:
+ y -- a number (integer or float)
+
+ Set the turtle's first coordinate to x, second coordinate remains
+ unchanged.
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.position()
+ (0.00, 40.00)
+ >>> turtle.sety(-10)
+ >>> turtle.position()
+ (0.00, -10.00)
+ """
+ self._goto(Vec2D(self._position[0], y))
+
+ def distance(self, x, y=None):
+ """Return the distance from the turtle to (x,y) in turtle step units.
+
+ Arguments:
+ x -- a number or a pair/vector of numbers or a turtle instance
+ y -- a number None None
+
+ call: distance(x, y) # two coordinates
+ --or: distance((x, y)) # a pair (tuple) of coordinates
+ --or: distance(vec) # e.g. as returned by pos()
+ --or: distance(mypen) # where mypen is another turtle
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.pos()
+ (0.00, 0.00)
+ >>> turtle.distance(30,40)
+ 50.0
+ >>> pen = Turtle()
+ >>> pen.forward(77)
+ >>> turtle.distance(pen)
+ 77.0
+ """
+ if y is not None:
+ pos = Vec2D(x, y)
+ if isinstance(x, Vec2D):
+ pos = x
+ elif isinstance(x, tuple):
+ pos = Vec2D(*x)
+ elif isinstance(x, TNavigator):
+ pos = x._position
+ return abs(pos - self._position)
+
+ def towards(self, x, y=None):
+ """Return the angle of the line from the turtle's position to (x, y).
+
+ Arguments:
+ x -- a number or a pair/vector of numbers or a turtle instance
+ y -- a number None None
+
+ call: distance(x, y) # two coordinates
+ --or: distance((x, y)) # a pair (tuple) of coordinates
+ --or: distance(vec) # e.g. as returned by pos()
+ --or: distance(mypen) # where mypen is another turtle
+
+ Return the angle, between the line from turtle-position to position
+ specified by x, y and the turtle's start orientation. (Depends on
+ modes - "standard" or "logo")
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.pos()
+ (10.00, 10.00)
+ >>> turtle.towards(0,0)
+ 225.0
+ """
+ if y is not None:
+ pos = Vec2D(x, y)
+ if isinstance(x, Vec2D):
+ pos = x
+ elif isinstance(x, tuple):
+ pos = Vec2D(*x)
+ elif isinstance(x, TNavigator):
+ pos = x._position
+ x, y = pos - self._position
+ result = round(math.atan2(y, x)*180.0/math.pi, 10) % 360.0
+ result /= self._degreesPerAU
+ return (self._angleOffset + self._angleOrient*result) % self._fullcircle
+
+ def heading(self):
+ """ Return the turtle's current heading.
+
+ No arguments.
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.left(67)
+ >>> turtle.heading()
+ 67.0
+ """
+ x, y = self._orient
+ result = round(math.atan2(y, x)*180.0/math.pi, 10) % 360.0
+ result /= self._degreesPerAU
+ return (self._angleOffset + self._angleOrient*result) % self._fullcircle
+
+ def setheading(self, to_angle):
+ """Set the orientation of the turtle to to_angle.
+
+ Aliases: setheading | seth
+
+ Argument:
+ to_angle -- a number (integer or float)
+
+ Set the orientation of the turtle to to_angle.
+ Here are some common directions in degrees:
+
+ standard - mode: logo-mode:
+ -------------------|--------------------
+ 0 - east 0 - north
+ 90 - north 90 - east
+ 180 - west 180 - south
+ 270 - south 270 - west
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.setheading(90)
+ >>> turtle.heading()
+ 90
+ """
+ angle = (to_angle - self.heading())*self._angleOrient
+ full = self._fullcircle
+ angle = (angle+full/2.)%full - full/2.
+ self._rotate(angle)
+
+ def circle(self, radius, extent = None, steps = None):
+ """ Draw a circle with given radius.
+
+ Arguments:
+ radius -- a number
+ extent (optional) -- a number
+ steps (optional) -- an integer
+
+ Draw a circle with given radius. The center is radius units left
+ of the turtle; extent - an angle - determines which part of the
+ circle is drawn. If extent is not given, draw the entire circle.
+ If extent is not a full circle, one endpoint of the arc is the
+ current pen position. Draw the arc in counterclockwise direction
+ if radius is positive, otherwise in clockwise direction. Finally
+ the direction of the turtle is changed by the amount of extent.
+
+ As the circle is approximated by an inscribed regular polygon,
+ steps determines the number of steps to use. If not given,
+ it will be calculated automatically. Maybe used to draw regular
+ polygons.
+
+ call: circle(radius) # full circle
+ --or: circle(radius, extent) # arc
+ --or: circle(radius, extent, steps)
+ --or: circle(radius, steps=6) # 6-sided polygon
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.circle(50)
+ >>> turtle.circle(120, 180) # semicircle
+ """
+ if self.undobuffer:
+ self.undobuffer.push(["seq"])
+ self.undobuffer.cumulate = True
+ speed = self.speed()
+ if extent is None:
+ extent = self._fullcircle
+ if steps is None:
+ frac = abs(extent)/self._fullcircle
+ steps = 1+int(min(11+abs(radius)/6.0, 59.0)*frac)
+ w = 1.0 * extent / steps
+ w2 = 0.5 * w
+ l = 2.0 * radius * math.sin(w2*math.pi/180.0*self._degreesPerAU)
+ if radius < 0:
+ l, w, w2 = -l, -w, -w2
+ tr = self.tracer()
+ dl = self._delay()
+ if speed == 0:
+ self.tracer(0, 0)
+ else:
+ self.speed(0)
+ self._rotate(w2)
+ for i in range(steps):
+ self.speed(speed)
+ self._go(l)
+ self.speed(0)
+ self._rotate(w)
+ self._rotate(-w2)
+ if speed == 0:
+ self.tracer(tr, dl)
+ self.speed(speed)
+ if self.undobuffer:
+ self.undobuffer.cumulate = False
+
+## three dummy methods to be implemented by child class:
+
+ def speed(self, s=0):
+ """dummy method - to be overwritten by child class"""
+ def tracer(self, a=None, b=None):
+ """dummy method - to be overwritten by child class"""
+ def _delay(self, n=None):
+ """dummy method - to be overwritten by child class"""
+
+ fd = forward
+ bk = back
+ backward = back
+ rt = right
+ lt = left
+ position = pos
+ setpos = goto
+ setposition = goto
+ seth = setheading
+
+
+class TPen(object):
+ """Drawing part of the RawTurtle.
+ Implements drawing properties.
+ """
+ def __init__(self, resizemode=_CFG["resizemode"]):
+ self._resizemode = resizemode # or "user" or "noresize"
+ self.undobuffer = None
+ TPen._reset(self)
+
+ def _reset(self, pencolor=_CFG["pencolor"],
+ fillcolor=_CFG["fillcolor"]):
+ self._pensize = 1
+ self._shown = True
+ self._pencolor = pencolor
+ self._fillcolor = fillcolor
+ self._drawing = True
+ self._speed = 3
+ self._stretchfactor = (1, 1)
+ self._tilt = 0
+ self._outlinewidth = 1
+ ### self.screen = None # to override by child class
+
+ def resizemode(self, rmode=None):
+ """Set resizemode to one of the values: "auto", "user", "noresize".
+
+ (Optional) Argument:
+ rmode -- one of the strings "auto", "user", "noresize"
+
+ Different resizemodes have the following effects:
+ - "auto" adapts the appearance of the turtle
+ corresponding to the value of pensize.
+ - "user" adapts the appearance of the turtle according to the
+ values of stretchfactor and outlinewidth (outline),
+ which are set by shapesize()
+ - "noresize" no adaption of the turtle's appearance takes place.
+ If no argument is given, return current resizemode.
+ resizemode("user") is called by a call of shapesize with arguments.
+
+
+ Examples (for a Turtle instance named turtle):
+ >>> turtle.resizemode("noresize")
+ >>> turtle.resizemode()
+ 'noresize'
+ """
+ if rmode is None:
+ return self._resizemode
+ rmode = rmode.lower()
+ if rmode in ["auto", "user", "noresize"]:
+ self.pen(resizemode=rmode)
+
+ def pensize(self, width=None):
+ """Set or return the line thickness.
+
+ Aliases: pensize | width
+
+ Argument:
+ width -- positive number
+
+ Set the line thickness to width or return it. If resizemode is set
+ to "auto" and turtleshape is a polygon, that polygon is drawn with
+ the same line thickness. If no argument is given, current pensize
+ is returned.
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.pensize()
+ 1
+ turtle.pensize(10) # from here on lines of width 10 are drawn
+ """
+ if width is None:
+ return self._pensize
+ self.pen(pensize=width)
+
+
+ def penup(self):
+ """Pull the pen up -- no drawing when moving.
+
+ Aliases: penup | pu | up
+
+ No argument
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.penup()
+ """
+ if not self._drawing:
+ return
+ self.pen(pendown=False)
+
+ def pendown(self):
+ """Pull the pen down -- drawing when moving.
+
+ Aliases: pendown | pd | down
+
+ No argument.
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.pendown()
+ """
+ if self._drawing:
+ return
+ self.pen(pendown=True)
+
+ def isdown(self):
+ """Return True if pen is down, False if it's up.
+
+ No argument.
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.penup()
+ >>> turtle.isdown()
+ False
+ >>> turtle.pendown()
+ >>> turtle.isdown()
+ True
+ """
+ return self._drawing
+
+ def speed(self, speed=None):
+ """ Return or set the turtle's speed.
+
+ Optional argument:
+ speed -- an integer in the range 0..10 or a speedstring (see below)
+
+ Set the turtle's speed to an integer value in the range 0 .. 10.
+ If no argument is given: return current speed.
+
+ If input is a number greater than 10 or smaller than 0.5,
+ speed is set to 0.
+ Speedstrings are mapped to speedvalues in the following way:
+ 'fastest' : 0
+ 'fast' : 10
+ 'normal' : 6
+ 'slow' : 3
+ 'slowest' : 1
+ speeds from 1 to 10 enforce increasingly faster animation of
+ line drawing and turtle turning.
+
+ Attention:
+ speed = 0 : *no* animation takes place. forward/back makes turtle jump
+ and likewise left/right make the turtle turn instantly.
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.speed(3)
+ """
+ speeds = {'fastest':0, 'fast':10, 'normal':6, 'slow':3, 'slowest':1 }
+ if speed is None:
+ return self._speed
+ if speed in speeds:
+ speed = speeds[speed]
+ elif 0.5 < speed < 10.5:
+ speed = int(round(speed))
+ else:
+ speed = 0
+ self.pen(speed=speed)
+
+ def color(self, *args):
+ """Return or set the pencolor and fillcolor.
+
+ Arguments:
+ Several input formats are allowed.
+ They use 0, 1, 2, or 3 arguments as follows:
+
+ color()
+ Return the current pencolor and the current fillcolor
+ as a pair of color specification strings as are returned
+ by pencolor and fillcolor.
+ color(colorstring), color((r,g,b)), color(r,g,b)
+ inputs as in pencolor, set both, fillcolor and pencolor,
+ to the given value.
+ color(colorstring1, colorstring2),
+ color((r1,g1,b1), (r2,g2,b2))
+ equivalent to pencolor(colorstring1) and fillcolor(colorstring2)
+ and analogously, if the other input format is used.
+
+ If turtleshape is a polygon, outline and interior of that polygon
+ is drawn with the newly set colors.
+ For mor info see: pencolor, fillcolor
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.color('red', 'green')
+ >>> turtle.color()
+ ('red', 'green')
+ >>> colormode(255)
+ >>> color((40, 80, 120), (160, 200, 240))
+ >>> color()
+ ('#285078', '#a0c8f0')
+ """
+ if args:
+ l = len(args)
+ if l == 1:
+ pcolor = fcolor = args[0]
+ elif l == 2:
+ pcolor, fcolor = args
+ elif l == 3:
+ pcolor = fcolor = args
+ pcolor = self._colorstr(pcolor)
+ fcolor = self._colorstr(fcolor)
+ self.pen(pencolor=pcolor, fillcolor=fcolor)
+ else:
+ return self._color(self._pencolor), self._color(self._fillcolor)
+
+ def pencolor(self, *args):
+ """ Return or set the pencolor.
+
+ Arguments:
+ Four input formats are allowed:
+ - pencolor()
+ Return the current pencolor as color specification string,
+ possibly in hex-number format (see example).
+ May be used as input to another color/pencolor/fillcolor call.
+ - pencolor(colorstring)
+ s is a Tk color specification string, such as "red" or "yellow"
+ - pencolor((r, g, b))
+ *a tuple* of r, g, and b, which represent, an RGB color,
+ and each of r, g, and b are in the range 0..colormode,
+ where colormode is either 1.0 or 255
+ - pencolor(r, g, b)
+ r, g, and b represent an RGB color, and each of r, g, and b
+ are in the range 0..colormode
+
+ If turtleshape is a polygon, the outline of that polygon is drawn
+ with the newly set pencolor.
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.pencolor('brown')
+ >>> tup = (0.2, 0.8, 0.55)
+ >>> turtle.pencolor(tup)
+ >>> turtle.pencolor()
+ '#33cc8c'
+ """
+ if args:
+ color = self._colorstr(args)
+ if color == self._pencolor:
+ return
+ self.pen(pencolor=color)
+ else:
+ return self._color(self._pencolor)
+
+ def fillcolor(self, *args):
+ """ Return or set the fillcolor.
+
+ Arguments:
+ Four input formats are allowed:
+ - fillcolor()
+ Return the current fillcolor as color specification string,
+ possibly in hex-number format (see example).
+ May be used as input to another color/pencolor/fillcolor call.
+ - fillcolor(colorstring)
+ s is a Tk color specification string, such as "red" or "yellow"
+ - fillcolor((r, g, b))
+ *a tuple* of r, g, and b, which represent, an RGB color,
+ and each of r, g, and b are in the range 0..colormode,
+ where colormode is either 1.0 or 255
+ - fillcolor(r, g, b)
+ r, g, and b represent an RGB color, and each of r, g, and b
+ are in the range 0..colormode
+
+ If turtleshape is a polygon, the interior of that polygon is drawn
+ with the newly set fillcolor.
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.fillcolor('violet')
+ >>> col = turtle.pencolor()
+ >>> turtle.fillcolor(col)
+ >>> turtle.fillcolor(0, .5, 0)
+ """
+ if args:
+ color = self._colorstr(args)
+ if color == self._fillcolor:
+ return
+ self.pen(fillcolor=color)
+ else:
+ return self._color(self._fillcolor)
+
+ def showturtle(self):
+ """Makes the turtle visible.
+
+ Aliases: showturtle | st
-from math import * # Also for export
-from time import sleep
-import Tkinter
+ No argument.
-speeds = ['fastest', 'fast', 'normal', 'slow', 'slowest']
+ Example (for a Turtle instance named turtle):
+ >>> turtle.hideturtle()
+ >>> turtle.showturtle()
+ """
+ self.pen(shown=True)
+
+ def hideturtle(self):
+ """Makes the turtle invisible.
+
+ Aliases: hideturtle | ht
+
+ No argument.
+
+ It's a good idea to do this while you're in the
+ middle of a complicated drawing, because hiding
+ the turtle speeds up the drawing observably.
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.hideturtle()
+ """
+ self.pen(shown=False)
+
+ def isvisible(self):
+ """Return True if the Turtle is shown, False if it's hidden.
+
+ No argument.
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.hideturtle()
+ >>> print turtle.isvisible():
+ False
+ """
+ return self._shown
+
+ def pen(self, pen=None, **pendict):
+ """Return or set the pen's attributes.
+
+ Arguments:
+ pen -- a dictionary with some or all of the below listed keys.
+ **pendict -- one or more keyword-arguments with the below
+ listed keys as keywords.
+
+ Return or set the pen's attributes in a 'pen-dictionary'
+ with the following key/value pairs:
+ "shown" : True/False
+ "pendown" : True/False
+ "pencolor" : color-string or color-tuple
+ "fillcolor" : color-string or color-tuple
+ "pensize" : positive number
+ "speed" : number in range 0..10
+ "resizemode" : "auto" or "user" or "noresize"
+ "stretchfactor": (positive number, positive number)
+ "outline" : positive number
+ "tilt" : number
+
+ This dicionary can be used as argument for a subsequent
+ pen()-call to restore the former pen-state. Moreover one
+ or more of these attributes can be provided as keyword-arguments.
+ This can be used to set several pen attributes in one statement.
+
+
+ Examples (for a Turtle instance named turtle):
+ >>> turtle.pen(fillcolor="black", pencolor="red", pensize=10)
+ >>> turtle.pen()
+ {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+ 'pencolor': 'red', 'pendown': True, 'fillcolor': 'black',
+ 'stretchfactor': (1,1), 'speed': 3}
+ >>> penstate=turtle.pen()
+ >>> turtle.color("yellow","")
+ >>> turtle.penup()
+ >>> turtle.pen()
+ {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+ 'pencolor': 'yellow', 'pendown': False, 'fillcolor': '',
+ 'stretchfactor': (1,1), 'speed': 3}
+ >>> p.pen(penstate, fillcolor="green")
+ >>> p.pen()
+ {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+ 'pencolor': 'red', 'pendown': True, 'fillcolor': 'green',
+ 'stretchfactor': (1,1), 'speed': 3}
+ """
+ _pd = {"shown" : self._shown,
+ "pendown" : self._drawing,
+ "pencolor" : self._pencolor,
+ "fillcolor" : self._fillcolor,
+ "pensize" : self._pensize,
+ "speed" : self._speed,
+ "resizemode" : self._resizemode,
+ "stretchfactor" : self._stretchfactor,
+ "outline" : self._outlinewidth,
+ "tilt" : self._tilt
+ }
-class Error(Exception):
- pass
+ if not (pen or pendict):
+ return _pd
-class RawPen:
+ if isinstance(pen, dict):
+ p = pen
+ else:
+ p = {}
+ p.update(pendict)
- def __init__(self, canvas):
- self._canvas = canvas
- self._items = []
- self._tracing = 1
- self._arrow = 0
- self._delay = 10 # default delay for drawing
- self._angle = 0.0
- self.degrees()
- self.reset()
+ _p_buf = {}
+ for key in p:
+ _p_buf[key] = _pd[key]
+
+ if self.undobuffer:
+ self.undobuffer.push(("pen", _p_buf))
+
+ newLine = False
+ if "pendown" in p:
+ if self._drawing != p["pendown"]:
+ newLine = True
+ if "pencolor" in p:
+ if isinstance(p["pencolor"], tuple):
+ p["pencolor"] = self._colorstr((p["pencolor"],))
+ if self._pencolor != p["pencolor"]:
+ newLine = True
+ if "pensize" in p:
+ if self._pensize != p["pensize"]:
+ newLine = True
+ if newLine:
+ self._newLine()
+ if "pendown" in p:
+ self._drawing = p["pendown"]
+ if "pencolor" in p:
+ self._pencolor = p["pencolor"]
+ if "pensize" in p:
+ self._pensize = p["pensize"]
+ if "fillcolor" in p:
+ if isinstance(p["fillcolor"], tuple):
+ p["fillcolor"] = self._colorstr((p["fillcolor"],))
+ self._fillcolor = p["fillcolor"]
+ if "speed" in p:
+ self._speed = p["speed"]
+ if "resizemode" in p:
+ self._resizemode = p["resizemode"]
+ if "stretchfactor" in p:
+ sf = p["stretchfactor"]
+ if isinstance(sf, (int, float)):
+ sf = (sf, sf)
+ self._stretchfactor = sf
+ if "outline" in p:
+ self._outlinewidth = p["outline"]
+ if "shown" in p:
+ self._shown = p["shown"]
+ if "tilt" in p:
+ self._tilt = p["tilt"]
+ self._update()
+
+## three dummy methods to be implemented by child class:
+
+ def _newLine(self, usePos = True):
+ """dummy method - to be overwritten by child class"""
+ def _update(self, count=True, forced=False):
+ """dummy method - to be overwritten by child class"""
+ def _color(self, args):
+ """dummy method - to be overwritten by child class"""
+ def _colorstr(self, args):
+ """dummy method - to be overwritten by child class"""
+
+ width = pensize
+ up = penup
+ pu = penup
+ pd = pendown
+ down = pendown
+ st = showturtle
+ ht = hideturtle
- def degrees(self, fullcircle=360.0):
- """ Set angle measurement units to degrees.
- Example:
- >>> turtle.degrees()
- """
- # Don't try to change _angle if it is 0, because
- # _fullcircle might not be set, yet
- if self._angle:
- self._angle = (self._angle / self._fullcircle) * fullcircle
- self._fullcircle = fullcircle
- self._invradian = pi / (fullcircle * 0.5)
+class _TurtleImage(object):
+ """Helper class: Datatype to store Turtle attributes
+ """
- def radians(self):
- """ Set the angle measurement units to radians.
+ def __init__(self, screen, shapeIndex):
+ self.screen = screen
+ self._type = None
+ self._setshape(shapeIndex)
+
+ def _setshape(self, shapeIndex):
+ screen = self.screen # RawTurtle.screens[self.screenIndex]
+ self.shapeIndex = shapeIndex
+ if self._type == "polygon" == screen._shapes[shapeIndex]._type:
+ return
+ if self._type == "image" == screen._shapes[shapeIndex]._type:
+ return
+ if self._type in ["image", "polygon"]:
+ screen._delete(self._item)
+ elif self._type == "compound":
+ for item in self._item:
+ screen._delete(item)
+ self._type = screen._shapes[shapeIndex]._type
+ if self._type == "polygon":
+ self._item = screen._createpoly()
+ elif self._type == "image":
+ self._item = screen._createimage(screen._shapes["blank"]._data)
+ elif self._type == "compound":
+ self._item = [screen._createpoly() for item in
+ screen._shapes[shapeIndex]._data]
+
+
+class RawTurtle(TPen, TNavigator):
+ """Animation part of the RawTurtle.
+ Puts RawTurtle upon a TurtleScreen and provides tools for
+ it's animation.
+ """
+ screens = []
- Example:
- >>> turtle.radians()
- """
- self.degrees(2.0*pi)
+ def __init__(self, canvas=None,
+ shape=_CFG["shape"],
+ undobuffersize=_CFG["undobuffersize"],
+ visible=_CFG["visible"]):
+ if isinstance(canvas, Screen):
+ self.screen = canvas
+ elif isinstance(canvas, TurtleScreen):
+ if canvas not in RawTurtle.screens:
+ RawTurtle.screens.append(canvas)
+ self.screen = canvas
+ elif isinstance(canvas, (ScrolledCanvas, Canvas)):
+ for screen in RawTurtle.screens:
+ if screen.cv == canvas:
+ self.screen = screen
+ break
+ else:
+ self.screen = TurtleScreen(canvas)
+ RawTurtle.screens.append(self.screen)
+ else:
+ raise TurtleGraphicsError("bad cavas argument %s" % canvas)
+
+ screen = self.screen
+ TNavigator.__init__(self, screen.mode())
+ TPen.__init__(self)
+ screen._turtles.append(self)
+ self.drawingLineItem = screen._createline()
+ self.turtle = _TurtleImage(screen, shape)
+ self._poly = None
+ self._creatingPoly = False
+ self._fillitem = self._fillpath = None
+ self._shown = visible
+ self._hidden_from_screen = False
+ self.currentLineItem = screen._createline()
+ self.currentLine = [self._position]
+ self.items = [self.currentLineItem]
+ self.stampItems = []
+ self._undobuffersize = undobuffersize
+ self.undobuffer = Tbuffer(undobuffersize)
+ self._update()
def reset(self):
- """ Clear the screen, re-center the pen, and set variables to
- the default values.
+ """Delete the turtle's drawings and restore it's default values.
- Example:
+ No argument.
+,
+ Delete the turtle's drawings from the screen, re-center the turtle
+ and set variables to the default values.
+
+ Example (for a Turtle instance named turtle):
>>> turtle.position()
- [0.0, -22.0]
+ (0.00,-22.00)
>>> turtle.heading()
100.0
>>> turtle.reset()
>>> turtle.position()
- [0.0, 0.0]
+ (0.00,0.00)
>>> turtle.heading()
0.0
"""
- canvas = self._canvas
- self._canvas.update()
- width = canvas.winfo_width()
- height = canvas.winfo_height()
- if width <= 1:
- width = canvas['width']
- if height <= 1:
- height = canvas['height']
- self._origin = float(width)/2.0, float(height)/2.0
- self._position = self._origin
- self._angle = 0.0
- self._drawing = 1
- self._width = 1
- self._color = "black"
- self._filling = 0
- self._path = []
- self.clear()
- canvas._root().tkraise()
-
- def clear(self):
- """ Clear the screen. The turtle does not move.
-
- Example:
- >>> turtle.clear()
- """
- self.fill(0)
- canvas = self._canvas
- items = self._items
- self._items = []
- for item in items:
- canvas.delete(item)
- self._delete_turtle()
- self._draw_turtle()
-
- def tracer(self, flag):
- """ Set tracing on if flag is True, and off if it is False.
- Tracing means line are drawn more slowly, with an
- animation of an arrow along the line.
-
- Example:
- >>> turtle.tracer(False) # turns off Tracer
- """
- self._tracing = flag
- if not self._tracing:
- self._delete_turtle()
- self._draw_turtle()
-
- def forward(self, distance):
- """ Go forward distance steps.
-
- Example:
- >>> turtle.position()
- [0.0, 0.0]
- >>> turtle.forward(25)
- >>> turtle.position()
- [25.0, 0.0]
- >>> turtle.forward(-75)
- >>> turtle.position()
- [-50.0, 0.0]
- """
- x0, y0 = start = self._position
- x1 = x0 + distance * cos(self._angle*self._invradian)
- y1 = y0 - distance * sin(self._angle*self._invradian)
- self._goto(x1, y1)
+ TNavigator.reset(self)
+ TPen._reset(self)
+ self._clear()
+ self._drawturtle()
+ self._update()
+
+ def setundobuffer(self, size):
+ """Set or disable undobuffer.
+
+ Argument:
+ size -- an integer or None
+
+ If size is an integer an empty undobuffer of given size is installed.
+ Size gives the maximum number of turtle-actions that can be undone
+ by the undo() function.
+ If size is None, no undobuffer is present.
- def backward(self, distance):
- """ Go backwards distance steps.
-
- The turtle's heading does not change.
-
- Example:
- >>> turtle.position()
- [0.0, 0.0]
- >>> turtle.backward(30)
- >>> turtle.position()
- [-30.0, 0.0]
+ Example (for a Turtle instance named turtle):
+ >>> turtle.setundobuffer(42)
"""
- self.forward(-distance)
-
- def left(self, angle):
- """ Turn left angle units (units are by default degrees,
- but can be set via the degrees() and radians() functions.)
-
- When viewed from above, the turning happens in-place around
- its front tip.
+ if size is None:
+ self.undobuffer = None
+ else:
+ self.undobuffer = Tbuffer(size)
- Example:
- >>> turtle.heading()
- 22
- >>> turtle.left(45)
- >>> turtle.heading()
- 67.0
- """
- self._angle = (self._angle + angle) % self._fullcircle
- self._draw_turtle()
+ def undobufferentries(self):
+ """Return count of entries in the undobuffer.
- def right(self, angle):
- """ Turn right angle units (units are by default degrees,
- but can be set via the degrees() and radians() functions.)
+ No argument.
- When viewed from above, the turning happens in-place around
- its front tip.
+ Example (for a Turtle instance named turtle):
+ >>> while undobufferentries():
+ undo()
+ """
+ if self.undobuffer is None:
+ return 0
+ return self.undobuffer.nr_of_items()
+
+ def _clear(self):
+ """Delete all of pen's drawings"""
+ self._fillitem = self._fillpath = None
+ for item in self.items:
+ self.screen._delete(item)
+ self.currentLineItem = self.screen._createline()
+ self.currentLine = []
+ if self._drawing:
+ self.currentLine.append(self._position)
+ self.items = [self.currentLineItem]
+ self.clearstamps()
+ self.setundobuffer(self._undobuffersize)
- Example:
- >>> turtle.heading()
- 22
- >>> turtle.right(45)
- >>> turtle.heading()
- 337.0
- """
- self.left(-angle)
- def up(self):
- """ Pull the pen up -- no drawing when moving.
+ def clear(self):
+ """Delete the turtle's drawings from the screen. Do not move turtle.
- Example:
- >>> turtle.up()
- """
- self._drawing = 0
+ No arguments.
- def down(self):
- """ Put the pen down -- draw when moving.
+ Delete the turtle's drawings from the screen. Do not move turtle.
+ State and position of the turtle as well as drawings of other
+ turtles are not affected.
- Example:
- >>> turtle.down()
+ Examples (for a Turtle instance named turtle):
+ >>> turtle.clear()
"""
- self._drawing = 1
+ self._clear()
+ self._update()
- def width(self, width):
- """ Set the line to thickness to width.
+ def _update_data(self):
+ self.screen._incrementudc()
+ if self.screen._updatecounter != 0:
+ return
+ if len(self.currentLine)>1:
+ self.screen._drawline(self.currentLineItem, self.currentLine,
+ self._pencolor, self._pensize)
- Example:
- >>> turtle.width(10)
+ def _update(self):
+ """Perform a Turtle-data update.
"""
- self._width = float(width)
-
- def color(self, *args):
- """ Set the pen color.
-
- Three input formats are allowed:
-
- color(s)
- s is a Tk specification string, such as "red" or "yellow"
-
- color((r, g, b))
- *a tuple* of r, g, and b, which represent, an RGB color,
- and each of r, g, and b are in the range [0..1]
-
- color(r, g, b)
- r, g, and b represent an RGB color, and each of r, g, and b
- are in the range [0..1]
+ screen = self.screen
+ if screen._tracing == 0:
+ return
+ elif screen._tracing == 1:
+ self._update_data()
+ self._drawturtle()
+ screen._update() # TurtleScreenBase
+ screen._delay(screen._delayvalue) # TurtleScreenBase
+ else:
+ self._update_data()
+ if screen._updatecounter == 0:
+ for t in screen.turtles():
+ t._drawturtle()
+ screen._update()
+
+ def tracer(self, flag=None, delay=None):
+ """Turns turtle animation on/off and set delay for update drawings.
+
+ Optional arguments:
+ n -- nonnegative integer
+ delay -- nonnegative integer
+
+ If n is given, only each n-th regular screen update is really performed.
+ (Can be used to accelerate the drawing of complex graphics.)
+ Second arguments sets delay value (see RawTurtle.delay())
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.tracer(8, 25)
+ >>> dist = 2
+ >>> for i in range(200):
+ turtle.fd(dist)
+ turtle.rt(90)
+ dist += 2
+ """
+ return self.screen.tracer(flag, delay)
+
+ def _color(self, args):
+ return self.screen._color(args)
- Example:
+ def _colorstr(self, args):
+ return self.screen._colorstr(args)
- >>> turtle.color('brown')
- >>> tup = (0.2, 0.8, 0.55)
- >>> turtle.color(tup)
- >>> turtle.color(0, .5, 0)
+ def _cc(self, args):
+ """Convert colortriples to hexstrings.
"""
- if not args:
- raise Error, "no color arguments"
- if len(args) == 1:
- color = args[0]
- if type(color) == type(""):
- # Test the color first
- try:
- id = self._canvas.create_line(0, 0, 0, 0, fill=color)
- except Tkinter.TclError:
- raise Error, "bad color string: %r" % (color,)
- self._set_color(color)
+ if isinstance(args, str):
+ return args
+ try:
+ r, g, b = args
+ except:
+ raise TurtleGraphicsError("bad color arguments: %s" % str(args))
+ if self.screen._colormode == 1.0:
+ r, g, b = [round(255.0*x) for x in (r, g, b)]
+ if not ((0 <= r <= 255) and (0 <= g <= 255) and (0 <= b <= 255)):
+ raise TurtleGraphicsError("bad color sequence: %s" % str(args))
+ return "#%02x%02x%02x" % (r, g, b)
+
+ def clone(self):
+ """Create and return a clone of the turtle.
+
+ No argument.
+
+ Create and return a clone of the turtle with same position, heading
+ and turtle properties.
+
+ Example (for a Turtle instance named mick):
+ mick = Turtle()
+ joe = mick.clone()
+ """
+ screen = self.screen
+ self._newLine(self._drawing)
+
+ turtle = self.turtle
+ self.screen = None
+ self.turtle = None # too make self deepcopy-able
+
+ q = deepcopy(self)
+
+ self.screen = screen
+ self.turtle = turtle
+
+ q.screen = screen
+ q.turtle = _TurtleImage(screen, self.turtle.shapeIndex)
+
+ screen._turtles.append(q)
+ ttype = screen._shapes[self.turtle.shapeIndex]._type
+ if ttype == "polygon":
+ q.turtle._item = screen._createpoly()
+ elif ttype == "image":
+ q.turtle._item = screen._createimage(screen._shapes["blank"]._data)
+ elif ttype == "compound":
+ q.turtle._item = [screen._createpoly() for item in
+ screen._shapes[self.turtle.shapeIndex]._data]
+ q.currentLineItem = screen._createline()
+ q._update()
+ return q
+
+ def shape(self, name=None):
+ """Set turtle shape to shape with given name / return current shapename.
+
+ Optional argument:
+ name -- a string, which is a valid shapename
+
+ Set turtle shape to shape with given name or, if name is not given,
+ return name of current shape.
+ Shape with name must exist in the TurtleScreen's shape dictionary.
+ Initially there are the following polygon shapes:
+ 'arrow', 'turtle', 'circle', 'square', 'triangle', 'classic'.
+ To learn about how to deal with shapes see Screen-method register_shape.
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.shape()
+ 'arrow'
+ >>> turtle.shape("turtle")
+ >>> turtle.shape()
+ 'turtle'
+ """
+ if name is None:
+ return self.turtle.shapeIndex
+ if not name in self.screen.getshapes():
+ raise TurtleGraphicsError("There is no shape named %s" % name)
+ self.turtle._setshape(name)
+ self._update()
+
+ def shapesize(self, stretch_wid=None, stretch_len=None, outline=None):
+ """Set/return turtle's stretchfactors/outline. Set resizemode to "user".
+
+ Optinonal arguments:
+ stretch_wid : positive number
+ stretch_len : positive number
+ outline : positive number
+
+ Return or set the pen's attributes x/y-stretchfactors and/or outline.
+ Set resizemode to "user".
+ If and only if resizemode is set to "user", the turtle will be displayed
+ stretched according to its stretchfactors:
+ stretch_wid is stretchfactor perpendicular to orientation
+ stretch_len is stretchfactor in direction of turtles orientation.
+ outline determines the width of the shapes's outline.
+
+ Examples (for a Turtle instance named turtle):
+ >>> turtle.resizemode("user")
+ >>> turtle.shapesize(5, 5, 12)
+ >>> turtle.shapesize(outline=8)
+ """
+ if stretch_wid is None and stretch_len is None and outline == None:
+ stretch_wid, stretch_len = self._stretchfactor
+ return stretch_wid, stretch_len, self._outlinewidth
+ if stretch_wid is not None:
+ if stretch_len is None:
+ stretchfactor = stretch_wid, stretch_wid
+ else:
+ stretchfactor = stretch_wid, stretch_len
+ elif stretch_len is not None:
+ stretchfactor = self._stretchfactor[0], stretch_len
+ else:
+ stretchfactor = self._stretchfactor
+ if outline is None:
+ outline = self._outlinewidth
+ self.pen(resizemode="user",
+ stretchfactor=stretchfactor, outline=outline)
+
+ def settiltangle(self, angle):
+ """Rotate the turtleshape to point in the specified direction
+
+ Optional argument:
+ angle -- number
+
+ Rotate the turtleshape to point in the direction specified by angle,
+ regardless of its current tilt-angle. DO NOT change the turtle's
+ heading (direction of movement).
+
+
+ Examples (for a Turtle instance named turtle):
+ >>> turtle.shape("circle")
+ >>> turtle.shapesize(5,2)
+ >>> turtle.settiltangle(45)
+ >>> stamp()
+ >>> turtle.fd(50)
+ >>> turtle.settiltangle(-45)
+ >>> stamp()
+ >>> turtle.fd(50)
+ """
+ tilt = -angle * self._degreesPerAU * self._angleOrient
+ tilt = (tilt * math.pi / 180.0) % (2*math.pi)
+ self.pen(resizemode="user", tilt=tilt)
+
+ def tiltangle(self):
+ """Return the current tilt-angle.
+
+ No argument.
+
+ Return the current tilt-angle, i. e. the angle between the
+ orientation of the turtleshape and the heading of the turtle
+ (it's direction of movement).
+
+ Examples (for a Turtle instance named turtle):
+ >>> turtle.shape("circle")
+ >>> turtle.shapesize(5,2)
+ >>> turtle.tilt(45)
+ >>> turtle.tiltangle()
+ >>>
+ """
+ tilt = -self._tilt * (180.0/math.pi) * self._angleOrient
+ return (tilt / self._degreesPerAU) % self._fullcircle
+
+ def tilt(self, angle):
+ """Rotate the turtleshape by angle.
+
+ Argument:
+ angle - a number
+
+ Rotate the turtleshape by angle from its current tilt-angle,
+ but do NOT change the turtle's heading (direction of movement).
+
+ Examples (for a Turtle instance named turtle):
+ >>> turtle.shape("circle")
+ >>> turtle.shapesize(5,2)
+ >>> turtle.tilt(30)
+ >>> turtle.fd(50)
+ >>> turtle.tilt(30)
+ >>> turtle.fd(50)
+ """
+ self.settiltangle(angle + self.tiltangle())
+
+ def _polytrafo(self, poly):
+ """Computes transformed polygon shapes from a shape
+ according to current position and heading.
+ """
+ screen = self.screen
+ p0, p1 = self._position
+ e0, e1 = self._orient
+ e = Vec2D(e0, e1 * screen.yscale / screen.xscale)
+ e0, e1 = (1.0 / abs(e)) * e
+ return [(p0+(e1*x+e0*y)/screen.xscale, p1+(-e0*x+e1*y)/screen.yscale)
+ for (x, y) in poly]
+
+ def _drawturtle(self):
+ """Manages the correct rendering of the turtle with respect to
+ it's shape, resizemode, strech and tilt etc."""
+ screen = self.screen
+ shape = screen._shapes[self.turtle.shapeIndex]
+ ttype = shape._type
+ titem = self.turtle._item
+ if self._shown and screen._updatecounter == 0 and screen._tracing > 0:
+ self._hidden_from_screen = False
+ tshape = shape._data
+ if ttype == "polygon":
+ if self._resizemode == "noresize":
+ w = 1
+ shape = tshape
+ else:
+ if self._resizemode == "auto":
+ lx = ly = max(1, self._pensize/5.0)
+ w = self._pensize
+ tiltangle = 0
+ elif self._resizemode == "user":
+ lx, ly = self._stretchfactor
+ w = self._outlinewidth
+ tiltangle = self._tilt
+ shape = [(lx*x, ly*y) for (x, y) in tshape]
+ t0, t1 = math.sin(tiltangle), math.cos(tiltangle)
+ shape = [(t1*x+t0*y, -t0*x+t1*y) for (x, y) in shape]
+ shape = self._polytrafo(shape)
+ fc, oc = self._fillcolor, self._pencolor
+ screen._drawpoly(titem, shape, fill=fc, outline=oc,
+ width=w, top=True)
+ elif ttype == "image":
+ screen._drawimage(titem, self._position, tshape)
+ elif ttype == "compound":
+ lx, ly = self._stretchfactor
+ w = self._outlinewidth
+ for item, (poly, fc, oc) in zip(titem, tshape):
+ poly = [(lx*x, ly*y) for (x, y) in poly]
+ poly = self._polytrafo(poly)
+ screen._drawpoly(item, poly, fill=self._cc(fc),
+ outline=self._cc(oc), width=w, top=True)
+ else:
+ if self._hidden_from_screen:
return
- try:
- r, g, b = color
- except:
- raise Error, "bad color sequence: %r" % (color,)
+ if ttype == "polygon":
+ screen._drawpoly(titem, ((0, 0), (0, 0), (0, 0)), "", "")
+ elif ttype == "image":
+ screen._drawimage(titem, self._position,
+ screen._shapes["blank"]._data)
+ elif ttype == "compound":
+ for item in titem:
+ screen._drawpoly(item, ((0, 0), (0, 0), (0, 0)), "", "")
+ self._hidden_from_screen = True
+
+############################## stamp stuff ###############################
+
+ def stamp(self):
+ """Stamp a copy of the turtleshape onto the canvas and return it's id.
+
+ No argument.
+
+ Stamp a copy of the turtle shape onto the canvas at the current
+ turtle position. Return a stamp_id for that stamp, which can be
+ used to delete it by calling clearstamp(stamp_id).
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.color("blue")
+ >>> turtle.stamp()
+ 13
+ >>> turtle.fd(50)
+ """
+ screen = self.screen
+ shape = screen._shapes[self.turtle.shapeIndex]
+ ttype = shape._type
+ tshape = shape._data
+ if ttype == "polygon":
+ stitem = screen._createpoly()
+ if self._resizemode == "noresize":
+ w = 1
+ shape = tshape
+ else:
+ if self._resizemode == "auto":
+ lx = ly = max(1, self._pensize/5.0)
+ w = self._pensize
+ tiltangle = 0
+ elif self._resizemode == "user":
+ lx, ly = self._stretchfactor
+ w = self._outlinewidth
+ tiltangle = self._tilt
+ shape = [(lx*x, ly*y) for (x, y) in tshape]
+ t0, t1 = math.sin(tiltangle), math.cos(tiltangle)
+ shape = [(t1*x+t0*y, -t0*x+t1*y) for (x, y) in shape]
+ shape = self._polytrafo(shape)
+ fc, oc = self._fillcolor, self._pencolor
+ screen._drawpoly(stitem, shape, fill=fc, outline=oc,
+ width=w, top=True)
+ elif ttype == "image":
+ stitem = screen._createimage("")
+ screen._drawimage(stitem, self._position, tshape)
+ elif ttype == "compound":
+ stitem = []
+ for element in tshape:
+ item = screen._createpoly()
+ stitem.append(item)
+ stitem = tuple(stitem)
+ lx, ly = self._stretchfactor
+ w = self._outlinewidth
+ for item, (poly, fc, oc) in zip(stitem, tshape):
+ poly = [(lx*x, ly*y) for (x, y) in poly]
+ poly = self._polytrafo(poly)
+ screen._drawpoly(item, poly, fill=self._cc(fc),
+ outline=self._cc(oc), width=w, top=True)
+ self.stampItems.append(stitem)
+ self.undobuffer.push(("stamp", stitem))
+ return stitem
+
+ def _clearstamp(self, stampid):
+ """does the work for clearstamp() and clearstamps()
+ """
+ if stampid in self.stampItems:
+ if isinstance(stampid, tuple):
+ for subitem in stampid:
+ self.screen._delete(subitem)
+ else:
+ self.screen._delete(stampid)
+ self.stampItems.remove(stampid)
+ # Delete stampitem from undobuffer if necessary
+ # if clearstamp is called directly.
+ item = ("stamp", stampid)
+ buf = self.undobuffer
+ if item not in buf.buffer:
+ return
+ index = buf.buffer.index(item)
+ buf.buffer.remove(item)
+ if index <= buf.ptr:
+ buf.ptr = (buf.ptr - 1) % buf.bufsize
+ buf.buffer.insert((buf.ptr+1)%buf.bufsize, [None])
+
+ def clearstamp(self, stampid):
+ """Delete stamp with given stampid
+
+ Argument:
+ stampid - an integer, must be return value of previous stamp() call.
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.color("blue")
+ >>> astamp = turtle.stamp()
+ >>> turtle.fd(50)
+ >>> turtle.clearstamp(astamp)
+ """
+ self._clearstamp(stampid)
+ self._update()
+
+ def clearstamps(self, n=None):
+ """Delete all or first/last n of turtle's stamps.
+
+ Optional argument:
+ n -- an integer
+
+ If n is None, delete all of pen's stamps,
+ else if n > 0 delete first n stamps
+ else if n < 0 delete last n stamps.
+
+ Example (for a Turtle instance named turtle):
+ >>> for i in range(8):
+ turtle.stamp(); turtle.fd(30)
+ ...
+ >>> turtle.clearstamps(2)
+ >>> turtle.clearstamps(-2)
+ >>> turtle.clearstamps()
+ """
+ if n is None:
+ toDelete = self.stampItems[:]
+ elif n >= 0:
+ toDelete = self.stampItems[:n]
else:
- try:
- r, g, b = args
- except:
- raise Error, "bad color arguments: %r" % (args,)
- assert 0 <= r <= 1
- assert 0 <= g <= 1
- assert 0 <= b <= 1
- x = 255.0
- y = 0.5
- self._set_color("#%02x%02x%02x" % (int(r*x+y), int(g*x+y), int(b*x+y)))
-
- def _set_color(self,color):
- self._color = color
- self._draw_turtle()
+ toDelete = self.stampItems[n:]
+ for item in toDelete:
+ self._clearstamp(item)
+ self._update()
+
+ def _goto(self, end):
+ """Move the pen to the point end, thereby drawing a line
+ if pen is down. All other methodes for turtle movement depend
+ on this one.
+ """
+ ## Version mit undo-stuff
+ go_modes = ( self._drawing,
+ self._pencolor,
+ self._pensize,
+ isinstance(self._fillpath, list))
+ screen = self.screen
+ undo_entry = ("go", self._position, end, go_modes,
+ (self.currentLineItem,
+ self.currentLine[:],
+ screen._pointlist(self.currentLineItem),
+ self.items[:])
+ )
+ if self.undobuffer:
+ self.undobuffer.push(undo_entry)
+ start = self._position
+ if self._speed and screen._tracing == 1:
+ diff = (end-start)
+ diffsq = (diff[0]*screen.xscale)**2 + (diff[1]*screen.yscale)**2
+ nhops = 1+int((diffsq**0.5)/(3*(1.1**self._speed)*self._speed))
+ delta = diff * (1.0/nhops)
+ for n in range(1, nhops):
+ if n == 1:
+ top = True
+ else:
+ top = False
+ self._position = start + delta * n
+ if self._drawing:
+ screen._drawline(self.drawingLineItem,
+ (start, self._position),
+ self._pencolor, self._pensize, top)
+ self._update()
+ if self._drawing:
+ screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)),
+ fill="", width=self._pensize)
+ # Turtle now at end,
+ if self._drawing: # now update currentLine
+ self.currentLine.append(end)
+ if isinstance(self._fillpath, list):
+ self._fillpath.append(end)
+ ###### vererbung!!!!!!!!!!!!!!!!!!!!!!
+ self._position = end
+ if self._creatingPoly:
+ self._poly.append(end)
+ if len(self.currentLine) > 42: # 42! answer to the ultimate question
+ # of life, the universe and everything
+ self._newLine()
+ self._update() #count=True)
+
+ def _undogoto(self, entry):
+ """Reverse a _goto. Used for undo()
+ """
+ old, new, go_modes, coodata = entry
+ drawing, pc, ps, filling = go_modes
+ cLI, cL, pl, items = coodata
+ screen = self.screen
+ if abs(self._position - new) > 0.5:
+ print "undogoto: HALLO-DA-STIMMT-WAS-NICHT!"
+ # restore former situation
+ self.currentLineItem = cLI
+ self.currentLine = cL
- def write(self, text, move=False):
- """ Write text at the current pen position.
-
- If move is true, the pen is moved to the bottom-right corner
- of the text. By default, move is False.
+ if pl == [(0, 0), (0, 0)]:
+ usepc = ""
+ else:
+ usepc = pc
+ screen._drawline(cLI, pl, fill=usepc, width=ps)
- Example:
- >>> turtle.write('The race is on!')
- >>> turtle.write('Home = (0, 0)', True)
- """
- x, y = self._position
- x = x-1 # correction -- calibrated for Windows
- item = self._canvas.create_text(x, y,
- text=str(text), anchor="sw",
- fill=self._color)
- self._items.append(item)
- if move:
- x0, y0, x1, y1 = self._canvas.bbox(item)
- self._goto(x1, y1)
- self._draw_turtle()
-
- def fill(self, flag):
- """ Call fill(1) before drawing the shape you
- want to fill, and fill(0) when done.
+ todelete = [i for i in self.items if (i not in items) and
+ (screen._type(i) == "line")]
+ for i in todelete:
+ screen._delete(i)
+ self.items.remove(i)
+
+ start = old
+ if self._speed and screen._tracing == 1:
+ diff = old - new
+ diffsq = (diff[0]*screen.xscale)**2 + (diff[1]*screen.yscale)**2
+ nhops = 1+int((diffsq**0.5)/(3*(1.1**self._speed)*self._speed))
+ delta = diff * (1.0/nhops)
+ for n in range(1, nhops):
+ if n == 1:
+ top = True
+ else:
+ top = False
+ self._position = new + delta * n
+ if drawing:
+ screen._drawline(self.drawingLineItem,
+ (start, self._position),
+ pc, ps, top)
+ self._update()
+ if drawing:
+ screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)),
+ fill="", width=ps)
+ # Turtle now at position old,
+ self._position = old
+ ## if undo is done during crating a polygon, the last vertex
+ ## will be deleted. if the polygon is entirel deleted,
+ ## creatigPoly will be set to False.
+ ## Polygons created before the last one will not be affected by undo()
+ if self._creatingPoly:
+ if len(self._poly) > 0:
+ self._poly.pop()
+ if self._poly == []:
+ self._creatingPoly = False
+ self._poly = None
+ if filling:
+ if self._fillpath == []:
+ self._fillpath = None
+ print "Unwahrscheinlich in _undogoto!"
+ elif self._fillpath is not None:
+ self._fillpath.pop()
+ self._update() #count=True)
+
+ def _rotate(self, angle):
+ """Turns pen clockwise by angle.
+ """
+ if self.undobuffer:
+ self.undobuffer.push(("rot", angle, self._degreesPerAU))
+ angle *= self._degreesPerAU
+ neworient = self._orient.rotate(angle)
+ tracing = self.screen._tracing
+ if tracing == 1 and self._speed > 0:
+ anglevel = 3.0 * self._speed
+ steps = 1 + int(abs(angle)/anglevel)
+ delta = 1.0*angle/steps
+ for _ in range(steps):
+ self._orient = self._orient.rotate(delta)
+ self._update()
+ self._orient = neworient
+ self._update()
+
+ def _newLine(self, usePos=True):
+ """Closes current line item and starts a new one.
+ Remark: if current line became too long, animation
+ performance (via _drawline) slowed down considerably.
+ """
+ if len(self.currentLine) > 1:
+ self.screen._drawline(self.currentLineItem, self.currentLine,
+ self._pencolor, self._pensize)
+ self.currentLineItem = self.screen._createline()
+ self.items.append(self.currentLineItem)
+ else:
+ self.screen._drawline(self.currentLineItem, top=True)
+ self.currentLine = []
+ if usePos:
+ self.currentLine = [self._position]
+
+ def fill(self, flag=None):
+ """Call fill(True) before drawing a shape to fill, fill(False) when done.
+
+ Optional argument:
+ flag -- True/False (or 1/0 respectively)
+
+ Call fill(True) before drawing the shape you want to fill,
+ and fill(False) when done.
+ When used without argument: return fillstate (True if filling,
+ False else)
- Example:
- >>> turtle.fill(1)
+ Example (for a Turtle instance named turtle):
+ >>> turtle.fill(True)
>>> turtle.forward(100)
>>> turtle.left(90)
>>> turtle.forward(100)
@@ -296,27 +3144,43 @@
>>> turtle.forward(100)
>>> turtle.left(90)
>>> turtle.forward(100)
- >>> turtle.fill(0)
+ >>> turtle.fill(False)
"""
- if self._filling:
- path = tuple(self._path)
- smooth = self._filling < 0
- if len(path) > 2:
- item = self._canvas._create('polygon', path,
- {'fill': self._color,
- 'smooth': smooth})
- self._items.append(item)
- self._path = []
- self._filling = flag
+ filling = isinstance(self._fillpath, list)
+ if flag is None:
+ return filling
+ screen = self.screen
+ entry1 = entry2 = ()
+ if filling:
+ if len(self._fillpath) > 2:
+ self.screen._drawpoly(self._fillitem, self._fillpath,
+ fill=self._fillcolor)
+ entry1 = ("dofill", self._fillitem)
if flag:
- self._path.append(self._position)
+ self._fillitem = self.screen._createpoly()
+ self.items.append(self._fillitem)
+ self._fillpath = [self._position]
+ entry2 = ("beginfill", self._fillitem) # , self._fillpath)
+ self._newLine()
+ else:
+ self._fillitem = self._fillpath = None
+ if self.undobuffer:
+ if entry1 == ():
+ if entry2 != ():
+ self.undobuffer.push(entry2)
+ else:
+ if entry2 == ():
+ self.undobuffer.push(entry1)
+ else:
+ self.undobuffer.push(["seq", entry1, entry2])
+ self._update()
def begin_fill(self):
- """ Called just before drawing a shape to be filled.
- Must eventually be followed by a corresponding end_fill() call.
- Otherwise it will be ignored.
+ """Called just before drawing a shape to be filled.
- Example:
+ No argument.
+
+ Example (for a Turtle instance named turtle):
>>> turtle.begin_fill()
>>> turtle.forward(100)
>>> turtle.left(90)
@@ -327,13 +3191,14 @@
>>> turtle.forward(100)
>>> turtle.end_fill()
"""
- self._path = [self._position]
- self._filling = 1
+ self.fill(True)
def end_fill(self):
- """ Called after drawing a shape to be filled.
+ """Fill the shape drawn after the call begin_fill().
- Example:
+ No argument.
+
+ Example (for a Turtle instance named turtle):
>>> turtle.begin_fill()
>>> turtle.forward(100)
>>> turtle.left(90)
@@ -344,613 +3209,820 @@
>>> turtle.forward(100)
>>> turtle.end_fill()
"""
- self.fill(0)
+ self.fill(False)
- def circle(self, radius, extent = None):
- """ Draw a circle with given radius.
- The center is radius units left of the turtle; extent
- determines which part of the circle is drawn. If not given,
- the entire circle is drawn.
+ def dot(self, size=None, *color):
+ """Draw a dot with diameter size, using color.
- If extent is not a full circle, one endpoint of the arc is the
- current pen position. The arc is drawn in a counter clockwise
- direction if radius is positive, otherwise in a clockwise
- direction. In the process, the direction of the turtle is
- changed by the amount of the extent.
+ Optional argumentS:
+ size -- an integer >= 1 (if given)
+ color -- a colorstring or a numeric color tuple
+
+ Draw a circular dot with diameter size, using color.
+ If size is not given, the maximum of pensize+4 and 2*pensize is used.
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.dot()
+ >>> turtle.fd(50); turtle.dot(20, "blue"); turtle.fd(50)
+ """
+ #print "dot-1:", size, color
+ if not color:
+ if isinstance(size, (str, tuple)):
+ color = self._colorstr(size)
+ size = self._pensize + max(self._pensize, 4)
+ else:
+ color = self._pencolor
+ if not size:
+ size = self._pensize + max(self._pensize, 4)
+ else:
+ if size is None:
+ size = self._pensize + max(self._pensize, 4)
+ color = self._colorstr(color)
+ #print "dot-2:", size, color
+ if hasattr(self.screen, "_dot"):
+ item = self.screen._dot(self._position, size, color)
+ #print "dot:", size, color, "item:", item
+ self.items.append(item)
+ if self.undobuffer:
+ self.undobuffer.push(("dot", item))
+ else:
+ pen = self.pen()
+ if self.undobuffer:
+ self.undobuffer.push(["seq"])
+ self.undobuffer.cumulate = True
+ try:
+ if self.resizemode() == 'auto':
+ self.ht()
+ self.pendown()
+ self.pensize(size)
+ self.pencolor(color)
+ self.forward(0)
+ finally:
+ self.pen(pen)
+ if self.undobuffer:
+ self.undobuffer.cumulate = False
+
+ def _write(self, txt, align, font):
+ """Performs the writing for write()
+ """
+ item, end = self.screen._write(self._position, txt, align, font,
+ self._pencolor)
+ self.items.append(item)
+ if self.undobuffer:
+ self.undobuffer.push(("wri", item))
+ return end
+
+ def write(self, arg, move=False, align="left", font=("Arial", 8, "normal")):
+ """Write text at the current turtle position.
+
+ Arguments:
+ arg -- info, which is to be written to the TurtleScreen
+ move (optional) -- True/False
+ align (optional) -- one of the strings "left", "center" or right"
+ font (optional) -- a triple (fontname, fontsize, fonttype)
+
+ Write text - the string representation of arg - at the current
+ turtle position according to align ("left", "center" or right")
+ and with the given font.
+ If move is True, the pen is moved to the bottom-right corner
+ of the text. By default, move is False.
- >>> turtle.circle(50)
- >>> turtle.circle(120, 180) # half a circle
+ Example (for a Turtle instance named turtle):
+ >>> turtle.write('Home = ', True, align="center")
+ >>> turtle.write((0,0), True)
+ """
+ if self.undobuffer:
+ self.undobuffer.push(["seq"])
+ self.undobuffer.cumulate = True
+ end = self._write(str(arg), align.lower(), font)
+ if move:
+ x, y = self.pos()
+ self.setpos(end, y)
+ if self.undobuffer:
+ self.undobuffer.cumulate = False
+
+ def begin_poly(self):
+ """Start recording the vertices of a polygon.
+
+ No argument.
+
+ Start recording the vertices of a polygon. Current turtle position
+ is first point of polygon.
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.begin_poly()
"""
- if extent is None:
- extent = self._fullcircle
- frac = abs(extent)/self._fullcircle
- steps = 1+int(min(11+abs(radius)/6.0, 59.0)*frac)
- w = 1.0 * extent / steps
- w2 = 0.5 * w
- l = 2.0 * radius * sin(w2*self._invradian)
- if radius < 0:
- l, w, w2 = -l, -w, -w2
- self.left(w2)
- for i in range(steps):
- self.forward(l)
- self.left(w)
- self.right(w2)
+ self._poly = [self._position]
+ self._creatingPoly = True
- def heading(self):
- """ Return the turtle's current heading.
+ def end_poly(self):
+ """Stop recording the vertices of a polygon.
- Example:
- >>> turtle.heading()
- 67.0
+ No argument.
+
+ Stop recording the vertices of a polygon. Current turtle position is
+ last point of polygon. This will be connected with the first point.
+
+ Example (for a Turtle instance named turtle):
+ >>> turtle.end_poly()
"""
- return self._angle
+ self._creatingPoly = False
- def setheading(self, angle):
- """ Set the turtle facing the given angle.
+ def get_poly(self):
+ """Return the lastly recorded polygon.
- Here are some common directions in degrees:
+ No argument.
+
+ Example (for a Turtle instance named turtle):
+ >>> p = turtle.get_poly()
+ >>> turtle.register_shape("myFavouriteShape", p)
+ """
+ ## check if there is any poly? -- 1st solution:
+ if self._poly is not None:
+ return tuple(self._poly)
+
+ def getscreen(self):
+ """Return the TurtleScreen object, the turtle is drawing on.
+
+ No argument.
- 0 - east
- 90 - north
- 180 - west
- 270 - south
+ Return the TurtleScreen object, the turtle is drawing on.
+ So TurtleScreen-methods can be called for that object.
+
+ Example (for a Turtle instance named turtle):
+ >>> ts = turtle.getscreen()
+ >>> ts
+ <turtle.TurtleScreen object at 0x0106B770>
+ >>> ts.bgcolor("pink")
+ """
+ return self.screen
+
+ def getturtle(self):
+ """Return the Turtleobject itself.
+
+ No argument.
+
+ Only reasonable use: as a function to return the 'anonymous turtle':
Example:
- >>> turtle.setheading(90)
- >>> turtle.heading()
- 90
- >>> turtle.setheading(128)
- >>> turtle.heading()
- 128
+ >>> pet = getturtle()
+ >>> pet.fd(50)
+ >>> pet
+ <turtle.Turtle object at 0x0187D810>
+ >>> turtles()
+ [<turtle.Turtle object at 0x0187D810>]
"""
- self._angle = angle
- self._draw_turtle()
+ return self
+
+ getpen = getturtle
+
+
+ ################################################################
+ ### screen oriented methods recurring to methods of TurtleScreen
+ ################################################################
def window_width(self):
""" Returns the width of the turtle window.
- Example:
- >>> turtle.window_width()
+ No argument.
+
+ Example (for a TurtleScreen instance named screen):
+ >>> screen.window_width()
640
"""
- width = self._canvas.winfo_width()
- if width <= 1: # the window isn't managed by a geometry manager
- width = self._canvas['width']
- return width
+ return self.screen._window_size()[0]
def window_height(self):
""" Return the height of the turtle window.
- Example:
- >>> turtle.window_height()
- 768
- """
- height = self._canvas.winfo_height()
- if height <= 1: # the window isn't managed by a geometry manager
- height = self._canvas['height']
- return height
+ No argument.
- def position(self):
- """ Return the current (x, y) location of the turtle.
+ Example (for a TurtleScreen instance named screen):
+ >>> screen.window_height()
+ 480
+ """
+ return self.screen._window_size()[1]
- Example:
- >>> turtle.position()
- [0.0, 240.0]
+ def _delay(self, delay=None):
+ """Set delay value which determines speed of turtle animation.
"""
- x0, y0 = self._origin
- x1, y1 = self._position
- return [x1-x0, -y1+y0]
+ return self.screen.delay(delay)
- def setx(self, xpos):
- """ Set the turtle's x coordinate to be xpos.
+ ##### event binding methods #####
- Example:
- >>> turtle.position()
- [10.0, 240.0]
- >>> turtle.setx(10)
- >>> turtle.position()
- [10.0, 240.0]
- """
- x0, y0 = self._origin
- x1, y1 = self._position
- self._goto(x0+xpos, y1)
+ def onclick(self, fun, btn=1, add=None):
+ """Bind fun to mouse-click event on this turtle on canvas.
- def sety(self, ypos):
- """ Set the turtle's y coordinate to be ypos.
+ Arguments:
+ fun -- a function with two arguments, to which will be assigned
+ the coordinates of the clicked point on the canvas.
+ num -- number of the mouse-button defaults to 1 (left mouse button).
+ add -- True or False. If True, new binding will be added, otherwise
+ it will replace a former binding.
- Example:
- >>> turtle.position()
- [0.0, 0.0]
- >>> turtle.sety(-22)
- >>> turtle.position()
- [0.0, -22.0]
+ Example for the anonymous turtle, i. e. the procedural way:
+
+ >>> def turn(x, y):
+ left(360)
+
+ >>> onclick(turn) # Now clicking into the turtle will turn it.
+ >>> onclick(None) # event-binding will be removed
"""
- x0, y0 = self._origin
- x1, y1 = self._position
- self._goto(x1, y0-ypos)
+ self.screen._onclick(self.turtle._item, fun, btn, add)
+ self._update()
- def towards(self, *args):
- """Returs the angle, which corresponds to the line
- from turtle-position to point (x,y).
+ def onrelease(self, fun, btn=1, add=None):
+ """Bind fun to mouse-button-release event on this turtle on canvas.
- Argument can be two coordinates or one pair of coordinates
- or a RawPen/Pen instance.
+ Arguments:
+ fun -- a function with two arguments, to which will be assigned
+ the coordinates of the clicked point on the canvas.
+ num -- number of the mouse-button defaults to 1 (left mouse button).
- Example:
- >>> turtle.position()
- [10.0, 10.0]
- >>> turtle.towards(0,0)
- 225.0
+ Example (for a MyTurtle instance named joe):
+ >>> class MyTurtle(Turtle):
+ def glow(self,x,y):
+ self.fillcolor("red")
+ def unglow(self,x,y):
+ self.fillcolor("")
+
+ >>> joe = MyTurtle()
+ >>> joe.onclick(joe.glow)
+ >>> joe.onrelease(joe.unglow)
+ ### clicking on joe turns fillcolor red,
+ ### unclicking turns it to transparent.
"""
- if len(args) == 2:
- x, y = args
- else:
- arg = args[0]
- if isinstance(arg, RawPen):
- x, y = arg.position()
- else:
- x, y = arg
- x0, y0 = self.position()
- dx = x - x0
- dy = y - y0
- return (atan2(dy,dx) / self._invradian) % self._fullcircle
+ self.screen._onrelease(self.turtle._item, fun, btn, add)
+ self._update()
- def goto(self, *args):
- """ Go to the given point.
+ def ondrag(self, fun, btn=1, add=None):
+ """Bind fun to mouse-move event on this turtle on canvas.
- If the pen is down, then a line will be drawn. The turtle's
- orientation does not change.
+ Arguments:
+ fun -- a function with two arguments, to which will be assigned
+ the coordinates of the clicked point on the canvas.
+ num -- number of the mouse-button defaults to 1 (left mouse button).
- Two input formats are accepted:
+ Every sequence of mouse-move-events on a turtle is preceded by a
+ mouse-click event on that turtle.
- goto(x, y)
- go to point (x, y)
+ Example (for a Turtle instance named turtle):
+ >>> turtle.ondrag(turtle.goto)
- goto((x, y))
- go to point (x, y)
+ ### Subsequently clicking and dragging a Turtle will
+ ### move it across the screen thereby producing handdrawings
+ ### (if pen is down).
+ """
+ self.screen._ondrag(self.turtle._item, fun, btn, add)
- Example:
- >>> turtle.position()
- [0.0, 0.0]
- >>> turtle.goto(50, -45)
- >>> turtle.position()
- [50.0, -45.0]
+
+ def _undo(self, action, data):
+ """Does the main part of the work for undo()
"""
- if len(args) == 1:
- try:
- x, y = args[0]
- except:
- raise Error, "bad point argument: %r" % (args[0],)
- else:
- try:
- x, y = args
- except:
- raise Error, "bad coordinates: %r" % (args[0],)
- x0, y0 = self._origin
- self._goto(x0+x, y0-y)
-
- def _goto(self, x1, y1):
- x0, y0 = self._position
- self._position = map(float, (x1, y1))
- if self._filling:
- self._path.append(self._position)
- if self._drawing:
- if self._tracing:
- dx = float(x1 - x0)
- dy = float(y1 - y0)
- distance = hypot(dx, dy)
- nhops = int(distance)
- item = self._canvas.create_line(x0, y0, x0, y0,
- width=self._width,
- capstyle="round",
- fill=self._color)
- try:
- for i in range(1, 1+nhops):
- x, y = x0 + dx*i/nhops, y0 + dy*i/nhops
- self._canvas.coords(item, x0, y0, x, y)
- self._draw_turtle((x,y))
- self._canvas.update()
- self._canvas.after(self._delay)
- # in case nhops==0
- self._canvas.coords(item, x0, y0, x1, y1)
- self._canvas.itemconfigure(item, arrow="none")
- except Tkinter.TclError:
- # Probably the window was closed!
- return
- else:
- item = self._canvas.create_line(x0, y0, x1, y1,
- width=self._width,
- capstyle="round",
- fill=self._color)
- self._items.append(item)
- self._draw_turtle()
-
- def speed(self, speed):
- """ Set the turtle's speed.
-
- speed must one of these five strings:
-
- 'fastest' is a 0 ms delay
- 'fast' is a 5 ms delay
- 'normal' is a 10 ms delay
- 'slow' is a 15 ms delay
- 'slowest' is a 20 ms delay
+ if self.undobuffer is None:
+ return
+ if action == "rot":
+ angle, degPAU = data
+ self._rotate(-angle*degPAU/self._degreesPerAU)
+ dummy = self.undobuffer.pop()
+ elif action == "stamp":
+ stitem = data[0]
+ self.clearstamp(stitem)
+ elif action == "go":
+ self._undogoto(data)
+ elif action in ["wri", "dot"]:
+ item = data[0]
+ self.screen._delete(item)
+ self.items.remove(item)
+ elif action == "dofill":
+ item = data[0]
+ self.screen._drawpoly(item, ((0, 0),(0, 0),(0, 0)),
+ fill="", outline="")
+ elif action == "beginfill":
+ item = data[0]
+ self._fillitem = self._fillpath = None
+ self.screen._delete(item)
+ self.items.remove(item)
+ elif action == "pen":
+ TPen.pen(self, data[0])
+ self.undobuffer.pop()
+
+ def undo(self):
+ """undo (repeatedly) the last turtle action.
+
+ No argument.
+
+ undo (repeatedly) the last turtle action.
+ Number of available undo actions is determined by the size of
+ the undobuffer.
+
+ Example (for a Turtle instance named turtle):
+ >>> for i in range(4):
+ turtle.fd(50); turtle.lt(80)
- Example:
- >>> turtle.speed('slow')
+ >>> for i in range(8):
+ turtle.undo()
"""
- try:
- speed = speed.strip().lower()
- self._delay = speeds.index(speed) * 5
- except:
- raise ValueError("%r is not a valid speed. speed must be "
- "one of %s" % (speed, speeds))
+ if self.undobuffer is None:
+ return
+ item = self.undobuffer.pop()
+ action = item[0]
+ data = item[1:]
+ if action == "seq":
+ while data:
+ item = data.pop()
+ self._undo(item[0], item[1:])
+ else:
+ self._undo(action, data)
+ turtlesize = shapesize
- def delay(self, delay):
- """ Set the drawing delay in milliseconds.
+RawPen = RawTurtle
- This is intended to allow finer control of the drawing speed
- than the speed() method
+### Screen - Klasse ########################
- Example:
- >>> turtle.delay(15)
- """
- if int(delay) < 0:
- raise ValueError("delay must be greater than or equal to 0")
- self._delay = int(delay)
-
- def _draw_turtle(self, position=[]):
- if not self._tracing:
- self._canvas.update()
- return
- if position == []:
- position = self._position
- x,y = position
- distance = 8
- dx = distance * cos(self._angle*self._invradian)
- dy = distance * sin(self._angle*self._invradian)
- self._delete_turtle()
- self._arrow = self._canvas.create_line(x-dx,y+dy,x,y,
- width=self._width,
- arrow="last",
- capstyle="round",
- fill=self._color)
- self._canvas.update()
-
- def _delete_turtle(self):
- if self._arrow != 0:
- self._canvas.delete(self._arrow)
- self._arrow = 0
-
-
-_root = None
-_canvas = None
-_pen = None
-_width = 0.50 # 50% of window width
-_height = 0.75 # 75% of window height
-_startx = None
-_starty = None
-_title = "Turtle Graphics" # default title
+class Screen(TurtleScreen):
+
+ _root = None
+ _canvas = None
+ _title = _CFG["title"]
+
+ # Borg-Idiom
-class Pen(RawPen):
+ _shared_state = {}
+
+ def __new__(cls, *args, **kwargs):
+ obj = object.__new__(cls, *args, **kwargs)
+ obj.__dict__ = cls._shared_state
+ return obj
def __init__(self):
- global _root, _canvas
- if _root is None:
- _root = Tkinter.Tk()
- _root.wm_protocol("WM_DELETE_WINDOW", self._destroy)
- _root.title(_title)
-
- if _canvas is None:
- # XXX Should have scroll bars
- _canvas = Tkinter.Canvas(_root, background="white")
- _canvas.pack(expand=1, fill="both")
+ 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:
+ width = _CFG["width"]
+ height = _CFG["height"]
+ canvwidth = _CFG["canvwidth"]
+ canvheight = _CFG["canvheight"]
+ leftright = _CFG["leftright"]
+ topbottom = _CFG["topbottom"]
+ self._root.setupcanvas(width, height, canvwidth, canvheight)
+ Screen._canvas = self._root._getcanvas()
+ self.setup(width, height, leftright, topbottom)
+ TurtleScreen.__init__(self, Screen._canvas)
+ Turtle._screen = self
+
+ def setup(self, width=_CFG["width"], height=_CFG["height"],
+ startx=_CFG["leftright"], starty=_CFG["topbottom"]):
+ """ Set the size and position of the main window.
+
+ Arguments:
+ width: as integer a size in pixels, as float a fraction of the screen.
+ Default is 50% of screen.
+ height: as integer the height in pixels, as float a fraction of the
+ screen. Default is 75% of screen.
+ startx: if positive, starting position in pixels from the left
+ edge of the screen, if negative from the right edge
+ Default, startx=None is to center window horizontally.
+ starty: if positive, starting position in pixels from the top
+ edge of the screen, if negative from the bottom edge
+ Default, starty=None is to center window vertically.
+
+ Examples (for a Screen instance named screen):
+ >>> screen.setup (width=200, height=200, startx=0, starty=0)
+
+ sets window to 200x200 pixels, in upper left of screen
- setup(width=_width, height= _height, startx=_startx, starty=_starty)
+ >>> screen.setup(width=.75, height=0.5, startx=None, starty=None)
- RawPen.__init__(self, _canvas)
+ sets window to 75% of screen by 50% of screen and centers
+ """
+ if not hasattr(self._root, "set_geometry"):
+ return
+ sw = self._root.win_width()
+ sh = self._root.win_height()
+ if isinstance(width, float) and 0 <= width <= 1:
+ width = sw*width
+ if startx is None:
+ startx = (sw - width) / 2
+ if isinstance(height, float) and 0 <= height <= 1:
+ height = sh*height
+ if starty is None:
+ starty = (sh - height) / 2
+ self._root.set_geometry(width, height, startx, starty)
+
+ def title(self, titlestring):
+ """Set title of turtle-window
+
+ Argument:
+ titlestring -- a string, to appear in the titlebar of the
+ turtle graphics window.
+
+ This is a method of Screen-class. Not available for TurtleScreen-
+ objects.
+
+ Example (for a Screen instance named screen):
+ >>> screen.title("Welcome to the turtle-zoo!")
+ """
+ if Screen._root is not None:
+ Screen._root.title(titlestring)
+ Screen._title = titlestring
def _destroy(self):
- global _root, _canvas, _pen
- root = self._canvas._root()
- if root is _root:
- _pen = None
- _root = None
- _canvas = None
+ root = self._root
+ if root is Screen._root:
+ Turtle._pen = None
+ Turtle._screen = None
+ Screen._root = None
+ Screen._canvas = None
+ TurtleScreen._RUNNING = True
root.destroy()
-def _getpen():
- global _pen
- if not _pen:
- _pen = Pen()
- return _pen
+ def bye(self):
+ """Shut the turtlegraphics window.
-class Turtle(Pen):
- pass
+ Example (for a TurtleScreen instance named screen):
+ >>> screen.bye()
+ """
+ self._destroy()
-"""For documentation of the following functions see
- the RawPen methods with the same names
-"""
+ def exitonclick(self):
+ """Go into mainloop until the mouse is clicked.
-def degrees(): _getpen().degrees()
-def radians(): _getpen().radians()
-def reset(): _getpen().reset()
-def clear(): _getpen().clear()
-def tracer(flag): _getpen().tracer(flag)
-def forward(distance): _getpen().forward(distance)
-def backward(distance): _getpen().backward(distance)
-def left(angle): _getpen().left(angle)
-def right(angle): _getpen().right(angle)
-def up(): _getpen().up()
-def down(): _getpen().down()
-def width(width): _getpen().width(width)
-def color(*args): _getpen().color(*args)
-def write(arg, move=0): _getpen().write(arg, move)
-def fill(flag): _getpen().fill(flag)
-def begin_fill(): _getpen().begin_fill()
-def end_fill(): _getpen().end_fill()
-def circle(radius, extent=None): _getpen().circle(radius, extent)
-def goto(*args): _getpen().goto(*args)
-def heading(): return _getpen().heading()
-def setheading(angle): _getpen().setheading(angle)
-def position(): return _getpen().position()
-def window_width(): return _getpen().window_width()
-def window_height(): return _getpen().window_height()
-def setx(xpos): _getpen().setx(xpos)
-def sety(ypos): _getpen().sety(ypos)
-def towards(*args): return _getpen().towards(*args)
-
-def done(): _root.mainloop()
-def delay(delay): return _getpen().delay(delay)
-def speed(speed): return _getpen().speed(speed)
-
-for methodname in dir(RawPen):
- """ copies RawPen docstrings to module functions of same name """
- if not methodname.startswith("_"):
- eval(methodname).__doc__ = RawPen.__dict__[methodname].__doc__
-
-
-def setup(**geometry):
- """ Sets the size and position of the main window.
-
- Keywords are width, height, startx and starty:
-
- width: either a size in pixels or a fraction of the screen.
- Default is 50% of screen.
- height: either the height in pixels or a fraction of the screen.
- Default is 75% of screen.
-
- Setting either width or height to None before drawing will force
- use of default geometry as in older versions of turtle.py
-
- startx: starting position in pixels from the left edge of the screen.
- Default is to center window. Setting startx to None is the default
- and centers window horizontally on screen.
-
- starty: starting position in pixels from the top edge of the screen.
- Default is to center window. Setting starty to None is the default
- and centers window vertically on screen.
-
- Examples:
- >>> setup (width=200, height=200, startx=0, starty=0)
-
- sets window to 200x200 pixels, in upper left of screen
-
- >>> setup(width=.75, height=0.5, startx=None, starty=None)
-
- sets window to 75% of screen by 50% of screen and centers
-
- >>> setup(width=None)
-
- forces use of default geometry as in older versions of turtle.py
- """
-
- global _width, _height, _startx, _starty
-
- width = geometry.get('width',_width)
- if width >= 0 or width is None:
- _width = width
- else:
- raise ValueError, "width can not be less than 0"
+ No arguments.
- height = geometry.get('height',_height)
- if height >= 0 or height is None:
- _height = height
- else:
- raise ValueError, "height can not be less than 0"
+ Bind bye() method to mouseclick on TurtleScreen.
+ If "using_IDLE" - value in configuration dictionary is False
+ (default value), enter mainloop.
+ If IDLE with -n switch (no subprocess) is used, this value should be
+ set to True in turtle.cfg. In this case IDLE's mainloop
+ is active also for the client script.
- startx = geometry.get('startx', _startx)
- if startx >= 0 or startx is None:
- _startx = _startx
- else:
- raise ValueError, "startx can not be less than 0"
+ This is a method of the Screen-class and not available for
+ TurtleScreen instances.
- starty = geometry.get('starty', _starty)
- if starty >= 0 or starty is None:
- _starty = starty
- else:
- raise ValueError, "startx can not be less than 0"
+ Example (for a Screen instance named screen):
+ >>> screen.exitonclick()
+ """
+ def exitGracefully(x, y):
+ """Screen.bye() with two dummy-parameters"""
+ self.bye()
+ self.onclick(exitGracefully)
+ if _CFG["using_IDLE"]:
+ return
+ try:
+ mainloop()
+ except AttributeError:
+ exit(0)
- if _root and _width and _height:
- if 0 < _width <= 1:
- _width = _root.winfo_screenwidth() * +width
- if 0 < _height <= 1:
- _height = _root.winfo_screenheight() * _height
- # center window on screen
- if _startx is None:
- _startx = (_root.winfo_screenwidth() - _width) / 2
+class Turtle(RawTurtle):
+ """RawTurtle auto-crating (scrolled) canvas.
- if _starty is None:
- _starty = (_root.winfo_screenheight() - _height) / 2
+ When a Turtle object is created or a function derived from some
+ Turtle method is called a TurtleScreen object is automatically created.
+ """
+ _pen = None
+ _screen = None
- _root.geometry("%dx%d+%d+%d" % (_width, _height, _startx, _starty))
+ def __init__(self,
+ shape=_CFG["shape"],
+ undobuffersize=_CFG["undobuffersize"],
+ visible=_CFG["visible"]):
+ if Turtle._screen is None:
+ Turtle._screen = Screen()
+ RawTurtle.__init__(self, Turtle._screen,
+ shape=shape,
+ undobuffersize=undobuffersize,
+ visible=visible)
-def title(title):
- """Set the window title.
+Pen = Turtle
- By default this is set to 'Turtle Graphics'
+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.
+
+ Optional argument:
+ filename -- a string, used as filename
+ default value is turtle_docstringdict
+
+ Has to be called explicitely, (not used by the turtle-graphics classes)
+ The docstring dictionary will be written to the Python script <filname>.py
+ It is intended to serve as a template for translation of the docstrings
+ into different languages.
+ """
+ docsdict = {}
- Example:
- >>> title("My Window")
+ for methodname in _tg_screen_functions:
+ key = "Screen."+methodname
+ docsdict[key] = eval(key).__doc__
+ for methodname in _tg_turtle_functions:
+ key = "Turtle."+methodname
+ docsdict[key] = eval(key).__doc__
+
+ f = open("%s.py" % filename,"w")
+ keys = sorted([x for x in docsdict.keys()
+ if x.split('.')[1] not in _alias_list])
+ f.write('docsdict = {\n\n')
+ for key in keys[:-1]:
+ f.write('%s :\n' % repr(key))
+ f.write(' """%s\n""",\n\n' % docsdict[key])
+ key = keys[-1]
+ f.write('%s :\n' % repr(key))
+ f.write(' """%s\n"""\n\n' % docsdict[key])
+ f.write("}\n")
+ f.close()
+
+def read_docstrings(lang):
+ """Read in docstrings from lang-specific docstring dictionary.
+
+ Transfer docstrings, translated to lang, from a dictionary-file
+ to the methods of classes Screen and Turtle and - in revised form -
+ to the corresponding functions.
"""
+ modname = "turtle_docstringdict_%(language)s" % {'language':lang.lower()}
+ module = __import__(modname)
+ docsdict = module.docsdict
+ for key in docsdict:
+ #print key
+ try:
+ eval(key).im_func.__doc__ = docsdict[key]
+ except:
+ print "Bad docstring-entry: %s" % key
- global _title
- _title = title
+_LANGUAGE = _CFG["language"]
-def demo():
- reset()
- tracer(1)
- up()
- backward(100)
- down()
- # draw 3 squares; the last filled
- width(3)
- for i in range(3):
- if i == 2:
- fill(1)
- for j in range(4):
- forward(20)
- left(90)
- if i == 2:
- color("maroon")
- fill(0)
+try:
+ if _LANGUAGE != "english":
+ read_docstrings(_LANGUAGE)
+except ImportError:
+ print "Cannot find docsdict for", _LANGUAGE
+except:
+ print ("Unknown Error when trying to import %s-docstring-dictionary" %
+ _LANGUAGE)
+
+
+def getmethparlist(ob):
+ "Get strings describing the arguments for the given object"
+ argText1 = argText2 = ""
+ # bit of a hack for methods - turn it into a function
+ # but we drop the "self" param.
+ if type(ob)==types.MethodType:
+ fob = ob.im_func
+ argOffset = 1
+ else:
+ fob = ob
+ argOffset = 0
+ # Try and build one for Python defined functions
+ if type(fob) in [types.FunctionType, types.LambdaType]:
+ try:
+ counter = fob.func_code.co_argcount
+ items2 = list(fob.func_code.co_varnames[argOffset:counter])
+ realArgs = fob.func_code.co_varnames[argOffset:counter]
+ defaults = fob.func_defaults or []
+ defaults = list(map(lambda name: "=%s" % repr(name), defaults))
+ defaults = [""] * (len(realArgs)-len(defaults)) + defaults
+ items1 = map(lambda arg, dflt: arg+dflt, realArgs, defaults)
+ if fob.func_code.co_flags & 0x4:
+ items1.append("*"+fob.func_code.co_varnames[counter])
+ items2.append("*"+fob.func_code.co_varnames[counter])
+ counter += 1
+ if fob.func_code.co_flags & 0x8:
+ items1.append("**"+fob.func_code.co_varnames[counter])
+ items2.append("**"+fob.func_code.co_varnames[counter])
+ argText1 = ", ".join(items1)
+ argText1 = "(%s)" % argText1
+ argText2 = ", ".join(items2)
+ argText2 = "(%s)" % argText2
+ except:
+ pass
+ return argText1, argText2
+
+def _turtle_docrevise(docstr):
+ """To reduce docstrings from RawTurtle class for functions
+ """
+ import re
+ if docstr is None:
+ return None
+ turtlename = _CFG["exampleturtle"]
+ newdocstr = docstr.replace("%s." % turtlename,"")
+ parexp = re.compile(r' \(.+ %s\):' % turtlename)
+ newdocstr = parexp.sub(":", newdocstr)
+ return newdocstr
+
+def _screen_docrevise(docstr):
+ """To reduce docstrings from TurtleScreen class for functions
+ """
+ import re
+ if docstr is None:
+ return None
+ screenname = _CFG["examplescreen"]
+ newdocstr = docstr.replace("%s." % screenname,"")
+ parexp = re.compile(r' \(.+ %s\):' % screenname)
+ newdocstr = parexp.sub(":", newdocstr)
+ return newdocstr
+
+## The following mechanism makes all methods of RawTurtle and Turtle available
+## 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__)
+
+
+done = mainloop = TK.mainloop
+del pl1, pl2, defstr
+
+if __name__ == "__main__":
+ def switchpen():
+ if isdown():
+ pu()
+ else:
+ pd()
+
+ def demo1():
+ """Demo of old turtle.py - module"""
+ reset()
+ tracer(True)
up()
- forward(30)
+ backward(100)
down()
- width(1)
- color("black")
- # move out of the way
- tracer(0)
- up()
- right(90)
- forward(100)
- right(90)
- forward(100)
- right(180)
- down()
- # some text
- write("startstart", 1)
- write("start", 1)
- color("red")
- # staircase
- for i in range(5):
- forward(20)
- left(90)
- forward(20)
- right(90)
- # filled staircase
- fill(1)
- for i in range(5):
- forward(20)
- left(90)
- forward(20)
- right(90)
- fill(0)
- tracer(1)
- # more text
- write("end")
-
-def demo2():
- # exercises some new and improved features
- speed('fast')
- width(3)
-
- # draw a segmented half-circle
- setheading(towards(0,0))
- x,y = position()
- r = (x**2+y**2)**.5/2.0
- right(90)
- pendown = True
- for i in range(18):
- if pendown:
+ # draw 3 squares; the last filled
+ width(3)
+ for i in range(3):
+ if i == 2:
+ fill(1)
+ for _ in range(4):
+ forward(20)
+ left(90)
+ if i == 2:
+ color("maroon")
+ fill(0)
up()
- pendown = False
- else:
+ forward(30)
down()
- pendown = True
- circle(r,10)
- sleep(2)
-
- reset()
- left(90)
-
- # draw a series of triangles
- l = 10
- color("green")
- width(3)
- left(180)
- sp = 5
- for i in range(-2,16):
- if i > 0:
- color(1.0-0.05*i,0,0.05*i)
- fill(1)
- color("green")
- for j in range(3):
- forward(l)
- left(120)
- l += 10
- left(15)
- if sp > 0:
- sp = sp-1
- speed(speeds[sp])
- color(0.25,0,0.75)
- fill(0)
-
- # draw and fill a concave shape
- left(120)
- up()
- forward(70)
- right(30)
- down()
- color("red")
- speed("fastest")
- fill(1)
- for i in range(4):
- circle(50,90)
+ width(1)
+ color("black")
+ # move out of the way
+ tracer(False)
+ up()
right(90)
- forward(30)
+ forward(100)
right(90)
- color("yellow")
- fill(0)
- left(90)
- up()
- forward(30)
- down();
-
- color("red")
-
- # create a second turtle and make the original pursue and catch it
- turtle=Turtle()
- turtle.reset()
- turtle.left(90)
- turtle.speed('normal')
- turtle.up()
- turtle.goto(280,40)
- turtle.left(24)
- turtle.down()
- turtle.speed('fast')
- turtle.color("blue")
- turtle.width(2)
- speed('fastest')
-
- # turn default turtle towards new turtle object
- setheading(towards(turtle))
- while ( abs(position()[0]-turtle.position()[0])>4 or
- abs(position()[1]-turtle.position()[1])>4):
- turtle.forward(3.5)
- turtle.left(0.6)
- # turn default turtle towards new turtle object
+ forward(100)
+ right(180)
+ down()
+ # some text
+ write("startstart", 1)
+ write("start", 1)
+ color("red")
+ # staircase
+ for i in range(5):
+ forward(20)
+ left(90)
+ forward(20)
+ right(90)
+ # filled staircase
+ tracer(True)
+ fill(1)
+ for i in range(5):
+ forward(20)
+ left(90)
+ forward(20)
+ right(90)
+ fill(0)
+ # more text
+
+ def demo2():
+ """Demo of some new features."""
+ speed(1)
+ st()
+ pensize(3)
+ setheading(towards(0, 0))
+ radius = distance(0, 0)/2.0
+ rt(90)
+ for _ in range(18):
+ switchpen()
+ circle(radius, 10)
+ write("wait a moment...")
+ while undobufferentries():
+ undo()
+ reset()
+ lt(90)
+ colormode(255)
+ laenge = 10
+ pencolor("green")
+ pensize(3)
+ lt(180)
+ for i in range(-2, 16):
+ if i > 0:
+ begin_fill()
+ fillcolor(255-15*i, 0, 15*i)
+ for _ in range(3):
+ fd(laenge)
+ lt(120)
+ laenge += 10
+ lt(15)
+ speed((speed()+1)%12)
+ end_fill()
+
+ lt(120)
+ pu()
+ fd(70)
+ rt(30)
+ pd()
+ color("red","yellow")
+ speed(0)
+ fill(1)
+ for _ in range(4):
+ circle(50, 90)
+ rt(90)
+ fd(30)
+ rt(90)
+ fill(0)
+ lt(90)
+ pu()
+ fd(30)
+ pd()
+ shape("turtle")
+
+ tri = getturtle()
+ tri.resizemode("auto")
+ turtle = Turtle()
+ turtle.resizemode("auto")
+ turtle.shape("turtle")
+ turtle.reset()
+ turtle.left(90)
+ turtle.speed(0)
+ turtle.up()
+ turtle.goto(280, 40)
+ turtle.lt(30)
+ turtle.down()
+ turtle.speed(6)
+ turtle.color("blue","orange")
+ turtle.pensize(2)
+ tri.speed(6)
setheading(towards(turtle))
- forward(4)
- write("CAUGHT! ", move=True)
-
-
+ count = 1
+ while tri.distance(turtle) > 4:
+ turtle.fd(3.5)
+ turtle.lt(0.6)
+ tri.setheading(tri.towards(turtle))
+ tri.fd(4)
+ if count % 20 == 0:
+ turtle.stamp()
+ tri.stamp()
+ switchpen()
+ count += 1
+ tri.write("CAUGHT! ", font=("Arial", 16, "bold"), align="right")
+ tri.pencolor("black")
+ tri.pencolor("red")
+
+ def baba(xdummy, ydummy):
+ clearscreen()
+ bye()
+
+ time.sleep(2)
+
+ while undobufferentries():
+ tri.undo()
+ turtle.undo()
+ tri.fd(50)
+ tri.write(" Click me!", font = ("Courier", 12, "bold") )
+ tri.onclick(baba, 1)
-if __name__ == '__main__':
- demo()
- sleep(3)
+ demo1()
demo2()
- done()
+ exitonclick()
Modified: python/branches/tlee-ast-optimize/Lib/test/test_complex.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/test/test_complex.py (original)
+++ python/branches/tlee-ast-optimize/Lib/test/test_complex.py Thu Jun 5 17:42:10 2008
@@ -373,6 +373,14 @@
except (OSError, IOError):
pass
+ def test_getnewargs(self):
+ self.assertEqual((1+2j).__getnewargs__(), (1.0, 2.0))
+ self.assertEqual((1-2j).__getnewargs__(), (1.0, -2.0))
+ self.assertEqual((2j).__getnewargs__(), (0.0, 2.0))
+ self.assertEqual((-0j).__getnewargs__(), (0.0, -0.0))
+ self.assertEqual(complex(0, INF).__getnewargs__(), (0.0, INF))
+ self.assertEqual(complex(INF, 0).__getnewargs__(), (INF, 0.0))
+
if float.__getformat__("double").startswith("IEEE"):
def test_plus_minus_0j(self):
# test that -0j and 0j literals are not identified
Modified: python/branches/tlee-ast-optimize/Mac/IDLE/Makefile.in
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/IDLE/Makefile.in (original)
+++ python/branches/tlee-ast-optimize/Mac/IDLE/Makefile.in Thu Jun 5 17:42:10 2008
@@ -42,7 +42,7 @@
$(srcdir)/../Icons/PythonSource.icns \
$(srcdir)/../Icons/PythonCompiled.icns Info.plist
rm -fr IDLE.app
- $(RUNSHARED) $(BUILDPYTHON) $(BUNDLEBULDER) \
+ $(RUNSHARED) arch -ppc -i386 $(BUILDPYTHON) $(BUNDLEBULDER) \
--builddir=. \
--name=IDLE \
--link-exec \
@@ -51,7 +51,7 @@
--iconfile=$(srcdir)/../Icons/IDLE.icns \
--resource=$(srcdir)/../Icons/PythonSource.icns \
--resource=$(srcdir)/../Icons/PythonCompiled.icns \
- --python=$(prefix)/Resources/Python.app/Contents/MacOS/Python \
+ --python=$(prefix)/Resources/Python.app/Contents/MacOS/$(PYTHONFRAMEWORK)`test -f "$(DESTDIR)$(prefix)/Resources/Python.app/Contents/MacOS/$(PYTHONFRAMEWORK)-32" && echo "-32"` \
build
Modified: python/branches/tlee-ast-optimize/Mac/IDLE/idlemain.py
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/IDLE/idlemain.py (original)
+++ python/branches/tlee-ast-optimize/Mac/IDLE/idlemain.py Thu Jun 5 17:42:10 2008
@@ -13,7 +13,10 @@
# Make sure sys.executable points to the python interpreter inside the
# framework, instead of at the helper executable inside the application
# bundle (the latter works, but doesn't allow access to the window server)
-sys.executable = os.path.join(sys.prefix, 'bin', 'python')
+if sys.executable.endswith('-32'):
+ sys.executable = os.path.join(sys.prefix, 'bin', 'python-32')
+else:
+ sys.executable = os.path.join(sys.prefix, 'bin', 'python')
# Look for the -psn argument that the launcher adds and remove it, it will
# only confuse the IDLE startup code.
Modified: python/branches/tlee-ast-optimize/Mac/Makefile.in
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Makefile.in (original)
+++ python/branches/tlee-ast-optimize/Mac/Makefile.in Thu Jun 5 17:42:10 2008
@@ -49,12 +49,42 @@
installapps: install_Python install_BuildApplet install_PythonLauncher \
install_IDLE checkapplepython install_pythonw install_versionedtools
+installapps4way: install_Python4way install_BuildApplet install_PythonLauncher install_IDLE install_pythonw4way install_versionedtools
+
+
install_pythonw: pythonw
$(INSTALL_PROGRAM) $(STRIPFLAG) pythonw "$(DESTDIR)$(prefix)/bin/pythonw$(VERSION)"
$(INSTALL_PROGRAM) $(STRIPFLAG) pythonw "$(DESTDIR)$(prefix)/bin/python$(VERSION)"
ln -sf python$(VERSION) "$(DESTDIR)$(prefix)/bin/python"
ln -sf pythonw$(VERSION) "$(DESTDIR)$(prefix)/bin/pythonw"
+
+# Install 3 variants of python/pythonw:
+# - 32-bit (i386 and ppc)
+# - 64-bit (x86_64 and ppc64)
+# - all (all four architectures)
+# - Make 'python' and 'pythonw' aliases for the 32-bit variant
+install_pythonw4way: pythonw-32 pythonw-64 pythonw
+ $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw-64 "$(DESTDIR)$(prefix)/bin/pythonw$(VERSION)-64"
+ $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw-64 "$(DESTDIR)$(prefix)/bin/python$(VERSION)-64"
+ ln -sf python$(VERSION)-64 "$(DESTDIR)$(prefix)/bin/python-64"
+ ln -sf pythonw$(VERSION)-64 "$(DESTDIR)$(prefix)/bin/pythonw-64"
+
+ $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw-32 "$(DESTDIR)$(prefix)/bin/pythonw$(VERSION)-32"
+ $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw-32 "$(DESTDIR)$(prefix)/bin/python$(VERSION)-32"
+ ln -sf python$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/python-32"
+ ln -sf pythonw$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/pythonw-32"
+
+ $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw "$(DESTDIR)$(prefix)/bin/pythonw$(VERSION)-all"
+ $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw "$(DESTDIR)$(prefix)/bin/python$(VERSION)-all"
+ ln -sf python$(VERSION)-all "$(DESTDIR)$(prefix)/bin/python-all"
+ ln -sf pythonw$(VERSION)-all "$(DESTDIR)$(prefix)/bin/pythonw-all"
+
+ ln -sf pythonw$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/pythonw$(VERSION)"
+ ln -sf python$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/python$(VERSION)"
+ ln -sf pythonw$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/pythonw"
+ ln -sf python$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/python"
+
#
# Install unix tools in /usr/local/bin. These are just aliases for the
# actual installation inside the framework.
@@ -65,11 +95,16 @@
fi
for fn in python pythonw idle pydoc python-config smtpd.py \
python$(VERSION) pythonw$(VERSION) idle$(VERSION) \
- pydoc$(VERSION) python-config$(VERSION) smtpd$(VERSION).py ;\
+ pydoc$(VERSION) python$(VERSION)-config smtpd$(VERSION).py ;\
do \
ln -fs "$(prefix)/bin/$${fn}" "$(DESTDIR)$(FRAMEWORKUNIXTOOLSPREFIX)/bin/$${fn}" ;\
done
+
+# TODO: install symlinks for -32, -64 and -all as well
+installunixtools4way: installunixtools
+
+
#
# Like installunixtools, but only install links to the versioned binaries.
#
@@ -78,18 +113,20 @@
$(INSTALL) -d -m $(DIRMODE) "$(DESTDIR)$(FRAMEWORKUNIXTOOLSPREFIX)/bin" ;\
fi
for fn in python$(VERSION) pythonw$(VERSION) idle$(VERSION) \
- pydoc$(VERSION) python-config$(VERSION) smtpd$(VERSION).py ;\
+ pydoc$(VERSION) python$(VERSION)-config) smtpd$(VERSION).py ;\
do \
ln -fs "$(prefix)/bin/$${fn}" "$(DESTDIR)$(FRAMEWORKUNIXTOOLSPREFIX)/bin/$${fn}" ;\
done
+# TODO: -32, -64 and -all variants
+altinstallunixtools4way: altinstallunixtools
# By default most tools are installed without a version in their basename, to
# make it easier to install (and use) several python versions side-by-side move
# the tools to a version-specific name and add the non-versioned name as an
# alias.
install_versionedtools:
- for fn in idle pydoc python-config ;\
+ for fn in idle pydoc ;\
do \
if [ -h "$(DESTDIR)$(prefix)/bin/$${fn}" ]; then \
continue ;\
@@ -97,6 +134,10 @@
mv "$(DESTDIR)$(prefix)/bin/$${fn}" "$(DESTDIR)$(prefix)/bin/$${fn}$(VERSION)" ;\
ln -sf "$${fn}$(VERSION)" "$(DESTDIR)$(prefix)/bin/$${fn}" ;\
done
+ if [ ! -h "$(DESTDIR)$(prefix)/bin/python-config" ]; then \
+ mv "$(DESTDIR)$(prefix)/bin/python-config" "$(DESTDIR)$(prefix)/bin/python$(VERSION)-config" ;\
+ ln -sf "python$(VERSION)-config" "$(DESTDIR)$(prefix)/bin/python-config" ; \
+ fi
if [ ! -h "$(DESTDIR)$(prefix)/bin/smtpd.py" ]; then \
mv "$(DESTDIR)$(prefix)/bin/smtpd.py" "$(DESTDIR)$(prefix)/bin/smtpd$(VERSION).py" ;\
ln -sf "smtpd$(VERSION).py" "$(DESTDIR)$(prefix)/bin/smtpd.py" ;\
@@ -107,6 +148,13 @@
$(CC) $(LDFLAGS) -o $@ $(srcdir)/Tools/pythonw.c \
-DPYTHONWEXECUTABLE='"$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)"'
+pythonw-32: $(srcdir)/Tools/pythonw.c Makefile
+ $(CC) $(LDFLAGS) -o $@ -arch i386 -arch ppc $(srcdir)/Tools/pythonw.c \
+ -DPYTHONWEXECUTABLE='"$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)-32"'
+
+pythonw-64: $(srcdir)/Tools/pythonw.c Makefile
+ $(CC) $(LDFLAGS) -o $@ -arch x86_64 -arch ppc64 $(srcdir)/Tools/pythonw.c \
+ -DPYTHONWEXECUTABLE='"$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)-64"'
install_PythonLauncher:
cd PythonLauncher && make install DESTDIR=$(DESTDIR)
@@ -159,13 +207,19 @@
done
$(INSTALL_PROGRAM) $(STRIPFLAG) $(BUILDPYTHON) "$(DESTDIR)$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)"
+install_Python4way: install_Python
+ lipo -extract i386 -extract ppc7400 -output "$(DESTDIR)$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)-32" "$(DESTDIR)$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)"
+ lipo -extract x86_64 -extract ppc64 -output "$(DESTDIR)$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)-64" "$(DESTDIR)$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)"
+
+
+
install_IDLE:
cd IDLE && make install
install_BuildApplet:
- $(RUNSHARED) $(BUILDPYTHON) $(srcdir)/scripts/BuildApplet.py \
+ $(RUNSHARED) arch -ppc -i386 $(BUILDPYTHON) $(srcdir)/scripts/BuildApplet.py \
--destroot "$(DESTDIR)" \
- --python $(INSTALLED_PYTHONAPP) \
+ --python=$(prefix)/Resources/Python.app/Contents/MacOS/$(PYTHONFRAMEWORK)`test -f "$(DESTDIR)$(prefix)/Resources/Python.app/Contents/MacOS/$(PYTHONFRAMEWORK)-32" && echo "-32"` \
--output "$(DESTDIR)$(PYTHONAPPSDIR)/Build Applet.app" \
$(srcdir)/scripts/BuildApplet.py
@@ -225,7 +279,7 @@
done
- $(RUNSHARED) $(BUILDPYTHON) $(CACHERSRC) -v $(DESTDIR)$(MACLIBDEST) $(DESTDIR)$(MACTOOLSDEST)
+ $(RUNSHARED) arch -ppc -i386 $(BUILDPYTHON) $(CACHERSRC) -v $(DESTDIR)$(MACLIBDEST) $(DESTDIR)$(MACTOOLSDEST)
$(RUNSHARED) $(BUILDPYTHON) -Wi -tt $(compileall) -d $(MACTOOLSDEST) -x badsyntax $(DESTDIR)$(MACTOOLSDEST)
$(RUNSHARED) $(BUILDPYTHON) -O -Wi -tt $(compileall) -d $(MACTOOLSDEST) -x badsyntax $(DESTDIR)$(MACTOOLSDEST)
Modified: python/branches/tlee-ast-optimize/Mac/Modules/ColorPickermodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/ColorPickermodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/ColorPickermodule.c Thu Jun 5 17:42:10 2008
@@ -27,6 +27,9 @@
/* ----------------------------------------------------- */
+
+#ifndef __LP64__
+
static char cp_GetColor__doc__[] =
"GetColor(prompt, (r, g, b)) -> (r, g, b), ok"
;
@@ -46,11 +49,14 @@
return Py_BuildValue("O&h", QdRGB_New, &outColor, ok);
}
+#endif /* __LP64__ */
/* List of methods defined in the module */
static struct PyMethodDef cp_methods[] = {
+#ifndef __LP64__
{"GetColor", (PyCFunction)cp_GetColor, METH_VARARGS, cp_GetColor__doc__},
+#endif /* __LP64__ */
{NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
};
Modified: python/branches/tlee-ast-optimize/Mac/Modules/MacOS.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/MacOS.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/MacOS.c Thu Jun 5 17:42:10 2008
@@ -30,6 +30,7 @@
#include <Carbon/Carbon.h>
#include <ApplicationServices/ApplicationServices.h>
+
static PyObject *MacOS_Error; /* Exception MacOS.Error */
#define PATHNAMELEN 1024
@@ -40,7 +41,7 @@
typedef struct {
PyObject_HEAD
- short fRefNum;
+ FSIORefNum fRefNum;
int isclosed;
} rfobject;
@@ -54,7 +55,7 @@
do_close(rfobject *self)
{
if (self->isclosed ) return;
- (void)FSClose(self->fRefNum);
+ (void)FSCloseFork(self->fRefNum);
self->isclosed = 1;
}
@@ -68,6 +69,7 @@
long n;
PyObject *v;
OSErr err;
+ ByteCount n2;
if (self->isclosed) {
PyErr_SetString(PyExc_ValueError, "Operation on closed file");
@@ -81,13 +83,13 @@
if (v == NULL)
return NULL;
- err = FSRead(self->fRefNum, &n, PyBytes_AsString(v));
+ err = FSReadFork(self->fRefNum, fsAtMark, 0, n, PyString_AsString(v), &n2);
if (err && err != eofErr) {
PyMac_Error(err);
Py_DECREF(v);
return NULL;
}
- _PyBytes_Resize(&v, n);
+ _PyString_Resize(&v, n2);
return v;
}
@@ -109,7 +111,7 @@
}
if (!PyArg_ParseTuple(args, "s#", &buffer, &size))
return NULL;
- err = FSWrite(self->fRefNum, &size, buffer);
+ err = FSWriteFork(self->fRefNum, fsAtMark, 0, size, buffer, NULL);
if (err) {
PyMac_Error(err);
return NULL;
@@ -126,47 +128,36 @@
static PyObject *
rf_seek(rfobject *self, PyObject *args)
{
- long amount, pos;
+ long amount;
int whence = SEEK_SET;
- long eof;
+ int mode;
OSErr err;
if (self->isclosed) {
PyErr_SetString(PyExc_ValueError, "Operation on closed file");
return NULL;
}
- if (!PyArg_ParseTuple(args, "l|i", &amount, &whence))
+ if (!PyArg_ParseTuple(args, "l|i", &amount, &whence)) {
return NULL;
-
- if ((err = GetEOF(self->fRefNum, &eof)))
- goto ioerr;
+ }
switch (whence) {
case SEEK_CUR:
- if ((err = GetFPos(self->fRefNum, &pos)))
- goto ioerr;
+ mode = fsFromMark;
break;
case SEEK_END:
- pos = eof;
+ mode = fsFromLEOF;
break;
case SEEK_SET:
- pos = 0;
+ mode = fsFromStart;
break;
default:
PyErr_BadArgument();
return NULL;
}
-
- pos += amount;
-
- /* Don't bother implementing seek past EOF */
- if (pos > eof || pos < 0) {
- PyErr_BadArgument();
- return NULL;
- }
-
- if ((err = SetFPos(self->fRefNum, fsFromStart, pos)) ) {
-ioerr:
+
+ err = FSSetForkPosition(self->fRefNum, mode, amount);
+ if (err != noErr) {
PyMac_Error(err);
return NULL;
}
@@ -182,7 +173,7 @@
static PyObject *
rf_tell(rfobject *self, PyObject *args)
{
- long where;
+ long long where;
OSErr err;
if (self->isclosed) {
@@ -191,11 +182,13 @@
}
if (!PyArg_ParseTuple(args, ""))
return NULL;
- if ((err = GetFPos(self->fRefNum, &where)) ) {
+
+ err = FSGetForkPosition(self->fRefNum, &where);
+ if (err != noErr) {
PyMac_Error(err);
return NULL;
}
- return PyInt_FromLong(where);
+ return PyLong_FromLongLong(where);
}
static char rf_close__doc__[] =
@@ -281,6 +274,7 @@
Rftype__doc__ /* Documentation string */
};
+
/* End of code for Resource fork objects */
/* -------------------------------------------------------- */
@@ -292,17 +286,61 @@
static PyObject *
MacOS_GetCreatorAndType(PyObject *self, PyObject *args)
{
- FSSpec fss;
- FInfo info;
PyObject *creator, *type, *res;
OSErr err;
-
- if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSSpec, &fss))
+ FSRef ref;
+ FSCatalogInfo cataloginfo;
+ FileInfo* finfo;
+
+ if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSRef, &ref)) {
+#ifndef __LP64__
+ /* This function is documented to take an FSSpec as well,
+ * which only works in 32-bit mode.
+ */
+ PyErr_Clear();
+ FSSpec fss;
+ FInfo info;
+
+ if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSSpec, &fss))
+ return NULL;
+
+ if ((err = FSpGetFInfo(&fss, &info)) != noErr) {
+ return PyErr_Mac(MacOS_Error, err);
+ }
+ creator = PyString_FromStringAndSize(
+ (char *)&info.fdCreator, 4);
+ type = PyString_FromStringAndSize((char *)&info.fdType, 4);
+ res = Py_BuildValue("OO", creator, type);
+ Py_DECREF(creator);
+ Py_DECREF(type);
+ return res;
+#else /* __LP64__ */
+ return NULL;
+#endif /* __LP64__ */
+ }
+
+ err = FSGetCatalogInfo(&ref,
+ kFSCatInfoFinderInfo|kFSCatInfoNodeFlags, &cataloginfo,
+ NULL, NULL, NULL);
+ if (err != noErr) {
+ PyErr_Mac(MacOS_Error, err);
return NULL;
- if ((err = FSpGetFInfo(&fss, &info)) != noErr)
- return PyErr_Mac(MacOS_Error, err);
- creator = PyBytes_FromStringAndSize((char *)&info.fdCreator, 4);
- type = PyBytes_FromStringAndSize((char *)&info.fdType, 4);
+ }
+
+ if ((cataloginfo.nodeFlags & kFSNodeIsDirectoryMask) != 0) {
+ /* Directory: doesn't have type/creator info.
+ *
+ * The specific error code is for backward compatibility with
+ * earlier versions.
+ */
+ PyErr_Mac(MacOS_Error, fnfErr);
+ return NULL;
+
+ }
+ finfo = (FileInfo*)&(cataloginfo.finderInfo);
+ creator = PyString_FromStringAndSize((char*)&(finfo->fileCreator), 4);
+ type = PyString_FromStringAndSize((char*)&(finfo->fileType), 4);
+
res = Py_BuildValue("OO", creator, type);
Py_DECREF(creator);
Py_DECREF(type);
@@ -314,20 +352,66 @@
static PyObject *
MacOS_SetCreatorAndType(PyObject *self, PyObject *args)
{
- FSSpec fss;
ResType creator, type;
- FInfo info;
+ FSRef ref;
+ FileInfo* finfo;
OSErr err;
-
+ FSCatalogInfo cataloginfo;
+
if (!PyArg_ParseTuple(args, "O&O&O&",
+ PyMac_GetFSRef, &ref, PyMac_GetOSType, &creator, PyMac_GetOSType, &type)) {
+#ifndef __LP64__
+ /* Try to handle FSSpec arguments, for backward compatibility */
+ FSSpec fss;
+ FInfo info;
+
+ if (!PyArg_ParseTuple(args, "O&O&O&",
PyMac_GetFSSpec, &fss, PyMac_GetOSType, &creator, PyMac_GetOSType, &type))
+ return NULL;
+
+ if ((err = FSpGetFInfo(&fss, &info)) != noErr)
+ return PyErr_Mac(MacOS_Error, err);
+
+ info.fdCreator = creator;
+ info.fdType = type;
+
+ if ((err = FSpSetFInfo(&fss, &info)) != noErr)
+ return PyErr_Mac(MacOS_Error, err);
+ Py_INCREF(Py_None);
+ return Py_None;
+#else /* __LP64__ */
+ return NULL;
+#endif /* __LP64__ */
+ }
+
+ err = FSGetCatalogInfo(&ref,
+ kFSCatInfoFinderInfo|kFSCatInfoNodeFlags, &cataloginfo,
+ NULL, NULL, NULL);
+ if (err != noErr) {
+ PyErr_Mac(MacOS_Error, err);
+ return NULL;
+ }
+
+ if ((cataloginfo.nodeFlags & kFSNodeIsDirectoryMask) != 0) {
+ /* Directory: doesn't have type/creator info.
+ *
+ * The specific error code is for backward compatibility with
+ * earlier versions.
+ */
+ PyErr_Mac(MacOS_Error, fnfErr);
+ return NULL;
+
+ }
+ finfo = (FileInfo*)&(cataloginfo.finderInfo);
+ finfo->fileCreator = creator;
+ finfo->fileType = type;
+
+ err = FSSetCatalogInfo(&ref, kFSCatInfoFinderInfo, &cataloginfo);
+ if (err != noErr) {
+ PyErr_Mac(MacOS_Error, fnfErr);
return NULL;
- if ((err = FSpGetFInfo(&fss, &info)) != noErr)
- return PyErr_Mac(MacOS_Error, err);
- info.fdCreator = creator;
- info.fdType = type;
- if ((err = FSpSetFInfo(&fss, &info)) != noErr)
- return PyErr_Mac(MacOS_Error, err);
+ }
+
Py_INCREF(Py_None);
return Py_None;
}
@@ -399,6 +483,9 @@
return Py_BuildValue("s", buf);
}
+
+#ifndef __LP64__
+
static char splash_doc[] = "Open a splash-screen dialog by resource-id (0=close)";
static PyObject *
@@ -417,7 +504,7 @@
return NULL;
olddialog = curdialog;
curdialog = NULL;
-
+
if ( resid != -1 ) {
curdialog = GetNewDialog(resid, NULL, (WindowPtr)-1);
if ( curdialog ) {
@@ -452,11 +539,13 @@
if (!PyArg_ParseTuple(args, "O&|O", PyMac_GetStr255, message, &object))
return NULL;
+
DebugStr(message);
Py_INCREF(Py_None);
return Py_None;
}
+
static char SysBeep_doc[] = "BEEEEEP!!!";
static PyObject *
@@ -471,6 +560,8 @@
return Py_None;
}
+#endif /* __LP64__ */
+
static char WMAvailable_doc[] =
"True if this process can interact with the display."
"Will foreground the application on the first call as a side-effect."
@@ -530,51 +621,37 @@
{
OSErr err;
char *mode = "r";
- FSSpec fss;
- SignedByte permission = 1;
+ FSRef ref;
+ SInt8 permission = fsRdPerm;
rfobject *fp;
+ HFSUniStr255 name;
- if (!PyArg_ParseTuple(args, "O&|s", PyMac_GetFSSpec, &fss, &mode))
+ if (!PyArg_ParseTuple(args, "O&|s", PyMac_GetFSRef, &ref, &mode))
return NULL;
while (*mode) {
switch (*mode++) {
case '*': break;
- case 'r': permission = 1; break;
- case 'w': permission = 2; break;
+ case 'r': permission = fsRdPerm; break;
+ case 'w': permission = fsWrPerm; break;
case 'b': break;
default:
PyErr_BadArgument();
return NULL;
}
}
+
+ err = FSGetResourceForkName(&name);
+ if (err != noErr) {
+ PyMac_Error(err);
+ return NULL;
+ }
if ( (fp = newrfobject()) == NULL )
return NULL;
-
- err = HOpenRF(fss.vRefNum, fss.parID, fss.name, permission, &fp->fRefNum);
+
- if ( err == fnfErr ) {
- /* In stead of doing complicated things here to get creator/type
- ** correct we let the standard i/o library handle it
- */
- FILE *tfp;
- char pathname[PATHNAMELEN];
-
- if ( (err=PyMac_GetFullPathname(&fss, pathname, PATHNAMELEN)) ) {
- PyMac_Error(err);
- Py_DECREF(fp);
- return NULL;
- }
-
- if ( (tfp = fopen(pathname, "w")) == NULL ) {
- PyMac_Error(fnfErr); /* What else... */
- Py_DECREF(fp);
- return NULL;
- }
- fclose(tfp);
- err = HOpenRF(fss.vRefNum, fss.parID, fss.name, permission, &fp->fRefNum);
- }
- if ( err ) {
+ err = FSOpenFork(&ref, name.length, name.unicode, permission, &fp->fRefNum);
+ if (err != noErr) {
Py_DECREF(fp);
PyMac_Error(err);
return NULL;
@@ -584,15 +661,18 @@
}
+
static PyMethodDef MacOS_Methods[] = {
{"GetCreatorAndType", MacOS_GetCreatorAndType, 1, getcrtp_doc},
{"SetCreatorAndType", MacOS_SetCreatorAndType, 1, setcrtp_doc},
{"GetErrorString", MacOS_GetErrorString, 1, geterr_doc},
{"openrf", MacOS_openrf, 1, openrf_doc},
+#ifndef __LP64__
{"splash", MacOS_splash, 1, splash_doc},
{"DebugStr", MacOS_DebugStr, 1, DebugStr_doc},
- {"GetTicks", MacOS_GetTicks, 1, GetTicks_doc},
{"SysBeep", MacOS_SysBeep, 1, SysBeep_doc},
+#endif /* __LP64__ */
+ {"GetTicks", MacOS_GetTicks, 1, GetTicks_doc},
{"WMAvailable", MacOS_WMAvailable, 1, WMAvailable_doc},
{NULL, NULL} /* Sentinel */
};
Modified: python/branches/tlee-ast-optimize/Mac/Modules/Nav.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/Nav.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/Nav.c Thu Jun 5 17:42:10 2008
@@ -184,18 +184,22 @@
} else if( strcmp(keystr, "preferenceKey") == 0 ) {
if ( !PyArg_Parse(value, "O&", PyMac_GetOSType, &opt->preferenceKey) )
return 0;
+#ifndef __LP64__
} else if( strcmp(keystr, "popupExtension") == 0 ) {
if ( !PyArg_Parse(value, "O&", ResObj_Convert, &opt->popupExtension) )
return 0;
+#endif /* !__LP64__ */
} else if( eventProcP && strcmp(keystr, "eventProc") == 0 ) {
*eventProcP = my_eventProcUPP;
} else if( previewProcP && strcmp(keystr, "previewProc") == 0 ) {
*previewProcP = my_previewProcUPP;
} else if( filterProcP && strcmp(keystr, "filterProc") == 0 ) {
*filterProcP = my_filterProcUPP;
+#ifndef __LP64__
} else if( typeListP && strcmp(keystr, "typeList") == 0 ) {
if ( !PyArg_Parse(value, "O&", ResObj_Convert, typeListP) )
return 0;
+#endif /* !__LP64__ */
} else if( fileTypeP && strcmp(keystr, "fileType") == 0 ) {
if ( !PyArg_Parse(value, "O&", PyMac_GetOSType, fileTypeP) )
return 0;
@@ -301,13 +305,26 @@
static PyObject *
navrr_getattr(navrrobject *self, char *name)
{
- FSSpec fss;
FSRef fsr;
+#ifndef __LP64__
+ FSSpec fss;
+#endif /* !__LP64__ */
if( strcmp(name, "__members__") == 0 )
- return Py_BuildValue("ssssssssss", "version", "validRecord", "replacing",
- "isStationery", "translationNeeded", "selection", "selection_fsr",
+ return Py_BuildValue(
+#ifndef __LP64__
+ "ssssssssss",
+#else /* __LP64__ */
+ "ssssssssss",
+#endif /* __LP64__ */
+ "version", "validRecord", "replacing",
+ "isStationery", "translationNeeded",
+#ifndef __LP64__
+ "selection",
+#endif /* !__LP64__ */
+ "selection_fsr",
"fileTranslation", "keyScript", "saveFileName");
+
if( strcmp(name, "version") == 0 )
return Py_BuildValue("h", self->itself.version);
if( strcmp(name, "validRecord") == 0 )
@@ -318,8 +335,10 @@
return Py_BuildValue("l", (long)self->itself.isStationery);
if( strcmp(name, "translationNeeded") == 0 )
return Py_BuildValue("l", (long)self->itself.translationNeeded);
+#ifndef __LP64__
if( strcmp(name, "selection") == 0 ) {
- SInt32 i, count;
+ SInt32 i;
+ long count;
OSErr err;
PyObject *rv, *rvitem;
AEDesc desc;
@@ -348,8 +367,10 @@
}
return rv;
}
+#endif /* !__LP64__ */
if( strcmp(name, "selection_fsr") == 0 ) {
- SInt32 i, count;
+ SInt32 i;
+ long count;
OSErr err;
PyObject *rv, *rvitem;
AEDesc desc;
@@ -378,8 +399,10 @@
}
return rv;
}
+#ifndef __LP64__
if( strcmp(name, "fileTranslation") == 0 )
return ResObj_New((Handle)self->itself.fileTranslation);
+#endif
if( strcmp(name, "keyScript") == 0 )
return Py_BuildValue("h", (short)self->itself.keyScript);
if( strcmp(name, "saveFileName") == 0 )
@@ -861,7 +884,12 @@
PyErr_Mac(ErrorObject, err);
return NULL;
}
- return Py_BuildValue("{s:h,s:l,s:O&,s:O&,s:O&,s:O&,s:O&,s:O&,s:O&,s:O&,s:O&}",
+ return Py_BuildValue(
+#ifndef __LP64__
+ "{s:h,s:l,s:O&,s:O&,s:O&,s:O&,s:O&,s:O&,s:O&,s:O&,s:O&}",
+#else /* __LP64__ */
+ "{s:h,s:l,s:O&,s:O&,s:O&,s:O&,s:O&,s:O&,s:O&,s:O&}",
+#endif /* __LP64__ */
"version", dialogOptions.version,
"dialogOptionFlags", dialogOptions.dialogOptionFlags,
"location", PyMac_BuildPoint, dialogOptions.location,
@@ -871,8 +899,11 @@
"cancelButtonLabel", PyMac_BuildStr255, &dialogOptions.cancelButtonLabel,
"savedFileName", PyMac_BuildStr255, &dialogOptions.savedFileName,
"message", PyMac_BuildStr255, &dialogOptions.message,
- "preferenceKey", PyMac_BuildOSType, dialogOptions.preferenceKey,
- "popupExtension", OptResObj_New, dialogOptions.popupExtension);
+ "preferenceKey", PyMac_BuildOSType, dialogOptions.preferenceKey
+#ifndef __LP64__
+ ,"popupExtension", OptResObj_New, dialogOptions.popupExtension
+#endif /* __LP64__ */
+ );
}
/* List of methods defined in the module */
Modified: python/branches/tlee-ast-optimize/Mac/Modules/OSATerminology.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/OSATerminology.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/OSATerminology.c Thu Jun 5 17:42:10 2008
@@ -11,6 +11,7 @@
#include <Carbon/Carbon.h>
+#ifndef __LP64__
static PyObject *
PyOSA_GetAppTerminology(PyObject* self, PyObject* args)
{
@@ -68,12 +69,14 @@
if (err) return PyMac_Error(err);
return Py_BuildValue("O&i", AEDesc_New, &theDesc, didLaunch);
}
+#endif /* !__LP64__ */
/*
* List of methods defined in the module
*/
static struct PyMethodDef OSATerminology_methods[] =
{
+#ifndef __LP64__
{"GetAppTerminology",
(PyCFunction) PyOSA_GetAppTerminology,
METH_VARARGS,
@@ -82,14 +85,14 @@
(PyCFunction) PyOSA_GetSysTerminology,
METH_VARARGS,
"Get an applications system terminology, as an AEDesc object."},
+#endif /* !__LP64__ */
{NULL, (PyCFunction) NULL, 0, NULL}
};
-
void
initOSATerminology(void)
{
if (PyErr_WarnPy3k("In 3.x, OSATerminology is removed.", 1) < 0)
return;
Py_InitModule("OSATerminology", OSATerminology_methods);
-}
\ No newline at end of file
+}
Modified: python/branches/tlee-ast-optimize/Mac/Modules/ae/_AEmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/ae/_AEmodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/ae/_AEmodule.c Thu Jun 5 17:42:10 2008
@@ -683,7 +683,8 @@
return NULL;
_err = AEResumeTheCurrentEvent(&_self->ob_itself,
&reply,
- dispatcher__proc__, (long)dispatcher);
+ dispatcher__proc__,
+ (SRefCon)dispatcher);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
@@ -1154,7 +1155,7 @@
return NULL;
_err = AEInstallEventHandler(theAEEventClass,
theAEEventID,
- handler__proc__, (long)handler,
+ handler__proc__, (SRefCon)handler,
0);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
@@ -1203,7 +1204,7 @@
return NULL;
_err = AEGetEventHandler(theAEEventClass,
theAEEventID,
- &handler__proc__, (long *)&handler,
+ &handler__proc__, (SRefCon *)&handler,
0);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O",
Modified: python/branches/tlee-ast-optimize/Mac/Modules/app/_Appmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/app/_Appmodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/app/_Appmodule.c Thu Jun 5 17:42:10 2008
@@ -3,6 +3,8 @@
#include "Python.h"
+#ifndef __LP64__
+ /* Carbon GUI stuff, not available in 64-bit mode */
#include "pymactoolbox.h"
@@ -18,7 +20,7 @@
#include <Carbon/Carbon.h>
-int ThemeButtonDrawInfo_Convert(PyObject *v, ThemeButtonDrawInfo *p_itself)
+static int ThemeButtonDrawInfo_Convert(PyObject *v, ThemeButtonDrawInfo *p_itself)
{
return PyArg_Parse(v, "(iHH)", &p_itself->state, &p_itself->value, &p_itself->adornment);
}
@@ -1792,17 +1794,25 @@
};
+#else /* __LP64__ */
+
+static PyMethodDef App_methods[] = {
+ {NULL, NULL, 0}
+};
+
+#endif /* __LP64__ */
void init_App(void)
{
PyObject *m;
+#ifndef __LP64__
PyObject *d;
-
-
+#endif /* !__LP64__ */
m = Py_InitModule("_App", App_methods);
+#ifndef __LP64__
d = PyModule_GetDict(m);
App_Error = PyMac_GetOSErrException();
if (App_Error == NULL ||
@@ -1815,6 +1825,7 @@
/* Backward-compatible name */
Py_INCREF(&ThemeDrawingState_Type);
PyModule_AddObject(m, "ThemeDrawingStateType", (PyObject *)&ThemeDrawingState_Type);
+#endif /* __LP64__ */
}
/* ======================== End module _App ========================= */
Modified: python/branches/tlee-ast-optimize/Mac/Modules/carbonevt/_CarbonEvtmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/carbonevt/_CarbonEvtmodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/carbonevt/_CarbonEvtmodule.c Thu Jun 5 17:42:10 2008
@@ -3,7 +3,7 @@
#include "Python.h"
-
+#ifndef __LP64__
#include "pymactoolbox.h"
@@ -2141,20 +2141,28 @@
{NULL, NULL, 0}
};
+#else /* __LP64__ */
+
+static PyMethodDef CarbonEvents_methods[] = {
+ {NULL, NULL, 0}
+};
+
+#endif /* __LP64__ */
void init_CarbonEvt(void)
{
PyObject *m;
+#ifndef __LP64__
PyObject *d;
+#endif /* !__LP64__ */
+ m = Py_InitModule("_CarbonEvt", CarbonEvents_methods);
+#ifndef __LP64__
myEventHandlerUPP = NewEventHandlerUPP(myEventHandler);
-
-
- m = Py_InitModule("_CarbonEvt", CarbonEvents_methods);
d = PyModule_GetDict(m);
CarbonEvents_Error = PyMac_GetOSErrException();
if (CarbonEvents_Error == NULL ||
@@ -2216,6 +2224,7 @@
/* Backward-compatible name */
Py_INCREF(&EventHotKeyRef_Type);
PyModule_AddObject(m, "EventHotKeyRefType", (PyObject *)&EventHotKeyRef_Type);
+#endif /* !__LP64__ */
}
/* ===================== End module _CarbonEvt ====================== */
Modified: python/branches/tlee-ast-optimize/Mac/Modules/cg/_CGmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/cg/_CGmodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/cg/_CGmodule.c Thu Jun 5 17:42:10 2008
@@ -1025,6 +1025,7 @@
return _res;
}
+#ifndef __LP64__
static PyObject *CGContextRefObj_SyncCGContextOriginWithPort(CGContextRefObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
@@ -1055,6 +1056,7 @@
_res = Py_None;
return _res;
}
+#endif
static PyMethodDef CGContextRefObj_methods[] = {
{"CGContextSaveGState", (PyCFunction)CGContextRefObj_CGContextSaveGState, 1,
@@ -1173,10 +1175,12 @@
PyDoc_STR("() -> None")},
{"CGContextSetShouldAntialias", (PyCFunction)CGContextRefObj_CGContextSetShouldAntialias, 1,
PyDoc_STR("(int shouldAntialias) -> None")},
+#ifndef __LP64__
{"SyncCGContextOriginWithPort", (PyCFunction)CGContextRefObj_SyncCGContextOriginWithPort, 1,
PyDoc_STR("(CGrafPtr port) -> None")},
{"ClipCGContextToRegion", (PyCFunction)CGContextRefObj_ClipCGContextToRegion, 1,
PyDoc_STR("(Rect portRect, RgnHandle region) -> None")},
+#endif
{NULL, NULL, 0}
};
@@ -1254,6 +1258,7 @@
/* ------------------ End object type CGContextRef ------------------ */
+#ifndef __LP64__
static PyObject *CG_CreateCGContextForPort(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
@@ -1271,10 +1276,13 @@
return _res;
}
+#endif
static PyMethodDef CG_methods[] = {
+#ifndef __LP64__
{"CreateCGContextForPort", (PyCFunction)CG_CreateCGContextForPort, 1,
PyDoc_STR("(CGrafPtr) -> CGContextRef")},
+#endif
{NULL, NULL, 0}
};
Modified: python/branches/tlee-ast-optimize/Mac/Modules/cm/_Cmmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/cm/_Cmmodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/cm/_Cmmodule.c Thu Jun 5 17:42:10 2008
@@ -178,6 +178,7 @@
return _res;
}
+#ifndef __LP64__
static PyObject *CmpInstObj_ComponentFunctionImplemented(ComponentInstanceObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
@@ -228,6 +229,7 @@
_rv);
return _res;
}
+#endif /* !__LP64__*/
static PyMethodDef CmpInstObj_methods[] = {
{"CloseComponent", (PyCFunction)CmpInstObj_CloseComponent, 1,
@@ -240,12 +242,14 @@
PyDoc_STR("() -> (Handle _rv)")},
{"SetComponentInstanceStorage", (PyCFunction)CmpInstObj_SetComponentInstanceStorage, 1,
PyDoc_STR("(Handle theStorage) -> None")},
+#ifndef __LP64__
{"ComponentFunctionImplemented", (PyCFunction)CmpInstObj_ComponentFunctionImplemented, 1,
PyDoc_STR("(short ftnNumber) -> (long _rv)")},
{"GetComponentVersion", (PyCFunction)CmpInstObj_GetComponentVersion, 1,
PyDoc_STR("() -> (long _rv)")},
{"ComponentSetTarget", (PyCFunction)CmpInstObj_ComponentSetTarget, 1,
PyDoc_STR("(ComponentInstance target) -> (long _rv)")},
+#endif /* !__LP64__ */
{NULL, NULL, 0}
};
@@ -631,6 +635,7 @@
return _res;
}
+#ifndef __LP64__
static PyObject *CmpObj_GetComponentIconSuite(ComponentObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
@@ -648,6 +653,7 @@
ResObj_New, iconSuite);
return _res;
}
+#endif /* !__LP64__ */
static PyMethodDef CmpObj_methods[] = {
{"UnregisterComponent", (PyCFunction)CmpObj_UnregisterComponent, 1,
@@ -678,8 +684,10 @@
PyDoc_STR("(Component capturingComponent) -> (Component _rv)")},
{"UncaptureComponent", (PyCFunction)CmpObj_UncaptureComponent, 1,
PyDoc_STR("() -> None")},
+#ifndef __LP64__
{"GetComponentIconSuite", (PyCFunction)CmpObj_GetComponentIconSuite, 1,
PyDoc_STR("() -> (Handle iconSuite)")},
+#endif /* !__LP64__ */
{NULL, NULL, 0}
};
Modified: python/branches/tlee-ast-optimize/Mac/Modules/ctl/_Ctlmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/ctl/_Ctlmodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/ctl/_Ctlmodule.c Thu Jun 5 17:42:10 2008
@@ -3,6 +3,7 @@
#include "Python.h"
+#ifndef __LP64__
#include "pymactoolbox.h"
@@ -5765,13 +5766,20 @@
return (ControlPartCode)c_rv;
}
+#else /* __LP64__ */
+
+static PyMethodDef Ctl_methods[] = {
+ {NULL, NULL, 0}
+};
+
+#endif /* __LP64__ */
void init_Ctl(void)
{
PyObject *m;
- PyObject *d;
-
+#ifndef __LP64__
+ PyObject *d;
mytracker_upp = NewControlActionUPP(mytracker);
myactionproc_upp = NewControlActionUPP(myactionproc);
@@ -5783,9 +5791,11 @@
mytrackingproc_upp = NewControlUserPaneTrackingUPP(mytrackingproc);
PyMac_INIT_TOOLBOX_OBJECT_NEW(ControlHandle, CtlObj_New);
PyMac_INIT_TOOLBOX_OBJECT_CONVERT(ControlHandle, CtlObj_Convert);
-
+#endif /* !__LP64__ */
m = Py_InitModule("_Ctl", Ctl_methods);
+
+#ifndef __LP64__
d = PyModule_GetDict(m);
Ctl_Error = PyMac_GetOSErrException();
if (Ctl_Error == NULL ||
@@ -5798,6 +5808,7 @@
/* Backward-compatible name */
Py_INCREF(&Control_Type);
PyModule_AddObject(m, "ControlType", (PyObject *)&Control_Type);
+#endif /* !__LP64__ */
}
/* ======================== End module _Ctl ========================= */
Modified: python/branches/tlee-ast-optimize/Mac/Modules/dlg/_Dlgmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/dlg/_Dlgmodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/dlg/_Dlgmodule.c Thu Jun 5 17:42:10 2008
@@ -3,6 +3,7 @@
#include "Python.h"
+#ifndef __LP64__
#include "pymactoolbox.h"
@@ -1564,10 +1565,19 @@
return it;
}
+#else /* __LP64__ */
+
+static PyMethodDef Dlg_methods[] = {
+ {NULL, NULL, 0}
+};
+
+#endif /* __LP64__ */
+
void init_Dlg(void)
{
PyObject *m;
+#ifndef __LP64__
PyObject *d;
@@ -1575,9 +1585,11 @@
PyMac_INIT_TOOLBOX_OBJECT_NEW(DialogPtr, DlgObj_New);
PyMac_INIT_TOOLBOX_OBJECT_NEW(DialogPtr, DlgObj_WhichDialog);
PyMac_INIT_TOOLBOX_OBJECT_CONVERT(DialogPtr, DlgObj_Convert);
-
+#endif /* !__LP64__ */
m = Py_InitModule("_Dlg", Dlg_methods);
+
+#ifndef __LP64__
d = PyModule_GetDict(m);
Dlg_Error = PyMac_GetOSErrException();
if (Dlg_Error == NULL ||
@@ -1590,6 +1602,7 @@
/* Backward-compatible name */
Py_INCREF(&Dialog_Type);
PyModule_AddObject(m, "DialogType", (PyObject *)&Dialog_Type);
+#endif /* !__LP64__ */
}
/* ======================== End module _Dlg ========================= */
Modified: python/branches/tlee-ast-optimize/Mac/Modules/drag/_Dragmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/drag/_Dragmodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/drag/_Dragmodule.c Thu Jun 5 17:42:10 2008
@@ -3,6 +3,7 @@
#include "Python.h"
+#ifndef __LP64__
#include "pymactoolbox.h"
@@ -1106,21 +1107,28 @@
return 0;
}
#endif
-
+#else /* __LP64__ */
+static PyMethodDef Drag_methods[] = {
+ {NULL, NULL, 0}
+};
+#endif /* __LP64__ */
void init_Drag(void)
{
PyObject *m;
+#ifndef __LP64__
PyObject *d;
PyMac_INIT_TOOLBOX_OBJECT_NEW(DragRef, DragObj_New);
PyMac_INIT_TOOLBOX_OBJECT_CONVERT(DragRef, DragObj_Convert);
+#endif /* !__LP64__ */
m = Py_InitModule("_Drag", Drag_methods);
+#ifndef __LP64__
d = PyModule_GetDict(m);
Drag_Error = PyMac_GetOSErrException();
if (Drag_Error == NULL ||
@@ -1142,6 +1150,7 @@
dragglue_DrawingUPP = NewDragDrawingUPP(dragglue_Drawing);
#endif
+#endif /* !__LP64__ */
}
Modified: python/branches/tlee-ast-optimize/Mac/Modules/evt/_Evtmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/evt/_Evtmodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/evt/_Evtmodule.c Thu Jun 5 17:42:10 2008
@@ -3,6 +3,7 @@
#include "Python.h"
+#ifndef __LP64__
#include "pymactoolbox.h"
@@ -526,22 +527,32 @@
};
+#else /* __LP64__ */
+
+static PyMethodDef Evt_methods[] = {
+ {NULL, NULL, 0}
+};
+#endif /* __LP64__ */
void init_Evt(void)
{
PyObject *m;
+#ifndef __LP64__
PyObject *d;
+#endif /* __LP64__ */
m = Py_InitModule("_Evt", Evt_methods);
+#ifndef __LP64__
d = PyModule_GetDict(m);
Evt_Error = PyMac_GetOSErrException();
if (Evt_Error == NULL ||
PyDict_SetItemString(d, "Error", Evt_Error) != 0)
return;
+#endif /* __LP64__ */
}
/* ======================== End module _Evt ========================= */
Modified: python/branches/tlee-ast-optimize/Mac/Modules/file/_Filemodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/file/_Filemodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/file/_Filemodule.c Thu Jun 5 17:42:10 2008
@@ -18,30 +18,45 @@
#include <Carbon/Carbon.h>
#ifdef USE_TOOLBOX_OBJECT_GLUE
+
+#ifndef __LP64__
extern int _PyMac_GetFSSpec(PyObject *v, FSSpec *spec);
-extern int _PyMac_GetFSRef(PyObject *v, FSRef *fsr);
extern PyObject *_PyMac_BuildFSSpec(FSSpec *spec);
-extern PyObject *_PyMac_BuildFSRef(FSRef *spec);
+#define PyMac_BuildFSSpec _PyMac_BuildFSSpec
+#endif /* __LP64__*/
+extern int _PyMac_GetFSRef(PyObject *v, FSRef *fsr);
+extern PyObject *_PyMac_BuildFSRef(FSRef *spec);
+#define PyMac_BuildFSRef _PyMac_BuildFSRef
#define PyMac_GetFSSpec _PyMac_GetFSSpec
#define PyMac_GetFSRef _PyMac_GetFSRef
-#define PyMac_BuildFSSpec _PyMac_BuildFSSpec
-#define PyMac_BuildFSRef _PyMac_BuildFSRef
-#else
+
+#else /* !USE_TOOLBOX_OBJECT_GLUE */
+
+#ifndef __LP64__
extern int PyMac_GetFSSpec(PyObject *v, FSSpec *spec);
-extern int PyMac_GetFSRef(PyObject *v, FSRef *fsr);
extern PyObject *PyMac_BuildFSSpec(FSSpec *spec);
+#endif /* !__LP64__*/
+
+extern int PyMac_GetFSRef(PyObject *v, FSRef *fsr);
extern PyObject *PyMac_BuildFSRef(FSRef *spec);
-#endif
+
+#endif /* !USE_TOOLBOX_OBJECT_GLUE */
/* Forward declarations */
-static PyObject *FInfo_New(FInfo *itself);
static PyObject *FSRef_New(FSRef *itself);
+#ifndef __LP64__
+static PyObject *FInfo_New(FInfo *itself);
+
static PyObject *FSSpec_New(FSSpec *itself);
+#define FSSpec_Convert PyMac_GetFSSpec
+#endif /* !__LP64__ */
+
static PyObject *Alias_New(AliasHandle itself);
+#ifndef __LP64__
static int FInfo_Convert(PyObject *v, FInfo *p_itself);
+#endif /* !__LP64__ */
#define FSRef_Convert PyMac_GetFSRef
-#define FSSpec_Convert PyMac_GetFSSpec
static int Alias_Convert(PyObject *v, AliasHandle *p_itself);
/*
@@ -62,6 +77,7 @@
/*
** Optional fsspec and fsref pointers. None will pass NULL
*/
+#ifndef __LP64__
static int
myPyMac_GetOptFSSpecPtr(PyObject *v, FSSpec **spec)
{
@@ -71,6 +87,7 @@
}
return PyMac_GetFSSpec(v, *spec);
}
+#endif /* !__LP64__ */
static int
myPyMac_GetOptFSRefPtr(PyObject *v, FSRef **ref)
@@ -92,6 +109,7 @@
return Py_BuildValue("u#", itself->unicode, itself->length);
}
+#ifndef __LP64__
static OSErr
_PyMac_GetFullPathname(FSSpec *fss, char *path, int len)
{
@@ -135,6 +153,7 @@
}
return 0;
}
+#endif /* !__LP64__ */
static PyObject *File_Error;
@@ -174,6 +193,10 @@
static void FSCatalogInfo_dealloc(FSCatalogInfoObject *self)
{
/* Cleanup of self->ob_itself goes here */
+ FSPermissionInfo* info = (FSPermissionInfo*)&(self->ob_itself.permissions);
+ if (info->fileSec != NULL) {
+ CFRelease(info->fileSec);
+ }
self->ob_type->tp_free((PyObject *)self);
}
@@ -282,12 +305,28 @@
static PyObject *FSCatalogInfo_get_permissions(FSCatalogInfoObject *self, void *closure)
{
- return Py_BuildValue("(llll)", self->ob_itself.permissions[0], self->ob_itself.permissions[1], self->ob_itself.permissions[2], self->ob_itself.permissions[3]);
+ FSPermissionInfo* info = (FSPermissionInfo*)&(self->ob_itself.permissions);
+ return Py_BuildValue("(llll)", info->userID, info->groupID, info->userAccess, info->mode);
}
static int FSCatalogInfo_set_permissions(FSCatalogInfoObject *self, PyObject *v, void *closure)
{
- return PyArg_Parse(v, "(llll)", &self->ob_itself.permissions[0], &self->ob_itself.permissions[1], &self->ob_itself.permissions[2], &self->ob_itself.permissions[3])-1;
+ long userID;
+ long groupID;
+ long userAccess;
+ long mode;
+ int r;
+
+ FSPermissionInfo* info = (FSPermissionInfo*)&(self->ob_itself.permissions);
+
+ r = PyArg_Parse(v, "(llll)", &userID, &groupID, &userAccess, &mode);
+ if (!r) {
+ return -1;
+ }
+ info->userID = userID;
+ info->groupID = groupID;
+ info->userAccess = userAccess;
+ info->mode = mode;
return 0;
}
@@ -501,6 +540,8 @@
/* ----------------------- Object type FInfo ------------------------ */
+#ifndef __LP64__
+
static PyTypeObject FInfo_Type;
#define FInfo_Check(x) ((x)->ob_type == &FInfo_Type || PyObject_TypeCheck((x), &FInfo_Type))
@@ -682,6 +723,7 @@
FInfo_tp_free, /* tp_free */
};
+#endif /* !__LP64__ */
/* --------------------- End object type FInfo ---------------------- */
@@ -729,6 +771,7 @@
self->ob_type->tp_free((PyObject *)self);
}
+#ifndef __LP64__
static PyObject *Alias_ResolveAlias(AliasObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
@@ -818,6 +861,7 @@
wasChanged);
return _res;
}
+#endif /* !__LP64__ */
static PyObject *Alias_FSResolveAliasWithMountFlags(AliasObject *_self, PyObject *_args)
{
@@ -891,6 +935,7 @@
}
static PyMethodDef Alias_methods[] = {
+#ifndef __LP64__
{"ResolveAlias", (PyCFunction)Alias_ResolveAlias, 1,
PyDoc_STR("(FSSpec fromFile) -> (FSSpec target, Boolean wasChanged)")},
{"GetAliasInfo", (PyCFunction)Alias_GetAliasInfo, 1,
@@ -899,6 +944,7 @@
PyDoc_STR("(FSSpec fromFile, unsigned long mountFlags) -> (FSSpec target, Boolean wasChanged)")},
{"FollowFinderAlias", (PyCFunction)Alias_FollowFinderAlias, 1,
PyDoc_STR("(FSSpec fromFile, Boolean logon) -> (FSSpec target, Boolean wasChanged)")},
+#endif /* !__LP64__ */
{"FSResolveAliasWithMountFlags", (PyCFunction)Alias_FSResolveAliasWithMountFlags, 1,
PyDoc_STR("(FSRef fromFile, unsigned long mountFlags) -> (FSRef target, Boolean wasChanged)")},
{"FSResolveAlias", (PyCFunction)Alias_FSResolveAlias, 1,
@@ -1033,6 +1079,7 @@
/* ----------------------- Object type FSSpec ----------------------- */
+#ifndef __LP64__
static PyTypeObject FSSpec_Type;
@@ -1488,6 +1535,7 @@
FSSpec_tp_free, /* tp_free */
};
+#endif /* !__LP64__ */
/* --------------------- End object type FSSpec --------------------- */
@@ -1568,7 +1616,9 @@
FSCatalogInfoBitmap whichInfo;
FSCatalogInfo catalogInfo;
FSRef newRef;
+#ifndef __LP64__
FSSpec newSpec;
+#endif
if (!PyArg_ParseTuple(_args, "u#lO&",
&nameLength__in__, &nameLength__in_len__,
&whichInfo,
@@ -1580,11 +1630,22 @@
whichInfo,
&catalogInfo,
&newRef,
- &newSpec);
+#ifndef __LP64__
+ &newSpec
+#else /* __LP64__ */
+ NULL
+#endif /* __LP64__*/
+ );
if (_err != noErr) return PyMac_Error(_err);
+
+#ifndef __LP64__
_res = Py_BuildValue("O&O&",
FSRef_New, &newRef,
FSSpec_New, &newSpec);
+#else /* __LP64__ */
+ _res = Py_BuildValue("O&O", FSRef_New, &newRef, Py_None);
+#endif /* __LP64__ */
+
return _res;
}
@@ -1598,7 +1659,9 @@
FSCatalogInfoBitmap whichInfo;
FSCatalogInfo catalogInfo;
FSRef newRef;
+#ifndef __LP64__
FSSpec newSpec;
+#endif /* !__LP64__ */
UInt32 newDirID;
if (!PyArg_ParseTuple(_args, "u#lO&",
&nameLength__in__, &nameLength__in_len__,
@@ -1611,13 +1674,25 @@
whichInfo,
&catalogInfo,
&newRef,
+#ifndef __LP64__
&newSpec,
+#else /* !__LP64__ */
+ NULL,
+#endif /* !__LP64__ */
&newDirID);
if (_err != noErr) return PyMac_Error(_err);
+
+#ifndef __LP64__
_res = Py_BuildValue("O&O&l",
FSRef_New, &newRef,
FSSpec_New, &newSpec,
newDirID);
+#else /* __LP64__ */
+ _res = Py_BuildValue("O&Ol",
+ FSRef_New, &newRef,
+ Py_None,
+ newDirID);
+#endif /* __LP64__ */
return _res;
}
@@ -1699,7 +1774,9 @@
FSCatalogInfoBitmap whichInfo;
FSCatalogInfo catalogInfo;
HFSUniStr255 outName;
+#ifndef __LP64__
FSSpec fsSpec;
+#endif /* !__LP64__ */
FSRef parentRef;
if (!PyArg_ParseTuple(_args, "l",
&whichInfo))
@@ -1708,14 +1785,27 @@
whichInfo,
&catalogInfo,
&outName,
+#ifndef __LP64__
&fsSpec,
+#else /* __LP64__ */
+ NULL,
+#endif /* __LP64__ */
&parentRef);
if (_err != noErr) return PyMac_Error(_err);
+
+#ifndef __LP64__
_res = Py_BuildValue("O&O&O&O&",
FSCatalogInfo_New, &catalogInfo,
PyMac_BuildHFSUniStr255, &outName,
FSSpec_New, &fsSpec,
FSRef_New, &parentRef);
+#else /* __LP64__ */
+ _res = Py_BuildValue("O&O&OO&",
+ FSCatalogInfo_New, &catalogInfo,
+ PyMac_BuildHFSUniStr255, &outName,
+ Py_None,
+ FSRef_New, &parentRef);
+#endif /* __LP64__ */
return _res;
}
@@ -1784,7 +1874,7 @@
UniCharCount forkNameLength__len__;
int forkNameLength__in_len__;
SInt8 permissions;
- SInt16 forkRefNum;
+ FSIORefNum forkRefNum;
if (!PyArg_ParseTuple(_args, "u#b",
&forkNameLength__in__, &forkNameLength__in_len__,
&permissions))
@@ -2034,7 +2124,7 @@
/* --------------------- End object type FSRef ---------------------- */
-
+#ifndef __LP64__
static PyObject *File_UnmountVol(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
@@ -2562,6 +2652,7 @@
FSSpec_New, &spec);
return _res;
}
+#endif /* !__LP64__ */
static PyObject *File_FSGetForkPosition(PyObject *_self, PyObject *_args)
{
@@ -2785,6 +2876,7 @@
return _res;
}
+#ifndef __LP64__
static PyObject *File_NewAlias(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
@@ -2933,6 +3025,7 @@
wasAliased);
return _res;
}
+#endif /* !__LP64__ */
static PyObject *File_FSNewAlias(PyObject *_self, PyObject *_args)
{
@@ -3050,6 +3143,7 @@
}
static PyMethodDef File_methods[] = {
+#ifndef __LP64__
{"UnmountVol", (PyCFunction)File_UnmountVol, 1,
PyDoc_STR("(Str63 volName, short vRefNum) -> None")},
{"FlushVol", (PyCFunction)File_FlushVol, 1,
@@ -3100,6 +3194,7 @@
PyDoc_STR("(short vRefNum, long dirID, Str255 oldName, long newDirID, Str255 newName) -> None")},
{"FSMakeFSSpec", (PyCFunction)File_FSMakeFSSpec, 1,
PyDoc_STR("(short vRefNum, long dirID, Str255 fileName) -> (FSSpec spec)")},
+#endif /* !__LP64__*/
{"FSGetForkPosition", (PyCFunction)File_FSGetForkPosition, 1,
PyDoc_STR("(SInt16 forkRefNum) -> (SInt64 position)")},
{"FSSetForkPosition", (PyCFunction)File_FSSetForkPosition, 1,
@@ -3124,6 +3219,7 @@
PyDoc_STR("(UInt8 * path, FNMessage message, OptionBits flags) -> None")},
{"FNNotifyAll", (PyCFunction)File_FNNotifyAll, 1,
PyDoc_STR("(FNMessage message, OptionBits flags) -> None")},
+#ifndef __LP64__
{"NewAlias", (PyCFunction)File_NewAlias, 1,
PyDoc_STR("(FSSpec fromFile, FSSpec target) -> (AliasHandle alias)")},
{"NewAliasMinimalFromFullPath", (PyCFunction)File_NewAliasMinimalFromFullPath, 1,
@@ -3136,6 +3232,7 @@
PyDoc_STR("(FSSpec fromFile, FSSpec target, AliasHandle alias) -> (Boolean wasChanged)")},
{"ResolveAliasFileWithMountFlagsNoUI", (PyCFunction)File_ResolveAliasFileWithMountFlagsNoUI, 1,
PyDoc_STR("(FSSpec theSpec, Boolean resolveAliasChains, unsigned long mountFlags) -> (FSSpec theSpec, Boolean targetIsFolder, Boolean wasAliased)")},
+#endif /* !__LP64__ */
{"FSNewAlias", (PyCFunction)File_FSNewAlias, 1,
PyDoc_STR("(FSRef fromFile, FSRef target) -> (AliasHandle inAlias)")},
{"FSResolveAliasFileWithMountFlags", (PyCFunction)File_FSResolveAliasFileWithMountFlags, 1,
@@ -3150,7 +3247,7 @@
};
-
+#ifndef __LP64__
int
PyMac_GetFSSpec(PyObject *v, FSSpec *spec)
{
@@ -3188,12 +3285,15 @@
}
return 0;
}
+#endif /* !__LP64__ */
int
PyMac_GetFSRef(PyObject *v, FSRef *fsr)
{
OSStatus err;
+#ifndef __LP64__
FSSpec fss;
+#endif /* !__LP64__ */
if (FSRef_Check(v)) {
*fsr = ((FSRefObject *)v)->ob_itself;
@@ -3205,12 +3305,14 @@
char *path = NULL;
if (!PyArg_Parse(v, "et", Py_FileSystemDefaultEncoding, &path))
return 0;
- if ( (err=FSPathMakeRef(path, fsr, NULL)) )
+ if ( (err=FSPathMakeRef((unsigned char*)path, fsr, NULL)) )
PyMac_Error(err);
PyMem_Free(path);
return !err;
}
/* XXXX Should try unicode here too */
+
+#ifndef __LP64__
/* Otherwise we try to go via an FSSpec */
if (FSSpec_Check(v)) {
fss = ((FSSpecObject *)v)->ob_itself;
@@ -3219,15 +3321,19 @@
PyMac_Error(err);
return 0;
}
+#endif /* !__LP64__ */
+
PyErr_SetString(PyExc_TypeError, "FSRef, FSSpec or pathname required");
return 0;
}
+#ifndef __LP64__
extern PyObject *
PyMac_BuildFSSpec(FSSpec *spec)
{
return FSSpec_New(spec);
}
+#endif /* !__LP64__ */
extern PyObject *
PyMac_BuildFSRef(FSRef *spec)
@@ -3242,10 +3348,12 @@
PyObject *d;
-
+#ifndef __LP64__
PyMac_INIT_TOOLBOX_OBJECT_NEW(FSSpec *, PyMac_BuildFSSpec);
- PyMac_INIT_TOOLBOX_OBJECT_NEW(FSRef *, PyMac_BuildFSRef);
PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSSpec, PyMac_GetFSSpec);
+#endif /* !__LP64__ */
+
+ PyMac_INIT_TOOLBOX_OBJECT_NEW(FSRef *, PyMac_BuildFSRef);
PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSRef, PyMac_GetFSRef);
@@ -3262,6 +3370,8 @@
/* Backward-compatible name */
Py_INCREF(&FSCatalogInfo_Type);
PyModule_AddObject(m, "FSCatalogInfoType", (PyObject *)&FSCatalogInfo_Type);
+
+#ifndef __LP64__
FInfo_Type.ob_type = &PyType_Type;
if (PyType_Ready(&FInfo_Type) < 0) return;
Py_INCREF(&FInfo_Type);
@@ -3269,6 +3379,7 @@
/* Backward-compatible name */
Py_INCREF(&FInfo_Type);
PyModule_AddObject(m, "FInfoType", (PyObject *)&FInfo_Type);
+#endif /* !__LP64__ */
Alias_Type.ob_type = &PyType_Type;
if (PyType_Ready(&Alias_Type) < 0) return;
Py_INCREF(&Alias_Type);
@@ -3276,6 +3387,8 @@
/* Backward-compatible name */
Py_INCREF(&Alias_Type);
PyModule_AddObject(m, "AliasType", (PyObject *)&Alias_Type);
+
+#ifndef __LP64__
FSSpec_Type.ob_type = &PyType_Type;
if (PyType_Ready(&FSSpec_Type) < 0) return;
Py_INCREF(&FSSpec_Type);
@@ -3283,6 +3396,7 @@
/* Backward-compatible name */
Py_INCREF(&FSSpec_Type);
PyModule_AddObject(m, "FSSpecType", (PyObject *)&FSSpec_Type);
+#endif /* !__LP64__ */
FSRef_Type.ob_type = &PyType_Type;
if (PyType_Ready(&FSRef_Type) < 0) return;
Py_INCREF(&FSRef_Type);
Modified: python/branches/tlee-ast-optimize/Mac/Modules/file/filesupport.py
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/file/filesupport.py (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/file/filesupport.py Thu Jun 5 17:42:10 2008
@@ -6,6 +6,13 @@
# XXXX TO DO:
# - Implement correct missing FSSpec handling for Alias methods
# - Implement FInfo
+#
+# WARNING WARNING WARNING
+# The file _Filemodule.c was modified manually, don't run this script
+# unless you really know what you're doing.
+
+import sys
+sys.exit(42)
import string
@@ -199,6 +206,7 @@
return Py_BuildValue("u#", itself->unicode, itself->length);
}
+#ifndef __LP64__
/*
** Get pathname for a given FSSpec
*/
@@ -244,10 +252,13 @@
}
return 0;
}
+#endif /* !__LP64__ */
"""
finalstuff = finalstuff + """
+
+#ifndef __LP64__
int
PyMac_GetFSSpec(PyObject *v, FSSpec *spec)
{
@@ -286,6 +297,8 @@
return 0;
}
+#endif /* !__LP64__ */
+
int
PyMac_GetFSRef(PyObject *v, FSRef *fsr)
{
@@ -309,6 +322,7 @@
}
/* XXXX Should try unicode here too */
/* Otherwise we try to go via an FSSpec */
+#ifndef __LP64__
if (FSSpec_Check(v)) {
fss = ((FSSpecObject *)v)->ob_itself;
if ((err=FSpMakeFSRef(&fss, fsr)) == 0)
@@ -317,14 +331,19 @@
return 0;
}
PyErr_SetString(PyExc_TypeError, "FSRef, FSSpec or pathname required");
+#else /* __LP64__ */
+ PyErr_SetString(PyExc_TypeError, "FSRef or pathname required");
+#endif /* __LP64__ */
return 0;
}
+#ifndef __LP64__
extern PyObject *
PyMac_BuildFSSpec(FSSpec *spec)
{
return FSSpec_New(spec);
}
+#endif /* __LP64__ */
extern PyObject *
PyMac_BuildFSRef(FSRef *spec)
@@ -334,9 +353,11 @@
"""
initstuff = initstuff + """
+#ifndef __LP64__
PyMac_INIT_TOOLBOX_OBJECT_NEW(FSSpec *, PyMac_BuildFSSpec);
-PyMac_INIT_TOOLBOX_OBJECT_NEW(FSRef *, PyMac_BuildFSRef);
PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSSpec, PyMac_GetFSSpec);
+#endif /* !__LP64__*/
+PyMac_INIT_TOOLBOX_OBJECT_NEW(FSRef *, PyMac_BuildFSRef);
PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSRef, PyMac_GetFSRef);
"""
Modified: python/branches/tlee-ast-optimize/Mac/Modules/fm/_Fmmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/fm/_Fmmodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/fm/_Fmmodule.c Thu Jun 5 17:42:10 2008
@@ -3,6 +3,7 @@
#include "Python.h"
+#ifndef __LP64__
#include "pymactoolbox.h"
@@ -335,23 +336,32 @@
{NULL, NULL, 0}
};
+#else /* __LP64__ */
+static PyMethodDef Fm_methods[] = {
+ {NULL, NULL, 0}
+};
+#endif /* __LP64__ */
void init_Fm(void)
{
PyObject *m;
+#ifndef __LP64__
PyObject *d;
+#endif /* __LP64__ */
m = Py_InitModule("_Fm", Fm_methods);
+#ifndef __LP64__
d = PyModule_GetDict(m);
Fm_Error = PyMac_GetOSErrException();
if (Fm_Error == NULL ||
PyDict_SetItemString(d, "Error", Fm_Error) != 0)
return;
+#endif /* __LP64__ */
}
/* ========================= End module _Fm ========================= */
Modified: python/branches/tlee-ast-optimize/Mac/Modules/folder/_Foldermodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/folder/_Foldermodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/folder/_Foldermodule.c Thu Jun 5 17:42:10 2008
@@ -27,8 +27,8 @@
short vRefNum;
OSType folderType;
Boolean createFolder;
- short foundVRefNum;
- long foundDirID;
+ FSVolumeRefNum foundVRefNum;
+ SInt32 foundDirID;
if (!PyArg_ParseTuple(_args, "hO&b",
&vRefNum,
PyMac_GetOSType, &folderType,
@@ -158,6 +158,7 @@
return _res;
}
+#ifndef __LP64__
static PyObject *Folder_GetFolderName(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
@@ -248,6 +249,7 @@
flags);
return _res;
}
+#endif /* !__LP64__ */
static PyObject *Folder_InvalidateFolderDescriptorCache(PyObject *_self, PyObject *_args)
{
@@ -300,6 +302,7 @@
PyDoc_STR("(UInt32 requestedTypeCount) -> (UInt32 totalTypeCount, FolderType theTypes)")},
{"RemoveFolderDescriptor", (PyCFunction)Folder_RemoveFolderDescriptor, 1,
PyDoc_STR("(FolderType foldType) -> None")},
+#ifndef __LP64__
{"GetFolderName", (PyCFunction)Folder_GetFolderName, 1,
PyDoc_STR("(short vRefNum, OSType foldType, Str255 name) -> (short foundVRefNum)")},
{"AddFolderRouting", (PyCFunction)Folder_AddFolderRouting, 1,
@@ -308,6 +311,7 @@
PyDoc_STR("(OSType fileType, FolderType routeFromFolder) -> None")},
{"FindFolderRouting", (PyCFunction)Folder_FindFolderRouting, 1,
PyDoc_STR("(OSType fileType, FolderType routeFromFolder) -> (FolderType routeToFolder, RoutingFlags flags)")},
+#endif /* !__LP64__ */
{"InvalidateFolderDescriptorCache", (PyCFunction)Folder_InvalidateFolderDescriptorCache, 1,
PyDoc_STR("(short vRefNum, long dirID) -> None")},
{"IdentifyFolder", (PyCFunction)Folder_IdentifyFolder, 1,
Modified: python/branches/tlee-ast-optimize/Mac/Modules/help/_Helpmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/help/_Helpmodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/help/_Helpmodule.c Thu Jun 5 17:42:10 2008
@@ -3,6 +3,7 @@
#include "Python.h"
+#ifndef __LP64__
#include "pymactoolbox.h"
@@ -144,7 +145,10 @@
return _res;
}
+#endif /* __LP64__ */
+
static PyMethodDef Help_methods[] = {
+#ifndef __LP64__
{"HMGetHelpMenu", (PyCFunction)Help_HMGetHelpMenu, 1,
PyDoc_STR("() -> (MenuRef outHelpMenu, MenuItemIndex outFirstCustomItemIndex)")},
{"HMAreHelpTagsDisplayed", (PyCFunction)Help_HMAreHelpTagsDisplayed, 1,
@@ -161,6 +165,7 @@
PyDoc_STR("(DialogPtr inDialog, SInt16 inHdlgRsrcID, SInt16 inItemStart) -> None")},
{"HMHideTag", (PyCFunction)Help_HMHideTag, 1,
PyDoc_STR("() -> None")},
+#endif /* __LP64__ */
{NULL, NULL, 0}
};
@@ -170,17 +175,21 @@
void init_Help(void)
{
PyObject *m;
+#ifndef __LP64__
PyObject *d;
+#endif /* __LP64__ */
m = Py_InitModule("_Help", Help_methods);
+#ifndef __LP64__
d = PyModule_GetDict(m);
Help_Error = PyMac_GetOSErrException();
if (Help_Error == NULL ||
PyDict_SetItemString(d, "Error", Help_Error) != 0)
return;
+#endif /* __LP64__ */
}
/* ======================== End module _Help ======================== */
Modified: python/branches/tlee-ast-optimize/Mac/Modules/ibcarbon/_IBCarbon.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/ibcarbon/_IBCarbon.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/ibcarbon/_IBCarbon.c Thu Jun 5 17:42:10 2008
@@ -4,6 +4,7 @@
#include "Python.h"
+#ifndef __LP64__
#include <Carbon/Carbon.h>
#include "pymactoolbox.h"
@@ -224,10 +225,13 @@
IBNibRefObj_New, outNibRef);
return _res;
}
+#endif /* __LP64__ */
static PyMethodDef IBCarbon_methods[] = {
+#ifndef __LP64__
{"CreateNibReference", (PyCFunction)IBCarbon_CreateNibReference, 1,
PyDoc_STR("(CFStringRef inNibName) -> (IBNibRef outNibRef)")},
+#endif /* __LP64__ */
{NULL, NULL, 0}
};
@@ -237,13 +241,16 @@
void init_IBCarbon(void)
{
PyObject *m;
+#ifndef __LP64__
PyObject *d;
+#endif /* __LP64__ */
m = Py_InitModule("_IBCarbon", IBCarbon_methods);
+#ifndef __LP64__
d = PyModule_GetDict(m);
IBCarbon_Error = PyMac_GetOSErrException();
if (IBCarbon_Error == NULL ||
@@ -256,6 +263,7 @@
/* Backward-compatible name */
Py_INCREF(&IBNibRef_Type);
PyModule_AddObject(m, "IBNibRefType", (PyObject *)&IBNibRef_Type);
+#endif /* __LP64__ */
}
/* ====================== End module _IBCarbon ====================== */
Modified: python/branches/tlee-ast-optimize/Mac/Modules/icn/_Icnmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/icn/_Icnmodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/icn/_Icnmodule.c Thu Jun 5 17:42:10 2008
@@ -4,6 +4,7 @@
#include "Python.h"
+#ifndef __LP64__
#include "pymactoolbox.h"
@@ -1447,8 +1448,10 @@
_res = Py_None;
return _res;
}
+#endif /* __LP64__ */
static PyMethodDef Icn_methods[] = {
+#ifndef __LP64__
{"GetCIcon", (PyCFunction)Icn_GetCIcon, 1,
PyDoc_STR("(SInt16 iconID) -> (CIconHandle _rv)")},
{"PlotCIcon", (PyCFunction)Icn_PlotCIcon, 1,
@@ -1573,6 +1576,7 @@
PyDoc_STR("(FSRef ref) -> (IconFamilyHandle iconFamily)")},
{"WriteIconFile", (PyCFunction)Icn_WriteIconFile, 1,
PyDoc_STR("(IconFamilyHandle iconFamily, FSSpec iconFile) -> None")},
+#endif /* __LP64__ */
{NULL, NULL, 0}
};
@@ -1582,17 +1586,21 @@
void init_Icn(void)
{
PyObject *m;
+#ifndef __LP64__
PyObject *d;
+#endif /* __LP64__ */
m = Py_InitModule("_Icn", Icn_methods);
+#ifndef __LP64__
d = PyModule_GetDict(m);
Icn_Error = PyMac_GetOSErrException();
if (Icn_Error == NULL ||
PyDict_SetItemString(d, "Error", Icn_Error) != 0)
return;
+#endif /* __LP64__ */
}
/* ======================== End module _Icn ========================= */
Modified: python/branches/tlee-ast-optimize/Mac/Modules/launch/_Launchmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/launch/_Launchmodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/launch/_Launchmodule.c Thu Jun 5 17:42:10 2008
@@ -50,6 +50,7 @@
PyObject *
LSItemInfoRecord_New(LSItemInfoRecord *it)
{
+#ifndef __LP64__
return Py_BuildValue("{s:is:O&s:O&s:O&s:O&s:i}",
"flags", it->flags,
"filetype", PyMac_BuildOSType, it->filetype,
@@ -57,6 +58,13 @@
"extension", OptCFStringRefObj_New, it->extension,
"iconFileName", OptCFStringRefObj_New, it->iconFileName,
"kindID", it->kindID);
+#else
+ return Py_BuildValue("{s:is:O&s:O&s:O&}",
+ "flags", it->flags,
+ "filetype", PyMac_BuildOSType, it->filetype,
+ "creator", PyMac_BuildOSType, it->creator,
+ "extension", OptCFStringRefObj_New, it->extension);
+#endif
}
static PyObject *Launch_Error;
Modified: python/branches/tlee-ast-optimize/Mac/Modules/list/_Listmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/list/_Listmodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/list/_Listmodule.c Thu Jun 5 17:42:10 2008
@@ -3,6 +3,7 @@
#include "Python.h"
+#ifndef __LP64__
#include "pymactoolbox.h"
@@ -1032,8 +1033,10 @@
return _res;
}
+#endif /* __LP64__ */
static PyMethodDef List_methods[] = {
+#ifndef __LP64__
{"CreateCustomList", (PyCFunction)List_CreateCustomList, 1,
PyDoc_STR("(Rect rView, Rect dataBounds, Point cellSize, ListDefSpec theSpec, WindowPtr theWindow, Boolean drawIt, Boolean hasGrow, Boolean scrollHoriz, Boolean scrollVert) -> (ListHandle outList)")},
{"LNew", (PyCFunction)List_LNew, 1,
@@ -1056,9 +1059,11 @@
PyDoc_STR("(ListHandle list, OptionBits selectionFlags) -> None")},
{"as_List", (PyCFunction)List_as_List, 1,
PyDoc_STR("(Resource)->List.\nReturns List object (which is not auto-freed!)")},
+#endif /* __LP64__ */
{NULL, NULL, 0}
};
+#ifndef __LP64__
static void myListDefFunction(SInt16 message,
@@ -1096,11 +1101,13 @@
Py_DECREF(rv);
}
}
+#endif /* __LP64__ */
void init_List(void)
{
PyObject *m;
+#ifndef __LP64__
PyObject *d;
@@ -1109,9 +1116,11 @@
PyMac_INIT_TOOLBOX_OBJECT_NEW(ListHandle, ListObj_New);
PyMac_INIT_TOOLBOX_OBJECT_CONVERT(ListHandle, ListObj_Convert);
+#endif /* __LP64__ */
m = Py_InitModule("_List", List_methods);
+#ifndef __LP64__
d = PyModule_GetDict(m);
List_Error = PyMac_GetOSErrException();
if (List_Error == NULL ||
@@ -1124,6 +1133,7 @@
/* Backward-compatible name */
Py_INCREF(&List_Type);
PyModule_AddObject(m, "ListType", (PyObject *)&List_Type);
+#endif /* __LP64__ */
}
/* ======================== End module _List ======================== */
Modified: python/branches/tlee-ast-optimize/Mac/Modules/menu/_Menumodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/menu/_Menumodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/menu/_Menumodule.c Thu Jun 5 17:42:10 2008
@@ -3,6 +3,7 @@
#include "Python.h"
+#ifndef __LP64__
#include "pymactoolbox.h"
@@ -3347,8 +3348,10 @@
_res = Py_None;
return _res;
}
+#endif /* __LP64__ */
static PyMethodDef Menu_methods[] = {
+#ifndef __LP64__
{"NewMenu", (PyCFunction)Menu_NewMenu, 1,
PyDoc_STR("(MenuID menuID, Str255 menuTitle) -> (MenuHandle _rv)")},
{"MacGetMenu", (PyCFunction)Menu_MacGetMenu, 1,
@@ -3433,6 +3436,7 @@
PyDoc_STR("(MenuHandle inMenu, MenuCommand inCommandID, OSType inPropertyCreator, OSType inPropertyTag) -> (ByteCount outSize)")},
{"RemoveMenuCommandProperty", (PyCFunction)Menu_RemoveMenuCommandProperty, 1,
PyDoc_STR("(MenuHandle inMenu, MenuCommand inCommandID, OSType inPropertyCreator, OSType inPropertyTag) -> None")},
+#endif /* __LP64__ */
{NULL, NULL, 0}
};
@@ -3442,15 +3446,18 @@
void init_Menu(void)
{
PyObject *m;
+#ifndef __LP64__
PyObject *d;
PyMac_INIT_TOOLBOX_OBJECT_NEW(MenuHandle, MenuObj_New);
PyMac_INIT_TOOLBOX_OBJECT_CONVERT(MenuHandle, MenuObj_Convert);
+#endif /* __LP64__ */
m = Py_InitModule("_Menu", Menu_methods);
+#ifndef __LP64__
d = PyModule_GetDict(m);
Menu_Error = PyMac_GetOSErrException();
if (Menu_Error == NULL ||
@@ -3463,6 +3470,7 @@
/* Backward-compatible name */
Py_INCREF(&Menu_Type);
PyModule_AddObject(m, "MenuType", (PyObject *)&Menu_Type);
+#endif /* __LP64__ */
}
/* ======================== End module _Menu ======================== */
Modified: python/branches/tlee-ast-optimize/Mac/Modules/mlte/_Mltemodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/mlte/_Mltemodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/mlte/_Mltemodule.c Thu Jun 5 17:42:10 2008
@@ -3,6 +3,7 @@
#include "Python.h"
+#ifndef __LP64__
#include "pymactoolbox.h"
@@ -1622,7 +1623,10 @@
}
+#endif /* __LP64__ */
+
static PyMethodDef Mlte_methods[] = {
+#ifndef __LP64__
{"TXNNewObject", (PyCFunction)Mlte_TXNNewObject, 1,
PyDoc_STR("(FSSpec * iFileSpec, WindowPtr iWindow, Rect iFrame, TXNFrameOptions iFrameOptions, TXNFrameType iFrameType, TXNFileType iFileType, TXNPermanentTextEncodingType iPermanentEncoding) -> (TXNObject oTXNObject, TXNFrameID oTXNFrameID)")},
{"TXNTerminateTextension", (PyCFunction)Mlte_TXNTerminateTextension, 1,
@@ -1639,6 +1643,7 @@
PyDoc_STR("() -> (TXNVersionValue _rv, TXNFeatureBits oFeatureFlags)")},
{"TXNInitTextension", (PyCFunction)Mlte_TXNInitTextension, 1,
PyDoc_STR("(TXNInitOptions) -> None")},
+#endif /* __LP64__ */
{NULL, NULL, 0}
};
@@ -1648,14 +1653,17 @@
void init_Mlte(void)
{
PyObject *m;
+#ifndef __LP64__
PyObject *d;
// PyMac_INIT_TOOLBOX_OBJECT_NEW(xxxx);
+#endif /* __LP64__ */
m = Py_InitModule("_Mlte", Mlte_methods);
+#ifndef __LP64__
d = PyModule_GetDict(m);
Mlte_Error = PyMac_GetOSErrException();
if (Mlte_Error == NULL ||
@@ -1675,6 +1683,7 @@
/* Backward-compatible name */
Py_INCREF(&TXNFontMenuObject_Type);
PyModule_AddObject(m, "TXNFontMenuObjectType", (PyObject *)&TXNFontMenuObject_Type);
+#endif /* __LP64__ */
}
/* ======================== End module _Mlte ======================== */
Modified: python/branches/tlee-ast-optimize/Mac/Modules/qd/_Qdmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/qd/_Qdmodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/qd/_Qdmodule.c Thu Jun 5 17:42:10 2008
@@ -4,6 +4,7 @@
#include "Python.h"
+#ifndef __LP64__
#include "pymactoolbox.h"
@@ -6544,8 +6545,10 @@
return _res;
}
+#endif /* __LP64__ */
static PyMethodDef Qd_methods[] = {
+#ifndef __LP64__
{"GetPort", (PyCFunction)Qd_GetPort, 1,
PyDoc_STR("() -> (GrafPtr port)")},
{"GrafDevice", (PyCFunction)Qd_GrafDevice, 1,
@@ -7080,10 +7083,12 @@
PyDoc_STR("Take (string, int, Rect) argument and create BitMap")},
{"RawBitMap", (PyCFunction)Qd_RawBitMap, 1,
PyDoc_STR("Take string BitMap and turn into BitMap object")},
+#endif /* __LP64__ */
{NULL, NULL, 0}
};
+#ifndef __LP64__
/* Like BMObj_New, but the original bitmap data structure is copied (and
** released when the object is released)
@@ -7101,11 +7106,13 @@
return (PyObject *)it;
}
+#endif /* __LP64__ */
void init_Qd(void)
{
PyObject *m;
+#ifndef __LP64__
PyObject *d;
@@ -7117,8 +7124,10 @@
PyMac_INIT_TOOLBOX_OBJECT_NEW(RGBColorPtr, QdRGB_New);
PyMac_INIT_TOOLBOX_OBJECT_CONVERT(RGBColor, QdRGB_Convert);
+#endif /* __LP64__ */
m = Py_InitModule("_Qd", Qd_methods);
+#ifndef __LP64__
d = PyModule_GetDict(m);
Qd_Error = PyMac_GetOSErrException();
if (Qd_Error == NULL ||
@@ -7138,6 +7147,7 @@
/* Backward-compatible name */
Py_INCREF(&BitMap_Type);
PyModule_AddObject(m, "BitMapType", (PyObject *)&BitMap_Type);
+#endif /* __LP64__ */
}
/* ========================= End module _Qd ========================= */
Modified: python/branches/tlee-ast-optimize/Mac/Modules/qdoffs/_Qdoffsmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/qdoffs/_Qdoffsmodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/qdoffs/_Qdoffsmodule.c Thu Jun 5 17:42:10 2008
@@ -4,6 +4,7 @@
#include "Python.h"
+#ifndef __LP64__
#include "pymactoolbox.h"
@@ -630,8 +631,10 @@
return _res;
}
+#endif /* __LP64__ */
static PyMethodDef Qdoffs_methods[] = {
+#ifndef __LP64__
{"NewGWorld", (PyCFunction)Qdoffs_NewGWorld, 1,
PyDoc_STR("(short PixelDepth, Rect boundsRect, CTabHandle cTable, GDHandle aGDevice, GWorldFlags flags) -> (GWorldPtr offscreenGWorld)")},
{"LockPixels", (PyCFunction)Qdoffs_LockPixels, 1,
@@ -678,6 +681,7 @@
PyDoc_STR("(pixmap, int start, int size) -> string. Return bytes from the pixmap")},
{"PutPixMapBytes", (PyCFunction)Qdoffs_PutPixMapBytes, 1,
PyDoc_STR("(pixmap, int start, string data). Store bytes into the pixmap")},
+#endif /* __LP64__ */
{NULL, NULL, 0}
};
@@ -687,6 +691,7 @@
void init_Qdoffs(void)
{
PyObject *m;
+#ifndef __LP64__
PyObject *d;
@@ -694,8 +699,10 @@
PyMac_INIT_TOOLBOX_OBJECT_NEW(GWorldPtr, GWorldObj_New);
PyMac_INIT_TOOLBOX_OBJECT_CONVERT(GWorldPtr, GWorldObj_Convert);
+#endif /* __LP64__ */
m = Py_InitModule("_Qdoffs", Qdoffs_methods);
+#ifndef __LP64__
d = PyModule_GetDict(m);
Qdoffs_Error = PyMac_GetOSErrException();
if (Qdoffs_Error == NULL ||
@@ -708,6 +715,7 @@
/* Backward-compatible name */
Py_INCREF(&GWorld_Type);
PyModule_AddObject(m, "GWorldType", (PyObject *)&GWorld_Type);
+#endif /* __LP64__ */
}
/* ======================= End module _Qdoffs ======================= */
Modified: python/branches/tlee-ast-optimize/Mac/Modules/qt/_Qtmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/qt/_Qtmodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/qt/_Qtmodule.c Thu Jun 5 17:42:10 2008
@@ -4,6 +4,7 @@
#include "Python.h"
+#ifndef __LP64__
#include "pymactoolbox.h"
@@ -26294,8 +26295,10 @@
_res = Py_None;
return _res;
}
+#endif /* __LP64__ */
static PyMethodDef Qt_methods[] = {
+#ifndef __LP64__
{"EnterMovies", (PyCFunction)Qt_EnterMovies, 1,
PyDoc_STR("() -> None")},
{"ExitMovies", (PyCFunction)Qt_ExitMovies, 1,
@@ -27988,6 +27991,7 @@
PyDoc_STR("(WindowPtr wp, Point startPt, Rect boundsRect) -> None")},
{"MoviesTask", (PyCFunction)Qt_MoviesTask, 1,
PyDoc_STR("(long maxMilliSecToUse) -> None")},
+#endif /* __LP64__ */
{NULL, NULL, 0}
};
@@ -27997,6 +28001,7 @@
void init_Qt(void)
{
PyObject *m;
+#ifndef __LP64__
PyObject *d;
@@ -28013,9 +28018,11 @@
PyMac_INIT_TOOLBOX_OBJECT_CONVERT(UserData, UserDataObj_Convert);
PyMac_INIT_TOOLBOX_OBJECT_NEW(Media, MediaObj_New);
PyMac_INIT_TOOLBOX_OBJECT_CONVERT(Media, MediaObj_Convert);
+#endif /* __LP64__ */
m = Py_InitModule("_Qt", Qt_methods);
+#ifndef __LP64__
d = PyModule_GetDict(m);
Qt_Error = PyMac_GetOSErrException();
if (Qt_Error == NULL ||
@@ -28077,6 +28084,7 @@
/* Backward-compatible name */
Py_INCREF(&SGOutput_Type);
PyModule_AddObject(m, "SGOutputType", (PyObject *)&SGOutput_Type);
+#endif /* __LP64__ */
}
/* ========================= End module _Qt ========================= */
Modified: python/branches/tlee-ast-optimize/Mac/Modules/res/_Resmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/res/_Resmodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/res/_Resmodule.c Thu Jun 5 17:42:10 2008
@@ -4,7 +4,6 @@
#include "Python.h"
-
#include "pymactoolbox.h"
/* Macro to test whether a weak-loaded CFM function exists */
@@ -414,6 +413,7 @@
return _res;
}
+#ifndef __LP64__
static PyObject *ResObj_as_Control(ResourceObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
@@ -431,6 +431,7 @@
return _res;
}
+#endif /* !__LP64__ */
static PyObject *ResObj_LoadResource(ResourceObject *_self, PyObject *_args)
{
@@ -501,10 +502,12 @@
PyDoc_STR("(long newSize) -> None")},
{"GetNextFOND", (PyCFunction)ResObj_GetNextFOND, 1,
PyDoc_STR("() -> (Handle _rv)")},
+#ifndef __LP64__
{"as_Control", (PyCFunction)ResObj_as_Control, 1,
PyDoc_STR("Return this resource/handle as a Control")},
{"as_Menu", (PyCFunction)ResObj_as_Menu, 1,
PyDoc_STR("Return this resource/handle as a Menu")},
+#endif /* !__LP64__ */
{"LoadResource", (PyCFunction)ResObj_LoadResource, 1,
PyDoc_STR("() -> None")},
{"AutoDispose", (PyCFunction)ResObj_AutoDispose, 1,
@@ -1152,6 +1155,7 @@
return _res;
}
+#ifndef __LP64__
static PyObject *Res_OpenRFPerm(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
@@ -1287,6 +1291,7 @@
_res = Py_None;
return _res;
}
+#endif /* !__LP64__ */
static PyObject *Res_InsertResourceFile(PyObject *_self, PyObject *_args)
{
@@ -1327,6 +1332,7 @@
return _res;
}
+#ifndef __LP64__
static PyObject *Res_FSpResourceFileAlreadyOpen(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
@@ -1394,6 +1400,7 @@
return _res;
}
+
static PyObject *Res_GetNextResourceFile(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
@@ -1413,6 +1420,7 @@
nextRefNum);
return _res;
}
+#endif /* !__LP64__ */
static PyObject *Res_FSOpenResFile(PyObject *_self, PyObject *_args)
{
@@ -1438,6 +1446,8 @@
return _res;
}
+
+#ifndef __LP64__
static PyObject *Res_FSCreateResFile(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
@@ -1534,6 +1544,7 @@
PyMac_BuildFSSpec, &newSpec);
return _res;
}
+#endif /* __LP64__ */
static PyObject *Res_FSOpenResourceFile(PyObject *_self, PyObject *_args)
{
@@ -1544,7 +1555,7 @@
UniCharCount forkNameLength__len__;
int forkNameLength__in_len__;
SignedByte permissions;
- SInt16 refNum;
+ ResFileRefNum refNum;
#ifndef FSOpenResourceFile
PyMac_PRECHECK(FSOpenResourceFile);
#endif
@@ -1637,6 +1648,7 @@
PyDoc_STR("(short refNum) -> (short _rv)")},
{"SetResFileAttrs", (PyCFunction)Res_SetResFileAttrs, 1,
PyDoc_STR("(short refNum, short attrs) -> None")},
+#ifndef __LP64__
{"OpenRFPerm", (PyCFunction)Res_OpenRFPerm, 1,
PyDoc_STR("(Str255 fileName, short vRefNum, SignedByte permission) -> (short _rv)")},
{"HOpenResFile", (PyCFunction)Res_HOpenResFile, 1,
@@ -1647,10 +1659,12 @@
PyDoc_STR("(FSSpec spec, SignedByte permission) -> (short _rv)")},
{"FSpCreateResFile", (PyCFunction)Res_FSpCreateResFile, 1,
PyDoc_STR("(FSSpec spec, OSType creator, OSType fileType, ScriptCode scriptTag) -> None")},
+#endif /* !__LP64__ */
{"InsertResourceFile", (PyCFunction)Res_InsertResourceFile, 1,
PyDoc_STR("(SInt16 refNum, RsrcChainLocation where) -> None")},
{"DetachResourceFile", (PyCFunction)Res_DetachResourceFile, 1,
PyDoc_STR("(SInt16 refNum) -> None")},
+#ifndef __LP64__
{"FSpResourceFileAlreadyOpen", (PyCFunction)Res_FSpResourceFileAlreadyOpen, 1,
PyDoc_STR("(FSSpec resourceFile) -> (Boolean _rv, Boolean inChain, SInt16 refNum)")},
{"FSpOpenOrphanResFile", (PyCFunction)Res_FSpOpenOrphanResFile, 1,
@@ -1659,14 +1673,17 @@
PyDoc_STR("() -> (SInt16 refNum)")},
{"GetNextResourceFile", (PyCFunction)Res_GetNextResourceFile, 1,
PyDoc_STR("(SInt16 curRefNum) -> (SInt16 nextRefNum)")},
+#endif /* __LP64__ */
{"FSOpenResFile", (PyCFunction)Res_FSOpenResFile, 1,
PyDoc_STR("(FSRef ref, SignedByte permission) -> (short _rv)")},
+#ifndef __LP64__
{"FSCreateResFile", (PyCFunction)Res_FSCreateResFile, 1,
PyDoc_STR("(FSRef parentRef, Buffer nameLength) -> (FSRef newRef, FSSpec newSpec)")},
{"FSResourceFileAlreadyOpen", (PyCFunction)Res_FSResourceFileAlreadyOpen, 1,
PyDoc_STR("(FSRef resourceFileRef) -> (Boolean _rv, Boolean inChain, SInt16 refNum)")},
{"FSCreateResourceFile", (PyCFunction)Res_FSCreateResourceFile, 1,
PyDoc_STR("(FSRef parentRef, Buffer nameLength, Buffer forkNameLength) -> (FSRef newRef, FSSpec newSpec)")},
+#endif /* __LP64__ */
{"FSOpenResourceFile", (PyCFunction)Res_FSOpenResourceFile, 1,
PyDoc_STR("(FSRef ref, Buffer forkNameLength, SignedByte permissions) -> (SInt16 refNum)")},
{"Handle", (PyCFunction)Res_Handle, 1,
@@ -1676,7 +1693,6 @@
-
/* Alternative version of ResObj_New, which returns None for null argument */
PyObject *OptResObj_New(Handle itself)
{
Modified: python/branches/tlee-ast-optimize/Mac/Modules/scrap/_Scrapmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/scrap/_Scrapmodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/scrap/_Scrapmodule.c Thu Jun 5 17:42:10 2008
@@ -4,6 +4,7 @@
#include "Python.h"
+#ifndef __LP64__
#include "pymactoolbox.h"
@@ -315,8 +316,10 @@
_res = Py_None;
return _res;
}
+#endif /* __LP64__ */
static PyMethodDef Scrap_methods[] = {
+#ifndef __LP64__
{"LoadScrap", (PyCFunction)Scrap_LoadScrap, 1,
PyDoc_STR("() -> None")},
{"UnloadScrap", (PyCFunction)Scrap_UnloadScrap, 1,
@@ -327,6 +330,7 @@
PyDoc_STR("() -> None")},
{"CallInScrapPromises", (PyCFunction)Scrap_CallInScrapPromises, 1,
PyDoc_STR("() -> None")},
+#endif /* __LP64__ */
{NULL, NULL, 0}
};
@@ -336,12 +340,15 @@
void init_Scrap(void)
{
PyObject *m;
+#ifndef __LP64__
PyObject *d;
+#endif /* __LP64__ */
m = Py_InitModule("_Scrap", Scrap_methods);
+#ifndef __LP64__
d = PyModule_GetDict(m);
Scrap_Error = PyMac_GetOSErrException();
if (Scrap_Error == NULL ||
@@ -351,6 +358,7 @@
Py_INCREF(&Scrap_Type);
if (PyDict_SetItemString(d, "ScrapType", (PyObject *)&Scrap_Type) != 0)
Py_FatalError("can't initialize ScrapType");
+#endif /* __LP64__ */
}
/* ======================= End module _Scrap ======================== */
Modified: python/branches/tlee-ast-optimize/Mac/Modules/snd/_Sndmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/snd/_Sndmodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/snd/_Sndmodule.c Thu Jun 5 17:42:10 2008
@@ -3,6 +3,7 @@
#include "Python.h"
+#ifndef __LP64__
#include "pymactoolbox.h"
@@ -981,8 +982,10 @@
byteCount);
return _res;
}
+#endif /* __LP64__ */
static PyMethodDef Snd_methods[] = {
+#ifndef __LP64__
{"SPB", (PyCFunction)Snd_SPB, 1,
PyDoc_STR(NULL)},
{"SysBeep", (PyCFunction)Snd_SysBeep, 1,
@@ -1047,10 +1050,12 @@
PyDoc_STR("(long inRefNum) -> (long milliseconds)")},
{"SPBBytesToMilliseconds", (PyCFunction)Snd_SPBBytesToMilliseconds, 1,
PyDoc_STR("(long inRefNum) -> (long byteCount)")},
+#endif /* __LP64__ */
{NULL, NULL, 0}
};
+#ifndef __LP64__
/* Routine passed to Py_AddPendingCall -- call the Python callback */
static int
@@ -1113,19 +1118,23 @@
SetA5(A5);
}
}
+#endif /* __LP64__ */
void init_Snd(void)
{
PyObject *m;
+#ifndef __LP64__
PyObject *d;
+#endif /* __LP64__ */
m = Py_InitModule("_Snd", Snd_methods);
+#ifndef __LP64__
d = PyModule_GetDict(m);
Snd_Error = PyMac_GetOSErrException();
if (Snd_Error == NULL ||
@@ -1145,6 +1154,7 @@
/* Backward-compatible name */
Py_INCREF(&SPB_Type);
PyModule_AddObject(m, "SPBType", (PyObject *)&SPB_Type);
+#endif /* __LP64__ */
}
/* ======================== End module _Snd ========================= */
Modified: python/branches/tlee-ast-optimize/Mac/Modules/te/_TEmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/te/_TEmodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/te/_TEmodule.c Thu Jun 5 17:42:10 2008
@@ -3,6 +3,7 @@
#include "Python.h"
+#ifndef __LP64__
#include "pymactoolbox.h"
@@ -1267,8 +1268,10 @@
TEObj_New, _rv);
return _res;
}
+#endif /* __LP64__ */
static PyMethodDef TE_methods[] = {
+#ifndef __LP64__
{"TEScrapHandle", (PyCFunction)TE_TEScrapHandle, 1,
PyDoc_STR("() -> (Handle _rv)")},
{"TEGetScrapLength", (PyCFunction)TE_TEGetScrapLength, 1,
@@ -1295,6 +1298,7 @@
PyDoc_STR("(UInt8 value) -> None")},
{"as_TE", (PyCFunction)TE_as_TE, 1,
PyDoc_STR("(Handle h) -> (TEHandle _rv)")},
+#endif /* __LP64__ */
{NULL, NULL, 0}
};
@@ -1304,6 +1308,7 @@
void init_TE(void)
{
PyObject *m;
+#ifndef __LP64__
PyObject *d;
@@ -1311,8 +1316,10 @@
PyMac_INIT_TOOLBOX_OBJECT_NEW(TEHandle, TEObj_New);
PyMac_INIT_TOOLBOX_OBJECT_CONVERT(TEHandle, TEObj_Convert);
+#endif /* __LP64__ */
m = Py_InitModule("_TE", TE_methods);
+#ifndef __LP64__
d = PyModule_GetDict(m);
TE_Error = PyMac_GetOSErrException();
if (TE_Error == NULL ||
@@ -1325,6 +1332,7 @@
/* Backward-compatible name */
Py_INCREF(&TE_Type);
PyModule_AddObject(m, "TEType", (PyObject *)&TE_Type);
+#endif /* __LP64__ */
}
/* ========================= End module _TE ========================= */
Modified: python/branches/tlee-ast-optimize/Mac/Modules/win/_Winmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Mac/Modules/win/_Winmodule.c (original)
+++ python/branches/tlee-ast-optimize/Mac/Modules/win/_Winmodule.c Thu Jun 5 17:42:10 2008
@@ -3,7 +3,7 @@
#include "Python.h"
-
+#ifndef __LP64__
#include "pymactoolbox.h"
@@ -3147,8 +3147,10 @@
WinObj_WhichWindow, theWindow);
return _res;
}
+#endif /* __LP64__ */
static PyMethodDef Win_methods[] = {
+#ifndef __LP64__
{"GetNewCWindow", (PyCFunction)Win_GetNewCWindow, 1,
PyDoc_STR("(short windowID, WindowPtr behind) -> (WindowPtr _rv)")},
{"NewWindow", (PyCFunction)Win_NewWindow, 1,
@@ -3200,10 +3202,12 @@
{"FindWindow", (PyCFunction)Win_FindWindow, 1,
PyDoc_STR("(Point thePoint) -> (short _rv, WindowPtr theWindow)")},
{NULL, NULL, 0}
+#endif /* __LP64__ */
};
+#ifndef __LP64__
/* Return the object corresponding to the window, or NULL */
PyObject *
@@ -3226,20 +3230,22 @@
return it;
}
+#endif /* __LP64__ */
void init_Win(void)
{
PyObject *m;
+#ifndef __LP64__
PyObject *d;
+ PyMac_INIT_TOOLBOX_OBJECT_NEW(WindowPtr, WinObj_New);
+ PyMac_INIT_TOOLBOX_OBJECT_NEW(WindowPtr, WinObj_WhichWindow);
+ PyMac_INIT_TOOLBOX_OBJECT_CONVERT(WindowPtr, WinObj_Convert);
-
- PyMac_INIT_TOOLBOX_OBJECT_NEW(WindowPtr, WinObj_New);
- PyMac_INIT_TOOLBOX_OBJECT_NEW(WindowPtr, WinObj_WhichWindow);
- PyMac_INIT_TOOLBOX_OBJECT_CONVERT(WindowPtr, WinObj_Convert);
-
+#endif /* __LP64__ */
m = Py_InitModule("_Win", Win_methods);
+#ifndef __LP64__
d = PyModule_GetDict(m);
Win_Error = PyMac_GetOSErrException();
if (Win_Error == NULL ||
@@ -3252,6 +3258,7 @@
/* Backward-compatible name */
Py_INCREF(&Window_Type);
PyModule_AddObject(m, "WindowType", (PyObject *)&Window_Type);
+#endif /* __LP64__ */
}
/* ======================== End module _Win ========================= */
Modified: python/branches/tlee-ast-optimize/Makefile.pre.in
==============================================================================
--- python/branches/tlee-ast-optimize/Makefile.pre.in (original)
+++ python/branches/tlee-ast-optimize/Makefile.pre.in Thu Jun 5 17:42:10 2008
@@ -431,7 +431,7 @@
$(RESSRCDIR)/Info.plist
$(INSTALL) -d -m $(DIRMODE) $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)
if test "${UNIVERSALSDK}"; then \
- $(CC) -o $(LDLIBRARY) -arch i386 -arch ppc -dynamiclib \
+ $(CC) -o $(LDLIBRARY) @UNIVERSAL_ARCH_FLAGS@ -dynamiclib \
-isysroot "${UNIVERSALSDK}" \
-all_load $(LIBRARY) -Wl,-single_module \
-install_name $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK) \
@@ -1052,13 +1052,22 @@
frameworkinstallapps:
cd Mac && $(MAKE) installapps DESTDIR="$(DESTDIR)"
+frameworkinstallapps4way:
+ cd Mac && $(MAKE) installapps4way DESTDIR="$(DESTDIR)"
+
# This install the unix python and pythonw tools in /usr/local/bin
frameworkinstallunixtools:
cd Mac && $(MAKE) installunixtools DESTDIR="$(DESTDIR)"
+frameworkinstallunixtools4way:
+ cd Mac && $(MAKE) installunixtools4way DESTDIR="$(DESTDIR)"
+
frameworkaltinstallunixtools:
cd Mac && $(MAKE) altinstallunixtools DESTDIR="$(DESTDIR)"
+frameworkaltinstallunixtools4way:
+ cd Mac && $(MAKE) altinstallunixtools4way DESTDIR="$(DESTDIR)"
+
# This installs the Demos and Tools into the applications directory.
# It is not part of a normal frameworkinstall
frameworkinstallextras:
@@ -1185,7 +1194,7 @@
# Perform some verification checks on any modified files.
check:
- ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/patchcheck.py
+ $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/patchcheck.py
# Dependencies
Modified: python/branches/tlee-ast-optimize/Misc/ACKS
==============================================================================
--- python/branches/tlee-ast-optimize/Misc/ACKS (original)
+++ python/branches/tlee-ast-optimize/Misc/ACKS Thu Jun 5 17:42:10 2008
@@ -412,6 +412,7 @@
Bjorn Lindqvist
Per Lindqvist
Eric Lindvall
+Gregor Lingl
Nick Lockwood
Stephanie Lockwood
Anne Lord
Modified: python/branches/tlee-ast-optimize/Misc/NEWS
==============================================================================
--- python/branches/tlee-ast-optimize/Misc/NEWS (original)
+++ python/branches/tlee-ast-optimize/Misc/NEWS Thu Jun 5 17:42:10 2008
@@ -259,6 +259,14 @@
- The Mac Modules (including Carbon) have been deprecated for removal
in Python 3.0.
+- Library: on MacOS X you can now set ``ARCHFLAGS`` in the shell
+ environment to control the '-arch' flags that are used to build
+ an extension. This was added for compatibility with Apple's build
+ of Python.
+
+- The bundled OSX-specific copy of libbffi is now in sync with the version
+ shipped with PyObjC 2.0 and includes support for x86_64 and ppc64 platforms.
+
Build
-----
@@ -266,6 +274,23 @@
- ``Lib/lib-old`` is now added to sys.path.
+- On MacOS X it is now possible to install the framework in 64-bit
+ mode or even as a 4-way universal binary (that is, PPC, i386,
+ PPC64 and x86_64 support in one binary)
+
+ This is controlled by the configure argument ``--with-universal-archs``:
+
+ - ``--with-universal-archs=all``: install 4-way universal
+
+ - ``--with-universal-archs=32-bit``: install 2-way universal, 32-bit (the default)
+
+ - ``--with-universal-archs=64-bit``: install 2-way universal, 64-bit
+
+ This option should be used in combination with ``--enable-universalsdk=``.
+
+ NOTE: 64-bit and 4-way builds are only suppported on Mac OS X 10.5 (or later).
+
+
C API
-----
Modified: python/branches/tlee-ast-optimize/Modules/_ctypes/cfield.c
==============================================================================
--- python/branches/tlee-ast-optimize/Modules/_ctypes/cfield.c (original)
+++ python/branches/tlee-ast-optimize/Modules/_ctypes/cfield.c Thu Jun 5 17:42:10 2008
@@ -1758,6 +1758,7 @@
#ifdef ffi_type_longdouble
#undef ffi_type_longdouble
#endif
+ /* This is already defined on OSX */
ffi_type ffi_type_longdouble = { sizeof(long double), LONGDOUBLE_ALIGN,
FFI_TYPE_LONGDOUBLE };
Modified: python/branches/tlee-ast-optimize/Modules/_ctypes/libffi_osx/x86/x86-darwin.S
==============================================================================
--- python/branches/tlee-ast-optimize/Modules/_ctypes/libffi_osx/x86/x86-darwin.S (original)
+++ python/branches/tlee-ast-optimize/Modules/_ctypes/libffi_osx/x86/x86-darwin.S Thu Jun 5 17:42:10 2008
@@ -179,7 +179,6 @@
movl %ebp,%esp
popl %ebp
ret
-.LFE1:
.ffi_call_SYSV_end:
#if 0
.size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
@@ -220,7 +219,7 @@
#else
.long .LFB1 /* FDE initial location */
#endif
- .long .LFE1-.LFB1 /* FDE address range */
+ .long .ffi_call_SYSV_end-.LFB1 /* FDE address range */
#ifdef __PIC__
.byte 0x0 /* .uleb128 0x0; Augmentation size */
#endif
Modified: python/branches/tlee-ast-optimize/Objects/complexobject.c
==============================================================================
--- python/branches/tlee-ast-optimize/Objects/complexobject.c (original)
+++ python/branches/tlee-ast-optimize/Objects/complexobject.c Thu Jun 5 17:42:10 2008
@@ -822,7 +822,8 @@
static PyObject *
complex_getnewargs(PyComplexObject *v)
{
- return Py_BuildValue("(D)", &v->cval);
+ Py_complex c = v->cval;
+ return Py_BuildValue("(dd)", c.real, c.imag);
}
#if 0
Modified: python/branches/tlee-ast-optimize/Python/bltinmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Python/bltinmodule.c (original)
+++ python/branches/tlee-ast-optimize/Python/bltinmodule.c Thu Jun 5 17:42:10 2008
@@ -565,8 +565,6 @@
!(supplied_flags & PyCF_NO_OPTIMIZE), &cf);
}
return result;
-
- /* XXX: this is awful */
}
#ifdef Py_USING_UNICODE
Modified: python/branches/tlee-ast-optimize/Python/mactoolboxglue.c
==============================================================================
--- python/branches/tlee-ast-optimize/Python/mactoolboxglue.c (original)
+++ python/branches/tlee-ast-optimize/Python/mactoolboxglue.c Thu Jun 5 17:42:10 2008
@@ -106,6 +106,7 @@
}
+#ifndef __LP64__
OSErr
PyMac_GetFullPathname(FSSpec *fss, char *path, int len)
{
@@ -153,6 +154,7 @@
Py_XDECREF(fs);
return err;
}
+#endif /* !__LP64__ */
/* Convert a 4-char string object argument to an OSType value */
int
@@ -417,6 +419,7 @@
GLUE_NEW(GWorldPtr, GWorldObj_New, "Carbon.Qdoffs")
GLUE_CONVERT(GWorldPtr, GWorldObj_Convert, "Carbon.Qdoffs")
+#ifndef __LP64__
GLUE_NEW(Track, TrackObj_New, "Carbon.Qt")
GLUE_CONVERT(Track, TrackObj_Convert, "Carbon.Qt")
GLUE_NEW(Movie, MovieObj_New, "Carbon.Qt")
@@ -429,6 +432,7 @@
GLUE_CONVERT(UserData, UserDataObj_Convert, "Carbon.Qt")
GLUE_NEW(Media, MediaObj_New, "Carbon.Qt")
GLUE_CONVERT(Media, MediaObj_Convert, "Carbon.Qt")
+#endif /* !__LP64__ */
GLUE_NEW(Handle, ResObj_New, "Carbon.Res")
GLUE_CONVERT(Handle, ResObj_Convert, "Carbon.Res")
Modified: python/branches/tlee-ast-optimize/configure
==============================================================================
--- python/branches/tlee-ast-optimize/configure (original)
+++ python/branches/tlee-ast-optimize/configure Thu Jun 5 17:42:10 2008
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.in Revision: 63545 .
+# From configure.in Revision: 63690 .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.61 for python 2.6.
#
@@ -703,6 +703,7 @@
LN
OPT
BASECFLAGS
+UNIVERSAL_ARCH_FLAGS
OTHER_LIBTOOL_OPT
LIBTOOL_CRUFT
SO
@@ -1328,6 +1329,9 @@
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-universal-archs=ARCH
+ select architectures for universal build ("32-bit",
+ "64-bit" or "all")
--with-framework-name=FRAMEWORK
specify an alternate name of the framework built
with --enable-framework
@@ -1850,6 +1854,16 @@
_ACEOF
+# The later defininition of _XOPEN_SOURCE and _POSIX_C_SOURCE disables
+# certain features on Mac OS X, so we need _DARWIN_C_SOURCE to re-enable
+# them.
+
+cat >>confdefs.h <<\_ACEOF
+#define _DARWIN_C_SOURCE 1
+_ACEOF
+
+
+
define_xopen_source=yes
# Arguments passed to configure.
@@ -1883,6 +1897,27 @@
+UNIVERSAL_ARCHS="32-bit"
+{ echo "$as_me:$LINENO: checking for --with-universal-archs" >&5
+echo $ECHO_N "checking for --with-universal-archs... $ECHO_C" >&6; }
+
+# Check whether --with-universal-archs was given.
+if test "${with_universal_archs+set}" = set; then
+ withval=$with_universal_archs;
+ { echo "$as_me:$LINENO: result: $withval" >&5
+echo "${ECHO_T}$withval" >&6; }
+ UNIVERSAL_ARCHS="$withval"
+
+else
+
+ { echo "$as_me:$LINENO: result: 32-bit" >&5
+echo "${ECHO_T}32-bit" >&6; }
+
+fi
+
+
+
+
# Check whether --with-framework-name was given.
if test "${with_framework_name+set}" = set; then
@@ -1927,9 +1962,14 @@
PYTHONFRAMEWORKPREFIX=$enableval
PYTHONFRAMEWORKINSTALLDIR=$PYTHONFRAMEWORKPREFIX/$PYTHONFRAMEWORKDIR
FRAMEWORKINSTALLFIRST="frameworkinstallstructure"
- FRAMEWORKINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools"
- FRAMEWORKALTINSTALLFIRST="${FRAMEWORKINSTALLFIRST} bininstall maninstall"
- FRAMEWORKALTINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkaltinstallunixtools"
+ FRAMEWORKALTINSTALLFIRST="frameworkinstallstructure bininstall maninstall"
+ if test "$UNIVERSAL_ARCHS" = "all"
+ then
+ FRAMEWORKINSTALLLAST="frameworkinstallmaclib frameworkinstallapps4way frameworkinstallunixtools4way"
+ else
+ FRAMEWORKALTINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkaltinstallunixtools"
+ fi
+
if test "x${prefix}" = "xNONE" ; then
FRAMEWORKUNIXTOOLSPREFIX="${ac_default_prefix}"
else
@@ -1968,6 +2008,12 @@
fi
enable_framework=
+ if test "$UNIVERSAL_ARCHS" = "all"
+ then
+ FRAMEWORKINSTALLLAST=update4wayuniversal
+ FRAMEWORKALTINSTALLLAST=update4wayuniversal
+ fi
+
fi
@@ -4509,6 +4555,11 @@
fi
+
+# The -arch flags for universal builds on OSX
+UNIVERSAL_ARCH_FLAGS=
+
+
# tweak BASECFLAGS based on compiler and platform
case $GCC in
yes)
@@ -4589,7 +4640,25 @@
# -Wno-long-double, -no-cpp-precomp, and -mno-fused-madd
# used to be here, but non-Apple gcc doesn't accept them.
if test "${enable_universalsdk}"; then
- BASECFLAGS="-arch ppc -arch i386 -isysroot ${UNIVERSALSDK} ${BASECFLAGS}"
+ UNIVERSAL_ARCH_FLAGS=""
+ if test "$UNIVERSAL_ARCHS" = "32-bit" ; then
+ UNIVERSAL_ARCH_FLAGS="-arch ppc -arch i386"
+
+ elif test "$UNIVERSAL_ARCHS" = "64-bit" ; then
+ UNIVERSAL_ARCH_FLAGS="-arch ppc64 -arch x86_64"
+
+ elif test "$UNIVERSAL_ARCHS" = "all" ; then
+ UNIVERSAL_ARCH_FLAGS="-arch i386 -arch ppc -arch ppc64 -arch x86_64"
+
+ else
+ { { echo "$as_me:$LINENO: error: proper usage is --with-universalarch=32-bit|64-bit|all" >&5
+echo "$as_me: error: proper usage is --with-universalarch=32-bit|64-bit|all" >&2;}
+ { (exit 1); exit 1; }; }
+
+ fi
+
+
+ BASECFLAGS="${UNIVERSAL_ARCH_FLAGS} -isysroot ${UNIVERSALSDK} ${BASECFLAGS}"
fi
;;
@@ -12500,6 +12569,12 @@
if test ${cur_target} '>' 10.2; then
cur_target=10.3
fi
+ if test "${UNIVERSAL_ARCHS}" = "all"; then
+ # Ensure that the default platform for a 4-way
+ # universal build is OSX 10.5, that's the first
+ # OS release where 4-way builds make sense.
+ cur_target='10.5'
+ fi
CONFIGURE_MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET-${cur_target}}
# Make sure that MACOSX_DEPLOYMENT_TARGET is set in the
@@ -12510,10 +12585,10 @@
export MACOSX_DEPLOYMENT_TARGET
EXPORT_MACOSX_DEPLOYMENT_TARGET=''
- if test ${MACOSX_DEPLOYMENT_TARGET-${cur_target}} '>' 10.2
+ if test ${MACOSX_DEPLOYMENT_TARGET} '>' 10.2
then
if test "${enable_universalsdk}"; then
- LDFLAGS="-arch i386 -arch ppc -isysroot ${UNIVERSALSDK} ${LDFLAGS}"
+ LDFLAGS="${UNIVERSAL_ARCH_FLAGS} -isysroot ${UNIVERSALSDK} ${LDFLAGS}"
fi
LDSHARED='$(CC) $(LDFLAGS) -bundle -undefined dynamic_lookup'
BLDSHARED="$LDSHARED"
@@ -22212,8 +22287,6 @@
esac
-
-
# Check whether right shifting a negative integer extends the sign bit
# or fills with zeros (like the Cray J90, according to Tim Peters).
{ echo "$as_me:$LINENO: checking whether right shift extends the sign bit" >&5
@@ -24771,6 +24844,7 @@
LN!$LN$ac_delim
OPT!$OPT$ac_delim
BASECFLAGS!$BASECFLAGS$ac_delim
+UNIVERSAL_ARCH_FLAGS!$UNIVERSAL_ARCH_FLAGS$ac_delim
OTHER_LIBTOOL_OPT!$OTHER_LIBTOOL_OPT$ac_delim
LIBTOOL_CRUFT!$LIBTOOL_CRUFT$ac_delim
SO!$SO$ac_delim
@@ -24780,7 +24854,6 @@
LINKFORSHARED!$LINKFORSHARED$ac_delim
CFLAGSFORSHARED!$CFLAGSFORSHARED$ac_delim
SHLIBS!$SHLIBS$ac_delim
-USE_SIGNAL_MODULE!$USE_SIGNAL_MODULE$ac_delim
_ACEOF
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
@@ -24822,6 +24895,7 @@
ac_delim='%!_!# '
for ac_last_try in false false false false false :; do
cat >conf$$subs.sed <<_ACEOF
+USE_SIGNAL_MODULE!$USE_SIGNAL_MODULE$ac_delim
SIGNAL_OBJS!$SIGNAL_OBJS$ac_delim
USE_THREAD_MODULE!$USE_THREAD_MODULE$ac_delim
LDLAST!$LDLAST$ac_delim
@@ -24844,7 +24918,7 @@
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 20; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 21; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
Modified: python/branches/tlee-ast-optimize/configure.in
==============================================================================
--- python/branches/tlee-ast-optimize/configure.in (original)
+++ python/branches/tlee-ast-optimize/configure.in Thu Jun 5 17:42:10 2008
@@ -57,6 +57,12 @@
# u_int on Irix 5.3. Defining _BSD_TYPES brings it back.
AC_DEFINE(_BSD_TYPES, 1, [Define on Irix to enable u_int])
+# The later defininition of _XOPEN_SOURCE and _POSIX_C_SOURCE disables
+# certain features on Mac OS X, so we need _DARWIN_C_SOURCE to re-enable
+# them.
+AC_DEFINE(_DARWIN_C_SOURCE, 1, [Define on Darwin to activate all library features])
+
+
define_xopen_source=yes
# Arguments passed to configure.
@@ -86,6 +92,20 @@
])
AC_SUBST(UNIVERSALSDK)
+UNIVERSAL_ARCHS="32-bit"
+AC_MSG_CHECKING(for --with-universal-archs)
+AC_ARG_WITH(universal-archs,
+ AC_HELP_STRING(--with-universal-archs=ARCH, select architectures for universal build ("32-bit", "64-bit" or "all")),
+[
+ AC_MSG_RESULT($withval)
+ UNIVERSAL_ARCHS="$withval"
+],
+[
+ AC_MSG_RESULT(32-bit)
+])
+
+
+
AC_ARG_WITH(framework-name,
AC_HELP_STRING(--with-framework-name=FRAMEWORK,
specify an alternate name of the framework built with --enable-framework),
@@ -127,9 +147,14 @@
PYTHONFRAMEWORKPREFIX=$enableval
PYTHONFRAMEWORKINSTALLDIR=$PYTHONFRAMEWORKPREFIX/$PYTHONFRAMEWORKDIR
FRAMEWORKINSTALLFIRST="frameworkinstallstructure"
- FRAMEWORKINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools"
- FRAMEWORKALTINSTALLFIRST="${FRAMEWORKINSTALLFIRST} bininstall maninstall"
- FRAMEWORKALTINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkaltinstallunixtools"
+ FRAMEWORKALTINSTALLFIRST="frameworkinstallstructure bininstall maninstall"
+ if test "$UNIVERSAL_ARCHS" = "all"
+ then
+ FRAMEWORKINSTALLLAST="frameworkinstallmaclib frameworkinstallapps4way frameworkinstallunixtools4way"
+ else
+ FRAMEWORKALTINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkaltinstallunixtools"
+ fi
+
if test "x${prefix}" = "xNONE" ; then
FRAMEWORKUNIXTOOLSPREFIX="${ac_default_prefix}"
else
@@ -160,6 +185,12 @@
FRAMEWORKUNIXTOOLSPREFIX="${prefix}"
fi
enable_framework=
+
+ if test "$UNIVERSAL_ARCHS" = "all"
+ then
+ FRAMEWORKINSTALLLAST=update4wayuniversal
+ FRAMEWORKALTINSTALLLAST=update4wayuniversal
+ fi
])
AC_SUBST(PYTHONFRAMEWORK)
AC_SUBST(PYTHONFRAMEWORKIDENTIFIER)
@@ -827,6 +858,11 @@
fi
AC_SUBST(BASECFLAGS)
+
+# The -arch flags for universal builds on OSX
+UNIVERSAL_ARCH_FLAGS=
+AC_SUBST(UNIVERSAL_ARCH_FLAGS)
+
# tweak BASECFLAGS based on compiler and platform
case $GCC in
yes)
@@ -865,7 +901,23 @@
# -Wno-long-double, -no-cpp-precomp, and -mno-fused-madd
# used to be here, but non-Apple gcc doesn't accept them.
if test "${enable_universalsdk}"; then
- BASECFLAGS="-arch ppc -arch i386 -isysroot ${UNIVERSALSDK} ${BASECFLAGS}"
+ UNIVERSAL_ARCH_FLAGS=""
+ if test "$UNIVERSAL_ARCHS" = "32-bit" ; then
+ UNIVERSAL_ARCH_FLAGS="-arch ppc -arch i386"
+
+ elif test "$UNIVERSAL_ARCHS" = "64-bit" ; then
+ UNIVERSAL_ARCH_FLAGS="-arch ppc64 -arch x86_64"
+
+ elif test "$UNIVERSAL_ARCHS" = "all" ; then
+ UNIVERSAL_ARCH_FLAGS="-arch i386 -arch ppc -arch ppc64 -arch x86_64"
+
+ else
+ AC_MSG_ERROR([proper usage is --with-universalarch=32-bit|64-bit|all])
+
+ fi
+
+
+ BASECFLAGS="${UNIVERSAL_ARCH_FLAGS} -isysroot ${UNIVERSALSDK} ${BASECFLAGS}"
fi
;;
@@ -1558,6 +1610,12 @@
if test ${cur_target} '>' 10.2; then
cur_target=10.3
fi
+ if test "${UNIVERSAL_ARCHS}" = "all"; then
+ # Ensure that the default platform for a 4-way
+ # universal build is OSX 10.5, that's the first
+ # OS release where 4-way builds make sense.
+ cur_target='10.5'
+ fi
CONFIGURE_MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET-${cur_target}}
# Make sure that MACOSX_DEPLOYMENT_TARGET is set in the
@@ -1568,10 +1626,10 @@
export MACOSX_DEPLOYMENT_TARGET
EXPORT_MACOSX_DEPLOYMENT_TARGET=''
- if test ${MACOSX_DEPLOYMENT_TARGET-${cur_target}} '>' 10.2
+ if test ${MACOSX_DEPLOYMENT_TARGET} '>' 10.2
then
if test "${enable_universalsdk}"; then
- LDFLAGS="-arch i386 -arch ppc -isysroot ${UNIVERSALSDK} ${LDFLAGS}"
+ LDFLAGS="${UNIVERSAL_ARCH_FLAGS} -isysroot ${UNIVERSALSDK} ${LDFLAGS}"
fi
LDSHARED='$(CC) $(LDFLAGS) -bundle -undefined dynamic_lookup'
BLDSHARED="$LDSHARED"
@@ -3191,23 +3249,6 @@
# check for endianness
AC_C_BIGENDIAN
-AH_VERBATIM([WORDS_BIGENDIAN],
-[
- /* Define to 1 if your processor stores words with the most significant byte
- first (like Motorola and SPARC, unlike Intel and VAX).
-
- The block below does compile-time checking for endianness on platforms
- that use GCC and therefore allows compiling fat binaries on OSX by using
- '-arch ppc -arch i386' as the compile flags. The phrasing was choosen
- such that the configure-result is used on systems that don't use GCC.
- */
-#ifdef __BIG_ENDIAN__
-#define WORDS_BIGENDIAN 1
-#else
-#ifndef __LITTLE_ENDIAN__
-#undef WORDS_BIGENDIAN
-#endif
-#endif])
# Check whether right shifting a negative integer extends the sign bit
# or fills with zeros (like the Cray J90, according to Tim Peters).
Modified: python/branches/tlee-ast-optimize/pyconfig.h.in
==============================================================================
--- python/branches/tlee-ast-optimize/pyconfig.h.in (original)
+++ python/branches/tlee-ast-optimize/pyconfig.h.in Thu Jun 5 17:42:10 2008
@@ -489,6 +489,9 @@
/* Define if you have readline 4.2 */
#undef HAVE_RL_COMPLETION_MATCHES
+/* Define when using libedit's readline emulation */
+#undef HAVE_RL_DISPM_VFUNC
+
/* Define if you have readline 4.0 */
#undef HAVE_RL_PRE_INPUT_HOOK
@@ -973,22 +976,9 @@
/* Define to profile with the Pentium timestamp counter */
#undef WITH_TSC
-
- /* Define to 1 if your processor stores words with the most significant byte
- first (like Motorola and SPARC, unlike Intel and VAX).
-
- The block below does compile-time checking for endianness on platforms
- that use GCC and therefore allows compiling fat binaries on OSX by using
- '-arch ppc -arch i386' as the compile flags. The phrasing was choosen
- such that the configure-result is used on systems that don't use GCC.
- */
-#ifdef __BIG_ENDIAN__
-#define WORDS_BIGENDIAN 1
-#else
-#ifndef __LITTLE_ENDIAN__
+/* Define to 1 if your processor stores words with the most significant byte
+ first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
-#endif
-#endif
/* Define to 1 if on AIX 3.
System headers sometimes define this.
@@ -1003,6 +993,9 @@
/* Define on Irix to enable u_int */
#undef _BSD_TYPES
+/* Define on Darwin to activate all library features */
+#undef _DARWIN_C_SOURCE
+
/* This must be set to 64 on some systems to enable large file support. */
#undef _FILE_OFFSET_BITS
Modified: python/branches/tlee-ast-optimize/setup.py
==============================================================================
--- python/branches/tlee-ast-optimize/setup.py (original)
+++ python/branches/tlee-ast-optimize/setup.py Thu Jun 5 17:42:10 2008
@@ -248,6 +248,19 @@
'WARNING: skipping import check for Carbon-based "%s"' %
ext.name)
return
+
+ if self.get_platform() == 'darwin' and (
+ sys.maxint > 2**32 and '-arch' in ext.extra_link_args):
+ # Don't bother doing an import check when an extension was
+ # build with an explicit '-arch' flag on OSX. That's currently
+ # only used to build 32-bit only extensions in a 4-way
+ # universal build and loading 32-bit code into a 64-bit
+ # process will fail.
+ self.announce(
+ 'WARNING: skipping import check for "%s"' %
+ ext.name)
+ return
+
# Workaround for Cygwin: Cygwin currently has fork issues when many
# modules have been imported
if self.get_platform() == 'cygwin':
@@ -541,10 +554,12 @@
# readline
do_readline = self.compiler.find_library_file(lib_dirs, 'readline')
- if platform == 'darwin':
+ if platform == 'darwin': # and os.uname()[2] < '9.':
# MacOSX 10.4 has a broken readline. Don't try to build
# the readline module unless the user has installed a fixed
# readline package
+ # FIXME: The readline emulation on 10.5 is better, but the
+ # readline module doesn't compile out of the box.
if find_file('readline/rlconf.h', inc_dirs, []) is None:
do_readline = False
if do_readline:
@@ -1304,11 +1319,24 @@
'_Dlg', '_Drag', '_Evt', '_File', '_Folder', '_Fm',
'_Help', '_Icn', '_IBCarbon', '_List',
'_Menu', '_Mlte', '_OSA', '_Res', '_Qd', '_Qdoffs',
- '_Scrap', '_Snd', '_TE', '_Win',
+ '_Scrap', '_Snd', '_TE',
]
for name in CARBON_EXTS:
addMacExtension(name, carbon_kwds)
+ # Workaround for a bug in the version of gcc shipped with Xcode 3.
+ # The _Win extension should build just like the other Carbon extensions, but
+ # this actually results in a hard crash of the linker.
+ #
+ if '-arch ppc64' in cflags and '-arch ppc' in cflags:
+ win_kwds = {'extra_compile_args': carbon_extra_compile_args + ['-arch', 'i386', '-arch', 'ppc'],
+ 'extra_link_args': ['-framework', 'Carbon', '-arch', 'i386', '-arch', 'ppc'],
+ }
+ addMacExtension('_Win', win_kwds)
+ else:
+ addMacExtension('_Win', carbon_kwds)
+
+
# Application Services & QuickTime
app_kwds = {'extra_compile_args': carbon_extra_compile_args,
'extra_link_args': ['-framework','ApplicationServices'],
@@ -1375,11 +1403,29 @@
include_dirs.append('/usr/X11R6/include')
frameworks = ['-framework', 'Tcl', '-framework', 'Tk']
+ # All existing framework builds of Tcl/Tk don't support 64-bit
+ # architectures.
+ cflags = sysconfig.get_config_vars('CFLAGS')[0]
+ archs = re.findall('-arch\s+(\w+)', cflags)
+ if 'x86_64' in archs or 'ppc64' in archs:
+ try:
+ archs.remove('x86_64')
+ except ValueError:
+ pass
+ try:
+ archs.remove('ppc64')
+ except ValueError:
+ pass
+
+ for a in archs:
+ frameworks.append('-arch')
+ frameworks.append(a)
+
ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'],
define_macros=[('WITH_APPINIT', 1)],
include_dirs = include_dirs,
libraries = [],
- extra_compile_args = frameworks,
+ extra_compile_args = frameworks[2:],
extra_link_args = frameworks,
)
self.extensions.append(ext)
@@ -1510,6 +1556,7 @@
'_ctypes', 'libffi_osx'))
sources = [os.path.join(ffi_srcdir, p)
for p in ['ffi.c',
+ 'x86/darwin64.S',
'x86/x86-darwin.S',
'x86/x86-ffi_darwin.c',
'x86/x86-ffi64.c',
More information about the Python-checkins
mailing list