Repository: sympy/sympy

Issue:
Error in solveset in a rational function with a radical denominator
I'm using Sympy in order to get extrema and inflection points of certain functions.
When I used solveset in this case (I just put the function immediately to make reading easier):
```python
from sympy import S, diff, solveset, sqrt, symbols

x = symbols('x')
function = (x + 5)/sqrt(-x**2 - 10*x)
print(function)
solveset(function, x, S.Reals)
```
I get this error:
```
Traceback (most recent call last):
  File "...\stub.py", line 6, in <module>
    solveset(function, x, S.Reals)
  File "...\AppData\Local\Programs\Python\Python36\lib\site-packages\sympy\solvers\solveset.py", line 1127, in solveset
    return solveset(f.xreplace({symbol: r}), r, domain
  File "...\AppData\Local\Programs\Python\Python36\lib\site-packages\sympy\solvers\solveset.py", line 1145, in solveset
    return _solveset(f, symbol, domain, _check=True)
  File "...\AppData\Local\Programs\Python\Python36\lib\site-packages\sympy\solvers\solveset.py", line 942, in _solveset
    solver)
  File "...\AppData\Local\Programs\Python\Python36\lib\site-packages\sympy\solvers\solveset.py", line 717, in _solve_radical
    eq, cov = unrad(f)
TypeError: 'NoneType' object is not iterable
```
...which is somewhere around here:
https://github.com/sympy/sympy/blob/49a1c33d60a7359ad0acb7a13cd212b2e8d0ac80/sympy/solvers/solveset.py#L721-L723

Discussion:

Patch:
diff --git a/sympy/solvers/solveset.py b/sympy/solvers/solveset.py
index ee0419dec1..b2797e59c3 100644
--- a/sympy/solvers/solveset.py
+++ b/sympy/solvers/solveset.py
@@ -2186,6 +2186,9 @@ def solveset(f, symbol=None, domain=S.Complexes):
 
     free_symbols = f.free_symbols
 
+    if f.has(Piecewise):
+        f = piecewise_fold(f)
+
     if symbol is None and not free_symbols:
         b = Eq(f, 0)
         if b is S.true:


Test patch:
diff --git a/.github/workflows/runtests.yml b/.github/workflows/runtests.yml
index 6f7879be2d..9ec3ea206c 100644
--- a/.github/workflows/runtests.yml
+++ b/.github/workflows/runtests.yml
@@ -152,7 +152,7 @@ jobs:
     runs-on: ubuntu-20.04
     strategy:
       matrix:
-        python-version: ['3.6', '3.7', '3.8', '3.10.0-rc.1', 'pypy-3.7']
+        python-version: ['3.6', '3.7', '3.8', '3.10.0-rc.1', 'pypy-3.6']
     steps:
       - uses: actions/checkout@v2
       - uses: actions/setup-python@v2
@@ -170,7 +170,7 @@ jobs:
     runs-on: ubuntu-20.04
     strategy:
       matrix:
-        python-version: ['3.6', '3.7', '3.8', '3.10.0-rc.1', 'pypy-3.7']
+        python-version: ['3.6', '3.7', '3.8', '3.10.0-rc.1', 'pypy-3.6']
     steps:
       - uses: actions/checkout@v2
       - uses: actions/setup-python@v2
@@ -188,7 +188,7 @@ jobs:
     runs-on: ubuntu-20.04
     strategy:
       matrix:
-        python-version: ['3.6', '3.7', '3.8', '3.10.0-rc.1', 'pypy-3.7']
+        python-version: ['3.6', '3.7', '3.8', '3.10.0-rc.1', 'pypy-3.6']
     steps:
       - uses: actions/checkout@v2
       - uses: actions/setup-python@v2
diff --git a/sympy/solvers/tests/test_solveset.py b/sympy/solvers/tests/test_solveset.py
index 8d37bf0e39..079d233a52 100644
--- a/sympy/solvers/tests/test_solveset.py
+++ b/sympy/solvers/tests/test_solveset.py
@@ -2,9 +2,9 @@
 from sympy.core.compatibility import ordered
 from sympy.core.function import (Function, Lambda, nfloat, diff)
 from sympy.core.mod import Mod
-from sympy.core.numbers import (E, I, Rational, oo, pi)
+from sympy.core.numbers import (E, I, Rational, oo, pi, Integer)
 from sympy.core.relational import (Eq, Gt,
-    Ne)
+    Ne, Ge)
 from sympy.core.singleton import S
 from sympy.core.symbol import (Dummy, Symbol, symbols)
 from sympy.functions.elementary.complexes import (Abs, arg, im, re, sign)
@@ -2822,6 +2822,67 @@ def test_substitution_with_infeasible_solution():
     assert sol != nonlinsolve(system, solvefor)
 
 
+def test_issue_20097():
+    assert solveset(1/sqrt(x)) == EmptySet()
+
+
+def test_issue_15350():
+    assert solveset(diff(sqrt(1/x+x))) == FiniteSet(-1, 1)
+
+
+def test_issue_18359():
+    c1 = Piecewise((0, x < 0), (Min(1, x)/2 - Min(2, x)/2 + Min(3, x)/2, True))
+    c2 = Piecewise((Piecewise((0, x < 0), (Min(1, x)/2 - Min(2, x)/2 + Min(3, x)/2, True)), x >= 0), (0, True))
+    correct_result = Interval(1, 2)
+    result1 = solveset(c1 - Rational(1, 2), x, Interval(0, 3))
+    result2 = solveset(c2 - Rational(1, 2), x, Interval(0, 3))
+    assert result1 == correct_result
+    assert result2 == correct_result
+
+
+def test_issue_17604():
+    lhs = -2**(3*x/11)*exp(x/11) + pi**(x/11)
+    assert _is_exponential(lhs, x)
+    assert _solve_exponential(lhs, 0, x, S.Complexes) == FiniteSet(0)
+
+
+def test_issue_17580():
+    assert solveset(1/(1 - x**3)**2, x, S.Reals) == EmptySet()
+
+
+def test_issue_17566_actual():
+    sys = [2**x + 2**y - 3, 4**x + 9**y - 5]
+    # Not clear this is the correct result, but at least no recursion error
+    assert nonlinsolve(sys, x, y) == FiniteSet((log(3 - 2**y)/log(2), y))
+
+
+def test_issue_17565():
+    eq = Ge(2*(x - 2)**2/(3*(x + 1)**(Integer(1)/3)) + 2*(x - 2)*(x + 1)**(Integer(2)/3), 0)
+    res = Union(Interval.Lopen(-1, -Rational(1, 4)), Interval(2, oo))
+    assert solveset(eq, x, S.Reals) == res
+
+
+def test_issue_15024():
+    function = (x + 5)/sqrt(-x**2 - 10*x)
+    assert solveset(function, x, S.Reals) == FiniteSet(Integer(-5))
+
+
+def test_issue_16877():
+    assert dumeq(nonlinsolve([x - 1, sin(y)], x, y),
+                 FiniteSet((FiniteSet(1), ImageSet(Lambda(n, 2*n*pi), S.Integers)),
+                           (FiniteSet(1), ImageSet(Lambda(n, 2*n*pi + pi), S.Integers))))
+    # Even better if (FiniteSet(1), ImageSet(Lambda(n, n*pi), S.Integers)) is obtained
+
+
+def test_issue_16876():
+    assert dumeq(nonlinsolve([sin(x), 2*x - 4*y], x, y),
+                 FiniteSet((ImageSet(Lambda(n, 2*n*pi), S.Integers),
+                            ImageSet(Lambda(n, n*pi), S.Integers)),
+                           (ImageSet(Lambda(n, 2*n*pi + pi), S.Integers),
+                            ImageSet(Lambda(n, n*pi + pi/2), S.Integers))))
+    # Even better if (ImageSet(Lambda(n, n*pi), S.Integers),
+    #                 ImageSet(Lambda(n, n*pi/2), S.Integers)) is obtained
+
 def test_issue_21236():
     x, z = symbols("x z")
     y = symbols('y', rational=True)