Thanks to visit codestin.com
Credit goes to github.com

Skip to content

TST: use xpx.testing assertions#25143

Draft
prady0t wants to merge 19 commits into
scipy:mainfrom
prady0t:use_array-api-extra-testing
Draft

TST: use xpx.testing assertions#25143
prady0t wants to merge 19 commits into
scipy:mainfrom
prady0t:use_array-api-extra-testing

Conversation

@prady0t
Copy link
Copy Markdown

@prady0t prady0t commented May 15, 2026

Reference issue

What does this implement/fix?

This is a draft PR to check how much we have progressed with xp_assert functions in the array_api_extra library. We are checking how easy it is for other libraries to implement these testing functions in their existing test suite.

Additional information

This is to remain a draft PR for reference. In case we want to merge it, I can put some effort into cleaning it and making some necessary changes in the test_array_api.py file. There are 2 things different in the array_api_extra version of tests from scipy:

  • Checking namespaces cannot be disabled, which can be done in SciPy. See
  • SciPy allows for Python lists and scalars in the assert functions; these are not allowed in the array_api_extra version. See

I've made some efforts to take these into account and reduce the number of failing tests by checking for Python scalars and lists, and converting them with xp.asarray before feeding them to array_api_extra.
Most test failures are due to our inability to disable namespace checks; they originate from test_array_api.py.

See:

AI Generation Disclosure

No AI tools used

@github-actions github-actions Bot added scipy.interpolate scipy.cluster scipy._lib array types Items related to array API support and input array validation (see gh-18286) labels May 15, 2026
@prady0t prady0t changed the title Use array api extra testing Use array_api_extra's testing functions May 15, 2026
@prady0t
Copy link
Copy Markdown
Author

prady0t commented May 15, 2026

We have 8 total failures. All of them are expected namespace mismatch failures, as array_api_extra doesn't allow disabling the namespace check.

Comment thread scipy/interpolate/tests/test_bsplines.py Outdated
Comment thread scipy/_lib/_array_api.py Outdated
Signed-off-by: Pradyot Ranjan <[email protected]>
Comment thread scipy/interpolate/tests/test_bsplines.py Outdated
Comment thread scipy/_lib/_array_api.py Outdated
Comment thread scipy/_lib/_array_api.py Outdated
Comment thread scipy/_lib/_array_api.py Outdated
Comment thread scipy/_lib/tests/test_array_api.py Outdated
Comment thread scipy/_lib/_array_api.py Outdated
@lucascolley lucascolley changed the title Use array_api_extra's testing functions TST: use xpx.testing assertions May 16, 2026
@lucascolley lucascolley added maintenance Items related to regular maintenance tasks and removed scipy.interpolate scipy.cluster scipy._lib labels May 16, 2026
Signed-off-by: Pradyot Ranjan <[email protected]>
@lucascolley
Copy link
Copy Markdown
Member

The GPU failures demonstrate something we need to address — atol and rtol should either be explicitly rejected if they are arrays (rather than Python scalars), or explicitly accepted and converted either to NumPy arrays or a scalar type. I'm not sure exactly what we'd want yet.

The 'install into venv' failure I think can be addressed when we make the assertions public by ensuring that their module does not depend on pytest.

RuntimeError: Can't call numpy() on Tensor that has conjugate bit set. Use tensor.resolve_conj().numpy() instead.

That's probably something we want to fix over in array-api-extra.

@lucascolley
Copy link
Copy Markdown
Member

The GPU failures demonstrate something we need to address — atol and rtol should either be explicitly rejected if they are arrays (rather than Python scalars), or explicitly accepted and converted either to NumPy arrays or a scalar type. I'm not sure exactly what we'd want yet.

I think we should try explicitly accepting 0-D arrays in array-api-extra for these parameters, but rejecting higher-dimensional arrays. If there are a bunch of failures for 1-D arrays with a single element then maybe it makes sense to accept that also.

@prady0t
Copy link
Copy Markdown
Author

prady0t commented May 16, 2026

or explicitly accepted and converted either to NumPy arrays or a scalar type.

I don't know much about pytorch tensors, but can we do

float(4e-16 * ref.integral)

In the tests to make this work?

Or : https://docs.pytorch.org/docs/2.12/tensors.html

@prady0t
Copy link
Copy Markdown
Author

prady0t commented May 16, 2026

But ofc this won't be a proper fix as we need to address these inputs in the extra module.

@lucascolley
Copy link
Copy Markdown
Member

