Skip to content

test.test_math.MathTests.testAtan2 failure on OpenIndiana/Solaris #138573

Closed

Description

@mtelka

I do see the following failure with Python-3.14.0rc2 on OpenIndiana. This is a regression from Python-3.13.7.

======================================================================
ERROR: testAtan2 (test.test_math.MathTests.testAtan2)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/data/builds/ul-workspace/components/python/python-314/Python-3.14.0rc2/Lib/test/test_math.py", line 339, in testAtan2
    self.ftest('atan2(0., -0.)', math.atan2(0., -0.), math.pi)
                                 ~~~~~~~~~~^^^^^^^^^
ValueError: math domain error

----------------------------------------------------------------------

Linked PRs

Activity

  1. added
    pendingThe issue will be closed if no feedback is provided
    on Sep 6, 2025
  2. skirpichev commented on Sep 6, 2025

    @skirpichev
    Member

    I assume in both cases same libm is used (I don't know how you build Python).

    Well, as you can see from linked above math_2() code, "math domain error" can arise only in if(isnan(r)) branch on L1031. Is isnan() macro working as expected on your system?

  3. mtelka commented on Sep 6, 2025

    @mtelka
    ContributorAuthor

    I assume in both cases same libm is used (I don't know how you build Python).

    We do have only one libm implementation, so yes.

    Well, as you can see from linked above math_2() code, "math domain error" can arise only in if(isnan(r)) branch on L1031. Is isnan() macro working as expected on your system?

    I'm not sure if the following serves as a proof the isnan() works, but I'm not aware about any issue there.

    $ cat test.c 
    #include <math.h>
    #include <stdio.h>
    
    int main(void)
    {
            printf("%f\n", atan2(0., -0.));
            printf("%d\n", isnan(atan2(0., -0.)));
            return 0;
    }
    $ gcc -Wall -o test test.c 
    $ ./test 
    3.141593
    0
    $
    

    For completeness, here is list of failed tests on OpenIndiana with Python 3.13.7:

    6 tests failed:
        test.test_asyncio.test_ssl test_cext test_cppext test_embed
        test_shutil test_socket
    

    And yes, I do build both 3.13.7 and 3.14.0rc0 on the same machine using same steps (or as close as possible).

  4. mtelka commented on Sep 6, 2025

    @mtelka
    ContributorAuthor

    This is another related failure I do see with 3.14.0rc2:

    ======================================================================
    ERROR: testAtan2 (test.test_math.MathTests.testAtan2)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/data/builds/ul-workspace/components/python/python-314/Python-3.14.0rc2/Lib/test/test_math.py", line 339, in testAtan2
        self.assertEqual(math.atan2(0., 0.), 0.)
                         ~~~~~~~~~~^^^^^^^^
    ValueError: math domain error
    
    ----------------------------------------------------------------------
    
  5. skirpichev commented on Sep 6, 2025

    @skirpichev
    Member

    Then probably libm's atan2 just set errno to EDOM if both arguments are zero. This happens for non IEEE-compliant systems.

  6. kulikjak commented on Sep 6, 2025

    @kulikjak
    Contributor

    Hi, from my investigation, the problem is that atan2 on Solaris sets errno when both arguments are +-0 (the result is correct, though). This was the case for many many years (I found mentions of this behavior on our bug tracker from 1988), so it likely affects all Solaris forks as well. Python 3.14 likely just added a new test that uncovered this.

    I personally think this should not be the case and reported this internally, but I don't know when or whether it will get fixed considering how long this has been the case.

  7. skirpichev commented on Sep 6, 2025

    @skirpichev
    Member

    the problem is that atan2 on Solaris sets errno when both arguments are +-0

    @kulikjak, thanks. That confirms my guess above, sorry it wasn't first.

    I personally think this should not be the case and reported this internally

    C17 says for atan2:

    atan2(±0, −0) returns ±π. (and doesn't raise invalid of divide-by-zero exceptions)

    if implementation conforms to Annex F. Then __STDC_IEC_559__ should be defined. Can you confirm it's not defined?

    If not, standard says: "A domain error may occur if both arguments are zero."

    Comment from mathmodule.c says:

    In general, on an IEEE-754 platform the aim is to follow the C99 standard, including Annex 'F', whenever possible.

    So, I don't think we should either add a workaround or fix the test. Though, maybe we can filter it out for implementations, that don't conform to Annex F.

    I think macro __STDC_IEC_559__ - should be exposed somewhere, maybe in sys.float_info? Or in the math module itself.

    Python 3.14 likely just added a new test that uncovered this.

    Git blame thinks this come from old commit (e57950f).

  8. self-assigned this
    on Sep 6, 2025
  9. mtelka commented on Sep 6, 2025

    @mtelka
    ContributorAuthor

    What about this?

    $ cat test.c 
    #include <math.h>
    #include <stdio.h>
    #include <errno.h>
    
    int main(void)
    {
            errno = 0;
            double r = atan2(0., -0.);
            int e = errno;
            printf("%f\n", r);
            printf("%d\n", e);
            return 0;
    }
    $ gcc -Wall -o test test.c 
    $ ./test 
    3.141593
    0
    $
    

    @kulikjak does the above print non-zero on 2nd line on Solaris?

  10. mtelka commented on Sep 6, 2025

    @mtelka
    ContributorAuthor

    For reference, here is the illumos man page: https://illumos.org/man/3M/atan2

  11. mtelka commented on Sep 6, 2025

    @mtelka
    ContributorAuthor

    if implementation conforms to Annex F. Then __STDC_IEC_559__ should be defined. Can you confirm it's not defined?

    I do not see it defined on illumos.

  12. skirpichev commented on Sep 6, 2025

    @skirpichev
    Member

    What about this?

    Then I suggest you to run math.atan2(0., -0.) under debugger.

    I see no other options where EDOM might be set: either isnan(r) test or the libm's atan2 itself.

    For reference, here is the illumos man page: https://illumos.org/man/3M/atan2

    Yes, it looks to be compatible with Annex F.

    I do not see it defined on illumos.

    So, it doesn't claims to be IEEE-compliant. We should just filter out this test. But I'm curious why it doesn't work and appreciate debugging.

  13. kulikjak commented on Sep 6, 2025

    @kulikjak
    Contributor

    @kulikjak does the above print non-zero on 2nd line on Solaris?

    This also prints zero on Solaris, but if you pass in doubles from variables, it no longer does so - interesting...

    double x = 0.0;
    double y = 0.0;
    double r = atan2(x, y);
    ...
    

    if implementation conforms to Annex F. Then __STDC_IEC_559__ should be defined. Can you confirm it's not defined?

    Same here.

  14. mtelka commented on Sep 6, 2025

    @mtelka
    ContributorAuthor

    @kulikjak does the above print non-zero on 2nd line on Solaris?

    This also prints zero on Solaris, but if you pass in doubles from variables, it no longer does so - interesting...

    double x = 0.0;
    double y = 0.0;
    double r = atan2(x, y);
    ...
    

    The difference is that atan2(0., -0.) is evaluated during the compile, while atan2(x, y) is not.

    $ cat test.c 
    #include <math.h>
    #include <stdio.h>
    #include <errno.h>
    
    int main(void)
    {
            errno = 0;
            double x = 0.0;
            double y = -0.0;
            double r = atan2(x, y);
            int e = errno;
            printf("%f\n", r);
            printf("%d\n", e);
            return 0;
    }
    $ gcc -Wall -lm -o test test.c
    $ ./test 
    3.141593
    33
    $
    
  15. mtelka commented on Sep 6, 2025

    @mtelka
    ContributorAuthor

    Okay, it looks like the issue is really with the platform, so I reported the bug at https://www.illumos.org/issues/17602.

  16. mtelka commented on Sep 6, 2025

    @mtelka
    ContributorAuthor

    While thinking more about this...

    Since both Solaris and illumos does not define __STDC_IEC_559__ then it should be okay for them to return EDOM for the atan2(0.0, 0.0) case (as already mentioned above by @skirpichev). Isn't the bug really at the Python side then where Python silently expects that all implementations are IEC 60559 conformant even in a case they do not claim so?

  17. skirpichev commented on Sep 6, 2025

    @skirpichev
    Member

    Yes, I think we should filter out test (or rather part of it). I'm working on it, see created issue above.

  18. added
    type-bugAn unexpected behavior, bug, or error
    and removed
    pendingThe issue will be closed if no feedback is provided
    interpreter-core(Objects, Python, Grammar, and Parser dirs)
    on Sep 6, 2025
  19. kulikjak commented on Sep 8, 2025

    @kulikjak
    Contributor

    The difference is that atan2(0., -0.) is evaluated during the compile, while atan2(x, y) is not.

    Makes sense, and it's one more reason it should be fixed on our side.

    But I agree that Python probably shouldn't expect that the implementation is IEEE-compliant.

  20. added a commit that references this issue on Sep 12, 2025
  21. removed their assignment
    on Sep 12, 2025
  22. skirpichev commented on Sep 12, 2025

    @skirpichev
    Member

    In pr #138812 this test restricted to the IEC 60559-compatible platforms.

    I'm not sure that it's The Right Way. Perhaps, we can factor out only tests where F.10.1.4 and 7.12.4.4 of the C standard (e.g. C17) differ (i.e. both arguments are zeros). But I suspect other non-IEEE platforms have more quirks when arguments and/or result are zero.

  23. mtelka commented on Sep 12, 2025

    @mtelka
    ContributorAuthor

    FYI, here is the full list of related tests I had to remove to see both test_math and test_cmath passing:

    --- Python-3.14.0rc2/Lib/test/test_math.py.orig
    +++ Python-3.14.0rc2/Lib/test/test_math.py
    @@ -336,7 +336,5 @@
             # math.atan2(0, x)
             self.ftest('atan2(0., -inf)', math.atan2(0., NINF), math.pi)
             self.ftest('atan2(0., -2.3)', math.atan2(0., -2.3), math.pi)
    -        self.ftest('atan2(0., -0.)', math.atan2(0., -0.), math.pi)
    -        self.assertEqual(math.atan2(0., 0.), 0.)
             self.assertEqual(math.atan2(0., 2.3), 0.)
             self.assertEqual(math.atan2(0., INF), 0.)
    @@ -342,7 +342,5 @@
             # math.atan2(-0, x)
             self.ftest('atan2(-0., -inf)', math.atan2(-0., NINF), -math.pi)
             self.ftest('atan2(-0., -2.3)', math.atan2(-0., -2.3), -math.pi)
    -        self.ftest('atan2(-0., -0.)', math.atan2(-0., -0.), -math.pi)
    -        self.assertEqual(math.atan2(-0., 0.), -0.)
             self.assertEqual(math.atan2(-0., 2.3), -0.)
             self.assertEqual(math.atan2(-0., INF), -0.)
    --- Python-3.14.0rc2/Lib/test/test_cmath.py.orig
    +++ Python-3.14.0rc2/Lib/test/test_cmath.py
    @@ -407,7 +407,6 @@
             self.check_polar(polar_with_errno_set)
     
         def test_phase(self):
    -        self.assertAlmostEqual(phase(0), 0.)
             self.assertAlmostEqual(phase(1.), 0.)
             self.assertAlmostEqual(phase(-1.), pi)
             self.assertAlmostEqual(phase(-1.+1E-300j), pi)
    @@ -416,9 +415,5 @@
             self.assertAlmostEqual(phase(-1j), -pi/2)
     
             # zeros
    -        self.assertEqual(phase(complex(0.0, 0.0)), 0.0)
    -        self.assertEqual(phase(complex(0.0, -0.0)), -0.0)
    -        self.assertEqual(phase(complex(-0.0, 0.0)), pi)
    -        self.assertEqual(phase(complex(-0.0, -0.0)), -pi)
     
             # infinities
    
  24. skirpichev commented on Sep 13, 2025

    @skirpichev
    Member

    All related to atan2(), when both arguments are zeros. (cmath.phase() is just atan2 wrapper.)

  25. self-assigned this
    on Mar 24, 2026
  26. added a commit that references this issue on Mar 25, 2026
  27. skirpichev commented on Mar 25, 2026

    @skirpichev
    Member
  28. removed their assignment
    on Mar 25, 2026
  29. vstinner commented on Mar 25, 2026

    @vstinner
    Member

    (I found mentions of this behavior on our bug tracker from 1988)

    Wow, this is an old bug! 😄

    For completeness, here is list of failed tests on OpenIndiana with Python 3.13.7:

    6 tests failed:
    test.test_asyncio.test_ssl test_cext test_cppext test_embed
    test_shutil test_socket

    I'm interested by test_cext and test_cppext failures, but also by test_embed failure. Would you mind to open an issue for test_cext+test_cppext and another one for test_embed?

  30. added a commit that references this issue on Mar 25, 2026
  31. added a commit that references this issue on Mar 25, 2026
  32. vstinner commented on Mar 25, 2026

    @vstinner
    Member

    The two failing tests are now skipped on Solaris: 8e1469c. The change will be backported to 3.14 once the CI pass on the PR.

    Thanks for your bug report @mtelka.

  33. vstinner commented on Mar 25, 2026

    @vstinner
    Member

    Okay, it looks like the issue is really with the platform, so I reported the bug at https://www.illumos.org/issues/17602.

    Oh, this issue has been fixed by the change illumos/illumos-gate@2eba8eb in the meanwhile, nice!

    We do have only one libm implementation, so yes.

    What is lib_version != libm_ieee test in the implementation? It's possible to select a "lib_version" to get different behaviors?

  34. added a commit that references this issue on Mar 26, 2026
  35. mtelka commented on Mar 26, 2026

    @mtelka
    ContributorAuthor

    We do have only one libm implementation, so yes.

    What is lib_version != libm_ieee test in the implementation? It's possible to select a "lib_version" to get different behaviors?

    I do not think so. However, there was a discussion about this line during the code review. You can find it here: https://code.illumos.org/c/illumos-gate/+/4476

  36. mtelka commented on Mar 26, 2026

    @mtelka
    ContributorAuthor

    I'm interested by test_cext and test_cppext failures, but also by test_embed failure. Would you mind to open an issue for test_cext+test_cppext and another one for test_embed?

    These tests pass with Python 3.14.3.

  37. kulikjak commented on Mar 31, 2026

    @kulikjak
    Contributor

    Thank you for the merge. We still didn't fix (or change) the atan2 behavior, so the skip at least helps us.

  38. added a commit that references this issue on Apr 16, 2026
  39. added a commit that references this issue on Apr 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    OS-unsupportedextension-modulesC modules in the Modules dirtestsTests in the Lib/test dirtype-bugAn unexpected behavior, bug, or error

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions