[Pywikipedia-l] SVN: [6430] branches/rewrite/pywikibot/userinterfaces/terminal_interface.py

nicdumz at svn.wikimedia.org nicdumz at svn.wikimedia.org
Mon Feb 23 15:14:28 UTC 2009


Revision: 6430
Author:   nicdumz
Date:     2009-02-23 15:14:27 +0000 (Mon, 23 Feb 2009)

Log Message:
-----------
Adding a write RLock so that no concurrent output() are written to the terminal when input() has written the prompt and is waiting for user input.

Tested:
* that this output lock is process independant. A waiting input() in a process doesn't stop a output() in another one. (!!)
* in replace.py with manual check of edits, checked behavior of input & output, + concurrent properties (i.e. made sure that output() from the async_put thread waits for termination of the main process input() asking for "put changes ? [y/n/q]")

Modified Paths:
--------------
    branches/rewrite/pywikibot/userinterfaces/terminal_interface.py

Modified: branches/rewrite/pywikibot/userinterfaces/terminal_interface.py
===================================================================
--- branches/rewrite/pywikibot/userinterfaces/terminal_interface.py	2009-02-23 14:50:57 UTC (rev 6429)
+++ branches/rewrite/pywikibot/userinterfaces/terminal_interface.py	2009-02-23 15:14:27 UTC (rev 6430)
@@ -9,6 +9,7 @@
 
 import traceback, re, sys
 import logging
+import threading
 import pywikibot
 from pywikibot import config
 from pywikibot.userinterfaces import transliteration
@@ -115,6 +116,7 @@
 
 class UI:
     def __init__(self):
+        self.writelock = threading.RLock()
         pass
 
     def printColorizedInUnix(self, text, level):
@@ -227,7 +229,12 @@
                     prev = transliterated[-1:]
                     prevchar = char
             text = u"".join(transliteratedText)
-        self.printColorized(text, level)
+        
+        self.writelock.acquire()
+        try:
+            self.printColorized(text, level)
+        finally:
+            self.writelock.release()
 
     def input(self, question, password = False):
         """
@@ -240,12 +247,21 @@
         # sound the terminal bell to notify the user
         if config.ring_bell:
             sys.stdout.write('\07')
+
+        # While we're waiting for user input, 
+        # we don't want terminal writes from other Threads
+        self.writelock.acquire()
         self.output(question + ' ', level=pywikibot.INPUT)
-        if password:
-            import getpass
-            text = getpass.getpass('')
-        else:
-            text = raw_input()
+
+        try:
+            if password:
+                import getpass
+                text = getpass.getpass('')
+            else:
+                text = raw_input()
+        finally:
+            self.writelock.release()
+
         text = unicode(text, config.console_encoding)
         return text
 
@@ -265,15 +281,30 @@
                 options[i] = '%s[%s]%s' % (option[:pos], caseHotkey, option[pos+1:])
             else:
                 options[i] = '%s [%s]' % (option, caseHotkey)
-        # loop until the user entered a valid choice
-        while True:
-            prompt = '%s (%s)' % (question, ', '.join(options))
-            answer = self.input(prompt)
-            if answer.lower() in hotkeys or answer.upper() in hotkeys:
-                return answer
-            elif default and answer=='':		# empty string entered
-                return default
+        
+        answer = ''
 
+        # While we're waiting for user input, 
+        # we don't want terminal writes from other Threads
+        self.writelock.acquire()
+        try:
+            # loop until the user entered a valid choice
+            while True:
+                prompt = '%s (%s)' % (question, ', '.join(options))
+                
+                # it's okay to enter input with the lock, RLock is reentrant.
+                answer = self.input(prompt)
+                if answer.lower() in hotkeys or answer.upper() in hotkeys:
+                    break
+                elif default and answer=='':		# empty string entered
+                    answer = default
+                    break
+        finally:
+            self.writelock.release()
+        return answer
+            
+        
+
     def editText(self, text, jumpIndex = None, highlight = None):
         """
         Uses a Tkinter edit box because we don't have a console editor
@@ -294,9 +325,9 @@
     def askForCaptcha(self, url):
         try:
             import webbrowser
-            wikipedia.output(u'Opening CAPTCHA in your web browser...')
+            pywikibot.output(u'Opening CAPTCHA in your web browser...')
             webbrowser.open(url)
-            return wikipedia.input(u'What is the solution of the CAPTCHA that is shown in your web browser?')
+            return pywikibot.input(u'What is the solution of the CAPTCHA that is shown in your web browser?')
         except:
-            wikipedia.output(u'Error in opening web browser: %s' % sys.exc_info()[0])
-            return wikipedia.input(u'What is the solution of the CAPTCHA at %s ?' % url)
+            pywikibot.output(u'Error in opening web browser: %s' % sys.exc_info()[0])
+            return pywikibot.input(u'What is the solution of the CAPTCHA at %s ?' % url)





More information about the Pywikipedia-l mailing list