Learning Python

Errata for Learning Python

Submit your own errata for this product.


The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".

The following errata were submitted by our customers and approved as valid errors by the author or editor.

Color Key: Serious Technical Mistake Minor Technical Mistake Language or formatting error Typo Question Note Update



Version Location Description Submitted By Date Submitted Date Corrected
Printed, PDF, ePub, Mobi, Safari Books Online, Other Digital Version
Page N/A
N/A

[Informational only: no changes required.] A new first beta version of PyPy with support for Python 3.2.3 was announced on August 1, 2013. If successful, PyPy will no longer be a Python 2.X-only system. This edition discusses the PyPy optimized Python implementation repeatedly -- in the Preface, in Chapter 2's implementations overview, and in Chapter 21's benchmarking study. When this material was written, PyPy was accurately described as 2.X-only, with caveats about possible future evolution; half a year later, PyPy has acquired both ARM and Python 3.X support. See pypy.org for up-to-date details.

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Aug 02, 2013 
Printed, PDF, ePub, Mobi, Safari Books Online
Page N/A
N/A

[Supplemental resources] At the following pages I've started collecting reader FAQs and Python change notes which are too large to post on this errata list, and do not require changes in book reprints: --Reader FAQs: http://www.rmi.net/~lutz/book-faqs-lp5e.html --Python changes: http://www.rmi.net/~lutz/python-changes-2014-plus.html Per the Preface, you'll find these and other links at the book's support page at http://www.rmi.net/~lutz/about-lp5e.html.

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Oct 08, 2013 
Printed
Page xlvi
Fetching... section

The website for fetching code is listed incorrectly as http://oreil.ly/LearningPython That url is also given on page xlvii as the publisher's site. It didn't take long to find the correct url and took me to some strange places. Great book, I'm enjoying and learning a lot so far. And I like the detail and forward references. Roberto

Note from the Author or Editor:
Did you miss the "-5E" at the end of the URL? It appears as the following correct/working URL in both the paper version and ebooks (PDF, Mobi, and Epub versions are all correct as far as I can tell): http://oreil.ly/LearningPython-5E If there is another format/viewer where the URL is not appearing correctly, please repost this issue with more details.

Roberto Riley  Nov 18, 2013 
Printed, PDF
Page 36
2nd paragraph

"[...] and is able to created type-specific machine code [...]" should rather read "create".

Note from the Author or Editor:
Yes -- a valid minor typo. Please fix in reprints as suggested.

Julian R.  Jan 25, 2014  May 02, 2014
Printed, PDF, ePub, Mobi, Safari Books Online
Page 47
Last paragraph

The line "(e.g., cd c\: and mkdir code)" should read "(e.g., cd c:\ and mkdir code)." Specifically, the c\: is wrong.

Note from the Author or Editor:
Yes -- minor, but a true typo. Please patch in the next reprint as suggesed.

Anonymous  Nov 22, 2013  Jan 24, 2014
Printed, PDF, ePub, Mobi, Safari Books Online
Page 58
4th parageaph

"In Python, using a variable before it has been assigned a value is always an error— otherwise, if names were filled in with defaults, some errors might go undetected. This means you must initial counters to zero before you can add to them, must initial lists" In the last line above, the transitive verb use of the word "initial" means to mark with your initials. The word used should be "initialize", the definition of which is referred to in the first line above.

Note from the Author or Editor:
[This is actually on Page 51 in print and PDF, not 58] Yes -- a typo. Change: "This means you must initial counters to zero before you can add to them, must initial lists before extending them, ..." to this, changing the two "initial" to "initialize": "This means you must initialize counters to zero before you can add to them, must initialize lists before extending them, ..." [Discussion only follows] This typo isn't serious given that the terms aren't formal here, and the intent is spelled out fairly clearly in the remainder of this sentence -- "; you don’t declare variables, but they must be assigned before you can fetch their values". Still, "initialize" is the better term. In fact, "initialize" does appear correctly 60 times in the book, and the term "must initialize" itself is used properly in 3 other places (page 176, 349, and 516). Given that, and the fact that a similar typo appears in the 3rd but not 4th edition, a Word auto-correct seems a prime suspect here.

eatyourhat  Sep 30, 2013  Nov 08, 2013
Printed, PDF, ePub, Mobi, Safari Books Online, Other Digital Version
Page 75
second paragraph of section "IDLE Basic Usage"

IDLE Basic Usage Let’s jump into an example. Figure 3-3 shows the scene after you start IDLE on Win- dows. The Python shell window that opens initially is the main window, which runs an interactive session (notice the >>> prompt). This works like all interactive sessions —code you type here is run immediately after you type it—and serves as a testing and experimenting tool. IDLE uses familiar menus with keyboard shortcuts for most of its operations. To make a new script file under IDLE, use File→New: in the main shell window, select the File In the last line above, the command in Python 2.7.4 is File-New Window Note: Helping improve the book is the least I can do for free use of one so good. Thanks!

Note from the Author or Editor:
Yes -- for full accuracy, this should probably use "New Window", not just "New". This is true of IDLE in both Python 3.X and 2.X today, at least in 3.3.2 and 2.7.5. However, it turns out that this menu label will be changed to instead say "New File" in Python 3.3.3 and 2.7.6. This is despite common GUI practice; any existing IDLE documentation; and the fact that it's really just a new text _editor_ window, and not associated with any _file_ at all unless and until you open or save the window's text. Better, perhaps, but this still seems to have just as much potential to confuse newcomers! [THE BOOK CHANGE] This report's type was changed to typo, because most readers will likely get the point anyhow; "New" is the full option name's prefix in all Pythons, and common usage in GUIs. But to clarify, let's change sentence 2 of paragraph 2 in this section from this (which may show up here with an embedded arrow symbol given as an "&" escape): """ To make a new script file under IDLE, use File→New: in the main shell window, select the File pull-down menu, and pick New to open a new text edit window where you can type, save, and run your file’s code. """ To this, replacing the two "New" as shown (retaining existing italics on the first 6 words, and adding a "that is," for clarity, since this page has the space): """ To make a new script file under IDLE, use File→New Window: that is, in the main shell window, select the File pull-down menu, and pick New Window (New File as of 3.3.3 and 2.7.6) to open a new text edit window where you can type, save, and run your file’s code. """ [MORE DISCUSSION] This section was revamped substantially in the 5th edition, and in the process the menu option name was abbreviated in this paragraph only (on the assumption that the standard menu name prefix would suffice, and be more immune to change like that in 3.3.3). The full "New Window" is still given correctly in the caption to Figure 3-3, a holdover from prior editions whose coverage of IDLE basics was also a bit less useful. This is a minor detail, of course, but important to get right at this early stage of the text.

eatyourhat  Oct 02, 2013  Nov 08, 2013
Printed, PDF, ePub, Mobi, Safari Books Online
Page 102
code comments

# B[i] = ord(c) works here too ord(c) should be ord('c')

Note from the Author or Editor:
CHANGE this comment's text (in line 10 of listing 1) from: ... # B[i] = ord(c) works here too to this, (replacing just "c" with "x"): ... # B[i] = ord(x) works here too DISCUSSION: This isn't an errata, and I nearly dismissed it altgether, but opted to retain it with a minor tweak and note, and reclassify as a clarification. I understand how this may seem confusing, if compared to the "L[1] = ord('c')" given for a list above this. However, this is comment, not concrete code, and was meant as abtract only -- it means for some integer "i" and some character "c", "B[i] = ord(c)" works. Either this should be fully concrete (using 1 and 'c') or fully abstract (using i and c, as given); both would be valid, but changing just the right part to be concrete isn't enough. On the other hand, the "c" is the point of confusion, so we'll change this to use a dfferent variable name to make the abstractness more obvious, and render this moot.

Anonymous  Apr 28, 2014 
Printed, PDF, ePub, Mobi, Safari Books Online
Page 105
last line of 1st code listing section on page

Reported by a sharp-eyed reader's email: the first character in this output line should be uppercase "A", not "a" (a minor typo missed by many, but potentially confusing nonetheless). Change: >>> S # ... 'a\x00B\x00C' to: >>> S # ... 'A\x00B\x00C' retaining the "# ..." comment's text and its indentation verbatim.

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Apr 05, 2014  May 02, 2014
Printed, Mobi
Page 108
P4, s3: The following pattern, for example, . .

The narrative describes the example following it incompletely. In the sentence beginning "The following pattern, for example, . . . " change "separated by slashes, and is similar" adding "or colons" thus: "separated by slashes or colons, and is similar"

Note from the Author or Editor:
Yes -- change as described. This seems minor, given that the re module isn't covered by this book (as it states), and the example's full behavior is implied by the listing immediately following this sentence; but it's worth tightening up the description this way. This reflects an expansion of this example in this edition: the alternatives syntax and re.split equivalent were added for color, but the narrative wasn't updated for the former.

Christopher Karl Johansen  Jul 18, 2013  Aug 16, 2013
Printed, PDF, ePub, Mobi, Safari Books Online, Other Digital Version
Page 144
line 7 of first code listing on page

Minor formatting fix: the second line of the following on this page should not be in italics font; it should be straight, non-bold, and fixed-width like all other output text: >>> '%e' % num # String formatting expression '3.333333e-01'

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Jul 11, 2013  Aug 16, 2013
Printed, PDF, ePub, Mobi, Safari Books Online
Page 192
3rd line of text, below table

Minor, but the wrong chapter is referenced in one place here (it's given correctly as 37 elsewhere, often, and nearby). CHANGE: "module, introduced in Chapter 4 and Chapter 36," to this, replacing 36 with 37 and adjusting the link: "module, introduced in Chapter 4 and Chapter 37," (Also note that, as stated in the book, the "re" module shows up in brief examples in Chapters 4 and 37, but is not covered by this book in any sort of useable depth -- on purpose. Instead, Programming Python has an entire dedicated chapter on text processing that delves into pattern matching in a much more useful fashion, and Python Pocket Reference gives complete reference details for "re".)

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Apr 28, 2014 
Printed, PDF, ePub, Mobi, Safari Books Online
Page 223
"Adding Keys, Attributes, and Offsets" section

The book says: '[...] The first of the following examples indexes a dictionary on the key "spam" and then fetches....' I think it should be: ''[...] The first of the following examples indexes a dictionary on the key "KIND" and then fetches...." because according to the example: >>> 'My {1[kind]} runs {0.platform}'.format(sys, {'kind': 'laptop'})

Note from the Author or Editor:
Yes, a valid typo. Please replace "spam" with "kind" (lowercase) in the sentence described. This is in line 5 of the last paragraph on page 223. Inherited from the book's prior edition, where the code actually did use the less mnemonic key "spam", but was edited for space.

Antonio Cota  Jul 15, 2014 
, Printed, PDF, ePub, Mobi, Safari Books Online, Other Digital Version
Page 247
first paragraph of note box at end of page

Minor nit, but it would be useful to add a back-reference to where this topic was first noted. In line 2 of this note, just before the emdash designated with a double dash here, change: "and a list) work--the" to: "and a list) work as first noted in Chapter 5--the".

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Jul 11, 2013  Aug 16, 2013
Printed, PDF, ePub, Mobi, Safari Books Online
Page 253
bottom paragraph

The text (penultimate line) says "Technically, this ['in' for dictionaries] works because dictionaries define iterators that step through their keys lists automatically." I was very surprised by this assertion and seriously doubted that it is true: because dictionaries are implemented as hashes, the operation of deciding whether or not a key is in the dictionary will be very fast by using the hashing algorithm, and should not be done via creating a list/iterable of the keys and linearly searching through it. And checking the Python 3.4 source code, I find that this is indeed the way it is implemented - the 'in' operation for dictionaries is special-cased in exactly this way. See Objects/dictobject.c, around line 2615: /* Hack to implement "key in dict" */ static PySequenceMethods dict_as_sequence = { 0, /* sq_length */ 0, /* sq_concat */ 0, /* sq_repeat */ 0, /* sq_item */ 0, /* sq_slice */ 0, /* sq_ass_item */ 0, /* sq_ass_slice */ PyDict_Contains, /* sq_contains */ 0, /* sq_inplace_concat */ 0, /* sq_inplace_repeat */ }; and PyDict_Contains just checks whether the key hash is found in the dictionary without attempting to list all the keys. A better replacement for this sentence would therefore be: "Although the 'in' membership test for iterables works by iterating through the iterms, dictionaries are treated as a special case because their keys can be looked up very quickly." Or maybe: "The 'in' membership test for dictionary keys is implemented using the fast key lookup algorithm, so it is very efficient." Or something like that.

Note from the Author or Editor:
This may be splitting hairs a bit (as explained below), but to avoid future confusion, let's change this sentence from: "Technically, this works because dictionaries define iterators that step through their keys lists automatically." to this: "Technically, this works because dictionaries define keys iterators, and use fast direct lookups whenever possible." [Discussion only follows] I'm marking this as clarification, not errata. Your analysis is technically correct (and kudos on both your exploration and explanation), but the sentence in question was not meant to be rigorous, and was not intended to imply a specific implementation mechanism. Instead, this is a generic and intentionally simplistic statement at an early point in the book when most readers are probably not ready to grapple with subtle shades of difference between general __iter__ and specialized __contains__ methods. Dictionaries' internal implementation by hash tables is stated elsewhere in this book (see Page 251's paragraph on the subject), and the __contains__ (i.e., "in" operator) customization for dictionaries is mentioned both in a footnote on Page 482, and in the full section on the subject on Pages 906-909. The text straddling Pages 906/907 especially seems to call this out, once OOP has become fair game in the book: """ In the iterations domain, classes can implement the in membership operator as an iteration, using either the __iter__ or __getitem__ methods. To support more specific membership, though, classes may code a __contains__ method — when present, this method is preferred over __iter__, which is preferred over __getitem__. The __contains__ method should define membership as applying to keys for a mapping (and can use quick lookups), and as a search for sequences. """ The C code you referenced is the internal equivalent of these class methods. That said, a minor edit here may help disambiguate. I'd also note that discovering this by exploring Python's implementation itself is a great way to clarify such things in open source projects.

Julian Gilbey  Jun 07, 2014 
Printed, PDF, ePub, Mobi, Safari Books Online
Page 261
Very end of last paragraph on this page

In response to a post in a reader forum, I'm going to add some parenthetical text for clarity. Change the end of this paragraph from: "plays the role of top-level container in realistic programs:" to: "plays the role of top-level container in realistic programs (the following snippets both print Bob's 2-item job list if run live and provided with another record structure):" For the rationale behind this, see the original post and reply at my reader FAQ page, http://www.rmi.net/~lutz/book-faqs-lp5e.html#q3.

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Oct 22, 2013  Nov 08, 2013
Printed, PDF, ePub, Mobi, Safari Books Online, Other Digital Version
Page 287
Last sentence of Windows note

"second" should be "first". (The first of the three command examples uses a raw string.)

Note from the Author or Editor:
Yes--a valid typo, in a new note box about Windows fie paths added in this edition. As suggested, change: "The raw string form in the second command..." to: "The raw string form in the first command..."

Christopher Karl Johansen  Aug 27, 2013  Nov 08, 2013
Printed, PDF, ePub, Mobi, Safari Books Online
Page 333
End of first output listing

Add a new line to the end of the first output listing on this page that appears just before heading "Handling Errors with try Statements". This new final line should contain a single word, "Bye", non-bold and without quotes. The last 3 lines in this listing will be this (with only "stop" bold, and similar to other output listings nearby): 100 Enter text:stop Bye [Discussion] This was reported by a reader by direct email; my reply with description follows: I appreciate your report on this. You are correct, of course: the code listing on page 332 has a final "Bye" print statement, whose output does not appear in the output listing following it on page 333. I'll add an errata note to patch this in reprints. This isn't critical, as the "Bye" does appear in the first such example in this section on page 331-332, and again in some later variations' output listings on pages 335 and 336. It could be argued that it's not necessary to show the complete output at each such variation, especially after the first establishes the pattern. But I agree that it would be better to be consistent about this throughout the section. For the record, the "Bye" output line was also missing in the 4th Edition for this same mid-section example, but went unreported; this might underscore its relatively low priority. > -----Original Message----- > im wondering about something in your book > first of all see the "first" photo attached > the last statement {print('Bye')} thats means when the while loop ends its must print 'Bye' > But on the other hand .. check the 'second' photo attached > at the end when the user typed stop the loop ends and 'bye' was missed > now am i right ?! > these at (Chapter 10: Introducing Python Statements) > page 322 > thanks!

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Jul 20, 2014 
Printed, PDF, ePub, Mobi, Safari Books Online, Other Digital Version
Page 341
7th line on page

This was filed by a reader as an errata against the 4th edition, but I'm reposting it here against the 5th, which inherits the same text. The patch: on Page 341, in line 7, change: "...rest: a is assigned 's', and b is assigned 'pam'." to: "...rest: a is assigned 's', and b is assigned ['p', 'a', 'm']." The issue: per the reader's report, the text states the former, but the latter is more accurate, While true, this is an introductory description only and is deliberately informal; moreover, the actual and formal output of this code is shown explicitly by example later in this section. To avoid confusion, though, let's make the patch as described. For non-PDF e-book readers, this is in "Assignment Statement Forms" in Chapter 11, in list item "Extended sequence unpacking."

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Jun 30, 2013  Aug 16, 2013
Printed, PDF, ePub, Mobi, Safari Books Online
Page 363
End of paragraph 3 under

Not an error, but for clarity, expand this sentence: """ In fact, if you enjoy working harder than you must, you can also code print operations this way: """ To the following, adding only the parenthesized text just before the colon, with links to the two referenced chapters -- and please let me know if this changes page breaks; I'm hoping to avoid that: """ In fact, if you enjoy working harder than you must, you can also code print operations this way (per Chapters 4 and 9, a 3.X-only return value is omitted here): """ [Discussion only follows] A reader wrote by email: > > This is on page 357 of the Ebook; page numbering doesn't seem > to match the print edition. Looking at the last example before the > "Manual stream redirection" subheading in chapter 11: > > >>> import sys > >>> sys.stdout.write('hello world\n') > hello world > > The system call of course returns a result, and when run > interactively the result is also printed. As such, when running this > example under Linux an additional line is added: > > >>> import sys > >>> sys.stdout.write('hello world\n') > hello world > 12 > > where the "hello world" is the text written and the "12" is the result > of the sys.stdout.write() call. I couldn't find any mention of this on > your or O'Reilly's errata pages. The omission could be deliberate, > but some people would find the extra line confusing. I would > expect the Windows version would add a similar line. There is > also no mention of this in the following text (i.e. that print always > returns None where write() returns the number of characters > written). Sure, but this isn't platform specific, and is probably not an issue for most readers. The return value of the file's write method is well documented in general file coverage earlier in the book -- starting on Page 122, and spanning Chapters 4 and 9, including the blanket note on Page 288 that reads this way: "... (for space, I'm omitting byte-count return values from write methods from here on):". Still, this seems a potential point of confusion, especially for non-linear readers using 3.X. To clarify, I'm suggesting the addition of another parenthetical note about the deliberate omission of the return value in this section, as described above. Such reminders risk becoming overly redundant, but this one seems justified.

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Oct 07, 2013  Nov 08, 2013
PDF, ePub, Mobi, Safari Books Online
Page 428
3rd text block

