Repository: sympy/sympy

Issue:
TypeError in Complement is_subset
`Complement(S.Complexes, FiniteSet(-I, I)).is_subset(S.Reals)`

Discussion:

Patch:
diff --git a/sympy/sets/sets.py b/sympy/sets/sets.py
index 42b29ad306..3e5c050858 100644
--- a/sympy/sets/sets.py
+++ b/sympy/sets/sets.py
@@ -1806,24 +1806,34 @@ def __iter__(self):
 
     def _complement(self, other):
         if isinstance(other, Interval):
-            nums = sorted(m for m in self.args if m.is_number)
+            # Splitting in sub-intervals is only done for S.Reals;
+            # other cases that need splitting will first pass through
+            # Set._complement().
+            nums, syms = [], []
+            for m in self.args:
+                if m.is_number and m.is_real:
+                    nums.append(m)
+                elif m.is_real == False:
+                    pass  # drop non-reals
+                else:
+                    syms.append(m)  # various symbolic expressions
             if other == S.Reals and nums != []:
-                syms = [m for m in self.args if m.is_Symbol]
-                # Reals cannot contain elements other than numbers and symbols.
-
+                nums.sort()
                 intervals = []  # Build up a list of intervals between the elements
                 intervals += [Interval(S.NegativeInfinity, nums[0], True, True)]
                 for a, b in zip(nums[:-1], nums[1:]):
                     intervals.append(Interval(a, b, True, True))  # both open
                 intervals.append(Interval(nums[-1], S.Infinity, True, True))
-
                 if syms != []:
                     return Complement(Union(*intervals, evaluate=False),
                             FiniteSet(*syms), evaluate=False)
                 else:
                     return Union(*intervals, evaluate=False)
-            elif nums == []:
-                return None
+            elif nums == []:  # no splitting necessary or possible:
+                if syms:
+                    return Complement(other, FiniteSet(*syms), evaluate=False)
+                else:
+                    return other
 
         elif isinstance(other, FiniteSet):
             unk = []


Test patch:
diff --git a/sympy/sets/tests/test_sets.py b/sympy/sets/tests/test_sets.py
index afcb622a0c..0f5c57ab1c 100644
--- a/sympy/sets/tests/test_sets.py
+++ b/sympy/sets/tests/test_sets.py
@@ -251,6 +251,16 @@ def test_difference():
     assert Interval(0, 2) - FiniteSet(1) == \
         Union(Interval(0, 1, False, True), Interval(1, 2, True, False))
 
+    # issue #18119
+    assert S.Reals - FiniteSet(I) == S.Reals
+    assert S.Reals - FiniteSet(-I, I) == S.Reals
+    assert Interval(0, 10) - FiniteSet(-I, I) == Interval(0, 10)
+    assert Interval(0, 10) - FiniteSet(1, I) == Union(
+        Interval.Ropen(0, 1), Interval.Lopen(1, 10))
+    assert S.Reals - FiniteSet(1, 2 + I, x, y**2) == Complement(
+        Union(Interval.open(-oo, 1), Interval.open(1, oo)), FiniteSet(x, y**2),
+        evaluate=False)
+
     assert FiniteSet(1, 2, 3) - FiniteSet(2) == FiniteSet(1, 3)
     assert FiniteSet('ham', 'eggs') - FiniteSet('eggs') == FiniteSet('ham')
     assert FiniteSet(1, 2, 3, 4) - Interval(2, 10, True, False) == \