jenkins-bot has submitted this change and it was merged.
Change subject: Site.editpage: Moving locking mechanism into a try...finally block
......................................................................
Site.editpage: Moving locking mechanism into a try...finally block
Repetition is the root of all evil. One place where self.unlock_page(page)
is forgotten can cause a deadlock.
Try...finally block is used everywhere else for unlocking in Site except
for editpage.
Bug: T145633
Change-Id: Ia5738f651fa23ab1a62d0f3ead85e0dbf4856136
---
M pywikibot/site.py
1 file changed, 77 insertions(+), 79 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/site.py b/pywikibot/site.py
index 27f45fc..92cf5e1 100644
--- a/pywikibot/site.py
+++ b/pywikibot/site.py
@@ -4947,7 +4947,6 @@
token = self.tokens['edit']
if bot is None:
bot = ("bot" in self.userinfo["rights"])
- self.lock_page(page)
params = dict(action='edit', title=page,
text=text, token=token, summary=summary, bot=bot,
recreate=recreate, createonly=createonly,
@@ -4973,92 +4972,91 @@
u"editpage: Invalid watch value '%(watch)s' ignored."
% {'watch': watch})
req = self._simple_request(**params)
- while True:
- try:
- result = req.submit()
- pywikibot.debug(u"editpage response: %s" % result,
- _logger)
- except api.APIError as err:
- self.unlock_page(page)
- if err.code.endswith("anon") and self.logged_in():
+
+ self.lock_page(page)
+ try:
+ while True:
+ try:
+ result = req.submit()
+ pywikibot.debug(u"editpage response: %s" % result,
+ _logger)
+ except api.APIError as err:
+ if err.code.endswith("anon") and self.logged_in():
+ pywikibot.debug(
+ u"editpage: received '%s' even though bot is
logged in"
+ % err.code,
+ _logger)
+ if err.code in self._ep_errors:
+ if isinstance(self._ep_errors[err.code], basestring):
+ errdata = {
+ 'site': self,
+ 'title': page.title(withSection=False),
+ 'user': self.user(),
+ 'info': err.info
+ }
+ raise Error(self._ep_errors[err.code] % errdata)
+ else:
+ raise self._ep_errors[err.code](page)
pywikibot.debug(
- u"editpage: received '%s' even though bot is logged
in"
+ u"editpage: Unexpected error code '%s'
received."
% err.code,
_logger)
- if err.code in self._ep_errors:
- if isinstance(self._ep_errors[err.code], basestring):
- errdata = {
- 'site': self,
- 'title': page.title(withSection=False),
- 'user': self.user(),
- 'info': err.info
- }
- raise Error(self._ep_errors[err.code] % errdata)
- else:
- raise self._ep_errors[err.code](page)
- pywikibot.debug(
- u"editpage: Unexpected error code '%s' received."
- % err.code,
- _logger)
- raise
- assert "edit" in result and "result" in
result["edit"], result
- if result["edit"]["result"] == "Success":
- self.unlock_page(page)
- if "nochange" in result["edit"]:
- # null edit, page not changed
- pywikibot.log(u"Page [[%s]] saved without any changes."
- % page.title())
+ raise
+ assert "edit" in result and "result" in
result["edit"], result
+ if result["edit"]["result"] == "Success":
+ if "nochange" in result["edit"]:
+ # null edit, page not changed
+ pywikibot.log(u"Page [[%s]] saved without any
changes."
+ % page.title())
+ return True
+ page.latest_revision_id =
result["edit"]["newrevid"]
+ # see
https://www.mediawiki.org/wiki/API:Wikimania_2006_API_discussion#Notes
+ # not safe to assume that saved text is the same as sent
+ del page.text
return True
- page.latest_revision_id = result["edit"]["newrevid"]
- # see
https://www.mediawiki.org/wiki/API:Wikimania_2006_API_discussion#Notes
- # not safe to assume that saved text is the same as sent
- del page.text
- return True
- elif result["edit"]["result"] == "Failure":
- if "captcha" in result["edit"]:
- captcha = result["edit"]["captcha"]
- req['captchaid'] = captcha['id']
- if captcha["type"] == "math":
- # TODO: Should the input be parsed through eval in py3?
- req['captchaword'] =
input(captcha["question"])
- continue
- elif "url" in captcha:
- import webbrowser
- webbrowser.open('%s://%s%s'
- % (self.protocol(),
- self.hostname(),
- captcha["url"]))
- req['captchaword'] = pywikibot.input(
- "Please view CAPTCHA in your browser, "
- "then type answer here:")
- continue
- else:
- self.unlock_page(page)
+ elif result["edit"]["result"] ==
"Failure":
+ if "captcha" in result["edit"]:
+ captcha = result["edit"]["captcha"]
+ req['captchaid'] = captcha['id']
+ if captcha["type"] == "math":
+ # TODO: Should the input be parsed through eval in py3?
+ req['captchaword'] =
input(captcha["question"])
+ continue
+ elif "url" in captcha:
+ import webbrowser
+ webbrowser.open('%s://%s%s'
+ % (self.protocol(),
+ self.hostname(),
+ captcha["url"]))
+ req['captchaword'] = pywikibot.input(
+ "Please view CAPTCHA in your browser, "
+ "then type answer here:")
+ continue
+ else:
+ pywikibot.error(
+ u"editpage: unknown CAPTCHA response %s, "
+ u"page not saved"
+ % captcha)
+ return False
+ elif 'spamblacklist' in result['edit']:
+ raise SpamfilterError(page,
result['edit']['spamblacklist'])
+ elif 'code' in result['edit'] and 'info' in
result['edit']:
pywikibot.error(
- u"editpage: unknown CAPTCHA response %s, "
- u"page not saved"
- % captcha)
+ u"editpage: %s\n%s, "
+ % (result['edit']['code'],
result['edit']['info']))
return False
- elif 'spamblacklist' in result['edit']:
- raise SpamfilterError(page,
result['edit']['spamblacklist'])
- elif 'code' in result['edit'] and 'info' in
result['edit']:
- self.unlock_page(page)
- pywikibot.error(
- u"editpage: %s\n%s, "
- % (result['edit']['code'],
result['edit']['info']))
- return False
+ else:
+ pywikibot.error(u"editpage: unknown failure reason %s"
+ % str(result))
+ return False
else:
- self.unlock_page(page)
- pywikibot.error(u"editpage: unknown failure reason %s"
- % str(result))
+ pywikibot.error(
+ u"editpage: Unknown result code '%s' received;
"
+ u"page not saved" %
result["edit"]["result"])
+ pywikibot.log(str(result))
return False
- else:
- self.unlock_page(page)
- pywikibot.error(
- u"editpage: Unknown result code '%s' received; "
- u"page not saved" %
result["edit"]["result"])
- pywikibot.log(str(result))
- return False
+ finally:
+ self.unlock_page(page)
OnErrorExc = namedtuple('OnErrorExc', 'exception on_new_page')
--
To view, visit
https://gerrit.wikimedia.org/r/310531
To unsubscribe, visit
https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Ia5738f651fa23ab1a62d0f3ead85e0dbf4856136
Gerrit-PatchSet: 2
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: Zhuyifei1999 <zhuyifei1999(a)gmail.com>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot <>