This page describes all of the typos and corrections for the Python
Essential Reference, 4th Edition. If you find errors not listed here,
please let me know so that I can make future editions better!
Locations are specified by page and paragraph numbers (counting from the top of the page). Errors
are denoted in red. Additions or corrections are denoted in
blue.
| Location |
Description |
|
pg 7, ¶1
|
"On UNIX, EOF is Ctrl-D; on Windows, it's Ctrl-Z."
Should be
"On UNIX, EOF is Ctrl-D; on Windows, it's Ctrl-Z (or F6)."
|
|
pg 9, Note midpage.
|
"... If you do this, the normal indentation rules don't apply to the
next line, so you are free to format the continued lines as you wish."
Should be
"... If you do this, the normal indentation rules don't apply to the
next line, so you are free to format the continued lines as you wish.
A backslash is never needed for code enclosed in ( ), [
], or { }."
|
|
pg 13, Listing 1.2
|
Missing semicolon in code example.
import sys # Load the sys module
if len(sys.argv) != 2 # Check number of command line arguments
...
Should be:
import sys # Load the sys module
if len(sys.argv) != 2: # Check number of command line arguments
...
|
|
pg 21, ¶1 code
|
Inconsistent indentation in code example at top of page.
...
# Feed an active log file into all matchers. Note for this to work,
# a web server must be actively writing data to the log
Should be:
...
# Feed an active log file into all matchers. Note for this to work,
# a web server must be actively writing data to the log
|
|
pg 27, ¶1
|
"To specify an integer using octal, hexadecimal, or binary notation, precede the value
with 0, 0x, or 0b respectively (for example, 0644, 0x100fea8, or 0b11101010)."
Should be
"To specify an integer using octal, hexadecimal, or binary notation, precede the value
with 0o, 0x, or 0b respectively (for example, 0o644, 0x100fea8, or 0b11101010)."
Note: 0o is the number zero followed by a lowercase letter O.
|
|
pg 36, code at bottom
|
Missing comma and inconsistent use of quotation marks in dictionary.
items = {
'number' : 42
'text' : "Hello World"
}
Should be:
items = {
'number' : 42,
'text' : 'Hello World'
}
|
|
pg 40, ¶2
|
Clarification of sorting requirements.
"The s.sort() method sorts the elements of a list and
optionally accepts a key function and reverse flag, both of which must
be specified as keyword arguments."
Should be
"The s.sort() method sorts the elements of a list (all of
which should be of a uniform type) and optionally accepts a key function
and reverse flag, both of which must be specified as keyword
arguments."
|
|
pg 41, table 3.4
|
Clarification of sort() description.
"Sorts items of s in place.
key is a key function. reverse is
a flag that sorts the list in reverse order. key
and reverse should always be specified as keyword
arguments."
Should be
"Sorts items of s in place.
key is a key function. reverse is
a flag that sorts the list in reverse order. key
and reverse should always be specified as keyword
arguments. The items in s should all be of a
uniform type.
|
|
pg 44, table 3.5
|
Clarification of zfill() description.
"Pads a string with zeros on the left up to the specified width.
Should be
"Pads a string with the '0' digit character on the left up to the specified width.
|
|
pg 45, table 3.6
|
Clarification of items() description.
"Returns a sequence of (key, value) pairs."
Should be
"Returns a sequence of all (key, value) pairs in m."
|
|
pg 45, table 3.6
|
Clarification of keys() description.
"Returns a sequence of key values."
Should be
"Returns a sequence of all key values in m."
|
|
pg 49, ¶3
|
"In the example, we have passed f, a an instance of Foo, ..."
Should be
"In the example, we have passed f, an instance of Foo, ..."
|
|
pg 55, code midpage
|
"is" should be "if".
x = A.__new__(A,args)
is isinstance(x,A): x.__init__(args)
Should be:
x = A.__new__(A,args)
if isinstance(x,A): x.__init__(args)
|
|
pg 58, ¶1
|
"Keep in mind that descriptions are optional and rarely need to be defined."
Should be
"Keep in mind that descriptors are optional and are rarely defined directly."
|
|
pg 58, Table 3.17
|
Clarify the description of __get__().
"Returns an attribute value or raises AttributeError."
Should be
"Returns the value of an attribute on instance. If instance is None, self should be returned."
|
|
pg 59, ¶3
|
Clarification of extended slicing
"For example, the following variations of extended slicing are all supported and might be useful for working with multidimensional data structures such as matrices and arrays:"
Should be
"For example, the following variations of extended slicing are all supported by Python's syntax and are sometimes used to manipulate multidimensional data structures such as
matrices and arrays in third-party extensions such as NumPy:"
|
|
pg 60, code at top of page
|
Extra parens in code comment
x = _iter.next() (#_iter.__next__() in Python 3)
Should be:
x = _iter.next() # _iter.__next__() in Python 3
|
|
pg 67, table midpage
|
In the "Operations on Sequences" section, there is a missing comma after "v2" and the wrong font used on the "s" in this fragment:
v1, v2... , vn = s
Should be (note italics on "s"):
v1, v2, ... , vn = s
|
|
pg 68, code at bottom
|
Wrong result in code example:
...
d = a[0:5:2] # d = [0,2]
...
Should be:
...
d = a[0:5:2] # d = [0,2,4]
...
|
|
pg 69, code in bottom half page
|
Use of a better example that illustrates replacing the entire contents of a list:
...
a[2:] = [0] # a = [1,6,0]
...
Should be replaced with:
...
a[:] = [7,8] # a = [7,8]. id(a) remains the same
...
|
|
pg 72, 2nd code example
|
More consistent use of string formatting:
name = "Elwood"
age = 41
r = "%(name)s is %(age)s years old" % vars()
Should be:
name = "Elwood"
age = 41
r = "%(name)s is %(age)d years old" % vars()
|
|
pg 72, ¶3
|
Missing "*" on kwargs:
"A more advanced form of string formatting is available using the s.format(*args,*kwargs) method on strings."
Should be:
"A more advanced form of string formatting is available using the s.format(*args,**kwargs) method on strings."
|
|
pg 75, ¶5
|
Clarification on augmented assignment semantics:
"Augmented assignment doesn't violate mutability of perform in-place modifications of the objects. Therefore, writing x += y creates an entirely
new object x with the value x + y.
Should be:
"Augmented assignment may or may not perform in-place modification of an object depending on its implementation. There, writing x + y
might modify x in-place or create an entirely new object with the value x + y.
|
|
pg 76, code example midpage
|
Code cleanup
from functools import partial
f = partial(foo,1,2) # Supply values to x and y arguments of foo
f(3) # Calls foo(1,2,3), result is 6
Should be:
from functools import partial
f = partial(foo,1,2) # Supply values to x and y arguments of foo
result = f(3) # Calls foo(1,2,3), result is 6
|
|
pg 78, Table 4.3, bottom of page
|
Cleanup of comparisons:
There is an extra blank line that should be eliminated and a semicolon in place of comma:
x < y, x <= y,
x > y; x >= y,
x == y, x != y
Should be (pay careful attention to punctuation including trailing commas)
x < y, x <= y,
x > y, x >= y,
x == y, x != y,
Also, change this description:
"Comparison, identity, and sequence membership tests"
To the following:
"Value comparison, object identity, and sequence membership tests"
|
|
pg 79, Table 4.3, top of page
|
Missing punctuation:
x is y, x is not y
x in s, x not in s
Should be (pay careful attention to trailing comma on first line):
x is y, x is not y,
x in s, x not in s
|
|
pg 79, Code Example
|
Bad spacing in example:
minvalue = a if a <=b else b
Should be (pay careful attention to the extra space before b):
minvalue = a if a <= b else b
|
|
pg 85, Code example at bottom
|
Add a code comment with clarification:
try:
do something
except Exception as e:
error_log.write('An error occurred : %s\n' % e)
Should be:
try:
do something
except Exception as e:
# error_log is previously opened file-like object
error_log.write('An error occurred : %s\n' % e)
|
|
pg 87, Table 5.1
|
Bad indentation and missing entries.
UnboundLocalError should be indented under NameError like this:
NameError
UnboundLocalError
- NotImplementedError should be indented under RuntimeError like this:
RuntimeError
NotImplementedError
- OverflowError is missing from the table. Should appear after FloatingPointError.
ArithmeticError Base for arithmetic exceptions
FloatingPointError Failure of a floating-point operation
OverflowError Integer value too large
ZeroDivisionError Division or modulus operation with 0
- WindowsError is missing from the table. Should appear indented under OSError.
EnvironmentError Errors that occur externally to Python
IOError I/O or file-related error
OSError Operating system error
WindowsError Windows-specific error
|
|
pg 90, Code example at top
|
Use of a better variable name in __exit__() method:
class ListTransaction(object):
...
def __exit__(self,type,value,tb):
if type is None:
self.thelist[:] = self.workingcopy
return False
Should be (replace "type" with "exctype"):
class ListTransaction(object):
...
def __exit__(self,exctype,value,tb):
if exctype is None:
self.thelist[:] = self.workingcopy
return False
|
|
pg 101, Code example midpage
|
Missing underscores on __name__ attribute:
def trace(func):
...
debug_log.write("%s returned %s\n" % (func.__name, r))
...
Should be (note extra underscores):
def trace(func):
...
debug_log.write("%s returned %s\n" % (func.__name__, r))
...
|
|
pg 103, Code example at top
|
Add clarifying comment to the return:
def countdown(n):
print("Counting down from %d" % n)
...
return
Should be:
def countdown(n):
print("Counting down from %d" % n)
...
return # Note: generators can only return None
|
|
pg 104, ¶2
|
"Moreover, if a program is currently iterating on generator, you should ..."
Should be:
"Moreover, if a program is currently iterating on a generator, you should ..."
|
|
pg 107, Code example at top
|
Fix broken code example ("find" should be "find_files"):
wwwlogs = find("www","access-log*")
...
Should be:
wwwlogs = find_files("www","access-log*")
...
|
|
pg 109, Code example midpage
|
Bad code comment ("f" should be "g"):
g = [math.sqrt(x*x+y*y) # f = [2.23606, 5.0, 7.81024]
for x,y in f]
Should be:
g = [math.sqrt(x*x+y*y) # g = [2.23606, 5.0, 7.81024]
for x,y in f]
|
|
pg 113, ¶3
|
"It is common practice for the first statement of function to be..."
Should be:
"It is common practice for the first statement of a function to be..."
|
|
pg 115, Code example at bottom
|
Bad code comment ("Execute" should be "Evaluate"):
...
c2 = compile(s2, '', 'eval') # Compile into an expression
result = eval(c2) # Execute it
Should be:
...
c2 = compile(s2, '', 'eval') # Compile into an expression
result = eval(c2) # Evaluate it
|
|
pg 122, Code example at top
|
Extra underscores in comment:
...
class Z(X,Y): pass # TypeError.
# Can't create consistent method resolution order__
Should be:
...
class Z(X,Y): pass # TypeError.
# Can't create consistent method resolution order
|
|
pg 123, Code example midpage
|
Missing module import.
class Date(object):
...
Should be (added line at beginning):
import time
class Date(object):
...
|
|
pg 124, Code example midpage
|
Bad attribute name (tm_month).
class Date(object):
...
def now(cls):
t = time.localtime()
# Create an object of the appropriate type
return cls(t.tm_year, t.tm_month, t.tm_day)
Should be ("tm_month" changed to "tm_mon")
class Date(object):
...
def now(cls):
t = time.localtime()
# Create an object of the appropriate type
return cls(t.tm_year, t.tm_mon, t.tm_day)
|
|
pg 125, Code example midpage
|
Missing parenthesis.
def spam(self, x):
print("%s,%s" % (self.name, x)
Should be:
def spam(self, x):
print("%s,%s" % (self.name, x))
|
|
pg 127, Code example at top
|
Bad indentation and minor correction:
class TypedProperty(object):
def __init__(self,name,type,default=None):
self.name = "_" + name
self.type = type
self.default = default if default else type()
def __get__(self,instance,cls):
return getattr(instance,self.name,self.default)
...
Should be (note: there are two changed statements):
class TypedProperty(object):
def __init__(self,name,type,default=None):
self.name = "_" + name
self.type = type
self.default = type() if default is None else default
def __get__(self,instance,cls):
return getattr(instance,self.name,self.default) if instance else self
...
These changes reflect the fact that the __get__() method of a descriptor should return the descriptor itself if the instance parameter is None.
This might occur if someone accesses a descriptor using the class instead of an instance.
|
|
pg 129, Code example midpage
|
Better comment:
u = Upperstr("hello") # value is "HELLO"
Should be:
u = Upperstr("hello") # u = "HELLO"
|
|
pg 132, ¶2
|
"For attribute lookup such as obj.name, the special method obj.__getattrribute__("name") is invoked:
Should be (fix mispelling of "getattribute)":
"For attribute lookup such as obj.name, the special method obj.__getattribute__("name") is invoked:
|
|
pg 137, ¶5
|
"Although an abstract class can not be instantiated ..."
Should be ("can not" changed to "cannot"):
"Although an abstract class cannot be instantiated ..."
|
|
pg 139, code example at top
|
In this code example, add a small amount of space around the underscores in "__metaclass__" to make it
clear that there are two leading/trailing underscores and to match the typography used elsewhere on the same page :
class Foo: # In Python 3, use the syntax
__metaclass__ = type # class Foo(metaclass=type)
...
|
|
pg 139, Code example near bottom
|
A better argument name than "dict" should be used.
class DocMeta(type):
def __init__(self,name,bases,dict):
for key, value in dict.items():
# Skip special and private methods
if key.startswith("__"): continue
# Skip anything not callable
if not hasattr(value,"__call__"): continue
# Check for a doc-string
if not getattr(value,"__doc__"):
raise TypeError("%s must have a docstring" % key)
type.__init__(self,name,bases,dict)
Should be (change all occurrences of "dict" to "attrs"):
class DocMeta(type):
def __init__(self,name,bases,attrs):
for key, value in attrs.items():
# Skip special and private methods
if key.startswith("__"): continue
# Skip anything not callable
if not hasattr(value,"__call__"): continue
# Check for a doc-string
if not getattr(value,"__doc__"):
raise TypeError("%s must have a docstring" % key)
type.__init__(self,name,bases,attrs)
|
|
pg 140, Code example in bottom half
|
A better argument name than "dict" should be used.
class TypedMeta(type):
def __new__(cls,name,bases,dict):
slots = []
for key,value in dict.items():
if isinstance(value,TypedProperty):
value.name = "_" + key
slots.append(value.name)
dict['__slots__'] = slots
return type.__new__(cls,name,bases,dict)
Should be (change all occurrences of "dict" to "attrs"):
class TypedMeta(type):
def __new__(cls,name,bases,attrs):
slots = []
for key,value in attrs.items():
if isinstance(value,TypedProperty):
value.name = "_" + key
slots.append(value.name)
dict['__slots__'] = slots
return type.__new__(cls,name,bases,attrs)
|
|
pg 147, ¶6
|
"First, it is only possible import .py, .pyw, .pyc, and .pyo files from an archive."
Should be:
"First, the only file types that can be imported from an archive are .py, .pyc, .pyo, and .pyw."
|
|
pg 150, ¶6 (near bottom)
|
"To do this, you can simply use the fully specified named (e.g., ..."
Should be ("named" changed to "name"):
"To do this, you can simply use the fully specified name (e.g., ..."
|
|
pg 152, Code example in middle
|
Use more consistent indentation:
# setup.py
from distutils.core import setup
setup(name = "spam",
version = "1.0",
py_modules = ['libspam'],
packages = ['spampkg'],
scripts = ['runspam.py'],
)
Should be:
# setup.py
from distutils.core import setup
setup(name = "spam",
version = "1.0",
py_modules = ['libspam'],
packages = ['spampkg'],
scripts = ['runspam.py'],
)
|
|
pg 160, Table 9.1
|
Change the description for f.fileno().
"Returns an integer file descriptor."
Should be:
"Returns the integer file descriptor or raises ValueError if closed."
|
|
pg 163, ¶4 (midpage)
|
Add a clarifying note:
"To suppress or change the line ending, use the end=ending keyword argument. For example:"
Should be:
"To suppress or change the line ending, use the end=ending keyword argument (note: if you specify something other
than a newline, you may have to flush sys.stdout to see the output)."
|
|
pg 164, code example at top
|
Messy formatting.
print form % { 'name' : 'Mr. Bush',
'item' : 'blender',
'amount' : 50.00
}
Should be (just move the brace)
print form % { 'name' : 'Mr. Bush',
'item' : 'blender',
'amount' : 50.00 }
|
|
pg 165, code example midpage
|
Missing parenthesis.
...
buffered_size = 0
out.write("".join(chunks)
Should be (note extra ')' at end):
...
buffered_size = 0
out.write("".join(chunks))
|
|
pg 173, Table 10.1
|
The font on "-Q arg" is wrong. The '-Q' should be monospaced like other options and "arg" should be monospaced italics. See the "-m module" entry for an example.
|
|
pg 191, ¶4
|
"If you simply want to time a long-running Python program, the easiest way to do it is often to just run it until the control of something..."
Should be ("until" replaced by "under")
"If you simply want to time a long-running Python program, the easiest way to do it is often to just run it under the control of something..."
|
|
pg 194, midpage
|
Bad font for section headers. The "Understand Algorithms" and "Use the Built-In Types" headers should be typeset in the same font as used for the "Understand Your Program" header above.
|
|
pg 203, midpage
|
Add Python 3 note to cmp() description.
"... In certain circumstances, such comparisons may also raise an exception."
Should be
"... In certain circumstances, such comparisons may also raise an exception. Python 3 only."
|
|
pg 204, midpage
|
Missing ] and extra space.
"enumerate(iter [, initial value)"
Should be (note extra ']' at end and added underscore in "initial_value")
"enumerate(iter [, initial_value])"
|
|
pg 206, midpage
|
Add clarifying note to input() description.
"... line of input is read without any kind of evaluation or modification."
Should be
"... line of input is read without any kind of evaluation or modification. The returned line does not include a trailing newline character."
|
|
pg 210, top
|
Typo in description of slice()
"Slice objects are also generated by the extended slice syntax a[i:i:k]."
Should be (change second "i" to "j")
"Slice objects are also generated by the extended slice syntax a[i:j:k]."
|
|
pg 213, bottom
|
In description of FloatingPointError:
"It should be noted that floating-point exception handling is a tricky problem and only that this exception only gets raised if..."
Should be (delete "only"):
"It should be noted that floating-point exception handling is a tricky problem and that this exception only gets raised if..."
|
|
pg 226, midpage
|
Clarify the use of byte strings (marshal module). Changes in multiple places.
Description of dumps():
"Returns the string written by..."
Should be (add "byte")
"Returns the byte string written by..."
-
Heading for loads():
"loads(string)" should be "loads(bytes)".
-
Description of loads():
"Reads and returns the next value from the string string."
Should be:
"Reads and returns the next value from the byte string bytes."
|
|
pg 227, midpage
|
Clarify the use of byte strings (pickle module). Changes in multiple places.
Description of dumps():
"Same as dump(), but returns a string containing the pickled data."
Should be (add "byte")
"Same as dump(), but returns a byte string containing the pickled data."
-
Heading for loads():
"loads(string)" should be "loads(bytes)".
-
Description of loads():
"Same as load(), but reads the pickled representation of an object from a string.
Should be (add "byte"):
"Same as load(), but reads the pickled representation of an object from a byte string.
|
|
pg 233, midpage
|
Typo and confusing typography in description of displayhook().
"... is printed to standard output and value is saved in the variable __builtin__._.displayhook can be redefined..."
Should be (extra 's' on '__builtins__' and added text):
"... is printed to standard output and value is saved in the variable __builtins__._. The displayhook
function can be redefined..."
|
|
pg 237, note at bottom
|
"The types module should not be used to refer the type of ..."
Should be (added "to"):
"The types module should not be used to refer to the type of ..."
|
|
pg 242, code example at top
|
Use modern idioms in code:
def foocache(x):
if resultcache.has_key(x):
...
Should be
def foocache(x):
if x in resultcache:
...
|
|
pg 259, Table 15.1
|
Delete the entire first entry in the table. This is the entry that looks like:
'c' 8-bit character char 1
Note: This isn't supported in Python 3 and using it in Python 2 is probably ill-advised anyways.
|
|
pg 260, code at bottom
|
Typo in code comment:
b = array.array(a.typecode, (2*x for x in a)) # Create a new array from b
Should be (change "b" to "a")
b = array.array(a.typecode, (2*x for x in a)) # Create a new array from a
|
|
pg 283, midpage
|
Use a better argument name in compile()
"compile(str [, flags])"
Should be (change "str" to "pattern")
"compile(pattern [, flags])"
|
|
pg 288, last line
|
Bad quotation mark on '0.name'. The ending quotation mark should be straight.
|
|
pg 300, code at bottom
|
Bad indentation.
symbol = "AIG"
account = 12345
Should be
symbol = "AIG"
account = 12345
|
|
pg 300, 2nd to last paragraph
|
Add a clarifying sentence:
"Here the '?' placeholders are successively replaced with values from the tuple
(symbol, account)."
Should be
"Here the '?' placeholders are successively replaced with values from the tuple
(symbol, account). '?' can only be used for values, not other parts of the query
such as the command or table name."
Layout note: To add the above sentence, you might have to make space (suggest using extra space right above the "Forming Queries" heading).
|
|
pg 311, ¶3
|
In description of open()
"... has the same meaning as described in the chapter introduction and is ..."
Should be
"... has the same meaning as described in the previous section and is ..."
|
|
pg 311, midpage
|
In table describing operations on shelves:
d.has_key(key)
Should be
key in d
|
|
pg 313, bottom
|
In description of c.compress():
"Feeds new string data to the compressor object, c.
Returns a string of compressed data if possible. Because compression
involves chunks of data, the returned string may not include..."
Should be (add "byte")
"Feeds new byte string data to the compressor object, c.
Returns a byte string of compressed data if possible. Because compression
involves chunks of data, the returned byte string may not include..."
|
|
pg 314, top
|
In description of c.flush():
"Flushes the internal buffers and returns a string containing..."
Should be (add "byte")
"Flushes the internal buffers and returns a byte string containing..."
|
|
pg 314, top
|
In description of d.decompress():
"Given a chunk of compressed data in the string data, this method returns
uncompressed data. Because data is processed in chunks, the returned string may or may not ..."
Should be (add "byte")
"Given a chunk of compressed data in the byte string data, this method returns
uncompressed data. Because data is processed in chunks, the returned byte string may or may not ..."
|
|
pg 314, midpage
|
In description of compress():
"Returns a compressed version of the data supplied in the string data."
Should be (add "byte")
"Returns a compressed version of the data supplied in the byte string data."
|
|
pg 314, midpage
|
In description of decompress():
"Returns a string containing the decompressed data in the string data."
Should be (add "byte")
"Returns a byte string containing the decompressed data in the byte string data."
|
|
pg 316, last line of code
|
Last line of code is missing parentheses:
for pyfile in findall(".","*.py"):
print pyfile
Should be (add parens):
for pyfile in findall(".","*.py"):
print(pyfile)
|
|
pg 333, near bottom
|
In the description of c.items().
There is a bad quotation mark style used in the sentence with "values that can be used in '%' expansions." Use straight quotes.
|
|
pg 349, code at top of page
|
Use modern exception handling style:
...
except IOError,e:
print "Unabled to acquire lock", e
Should be:
...
except IOError as e:
print("Unabled to acquire lock %s" % e)
|
|
pg 356, code midpage
|
Missing comma in arguments:
logging.basicConfig(
filename = "app.log",
format = "%(levelname)-10s %(asctime)s %(message)s"
level = logging.INFO
)
Should be (note extra comma on third line):
logging.basicConfig(
filename = "app.log",
format = "%(levelname)-10s %(asctime)s %(message)s",
level = logging.INFO
)
|
|
pg 398, midpage
|
Extra space in in description for split():
"For example, '/home/user/foo' gets split into ('/home/ user', 'foo')."
Should be (eliminate extra space in '/home/ user')
"For example, '/home/user/foo' gets split into ('/home/user', 'foo')."
|
|
pg 403, ¶3 midpage
|
Add an extra blank line before this sentence to better separate it from the description of
check_call() above it.
"The Popen object p returned by Popen() has a variety of..."
Layout note: To do this, there is some extra blank space at the end of the table at the top of the page. Perhaps
the description of call() can be moved up to make room.
|
|
pg 406, bottom half
|
In description of sleep():
"Puts the current process to sleep for ..."
Should be (change "current process" to "calling thread"):
"Puts the calling thread to sleep for ..."
|
|
pg 408, bottom half
|
In description of ConnectRegistry():
"key is a predefined handle such as HKEY_CURRENT_USER or HKEY_ USERS."
Should be (removed extra space in HKEY_USERS):
"key is a predefined handle such as HKEY_CURRENT_USER or HKEY_USERS."
|
|
pg 414, ¶3
|
"There's a joke attributed to Jason Whittington that goes as like this:"
Should be (remove "as"):
"There's a joke attributed to Jason Whittington that goes like this:"
|
|
pg 415, ¶2
|
In the 2nd to last sentence of this paragraph.
"... For example, a coroutine is a function that can receive and processe messages that are sent to it."
Should be (fix spelling of "process"):
"... For example, a coroutine is a function that can receive and process messages that are sent to it."
|
|
pg 416, top
|
In description of Process():
"... The arguments in the constructor should always been specified using ..."
Should be (change "been" to "be")
"... The arguments in the constructor should always be specified using ..."
|
|
pg 417, bottom
|
"... to run the preceding examples in the command shell (command.exe) instead of a ..."
Should be (change "command" to "cmd"):
"... to run the preceding examples in the command shell (cmd.exe) instead of a ..."
|
|
pg 426, ¶3 midpage
|
"Normally, processes are completed isolated from each other..."
Should be (change "completed" to "completely"):
"Normally, processes are completely isolated from each other..."
|
|
pg 465, code example, midpage
|
Change the implementation of the send() method so that it doesn't use the built-in "bytes" name.
...
def send(self,bytes):
while bytes:
evt = yield WriteWait(self.sock)
nsent = self.sock.send(bytes)
bytes = bytes[nsent:]
...
Should be (change "bytes" to "data"):
...
def send(self,data):
while data:
evt = yield WriteWait(self.sock)
nsent = self.sock.send(data)
data = data[nsent:]
...
|
|
pg 493, bottom
|
In description of Server.verify_request():
"Redefine this method if you want to verify the connection before
any further processing. This is what you define if you want to
implement a firewall or perform some other kind of a validation."
Should be (reworded for consistency):
"Method that is called to verify the connection before any further
processing. By redefining this method, you can implement a firewall or
perform other kinds of validation."
|
|
pg 493, bottom
|
In second to last paragraph.
"Finally, addition server features are available..."
Should be:
"Finally, additional server features are available..."
|
|
pg 493, bottom
|
In second to last paragraph.
"Finally, addition server features are available..."
Should be:
"Finally, additional server features are available..."
|
|
pg 497, bottom
|
In description of f.abort():
"Attempts to abort a file transfer that is in progress. This may or may not work depending the remote server."
Should be (add missing "on"):
"Attempts to abort a file transfer that is in progress. This may or may not work depending on the remote server."
|
|
pg 518, bottom
|
In description of install_opener():
"Installs a different opener object for use as the global URL
opener used by urlopen(). opener is
usually of an opener object created by build_opener().
Should be (delete "of"):
"Installs a different opener object for use as the global URL
opener used by urlopen(). opener is
usually an opener object created by build_opener().
|
|
pg 532, last sentence
|
"The topics of web frameworks is far beyond the scope..."
Should be (change "topics" to "topic"):
"The topic of web frameworks is far beyond the scope..."
|
|
pg 536, bottom
|
In description of parse_header():
('text/html', {'a':'hello', 'b':'world'})
parse_multipart(fp, pdict)
Should be (delete the second line):
('text/html', {'a':'hello', 'b':'world'})
|
|
pg 538, code at top
|
# Print the output page
values = {
'name' : name,
'email' : email,
'confirmation: ': confirmation,
# Add other values here...
}
Should be (delete the extra ' :' after the word 'confirmation' on the third line):
# Print the output page
values = {
'name' : name,
'email' : email,
'confirmation' : confirmation,
# Add other values here...
}
|
|
pg 570, ¶3
|
In description of parse():
"ile is a filename or already-open file object."
Should be:
"file is a filename or already-open file object."
|
|
pg 588, last table
|
The table entry for sched should be deleted. This module was already listed on page 587.
|
|
pg 624, bottom third of page
|
>>> foo.__annotations__
{'y': 4, 'x': 3, 'return': 5}
>>>
Should be (values are corrected):
>>> foo.__annotations__
{'y': 2, 'x': 1, 'return': 3}
>>>
|
|
pg 638, last paragraph
|
"For Python 3, especially, it is critically to report bugs, ..."
Should be (added "important"):
"For Python 3, especially, it is critically important to report bugs, ..."
|
|
pg 686, top of first column
|
Index entry for "numeric type coercision" should be "numeric type coercion"
|
|
pg 695, bottom part of first column
|
Index entry for "readlines() method of StreamReder objects" should be "readlines() method of StreamReader objects"
|
|
pg 712, middle of first column
|
Index entry for "Unicode strings, encoding and decoing" should be "Unicode strings, encoding and decoding"
|