jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/786956 )
Change subject: [7.3] Prepare next release 7.3
......................................................................
[7.3] Prepare next release 7.3
Change-Id: Ibf7f64dd888da1bc6ac736fa2a877a11cbbe8b60
---
M .appveyor.yml
M HISTORY.rst
M ROADMAP.rst
M pywikibot/__metadata__.py
M scripts/CHANGELOG.md
M scripts/__init__.py
6 files changed, 48 insertions(+), 37 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/.appveyor.yml b/.appveyor.yml
index e0d352f..13593b4 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -1,7 +1,7 @@
image: Visual Studio 2019
clone_depth: 50
skip_tags: true
-version: 7.2.{build}
+version: 7.3.{build}
environment:
PYWIKIBOT_DIR: "%appdata%\\Pywikibot"
diff --git a/HISTORY.rst b/HISTORY.rst
index 528515c..b66d94e 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -1,6 +1,44 @@
Release history
^^^^^^^^^^^^^^^
+7.2.0
+-----
+*26 April 2022*
+
+* Make logging system consistent, add pywikibot.info() alias for pywikibot.output() (:phab:`T85620`)
+* L10N updates
+* Circumvent circular import in tools module (:phab:`T306760`)
+* Don't fix html inside syntaxhighlight parts in fixes.py (:phab:`T306723`)
+* Make layer parameter optional in `pywikibot.debug()` (:phab:`T85620`)
+* Retry for internal_api_error_DBQueryTimeoutError errors due to :phab:`T297708`
+* Handle ParserError within xmlreader.XmlDump.parse() instead of raising an exception (:phab:`T306134`)
+* XMLDumpOldPageGenerator is deprecated in favour of a `content` parameter (:phab:`T306134`)
+* `use_disambig` BaseBot attribute was added to hande disambig skipping
+* Deprecate RedirectPageBot and NoRedirectPageBot in favour of `use_redirects` attribute
+* tools.formatter.color_format is deprecated and will be removed
+* A new and easier color format was implemented; colors can be used like:
+ ``'this is a <<green>>colored<<default>> text'``
+* Unused and unsupported `xmlreader.XmlParserThread` was removed
+* Use upercased IP user titles (:phab:`T306291`)
+* Use pathlib to extract filename and file_package in pwb.py
+* Fix isbn messages in fixes.py (:phab:`T306166`)
+* Fix Page.revisions() with starttime (:phab:`T109181`)
+* Use stream_output for messages inside input_list_choice method (:phab:`T305940`)
+* Expand simulate query result (:phab:`T305918`)
+* Do not delete text when updating a Revision (:phab:`T304786`)
+* Re-enable scripts package version check with pwb wrapper (:phab:`T305799`)
+* Provide textlib.ignore_case() as a public method
+* Don't try to upcast timestamp from global userinfo if global account does not exists (:phab:`T305351`)
+* Archived scripts were removed; create a Phabricator task to restore some (:phab:`T223826`)
+* Add Lexeme support for Lexicographical data (:phab:`T189321`, :phab:`T305297`)
+* enable all parameters of `APISite.imageusage()` with `FilePage.usingPages()`
+* Don't raise `NoPageError` with `file_is_shared` (:phab:`T305182`)
+* Fix URL of GoogleOCR
+* Handle ratelimit with purgepages() (:phab:`T152597`)
+* Add movesubpages parameter to Page.move() and APISite.movepage() (:phab:`T57084`)
+* Do not iterate over sys.modules (:phab:`T304785`)
+
+
7.1.0
-----
*26 March 2022*
diff --git a/ROADMAP.rst b/ROADMAP.rst
index 89c0ac3..569d2f4 100644
--- a/ROADMAP.rst
+++ b/ROADMAP.rst
@@ -1,38 +1,7 @@
-Current release 7.2.0
+Current release 7.3.0
^^^^^^^^^^^^^^^^^^^^^
-* Make logging system consistent, add pywikibot.info() alias for pywikibot.output() (:phab:`T85620`)
-* L10N updates
-* Circumvent circular import in tools module (:phab:`T306760`)
-* Don't fix html inside syntaxhighlight parts in fixes.py (:phab:`T306723`)
-* Make layer parameter optional in `pywikibot.debug()` (:phab:`T85620`)
-* Retry for internal_api_error_DBQueryTimeoutError errors due to :phab:`T297708`
-* Handle ParserError within xmlreader.XmlDump.parse() instead of raising an exception (:phab:`T306134`)
-* XMLDumpOldPageGenerator is deprecated in favour of a `content` parameter (:phab:`T306134`)
-* `use_disambig` BaseBot attribute was added to hande disambig skipping
-* Deprecate RedirectPageBot and NoRedirectPageBot in favour of `use_redirects` attribute
-* tools.formatter.color_format is deprecated and will be removed
-* A new and easier color format was implemented; colors can be used like:
- ``'this is a <<green>>colored<<default>> text'``
-* Unused and unsupported `xmlreader.XmlParserThread` was removed
-* Use upercased IP user titles (:phab:`T306291`)
-* Use pathlib to extract filename and file_package in pwb.py
-* Fix isbn messages in fixes.py (:phab:`T306166`)
-* Fix Page.revisions() with starttime (:phab:`T109181`)
-* Use stream_output for messages inside input_list_choice method (:phab:`T305940`)
-* Expand simulate query result (:phab:`T305918`)
-* Do not delete text when updating a Revision (:phab:`T304786`)
-* Re-enable scripts package version check with pwb wrapper (:phab:`T305799`)
-* Provide textlib.ignore_case() as a public method
-* Don't try to upcast timestamp from global userinfo if global account does not exists (:phab:`T305351`)
-* Archived scripts were removed; create a Phabricator task to restore some (:phab:`T223826`)
-* Add Lexeme support for Lexicographical data (:phab:`T189321`, :phab:`T305297`)
-* enable all parameters of `APISite.imageusage()` with `FilePage.usingPages()`
-* Don't raise `NoPageError` with `file_is_shared` (:phab:`T305182`)
-* Fix URL of GoogleOCR
-* Handle ratelimit with purgepages() (:phab:`T152597`)
-* Add movesubpages parameter to Page.move() and APISite.movepage() (:phab:`T57084`)
-* Do not iterate over sys.modules (:phab:`T304785`)
+* *(no changes yet)*
Deprecations
diff --git a/pywikibot/__metadata__.py b/pywikibot/__metadata__.py
index a4fffeb..545603e 100644
--- a/pywikibot/__metadata__.py
+++ b/pywikibot/__metadata__.py
@@ -11,7 +11,7 @@
__name__ = 'pywikibot'
-__version__ = '7.2.0'
+__version__ = '7.3.0.dev0'
__description__ = 'Python MediaWiki Bot Framework'
__maintainer__ = 'The Pywikibot team'
__maintainer_email__ = 'pywikibot(a)lists.wikimedia.org'
diff --git a/scripts/CHANGELOG.md b/scripts/CHANGELOG.md
index a89eb6d..55eaff8 100644
--- a/scripts/CHANGELOG.md
+++ b/scripts/CHANGELOG.md
@@ -1,8 +1,12 @@
# Scripts Changelog
-## 7.2.0
+## 7.3.0
*In development*
+
+## 7.2.0
+*26 April 2022*
+
### general
* Archived scripts were removed
diff --git a/scripts/__init__.py b/scripts/__init__.py
index 92c0935..41f6eb7 100644
--- a/scripts/__init__.py
+++ b/scripts/__init__.py
@@ -29,4 +29,4 @@
#
# Distributed under the terms of the MIT license.
#
-__version__ = '7.2.0'
+__version__ = '7.3.0'
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/786956
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: Ibf7f64dd888da1bc6ac736fa2a877a11cbbe8b60
Gerrit-Change-Number: 786956
Gerrit-PatchSet: 2
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: D3r1ck01 <xsavitar.wiki(a)aol.com>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged
Xqt has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/786942 )
Change subject: [doc] Update roadmap
......................................................................
[doc] Update roadmap
Change-Id: I70093380d37df924c51ba4bb6605fb0fe1349026
---
M ROADMAP.rst
1 file changed, 2 insertions(+), 0 deletions(-)
Approvals:
Xqt: Verified; Looks good to me, approved
diff --git a/ROADMAP.rst b/ROADMAP.rst
index 66dfe63..89c0ac3 100644
--- a/ROADMAP.rst
+++ b/ROADMAP.rst
@@ -1,6 +1,7 @@
Current release 7.2.0
^^^^^^^^^^^^^^^^^^^^^
+* Make logging system consistent, add pywikibot.info() alias for pywikibot.output() (:phab:`T85620`)
* L10N updates
* Circumvent circular import in tools module (:phab:`T306760`)
* Don't fix html inside syntaxhighlight parts in fixes.py (:phab:`T306723`)
@@ -24,6 +25,7 @@
* Re-enable scripts package version check with pwb wrapper (:phab:`T305799`)
* Provide textlib.ignore_case() as a public method
* Don't try to upcast timestamp from global userinfo if global account does not exists (:phab:`T305351`)
+* Archived scripts were removed; create a Phabricator task to restore some (:phab:`T223826`)
* Add Lexeme support for Lexicographical data (:phab:`T189321`, :phab:`T305297`)
* enable all parameters of `APISite.imageusage()` with `FilePage.usingPages()`
* Don't raise `NoPageError` with `file_is_shared` (:phab:`T305182`)
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/786942
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I70093380d37df924c51ba4bb6605fb0fe1349026
Gerrit-Change-Number: 786942
Gerrit-PatchSet: 1
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-MessageType: merged
Xqt has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/630209 )
Change subject: [IMPR] make logging interface consistent
......................................................................
[IMPR] make logging interface consistent
- all interface is like msg. *args, **kwargs and all parameters
are the same; all parameters of Python logging utility functions
are supported
- introduce layer argument for all logging methods as proposed
- rename text parameter to msg like in python.logging
- all arguments except msg are keyword arguments, all positional
arguments are dropped
- cleanup deprecated postitional arguments
- only use decoder if bytes is given with msg
- update frame due to deprecated_args decorators
- only update extra parameter if required but do not override the
given content
- rename tb in exception with exc_info to be sync with Python
logging.exception
- all Pywikibot logger output functions are similar to Python
logging function with few differences:
- no parameter has to be given with output and stdout; this enables
to print an empty line previously done with pywikibot.output('')
- if no parameter is given with exception(), the error message is
computed from sys.exc_info. If a parameter is given with exception,
it works like error() function. This is different with Python
logging exception where 'exc_info' is set to True which prints
the traceback by default.
- rename output function to info to be in sync with Python logging.info
but keep the output function for backward compatibility
- update usage of these functions
- update ui tests
Bug: T85620
Change-Id: I17759dd9f2f31ee4efa84f6b390b20998a63f188
---
M pwb.py
M pywikibot/__init__.py
M pywikibot/cosmetic_changes.py
M pywikibot/logging.py
M pywikibot/pagegenerators.py
M scripts/archivebot.py
M scripts/category.py
M scripts/checkimages.py
M scripts/dataextend.py
M scripts/download_dump.py
M scripts/interwiki.py
M scripts/maintenance/cache.py
M scripts/maintenance/colors.py
M scripts/replicate_wiki.py
M scripts/solve_disambiguation.py
M tests/aspects.py
M tests/ui_tests.py
17 files changed, 277 insertions(+), 216 deletions(-)
Approvals:
jenkins-bot: Verified
Xqt: Looks good to me, approved
diff --git a/pwb.py b/pwb.py
index 6fddcec..3c46597 100755
--- a/pwb.py
+++ b/pwb.py
@@ -291,7 +291,7 @@
def find_alternates(filename, script_paths):
"""Search for similar filenames in the given script paths."""
- from pywikibot import config, input_choice, output
+ from pywikibot import config, input_choice, info
from pywikibot.bot import QuitKeyboardInterrupt, ShowingListOption
assert config.pwb_close_matches > 0, \
@@ -323,10 +323,10 @@
if len(similar_scripts) == 1:
script = similar_scripts[0]
wait_time = config.pwb_autostart_waittime
- output('NOTE: Starting the most similar script '
- '<<lightyellow>>{}.py<<default>>\n'
- ' in {} seconds; type CTRL-C to stop.'
- .format(script, wait_time))
+ info('NOTE: Starting the most similar script '
+ '<<lightyellow>>{}.py<<default>>\n'
+ ' in {} seconds; type CTRL-C to stop.'
+ .format(script, wait_time))
try:
sleep(wait_time) # Wait a bit to let it be cancelled
except KeyboardInterrupt:
diff --git a/pywikibot/__init__.py b/pywikibot/__init__.py
index 54780d2..b94b610 100644
--- a/pywikibot/__init__.py
+++ b/pywikibot/__init__.py
@@ -60,6 +60,7 @@
debug,
error,
exception,
+ info,
log,
output,
stdout,
@@ -78,12 +79,12 @@
'__version__',
'Bot', 'calledModuleName', 'Category', 'Claim', 'Coordinate', 'critical',
'CurrentPageBot', 'debug', 'error', 'exception', 'FilePage', 'handle_args',
- 'html2unicode', 'input', 'input_choice', 'input_yn', 'ItemPage',
- 'LexemeForm', 'LexemePage', 'LexemeSense', 'Link',
- 'log', 'MediaInfo', 'output', 'Page', 'PropertyPage', 'showDiff',
- 'show_help', 'Site', 'SiteLink', 'stdout', 'Timestamp', 'translate', 'ui',
- 'url2unicode', 'User', 'warning', 'WbGeoShape', 'WbMonolingualText',
- 'WbQuantity', 'WbTabularData', 'WbTime', 'WbUnknown', 'WikidataBot',
+ 'html2unicode', 'info', 'input', 'input_choice', 'input_yn', 'ItemPage',
+ 'LexemeForm', 'LexemePage', 'LexemeSense', 'Link', 'log', 'MediaInfo',
+ 'output', 'Page', 'PropertyPage', 'showDiff', 'show_help', 'Site',
+ 'SiteLink', 'stdout', 'Timestamp', 'translate', 'ui', 'url2unicode',
+ 'User', 'warning', 'WbGeoShape', 'WbMonolingualText', 'WbQuantity',
+ 'WbTabularData', 'WbTime', 'WbUnknown', 'WikidataBot',
)
# argvu is set by pywikibot.bot when it's imported
diff --git a/pywikibot/cosmetic_changes.py b/pywikibot/cosmetic_changes.py
index 09f12dc..522f153 100644
--- a/pywikibot/cosmetic_changes.py
+++ b/pywikibot/cosmetic_changes.py
@@ -283,7 +283,7 @@
if self.ignore == CANCEL.METHOD:
pywikibot.warning('Unable to perform "{}" on "{}"!'
.format(method.__name__, self.title))
- pywikibot.exception(e)
+ pywikibot.error(e)
else:
raise
return text if result is None else result
@@ -302,7 +302,7 @@
if self.ignore == CANCEL.PAGE:
pywikibot.warning('Skipped "{}", because an error occurred.'
.format(self.title))
- pywikibot.exception(e)
+ pywikibot.error(e)
return False
raise
else:
diff --git a/pywikibot/logging.py b/pywikibot/logging.py
index 1eaa02a..5399d03 100644
--- a/pywikibot/logging.py
+++ b/pywikibot/logging.py
@@ -1,21 +1,21 @@
"""User output/logging functions.
-Six output functions are defined. Each requires a string argument
+Six output functions are defined. Each requires a ``msg`` argument
All of these functions generate a message to the log file if
logging is enabled (`-log` or `-debug` command line arguments).
-The functions :func:`output()`, :func:`stdout()`, :func:`warning()` and
-:func:`error()` all display a message to the user through the logger
-object; the only difference is the priority level, which can be used by
-the application layer to alter the display. The :func:`stdout()`
-function should be used only for data that is the "result" of a script,
-as opposed to information messages to the user.
+The functions :func:`info` (alias :func:`output`), :func:`stdout`,
+:func:`warning` and :func:`error` all display a message to the user
+through the logger object; the only difference is the priority level,
+which can be used by the application layer to alter the display. The
+:func:`stdout` function should be used only for data that is the
+"result" of a script, as opposed to information messages to the user.
-The function :func:`log()` by default does not display a message to the
+The function :func:`log` by default does not display a message to the
user, but this can be altered by using the `-verbose` command line
option.
-The function :func:`debug()` only logs its messages, they are never
+The function :func:`debug` only logs its messages, they are never
displayed on the user console. :func:`debug()` takes a required second
argument, which is a string indicating the debugging layer.
"""
@@ -30,16 +30,17 @@
# logging levels
from logging import CRITICAL, DEBUG, ERROR, INFO, WARNING
-from typing import Any, Optional, Union
+from typing import Any
from pywikibot.backports import Callable, List
-
+from pywikibot.tools import deprecated_args, issue_deprecation_warning
STDOUT = 16 #:
VERBOSE = 18 #:
INPUT = 25 #:
"""Three additional logging levels which are implemented beside
-`CRITICAL`, `DEBUG`, `ERROR`, `INFO` and `WARNING`.
+:const:`CRITICAL`, :const:`DEBUG`, :const:`ERROR`, :const:`INFO` and
+:const:`WARNING`.
.. seealso:: :python:`Python Logging Levels<logging.html#logging-levels>`
"""
@@ -65,212 +66,266 @@
_init_routines[:] = [] # the global variable is used with slice operator
-def logoutput(text: object, decoder: Optional[str] = None,
- newline: bool = True, _level: int = INFO, _logger: str = '',
+# Note: The frame must be updated if this decorator is removed
+@deprecated_args(text='msg') # since 7.2
+def logoutput(msg: Any,
+ *args: Any,
+ level: int = INFO,
**kwargs: Any) -> None:
"""Format output and send to the logging module.
Helper function used by all the user-output convenience functions.
It can be used to implement your own high-level output function with
- a different lgging level.
- """
- if _logger:
- logger = logging.getLogger('pywiki.' + _logger)
- else:
- logger = logging.getLogger('pywiki')
+ a different logging level.
+ `msg` can contain special sequences to create colored output. These
+ consist of the color name in angle bracket, e. g. <<lightpurple>>.
+ <<default>> resets the color.
+
+ Other keyword arguments are passed unchanged to the logger; so far,
+ the only argument that is useful is ``exc_info=True``, which causes
+ the log message to include an exception traceback.
+
+ :param msg: The message to be printed.
+ :param args: Not used yet; prevents positinal arguments except `msg`.
+ :param level: The logging level; supported by :func:`logoutput` only.
+ :keyword newline: If newline is True (default), a line feed will be
+ added after printing the msg.
+ :type newline: bool
+ :keyword layer: Suffix of the logger name separated by dot. By
+ default no suffix is used.
+ :type layer: str
+ :keyword decoder: If msg is bytes, this decoder is used to deccode.
+ Default is 'utf-8', fallback is 'iso8859-1'
+ :type decoder: str
+ :param kwargs: For the other keyword arguments refer
+ :python:`Logger.debug()<library/logging.html#logging.Logger.debug>`
+ and :pyhow:`logging-cookbook`
+ """
# invoke any init routines
if _init_routines:
_init()
- # frame 0 is logoutput() in this module,
- # frame 1 is the convenience function (output(), etc.)
- # frame 2 is whatever called the convenience function
- frame = sys._getframe(2)
+ # cleanup positional args
+ if level == ERROR:
+ keys = ('decoder', 'newline', 'exc_info')
+ elif level == DEBUG:
+ keys = ('layer', 'decoder', 'newline')
+ else:
+ keys = ('decoder', 'newline')
+ for i, arg in enumerate(args):
+ key = keys[i]
+ issue_deprecation_warning(
+ 'Positional argument {} ({})'.format(i + 1, arg),
+ 'keyword argument "{}={}"'.format(key, arg),
+ since='7.2.0')
+ if key in kwargs:
+ warning('{!r} is given as keyword argument {!r} already; ignoring '
+ '{!r}'.format(key, arg, kwargs[key]))
+ else:
+ kwargs[key] = arg
+ # frame 0 is logoutput() in this module,
+ # frame 1 is the deprecation wrapper of this function
+ # frame 2 is the convenience function (output(), etc.)
+ # frame 3 is the deprecation wrapper the convenience function
+ # frame 4 is whatever called the convenience function
+ newline = kwargs.pop('newline', True)
+ frame = sys._getframe(4)
module = os.path.basename(frame.f_code.co_filename)
context = {'caller_name': frame.f_code.co_name,
'caller_file': module,
'caller_line': frame.f_lineno,
'newline': ('\n' if newline else '')}
+ context.update(kwargs.pop('extra', {}))
- if isinstance(text, str):
- decoded_text = text
- elif isinstance(text, bytes):
- if decoder:
- decoded_text = text.decode(decoder)
- else:
- try:
- decoded_text = text.decode('utf-8')
- except UnicodeDecodeError:
- decoded_text = text.decode('iso8859-1')
- else:
- # looks like text is a non-text object.
- # Maybe it has a __str__ builtin ?
- # (allows to print Page, Site...)
- decoded_text = str(text)
+ decoder = kwargs.pop('decoder', 'utf-8')
+ if isinstance(msg, bytes):
+ try:
+ msg = msg.decode(decoder)
+ except UnicodeDecodeError:
+ msg = msg.decode('iso8859-1')
- logger.log(_level, decoded_text, extra=context, **kwargs)
+ layer = kwargs.pop('layer', '')
+ logger = logging.getLogger(('pywiki.' + layer).strip('.'))
+ logger.log(level, msg, extra=context, **kwargs)
-def output(text: object, decoder: Optional[str] = None, newline: bool = True,
- **kwargs: Any) -> None:
- """Output a message to the user via the userinterface.
+# Note: The logoutput frame must be updated if this decorator is removed
+@deprecated_args(text='msg') # since 7.2
+def info(msg: Any = '', *args: Any, **kwargs: Any) -> None:
+ """Output a message to the user with level :const:`INFO`.
- Works like print, but uses the encoding used by the user's console
- (console_encoding in the configuration file) instead of ASCII.
+ ``msg`` will be sent to stderr via :mod:`pywikibot.userinterfaces`.
+ It may be omitted and a newline is printed in that case.
+ The arguments are interpreted as for :func:`logoutput`.
- If decoder is None, text should be a unicode string. Otherwise it
- should be encoded in the given encoding.
+ .. versionadded:: 7.2
+ was renamed from :func:`output`.
- If newline is True, a line feed will be added after printing the text.
-
- text can contain special sequences to create colored output. These
- consist of the color name in angle bracket, e. g. <<lightpurple>>.
- <<default>> resets the color.
-
- Other keyword arguments are passed unchanged to the logger; so far, the
- only argument that is useful is "exc_info=True", which causes the
- log message to include an exception traceback.
+ .. seealso::
+ :python:`Logger.info()<library/logging.html#logging.Logger.info>`
"""
- logoutput(text, decoder, newline, INFO, **kwargs)
+ logoutput(msg, *args, **kwargs)
-def stdout(text: object, decoder: Optional[str] = None, newline: bool = True,
- **kwargs: Any) -> None:
- """Output script results to the user via the userinterface.
+output = info
+"""Synomym for :func:`info` for backward compatibility. The arguments
+are interpreted as for :func:`logoutput`.
- The text will be sent to standard output, so that it can be piped to
- another process. All other text will be sent to stderr.
- See: https://en.wikipedia.org/wiki/Pipeline_%28Unix%29
-
- :param text: the message printed via stdout logger to the user.
- :param decoder: If None, text should be a unicode string else it should
- be encoded in the given encoding.
- :param newline: If True, a line feed will be added after printing the text.
- :param kwargs: The keyword arguments can be found in the python doc:
- :pyhow:`logging-cookbook`
- """
- logoutput(text, decoder, newline, STDOUT, **kwargs)
+.. versionchanged:: 7.2
+ was renamed to :func:`info`; `text`was renamed to `msg`; `msg`
+ paramerer may be omitted; only keyword arguments are allowed except
+ for `msg`.
+.. seealso::
+ :python:`Logger.info()<library/logging.html#logging.Logger.info>`
+"""
-def warning(text: object, decoder: Optional[str] = None,
- newline: bool = True, **kwargs: Any) -> None:
- """Output a warning message to the user via the userinterface.
+# Note: The logoutput frame must be updated if this decorator is removed
+@deprecated_args(text='msg') # since 7.2
+def stdout(msg: Any = '', *args: Any, **kwargs: Any) -> None:
+ """Output script results to the user with level :const:`STDOUT`.
- :param text: the message the user wants to display.
- :param decoder: If None, text should be a unicode string else it
- should be encoded in the given encoding.
- :param newline: If True, a line feed will be added after printing the text.
- :param kwargs: The keyword arguments can be found in the python doc:
- :pyhow:`logging-cookbook`
- """
- logoutput(text, decoder, newline, WARNING, **kwargs)
+ ``msg`` will be sent to standard output (stdout) via
+ :mod:`pywikibot.userinterfaces`, so that it can be piped to another
+ process. All other functions will sent to stderr.
+ `msg` may be omitted and a newline is printed in that case.
-
-def error(text: object, decoder: Optional[str] = None, newline: bool = True,
- **kwargs: Any) -> None:
- """Output an error message to the user via the userinterface.
-
- :param text: the message containing the error which occurred.
- :param decoder: If None, text should be a unicode string else it should
- be encoded in the given encoding.
- :param newline: If True, a line feed will be added after printing the text.
- :param kwargs: The keyword arguments can be found in the python doc:
- :pyhow:`logging-cookbook`
- """
- logoutput(text, decoder, newline, ERROR, **kwargs)
-
-
-def log(text: object, decoder: Optional[str] = None, newline: bool = True,
- **kwargs: Any) -> None:
- """Output a record to the log file.
-
- :param text: the message which is to be logged to the log file.
- :param decoder: If None, text should be a unicode string else it should
- be encoded in the given encoding.
- :param newline: If True, a line feed will be added after printing the text.
- :param kwargs: The keyword arguments can be found in the python doc:
- :pyhow:`logging-cookbook`
- """
- logoutput(text, decoder, newline, VERBOSE, **kwargs)
-
-
-def critical(text: object, decoder: Optional[str] = None, newline: bool = True,
- **kwargs: Any) -> None:
- """Output a critical record to the user via the userinterface.
-
- :param text: the critical message which is to be displayed to the user.
- :param decoder: If None, text should be a unicode string else it should
- be encoded in the given encoding.
- :param newline: If True, a line feed will be added after printing the text.
- :param kwargs: The keyword arguments can be found in the python doc:
- :pyhow:`logging-cookbook`
- """
- logoutput(text, decoder, newline, CRITICAL, **kwargs)
-
-
-def debug(text: object, layer: str = '', decoder: Optional[str] = None,
- newline: bool = True, **kwargs: Any) -> None:
- """Output a debug record to the log file.
+ The arguments are interpreted as for :func:`logoutput`.
.. versionchanged:: 7.2
- `layer` parameter is optional.
-
- :param text: the message of the debug record to be logged to the log file.
- :param layer: dot-separated logger suffix to record this message
- upon. If not given only 'pywiki' is used as logger name.
- :param decoder: If None, text should be a unicode string else it should
- be encoded in the given encoding.
- :param newline: If True, a line feed will be added after printing the text.
- :param kwargs: The keyword arguments can be found in the python doc:
- :pyhow:`logging-cookbook`
+ `text`was renamed to `msg`; `msg` paramerer may be omitted;
+ only keyword arguments are allowed except for `msg`.
+ .. seealso::
+ - :python:`Logger.log()<library/logging.html#logging.Logger.log>`
+ - https://en.wikipedia.org/wiki/Pipeline_%28Unix%29
"""
- logoutput(text, decoder, newline, DEBUG, layer, **kwargs)
+ logoutput(msg, *args, level=STDOUT, **kwargs)
-def exception(
- msg: Union[Exception, str, None] = None,
- decoder: Optional[str] = None,
- newline: bool = True,
- tb: bool = False,
- **kwargs: Any
-) -> None:
- """Output an error traceback to the user via the userinterface.
+# Note: The logoutput frame must be updated if this decorator is removed
+@deprecated_args(text='msg') # since 7.2
+def warning(msg: Any, *args: Any, **kwargs: Any) -> None:
+ """Output a warning message to the user with level :const:`WARNING`.
+
+ ``msg`` will be sent to stderr via :mod:`pywikibot.userinterfaces`.
+ The arguments are interpreted as for :func:`logoutput`.
+
+ .. versionchanged:: 7.2
+ `text`was renamed to `msg`; only keyword arguments are allowed
+ except for `msg`.
+ .. seealso::
+ :python:`Logger.warning()<library/logging.html#logging.Logger.warning>`
+ """
+ logoutput(msg, *args, level=WARNING, **kwargs)
+
+
+# Note: The logoutput frame must be updated if this decorator is removed
+@deprecated_args(text='msg') # since 7.2
+def error(msg: Any, *args: Any, **kwargs: Any) -> None:
+ """Output an error message to the user with level :const:`ERROR`.
+
+ ``msg`` will be sent to stderr via :mod:`pywikibot.userinterfaces`.
+ The arguments are interpreted as for :func:`logoutput`.
+
+ .. versionchanged:: 7.2
+ `text`was renamed to `msg`; only keyword arguments are allowed
+ except for `msg`.
+ .. seealso::
+ :python:`Logger.error()<library/logging.html#logging.Logger.error>`
+ """
+ logoutput(msg, *args, level=ERROR, **kwargs)
+
+
+# Note: The logoutput frame must be updated if this decorator is removed
+@deprecated_args(text='msg') # since 7.2
+def log(msg: Any, *args: Any, **kwargs: Any) -> None:
+ """Output a record to the log file with level :const:`VERBOSE`.
+
+ The arguments are interpreted as for :func:`logoutput`.
+
+ .. versionchanged:: 7.2
+ `text`was renamed to `msg`; only keyword arguments are allowed
+ except for `msg`.
+ .. seealso::
+ :python:`Logger.log()<library/logging.html#logging.Logger.log>`
+ """
+ logoutput(msg, *args, level=VERBOSE, **kwargs)
+
+
+# Note: The logoutput frame must be updated if this decorator is removed
+@deprecated_args(text='msg') # since 7.2
+def critical(msg: Any, *args: Any, **kwargs: Any) -> None:
+ """Output a critical record to the user with level :const:`CRITICAL`.
+
+ ``msg`` will be sent to stderr via :mod:`pywikibot.userinterfaces`.
+ The arguments are interpreted as for :func:`logoutput`.
+
+ .. versionchanged:: 7.2
+ `text`was renamed to `msg`; only keyword arguments are allowed
+ except for `msg`.
+ .. seealso::
+ :python:`Logger.critical()
+ <library/logging.html#logging.Logger.critical>`
+ """
+ logoutput(msg, *args, level=CRITICAL, **kwargs)
+
+
+# Note: The logoutput frame must be updated if this decorator is removed
+@deprecated_args(text='msg') # since 7.2
+def debug(msg: Any, *args: Any, **kwargs: Any) -> None:
+ """Output a debug record to the log file with level :const:`DEBUG`.
+
+ The arguments are interpreted as for :func:`logoutput`.
+
+ .. versionchanged:: 7.2
+ `layer` parameter is optional; `text`was renamed to `msg`;
+ only keyword arguments are allowed except for `msg`.
+ .. seealso::
+ :python:`Logger.debug()<library/logging.html#logging.Logger.debug>`
+ """
+ logoutput(msg, *args, level=DEBUG, **kwargs)
+
+
+# Note: The logoutput frame must be updated if this decorator is removed
+@deprecated_args(tb='exc_info') # since 7.2
+def exception(msg: Any = None, *args: Any, **kwargs: Any) -> None:
+ """Output an error traceback to the user with level :const:`ERROR`.
Use directly after an 'except' statement::
...
except Exception:
- pywikibot.exception()
+ pywikibot.exception('exc_info'=True)
...
or alternatively::
...
except Exception as e:
- pywikibot.exception(e)
+ pywikibot.exception(e, 'exc_info'=True)
...
+ Without `exc_info` parameter this function works like :func:`error`
+ except that the `msg` parameter may be omitted.
This function should only be called from an Exception handler.
+ ``msg`` will be sent to stderr via :mod:`pywikibot.userinterfaces`.
+ The arguments are interpreted as for :func:`logoutput`.
- :param msg: If not None, contains the description of the exception
- that occurred.
- :param decoder: If None, text should be a unicode string else it should
- be encoded in the given encoding.
- :param newline: If True, a line feed will be added after printing the text.
- :param kwargs: The keyword arguments can be found in the python doc:
- :pyhow:`logging-cookbook`
- :param tb: Set to True in order to output traceback also.
+ .. versionchanged:: 7.2
+ only keyword arguments are allowed except for `msg`;
+ `exc_info` keyword is to be used instead of `tb`.
+ .. seealso::
+ :python:`Logger.exception()
+ <library/logging.html#logging.Logger.exception>`
+
+ The arguments are interpreted as for :meth:`output`.
"""
- if isinstance(msg, BaseException):
- if tb:
- kwargs['exc_info'] = 1
- else:
- exc_info = sys.exc_info()
- msg = '{}: {}'.format(repr(exc_info[1]).split('(')[0],
- str(exc_info[1]).strip())
- if tb:
- kwargs['exc_info'] = exc_info
+ if msg is None:
+ exc_type, value, _tb = sys.exc_info()
+ msg = str(value)
+ if not kwargs.get('exc_info', False):
+ msg += ' ({})'.format(exc_type.__name__)
assert msg is not None
- logoutput(msg, decoder, newline, ERROR, **kwargs)
+ error(msg, *args, **kwargs)
diff --git a/pywikibot/pagegenerators.py b/pywikibot/pagegenerators.py
index 50160b1..796cecf 100644
--- a/pywikibot/pagegenerators.py
+++ b/pywikibot/pagegenerators.py
@@ -1422,7 +1422,7 @@
pywikibot.warning('LogeventsPageGenerator: '
'failed to load page for {!r}; skipping'
.format(entry.data))
- pywikibot.exception(e)
+ pywikibot.error(e)
def NewpagesPageGenerator(site: OPT_SITE_TYPE = None,
@@ -1752,7 +1752,7 @@
namespaces = site.namespaces.resolve(namespaces)
except KeyError as e:
pywikibot.log('Failed resolving namespaces:')
- pywikibot.exception(e)
+ pywikibot.error(e)
raise
return (page for page in generator if page.namespace() in namespaces)
@@ -2707,7 +2707,7 @@
try:
import google
except ImportError:
- pywikibot.error('ERROR: generator GoogleSearchPageGenerator '
+ pywikibot.error('generator GoogleSearchPageGenerator '
"depends on package 'google'.\n"
'To install, please run: pip install google.')
sys.exit(1)
diff --git a/scripts/archivebot.py b/scripts/archivebot.py
index 13d362d..1ba136b 100755
--- a/scripts/archivebot.py
+++ b/scripts/archivebot.py
@@ -910,9 +910,8 @@
pywikibot.error('Missing or malformed template in page {}: {}'
.format(pg, e))
except Exception:
- pywikibot.error('Error occurred while processing page {}'
- .format(pg))
- pywikibot.exception(tb=True)
+ pywikibot.exception('Error occurred while processing page {}'
+ .format(pg), exc_info=True)
if __name__ == '__main__':
diff --git a/scripts/category.py b/scripts/category.py
index 0119536..5a7e12b 100755
--- a/scripts/category.py
+++ b/scripts/category.py
@@ -1114,8 +1114,7 @@
pywikibot.output(line)
# show the title of the page where the link was found.
- pywikibot.output('')
- pywikibot.output('>>> <<lightpurple>>{}<<default>> <<<'
+ pywikibot.output('\n>>> <<lightpurple>>{}<<default>> <<<'
.format(member.title()))
# determine a reasonable amount of context.
@@ -1151,8 +1150,7 @@
key=methodcaller('title'))
# show categories as possible choices with numbers
- pywikibot.output('')
-
+ pywikibot.output()
supercat_option = CatIntegerOption(0, len(supercatlist), 'u')
if not supercatlist:
pywikibot.output('This category has no supercategories.')
@@ -1171,7 +1169,7 @@
subcat_option.list_categories(cat_list)
# show possible options for the user
- pywikibot.output('')
+ pywikibot.output()
options = (supercat_option,
subcat_option,
StandardOption(
@@ -1248,7 +1246,7 @@
def treat(self, page) -> None:
"""Process page."""
- pywikibot.output('')
+ pywikibot.output()
self.move_to_category(page, self.cat, self.cat)
@@ -1343,7 +1341,7 @@
cat = pywikibot.Category(self.site, self.cat_title)
pywikibot.output('Generating tree...', newline=False)
tree = self.treeview(cat)
- pywikibot.output('')
+ pywikibot.output()
if self.filename:
pywikibot.output('Saving results in ' + self.filename)
with codecs.open(self.filename, 'a', 'utf-8') as f:
diff --git a/scripts/checkimages.py b/scripts/checkimages.py
index a929f54..0c9430e 100755
--- a/scripts/checkimages.py
+++ b/scripts/checkimages.py
@@ -745,7 +745,7 @@
self.num_notify[self.talk_page.title()] -= 1
err = None
if err:
- pywikibot.exception(err)
+ pywikibot.error(err)
pywikibot.output('Skipping saving talk page {}'
.format(self.talk_page))
@@ -1351,9 +1351,9 @@
pywikibot.output('Skipping {}...'.format(self.image_name))
self.skip_list.append(self.image_name)
if skip_number == 1:
- pywikibot.output('')
+ pywikibot.output()
return True
- pywikibot.output('')
+ pywikibot.output()
return False
@staticmethod
diff --git a/scripts/dataextend.py b/scripts/dataextend.py
index f8ee391..5f916df 100644
--- a/scripts/dataextend.py
+++ b/scripts/dataextend.py
@@ -1290,7 +1290,7 @@
if not self.url and not self.sparqlquery:
return
newclaims = []
- pywikibot.output('')
+ pywikibot.output()
pagerequest = None
if not self.skipfirst:
try:
@@ -1638,7 +1638,7 @@
if result:
newclaims.append((prop, result, self))
- pywikibot.output('')
+ pywikibot.output()
for (function, prop) in [
(self.findcoords, 'coordinates'),
]:
diff --git a/scripts/download_dump.py b/scripts/download_dump.py
index 66626d8..4a7b6cf 100755
--- a/scripts/download_dump.py
+++ b/scripts/download_dump.py
@@ -133,7 +133,7 @@
parts = 50
display_string = ''
- pywikibot.output('')
+ pywikibot.output()
for data in response.iter_content(100 * 1024):
result_file.write(data)
@@ -156,7 +156,7 @@
- len(display_string.rstrip()))
pywikibot.output(display_string, newline=False)
- pywikibot.output('')
+ pywikibot.output()
# Rename the temporary file to the target file
# if the download completes successfully
diff --git a/scripts/interwiki.py b/scripts/interwiki.py
index 9eb1dfd..d6473b0 100755
--- a/scripts/interwiki.py
+++ b/scripts/interwiki.py
@@ -1823,7 +1823,7 @@
page, linkedPage))
except OSError:
- pywikibot.output('ERROR: could not report backlinks')
+ pywikibot.error('could not report backlinks')
class InterwikiBot:
diff --git a/scripts/maintenance/cache.py b/scripts/maintenance/cache.py
index 512a818..cb24d54 100755
--- a/scripts/maintenance/cache.py
+++ b/scripts/maintenance/cache.py
@@ -268,7 +268,7 @@
except ValueError as e:
pywikibot.error('Failed loading {}'.format(
entry._cachefile_path()))
- pywikibot.exception(e, tb=True)
+ pywikibot.exception(e, exc_info=True)
continue
if use_accesstime is None:
@@ -294,7 +294,7 @@
pywikibot.error('Problems loading {} with key {}, {!r}'
.format(entry.filename, entry.key,
entry._parsed_key))
- pywikibot.exception(e, tb=True)
+ pywikibot.exception(e, exc_info=True)
continue
if func is None or func(entry):
diff --git a/scripts/maintenance/colors.py b/scripts/maintenance/colors.py
index 9a0434d..2f4543b 100755
--- a/scripts/maintenance/colors.py
+++ b/scripts/maintenance/colors.py
@@ -37,7 +37,7 @@
line = '{} {}'.format(bg_col.ljust(max_len_bc_color), line)
pywikibot.output(line)
- pywikibot.output('')
+ pywikibot.output()
if __name__ == '__main__':
diff --git a/scripts/replicate_wiki.py b/scripts/replicate_wiki.py
index f4e2478..18735fa 100755
--- a/scripts/replicate_wiki.py
+++ b/scripts/replicate_wiki.py
@@ -94,7 +94,7 @@
for s in self.sites:
s.login()
pywikibot.output(str(s), newline=False)
- pywikibot.output('')
+ pywikibot.output()
def check_sysops(self) -> None:
"""Check if sysops are the same on all wikis."""
@@ -145,9 +145,8 @@
pywikibot.output('Bizarre NoPageError that we are '
'just going to ignore')
except IsRedirectPageError:
- pywikibot.output(
- 'error: Redirectpage - todo: handle gracefully')
- pywikibot.output('')
+ pywikibot.error('Redirectpage - todo: handle gracefully')
+ pywikibot.output()
def generate_overviews(self) -> None:
"""Create page on wikis with overview of bot results."""
diff --git a/scripts/solve_disambiguation.py b/scripts/solve_disambiguation.py
index 63e3e2e..5e3d8a4 100755
--- a/scripts/solve_disambiguation.py
+++ b/scripts/solve_disambiguation.py
@@ -1084,7 +1084,7 @@
else:
pywikibot.output('\nThe following changes have been made:\n')
pywikibot.showDiff(original_text, text)
- pywikibot.output('')
+ pywikibot.output()
# save the page
self.setSummaryMessage(disamb_page, new_targets,
unlink_counter, dn)
diff --git a/tests/aspects.py b/tests/aspects.py
index c93da45..b2b8af8 100644
--- a/tests/aspects.py
+++ b/tests/aspects.py
@@ -467,9 +467,9 @@
'HTTP status: {} - {}'.format(
r.status_code, HTTPStatus(r.status_code).phrase))
except Exception as e:
- pywikibot.error('{}: accessing {} caused exception:'
- .format(cls.__name__, hostname))
- pywikibot.exception(e, tb=True)
+ pywikibot.exception('{}: accessing {} caused exception:'
+ .format(cls.__name__, hostname),
+ exc_info=True)
cls._checked_hostnames[hostname] = e
raise unittest.SkipTest(
diff --git a/tests/ui_tests.py b/tests/ui_tests.py
index cab4146..6df6054 100755
--- a/tests/ui_tests.py
+++ b/tests/ui_tests.py
@@ -160,17 +160,26 @@
pywikibot.exception('exception')
self.assertEqual(self.strout.getvalue(), '')
self.assertEqual(self.strerr.getvalue(),
- 'ERROR: TestExceptionError: Testing Exception\n')
+ 'ERROR: exception\n')
+
+ def test_exception_empty(self):
+ try:
+ raise TestExceptionError('Testing Exception')
+ except TestExceptionError:
+ pywikibot.exception()
+ self.assertEqual(self.strout.getvalue(), '')
+ self.assertEqual(self.strerr.getvalue(),
+ 'ERROR: Testing Exception (TestExceptionError)\n')
def test_exception_tb(self):
try:
raise TestExceptionError('Testing Exception')
except TestExceptionError:
- pywikibot.exception('exception', tb=True)
+ pywikibot.exception(exc_info=True)
self.assertEqual(self.strout.getvalue(), '')
stderrlines = self.strerr.getvalue().split('\n')
self.assertEqual(stderrlines[0],
- 'ERROR: TestExceptionError: Testing Exception')
+ 'ERROR: Testing Exception')
self.assertEqual(stderrlines[1], 'Traceback (most recent call last):')
self.assertEqual(stderrlines[3],
" raise TestExceptionError('Testing Exception')")
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/630209
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I17759dd9f2f31ee4efa84f6b390b20998a63f188
Gerrit-Change-Number: 630209
Gerrit-PatchSet: 13
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: JJMC89 <JJMC89.Wikimedia(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged
Xqt has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/786339 )
Change subject: [doc] Update documentation for logging system and user interfaces
......................................................................
[doc] Update documentation for logging system and user interfaces
Change-Id: I6ea61d051071f4ed2357b681e3eaf8ec907a5221
---
M docs/api_ref/pywikibot.rst
M docs/api_ref/pywikibot.userinterfaces.rst
M docs/scripts_ref/scripts.rst
M pywikibot/bot.py
M pywikibot/userinterfaces/__init__.py
M pywikibot/userinterfaces/buffer_interface.py
6 files changed, 68 insertions(+), 37 deletions(-)
Approvals:
jenkins-bot: Verified
Xqt: Looks good to me, approved
diff --git a/docs/api_ref/pywikibot.rst b/docs/api_ref/pywikibot.rst
index 4721eeb..02bd83a 100644
--- a/docs/api_ref/pywikibot.rst
+++ b/docs/api_ref/pywikibot.rst
@@ -3,8 +3,8 @@
.. automodule:: pywikibot
-Subpackages
------------
+Pywikibot Subpackages
+---------------------
.. toctree::
diff --git a/docs/api_ref/pywikibot.userinterfaces.rst b/docs/api_ref/pywikibot.userinterfaces.rst
index 6d0b506..0c05a30 100644
--- a/docs/api_ref/pywikibot.userinterfaces.rst
+++ b/docs/api_ref/pywikibot.userinterfaces.rst
@@ -28,6 +28,11 @@
.. automodule:: pywikibot.userinterfaces.terminal_interface_win32
+buffer\_interface module
+------------------------
+
+.. automodule:: pywikibot.userinterfaces.buffer_interface
+
gui module
----------
diff --git a/docs/scripts_ref/scripts.rst b/docs/scripts_ref/scripts.rst
index d4c262d..0bda098 100644
--- a/docs/scripts_ref/scripts.rst
+++ b/docs/scripts_ref/scripts.rst
@@ -3,8 +3,8 @@
.. automodule:: scripts
-Subpackages
------------
+Scripts Subpackages
+-------------------
.. toctree::
diff --git a/pywikibot/bot.py b/pywikibot/bot.py
index 00f0e5f..b7eb314 100644
--- a/pywikibot/bot.py
+++ b/pywikibot/bot.py
@@ -190,9 +190,6 @@
]
PageLinkType = Union['pywikibot.page.Link', 'pywikibot.page.Page']
-ui = None # type: Optional[pywikibot.userinterfaces._interface_base.ABUIC]
-
-
_GLOBAL_HELP = """
GLOBAL OPTIONS
==============
@@ -270,13 +267,24 @@
"""
+ui = None # type: Optional[pywikibot.userinterfaces._interface_base.ABUIC]
+"""Holds a user interface object defined in
+:mod:`pywikibot.userinterfaces` subpackage.
+"""
+
def set_interface(module_name: str) -> None:
- """Configures any bots to use the given interface module."""
+ """Configures any bots to use the given interface module.
+
+ Search for user interface module in the
+ :mod:`pywikibot.userinterfaces` subdirectory and initialize UI.
+ Calls :func:`init_handlers` to re-initialize if we were already
+ initialized with another UI.
+
+ .. versionadded:: 6.4
+ """
global ui
- # User interface initialization
- # search for user interface module in the 'userinterfaces' subdirectory
ui_module = __import__('pywikibot.userinterfaces.{}_interface'
.format(module_name), fromlist=['UI'])
ui = ui_module.UI()
@@ -284,47 +292,39 @@
atexit.register(ui.flush)
pywikibot.argvu = ui.argvu()
- # re-initialize if we were already initialized with another UI
+ # re-initialize
if _handlers_initialized:
init_handlers()
-# Initialize the handlers and formatters for the logging system.
-#
-# This relies on the global variable 'ui' which is a UserInterface object
-# defined in the 'userinterface' subpackage.
-#
-# The UserInterface object must define its own init_handlers() method
-# which takes the root logger as its only argument, and which adds to that
-# logger whatever handlers and formatters are needed to process output and
-# display it to the user. The default (terminal) interface sends level
-# STDOUT to sys.stdout (as all interfaces should) and sends all other
-# levels to sys.stderr; levels WARNING and above are labeled with the
-# level name.
-#
-# UserInterface objects must also define methods input(), input_choice(),
-# and editText(), all of which are documented in
-# userinterfaces/terminal_interface.py
-
_handlers_initialized = False
def handler_namer(name: str) -> str:
- """Modify the filename of a log file when rotating."""
+ """Modify the filename of a log file when rotating.
+
+ .. versionadded:: 6.5
+ """
path, qualifier = name.rsplit('.', 1)
root, ext = os.path.splitext(path)
return '{}.{}{}'.format(root, qualifier, ext)
def init_handlers() -> None:
- """Initialize logging system for terminal-based bots.
+ """Initialize the handlers and formatters for the logging system.
+ This relies on the global variable :attr:`ui` which is a UI object.
+
+ .. seealso:: :mod:`pywikibot.userinterfaces`
+
+ Calls :func:`writelogheader` after handlers are initialized.
This function must be called before using any input/output methods;
- and must be called again if ui handler is changed..
+ and must be called again if ui handler is changed. Use
+ :func:`set_interface` to set the new interface which initializes it.
- Note: this function is called by any user input and output function,
- so it should normally not need to be called explicitly.
+ .. note:: this function is called by any user input and output
+ function, so it should normally not need to be called explicitly.
All user output is routed through the logging module.
Each type of output is handled by an appropriate handler object.
@@ -343,8 +343,13 @@
- ERROR: user error messages.
- CRITICAL: fatal error messages.
+ .. seealso::
+ * :mod:`pywikibot.logging`
+ * :python:`Python Logging Levels<library/logging.html#logging-levels>`
+
Accordingly, do **not** use print statements in bot code; instead,
- use pywikibot.output function.
+ use :func:`pywikibot.output` function and other functions from
+ :mod:`pywikibot.logging` module.
.. versionchanged:: 6.2
Different logfiles are used if multiple processes of the same
diff --git a/pywikibot/userinterfaces/__init__.py b/pywikibot/userinterfaces/__init__.py
index b57ecdc..fa9afbd 100644
--- a/pywikibot/userinterfaces/__init__.py
+++ b/pywikibot/userinterfaces/__init__.py
@@ -1 +1,16 @@
-"""User interfaces."""
+"""User interfaces Module.
+
+The user interface object must define its own `init_handlers()` method
+which takes the root logger as its only argument, and which adds to that
+logger whatever handlers and formatters are needed to process output and
+display it to the user. The default
+(:mod:`terminal<pywikibot.userinterfaces.terminal_interface_base>`)
+interface sends level :const:`STDOUT` to `sys.stdout` (as all interfaces
+should) and sends all other levels to `sys.stderr`; levels
+:const:`WARNING` and above are labeled with the level name.
+
+UserInterface objects must also define methods `input()`,
+`input_choice()`, `input_list_choice()`, `output()` and `editText()`,
+all of which are documented in the abstract class
+:class:`pywikibot.userinterfaces._interface_base.ABUIC`.
+"""
diff --git a/pywikibot/userinterfaces/buffer_interface.py b/pywikibot/userinterfaces/buffer_interface.py
index b12ba02..3da1975 100644
--- a/pywikibot/userinterfaces/buffer_interface.py
+++ b/pywikibot/userinterfaces/buffer_interface.py
@@ -1,4 +1,7 @@
-"""Non-interactive interface that stores output."""
+"""Non-interactive interface that stores output.
+
+.. versionadded:: 6.4
+"""
#
# (C) Pywikibot team, 2021-2022
#
@@ -15,7 +18,10 @@
class UI(ABUIC):
- """Collects output into an unseen buffer."""
+ """Collects output into an unseen buffer.
+
+ .. versionadded:: 6.4
+ """
def __init__(self) -> None:
"""Initialize the UI."""
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/786339
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I6ea61d051071f4ed2357b681e3eaf8ec907a5221
Gerrit-Change-Number: 786339
Gerrit-PatchSet: 5
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged
jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/785974 )
Change subject: [cleanup] Remove WikimediaSiteTestCase class
......................................................................
[cleanup] Remove WikimediaSiteTestCase class
The wmf flag was never used
Change-Id: I1d8b53748448319dba9dce6ea19addc4d57285bc
---
M tests/aspects.py
1 file changed, 1 insertion(+), 8 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/tests/aspects.py b/tests/aspects.py
index c93da45..06d88aa 100644
--- a/tests/aspects.py
+++ b/tests/aspects.py
@@ -1137,14 +1137,7 @@
dry = True
-class WikimediaSiteTestCase(TestCase):
-
- """Test class uses only WMF sites."""
-
- wmf = True
-
-
-class WikimediaDefaultSiteTestCase(DefaultSiteTestCase, WikimediaSiteTestCase):
+class WikimediaDefaultSiteTestCase(DefaultSiteTestCase):
"""Test class to run against a WMF site, preferring the default site."""
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/785974
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I1d8b53748448319dba9dce6ea19addc4d57285bc
Gerrit-Change-Number: 785974
Gerrit-PatchSet: 1
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged