Bug 1936947 - python-gmpy2 fails to build with Python 3.10: TypeError: unsupported operand type(s) for ** or pow(): 'xmpz' and 'mpfr'
Summary: python-gmpy2 fails to build with Python 3.10: TypeError: unsupported operand ...
Keywords:
Status: CLOSED RAWHIDE
Alias: None
Product: Fedora
Classification: Fedora
Component: python-gmpy2
Version: rawhide
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Jerry James
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks: PYTHON3.10
TreeView+ depends on / blocked
 
Reported: 2021-03-09 14:16 UTC by Tomáš Hrnčiar
Modified: 2021-03-09 21:40 UTC (History)
4 users (show)

Fixed In Version: python-gmpy2-2.1.0-0.22.b5.fc35
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2021-03-09 21:31:22 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description Tomáš Hrnčiar 2021-03-09 14:16:56 UTC
python-gmpy2 fails to build with Python 3.10.0a6.

File "/builddir/build/BUILD/gmpy-gmpy2-2.1.0b5/test/test_gmpy2_mpz_inplace.txt", line 150, in test_gmpy2_mpz_inplace.txt
Failed example:
    x **= -2
Differences (ndiff with -expected +actual):
      Traceback (most recent call last):
    -   File "<stdin>", line 1, in <module>
    - TypeError: unsupported operand type(s) for ** or pow(): 'mpz' and 'int'
    +   File "/usr/lib64/python3.10/doctest.py", line 1340, in __run
    +     exec(compile(example.source, filename, "single",
    +   File "<doctest test_gmpy2_mpz_inplace.txt[57]>", line 1, in <module>
    +     x **= -2
    + ValueError: pow() exponent cannot be negative
**********************************************************************
File "/builddir/build/BUILD/gmpy-gmpy2-2.1.0b5/test/test_gmpy2_mpz_inplace.txt", line 156, in test_gmpy2_mpz_inplace.txt
Failed example:
    x **= mpfr(2)
Differences (ndiff with -expected +actual):
    - Traceback (most recent call last):
    -   File "<stdin>", line 1, in <module>
    - TypeError: unsupported operand type(s) for ** or pow(): 'mpz' and 'mpfr'
**********************************************************************
1 items had failures:
   2 of  85 in test_gmpy2_mpz_inplace.txt
***Test Failed*** 2 failures.
Results for:  test_gmpy2_mpz_inplace    Attempted:   85   Failed:    2
Results for:  test_gmpy2_mpz_misc       Attempted:  225   Failed:    0
Results for:  test_gmpy2_mpz_misc_py3   Attempted:   19   Failed:    0
Results for:  test_gmpy2_mul            Attempted:   68   Failed:    0
Results for:  test_gmpy2_muldiv_2exp    Attempted:   24   Failed:    0
Results for:  test_gmpy2_plus           Attempted:   16   Failed:    0
Results for:  test_gmpy2_pow            Attempted:   53   Failed:    0
Results for:  test_gmpy2_predicate      Attempted:  120   Failed:    0
Results for:  test_gmpy2_prp            Attempted:   57   Failed:    0
Results for:  test_gmpy2_root           Attempted:   23   Failed:    0
Results for:  test_gmpy2_square         Attempted:   19   Failed:    0
Results for:  test_gmpy2_sub            Attempted:   83   Failed:    0
**********************************************************************
File "/builddir/build/BUILD/gmpy-gmpy2-2.1.0b5/test/test_gmpy2_xmpz_inplace.txt", line 135, in test_gmpy2_xmpz_inplace.txt
Failed example:
    x **= -2
Differences (ndiff with -expected +actual):
      Traceback (most recent call last):
    -   File "<stdin>", line 1, in <module>
    - TypeError: unsupported operand type(s) for ** or pow(): 'xmpz' and 'int'
    +   File "/usr/lib64/python3.10/doctest.py", line 1340, in __run
    +     exec(compile(example.source, filename, "single",
    +   File "<doctest test_gmpy2_xmpz_inplace.txt[51]>", line 1, in <module>
    +     x **= -2
    + ValueError: pow() exponent cannot be negative
**********************************************************************
File "/builddir/build/BUILD/gmpy-gmpy2-2.1.0b5/test/test_gmpy2_xmpz_inplace.txt", line 141, in test_gmpy2_xmpz_inplace.txt
Failed example:
    x **= mpfr(2)
Differences (ndiff with -expected +actual):
    - Traceback (most recent call last):
    -   File "<stdin>", line 1, in <module>
    - TypeError: unsupported operand type(s) for ** or pow(): 'xmpz' and 'mpfr'
**********************************************************************
1 items had failures:
   2 of  79 in test_gmpy2_xmpz_inplace.txt

For the build logs, see:
https://copr-be.cloud.fedoraproject.org/results/@python/python3.10/fedora-rawhide-x86_64/02054820-python-gmpy2/

For all our attempts to build python-gmpy2 with Python 3.10, see:
https://copr.fedorainfracloud.org/coprs/g/python/python3.10/package/python-gmpy2/

Testing and mass rebuild of packages is happening in copr. You can follow these instructions to test locally in mock if your package builds with Python 3.10:
https://copr.fedorainfracloud.org/coprs/g/python/python3.10/

Let us know here if you have any questions.

Python 3.10 will be included in Fedora 35. To make that update smoother, we're building Fedora packages with early pre-releases of Python 3.10.
A build failure prevents us from testing all dependent packages (transitive [Build]Requires), so if this package is required a lot, it's important for us to get it fixed soon.
We'd appreciate help from the people who know this package best, but if you don't want to work on this now, let us know so we can try to work around it on our side.

Comment 1 Jerry James 2021-03-09 16:28:35 UTC
Both of those tests are expected to fail with a TypeError.  Taking the power of a negative integer is supposed to throw this exception:

TypeError: unsupported operand type(s) for ** or pow(): 'mpz' and 'int'

but now it throws this exception:

ValueError: pow() exponent cannot be negative

suggesting that -2 was automatically converted to an mpz.  In the second test, taking the power of an mpfr floating point number is supposed to throw this exception:

TypeError: unsupported operand type(s) for ** or pow(): 'mpz' and 'mpfr'

but now it produces a value:

mpfr('152587890625.0')

suggesting that mpz(390625) was automatically converted to an mpfr.  Has something changed in python 3.10 regarding automatic promotion of operands?

Comment 2 Jerry James 2021-03-09 18:59:44 UTC
The difference is that, with python 3.9, "x **= -2" results in a call through the nb_inplace_power slot of GMPy_MPZ_number_methods (of type PyNumberMethods).  With the latest python 3.10 alpha, that same expression results in a call through the nb_power slot instead.  Why isn't it using the inplace slot?

Anyway, gmpy2, for whatever reason, treats type promotions differently in the methods used to implement those two slots, which is why the tests are failing.

Comment 3 Miro Hrončok 2021-03-09 19:11:05 UTC
https://docs.python.org/3.10/whatsnew/3.10.html only mentions this:

If object.__ipow__() returns NotImplemented, the operator will correctly fall back to object.__pow__() and object.__rpow__() as expected. https://bugs.python.org/issue38302

Maybe it is related?

Comment 4 Jerry James 2021-03-09 20:44:24 UTC
Yes, that's exactly it.  With python 3.9, we try the __ipow__ method, get NotImplemented and fail.  With python 3.10, we fall back to __pow__ or __rpow__ and either get a different error or succeed, respectively.  I actually like the python 3.10 results better.  I'll let upstream know to expect this change and try to come up with a way to unblock your work.

Comment 5 Jerry James 2021-03-09 21:31:22 UTC
Upstream issue: https://github.com/aleaxit/gmpy/issues/296

I added a patch to Rawhide, applied if and only if building with python >= 3.10, that changes the test suite to expect the new results.  A Rawhide build just completed.

Comment 6 Miro Hrončok 2021-03-09 21:40:46 UTC
So did the copr build. https://copr.fedorainfracloud.org/coprs/g/python/python3.10/package/python-gmpy2/
Thanks!


Note You need to log in before you can comment on or make changes to this bug.