diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index fc93c1b..1d3f862 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -25,6 +25,9 @@ jobs: strategy: matrix: python: ["3.10", "3.11", "3.12", "3.13"] + django: ["NO_DJANGO", "5.2"] # add more versions as we add support + # exclude incompatible python+django combinations if needed + # OR limit django+python to specific combinations to avoid too many builds defaults: run: working-directory: . @@ -40,8 +43,11 @@ jobs: cache: 'pip' cache-dependency-path: '**/pyproject.toml' - - name: Install package with dependencies - run: pip install -e ".[test]" + # test with and without django based on build matrix + - name: Install package with dependencies (and optionally django) + run: | + if [ "${{ matrix.django }}" != "NO_DJANGO"]; then pip install -q Django==${{ matrix.django }} pytest-django; fi + pip install -e '.[test]' # for all versions but the one we use for code coverage, run normally - name: Run unit tests without code coverage diff --git a/README.md b/README.md index c1b662d..928be95 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,14 @@ Use the `@name` notation to specify the branch or tag; e.g., to install developm pip install git+https://github.com/dh-tech/undate-python@develop#egg=undate ``` +### Optional Django Support (PRELIMINARY / IN PROGRESS) + +To install with optional Django integration field support: +```console +pip install undate[django] +``` + + ## Example Usage Often humanities and cultural data include imprecise or uncertain diff --git a/pyproject.toml b/pyproject.toml index fcebbbd..ec6e469 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,6 +40,8 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Framework :: Django", + "Framework :: Django :: 5.2", "Intended Audience :: Developers", "Intended Audience :: Science/Research", "License :: OSI Approved :: Apache Software License", @@ -53,9 +55,16 @@ classifiers = [ [project.optional-dependencies] docs = ["sphinx>=7.0.0", "alabaster", "myst-parser", "myst-parser[linkify]"] +django = ["django>=5.2"] test = ["pytest>=7.2", "pytest-ordering", "pytest-cov"] notebooks = ["jupyterlab", "pandas", "treon", "altair"] -check = ["undate[docs]", "undate[notebooks]", "mypy", "ruff"] +check = [ + "undate[docs]", + "undate[notebooks]", + "mypy", + "ruff", + "pip>=25.3", +] dev = [ "pre-commit>=2.20.0", "twine", @@ -87,6 +96,3 @@ markers = [ "last : run marked tests after all others", "first : run marked tests before all others", ] - -[tool.mypy] -plugins = ["numpy.typing.mypy_plugin"] diff --git a/src/undate/django/__init__.py b/src/undate/django/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/undate/test_utils.py b/src/undate/test_utils.py new file mode 100644 index 0000000..3cc8bdb --- /dev/null +++ b/src/undate/test_utils.py @@ -0,0 +1,28 @@ +""" +Utility decorators for unit tests that require django to be installed, +or not installed. To use, import into unit test and apply +to test method or class: + +```python + +from undate.test_utils import skipif_no_django, skipif_django + +@skipif_no_django +def test_django_functionality(): + .... +``` + +""" + +import pytest +from types import ModuleType + +django: ModuleType | None = None +try: + import django # type: ignore[import-not-found, no-redef] +except ImportError: + pass + +skipif_no_django = pytest.mark.skipif(django is None, reason="requires Django") + +skipif_django = pytest.mark.skipif(django is not None, reason="requires no Django") diff --git a/tests/test_django/test_django_setup.py b/tests/test_django/test_django_setup.py new file mode 100644 index 0000000..9fa39a2 --- /dev/null +++ b/tests/test_django/test_django_setup.py @@ -0,0 +1,16 @@ +try: + import django +except ImportError: + django = None + +from undate.test_utils import skipif_no_django, skipif_django + + +@skipif_no_django +def test_django(): + assert django is not None + + +@skipif_django +def test_no_django(): + assert django is None