jenkins-bot has submitted this change and it was merged.
Change subject: Add Page.revisions, getCreator, getLatestEditors
......................................................................
Add Page.revisions, getCreator, getLatestEditors
Adds Page.getCreator() and Page.getLatestEditors() to be the same as the
original compat methods. They were just added for compatibility but are
deprecated. The newly added Page property 'oldest_revision' now returns
a Revision object.
Page.revisions() is a generator to retrieve Revision objects and similar
to Page.getVersionHistory().
Bug: T75023
Change-Id: Ifee5de37e6feb7855550c2d8c9eeebc70ac542da
---
M pywikibot/page.py
M tests/page_tests.py
2 files changed, 44 insertions(+), 1 deletion(-)
Approvals:
John Vandenberg: Looks good to me, approved
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/page.py b/pywikibot/page.py
index 2d71d8a..f4aeeaf 100644
--- a/pywikibot/page.py
+++ b/pywikibot/page.py
@@ -578,7 +578,12 @@
@property
def oldest_revision(self):
- return self.getVersionHistory(reverseOrder=True, total=1)[0]
+ """
+ Return the first revision of this page.
+
+ @rtype: L{Revision}
+ """
+ return next(self.revisions(reverseOrder=True, total=1))
def isRedirectPage(self):
"""Return True if this is a redirect, False if not or not existing."""
@@ -1384,6 +1389,14 @@
"""
return self.site.getredirtarget(self)
+ def revisions(self, reverseOrder=False, step=None, total=None):
+ """Generator which loads the version history as Revision instances."""
+ # TODO: Only request uncached revisions
+ self.site.loadrevisions(self, getText=False, rvdir=reverseOrder,
+ step=step, total=total)
+ return (self._revisions[rev] for rev in
+ sorted(self._revisions, reverse=not reverseOrder)[:total])
+
# BREAKING CHANGE: in old framework, default value for getVersionHistory
# returned no more than 500 revisions; now, it iterates
# all revisions unless 'total' argument is used
@@ -1450,6 +1463,30 @@
users = set(entry.user for entry in history)
return users
+ @deprecated('oldest_revision')
+ def getCreator(self):
+ """Get the first revision of the page.
+
+ DEPRECATED: Use Page.oldest_revision.
+
+ @rtype: tuple(username, Timestamp)
+ """
+ result = self.oldest_revision
+ return result.user, result.timestamp
+
+ @deprecated('revisions')
+ @deprecated_args(limit="total")
+ def getLatestEditors(self, total=1):
+ """Get a list of revision informations of the last total edits.
+
+ DEPRECATED: Use Page.revisions.
+
+ @param total: iterate no more than this number of revisions in total
+ @rtype: list of dict, each dict containing the username and Timestamp
+ """
+ return [{'user': rev.user, 'timestamp': rev.timestamp}
+ for rev in self.revisions(total=total)]
+
@deprecate_arg("throttle", None)
def move(self, newtitle, reason=None, movetalkpage=True, sysop=False,
deleteAndMove=False, safe=True):
diff --git a/tests/page_tests.py b/tests/page_tests.py
index 1bb1fde..66059ad 100644
--- a/tests/page_tests.py
+++ b/tests/page_tests.py
@@ -252,6 +252,12 @@
withNamespace=False, insite=site),
u"[[:File:Jean-Léon Gérôme 003.jpg|Jean-Léon Gérôme 003.jpg]]")
+ def test_creation(self):
+ mainpage = self.get_mainpage()
+ creation = mainpage.getCreator()
+ self.assertEqual(creation[0], 'TwoOneTwo')
+ self.assertIsInstance(creation[1], pywikibot.Timestamp)
+
class TestPageObject(DefaultSiteTestCase):
--
To view, visit https://gerrit.wikimedia.org/r/114982
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Ifee5de37e6feb7855550c2d8c9eeebc70ac542da
Gerrit-PatchSet: 9
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: Legoktm <legoktm.wikipedia(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: Mpaa <mpaa.wiki(a)gmail.com>
Gerrit-Reviewer: Nullzero <nullzero.free(a)gmail.com>
Gerrit-Reviewer: Pyfisch <pyfisch(a)gmail.com>
Gerrit-Reviewer: Russell Blau <russblau(a)imapmail.org>
Gerrit-Reviewer: XZise <CommodoreFabianus(a)gmx.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot <>
XZise has submitted this change and it was merged.
Change subject: Export UserActionRefuse and deprecate PageNotFound
......................................................................
Export UserActionRefuse and deprecate PageNotFound
UserActionRefuse is used by pywikibot and scripts checkimages and
script_wui, but both scripts have been broken since August 2cddfcd
as it is not exported as a top level package class.
PageNotFound was used in compat for HTTP 40x responses, and has
never been implemented in core. Deprecate it and remove uses of it.
Also, tools.ModuleDeprecationWrapper enhanced to allow custom
deprecation messages.
Change-Id: I55b9912c8d606e1c9f12901ade2d277eb2efabbc
---
M pywikibot/__init__.py
M pywikibot/exceptions.py
M pywikibot/tools.py
M scripts/commonscat.py
M scripts/featured.py
A tests/exceptions_tests.py
6 files changed, 122 insertions(+), 26 deletions(-)
Approvals:
John Vandenberg: Looks good to me, but someone else must approve
XZise: Looks good to me, approved
diff --git a/pywikibot/__init__.py b/pywikibot/__init__.py
index 2e32da1..1cf0436 100644
--- a/pywikibot/__init__.py
+++ b/pywikibot/__init__.py
@@ -36,7 +36,7 @@
from pywikibot.exceptions import (
Error, InvalidTitle, BadTitle, NoPage, SectionError,
SiteDefinitionError, NoSuchSite, UnknownSite, UnknownFamily,
- NoUsername, UserBlocked,
+ NoUsername, UserBlocked, UserActionRefuse,
PageRelatedError, IsRedirectPage, IsNotRedirectPage,
PageSaveRelatedError, PageNotSaved, OtherPageSaveError,
LockedPage, CascadeLockedPage, LockedNoPage, NoCreateError,
@@ -73,7 +73,7 @@
'calledModuleName', 'Bot', 'WikidataBot',
'Error', 'InvalidTitle', 'BadTitle', 'NoPage', 'SectionError',
'SiteDefinitionError', 'NoSuchSite', 'UnknownSite', 'UnknownFamily',
- 'NoUsername', 'UserBlocked',
+ 'NoUsername', 'UserBlocked', 'UserActionRefuse',
'PageRelatedError', 'IsRedirectPage', 'IsNotRedirectPage',
'PageSaveRelatedError', 'PageNotSaved', 'OtherPageSaveError',
'LockedPage', 'CascadeLockedPage', 'LockedNoPage', 'NoCreateError',
@@ -716,3 +716,7 @@
wrapper = pywikibot.tools.ModuleDeprecationWrapper(__name__)
wrapper._add_deprecated_attr('ImagePage', FilePage)
+wrapper._add_deprecated_attr(
+ 'PageNotFound', pywikibot.exceptions.DeprecatedPageNotFoundError,
+ warning_message=('{0}.{1} is deprecated, and no longer '
+ 'used by pywikibot; use http.fetch() instead.'))
diff --git a/pywikibot/exceptions.py b/pywikibot/exceptions.py
index 0aef6ed..697d904 100644
--- a/pywikibot/exceptions.py
+++ b/pywikibot/exceptions.py
@@ -6,12 +6,12 @@
- NoUsername: Username is not in user-config.py, or it is invalid.
- UserBlockedY: our username or IP has been blocked
- AutoblockUser: requested action on a virtual autoblock user not valid
- - UserActionRefuse
+ - UserActionRefuse: requested user action, such as email user, refused
- BadTitle: Server responded with BadTitle
- InvalidTitle: Invalid page title
- - PageNotFound: Page not found in list
- CaptchaError: Captcha is asked and config.solve_captcha == False
- Server504Error: Server timed out with HTTP 504 code
+ - PageNotFound: Page not found (deprecated)
SiteDefinitionError: Site loading problem
- UnknownSite: Site does not exist in Family
@@ -394,13 +394,6 @@
pass
-class PageNotFound(Error): # noqa
-
- """Page not found in list"""
-
- pass
-
-
class CaptchaError(Error):
"""Captcha is asked and config.solve_captcha == False."""
@@ -450,5 +443,19 @@
import pywikibot.data.api
import pywikibot.tools
+
+
+(a)pywikibot.tools.deprecated
+class DeprecatedPageNotFoundError(Error):
+
+ """Page not found (deprecated)."""
+
+ pass
+
+
wrapper = pywikibot.tools.ModuleDeprecationWrapper(__name__)
wrapper._add_deprecated_attr('UploadWarning', pywikibot.data.api.UploadWarning)
+wrapper._add_deprecated_attr('PageNotFound', DeprecatedPageNotFoundError,
+ warning_message='{0}.{1} is deprecated, and no '
+ 'longer used by pywikibot; use '
+ 'http.fetch() instead.')
diff --git a/pywikibot/tools.py b/pywikibot/tools.py
index 7ff4008..b12341a 100644
--- a/pywikibot/tools.py
+++ b/pywikibot/tools.py
@@ -852,7 +852,7 @@
sys.modules[module.__name__] = self
def _add_deprecated_attr(self, name, replacement=None,
- replacement_name=None):
+ replacement_name=None, warning_message=None):
"""
Add the name to the local deprecated names dict.
@@ -866,6 +866,9 @@
@param replacement_name: The name of the new replaced value. Required
if C{replacement} is not None and it has no __name__ attribute.
@type replacement_name: str
+ @param warning_message: The warning to display, with positional
+ variables: {0} = module, {1} = attribute name, {2} = replacement.
+ @type warning_message: basestring
"""
if '.' in name:
raise ValueError('Deprecated name "{0}" may not contain '
@@ -875,6 +878,7 @@
if replacement is not None and hasattr(self._module, name):
raise ValueError('Module has already an attribute named '
'"{0}".'.format(name))
+
if replacement_name is None:
if hasattr(replacement, '__name__'):
replacement_name = replacement.__module__
@@ -886,24 +890,28 @@
raise TypeError('Replacement must have a __name__ attribute '
'or a replacement name must be set '
'specifically.')
- self._deprecated[name] = (replacement_name, replacement)
+
+ if not warning_message:
+ if replacement_name:
+ warning_message = u"{0}.{1} is DEPRECATED, use {2} instead."
+ else:
+ warning_message = u"{0}.{1} is DEPRECATED."
+
+ self._deprecated[name] = replacement_name, replacement, warning_message
def __setattr__(self, attr, value):
- """Set a the value of the wrapped module."""
+ """Set the value of the wrapped module."""
setattr(self._module, attr, value)
def __getattr__(self, attr):
"""Return the attribute with a deprecation warning if required."""
if attr in self._deprecated:
- if self._deprecated[attr][0]:
- warning(u"{0}.{1} is DEPRECATED, use {2} instead.".format(
- self._module.__name__, attr,
- self._deprecated[attr][0]))
- if self._deprecated[attr][1]:
- return self._deprecated[attr][1]
- else:
- warning(u"{0}.{1} is DEPRECATED.".format(
- self._module.__name__, attr))
+ warning_message = self._deprecated[attr][2]
+ warning(warning_message.format(self._module.__name__,
+ attr,
+ self._deprecated[attr][0]))
+ if self._deprecated[attr][1]:
+ return self._deprecated[attr][1]
return getattr(self._module, attr)
diff --git a/scripts/commonscat.py b/scripts/commonscat.py
index 1a970e3..c286545 100755
--- a/scripts/commonscat.py
+++ b/scripts/commonscat.py
@@ -516,8 +516,6 @@
except pywikibot.BadTitle:
# Funky title so not correct
return u''
- except pywikibot.PageNotFound:
- return u''
def main(*args):
diff --git a/scripts/featured.py b/scripts/featured.py
index 125076e..d2c2dab 100644
--- a/scripts/featured.py
+++ b/scripts/featured.py
@@ -96,7 +96,7 @@
dp = pywikibot.ItemPage(site.data_repository(), name)
try:
title = dp.getSitelink(site)
- except pywikibot.PageNotFound:
+ except pywikibot.NoPage:
return
cat = pywikibot.Category(site, title)
if isinstance(hide, dict):
diff --git a/tests/exceptions_tests.py b/tests/exceptions_tests.py
new file mode 100644
index 0000000..f4d03f0
--- /dev/null
+++ b/tests/exceptions_tests.py
@@ -0,0 +1,79 @@
+# -*- coding: utf-8 -*-
+"""Tests for exceptions."""
+#
+# (C) Pywikibot team, 2014
+#
+# Distributed under the terms of the MIT license.
+#
+__version__ = '$Id$'
+
+import pywikibot
+
+from tests.aspects import unittest, DeprecationTestCase
+
+
+class TestDeprecatedExceptions(DeprecationTestCase):
+
+ """Test usage of deprecation in library code."""
+
+ net = False
+
+ def test_UploadWarning(self):
+ """Test exceptions.UploadWarning is deprecated only."""
+ # Accessing from the main package should work fine.
+ cls = pywikibot.UploadWarning
+ self.assertNoDeprecation()
+ e = cls('foo', 'bar')
+ self.assertIsInstance(e, pywikibot.Error)
+ self.assertNoDeprecation()
+
+ self._reset_messages()
+
+ # But it sholdnt be accessed from the exceptions module.
+ cls = pywikibot.exceptions.UploadWarning
+
+ self.assertDeprecation(
+ 'pywikibot.exceptions.UploadWarning is DEPRECATED, '
+ 'use pywikibot.data.api.UploadWarning instead.')
+
+ self._reset_messages()
+
+ e = cls('foo', 'bar')
+ self.assertIsInstance(e, pywikibot.Error)
+ self.assertNoDeprecation()
+
+ def test_PageNotFound(self):
+ """Test PageNotFound is deprecated from the package."""
+ cls = pywikibot.PageNotFound
+ self.assertDeprecation(
+ 'pywikibot.PageNotFound is deprecated, and no longer '
+ 'used by pywikibot; use http.fetch() instead.')
+
+ self._reset_messages()
+
+ e = cls('foo')
+ self.assertIsInstance(e, pywikibot.Error)
+ self.assertDeprecation(
+ 'pywikibot.exceptions.DeprecatedPageNotFoundError is deprecated.')
+
+ self._reset_messages()
+
+ cls = pywikibot.exceptions.PageNotFound
+
+ self.assertDeprecation(
+ 'pywikibot.exceptions.PageNotFound is deprecated, and no longer '
+ 'used by pywikibot; use http.fetch() instead.')
+
+ self._reset_messages()
+
+ e = cls('foo')
+ self.assertIsInstance(e, pywikibot.Error)
+ self.assertDeprecation(
+ 'pywikibot.exceptions.DeprecatedPageNotFoundError is deprecated.')
+
+
+if __name__ == '__main__':
+ try:
+ unittest.main()
+ except SystemExit:
+ pass
--
To view, visit https://gerrit.wikimedia.org/r/179859
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I55b9912c8d606e1c9f12901ade2d277eb2efabbc
Gerrit-PatchSet: 3
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: XZise <CommodoreFabianus(a)gmx.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot <>
jenkins-bot has submitted this change and it was merged.
Change subject: Do not decode docstring when it is already unicode.
......................................................................
Do not decode docstring when it is already unicode.
Bug was established with Ic5a25fac9592fead9a6d8b0748bf13947ef7f2c7
Bug: T78519
Change-Id: Ia7beef2f8111f8a76c2241b88048f4cc62eb9cd9
---
M pywikibot/bot.py
1 file changed, 1 insertion(+), 1 deletion(-)
Approvals:
John Vandenberg: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/bot.py b/pywikibot/bot.py
index 8643081..ddfbbc9 100644
--- a/pywikibot/bot.py
+++ b/pywikibot/bot.py
@@ -834,7 +834,7 @@
try:
module = __import__('%s' % module_name)
helpText = module.__doc__
- if sys.version_info[0] < 3:
+ if sys.version_info[0] < 3 and isinstance(helpText, str):
helpText = helpText.decode('utf-8')
if hasattr(module, 'docuReplacements'):
for key, value in module.docuReplacements.items():
--
To view, visit https://gerrit.wikimedia.org/r/179874
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Ia7beef2f8111f8a76c2241b88048f4cc62eb9cd9
Gerrit-PatchSet: 4
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: XZise <CommodoreFabianus(a)gmx.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot <>
jenkins-bot has submitted this change and it was merged.
Change subject: New BasePage.content_model property
......................................................................
New BasePage.content_model property
If it cannot be reliably determined via the API,
None is returned, to allow case-by-case fallbacks.
Bug: T75488
Change-Id: Ia337b5ba9e914d44232c2b9bd09781047e874e04
---
M pywikibot/data/api.py
M pywikibot/page.py
2 files changed, 12 insertions(+), 0 deletions(-)
Approvals:
John Vandenberg: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/data/api.py b/pywikibot/data/api.py
index a460313..4bb7962 100644
--- a/pywikibot/data/api.py
+++ b/pywikibot/data/api.py
@@ -1795,6 +1795,7 @@
else:
raise AssertionError(
"Page %s has neither 'pageid' nor 'missing' attribute" % pagedict['title'])
+ page._contentmodel = pagedict.get('contentmodel') # can be None
if 'info' in props:
page._isredir = 'redirect' in pagedict
if 'touched' in pagedict:
diff --git a/pywikibot/page.py b/pywikibot/page.py
index 08eddc3..b5ada5b 100644
--- a/pywikibot/page.py
+++ b/pywikibot/page.py
@@ -162,6 +162,17 @@
"""
return self._link.namespace
+ @property
+ def content_model(self):
+ """Return the content model for this page.
+
+ If it cannot be reliably determined via the API,
+ None is returned.
+ """
+ if not hasattr(self, '_contentmodel'):
+ self.site.loadpageinfo(self)
+ return self._contentmodel
+
@deprecated_args(decode=None, savetitle="asUrl")
def title(self, underscore=False, withNamespace=True,
withSection=True, asUrl=False, asLink=False,
--
To view, visit https://gerrit.wikimedia.org/r/179591
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Ia337b5ba9e914d44232c2b9bd09781047e874e04
Gerrit-PatchSet: 5
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: Ricordisamoa <ricordisamoa(a)openmailbox.org>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: Ricordisamoa <ricordisamoa(a)openmailbox.org>
Gerrit-Reviewer: XZise <CommodoreFabianus(a)gmx.de>
Gerrit-Reviewer: jenkins-bot <>