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 Author 
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 Author 
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, ePub
Page Multiple
Solution links at end of each part's exercises

Reported by a reader offline: the hyperinks to exercise solutions at the end of each part are not very useful as is. They typically are coded as variations on: "See Part _X_ in _Appendix D_ for solutions" with a link from "X" to the start of the part itself, and a link from "Appendix D" to the start of the entire appendix. The first of these seems almost useless, as it points back to the start of the part just read. The second takes readers to the appendix start, but they then have to scroll to the portion within it having the part's answers. I'm open to ideas (or O'Reilly standards) on this, but at least one of these two links should point to the subsection of Appendix D for the specific part's answers. As a model for how these links should ideally work, see the Index entry for "exercises", which has correct subsection links; for each part, the first link gives the page having the questions, and the second is the page with their solutions: """ exercises part I, 87–89, 1465–1467 part II, 313–315, 1468–1472 part III, 467–469, 1473–1475 part IV, 663–665, 1475–1485 part V, 778–779, 1485–1489 part VI, 1072–1076, 1489–1496 part VII, 1161, 1497–1499 """ Locations where these links appear along with their text (the wording itself is fine and probably shouldn't be changed; only the links need be adjusted): Page 87: "Be sure to check Part I in Appendix D for the answers" Part I links to the part start, Appendix D to appendix start. We really need only Appendix D to link to page 1465. Page 313: "answers in Appendix D" Appendix D links to appendix start on page 1465, but should be to this part's subsection start on page 1467/1468 Page 467: "See Part III in Appendix D for the solutions" Same pattern as page 87: need only link to page 1473 instead. Page 663: "solutions in Part IV in Appendix D," Ditto; need only link to page 1475 instead. Page 778: "See Part V in Appendix D for the solutions." Ditto; need only link to page 1485 instead. Page 1072: "You’ll find them in Appendix D, under Part VI." Ditto (order swapped): need only link to page 1489 instead Page 1161: "See Part VII in Appendix D for the solutions." Same: need only link to page 1497 instead. If this is unclear please contact me prior to reprint edits.

Mark Lutz
O'Reilly Author 
Oct 18, 2014 
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 dont 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 Lets 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 itand 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 files 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 files 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
Page 98
6th text paragraph, line 1

The word "random" is strangely broken across 2 lines. At the least, it should have a hyphen at the break. Even better, because it is in different typeface, it probably shouldn't be broken at all, so that the whole word is on one line.

Note from the Author or Editor:
Reprints: please remove the line break in the middle of this "random" literal (by forcing the entire word to the next line, probably). This one is so short that it shouldn't have a noticeable impact on the surrounding lines, and there are no later literals in this paragraph that may split as a result. Discussion: whether official style or not, line-breaks in the middle of literals are, unfortunately, common in O'Reilly books. I've raised this issue on each of mine, and pointed out the most grievous for manual repair, but some seem to slip through the cracks anyhow. The rationale is that long literals may cause prior/next lines to be too sparse or choppy if not split, and the shifting that results from fixing one may cause other later literals to be split anyhow. In this case, however, the split literal is so short that the effect of removing the line break will be harmless.

Mitch Butler  Jul 29, 2014  Aug 22, 2014
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] = '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  Aug 22, 2014
Printed
Page 102
2nd text paragraph

The word "bytearray" in line 2 is strangely broken across 2 lines. At the least, it should have a hyphen at the break. Even better, because it is in different typeface, it probably shouldn't be broken at all, so that the whole word is on one line.

Note from the Author or Editor:
Reprints: try to remove the line-break in the middle of this literal (by forcing it to the next line?), but only if doing so does not stretch/empty the surrounding lines too much, cause similar literal line-breaks later in this paragraph, or degrade formatting in this paragraph in general. Discussion: whether official style or not, line-breaks in the middle of literals is, unfortunately, common in O'Reilly books. I've raised this issue on each of mine, and pointed out the most grievous for manual repair, but some seem to slip through the cracks anyhow. The rationale is that long literals may cause prior/next lines to be too sparse or choppy if not split, and the shifting that results from fixing one may cause other later literals to be split anyhow. I'm marking this one for possible repair, but only if it doesn't harm other formatting; in this case, it will leave a dash at the end of the prior line, and might introduce a new line-break in another literal later in this paragraph.

Mitch Butler  Jul 29, 2014  Aug 22, 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 Author 
Apr 05, 2014  May 02, 2014
PDF
Page 105
Last paragraph

Shouldn't "but allow the other type of quote to be embedded with an escape" be "but allow the other type of quote to be embedded without an escape" After all, the following works: a = '"' # this is a single quote followed by a double quote followed by a single quote

Note from the Author or Editor:
Yes, a genuine typo (in a brief mention of a subject that is covered in full later in the book: see the section on Page 193). Change as described -- Page 105, last paragraph, end of line 2, from the first of these to the second: "to be embedded with an escape (most" "to be embedded without an escape (most"

Jon Forrest  Sep 28, 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
Page 122, 278
122: end of 1st paragraph, 278: end of 3rd paragraph

I'd like to add two short inserts to clarify unparenthesized tuple syntax. It can lead to fairly nasty syntax errors, in constructs such as lambda bodies. This is addressed elsewhere, but could use a bit of elaboration at the insert locations. The two inserts: 1) Page 122, end of 1st paragraph. Change: " (the parentheses enclosing a tuples items can usually be omitted, as done here): " to the extended: " (the parentheses enclosing a tuples items can often be omitted, as done here; in contexts where commas don't otherwise matter, the commas are what actually builds a tuple): " 2) Page 278, end of 3rd paragraph. Change: " Many programmers (myself included) also find that parentheses tend to aid script readability by making the tuples more explicit and obvious, but your mileage may vary. " to the shortened: " Many programmers also find that parentheses tend to aid script readability by making the tuples more explicit and obvious*. " where the * references a new footnote at the bottom of this page, with text: " *A subtler factor: the comma is a sort of lowest precedence operator, but only in contexts where it's not otherwise significant. In such contexts, it's the comma that builds tuples, not the parenthesis; this makes the latter optional, but can also lead to odd, unexpected syntax errors if parentheses are omitted. " If this changes page breaks, please ask me to shorten the wording (I've shortened the existing text to try to avoid breaking the current content across pages).

