Programming Python 4th Edition: Updates Page

I've deleted most of this page for use here. For the full story, see either www.rmi.net/~lutz/pp4e-updates.html live, or the snapshot of the book's website in this package's changes\book-web-site\snapshot-feb11 folder.


Book Corrections



  1. Page 702 and 704, PyEdit: add text.focus() calls after askstring() Unicode popups
    For convenience, and per the detailed description above, we should add a call to reset focus back to the text widget after the Unicode encoding prompt popups which may be issued on Open and Save/SaveAs requests (depending on texconfig settings). As is, the code works, but requires the user to click in the text area if they wish to resume editing it immediately after the Unicode popup is dismissed; this standard popup itself should probably restore focus, but does not. To fix, add focus calls in two places. First, on page 702, at code line 21 at roughly mid page, change:
                if askuser:
                    try:
                        text = open(file, 'r', encoding=askuser).read()
    
    to the following, adding the new first line (the rest of this code is unchanged):
                self.text.focus() # else must click
                if askuser:
                    try:
                        text = open(file, 'r', encoding=askuser).read()
    
    Second, on page 704, at code line 8 near top of page, similarly change:
                if askuser:
                    try:
                        text.encode(askuser)
    
    to the following, again just adding the new first line:
                self.text.focus() # else must click
                if askuser:
                    try:
                        text.encode(askuser)
    
    Reprints: please let me know if there is not enough space for the inserts; I'd rather avoid altering page breaks in the process. This patch will also be applied to future versions of the book's examples package; in the package, the code in question is in file PP4E\Gui\TextEditor\textEditor.py, at lines 298 and 393.



  2. Page 963 line 9, and page 970 line 4: add timeout arguments to email server connect calls
    For robustness, and per the detailed description above, add "timeout=15" arguments to the POP and SMTP connect calls, so that email clients don't hang when email servers fail to respond. In the book, change code line 9 on page 963 from the first of the following to the second:
            server = smtplib.SMTP(self.smtpServerName)           # this may fail too
            server = smtplib.SMTP(self.smtpServerName, timeout=15)  # this may fail too
    
    Similarly, change code line 4 on page 970 from the first of the following to the second:
            server = poplib.POP3(self.popServer)
            server = poplib.POP3(self.popServer, timeout=15)
    
    In the book examples package, these changes would be applied to line 153 of mailSender.py, and line 34 of file mailFetcher.py, both of which reside in directory PP4E\Internet\Email\mailtools. They'll be patched in a future examples package version.

    Update: I made the timeout 20 seconds in the examples package release version 1.2, to allow for slower email servers; 15 is more than enough to detect a problem with mine, but tweak this as desired.



  3. Page 1072, code line 10 from top of page, PyMailGUI: add a close() for HTML mail files
    For portability, and per the detailed description above, we should add an explicit close() call to flush the temporary file of an HTML-only email before starting a web browser to view it, so that this code works in all contexts. As is, it works on the test platform used for the book, and likely works on most others, because the method in question exits and thus reclaims, closes, and flushes the file before the spawned web browser gets around to reading it. However, this is timing and platform dependent, and may fail on some machines that start browsers more quickly; its been seen to fail on a fast Vista machine. To fix in the book, change the middle line of the following three current code lines:
                            tmp = open(tempname, 'wb')      # already encoded
                            tmp.write(asbytes)
                            webbrowser.open_new('file://' + tempname)
    
    to read as follows, adding the text that starts with the semicolon (I'm combining statements to avoid altering page breaks):
                            tmp = open(tempname, 'wb')      # already encoded
                            tmp.write(asbytes); tmp.close() # flush output now
                            webbrowser.open_new('file://' + tempname)
    
    In the book's examples package, this code is located at line 209 in file PP4E\Internet\Email\PyMailGUI\ListWindows.py; it will be patched there too in a future examples package release (version 1.2, date TBD).