diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index 6d13c03..f75fb1b 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -3,36 +3,35 @@ name: dac actions on: push: branches: - - '*' + - "*" tags: - - '*' + - "*" jobs: - check-style: runs-on: ubuntu-latest steps: - - name: Checkout πŸ”– - uses: actions/checkout@v3 - with: - fetch-depth: 1 - - name: Setup python 🐍 - uses: actions/setup-python@v4 - with: - python-version: '3.12' - - name: Setup cache πŸ’Ύ - uses: actions/cache@v3 - with: - path: ~/.cache/pre-commit - key: pre-commit - - name: Prepare pre-commit πŸ™†β€β™‚οΈπŸ‘— - run: | - python -m venv venv || . venv/bin/activate - pip install -U pip wheel setuptools pre-commit - pre-commit install - - name: Run pre-commit πŸ‘—πŸš€ - run: | - pre-commit run --all-files + - name: Checkout πŸ”– + uses: actions/checkout@v3 + with: + fetch-depth: 1 + - name: Setup python 🐍 + uses: actions/setup-python@v4 + with: + python-version: "3.12" + - name: Setup cache πŸ’Ύ + uses: actions/cache@v3 + with: + path: ~/.cache/pre-commit + key: pre-commit + - name: Prepare pre-commit πŸ™†β€β™‚οΈπŸ‘— + run: | + python -m venv venv || . venv/bin/activate + pip install -U pip wheel setuptools pre-commit + pre-commit install + - name: Run pre-commit πŸ‘—πŸš€ + run: | + pre-commit run --all-files test: runs-on: "${{ matrix.os }}" @@ -41,60 +40,60 @@ jobs: os: ["ubuntu-latest"] version: ["3.9", "3.10", "3.11"] steps: - - name: Checkout πŸ”– - uses: actions/checkout@v3 - with: - fetch-depth: 1 - - name: Setup python 🐍 - uses: actions/setup-python@v4 - with: - python-version: "${{ matrix.version }}" - - name: Prepare tests πŸ™†β€β™‚οΈπŸ”¬ - run: | - python -m venv venv || . venv/bin/activate - pip install -U pip wheel setuptools - pip install -r requirements-test.txt - - name: Run tests πŸ”¬πŸš€ - run: | - pytest test --run-slow + - name: Checkout πŸ”– + uses: actions/checkout@v3 + with: + fetch-depth: 1 + - name: Setup python 🐍 + uses: actions/setup-python@v4 + with: + python-version: "${{ matrix.version }}" + - name: Prepare tests πŸ™†β€β™‚οΈπŸ”¬ + run: | + python -m venv venv || . venv/bin/activate + pip install -U pip wheel setuptools + pip install -r requirements-test.txt + - name: Run tests πŸ”¬πŸš€ + run: | + pytest test --run-slow docs: needs: [test, check-style] if: ${{ github.ref == 'refs/heads/main' }} runs-on: ubuntu-latest steps: - - name: Checkout πŸ”– - uses: actions/checkout@v3 - - name: Deploy docs - uses: mhausenblas/mkdocs-deploy-gh-pages@master - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CONFIG_FILE: mkdocs.yml - REQUIREMENTS: requirements-docs.txt + - name: Checkout πŸ”– + uses: actions/checkout@v3 + - name: Deploy docs + uses: mhausenblas/mkdocs-deploy-gh-pages@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CONFIG_FILE: mkdocs.yml + REQUIREMENTS: requirements-docs.txt pypi-release: needs: [test, check-style] if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }} runs-on: ubuntu-latest steps: - - name: Checkout πŸ”– - uses: actions/checkout@v3 - with: - fetch-depth: 1 - - name: Setup python 🐍 - uses: actions/setup-python@v4 - with: - python-version: "3.12" - - name: Prepare release πŸ™†β€β™‚οΈπŸ“¦test - run: | - python -m venv venv || . venv/bin/activate - pip install -U pip wheel setuptools build twine - - name: Build πŸ› οΈπŸ“¦ - run: | - python -m build - - name: Release πŸ“¦πŸš€ - env: - TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }} - TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }} - run: | - python -m twine upload dist/* + - name: Checkout πŸ”– + uses: actions/checkout@v3 + with: + fetch-depth: 1 + - name: Setup python 🐍 + uses: actions/setup-python@v4 + with: + python-version: "3.12" + - name: Prepare release πŸ™†β€β™‚οΈπŸ“¦test + run: | + python -m venv venv || . venv/bin/activate + pip install -U pip wheel setuptools build twine + - name: Build πŸ› οΈπŸ“¦ + run: | + python -m build + - name: Release πŸ“¦πŸš€ + env: + TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }} + TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }} + run: | + python -m twine upload dist/* diff --git a/CHANGELOG.md b/CHANGELOG.md index 2dd301f..3eba1de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Anything MAY change at any time. The public API SHOULD NOT be considered stable."). While in this phase, we will denote breaking changes with a minor increase. +## 0.4.3 + +### Fixed + +* Bump all dependencies to the latest version and introduce necessary adaptation in the source code (affecting only `dac info`): + - `build~=0.9` -> `build==1.2.2` + - `toml~=0.10` -> `toml==0.10.2` + - `typer[all]~=0.7` -> `typer[all]==0.15.2` + - `wheel~=0.38` -> `wheel==0.45.1` +* Prevent installation with python > `3.11` + ## 0.4.2 ### Fixed diff --git a/pyproject.toml b/pyproject.toml index 368ec44..ae131dc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,25 +3,30 @@ name = "dac" dynamic = ["version"] description = "Tool to distribute data as code" readme = "README.md" -requires-python = ">=3.9" +requires-python = ">=3.9,<3.12" license = { text = "MIT" } authors = [ - { name = "Francesco Calcavecchia", email = "francesco.calcavecchia@gmail.com" }, + { name = "Francesco Calcavecchia", email = "francesco.calcavecchia@gmail.com" }, ] maintainers = [ - { name = "Francesco Calcavecchia", email = "francesco.calcavecchia@gmail.com" }, + { name = "Francesco Calcavecchia", email = "francesco.calcavecchia@gmail.com" }, ] classifiers = [ - "Programming Language :: Python :: 3", - "Development Status :: 3 - Alpha", - "Intended Audience :: Developers", - "Topic :: Software Development :: Build Tools", - "License :: OSI Approved :: MIT License", - "Topic :: Scientific/Engineering", - "Operating System :: OS Independent", + "Programming Language :: Python :: 3", + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "Topic :: Software Development :: Build Tools", + "License :: OSI Approved :: MIT License", + "Topic :: Scientific/Engineering", + "Operating System :: OS Independent", ] -dependencies = ["build~=0.9", "toml~=0.10", "typer[all]~=0.7", "wheel~=0.38"] +dependencies = [ + "build==1.2.2", + "toml==0.10.2", + "typer[all]==0.15.2", + "wheel==0.45.1", +] # [project.optional-dependencies] # diff --git a/requirements-test.txt b/requirements-test.txt index c4dc066..08a711b 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,5 +1,5 @@ -e . -pandas~=1.5 -pandera~=0.13 +pandas~=2.2 +pandera~=0.23.1 pyarrow -pytest~=7.2 +pytest~=8.3 diff --git a/src/dac/_cli.py b/src/dac/_cli.py index 1191c4c..f216f6b 100644 --- a/src/dac/_cli.py +++ b/src/dac/_cli.py @@ -1,6 +1,7 @@ import platform +import re import sys -from importlib.metadata import requires, version +from importlib.metadata import PackageNotFoundError, requires, version from pathlib import Path from typing import Optional @@ -105,8 +106,11 @@ def info(): requirements = requires(dac.__name__) assert requirements is not None for r in requirements: - lib_name = r.split(" ")[0] - table.add_row(lib_name, version(lib_name.split("[")[0])) + lib_name = re.match(r"^[a-zA-Z0-9]*", r).group(0) + try: + table.add_row(lib_name, version(lib_name.split("[")[0])) + except PackageNotFoundError as e: + table.add_row(lib_name, e.msg) table.add_row("python", sys.version) table.add_row("platform", platform.platform()) console.print(table) diff --git a/test/cli_utilities.py b/test/cli_utilities.py index 1f303a2..2d11238 100644 --- a/test/cli_utilities.py +++ b/test/cli_utilities.py @@ -1,16 +1,17 @@ from tempfile import TemporaryDirectory +from typing import Optional + +from click.testing import Result +from typer.testing import CliRunner + +from dac._cli import app +from dac._input.config import PackConfig from test.data import ( generate_random_project_name, get_path_to_self_contained_load_as_pandas, get_path_to_self_contained_schema, get_test_project_version, ) -from typing import Optional - -from click.testing import Result -from dac._cli import app -from dac._input.config import PackConfig -from typer.testing import CliRunner runner = CliRunner() diff --git a/test/data/load/parquet_as_pandas.py b/test/data/load/parquet_as_pandas.py index 16104da..bb2843f 100644 --- a/test/data/load/parquet_as_pandas.py +++ b/test/data/load/parquet_as_pandas.py @@ -4,4 +4,6 @@ def load() -> pd.DataFrame: - return pd.read_parquet(Path(__file__).parent / "sample.parquet") + df = pd.read_parquet(Path(__file__).parent / "sample.parquet") + df["datetime1"] = df["datetime1"].astype("datetime64[ns]") + return df diff --git a/test/data/requirements/parquet_as_pandas.txt b/test/data/requirements/parquet_as_pandas.txt index 62a61a1..8a82915 100644 --- a/test/data/requirements/parquet_as_pandas.txt +++ b/test/data/requirements/parquet_as_pandas.txt @@ -1,3 +1,3 @@ -pandas~=1.0 +pandas~=2.0 pyarrow -pandera~=0.13.4 +pandera~=0.23.1 diff --git a/test/data/schema/incompatible_with_sample_df.py b/test/data/schema/incompatible_with_sample_df.py index 20c2046..5d1b6ad 100644 --- a/test/data/schema/incompatible_with_sample_df.py +++ b/test/data/schema/incompatible_with_sample_df.py @@ -4,7 +4,7 @@ from pandera.typing import Series -class Schema(pa.SchemaModel): +class Schema(pa.DataFrameModel): int1: Series[int] = pa.Field(nullable=False) float1: Series[int] = pa.Field() string1: Series[float] = pa.Field() diff --git a/test/data/schema/invalid.py b/test/data/schema/invalid.py index d9c8b3f..b7becd2 100644 --- a/test/data/schema/invalid.py +++ b/test/data/schema/invalid.py @@ -4,7 +4,7 @@ from pandera.typing import Series -class SchemaWithWrongName(pa.SchemaModel): +class SchemaWithWrongName(pa.DataFrameModel): int1: Series[int] = pa.Field(nullable=False) float1: Series[float] = pa.Field() string1: Series[str] = pa.Field() diff --git a/test/data/schema/sample.py b/test/data/schema/sample.py index 2a3a016..96b51b3 100644 --- a/test/data/schema/sample.py +++ b/test/data/schema/sample.py @@ -4,7 +4,7 @@ from pandera.typing import Series -class Schema(pa.SchemaModel): +class Schema(pa.DataFrameModel): int1: Series[int] = pa.Field(nullable=False) float1: Series[float] = pa.Field() string1: Series[str] = pa.Field() diff --git a/test/data/schema/self_contained.py b/test/data/schema/self_contained.py index e86afcc..699b706 100644 --- a/test/data/schema/self_contained.py +++ b/test/data/schema/self_contained.py @@ -2,6 +2,6 @@ from pandera.typing import Series -class Schema(pa.SchemaModel): +class Schema(pa.DataFrameModel): A: Series[int] = pa.Field(nullable=False) B: Series[float] = pa.Field(nullable=False) diff --git a/test/data/schema/wrong_syntax.py b/test/data/schema/wrong_syntax.py index f2d79d0..eb1ebc6 100644 --- a/test/data/schema/wrong_syntax.py +++ b/test/data/schema/wrong_syntax.py @@ -2,6 +2,6 @@ from pandera.typing import Series -class Schema(pa.SchemaModel): +class Schema(pa.DataFrameModel): A: Series[int] = pa.Field(nullable=False) B: Series[float] = pa.Field(nullable=False) diff --git a/test/integration_test/pack_test.py b/test/integration_test/pack_test.py index 2aa83cb..4a34d23 100644 --- a/test/integration_test/pack_test.py +++ b/test/integration_test/pack_test.py @@ -4,6 +4,13 @@ from importlib.metadata import version from pathlib import Path from tempfile import TemporaryDirectory +from typing import Generator, Optional + +import pandas as pd +import pandera as pa +import pytest + +from dac import PackConfig, PyProjectConfig from test.cli_utilities import invoke_dac_pack_from_config from test.data import ( generate_random_project_name, @@ -18,12 +25,6 @@ get_test_project_version, ) from test.data.load import self_contained_as_pandas -from typing import Generator, Optional - -import pandas as pd -import pandera as pa -import pytest -from dac import PackConfig, PyProjectConfig @pytest.mark.slow @@ -54,7 +55,7 @@ def test_if_installed_then_can_access_schema(): files_in_wheel_dir = list(Path(config.wheel_dir).iterdir()) with _pip_installed_wheel(path=files_in_wheel_dir[0]): pkg = import_module(config.pyproject.project_name) - assert issubclass(pkg.Schema, pa.SchemaModel) + assert issubclass(pkg.Schema, pa.DataFrameModel) @pytest.mark.slow diff --git a/test/unit_test/_cli/info_test.py b/test/unit_test/_cli/info_test.py index fcb9f5e..9725366 100644 --- a/test/unit_test/_cli/info_test.py +++ b/test/unit_test/_cli/info_test.py @@ -1,7 +1,7 @@ from importlib.metadata import version -from test.cli_utilities import invoke_dac_info import dac +from test.cli_utilities import invoke_dac_info def test_if_invoke_dac_info_from_shell_then_do_not_raise_error(): diff --git a/test/unit_test/_cli/pack_test.py b/test/unit_test/_cli/pack_test.py index 860f7c6..e2ecbcf 100644 --- a/test/unit_test/_cli/pack_test.py +++ b/test/unit_test/_cli/pack_test.py @@ -1,5 +1,11 @@ from importlib import import_module from inspect import signature +from unittest.mock import MagicMock, patch + +import pytest +from click.testing import Result + +from dac._input.config import PackConfig from test.cli_utilities import invoke_dac_pack from test.data import ( get_path_to_missing_requirement_load, @@ -9,11 +15,6 @@ get_path_to_wrong_syntax_schema, ) from test.data.pack_input import input_with_local_data, input_with_self_contained_data -from unittest.mock import MagicMock, patch - -import pytest -from click.testing import Result -from dac._input.config import PackConfig @pytest.fixture(autouse=True) @@ -45,11 +46,11 @@ def test_if_data_does_not_match_schema_error_contains_pandera_error_info(): result = invoke_dac_pack(schema=get_path_to_sample_schema().as_posix()) assert result.exit_code != 0 error_message = str(result.exception) - assert "schema_context" in error_message - assert "check" in error_message - assert "failure_case" in error_message assert "int1" in error_message + assert "float1" in error_message + assert "string1" in error_message assert "date1" in error_message + assert "datetime1" in error_message def test_if_load_requires_missing_requirement_then_error_contains_meaningful_info(): diff --git a/test/unit_test/_input/pyproject_test.py b/test/unit_test/_input/pyproject_test.py index 137f610..a41486a 100644 --- a/test/unit_test/_input/pyproject_test.py +++ b/test/unit_test/_input/pyproject_test.py @@ -1,8 +1,8 @@ -from test.data import get_path_to_parquet_as_pandas_requirements - import pytest import toml # type: ignore + from dac._input.pyproject import PyProjectConfig +from test.data import get_path_to_parquet_as_pandas_requirements @pytest.mark.parametrize("project_name,project_version", [("project_1", "0.1.2"), ("test_project", "6.6.6")]) @@ -35,8 +35,8 @@ def test_if_dependencies_are_passed_from_cat_requirements_then_valid_pyproject_i assert parsed_toml["project"]["name"] == pm.project_name assert parsed_toml["project"]["version"] == pm.project_version assert parsed_toml["project"]["dependencies"] == [ - "pandas~=1.0", - "pandera~=0.13.4", + "pandas~=2.0", + "pandera~=0.23.1", "pyarrow", ]