jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/770088 )
Change subject: [tests] set noisysleep to inf during tests
......................................................................
[tests] set noisysleep to inf during tests
- the sleeping message isn't usefull during tests.
Remove collecting it within script_tests.py
- update doc for max_retries in tests/__init__.py
Change-Id: I34f21b77d3b515a35d7e1b84943622bebb2d1f71
---
M .appveyor.yml
M .github/workflows/login_tests-ci.yml
M .github/workflows/pywikibot-ci.yml
M tests/__init__.py
M tests/script_tests.py
5 files changed, 13 insertions(+), 20 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/.appveyor.yml b/.appveyor.yml
index 6391b91..c3d815f 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -78,6 +78,7 @@
- "mkdir %PYWIKIBOT_DIR%"
- "python -Werror::UserWarning -m pwb generate_user_files -dir:%PYWIKIBOT_DIR% -family:wikipedia -lang:en -v -debug -user:%PYWIKIBOT_USERNAME%"
- ps: "[IO.File]::AppendAllText($env:PYWIKIBOT_USER_CONFIG, 'max_retries = 2; maximum_GET_length = 5000; transliteration_target = None;')"
+ - ps: "[IO.File]::AppendAllText($env:PYWIKIBOT_USER_CONFIG, 'noisysleep = float(\'inf\')')"
- ps: "[IO.File]::AppendAllText($env:PYWIKIBOT_USER_CONFIG, 'usernames[''wikipedia''][''test''] = ''{0}'';' -f $env:PYWIKIBOT_USERNAME)"
- ps: "[IO.File]::AppendAllText($env:PYWIKIBOT_USER_CONFIG, 'usernames[''wikidata''][''test''] = ''{0}'';' -f $env:PYWIKIBOT_USERNAME)"
- ps: "[IO.File]::AppendAllText($env:PYWIKIBOT_USER_CONFIG, 'usernames[''commons''][''commons''] = ''{0}'';' -f $env:PYWIKIBOT_USERNAME)"
diff --git a/.github/workflows/login_tests-ci.yml b/.github/workflows/login_tests-ci.yml
index ebefc4b..14d46ff 100644
--- a/.github/workflows/login_tests-ci.yml
+++ b/.github/workflows/login_tests-ci.yml
@@ -101,6 +101,7 @@
echo "usernames['commons']['commons'] = '${{ env.PYWIKIBOT_USERNAME }}'" >> user-config.py
echo "usernames['meta']['meta'] = '${{ env.PYWIKIBOT_USERNAME }}'" >> user-config.py
echo "max_retries = 3" >> user-config.py
+ echo "noisysleep = float('inf')" >> user-config.py
echo "maximum_GET_length = 5000" >> user-config.py
echo "console_encoding = 'utf8'" >> user-config.py
echo "import os" >> user-config.py
diff --git a/.github/workflows/pywikibot-ci.yml b/.github/workflows/pywikibot-ci.yml
index 55805e2..f7832bb 100644
--- a/.github/workflows/pywikibot-ci.yml
+++ b/.github/workflows/pywikibot-ci.yml
@@ -104,6 +104,7 @@
echo "usernames['commons']['commons'] = '${{ env.PYWIKIBOT_USERNAME }}'" >> user-config.py
echo "usernames['meta']['meta'] = '${{ env.PYWIKIBOT_USERNAME }}'" >> user-config.py
echo "max_retries = 3" >> user-config.py
+ echo "noisysleep = float('inf')" >> user-config.py
echo "maximum_GET_length = 5000" >> user-config.py
echo "console_encoding = 'utf8'" >> user-config.py
echo "import os" >> user-config.py
diff --git a/tests/__init__.py b/tests/__init__.py
index 4f05ff9..4576123 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -268,17 +268,16 @@
lambda cls, *args: cls._make_dir(join_cache_path()))
-# Travis-CI builds are set to retry twice, which aims to reduce the number
-# of 'red' builds caused by intermittent server problems, while also avoiding
-# the builds taking a long time due to retries.
-# The following allows builds to retry twice, but higher default values are
-# overridden here to restrict retries to only 1, so developer builds fail more
-# frequently in code paths resulting from mishandled server problems.
-if config.max_retries > 2:
+# Appveyor and Github action builds are set to retry twice or thrice, which
+# aims to reduce the number of 'red' builds caused by intermittent server
+# problems, while also avoiding the builds taking a long time due to retries.
+# The following allows builds to retry up to three times, but higher default
+# values are overridden here to restrict retries to only 1, so developer builds
+# fail more frequently in code paths resulting from mishandled server problems.
+if config.max_retries > 3:
if 'PYWIKIBOT_TEST_QUIET' not in os.environ:
- unittest_print(
- 'tests: max_retries reduced from {} to 1'
- .format(config.max_retries))
+ unittest_print('tests: max_retries reduced from {} to 1'
+ .format(config.max_retries))
config.max_retries = 1
# Raise CaptchaError if a test requires solving a captcha
diff --git a/tests/script_tests.py b/tests/script_tests.py
index 245e491..c11c7d8 100644
--- a/tests/script_tests.py
+++ b/tests/script_tests.py
@@ -243,16 +243,7 @@
err_result = result['stderr']
out_result = result['stdout']
-
- stderr_sleep, stderr_other = [], []
- for line in err_result.splitlines():
- if line.startswith('Sleeping for '):
- stderr_sleep.append(line)
- else:
- stderr_other.append(line)
-
- if stderr_sleep:
- unittest_print('\n'.join(stderr_sleep))
+ stderr_other = err_result.splitlines()
if result['exit_code'] == -9:
unittest_print(' killed', end=' ')
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/770088
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: I34f21b77d3b515a35d7e1b84943622bebb2d1f71
Gerrit-Change-Number: 770088
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/+/769980 )
Change subject: [IMPR] Remove unused notUpdatedSites list inside post_processing
......................................................................
[IMPR] Remove unused notUpdatedSites list inside post_processing
Also split post_processing into two method
Change-Id: I301cfc512f89dae2d095464d70b9302ba435cfa5
---
M scripts/interwiki.py
1 file changed, 70 insertions(+), 80 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/scripts/interwiki.py b/scripts/interwiki.py
index 540280a..8d6a194 100755
--- a/scripts/interwiki.py
+++ b/scripts/interwiki.py
@@ -1444,19 +1444,11 @@
.format(self.origin))
return
- # The following check is not always correct and thus disabled.
- # self.done might contain no interwiki links because of the -neverlink
- # argument or because of disambiguation conflicts.
-# if len(self.done) == 1:
-# # No interwiki at all
-# return
-
self.post_processing()
def post_processing(self):
"""Some finishing processes to be done."""
- pywikibot.output('======Post-processing {}======'
- .format(self.origin))
+ pywikibot.output('======Post-processing {}======'.format(self.origin))
# Assemble list of accepted interwiki links
new = self.assemble()
if new is None: # User said give up
@@ -1474,86 +1466,84 @@
new[self.origin.site] = self.origin
updatedSites = []
- notUpdatedSites = []
# Process all languages here
self.conf.always = False
if self.conf.limittwo:
- lclSite = self.origin.site
- lclSiteDone = False
- frgnSiteDone = False
-
- for siteCode in lclSite.family.languages_by_size:
- site = pywikibot.Site(siteCode, lclSite.family)
- if (not lclSiteDone and site == lclSite) \
- or (not frgnSiteDone and site != lclSite and site in new):
- if site == lclSite:
- lclSiteDone = True # even if we fail the update
- if (site.family.name in config.usernames
- and site.code in config.usernames[
- site.family.name]):
- try:
- if self.replaceLinks(new[site], new):
- updatedSites.append(site)
- if site != lclSite:
- frgnSiteDone = True
- except SaveError:
- notUpdatedSites.append(site)
- except GiveUpOnPage:
- break
- elif (not self.conf.strictlimittwo
- and site in new and site != lclSite):
- old = {}
- try:
- for link in new[site].iterlanglinks():
- page = pywikibot.Page(link)
- old[page.site] = page
- except NoPageError:
- pywikibot.output('BUG>>> {} no longer exists?'
- .format(new[site]))
- continue
- _mods, _comment, adding, removing, modifying \
- = compareLanguages(old, new, lclSite,
- self.conf.summary)
- if (removing and not self.conf.autonomous
- or modifying and self.problemfound
- or not old
- or (self.conf.needlimit
- and len(adding) + len(modifying)
- >= self.conf.needlimit + 1)):
- try:
- if self.replaceLinks(new[site], new):
- updatedSites.append(site)
- except SaveError:
- notUpdatedSites.append(site)
- except NoUsernameError:
- pass
- except GiveUpOnPage:
- break
+ self.process_limittwo(new, updatedSites)
else:
- for (site, page) in new.items():
- # if we have an account for this site
- if site.family.name in config.usernames \
- and site.code in config.usernames[site.family.name] \
- and not site.has_data_repository:
- # Try to do the changes
- try:
- if self.replaceLinks(page, new):
- # Page was changed
- updatedSites.append(site)
- except SaveError:
- notUpdatedSites.append(site)
- except GiveUpOnPage:
- break
-
- # disabled graph drawing for minor problems: it just takes too long
- # if notUpdatedSites != [] and config.interwiki_graph:
- # # at least one site was not updated, save a conflict graph
- # self.createGraph()
+ self.process_unlimited(new, updatedSites)
# don't report backlinks for pages we already changed
if config.interwiki_backlink:
self.reportBacklinks(new, updatedSites)
+ def process_limit_two(self, new, updated):
+ """Post process limittwo."""
+ lclSite = self.origin.site
+ lclSiteDone = False
+ frgnSiteDone = False
+
+ for code in lclSite.family.languages_by_size:
+ site = pywikibot.Site(code, lclSite.family)
+ if not lclSiteDone and site == lclSite \
+ or (not frgnSiteDone and site != lclSite and site in new):
+ if site == lclSite:
+ lclSiteDone = True # even if we fail the update
+ if (site.family.name in config.usernames
+ and site.code in config.usernames[site.family.name]):
+ try:
+ if self.replaceLinks(new[site], new):
+ updated.append(site)
+ if site != lclSite:
+ frgnSiteDone = True
+ except SaveError:
+ pass
+ except GiveUpOnPage:
+ break
+
+ elif (not self.conf.strictlimittwo
+ and site in new and site != lclSite):
+ old = {}
+ try:
+ for link in new[site].iterlanglinks():
+ page = pywikibot.Page(link)
+ old[page.site] = page
+ except NoPageError:
+ pywikibot.error('{} no longer exists?'.format(new[site]))
+ continue
+ *_, adding, removing, modifying = compareLanguages(
+ old, new, lclSite, self.conf.summary)
+ if (removing and not self.conf.autonomous
+ or modifying and self.problemfound
+ or not old
+ or (self.conf.needlimit
+ and len(adding) + len(modifying)
+ >= self.conf.needlimit + 1)):
+ try:
+ if self.replaceLinks(new[site], new):
+ updated.append(site)
+ except (NoUsernameError, SaveError):
+ pass
+ except GiveUpOnPage:
+ break
+
+ def process_unlimited(self, new, updated):
+ """Post process unlimited."""
+ for (site, page) in new.items():
+ # if we have an account for this site
+ if site.family.name in config.usernames \
+ and site.code in config.usernames[site.family.name] \
+ and not site.has_data_repository:
+ # Try to do the changes
+ try:
+ if self.replaceLinks(page, new):
+ # Page was changed
+ updated.append(site)
+ except SaveError:
+ pass
+ except GiveUpOnPage:
+ break
+
def replaceLinks(self, page, newPages) -> bool:
"""Return True if saving was successful."""
# In this case only continue on the Page we started with
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/769980
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: I301cfc512f89dae2d095464d70b9302ba435cfa5
Gerrit-Change-Number: 769980
Gerrit-PatchSet: 3
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: D3r1ck01 <xsavitar.wiki(a)aol.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/+/769076 )
Change subject: [IMPR] Remove private _verify_stash upload() parameter
......................................................................
[IMPR] Remove private _verify_stash upload() parameter
_verify_stash was never used as parameter and can be removed
Change-Id: Ie643a3a468590855f109ef9b9bb3771bb9edbedc
---
M pywikibot/site/_upload.py
1 file changed, 11 insertions(+), 13 deletions(-)
Approvals:
Matěj Suchánek: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/site/_upload.py b/pywikibot/site/_upload.py
index 2a9c754..d09a505 100644
--- a/pywikibot/site/_upload.py
+++ b/pywikibot/site/_upload.py
@@ -43,8 +43,7 @@
asynchronous: bool = False,
report_success: Optional[bool] = None,
_file_key: Optional[str] = None,
- _offset: Union[bool, int] = 0,
- _verify_stash: Optional[bool] = None) -> bool:
+ _offset: Union[bool, int] = 0) -> bool:
"""
Upload a file to the wiki.
@@ -97,12 +96,6 @@
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.
- :param _verify_stash: Private parameter for upload recurion.
- 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.
:return: It returns True if the upload was successful and False
otherwise.
"""
@@ -187,10 +180,15 @@
raise ValueError("File '{}' does not exist."
.format(source_filename))
+ # Verify the stash when a file key and offset is given:
+ # requests the SHA1 and file size uploaded and compares it to
+ # the local file. Also verify 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.
+ verify_stash = False
if source_filename and _file_key:
assert offset is False or file_size is not None
- if _verify_stash is None:
- _verify_stash = True
+ verify_stash = True
if (offset is not False and offset is not True
and offset > file_size):
raise ValueError(
@@ -198,7 +196,7 @@
'while the file is only {} bytes large.'.format(
_file_key, offset, file_size))
- if _verify_stash or offset is True:
+ if verify_stash or offset is True:
if not _file_key:
raise ValueError('Without a file key it cannot request the '
'stash information')
@@ -206,7 +204,7 @@
raise ValueError('Can request stash information only when '
'using a file name.')
props = ['size']
- if _verify_stash:
+ if verify_stash:
props += ['sha1']
stash_info = self.stash_info(_file_key, props)
if offset is True:
@@ -223,7 +221,7 @@
'while the offset was {}'.format(
_file_key, stash_info['size'], offset))
- if _verify_stash:
+ if verify_stash:
# The SHA1 was also requested so calculate and compare it
assert 'sha1' in stash_info, \
'sha1 not in stash info: {}'.format(stash_info)
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/769076
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: Ie643a3a468590855f109ef9b9bb3771bb9edbedc
Gerrit-Change-Number: 769076
Gerrit-PatchSet: 1
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Matěj Suchánek <matejsuchanek97(a)gmail.com>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged
jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/769734 )
Change subject: [IMPR] Split check_page() to reduce code complexity
......................................................................
[IMPR] Split check_page() to reduce code complexity
Change-Id: I536d27c2d419b682ca06670b45728524336ea3c3
---
M scripts/interwiki.py
1 file changed, 45 insertions(+), 42 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/scripts/interwiki.py b/scripts/interwiki.py
index c047fb2..6dff347 100755
--- a/scripts/interwiki.py
+++ b/scripts/interwiki.py
@@ -1067,6 +1067,50 @@
if self.conf.hintsareright:
self.hintedsites.add(page.site)
+ def redir_checked(self, page, counter):
+ """Check and handle redirect. Return True if check is done."""
+ if page.isRedirectPage():
+ redirect_target = page.getRedirectTarget()
+ redir = ''
+ elif page.isCategoryRedirect():
+ redirect_target = page.getCategoryRedirectTarget()
+ redir = 'category '
+ else:
+ return False
+
+ self.conf.note('{} is {}redirect to {}'
+ .format(page, redir, redirect_target))
+ if self.origin is None or page == self.origin:
+ # the 1st existig page becomes the origin page, if none was
+ # supplied
+ if self.conf.initialredirect:
+ # don't follow another redirect; it might be a self
+ # loop
+ if not redirect_target.isRedirectPage() \
+ and not redirect_target.isCategoryRedirect():
+ self.origin = redirect_target
+ self.todo.append(redirect_target)
+ counter.plus(redirect_target.site)
+ else:
+ # This is a redirect page to the origin. We don't need
+ # to follow the redirection.
+ # In this case we can also stop all hints!
+ for site, count in self.todo.iter_values_len():
+ counter.minus(site, count)
+ self.todo.clear()
+ elif not self.conf.followredirect:
+ self.conf.note('not following {}redirects.'.format(redir))
+ elif page.isStaticRedirect():
+ self.conf.note('not following static {}redirects.'.format(redir))
+ elif (page.site.family == redirect_target.site.family
+ and not self.skipPage(page, redirect_target, counter)):
+ if self.addIfNew(redirect_target, counter, page):
+ if config.interwiki_shownew:
+ pywikibot.output('{}: {} gives new {}redirect {}'
+ .format(self.origin, page, redir,
+ redirect_target))
+ return True
+
def check_page(self, page, counter) -> None:
"""Check whether any iw links should be added to the todo list."""
if not page.exists():
@@ -1083,48 +1127,7 @@
self.done.clear()
return
- if page.isRedirectPage():
- redirectTargetPage = page.getRedirectTarget()
- redir = ''
- elif page.isCategoryRedirect():
- redirectTargetPage = page.getCategoryRedirectTarget()
- redir = 'category '
- else:
- redir = None
-
- if redir is not None:
- self.conf.note('{} is {}redirect to {}'
- .format(page, redir, redirectTargetPage))
- if self.origin is None or page == self.origin:
- # the 1st existig page becomes the origin page, if none was
- # supplied
- if self.conf.initialredirect:
- # don't follow another redirect; it might be a self
- # loop
- if not redirectTargetPage.isRedirectPage() \
- and not redirectTargetPage.isCategoryRedirect():
- self.origin = redirectTargetPage
- self.todo.append(redirectTargetPage)
- counter.plus(redirectTargetPage.site)
- else:
- # This is a redirect page to the origin. We don't need
- # to follow the redirection.
- # In this case we can also stop all hints!
- for site, count in self.todo.iter_values_len():
- counter.minus(site, count)
- self.todo.clear()
- elif not self.conf.followredirect:
- self.conf.note('not following {}redirects.'.format(redir))
- elif page.isStaticRedirect():
- self.conf.note('not following static {}redirects.'
- .format(redir))
- elif (page.site.family == redirectTargetPage.site.family
- and not self.skipPage(page, redirectTargetPage, counter)):
- if self.addIfNew(redirectTargetPage, counter, page):
- if config.interwiki_shownew:
- pywikibot.output('{}: {} gives new {}redirect {}'
- .format(self.origin, page, redir,
- redirectTargetPage))
+ if self.redir_checked(page, counter):
return
# must be behind the page.isRedirectPage() part
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/769734
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: I536d27c2d419b682ca06670b45728524336ea3c3
Gerrit-Change-Number: 769734
Gerrit-PatchSet: 1
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: D3r1ck01 <xsavitar.wiki(a)aol.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/+/768087 )
Change subject: [IMPR] Use a dictionary for modified warning keys
......................................................................
[IMPR] Use a dictionary for modified warning keys
Some upload warning keys were changed. Add a warning_keys lookup dict
to get the right warning message.
See T130484 and https://www.mediawiki.org/wiki/API:Upload#Upload_warnings
Change-Id: I31098c1398b4247e72effef84266c760832af113
---
M pywikibot/site/_upload.py
1 file changed, 12 insertions(+), 4 deletions(-)
Approvals:
Matěj Suchánek: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/site/_upload.py b/pywikibot/site/_upload.py
index af8a96c..2a9c754 100644
--- a/pywikibot/site/_upload.py
+++ b/pywikibot/site/_upload.py
@@ -114,13 +114,20 @@
_file_key, response['offset'])
for warning, data in response['warnings'].items()]
+ # some warning keys have been changed
+ warning_keys = {
+ 'nochange': 'no-change',
+ 'duplicateversions': 'duplicate-version',
+ 'emptyfile': 'empty-file',
+ }
+
upload_warnings = {
# map API warning codes to user error messages
# {msg} will be replaced by message string from API response
'duplicate-archive':
'The file is a duplicate of a deleted file {msg}.',
'was-deleted': 'The file {msg} was previously deleted.',
- 'emptyfile': 'File {msg} is empty.',
+ 'empty-file': 'File {msg} is empty.',
'exists': 'File {msg} already exists.',
'duplicate': 'Uploaded file is a duplicate of {msg}.',
'badfilename': 'Target filename is invalid.',
@@ -132,9 +139,9 @@
'Target filename exists but with a different file {msg}.',
# API-returned message string will be timestamps, not much use here
- 'nochange': 'The upload is an exact duplicate of the current '
- 'version of this file.',
- 'duplicateversions': 'The upload is an exact duplicate of older '
+ 'no-change': 'The upload is an exact duplicate of the current '
+ 'version of this file.',
+ 'duplicate-version': 'The upload is an exact duplicate of older '
'version(s) of this file.',
}
@@ -489,6 +496,7 @@
UserWarning, 3)
warning = list(result['warnings'].keys())[0]
message = result['warnings'][warning]
+ warning = warning_keys.get(warning, warning)
raise UploadError(warning,
upload_warnings[warning]
.format(msg=message),
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/768087
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: I31098c1398b4247e72effef84266c760832af113
Gerrit-Change-Number: 768087
Gerrit-PatchSet: 4
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Matěj Suchánek <matejsuchanek97(a)gmail.com>
Gerrit-Reviewer: Zhuyifei1999 <zhuyifei1999(a)gmail.com>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged