diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index d369eec05a..3c8031220f 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -25,7 +25,7 @@ jobs: # # We use Py3.8 here for historical reasons. # - python-version: "3.8" + python-version: "3.9" - name: Update pip run: python -m pip install -U pip @@ -35,7 +35,7 @@ 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.8-dev + sudo apt-get -yq install build-essential python3.9-dev - name: Install gensim and its dependencies run: pip install -e .[docs] diff --git a/.github/workflows/build-wheels.yml b/.github/workflows/build-wheels.yml index 856efcbd00..aa80162b2e 100644 --- a/.github/workflows/build-wheels.yml +++ b/.github/workflows/build-wheels.yml @@ -23,7 +23,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-20.04, windows-2019, macos-11] + os: [ubuntu-20.04, windows-2019, macos-12] steps: - name: Checkout @@ -61,21 +61,17 @@ jobs: fail-fast: false matrix: include: - - {python: '3.8', os: macos-11} - - {python: '3.9', os: macos-11} - - {python: '3.10', os: macos-11} - - {python: '3.11', os: macos-11} - - {python: '3.12', os: macos-11} + - {python: '3.9', os: macos-12} + - {python: '3.10', os: macos-12} + - {python: '3.11', os: macos-12} + - {python: '3.12', os: macos-12} - - {python: '3.8', os: ubuntu-20.04} - {python: '3.9', os: ubuntu-20.04} - {python: '3.10', os: ubuntu-20.04} - {python: '3.11', os: ubuntu-20.04} - {python: '3.12', os: ubuntu-20.04} - - {python: '3.8', os: windows-2019} - {python: '3.9', os: windows-2019} - - {python: '3.10', os: windows-2019} - {python: '3.11', os: windows-2019} - {python: '3.12', os: windows-2019} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 64505894b7..9bd6c2bd47 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -33,7 +33,7 @@ jobs: # # We use Py3.8 here for historical reasons. # - python-version: "3.8" + python-version: "3.9" - name: Update pip run: python -m pip install -U pip @@ -43,7 +43,7 @@ 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.8-dev + sudo apt-get -yq install build-essential python3.9-dev - name: Install gensim and its dependencies run: pip install -e .[docs] @@ -63,13 +63,11 @@ jobs: fail-fast: false matrix: include: - - {python: '3.8', os: ubuntu-20.04} - {python: '3.9', os: ubuntu-20.04} - {python: '3.10', os: ubuntu-20.04} - {python: '3.11', os: ubuntu-20.04} - {python: '3.12', os: ubuntu-20.04} - - {python: '3.8', os: windows-2019} - {python: '3.9', os: windows-2019} - {python: '3.10', os: windows-2019} - {python: '3.11', os: windows-2019} @@ -161,7 +159,7 @@ jobs: - name: Upload coverage to Codecov if: matrix.coverage == true - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: fail_ci_if_error: true files: ./coverage.xml diff --git a/.github/workflows/update_index.py b/.github/workflows/update_index.py index b685d2b01a..a64ced7227 100644 --- a/.github/workflows/update_index.py +++ b/.github/workflows/update_index.py @@ -21,7 +21,13 @@ def main(): for page in paginator.paginate(Bucket=bucket, Delimiter='/', Prefix=prefix): for content in page.get('Contents', []): key = content['Key'] - print(f"
  • {key}
  • ") + # + # NB. use double quotes in href because that's that + # wheelhouse_uploader expects. + # + # https://github.com/ogrisel/wheelhouse-uploader/blob/eb32a7bb410769bb4212a9aa7fb3bfa3cef1aaec/wheelhouse_uploader/fetch.py#L15 + # + print(f"""
  • {key}
  • """) print("") diff --git a/CHANGELOG.md b/CHANGELOG.md index 91984fded2..62636aef13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,26 @@ Changes ======= + +## 4.3.3, 2024-07-19 + +### :star2: New Features + +### :red_circle: Bug fixes + +* Correct file argument name in KeyedVectors.save docstring (__[hammad7](https://github.com/hammad7)__, [#3532](https://github.com/piskvorky/gensim/pull/3532)) +* Import deprecated scipy.linalg.triu from numpy.triu instead (__[Luffy610](https://github.com/Luffy610)__, [#3524](https://github.com/piskvorky/gensim/pull/3524)) + +### :books: Tutorial and doc improvements + +* Updated the broken Documentation Link on the README.md (__[wittyicon29](https://github.com/wittyicon29)__, [#3505](https://github.com/piskvorky/gensim/pull/3505)) + +### :+1: Improvements + +* Add support for python3.12 wheels (__[YoungMind1](https://github.com/YoungMind1)__, [#3531](https://github.com/piskvorky/gensim/pull/3531)) +* Removed scipy from build-only dependencies (__[filip-komarzyniec](https://github.com/filip-komarzyniec)__, [#3538](https://github.com/piskvorky/gensim/pull/3538)) +* Use newer unittest.mock everwhere (__[a-detiste](https://github.com/a-detiste)__, [#3529](https://github.com/piskvorky/gensim/pull/3529)) +* Handle optional parameters without implicit bool cast (__[nk-fouque](https://github.com/nk-fouque)__, [#3502](https://github.com/piskvorky/gensim/pull/3502)) + ## 4.3.2, 2023-08-23 ### :red_circle: Bug fixes diff --git a/README.md b/README.md index bfd587d594..b876aaf8b2 100644 --- a/README.md +++ b/README.md @@ -49,13 +49,12 @@ on Wikipedia. Installation ------------ -This software depends on [NumPy and Scipy], two Python packages for -scientific computing. You must have them installed prior to installing -gensim. - -It is also recommended you install a fast BLAS library before installing -NumPy. This is optional, but using an optimized BLAS such as MKL, [ATLAS] or -[OpenBLAS] is known to improve performance by as much as an order of +This software depends on [NumPy], a Python package for +scientific computing. Please bear in mind that building NumPy from source +(e.g. by installing gensim on a platform which lacks NumPy .whl distribution) +is a non-trivial task involving [linking NumPy to a BLAS library]. +It is recommended to provide a fast one (such as MKL, [ATLAS] or +[OpenBLAS]) which can improve performance by as much as an order of magnitude. On OSX, NumPy picks up its vecLib BLAS automatically, so you don’t need to do anything special. @@ -69,7 +68,9 @@ Or, if you have instead downloaded and unzipped the [source tar.gz] package: ```bash - python setup.py install + tar -xvzf gensim-X.X.X.tar.gz + cd gensim-X.X.X/ + pip install . ``` For alternative modes of installation, see the [documentation]. @@ -172,8 +173,10 @@ BibTeX entry: [documentation and Jupyter Notebook tutorials]: https://github.com/RaRe-Technologies/gensim/#documentation [Vector Space Model]: https://en.wikipedia.org/wiki/Vector_space_model [unsupervised document analysis]: https://en.wikipedia.org/wiki/Latent_semantic_indexing - [NumPy and Scipy]: https://scipy.org/install/ + [NumPy]: https://numpy.org/install/ + [linking NumPy to a BLAS library]: https://numpy.org/devdocs/building/blas_lapack.html [ATLAS]: https://math-atlas.sourceforge.net/ [OpenBLAS]: https://xianyi.github.io/OpenBLAS/ [source tar.gz]: https://pypi.org/project/gensim/ [documentation]: https://radimrehurek.com/gensim/#install + diff --git a/docs/src/_static/images/route4me-logo.png b/docs/src/_static/images/route4me-logo.png new file mode 100644 index 0000000000..46df6d2f84 Binary files /dev/null and b/docs/src/_static/images/route4me-logo.png differ diff --git a/docs/src/auto_examples/core/run_core_concepts.ipynb b/docs/src/auto_examples/core/run_core_concepts.ipynb index a1fb7857da..d12965ff7d 100644 --- a/docs/src/auto_examples/core/run_core_concepts.ipynb +++ b/docs/src/auto_examples/core/run_core_concepts.ipynb @@ -195,7 +195,7 @@ }, "outputs": [], "source": [ - "from gensim import similarities\n\nindex = similarities.SparseMatrixSimilarity(tfidf[bow_corpus], num_features=12)" + "from gensim import similarities\n\nindex = similarities.SparseMatrixSimilarity(tfidf[bow_corpus], num_features=max(tfidf.dfs) + 1)" ] }, { @@ -274,4 +274,4 @@ }, "nbformat": 4, "nbformat_minor": 0 -} \ No newline at end of file +} diff --git a/docs/src/conf.py b/docs/src/conf.py index 0fbb479b65..41a63d67ef 100644 --- a/docs/src/conf.py +++ b/docs/src/conf.py @@ -61,9 +61,9 @@ # built documents. # # The short X.Y version. -version = '4.3' +version = '4.3.3' # The full version, including alpha/beta/rc tags. -release = '4.3.2.dev0' +release = '4.3.3' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/src/people.rst b/docs/src/people.rst index 99dbd33d9e..26b2bcac89 100644 --- a/docs/src/people.rst +++ b/docs/src/people.rst @@ -48,6 +48,11 @@ Silver Sponsors Bronze Sponsors --------------- +.. figure:: _static/images/route4me-logo.png + :target: https://route4me.com + :width: 50% + :alt: Route Optimizer and Route Planner Software + .. figure:: _static/images/eaccidents-logo.png :target: https://eaccidents.com/ :width: 50% diff --git a/gensim/__init__.py b/gensim/__init__.py index f2a576eed1..442a4bef6b 100644 --- a/gensim/__init__.py +++ b/gensim/__init__.py @@ -4,7 +4,7 @@ """ -__version__ = '4.3.2.dev0' +__version__ = '4.3.3' import logging diff --git a/gensim/corpora/sharded_corpus.py b/gensim/corpora/sharded_corpus.py index c82d711137..377b0bdb6a 100644 --- a/gensim/corpora/sharded_corpus.py +++ b/gensim/corpora/sharded_corpus.py @@ -17,8 +17,6 @@ """ -from __future__ import print_function - import logging import os import math diff --git a/gensim/models/keyedvectors.py b/gensim/models/keyedvectors.py index 821e977d4d..475a0b4810 100644 --- a/gensim/models/keyedvectors.py +++ b/gensim/models/keyedvectors.py @@ -495,9 +495,9 @@ def get_mean_vector(self, keys, weights=None, pre_normalize=True, post_normalize if len(keys) == 0: raise ValueError("cannot compute mean with no input") if isinstance(weights, list): - weights = np.array(weights) + weights = np.array(weights, dtype=self.vectors.dtype) if weights is None: - weights = np.ones(len(keys)) + weights = np.ones(len(keys), dtype=self.vectors.dtype) if len(keys) != weights.shape[0]: # weights is a 1-D numpy array raise ValueError( "keys and weights array must have same number of elements" @@ -762,7 +762,7 @@ def save(self, *args, **kwargs): Parameters ---------- - fname : str + fname_or_handle : str Path to the output file. See Also @@ -1667,7 +1667,7 @@ def save_word2vec_format( if binary: fout.write(f"{prefix}{key} ".encode('utf8') + key_vector.astype(REAL).tobytes()) else: - fout.write(f"{prefix}{key} {' '.join(repr(val) for val in key_vector)}\n".encode('utf8')) + fout.write(f"{prefix}{key} {' '.join(repr(val) for val in key_vector.tolist())}\n".encode('utf8')) @classmethod def load_word2vec_format( @@ -1977,7 +1977,7 @@ def _word2vec_read_text(fin, kv, counts, vocab_size, vector_size, datatype, unic def _word2vec_line_to_vector(line, datatype, unicode_errors, encoding): parts = utils.to_unicode(line.rstrip(), encoding=encoding, errors=unicode_errors).split(" ") - word, weights = parts[0], [datatype(x) for x in parts[1:]] + word, weights = parts[0], [datatype(x).item() for x in parts[1:]] return word, weights diff --git a/gensim/models/ldamodel.py b/gensim/models/ldamodel.py index 945ff04599..c3e8afbf85 100755 --- a/gensim/models/ldamodel.py +++ b/gensim/models/ldamodel.py @@ -133,10 +133,11 @@ def update_dir_prior(prior, N, logphat, rho): The updated prior. """ + dtype = logphat.dtype gradf = N * (psi(np.sum(prior)) - psi(prior) + logphat) - c = N * polygamma(1, np.sum(prior)) - q = -N * polygamma(1, prior) + c = N * polygamma(1, np.sum(prior)).astype(dtype) + q = -N * polygamma(1, prior).astype(dtype) b = np.sum(gradf / q) / (1 / c + np.sum(1 / q)) diff --git a/gensim/models/lsimodel.py b/gensim/models/lsimodel.py index cce19b0b6b..c38da5f91a 100644 --- a/gensim/models/lsimodel.py +++ b/gensim/models/lsimodel.py @@ -66,7 +66,6 @@ import numpy as np import scipy.linalg import scipy.sparse -from scipy.sparse import sparsetools from gensim import interfaces, matutils, utils from gensim.models import basemodel @@ -960,10 +959,8 @@ def stochastic_svd( m, n = corpus.shape assert num_terms == m, f"mismatch in number of features: {m} in sparse matrix vs. {num_terms} parameter" o = random_state.normal(0.0, 1.0, (n, samples)).astype(y.dtype) # draw a random gaussian matrix - sparsetools.csc_matvecs( - m, n, samples, corpus.indptr, corpus.indices, - corpus.data, o.ravel(), y.ravel(), - ) # y = corpus * o + y = corpus.dot(o) # y = corpus * o + del o # unlike np, scipy.sparse `astype()` copies everything, even if there is no change to dtype! @@ -994,10 +991,7 @@ def stochastic_svd( num_docs += n logger.debug("multiplying chunk * gauss") o = random_state.normal(0.0, 1.0, (n, samples), ).astype(dtype) # draw a random gaussian matrix - sparsetools.csc_matvecs( - m, n, samples, chunk.indptr, chunk.indices, # y = y + chunk * o - chunk.data, o.ravel(), y.ravel(), - ) + y = y + chunk * o del chunk, o y = [y] q, _ = matutils.qr_destroy(y) # orthonormalize the range diff --git a/gensim/models/tfidfmodel.py b/gensim/models/tfidfmodel.py index 336023bc1e..a56d7d31b1 100644 --- a/gensim/models/tfidfmodel.py +++ b/gensim/models/tfidfmodel.py @@ -360,16 +360,16 @@ def __init__(self, corpus=None, id2word=None, dictionary=None, wlocal=utils.iden self.pivot = pivot self.eps = 1e-12 - if smartirs: + if smartirs is not None: n_tf, n_df, n_n = self.smartirs self.wlocal = partial(smartirs_wlocal, local_scheme=n_tf) self.wglobal = partial(smartirs_wglobal, global_scheme=n_df) - if dictionary: + if dictionary is not None: # user supplied a Dictionary object, which already contains all the # statistics we need to construct the IDF mapping. we can skip the # step that goes through the corpus (= an optimization). - if corpus: + if corpus is not None: logger.warning( "constructor received both corpus and explicit inverse document frequencies; ignoring the corpus" ) @@ -378,9 +378,9 @@ def __init__(self, corpus=None, id2word=None, dictionary=None, wlocal=utils.iden self.dfs = dictionary.dfs.copy() self.term_lens = {termid: len(term) for termid, term in dictionary.items()} self.idfs = precompute_idfs(self.wglobal, self.dfs, self.num_docs) - if not id2word: + if id2word is None: self.id2word = dictionary - elif corpus: + elif corpus is not None: self.initialize(corpus) else: # NOTE: everything is left uninitialized; presumably the model will @@ -388,7 +388,7 @@ def __init__(self, corpus=None, id2word=None, dictionary=None, wlocal=utils.iden pass # If smartirs is not None, override pivot and normalize - if not smartirs: + if smartirs is None: return if self.pivot is not None: if n_n in 'ub': diff --git a/gensim/test/test_parsing.py b/gensim/test/test_parsing.py index f96ad332d2..bdf82ab27e 100644 --- a/gensim/test/test_parsing.py +++ b/gensim/test/test_parsing.py @@ -7,8 +7,8 @@ import logging import unittest +from unittest import mock -import mock import numpy as np from gensim.parsing.preprocessing import ( diff --git a/gensim/test/test_poincare.py b/gensim/test/test_poincare.py index ae99335b69..915f07ea21 100644 --- a/gensim/test/test_poincare.py +++ b/gensim/test/test_poincare.py @@ -13,10 +13,7 @@ import os import tempfile import unittest -try: - from mock import Mock -except ImportError: - from unittest.mock import Mock +from unittest.mock import Mock import numpy as np try: diff --git a/gensim/test/test_similarities.py b/gensim/test/test_similarities.py index 314336dadc..ab03551d7c 100644 --- a/gensim/test/test_similarities.py +++ b/gensim/test/test_similarities.py @@ -323,11 +323,11 @@ def test_full(self, num_best=None): # Sparse array. for i, sim in sims: # Note that similarities are bigger than zero, as they are the 1/ 1 + distances. - self.assertTrue(numpy.alltrue(sim > 0.0)) + self.assertTrue(numpy.all(sim > 0.0)) else: self.assertTrue(sims[0] == 1.0) # Similarity of a document with itself is 0.0. - self.assertTrue(numpy.alltrue(sims[1:] > 0.0)) - self.assertTrue(numpy.alltrue(sims[1:] < 1.0)) + self.assertTrue(numpy.all(sims[1:] > 0.0)) + self.assertTrue(numpy.all(sims[1:] < 1.0)) @unittest.skipIf(POT_EXT is False, "POT not installed") def test_non_increasing(self): @@ -354,15 +354,15 @@ def test_chunking(self): sims = index[query] for i in range(3): - self.assertTrue(numpy.alltrue(sims[i, i] == 1.0)) # Similarity of a document with itself is 0.0. + self.assertTrue(numpy.all(sims[i, i] == 1.0)) # Similarity of a document with itself is 0.0. # test the same thing but with num_best index.num_best = 3 sims = index[query] for sims_temp in sims: for i, sim in sims_temp: - self.assertTrue(numpy.alltrue(sim > 0.0)) - self.assertTrue(numpy.alltrue(sim <= 1.0)) + self.assertTrue(numpy.all(sim > 0.0)) + self.assertTrue(numpy.all(sim <= 1.0)) @unittest.skipIf(POT_EXT is False, "POT not installed") def test_iter(self): @@ -370,8 +370,8 @@ def test_iter(self): index = self.cls(TEXTS, self.w2v_model) for sims in index: - self.assertTrue(numpy.alltrue(sims >= 0.0)) - self.assertTrue(numpy.alltrue(sims <= 1.0)) + self.assertTrue(numpy.all(sims >= 0.0)) + self.assertTrue(numpy.all(sims <= 1.0)) @unittest.skipIf(POT_EXT is False, "POT not installed") def test_str(self): @@ -399,12 +399,12 @@ def test_full(self, num_best=None): if num_best is not None: # Sparse array. for i, sim in sims: - self.assertTrue(numpy.alltrue(sim <= 1.0)) - self.assertTrue(numpy.alltrue(sim >= 0.0)) + self.assertTrue(numpy.all(sim <= 1.0)) + self.assertTrue(numpy.all(sim >= 0.0)) else: self.assertAlmostEqual(1.0, sims[0]) # Similarity of a document with itself is 1.0. - self.assertTrue(numpy.alltrue(sims[1:] >= 0.0)) - self.assertTrue(numpy.alltrue(sims[1:] < 1.0)) + self.assertTrue(numpy.all(sims[1:] >= 0.0)) + self.assertTrue(numpy.all(sims[1:] < 1.0)) # Corpora for query in ( @@ -416,15 +416,15 @@ def test_full(self, num_best=None): # Sparse array. for result in sims: for i, sim in result: - self.assertTrue(numpy.alltrue(sim <= 1.0)) - self.assertTrue(numpy.alltrue(sim >= 0.0)) + self.assertTrue(numpy.all(sim <= 1.0)) + self.assertTrue(numpy.all(sim >= 0.0)) else: for i, result in enumerate(sims): self.assertAlmostEqual(1.0, result[i]) # Similarity of a document with itself is 1.0. - self.assertTrue(numpy.alltrue(result[:i] >= 0.0)) - self.assertTrue(numpy.alltrue(result[:i] < 1.0)) - self.assertTrue(numpy.alltrue(result[i + 1:] >= 0.0)) - self.assertTrue(numpy.alltrue(result[i + 1:] < 1.0)) + self.assertTrue(numpy.all(result[:i] >= 0.0)) + self.assertTrue(numpy.all(result[:i] < 1.0)) + self.assertTrue(numpy.all(result[i + 1:] >= 0.0)) + self.assertTrue(numpy.all(result[i + 1:] < 1.0)) def test_non_increasing(self): """ Check that similarities are non-increasing when `num_best` is not `None`.""" @@ -445,7 +445,7 @@ def test_chunking(self): sims = index[query] for i in range(3): - self.assertTrue(numpy.alltrue(sims[i, i] == 1.0)) # Similarity of a document with itself is 1.0. + self.assertTrue(numpy.all(sims[i, i] == 1.0)) # Similarity of a document with itself is 1.0. # test the same thing but with num_best index.num_best = 5 @@ -459,8 +459,8 @@ def test_chunking(self): def test_iter(self): index = self.cls(CORPUS, self.similarity_matrix) for sims in index: - self.assertTrue(numpy.alltrue(sims >= 0.0)) - self.assertTrue(numpy.alltrue(sims <= 1.0)) + self.assertTrue(numpy.all(sims >= 0.0)) + self.assertTrue(numpy.all(sims <= 1.0)) class TestSparseMatrixSimilarity(_TestSimilarityABC): diff --git a/gensim/utils.py b/gensim/utils.py index 755b6c7f0c..2abd5179e0 100644 --- a/gensim/utils.py +++ b/gensim/utils.py @@ -6,7 +6,6 @@ """Various general utility functions.""" -from __future__ import with_statement from contextlib import contextmanager import collections.abc import logging diff --git a/pyproject.toml b/pyproject.toml index 5abdf82efb..515d69c5a8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,8 +7,9 @@ requires = [ "Cython>=0.29.32,<3.0.0", # oldest supported Numpy for this platform is 1.17 but the oldest supported by Gensim # is 1.18.5, remove the line when they increase oldest supported Numpy for this platform - "numpy==1.18.5; python_version=='3.8' and platform_machine not in 'arm64|aarch64'", - "oldest-supported-numpy; python_version>'3.8' or platform_machine in 'arm64|aarch64'", + # 20240604 GM: testing numpy-2.0.0 which requires python >= 3.9 (to 3.12) + "numpy==2.0.0; python_version>='3.9' and platform_machine not in 'arm64|aarch64'", + # "oldest-supported-numpy; python_version>'3.8' or platform_machine in 'arm64|aarch64'", "scipy", "setuptools", "wheel", diff --git a/setup.py b/setup.py index 350869a236..7a20a09f96 100644 --- a/setup.py +++ b/setup.py @@ -272,7 +272,6 @@ def run(self): core_testenv = [ 'pytest', 'pytest-cov', - 'mock', 'testfixtures', ] @@ -325,17 +324,20 @@ def run(self): 'pandas', ] -NUMPY_STR = 'numpy >= 1.18.5' +NUMPY_STR = 'numpy == 2.0.0' install_requires = [ NUMPY_STR, - 'scipy >= 1.7.0', + # + # scipy 1.14.0 and onwards removes deprecated sparsetools submodule + # + 'scipy >= 1.7.0, <1.14.0', 'smart_open >= 1.8.1', ] setup( name='gensim', - version='4.3.2.dev0', + version='4.4.0a0.dev0', description='Python framework for fast Vector Space Modelling', long_description=LONG_DESCRIPTION, @@ -368,7 +370,6 @@ def run(self): 'Environment :: Console', 'Intended Audience :: Science/Research', 'Operating System :: OS Independent', - 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', @@ -380,7 +381,7 @@ def run(self): ], test_suite="gensim.test", - python_requires='>=3.8', + python_requires='>=3.9', install_requires=install_requires, tests_require=linux_testenv, extras_require={