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)