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)}