sympy / sympy

A computer algebra system written in pure Python

Home Page:https://sympy.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[1.13.0rc1] possible regression in comparison (`numbers.One()` VS `float(1.0)`) ?

neutrinoceros opened this issue · comments

I ran unyt's test suite against sympy 1.13.0rc1 and found one regression that boils down to the following test passing in version 1.12.1 and failing in 1.13

from sympy.core.numbers import One

def test_reg_sympy_1_13():
    assert One() == 1.0
    assert not (One() != 1.0)

I see that a number of changes regarding number comparison were intentionally made in this release but it's not clear to me wether this specific behavior change is intended or not.

This is the change in number comparisons that was made. Integer and Float objects no longer compare equal to one another. We would definitely be interested in hearing how this change affects upstream projects like unyt.

Thanks for your prompt answer !

Here's the regression we see in unyt

from unyt import Unit
def test_dB_pow():
    assert Unit("dB") ** 1 == Unit("dB")
...
        if self.dimensions is logarithmic and p != 1.0:
>           raise InvalidUnitOperation(f"Tried to raise '{self}' to power '{p}'")
E           unyt.exceptions.InvalidUnitOperation: Tried to raise 'dB' to power '1'

...

Basically a wrong turn is taken on this line
https://github.com/yt-project/unyt/blob/c4220c71e80741a58ca83c561b2440b854bc69ef/unyt/unit_object.py#L470

It's not critical, and from your answer I conclude that this is trivially fixed on unyt's side by using an int instead of a float for comparison

diff --git a/unyt/unit_object.py b/unyt/unit_object.py
index 698c75b..bec72b2 100644
--- a/unyt/unit_object.py
+++ b/unyt/unit_object.py
@@ -467,7 +467,7 @@ class Unit:
                 "Failed to cast it to a float."
             )

-        if self.dimensions is logarithmic and p != 1.0:
+        if self.dimensions is logarithmic and p != 1:
             raise InvalidUnitOperation(f"Tried to raise '{self}' to power '{p}'")

         return Unit(

So I think we can close this. Thanks again !

quick follow up question though: are you planning to get the final release out anytime in the coming two weeks ? If so, I'll need to cut out a patch release for unyt sooner than I'm currently expecting, which would of course be perfectly fine. I would just like to know :)

That's a question for @oscarbenjamin

There is no schedule for the release. It also depends how many reports like this we get. If you're planning a unyt release in the next two weeks I don't see why we couldn't hold off for that.

A quick fix would be to push out a unyt release that puts an upper cap on the sympy version.

trivially fixed on unyt's side by using an int instead of a float for comparison

The question is whether this is the fix that you actually wanted. If you want to compare both floats and ints then there is now a function from sympy.core.numbers import integer_valued that compares expressions but treats floats as being equal to rationals.

Thanks for your detailled answer, much appreciated.

The question is whether this is the fix that you actually wanted.

What really matters to us is that Unit("dB") ** 1 continues to evaluate as Unit("dB"), and my fix also works with Unit("dB") ** 1.0 because the exponent gets converted to sympy.numbers.One either way, so I think we're good !

I'm setting out to publish a new unyt release as soon as possible after numpy 2.0 comes out (which is scheduled 5 days from now), so I won't be blocking you guys for long !