diff --git a/src/flint/test/test.py b/src/flint/test/test.py index 6b809a48..0631e769 100644 --- a/src/flint/test/test.py +++ b/src/flint/test/test.py @@ -3,6 +3,7 @@ import operator import pickle import doctest +import platform from flint.utils.flint_exceptions import DomainError @@ -11,6 +12,8 @@ if sys.version_info[0] >= 3: long = int +PYPY = platform.python_implementation() == "PyPy" + ctx = flint.ctx def raises(f, exception): @@ -141,13 +144,17 @@ def test_fmpz(): for a, b, c, ab_mod_c in pow_mod_examples: assert pow(a, b, c) == ab_mod_c assert pow(flint.fmpz(a), b, c) == ab_mod_c - assert pow(a, flint.fmpz(b), c) == ab_mod_c - assert pow(a, b, flint.fmpz(c)) == ab_mod_c assert pow(flint.fmpz(a), flint.fmpz(b), c) == ab_mod_c assert pow(flint.fmpz(a), b, flint.fmpz(c)) == ab_mod_c - assert pow(a, flint.fmpz(b), flint.fmpz(c)) == ab_mod_c assert pow(flint.fmpz(a), flint.fmpz(b), flint.fmpz(c)) == ab_mod_c + # 3-arg pow cannot be made to work with fmpz on PyPy + # https://github.com/flintlib/python-flint/issues/74 + if not PYPY: + assert pow(a, flint.fmpz(b), c) == ab_mod_c + assert pow(a, b, flint.fmpz(c)) == ab_mod_c + assert pow(a, flint.fmpz(b), flint.fmpz(c)) == ab_mod_c + assert raises(lambda: pow(flint.fmpz(2), 2, 0), ValueError) # XXX: Handle negative modulus like int? assert raises(lambda: pow(flint.fmpz(2), 2, -1), ValueError) diff --git a/src/flint/types/fmpz_mod_poly.pyx b/src/flint/types/fmpz_mod_poly.pyx index 5f875f0a..8502b001 100644 --- a/src/flint/types/fmpz_mod_poly.pyx +++ b/src/flint/types/fmpz_mod_poly.pyx @@ -880,6 +880,9 @@ cdef class fmpz_mod_poly(flint_poly): """ return self[0] + # XXX: Methods like leading_coefficient() that are generic should be moved + # to the flint_poly base class rather than defined here. + def leading_coefficient(self): """ Return the leading coefficient of this polynomial. @@ -889,6 +892,12 @@ cdef class fmpz_mod_poly(flint_poly): >>> f.leading_coefficient() fmpz_mod(3, 163) """ + # XXX: This is a workaround for a Cython/PyPy bug: + # https://github.com/flintlib/python-flint/issues/74 + # https://github.com/cython/cython/issues/5776 + d = self.degree() + if d < 0: + return self.ctx.mod.zero() return self[self.degree()] def reverse(self, degree=None):