import logging import urllib.parse import wikidata.entity import datetime from dataclasses import dataclass from enforce_typing import enforce_types from typing import List, Set, Optional, Union from enum import Enum STRICT_VALIDATION = True class Concept(object): def __init__(self, context, data): self.context = context self.data = {self.canonical_key(k):v for (k, v) in data.items()} def get(self, key, *args, **kwargs): return self.data.get(self.canonical_key(key, *args, **kwargs)) def keys(self): return self.data.keys() def setdefault(self, key, value): return self.data.setdefault(self.canonical_key(key), value) def to_dict(self): return {k:v for k,v in self.data.items()} def __getitem__(self, key): return self.data[self.canonical_key(key)] def __setitem__(self, key, value): if STRICT_VALIDATION: if not isinstance(key, str) or key != '@id': assert isinstance(value, list), value for v in value: assert isinstance(v, dict), value assert 'value' in v, value for subk in v: assert not isinstance(v[subk], list), value self.data[self.canonical_key(key)] = value def __contains__(self, key): return self.canonical_key(key) in self.data def __delitem__(self, key): del self.data[self.canonical_key(key)] def canonical_key(self, key): if isinstance(key, urllib.parse.ParseResult): return key if not isinstance(key, str): return key elif key.startswith('@'): return key if self.context is None: return key return self.context._replace(path = key) def __repr__(self): if id := self.data.get('@id'): return 'Concept {{ @id = {} }}'.format(id) return 'Concept '+str(self.data) def __str__(self): return repr(self)