Mark Lutz
O'Reilly Author 
Aug 07, 2014  Aug 22, 2014
Printed
Page 127
2nd group of interpreter session input/output

I believe the comment at the end of one of the lines: # Order-neutral equality tests (== is False) should be: # Order-neutral equality tests (!= is False)

Note from the Author or Editor:
Reprints: in the referenced comment text, please change: # Order-neutral equality tests (== is False) to: # Order-neutral equality ('spam'=='asmp' False) using straight quotes, and keeping all other text unchanged, including the preceding whitespace used for "#' vertical alignment. I deleted the word "tests" so that this still fits on one line. Discussion: Not an error and just a comment, but I agree this is a bit terse and worth a minor clarification. The intent here was that running strings through set() makes them compare equal (order neutral), while comparing the strings themselves is False (order matters). This is called out in more detail in the next chapter's fuller coverage of sets, where the same example makes this more obvious, and also compares the finding to sorts (Page 170): >>> 'spam' == 'asmp', set('spam') == set('asmp'), sorted('spam') == sorted('asmp') (False, True, True) Interestingly, the "is" identity test is False for these sets too (they have same value but are different objects), but this operator isn't introduced until the next chapter. Per the post, "!=" is False for the sets as well, but that's just the inverse of what's shown, and wasn't the comment's intent about the underlying strings.

Mitch Butler  Jul 29, 2014  Aug 22, 2014
Printed, PDF, ePub, Mobi, Safari Books Online
Page 138
Insert at end of 5th bullet item

A minor insert to further clarify how commas work in unparenthesized tuples. At the end of the 5th bullet item on this page (that begins "The syntax (...)"), add this single sentence, with its "comma" in italics: " When a tuple's parentheses are omitted, the comma separating its items acts like a lowest-precedence operator if not otherwise significant. " [Discussion only follows] This is trivial when this is intended or appears standalone, but can lead to odd syntax errors in contexts where the tuple may not have been expected (e.g., in lambda return expressions). It could be argued that the comma is an operator in general, but it's a special case, as it serves this tupling role only in cases where it's not otherwise significant. It's really specific top-level separator syntax that doesn't work in contexts like function argument lists. A new clause and footnote on pages 122 and 278 address this as well, but I'm also propagating the insert here from Python Pocket Reference 5th Ed. This insert adds 2 lines, but there seems ample space on the page.

Mark Lutz
O'Reilly Author 
Aug 18, 2014  Aug 22, 2014
PDF
Page 142
1st code sample

The text shows the following: >>> b * 3, b / 2 # Multiplication (4 * 3), division (4 / 2) (12, 2.0) Shouldn't the result be (12, 2) This is what I see with Python 2.7.7

Note from the Author or Editor:
No, and this is getting a bit redundant, as the 2.X difference is mentioned before this example and described again on the very next page. But to avoid such understandable confusion -- on Page 142, 1st code listing, line 3, expand the comment test on the right from the first of the following to the second, retaining the "#" vertical alignment: "# Multiplication (4 * 3), division (4 / 2)" "# Multiplication (4 * 3), division (4 / 2, 3.X result)" [Discussion only follows] I'm marking the edit grudgingly, because it gets tedious to see "3.X" called out everywhere a trivial output differs from 2.X, especially when the difference is explained both earlier and later in the text. In this case, Page 138 (before this example, which is just one among many) states: """ The X / Y expression performs true division in 3.X (retaining remainders) and classic division in 2.X (truncating for integers). See “Division: Classic, Floor, and True” on page 146. """ And again on the very next page following the example (Page 143, shortly before an entire section on the subject on Pages 146-150), the book says: """ Also, notice that all the numbers are integers in the first expression. Because of that, Python 2.X’s / performs integer division and addition and will give a result of 5, whereas Python 3.X’s / performs true division, which always retains fractional remainders and gives the result 5.0 shown. """ Hence category was changed from technical mistake to clarification, and this is likely the last edit we'll make of this kind. I appreciate such posts and understand their intent, but examples can't generally be understood in isolation from their surrounding context and narrative.

Jon Forrest  Oct 05, 2014 
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 Author 
Jul 11, 2013  Aug 16, 2013
PDF
Page 158
2nd paragraph

You say The following in 3.3 gives the same result as the previous output: >>> print(0.1 + 0.1 + 0.1 - 0.3) # Pythons < 2.7, 3.1 5.55111512313e-17 The version number(s) in the comment and the prose don't match. I think you meant to say "The following in versions prior to 3.1 and 2.7 gives the same result as the previous output". Another problem with this is that you say the two examples give the same result. But, they aren't the same. The second is a rounded version of the first. Also, once again you say "On Python ..." in this paragraph instead of "In Python ..."

Note from the Author or Editor:
This narrative tries to accommodate an odd and trivial print precision change present as of 3.3, but it's really not germane to the topic here in any event. So, let's change this way: 1) Page 158, start of paragraph #2, change the first to the second: "On Pythons prior to 3.1 and 2.7, printing ..." "Printing ..." 2) Page 158, comment on right of code line #1 of 2nd code listing, change first to second: "# Pythons < 2.7, 3.1" "# Earlier Pythons (3.3 differs)" [Discussion only follows] The 'other problem' isn't present. The sentence preceding the code states: "The following in 3.3 gives the same result as the previous output:", which means it differs from the next line. The results do differ slightly in 2.7, but that's not what was stated here. The 'on/in' point goes away here with this edit, but does not require universal consistency in general. This book's narrative is informal.

Jon Forrest  Oct 05, 2014 
Printed
Page 159
1st new paragraph (starting "This") and example following

The paragraph talks about monetary applications and representing cents with two decimal digits. The example suggests that such "cents" in a monetary application will be handled properly if you set getcontext().prec to 2. But the Decimal "prec" (at least with an otherwise default context) is the number of total digits of precision in operations, not in the creation of a Decimal (which stores everything you feed it--see link below). So in the example, Decimal(str(1999 + 1.33)) creates a Decimal('2000.33'). But that actually has 6 digits of precision. Decimal('1999') + Decimal('1.33') in that same context actually yields Decimal('2.0E+3'), not Decimal('2000.33') as the example implies. I assume there is a way to handle monetary applications (i.e. with a fixed number of "places" after the decimal point) with Decimals, but I don't know it (I am just learning Python ... that's why I'm reading the book). But it can't be by using getcontext().prec = 2 with an otherwise default context (I am using Python 3.3.2 on Win32, FWIW), as in the example. See https://docs.python.org/3/library/decimal.html#decimal.FloatOperation "The significance of a new Decimal is determined solely by the number of digits input. Context precision and rounding only come into play during arithmetic operations."

Note from the Author or Editor:
This post seems to expect too much of the deliberately limited Decimal coverage here (see below). To avoid similar confusion, though, let's change the potentially misleading paragraph in question from the first of the following to the second: "This is especially useful for monetary applications, where cents are represented as two decimal digits. Decimals are essentially an alternative to manual rounding and string formatting in this context:" "Technically, significance is determined by digits input, and precision is applied on math operations. Although more subtle than we can explore in this brief overview, this property can make decimals useful as the basis for some monetary applications, and may sometimes serve as an alternative to manual rounding and string formatting:" [Discussion only follows] All true, and thanks for the informative post which others may find helpful. But you seem to be reading too much into the book's very limited and even terse coverage of Decimals. This is a 2-page tutorial in a chapter on number basics, about a complex tool that has a limited audience, and changes often across Python releases. Its code samples are not the whole story, and weren't meant to be. The book is at best an introduction to this obscure topic -- as it is for Fractions in the same section, complex numbers earlier in the chapter, and namedtuples in later chapters. Its examples do work as shown: the code in question relies on the 2-digit str() result to set initial sizes, but the "prec" setting would also be applied on future math operations. Still, Decimal is much more complex than presented in the book. The book expects readers interested in the subject to go the docs for more usage details, which you clearly have. Or, to quote from this brief section's conclusion in the book: """ Because use of the decimal type is still relatively rare in practice, I’ll defer to Python’s standard library manuals and interactive help for more details. """ Given that, I'm disinclined to write much more about them either in the book or here, when the standard manual fills in their background and details well. Hence, no book changes required apart from the minor rewording above, but post retained for other readers, and category changed from "serious technical mistake" to "clarification", as the text seems to have worked exactly as designed on this. That said, and viewing this post as a request for clarification, the Decimal class can form the _basis_ of monetary calculations, but it takes more to flesh out a full implementation. For pointers, try a web search for Python Money classes (that yields the following), and see the FAQ on the quantize() method in Decimal's standard library manual (the last of the following): https://code.google.com/p/python-money/ https://pypi.python.org/pypi/py-moneyed https://docs.python.org/3/library/decimal.html Python isn't COBOL, and floating-point and integer suffice as monetary data for many; but fixed point solutions are also readily available. Decimal itself is complex and nonintuitive, is largely skipped in the text, and requires additional research on the part of readers.

Frank Hollander  Oct 19, 2014 
PDF
Page 177
Fig 6.1

Figure 6.1 and its caption use the word "names" in several places. It would be clearer, and more consistent, if you instead used "variables".

Note from the Author or Editor:
The equivalence is already mentioned once on the prior page (see below); but to further clarify, let's apply two edit in reprints. 1) On Page 176, start of paragraph 2, change the first of the following to the second, with its "name" in italics for emphasis: "A variable (i.e., name), like a," "A variable (also known in Python as a name), like a, ..." 2) On Page 177, start of caption to Figure 6-1, change the first of the following to the second: "Figure 6-1. Names and objects ..." "Figure 6-1. Names (a.k.a. variables) and objects ..." [Discussion only follows] I agree with the poster in principle, but the book points out the equivalence of "variable" and "name" on Page 176, just before the caption mentioned. It reads like this (with an "i.e." for "that is"): """ Variable creation A variable (i.e., name), like a, is created when your code... """ Still, that's a bit terse, and the edits above may help make this more obvious and avoid confusion. Using one or the other terms universally isn't an option at this point, given their widespread usage. The occasional "name" also highlights distinctions with other languages, and you'll generally see "name" in error messages from Python itself, despite the common use of "variable" in math. Using both terms is intended to have wider scope. In any event, "variables" would be the worse of the two to use -- it's "name" almost everywhere in Python.

Jon Forrest  Oct 05, 2014 
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 Author 
Apr 28, 2014  Aug 22, 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  Aug 22, 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 Author 
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  Aug 22, 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 Author 
Oct 22, 2013  Nov 08, 2013
Printed, PDF, ePub
Page 268
lines 7 and 11 of first code listing

Line 7: "['b', 'c', 'a']" appears to have one leading space at its start; the leading space should be removed. Line 11: ">>> D" is all italics; all italics on this line should be removed (and "D" should be bold, per interactive input formatting--like line 2).

Mark Lutz
O'Reilly Author 
Oct 15, 2014 
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 Author 
Jul 20, 2014  Aug 22, 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 Author 
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 Author 
Oct 07, 2013  Nov 08, 2013
Printed, PDF, ePub, Mobi, Safari Books Online
Page 380
A Few Special Cases section (last paragraph)

the sentence 'indent all but the simplest of blocks', what does the book mean with "the simplest of blocks"? Which are the "simplest of blocks" it refers to?

Note from the Author or Editor:
[No changes required] The phrase "simplest of blocks" refers to a nested block that's composed of one or two simple, non-compound statements that are not indented, but coded on the same line as the statement header. It's generally consider bad style to do this when the unindented block's statements are non-trivial, as it can lead to code that's difficult to read and change. Retained as a clarification, but no change required in the book. The page 380 text is an intentionally brief summary wrap-up of the second section that discusses nested block syntax, exceptions, and style. By this point in the book, both the meaning and disfavor of coding all but the "simplest of blocks" unindented have been discussed. For example, the section on Page 329, and the multiple-page example which follows it, discuss and illustrate both this topic and the advice. I appreciate the question, and readers who jump to Page 380's wrap-up at random might indeed find it terse; but some extra research can help clarify topics covered in more depth earlier in the book.

Antonio Cota  Aug 01, 2014 
Printed, PDF, ePub, Mobi, Safari Books Online
Page 389
last example on page (under General Loop Format)

Change the comment on the right side of code line 4 from: # Go to top of loop now, to test1 to this, retaining the original vertical alignment of the '#": # Go to test at top of loop now [Discussion] Just comment text and minor, and probably accepted by most readers because this did refer to the 1st of 3 tests. Still, "test1" sounds formal enough to be confusing. It's legacy from a 4th edition version which had a "test1", "test2", and "test3", but which was odd enough to merit a rework in the 5th edition. The following was the original report submitted by Roger A. Davidson, moved here verbatim as this pertains to the 5th Edition: """ The second comment (explaining the continue statement) refers to going "to test1", but all the tests in the example are labeled simply "test" and there is no "test1." This is likely just a typo where the three tests were intended to be numbered "test1" for the while, "test2" for the break and "test3" for the continue. It's a wonderfully detailed book though, and I'm learning a lot in my self-paced journey through it. """

Mark Lutz
O'Reilly Author 
Aug 20, 2014  Aug 22, 2014
Printed
Page 389
3rd main paragraph

Another word break issue: con - tinue broken across 2 lines. There is another one on page 391, 2nd main paragraph.

Note from the Author or Editor:
Minor and cosmetic, but yes -- both of these should be fixed in the print version if possible. Do not split the "continue" keyword literal; force its "con" to the start of the next line, and verify that other literals in these paragraphs are not split in the process. See also notes on pages 98 and 102 for similar items and more background. There are almost certainly more of these on later pages, but it's been a longstanding O'Reilly style, whether explicit policy or tool artifact. Given that this hasn't drawn more reader posts, it doesn't seem worth an exhaustive scan at this time.

Mitch Butler  Aug 18, 2014  Aug 22, 2014
Printed, PDF, ePub, Mobi, Safari Books Online
Page 413
Why You Will Care: Shell Commands and More (last paragraph - last line)

it says: "[...] but uses urllib instead of urlib.quest, ...." I think it should be: "[...] but uses urllib instead of urllib.quest, ...." One "l" is missing in 'urlib.request'

Note from the Author or Editor:
Yes -- a valid typo and good catch, though the change should be from: urlib.request to: urllib.request

Antonio Cota  Aug 03, 2014  Aug 22, 2014
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  Aug 22, 2014
Printed, PDF, ePub
Page 446
paragraph -2, line 4

Minor uncaught typo: Change "Unix-stye #!" to "Unix-style #!" (adding just the "l").

Mark Lutz
O'Reilly Author 
Oct 15, 2014 
Printed
Page 473
Table 16-1, line starting with def

the second column of this line says def printer(messge): I believe it should say: def printer(message)

Note from the Author or Editor:
Yes. This is abstract sample code in a table that isn't actually run, so the variable name is unimportant; it should probably match that in the next line, though. Change as directed: "messge" => "message".

Alexander Hilsbos  Aug 22, 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 Author 
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  Aug 22, 2014
Printed
Page 520
Last line of the page

it says: "[...] and the PRINT at the end finds the variable in the..." but according the exercise number 5 there is no print statement, just `X`

Note from the Author or Editor:
Yes; this has been present since the 3rd edition so it's probably not too grievous (an interactive display is a print of sorts, though not a formal one), but it merits a patch. Change the middle of the last line on Page 52 from the first of these to the second, with no words in literal font: "and the print at the end finds" "and the display at the end finds"

Antonio Cota  Aug 23, 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 Author 
Oct 02, 2013 
Printed
Page 542
The min Wakeup Call! seciton, 2nd paragraph

The paragraph says: "Moreover, the function should work for all kinds of Python object types: numbers, strings, lists, lists of dictionaries, files and even None". I think that's not quite right, in Python 3.X (as the books says too), dictionariy comparison tests were removed, so I can't figure out out the 3 functions coded can work if they all use the `<` test.

Note from the Author or Editor:
Yes -- and good catch: these functions do work for dicts in 2.X, but not in 3.X where direct dict comparison was dropped. To clarify, on Page 542, add the following sentence to the very end of paragraph #2 under "The minWakeup Call!" that begins with "Suppose you ...", including the parenthesis, and with links to chapters 8 and 9: "(To be fair, Python 3.X users don't need to support dictionaries, because their dictionaries don't support direct comparisons; see Chapters 8 and 9.)" [Discussion only follows] With the solutions shown in the book, the following code : >>> import mins >>> mins.min1(dict(a=1), dict(b=2)) TypeError: unorderable types: dict() < dict() works in 2.X but fails in 3.X -- as does a built-in min(dict(a=1), dict(b=2)). This extends also to lists of dictionaries -- what the book actually mentions: >>> mins.min1([dict(a=1)], [dict(b=2)]) TypeError: unorderable types: dict() < dict() Dictionaries can be made to work with these functions in 3.X by converting them to key/value lists before being passed in via dict.items(), and then back to dicts on return via dict(), thereby comparing items lists (technically the values in items iterables) instead of dictionaries: >>> dict(mins.min1(dict(a=1).items(), dict(b=2).items())) {'a': 1} >>> [dict(I) for I in mins.min1([dict(a=1).items()], [dict(b=2).items()])] [{'a': 1}] But that's strictly extra credit here.

Antonio Cota  Aug 27, 2014 
Printed
Page 550
Why You Will Care: Keyword Arguments section, second-last paragraph

The sentence: "but also allows us to pass in optional keyword arguments to specify a dictionary sort key and a reversal flag, which.....". I think that 'dictionary sort key' is too ambiguous, in fact according to the documentation: "key specifies a function of one argument that is used to extract a comparison key from each list element" So in my opinion it should be more clear.

Note from the Author or Editor:
This is covered earlier, but to avoid confusion, let's add a word -- Page 55, paragraph -2, middle of line 2, change the first of these to the second: "a dictionary sort key" "a dictionary sort key function" [Discussion only follows] Actually, the book also makes this pretty clear in the full section on the subject earlier, which is back-referenced here. Did you try following the link in the book here before going to Python docs? It points to Chapter 8, where Page 247 says: """ the key argument gives a one-argument function that returns the value to be used in sorting ... """ and then demonstrates this live. That said, a 1-word augmentation seems harmless and useful here.

Antonio Cota  Aug 27, 2014 
Printed, PDF, ePub, Mobi, Safari Books Online
Page 567
end of footnote

We have space to augment a footnote on this page with a few key and useful summary details. On Page 567, at the end of the footnote on this page, change: " lambda is simpler to use than you may think. " to the extended: " lambda is simpler to use than you may think: it's simply an alternative way to code a function, albeit without full statements, decorators, or 3.X annotations. "

Mark Lutz
O'Reilly Author 
Aug 07, 2014  Aug 22, 2014
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 Author 
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 Author 
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
Page 617
"Example: Emulating zip and map with Iteration Tools" section

The example: map(lambda x, y: x+y, open('script2.py'), open('script2.py')) ['import sys\nimport sys\n', ....................., ...etc...] I think that there should be a 'list()' call wrapping the map function to return the list shown.

Note from the Author or Editor:
Yes, the list() is required, though only for 3.X (this code was likely from a 2.X session,as it's new in this edition). Given that all other code in this section uses 3.X form, lets change as suggested -- Page 617, 1st code listing, line -4, change from the first of the following to the second, adding just the enclosing list(...), and retaining the bold code font: >>> map(lambda x, y: x + y, open('script2.py'), open('script2.py')) >>> list(map(lambda x, y: x + y, open('script2.py'), open('script2.py')))

Antonio Cota  Sep 08, 2014 
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
Page 629
Timing Iteration Alternatives - Second Paragraph

The book: "The generator functions and expressions of the preceding chapter tend to be slightly slower than list comprehensions, though they minimize memory space requirements and DON'T delay result generation." I think that "don't"' shouldn't be there, because as the book said previously generators delay results.

Note from the Author or Editor:
No, the text as intended is correct here (see below). But to clarify, let's change the end of the 2nd last paragraph on Page 629 from the first of the following to the second (hopefully this won't change page breaks here; please contact me if it does): "don’t delay result generation." "don’t delay the caller for result generation when there are many results to generate." [Discussion only follows] Not an errata, though I understand the confusion. Generators do produce results only on request. as covered in the entire preceding chapter. However, the "don't delay" here is referring to the fact that generators won't pause a program to produce results when there are many in the results set, or it takes a long time to produce them; generators return the first result quickly, rather than making the caller wait for the entire results set to be computed all at once. If that's unclear, please see the permutations case study in the prior chapter, Pages 612-616 -- a non-generator pauses the caller for nontrivial lengths (and perhaps forever), but the generator returns the first result quickly; quoting from this: """ The list and generator versions' results are the same, though the generator minimizes both space usage and delays for results. """ This was what the "don't delay" meant here.

Antonio Cota  Sep 10, 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 packages 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 Author 
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 Author 
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 Author 
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  Aug 22, 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  Aug 22, 2014
ePub
Page 966
last few lines before "Listing attributes per object in class trees" section

Addressing the "Looping in __repr__" question, it is mentioned that "you can avoid the loops by using isinstance to compare the type of attribute values against types.MethodType in the standard library, to know which items to skip." But this does not seem to work. Once you use getattr(self, attr) or its alternative (e.g., eval) to access the attribute values, you trigger __repr__, before doing comparison with types.MethodType or skipping any items. Therefore the loop is not avoided. Would you mind clarifying this or posting the code for the updated __repr__ overloading?

Note from the Author or Editor:
[No book changes required: informational only] Sure -- though the code formatting might not come out very well on this page. In short, you must run the type test _before_ the string formatting; getattr() doesn't trigger __repr__ itself, the string formatting does. Here's the __repr_ version without the loop: # listinherited-reprfix.py (less __main__ code and comments trimmed) import types class ListInherited: """ Use dir() to collect both instance attrs and names inherited from its classes; use __repr__, but avoid loops for methods by type testing; """ def __attrnames(self): result = '' for attr in dir(self): if attr[:2] == '__' and attr[-2:] == '__': result += '\t%s\n' % attr else: obj = getattr(self, attr) if isinstance(obj, types.MethodType): result += '\t%s=<<Method: %s>>\n' % (attr, obj.__name__) else: result += '\t%s=%s\n' % (attr, obj) return result def __repr__(self): return '<Instance of %s, address %s:\n%s>' % ( self.__class__.__name__, id(self), self.__attrnames()) This works the same as the __str__ based listinherited.py in the book, but doesn't display the class to avoid the loop (displaying additional detail is left as exercise): c:\code> listinherited.py <Instance of Sub, address 43359144: _ListInherited__attrnames=<bound method Sub.__attrnames ... ...__X names trimmed data1=spam data2=eggs data3=42 ham=<bound method Sub.ham of <testmixin.tester.<locals>.Sub ... spam=<bound method Sub.spam of <testmixin.tester.<locals>.Sub ... > c:\code> listinherited-reprfix.py <Instance of Sub, address 43549640: _ListInherited__attrnames=<<Method: __attrnames>> ...__X names trimmed data1=spam data2=eggs data3=42 ham=<<Method: ham>> spam=<<Method: spam>> > Folow-ups to lutz@rmi.net.

Shaopeng  Sep 03, 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 Author 
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 Author 
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 Author 
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 Author 
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
Page 1311
paragraph -2 (second last)

An expansion for clarity on decorator tradeoffs. On Page 1311, change the entire second last paragraph from: """ Decorators also promote code encapsulation to reduce redundancy and minimize future maintenance effort; although other code structuring tools do too, decorators add explicit structure that makes this natural for augmentation tasks. """ to this: """ Decorators also promote code encapsulation to reduce redundancy and minimize future maintenance effort; augmentation code appears just once in the decorator callable, instead of being copied for each deployment. Although manager functions can achieve this too, decorators also offer an explicit syntax and seamless call model that makes them natural for augmentation tasks. """ This should add 2 lines, there seems to be room on the page, but please contact me if this changes page breaks.

Mark Lutz
O'Reilly Author 
Oct 18, 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: "well also employ that third of the mix-in options" to: "well also employ the third of the mix-in options".

Mark Lutz
O'Reilly Author 
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 Author 
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 Author 
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 Author 
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 Author 
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