Programming Python corrections and clarifications

This page lists all known errata in the first edition of the book Programming Python. Corrections are listed by increasing page numbers, and entries added recently are marked with the word "NEW" (search the page to find these updates). A few very recent additions appear at the end of this page.

Notes: some of the items below are more like wishes than errors. Most were fixed in later printings of the book, so you may or may not find these in yours. In fact, most or all of the items listed below have been fixed in the last few printings of the book. At this writing, the English version of the book is currently in the sixth printing of the first edition (4/99).

Related pages:


Corrections for "Programming Python", first printing.

Last updated: February 1999

Here are the problems uncovered so far, in the first printing of the book. Most have been fixed in later printings of the book, but new issues still pop up from time to time. This list was recently reordered by page numbers, in response to reader requests; it's no longer ordered by severity, but the vast majority of these are minor corrections. Newly added entries will have the word "NEW" in their first line for at least a month after I post them (search on NEW to find recent additions) and/or may be added at the end.

There probably are a few mistakes yet to be uncovered (in a 900-page book, there's plenty of room for error). If you find one that's not on this list, please drop me (or O'Reilly) a line; we want to make the book as accurate as possible, and will be correcting bugs each time the book is printed. You can send a bug report by email (see the end of this page). I'm also interested in any and all suggestions about new material for future editions.

Thanks to everyone who took time to send in comments and problem reports.




1)  Type:  Acknowledgements adjustment
    Where: page xxii, preface, last paragraph
    Fix:   The set of kids names mentioned in the last paragraph 
           needs to be expanded to include the name "Roxanne"; 
           another case of concatenation in action...
 
 
2)  Type:  Adjustment: spacing
    Where: Page 16, "Methods" paragraph, second sentence, after comma
    Fix:   Shorten to
              ", the self argument receives the implied instance object:"
    Notes: Just a suggestion--the word spacing looks a little odd, so we
           may shorten this sentence this way if it helps
 
 
3)  Type:  Printing glitch
    Where: Page 22, just before "Tuple packing" paragraph label
    Fix:   Change ":186" to ":"  (delete the "186")
 
 
4)  Type:  Technical adjustment
    Where: Page 22, start of example at bottom
    Fix:   Change "% Python" to "% python"
    Notes: Not serious (there are many ways to start the interpreter),
           but I use lower case "% python" in all other places
 
 
5)  Type:  Adjustment: code indentation
    Where: Page 62, end of example 2-39
    Fix:   The two lines that start with "cc " should be indented the same
    Notes: Not serious, but these usually both start with a tab in a
           makefile, so they should look the same in terms of indenting
 
 
6)  Type:  Production adjustment
    Where: Page 64, end of sidebar "Towards automated integration"
    Fix:   Change "..." at end to "!"
    Notes: I'm being picky on this one, but there are now 2 sidebars on
           facing pages that both end in "..."; should probably differ.
           The "What's in a Name" sidebar originally appeared on a
           separate (non-facing) page.
 
 
7)  Type:  Spelling
    Where: Page 103 (table 4-1), and page 764 (last list item)
    Fix:   Change "Hexidecimal" to "Hexadecimal" [note the "a"]
    Notes: My spell checker says it's wrong with the "i"
 
 
8)  Type:  Inaccurate wording: "ref"
    Where: Page 143, 1st bullet item at top, AND
           Page 855, 5th paragraph (labeled "Ref parameters")
    Fix:   Change the word "ref" to "reference"
           on both pages, in both the text and the paragraph label
    Notes: "ref" is a common abbreviation; but as used, it makes it look
           like it's a C++ keyword (it's not).  These pages are talking
           about C++ "&" reference parameters.

 
9)  Type:  Program error: bad variable name
    Where: Page 154, code near middle of page
    Fix:   Change
               "y, y = 1, 2"
           to
               "y, z = 1, 2"
 
    Notes: I broke this with a last-minute attempt to save a line.
           As is, there's an undefined name error if "z" is used.
 

10) Type:  Ambiguous wording
    Where: page 233, line -12 (12th from bottom)
    Fix:   change "within class members:" --> "within class methods:"
  

11) Type:  Typo
    Where: page 233, line -3
    Fix:   change ". namespace" --> ". Namespace"
 
 
12) Type:  Bad figure reference
    Where: Page 237, start of last full (non-bullet) paragraph
    Fix:   Change "In Figure 9-4" to "In Figure 9-5"
 
 
13) Type:  Bad label in figure (NEW: added 8/13/97)
    Where: Page 328, in figure 11-17, in bottommost rectangle
    Fix:   Change two "Menubutton" in bottom frame to "Button"


14) Type:  Tkinter incompatibility in Python 1.4: ScrolledText options
    Where: page 331, "guimixin.py" example in chapter 11
    Fix:   change
             "text = ScrolledText(new, {'height':30, 'width':90, Pack:{}})"
           to
             "text = ScrolledText(new, height=30, width=90); text.pack()"
 
    Notes: This is also only an issue when using Python version 1.4
           (the book and CD are based on version 1.3).  But the new
           ScrolledText widget in 1.4 is not backward compatible with
           the 1.3 creation signature: 1.3 supports only configuration
           option dictionaries, and 1.4 supports only keywords.
 
           Hence, the call above needs to be changed to use keywords
           for 1.4.  Unfortunately, this will break the example for 1.3
           users.  Release 1.5 might support both schemes (like most
           other widgets), but for now users need to pick either
           dictionaries (for 1.3) or keywords (for 1.4):
 
           Python 1.2 and 1.3 (dictionaries only)
               >> class ScrolledText(Text):
               >>       def __init__(self, master=None, cnf={}):
 
           Python 1.4 (keywords only)
               >> class ScrolledText(Text):
               >>       def __init__(self, master=None, **cnf):
 
           Python 1.5?? (both)
               >> class ScrolledText(Text):
               >>       def __init__(self, master=None, cnf={}, **kw):
 
           The example must be updated on the CD-ROM too.
           UPDATE: Guido says this will be fixed in 1.5 to support both
           schemes; the example in the first printing will work as is.
           See the example diffs page for specific changes required.
 
 
15) Type:  Wording
    Where: Page 380, second paragraph from the end, last sentence
    Fix:   Change "Bibliography," to "The bibliography"
  

16) Type:  Typo 
    Where: page 390, table 12-1, line 1
    Fix:   change "Get dbm, gbmd, ..." --> "Get dbm, gdbm, ..."


17) Type:  Tkinter incompatibility in Python 1.4: Variable get/set
    Where: page 394, "formgui.py" example in chapter 12
    Fix:   For all StringVar() objects used, change call styles:
               text()       -->  text.get()
               text(value)  -->  text.set(value)
 
    Notes: The same problem as in calcgui2 (p688), and only an issue when
           running the example under Python release 1.4 (works okay under 
           1.3).  FormGui uses the 1.3 call style more heavily than 
           calcgui2.  To make it work under 1.4, change all the calls 
           to the:
 
           1) "self.keytext" member
           2) "text" variables in methods "display", "onStore", "onNew"
 
           to use the new get/set styles above.  This will be updated
           in the book for the next printing.  Please see the 
           example diffs page for specific changes required, and a patch file.
  

18) Type:  Typo
    Where: page 413, line 13
    Fix:   (Looks like an extra space before the last close-parenthesis.)
 
 
19) Type:  Bad figure reference
    Where: Page 428, first real paragraph
    Fix:   Change "(Example 12-11)" to "(Example 12-12)"
 
 
20) Type:  Production adjustment
    Where: Page 461, before code example near top of page
    Fix:   Seems to be an extra blank line that could be deleted here
 
 
21) Type:  Punctuation
    Where: Page 470, just before example 13-20
    Fix:   Needs a ":" or "." at the end of the paragraph
 
 
22) Type:  Adjustment: code indentation
    Where: Page 481, example 13-25, inside "class BinaryTree"
    Fix:   Align the code on the right (in the 4 "def" lines, after ":")
    Notes: Off by very little, and it's not an error, but looks a bit odd
 
 
23) Type:  Punctuation
    Where: Page 489, first paragraph, just before last sentence
    Fix:   Change "). we'll revisit" to
                  "); we'll revisit"      [needs a ";", not a "."]
 
 
24) Type:  Inaccurate wording
    Where: Page 495, last paragraph on page (starts with "Combinations are")
    Fix:   Change
               ", and order matters here:"
           to
               ", and order does not matter here:"
 
    Notes: Note the "not"; this is implied on the prior page.
 
 
25) Type:  Bogus paragraph label
    Where: Page 528, "References" paragraph label at bottom of page
    Fix:   Change "References" label to "Exceptions"
    Notes: It's repeated again on the next page; the second "References"
           label is correct--the first is the one to be changed
 
 
26) Type:  Bogus code line
    Where: Page 552, last line on the page
    Fix:   Delete the line
               "The test driver."
 
    Notes: A printing glitch.  It's a heading on the next page, not part
           of example 14-3; remove it from example at bottom of page 552.
 
 
27) Type:  Output alignment
    Where: Page 554, labeled program outputs
    Fix:   In output lines that start with a label ("label:"),
           the numbers to the right must be aligned on their
           first digits, not on their decimal point:
 
                 Python module: 17.94
                 C ext module:  7.323
 
    Notes: There's always at least one blank after a label's ":".
           It actually looks better as shown in the book, but that's
           not what the programs being run really print

 
28) Type:  Inaccurate wording (NEW: added 7/31/97)
    Where: page 560, near end of chapter 14, integer type discussion
    Fix:   The book says:

           "In user-defined numeric types, we can pick and choose
            operators to respond to.  If a slot is left as zero, 
            the type doesn't respond to the corresponding operation
            and we'll get an exception at run-time."

           Not 100% true (in Python1.4 and earlier): some operations 
           check for NULL (zero) and raise the exception, but some don't.
           Those that don't can cause a crash at run-time if you leave 
           the slot NULL, so you need to store a pointer to a real C 
           function which raises an exception manually (if desired).  

           This is going back two years now, but I suspect the missing
           NULL tests were something that was supposed to be fixed but
           hasn't been yet (much like the "Great Renaming"--still 
           pending as of 1.4).  For instance, 1.4's "object.h" header
           file implies that only 'dealloc' need be non-NULL (as the 
           book says):

           >> Methods are optional, a
           >> nil pointer meaning that particular kind of access is not
           >> available for this type.  The Py_DECREF() macro uses the
           >> tp_dealloc method without checking for a nil pointer; it
           >> should always be implemented except if the implementation
           >> can guarantee that the reference count will never reach 
           >> zero (e.g., for type objects).

           Guido may add the missing NULL tests later on, but for now, 
           change these sentences to:

           "In user-defined numeric types, we can pick and choose
            operators to respond to, but need to provide a pointer
            to a dummy function for all unimplemented operations
            (Python may or may not test for NULL pointers)."

           UPDATE: the missing NULL pointer tests should be added in 
           Python1.5.  With the fix, you'll be able to use NULL pointers
           instead of dummy functions, for all unimplemented C type ops.
           You'll get an exception instead of a crash, and performance
           impacts should be negligible.  So this section should now say:

           "In user-defined numeric types, we can pick and choose
            operators to respond to.  In Python1.5 (and later), use 
            NULL pointers in unimplemented operation slots: Python will
            raise an exception when they are attempted.  But in Python
            releases 1.4 and earlier, NULL pointers may or may not be
            detected; to be safe, provide pointers to dummy functions 
            for all unimplemented operations instead of NULLs."

 
XX) Type:  API function name changed in 1.5 (NEW, 10/98)
    Where: Page 576
    Fix:   Change "PyArgs_VaParse" to "PyArg_VaParse"  (for 1.5 only)
    Notes: Actually, this function must be called PyArgs_VaParse in 
           Python versions 1.2, 1.3, and 1.4, but was apparently renamed
           to PyArg_VaParse (without the "s") in Python 1.5.  It's only 
           mentioned in the API functions list in the book, and isn't used 
           in any example code, so this is a minor diff.  It's also just
           version skew, not a typo: it really was called PyArgs_VaParse
           up until 1.5.

           The reason for the name change in 1.5 is too complex to
           explain well here.  The short story is that it broke during
           the "Grand Renaming".  It was called "PyArgs_VaParse" in the
           old rename2.h header file in Python 1.2 - 1.4; but as of 1.5
           the function was physically renamed to be PyArg_VaParse in
           getargs.c, despite the older rename2.h name.
 

29) Type:  Wording error
    Where: Page 584, first sentence in sidebar at top of page
    Fix:   Change "__builtin__" to "__builtins__"   (add an "s")
 
 
30) Type:  Technical clarification
    Where: Page 622, last paragraph on page
    Fix:   Change "global variables," to "global variables, mutable objects,"
    Notes: I should have also mentioned changing passed-in objects
 

31) Type:  Printing glitch
    Where: Page 644, near end of interaction at top of page
    Fix:   Change ">>>;" to ">>>"  (delete the ";")
  

32) Type:  Typo
    Where: page 646, line -9, in object.search paragraph
    Fix:   change "Like regex.match" --> "Like regex.search"
  

33) Type:  Typo
    Where: page 648, line -8
    Fix:   change ", For instance" --> ". For instance"
 

34) Type:  Output alignment
    Where: Page 653, program output near bottom of page
    Fix:   The '%' must align (that's what is really output):
               "interactive:   % pygrep1.py
                command line:  % pygrep1.py ..."


35) Type:  Typo
    Where: page 680, line 7
    Fix:   change "top-level program. the" --> "top-level program, the"


36) Type:  Tkinter incompatibility in Python 1.4: Variable get/set
    Where: page 688, "calcgui2.py" example at the end of chapter 16
    Fix:   change all "self.text()"   --> "self.text.get()"
           change all "self.text(X)"  --> "self.text.set(X)"

    Notes: This is only a concern when using Python release 1.4;
           since the book is based on 1.3, and all the binaries 
           on the CD-ROM are Python 1.3, this isn't a bug per-se.
           But starting with release 1.4, we need to call set/get
           explicitly, instead of calling the Variable instance 
           with/without an argument.

           Why?  Guido took out the 1.3 Variable.__call__ method
           that made the two forms above work.  To retain the 1.3
           interface, you can add this method to class Variable
           in Lib/tkinter/Tkinter.py:

           >> class Variable:
           >>     ...
           >>     def __call__(self, value=None):
           >>         if value == None:
           >>             return self.get()
           >>         else:
           >>             self.set(value)

           Of course, this makes your Tkinter non-standard, so
           using get/set is a better solution.  For an overview
           of both forms, see "Linking variables to entry fields"
           in chapter 11 (this section needs to be updated too).
           See the example diffs page for specific changes required.
 

37) Type:  Bad backreference (GuiMixin)
    Where: Page 692, section "Running the new calculator",
           end of last sentence in first paragraph
    Fix:   Change "earlier in this chapter" to "earlier in this book"
 
 
38) Type:  Adjustment: tense
    Where: Page 703, second paragraph from botton, first sentenence
    Fix:   Change "Python geared" to "Python is geared"
    Notes: Just a suggestion; the original was "Python's geared".  It's
           really not an error as is and I can live with it, but the prior
           sentence uses present tense; these should probably match.
 

39) Type:  CD directory reference
    Where: Page 732, CD directory for the Holmes package is wrong
    Fix:   As given, it's the FTP site's dir; on the CD, it is
           really in directory "ftp.python.org/contrib/Misc"
 
 
40) Type:  Wording adjustment (non-error)
    Where: Page 760, "Expressions" section, first list item
    Fix:   Change "egs" to "eggs"
    Notes: Not an error, but embarrassing enough to fix :-)
 

41) Type:  Spelling error
    Where: Page 765, twice--in "Lists" and "Tuples" item lists
    Fix:   Change "repitition" to "repetition"  (in both places)
 

42) Type:  Typo (NEW: added 8/13/97)
    Where: Page 828, near start of paragraph 3
    Fix:   Change "contains and items" to "contains items"
 
 
43) Type:  Program error: missing comma in single-item tuple
    Where: Page 834, examples at end of page, third line up
    Fix:   Change
               "(firstFunction, ('Hello world!'))"
           to
               "(firstFunction, ('Hello world!',))"
 
    Notes: This was correct in a very early draft, but the comma was lost
           in some cut-and-paste along the way.  The need for the comma
           is implied elsewhere in the book (appendix C, chapter 7, etc.)
           This also needs to be fixed on the CD: the bad example code
           was cut-and-paste from the book.  The files where it occurs:
           "/examples/{dos,unix}/examples/other/tutor/func1.py"


44) Type:  Printing glitch
    Where: Page 845, last line in code of "class SecondClass"
    Fix:   The line:
               "x = SecondClass()" 
           should begin in column 1 (just like the following line).
           It's not part of the class definition.
 
    Notes: This may be obvious to most readers, given that this line isn't
           even aligned with the class def properly, and similar lines
           appear in most of the prior examples.  The code for this example
           is correct on the CD too (examples/other/tutor/class1.py), so
           it isn't a problem if you're running the examples.  But in strict
           conformance with Murphy's Law, this glitch wasn't discovered until
           3 days after the second printing was run off; unless someone else
           caught it, it may not be fixed until the third printing.
 
 
45) Type:  Bogus output line
    Where: Page 847, interpreter interaction just before last paragraph
    Fix:   A superfluous line snuck into the output--'legs':
  
                                 >>> x = Hacker('Data')
           [delete this line]->  'legs'
                                 >>> print x.stance, x.name, x.legs
 
    Notes: Introduced during production: seems to have been repeated
           from the end of the line-comment on the preceding line.  The
           code line "x = Hacker('Data')" doesn't produce any output.
 
 
46) Type:  Bad string constant (NEW: added 8/13/97)
    Where: Page 852, String missing quotes, in printings 1 and 2
    Fix:   Change:
               file = open('data', r) 
           to:
               file = open('data', 'r')
 
 
47) Type:  Bad backquote
    Where: Page 868, Index, entry for "backquote"
    Fix:   Needs a real backquote in the parenthesis: (`), not (")
 
 
48) Type:  Index addition
    Where: Index
    Fix:   Add "__call__" to the index.  It's mentioned in
           appendix A, in particular.
 

49) Type:  Index entry
    Where: Index, "S" list
    Fix:   "__getitem__" appears under "S"  (should be "__setitem__")

 
50) Type:  Index addition
    Where: Index, "getattr" entry
    Fix:   "getattr" should list a reference to chapter 10 appearance

 
51) Type:  Index additions (NEW: added 8/13/97)
    Where: Index, need expansion in general
    Fix:   add entries for "==", "is"
 
 
52) Type:  CD file permissions, name case conflicts
    Where: CD ROM
    Fix:   Some of the README files apparently had root-level
           access protections.  This doesn't matter if the CD is
           read on PCs, but some UNIX users may not be able to
           access the files.  Please see O'Reilly's FTP site, 
           at ftp.ora.com/pub/examples/nutshell/python for a 
           description and a fix.  

           There was also an issue with some HTML files having 
           the same name but different case (which means you can't
           see both of the files on some platforms).  This only
           occurs in the www.python.org/doc directory.  Again, see
           the FTP site above for more details.

 
53) Type:  CD addition: windows usage note
    Where: CD: "/readme" file
    Fix:   I'd like to add a note telling MS-Windows users to try the
           PythonWin package in "/pc", not the (older) version in the
           "/ftp.python.org" directory.  The older one has known install
           problems not present in the "/pc" version.  The NT executable
           in "/special.bin" can also be used on PC's to run Tkinter GUI
           programs under Windows.  (Also see the updates and additions 
           section at the bottom of this page).
 
 
54) Type:  CD additions: updated versions
    Where: CD
    Fix:   There are newer releases of many of the CD's packages, which
           would be nice to include with the next printing.  Python-1.4
           source code is now officially released, for example, along 
           with new versions of SWIG, PythonWin, etc.  All new versions
           can be had by ftp, but it would be good to update the CD too.
 
 
55) Type:  Extend filename for UNIX examples
    Where: CD, /examples/unix/examples/dstruct/basic/faststac.py
    Fix:   This file should be renamed "faststack.py"--no point in
           making UNIX users conform to DOS filename limits.  Some
           examples won't work unless this file is renamed (they
           import a module called "faststack", not "faststac").
 
 

Recent Additions (to be organized)

Items added on 2/99; they need to be added to the main list above when I have time, but I wanted to post them asap:



A)  NEW -- rand module replaced with random in 1.5.2

    Page 690, 691 (ch16)

    Replace the statement from rand import * in the example
    code on page 690 with from random import *.  You'll get an
    import error if you don't, because "rand" no longer exists.
    As of Python 1.5.2, the "rand" module is now officially 
    deprecated, and has been replaced by the "random" module.
    Page 691 mentions "rand", and should now mention "random".


B)  NEW -- anydbm.open requires a 'c' second argument in 1.5.2

    Pages: 39, 41 (twice), 390?, 411, 412, 422, 

    As of Python version 1.5.2, the anydbm.open function requires 
    you to pass a 'c' as a secod argument, to get the behavior shown
    in the book--that is, you must use anydbm.open('file', 'c'), 
    rather than the anydbm.open('file') form in the book.
    The 'c' flag tells anydbm to create the file if and only 
    if it doesn't yet exist, and open it in read/write mode.

    This is a non-backward-compatible change that impacts a 
    few anydbm examples in chapters 2 and 12.  Specifically, on
    all the pages listed above, change all anydbm.open('xxx')
    calls to be anydbm.open('xxx', 'c').

    Discussion: It looks like this change happened sometime
    between versions 1.4 and 1.5.2.  In 1.5.2 you need to use a 'c'
    as the second argument to the anydbm.open function.  As long
    as you do, it works the same as in versions 1.4. and 
    earlier.  You can use more specific second arguments too
    (e.g., 'r' for input only (the default), 'w' for output only)
    but 'c' now does what passing no second argument used to do.

    I'm not sure why anydbm was changed in an incompatible
    way like this, but suspect it has something to do with
    the bsd interface on Windows, which requires the argument
    anyhow (requiring it always makes code more portable).   

    Note that this change does not impact the shelve 
    interface at all; shelve.open still works as advertised with 
    just one argument, the external file name.  (shelve.open passes
    the 'c' flag to anydbm.open internally.)  Shelves are used in 
    the book much more than raw dbm files, so this isn't as big an 
    issue as it might have been.


C)  NEW -- Pythons and geography

    Pages: colophon description, backmatter

    And last but not least, I'd like to underscore a seemingly
    critical zoological paradox in the book, pointed out recently
    on comp.lang.python by a reader:

    Andrew Dalke wrote in message 36C30D37.A49915E5@bioreason.com...
    : I'm wearing my O'Reilly Python shirt today.  Someone asked me
    : where Pythons are from.  I pulled out Lutz's book and read:
    :
    : "The animal featured on the cover ... is a South American rock
    : python, one of approximately 18 species of python.  Pythons ...
    : live in tropical regions of Africa, Asia, Australia and some
    : Pacific islands."
    :
    : I was then asked "so the South American rock python doesn't
    : live in South America?"
    :
    : Looks like another bit of errata to add to
    :   http://shell.rmi.net/~lutz/errata-book-fixes.html
    :
    :   :)

    :)

    Update: Per the suggestion of another reader who really knows 
    something of snakes, O'Reilly plans to change this as follows:
    Change:
      The animal featured on the cover of Programming Python is a South
      American rock python, one of approximately 18 species of python.
    To:
      The animal featured on the cover of Programming Python is an
      African rock python, one of approximately 18 species of python.
                                                                   


Back to the errata page
Back to my homepage



[Home page] Books Code Blog Python Author Train Find ©M.Lutz