Taking a step back, the main feature of assertions is that they are stable and "boring", so that when porting a library or writing a new library, the author can concentrate on the functionality and rely on assertions just doing the right thing. What exactly is the right thing can be open to discussions of course, and we had way too many of those in scipy at least (I'm sure elsewhere too), which is why I thought they just work, and there's no need to rewrite then stabilize them, again.

Yeah, part of the motivation for avoiding use of native assertions is for this kind of stability (or at least consistency) — we don't want to have to deal with bugs or nuances of various different xp.testing libraries if we can achieve it all via np.testing anyway.

I think you have a good argument if the question was "should we put in a bunch of thought to re-write these now?" But really, that work has already been done by Guido and Matt, so I think we are right to make use of it (presuming, fairly, that that work is of good quality).

Apparently not without changes; unfortunate but well, okay.

Let's check what changes would be required before we finalise the public API! Would you be willing to try these out in scikit-image and report any difficulties? I already have my eyes on wilsonrljr/sysidentpy#232 and glass-dev/glass#1076 too.

  • default_xp: this one is large and extremely useful.

I think this may be the key remaining area of work.

@prady0t
Copy link
Copy Markdown
Author

prady0t commented May 17, 2026

strictness and knobs to turn some checks off. Strictness, accepting lists vs array-likes vs arrays only, check_* keywords etc --- this is something a library can and will customize; what's needed downstream is a way to customize the behavior without copy-pasting the whole thing, with just small wrappers on top of xpx assertions.

default_xp: this one is large and extremely useful.

xp_capabilities should probably best decoupled from core assertions.

I think these are useful points. Numpy also has a strict parameter; if set to True, it checks for dtypes, scalars, and shape. It could be useful for libraries that want to rely on this parameter. Can we open a tracking issue in array_api_extra for these improvements?

@lucascolley
Copy link
Copy Markdown
Member

Numpy also has a strict parameter; if set to True, it checks for dtypes, scalars, and shape. It could be useful for libraries that want to rely on this parameter.

I would wait until it is explicitly requested, the finer grained parameters we have already are better IMO.

@prady0t
Copy link
Copy Markdown
Author

prady0t commented May 17, 2026

the finer grained parameters we have already are better IMO.

True.

@prady0t
Copy link
Copy Markdown
Author

prady0t commented May 18, 2026

All checks are passing now!

@lucascolley
Copy link
Copy Markdown
Member

nice, I think #25143 (comment) is the next step

Signed-off-by: Pradyot Ranjan <[email protected]>
@prady0t
Copy link
Copy Markdown
Author

prady0t commented May 19, 2026

Only assert_array_almost_equal_nulp remains as a non-array_api_extra testing utility here. Can we port it too? If so, we can remove _strict_check and _assert_matching_namespace helper functions entirely from here.

@lucascolley
Copy link
Copy Markdown
Member

Only assert_array_almost_equal_nulp remains as a non-array_api_extra testing utility here. Can we port it too? If so, we can remove _strict_check and _assert_matching_namespace helper functions entirely from here.

Let's leave it for now, but yes let's return to it when we bring this PR out of draft.

[skip circle]
@lucascolley lucascolley force-pushed the use_array-api-extra-testing branch from 92416b6 to 4e0a864 Compare May 22, 2026 15:26
Comment thread scipy/_lib/_array_api.py Outdated
Comment thread scipy/_lib/_array_api.py Outdated
@lucascolley
Copy link
Copy Markdown
Member

I think data-apis/array-api-extra#755 is the next step here

Comment thread scipy/_lib/_array_api.py Outdated


def xp_assert_equal(actual, desired, *, check_dtype=True,
check_shape=True, check_0d=False, err_msg='', xp=None):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
check_shape=True, check_0d=False, err_msg='', xp=None):
check_shape=True, check_0d=True, err_msg='', xp=None):

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Actually, I kept it False on purpose.
Before scipy did

    actual = xp.asarray(actual)
    desired = xp.asarray(desired)
    

To all arrays, but we now do:


    if isinstance(x, (list, tuple)) or type(x) in (
        int,
        float,
        complex,
        bool,
    ):
        return xp.asarray(x)

(only use asarrya for Python scalar and lists.)

This leads to many a place where a scalar input becomes a 0D array, and hence check_0d fails (where it was being compared to numpy scalars).
In scipy, for this reason, we first check_scalar before converting to xp.asarray, see

# only NumPy distinguishes between scalars and arrays; we do if check_0d=True.

. We can't do that in array_api_extra.

If we want to keep it True, I can give check_0d=False as parameters for tests that currently fail with this change.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This leads to many a place where a scalar input becomes a 0D array, and hence check_0d fails (where it was being compared to numpy scalars).

can you give a concrete example? I thought the type(x) in (int, float, complex, bool) would fail for NumPy scalars.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

It doesn't actually. Only works for Python scalars.See here for example:

assert_almost_equal(w, 1.0)

w here is an np scalar, this raises

E           AssertionError: array-ness does not match:
E            Actual: <class 'numpy.float64'>
E            Desired: <class 'numpy.ndarray'>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

are there cases where we hit this via the xp_... assertions, or only those with the same names as the ones from np.testing?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This line also produces a similar error:

xp_assert_close(w, 1.0+0j)

E           AssertionError: array-ness does not match:
E            Actual: <class 'numpy.complex128'>
E            Desired: <class 'numpy.ndarray'>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

thanks, I pushed a commit which aims to address this.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Nicely done 👏🏼

Comment thread scipy/_lib/_array_api.py Outdated
@lucascolley lucascolley force-pushed the use_array-api-extra-testing branch from 5947421 to bce12e6 Compare May 28, 2026 11:22
@lucascolley
Copy link
Copy Markdown
Member

time to use assert_close_nulp 👀?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

array types Items related to array API support and input array validation (see gh-18286) maintenance Items related to regular maintenance tasks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants