# Buggy code
def maybe_cast_to_datetime(value, dtype, errors: str = "raise"):
    """
    try to cast the array/value to a datetimelike dtype, converting float
    nan to iNaT
    """
    from pandas.core.tools.timedeltas import to_timedelta
    from pandas.core.tools.datetimes import to_datetime

    if dtype is not None:
        if isinstance(dtype, str):
            dtype = np.dtype(dtype)

        is_datetime64 = is_datetime64_dtype(dtype)
        is_datetime64tz = is_datetime64tz_dtype(dtype)
        is_timedelta64 = is_timedelta64_dtype(dtype)

        if is_datetime64 or is_datetime64tz or is_timedelta64:
            # Force the dtype if needed.
            msg = (
                f"The '{dtype.name}' dtype has no unit. "
                f"Please pass in '{dtype.name}[ns]' instead."
            )

            if is_datetime64 and not is_dtype_equal(dtype, DT64NS_DTYPE):
                # pandas supports dtype whose granularity is less than [ns]
                # e.g., [ps], [fs], [as]
                if dtype <= np.dtype("M8[ns]"):
                    if dtype.name == "datetime64":
                        raise ValueError(msg)
                    dtype = DT64NS_DTYPE
                else:
                    raise TypeError(f"cannot convert datetimelike to dtype [{dtype}]")
            elif is_datetime64tz:
                # our NaT doesn't support tz's
                # this will coerce to DatetimeIndex with
                # a matching dtype below
                if is_scalar(value) and isna(value):
                    value = [value]

            elif is_timedelta64 and not is_dtype_equal(dtype, TD64NS_DTYPE):
                # pandas supports dtype whose granularity is less than [ns]
                # e.g., [ps], [fs], [as]
                if dtype <= np.dtype("m8[ns]"):
                    if dtype.name == "timedelta64":
                        raise ValueError(msg)
                    dtype = TD64NS_DTYPE
                else:
                    raise TypeError(f"cannot convert timedeltalike to dtype [{dtype}]")

            if is_scalar(value):
                if value == iNaT or isna(value):
                    value = iNaT
            else:
                value = np.array(value, copy=False)

                # have a scalar array-like (e.g. NaT)
                if value.ndim == 0:
                    value = iNaT

                # we have an array of datetime or timedeltas & nulls
                elif np.prod(value.shape) or not is_dtype_equal(value.dtype, dtype):
                    try:
                        if is_datetime64:
                            value = to_datetime(value, errors=errors)
                            # GH 25843: Remove tz information since the dtype
                            # didn't specify one
                            if value.tz is not None:
                                value = value.tz_localize(None)
                            value = value._values
                        elif is_datetime64tz:
                            # The string check can be removed once issue #13712
                            # is solved. String data that is passed with a
                            # datetime64tz is assumed to be naive which should
                            # be localized to the timezone.
                            is_dt_string = is_string_dtype(value)
                            value = to_datetime(value, errors=errors).array
                            if is_dt_string:
                                # Strings here are naive, so directly localize
                                value = value.tz_localize(dtype.tz)
                            else:
                                # Numeric values are UTC at this point,
                                # so localize and convert
                                value = value.tz_localize("UTC").tz_convert(dtype.tz)
                        elif is_timedelta64:
                            value = to_timedelta(value, errors=errors)._values
                    except OutOfBoundsDatetime:
                        raise
                    except (AttributeError, ValueError, TypeError):
                        pass

        # coerce datetimelike to object
        elif is_datetime64_dtype(value) and not is_datetime64_dtype(dtype):
            if is_object_dtype(dtype):
                if value.dtype != DT64NS_DTYPE:
                    value = value.astype(DT64NS_DTYPE)
                ints = np.asarray(value).view("i8")
                return tslib.ints_to_pydatetime(ints)

            # we have a non-castable dtype that was passed
            raise TypeError(f"Cannot cast datetime64 to {dtype}")

    else:
        is_array = isinstance(value, np.ndarray)

        # catch a datetime/timedelta that is not of ns variety
        # and no coercion specified
        if is_array and value.dtype.kind in ["M", "m"]:
            dtype = value.dtype

            if dtype.kind == "M" and dtype != DT64NS_DTYPE:
                value = tslibs.conversion.ensure_datetime64ns(value)

            elif dtype.kind == "m" and dtype != TD64NS_DTYPE:
                value = to_timedelta(value)

        # only do this if we have an array and the dtype of the array is not
        # setup already we are not an integer/object, so don't bother with this
        # conversion
        elif not (
            is_array
            and not (
                issubclass(value.dtype.type, np.integer) or value.dtype == np.object_
            )
        ):
            value = maybe_infer_to_datetimelike(value)

    return value


# Traceback (TypeError)
In [8]: pd.Series(None, index=[1, 2, 3], dtype='Int64')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
~/scipy/pandas/pandas/core/internals/construction.py in _try_cast(arr, take_fast_path, dtype, copy, raise_cast_failure)
691         if is_integer_dtype(dtype):
--> 692             subarr = maybe_cast_to_integer_array(arr, dtype)
693

~/scipy/pandas/pandas/core/dtypes/cast.py in maybe_cast_to_integer_array(arr, dtype, copy)
1311         if not hasattr(arr, "astype"):
-> 1312             casted = np.array(arr, dtype=dtype, copy=copy)
1313         else:

TypeError: data type not understood

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
<ipython-input-8-9447295feee6> in <module>
----> 1 pd.Series(None, index=[1, 2, 3], dtype='Int64')

~/scipy/pandas/pandas/core/series.py in __init__(self, data, index, dtype, name, copy, fastpath)
202                 data = data._data
203             elif isinstance(data, dict):
--> 204                 data, index = self._init_dict(data, index, dtype)
205                 dtype = None
206                 copy = False

~/scipy/pandas/pandas/core/series.py in _init_dict(self, data, index, dtype)
295
296         # Input is now list-like, so rely on "standard" construction:
--> 297         s = Series(values, index=keys, dtype=dtype)
298
299         # Now we just make sure the order is respected, if any

~/scipy/pandas/pandas/core/series.py in __init__(self, data, index, dtype, name, copy, fastpath)
253             else:
254                 data = sanitize_array(data, index, dtype, copy,
--> 255                                       raise_cast_failure=True)
256
257                 data = SingleBlockManager(data, index, fastpath=True)

~/scipy/pandas/pandas/core/internals/construction.py in sanitize_array(data, index, dtype, copy, raise_cast_failure)
620         subarr = _try_cast(arr, False, dtype, copy, raise_cast_failure)
621     else:
--> 622         subarr = _try_cast(data, False, dtype, copy, raise_cast_failure)
623
624     # scalar like, GH

~/scipy/pandas/pandas/core/internals/construction.py in _try_cast(arr, take_fast_path, dtype, copy, raise_cast_failure)
711             # create an extension array from its dtype
712             array_type = dtype.construct_array_type()._from_sequence
--> 713             subarr = array_type(arr, dtype=dtype, copy=copy)
714         elif dtype is not None and raise_cast_failure:
715             raise

~/scipy/pandas/pandas/core/arrays/integer.py in _from_sequence(cls, scalars, dtype, copy)
305     @classmethod
306     def _from_sequence(cls, scalars, dtype=None, copy=False):
--> 307         return integer_array(scalars, dtype=dtype, copy=copy)
308
309     @classmethod

~/scipy/pandas/pandas/core/arrays/integer.py in integer_array(values, dtype, copy)
110     TypeError if incompatible types
111     """
--> 112     values, mask = coerce_to_array(values, dtype=dtype, copy=copy)
113     return IntegerArray(values, mask)
114

~/scipy/pandas/pandas/core/arrays/integer.py in coerce_to_array(values, dtype, mask, copy)
202
203     if not values.ndim == 1:
--> 204         raise TypeError("values must be a 1D list-like")
205     if not mask.ndim == 1:
206         raise TypeError("mask must be a 1D list-like")

TypeError: values must be a 1D list-like

# Fixed code
def maybe_cast_to_datetime(value, dtype, errors: str = "raise"):
    """
    try to cast the array/value to a datetimelike dtype, converting float
    nan to iNaT
    """
    from pandas.core.tools.timedeltas import to_timedelta
    from pandas.core.tools.datetimes import to_datetime

    if dtype is not None:
        if isinstance(dtype, str):
            dtype = np.dtype(dtype)

        is_datetime64 = is_datetime64_dtype(dtype)
        is_datetime64tz = is_datetime64tz_dtype(dtype)
        is_timedelta64 = is_timedelta64_dtype(dtype)

        if is_datetime64 or is_datetime64tz or is_timedelta64:
            # Force the dtype if needed.
            msg = (
                f"The '{dtype.name}' dtype has no unit. "
                f"Please pass in '{dtype.name}[ns]' instead."
            )

            if is_datetime64 and not is_dtype_equal(dtype, DT64NS_DTYPE):
                # pandas supports dtype whose granularity is less than [ns]
                # e.g., [ps], [fs], [as]
                if dtype <= np.dtype("M8[ns]"):
                    if dtype.name == "datetime64":
                        raise ValueError(msg)
                    dtype = DT64NS_DTYPE
                else:
                    raise TypeError(f"cannot convert datetimelike to dtype [{dtype}]")
            elif is_datetime64tz:
                # our NaT doesn't support tz's
                # this will coerce to DatetimeIndex with
                # a matching dtype below
                if is_scalar(value) and isna(value):
                    value = [value]

            elif is_timedelta64 and not is_dtype_equal(dtype, TD64NS_DTYPE):
                # pandas supports dtype whose granularity is less than [ns]
                # e.g., [ps], [fs], [as]
                if dtype <= np.dtype("m8[ns]"):
                    if dtype.name == "timedelta64":
                        raise ValueError(msg)
                    dtype = TD64NS_DTYPE
                else:
                    raise TypeError(f"cannot convert timedeltalike to dtype [{dtype}]")

            if is_scalar(value):
                if value == iNaT or isna(value):
                    value = iNaT
            else:
                value = np.array(value, copy=False)

                # have a scalar array-like (e.g. NaT)
                if value.ndim == 0:
                    value = iNaT

                # we have an array of datetime or timedeltas & nulls
                elif np.prod(value.shape) or not is_dtype_equal(value.dtype, dtype):
                    try:
                        if is_datetime64:
                            value = to_datetime(value, errors=errors)
                            # GH 25843: Remove tz information since the dtype
                            # didn't specify one
                            if value.tz is not None:
                                value = value.tz_localize(None)
                            value = value._values
                        elif is_datetime64tz:
                            # The string check can be removed once issue #13712
                            # is solved. String data that is passed with a
                            # datetime64tz is assumed to be naive which should
                            # be localized to the timezone.
                            is_dt_string = is_string_dtype(value)
                            value = to_datetime(value, errors=errors).array
                            if is_dt_string:
                                # Strings here are naive, so directly localize
                                value = value.tz_localize(dtype.tz)
                            else:
                                # Numeric values are UTC at this point,
                                # so localize and convert
                                value = value.tz_localize("UTC").tz_convert(dtype.tz)
                        elif is_timedelta64:
                            value = to_timedelta(value, errors=errors)._values
                    except OutOfBoundsDatetime:
                        raise
                    except (AttributeError, ValueError, TypeError):
                        pass

        # coerce datetimelike to object
        elif is_datetime64_dtype(
            getattr(value, "dtype", None)
        ) and not is_datetime64_dtype(dtype):
            if is_object_dtype(dtype):
                if value.dtype != DT64NS_DTYPE:
                    value = value.astype(DT64NS_DTYPE)
                ints = np.asarray(value).view("i8")
                return tslib.ints_to_pydatetime(ints)

            # we have a non-castable dtype that was passed
            raise TypeError(f"Cannot cast datetime64 to {dtype}")

    else:
        is_array = isinstance(value, np.ndarray)

        # catch a datetime/timedelta that is not of ns variety
        # and no coercion specified
        if is_array and value.dtype.kind in ["M", "m"]:
            dtype = value.dtype

            if dtype.kind == "M" and dtype != DT64NS_DTYPE:
                value = tslibs.conversion.ensure_datetime64ns(value)

            elif dtype.kind == "m" and dtype != TD64NS_DTYPE:
                value = to_timedelta(value)

        # only do this if we have an array and the dtype of the array is not
        # setup already we are not an integer/object, so don't bother with this
        # conversion
        elif not (
            is_array
            and not (
                issubclass(value.dtype.type, np.integer) or value.dtype == np.object_
            )
        ):
            value = maybe_infer_to_datetimelike(value)

    return value