Source code for wikibaseintegrator.models.qualifiers

from __future__ import annotations

from collections.abc import Iterator
from typing import TYPE_CHECKING, Self

from wikibaseintegrator.models.basemodel import BaseModel
from wikibaseintegrator.models.snak import Snak
from wikibaseintegrator.wbi_enums import ActionIfExists

if TYPE_CHECKING:
    from wikibaseintegrator.models.claim import Claim


[docs] class Qualifiers(BaseModel): def __init__(self) -> None: self.qualifiers: dict[str, list[Snak]] = {} @property def qualifiers(self): return self.__qualifiers @qualifiers.setter def qualifiers(self, value: dict[str, list[Snak]]) -> None: assert isinstance(value, dict) self.__qualifiers = value
[docs] def set(self, qualifiers: Qualifiers | list[Snak | Claim] | None) -> Self: if isinstance(qualifiers, list) or isinstance(qualifiers, Qualifiers): for qualifier in qualifiers: self.add(qualifier) elif qualifiers is None: self.qualifiers = {} else: self.qualifiers = qualifiers return self
[docs] def get(self, property: str | int) -> list[Snak]: if isinstance(property, int): property = 'P' + str(property) if property in self.qualifiers: return self.qualifiers[property] return []
# TODO: implement action_if_exists # action_if_exists is accepted for symmetry with Claims.add() but not implemented yet # pylint: disable-next=unused-argument
[docs] def add(self, qualifier: Snak | Claim, action_if_exists: ActionIfExists = ActionIfExists.APPEND_OR_REPLACE) -> Self: # Imported here because Claim holds Qualifiers, which would make a circular import at module level from wikibaseintegrator.models.claim import Claim if isinstance(qualifier, Claim): qualifier = Snak().from_json(qualifier.get_json()['mainsnak']) if qualifier is not None: assert isinstance(qualifier, Snak) property = qualifier.property_number if property not in self.qualifiers: self.qualifiers[property] = [] self.qualifiers[property].append(qualifier) return self
[docs] def remove(self, qualifier: Snak | Claim) -> Self: """ Remove a qualifier, given as a Snak or as a Claim of the same property and value. Nothing happens if it isn't there. :param qualifier: The qualifier to remove :return: This Qualifiers object """ from wikibaseintegrator.models.claim import Claim if isinstance(qualifier, Claim): qualifier = Snak().from_json(qualifier.get_json()['mainsnak']) if qualifier is not None: assert isinstance(qualifier, Snak) # Removing a qualifier that isn't there does nothing, whether its property has other qualifiers or none qualifiers = self.qualifiers.get(qualifier.property_number) if qualifiers is None: return self if qualifier in qualifiers: qualifiers.remove(qualifier) if len(qualifiers) == 0: del self.qualifiers[qualifier.property_number] return self
[docs] def clear(self, property: str | int | None = None) -> Self: if isinstance(property, int): property = 'P' + str(property) if property is None: self.qualifiers = {} elif property in self.qualifiers: del self.qualifiers[property] return self
[docs] def from_json(self, json_data: dict[str, list]) -> Self: for property in json_data: for snak in json_data[property]: self.add(qualifier=Snak().from_json(snak)) return self
[docs] def get_json(self) -> dict[str, list]: json_data: dict[str, list] = {} for property, qualifiers in self.qualifiers.items(): json_data[property] = [qualifier.get_json() for qualifier in qualifiers] return json_data
[docs] def count(self) -> int: """ Return the total number of individual qualifier snaks, across every property. Note: ``len(qualifiers)`` returns the number of distinct properties, while iterating yields the individual snaks. Use this method when you need the qualifier count. """ return sum(len(snak_list) for snak_list in self.qualifiers.values())
def __iter__(self) -> Iterator[Snak]: iterate = [] for qualifier in self.qualifiers.values(): iterate.extend(qualifier) return iter(iterate) def __len__(self) -> int: # Returns the number of distinct properties. See count() for the total number of individual snaks. return len(self.qualifiers)