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.

The following errata were submitted by our customers and have not yet been approved or disproved by the author or editor. They solely represent the opinion of the customer.

Color Key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted by Date submitted
Other Digital Version Page 56 of 708
Python Code

The code imports float parameters from 'floats-10M-lines.txt'. The code in the book implies the file comes from the last code written where the imported 'array' library was used to generate 10 million float parameters. However using numpy (1.13.1) loadtxt method it is not possible to load the previously created file. More over when creating a numpy array with 10 million parameters and saving it to txt, the code still failts to import the content.

Attempt to workarround code:
flts = numpy.array([random() for x in range(10**7)],dtype='float64')
flts.tofile('numpy_floats.txt')
floats = numpy.loadtxt('numpy_floats.txt')

Error:
UnicodeDecodeError: 'charmap' codec can't decode byte 0x90 in position 17: character maps to <undefined>

Javier Granados  Oct 21, 2018 
Printed Page Page 13
Table 1.2

In the table, several of the methods have the wrong names. For example:

__le__<=

The "<=" is not part of a valid method name. There are several similar instances.

Leam Hall  Jul 01, 2022 
PDF Page Page 222
Example 6-18

The example is given as follows:
Example 6-18. String literals may create shared objects
>>>t1=(1,2,3)
>>>t3=(1,2,3)
>>>t3 is t1
False
>>> s1 = 'ABC'
>>> s2 = 'ABC'
>>> s2 is s1
True

And author uses the Python 3.10 version.
But I checked this code with both Python 3.10 and 3.9 both give the first statement as true.

```
t = (1, 2, 3)
tt = (1, 2, 3)
print(tt is t)
s = 'ABC'
ss = 'ABC'
print(ss is s)
```
Python 3.10 output:
```
True
True
```

Python 3.9 output:
```
True
True
```

Mamatkasym  Sep 16, 2023 
PDF Page code-demo:16-17
in the 'averager()' function

The issue is that the `return Result(count, average)` statement is placed inside the `while` loop in the `averager` function. This placement is incorrect because using `return` inside the loop causes the generator to terminate immediately, and the values of `total` and `count` get reset on each iteration.

Here is the corrected version of the `averager` function:

```python
def averager():
total = 0.0
count = 0
average = None

while True:
term = yield
if term is None:
break
total += term
count += 1
average = total / count
return Result(count, average)
```

In this corrected version, the `return Result(count, average)` statement is moved outside the `while` loop. This way, when a `None` value is received and the loop exits, the generator will return a `Result` object containing the final count and average.

DarrenYing  Sep 26, 2023 
Printed Page Example 8-13
Bottom example

In the lines:

num_rows, reminder = divmod(len(sequence), num_columns)
num_rows += bool(reminder)

"reminder" should be "remainder"

Daniel S Cox  Jan 22, 2024 
Printed Page Page 45
2nd paragraph from bottom

It is not true that there must be a list after the lambda keyword in Scheme. It can simply be a variable name, in which case it will contain a list of all the arguments passed to the function. For example, the following is perfectly valid:

((lambda x (reverse x)) 'a 7 5.4) ; returns '(5.4 7 a)

In other words, the variable x is a list containing all of the arguments.

I realize lisp.py is meant to cover a subset of Scheme, but it's still preferable to be accurate about the syntax of Scheme's lambda.

Brian Adkins  Feb 19, 2024 
Printed, O'Reilly learning platform Page Preface, footnote 1
Bottom of page (print version 1)

The URL in the footnote, that’s intended to go to the quote of Tim Peters, is incorrect. This platform prohibits the inclusion of URLs, so I’ll say that the page should be 134521.html rather than 147293.html

Louise Penberthy  Apr 09, 2024 
Printed Page 2nd ed, P 456, ex 13-7
3rd line

Very minor, but the comment for the inspect() method says it returns a sorted tuple. It doesn’t seem to. The implementation of the abstract method load() could potentially do that. However, its comment doesn’t say anything about sorting.

Bill Arduser  Apr 18, 2024 
Printed, PDF Page 30
if longitude <= 0: limits the output to metropolitan areas in the Western hemisphere.

The dividing line between the eastern and western hemispheres is -20, not 0

杨可  Sep 11, 2020 
Printed Page 32
Line 4/5

In response to Brian van den Broek: There is a line break in the midst of an identifier. It should be "City(*delhi_data)"; the line breaks after " del".

This is NOT a typo or error. Please see Page xx of the Preface, section Conventions Used In This Book:
Note that when a line break falls within a constant_width term, a hyphen is not added --it could be misunderstood as part of the term.

fracjackmac  Apr 08, 2016 
Printed, PDF Page 67
the last line

b OrderedDict.popitem() removes the first item inserted (FIFO); an optional last argument, if set to True, pops the last item (LIFO).
But,I tested and found that OrderedDict.popitem() removes the last item inserted (LIFO)
ps: My python version is 3.6.0

杨可  Sep 16, 2020 
Printed Page 70
2nd to last paragraph

liscomps -> listcomps (missing t)

Richard Pattis  Aug 11, 2019 
Printed Page 93
Last paragraph (bird quote)

The random salt is a security measure to prevent not only a DoS attack. I'd say to prevent a brute-force attack, which might end up being a DoS attack or anything else. A DoS attack is quite specific.

Michalis Despotopoulos  Aug 11, 2020 
PDF, ePub Page 95
Bottom

In the note about the custom __eq__ method, the second reference to this method calls it __eq$__. The dollar sign should not be there.

Matthew Halverson  May 26, 2016 
Printed, PDF, ePub Page 95
bottom

In the note about the custom __eq__ method, the second reference to this method calls it __eq$__. The dollar sign should not be there.

Note: I already reported this for the PDF and ePub, but it is also present in the printed book, but only the third release revision.

Matthew Halverson  Jun 04, 2016 
Printed Page 111
around middle of page

"Example 4-7. Decoding from str to bytes: success and error handling"

substitute the substring:
"str to bytes"
to
"bytes to str"

Anonymous  Feb 27, 2018 
Printed Page 147
2nd line

The second line ends with '__in' and the third starts with 'it__'. There should not be a line break, there as '__init__' is an identifier.

Brian van den Broek  Mar 21, 2016 
Printed Page 151
Example 5-15 Function to shorten a string by clipping at a space near the desired length

To clip near the desired length, when the space is not found before max_len the function should search for the space from left to right, starting from max_len. Thus text.find() should be used instead of text.rfind(). That is,
space_after = text.find(' ', max_len)

Hao Wang  Jun 04, 2021 
PDF Page 154
Example 5-19. Annotated clip function

The `rfind` method in `space_after = text.rfind(' ', max_len)` should be `find`.

Above this line there is a line `space_before = text.rfind(' ', 0, max_len)`, of which the `rfind` is right.

If both of the two cases use `rfind`, this code CANNOT do what the author want to do.

Jian Lan  Sep 08, 2017 
Printed Page 155
Example 5-11, item tagged #5

The example tagged #5 in Example 5-11 is:

tag(content='testing', name="img")

This seems like a bad choice of example to show that the first positional argument can be passed as a keyword when tag is called.

While that is true, the first keyword argument being passed (content='testing') doesn't actually get assigned to the second positional parameter content ! Instead it is captured by the **attrs as a dict (even though content is explicitly named in the signature!) which is likely not what is expected or intended. (The <img> tag is used to insert an image into a document. This element must not contain any content, and does not need a closing tag.)

If name is not passed as the first positional argument, you can't actually pass a value to the content argument because everything will end up in the attrs dict.

So rather than passing content='testing' before the name='img' I would pass something else that appropriately belongs in the attrs of an img tag, say src='example.jpg'.

Sam Roberts  Apr 05, 2020 
Printed Page 177
in example 6-2

watermelon is misspelled watermellon

Matt Savoie  Apr 02, 2017 
PDF Page 211
general note

Misspelled @singledispath, missing a C letter

Juracy Filho  Feb 20, 2020 
Printed Page 235
2nd paragraph

atributes -> attributes

Jürgen Gmach  Feb 09, 2018 
Printed Page 243
Explanation of Example 8-21

In step 4

> Surprise: a and b refer to the same str!

I think it should be:

> Surprise: s1 and s2 refer to the same str!

if we follow the names in Example 8-21.

Thanks.

Moe  Feb 08, 2017 
Printed Page 247
Object Destruction and Garbage Collection, last paragraph

"Python Garbage Collector Implementations: CPython, PyPy and GaS" (http://bit.ly/1Gt0HrJ)
links to a 404 page (https://thp.io/2012/python-gc/python_gc_final_2012-01-22.pdf)

Anonymous  Feb 22, 2016 
Printed Page 247
5th paragraph / last paragraph of Object Destruction and Garbage Collection

In response to Anonymous: "Python Garbage Collector Implementations: CPython, PyPy and GaS" (http://bit.ly/1Gt0HrJ) links to a 404 page (https://thp.io/2012/python-gc/python_gc_final_2012-01-22.pdf)

The 2012/python-gc section of Thomas Perl's website had gone dark. I reached out to Thomas and he reposted the document at the same link on Friday, 08 April 2016: http://bit.ly/1Gt0HrJ
[Thanks Thomas!!]

fracjackmac  Apr 08, 2016 
Printed Page 252
4th paragraph

In the second line of the section "Parameter Passing: ..." where it says ... "This not wrong ..." it should be ... "This is not wrong ..."

Guillermo Irisarri  May 17, 2018 
PDF Page 258
2nd paragraph and Example 9-8

Vector2d.__hash__ - method does not work correctly
because gives same hashes for different vectors


$ python3 -i ./vector2d_v3_prophash.py
>>> v1 = Vector2d(1,3)
>>> v2 = Vector2d(3, 1)
>>> v1 == v2
False
>>>
>>> hash(v1) == hash(v2)
True
>>>

Ait  Nov 02, 2016 
Printed Page 258
__eq__ and __hash__ definitions

There seems to be a "didactic" inconsistency in the way that the __eq__ (page 258) and __hash__ (page 268) are defined. Why not use

return tuple(self)

in the definition of hash? It will be consistent with:

return tuple(self) == tuple(other)

as defined in __eq__.

Or, possibly, but inefficiently, in __eq__ use

return hash(self.x) ^ hash(self.y) == hash(other.x) ^ hash(other.y)

or something similar?

Guillermo Irisarri  May 17, 2018 
Printed Page 259
Footnote 3

The following concerns the third release (2016-03-18) of the first edition August 2015 (printed):

There is a stray period in the code.
Instead of "yield self.x; yield.self.y" the code should read:

yield self.x; yield self.y

Werner Wenzel  Sep 17, 2017 
Printed Page 262
1st paragraph

About half way in the paragraph, where it says " ... so you want to them nearby ..." it should say something like "... so you want to place them nearby ...."

Guillermo Irisarri  May 17, 2018 
Printed Page 269
The Problems with __slots__

"You must remember to redeclare `__slots__` in each subclass, because the inherited attribute is ignored by the interpreter."

I think it's worth clarifying superclasses' `__slots__` have effect, if subclasses also define `__slots__`.

>>> class A:
... __slots__ = ('x', 'y')
...
>>> class B(A):
... __slots__ = ()
...
>>> obj = B()
>>> obj.x = 3 # (No Errors)
>>> obj.z = 4
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'B' object has no attribute 'z'

Anonymous  Feb 22, 2016 
Printed Page 286
first paragraph

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

Pascal Ortiz  Jul 29, 2016 
PDF Page 288
Vector Take #4: Hashing and a Faster ==

Vector.__hash__ - method does not work correctly because gives same hashes for different vectors

$ python3 -i ./vector_v4.py
>>> v1 = Vector([1, 3])
>>> v2 = Vector([3, 1])
>>> v1 == v2
False
>>> hash(v1) == hash(v2)
True
>>>

All examples in Chapter 10 with __hash_ method uses incorrect approach.

Anonymous  Nov 02, 2016 
Printed Page 289
Code at the top of the page, line 5

The code disallows all lowercase, single letter names, such as a, z or δ.

The error message "can't set attributes 'a' to 'z' in {cls_name!r}" does not convey that all single letter unicode identifiers will raise an error, not just the lower case ASCII letters.

Anonymous  May 01, 2018 
Printed Page 293
code in the __hash__ method

map(hash, self._components) should be map(hash, self) because instances of the Vector class are iterable.

Anonymous  May 01, 2018 
Printed Page 297-302
Code for Vector class

Finale Vector class is missing __setattr__ method discussed on page 288-289.

Anonymous  May 01, 2018 
Printed Page 304
2nd paragraph

"...the subjects of Chapters 11 and 11."
should be
"...the subjects of Chapters 11 and 12."

Oleg Marshev  Sep 16, 2018 
Printed Page 307
David Epstenin's comment on Evan Simpson's code

It is clear that Simpson's code has been transcribed incorrectly, but if you change the name of the variable from t to total, or viceversa, remember to change it also in David Epstein's comment just below that code.
The sentence says: "loop over these items, maintain a variable t, [...]" so the name of the variable must match the one used in the code.

Anonymous  Apr 09, 2016 
Printed Page 310
2nd paragraph under section "Interfaces and Protocols in Python Culture"

"...the set public attributes..." needs "of" inserted between "set" and "public".

Dean Draayer  May 26, 2016 
Printed Page 312
UML diagram in center of page

Why is __len__ omitted from the Sequence ABC?

Anonymous  May 01, 2018 
Printed Page 319
4th and 6th paragraph

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

Pascal Ortiz  Jul 29, 2016 
Printed Page 320
2nd paragraph of "Interfaces and Protocols in Python Culture"

> every class has an interface: the set public attributes ...

I think it should be "the set *of* public attributes"

Nick Cleaton  Apr 10, 2019 
Printed Page 321
Penultimate paragraph

Protocol is misspelled 'procotol' in italics.

David  Apr 25, 2018 
Printed Page 322
1st paragraph

Half way through paragraph where it says "... accepts an "an object conforming to ..." , remove the first 'an' to read "... accepts "an object conforming to ..."

Guillermo Irisarri  May 23, 2018 
Printed Page 323
Example 11-3

in the book:

>>> class Foo:
... def __getitem__(self, pos):
... return range(0, 30, 10)[pos]
...
>>> f[1]
10
>>> f = Foo()

the above should throw a syntax error.

it should be:
>>> class Foo:
... def __getitem__(self, pos):
... return range(0, 30, 10)[pos]
...
>>> f = Foo()
>>> f[1]
10

tony tang  May 26, 2016 
Printed Page 323
2nd paragraph after Example 11-3

Where it says "... in the absence __iter__ ..." should say "... in the absence of __iter__ ..."

Guillermo Irisarri  May 23, 2018 
Printed Page 325
1st paragraph

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

Pascal Ortiz  Jul 29, 2016 
Printed Page 325
code note (3) on example 11-6

It says " deck can now be sorted" but the example is about shuffling, not sorting.

Nick Cleaton  Apr 10, 2019 
Printed Page 330
Interpreter session in upper half of the page

There is an extra line of output

<class 'abc.ABC'>, <class 'object'>)

that does not seem to belong here.

Anonymous  May 03, 2018 
Printed Page 330
First line, and again approximately two-thirds into second paragraph.

The function name "isinstance" has been written as "insinstance".

Peter Ryan  Feb 09, 2019 
PDF Page 331-332
Paragraph above code for BingoCage

The text claims that BingoCage overrides inspect, but this is not true.

Anonymous  May 03, 2018 
Printed Page 332
last method in code block

The implementation of BingoCage here defines the following __call__ method:

def __call__(self):
self.pick()

While this is not referred to later, and is not crucial to the example, it seems that it ought to return self.pick() rather than just evaluate it, lest calling the BingoCage instance remove an item from the list and drop it on the floor.

Ryan Rubin  Mar 13, 2017 
Printed Page 333
Middle of class LotteryBlower definition.

Error message of raise LookupError is "pick from empty BingoCage" It should be "pick from empty LotteryBlower" because this function is in the LotteryBlower class.

Charles Henri Darakdjian  Jun 09, 2017 
Printed Page 333
1st paragraph

In the suggestion element, around the previous to last line, where it says "... a binary search using bisect function ..." should read " ... a binary search using the bisect function ..."

Guillermo Irisarri  May 23, 2018 
Printed Page 334
MappingView entry

"the mapping methods .items(), .keys(), and .values() inherit from ItemsView, ValuesView, and ValuesView, respectively."
The first 'ValuesView' should be 'KeysView'

This errata has already been reported for the PDF version (page 322) so may have been corrected for a future printed version already.

David  Apr 25, 2018 
Printed, PDF Page 334
Item 3 of bullet list

Hi Luciano,

Thanks for your great book. I've spent one year reading 4pg/day of it and I am almost finishing ch 21.

Revisiting ch 11, I found a minor correction on page 334 of PDF (also occurs in translated printed version):

"Tombolist inherits __bool__ from list, and that returns True if the list is not
empty."

Should read:

"Tombolist inherits __len__ from list, and that returns zero (which is evaluated to False in an expression) when the list is empty."

Best wishes,

Nilo

Nilo César Teixeira  Dec 03, 2020 
Printed Page 335
Chapter 11

On UML diagram (figure 11-5) list class should not have __bool__ method.

Max Lo  Mar 25, 2017 
Printed Page 335
1st paragraph

In the first line insinstance should be isinstance.

Guillermo Irisarri  May 23, 2018 
Printed Page 336
Bullet point 3 on top of page and footnote 15 at bottom of page.

In bulletpoint 3, the text claims that TomboList inherits __bool__ from list.
In the footnote 15 on the same page it is claimed that list does not implement __bool__.

The two statements contradict each other.

Anonymous  May 03, 2018 
Printed Page 343
Example 11-13

in the pick() method:

def pick(self):
......
......
raise LookupError('pick from empty BingoCage')


I think it should be
raise LookupError('pick from empty LotteryBlower')


So it will match the class name.

tony tang  May 27, 2016 
Printed Page 363
2nd paragraph, second line of paragraph (l. 8 of the page)

There is an extra right parenthesis in the text. The first sentence of the second paragraph starts:

"The problem is not limited to calls within an instance - wheteher self.get() calls self.__getitem__()) - but also happens..."

and here the "self.__getitem__())" should just be "self.__getitem()".





P.S. Great book!

Rami Luisto  Jun 03, 2021 
PDF, Page 380
First 3 paragraphs of "Overloading * for Scalar Multiplication" section

In the 1st paragraph, the book writes "If x is a number, that would be a scalar product [...]" However, in mathematics, "scalar product" actually means the same thing as the dot product. The correct term to use would be "scalar multiplication" as in the section heading.

Likewise in the 2nd paragraph: "The current practice [...] is to use * only for the scalar product" and 3rd paragraph: "Back to our scalar product"...

Jonathan Yong  Apr 28, 2020 
PDF Page 390
Top of page

The warning box notes that the Python documentation doesn't say that the default behavior for __ne__ in Python 3 is the inverse of __eq__. However, it seems the documentation has been updated to reflect this fact, so this warning box could be removed in a future edition.

Paul Romano  Sep 12, 2017 
Printed Page 395
Last paragraph before scorpion remark.

In the last sentence in the last paragraph before the scorpion remark on page 395 we have possibly small text formatting error where a space and an underscore have switched places. The last sentence says:

"Example 3-11 shows a practical use of goose typing - an explicit check against an abstract type; see the_ Fluent Python_ code repository..."

Here I think that the part "the_ Fluent Python_" should be "the _Fluent Python_", which, I guess, would then italicize the book name.

Rami Luisto  Jun 05, 2021 
Printed Page 412
A Glimpse at Lazy Evaluation

The code call outs for 1, 2, 3 in the stack trace should be reversed, with (3) appearing on the highest line, (2) the middle line, and (1) the lowest line. More concretely, the code description for "The Vector call gets a generator expression as its components argument. No problem at this stage." should be paired with the lines in the code

File "vector_v6.py", line 329, in <genexpr>
return Vector(a + b for a, b in pairs)

Nate Guerin  Mar 14, 2017 
ePub Page 414
Table 14-3 and following text


"(built-in)
zip(it1, …, itN)
Yields N-tuples built from items taken from the iterables in parallel, silently stopping when the first iterable is exhausted"

"Any number of iterables can be consumed by zip in parallel, but the generator stops as soon as the first iterable ends."

incorrect - both should end with "the shortest iterable" - as shown below:

>>> list(zip('ABCDEFGH', 'abc', range(5)))
[('A', 'a', 0), ('B', 'b', 1), ('C', 'c', 2)]
>>>

Gregory Sherman  Nov 17, 2018 
ePub Page 418
Table 14-5 and Example 14-21


"itertools
groupby(it, key=None)
Yields 2-tuples of the form (key, group), where key is the grouping criterion and group is a generator yielding the items in the group"

>>> list(itertools.groupby('LLLLAAGGG')) 1
[('L', <itertools._grouper object at 0x102227cc0>),
('A', <itertools._grouper object at 0x102227b38>),
('G', <itertools._grouper object at 0x102227b70>)]
>>>


key is not explicitly supplied in groupby() call, but somehow becomes 'L , 'A', and 'G'

Gregory Sherman  Nov 17, 2018 
Printed Page 420
Step 11

I think "next(it)" should be "next(g)".

Dean Draayer  May 26, 2016 
Printed Page 425
2nd paragraph after ending numbered list

It reads

Note that implementing __iter__ in SentenceIterator is not actually needed for this example to work, but the it's the right thing to do...

The first `the` in the `but the it's the right thing` should be removed.

Alexey Tereshenkov  Aug 12, 2017 
Printed Page 431
Second numbered item (enumerated 11)

It seems the author meant next(g) and not next(it), as appears in items 5, 6 and 9 in the previous page, the equivalent in the for loop is formulated as g = iter(gen_AB()).

Yonathan Mizrahi  Jan 20, 2019 
Printed Page 437
1st paragraph

Duplicate word in "reduce the cumulative effect of errors when working with with floats".

William Smith  Nov 03, 2019 
Printed Page 448
Second code example

The sample code in the book

for char, group in itertools.groupby('LLLLAAAGG'):
print(char, '->', list(group))

shows the output as

L -> ['L', 'L', 'L', 'L']
A -> ['A', 'A']
G -> ['G', 'G', 'G']

However, when running this code using Python 3.x, you would get:

L -> ['L', 'L', 'L', 'L']
A -> ['A', 'A', 'A']
G -> ['G', 'G']

That is, one `A` is missing and there is an extra `G`.

Alexey Tereshenkov  Aug 12, 2017 
Printed Page 452
3rd line of 5th text paragraph after title "A closer look at the iter function"

(1st Edition, 3rd Release of printed version)

In "with \n is found", the "\n" in code font is also italicized.

This is inconsistent with the other text in code font, and makes \n look similar to |n

The typo occurs in the correction to the erratum reported on Oct 16, 2015 (the author indicates where to use code font but doesn't mention italic).

Anonymous  Nov 21, 2018 
PDF Page 469
last paragraph + item 5 in example 13-15

As of python3.11, the

isinstance(c, SupportsComplex)

returns True

returns True and there is no need to check against both complex and SupportsComplex
-----------

Also, on page 440, third paragraph, "a" should be "at" and the sentence should read as :
rejecting invalid arguments right at the beginning of a function body

MohammadSaleh Dehqanpour  Jan 18, 2024 
PDF Page 480
definition of `grouper()`

As written, it is not exactly clear why the while True loop is required in grouper (i.e., the delegating generator):

def grouper(results, key):
while True:
results[key] = yield from average()


Since the real purpose of the while True loop is to prevent the grouper generator from raising the StopIteration when the subgenerator is done, the code could be made clearer as so:

def grouper(results, key):
results[key] = yield from average()
yield # Additional yield to suppress StopIteration

Yong Jie  May 31, 2020 
Printed Page 480
2nd paragraph, first line of paragraph (l. 3 of the page)

The second paragraph of the page, just above the next section header, starts with:

"After a brief overview of how generators were enable to act as a..."

Here I think the 'enable' has been conjugated wrong, and the part should read

"After a brief overview of how generators were enabled to act as a...".

Rami Luisto  Jul 19, 2021 
Printed Page 509
Figure caption

In the caption for figure 16-3, it notes that "Colored arrows highlight taxi trips", but there is not color in the printed version.

This is listed as having been fixed, but although the graphic now has (colored, but appearing in grayscale in the printed version) dashed and solid lines (which are clearly distinguishable in print even without different colors), the caption still refers exclusively to colored arrows, and does not have the text change listed.

Matthew Halverson  Jun 04, 2016 
PDF Page 541
First paragraph

Spelling error. "were" should be "where" in the sentence:

"... you’ll see an animated progress bar were the comment is:"

Peter Goldthorpe  Jul 07, 2019 
Other Digital Version 544
Example 17-12

In the book:

resp = requests.get(url)
if resp.status_code != 200:
resp.raise_for_status()

should be:

resp = requests.get(url)
resp.raise_for_status()

explanation:

raise_for_status only raises if an error actually occurred (see http://docs.python-requests.org/en/master/api/#requests.Response.raise_for_status). The code in the book is redundant and a bit misleading, as it might suggest that the exception will happen for every HTTP status code other than 200, which is not the case (e.g. there won't be an exception for 201 status code - Created)

Zbigniew Halas  Dec 02, 2016 
Printed Page 559
First paragraph

The link on line 3 of the text (https://bit.ly/1Ox3vWA) seems to lead to a different discussion that the author is describing (even with the variations '10', 'lO', 'l0' of the first two letters after 'bit.ly/').

Rami Luisto  Aug 10, 2021 
PDF Page 564
1st paragraph

Replace the with than
-------------------------
Example 18-12 is much easier to follow the previous JavaScript and Python examples:
-------------------------
Should be:
Example 18-12 is much easier to follow than previous JavaScript and Python examples:

Dani  Mar 12, 2023 
Printed Page 577
def get_flag(base_url, cc);

in the book, the function is implemented as:
def get_flag(base_url, cc):
url = '{}/{cc}/{cc}.gif'.format(base_url, cc = cc.lower())
resp = yield from aiohttp.request( 'GET', url)
if resp.status == 200:
......


in the downloaded source code, the function is implemented as:
def get_flag(base_url, cc):
url = '{}/{cc}/{cc}.gif'.format(base_url, cc = cc.lower())
resp = yield from aiohttp.request( 'GET', url)
with contextlib.closing(resp):
if resp.status == 200:
image = yield from resp.read()
......

tony tang  Jun 21, 2016 
Printed Page 578
5th bullet point

""When this with statement exists, the semaphore counter is decremented, unblocking some other coroutine instance that may be waiting for the same semaphore object."

This is false. The semaphore counter is INCREMENTED when the with statement exits (as it calls .release())

David Malvar  Feb 17, 2021 
Other Digital Version 585
3rd paragraph under "Boolean Value of a custom Type"

On the kindle digital version the paragraph indicated states "Our implementation of __bool__ is conceptually simple: it returns False if the magnitude of the vector is zero, True otherwise". I have found this is not accurate (at least on python 3.6.1). The use of a Vector object with any magnitude value returns True.

Javier Granados  Oct 20, 2018 
PDF Page 594
Last paragraph

In discussing the __new__() special method, the book says "it's a class method". The Python 3 documentation actually indicates that it is a static method, not a class method (see https://docs.python.org/3/reference/datamodel.html#object.__new__). This can be confirmed by trying to call, e.g., float.__new__(). If __new__() were a class method, float would automatically be passed; instead, it has to be passed explicitly as in float.__new__(float).

Paul Romano  Sep 09, 2017 
PDF Page 595
First code block

The use of __new__() is incorrect in the code example showing how object construction happens. The code is:

def object_maker(the_class, some_arg):
new_object = the_class.__new__(some_arg)
if isinstance(new_object, the_class):
the_class.__init__(new_object, some_arg)
return new_object

The problem is that __new__() is a static method that must receive the class as its first argument. Thus, the code should be:

def object_maker(the_class, some_arg):
new_object = the_class.__new__(the_class, some_arg)
if isinstance(new_object, the_class):
the_class.__init__(new_object, some_arg)
return new_object

Paul Romano  Sep 09, 2017 
Printed Page 597
first paragraph

Book states :

-----------------------------
The special method that actually constructs an instance is __new__: it’s a class method (but gets special treatment, so the @classmethod decorator is not used)
-----------------------------

This is incorrect : __new__ is not a CLASS method but rather a STATIC method. Quoting Guido himself (cf. "Unifying types and classes in Python 2.2"):

Factoid: __new__ is a static method, not a class method.

Pascal Ortiz  Jul 26, 2016 
Printed Page 612
3rd (last) paragraph

"[...] uses `name` as a key to retrieve an item from `self.__dict`"

-->

"[...] uses `name` as a key to retrieve an item from `self.__data`"

In reference to Example 19-5, the line annotated with a circled 4.

Alex Povel  Jun 29, 2020 
Printed Page 618
Last paragraph (right before Example 19-26)

"@my_propety.deleter" is missing the "r" in "property".

Dean Draayer  May 26, 2016 
PDF Page 621
First paragraph of chapter summary

In the second sentence of the first paragraph of the chapter summary, it looks like there is a missing backtick on FrozenJSON:

"The first example was the FrozenJSON` class that converted..."

Paul Romano  Sep 13, 2017 
Printed Page 626
Last line on the page (before footnote)

'defauldict' should of course be 'defaultdict'.

Dean Draayer  May 26, 2016 
Printed Page 637
The session display near the top of the page

Where did the object referenced as "raisins" come from in the last line of the session presentation? It seems to have the same _Quantity#0 & 1 values as the object bound to "coconut", but I don't see any binding / creation of "raisins"

>>> getattr(raisins, '_Quantity#0'), getattr(raisins, '_Quantity#1')

Thanks for the absolutely fantastic book. It definitely made me a more competent Python coder!

Dean Stevens  Apr 09, 2016 
Printed Page 638
3rd to last paragraph

"The code in Example 19-25 may be a bit tricky [...]"

should probably read

"The code in Example 19-24 may be a bit tricky [...]"

Alex Povel  Jul 02, 2020 
Printed Page 641
First line of first paragraph

The first line on the page currently reads:
"he imaginary organic food store..."
It appears to be missing a "T"

This is documented for the PDF, but apparently not yet for the printed book.

Dean Stevens  Apr 10, 2016 
Printed Page 655
Penultimate paragraph in "Chapter Summary"

It says '"Descriptor Usage Tips" on page 652 provided a brief look at how descriptor deletion and documentation work'. That is actually covered in the following section, starting on page 654.

Dean Draayer  May 26, 2016 
Printed Page 657
test code at the bottom of the page

in the book:
>>> coconuts = LineItem('Brazilian coconut', 20, 17.95)
>>> coconuts.weight, coconuts.price
(20, 17.95)
>>> getattr(raisins, '_Quantity#0'), getattr(raisins, '_Quantity#1')

it should be:
>>> coconuts = LineItem('Brazilian coconut', 20, 17.95)
>>> coconuts.weight, coconuts.price
(20, 17.95)
getattr(coconuts, '_Quantity#0'), getattr(coconuts, '_Quantity#1')

tony tang  Jul 07, 2016 
Printed Page 657
Last 2 lines

The last code snippet says `getattr(raisins ...` but it would make more sense to me to change raisins --> coconut as this is the above example.

Anonymous  Dec 29, 2019 
PDF Page 667
Second to last paragraph

The contextlib._GeneratorContextManager code shows that it does not suppress exceptions and if any exception is not handled by the generator function, it will be re-raised. (either literal raise or "return False" depending on the returning exception)

The inaccurate paragraph is:

With @contextmanager, the default behavior is inverted: the __exit__ method provided by the decorator assumes any exception sent into the generator is handled and should be suppressed.


MohammadSaleh Dehqanpour  Mar 22, 2024 
PDF Page 669
Last paragraph

The text says "Besides type, a few other metaclasses exist in the standard library, such as ABCMeta and Enum." The error is that Enum is actually not a metaclass; the standard library documentation actually indicates that there's a metaclass EnumMeta, of which Enum is an instance of. See https://docs.python.org/3/library/enum.html#enum-classes.

Paul Romano  Sep 09, 2017 
Printed, PDF Page 678
Chameleon sidenote

Hi,

Just another minor correction:

"None of the attributes mentioned in this section are listed by the
dir(…) function."

should be:

"None of the attributes mentioned in this section are listed by the
dir(…) function, except for dir(type)"

>>> dir(type)
['__abstractmethods__', '__base__', '__bases__', '__basicsize__', '__call__', '__class__', '__delatt
r__', '__dict__', '__dictoffset__', '__dir__', '__doc__', '__eq__', '__flags__', '__format__', '__ge
__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__instancecheck__',
'__itemsize__', '__le__', '__lt__', '__module__', '__mro__', '__name__', '__ne__', '__new__', '__pr
epare__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '_
_str__', '__subclasscheck__', '__subclasses__', '__subclasshook__', '__text_signature__', '__weakref
offset__', 'mro']

Nilo César Teixeira  Dec 04, 2020 
Printed Page 689
2nd paragraph

"..., from the team who brings us Flake, Sphinx, ..."

Where the "Flake" should be "Flask".

andor_chen  Feb 25, 2016 
Printed Page 721
1st paragraph, right column

As previously submited in the errata list, __new__ is not a class method (I know, this is misleading for the fisrt argument of __new__ being a class), so the sentence

The constructor term better describes the __new__ class method, which ...

should be corrected as:

The constructor term better describes the __new__ static method, which ...

Pascal Ortiz  Jul 29, 2016 
PDF Page 820
callout

"Using await in a list comprehension is similar to using asyncio.gather...."

This sentence is wrong; asyncio.gather properly allows multiple async tasks to run asynchronously while the list comprehension awaits one after the other, leading to effectively serial code.

MohammadSaleh Dehqanpour  Jun 23, 2024 
PDF Page 856
Second to last paragraph

As of python 3.12, cached_property no longer uses a Lock. So this paragraph should be removed:

Despite these limitations, @cached_property addresses a common need in a simple way, and it is thread safe. Its Python code is an example of using a reentrant lock.

MohammadSaleh Dehqanpour  Mar 21, 2024 
PDF Page 877
Second to last paragraph

PEP-8 recommends CapWords for class names not camelCase!

wrong sentence:

This function-class duality would be easier to leverage if PEP 8 — Style Guide for
Python Code did not recommend CamelCase for class names.

MohammadSaleh Dehqanpour  Mar 21, 2024 
PDF, ePub, Mobi Page 9912
text

Current
Transform some Western typographical symbols into ASCII (this snippet is also part of sanitize.py from Example 4-14) single_map = str.maketrans("""‚ ƒ„† ˆ‹‘’“”•– — ˜›""", """' f"* ^ <''""---~ >""") multi_map = str.maketrans({ '€': '< euro >', '…': '...', 'Œ': 'OE', '™': '( TM)', 'œ': 'oe', '‰': '<

Suggested
ƒ„† should be p„†


Anonymous  Sep 16, 2019 
PDF, ePub, Mobi Page 9912
text

Current
It’s usually not OK to have a chain of if/ elif/ elif with insinstance checks performing different actions depending on the type of an object: you should be using polymorphism for that — i.e., designing your classes so that the interpreter dispatches calls to the proper methods, instead of you hardcoding


Suggested
"with insinstance checks performing" should be "with insistence checks performing"

Anonymous  Sep 16, 2019 
PDF, ePub, Mobi Page 10672
text

Current
the surface, this may sound like what Microsoft did with with TypeScript, its JavaScript superset, except that TypeScript goes much further:

Suggested
"did with with TypeScript," should be "did with TypeScript,"

Anonymous  Sep 16, 2019 
PDF, ePub, Mobi Page 11905
text

Current
tries Vector2d.__eq__(v2d, vc). Vector2d.__eq__(v2d, vc) turns both operands into tuples an compares them: the result is True (the code for Vector2d.__eq__

Suggested
"tuples an compares" should be "tuples and compares"

Anonymous  Sep 16, 2019 
PDF, ePub, Mobi Page 12620
text

Current
is not actually needed for this example to work, but the it’s the right thing to do: iterators are supposed to

Suggested
"but the it’s the right" should be "but it’s the right"

Anonymous  Sep 16, 2019 
ePub, Mobi Page 12620
text

Current
The venue field, present in every event record, also holds the a serial number, but finding the corresponding venue record requires a

Suggested
"also holds the a serial number," should be "also holds a serial number,"

Anonymous  Sep 24, 2019 
PDF, ePub, Mobi Page 18749
text

Current
The venue field, present in every event record, also holds the a serial number, but finding the corresponding venue record requires


Suggested
"holds the a serial" should be "holds a serial"

Anonymous  Sep 16, 2019 
PDF, ePub, Mobi Page 21768
text

Current
will wrap up the book with references regarding what it its to be “Pythonic” — the main question this book tried

Suggested
"what it its to" should be "what it is to"

Anonymous  Sep 16, 2019