jenkins-bot submitted this change.

View Change


Approvals: Xqt: Looks good to me, approved jenkins-bot: Verified
[doc] Update ROADMAP.rst and CHANGELOG.rst

Also update documentation in several modules/scripts
and add category_graph.py to the sphinx documentation.

Change-Id: If11e2c0859b840768d5ecf4776c74177bf8bdd9e
---
M scripts/category_graph.py
M docs/scripts/categories.rst
M pywikibot/__init__.py
M ROADMAP.rst
M scripts/CHANGELOG.rst
M scripts/README.rst
M pywikibot/time.py
M docs/scripts_ref/scripts.rst
M pywikibot/families/wiktionary_family.py
M pywikibot/proofreadpage.py
10 files changed, 216 insertions(+), 82 deletions(-)

diff --git a/ROADMAP.rst b/ROADMAP.rst
index a4958c6..4a0ef7b 100644
--- a/ROADMAP.rst
+++ b/ROADMAP.rst
@@ -1,9 +1,18 @@
Current release 8.0.0
---------------------

+Improvements
+^^^^^^^^^^^^
+
+* Allow normalization of :class:`pywikibot.WbTime` objects (:phab:`T123888`)
+* Add parser for ``<pages />`` tag to :mod:`proofreadpage`
+* ``addOnly`` parameter of :func:`textlib.replaceLanguageLinks` and :func:`textlib.replaceCategoryLinks`
+ were renamed to ``add_only``
+* ``known_codes`` attribute was added to :class:`family.WikimediaFamily` (:phab:`T325426`)
+* Unify representation for :class:`time.Timestamp` between CPython and Pypy (:phab:`T325905`)
+* Implement comparison for :class:`pywikibot.WbTime` object (:phab:`T148280`, :phab:`T325863`)
* Create a cookie file for each account (:phab:`T324000`)
* Move data.api._login.LoginManager to :class:`login.ClientLoginManager`
-* Unquote title for red-links in class:`proofreadpage.IndexPage`
* Let user the choice which section to be copied with :mod:`generate_user_files
<pywikibot.scripts.generate_user_files>` (:phab:`T145372`)
* use :func:`roundrobin_generators<tools.itertools.roundrobin_generators>` to combine generators
@@ -13,9 +22,6 @@
* :meth:`Timestamp.set_timestamp()<pywikibot.time.Timestamp.set_timestamp>` raises TypeError
instead of ValueError if conversion fails
* Python 3.12 is supported
-* All parameters of :meth:`Category.members()<page.Category.members>`,
- :meth:`Category.subcategories()<page.Category.subcategories>` and
- :meth:`Category.articles()<page.Category.articles>` are keyword only
* All parameters of :meth:`APISite.categorymembers()
<pywikibot.site._generators.GeneratorsMixin.categorymembers>` are provided with
:meth:`Category.members()<page.Category.members>`,
@@ -27,23 +33,67 @@
:attr:`Page.latest_revision.timestamp<page.BasePage.latest_revision>`
* Raise a generic ServerError if requests response is a ServerError (:phab:`T320590`)
* Add a new variable 'private_folder_permission' to config.py (:phab:`T315045`)
-* Fix disolving script_paths for site-package (:phab:`T320530`)
-* Respect limit argument with Board.topics() (:phab:`T138215`, :phab:`T138307`)
-* The ``parent_id`` and ``content_model`` attributes of :class:`page.Revision` were removed in favour of ``parentid`` and ``contentmodel``
-* Support for MediaWiki < 1.27 was dropped
-* ListBoxWindows class of :mod:`userinterfaces.gui` was removed
* L10N and i18n updates
* Adjust subprocess args in :mod:`tools.djvu`
* Short site value can be given if site code is equal to family like ``-site:meta`` or ``-site:commons``
+
+Documentation improvements
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add highlighting to targeted code snippet within documentation (:phab:`T323800`)
+* Add previous, next, index, and modules links to documentation sidebar (:phab:`T323803`)
+* Introduce standard colors (legacy palette) in Furo theme (:phab:`T323802`)
+* Improve basic content structure and navigation of documentation (:phab:`T323812`)
+* Use ``Furo`` sphinx theme instead of ``Natural`` and improve documentation look and feel (:phab:`T322212`)
+* MediaWiki API cross reference was added to the documentation
+
+Bugfixes
+^^^^^^^^
+
+* Fix :class:`pywikibot.WbTime` precision (:phab:`T324798`)
+* Unquote title for red-links in class:`proofreadpage.IndexPage`
+* Find month with first letter uppercase or lowercase with :class:`textlib.TimeStripper` (:phab:`T324310`)
+* Fix disolving script_paths for site-package (:phab:`T320530`)
+* Respect limit argument with Board.topics() (:phab:`T138215`, :phab:`T138307`)
+
+Breaking changes
+^^^^^^^^^^^^^^^^
+
+* All parameters of :meth:`Category.members()<page.Category.members>`,
+ :meth:`Category.subcategories()<page.Category.subcategories>` and
+ :meth:`Category.articles()<page.Category.articles>` are keyword only
+* The ``parent_id`` and ``content_model`` attributes of :class:`page.Revision` were removed in favour
+ of ``parentid`` and ``contentmodel``
+* Support for MediaWiki < 1.27 was dropped
+* ListBoxWindows class of :mod:`userinterfaces.gui` was removed
* Require Python 3.6.1+ with Pywikibot and drop support for Python 3.6.0 (:phab:`T318912`)
* pymysql >= 0.9.3 is required (:phab:`T216741`)
* Python 3.5 support was dropped (:phab:`T301908`)
-* MediaWiki API cross reference was added to the documentation
+* *See also Code cleanups below*
+
+Code cleanups
+^^^^^^^^^^^^^
+* ``maintenance/sorting_order`` script was removed (:phab:`T325426`)
+* ``alphabetic_sv`` and ``interwiki_putfirst`` attributes of
+ :class:`Wiktionary<families.wiktionary_family.Family>` family were removed (:phab:`T325426`)
+* ``alphabetic``, ``alphabetic_revised`` and ``fyinterwiki`` attributes of :class:`family.Family`
+ were removed (:phab:`T325426`)
+* *See also Deprecations below*

Deprecations
------------

-* 8.0.0: :meth:`LoginManager.get_login_token<login.ClientLoginManager.get_login_token>` was
+* 8.0.0: :meth:`Timestamp.clone()<pywikibot.time.Timestamp.clone>` method is deprecated
+ in favour of ``Timestamp.replace()`` method.
+* 8.0.0: :meth:`family.Family.maximum_GET_length` method is deprecated in favour of
+ :ref:`config.maximum_GET_length<Account Settings>` (:phab:`T325957`)
+* 8.0.0: ``addOnly`` parameter of :func:`textlib.replaceLanguageLinks` and
+ :func:`textlib.replaceCategoryLinks` are deprecated in favour of ``add_only``
+* 8.0.0: :class:`textlib.TimeStripper` regex attributes ``ptimeR``, ``ptimeznR``, ``pyearR``, ``pmonthR``,
+ ``pdayR`` are deprecated in favour of ``patterns`` attribute which is a
+ :class:`textlib.TimeStripperPatterns`.
+* 8.0.0: :class:`textlib.TimeStripper` ``groups`` attribute is deprecated in favour of ``textlib.TIMEGROUPS``
+* 8.0.0: :meth:`LoginManager.get_login_token<login.ClientLoginManager.get_login_token>` was
replaced by ``login.ClientLoginManager.site.tokens['login']``
* 8.0.0: ``data.api.LoginManager()`` is deprecated in favour of :class:`login.ClientLoginManager`
* 8.0.0: :meth:`APISite.messages()<pywikibot.site._apisite.APISite.messages>` method is deprecated in favour of
diff --git a/docs/scripts/categories.rst b/docs/scripts/categories.rst
index a282357..2c78359 100644
--- a/docs/scripts/categories.rst
+++ b/docs/scripts/categories.rst
@@ -9,6 +9,13 @@
:no-members:
:noindex:

+category\_graph script
+======================
+
+.. automodule:: scripts.category_graph
+ :no-members:
+ :noindex:
+
commonscat script
=================

diff --git a/docs/scripts_ref/scripts.rst b/docs/scripts_ref/scripts.rst
index 4009f52..001b818 100644
--- a/docs/scripts_ref/scripts.rst
+++ b/docs/scripts_ref/scripts.rst
@@ -29,6 +29,11 @@

.. automodule:: scripts.category

+category\_graph script
+======================
+
+.. automodule:: scripts.category_graph
+
category\_redirect script
=========================

diff --git a/pywikibot/__init__.py b/pywikibot/__init__.py
index 156c059..647c283 100644
--- a/pywikibot/__init__.py
+++ b/pywikibot/__init__.py
@@ -1,6 +1,6 @@
"""The initialization file for the Pywikibot framework."""
#
-# (C) Pywikibot team, 2008-2022
+# (C) Pywikibot team, 2008-2023
#
# Distributed under the terms of the MIT license.
#
@@ -360,26 +360,27 @@
site: Optional[DataSite] = None) -> None:
"""Create a new WbTime object.

- The precision can be set by the Wikibase int value (0-14) or by a human
- readable string, e.g., 'hour'. If no precision is given, it is set
- according to the given time units.
+ The precision can be set by the Wikibase int value (0-14) or by
+ a human readable string, e.g., ``hour``. If no precision is
+ given, it is set according to the given time units.

- Timezone information is given in three different ways depending on the
- time:
+ Timezone information is given in three different ways depending
+ on the time:

- * Times after the implementation of UTC (1972): as an offset from UTC
- in minutes;
- * Times before the implementation of UTC: the offset of the time zone
- from universal time;
- * Before the implementation of time zones: The longitude of the place
- of the event, in the range −180° to 180°, multiplied by 4 to convert
- to minutes.
+ * Times after the implementation of UTC (1972): as an offset
+ from UTC in minutes;
+ * Times before the implementation of UTC: the offset of the time
+ zone from universal time;
+ * Before the implementation of time zones: The longitude of the
+ place of the event, in the range −180° to 180°, multiplied by
+ 4 to convert to minutes.

- Comparison information: When using the greater than or equal to
- operator, or the less than or equal to operator, two different time
- objects with the same UTC time after factoring in timezones are
- considered equal. However, the equality operator will return false
- if the timezone is different.
+ .. note:: **Comparison information:** When using the greater
+ than or equal to operator, or the less than or equal to
+ operator, two different time objects with the same UTC time
+ after factoring in timezones are considered equal. However,
+ the equality operator will return false if the timezone is
+ different.

:param year: The year as a signed integer of between 1 and 16 digits.
:param month: Month of the timestamp, if it exists.
@@ -452,11 +453,13 @@
def _getSecondsAdjusted(self) -> int:
"""Return an internal representation of the time object as seconds.

- The value adjusts itself for timezones. It is not compatible with
- before/after.
+ The value adjusts itself for timezones. It is not compatible
+ with before/after.

- This value should *only* be used for comparisons, and
- its value may change without warning.
+ This value should *only* be used for comparisons, and its value
+ may change without warning.
+
+ .. versionadded:: 8.0

:return: An integer roughly representing the number of seconds
since January 1, 0000 AD, adjusted for leap years.
@@ -489,25 +492,37 @@
return elapsed_seconds

def __lt__(self, other: object) -> bool:
- """Compare if self is less than other."""
+ """Compare if self is less than other.
+
+ .. versionadded:: 8.0
+ """
if isinstance(other, WbTime):
return self._getSecondsAdjusted() < other._getSecondsAdjusted()
return NotImplemented

def __le__(self, other: object) -> bool:
- """Compare if self is less equals other."""
+ """Compare if self is less equals other.
+
+ .. versionadded:: 8.0
+ """
if isinstance(other, WbTime):
return self._getSecondsAdjusted() <= other._getSecondsAdjusted()
return NotImplemented

def __gt__(self, other: object) -> bool:
- """Compare if self is greater than other."""
+ """Compare if self is greater than other.
+
+ .. versionadded:: 8.0
+ """
if isinstance(other, WbTime):
return self._getSecondsAdjusted() > other._getSecondsAdjusted()
return NotImplemented

def __ge__(self, other: object) -> bool:
- """Compare if self is greater equals other."""
+ """Compare if self is greater equals other.
+
+ .. versionadded:: 8.0
+ """
if isinstance(other, WbTime):
return self._getSecondsAdjusted() >= other._getSecondsAdjusted()
return NotImplemented
diff --git a/pywikibot/families/wiktionary_family.py b/pywikibot/families/wiktionary_family.py
index 53647a0..17055aa 100644
--- a/pywikibot/families/wiktionary_family.py
+++ b/pywikibot/families/wiktionary_family.py
@@ -1,6 +1,6 @@
"""Family module for Wiktionary."""
#
-# (C) Pywikibot team, 2005-2022
+# (C) Pywikibot team, 2005-2023
#
# Distributed under the terms of the MIT license.
#
@@ -10,7 +10,13 @@
# The Wikimedia family that is known as Wiktionary
class Family(family.SubdomainFamily, family.WikimediaFamily):

- """Family class for Wiktionary."""
+ """Family class for Wiktionary.
+
+ .. versionchanged:: 8.0
+ ``alphabetic_sv`` attribute was removed; ``interwiki_putfirst``
+ attribute was removed and default setting from parent class is
+ used.
+ """

name = 'wiktionary'

diff --git a/pywikibot/proofreadpage.py b/pywikibot/proofreadpage.py
index eaec537..4149124 100644
--- a/pywikibot/proofreadpage.py
+++ b/pywikibot/proofreadpage.py
@@ -22,7 +22,7 @@

"""
#
-# (C) Pywikibot team, 2015-2022
+# (C) Pywikibot team, 2015-2023
#
# Distributed under the terms of the MIT license.
#
@@ -82,12 +82,12 @@
class TagAttr:
"""Tag attribute of <pages />.

- Represent a single attribute.
- It is used internally in PagesTagParser() and shall not be used
- stand-alone.
+ Represent a single attribute. It is used internally in
+ :class:`PagesTagParser` and shall not be used stand-alone.

- It manages string formatting output and conversion str <--> int and quotes.
- Input value can only be srt or int and shall have quotes or nothing.
+ It manages string formatting output and conversion str <--> int and
+ quotes. Input value can only be str or int and shall have quotes or
+ nothing.

>>> a = TagAttr('to', 3.0)
Traceback (most recent call last):
@@ -142,6 +142,8 @@
'to=A123'
>>> a.value
'A123'
+
+ .. versionadded:: 8.0
"""

def __init__(self, attr, value):
@@ -184,7 +186,10 @@


class TagAttrDesc:
- """A descriptor tag."""
+ """A descriptor tag.
+
+ .. versionadded:: 8.0
+ """

def __init__(self):
"""Initializer."""
@@ -209,11 +214,12 @@


class PagesTagParser(collections.abc.Container):
- """Parser for tag <pages />.
+ """Parser for tag ``<pages />``.

- See https://www.mediawiki.org/wiki/Help:Extension:ProofreadPage/Pages_tag
+ .. seealso::
+ https://www.mediawiki.org/wiki/Help:Extension:ProofreadPage/Pages_tag

- Parse text and extract the first <pages ... /> tag.
+ Parse text and extract the first ``<pages ... />`` tag.
Individual attributes will be accessible with dot notation.

>>> tp = PagesTagParser(
@@ -221,29 +227,36 @@
>>> tp
PagesTagParser('<pages index="Index.pdf" from="first" to="last" />')

- Atttributes can be modified via dot notation.
- If an attribute is a number, it is converted to int.
- Note: 'from' is represented as 'ffrom' due to conflict with keyword.
+ Attributes can be modified via dot notation. If an attribute is a
+ number, it is converted to int.
+
+ .. note:: ``from`` is represented as ``ffrom`` due to conflict with
+ keyword.
+
>>> tp.ffrom = 1; tp.to = '"3"'
>>> tp.ffrom
1
>>> tp.to
3

- Quotes are stripped in the value and added back in the str representation.
- Note that quotes are not mandatory.
+ Quotes are stripped in the value and added back in the str
+ representation.
+
+ .. note:: Quotes are not mandatory.
+
>>> tp
PagesTagParser('<pages index="Index.pdf" from=1 to="3" />')

- Atttributes can be added via dot notation.
- Order is fixed (same order as attribute definition in the class).
+ Attributes can be added via dot notation. Order is fixed (same order
+ as attribute definition in the class).
+
>>> tp.fromsection = '"A"'
>>> tp.fromsection
'A'
>>> tp
PagesTagParser('<pages index="Index.pdf" from=1 to="3" fromsection="A" />')

- Atttributes can be deleted.
+ Attributes can be deleted.
>>> del tp.fromsection
>>> tp
PagesTagParser('<pages index="Index.pdf" from=1 to="3" />')
@@ -254,6 +267,8 @@

>>> 'step' in tp
False
+
+ .. versionadded:: 8.0
"""

pat_tag = re.compile(r'<pages (?P<attrs>[^/]*?)/>')
diff --git a/pywikibot/time.py b/pywikibot/time.py
index d02d53f..656b5f4 100644
--- a/pywikibot/time.py
+++ b/pywikibot/time.py
@@ -326,7 +326,10 @@
return f'{self.posix_timestamp():.6f}'

def __repr__(self) -> str:
- """Unify repr string between CPython and Pypy (T325905)."""
+ """Unify repr string between CPython and Pypy (T325905).
+
+ .. versionadded:: 8.0
+ """
s = super().__repr__()
return f'{type(self).__name__}{s[s.find("("):]}'

diff --git a/scripts/CHANGELOG.rst b/scripts/CHANGELOG.rst
index 0119e56..b20b4da 100644
--- a/scripts/CHANGELOG.rst
+++ b/scripts/CHANGELOG.rst
@@ -14,6 +14,11 @@

* Enable pagegenerators options with ``move`` and ``remove`` actions (:phab:`T318239`)

+category_graph
+~~~~~~~~~~~~~~
+
+* :mod:`category_graph` script was added which creates category graph in formats dot, svg and html5
+
clean_sandbox
~~~~~~~~~~~~~

@@ -24,6 +29,11 @@

* Fix argument parsing

+fixing_redirects
+~~~~~~~~~~~~~~~~
+
+* Skip invalid link titles (:phab:`T324434`)
+
interwiki
~~~~~~~~~

diff --git a/scripts/README.rst b/scripts/README.rst
index 0d27749..e7fbffe 100644
--- a/scripts/README.rst
+++ b/scripts/README.rst
@@ -31,6 +31,8 @@
| category.py | Add a category link to all pages mentioned on a page, |
| | change or remove category tags. |
+--------------------------+---------------------------------------------------------+
+| category_graph.py | Visualizes category hierarchy |
++--------------------------+---------------------------------------------------------+
| category_redirect.py | Maintain category redirects and replace links to |
| | redirected categories. |
+--------------------------+---------------------------------------------------------+
diff --git a/scripts/category_graph.py b/scripts/category_graph.py
index d871225..97c3f0a 100755
--- a/scripts/category_graph.py
+++ b/scripts/category_graph.py
@@ -1,33 +1,45 @@
#!/usr/bin/python3
-
-r"""
-Visualizes category hierarchy.
+r"""Visualizes category hierarchy.

Generates graphical representation in formats dot, svg and html5
of category hierarchy.

-usage: pwb.py graph [-style STYLE] [-depth DEPTH] [-from FROM] [-to TO]
+Usage:
+
+ pwb.py graph [-style STYLE] [-depth DEPTH] [-from FROM] [-to TO]

actions:
- -from [FROM] Category name to scan, default is main category, "?" to ask.
+
+-from [FROM] Category name to scan, default is main category, "?" to ask.

optional arguments:
- -to TO base file name to save, "?" to ask.
- -style STYLE graphviz style definitions in dot format:
- https://graphviz.org/doc/info/attrs.html
- -depth DEPTH maximal hierarchy depth. 2 by default.
- -downsize K font size divider for subcategories. 4 by default.
- Use 1 for the same font size.

-Examples:
+-to TO base file name to save, "?" to ask
+-style STYLE graphviz style definitions in dot format (see below)
+-depth DEPTH maximal hierarchy depth. 2 by default
+-downsize K font size divider for subcategories. 4 by default
+ Use 1 for the same font size

-pwb.py -v category_graph -from
-pwb.py category_graph -from Life -downsize 1.5 \
- -style 'graph[rankdir=BT ranksep=0.5] node[shape=circle
- style=filled fillcolor=green] edge[style=dashed penwidth=3]'
+.. seealso:: https://graphviz.org/doc/info/attrs.html
+ for graphviz style definitions.

+Example::
+
+ pwb.py -v category_graph -from
+
+Extended example with style settings::
+
+ pwb.py category_graph -from Life -downsize 1.5 \
+ -style 'graph[rankdir=BT ranksep=0.5] node[shape=circle
+ style=filled fillcolor=green] edge[style=dashed penwidth=3]'
+
+.. versionadded:: 8.0
"""
-
+#
+# (C) Pywikibot team, 2022-2023
+#
+# Distributed under the terms of the MIT license.
+#
import argparse
import io
from collections import defaultdict
@@ -82,14 +94,11 @@
self.dot.set_name('"' + cat_title + '"')

def scan_level(self, cat, level, hue=None) -> str:
- """
- Recursive function to fill dot graph.
+ """Recursive function to fill dot graph.

- Parameters:
- * cat - the Category of the node we're currently opening.
- * level - the current decreasing from depth to zero
- level in the tree (for recursion), opposite of depth.
-
+ :param cat: the Category of the node we're currently opening.
+ :param level: the current decreasing from depth to zero level in
+ the tree (for recursion), opposite of depth.
"""
title = cat.title(with_ns=False)
size = float(args.downsize) ** level

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

Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: If11e2c0859b840768d5ecf4776c74177bf8bdd9e
Gerrit-Change-Number: 874425
Gerrit-PatchSet: 2
Gerrit-Owner: Xqt <info@gno.de>
Gerrit-Reviewer: D3r1ck01 <xsavitar.wiki@aol.com>
Gerrit-Reviewer: Xqt <info@gno.de>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged