Errata

Fluent Python

Errata for Fluent 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
PDF
Page xviii
1st paragraph after title "Hands-On Approach"

replace # character with space in this snippet: read-eval-print#loop. I should be:
read-eval-print loop

Luciano Ramalho  Aug 30, 2015  Mar 25, 2016
???
Ch 14, Section "A Closer Look at the iter Function"

--------
A useful example is found in the iter built-in function documentation. This snippet reads lines from a file until a blank line is found or the end of file is reached:

with open('mydata.txt') as fp:
for line in iter(fp.readline, ''):
process_line(line)
--------

fp.readline will not return '' for a blank line, but rather '\n', so this snippet will actually process every line in the file. Code should be changed to

for line in iter(fp.readline, '\n'):

which may its own problems if the file does not end with a newline, OR the prose should be changed to remove "a blank line is found or"

Note from the Author or Editor:
The reader is correct. The issue appears on p. 436 of the PDF at the end of the section "A Closer Look at the iter Function". The bug is found in the official Python docs I quoted, so to fix the book we need to change the next to last paragraph in that section, as well as the code snippet. Here is the corrected text (using `` to enclose what should be in code font -- the `` must not be in the rendered text)

"""
The following snippet reads lines from a file until a blank line terminated with `'\n'`is found; if no such line is present, the `for` loop will run forever because `fp.readline()` returns an empty string `''` when the end of file is reached.

with open('mydata.txt') as fp:
for line in iter(fp.readline, '\n'):
process_line(line)

"""

Greg Back  Oct 16, 2015  Mar 25, 2016
unknown
Under Section II: Data Structures, Chapter 3: Dictionaries and sets, Subheader: dict and set under the hood, subsection: "Practical consequences of how dict works", item #1 "Keys must be hashable objects", in the "Warning" block

I could not provide a page number because I am working from a Rough Cut Safari reference that lacks page numbers.

The Warning states that "If you implement a class with a custom __eq__ method then you must also implement a suitable __hash__ [to satisfy the hash invariant] ... If a custom __eq__ depends on mutable state, then __hash__ must raise TypeError with a message like unhashable type: 'MyClass'". This is wrong. Per object.__hash__'s documentation ( https://docs.python.org/3/reference/datamodel.html#object.__hash__ ):

"A class that overrides __eq__() and does not define __hash__() will have its __hash__() implicitly set to None. When the __hash__() method of a class is None, instances of the class will raise an appropriate TypeError when a program attempts to retrieve their hash value, and will also be correctly identified as unhashable when checking isinstance(obj, collections.Hashable)."

So in fact, if you define __eq__ in a subclass, then you disable hashability by default, even if the superclass is hashable. You cannot violate the hash invariant accidentally; it can only be violated if a subclass defines __hash__ *explicitly* in a way that violates the hash invariant, the violation may be implicit; the inheritance relationship between __eq__ and __hash__ is not commutative, defining __hash__ alone does not prevent inheritance of a potentially conflicting __eq__ the way defining __eq__ alone prevents inheritance of __hash__.

This also means that the suggestion to explicitly define a __hash__ that raises TypeError for classes with logically mutable instances is a bad one for two reasons:

1. It adds unnecessary boilerplate to the class definition (if the class inherits object's __eq__ and __hash__, then it doesn't matter that it's mutable; identity checks won't be affected by mutable state)
2. It breaks the doc described isinstance(obj, collections.Hashable) check; by defining __hash__ at all, the class is now a virtual subclass of Hashable. Defining __eq__ and leaving __hash__ undefined/None would raise the same TypeError if you tried to hash it, *and* correctly return False when checking isinstance(obj, collections.Hashable), rather than the explicit definition returning True on the isinstance test, then failing when hashed.

A more accurate warning might be:

"To implement a hashable class, then instances of the class should be logically immutable, and if a == b is True, then hash(a) == hash(b) must also be True. If the superclass's __eq__ does not align with the subclass's definition of __hash__, then you must an appropriate __eq__ in the subclass."

Note from the Author or Editor:
The reader is correct. The error appears in the warning on page 90 of the PDF. To fix, we need change the whole warning to read like this (I'm using `` to denote code font; the `` should not be in the output):

"""
If you implement a class with a custom `__eq__` method, and you want the instances to be hashable, you must also implement a suitable `__hash__`, to make sure that when `a == b` is `True` then `hash(a) == hash(b)` is also `True`. Otherwise you are breaking an invariant of the hash table algorithm, with the grave consequence that dicts and sets will not handle your objects reliably. On the other hand, if a class has a custom `__eq__` which depends on mutable state, its instances are not hashable and you must never implement a `__hash__` method in such a class.
"""

Josh Rosenberg  Oct 27, 2015  Mar 25, 2016
???
Section II Data Structures, Chapter 2 "An array of sequences", subheader "When a list is not the answer", first paragraph

It's not exactly a mistake, but when you say "if you are constantly adding and removing items from the ends of a list as a FIFO or LIFO data structure, a deque (double-ended queue) works faster" you are lumping together claims of significantly different weight.

Using a list as a FIFO queue does sign you up for O(n) left side pops with .pop(0) vs. deque's O(1) .popleft(), so it starts slightly slower than a deque for small FIFO queues and becomes *much* slower as the number of elements increases (for my personal tests with a 100,000 element FIFO queue, popping 100 elements and then appending 100 over and over took 10-11 microseconds for a deque, and nearly five milliseconds for a list, a difference of 500x).

But for a LIFO stack, while list is slower under CPython 3.5's current implementation, it's not asymptotically slower, nor is the degree of slowdown sufficient to make the choice of deque an obvious one. The same test of popping then appending 100 elements (this time from the right in both cases, for LIFO behavior) showed the same 10-11 microsecond timing for deque, and a trivially higher 12-13 microsecond timing for list. Given that the difference in use is largely about how work is amortized (deque allocates and frees blocks of storage semi-frequently, list reallocates infrequently), the performance differences for the LIFO stack case are not meaningful, only the FIFO benefit of deque is meaningful enough to explicitly recommend incurring the import cost to import collections (a fairly heavyweight module) to get it.

Python's standard libraries support the choice of list for LIFO stacks too; while queue.Queue (FIFO) uses a deque for storage, queue.LifoQueue (LIFO) uses a list ( https://hg.python.org/cpython/file/v3.5.0/Lib/queue.py#l233 ), even though deque was already imported and available.

Note from the Author or Editor:
The reader is right. The problem is on p. 48 of the PDF, in the last sentence o the 1st paragraph of section "When a List Is Not the Answer". Let's change this:

"""
On the other hand, if you are constantly adding and removing items from the ends of a list as a FIFO or LIFO data structure, a deque (double-ended queue) works faster.
"""
To this:

"""
On the other hand, if you are constantly adding and removing items from opposite ends of a list as a FIFO data structure, a deque (double-ended queue) works faster.
"""



Josh Rosenberg  Oct 27, 2015  Mar 25, 2016
PDF,
Page ???
In "Sentence take #2: a classic iterator"

In two separate places, it's suggested that it is only "for convenience" and technical correctness that you'd implement "__iter__" on an iterator (returning self). It's more than just convenience, and should be stressed as a "always do this" requirement. The language implicitly calls iter() for a lot of basic stuff, if you're mixing explicit iteration with implicit iteration, failing to provide __iter__ on iterators will break the code. For example, a simple case where you consume the next element of an iterator without using it when the current element is special:

it = iter(someiterable)
for x in it:
if isspecial(x):
next(it, None)
... do other stuff with x ...

The above code would fail immediately when the for loop began if __iter__ was not defined for the iterator produced by someiterable. This comes up in some itertools recipes, and it's the reason that Iterator requires __iter__ to be defined (not just some coincidence of inheriting from Iterable).

Note from the Author or Editor:
The reader is correct. I looked at both passages mentioned and the second one does need fixing. The problem is in the tip/suggestion on the top of page 412 of the PDF. The tip icon should be changed to a warning icon (scorpion), and the text should be changed to read (using `` to denote code font, omit the `` on output):

An iterable should never act as an iterator over itself. In other words, iterables must implement `__iter__`, but not `__next__`.
On the other hand, iterators should always be iterable. An iterator’s `__iter__` should just return `self`.

Josh Rosenberg  Nov 02, 2015  Mar 25, 2016
PDF
Pages 627 and 653

Raymond Hettinger's first name is misspelled as "Reymond" twice in chapter 20

Luciano Ramalho
Luciano Ramalho
 
May 03, 2015  Jul 24, 2015
PDF
Page xxiii
2nd paragraph from bottom

Érico Andrei's first name is mispelled as "Erico" (missing acute accent on E)

Luciano Ramalho
Luciano Ramalho
 
May 03, 2015  Jul 24, 2015
PDF, ePub, Mobi
Page xix
First paragraph under "Python version covered"

"excpetion" should be "exception"

Note from the Author or Editor:
Noted for replacement in QC1.

Anonymous  May 07, 2015  Jul 24, 2015
Other Digital Version
I
Preface

I am not sure about that, but i think is GB instead of MB.


Neste trecho aqui:

Hardware used for timings

The book has some simple benchmarks and timings. Those tests were performed on one or the other laptop I used to write the book: a 2011 MacBook Pro 13” with a 2.7 GHz Intel Core i7 CPU, 8MB of RAM and a spinning hard disk, and a 2014 MacBook Air 13” with a 1.4 GHZ Intel Core i5 CPU, 4MB of RAM and a solid state disk. The MacBook Air has a slower CPU and less RAM, but its RAM is faster (1600 vs. 1333 MHz) and the SSD is much faster than the HD. In daily usage I can’t tell which machine is faster.

Erick Oliveira  Jul 15, 2015  Jul 24, 2015
PDF
Page 3
Epigraph

At the end of the quotation in the chapter epigraph there is the superscript 1 for the footnote, then the text "(O’Reilly, 2002), by Samuele Pedroni and Noel Rappin." That text should be in the footnote, not in the epigraph.

The epigraph quotation should end with the superscript 1, and the full text of the footnote should be:

Story of Jython, written as a Foreword to Jython Essentials O’Reilly, 2002), by Samuele Pedroni and Noel Rappin.

Luciano Ramalho  Aug 07, 2015  Aug 21, 2015
Printed, PDF
Page 7
Last code example section on the page

The word 'omitted' has an extra 'm' in it:

> (46 cards ommitted)

I noticed it in the printed version of the book and then double-checked the PDF sample chapter on the O'Reilly website here:

https://cdn.oreillystatic.com/oreilly/booksamplers/9781491946008_sampler.pdf

Both printed and sample PDF have the same typo.

Although I have just started reading the book, I am enjoying it very much!

Note from the Author or Editor:
change (46 cards ommitted) to (46 cards omitted) in ch01

Anonymous  Aug 05, 2016 
PDF
Page 13
Table 1-2

__lt__>,__le__<=,
should be
__lt__<,__le__<=,

Scott  Sep 06, 2015  Mar 25, 2016
PDF
Page 13
Table 1-2 Special method names ...

"rich compartison operators" should be "rich comparison operators"

Note from the Author or Editor:
Noted for replacement in QC1.

davidp314  May 07, 2015  Jul 24, 2015
PDF
Page 14
2nd paragraph under section Why len is not a method

The first ocurrence of the word len in this sentence appears in code font and italics:

"""
But thanks to the special method len, you can also make len work with your own custom objects.
"""

However it should not be italics, but should be in code font and written as __len__ (with two underscores on each side of the word).

Luciano Ramalho  Aug 07, 2015  Aug 21, 2015
Printed, PDF
Page 15
4th paragraph

'is covered' should be 'are covered'

Note from the Author or Editor:
I am not sure about this one -- it's a matter of English grammar.

Please have somebody with a solid grasp of English grammar review it and make the call.

Thanks!

Dean Draayer  Oct 10, 2015  Mar 25, 2016
PDF
Page 16
3rd paragraph - Metaobjects

The word 'protocol' is misspelled twice. First, in the book title as 'Procotol' and second in the second to last sentence of the paracraph as 'prococol'.

jefflefevre  Apr 28, 2015  Jul 24, 2015
Printed
Page 27
2nd line from top, Example 2-7

Callout 2 says population is in millions.

So this
> city, year, pop, chg, area = ('Tokyo', 2003, 32450, 0.66, 8014)

Should be this
> city, year, pop, chg, area = ('Tokyo', 2003, 32.450, 0.66, 8014)

Note from the Author or Editor:
Fixed for the 2nd edition: changed callout #2 text to say "population (thousands)" and used the opportunity to introduce new Python syntax allowing the use of _ to make numbers more readable: 32_450.

Tim Condit  Jan 27, 2017 
PDF
Page 30
"Tip box" on named tuples

I found the last sentence confusing. It states, of `namedtuple` types, "They use less memory than a regular object because they do store attributes in a per-instance __dict__."

