diff --git a/setup.cfg b/.bumpversion.cfg similarity index 61% rename from setup.cfg rename to .bumpversion.cfg index 00647d16..17962fe2 100644 --- a/setup.cfg +++ b/.bumpversion.cfg @@ -4,14 +4,7 @@ commit = True tag = True tag_name = {new_version} -[flake8] -max-line-length = 120 -builtins = json -statistics = true -ignore = E202 -exclude = ./data,./src,.svn,CVS,.bzr,.hg,.git,__pycache__ - -[bumpversion:file:setup.py] +[bumpversion:file:pyproject.toml] [bumpversion:file:README.md] diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 345ee9f6..b8b8ad09 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -8,11 +8,12 @@ on: jobs: build: - + env: + DEFAULT_PYTHON: 3.12 runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] architecture: ["x64"] steps: - uses: actions/checkout@v2 @@ -21,59 +22,36 @@ jobs: with: python-version: ${{ matrix.python-version }} architecture: ${{ matrix.architecture }} - - name: Cache pip 3.8 - if: matrix.python-version == 3.8 - uses: actions/cache@v4 - with: - # This path is specific to Ubuntu - path: ~/.cache/pip - # Look to see if there is a cache hit for the corresponding requirements file - key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements-dev3.8.txt') }} - restore-keys: | - ${{ runner.os }}-pip- - ${{ runner.os }}- - name: Cache pip - if: matrix.python-version != 3.8 env: PYO3_USE_ABI3_FORWARD_COMPATIBILITY: "1" uses: actions/cache@v4 with: - # This path is specific to Ubuntu - path: ~/.cache/pip - # Look to see if there is a cache hit for the corresponding requirements file - key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements-dev.txt') }} restore-keys: | - ${{ runner.os }}-pip- ${{ runner.os }}- - name: Upgrade setuptools if: matrix.python-version >= 3.12 run: | # workaround for 3.12, SEE: https://github.com/pypa/setuptools/issues/3661#issuecomment-1813845177 pip install --upgrade setuptools - - name: Install dependencies - if: matrix.python-version > 3.9 - run: pip install -r requirements-dev.txt - - name: Install dependencies - if: matrix.python-version <= 3.9 - run: pip install -r requirements-dev3.8.txt - name: Lint with flake8 - if: matrix.python-version == 3.12 + if: matrix.python-version == ${{ env.DEFAULT_PYTHON }} run: | # stop the build if there are Python syntax errors or undefined names - flake8 deepdiff --count --select=E9,F63,F7,F82 --show-source --statistics + nox -e flake8 -- deepdiff --count --select=E9,F63,F7,F82 --show-source --statistics # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - flake8 deepdiff --count --exit-zero --max-complexity=26 --max-line-lengt=250 --statistics + nox -e flake8 -- deepdiff --count --exit-zero --max-complexity=26 --max-line-length=250 --statistics - name: Test with pytest and get the coverage - if: matrix.python-version == 3.12 + if: matrix.python-version == ${{ env.DEFAULT_PYTHON }} run: | - pytest --benchmark-disable --cov-report=xml --cov=deepdiff tests/ --runslow + nox -e pytest -s -- --benchmark-disable --cov-report=xml --cov=deepdiff tests/ --runslow - name: Test with pytest and no coverage report - if: matrix.python-version != 3.12 + if: matrix.python-version != ${{ env.DEFAULT_PYTHON }} run: | - pytest --benchmark-disable + nox -e pytest -s -- --benchmark-disable tests/ - name: Upload coverage to Codecov uses: codecov/codecov-action@v4 - if: matrix.python-version == 3.12 + if: matrix.python-version == ${{ env.DEFAULT_PYTHON }} env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: diff --git a/README.md b/README.md index b1352435..3c2ff681 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ - [Extract](https://zepworks.com/deepdiff/current/extract.html): Extract an item from a nested Python object using its path. - [commandline](https://zepworks.com/deepdiff/current/commandline.html): Use DeepDiff from commandline. -Tested on Python 3.8+ and PyPy3. +Tested on Python 3.9+ and PyPy3. - **[Documentation](https://zepworks.com/deepdiff/8.4.2/)** diff --git a/deepdiff/base.py b/deepdiff/base.py index d3b24fb8..d16bad50 100644 --- a/deepdiff/base.py +++ b/deepdiff/base.py @@ -1,4 +1,3 @@ -from typing import Any from deepdiff.helper import strings, numbers, SetOrdered diff --git a/deepdiff/serialization.py b/deepdiff/serialization.py index c148aadf..a9e2d68a 100644 --- a/deepdiff/serialization.py +++ b/deepdiff/serialization.py @@ -32,7 +32,6 @@ pydantic_base_model_type, PydanticBaseModel, NotPresent, - ipranges, ) from deepdiff.model import DeltaResult diff --git a/noxfile.py b/noxfile.py new file mode 100644 index 00000000..f112fe13 --- /dev/null +++ b/noxfile.py @@ -0,0 +1,49 @@ +"""nox configuration file.""" + +# ruff: noqa: ANN001, D401 + +import nox + + +@nox.session +def flake8(session) -> None: + """Run flake8.""" + posargs = session.posargs if session.posargs else ["deepdiff"] + session.install(".[cli,dev,static]") + session.run( + "python", + "-m", + "flake8", + *posargs, + ) + + +@nox.session +def mypy(session) -> None: + """Run mypy.""" + posargs = session.posargs if session.posargs else ["deepdiff"] + session.install(".[cli,dev,static]") + session.run( + "python", + "-m", + "mypy", + "--install-types", + "--non-interactive", + *posargs, + ) + + +@nox.session(python=["3.9", "3.10", "3.11", "3.12", "3.13"]) +def pytest(session) -> None: + """Test with pytest.""" + posargs = session.posargs if session.posargs else ["-vv", "tests"] + session.install(".[cli,dev,static,test]") + session.run( + "python", + "-m", + "pytest", + "--cov=deepdiff", + "--cov-report", + "term-missing", + *posargs, + ) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..1511930b --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,104 @@ +[build-system] +requires = ["flit_core >=3.11,<4"] +build-backend = "flit_core.buildapi" + +[project] +name = "deepdiff" +version = "8.4.2" +dependencies = [ + "orderly-set>=5.3.0,<6", +] +requires-python = ">=3.9" +authors = [ + { name = "Seperman", email = "sep@zepworks.com" } +] +maintainers = [ + { name = "Seperman", email = "sep@zepworks.com" } +] +description = "Deep Difference and Search of any Python object/data. Recreate objects by adding adding deltas to each other." +readme = "README.md" +license = {file = "LICENSE"} +keywords = [] +classifiers = [ + "Intended Audience :: Developers", + "Operating System :: OS Independent", + "Topic :: Software Development", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: Implementation :: PyPy", + "Development Status :: 5 - Production/Stable", + "License :: OSI Approved :: MIT License" +] + +# `dependency-groups` would make this a lot cleaner, in theory. +[project.optional-dependencies] +coverage = [ + "coverage~=7.6.0" +] +cli = [ + "click~=8.1.0", + "pyyaml~=6.0.0" +] +dev = [ + "bump2version~=1.0.0", + "jsonpickle~=4.0.0", + "ipdb~=0.13.0", + "numpy~=2.2.0; python_version >= '3.10'", + "numpy~=2.0; python_version < '3.10'", + "python-dateutil~=2.9.0", + "orjson~=3.10.0", + "tomli~=2.2.0", + "tomli-w~=1.2.0", + "pandas~=2.2.0", + "polars~=1.21.0", +] +docs = [ + # We use the html style that is not supported in Sphinx 7 anymore. + "Sphinx~=6.2.0", + "sphinx-sitemap~=2.6.0", + "sphinxemoji~=0.3.0" +] +static = [ + "flake8~=7.1.0", + "flake8-pyproject~=1.2.3", + "pydantic~=2.10.0", + "types-setuptools~=75.8.0", +] +test = [ + "pytest~=8.3.0", + "pytest-benchmark~=5.1.0", + "pytest-cov~=6.0.0", + "python-dotenv~=1.0.0", +] + +[project.scripts] +deep = "deepdiff.commands:cli" + +[project.urls] +Homepage = "https://zepworks.com/deepdiff/" +Documentation = "https://zepworks.com/deepdiff/" +Repository = "https://github.com/seperman/deepdiff" +Issues = "https://github.com/seperman/deepdiff/issues" + +[tool.coverage.run] +branch = true +source = ["."] + +[tool.flake8] +max-line-length = 120 +builtins = "json" +statistics = true +ignore = "E202" +exclude = "./data,./src,.svn,CVS,.bzr,.hg,.git,__pycache__" + +[tool.pytest.ini_options] +addopts = "--pdbcls=IPython.terminal.debugger:Pdb" + +[tool.setuptools] +packages = ["deepdiff"] + +[tool.setuptools.package-metadata] +deepdiff = ["py.typed"] diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index 8509e73b..00000000 --- a/pytest.ini +++ /dev/null @@ -1,2 +0,0 @@ -[pytest] -addopts = --pdbcls=IPython.terminal.debugger:Pdb diff --git a/requirements-cli.txt b/requirements-cli.txt deleted file mode 100644 index 3ed63615..00000000 --- a/requirements-cli.txt +++ /dev/null @@ -1,2 +0,0 @@ -click==8.1.8 -pyyaml==6.0.2 diff --git a/requirements-dev.txt b/requirements-dev.txt deleted file mode 100644 index a0a5ea26..00000000 --- a/requirements-dev.txt +++ /dev/null @@ -1,22 +0,0 @@ --r requirements.txt --r requirements-cli.txt -bump2version==1.0.1 -jsonpickle==4.0.1 -coverage==7.6.10 -ipdb==0.13.13 -numpy==2.2.2 -pytest==8.3.4 -pytest-cov==6.0.0 -python-dotenv==1.0.1 -flake8==7.1.1 -python-dateutil==2.9.0.post0 -orjson==3.10.15 -wheel==0.45.1 -tomli==2.2.1 -tomli-w==1.2.0 -pydantic==2.10.6 -pytest-benchmark==5.1.0 -pandas==2.2.3 -polars==1.21.0 -setuptools==75.8.0 -types-setuptools==75.8.0 diff --git a/requirements-dev3.8.txt b/requirements-dev3.8.txt deleted file mode 100644 index b4f84058..00000000 --- a/requirements-dev3.8.txt +++ /dev/null @@ -1,20 +0,0 @@ --r requirements.txt --r requirements-cli.txt -bump2version==1.0.1 -jsonpickle==3.2.1 -coverage==7.5.3 -ipdb==0.13.13 -numpy>=1.24.4,<2.0.0 -pytest==8.2.2 -pytest-cov==5.0.0 -python-dotenv==1.0.1 -flake8==7.1.0 -python-dateutil==2.9.0.post0 -orjson==3.10.12 -wheel==0.43.0 -tomli==2.0.1 -tomli-w==1.0.0 -pydantic==2.7.4 -pytest-benchmark==4.0.0 -pandas==2.0.3 -polars==1.0.0 diff --git a/requirements-docs.txt b/requirements-docs.txt deleted file mode 100644 index 9a036843..00000000 --- a/requirements-docs.txt +++ /dev/null @@ -1,3 +0,0 @@ -Sphinx==6.2.1 # We use the html style that is not supported in Sphinx 7 anymore. -sphinx-sitemap==2.6.0 -sphinxemoji==0.3.1 diff --git a/requirements-optimize.txt b/requirements-optimize.txt deleted file mode 100644 index b3fe036f..00000000 --- a/requirements-optimize.txt +++ /dev/null @@ -1 +0,0 @@ -orjson diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 7fc4bb42..00000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -orderly-set>=5.3.0,<6 diff --git a/run_tests.sh b/run_tests.sh deleted file mode 100755 index 660146f5..00000000 --- a/run_tests.sh +++ /dev/null @@ -1 +0,0 @@ -pytest --cov=deepdiff --cov-report term-missing diff --git a/setup.py b/setup.py deleted file mode 100755 index 04cae3fd..00000000 --- a/setup.py +++ /dev/null @@ -1,69 +0,0 @@ -import os -import sys -from setuptools import setup - -if sys.version_info.major == 2: # pragma: no cover - sys.exit('Python 2 is not supported anymore. The last version of DeepDiff that supported Py2 was 3.3.0') - -# if you are not using vagrant, just delete os.link directly, -# The hard link only saves a little disk space, so you should not care -if os.environ.get('USER', '') == 'vagrant': - del os.link - -version = '8.4.2' - - -def get_reqs(filename): - with open(filename, "r") as reqs_file: - reqs = reqs_file.readlines() - return reqs - - -reqs = get_reqs("requirements.txt") -cli_reqs = get_reqs("requirements-cli.txt") -optimize_reqs = get_reqs("requirements-optimize.txt") - -with open('README.md') as file: - long_description = file.read() - - -setup(name='deepdiff', - version=version, - description='Deep Difference and Search of any Python object/data. Recreate objects by adding adding deltas to each other.', - url='https://github.com/seperman/deepdiff', - download_url='https://github.com/seperman/deepdiff/tarball/master', - author='Seperman', - author_email='sep@zepworks.com', - license='MIT', - packages=['deepdiff'], - package_data={"deepdiff": ["py.typed"]}, - zip_safe=True, - include_package_data=True, - long_description=long_description, - long_description_content_type='text/markdown', - install_requires=reqs, - python_requires='>=3.8', - extras_require={ - "cli": cli_reqs, - "optimize": optimize_reqs, - }, - classifiers=[ - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Topic :: Software Development", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Programming Language :: Python :: Implementation :: PyPy", - "Development Status :: 5 - Production/Stable", - "License :: OSI Approved :: MIT License" - ], - entry_points={ - 'console_scripts': [ - 'deep=deepdiff.commands:cli', - ], - }, - ) diff --git a/tests/test_serialization.py b/tests/test_serialization.py index 3c506834..6f16cdca 100644 --- a/tests/test_serialization.py +++ b/tests/test_serialization.py @@ -393,9 +393,6 @@ def prefix_callback(**kwargs): (9, np.array([[ 101, 3533, 1998, 4532, 2024, 3415, 1012, 102]]), np.array) ]) def test_json_dumps_and_loads(self, test_num, value, func_to_convert_back): - if test_num == 8 and py_current_version < 3.8: - print(f"Skipping test_json_dumps_and_loads #{test_num} on Python {py_current_version}") - return serialized = json_dumps(value) back = json_loads(serialized) if func_to_convert_back: