Xqt has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1073778?usp=email )
Change subject: [IMPR] Check whether Claim exists within Claim.fromJSON() method ......................................................................
[IMPR] Check whether Claim exists within Claim.fromJSON() method
- If a Claim type is not given to the initializer, the type is fetched from wikibase. This can fail if it does not exist. Try to get the type and if NoWikibaseEntityError write a warning instead raising a KeyError - add a new exists() method to Property class - raise NoWikibaseEntityError in Property.type property instead of KeyError
Bug: T374681 Change-Id: Id9047cfe688c9a13c9ccc4c4ee1aebe5628abe4c --- M pywikibot/page/_wikibase.py 1 file changed, 47 insertions(+), 10 deletions(-)
Approvals: Xqt: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/page/_wikibase.py b/pywikibot/page/_wikibase.py index 5ebe25d..881f3d3 100644 --- a/pywikibot/page/_wikibase.py +++ b/pywikibot/page/_wikibase.py @@ -1428,11 +1428,34 @@ if datatype: self._type = datatype
+ def exists(self): + """Determine if the property exists in the data repository. + + .. versionadded:: 9.4 + """ + try: + self._type = self.repo.getPropertyType(self) + except KeyError: + return False + return True + @property @cached def type(self) -> str: - """Return the type of this property.""" - return self.repo.getPropertyType(self) + """Return the type of this property. + + .. versionchanged:: 9.4 + raises :exc:`NoWikibaseEntityError` if property does not + exist. + + :raises NoWikibaseEntityError: property does not exist + """ + try: + prop_type = self.repo.getPropertyType(self) + except KeyError as e: + raise NoWikibaseEntityError(e) + + return prop_type
def getID(self, numeric: bool = False): """ @@ -1727,14 +1750,14 @@ return copy
@classmethod - def fromJSON(cls, site, data): - """ - Create a claim object from JSON returned in the API call. + def fromJSON(cls, site, data: dict[str, Any]) -> Claim: + """Create a claim object from JSON returned in the API call. + + .. versionchanged:: 9.4 + print a warning if the Claim.type is not given and missing in + the wikibase.
:param data: JSON containing claim data - :type data: dict - - :rtype: pywikibot.page.Claim """ claim_repo = site.get_repo_for_entity_type('property') claim = cls(claim_repo, data['mainsnak']['property'], @@ -1743,17 +1766,31 @@ claim.snak = data['id'] elif 'hash' in data: claim.hash = data['hash'] + claim.snaktype = data['mainsnak']['snaktype'] if claim.getSnakType() == 'value': value = data['mainsnak']['datavalue']['value'] - # The default covers string, url types - if claim.type in cls.types: + + # note: claim.type could be set during claim initialization + try: + claim_type = claim.type + except NoWikibaseEntityError: + claim_type = None + + claim.target = None + if not claim_type: + pywikibot.warning(f'{claim.id} does not exist.') + elif claim.type in cls.types: + # The default covers string, url types claim.target = cls.TARGET_CONVERTER.get( claim.type, lambda value, site: value)(value, site) else: pywikibot.warning( f'{claim.type} datatype is not supported yet.') + + if claim.target is None: claim.target = pywikibot.WbUnknown.fromWikibase(value) + if 'rank' in data: # References/Qualifiers don't have ranks claim.rank = data['rank'] if 'references' in data: