Python Essential Reference, 4th Edition [Amazon]
Addison-Wesley Professional (July 19, 2009)
ISBN 0672329786; 717 pages
Official Errata Page
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!
Special thanks to the following contributors for their "eagle eyes":
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 colon 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.
NameError UnboundLocalError |
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 100, ¶5 |
"The fact that closures capture the environment of inner functions..." should be "The fact that closures capture the environment of outer functions..." |
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 136, code at top |
def __subclasscheck__(self, sub): return any(c in self.implementors for c in sub.mro()) Should be def __subclasscheck__(self, sub): return any(c in self.implementors for c in sub.__mro__) |
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, ¶1 |
"... or supplying the metaclass keyword argument in the tuple of base classes (Python 3)." Should be "... or supplying the metaclass keyword argument after the tuple of base classes (Python 3)." |
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.
|
pg 227, midpage |
Clarify the use of byte strings (pickle module). Changes in multiple places.
|
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 416, middle |
In description of p.join(): "it is an error for a process to try and join itself." Should be "it is an error for a process to try to join itself." |
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 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 628, code at bottom |
class MultiMeta(type): ... def __new__(cls, name, bases, classdict): for name in classdict.multiple: print(name, 'multiply defined') if classdict.multiple: raise TypeError('Multiple definitions exist') return type.__new__(cls, name, bases, classdict) Should be changed to avoid variable name clash class MultiMeta(type): ... def __new__(cls, clsname, bases, classdict): for name in classdict.multiple: print(name, 'multiply defined') if classdict.multiple: raise TypeError('Multiple definitions exist') return type.__new__(cls, clsname, bases, classdict) |
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" |
Copyright (C) 2005-2023, David Beazley