# Buggy code
def _astype(
    self, dtype, copy=False, errors="raise", values=None, klass=None, mgr=None, **kwargs
):
    """Coerce to the new type

    Parameters
    ----------
    dtype : str, dtype convertible
    copy : boolean, default False
        copy if indicated
    errors : str, {'raise', 'ignore'}, default 'ignore'
        - ``raise`` : allow exceptions to be raised
        - ``ignore`` : suppress exceptions. On error return original object

    Returns
    -------
    Block
    """
    errors_legal_values = ("raise", "ignore")

    if errors not in errors_legal_values:
        invalid_arg = (
            "Expected value of kwarg 'errors' to be one of {}. "
            "Supplied value is '{}'".format(list(errors_legal_values), errors)
        )
        raise ValueError(invalid_arg)

    if inspect.isclass(dtype) and issubclass(
        dtype, (PandasExtensionDtype, ExtensionDtype)
    ):
        msg = (
            "Expected an instance of {}, but got the class instead. "
            "Try instantiating 'dtype'.".format(dtype.__name__)
        )
        raise TypeError(msg)

    # may need to convert to categorical
    if self.is_categorical_astype(dtype):
        # deprecated 17636
        if "categories" in kwargs or "ordered" in kwargs:
            if isinstance(dtype, CategoricalDtype):
                raise TypeError(
                    "Cannot specify a CategoricalDtype and also "
                    "`categories` or `ordered`. Use "
                    "`dtype=CategoricalDtype(categories, ordered)`"
                    " instead."
                )
            warnings.warn(
                "specifying 'categories' or 'ordered' in "
                ".astype() is deprecated; pass a "
                "CategoricalDtype instead",
                FutureWarning,
                stacklevel=7,
            )

        categories = kwargs.get("categories", None)
        ordered = kwargs.get("ordered", None)
        if com._any_not_none(categories, ordered):
            dtype = CategoricalDtype(categories, ordered)

        if is_categorical_dtype(self.values):
            # GH 10696/18593: update an existing categorical efficiently
            return self.make_block(self.values.astype(dtype, copy=copy))

        return self.make_block(Categorical(self.values, dtype=dtype))

    # convert dtypes if needed
    dtype = pandas_dtype(dtype)

    # astype processing
    if is_dtype_equal(self.dtype, dtype):
        if copy:
            return self.copy()
        return self

    if klass is None:
        if dtype == np.object_:
            klass = ObjectBlock
    try:
        # force the copy here
        if values is None:
            if self.is_extension:
                values = self.values.astype(dtype)
            else:
                if issubclass(dtype.type, (compat.text_type, compat.string_types)):
                    # use native type formatting for datetime/tz/timedelta
                    if self.is_datelike:
                        values = self.to_native_types()

                    # astype formatting
                    else:
                        values = self.get_values()

                else:
                    values = self.get_values(dtype=dtype)

                # _astype_nansafe works fine with 1-d only
                values = astype_nansafe(values.ravel(), dtype, copy=True)

            # TODO(extension)
            # should we make this attribute?
            try:
                values = values.reshape(self.shape)
            except AttributeError:
                pass

        newb = make_block(values, placement=self.mgr_locs, klass=klass, ndim=self.ndim)
    except Exception:  # noqa: E722
        if errors == "raise":
            raise
        newb = self.copy() if copy else self

    if newb.is_numeric and self.is_numeric:
        if newb.shape != self.shape:
            raise TypeError(
                "cannot set astype for copy = [{copy}] for dtype "
                "({dtype} [{itemsize}]) with smaller itemsize than "
                "current ({newb_dtype} [{newb_size}])".format(
                    copy=copy,
                    dtype=self.dtype.name,
                    itemsize=self.itemsize,
                    newb_dtype=newb.dtype.name,
                    newb_size=newb.itemsize,
                )
            )
    return newb


# Traceback (AttributeError)
In [8]: df = pd.DataFrame([[1., 2.], [3., 4.], [5., 6.]], columns=['a', 'b'])

In [9]: df
Out[9]:
a    b
0  1.0  2.0
1  3.0  4.0
2  5.0  6.0

In [10]: df.astype('Int64')
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-10-b9d2763e69d8> in <module>()
----> 1 df.astype('Int64')

~/scipy/pandas/pandas/util/_decorators.py in wrapper(*args, **kwargs)
175                 else:
176                     kwargs[new_arg_name] = new_arg_value
--> 177             return func(*args, **kwargs)
178         return wrapper
179     return _deprecate_kwarg

~/scipy/pandas/pandas/core/generic.py in astype(self, dtype, copy, errors, **kwargs)
5162             # else, only a single dtype is given
5163             new_data = self._data.astype(dtype=dtype, copy=copy, errors=errors,
-> 5164                                          **kwargs)
5165             return self._constructor(new_data).__finalize__(self)
5166

~/scipy/pandas/pandas/core/internals/managers.py in astype(self, dtype, **kwargs)
554
555     def astype(self, dtype, **kwargs):
--> 556         return self.apply('astype', dtype=dtype, **kwargs)
557
558     def convert(self, **kwargs):

~/scipy/pandas/pandas/core/internals/managers.py in apply(self, f, axes, filter, do_integrity_check, consolidate, **kwargs)
421
422             kwargs['mgr'] = self
--> 423             applied = getattr(b, f)(**kwargs)
424             result_blocks = _extend_blocks(applied, result_blocks)
425

~/scipy/pandas/pandas/core/internals/blocks.py in astype(self, dtype, copy, errors, values, **kwargs)
562     def astype(self, dtype, copy=False, errors='raise', values=None, **kwargs):
563         return self._astype(dtype, copy=copy, errors=errors, values=values,
--> 564                             **kwargs)
565
566     def _astype(self, dtype, copy=False, errors='raise', values=None,

~/scipy/pandas/pandas/core/internals/blocks.py in _astype(self, dtype, copy, errors, values, klass, mgr, **kwargs)
679                     "current ({newb_dtype} [{newb_size}])".format(
680                         copy=copy, dtype=self.dtype.name,
--> 681                         itemsize=self.itemsize, newb_dtype=newb.dtype.name,
682                         newb_size=newb.itemsize))
683         return newb

AttributeError: 'FloatBlock' object has no attribute 'itemsize'

# Fixed code
def _astype(
    self, dtype, copy=False, errors="raise", values=None, klass=None, mgr=None, **kwargs
):
    """Coerce to the new type

    Parameters
    ----------
    dtype : str, dtype convertible
    copy : boolean, default False
        copy if indicated
    errors : str, {'raise', 'ignore'}, default 'ignore'
        - ``raise`` : allow exceptions to be raised
        - ``ignore`` : suppress exceptions. On error return original object

    Returns
    -------
    Block
    """
    errors_legal_values = ("raise", "ignore")

    if errors not in errors_legal_values:
        invalid_arg = (
            "Expected value of kwarg 'errors' to be one of {}. "
            "Supplied value is '{}'".format(list(errors_legal_values), errors)
        )
        raise ValueError(invalid_arg)

    if inspect.isclass(dtype) and issubclass(
        dtype, (PandasExtensionDtype, ExtensionDtype)
    ):
        msg = (
            "Expected an instance of {}, but got the class instead. "
            "Try instantiating 'dtype'.".format(dtype.__name__)
        )
        raise TypeError(msg)

    # may need to convert to categorical
    if self.is_categorical_astype(dtype):
        # deprecated 17636
        if "categories" in kwargs or "ordered" in kwargs:
            if isinstance(dtype, CategoricalDtype):
                raise TypeError(
                    "Cannot specify a CategoricalDtype and also "
                    "`categories` or `ordered`. Use "
                    "`dtype=CategoricalDtype(categories, ordered)`"
                    " instead."
                )
            warnings.warn(
                "specifying 'categories' or 'ordered' in "
                ".astype() is deprecated; pass a "
                "CategoricalDtype instead",
                FutureWarning,
                stacklevel=7,
            )

        categories = kwargs.get("categories", None)
        ordered = kwargs.get("ordered", None)
        if com._any_not_none(categories, ordered):
            dtype = CategoricalDtype(categories, ordered)

        if is_categorical_dtype(self.values):
            # GH 10696/18593: update an existing categorical efficiently
            return self.make_block(self.values.astype(dtype, copy=copy))

        return self.make_block(Categorical(self.values, dtype=dtype))

    # convert dtypes if needed
    dtype = pandas_dtype(dtype)

    # astype processing
    if is_dtype_equal(self.dtype, dtype):
        if copy:
            return self.copy()
        return self

    if klass is None:
        if dtype == np.object_:
            klass = ObjectBlock
    try:
        # force the copy here
        if values is None:
            if self.is_extension:
                values = self.values.astype(dtype)
            else:
                if issubclass(dtype.type, (compat.text_type, compat.string_types)):
                    # use native type formatting for datetime/tz/timedelta
                    if self.is_datelike:
                        values = self.to_native_types()

                    # astype formatting
                    else:
                        values = self.get_values()

                else:
                    values = self.get_values(dtype=dtype)

                # _astype_nansafe works fine with 1-d only
                values = astype_nansafe(values.ravel(), dtype, copy=True)

            # TODO(extension)
            # should we make this attribute?
            try:
                values = values.reshape(self.shape)
            except AttributeError:
                pass

        newb = make_block(values, placement=self.mgr_locs, klass=klass, ndim=self.ndim)
    except Exception:  # noqa: E722
        if errors == "raise":
            raise
        newb = self.copy() if copy else self

    if newb.is_numeric and self.is_numeric:
        if newb.shape != self.shape:
            raise TypeError(
                "cannot set astype for copy = [{copy}] for dtype "
                "({dtype} [{shape}]) to different shape "
                "({newb_dtype} [{newb_shape}])".format(
                    copy=copy,
                    dtype=self.dtype.name,
                    shape=self.shape,
                    newb_dtype=newb.dtype.name,
                    newb_shape=newb.shape,
                )
            )
    return newb