"[...] and the second strips whitespace on both ends to omit blank links [...]" should probably rather read "[...] to omit blank lines [...]".

Note from the Author or Editor:
Yes -- change just the italicized word "links" to "lines" in this text. That is, it should read: "..., and the second strips whitespace on both ends to omit blank lines in the tally..." Minor typo, but the italics probably helped this one get past proofing.

Julian R.  Feb 20, 2014  May 02, 2014
Printed, PDF, ePub, Mobi, Safari Books Online
Page 428
2nd code block

"[line.rstrip() for line in open('script2.py') if line.rstrip()[-1].isdigit()]" The code raises an IndexError in Python 3.3.2 and 2.7.5.

Note from the Author or Editor:
[Not an errata, but retained as a clarification, with a minor supplemental insert] CHANGE the last line of paragraph 2 on page 428 from: "expression on the right side:" to this, where [-1] and [-1:] are literal/fixed font: "expression on the right side (replace [-1] with [-1:] for files with blank lines):" DISCUSSION: This code works correctly and as shown when run on the 4-line test file whose content is given at the start of this section and implied by all the other examples here. See the first example on page 426: >>> f = open('script2.py') >>> lines = f.readlines() >>> lines ['import sys\n', 'print(sys.path)\n', 'x = 2\n', 'print(x ** 32)\n'] If you use this same 4-line test file, the example in question works properly: C:\code> type script2.py import sys print(sys.path) x = 2 print(x ** 32) C:\code> py -3 >>> [line.rstrip() for line in open('script2.py') if line.rstrip()[-1].isdigit()] ['x = 2'] That said, running this code on a file whose content is different than that shown in the book may indeed raise the exception, if the file used includes a blank line. This can occur because [-1] on an empty string triggers IndexError. Although this is a different context than that used in the book, the code could be easily generalized to allow for empty lines too, by slicing instead of indexing, like this: >>> [line.rstrip() for line in open('script2.py') if line.rstrip()[-1:].isdigit()] ['x = 2'] This works more robustly, because, as explained in the book, slicing a string always returns a string, and slices scale themselves to be inbounds but indexing does not: >>> 'abc1'[-1], 'abc1'[-1:] ('1', '1') >>> ''[-1] IndexError: string index out of range >>> ''[-1:] '' For background on such things, see the book's types part and exercises.

Anonymous  Apr 11, 2014  May 02, 2014
Printed, PDF, ePub, Mobi, Safari Books Online
Page 431
Second paragraph

The first sentence begins: "We first saw the sorted function used here at work in, and ..." - there's clearly a reference missing before the comma. (Just commenting because I'm finding the book excellent, and am happy to help improve it.)

Note from the Author or Editor:
Yes -- we lost a link in this sentence. It should say this (add just the "Chapter 4" text/link): "We first saw the sorted function used here at work in Chapter 4, and we used it for dictionaries in Chapter 8." (Origin note: this is a minor issue, but it appears to have been broken during production. The "Chapter 4" appeared in both my final draft and the copyedit versions, but disappeared as of QC1.)

Julian Gilbey  Jun 07, 2014 
Printed, PDF, ePub, Mobi, Safari Books Online, Other Digital Version
Page 490
1st paragraph

"dictionary compressions". And in page 1109, "Unlike compression loop variables", I think they should be "comprehension".

Note from the Author or Editor:
Yes--change both of these: the 1st to "comprehensions" and the 2nd to "comprehension". The 1st occurrence is on Page 490, text line 6; the 2nd is Page 1109, paragraph 2, line 1. Probably the result of the auto-correct-as-you-type feature in Word, and implied by surrounding text and context, but worth the patch.

Yang Lifu  Aug 15, 2013  Nov 08, 2013
Printed, PDF, ePub, Mobi, Safari Books Online, Other Digital Version
Page 518
Paragraph 1, line 2 (in sidebar)

Minor typo--delete extraneous "it", with this change: "...nested def, after it saving the original..." => "...nested def, after saving the original..." For e-book readers this is in sidebar "Why You Will Care: Customizing open" in Chapter 17.

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Jun 30, 2013  Aug 16, 2013
Printed, PDF, ePub, Mobi, Safari Books Online
Page 518
Code samples: definitions of makeopen (twice)

In both of the code samples, the positional arguments are defined and called as *kargs, while the keyword arguments are defined and called as **pargs. The choice of variable names is suggestive but the wrong way round for their respective meanings. I would suggest swapping the names and instead using *pargs and **kargs.

Note from the Author or Editor:
Yes: a minor typo and a bit tricky to adjust, but worth a patch. In the 1st code listing on this page, change this way, swapping "kargs" and "pargs" in all 3 of these lines (only), taking care to keep all else the same, including the "*" and "**" characters: def custom(*pargs, **kargs): print('Custom open call %r:' % id , pargs, kargs) return original(*pargs, **kargs) In the last code listing on this page, do likewise: def __call__(self, *pargs, **kargs): print('Custom open call %r:' % self.id, pargs, kargs) return self.original(*pargs, **kargs) This code works correctly as is and as shown, and the argument names are not the main point of this sidebar and its code -- nestable customization of a built-in with closures and classes. But I agree that the two variable names are potentially a bit misleading, as "pargs" and "kargs" are used some 92 and 140 times elsewhere in the book, respectively, for positional and keyword arguments. Their swapped roles on this page most likely reflect a harried last-minute edit, followed by an unfortunate cut-and-paste.

Julian Gilbey  Jun 15, 2014 
Printed, PDF, ePub, Mobi, Safari Books Online
Page 524
Paragraph 2 in section "Arguments and Shared References"

[No change required: cross-posting a reply to a 4th Ed page 438 report, as the text in question is also on page 524 of the 5th Ed.] A reader posted: > Page: 438 > Location: 7th paragraph in page > Description: > "In this example the variable a is assigned with the object 88 at the > moment the function is called with f(b), but a lives only within the > called function." > > this should read... > "In this example the variable a is assigned with the object 99 at the > moment the function is called with f(a), but a lives only within the > called function." > > changes: > object 88 --> object 99 > f(b) --> f(a) No, this wording is correct as is. The suggested change misses the whole point of this section, but seems a confusion common enough to warrant a clarification here. This section describes the assignment of object 88 -- the value referenced by global variable b -- to variable a, which is a local variable within function f. This assignment occurs automatically when the function f is initially called. That is, a is assigned 88 at the moment of function call, by virtue of the argument passing mechanism, as stated in the book. Names a and b share the same object at this point. The later assignment of name a to object 99 -- via the code a=99 within f -- simply resets local name a to a different object, and hence does not impact name b outside the function. That's the whole point of this example: the names a and b are not linked in any way. That said, this text is describing a mechanism that has been historically confusing to some Python newcomers. When studying code like this, remember to keep the fundamental distinction of names and objects clear, and don't let prior language exposure cloud your judgement; Python is everywhere about names, objects, and references.

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Oct 02, 2013 
Printed, PDF, ePub, Mobi, Safari Books Online
Page 581
3rd paragraph

The text reads: "In fact, Python has a host of tools that most would considered functional in nature," It should read: "In fact, Python has a host of tools that most would consider functional in nature,"

Note from the Author or Editor:
Yes -- a minor but valid typo (that eluded many proofs); please fix as described.

Anonymous  Feb 03, 2014  May 02, 2014
Printed, PDF, ePub, Mobi, Safari Books Online
Page 591
Line 1 of last paragraph on page

Change: "(generator expressions were available as an option as early as Python 2.2)" To this, replacing just word #2: "(generator functions were available as an option as early as Python 2.2)" That is, generator _functions_ were available in 2.2, not generator _expressions_, which came online in 2.4 -- facts stated explicitly in the bullet list just above this text on the same page. A minor typo officially blamed on being distracted by writing a 1600 page book...

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Jan 12, 2014  Jan 24, 2014
Printed, PDF, ePub, Mobi, Safari Books Online
Page 594
first sentence, add new footnote

There's a minor extension in 3.3 regarding return statements in generator functions that was omitted in the book due to its obscurity, but has potential to confuse if it shows up in code over time. If we can squeeze it in without impacting page breaks badly, I'd like to add a clarifying footnote. THE CHANGE: On Page 594, add a footnote reference to the very end of the first sentence: """ To end the generation of values, functions either use a return statement with no value or simply allow control to fall off the end of the function body.* """ with this footnote text at page bottom (its "StopIteration" is literal font, and it looks like the next 2 pages have room to absorb the insert; let me know if shortening is needed to avoid changing page breaks for the rest of the chapter): """ * Technically, Python treats return statement values in generator functions as syntax errors in 2.X, and in all 3.X prior to 3.3. As of 3.3, a return statement value is allowed and attached to the StopIteration object, but the value is ignored in automatic iterations contexts, and using this makes code incompatible with all prior releases. """

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Nov 08, 2013  Jan 24, 2014
Other Digital Version
612
last line on my kindle

def permute2: I think there should be a set of brackets around seq [I:i+1] + x so that it reads yield(seq[I:i+1] + x) not sure why but I can't get it to work otherwise

Note from the Author or Editor:
[Informational only: not an errata, no change required.] This example's code (list-builder and generator-based recursive permutations) works as shown in every Python I've tested, from 3.3 down to 2.3; prior to 2.3, yield wasn't available by default: >>> import sys; sys.version '3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:57:17) ...' >>> from permute import * >>> permute1('abcd') == list(permute2('abcd')) True >>> len(list(permute2('abcd'))), 4*3*2*1 (24, 24) >>> import sys; sys.version '2.3 (#46, Jul 29 2003, 18:54:32) ...' >>> ..identical behavior... Yield morphed from statement to expression in 2.5 to support sends (and sometimes must be enclosed in parenthesis in this role), but it never was required to use function call-like parenthesis. I can't tell what the issue may be, but make sure you're running the exact code in the book (or its examples zip file); the post has mixed case for variable "i" which would fail, but this may be just in the post. For more yield background: see Pages 137-138 (expressions), 320-321 (statements), 353-354 (reserved words), and most of Chapter 20 (generators).

Stephen Gregory  Aug 07, 2013 
Printed, PDF, ePub, Mobi, Safari Books Online
Page 621
1st paragraph

The text reads: "..raised by the next(it) inside the comprehension..." It should read: "..raised by the next(i) inside the comprehension..."

Note from the Author or Editor:
Yes--this reference is abstract, but it should be "i" to match the preceding code. Please change as described. Note that this is In line 2 of page 622 (not 621) in all the books and pdfs, including the latest Jan 2014 4th printing.

Anonymous  Feb 04, 2014  May 02, 2014
Printed, PDF, ePub, Mobi, Safari Books Online
Page 624
3rd or last paragraph

The text reads: "Here are statement-based equivalents of the last two comprehensions (though they differ in that name localization):" Maybe its just me, but the parenthetical note is either is either cut-off short, as in "though they differ in that name-localization thing we just talked about", or maybe it should just be rendered as "though they differ in name localization"

Note from the Author or Editor:
Yes--a minor typo as is ("that" was supposed to be "their"). But for more clarity, let's change the parenthesized part to read: "(though they differ in their name localization, per the prior section):"

Anonymous  Feb 04, 2014  May 02, 2014
Printed, PDF, ePub, Mobi, Safari Books Online
Page 735
Page 735 (para -1, line 2/3), and 736 (para 5, line 2)

Page 735 calls sys.path the module search path. That's true generally and acceptable informally, but the search path is really only sys.path at the top (left) in absolute imports; in other cases, it may be limited to a package's location, whether that is a regular package's sole directory or a namespace package's __path__. This should be apparent given the preceding description of package and relative imports and later discussion of __path__ and sys.path's leftmost role, but this terminology may be a bit too loose here, especially following the sections on packages and preceding a formal import algorithm sketch for namespaces. THE CHANGES: 1) To clarify, in Page 735's paragraph -1 line 2, change this sentence: " During imports, Python still iterates over each directory in the module search path, sys.path, just as in 3.2 and earlier. " to this, expanding the "sys.path" in the middle, retaining the literal font on "sys.path", and using a normal dash for both of the "--": " During imports, Python still iterates over each directory in the module search path--defined by sys.path for the leftmost components of absolute imports, and by a package’s location for relative imports and components nested in package paths--just as in 3.2 and earlier. " 2) Also, in Page 736's paragraph 5 line 2, change: " located via multiple sys.path entries. " to this (with no fixed-width font): " located via possibly multiple module search path entries. " It looks like we have space for both changes without impacting page breaks, but let me know if this won't work.

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Nov 06, 2013  Jan 24, 2014
Printed, PDF, ePub, Mobi, Safari Books Online, Other Digital Version
Page 770
Second code listing section, lines 2-6

