Repository: sympy/sympy

Issue:
solveset(sin(pi*x), x) raises TypeError in _solve_trig2
```
In [1]: solveset(sin(pi*x), x)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/root/sympy/sympy/core/cache.py in wrapper(*args, **kwargs)
     95                 try:
---> 96                     retval = cfunc(*args, **kwargs)
     97                 except TypeError:

/root/sympy/sympy/core/numbers.py in __new__(cls, p, q, gcd)
   1631                 if not isinstance(p, Rational):
-> 1632                     raise TypeError('invalid input: %s' % p)
   1633

TypeError: invalid input: pi

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
<ipython-input-1-c31c3e2926eb> in <module>()
----> 1 solveset(sin(pi*x), x)

/root/sympy/sympy/solvers/solveset.py in solveset(f, symbol, domain)
   2024     f = piecewise_fold(f)
   2025
-> 2026     return _solveset(f, symbol, domain, _check=True)
   2027
   2028
/root/sympy/sympy/solvers/solveset.py in _solveset(f, symbol, domain, _check)
    920     elif _is_function_class_equation(TrigonometricFunction, f, symbol) or \
    921             _is_function_class_equation(HyperbolicFunction, f, symbol):
--> 922         result = _solve_trig(f, symbol, domain)
    923     elif isinstance(f, arg):
    924         a = f.args[0]

/root/sympy/sympy/solvers/solveset.py in _solve_trig(f, symbol, domain)
    532     if sol1 is None or isinstance(sol1, ConditionSet):
    533         try:
--> 534             sol = _solve_trig2(f, symbol, domain)
    535         except ValueError:
    536             sol = sol1

/root/sympy/sympy/solvers/solveset.py in _solve_trig2(f, symbol, domain)
    607             continue
    608         c = poly_ar.all_coeffs()[0]   # got the coefficient of 'symbol'
--> 609         numerators.append(Rational(c).p)
    610         denominators.append(Rational(c).q)
    611

/root/sympy/sympy/core/cache.py in wrapper(*args, **kwargs)
     96                     retval = cfunc(*args, **kwargs)
     97                 except TypeError:
---> 98                     retval = func(*args, **kwargs)
     99                 return retval
    100

/root/sympy/sympy/core/numbers.py in __new__(cls, p, q, gcd)
   1630
   1631                 if not isinstance(p, Rational):
-> 1632                     raise TypeError('invalid input: %s' % p)
   1633
   1634             q = 1

TypeError: invalid input: pi
```
I think the above buggy behavior has been uncovered by #18202. So that PR is doing its job :-)

(The equation is the one of #11218.)
AssertionError in solveset(sinh(8*x) + coth(12*x))
```
In [26]: solveset(sinh(8*x) + coth(12*x))                                                                            [4/1675]---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-26-cc67099ea05a> in <module>
----> 1 solveset(sinh(8*x) + coth(12*x))

~/sympy/sympy/solvers/solveset.py in solveset(f, symbol, domain)
   2037     f = piecewise_fold(f)
   2038
-> 2039     return _solveset(f, symbol, domain, _check=True)
   2040
   2041

~/sympy/sympy/solvers/solveset.py in _solveset(f, symbol, domain, _check)
    933     elif _is_function_class_equation(TrigonometricFunction, f, symbol) or \
    934             _is_function_class_equation(HyperbolicFunction, f, symbol):
--> 935         result = _solve_trig(f, symbol, domain)
    936     elif isinstance(f, arg):
    937         a = f.args[0]

~/sympy/sympy/solvers/solveset.py in _solve_trig(f, symbol, domain)
    542     if sol1 is None or isinstance(sol1, ConditionSet):
    543         try:
--> 544             sol = _solve_trig2(f, symbol, domain)
    545         except ValueError:
    546             sol = sol1

~/sympy/sympy/solvers/solveset.py in _solve_trig2(f, symbol, domain)
    626         mu = Rational(2)*ilcm(*denominators)/igcd(*numerators)
    627     else:
--> 628         assert len(numerators) == 1
    629         mu = Rational(2)*denominators[0]/numerators[0]
    630

AssertionError:
```
Currently `_solve_trig2` is not actually designed to handle hyperbolic functions. It's possible to extend this solver to hyperbolic functions, but for now those equations shouldn't end up there.

Discussion:

Patch:
diff --git a/sympy/solvers/solveset.py b/sympy/solvers/solveset.py
index c07a58e2bf..cc160879fa 100644
--- a/sympy/solvers/solveset.py
+++ b/sympy/solvers/solveset.py
@@ -605,19 +605,30 @@ def _solve_trig2(f, symbol, domain):
     denominators = []
     numerators = []
 
+    # todo: This solver can be extended to hyperbolics if the
+    # analogous change of variable to tanh (instead of tan)
+    # is used.
+    if not trig_functions:
+        return ConditionSet(symbol, Eq(f_original, 0), domain)
+
+    # todo: The pre-processing below (extraction of numerators, denominators,
+    # gcd, lcm, mu, etc.) should be updated to the enhanced version in
+    # _solve_trig1. (See #19507)
     for ar in trig_arguments:
         try:
             poly_ar = Poly(ar, symbol)
-
-        except ValueError:
+        except PolynomialError:
             raise ValueError("give up, we can't solve if this is not a polynomial in x")
         if poly_ar.degree() > 1:  # degree >1 still bad
             raise ValueError("degree of variable inside polynomial should not exceed one")
         if poly_ar.degree() == 0:  # degree 0, don't care
             continue
         c = poly_ar.all_coeffs()[0]   # got the coefficient of 'symbol'
-        numerators.append(Rational(c).p)
-        denominators.append(Rational(c).q)
+        try:
+            numerators.append(Rational(c).p)
+            denominators.append(Rational(c).q)
+        except TypeError:
+            return ConditionSet(symbol, Eq(f_original, 0), domain)
 
     x = Dummy('x')
 


Test patch:
diff --git a/sympy/solvers/tests/test_solveset.py b/sympy/solvers/tests/test_solveset.py
index 133634fd96..1d8c16b8a1 100644
--- a/sympy/solvers/tests/test_solveset.py
+++ b/sympy/solvers/tests/test_solveset.py
@@ -866,6 +866,12 @@ def test_solve_hyperbolic():
         ImageSet(Lambda(n, I*(2*n*pi + pi)), S.Integers),
         ImageSet(Lambda(n, 2*n*I*pi), S.Integers))
 
+    # issues #18490 / #19489
+    assert solveset(cosh(x) + cosh(3*x) - cosh(5*x), x, S.Reals) == \
+        ConditionSet(x, Eq(cosh(x) + cosh(3*x) - cosh(5*x), 0), S.Reals)
+    assert solveset(sinh(8*x) + coth(12*x)) == ConditionSet(
+        x, Eq(sinh(8*x) + coth(12*x), 0), S.Complexes)
+
 
 def test_solve_invalid_sol():
     assert 0 not in solveset_real(sin(x)/x, x)