def as_compatible_data(
    data: T_DuckArray | ArrayLike, fastpath: bool = False
) -> T_DuckArray:
    """Prepare and wrap data to put in a Variable.

    - If data does not have the necessary attributes, convert it to ndarray.
    - If it's a pandas.Timestamp, convert it to datetime64.
    - If data is already a pandas or xarray object (other than an Index), just
      use the values.

    Finally, wrap it up with an adapter if necessary.
    """
    if fastpath and getattr(data, "ndim", None) is not None:
        return cast("T_DuckArray", data)

    from xarray.core.dataarray import DataArray

    # TODO: do this uwrapping in the Variable/NamedArray constructor instead.
    if isinstance(data, Variable):
        return cast("T_DuckArray", data._data)

    # TODO: do this uwrapping in the DataArray constructor instead.
    if isinstance(data, DataArray):
        return cast("T_DuckArray", data._variable._data)

    def convert_non_numpy_type(data):
        return cast("T_DuckArray", _maybe_wrap_data(data))

    if isinstance(data, NON_NUMPY_SUPPORTED_ARRAY_TYPES):
        return convert_non_numpy_type(data)

    if isinstance(data, tuple):
        data = utils.to_0d_object_array(data)

    # we don't want nested self-described arrays
    if isinstance(data, pd.Series | pd.DataFrame):
        if (
            isinstance(data, pd.Series)
            and pd.api.types.is_extension_array_dtype(data)
            and not isinstance(data.array, UNSUPPORTED_EXTENSION_ARRAY_TYPES)
        ):
            pandas_data = data.array
        else:
            pandas_data = data.values  # type: ignore[assignment]
        if isinstance(pandas_data, NON_NUMPY_SUPPORTED_ARRAY_TYPES):
            return convert_non_numpy_type(pandas_data)
        else:
            data = pandas_data

    if isinstance(data, np.ma.MaskedArray):
        mask = np.ma.getmaskarray(data)
        if mask.any():
            dtype, fill_value = dtypes.maybe_promote(data.dtype)
            data = duck_array_ops.where_method(data, ~mask, fill_value)
        else:
            data = np.asarray(data)

    if isinstance(data, np.matrix):
        data = np.asarray(data)

    # immediately return array-like types except `numpy.ndarray` and `numpy` scalars
    # compare types with `is` instead of `isinstance` to allow `numpy.ndarray` subclasses
    is_numpy = type(data) is np.ndarray or isinstance(data, np.generic)
    if not is_numpy and (
        hasattr(data, "__array_function__") or hasattr(data, "__array_namespace__")
    ):
        return cast("T_DuckArray", data)

    # anything left will be converted to `numpy.ndarray`, including `numpy` scalars
    data = np.asarray(data)

    if data.dtype.kind in "OMm":
        data = _possibly_convert_objects(data)
    return _maybe_wrap_data(data)
Prepare and wrap data to put in a Variable.

    - If data does not have the necessary attributes, convert it to ndarray.
    - If it's a pandas.Timestamp, convert it to datetime64.
    - If data is already a pandas or xarray object (other than an Index), just
      use the values.

    Finally, wrap it up with an adapter if necessary.
    
xarray/core/variable.py