diff --git a/.github/workflows/pythonapp.yml b/.github/workflows/pythonapp.yml index aac0403ee..b0db1a7e1 100644 --- a/.github/workflows/pythonapp.yml +++ b/.github/workflows/pythonapp.yml @@ -153,6 +153,14 @@ jobs: run: pip install nanobind scikit-build-core[pyproject] - name: Install Basix run: pip install --no-build-isolation . + - name: Install mypy + run: pip install mypy + - name: Run mypy (module) + run: mypy -p basix + - name: Run mypy (test) + run: mypy test + # - name: Run mypy (demo) + # run: mypy demo/python build-cmake: name: Build using C++ and Python parts separately and run tests diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 8a946a2e3..54f5600d1 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -7,7 +7,7 @@ endif() project(basix_nanobind VERSION "0.9.0.0" LANGUAGES CXX) -if (WIN32) +if(WIN32) # Windows requires all symbols to be manually exported. # This flag exports all symbols automatically, as in Unix. set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) @@ -112,15 +112,45 @@ else() set_target_properties(_basixcpp PROPERTIES INSTALL_RPATH ${_basix_dir}) endif() -install(TARGETS _basixcpp LIBRARY DESTINATION basix) - # and the nanobind typing stubs. -nanobind_add_stub( - _basixcpp_stub - MODULE basix._basixcpp - DEPENDS _basixcpp - VERBOSE - INSTALL_TIME - OUTPUT - basix/_basixcpp.pyi -) +if (WIN32) + # On Windows we cannot import basix._basixcpp without installing the package + # alongside its external dlls. + + # This *must* be called prior to nanobind_add_stub + install(TARGETS _basixcpp LIBRARY DESTINATION basix) + # nanobind automatically installs into ${CMAKE_INSTALL_PREFIX} in + # INSTALL_TIME mode. + # DEPENDS is redundant in INSTALL_TIME mode - _basixcpp must be installed. + nanobind_add_stub( + _basixcpp_stub + MODULE basix._basixcpp + INSTALL_TIME + PATTERN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/pattern_stub.txt + MARKER_FILE basix/py.typed + VERBOSE + OUTPUT + basix/_basixcpp.pyi + ) +else() + # On UNIX-like systems we can import the cpp compiled module before + # installing and rely on dynamic linking at import time. + nanobind_add_stub( + _basixcpp_stub + MODULE _basixcpp + PYTHON_PATH $ + DEPENDS _basixcpp + PATTERN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/pattern_stub.txt + MARKER_FILE ${CMAKE_CURRENT_SOURCE_DIR}/basix/py.typed + VERBOSE + OUTPUT + _basixcpp.pyi + ) + + install(TARGETS _basixcpp LIBRARY DESTINATION basix) + install(FILES + ${CMAKE_CURRENT_SOURCE_DIR}/basix/py.typed + ${CMAKE_CURRENT_BINARY_DIR}/_basixcpp.pyi + DESTINATION basix + ) +endif() diff --git a/python/basix/py.typed b/python/basix/py.typed deleted file mode 100644 index e69de29bb..000000000 diff --git a/python/pattern_stub.txt b/python/pattern_stub.txt index 24d5707f6..10c317831 100644 --- a/python/pattern_stub.txt +++ b/python/pattern_stub.txt @@ -1,2 +1,7 @@ -basix._basixcpp.tabulate_polynomial_set: - def tabulate_polynomial_set(celltype: CellType, polytype: PolysetType, d: int, n: int, x: Annotated[ArrayLike, dict(dtype='float64', writable=False, shape=(None, None), order='C')]) -> Annotated[ArrayLike, dict(dtype='float64', )]: ... \ No newline at end of file +tabulate_polynomial_set: + \from typing import TypeVar + \from numpy.typing import NDArray as _NDArray + \from numpy import float32 as _f32, float64 as _f64 + _polynomial_set_floats = TypeVar("_polynomial_set_floats", _f32, _f64) + + def tabulate_polynomial_set(celltype: CellType, polytype: PolysetType, d: int, n: int, x: _NDArray[_polynomial_set_floats],) -> _NDArray[_polynomial_set_floats]: ...