Source code for toolbox.collections.item

from typing import Union, Iterator

ENCODE = "ascii"
ItemType = Union[bytes, str, int, bool, None, "Item"]


[docs] class Item: __slots__ = ["_item", "_type"] def __init__(self, item: ItemType): """ An interface for type-agnostic operations between ``bytes``, ``str``, ``int``, ``bool``, and ``None``. Internally, the passed ``item`` object is stored as its ``bytes`` representation. Any operation or modification to the new ``Item`` instance is done to the internal ``bytes`` object. The true usefulness of this container is for type-agnostic operations such as equality checks. Args: item: Input to be stored. Example: .. code-block:: python from toolbox.collections.item import Item item = Item("hello world") if b" world" in item: item -= " world" print(item.raw, item.string) # >>> b'hello' hello print(repr(item)) # >>> Item(bytes=b'hello', str='hello', int=None, bool=True, original_type=str) """ self._type = type(item) self._item = self.byte_item(item=item) @property def raw(self) -> bytes: """ Bytes representation of the passed item. """ return self._item @property def string(self) -> str: """ String representation of the passed item. """ return self._item.decode(ENCODE) @property def integer(self) -> Union[int, None]: """ Integer representation of the passed item. If passed item is not a sub class of type int or str.isdigit() this property returns None. """ if issubclass(self._type, int) or self.string.isdigit(): return int(self._item) else: return None @property def boolean(self) -> bool: """ Boolean representation of the passed item. """ if issubclass(self._type, int): return bool(int(self._item)) else: return bool(self._item) @property def original(self) -> ItemType: """ Original representation of the passed item. """ if self._type is str and isinstance(self._item, bytes): return self._item.decode(ENCODE) elif self._type is type(None): return None return self._type(self._item)
[docs] def replace(self, old: ItemType, new: ItemType, count: int = -1) -> bytes: """ ``bytes.replace()`` functionality on item. See Python `docs <https://docs.python.org/3/library/stdtypes.html?highlight=replace#bytes.replace>`_ for more info. """ old = self.byte_item(item=old) new = self.byte_item(item=new) return self.raw.replace(old, new, count)
[docs] def __pos__(self): """ Returns the string representation of the object. Example: .. code-block:: python from toolbox.collections.item import Item item = Item(100) print(+item, type(+item)) # >>> 100 <class 'str'> """ return self.string
[docs] def __neg__(self): """ Returns the integer representation of the object. Example: .. code-block:: python from toolbox.collections.item import Item item = Item(100) print(-item, type(-item)) # >>> 100 <class 'int'> """ return self.integer
[docs] def __contains__(self, item: ItemType) -> bool: _item = self.byte_item(item=item) return _item in self._item
[docs] def __eq__(self, item: ItemType) -> bool: _item = self.byte_item(item=item) return self._item == _item
[docs] def __add__(self, item: ItemType) -> "Item": _item = self.byte_item(item=item) return Item(self._item + _item)
[docs] def __iadd__(self, item: ItemType) -> "Item": self._item = (self + Item(item))._item return self
[docs] def __sub__(self, item: ItemType) -> "Item": _item = self.byte_item(item=item) return Item(self._item.replace(_item, b""))
[docs] def __isub__(self, item: ItemType) -> "Item": self._item = (self - Item(item))._item return self
[docs] def __iter__(self) -> Iterator[str]: return iter(self.string)
[docs] def __hash__(self) -> int: return hash(self._item)
[docs] def __len__(self) -> int: return len(self.raw)
[docs] def __bool__(self) -> bool: return self.boolean
[docs] def __str__(self) -> str: return self.string
[docs] def __repr__(self) -> str: return str(self.original)
@staticmethod def byte_item(item: ItemType) -> "Item": """ Converts passed item into its bytes representation, and returns an Item instance. Args: item: Item of str, bytes, int, bool, None, or Item to convert to an Item. """ if isinstance(item, str): _item = item.encode(ENCODE) elif isinstance(item, bytes): _item = item elif isinstance(item, int): _item = b"%d" % item elif item is None: _item = b"" elif isinstance(item, Item): _item = item.raw else: err = "Passed 'item' is not of type str, bytes, int, None, or Item." raise TypeError(err) return _item