Repository: sympy/sympy
File: sympy/polys/polyclasses.py (Python)

Code before:
            return flint.fmpz_poly
        elif dom.is_QQ:
            return flint.fmpq_poly
        elif dom.is_FF:
            return dom._poly_ctx
        else:
            raise RuntimeError("Domain %s is not supported with flint" % dom)

    @classmethod
    def from_rep(cls, rep, dom):
        """Create a DMP from the given representation. """

        if dom.is_ZZ:
            assert isinstance(rep, flint.fmpz_poly)
            _cls = flint.fmpz_poly
        elif dom.is_QQ:
            assert isinstance(rep, flint.fmpq_poly)
            _cls = flint.fmpq_poly
        elif dom.is_FF:
            c = dom.characteristic()
            if isinstance(rep, flint.nmod_poly):
                _cls = lambda e: flint.nmod_poly(e, c)
            elif isinstance(rep, flint.fmpz_mod_poly):
                _cls = lambda e: flint.fmpz_mod_poly(e, flint.fmpz_mod_poly_ctx(c))
            else:
                raise AssertionError
        else:
            raise RuntimeError("Domain %s is not supported with flint" % dom)

        obj = object.__new__(cls)
        obj.dom = dom
        obj._rep = rep
        obj._cls = _cls

        return obj

    def _strict_eq(f, g):
        if type(f) != type(g):
            return False
        return f.dom == g.dom and f._rep == g._rep

    def ground_new(f, coeff):
        """Construct a new ground instance of ``f``. """
        return f.from_rep(f._cls([coeff]), f.dom)

    def _one(f):
        return f.ground_new(f.dom.one)

    def unify(f, g):
        """Unify representations of two polynomials. """
        raise RuntimeError

Review comment (suggestion):
A better fix would be:
```diff
diff --git a/sympy/polys/polyclasses.py b/sympy/polys/polyclasses.py
index 1cc0e0f368..1c12935f36 100644
--- a/sympy/polys/polyclasses.py
+++ b/sympy/polys/polyclasses.py
@@ -1764,7 +1764,7 @@ def _get_flint_poly_cls(cls, dom):
             return flint.fmpz_poly
         elif dom.is_QQ:
             return flint.fmpq_poly
-        elif dom.is_FF:
+        elif dom.is_FF and dom._is_flint:
             return dom._poly_ctx
         else:
             raise RuntimeError("Domain %s is not supported with flint" % dom)
@@ -1773,19 +1773,7 @@ def _get_flint_poly_cls(cls, dom):
     def from_rep(cls, rep, dom):
         """Create a DMP from the given representation. """
 
-        if dom.is_ZZ:
-            assert isinstance(rep, flint.fmpz_poly)
-            _cls = flint.fmpz_poly
-        elif dom.is_QQ:
-            assert isinstance(rep, flint.fmpq_poly)
-            _cls = flint.fmpq_poly
-        elif dom.is_FF:
-            assert isinstance(rep, (flint.nmod_poly, flint.fmpz_mod_poly))
-            c = dom.characteristic()
-            __cls = type(rep)
-            _cls = lambda e: __cls(e, c)
-        else:
-            raise RuntimeError("Domain %s is not supported with flint" % dom)
+        _cls = cls._get_flint_poly_cls(dom)
 
         obj = object.__new__(cls)
         obj.dom = dom
```
A slightly bigger rearrangement might even be better though looking closely at these functions...

Code after:
            return flint.fmpz_poly
        elif dom.is_QQ:
            return flint.fmpq_poly
        elif dom.is_FF and dom._is_flint:
            return dom._poly_ctx
        else:
            raise RuntimeError("Domain %s is not supported with flint" % dom)

    @classmethod
    def from_rep(cls, rep, dom):
        """Create a DMP from the given representation. """

        _cls = cls._get_flint_poly_cls(dom)

        obj = object.__new__(cls)
        obj.dom = dom
        obj._rep = rep
        obj._cls = _cls

        return obj

    def _strict_eq(f, g):
        if type(f) != type(g):
            return False
        return f.dom == g.dom and f._rep == g._rep

    def ground_new(f, coeff):
        """Construct a new ground instance of ``f``. """
        return f.from_rep(f._cls([coeff]), f.dom)

    def _one(f):
        return f.ground_new(f.dom.one)

    def unify(f, g):
        """Unify representations of two polynomials. """
        raise RuntimeError

    def to_DMP_Python(f):
        """Convert ``f`` to a Python native representation. """
        return DMP_Python._new(f.to_list(), f.dom, f.lev)

    def to_tuple(f):
        """Convert ``f`` to a tuple representation with native coefficients. """
        return tuple(f.to_list())

    def _convert(f, dom):
        """Convert the ground domain of ``f``. """
        if dom == QQ and f.dom == ZZ:
            return f.from_rep(flint.fmpq_poly(f._rep), dom)
        elif _supported_flint_domain(dom) and _supported_flint_domain(f.dom):
            # XXX: python-flint should provide a faster way to do this.