def METHOD_NAME(self, X: DataFrame, dtype_buffer=2):
    assert dtype_buffer >= 1, "dtype_buffer must be >= 1 or else fillna_val could be invalid."
    dtype = None
    max_val_all = None
    for col in X.columns:
        try:
            max_val = X[col].dtype.categories.max()
            min_val = X[col].dtype.categories.min()
        except:
            max_val = X[col].max()
            min_val = X[col].min()
        if type(max_val) == str:
            max_dtype = np.min_scalar_type(max_val)
        else:
            if max_val_all is None:
                max_val_all = max_val
            else:
                max_val_all = max(max_val_all, max_val)
            max_val_with_buffer = max_val + dtype_buffer
            max_dtype = np.min_scalar_type(max_val_with_buffer)
        min_dtype = np.min_scalar_type(min_val)
        cur_dtype = np.promote_types(min_dtype, max_dtype)
        if dtype is None:
            dtype = cur_dtype
        else:
            dtype = np.promote_types(dtype, cur_dtype)
    if max_val_all is None:
        fillna_val = 0
    else:
        fillna_val = max_val_all + 1
    return dtype, fillna_val