mirror of
https://github.com/apache/superset.git
synced 2026-05-24 17:25:20 +00:00
Follow-up to #40231 (merged), where a reviewer flagged a function-body `from datetime import datetime, timedelta` instead of a top-of-file import. Adds a `ruff-import-placement` pre-commit hook running `ruff check --select PLC0415 --preview --no-fix`. Per @rusackas's pushback on the first cut of this PR — which spammed 2,657 `# noqa: PLC0415` annotations across ~410 files without fixing anything — this revision is a much smaller surface area: 1. **Per-file-ignores** for whole directories where function-body imports are a deliberate pattern, not an oversight: - `superset/cli/**` and `scripts/**`: subcommand-deferred imports keep heavy modules out of the CLI startup path. - `superset/tasks/**`: Celery task bodies defer imports of the modules they orchestrate. - `superset/migrations/versions/**`: Alembic migrations interact with model state at runtime, not at module load. - `superset/mcp_service/**`: MCP tools lazy-load resources on invocation so the server can register many tools without paying their import cost at startup. - `superset/db_engine_specs/**`: engine specs defer driver imports so optional DB drivers don't have to be installed. - `superset/initialization/__init__.py`, `superset/extensions/__init__.py`, `superset/app.py`: the app-factory and extension wiring are intentionally full of circular-import workarounds. - `tests/**`: test files routinely defer imports for fixture isolation; the rule still applies to production code. 2. **Per-line `# noqa: PLC0415`** on the 259 remaining genuine circular-import sites (security/manager.py, sql/execution/executor.py, semantic_layers/labels.py, tags/core.py, core_api_injection.py, etc.). These are foundational modules where moving the imports up would actually break things. Net result: ~410 files / 2,657 grandfathered → ~73 files / 259 actual noqa annotations. The rule still catches every new function-body import outside the explicitly-allowed directories. Also: silences a pre-existing C901 on `mcp_service/sql_lab/tool/execute_sql.py` that fires under newer local ruff but not CI's pinned ruff 0.9.7 — blocks the local pre-commit run otherwise. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
174 lines
7.0 KiB
YAML
174 lines
7.0 KiB
YAML
#
|
|
# Licensed to the Apache Software Foundation (ASF) under one or more
|
|
# contributor license agreements. See the NOTICE file distributed with
|
|
# this work for additional information regarding copyright ownership.
|
|
# The ASF licenses this file to You under the Apache License, Version 2.0
|
|
# (the "License"); you may not use this file except in compliance with
|
|
# the License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
repos:
|
|
- repo: https://github.com/MarcoGorelli/auto-walrus
|
|
rev: 0.3.4
|
|
hooks:
|
|
- id: auto-walrus
|
|
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
rev: v1.15.0
|
|
hooks:
|
|
- id: mypy
|
|
name: mypy (main)
|
|
args: [--check-untyped-defs]
|
|
exclude: ^superset-extensions-cli/
|
|
additional_dependencies: [
|
|
types-cachetools,
|
|
types-simplejson,
|
|
types-python-dateutil,
|
|
types-requests,
|
|
# types-redis 4.6.0.5 is failing mypy
|
|
# because of https://github.com/python/typeshed/pull/10531
|
|
types-redis==4.6.0.4,
|
|
types-pytz,
|
|
types-croniter,
|
|
types-PyYAML,
|
|
types-setuptools,
|
|
types-paramiko,
|
|
types-Markdown,
|
|
]
|
|
- id: mypy
|
|
name: mypy (superset-extensions-cli)
|
|
args: [--check-untyped-defs]
|
|
files: ^superset-extensions-cli/
|
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
rev: v5.0.0
|
|
hooks:
|
|
- id: check-docstring-first
|
|
- id: check-added-large-files
|
|
exclude: ^.*\.(geojson)$|^docs/static/img/screenshots/.*|^superset-frontend/CHANGELOG\.md$|^superset/examples/.*/data\.parquet$
|
|
- id: check-yaml
|
|
exclude: ^helm/superset/templates/
|
|
- id: debug-statements
|
|
- id: end-of-file-fixer
|
|
exclude: .*/lerna\.json$|^docs/static/img/logos/
|
|
- id: trailing-whitespace
|
|
exclude: ^.*\.(snap)
|
|
args: ["--markdown-linebreak-ext=md"]
|
|
- repo: local
|
|
hooks:
|
|
- id: prettier-frontend
|
|
name: prettier (frontend)
|
|
entry: bash -c 'cd superset-frontend && for file in "$@"; do npx prettier --write "${file#superset-frontend/}"; done'
|
|
language: system
|
|
pass_filenames: true
|
|
files: ^superset-frontend/.*\.(js|jsx|ts|tsx|css|scss|sass|json)$
|
|
- repo: local
|
|
hooks:
|
|
- id: oxlint-frontend
|
|
name: oxlint (frontend)
|
|
entry: ./scripts/oxlint.sh
|
|
language: system
|
|
pass_filenames: true
|
|
files: ^superset-frontend/.*\.(js|jsx|ts|tsx)$
|
|
- id: custom-rules-frontend
|
|
name: custom rules (frontend)
|
|
entry: ./scripts/check-custom-rules.sh
|
|
language: system
|
|
pass_filenames: true
|
|
files: ^superset-frontend/.*\.(js|jsx|ts|tsx)$
|
|
- id: eslint-docs
|
|
name: eslint (docs)
|
|
entry: bash -c 'cd docs && FILES=$(printf "%s\n" "$@" | sed "s|^docs/||" | tr "\n" " ") && yarn eslint --fix --quiet $FILES'
|
|
language: system
|
|
pass_filenames: true
|
|
files: ^docs/.*\.(js|jsx|ts|tsx)$
|
|
- id: type-checking-frontend
|
|
name: Type-Checking (Frontend)
|
|
entry: ./scripts/check-type.js package=superset-frontend excludeDeclarationDir=cypress-base
|
|
language: system
|
|
files: ^superset-frontend\/.*\.(js|jsx|ts|tsx)$
|
|
exclude: ^superset-frontend/cypress-base\/
|
|
require_serial: true
|
|
# blacklist unsafe functions like make_url (see #19526)
|
|
- repo: https://github.com/skorokithakis/blacklist-pre-commit-hook
|
|
rev: e2f070289d8eddcaec0b580d3bde29437e7c8221
|
|
hooks:
|
|
- id: blacklist
|
|
args: ["--blacklisted-names=make_url", "--ignore=tests/"]
|
|
- repo: https://github.com/norwoodj/helm-docs
|
|
rev: v1.14.2
|
|
hooks:
|
|
- id: helm-docs
|
|
files: helm
|
|
verbose: false
|
|
args: ["--log-level", "error"]
|
|
# Using local hooks ensures ruff version matches requirements/development.txt
|
|
- repo: local
|
|
hooks:
|
|
- id: ruff-format
|
|
name: ruff-format
|
|
entry: ruff format
|
|
language: system
|
|
types: [python]
|
|
- id: ruff
|
|
name: ruff
|
|
entry: ruff check --fix --show-fixes
|
|
language: system
|
|
types: [python]
|
|
- id: ruff-import-placement
|
|
name: ruff (import placement / PLC0415)
|
|
# PLC0415 ("import should be at top-level") is preview-only in
|
|
# ruff, so we can't put it in `[tool.ruff.lint] select` without
|
|
# enabling preview mode globally (which would also activate
|
|
# behavior changes for unrelated stable rules). Run it as a
|
|
# dedicated step instead. Existing function-body imports are
|
|
# grandfathered with per-line `# noqa: PLC0415`; new code must
|
|
# either move the import to the top or add the same noqa with
|
|
# a justification.
|
|
entry: ruff check --select PLC0415 --preview --no-fix
|
|
language: system
|
|
types: [python]
|
|
- repo: local
|
|
hooks:
|
|
- id: pylint
|
|
name: pylint with custom Superset plugins
|
|
entry: bash
|
|
language: system
|
|
types: [python]
|
|
exclude: ^(tests/|superset/migrations/|scripts/|RELEASING/|docker/)
|
|
args:
|
|
- -c
|
|
- |
|
|
TARGET_BRANCH=${GITHUB_BASE_REF:-master}
|
|
# Only fetch if we're not in CI (CI already has all refs)
|
|
if [ -z "$CI" ]; then
|
|
git fetch --no-recurse-submodules origin "$TARGET_BRANCH" 2>/dev/null || true
|
|
fi
|
|
BASE=$(git merge-base origin/"$TARGET_BRANCH" HEAD 2>/dev/null) || BASE="HEAD"
|
|
files=$(git diff --name-only --diff-filter=ACM "$BASE"..HEAD 2>/dev/null | grep '^superset/.*\.py$' || true)
|
|
if [ -n "$files" ]; then
|
|
pylint --rcfile=.pylintrc --load-plugins=superset.extensions.pylint --reports=no $files
|
|
else
|
|
echo "No Python files to lint."
|
|
fi
|
|
- id: db-engine-spec-metadata
|
|
name: database engine spec metadata validation
|
|
entry: python superset/db_engine_specs/lint_metadata.py --strict
|
|
language: system
|
|
files: ^superset/db_engine_specs/.*\.py$
|
|
exclude: ^superset/db_engine_specs/(base|lib|lint_metadata|__init__)\.py$
|
|
pass_filenames: false
|
|
- repo: local
|
|
hooks:
|
|
- id: feature-flags-sync
|
|
name: feature flags documentation sync
|
|
entry: bash -c 'python scripts/extract_feature_flags.py > docs/static/feature-flags.json.tmp && if ! diff -q docs/static/feature-flags.json docs/static/feature-flags.json.tmp > /dev/null 2>&1; then mv docs/static/feature-flags.json.tmp docs/static/feature-flags.json && echo "Updated docs/static/feature-flags.json" && exit 1; else rm docs/static/feature-flags.json.tmp; fi'
|
|
language: system
|
|
files: ^superset/config\.py$
|
|
pass_filenames: false
|