|
|
PP4E: Updates Page |
|---|
Last revised: June 2020
This page collects notes, updates, and examples related to the book Programming Python, 4th Edition (PP4E), to serve as supplemental resources for this book's readers. If this page's posts ever had a sequential ordering, it was either accidental or abandoned long ago. Today, items here are best accessed randomly using the topic groupings of the content lists below.
Note that there are only a few true errata (corrections) in the last list below, all of which were fixed in early reprints. If you're looking for a complete corrections list, or find a new issue you wish to report, please see the publisher's errata page for this book. That page automatically notifies me when new posts appear, and hosts both book notes and answers to reader questions not duplicated here.
For more book resources, be sure to also see the following external pages, some of which are newer than this page, and continue its mission:
[May-5-14] New book-related example: Mergeall consists of a script and GUI that synchronize directory trees, and can provide both an incremental updates tool and a manual alternative to cloud storage. Mergeall's main script reuses a number of directory-processing examples that appear in the book's systems programming part. This program's coverage includes code and screenshots, but grew too long for inline treatment here, and was moved off page.
⇨ Click here to go to the Mergeall page
As you'll find on that page, Mergeall eventually was ported to Mac OS too, and packaged as both source code and standalone executables for Mac, Windows, and Linux. It's a realistically scaled project that's too large to cover in the book, but suggested as follow-up study for readers.
Update, 2017
For more book-related example code, see also the newer
Frigcal calendar GUI
example, which showcases Python's tkinter GUI library covered
extensively in the book, and the even newer
programs page, which leads to
upgraded versions of many of the book's major examples—most notably,
PyEdit,
PyMailGUI, and
PyGadgets.
[May-5-14] I've recently begun running book examples on a Linux dual-boot system, under Fedora 20 and Gnome 3 (and later, Ubuntu). This is partly in response to the focus in Windows on clouds, subscriptions, advertising, and devices that are proprietary and seem intentionally crippled, but that's not what this note is about (see the related post).
So far, all the major GUI-based examples work well unchanged, with one minor exception: the script
used to launch PyMailGUI after selecting from one of N email accounts contains an unfortunately
nonportable and hardcoded Windows path. You may never encounter this; PyMailGUI can be run
directly too—and is by the book's demo launchers—and this script is in part
coded to work when PYTHONPATH has not been set to include the book's examples root. But to
fix the account-selector script so it works on Linux too, in this book examples tree file:
.../PP4E/Internet/Email/PyMailGui/altconfigs/launch_PyMailGui.pychange the 2nd-from-last line from the first of the following to the second, in order to pick up the underlying platform's path separator portably:
os.environ['PYTHONPATH'] = r'..\..\..\..\..' # hmm; generalize me os.environ['PYTHONPATH'] = '..%s..%s..%s..%s..' % ((os.path.sep,) * 4) # hmm; generalize meYou may also want to change the last line from
os.system('PyMailGui.py') to
something like os.system('python3 PyMailGui.py') in order to force 3.X execution
on Linux for the spawned PyMailGUI, but this depends on your system's links and
configuration (Python Windows launcher settings don't apply in any event—you'll
need to specialize this line's code per sys.platform if needed). There are undoubtedly
other Linux portability issues in smaller book examples, especially those in the Systems
section; more here as they surface. See also: tkinter Linux
portability notes elsewhere on this page.
Update, 2018 Subsequent to this post, the book's major book examples were also ported to and run successfully on Mac OS. For a sampling of some of the issues this platform poses, both GUI-related and general, see the release notes of:
Each of the above programs is also available in source-code form that illustrates Mac
coding. Python and tkinter may be relatively portable, but some platform-specific
divergence is unavoidable. The Mac's richer GUI experience—including global toolbars,
slide-down dialogs, and app state—implies unique coding requirements.
Short story:
due to a temporary regression in Python's email package, you probably should not run
the book's PyMailGUI email client on Python 3.3.3. Instead, use any other
Python 3.X version—3.1 or 3.2; 3.3.0 through 3.3.2; 3.3.4 or later 3.3; or 3.4.0 or later 3.4.
[Mar-4-14]
In 3.3.3 only, Python's email package changed in a way that broke this book's
PyMailGUI. The break occurs when replying to or forwarding a message whose main body text contains
a non-ASCII character that was encoded per base64 or quoted-printable in the original message.
Such email messages worked fine in PyMailGUI from Pythons 3.1 through 3.3.2. In 3.3.3,
though, a simple slanted quote or emdash suffices to cause problems; when such characters
are present in the body text, PyMailGUI doesn't crash, but the message can't be sent,
and the GUI displays an error dialog with text:
Send failed: <class 'UnicodeEncodeError'> 'utf-8' codec can't encode character '\udce2' in position 688: surrogates not allowed
This makes no sense, given that surrogates are supposed to be employed
in the email package's new bytes API only—an API which
PyMailGUI predates, and does not use in any way (PyMailGUI decodes message
full-text to str text instead). The 3.3.3 email package must be
mutating the already-decoded body text, and inserting surrogate Unicode
escapes—something it absolutely should not do, and did not do until
the 3.3.3 point release.
Timing: because the error occurs on Send in the Message.set_payload() call following
the fix_text_required() workaround for an earlier email issue, a change in character-set
output encoding logic is the prime suspect. Before this point, the fetched
raw text of mails is correct (double-clicks show its original encoded form),
as is the result of mail parsing (View, Reply, and Fwd all display correctly
decoded text, including any non-ASCII characters). Both failing cases observed
were attempting to encode text per UTF-8 plus base64 on Send. In any event, the next
section makes this largely a moot point.
The good news is that this Python regression appears to have been present in just one point release, and was fixed quickly. It has been observed in 3.3.3 only (plus an early 3.4 beta which inherited the issue temporarily). It is not present in 3.3.2, and is fixed as of 3.3.4. Its repair was also propagated to later 3.4 prereleases. Since the latest official 3.3 and 3.4 downloads available at python.org—currently 3.3.4, 3.3.5rc2, and 3.4.0rc2—do not have the problem, its impact should be minimal.
PyMailGUI itself was coded for Pythons 3.1 and 3.2, current at book development time, but is known to work well through 3.4.0, apart from this temporary surrogates issue in 3.3.3. I use this program constantly, but only recently discovered the issue when using a newer 3.3.3 install. It's less than ideal for point releases to break working programs this way, of course, but mistakes happen, and programs like PyMailGUI have to mind the bleeding edge of Python releases more than most; book readers tend to prefer the latest Python either way.
For examples of other PyMailGUI breakages caused by Python email package changes,
see the patch for item #3 on this page;
it's been a potential source of problems with each new Python release installed.
I've also observed some Windows line-break strangeness in recent email package versions
(text is sometimes saved as one long line), but this is to be investigated.
In the end, this makes for a reasonable lesson in itself: library dependencies
are an unavoidable aspect of real-world software development.
Footnote: You can verify the Python version that PyMailGUI is using by clicking Write, entering the following program code in the Write window's main text area, and then clicking its Tools -> Run Code menu option; this is a feature of the PyEdit component, which runs the edited text as program code, and shows its output in the console window where PyMailGUI was launched (don't try that in Outlook...):
import sys print(sys.version)
Update, 2018 PyMailGUI eventually broke its dependencies on the latest-and-greatest Python release by providing standalone executable packages for each major desktop platform. These "frozen" executables simplify installs and better integrate with platform GUI metaphors. Perhaps more importantly, by bundling specific and verified versions of Python and Tk, they grow immune to future changes in either. The downside of such packages is extra build complexity beyond this update's scope; see PyMailGUI's home page and build folder for more details.
Short story: Tk, the library underlying the tkinter GUI module used in
book examples, does not currently support some Unicode characters. If unsupported characters
may crop up, programs need to replace these for display to avoid possibly uncaught exceptions.
PyMailGUI, PyEdit, and other book-related programs now do.
[Jan-16-14]
After using the threaded PyMailGUI on a daily basis for 8 years (more than 3 in its
latest 4th Edition form), a new issue cropped up when someone sent an email whose alternative
text part contained a Unicode character not supported by the underlying Tk GUI
library—character 🙊, which is Unicode codepoint U+1f64a
and u'\U0001F64A' in Pythonese, the "Speak-No-Evil Monkey"
character (no really; look it up).
The Tk GUI system can't handle character codes over
16 bits like this one (technically, outside the "BMP"), and PyMailGUI relies on Tk's
rendering prowess to do the right thing for Unicode, as described in the book; see pages 538-548.
As is, PyMailGUI reports the Tk error message in the console window and doesn't crash per se, but the GUI is partly disabled, because this error is raised and uncaught in a thread-exit callback, thus preventing a thread-busy lock from being released... which in turn disables future Loads, Views, Deletes, and Quits (in fact, Task Manager may be required to close the GUI on Windows, and similar elsewhere).
To do better, fetch this updated ViewWindows.py, and copy it
into your book example tree's PP4E\Internet\Email\PyMailGUI folder. It simply catches the Tk
library exception, displays a popup and stack trace, and continues, so that thread-busy locks are
released. Search for "1.5" in the file for more on the changes; the too-large Unicode character
also triggers a Tk exception in other places (e.g., viewing the text part later), but these are
already caught and reported with popups, and don't impact thread locks.
From the semi-related-topics department: additional PyMailGUI changes to support POP over SSL, SMTP over SSL/TLS, and POP servers that limit logins by time (thereby perhaps requiring a single persistent login instead of one login per transaction) are in progress, but are also suggested exercise. Accounts on outlook.com are one motivation for some of these mods. The first two (SSL/TLS) are now supported in Python's libs, but not yet in PyMailGUI; see Python manuals for usage details, and this related note on this page.
Update, 2016 For much more on the Tk Unicode limitation, see its later description in the Frigcal docs. That program confronts the same issue, in the context of calendars and events. This is most egregious to people who abuse emojis (hey—you know who you are!).
Update, 2017 The Tk Unicode limitation in PyMailGUI—and the PyEdit component it uses—was eventually addressed more globally in its standalone release available here. To fix, all non-BMP Unicode characters are now replaced with the Unicode replacement character � for display (until Tk supports more of Unicode, including emojis). There's more on the issue at large in standalone PyEdit's user guide; search for its "About emojis" notebox.
Update, 2018
Support for email servers that use or require SSL/TLS also eventually found its way
into PyMailGUI's standalone release; see its
change log and
mailconfig
files for details.
[Sep-15-13]
Per the description elsewhere on this page, a Python 3.3
standard library change broke some email address displays of non-ASCII names in
PyMailGUI, the largest example in the book.
In short, the Python 3.3 email package's formataddr utility function now
applies a new automatic MIME encoding for names, which it did not in the past—a curious and undocumented
incompatible change, which did not account for display-oriented use cases, and can break code that
worked well under Pythons 3.0 through 3.2 (including some in this book). Luckily, this is fairly
easy to repair.
To apply and use the patch for this Python change, simply fetch the following two files,
and copy them to the PP4E\Internet\Email\PyMailGui folder in your book examples tree,
per the more detailed instructions in the first of these:
py33patch.py—the patch to import, with self-test and docs
SharedNames.py—replacement for this file with required patch import
email package to be backward compatible for the duration
of the PyMailGUI program's run only. The second file, an existing part of PyMailGUI,
is simply augmented to import the first. The first file also has additional
documentation on the issue and its patch—see its comments for more details.
(And yes, this is a module-level example of what's called "monkey patching" today, though applying a new label to an old technique doesn't necessarily make it any more palatable...)
Update, Oct-15-13 There is a new 1.4 release of the book's examples package which incorporates the small Python 3.3 patch described above. Get the new examples release here, and read about its 3.3 (and later) changes here.
Update, Nov-26-13 It has now been verified that this patch and the 1.4 examples release also suffice to make the book examples described here work under Python 3.4, per its beta releases.
Update, Oct-1-15 It's now also been verified that this patch and the 1.4 examples release suffice to make the book examples mentioned here work under Python 3.5, per its final 3.5.0 release.
Update, 2018 Naturally, this patch was also present in PyMailGUI's later standalone release. This release used Python 3.5 in 2017 and still does; later 3.Xs are not compelling enough to offset revalidation and redistribution costs (despite the PR).
[Aug-22-13] Because it is now officially an FAQ, this post includes the important bits from a dialog with a reader who was having trouble running the web examples in the preview chapter of the book. In short, on some machines you may need to change the hardcoded port number used in this script to something other than "80," and list it in the URL explicitly (and read ahead in the book itself to the full coverage of this subject in later sections).
> > -----Original Message----- > > To: lutz@rmi.net > > Subject: Programming Python 4th Ed > > Date: Wed, 21 Aug 2013 13:49:19 +0100 > > > > Dear Sir > > > > Programming Python 4th Edition. > > I'm stuck on page 53. Example 1-30 runs ok but I can't get example > > 1-31 to reply. When I run the html script it lists the contents of > > 1-31, How do I get it to execute 1-31? > > I am using Python 3.3 on Windows 7. > > > -----Original Message----- > From: Mark Lutz [mailto:lutz@rmi.net] > Sent: 21 August 2013 17:14 > Subject: Re: Programming Python 4th Ed > > There are too many things that can go wrong in the Web realm to offer advice > based on your email (including but not limited to running the web server > shown a page or two ahead). My advice is to read ahead to the server side > scripting chapter of the book for the full story on the Web/CGI domain. > > > -----Original Message----- > To: 'Mark Lutz'> Subject: RE: Programming Python 4th Ed > Date: Thu, 22 Aug 2013 11:39:13 +0100 > > Hi Mark > Thanks for your prompt reply. I followed your advice to read further. > When I run Example 1-32 Pg56 webserver.py I get the following output:- > > Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:55:48) [MSC v.1600 32 bit (Intel)] on win32 > Type "copyright", "credits" or "license()" for more information. > >>> ================================ RESTART================================ > >>> > Traceback (most recent call last): > File "C:\Users\...\Documents\AAAPROJECTS\COMPUTERSCIENCE\PYTHON\PROGPY33\C01\webserver.py", line 15, in > srvrobj = HTTPServer(srvraddr, CGIHTTPRequestHandler) > File "C:\Python33\lib\socketserver.py", line 430, in __init__ > self.server_bind() > File "C:\Python33\lib\http\server.py", line 135, in server_bind > socketserver.TCPServer.server_bind(self) > File "C:\Python33\lib\socketserver.py", line 441, in server_bind > self.socket.bind(self.server_address) > OSError: [WinError 10013] An attempt was made to access a socket in a way forbidden by its access permissions > >>> > > Could you please help me with "socket access permissions" as I am new to web > programming. This is the reason I purchased your book to extend my Python > Programming into web applications. > > I am running on my own Dell desktop as administrator using Windows 7 > Internet Explorer 10. > The webserver script works fine for me on Python 3.3 and Windows7. Running the server in a Command Prompt window: c:\PP4E\Examples\PP4E\Preview> py -3.3 webserver.py 127.0.0.1 - - [22/Aug/2013 09:04:08] code 404, message File not found 127.0.0.1 - - [22/Aug/2013 09:04:08] "GET /favicon.ico HTTP/1.1" 404 - 127.0.0.1 - - [22/Aug/2013 09:04:17] "POST /cgi-bin/cgi101.py HTTP/1.1" 200 - 127.0.0.1 - - [22/Aug/2013 09:04:17] command: C:\Python33\python.exe -u c:\PP4E\Examples\PP4E\Preview\cgi-bin\cgi101.py "" 127.0.0.1 - - [22/Aug/2013 09:04:17] CGI script exited OK And responding to this URL typed in a web browser window: http://localhost/cgi101.html Probably, you cannot run a server on port #80 (the script's default) on your machine, because it is locked down by something else (e.g., virus software?). Try changing the port# in the webserver script, and then name the port# in the URL explicitly: port = 8080 # default http://localhost/, else use http://localhost:xxxx/ c:\PP4E\Examples\PP4E\Preview> py -3.3 webserver.py http://localhost:8080/cgi101.html Or, pass the port# in on the command line to the expanded version of this script that appears later in the book, and run the examples in that later section's directory: c:\PP4E\Examples\PP4E\Internet\Web> py -3.3 webserver.py . 8080 webdir ".", port 8080 ...server log... http://localhost:8080/languages.html This is all explained in detail later in the book in the server-side scripting chapter. It's also mentioned in the preview chapter you're reading; quoting from page 57: """ One pragmatic note here: you may need administrator privileges in order to run a server on the script’s default port 80 on some platforms: either find out how to run this way or try running on a different port. To run this server on a different port, change the port number in the script and name it explicitly in the URL (e.g., http://localhost:8888/). We’ll learn more about this convention later in this book. """ If changing port #s doesn't suffice, I'm afraid there's nothing more I can offer; server setup is widely variable, and may require some supplemental exploration. Best wishes, --Mark Lutz (http://learning-python.com, http://rmi.net/~lutz)
Short story: this section includes a now-dated summary of post-publication changes to PyMailGUI, followed by updates on that program's later evolution. Be sure to also see this section's updates ahead for more recent information.
[Oct-1-11] After using the book's PyMailGUI email client for just over a year, I've collected a list of additional enhancements beyond those already described in the book (see the original enhancements list at the end of PyMailGUI's Chapter 14). I am the entire testing department and user base for this program, so some issues have taken longer to shake out than others. The following is a list of all these additional PyMailGUI enhancements discovered and applied after the book was published, for completeness; their write-ups are located elsewhere on this page:
| 1 | Feb-01-11 | Using POP and SMPT timeout parameters (patched in 1.2, and book) | write-up |
|---|---|---|---|
| 2 | Jan-10-11 | Closing temporary output files for HTML-only emails (patched in 1.2, and book) | write-up |
| 3 | Aug-08-11 | Decoding and encoding non-ASCII attachment filenames (patched in 1.3, and book) | write-up |
| 4 | Oct-01-11 | Improved sent-time display in list windows (patched in 1.3) | write-up |
| 5 | Sep-29-11 | Delete and Save timing issue, rare bug (patched in 1.3) | write-up |
| 6 | Jul-29-11 | Using authenticating SMTP servers for sends in mailconfig (patched in 1.3) | write-up |
Interestingly, two of these changes, #1 and #3, are also inherited by the less functional PyMailCGI
webmail example of Chapter 16, because they were applied in the common mailtools package.
There were a handful of additional changes made in the examples package and their book listings (e.g., a
focus fix in the PyEdit component used by PyMailGUI); see the
change log as well as the changes'
write-ups on this page for more details.
To sample the effect of changes #3 and #4 above, see the following PyMailGUI screenshots:
The support for non-ASCII attachment filenames and local-relative time in these is new in the 1.3 example package, but the rest is original behavior. See the book for more on PyMailGUI's i18n and Unicode support in other headers and mail content.
[Oct-19-11] I've posted a new release of the book examples package, version 1.3, which has patches for all 6 of the PyMailGUI updates listed in this section above. The first two of these were already patched in release 1.2, but the rest are new in 1.3. Get the change log and the complete new examples zip file at O'Reilly's site, or fetch just the files changed within it in this zip file. See the book for details on running PyMailGUI in the examples package (via auto launchers, command lines, etc.). I don't distribute this program standalone, partly because it uses many other files in the book examples tree, and partly because the book is its documentation (but see the later update ahead).
One admin note: Some of the changes made in version 1.3 of the examples package are too large
to find their way into reprints of the book itself, but I recommend using the new version in
general, and studying the files changed to see what was involved; it's a fair example of code
maintenance in action. For changes too big to merge into the book, versions of the changed
source files which mirror the code in the book are retained in the examples package with
a "BOOK-" name prefix. For details, see the
change log which is also
file changes\CHANGES.txt in the examples package.
[Sep-15-13]
There is a simple patch for an address-display issue introduced by a change in
Python 3.3's email package, that is included in version 1.4 of the examples package.
For details, see the bug, as well as its fix.
[2018] PyMailGUI eventually was released as a standalone product (apart from the book) in 2017, with numerous enhancements not noted here, and ports to Linux and Mac OS. You can read a summary of all its post-publication changes here, and trace its evolution at its home page and user guide. The related PyEdit program was similarly upgraded, ported, and packaged at the same time; it's post-publication changes history is chronicled here. Book readers are encouraged to begin by studying the base versions of these programs in the book, and move on to explore the new standalone versions' code later. The newer versions are more polished for general use and portability, but retain the original versions' core ideas.
[Jan-4-12]
If a book example which uses the input() built-in seems to be failing,
and you are using Python 3.2.0 in a Windows console window, see
this post
on Learning Python 4E's update pages.
This built-in was apparently broken temporarily in 3.2.0 (3.2) in Windows console mode, but has been fixed in later Python releases. The quickest fix is to upgrade to 3.2.1 or later, or try a different environment; the book examples work fine in all other Pythons and most other contexts such as IDLE. Scripts in both books may be impacted by this regression.
[Jan-11-12]
Another cross-post from the Learning Python update pages about a Python change
which impacts examples in Programming Python too—see
this note
for details on Python 3.2's decision to drop support of str strings
for the "s" type code in struct.pack.
This impacts a variety of examples in this book. The simplest fix is to manually
encode str Unicode strings to bytes byte strings when passing to
struct.pack, per the referenced note. You can also run these examples in 3.1
or earlier if that's an option, though newer Pythons are generally better Pythons.
[Oct-2012] I've started testing the book's examples under Python 3.3, the latest release which features:
__init__.py file
yield from ...),
suppressing exception context (raise ... from None), and
accepting 2.X's Unicode literals to ease migration (3.3 now treats
2.X's Unicode literal u'xxxx' the same as its normal str
literal 'xxxx', similar to the way 2.X treats 3.X's bytes-string literal
b'xxxx' the same as its normal str literal 'xxxx')
pydoc -b)
ftplib,
time, and email
PATH
setting to include 3.3's directory as an install-time option to simplify
command lines
#!...
lines for dispatching Python scripts on Windows, and allows both #! lines
and new py command lines to select between Python 2.X and 3.X explicitly on
both a per-file and per-command basis
Of these, the last 3.3 enhancement listed above will probably have the broadest impact (in fact, it affects every Python 3.3+ user on Windows, which, for better or worse, is a huge audience), and merits a few more words. Those words have grown too large for this page, however, so I've moved them to this separate article:
⇨ The New Windows Launcher in Python 3.3
The very short story on the launcher is that it registers new
executables which are installed on your system path normally;
attempts to parse #! Unix-style lines at the top of scripts to
determine which version of Python run; and supports command-line
arguments that give Python version numbers. The net effect is
to better support multiple Pythons coexisting on the same machine,
by allowing Python version numbers to be specified on both a
per-file and per-command-line basis, and in both full and partial
form. It's quite a useful trick, though not without the pitfalls
described below. For much more on the launcher in general,
see the link above, or the new appendix on the subject in 2013's
Learning Python, 5th Edition.
PP4E's book examples were initially developed on 3.1, but tested successfully on 3.2 alpha before publication. In general, most examples tested so far appear to work well on 3.3 and as shown in the book. As expected, though, the evolution in the 3.X line has impacted some behaviors. Among the most notable 3.3 changes that affect book examples:
ftplib and time modules.
See my earlier 3.3 preview
for details. The email package has also changed, but merits its own bullet here.
email package
have broken some aspects of the book's email examples, including the
larger PyMailGui program. Most of PyMailGui works fine as is under 3.3,
which is surprising given the scope of email changes. But non-ASCII (I18N)
email addresses in header lines which decoded properly in 3.0 through 3.2
no longer decode under 3.3.
For a graphical representation of this 3.3 regression, see this screen shot—the PyMailGui window on the left is the book's I18N saved-mail file open under 3.3, and the window on the right is the same open in 3.2. The 3.3 version on the left fails to decode the non-ASCII addresses which 3.2 handled, most likely reflecting an incompatible API change. More details on a fix, as well as additional 3.3 email issues, as they emerge.
Update, 9/2013: A patch for this 3.3 incompatibility is now available, as described elsewhere on this page.
The short story in this department is that the new launcher:
#! Unix lines,
which causes a dozen book example files to fail in 3.3 (including
the top-level PyGadgets and PyDemos demo launcher scripts)
#! names just "python", as well as files with no
#! line at all—the normal case on Windows)
With respect to book examples, the first point requires changing
#!/bin/env to #!/usr/bin/env in a dozen examples files,
and the second point can be addressed by setting the launcher's default
to 3.X, via set PY_PYTHON=3 (or the equivalent in Control Panel).
The Python 3.3 installer also has an optional PATH extension
feature, which seems contradictory to the new launcher's goals,
but shouldn't cause scripts to fail in general.
As the off-page launcher write-up concludes, the new launcher is
a net Good Thing, but you need to be aware that it may break some
formerly valid scripts with #! lines, and may choose a default
version you don't expect which causes many scripts to fail initially.
More here on 3.3 in general as testing continues. You can also read about earlier Python 3.2 changes here, and later 3.4+ changes here.
Short story: PIL became the largely compatible Pillow, which is still
actively supported, and freely available at the standard PyPI website
here.
Fetch and install the Pillow drop-in replacement to run the book's image-related
PIL examples, per this section's updates. As of Tk 8.6, this install isn't
required if you just need to display PNG
images in tkinter GUIs.
[Apr-21-12]
This book uses the PIL (Python Imaging Library) extension for some image-based examples,
both to render thumbnail images, and to display additional image file types in tkinter GUIs.
Because PIL was not yet ported to 3.X, the book employed a custom installer provided by
PIL's creator, and included this installer in its examples package as a temporary measure
pending an official 3.X port.
A reader wrote recently to note that the PIL installer in the book's examples package works only under Python 3.1, and not for 3.2. I don't track PIL's progress, but it has much more utility than the book leverages, and I suspect that this has held up the 3.X port (naturally, this is a non-issue for 2.X readers, for which PIL installers are available). Since this is a general issue which other readers have asked about too, the relevant portion of my reply follows:
About a PIL installer for 3.2: an official 3.X PIL port has
yet to materialize; it was considered imminent two years ago.
The stop-gap installer I was given by PIL's creator and shipped
in the book examples package is an executable for 3.1 only,
which I unfortunately have no way to update.
I recommend contacting PIL's creator, F. Lundh, about
this, and/or browsing the archives of and posting your query
to PIL's email list to see what may be possible today.
PIL's creator's last known email address (two years ago):
(please search pythonware.com)
and the image-sig email list for PIL lives here:
http://mail.python.org/mailman/listinfo/image-sig
If you get a resolution on this and can spare the time, I'd
appreciate a copy on what you find; other readers have run
into the same issue. If I'm able to uncover anything myself,
I'll follow-up.
In the worst case, you can always install 3.1 alongside 3.2
to experiment with PIL examples, or take the examples' code
as demonstrative if not runnable.
Update, May 2012 A web search turns up unofficial PIL installers for Python 3.2 and 3.3, including those at this site, though I have yet to test their operation with book examples.
Update, July 2012 It's now been verified that the "unofficial" PIL ports for Python 3.X described in the prior update do work correctly, at least on Windows under Python 3.2 and 3.3 and for the PIL subset used by the book's examples—tkinter image display, thumbnail generation, and resize operations. Specifically: