Skip to main content
`Ctrl`+`K`

# Source code for astropy.utils.metadata.utils

    # Licensed under a 3-clause BSD style license - see LICENSE.rst
    """This module contains helper functions handling metadata."""

    import numpy as np

    from .exceptions import MergeConflictError

    __all__ = ["common_dtype"]

    def dtype(arr):
        return getattr(arr, "dtype", np.dtype("O"))

    def common_dtype(arrs):
        """
        Use numpy to find the common dtype for a list of ndarrays.

        Only allow arrays within the following fundamental numpy data types:
        ``np.bool_``, ``np.object_``, ``np.number``, ``np.character``, ``np.void``

        Parameters
        ----------
        arrs : list of ndarray
            Arrays for which to find the common dtype

        Returns
        -------
        dtype_str : str
            String representation of dytpe (dtype ``str`` attribute)
        """
        dt = result_type(arrs)
        return dt.str if dt.names is None else dt.descr

    def result_type(arrs):
        """
        Use numpy to find the common type for a list of ndarray.

        The difference with `numpy.result_type` is that all arrays should
        share the same fundamental numpy data type, one of:
        ``np.bool_``, ``np.object_``, ``np.number``, ``np.character``, ``np.void``
        Hence, a mix like integer and string will raise instead of resulting
        in a string type.

        Parameters
        ----------
        arrs : list of ndarray
            Array likes for which to find the common dtype. Anything not
            an array (e.g, |Time|), will be considered an object array.

        Returns
        -------
        dtype : ~numpy.dtype
            The common type.
        """
        dtypes = [dtype(arr) for arr in arrs]
        np_types = (np.bool_, np.object_, np.number, np.character, np.void)
        uniq_types = {
            tuple(issubclass(dt.type, np_type) for np_type in np_types) for dt in dtypes
        }
        if len(uniq_types) > 1:
            # Embed into the exception the actual list of incompatible types.
            incompat_types = [dt.name for dt in dtypes]
            tme = MergeConflictError(f"Arrays have incompatible types {incompat_types}")
            tme._incompat_types = incompat_types
            raise tme

        return np.result_type(*dtypes)