SF.net SVN: spambayes:[3254] branches/python3/spambayes

[email protected] Mon, 09 Nov 2009 02:59:11 +0000
Newsgroups gmane.mail.spam.spambayes.cvs
Message-ID <[email protected]>
Revision: 3254
          http://spambayes.svn.sourceforge.net/spambayes/?rev=3254&view=rev
Author:   montanaro
Date:     2009-11-09 02:59:10 +0000 (Mon, 09 Nov 2009)

Log Message:
-----------
First pass with 2o3.  Haven't tested it yet.  The proof will be to see how
many other changes are required from this point on...

Modified Paths:
--------------
    branches/python3/spambayes/Outlook2000/addin.py
    branches/python3/spambayes/Outlook2000/config.py
    branches/python3/spambayes/Outlook2000/config_wizard.py
    branches/python3/spambayes/Outlook2000/dialogs/FolderSelector.py
    branches/python3/spambayes/Outlook2000/dialogs/__init__.py
    branches/python3/spambayes/Outlook2000/dialogs/async_processor.py
    branches/python3/spambayes/Outlook2000/dialogs/dialog_map.py
    branches/python3/spambayes/Outlook2000/dialogs/dlgcore.py
    branches/python3/spambayes/Outlook2000/dialogs/opt_processors.py
    branches/python3/spambayes/Outlook2000/dialogs/processors.py
    branches/python3/spambayes/Outlook2000/dialogs/resources/rc2py.py
    branches/python3/spambayes/Outlook2000/dialogs/resources/rclabels2text.py
    branches/python3/spambayes/Outlook2000/dialogs/resources/rcparser.py
    branches/python3/spambayes/Outlook2000/dialogs/test_dialogs.py
    branches/python3/spambayes/Outlook2000/dialogs/win32struct.py
    branches/python3/spambayes/Outlook2000/dialogs/wizard_processors.py
    branches/python3/spambayes/Outlook2000/export.py
    branches/python3/spambayes/Outlook2000/filter.py
    branches/python3/spambayes/Outlook2000/manager.py
    branches/python3/spambayes/Outlook2000/msgstore.py
    branches/python3/spambayes/Outlook2000/sandbox/delete_outlook_field.py
    branches/python3/spambayes/Outlook2000/sandbox/dump_email.py
    branches/python3/spambayes/Outlook2000/sandbox/dump_profiles.py
    branches/python3/spambayes/Outlook2000/sandbox/dump_props.py
    branches/python3/spambayes/Outlook2000/sandbox/extract_bad_msg_from_log.py
    branches/python3/spambayes/Outlook2000/sandbox/extract_prop.py
    branches/python3/spambayes/Outlook2000/sandbox/find_dupe_props.py
    branches/python3/spambayes/Outlook2000/sandbox/mapi_driver.py
    branches/python3/spambayes/Outlook2000/sandbox/score.py
    branches/python3/spambayes/Outlook2000/sandbox/set_read_flag.py
    branches/python3/spambayes/Outlook2000/tester.py
    branches/python3/spambayes/Outlook2000/train.py
    branches/python3/spambayes/contrib/SmarterHTTPServer.py
    branches/python3/spambayes/contrib/bulkgraph.py
    branches/python3/spambayes/contrib/findbest.py
    branches/python3/spambayes/contrib/mod_spambayes.py
    branches/python3/spambayes/contrib/nway.py
    branches/python3/spambayes/contrib/pycksum.py
    branches/python3/spambayes/contrib/sb_culler.py
    branches/python3/spambayes/contrib/showclues.py
    branches/python3/spambayes/contrib/spamcounts.py
    branches/python3/spambayes/contrib/tte.py
    branches/python3/spambayes/pspam/pop.py
    branches/python3/spambayes/pspam/pspam/folder.py
    branches/python3/spambayes/pspam/pspam/profile.py
    branches/python3/spambayes/pspam/scoremsg.py
    branches/python3/spambayes/scripts/core_server.py
    branches/python3/spambayes/scripts/sb_bnfilter.py
    branches/python3/spambayes/scripts/sb_bnserver.py
    branches/python3/spambayes/scripts/sb_client.py
    branches/python3/spambayes/scripts/sb_dbexpimp.py
    branches/python3/spambayes/scripts/sb_evoscore.py
    branches/python3/spambayes/scripts/sb_filter.py
    branches/python3/spambayes/scripts/sb_imapfilter.py
    branches/python3/spambayes/scripts/sb_mailsort.py
    branches/python3/spambayes/scripts/sb_mboxtrain.py
    branches/python3/spambayes/scripts/sb_notesfilter.py
    branches/python3/spambayes/scripts/sb_pop3dnd.py
    branches/python3/spambayes/scripts/sb_server.py
    branches/python3/spambayes/scripts/sb_unheader.py
    branches/python3/spambayes/scripts/sb_upload.py
    branches/python3/spambayes/scripts/sb_xmlrpcserver.py
    branches/python3/spambayes/setup.py
    branches/python3/spambayes/spambayes/CoreUI.py
    branches/python3/spambayes/spambayes/Corpus.py
    branches/python3/spambayes/spambayes/CostCounter.py
    branches/python3/spambayes/spambayes/Dibbler.py
    branches/python3/spambayes/spambayes/FileCorpus.py
    branches/python3/spambayes/spambayes/Histogram.py
    branches/python3/spambayes/spambayes/ImageStripper.py
    branches/python3/spambayes/spambayes/ImapUI.py
    branches/python3/spambayes/spambayes/MoinSecurityPolicy.py
    branches/python3/spambayes/spambayes/Options.py
    branches/python3/spambayes/spambayes/OptionsClass.py
    branches/python3/spambayes/spambayes/ProxyUI.py
    branches/python3/spambayes/spambayes/PyMeldLite.py
    branches/python3/spambayes/spambayes/ServerUI.py
    branches/python3/spambayes/spambayes/Stats.py
    branches/python3/spambayes/spambayes/TestDriver.py
    branches/python3/spambayes/spambayes/TestToolsUI.py
    branches/python3/spambayes/spambayes/UserInterface.py
    branches/python3/spambayes/spambayes/Version.py
    branches/python3/spambayes/spambayes/XMLRPCPlugin.py
    branches/python3/spambayes/spambayes/cdb.py
    branches/python3/spambayes/spambayes/cdb_classifier.py
    branches/python3/spambayes/spambayes/chi2.py
    branches/python3/spambayes/spambayes/classifier.py
    branches/python3/spambayes/spambayes/compatcsv.py
    branches/python3/spambayes/spambayes/compatheapq.py
    branches/python3/spambayes/spambayes/compatsets.py
    branches/python3/spambayes/spambayes/dbmstorage.py
    branches/python3/spambayes/spambayes/dnscache.py
    branches/python3/spambayes/spambayes/hammiebulk.py
    branches/python3/spambayes/spambayes/i18n.py
    branches/python3/spambayes/spambayes/mboxutils.py
    branches/python3/spambayes/spambayes/message.py
    branches/python3/spambayes/spambayes/msgs.py
    branches/python3/spambayes/spambayes/oe_mailbox.py
    branches/python3/spambayes/spambayes/port.py
    branches/python3/spambayes/spambayes/postfixproxy.py
    branches/python3/spambayes/spambayes/safepickle.py
    branches/python3/spambayes/spambayes/smtpproxy.py
    branches/python3/spambayes/spambayes/storage.py
    branches/python3/spambayes/spambayes/test/test_Corpus.py
    branches/python3/spambayes/spambayes/test/test_FileCorpus.py
    branches/python3/spambayes/spambayes/test/test_message.py
    branches/python3/spambayes/spambayes/test/test_programs.py
    branches/python3/spambayes/spambayes/test/test_sb_dbexpimp.py
    branches/python3/spambayes/spambayes/test/test_sb_filter.py
    branches/python3/spambayes/spambayes/test/test_sb_imapfilter.py
    branches/python3/spambayes/spambayes/test/test_sb_pop3dnd.py
    branches/python3/spambayes/spambayes/test/test_sb_server.py
    branches/python3/spambayes/spambayes/test/test_smtpproxy.py
    branches/python3/spambayes/spambayes/test/test_stats.py
    branches/python3/spambayes/spambayes/test/test_storage.py
    branches/python3/spambayes/spambayes/tokenizer.py
    branches/python3/spambayes/testtools/cmp.py
    branches/python3/spambayes/testtools/es2hs.py
    branches/python3/spambayes/testtools/fpfn.py
    branches/python3/spambayes/testtools/incremental.py
    branches/python3/spambayes/testtools/mboxtest.py
    branches/python3/spambayes/testtools/mkgraph.py
    branches/python3/spambayes/testtools/mksets.py
    branches/python3/spambayes/testtools/rates.py
    branches/python3/spambayes/testtools/regimes.py
    branches/python3/spambayes/testtools/simplexloop.py
    branches/python3/spambayes/testtools/sort+group.py
    branches/python3/spambayes/testtools/table.py
    branches/python3/spambayes/testtools/timcv.py
    branches/python3/spambayes/testtools/timtest.py
    branches/python3/spambayes/testtools/weaktest.py
    branches/python3/spambayes/utilities/HistToGNU.py
    branches/python3/spambayes/utilities/cleanarch.py
    branches/python3/spambayes/utilities/convert_config_file.py
    branches/python3/spambayes/utilities/convert_db.py
    branches/python3/spambayes/utilities/dump_cdb.py
    branches/python3/spambayes/utilities/export_apple_mail.py
    branches/python3/spambayes/utilities/extractmessages.py
    branches/python3/spambayes/utilities/hammer.py
    branches/python3/spambayes/utilities/hammie2cdb.py
    branches/python3/spambayes/utilities/loosecksum.py
    branches/python3/spambayes/utilities/mboxcount.py
    branches/python3/spambayes/utilities/mkreversemap.py
    branches/python3/spambayes/utilities/pop3graph.py
    branches/python3/spambayes/utilities/rebal.py
    branches/python3/spambayes/utilities/split.py
    branches/python3/spambayes/utilities/splitn.py
    branches/python3/spambayes/utilities/splitndirs.py
    branches/python3/spambayes/utilities/which_database.py
    branches/python3/spambayes/windows/autoconfigure.py
    branches/python3/spambayes/windows/pop3proxy_service.py
    branches/python3/spambayes/windows/pop3proxy_tray.py
    branches/python3/spambayes/windows/py2exe/gen_py/office-9.py
    branches/python3/spambayes/windows/py2exe/gen_py/outlook-9.py

Modified: branches/python3/spambayes/Outlook2000/addin.py
===================================================================
--- branches/python3/spambayes/Outlook2000/addin.py	2009-11-09 02:30:03 UTC (rev 3253)
+++ branches/python3/spambayes/Outlook2000/addin.py	2009-11-09 02:59:10 UTC (rev 3254)
@@ -3,7 +3,7 @@
 import types
 import warnings
 import traceback
-import _winreg
+import winreg
 from types import UnicodeType
 
 # *sigh* - this is for the binary installer, and for the sake of one line
@@ -35,7 +35,7 @@
 
 import win32gui, win32con, win32clipboard # for button images!
 
-import timer, thread
+import timer, _thread
 
 from dialogs.dlgutils import SetWaitCursor
 
@@ -106,9 +106,9 @@
 try:
     from win32com.client import CastTo, WithEvents
 except ImportError:
-    print "*" * 50
-    print "You appear to be running a win32all version pre 151, which is pretty old"
-    print "I'm afraid it is time to upgrade"
+    print("*" * 50)
+    print("You appear to be running a win32all version pre 151, which is pretty old")
+    print("I'm afraid it is time to upgrade")
     raise
 # we seem to have all the COM support we need - let's rock!
 
@@ -134,18 +134,18 @@
 def TrainAsHam(msgstore_message, manager, rescore = True, save_db = True):
     import train
     subject = msgstore_message.subject
-    print "Training on message '%s' in '%s - " % \
+    print("Training on message '%s' in '%s - " % \
             (subject,
-             msgstore_message.GetFolder().GetFQName()),
+             msgstore_message.GetFolder().GetFQName()), end=' ')
     if train.train_message(msgstore_message, False, manager.classifier_data):
-        print "trained as good"
+        print("trained as good")
         # Simplest way to rescore is to re-filter with all_actions = False
         if rescore:
             import filter
             filter.filter_message(msgstore_message, manager, all_actions = False)
 
     else:
-        print "already was trained as good"
+        print("already was trained as good")
     manager.classifier_data.message_db.load_msg(msgstore_message)
     assert train.been_trained_as_ham(msgstore_message)
     if save_db:
@@ -154,17 +154,17 @@
 def TrainAsSpam(msgstore_message, manager, rescore = True, save_db = True):
     import train
     subject = msgstore_message.subject
-    print "Training on message '%s' in '%s - " % \
+    print("Training on message '%s' in '%s - " % \
             (subject,
-             msgstore_message.GetFolder().GetFQName()),
+             msgstore_message.GetFolder().GetFQName()), end=' ')
     if train.train_message(msgstore_message, True, manager.classifier_data):
-        print "trained as spam"
+        print("trained as spam")
         # Simplest way to rescore is to re-filter with all_actions = False
         if rescore:
             import filter
             filter.filter_message(msgstore_message, manager, all_actions = False)
     else:
-        print "already was trained as spam"
+        print("already was trained as spam")
     manager.classifier_data.message_db.load_msg(msgstore_message)
     assert train.been_trained_as_spam(msgstore_message)
     # And if the DB can save itself incrementally, do it now
@@ -215,14 +215,14 @@
             # get the foldername before the move operation!
             folder_name = msgstore_message.GetFolder().GetFQName()
             disposition = filter.filter_message(msgstore_message, manager)
-            print "Message '%s' in '%s' had a Spam classification of '%s'" \
+            print("Message '%s' in '%s' had a Spam classification of '%s'" \
                   % (msgstore_message.GetSubject(),
                      folder_name,
-                     disposition)
+                     disposition))
 
             manager.HandleNotification(disposition)
         else:
-            print "Spam filtering is disabled - ignoring new message"
+            print("Spam filtering is disabled - ignoring new message")
     except manager.message_store.NotFoundException:
         manager.LogDebug(1, "ProcessMessage had the message moved out from underneath us")
     manager.LogDebug(2, "ProcessMessage finished for", msgstore_message.subject)
@@ -242,7 +242,7 @@
 # Folder event handler classes
 class _BaseItemsEvent:
     def Init(self, target, application, manager):
-        self.owner_thread_ident = thread.get_ident() # check we arent multi-threaded
+        self.owner_thread_ident = _thread.get_ident() # check we arent multi-threaded
         self.application = application
         self.manager = manager
         self.target = target
@@ -261,17 +261,17 @@
         interval = self.manager.config.filter.timer_interval
         use_timer = timer_enabled and start_delay and interval
         if timer_enabled and not use_timer:
-            print "*" * 50
-            print "The timer is enabled, but one of the timer intervals values is zero"
-            print "You must set both intervals before the timer will enable"
+            print("*" * 50)
+            print("The timer is enabled, but one of the timer intervals values is zero")
+            print("You must set both intervals before the timer will enable")
         if use_timer and not hasattr(timer, "__version__"):
             # No binaries will see this.
-            print "*" * 50
-            print "SORRY: You have tried to enable the timer, but you have a"
-            print "leaky version of the 'timer' module.  These leaks prevent"
-            print "Outlook from shutting down.  Please update win32all to post 154"
-            print "The timer is NOT enabled..."
-            print "*" * 50
+            print("*" * 50)
+            print("SORRY: You have tried to enable the timer, but you have a")
+            print("leaky version of the 'timer' module.  These leaks prevent")
+            print("Outlook from shutting down.  Please update win32all to post 154")
+            print("The timer is NOT enabled...")
+            print("*" * 50)
             use_timer = False
 
         if use_timer:
@@ -284,22 +284,22 @@
         # Don't allow insane values for the timer.
         if use_timer:
             too = None
-            if not isinstance(start_delay, types.FloatType) or \
-               not isinstance(interval, types.FloatType):
-                print "*" * 50
-                print "Timer values are garbage!", repr(start_delay), repr(interval)
+            if not isinstance(start_delay, float) or \
+               not isinstance(interval, float):
+                print("*" * 50)
+                print("Timer values are garbage!", repr(start_delay), repr(interval))
                 use_timer = False
             elif start_delay < 0.4 or interval < 0.4:
                 too = "too often"
             elif start_delay > 60 or interval > 60:
                 too = "too infrequently"
             if too:
-                print "*" * 50
-                print "The timer is configured to fire way " + too + \
+                print("*" * 50)
+                print("The timer is configured to fire way " + too + \
                   " (delay=%s seconds, interval=%s seconds)" \
-                  % (start_delay, interval)
-                print "Please adjust your configuration.  The timer is NOT enabled..."
-                print "*" * 50
+                  % (start_delay, interval))
+                print("Please adjust your configuration.  The timer is NOT enabled...")
+                print("*" * 50)
                 use_timer = False
 
         self.use_timer = use_timer
@@ -315,9 +315,9 @@
         self._KillTimer()
         _BaseItemsEvent.Close(self, *args)
     def _DoStartTimer(self, delay):
-        assert thread.get_ident() == self.owner_thread_ident
+        assert _thread.get_ident() == self.owner_thread_ident
         assert self.timer_id is None, "Shouldn't start a timer when already have one"
-        assert isinstance(delay, types.FloatType), "Timer values are float seconds"
+        assert isinstance(delay, float), "Timer values are float seconds"
         # And start a new timer.
         assert delay, "No delay means no timer!"
         delay = int(delay*1000) # convert to ms.
@@ -334,7 +334,7 @@
         self._DoStartTimer(delay)
 
     def _KillTimer(self):
-        assert thread.get_ident() == self.owner_thread_ident
+        assert _thread.get_ident() == self.owner_thread_ident
         if self.timer_id is not None:
             timer.kill_timer(self.timer_id)
             self.manager.LogDebug(2, "The timer with id=%d was stopped" % self.timer_id)
@@ -342,7 +342,7 @@
 
     def _TimerFunc(self, event, time):
         # Kill the timer first
-        assert thread.get_ident() == self.owner_thread_ident
+        assert _thread.get_ident() == self.owner_thread_ident
         self.manager.LogDebug(1, "The timer with id=%s fired" % self.timer_id)
         self._KillTimer()
         assert self.timer_generator, "Can't have a timer with no generator"
@@ -360,7 +360,7 @@
             # If the Spam score *is* saved, the generator should only return
             # ones that HaveSeen() returns False for, so therefore isn't a hit.
             while 1:
-                item = self.timer_generator.next()
+                item = next(self.timer_generator)
                 try:
                     if not HaveSeenMessage(item, self.manager):
                         break
@@ -627,7 +627,7 @@
         ver_latest = get_version(app_name, version_dict=latest)
         latest_ver_string = ver_latest.get_long_version(ADDIN_DISPLAY_NAME)
     except:
-        print "Error checking the latest version"
+        print("Error checking the latest version")
         traceback.print_exc()
         manager.ReportError(
             _("There was an error checking for the latest version\r\n"
@@ -636,7 +636,7 @@
         )
         return
 
-    print "Current version is %s, latest is %s." % (str(ver_current), str(ver_latest))
+    print("Current version is %s, latest is %s." % (str(ver_current), str(ver_latest)))
     if ver_latest > ver_current:
         url = get_download_page(app_name, version_dict=latest)
         msg = _("You are running %s\r\n\r\nThe latest available version is %s" \
@@ -644,7 +644,7 @@
                 "\r\n\r\nWould you like to visit this page now?") \
                 % (cur_ver_string, latest_ver_string, url)
         if manager.AskQuestion(msg):
-            print "Opening browser page", url
+            print("Opening browser page", url)
             os.startfile(url)
     else:
         msg = _("The latest available version is %s\r\n\r\n" \
@@ -658,12 +658,12 @@
     # the test suite to save shutting down Outlook each time we tweak it.
     reload(tester)
     try:
-        print "Executing automated tests..."
+        print("Executing automated tests...")
         tester.test(manager)
     except:
         traceback.print_exc()
-        print "Tests FAILED.  Sorry about that.  If I were you, I would do a full re-train ASAP"
-        print "Please delete any test messages from your Spam, Unsure or Inbox/Watch folders first."
+        print("Tests FAILED.  Sorry about that.  If I were you, I would do a full re-train ASAP")
+        print("Please delete any test messages from your Spam, Unsure or Inbox/Watch folders first.")
 
 # The "Spam" and "Not Spam" buttons
 # The event from Outlook's explorer that our folder has changed.
@@ -717,7 +717,7 @@
             msgstore_message.Save()
             # Must train before moving, else we lose the message!
             subject = msgstore_message.GetSubject()
-            print "Moving and spam training message '%s' - " % (subject,),
+            print("Moving and spam training message '%s' - " % (subject,), end=' ')
             TrainAsSpam(msgstore_message, self.manager, save_db = False)
             # Do the new message state if necessary.
             try:
@@ -727,9 +727,9 @@
                     msgstore_message.SetReadState(False)
                 else:
                     if new_msg_state not in ["", "None", None]:
-                        print "*** Bad new_msg_state value: %r" % (new_msg_state,)
+                        print("*** Bad new_msg_state value: %r" % (new_msg_state,))
             except pythoncom.com_error:
-                print "*** Failed to set the message state to '%s' for message '%s'" % (new_msg_state, subject)
+                print("*** Failed to set the message state to '%s' for message '%s'" % (new_msg_state, subject))
             # Now move it.
             msgstore_message.MoveToReportingError(self.manager, spam_folder)
             # Note the move will possibly also trigger a re-train
@@ -774,14 +774,14 @@
                 restore_folder = msgstore_message.GetRememberedFolder()
                 if restore_folder is None or \
                    msgstore_message.GetFolder() == restore_folder:
-                    print "Unable to determine source folder for message '%s' - restoring to Inbox" % (subject,)
+                    print("Unable to determine source folder for message '%s' - restoring to Inbox" % (subject,))
                     restore_folder = inbox_folder
 
                 # Record this recovery in our stats.
                 self.manager.stats.RecordTraining(True,
                                         self.manager.score(msgstore_message))
                 # Must train before moving, else we lose the message!
-                print "Recovering to folder '%s' and ham training message '%s' - " % (restore_folder.name, subject),
+                print("Recovering to folder '%s' and ham training message '%s' - " % (restore_folder.name, subject), end=' ')
                 TrainAsHam(msgstore_message, self.manager, save_db = False)
                 # Do the new message state if necessary.
                 try:
@@ -791,10 +791,10 @@
                         msgstore_message.SetReadState(False)
                     else:
                         if new_msg_state not in ["", "None", None]:
-                            print "*** Bad new_msg_state value: %r" % (new_msg_state,)
-                except msgstore.MsgStoreException, details:
-                    print "*** Failed to set the message state to '%s' for message '%s'" % (new_msg_state, subject)
-                    print details
+                            print("*** Bad new_msg_state value: %r" % (new_msg_state,))
+                except msgstore.MsgStoreException as details:
+                    print("*** Failed to set the message state to '%s' for message '%s'" % (new_msg_state, subject))
+                    print(details)
                 # Now move it.
                 msgstore_message.MoveToReportingError(self.manager, restore_folder)
             except msgstore.NotFoundException:
@@ -819,7 +819,7 @@
         elif fname=="delete_as_spam.bmp":
             bid = 6001
         else:
-            raise RuntimeError, "What bitmap to use for '%s'?" % fname
+            raise RuntimeError("What bitmap to use for '%s'?" % fname)
         handle = win32gui.LoadImage(sys.frozendllhandle, bid, win32con.IMAGE_BITMAP, 0, 0, win32con.LR_DEFAULTSIZE)
     else:
         if not os.path.isabs(fname):
@@ -827,7 +827,7 @@
             fname = os.path.join(manager.application_directory,
                                      "images", fname)
         if not os.path.isfile(fname):
-            print "WARNING - Trying to use image '%s', but it doesn't exist" % (fname,)
+            print("WARNING - Trying to use image '%s', but it doesn't exist" % (fname,))
             return None
         handle = win32gui.LoadImage(0, fname, win32con.IMAGE_BITMAP, 0, 0, win32con.LR_DEFAULTSIZE | win32con.LR_LOADFROMFILE)
     win32clipboard.OpenClipboard()
@@ -918,13 +918,13 @@
                                     Type = constants.msoControlPopup,
                                     Tag = "SpamBayesCommand.Popup")
                     if item is None:
-                        print "ERROR: Could't re-find control to delete"
+                        print("ERROR: Could't re-find control to delete")
                         break
                     item.Delete(False)
-                    print "The above toolbar message is common - " \
-                          "recreating the toolbar..."
-                except pythoncom.com_error, e:
-                    print "ERROR: Failed to delete our dead toolbar control"
+                    print("The above toolbar message is common - " \
+                          "recreating the toolbar...")
+                except pythoncom.com_error as e:
+                    print("ERROR: Failed to delete our dead toolbar control")
                     break
                 # ok - toolbar deleted - just run around the loop again
                 continue
@@ -1027,7 +1027,7 @@
         # elsewhere).  If we can not find the child control, we then try and
         # locate our toolbar, creating if necessary.  Our items get added to
         # that.
-        assert item_attrs.has_key('Tag'), "Need a 'Tag' attribute!"
+        assert 'Tag' in item_attrs, "Need a 'Tag' attribute!"
         image_fname = None
         if 'image' in item_attrs:
             image_fname = item_attrs['image']
@@ -1067,7 +1067,7 @@
                     else:
                         # for not broken - can't find toolbar.  Create a new one.
                         # Create it as a permanent one (which is default)
-                        print "Creating new SpamBayes toolbar to host our buttons"
+                        print("Creating new SpamBayes toolbar to host our buttons")
                         self.toolbar = bars.Add(toolbar_name,
                                                 constants.msoBarTop,
                                                 Temporary=False)
@@ -1076,10 +1076,10 @@
             # Now add the item itself to the parent.
             try:
                 item = parent.Controls.Add(Type=control_type, Temporary=temporary)
-            except pythoncom.com_error, e:
+            except pythoncom.com_error as e:
                 # Toolbars seem to still fail randomly for some users.
                 # eg, bug [ 755738 ] Latest CVS outllok doesn't work
-                print "FAILED to add the toolbar item '%s' - %s" % (tag,e)
+                print("FAILED to add the toolbar item '%s' - %s" % (tag,e))
                 return
             if image_fname:
                 # Eeek - only available in derived class.
@@ -1087,7 +1087,7 @@
                 but = CastTo(item, "_CommandBarButton")
                 SetButtonImage(but, image_fname, self.manager)
             # Set the extra attributes passed in.
-            for attr, val in item_attrs.items():
+            for attr, val in list(item_attrs.items()):
                 setattr(item, attr, val)
         # didn't previously set this, and it seems to fix alot of problem - so
         # we set it for every object, even existing ones.
@@ -1122,10 +1122,10 @@
                     ret.append(msgstore_message)
             except ms.NotFoundException:
                 pass
-            except ms.MsgStoreException, details:
-                print "Unexpected error fetching message"
+            except ms.MsgStoreException as details:
+                print("Unexpected error fetching message")
                 traceback.print_exc()
-                print details
+                print(details)
 
         if len(ret) == 0:
             self.manager.ReportError(_("No filterable mail items are selected"),
@@ -1197,7 +1197,7 @@
                         show_recover_as = True
                         show_delete_as = True
             except:
-                print "Error finding the MAPI folders for a folder switch event"
+                print("Error finding the MAPI folders for a folder switch event")
                 # As this happens once per move, we should only display it once.
                 self.manager.ReportErrorOnce(_(
                     "There appears to be a problem with the SpamBayes"
@@ -1243,7 +1243,7 @@
         if len(self.explorers)==0:
             # No more explorers - disconnect all events.
             # (not doing this causes shutdown problems)
-            for tag, button in self.button_event_map.items():
+            for tag, button in list(self.button_event_map.items()):
                 closer = getattr(button, "Close", None)
                 if closer is not None:
                     closer()
@@ -1295,13 +1295,13 @@
             v = get_current_version()
             vstring = v.get_long_version(ADDIN_DISPLAY_NAME)
             if not hasattr(sys, "frozen"): vstring += " from source"
-            print vstring
+            print(vstring)
             major, minor, spack, platform, ver_str = win32api.GetVersionEx()
-            print "on Windows %d.%d.%d (%s)" % \
-                  (major, minor, spack, ver_str)
-            print "using Python", sys.version
+            print("on Windows %d.%d.%d (%s)" % \
+                  (major, minor, spack, ver_str))
+            print("using Python", sys.version)
             from time import asctime, localtime
-            print "Log created", asctime(localtime())
+            print("Log created", asctime(localtime()))
 
             self.explorers_events = None # create at OnStartupComplete
 
@@ -1311,7 +1311,7 @@
                 # bootstrap code that can't happen until startup is complete.
                 self.OnStartupComplete(None)
         except:
-            print "Error connecting to Outlook!"
+            print("Error connecting to Outlook!")
             traceback.print_exc()
             # We can't translate this string, as we haven't managed to load
             # the translation tools.
@@ -1346,7 +1346,7 @@
             try:
                 self.ProcessMissedMessages()
             except:
-                print "Error processing missed messages!"
+                print("Error processing missed messages!")
                 traceback.print_exc()
         else:
             # We should include this fact in the log, as I suspect a
@@ -1385,8 +1385,8 @@
                     "Skipping processing of missed messages in folder '%s', "
                     "as it is not available" % folder.name)
             elif event_hook.use_timer:
-                print "Processing missed spam in folder '%s' by starting a timer" \
-                      % (folder.name,)
+                print("Processing missed spam in folder '%s' by starting a timer" \
+                      % (folder.name,))
                 event_hook._StartTimer()
             else:
                 num = 0
@@ -1395,8 +1395,8 @@
                     ProcessMessage(message, manager)
                     num += 1
                 # See if perf hurts anyone too much.
-                print "Processing %d missed spam in folder '%s' took %gms" \
-                      % (num, folder.name, (clock()-start)*1000)
+                print("Processing %d missed spam in folder '%s' took %gms" \
+                      % (num, folder.name, (clock()-start)*1000))
 
     def FiltersChanged(self):
         try:
@@ -1415,7 +1415,7 @@
             except:
                 # If this fails, just log an error - don't bother with
                 # the traceback
-                print "Error adding field to 'Unsure' folder %r" % (unsure_id,)
+                print("Error adding field to 'Unsure' folder %r" % (unsure_id,))
                 etype, value, tb = sys.exc_info()
                 tb = None # dont want it, and nuke circular ref
                 traceback.print_exception(etype, value, tb)
@@ -1438,8 +1438,8 @@
                                        SpamFolderItemsEvent,
                                        "incremental training")
                 )
-        for k in self.folder_hooks.keys():
-            if not new_hooks.has_key(k):
+        for k in list(self.folder_hooks.keys()):
+            if k not in new_hooks:
                 self.folder_hooks[k].Close()
         self.folder_hooks = new_hooks
 
@@ -1459,7 +1459,7 @@
                 name = msgstore_folder.GetFQName()
                 try:
                     folder = msgstore_folder.GetOutlookItem()
-                except self.manager.message_store.MsgStoreException, details:
+                except self.manager.message_store.MsgStoreException as details:
                     # Exceptions here are most likely when the folder is valid
                     # and available to MAPI, but not via the Outlook.
                     # One good way to provoke this is to configure Outlook's
@@ -1467,9 +1467,9 @@
                     # when you start Outlook, it immediately displays an
                     # error and terminates.  During this process, the addin
                     # is initialized, attempts to get the folders, and fails.
-                    print "FAILED to open the Outlook folder '%s' " \
-                          "to hook events" % name
-                    print details
+                    print("FAILED to open the Outlook folder '%s' " \
+                          "to hook events" % name)
+                    print(details)
                     continue
                 # Ensure the field is created before we hook the folder
                 # events, else there is a chance our event handler will
@@ -1481,8 +1481,8 @@
                     # 'spam' field is not fatal, nor really even worth
                     # telling the user about, nor even worth a traceback
                     # (as it is likely a COM error).
-                    print "ERROR: Failed to check folder '%s' for " \
-                          "Spam field" % name
+                    print("ERROR: Failed to check folder '%s' for " \
+                          "Spam field" % name)
                     etype, value, tb = sys.exc_info()
                     tb = None # dont want it, and nuke circular ref
                     traceback.print_exception(etype, value, tb)
@@ -1490,21 +1490,21 @@
                 try:
                     new_hook = DispatchWithEvents(folder.Items, HandlerClass)
                 except ValueError:
-                    print "WARNING: Folder '%s' can not hook events" % (name,)
+                    print("WARNING: Folder '%s' can not hook events" % (name,))
                     new_hook = None
                 if new_hook is not None:
                     new_hook.Init(msgstore_folder, self.application, self.manager)
                     new_hooks[msgstore_folder.id] = new_hook
-                    print "SpamBayes: Watching (for %s) in '%s'" % (what, name)
+                    print("SpamBayes: Watching (for %s) in '%s'" % (what, name))
             else:
                 new_hooks[msgstore_folder.id] = existing
                 existing.ReInit()
         return new_hooks
 
     def OnDisconnection(self, mode, custom):
-        print "SpamBayes - Disconnecting from Outlook"
+        print("SpamBayes - Disconnecting from Outlook")
         if self.folder_hooks:
-            for hook in self.folder_hooks.values():
+            for hook in list(self.folder_hooks.values()):
                 hook.Close()
             self.folder_hooks = None
         if self.explorers_events is not None:
@@ -1517,10 +1517,10 @@
             # it (ie, the dialog)
             self.manager.Save()
             # Report some simple stats, for session, and for total.
-            print "Session:"
-            print "\r\n".join(self.manager.stats.GetStats(session_only=True))
-            print "Total:"
-            print "\r\n".join(self.manager.stats.GetStats())
+            print("Session:")
+            print("\r\n".join(self.manager.stats.GetStats(session_only=True)))
+            print("Total:")
+            print("\r\n".join(self.manager.stats.GetStats()))
             self.manager.Close()
             self.manager = None
 
@@ -1528,7 +1528,7 @@
             # The user has de-selected us.  Remove the toolbars we created
             # (Maybe we can exploit this later to remove toolbars as part
             # of uninstall?)
-            print "SpamBayes is being manually disabled - deleting toolbar"
+            print("SpamBayes is being manually disabled - deleting toolbar")
             try:
                 explorers = self.application.Explorers
                 for i in range(explorers.Count):
@@ -1536,22 +1536,22 @@
                     try:
                         toolbar = explorer.CommandBars.Item(toolbar_name)
                     except pythoncom.com_error:
-                        print "Could not find our toolbar to delete!"
+                        print("Could not find our toolbar to delete!")
                     else:
                         toolbar.Delete()
             except:
-                print "ERROR deleting toolbar"
+                print("ERROR deleting toolbar")
                 traceback.print_exc()
 
         self.application = None
 
-        print "Addin terminating: %d COM client and %d COM servers exist." \
-              % (pythoncom._GetInterfaceCount(), pythoncom._GetGatewayCount())
+        print("Addin terminating: %d COM client and %d COM servers exist." \
+              % (pythoncom._GetInterfaceCount(), pythoncom._GetGatewayCount()))
         try:
             # will be available if "python_d addin.py" is used to
             # register the addin.
             total_refs = sys.gettotalrefcount() # debug Python builds only
-            print "%d Python references exist" % (total_refs,)
+            print("%d Python references exist" % (total_refs,))
         except AttributeError:
             pass
 
@@ -1562,13 +1562,13 @@
         pass
 
 def _DoRegister(klass, root):
-    key = _winreg.CreateKey(root,
+    key = winreg.CreateKey(root,
                             "Software\\Microsoft\\Office\\Outlook\\Addins")
-    subkey = _winreg.CreateKey(key, klass._reg_progid_)
-    _winreg.SetValueEx(subkey, "CommandLineSafe", 0, _winreg.REG_DWORD, 0)
-    _winreg.SetValueEx(subkey, "LoadBehavior", 0, _winreg.REG_DWORD, 3)
-    _winreg.SetValueEx(subkey, "Description", 0, _winreg.REG_SZ, "SpamBayes anti-spam tool")
-    _winreg.SetValueEx(subkey, "FriendlyName", 0, _winreg.REG_SZ, "SpamBayes")
+    subkey = winreg.CreateKey(key, klass._reg_progid_)
+    winreg.SetValueEx(subkey, "CommandLineSafe", 0, winreg.REG_DWORD, 0)
+    winreg.SetValueEx(subkey, "LoadBehavior", 0, winreg.REG_DWORD, 3)
+    winreg.SetValueEx(subkey, "Description", 0, winreg.REG_SZ, "SpamBayes anti-spam tool")
+    winreg.SetValueEx(subkey, "FriendlyName", 0, winreg.REG_SZ, "SpamBayes")
 
 # Note that Addins can be registered either in HKEY_CURRENT_USER or
 # HKEY_LOCAL_MACHINE.  If the former, then:
@@ -1594,8 +1594,8 @@
         DllUnregisterServer()
         # Don't catch exceptions here - if it fails, the Dll registration
         # must fail.
-        _DoRegister(klass, _winreg.HKEY_LOCAL_MACHINE)
-        print "Registration (in HKEY_LOCAL_MACHINE) complete."
+        _DoRegister(klass, winreg.HKEY_LOCAL_MACHINE)
+        print("Registration (in HKEY_LOCAL_MACHINE) complete.")
 
 def DllRegisterServer():
     klass = OutlookAddin
@@ -1604,26 +1604,26 @@
     # remove the HKLM registration here (but it can be re-added - see the
     # notes above.)
     try:
-        _winreg.DeleteKey(_winreg.HKEY_LOCAL_MACHINE,
+        winreg.DeleteKey(winreg.HKEY_LOCAL_MACHINE,
                           "Software\\Microsoft\\Office\\Outlook\\Addins\\" \
                           + klass._reg_progid_)
     except WindowsError:
         pass
-    _DoRegister(klass, _winreg.HKEY_CURRENT_USER)
-    print "Registration complete."
+    _DoRegister(klass, winreg.HKEY_CURRENT_USER)
+    print("Registration complete.")
 
 def DllUnregisterServer():
     klass = OutlookAddin
     # Try to remove the HKLM version.
     try:
-        _winreg.DeleteKey(_winreg.HKEY_LOCAL_MACHINE,
+        winreg.DeleteKey(winreg.HKEY_LOCAL_MACHINE,
                           "Software\\Microsoft\\Office\\Outlook\\Addins\\" \
                           + klass._reg_progid_)
     except WindowsError:
         pass
     # and again for current user.
     try:
-        _winreg.DeleteKey(_winreg.HKEY_CURRENT_USER,
+        winreg.DeleteKey(winreg.HKEY_CURRENT_USER,
                           "Software\\Microsoft\\Office\\Outlook\\Addins\\" \
                           + klass._reg_progid_)
     except WindowsError:

Modified: branches/python3/spambayes/Outlook2000/config.py
===================================================================
--- branches/python3/spambayes/Outlook2000/config.py	2009-11-09 02:30:03 UTC (rev 3253)
+++ branches/python3/spambayes/Outlook2000/config.py	2009-11-09 02:59:10 UTC (rev 3254)
@@ -37,18 +37,18 @@
         if not is_multi and not value:
             return None
         # Now sure why we get non-strings here for multis
-        if type(value) == types.ListType:
+        if type(value) == list:
             return value
         # If we really care here, it would be fairly easy to use a regex
         # etc to pull these IDs apart.  eval is easier for now :)
         try:
             items = eval(value)
         except:
-            error = "Invalid value (%s:%s)" % (sys.exc_type, sys.exc_value)
+            error = "Invalid value (%s:%s)" % (sys.exc_info()[0], sys.exc_info()[1])
         check_items = []
         if error is None:
             if is_multi:
-                if type(items) != types.ListType:
+                if type(items) != list:
                     error = "Multi-valued ID must yield a list"
                 check_items = items
             else:
@@ -62,9 +62,9 @@
                     error = "Each ID must be a tuple of 2 strings"
                     break
         if error is not None:
-            print "Failed to convert FolderID value '%r', is_multi=%d" % \
-                  (value, is_multi)
-            print error
+            print("Failed to convert FolderID value '%r', is_multi=%d" % \
+                  (value, is_multi))
+            print(error)
             if is_multi:
                 return []
             else:
@@ -78,13 +78,13 @@
         return str(self.value)
 
     def multiple_values_allowed(self):
-        return type(self.value)==types.ListType
+        return type(self.value)==list
 
     def is_valid_single(self, value):
         return value is None or \
-               (type(value)==types.TupleType and \
+               (type(value)==tuple and \
                len(value)==2 and \
-               type(value[0])==type(value[1])==types.StringType)
+               type(value[0])==type(value[1])==bytes)
 
 defaults = {
     "General" : (
@@ -337,9 +337,9 @@
                 container = SectionContainer(self._options, key)
                 self.__dict__[attr] = container
                 return container
-        raise AttributeError, "Options has no section '%s'" % attr
+        raise AttributeError("Options has no section '%s'" % attr)
     def __setattr__(self, attr, val):
-        raise AttributeError, "No section [%s]" % attr
+        raise AttributeError("No section [%s]" % attr)
     # and delegate a few methods so this object can be used in place of
     # a real options object. maybe should add this to getattr. do we want all?
     def get_option(self, section, name):
@@ -365,11 +365,11 @@
     def _dump(self, thisname="<root>", level=0):
         import pprint
         prefix = "  " * level
-        print "%s%s:" % (prefix, thisname)
-        for name, ob in self.__dict__.items():
+        print("%s%s:" % (prefix, thisname))
+        for name, ob in list(self.__dict__.items()):
             d = getattr(ob, "_dump", None)
             if d is None:
-                print "%s %s: %s" % (prefix, name, pprint.pformat(ob))
+                print("%s %s: %s" % (prefix, name, pprint.pformat(ob)))
             else:
                 d(name, level+1)
 
@@ -383,56 +383,56 @@
     options.merge_files(['delme.cfg'])
     c = OptionsContainer(options)
     f = options.get("Training", "ham_folder_ids")
-    print "Folders before set are", f
+    print("Folders before set are", f)
     for i in f:
-        print i, type(i)
+        print(i, type(i))
     new_folder_ids = [('000123','456789'), ('ABCDEF', 'FEDCBA')]
     options.set("Training", "ham_folder_ids", new_folder_ids)
     f = options.get("Training", "ham_folder_ids")
-    print "Folders after set are", f
+    print("Folders after set are", f)
     for i in f:
-        print i, type(i)
+        print(i, type(i))
 
     try:
         c.filter.oops = "Foo"
     except (AttributeError,KeyError): # whatever :)
         pass
     else:
-        print "ERROR: I was able to set an invalid sub-property!"
+        print("ERROR: I was able to set an invalid sub-property!")
 
     try:
         c.oops = "Foo"
     except (AttributeError,KeyError): # whatever :)
         pass
     else:
-        print "ERROR: I was able to set an invalid top-level property!"
+        print("ERROR: I was able to set an invalid top-level property!")
 
     # Test single ID folders.
     if c.filter.unsure_folder_id is not None:
-        print "It appears we loaded a folder ID - resetting"
+        print("It appears we loaded a folder ID - resetting")
         c.filter.unsure_folder_id = None
     unsure_id = c.filter.unsure_folder_id
-    if unsure_id is not None: raise ValueError, "unsure_id wrong (%r)" % (c.filter.unsure_folder_id,)
+    if unsure_id is not None: raise ValueError("unsure_id wrong (%r)" % (c.filter.unsure_folder_id,))
     unsure_id = c.filter.unsure_folder_id = ('12345', 'abcdef')
-    if unsure_id != c.filter.unsure_folder_id: raise ValueError, "unsure_id wrong (%r)" % (c.filter.unsure_folder_id,)
+    if unsure_id != c.filter.unsure_folder_id: raise ValueError("unsure_id wrong (%r)" % (c.filter.unsure_folder_id,))
     c.filter.unsure_folder_id = None
-    if c.filter.unsure_folder_id is not None: raise ValueError, "unsure_id wrong (%r)" % (c.filter.unsure_folder_id,)
+    if c.filter.unsure_folder_id is not None: raise ValueError("unsure_id wrong (%r)" % (c.filter.unsure_folder_id,))
 
     options.set("Filter", "filter_now", True)
-    print "Filter_now from container is", c.filter.filter_now
+    print("Filter_now from container is", c.filter.filter_now)
     options.set("Filter", "filter_now", False)
-    print "Filter_now from container is now", c.filter.filter_now
+    print("Filter_now from container is now", c.filter.filter_now)
     c.filter.filter_now = True
-    print "Filter_now from container is finally", c.filter.filter_now
-    print "Only unread is", c.filter_now.only_unread
+    print("Filter_now from container is finally", c.filter.filter_now)
+    print("Only unread is", c.filter_now.only_unread)
     v = r"/foo/bar"
     c.general.data_directory=v
-    if c.general.data_directory!=v: print "Bad directory!", c.general.data_directory
+    if c.general.data_directory!=v: print("Bad directory!", c.general.data_directory)
     v = r"c:\test directory\some sub directory"
     c.general.data_directory=v
-    if c.general.data_directory!=v: print "Bad directory!", c.general.data_directory
+    if c.general.data_directory!=v: print("Bad directory!", c.general.data_directory)
     v = r"\\server\c$"
     c.general.data_directory=v
-    if c.general.data_directory!=v: print "Bad directory!", c.general.data_directory
+    if c.general.data_directory!=v: print("Bad directory!", c.general.data_directory)
     options.update_file("delme.cfg")
-    print "Created 'delme.cfg'"
+    print("Created 'delme.cfg'")

Modified: branches/python3/spambayes/Outlook2000/config_wizard.py
===================================================================
--- branches/python3/spambayes/Outlook2000/config_wizard.py	2009-11-09 02:30:03 UTC (rev 3253)
+++ branches/python3/spambayes/Outlook2000/config_wizard.py	2009-11-09 02:59:10 UTC (rev 3254)
@@ -139,7 +139,7 @@
             try:
                 os.remove(fname)
             except OSError:
-                print "Warning: unable to remove", fname
+                print("Warning: unable to remove", fname)
 
 def CreateWizardConfig(manager, from_existing):
     import config

Modified: branches/python3/spambayes/Outlook2000/dialogs/FolderSelector.py
===================================================================
--- branches/python3/spambayes/Outlook2000/dialogs/FolderSelector.py	2009-11-09 02:30:03 UTC (rev 3253)
+++ branches/python3/spambayes/Outlook2000/dialogs/FolderSelector.py	2009-11-09 02:59:10 UTC (rev 3254)
@@ -1,5 +1,5 @@
-from __future__ import generators
 
+
 import sys, os
 import win32con
 import commctrl
@@ -9,7 +9,7 @@
 
 import struct, array
 
-import dlgutils
+from . import dlgutils
 
 from pprint import pprint # debugging only
 verbose = 0
@@ -29,7 +29,7 @@
 
     def dump(self, level=0):
         prefix = "  " * level
-        print prefix + self.name
+        print(prefix + self.name)
         for c in self.children:
             c.dump(level+1)
 
@@ -69,7 +69,7 @@
                                        PR_STORE_ENTRYID,
                                        PR_DISPLAY_NAME_A), None, order, 0)
     if verbose:
-        print "Rows for sub-folder of", folder_spec.name, "-", folder_spec.folder_id
+        print("Rows for sub-folder of", folder_spec.name, "-", folder_spec.folder_id)
         pprint(rows)
     for (eid_tag, eid),(storeeid_tag, store_eid), (name_tag, name) in rows:
         # Note the eid we get here is short-term - hence we must
@@ -97,11 +97,11 @@
             else:
                 spec.children = None # Flag as "not yet built"
             children.append(spec)
-        except (pythoncom.com_error, manager.message_store.MsgStoreException), details:
+        except (pythoncom.com_error, manager.message_store.MsgStoreException) as details:
             # Users have reported failure here - it is not clear if the
             # entire tree is going to fail, or just this folder
-            print "** Unable to open child folder - ignoring"
-            print details
+            print("** Unable to open child folder - ignoring")
+            print(details)
     dlgutils.SetWaitCursor(0)
     return children
 
@@ -111,7 +111,7 @@
     prop_tags = PR_ENTRYID, PR_DISPLAY_NAME_A
     rows = mapi.HrQueryAllRows(tab, prop_tags, None, None, 0)
     if verbose:
-        print "message store rows:"
+        print("message store rows:")
         pprint(rows)
     for row in rows:
         (eid_tag, eid), (name_tag, name) = row
@@ -122,24 +122,24 @@
             hr, data = msgstore.GetProps((PR_IPM_SUBTREE_ENTRYID,)+ignore_ids, 0)
             # It appears that not all stores have a subtree.
             if PROP_TYPE(data[0][0]) != PT_BINARY:
-                print "FolderSelector dialog found message store without a subtree - ignoring"
+                print("FolderSelector dialog found message store without a subtree - ignoring")
                 continue
             subtree_eid = data[0][1]
             ignore_eids = [item[1] for item in data[1:] if PROP_TYPE(item[0])==PT_BINARY]
-        except pythoncom.com_error, details:
+        except pythoncom.com_error as details:
             # Handle 'expected' errors.
             if details[0]== mapi.MAPI_E_FAILONEPROVIDER:
-                print "A message store is temporarily unavailable - " \
-                      "it will not appear in the Folder Selector dialog"
+                print("A message store is temporarily unavailable - " \
+                      "it will not appear in the Folder Selector dialog")
             else:
                 # Some weird error opening a folder tree
                 # Just print a warning and ignore the tree.
-                print "Failed to open a message store for the FolderSelector dialog"
-                print "Exception details:", details
+                print("Failed to open a message store for the FolderSelector dialog")
+                print("Exception details:", details)
             continue
         folder_id = hex_eid, mapi.HexFromBin(subtree_eid)
         if verbose:
-            print "message store root folder id is", folder_id
+            print("message store root folder id is", folder_id)
 
         spec = FolderSpec(folder_id, name, ignore_eids)
         spec.children = None
@@ -254,7 +254,7 @@
 #########################################################################
 ## The dialog itself
 #########################################################################
-import dlgcore
+from . import dlgcore
 
 FolderSelector_Parent = dlgcore.TooltipDialog
 class FolderSelector(FolderSelector_Parent):
@@ -338,11 +338,11 @@
                                         cItems,
                                         item_id))
         if verbose:
-            print "Inserting item", repr(insert_buf), "-",
+            print("Inserting item", repr(insert_buf), "-", end=' ')
         hitem = win32gui.SendMessage(self.list, commctrl.TVM_INSERTITEM,
                                         0, insert_buf)
         if verbose:
-            print "got back handle", hitem
+            print("got back handle", hitem)
         return hitem
 
     def _InsertSubFolders(self, hParent, folderSpec):
@@ -368,14 +368,14 @@
         for folder_id in self.selected_ids:
             try:
                 folder = self.manager.message_store.GetFolder(folder_id)
-            except self.manager.message_store.MsgStoreException, details:
-                print "Can't find a folder to expand:", details
+            except self.manager.message_store.MsgStoreException as details:
+                print("Can't find a folder to expand:", details)
                 folder = None
             while folder is not None:
                 try:
                     parent = folder.GetParent()
-                except self.manager.message_store.MsgStoreException, details:
-                    print "Can't find folder's parent:", details
+                except self.manager.message_store.MsgStoreException as details:
+                    print("Can't find folder's parent:", details)
                     parent = None
                 if parent is not None and \
                    not self.InIDs(parent.GetID(), folders_to_expand):
@@ -503,7 +503,7 @@
                         # empty-display-name parent, which should not be
                         # the case.
                         grandparent = parent.GetParent()
-                    except self.manager.message_store.MsgStoreException, details:
+                    except self.manager.message_store.MsgStoreException as details:
                         hr, msg, exc, argErr = details.mapi_exception
                         if hr == winerror.E_ACCESSDENIED:
                             valid = parent is not None
@@ -511,9 +511,9 @@
                             raise # but only down a couple of lines...
                     else:
                         valid = parent is not None and grandparent is not None
-                except self.manager.message_store.MsgStoreException, details:
-                    print "Eeek - couldn't get the folder to check " \
-                          "valid:", details
+                except self.manager.message_store.MsgStoreException as details:
+                    print("Eeek - couldn't get the folder to check " \
+                          "valid:", details)
                     valid = False
                 if not valid:
                     if result_valid: # are we the first invalid?
@@ -542,7 +542,7 @@
         else:
             win32gui.SendMessage(child, win32con.BM_SETCHECK, self.checkbox_state)
         self.list = self.GetDlgItem("IDC_LIST_FOLDERS")
-        import resources
+        from . import resources
         mod_handle, mod_bmp, extra_flags = \
              resources.GetImageParamsFromBitmapID(self.dialog_parser, "IDB_FOLDERS")
         bitmapMask = win32api.RGB(0,0,255)
@@ -732,7 +732,7 @@
                         # And update the tree with the new item
                         buf, extra = PackTVITEM(handle, None, None, name, None, None, None, None)
                         win32gui.SendMessage(self.list, commctrl.TVM_SETITEM, 0, buf)
-                    except pythoncom.com_error, details:
+                    except pythoncom.com_error as details:
                         hr, msg, exc, arg = details
                         if hr == mapi.MAPI_E_COLLISION:
                             user_msg = "A folder with that name already exists"
@@ -763,7 +763,7 @@
     ids = [("0000","0000"),] # invalid ID for testing.
     d=FolderSelector(0, mgr, ids, single_select = single_select)
     if d.DoModal() != win32con.IDOK:
-        print "Cancelled"
+        print("Cancelled")
         return
     ids, include_sub = d.GetSelectedIDs()
     d=FolderSelector(0, mgr, ids, single_select = single_select, checkbox_state = include_sub)

Modified: branches/python3/spambayes/Outlook2000/dialogs/__init__.py
===================================================================
--- branches/python3/spambayes/Outlook2000/dialogs/__init__.py	2009-11-09 02:30:03 UTC (rev 3253)
+++ branches/python3/spambayes/Outlook2000/dialogs/__init__.py	2009-11-09 02:59:10 UTC (rev 3254)
@@ -19,7 +19,7 @@
     # If we are running from binaries, the rc name is not used at all - we
     # assume someone running from source previously generated the .py!
     if not hasattr(sys, "frozen") and not mod:
-        from resources import rc2py
+        from .resources import rc2py
         rc_path = os.path.dirname( rc2py.__file__ )
         if not os.path.isabs(rc_name):
             rc_name = os.path.join( rc_path, rc_name)
@@ -41,7 +41,7 @@
             rc_mtime = rc_size = None
         if rc_mtime!=mtime or rc_size!=size:
             # Need to generate the dialog.
-            print "Generating %s from %s" % (py_name, rc_name)
+            print("Generating %s from %s" % (py_name, rc_name))
             rc2py.convert(rc_name, py_name)
             if mod is not None:
                 reload(mod)
@@ -54,7 +54,7 @@
     """Displays another dialog"""
     if manager.dialog_parser is None:
         manager.dialog_parser = LoadDialogs()
-    import dialog_map
+    from . import dialog_map
     commands = dialog_map.dialog_map[idd]
     if not parent:
         import win32gui
@@ -63,7 +63,7 @@
         except win32gui.error:
             pass
 
-    import dlgcore
+    from . import dlgcore
     dlg = dlgcore.ProcessorDialog(parent, manager, config, idd, commands)
     return dlg.DoModal()
 
@@ -71,24 +71,24 @@
     import config_wizard, win32con
     config = config_wizard.CreateWizardConfig(manager, use_existing_config)
     if ShowDialog(parent, manager, config, idd) == win32con.IDOK:
-        print "Saving wizard changes"
+        print("Saving wizard changes")
         config_wizard.CommitWizardConfig(manager, config)
     else:
-        print "Cancelling wizard"
+        print("Cancelling wizard")
         config_wizard.CancelWizardConfig(manager, config)
 
 def MakePropertyPage(parent, manager, config, idd, yoffset=24):
     """Creates a child dialog box to use as property page in a tab control"""
     if manager.dialog_parser is None:
         manager.dialog_parser = LoadDialogs()
-    import dialog_map
+    from . import dialog_map
     commands = dialog_map.dialog_map[idd]
     if not parent:
         raise ValueError("Parent must be the tab control")
 
-    import dlgcore
+    from . import dlgcore
     dlg = dlgcore.ProcessorPage(parent, manager, config, idd, commands, yoffset)
     return dlg
 
-import dlgutils
+from . import dlgutils
 SetWaitCursor = dlgutils.SetWaitCursor

Modified: branches/python3/spambayes/Outlook2000/dialogs/async_processor.py
===================================================================
--- branches/python3/spambayes/Outlook2000/dialogs/async_processor.py	2009-11-09 02:30:03 UTC (rev 3253)
+++ branches/python3/spambayes/Outlook2000/dialogs/async_processor.py	2009-11-09 02:59:10 UTC (rev 3254)
@@ -1,10 +1,10 @@
 # An async command processor
-from dlgutils import *
+from .dlgutils import *
 import win32gui, win32api, win32con, commctrl
 import win32process
 import time
 
-import processors
+from . import processors
 
 verbose = 0
 
@@ -74,7 +74,7 @@
         # user knows the process has actually started.)
         control_tick = max(1,int(total_prop * self.total_control_ticks))
         if verbose:
-            print "Tick", self.current_stage_tick, "is", this_prop, "through the stage,", total_prop, "through the total - ctrl tick is", control_tick
+            print("Tick", self.current_stage_tick, "is", this_prop, "through the stage,", total_prop, "through the total - ctrl tick is", control_tick)
         win32api.PostMessage(self.hprogress, commctrl.PBM_SETPOS, control_tick)
 
     def _get_stage_text(self, text):
@@ -130,7 +130,7 @@
             while self.running:
                 win32gui.PumpWaitingMessages(0,-1)
                 if i % 100 == 0:
-                    print "Still waiting for async process to finish..."
+                    print("Still waiting for async process to finish...")
                 time.sleep(0.01)
                 i += 1
         return True
@@ -152,7 +152,7 @@
         elif msg == MYWM_FINISHED:
             self.OnFinished(wparam, lparam)
         else:
-            raise RuntimeError, "Not one of my messages??"
+            raise RuntimeError("Not one of my messages??")
 
     def OnFinished(self, wparam, lparam):
         self.seen_finished = True
@@ -244,13 +244,13 @@
             self.current_stage = 0
             self.set_stages( (("", 1.0),) )
 
-    print "Single stage test"
+    print("Single stage test")
     p = HackProgress()
     p.set_max_ticks(10)
     for i in range(10):
         p.tick()
 
-    print "First stage test"
+    print("First stage test")
     p = HackProgress()
     stages = ("Stage 1", 0.2), ("Stage 2", 0.8)
     p.set_stages(stages)
@@ -262,7 +262,7 @@
     p.set_max_ticks(20)
     for i in range(20):
         p.tick()
-    print "Second stage test"
+    print("Second stage test")
     p = HackProgress()
     stages = ("Stage 1", 0.9), ("Stage 2", 0.1)
     p.set_stages(stages)
@@ -272,7 +272,7 @@
     p.set_max_ticks(2)
     for i in range(2):
         p.tick()
-    print "Third stage test"
+    print("Third stage test")
     p = HackProgress()
     stages = ("Stage 1", 0.9), ("Stage 2", 0.1)
     p.set_stages(stages)
@@ -283,4 +283,4 @@
     for i in range(2):
         p.tick()
 
-    print "Done!"
+    print("Done!")

Modified: branches/python3/spambayes/Outlook2000/dialogs/dialog_map.py
===================================================================
--- branches/python3/spambayes/Outlook2000/dialogs/dialog_map.py	2009-11-09 02:30:03 UTC (rev 3253)
+++ branches/python3/spambayes/Outlook2000/dialogs/dialog_map.py	2009-11-09 02:59:10 UTC (rev 3254)
@@ -2,9 +2,9 @@
 # The Python Software Foundation and is covered by the Python Software
 # Foundation license.
 
-from processors import *
-from opt_processors import *
-import wizard_processors as wiz
+from .processors import *
+from .opt_processors import *
+from . import wizard_processors as wiz
 
 from dialogs import ShowDialog, MakePropertyPage, ShowWizard
 
@@ -119,7 +119,7 @@
         str_val = buf[:nchars]
         val = int(str_val)
         if val < 0 or val > 10:
-            raise ValueError, "Value must be between 0 and 10"
+            raise ValueError("Value must be between 0 and 10")
         self.SetOptionValue(val)
     def OnCommand(self, wparam, lparam):
         code = win32api.HIWORD(wparam)
@@ -145,7 +145,7 @@
             reason = self.window.manager.GetDisabledReason()
             if reason is not None:
                 win32gui.SendMessage(self.GetControl(), win32con.BM_SETCHECK, 0)
-                raise ValueError, reason
+                raise ValueError(reason)
         check = not not check # force bool!
         self.SetOptionValue(check)
 
@@ -376,7 +376,7 @@
         ShowWizard(parent, manager, self.idd, use_existing_config = True)
 
 def WizardFinish(mgr, window):
-    print _("Wizard Done!")
+    print(_("Wizard Done!"))
 
 def WizardTrainer(mgr, config, progress):
     import os, manager, train
@@ -429,7 +429,7 @@
         mgr.wizard_classifier_data = classifier_data
         mgr.classifier_data = orig_classifier_data
 
-from async_processor import AsyncCommandProcessor
+from .async_processor import AsyncCommandProcessor
 import filter, train
 
 dialog_map = {

Modified: branches/python3/spambayes/Outlook2000/dialogs/dlgcore.py
===================================================================
--- branches/python3/spambayes/Outlook2000/dialogs/dlgcore.py	2009-11-09 02:30:03 UTC (rev 3253)
+++ branches/python3/spambayes/Outlook2000/dialogs/dlgcore.py	2009-11-09 02:59:10 UTC (rev 3254)
@@ -9,7 +9,7 @@
 import commctrl
 import struct, array
 
-from dlgutils import *
+from .dlgutils import *
 
 # Isolate the nasty stuff for tooltips somewhere.
 class TooltipManager:
@@ -203,9 +203,9 @@
 
     def GetMessageMap(self):
         ret = TooltipDialog.GetMessageMap(self)
-        for key in self.processor_message_map.keys():
+        for key in list(self.processor_message_map.keys()):
             if key in ret:
-                print "*** WARNING: Overwriting message!!!"
+                print("*** WARNING: Overwriting message!!!")
             ret[key] = self.OnCommandProcessorMessage
         return ret
 
@@ -216,8 +216,8 @@
                 try:
                     self.GetDlgItem(int_id)
                 except win32gui.error:
-                    print "ERROR: Dialog item %s refers to an invalid control" % \
-                          self._GetIDName(int_id)
+                    print("ERROR: Dialog item %s refers to an invalid control" % \
+                          self._GetIDName(int_id))
         self.LoadAllControls()
 
     def GetPopupHelpText(self, iCtrlId):
@@ -226,10 +226,10 @@
         if cp is not None:
             return cp.GetPopupHelpText(iCtrlId)
 
-        print "Can not get command processor for", self._GetIDName(iCtrlId)
+        print("Can not get command processor for", self._GetIDName(iCtrlId))
         return None
     def OnRButtonUp(self, hwnd, msg, wparam, lparam):
-        for cp in self.command_processors.values():
+        for cp in list(self.command_processors.values()):
             cp.OnRButtonUp(wparam,lparam)
 
     def OnCommandProcessorMessage(self, hwnd, msg, wparam, lparam):
@@ -260,7 +260,7 @@
     def ApplyHandlingOptionValueError(self, func, *args):
         try:
             return func(*args)
-        except ValueError, why:
+        except ValueError as why:
             mb_flags = win32con.MB_ICONEXCLAMATION | win32con.MB_OK
             win32gui.MessageBox(self.hwnd, str(why), "SpamBayes", mb_flags)
             return False
@@ -290,7 +290,7 @@
         # delegate rest to our commands.
         handler = self.command_processors.get(idFrom)
         if handler is None:
-            print "Ignoring OnNotify for", self._GetIDName(idFrom)
+            print("Ignoring OnNotify for", self._GetIDName(idFrom))
             return
         return handler.OnNotify( (hwndFrom, idFrom, code), wparam, lparam)
 
@@ -299,12 +299,12 @@
         id = win32api.LOWORD(wparam)
         # Sometimes called after OnDestroy???
         if self.command_processors is None:
-            print "Ignoring OnCommand for", self._GetIDName(id)
+            print("Ignoring OnCommand for", self._GetIDName(id))
             return
         else:
             handler = self.command_processors.get(id)
             if handler is None:
-                print "Ignoring OnCommand for", self._GetIDName(id)
+                print("Ignoring OnCommand for", self._GetIDName(id))
                 return
 
         self.ApplyHandlingOptionValueError(handler.OnCommand, wparam, lparam)

Modified: branches/python3/spambayes/Outlook2000/dialogs/opt_processors.py
===================================================================
--- branches/python3/spambayes/Outlook2000/dialogs/opt_processors.py	2009-11-09 02:30:03 UTC (rev 3253)
+++ branches/python3/spambayes/Outlook2000/dialogs/opt_processors.py	2009-11-09 02:59:10 UTC (rev 3254)
@@ -9,9 +9,9 @@
 import win32gui, win32api, win32con
 import commctrl
 import struct, array
-from dlgutils import *
+from .dlgutils import *
 
-import processors
+from . import processors
 
 verbose = 0 # set to 1 to see option values fetched and set.
 
@@ -48,8 +48,8 @@
         if option is None:
             option = self.option
         if verbose:
-            print "Setting option '%s' (%s) -> %s" % \
-                  (option.display_name(), option.name, value)
+            print("Setting option '%s' (%s) -> %s" % \
+                  (option.display_name(), option.name, value))
         option.set(value)
         self.NotifyOptionChanged(option)
     def GetOptionValue(self, option = None):
@@ -57,8 +57,8 @@
             option = self.option
         ret = option.get()
         if verbose:
-            print "Got option '%s' (%s) -> %s" % \
-                  (option.display_name(), option.name, ret)
+            print("Got option '%s' (%s) -> %s" % \
+                  (option.display_name(), option.name, ret))
         return ret
 
     # Only sub-classes know how to update their controls from the value.
@@ -134,10 +134,10 @@
         OptionControlProcessor.__init__(self, window, control_ids, option)
         if text:
             temp = text.split(",")
-            self.option_to_text = zip(self.option.valid_input(), temp)
-            self.text_to_option = dict(zip(temp, self.option.valid_input()))
+            self.option_to_text = list(zip(self.option.valid_input(), temp))
+            self.text_to_option = dict(list(zip(temp, self.option.valid_input())))
         else:
-            self.option_to_text = zip(self.option.valid_input(),self.option.valid_input())
+            self.option_to_text = list(zip(self.option.valid_input(),self.option.valid_input()))
             self.text_to_option = dict(self.option_to_text)
 
     def OnCommand(self, wparam, lparam):
@@ -248,7 +248,7 @@
         str_val = buf[:nchars]
         val = float(str_val)
         if val < self.min_val or val > self.max_edit_val:
-            raise ValueError, "Value must be between %d and %d" % (self.min_val, self.max_val)
+            raise ValueError("Value must be between %d and %d" % (self.min_val, self.max_val))
         self.SetOptionValue(val)
 
 class FilenameProcessor(OptionControlProcessor):
@@ -263,7 +263,7 @@
         return OptionControlProcessor.GetPopupHelpText(self, id)
 
     def DoBrowse(self):
-        from win32struct import OPENFILENAME
+        from .win32struct import OPENFILENAME
         ofn = OPENFILENAME(512)
         ofn.hwndOwner = self.window.hwnd
         ofn.setFilter(self.file_filter)

Modified: branches/python3/spambayes/Outlook2000/dialogs/processors.py
===================================================================
--- branches/python3/spambayes/Outlook2000/dialogs/processors.py	2009-11-09 02:30:03 UTC (rev 3253)
+++ branches/python3/spambayes/Outlook2000/dialogs/processors.py	2009-11-09 02:59:10 UTC (rev 3254)
@@ -7,7 +7,7 @@
 import win32gui, win32api, win32con
 import commctrl
 import struct, array
-from dlgutils import *
+from .dlgutils import *
 
 # Cache our leaky bitmap handles
 bitmap_handles = {}
@@ -43,7 +43,7 @@
     def GetMessages(self):
         return []
     def OnMessage(self, msg, wparam, lparam):
-        raise RuntimeError, "I don't hook any messages, so I shouldn't be called"
+        raise RuntimeError("I don't hook any messages, so I shouldn't be called")
     def OnOptionChanged(self, option):
         pass
     def OnRButtonUp(self, wparam, lparam):
@@ -54,10 +54,10 @@
         rcp = self.window.manager.dialog_parser;
         bmp_id = int(win32gui.GetWindowText(self.GetControl()))
 
-        if bitmap_handles.has_key(bmp_id):
+        if bmp_id in bitmap_handles:
             handle = bitmap_handles[bmp_id]
         else:
-            import resources
+            from . import resources
             mod_handle, mod_bmp, extra_flags = resources.GetImageParamsFromBitmapID(rcp, bmp_id)
             load_flags = extra_flags|win32con.LR_COLOR|win32con.LR_SHARED
             handle = win32gui.LoadImage(mod_handle, mod_bmp,

Modified: branches/python3/spambayes/Outlook2000/dialogs/resources/rc2py.py
===================================================================
--- branches/python3/spambayes/Outlook2000/dialogs/resources/rc2py.py	2009-11-09 02:30:03 UTC (rev 3253)
+++ branches/python3/spambayes/Outlook2000/dialogs/resources/rc2py.py	2009-11-09 02:59:10 UTC (rev 3254)
@@ -8,7 +8,7 @@
 with the same basic public interface as the rcparser module.
 """
 import sys, os, stat
-import rcparser
+from . import rcparser
 
 def convert(inputFilename = None, outputFilename = None,
             enableGettext = True):

Modified: branches/python3/spambayes/Outlook2000/dialogs/resources/rclabels2text.py
===================================================================
--- branches/python3/spambayes/Outlook2000/dialogs/resources/rclabels2text.py	2009-11-09 02:30:03 UTC (rev 3253)
+++ branches/python3/spambayes/Outlook2000/dialogs/resources/rclabels2text.py	2009-11-09 02:59:10 UTC (rev 3254)
@@ -8,7 +8,7 @@
 and writes them into a text file for spell checking purposes.
 """
 import sys, os, re
-import rcparser
+from . import rcparser
 
 anti_and = re.compile(r"([^\\]*)&([^&]*)");
 anti_nl = re.compile(r"([^\\]*)\\n([^\\])");
@@ -23,7 +23,7 @@
 
     out = open(outputFilename, "wt")
     for dlg_id in rcp._dialogs:
-        print dlg_id
+        print(dlg_id)
         dlg = rcp._dialogs[dlg_id]
         out.write("\n================================================\n")
         out.write("In Dialog: "+str(dlg_id)+" Title: "+str(dlg.caption)+"\n\n")

Modified: branches/python3/spambayes/Outlook2000/dialogs/resources/rcparser.py
===================================================================
--- branches/python3/spambayes/Outlook2000/dialogs/resources/rcparser.py	2009-11-09 02:30:03 UTC (rev 3253)
+++ branches/python3/spambayes/Outlook2000/dialogs/resources/rcparser.py	2009-11-09 02:59:10 UTC (rev 3254)
@@ -117,7 +117,7 @@
 
     def debug(self, *args):
         if self.debugEnabled:
-            print args
+            print(args)
 
     def getToken(self):
         self.token = self.lex.get_token()
@@ -152,7 +152,7 @@
             self.parseH(h)
             h.close()
         except IOError:
-            print "No .h file. ignoring."
+            print("No .h file. ignoring.")
         f = open(rcFileName)
         self.open(f)
         self.getToken()
@@ -177,10 +177,10 @@
                     n = lex.get_token()
                     i = int(lex.get_token())
                     self.ids[n] = i
-                    if self.names.has_key(i):
+                    if i in self.names:
                         # ignore AppStudio special ones.
                         if not n.startswith("_APS_"):
-                            print "Duplicate id",i,"for",n,"is", self.names[i]
+                            print("Duplicate id",i,"for",n,"is", self.names[i])
                     else:
                         self.names[i] = n
                     if self.next_id<=i:
@@ -214,7 +214,7 @@
                     self.getToken() # bmpname
                 bmf = self.token[1:-1] # quotes
                 self.bitmaps[possibleBitmap] = bmf
-                print "BITMAP", possibleBitmap, bmf
+                print("BITMAP", possibleBitmap, bmf)
                 #print win32gui.LoadImage(0, bmf, win32con.IMAGE_BITMAP,0,0,win32con.LR_DEFAULTCOLOR|win32con.LR_LOADFROMFILE)
 
     def addId(self, id_name):
@@ -351,8 +351,7 @@
             # msvc seems to occasionally replace "IDC_STATIC" with -1
             if self.token=='-':
                 if self.getToken() != '1':
-                    raise RuntimeError, \
-                          "Negative literal in rc script (other than -1) - don't know what to do"
+                    raise RuntimeError("Negative literal in rc script (other than -1) - don't know what to do")
                 self.token = "IDC_STATIC"
             control.id = self.token
             control.idNum = self.addId(control.id)
@@ -389,11 +388,11 @@
     except:
         lex = getattr(rcp, "lex", None)
         if lex:
-            print "ERROR parsing dialogs at line", lex.lineno
-            print "Next 10 tokens are:"
+            print("ERROR parsing dialogs at line", lex.lineno)
+            print("Next 10 tokens are:")
             for i in range(10):
-                print lex.get_token(),
-            print
+                print(lex.get_token(), end=' ')
+            print()
         raise
 
     return rcp
@@ -402,7 +401,7 @@
     rc_file = os.path.join(os.path.dirname(__file__), "dialogs.rc")
     d = ParseDialogs(rc_file)
     import pprint
-    for id, ddef in d.dialogs.items():
-        print "Dialog %s (%d controls)" % (id, len(ddef))
+    for id, ddef in list(d.dialogs.items()):
+        print("Dialog %s (%d controls)" % (id, len(ddef)))
         pprint.pprint(ddef)
-        print
+        print()

Modified: branches/python3/spambayes/Outlook2000/dialogs/test_dialogs.py
===================================================================
--- branches/python3/spambayes/Outlook2000/dialogs/test_dialogs.py	2009-11-09 02:30:03 UTC (rev 3253)
+++ branches/python3/spambayes/Outlook2000/dialogs/test_dialogs.py	2009-11-09 02:59:10 UTC (rev 3254)
@@ -22,7 +22,7 @@
     else:
         ShowDialog(0, mgr, mgr.config, idd)
     if "-d" in sys.argv:
-        print "Dumping(but not saving) new manager configuration:"
-        print mgr.options.display()
-        print "-- end of configuration --"
+        print("Dumping(but not saving) new manager configuration:")
+        print(mgr.options.display())
+        print("-- end of configuration --")
     mgr.Close()

Modified: branches/python3/spambayes/Outlook2000/dialogs/win32struct.py
===================================================================
--- branches/python3/spambayes/Outlook2000/dialogs/win32struct.py	2009-11-09 02:30:03 UTC (rev 3253)
+++ branches/python3/spambayes/Outlook2000/dialogs/win32struct.py	2009-11-09 02:59:10 UTC (rev 3254)
@@ -49,9 +49,9 @@
         t = struct.unpack(self.fs, self.data)
         ii = 0
         for i in self.nlst:
-            print i, "=", t[ii]
+            print(i, "=", t[ii])
             ii += 1
-        print "fs =", self.fs
+        print("fs =", self.fs)
         return
 
 
@@ -94,19 +94,19 @@
         return win32gui.PyGetString(self.fn_buf_addr)
 
     def setTitle(self, title):
-        if isinstance(title, unicode):
+        if isinstance(title, str):
             title = title.encode("mbcs")
         self.title_buf = array.array("c", title+'\0')
         self.lpstrTitle = self.title_buf.buffer_info()[0]
 
     def setInitialDir(self, initialDir):
-        if isinstance(initialDir, unicode):
+        if isinstance(initialDir, str):
             initialDir = initialDir.encode("mbcs")
         self.initialDir_buf = array.array("c", initialDir+'\0')
         self.lpstrInitialDir = self.initialDir_buf.buffer_info()[0]
 
     def setFilter(self, fileFilter):
-        if isinstance(fileFilter, unicode):
+        if isinstance(fileFilter, str):
             fileFilter = fileFilter.encode("mbcs")
         fileFilter = fileFilter.replace('|', '\0') + '\0'
         self.fileFilter_buf = array.array("c", fileFilter+'\0')

Modified: branches/python3/spambayes/Outlook2000/dialogs/wizard_processors.py
===================================================================
--- branches/python3/spambayes/Outlook2000/dialogs/wizard_processors.py	2009-11-09 02:30:03 UTC (rev 3253)
+++ branches/python3/spambayes/Outlook2000/dialogs/wizard_processors.py	2009-11-09 02:59:10 UTC (rev 3254)
@@ -7,9 +7,9 @@
 import win32gui, win32con, win32api, commctrl
 from dialogs import ShowDialog, MakePropertyPage
 
-import processors
-import opt_processors
-import async_processor
+from . import processors
+from . import opt_processors
+from . import async_processor
 
 import timer
 
@@ -94,7 +94,7 @@
             #backward
             assert self.page_stack, "Back should be disabled when no back stack"
             pageNo = self.page_stack.pop()
-            print "Back button switching to page", pageNo
+            print("Back button switching to page", pageNo)
             self.switchToPage(pageNo)
 
     def switchToPage(self, index):
@@ -103,7 +103,7 @@
                 return 1
             win32gui.DestroyWindow(self.currentPageHwnd)
         #template = self.window.manager.dialog_parser.dialogs[self.page_ids[index]]
-        import dlgcore
+        from . import dlgcore
         self.currentPage = MakePropertyPage(self.page_placeholder_hwnd,
                                             self.window.manager,
                                             self.window.config,
@@ -166,7 +166,7 @@
         index = self.currentPageIndex
         id = self.page_ids[index]
         config = self.window.config
-        print "GetNextPage with current", index, id
+        print("GetNextPage with current", index, id)
         if id == 'IDD_WIZARD_WELCOME':
             # Welcome page
             if config.wizard.preparation == 0: # unprepared

Modified: branches/python3/spambayes/Outlook2000/export.py
===================================================================
--- branches/python3/spambayes/Outlook2000/export.py	2009-11-09 02:30:03 UTC (rev 3253)
+++ branches/python3/spambayes/Outlook2000/export.py	2009-11-09 02:59:10 UTC (rev 3254)
@@ -101,7 +101,7 @@
     num = 0
     store = manager.message_store
     for folder in store.GetFolderGenerator(folder_ids, include_sub):
-        print "", folder.name
+        print("", folder.name)
         for message in folder.GetMessageGenerator():
             this_dir = os.path.join(root,  choice(buckets))
             # filename is the EID.txt
@@ -110,8 +110,8 @@
             except KeyboardInterrupt:
                 raise
             except:
-                print "Failed to get message text for '%s': %s" \
-                      % (message.GetSubject(), sys.exc_info()[1])
+                print("Failed to get message text for '%s': %s" \
+                      % (message.GetSubject(), sys.exc_info()[1]))
                 continue
 
             fname = os.path.join(this_dir, message.GetID()[1]) + ".txt"
@@ -124,12 +124,12 @@
 # This does all the work.  'directory' is the parent directory for the
 # generated Ham and Spam sub-folders.
 def export(directory, num_buckets, old_style):
-    print "Loading bayes manager..."
+    print("Loading bayes manager...")
     manager = GetManager()
     config = manager.config
     num_spam, num_ham, buckets = BuildBuckets(manager, num_buckets)
-    print "Have", num_spam, "spam and", num_ham, "ham to export,",
-    print "spread over", len(buckets), "directories."
+    print("Have", num_spam, "spam and", num_ham, "ham to export,", end=' ')
+    print("spread over", len(buckets), "directories.")
 
     for sub in "Spam", "Ham":
         if os.path.exists(os.path.join(directory, sub)):
@@ -138,30 +138,30 @@
             d = os.path.join(directory, sub, b)
             os.makedirs(d)
 
-    print "Exporting spam..."
+    print("Exporting spam...")
     num = _export_folders(manager,
                           os.path.join(directory, "Spam"),
                           buckets,
                           config.training.spam_folder_ids,
                           config.training.spam_include_sub,
                           old_style)
-    print "Exported", num, "spam messages."
+    print("Exported", num, "spam messages.")
 
-    print "Exporting ham..."
+    print("Exporting ham...")
     num = _export_folders(manager,
                           os.path.join(directory, "Ham"),
                           buckets,
                           config.training.ham_folder_ids,
                           config.training.ham_include_sub,
                           old_style)
-    print "Exported", num, "ham messages."
+    print("Exported", num, "ham messages.")
 
 def main():
     import getopt
 
     try:
         opts, args = getopt.getopt(sys.argv[1:], "hqon:")
-    except getopt.error, d:
+    except getopt.error as d:
         usage(d)
     quiet = 0
     old_style = False
@@ -190,24 +190,24 @@
         usage("-n must be at least 1.")
 
     directory = os.path.abspath(directory)
-    print "This program will export your Outlook Ham and Spam folders"
-    print "to the directory '%s'" % directory
+    print("This program will export your Outlook Ham and Spam folders")
+    print("to the directory '%s'" % directory)
     if os.path.exists(directory):
-        print "*******"
-        print "WARNING: all existing files in '%s' will be deleted" % directory
-        print "*******"
+        print("*******")
+        print("WARNING: all existing files in '%s' will be deleted" % directory)
+        print("*******")
     if not quiet:
-        raw_input("Press enter to continue, or Ctrl+C to abort.")
+        input("Press enter to continue, or Ctrl+C to abort.")
     export(directory, num_buckets, old_style=old_style)
 
 # Display errormsg (if specified), a blank line, and usage information; then
 # exit with status 1 (usage doesn't return).
 def usage(errormsg=None):
     if errormsg:
-        print str(errormsg)
-        print
+        print(str(errormsg))
+        print()
 
-    print """ \
+    print(""" \
 Usage: %s [-h] [-q] [-n nsets] [directory]
 
 -h : help - display this msg and stop
@@ -226,7 +226,7 @@
 the export (but you will be asked to confirm unless -q is given).""" \
             % (os.path.basename(sys.argv[0]),
                NUM_BUCKETS,
-               DEFAULT_DIRECTORY)
+               DEFAULT_DIRECTORY))
     sys.exit(1)
 
 if __name__=='__main__':

Modified: branches/python3/spambayes/Outlook2000/filter.py
===================================================================
--- branches/python3/spambayes/Outlook2000/filter.py	2009-11-09 02:30:03 UTC (rev 3253)
+++ branches/python3/spambayes/Outlook2000/filter.py	2009-11-09 02:59:10 UTC (rev 3254)
@@ -76,10 +76,10 @@
             # Clear dirty flag anyway
             mgr.LogDebug(1, "Message is read-only - could not save Spam score")
             msg.dirty = False
-        except ms.MsgStoreException, details:
+        except ms.MsgStoreException as details:
             # Some other error saving - this is nasty.
-            print "Unexpected MAPI error saving the spam score for", msg
-            print details
+            print("Unexpected MAPI error saving the spam score for", msg)
+            print(details)
             # Clear dirty flag anyway
             msg.dirty = False
 
@@ -95,8 +95,8 @@
                 try:
                     dest_folder = ms.GetFolder(folder_id)
                 except ms.MsgStoreException:
-                    print "ERROR: Unable to open the folder to Copy the " \
-                          "message - this message was not copied"
+                    print("ERROR: Unable to open the folder to Copy the " \
+                          "message - this message was not copied")
                 else:
                     msg.CopyToReportingError(mgr, dest_folder)
                     mgr.LogDebug(1, "Copied message '%s' to folder '%s'" \
@@ -105,14 +105,14 @@
                 try:
                     dest_folder = ms.GetFolder(folder_id)
                 except ms.MsgStoreException:
-                    print "ERROR: Unable to open the folder to Move the " \
-                          "message - this message was not moved"
+                    print("ERROR: Unable to open the folder to Move the " \
+                          "message - this message was not moved")
                 else:
                     msg.MoveToReportingError(mgr, dest_folder)
                     mgr.LogDebug(1, "Moved message '%s' to folder '%s'" \
                                  % (msg.subject, dest_folder.GetFQName()))
             else:
-                raise RuntimeError, "Eeek - bad action '%r'" % (action,)
+                raise RuntimeError("Eeek - bad action '%r'" % (action,))
 
         if all_actions:
             mgr.stats.RecordClassification(prob)
@@ -121,7 +121,7 @@
             mgr.classifier_data.SavePostIncrementalTrain()
         return disposition
     except:
-        print "Failed filtering message!", msg
+        print("Failed filtering message!", msg)
         import traceback
         traceback.print_exc()
         return "Failed"
@@ -143,7 +143,7 @@
             disposition = filter_message(message, mgr, all_actions)
         except:
             import traceback
-            print "Error filtering message '%s'" % (message,)
+            print("Error filtering message '%s'" % (message,))
             traceback.print_exc()
             disposition = "Error"
 
@@ -167,13 +167,13 @@
     for f in mgr.message_store.GetFolderGenerator(config.folder_ids, config.include_sub):
         progress.set_status(_("Filtering folder '%s'") % (f.name))
         this_dispositions = filter_folder(f, mgr, config, progress)
-        for key, val in this_dispositions.items():
+        for key, val in list(this_dispositions.items()):
             dispositions[key] = dispositions.get(key, 0) + val
         if progress.stop_requested():
             return
     # All done - report what we did.
     err_text = ""
-    if dispositions.has_key("Error"):
+    if "Error" in dispositions:
         err_text = _(" (%d errors)") % dispositions["Error"]
     dget = dispositions.get
     text = _("Found %d spam, %d unsure and %d good messages%s") % \
@@ -181,7 +181,7 @@
     progress.set_status(text)
 
 def main():
-    print "Sorry - we don't do anything here any more"
+    print("Sorry - we don't do anything here any more")
 
 if __name__ == "__main__":
     main()

Modified: branches/python3/spambayes/Outlook2000/manager.py
===================================================================
--- branches/python3/spambayes/Outlook2000/manager.py	2009-11-09 02:30:03 UTC (rev 3253)
+++ branches/python3/spambayes/Outlook2000/manager.py	2009-11-09 02:59:10 UTC (rev 3254)
@@ -1,6 +1,6 @@
-from __future__ import generators
 
-import cPickle
+
+import pickle
 import os
 import sys
 import errno
@@ -10,7 +10,7 @@
 import operator
 import win32api, win32con, win32gui
 
-import timer, thread
+import timer, _thread
 
 import win32com.client
 import win32com.client.gencache
@@ -40,7 +40,7 @@
 
 def ReportError(message, title = None):
     import traceback
-    print "ERROR:", repr(message)
+    print("ERROR:", repr(message))
     if sys.exc_info()[0] is not None:
         traceback.print_exc()
     if title is None: title = "SpamBayes"
@@ -132,7 +132,7 @@
     # Convert if necessary.
     use_names = []
     for name in ini_filenames:
-        if isinstance(name, unicode):
+        if isinstance(name, str):
             name = name.encode(filesystem_encoding)
         use_names.append(name)
     os.environ["BAYESCUSTOMIZE"] = os.pathsep.join(use_names)
@@ -157,7 +157,7 @@
     temp_filename = filename + ".tmp"
     file = open(temp_filename,"wb")
     try:
-        cPickle.dump(what, file, 1)
+        pickle.dump(what, file, 1)
     finally:
         file.close()
     # now rename to the correct file.
@@ -183,7 +183,7 @@
         # Just delete the file and do an "open"
         try:
             os.unlink(self.bayes_filename)
-        except EnvironmentError, e:
+        except EnvironmentError as e:
             if e.errno != errno.ENOENT: raise
         return self.open_bayes()
     def store_bayes(self, bayes):
@@ -195,7 +195,7 @@
     def open_mdb(self):
         # MessageInfo storage types may lag behind, so use pickle if the
         # matching type isn't available.
-        if self.klass in bayes_message._storage_types.keys():
+        if self.klass in list(bayes_message._storage_types.keys()):
             return bayes_message.open_storage(self.mdb_filename, self.klass)
         return bayes_message.open_storage(self.mdb_filename, "pickle")
     def store_mdb(self, mdb):
@@ -217,7 +217,7 @@
     def new_mdb(self):
         try:
             os.unlink(self.mdb_filename)
-        except EnvironmentError, e:
+        except EnvironmentError as e:
             if e.errno != errno.ENOENT: raise
         return self.open_mdb()
     def is_incremental(self):
@@ -247,11 +247,11 @@
         # file-not-found handled gracefully by storage.
         bayes = self.db_manager.open_bayes()
         fname = self.db_manager.bayes_filename.encode("mbcs", "replace")
-        print "Loaded bayes database from '%s'" % (fname,)
+        print("Loaded bayes database from '%s'" % (fname,))
 
         message_db = self.db_manager.open_mdb()
         fname = self.db_manager.mdb_filename.encode("mbcs", "replace")
-        print "Loaded message database from '%s'" % (fname,)
+        print("Loaded message database from '%s'" % (fname,))
 
         self.logger.LogDebug(0, "Bayes database initialized with "
                    "%d spam and %d good messages" % (bayes.nspam, bayes.nham))
@@ -284,7 +284,7 @@
             else:
                 self.logger.LogDebug(1, "Bayes database is not dirty - not writing")
         else:
-            print "Using a slow database - not saving after incremental train"
+            print("Using a slow database - not saving after incremental train")
 
     def Save(self):
         import time
@@ -292,19 +292,19 @@
         bayes = self.bayes
 
         if self.logger.verbose:
-            print "Saving bayes database with %d spam and %d good messages" %\
-                   (bayes.nspam, bayes.nham)
-            print " ->", self.db_manager.bayes_filename
+            print("Saving bayes database with %d spam and %d good messages" %\
+                   (bayes.nspam, bayes.nham))
+            print(" ->", self.db_manager.bayes_filename)
         self.db_manager.store_bayes(self.bayes)
         if self.logger.verbose:
-            print " ->", self.db_manager.mdb_filename
+            print(" ->", self.db_manager.mdb_filename)
         self.db_manager.store_mdb(self.message_db)
         self.dirty = False
         self.logger.LogDebug(1, "Saved databases in %gms" % ((time.clock()-start)*1000))
 
     def Close(self):
         if self.dirty and self.bayes:
-            print "Warning: ClassifierData closed while Bayes database dirty"
+            print("Warning: ClassifierData closed while Bayes database dirty")
         if self.db_manager:
             self.db_manager.close_bayes(self.bayes)
             self.db_manager.close_mdb(self.message_db)
@@ -339,14 +339,14 @@
     if use_db not in available:
         # User is trying to use something fancy which isn't available.
         # Fall back on bsddb.
-        print use_db, "storage type not available.  Using bsddb."
+        print(use_db, "storage type not available.  Using bsddb.")
         use_db = "dbm"
     return available[use_db]
 
 # Our main "bayes manager"
 class BayesManager:
     def __init__(self, config_base="default", outlook=None, verbose=0):
-        self.owner_thread_ident = thread.get_ident() # check we aren't multi-threaded
+        self.owner_thread_ident = _thread.get_ident() # check we aren't multi-threaded
         self.never_configured = True
         self.reported_error_map = {}
         self.reported_startup_error = False
@@ -387,16 +387,16 @@
                 value = value.decode(filesystem_encoding)
             except AttributeError: # May already be Unicode
                 pass
-            assert isinstance(value, types.UnicodeType), "%r should be a unicode" % value
+            assert isinstance(value, str), "%r should be a unicode" % value
             try:
                 if not os.path.isdir(value):
                     os.makedirs(value)
                 assert os.path.isdir(value), "just made the *ucker"
                 value = os.path.abspath(value)
             except os.error:
-                print "The configuration files have specified a data " \
+                print("The configuration files have specified a data " \
                       "directory of", repr(value), "but it is not valid. " \
-                      "Using default."
+                      "Using default.")
                 value = None
         if value:
             self.data_directory = value
@@ -468,19 +468,19 @@
     def LogDebug(self, level, *args):
         if self.verbose >= level:
             for arg in args[:-1]:
-                print arg,
-            print args[-1]
+                print(arg, end=' ')
+            print(args[-1])
 
     def ReportError(self, message, title = None):
         if self.test_suite_running:
-            print "ReportError:", repr(message)
-            print "(but test suite running - not reported)"
+            print("ReportError:", repr(message))
+            print("(but test suite running - not reported)")
             return
         ReportError(message, title)
     def ReportInformation(self, message, title=None):
         if self.test_suite_running:
-            print "ReportInformation:", repr(message)
-            print "(but test suite running - not reported)"
+            print("ReportInformation:", repr(message))
+            print("(but test suite running - not reported)")
             return
         ReportInformation(message, title)
     def AskQuestion(self, message, title=None):
@@ -506,19 +506,19 @@
         else:
             # We have reported the error, but for the sake of the log, we
             # still want it logged there.
-            print "ERROR:", repr(message)
+            print("ERROR:", repr(message))
             traceback.print_exc()
 
     def ReportErrorOnce(self, msg, title = None, key = None):
         if key is None: key = msg
         # Always print the message and traceback.
         if self.test_suite_running:
-            print "ReportErrorOnce:", repr(msg)
-            print "(but test suite running - not reported)"
+            print("ReportErrorOnce:", repr(msg))
+            print("(but test suite running - not reported)")
             return
-        print "ERROR:", repr(msg)
+        print("ERROR:", repr(msg))
         if key in self.reported_error_map:
-            print "(this error has already been reported - not displaying it again)"
+            print("(this error has already been reported - not displaying it again)")
         else:
             traceback.print_exc()
             self.reported_error_map[key] = True
@@ -618,15 +618,15 @@
                        True, # Add to folder
                        format)
                 outlook_message.Save()
-            except pythoncom.com_error, details:
+            except pythoncom.com_error as details:
                 if msgstore.IsReadOnlyCOMException(details):
                     self.LogDebug(1, "The folder '%s' is read-only - user "
                                      "property can't be added" % (folder_name,))
                 else:
-                    print "Warning: failed to create the Outlook " \
+                    print("Warning: failed to create the Outlook " \
                           "user-property in folder '%s'" \
-                          % (folder_name,)
-                    print "", details
+                          % (folder_name,))
+                    print("", details)
             msgstore_folder.DeleteMessages((message,))
             # Check our DoesFolderHaveOutlookField logic holds up.
             if not msgstore_folder.DoesFolderHaveOutlookField(field_name):
@@ -674,10 +674,10 @@
             # should only happen in source-code versions - older win32alls can't
             # determine this.
             profile_name = "unknown_profile"
-            print "*** NOTE: It appears you are running the source-code version of"
-            print "* SpamBayes, and running a win32all version pre 154."
-            print "* If you work with multiple Outlook profiles, it is recommended"
-            print "* you upgrade - see http://starship.python.net/crew/mhammond"""
+            print("*** NOTE: It appears you are running the source-code version of")
+            print("* SpamBayes, and running a win32all version pre 154.")
+            print("* If you work with multiple Outlook profiles, it is recommended")
+            print("* you upgrade - see http://starship.python.net/crew/mhammond""")
         return profile_name
 
     def LoadConfig(self):
@@ -702,9 +702,9 @@
         config.MigrateOptions(self.options)
 
         if self.verbose > 1:
-            print "Dumping loaded configuration:"
-            print self.options.display()
-            print "-- end of configuration --"
+            print("Dumping loaded configuration:")
+            print(self.options.display())
+            print("-- end of configuration --")
 
     def MigrateOldPickle(self):
         assert self.config is not None, "Must have a config"
@@ -715,12 +715,12 @@
         except IOError:
             self.LogDebug(1, "No old pickle file to migrate")
             return
-        print "Migrating old pickle '%s'" % pickle_filename
+        print("Migrating old pickle '%s'" % pickle_filename)
         try:
             try:
-                old_config = cPickle.load(f)
+                old_config = pickle.load(f)
             except:
-                print "FAILED to load old pickle"
+                print("FAILED to load old pickle")
                 traceback.print_exc()
                 msg = _("There was an error loading your old\r\n" \
                         "SpamBayes configuration file.\r\n\r\n" \
@@ -733,14 +733,14 @@
         finally:
             f.close()
         if old_config is not None:
-            for section, items in old_config.__dict__.items():
-                print " migrating section '%s'" % (section,)
+            for section, items in list(old_config.__dict__.items()):
+                print(" migrating section '%s'" % (section,))
                 # exactly one value wasn't in a section - now in "general"
                 dict = getattr(items, "__dict__", None)
                 if dict is None:
                     dict = {section: items}
                     section = "general"
-                for name, value in dict.items():
+                for name, value in list(dict.items()):
                     sect = getattr(self.config, section)
                     setattr(sect, name, value)
         # Save the config, then delete the pickle so future attempts to
@@ -769,12 +769,12 @@
 
         # Update our runtime verbosity from the options.
         self.verbose = self.config.general.verbose
-        print "Saving configuration ->", self.config_filename.encode("mbcs", "replace")
+        print("Saving configuration ->", self.config_filename.encode("mbcs", "replace"))
         assert self.config and self.options, "Have no config to save!"
         if self.verbose > 1:
-            print "Dumping configuration to save:"
-            print self.options.display()
-            print "-- end of configuration --"
+            print("Dumping configuration to save:")
+            print(self.options.display())
+            print("-- end of configuration --")
         self.options.update_file(self.config_filename)
 
     def Save(self):
@@ -847,11 +847,11 @@
         if config.unsure_folder_id:
             try:
                 unsure_folder = ms.GetFolder(config.unsure_folder_id)
-            except ms.MsgStoreException, details:
+            except ms.MsgStoreException as details:
                 return _("The unsure folder is invalid: %s") % (details,)
         try:
             spam_folder = ms.GetFolder(config.spam_folder_id)
-        except ms.MsgStoreException, details:
+        except ms.MsgStoreException as details:
             return _("The spam folder is invalid: %s") % (details,)
         if ok_to_enable:
             for folder in ms.GetFolderGenerator(config.watch_folder_ids,
@@ -894,8 +894,8 @@
 
     def ShowHtml(self,url):
         """Displays the main SpamBayes documentation in your Web browser"""
-        import sys, os, urllib
-        if urllib.splittype(url)[0] is None: # just a file spec
+        import sys, os, urllib.request, urllib.parse, urllib.error
+        if urllib.parse.splittype(url)[0] is None: # just a file spec
             if hasattr(sys, "frozen"):
                 # New binary is in ../docs/outlook relative to executable.
                 fname = os.path.join(os.path.dirname(sys.argv[0]),
@@ -938,9 +938,9 @@
         self._DoStartNotifyTimer(delay)
         
     def _DoStartNotifyTimer(self, delay):
-        assert thread.get_ident() == self.owner_thread_ident
+        assert _thread.get_ident() == self.owner_thread_ident
         assert self.notify_timer_id is None, "Shouldn't start a timer when already have one"
-        assert isinstance(delay, types.FloatType), "Timer values are float seconds"
+        assert isinstance(delay, float), "Timer values are float seconds"
         # And start a new timer.
         assert delay, "No delay means no timer!"
         delay = int(delay*1000) # convert to ms.
@@ -948,7 +948,7 @@
         self.LogDebug(1, "Notify timer started - id=%d, delay=%d" % (self.notify_timer_id, delay))
         
     def _KillNotifyTimer(self):
-        assert thread.get_ident() == self.owner_thread_ident
+        assert _thread.get_ident() == self.owner_thread_ident
         if self.notify_timer_id is not None:
             timer.kill_timer(self.notify_timer_id)
             self.LogDebug(2, "The notify timer with id=%d was stopped" % self.notify_timer_id)
@@ -956,7 +956,7 @@
         
     def _NotifyTimerFunc(self, event, time):
         # Kill the timer first
-        assert thread.get_ident() == self.owner_thread_ident
+        assert _thread.get_ident() == self.owner_thread_ident
         self.LogDebug(1, "The notify timer with id=%s fired" % self.notify_timer_id)
         self._KillNotifyTimer()
         
@@ -999,7 +999,7 @@
     return 0
 
 def usage():
-    print "Usage: manager [-v ...]"
+    print("Usage: manager [-v ...]")
     sys.exit(1)
 
 if __name__=='__main__':

Modified: branches/python3/spambayes/Outlook2000/msgstore.py
===================================================================
--- branches/python3/spambayes/Outlook2000/msgstore.py	2009-11-09 02:30:03 UTC (rev 3253)
+++ branches/python3/spambayes/Outlook2000/msgstore.py	2009-11-09 02:59:10 UTC (rev 3254)
@@ -1,5 +1,5 @@
-from __future__ import generators
 
+
 import sys, os, re
 import locale
 from time import timezone
@@ -13,9 +13,9 @@
 from email.Utils import formatdate
 
 try:
-    from cStringIO import StringIO
+    from io import StringIO
 except ImportError:
-    from StringIO import StringIO
+    from io import StringIO
 
 # MAPI imports etc.
 from win32com.client import Dispatch, constants
@@ -64,7 +64,7 @@
             test_suite_failure_count -= 1
             if test_suite_failure_count==0:
                 test_suite_failure_request = None
-        raise test_suite_failure[0], test_suite_failure[1]
+        raise test_suite_failure[0](test_suite_failure[1])
 
 # Exceptions raised by this module.  Raw MAPI exceptions should never
 # be raised to the caller.
@@ -83,7 +83,7 @@
          # Python silently consumes exceptions here, and uses
          # <unprintable object>
         except:
-            print "FAILED to str() a MsgStore exception!"
+            print("FAILED to str() a MsgStore exception!")
             import traceback
             traceback.print_exc()
 
@@ -307,23 +307,23 @@
         for folder_id in folder_ids:
             try:
                 folder_id = self.NormalizeID(folder_id)
-            except MsgStoreException, details:
-                print "NOTE: Skipping invalid folder", details
+            except MsgStoreException as details:
+                print("NOTE: Skipping invalid folder", details)
                 continue
             try:
                 folder = self._OpenEntry(folder_id)
                 table = folder.GetContentsTable(0)
-            except pythoncom.com_error, details:
+            except pythoncom.com_error as details:
                 # We will ignore *all* such errors for the time
                 # being, but give verbose details for results we don't
                 # know about
                 if IsNotAvailableCOMException(details):
-                    print "NOTE: Skipping folder for this session - temporarily unavailable"
+                    print("NOTE: Skipping folder for this session - temporarily unavailable")
                 elif IsNotFoundCOMException(details):
-                    print "NOTE: Skipping deleted folder"
+                    print("NOTE: Skipping deleted folder")
                 else:
-                    print "WARNING: Unexpected MAPI error opening folder"
-                    print GetCOMExceptionString(details)
+                    print("WARNING: Unexpected MAPI error opening folder")
+                    print(GetCOMExceptionString(details))
                 continue
             rc, props = folder.GetProps( (PR_DISPLAY_NAME_A,), 0)
             yield MAPIMsgStoreFolder(self, folder_id, props[0][1],
@@ -350,7 +350,7 @@
             folder_id = folder_id[0], props[0][1]
             return MAPIMsgStoreFolder(self, folder_id, props[1][1],
                                   table.GetRowCount(0))
-        except pythoncom.com_error, details:
+        except pythoncom.com_error as details:
             raise MsgStoreExceptionFromCOMException(details)
 
     def GetMessage(self, message_id):
@@ -367,7 +367,7 @@
             mapi_object = self._OpenEntry(message_id)
             hr, data = mapi_object.GetProps(MAPIMsgStoreMsg.message_init_props,0)
             return MAPIMsgStoreMsg(self, data)
-        except pythoncom.com_error, details:
+        except pythoncom.com_error as details:
             raise MsgStoreExceptionFromCOMException(details)
 
     def YieldReceiveFolders(self, msg_class = "IPM.Note"):
@@ -386,9 +386,9 @@

@@ Diff output truncated at 100000 characters. @@

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.