Note: This is a public test instance of Red Hat Bugzilla. The data contained within is a snapshot of the live data so any changes you make will not be reflected in the production Bugzilla. Email is disabled so feel free to test any aspect of the site that you want. File any problems you find or give feedback at bugzilla.redhat.com.

Bug 1936947

Summary: python-gmpy2 fails to build with Python 3.10: TypeError: unsupported operand type(s) for ** or pow(): 'xmpz' and 'mpfr'
Product: [Fedora] Fedora Reporter: Tomáš Hrnčiar <thrnciar>
Component: python-gmpy2Assignee: Jerry James <loganjerry>
Status: CLOSED RAWHIDE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: rawhideCC: loganjerry, mhroncok, orion, thrnciar
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: python-gmpy2-2.1.0-0.22.b5.fc35 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2021-03-09 21:31:22 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1890881    

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!