github.com/NVIDIA/aistore@v1.3.23-0.20240517131212-7df6609be51d/python/aistore/sdk/multiobj/object_range.py (about)

     1  #
     2  # Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved.
     3  #
     4  from typing import Iterator
     5  
     6  from aistore.sdk import utils
     7  from aistore.sdk.errors import InvalidObjectRangeIndex
     8  from aistore.sdk.multiobj.object_collection import ObjectCollection
     9  
    10  
    11  # pylint: disable=unused-variable,too-few-public-methods
    12  class ObjectRange(ObjectCollection):
    13      """
    14      Class representing a range of object names
    15  
    16      Args:
    17          prefix (str): Prefix contained in all names of objects
    18          min_index (int): Starting index in the name of objects
    19          max_index (int): Last index in the name of all objects
    20          pad_width (int, optional): Left-pad indices with zeros up to the width provided, e.g. pad_width = 3 will
    21              transform 1 to 001
    22          step (int, optional): Size of iterator steps between each item
    23          suffix (str, optional): Suffix at the end of all object names
    24      """
    25  
    26      # pylint: disable=too-many-arguments
    27      def __init__(
    28          self,
    29          prefix: str,
    30          min_index: int = None,
    31          max_index: int = None,
    32          pad_width: int = 0,
    33          step: int = 1,
    34          suffix: str = "",
    35      ):
    36          self._prefix = prefix
    37          self._step = step
    38          self._suffix = suffix
    39          self._validate_indices(min_index, max_index, pad_width)
    40          min_set = isinstance(min_index, int)
    41          if self._suffix and not min_set:
    42              raise ValueError("Suffix cannot be used without indices")
    43          self._min_index = str(min_index).zfill(pad_width) if min_set else None
    44          self._max_index = (
    45              str(max_index).zfill(pad_width) if isinstance(min_index, int) else None
    46          )
    47  
    48      @staticmethod
    49      def _validate_indices(min_index, max_index, pad_width):
    50          """
    51          Validate the indices passed to create a range: min_index < max_index and pad_width (if set) can fit the indices
    52              provided.
    53  
    54          Raises:
    55              InvalidObjectRangeIndex: If the indices passed to the range are not valid
    56          """
    57          indices = [isinstance(min_index, int), isinstance(max_index, int)]
    58          if not all(indices):
    59              if any(indices):
    60                  raise InvalidObjectRangeIndex(
    61                      "Provide both min_index and max_index or neither"
    62                  )
    63              return
    64  
    65          if min_index >= max_index:
    66              raise InvalidObjectRangeIndex(f"{min_index} must be less than {max_index}")
    67          if pad_width != 0 and len(str(min_index)) > pad_width:
    68              raise InvalidObjectRangeIndex(
    69                  f"Number of digits in min index {min_index} must not be greater than pad width {pad_width}"
    70              )
    71  
    72      def _indices_set(self) -> bool:
    73          if all([self._min_index, self._max_index]):
    74              return True
    75          return False
    76  
    77      def __str__(self) -> str:
    78          if self._indices_set():
    79              return f"{self._prefix}{{{self._min_index}..{self._max_index}..{self._step}}}{self._suffix}"
    80          return f"{self._prefix}"
    81  
    82      def __iter__(self) -> Iterator[str]:
    83          if not self._indices_set():
    84              raise RuntimeError("Cannot iterate over object range with no indices")
    85          return utils.expand_braces(str(self))
    86  
    87      def get_value(self):
    88          return {"template": str(self)}