jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/523690 )
Change subject: [FEAT] Add WikibaseEntity.get ......................................................................
[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(-)
Approvals: Xqt: Looks good to me, approved jenkins-bot: Verified
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
pywikibot-commits@lists.wikimedia.org