from __future__ import annotations from typing import TYPE_CHECKING import weakref if TYPE_CHECKING: from pandas.core.generic import NDFrame class Flags: """ Flags that apply to pandas objects. Parameters ---------- obj : Series or DataFrame The object these flags are associated with. allows_duplicate_labels : bool, default True Whether to allow duplicate labels in this object. By default, duplicate labels are permitted. Setting this to ``False`` will cause an :class:`errors.DuplicateLabelError` to be raised when `index` (or columns for DataFrame) is not unique, or any subsequent operation on introduces duplicates. See :ref:`duplicates.disallow` for more. .. warning:: This is an experimental feature. Currently, many methods fail to propagate the ``allows_duplicate_labels`` value. In future versions it is expected that every method taking or returning one or more DataFrame or Series objects will propagate ``allows_duplicate_labels``. Examples -------- Attributes can be set in two ways: >>> df = pd.DataFrame() >>> df.flags >>> df.flags.allows_duplicate_labels = False >>> df.flags >>> df.flags['allows_duplicate_labels'] = True >>> df.flags """ _keys: set[str] = {"allows_duplicate_labels"} def __init__(self, obj: NDFrame, *, allows_duplicate_labels: bool) -> None: self._allows_duplicate_labels = allows_duplicate_labels self._obj = weakref.ref(obj) @property def allows_duplicate_labels(self) -> bool: """ Whether this object allows duplicate labels. Setting ``allows_duplicate_labels=False`` ensures that the index (and columns of a DataFrame) are unique. Most methods that accept and return a Series or DataFrame will propagate the value of ``allows_duplicate_labels``. See :ref:`duplicates` for more. See Also -------- DataFrame.attrs : Set global metadata on this object. DataFrame.set_flags : Set global flags on this object. Examples -------- >>> df = pd.DataFrame({"A": [1, 2]}, index=['a', 'a']) >>> df.flags.allows_duplicate_labels True >>> df.flags.allows_duplicate_labels = False Traceback (most recent call last): ... pandas.errors.DuplicateLabelError: Index has duplicates. positions label a [0, 1] """ return self._allows_duplicate_labels @allows_duplicate_labels.setter def allows_duplicate_labels(self, value: bool) -> None: value = bool(value) obj = self._obj() if obj is None: raise ValueError("This flag's object has been deleted.") if not value: for ax in obj.axes: ax._maybe_check_unique() self._allows_duplicate_labels = value def __getitem__(self, key: str): if key not in self._keys: raise KeyError(key) return getattr(self, key) def __setitem__(self, key: str, value) -> None: if key not in self._keys: raise ValueError(f"Unknown flag {key}. Must be one of {self._keys}") setattr(self, key, value) def __repr__(self) -> str: return f"" def __eq__(self, other) -> bool: if isinstance(other, type(self)): return self.allows_duplicate_labels == other.allows_duplicate_labels return False