This interactively-entered code tries to prove order-neutral equality of script output lines using sets. As is, though, the code makes and compares sets of characters instead of lines. Recall that set() takes any iterable--in this case using the string returned by file.read, which is an iterable of individual characters, not lines. This works as shown, but only by luck: it proves output character equivalence, not output line equivalence. We should use file.readline's iterable of line strings. To improve, replace these 5 code listing lines: >>> res1 = os.popen('reloadall.py tkinter').read() >>> res2 = os.popen('reloadall2.py tkinter').read() >>> res3 = os.popen('reloadall3.py tkinter').read() >>> res1[:75] 'reloading tkinter\nreloading tkinter.constants\nreloading tkinter._fix\nreload' with the following 5 lines, changing the 3 "read()" to "readlines()", and changing the last two lines completely; the remainder of the listing is correct as is (note: the 4 code parts following ">>>" prompts must be bold font, per the book's convention): >>> res1 = os.popen('reloadall.py tkinter').readlines() >>> res2 = os.popen('reloadall2.py tkinter').readlines() >>> res3 = os.popen('reloadall3.py tkinter').readlines() >>> res1[:3] ['reloading tkinter\n', 'reloading sys\n', 'reloading tkinter._fix\n']

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Jun 30, 2013  Aug 16, 2013
Printed, PDF, ePub, Mobi, Safari Books Online, Other Digital Version
Page 888
Very end of note near page bottom

Not really covered in this book, but the "mutable" should be "immutable" at the second-last word in this note (about __new__ use cases: it allows subclasses to set-up initial values for immutables if needed). Change: "... instances of mutable types." to: "... instances of immutable types.".

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Aug 01, 2013  Aug 16, 2013
Printed, PDF, ePub, Mobi, Safari Books Online
Page 960
second bullet point on page

""" ... the instance's memory address by calling the id built-function..... """ I believe it meant to read "" ...by calling the id built-in function ""

Note from the Author or Editor:
Yes -- change as noted: "id built-function" => "id built-in function".

Joseph Chandler  Jun 06, 2014 
Printed
Page 960
last paragraph

""" ...echoes still use the default format because we're left __repr__ as an option for clients """ should read """ ...format because we've left ... """

Note from the Author or Editor:
Yes -- change as noted: "we're left" => "we've left".

Joseph Chandler  Jun 06, 2014 
Printed, PDF, ePub, Mobi, Safari Books Online
Page 977, 1235
Two new footnotes

Assuming we can fit them in without impacting page breaks badly, I'd like to add two footnotes about use of the __dir__ method in dynamic or proxy classes based on __getattr__ or __getattribute__. This operator overloading method (among others) is not covered in this book for space, but there are two ideal places to add a mention, plus a pointer to additional coverage in the latest Python Pocket Reference. THE CHANGES: 1) On Page 977, add a footnote reference at the end of the first paragraph on this page: """ ...ethereal at best!* "''" which refers to the following new footnote text: """ * Some dynamic and proxy objects based on __getattr__and the like can also use the __dir__ operator overloading method to manually publish an attributes list for dir calls. Because this is optional, though, general tools cannot rely on their client classes to do so. See other resources such as Python Pocket Reference, 5th Edition for more on the __dir__ method. ''"" in which __dir__, __getattr__, and dir are literal font, and the book title is italics and possibly a link (this is the end of chapter, so it's okay if this changes the last page break, but if this adds a page, we can shorten or drop the last sentence of the insert, or simply cut its "other resources such as" part if sufficient). 2) On Page 1235, add a footnote reference to the end of the first sentence in the last paragraph: """ ...names do not appear in dir results.* """ which refers to this new footnote text: """ * As noted in Chapter 31, such dynamic classes can also use a __dir__ method to provide an attribute result list for dir calls, though general tools cannot depend on this optional interface. """" in which __dir__ and dir are literal font (this page appears to have enough space, but again, let me know if it changes paging substantially).

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Jan 12, 2014  Jan 24, 2014
Printed, PDF, ePub, Mobi, Safari Books Online
Page 977
1st paragraph

The text reads: "Tools that attempt to display data in a wildly dynamic language Python must come with the caveat that some data is etheral at best!" And should probably read: "Tools that attempt to display data in a wildly dynamic language like Python must come with the caveat that some data is etheral at best!"

Note from the Author or Editor:
Yes--please insert the "like" as suggested. (It could be argued that the sentence parses either way, but the "like" was the intended and better phrasing--a typo that somehow went unnoticed, despite being read at least 50 times by its author, not to mention editors and proofers.)

Anonymous  Feb 21, 2014  May 02, 2014
Printed, PDF, ePub, Mobi, Safari Books Online, Other Digital Version
Page 982
bottom code listing (setsubclass.py, line #4)

ORIGINAL READER POST (misfiled against 3rd Ed, moved here by author): """ On line 5 of code listing, inside the __init__ function, this line appears: list.__init__([]) # Customizes list Presumably this is meant to call the parent __init__ method to initialize the Set instance. It is however dead code, since it initializes the empty list given in the argument instead. The correct code is like this: list.__init__(self, []) # The second argument is not really needed Another minor gripe is the use of a mutable default for the value argument to __init__. This may lead to subtle bugs in future versions if the list referred to by value is somehow stored or returned so that the user can get at it. [...plus an editorial remark on how this reflects "bad coding practice" pruned here...] """

Note from the Author or Editor:
Reprints: this merits a single patch -- please change the referenced line to the following, only replacing "[]" with "self" (retaining the #'s vertical alignment): list.__init__(self) # Customizes list Discussion: The post raised two different points: the __init__ call (valid), and the "value" mutable argument (invalid). POINT 1) Yes -- the list.__init__ line as shown in the book is harmless and not a bug per se, but it is coded out of idiom, and is pointless code. In short, because list.__new__ initializes the list to be empty before list.__init__ is ever invoked, there is no need to call the latter. The ideal coding is to omit this line altogether, but if used it should pass "self" as its first argument for consistency. Per the C implementation of the list type (file Objects/listobject.c of Python's source code), list.__new__ creates a new, empty list instance object; a later call to list.__init__ simply clears the 1st argument (called "self", but required only to be any list) to be empty if it isn't already, and then extends it with the items in a sequence if one is passed in as a 2nd argument. Hence, passing in just "[]" for the 1st argument to list.__init__ does nothing: the passed empty list is already empty, and no 2nd argument is appended to it. But the same will be true if we pass in just "self" as the 1st argument as prescribed, because it's already an empty list after list.__new__ has run. That is, there is no reason to also call list.__init__ from its redefinition to reinitialize to an empty list. On the other hand, this example also aims to reinforce the general pattern of calling redefined constructors, and this code must still call its own self.concat to extend without duplicates (this is a set implementation). Interestingly, this code line has been present in the book since the 2nd Edition (of 2003--10 years ago), and has gone unremarked by hundreds of thousands of readers until now. It's on Page 982 of the 5th Edition, 778 of the 4th, 542 of the 3rd, and 365 (?) of the 2nd, before which types could not be subclassed. POINT 2) No -- the mutable nature of the default "value" argument is neither relevant nor problematic here. This class simply scans the value's individual items in self.concat, and never stores, changes, or returns the value object itself as a whole. In the process, it effectively creates a copy that is immune to mutable side-effects. Please reread the code, and see earlier in the book (e.g. much of Chapter 6, the latter portions of Chapter 9, and Page 658) for coverage of this key core concept.

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Aug 01, 2013  Aug 16, 2013
PDF, ePub, Mobi
Page 1040
4th paragraph

Really minor, but anyway, the text reads "Such mind-binding concepts will require..." Was that meant to say: "Such mind-bending concepts will require..." ?

Note from the Author or Editor:
Yep -- change to "bending". (It works the other way too, and "binding" may be arguably funnier, but it was supposed to say "bending".)

Anonymous  Mar 13, 2014  May 02, 2014
Printed, PDF, ePub, Mobi, Safari Books Online
Page 1064, 1386
Adding a new notebox and backreference

Assuming we can fit it in without impacting page breaks badly, I wish to add a note clarifying how super() and inheritance relate. The short story is that they don't: super() precludes normal full inheritance, and instead performs a custom scan. There's more on this in the latest Python Pocket Reference (along with other fine points omitted from LP5E for space), but a few words may help here too. THE CHANGES: 1) On Page 1064, just before header "Class Gotchas", add a new Note box with the following text (in which "super" is literal font, "Chapter 40" is a link, and "--" is a single dash character; this will shift some page breaks, but it's near the end of chapter, and the breaks from here to chapter end are arbitrary; let me know if it adds a page): """ Also watch for Chapter 40's formal description of full inheritance -- a procedure which super objects eschew for a custom scan of a context-specific MRO tail, looking for the first appearance of an attribute (descriptor or value) along the way. Full inheritance is used on the super object itself only if this scan fails. The net effect is a special case for basic name resolution, imposed on both the language and your code for the sake of a relatively rare use case. """ 2) On Page 1386, at the end of paragraph 2, change the sentence just before header "Assignment inheritance" that reads: """ See Chapter 38 for more on these tools and descriptors. """ to the following, adding just the clause at the end, in which "super" is literal font, and "Chapter 32" is a link: """ See Chapter 38 for more on these tools and descriptors, and Chapter 32 for the super special-case MRO scan. """ I'm hoping this doesn't add a line and change page breaks; let me know if it does,

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Jan 12, 2014  Jan 24, 2014
PDF
Page 1156
2nd paragraph

functional programing tools...

Note from the Author or Editor:
Yes -- change to "programming". MS-Word's spellchecker says it can be spelled either way (which is likely why this went unnoticed), but we use the double-"m" form everywhere else.

Anonymous  Aug 20, 2013  Nov 08, 2013
Printed, PDF, ePub
Page 1169
5th paragraph

The text reads: "But all of these encoding schemes -- ASCII, Latin-1, UTF-8, and many others -- are considered to be Unicode." Perhaps it should be clarified that though the ASCII and Latin-1 **character sets** are both considered Unicode (are proper subsets of Unicode), only ASCII and UTF-8 **encodings** would pass as "Unicode encodings" (a Latin-1 encoding would encode characters (128-255) as single bytes with bit patterns outside of those accepted by UTF-8, and UTF-16 and UTF-32 also - naturally).

Note from the Author or Editor:
No change required on this, but I'm retaining it as a confirmed author note in case it may prove useful context to other readers. To me, this seems to be splitting hairs over very subtle shades of meaning, and the proposed rewording doesn't offer much over the original. The main and simple point here was that all three fall under the Unicode umbrella. Tightening this text up to distinguish character sets and encodings would seem to distract too much from its simpler goal, but your milage may vary.

Anonymous  Mar 19, 2014 
PDF, Mobi
Page 1238
4th paragraph

In the description of the __setattr__ method: "...an operator overloading method run for every attribute fetch,..." Did you mean to say: "...an operator overloading method run for every attribute assignment,..."

Note from the Author or Editor:
Yes -- change as described. (Likely obvious to most readers, given the many surrounding descriptions and examples, and "fetch" can be interpreted broadly; but "assignment" was clearly the intended and proper word in this clause.)

Anonymous  Mar 20, 2014  May 02, 2014
Printed, PDF, ePub, Mobi, Safari Books Online
Page 1250
code line 11

return lambda *args: '[Getattr str]' It seems that "*args" here is unnecessary under all circumstances because object.__str__(self) expect 0 arguments.

Note from the Author or Editor:
No -- I'm not going to mark this as an errata, because the goal here was to simply flag interceptions of attribute fetches for built-in operations, not to provide full implementations for the intercepted operations. Hence, the intentional coding of a generic "any argument list goes" function with a *args is fine; it simply catches the call so as to produce an indicator message. This was also coded for symmetry with the result for other operations, whose arguments do vary. That being said, this underscore an interesting point. The "*args" is indeed optional in this lambda, but for reasons more subtle than the post may have meant to imply. A __str__ implementation run by some prints should normally allow for at least the automatic "self" argument: >>> help(object.__str__) # in 3.X Help on wrapper_descriptor: __str__(...) x.__str__() <==> str(x) >>> object.__str__() TypeError: descriptor '__str__' of 'object' object needs an argument Importantly, in this book example, __getattr__ is intercepting the attribute *fetch*, not the later operation *call*. By contrast, the explicitly coded __len__ in this class catches the operation call, not the attribute fetch. That is, the book example deliberately handles this step only: >>> object.__str__ <slot wrapper '__str__' of 'object' objects> In general, though, a program that really intends to implement __str__ in full should usually return a *bound method* object that retains the "self" available at attribute fetch time, and not a simple function created by a lambda. When Python later calls the fetch's result, it omits the original "self" from the arguments list, assuming it to be part of and provided by a bound method (or other state retention device) if needed by the operation implementation. Thus, no self argument is required of or passed to a simple function fetch result. Python normally creates bound methods automatically on attribute fetch, when one is coded explicitly as a method with a self argument (like the class's __len__), or fetched from a proxied object (by calling the built-in getattr(wrapped, attrname), the normal coding pattern in delegation contexts). By using a lambda in the example, we're implying that the later operation call won't require the self object that was present at attribute fetch time; this simple call tracer does not. Again, though, illustrating all this was well beyond the goals of this particular code. Its liberal method coding suffices as a catch-all demo of attribute fetch interception in __getttr__ and __getattribute__ -- and the lack thereof for built-in implicit fetches in new-style classes. See Chapter 31 for more on bound methods in general.

Yang Lifu  Aug 22, 2013 
PDF, Mobi
Page 1256
2nd paragraph

The paragraph starts: "That short story here is..." and should probably read: "The short story here is..."

Note from the Author or Editor:
Yes -- change as described. (A minor typo that was missed by all.)

Anonymous  Mar 21, 2014  May 02, 2014
PDF, Mobi
Page 1273
4th paragraph

The text reads: "...where decorator is a one-argument callable object that returns a callable object with the same number of arguments as F (in not F itself):" The parenthetical note seems meant to have read: "...(not F itself):" OR "...(not necessarily F itself):"

Note from the Author or Editor:
The parenthesized bit should say: "(if not F itself)" Please change this way in reprints. Probably apparent to most given the text following this: "...which may be either another object that implements required wrapping logic, or the original function itself". The "in" typo's clause was added in the 5th Ed.

Anonymous  Mar 23, 2014  May 02, 2014
Printed, PDF, ePub, Mobi, Safari Books Online, Other Digital Version
Page 1294
Very end of last paragraph on page

Trivial detail, but we need to add a missing colon (":") at the end of this paragraph, just before the last code listing at the end of the page. The page number is from the PDF and print versions; in e-books, this is near the end of "Using descriptors to decorate methods" in Chapter 39.

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Jun 30, 2013  Aug 16, 2013
Printed, PDF, ePub, Mobi, Safari Books Online
Page 1302
second code example (singletons.py), inline comment #5

The mention of "onCall" in that inline comment isn't formatted correctly – while "onCal" is good (italicized and in "normal text" font), the last "l" isn't; it's printed in the monospaced code font again, also not italicized, just like actual code.

Note from the Author or Editor:
Yes -- minor but true. As suggested, make the last "l" character italics too, like the rest of the text in comment "# Rebinds Spam to onCall". It's one character in a 1600-page book, but it looks like a digit as is.

Julian R.  Mar 04, 2014  May 02, 2014
, Printed, PDF, ePub, Mobi, Safari Books Online, Other Digital Version
Page 1327
2nd last line of 2nd paragraph on page

Minor typo that eluded all proofing: "that" should be "the". Change: "we’ll also employ that third of the mix-in options" to: "we’ll also employ the third of the mix-in options".

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Jul 11, 2013  Aug 16, 2013
Printed, PDF, ePub, Mobi, Safari Books Online
Page 1363
3rd paragraph

The text reads: "decorators must provide class behavior is less direct ways." should read: "decorators must provide class behavior in less direct ways."

Note from the Author or Editor:
Yes -- please correct as suggested (and consider hiring this reader for copyedits!).

Anonymous  Mar 26, 2014  May 02, 2014
Printed, PDF, ePub, Mobi, Safari Books Online, Other Digital Version
Page 1386
Just before "Assignment inheritance"

Reprints: please contact me when applying patches in the next reprint--it looks like there is a bit of room on this page and later, and I may opt to add a few more details here drawn from a recent article on the subject (which is also to be posted on O'Reilly's site as I write these words): http://rmi.net/~lutz/python-newstyle-inheritance.html Readers: you'll find another look at inheritance in this article, though its extra details are all implied by material and examples surrounding the algorithm in the book's more in-depth coverage.

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Jun 30, 2013  Aug 16, 2013
Printed, PDF, ePub, Mobi, Safari Books Online
Page 1447 (and TOC)
First bullet item, 2nd header line, TOC entry of latter

On this page, change "!#" to "#!" in the two appearances of the text "Unrecognized Unix !# lines" noted in Location. The second is a header line, so this must also be fixed in its Table of Cotents entry. Minor and likely obvious, if noticed at all; the correct "#!" shows up 107 times in the book, and these 2 look like a single finger slip that was copied, but escaped multiple proofs.

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Jan 12, 2014  Jan 24, 2014
, Printed, PDF, ePub, Mobi, Safari Books Online, Other Digital Version
Page 1457
line 2 of paragraph 4

Trivial typo, singular->plural: change "code written for prior release in the 3.X line" to "code written for prior releases in the 3.X line". (Typos happen In a 1600-page book, despite the best of proofing efforts.)

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Jul 15, 2013  Aug 16, 2013
Printed, PDF, ePub, Mobi, Safari Books Online, Other Digital Version
Page 1505
# Fetch and open/play a file by FTP

userinofo = () connection.login(*userinfo)

Note from the Author or Editor:
Yes--a typo (and a good catch: this is in self-study code, in a branch run only for anonymous FTP which was never exercised in testing). To patch, please change code line -3 on this page (per PDF paging) from: userinofo = () to: userinfo = ()

Anonymous  Aug 20, 2013  Nov 08, 2013
ePub, Mobi, Safari Books Online
Page 1541
About the Author bio at end of some versions (only)

The author bio at the end of the EPUB and MOBI e-books and the Safari online releases is an abbreviated version that does not match the full and final bio that appears in both the print and PDF e-book versions. Not critical, but for consistency, please use the print/PDF's full and final author bio in all releases.

Mark Lutz
O'Reilly AuthorO'Reilly Blogger 
Jun 30, 2013  Aug 16, 2013
Printed, PDF, ePub, Mobi, Safari Books Online
Page 9999
URL above the last paragraph in the page

The following is the Safari Online URL for the page in error: http://proquest.safaribooksonline.com/book/programming/python/9781449355722/preface/pr04s09_html?uicode=califa (If there is a better way to locate the problem location in the online text, please let me know.) The problem is with the HREF associated with the following link: http://rmi.net/~lutz ... it justs hangs there. However, modifying the HREF to http://www.rmi.net/~lutz works fine. N.B. The page number I entered for this issue - 9999 - is entered only to satisfy the requirement of that being a required field.

Note from the Author or Editor:
This is on the middle of Page xlviii of the Preface. Replace: http://rmi.net/~lutz to: http://www.rmi.net/~lutz in both the text and the underlying ebooks' link. This is the only spot in the book where the short and now invalid form of this URL appears. It reflects a change at my ISP -- Earthlink, which owns rmi.net after multiple shuffles, dropped the non-"www" domain name after the book was published. The longer "www" form of this domain does appear just above on the same page, and a web search should find the proper form too (and may be required if www.rmi.net ever goes away altogether), but it's worth a patch.

pob  Mar 23, 2014  May 02, 2014