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

Code before:
        compatibility with ArrowStringArray.
        """
        return type(self)(pa_array)

    def _cast_pointwise_result(self, values) -> ArrayLike:
        if len(values) == 0:
            # Retain our dtype
            return self[:0].copy()

        try:
            if self.dtype.kind in "iufc" and not is_nan_na():
                values = np.asarray(values, dtype=object)
                mask = is_pdna_or_none(values)
                arr = pa.array(values, mask=mask)
            else:
                arr = pa.array(values, from_pandas=True)
        except (ValueError, TypeError):
            # e.g. test_by_column_values_with_same_starting_value with nested
            #  values, one entry of which is an ArrowStringArray
            #  or test_agg_lambda_complex128_dtype_conversion for complex values
            return super()._cast_pointwise_result(values)

        if pa.types.is_null(arr.type):
            if lib.infer_dtype(values) == "decimal":
                # GH#62522; the specific decimal precision here is arbitrary
                arr = arr.cast(pa.decimal32(1))
        if pa.types.is_duration(arr.type):
            # workaround for https://github.com/apache/arrow/issues/40620
            result = ArrowExtensionArray._from_sequence(values)
            if pa.types.is_duration(self._pa_array.type):
                result = result.astype(self.dtype)  # type: ignore[assignment]
            elif pa.types.is_timestamp(self._pa_array.type):
                # Try to retain original unit
                new_dtype = ArrowDtype(pa.duration(self._pa_array.type.unit))
                try:
                    result = result.astype(new_dtype)  # type: ignore[assignment]
                except ValueError:
                    pass
            elif pa.types.is_date64(self._pa_array.type):
                # Try to match unit we get on non-pointwise op
                dtype = ArrowDtype(pa.duration("ms"))
                result = result.astype(dtype)  # type: ignore[assignment]
            elif pa.types.is_date(self._pa_array.type):
                # Try to match unit we get on non-pointwise op
                dtype = ArrowDtype(pa.duration("s"))
                result = result.astype(dtype)  # type: ignore[assignment]
            return result

        elif pa.types.is_date(arr.type) and pa.types.is_date(self._pa_array.type):
            arr = arr.cast(self._pa_array.type)
        elif pa.types.is_time(arr.type) and pa.types.is_time(self._pa_array.type):

Review comment (bug):
While it would be nice to use a smaller 32 bit-width here, this API is only available in PyArrow 19 (evident by the xfail). I think we'll need to use `decimal128` for our version compatibility.

Code after:
        compatibility with ArrowStringArray.
        """
        return type(self)(pa_array)

    def _cast_pointwise_result(self, values) -> ArrayLike:
        if len(values) == 0:
            # Retain our dtype
            return self[:0].copy()

        try:
            if self.dtype.kind in "iufc" and not is_nan_na():
                values = np.asarray(values, dtype=object)
                mask = is_pdna_or_none(values)
                arr = pa.array(values, mask=mask)
            else:
                arr = pa.array(values, from_pandas=True)
        except (ValueError, TypeError):
            # e.g. test_by_column_values_with_same_starting_value with nested
            #  values, one entry of which is an ArrowStringArray
            #  or test_agg_lambda_complex128_dtype_conversion for complex values
            return super()._cast_pointwise_result(values)

        if pa.types.is_null(arr.type):
            if lib.infer_dtype(values) == "decimal":
                # GH#62522; the specific decimal precision here is arbitrary
                arr = arr.cast(pa.decimal128(1))
        if pa.types.is_duration(arr.type):
            # workaround for https://github.com/apache/arrow/issues/40620
            result = ArrowExtensionArray._from_sequence(values)
            if pa.types.is_duration(self._pa_array.type):
                result = result.astype(self.dtype)  # type: ignore[assignment]
            elif pa.types.is_timestamp(self._pa_array.type):
                # Try to retain original unit
                new_dtype = ArrowDtype(pa.duration(self._pa_array.type.unit))
                try:
                    result = result.astype(new_dtype)  # type: ignore[assignment]
                except ValueError:
                    pass
            elif pa.types.is_date64(self._pa_array.type):
                # Try to match unit we get on non-pointwise op
                dtype = ArrowDtype(pa.duration("ms"))
                result = result.astype(dtype)  # type: ignore[assignment]
            elif pa.types.is_date(self._pa_array.type):
                # Try to match unit we get on non-pointwise op
                dtype = ArrowDtype(pa.duration("s"))
                result = result.astype(dtype)  # type: ignore[assignment]
            return result

        elif pa.types.is_date(arr.type) and pa.types.is_date(self._pa_array.type):
            arr = arr.cast(self._pa_array.type)
        elif pa.types.is_time(arr.type) and pa.types.is_time(self._pa_array.type):