jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/672405 )
Change subject: [doc] update setup.py doc
......................................................................
[doc] update setup.py doc
stable is a branch now, not a tag. Update the doc accordingly
Change-Id: Idf797ab149dd9ff00e947a723133c9535481446b
---
M setup.py
1 file changed, 5 insertions(+), 5 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/setup.py b/setup.py
index 757acde..a8378f4 100644
--- a/setup.py
+++ b/setup.py
@@ -4,7 +4,7 @@
To create a new distribution:
-----------------------------
-- replace the developmental version string in ``pywikibot.__metadata.py``
+- replace the developmental version string in ``pywikibot.__metadata__.py``
by the corresponing final release
- create the package with::
@@ -16,11 +16,11 @@
twine upload dist/*
- create a new tag with the version number of the final release
-- move the existing 'stable' tag to that new tag
-- delete 'stable' tag in gerrit to be overridden later
- synchronize the local tags with the remote repositoy
-- prepare the next release by increasing the version number in
- ``pywikibot.__metadata.py`` and adding developmental identifier
+- merge current master branch to stable branch
+- push new stable branch to gerrit and merge it the stable repository
+- prepare the next master release by increasing the version number in
+ ``pywikibot.__metadata__.py`` and adding developmental identifier
- upload this patchset to gerrit and merge it.
"""
#
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/672405
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: Idf797ab149dd9ff00e947a723133c9535481446b
Gerrit-Change-Number: 672405
Gerrit-PatchSet: 1
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/+/672392 )
Change subject: [doc] Update ROADMAP.rst
......................................................................
[doc] Update ROADMAP.rst
Change-Id: I3ba6c013f9bc2fb72a7cb9a9b4b0db643aa66043
---
M ROADMAP.rst
1 file changed, 26 insertions(+), 12 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/ROADMAP.rst b/ROADMAP.rst
index c2a0752..2fea4ec 100644
--- a/ROADMAP.rst
+++ b/ROADMAP.rst
@@ -11,43 +11,57 @@
* Return requests.Response with http.request() instead of plain text (T265206)
* config.db_hostname has been renamed to db_hostname_format
+Code cleanups
+^^^^^^^^^^^^^
+
+* tools.PY2 was removed (T213287)
+* Site.language() method was removed in favour of Site.lang property
+* Deprecated Page.getMovedTarget() method was removed in favour of moved_target()
+* Remove deprecated Wikibase.lastrevid attribute
+* config settings of archived scripts were removed (T223826)
+* Drop startsort/endsort parameter for site.categorymembers method (T74101)
+* Deprecated data attribute of http.fetch() result has been dropped (T265206)
+* toStdout parameter of pywikibot.output() has been dropped
+* Deprecated Site.getToken() and Site.case was removed
+* Deprecated Family.known_families dict was removed (T89451)
+* Deprecated DataSite.get_* methods was removed
+* Deprecated LogEntryFactory.logtypes classproperty was removed
+* Unused comms.threadedhttp module was removed; threadedhttp.HttpRequest was already replaced with requests.Response (T265206)
+
Other changes
^^^^^^^^^^^^^
+* Raise a SiteDefinitionError if api request response is Non-JSON and site is AutoFamily (T272911)
+* Support deleting and undeleting specific file versions (T276725)
+* Only add bot option generator if the bot class have it already
+* Raise a RuntimeError if pagegenerators -namespace option is provided too late (T276916)
+* Check for LookupError exception in http._decide_encoding (T276715)
+* Re-enable setting private family files (T270949)
+* Move the hardcoded namespace identifiers to an IntEnum
+* Buffer 'pageprops' in api.QueryGenerator
* Ensure that BaseBot.generator is a Generator
* Add additional info into log if 'messagecode' is missing during login (T261061, T269503)
* Use hardcoded messages if i18n system is not available (T275981)
* Move wikibase data structures to page/_collections.py
-* Remove deprecated Wikibase.lastrevid attribute
* L10N updates
* Add support for altwiki (T271984)
* Add support for mniwiki and mniwiktionary (T273467, T273462)
-* config settings of archived scripts were removed (T223826)
-* Drop startsort/endsort parameter for site.categorymembers method (T74101)
* Don't use mime parameter as boolean in api.Request (T274723)
-* Deprecated data attribute of http.fetch() result has been dropped (T265206)
* textlib.removeDisabledPart is able to remove templates (T274138)
-* toStdout parameter of pywikibot.output() has been dropped
-* Deprecated Site.getToken() and Site.case was removed
* Create a SiteLink with __getitem__ method and implement lazy load (T273386, T245809, T238471, T226157)
* Fix date.formats['MonthName'] behaviour (T273573)
-* Deprecated Family.known_families dict was removed (T89451)
* Implement pagegenerators.handle_args() to process all options at once
-* Deprecated DataSite.get_* methods was removed
-* Deprecated LogEntryFactory.logtypes classproperty was removed
* Add enabled_options, disabled_options to GeneratorFactory (T271320)
* Move interwiki() interwiki_prefix() and local_interwiki() methods from BaseSite to APISite
* Add requests.Response.headers to log when an API error occurs (T272325)
-* Unused comms.threadedhttp module was removed; threadedhttp.HttpRequest was already replaced with requests.Response (T265206)
Future release notes
~~~~~~~~~~~~~~~~~~~~
-* 5.6.0: APISite.loadimageinfo will no longer return any content
+* 6.0.0: User.name() method will be removed in favour of User.username property
* 5.6.0: pagenenerators.handleArg() method will be removed in favour of handle_arg() (T271437)
* 5.5.0: Site.getuserinfo() method will be dropped in favour of userinfo property
* 5.5.0: Site.getglobaluserinfo() method will be dropped in favour of globaluserinfo property
-* 5.4.0: tools.PY2 will be removed (T213287)
* 5.0.0: OptionHandler.options dict will be removed in favour of OptionHandler.opt
* 5.0.0: Methods deprecated for 5 years or longer will be removed
* 5.0.0: pagegenerators.ReferringPageGenerator is desupported and will be removed
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/672392
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: I3ba6c013f9bc2fb72a7cb9a9b4b0db643aa66043
Gerrit-Change-Number: 672392
Gerrit-PatchSet: 1
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/+/658001 )
Change subject: [6.0] drop support for mw 1.19-1.22 in pywikibot.site._apisite
......................................................................
[6.0] drop support for mw 1.19-1.22 in pywikibot.site._apisite
Also require keyword arguments for upload method except for filepage
Bug: T268979
Change-Id: Ic02f2e416d9878ef664f944a88fb4df66a58791e
---
M pywikibot/site/_apisite.py
1 file changed, 89 insertions(+), 158 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/site/_apisite.py b/pywikibot/site/_apisite.py
index 698d10b..7dc99d3 100644
--- a/pywikibot/site/_apisite.py
+++ b/pywikibot/site/_apisite.py
@@ -961,7 +961,7 @@
"""Return the code for the language of this Site."""
return self.siteinfo['lang']
- def version(self):
+ def version(self) -> str:
"""Return live project version number as a string.
Use L{pywikibot.site.mw_version} to compare MediaWiki versions.
@@ -976,18 +976,10 @@
raise
if MediaWikiVersion(version) < '1.23':
- warn('\n'
- + fill('Support of MediaWiki {version} will be dropped. '
- 'It is recommended to use MediaWiki 1.23 or above. '
- 'You may use every Pywikibot 5.X for older MediaWiki '
- 'versions. See T268979 for further information.'
- .format(version=version)), FutureWarning)
-
- if MediaWikiVersion(version) < '1.19':
raise RuntimeError(
'Pywikibot "{}" does not support MediaWiki "{}".\n'
- 'Use Pywikibot prior to "5.0" or "python2" branch '
- 'instead.'.format(pywikibot.__version__, version))
+ 'Use Pywikibot prior to "6.0" branch instead.'
+ .format(pywikibot.__version__, version))
return version
@property
@@ -1518,15 +1510,8 @@
Valid tokens depend on mw version.
"""
mw_ver = self.mw_version
- if mw_ver < '1.20':
- types_wiki = self._paraminfo.parameter('query+info',
- 'token')['type']
- types_wiki.append('patrol')
- valid_types = [token for token in types if token in types_wiki]
-
- elif mw_ver < '1.24wmf19':
- types_wiki = self._paraminfo.parameter('tokens',
- 'type')['type']
+ if mw_ver < '1.24wmf19':
+ types_wiki = self._paraminfo.parameter('tokens', 'type')['type']
valid_types = [token for token in types if token in types_wiki]
else:
types_wiki_old = self._paraminfo.parameter('query+info',
@@ -1537,16 +1522,15 @@
'type')['type']
valid_types = [token for token in types if token in types_wiki]
for token in types:
- if (token not in valid_types
- and (token in types_wiki_old or token
- in types_wiki_action)):
+ if (token in types_wiki_old or token in types_wiki_action) \
+ and token not in valid_types:
valid_types.append('csrf')
return valid_types
- def get_tokens(self, types, all=False):
+ def get_tokens(self, types, all: bool = False) -> dict:
"""Preload one or multiple tokens.
- For MediaWiki version 1.19, only one token can be retrieved at once.
+ For MediaWiki version 1.23, only one token can be retrieved at once.
For MediaWiki versions since 1.24wmfXXX a new token
system was introduced which reduced the amount of tokens available.
Most of them were merged into the 'csrf' token. If the token type in
@@ -1554,15 +1538,12 @@
The other token types available are:
- deleteglobalaccount
- - patrol (*)
+ - patrol
- rollback
- setglobalaccountstatus
- userrights
- watch
- (*) For v1.19, the patrol token must be obtained from the query
- list recentchanges.
-
@see: U{https://www.mediawiki.org/wiki/API:Tokens}
@param types: the types of token (e.g., "edit", "move", "delete");
@@ -1570,10 +1551,8 @@
@type types: iterable
@param all: load all available tokens, if None only if it can be done
in one request.
- @type all: bool
return: a dict with retrieved valid tokens.
- rtype: dict
"""
def warn_handler(mod, text):
"""Filter warnings for not available tokens."""
@@ -1581,72 +1560,32 @@
r'Action \'\w+\' is not allowed for the current user', text)
user_tokens = {}
- mw_ver = self.mw_version
- if mw_ver < '1.20':
- if all:
- types_wiki = self._paraminfo.parameter('query+info',
- 'token')['type']
+ if self.mw_version < '1.24wmf19':
+ if all is not False:
+ types_wiki = self._paraminfo.parameter('tokens',
+ 'type')['type']
types.extend(types_wiki)
- valid_tokens = set(self.validate_tokens(types))
- # don't request patrol
- query = api.PropertyGenerator(
- 'info',
- site=self,
- parameters={
- 'intoken': valid_tokens - {'patrol'},
- 'titles': 'Dummy page'})
- query.request._warning_handler = warn_handler
-
- for item in query:
- pywikibot.debug(str(item), _logger)
- for tokentype in valid_tokens:
- if (tokentype + 'token') in item:
- user_tokens[tokentype] = item[tokentype + 'token']
-
- # patrol token require special handling.
- # TODO: try to catch exceptions?
- if 'patrol' in valid_tokens:
- req = self._simple_request(action='query',
- list='recentchanges',
- rctoken='patrol', rclimit=1)
-
- req._warning_handler = warn_handler
- data = req.submit()
-
- if 'query' in data:
- data = data['query']
- if 'recentchanges' in data:
- item = data['recentchanges'][0]
- pywikibot.debug(str(item), _logger)
- if 'patroltoken' in item:
- user_tokens['patrol'] = item['patroltoken']
+ req = self._simple_request(action='tokens',
+ type=self.validate_tokens(types))
else:
- if mw_ver < '1.24wmf19':
- if all is not False:
- types_wiki = self._paraminfo.parameter('tokens',
- 'type')['type']
- types.extend(types_wiki)
- req = self._simple_request(action='tokens',
- type=self.validate_tokens(types))
- else:
- if all is not False:
- types_wiki = self._paraminfo.parameter('query+tokens',
- 'type')['type']
- types.extend(types_wiki)
+ if all is not False:
+ types_wiki = self._paraminfo.parameter('query+tokens',
+ 'type')['type']
+ types.extend(types_wiki)
- req = self._simple_request(action='query', meta='tokens',
- type=self.validate_tokens(types))
+ req = self._simple_request(action='query', meta='tokens',
+ type=self.validate_tokens(types))
- req._warning_handler = warn_handler
- data = req.submit()
+ req._warning_handler = warn_handler
+ data = req.submit()
- if 'query' in data:
- data = data['query']
+ if 'query' in data:
+ data = data['query']
- if 'tokens' in data and data['tokens']:
- user_tokens = {key[:-5]: val
- for key, val in data['tokens'].items()
- if val != '+\\'}
+ if 'tokens' in data and data['tokens']:
+ user_tokens = {key[:-5]: val
+ for key, val in data['tokens'].items()
+ if val != '+\\'}
return user_tokens
@@ -2041,17 +1980,15 @@
return self._generator(api.PageGenerator, namespaces=namespaces,
total=total, g_content=content, **cmargs)
- def _rvprops(self, content=False) -> list:
+ def _rvprops(self, content: bool = False) -> List[str]:
"""Setup rvprop items for loadrevisions and preloadpages.
@return: rvprop items
"""
- props = ['comment', 'ids', 'flags', 'parsedcomment', 'sha1', 'size',
- 'tags', 'timestamp', 'user', 'userid']
+ props = ['comment', 'contentmodel', 'flags', 'ids', 'parsedcomment',
+ 'sha1', 'size', 'tags', 'timestamp', 'user', 'userid']
if content:
props.append('content')
- if self.mw_version >= '1.21':
- props.append('contentmodel')
if self.mw_version >= '1.32':
props.append('roles')
return props
@@ -4073,13 +4010,7 @@
revid = revid or set()
revision = revision or set()
- # TODO: remove exception for mw < 1.22
- if (revid or revision) and self.mw_version < '1.22':
- raise NotImplementedError(
- 'Support of "revid" parameter\n'
- 'is not implemented in MediaWiki version < "1.22"')
- else:
- combined_revid = set(revid) | {r.revid for r in revision}
+ combined_revid = set(revid) | {r.revid for r in revision}
gen = itertools.chain(
zip_longest(rcid, [], fillvalue='rcid'),
@@ -4191,7 +4122,7 @@
return data
@need_right('editmywatchlist')
- def watch(self, pages, unwatch=False) -> bool:
+ def watch(self, pages, unwatch: bool = False) -> bool:
"""Add or remove pages from watchlist.
@see: U{https://www.mediawiki.org/wiki/API:Watch}
@@ -4203,32 +4134,17 @@
if False add them (default).
@return: True if API returned expected response; False otherwise
@raises KeyError: 'watch' isn't in API response
-
"""
- parameters = {'action': 'watch',
- 'token': self.tokens['watch'],
- 'unwatch': unwatch}
+ parameters = {
+ 'action': 'watch',
+ 'titles': pages,
+ 'token': self.tokens['watch'],
+ 'unwatch': unwatch,
+ }
+ req = self._simple_request(**parameters)
+ results = req.submit()
unwatch = 'unwatched' if unwatch else 'watched'
- if self.mw_version >= '1.23':
- parameters['titles'] = pages
- req = self._simple_request(**parameters)
- results = req.submit()
- return all(unwatch in r for r in results['watch'])
-
- # MW version < 1.23
- if isinstance(pages, str):
- if '|' in pages:
- pages = pages.split('|')
- else:
- pages = (pages,)
-
- for page in pages:
- parameters['title'] = page
- req = self._simple_request(**parameters)
- result = req.submit()
- if unwatch not in result['watch']:
- return False
- return True
+ return all(unwatch in r for r in results['watch'])
@need_right('editmywatchlist')
@deprecated('Site().watch', since='20160102', future_warning=True)
@@ -4345,10 +4261,18 @@
@deprecate_arg('imagepage', 'filepage')
@need_right('upload')
- def upload(self, filepage, source_filename=None, source_url=None,
- comment=None, text=None, watch=False, ignore_warnings=False,
- chunk_size: int = 0, _file_key: Optional[str] = None,
- _offset=0, _verify_stash=None, report_success=None):
+ def upload(self, filepage, *,
+ source_filename: Optional[str] = None,
+ source_url: Optional[str] = None,
+ comment: Optional[str] = None,
+ text: Optional[str] = None,
+ watch: bool = False,
+ ignore_warnings=False,
+ chunk_size: int = 0,
+ _file_key: Optional[str] = None,
+ _offset: Union[bool, int] = 0,
+ _verify_stash: Optional[bool] = None,
+ report_success: Optional[bool] = None) -> bool:
"""
Upload a file to the wiki.
@@ -4376,23 +4300,21 @@
or None it'll raise an UploadWarning exception if the static
boolean is False.
@type ignore_warnings: bool or callable or iterable of str
- @param chunk_size: The chunk size in bytesfor chunked uploading (see
- U{https://www.mediawiki.org/wiki/API:Upload#Chunked_uploading}). It
- will only upload in chunks, if the version number is 1.20 or higher
- and the chunk size is positive but lower than the file size.
+ @param chunk_size: The chunk size in bytes for chunked uploading (see
+ U{https://www.mediawiki.org/wiki/API:Upload#Chunked_uploading}).
+ It will only upload in chunks, if the chunk size is positive
+ but lower than the file size.
@param _file_key: Reuses an already uploaded file using the filekey. If
None (default) it will upload the file.
@param _offset: When file_key is not None this can be an integer to
continue a previously canceled chunked upload. If False it treats
that as a finished upload. If True it requests the stash info from
the server to determine the offset. By default starts at 0.
- @type _offset: int or bool
@param _verify_stash: Requests the SHA1 and file size uploaded and
compares it to the local file. Also verifies that _offset is
matching the file size if the _offset is an int. If _offset is
False if verifies that the file size match with the local file. If
None it'll verifies the stash when a file key and offset is given.
- @type _verify_stash: bool or None
@param report_success: If the upload was successful it'll print a
success message and if ignore_warnings is set to False it'll
raise an UploadWarning if a warning occurred. If it's None
@@ -4400,7 +4322,6 @@
otherwise. If it's True or None ignore_warnings must be a bool.
@return: It returns True if the upload was successful and False
otherwise.
- @rtype: bool
"""
def create_warnings_list(response):
return [
@@ -4437,7 +4358,7 @@
# An offset != 0 doesn't make sense without a file key
assert(_offset == 0 or _file_key is not None)
# check for required parameters
- if bool(source_filename) == bool(source_url):
+ if source_filename and source_url:
raise ValueError('APISite.upload: must provide either '
'source_filename or source_url, not both.')
if comment is None:
@@ -4545,8 +4466,7 @@
# upload local file
throttle = True
filesize = os.path.getsize(source_filename)
- chunked_upload = (
- 0 < chunk_size < filesize and self.mw_version >= '1.20')
+ chunked_upload = 0 < chunk_size < filesize
with open(source_filename, 'rb') as f:
final_request = self._request(
throttle=throttle, parameters={
@@ -4640,10 +4560,18 @@
# can be ignored
if restart:
return self.upload(
- filepage, source_filename,
- source_url, comment, text, watch,
- True, chunk_size, None, 0,
- report_success=False)
+ filepage,
+ source_filename=source_filename,
+ source_url=source_url,
+ comment=comment,
+ text=text,
+ watch=watch,
+ ignore_warnings=True,
+ chunk_size=chunk_size,
+ _file_key=None,
+ _offset=0,
+ report_success=False
+ )
ignore_warnings = True
ignore_all_warnings = True
@@ -4691,6 +4619,7 @@
final_request = self._simple_request(
action='upload', filename=file_page_title,
url=source_url, comment=comment, text=text, token=token)
+
if not result:
final_request['watch'] = watch
final_request['ignorewarnings'] = ignore_all_warnings
@@ -4715,15 +4644,19 @@
else:
_file_key = None
pywikibot.warning('No filekey defined.')
+
if not report_success:
result.setdefault('offset', True)
if ignore_warnings(create_warnings_list(result)):
return self.upload(
- filepage, source_filename, source_url, comment, text,
- watch, True, chunk_size, _file_key,
- result['offset'], report_success=False)
- else:
- return False
+ filepage, source_filename=source_filename,
+ source_url=source_url, comment=comment, text=text,
+ watch=watch, ignore_warnings=True,
+ chunk_size=chunk_size, _file_key=_file_key,
+ _offset=result['offset'], report_success=False
+ )
+ return False
+
warn('When ignore_warnings=False in APISite.upload will change '
'from raising an UploadWarning into behaving like being a '
'callable returning False.', DeprecationWarning, 3)
@@ -4740,6 +4673,7 @@
offset=result.get('offset', False))
elif 'result' not in result:
pywikibot.output('Upload: unrecognized response: %s' % result)
+
if result['result'] == 'Success':
if report_success:
pywikibot.output('Upload successful.')
@@ -4747,6 +4681,7 @@
# mode, don't attempt to access imageinfo
if 'nochange' not in result:
filepage._load_file_revisions([result['imageinfo']])
+
return result['result'] == 'Success'
@deprecated_args(number='total', repeat=None, namespace='namespaces',
@@ -5052,31 +4987,27 @@
return self.allpages(namespace=namespaces[0], protect_level=level,
protect_type=type, total=total)
- @need_version('1.21')
- def get_property_names(self, force=False):
+ def get_property_names(self, force: bool = False):
"""
Get property names for pages_with_property().
@see: U{https://www.mediawiki.org/wiki/API:Pagepropnames}
@param force: force to retrieve userinfo ignoring cache
- @type force: bool
"""
if force or not hasattr(self, '_property_names'):
ppngen = self._generator(api.ListGenerator, 'pagepropnames')
self._property_names = [pn['propname'] for pn in ppngen]
return self._property_names
- @need_version('1.21')
- def pages_with_property(self, propname, *, total=None):
+ def pages_with_property(self, propname: str, *,
+ total: Optional[int] = None):
"""Yield Page objects from Special:PagesWithProp.
@see: U{https://www.mediawiki.org/wiki/API:Pageswithprop}
@param propname: must be a valid property.
- @type propname: str
@param total: number of pages to return
- @type total: int or None
@return: return a generator of Page objects
@rtype: iterator
"""
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/658001
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: Ic02f2e416d9878ef664f944a88fb4df66a58791e
Gerrit-Change-Number: 658001
Gerrit-PatchSet: 7
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged