As mentioned, this edition now covers Python 3.X only. Python 3.X is an incompatible version of the language. The 3.X core language itself is very similar to Python 2.X, but there are substantial changes in both the language and its many standard libraries. Although some readers with no prior background in 2.X may be able to bypass the differences, the changes had a big impact on the content of this edition. For the still very large existing Python 2.X user base, this section documents the most noteworthy changes in this category.
If you’re interested in 2.X differences, I also suggest finding a copy of the Fourth Edition of the book Python Pocket Reference described earlier. That book gives both 2.X and 3.X versions of core language structures, built-in functions and exceptions, and many of the standard library modules and tools used in this book. Though not designed to be a reference or version translator per se, the Fourth Edition of Learning Python similarly covers both 2.X and 3.X, and as stated, is prerequisite material to this book. The goal of this 3.X-only Programming Python is not to abandon the current vast 2.X user base in favor of a still imaginary one for 3.X; it is to help readers with the migration, and avoid doubling the size of an already massive book.
Luckily, many of the 2.X/3.X differences that impact this book’s
presentation are trivial. For instance, the
tkinter GUI toolkit, used extensively in
this book, is shown under its 3.X
tkinter name and package structure only; its
Tkinter module incarnation is
not described. This mostly boils down to different import statements,
but only their Python 3 versions are given here. Similarly, to satisfy
3.X module naming conventions, 2.X’s
urllib.request.urlopen, respectively, in
both Python 3.X and this edition. Other tools are similarly
On the other hand, 3.X implies broader idiomatic changes which
are, of course, more radical. For example, Python 3.X’s new Unicode
awareness has inspired fully Internationalized versions of the PyEdit
text editor and the PyMailGUI email client examples in this edition
(more on this in a moment). Furthermore: the replacement of
os.popen2 with the
subprocess module required new examples; the
os.path.walk in favor of
os.walk allowed some examples to be
trimmed; the new Unicode and binary dichotomy of files and strings
impacted a host of additional existing examples and material; and new
modules such as
offer new options covered in this edition.
Beyond such library changes, core language changes in Python 3
are also reflected in this book’s example code. For instance, changes
apply all required changes here. In
addition, 3.X’s new package-relative import model
impacted a few examples including
mailtools and expression parsers, and its
different flavor of division forced some minor
math updates in canvas-based GUI examples such as PyClock, PyDraw, and
Of note here, I did not change all
% string formatting
expressions to use the new
format, since both forms are supported
in Python 3.1, and it now appears that they will be either
indefinitely or forever. In fact, per a “grep” we’ll build and run in
Chapter 11’s PyEdit example, it seems
that this expression still appears over 3,000 times in Python 3.1’s
own library code. Since I cannot predict Python evolution completely,
see the first chapter for more on this if it ever requires updates in
an unexpected future.
Also because of the 3.X scope, this edition is unable to use some third-party packages that are still in 2.X form only, as described earlier. This includes the leading MySQL interface, ZODB, PyCrypto, and others; as also mentioned, PIL was ported to 3.1 for use in this book, but this required a special patch and an official 3.X release is still presently pending. Many of these may be available in 3.X form by the time you read these words, assuming the Python world can either break some of the current cross dependencies in 2.X packages or adopt new 3.X-only tools.
As a book focused on applications instead of core language fundamentals, language changes are not always obtrusive here. Indeed, in retrospect the book Learning Python may have been affected by 3.X core language changes more than this book. In most cases here, more example changes were probably made in the name of clarity or functionality than in support of 3.X itself.
On the other hand, Python 3.X does impact much code, and the impacts can be subtle at times. Readers with Python 2.X backgrounds will find that while 3.X core language changes are often simple to apply, updates required for changes in the 3.X standard library are sometimes more far reaching.
Chief among these, Python 3.X’s Unicode strings have had broad ramifications. Let’s be honest: to people who have spent their lives in an ASCII world, the impacts of the 3.X Unicode model can be downright aggravating at times! As we’ll see in this book, it affects file content; file names; pipe descriptors; sockets; text in GUIs; Internet protocols such as FTP and email; CGI scripts; and even some persistence tools. For better or worse, once we reach the world of applications programming as covered in this book, Unicode is no longer an optional topic for many or most Python 3.X programmers.
Of course, Unicode arguably never should have been entirely optional for many programmers in the first place. Indeed, we’ll find that things that may have appeared to work in 2.X never really did—treating text as raw byte strings can mask issues such as comparison results across encodings (see the grep utility of Chapter 11’s PyEdit for a prime example of code that should fail in the face of Unicode mismatches). Python 3.X elevates such issues to potentially every programmer’s panorama.
Still, porting nontrivial code to 3.X is not at all an insurmountable task. Moreover, many readers of this edition have the luxury of approaching Python 3.X as their first Python and need not deal with existing 2.X code. If this is your case, you’ll find Python 3.X to be a robust and widely applicable scripting and programming language, which addresses head-on many issues that once lurked in the shadows in 2.X.
There’s one exception that I should call out here because of its impact on major book examples. In order to make its code relevant to the widest possible audience, this book’s major examples are related to Internet email and have much new support in this edition for Internationalization and Unicode in this domain. Chapter 14’s PyMailGUI and Chapter 16’s PyMailCGI, and all the prior examples they reuse, fall into this category. This includes the PyEdit text editor—now Unicode-aware for files, display, and greps.
On this front, there is both proverbial good news and bad. The
good news is that in the end, we will be able to develop the
feature-rich and fully Internationalized PyMailGUI email client in
this book, using the
Unfortunately, as we’ll learn in Chapter 13, the
bytes combinations in Python 3.X. For
example, there’s no simple way to guess the encoding needed to convert
bytes returned by the
poplib module to the
str expected by the
This situation appears to be temporary. Some of the issues
encountered in this book are already scheduled to be repaired (in
fact, one such fix in 3.2 required a last-minute patch to one of this
book’s 3.1 workarounds in Chapter 13).
Furthermore, a new version of
These issues in the
cgi module for CGI file uploads, which are
in large measure broken in 3.1. CGI scripts are a basic technique
eclipsed by many web frameworks today, but they still serve as an
entry-level way to learn Web fundamentals and are still at the heart
of many larger toolkits. A future fix seems likely for this 3.1 flaw
as well, but we have to make do with nonbinary CGI file uploads for
this edition in Chapters 15 and 16, and
limited email attachments in PyMailCGI. This seems less than ideal
nearly two years after 3.0’s release, but such is life in the dynamic
worlds of both software development at large and books that aim to
lead the curve instead of following it.