import contextlib

# Copyright (c) 2011, 2012
# Authors: Pietro Berkes,
#          Andreas Muller
#          Mathieu Blondel
#          Olivier Grisel
#          Arnaud Joly
#          Denis Engemann
#          Giorgio Patrini
#          Thierry Guillemot
# License: BSD 3 clause
from collections.abc import Sequence
from typing import Any, Callable, ClassVar

from numpy import ndarray
from numpy.random import RandomState
from numpy.testing import (
    assert_almost_equal,
    assert_approx_equal,
    assert_array_almost_equal,
    assert_array_equal,
    assert_array_less,
)

from .._typing import ArrayLike, Float, Int, MatrixLike

__all__ = [
    "assert_raises",
    "assert_raises_regexp",
    "assert_array_equal",
    "assert_almost_equal",
    "assert_array_almost_equal",
    "assert_array_less",
    "assert_approx_equal",
    "assert_allclose",
    "assert_run_python_script_without_output",
    "assert_no_warnings",
    "SkipTest",
]

_dummy = ...
assert_raises = ...
SkipTest = ...
assert_dict_equal = ...

assert_raises_regex = ...
# assert_raises_regexp is deprecated in Python 3.4 in favor of
# assert_raises_regex but lets keep the backward compat in scikit-learn with
# the old name for now
assert_raises_regexp = ...

# To remove when we support numpy 1.7
def assert_no_warnings(func, *args, **kw): ...
def ignore_warnings(obj: None | Callable = None, category: Warning = ...) -> _IgnoreWarnings | Callable: ...

class _IgnoreWarnings:
    def __init__(self, category: tuple[Warning]) -> None: ...
    def __call__(self, fn: Callable) -> Callable: ...
    def __enter__(self) -> None: ...
    def __exit__(self, *exc_info) -> None: ...

def assert_raise_message(exceptions: tuple[Exception, ...] | Exception, message: str, function: Callable, *args, **kwargs): ...
def assert_allclose(
    actual: ArrayLike,
    desired: ArrayLike,
    rtol: float | None = None,
    atol: float | None = 0.0,
    equal_nan: None | bool = True,
    err_msg: None | str = "",
    verbose: None | bool = True,
): ...
def assert_allclose_dense_sparse(
    x: MatrixLike | ArrayLike,
    y: MatrixLike | ArrayLike,
    rtol: Float = 1e-07,
    atol: Float = 1e-9,
    err_msg: str = "",
): ...
def set_random_state(estimator: Any, random_state: RandomState | None | Int = 0): ...
def check_skip_network(): ...

class TempMemmap:
    def __init__(self, data, mmap_mode: str = "r") -> None: ...
    def __enter__(self): ...
    def __exit__(self, exc_type, exc_val, exc_tb): ...

def create_memmap_backed_data(data, mmap_mode: str = "r", return_folder: bool = False, aligned: bool = False): ...
def assert_run_python_script_without_output(source_code, pattern=".+", timeout=60) -> None: ...
def check_docstring_parameters(func: Callable, doc: None | str = None, ignore: Sequence | None = None) -> ndarray: ...
def assert_run_python_script(source_code: str, timeout: Int = 60): ...
def raises(
    expected_exc_type,
    match: None | str | Sequence[str] = None,
    may_pass: bool = False,
    err_msg: None | str = None,
): ...

class _Raises(contextlib.AbstractContextManager):
    # see raises() for parameters
    def __init__(self, expected_exc_type, match, may_pass, err_msg) -> None: ...
    def __exit__(self, exc_type, exc_value, _): ...

class MinimalClassifier:
    _estimator_type: ClassVar[str] = ...

    def __init__(self, param=None) -> None: ...
    def get_params(self, deep: bool = True): ...
    def set_params(self, **params): ...
    def fit(self, X, y): ...
    def predict_proba(self, X): ...
    def predict(self, X): ...
    def score(self, X, y): ...

class MinimalRegressor:
    _estimator_type: ClassVar[str] = ...

    def __init__(self, param=None) -> None: ...
    def get_params(self, deep: bool = True): ...
    def set_params(self, **params): ...
    def fit(self, X, y): ...
    def predict(self, X): ...
    def score(self, X, y): ...

class MinimalTransformer:
    def __init__(self, param=None) -> None: ...
    def get_params(self, deep: bool = True): ...
    def set_params(self, **params): ...
    def fit(self, X, y=None): ...
    def transform(self, X, y=None): ...
    def fit_transform(self, X, y=None): ...
