diff --git a/.circleci/config.yml b/.circleci/config.yml index fd4dc7f12f..48a2e31169 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,7 +2,7 @@ version: 2 jobs: build: docker: - - image: circleci/python:2.7 + - image: circleci/python:3.7.4 working_directory: ~/gensim @@ -18,11 +18,12 @@ jobs: sudo apt-get -yq update sudo apt-get -yq remove texlive-binaries --purge sudo apt-get -yq --no-install-suggests --no-install-recommends --force-yes install dvipng texlive-latex-base texlive-latex-extra texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended latexmk + sudo apt-get -yq install build-essential python3.7-dev - run: name: Basic installation (tox) command: | - python -m virtualenv venv + python3.7 -m virtualenv venv source venv/bin/activate pip install tox diff --git a/.travis.yml b/.travis.yml index e8df82ceec..185394f8b3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,15 +12,9 @@ language: python matrix: include: - - python: '2.7' - env: TOXENV="flake8,flake8-docs" - - python: '3.6' env: TOXENV="flake8,flake8-docs" - - python: '2.7' - env: TOXENV="py27-linux" - - python: '3.5' env: TOXENV="py35-linux" @@ -35,5 +29,7 @@ matrix: sudo: true -install: pip install tox +install: + - pip install tox + - python ci/install_wheels.py script: tox -vv diff --git a/appveyor.yml b/appveyor.yml index 7d92188934..4fbb831a38 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -13,11 +13,6 @@ environment: secure: qXqY3dFmLOqvxa3Om2gQi/BjotTOK+EP2IPLolBNo0c61yDtNWxbmE4wH3up72Be matrix: - - PYTHON: "C:\\Python27-x64" - PYTHON_VERSION: "2.7.12" - PYTHON_ARCH: "64" - TOXENV: "py27-win" - - PYTHON: "C:\\Python35-x64" PYTHON_VERSION: "3.5.2" PYTHON_ARCH: "64" @@ -60,6 +55,8 @@ install: - "python --version" - "python -c \"import struct; print(struct.calcsize('P') * 8)\"" + - "python ci/install_wheels.py" + build: false test_script: diff --git a/ci/install_wheels.py b/ci/install_wheels.py new file mode 100644 index 0000000000..97d5646da6 --- /dev/null +++ b/ci/install_wheels.py @@ -0,0 +1,30 @@ +"""Install wheels for numpy and scipy. + +Without wheels, installation requires doing a build, which is too much. +The versions of the packages for which wheels are available depends on +the current Python version. + +We use this when building/testing gensim in a CI environment (Travis, AppVeyor, +etc). +""" + +import subprocess +import sys + + +def main(): + if sys.version_info[:2] == (3, 7): + packages = ['numpy==1.14.5', 'scipy==1.1.0'] + else: + packages = ['numpy==1.11.3', 'scipy==1.0.0'] + command = [sys.executable, '-m', 'pip', 'install'] + packages + + print('sys.executable: %r' % sys.executable, file=sys.stderr) + print('sys.version_info: %r' % list(sys.version_info), file=sys.stderr) + print('command: %r' % command, file=sys.stderr) + + subprocess.check_call(command) + + +if __name__ == '__main__': + main() diff --git a/gensim/similarities/index.py b/gensim/similarities/index.py index 1f27e6c82c..08ecd221c6 100644 --- a/gensim/similarities/index.py +++ b/gensim/similarities/index.py @@ -11,6 +11,10 @@ :class:`~gensim.models.doc2vec.Doc2Vec`, :class:`~gensim.models.fasttext.FastText` and :class:`~gensim.models.keyedvectors.KeyedVectors`. +.. Important:: + To use this module, you must have the ``annoy`` library install. + To install it, run ``pip install annoy``. + What is Annoy ------------- @@ -44,12 +48,12 @@ from gensim.models.fasttext import FastText from gensim.models import KeyedVectors from gensim.models.keyedvectors import WordEmbeddingsKeyedVectors -try: - from annoy import AnnoyIndex -except ImportError: - raise ImportError( - "Annoy has not been installed, if you wish to use the annoy indexer, please run `pip install annoy`" - ) + + +_NOANNOY = ImportError( + "Annoy is not installed, if you wish to use the annoy " + "indexer, please run `pip install annoy`" +) class AnnoyIndexer(object): @@ -153,6 +157,11 @@ def load(self, fname): "Can't find index files '%s' and '%s' - Unable to restore AnnoyIndexer state." % (fname, fname_dict) ) else: + try: + from annoy import AnnoyIndex + except ImportError: + raise _NOANNOY + with utils.open(fname_dict, 'rb') as f: d = _pickle.loads(f.read()) self.num_trees = d['num_trees'] @@ -181,6 +190,11 @@ def build_from_keyedvectors(self): return self._build_from_model(self.model.vectors_norm, self.model.index2word, self.model.vector_size) def _build_from_model(self, vectors, labels, num_features): + try: + from annoy import AnnoyIndex + except ImportError: + raise _NOANNOY + index = AnnoyIndex(num_features) for vector_num, vector in enumerate(vectors): diff --git a/most_recent_pip_install.py b/most_recent_pip_install.py deleted file mode 100644 index 930fec5ae4..0000000000 --- a/most_recent_pip_install.py +++ /dev/null @@ -1,18 +0,0 @@ -"""Upgrade pip to the most recent version before running pip install.""" -import os -import sys - - -def run(command): - print(command) - os.system(command) - - -def main(): - opts_and_packages = ' '.join(sys.argv[1:]) - run('python -m pip install --upgrade pip') - run('python -m pip install %s' % opts_and_packages) - - -if __name__ == '__main__': - main() diff --git a/setup.py b/setup.py index 695edd1176..9bbc275d6e 100644 --- a/setup.py +++ b/setup.py @@ -272,7 +272,6 @@ def finalize_options(self): linux_testenv.extend([ 'tensorflow <= 1.3.0', 'keras >= 2.0.4, <= 2.1.4', - 'annoy', ]) if (3, 0) < sys.version_info < (3, 7): @@ -282,8 +281,7 @@ def finalize_options(self): 'sphinx', 'sphinxcontrib-napoleon', 'plotly', -# Pattern's version is specified to install Pattern 3.6, which adds python3 support - 'Pattern >= 3.6', + 'Pattern >= 3.6', # Need 3.6 or later for Py3 support 'sphinxcontrib.programoutput', ] # diff --git a/tox.ini b/tox.ini index d537b6f983..d46bc7076a 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] minversion = 2.0 -envlist = {py27,py35,py36,py37}-{win,linux}, flake8, docs, docs-upload, download-wheels, upload-wheels, test-pypi +envlist = {py35,py36,py37}-{win,linux}, flake8, docs, docs-upload, download-wheels, upload-wheels, test-pypi skipsdist = True platform = linux: linux win: win64 @@ -22,21 +22,10 @@ addopts = -rfxEXs --durations=20 --showlocals --reruns 3 --reruns-delay 1 [testenv] recreate = True -; rackcdn host only for windows wheels (numpy, scipy) -install_command = python most_recent_pip_install.py --timeout=60 --trusted-host 28daf2247a33ed269873-7b1aad3fab3cc330e1fd9d109892382a.r6.cf2.rackcdn.com --find-links http://28daf2247a33ed269873-7b1aad3fab3cc330e1fd9d109892382a.r6.cf2.rackcdn.com/ {env:TOX_PIP_OPTS:} {opts} {packages} +install_command = python -m pip install --timeout=60 {env:TOX_PIP_OPTS:} {opts} {packages} deps = pip>=19.1.1 - py37: numpy==1.14.5 - py37: scipy==1.1.0 - - py27: numpy==1.11.3 - py27: scipy==0.18.1 - py35: numpy==1.11.3 - py35: scipy==0.18.1 - py36: numpy==1.11.3 - py36: scipy==0.18.1 - linux: .[test] win: .[test-win] @@ -49,10 +38,12 @@ setenv = SKIP_NETWORK_TESTS={env:SKIP_NETWORK_TESTS:} BOTO_CONFIG={env:BOTO_CONFIG:} PYTHONHASHSEED=1 + TOX_PARALLEL_NO_SPINNER=1 commands = python --version pip --version + python ci/install_wheels.py python -c "from gensim.models.word2vec import FAST_VERSION; print(FAST_VERSION)" python setup.py build_ext --inplace python -c "from gensim.models.word2vec import FAST_VERSION; print(FAST_VERSION)" @@ -73,15 +64,15 @@ commands = flake8-rst gensim/ docs/ {posargs} [testenv:compile] -basepython = python2 +basepython = python3 recreate = True -deps = numpy==1.11.3 +deps = numpy==1.14.5 commands = python setup.py build_ext --inplace [testenv:docs] -basepython = python2 +basepython = python3 recreate = True whitelist_externals = make deps = .[docs]