Repository: elastic/elasticsearch-dsl-py

Issue:
Hit objects are not pickleable
`Hit` obejcts are not properly serialized when using `pickle` because the `meta` member is not available after loading the object using `pickle.load`. This happens because of the [way ](https://github.com/elastic/elasticsearch-dsl-py/blob/master/elasticsearch_dsl/response/hit.py#L13) the `meta` member of the `Hit` class is added in the `__init__` method. Anyways, I have fixed it by adding `__getstate__` and `__setstate__` methods to `Hit` that make sure we don't lose the metadata. I have the fix on a local fork and would like to open a PR :)

Discussion:

Patch:
diff --git a/elasticsearch_dsl/response/hit.py b/elasticsearch_dsl/response/hit.py
index 4093f01..29a6d95 100644
--- a/elasticsearch_dsl/response/hit.py
+++ b/elasticsearch_dsl/response/hit.py
@@ -12,6 +12,14 @@ class Hit(AttrDict):
         # assign meta as attribute and not as key in self._d_
         super(AttrDict, self).__setattr__('meta', HitMeta(document))
 
+    def __getstate__(self):
+        # add self.meta since it is not in self.__dict__
+        return super(Hit, self).__getstate__() + (self.meta, )
+
+    def __setstate__(self, state):
+        super(AttrDict, self).__setattr__('meta', state[-1])
+        super(Hit, self).__setstate__(state[:-1])
+
     def __dir__(self):
         # be sure to expose meta in dir(self)
         return super(Hit, self).__dir__() + ['meta']


Test patch:
diff --git a/test_elasticsearch_dsl/test_result.py b/test_elasticsearch_dsl/test_result.py
index e4faf88..e6f46da 100644
--- a/test_elasticsearch_dsl/test_result.py
+++ b/test_elasticsearch_dsl/test_result.py
@@ -32,6 +32,7 @@ def test_hit_is_pickleable(dummy_response):
     hits = pickle.loads(pickle.dumps(res.hits))
 
     assert hits == res.hits
+    assert hits[0].meta == res.hits[0].meta
 
 def test_response_stores_search(dummy_response):
     s = Search()