diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index de6ad2fde..a6463b7ab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -74,6 +74,23 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} + test-pyinstaller-build: + name: Test pyinstaller + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: 3.12 + - name: Install package and dev dependencies + run: | + python -m pip install --upgrade pip + pip install . + pip install pytest pyinstaller + - name: Unit tests + run: pytest -v --pyargs cmap.__pyinstaller + deploy: name: Deploy needs: test diff --git a/pyproject.toml b/pyproject.toml index 1d41029f0..0b231908d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -75,6 +75,10 @@ dev = [ "pyqt6", ] +[project.entry-points."pyinstaller40"] +hook-dirs = "cmap.__pyinstaller:get_hook_dirs" +tests = "cmap.__pyinstaller:get_test_dirs" + [project.urls] Homepage = "https://github.com/pyapp-kit/cmap" Repository = "https://github.com/pyapp-kit/cmap" @@ -139,6 +143,9 @@ filterwarnings = [ "ignore:datetime.datetime.utcfromtimestamp:DeprecationWarning", "ignore::DeprecationWarning:docstring_parser", "ignore:Pyarrow will become a required dependency of pandas", + "ignore::DeprecationWarning:Pyinstaller", + "ignore::DeprecationWarning:pkg_resources", + "ignore::DeprecationWarning:altgraph", ] # https://mypy.readthedocs.io/en/stable/config_file.html diff --git a/src/cmap/__pyinstaller/__init__.py b/src/cmap/__pyinstaller/__init__.py new file mode 100644 index 000000000..cb647dbc1 --- /dev/null +++ b/src/cmap/__pyinstaller/__init__.py @@ -0,0 +1,11 @@ +from os.path import dirname + +HERE = dirname(__file__) + + +def get_hook_dirs() -> list[str]: + return [HERE] + + +def get_test_dirs() -> list[str]: + return [HERE] diff --git a/src/cmap/__pyinstaller/conftest.py b/src/cmap/__pyinstaller/conftest.py new file mode 100644 index 000000000..67f89ed8a --- /dev/null +++ b/src/cmap/__pyinstaller/conftest.py @@ -0,0 +1,4 @@ +import os + +os.environ["PYI_BUILDER_CLEANUP"] = "0" +from PyInstaller.utils.conftest import * # noqa diff --git a/src/cmap/__pyinstaller/hook-cmap.py b/src/cmap/__pyinstaller/hook-cmap.py new file mode 100644 index 000000000..6d444a662 --- /dev/null +++ b/src/cmap/__pyinstaller/hook-cmap.py @@ -0,0 +1,24 @@ +from PyInstaller.utils.hooks import collect_all + +datas, binaries, hiddenimports = collect_all( + "cmap", + # include_datas=["data/"], + exclude_datas=["**/__pycache__/"], + # filter_submodules=lambda x: x.startswith("cmap.data"), +) +excludedimports = [ + "bokeh", + "colorspacious", + "matplotlib", + "napari", + "numpy.typing", + "pydantic_core", + "pydantic", + "numba", + "pygfx", + "pyqtgraph", + "tkinter", + "typing_extensions", + "viscm", + "vispy", +] diff --git a/src/cmap/__pyinstaller/test_cmap.py b/src/cmap/__pyinstaller/test_cmap.py new file mode 100644 index 000000000..1419086b2 --- /dev/null +++ b/src/cmap/__pyinstaller/test_cmap.py @@ -0,0 +1,9 @@ +from typing import Any + + +def test_pyi_cmap_data(pyi_builder: Any) -> None: + pyi_builder.test_source(""" + import cmap + assert isinstance(cmap.Colormap('viridis'), cmap.Colormap) + assert isinstance(cmap.Colormap('crameri:acton'), cmap.Colormap) + """) diff --git a/src/cmap/_color.py b/src/cmap/_color.py index 1c69e5e44..db57f085d 100644 --- a/src/cmap/_color.py +++ b/src/cmap/_color.py @@ -21,11 +21,6 @@ import numpy as np -try: - from pydantic import model_serializer -except ImportError: - model_serializer = lambda x: x # noqa: E731 - from . import _external if TYPE_CHECKING: