def append(self, value: tp.Hashable) -> None: '''append a value ''' if self.__contains__(value): #type: ignore raise KeyError(f'duplicate key append attempted: {value}') # we might need to initialize map if not an increment that keeps loc_is_iloc relationship initialize_map = False if self._map is None: # loc_is_iloc if not (isinstance(value, INT_TYPES) and value == self._positions_mutable_count): initialize_map = True else: self._map.add(value) if self._labels_mutable_dtype is not None: self._labels_mutable_dtype = resolve_dtype( np.array(value).dtype, self._labels_mutable_dtype) else: self._labels_mutable_dtype = np.array(value).dtype self._labels_mutable.append(value) if initialize_map: self._map = AutoMap(self._labels_mutable) self._positions_mutable_count += 1 self._recache = True
def test_auto_map___contains__(keys: FrozenSet[Hashable], others: FrozenSet[Hashable]): a = AutoMap(keys) for key in keys: assert key in a others -= keys for key in others: assert key not in a
def test_auto_map___getitem__(keys: FrozenSet[Hashable], others: FrozenSet[Hashable]): a = AutoMap(keys) for index, key in enumerate(keys): assert a[key] == index others -= keys for key in others: with raises(KeyError): a[key]
def test_auto_map___contains__(keys: FrozenSet[CompositeAtom], others: FrozenSet[CompositeAtom]): a = AutoMap(keys) for key in keys: assert key in a others -= keys for key in others: assert key not in a
def test_issue_3(keys: FrozenSet[Hashable], key: Hashable): assume(key not in keys) a = AutoMap(keys) a |= (key,) with raises(KeyError): a |= (key,)
def test_auto_map___iter__(keys: FrozenSet[Hashable]): assert [*AutoMap(keys)] == [*keys]
def test_auto_map___len__(keys: FrozenSet[Hashable]): assert len(AutoMap(keys)) == len(keys)
def test_pickle(keys: FrozenSet[CompositeAtom]): assume(loads(dumps(keys)) == keys) a = AutoMap(keys) assert loads(dumps(a)) == a
def test_issue_3(keys: FrozenSet[CompositeAtom], key: CompositeAtom): assume(key not in keys) a = AutoMap(keys) a |= (key, ) with raises(ValueError): a |= (key, )
def test_auto_map_add(keys: FrozenSet[CompositeAtom]): a = AutoMap() for l, key in enumerate(keys): assert a.add(key) is None assert len(a) == l + 1 assert a[key] == l
def test_auto_map___reversed__(keys: FrozenSet[CompositeAtom]): assert [*reversed(AutoMap(keys))] == [*reversed([*keys])]
def test_auto_map___iter__(keys: FrozenSet[CompositeAtom]): assert [*AutoMap(keys)] == [*keys]
def test_auto_map___len__(keys: FrozenSet[CompositeAtom]): assert len(AutoMap(keys)) == len(keys)
def __init__(self, labels: IndexInitializer, *, loc_is_iloc: bool = False, name: NameType = NAME_DEFAULT, dtype: DtypeSpecifier = None) -> None: self._recache: bool = False self._map: tp.Optional[FrozenAutoMap] = None positions = None is_typed = self._DTYPE is not None # resolve the targetted labels dtype, by lookin at the class attr _DTYPE and/or the passed dtype argument if dtype is None: dtype_extract = self._DTYPE # set in some specialized Index classes else: # passed dtype is not None if is_typed and dtype != self._DTYPE: # NOTE: should never get to this branch, as derived Index classes that set _DTYPE remove dtype from __init__ raise ErrorInitIndex('invalid dtype argument for this Index', dtype, self._DTYPE) #pragma: no cover # self._DTYPE is None, passed dtype is not None, use dtype dtype_extract = dtype #----------------------------------------------------------------------- # handle all Index subclasses if isinstance(labels, IndexBase): if labels._recache: labels._update_array_cache() if name is NAME_DEFAULT: name = labels.name # immutable, so no copy necessary if isinstance(labels, Index): # not an IndexHierarchy if (labels.STATIC and self.STATIC and dtype is None): if not is_typed or (is_typed and self._DTYPE == labels.dtype): # can take the map if static and if types in the dict are the same as those in the labels (or to become the labels after conversion) self._map = labels._map # get a reference to the immutable arrays, even if this is an IndexGO index, we can take the cached arrays, assuming they are up to date; for datetime64 indices, we might need to translate to a different type positions = labels._positions loc_is_iloc = labels._map is None labels = labels._labels else: # IndexHierarchy # will be a generator of tuples; already updated caches labels = array2d_to_tuples(labels.__iter__()) elif isinstance(labels, ContainerOperand): # it is a Series or similar array = labels.values if array.ndim == 1: labels = array else: labels = array2d_to_tuples(array) # else: assume an iterable suitable for labels usage #----------------------------------------------------------------------- if is_typed: # do not need to check arrays, as will and checked to match dtype_extract in _extract_labels if not isinstance(labels, np.ndarray): # for now, assume that if _DTYPE is defined, we have a date labels = (to_datetime64(v, dtype_extract) for v in labels) # coerce to target type elif labels.dtype != dtype_extract: labels = labels.astype(dtype_extract) labels.flags.writeable = False #type: ignore self._name = None if name is NAME_DEFAULT else name_filter(name) if self._map is None: # if _map not shared from another Index if not loc_is_iloc: try: self._map = FrozenAutoMap( labels) if self.STATIC else AutoMap(labels) except ValueError: # Automap will raise ValueError of non-unique values are encountered pass if self._map is None: raise ErrorInitIndex( f'labels ({len(tuple(labels))}) have non-unique values ({len(set(labels))})' ) size = len(self._map) else: # must assume labels are unique # labels must not be a generator, but we assume that internal clients that provided loc_is_iloc will not give a generator size = len(labels) #type: ignore if positions is None: positions = PositionsAllocator.get(size) else: # map shared from another Index size = len(self._map) # this might be NP array, or a list, depending on if static or grow only; if an array, dtype will be compared with passed dtype_extract self._labels = self._extract_labels(self._map, labels, dtype_extract) self._positions = self._extract_positions(size, positions) if self._DTYPE and self._labels.dtype != self._DTYPE: raise ErrorInitIndex( 'invalid label dtype for this Index', #pragma: no cover self._labels.dtype, self._DTYPE)