Changeset View
Changeset View
Standalone View
Standalone View
swh/model/swhids.py
Show First 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | |||||
# ObjectType or ExtendedObjectType | # ObjectType or ExtendedObjectType | ||||
_TObjectType = TypeVar("_TObjectType", ObjectType, ExtendedObjectType) | _TObjectType = TypeVar("_TObjectType", ObjectType, ExtendedObjectType) | ||||
# the SWHID class itself (this is used so that X.from_string() can return X | # the SWHID class itself (this is used so that X.from_string() can return X | ||||
# for all X subclass of _BaseSWHID) | # for all X subclass of _BaseSWHID) | ||||
_TSWHID = TypeVar("_TSWHID", bound="_BaseSWHID") | _TSWHID = TypeVar("_TSWHID", bound="_BaseSWHID") | ||||
@attr.s(frozen=True, kw_only=True) | @attr.s(frozen=True, kw_only=True, repr=False) | ||||
class _BaseSWHID(Generic[_TObjectType]): | class _BaseSWHID(Generic[_TObjectType]): | ||||
"""Common base class for CoreSWHID, QualifiedSWHID, and ExtendedSWHID. | """Common base class for CoreSWHID, QualifiedSWHID, and ExtendedSWHID. | ||||
This is an "abstract" class and should not be instantiated directly; | This is an "abstract" class and should not be instantiated directly; | ||||
it only exists to deduplicate code between these three SWHID classes.""" | it only exists to deduplicate code between these three SWHID classes.""" | ||||
namespace = attr.ib(type=str, default=SWHID_NAMESPACE) | namespace = attr.ib(type=str, default=SWHID_NAMESPACE) | ||||
"""the namespace of the identifier, defaults to ``swh``""" | """the namespace of the identifier, defaults to ``swh``""" | ||||
Show All 36 Lines | def __str__(self) -> str: | ||||
[ | [ | ||||
self.namespace, | self.namespace, | ||||
str(self.scheme_version), | str(self.scheme_version), | ||||
self.object_type.value, | self.object_type.value, | ||||
hash_to_hex(self.object_id), | hash_to_hex(self.object_id), | ||||
] | ] | ||||
) | ) | ||||
def __repr__(self) -> str: | |||||
return f"{self.__class__.__name__}.from_string('{self}')" | |||||
@classmethod | @classmethod | ||||
def from_string(cls: Type[_TSWHID], s: str) -> _TSWHID: | def from_string(cls: Type[_TSWHID], s: str) -> _TSWHID: | ||||
parts = _parse_swhid(s) | parts = _parse_swhid(s) | ||||
if parts.pop("qualifiers"): | if parts.pop("qualifiers"): | ||||
raise ValidationError(f"{cls.__name__} does not support qualifiers.") | raise ValidationError(f"{cls.__name__} does not support qualifiers.") | ||||
try: | try: | ||||
return cls(**parts) | return cls(**parts) | ||||
except ValueError as e: | except ValueError as e: | ||||
raise ValidationError( | raise ValidationError( | ||||
"ValueError: %(args)s", params={"args": e.args} | "ValueError: %(args)s", params={"args": e.args} | ||||
) from None | ) from None | ||||
@attr.s(frozen=True, kw_only=True) | @attr.s(frozen=True, kw_only=True, repr=False) | ||||
class CoreSWHID(_BaseSWHID[ObjectType]): | class CoreSWHID(_BaseSWHID[ObjectType]): | ||||
""" | """ | ||||
Dataclass holding the relevant info associated to a SoftWare Heritage | Dataclass holding the relevant info associated to a SoftWare Heritage | ||||
persistent IDentifier (SWHID). | persistent IDentifier (SWHID). | ||||
Unlike `QualifiedSWHID`, it is restricted to core SWHIDs, ie. SWHIDs | Unlike `QualifiedSWHID`, it is restricted to core SWHIDs, ie. SWHIDs | ||||
with no qualifiers. | with no qualifiers. | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | |||||
def _parse_path_qualifier(path: Union[str, bytes, None]) -> Optional[bytes]: | def _parse_path_qualifier(path: Union[str, bytes, None]) -> Optional[bytes]: | ||||
if path is None or isinstance(path, bytes): | if path is None or isinstance(path, bytes): | ||||
return path | return path | ||||
else: | else: | ||||
return urllib.parse.unquote_to_bytes(path) | return urllib.parse.unquote_to_bytes(path) | ||||
@attr.s(frozen=True, kw_only=True) | @attr.s(frozen=True, kw_only=True, repr=False) | ||||
class QualifiedSWHID(_BaseSWHID[ObjectType]): | class QualifiedSWHID(_BaseSWHID[ObjectType]): | ||||
""" | """ | ||||
Dataclass holding the relevant info associated to a SoftWare Heritage | Dataclass holding the relevant info associated to a SoftWare Heritage | ||||
persistent IDentifier (SWHID) | persistent IDentifier (SWHID) | ||||
Raises: | Raises: | ||||
swh.model.exceptions.ValidationError: In case of invalid object type or id | swh.model.exceptions.ValidationError: In case of invalid object type or id | ||||
▲ Show 20 Lines • Show All 121 Lines • ▼ Show 20 Lines | def __str__(self) -> str: | ||||
] | ] | ||||
) | ) | ||||
qualifiers = self.qualifiers() | qualifiers = self.qualifiers() | ||||
if qualifiers: | if qualifiers: | ||||
for k, v in qualifiers.items(): | for k, v in qualifiers.items(): | ||||
swhid += "%s%s=%s" % (SWHID_CTXT_SEP, k, v) | swhid += "%s%s=%s" % (SWHID_CTXT_SEP, k, v) | ||||
return swhid | return swhid | ||||
def __repr__(self) -> str: | |||||
return super().__repr__() | |||||
@classmethod | @classmethod | ||||
def from_string(cls, s: str) -> QualifiedSWHID: | def from_string(cls, s: str) -> QualifiedSWHID: | ||||
parts = _parse_swhid(s) | parts = _parse_swhid(s) | ||||
qualifiers = parts.pop("qualifiers") | qualifiers = parts.pop("qualifiers") | ||||
invalid_qualifiers = set(qualifiers) - SWHID_QUALIFIERS | invalid_qualifiers = set(qualifiers) - SWHID_QUALIFIERS | ||||
if invalid_qualifiers: | if invalid_qualifiers: | ||||
raise ValidationError( | raise ValidationError( | ||||
"Invalid qualifier(s): %(qualifiers)s", | "Invalid qualifier(s): %(qualifiers)s", | ||||
params={"qualifiers": ", ".join(invalid_qualifiers)}, | params={"qualifiers": ", ".join(invalid_qualifiers)}, | ||||
) | ) | ||||
try: | try: | ||||
return QualifiedSWHID(**parts, **qualifiers) | return QualifiedSWHID(**parts, **qualifiers) | ||||
except ValueError as e: | except ValueError as e: | ||||
raise ValidationError( | raise ValidationError( | ||||
"ValueError: %(args)s", params={"args": e.args} | "ValueError: %(args)s", params={"args": e.args} | ||||
) from None | ) from None | ||||
@attr.s(frozen=True, kw_only=True) | @attr.s(frozen=True, kw_only=True, repr=False) | ||||
class ExtendedSWHID(_BaseSWHID[ExtendedObjectType]): | class ExtendedSWHID(_BaseSWHID[ExtendedObjectType]): | ||||
""" | """ | ||||
Dataclass holding the relevant info associated to a SoftWare Heritage | Dataclass holding the relevant info associated to a SoftWare Heritage | ||||
persistent IDentifier (SWHID). | persistent IDentifier (SWHID). | ||||
It extends `CoreSWHID`, by allowing non-standard object types; and should | It extends `CoreSWHID`, by allowing non-standard object types; and should | ||||
only be used internally to Software Heritage. | only be used internally to Software Heritage. | ||||
▲ Show 20 Lines • Show All 67 Lines • Show Last 20 Lines |