Since named tuples store field names in the class, I assume they use less memory than objects because *objects* store attributes in a per-instance __dict__. That is, I assume the second "they" in that sentence refers to objects, not to named tuples. If this interpretation is right, then I would say that repeating "they" makes the sentence hard to parse, and that it would be much more clear to change the second "they" to "objects", for example. (If this interpretation is wrong, then it really isn't clear what the sentence is saying-- why would storing attributes per-instance in named tuples make them smaller?)

Note from the Author or Editor:
The sentence is confusing because where it says "do" it should be "don't". Noted for correction in QC1.

dml  Jun 02, 2015  Jul 24, 2015
Printed
Page 32
4th and 5th line

There is a line break in the midst of an identifier. It should be "City(*delhi_data)"; the line breaks after " del".

Note from the Author or Editor:
I did not find the error in the 3rd release PDF, but I noticed the offending line has a lot of extra space between words. For the second edition, I changed the wording of the line to avoid the issue reported and the extra spaces. The offending line is now in Chapter 5.

Brian van den Broek  Mar 13, 2016 
PDF
Page 32
First para under "Tuples as immutable lists"

This is a bit of a run-on sentence: "As you can see in Table 2-1, all list methods that do not involve adding or removing items are supported by tuple with one exception — tuple lacks the __reversed__ method, but that is just for optimization; reversed(my_tuple) works without it."

Maybe "As you can see in Table 2-1, tuple supports all list methods that do not involve adding or removing items, with one exception — tuple lacks the __reversed__ method. However, that is just for optimization; reversed(my_tuple) works without it."

Note from the Author or Editor:
Reader's phrasing is better. Noted for replacement in QC1.

dml  Jun 02, 2015  Jul 24, 2015
ePub
Page 32.7
United Kingdom

__str__ should return a string suitable to for displaying to end-users.

note 'to for'

Note from the Author or Editor:
"suitable to for displaying" should be "suitable for display"

Dave Pawson  Oct 06, 2014  Jul 24, 2015
ePub
Page 37
Footnote

“[4] I personally first heard “dunder” from Steve Holden. Wikipedia credits Mark Johnson and Tim Hochberg for the first written records of “dunder” in responses to the question “How do you pronounce __ (double underscore)?” in the python-list on September 26, 2002: Johnson’s message; Hochberg’s (11 minutes later).”

Excerpt From: Luciano Ramalho. “Fluent Python.” iBooks.


It is Mark Jackson not Mark Johnson

Note from the Author or Editor:
The offending passage was removed in the 2nd edition of Fluent Python.

Robert Livingston  Apr 05, 2016 
Mobi
Page 40
List of multiple choice answers

In the section "A += Assignment Puzzler" of the ePUB version, the list of multiple choice answers are numbered '1', '2', '3', '4'. The text in both item 4 and in the following paragraph refers to choices 'a', 'b' and 'd'.

The list is correctly labelled in the PDF version.

Note from the Author or Editor:
The reader reported the problem on the ePub version, but I checked and it's OK. The problem appears in the Kindle version, so maybe the reader confused ePub with Mobi.

Niall Creedon  Jan 08, 2016 
PDF
Page 42
Last sentence in tip with raven icon

Christian Clauss reported this as part of another errata item.

The term "Wikipedia's" is repeated here:

See Wikipedia’s Wikipedia’s “Fluent interface” entry for further description of this topic.

Luciano Ramalho
Luciano Ramalho
 
Feb 09, 2016  Mar 25, 2016
ePub
Page 50.5
United Kingdom

length equal to the lenghts of the input iterables

spelling

Note from the Author or Editor:
That is a spelling error: lenghts should be lengths

Dave Pawson  Oct 09, 2014  Jul 24, 2015
PDF, ePub
Page 51
First paragraph after the title Memory Views

In the very first sentence of Memory Views section author misspelled "memoryview" as "memorview"

Adylzhan  Aug 28, 2015  Mar 25, 2016
PDF, Mobi
Page 55
1st paragraph

I think ``.append`` and ``.pop`` give last-in first-out (LIFO) behaviour, and ``.append`` and ``.pop(0)`` in fact give first-in first-out (FIFO) behaviour, contrary to what it says in the paragraph.

Note from the Author or Editor:
The reader is correct. The text in parenthesis in the first sentence of section "Deques and Other Queues" should read:

"(if you use .append and .pop(0), you get FIFO behavior)".

lhuckvale  Oct 23, 2015  Mar 25, 2016
PDF
Page 55
1st paragraph under Deques and other queues, and again just before Table 2-3

In the first paragraph, it is stated that .append and .pop(0) get you LIFO behavior with a list. LIFO means a stack, not a queue, where you'd be mutating at the same end (that is, .append() and .pop(), not .append() and .pop(0)). Using .pop(0) would get you FIFO (queue) behavior (and entail all the performance issues mentioned that make deques the better option).

Later in the same section, the same mistake is made, it says (regarding deques) "The append and popleft operations are atomic, so deque is safe to use as a LIFO-queue in multi-threaded application...". Again, this should be FIFO-queue, not LIFO-queue; append adds to the right, popleft removes from the left, which is a FIFO design, not LIFO.

The former issue was already reported by lhuckvale on Oct 23rd, but I wanted to make sure both issues were reported.

Note from the Author or Editor:
This reader is reporting two wrong uses of the word LIFO where the correct would be FIFO. The first one has been reported and confirmed as an errata reported by lhuckvale (I wish the confirmed errata report displayed a link or an id next to each item).

The second wrong use of LIFO is on p. 56 in this sentence:

The append and popleft operations are atomic, so deque is safe to use as a LIFO queue in multithreaded applications without the need for using locks.

The correct would be

The append and popleft operations are atomic, so deque is safe to use as a FIFO queue in multithreaded applications without the need for using locks.

Josh Rosenberg  Oct 27, 2015  Mar 25, 2016
Printed
Page 58
text before Figure 2-5


" ... bisect is actually an alias for bisect_right, and there is a sister function called bisect_left. Their difference is apparent only when the needle compares equal to an item in the list: bisect_right returns an insertion point after the existing item, and bisect_left returns the position of the existing item, so insertion would occur before it. With simple types like int this makes no difference ..."

However, there can be a significant difference - at least with table lookups - as shown below in IPython with some changes to Example 2-18:

In [26]: def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
...: i = bisect.bisect_right(breakpoints, score)
...: return grades[i]

In [27]: [grade(score) for score in [60, 80, 77, 70, 89, 90, 100]]
Out[27]: ['D', 'B', 'C', 'C', 'B', 'A', 'A']

In [28]: def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
...: i = bisect.bisect_left(breakpoints, score)
...: return grades[i]

In [29]: [grade(score) for score in [60, 80, 77, 70, 89, 90, 100]]
Out[29]: ['F', 'C', 'C', 'D', 'B', 'B', 'A']

Note from the Author or Editor:
For the second edition I am using a modified example inspired by the reader's suggestion, and I will point out that in the lookup use case there is a big difference between using bisect_right and bisect_left.

Gregory Sherman  Feb 10, 2019 
PDF,
Page 62
footnote [28] for the 3rd bullet in the bullet list

The footnote (which is linked on page 62, at the end of the third bullet, but is actually rendered on page 67 in the Safari Books Online interface) reads:

"Thanks to Leonardo Rachael who went beyond his duties as tech reviewer and researched these Windows details, even though he is a GNU/Linux user himself."

The tech reviewer name is "Leonardo Rochael", not "Leonardo Rachael".

Note from the Author or Editor:
I found the error on page 126 of the PDF -- footnote 10 of Chapter 4. The reviewers last name is "Rochael" and NOT "Rachael" as I mistyped it.

Leonardo Rochael  Nov 09, 2015  Mar 25, 2016
PDF,
Page 62
3rd bullet in the bullet list

In the sentence

* "...but on Windows the syntax is more complicated: Language Name-Language Variant_Region Name.codepage>."

The ">" should not be there.

Note from the Author or Editor:
The issue appears in the third bullet at the bottom of page 125 in the PDF. Please remove the only > character that appears there, at the end of the code word `codepage`.

Leonardo Rochael  Nov 09, 2015  Mar 25, 2016
PDF
Page 63
Epigraph

Part of the source for the citation was omitted. If I recall correctly there was a footnote that is missing.

The source is this book:

Beautiful Code: Leading Programmers Explain How They Think
By Andy Oram, Greg Wilson (O'Reilly, 2007).

Note from the Author or Editor:
The epigraph should be credited like this, with a footnote giving the full reference:

-- A. M. Kuchling
Python's Dictionary Implementation: Being All Things to All People [1]

[1] Chapter 18 of Beautiful Code: Leading Programmers Explain How They Think, edited by Andy Oram and Greg Wilson (O'Reilly, 2007).

Luciano Ramalho  Sep 04, 2015  Mar 25, 2016
Printed
Page 68
code snippet

On this page (and later on page 71 I think) you have:

WORD_RE = re.compile('\w+')

This does work but IMO it is poor practice since it only works because \w doesn't happen to be a legitimate escape (unlike \a, \n, \t, etc.). Personally,, I aways write regexes using raw strings, i.e.,

WORD_RE = re.compile(r'\w+')

Note from the Author or Editor:
The reader is correct. That line of code is better written as

WORD_RE = re.compile(r'\w+')

That line appears and should be fixed in the following examples:
* 3-2 (p. 68)
* 3-4 (p. 69)
* 3-5 (p. 71)

Anonymous  Sep 23, 2015  Mar 25, 2016
PDF
Page 75
2nd paragraph

"... Maintains keys in insertion order, allowing iteration over items in a predictable
order. The popitem method of an OrderedDict pops the first item by default, but
if called as my_odict.popitem(last=True) , it pops the last item added."

The popitem method of an OrderedDict pops the last item by default not the first one.

https://docs.python.org/3.4/library/collections.html#collections.OrderedDict.popitem

Note from the Author or Editor:
The last sentence of the collections.OrderedDict entry (2nd paragraph of page 75 in PDF) should be changed in three places to read like this:

The `popitem` method of an `OrderedDict` pops the last item by default, but if called as `my_odict.popitem(last=False)`, it pops the first item added.

Marco Badan  Jan 02, 2016  Mar 25, 2016
PDF
Page 90
Items 1 and 2 under heading "Keys must be hashable objects"

Two method names mentioned in items 1 and 2 are special method names and should be written with leading and trailing doule-underscores, as shown here:

1. It supports the hash() function via a __hash__() method that always returns the same value over the lifetime of the object.
2. It supports equality via an __eq__() method.

Luciano Ramalho  Sep 09, 2015  Mar 25, 2016
PDF
Page 94
1st paragraph under Further Reading

There are missing double underscores in the __init__.py filename in this path:

Lib/collections/init.py

It should read:

Lib/collections/__init__.py

BTW, this is a widespread problem because of the conflict between the Python use of double underscores and their meaning in asciidoc...

Luciano Ramalho  Sep 09, 2015  Mar 25, 2016
Printed, PDF
Page 94
3rd paragraph under Further Reading

Missing a closing double-quote after Being All Things to All People

Dean Draayer  Oct 10, 2015  Mar 25, 2016
Printed, PDF
Page 94
3rd paragraph under Further Reading

Need a space between "dictobject.c" and "CPython"

Dean Draayer  Oct 10, 2015  Mar 25, 2016
PDF
Page 100
General Note

The text of the general note states "For every other sequence,
s[i] returns one item, and s[i:i+1] returns a sequence of the same
type with the s[1] item inside it."

Shouldn't this be "..with the s[i] item inside it" ?

Note from the Author or Editor:
The reader is correct. The corrected sentence should read:

"""
For every other sequence, s[i] returns one item, and s[i:i+1] returns a sequence of the same type with the s[i] item inside it.
"""

James Maringa  Oct 07, 2015  Mar 25, 2016
PDF
Page 128
caption for Figure 4.3

At the end of the caption for Figure 4.3:

* The first single-quote is straight, but the second single-quote is curly.

* The semicolon character that ends the caption should be removed.

Note from the Author or Editor:
I confirm those issues as reported. In addition, in the same portion of the caption, the expression r'\d' should appear in a code font, with both single-quotes straight, not curly.

John Posner  Sep 20, 2015  Mar 25, 2016
PDF
Page 143
Middle of page

any(iterable)
return True if any element of the iterable is truthy; all([]) returns False.

should be

any(iterable)
return True if any element of the iterable is truthy; any([]) returns False.

Note from the Author or Editor:
Noted for replacement by author in QC1: all([]) should be any([]) as noted by reader.

Timothy Knox  Jun 04, 2015  Jul 24, 2015
Printed, PDF
Page 166
Footnote 3

"There also" should be "There is also".

Note from the Author or Editor:
The problem reported is in footnote #3 of p. 164 of the PDF. The word "is" is missing from this sentence:

There is also the problem of lost indentation [...]

Dean Draayer  Jan 23, 2016  Mar 25, 2016
PDF
Page 180
first line

The sentence "...as end-points instead of steps in the design patterns." should be "...as end-points instead of steps in the design process."

Note from the Author or Editor:
Confirmed issue. To be clear, the full sentence within quotes should be:

“Too much emphasis on patterns as end-points instead of steps in the design process.”

Luciano Ramalho  Sep 20, 2015  Mar 25, 2016
PDF, ePub, Mobi
Page 183
2nd paragraph

"enhance their behavior is some way" should be "enhance their behavior in some way"

Note from the Author or Editor:
This is already solved.

Farhad Fouladi  Sep 16, 2015  Mar 25, 2016
Printed, PDF
Page 183
4th paragraph

"In spite of many the differences..." transpose "many" and "the".

Note from the Author or Editor:
This issue is on p. 181 of the PDF, 4th paragraph, last sentence. We'll fix it a little differently than suggested by the reader. The correct sentence would be:

In spite of their many syntactic differences, at the semantic level Python and Ruby are closer to each other than to Java or C++.

Dean Draayer  Jan 23, 2016  Mar 25, 2016
PDF
Page 184
United Kingdom

@decorate
def target():
print('running target()')


returns error

raceback (most recent call last):
File "7.1.py", line 3, in <module>
@decorate
NameError: name 'decorate' is not defined


Note from the Author or Editor:
That code is not intended to be executed, it's only there as an illustration to say that this:
@decorate
def target():
print('running target()')

Means the same as this:

def target():
print('running target()')

To clarify, I have added the text "assuming an existing decorator named `decorate` to the paragraph right before the first snippet.
target = decorate(target)

Dave Pawson  Jun 18, 2015  Jul 24, 2015
Printed, PDF
Page 191
1st line

"...take a step back a have a close look..." change "a" to "and" between "back" and "have".

Note from the Author or Editor:
Issue on p. 189 of PDF. Please correct as suggested by reader.

Dean Draayer  Jan 23, 2016  Mar 25, 2016
Printed, PDF
Page 192
code of 4th paragraph

Not sure where the 2nd input of f3(3) and b, and their outputs, are coming from. Is it a typo? Or is code missing? As seen below:
>>>f3(3)
a = 3
b = 8
b = 30
>>> b
30
>>>

Note from the Author or Editor:
The reader is correct, there is extraneous code in the snippet. The code appears in p. 190 of the PDF. The full snippet should be (note that there 5 spaces after each ... in the code):

>>> b = 6
>>> def f3(a):
... global b
... print(a)
... print(b)
... b = 9
...
>>> f3(3)
3
6
>>> b
9

Lung Chen  Oct 14, 2015  Mar 25, 2016
PDF
Page 212
Second paragraph of Further Reading

Graham Dumpleton informs that the best link for his blog posts about decorators starting with "How you implemented your Python decorator is wrong" is this page:

https://github.com/GrahamDumpleton/wrapt/blob/develop/blog/README.md

Luciano Ramalho
Luciano Ramalho
 
May 06, 2015  Jul 24, 2015
PDF
Page 228
3rd paragraph

In this paragraph the words "we will create" appear twice:

Now in the interactive Example 8-9 we will create we will create a bus object (bus1) and two clones—a shallow copy (bus2) and a deep copy (bus3)—to observe what happens as bus1 drops off a student.

Luciano Ramalho  Sep 23, 2015  Mar 25, 2016
PDF
Page 232
1st paragraph after callout #7

The name "Bus" is wrong, it should be "HauntedBus". The paragraph should read:

"""
The problem is that HauntedBus instances that don’t get an initial passenger list end up sharing the same passenger list among themselves.
"""

Luciano Ramalho  Sep 29, 2015  Mar 25, 2016
Printed
Page 242
2nd paragraph

Second paragraph, second line:

"other Python iterpreters." should be "interpreters."

Ricardo Muñoz Fernández  Feb 12, 2016  Mar 25, 2016
PDF
Page 265
Last sentence in 2nd paragraph

This can make a huge difference in memory usage if you(r) have millions of instances active at the same time. ^

Remove the 'r' making it read ' if you have millions . . .'

Note from the Author or Editor:
The reader is right. Please remove trailing "r" as described.

Steven Young  Nov 30, 2015  Mar 25, 2016
PDF
Page 267
2nd paragraph

On page 267 of the 2nd revision PDF there are two paragraphs starting with "To summarize, __slots__...". To eliminate this repetition, I'd like to change the second paragraph to use this wording:

"""
The __slots__ class attribute may provide significant memory savings if properly used, but there are a few caveats:
"""

Thanks!

Luciano Ramalho
Luciano Ramalho
 
Feb 04, 2016  Mar 25, 2016
Printed
Page 268
Scorpion aside, last sentence

"__slots__ should used for..." insert "be" before "should".

Note from the Author or Editor:
Issue on p. 266 of the PDF, last sentence of warning. Add the word "be" after "should". Correct sentence is (using `` to denote code font):

`__slots__` should be used for optimization, not for programmer restraint.

Dean Draayer  Jan 23, 2016  Mar 25, 2016
PDF
Page 276
3rd paragraph in 'Vector Applications Beyond Three Dimensions"

The PyPI package 'gemsim' should be spelled 'gensim'

Note from the Author or Editor:
Please correct as described. The package name "gensim" was misspelled as "gemsim" (but the link on the word has the correct URL).

Steven Young  Dec 02, 2015  Mar 25, 2016
Printed, PDF
Page 283
1st paragraph

"...Vector instance and not a array": change "a" to "an".

Note from the Author or Editor:
Issue on p. 281 of PDF, 1st paragraph, 2nd period. Please fix as suggested by reader.

Dean Draayer  Jan 23, 2016  Mar 25, 2016
Printed, PDF
Page 292
Last sentence on page

The last sentence on the page reads:

As implemented, the __hash__ method in Example 10-8 is a perfect example of a mapreduce computation (Figure 10-2).

The example cited is wrong. This sentence should read:

As implemented, the __hash__ method in Example 10-12 is a perfect example of a mapreduce computation (Figure 10-2).

Note from the Author or Editor:
Issue on p. 292 of PDF, last sentence on page. Please fix as described by user.

Please make sure the link in "Example 10-12" also points to Example 10-12.

MacBent  Jan 24, 2016  Mar 25, 2016
PDF
Page 302
End of the second paragraph

In the final sentence of the second paragraph in chapter 10, it states:

"...and look at organizing multiple classes with interfaces and inheritance, the subjects of Chapters 11 and 11."

Note the duplicate references to Chapter 11. The "11's" are both in-text links to Chapter 11 as well.

Note from the Author or Editor:
The error is in the last sentence of the 2nd paragraph, right before "Further Reading" on p. 302. The end of the sentence should read:

"""...organizing multiple classes with interfaces and inheritance, the subjects of Chapters 11 and 12."""

Also, please check that the links on 11 and 12 point to the correct chapters.

Anonymous  Nov 04, 2015  Mar 25, 2016
PDF
Page 303

The Evan Simpson code on page 303 appears to have been copied transcribed incorrectly. It states:

>> t = 0
>> for sub in my_list:
. . . total += sub[1]
>>> t
60

I think 't' was supposed to be 'total' or vice-versa as 'total' was never defined.

Note from the Author or Editor:
The reader is correct. The snippet on top of page 305 on the PDF should read like this (note: there are 5 spaces between ... and total on the 3rd line):

>>> total = 0
>>> for sub in my_list:
... total += sub[1]
...
>>> total
60

Anonymous  Nov 04, 2015  Mar 25, 2016
PDF
Page 306
the code of the 3rd paragraph

functools.reduce(lambda a, b: a+b, [sub[1] for item in my_list])
The correct code should be:
functools.reduce(lambda a, b: a+b, [sub[1] for sub in my_list])

Note from the Author or Editor:
Noted for change by author in QC1

Ziwei Xue  Jun 12, 2015  Jul 24, 2015
PDF
Page 309
last paragraph

Fix the missing closing quotation mark after "support the buffer protocol" in the following text:

As I write this, the Python 3 documentation of memoryview says that it works with objects
that “support the buffer protocol, which is only documented at the C API level.

The text referenced in the Python 3 documentation is "Create a memoryview that references obj. obj must support the buffer protocol. Built-in objects that support the buffer protocol include bytes and bytearray."

Note from the Author or Editor:
The reader is right. To clarify, the correction is to add closing double quotation mark after the word protocol in this sentence:

As I write this, the Python 3 documentation of memoryview says that it works with objects that “support the buffer protocol”, which is only documented at the C API level.

Jeff Trawick  Sep 22, 2015  Mar 25, 2016
PDF
Page 311
2nd paragraph

The word "of" is missing after the word "absence" in the following sentence:

In summary, given the importance of the sequence protocol, in the absence __iter__
and __contains__ Python still manages to make iteration and the in operator work by
invoking __getitem__.

Note from the Author or Editor:
The reader is right. The corrected sentence would be:

In summary, given the importance of the sequence protocol, in the absence of __iter__ and __contains__ Python still manages to make iteration and the in operator work by invoking __getitem__.

Jeff Trawick  Sep 22, 2015  Mar 25, 2016
PDF
Page 311

f[1] is called before f is assigned to the Foo class.

Note from the Author or Editor:
In example 11-3, the first four lines on top of page 310 are:

...
>>> f[1]
10
>>> f = Foo()

However, they should be:

...
>>> f = Foo()
>>> f[1]
10


In other words, the `f = Foo()` expression should appear before the `f[1]` expression.

Anonymous  Nov 04, 2015  Mar 25, 2016
Printed, PDF
Page 311
Last paragraph

"… accepts an 'an …"; appears to be an extra "an".

Note from the Author or Editor:
The error is on page 309 of the PDF. The full sentence is:

"""
The bytearray constructor accepts an “an object conforming to the buffer interface.”
"""

Please remove the first occurrence of the word 'an' in that sentence.

mike  Nov 27, 2015  Mar 25, 2016
PDF
Page 313
callout #3

Replace word "sorted" with "shuffled" in callout #3. Corrected text will start with:

"""
deck can now be shuffled because...
"""


Luciano Ramalho  Sep 30, 2015  Mar 25, 2016
PDF
Page 318
1st paragraph, 8th line

The function name "isinstance" is mispelled as "insinstance".

Luciano Ramalho  Oct 17, 2015  Mar 25, 2016
PDF
Page 322
MappingView entry

the identifier ValuesView appears twice in that paragraph, but the first occurrence should be KeysView. The corrected sentence should read:

In Python 3, the objects returned from the mapping methods .items(), .keys(), and .values() inherit from ItemsView, KeysView, and ValuesView, respectively.

Note from the Author or Editor:
Besides the error mentioned above, there is another conceptual error in the paragraph for MappingView (4th paragraph on page 322). To fix both issues, I'd like to rephrase the first sentence of that entry like this:

"""
In Python 3, the objects returned from the mapping methods .items(), .keys(), and .values() are instances of ItemsView, KeysView, and ValuesView, respectively.
"""

Luciano Ramalho  Oct 17, 2015  Mar 25, 2016
PDF
Page 322
Figure 11-3

In the diagram, the rectangles in the lower right corner labeled KeysView and ValuesView are swapped.

To correct, just swap those two rectangles.

To clarify, in the corrected diagram we should have:

1) KeysView rectangle next to ItemsView; KeysView connected to the Set and MappingView rectangles.

2) ValuesView as the rightmost rectangle, connected only to the MappingView rectangle.

Luciano Ramalho
Luciano Ramalho
 
Feb 04, 2016  Mar 25, 2016
PDF
Page 325
last paragraph

So here is our our context
should be:
So here is our context

Note from the Author or Editor:
Duplicate word "our" marked for deletion in author QC1 review.

beeshu  Jun 13, 2015  Jul 24, 2015
Printed, PDF
Page 342
End of first paragraph

"… OrderedDict, which preserves the insertion order, but which does [does not?] support item retrieval by offset either."

Note from the Author or Editor:
The problem is in the last part of the 1st paragraph on page 340 of the PDF. Please change "does" to "does not". The corrected text is:

-- except of course for OrderedDict, which preserves the insertion order, but does not support item retrieval by offset either.

mike  Nov 27, 2015  Mar 25, 2016
PDF
Page 343
the second last sentence in the second last paragraph

the decorator name from the ABC module is misspelled: @abtractmethod instead of @abstractmethod

Note from the Author or Editor:
The reader is correct. Please change @abractmethod to @abstractmethod

Anonymous  Jul 25, 2015  Aug 21, 2015
PDF
Page 352
1st paragraph under the code example

because the versions inherited from dict refused to cooperate with with the overridden ...
should be:
because the versions inherited from dict refused to cooperate with the overridden ...

Note from the Author or Editor:
Fixed prior to QC1.

beeshu  Jun 13, 2015  Jul 24, 2015
PDF
Page 354
Callouts #2 and #4 in example 12-7

In callouts #2 and #4 for Example 12-7 the calls super.ping() should be written as super().ping().

Luciano Ramalho  Oct 01, 2015  Mar 25, 2016
PDF
Page 356
Caption of figure 12-2

The last words of the caption are Text.mro. It should be Text.__mro__ (with two underscores on each side of mro).

Luciano Ramalho  Oct 01, 2015  Mar 25, 2016
Printed
Page 357
Footnote #4

"In Python 2, the first [second?] line of D.pingpong …"

Note from the Author or Editor:
The reader is right. Please replace 'first' with 'second' on footnote 4 on page 353 of the PDF. The corrected footnote should read:

4. In Python 2, the second line of D.pingpong would be written as super(D, self).ping() rather than super().ping()

mike  Nov 27, 2015  Mar 25, 2016
Printed, PDF
Page 357
Code example at bottom of page

The call to d.pingpong() is unnecessarily repeated. ie

>>> from diamond import D
>>> d = D()
>>> d.pingpong()
>>> d.pingpong()
ping: <diamond.D object at 0x10bf235c0>
...

Should be

>>> from diamond import D
>>> d = D()
>>> d.pingpong()
ping: <diamond.D object at 0x10bf235c0>
...

Note from the Author or Editor:
Issue on Example 12-7, p. 353 of the PDF.

This duplication is an error, we only need one occurrence of that line:

>>> d.pingpong()
>>> d.pingpong()

MacBent  Jan 24, 2016  Mar 25, 2016
Printed, PDF
Page 369
2nd paragraph

"Thats' [That's?] why the BaseListView exists."

Note from the Author or Editor:
The error is on p. 365 of the PDF. In the 2nd sentence of the 2nd full paragraph, the apostrophe in "Thats'" is misplaced. This is the corrected text

Suppose you want to create a view that will not render a template, but will produce a list of objects in JSON format. That's why the BaseListView exists. [...]

mike  Nov 27, 2015  Mar 25, 2016
PDF
Page 382
callout #3

Callout #3 states:

(3) Otherwise, raise TypeError with an explicit message.

Although that may be the end result of the code in the example in many cases, a better explanation for the code is this:

(3) Otherwise, return NotImplemented, to let Python try __rmul__ on the scalar operand.

Note from the Author or Editor:
Callout #3 does not describe what is in the code. Please replace it with the text suggested in the description of this item. Also, please make sure the double-underscores around __rmul__ are visible in the rendered text.

<3> Otherwise, return NotImplemented, to let Python try __rmul__ on the scalar operand.

Luciano Ramalho  Oct 01, 2015  Mar 25, 2016
Printed, PDF
Page 383
Paragraph "In the spirit…"

"… returns NotImplemented, then Python will raise issue [superfluous 'issue'?] TypeError …"

Note from the Author or Editor:
The issue is on page 379 of the PDF, in the next to last paragraph. In this sentence, please remove the word "issue":

If the reverse method call returns NotImplemented, then Python will raise *issue* TypeError with a standard error message

mike  Nov 27, 2015  Mar 25, 2016
Printed, PDF
Page 396
callout list

There are 8 items in the list, but 9 callouts in the preceding code block. Is there a missing explanation?

Note from the Author or Editor:
The problem appears in Example 13-18, on p. 391 of the PDF. But the source of the problem is in the example file bingoaddable.py (in the chapter 14 folder -- I lost track of the folders and file names after the production team renamed them all...).

On line 66 of that file there is a callout # <6> which should not be there -- notice that it's out of order, and the correct # <6> is on line 76. Just remove that # <6> from line 66 and everything should be fine. The listing should have only 8 callouts.

O'Reilly Media
 
Jan 14, 2016  Mar 25, 2016
PDF
Page 407
Caption of figure 14-1

Yet another case of missing __x__.These errors were introduced in production, after the writing and tech review stages were done...

In this case, there are missing double-underscores in the following places of the caption for Figure 14-1:

A concrete Iterable.iter --> A concrete Iterable.__iter__
implement next --> implement __next__
The Iterator.iter --> The Iterator.__iter__

Luciano Ramalho  Oct 01, 2015  Mar 25, 2016
PDF
Page 409
section title

The section title reads:

Sentence Take #2: A Classic Interior

But it should be:

Sentence Take #2: A Classic Iterator

Luciano Ramalho  Aug 07, 2015  Aug 21, 2015
PDF
Page 409
1st paragraph of "Making Sentence an iterator: bad idea"

The paragraph reads:

A common cause of errors in building iterables and iterators is to confuse the two. To
be clear: iterators have a __iter__ method that instantiates a new iterator every time.
Iterators implement a __next__ method that returns individual items, and a __iter__
method that returns self.

However, it should be *iterables* that have an __iter__ method that instantiates a new iterator every time.

Note from the Author or Editor:
Fixed during a previous review.

jcdyer  Jun 17, 2015  Jul 24, 2015
Printed, PDF
Page 416
Code explanation #1

"Iterate over self.word [self.words?]"

Note from the Author or Editor:
The issue is callout #1 of Example 14-5 (p. 412 of the PDF). The text should read:

<1> Iterate over self.words

mike  Nov 27, 2015  Mar 25, 2016
PDF
Page 417
The third line of footnote.

the return value from from the exception object.
should be:
the return value from the exception object.

Note from the Author or Editor:
Duplicate word "from" in the footnote.

beeshu  Jun 14, 2015  Jul 24, 2015
Printed, PDF
Page 424
3rd paragraph

-----
Also, because generator functions have a name, they can be reused. You can always name a generator expression and use it later by assigning it to a variable, of course, but that is stretching its intended usage as a one-off generator.
-----

You actually cannot name a generator expression - you can just name the generator produced by evaluating a generator expression.

The lines above make it look like a form of re-use is possible, but outside of "intended usage"; when in fact re-using a generator expression isn't possible at all. I suggest changing the wording here to make that clear.

Note from the Author or Editor:
The reader is correct. The best fix is to DELETE the entire sentence below, which appears at the end of the 2nd full paragraph on p. 420 of the PDF (section title "Generator Expressions: When to Use Them")

You can always name a generator expression and use it later by assigning it to a variable, of course, but that is stretching its intended usage as a one-off generator.

Kevin Christopher Henry  Feb 01, 2016  Mar 25, 2016
Printed, PDF
Page 426
Footnote 9

The bitly link here is to the wrong Steven D'Aprano post. I think you meant this one: https://mail.python.org/pipermail/python-list/2014-December/682658.html.

Note from the Author or Editor:
The reader is right, and the link is also wrong in the PDF. I discovered too late that URLs in the mail.python.org mailing lists are not permanent... they point to different messages over time.

Here is an URL for another archive that has the same message, let's hope it's a permanent URL:

https://marc.info/?l=python-list&m=141826925106951&w=2

Kevin C  Feb 01, 2016  Mar 25, 2016
PDF, ePub, Mobi
Page 436
5th paragraph

"to roll a six-sided die until a 1 is rolled" should be "to roll a six-sided dice until a 1 is rolled"

Note from the Author or Editor:
The reader is correct, according to the Oxford Dictionary "Historically, dice is the plural of die, but in modern standard English, dice is both the singular and the plural: throw the dice could mean a reference to two or more dice, or to just one. In fact, the singular die (rather than dice) is increasingly uncommon."

The full sentence is the 3rd paragraph in section "A Closer Look at the iter Function". The corrected sentence should read:

The following example shows how to use iter to roll a six-sided dice until a 1 is rolled:

Farhad Fouladi  Nov 02, 2015  Mar 25, 2016
Printed
Page 459
4th paragraph

In '...at the beginning of the while block...', the 'while' should be 'with'.

Note from the Author or Editor:
The reader is correct. In the PDF, the error is on p. 455, in the 2nd paragraph of the section titled Using @contextmanager.

The code word "while" should be "with" in this snippet:

everything before the yield will be executed at the beginning of the while block

The corrected text is:

everything before the yield will be executed at the beginning of the with block

Dean Draayer  Oct 10, 2015  Mar 25, 2016
PDF
Page 473
2nd paragraph after code example

"[...] is designed to work with *yield form* [...]" should read should read "[... is designed to work with *yield from* [...]".

Volker Schmitz  Jul 22, 2015  Aug 21, 2015
PDF
Page 481
Footnote

Paul Sokolovsky's name is misspelled as Sokolovksy on page 481 and twice on page 502.

Luciano Ramalho  May 05, 2015  Jul 24, 2015
Printed, PDF
Page 488
Last paragraph

"The client code drives delegating [the delegating?] generator …"

Note from the Author or Editor:
The issue is on p. 484 of the PDF, in the last paragraph, second sentence. The article "the" is missing where highlighted here:

The client code drives *the* delegating generator, which drives the subgenerator.

mike  Nov 27, 2015  Mar 25, 2016
Printed, PDF
Page 490
Second-to-last paragraph

"… syntax-highlighted and annotated". The print edition doesn't have syntax highlighting.

Note from the Author or Editor:
The issue is on page 486 of the PDF, next-to-last paragraph, 1st sentence. Please change this:

...PEP 380, syntax-highlighted and annotated.

to this:

...PEP 380, with numbered annotations.

mike  Nov 27, 2015  Mar 25, 2016
ePub, Mobi
Page 493
Figure 1-1 (the "page number" above is the Kindle location)

The background for the image in Figure 1-1 should be white but is black in the .epub and .mobi files -- but it's white in the .pdf.

The black background is not only ugly and reveals aliasing artifacts, but it hides the x and y axis in the graph, which were drawn in black.

Luciano Ramalho  Sep 10, 2015  Mar 25, 2016
Printed, PDF
Page 493
Last line of the general note

"… when we tackle asyncio with [unnecessary 'with'?] in Chapter 18".

Note from the Author or Editor:
Issue on page 489 of the PDF. The tip inside section "Use Case: Coroutines for Discrete Event Simulation" has a needless word "with" in its last sentence, right after the word "asyncio".

mike  Nov 27, 2015  Mar 25, 2016
Printed, PDF
Page 495
Figure 16-3 caption

"Colored arrows highlight taxi trips". No color in the printed version.

Note from the Author or Editor:
This issue is on p. 491 of the PDF. Fixing it requires two actions:

1) replace the image in Figure 16-3 with one of taxi-sim-arrows.pdf or taxi-sim-arrows.png which I sent to Kristen Brown of Feb. 7.

2) change the last sentence of the caption for that figure to read:

Solid or dashed arrows highlight the trips of each taxi.

mike  Nov 27, 2015  Mar 25, 2016
PDF
Page 502
3rd paragraph of Further Reading

Paul Sokolovsky is a contributor to MicroPython; the main author is Damien George. Therefore, the word "his" should be changed to "the" in this sentence:

"""
Paul Sokolovsky implemented yield from in his super lean MicroPython interpreter designed to run on microcontrollers.
"""

Luciano Ramalho
Luciano Ramalho
 
May 05, 2015  Jul 24, 2015
Printed, PDF
Page 532
Code explanation #3

"Reuse the dnowload_one [download_one] from …"

Note from the Author or Editor:
The issue is in Example 17-14, callout #3, on p. 528 of the PDF.

The code word `download_one` is misspelled as `donwload_one`.

mike  Nov 27, 2015  Mar 25, 2016
Printed, PDF
Page 536
Last paragraph

"While the GIL is [a] real problem …"

Note from the Author or Editor:
The issue is on p. 532 of the PDF. The word "a" is missing from the first sentence of the last paragraph on that page:

While the GIL is *a* real problem and is not likely to go away soon

mike  Nov 27, 2015  Mar 25, 2016
PDF
Page 546
1st and 9th paragraphs

