jenkins-bot submitted this change.

View Change

Approvals: Xqt: Looks good to me, approved jenkins-bot: Verified
[IMPR] logging.py type hints

This removes backports.py import of tools because it causes a circular import
if modules like logging.py attempt to use it.

Bug: T286403
Change-Id: Ia249fb9a266c09cda1cdcea97bce85c5d5cfbbb1
---
M pywikibot/backports.py
M pywikibot/logging.py
2 files changed, 45 insertions(+), 29 deletions(-)

diff --git a/pywikibot/backports.py b/pywikibot/backports.py
index 43abbd4..9ae2e7b 100644
--- a/pywikibot/backports.py
+++ b/pywikibot/backports.py
@@ -4,10 +4,10 @@
#
# Distributed under the terms of the MIT license.
#
+import sys
from typing import Any

-from pywikibot.tools import PYTHON_VERSION
-
+PYTHON_VERSION = sys.version_info[:3]

# functools.cache
if PYTHON_VERSION >= (3, 9):
diff --git a/pywikibot/logging.py b/pywikibot/logging.py
index b91ed5b..31a8726 100644
--- a/pywikibot/logging.py
+++ b/pywikibot/logging.py
@@ -7,26 +7,29 @@
import logging
import os
import sys
+from typing import Any

# logging levels
from logging import CRITICAL, DEBUG, ERROR, INFO, WARNING
-from typing import Optional
+from typing import AnyStr, Optional
+
+from pywikibot.backports import Callable, List


STDOUT = 16
VERBOSE = 18
INPUT = 25

-_init_routines = []
+_init_routines = [] # type: List[Callable[[], Any]]
_inited_routines = set()


-def add_init_routine(routine):
+def add_init_routine(routine: Callable[[], Any]) -> None:
"""Add a routine to be run as soon as possible."""
_init_routines.append(routine)


-def _init():
+def _init() -> None:
"""Init any routines which have not already been called."""
for init_routine in _init_routines:
found = init_routine in _inited_routines # prevent infinite loop
@@ -59,12 +62,12 @@
# string indicating the debugging layer.


-def logoutput(text, decoder=None, newline=True, _level=INFO, _logger='',
- **kwargs):
+def logoutput(text: Any, decoder: Optional[str] = None,
+ newline: bool = True, _level: int = INFO, _logger: str = '',
+ **kwargs: Any) -> None:
"""Format output and send to the logging module.

Helper function used by all the user-output convenience functions.
-
"""
if _logger:
logger = logging.getLogger('pywiki.' + _logger)
@@ -86,23 +89,27 @@
'caller_line': frame.f_lineno,
'newline': ('\n' if newline else '')}

- if decoder:
- text = text.decode(decoder)
+ if isinstance(text, str):
+ decoded_text = text
elif isinstance(text, bytes):
- try:
- text = text.decode('utf-8')
- except UnicodeDecodeError:
- text = text.decode('iso8859-1')
+ 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...)
- text = str(text)
+ decoded_text = str(text)

- logger.log(_level, text, extra=context, **kwargs)
+ logger.log(_level, decoded_text, extra=context, **kwargs)


-def output(text, decoder=None, newline=True, **kwargs):
+def output(text: AnyStr, decoder: Optional[str] = None, newline: bool = True,
+ **kwargs: Any) -> None:
r"""Output a message to the user via the userinterface.

Works like print, but uses the encoding used by the user's console
@@ -126,7 +133,8 @@
logoutput(text, decoder, newline, INFO, **kwargs)


-def stdout(text, decoder=None, newline=True, **kwargs):
+def stdout(text: AnyStr, decoder: Optional[str] = None, newline: bool = True,
+ **kwargs: Any) -> None:
"""Output script results to the user via the userinterface.

The text will be sent to standard output, so that it can be piped to
@@ -143,8 +151,8 @@
logoutput(text, decoder, newline, STDOUT, **kwargs)


-def warning(text: str, decoder: Optional[str] = None,
- newline: bool = True, **kwargs):
+def warning(text: AnyStr, decoder: Optional[str] = None,
+ newline: bool = True, **kwargs: Any) -> None:
"""Output a warning message to the user via the userinterface.

:param text: the message the user wants to display.
@@ -157,7 +165,8 @@
logoutput(text, decoder, newline, WARNING, **kwargs)


-def error(text, decoder=None, newline=True, **kwargs):
+def error(text: AnyStr, 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.
@@ -170,7 +179,8 @@
logoutput(text, decoder, newline, ERROR, **kwargs)


-def log(text, decoder=None, newline=True, **kwargs):
+def log(text: AnyStr, 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.
@@ -183,7 +193,8 @@
logoutput(text, decoder, newline, VERBOSE, **kwargs)


-def critical(text, decoder=None, newline=True, **kwargs):
+def critical(text: AnyStr, 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.
@@ -196,10 +207,12 @@
logoutput(text, decoder, newline, CRITICAL, **kwargs)


-def debug(text, layer, decoder=None, newline=True, **kwargs):
+def debug(text: AnyStr, layer: str, decoder: Optional[str] = None,
+ newline: bool = True, **kwargs: Any) -> None:
"""Output a debug record to the log file.

:param text: the message of the debug record to be logged to the log file.
+ :param layer: logger to record this message upon
: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.
@@ -210,7 +223,8 @@
logoutput(text, decoder, newline, DEBUG, layer, **kwargs)


-def exception(msg=None, decoder=None, newline=True, tb=False, **kwargs):
+def exception(msg: Optional[Exception] = None, decoder: Optional[str] = None,
+ newline: bool = True, tb: bool = False, **kwargs: Any) -> None:
"""Output an error traceback to the user via the userinterface.

Use directly after an 'except' statement::
@@ -229,7 +243,8 @@

This function should only be called from an Exception handler.

- :param msg: If not None,contains the description of the exception occurred.
+ :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.
@@ -238,11 +253,12 @@
:param tb: Set to True in order to output traceback also.
"""
if isinstance(msg, BaseException):
- exc_info = 1
+ exc_info = 1 # type: Any
else:
exc_info = sys.exc_info()
- msg = '{}: {}'.format(repr(exc_info[1]).split('(')[0],
+ msg = '{}: {}'.format(repr(exc_info[1]).split('(')[0], # type: ignore
str(exc_info[1]).strip())
if tb:
kwargs['exc_info'] = exc_info
+ assert msg is not None
logoutput(msg, decoder, newline, ERROR, **kwargs)

To view, visit change 710673. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: Ia249fb9a266c09cda1cdcea97bce85c5d5cfbbb1
Gerrit-Change-Number: 710673
Gerrit-PatchSet: 1
Gerrit-Owner: Damian <atagar1@gmail.com>
Gerrit-Reviewer: Xqt <info@gno.de>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged