Repository: sympy/sympy

Issue:
problems converting an intersection to a list
```
>>> list(Intersection(S.Reals, FiniteSet(x)))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "sympy\sets\sets.py", line 1434, in <genexpr>
    return (x for x in s if x in other)
  File "sympy\sets\sets.py", line 516, in __contains__
    raise TypeError('contains did not evaluate to a bool: %r' % symb)
TypeError: contains did not evaluate to a bool: And(x < oo, x > -oo)
```

Discussion:

Patch:
diff --git a/doc/src/tutorial/printing.rst b/doc/src/tutorial/printing.rst
index ed08ded3a2..a606146357 100644
--- a/doc/src/tutorial/printing.rst
+++ b/doc/src/tutorial/printing.rst
@@ -14,7 +14,7 @@ Printers
 There are several printers available in SymPy.  The most common ones are
 
 - str
-- srepr
+- repr
 - ASCII pretty printer
 - Unicode pretty printer
 - LaTeX
@@ -119,17 +119,17 @@ exactly the same as the expression as you would enter it.
     >>> print(Integral(sqrt(1/x), x))
     Integral(sqrt(1/x), x)
 
-srepr
------
+repr
+----
 
-The srepr form of an expression is designed to show the exact form of an
+The repr form of an expression is designed to show the exact form of an
 expression.  It will be discussed more in the :ref:`tutorial-manipulation`
 section.  To get it, use ``srepr()`` [#srepr-fn]_.
 
     >>> srepr(Integral(sqrt(1/x), x))
     "Integral(Pow(Pow(Symbol('x'), Integer(-1)), Rational(1, 2)), Tuple(Symbol('x')))"
 
-The srepr form is mostly useful for understanding how an expression is built
+The repr form is mostly useful for understanding how an expression is built
 internally.
 
 
diff --git a/sympy/categories/baseclasses.py b/sympy/categories/baseclasses.py
index 9b3d68937a..79b12d08da 100644
--- a/sympy/categories/baseclasses.py
+++ b/sympy/categories/baseclasses.py
@@ -1,6 +1,6 @@
 from __future__ import print_function, division
 
-from sympy.core import S, Basic, Dict, Symbol, Tuple
+from sympy.core import S, Basic, Dict, Symbol, Tuple, sympify
 from sympy.core.compatibility import range, iterable
 from sympy.sets import Set, FiniteSet, EmptySet
 
@@ -722,8 +722,8 @@ def __new__(cls, *args):
 
                 for morphism in conclusions_arg:
                     # Check that no new objects appear in conclusions.
-                    if ((objects.contains(morphism.domain) == S.true) and
-                        (objects.contains(morphism.codomain) == S.true)):
+                    if ((sympify(objects.contains(morphism.domain)) is S.true) and
+                        (sympify(objects.contains(morphism.codomain)) is S.true)):
                         # No need to add identities and recurse
                         # composites this time.
                         Diagram._add_morphism_closure(
@@ -920,14 +920,14 @@ def subdiagram_from_objects(self, objects):
 
         new_premises = {}
         for morphism, props in self.premises.items():
-            if ((objects.contains(morphism.domain) == S.true) and
-                (objects.contains(morphism.codomain) == S.true)):
+            if ((sympify(objects.contains(morphism.domain)) is S.true) and
+                (sympify(objects.contains(morphism.codomain)) is S.true)):
                 new_premises[morphism] = props
 
         new_conclusions = {}
         for morphism, props in self.conclusions.items():
-            if ((objects.contains(morphism.domain) == S.true) and
-                (objects.contains(morphism.codomain) == S.true)):
+            if ((sympify(objects.contains(morphism.domain)) is S.true) and
+                (sympify(objects.contains(morphism.codomain)) is S.true)):
                 new_conclusions[morphism] = props
 
         return Diagram(new_premises, new_conclusions)
diff --git a/sympy/sets/sets.py b/sympy/sets/sets.py
index 3b0ba18a62..ac7a486dba 100644
--- a/sympy/sets/sets.py
+++ b/sympy/sets/sets.py
@@ -511,8 +511,8 @@ def __sub__(self, other):
         return Complement(self, other)
 
     def __contains__(self, other):
-        symb = self.contains(other)
-        if symb not in (True, False):
+        symb = sympify(self.contains(other))
+        if not (symb is S.true or symb is S.false):
             raise TypeError('contains did not evaluate to a bool: %r' % symb)
         return bool(symb)
 
@@ -949,8 +949,8 @@ def _union(self, other):
                 return Interval(start, end, left_open, right_open)
 
         # If I have open end points and these endpoints are contained in other
-        if ((self.left_open and other.contains(self.start) == True) or
-                (self.right_open and other.contains(self.end) == True)):
+        if ((self.left_open and sympify(other.contains(self.start)) is S.true) or
+                (self.right_open and sympify(other.contains(self.end)) is S.true)):
             # Fill in my end points and return
             open_left = self.left_open and self.start not in other
             open_right = self.right_open and self.end not in other
@@ -1427,13 +1427,23 @@ def _contains(self, other):
         return And(*[set.contains(other) for set in self.args])
 
     def __iter__(self):
+        no_iter = True
         for s in self.args:
             if s.is_iterable:
+                no_iter = False
                 other_sets = set(self.args) - set((s,))
                 other = Intersection(other_sets, evaluate=False)
-                return (x for x in s if x in other)
+                for x in s:
+                    c = sympify(other.contains(x))
+                    if c is S.true:
+                        yield x
+                    elif c is S.false:
+                        pass
+                    else:
+                        yield c
 
-        raise ValueError("None of the constituent sets are iterable")
+        if no_iter:
+            raise ValueError("None of the constituent sets are iterable")
 
     @staticmethod
     def _handle_finite_sets(args):
@@ -1485,7 +1495,7 @@ def _handle_finite_sets(args):
                     # contained in `v` then remove them from `v`
                     # and add this as a new arg
                     contained = [x for x in symbolic_s_list
-                        if v.contains(x) == True]
+                        if sympify(v.contains(x)) is S.true]
                     if contained != symbolic_s_list:
                         new_args.append(
                             v - FiniteSet(
@@ -1837,12 +1847,20 @@ def _complement(self, other):
                 return None
 
         elif isinstance(other, FiniteSet):
-            unk = FiniteSet(*[el for el in self if other.contains(el)
-                not in (True, False)])
+            unk = []
+            for i in self:
+                c = sympify(other.contains(i))
+                if c is not S.true and c is not S.false:
+                    unk.append(i)
+            unk = FiniteSet(*unk)
             if unk == self:
                 return
-            return Complement(FiniteSet(*[el for el in other if
-                self.contains(el) != True]), unk)
+            not_true = []
+            for i in other:
+                c = sympify(self.contains(i))
+                if c is not S.true:
+                    not_true.append(i)
+            return Complement(FiniteSet(*not_true), unk)
 
         return Set._complement(self, other)
 
@@ -1857,7 +1875,7 @@ def _union(self, other):
             return FiniteSet(*(self._elements | other._elements))
 
         # If other set contains one of my elements, remove it from myself
-        if any(other.contains(x) == True for x in self):
+        if any(sympify(other.contains(x)) is S.true for x in self):
             return set((
                 FiniteSet(*[x for x in self
                     if other.contains(x) != True]), other))
diff --git a/sympy/stats/rv.py b/sympy/stats/rv.py
index b3686a1fab..1b04700aec 100644
--- a/sympy/stats/rv.py
+++ b/sympy/stats/rv.py
@@ -387,7 +387,8 @@ def __contains__(self, other):
         for domain in self.domains:
             # Collect the parts of this event which associate to this domain
             elem = frozenset([item for item in other
-                              if domain.symbols.contains(item[0]) == S.true])
+                              if sympify(domain.symbols.contains(item[0]))
+                              is S.true])
             # Test this sub-event
             if elem not in domain:
                 return False


Test patch:
diff --git a/sympy/sets/tests/test_sets.py b/sympy/sets/tests/test_sets.py
index cc9065d56c..1afe34c7bb 100644
--- a/sympy/sets/tests/test_sets.py
+++ b/sympy/sets/tests/test_sets.py
@@ -936,3 +936,8 @@ def test_issue_10113():
     assert imageset(x, f, S.Reals) == Union(Interval(-oo, 0), Interval(1, oo, True, True))
     assert imageset(x, f, Interval(-2, 2)) == Interval(-oo, 0)
     assert imageset(x, f, Interval(-2, 3)) == Union(Interval(-oo, 0), Interval(S(9)/5, oo))
+
+
+def test_issue_10248():
+    assert list(Intersection(S.Reals, FiniteSet(x))) == [
+        And(x < oo, x > -oo)]