import warnings
from typing import Optional, Set
from ts_lib_units.unit_types import UnitType
[docs]
class TetraUnit(str):
"""A class to represent a unit in the TetraScience Unit Vocabulary"""
_ts_format: str
_pint_format: Optional[str]
_qudt_uri: Optional[str]
_aliases: Set[str]
_unit_type: UnitType
def __new__( # pylint: disable=unused-argument
cls,
ts_format: str,
pint_format: Optional[str] = None,
qudt_uri: Optional[str] = None,
unit_type: UnitType = UnitType.ARBITRARY_UNIT,
aliases: Optional[Set[str]] = None,
):
return super().__new__(cls, ts_format)
def __init__(
self,
ts_format: str,
pint_format: Optional[str] = None,
qudt_uri: Optional[str] = None,
unit_type: UnitType = UnitType.ARBITRARY_UNIT,
aliases: Optional[Set[str]] = None,
):
self._ts_format = ts_format
self._pint_format = pint_format
self._qudt_uri = qudt_uri
self._unit_type = unit_type
self._aliases = aliases or set()
def __eq__(self, other: object) -> bool:
"""Check equality with another TetraUnit or a string."""
if isinstance(other, TetraUnit):
return (
self._ts_format == other._ts_format
and self._pint_format == other._pint_format
and self._qudt_uri == other._qudt_uri
)
if isinstance(other, str):
# String comparison is case insensitive
return self._ts_format.lower() == other.lower()
return False
def __ne__(self, other: object) -> bool:
"""Check inequality with another TetraUnit or a string."""
if isinstance(other, TetraUnit):
return (
self._ts_format != other._ts_format
or self._pint_format != other._pint_format
or self._qudt_uri != other._qudt_uri
)
if isinstance(other, str):
# String comparison is case insensitive
return self._ts_format.lower() != other.lower()
return True
def __repr__(self) -> str:
"""Return a string representation of the TetraUnit."""
return f"TetraUnit({self._ts_format}, {self._pint_format}, {self._qudt_uri})"
def __hash__(self):
"""Return the hash of the TetraUnit."""
return hash(self._ts_format)
@property
def ts_format(self) -> str:
"""Get the TetraScience format."""
return self._ts_format
@property
def pint_format(self) -> Optional[str]:
"""Get the Pint format."""
return self._pint_format
@property
def qudt_uri(self) -> Optional[str]:
"""Get the QUDT URI."""
return self._qudt_uri
@property
def unit_type(self) -> UnitType:
"""Get the unit type."""
return self._unit_type
@property
def aliases(self) -> Set[str]:
"""Get the set of aliases for the unit."""
return self._aliases
@property
def value(self) -> str:
"""Get the value of the unit.
For backwards compatibility with previous `Enum` library.
"""
return self._ts_format
[docs]
def strip_aliases(self):
"""Return the base unit for this unit."""
unit = TetraUnit(
ts_format=self._ts_format,
pint_format=self._pint_format,
qudt_uri=self._qudt_uri,
unit_type=self._unit_type,
)
return unit
[docs]
class DeprecatedTetraUnit(TetraUnit):
"""A class to represent a deprecated unit in the TetraScience Unit Vocabulary"""
def __new__( # pylint: disable=unused-argument
cls,
ts_format: str,
pint_format: Optional[str],
qudt_uri: Optional[str] = None,
deprecated_message: str = "This unit is deprecated",
):
return super().__new__(cls, ts_format, pint_format, qudt_uri)
def __init__(
self,
ts_format: str,
pint_format: Optional[str],
qudt_uri: Optional[str] = None,
deprecated_message: str = "This unit is deprecated",
):
super().__init__(ts_format, pint_format, qudt_uri)
self._deprecated_message = deprecated_message
def __get__(self, instance, owner):
warnings.warn(self._deprecated_message, DeprecationWarning)
return self