From 72634dd193d5ee740fe09436dfbcc2ec5416d5d8 Mon Sep 17 00:00:00 2001 From: Maxime Mulder Date: Fri, 13 Sep 2024 10:05:05 -0400 Subject: [PATCH] LORIS-MRI tooling configuration (#1170) * add pyproject.toml * keep flake8 (for now) * double type checking * Use Pyright as main type checker * remove comment * test * test * change configuration * add python environment variables * try factorization * test * test * test * test * remove temporary things * test ruff error * ruff output github * further test errors * test pyright output github * test * test * test * change comment * remove test errors * test --------- Co-authored-by: Maxime Mulder --- .github/actions/setup-python/action.yml | 23 +++++++ .github/workflows/flake8_python_linter.yml | 42 ------------- .github/workflows/python-checks.yml | 73 ++++++++++++++++++++++ pyproject.toml | 26 ++++++++ python/requirements.txt | 4 +- test/pyrightconfig.json | 7 +++ 6 files changed, 132 insertions(+), 43 deletions(-) create mode 100644 .github/actions/setup-python/action.yml delete mode 100644 .github/workflows/flake8_python_linter.yml create mode 100644 .github/workflows/python-checks.yml create mode 100644 pyproject.toml create mode 100644 test/pyrightconfig.json diff --git a/.github/actions/setup-python/action.yml b/.github/actions/setup-python/action.yml new file mode 100644 index 000000000..921d96b61 --- /dev/null +++ b/.github/actions/setup-python/action.yml @@ -0,0 +1,23 @@ +name: Set up Python +input: +inputs: + python-version: + required: true + +runs: + using: composite + + steps: + - name: Set up the Python environment + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + cache: 'pip' + + - name: Install Python dependencies + run: pip install -r python/requirements.txt + shell: bash + + - name: Set up environment variables + run: echo PYTHONPATH=$PYTHONPATH:/`pwd`/python:/`pwd`/python/react-series-data-viewer >> $GITHUB_ENV + shell: bash diff --git a/.github/workflows/flake8_python_linter.yml b/.github/workflows/flake8_python_linter.yml deleted file mode 100644 index 3c52466ca..000000000 --- a/.github/workflows/flake8_python_linter.yml +++ /dev/null @@ -1,42 +0,0 @@ -# This workflow runs flake8 with reviewdog. The documentation can be found below: -# https://github.com/marketplace/actions/run-flake8-with-reviewdog -# Flake8 is a Python linter that analyzes code and checks for programming and stylistic errors -name: Flake8 Linter - -# This workflow acts only on pull requests -on: pull_request - -jobs: - - flake8-lint: - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.11", "3.12"] - - steps: - - name: Check out source repository - uses: actions/checkout@v2 - - - name: Set up Python environment - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - - name: Flake8 Lint - uses: reviewdog/action-flake8@v3 - with: - # For more flake 8 arguments, visit the link below: - # https://flake8.pycqa.org/en/latest/user/options.html - # Currently, flake8 ignores the following; - # E202: Whitespace before ')' - # E203: Whitespace before ':' - # E221: Multiple spaces before operator - # E241: Multiple spaces after ',' - # E251: Unexpected spaces around keyword / parameter equals - # E272: Multiple spaces before keyword - flake8_args: "--ignore=W503,E202,E203,E221,E241,E251,E272,E126,E131,E121,E111,E127 - --max-line-length 120 - --exclude python/react-series-data-viewer/protocol_buffers/ - --exclude Loris " - github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/python-checks.yml b/.github/workflows/python-checks.yml new file mode 100644 index 000000000..fddf5c1f1 --- /dev/null +++ b/.github/workflows/python-checks.yml @@ -0,0 +1,73 @@ +name: Python checks + +on: + - push + - pull_request + +jobs: + ruff: + name: "Ruff" + runs-on: ubuntu-latest + + strategy: + matrix: + python-version: ["3.11", "3.12"] + + steps: + - name: Check out LORIS-MRI + uses: actions/checkout@v4 + + - name: Set up Python + uses: ./.github/actions/setup-python + with: + python-version: ${{ matrix.python-version }} + + - name: Run Ruff + run: ruff check --output-format=github + + pyright-strict: + name: "Pyright strict" + runs-on: ubuntu-latest + + strategy: + matrix: + python-version: ["3.11", "3.12"] + + steps: + - name: Check out LORIS-MRI + uses: actions/checkout@v4 + + - name: Set up Python + uses: ./.github/actions/setup-python + with: + python-version: ${{ matrix.python-version }} + + # Like in the other Pyright run, the `jq` arcane is used to translate the errors from JSON to + # the GitHub actions format + - name: Run Pyright + run: | + pyright --outputjson | jq -r '.generalDiagnostics[] | "::error file=\(.file),line=\(.range.start.line),col=\(.range.start.character)::\(.message)"' + (exit ${PIPESTATUS[0]}) + + pyrigh-global: + name: "Pyright global" + runs-on: ubuntu-latest + + strategy: + matrix: + python-version: ["3.11", "3.12"] + + steps: + - name: Check out LORIS-MRI + uses: actions/checkout@v4 + + - name: Set up Python + uses: ./.github/actions/setup-python + with: + python-version: ${{ matrix.python-version }} + + - name: Run Pyright + run: | + cd test + pyright --outputjson | jq -r '.generalDiagnostics[] | "::error file=\(.file),line=\(.range.start.line),col=\(.range.start.character)::\(.message)"' + (exit ${PIPESTATUS[0]}) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..bc66769a8 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,26 @@ +[tool.ruff] +include = ["python/**/*.py"] +exclude = ["python/react-series-data-viewer"] +line-length = 120 +preview = true + +[tool.ruff.lint] +ignore = ["E202", "E203", "E221", "E241", "E251", "E272"] +# TODO: Select "F", "I", "N", "UP" and format the codebase accordingly. +select = ["E", "W"] + +# The strict type checking configuration is used to type check only the modern (typed) modules. An +# additional basic type checking configuration to type check legacy modules can be found in the +# `test` directory. + +[tool.pyright] +include = [ + "python/lib/db", + "python/lib/exception", + "python/lib/validate_subject_ids.py" +] +typeCheckingMode = "strict" +reportMissingTypeStubs = "none" + +[tool.pytest.ini-options] +testpaths = ["python/tests"] diff --git a/python/requirements.txt b/python/requirements.txt index 0d1abe193..9e5eaa6ed 100644 --- a/python/requirements.txt +++ b/python/requirements.txt @@ -1,5 +1,4 @@ boto3 -flake8 google mat73 matplotlib @@ -13,7 +12,10 @@ nose numpy protobuf>=3.0.0 pybids==0.17.0 +pyright +pytest python-dateutil +ruff scikit-learn scipy sqlalchemy>=2.0.0 diff --git a/test/pyrightconfig.json b/test/pyrightconfig.json new file mode 100644 index 000000000..b9189aa38 --- /dev/null +++ b/test/pyrightconfig.json @@ -0,0 +1,7 @@ +{ + "include": ["../python"], + "exclude": ["../python/react-series-data-viewer"], + "typeCheckingMode": "off", + "reportDeprecated": "warning", + "reportMissingImports": "error" +}