Repository: pandas-dev/pandas
File: pandas/core/arrays/base.py (Python)

Code before:
        # on a copy of the data.
        # Check if the array is readonly
        if self._readonly:
            raise ValueError("Cannot modify read-only array")

        raise NotImplementedError(f"{type(self)} does not implement __setitem__.")

    def __len__(self) -> int:
        """
        Length of this array

        Returns
        -------
        length : int
        """
        raise AbstractMethodError(self)

    def item(self, *args):
        """
        Return the array element at the specified position as a Python scalar.

        Parameters
        ----------
        *args : int, optional
            Position of the element. If not provided, the array must contain
            exactly one element.

        Returns
        -------
        scalar
            The element at the specified position.

        Raises
        ------
        ValueError
            If no arguments are provided and the array does not have exactly
            one element.
        IndexError
            If the specified position is out of bounds.

        See Also
        --------
        numpy.ndarray.item : Return the item of an array as a scalar.

        Examples
        --------
        >>> arr = pd.array([1], dtype="Int64")
        >>> arr.item()
        np.int64(1)

        >>> arr = pd.array([1, 2, 3], dtype="Int64")

Review comment (suggestion):
I can see why this was done for consistency with NumPy arguments, but I don't see any downside to just accepting a single optional int. I think we should do that instead.

Code after:
        #   __init__ method coerces that value, then so should __setitem__
        # Note, also, that Series/DataFrame.where internally use __setitem__
        # on a copy of the data.
        # Check if the array is readonly
        if self._readonly:
            raise ValueError("Cannot modify read-only array")

        raise NotImplementedError(f"{type(self)} does not implement __setitem__.")

    def __len__(self) -> int:
        """
        Length of this array

        Returns
        -------
        length : int
        """
        raise AbstractMethodError(self)

    def __iter__(self) -> Iterator[Any]:
        """
        Iterate over elements of the array.
        """
        # This needs to be implemented so that pandas recognizes extension
        # arrays as list-like. The default implementation makes successive
        # calls to ``__getitem__``, which may be slower than necessary.
        for i in range(len(self)):
            yield self[i]

    def __contains__(self, item: object) -> bool | np.bool_:
        """
        Return for `item in self`.
        """
        # GH37867
        # comparisons of any item to pd.NA always return pd.NA, so e.g. "a" in [pd.NA]
        # would raise a TypeError. The implementation below works around that.
        if is_scalar(item) and isna(item):
            if not self._can_hold_na:
                return False
            elif item is self.dtype.na_value or isinstance(item, self.dtype.type):
                return self._hasna
            else:
                return False
        else:
            # error: Item "ExtensionArray" of "Union[ExtensionArray, ndarray]" has no
            # attribute "any"
            return (item == self).any()  # type: ignore[union-attr]

    # error: Signature of "__eq__" incompatible with supertype "object"
    def __eq__(self, other: object) -> ArrayLike:  # type: ignore[override]
        """