Revision: 7290 Author: russblau Date: 2009-09-22 23:45:16 +0000 (Tue, 22 Sep 2009)
Log Message: ----------- Fix bug #2860737: pywikibot should not alter the root logger
Modified Paths: -------------- branches/rewrite/pywikibot/__init__.py branches/rewrite/pywikibot/bot.py branches/rewrite/pywikibot/comms/http.py branches/rewrite/pywikibot/comms/threadedhttp.py branches/rewrite/pywikibot/data/api.py branches/rewrite/pywikibot/family.py branches/rewrite/pywikibot/login.py branches/rewrite/pywikibot/page.py branches/rewrite/pywikibot/site.py branches/rewrite/pywikibot/throttle.py branches/rewrite/pywikibot/userinterfaces/terminal_interface.py branches/rewrite/scripts/editarticle.py
Modified: branches/rewrite/pywikibot/__init__.py =================================================================== --- branches/rewrite/pywikibot/__init__.py 2009-09-22 13:27:15 UTC (rev 7289) +++ branches/rewrite/pywikibot/__init__.py 2009-09-22 23:45:16 UTC (rev 7290) @@ -20,9 +20,7 @@ from exceptions import * from textlib import *
-logging.basicConfig(fmt="%(message)s")
- class Timestamp(datetime.datetime): """Class for handling Mediawiki timestamps.
@@ -98,7 +96,7 @@
def deprecate_arg(old_arg, new_arg): """Decorator to declare old_arg deprecated and replace it with new_arg""" - logger = logging.getLogger() + logger = logging.getLogger("pywiki") def decorator(method): def wrapper(*__args, **__kw): meth_name = method.__name__ @@ -141,7 +139,7 @@ @type user: unicode
""" - logger = logging.getLogger("wiki") + logger = logging.getLogger("pywiki.wiki")
if code is None: code = config.mylang @@ -167,7 +165,7 @@ key = '%s:%s:%s' % (fam, code, user) if not key in _sites: _sites[key] = __Site(code=code, fam=fam, user=user, sysop=sysop) - logging.debug(u"Instantiating Site object '%(site)s'" + logger.debug(u"Instantiating Site object '%(site)s'" % {'site': _sites[key]}) return _sites[key]
@@ -203,7 +201,7 @@ This method does not check the 'layer' argument for validity.
""" - logging.getLogger(layer).setLevel(DEBUG) + logging.getLogger("pywiki."+layer).setLevel(DEBUG)
def showDiff(oldtext, newtext): @@ -282,10 +280,10 @@
""" global stopped - logger = logging.getLogger("wiki") + logger = logging.getLogger("pywiki.wiki")
if not stopped: - logging.debug("stopme() called") + logger.debug("stopme() called") count = sum(1 for thd in threadpool if thd.isAlive()) if count: pywikibot.output(u"Waiting for about %(count)s pages to be saved."
Modified: branches/rewrite/pywikibot/bot.py =================================================================== --- branches/rewrite/pywikibot/bot.py 2009-09-22 13:27:15 UTC (rev 7289) +++ branches/rewrite/pywikibot/bot.py 2009-09-22 23:45:16 UTC (rev 7290) @@ -21,7 +21,7 @@ import sys
# logging levels -logger = logging.getLogger("bot") +logger = logging.getLogger("pywiki.bot")
from logging import DEBUG, INFO, WARNING, ERROR, CRITICAL STDOUT = 16 @@ -53,9 +53,8 @@ # search for user interface module in the 'userinterfaces' subdirectory uiModule = __import__("pywikibot.userinterfaces.%s_interface" % config.userinterface, - fromlist=['UI', 'TerminalHandler'] ) + fromlist=['UI'] ) ui = uiModule.UI() -TerminalHandler = uiModule.TerminalHandler
class RotatingFileHandler(logging.handlers.RotatingFileHandler): @@ -64,6 +63,7 @@ text = logging.handlers.RotatingFileHandler.format(self, record) return text.rstrip("\r\n")
+ class LoggingFormatter(logging.Formatter): def formatException(self, ei): """ @@ -83,6 +83,7 @@ else: return strExc + '\n'
+ def output(text, decoder=None, newline=True, toStdout=False, level=INFO): """Output a message to the user via the userinterface.
@@ -107,19 +108,13 @@
""" # make sure logging system has been initialized - root = logging.getLogger() + root = logging.getLogger("pywiki") if root.level == 30: # init_handlers sets this level - init_handlers() + init_handlers(strm=ui.output_stream)
if decoder: text = unicode(text, decoder) elif not isinstance(text, unicode): -## import traceback -## pywikibot.output( -## u"Non-unicode (%s) passed to wikipedia.output without decoder!\n" -## % type(text), -## level=VERBOSE -## ) if not isinstance(text, str): # looks like text is a non-text object. # Maybe it has a __unicode__ builtin ? @@ -149,9 +144,9 @@
""" # make sure logging system has been initialized - root = logging.getLogger() + root = logging.getLogger("pywiki") if root.level == 30: # init_handlers sets this level - init_handlers() + init_handlers(strm=ui.output_stream)
data = ui.input(question, password) return data @@ -175,17 +170,25 @@
""" # make sure logging system has been initialized - root = logging.getLogger() + root = logging.getLogger("pywiki") if root.level == 30: # init_handlers sets this level - init_handlers() + init_handlers(strm=ui.output_stream)
data = ui.inputChoice(question, answers, hotkeys, default).lower() return data
-def init_handlers(): - """Initialize logging system for terminal-based bots""" +def init_handlers(strm=None): + """Initialize logging system for terminal-based bots.
+ This function must be called before using pywikibot.output(); and must + be called again if the destination stream is changed. + + @param strm: Output stream. If None, re-uses the last stream if one + was defined, otherwise uses sys.stderr + + """ + # All user output is routed through the logging module. # Each type of output is handled by an appropriate handler object. # This structure is used to permit eventual development of other @@ -203,6 +206,14 @@ # Accordingly, do ''not'' use print statements in bot code; instead, # use pywikibot.output function.
+ global _stream + if strm: + _stream = strm + else: + try: + _stream + except NameError: + _stream = sys.stderr moduleName = calledModuleName() if not moduleName: moduleName = "terminal-interface" @@ -215,12 +226,12 @@ logging.addLevelName(INPUT, "INPUT") # for prompts requiring user response
- root_logger = logging.getLogger() - root_logger.handlers = [] # get rid of default handler + root_logger = logging.getLogger("pywiki") root_logger.setLevel(DEBUG+1) # all records except DEBUG go to logger + root_logger.handlers = [] # remove any old handlers
# configure default handler for VERBOSE and INFO levels - default_handler = TerminalHandler(strm=sys.stderr) + default_handler = ui.OutputHandlerClass(strm=_stream) if config.verbose_output: default_handler.setLevel(VERBOSE) else: @@ -247,19 +258,19 @@ file_handler.setFormatter(form) root_logger.addHandler(file_handler) for component in config.debug_log: - debuglogger = logging.getLogger(component) + debuglogger = logging.getLogger("pywiki."+component) debuglogger.setLevel(DEBUG) debuglogger.addHandler(file_handler)
# handler for level STDOUT - output_handler = TerminalHandler(strm=sys.stdout) + output_handler = ui.OutputHandlerClass(strm=sys.stdout) output_handler.setLevel(STDOUT) output_handler.addFilter(MaxLevelFilter(STDOUT)) output_handler.setFormatter(LoggingFormatter(fmt="%(message)s")) root_logger.addHandler(output_handler)
# handler for levels WARNING and higher - warning_handler = TerminalHandler(strm=sys.stderr) + warning_handler = ui.OutputHandlerClass(strm=_stream) warning_handler.setLevel(logging.WARNING) warning_handler.setFormatter( LoggingFormatter(fmt="%(levelname)s: %(message)s")) @@ -374,7 +385,7 @@ if username: config.usernames[config.family][config.mylang] = username
- init_handlers() + init_handlers(strm=ui.output_stream)
if config.verbose_output: import re @@ -450,7 +461,7 @@ if modname: pywikibot.output(u'Sorry, no help available for %s' % modname, level=pywikibot.STDOUT) - logging.exception('showHelp:') + logger.exception('showHelp:') pywikibot.output(globalHelp, level=pywikibot.STDOUT)
class Bot(object): @@ -486,7 +497,9 @@ self.options[opt] = kwargs[opt]
for opt in receivedOptions - validOptions: - logging.warning(u'%s is not a valid option. It was ignored\n' % opt) + pywikibot.output(u'%s is not a valid option. It was ignored\n' + % opt, + level=pywikibot.WARNING)
def getOption(self, option): """
Modified: branches/rewrite/pywikibot/comms/http.py =================================================================== --- branches/rewrite/pywikibot/comms/http.py 2009-09-22 13:27:15 UTC (rev 7289) +++ branches/rewrite/pywikibot/comms/http.py 2009-09-22 23:45:16 UTC (rev 7290) @@ -33,7 +33,7 @@ import cookielib import threadedhttp
-logger = logging.getLogger("comms.http") +logger = logging.getLogger("pywiki.comms.http")
# global variables
Modified: branches/rewrite/pywikibot/comms/threadedhttp.py =================================================================== --- branches/rewrite/pywikibot/comms/threadedhttp.py 2009-09-22 13:27:15 UTC (rev 7289) +++ branches/rewrite/pywikibot/comms/threadedhttp.py 2009-09-22 23:45:16 UTC (rev 7290) @@ -32,7 +32,7 @@
import pywikibot
-logger = logging.getLogger("comms.threadedhttp") +logger = logging.getLogger("pywiki.comms.threadedhttp")
# easy_install safeguarded dependencies
Modified: branches/rewrite/pywikibot/data/api.py =================================================================== --- branches/rewrite/pywikibot/data/api.py 2009-09-22 13:27:15 UTC (rev 7289) +++ branches/rewrite/pywikibot/data/api.py 2009-09-22 23:45:16 UTC (rev 7290) @@ -26,7 +26,7 @@ from pywikibot import config, login from pywikibot.exceptions import *
-logger = logging.getLogger("data.api") +logger = logging.getLogger("pywiki.data.api")
lagpattern = re.compile(r"Waiting for [\d.]+: (?P<lag>\d+) seconds? lagged")
Modified: branches/rewrite/pywikibot/family.py =================================================================== --- branches/rewrite/pywikibot/family.py 2009-09-22 13:27:15 UTC (rev 7289) +++ branches/rewrite/pywikibot/family.py 2009-09-22 23:45:16 UTC (rev 7290) @@ -14,7 +14,7 @@
import pywikibot
-logger = logging.getLogger("wiki.family") +logger = logging.getLogger("pywiki.wiki.family")
# Parent class for all wiki families
Modified: branches/rewrite/pywikibot/login.py =================================================================== --- branches/rewrite/pywikibot/login.py 2009-09-22 13:27:15 UTC (rev 7289) +++ branches/rewrite/pywikibot/login.py 2009-09-22 23:45:16 UTC (rev 7290) @@ -49,7 +49,7 @@ from pywikibot import config from pywikibot.exceptions import NoSuchSite, NoUsername
-logger = logging.getLogger("wiki.login") +logger = logging.getLogger("pywiki.wiki.login")
# On some wikis you are only allowed to run a bot if there is a link to
Modified: branches/rewrite/pywikibot/page.py =================================================================== --- branches/rewrite/pywikibot/page.py 2009-09-22 13:27:15 UTC (rev 7289) +++ branches/rewrite/pywikibot/page.py 2009-09-22 23:45:16 UTC (rev 7290) @@ -22,7 +22,7 @@ import unicodedata import urllib
-logger = logging.getLogger("wiki.page") +logger = logging.getLogger("pywiki.wiki.page")
reNamespace = re.compile("^(.+?) *: *(.*)$")
Modified: branches/rewrite/pywikibot/site.py =================================================================== --- branches/rewrite/pywikibot/site.py 2009-09-22 13:27:15 UTC (rev 7289) +++ branches/rewrite/pywikibot/site.py 2009-09-22 23:45:16 UTC (rev 7290) @@ -30,7 +30,7 @@ import threading import urllib
-logger = logging.getLogger("wiki.site") +logger = logging.getLogger("pywiki.wiki.site")
class PageInUse(pywikibot.Error): """Page cannot be reserved for writing due to existing lock.""" @@ -110,7 +110,11 @@ # is cut to zh-classic) elif self.__family.name in self.__family.langs.keys() \ or len(self.__family.langs) == 1: + oldcode = self.__code self.__code = self.__family.name + if self.__family == pywikibot.config.family \ + and oldcode == pywikibot.config.mylang: + pywikibot.config.mylang = self.__code else: raise NoSuchSite("Language %s does not exist in family %s" % (self.__code, self.__family.name))
Modified: branches/rewrite/pywikibot/throttle.py =================================================================== --- branches/rewrite/pywikibot/throttle.py 2009-09-22 13:27:15 UTC (rev 7289) +++ branches/rewrite/pywikibot/throttle.py 2009-09-22 23:45:16 UTC (rev 7290) @@ -17,7 +17,7 @@ import threading import time
-logger = logging.getLogger("wiki.throttle") +logger = logging.getLogger("pywiki.wiki.throttle")
pid = False # global process identifier # when the first Throttle is instantiated, it will set this
Modified: branches/rewrite/pywikibot/userinterfaces/terminal_interface.py =================================================================== --- branches/rewrite/pywikibot/userinterfaces/terminal_interface.py 2009-09-22 13:27:15 UTC (rev 7289) +++ branches/rewrite/pywikibot/userinterfaces/terminal_interface.py 2009-09-22 23:45:16 UTC (rev 7290) @@ -117,7 +117,8 @@ class UI: def __init__(self): self.writelock = threading.RLock() - pass + self.OutputHandlerClass = TerminalHandler + self.output_stream = sys.stderr
def output(self, text, level=logging.INFO): """ @@ -127,7 +128,7 @@ """ self.writelock.acquire() try: - logging.log(level, text) + logging.getLogger("pywiki").log(level, text) finally: self.writelock.release()
Modified: branches/rewrite/scripts/editarticle.py =================================================================== --- branches/rewrite/scripts/editarticle.py 2009-09-22 13:27:15 UTC (rev 7289) +++ branches/rewrite/scripts/editarticle.py 2009-09-22 23:45:16 UTC (rev 7290) @@ -108,7 +108,8 @@ """ text = self.convertLinebreaks(text) if config.editor: - tempFilename = '%s.%s' % (tempfile.mktemp(), config.editor_filename_extension) + tempFilename = '%s.%s' % (tempfile.mktemp(), + config.editor_filename_extension) tempFile = open(tempFilename, 'w') tempFile.write(text.encode(config.editor_encoding)) tempFile.close() @@ -120,14 +121,18 @@ # Nothing changed return None else: - newcontent = open(tempFilename).read().decode(config.editor_encoding) + newcontent = open(tempFilename).read().decode( + config.editor_encoding) os.unlink(tempFilename) return self.restoreLinebreaks(newcontent) else: - return self.restoreLinebreaks(pywikibot.ui.editText(text, jumpIndex = jumpIndex, highlight = highlight)) + return self.restoreLinebreaks( + pywikibot.editText(text, jumpIndex=jumpIndex, + highlight=highlight))
class ArticleEditor: - joinchars = string.letters + '[]' + string.digits # join lines if line starts with this ones + joinchars = string.letters + '[]' + string.digits + # join lines if line starts with this ones
def __init__(self, *args): self.set_options(*args)