Skip to content

Commit c65ba5d

Browse files
committed
Clean up exceptions and composite_characteristic
1 parent f29a0fc commit c65ba5d

File tree

4 files changed

+35
-24
lines changed

4 files changed

+35
-24
lines changed

src/flint/test/test_all.py

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2173,7 +2173,7 @@ def test_fmpz_mod_poly():
21732173
assert raises(lambda: f_bad.divmod(f_bad), ValueError)
21742174

21752175
# gcd
2176-
assert raises(lambda: f_cmp.gcd(f_cmp), NotImplementedError)
2176+
assert raises(lambda: f_cmp.gcd(f_cmp), DomainError)
21772177
assert raises(lambda: f.gcd("f"), TypeError)
21782178

21792179
# xgcd
@@ -2766,7 +2766,7 @@ def setbad(obj, i, val):
27662766
pass
27672767
else:
27682768
# Z/nZ for n not prime
2769-
assert raises(lambda: P([1, 2, 1]).gcd(P([1, 1])), NotImplementedError)
2769+
assert raises(lambda: P([1, 2, 1]).gcd(P([1, 1])), DomainError)
27702770
assert raises(lambda: P([1, 2, 1]).gcd(None), TypeError)
27712771

27722772
if is_field:
@@ -2846,11 +2846,12 @@ def _all_mpolys():
28462846
def test_mpolys():
28472847
for P, get_context, S, is_field, characteristic in _all_mpolys():
28482848

2849-
# Division under modulo will raise a flint exception if something is not invertible, crashing the program. We
2850-
# can't tell before what is invertible and what is not before hand so we always raise an exception, except for
2851-
# fmpz_mpoly, that returns an bool noting if the division is exact or not.
2852-
division_not_supported = P is not flint.fmpz_mpoly and not is_field
2853-
characteristic_zero = not (P is flint.fmpz_mod_mpoly or P is flint.nmod_mpoly)
2849+
# Division under modulo will raise a flint exception if something is
2850+
# not invertible, crashing the program. We can't tell before what is
2851+
# invertible and what is not before hand so we always raise an
2852+
# exception, except for fmpz_mpoly, that returns an bool noting if the
2853+
# division is exact or not.
2854+
composite_characteristic = characteristic != 0 and not characteristic.is_prime()
28542855

28552856
ctx = get_context(nvars=2)
28562857

@@ -3115,7 +3116,7 @@ def quick_poly():
31153116
assert raises(lambda: quick_poly().imul(P(ctx=ctx1)), IncompatibleContextError)
31163117
assert raises(lambda: quick_poly().imul(None), NotImplementedError)
31173118

