Repository: sagemath/sage

Issue:
Corrupted polynomial (wrong results/exceptions, crash SIGABRT) obtained from sparse FractionField (FLINT)
### Steps To Reproduce

The following code creates a univariate polynomial $f(x)$ modulo 37, which has very strange and wrong behavior. It misses some attributes (e.g. `factor(f)` can not find `.modulus`, `f.radical()` produces wrong result, wrong arithmetic, probably more).

```py
print(version())  
x = PolynomialRing(GF(37), ['x'], sparse=True).fraction_field().gen()
f = (x^8 + 16*x^6 + 4*x^4 + x^2 + 12).numerator()
print(type(f), f.parent())
print("  f", f)
print("f+1", f+1)
print("rad", f.radical())
print("r^2", f.radical()**2)
print(factor(f))
```
Output:
```
SageMath version 10.2, Release Date: 2023-12-03
<class 'sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint'> Sparse Univariate Polynomial Ring in x over Finite Field of size 37
  f x^8 + 16*x^6 + 4*x^4 + x^2 + 12
f+1 x^8 + 16*x^6 + 4*x^4 + x^2 + 12
rad x^4 + 15*x^2 + 26
r^2 x^8 + x^4
...
AttributeError: 'PolynomialRing_field_with_category' object has no attribute 'modulus'
```

While the actual radical should be just the square root of the polynomial which is:

```py
sage: x = GF(37)['x'].gen()
sage: f = (x^8 + 16*x^6 + 4*x^4 + x^2 + 12)
sage: f.radical()
x^4 + 8*x^2 + 7
sage: f.radical()**2
x^8 + 16*x^6 + 4*x^4 + x^2 + 12
sage: factor(f)
(x + 6)^2 * (x + 17)^2 * (x + 20)^2 * (x + 31)^2
```


### Expected Behavior

The output object is well formed and performs correctly (e.g. factor(f) succeeds, f.radical() is computed correctly, f+1 is computed correctly, etc.).

### Actual Behavior

The output object is corrupted and yields wrong results / exceptions.

### Additional Information

It might be that flint does not support sparse polynomials, while Sage wrongfully forces a dense object to be interpreted as a sparse one?

```py
sage: PolynomialRing(GF(37), ['x'], sparse=False, implementation="FLINT")
Univariate Polynomial Ring in x over Finite Field of size 37
sage: PolynomialRing(GF(37), ['x'], sparse=True, implementation="FLINT")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
...
ValueError: unknown implementation 'FLINT' for sparse polynomial rings over Finite Field of size 37
```

### Environment

```markdown
- **OS**: Linux Mint 21.3
- **Sage Version**: 10.2
```


### Checklist

- [X] I have searched the existing issues for a bug report that matches the one I want to file, without success.
- [X] I have read the documentation and troubleshoot guide


Discussion:
Actually, `f-1` causes a crash.

```py
sage: print("f-1", f-1)
Exception (FLINT memory_manager). Unable to allocate memory (3999070376720).
```
May be related to other FLINT crashes https://github.com/sagemath/sage/issues/37317 https://github.com/sagemath/sage/issues/37169

(But this seems to be an actual memory corruption rather than an unhandled FLINT exception, also here the modulus is prime)

Resolving patch:
diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py
--- a/src/sage/rings/polynomial/polynomial_ring.py
+++ b/src/sage/rings/polynomial/polynomial_ring.py
@@ -2456,14 +2456,13 @@ def lagrange_polynomial(self, points, algorithm="divided_difference", previous_r
     @cached_method
     def fraction_field(self):
         """
-        Returns the fraction field of self.
+        Return the fraction field of ``self``.
 
         EXAMPLES::
 
-            sage: R.<t> = GF(5)[]
-            sage: R.fraction_field()
-            Fraction Field of Univariate Polynomial Ring in t
-             over Finite Field of size 5
+            sage: QQbar['x'].fraction_field()
+            Fraction Field of Univariate Polynomial Ring in x over Algebraic
+            Field
 
         TESTS:
 
@@ -2483,17 +2482,14 @@ def fraction_field(self):
             sage: t(x)
             x
 
+        Fixed :issue:`37374`::
+
+            sage: x = PolynomialRing(GF(37), ['x'], sparse=True).fraction_field().gen()
+            sage: type(x.numerator())
+            <class 'sage.rings.polynomial.polynomial_ring.PolynomialRing_field_with_category.element_class'>
+            sage: (x^8 + 16*x^6 + 4*x^4 + x^2 + 12).numerator() - 1
+            x^8 + 16*x^6 + 4*x^4 + x^2 + 11
         """
-        R = self.base_ring()
-        p = R.characteristic()
-        if p != 0 and R.is_prime_field():
-            try:
-                from sage.rings.fraction_field_FpT import FpT
-            except ImportError:
-                pass
-            else:
-                if 2 < p and p < FpT.INTEGER_LIMIT:
-                    return FpT(self)
         from sage.rings.fraction_field import FractionField_1poly_field
         return FractionField_1poly_field(self)
 
@@ -3566,6 +3562,31 @@ def irreducible_element(self, n, algorithm=None):
         # No suitable algorithm found, try algorithms from the base class.
         return PolynomialRing_dense_finite_field.irreducible_element(self, n, algorithm)
 
+    @cached_method
+    def fraction_field(self):
+        """
+        Return the fraction field of ``self``.
+
+        EXAMPLES::
+
+            sage: R.<t> = GF(5)[]
+            sage: R.fraction_field()
+            Fraction Field of Univariate Polynomial Ring in t
+             over Finite Field of size 5
+        """
+        try:
+            from sage.rings.fraction_field_FpT import FpT
+            from sage.rings.polynomial.polynomial_zmod_flint import Polynomial_zmod_flint
+        except ImportError:
+            pass
+        else:
+            p = self.base_ring().characteristic()
+            if (issubclass(self.element_class, Polynomial_zmod_flint)
+                    and 2 < p < FpT.INTEGER_LIMIT):
+                return FpT(self)
+        return super().fraction_field()
+
+
 def polygen(ring_or_element, name="x"):
     """
     Return a polynomial indeterminate.


Test patch: