File: utils.py

package info (click to toggle)
brian 2.9.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,872 kB
  • sloc: python: 51,820; cpp: 2,033; makefile: 108; sh: 72
file content (70 lines) | stat: -rw-r--r-- 2,349 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import numpy as np
from numpy.testing import assert_allclose as numpy_allclose

from brian2 import prefs
from brian2.units.fundamentalunits import have_same_dimensions


def assert_allclose(actual, desired, rtol=4.5e8, atol=1e-9, **kwds):
    """
    Thin wrapper around numpy's `~numpy.testing.utils.assert_allclose` function. The tolerance depends on the floating
    point precision as defined by the `core.default_float_dtype` preference.

    Parameters
    ----------
    actual : `numpy.ndarray`
        The results to check.
    desired : `numpy.ndarray`
        The expected results.
    rtol : float, optional
        The relative tolerance which will be multiplied with the machine epsilon of the type set as
        `core.default_float_type`.
    atol : float, optional
        The absolute tolerance
    """
    assert have_same_dimensions(actual, desired)
    eps = np.finfo(prefs["core.default_float_dtype"]).eps
    rtol = eps * rtol
    numpy_allclose(
        np.asarray(actual), np.asarray(desired), rtol=rtol, atol=atol, **kwds
    )


def exc_isinstance(exc_info, expected_exception, raise_not_implemented=False):
    """
    Simple helper function as an alternative to calling
    `~.pytest.ExceptionInfo.errisinstance` which will take into account all
    the "causing" exceptions in an exception chain.

    Parameters
    ----------
    exc_info : `pytest.ExceptionInfo` or `Exception`
        The exception info as returned by `pytest.raises`.
    expected_exception : `type`
        The expected exception class
    raise_not_implemented : bool, optional
        Whether to re-raise a `NotImplementedError` – necessary for tests that
        should be skipped with ``@skip_if_not_implemented``. Defaults to
        ``False``.

    Returns
    -------
    correct_exception : bool
        Whether the exception itself or one of the causing exceptions is of the
        expected type.
    """
    if exc_info is None:
        return False
    if hasattr(exc_info, "value"):
        exc_info = exc_info.value

    if isinstance(exc_info, expected_exception):
        return True
    elif raise_not_implemented and isinstance(exc_info, NotImplementedError):
        raise exc_info

    return exc_isinstance(
        exc_info.__cause__,
        expected_exception,
        raise_not_implemented=raise_not_implemented,
    )