jenkins-bot merged this change.

View Change

Approvals: Xqt: Looks good to me, approved jenkins-bot: Verified
[FEAT] Add WikibaseEntity.get

This refactors data loading for WikibaseEntities.

Also add a new exception class NoWikibaseEntity because
entities are not always pages anymore.

Bug: T233406
Change-Id: Id2c068635a96f7164f5ffc17702df757512afac4
---
M pywikibot/__init__.py
M pywikibot/exceptions.py
M pywikibot/page.py
M tests/utils.py
4 files changed, 76 insertions(+), 28 deletions(-)

diff --git a/pywikibot/__init__.py b/pywikibot/__init__.py
index 9c9632d..65b00a5 100644
--- a/pywikibot/__init__.py
+++ b/pywikibot/__init__.py
@@ -44,7 +44,7 @@
EditConflict, PageDeletedConflict, PageCreatedConflict,
ServerError, FatalServerError, Server504Error,
CaptchaError, SpamfilterError, TitleblacklistError,
- CircularRedirect, InterwikiRedirectPage, WikiBaseError,
+ CircularRedirect, InterwikiRedirectPage, WikiBaseError, NoWikibaseEntity,
CoordinateGlobeUnknownException,
DeprecatedPageNotFoundError as _DeprecatedPageNotFoundError,
_EmailUserError,
@@ -97,7 +97,8 @@
'input_choice', 'input_yn', 'inputChoice', 'InterwikiRedirectPage',
'InvalidTitle', 'IsNotRedirectPage', 'IsRedirectPage', 'ItemPage', 'Link',
'LockedNoPage', 'LockedPage', 'log', 'NoCreateError', 'NoMoveTarget',
- 'NoPage', 'NoSuchSite', 'NoUsername', 'OtherPageSaveError', 'output',
+ 'NoPage', 'NoSuchSite', 'NoUsername', 'NoWikibaseEntity',
+ 'OtherPageSaveError', 'output',
'Page', 'PageCreatedConflict', 'PageDeletedConflict', 'PageNotSaved',
'PageRelatedError', 'PageSaveRelatedError', 'PropertyPage',
'QuitKeyboardInterrupt', 'SectionError', 'Server504Error', 'ServerError',
diff --git a/pywikibot/exceptions.py b/pywikibot/exceptions.py
index 7912a14..cdadc09 100644
--- a/pywikibot/exceptions.py
+++ b/pywikibot/exceptions.py
@@ -56,6 +56,7 @@

WikiBaseError: any issue specific to Wikibase.

+ - NoWikibaseEntity: entity doesn't exist
- CoordinateGlobeUnknownException: globe is not implemented yet.
- EntityTypeUnknownException: entity type is not available on the site.

@@ -564,6 +565,22 @@
pass


+class NoWikibaseEntity(WikiBaseError):
+
+ """This entity doesn't exist."""
+
+ def __init__(self, entity):
+ """
+ Initializer.
+
+ @param entity: Wikibase entity
+ @type entity: WikibaseEntity
+ """
+ super(NoWikibaseEntity, self).__init__(
+ "Entity '%s' doesn't exist on %s" % (entity.id, entity.repo))
+ self.entity = entity
+
+
class CoordinateGlobeUnknownException(WikiBaseError, NotImplementedError):

"""This globe is not implemented yet in either WikiBase or pywikibot."""
diff --git a/pywikibot/page.py b/pywikibot/page.py
index e1cd72c..8a51b9c 100644
--- a/pywikibot/page.py
+++ b/pywikibot/page.py
@@ -3781,6 +3781,48 @@
"""
return {}

+ def exists(self):
+ """
+ Determine if an entity exists in the data repository.
+
+ @rtype: bool
+ """
+ if not hasattr(self, '_content'):
+ try:
+ self.get()
+ return True
+ except pywikibot.NoWikibaseEntity:
+ return False
+ return 'missing' not in self._content
+
+ def get(self, force=False):
+ """
+ Fetch all entity data and cache it.
+
+ @param force: override caching
+ @type force: bool
+ @raise NoWikibaseEntity: if this entity doesn't exist
+ @return: actual data which entity holds
+ @rtype: dict
+ """
+ if force or not hasattr(self, '_content'):
+ identification = self._defined_by()
+ if not identification:
+ raise pywikibot.NoWikibaseEntity(self)
+
+ try:
+ data = self.repo.loadcontent(identification)
+ except APIError as err:
+ if err.code == 'no-such-entity':
+ raise pywikibot.NoWikibaseEntity(self)
+ raise
+ item_index, content = data.popitem()
+ self.id = item_index
+ self._content = content
+ if 'missing' in self._content:
+ raise pywikibot.NoWikibaseEntity(self)
+ return {}
+
def concept_uri(self):
"""Return the full concept URI."""
# todo: raise when self.id is -1
@@ -3946,7 +3988,7 @@
return True
except pywikibot.NoPage:
return False
- return 'lastrevid' in self._content
+ return 'missing' not in self._content

def botMayEdit(self):
"""
@@ -3982,31 +4024,19 @@

# todo: this variable is specific to ItemPage
lazy_loading_id = not hasattr(self, 'id') and hasattr(self, '_site')
- if force or not hasattr(self, '_content'):
- identification = self._defined_by()
- if not identification:
- raise pywikibot.NoPage(self)
-
- try:
- data = self.repo.loadcontent(identification)
- except APIError as err:
- if err.code == 'no-such-entity':
- raise pywikibot.NoPage(self)
- raise
- item_index = list(data.keys())[0]
- if lazy_loading_id or item_index != '-1':
- self.id = item_index
-
- self._content = data[item_index]
- if 'lastrevid' in self._content:
- self.latest_revision_id = self._content['lastrevid']
- else:
+ try:
+ data = WikibaseEntity.get(self, force=force)
+ except pywikibot.NoWikibaseEntity:
if lazy_loading_id:
p = Page(self._site, self._title)
if not p.exists():
raise pywikibot.NoPage(p)
+ # todo: raise a nicer exception here (T87345)
raise pywikibot.NoPage(self)

+ if 'lastrevid' in self._content:
+ self.latest_revision_id = self._content['lastrevid']
+
if 'pageid' in self._content:
self._pageid = self._content['pageid']

@@ -4038,11 +4068,11 @@
c.on_item = self
self.claims[pid].append(c)

- return {'aliases': self.aliases,
- 'labels': self.labels,
- 'descriptions': self.descriptions,
- 'claims': self.claims,
- }
+ data['labels'] = self.labels
+ data['descriptions'] = self.descriptions
+ data['aliases'] = self.aliases
+ data['claims'] = self.claims
+ return data

def _diff_to(self, type_key, key_name, value_name, diffto, data):
assert type_key not in data, 'Key type must be defined in data'
diff --git a/tests/utils.py b/tests/utils.py
index fefff75..89f54e8 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -645,7 +645,7 @@
@type command: list of unicode
"""
if PY2:
- command.insert(1, '-W ignore::FutureWarning:pywikibot:124')
+ command.insert(1, '-W ignore::FutureWarning:pywikibot:125')
if cryptography_version and cryptography_version < [1, 3, 4]:
command.insert(1, '-W ignore:Old version of cryptography:Warning')
# Any environment variables added on Windows must be of type

To view, visit change 523690. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: Id2c068635a96f7164f5ffc17702df757512afac4
Gerrit-Change-Number: 523690
Gerrit-PatchSet: 8
Gerrit-Owner: Matěj Suchánek <matejsuchanek97@gmail.com>
Gerrit-Reviewer: John Vandenberg <jayvdb@gmail.com>
Gerrit-Reviewer: Lokal Profil <andre.costa@wikimedia.se>
Gerrit-Reviewer: Matěj Suchánek <matejsuchanek97@gmail.com>
Gerrit-Reviewer: Xqt <info@gno.de>
Gerrit-Reviewer: jenkins-bot (75)