Python in a Nutshell by Alex Martelli This errata page lists errors outstanding in the most recent printing. If you have technical questions or error reports, you can send them to booktech@oreilly.com. Please specify the printing date of your copy. This page was updated March 15, 2006. Here's a key to the markup: [page-number]: serious technical mistake {page-number}: minor technical mistake : important language/formatting problem (page-number): language change or minor formatting problem ?page-number?: reader question or request for clarification Confirmed errors: {86} middle of the page; The code: class OptimizedRectangle(object): __slots__ = 'width', 'height' __slots__ cannot usefully be added by inheritance in this way; so the example should be rewritten to avoid inheritance and rather just copy the whole Rectangle class as given at the top of page 85 under the new name OptimizedRectangle: class OptimizedRectangle(object): __slots__ = 'width', 'height' def __init__(self, width, height): self.width = width self.height = height def getArea(self): return self.width * self.height area = property(getArea, doc="area of the rectangle") {177} Last paragraph; The os.path Module functions table is missing the "expanduser" method and related description. (See, for example, the documentation at the following URL: http://python.org/doc/2.2.3/lib/module-os.path.html) {185} third line from the bottom; the description of lseek "but calling lstat on a file that does not support seeking ..." should be: "but calling lseek on a file that does not support seeking ..." {225} "in releases of Python older than the ones covered in this book, unpickling from an untrusted data source was a security risk ... No such weaknesses are known in Python 2.1 and later." This is no longer true, the 2nd edition says: Note that unpickling from an untrusted data source is a security risk; an attacker could exploit this to execute arbitrary code. Don't unpickle untrusted data! [284] Threading example program at bottom of page; Classes ExternalInterfacing and Serializer (snippets on pages 284-285) are not thread-safe as shown in the book. Change the snippets as follows: Add the following auxiliary class, to be used in both snippets, and useful in its own right: class PoolOfQueues: # thread-safe, because a list's pop and append methods are atomic def __init__(self): self.pool = [] def get_a_queue_from_pool(self): try: return self.pool.pop() except IndexError: return Queue.Queue() def return_a_queue_to_pool(self, q): self.pool.append(q) queues=PoolOfQueues() Change class ExternalInterfacing to: class ExternalInterfacing(Threading.Thread): def __init__(self, externalCallable, **kwds): Threading.Thread.__init__(self, **kwds) self.setDaemon(1) self.externalCallable = externalCallable self.workRequestQueue = Queue.Queue() self.start() def request(self, *args, **kwds): "called by other threads as externalCallable would be" q = queues.get_a_queue_from_pool() self.workRequestQueue.put((q, args, kwds)) try: return q.get() finally: queues.return_a_queue_to_pool(q) def run(self): while 1: q, args, kwds = self.workRequestQueue.get() q.put(self.externalCallable(*args, **kwds)) Change class Serializer to: class Serializer(Threading.Thread): def __init__(self, **kwds): Threading.Thread.__init__(self, **kwds) self.setDaemon(1) self.workRequestQueue = Queue.Queue() self.start() def apply(self, callable, *args, **kwds): "called by other threads as callable would be" q = queues.get_a_queue_from_pool() self.workRequestQueue.put((q, callable, args, kwds)) try: return q.get() finally: queues.return_a_queue_to_pool(q) def run(self): while 1: q, callable, args, kwds = self.workRequestQueue.get() q.put(callable(*args, **kwds)) {421} between mkd and pwd methods; omitted nlist method. The nlst method should probably be included, in its normal alphabetical order (i.e., after mkd but before pwd) with the text (in the usual mixture of fonts and typefaces like for the other methods): nlst f.nlst(pathname='.') Sends a NLST command to the FTP server, asking for the names of the files in the directory named by pathname (by default, the current directory), and returns the list of the filenames. ((i.e., as usual, I would omit weird, rarely used stuff such as, in this case, the optional, non-portable extra arguments)). {567} Manifest section 1st bullet; sdist default does not include scripts or data files, even if specifically mentioned in the setup.py script. The default only includes: "all Python source files implied by the py_modules and packages options" To include scripts or data files by sdist, you have to create a MANIFEST.in (571) Index of Symbols "*" and "**"; Index for "*" and "**" should be augmented for define extra arguments, 60 pass extra arguments, 64 {591} bottom right; There is no entry in the index for the consept "frozen", mentioned on page 121 just before and after the heading "Searching the Filesystem for a Module". Worse IMHO, there's no explanation in the book, that I can find, on what "frozen modules" is. A line or two on page 121 would have been nice.