jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1043479?usp=email )
Change subject: [cleanup] deprecate logging functions in pywikibot.bot
......................................................................
[cleanup] deprecate logging functions in pywikibot.bot
logging functions were moved from pywikibot.bot module to
pywikibot.logging module somewhere in Pywikibot 2.0. Therefore
deprecate these functions; they should not imported from pywikibot.bot
but either from pywikibot.logging or directly from pywikibot module
like pywikibot.info().
logging functions calls where updated as well as the documentation.
This change also prevents having multiple logging functions entries
in documentation made by Sphinx.
Change-Id: I56674141ac2fc5944d5d9e1044aeac754b87ebd9
---
M pywikibot/bot.py
M pywikibot/logging.py
2 files changed, 183 insertions(+), 129 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/bot.py b/pywikibot/bot.py
index bb732d8..cff70ef 100644
--- a/pywikibot/bot.py
+++ b/pywikibot/bot.py
@@ -1,30 +1,30 @@
-"""
-User-interface related functions for building bots.
+"""User-interface related functions for building bots.
This module supports several different bot classes which could be used in
conjunction. Each bot should subclass at least one of these four classes:
-* :py:obj:`BaseBot`: Basic bot class in case where the site is handled
+* :class:`BaseBot`: Basic bot class in case where the site is handled
differently, like working on multiple sites in parallel. No site
attribute is provided. Instead site of the current page should be used.
This class should normally not be used directly.
-* :py:obj:`SingleSiteBot`: Bot class which should only be run on a
- single site. They usually store site specific content and thus can't
- be easily run when the generator returns a page on another site. It
- has a property ``site`` which can also be changed. If the generator
- returns a page of a different site it'll skip that page.
+* :class:`SingleSiteBot`: Bot class which should only be run on a single
+ site. They usually store site specific content and thus can't be
+ easily run when the generator returns a page on another site. It has a
+ property ``site`` which can also be changed. If the generator returns
+ a page of a different site it'll skip that page.
-* :py:obj:`MultipleSitesBot`: An alias of :py:obj:`BaseBot`. Should not
+* :class:`MultipleSitesBot`: An alias of :class:`BaseBot`. Should not
be used if any other bot class is used.
-* :py:obj:`ConfigParserBot`: Bot class which supports reading options from a
- scripts.ini configuration file. That file consists of sections, led by a
- ``[section]`` header and followed by ``option: value`` or ``option=value``
- entries. The section is the script name without .py suffix. All options
- identified must be predefined in available_options dictionary.
+* :class:`ConfigParserBot`: Bot class which supports reading options
+ from a ``scripts.ini`` configuration file. That file consists of
+ sections, led by a ``[section]`` header and followed by
+ ``option: value`` or ``option=value`` entries. The section is the
+ script name without .py suffix. All options identified must be
+ predefined in available_options dictionary.
-* :py:obj:`Bot`: The previous base class which should be avoided. This
+* :class:`Bot`: The previous base class which should be avoided. This
class is mainly used for bots which work with Wikibase or together
with an image repository.
@@ -34,27 +34,50 @@
``treat`` and ``put_current`` instead of ``userPut``. It by default
subclasses the ``BaseBot`` class.
-With :py:obj:`CurrentPageBot` it's possible to subclass one of the
+With :class:`CurrentPageBot` it's possible to subclass one of the
following classes to filter the pages which are ultimately handled by
-``treat_page``:
+:meth:`CurrentPageBot.treat_page`:
-* :py:obj:`ExistingPageBot`: Only handle pages which do exist.
-* :py:obj:`CreatingPageBot`: Only handle pages which do not exist.
-* :py:obj:`RedirectPageBot`: Only handle pages which are redirect pages.
-* :py:obj:`NoRedirectPageBot`: Only handle pages which are not redirect pages.
-* :py:obj:`FollowRedirectPageBot`: If the generator returns a redirect
- page it'll follow the redirect and instead work on the redirected class.
+* :class:`ExistingPageBot`: Only handle pages which do exist.
+* :class:`CreatingPageBot`: Only handle pages which do not exist.
+* :class:`FollowRedirectPageBot`: If the generator returns a redirect
+ page it'll follow the redirect and instead work on the redirected
+ class.
-It is possible to combine filters by subclassing multiple of them. They are
-new-style classes so when a class is first subclassing
-:py:obj:`ExistingPageBot` and then :py:obj:`FollowRedirectPageBot` it
+It is possible to combine filters by subclassing multiple of them. They
+are new-style classes so when a class is first subclassing
+:class:`ExistingPageBot` and then :class:`FollowRedirectPageBot` it
will also work on pages which do not exist when a redirect pointed to
that. If the order is inversed it'll first follow them and then check
whether they exist.
-Additionally there is the :py:obj:`AutomaticTWSummaryBot` which subclasses
-:py:obj:`CurrentPageBot` and automatically defines the summary when
-``put_current`` is used.
+Additionally there is the :class:`AutomaticTWSummaryBot` which
+subclasses :class:`CurrentPageBot` and automatically defines the summary
+when :meth:`put_current` is used.
+
+.. deprecated:: 7.2
+ The bot classes :class:`RedirectPageBot` and
+ :class:`NoRedirectPageBot` are deprecated. Use
+ :attr:`use_redirects<BaseBot.use_redirects>` attribute instead.
+
+.. deprecated:: 9.2
+ The functions
+ :func:`critical()<pywikibot.logging.critical>`
+ :func:`debug()<pywikibot.logging.debug>`
+ :func:`error()<pywikibot.logging.error>`
+ :func:`exception()<pywikibot.logging.exception>`
+ :func:`log()<pywikibot.logging.log>`
+ :func:`output()<pywikibot.logging.output>`
+ :func:`stdout()<pywikibot.logging.stdout>` and
+ :func:`warning()<pywikibot.logging.warning>`
+ as well as the constants
+ ``CRITICAL``, ``DEBUG``, ``ERROR``, ``INFO``,
+ :attr:`INPUT<pywikibot.logging.INPUT>`
+ :attr:`STDOUT<pywikibot.logging.STDOUT>`
+ :attr:`VERBOSE<pywikibot.logging.VERBOSE>`
+ and ``WARNING`` imported from :mod:`logging` module are deprecated
+ within this module. Import them directly. These functions can also be
+ used as :mod:`pywikibot` members.
"""
#
# (C) Pywikibot team, 2008-2024
@@ -65,9 +88,7 @@
__all__ = (
- 'CRITICAL', 'ERROR', 'INFO', 'WARNING', 'DEBUG', 'INPUT', 'STDOUT',
- 'VERBOSE', 'critical', 'debug', 'error', 'exception', 'log', 'warning',
- 'output', 'stdout', 'LoggingFormatter',
+ 'LoggingFormatter',
'set_interface', 'init_handlers', 'writelogheader',
'input', 'input_choice', 'input_yn', 'input_list_choice', 'ui',
'Option', 'StandardOption', 'NestedOption', 'IntegerOption',
@@ -111,6 +132,7 @@
from warnings import warn
import pywikibot
+import pywikibot.logging as pwb_logging
from pywikibot import config, daemonize, i18n, version
from pywikibot.backports import Callable, Dict, Iterable, Sequence
from pywikibot.bot_choice import (
@@ -147,7 +169,8 @@
VersionParseError,
WikiBaseError,
)
-from pywikibot.logging import (
+# the constants are
+from pywikibot.logging import ( # noqa: F401
CRITICAL,
DEBUG,
ERROR,
@@ -157,17 +180,15 @@
VERBOSE,
WARNING,
add_init_routine,
- critical,
- debug,
- error,
- exception,
- log,
- output,
- stdout,
- warning,
)
+from pywikibot.logging import debug as _debug
+from pywikibot.logging import error as _error
+from pywikibot.logging import exception as _exception
+from pywikibot.logging import log as _log
+from pywikibot.logging import stdout as _stdout
+from pywikibot.logging import warning as _warning
from pywikibot.throttle import Throttle
-from pywikibot.tools import issue_deprecation_warning, strtobool
+from pywikibot.tools import issue_deprecation_warning, redirect_func, strtobool
from pywikibot.tools._logging import LoggingFormatter
@@ -450,29 +471,28 @@
.. versionchanged:: 9.0
ignore milliseconds with timestamp.
"""
- log('')
- log(f'=== Pywikibot framework v{pywikibot.__version__} -- Logging header'
- ' ===')
+ _log(f'\n=== Pywikibot framework v{pywikibot.__version__} --'
+ ' Logging header ===')
# script call
- log(f'COMMAND: {sys.argv}')
+ _log(f'COMMAND: {sys.argv}')
# script call time stamp
- log(f'DATE: {pywikibot.Timestamp.nowutc()} UTC')
+ _log(f'DATE: {pywikibot.Timestamp.nowutc()} UTC')
# new framework release/revision? (handle_args needs to be called first)
try:
- log('VERSION: {}'.format(
- version.getversion(online=config.log_pywiki_repo_version).strip()))
+ _log('VERSION: {}'.format(version.getversion(
+ online=config.log_pywiki_repo_version).strip()))
except VersionParseError:
- exception()
+ _exception()
# system
if hasattr(os, 'uname'):
- log(f'SYSTEM: {os.uname()}')
+ _log(f'SYSTEM: {os.uname()}')
# config file dir
- log(f'CONFIG FILE DIR: {pywikibot.config.base_dir}')
+ _log(f'CONFIG FILE DIR: {pywikibot.config.base_dir}')
# These are the main dependencies of pywikibot.
check_package_list = [
@@ -484,7 +504,7 @@
if config.verbose_output:
check_package_list += sys.modules
- log('PACKAGES:')
+ _log('PACKAGES:')
packages = version.package_versions(check_package_list)
for name in sorted(packages.keys()):
info = packages[name]
@@ -492,12 +512,12 @@
f"[{info.get('type', 'path unknown')}]")
info.setdefault('ver', '??')
if 'err' in info:
- log(' {name}: {err}'.format_map(info))
+ _log(' {name}: {err}'.format_map(info))
else:
- log(' {name} ({path}) = {ver}'.format_map(info))
+ _log(' {name} ({path}) = {ver}'.format_map(info))
# imported modules
- log('MODULES:')
+ _log('MODULES:')
for module in sys.modules.copy().values():
filename = version.get_module_filename(module)
if not filename:
@@ -505,12 +525,12 @@
mtime = version.get_module_mtime(module).isoformat(sep=' ',
timespec='seconds')
- log(f' {mtime} {filename}')
+ _log(f' {mtime} {filename}')
if config.log_pywiki_repo_version:
- log(f'PYWIKI REPO VERSION: {version.getversion_onlinerepo()}')
+ _log(f'PYWIKI REPO VERSION: {version.getversion_onlinerepo()}')
- log('=' * 57)
+ _log('=' * 57)
add_init_routine(init_handlers)
@@ -831,12 +851,12 @@
try:
pywikibot.Site()
except (UnknownFamilyError, UnknownSiteError):
- pywikibot.exception(exc_info=False)
+ _exception(exc_info=False)
sys.exit(1)
if calledModuleName() == 'wrapper':
pywikibot._sites.clear()
- debug('handle_args() completed.')
+ _debug('handle_args() completed.')
return non_global_args
@@ -863,8 +883,8 @@
module = import_module(module_name)
except ModuleNotFoundError:
if module_name:
- pywikibot.stdout('Sorry, no help available for ' + module_name)
- pywikibot.log('show_help:', exc_info=True)
+ _stdout('Sorry, no help available for ' + module_name)
+ _log('show_help:', exc_info=True)
else:
assert module.__doc__ is not None
help_text = re.sub(r'^\.\. version(added|changed)::.+', '',
@@ -872,12 +892,12 @@
if hasattr(module, 'docuReplacements'):
for key, value in module.docuReplacements.items():
help_text = help_text.replace(key, value.strip())
- pywikibot.stdout(help_text)
+ _stdout(help_text)
if show_global or module_name == 'pwb':
- pywikibot.stdout(_GLOBAL_HELP.format(module_name))
+ _stdout(_GLOBAL_HELP.format(module_name))
else:
- pywikibot.stdout(_GLOBAL_HELP_NOTE)
+ _stdout(_GLOBAL_HELP_NOTE)
def suggest_help(missing_parameters: Sequence[str] | None = None,
@@ -925,7 +945,7 @@
messages.append(additional_text.strip())
if messages:
messages.append('Use -help for further information.')
- error('\n'.join(messages))
+ _error('\n'.join(messages))
return True
return False
@@ -1056,7 +1076,7 @@
self.opt.update((opt, options[opt])
for opt in received_options & valid_options)
for opt in received_options - valid_options:
- pywikibot.warning(f'{opt} is not a valid option. It was ignored.')
+ _warning(f'{opt} is not a valid option. It was ignored.')
class BaseBot(OptionHandler):
@@ -1204,10 +1224,11 @@
self._current_page = page
msg = f'Working on {page.title()!r}'
if config.colorized_output:
- log(msg)
- stdout(f'\n\n>>> <<lightpurple>>{page.title()}<<default>> <<<')
+ _log(msg)
+ _stdout(
+ f'\n\n>>> <<lightpurple>>{page.title()}<<default>> <<<')
else:
- stdout(msg)
+ _stdout(msg)
def user_confirm(self, question: str) -> bool:
"""Obtain user response if bot option 'always' not enabled."""
@@ -1316,12 +1337,11 @@
elif isinstance(e, LockedPageError):
pywikibot.info(f'Skipping {page.title()} (locked page)')
else:
- pywikibot.error('Skipping {} because of a save related '
- 'error: {}'.format(page.title(), e))
+ _error(f'Skipping {page} because of a save related error: {e}')
except ServerError as e:
if not ignore_server_errors:
raise
- pywikibot.error(
+ _error(
f'Server Error while processing {page.title()}: {e}')
else:
return True
@@ -1385,7 +1405,7 @@
pywikibot.info('successfully.')
else:
pywikibot.info('by exception:\n')
- pywikibot.exception(exc_info=False)
+ _exception(exc_info=False)
def init_page(self, item: Any) -> pywikibot.page.BasePage:
"""Initialize a generator item before treating.
@@ -1416,7 +1436,7 @@
"""
if isinstance(self.use_redirects, bool) \
and page.isRedirectPage() is not self.use_redirects:
- pywikibot.warning(
+ _warning(
'Page {page} on {page.site} is skipped because it is {not_}'
'a redirect'
.format(page=page, not_='not ' if self.use_redirects else ''))
@@ -1424,7 +1444,7 @@
if isinstance(self.use_disambigs, bool) \
and page.isDisambig() is not self.use_disambigs:
- pywikibot.warning(
+ _warning(
'Page {page} on {page.site} is skipped because it is {not_}'
'a disambig'
.format(page=page, not_='not ' if self.use_disambigs else ''))
@@ -1535,7 +1555,7 @@
if not isinstance(self.generator, Generator):
gen_type = type(self.generator).__name__
- pywikibot.debug(f'wrapping {gen_type} type to a Generator type')
+ _debug(f'wrapping {gen_type} type to a Generator type')
try:
# to provide generator.close() method
self.generator = (item for item in self.generator)
@@ -1598,9 +1618,9 @@
def site(self) -> BaseSite | None:
"""Get the current site."""
if not self._site:
- warning('Bot.site was not set before being retrieved.')
+ _warning('Bot.site was not set before being retrieved.')
self.site = pywikibot.Site()
- warning(f'Using the default site: {self.site}')
+ _warning(f'Using the default site: {self.site}')
assert self._site is not None
return self._site
@@ -1617,14 +1637,16 @@
return
if site not in self._sites:
- log(f'LOADING SITE {site} VERSION: {site.mw_version}')
+ _log(f'LOADING SITE {site} VERSION: {site.mw_version}')
self._sites.add(site)
if len(self._sites) == 2:
- log(f'{self.__class__.__name__} uses multiple sites')
+ _log(f'{self.__class__.__name__} uses multiple sites')
+
if self._site and self._site != site:
- log('{}: changing site from {} to {}'
- .format(self.__class__.__name__, self._site, site))
+ _log(f'{type(self).__name__}: changing site from {self._site} '
+ f'to {site}')
+
self._site = site
def run(self) -> None:
@@ -1637,12 +1659,13 @@
# set self.site in __init__, and use page.site in treat().
self._auto_update_site = not self._site
if not self._auto_update_site:
- warning('{}.__init__ set the Bot.site property; this is only '
- 'needed when the Bot accesses many sites.'
- .format(self.__class__.__name__))
+ _warning(
+ f'{type(self).__name__}.__init__ set the Bot.site property;'
+ ' this is only needed when the Bot accesses many sites.'
+ )
else:
- log('Bot is managing the {}.site property in run()'
- .format(self.__class__.__name__))
+ _log(f'Bot is managing the {type(self).__name__}.site property in'
+ ' run()')
super().run()
def init_page(self, item: Any) -> pywikibot.page.BasePage:
@@ -1698,10 +1721,9 @@
# setting it the first time. The appropriate variant is not to use
# self.site at all or define it once and never change it again
if self._site == value:
- pywikibot.warning('Defined site without changing it.')
+ _warning('Defined site without changing it.')
else:
- pywikibot.warning(
- f'Changed the site from "{self._site}" to "{value}"')
+ _warning(f'Changed the site from "{self._site}" to "{value}"')
self._site = value
def init_page(self, item: Any) -> pywikibot.page.BasePage:
@@ -1714,10 +1736,9 @@
def skip_page(self, page: pywikibot.page.BasePage) -> bool:
"""Skip page if it is not on the defined site."""
if page.site != self.site:
- pywikibot.warning(
- fill('Skipped {page} due to: '
- 'The bot is on site "{site}" but the page on '
- 'site "{page.site}"'.format(site=self.site, page=page)))
+ _warning(fill(f'Skipped {page} due to: '
+ f'The bot is on site "{self.site}" but the page on '
+ f'site "{page.site}"'))
return True
return super().skip_page(page)
@@ -1782,8 +1803,7 @@
method = getattr(conf, 'get' + value_type, default)
options[option] = method(section, option)
for opt in set(conf.options(section)) - set(options):
- pywikibot.warning(
- f'"{opt}" is not a valid option. It was ignored.')
+ _warning(f'"{opt}" is not a valid option. It was ignored.')
options.update(kwargs)
else:
options = kwargs
@@ -1884,7 +1904,7 @@
summary = i18n.twtranslate(self.current_page.site,
self.summary_key,
self.summary_parameters)
- pywikibot.log(f'Use automatic summary message "{summary}"')
+ _log(f'Use automatic summary message "{summary}"')
kwargs['summary'] = summary
super().put_current(*args, **kwargs)
@@ -1901,8 +1921,7 @@
calls are made
"""
if not page.exists():
- pywikibot.warning('Page {page} does not exist on {page.site}.'
- .format(page=page))
+ _warning(f'Page {page} does not exist on {page.site}.')
return True
return super().skip_page(page)
@@ -1925,8 +1944,7 @@
def skip_page(self, page: pywikibot.page.BasePage) -> bool:
"""Treat page if doesn't exist."""
if page.exists():
- pywikibot.warning('Page {page} does already exist on {page.site}.'
- .format(page=page))
+ _warning(f'Page {page} does already exist on {page.site}.')
return True
return super().skip_page(page)
@@ -1950,9 +1968,8 @@
def skip_page(self, page: pywikibot.page.BasePage) -> bool:
"""Treat only redirect pages and handle IsNotRedirectPageError."""
if not page.isRedirectPage():
- pywikibot.warning(
- 'Page {page} on {page.site} is skipped because it is '
- 'not a redirect'.format(page=page))
+ _warning(f'Page {page} on {page.site} is skipped because it is'
+ ' not a redirect')
return True
return super().skip_page(page)
@@ -1976,9 +1993,8 @@
def skip_page(self, page: pywikibot.page.BasePage) -> bool:
"""Treat only non-redirect pages and handle IsRedirectPageError."""
if page.isRedirectPage():
- pywikibot.warning(
- 'Page {page} on {page.site} is skipped because it is '
- 'a redirect'.format(page=page))
+ _warning(f'Page {page} on {page.site} is skipped because it is'
+ ' a redirect')
return True
return super().skip_page(page)
@@ -2151,7 +2167,7 @@
claim: pywikibot.page.Claim,
exists_arg: Container = '',
source: BaseSite | None = None,
- logger_callback: Callable[[str], Any] = log,
+ logger_callback: Callable[[str], Any] = pwb_logging.log,
**kwargs: Any) -> bool:
"""
Decorator of :py:obj:`user_add_claim`.
@@ -2182,13 +2198,14 @@
claims = item.get().get('claims')
assert claims is not None
- for existing in claims.get(claim.getID(), []):
+ claim_id = claim.getID()
+ for existing in claims.get(claim_id, []):
# If claim with same property already exists...
if 'p' not in exists_arg:
logger_callback(
- 'Skipping {} because claim with same property '
- 'already exists'.format(claim.getID()))
- log('Use -exists:p option to override this behavior')
+ f'Skipping {claim_id} because claim with same property'
+ ' already exists')
+ _log('Use -exists:p option to override this behavior')
break
if not existing.target_equals(claim.getTarget()):
@@ -2200,24 +2217,27 @@
# 'exists' argument overrides it.
if 't' not in exists_arg:
logger_callback(
- 'Skipping {} because claim with same target already exists'
- .format(claim.getID()))
- log("Append 't' to -exists argument to override this behavior")
+ f'Skipping {claim_id} because claim with same target'
+ ' already exists')
+ _log("Append 't' to -exists argument to override this "
+ 'behavior')
break
if 'q' not in exists_arg and not existing.qualifiers:
logger_callback(
- 'Skipping {} because claim without qualifiers already '
- 'exists'.format(claim.getID()))
- log("Append 'q' to -exists argument to override this behavior")
+ f'Skipping {claim_id} because claim without qualifiers'
+ ' already exists')
+ _log("Append 'q' to -exists argument to override this "
+ 'behavior')
break
if ('s' not in exists_arg or not sourceclaim) \
and not existing.sources:
logger_callback(
- 'Skipping {} because claim without source already exists'
- .format(claim.getID()))
- log("Append 's' to -exists argument to override this behavior")
+ f'Skipping {claim_id} because claim without source already'
+ ' exists')
+ _log("Append 's' to -exists argument to override this "
+ 'behavior')
break
# FIXME: the user may provide a better source, but we only
@@ -2228,9 +2248,10 @@
for snak in ref[sourceclaim.getID()])
for ref in existing.sources)):
logger_callback(
- 'Skipping {} because claim with the same source already '
- 'exists'.format(claim.getID()))
- log("Append 's' to -exists argument to override this behavior")
+ f'Skipping {claim_id} because claim with the same source'
+ ' already exists')
+ _log("Append 's' to -exists argument to override this "
+ 'behavior')
break
else:
return self.user_add_claim(item, claim, source, **kwargs)
@@ -2309,8 +2330,8 @@
except NoPageError:
item = None
if self.use_from_page is False:
- pywikibot.error('{} is not in the item namespace but '
- 'must be an item.'.format(page))
+ _error(f'{page} is not in the item namespace but must'
+ ' be an item.')
return
assert not (page is None and item is None)
@@ -2338,6 +2359,31 @@
set_interface(config.userinterface)
+critical = redirect_func(pwb_logging.critical,
+ target_module='pywikibot',
+ since='9.2.0')
+debug = redirect_func(_debug,
+ target_module='pywikibot',
+ since='9.2.0')
+error = redirect_func(_error,
+ target_module='pywikibot',
+ since='9.2.0')
+exception = redirect_func(_exception,
+ target_module='pywikibot',
+ since='9.2.0')
+log = redirect_func(_log,
+ target_module='pywikibot',
+ since='9.2.0')
+output = redirect_func(pwb_logging.output,
+ target_module='pywikibot',
+ since='9.2.0')
+stdout = redirect_func(_stdout,
+ target_module='pywikibot',
+ since='9.2.0')
+warning = redirect_func(_warning,
+ target_module='pywikibot',
+ since='9.2.0')
+
# NOTE: (T286348)
# Do not use ModuleDeprecationWrapper with this module.
# pywikibot.bot.ui would be wrapped through the ModuleDeprecationWrapper
diff --git a/pywikibot/logging.py b/pywikibot/logging.py
index 72a0034..6965fd6 100644
--- a/pywikibot/logging.py
+++ b/pywikibot/logging.py
@@ -20,12 +20,20 @@
argument, which is a string indicating the debugging layer.
"""
#
-# (C) Pywikibot team, 2010-2023
+# (C) Pywikibot team, 2010-2024
#
# Distributed under the terms of the MIT license.
#
from __future__ import annotations
+__all__ = (
+ 'CRITICAL', 'DEBUG', 'ERROR', 'INFO', 'WARNING', 'STDOUT', 'VERBOSE',
+ 'INPUT',
+ 'add_init_routine',
+ 'logoutput', 'info', 'output', 'stdout', 'warning', 'error', 'log',
+ 'critical', 'debug', 'exception',
+)
+
import logging
import os
import sys
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1043479?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I56674141ac2fc5944d5d9e1044aeac754b87ebd9
Gerrit-Change-Number: 1043479
Gerrit-PatchSet: 8
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot
jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1043069?usp=email )
Change subject: [doc] update some :math: roles in _wbtypes.py
......................................................................
[doc] update some :math: roles in _wbtypes.py
Change-Id: I9c6c1b05e0491ff633bab52b7f8837be5045df67
---
M pywikibot/_wbtypes.py
1 file changed, 25 insertions(+), 16 deletions(-)
Approvals:
jenkins-bot: Verified
Xqt: Looks good to me, approved
diff --git a/pywikibot/_wbtypes.py b/pywikibot/_wbtypes.py
index 868b7e6..cd24060 100644
--- a/pywikibot/_wbtypes.py
+++ b/pywikibot/_wbtypes.py
@@ -188,32 +188,34 @@
@property
def precision(self) -> float | None:
- """
- Return the precision of the geo coordinate.
+ """Return the precision of the geo coordinate.
The precision is calculated if the Coordinate does not have a
precision, and self._dim is set.
When no precision and no self._dim exists, None is returned.
- The biggest error (in degrees) will be given by the longitudinal error;
- the same error in meters becomes larger (in degrees) further up north.
- We can thus ignore the latitudinal error.
+ The biggest error (in degrees) will be given by the longitudinal
+ error; the same error in meters becomes larger (in degrees)
+ further up north. We can thus ignore the latitudinal error.
The longitudinal can be derived as follows:
In small angle approximation (and thus in radians):
- M{Δλ ≈ Δpos / r_φ}, where r_φ is the radius of earth at the given
- latitude.
- Δλ is the error in longitude.
+ :math:`M{Δλ ≈ Δpos / r_φ}`, where :math:`r_φ` is the radius of
+ earth at the given latitude. :math:`Δλ` is the error in
+ longitude.
- M{r_φ = r cos φ}, where r is the radius of earth, φ the latitude
+ :math:`M{r_φ = r cos(φ)}`, where :math:`r` is the radius of
+ earth, :math:`φ` the latitude
- Therefore::
+ Therefore:
- precision = math.degrees(
- self._dim/(radius*math.cos(math.radians(self.lat))))
+ .. code-block:: python
+
+ precision = math.degrees(
+ self._dim / (radius * math.cos(math.radians(self.lat))))
"""
if self._dim is None and self._precision is None:
return None
@@ -236,11 +238,18 @@
is thrown.
Carrying on from the earlier derivation of precision, since
- precision = math.degrees(dim/(radius*math.cos(math.radians(self.lat))))
- we get::
- dim = math.radians(
- precision)*radius*math.cos(math.radians(self.lat))
+ .. code-block::
+
+ precision = math.degrees(
+ dim / (radius * math.cos(math.radians(self.lat))))
+
+ we get:
+
+ .. code-block:: python
+
+ dim = math.radians(
+ precision) * radius * math.cos(math.radians(self.lat))
But this is not valid, since it returns a float value for dim which is
an integer. We must round it off to the nearest integer.
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1043069?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I9c6c1b05e0491ff633bab52b7f8837be5045df67
Gerrit-Change-Number: 1043069
Gerrit-PatchSet: 1
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot
jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1043068?usp=email )
Change subject: [doc] prevent multiple entries in Sphinx documentation
......................................................................
[doc] prevent multiple entries in Sphinx documentation
Some classes and functions of i18n, logging, page and time modules are
imported in pywikibot and can also be used as pywikibot members. Remove
the documentation from pywikibot and add a reference to bot module for
them.
Change-Id: I391e057eaf368b3a01e6c7df96f2ae3dd95e4e49
---
M docs/api_ref/bot.rst
M docs/api_ref/date_time.rst
M docs/api_ref/i18n.rst
M docs/api_ref/logging.rst
M docs/api_ref/pywikibot.page.rst
M docs/api_ref/pywikibot.rst
6 files changed, 122 insertions(+), 9 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/docs/api_ref/bot.rst b/docs/api_ref/bot.rst
index 2e17aa9..ce8117d 100644
--- a/docs/api_ref/bot.rst
+++ b/docs/api_ref/bot.rst
@@ -7,6 +7,7 @@
:member-order: bysource
.. admonition:: Imports in :mod:`pywikibot` module
+ :class: note
The following classes and functions are inported in :mod:`pywikibot`
module and can also be used as :mod:`pywikibot` members:
diff --git a/docs/api_ref/date_time.rst b/docs/api_ref/date_time.rst
index 7741b6e..f6c65d8 100644
--- a/docs/api_ref/date_time.rst
+++ b/docs/api_ref/date_time.rst
@@ -3,3 +3,11 @@
******************************************
.. automodule:: pywikibot.time
+
+ .. admonition:: Imports in :mod:`pywikibot` module
+ :class: note
+
+ The following class is imported in :mod:`time<pywikibot.time>` module but
+ can also be used as :mod:`pywikibot` members:
+
+ - :class:`pywikibot.Timestamp<pywikibot.time.Timestamp>`
diff --git a/docs/api_ref/i18n.rst b/docs/api_ref/i18n.rst
index 9b41287..f682e73 100644
--- a/docs/api_ref/i18n.rst
+++ b/docs/api_ref/i18n.rst
@@ -3,4 +3,12 @@
****************************
.. automodule:: i18n
- :synopsis: Various i18n functions
\ No newline at end of file
+ :synopsis: Various i18n functions
+
+ .. admonition:: Imports in :mod:`pywikibot` module
+ :class: note
+
+ The following function is inported in :mod:`pywikibot` module but can also
+ be used as :mod:`pywikibot` members:
+
+ - :class:`pywikibot.translate()<i18n.translate>`
diff --git a/docs/api_ref/logging.rst b/docs/api_ref/logging.rst
index 842c542..1266f2e 100644
--- a/docs/api_ref/logging.rst
+++ b/docs/api_ref/logging.rst
@@ -7,3 +7,19 @@
.. automodule:: pywikibot.logging
:member-order: bysource
+
+ .. admonition:: Imports in :mod:`pywikibot` module
+ :class: note
+
+ The following functions are inported in :mod:`pywikibot` module and can
+ also be used as :mod:`pywikibot` members:
+
+ - :func:`pywikibot.critical()<pywikibot.logging.critical>`
+ - :func:`pywikibot.debug()<pywikibot.logging.debug>`
+ - :func:`pywikibot.error()<pywikibot.logging.error>`
+ - :func:`pywikibot.exception()<pywikibot.logging.exception>`
+ - :func:`pywikibot.info()<pywikibot.logging.info>`
+ - :func:`pywikibot.log()<pywikibot.logging.log>`
+ - :func:`pywikibot.output()<pywikibot.logging.output>`
+ - :func:`pywikibot.stdout()<pywikibot.logging.stdout>`
+ - :func:`pywikibot.warning()<pywikibot.logging.warning>`
diff --git a/docs/api_ref/pywikibot.page.rst b/docs/api_ref/pywikibot.page.rst
index f3712ad..7d38815 100644
--- a/docs/api_ref/pywikibot.page.rst
+++ b/docs/api_ref/pywikibot.page.rst
@@ -5,6 +5,27 @@
.. automodule:: page
:synopsis: Interface of various types of MediaWiki pages
+ .. admonition:: Imports in :mod:`pywikibot` module
+ :class: note
+
+ The following classes and function are inported in :mod:`pywikibot` module
+ and can also be used as :mod:`pywikibot` members:
+
+ - :class:`pywikibot.Category<page.Category>`
+ - :class:`pywikibot.Claim<page.Claim>`
+ - :class:`pywikibot.FilePage<page.FilePage>`
+ - :class:`pywikibot.ItemPage<page.ItemPage>`
+ - :class:`pywikibot.LexemeForm<page.LexemeForm>`
+ - :class:`pywikibot.LexemePage<page.LexemePage>`
+ - :class:`pywikibot.LexemeSense<page.LexemeSense>`
+ - :class:`pywikibot.Link<page.Link>`
+ - :class:`pywikibot.Page<page.Page>`
+ - :class:`pywikibot.PropertyPage<page.PropertyPage>`
+ - :class:`pywikibot.SiteLink<page.SiteLink>`
+ - :class:`pywikibot.User<page.User>`
+ - :func:`pywikibot.html2unicode()<page.html2unicode>`
+
+
:mod:`page.\_collections` Wikibase Entity Structures
====================================================
diff --git a/docs/api_ref/pywikibot.rst b/docs/api_ref/pywikibot.rst
index b3e6b92..804cd7e 100644
--- a/docs/api_ref/pywikibot.rst
+++ b/docs/api_ref/pywikibot.rst
@@ -3,10 +3,17 @@
***********************************************
.. automodule:: pywikibot
- :exclude-members: Bot, CurrentPageBot, WikidataBot, calledModuleName,
- handle_args, input, input_choice, input_yn, show_help
+ :exclude-members:
+ Bot, CurrentPageBot, WikidataBot, calledModuleName, handle_args, input,
+ input_choice, input_yn, show_help,
+ translate,
+ critical, debug, error, exception, info, log, output, stdout, warning,
+ Category, Claim, FilePage, ItemPage, LexemeForm, LexemePage, LexemeSense,
+ Link, MediaInfo, Page, PropertyPage, SiteLink, User, html2unicode,
+ Timestamp
.. admonition:: Imports from :mod:`bot` module
+ :class: tip
The following classes and functions are inported from :mod:`bot` module
but can also be used as :mod:`pywikibot` members:
@@ -14,9 +21,61 @@
- :class:`pywikibot.Bot<bot.Bot>`
- :class:`pywikibot.CurrentPageBot<bot.CurrentPageBot>`
- :class:`pywikibot.WikidataBot<bot.WikidataBot>`
- - :func:`pywikibot.calledModuleName<bot.calledModuleName>`
- - :func:`pywikibot.handle_args<bot.handle_args>`
- - :func:`pywikibot.input<bot.input>`
- - :func:`pywikibot.input_choice<bot.input_choice>`
- - :func:`pywikibot.input_yn<bot.input_yn>`
- - :func:`pywikibot.show_help<bot.show_help>`
+ - :func:`pywikibot.calledModuleName()<bot.calledModuleName>`
+ - :func:`pywikibot.handle_args()<bot.handle_args>`
+ - :func:`pywikibot.input()<bot.input>`
+ - :func:`pywikibot.input_choice()<bot.input_choice>`
+ - :func:`pywikibot.input_yn()<bot.input_yn>`
+ - :func:`pywikibot.show_help()<bot.show_help>`
+
+ .. admonition:: Imports from :mod:`i18n` module
+ :class: tip
+
+ The following function is inported from :mod:`i18n` module but can also be
+ used as :mod:`pywikibot` members:
+
+ - :class:`pywikibot.translate()<i18n.translate>`
+
+ .. admonition:: Imports from :mod:`logging` module
+ :class: tip
+
+ The following functions are inported from :mod:`logging` module but can
+ also be used as :mod:`pywikibot` members:
+
+ - :func:`pywikibot.critical()<logging.critical>`
+ - :func:`pywikibot.debug()<logging.debug>`
+ - :func:`pywikibot.error()<logging.error>`
+ - :func:`pywikibot.exception()<logging.exception>`
+ - :func:`pywikibot.info()<logging.info>`
+ - :func:`pywikibot.log()<logging.log>`
+ - :func:`pywikibot.output()<logging.output>`
+ - :func:`pywikibot.stdout()<logging.stdout>`
+ - :func:`pywikibot.warning()<logging.warning>`
+
+ .. admonition:: Imports from :mod:`page` module
+ :class: tip
+
+ The following classes and function are inported from :mod:`page` module
+ but can also be used as :mod:`pywikibot` members:
+
+ - :class:`pywikibot.Category<page.Category>`
+ - :class:`pywikibot.Claim<page.Claim>`
+ - :class:`pywikibot.FilePage<page.FilePage>`
+ - :class:`pywikibot.ItemPage<page.ItemPage>`
+ - :class:`pywikibot.LexemeForm<page.LexemeForm>`
+ - :class:`pywikibot.LexemePage<page.LexemePage>`
+ - :class:`pywikibot.LexemeSense<page.LexemeSense>`
+ - :class:`pywikibot.Link<page.Link>`
+ - :class:`pywikibot.Page<page.Page>`
+ - :class:`pywikibot.PropertyPage<page.PropertyPage>`
+ - :class:`pywikibot.SiteLink<page.SiteLink>`
+ - :class:`pywikibot.User<page.User>`
+ - :func:`pywikibot.html2unicode()<page.html2unicode>`
+
+ .. admonition:: Imports from :mod:`time<pywikibot.time>` module
+ :class: tip
+
+ The following class is inported from :mod:`time<pywikibot.time>` module
+ but can also be used as :mod:`pywikibot` members:
+
+ - :class:`pywikibot.Timestamp<time.Timestamp>`
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1043068?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I391e057eaf368b3a01e6c7df96f2ae3dd95e4e49
Gerrit-Change-Number: 1043068
Gerrit-PatchSet: 1
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot
jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1042937?usp=email )
Change subject: [doc] prevent multiple entries in Sphinx documentation
......................................................................
[doc] prevent multiple entries in Sphinx documentation
Some classes and functions of bot module are imported in pywikibot and
can also be used as pywikibot members. Remove the documentation from
pywikibot and add a reference to bot module for them.
Change-Id: Ic9ac9604023828017e15a7854ef71ebecc29091c
---
M docs/api_ref/bot.rst
M docs/api_ref/pywikibot.rst
2 files changed, 32 insertions(+), 0 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/docs/api_ref/bot.rst b/docs/api_ref/bot.rst
index 640902f..2e17aa9 100644
--- a/docs/api_ref/bot.rst
+++ b/docs/api_ref/bot.rst
@@ -6,6 +6,21 @@
:synopsis: User-interface related functions for building bots
:member-order: bysource
+ .. admonition:: Imports in :mod:`pywikibot` module
+
+ The following classes and functions are inported in :mod:`pywikibot`
+ module and can also be used as :mod:`pywikibot` members:
+
+ - :class:`pywikibot.Bot<bot.Bot>`
+ - :class:`pywikibot.CurrentPageBot<bot.CurrentPageBot>`
+ - :class:`pywikibot.WikidataBot<bot.WikidataBot>`
+ - :func:`pywikibot.calledModuleName<bot.calledModuleName>`
+ - :func:`pywikibot.handle_args<bot.handle_args>`
+ - :func:`pywikibot.input<bot.input>`
+ - :func:`pywikibot.input_choice<bot.input_choice>`
+ - :func:`pywikibot.input_yn<bot.input_yn>`
+ - :func:`pywikibot.show_help<bot.show_help>`
+
.. autoclass:: BaseBot
.. attribute:: generator
diff --git a/docs/api_ref/pywikibot.rst b/docs/api_ref/pywikibot.rst
index 3e87817..b3e6b92 100644
--- a/docs/api_ref/pywikibot.rst
+++ b/docs/api_ref/pywikibot.rst
@@ -3,3 +3,20 @@
***********************************************
.. automodule:: pywikibot
+ :exclude-members: Bot, CurrentPageBot, WikidataBot, calledModuleName,
+ handle_args, input, input_choice, input_yn, show_help
+
+ .. admonition:: Imports from :mod:`bot` module
+
+ The following classes and functions are inported from :mod:`bot` module
+ but can also be used as :mod:`pywikibot` members:
+
+ - :class:`pywikibot.Bot<bot.Bot>`
+ - :class:`pywikibot.CurrentPageBot<bot.CurrentPageBot>`
+ - :class:`pywikibot.WikidataBot<bot.WikidataBot>`
+ - :func:`pywikibot.calledModuleName<bot.calledModuleName>`
+ - :func:`pywikibot.handle_args<bot.handle_args>`
+ - :func:`pywikibot.input<bot.input>`
+ - :func:`pywikibot.input_choice<bot.input_choice>`
+ - :func:`pywikibot.input_yn<bot.input_yn>`
+ - :func:`pywikibot.show_help<bot.show_help>`
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1042937?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: Ic9ac9604023828017e15a7854ef71ebecc29091c
Gerrit-Change-Number: 1042937
Gerrit-PatchSet: 1
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot
jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1042295?usp=email )
Change subject: [bugfix] 'move' token is no longer supported, no longer skip here
......................................................................
[bugfix] 'move' token is no longer supported, no longer skip here
Change-Id: I687daf491216638970b222cb49a33dfd350d1236
---
M tests/edit_failure_tests.py
1 file changed, 0 insertions(+), 4 deletions(-)
Approvals:
jenkins-bot: Verified
Xqt: Looks good to me, approved
diff --git a/tests/edit_failure_tests.py b/tests/edit_failure_tests.py
index a9eab69..c485d1c 100755
--- a/tests/edit_failure_tests.py
+++ b/tests/edit_failure_tests.py
@@ -116,10 +116,6 @@
"""Test that site.movepage raises the appropriate exceptions."""
mysite = self.get_site()
mainpage = self.get_mainpage()
- if 'move' not in mysite.tokens:
- self.skipTest(
- "movepage test requires 'move' token not given to user on {}"
- .format(self.site))
with self.assertRaises(Error):
mysite.movepage(mainpage, mainpage.title(), 'test')
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1042295?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I687daf491216638970b222cb49a33dfd350d1236
Gerrit-Change-Number: 1042295
Gerrit-PatchSet: 1
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot