Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 29 additions & 23 deletions scipy/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,11 +229,13 @@ def _backends_kwargs_from_request(request, skip_or_xfail):
if marker.kwargs.get('np_only'):
kwargs['np_only'] = True
kwargs['exceptions'] = marker.kwargs.get('exceptions', [])
kwargs['reason'] = marker.kwargs.get('reason', None)
elif marker.kwargs.get('cpu_only'):
if not kwargs.get('np_only'):
# if np_only is given, it is certainly cpu only
kwargs['cpu_only'] = True
kwargs['exceptions'] = marker.kwargs.get('exceptions', [])
kwargs['reason'] = marker.kwargs.get('reason', None)

# add backends, if any
if len(marker.args) > 0:
Expand Down Expand Up @@ -291,22 +293,20 @@ def skip_or_xfail_xp_backends(xp, backends, kwargs, skip_or_xfail='skip'):
Backends to skip/xfail, e.g. ``("array_api_strict", "torch")``.
These are overriden when ``np_only`` is ``True``, and are not
necessary to provide for non-CPU backends when ``cpu_only`` is ``True``.
For a custom reason to apply, you should pass a dict ``{'reason': '...'}``
to a keyword matching the name of the backend.
reason : str, optional
A reason for the skip/xfail in the case of ``np_only=True``.
If unprovided, a default reason is used. Note that it is not possible
to specify a custom reason with ``cpu_only``.
For a custom reason to apply, you should pass
``kwargs={<backend name>: {'reason': '...'}, ...}``.
np_only : bool, optional
When ``True``, the test is skipped/xfailed for all backends other
than the default NumPy backend. There is no need to provide
any ``backends`` in this case. To specify a reason, pass a
value to ``reason``. Default: ``False``.
any ``backends`` in this case. Default: ``False``.
cpu_only : bool, optional
When ``True``, the test is skipped/xfailed on non-CPU devices.
There is no need to provide any ``backends`` in this case,
but any ``backends`` will also be skipped on the CPU.
Default: ``False``.
reason : str, optional
A reason for the skip/xfail in the case of ``np_only=True`` or
``cpu_only=True``. If omitted, a default reason is used.
exceptions : list, optional
A list of exceptions for use with ``cpu_only`` or ``np_only``.
This should be provided when delegation is implemented for some,
Expand All @@ -329,17 +329,32 @@ def skip_or_xfail_xp_backends(xp, backends, kwargs, skip_or_xfail='skip'):
if exceptions and not (cpu_only or np_only):
raise ValueError("`exceptions` is only valid alongside `cpu_only` or `np_only`")

# Test explicit backends first so that their reason can override
# those from np_only/cpu_only
if backends is not None:
for i, backend in enumerate(backends):
if xp.__name__ == backend:
reason = kwargs[backend].get('reason')
if not reason:
reason = f"do not run with array API backend: {backend}"

skip_or_xfail(reason=reason)

if np_only:
reason = kwargs.get("reason", "do not run with non-NumPy backends.")
if not isinstance(reason, str) and len(reason) > 1:
raise ValueError("please provide a singleton `reason` "
"when using `np_only`")
Comment on lines -335 to -336
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant with pytest's own error

reason = kwargs.get("reason")
if not reason:
reason = "do not run with non-NumPy backends"

if xp.__name__ != 'numpy' and xp.__name__ not in exceptions:
skip_or_xfail(reason=reason)
return

if cpu_only:
reason = ("no array-agnostic implementation or delegation available "
"for this backend and device")
reason = kwargs.get("reason")
if not reason:
reason = ("no array-agnostic implementation or delegation available "
"for this backend and device")

exceptions = [] if exceptions is None else exceptions
if SCIPY_ARRAY_API and SCIPY_DEVICE != 'cpu':
if xp.__name__ == 'cupy' and 'cupy' not in exceptions:
Expand All @@ -352,15 +367,6 @@ def skip_or_xfail_xp_backends(xp, backends, kwargs, skip_or_xfail='skip'):
if 'cpu' not in d.device_kind:
skip_or_xfail(reason=reason)

if backends is not None:
for i, backend in enumerate(backends):
if xp.__name__ == backend:
reason = kwargs[backend].get('reason')
if not reason:
reason = f"do not run with array API backend: {backend}"

skip_or_xfail(reason=reason)


# Following the approach of NumPy's conftest.py...
# Use a known and persistent tmpdir for hypothesis' caches, which
Expand Down
Loading