From a8169a59fc685af1389ac7b51d1e0a6e78897a7b Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Thu, 9 Apr 2026 16:31:17 -0700 Subject: [PATCH 1/3] make mkl-service an optional dependency mkl-service is only a dependency for the sake of the scipy interface, which is optional --- .github/workflows/build_pip.yaml | 5 +---- .github/workflows/conda-package-cf.yml | 4 ++-- .github/workflows/conda-package.yml | 4 ++-- conda-recipe-cf/meta.yaml | 3 ++- conda-recipe/meta.yaml | 6 +++--- mkl_fft/interfaces/__init__.py | 23 ++++++++++++++++------- pyproject.toml | 6 +++--- 7 files changed, 29 insertions(+), 22 deletions(-) diff --git a/.github/workflows/build_pip.yaml b/.github/workflows/build_pip.yaml index 00bcdfa6..80cc1e2c 100644 --- a/.github/workflows/build_pip.yaml +++ b/.github/workflows/build_pip.yaml @@ -44,10 +44,7 @@ jobs: - name: Install MKL run: | - conda install mkl-devel mkl-service - python -c "import sys; print(sys.executable)" - which python - python -c "import mkl; print(mkl.__file__)" + conda install mkl-devel - name: Build conda package run: | diff --git a/.github/workflows/conda-package-cf.yml b/.github/workflows/conda-package-cf.yml index bb6a1cf8..d7e68ab7 100644 --- a/.github/workflows/conda-package-cf.yml +++ b/.github/workflows/conda-package-cf.yml @@ -143,7 +143,7 @@ jobs: - name: Install mkl_fft run: | CHANNELS=(-c "$GITHUB_WORKSPACE"/channel ${{ env.CHANNELS }}) - conda create -n ${{ env.TEST_ENV_NAME }} python=${{ matrix.python }} ${{ matrix.numpy }} "$PACKAGE_NAME" pytest scipy "${CHANNELS[@]}" + conda create -n ${{ env.TEST_ENV_NAME }} python=${{ matrix.python }} ${{ matrix.numpy }} "$PACKAGE_NAME" pytest scipy mkl-service "${CHANNELS[@]}" # Test installed packages conda list -n ${{ env.TEST_ENV_NAME }} @@ -318,7 +318,7 @@ jobs: FOR /F "tokens=* USEBACKQ" %%F IN (`python -c "%SCRIPT%"`) DO ( SET PACKAGE_VERSION=%%F ) - SET "TEST_DEPENDENCIES=pytest scipy" + SET "TEST_DEPENDENCIES=pytest scipy mkl-service" conda install -n ${{ env.TEST_ENV_NAME }} ${{ env.PACKAGE_NAME }}=%PACKAGE_VERSION% %TEST_DEPENDENCIES% python=${{ matrix.python }} ${{ matrix.numpy }} -c ${{ env.workdir }}/channel ${{ env.CHANNELS }} - name: Report content of test environment diff --git a/.github/workflows/conda-package.yml b/.github/workflows/conda-package.yml index 4ba92021..c97b7abf 100644 --- a/.github/workflows/conda-package.yml +++ b/.github/workflows/conda-package.yml @@ -143,7 +143,7 @@ jobs: run: | CHANNELS=(-c "$GITHUB_WORKSPACE"/channel ${{ env.CHANNELS }}) conda create -n ${{ env.TEST_ENV_NAME }} "$PACKAGE_NAME"=${{ env.PACKAGE_VERSION }} python=${{ matrix.python }} pytest "${CHANNELS[@]}" - conda install -n ${{ env.TEST_ENV_NAME }} "scipy>=1.10" "${CHANNELS[@]}" + conda install -n ${{ env.TEST_ENV_NAME }} "scipy>=1.10" "mkl-service" "${CHANNELS[@]}" # Test installed packages conda list -n ${{ env.TEST_ENV_NAME }} @@ -308,7 +308,7 @@ jobs: ) SET "TEST_DEPENDENCIES=pytest" conda install -n ${{ env.TEST_ENV_NAME }} ${{ env.PACKAGE_NAME }}=%PACKAGE_VERSION% %TEST_DEPENDENCIES% python=${{ matrix.python }} -c ${{ env.workdir }}/channel ${{ env.CHANNELS }} - conda install -n ${{ env.TEST_ENV_NAME }} scipy -c ${{ env.workdir }}/channel ${{ env.CHANNELS }} + conda install -n ${{ env.TEST_ENV_NAME }} scipy mkl-service -c ${{ env.workdir }}/channel ${{ env.CHANNELS }} } - name: Report content of test environment shell: cmd /C CALL {0} diff --git a/conda-recipe-cf/meta.yaml b/conda-recipe-cf/meta.yaml index fd61e537..6d3a1745 100644 --- a/conda-recipe-cf/meta.yaml +++ b/conda-recipe-cf/meta.yaml @@ -26,7 +26,7 @@ requirements: run: - python - python-gil # [py>=314] - - mkl-service + - {{ pin_compatible('mkl') }} - numpy test: @@ -35,6 +35,7 @@ test: requires: - pytest - scipy >=1.10 + - mkl-service imports: - mkl_fft - mkl_fft.interfaces diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index 949fdec2..7211767d 100644 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -40,7 +40,7 @@ requirements: run: - python - python-gil # [py>=314] - - mkl-service + - {{ pin_compatible('mkl') }} {% if use_numpy_base %} - numpy-base {% else %} @@ -52,8 +52,8 @@ test: - pytest -v --pyargs mkl_fft requires: - pytest - # This is a temporary python restriction - - scipy >=1.10 # [py<314] + - scipy >=1.10 + - mkl-service imports: - mkl_fft - mkl_fft.interfaces diff --git a/mkl_fft/interfaces/__init__.py b/mkl_fft/interfaces/__init__.py index ff17c4b9..6bd8f7fd 100644 --- a/mkl_fft/interfaces/__init__.py +++ b/mkl_fft/interfaces/__init__.py @@ -23,12 +23,21 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import importlib.util + from . import numpy_fft -# find scipy, not scipy.fft, to avoid circular dependency -try: - import scipy -except ImportError: - pass -else: - from . import scipy_fft +__all__ = ["numpy_fft"] + +_has_scipy = importlib.util.find_spec("scipy") is not None +_has_mkl_service = importlib.util.find_spec("mkl") is not None + +if _has_scipy: + if not _has_mkl_service: + pass + else: + from . import scipy_fft + + __all__.append("scipy_fft") + +del importlib, _has_scipy, _has_mkl_service diff --git a/pyproject.toml b/pyproject.toml index d3f60298..a17d776a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,7 +50,7 @@ classifiers = [ "Operating System :: POSIX", "Operating System :: Unix" ] -dependencies = ["numpy>=1.26.4", "mkl-service"] +dependencies = ["numpy>=1.26.4", "mkl"] description = "MKL-based FFT transforms for NumPy arrays" dynamic = ["version"] keywords = ["DFTI", "FFT", "Fourier", "MKL"] @@ -60,8 +60,8 @@ readme = {file = "README.md", content-type = "text/markdown"} requires-python = ">=3.10,<3.15" [project.optional-dependencies] -scipy_interface = ["scipy>=1.10"] -test = ["pytest", "scipy>=1.10"] +scipy_interface = ["scipy>=1.10", "mkl-service"] +test = ["pytest", "scipy>=1.10", "mkl-service"] [project.urls] Download = "http://github.com/IntelPython/mkl_fft" From 33d2698d0f8168732412f626f91272707939138d Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Fri, 10 Apr 2026 17:44:49 -0700 Subject: [PATCH 2/3] revert use of importlib in interfaces __init__ --- mkl_fft/interfaces/__init__.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/mkl_fft/interfaces/__init__.py b/mkl_fft/interfaces/__init__.py index 6bd8f7fd..01573bc2 100644 --- a/mkl_fft/interfaces/__init__.py +++ b/mkl_fft/interfaces/__init__.py @@ -23,21 +23,25 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import importlib.util - from . import numpy_fft __all__ = ["numpy_fft"] -_has_scipy = importlib.util.find_spec("scipy") is not None -_has_mkl_service = importlib.util.find_spec("mkl") is not None +try: + import scipy + + _has_scipy = True +except ImportError: + _has_scipy = False if _has_scipy: - if not _has_mkl_service: + try: + import mkl + + from . import scipy_fft + except ImportError: pass else: - from . import scipy_fft - __all__.append("scipy_fft") -del importlib, _has_scipy, _has_mkl_service +del _has_scipy From 74a53098f9dd1f3fc4bf25d2069a5708b79756c8 Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Fri, 10 Apr 2026 17:52:44 -0700 Subject: [PATCH 3/3] restructure interfaces __init__ to avoid local variables and namespace pollution --- mkl_fft/interfaces/__init__.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/mkl_fft/interfaces/__init__.py b/mkl_fft/interfaces/__init__.py index 01573bc2..f48313a8 100644 --- a/mkl_fft/interfaces/__init__.py +++ b/mkl_fft/interfaces/__init__.py @@ -30,18 +30,17 @@ try: import scipy - _has_scipy = True + del scipy except ImportError: - _has_scipy = False - -if _has_scipy: + pass +else: try: import mkl - from . import scipy_fft + del mkl except ImportError: pass else: - __all__.append("scipy_fft") + from . import scipy_fft -del _has_scipy + __all__.append("scipy_fft")