Repository: sympy/sympy

Issue:
do not use `has` to test against self.variables when factoring Sum
```python
>>> c = Sum(x,(x,1,2))
>>> (c*Sum(x, (x, 1, 3))).doit()
18
>>> (Sum(c*x, (x, 1, 3))).doit()
18
>>> (Sum(c*x, (x, 1, 3))).factor()
Sum(x*Sum(x, (x, 1, 2)), (x, 1, 3))  <--- should be Sum(x, (x, 1, 2))*Sum(x, (x, 1, 3))
```

Discussion:

Patch:
diff --git a/sympy/concrete/expr_with_limits.py b/sympy/concrete/expr_with_limits.py
index 0a8293a7de..1a7012bd9c 100644
--- a/sympy/concrete/expr_with_limits.py
+++ b/sympy/concrete/expr_with_limits.py
@@ -410,7 +410,7 @@ def _eval_factor(self, **hints):
             summand = self.function.factor(**hints)
             if summand.is_Mul:
                 out = sift(summand.args, lambda w: w.is_commutative \
-                    and not w.has(*self.variables))
+                    and not set(self.variables) & w.free_symbols)
                 return Mul(*out[True])*self.func(Mul(*out[False]), \
                     *self.limits)
         else:
diff --git a/sympy/polys/polytools.py b/sympy/polys/polytools.py
index f9b8399e5e..95b9a2ec0c 100644
--- a/sympy/polys/polytools.py
+++ b/sympy/polys/polytools.py
@@ -5611,19 +5611,15 @@ def _symbolic_factor_list(expr, opt, method):
     """Helper function for :func:`_symbolic_factor`. """
     coeff, factors = S.One, []
 
-    args = list(Mul.make_args(expr))
+    args = [i._eval_factor() if hasattr(i, '_eval_factor') else i for i in Mul.make_args(expr)]
     for arg in args:
         if arg.is_Number:
             coeff *= arg
             continue
-        elif hasattr(arg, '_eval_factor'):
-            for i in Mul.make_args(arg._eval_factor()):
-                if hasattr(i, '_eval_factor'):
-                    factors.append( (i, 1) )
-                else:
-                    args.append(i)
+        if arg.is_Mul:
+            args.extend(arg.args)
             continue
-        elif arg.is_Pow:
+        if arg.is_Pow:
             base, exp = arg.args
             if base.is_Number:
                 factors.append((base, exp))


Test patch:
diff --git a/sympy/concrete/tests/test_sums_products.py b/sympy/concrete/tests/test_sums_products.py
index 8019a6a6c6..47c27b3a1a 100644
--- a/sympy/concrete/tests/test_sums_products.py
+++ b/sympy/concrete/tests/test_sums_products.py
@@ -922,3 +922,10 @@ def test_convergent_failing():
     # dirichlet tests
     assert Sum(sin(n)/n, (n, 1, oo)).is_convergent() is S.true
     assert Sum(sin(2*n)/n, (n, 1, oo)).is_convergent() is S.true
+
+
+def test_issue_10156():
+    cx = Sum(2*y**2*x, (x, 1,3))
+    e = 2*y*Sum(2*cx*x**2, (x, 1, 9))
+    assert e.factor() == \
+        8*y**3*Sum(x, (x, 1, 3))*Sum(x**2, (x, 1, 9))
diff --git a/sympy/polys/tests/test_polytools.py b/sympy/polys/tests/test_polytools.py
index 6a700633bc..82ff417971 100644
--- a/sympy/polys/tests/test_polytools.py
+++ b/sympy/polys/tests/test_polytools.py
@@ -2403,7 +2403,6 @@ def test_factor():
     assert (2*Sum(x**2, (x, 1, 9))).factor() == 2*Sum(x**2, (x, 1, 9))
 
 
-
 def test_factor_large():
     f = (x**2 + 4*x + 4)**10000000*(x**2 + 1)*(x**2 + 2*x + 1)**1234567
     g = ((x**2 + 2*x + 1)**3000*y**2 + (x**2 + 2*x + 1)**3000*2*y + (