diff --git a/.github/workflows/CI_build.yml b/.github/workflows/CI_build.yml index 82ccce4..fdb92ee 100644 --- a/.github/workflows/CI_build.yml +++ b/.github/workflows/CI_build.yml @@ -24,6 +24,9 @@ jobs: run: | python -m pip install --upgrade pip pip install -e .[dev] + - name: Show pip list + run: | + pip list - name: Test with coverage run: | pytest --cov --cov-report term --cov-report xml --junitxml=xunit-result.xml @@ -50,7 +53,7 @@ jobs: fail-fast: false matrix: os: ['ubuntu-latest', 'macos-latest', 'windows-latest'] - python-version: ['3.7', '3.8'] + python-version: ['3.7', '3.8', '3.9'] exclude: # already tested in first_check job - python-version: 3.8 @@ -160,7 +163,7 @@ jobs: fail-fast: false matrix: os: ['ubuntu-latest', 'macos-latest', 'windows-latest'] - python-version: ['3.7', '3.8'] + python-version: ['3.7', '3.8', '3.9'] runs-on: ${{ matrix.os }} needs: anaconda_build steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f207b4..9f2b7bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## Added + +- Now supports Python 3.9 (including CI test runs) [#40](https://github.com/iomega/spec2vec/issues/40) + ## [0.5.0] - 2021-06-18 ## Changed diff --git a/README.rst b/README.rst index bfe5ca7..0b08293 100644 --- a/README.rst +++ b/README.rst @@ -115,7 +115,7 @@ Installation Prerequisites: -- Python 3.7 or 3.8 +- Python 3.7, 3.8, or 3.9 - Recommended: Anaconda We recommend installing spec2vec from Anaconda Cloud with diff --git a/conda/environment-build.yml b/conda/environment-build.yml index fad9dd6..c5baf80 100644 --- a/conda/environment-build.yml +++ b/conda/environment-build.yml @@ -5,4 +5,4 @@ dependencies: - anaconda-client - conda-build - conda-verify - - python >=3.7,<3.9 + - python >=3.7 diff --git a/conda/environment-dev.yml b/conda/environment-dev.yml index 743e3b9..78d3c57 100644 --- a/conda/environment-dev.yml +++ b/conda/environment-dev.yml @@ -10,7 +10,7 @@ dependencies: - numba >=0.51 - numpy - pip - - python >=3.7,<3.9 + - python >=3.7 - tqdm - pip: - -e ..[dev] diff --git a/conda/environment.yml b/conda/environment.yml index dd7000f..9467d60 100644 --- a/conda/environment.yml +++ b/conda/environment.yml @@ -8,5 +8,5 @@ dependencies: - matchms >=0.6.2 - numba >=0.51 - numpy - - python >=3.7,<3.9 + - python >=3.7 - tqdm diff --git a/conda/meta.yaml b/conda/meta.yaml index d09be8b..14026cb 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -31,7 +31,7 @@ requirements: - numpy {{ numpy }} - setuptools host: - - python >=3.7,<3.9 + - python >=3.7 - pip - pytest-runner - setuptools @@ -41,7 +41,7 @@ requirements: - numba >=0.51 - numpy - pip - - python >=3.7,<3.9 + - python >=3.7 - tqdm test: diff --git a/setup.py b/setup.py index 1582c71..c3e994d 100644 --- a/setup.py +++ b/setup.py @@ -55,6 +55,7 @@ ], extras_require={"dev": ["bump2version", "isort>=4.2.5,<5", + "pylint<2.12.0", "prospector[with_pyroma]", "pytest", "pytest-cov", diff --git a/spec2vec/SpectrumDocument.py b/spec2vec/SpectrumDocument.py index 70c8925..4c0c2da 100644 --- a/spec2vec/SpectrumDocument.py +++ b/spec2vec/SpectrumDocument.py @@ -57,10 +57,9 @@ def __init__(self, spectrum, n_decimals: int = 2): def _make_words(self): """Create word from peaks (and losses).""" - format_string = "{}@{:." + "{}".format(self.n_decimals) + "f}" - peak_words = [format_string.format("peak", mz) for mz in self._obj.peaks.mz] + peak_words = [f"peak@{mz:.{self.n_decimals}f}" for mz in self._obj.peaks.mz] if self._obj.losses is not None: - loss_words = [format_string.format("loss", mz) for mz in self._obj.losses.mz] + loss_words = [f"loss@{mz:.{self.n_decimals}f}" for mz in self._obj.losses.mz] else: loss_words = [] self.words = peak_words + loss_words diff --git a/spec2vec/model_building.py b/spec2vec/model_building.py index 692d84c..85779ee 100644 --- a/spec2vec/model_building.py +++ b/spec2vec/model_building.py @@ -116,12 +116,11 @@ def set_spec2vec_defaults(**settings): assert "alpha" not in settings, "Expect 'learning_rate_initial' instead of 'alpha'." # Set default parameters or replace by **settings input - for key in defaults: + for key, value in defaults.items(): if key in settings: - print("The value of {} is set from {} (default) to {}".format(key, defaults[key], - settings[key])) + print(f"The value of {key} is set from {value} (default) to {settings[key]}") else: - settings[key] = defaults[key] + settings[key] = value return settings @@ -166,7 +165,7 @@ def set_learning_rate_decay(learning_rate_initial: float, learning_rate_decay: f min_alpha = learning_rate_initial - num_of_epochs * learning_rate_decay if min_alpha < 0: print("Warning! Number of total iterations is too high for given learning_rate decay.") - print("Learning_rate_decay will be set from {} to {}.".format(learning_rate_decay, - learning_rate_initial/num_of_epochs)) + print("Learning_rate_decay will be set from {learning_rate_decay} ", + "to {learning_rate_initial/num_of_epochs}.") min_alpha = 0 return learning_rate_initial, min_alpha diff --git a/spec2vec/utils.py b/spec2vec/utils.py index d03c665..cee52e0 100644 --- a/spec2vec/utils.py +++ b/spec2vec/utils.py @@ -24,7 +24,7 @@ def on_epoch_end(self, model): print('\r', ' Epoch ' + str(self.epoch+1) + ' of ' + str(self.num_of_epochs) + '.', end="") - print('Change in loss after epoch {}: {}'.format(self.epoch+1, loss - self.loss)) + print(f'Change in loss after epoch {self.epoch + 1}: {loss - self.loss}') self.epoch += 1 self.loss = loss @@ -56,7 +56,7 @@ def on_epoch_end(self, model): if self.filename and self.epoch in self.iterations: if self.epoch < self.num_of_epochs: - filename = self.filename.split(".model")[0] + "_iter_{}.model".format(self.epoch) + filename = f"{self.filename.split('.model')[0]}_iter_{self.epoch}.model" else: filename = self.filename print("Saving model with name:", filename) diff --git a/spec2vec/vector_operations.py b/spec2vec/vector_operations.py index 536a645..7d13bea 100644 --- a/spec2vec/vector_operations.py +++ b/spec2vec/vector_operations.py @@ -41,8 +41,8 @@ def _check_model_coverage(): weights_missing_raised = numpy.power(weights_missing, intensity_weighting_power) missing_percentage = 100 * weights_missing_raised.sum() / (weights_raised.sum() + weights_missing_raised.sum()) - print("Found {} word(s) missing in the model.".format(len(idx_not_in_model)), - "Weighted missing percentage not covered by the given model is {:.2f}%.".format(missing_percentage)) + print(f"Found {len(idx_not_in_model)} word(s) missing in the model.", + f"Weighted missing percentage not covered by the given model is {missing_percentage:.2f}%.") message = ("Missing percentage is larger than set maximum.", "Consider retraining the used model or increasing the allowed percentage.") diff --git a/tests/test_version_string_consistency.py b/tests/test_version_string_consistency.py index 3d127eb..f7cb8ce 100644 --- a/tests/test_version_string_consistency.py +++ b/tests/test_version_string_consistency.py @@ -9,7 +9,7 @@ def test_version_string_consistency(): repository_root = os.path.join(os.path.dirname(__file__), "..") fixture = os.path.join(repository_root, "conda", "meta.yaml") - with open(fixture, "r") as f: + with open(fixture, "r", encoding="utf-8") as f: metayaml_contents = f.read() match = re.search(r"^{% set version = \"(?P.*)\" %}$", metayaml_contents, re.MULTILINE)