From a4e8c2c674c8cb27a1d0f122d0a6ecbeb78e0a1b Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Thu, 22 Aug 2024 10:34:50 +0800 Subject: [PATCH 01/20] drop python 3.9 --- .github/workflows/test.yml | 2 +- README.md | 2 +- pylintrc | 2 +- pyproject.toml | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 24e816d9a..a65bd38fc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ jobs: max-parallel: 20 matrix: os: [ubuntu-latest, macos-14, windows-latest] - python-version: ["3.9", "3.x"] + python-version: ["3.10", "3.x"] runs-on: ${{ matrix.os }} diff --git a/README.md b/README.md index 08be028f0..3b5d01ff6 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,6 @@ Monty is created to serve as a complement to the Python standard library. It provides suite of tools to solve many common problems, and hopefully, be a resource to collect the best solutions. -Monty supports Python 3.x. +Monty supports Python 3.10+. Please visit the [official docs](https://materialsvirtuallab.github.io/monty) for more information. diff --git a/pylintrc b/pylintrc index 932c509e4..d339072e0 100644 --- a/pylintrc +++ b/pylintrc @@ -80,7 +80,7 @@ persistent=yes # Minimum Python version to use for version dependent checks. Will default to # the version used to run pylint. -py-version=3.9 +py-version=3.10 # Discover python modules and packages in the file system subtree. recursive=no diff --git a/pyproject.toml b/pyproject.toml index b0b8683ab..445ef4435 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools", "setuptools-scm"] +requires = ["setuptools", "setuptools-scm", "numpy>=2.1.0",] build-backend = "setuptools.build_meta" [project] @@ -9,7 +9,7 @@ maintainers = [ ] description = "Monty is the missing complement to Python." readme = "README.md" -requires-python = ">=3.9" +requires-python = ">=3.10" classifiers = [ "Programming Language :: Python :: 3", "Development Status :: 4 - Beta", @@ -51,7 +51,7 @@ include = ["monty"] [tool.black] line-length = 120 -target-version = ['py39'] +target-version = ['py310'] include = '\.pyi?$' exclude = ''' From fc3776bff722b7c92acfd10b00e36e357c39b90f Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Thu, 22 Aug 2024 10:38:43 +0800 Subject: [PATCH 02/20] make module var all cap --- tests/test_shutil.py | 90 ++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/tests/test_shutil.py b/tests/test_shutil.py index 16cd9aa78..a334bf17b 100644 --- a/tests/test_shutil.py +++ b/tests/test_shutil.py @@ -19,57 +19,57 @@ remove, ) -test_dir = os.path.join(os.path.dirname(__file__), "test_files") +TEST_DIR = os.path.join(os.path.dirname(__file__), "test_files") class TestCopyR: def setup_method(self): - os.mkdir(os.path.join(test_dir, "cpr_src")) - with open(os.path.join(test_dir, "cpr_src", "test"), "w") as f: + os.mkdir(os.path.join(TEST_DIR, "cpr_src")) + with open(os.path.join(TEST_DIR, "cpr_src", "test"), "w") as f: f.write("what") - os.mkdir(os.path.join(test_dir, "cpr_src", "sub")) - with open(os.path.join(test_dir, "cpr_src", "sub", "testr"), "w") as f: + os.mkdir(os.path.join(TEST_DIR, "cpr_src", "sub")) + with open(os.path.join(TEST_DIR, "cpr_src", "sub", "testr"), "w") as f: f.write("what2") if os.name != "nt": os.symlink( - os.path.join(test_dir, "cpr_src", "test"), - os.path.join(test_dir, "cpr_src", "mysymlink"), + os.path.join(TEST_DIR, "cpr_src", "test"), + os.path.join(TEST_DIR, "cpr_src", "mysymlink"), ) def test_recursive_copy_and_compress(self): - copy_r(os.path.join(test_dir, "cpr_src"), os.path.join(test_dir, "cpr_dst")) - assert os.path.exists(os.path.join(test_dir, "cpr_dst", "test")) - assert os.path.exists(os.path.join(test_dir, "cpr_dst", "sub", "testr")) - - compress_dir(os.path.join(test_dir, "cpr_src")) - assert os.path.exists(os.path.join(test_dir, "cpr_src", "test.gz")) - assert os.path.exists(os.path.join(test_dir, "cpr_src", "sub", "testr.gz")) - - decompress_dir(os.path.join(test_dir, "cpr_src")) - assert os.path.exists(os.path.join(test_dir, "cpr_src", "test")) - assert os.path.exists(os.path.join(test_dir, "cpr_src", "sub", "testr")) - with open(os.path.join(test_dir, "cpr_src", "test")) as f: + copy_r(os.path.join(TEST_DIR, "cpr_src"), os.path.join(TEST_DIR, "cpr_dst")) + assert os.path.exists(os.path.join(TEST_DIR, "cpr_dst", "test")) + assert os.path.exists(os.path.join(TEST_DIR, "cpr_dst", "sub", "testr")) + + compress_dir(os.path.join(TEST_DIR, "cpr_src")) + assert os.path.exists(os.path.join(TEST_DIR, "cpr_src", "test.gz")) + assert os.path.exists(os.path.join(TEST_DIR, "cpr_src", "sub", "testr.gz")) + + decompress_dir(os.path.join(TEST_DIR, "cpr_src")) + assert os.path.exists(os.path.join(TEST_DIR, "cpr_src", "test")) + assert os.path.exists(os.path.join(TEST_DIR, "cpr_src", "sub", "testr")) + with open(os.path.join(TEST_DIR, "cpr_src", "test")) as f: txt = f.read() assert txt == "what" def test_pathlib(self): - test_path = Path(test_dir) + test_path = Path(TEST_DIR) copy_r(test_path / "cpr_src", test_path / "cpr_dst") assert (test_path / "cpr_dst" / "test").exists() assert (test_path / "cpr_dst" / "sub" / "testr").exists() def teardown_method(self): - shutil.rmtree(os.path.join(test_dir, "cpr_src")) - shutil.rmtree(os.path.join(test_dir, "cpr_dst")) + shutil.rmtree(os.path.join(TEST_DIR, "cpr_src")) + shutil.rmtree(os.path.join(TEST_DIR, "cpr_dst")) class TestCompressFileDir: def setup_method(self): - with open(os.path.join(test_dir, "tempfile"), "w") as f: + with open(os.path.join(TEST_DIR, "tempfile"), "w") as f: f.write("hello world") def test_compress_and_decompress_file(self): - fname = os.path.join(test_dir, "tempfile") + fname = os.path.join(TEST_DIR, "tempfile") for fmt in ["gz", "bz2"]: compress_file(fname, fmt) @@ -92,8 +92,8 @@ def test_compress_and_decompress_file(self): assert decompress_file("non-existent.bz2") is None def test_compress_and_decompress_with_target_dir(self): - fname = os.path.join(test_dir, "tempfile") - target_dir = os.path.join(test_dir, "temp_target_dir") + fname = os.path.join(TEST_DIR, "tempfile") + target_dir = os.path.join(TEST_DIR, "temp_target_dir") for fmt in ["gz", "bz2"]: compress_file(fname, fmt, target_dir) @@ -116,20 +116,20 @@ def test_compress_and_decompress_with_target_dir(self): assert f.read() == "hello world" def teardown_method(self): - os.remove(os.path.join(test_dir, "tempfile")) + os.remove(os.path.join(TEST_DIR, "tempfile")) class TestGzipDir: def setup_method(self): - os.mkdir(os.path.join(test_dir, "gzip_dir")) - with open(os.path.join(test_dir, "gzip_dir", "tempfile"), "w") as f: + os.mkdir(os.path.join(TEST_DIR, "gzip_dir")) + with open(os.path.join(TEST_DIR, "gzip_dir", "tempfile"), "w") as f: f.write("what") - self.mtime = os.path.getmtime(os.path.join(test_dir, "gzip_dir", "tempfile")) + self.mtime = os.path.getmtime(os.path.join(TEST_DIR, "gzip_dir", "tempfile")) def test_gzip_dir(self): - full_f = os.path.join(test_dir, "gzip_dir", "tempfile") - gzip_dir(os.path.join(test_dir, "gzip_dir")) + full_f = os.path.join(TEST_DIR, "gzip_dir", "tempfile") + gzip_dir(os.path.join(TEST_DIR, "gzip_dir")) assert os.path.exists(f"{full_f}.gz") assert not os.path.exists(full_f) @@ -141,7 +141,7 @@ def test_gzip_dir(self): def test_gzip_dir_file_coexist(self): """Test case where both file and file.gz exist.""" - full_f = os.path.join(test_dir, "gzip_dir", "temptestfile") + full_f = os.path.join(TEST_DIR, "gzip_dir", "temptestfile") gz_f = f"{full_f}.gz" # Create both the file and its gzipped version @@ -153,7 +153,7 @@ def test_gzip_dir_file_coexist(self): with pytest.warns( UserWarning, match="Both temptestfile and temptestfile.gz exist." ): - gzip_dir(os.path.join(test_dir, "gzip_dir")) + gzip_dir(os.path.join(TEST_DIR, "gzip_dir")) # Verify contents of the files with open(full_f, "r") as f: @@ -163,13 +163,13 @@ def test_gzip_dir_file_coexist(self): assert g.read() == b"gzipped" def test_handle_sub_dirs(self): - sub_dir = os.path.join(test_dir, "gzip_dir", "sub_dir") + sub_dir = os.path.join(TEST_DIR, "gzip_dir", "sub_dir") sub_file = os.path.join(sub_dir, "new_tempfile") os.mkdir(sub_dir) with open(sub_file, "w") as f: f.write("anotherwhat") - gzip_dir(os.path.join(test_dir, "gzip_dir")) + gzip_dir(os.path.join(TEST_DIR, "gzip_dir")) assert os.path.exists(f"{sub_file}.gz") assert not os.path.exists(sub_file) @@ -178,13 +178,13 @@ def test_handle_sub_dirs(self): assert g.readline().decode("utf-8") == "anotherwhat" def teardown_method(self): - shutil.rmtree(os.path.join(test_dir, "gzip_dir")) + shutil.rmtree(os.path.join(TEST_DIR, "gzip_dir")) class TestRemove: @unittest.skipIf(platform.system() == "Windows", "Skip on windows") def test_remove_file(self): - tempdir = tempfile.mkdtemp(dir=test_dir) + tempdir = tempfile.mkdtemp(dir=TEST_DIR) tempf = tempfile.mkstemp(dir=tempdir)[1] remove(tempf) assert not os.path.isfile(tempf) @@ -192,17 +192,17 @@ def test_remove_file(self): @unittest.skipIf(platform.system() == "Windows", "Skip on windows") def test_remove_folder(self): - tempdir = tempfile.mkdtemp(dir=test_dir) + tempdir = tempfile.mkdtemp(dir=TEST_DIR) remove(tempdir) assert not os.path.isdir(tempdir) @unittest.skipIf(platform.system() == "Windows", "Skip on windows") def test_remove_symlink(self): - tempdir = tempfile.mkdtemp(dir=test_dir) + tempdir = tempfile.mkdtemp(dir=TEST_DIR) tempf = tempfile.mkstemp(dir=tempdir)[1] - os.symlink(tempdir, os.path.join(test_dir, "temp_link")) - templink = os.path.join(test_dir, "temp_link") + os.symlink(tempdir, os.path.join(TEST_DIR, "temp_link")) + templink = os.path.join(TEST_DIR, "temp_link") remove(templink) assert os.path.isfile(tempf) assert os.path.isdir(tempdir) @@ -211,11 +211,11 @@ def test_remove_symlink(self): @unittest.skipIf(platform.system() == "Windows", "Skip on windows") def test_remove_symlink_follow(self): - tempdir = tempfile.mkdtemp(dir=test_dir) + tempdir = tempfile.mkdtemp(dir=TEST_DIR) tempf = tempfile.mkstemp(dir=tempdir)[1] - os.symlink(tempdir, os.path.join(test_dir, "temp_link")) - templink = os.path.join(test_dir, "temp_link") + os.symlink(tempdir, os.path.join(TEST_DIR, "temp_link")) + templink = os.path.join(TEST_DIR, "temp_link") remove(templink, follow_symlink=True) assert not os.path.isfile(tempf) assert not os.path.isdir(tempdir) From b100e39c4c891f97fb0a7ed2963d83053867dce1 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Thu, 22 Aug 2024 10:40:50 +0800 Subject: [PATCH 03/20] NEED CONFIRM: drop black linter in favor of ruff --- pyproject.toml | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 445ef4435..8af7fef67 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,29 +49,6 @@ docs = [ where = ["src"] include = ["monty"] -[tool.black] -line-length = 120 -target-version = ['py310'] -include = '\.pyi?$' -exclude = ''' - -( - /( - \.eggs # exclude a few common directories in the - | \.git # root of the project - | \.hg - | \.mypy_cache - | \.tox - | \.venv - | _build - | buck-out - | build - | dist - | tests - )/ -) -''' - [tool.coverage.run] branch = true From 8a593be076696ef8f4892d526643addd5a4670b9 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Thu, 22 Aug 2024 10:41:09 +0800 Subject: [PATCH 04/20] ruff fix imports --- tasks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tasks.py b/tasks.py index 921412adb..7432034a0 100755 --- a/tasks.py +++ b/tasks.py @@ -11,6 +11,7 @@ import requests from invoke import task + from monty import __version__ as ver from monty.os import cd From da9c95fdeb829bd29794b9ede09dc2983315c666 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Thu, 22 Aug 2024 10:43:56 +0800 Subject: [PATCH 05/20] Revert "NEED CONFIRM: drop black linter in favor of ruff" This reverts commit b100e39c4c891f97fb0a7ed2963d83053867dce1. --- pyproject.toml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 8af7fef67..445ef4435 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,6 +49,29 @@ docs = [ where = ["src"] include = ["monty"] +[tool.black] +line-length = 120 +target-version = ['py310'] +include = '\.pyi?$' +exclude = ''' + +( + /( + \.eggs # exclude a few common directories in the + | \.git # root of the project + | \.hg + | \.mypy_cache + | \.tox + | \.venv + | _build + | buck-out + | build + | dist + | tests + )/ +) +''' + [tool.coverage.run] branch = true From 40296140d9b620504f1833a653251dee1d9adb08 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Thu, 22 Aug 2024 10:48:37 +0800 Subject: [PATCH 06/20] bump supported numpy to 2.x in optional dependency --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 445ef4435..e475a8c01 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools", "setuptools-scm", "numpy>=2.1.0",] +requires = ["setuptools", "setuptools-scm",] build-backend = "setuptools.build_meta" [project] @@ -28,7 +28,7 @@ ci = [ "pytest>=8", "pytest-cov>=4", "coverage", - "numpy<2.0.0", + "numpy<3", "ruamel.yaml", "msgpack", "tqdm", From fa30c361ad36c3adc9effcb871cdc54e21507c9b Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Thu, 22 Aug 2024 10:54:20 +0800 Subject: [PATCH 07/20] bumpy codecov action to v4 --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a65bd38fc..67f18a460 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -29,6 +29,6 @@ jobs: run: pytest --cov=monty --cov-report html:coverage_reports tests - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} From f0a873bb90336dadf95d93b7385499d780d296eb Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Thu, 22 Aug 2024 10:55:27 +0800 Subject: [PATCH 08/20] turn off fail-fast --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 67f18a460..623ae3492 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,6 +5,7 @@ on: [push, pull_request, workflow_call] jobs: build: strategy: + fail-fast: false max-parallel: 20 matrix: os: [ubuntu-latest, macos-14, windows-latest] From 82cc2825ef648dd16d6c4c6ceadd2258c39ab3b0 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Thu, 22 Aug 2024 11:03:16 +0800 Subject: [PATCH 09/20] remove extra comma --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e475a8c01..576719a2e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools", "setuptools-scm",] +requires = ["setuptools", "setuptools-scm"] build-backend = "setuptools.build_meta" [project] From 5a5bc047b685b304a877596a562ba2a758a5d54d Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Thu, 22 Aug 2024 11:07:27 +0800 Subject: [PATCH 10/20] remove blank line --- pyproject.toml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 576719a2e..017e0403b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,10 +51,9 @@ include = ["monty"] [tool.black] line-length = 120 -target-version = ['py310'] +target-version = ["py310"] include = '\.pyi?$' exclude = ''' - ( /( \.eggs # exclude a few common directories in the @@ -97,7 +96,7 @@ ignore_missing_imports = true [tool.ruff] lint.select = [ - "I", #isort + "I", # isort ] lint.isort.required-imports = ["from __future__ import annotations"] From 579cf02b1a8ca25c75ffb9610525b77b7f8561f4 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Thu, 22 Aug 2024 11:39:47 +0800 Subject: [PATCH 11/20] add monty as first party import --- pyproject.toml | 8 ++++---- tests/test_collections.py | 1 + tests/test_design_patterns.py | 1 + tests/test_dev.py | 1 + tests/test_fractions.py | 1 + tests/test_functools.py | 1 + tests/test_io.py | 1 + tests/test_json.py | 1 + tests/test_os.py | 1 + tests/test_shutil.py | 1 + tests/test_tempfile.py | 1 + 11 files changed, 14 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 017e0403b..0ed6acd8a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,9 +94,9 @@ exclude_also = [ [tool.mypy] ignore_missing_imports = true -[tool.ruff] -lint.select = [ +[tool.ruff.lint] +select = [ "I", # isort ] - -lint.isort.required-imports = ["from __future__ import annotations"] +isort.required-imports = ["from __future__ import annotations"] +isort.known-first-party = ["monty"] diff --git a/tests/test_collections.py b/tests/test_collections.py index 8057f7bc2..58d2af9e7 100644 --- a/tests/test_collections.py +++ b/tests/test_collections.py @@ -3,6 +3,7 @@ import os import pytest + from monty.collections import AttrDict, FrozenAttrDict, Namespace, frozendict, tree TEST_DIR = os.path.join(os.path.dirname(__file__), "test_files") diff --git a/tests/test_design_patterns.py b/tests/test_design_patterns.py index c37bc87da..67a7ffc2b 100644 --- a/tests/test_design_patterns.py +++ b/tests/test_design_patterns.py @@ -6,6 +6,7 @@ from typing import Any import pytest + from monty.design_patterns import cached_class, singleton diff --git a/tests/test_dev.py b/tests/test_dev.py index 8c44d8aec..13bb211be 100644 --- a/tests/test_dev.py +++ b/tests/test_dev.py @@ -7,6 +7,7 @@ from unittest.mock import patch import pytest + from monty.dev import deprecated, install_excepthook, requires # Set all warnings to always be triggered. diff --git a/tests/test_fractions.py b/tests/test_fractions.py index 7d5f27709..230dcf5a7 100644 --- a/tests/test_fractions.py +++ b/tests/test_fractions.py @@ -1,6 +1,7 @@ from __future__ import annotations import pytest + from monty.fractions import gcd, gcd_float, lcm diff --git a/tests/test_functools.py b/tests/test_functools.py index 8bf3fabff..120e6bd75 100644 --- a/tests/test_functools.py +++ b/tests/test_functools.py @@ -5,6 +5,7 @@ import unittest import pytest + from monty.functools import ( TimeoutError, lazy_property, diff --git a/tests/test_io.py b/tests/test_io.py index 9daa17bef..052bc471b 100644 --- a/tests/test_io.py +++ b/tests/test_io.py @@ -5,6 +5,7 @@ from unittest.mock import patch import pytest + from monty.io import ( FileLock, FileLockException, diff --git a/tests/test_json.py b/tests/test_json.py index 9c9e572c7..9e878311b 100644 --- a/tests/test_json.py +++ b/tests/test_json.py @@ -39,6 +39,7 @@ ObjectId = None import pytest + from monty.json import ( MontyDecoder, MontyEncoder, diff --git a/tests/test_os.py b/tests/test_os.py index c6ca8d7ca..af5b156f4 100644 --- a/tests/test_os.py +++ b/tests/test_os.py @@ -4,6 +4,7 @@ from pathlib import Path import pytest + from monty.os import cd, makedirs_p from monty.os.path import find_exts, zpath diff --git a/tests/test_shutil.py b/tests/test_shutil.py index a334bf17b..dfc1375fd 100644 --- a/tests/test_shutil.py +++ b/tests/test_shutil.py @@ -9,6 +9,7 @@ from pathlib import Path import pytest + from monty.shutil import ( compress_dir, compress_file, diff --git a/tests/test_tempfile.py b/tests/test_tempfile.py index 4dfd3b17f..088aec670 100644 --- a/tests/test_tempfile.py +++ b/tests/test_tempfile.py @@ -4,6 +4,7 @@ import shutil import pytest + from monty.tempfile import ScratchDir TEST_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "test_files") From f8b862db4f3a07aa816400b22c90a72c320d4d70 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Thu, 22 Aug 2024 11:42:44 +0800 Subject: [PATCH 12/20] remove pragma hint --- pyproject.toml | 8 ++++---- src/monty/__init__.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 0ed6acd8a..1042efeea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,7 +19,6 @@ classifiers = [ "Topic :: Software Development :: Libraries :: Python Modules", ] dependencies = [ - ] version = "2024.7.30" @@ -82,7 +81,6 @@ exclude_also = [ "if __name__ == .__main__.:", "if self.debug:", "if settings.DEBUG", - "pragma: no cover", "raise AssertionError", "raise NotImplementedError", "show_plot", @@ -98,5 +96,7 @@ ignore_missing_imports = true select = [ "I", # isort ] -isort.required-imports = ["from __future__ import annotations"] -isort.known-first-party = ["monty"] + +[tool.ruff.isort] +required-imports = ["from __future__ import annotations"] +known-first-party = ["monty"] diff --git a/src/monty/__init__.py b/src/monty/__init__.py index 7ca10bb28..ef9f63547 100644 --- a/src/monty/__init__.py +++ b/src/monty/__init__.py @@ -17,6 +17,6 @@ try: __version__ = version("monty") -except PackageNotFoundError: # pragma: no cover +except PackageNotFoundError: # package is not installed pass From acdae894a230229844493495f09aefa2b133dd30 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Thu, 22 Aug 2024 11:45:35 +0800 Subject: [PATCH 13/20] remove non-existent exclude pattern --- pyproject.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1042efeea..2371e082d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -77,15 +77,12 @@ branch = true exclude_also = [ "@deprecated", "def __repr__", - "if 0:", - "if __name__ == .__main__.:", "if self.debug:", "if settings.DEBUG", "raise AssertionError", "raise NotImplementedError", "show_plot", "if TYPE_CHECKING:", - "if typing.TYPE_CHECKING:", "except ImportError:" ] From 278f1f90551e9fd35adb806bba475b136c858711 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Thu, 22 Aug 2024 11:50:27 +0800 Subject: [PATCH 14/20] access isort thru lint --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 2371e082d..b1c272f93 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,6 +94,6 @@ select = [ "I", # isort ] -[tool.ruff.isort] +[tool.ruff.lint.isort] required-imports = ["from __future__ import annotations"] known-first-party = ["monty"] From 6d642450d7719255d1fd442b8eb710cd11b9b828 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Thu, 22 Aug 2024 11:58:12 +0800 Subject: [PATCH 15/20] recover pragma: no cover tag --- pyproject.toml | 1 + src/monty/__init__.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b1c272f93..a1c6cb64d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -79,6 +79,7 @@ exclude_also = [ "def __repr__", "if self.debug:", "if settings.DEBUG", + "pragma: no cover", "raise AssertionError", "raise NotImplementedError", "show_plot", diff --git a/src/monty/__init__.py b/src/monty/__init__.py index ef9f63547..7ca10bb28 100644 --- a/src/monty/__init__.py +++ b/src/monty/__init__.py @@ -17,6 +17,6 @@ try: __version__ = version("monty") -except PackageNotFoundError: +except PackageNotFoundError: # pragma: no cover # package is not installed pass From 2789d2b0719386a87e13f37581cdc5857f08bdb2 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Thu, 22 Aug 2024 22:41:36 +0800 Subject: [PATCH 16/20] add missing pydantic dep --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index a1c6cb64d..da65c8dc1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,6 +34,7 @@ ci = [ "pymongo", "pandas", "pint", + "pydantic", "orjson", "types-orjson", "types-requests", From 54697de83ffd30b515612a88c50e574a9a0c87ad Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Thu, 22 Aug 2024 22:45:23 +0800 Subject: [PATCH 17/20] still use np2 ATM, one thing at a time --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index da65c8dc1..f392ff77f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,7 @@ ci = [ "pytest>=8", "pytest-cov>=4", "coverage", - "numpy<3", + "numpy<2", "ruamel.yaml", "msgpack", "tqdm", From 9b635b7ca7c562f0c09a9afabf99cc7553cd7334 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Tue, 22 Oct 2024 10:36:05 +0800 Subject: [PATCH 18/20] sync ci dep --- pyproject.toml | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d42e13247..a34737239 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,21 +26,11 @@ version = "2024.10.21" [project.optional-dependencies] ci = [ - "pytest>=8", - "pytest-cov>=4", - "coverage", - "numpy<2", - "ruamel.yaml", - "msgpack", - "tqdm", - "pymongo", - "pandas", - "pint", - "pydantic", - "orjson", - "types-orjson", - "types-requests", - "torch" + "coverage", + "monty[optional]", + "pytest>=8", + "pytest-cov>=4", + "types-requests", ] # dev is for "dev" module, not for development dev = ["ipython"] From 0b5e33ec3e6f12af561f3caa888ed69520a58507 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Tue, 22 Oct 2024 10:37:05 +0800 Subject: [PATCH 19/20] remove duplicate after merge --- tests/test_json.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/tests/test_json.py b/tests/test_json.py index 0605a0d36..e59e89d57 100644 --- a/tests/test_json.py +++ b/tests/test_json.py @@ -47,19 +47,6 @@ except ImportError: ObjectId = None -import pytest - -from monty.json import ( - MontyDecoder, - MontyEncoder, - MSONable, - _load_redirect, - jsanitize, - load, -) - -from . import __version__ as tests_version - TEST_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "test_files") From 7f261d8bd1e3a61f79b30a146b98a2f3e89d3c33 Mon Sep 17 00:00:00 2001 From: "Haoyu (Daniel)" Date: Tue, 22 Oct 2024 10:37:39 +0800 Subject: [PATCH 20/20] migrate code clean up change --- tests/test_shutil.py | 90 ++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/tests/test_shutil.py b/tests/test_shutil.py index dfc1375fd..e506b4ae4 100644 --- a/tests/test_shutil.py +++ b/tests/test_shutil.py @@ -20,57 +20,57 @@ remove, ) -TEST_DIR = os.path.join(os.path.dirname(__file__), "test_files") +test_dir = os.path.join(os.path.dirname(__file__), "test_files") class TestCopyR: def setup_method(self): - os.mkdir(os.path.join(TEST_DIR, "cpr_src")) - with open(os.path.join(TEST_DIR, "cpr_src", "test"), "w") as f: + os.mkdir(os.path.join(test_dir, "cpr_src")) + with open(os.path.join(test_dir, "cpr_src", "test"), "w") as f: f.write("what") - os.mkdir(os.path.join(TEST_DIR, "cpr_src", "sub")) - with open(os.path.join(TEST_DIR, "cpr_src", "sub", "testr"), "w") as f: + os.mkdir(os.path.join(test_dir, "cpr_src", "sub")) + with open(os.path.join(test_dir, "cpr_src", "sub", "testr"), "w") as f: f.write("what2") if os.name != "nt": os.symlink( - os.path.join(TEST_DIR, "cpr_src", "test"), - os.path.join(TEST_DIR, "cpr_src", "mysymlink"), + os.path.join(test_dir, "cpr_src", "test"), + os.path.join(test_dir, "cpr_src", "mysymlink"), ) def test_recursive_copy_and_compress(self): - copy_r(os.path.join(TEST_DIR, "cpr_src"), os.path.join(TEST_DIR, "cpr_dst")) - assert os.path.exists(os.path.join(TEST_DIR, "cpr_dst", "test")) - assert os.path.exists(os.path.join(TEST_DIR, "cpr_dst", "sub", "testr")) - - compress_dir(os.path.join(TEST_DIR, "cpr_src")) - assert os.path.exists(os.path.join(TEST_DIR, "cpr_src", "test.gz")) - assert os.path.exists(os.path.join(TEST_DIR, "cpr_src", "sub", "testr.gz")) - - decompress_dir(os.path.join(TEST_DIR, "cpr_src")) - assert os.path.exists(os.path.join(TEST_DIR, "cpr_src", "test")) - assert os.path.exists(os.path.join(TEST_DIR, "cpr_src", "sub", "testr")) - with open(os.path.join(TEST_DIR, "cpr_src", "test")) as f: + copy_r(os.path.join(test_dir, "cpr_src"), os.path.join(test_dir, "cpr_dst")) + assert os.path.exists(os.path.join(test_dir, "cpr_dst", "test")) + assert os.path.exists(os.path.join(test_dir, "cpr_dst", "sub", "testr")) + + compress_dir(os.path.join(test_dir, "cpr_src")) + assert os.path.exists(os.path.join(test_dir, "cpr_src", "test.gz")) + assert os.path.exists(os.path.join(test_dir, "cpr_src", "sub", "testr.gz")) + + decompress_dir(os.path.join(test_dir, "cpr_src")) + assert os.path.exists(os.path.join(test_dir, "cpr_src", "test")) + assert os.path.exists(os.path.join(test_dir, "cpr_src", "sub", "testr")) + with open(os.path.join(test_dir, "cpr_src", "test")) as f: txt = f.read() assert txt == "what" def test_pathlib(self): - test_path = Path(TEST_DIR) + test_path = Path(test_dir) copy_r(test_path / "cpr_src", test_path / "cpr_dst") assert (test_path / "cpr_dst" / "test").exists() assert (test_path / "cpr_dst" / "sub" / "testr").exists() def teardown_method(self): - shutil.rmtree(os.path.join(TEST_DIR, "cpr_src")) - shutil.rmtree(os.path.join(TEST_DIR, "cpr_dst")) + shutil.rmtree(os.path.join(test_dir, "cpr_src")) + shutil.rmtree(os.path.join(test_dir, "cpr_dst")) class TestCompressFileDir: def setup_method(self): - with open(os.path.join(TEST_DIR, "tempfile"), "w") as f: + with open(os.path.join(test_dir, "tempfile"), "w") as f: f.write("hello world") def test_compress_and_decompress_file(self): - fname = os.path.join(TEST_DIR, "tempfile") + fname = os.path.join(test_dir, "tempfile") for fmt in ["gz", "bz2"]: compress_file(fname, fmt) @@ -93,8 +93,8 @@ def test_compress_and_decompress_file(self): assert decompress_file("non-existent.bz2") is None def test_compress_and_decompress_with_target_dir(self): - fname = os.path.join(TEST_DIR, "tempfile") - target_dir = os.path.join(TEST_DIR, "temp_target_dir") + fname = os.path.join(test_dir, "tempfile") + target_dir = os.path.join(test_dir, "temp_target_dir") for fmt in ["gz", "bz2"]: compress_file(fname, fmt, target_dir) @@ -117,20 +117,20 @@ def test_compress_and_decompress_with_target_dir(self): assert f.read() == "hello world" def teardown_method(self): - os.remove(os.path.join(TEST_DIR, "tempfile")) + os.remove(os.path.join(test_dir, "tempfile")) class TestGzipDir: def setup_method(self): - os.mkdir(os.path.join(TEST_DIR, "gzip_dir")) - with open(os.path.join(TEST_DIR, "gzip_dir", "tempfile"), "w") as f: + os.mkdir(os.path.join(test_dir, "gzip_dir")) + with open(os.path.join(test_dir, "gzip_dir", "tempfile"), "w") as f: f.write("what") - self.mtime = os.path.getmtime(os.path.join(TEST_DIR, "gzip_dir", "tempfile")) + self.mtime = os.path.getmtime(os.path.join(test_dir, "gzip_dir", "tempfile")) def test_gzip_dir(self): - full_f = os.path.join(TEST_DIR, "gzip_dir", "tempfile") - gzip_dir(os.path.join(TEST_DIR, "gzip_dir")) + full_f = os.path.join(test_dir, "gzip_dir", "tempfile") + gzip_dir(os.path.join(test_dir, "gzip_dir")) assert os.path.exists(f"{full_f}.gz") assert not os.path.exists(full_f) @@ -142,7 +142,7 @@ def test_gzip_dir(self): def test_gzip_dir_file_coexist(self): """Test case where both file and file.gz exist.""" - full_f = os.path.join(TEST_DIR, "gzip_dir", "temptestfile") + full_f = os.path.join(test_dir, "gzip_dir", "temptestfile") gz_f = f"{full_f}.gz" # Create both the file and its gzipped version @@ -154,7 +154,7 @@ def test_gzip_dir_file_coexist(self): with pytest.warns( UserWarning, match="Both temptestfile and temptestfile.gz exist." ): - gzip_dir(os.path.join(TEST_DIR, "gzip_dir")) + gzip_dir(os.path.join(test_dir, "gzip_dir")) # Verify contents of the files with open(full_f, "r") as f: @@ -164,13 +164,13 @@ def test_gzip_dir_file_coexist(self): assert g.read() == b"gzipped" def test_handle_sub_dirs(self): - sub_dir = os.path.join(TEST_DIR, "gzip_dir", "sub_dir") + sub_dir = os.path.join(test_dir, "gzip_dir", "sub_dir") sub_file = os.path.join(sub_dir, "new_tempfile") os.mkdir(sub_dir) with open(sub_file, "w") as f: f.write("anotherwhat") - gzip_dir(os.path.join(TEST_DIR, "gzip_dir")) + gzip_dir(os.path.join(test_dir, "gzip_dir")) assert os.path.exists(f"{sub_file}.gz") assert not os.path.exists(sub_file) @@ -179,13 +179,13 @@ def test_handle_sub_dirs(self): assert g.readline().decode("utf-8") == "anotherwhat" def teardown_method(self): - shutil.rmtree(os.path.join(TEST_DIR, "gzip_dir")) + shutil.rmtree(os.path.join(test_dir, "gzip_dir")) class TestRemove: @unittest.skipIf(platform.system() == "Windows", "Skip on windows") def test_remove_file(self): - tempdir = tempfile.mkdtemp(dir=TEST_DIR) + tempdir = tempfile.mkdtemp(dir=test_dir) tempf = tempfile.mkstemp(dir=tempdir)[1] remove(tempf) assert not os.path.isfile(tempf) @@ -193,17 +193,17 @@ def test_remove_file(self): @unittest.skipIf(platform.system() == "Windows", "Skip on windows") def test_remove_folder(self): - tempdir = tempfile.mkdtemp(dir=TEST_DIR) + tempdir = tempfile.mkdtemp(dir=test_dir) remove(tempdir) assert not os.path.isdir(tempdir) @unittest.skipIf(platform.system() == "Windows", "Skip on windows") def test_remove_symlink(self): - tempdir = tempfile.mkdtemp(dir=TEST_DIR) + tempdir = tempfile.mkdtemp(dir=test_dir) tempf = tempfile.mkstemp(dir=tempdir)[1] - os.symlink(tempdir, os.path.join(TEST_DIR, "temp_link")) - templink = os.path.join(TEST_DIR, "temp_link") + os.symlink(tempdir, os.path.join(test_dir, "temp_link")) + templink = os.path.join(test_dir, "temp_link") remove(templink) assert os.path.isfile(tempf) assert os.path.isdir(tempdir) @@ -212,11 +212,11 @@ def test_remove_symlink(self): @unittest.skipIf(platform.system() == "Windows", "Skip on windows") def test_remove_symlink_follow(self): - tempdir = tempfile.mkdtemp(dir=TEST_DIR) + tempdir = tempfile.mkdtemp(dir=test_dir) tempf = tempfile.mkstemp(dir=tempdir)[1] - os.symlink(tempdir, os.path.join(TEST_DIR, "temp_link")) - templink = os.path.join(TEST_DIR, "temp_link") + os.symlink(tempdir, os.path.join(test_dir, "temp_link")) + templink = os.path.join(test_dir, "temp_link") remove(templink, follow_symlink=True) assert not os.path.isfile(tempf) assert not os.path.isdir(tempdir)