jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/709832 )
Change subject: [IMPR] flow.py type hints
......................................................................
[IMPR] flow.py type hints
Bug: T286403
Change-Id: I1b4b4bedd186e68b2ad57177da51e4ae661ad9db
---
M pywikibot/fixes.py
M pywikibot/flow.py
2 files changed, 68 insertions(+), 61 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/fixes.py b/pywikibot/fixes.py
index 2055b5c..f17cf95 100644
--- a/pywikibot/fixes.py
+++ b/pywikibot/fixes.py
@@ -678,7 +678,7 @@
}
-def _load_file(filename):
+def _load_file(filename: str) -> bool:
"""Load the fixes from the given filename."""
if os.path.exists(filename):
# load binary, to let compile decode it according to the file header
diff --git a/pywikibot/flow.py b/pywikibot/flow.py
index f6db2f4..39c7b23 100644
--- a/pywikibot/flow.py
+++ b/pywikibot/flow.py
@@ -5,9 +5,13 @@
# Distributed under the terms of the MIT license.
#
import abc
+import datetime
import logging
+from typing import Any, Union
from urllib.parse import parse_qs, urlparse
+import pywikibot
+from pywikibot.backports import Dict, Iterator, List, Mapping
from pywikibot.exceptions import (
LockedPageError,
NoPageError,
@@ -19,6 +23,15 @@
logger = logging.getLogger('pywiki.wiki.flow')
+# TODO: replace these after T286867
+
+TOPIC_CLASS_TYPE = Any # Type['Topic']
+
+# Union['pywikibot.site.BaseSite', 'pywikibot.page.Link',
+# 'pywikibot.page.Page']
+
+SOURCE_TYPE = Any
+
# Flow page-like objects (boards and topics)
class FlowPage(BasePage, abc.ABC):
@@ -28,11 +41,10 @@
It cannot be instantiated directly.
"""
- def __init__(self, source, title: str = ''):
+ def __init__(self, source: SOURCE_TYPE, title: str = '') -> None:
"""Initializer.
:param source: A Flow-enabled site or a Link or Page on such a site
- :type source: Site, pywikibot.page.Link, or pywikibot.page.Page
:param title: normalized title of the page
:raises TypeError: incorrect use of parameters
@@ -44,7 +56,7 @@
raise UnknownExtensionError('site is not Flow-enabled')
@abc.abstractmethod
- def _load(self, force: bool = False):
+ def _load(self, force: bool = False) -> Dict[str, Any]:
"""Abstract method to load and cache the Flow data.
Subclasses must overwrite _load() method to load and cache
@@ -62,7 +74,8 @@
self._uuid = self._load()['workflowId']
return self._uuid
- def get(self, force=False, get_redirect=False):
+ def get(self, force: bool = False, get_redirect: bool = False
+ ) -> Dict[str, Any]:
"""Get the page's content."""
if get_redirect or force:
raise NotImplementedError(
@@ -70,14 +83,14 @@
'in {}.get()'.format(self.__class__.__name__))
# TODO: Return more useful data
- return self._data
+ return getattr(self, '_data', {})
class Board(FlowPage):
"""A Flow discussion board."""
- def _load(self, force: bool = False):
+ def _load(self, force: bool = False) -> Dict[str, Any]:
"""Load and cache the Board's data, derived from its topic list.
:param force: Whether to force a reload if the data is already loaded
@@ -86,12 +99,12 @@
self._data = self.site.load_board(self)
return self._data
- def _parse_url(self, links):
+ def _parse_url(self, links: Mapping[str, Any]) -> Dict[str, Any]:
"""Parse a URL retrieved from the API."""
rule = links['fwd']
parsed_url = urlparse(rule['url'])
params = parse_qs(parsed_url.query)
- new_params = {}
+ new_params = {} # type: Dict[str, Any]
for key, value in params.items():
if key != 'title':
key = key.replace('topiclist_', '').replace('-', '_')
@@ -103,9 +116,11 @@
@deprecate_arg('format', 'content_format')
def topics(self, content_format: str = 'wikitext', limit: int = 100,
- sort_by: str = 'newest', offset=None, offset_uuid: str = '',
- reverse: bool = False, include_offset: bool = False,
- toc_only: bool = False):
+ sort_by: str = 'newest',
+ offset: Union[str, datetime.datetime, None] = None,
+ offset_uuid: str = '', reverse: bool = False,
+ include_offset: bool = False, toc_only: bool = False
+ ) -> Iterator['Topic']:
"""Load this board's topics.
:param content_format: The content format to request the data in;
@@ -114,13 +129,11 @@
:param sort_by: Algorithm to sort topics by;
must be either 'newest' or 'updated'
:param offset: The timestamp to start at (when sortby is 'updated').
- :type offset: Timestamp or equivalent str
:param offset_uuid: The UUID to start at (when sortby is 'newest').
:param reverse: Whether to reverse the topic ordering.
:param include_offset: Whether to include the offset topic.
:param toc_only: Whether to only include information for the TOC.
:return: A generator of this board's topics.
- :rtype: generator of Topic objects
"""
data = self.site.load_topiclist(self, content_format=content_format,
limit=limit, sortby=sort_by,
@@ -136,7 +149,7 @@
@deprecate_arg('format', 'content_format')
def new_topic(self, title: str, content: str,
- content_format: str = 'wikitext'):
+ content_format: str = 'wikitext') -> 'Topic':
"""Create and return a Topic object for a new topic on this Board.
:param title: The title of the new topic (must be in plaintext)
@@ -144,7 +157,6 @@
:param content_format: The content format of the supplied content;
either 'wikitext' or 'html'
:return: The new topic
- :rtype: Topic
"""
return Topic.create_topic(self, title, content, content_format)
@@ -153,7 +165,8 @@
"""A Flow discussion topic."""
- def _load(self, force: bool = False, content_format: str = 'wikitext'):
+ def _load(self, force: bool = False, content_format: str = 'wikitext'
+ ) -> Dict[str, Any]:
"""Load and cache the Topic's data.
:param force: Whether to force a reload if the data is already loaded
@@ -163,39 +176,38 @@
self._data = self.site.load_topic(self, content_format)
return self._data
- def _reload(self):
+ def _reload(self) -> None:
"""Forcibly reload the topic's root post."""
self.root._load(load_from_topic=True)
@classmethod
@deprecate_arg('format', 'content_format')
- def create_topic(cls, board, title: str, content: str,
- content_format: str = 'wikitext'):
+ def create_topic(cls: TOPIC_CLASS_TYPE, board: 'Board', title: str,
+ content: str, content_format: str = 'wikitext'
+ ) -> 'Topic':
"""Create and return a Topic object for a new topic on a Board.
:param board: The topic's parent board
- :type board: Board
:param title: The title of the new topic (must be in plaintext)
:param content: The content of the topic's initial post
:param content_format: The content format of the supplied content;
either 'wikitext' or 'html'
:return: The new topic
- :rtype: Topic
"""
data = board.site.create_new_topic(board, title, content,
content_format)
return cls(board.site, data['topic-page'])
@classmethod
- def from_topiclist_data(cls, board, root_uuid: str, topiclist_data: dict):
+ def from_topiclist_data(cls: TOPIC_CLASS_TYPE, board: 'Board',
+ root_uuid: str,
+ topiclist_data: Dict[str, Any]) -> 'Topic':
"""Create a Topic object from API data.
:param board: The topic's parent Flow board
- :type board: Board
:param root_uuid: The UUID of the topic and its root post
:param topiclist_data: The data returned by view-topiclist
:return: A Topic object derived from the supplied data
- :rtype: Topic
:raises TypeError: any passed parameters have wrong types
:raises ValueError: the passed topiclist_data is missing required data
"""
@@ -210,48 +222,47 @@
return topic
@property
- def root(self):
+ def root(self) -> 'Post':
"""The root post of this topic."""
if not hasattr(self, '_root'):
self._root = Post.fromJSON(self, self.uuid, self._data)
return self._root
@property
- def is_locked(self):
+ def is_locked(self) -> bool:
"""Whether this topic is locked."""
return self.root._current_revision['isLocked']
@property
- def is_moderated(self):
+ def is_moderated(self) -> bool:
"""Whether this topic is moderated."""
return self.root._current_revision['isModerated']
@deprecate_arg('format', 'content_format')
- def replies(self, content_format: str = 'wikitext', force: bool = False):
+ def replies(self, content_format: str = 'wikitext', force: bool = False
+ ) -> List['Post']:
"""A list of replies to this topic's root post.
:param content_format: Content format to return contents in;
must be 'wikitext', 'html', or 'fixed-html'
:param force: Whether to reload from the API instead of using the cache
:return: The replies of this topic's root post
- :rtype: list of Posts
"""
return self.root.replies(content_format=content_format, force=force)
@deprecate_arg('format', 'content_format')
- def reply(self, content: str, content_format: str = 'wikitext'):
+ def reply(self, content: str, content_format: str = 'wikitext') -> 'Post':
"""A convenience method to reply to this topic's root post.
:param content: The content of the new post
:param content_format: The format of the given content;
must be 'wikitext' or 'html')
:return: The new reply to this topic's root post
- :rtype: Post
"""
return self.root.reply(content, content_format)
# Moderation
- def lock(self, reason: str):
+ def lock(self, reason: str) -> None:
"""Lock this topic.
:param reason: The reason for locking this topic
@@ -259,7 +270,7 @@
self.site.lock_topic(self, True, reason)
self._reload()
- def unlock(self, reason: str):
+ def unlock(self, reason: str) -> None:
"""Unlock this topic.
:param reason: The reason for unlocking this topic
@@ -267,7 +278,7 @@
self.site.lock_topic(self, False, reason)
self._reload()
- def delete_mod(self, reason: str):
+ def delete_mod(self, reason: str) -> None:
"""Delete this topic through the Flow moderation system.
:param reason: The reason for deleting this topic.
@@ -275,7 +286,7 @@
self.site.delete_topic(self, reason)
self._reload()
- def hide(self, reason: str):
+ def hide(self, reason: str) -> None:
"""Hide this topic.
:param reason: The reason for hiding this topic.
@@ -283,7 +294,7 @@
self.site.hide_topic(self, reason)
self._reload()
- def suppress(self, reason: str):
+ def suppress(self, reason: str) -> None:
"""Suppress this topic.
:param reason: The reason for suppressing this topic.
@@ -291,7 +302,7 @@
self.site.suppress_topic(self, reason)
self._reload()
- def restore(self, reason: str):
+ def restore(self, reason: str) -> None:
"""Restore this topic.
:param reason: The reason for restoring this topic.
@@ -305,12 +316,11 @@
"""A post to a Flow discussion topic."""
- def __init__(self, page, uuid: str):
+ def __init__(self, page: 'Topic', uuid: str) -> None:
"""
Initializer.
:param page: Flow topic
- :type page: Topic
:param uuid: UUID of a Flow post
:raises TypeError: incorrect types of parameters
@@ -325,15 +335,15 @@
self._page = page
self._uuid = uuid
- self._content = {}
+ self._content = {} # type: Dict[str, Any]
@classmethod
- def fromJSON(cls, page, post_uuid: str, data: dict): # noqa: N802
+ def fromJSON(cls, page: 'Topic', post_uuid: str, # noqa: N802
+ data: Dict[str, Any]) -> 'Post':
"""
Create a Post object using the data returned from the API call.
:param page: A Flow topic
- :type page: Topic
:param post_uuid: The UUID of the post
:param data: The JSON data returned from the API
@@ -346,7 +356,7 @@
return post
- def _set_data(self, data: dict):
+ def _set_data(self, data: Dict[str, Any]) -> None:
"""Set internal data and cache content.
:param data: The data to store internally
@@ -373,7 +383,7 @@
self._content[content['format']] = content['content']
def _load(self, force: bool = True, content_format: str = 'wikitext',
- load_from_topic: bool = False):
+ load_from_topic: bool = False) -> Dict[str, Any]:
"""Load and cache the Post's data using the given content format.
:param load_from_topic: Whether to load the post from the whole topic
@@ -395,32 +405,30 @@
return self._uuid
@property
- def site(self):
+ def site(self) -> 'pywikibot.site.BaseSite':
"""Return the site associated with the post.
:return: Site associated with the post
- :rtype: Site
"""
return self._page.site
@property
- def page(self):
+ def page(self) -> 'Topic':
"""Return the page associated with the post.
:return: Page associated with the post
- :rtype: Topic
"""
return self._page
@property
- def is_moderated(self):
+ def is_moderated(self) -> bool:
"""Whether this post is moderated."""
if not hasattr(self, '_current_revision'):
self._load()
return self._current_revision['isModerated']
@property
- def creator(self):
+ def creator(self) -> str:
"""The creator of this post."""
if not hasattr(self, '_current_revision'):
self._load()
@@ -443,20 +451,20 @@
return self._content[content_format]
@deprecate_arg('format', 'content_format')
- def replies(self, content_format: str = 'wikitext', force: bool = False):
+ def replies(self, content_format: str = 'wikitext', force: bool = False
+ ) -> List['Post']:
"""Return this post's replies.
:param content_format: Content format to return contents in;
must be 'wikitext', 'html', or 'fixed-html'
:param force: Whether to reload from the API instead of using the cache
:return: This post's replies
- :rtype: list of Posts
"""
if content_format not in ('wikitext', 'html', 'fixed-html'):
raise ValueError('Invalid content format.')
if hasattr(self, '_replies') and not force:
- return self._replies
+ return self._replies # type: ignore[has-type]
# load_from_topic workaround due to T106733
# (replies not returned by view-post)
@@ -469,14 +477,13 @@
return self._replies
@deprecate_arg('format', 'content_format')
- def reply(self, content: str, content_format: str = 'wikitext'):
+ def reply(self, content: str, content_format: str = 'wikitext') -> 'Post':
"""Reply to this post.
:param content: The content of the new post
:param content_format: The format of the given content;
must be 'wikitext' or 'html'
:return: The new reply post
- :rtype: Post
"""
self._load()
if self.page.is_locked:
@@ -495,7 +502,7 @@
return post
# Moderation
- def delete(self, reason: str):
+ def delete(self, reason: str) -> None:
"""Delete this post through the Flow moderation system.
:param reason: The reason for deleting this post.
@@ -503,7 +510,7 @@
self.site.delete_post(self, reason)
self._load()
- def hide(self, reason: str):
+ def hide(self, reason: str) -> None:
"""Hide this post.
:param reason: The reason for hiding this post.
@@ -511,7 +518,7 @@
self.site.hide_post(self, reason)
self._load()
- def suppress(self, reason: str):
+ def suppress(self, reason: str) -> None:
"""Suppress this post.
:param reason: The reason for suppressing this post.
@@ -519,7 +526,7 @@
self.site.suppress_post(self, reason)
self._load()
- def restore(self, reason: str):
+ def restore(self, reason: str) -> None:
"""Restore this post.
:param reason: The reason for restoring this post.
@@ -527,6 +534,6 @@
self.site.restore_post(self, reason)
self._load()
- def thank(self):
+ def thank(self) -> None:
"""Thank the user who made this post."""
self.site.thank_post(self)
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/709832
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: I1b4b4bedd186e68b2ad57177da51e4ae661ad9db
Gerrit-Change-Number: 709832
Gerrit-PatchSet: 1
Gerrit-Owner: Damian <atagar1(a)gmail.com>
Gerrit-Reviewer: Huji <huji.huji(a)gmail.com>
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/+/719648 )
Change subject: Drop piprop from meta=proofreadinfo API call
......................................................................
Drop piprop from meta=proofreadinfo API call
Because the "pi" prefix is already in use by PageImages, this module
is being changed to use a prefix of prpi instead. This should not be
a breaking change in either direction because the default value of
the parameter included all of the current prop values.
Because the default parameter for piprop was always
'namespaces|qualitylevels', it is safe to remove this parameter
entriely, thus avoiding an unrecognized parameter warning.
Bug: T290585
Change-Id: I0f269e06a10c75c296d9c126228970b7ccff72d4
---
M pywikibot/site/_extensions.py
1 file changed, 1 insertion(+), 2 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/site/_extensions.py b/pywikibot/site/_extensions.py
index 634cff7..6a1d2df 100644
--- a/pywikibot/site/_extensions.py
+++ b/pywikibot/site/_extensions.py
@@ -103,8 +103,7 @@
pirequest = self._request(
expiry=pywikibot.config.API_config_expiry
if expiry is False else expiry,
- parameters={'action': 'query', 'meta': 'proofreadinfo',
- 'piprop': 'namespaces|qualitylevels'}
+ parameters={'action': 'query', 'meta': 'proofreadinfo'}
)
pidata = pirequest.submit()
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/719648
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: I0f269e06a10c75c296d9c126228970b7ccff72d4
Gerrit-Change-Number: 719648
Gerrit-PatchSet: 3
Gerrit-Owner: Legoktm <legoktm(a)debian.org>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot
Gerrit-CC: Urbanecm <martin.urbanec(a)wikimedia.cz>
Gerrit-MessageType: merged
jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/720479 )
Change subject: [cleanup] remove unnecessary `elif` after `continue`
......................................................................
[cleanup] remove unnecessary `elif` after `continue`
Change-Id: I016423bc9f925e0f0ed1b5e92cbf63fc3a9e0e57
---
M pywikibot/data/api.py
1 file changed, 1 insertion(+), 1 deletion(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/data/api.py b/pywikibot/data/api.py
index 305c5c1..c386849 100644
--- a/pywikibot/data/api.py
+++ b/pywikibot/data/api.py
@@ -1804,7 +1804,7 @@
self.site.throttle.lag(lag * retries)
continue
- elif code == 'help' and self.action == 'help':
+ if code == 'help' and self.action == 'help':
# The help module returns an error result with the complete
# API information. As this data was requested, return the
# data instead of raising an exception.
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/720479
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: I016423bc9f925e0f0ed1b5e92cbf63fc3a9e0e57
Gerrit-Change-Number: 720479
Gerrit-PatchSet: 1
Gerrit-Owner: Zabe <alexander.vorwerk(a)stud.uni-goettingen.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged