Skip to content

Commit

Permalink
[IMPR] Check whether Claim exists within Claim.fromJSON() method
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
xqt committed Sep 20, 2024
1 parent 2e531e0 commit 5b4f3d7
Showing 1 changed file with 47 additions and 10 deletions.
57 changes: 47 additions & 10 deletions pywikibot/page/_wikibase.py
Original file line number Diff line number Diff line change
Expand Up @@ -1428,11 +1428,34 @@ def __init__(self, site, id: str, datatype: str | None = None) -> None:
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):
"""
Expand Down Expand Up @@ -1727,14 +1750,14 @@ def copy(self):
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.
:param data: JSON containing claim data
:type data: dict
.. versionchanged:: 9.4
print a warning if the Claim.type is not given and missing in
the wikibase.
:rtype: pywikibot.page.Claim
:param data: JSON containing claim data
"""
claim_repo = site.get_repo_for_entity_type('property')
claim = cls(claim_repo, data['mainsnak']['property'],
Expand All @@ -1743,17 +1766,31 @@ def fromJSON(cls, site, data):
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:
Expand Down

0 comments on commit 5b4f3d7

Please sign in to comment.