Repository: piskvorky/gensim

Issue:
Accesing vector model vocabulary broken in Gensim 3.3 when loading from word2vec format
After upgrading to 3.3.0, it is now impossible to get the model's vocabulary with `model.wv.vocab` method, if the model is loaded from a text or binary word2vec file. However, it works for models saved in the Gensim native format. 
I suppose it is related to re-designing vector models implementations in #1777.  Anyway, it is not good to break compatibility in this way, without even notifying users.

#### Steps/ to Reproduce
```
import gensim, logging
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
model = gensim.models.KeyedVectors.load_word2vec_format('ANY_MODEL.bin.gz', binary=True)
WORD in model.wv.vocab
```
#### Expected Results
`True` or `False`, as it is in Gensim 3.2

#### Actual Results
```
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Word2VecKeyedVectors' object has no attribute 'wv'
```

#### Versions
```
Linux-4.13.0-32-generic-x86_64-with-LinuxMint-18.2-sonya
Python 3.5.2 (default, Nov 23 2017, 16:37:01) 
[GCC 5.4.0 20160609]
NumPy 1.14.0
SciPy 1.0.0
gensim 3.3.0
FAST_VERSION 1
```

Accesing vector model vocabulary broken in Gensim 3.3 when loading from word2vec format
After upgrading to 3.3.0, it is now impossible to get the model's vocabulary with `model.wv.vocab` method, if the model is loaded from a text or binary word2vec file. However, it works for models saved in the Gensim native format. 
I suppose it is related to re-designing vector models implementations in #1777.  Anyway, it is not good to break compatibility in this way, without even notifying users.

#### Steps/ to Reproduce
```
import gensim, logging
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
model = gensim.models.KeyedVectors.load_word2vec_format('ANY_MODEL.bin.gz', binary=True)
WORD in model.wv.vocab
```
#### Expected Results
`True` or `False`, as it is in Gensim 3.2

#### Actual Results
```
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Word2VecKeyedVectors' object has no attribute 'wv'
```

#### Versions
```
Linux-4.13.0-32-generic-x86_64-with-LinuxMint-18.2-sonya
Python 3.5.2 (default, Nov 23 2017, 16:37:01) 
[GCC 5.4.0 20160609]
NumPy 1.14.0
SciPy 1.0.0
gensim 3.3.0
FAST_VERSION 1
```



Discussion:
@akutuzov thanks for the report! Sorry for this, we did not plan anything to break (but this happens :( ).

CC: @manneshiva 

Hi @akutuzov,
Thanks for reporting this issue. This shall be fixed very soon (a couple of hours from now). I tested your code in gensim `3.2.0` and saw that `model is model.wv` returns `True`. So, for the time being, you could use `model.vocab` instead of `model.wv.vocab` (or any other property).
I seem to have missed the self-referential property for `KeyedVectors` -- https://github.com/RaRe-Technologies/gensim/blob/3.2.0/gensim/models/keyedvectors.py#L422. Not sure about the purpose of this property. Will add it back for backward compatibility.
@akutuzov thanks for the report! Sorry for this, we did not plan anything to break (but this happens :( ).

CC: @manneshiva 

Hi @akutuzov,
Thanks for reporting this issue. This shall be fixed very soon (a couple of hours from now). I tested your code in gensim `3.2.0` and saw that `model is model.wv` returns `True`. So, for the time being, you could use `model.vocab` instead of `model.wv.vocab` (or any other property).
I seem to have missed the self-referential property for `KeyedVectors` -- https://github.com/RaRe-Technologies/gensim/blob/3.2.0/gensim/models/keyedvectors.py#L422. Not sure about the purpose of this property. Will add it back for backward compatibility.

Resolving patch:
diff --git a/gensim/models/keyedvectors.py b/gensim/models/keyedvectors.py
--- a/gensim/models/keyedvectors.py
+++ b/gensim/models/keyedvectors.py
@@ -198,6 +198,11 @@ def __init__(self, vector_size):
         self.vectors_norm = None
         self.index2word = []
 
+    @property
+    @deprecated("Attribute will be removed in 4.0.0, use self instead")
+    def wv(self):
+        return self
+
     @property
     def index2entity(self):
         return self.index2word


Test patch:
diff --git a/gensim/test/test_keyedvectors.py b/gensim/test/test_keyedvectors.py
--- a/gensim/test/test_keyedvectors.py
+++ b/gensim/test/test_keyedvectors.py
@@ -149,6 +149,10 @@ def test_rank(self):
         self.assertEqual(self.vectors.rank('war', 'war'), 1)
         self.assertEqual(self.vectors.rank('war', 'terrorism'), 3)
 
+    def test_wv_property(self):
+        """Test that the deprecated `wv` property returns `self`. To be removed in v4.0.0."""
+        self.assertTrue(self.vectors is self.vectors.wv)
+
 
 if __name__ == '__main__':
     logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.DEBUG)