Skip to content

Commit

Permalink
Numpy 2.0 + scipy + matplotlib pre-release workflow (#89)
Browse files Browse the repository at this point in the history
* pin pytest to 8.0 and above

* move conftest.py to root and turn warnings into errors

* add workflow testing against numpy 2.0

* skip coverage

* fix config file used

* also install pip-pre scipy and matplotlib

* scikit-learn also for nilearn compatibility with numpy 2.0

* don't run nilearn tests on pip-pre

* run 3.9 and 3.12 on circle and 3.7 compat on gh

* fix workflow name

* fix: importorskip is not a mark decorator

* catch user warning

* fix deprecated readfp

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* ignore conftest in module discovery

* fix uninstall step of nilearn

* try again to rm nilearn

* fix module discovery logic

* fix numpy deprecation of np.NINF and np.trapz

* fix missed importorskip("nilearn")

* fix deprecation of find_module in module discovery logic

* fix compatibility trapz <-> trapezoid

* fix compatibility function

* add missed pytest.importorskip("nilearn")

* fix imports, drop pkg_utils entirely

* fix missed imports

* rm unused variable

* use relative imports and fix circular import and namespace

* revert version import

* close log file handler

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix missed importorskip("nilearn")

* fix codecov yml

* suppress sphinx gallery warning

* mv trapezoid_compat

* trigger ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
Mathieu Scheltienne and pre-commit-ci[bot] authored Apr 25, 2024
1 parent cb99342 commit 3a8bd18
Show file tree
Hide file tree
Showing 20 changed files with 230 additions and 93 deletions.
20 changes: 10 additions & 10 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ orbs:
# Define a job to be invoked later in a workflow.
# See: https://circleci.com/docs/2.0/configuration-reference/#jobs
jobs:
test37: # This is the name of the job, feel free to change it to better match what you're trying to do!
test39: # This is the name of the job, feel free to change it to better match what you're trying to do!
# These next lines defines a Docker executors: https://circleci.com/docs/2.0/executor-types/
# You can specify an image from Dockerhub or use one of the convenience images from CircleCI's Developer Hub
# A list of available CircleCI Docker convenience images are available here: https://circleci.com/developer/images/image/cimg/python
# The executor is the environment in which the steps below will be executed - below will use a python 3.6.14 container
# Change the version below to your required version of python
docker:
- image: cimg/python:3.7
- image: cimg/python:3.9
working_directory: /tmp/src/nigsp
resource_class: medium
# Checkout the code as the first step. This is a dedicated CircleCI step.
Expand Down Expand Up @@ -58,9 +58,9 @@ jobs:
paths:
- src/coverage/.coverage.py37

test310:
test312:
docker:
- image: cimg/python:3.10
- image: cimg/python:3.12
working_directory: /tmp/src/nigsp
resource_class: medium
steps:
Expand All @@ -85,7 +85,7 @@ jobs:

style_check:
docker:
- image: cimg/python:3.7
- image: cimg/python:3.11
working_directory: /tmp/src/nigsp
resource_class: small
steps:
Expand All @@ -105,7 +105,7 @@ jobs:
merge_coverage:
working_directory: /tmp/src/nigsp
docker:
- image: cimg/python:3.10
- image: cimg/python:3.11
resource_class: small
steps:
- attach_workspace:
Expand Down Expand Up @@ -133,13 +133,13 @@ workflows:
# Inside the workflow, you define the jobs you want to run.
jobs:
- style_check
- test37:
- test39:
requires:
- style_check
- test310:
- test312:
requires:
- style_check
- merge_coverage:
requires:
- test37
- test310
- test39
- test312
84 changes: 84 additions & 0 deletions .github/workflows/pytest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: pytest
concurrency:
group: ${{ github.workflow }}-${{ github.event.number }}-${{ github.event.ref }}
cancel-in-progress: true
on: # yamllint disable-line rule:truthy
pull_request:
push:
branches: [main]
workflow_dispatch:
schedule:
- cron: '0 8 * * 1'

jobs:
pytest-compat:
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
python-version: ["3.7"]
name: pip compat - py${{ matrix.python-version }}
runs-on: ubuntu-latest
defaults:
run:
shell: bash
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
architecture: 'x64'
- name: Install dependencies
run: |
python -m pip install --progress-bar off --upgrade pip setuptools
python -m pip install --progress-bar off .[all,style]
python -m pip install --progress-bar off pytest pytest-cov coverage
- name: Run pytest
run: pytest nigsp --cov=nigsp --cov-report=xml --cov-config=setup.cfg
- name: Upload to codecov
uses: codecov/codecov-action@v4
with:
files: ./coverage.xml
flags: unittests # optional
name: codecov-umbrella # optional
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true # optional (default = false)
pytest-pip-pre:
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
python-version: ["3.11"]
name: pip pre-release - py${{ matrix.python-version }}
runs-on: ubuntu-latest
defaults:
run:
shell: bash
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
architecture: 'x64'
- name: Install dependencies
run: |
python -m pip install --progress-bar off --upgrade pip setuptools
python -m pip install --progress-bar off .[test]
python -m pip install matplotlib
python -m pip install --progress-bar off --upgrade --no-deps --pre --only-binary :all: -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple --timeout=180 matplotlib
python -m pip install --progress-bar off --upgrade --pre --only-binary :all: -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple --timeout=180 numpy scipy
python -m pip uninstall -y nilearn
- name: Run pytest
run: pytest nigsp --cov=nigsp --cov-report=xml --cov-config=setup.cfg
- name: Upload to codecov
uses: codecov/codecov-action@v4
with:
files: ./coverage.xml
flags: unittests # optional
name: codecov-umbrella # optional
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true # optional (default = false)
6 changes: 3 additions & 3 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
codecov:
branch: master
strict_yaml_branch: master
require_ci_to_pass: yes
require_ci_to_pass: true
bot: "codecov-io"
max_report_age: 48
disable_default_path_fixes: no
disable_default_path_fixes: false

coverage:
precision: 2
Expand Down Expand Up @@ -40,4 +40,4 @@ ignore:
comment:
layout: "reach,diff,flags,tree"
behavior: default
require_changes: no
require_changes: false
3 changes: 3 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@
nitpicky = True
nitpick_ignore = []

# list of warning types to suppress
suppress_warnings = ["config.cache"]

# -- Options for HTML output -------------------------------------------------

# The theme to use for HTML and HTML Help pages. See the documentation for
Expand Down
26 changes: 12 additions & 14 deletions nigsp/__init__.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
"""Hopefully importing everything."""

import pkgutil

from . import (
blocks,
cli,
due,
io,
objects,
operations,
references,
utils,
viz,
workflow,
)
from ._version import get_versions
from .operations import graph, laplacian, metrics, nifti, surrogates, timeseries

SKIP_MODULES = ["tests"]

__version__ = get_versions()["version"]
del get_versions

__all__ = []
for loader, module_name, is_pkg in pkgutil.walk_packages(__path__):
if "tests" not in module_name:
__all__.append(module_name)
_module = loader.find_module(module_name).load_module(module_name)
globals()[module_name] = _module
4 changes: 2 additions & 2 deletions nigsp/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@

import logging

from nigsp import io, viz
from nigsp.operations import nifti
from . import io, viz
from .operations import nifti

LGR = logging.getLogger(__name__)

Expand Down
9 changes: 3 additions & 6 deletions nigsp/cli/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,15 @@

import argparse

from nigsp import __version__
from .. import __version__


def _get_parser():
"""
Parse command line inputs for this function.
"""Parse command line inputs for this function.
Returns
-------
parser.parse_args() : argparse dict
"""
parser = argparse.ArgumentParser(
description=(
Expand Down Expand Up @@ -251,8 +249,7 @@ def _get_parser():
if __name__ == "__main__":
raise RuntimeError(
"nigsp/cli/run.py should not be run directly;\n"
"Please `pip install` nigsp and use the "
"`nigsp` command"
"Please `pip install` nigsp and use the `nigsp` command."
)


Expand Down
42 changes: 30 additions & 12 deletions nigsp/tests/conftest.py → nigsp/conftest.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,31 @@
"""
This configuration test module was taken from phys2bids.
Credit to the original author(s) and to the phys2bids community.
"""
from __future__ import annotations # c.f. PEP 563, PEP 649

import os
import ssl
from typing import TYPE_CHECKING
from urllib.request import urlretrieve

import pytest
from pytest import fixture

if TYPE_CHECKING:
from pytest import Config


def pytest_configure(config: Config) -> None:
"""Configure pytest options."""
warnings_lines = r"""
error::
"""
for warning_line in warnings_lines.split("\n"):
warning_line = warning_line.strip()
if warning_line and not warning_line.startswith("#"):
config.addinivalue_line("filterwarnings", warning_line)


"""
The following fetch_file and configuration test module was taken from phys2bids.
Credit to the original author(s) and to the phys2bids community.
"""


def fetch_file(osf_id, path, filename):
Expand Down Expand Up @@ -48,37 +66,37 @@ def fetch_file(osf_id, path, filename):
return full_path


@pytest.fixture(scope="session")
@fixture(scope="session")
def testdir(tmp_path_factory):
"""Test path that will be used to download all files."""
return tmp_path_factory.getbasetemp()


@pytest.fixture
@fixture(scope="function")
def atlas(testdir):
return fetch_file("h6nj7", testdir, "atlas.nii.gz")


@pytest.fixture
@fixture(scope="function")
def atlastime(testdir):
return fetch_file("ts6a8", testdir, "ats.nii.gz")


@pytest.fixture
@fixture(scope="function")
def mean_fc(testdir):
return fetch_file("jrg8d", testdir, "mean_fc_matlab.tsv")


@pytest.fixture
@fixture(scope="function")
def sdi(testdir):
return fetch_file("rs4dn", testdir, "SDI_matlab.tsv")


@pytest.fixture
@fixture(scope="function")
def sc_mtx(testdir):
return fetch_file("vwh75", testdir, "sc.mat")


@pytest.fixture
@fixture(scope="function")
def timeseries(testdir):
return fetch_file("ay8df", testdir, "func.mat")
2 changes: 1 addition & 1 deletion nigsp/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

import numpy as np

from nigsp.utils import change_var_type
from .utils import change_var_type

EXT_1D = [".txt", ".csv", ".tsv", ".1d", ".par", ".tsv.gz", ".csv.gz"]
EXT_MAT = [".mat"]
Expand Down
2 changes: 1 addition & 1 deletion nigsp/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import logging
from copy import deepcopy

from nigsp import operations
from . import operations

LGR = logging.getLogger(__name__)

Expand Down
2 changes: 1 addition & 1 deletion nigsp/operations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
`nigsp.operations.sdi` or `nigsp.metrisc.sdi`.
"""

# Import all operations.
from . import graph, laplacian, metrics, nifti, surrogates, timeseries
from .graph import nodestrength, zerocross
from .laplacian import (
compute_laplacian,
Expand Down
2 changes: 1 addition & 1 deletion nigsp/operations/surrogates.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ def _pmf(x, n, p):
if return_masked:
LGR.info("Returning masked empirical data")
stat_mask = np.ma.array(
data=surr[..., -1], mask=np.invert(stat_mask), fill_value=np.NINF
data=surr[..., -1], mask=np.invert(stat_mask), fill_value=-np.inf
).squeeze()
else:
LGR.info("Returning mask")
Expand Down
Loading

0 comments on commit 3a8bd18

Please sign in to comment.