The `.result()` method name is misspelled as `.results()` twice in this page -- the second time the word is split as `.re` and `sults()`.

Luciano Ramalho  Jan 04, 2016  Mar 25, 2016
PDF
Page 552
Section title

The title of the section "Running Circling Around Blocking Calls" should be "Running Circles Around Blocking Calls"

Luciano Ramalho  Oct 08, 2015  Mar 25, 2016
PDF
Page 554
2nd paragraph

In the last period, the identifier download_flag should be download_one. The full period should read:

As each get_flag returns, the delegating generator download_one resumes and saves the image file.

Luciano Ramalho  Oct 13, 2015  Mar 25, 2016
Printed
Page 559
1st paragraph under "Using asyncio.as_completed"

"… when driven by loop.run_until.complete [loop.run_until_complete] …"

Note from the Author or Editor:
page 555 of PDF, 1st paragraph of section "Using asyncio.as_completed". The code word "loop_until_complete" is misspelled with a dot "." instead of the second underscore ".". The corrected text is:

In Example 18-5, I passed a list of coroutines to asyncio.wait, which—when driven by loop.run_until_complete [...]

mike  Nov 27, 2015  Mar 25, 2016
PDF
Page 595
1st paragraph, last sentence

Word missing between 'rarely' and 'to': '[...] -- which we rarely to code because [...]' should maybe read "[...] which we rarely need to code [...]'

Volker Schmitz  Jul 23, 2015  Jul 24, 2015
PDF
Page 598
description of item (2)

'DbRecord.get' should be 'DbRecord.fetch' according to the code above

Note from the Author or Editor:
The reader is correct. Text of callout #2 in this page should start with "The DbRecord.fetch..." and not "The DbRecord.get".

Anonymous  Aug 06, 2015  Aug 21, 2015
PDF
Page 601
1st paragraph after 'Event' description, end of first sentence

'[...] that depend in it.' should read '[...] that depend on it.'

Volker Schmitz  Jul 24, 2015  Aug 21, 2015
PDF
Page 603
In descriptions of items 3, 5 and 6

In the code at the top of the page, the __db class attribute has two underscores. In the text of items 3, 5 and 6, only one underscore is used.

Volker Schmitz  Jul 24, 2015  Aug 21, 2015
PDF
Page 605
middle of page (3rd paragraph)

'__gettarr__' should be '__getattr__'

Volker Schmitz  Jul 24, 2015  Aug 21, 2015
Printed, PDF
Page 613
Callout #5

'attr' should be 'data'? (see Example 19-19).

Note from the Author or Editor:
The error is in Example 19-20 on page 609 of the PDF. There are two problems:

1) in the code listing, the code and response sequence marked with callout #5 should be:

>>> vars(obj) # <5>
{'data': 'bar', 'prop': 'foo'}

2) In the #5 callout below the listing, the text should be (using `` to indicate code font):

<5> We can see that `obj` now has two instance attributes: `data` and `prop`.

mike  Nov 27, 2015  Mar 25, 2016
PDF
Page 615
Last paragraph before Example 19-25

I think it should read 'In Example 19-25 I create and inspect a LineItem [...]' instead of 19-24.

Volker Schmitz  Jul 24, 2015  Jul 24, 2015
Printed, PDF
Page 616
2nd paragraph

"… so when quantity() is invoked, the price [weight?] class attribute doesn't even exist." 'price' is valid, but 'weight' was used in the previous paragraph.

Note from the Author or Editor:
The issue is on page 612 of the PDF. We need to replace the code word `price` with `weight` in the last sentence. The full paragraph, corrected, reads:

But avoiding that repetition is complicated because the property has no way of knowing which class attribute name will be bound to it. Remember: the right side of an assignment is evaluated first, so when `quantity()` is invoked, the `weight` class attribute doesn’t even exist.

mike  Nov 27, 2015  Mar 25, 2016
PDF
Page 616
First paragraph after enumeration

middle of sentence: 'reverence' --> 'reference'

Volker Schmitz  Jul 24, 2015  Aug 21, 2015
Printed, PDF
Page 619
Last paragraph

"… we'll review some [of?] the core APIs …"

Note from the Author or Editor:
Issue on p. 615 of PDF, last paragraph, missing the word "of" highlighted below:

In the final section of this chapter, we’ll review some *of* the core APIs that Python offers for dynamic attribute programming.

mike  Nov 27, 2015  Mar 25, 2016
PDF
Page 619
end of page, paragraph starting with 'Attribute access ...'

'gettattr' should be 'getattr'

Volker Schmitz  Jul 25, 2015  Jul 24, 2015
PDF
Page 620
explanation of __getattribute__

2nd sentence: 'gettattr' should read 'getattr'
3rd sentence: '__gatattribute__' should read '__getattribute__' (twice)

Volker Schmitz  Jul 25, 2015  Jul 24, 2015
PDF
Page 620
end of page, explanation of __setattr__

2nd sentence: 'settattr' should be 'setattr'

Volker Schmitz  Jul 25, 2015  Aug 21, 2015
PDF
Page 637
1st paragraph, 1st line

The word "The" is missing the initial "T":

"?he imaginary organic food store..."

Luciano Ramalho  Oct 15, 2015  Mar 25, 2016
PDF
Page 643
Caption of Example 20-10

Once again, __ (double underscores) that should appear around a special method identifier were removed during production. The first occurrence of the word "get" in the caption of Example 20-10 must appear as __get__:

Example 20-10: Overriding descriptor without __get__: ...

Luciano Ramalho  Oct 15, 2015  Mar 25, 2016
PDF
Page 655
2nd paragraph after citation

To my knowledge, class decorators have been introduced to Python with version 2.6 (see https://docs.python.org/2/whatsnew/2.6.html#pep-3129-class-decorators).
--> Change "Python 3" to "Python 2.6"

Note from the Author or Editor:
The reader is correct. Please change Python 3 to Python 2.6 as indicated.

Volker Schmitz  Aug 10, 2015  Mar 25, 2016
PDF
Page 664
Example 21-7

These comments should be removed from the listing.

# BEGIN META_ALEPH

# END META_ALEPH

They do not interfere with the operation of the code, but are asciidoc include markers which were not used after all.

Luciano Ramalho  Oct 15, 2015  Mar 25, 2016
PDF
Page 665
Example 21-8, callout #2

In the source code, MetaAleph is a class, not a function, so the text for callout #2 should be:

(2) The body of the MetaAleph class does run.

Luciano Ramalho  Oct 15, 2015  Mar 25, 2016
Printed
Page 674
Example 21-10

Output from print() appears to be wrong for the method_z() methods in ClassFive and ClassSix (prints "method_y" instead of "method_z").

Note from the Author or Editor:
The reader is correct. The problems are in the code for evaltime_meta.py, example 21-10, on page 670 of the PDF. We need to make two changes:

1) Inside the `class ClassFive` block, change `method_y` to `method_z` inside the parenthesis of the `print(...)`:

def method_z(self):
print('<[8]> ClassFive.method_z')


2) Inside the `class ClassSix` block, change `method_y` to `method_z` inside the parenthesis of the `print(...)`:

def method_z(self):
print('<[10]> ClassFive.method_z')

mike  Nov 27, 2015  Mar 25, 2016
PDF
Page 676
Caption of Example 21-16

Yet another case of missing double-underscores. In the caption for example 21-16 the word "prepare" should be written as "__prepare__", because it is the name of the first special method that appears in the code.

Luciano Ramalho  Oct 15, 2015  Mar 25, 2016
Printed
Page 719
Glossary entry 'accessor'

Mis-spelling as 'acessor'

Note from the Author or Editor:
The word "accessor" is correctly spelled in the glossary entry but mispelled inside the definition, in this sentence:

"""Some authors use acessor as a generic term [...]"""

The correct would be:

"""Some authors use accessor as a generic term [...]"""

Dean Draayer  Oct 10, 2015  Mar 25, 2016
PDF
Page 726
2nd entry (word

Andrew M. Kuchling's last name is misspelled as "Kushling"

Luciano Ramalho
Luciano Ramalho
 
May 03, 2015  Jul 24, 2015
ePub
Page 771
Last paragraph

In the sentence:
A Pythonic implementation of the same functionality uses a generator function to replace the SequenceIterator class.

Shouldn't it be:
SentenceIterator class.

Note from the Author or Editor:
The reader is correct. The problem described is in the first sentence of section "Sentence Take #3: A Generator Function" of Chapter 14, page 412 of the PDF.

The correct sentence should be:

A Pythonic implementation of the same functionality uses a generator function to replace the SentenceIterator class.

Kayomarz  Sep 18, 2015  Mar 25, 2016