3118-
if division_not_supported:
3119+
if composite_characteristic:
31193120
assert raises(lambda: quick_poly() // mpoly({(1, 1): 1}), DomainError)
31203121
assert raises(lambda: quick_poly() % mpoly({(1, 1): 1}), DomainError)
31213122
assert raises(lambda: divmod(quick_poly(), mpoly({(1, 1): 1})), DomainError)
@@ -3145,7 +3146,7 @@ def quick_poly():
31453146

31463147
f = mpoly({(1, 1): 4, (0, 0): 1})
31473148
g = mpoly({(0, 1): 2, (1, 0): 2})
3148-
if not division_not_supported:
3149+
if not composite_characteristic:
31493150
assert 1 // quick_poly() == P(ctx=ctx)
31503151
assert 1 % quick_poly() == P(1, ctx=ctx)
31513152
assert divmod(1, quick_poly()) == (P(ctx=ctx), P(1, ctx=ctx))
@@ -3212,7 +3213,7 @@ def quick_poly():
32123213
# # XXX: Not sure what this should do in general:
32133214
assert raises(lambda: pow(P(1, ctx=ctx), 2, 3), NotImplementedError)
32143215

3215-
if division_not_supported:
3216+
if composite_characteristic:
32163217
assert raises(lambda: (f * g).gcd(f), DomainError)
32173218
else:
32183219
if is_field:
@@ -3222,18 +3223,18 @@ def quick_poly():
32223223
assert raises(lambda: quick_poly().gcd(None), TypeError)
32233224
assert raises(lambda: quick_poly().gcd(P(ctx=ctx1)), IncompatibleContextError)
32243225

3225-
if division_not_supported:
3226+
if composite_characteristic:
32263227
# Factorisation not allowed over Z/nZ for n not prime.
32273228
# Flint would abort so we raise an exception instead:
32283229
assert raises(lambda: (f * g).factor(), DomainError)
3229-
elif characteristic_zero:
3230+
elif characteristic == 0:
32303231
# Primitive factors over Z for fmpz_mpoly and fmpq_mpoly
32313232
assert (f * g).factor() == (S(2), [(g / 2, 1), (f, 1)])
32323233
elif is_field:
32333234
# Monic polynomials over Z/pZ for nmod_mpoly and fmpz_mod_mpoly
32343235
assert (f * g).factor() == (S(8), [(g / 2, 1), (f / 4, 1)])
32353236

3236-
if division_not_supported:
3237+
if composite_characteristic:
32373238
assert raises(lambda: (f * g).sqrt(), DomainError)
32383239
else:
32393240
assert (f * f).sqrt() == f
@@ -3365,11 +3366,21 @@ def factor_sqf(p):
33653366
# https://github.com/flintlib/python-flint/issues/124
33663367
# so we can't even test it...
33673368
nmod_poly_will_crash = type(x) is flint.nmod_poly
3369+
if nmod_poly_will_crash:
3370+
continue
33683371

3369-
if not nmod_poly_will_crash:
3370-
assert raises(lambda: x.factor(), DomainError)
3371-
3372-
# All tests below would raise
3372+
try:
3373+
S(4).sqrt() ** 2 == S(4)
3374+
except DomainError:
3375+
pass
3376+
assert raises(lambda: (x**2).sqrt(), DomainError)
3377+
assert raises(lambda: x.gcd(x), DomainError)
3378+
assert raises(lambda: x.gcd(None), TypeError)
3379+
assert raises(lambda: x.factor(), DomainError)
3380+
assert raises(lambda: x.factor_squarefree(), DomainError)
3381+
3382+
# All tests below can be expected to raise DomainError
3383+
# Not sure if that is guaranteed in all cases though...
33733384
continue
33743385

33753386
assert S(0).sqrt() == S(0)

src/flint/types/fmpz_mod_mpoly.pyx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -798,12 +798,12 @@ cdef class fmpz_mod_mpoly(flint_mpoly):
798798
4*x0*x1 + 1
799799
"""
800800
cdef fmpz_mod_mpoly res
801-
if not self.ctx.is_prime():
802-
raise DomainError("gcd with non-prime modulus is not supported")
803-
elif not typecheck(other, fmpz_mod_mpoly):
801+
if not typecheck(other, fmpz_mod_mpoly):
804802
raise TypeError("argument must be a fmpz_mod_mpoly")
805803
elif (<fmpz_mod_mpoly>self).ctx is not (<fmpz_mod_mpoly>other).ctx:
806804
raise IncompatibleContextError(f"{(<fmpz_mod_mpoly>self).ctx} is not {(<fmpz_mod_mpoly>other).ctx}")
805+
elif not self.ctx.is_prime():
806+
raise DomainError("gcd with non-prime modulus is not supported")
807807
res = create_fmpz_mod_mpoly(self.ctx)
808808
fmpz_mod_mpoly_gcd(res.val, (<fmpz_mod_mpoly>self).val, (<fmpz_mod_mpoly>other).val, res.ctx.val)
809809
return res

src/flint/types/fmpz_mod_poly.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1274,7 +1274,7 @@ cdef class fmpz_mod_poly(flint_poly):
12741274
raise TypeError(f"Cannot interpret {other} as a polynomial")
12751275

12761276
if not self.ctx.is_prime():
1277-
raise NotImplementedError("gcd algorithm assumes that the modulus is prime")
1277+
raise DomainError("gcd algorithm assumes that the modulus is prime")
12781278

12791279
res = self.ctx.new_ctype_poly()
12801280
fmpz_mod_poly_gcd(

src/flint/types/nmod_mpoly.pyx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -774,12 +774,12 @@ cdef class nmod_mpoly(flint_mpoly):
774774
4*x0*x1 + 1
775775
"""
776776
cdef nmod_mpoly res
777-
if not self.ctx.is_prime():
778-
raise DomainError("gcd with non-prime modulus is not supported")
779-
elif not typecheck(other, nmod_mpoly):
777+
if not typecheck(other, nmod_mpoly):
780778
raise TypeError("argument must be a nmod_mpoly")
781779
elif (<nmod_mpoly>self).ctx is not (<nmod_mpoly>other).ctx:
782780
raise IncompatibleContextError(f"{(<nmod_mpoly>self).ctx} is not {(<nmod_mpoly>other).ctx}")
781+
elif not self.ctx.is_prime():
782+
raise DomainError("gcd with non-prime modulus is not supported")
783783
res = create_nmod_mpoly(self.ctx)
784784
nmod_mpoly_gcd(res.val, (<nmod_mpoly>self).val, (<nmod_mpoly>other).val, res.ctx.val)
785785
return res

0 commit comments

Comments
 (0)