@@ -0,0 +1,3087 @@
+from __future__ import annotations%0A%0Aimport numpy as np%0Aimport pyarrow as pa%0A%0Afrom pandas._typing import DtypeObj%0Afrom pandas.util._decorators import cache_readonly%0A%0Afrom pandas.core.dtypes.base import StorageExtensionDtype%0A%0Afrom pandas.core.arrays.arrow import ArrowExtensionArray%0A%0A%0Aclass ArrowDtype(StorageExtensionDtype):%0A    %22%22%22%0A    Base class for dtypes for BaseArrowArray subclasses.%0A    Modeled after BaseMaskedDtype%0A    %22%22%22%0A%0A    name: str%0A    base = None%0A    type: pa.DataType%0A%0A    na_value = pa.NA%0A%0A    def __init__(self, storage=%22pyarrow%22) -%3E None:%0A        super().__init__(storage)%0A%0A    @cache_readonly%0A    def numpy_dtype(self) -%3E np.dtype:%0A        %22%22%22Return an instance of the related numpy dtype%22%22%22%0A        return self.type.to_pandas_dtype()%0A%0A    @cache_readonly%0A    def kind(self) -%3E str:%0A        return self.numpy_dtype.kind%0A%0A    @cache_readonly%0A    def itemsize(self) -%3E int:%0A        %22%22%22Return the number of bytes in this dtype%22%22%22%0A        return self.numpy_dtype.itemsize%0A%0A    @classmethod%0A    def construct_array_type(cls):%0A        %22%22%22%0A        Return the array type associated with this dtype.%0A%0A        Returns%0A        -------%0A        type%0A        %22%22%22%0A        return ArrowExtensionArray%0A%0A    @classmethod%0A    def construct_from_string(cls, string: str):%0A        %22%22%22%0A        Construct this type from a string.%0A%0A        Parameters%0A        ----------%0A        string : str%0A        %22%22%22%0A        if not isinstance(string, str):%0A            raise TypeError(%0A                f%22'construct_from_string' expects a string, got %7Btype(string)%7D%22%0A            )%0A        if string == f%22%7Bcls.name%7D%5Bpyarrow%5D%22:%0A            return cls(storage=%22pyarrow%22)%0A        raise TypeError(f%22Cannot construct a '%7Bcls.__name__%7D' from '%7Bstring%7D'%22)%0A%0A    @classmethod%0A    def from_numpy_dtype(cls, dtype: np.dtype) -%3E ArrowDtype:%0A        %22%22%22%0A        Construct the ArrowDtype corresponding to the given numpy dtype.%0A        %22%22%22%0A        # TODO: This may be incomplete%0A        pa_dtype = pa.from_numpy_dtype(dtype)%0A        if pa_dtype is cls.type:%0A            return cls()%0A        raise NotImplementedError(dtype)%0A%0A    def _get_common_dtype(self, dtypes: list%5BDtypeObj%5D) -%3E DtypeObj %7C None:%0A        # We unwrap any masked dtypes, find the common dtype we would use%0A        #  for that, then re-mask the result.%0A        from pandas.core.dtypes.cast import find_common_type%0A%0A        new_dtype = find_common_type(%0A            %5B%0A                dtype.numpy_dtype if isinstance(dtype, ArrowDtype) else dtype%0A                for dtype in dtypes%0A            %5D%0A        )%0A        if not isinstance(new_dtype, np.dtype):%0A            # If we ever support e.g. Masked%5BDatetimeArray%5D then this will change%0A            return None%0A        try:%0A            return type(self).from_numpy_dtype(new_dtype)%0A        except (KeyError, NotImplementedError):%0A            return None%0A%0A    def __from_arrow__(self, array: pa.Array %7C pa.ChunkedArray):%0A        %22%22%22%0A        Construct IntegerArray/FloatingArray from pyarrow Array/ChunkedArray.%0A        %22%22%22%0A        array_class = self.construct_array_type()%0A        return array_class(array)%0A

Create ArrowDtype (#46774)