Repository: pandas-dev/pandas

Issue:
BUG: boolean op with empty frames should not raise
```
In [4]: DataFrame(index=[1]) & DataFrame(index=[1])
TypeError: ufunc 'bitwise_and' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
```

should just return an empty frame (also raises if one side is non-empty)



Discussion:

Resolving patch:
diff --git a/pandas/core/ops.py b/pandas/core/ops.py
--- a/pandas/core/ops.py
+++ b/pandas/core/ops.py
@@ -736,11 +736,16 @@ def na_op(x, y):
                 result = np.empty(x.size, dtype=dtype)
                 yrav = y.ravel()
                 mask = notnull(xrav) & notnull(yrav)
-                result[mask] = op(xrav[mask], yrav[mask])
+                xrav = xrav[mask]
+                yrav = yrav[mask]
+                if np.prod(xrav.shape) and np.prod(yrav.shape):
+                    result[mask] = op(xrav, yrav)
             else:
                 result = np.empty(x.size, dtype=x.dtype)
                 mask = notnull(xrav)
-                result[mask] = op(xrav[mask], y)
+                xrav = xrav[mask]
+                if np.prod(xrav.shape):
+                    result[mask] = op(xrav, y)
 
             result, changed = com._maybe_upcast_putmask(result, -mask, np.nan)
             result = result.reshape(x.shape)


Test patch:
diff --git a/pandas/tests/test_frame.py b/pandas/tests/test_frame.py
--- a/pandas/tests/test_frame.py
+++ b/pandas/tests/test_frame.py
@@ -4392,6 +4392,41 @@ def test_operators(self):
         df = DataFrame({'a': ['a', None, 'b']})
         assert_frame_equal(df + df, DataFrame({'a': ['aa', np.nan, 'bb']}))
 
+    def test_operators_boolean(self):
+
+        # GH 5808
+        # empty frames, non-mixed dtype
+
+        result = DataFrame(index=[1]) & DataFrame(index=[1])
+        assert_frame_equal(result,DataFrame(index=[1]))
+
+        result = DataFrame(index=[1]) | DataFrame(index=[1])
+        assert_frame_equal(result,DataFrame(index=[1]))
+
+        result = DataFrame(index=[1]) & DataFrame(index=[1,2])
+        assert_frame_equal(result,DataFrame(index=[1,2]))
+
+        result = DataFrame(index=[1],columns=['A']) & DataFrame(index=[1],columns=['A'])
+        assert_frame_equal(result,DataFrame(index=[1],columns=['A']))
+
+        result = DataFrame(True,index=[1],columns=['A']) & DataFrame(True,index=[1],columns=['A'])
+        assert_frame_equal(result,DataFrame(True,index=[1],columns=['A']))
+
+        result = DataFrame(True,index=[1],columns=['A']) | DataFrame(True,index=[1],columns=['A'])
+        assert_frame_equal(result,DataFrame(True,index=[1],columns=['A']))
+
+        # boolean ops
+        result = DataFrame(1,index=[1],columns=['A']) | DataFrame(True,index=[1],columns=['A'])
+        assert_frame_equal(result,DataFrame(1,index=[1],columns=['A']))
+
+        def f():
+            DataFrame(1.0,index=[1],columns=['A']) | DataFrame(True,index=[1],columns=['A'])
+        self.assertRaises(TypeError, f)
+
+        def f():
+            DataFrame('foo',index=[1],columns=['A']) | DataFrame(True,index=[1],columns=['A'])
+        self.assertRaises(TypeError, f)
+
     def test_operators_none_as_na(self):
         df = DataFrame({"col1": [2, 5.0, 123, None],
                         "col2": [1, 2, 3, 4]}, dtype=object)