Repository: elastic/elasticsearch-dsl-py

Issue:
~Bool() should return MatchNone()
`Bool()` is the same as `MatchAll()` so inversion should have the same effect and result in `MatchNone()`

Discussion:

Patch:
diff --git a/elasticsearch_dsl/query.py b/elasticsearch_dsl/query.py
index 48b6ba7..cedd0a7 100644
--- a/elasticsearch_dsl/query.py
+++ b/elasticsearch_dsl/query.py
@@ -180,6 +180,11 @@ class Bool(Query):
         )
 
     def __invert__(self):
+        # Because an empty Bool query is treated like
+        # MatchAll the inverse should be MatchNone
+        if not any(chain(self.must, self.filter, self.should, self.must_not)):
+            return MatchNone()
+
         negations = []
         for q in chain(self.must, self.filter):
             negations.append(~q)


Test patch:
diff --git a/tests/test_query.py b/tests/test_query.py
index 098118d..2e58040 100644
--- a/tests/test_query.py
+++ b/tests/test_query.py
@@ -206,6 +206,12 @@ def test_not_match_none_is_match_all():
     assert ~q == query.MatchAll()
 
 
+def test_invert_empty_bool_is_match_none():
+    q = query.Bool()
+
+    assert ~q == query.MatchNone()
+
+
 def test_match_none_or_query_equals_query():
     q1 = query.Match(f=42)
     q2 = query.MatchNone()