Compare commits

..

4 Commits

Author SHA1 Message Date
Jack O'Connor
abe6a36c80 don't do nested bindings inference if we have a declared type 2025-08-08 15:54:56 -07:00
Jack O'Connor
b82bbcd51c stop tracking implicit (read-only) free variables 2025-08-08 13:22:01 -07:00
Jack O'Connor
56e550176c addressing some of Micha's comments 2025-08-08 09:05:50 -07:00
Jack O'Connor
a6569ed960 [ty] add nested bindings to the semantic index 2025-08-07 20:39:10 -07:00
2057 changed files with 42557 additions and 70524 deletions

View File

@@ -49,7 +49,7 @@ jobs:
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
- name: "Build sdist"
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
uses: PyO3/maturin-action@e10f6c464b90acceb5f640d31beda6d586ba7b4a # v1.49.3
with:
command: sdist
args: --out dist
@@ -79,7 +79,7 @@ jobs:
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
- name: "Build wheels - x86_64"
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
uses: PyO3/maturin-action@e10f6c464b90acceb5f640d31beda6d586ba7b4a # v1.49.3
with:
target: x86_64
args: --release --locked --out dist
@@ -121,7 +121,7 @@ jobs:
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
- name: "Build wheels - aarch64"
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
uses: PyO3/maturin-action@e10f6c464b90acceb5f640d31beda6d586ba7b4a # v1.49.3
with:
target: aarch64
args: --release --locked --out dist
@@ -177,7 +177,7 @@ jobs:
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
- name: "Build wheels"
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
uses: PyO3/maturin-action@e10f6c464b90acceb5f640d31beda6d586ba7b4a # v1.49.3
with:
target: ${{ matrix.platform.target }}
args: --release --locked --out dist
@@ -230,7 +230,7 @@ jobs:
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
- name: "Build wheels"
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
uses: PyO3/maturin-action@e10f6c464b90acceb5f640d31beda6d586ba7b4a # v1.49.3
with:
target: ${{ matrix.target }}
manylinux: auto
@@ -292,8 +292,6 @@ jobs:
maturin_docker_options: -e JEMALLOC_SYS_WITH_LG_PAGE=16
- target: arm-unknown-linux-musleabihf
arch: arm
- target: riscv64gc-unknown-linux-gnu
arch: riscv64
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -306,7 +304,7 @@ jobs:
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
- name: "Build wheels"
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
uses: PyO3/maturin-action@e10f6c464b90acceb5f640d31beda6d586ba7b4a # v1.49.3
with:
target: ${{ matrix.platform.target }}
manylinux: auto
@@ -321,7 +319,7 @@ jobs:
githubToken: ${{ github.token }}
install: |
apt-get update
apt-get install -y --no-install-recommends python3 python3-pip libatomic1
apt-get install -y --no-install-recommends python3 python3-pip
pip3 install -U pip
run: |
pip3 install ${{ env.PACKAGE_NAME }} --no-index --find-links dist/ --force-reinstall
@@ -372,7 +370,7 @@ jobs:
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
- name: "Build wheels"
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
uses: PyO3/maturin-action@e10f6c464b90acceb5f640d31beda6d586ba7b4a # v1.49.3
with:
target: ${{ matrix.target }}
manylinux: musllinux_1_2
@@ -437,7 +435,7 @@ jobs:
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
- name: "Build wheels"
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
uses: PyO3/maturin-action@e10f6c464b90acceb5f640d31beda6d586ba7b4a # v1.49.3
with:
target: ${{ matrix.platform.target }}
manylinux: musllinux_1_2

View File

@@ -40,7 +40,7 @@ jobs:
- uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
- uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
@@ -131,7 +131,7 @@ jobs:
type=pep440,pattern={{ version }},value=${{ fromJson(inputs.plan).announcement_tag }}
type=pep440,pattern={{ major }}.{{ minor }},value=${{ fromJson(inputs.plan).announcement_tag }}
- uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
- uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
@@ -169,7 +169,7 @@ jobs:
steps:
- uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
- uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
@@ -276,7 +276,7 @@ jobs:
type=pep440,pattern={{ version }},value=${{ fromJson(inputs.plan).announcement_tag }}
type=pep440,pattern={{ major }}.{{ minor }},value=${{ fromJson(inputs.plan).announcement_tag }}
- uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
- uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}

View File

@@ -38,8 +38,7 @@ jobs:
fuzz: ${{ steps.check_fuzzer.outputs.changed }}
# Flag that is set to "true" when code related to ty changes.
ty: ${{ steps.check_ty.outputs.changed }}
# Flag that is set to "true" when code related to the py-fuzzer folder changes.
py-fuzzer: ${{ steps.check_py_fuzzer.outputs.changed }}
# Flag that is set to "true" when code related to the playground changes.
playground: ${{ steps.check_playground.outputs.changed }}
steps:
@@ -69,6 +68,7 @@ jobs:
':crates/ruff_text_size/**' \
':crates/ruff_python_ast/**' \
':crates/ruff_python_parser/**' \
':python/py-fuzzer/**' \
':.github/workflows/ci.yaml' \
; then
echo "changed=false" >> "$GITHUB_OUTPUT"
@@ -138,18 +138,6 @@ jobs:
echo "changed=true" >> "$GITHUB_OUTPUT"
fi
- name: Check if the py-fuzzer code changed
id: check_py_fuzzer
env:
MERGE_BASE: ${{ steps.merge_base.outputs.sha }}
run: |
if git diff --quiet "${MERGE_BASE}...HEAD" -- 'python/py_fuzzer/**' \
; then
echo "changed=false" >> "$GITHUB_OUTPUT"
else
echo "changed=true" >> "$GITHUB_OUTPUT"
fi
- name: Check if there was any code related change
id: check_code
env:
@@ -250,7 +238,7 @@ jobs:
- name: "Install Rust toolchain"
run: rustup show
- name: "Install mold"
uses: rui314/setup-mold@7344740a9418dcdcb481c7df83d9fbd1d5072d7d # v1
uses: rui314/setup-mold@702b1908b5edf30d71a8d1666b724e0f0c6fa035 # v1
- name: "Install cargo nextest"
uses: taiki-e/install-action@6064345e6658255e90e9500fdf9a06ab77e6909c # v2.57.6
with:
@@ -308,7 +296,7 @@ jobs:
- name: "Install Rust toolchain"
run: rustup show
- name: "Install mold"
uses: rui314/setup-mold@7344740a9418dcdcb481c7df83d9fbd1d5072d7d # v1
uses: rui314/setup-mold@702b1908b5edf30d71a8d1666b724e0f0c6fa035 # v1
- name: "Install cargo nextest"
uses: taiki-e/install-action@6064345e6658255e90e9500fdf9a06ab77e6909c # v2.57.6
with:
@@ -393,7 +381,7 @@ jobs:
- name: "Install Rust toolchain"
run: rustup show
- name: "Install mold"
uses: rui314/setup-mold@7344740a9418dcdcb481c7df83d9fbd1d5072d7d # v1
uses: rui314/setup-mold@702b1908b5edf30d71a8d1666b724e0f0c6fa035 # v1
- name: "Build"
run: cargo build --release --locked
@@ -418,7 +406,7 @@ jobs:
MSRV: ${{ steps.msrv.outputs.value }}
run: rustup default "${MSRV}"
- name: "Install mold"
uses: rui314/setup-mold@7344740a9418dcdcb481c7df83d9fbd1d5072d7d # v1
uses: rui314/setup-mold@702b1908b5edf30d71a8d1666b724e0f0c6fa035 # v1
- name: "Build tests"
shell: bash
env:
@@ -441,7 +429,7 @@ jobs:
- name: "Install Rust toolchain"
run: rustup show
- name: "Install cargo-binstall"
uses: cargo-bins/cargo-binstall@79e4beb1e02f733a26129a6bf26c37dab4ab3307 # v1.14.4
uses: cargo-bins/cargo-binstall@dd6a0ac24caa1243d18df0f770b941e990e8facc # v1.14.3
with:
tool: cargo-fuzz@0.11.2
- name: "Install cargo-fuzz"
@@ -455,7 +443,7 @@ jobs:
needs:
- cargo-test-linux
- determine_changes
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.parser == 'true' || needs.determine_changes.outputs.py-fuzzer == 'true') }}
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && needs.determine_changes.outputs.parser == 'true' }}
timeout-minutes: 20
env:
FORCE_COLOR: 1
@@ -645,7 +633,7 @@ jobs:
- cargo-test-linux
- determine_changes
# Only runs on pull requests, since that is the only we way we can find the base version for comparison.
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && github.event_name == 'pull_request' && (needs.determine_changes.outputs.ty == 'true' || needs.determine_changes.outputs.py-fuzzer == 'true') }}
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && github.event_name == 'pull_request' && needs.determine_changes.outputs.ty == 'true' }}
timeout-minutes: 20
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -694,7 +682,7 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- uses: cargo-bins/cargo-binstall@79e4beb1e02f733a26129a6bf26c37dab4ab3307 # v1.14.4
- uses: cargo-bins/cargo-binstall@dd6a0ac24caa1243d18df0f770b941e990e8facc # v1.14.3
- run: cargo binstall --no-confirm cargo-shear
- run: cargo shear
@@ -715,7 +703,7 @@ jobs:
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
- name: "Build wheels"
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
uses: PyO3/maturin-action@e10f6c464b90acceb5f640d31beda6d586ba7b4a # v1.49.3
with:
args: --out dist
- name: "Test wheel"
@@ -740,7 +728,7 @@ jobs:
with:
node-version: 22
- name: "Cache pre-commit"
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: ~/.cache/pre-commit
key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }}

View File

@@ -38,7 +38,7 @@ jobs:
- name: "Install Rust toolchain"
run: rustup show
- name: "Install mold"
uses: rui314/setup-mold@7344740a9418dcdcb481c7df83d9fbd1d5072d7d # v1
uses: rui314/setup-mold@702b1908b5edf30d71a8d1666b724e0f0c6fa035 # v1
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
- name: Build ruff
# A debug build means the script runs slower once it gets started,

View File

@@ -11,7 +11,6 @@ on:
- "crates/ruff_python_parser"
- ".github/workflows/mypy_primer.yaml"
- ".github/workflows/mypy_primer_comment.yaml"
- "scripts/mypy_primer.sh"
- "Cargo.lock"
- "!**.md"

View File

@@ -61,7 +61,7 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f
with:
persist-credentials: false
submodules: recursive
@@ -124,19 +124,19 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f
with:
persist-credentials: false
submodules: recursive
- name: Install cached dist
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
with:
name: cargo-dist-cache
path: ~/.cargo/bin/
- run: chmod +x ~/.cargo/bin/dist
# Get all the local artifacts for the global tasks to use (for e.g. checksums)
- name: Fetch local artifacts
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
with:
pattern: artifacts-*
path: target/distrib/
@@ -175,19 +175,19 @@ jobs:
outputs:
val: ${{ steps.host.outputs.manifest }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f
with:
persist-credentials: false
submodules: recursive
- name: Install cached dist
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
with:
name: cargo-dist-cache
path: ~/.cargo/bin/
- run: chmod +x ~/.cargo/bin/dist
# Fetch artifacts from scratch-storage
- name: Fetch artifacts
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
with:
pattern: artifacts-*
path: target/distrib/
@@ -251,13 +251,13 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f
with:
persist-credentials: false
submodules: recursive
# Create a GitHub Release while uploading all files to it
- name: "Download GitHub Artifacts"
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
with:
pattern: artifacts-*
path: artifacts

View File

@@ -54,9 +54,6 @@ jobs:
- name: Compute diagnostic diff
shell: bash
env:
# TODO: Remove this once we fixed the remaining panics in the conformance suite.
TY_MAX_PARALLELISM: 1
run: |
RUFF_DIR="$GITHUB_WORKSPACE/ruff"
@@ -66,15 +63,15 @@ jobs:
echo "new commit"
git rev-list --format=%s --max-count=1 "$GITHUB_SHA"
cargo build --bin ty
mv target/debug/ty ty-new
cargo build --release --bin ty
mv target/release/ty ty-new
MERGE_BASE="$(git merge-base "$GITHUB_SHA" "origin/$GITHUB_BASE_REF")"
git checkout -b old_commit "$MERGE_BASE"
echo "old commit (merge base)"
git rev-list --format=%s --max-count=1 old_commit
cargo build --bin ty
mv target/debug/ty ty-old
cargo build --release --bin ty
mv target/release/ty ty-old
)
(

View File

@@ -1,78 +1,5 @@
# Changelog
## 0.12.10
### Preview features
- \[`flake8-simplify`\] Implement fix for `maxsplit` without separator (`SIM905`) ([#19851](https://github.com/astral-sh/ruff/pull/19851))
- \[`flake8-use-pathlib`\] Add fixes for `PTH102` and `PTH103` ([#19514](https://github.com/astral-sh/ruff/pull/19514))
### Bug fixes
- \[`isort`\] Handle multiple continuation lines after module docstring (`I002`) ([#19818](https://github.com/astral-sh/ruff/pull/19818))
- \[`pyupgrade`\] Avoid reporting `__future__` features as unnecessary when they are used (`UP010`) ([#19769](https://github.com/astral-sh/ruff/pull/19769))
- \[`pyupgrade`\] Handle nested `Optional`s (`UP045`) ([#19770](https://github.com/astral-sh/ruff/pull/19770))
### Rule changes
- \[`pycodestyle`\] Make `E731` fix unsafe instead of display-only for class assignments ([#19700](https://github.com/astral-sh/ruff/pull/19700))
- \[`pyflakes`\] Add secondary annotation showing previous definition (`F811`) ([#19900](https://github.com/astral-sh/ruff/pull/19900))
### Documentation
- Fix description of global config file discovery strategy ([#19188](https://github.com/astral-sh/ruff/pull/19188))
- Update outdated links to <https://typing.python.org/en/latest/source/stubs.html> ([#19992](https://github.com/astral-sh/ruff/pull/19992))
- \[`flake8-annotations`\] Remove unused import in example (`ANN401`) ([#20000](https://github.com/astral-sh/ruff/pull/20000))
## 0.12.9
### Preview features
- \[`airflow`\] Add check for `airflow.secrets.cache.SecretCache` (`AIR301`) ([#17707](https://github.com/astral-sh/ruff/pull/17707))
- \[`ruff`\] Offer a safe fix for multi-digit zeros (`RUF064`) ([#19847](https://github.com/astral-sh/ruff/pull/19847))
### Bug fixes
- \[`flake8-blind-except`\] Fix `BLE001` false-positive on `raise ... from None` ([#19755](https://github.com/astral-sh/ruff/pull/19755))
- \[`flake8-comprehensions`\] Fix false positive for `C420` with attribute, subscript, or slice assignment targets ([#19513](https://github.com/astral-sh/ruff/pull/19513))
- \[`flake8-simplify`\] Fix handling of U+001C..U+001F whitespace (`SIM905`) ([#19849](https://github.com/astral-sh/ruff/pull/19849))
### Rule changes
- \[`pylint`\] Use lowercase hex characters to match the formatter (`PLE2513`) ([#19808](https://github.com/astral-sh/ruff/pull/19808))
### Documentation
- Fix `lint.future-annotations` link ([#19876](https://github.com/astral-sh/ruff/pull/19876))
### Other changes
- Build `riscv64` binaries for release ([#19819](https://github.com/astral-sh/ruff/pull/19819))
- Add rule code to error description in GitLab output ([#19896](https://github.com/astral-sh/ruff/pull/19896))
- Improve rendering of the `full` output format ([#19415](https://github.com/astral-sh/ruff/pull/19415))
Below is an example diff for [`F401`](https://docs.astral.sh/ruff/rules/unused-import/):
```diff
-unused.py:8:19: F401 [*] `pathlib` imported but unused
+F401 [*] `pathlib` imported but unused
+ --> unused.py:8:19
|
7 | # Unused, _not_ marked as required (due to the alias).
8 | import pathlib as non_alias
- | ^^^^^^^^^ F401
+ | ^^^^^^^^^
9 |
10 | # Unused, marked as required.
|
- = help: Remove unused import: `pathlib`
+help: Remove unused import: `pathlib`
```
For now, the primary difference is the movement of the filename, line number, and column information to a second line in the header. This new representation will allow us to make further additions to Ruff's diagnostics, such as adding sub-diagnostics and multiple annotations to the same snippet.
## 0.12.8
### Preview features

109
Cargo.lock generated
View File

@@ -128,9 +128,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.99"
version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100"
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
[[package]]
name = "approx"
@@ -257,9 +257,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.9.2"
version = "2.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a65b545ab31d687cff52899d4890855fec459eb6afe0da6417b8a18da87aa29"
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
[[package]]
name = "bitvec"
@@ -322,9 +322,9 @@ dependencies = [
[[package]]
name = "camino"
version = "1.1.11"
version = "1.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d07aa9a93b00c76f71bc35d598bed923f6d4f3a9ca5c24b7737ae1a292841c0"
checksum = "0da45bc31171d8d6960122e222a67740df867c1dd53b4d51caa297084c185cab"
dependencies = [
"serde",
]
@@ -408,9 +408,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.5.45"
version = "4.5.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fc0e74a703892159f5ae7d3aac52c8e6c392f5ae5f359c70b5881d60aaac318"
checksum = "50fd97c9dc2399518aa331917ac6f274280ec5eb34e555dd291899745c48ec6f"
dependencies = [
"clap_builder",
"clap_derive",
@@ -418,9 +418,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.5.44"
version = "4.5.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3e7f4214277f3c7aa526a59dd3fbe306a370daee1f8b7b8c987069cd8e888a8"
checksum = "c35b5830294e1fa0462034af85cc95225a4cb07092c088c55bda3147cfcd8f65"
dependencies = [
"anstream",
"anstyle",
@@ -461,9 +461,9 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "4.5.45"
version = "4.5.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6"
checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491"
dependencies = [
"heck",
"proc-macro2",
@@ -1178,7 +1178,7 @@ checksum = "5697765925a05c9d401dd04a93dfd662d336cc25fdcc3301220385a1ffcfdde5"
dependencies = [
"compact_str",
"get-size-derive2",
"hashbrown 0.15.5",
"hashbrown 0.15.4",
"smallvec",
]
@@ -1218,9 +1218,9 @@ dependencies = [
[[package]]
name = "glob"
version = "0.3.3"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
[[package]]
name = "globset"
@@ -1241,7 +1241,7 @@ version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757"
dependencies = [
"bitflags 2.9.2",
"bitflags 2.9.1",
"ignore",
"walkdir",
]
@@ -1264,9 +1264,9 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]]
name = "hashbrown"
version = "0.15.5"
version = "0.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
dependencies = [
"allocator-api2",
"equivalent",
@@ -1279,7 +1279,7 @@ version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1"
dependencies = [
"hashbrown 0.15.5",
"hashbrown 0.15.4",
]
[[package]]
@@ -1471,7 +1471,7 @@ version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17d34b7d42178945f775e84bc4c36dde7c1c6cdfea656d3354d009056f2bb3d2"
dependencies = [
"hashbrown 0.15.5",
"hashbrown 0.15.4",
]
[[package]]
@@ -1491,7 +1491,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661"
dependencies = [
"equivalent",
"hashbrown 0.15.5",
"hashbrown 0.15.4",
"serde",
]
@@ -1521,7 +1521,7 @@ version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3"
dependencies = [
"bitflags 2.9.2",
"bitflags 2.9.1",
"inotify-sys",
"libc",
]
@@ -1764,9 +1764,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.175"
version = "0.2.174"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
[[package]]
name = "libcst"
@@ -1809,7 +1809,7 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3"
dependencies = [
"bitflags 2.9.2",
"bitflags 2.9.1",
"libc",
"redox_syscall",
]
@@ -2014,7 +2014,7 @@ version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
dependencies = [
"bitflags 2.9.2",
"bitflags 2.9.1",
"cfg-if",
"cfg_aliases",
"libc",
@@ -2026,7 +2026,7 @@ version = "0.30.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
dependencies = [
"bitflags 2.9.2",
"bitflags 2.9.1",
"cfg-if",
"cfg_aliases",
"libc",
@@ -2054,7 +2054,7 @@ version = "8.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3"
dependencies = [
"bitflags 2.9.2",
"bitflags 2.9.1",
"fsevent-sys",
"inotify",
"kqueue",
@@ -2473,9 +2473,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.96"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "beef09f85ae72cea1ef96ba6870c51e6382ebfa4f0e85b643459331f3daa5be0"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [
"unicode-ident",
]
@@ -2666,7 +2666,7 @@ version = "0.5.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77"
dependencies = [
"bitflags 2.9.2",
"bitflags 2.9.1",
]
[[package]]
@@ -2743,13 +2743,13 @@ dependencies = [
[[package]]
name = "ruff"
version = "0.12.10"
version = "0.12.8"
dependencies = [
"anyhow",
"argfile",
"assert_fs",
"bincode 2.0.1",
"bitflags 2.9.2",
"bitflags 2.9.1",
"cachedir",
"clap",
"clap_complete_command",
@@ -2886,7 +2886,6 @@ dependencies = [
"schemars",
"serde",
"serde_json",
"similar",
"tempfile",
"thiserror 2.0.12",
"tracing",
@@ -2997,17 +2996,17 @@ dependencies = [
[[package]]
name = "ruff_linter"
version = "0.12.10"
version = "0.12.8"
dependencies = [
"aho-corasick",
"anyhow",
"bitflags 2.9.2",
"bitflags 2.9.1",
"clap",
"colored 3.0.0",
"fern",
"glob",
"globset",
"hashbrown 0.15.5",
"hashbrown 0.15.4",
"imperative",
"insta",
"is-macro",
@@ -3023,6 +3022,7 @@ dependencies = [
"pep440_rs",
"pyproject-toml",
"regex",
"ruff_annotate_snippets",
"ruff_cache",
"ruff_db",
"ruff_diagnostics",
@@ -3074,7 +3074,6 @@ name = "ruff_memory_usage"
version = "0.0.0"
dependencies = [
"get-size2",
"ordermap",
]
[[package]]
@@ -3107,7 +3106,7 @@ name = "ruff_python_ast"
version = "0.0.0"
dependencies = [
"aho-corasick",
"bitflags 2.9.2",
"bitflags 2.9.1",
"compact_str",
"get-size2",
"is-macro",
@@ -3195,7 +3194,7 @@ dependencies = [
name = "ruff_python_literal"
version = "0.0.0"
dependencies = [
"bitflags 2.9.2",
"bitflags 2.9.1",
"itertools 0.14.0",
"ruff_python_ast",
"unic-ucd-category",
@@ -3206,7 +3205,7 @@ name = "ruff_python_parser"
version = "0.0.0"
dependencies = [
"anyhow",
"bitflags 2.9.2",
"bitflags 2.9.1",
"bstr",
"compact_str",
"get-size2",
@@ -3231,7 +3230,7 @@ dependencies = [
name = "ruff_python_semantic"
version = "0.0.0"
dependencies = [
"bitflags 2.9.2",
"bitflags 2.9.1",
"insta",
"is-macro",
"ruff_cache",
@@ -3252,7 +3251,7 @@ dependencies = [
name = "ruff_python_stdlib"
version = "0.0.0"
dependencies = [
"bitflags 2.9.2",
"bitflags 2.9.1",
"unicode-ident",
]
@@ -3336,7 +3335,7 @@ dependencies = [
[[package]]
name = "ruff_wasm"
version = "0.12.10"
version = "0.12.8"
dependencies = [
"console_error_panic_hook",
"console_log",
@@ -3429,7 +3428,7 @@ version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8"
dependencies = [
"bitflags 2.9.2",
"bitflags 2.9.1",
"errno",
"libc",
"linux-raw-sys",
@@ -3451,13 +3450,13 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "salsa"
version = "0.23.0"
source = "git+https://github.com/salsa-rs/salsa.git?rev=a3ffa22cb26756473d56f867aedec3fd907c4dd9#a3ffa22cb26756473d56f867aedec3fd907c4dd9"
source = "git+https://github.com/salsa-rs/salsa.git?rev=b121ee46c4483ba74c19e933a3522bd548eb7343#b121ee46c4483ba74c19e933a3522bd548eb7343"
dependencies = [
"boxcar",
"compact_str",
"crossbeam-queue",
"crossbeam-utils",
"hashbrown 0.15.5",
"hashbrown 0.15.4",
"hashlink",
"indexmap",
"intrusive-collections",
@@ -3475,12 +3474,12 @@ dependencies = [
[[package]]
name = "salsa-macro-rules"
version = "0.23.0"
source = "git+https://github.com/salsa-rs/salsa.git?rev=a3ffa22cb26756473d56f867aedec3fd907c4dd9#a3ffa22cb26756473d56f867aedec3fd907c4dd9"
source = "git+https://github.com/salsa-rs/salsa.git?rev=b121ee46c4483ba74c19e933a3522bd548eb7343#b121ee46c4483ba74c19e933a3522bd548eb7343"
[[package]]
name = "salsa-macros"
version = "0.23.0"
source = "git+https://github.com/salsa-rs/salsa.git?rev=a3ffa22cb26756473d56f867aedec3fd907c4dd9#a3ffa22cb26756473d56f867aedec3fd907c4dd9"
source = "git+https://github.com/salsa-rs/salsa.git?rev=b121ee46c4483ba74c19e933a3522bd548eb7343#b121ee46c4483ba74c19e933a3522bd548eb7343"
dependencies = [
"proc-macro2",
"quote",
@@ -4239,7 +4238,7 @@ dependencies = [
name = "ty_ide"
version = "0.0.0"
dependencies = [
"bitflags 2.9.2",
"bitflags 2.9.1",
"insta",
"itertools 0.14.0",
"regex",
@@ -4298,7 +4297,7 @@ name = "ty_python_semantic"
version = "0.0.0"
dependencies = [
"anyhow",
"bitflags 2.9.2",
"bitflags 2.9.1",
"bitvec",
"camino",
"colored 3.0.0",
@@ -4307,7 +4306,7 @@ dependencies = [
"drop_bomb",
"get-size2",
"glob",
"hashbrown 0.15.5",
"hashbrown 0.15.4",
"indexmap",
"insta",
"itertools 0.14.0",
@@ -4351,7 +4350,7 @@ name = "ty_server"
version = "0.0.0"
dependencies = [
"anyhow",
"bitflags 2.9.2",
"bitflags 2.9.1",
"crossbeam",
"dunce",
"insta",
@@ -4394,7 +4393,7 @@ name = "ty_test"
version = "0.0.0"
dependencies = [
"anyhow",
"bitflags 2.9.2",
"bitflags 2.9.1",
"camino",
"colored 3.0.0",
"insta",
@@ -5144,7 +5143,7 @@ version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags 2.9.2",
"bitflags 2.9.1",
]
[[package]]

View File

@@ -5,7 +5,7 @@ resolver = "2"
[workspace.package]
# Please update rustfmt.toml when bumping the Rust edition
edition = "2024"
rust-version = "1.87"
rust-version = "1.86"
homepage = "https://docs.astral.sh/ruff"
documentation = "https://docs.astral.sh/ruff"
repository = "https://github.com/astral-sh/ruff"
@@ -143,7 +143,7 @@ regex-automata = { version = "0.4.9" }
rustc-hash = { version = "2.0.0" }
rustc-stable-hash = { version = "0.1.2" }
# When updating salsa, make sure to also update the revision in `fuzz/Cargo.toml`
salsa = { git = "https://github.com/salsa-rs/salsa.git", rev = "a3ffa22cb26756473d56f867aedec3fd907c4dd9", default-features = false, features = [
salsa = { git = "https://github.com/salsa-rs/salsa.git", rev = "b121ee46c4483ba74c19e933a3522bd548eb7343", default-features = false, features = [
"compact_str",
"macros",
"salsa_unstable",

View File

@@ -148,8 +148,8 @@ curl -LsSf https://astral.sh/ruff/install.sh | sh
powershell -c "irm https://astral.sh/ruff/install.ps1 | iex"
# For a specific version.
curl -LsSf https://astral.sh/ruff/0.12.10/install.sh | sh
powershell -c "irm https://astral.sh/ruff/0.12.10/install.ps1 | iex"
curl -LsSf https://astral.sh/ruff/0.12.8/install.sh | sh
powershell -c "irm https://astral.sh/ruff/0.12.8/install.ps1 | iex"
```
You can also install Ruff via [Homebrew](https://formulae.brew.sh/formula/ruff), [Conda](https://anaconda.org/conda-forge/ruff),
@@ -182,7 +182,7 @@ Ruff can also be used as a [pre-commit](https://pre-commit.com/) hook via [`ruff
```yaml
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.12.10
rev: v0.12.8
hooks:
# Run the linter.
- id: ruff-check

View File

@@ -1,6 +1,6 @@
[package]
name = "ruff"
version = "0.12.10"
version = "0.12.8"
publish = true
authors = { workspace = true }
edition = { workspace = true }
@@ -85,7 +85,7 @@ dist = true
[target.'cfg(target_os = "windows")'.dependencies]
mimalloc = { workspace = true }
[target.'cfg(all(not(target_os = "windows"), not(target_os = "openbsd"), not(target_os = "aix"), not(target_os = "android"), any(target_arch = "x86_64", target_arch = "aarch64", target_arch = "powerpc64", target_arch = "riscv64")))'.dependencies]
[target.'cfg(all(not(target_os = "windows"), not(target_os = "openbsd"), not(target_os = "aix"), not(target_os = "android"), any(target_arch = "x86_64", target_arch = "aarch64", target_arch = "powerpc64")))'.dependencies]
tikv-jemallocator = { workspace = true }
[lints]

View File

@@ -13,16 +13,25 @@ use itertools::Itertools;
use log::{debug, error};
use rayon::iter::ParallelIterator;
use rayon::iter::{IntoParallelIterator, ParallelBridge};
use ruff_linter::codes::Rule;
use rustc_hash::FxHashMap;
use tempfile::NamedTempFile;
use ruff_cache::{CacheKey, CacheKeyHasher};
use ruff_db::diagnostic::Diagnostic;
use ruff_diagnostics::Fix;
use ruff_linter::message::create_lint_diagnostic;
use ruff_linter::package::PackageRoot;
use ruff_linter::{VERSION, warn_user};
use ruff_macros::CacheKey;
use ruff_notebook::NotebookIndex;
use ruff_source_file::SourceFileBuilder;
use ruff_text_size::{TextRange, TextSize};
use ruff_workspace::Settings;
use ruff_workspace::resolver::Resolver;
use crate::diagnostics::Diagnostics;
/// [`Path`] that is relative to the package root in [`PackageCache`].
pub(crate) type RelativePath = Path;
/// [`PathBuf`] that is relative to the package root in [`PackageCache`].
@@ -289,8 +298,13 @@ impl Cache {
});
}
pub(crate) fn set_linted(&self, path: RelativePathBuf, key: &FileCacheKey, yes: bool) {
self.update(path, key, ChangeData::Linted(yes));
pub(crate) fn update_lint(
&self,
path: RelativePathBuf,
key: &FileCacheKey,
data: LintCacheData,
) {
self.update(path, key, ChangeData::Lint(data));
}
pub(crate) fn set_formatted(&self, path: RelativePathBuf, key: &FileCacheKey) {
@@ -325,15 +339,42 @@ pub(crate) struct FileCache {
}
impl FileCache {
/// Return whether or not the file in the cache was linted and found to have no diagnostics.
pub(crate) fn linted(&self) -> bool {
self.data.linted
/// Convert the file cache into `Diagnostics`, using `path` as file name.
pub(crate) fn to_diagnostics(&self, path: &Path) -> Option<Diagnostics> {
self.data.lint.as_ref().map(|lint| {
let diagnostics = if lint.messages.is_empty() {
Vec::new()
} else {
let file = SourceFileBuilder::new(path.to_string_lossy(), &*lint.source).finish();
lint.messages
.iter()
.map(|msg| {
create_lint_diagnostic(
&msg.body,
msg.suggestion.as_ref(),
msg.range,
msg.fix.clone(),
msg.parent,
file.clone(),
msg.noqa_offset,
msg.rule,
)
})
.collect()
};
let notebook_indexes = if let Some(notebook_index) = lint.notebook_index.as_ref() {
FxHashMap::from_iter([(path.to_string_lossy().to_string(), notebook_index.clone())])
} else {
FxHashMap::default()
};
Diagnostics::new(diagnostics, notebook_indexes)
})
}
}
#[derive(Debug, Default, bincode::Decode, bincode::Encode)]
struct FileCacheData {
linted: bool,
lint: Option<LintCacheData>,
formatted: bool,
}
@@ -369,6 +410,88 @@ pub(crate) fn init(path: &Path) -> Result<()> {
Ok(())
}
#[derive(bincode::Decode, Debug, bincode::Encode, PartialEq)]
pub(crate) struct LintCacheData {
/// Imports made.
// pub(super) imports: ImportMap,
/// Diagnostic messages.
pub(super) messages: Vec<CacheMessage>,
/// Source code of the file.
///
/// # Notes
///
/// This will be empty if `messages` is empty.
pub(super) source: String,
/// Notebook index if this file is a Jupyter Notebook.
#[bincode(with_serde)]
pub(super) notebook_index: Option<NotebookIndex>,
}
impl LintCacheData {
pub(crate) fn from_diagnostics(
diagnostics: &[Diagnostic],
notebook_index: Option<NotebookIndex>,
) -> Self {
let source = if let Some(msg) = diagnostics.first() {
msg.expect_ruff_source_file().source_text().to_owned()
} else {
String::new() // No messages, no need to keep the source!
};
let messages = diagnostics
.iter()
// Parse the kebab-case rule name into a `Rule`. This will fail for syntax errors, so
// this also serves to filter them out, but we shouldn't be caching files with syntax
// errors anyway.
.filter_map(|msg| Some((msg.name().parse().ok()?, msg)))
.map(|(rule, msg)| {
// Make sure that all message use the same source file.
assert_eq!(
msg.expect_ruff_source_file(),
diagnostics.first().unwrap().expect_ruff_source_file(),
"message uses a different source file"
);
CacheMessage {
rule,
body: msg.body().to_string(),
suggestion: msg.first_help_text().map(ToString::to_string),
range: msg.expect_range(),
parent: msg.parent(),
fix: msg.fix().cloned(),
noqa_offset: msg.noqa_offset(),
}
})
.collect();
Self {
messages,
source,
notebook_index,
}
}
}
/// On disk representation of a diagnostic message.
#[derive(bincode::Decode, Debug, bincode::Encode, PartialEq)]
pub(super) struct CacheMessage {
/// The rule for the cached diagnostic.
#[bincode(with_serde)]
rule: Rule,
/// The message body to display to the user, to explain the diagnostic.
body: String,
/// The message to display to the user, to explain the suggested fix.
suggestion: Option<String>,
/// Range into the message's [`FileCache::source`].
#[bincode(with_serde)]
range: TextRange,
#[bincode(with_serde)]
parent: Option<TextSize>,
#[bincode(with_serde)]
fix: Option<Fix>,
#[bincode(with_serde)]
noqa_offset: Option<TextSize>,
}
pub(crate) trait PackageCaches {
fn get(&self, package_root: &Path) -> Option<&Cache>;
@@ -456,15 +579,15 @@ struct Change {
#[derive(Debug)]
enum ChangeData {
Linted(bool),
Lint(LintCacheData),
Formatted,
}
impl ChangeData {
fn apply(self, data: &mut FileCacheData) {
match self {
ChangeData::Linted(yes) => {
data.linted = yes;
ChangeData::Lint(new_lint) => {
data.lint = Some(new_lint);
}
ChangeData::Formatted => {
data.formatted = true;
@@ -489,6 +612,7 @@ mod tests {
use test_case::test_case;
use ruff_cache::CACHE_DIR_NAME;
use ruff_db::diagnostic::Diagnostic;
use ruff_linter::package::PackageRoot;
use ruff_linter::settings::LinterSettings;
use ruff_linter::settings::flags;
@@ -496,7 +620,7 @@ mod tests {
use ruff_python_ast::{PySourceType, PythonVersion};
use ruff_workspace::Settings;
use crate::cache::{self, ChangeData, FileCache, FileCacheData, FileCacheKey};
use crate::cache::{self, FileCache, FileCacheData, FileCacheKey};
use crate::cache::{Cache, RelativePathBuf};
use crate::commands::format::{FormatCommandError, FormatMode, FormatResult, format_path};
use crate::diagnostics::{Diagnostics, lint_path};
@@ -523,7 +647,7 @@ mod tests {
assert_eq!(cache.changes.lock().unwrap().len(), 0);
let mut paths = Vec::new();
let mut paths_with_diagnostics = Vec::new();
let mut parse_errors = Vec::new();
let mut expected_diagnostics = Diagnostics::default();
for entry in fs::read_dir(&package_root).unwrap() {
let entry = entry.unwrap();
@@ -547,7 +671,7 @@ mod tests {
continue;
}
let mut diagnostics = lint_path(
let diagnostics = lint_path(
&path,
Some(PackageRoot::root(&package_root)),
&settings.linter,
@@ -557,15 +681,8 @@ mod tests {
UnsafeFixes::Enabled,
)
.unwrap();
if diagnostics.inner.is_empty() {
// We won't load a notebook index from the cache for files without diagnostics,
// so remove them from `expected_diagnostics` too. This allows us to keep the
// full equality assertion below.
diagnostics
.notebook_indexes
.remove(&path.to_string_lossy().to_string());
} else {
paths_with_diagnostics.push(path.clone());
if diagnostics.inner.iter().any(Diagnostic::is_invalid_syntax) {
parse_errors.push(path.clone());
}
paths.push(path);
expected_diagnostics += diagnostics;
@@ -578,11 +695,11 @@ mod tests {
let cache = Cache::open(package_root.clone(), &settings);
assert_ne!(cache.package.files.len(), 0);
paths_with_diagnostics.sort();
parse_errors.sort();
for path in &paths {
if paths_with_diagnostics.binary_search(path).is_ok() {
continue; // We don't cache files with diagnostics.
if parse_errors.binary_search(path).is_ok() {
continue; // We don't cache parsing errors.
}
let relative_path = cache.relative_path(path).unwrap();
@@ -616,7 +733,7 @@ mod tests {
#[test]
fn cache_adds_file_on_lint() {
let source: &[u8] = b"a = 1\n\n__all__ = list([\"a\"])\n";
let source: &[u8] = b"a = 1\n\n__all__ = list([\"a\", \"b\"])\n";
let test_cache = TestCache::new("cache_adds_file_on_lint");
let cache = test_cache.open();
@@ -640,7 +757,7 @@ mod tests {
#[test]
fn cache_adds_files_on_lint() {
let source: &[u8] = b"a = 1\n\n__all__ = list([\"a\"])\n";
let source: &[u8] = b"a = 1\n\n__all__ = list([\"a\", \"b\"])\n";
let test_cache = TestCache::new("cache_adds_files_on_lint");
let cache = test_cache.open();
@@ -665,40 +782,6 @@ mod tests {
cache.persist().unwrap();
}
#[test]
fn cache_does_not_add_file_on_lint_with_diagnostic() {
let source: &[u8] = b"a = 1\n\n__all__ = list([\"a\", \"b\"])\n";
let test_cache = TestCache::new("cache_does_not_add_file_on_lint_with_diagnostic");
let cache = test_cache.open();
test_cache.write_source_file("source.py", source);
assert_eq!(cache.changes.lock().unwrap().len(), 0);
cache.persist().unwrap();
let cache = test_cache.open();
let results = test_cache
.lint_file_with_cache("source.py", &cache)
.expect("Failed to lint test file");
assert_eq!(results.inner.len(), 1, "Expected one F822 diagnostic");
assert_eq!(
cache.changes.lock().unwrap().len(),
1,
"Files with diagnostics still trigger change events"
);
assert!(
cache
.changes
.lock()
.unwrap()
.last()
.is_some_and(|change| matches!(change.new_data, ChangeData::Linted(false))),
"Files with diagnostics are marked as unlinted"
);
cache.persist().unwrap();
}
#[test]
fn cache_adds_files_on_format() {
let source: &[u8] = b"a = 1\n\n__all__ = list([\"a\", \"b\"])\n";
@@ -729,7 +812,7 @@ mod tests {
#[test]
fn cache_invalidated_on_file_modified_time() {
let source: &[u8] = b"a = 1\n\n__all__ = list([\"a\"])\n";
let source: &[u8] = b"a = 1\n\n__all__ = list([\"a\", \"b\"])\n";
let test_cache = TestCache::new("cache_invalidated_on_file_modified_time");
let cache = test_cache.open();
@@ -786,7 +869,7 @@ mod tests {
file.set_permissions(perms)
}
let source: &[u8] = b"a = 1\n\n__all__ = list([\"a\"])\n";
let source: &[u8] = b"a = 1\n\n__all__ = list([\"a\", \"b\"])\n";
let test_cache = TestCache::new("cache_invalidated_on_permission_change");
let cache = test_cache.open();
@@ -839,7 +922,7 @@ mod tests {
);
// Now actually lint a file.
let source: &[u8] = b"a = 1\n\n__all__ = list([\"a\"])\n";
let source: &[u8] = b"a = 1\n\n__all__ = list([\"a\", \"b\"])\n";
test_cache.write_source_file("new.py", source);
let new_path_key = RelativePathBuf::from("new.py");
assert_eq!(cache.changes.lock().unwrap().len(), 0);
@@ -862,7 +945,7 @@ mod tests {
#[test]
fn format_updates_cache_entry() {
let source: &[u8] = b"a = 1\n\n__all__ = list([\"a\"])\n";
let source: &[u8] = b"a = 1\n\n__all__ = list([\"a\", \"b\"])\n";
let test_cache = TestCache::new("format_updates_cache_entry");
let cache = test_cache.open();
@@ -896,7 +979,7 @@ mod tests {
panic!("Cache entry for `source.py` is missing.");
};
assert!(file_cache.data.linted);
assert!(file_cache.data.lint.is_some());
assert!(file_cache.data.formatted);
}
@@ -946,7 +1029,7 @@ mod tests {
panic!("Cache entry for `source.py` is missing.");
};
assert!(!file_cache.data.linted);
assert_eq!(file_cache.data.lint, None);
assert!(file_cache.data.formatted);
}

View File

@@ -20,21 +20,15 @@ use ruff_linter::settings::types::UnsafeFixes;
use ruff_linter::settings::{LinterSettings, flags};
use ruff_linter::source_kind::{SourceError, SourceKind};
use ruff_linter::{IOError, Violation, fs};
use ruff_notebook::{NotebookError, NotebookIndex};
use ruff_notebook::{Notebook, NotebookError, NotebookIndex};
use ruff_python_ast::{PySourceType, SourceType, TomlSourceType};
use ruff_source_file::SourceFileBuilder;
use ruff_text_size::TextRange;
use ruff_workspace::Settings;
use rustc_hash::FxHashMap;
use crate::cache::{Cache, FileCache, FileCacheKey};
use crate::cache::{Cache, FileCacheKey, LintCacheData};
/// A collection of [`Diagnostic`]s and additional information needed to render them.
///
/// Note that `notebook_indexes` may be empty if there are no diagnostics because the
/// `NotebookIndex` isn't cached in this case. This isn't a problem for any current uses as of
/// 2025-08-12, which are all related to diagnostic rendering, but could be surprising if used
/// differently in the future.
#[derive(Debug, Default, PartialEq)]
pub(crate) struct Diagnostics {
pub(crate) inner: Vec<Diagnostic>,
@@ -199,9 +193,19 @@ pub(crate) fn lint_path(
let cache_key = FileCacheKey::from_path(path).context("Failed to create cache key")?;
let cached_diagnostics = cache
.get(relative_path, &cache_key)
.is_some_and(FileCache::linted);
if cached_diagnostics {
return Ok(Diagnostics::default());
.and_then(|entry| entry.to_diagnostics(path));
if let Some(diagnostics) = cached_diagnostics {
// `FixMode::Generate` and `FixMode::Diff` rely on side-effects (writing to disk,
// and writing the diff to stdout, respectively). If a file has diagnostics, we
// need to avoid reading from and writing to the cache in these modes.
if match fix_mode {
flags::FixMode::Generate => true,
flags::FixMode::Apply | flags::FixMode::Diff => {
diagnostics.inner.is_empty() && diagnostics.fixed.is_empty()
}
} {
return Ok(diagnostics);
}
}
// Stash the file metadata for later so when we update the cache it reflects the prerun
@@ -318,21 +322,31 @@ pub(crate) fn lint_path(
(result, transformed, fixed)
};
let has_error = result.has_syntax_errors();
let diagnostics = result.diagnostics;
if let Some((cache, relative_path, key)) = caching {
// `FixMode::Apply` and `FixMode::Diff` rely on side-effects (writing to disk,
// and writing the diff to stdout, respectively). If a file has diagnostics
// with fixes, we need to avoid reading from and writing to the cache in these
// modes.
let use_fixes = match fix_mode {
flags::FixMode::Generate => true,
flags::FixMode::Apply | flags::FixMode::Diff => fixed.is_empty(),
};
// We don't cache files with diagnostics.
let linted = diagnostics.is_empty() && use_fixes;
cache.set_linted(relative_path.to_owned(), &key, linted);
// We don't cache parsing errors.
if !has_error {
// `FixMode::Apply` and `FixMode::Diff` rely on side-effects (writing to disk,
// and writing the diff to stdout, respectively). If a file has diagnostics, we
// need to avoid reading from and writing to the cache in these modes.
if match fix_mode {
flags::FixMode::Generate => true,
flags::FixMode::Apply | flags::FixMode::Diff => {
diagnostics.is_empty() && fixed.is_empty()
}
} {
cache.update_lint(
relative_path.to_owned(),
&key,
LintCacheData::from_diagnostics(
&diagnostics,
transformed.as_ipy_notebook().map(Notebook::index).cloned(),
),
);
}
}
}
let notebook_indexes = if let SourceKind::IpyNotebook(notebook) = transformed {

View File

@@ -19,8 +19,7 @@ static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
any(
target_arch = "x86_64",
target_arch = "aarch64",
target_arch = "powerpc64",
target_arch = "riscv64"
target_arch = "powerpc64"
)
))]
#[global_allocator]

View File

@@ -115,13 +115,12 @@ fn stdin_error() {
success: false
exit_code: 1
----- stdout -----
F401 [*] `os` imported but unused
--> -:1:8
-:1:8: F401 [*] `os` imported but unused
|
1 | import os
| ^^
| ^^ F401
|
help: Remove unused import: `os`
= help: Remove unused import: `os`
Found 1 error.
[*] 1 fixable with the `--fix` option.
@@ -140,13 +139,12 @@ fn stdin_filename() {
success: false
exit_code: 1
----- stdout -----
F401 [*] `os` imported but unused
--> F401.py:1:8
F401.py:1:8: F401 [*] `os` imported but unused
|
1 | import os
| ^^
| ^^ F401
|
help: Remove unused import: `os`
= help: Remove unused import: `os`
Found 1 error.
[*] 1 fixable with the `--fix` option.
@@ -176,21 +174,19 @@ import bar # unused import
success: false
exit_code: 1
----- stdout -----
F401 [*] `bar` imported but unused
--> bar.py:2:8
bar.py:2:8: F401 [*] `bar` imported but unused
|
2 | import bar # unused import
| ^^^
| ^^^ F401
|
help: Remove unused import: `bar`
= help: Remove unused import: `bar`
F401 [*] `foo` imported but unused
--> foo.py:2:8
foo.py:2:8: F401 [*] `foo` imported but unused
|
2 | import foo # unused import
| ^^^
| ^^^ F401
|
help: Remove unused import: `foo`
= help: Remove unused import: `foo`
Found 2 errors.
[*] 2 fixable with the `--fix` option.
@@ -212,13 +208,12 @@ fn check_warn_stdin_filename_with_files() {
success: false
exit_code: 1
----- stdout -----
F401 [*] `os` imported but unused
--> F401.py:1:8
F401.py:1:8: F401 [*] `os` imported but unused
|
1 | import os
| ^^
| ^^ F401
|
help: Remove unused import: `os`
= help: Remove unused import: `os`
Found 1 error.
[*] 1 fixable with the `--fix` option.
@@ -239,13 +234,12 @@ fn stdin_source_type_py() {
success: false
exit_code: 1
----- stdout -----
F401 [*] `os` imported but unused
--> TCH.py:1:8
TCH.py:1:8: F401 [*] `os` imported but unused
|
1 | import os
| ^^
| ^^ F401
|
help: Remove unused import: `os`
= help: Remove unused import: `os`
Found 1 error.
[*] 1 fixable with the `--fix` option.
@@ -477,11 +471,10 @@ fn stdin_fix_jupyter() {
"nbformat_minor": 5
}
----- stderr -----
F821 Undefined name `x`
--> Jupyter.ipynb:cell 3:1:7
Jupyter.ipynb:cell 3:1:7: F821 Undefined name `x`
|
1 | print(x)
| ^
| ^ F821
|
Found 3 errors (2 fixed, 1 remaining).
@@ -576,21 +569,19 @@ fn stdin_override_parser_ipynb() {
success: false
exit_code: 1
----- stdout -----
F401 [*] `os` imported but unused
--> Jupyter.py:cell 1:1:8
Jupyter.py:cell 1:1:8: F401 [*] `os` imported but unused
|
1 | import os
| ^^
| ^^ F401
|
help: Remove unused import: `os`
= help: Remove unused import: `os`
F401 [*] `sys` imported but unused
--> Jupyter.py:cell 3:1:8
Jupyter.py:cell 3:1:8: F401 [*] `sys` imported but unused
|
1 | import sys
| ^^^
| ^^^ F401
|
help: Remove unused import: `sys`
= help: Remove unused import: `sys`
Found 2 errors.
[*] 2 fixable with the `--fix` option.
@@ -614,13 +605,12 @@ fn stdin_override_parser_py() {
success: false
exit_code: 1
----- stdout -----
F401 [*] `os` imported but unused
--> F401.ipynb:1:8
F401.ipynb:1:8: F401 [*] `os` imported but unused
|
1 | import os
| ^^
| ^^ F401
|
help: Remove unused import: `os`
= help: Remove unused import: `os`
Found 1 error.
[*] 1 fixable with the `--fix` option.
@@ -643,13 +633,12 @@ fn stdin_fix_when_not_fixable_should_still_print_contents() {
print(sys.version)
----- stderr -----
F634 If test is a tuple, which is always `True`
--> -:3:4
-:3:4: F634 If test is a tuple, which is always `True`
|
1 | import sys
2 |
3 | if (1, 2):
| ^^^^^^
| ^^^^^^ F634
4 | print(sys.version)
|
@@ -809,8 +798,7 @@ fn stdin_parse_error() {
success: false
exit_code: 1
----- stdout -----
invalid-syntax: Expected one or more symbol names after import
--> -:1:16
-:1:16: invalid-syntax: Expected one or more symbol names after import
|
1 | from foo import
| ^
@@ -830,16 +818,14 @@ fn stdin_multiple_parse_error() {
success: false
exit_code: 1
----- stdout -----
invalid-syntax: Expected one or more symbol names after import
--> -:1:16
-:1:16: invalid-syntax: Expected one or more symbol names after import
|
1 | from foo import
| ^
2 | bar =
|
invalid-syntax: Expected an expression
--> -:2:6
-:2:6: invalid-syntax: Expected an expression
|
1 | from foo import
2 | bar =
@@ -861,8 +847,7 @@ fn parse_error_not_included() {
success: false
exit_code: 1
----- stdout -----
invalid-syntax: Expected an expression
--> -:1:6
-:1:6: invalid-syntax: Expected an expression
|
1 | foo =
| ^
@@ -882,11 +867,10 @@ fn full_output_preview() {
success: false
exit_code: 1
----- stdout -----
E741 Ambiguous variable name: `l`
--> -:1:1
-:1:1: E741 Ambiguous variable name: `l`
|
1 | l = 1
| ^
| ^ E741
|
Found 1 error.
@@ -911,11 +895,10 @@ preview = true
success: false
exit_code: 1
----- stdout -----
E741 Ambiguous variable name: `l`
--> -:1:1
-:1:1: E741 Ambiguous variable name: `l`
|
1 | l = 1
| ^
| ^ E741
|
Found 1 error.
@@ -933,11 +916,10 @@ fn full_output_format() {
success: false
exit_code: 1
----- stdout -----
E741 Ambiguous variable name: `l`
--> -:1:1
-:1:1: E741 Ambiguous variable name: `l`
|
1 | l = 1
| ^
| ^ E741
|
Found 1 error.
@@ -1424,9 +1406,7 @@ fn redirect_direct() {
success: false
exit_code: 1
----- stdout -----
RUF950 Hey this is a test rule that was redirected from another.
--> -:1:1
-:1:1: RUF950 Hey this is a test rule that was redirected from another.
Found 1 error.
----- stderr -----
@@ -1458,9 +1438,7 @@ fn redirect_prefix() {
success: false
exit_code: 1
----- stdout -----
RUF950 Hey this is a test rule that was redirected from another.
--> -:1:1
-:1:1: RUF950 Hey this is a test rule that was redirected from another.
Found 1 error.
----- stderr -----
@@ -1477,9 +1455,7 @@ fn deprecated_direct() {
success: false
exit_code: 1
----- stdout -----
RUF920 Hey this is a deprecated test rule.
--> -:1:1
-:1:1: RUF920 Hey this is a deprecated test rule.
Found 1 error.
----- stderr -----
@@ -1496,12 +1472,8 @@ fn deprecated_multiple_direct() {
success: false
exit_code: 1
----- stdout -----
RUF920 Hey this is a deprecated test rule.
--> -:1:1
RUF921 Hey this is another deprecated test rule.
--> -:1:1
-:1:1: RUF920 Hey this is a deprecated test rule.
-:1:1: RUF921 Hey this is another deprecated test rule.
Found 2 errors.
----- stderr -----
@@ -1519,12 +1491,8 @@ fn deprecated_indirect() {
success: false
exit_code: 1
----- stdout -----
RUF920 Hey this is a deprecated test rule.
--> -:1:1
RUF921 Hey this is another deprecated test rule.
--> -:1:1
-:1:1: RUF920 Hey this is a deprecated test rule.
-:1:1: RUF921 Hey this is another deprecated test rule.
Found 2 errors.
----- stderr -----
@@ -1670,23 +1638,22 @@ fn check_input_from_argfile() -> Result<()> {
(file_a_path.display().to_string().as_str(), "/path/to/a.py"),
]}, {
assert_cmd_snapshot!(cmd
.pass_stdin(""), @r"
.pass_stdin(""), @r###"
success: false
exit_code: 1
----- stdout -----
F401 [*] `os` imported but unused
--> /path/to/a.py:1:8
/path/to/a.py:1:8: F401 [*] `os` imported but unused
|
1 | import os
| ^^
| ^^ F401
|
help: Remove unused import: `os`
= help: Remove unused import: `os`
Found 1 error.
[*] 1 fixable with the `--fix` option.
----- stderr -----
");
"###);
});
Ok(())
@@ -1702,12 +1669,8 @@ fn check_hints_hidden_unsafe_fixes() {
success: false
exit_code: 1
----- stdout -----
RUF901 [*] Hey this is a stable test rule with a safe fix.
--> -:1:1
RUF902 Hey this is a stable test rule with an unsafe fix.
--> -:1:1
-:1:1: RUF901 [*] Hey this is a stable test rule with a safe fix.
-:1:1: RUF902 Hey this is a stable test rule with an unsafe fix.
Found 2 errors.
[*] 1 fixable with the `--fix` option (1 hidden fix can be enabled with the `--unsafe-fixes` option).
@@ -1724,9 +1687,7 @@ fn check_hints_hidden_unsafe_fixes_with_no_safe_fixes() {
success: false
exit_code: 1
----- stdout -----
RUF902 Hey this is a stable test rule with an unsafe fix.
--> -:1:1
-:1:1: RUF902 Hey this is a stable test rule with an unsafe fix.
Found 1 error.
No fixes available (1 hidden fix can be enabled with the `--unsafe-fixes` option).
@@ -1744,12 +1705,8 @@ fn check_no_hint_for_hidden_unsafe_fixes_when_disabled() {
success: false
exit_code: 1
----- stdout -----
RUF901 [*] Hey this is a stable test rule with a safe fix.
--> -:1:1
RUF902 Hey this is a stable test rule with an unsafe fix.
--> -:1:1
-:1:1: RUF901 [*] Hey this is a stable test rule with a safe fix.
-:1:1: RUF902 Hey this is a stable test rule with an unsafe fix.
Found 2 errors.
[*] 1 fixable with the --fix option.
@@ -1768,9 +1725,7 @@ fn check_no_hint_for_hidden_unsafe_fixes_with_no_safe_fixes_when_disabled() {
success: false
exit_code: 1
----- stdout -----
RUF902 Hey this is a stable test rule with an unsafe fix.
--> -:1:1
-:1:1: RUF902 Hey this is a stable test rule with an unsafe fix.
Found 1 error.
----- stderr -----
@@ -1787,12 +1742,8 @@ fn check_shows_unsafe_fixes_with_opt_in() {
success: false
exit_code: 1
----- stdout -----
RUF901 [*] Hey this is a stable test rule with a safe fix.
--> -:1:1
RUF902 [*] Hey this is a stable test rule with an unsafe fix.
--> -:1:1
-:1:1: RUF901 [*] Hey this is a stable test rule with a safe fix.
-:1:1: RUF902 [*] Hey this is a stable test rule with an unsafe fix.
Found 2 errors.
[*] 2 fixable with the --fix option.
@@ -1813,9 +1764,7 @@ fn fix_applies_safe_fixes_by_default() {
# fix from stable-test-rule-safe-fix
----- stderr -----
RUF902 Hey this is a stable test rule with an unsafe fix.
--> -:1:1
-:1:1: RUF902 Hey this is a stable test rule with an unsafe fix.
Found 2 errors (1 fixed, 1 remaining).
No fixes available (1 hidden fix can be enabled with the `--unsafe-fixes` option).
");
@@ -1852,9 +1801,7 @@ fn fix_does_not_apply_display_only_fixes() {
----- stdout -----
def add_to_list(item, some_list=[]): ...
----- stderr -----
RUF903 Hey this is a stable test rule with a display only fix.
--> -:1:1
-:1:1: RUF903 Hey this is a stable test rule with a display only fix.
Found 1 error.
");
}
@@ -1872,9 +1819,7 @@ fn fix_does_not_apply_display_only_fixes_with_unsafe_fixes_enabled() {
----- stdout -----
def add_to_list(item, some_list=[]): ...
----- stderr -----
RUF903 Hey this is a stable test rule with a display only fix.
--> -:1:1
-:1:1: RUF903 Hey this is a stable test rule with a display only fix.
Found 1 error.
");
}
@@ -1891,9 +1836,7 @@ fn fix_only_unsafe_fixes_available() {
----- stdout -----
----- stderr -----
RUF902 Hey this is a stable test rule with an unsafe fix.
--> -:1:1
-:1:1: RUF902 Hey this is a stable test rule with an unsafe fix.
Found 1 error.
No fixes available (1 hidden fix can be enabled with the `--unsafe-fixes` option).
");
@@ -2029,12 +1972,8 @@ extend-unsafe-fixes = ["RUF901"]
success: false
exit_code: 1
----- stdout -----
RUF901 Hey this is a stable test rule with a safe fix.
--> -:1:1
RUF902 Hey this is a stable test rule with an unsafe fix.
--> -:1:1
-:1:1: RUF901 Hey this is a stable test rule with a safe fix.
-:1:1: RUF902 Hey this is a stable test rule with an unsafe fix.
Found 2 errors.
No fixes available (2 hidden fixes can be enabled with the `--unsafe-fixes` option).
@@ -2065,12 +2004,8 @@ extend-safe-fixes = ["RUF902"]
success: false
exit_code: 1
----- stdout -----
RUF901 [*] Hey this is a stable test rule with a safe fix.
--> -:1:1
RUF902 [*] Hey this is a stable test rule with an unsafe fix.
--> -:1:1
-:1:1: RUF901 [*] Hey this is a stable test rule with a safe fix.
-:1:1: RUF902 [*] Hey this is a stable test rule with an unsafe fix.
Found 2 errors.
[*] 2 fixable with the `--fix` option.
@@ -2103,12 +2038,8 @@ extend-safe-fixes = ["RUF902"]
success: false
exit_code: 1
----- stdout -----
RUF901 [*] Hey this is a stable test rule with a safe fix.
--> -:1:1
RUF902 Hey this is a stable test rule with an unsafe fix.
--> -:1:1
-:1:1: RUF901 [*] Hey this is a stable test rule with a safe fix.
-:1:1: RUF902 Hey this is a stable test rule with an unsafe fix.
Found 2 errors.
[*] 1 fixable with the `--fix` option (1 hidden fix can be enabled with the `--unsafe-fixes` option).
@@ -2143,27 +2074,13 @@ extend-safe-fixes = ["RUF9"]
success: false
exit_code: 1
----- stdout -----
RUF900 Hey this is a stable test rule.
--> -:1:1
RUF901 Hey this is a stable test rule with a safe fix.
--> -:1:1
RUF902 [*] Hey this is a stable test rule with an unsafe fix.
--> -:1:1
RUF903 Hey this is a stable test rule with a display only fix.
--> -:1:1
RUF920 Hey this is a deprecated test rule.
--> -:1:1
RUF921 Hey this is another deprecated test rule.
--> -:1:1
RUF950 Hey this is a test rule that was redirected from another.
--> -:1:1
-:1:1: RUF900 Hey this is a stable test rule.
-:1:1: RUF901 Hey this is a stable test rule with a safe fix.
-:1:1: RUF902 [*] Hey this is a stable test rule with an unsafe fix.
-:1:1: RUF903 Hey this is a stable test rule with a display only fix.
-:1:1: RUF920 Hey this is a deprecated test rule.
-:1:1: RUF921 Hey this is another deprecated test rule.
-:1:1: RUF950 Hey this is a test rule that was redirected from another.
Found 7 errors.
[*] 1 fixable with the `--fix` option (1 hidden fix can be enabled with the `--unsafe-fixes` option).
@@ -2224,11 +2141,10 @@ def log(x, base) -> float:
success: false
exit_code: 1
----- stdout -----
D417 Missing argument description in the docstring for `log`: `base`
--> -:2:5
-:2:5: D417 Missing argument description in the docstring for `log`: `base`
|
2 | def log(x, base) -> float:
| ^^^
| ^^^ D417
3 | """Calculate natural log of a value
|
@@ -2261,15 +2177,14 @@ select = ["RUF017"]
success: false
exit_code: 1
----- stdout -----
RUF017 Avoid quadratic list summation
--> -:3:1
-:3:1: RUF017 Avoid quadratic list summation
|
1 | x = [1, 2, 3]
2 | y = [4, 5, 6]
3 | sum([x, y], [])
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^ RUF017
|
help: Replace with `functools.reduce`
= help: Replace with `functools.reduce`
Found 1 error.
No fixes available (1 hidden fix can be enabled with the `--unsafe-fixes` option).
@@ -2302,15 +2217,14 @@ unfixable = ["RUF"]
success: false
exit_code: 1
----- stdout -----
RUF017 Avoid quadratic list summation
--> -:3:1
-:3:1: RUF017 Avoid quadratic list summation
|
1 | x = [1, 2, 3]
2 | y = [4, 5, 6]
3 | sum([x, y], [])
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^ RUF017
|
help: Replace with `functools.reduce`
= help: Replace with `functools.reduce`
Found 1 error.
@@ -2332,11 +2246,10 @@ fn pyproject_toml_stdin_syntax_error() {
success: false
exit_code: 1
----- stdout -----
RUF200 Failed to parse pyproject.toml: unclosed table, expected `]`
--> pyproject.toml:1:9
pyproject.toml:1:9: RUF200 Failed to parse pyproject.toml: unclosed table, expected `]`
|
1 | [project
| ^
| ^ RUF200
|
Found 1 error.
@@ -2358,12 +2271,11 @@ fn pyproject_toml_stdin_schema_error() {
success: false
exit_code: 1
----- stdout -----
RUF200 Failed to parse pyproject.toml: invalid type: integer `1`, expected a string
--> pyproject.toml:2:8
pyproject.toml:2:8: RUF200 Failed to parse pyproject.toml: invalid type: integer `1`, expected a string
|
1 | [project]
2 | name = 1
| ^
| ^ RUF200
|
Found 1 error.
@@ -2451,12 +2363,11 @@ fn pyproject_toml_stdin_schema_error_fix() {
[project]
name = 1
----- stderr -----
RUF200 Failed to parse pyproject.toml: invalid type: integer `1`, expected a string
--> pyproject.toml:2:8
pyproject.toml:2:8: RUF200 Failed to parse pyproject.toml: invalid type: integer `1`, expected a string
|
1 | [project]
2 | name = 1
| ^
| ^ RUF200
|
Found 1 error.

View File

@@ -5588,15 +5588,15 @@ fn cookiecutter_globbing() -> Result<()> {
.args(STDIN_BASE_OPTIONS)
.arg("--select=F811")
.current_dir(tempdir.path()), @r"
success: false
exit_code: 1
----- stdout -----
{{cookiecutter.repo_name}}/tests/maintest.py:3:8: F811 [*] Redefinition of unused `foo` from line 1: `foo` redefined here
Found 1 error.
[*] 1 fixable with the `--fix` option.
success: false
exit_code: 1
----- stdout -----
{{cookiecutter.repo_name}}/tests/maintest.py:3:8: F811 [*] Redefinition of unused `foo` from line 1
Found 1 error.
[*] 1 fixable with the `--fix` option.
----- stderr -----
");
----- stderr -----
");
});
Ok(())
@@ -5801,32 +5801,3 @@ fn future_annotations_preview_warning() {
",
);
}
#[test]
fn up045_nested_optional_flatten_all() {
let contents = "\
from typing import Optional
nested_optional: Optional[Optional[Optional[str]]] = None
";
assert_cmd_snapshot!(
Command::new(get_cargo_bin(BIN_NAME))
.args(STDIN_BASE_OPTIONS)
.args(["--select", "UP045", "--diff", "--target-version", "py312"])
.arg("-")
.pass_stdin(contents),
@r"
success: false
exit_code: 1
----- stdout -----
@@ -1,2 +1,2 @@
from typing import Optional
-nested_optional: Optional[Optional[Optional[str]]] = None
+nested_optional: str | None = None
----- stderr -----
Would fix 1 error.
",
);
}

View File

@@ -16,28 +16,25 @@ info:
success: false
exit_code: 1
----- stdout -----
F401 [*] `os` imported but unused
--> input.py:1:8
input.py:1:8: F401 [*] `os` imported but unused
|
1 | import os # F401
| ^^
| ^^ F401
2 | x = y # F821
3 | match 42: # invalid-syntax
|
help: Remove unused import: `os`
= help: Remove unused import: `os`
F821 Undefined name `y`
--> input.py:2:5
input.py:2:5: F821 Undefined name `y`
|
1 | import os # F401
2 | x = y # F821
| ^
| ^ F821
3 | match 42: # invalid-syntax
4 | case _: ...
|
invalid-syntax: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10)
--> input.py:3:1
input.py:3:1: invalid-syntax: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10)
|
1 | import os # F401
2 | x = y # F821

View File

@@ -19,7 +19,7 @@ exit_code: 1
[
{
"check_name": "F401",
"description": "F401: `os` imported but unused",
"description": "`os` imported but unused",
"fingerprint": "4dbad37161e65c72",
"location": {
"path": "input.py",
@@ -38,7 +38,7 @@ exit_code: 1
},
{
"check_name": "F821",
"description": "F821: Undefined name `y`",
"description": "Undefined name `y`",
"fingerprint": "7af59862a085230",
"location": {
"path": "input.py",
@@ -56,8 +56,8 @@ exit_code: 1
"severity": "major"
},
{
"check_name": "invalid-syntax",
"description": "invalid-syntax: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10)",
"check_name": "syntax-error",
"description": "Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10)",
"fingerprint": "e558cec859bb66e8",
"location": {
"path": "input.py",

View File

@@ -1201,16 +1201,11 @@ fn format_snippet<'m>(
let is_file_level = snippet.annotations.iter().any(|ann| ann.is_file_level);
if is_file_level {
// TODO(brent) enable this assertion again once we set `is_file_level` for individual rules.
// It's causing too many false positives currently when the default is to make any
// annotation with a default range file-level. See
// https://github.com/astral-sh/ruff/issues/19688.
//
// assert!(
// snippet.source.is_empty(),
// "Non-empty file-level snippet that won't be rendered: {:?}",
// snippet.source
// );
assert!(
snippet.source.is_empty(),
"Non-empty file-level snippet that won't be rendered: {:?}",
snippet.source
);
let header = format_header(origin, main_range, &[], is_first, snippet.cell_index);
return DisplaySet {
display_lines: header.map_or_else(Vec::new, |header| vec![header]),
@@ -1278,20 +1273,13 @@ fn format_header<'a>(
..
} = item
{
// At the very end of the `main_range`, report the location as the first character
// in the next line instead of falling back to the default location of `1:1`. This
// is another divergence from upstream.
let end_of_range = range.1 + max(*end_line as usize, 1);
if main_range >= range.0 && main_range < end_of_range {
if main_range >= range.0 && main_range < range.1 + max(*end_line as usize, 1) {
let char_column = text[0..(main_range - range.0).min(text.len())]
.chars()
.count();
col = char_column + 1;
line_offset = lineno.unwrap_or(1);
break;
} else if main_range == end_of_range {
line_offset = lineno.map_or(1, |line| line + 1);
break;
}
}
}

View File

@@ -86,5 +86,5 @@ walltime = ["ruff_db/os", "ty_project", "divan"]
[target.'cfg(target_os = "windows")'.dev-dependencies]
mimalloc = { workspace = true }
[target.'cfg(all(not(target_os = "windows"), not(target_os = "openbsd"), any(target_arch = "x86_64", target_arch = "aarch64", target_arch = "powerpc64", target_arch = "riscv64")))'.dev-dependencies]
[target.'cfg(all(not(target_os = "windows"), not(target_os = "openbsd"), any(target_arch = "x86_64", target_arch = "aarch64", target_arch = "powerpc64")))'.dev-dependencies]
tikv-jemallocator = { workspace = true }

View File

@@ -21,8 +21,7 @@ static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
any(
target_arch = "x86_64",
target_arch = "aarch64",
target_arch = "powerpc64",
target_arch = "riscv64"
target_arch = "powerpc64"
)
))]
#[global_allocator]

View File

@@ -18,8 +18,7 @@ static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
any(
target_arch = "x86_64",
target_arch = "aarch64",
target_arch = "powerpc64",
target_arch = "riscv64"
target_arch = "powerpc64"
)
))]
#[global_allocator]

View File

@@ -26,8 +26,7 @@ static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
any(
target_arch = "x86_64",
target_arch = "aarch64",
target_arch = "powerpc64",
target_arch = "riscv64"
target_arch = "powerpc64"
)
))]
#[global_allocator]
@@ -43,8 +42,7 @@ static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
any(
target_arch = "x86_64",
target_arch = "aarch64",
target_arch = "powerpc64",
target_arch = "riscv64"
target_arch = "powerpc64"
)
))]
#[unsafe(export_name = "_rjem_malloc_conf")]
@@ -79,11 +77,8 @@ fn benchmark_linter(mut group: BenchmarkGroup, settings: &LinterSettings) {
b.iter_batched(
|| parsed.clone(),
|parsed| {
// Assert that file contains no parse errors
assert!(parsed.has_valid_syntax());
let path = case.path();
lint_only(
let result = lint_only(
&path,
None,
settings,
@@ -91,7 +86,10 @@ fn benchmark_linter(mut group: BenchmarkGroup, settings: &LinterSettings) {
&SourceKind::Python(case.code().to_string()),
PySourceType::from(path.as_path()),
ParseSource::Precomputed(parsed),
)
);
// Assert that file contains no parse errors
assert!(!result.has_syntax_errors());
},
criterion::BatchSize::SmallInput,
);

View File

@@ -20,8 +20,7 @@ static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
any(
target_arch = "x86_64",
target_arch = "aarch64",
target_arch = "powerpc64",
target_arch = "riscv64"
target_arch = "powerpc64"
)
))]
#[global_allocator]

View File

@@ -218,24 +218,6 @@ static TANJUN: std::sync::LazyLock<Benchmark<'static>> = std::sync::LazyLock::ne
)
});
static STATIC_FRAME: std::sync::LazyLock<Benchmark<'static>> = std::sync::LazyLock::new(|| {
Benchmark::new(
RealWorldProject {
name: "static-frame",
repository: "https://github.com/static-frame/static-frame",
commit: "34962b41baca5e7f98f5a758d530bff02748a421",
paths: vec![SystemPath::new("static_frame")],
// N.B. `arraykit` is installed as a dependency during mypy_primer runs,
// but it takes much longer to be installed in a Codspeed run than it does in a mypy_primer run
// (seems to be built from source on the Codspeed CI runners for some reason).
dependencies: vec!["numpy"],
max_dep_date: "2025-08-09",
python_version: PythonVersion::PY311,
},
500,
)
});
#[track_caller]
fn run_single_threaded(bencher: Bencher, benchmark: &Benchmark) {
bencher
@@ -250,7 +232,7 @@ fn small(bencher: Bencher, benchmark: &Benchmark) {
run_single_threaded(bencher, benchmark);
}
#[bench(args=[&*COLOUR_SCIENCE, &*PANDAS, &*STATIC_FRAME], sample_size=1, sample_count=3)]
#[bench(args=[&*COLOUR_SCIENCE, &*PANDAS], sample_size=1, sample_count=3)]
fn medium(bencher: Bencher, benchmark: &Benchmark) {
run_single_threaded(bencher, benchmark);
}

View File

@@ -40,7 +40,6 @@ salsa = { workspace = true }
schemars = { workspace = true, optional = true }
serde = { workspace = true, optional = true }
serde_json = { workspace = true, optional = true }
similar = { workspace = true }
thiserror = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true, optional = true }

View File

@@ -254,11 +254,6 @@ impl Diagnostic {
.find(|ann| ann.is_primary)
}
/// Returns a mutable borrow of all annotations of this diagnostic.
pub fn annotations_mut(&mut self) -> impl Iterator<Item = &mut Annotation> {
Arc::make_mut(&mut self.inner).annotations.iter_mut()
}
/// Returns the "primary" span of this diagnostic if one exists.
///
/// When there are multiple primary spans, then the first one that was
@@ -315,11 +310,6 @@ impl Diagnostic {
&self.inner.subs
}
/// Returns a mutable borrow of the sub-diagnostics of this diagnostic.
pub fn sub_diagnostics_mut(&mut self) -> impl Iterator<Item = &mut SubDiagnostic> {
Arc::make_mut(&mut self.inner).subs.iter_mut()
}
/// Returns the fix for this diagnostic if it exists.
pub fn fix(&self) -> Option<&Fix> {
self.inner.fix.as_ref()
@@ -631,11 +621,6 @@ impl SubDiagnostic {
&self.inner.annotations
}
/// Returns a mutable borrow of the annotations of this sub-diagnostic.
pub fn annotations_mut(&mut self) -> impl Iterator<Item = &mut Annotation> {
self.inner.annotations.iter_mut()
}
/// Returns a shared borrow of the "primary" annotation of this diagnostic
/// if one exists.
///
@@ -1294,10 +1279,6 @@ pub struct DisplayDiagnosticConfig {
hide_severity: bool,
/// Whether to show the availability of a fix in a diagnostic.
show_fix_status: bool,
/// Whether to show the diff for an available fix after the main diagnostic.
///
/// This currently only applies to `DiagnosticFormat::Full`.
show_fix_diff: bool,
/// The lowest applicability that should be shown when reporting diagnostics.
fix_applicability: Applicability,
}
@@ -1345,14 +1326,6 @@ impl DisplayDiagnosticConfig {
}
}
/// Whether to show a diff for an available fix after the main diagnostic.
pub fn show_fix_diff(self, yes: bool) -> DisplayDiagnosticConfig {
DisplayDiagnosticConfig {
show_fix_diff: yes,
..self
}
}
/// Set the lowest fix applicability that should be shown.
///
/// In other words, an applicability of `Safe` (the default) would suppress showing fixes or fix
@@ -1376,7 +1349,6 @@ impl Default for DisplayDiagnosticConfig {
preview: false,
hide_severity: false,
show_fix_status: false,
show_fix_diff: false,
fix_applicability: Applicability::Safe,
}
}

View File

@@ -2,15 +2,15 @@ use std::borrow::Cow;
use std::collections::BTreeMap;
use std::path::Path;
use full::FullRenderer;
use ruff_annotate_snippets::{
Annotation as AnnotateAnnotation, Level as AnnotateLevel, Message as AnnotateMessage,
Snippet as AnnotateSnippet,
Renderer as AnnotateRenderer, Snippet as AnnotateSnippet,
};
use ruff_notebook::{Notebook, NotebookIndex};
use ruff_source_file::{LineIndex, OneIndexed, SourceCode};
use ruff_text_size::{TextLen, TextRange, TextSize};
use crate::diagnostic::stylesheet::DiagnosticStylesheet;
use crate::{
Db,
files::File,
@@ -111,7 +111,37 @@ impl std::fmt::Display for DisplayDiagnostics<'_> {
ConciseRenderer::new(self.resolver, self.config).render(f, self.diagnostics)?;
}
DiagnosticFormat::Full => {
FullRenderer::new(self.resolver, self.config).render(f, self.diagnostics)?;
let stylesheet = if self.config.color {
DiagnosticStylesheet::styled()
} else {
DiagnosticStylesheet::plain()
};
let mut renderer = if self.config.color {
AnnotateRenderer::styled()
} else {
AnnotateRenderer::plain()
}
.cut_indicator("");
renderer = renderer
.error(stylesheet.error)
.warning(stylesheet.warning)
.info(stylesheet.info)
.note(stylesheet.note)
.help(stylesheet.help)
.line_no(stylesheet.line_no)
.emphasis(stylesheet.emphasis)
.none(stylesheet.none);
for diag in self.diagnostics {
let resolved = Resolved::new(self.resolver, diag, self.config);
let renderable = resolved.to_renderable(self.config.context);
for diag in renderable.diagnostics.iter() {
writeln!(f, "{}", renderer.render(diag.to_annotate()))?;
}
writeln!(f)?;
}
}
DiagnosticFormat::Azure => {
AzureRenderer::new(self.resolver).render(f, self.diagnostics)?;
@@ -212,12 +242,7 @@ impl<'a> ResolvedDiagnostic<'a> {
.annotations
.iter()
.filter_map(|ann| {
let path = ann
.span
.file
.relative_path(resolver)
.to_str()
.unwrap_or_else(|| ann.span.file.path(resolver));
let path = ann.span.file.path(resolver);
let diagnostic_source = ann.span.file.diagnostic_source(resolver);
ResolvedAnnotation::new(path, &diagnostic_source, ann, resolver)
})
@@ -264,12 +289,7 @@ impl<'a> ResolvedDiagnostic<'a> {
.annotations
.iter()
.filter_map(|ann| {
let path = ann
.span
.file
.relative_path(resolver)
.to_str()
.unwrap_or_else(|| ann.span.file.path(resolver));
let path = ann.span.file.path(resolver);
let diagnostic_source = ann.span.file.diagnostic_source(resolver);
ResolvedAnnotation::new(path, &diagnostic_source, ann, resolver)
})
@@ -635,22 +655,6 @@ impl<'r> RenderableSnippet<'r> {
.as_source_code()
.slice(TextRange::new(snippet_start, snippet_end));
// Strip the BOM from the beginning of the snippet, if present. Doing this here saves us the
// trouble of updating the annotation ranges in `replace_unprintable`, and also allows us to
// check that the BOM is at the very beginning of the file, not just the beginning of the
// snippet.
const BOM: char = '\u{feff}';
let bom_len = BOM.text_len();
let (snippet, snippet_start) =
if snippet_start == TextSize::ZERO && snippet.starts_with(BOM) {
(
&snippet[bom_len.to_usize()..],
snippet_start + TextSize::new(bom_len.to_u32()),
)
} else {
(snippet, snippet_start)
};
let annotations = anns
.iter()
.map(|ann| RenderableAnnotation::new(snippet_start, ann))
@@ -715,11 +719,7 @@ impl<'r> RenderableAnnotation<'r> {
/// lifetime parameter here refers to the lifetime of the resolver that
/// created the given `ResolvedAnnotation`.
fn new(snippet_start: TextSize, ann: &'_ ResolvedAnnotation<'r>) -> RenderableAnnotation<'r> {
// This should only ever saturate if a BOM is present _and_ the annotation range points
// before the BOM (i.e. at offset 0). In Ruff this typically results from the use of
// `TextRange::default()` for a diagnostic range instead of a range relative to file
// contents.
let range = ann.range.checked_sub(snippet_start).unwrap_or(ann.range);
let range = ann.range - snippet_start;
RenderableAnnotation {
range,
message: ann.message,
@@ -1000,12 +1000,7 @@ fn replace_unprintable<'r>(
let mut last_end = 0;
let mut result = String::new();
for (index, c) in source.char_indices() {
// normalize `\r` line endings but don't double `\r\n`
if c == '\r' && !source[index + 1..].starts_with("\n") {
result.push_str(&source[last_end..index]);
result.push('\n');
last_end = index + 1;
} else if let Some(printable) = unprintable_replacement(c) {
if let Some(printable) = unprintable_replacement(c) {
result.push_str(&source[last_end..index]);
let len = printable.text_len().to_u32();

View File

@@ -1,260 +1,7 @@
use std::borrow::Cow;
use std::num::NonZeroUsize;
use anstyle::Style;
use similar::{ChangeTag, TextDiff};
use ruff_annotate_snippets::Renderer as AnnotateRenderer;
use ruff_diagnostics::{Applicability, Fix};
use ruff_source_file::OneIndexed;
use ruff_text_size::{Ranged, TextRange, TextSize};
use crate::diagnostic::render::{FileResolver, Resolved};
use crate::diagnostic::stylesheet::{DiagnosticStylesheet, fmt_styled};
use crate::diagnostic::{Diagnostic, DiagnosticSource, DisplayDiagnosticConfig};
pub(super) struct FullRenderer<'a> {
resolver: &'a dyn FileResolver,
config: &'a DisplayDiagnosticConfig,
}
impl<'a> FullRenderer<'a> {
pub(super) fn new(resolver: &'a dyn FileResolver, config: &'a DisplayDiagnosticConfig) -> Self {
Self { resolver, config }
}
pub(super) fn render(
&self,
f: &mut std::fmt::Formatter,
diagnostics: &[Diagnostic],
) -> std::fmt::Result {
let stylesheet = if self.config.color {
DiagnosticStylesheet::styled()
} else {
DiagnosticStylesheet::plain()
};
let mut renderer = if self.config.color {
AnnotateRenderer::styled()
} else {
AnnotateRenderer::plain()
}
.cut_indicator("");
renderer = renderer
.error(stylesheet.error)
.warning(stylesheet.warning)
.info(stylesheet.info)
.note(stylesheet.note)
.help(stylesheet.help)
.line_no(stylesheet.line_no)
.emphasis(stylesheet.emphasis)
.none(stylesheet.none);
for diag in diagnostics {
let resolved = Resolved::new(self.resolver, diag, self.config);
let renderable = resolved.to_renderable(self.config.context);
for diag in renderable.diagnostics.iter() {
writeln!(f, "{}", renderer.render(diag.to_annotate()))?;
}
writeln!(f)?;
if self.config.show_fix_diff {
if let Some(diff) = Diff::from_diagnostic(diag, &stylesheet, self.resolver) {
writeln!(f, "{diff}")?;
}
}
}
Ok(())
}
}
/// Renders a diff that shows the code fixes.
///
/// The implementation isn't fully fledged out and only used by tests. Before using in production, try
/// * Improve layout
/// * Replace tabs with spaces for a consistent experience across terminals
/// * Replace zero-width whitespaces
/// * Print a simpler diff if only a single line has changed
/// * Compute the diff from the `Edit` because diff calculation is expensive.
struct Diff<'a> {
fix: &'a Fix,
diagnostic_source: DiagnosticSource,
stylesheet: &'a DiagnosticStylesheet,
}
impl<'a> Diff<'a> {
fn from_diagnostic(
diagnostic: &'a Diagnostic,
stylesheet: &'a DiagnosticStylesheet,
resolver: &'a dyn FileResolver,
) -> Option<Diff<'a>> {
Some(Diff {
fix: diagnostic.fix()?,
diagnostic_source: diagnostic
.primary_span_ref()?
.file
.diagnostic_source(resolver),
stylesheet,
})
}
}
impl std::fmt::Display for Diff<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let source_code = self.diagnostic_source.as_source_code();
let source_text = source_code.text();
// TODO(dhruvmanila): Add support for Notebook cells once it's user-facing
let mut output = String::with_capacity(source_text.len());
let mut last_end = TextSize::default();
for edit in self.fix.edits() {
output.push_str(source_code.slice(TextRange::new(last_end, edit.start())));
output.push_str(edit.content().unwrap_or_default());
last_end = edit.end();
}
output.push_str(&source_text[usize::from(last_end)..]);
let diff = TextDiff::from_lines(source_text, &output);
let message = match self.fix.applicability() {
// TODO(zanieb): Adjust this messaging once it's user-facing
Applicability::Safe => "Safe fix",
Applicability::Unsafe => "Unsafe fix",
Applicability::DisplayOnly => "Display-only fix",
};
// TODO(brent) `stylesheet.separator` is cyan rather than blue, as we had before. I think
// we're getting rid of this soon anyway, so I didn't think it was worth adding another
// style to the stylesheet temporarily. The color doesn't appear at all in the snapshot
// tests, which is the only place these are currently used.
writeln!(f, " {}", fmt_styled(message, self.stylesheet.separator))?;
let (largest_old, largest_new) = diff
.ops()
.last()
.map(|op| (op.old_range().start, op.new_range().start))
.unwrap_or_default();
let digit_with = OneIndexed::from_zero_indexed(largest_new.max(largest_old)).digits();
for (idx, group) in diff.grouped_ops(3).iter().enumerate() {
if idx > 0 {
writeln!(f, "{:-^1$}", "-", 80)?;
}
for op in group {
for change in diff.iter_inline_changes(op) {
let sign = match change.tag() {
ChangeTag::Delete => "-",
ChangeTag::Insert => "+",
ChangeTag::Equal => " ",
};
let line_style = LineStyle::from(change.tag(), self.stylesheet);
let old_index = change.old_index().map(OneIndexed::from_zero_indexed);
let new_index = change.new_index().map(OneIndexed::from_zero_indexed);
write!(
f,
"{} {} |{}",
Line {
index: old_index,
width: digit_with
},
Line {
index: new_index,
width: digit_with
},
fmt_styled(line_style.apply_to(sign), self.stylesheet.emphasis),
)?;
for (emphasized, value) in change.iter_strings_lossy() {
let value = show_nonprinting(&value);
if emphasized {
write!(
f,
"{}",
fmt_styled(line_style.apply_to(&value), self.stylesheet.underline)
)?;
} else {
write!(f, "{}", line_style.apply_to(&value))?;
}
}
if change.missing_newline() {
writeln!(f)?;
}
}
}
}
Ok(())
}
}
struct LineStyle {
style: Style,
}
impl LineStyle {
fn apply_to(&self, input: &str) -> impl std::fmt::Display {
fmt_styled(input, self.style)
}
fn from(value: ChangeTag, stylesheet: &DiagnosticStylesheet) -> LineStyle {
match value {
ChangeTag::Equal => LineStyle {
style: stylesheet.none,
},
ChangeTag::Delete => LineStyle {
style: stylesheet.deletion,
},
ChangeTag::Insert => LineStyle {
style: stylesheet.insertion,
},
}
}
}
struct Line {
index: Option<OneIndexed>,
width: NonZeroUsize,
}
impl std::fmt::Display for Line {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self.index {
None => {
for _ in 0..self.width.get() {
f.write_str(" ")?;
}
Ok(())
}
Some(idx) => write!(f, "{:<width$}", idx, width = self.width.get()),
}
}
}
fn show_nonprinting(s: &str) -> Cow<'_, str> {
if s.find(['\x07', '\x08', '\x1b', '\x7f']).is_some() {
Cow::Owned(
s.replace('\x07', "")
.replace('\x08', "")
.replace('\x1b', "")
.replace('\x7f', ""),
)
} else {
Cow::Borrowed(s)
}
}
#[cfg(test)]
mod tests {
use ruff_diagnostics::Applicability;
use ruff_text_size::{TextLen, TextRange, TextSize};
use ruff_text_size::TextRange;
use crate::diagnostic::{
Annotation, DiagnosticFormat, Severity,
@@ -439,7 +186,7 @@ print()
/// For example, without the fix, we get diagnostics like this:
///
/// ```
/// error[invalid-character-sub]: Invalid unescaped character SUB, use "\x1a" instead
/// error[invalid-character-sub]: Invalid unescaped character SUB, use "\x1A" instead
/// --> example.py:1:25
/// |
/// 1 | nested_fstrings = f'␈{f'{f'␛'}'}'
@@ -459,13 +206,13 @@ print()
.builder(
"invalid-character-sub",
Severity::Error,
r#"Invalid unescaped character SUB, use "\x1a" instead"#,
r#"Invalid unescaped character SUB, use "\x1A" instead"#,
)
.primary("example.py", "1:24", "1:24", "")
.build();
insta::assert_snapshot!(env.render(&diagnostic), @r#"
error[invalid-character-sub]: Invalid unescaped character SUB, use "\x1a" instead
error[invalid-character-sub]: Invalid unescaped character SUB, use "\x1A" instead
--> example.py:1:25
|
1 | nested_fstrings = f'␈{f'{f'␛'}'}'
@@ -484,13 +231,13 @@ print()
.builder(
"invalid-character-sub",
Severity::Error,
r#"Invalid unescaped character SUB, use "\x1a" instead"#,
r#"Invalid unescaped character SUB, use "\x1A" instead"#,
)
.primary("example.py", "1:1", "1:1", "")
.build();
insta::assert_snapshot!(env.render(&diagnostic), @r#"
error[invalid-character-sub]: Invalid unescaped character SUB, use "\x1a" instead
error[invalid-character-sub]: Invalid unescaped character SUB, use "\x1A" instead
--> example.py:1:2
|
1 | ␈
@@ -653,107 +400,4 @@ print()
help: Remove `print` statement
");
}
/// Carriage return (`\r`) is a valid line-ending in Python, so we should normalize this to a
/// line feed (`\n`) for rendering. Otherwise we report a single long line for this case.
#[test]
fn normalize_carriage_return() {
let mut env = TestEnvironment::new();
env.add(
"example.py",
"# Keep parenthesis around preserved CR\rint(-\r 1)\rint(+\r 1)",
);
env.format(DiagnosticFormat::Full);
let mut diagnostic = env.err().build();
let span = env
.path("example.py")
.with_range(TextRange::at(TextSize::new(39), TextSize::new(0)));
let annotation = Annotation::primary(span);
diagnostic.annotate(annotation);
insta::assert_snapshot!(env.render(&diagnostic), @r"
error[test-diagnostic]: main diagnostic message
--> example.py:2:1
|
1 | # Keep parenthesis around preserved CR
2 | int(-
| ^
3 | 1)
4 | int(+
|
");
}
/// Without stripping the BOM, we report an error in column 2, unlike Ruff.
#[test]
fn strip_bom() {
let mut env = TestEnvironment::new();
env.add("example.py", "\u{feff}import foo");
env.format(DiagnosticFormat::Full);
let mut diagnostic = env.err().build();
let span = env
.path("example.py")
.with_range(TextRange::at(TextSize::new(3), TextSize::new(0)));
let annotation = Annotation::primary(span);
diagnostic.annotate(annotation);
insta::assert_snapshot!(env.render(&diagnostic), @r"
error[test-diagnostic]: main diagnostic message
--> example.py:1:1
|
1 | import foo
| ^
|
");
}
#[test]
fn bom_with_default_range() {
let mut env = TestEnvironment::new();
env.add("example.py", "\u{feff}import foo");
env.format(DiagnosticFormat::Full);
let mut diagnostic = env.err().build();
let span = env.path("example.py").with_range(TextRange::default());
let annotation = Annotation::primary(span);
diagnostic.annotate(annotation);
insta::assert_snapshot!(env.render(&diagnostic), @r"
error[test-diagnostic]: main diagnostic message
--> example.py:1:1
|
1 | import foo
| ^
|
");
}
/// We previously rendered this correctly, but the header was falling back to 1:1 for ranges
/// pointing to the final newline in a file. Like Ruff, we now use the offset of the first
/// character in the nonexistent final line in the header.
#[test]
fn end_of_file() {
let mut env = TestEnvironment::new();
let contents = "unexpected eof\n";
env.add("example.py", contents);
env.format(DiagnosticFormat::Full);
let mut diagnostic = env.err().build();
let span = env
.path("example.py")
.with_range(TextRange::at(contents.text_len(), TextSize::new(0)));
let annotation = Annotation::primary(span);
diagnostic.annotate(annotation);
insta::assert_snapshot!(env.render(&diagnostic), @r"
error[test-diagnostic]: main diagnostic message
--> example.py:2:1
|
1 | unexpected eof
| ^
|
");
}
}

View File

@@ -40,12 +40,9 @@ pub struct DiagnosticStylesheet {
pub(crate) help: Style,
pub(crate) line_no: Style,
pub(crate) emphasis: Style,
pub(crate) underline: Style,
pub(crate) none: Style,
pub(crate) separator: Style,
pub(crate) secondary_code: Style,
pub(crate) insertion: Style,
pub(crate) deletion: Style,
}
impl Default for DiagnosticStylesheet {
@@ -66,12 +63,9 @@ impl DiagnosticStylesheet {
help: AnsiColor::BrightCyan.on_default().effects(Effects::BOLD),
line_no: bright_blue.effects(Effects::BOLD),
emphasis: Style::new().effects(Effects::BOLD),
underline: Style::new().effects(Effects::UNDERLINE),
none: Style::new(),
separator: AnsiColor::Cyan.on_default(),
secondary_code: AnsiColor::Red.on_default().effects(Effects::BOLD),
insertion: AnsiColor::Green.on_default(),
deletion: AnsiColor::Red.on_default(),
}
}
@@ -84,12 +78,9 @@ impl DiagnosticStylesheet {
help: Style::new(),
line_no: Style::new(),
emphasis: Style::new(),
underline: Style::new(),
none: Style::new(),
separator: Style::new(),
secondary_code: Style::new(),
insertion: Style::new(),
deletion: Style::new(),
}
}
}

View File

@@ -9,7 +9,7 @@ use crate::system::file_time_now;
/// * The last modification time of the file.
/// * The hash of the file's content.
/// * The revision as it comes from an external system, for example the LSP.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default, get_size2::GetSize)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
pub struct FileRevision(u128);
impl FileRevision {

View File

@@ -87,12 +87,11 @@ impl Files {
.system_by_path
.entry(absolute.clone())
.or_insert_with(|| {
tracing::trace!("Adding file '{path}'");
let metadata = db.system().path_metadata(path);
tracing::trace!("Adding file '{absolute}'");
let durability = self
.root(db, &absolute)
.root(db, path)
.map_or(Durability::default(), |root| root.durability(db));
let builder = File::builder(FilePath::System(absolute))
@@ -290,7 +289,7 @@ impl std::panic::RefUnwindSafe for Files {}
/// # Ordering
/// Ordering is based on the file's salsa-assigned id and not on its values.
/// The id may change between runs.
#[salsa::input(heap_size=ruff_memory_usage::heap_size)]
#[salsa::input]
#[derive(PartialOrd, Ord)]
pub struct File {
/// The path of the file (immutable).
@@ -522,7 +521,7 @@ impl VirtualFile {
// The types in here need to be public because they're salsa ingredients but we
// don't want them to be publicly accessible. That's why we put them into a private module.
mod private {
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default, get_size2::GetSize)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
pub enum FileStatus {
/// The file exists.
#[default]

View File

@@ -16,7 +16,7 @@ use crate::system::{SystemPath, SystemPathBuf};
/// The main usage of file roots is to determine a file's durability. But it can also be used
/// to make a salsa query dependent on whether a file in a root has changed without writing any
/// manual invalidation logic.
#[salsa::input(debug, heap_size=ruff_memory_usage::heap_size)]
#[salsa::input(debug)]
pub struct FileRoot {
/// The path of a root is guaranteed to never change.
#[returns(deref)]
@@ -37,7 +37,7 @@ impl FileRoot {
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, get_size2::GetSize)]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum FileRootKind {
/// The root of a project.
Project,

View File

@@ -11,7 +11,7 @@ use std::fmt::{Display, Formatter};
/// * a file stored on the [host system](crate::system::System).
/// * a virtual file stored on the [host system](crate::system::System).
/// * a vendored file stored in the [vendored file system](crate::vendored::VendoredFileSystem).
#[derive(Clone, Debug, Eq, PartialEq, Hash, get_size2::GetSize)]
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub enum FilePath {
/// Path to a file on the [host system](crate::system::System).
System(SystemPathBuf),

View File

@@ -762,7 +762,7 @@ impl SystemVirtualPath {
}
/// An owned, virtual path on [`System`](`super::System`) (akin to [`String`]).
#[derive(Eq, PartialEq, Clone, Hash, PartialOrd, Ord, get_size2::GetSize)]
#[derive(Eq, PartialEq, Clone, Hash, PartialOrd, Ord)]
pub struct SystemVirtualPathBuf(String);
impl SystemVirtualPathBuf {

View File

@@ -14,11 +14,8 @@ license = { workspace = true }
doctest = false
[dependencies]
ruff_text_size = { workspace = true, features = ["get-size"] }
ruff_text_size = { workspace = true }
get-size2 = { workspace = true }
is-macro = { workspace = true }
serde = { workspace = true, optional = true, features = [] }
[features]
serde = ["dep:serde", "ruff_text_size/serde"]

View File

@@ -1,6 +1,6 @@
[package]
name = "ruff_linter"
version = "0.12.10"
version = "0.12.8"
publish = false
authors = { workspace = true }
edition = { workspace = true }
@@ -13,6 +13,7 @@ license = { workspace = true }
[lib]
[dependencies]
ruff_annotate_snippets = { workspace = true }
ruff_cache = { workspace = true }
ruff_db = { workspace = true, features = ["junit", "serde"] }
ruff_diagnostics = { workspace = true, features = ["serde"] }

View File

@@ -13,7 +13,6 @@ from airflow.api_connexion.security import requires_access
from airflow.contrib.aws_athena_hook import AWSAthenaHook
from airflow.datasets import DatasetAliasEvent
from airflow.operators.subdag import SubDagOperator
from airflow.secrets.cache import SecretCache
from airflow.secrets.local_filesystem import LocalFilesystemBackend
from airflow.triggers.external_task import TaskStateTrigger
from airflow.utils import dates
@@ -57,9 +56,6 @@ SubDagOperator()
# get_connection
LocalFilesystemBackend()
# airflow.secrets.cache
SecretCache()
# airflow.triggers.external_task
TaskStateTrigger()

View File

@@ -154,11 +154,6 @@ try:
except Exception as e:
raise ValueError from e
try:
...
except Exception as e:
raise e from ValueError("hello")
try:
pass
@@ -250,9 +245,3 @@ try:
pass
except (Exception, ValueError) as e:
raise e
# `from None` cause
try:
pass
except BaseException as e:
raise e from None

View File

@@ -1,43 +0,0 @@
class C: a = None
{C.a: None for C.a in "abc"}
print(C.a)
x = [None]
{x[0]: None for x[0] in "abc"}
print(x)
class C(list):
def __getitem__(self, index, /):
item = super().__getitem__(index)
if isinstance(index, slice): item = tuple(item)
return item
x = C()
{x[:0]: None for x[:0] in "abc"}
print(x)
class C:
a = None
def func():
{(C.a,): None for (C.a,) in "abc"} # OK
def func():
obj = type('obj', (), {'attr': 1})()
{(obj.attr,): None for (obj.attr,) in "abc"} # OK
def func():
lst = [1, 2, 3]
{(lst[0],): None for (lst[0],) in "abc"} # OK
def func():
lst = [1, 2, 3, 4, 5]
{(lst[1:3],): None for (lst[1:3],) in "abc"} # OK
# C420: side-effecting assignment targets
# These should NOT trigger C420 because they have side-effecting assignment targets
# See https://github.com/astral-sh/ruff/issues/19511

View File

@@ -161,12 +161,3 @@ r"""first
'no need' to escape
"swap" quote style
"use' ugly triple quotes""".split("\n")
# https://github.com/astral-sh/ruff/issues/19845
print("S\x1cP\x1dL\x1eI\x1fT".split())
print("\x1c\x1d\x1e\x1f>".split(maxsplit=0))
print("<\x1c\x1d\x1e\x1f".rsplit(maxsplit=0))
# leading/trailing whitespace should not count towards maxsplit
" a b c d ".split(maxsplit=2) # ["a", "b", "c d "]
" a b c d ".rsplit(maxsplit=2) # [" a b", "c", "d"]

View File

@@ -106,22 +106,4 @@ os.replace("src", "dst", src_dir_fd=1)
os.replace("src", "dst", dst_dir_fd=2)
os.getcwd()
os.getcwdb()
os.mkdir(path="directory")
os.mkdir(
# comment 1
"directory",
mode=0o777
)
os.mkdir("directory", mode=0o777, dir_fd=1)
os.makedirs("name", 0o777, exist_ok=False)
os.makedirs("name", 0o777, False)
os.makedirs(name="name", mode=0o777, exist_ok=False)
os.makedirs("name", unknown_kwarg=True)
os.getcwdb()

View File

@@ -1,4 +0,0 @@
"""Hello, world!"""\
\
x = 1; y = 2

View File

@@ -1,18 +0,0 @@
from __future__ import nested_scopes, generators
from __future__ import with_statement, unicode_literals
from __future__ import absolute_import, division
from __future__ import generator_stop
from __future__ import print_function, nested_scopes, generator_stop
print(with_statement)
generators = 1
class Foo():
def boo(self):
print(division)
__all__ = ["print_function", "generator_stop"]

View File

@@ -69,10 +69,3 @@ a7: OptionalTE[typing.NamedTuple] = None
a8: typing_extensions.Optional[typing.NamedTuple] = None
a9: "Optional[NamedTuple]" = None
a10: Optional[NamedTupleTE] = None
# Test for: https://github.com/astral-sh/ruff/issues/19746
# Nested Optional types should be flattened
nested_optional: Optional[Optional[str]] = None
nested_optional_typing: typing.Optional[Optional[int]] = None
triple_nested_optional: Optional[Optional[Optional[str]]] = None

View File

@@ -51,11 +51,3 @@ dbm.ndbm.open("db", "r", 0o600) # OK
os.fchmod(0, 256) # 0o400
os.fchmod(0, 493) # 0o755
# https://github.com/astral-sh/ruff/issues/19010
os.chmod("foo", 000) # Error
os.chmod("foo", 0000) # Error
os.chmod("foo", 0b0) # Error
os.chmod("foo", 0x0) # Error
os.chmod("foo", 0) # Ok

View File

@@ -1,11 +1,10 @@
use ruff_python_ast::PythonVersion;
use ruff_python_semantic::{Binding, ScopeKind};
use crate::checkers::ast::Checker;
use crate::codes::Rule;
use crate::rules::{
flake8_builtins, flake8_pyi, flake8_type_checking, flake8_unused_arguments, pep8_naming,
pyflakes, pylint, pyupgrade, ruff,
pyflakes, pylint, ruff,
};
/// Run lint rules over all deferred scopes in the [`SemanticModel`].
@@ -46,7 +45,6 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
Rule::UnusedStaticMethodArgument,
Rule::UnusedUnpackedVariable,
Rule::UnusedVariable,
Rule::UnnecessaryFutureImport,
]) {
return;
}
@@ -226,11 +224,6 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
if checker.is_rule_enabled(Rule::UnusedImport) {
pyflakes::rules::unused_import(checker, scope);
}
if checker.is_rule_enabled(Rule::UnnecessaryFutureImport) {
if checker.target_version() >= PythonVersion::PY37 {
pyupgrade::rules::unnecessary_future_import(checker, scope);
}
}
if checker.is_rule_enabled(Rule::ImportPrivateName) {
pylint::rules::import_private_name(checker, scope);

View File

@@ -1039,6 +1039,8 @@ pub(crate) fn expression(expr: &Expr, checker: &Checker) {
flake8_simplify::rules::zip_dict_keys_and_values(checker, call);
}
if checker.any_rule_enabled(&[
Rule::OsMkdir,
Rule::OsMakedirs,
Rule::OsStat,
Rule::OsPathJoin,
Rule::OsPathSplitext,
@@ -1118,12 +1120,6 @@ pub(crate) fn expression(expr: &Expr, checker: &Checker) {
if checker.is_rule_enabled(Rule::OsPathSamefile) {
flake8_use_pathlib::rules::os_path_samefile(checker, call, segments);
}
if checker.is_rule_enabled(Rule::OsMkdir) {
flake8_use_pathlib::rules::os_mkdir(checker, call, segments);
}
if checker.is_rule_enabled(Rule::OsMakedirs) {
flake8_use_pathlib::rules::os_makedirs(checker, call, segments);
}
if checker.is_rule_enabled(Rule::PathConstructorCurrentDirectory) {
flake8_use_pathlib::rules::path_constructor_current_directory(
checker, call, segments,

View File

@@ -728,6 +728,13 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
pylint::rules::non_ascii_module_import(checker, alias);
}
}
if checker.is_rule_enabled(Rule::UnnecessaryFutureImport) {
if checker.target_version() >= PythonVersion::PY37 {
if let Some("__future__") = module {
pyupgrade::rules::unnecessary_future_import(checker, stmt, names);
}
}
}
if checker.is_rule_enabled(Rule::DeprecatedMockImport) {
pyupgrade::rules::deprecated_mock_import(checker, stmt);
}

View File

@@ -28,7 +28,7 @@ use itertools::Itertools;
use log::debug;
use rustc_hash::{FxHashMap, FxHashSet};
use ruff_db::diagnostic::{Annotation, Diagnostic, IntoDiagnosticMessage, Span};
use ruff_db::diagnostic::Diagnostic;
use ruff_diagnostics::{Applicability, Fix, IsolationLevel};
use ruff_notebook::{CellOffsets, NotebookIndex};
use ruff_python_ast::helpers::{collect_import_from_member, is_docstring_stmt, to_module_path};
@@ -684,7 +684,8 @@ impl SemanticSyntaxContext for Checker<'_> {
| SemanticSyntaxErrorKind::LoadBeforeNonlocalDeclaration { .. }
| SemanticSyntaxErrorKind::NonlocalAndGlobal(_)
| SemanticSyntaxErrorKind::AnnotatedGlobal(_)
| SemanticSyntaxErrorKind::AnnotatedNonlocal(_) => {
| SemanticSyntaxErrorKind::AnnotatedNonlocal(_)
| SemanticSyntaxErrorKind::NoBindingForNonlocal(_) => {
self.semantic_errors.borrow_mut().push(error);
}
}
@@ -3305,17 +3306,6 @@ impl DiagnosticGuard<'_, '_> {
Err(err) => log::debug!("Failed to create fix for {}: {}", self.name(), err),
}
}
/// Add a secondary annotation with the given message and range.
pub(crate) fn secondary_annotation<'a>(
&mut self,
message: impl IntoDiagnosticMessage + 'a,
range: impl Ranged,
) {
let span = Span::from(self.context.source_file.clone()).with_range(range.range());
let ann = Annotation::secondary(span).message(message);
self.diagnostic.as_mut().unwrap().annotate(ann);
}
}
impl std::ops::Deref for DiagnosticGuard<'_, '_> {

View File

@@ -921,8 +921,8 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
// flake8-use-pathlib
(Flake8UsePathlib, "100") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsPathAbspath),
(Flake8UsePathlib, "101") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsChmod),
(Flake8UsePathlib, "102") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsMkdir),
(Flake8UsePathlib, "103") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsMakedirs),
(Flake8UsePathlib, "102") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsMkdir),
(Flake8UsePathlib, "103") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsMakedirs),
(Flake8UsePathlib, "104") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsRename),
(Flake8UsePathlib, "105") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsReplace),
(Flake8UsePathlib, "106") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsRmdir),

View File

@@ -63,9 +63,9 @@ impl<'a> Insertion<'a> {
return Insertion::inline(" ", location.add(offset).add(TextSize::of(';')), ";");
}
// While the first token after the docstring is a continuation character (i.e. "\"), advance
// additional rows to prevent inserting in the same logical line.
while match_continuation(locator.after(location)).is_some() {
// If the first token after the docstring is a continuation character (i.e. "\"), advance
// an additional row to prevent inserting in the same logical line.
if match_continuation(locator.after(location)).is_some() {
location = locator.full_line_end(location);
}
@@ -379,17 +379,6 @@ mod tests {
Insertion::own_line("", TextSize::from(22), "\n")
);
let contents = r#"
"""Hello, world!"""\
\
"#
.trim_start();
assert_eq!(
insert(contents)?,
Insertion::own_line("", TextSize::from(24), "\n")
);
let contents = r"
x = 1
"

View File

@@ -44,15 +44,44 @@ pub struct LinterResult {
/// Flag indicating that the parsed source code does not contain any
/// [`ParseError`]s
has_valid_syntax: bool,
/// Flag indicating that the parsed source code does not contain any [`ParseError`]s,
/// [`UnsupportedSyntaxError`]s, or [`SemanticSyntaxError`]s.
has_no_syntax_errors: bool,
}
impl LinterResult {
/// Returns `true` if the parsed source code contains any [`ParseError`]s *or*
/// [`UnsupportedSyntaxError`]s.
///
/// See [`LinterResult::has_invalid_syntax`] for a version specific to [`ParseError`]s.
pub fn has_syntax_errors(&self) -> bool {
!self.has_no_syntax_errors()
}
/// Returns `true` if the parsed source code does not contain any [`ParseError`]s *or*
/// [`UnsupportedSyntaxError`]s.
///
/// See [`LinterResult::has_valid_syntax`] for a version specific to [`ParseError`]s.
pub fn has_no_syntax_errors(&self) -> bool {
self.has_valid_syntax() && self.has_no_syntax_errors
}
/// Returns `true` if the parsed source code is valid i.e., it has no [`ParseError`]s.
///
/// Note that this does not include version-related [`UnsupportedSyntaxError`]s.
///
/// See [`LinterResult::has_no_syntax_errors`] for a version that takes these into account.
pub fn has_valid_syntax(&self) -> bool {
self.has_valid_syntax
}
/// Returns `true` if the parsed source code is invalid i.e., it has [`ParseError`]s.
///
/// Note that this does not include version-related [`UnsupportedSyntaxError`]s or
/// [`SemanticSyntaxError`]s.
/// Note that this does not include version-related [`UnsupportedSyntaxError`]s.
///
/// See [`LinterResult::has_no_syntax_errors`] for a version that takes these into account.
pub fn has_invalid_syntax(&self) -> bool {
!self.has_valid_syntax
!self.has_valid_syntax()
}
}
@@ -484,6 +513,7 @@ pub fn lint_only(
LinterResult {
has_valid_syntax: parsed.has_valid_syntax(),
has_no_syntax_errors: !diagnostics.iter().any(Diagnostic::is_invalid_syntax),
diagnostics,
}
}
@@ -640,6 +670,7 @@ pub fn lint_fix<'a>(
result: LinterResult {
diagnostics,
has_valid_syntax,
has_no_syntax_errors,
},
transformed,
fixed,

View File

@@ -0,0 +1,202 @@
use std::fmt::{Display, Formatter};
use std::num::NonZeroUsize;
use colored::{Color, ColoredString, Colorize, Styles};
use similar::{ChangeTag, TextDiff};
use ruff_db::diagnostic::Diagnostic;
use ruff_source_file::{OneIndexed, SourceFile};
use ruff_text_size::{Ranged, TextRange, TextSize};
use crate::text_helpers::ShowNonprinting;
use crate::{Applicability, Fix};
/// Renders a diff that shows the code fixes.
///
/// The implementation isn't fully fledged out and only used by tests. Before using in production, try
/// * Improve layout
/// * Replace tabs with spaces for a consistent experience across terminals
/// * Replace zero-width whitespaces
/// * Print a simpler diff if only a single line has changed
/// * Compute the diff from the [`Edit`] because diff calculation is expensive.
pub(super) struct Diff<'a> {
fix: &'a Fix,
source_code: &'a SourceFile,
}
impl<'a> Diff<'a> {
pub(crate) fn from_message(message: &'a Diagnostic) -> Option<Diff<'a>> {
message.fix().map(|fix| Diff {
source_code: message.expect_ruff_source_file(),
fix,
})
}
}
impl Display for Diff<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
// TODO(dhruvmanila): Add support for Notebook cells once it's user-facing
let mut output = String::with_capacity(self.source_code.source_text().len());
let mut last_end = TextSize::default();
for edit in self.fix.edits() {
output.push_str(
self.source_code
.slice(TextRange::new(last_end, edit.start())),
);
output.push_str(edit.content().unwrap_or_default());
last_end = edit.end();
}
output.push_str(&self.source_code.source_text()[usize::from(last_end)..]);
let diff = TextDiff::from_lines(self.source_code.source_text(), &output);
let message = match self.fix.applicability() {
// TODO(zanieb): Adjust this messaging once it's user-facing
Applicability::Safe => "Safe fix",
Applicability::Unsafe => "Unsafe fix",
Applicability::DisplayOnly => "Display-only fix",
};
writeln!(f, " {}", message.blue())?;
let (largest_old, largest_new) = diff
.ops()
.last()
.map(|op| (op.old_range().start, op.new_range().start))
.unwrap_or_default();
let digit_with =
calculate_print_width(OneIndexed::from_zero_indexed(largest_new.max(largest_old)));
for (idx, group) in diff.grouped_ops(3).iter().enumerate() {
if idx > 0 {
writeln!(f, "{:-^1$}", "-", 80)?;
}
for op in group {
for change in diff.iter_inline_changes(op) {
let sign = match change.tag() {
ChangeTag::Delete => "-",
ChangeTag::Insert => "+",
ChangeTag::Equal => " ",
};
let line_style = LineStyle::from(change.tag());
let old_index = change.old_index().map(OneIndexed::from_zero_indexed);
let new_index = change.new_index().map(OneIndexed::from_zero_indexed);
write!(
f,
"{} {} |{}",
Line {
index: old_index,
width: digit_with
},
Line {
index: new_index,
width: digit_with
},
line_style.apply_to(sign).bold()
)?;
for (emphasized, value) in change.iter_strings_lossy() {
let value = value.show_nonprinting();
if emphasized {
write!(f, "{}", line_style.apply_to(&value).underline().on_black())?;
} else {
write!(f, "{}", line_style.apply_to(&value))?;
}
}
if change.missing_newline() {
writeln!(f)?;
}
}
}
}
Ok(())
}
}
struct LineStyle {
fgcolor: Option<Color>,
style: Option<Styles>,
}
impl LineStyle {
fn apply_to(&self, input: &str) -> ColoredString {
let mut colored = ColoredString::from(input);
if let Some(color) = self.fgcolor {
colored = colored.color(color);
}
if let Some(style) = self.style {
match style {
Styles::Clear => colored.clear(),
Styles::Bold => colored.bold(),
Styles::Dimmed => colored.dimmed(),
Styles::Underline => colored.underline(),
Styles::Reversed => colored.reversed(),
Styles::Italic => colored.italic(),
Styles::Blink => colored.blink(),
Styles::Hidden => colored.hidden(),
Styles::Strikethrough => colored.strikethrough(),
}
} else {
colored
}
}
}
impl From<ChangeTag> for LineStyle {
fn from(value: ChangeTag) -> Self {
match value {
ChangeTag::Equal => LineStyle {
fgcolor: None,
style: Some(Styles::Dimmed),
},
ChangeTag::Delete => LineStyle {
fgcolor: Some(Color::Red),
style: None,
},
ChangeTag::Insert => LineStyle {
fgcolor: Some(Color::Green),
style: None,
},
}
}
}
struct Line {
index: Option<OneIndexed>,
width: NonZeroUsize,
}
impl Display for Line {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
match self.index {
None => {
for _ in 0..self.width.get() {
f.write_str(" ")?;
}
Ok(())
}
Some(idx) => write!(f, "{:<width$}", idx, width = self.width.get()),
}
}
}
/// Calculate the length of the string representation of `value`
pub(super) fn calculate_print_width(mut value: OneIndexed) -> NonZeroUsize {
const TEN: OneIndexed = OneIndexed::from_zero_indexed(9);
let mut width = OneIndexed::ONE;
while value >= TEN {
value = OneIndexed::new(value.get() / 10).unwrap_or(OneIndexed::MIN);
width = width.checked_add(1).unwrap();
}
width
}

View File

@@ -88,14 +88,20 @@ impl Serialize for SerializedMessages<'_> {
}
fingerprints.insert(message_fingerprint);
let description = diagnostic.body();
let check_name = diagnostic.secondary_code_or_id();
let (description, check_name) = if let Some(code) = diagnostic.secondary_code() {
(diagnostic.body().to_string(), code.as_str())
} else {
let description = diagnostic.body();
let description_without_prefix = description
.strip_prefix("SyntaxError: ")
.unwrap_or(description);
(description_without_prefix.to_string(), "syntax-error")
};
let value = json!({
"check_name": check_name,
// GitLab doesn't display the separate `check_name` field in a Code Quality report,
// so prepend it to the description too.
"description": format!("{check_name}: {description}"),
"description": description,
"severity": "major",
"fingerprint": format!("{:x}", message_fingerprint),
"location": {

View File

@@ -1,4 +1,3 @@
use std::collections::BTreeMap;
use std::fmt::{Display, Formatter};
use std::io::Write;
use std::num::NonZeroUsize;
@@ -7,15 +6,18 @@ use colored::Colorize;
use ruff_db::diagnostic::Diagnostic;
use ruff_notebook::NotebookIndex;
use ruff_source_file::{LineColumn, OneIndexed};
use ruff_source_file::OneIndexed;
use crate::fs::relativize_path;
use crate::message::{Emitter, EmitterContext};
use crate::message::diff::calculate_print_width;
use crate::message::text::{MessageCodeFrame, RuleCodeAndBody};
use crate::message::{Emitter, EmitterContext, MessageWithLocation, group_diagnostics_by_filename};
use crate::settings::types::UnsafeFixes;
#[derive(Default)]
pub struct GroupedEmitter {
show_fix_status: bool,
show_source: bool,
unsafe_fixes: UnsafeFixes,
}
@@ -26,6 +28,12 @@ impl GroupedEmitter {
self
}
#[must_use]
pub fn with_show_source(mut self, show_source: bool) -> Self {
self.show_source = show_source;
self
}
#[must_use]
pub fn with_unsafe_fixes(mut self, unsafe_fixes: UnsafeFixes) -> Self {
self.unsafe_fixes = unsafe_fixes;
@@ -52,8 +60,8 @@ impl Emitter for GroupedEmitter {
max_column_length = max_column_length.max(message.start_location.column);
}
let row_length = max_row_length.digits();
let column_length = max_column_length.digits();
let row_length = calculate_print_width(max_row_length);
let column_length = calculate_print_width(max_column_length);
// Print the filename.
writeln!(writer, "{}:", relativize_path(&*filename).underline())?;
@@ -68,53 +76,29 @@ impl Emitter for GroupedEmitter {
message,
show_fix_status: self.show_fix_status,
unsafe_fixes: self.unsafe_fixes,
show_source: self.show_source,
row_length,
column_length,
}
)?;
}
// Print a blank line between files.
writeln!(writer)?;
// Print a blank line between files, unless we're showing the source, in which case
// we'll have already printed a blank line between messages.
if !self.show_source {
writeln!(writer)?;
}
}
Ok(())
}
}
struct MessageWithLocation<'a> {
message: &'a Diagnostic,
start_location: LineColumn,
}
impl std::ops::Deref for MessageWithLocation<'_> {
type Target = Diagnostic;
fn deref(&self) -> &Self::Target {
self.message
}
}
fn group_diagnostics_by_filename(
diagnostics: &[Diagnostic],
) -> BTreeMap<String, Vec<MessageWithLocation<'_>>> {
let mut grouped_messages = BTreeMap::default();
for diagnostic in diagnostics {
grouped_messages
.entry(diagnostic.expect_ruff_filename())
.or_insert_with(Vec::new)
.push(MessageWithLocation {
message: diagnostic,
start_location: diagnostic.expect_ruff_start_location(),
});
}
grouped_messages
}
struct DisplayGroupedMessage<'a> {
message: MessageWithLocation<'a>,
show_fix_status: bool,
unsafe_fixes: UnsafeFixes,
show_source: bool,
row_length: NonZeroUsize,
column_length: NonZeroUsize,
notebook_index: Option<&'a NotebookIndex>,
@@ -130,7 +114,8 @@ impl Display for DisplayGroupedMessage<'_> {
write!(
f,
" {row_padding}",
row_padding = " ".repeat(self.row_length.get() - start_location.line.digits().get())
row_padding = " "
.repeat(self.row_length.get() - calculate_print_width(start_location.line).get())
)?;
// Check if we're working on a jupyter notebook and translate positions with cell accordingly
@@ -157,8 +142,9 @@ impl Display for DisplayGroupedMessage<'_> {
f,
"{row}{sep}{col}{col_padding} {code_and_body}",
sep = ":".cyan(),
col_padding =
" ".repeat(self.column_length.get() - start_location.column.digits().get()),
col_padding = " ".repeat(
self.column_length.get() - calculate_print_width(start_location.column).get()
),
code_and_body = RuleCodeAndBody {
message,
show_fix_status: self.show_fix_status,
@@ -166,50 +152,51 @@ impl Display for DisplayGroupedMessage<'_> {
},
)?;
if self.show_source {
use std::fmt::Write;
let mut padded = PadAdapter::new(f);
writeln!(
padded,
"{}",
MessageCodeFrame {
message,
notebook_index: self.notebook_index
}
)?;
}
Ok(())
}
}
pub(super) struct RuleCodeAndBody<'a> {
pub(crate) message: &'a Diagnostic,
pub(crate) show_fix_status: bool,
pub(crate) unsafe_fixes: UnsafeFixes,
/// Adapter that adds a ' ' at the start of every line without the need to copy the string.
/// Inspired by Rust's `debug_struct()` internal implementation that also uses a `PadAdapter`.
struct PadAdapter<'buf> {
buf: &'buf mut (dyn std::fmt::Write + 'buf),
on_newline: bool,
}
impl Display for RuleCodeAndBody<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
if self.show_fix_status {
if let Some(fix) = self.message.fix() {
// Do not display an indicator for inapplicable fixes
if fix.applies(self.unsafe_fixes.required_applicability()) {
if let Some(code) = self.message.secondary_code() {
write!(f, "{} ", code.red().bold())?;
}
return write!(
f,
"{fix}{body}",
fix = format_args!("[{}] ", "*".cyan()),
body = self.message.body(),
);
}
impl<'buf> PadAdapter<'buf> {
fn new(buf: &'buf mut (dyn std::fmt::Write + 'buf)) -> Self {
Self {
buf,
on_newline: true,
}
}
}
impl std::fmt::Write for PadAdapter<'_> {
fn write_str(&mut self, s: &str) -> std::fmt::Result {
for s in s.split_inclusive('\n') {
if self.on_newline {
self.buf.write_str(" ")?;
}
self.on_newline = s.ends_with('\n');
self.buf.write_str(s)?;
}
if let Some(code) = self.message.secondary_code() {
write!(
f,
"{code} {body}",
code = code.red().bold(),
body = self.message.body(),
)
} else {
write!(
f,
"{code}: {body}",
code = self.message.id().as_str().red().bold(),
body = self.message.body(),
)
}
Ok(())
}
}
@@ -239,9 +226,19 @@ mod tests {
assert_snapshot!(content);
}
#[test]
fn show_source() {
let mut emitter = GroupedEmitter::default().with_show_source(true);
let content = capture_emitter_output(&mut emitter, &create_diagnostics());
assert_snapshot!(content);
}
#[test]
fn fix_status() {
let mut emitter = GroupedEmitter::default().with_show_fix_status(true);
let mut emitter = GroupedEmitter::default()
.with_show_fix_status(true)
.with_show_source(true);
let content = capture_emitter_output(&mut emitter, &create_diagnostics());
assert_snapshot!(content);
@@ -251,6 +248,7 @@ mod tests {
fn fix_status_unsafe() {
let mut emitter = GroupedEmitter::default()
.with_show_fix_status(true)
.with_show_source(true)
.with_unsafe_fixes(UnsafeFixes::Enabled);
let content = capture_emitter_output(&mut emitter, &create_diagnostics());

View File

@@ -1,5 +1,7 @@
use std::collections::BTreeMap;
use std::fmt::Display;
use std::io::Write;
use std::ops::Deref;
use rustc_hash::FxHashMap;
@@ -13,7 +15,7 @@ pub use github::GithubEmitter;
pub use gitlab::GitlabEmitter;
pub use grouped::GroupedEmitter;
use ruff_notebook::NotebookIndex;
use ruff_source_file::SourceFile;
use ruff_source_file::{LineColumn, SourceFile};
use ruff_text_size::{Ranged, TextRange, TextSize};
pub use sarif::SarifEmitter;
pub use text::TextEmitter;
@@ -21,6 +23,7 @@ pub use text::TextEmitter;
use crate::Fix;
use crate::registry::Rule;
mod diff;
mod github;
mod gitlab;
mod grouped;
@@ -131,6 +134,35 @@ impl FileResolver for EmitterContext<'_> {
}
}
struct MessageWithLocation<'a> {
message: &'a Diagnostic,
start_location: LineColumn,
}
impl Deref for MessageWithLocation<'_> {
type Target = Diagnostic;
fn deref(&self) -> &Self::Target {
self.message
}
}
fn group_diagnostics_by_filename(
diagnostics: &[Diagnostic],
) -> BTreeMap<String, Vec<MessageWithLocation<'_>>> {
let mut grouped_messages = BTreeMap::default();
for diagnostic in diagnostics {
grouped_messages
.entry(diagnostic.expect_ruff_filename())
.or_insert_with(Vec::new)
.push(MessageWithLocation {
message: diagnostic,
start_location: diagnostic.expect_ruff_start_location(),
});
}
grouped_messages
}
/// Display format for [`Diagnostic`]s.
///
/// The emitter serializes a slice of [`Diagnostic`]s and writes them to a [`Write`].

View File

@@ -5,7 +5,7 @@ expression: redact_fingerprint(&content)
[
{
"check_name": "F401",
"description": "F401: `os` imported but unused",
"description": "`os` imported but unused",
"fingerprint": "<redacted>",
"location": {
"path": "fib.py",
@@ -24,7 +24,7 @@ expression: redact_fingerprint(&content)
},
{
"check_name": "F841",
"description": "F841: Local variable `x` is assigned to but never used",
"description": "Local variable `x` is assigned to but never used",
"fingerprint": "<redacted>",
"location": {
"path": "fib.py",
@@ -43,7 +43,7 @@ expression: redact_fingerprint(&content)
},
{
"check_name": "F821",
"description": "F821: Undefined name `a`",
"description": "Undefined name `a`",
"fingerprint": "<redacted>",
"location": {
"path": "undef.py",

View File

@@ -4,8 +4,8 @@ expression: redact_fingerprint(&content)
---
[
{
"check_name": "invalid-syntax",
"description": "invalid-syntax: Expected one or more symbol names after import",
"check_name": "syntax-error",
"description": "Expected one or more symbol names after import",
"fingerprint": "<redacted>",
"location": {
"path": "syntax_errors.py",
@@ -23,8 +23,8 @@ expression: redact_fingerprint(&content)
"severity": "major"
},
{
"check_name": "invalid-syntax",
"description": "invalid-syntax: Expected ')', found newline",
"check_name": "syntax-error",
"description": "Expected ')', found newline",
"fingerprint": "<redacted>",
"location": {
"path": "syntax_errors.py",

View File

@@ -1,10 +1,30 @@
---
source: crates/ruff_linter/src/message/grouped.rs
expression: content
snapshot_kind: text
---
fib.py:
1:8 F401 `os` imported but unused
|
1 | import os
| ^^ F401
|
= help: Remove unused import: `os`
6:5 F841 Local variable `x` is assigned to but never used
|
4 | def fibonacci(n):
5 | """Compute the nth number in the Fibonacci sequence."""
6 | x = 1
| ^ F841
7 | if n == 0:
8 | return 0
|
= help: Remove assignment to unused variable `x`
undef.py:
1:4 F821 Undefined name `a`
|
1 | if a == 1: pass
| ^ F821
|

View File

@@ -1,10 +1,30 @@
---
source: crates/ruff_linter/src/message/grouped.rs
expression: content
snapshot_kind: text
---
fib.py:
1:8 F401 [*] `os` imported but unused
|
1 | import os
| ^^ F401
|
= help: Remove unused import: `os`
6:5 F841 [*] Local variable `x` is assigned to but never used
|
4 | def fibonacci(n):
5 | """Compute the nth number in the Fibonacci sequence."""
6 | x = 1
| ^ F841
7 | if n == 0:
8 | return 0
|
= help: Remove assignment to unused variable `x`
undef.py:
1:4 F821 Undefined name `a`
|
1 | if a == 1: pass
| ^ F821
|

View File

@@ -0,0 +1,30 @@
---
source: crates/ruff_linter/src/message/grouped.rs
expression: content
snapshot_kind: text
---
fib.py:
1:8 F401 `os` imported but unused
|
1 | import os
| ^^ F401
|
= help: Remove unused import: `os`
6:5 F841 Local variable `x` is assigned to but never used
|
4 | def fibonacci(n):
5 | """Compute the nth number in the Fibonacci sequence."""
6 | x = 1
| ^ F841
7 | if n == 0:
8 | return 0
|
= help: Remove assignment to unused variable `x`
undef.py:
1:4 F821 Undefined name `a`
|
1 | if a == 1: pass
| ^ F821
|

View File

@@ -1,30 +1,28 @@
---
source: crates/ruff_linter/src/message/text.rs
expression: content
snapshot_kind: text
---
F401 `os` imported but unused
--> fib.py:1:8
fib.py:1:8: F401 `os` imported but unused
|
1 | import os
| ^^
| ^^ F401
|
help: Remove unused import: `os`
= help: Remove unused import: `os`
F841 Local variable `x` is assigned to but never used
--> fib.py:6:5
fib.py:6:5: F841 Local variable `x` is assigned to but never used
|
4 | def fibonacci(n):
5 | """Compute the nth number in the Fibonacci sequence."""
6 | x = 1
| ^
| ^ F841
7 | if n == 0:
8 | return 0
|
help: Remove assignment to unused variable `x`
= help: Remove assignment to unused variable `x`
F821 Undefined name `a`
--> undef.py:1:4
undef.py:1:4: F821 Undefined name `a`
|
1 | if a == 1: pass
| ^
| ^ F821
|

View File

@@ -1,30 +1,28 @@
---
source: crates/ruff_linter/src/message/text.rs
expression: content
snapshot_kind: text
---
F401 `os` imported but unused
--> fib.py:1:8
fib.py:1:8: F401 `os` imported but unused
|
1 | import os
| ^^
| ^^ F401
|
help: Remove unused import: `os`
= help: Remove unused import: `os`
F841 Local variable `x` is assigned to but never used
--> fib.py:6:5
fib.py:6:5: F841 Local variable `x` is assigned to but never used
|
4 | def fibonacci(n):
5 | """Compute the nth number in the Fibonacci sequence."""
6 | x = 1
| ^
| ^ F841
7 | if n == 0:
8 | return 0
|
help: Remove assignment to unused variable `x`
= help: Remove assignment to unused variable `x`
F821 Undefined name `a`
--> undef.py:1:4
undef.py:1:4: F821 Undefined name `a`
|
1 | if a == 1: pass
| ^
| ^ F821
|

View File

@@ -1,30 +1,28 @@
---
source: crates/ruff_linter/src/message/text.rs
expression: content
snapshot_kind: text
---
F401 [*] `os` imported but unused
--> fib.py:1:8
fib.py:1:8: F401 [*] `os` imported but unused
|
1 | import os
| ^^
| ^^ F401
|
help: Remove unused import: `os`
= help: Remove unused import: `os`
F841 [*] Local variable `x` is assigned to but never used
--> fib.py:6:5
fib.py:6:5: F841 [*] Local variable `x` is assigned to but never used
|
4 | def fibonacci(n):
5 | """Compute the nth number in the Fibonacci sequence."""
6 | x = 1
| ^
| ^ F841
7 | if n == 0:
8 | return 0
|
help: Remove assignment to unused variable `x`
= help: Remove assignment to unused variable `x`
F821 Undefined name `a`
--> undef.py:1:4
undef.py:1:4: F821 Undefined name `a`
|
1 | if a == 1: pass
| ^
| ^ F821
|

View File

@@ -2,32 +2,29 @@
source: crates/ruff_linter/src/message/text.rs
expression: content
---
F401 [*] `os` imported but unused
--> notebook.ipynb:cell 1:2:8
notebook.ipynb:cell 1:2:8: F401 [*] `os` imported but unused
|
1 | # cell 1
2 | import os
| ^^
| ^^ F401
|
help: Remove unused import: `os`
= help: Remove unused import: `os`
F401 [*] `math` imported but unused
--> notebook.ipynb:cell 2:2:8
notebook.ipynb:cell 2:2:8: F401 [*] `math` imported but unused
|
1 | # cell 2
2 | import math
| ^^^^
| ^^^^ F401
3 |
4 | print('hello world')
|
help: Remove unused import: `math`
= help: Remove unused import: `math`
F841 [*] Local variable `x` is assigned to but never used
--> notebook.ipynb:cell 3:4:5
notebook.ipynb:cell 3:4:5: F841 [*] Local variable `x` is assigned to but never used
|
2 | def foo():
3 | print()
4 | x = 1
| ^
| ^ F841
|
help: Remove assignment to unused variable `x`
= help: Remove assignment to unused variable `x`

View File

@@ -2,17 +2,16 @@
source: crates/ruff_linter/src/message/text.rs
expression: content
---
invalid-syntax: Expected one or more symbol names after import
--> syntax_errors.py:1:15
syntax_errors.py:1:15: invalid-syntax: Expected one or more symbol names after import
|
1 | from os import
| ^
2 |
3 | if call(foo
4 | def bar():
|
invalid-syntax: Expected ')', found newline
--> syntax_errors.py:3:12
syntax_errors.py:3:12: invalid-syntax: Expected ')', found newline
|
1 | from os import
2 |

View File

@@ -1,19 +1,41 @@
use std::borrow::Cow;
use std::fmt::{Display, Formatter};
use std::io::Write;
use ruff_db::diagnostic::{
Diagnostic, DiagnosticFormat, DisplayDiagnosticConfig, DisplayDiagnostics,
};
use bitflags::bitflags;
use colored::Colorize;
use ruff_annotate_snippets::{Level, Renderer, Snippet};
use ruff_db::diagnostic::{
Diagnostic, DiagnosticFormat, DisplayDiagnosticConfig, SecondaryCode, ceil_char_boundary,
};
use ruff_notebook::NotebookIndex;
use ruff_source_file::OneIndexed;
use ruff_text_size::{TextLen, TextRange, TextSize};
use crate::message::diff::Diff;
use crate::message::{Emitter, EmitterContext};
use crate::settings::types::UnsafeFixes;
bitflags! {
#[derive(Default)]
struct EmitterFlags: u8 {
/// Whether to show the diff of a fix, for diagnostics that have a fix.
const SHOW_FIX_DIFF = 1 << 1;
/// Whether to show the source code of a diagnostic.
const SHOW_SOURCE = 1 << 2;
}
}
pub struct TextEmitter {
flags: EmitterFlags,
config: DisplayDiagnosticConfig,
}
impl Default for TextEmitter {
fn default() -> Self {
Self {
flags: EmitterFlags::default(),
config: DisplayDiagnosticConfig::default()
.format(DiagnosticFormat::Concise)
.hide_severity(true)
@@ -31,17 +53,13 @@ impl TextEmitter {
#[must_use]
pub fn with_show_fix_diff(mut self, show_fix_diff: bool) -> Self {
self.config = self.config.show_fix_diff(show_fix_diff);
self.flags.set(EmitterFlags::SHOW_FIX_DIFF, show_fix_diff);
self
}
#[must_use]
pub fn with_show_source(mut self, show_source: bool) -> Self {
self.config = self.config.format(if show_source {
DiagnosticFormat::Full
} else {
DiagnosticFormat::Concise
});
self.flags.set(EmitterFlags::SHOW_SOURCE, show_source);
self
}
@@ -73,16 +91,297 @@ impl Emitter for TextEmitter {
diagnostics: &[Diagnostic],
context: &EmitterContext,
) -> anyhow::Result<()> {
write!(
writer,
"{}",
DisplayDiagnostics::new(context, &self.config, diagnostics)
)?;
for message in diagnostics {
write!(writer, "{}", message.display(context, &self.config))?;
let filename = message.expect_ruff_filename();
let notebook_index = context.notebook_index(&filename);
if self.flags.intersects(EmitterFlags::SHOW_SOURCE) {
// The `0..0` range is used to highlight file-level diagnostics.
if message.expect_range() != TextRange::default() {
writeln!(
writer,
"{}",
MessageCodeFrame {
message,
notebook_index
}
)?;
}
}
if self.flags.intersects(EmitterFlags::SHOW_FIX_DIFF) {
if let Some(diff) = Diff::from_message(message) {
writeln!(writer, "{diff}")?;
}
}
}
Ok(())
}
}
pub(super) struct RuleCodeAndBody<'a> {
pub(crate) message: &'a Diagnostic,
pub(crate) show_fix_status: bool,
pub(crate) unsafe_fixes: UnsafeFixes,
}
impl Display for RuleCodeAndBody<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
if self.show_fix_status {
if let Some(fix) = self.message.fix() {
// Do not display an indicator for inapplicable fixes
if fix.applies(self.unsafe_fixes.required_applicability()) {
if let Some(code) = self.message.secondary_code() {
write!(f, "{} ", code.red().bold())?;
}
return write!(
f,
"{fix}{body}",
fix = format_args!("[{}] ", "*".cyan()),
body = self.message.body(),
);
}
}
}
if let Some(code) = self.message.secondary_code() {
write!(
f,
"{code} {body}",
code = code.red().bold(),
body = self.message.body(),
)
} else {
write!(
f,
"{code}: {body}",
code = self.message.id().as_str().red().bold(),
body = self.message.body(),
)
}
}
}
pub(super) struct MessageCodeFrame<'a> {
pub(crate) message: &'a Diagnostic,
pub(crate) notebook_index: Option<&'a NotebookIndex>,
}
impl Display for MessageCodeFrame<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let suggestion = self.message.first_help_text();
let footers = if let Some(suggestion) = suggestion {
vec![Level::Help.title(suggestion)]
} else {
Vec::new()
};
let source_file = self.message.expect_ruff_source_file();
let source_code = source_file.to_source_code();
let content_start_index = source_code.line_index(self.message.expect_range().start());
let mut start_index = content_start_index.saturating_sub(2);
// If we're working with a Jupyter Notebook, skip the lines which are
// outside of the cell containing the diagnostic.
if let Some(index) = self.notebook_index {
let content_start_cell = index.cell(content_start_index).unwrap_or(OneIndexed::MIN);
while start_index < content_start_index {
if index.cell(start_index).unwrap_or(OneIndexed::MIN) == content_start_cell {
break;
}
start_index = start_index.saturating_add(1);
}
}
// Trim leading empty lines.
while start_index < content_start_index {
if !source_code.line_text(start_index).trim().is_empty() {
break;
}
start_index = start_index.saturating_add(1);
}
let content_end_index = source_code.line_index(self.message.expect_range().end());
let mut end_index = content_end_index
.saturating_add(2)
.min(OneIndexed::from_zero_indexed(source_code.line_count()));
// If we're working with a Jupyter Notebook, skip the lines which are
// outside of the cell containing the diagnostic.
if let Some(index) = self.notebook_index {
let content_end_cell = index.cell(content_end_index).unwrap_or(OneIndexed::MIN);
while end_index > content_end_index {
if index.cell(end_index).unwrap_or(OneIndexed::MIN) == content_end_cell {
break;
}
end_index = end_index.saturating_sub(1);
}
}
// Trim trailing empty lines.
while end_index > content_end_index {
if !source_code.line_text(end_index).trim().is_empty() {
break;
}
end_index = end_index.saturating_sub(1);
}
let start_offset = source_code.line_start(start_index);
let end_offset = source_code.line_end(end_index);
let source = replace_unprintable(
source_code.slice(TextRange::new(start_offset, end_offset)),
self.message.expect_range() - start_offset,
)
.fix_up_empty_spans_after_line_terminator();
let label = self
.message
.secondary_code()
.map(SecondaryCode::as_str)
.unwrap_or_default();
let line_start = self.notebook_index.map_or_else(
|| start_index.get(),
|notebook_index| {
notebook_index
.cell_row(start_index)
.unwrap_or(OneIndexed::MIN)
.get()
},
);
let span = usize::from(source.annotation_range.start())
..usize::from(source.annotation_range.end());
let annotation = Level::Error.span(span).label(label);
let snippet = Snippet::source(&source.text)
.line_start(line_start)
.annotation(annotation)
.fold(false);
let message = Level::None.title("").snippet(snippet).footers(footers);
let renderer = if !cfg!(test) && colored::control::SHOULD_COLORIZE.should_colorize() {
Renderer::styled()
} else {
Renderer::plain()
}
.cut_indicator("");
let rendered = renderer.render(message);
writeln!(f, "{rendered}")
}
}
/// Given some source code and an annotation range, this routine replaces
/// unprintable characters with printable representations of them.
///
/// The source code returned has an annotation that is updated to reflect
/// changes made to the source code (if any).
///
/// We don't need to normalize whitespace, such as converting tabs to spaces,
/// because `annotate-snippets` handles that internally. Similarly, it's safe to
/// modify the annotation ranges by inserting 3-byte Unicode replacements
/// because `annotate-snippets` will account for their actual width when
/// rendering and displaying the column to the user.
fn replace_unprintable(source: &str, annotation_range: TextRange) -> SourceCode<'_> {
let mut result = String::new();
let mut last_end = 0;
let mut range = annotation_range;
// Updates the range given by the caller whenever a single byte (at
// `index` in `source`) is replaced with `len` bytes.
//
// When the index occurs before the start of the range, the range is
// offset by `len`. When the range occurs after or at the start but before
// the end, then the end of the range only is offset by `len`.
let mut update_range = |index, len| {
if index < usize::from(annotation_range.start()) {
range += TextSize::new(len - 1);
} else if index < usize::from(annotation_range.end()) {
range = range.add_end(TextSize::new(len - 1));
}
};
// If `c` is an unprintable character, then this returns a printable
// representation of it (using a fancier Unicode codepoint).
let unprintable_replacement = |c: char| -> Option<char> {
match c {
'\x07' => Some('␇'),
'\x08' => Some('␈'),
'\x1b' => Some('␛'),
'\x7f' => Some('␡'),
_ => None,
}
};
for (index, c) in source.char_indices() {
if let Some(printable) = unprintable_replacement(c) {
result.push_str(&source[last_end..index]);
result.push(printable);
last_end = index + 1;
let len = printable.text_len().to_u32();
update_range(index, len);
}
}
// No tabs or unprintable chars
if result.is_empty() {
SourceCode {
annotation_range,
text: Cow::Borrowed(source),
}
} else {
result.push_str(&source[last_end..]);
SourceCode {
annotation_range: range,
text: Cow::Owned(result),
}
}
}
struct SourceCode<'a> {
text: Cow<'a, str>,
annotation_range: TextRange,
}
impl<'a> SourceCode<'a> {
/// This attempts to "fix up" the span on `SourceCode` in the case where
/// it's an empty span immediately following a line terminator.
///
/// At present, `annotate-snippets` (both upstream and our vendored copy)
/// will render annotations of such spans to point to the space immediately
/// following the previous line. But ideally, this should point to the space
/// immediately preceding the next line.
///
/// After attempting to fix `annotate-snippets` and giving up after a couple
/// hours, this routine takes a different tact: it adjusts the span to be
/// non-empty and it will cover the first codepoint of the following line.
/// This forces `annotate-snippets` to point to the right place.
///
/// See also: <https://github.com/astral-sh/ruff/issues/15509>
fn fix_up_empty_spans_after_line_terminator(self) -> SourceCode<'a> {
if !self.annotation_range.is_empty()
|| self.annotation_range.start() == TextSize::from(0)
|| self.annotation_range.start() >= self.text.text_len()
{
return self;
}
if self.text.as_bytes()[self.annotation_range.start().to_usize() - 1] != b'\n' {
return self;
}
let start = self.annotation_range.start();
let end = ceil_char_boundary(&self.text, start + TextSize::from(1));
SourceCode {
annotation_range: TextRange::new(start, end),
..self
}
}
}
#[cfg(test)]
mod tests {
use insta::assert_snapshot;

View File

@@ -159,16 +159,6 @@ pub(crate) const fn is_fix_os_getcwd_enabled(settings: &LinterSettings) -> bool
settings.preview.is_enabled()
}
// https://github.com/astral-sh/ruff/pull/19514
pub(crate) const fn is_fix_os_mkdir_enabled(settings: &LinterSettings) -> bool {
settings.preview.is_enabled()
}
// https://github.com/astral-sh/ruff/pull/19514
pub(crate) const fn is_fix_os_makedirs_enabled(settings: &LinterSettings) -> bool {
settings.preview.is_enabled()
}
// https://github.com/astral-sh/ruff/pull/11436
// https://github.com/astral-sh/ruff/pull/11168
pub(crate) const fn is_dunder_init_fix_unused_import_enabled(settings: &LinterSettings) -> bool {
@@ -240,8 +230,3 @@ pub(crate) const fn is_add_future_annotations_imports_enabled(settings: &LinterS
pub(crate) const fn is_trailing_comma_type_params_enabled(settings: &LinterSettings) -> bool {
settings.preview.is_enabled()
}
// https://github.com/astral-sh/ruff/pull/19851
pub(crate) const fn is_maxsplit_without_separator_fix_enabled(settings: &LinterSettings) -> bool {
settings.preview.is_enabled()
}

View File

@@ -710,10 +710,6 @@ fn check_name(checker: &Checker, expr: &Expr, range: TextRange) {
},
// airflow.secrets
["airflow", "secrets", "cache", "SecretCache"] => Replacement::AutoImport {
module: "airflow.sdk",
name: "SecretCache",
},
["airflow", "secrets", "local_filesystem", "load_connections"] => Replacement::AutoImport {
module: "airflow.secrets.local_filesystem",
name: "load_connections_dict",

View File

@@ -1,32 +1,29 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR001 Task variable name should match the `task_id`: "my_task"
--> AIR001.py:11:1
AIR001.py:11:1: AIR001 Task variable name should match the `task_id`: "my_task"
|
10 | my_task = PythonOperator(task_id="my_task", callable=my_callable)
11 | incorrect_name = PythonOperator(task_id="my_task") # AIR001
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ AIR001
12 |
13 | my_task = AirbyteTriggerSyncOperator(task_id="my_task", callable=my_callable)
|
AIR001 Task variable name should match the `task_id`: "my_task"
--> AIR001.py:14:1
AIR001.py:14:1: AIR001 Task variable name should match the `task_id`: "my_task"
|
13 | my_task = AirbyteTriggerSyncOperator(task_id="my_task", callable=my_callable)
14 | incorrect_name = AirbyteTriggerSyncOperator(task_id="my_task") # AIR001
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ AIR001
15 |
16 | my_task = AppflowFlowRunOperator(task_id="my_task", callable=my_callable)
|
AIR001 Task variable name should match the `task_id`: "my_task"
--> AIR001.py:17:1
AIR001.py:17:1: AIR001 Task variable name should match the `task_id`: "my_task"
|
16 | my_task = AppflowFlowRunOperator(task_id="my_task", callable=my_callable)
17 | incorrect_name = AppflowFlowRunOperator(task_id="my_task") # AIR001
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ AIR001
18 |
19 | # Consider only from the `airflow.operators` (or providers operators) module
|

View File

@@ -1,22 +1,20 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR002 DAG should have an explicit `schedule` argument
--> AIR002.py:4:1
AIR002.py:4:1: AIR002 DAG should have an explicit `schedule` argument
|
2 | from airflow.timetables.simple import NullTimetable
3 |
4 | DAG(dag_id="class_default_schedule")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR002
5 |
6 | DAG(dag_id="class_schedule", schedule="@hourly")
|
AIR002 DAG should have an explicit `schedule` argument
--> AIR002.py:13:2
AIR002.py:13:2: AIR002 DAG should have an explicit `schedule` argument
|
13 | @dag()
| ^^^^^
| ^^^^^ AIR002
14 | def decorator_default_schedule():
15 | pass
|

View File

@@ -1,50 +1,46 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR301 `operators` is removed in Airflow 3.0
--> AIR301_airflow_plugin.py:7:5
AIR301_airflow_plugin.py:7:5: AIR301 `operators` is removed in Airflow 3.0
|
5 | name = "test_plugin"
6 | # --- Invalid extensions start
7 | operators = [PluginOperator]
| ^^^^^^^^^
| ^^^^^^^^^ AIR301
8 | sensors = [PluginSensorOperator]
9 | hooks = [PluginHook]
|
help: This extension should just be imported as a regular python module.
= help: This extension should just be imported as a regular python module.
AIR301 `sensors` is removed in Airflow 3.0
--> AIR301_airflow_plugin.py:8:5
AIR301_airflow_plugin.py:8:5: AIR301 `sensors` is removed in Airflow 3.0
|
6 | # --- Invalid extensions start
7 | operators = [PluginOperator]
8 | sensors = [PluginSensorOperator]
| ^^^^^^^
| ^^^^^^^ AIR301
9 | hooks = [PluginHook]
10 | executors = [PluginExecutor]
|
help: This extension should just be imported as a regular python module.
= help: This extension should just be imported as a regular python module.
AIR301 `hooks` is removed in Airflow 3.0
--> AIR301_airflow_plugin.py:9:5
AIR301_airflow_plugin.py:9:5: AIR301 `hooks` is removed in Airflow 3.0
|
7 | operators = [PluginOperator]
8 | sensors = [PluginSensorOperator]
9 | hooks = [PluginHook]
| ^^^^^
| ^^^^^ AIR301
10 | executors = [PluginExecutor]
11 | # --- Invalid extensions end
|
help: This extension should just be imported as a regular python module.
= help: This extension should just be imported as a regular python module.
AIR301 `executors` is removed in Airflow 3.0
--> AIR301_airflow_plugin.py:10:5
AIR301_airflow_plugin.py:10:5: AIR301 `executors` is removed in Airflow 3.0
|
8 | sensors = [PluginSensorOperator]
9 | hooks = [PluginHook]
10 | executors = [PluginExecutor]
| ^^^^^^^^^
| ^^^^^^^^^ AIR301
11 | # --- Invalid extensions end
12 | macros = [plugin_macro]
|
help: This extension should just be imported as a regular python module.
= help: This extension should just be imported as a regular python module.

View File

@@ -1,17 +1,16 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR301 [*] `schedule_interval` is removed in Airflow 3.0
--> AIR301_args.py:21:39
AIR301_args.py:21:39: AIR301 [*] `schedule_interval` is removed in Airflow 3.0
|
19 | DAG(dag_id="class_schedule", schedule="@hourly")
20 |
21 | DAG(dag_id="class_schedule_interval", schedule_interval="@hourly")
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ AIR301
22 |
23 | DAG(dag_id="class_timetable", timetable=NullTimetable())
|
help: Use `schedule` instead
= help: Use `schedule` instead
Safe fix
18 18 |
@@ -23,15 +22,14 @@ help: Use `schedule` instead
23 23 | DAG(dag_id="class_timetable", timetable=NullTimetable())
24 24 |
AIR301 [*] `timetable` is removed in Airflow 3.0
--> AIR301_args.py:23:31
AIR301_args.py:23:31: AIR301 [*] `timetable` is removed in Airflow 3.0
|
21 | DAG(dag_id="class_schedule_interval", schedule_interval="@hourly")
22 |
23 | DAG(dag_id="class_timetable", timetable=NullTimetable())
| ^^^^^^^^^
| ^^^^^^^^^ AIR301
|
help: Use `schedule` instead
= help: Use `schedule` instead
Safe fix
20 20 |
@@ -43,15 +41,14 @@ help: Use `schedule` instead
25 25 |
26 26 | DAG(dag_id="class_fail_stop", fail_stop=True)
AIR301 [*] `fail_stop` is removed in Airflow 3.0
--> AIR301_args.py:26:31
AIR301_args.py:26:31: AIR301 [*] `fail_stop` is removed in Airflow 3.0
|
26 | DAG(dag_id="class_fail_stop", fail_stop=True)
| ^^^^^^^^^
| ^^^^^^^^^ AIR301
27 |
28 | DAG(dag_id="class_default_view", default_view="dag_default_view")
|
help: Use `fail_fast` instead
= help: Use `fail_fast` instead
Safe fix
23 23 | DAG(dag_id="class_timetable", timetable=NullTimetable())
@@ -63,37 +60,34 @@ help: Use `fail_fast` instead
28 28 | DAG(dag_id="class_default_view", default_view="dag_default_view")
29 29 |
AIR301 `default_view` is removed in Airflow 3.0
--> AIR301_args.py:28:34
AIR301_args.py:28:34: AIR301 `default_view` is removed in Airflow 3.0
|
26 | DAG(dag_id="class_fail_stop", fail_stop=True)
27 |
28 | DAG(dag_id="class_default_view", default_view="dag_default_view")
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ AIR301
29 |
30 | DAG(dag_id="class_orientation", orientation="BT")
|
AIR301 `orientation` is removed in Airflow 3.0
--> AIR301_args.py:30:33
AIR301_args.py:30:33: AIR301 `orientation` is removed in Airflow 3.0
|
28 | DAG(dag_id="class_default_view", default_view="dag_default_view")
29 |
30 | DAG(dag_id="class_orientation", orientation="BT")
| ^^^^^^^^^^^
| ^^^^^^^^^^^ AIR301
31 |
32 | allow_future_exec_dates_dag = DAG(dag_id="class_allow_future_exec_dates")
|
AIR301 [*] `schedule_interval` is removed in Airflow 3.0
--> AIR301_args.py:41:6
AIR301_args.py:41:6: AIR301 [*] `schedule_interval` is removed in Airflow 3.0
|
41 | @dag(schedule_interval="0 * * * *")
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ AIR301
42 | def decorator_schedule_interval():
43 | pass
|
help: Use `schedule` instead
= help: Use `schedule` instead
Safe fix
38 38 | pass
@@ -105,15 +99,14 @@ help: Use `schedule` instead
43 43 | pass
44 44 |
AIR301 [*] `timetable` is removed in Airflow 3.0
--> AIR301_args.py:46:6
AIR301_args.py:46:6: AIR301 [*] `timetable` is removed in Airflow 3.0
|
46 | @dag(timetable=NullTimetable())
| ^^^^^^^^^
| ^^^^^^^^^ AIR301
47 | def decorator_timetable():
48 | pass
|
help: Use `schedule` instead
= help: Use `schedule` instead
Safe fix
43 43 | pass
@@ -125,17 +118,16 @@ help: Use `schedule` instead
48 48 | pass
49 49 |
AIR301 [*] `execution_date` is removed in Airflow 3.0
--> AIR301_args.py:54:62
AIR301_args.py:54:62: AIR301 [*] `execution_date` is removed in Airflow 3.0
|
52 | def decorator_deprecated_operator_args():
53 | trigger_dagrun_op = trigger_dagrun.TriggerDagRunOperator(
54 | task_id="trigger_dagrun_op1", trigger_dag_id="test", execution_date="2024-12-04"
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ AIR301
55 | )
56 | trigger_dagrun_op2 = TriggerDagRunOperator(
|
help: Use `logical_date` instead
= help: Use `logical_date` instead
Safe fix
51 51 | @dag()
@@ -147,16 +139,15 @@ help: Use `logical_date` instead
56 56 | trigger_dagrun_op2 = TriggerDagRunOperator(
57 57 | task_id="trigger_dagrun_op2", trigger_dag_id="test", execution_date="2024-12-04"
AIR301 [*] `execution_date` is removed in Airflow 3.0
--> AIR301_args.py:57:62
AIR301_args.py:57:62: AIR301 [*] `execution_date` is removed in Airflow 3.0
|
55 | )
56 | trigger_dagrun_op2 = TriggerDagRunOperator(
57 | task_id="trigger_dagrun_op2", trigger_dag_id="test", execution_date="2024-12-04"
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ AIR301
58 | )
|
help: Use `logical_date` instead
= help: Use `logical_date` instead
Safe fix
54 54 | task_id="trigger_dagrun_op1", trigger_dag_id="test", execution_date="2024-12-04"
@@ -168,16 +159,15 @@ help: Use `logical_date` instead
59 59 |
60 60 | branch_dt_op = datetime.BranchDateTimeOperator(
AIR301 [*] `use_task_execution_day` is removed in Airflow 3.0
--> AIR301_args.py:61:33
AIR301_args.py:61:33: AIR301 [*] `use_task_execution_day` is removed in Airflow 3.0
|
60 | branch_dt_op = datetime.BranchDateTimeOperator(
61 | task_id="branch_dt_op", use_task_execution_day=True, task_concurrency=5
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^ AIR301
62 | )
63 | branch_dt_op2 = BranchDateTimeOperator(
|
help: Use `use_task_logical_date` instead
= help: Use `use_task_logical_date` instead
Safe fix
58 58 | )
@@ -189,16 +179,15 @@ help: Use `use_task_logical_date` instead
63 63 | branch_dt_op2 = BranchDateTimeOperator(
64 64 | task_id="branch_dt_op2",
AIR301 [*] `task_concurrency` is removed in Airflow 3.0
--> AIR301_args.py:61:62
AIR301_args.py:61:62: AIR301 [*] `task_concurrency` is removed in Airflow 3.0
|
60 | branch_dt_op = datetime.BranchDateTimeOperator(
61 | task_id="branch_dt_op", use_task_execution_day=True, task_concurrency=5
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^ AIR301
62 | )
63 | branch_dt_op2 = BranchDateTimeOperator(
|
help: Use `max_active_tis_per_dag` instead
= help: Use `max_active_tis_per_dag` instead
Safe fix
58 58 | )
@@ -210,17 +199,16 @@ help: Use `max_active_tis_per_dag` instead
63 63 | branch_dt_op2 = BranchDateTimeOperator(
64 64 | task_id="branch_dt_op2",
AIR301 [*] `use_task_execution_day` is removed in Airflow 3.0
--> AIR301_args.py:65:9
AIR301_args.py:65:9: AIR301 [*] `use_task_execution_day` is removed in Airflow 3.0
|
63 | branch_dt_op2 = BranchDateTimeOperator(
64 | task_id="branch_dt_op2",
65 | use_task_execution_day=True,
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^ AIR301
66 | sla=timedelta(seconds=10),
67 | )
|
help: Use `use_task_logical_date` instead
= help: Use `use_task_logical_date` instead
Safe fix
62 62 | )
@@ -232,16 +220,15 @@ help: Use `use_task_logical_date` instead
67 67 | )
68 68 |
AIR301 [*] `use_task_execution_day` is removed in Airflow 3.0
--> AIR301_args.py:92:9
AIR301_args.py:92:9: AIR301 [*] `use_task_execution_day` is removed in Airflow 3.0
|
90 | follow_task_ids_if_true=None,
91 | week_day=1,
92 | use_task_execution_day=True,
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^ AIR301
93 | )
|
help: Use `use_task_logical_date` instead
= help: Use `use_task_logical_date` instead
Safe fix
89 89 | follow_task_ids_if_false=None,
@@ -253,54 +240,49 @@ help: Use `use_task_logical_date` instead
94 94 |
95 95 | trigger_dagrun_op >> trigger_dagrun_op2
AIR301 `filename_template` is removed in Airflow 3.0
--> AIR301_args.py:102:15
AIR301_args.py:102:15: AIR301 `filename_template` is removed in Airflow 3.0
|
101 | # deprecated filename_template argument in FileTaskHandler
102 | S3TaskHandler(filename_template="/tmp/test")
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ AIR301
103 | HdfsTaskHandler(filename_template="/tmp/test")
104 | ElasticsearchTaskHandler(filename_template="/tmp/test")
|
AIR301 `filename_template` is removed in Airflow 3.0
--> AIR301_args.py:103:17
AIR301_args.py:103:17: AIR301 `filename_template` is removed in Airflow 3.0
|
101 | # deprecated filename_template argument in FileTaskHandler
102 | S3TaskHandler(filename_template="/tmp/test")
103 | HdfsTaskHandler(filename_template="/tmp/test")
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ AIR301
104 | ElasticsearchTaskHandler(filename_template="/tmp/test")
105 | GCSTaskHandler(filename_template="/tmp/test")
|
AIR301 `filename_template` is removed in Airflow 3.0
--> AIR301_args.py:104:26
AIR301_args.py:104:26: AIR301 `filename_template` is removed in Airflow 3.0
|
102 | S3TaskHandler(filename_template="/tmp/test")
103 | HdfsTaskHandler(filename_template="/tmp/test")
104 | ElasticsearchTaskHandler(filename_template="/tmp/test")
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ AIR301
105 | GCSTaskHandler(filename_template="/tmp/test")
|
AIR301 `filename_template` is removed in Airflow 3.0
--> AIR301_args.py:105:16
AIR301_args.py:105:16: AIR301 `filename_template` is removed in Airflow 3.0
|
103 | HdfsTaskHandler(filename_template="/tmp/test")
104 | ElasticsearchTaskHandler(filename_template="/tmp/test")
105 | GCSTaskHandler(filename_template="/tmp/test")
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ AIR301
106 |
107 | FabAuthManager(None)
|
AIR301 `appbuilder` is removed in Airflow 3.0
--> AIR301_args.py:107:15
AIR301_args.py:107:15: AIR301 `appbuilder` is removed in Airflow 3.0
|
105 | GCSTaskHandler(filename_template="/tmp/test")
106 |
107 | FabAuthManager(None)
| ^^^^^^
| ^^^^^^ AIR301
|
help: The constructor takes no parameter now
= help: The constructor takes no parameter now

View File

@@ -1,16 +1,15 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR301 [*] `iter_datasets` is removed in Airflow 3.0
--> AIR301_class_attribute.py:25:19
AIR301_class_attribute.py:25:19: AIR301 [*] `iter_datasets` is removed in Airflow 3.0
|
23 | # airflow.Dataset
24 | dataset_from_root = DatasetFromRoot()
25 | dataset_from_root.iter_datasets()
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^ AIR301
26 | dataset_from_root.iter_dataset_aliases()
|
help: Use `iter_assets` instead
= help: Use `iter_assets` instead
Safe fix
22 22 |
@@ -22,17 +21,16 @@ help: Use `iter_assets` instead
27 27 |
28 28 | # airflow.datasets
AIR301 [*] `iter_dataset_aliases` is removed in Airflow 3.0
--> AIR301_class_attribute.py:26:19
AIR301_class_attribute.py:26:19: AIR301 [*] `iter_dataset_aliases` is removed in Airflow 3.0
|
24 | dataset_from_root = DatasetFromRoot()
25 | dataset_from_root.iter_datasets()
26 | dataset_from_root.iter_dataset_aliases()
| ^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^ AIR301
27 |
28 | # airflow.datasets
|
help: Use `iter_asset_aliases` instead
= help: Use `iter_asset_aliases` instead
Safe fix
23 23 | # airflow.Dataset
@@ -44,16 +42,15 @@ help: Use `iter_asset_aliases` instead
28 28 | # airflow.datasets
29 29 | dataset_to_test_method_call = Dataset()
AIR301 [*] `iter_datasets` is removed in Airflow 3.0
--> AIR301_class_attribute.py:30:29
AIR301_class_attribute.py:30:29: AIR301 [*] `iter_datasets` is removed in Airflow 3.0
|
28 | # airflow.datasets
29 | dataset_to_test_method_call = Dataset()
30 | dataset_to_test_method_call.iter_datasets()
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^ AIR301
31 | dataset_to_test_method_call.iter_dataset_aliases()
|
help: Use `iter_assets` instead
= help: Use `iter_assets` instead
Safe fix
27 27 |
@@ -65,17 +62,16 @@ help: Use `iter_assets` instead
32 32 |
33 33 | alias_to_test_method_call = DatasetAlias()
AIR301 [*] `iter_dataset_aliases` is removed in Airflow 3.0
--> AIR301_class_attribute.py:31:29
AIR301_class_attribute.py:31:29: AIR301 [*] `iter_dataset_aliases` is removed in Airflow 3.0
|
29 | dataset_to_test_method_call = Dataset()
30 | dataset_to_test_method_call.iter_datasets()
31 | dataset_to_test_method_call.iter_dataset_aliases()
| ^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^ AIR301
32 |
33 | alias_to_test_method_call = DatasetAlias()
|
help: Use `iter_asset_aliases` instead
= help: Use `iter_asset_aliases` instead
Safe fix
28 28 | # airflow.datasets
@@ -87,15 +83,14 @@ help: Use `iter_asset_aliases` instead
33 33 | alias_to_test_method_call = DatasetAlias()
34 34 | alias_to_test_method_call.iter_datasets()
AIR301 [*] `iter_datasets` is removed in Airflow 3.0
--> AIR301_class_attribute.py:34:27
AIR301_class_attribute.py:34:27: AIR301 [*] `iter_datasets` is removed in Airflow 3.0
|
33 | alias_to_test_method_call = DatasetAlias()
34 | alias_to_test_method_call.iter_datasets()
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^ AIR301
35 | alias_to_test_method_call.iter_dataset_aliases()
|
help: Use `iter_assets` instead
= help: Use `iter_assets` instead
Safe fix
31 31 | dataset_to_test_method_call.iter_dataset_aliases()
@@ -107,17 +102,16 @@ help: Use `iter_assets` instead
36 36 |
37 37 | any_to_test_method_call = DatasetAny()
AIR301 [*] `iter_dataset_aliases` is removed in Airflow 3.0
--> AIR301_class_attribute.py:35:27
AIR301_class_attribute.py:35:27: AIR301 [*] `iter_dataset_aliases` is removed in Airflow 3.0
|
33 | alias_to_test_method_call = DatasetAlias()
34 | alias_to_test_method_call.iter_datasets()
35 | alias_to_test_method_call.iter_dataset_aliases()
| ^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^ AIR301
36 |
37 | any_to_test_method_call = DatasetAny()
|
help: Use `iter_asset_aliases` instead
= help: Use `iter_asset_aliases` instead
Safe fix
32 32 |
@@ -129,15 +123,14 @@ help: Use `iter_asset_aliases` instead
37 37 | any_to_test_method_call = DatasetAny()
38 38 | any_to_test_method_call.iter_datasets()
AIR301 [*] `iter_datasets` is removed in Airflow 3.0
--> AIR301_class_attribute.py:38:25
AIR301_class_attribute.py:38:25: AIR301 [*] `iter_datasets` is removed in Airflow 3.0
|
37 | any_to_test_method_call = DatasetAny()
38 | any_to_test_method_call.iter_datasets()
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^ AIR301
39 | any_to_test_method_call.iter_dataset_aliases()
|
help: Use `iter_assets` instead
= help: Use `iter_assets` instead
Safe fix
35 35 | alias_to_test_method_call.iter_dataset_aliases()
@@ -149,17 +142,16 @@ help: Use `iter_assets` instead
40 40 |
41 41 | # airflow.datasets.manager
AIR301 [*] `iter_dataset_aliases` is removed in Airflow 3.0
--> AIR301_class_attribute.py:39:25
AIR301_class_attribute.py:39:25: AIR301 [*] `iter_dataset_aliases` is removed in Airflow 3.0
|
37 | any_to_test_method_call = DatasetAny()
38 | any_to_test_method_call.iter_datasets()
39 | any_to_test_method_call.iter_dataset_aliases()
| ^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^ AIR301
40 |
41 | # airflow.datasets.manager
|
help: Use `iter_asset_aliases` instead
= help: Use `iter_asset_aliases` instead
Safe fix
36 36 |
@@ -171,16 +163,15 @@ help: Use `iter_asset_aliases` instead
41 41 | # airflow.datasets.manager
42 42 | dm = DatasetManager()
AIR301 [*] `airflow.datasets.manager.DatasetManager` is removed in Airflow 3.0
--> AIR301_class_attribute.py:42:6
AIR301_class_attribute.py:42:6: AIR301 [*] `airflow.datasets.manager.DatasetManager` is removed in Airflow 3.0
|
41 | # airflow.datasets.manager
42 | dm = DatasetManager()
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ AIR301
43 | dm.register_dataset_change()
44 | dm.create_datasets()
|
help: Use `AssetManager` from `airflow.assets.manager` instead.
= help: Use `AssetManager` from `airflow.assets.manager` instead.
Safe fix
19 19 | from airflow.providers_manager import ProvidersManager
@@ -200,17 +191,16 @@ help: Use `AssetManager` from `airflow.assets.manager` instead.
44 45 | dm.create_datasets()
45 46 | dm.notify_dataset_created()
AIR301 [*] `register_dataset_change` is removed in Airflow 3.0
--> AIR301_class_attribute.py:43:4
AIR301_class_attribute.py:43:4: AIR301 [*] `register_dataset_change` is removed in Airflow 3.0
|
41 | # airflow.datasets.manager
42 | dm = DatasetManager()
43 | dm.register_dataset_change()
| ^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^ AIR301
44 | dm.create_datasets()
45 | dm.notify_dataset_created()
|
help: Use `register_asset_change` instead
= help: Use `register_asset_change` instead
Safe fix
40 40 |
@@ -222,17 +212,16 @@ help: Use `register_asset_change` instead
45 45 | dm.notify_dataset_created()
46 46 | dm.notify_dataset_changed()
AIR301 [*] `create_datasets` is removed in Airflow 3.0
--> AIR301_class_attribute.py:44:4
AIR301_class_attribute.py:44:4: AIR301 [*] `create_datasets` is removed in Airflow 3.0
|
42 | dm = DatasetManager()
43 | dm.register_dataset_change()
44 | dm.create_datasets()
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^ AIR301
45 | dm.notify_dataset_created()
46 | dm.notify_dataset_changed()
|
help: Use `create_assets` instead
= help: Use `create_assets` instead
Safe fix
41 41 | # airflow.datasets.manager
@@ -244,17 +233,16 @@ help: Use `create_assets` instead
46 46 | dm.notify_dataset_changed()
47 47 | dm.notify_dataset_alias_created()
AIR301 [*] `notify_dataset_created` is removed in Airflow 3.0
--> AIR301_class_attribute.py:45:4
AIR301_class_attribute.py:45:4: AIR301 [*] `notify_dataset_created` is removed in Airflow 3.0
|
43 | dm.register_dataset_change()
44 | dm.create_datasets()
45 | dm.notify_dataset_created()
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^ AIR301
46 | dm.notify_dataset_changed()
47 | dm.notify_dataset_alias_created()
|
help: Use `notify_asset_created` instead
= help: Use `notify_asset_created` instead
Safe fix
42 42 | dm = DatasetManager()
@@ -266,16 +254,15 @@ help: Use `notify_asset_created` instead
47 47 | dm.notify_dataset_alias_created()
48 48 |
AIR301 [*] `notify_dataset_changed` is removed in Airflow 3.0
--> AIR301_class_attribute.py:46:4
AIR301_class_attribute.py:46:4: AIR301 [*] `notify_dataset_changed` is removed in Airflow 3.0
|
44 | dm.create_datasets()
45 | dm.notify_dataset_created()
46 | dm.notify_dataset_changed()
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^ AIR301
47 | dm.notify_dataset_alias_created()
|
help: Use `notify_asset_changed` instead
= help: Use `notify_asset_changed` instead
Safe fix
43 43 | dm.register_dataset_change()
@@ -287,17 +274,16 @@ help: Use `notify_asset_changed` instead
48 48 |
49 49 | # airflow.lineage.hook
AIR301 [*] `notify_dataset_alias_created` is removed in Airflow 3.0
--> AIR301_class_attribute.py:47:4
AIR301_class_attribute.py:47:4: AIR301 [*] `notify_dataset_alias_created` is removed in Airflow 3.0
|
45 | dm.notify_dataset_created()
46 | dm.notify_dataset_changed()
47 | dm.notify_dataset_alias_created()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301
48 |
49 | # airflow.lineage.hook
|
help: Use `notify_asset_alias_created` instead
= help: Use `notify_asset_alias_created` instead
Safe fix
44 44 | dm.create_datasets()
@@ -309,15 +295,14 @@ help: Use `notify_asset_alias_created` instead
49 49 | # airflow.lineage.hook
50 50 | dl_info = DatasetLineageInfo()
AIR301 [*] `airflow.lineage.hook.DatasetLineageInfo` is removed in Airflow 3.0
--> AIR301_class_attribute.py:50:11
AIR301_class_attribute.py:50:11: AIR301 [*] `airflow.lineage.hook.DatasetLineageInfo` is removed in Airflow 3.0
|
49 | # airflow.lineage.hook
50 | dl_info = DatasetLineageInfo()
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^ AIR301
51 | dl_info.dataset
|
help: Use `AssetLineageInfo` from `airflow.lineage.hook` instead.
= help: Use `AssetLineageInfo` from `airflow.lineage.hook` instead.
Safe fix
9 9 | DatasetAny,
@@ -338,17 +323,16 @@ help: Use `AssetLineageInfo` from `airflow.lineage.hook` instead.
52 52 |
53 53 | hlc = HookLineageCollector()
AIR301 [*] `dataset` is removed in Airflow 3.0
--> AIR301_class_attribute.py:51:9
AIR301_class_attribute.py:51:9: AIR301 [*] `dataset` is removed in Airflow 3.0
|
49 | # airflow.lineage.hook
50 | dl_info = DatasetLineageInfo()
51 | dl_info.dataset
| ^^^^^^^
| ^^^^^^^ AIR301
52 |
53 | hlc = HookLineageCollector()
|
help: Use `asset` instead
= help: Use `asset` instead
Safe fix
48 48 |
@@ -360,16 +344,15 @@ help: Use `asset` instead
53 53 | hlc = HookLineageCollector()
54 54 | hlc.create_dataset()
AIR301 [*] `create_dataset` is removed in Airflow 3.0
--> AIR301_class_attribute.py:54:5
AIR301_class_attribute.py:54:5: AIR301 [*] `create_dataset` is removed in Airflow 3.0
|
53 | hlc = HookLineageCollector()
54 | hlc.create_dataset()
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ AIR301
55 | hlc.add_input_dataset()
56 | hlc.add_output_dataset()
|
help: Use `create_asset` instead
= help: Use `create_asset` instead
Safe fix
51 51 | dl_info.dataset
@@ -381,17 +364,16 @@ help: Use `create_asset` instead
56 56 | hlc.add_output_dataset()
57 57 | hlc.collected_datasets()
AIR301 [*] `add_input_dataset` is removed in Airflow 3.0
--> AIR301_class_attribute.py:55:5
AIR301_class_attribute.py:55:5: AIR301 [*] `add_input_dataset` is removed in Airflow 3.0
|
53 | hlc = HookLineageCollector()
54 | hlc.create_dataset()
55 | hlc.add_input_dataset()
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ AIR301
56 | hlc.add_output_dataset()
57 | hlc.collected_datasets()
|
help: Use `add_input_asset` instead
= help: Use `add_input_asset` instead
Safe fix
52 52 |
@@ -403,16 +385,15 @@ help: Use `add_input_asset` instead
57 57 | hlc.collected_datasets()
58 58 |
AIR301 [*] `add_output_dataset` is removed in Airflow 3.0
--> AIR301_class_attribute.py:56:5
AIR301_class_attribute.py:56:5: AIR301 [*] `add_output_dataset` is removed in Airflow 3.0
|
54 | hlc.create_dataset()
55 | hlc.add_input_dataset()
56 | hlc.add_output_dataset()
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^ AIR301
57 | hlc.collected_datasets()
|
help: Use `add_output_asset` instead
= help: Use `add_output_asset` instead
Safe fix
53 53 | hlc = HookLineageCollector()
@@ -424,17 +405,16 @@ help: Use `add_output_asset` instead
58 58 |
59 59 | # airflow.providers.amazon.auth_manager.aws_auth_manager
AIR301 [*] `collected_datasets` is removed in Airflow 3.0
--> AIR301_class_attribute.py:57:5
AIR301_class_attribute.py:57:5: AIR301 [*] `collected_datasets` is removed in Airflow 3.0
|
55 | hlc.add_input_dataset()
56 | hlc.add_output_dataset()
57 | hlc.collected_datasets()
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^ AIR301
58 |
59 | # airflow.providers.amazon.auth_manager.aws_auth_manager
|
help: Use `collected_assets` instead
= help: Use `collected_assets` instead
Safe fix
54 54 | hlc.create_dataset()
@@ -446,17 +426,16 @@ help: Use `collected_assets` instead
59 59 | # airflow.providers.amazon.auth_manager.aws_auth_manager
60 60 | aam = AwsAuthManager()
AIR301 [*] `is_authorized_dataset` is removed in Airflow 3.0
--> AIR301_class_attribute.py:61:5
AIR301_class_attribute.py:61:5: AIR301 [*] `is_authorized_dataset` is removed in Airflow 3.0
|
59 | # airflow.providers.amazon.auth_manager.aws_auth_manager
60 | aam = AwsAuthManager()
61 | aam.is_authorized_dataset()
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ AIR301
62 |
63 | # airflow.providers.apache.beam.hooks
|
help: Use `is_authorized_asset` instead
= help: Use `is_authorized_asset` instead
Safe fix
58 58 |
@@ -468,16 +447,15 @@ help: Use `is_authorized_asset` instead
63 63 | # airflow.providers.apache.beam.hooks
64 64 | # check get_conn_uri is caught if the class inherits from an airflow hook
AIR301 [*] `get_conn_uri` is removed in Airflow 3.0
--> AIR301_class_attribute.py:73:13
AIR301_class_attribute.py:73:13: AIR301 [*] `get_conn_uri` is removed in Airflow 3.0
|
71 | # airflow.providers.google.cloud.secrets.secret_manager
72 | csm_backend = CloudSecretManagerBackend()
73 | csm_backend.get_conn_uri()
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ AIR301
74 | csm_backend.get_connections()
|
help: Use `get_conn_value` instead
= help: Use `get_conn_value` instead
Safe fix
70 70 |
@@ -489,17 +467,16 @@ help: Use `get_conn_value` instead
75 75 |
76 76 | # airflow.providers.hashicorp.secrets.vault
AIR301 [*] `get_connections` is removed in Airflow 3.0
--> AIR301_class_attribute.py:74:13
AIR301_class_attribute.py:74:13: AIR301 [*] `get_connections` is removed in Airflow 3.0
|
72 | csm_backend = CloudSecretManagerBackend()
73 | csm_backend.get_conn_uri()
74 | csm_backend.get_connections()
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^ AIR301
75 |
76 | # airflow.providers.hashicorp.secrets.vault
|
help: Use `get_connection` instead
= help: Use `get_connection` instead
Safe fix
71 71 | # airflow.providers.google.cloud.secrets.secret_manager
@@ -511,16 +488,15 @@ help: Use `get_connection` instead
76 76 | # airflow.providers.hashicorp.secrets.vault
77 77 | vault_backend = VaultBackend()
AIR301 [*] `get_conn_uri` is removed in Airflow 3.0
--> AIR301_class_attribute.py:78:15
AIR301_class_attribute.py:78:15: AIR301 [*] `get_conn_uri` is removed in Airflow 3.0
|
76 | # airflow.providers.hashicorp.secrets.vault
77 | vault_backend = VaultBackend()
78 | vault_backend.get_conn_uri()
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ AIR301
79 | vault_backend.get_connections()
|
help: Use `get_conn_value` instead
= help: Use `get_conn_value` instead
Safe fix
75 75 |
@@ -532,17 +508,16 @@ help: Use `get_conn_value` instead
80 80 |
81 81 | not_an_error = NotAir302SecretError()
AIR301 [*] `get_connections` is removed in Airflow 3.0
--> AIR301_class_attribute.py:79:15
AIR301_class_attribute.py:79:15: AIR301 [*] `get_connections` is removed in Airflow 3.0
|
77 | vault_backend = VaultBackend()
78 | vault_backend.get_conn_uri()
79 | vault_backend.get_connections()
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^ AIR301
80 |
81 | not_an_error = NotAir302SecretError()
|
help: Use `get_connection` instead
= help: Use `get_connection` instead
Safe fix
76 76 | # airflow.providers.hashicorp.secrets.vault
@@ -554,17 +529,16 @@ help: Use `get_connection` instead
81 81 | not_an_error = NotAir302SecretError()
82 82 | not_an_error.get_conn_uri()
AIR301 [*] `initialize_providers_dataset_uri_resources` is removed in Airflow 3.0
--> AIR301_class_attribute.py:86:4
AIR301_class_attribute.py:86:4: AIR301 [*] `initialize_providers_dataset_uri_resources` is removed in Airflow 3.0
|
84 | # airflow.providers_manager
85 | pm = ProvidersManager()
86 | pm.initialize_providers_dataset_uri_resources()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301
87 | pm.dataset_factories
88 | pm.dataset_uri_handlers
|
help: Use `initialize_providers_asset_uri_resources` instead
= help: Use `initialize_providers_asset_uri_resources` instead
Safe fix
83 83 |
@@ -576,17 +550,16 @@ help: Use `initialize_providers_asset_uri_resources` instead
88 88 | pm.dataset_uri_handlers
89 89 | pm.dataset_to_openlineage_converters
AIR301 [*] `dataset_factories` is removed in Airflow 3.0
--> AIR301_class_attribute.py:87:4
AIR301_class_attribute.py:87:4: AIR301 [*] `dataset_factories` is removed in Airflow 3.0
|
85 | pm = ProvidersManager()
86 | pm.initialize_providers_dataset_uri_resources()
87 | pm.dataset_factories
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ AIR301
88 | pm.dataset_uri_handlers
89 | pm.dataset_to_openlineage_converters
|
help: Use `asset_factories` instead
= help: Use `asset_factories` instead
Safe fix
84 84 | # airflow.providers_manager
@@ -598,16 +571,15 @@ help: Use `asset_factories` instead
89 89 | pm.dataset_to_openlineage_converters
90 90 |
AIR301 [*] `dataset_uri_handlers` is removed in Airflow 3.0
--> AIR301_class_attribute.py:88:4
AIR301_class_attribute.py:88:4: AIR301 [*] `dataset_uri_handlers` is removed in Airflow 3.0
|
86 | pm.initialize_providers_dataset_uri_resources()
87 | pm.dataset_factories
88 | pm.dataset_uri_handlers
| ^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^ AIR301
89 | pm.dataset_to_openlineage_converters
|
help: Use `asset_uri_handlers` instead
= help: Use `asset_uri_handlers` instead
Safe fix
85 85 | pm = ProvidersManager()
@@ -619,17 +591,16 @@ help: Use `asset_uri_handlers` instead
90 90 |
91 91 | # airflow.secrets.base_secrets
AIR301 [*] `dataset_to_openlineage_converters` is removed in Airflow 3.0
--> AIR301_class_attribute.py:89:4
AIR301_class_attribute.py:89:4: AIR301 [*] `dataset_to_openlineage_converters` is removed in Airflow 3.0
|
87 | pm.dataset_factories
88 | pm.dataset_uri_handlers
89 | pm.dataset_to_openlineage_converters
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301
90 |
91 | # airflow.secrets.base_secrets
|
help: Use `asset_to_openlineage_converters` instead
= help: Use `asset_to_openlineage_converters` instead
Safe fix
86 86 | pm.initialize_providers_dataset_uri_resources()
@@ -641,16 +612,15 @@ help: Use `asset_to_openlineage_converters` instead
91 91 | # airflow.secrets.base_secrets
92 92 | base_secret_backend = BaseSecretsBackend()
AIR301 [*] `get_conn_uri` is removed in Airflow 3.0
--> AIR301_class_attribute.py:93:21
AIR301_class_attribute.py:93:21: AIR301 [*] `get_conn_uri` is removed in Airflow 3.0
|
91 | # airflow.secrets.base_secrets
92 | base_secret_backend = BaseSecretsBackend()
93 | base_secret_backend.get_conn_uri()
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ AIR301
94 | base_secret_backend.get_connections()
|
help: Use `get_conn_value` instead
= help: Use `get_conn_value` instead
Safe fix
90 90 |
@@ -662,17 +632,16 @@ help: Use `get_conn_value` instead
95 95 |
96 96 | # airflow.secrets.local_filesystem
AIR301 [*] `get_connections` is removed in Airflow 3.0
--> AIR301_class_attribute.py:94:21
AIR301_class_attribute.py:94:21: AIR301 [*] `get_connections` is removed in Airflow 3.0
|
92 | base_secret_backend = BaseSecretsBackend()
93 | base_secret_backend.get_conn_uri()
94 | base_secret_backend.get_connections()
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^ AIR301
95 |
96 | # airflow.secrets.local_filesystem
|
help: Use `get_connection` instead
= help: Use `get_connection` instead
Safe fix
91 91 | # airflow.secrets.base_secrets
@@ -684,15 +653,14 @@ help: Use `get_connection` instead
96 96 | # airflow.secrets.local_filesystem
97 97 | lfb = LocalFilesystemBackend()
AIR301 [*] `get_connections` is removed in Airflow 3.0
--> AIR301_class_attribute.py:98:5
AIR301_class_attribute.py:98:5: AIR301 [*] `get_connections` is removed in Airflow 3.0
|
96 | # airflow.secrets.local_filesystem
97 | lfb = LocalFilesystemBackend()
98 | lfb.get_connections()
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^ AIR301
|
help: Use `get_connection` instead
= help: Use `get_connection` instead
Safe fix
95 95 |

View File

@@ -1,342 +1,310 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR301 `conf` is removed in Airflow 3.0
--> AIR301_context.py:22:41
AIR301_context.py:22:41: AIR301 `conf` is removed in Airflow 3.0
|
20 | @task
21 | def access_invalid_key_task_out_of_dag(**context):
22 | print("access invalid key", context["conf"])
| ^^^^^^
| ^^^^^^ AIR301
23 | print("access invalid key", context.get("conf"))
|
AIR301 `conf` is removed in Airflow 3.0
--> AIR301_context.py:23:45
AIR301_context.py:23:45: AIR301 `conf` is removed in Airflow 3.0
|
21 | def access_invalid_key_task_out_of_dag(**context):
22 | print("access invalid key", context["conf"])
23 | print("access invalid key", context.get("conf"))
| ^^^^^^
| ^^^^^^ AIR301
|
AIR301 `execution_date` is removed in Airflow 3.0
--> AIR301_context.py:28:5
AIR301_context.py:28:5: AIR301 `execution_date` is removed in Airflow 3.0
|
26 | @task
27 | def access_invalid_argument_task_out_of_dag(
28 | execution_date, tomorrow_ds, logical_date, **context
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ AIR301
29 | ):
30 | print("execution date", execution_date)
|
AIR301 `tomorrow_ds` is removed in Airflow 3.0
--> AIR301_context.py:28:21
AIR301_context.py:28:21: AIR301 `tomorrow_ds` is removed in Airflow 3.0
|
26 | @task
27 | def access_invalid_argument_task_out_of_dag(
28 | execution_date, tomorrow_ds, logical_date, **context
| ^^^^^^^^^^^
| ^^^^^^^^^^^ AIR301
29 | ):
30 | print("execution date", execution_date)
|
AIR301 `conf` is removed in Airflow 3.0
--> AIR301_context.py:31:45
AIR301_context.py:31:45: AIR301 `conf` is removed in Airflow 3.0
|
29 | ):
30 | print("execution date", execution_date)
31 | print("access invalid key", context.get("conf"))
| ^^^^^^
| ^^^^^^ AIR301
|
AIR301 `execution_date` is removed in Airflow 3.0
--> AIR301_context.py:40:30
AIR301_context.py:40:30: AIR301 `execution_date` is removed in Airflow 3.0
|
39 | # Removed usage - should trigger violations
40 | execution_date = context["execution_date"]
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^ AIR301
41 | next_ds = context["next_ds"]
42 | next_ds_nodash = context["next_ds_nodash"]
|
AIR301 `next_ds` is removed in Airflow 3.0
--> AIR301_context.py:41:23
AIR301_context.py:41:23: AIR301 `next_ds` is removed in Airflow 3.0
|
39 | # Removed usage - should trigger violations
40 | execution_date = context["execution_date"]
41 | next_ds = context["next_ds"]
| ^^^^^^^^^
| ^^^^^^^^^ AIR301
42 | next_ds_nodash = context["next_ds_nodash"]
43 | next_execution_date = context["next_execution_date"]
|
AIR301 `next_ds_nodash` is removed in Airflow 3.0
--> AIR301_context.py:42:30
AIR301_context.py:42:30: AIR301 `next_ds_nodash` is removed in Airflow 3.0
|
40 | execution_date = context["execution_date"]
41 | next_ds = context["next_ds"]
42 | next_ds_nodash = context["next_ds_nodash"]
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^ AIR301
43 | next_execution_date = context["next_execution_date"]
44 | prev_ds = context["prev_ds"]
|
AIR301 `next_execution_date` is removed in Airflow 3.0
--> AIR301_context.py:43:35
AIR301_context.py:43:35: AIR301 `next_execution_date` is removed in Airflow 3.0
|
41 | next_ds = context["next_ds"]
42 | next_ds_nodash = context["next_ds_nodash"]
43 | next_execution_date = context["next_execution_date"]
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ AIR301
44 | prev_ds = context["prev_ds"]
45 | prev_ds_nodash = context["prev_ds_nodash"]
|
AIR301 `prev_ds` is removed in Airflow 3.0
--> AIR301_context.py:44:23
AIR301_context.py:44:23: AIR301 `prev_ds` is removed in Airflow 3.0
|
42 | next_ds_nodash = context["next_ds_nodash"]
43 | next_execution_date = context["next_execution_date"]
44 | prev_ds = context["prev_ds"]
| ^^^^^^^^^
| ^^^^^^^^^ AIR301
45 | prev_ds_nodash = context["prev_ds_nodash"]
46 | prev_execution_date = context["prev_execution_date"]
|
AIR301 `prev_ds_nodash` is removed in Airflow 3.0
--> AIR301_context.py:45:30
AIR301_context.py:45:30: AIR301 `prev_ds_nodash` is removed in Airflow 3.0
|
43 | next_execution_date = context["next_execution_date"]
44 | prev_ds = context["prev_ds"]
45 | prev_ds_nodash = context["prev_ds_nodash"]
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^ AIR301
46 | prev_execution_date = context["prev_execution_date"]
47 | prev_execution_date_success = context["prev_execution_date_success"]
|
AIR301 `prev_execution_date` is removed in Airflow 3.0
--> AIR301_context.py:46:35
AIR301_context.py:46:35: AIR301 `prev_execution_date` is removed in Airflow 3.0
|
44 | prev_ds = context["prev_ds"]
45 | prev_ds_nodash = context["prev_ds_nodash"]
46 | prev_execution_date = context["prev_execution_date"]
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ AIR301
47 | prev_execution_date_success = context["prev_execution_date_success"]
48 | tomorrow_ds = context["tomorrow_ds"]
|
AIR301 `prev_execution_date_success` is removed in Airflow 3.0
--> AIR301_context.py:47:43
AIR301_context.py:47:43: AIR301 `prev_execution_date_success` is removed in Airflow 3.0
|
45 | prev_ds_nodash = context["prev_ds_nodash"]
46 | prev_execution_date = context["prev_execution_date"]
47 | prev_execution_date_success = context["prev_execution_date_success"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301
48 | tomorrow_ds = context["tomorrow_ds"]
49 | yesterday_ds = context["yesterday_ds"]
|
AIR301 `tomorrow_ds` is removed in Airflow 3.0
--> AIR301_context.py:48:27
AIR301_context.py:48:27: AIR301 `tomorrow_ds` is removed in Airflow 3.0
|
46 | prev_execution_date = context["prev_execution_date"]
47 | prev_execution_date_success = context["prev_execution_date_success"]
48 | tomorrow_ds = context["tomorrow_ds"]
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^ AIR301
49 | yesterday_ds = context["yesterday_ds"]
50 | yesterday_ds_nodash = context["yesterday_ds_nodash"]
|
AIR301 `yesterday_ds` is removed in Airflow 3.0
--> AIR301_context.py:49:28
AIR301_context.py:49:28: AIR301 `yesterday_ds` is removed in Airflow 3.0
|
47 | prev_execution_date_success = context["prev_execution_date_success"]
48 | tomorrow_ds = context["tomorrow_ds"]
49 | yesterday_ds = context["yesterday_ds"]
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ AIR301
50 | yesterday_ds_nodash = context["yesterday_ds_nodash"]
|
AIR301 `yesterday_ds_nodash` is removed in Airflow 3.0
--> AIR301_context.py:50:35
AIR301_context.py:50:35: AIR301 `yesterday_ds_nodash` is removed in Airflow 3.0
|
48 | tomorrow_ds = context["tomorrow_ds"]
49 | yesterday_ds = context["yesterday_ds"]
50 | yesterday_ds_nodash = context["yesterday_ds_nodash"]
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ AIR301
|
AIR301 `execution_date` is removed in Airflow 3.0
--> AIR301_context.py:56:30
AIR301_context.py:56:30: AIR301 `execution_date` is removed in Airflow 3.0
|
54 | def print_config_with_get_current_context():
55 | context = get_current_context()
56 | execution_date = context["execution_date"]
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^ AIR301
57 | next_ds = context["next_ds"]
58 | next_ds_nodash = context["next_ds_nodash"]
|
AIR301 `next_ds` is removed in Airflow 3.0
--> AIR301_context.py:57:23
AIR301_context.py:57:23: AIR301 `next_ds` is removed in Airflow 3.0
|
55 | context = get_current_context()
56 | execution_date = context["execution_date"]
57 | next_ds = context["next_ds"]
| ^^^^^^^^^
| ^^^^^^^^^ AIR301
58 | next_ds_nodash = context["next_ds_nodash"]
59 | next_execution_date = context["next_execution_date"]
|
AIR301 `next_ds_nodash` is removed in Airflow 3.0
--> AIR301_context.py:58:30
AIR301_context.py:58:30: AIR301 `next_ds_nodash` is removed in Airflow 3.0
|
56 | execution_date = context["execution_date"]
57 | next_ds = context["next_ds"]
58 | next_ds_nodash = context["next_ds_nodash"]
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^ AIR301
59 | next_execution_date = context["next_execution_date"]
60 | prev_ds = context["prev_ds"]
|
AIR301 `next_execution_date` is removed in Airflow 3.0
--> AIR301_context.py:59:35
AIR301_context.py:59:35: AIR301 `next_execution_date` is removed in Airflow 3.0
|
57 | next_ds = context["next_ds"]
58 | next_ds_nodash = context["next_ds_nodash"]
59 | next_execution_date = context["next_execution_date"]
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ AIR301
60 | prev_ds = context["prev_ds"]
61 | prev_ds_nodash = context["prev_ds_nodash"]
|
AIR301 `prev_ds` is removed in Airflow 3.0
--> AIR301_context.py:60:23
AIR301_context.py:60:23: AIR301 `prev_ds` is removed in Airflow 3.0
|
58 | next_ds_nodash = context["next_ds_nodash"]
59 | next_execution_date = context["next_execution_date"]
60 | prev_ds = context["prev_ds"]
| ^^^^^^^^^
| ^^^^^^^^^ AIR301
61 | prev_ds_nodash = context["prev_ds_nodash"]
62 | prev_execution_date = context["prev_execution_date"]
|
AIR301 `prev_ds_nodash` is removed in Airflow 3.0
--> AIR301_context.py:61:30
AIR301_context.py:61:30: AIR301 `prev_ds_nodash` is removed in Airflow 3.0
|
59 | next_execution_date = context["next_execution_date"]
60 | prev_ds = context["prev_ds"]
61 | prev_ds_nodash = context["prev_ds_nodash"]
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^ AIR301
62 | prev_execution_date = context["prev_execution_date"]
63 | prev_execution_date_success = context["prev_execution_date_success"]
|
AIR301 `prev_execution_date` is removed in Airflow 3.0
--> AIR301_context.py:62:35
AIR301_context.py:62:35: AIR301 `prev_execution_date` is removed in Airflow 3.0
|
60 | prev_ds = context["prev_ds"]
61 | prev_ds_nodash = context["prev_ds_nodash"]
62 | prev_execution_date = context["prev_execution_date"]
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ AIR301
63 | prev_execution_date_success = context["prev_execution_date_success"]
64 | tomorrow_ds = context["tomorrow_ds"]
|
AIR301 `prev_execution_date_success` is removed in Airflow 3.0
--> AIR301_context.py:63:43
AIR301_context.py:63:43: AIR301 `prev_execution_date_success` is removed in Airflow 3.0
|
61 | prev_ds_nodash = context["prev_ds_nodash"]
62 | prev_execution_date = context["prev_execution_date"]
63 | prev_execution_date_success = context["prev_execution_date_success"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301
64 | tomorrow_ds = context["tomorrow_ds"]
65 | yesterday_ds = context["yesterday_ds"]
|
AIR301 `tomorrow_ds` is removed in Airflow 3.0
--> AIR301_context.py:64:27
AIR301_context.py:64:27: AIR301 `tomorrow_ds` is removed in Airflow 3.0
|
62 | prev_execution_date = context["prev_execution_date"]
63 | prev_execution_date_success = context["prev_execution_date_success"]
64 | tomorrow_ds = context["tomorrow_ds"]
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^ AIR301
65 | yesterday_ds = context["yesterday_ds"]
66 | yesterday_ds_nodash = context["yesterday_ds_nodash"]
|
AIR301 `yesterday_ds` is removed in Airflow 3.0
--> AIR301_context.py:65:28
AIR301_context.py:65:28: AIR301 `yesterday_ds` is removed in Airflow 3.0
|
63 | prev_execution_date_success = context["prev_execution_date_success"]
64 | tomorrow_ds = context["tomorrow_ds"]
65 | yesterday_ds = context["yesterday_ds"]
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ AIR301
66 | yesterday_ds_nodash = context["yesterday_ds_nodash"]
|
AIR301 `yesterday_ds_nodash` is removed in Airflow 3.0
--> AIR301_context.py:66:35
AIR301_context.py:66:35: AIR301 `yesterday_ds_nodash` is removed in Airflow 3.0
|
64 | tomorrow_ds = context["tomorrow_ds"]
65 | yesterday_ds = context["yesterday_ds"]
66 | yesterday_ds_nodash = context["yesterday_ds_nodash"]
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ AIR301
|
AIR301 `tomorrow_ds` is removed in Airflow 3.0
--> AIR301_context.py:73:22
AIR301_context.py:73:22: AIR301 `tomorrow_ds` is removed in Airflow 3.0
|
71 | """Print the Airflow context and ds variable from the context."""
72 | print(ds)
73 | print(kwargs.get("tomorrow_ds"))
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^ AIR301
74 | c = get_current_context()
75 | c.get("execution_date")
|
AIR301 `execution_date` is removed in Airflow 3.0
--> AIR301_context.py:75:11
AIR301_context.py:75:11: AIR301 `execution_date` is removed in Airflow 3.0
|
73 | print(kwargs.get("tomorrow_ds"))
74 | c = get_current_context()
75 | c.get("execution_date")
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^ AIR301
|
AIR301 `conf` is removed in Airflow 3.0
--> AIR301_context.py:87:49
AIR301_context.py:87:49: AIR301 `conf` is removed in Airflow 3.0
|
85 | @task()
86 | def access_invalid_key_task(**context):
87 | print("access invalid key", context.get("conf"))
| ^^^^^^
| ^^^^^^ AIR301
88 |
89 | @task()
|
AIR301 `execution_date` is removed in Airflow 3.0
--> AIR301_context.py:90:42
AIR301_context.py:90:42: AIR301 `execution_date` is removed in Airflow 3.0
|
89 | @task()
90 | def access_invalid_key_explicit_task(execution_date):
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ AIR301
91 | print(execution_date)
|
AIR301 [*] `schedule_interval` is removed in Airflow 3.0
--> AIR301_context.py:111:5
AIR301_context.py:111:5: AIR301 [*] `schedule_interval` is removed in Airflow 3.0
|
109 | with DAG(
110 | dag_id="example_dag",
111 | schedule_interval="@daily",
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ AIR301
112 | start_date=datetime(2023, 1, 1),
113 | template_searchpath=["/templates"],
|
help: Use `schedule` instead
= help: Use `schedule` instead
Safe fix
108 108 |
@@ -348,12 +316,11 @@ help: Use `schedule` instead
113 113 | template_searchpath=["/templates"],
114 114 | ) as dag:
AIR301 `next_ds` is removed in Airflow 3.0
--> AIR301_context.py:135:23
AIR301_context.py:135:23: AIR301 `next_ds` is removed in Airflow 3.0
|
134 | class CustomOperator(BaseOperator):
135 | def execute(self, next_ds, context):
| ^^^^^^^
| ^^^^^^^ AIR301
136 | execution_date = context["execution_date"]
137 | next_ds = context["next_ds"]
|

View File

@@ -1,352 +1,294 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR301 `airflow.PY36` is removed in Airflow 3.0
--> AIR301_names.py:39:1
AIR301_names.py:38:1: AIR301 `airflow.PY36` is removed in Airflow 3.0
|
38 | # airflow root
39 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
| ^^^^
40 |
41 | # airflow.api_connexion.security
37 | # airflow root
38 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
| ^^^^ AIR301
39 |
40 | # airflow.api_connexion.security
|
help: Use `sys.version_info` instead
= help: Use `sys.version_info` instead
AIR301 `airflow.PY37` is removed in Airflow 3.0
--> AIR301_names.py:39:7
AIR301_names.py:38:7: AIR301 `airflow.PY37` is removed in Airflow 3.0
|
38 | # airflow root
39 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
| ^^^^
40 |
41 | # airflow.api_connexion.security
37 | # airflow root
38 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
| ^^^^ AIR301
39 |
40 | # airflow.api_connexion.security
|
help: Use `sys.version_info` instead
= help: Use `sys.version_info` instead
AIR301 `airflow.PY38` is removed in Airflow 3.0
--> AIR301_names.py:39:13
AIR301_names.py:38:13: AIR301 `airflow.PY38` is removed in Airflow 3.0
|
38 | # airflow root
39 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
| ^^^^
40 |
41 | # airflow.api_connexion.security
37 | # airflow root
38 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
| ^^^^ AIR301
39 |
40 | # airflow.api_connexion.security
|
help: Use `sys.version_info` instead
= help: Use `sys.version_info` instead
AIR301 `airflow.PY39` is removed in Airflow 3.0
--> AIR301_names.py:39:19
AIR301_names.py:38:19: AIR301 `airflow.PY39` is removed in Airflow 3.0
|
38 | # airflow root
39 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
| ^^^^
40 |
41 | # airflow.api_connexion.security
37 | # airflow root
38 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
| ^^^^ AIR301
39 |
40 | # airflow.api_connexion.security
|
help: Use `sys.version_info` instead
= help: Use `sys.version_info` instead
AIR301 `airflow.PY310` is removed in Airflow 3.0
--> AIR301_names.py:39:25
AIR301_names.py:38:25: AIR301 `airflow.PY310` is removed in Airflow 3.0
|
38 | # airflow root
39 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
| ^^^^^
40 |
41 | # airflow.api_connexion.security
37 | # airflow root
38 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
| ^^^^^ AIR301
39 |
40 | # airflow.api_connexion.security
|
help: Use `sys.version_info` instead
= help: Use `sys.version_info` instead
AIR301 `airflow.PY311` is removed in Airflow 3.0
--> AIR301_names.py:39:32
AIR301_names.py:38:32: AIR301 `airflow.PY311` is removed in Airflow 3.0
|
38 | # airflow root
39 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
| ^^^^^
40 |
41 | # airflow.api_connexion.security
37 | # airflow root
38 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
| ^^^^^ AIR301
39 |
40 | # airflow.api_connexion.security
|
help: Use `sys.version_info` instead
= help: Use `sys.version_info` instead
AIR301 `airflow.PY312` is removed in Airflow 3.0
--> AIR301_names.py:39:39
AIR301_names.py:38:39: AIR301 `airflow.PY312` is removed in Airflow 3.0
|
38 | # airflow root
39 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
| ^^^^^
40 |
41 | # airflow.api_connexion.security
37 | # airflow root
38 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
| ^^^^^ AIR301
39 |
40 | # airflow.api_connexion.security
|
help: Use `sys.version_info` instead
= help: Use `sys.version_info` instead
AIR301 `airflow.api_connexion.security.requires_access` is removed in Airflow 3.0
--> AIR301_names.py:42:1
AIR301_names.py:41:1: AIR301 `airflow.api_connexion.security.requires_access` is removed in Airflow 3.0
|
41 | # airflow.api_connexion.security
42 | requires_access
| ^^^^^^^^^^^^^^^
43 |
44 | # airflow.contrib.*
40 | # airflow.api_connexion.security
41 | requires_access
| ^^^^^^^^^^^^^^^ AIR301
42 |
43 | # airflow.contrib.*
|
help: Use `airflow.api_fastapi.core_api.security.requires_access_*` instead
= help: Use `airflow.api_fastapi.core_api.security.requires_access_*` instead
AIR301 `airflow.contrib.aws_athena_hook.AWSAthenaHook` is removed in Airflow 3.0
--> AIR301_names.py:45:1
AIR301_names.py:44:1: AIR301 `airflow.contrib.aws_athena_hook.AWSAthenaHook` is removed in Airflow 3.0
|
44 | # airflow.contrib.*
45 | AWSAthenaHook()
| ^^^^^^^^^^^^^
43 | # airflow.contrib.*
44 | AWSAthenaHook()
| ^^^^^^^^^^^^^ AIR301
|
help: The whole `airflow.contrib` module has been removed.
= help: The whole `airflow.contrib` module has been removed.
AIR301 `airflow.datasets.DatasetAliasEvent` is removed in Airflow 3.0
--> AIR301_names.py:49:1
AIR301_names.py:48:1: AIR301 `airflow.datasets.DatasetAliasEvent` is removed in Airflow 3.0
|
48 | # airflow.datasets
49 | DatasetAliasEvent()
| ^^^^^^^^^^^^^^^^^
47 | # airflow.datasets
48 | DatasetAliasEvent()
| ^^^^^^^^^^^^^^^^^ AIR301
|
AIR301 `airflow.operators.subdag.SubDagOperator` is removed in Airflow 3.0
--> AIR301_names.py:53:1
AIR301_names.py:52:1: AIR301 `airflow.operators.subdag.SubDagOperator` is removed in Airflow 3.0
|
52 | # airflow.operators.subdag.*
53 | SubDagOperator()
| ^^^^^^^^^^^^^^
51 | # airflow.operators.subdag.*
52 | SubDagOperator()
| ^^^^^^^^^^^^^^ AIR301
|
help: The whole `airflow.subdag` module has been removed.
= help: The whole `airflow.subdag` module has been removed.
AIR301 [*] `airflow.secrets.cache.SecretCache` is removed in Airflow 3.0
--> AIR301_names.py:61:1
AIR301_names.py:61:1: AIR301 `airflow.triggers.external_task.TaskStateTrigger` is removed in Airflow 3.0
|
60 | # airflow.secrets.cache
61 | SecretCache()
| ^^^^^^^^^^^
60 | # airflow.triggers.external_task
61 | TaskStateTrigger()
| ^^^^^^^^^^^^^^^^ AIR301
62 |
63 | # airflow.utils.date
|
help: Use `SecretCache` from `airflow.sdk` instead.
Unsafe fix
13 13 | from airflow.contrib.aws_athena_hook import AWSAthenaHook
14 14 | from airflow.datasets import DatasetAliasEvent
15 15 | from airflow.operators.subdag import SubDagOperator
16 |-from airflow.secrets.cache import SecretCache
17 16 | from airflow.secrets.local_filesystem import LocalFilesystemBackend
18 17 | from airflow.triggers.external_task import TaskStateTrigger
19 18 | from airflow.utils import dates
--------------------------------------------------------------------------------
34 33 | from airflow.utils.trigger_rule import TriggerRule
35 34 | from airflow.www.auth import has_access, has_access_dataset
36 35 | from airflow.www.utils import get_sensitive_variables_fields, should_hide_value_for_key
36 |+from airflow.sdk import SecretCache
37 37 |
38 38 | # airflow root
39 39 | PY36, PY37, PY38, PY39, PY310, PY311, PY312
AIR301 `airflow.triggers.external_task.TaskStateTrigger` is removed in Airflow 3.0
--> AIR301_names.py:65:1
AIR301_names.py:64:1: AIR301 `airflow.utils.dates.date_range` is removed in Airflow 3.0
|
64 | # airflow.triggers.external_task
65 | TaskStateTrigger()
| ^^^^^^^^^^^^^^^^
63 | # airflow.utils.date
64 | dates.date_range
| ^^^^^^^^^^^^^^^^ AIR301
65 | dates.days_ago
|
AIR301_names.py:65:1: AIR301 `airflow.utils.dates.days_ago` is removed in Airflow 3.0
|
63 | # airflow.utils.date
64 | dates.date_range
65 | dates.days_ago
| ^^^^^^^^^^^^^^ AIR301
66 |
67 | # airflow.utils.date
67 | date_range
|
= help: Use `pendulum.today('UTC').add(days=-N, ...)` instead
AIR301_names.py:67:1: AIR301 `airflow.utils.dates.date_range` is removed in Airflow 3.0
|
65 | dates.days_ago
66 |
67 | date_range
| ^^^^^^^^^^ AIR301
68 | days_ago
69 | infer_time_unit
|
AIR301 `airflow.utils.dates.date_range` is removed in Airflow 3.0
--> AIR301_names.py:68:1
AIR301_names.py:68:1: AIR301 `airflow.utils.dates.days_ago` is removed in Airflow 3.0
|
67 | # airflow.utils.date
68 | dates.date_range
| ^^^^^^^^^^^^^^^^
69 | dates.days_ago
67 | date_range
68 | days_ago
| ^^^^^^^^ AIR301
69 | infer_time_unit
70 | parse_execution_date
|
= help: Use `pendulum.today('UTC').add(days=-N, ...)` instead
AIR301_names.py:69:1: AIR301 `airflow.utils.dates.infer_time_unit` is removed in Airflow 3.0
|
67 | date_range
68 | days_ago
69 | infer_time_unit
| ^^^^^^^^^^^^^^^ AIR301
70 | parse_execution_date
71 | round_time
|
AIR301 `airflow.utils.dates.days_ago` is removed in Airflow 3.0
--> AIR301_names.py:69:1
AIR301_names.py:70:1: AIR301 `airflow.utils.dates.parse_execution_date` is removed in Airflow 3.0
|
67 | # airflow.utils.date
68 | dates.date_range
69 | dates.days_ago
| ^^^^^^^^^^^^^^
70 |
71 | date_range
|
help: Use `pendulum.today('UTC').add(days=-N, ...)` instead
AIR301 `airflow.utils.dates.date_range` is removed in Airflow 3.0
--> AIR301_names.py:71:1
|
69 | dates.days_ago
70 |
71 | date_range
| ^^^^^^^^^^
72 | days_ago
73 | infer_time_unit
68 | days_ago
69 | infer_time_unit
70 | parse_execution_date
| ^^^^^^^^^^^^^^^^^^^^ AIR301
71 | round_time
72 | scale_time_units
|
AIR301 `airflow.utils.dates.days_ago` is removed in Airflow 3.0
--> AIR301_names.py:72:1
AIR301_names.py:71:1: AIR301 `airflow.utils.dates.round_time` is removed in Airflow 3.0
|
71 | date_range
72 | days_ago
| ^^^^^^^^
73 | infer_time_unit
74 | parse_execution_date
|
help: Use `pendulum.today('UTC').add(days=-N, ...)` instead
AIR301 `airflow.utils.dates.infer_time_unit` is removed in Airflow 3.0
--> AIR301_names.py:73:1
|
71 | date_range
72 | days_ago
73 | infer_time_unit
| ^^^^^^^^^^^^^^^
74 | parse_execution_date
75 | round_time
69 | infer_time_unit
70 | parse_execution_date
71 | round_time
| ^^^^^^^^^^ AIR301
72 | scale_time_units
|
AIR301 `airflow.utils.dates.parse_execution_date` is removed in Airflow 3.0
--> AIR301_names.py:74:1
AIR301_names.py:72:1: AIR301 `airflow.utils.dates.scale_time_units` is removed in Airflow 3.0
|
72 | days_ago
73 | infer_time_unit
74 | parse_execution_date
| ^^^^^^^^^^^^^^^^^^^^
75 | round_time
76 | scale_time_units
70 | parse_execution_date
71 | round_time
72 | scale_time_units
| ^^^^^^^^^^^^^^^^ AIR301
73 |
74 | # This one was not deprecated.
|
AIR301 `airflow.utils.dates.round_time` is removed in Airflow 3.0
--> AIR301_names.py:75:1
AIR301_names.py:79:1: AIR301 `airflow.utils.dag_cycle_tester.test_cycle` is removed in Airflow 3.0
|
73 | infer_time_unit
74 | parse_execution_date
75 | round_time
| ^^^^^^^^^^
76 | scale_time_units
78 | # airflow.utils.dag_cycle_tester
79 | test_cycle
| ^^^^^^^^^^ AIR301
|
AIR301 `airflow.utils.dates.scale_time_units` is removed in Airflow 3.0
--> AIR301_names.py:76:1
AIR301_names.py:83:1: AIR301 `airflow.utils.db.create_session` is removed in Airflow 3.0
|
74 | parse_execution_date
75 | round_time
76 | scale_time_units
| ^^^^^^^^^^^^^^^^
77 |
78 | # This one was not deprecated.
82 | # airflow.utils.db
83 | create_session
| ^^^^^^^^^^^^^^ AIR301
84 |
85 | # airflow.utils.decorators
|
AIR301 `airflow.utils.dag_cycle_tester.test_cycle` is removed in Airflow 3.0
--> AIR301_names.py:83:1
AIR301_names.py:86:1: AIR301 `airflow.utils.decorators.apply_defaults` is removed in Airflow 3.0
|
82 | # airflow.utils.dag_cycle_tester
83 | test_cycle
| ^^^^^^^^^^
85 | # airflow.utils.decorators
86 | apply_defaults
| ^^^^^^^^^^^^^^ AIR301
87 |
88 | # airflow.utils.file
|
= help: `apply_defaults` is now unconditionally done and can be safely removed.
AIR301_names.py:89:1: AIR301 `airflow.utils.file.mkdirs` is removed in Airflow 3.0
|
88 | # airflow.utils.file
89 | mkdirs
| ^^^^^^ AIR301
|
= help: Use `pathlib.Path({path}).mkdir` instead
AIR301_names.py:93:1: AIR301 `airflow.utils.state.SHUTDOWN` is removed in Airflow 3.0
|
92 | # airflow.utils.state
93 | SHUTDOWN
| ^^^^^^^^ AIR301
94 | terminating_states
|
AIR301 `airflow.utils.db.create_session` is removed in Airflow 3.0
--> AIR301_names.py:87:1
AIR301_names.py:94:1: AIR301 `airflow.utils.state.terminating_states` is removed in Airflow 3.0
|
86 | # airflow.utils.db
87 | create_session
| ^^^^^^^^^^^^^^
88 |
89 | # airflow.utils.decorators
92 | # airflow.utils.state
93 | SHUTDOWN
94 | terminating_states
| ^^^^^^^^^^^^^^^^^^ AIR301
95 |
96 | # airflow.utils.trigger_rule
|
AIR301 `airflow.utils.decorators.apply_defaults` is removed in Airflow 3.0
--> AIR301_names.py:90:1
AIR301_names.py:97:1: AIR301 `airflow.utils.trigger_rule.TriggerRule.DUMMY` is removed in Airflow 3.0
|
89 | # airflow.utils.decorators
90 | apply_defaults
| ^^^^^^^^^^^^^^
91 |
92 | # airflow.utils.file
|
help: `apply_defaults` is now unconditionally done and can be safely removed.
AIR301 `airflow.utils.file.mkdirs` is removed in Airflow 3.0
--> AIR301_names.py:93:1
|
92 | # airflow.utils.file
93 | mkdirs
| ^^^^^^
|
help: Use `pathlib.Path({path}).mkdir` instead
AIR301 `airflow.utils.state.SHUTDOWN` is removed in Airflow 3.0
--> AIR301_names.py:97:1
|
96 | # airflow.utils.state
97 | SHUTDOWN
| ^^^^^^^^
98 | terminating_states
96 | # airflow.utils.trigger_rule
97 | TriggerRule.DUMMY
| ^^^^^^^^^^^^^^^^^ AIR301
98 | TriggerRule.NONE_FAILED_OR_SKIPPED
|
AIR301 `airflow.utils.state.terminating_states` is removed in Airflow 3.0
--> AIR301_names.py:98:1
AIR301_names.py:98:1: AIR301 `airflow.utils.trigger_rule.TriggerRule.NONE_FAILED_OR_SKIPPED` is removed in Airflow 3.0
|
96 | # airflow.utils.trigger_rule
97 | TriggerRule.DUMMY
98 | TriggerRule.NONE_FAILED_OR_SKIPPED
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301
|
AIR301_names.py:102:1: AIR301 `airflow.www.auth.has_access` is removed in Airflow 3.0
|
96 | # airflow.utils.state
97 | SHUTDOWN
98 | terminating_states
| ^^^^^^^^^^^^^^^^^^
99 |
100 | # airflow.utils.trigger_rule
101 | # airflow.www.auth
102 | has_access
| ^^^^^^^^^^ AIR301
103 | has_access_dataset
|
AIR301 `airflow.utils.trigger_rule.TriggerRule.DUMMY` is removed in Airflow 3.0
--> AIR301_names.py:101:1
AIR301_names.py:103:1: AIR301 `airflow.www.auth.has_access_dataset` is removed in Airflow 3.0
|
100 | # airflow.utils.trigger_rule
101 | TriggerRule.DUMMY
| ^^^^^^^^^^^^^^^^^
102 | TriggerRule.NONE_FAILED_OR_SKIPPED
101 | # airflow.www.auth
102 | has_access
103 | has_access_dataset
| ^^^^^^^^^^^^^^^^^^ AIR301
104 |
105 | # airflow.www.utils
|
AIR301 `airflow.utils.trigger_rule.TriggerRule.NONE_FAILED_OR_SKIPPED` is removed in Airflow 3.0
--> AIR301_names.py:102:1
AIR301_names.py:106:1: AIR301 `airflow.www.utils.get_sensitive_variables_fields` is removed in Airflow 3.0
|
100 | # airflow.utils.trigger_rule
101 | TriggerRule.DUMMY
102 | TriggerRule.NONE_FAILED_OR_SKIPPED
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
105 | # airflow.www.utils
106 | get_sensitive_variables_fields
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301
107 | should_hide_value_for_key
|
AIR301 `airflow.www.auth.has_access` is removed in Airflow 3.0
--> AIR301_names.py:106:1
AIR301_names.py:107:1: AIR301 `airflow.www.utils.should_hide_value_for_key` is removed in Airflow 3.0
|
105 | # airflow.www.auth
106 | has_access
| ^^^^^^^^^^
107 | has_access_dataset
|
AIR301 `airflow.www.auth.has_access_dataset` is removed in Airflow 3.0
--> AIR301_names.py:107:1
|
105 | # airflow.www.auth
106 | has_access
107 | has_access_dataset
| ^^^^^^^^^^^^^^^^^^
108 |
109 | # airflow.www.utils
|
AIR301 `airflow.www.utils.get_sensitive_variables_fields` is removed in Airflow 3.0
--> AIR301_names.py:110:1
|
109 | # airflow.www.utils
110 | get_sensitive_variables_fields
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
111 | should_hide_value_for_key
|
AIR301 `airflow.www.utils.should_hide_value_for_key` is removed in Airflow 3.0
--> AIR301_names.py:111:1
|
109 | # airflow.www.utils
110 | get_sensitive_variables_fields
111 | should_hide_value_for_key
| ^^^^^^^^^^^^^^^^^^^^^^^^^
105 | # airflow.www.utils
106 | get_sensitive_variables_fields
107 | should_hide_value_for_key
| ^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301
|

View File

@@ -1,17 +1,16 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR301 [*] `airflow.api_connexion.security.requires_access_dataset` is removed in Airflow 3.0
--> AIR301_names_fix.py:17:1
AIR301_names_fix.py:17:1: AIR301 [*] `airflow.api_connexion.security.requires_access_dataset` is removed in Airflow 3.0
|
15 | from airflow.security.permissions import RESOURCE_DATASET
16 |
17 | requires_access_dataset()
| ^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^ AIR301
18 |
19 | DatasetDetails()
|
help: Use `requires_access_asset` from `airflow.api_fastapi.core_api.security` instead.
= help: Use `requires_access_asset` from `airflow.api_fastapi.core_api.security` instead.
Safe fix
13 13 | from airflow.metrics.validators import AllowListValidator, BlockListValidator
@@ -25,17 +24,16 @@ help: Use `requires_access_asset` from `airflow.api_fastapi.core_api.security` i
19 20 | DatasetDetails()
20 21 |
AIR301 [*] `airflow.auth.managers.models.resource_details.DatasetDetails` is removed in Airflow 3.0
--> AIR301_names_fix.py:19:1
AIR301_names_fix.py:19:1: AIR301 [*] `airflow.auth.managers.models.resource_details.DatasetDetails` is removed in Airflow 3.0
|
17 | requires_access_dataset()
18 |
19 | DatasetDetails()
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ AIR301
20 |
21 | DatasetManager()
|
help: Use `AssetDetails` from `airflow.api_fastapi.auth.managers.models.resource_details` instead.
= help: Use `AssetDetails` from `airflow.api_fastapi.auth.managers.models.resource_details` instead.
Safe fix
13 13 | from airflow.metrics.validators import AllowListValidator, BlockListValidator
@@ -51,17 +49,16 @@ help: Use `AssetDetails` from `airflow.api_fastapi.auth.managers.models.resource
21 22 | DatasetManager()
22 23 | dataset_manager()
AIR301 [*] `airflow.datasets.manager.DatasetManager` is removed in Airflow 3.0
--> AIR301_names_fix.py:21:1
AIR301_names_fix.py:21:1: AIR301 [*] `airflow.datasets.manager.DatasetManager` is removed in Airflow 3.0
|
19 | DatasetDetails()
20 |
21 | DatasetManager()
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ AIR301
22 | dataset_manager()
23 | resolve_dataset_manager()
|
help: Use `AssetManager` from `airflow.assets.manager` instead.
= help: Use `AssetManager` from `airflow.assets.manager` instead.
Safe fix
13 13 | from airflow.metrics.validators import AllowListValidator, BlockListValidator
@@ -79,15 +76,14 @@ help: Use `AssetManager` from `airflow.assets.manager` instead.
23 24 | resolve_dataset_manager()
24 25 |
AIR301 [*] `airflow.datasets.manager.dataset_manager` is removed in Airflow 3.0
--> AIR301_names_fix.py:22:1
AIR301_names_fix.py:22:1: AIR301 [*] `airflow.datasets.manager.dataset_manager` is removed in Airflow 3.0
|
21 | DatasetManager()
22 | dataset_manager()
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^ AIR301
23 | resolve_dataset_manager()
|
help: Use `asset_manager` from `airflow.assets.manager` instead.
= help: Use `asset_manager` from `airflow.assets.manager` instead.
Safe fix
13 13 | from airflow.metrics.validators import AllowListValidator, BlockListValidator
@@ -106,17 +102,16 @@ help: Use `asset_manager` from `airflow.assets.manager` instead.
24 25 |
25 26 | DatasetLineageInfo()
AIR301 [*] `airflow.datasets.manager.resolve_dataset_manager` is removed in Airflow 3.0
--> AIR301_names_fix.py:23:1
AIR301_names_fix.py:23:1: AIR301 [*] `airflow.datasets.manager.resolve_dataset_manager` is removed in Airflow 3.0
|
21 | DatasetManager()
22 | dataset_manager()
23 | resolve_dataset_manager()
| ^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^ AIR301
24 |
25 | DatasetLineageInfo()
|
help: Use `resolve_asset_manager` from `airflow.assets.manager` instead.
= help: Use `resolve_asset_manager` from `airflow.assets.manager` instead.
Safe fix
13 13 | from airflow.metrics.validators import AllowListValidator, BlockListValidator
@@ -136,17 +131,16 @@ help: Use `resolve_asset_manager` from `airflow.assets.manager` instead.
25 26 | DatasetLineageInfo()
26 27 |
AIR301 [*] `airflow.lineage.hook.DatasetLineageInfo` is removed in Airflow 3.0
--> AIR301_names_fix.py:25:1
AIR301_names_fix.py:25:1: AIR301 [*] `airflow.lineage.hook.DatasetLineageInfo` is removed in Airflow 3.0
|
23 | resolve_dataset_manager()
24 |
25 | DatasetLineageInfo()
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^ AIR301
26 |
27 | AllowListValidator()
|
help: Use `AssetLineageInfo` from `airflow.lineage.hook` instead.
= help: Use `AssetLineageInfo` from `airflow.lineage.hook` instead.
Safe fix
9 9 | dataset_manager,
@@ -167,16 +161,15 @@ help: Use `AssetLineageInfo` from `airflow.lineage.hook` instead.
27 27 | AllowListValidator()
28 28 | BlockListValidator()
AIR301 [*] `airflow.metrics.validators.AllowListValidator` is removed in Airflow 3.0
--> AIR301_names_fix.py:27:1
AIR301_names_fix.py:27:1: AIR301 [*] `airflow.metrics.validators.AllowListValidator` is removed in Airflow 3.0
|
25 | DatasetLineageInfo()
26 |
27 | AllowListValidator()
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^ AIR301
28 | BlockListValidator()
|
help: Use `PatternAllowListValidator` from `airflow.metrics.validators` instead.
= help: Use `PatternAllowListValidator` from `airflow.metrics.validators` instead.
Safe fix
10 10 | resolve_dataset_manager,
@@ -197,16 +190,15 @@ help: Use `PatternAllowListValidator` from `airflow.metrics.validators` instead.
29 29 |
30 30 | load_connections()
AIR301 [*] `airflow.metrics.validators.BlockListValidator` is removed in Airflow 3.0
--> AIR301_names_fix.py:28:1
AIR301_names_fix.py:28:1: AIR301 [*] `airflow.metrics.validators.BlockListValidator` is removed in Airflow 3.0
|
27 | AllowListValidator()
28 | BlockListValidator()
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^ AIR301
29 |
30 | load_connections()
|
help: Use `PatternBlockListValidator` from `airflow.metrics.validators` instead.
= help: Use `PatternBlockListValidator` from `airflow.metrics.validators` instead.
Safe fix
10 10 | resolve_dataset_manager,
@@ -227,17 +219,16 @@ help: Use `PatternBlockListValidator` from `airflow.metrics.validators` instead.
30 30 | load_connections()
31 31 |
AIR301 [*] `airflow.secrets.local_filesystem.load_connections` is removed in Airflow 3.0
--> AIR301_names_fix.py:30:1
AIR301_names_fix.py:30:1: AIR301 [*] `airflow.secrets.local_filesystem.load_connections` is removed in Airflow 3.0
|
28 | BlockListValidator()
29 |
30 | load_connections()
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^ AIR301
31 |
32 | RESOURCE_DATASET
|
help: Use `load_connections_dict` from `airflow.secrets.local_filesystem` instead.
= help: Use `load_connections_dict` from `airflow.secrets.local_filesystem` instead.
Safe fix
11 11 | )
@@ -258,15 +249,14 @@ help: Use `load_connections_dict` from `airflow.secrets.local_filesystem` instea
32 32 | RESOURCE_DATASET
33 33 |
AIR301 [*] `airflow.security.permissions.RESOURCE_DATASET` is removed in Airflow 3.0
--> AIR301_names_fix.py:32:1
AIR301_names_fix.py:32:1: AIR301 [*] `airflow.security.permissions.RESOURCE_DATASET` is removed in Airflow 3.0
|
30 | load_connections()
31 |
32 | RESOURCE_DATASET
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^ AIR301
|
help: Use `RESOURCE_ASSET` from `airflow.security.permissions` instead.
= help: Use `RESOURCE_ASSET` from `airflow.security.permissions` instead.
Safe fix
12 12 | from airflow.lineage.hook import DatasetLineageInfo
@@ -287,16 +277,15 @@ help: Use `RESOURCE_ASSET` from `airflow.security.permissions` instead.
34 34 |
35 35 | from airflow.listeners.spec.dataset import (
AIR301 [*] `airflow.listeners.spec.dataset.on_dataset_created` is removed in Airflow 3.0
--> AIR301_names_fix.py:40:1
AIR301_names_fix.py:40:1: AIR301 [*] `airflow.listeners.spec.dataset.on_dataset_created` is removed in Airflow 3.0
|
38 | )
39 |
40 | on_dataset_created()
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^ AIR301
41 | on_dataset_changed()
|
help: Use `on_asset_created` from `airflow.listeners.spec.asset` instead.
= help: Use `on_asset_created` from `airflow.listeners.spec.asset` instead.
Safe fix
36 36 | on_dataset_changed,
@@ -310,14 +299,13 @@ help: Use `on_asset_created` from `airflow.listeners.spec.asset` instead.
42 43 |
43 44 |
AIR301 [*] `airflow.listeners.spec.dataset.on_dataset_changed` is removed in Airflow 3.0
--> AIR301_names_fix.py:41:1
AIR301_names_fix.py:41:1: AIR301 [*] `airflow.listeners.spec.dataset.on_dataset_changed` is removed in Airflow 3.0
|
40 | on_dataset_created()
41 | on_dataset_changed()
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^ AIR301
|
help: Use `on_asset_changed` from `airflow.listeners.spec.asset` instead.
= help: Use `on_asset_changed` from `airflow.listeners.spec.asset` instead.
Safe fix
36 36 | on_dataset_changed,
@@ -332,17 +320,16 @@ help: Use `on_asset_changed` from `airflow.listeners.spec.asset` instead.
43 44 |
44 45 | # airflow.operators.python
AIR301 [*] `airflow.operators.python.get_current_context` is removed in Airflow 3.0
--> AIR301_names_fix.py:47:1
AIR301_names_fix.py:47:1: AIR301 [*] `airflow.operators.python.get_current_context` is removed in Airflow 3.0
|
45 | from airflow.operators.python import get_current_context
46 |
47 | get_current_context()
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^ AIR301
48 |
49 | # airflow.providers.mysql
|
help: Use `get_current_context` from `airflow.sdk` instead.
= help: Use `get_current_context` from `airflow.sdk` instead.
Unsafe fix
42 42 |
@@ -354,17 +341,16 @@ help: Use `get_current_context` from `airflow.sdk` instead.
47 47 | get_current_context()
48 48 |
AIR301 [*] `airflow.providers.mysql.datasets.mysql.sanitize_uri` is removed in Airflow 3.0
--> AIR301_names_fix.py:52:1
AIR301_names_fix.py:52:1: AIR301 [*] `airflow.providers.mysql.datasets.mysql.sanitize_uri` is removed in Airflow 3.0
|
50 | from airflow.providers.mysql.datasets.mysql import sanitize_uri
51 |
52 | sanitize_uri
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ AIR301
53 |
54 | # airflow.providers.postgres
|
help: Use `sanitize_uri` from `airflow.providers.mysql.assets.mysql` instead.
= help: Use `sanitize_uri` from `airflow.providers.mysql.assets.mysql` instead.
Unsafe fix
47 47 | get_current_context()
@@ -376,17 +362,16 @@ help: Use `sanitize_uri` from `airflow.providers.mysql.assets.mysql` instead.
52 52 | sanitize_uri
53 53 |
AIR301 [*] `airflow.providers.postgres.datasets.postgres.sanitize_uri` is removed in Airflow 3.0
--> AIR301_names_fix.py:57:1
AIR301_names_fix.py:57:1: AIR301 [*] `airflow.providers.postgres.datasets.postgres.sanitize_uri` is removed in Airflow 3.0
|
55 | from airflow.providers.postgres.datasets.postgres import sanitize_uri
56 |
57 | sanitize_uri
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ AIR301
58 |
59 | # airflow.providers.trino
|
help: Use `sanitize_uri` from `airflow.providers.postgres.assets.postgres` instead.
= help: Use `sanitize_uri` from `airflow.providers.postgres.assets.postgres` instead.
Unsafe fix
52 52 | sanitize_uri
@@ -398,17 +383,16 @@ help: Use `sanitize_uri` from `airflow.providers.postgres.assets.postgres` inste
57 57 | sanitize_uri
58 58 |
AIR301 [*] `airflow.providers.trino.datasets.trino.sanitize_uri` is removed in Airflow 3.0
--> AIR301_names_fix.py:62:1
AIR301_names_fix.py:62:1: AIR301 [*] `airflow.providers.trino.datasets.trino.sanitize_uri` is removed in Airflow 3.0
|
60 | from airflow.providers.trino.datasets.trino import sanitize_uri
61 |
62 | sanitize_uri
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ AIR301
63 |
64 | # airflow.notifications.basenotifier
|
help: Use `sanitize_uri` from `airflow.providers.trino.assets.trino` instead.
= help: Use `sanitize_uri` from `airflow.providers.trino.assets.trino` instead.
Unsafe fix
57 57 | sanitize_uri
@@ -420,17 +404,16 @@ help: Use `sanitize_uri` from `airflow.providers.trino.assets.trino` instead.
62 62 | sanitize_uri
63 63 |
AIR301 [*] `airflow.notifications.basenotifier.BaseNotifier` is removed in Airflow 3.0
--> AIR301_names_fix.py:67:1
AIR301_names_fix.py:67:1: AIR301 [*] `airflow.notifications.basenotifier.BaseNotifier` is removed in Airflow 3.0
|
65 | from airflow.notifications.basenotifier import BaseNotifier
66 |
67 | BaseNotifier()
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ AIR301
68 |
69 | # airflow.auth.manager
|
help: Use `BaseNotifier` from `airflow.sdk.bases.notifier` instead.
= help: Use `BaseNotifier` from `airflow.sdk.bases.notifier` instead.
Unsafe fix
62 62 | sanitize_uri
@@ -442,15 +425,14 @@ help: Use `BaseNotifier` from `airflow.sdk.bases.notifier` instead.
67 67 | BaseNotifier()
68 68 |
AIR301 [*] `airflow.auth.managers.base_auth_manager.BaseAuthManager` is removed in Airflow 3.0
--> AIR301_names_fix.py:72:1
AIR301_names_fix.py:72:1: AIR301 [*] `airflow.auth.managers.base_auth_manager.BaseAuthManager` is removed in Airflow 3.0
|
70 | from airflow.auth.managers.base_auth_manager import BaseAuthManager
71 |
72 | BaseAuthManager()
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^ AIR301
|
help: Use `BaseAuthManager` from `airflow.api_fastapi.auth.managers.base_auth_manager` instead.
= help: Use `BaseAuthManager` from `airflow.api_fastapi.auth.managers.base_auth_manager` instead.
Unsafe fix
67 67 | BaseNotifier()
@@ -462,15 +444,14 @@ help: Use `BaseAuthManager` from `airflow.api_fastapi.auth.managers.base_auth_ma
72 72 | BaseAuthManager()
73 73 |
AIR301 [*] `airflow.configuration.get` is removed in Airflow 3.0
--> AIR301_names_fix.py:87:1
AIR301_names_fix.py:87:1: AIR301 [*] `airflow.configuration.get` is removed in Airflow 3.0
|
86 | # airflow.configuration
87 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
| ^^^
| ^^^ AIR301
88 | from airflow.hooks.base_hook import BaseHook
|
help: Use `conf.get` from `airflow.configuration` instead.
= help: Use `conf.get` from `airflow.configuration` instead.
Safe fix
81 81 | has_option,
@@ -486,15 +467,14 @@ help: Use `conf.get` from `airflow.configuration` instead.
89 90 |
90 91 | # airflow.hooks
AIR301 [*] `airflow.configuration.getboolean` is removed in Airflow 3.0
--> AIR301_names_fix.py:87:6
AIR301_names_fix.py:87:6: AIR301 [*] `airflow.configuration.getboolean` is removed in Airflow 3.0
|
86 | # airflow.configuration
87 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
| ^^^^^^^^^^
| ^^^^^^^^^^ AIR301
88 | from airflow.hooks.base_hook import BaseHook
|
help: Use `conf.getboolean` from `airflow.configuration` instead.
= help: Use `conf.getboolean` from `airflow.configuration` instead.
Safe fix
81 81 | has_option,
@@ -510,15 +490,14 @@ help: Use `conf.getboolean` from `airflow.configuration` instead.
89 90 |
90 91 | # airflow.hooks
AIR301 [*] `airflow.configuration.getfloat` is removed in Airflow 3.0
--> AIR301_names_fix.py:87:18
AIR301_names_fix.py:87:18: AIR301 [*] `airflow.configuration.getfloat` is removed in Airflow 3.0
|
86 | # airflow.configuration
87 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
| ^^^^^^^^
| ^^^^^^^^ AIR301
88 | from airflow.hooks.base_hook import BaseHook
|
help: Use `conf.getfloat` from `airflow.configuration` instead.
= help: Use `conf.getfloat` from `airflow.configuration` instead.
Safe fix
81 81 | has_option,
@@ -534,15 +513,14 @@ help: Use `conf.getfloat` from `airflow.configuration` instead.
89 90 |
90 91 | # airflow.hooks
AIR301 [*] `airflow.configuration.getint` is removed in Airflow 3.0
--> AIR301_names_fix.py:87:28
AIR301_names_fix.py:87:28: AIR301 [*] `airflow.configuration.getint` is removed in Airflow 3.0
|
86 | # airflow.configuration
87 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
| ^^^^^^
| ^^^^^^ AIR301
88 | from airflow.hooks.base_hook import BaseHook
|
help: Use `conf.getint` from `airflow.configuration` instead.
= help: Use `conf.getint` from `airflow.configuration` instead.
Safe fix
81 81 | has_option,
@@ -558,15 +536,14 @@ help: Use `conf.getint` from `airflow.configuration` instead.
89 90 |
90 91 | # airflow.hooks
AIR301 [*] `airflow.configuration.has_option` is removed in Airflow 3.0
--> AIR301_names_fix.py:87:36
AIR301_names_fix.py:87:36: AIR301 [*] `airflow.configuration.has_option` is removed in Airflow 3.0
|
86 | # airflow.configuration
87 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
| ^^^^^^^^^^
| ^^^^^^^^^^ AIR301
88 | from airflow.hooks.base_hook import BaseHook
|
help: Use `conf.has_option` from `airflow.configuration` instead.
= help: Use `conf.has_option` from `airflow.configuration` instead.
Safe fix
81 81 | has_option,
@@ -582,15 +559,14 @@ help: Use `conf.has_option` from `airflow.configuration` instead.
89 90 |
90 91 | # airflow.hooks
AIR301 [*] `airflow.configuration.remove_option` is removed in Airflow 3.0
--> AIR301_names_fix.py:87:48
AIR301_names_fix.py:87:48: AIR301 [*] `airflow.configuration.remove_option` is removed in Airflow 3.0
|
86 | # airflow.configuration
87 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^ AIR301
88 | from airflow.hooks.base_hook import BaseHook
|
help: Use `conf.remove_option` from `airflow.configuration` instead.
= help: Use `conf.remove_option` from `airflow.configuration` instead.
Safe fix
81 81 | has_option,
@@ -606,15 +582,14 @@ help: Use `conf.remove_option` from `airflow.configuration` instead.
89 90 |
90 91 | # airflow.hooks
AIR301 [*] `airflow.configuration.as_dict` is removed in Airflow 3.0
--> AIR301_names_fix.py:87:63
AIR301_names_fix.py:87:63: AIR301 [*] `airflow.configuration.as_dict` is removed in Airflow 3.0
|
86 | # airflow.configuration
87 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
| ^^^^^^^
| ^^^^^^^ AIR301
88 | from airflow.hooks.base_hook import BaseHook
|
help: Use `conf.as_dict` from `airflow.configuration` instead.
= help: Use `conf.as_dict` from `airflow.configuration` instead.
Safe fix
81 81 | has_option,
@@ -630,15 +605,14 @@ help: Use `conf.as_dict` from `airflow.configuration` instead.
89 90 |
90 91 | # airflow.hooks
AIR301 [*] `airflow.configuration.set` is removed in Airflow 3.0
--> AIR301_names_fix.py:87:72
AIR301_names_fix.py:87:72: AIR301 [*] `airflow.configuration.set` is removed in Airflow 3.0
|
86 | # airflow.configuration
87 | get, getboolean, getfloat, getint, has_option, remove_option, as_dict, set
| ^^^
| ^^^ AIR301
88 | from airflow.hooks.base_hook import BaseHook
|
help: Use `conf.set` from `airflow.configuration` instead.
= help: Use `conf.set` from `airflow.configuration` instead.
Safe fix
81 81 | has_option,
@@ -654,16 +628,15 @@ help: Use `conf.set` from `airflow.configuration` instead.
89 90 |
90 91 | # airflow.hooks
AIR301 [*] `airflow.hooks.base_hook.BaseHook` is removed in Airflow 3.0
--> AIR301_names_fix.py:91:1
AIR301_names_fix.py:91:1: AIR301 [*] `airflow.hooks.base_hook.BaseHook` is removed in Airflow 3.0
|
90 | # airflow.hooks
91 | BaseHook()
| ^^^^^^^^
| ^^^^^^^^ AIR301
92 |
93 | from airflow.sensors.base_sensor_operator import BaseSensorOperator
|
help: Use `BaseHook` from `airflow.hooks.base` instead.
= help: Use `BaseHook` from `airflow.hooks.base` instead.
Unsafe fix
85 85 |
@@ -675,15 +648,14 @@ help: Use `BaseHook` from `airflow.hooks.base` instead.
90 90 | # airflow.hooks
91 91 | BaseHook()
AIR301 [*] `airflow.sensors.base_sensor_operator.BaseSensorOperator` is removed in Airflow 3.0
--> AIR301_names_fix.py:96:1
AIR301_names_fix.py:96:1: AIR301 [*] `airflow.sensors.base_sensor_operator.BaseSensorOperator` is removed in Airflow 3.0
|
95 | # airflow.sensors.base_sensor_operator
96 | BaseSensorOperator()
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^ AIR301
97 | BaseHook()
|
help: Use `BaseSensorOperator` from `airflow.sdk.bases.sensor` instead.
= help: Use `BaseSensorOperator` from `airflow.sdk.bases.sensor` instead.
Unsafe fix
90 90 | # airflow.hooks
@@ -695,17 +667,16 @@ help: Use `BaseSensorOperator` from `airflow.sdk.bases.sensor` instead.
95 95 | # airflow.sensors.base_sensor_operator
96 96 | BaseSensorOperator()
AIR301 [*] `airflow.hooks.base_hook.BaseHook` is removed in Airflow 3.0
--> AIR301_names_fix.py:97:1
AIR301_names_fix.py:97:1: AIR301 [*] `airflow.hooks.base_hook.BaseHook` is removed in Airflow 3.0
|
95 | # airflow.sensors.base_sensor_operator
96 | BaseSensorOperator()
97 | BaseHook()
| ^^^^^^^^
| ^^^^^^^^ AIR301
98 |
99 | from airflow.utils.helpers import chain as helper_chain
|
help: Use `BaseHook` from `airflow.hooks.base` instead.
= help: Use `BaseHook` from `airflow.hooks.base` instead.
Unsafe fix
85 85 |
@@ -722,15 +693,14 @@ help: Use `BaseHook` from `airflow.hooks.base` instead.
95 95 | # airflow.sensors.base_sensor_operator
96 96 | BaseSensorOperator()
AIR301 [*] `airflow.utils.helpers.chain` is removed in Airflow 3.0
--> AIR301_names_fix.py:103:1
AIR301_names_fix.py:103:1: AIR301 [*] `airflow.utils.helpers.chain` is removed in Airflow 3.0
|
102 | # airflow.utils.helpers
103 | helper_chain
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ AIR301
104 | helper_cross_downstream
|
help: Use `chain` from `airflow.sdk` instead.
= help: Use `chain` from `airflow.sdk` instead.
Safe fix
98 98 |
@@ -745,17 +715,16 @@ help: Use `chain` from `airflow.sdk` instead.
105 106 |
106 107 | # airflow.utils.file
AIR301 [*] `airflow.utils.helpers.cross_downstream` is removed in Airflow 3.0
--> AIR301_names_fix.py:104:1
AIR301_names_fix.py:104:1: AIR301 [*] `airflow.utils.helpers.cross_downstream` is removed in Airflow 3.0
|
102 | # airflow.utils.helpers
103 | helper_chain
104 | helper_cross_downstream
| ^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^ AIR301
105 |
106 | # airflow.utils.file
|
help: Use `cross_downstream` from `airflow.sdk` instead.
= help: Use `cross_downstream` from `airflow.sdk` instead.
Safe fix
98 98 |
@@ -771,17 +740,16 @@ help: Use `cross_downstream` from `airflow.sdk` instead.
106 107 | # airflow.utils.file
107 108 | from airflow.utils.file import TemporaryDirectory
AIR301 [*] `airflow.utils.file.TemporaryDirectory` is removed in Airflow 3.0
--> AIR301_names_fix.py:109:1
AIR301_names_fix.py:109:1: AIR301 [*] `airflow.utils.file.TemporaryDirectory` is removed in Airflow 3.0
|
107 | from airflow.utils.file import TemporaryDirectory
108 |
109 | TemporaryDirectory()
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^ AIR301
110 |
111 | from airflow.utils.log import secrets_masker
|
help: Use `TemporaryDirectory` from `tempfile` instead.
= help: Use `TemporaryDirectory` from `tempfile` instead.
Unsafe fix
104 104 | helper_cross_downstream
@@ -793,14 +761,13 @@ help: Use `TemporaryDirectory` from `tempfile` instead.
109 109 | TemporaryDirectory()
110 110 |
AIR301 [*] `airflow.utils.log.secrets_masker` is removed in Airflow 3.0
--> AIR301_names_fix.py:114:1
AIR301_names_fix.py:114:1: AIR301 [*] `airflow.utils.log.secrets_masker` is removed in Airflow 3.0
|
113 | # airflow.utils.log
114 | secrets_masker
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ AIR301
|
help: Use `secrets_masker` from `airflow.sdk.execution_time` instead.
= help: Use `secrets_masker` from `airflow.sdk.execution_time` instead.
Unsafe fix
108 108 |

View File

@@ -1,17 +1,16 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR301 [*] `airflow.providers.amazon.aws.auth_manager.avp.entities.AvpEntities.DATASET` is removed in Airflow 3.0
--> AIR301_provider_names_fix.py:11:1
AIR301_provider_names_fix.py:11:1: AIR301 [*] `airflow.providers.amazon.aws.auth_manager.avp.entities.AvpEntities.DATASET` is removed in Airflow 3.0
|
9 | from airflow.security.permissions import RESOURCE_DATASET
10 |
11 | AvpEntities.DATASET
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^ AIR301
12 |
13 | # airflow.providers.openlineage.utils.utils
|
help: Use `AvpEntities.ASSET` from `airflow.providers.amazon.aws.auth_manager.avp.entities` instead.
= help: Use `AvpEntities.ASSET` from `airflow.providers.amazon.aws.auth_manager.avp.entities` instead.
Safe fix
8 8 | from airflow.secrets.local_filesystem import load_connections
@@ -23,15 +22,14 @@ help: Use `AvpEntities.ASSET` from `airflow.providers.amazon.aws.auth_manager.av
13 13 | # airflow.providers.openlineage.utils.utils
14 14 | DatasetInfo()
AIR301 [*] `airflow.providers.openlineage.utils.utils.DatasetInfo` is removed in Airflow 3.0
--> AIR301_provider_names_fix.py:14:1
AIR301_provider_names_fix.py:14:1: AIR301 [*] `airflow.providers.openlineage.utils.utils.DatasetInfo` is removed in Airflow 3.0
|
13 | # airflow.providers.openlineage.utils.utils
14 | DatasetInfo()
| ^^^^^^^^^^^
| ^^^^^^^^^^^ AIR301
15 | translate_airflow_dataset()
|
help: Use `AssetInfo` from `airflow.providers.openlineage.utils.utils` instead.
= help: Use `AssetInfo` from `airflow.providers.openlineage.utils.utils` instead.
Safe fix
4 4 | from airflow.providers.openlineage.utils.utils import (
@@ -51,17 +49,16 @@ help: Use `AssetInfo` from `airflow.providers.openlineage.utils.utils` instead.
16 17 |
17 18 | # airflow.secrets.local_filesystem
AIR301 [*] `airflow.providers.openlineage.utils.utils.translate_airflow_dataset` is removed in Airflow 3.0
--> AIR301_provider_names_fix.py:15:1
AIR301_provider_names_fix.py:15:1: AIR301 [*] `airflow.providers.openlineage.utils.utils.translate_airflow_dataset` is removed in Airflow 3.0
|
13 | # airflow.providers.openlineage.utils.utils
14 | DatasetInfo()
15 | translate_airflow_dataset()
| ^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301
16 |
17 | # airflow.secrets.local_filesystem
|
help: Use `translate_airflow_asset` from `airflow.providers.openlineage.utils.utils` instead.
= help: Use `translate_airflow_asset` from `airflow.providers.openlineage.utils.utils` instead.
Safe fix
4 4 | from airflow.providers.openlineage.utils.utils import (
@@ -81,16 +78,15 @@ help: Use `translate_airflow_asset` from `airflow.providers.openlineage.utils.ut
17 18 | # airflow.secrets.local_filesystem
18 19 | load_connections()
AIR301 [*] `airflow.secrets.local_filesystem.load_connections` is removed in Airflow 3.0
--> AIR301_provider_names_fix.py:18:1
AIR301_provider_names_fix.py:18:1: AIR301 [*] `airflow.secrets.local_filesystem.load_connections` is removed in Airflow 3.0
|
17 | # airflow.secrets.local_filesystem
18 | load_connections()
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^ AIR301
19 |
20 | # airflow.security.permissions
|
help: Use `load_connections_dict` from `airflow.secrets.local_filesystem` instead.
= help: Use `load_connections_dict` from `airflow.secrets.local_filesystem` instead.
Safe fix
5 5 | DatasetInfo,
@@ -111,16 +107,15 @@ help: Use `load_connections_dict` from `airflow.secrets.local_filesystem` instea
20 20 | # airflow.security.permissions
21 21 | RESOURCE_DATASET
AIR301 [*] `airflow.security.permissions.RESOURCE_DATASET` is removed in Airflow 3.0
--> AIR301_provider_names_fix.py:21:1
AIR301_provider_names_fix.py:21:1: AIR301 [*] `airflow.security.permissions.RESOURCE_DATASET` is removed in Airflow 3.0
|
20 | # airflow.security.permissions
21 | RESOURCE_DATASET
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^ AIR301
22 |
23 | from airflow.providers.amazon.aws.datasets.s3 import (
|
help: Use `RESOURCE_ASSET` from `airflow.security.permissions` instead.
= help: Use `RESOURCE_ASSET` from `airflow.security.permissions` instead.
Safe fix
6 6 | translate_airflow_dataset,
@@ -141,16 +136,15 @@ help: Use `RESOURCE_ASSET` from `airflow.security.permissions` instead.
23 23 | from airflow.providers.amazon.aws.datasets.s3 import (
24 24 | convert_dataset_to_openlineage as s3_convert_dataset_to_openlineage,
AIR301 [*] `airflow.providers.amazon.aws.datasets.s3.create_dataset` is removed in Airflow 3.0
--> AIR301_provider_names_fix.py:28:1
AIR301_provider_names_fix.py:28:1: AIR301 [*] `airflow.providers.amazon.aws.datasets.s3.create_dataset` is removed in Airflow 3.0
|
26 | from airflow.providers.amazon.aws.datasets.s3 import create_dataset as s3_create_dataset
27 |
28 | s3_create_dataset()
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ AIR301
29 | s3_convert_dataset_to_openlineage()
|
help: Use `create_asset` from `airflow.providers.amazon.aws.assets.s3` instead.
= help: Use `create_asset` from `airflow.providers.amazon.aws.assets.s3` instead.
Safe fix
24 24 | convert_dataset_to_openlineage as s3_convert_dataset_to_openlineage,
@@ -164,16 +158,15 @@ help: Use `create_asset` from `airflow.providers.amazon.aws.assets.s3` instead.
30 31 |
31 32 | from airflow.providers.common.io.dataset.file import (
AIR301 [*] `airflow.providers.amazon.aws.datasets.s3.convert_dataset_to_openlineage` is removed in Airflow 3.0
--> AIR301_provider_names_fix.py:29:1
AIR301_provider_names_fix.py:29:1: AIR301 [*] `airflow.providers.amazon.aws.datasets.s3.convert_dataset_to_openlineage` is removed in Airflow 3.0
|
28 | s3_create_dataset()
29 | s3_convert_dataset_to_openlineage()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301
30 |
31 | from airflow.providers.common.io.dataset.file import (
|
help: Use `convert_asset_to_openlineage` from `airflow.providers.amazon.aws.assets.s3` instead.
= help: Use `convert_asset_to_openlineage` from `airflow.providers.amazon.aws.assets.s3` instead.
Safe fix
24 24 | convert_dataset_to_openlineage as s3_convert_dataset_to_openlineage,
@@ -188,17 +181,16 @@ help: Use `convert_asset_to_openlineage` from `airflow.providers.amazon.aws.asse
31 32 | from airflow.providers.common.io.dataset.file import (
32 33 | convert_dataset_to_openlineage as io_convert_dataset_to_openlineage,
AIR301 [*] `airflow.providers.google.datasets.bigquery.create_dataset` is removed in Airflow 3.0
--> AIR301_provider_names_fix.py:45:1
AIR301_provider_names_fix.py:45:1: AIR301 [*] `airflow.providers.google.datasets.bigquery.create_dataset` is removed in Airflow 3.0
|
43 | )
44 |
45 | bigquery_create_dataset()
| ^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^ AIR301
46 |
47 | # airflow.providers.google.datasets.gcs
|
help: Use `create_asset` from `airflow.providers.google.assets.bigquery` instead.
= help: Use `create_asset` from `airflow.providers.google.assets.bigquery` instead.
Safe fix
41 41 | from airflow.providers.google.datasets.bigquery import (
@@ -212,16 +204,15 @@ help: Use `create_asset` from `airflow.providers.google.assets.bigquery` instead
47 48 | # airflow.providers.google.datasets.gcs
48 49 | from airflow.providers.google.datasets.gcs import (
AIR301 [*] `airflow.providers.google.datasets.gcs.create_dataset` is removed in Airflow 3.0
--> AIR301_provider_names_fix.py:53:1
AIR301_provider_names_fix.py:53:1: AIR301 [*] `airflow.providers.google.datasets.gcs.create_dataset` is removed in Airflow 3.0
|
51 | from airflow.providers.google.datasets.gcs import create_dataset as gcs_create_dataset
52 |
53 | gcs_create_dataset()
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^ AIR301
54 | gcs_convert_dataset_to_openlineage()
|
help: Use `create_asset` from `airflow.providers.google.assets.gcs` instead.
= help: Use `create_asset` from `airflow.providers.google.assets.gcs` instead.
Safe fix
49 49 | convert_dataset_to_openlineage as gcs_convert_dataset_to_openlineage,
@@ -233,14 +224,13 @@ help: Use `create_asset` from `airflow.providers.google.assets.gcs` instead.
54 |+create_asset()
54 55 | gcs_convert_dataset_to_openlineage()
AIR301 [*] `airflow.providers.google.datasets.gcs.convert_dataset_to_openlineage` is removed in Airflow 3.0
--> AIR301_provider_names_fix.py:54:1
AIR301_provider_names_fix.py:54:1: AIR301 [*] `airflow.providers.google.datasets.gcs.convert_dataset_to_openlineage` is removed in Airflow 3.0
|
53 | gcs_create_dataset()
54 | gcs_convert_dataset_to_openlineage()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR301
|
help: Use `convert_asset_to_openlineage` from `airflow.providers.google.assets.gcs` instead.
= help: Use `convert_asset_to_openlineage` from `airflow.providers.google.assets.gcs` instead.
Safe fix
49 49 | convert_dataset_to_openlineage as gcs_convert_dataset_to_openlineage,

View File

@@ -1,16 +1,15 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR302 [*] `airflow.hooks.S3_hook.S3Hook` is moved into `amazon` provider in Airflow 3.0;
--> AIR302_amazon.py:14:1
AIR302_amazon.py:14:1: AIR302 [*] `airflow.hooks.S3_hook.S3Hook` is moved into `amazon` provider in Airflow 3.0;
|
12 | from airflow.sensors.s3_key_sensor import S3KeySensor
13 |
14 | S3Hook()
| ^^^^^^
| ^^^^^^ AIR302
15 | provide_bucket_name()
|
help: Install `apache-airflow-providers-amazon>=1.0.0` and use `S3Hook` from `airflow.providers.amazon.aws.hooks.s3` instead.
= help: Install `apache-airflow-providers-amazon>=1.0.0` and use `S3Hook` from `airflow.providers.amazon.aws.hooks.s3` instead.
Unsafe fix
1 1 | from __future__ import annotations
@@ -29,16 +28,15 @@ help: Install `apache-airflow-providers-amazon>=1.0.0` and use `S3Hook` from `ai
14 14 | S3Hook()
15 15 | provide_bucket_name()
AIR302 [*] `airflow.hooks.S3_hook.provide_bucket_name` is moved into `amazon` provider in Airflow 3.0;
--> AIR302_amazon.py:15:1
AIR302_amazon.py:15:1: AIR302 [*] `airflow.hooks.S3_hook.provide_bucket_name` is moved into `amazon` provider in Airflow 3.0;
|
14 | S3Hook()
15 | provide_bucket_name()
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^ AIR302
16 |
17 | GCSToS3Operator()
|
help: Install `apache-airflow-providers-amazon>=1.0.0` and use `provide_bucket_name` from `airflow.providers.amazon.aws.hooks.s3` instead.
= help: Install `apache-airflow-providers-amazon>=1.0.0` and use `provide_bucket_name` from `airflow.providers.amazon.aws.hooks.s3` instead.
Unsafe fix
2 2 |
@@ -57,17 +55,16 @@ help: Install `apache-airflow-providers-amazon>=1.0.0` and use `provide_bucket_n
14 14 | S3Hook()
15 15 | provide_bucket_name()
AIR302 [*] `airflow.operators.gcs_to_s3.GCSToS3Operator` is moved into `amazon` provider in Airflow 3.0;
--> AIR302_amazon.py:17:1
AIR302_amazon.py:17:1: AIR302 [*] `airflow.operators.gcs_to_s3.GCSToS3Operator` is moved into `amazon` provider in Airflow 3.0;
|
15 | provide_bucket_name()
16 |
17 | GCSToS3Operator()
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^ AIR302
18 | GoogleApiToS3Operator()
19 | RedshiftToS3Operator()
|
help: Install `apache-airflow-providers-amazon>=1.0.0` and use `GCSToS3Operator` from `airflow.providers.amazon.aws.transfers.gcs_to_s3` instead.
= help: Install `apache-airflow-providers-amazon>=1.0.0` and use `GCSToS3Operator` from `airflow.providers.amazon.aws.transfers.gcs_to_s3` instead.
Unsafe fix
4 4 | S3Hook,
@@ -84,16 +81,15 @@ help: Install `apache-airflow-providers-amazon>=1.0.0` and use `GCSToS3Operator`
14 14 | S3Hook()
15 15 | provide_bucket_name()
AIR302 [*] `airflow.operators.google_api_to_s3_transfer.GoogleApiToS3Operator` is moved into `amazon` provider in Airflow 3.0;
--> AIR302_amazon.py:18:1
AIR302_amazon.py:18:1: AIR302 [*] `airflow.operators.google_api_to_s3_transfer.GoogleApiToS3Operator` is moved into `amazon` provider in Airflow 3.0;
|
17 | GCSToS3Operator()
18 | GoogleApiToS3Operator()
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ AIR302
19 | RedshiftToS3Operator()
20 | S3FileTransformOperator()
|
help: Install `apache-airflow-providers-amazon>=1.0.0` and use `GoogleApiToS3Operator` from `airflow.providers.amazon.aws.transfers.google_api_to_s3` instead.
= help: Install `apache-airflow-providers-amazon>=1.0.0` and use `GoogleApiToS3Operator` from `airflow.providers.amazon.aws.transfers.google_api_to_s3` instead.
Unsafe fix
5 5 | provide_bucket_name,
@@ -109,17 +105,16 @@ help: Install `apache-airflow-providers-amazon>=1.0.0` and use `GoogleApiToS3Ope
14 14 | S3Hook()
15 15 | provide_bucket_name()
AIR302 [*] `airflow.operators.redshift_to_s3_operator.RedshiftToS3Operator` is moved into `amazon` provider in Airflow 3.0;
--> AIR302_amazon.py:19:1
AIR302_amazon.py:19:1: AIR302 [*] `airflow.operators.redshift_to_s3_operator.RedshiftToS3Operator` is moved into `amazon` provider in Airflow 3.0;
|
17 | GCSToS3Operator()
18 | GoogleApiToS3Operator()
19 | RedshiftToS3Operator()
| ^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^ AIR302
20 | S3FileTransformOperator()
21 | S3ToRedshiftOperator()
|
help: Install `apache-airflow-providers-amazon>=1.0.0` and use `RedshiftToS3Operator` from `airflow.providers.amazon.aws.transfers.redshift_to_s3` instead.
= help: Install `apache-airflow-providers-amazon>=1.0.0` and use `RedshiftToS3Operator` from `airflow.providers.amazon.aws.transfers.redshift_to_s3` instead.
Unsafe fix
6 6 | )
@@ -134,17 +129,16 @@ help: Install `apache-airflow-providers-amazon>=1.0.0` and use `RedshiftToS3Oper
14 14 | S3Hook()
15 15 | provide_bucket_name()
AIR302 [*] `airflow.operators.s3_file_transform_operator.S3FileTransformOperator` is moved into `amazon` provider in Airflow 3.0;
--> AIR302_amazon.py:20:1
AIR302_amazon.py:20:1: AIR302 [*] `airflow.operators.s3_file_transform_operator.S3FileTransformOperator` is moved into `amazon` provider in Airflow 3.0;
|
18 | GoogleApiToS3Operator()
19 | RedshiftToS3Operator()
20 | S3FileTransformOperator()
| ^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^ AIR302
21 | S3ToRedshiftOperator()
22 | S3KeySensor()
|
help: Install `apache-airflow-providers-amazon>=3.0.0` and use `S3FileTransformOperator` from `airflow.providers.amazon.aws.operators.s3` instead.
= help: Install `apache-airflow-providers-amazon>=3.0.0` and use `S3FileTransformOperator` from `airflow.providers.amazon.aws.operators.s3` instead.
Unsafe fix
7 7 | from airflow.operators.gcs_to_s3 import GCSToS3Operator
@@ -158,16 +152,15 @@ help: Install `apache-airflow-providers-amazon>=3.0.0` and use `S3FileTransformO
14 14 | S3Hook()
15 15 | provide_bucket_name()
AIR302 [*] `airflow.operators.s3_to_redshift_operator.S3ToRedshiftOperator` is moved into `amazon` provider in Airflow 3.0;
--> AIR302_amazon.py:21:1
AIR302_amazon.py:21:1: AIR302 [*] `airflow.operators.s3_to_redshift_operator.S3ToRedshiftOperator` is moved into `amazon` provider in Airflow 3.0;
|
19 | RedshiftToS3Operator()
20 | S3FileTransformOperator()
21 | S3ToRedshiftOperator()
| ^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^ AIR302
22 | S3KeySensor()
|
help: Install `apache-airflow-providers-amazon>=1.0.0` and use `S3ToRedshiftOperator` from `airflow.providers.amazon.aws.transfers.s3_to_redshift` instead.
= help: Install `apache-airflow-providers-amazon>=1.0.0` and use `S3ToRedshiftOperator` from `airflow.providers.amazon.aws.transfers.s3_to_redshift` instead.
Unsafe fix
8 8 | from airflow.operators.google_api_to_s3_transfer import GoogleApiToS3Operator
@@ -180,17 +173,16 @@ help: Install `apache-airflow-providers-amazon>=1.0.0` and use `S3ToRedshiftOper
14 14 | S3Hook()
15 15 | provide_bucket_name()
AIR302 [*] `airflow.sensors.s3_key_sensor.S3KeySensor` is moved into `amazon` provider in Airflow 3.0;
--> AIR302_amazon.py:22:1
AIR302_amazon.py:22:1: AIR302 [*] `airflow.sensors.s3_key_sensor.S3KeySensor` is moved into `amazon` provider in Airflow 3.0;
|
20 | S3FileTransformOperator()
21 | S3ToRedshiftOperator()
22 | S3KeySensor()
| ^^^^^^^^^^^
| ^^^^^^^^^^^ AIR302
23 |
24 | from airflow.operators.google_api_to_s3_transfer import GoogleApiToS3Transfer
|
help: Install `apache-airflow-providers-amazon>=1.0.0` and use `S3KeySensor` from `airflow.providers.amazon.aws.sensors.s3` instead.
= help: Install `apache-airflow-providers-amazon>=1.0.0` and use `S3KeySensor` from `airflow.providers.amazon.aws.sensors.s3` instead.
Unsafe fix
9 9 | from airflow.operators.redshift_to_s3_operator import RedshiftToS3Operator
@@ -202,17 +194,16 @@ help: Install `apache-airflow-providers-amazon>=1.0.0` and use `S3KeySensor` fro
14 14 | S3Hook()
15 15 | provide_bucket_name()
AIR302 [*] `airflow.operators.google_api_to_s3_transfer.GoogleApiToS3Transfer` is moved into `amazon` provider in Airflow 3.0;
--> AIR302_amazon.py:26:1
AIR302_amazon.py:26:1: AIR302 [*] `airflow.operators.google_api_to_s3_transfer.GoogleApiToS3Transfer` is moved into `amazon` provider in Airflow 3.0;
|
24 | from airflow.operators.google_api_to_s3_transfer import GoogleApiToS3Transfer
25 |
26 | GoogleApiToS3Transfer()
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ AIR302
27 |
28 | from airflow.operators.redshift_to_s3_operator import RedshiftToS3Transfer
|
help: Install `apache-airflow-providers-amazon>=1.0.0` and use `GoogleApiToS3Operator` from `airflow.providers.amazon.aws.transfers.google_api_to_s3` instead.
= help: Install `apache-airflow-providers-amazon>=1.0.0` and use `GoogleApiToS3Operator` from `airflow.providers.amazon.aws.transfers.google_api_to_s3` instead.
Unsafe fix
22 22 | S3KeySensor()
@@ -223,17 +214,16 @@ help: Install `apache-airflow-providers-amazon>=1.0.0` and use `GoogleApiToS3Ope
26 27 | GoogleApiToS3Transfer()
27 28 |
AIR302 [*] `airflow.operators.redshift_to_s3_operator.RedshiftToS3Transfer` is moved into `amazon` provider in Airflow 3.0;
--> AIR302_amazon.py:30:1
AIR302_amazon.py:30:1: AIR302 [*] `airflow.operators.redshift_to_s3_operator.RedshiftToS3Transfer` is moved into `amazon` provider in Airflow 3.0;
|
28 | from airflow.operators.redshift_to_s3_operator import RedshiftToS3Transfer
29 |
30 | RedshiftToS3Transfer()
| ^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^ AIR302
31 |
32 | from airflow.operators.s3_to_redshift_operator import S3ToRedshiftTransfer
|
help: Install `apache-airflow-providers-amazon>=1.0.0` and use `RedshiftToS3Operator` from `airflow.providers.amazon.aws.transfers.redshift_to_s3` instead.
= help: Install `apache-airflow-providers-amazon>=1.0.0` and use `RedshiftToS3Operator` from `airflow.providers.amazon.aws.transfers.redshift_to_s3` instead.
Unsafe fix
26 26 | GoogleApiToS3Transfer()
@@ -244,15 +234,14 @@ help: Install `apache-airflow-providers-amazon>=1.0.0` and use `RedshiftToS3Oper
30 31 | RedshiftToS3Transfer()
31 32 |
AIR302 [*] `airflow.operators.s3_to_redshift_operator.S3ToRedshiftTransfer` is moved into `amazon` provider in Airflow 3.0;
--> AIR302_amazon.py:34:1
AIR302_amazon.py:34:1: AIR302 [*] `airflow.operators.s3_to_redshift_operator.S3ToRedshiftTransfer` is moved into `amazon` provider in Airflow 3.0;
|
32 | from airflow.operators.s3_to_redshift_operator import S3ToRedshiftTransfer
33 |
34 | S3ToRedshiftTransfer()
| ^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-amazon>=1.0.0` and use `S3ToRedshiftOperator` from `airflow.providers.amazon.aws.transfers.s3_to_redshift` instead.
= help: Install `apache-airflow-providers-amazon>=1.0.0` and use `S3ToRedshiftOperator` from `airflow.providers.amazon.aws.transfers.s3_to_redshift` instead.
Unsafe fix
30 30 | RedshiftToS3Transfer()

View File

@@ -1,17 +1,16 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR302 [*] `airflow.config_templates.default_celery.DEFAULT_CELERY_CONFIG` is moved into `celery` provider in Airflow 3.0;
--> AIR302_celery.py:9:1
AIR302_celery.py:9:1: AIR302 [*] `airflow.config_templates.default_celery.DEFAULT_CELERY_CONFIG` is moved into `celery` provider in Airflow 3.0;
|
7 | )
8 |
9 | DEFAULT_CELERY_CONFIG
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ AIR302
10 |
11 | app
|
help: Install `apache-airflow-providers-celery>=3.3.0` and use `DEFAULT_CELERY_CONFIG` from `airflow.providers.celery.executors.default_celery` instead.
= help: Install `apache-airflow-providers-celery>=3.3.0` and use `DEFAULT_CELERY_CONFIG` from `airflow.providers.celery.executors.default_celery` instead.
Unsafe fix
1 1 | from __future__ import annotations
@@ -26,16 +25,15 @@ help: Install `apache-airflow-providers-celery>=3.3.0` and use `DEFAULT_CELERY_C
9 9 | DEFAULT_CELERY_CONFIG
10 10 |
AIR302 [*] `airflow.executors.celery_executor.app` is moved into `celery` provider in Airflow 3.0;
--> AIR302_celery.py:11:1
AIR302_celery.py:11:1: AIR302 [*] `airflow.executors.celery_executor.app` is moved into `celery` provider in Airflow 3.0;
|
9 | DEFAULT_CELERY_CONFIG
10 |
11 | app
| ^^^
| ^^^ AIR302
12 | CeleryExecutor()
|
help: Install `apache-airflow-providers-celery>=3.3.0` and use `app` from `airflow.providers.celery.executors.celery_executor_utils` instead.
= help: Install `apache-airflow-providers-celery>=3.3.0` and use `app` from `airflow.providers.celery.executors.celery_executor_utils` instead.
Unsafe fix
3 3 | from airflow.config_templates.default_celery import DEFAULT_CELERY_CONFIG
@@ -48,14 +46,13 @@ help: Install `apache-airflow-providers-celery>=3.3.0` and use `app` from `airfl
9 9 | DEFAULT_CELERY_CONFIG
10 10 |
AIR302 [*] `airflow.executors.celery_executor.CeleryExecutor` is moved into `celery` provider in Airflow 3.0;
--> AIR302_celery.py:12:1
AIR302_celery.py:12:1: AIR302 [*] `airflow.executors.celery_executor.CeleryExecutor` is moved into `celery` provider in Airflow 3.0;
|
11 | app
12 | CeleryExecutor()
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-celery>=3.3.0` and use `CeleryExecutor` from `airflow.providers.celery.executors.celery_executor` instead.
= help: Install `apache-airflow-providers-celery>=3.3.0` and use `CeleryExecutor` from `airflow.providers.celery.executors.celery_executor` instead.
Unsafe fix
2 2 |

View File

@@ -1,16 +1,15 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR302 [*] `airflow.hooks.dbapi.ConnectorProtocol` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:8:1
AIR302_common_sql.py:8:1: AIR302 [*] `airflow.hooks.dbapi.ConnectorProtocol` is moved into `common-sql` provider in Airflow 3.0;
|
6 | )
7 |
8 | ConnectorProtocol()
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ AIR302
9 | DbApiHook()
|
help: Install `apache-airflow-providers-common-sql>=1.0.0` and use `ConnectorProtocol` from `airflow.providers.common.sql.hooks.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.0.0` and use `ConnectorProtocol` from `airflow.providers.common.sql.hooks.sql` instead.
Unsafe fix
1 1 | from __future__ import annotations
@@ -24,16 +23,15 @@ help: Install `apache-airflow-providers-common-sql>=1.0.0` and use `ConnectorPro
8 8 | ConnectorProtocol()
9 9 | DbApiHook()
AIR302 [*] `airflow.hooks.dbapi.DbApiHook` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:9:1
AIR302_common_sql.py:9:1: AIR302 [*] `airflow.hooks.dbapi.DbApiHook` is moved into `common-sql` provider in Airflow 3.0;
|
8 | ConnectorProtocol()
9 | DbApiHook()
| ^^^^^^^^^
| ^^^^^^^^^ AIR302
10 |
11 | from airflow.hooks.dbapi_hook import DbApiHook
|
help: Install `apache-airflow-providers-common-sql>=1.0.0` and use `DbApiHook` from `airflow.providers.common.sql.hooks.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.0.0` and use `DbApiHook` from `airflow.providers.common.sql.hooks.sql` instead.
Unsafe fix
2 2 |
@@ -46,16 +44,15 @@ help: Install `apache-airflow-providers-common-sql>=1.0.0` and use `DbApiHook` f
8 8 | ConnectorProtocol()
9 9 | DbApiHook()
AIR302 [*] `airflow.hooks.dbapi_hook.DbApiHook` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:14:1
AIR302_common_sql.py:14:1: AIR302 [*] `airflow.hooks.dbapi_hook.DbApiHook` is moved into `common-sql` provider in Airflow 3.0;
|
12 | from airflow.operators.check_operator import SQLCheckOperator
13 |
14 | DbApiHook()
| ^^^^^^^^^
| ^^^^^^^^^ AIR302
15 | SQLCheckOperator()
|
help: Install `apache-airflow-providers-common-sql>=1.0.0` and use `DbApiHook` from `airflow.providers.common.sql.hooks.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.0.0` and use `DbApiHook` from `airflow.providers.common.sql.hooks.sql` instead.
Unsafe fix
8 8 | ConnectorProtocol()
@@ -68,14 +65,13 @@ help: Install `apache-airflow-providers-common-sql>=1.0.0` and use `DbApiHook` f
14 14 | DbApiHook()
15 15 | SQLCheckOperator()
AIR302 [*] `airflow.operators.check_operator.SQLCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:15:1
AIR302_common_sql.py:15:1: AIR302 [*] `airflow.operators.check_operator.SQLCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
|
14 | DbApiHook()
15 | SQLCheckOperator()
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
9 9 | DbApiHook()
@@ -87,16 +83,15 @@ help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLCheckOper
14 14 | DbApiHook()
15 15 | SQLCheckOperator()
AIR302 [*] `airflow.operators.sql.SQLCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:21:1
AIR302_common_sql.py:21:1: AIR302 [*] `airflow.operators.sql.SQLCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
|
19 | from airflow.operators.sql import SQLCheckOperator
20 |
21 | SQLCheckOperator()
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^ AIR302
22 | CheckOperator()
|
help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
16 16 |
@@ -108,14 +103,13 @@ help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLCheckOper
21 21 | SQLCheckOperator()
22 22 | CheckOperator()
AIR302 [*] `airflow.operators.check_operator.CheckOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:22:1
AIR302_common_sql.py:22:1: AIR302 [*] `airflow.operators.check_operator.CheckOperator` is moved into `common-sql` provider in Airflow 3.0;
|
21 | SQLCheckOperator()
22 | CheckOperator()
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
17 17 |
@@ -126,15 +120,14 @@ help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLCheckOper
21 22 | SQLCheckOperator()
22 23 | CheckOperator()
AIR302 [*] `airflow.operators.druid_check_operator.CheckOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:27:1
AIR302_common_sql.py:27:1: AIR302 [*] `airflow.operators.druid_check_operator.CheckOperator` is moved into `common-sql` provider in Airflow 3.0;
|
25 | from airflow.operators.druid_check_operator import CheckOperator
26 |
27 | CheckOperator()
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
23 23 |
@@ -145,15 +138,14 @@ help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLCheckOper
27 28 | CheckOperator()
28 29 |
AIR302 [*] `airflow.operators.presto_check_operator.CheckOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:32:1
AIR302_common_sql.py:32:1: AIR302 [*] `airflow.operators.presto_check_operator.CheckOperator` is moved into `common-sql` provider in Airflow 3.0;
|
30 | from airflow.operators.presto_check_operator import CheckOperator
31 |
32 | CheckOperator()
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
28 28 |
@@ -164,17 +156,16 @@ help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLCheckOper
32 33 | CheckOperator()
33 34 |
AIR302 [*] `airflow.operators.druid_check_operator.DruidCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:42:1
AIR302_common_sql.py:42:1: AIR302 [*] `airflow.operators.druid_check_operator.DruidCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
|
40 | from airflow.operators.presto_check_operator import PrestoCheckOperator
41 |
42 | DruidCheckOperator()
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^ AIR302
43 | PrestoCheckOperator()
44 | IntervalCheckOperator()
|
help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
38 38 | )
@@ -185,16 +176,15 @@ help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLCheckOper
42 43 | DruidCheckOperator()
43 44 | PrestoCheckOperator()
AIR302 [*] `airflow.operators.presto_check_operator.PrestoCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:43:1
AIR302_common_sql.py:43:1: AIR302 [*] `airflow.operators.presto_check_operator.PrestoCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
|
42 | DruidCheckOperator()
43 | PrestoCheckOperator()
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^ AIR302
44 | IntervalCheckOperator()
45 | SQLIntervalCheckOperator()
|
help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
38 38 | )
@@ -205,16 +195,15 @@ help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLCheckOper
42 43 | DruidCheckOperator()
43 44 | PrestoCheckOperator()
AIR302 [*] `airflow.operators.check_operator.IntervalCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:44:1
AIR302_common_sql.py:44:1: AIR302 [*] `airflow.operators.check_operator.IntervalCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
|
42 | DruidCheckOperator()
43 | PrestoCheckOperator()
44 | IntervalCheckOperator()
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ AIR302
45 | SQLIntervalCheckOperator()
|
help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLIntervalCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLIntervalCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
34 34 |
@@ -229,15 +218,14 @@ help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLIntervalC
42 42 | DruidCheckOperator()
43 43 | PrestoCheckOperator()
AIR302 [*] `airflow.operators.check_operator.SQLIntervalCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:45:1
AIR302_common_sql.py:45:1: AIR302 [*] `airflow.operators.check_operator.SQLIntervalCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
|
43 | PrestoCheckOperator()
44 | IntervalCheckOperator()
45 | SQLIntervalCheckOperator()
| ^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLIntervalCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLIntervalCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
34 34 |
@@ -252,17 +240,16 @@ help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLIntervalC
42 42 | DruidCheckOperator()
43 43 | PrestoCheckOperator()
AIR302 [*] `airflow.operators.presto_check_operator.IntervalCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:54:1
AIR302_common_sql.py:54:1: AIR302 [*] `airflow.operators.presto_check_operator.IntervalCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
|
52 | from airflow.operators.sql import SQLIntervalCheckOperator
53 |
54 | IntervalCheckOperator()
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ AIR302
55 | SQLIntervalCheckOperator()
56 | PrestoIntervalCheckOperator()
|
help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLIntervalCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLIntervalCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
50 50 | PrestoIntervalCheckOperator,
@@ -273,15 +260,14 @@ help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLIntervalC
54 55 | IntervalCheckOperator()
55 56 | SQLIntervalCheckOperator()
AIR302 [*] `airflow.operators.sql.SQLIntervalCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:55:1
AIR302_common_sql.py:55:1: AIR302 [*] `airflow.operators.sql.SQLIntervalCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
|
54 | IntervalCheckOperator()
55 | SQLIntervalCheckOperator()
| ^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^ AIR302
56 | PrestoIntervalCheckOperator()
|
help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLIntervalCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLIntervalCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
49 49 | IntervalCheckOperator,
@@ -293,15 +279,14 @@ help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLIntervalC
54 54 | IntervalCheckOperator()
55 55 | SQLIntervalCheckOperator()
AIR302 [*] `airflow.operators.presto_check_operator.PrestoIntervalCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:56:1
AIR302_common_sql.py:56:1: AIR302 [*] `airflow.operators.presto_check_operator.PrestoIntervalCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
|
54 | IntervalCheckOperator()
55 | SQLIntervalCheckOperator()
56 | PrestoIntervalCheckOperator()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLIntervalCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLIntervalCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
50 50 | PrestoIntervalCheckOperator,
@@ -312,16 +297,15 @@ help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLIntervalC
54 55 | IntervalCheckOperator()
55 56 | SQLIntervalCheckOperator()
AIR302 [*] `airflow.operators.check_operator.SQLThresholdCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:64:1
AIR302_common_sql.py:64:1: AIR302 [*] `airflow.operators.check_operator.SQLThresholdCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
|
62 | )
63 |
64 | SQLThresholdCheckOperator()
| ^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^ AIR302
65 | ThresholdCheckOperator()
|
help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLThresholdCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLThresholdCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
57 57 |
@@ -335,14 +319,13 @@ help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLThreshold
64 64 | SQLThresholdCheckOperator()
65 65 | ThresholdCheckOperator()
AIR302 [*] `airflow.operators.check_operator.ThresholdCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:65:1
AIR302_common_sql.py:65:1: AIR302 [*] `airflow.operators.check_operator.ThresholdCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
|
64 | SQLThresholdCheckOperator()
65 | ThresholdCheckOperator()
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLThresholdCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLThresholdCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
57 57 |
@@ -356,15 +339,14 @@ help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLThreshold
64 64 | SQLThresholdCheckOperator()
65 65 | ThresholdCheckOperator()
AIR302 [*] `airflow.operators.sql.SQLThresholdCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:70:1
AIR302_common_sql.py:70:1: AIR302 [*] `airflow.operators.sql.SQLThresholdCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
|
68 | from airflow.operators.sql import SQLThresholdCheckOperator
69 |
70 | SQLThresholdCheckOperator()
| ^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLThresholdCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLThresholdCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
65 65 | ThresholdCheckOperator()
@@ -376,16 +358,15 @@ help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLThreshold
70 70 | SQLThresholdCheckOperator()
71 71 |
AIR302 [*] `airflow.operators.check_operator.SQLValueCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:78:1
AIR302_common_sql.py:78:1: AIR302 [*] `airflow.operators.check_operator.SQLValueCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
|
76 | )
77 |
78 | SQLValueCheckOperator()
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ AIR302
79 | ValueCheckOperator()
|
help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLValueCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLValueCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
71 71 |
@@ -399,14 +380,13 @@ help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLValueChec
78 78 | SQLValueCheckOperator()
79 79 | ValueCheckOperator()
AIR302 [*] `airflow.operators.check_operator.ValueCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:79:1
AIR302_common_sql.py:79:1: AIR302 [*] `airflow.operators.check_operator.ValueCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
|
78 | SQLValueCheckOperator()
79 | ValueCheckOperator()
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLValueCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLValueCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
71 71 |
@@ -420,17 +400,16 @@ help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLValueChec
78 78 | SQLValueCheckOperator()
79 79 | ValueCheckOperator()
AIR302 [*] `airflow.operators.sql.SQLValueCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:88:1
AIR302_common_sql.py:88:1: AIR302 [*] `airflow.operators.sql.SQLValueCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
|
86 | from airflow.operators.sql import SQLValueCheckOperator
87 |
88 | SQLValueCheckOperator()
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ AIR302
89 | ValueCheckOperator()
90 | PrestoValueCheckOperator()
|
help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLValueCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLValueCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
83 83 | PrestoValueCheckOperator,
@@ -442,15 +421,14 @@ help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLValueChec
88 88 | SQLValueCheckOperator()
89 89 | ValueCheckOperator()
AIR302 [*] `airflow.operators.presto_check_operator.ValueCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:89:1
AIR302_common_sql.py:89:1: AIR302 [*] `airflow.operators.presto_check_operator.ValueCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
|
88 | SQLValueCheckOperator()
89 | ValueCheckOperator()
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^ AIR302
90 | PrestoValueCheckOperator()
|
help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLValueCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLValueCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
84 84 | ValueCheckOperator,
@@ -461,15 +439,14 @@ help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLValueChec
88 89 | SQLValueCheckOperator()
89 90 | ValueCheckOperator()
AIR302 [*] `airflow.operators.presto_check_operator.PrestoValueCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:90:1
AIR302_common_sql.py:90:1: AIR302 [*] `airflow.operators.presto_check_operator.PrestoValueCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
|
88 | SQLValueCheckOperator()
89 | ValueCheckOperator()
90 | PrestoValueCheckOperator()
| ^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLValueCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLValueCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
84 84 | ValueCheckOperator,
@@ -480,17 +457,16 @@ help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLValueChec
88 89 | SQLValueCheckOperator()
89 90 | ValueCheckOperator()
AIR302 [*] `airflow.operators.sql.BaseSQLOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:102:1
AIR302_common_sql.py:102:1: AIR302 [*] `airflow.operators.sql.BaseSQLOperator` is moved into `common-sql` provider in Airflow 3.0;
|
100 | )
101 |
102 | BaseSQLOperator()
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^ AIR302
103 | BranchSQLOperator()
104 | SQLTableCheckOperator()
|
help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `BaseSQLOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `BaseSQLOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
91 91 |
@@ -508,16 +484,15 @@ help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `BaseSQLOpera
102 102 | BaseSQLOperator()
103 103 | BranchSQLOperator()
AIR302 [*] `airflow.operators.sql.BranchSQLOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:103:1
AIR302_common_sql.py:103:1: AIR302 [*] `airflow.operators.sql.BranchSQLOperator` is moved into `common-sql` provider in Airflow 3.0;
|
102 | BaseSQLOperator()
103 | BranchSQLOperator()
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ AIR302
104 | SQLTableCheckOperator()
105 | SQLColumnCheckOperator()
|
help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `BranchSQLOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `BranchSQLOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
92 92 |
@@ -534,17 +509,16 @@ help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `BranchSQLOpe
102 102 | BaseSQLOperator()
103 103 | BranchSQLOperator()
AIR302 [*] `airflow.operators.sql.SQLTableCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:104:1
AIR302_common_sql.py:104:1: AIR302 [*] `airflow.operators.sql.SQLTableCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
|
102 | BaseSQLOperator()
103 | BranchSQLOperator()
104 | SQLTableCheckOperator()
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ AIR302
105 | SQLColumnCheckOperator()
106 | _convert_to_float_if_possible()
|
help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLTableCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLTableCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
94 94 | BaseSQLOperator,
@@ -559,17 +533,16 @@ help: Install `apache-airflow-providers-common-sql>=1.1.0` and use `SQLTableChec
102 102 | BaseSQLOperator()
103 103 | BranchSQLOperator()
AIR302 [*] `airflow.operators.sql.SQLColumnCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:105:1
AIR302_common_sql.py:105:1: AIR302 [*] `airflow.operators.sql.SQLColumnCheckOperator` is moved into `common-sql` provider in Airflow 3.0;
|
103 | BranchSQLOperator()
104 | SQLTableCheckOperator()
105 | SQLColumnCheckOperator()
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^ AIR302
106 | _convert_to_float_if_possible()
107 | parse_boolean()
|
help: Install `apache-airflow-providers-common-sql>=1.0.0` and use `SQLColumnCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.0.0` and use `SQLColumnCheckOperator` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
93 93 | from airflow.operators.sql import (
@@ -585,16 +558,15 @@ help: Install `apache-airflow-providers-common-sql>=1.0.0` and use `SQLColumnChe
102 102 | BaseSQLOperator()
103 103 | BranchSQLOperator()
AIR302 [*] `airflow.operators.sql._convert_to_float_if_possible` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:106:1
AIR302_common_sql.py:106:1: AIR302 [*] `airflow.operators.sql._convert_to_float_if_possible` is moved into `common-sql` provider in Airflow 3.0;
|
104 | SQLTableCheckOperator()
105 | SQLColumnCheckOperator()
106 | _convert_to_float_if_possible()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR302
107 | parse_boolean()
|
help: Install `apache-airflow-providers-common-sql>=1.0.0` and use `_convert_to_float_if_possible` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.0.0` and use `_convert_to_float_if_possible` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
95 95 | BranchSQLOperator,
@@ -608,15 +580,14 @@ help: Install `apache-airflow-providers-common-sql>=1.0.0` and use `_convert_to_
102 102 | BaseSQLOperator()
103 103 | BranchSQLOperator()
AIR302 [*] `airflow.operators.sql.parse_boolean` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:107:1
AIR302_common_sql.py:107:1: AIR302 [*] `airflow.operators.sql.parse_boolean` is moved into `common-sql` provider in Airflow 3.0;
|
105 | SQLColumnCheckOperator()
106 | _convert_to_float_if_possible()
107 | parse_boolean()
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-common-sql>=1.0.0` and use `parse_boolean` from `airflow.providers.common.sql.operators.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.0.0` and use `parse_boolean` from `airflow.providers.common.sql.operators.sql` instead.
Unsafe fix
96 96 | SQLColumnCheckOperator,
@@ -629,15 +600,14 @@ help: Install `apache-airflow-providers-common-sql>=1.0.0` and use `parse_boolea
102 102 | BaseSQLOperator()
103 103 | BranchSQLOperator()
AIR302 [*] `airflow.sensors.sql.SqlSensor` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:112:1
AIR302_common_sql.py:112:1: AIR302 [*] `airflow.sensors.sql.SqlSensor` is moved into `common-sql` provider in Airflow 3.0;
|
110 | from airflow.sensors.sql import SqlSensor
111 |
112 | SqlSensor()
| ^^^^^^^^^
| ^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-common-sql>=1.0.0` and use `SqlSensor` from `airflow.providers.common.sql.sensors.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.0.0` and use `SqlSensor` from `airflow.providers.common.sql.sensors.sql` instead.
Unsafe fix
107 107 | parse_boolean()
@@ -649,15 +619,14 @@ help: Install `apache-airflow-providers-common-sql>=1.0.0` and use `SqlSensor` f
112 112 | SqlSensor()
113 113 |
AIR302 [*] `airflow.sensors.sql_sensor.SqlSensor` is moved into `common-sql` provider in Airflow 3.0;
--> AIR302_common_sql.py:117:1
AIR302_common_sql.py:117:1: AIR302 [*] `airflow.sensors.sql_sensor.SqlSensor` is moved into `common-sql` provider in Airflow 3.0;
|
115 | from airflow.sensors.sql_sensor import SqlSensor
116 |
117 | SqlSensor()
| ^^^^^^^^^
| ^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-common-sql>=1.0.0` and use `SqlSensor` from `airflow.providers.common.sql.sensors.sql` instead.
= help: Install `apache-airflow-providers-common-sql>=1.0.0` and use `SqlSensor` from `airflow.providers.common.sql.sensors.sql` instead.
Unsafe fix
112 112 | SqlSensor()

View File

@@ -1,15 +1,14 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR302 [*] `airflow.executors.dask_executor.DaskExecutor` is moved into `daskexecutor` provider in Airflow 3.0;
--> AIR302_daskexecutor.py:5:1
AIR302_daskexecutor.py:5:1: AIR302 [*] `airflow.executors.dask_executor.DaskExecutor` is moved into `daskexecutor` provider in Airflow 3.0;
|
3 | from airflow.executors.dask_executor import DaskExecutor
4 |
5 | DaskExecutor()
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-daskexecutor>=1.0.0` and use `DaskExecutor` from `airflow.providers.daskexecutor.executors.dask_executor` instead.
= help: Install `apache-airflow-providers-daskexecutor>=1.0.0` and use `DaskExecutor` from `airflow.providers.daskexecutor.executors.dask_executor` instead.
Unsafe fix
1 1 | from __future__ import annotations

View File

@@ -1,16 +1,15 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR302 [*] `airflow.hooks.druid_hook.DruidDbApiHook` is moved into `apache-druid` provider in Airflow 3.0;
--> AIR302_druid.py:12:1
AIR302_druid.py:12:1: AIR302 [*] `airflow.hooks.druid_hook.DruidDbApiHook` is moved into `apache-druid` provider in Airflow 3.0;
|
10 | )
11 |
12 | DruidDbApiHook()
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ AIR302
13 | DruidHook()
|
help: Install `apache-airflow-providers-apache-druid>=1.0.0` and use `DruidDbApiHook` from `airflow.providers.apache.druid.hooks.druid` instead.
= help: Install `apache-airflow-providers-apache-druid>=1.0.0` and use `DruidDbApiHook` from `airflow.providers.apache.druid.hooks.druid` instead.
Unsafe fix
1 1 | from __future__ import annotations
@@ -28,16 +27,15 @@ help: Install `apache-airflow-providers-apache-druid>=1.0.0` and use `DruidDbApi
12 12 | DruidDbApiHook()
13 13 | DruidHook()
AIR302 [*] `airflow.hooks.druid_hook.DruidHook` is moved into `apache-druid` provider in Airflow 3.0;
--> AIR302_druid.py:13:1
AIR302_druid.py:13:1: AIR302 [*] `airflow.hooks.druid_hook.DruidHook` is moved into `apache-druid` provider in Airflow 3.0;
|
12 | DruidDbApiHook()
13 | DruidHook()
| ^^^^^^^^^
| ^^^^^^^^^ AIR302
14 |
15 | HiveToDruidOperator()
|
help: Install `apache-airflow-providers-apache-druid>=1.0.0` and use `DruidHook` from `airflow.providers.apache.druid.hooks.druid` instead.
= help: Install `apache-airflow-providers-apache-druid>=1.0.0` and use `DruidHook` from `airflow.providers.apache.druid.hooks.druid` instead.
Unsafe fix
2 2 |
@@ -54,16 +52,15 @@ help: Install `apache-airflow-providers-apache-druid>=1.0.0` and use `DruidHook`
12 12 | DruidDbApiHook()
13 13 | DruidHook()
AIR302 [*] `airflow.operators.hive_to_druid.HiveToDruidOperator` is moved into `apache-druid` provider in Airflow 3.0;
--> AIR302_druid.py:15:1
AIR302_druid.py:15:1: AIR302 [*] `airflow.operators.hive_to_druid.HiveToDruidOperator` is moved into `apache-druid` provider in Airflow 3.0;
|
13 | DruidHook()
14 |
15 | HiveToDruidOperator()
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^ AIR302
16 | HiveToDruidTransfer()
|
help: Install `apache-airflow-providers-apache-druid>=1.0.0` and use `HiveToDruidOperator` from `airflow.providers.apache.druid.transfers.hive_to_druid` instead.
= help: Install `apache-airflow-providers-apache-druid>=1.0.0` and use `HiveToDruidOperator` from `airflow.providers.apache.druid.transfers.hive_to_druid` instead.
Unsafe fix
5 5 | DruidHook,
@@ -77,14 +74,13 @@ help: Install `apache-airflow-providers-apache-druid>=1.0.0` and use `HiveToDrui
12 12 | DruidDbApiHook()
13 13 | DruidHook()
AIR302 [*] `airflow.operators.hive_to_druid.HiveToDruidTransfer` is moved into `apache-druid` provider in Airflow 3.0;
--> AIR302_druid.py:16:1
AIR302_druid.py:16:1: AIR302 [*] `airflow.operators.hive_to_druid.HiveToDruidTransfer` is moved into `apache-druid` provider in Airflow 3.0;
|
15 | HiveToDruidOperator()
16 | HiveToDruidTransfer()
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-apache-druid>=1.0.0` and use `HiveToDruidOperator` from `airflow.providers.apache.druid.transfers.hive_to_druid` instead.
= help: Install `apache-airflow-providers-apache-druid>=1.0.0` and use `HiveToDruidOperator` from `airflow.providers.apache.druid.transfers.hive_to_druid` instead.
Unsafe fix
5 5 | DruidHook,

View File

@@ -1,17 +1,16 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR302 [*] `airflow.api.auth.backend.basic_auth.CLIENT_AUTH` is moved into `fab` provider in Airflow 3.0;
--> AIR302_fab.py:10:1
AIR302_fab.py:10:1: AIR302 [*] `airflow.api.auth.backend.basic_auth.CLIENT_AUTH` is moved into `fab` provider in Airflow 3.0;
|
8 | )
9 |
10 | CLIENT_AUTH
| ^^^^^^^^^^^
| ^^^^^^^^^^^ AIR302
11 | init_app()
12 | auth_current_user()
|
help: Install `apache-airflow-providers-fab>=1.0.0` and use `CLIENT_AUTH` from `airflow.providers.fab.auth_manager.api.auth.backend.basic_auth` instead.
= help: Install `apache-airflow-providers-fab>=1.0.0` and use `CLIENT_AUTH` from `airflow.providers.fab.auth_manager.api.auth.backend.basic_auth` instead.
Unsafe fix
1 1 | from __future__ import annotations
@@ -27,16 +26,15 @@ help: Install `apache-airflow-providers-fab>=1.0.0` and use `CLIENT_AUTH` from `
10 10 | CLIENT_AUTH
11 11 | init_app()
AIR302 [*] `airflow.api.auth.backend.basic_auth.init_app` is moved into `fab` provider in Airflow 3.0;
--> AIR302_fab.py:11:1
AIR302_fab.py:11:1: AIR302 [*] `airflow.api.auth.backend.basic_auth.init_app` is moved into `fab` provider in Airflow 3.0;
|
10 | CLIENT_AUTH
11 | init_app()
| ^^^^^^^^
| ^^^^^^^^ AIR302
12 | auth_current_user()
13 | requires_authentication()
|
help: Install `apache-airflow-providers-fab>=1.0.0` and use `init_app` from `airflow.providers.fab.auth_manager.api.auth.backend.basic_auth` instead.
= help: Install `apache-airflow-providers-fab>=1.0.0` and use `init_app` from `airflow.providers.fab.auth_manager.api.auth.backend.basic_auth` instead.
Unsafe fix
3 3 | from airflow.api.auth.backend.basic_auth import (
@@ -50,16 +48,15 @@ help: Install `apache-airflow-providers-fab>=1.0.0` and use `init_app` from `air
10 10 | CLIENT_AUTH
11 11 | init_app()
AIR302 [*] `airflow.api.auth.backend.basic_auth.auth_current_user` is moved into `fab` provider in Airflow 3.0;
--> AIR302_fab.py:12:1
AIR302_fab.py:12:1: AIR302 [*] `airflow.api.auth.backend.basic_auth.auth_current_user` is moved into `fab` provider in Airflow 3.0;
|
10 | CLIENT_AUTH
11 | init_app()
12 | auth_current_user()
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ AIR302
13 | requires_authentication()
|
help: Install `apache-airflow-providers-fab>=1.0.0` and use `auth_current_user` from `airflow.providers.fab.auth_manager.api.auth.backend.basic_auth` instead.
= help: Install `apache-airflow-providers-fab>=1.0.0` and use `auth_current_user` from `airflow.providers.fab.auth_manager.api.auth.backend.basic_auth` instead.
Unsafe fix
2 2 |
@@ -74,17 +71,16 @@ help: Install `apache-airflow-providers-fab>=1.0.0` and use `auth_current_user`
10 10 | CLIENT_AUTH
11 11 | init_app()
AIR302 [*] `airflow.api.auth.backend.basic_auth.requires_authentication` is moved into `fab` provider in Airflow 3.0;
--> AIR302_fab.py:13:1
AIR302_fab.py:13:1: AIR302 [*] `airflow.api.auth.backend.basic_auth.requires_authentication` is moved into `fab` provider in Airflow 3.0;
|
11 | init_app()
12 | auth_current_user()
13 | requires_authentication()
| ^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^ AIR302
14 |
15 | from airflow.api.auth.backend.kerberos_auth import (
|
help: Install `apache-airflow-providers-fab>=1.0.0` and use `requires_authentication` from `airflow.providers.fab.auth_manager.api.auth.backend.basic_auth` instead.
= help: Install `apache-airflow-providers-fab>=1.0.0` and use `requires_authentication` from `airflow.providers.fab.auth_manager.api.auth.backend.basic_auth` instead.
Unsafe fix
4 4 | CLIENT_AUTH,
@@ -97,17 +93,16 @@ help: Install `apache-airflow-providers-fab>=1.0.0` and use `requires_authentica
10 10 | CLIENT_AUTH
11 11 | init_app()
AIR302 [*] `airflow.api.auth.backend.kerberos_auth.log` is moved into `fab` provider in Airflow 3.0;
--> AIR302_fab.py:23:1
AIR302_fab.py:23:1: AIR302 [*] `airflow.api.auth.backend.kerberos_auth.log` is moved into `fab` provider in Airflow 3.0;
|
21 | )
22 |
23 | log()
| ^^^
| ^^^ AIR302
24 | CLIENT_AUTH
25 | find_user()
|
help: Install `apache-airflow-providers-fab>=1.0.0` and use `log` from `airflow.providers.fab.auth_manager.api.auth.backend.kerberos_auth` instead.
= help: Install `apache-airflow-providers-fab>=1.0.0` and use `log` from `airflow.providers.fab.auth_manager.api.auth.backend.kerberos_auth` instead.
Unsafe fix
16 16 | CLIENT_AUTH,
@@ -121,16 +116,15 @@ help: Install `apache-airflow-providers-fab>=1.0.0` and use `log` from `airflow.
23 23 | log()
24 24 | CLIENT_AUTH
AIR302 [*] `airflow.api.auth.backend.kerberos_auth.CLIENT_AUTH` is moved into `fab` provider in Airflow 3.0;
--> AIR302_fab.py:24:1
AIR302_fab.py:24:1: AIR302 [*] `airflow.api.auth.backend.kerberos_auth.CLIENT_AUTH` is moved into `fab` provider in Airflow 3.0;
|
23 | log()
24 | CLIENT_AUTH
| ^^^^^^^^^^^
| ^^^^^^^^^^^ AIR302
25 | find_user()
26 | init_app()
|
help: Install `apache-airflow-providers-fab>=1.0.0` and use `CLIENT_AUTH` from `airflow.providers.fab.auth_manager.api.auth.backend.kerberos_auth` instead.
= help: Install `apache-airflow-providers-fab>=1.0.0` and use `CLIENT_AUTH` from `airflow.providers.fab.auth_manager.api.auth.backend.kerberos_auth` instead.
Unsafe fix
13 13 | requires_authentication()
@@ -147,17 +141,16 @@ help: Install `apache-airflow-providers-fab>=1.0.0` and use `CLIENT_AUTH` from `
23 23 | log()
24 24 | CLIENT_AUTH
AIR302 [*] `airflow.api.auth.backend.kerberos_auth.find_user` is moved into `fab` provider in Airflow 3.0;
--> AIR302_fab.py:25:1
AIR302_fab.py:25:1: AIR302 [*] `airflow.api.auth.backend.kerberos_auth.find_user` is moved into `fab` provider in Airflow 3.0;
|
23 | log()
24 | CLIENT_AUTH
25 | find_user()
| ^^^^^^^^^
| ^^^^^^^^^ AIR302
26 | init_app()
27 | requires_authentication()
|
help: Install `apache-airflow-providers-fab>=1.0.0` and use `find_user` from `airflow.providers.fab.auth_manager.api.auth.backend.kerberos_auth` instead.
= help: Install `apache-airflow-providers-fab>=1.0.0` and use `find_user` from `airflow.providers.fab.auth_manager.api.auth.backend.kerberos_auth` instead.
Unsafe fix
14 14 |
@@ -173,16 +166,15 @@ help: Install `apache-airflow-providers-fab>=1.0.0` and use `find_user` from `ai
23 23 | log()
24 24 | CLIENT_AUTH
AIR302 [*] `airflow.api.auth.backend.kerberos_auth.init_app` is moved into `fab` provider in Airflow 3.0;
--> AIR302_fab.py:26:1
AIR302_fab.py:26:1: AIR302 [*] `airflow.api.auth.backend.kerberos_auth.init_app` is moved into `fab` provider in Airflow 3.0;
|
24 | CLIENT_AUTH
25 | find_user()
26 | init_app()
| ^^^^^^^^
| ^^^^^^^^ AIR302
27 | requires_authentication()
|
help: Install `apache-airflow-providers-fab>=1.0.0` and use `init_app` from `airflow.providers.fab.auth_manager.api.auth.backend.kerberos_auth` instead.
= help: Install `apache-airflow-providers-fab>=1.0.0` and use `init_app` from `airflow.providers.fab.auth_manager.api.auth.backend.kerberos_auth` instead.
Unsafe fix
15 15 | from airflow.api.auth.backend.kerberos_auth import (
@@ -197,17 +189,16 @@ help: Install `apache-airflow-providers-fab>=1.0.0` and use `init_app` from `air
23 23 | log()
24 24 | CLIENT_AUTH
AIR302 [*] `airflow.api.auth.backend.kerberos_auth.requires_authentication` is moved into `fab` provider in Airflow 3.0;
--> AIR302_fab.py:27:1
AIR302_fab.py:27:1: AIR302 [*] `airflow.api.auth.backend.kerberos_auth.requires_authentication` is moved into `fab` provider in Airflow 3.0;
|
25 | find_user()
26 | init_app()
27 | requires_authentication()
| ^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^ AIR302
28 |
29 | from airflow.auth.managers.fab.api.auth.backend.kerberos_auth import (
|
help: Install `apache-airflow-providers-fab>=1.0.0` and use `requires_authentication` from `airflow.providers.fab.auth_manager.api.auth.backend.kerberos_auth` instead.
= help: Install `apache-airflow-providers-fab>=1.0.0` and use `requires_authentication` from `airflow.providers.fab.auth_manager.api.auth.backend.kerberos_auth` instead.
Unsafe fix
17 17 | find_user,
@@ -220,17 +211,16 @@ help: Install `apache-airflow-providers-fab>=1.0.0` and use `requires_authentica
23 23 | log()
24 24 | CLIENT_AUTH
AIR302 [*] `airflow.auth.managers.fab.api.auth.backend.kerberos_auth.log` is moved into `fab` provider in Airflow 3.0;
--> AIR302_fab.py:37:1
AIR302_fab.py:37:1: AIR302 [*] `airflow.auth.managers.fab.api.auth.backend.kerberos_auth.log` is moved into `fab` provider in Airflow 3.0;
|
35 | )
36 |
37 | log()
| ^^^
| ^^^ AIR302
38 | CLIENT_AUTH
39 | find_user()
|
help: Install `apache-airflow-providers-fab>=1.0.0` and use `log` from `airflow.providers.fab.auth_manager.api.auth.backend.kerberos_auth` instead.
= help: Install `apache-airflow-providers-fab>=1.0.0` and use `log` from `airflow.providers.fab.auth_manager.api.auth.backend.kerberos_auth` instead.
Unsafe fix
30 30 | CLIENT_AUTH,
@@ -244,16 +234,15 @@ help: Install `apache-airflow-providers-fab>=1.0.0` and use `log` from `airflow.
37 37 | log()
38 38 | CLIENT_AUTH
AIR302 [*] `airflow.auth.managers.fab.api.auth.backend.kerberos_auth.CLIENT_AUTH` is moved into `fab` provider in Airflow 3.0;
--> AIR302_fab.py:38:1
AIR302_fab.py:38:1: AIR302 [*] `airflow.auth.managers.fab.api.auth.backend.kerberos_auth.CLIENT_AUTH` is moved into `fab` provider in Airflow 3.0;
|
37 | log()
38 | CLIENT_AUTH
| ^^^^^^^^^^^
| ^^^^^^^^^^^ AIR302
39 | find_user()
40 | init_app()
|
help: Install `apache-airflow-providers-fab>=1.0.0` and use `CLIENT_AUTH` from `airflow.providers.fab.auth_manager.api.auth.backend.kerberos_auth` instead.
= help: Install `apache-airflow-providers-fab>=1.0.0` and use `CLIENT_AUTH` from `airflow.providers.fab.auth_manager.api.auth.backend.kerberos_auth` instead.
Unsafe fix
27 27 | requires_authentication()
@@ -270,17 +259,16 @@ help: Install `apache-airflow-providers-fab>=1.0.0` and use `CLIENT_AUTH` from `
37 37 | log()
38 38 | CLIENT_AUTH
AIR302 [*] `airflow.auth.managers.fab.api.auth.backend.kerberos_auth.find_user` is moved into `fab` provider in Airflow 3.0;
--> AIR302_fab.py:39:1
AIR302_fab.py:39:1: AIR302 [*] `airflow.auth.managers.fab.api.auth.backend.kerberos_auth.find_user` is moved into `fab` provider in Airflow 3.0;
|
37 | log()
38 | CLIENT_AUTH
39 | find_user()
| ^^^^^^^^^
| ^^^^^^^^^ AIR302
40 | init_app()
41 | requires_authentication()
|
help: Install `apache-airflow-providers-fab>=1.0.0` and use `find_user` from `airflow.providers.fab.auth_manager.api.auth.backend.kerberos_auth` instead.
= help: Install `apache-airflow-providers-fab>=1.0.0` and use `find_user` from `airflow.providers.fab.auth_manager.api.auth.backend.kerberos_auth` instead.
Unsafe fix
28 28 |
@@ -296,16 +284,15 @@ help: Install `apache-airflow-providers-fab>=1.0.0` and use `find_user` from `ai
37 37 | log()
38 38 | CLIENT_AUTH
AIR302 [*] `airflow.auth.managers.fab.api.auth.backend.kerberos_auth.init_app` is moved into `fab` provider in Airflow 3.0;
--> AIR302_fab.py:40:1
AIR302_fab.py:40:1: AIR302 [*] `airflow.auth.managers.fab.api.auth.backend.kerberos_auth.init_app` is moved into `fab` provider in Airflow 3.0;
|
38 | CLIENT_AUTH
39 | find_user()
40 | init_app()
| ^^^^^^^^
| ^^^^^^^^ AIR302
41 | requires_authentication()
|
help: Install `apache-airflow-providers-fab>=1.0.0` and use `init_app` from `airflow.providers.fab.auth_manager.api.auth.backend.kerberos_auth` instead.
= help: Install `apache-airflow-providers-fab>=1.0.0` and use `init_app` from `airflow.providers.fab.auth_manager.api.auth.backend.kerberos_auth` instead.
Unsafe fix
29 29 | from airflow.auth.managers.fab.api.auth.backend.kerberos_auth import (
@@ -320,17 +307,16 @@ help: Install `apache-airflow-providers-fab>=1.0.0` and use `init_app` from `air
37 37 | log()
38 38 | CLIENT_AUTH
AIR302 [*] `airflow.auth.managers.fab.api.auth.backend.kerberos_auth.requires_authentication` is moved into `fab` provider in Airflow 3.0;
--> AIR302_fab.py:41:1
AIR302_fab.py:41:1: AIR302 [*] `airflow.auth.managers.fab.api.auth.backend.kerberos_auth.requires_authentication` is moved into `fab` provider in Airflow 3.0;
|
39 | find_user()
40 | init_app()
41 | requires_authentication()
| ^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^ AIR302
42 |
43 | from airflow.auth.managers.fab.fab_auth_manager import FabAuthManager
|
help: Install `apache-airflow-providers-fab>=1.0.0` and use `requires_authentication` from `airflow.providers.fab.auth_manager.api.auth.backend.kerberos_auth` instead.
= help: Install `apache-airflow-providers-fab>=1.0.0` and use `requires_authentication` from `airflow.providers.fab.auth_manager.api.auth.backend.kerberos_auth` instead.
Unsafe fix
31 31 | find_user,
@@ -343,17 +329,16 @@ help: Install `apache-airflow-providers-fab>=1.0.0` and use `requires_authentica
37 37 | log()
38 38 | CLIENT_AUTH
AIR302 [*] `airflow.auth.managers.fab.fab_auth_manager.FabAuthManager` is moved into `fab` provider in Airflow 3.0;
--> AIR302_fab.py:49:1
AIR302_fab.py:49:1: AIR302 [*] `airflow.auth.managers.fab.fab_auth_manager.FabAuthManager` is moved into `fab` provider in Airflow 3.0;
|
47 | )
48 |
49 | FabAuthManager()
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ AIR302
50 | MAX_NUM_DATABASE_USER_SESSIONS
51 | FabAirflowSecurityManagerOverride()
|
help: Install `apache-airflow-providers-fab>=1.0.0` and use `FabAuthManager` from `airflow.providers.fab.auth_manager.fab_auth_manager` instead.
= help: Install `apache-airflow-providers-fab>=1.0.0` and use `FabAuthManager` from `airflow.providers.fab.auth_manager.fab_auth_manager` instead.
Unsafe fix
40 40 | init_app()
@@ -369,15 +354,14 @@ help: Install `apache-airflow-providers-fab>=1.0.0` and use `FabAuthManager` fro
49 49 | FabAuthManager()
50 50 | MAX_NUM_DATABASE_USER_SESSIONS
AIR302 [*] `airflow.auth.managers.fab.security_manager.override.MAX_NUM_DATABASE_USER_SESSIONS` is moved into `fab` provider in Airflow 3.0;
--> AIR302_fab.py:50:1
AIR302_fab.py:50:1: AIR302 [*] `airflow.auth.managers.fab.security_manager.override.MAX_NUM_DATABASE_USER_SESSIONS` is moved into `fab` provider in Airflow 3.0;
|
49 | FabAuthManager()
50 | MAX_NUM_DATABASE_USER_SESSIONS
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR302
51 | FabAirflowSecurityManagerOverride()
|
help: Install `apache-airflow-providers-fab>=1.0.0` and use `MAX_NUM_DATABASE_USER_SESSIONS` from `airflow.providers.fab.auth_manager.security_manager.override` instead.
= help: Install `apache-airflow-providers-fab>=1.0.0` and use `MAX_NUM_DATABASE_USER_SESSIONS` from `airflow.providers.fab.auth_manager.security_manager.override` instead.
Unsafe fix
42 42 |
@@ -391,17 +375,16 @@ help: Install `apache-airflow-providers-fab>=1.0.0` and use `MAX_NUM_DATABASE_US
49 49 | FabAuthManager()
50 50 | MAX_NUM_DATABASE_USER_SESSIONS
AIR302 [*] `airflow.auth.managers.fab.security_manager.override.FabAirflowSecurityManagerOverride` is moved into `fab` provider in Airflow 3.0;
--> AIR302_fab.py:51:1
AIR302_fab.py:51:1: AIR302 [*] `airflow.auth.managers.fab.security_manager.override.FabAirflowSecurityManagerOverride` is moved into `fab` provider in Airflow 3.0;
|
49 | FabAuthManager()
50 | MAX_NUM_DATABASE_USER_SESSIONS
51 | FabAirflowSecurityManagerOverride()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR302
52 |
53 | from airflow.www.security import FabAirflowSecurityManagerOverride
|
help: Install `apache-airflow-providers-fab>=1.0.0` and use `FabAirflowSecurityManagerOverride` from `airflow.providers.fab.auth_manager.security_manager.override` instead.
= help: Install `apache-airflow-providers-fab>=1.0.0` and use `FabAirflowSecurityManagerOverride` from `airflow.providers.fab.auth_manager.security_manager.override` instead.
Unsafe fix
43 43 | from airflow.auth.managers.fab.fab_auth_manager import FabAuthManager
@@ -414,15 +397,14 @@ help: Install `apache-airflow-providers-fab>=1.0.0` and use `FabAirflowSecurityM
49 49 | FabAuthManager()
50 50 | MAX_NUM_DATABASE_USER_SESSIONS
AIR302 [*] `airflow.www.security.FabAirflowSecurityManagerOverride` is moved into `fab` provider in Airflow 3.0;
--> AIR302_fab.py:55:1
AIR302_fab.py:55:1: AIR302 [*] `airflow.www.security.FabAirflowSecurityManagerOverride` is moved into `fab` provider in Airflow 3.0;
|
53 | from airflow.www.security import FabAirflowSecurityManagerOverride
54 |
55 | FabAirflowSecurityManagerOverride()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-fab>=1.0.0` and use `FabAirflowSecurityManagerOverride` from `airflow.providers.fab.auth_manager.security_manager.override` instead.
= help: Install `apache-airflow-providers-fab>=1.0.0` and use `FabAirflowSecurityManagerOverride` from `airflow.providers.fab.auth_manager.security_manager.override` instead.
Unsafe fix
50 50 | MAX_NUM_DATABASE_USER_SESSIONS

View File

@@ -1,16 +1,15 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR302 [*] `airflow.hooks.webhdfs_hook.WebHDFSHook` is moved into `apache-hdfs` provider in Airflow 3.0;
--> AIR302_hdfs.py:6:1
AIR302_hdfs.py:6:1: AIR302 [*] `airflow.hooks.webhdfs_hook.WebHDFSHook` is moved into `apache-hdfs` provider in Airflow 3.0;
|
4 | from airflow.sensors.web_hdfs_sensor import WebHdfsSensor
5 |
6 | WebHDFSHook()
| ^^^^^^^^^^^
| ^^^^^^^^^^^ AIR302
7 | WebHdfsSensor()
|
help: Install `apache-airflow-providers-apache-hdfs>=1.0.0` and use `WebHDFSHook` from `airflow.providers.apache.hdfs.hooks.webhdfs` instead.
= help: Install `apache-airflow-providers-apache-hdfs>=1.0.0` and use `WebHDFSHook` from `airflow.providers.apache.hdfs.hooks.webhdfs` instead.
Unsafe fix
1 1 | from __future__ import annotations
@@ -22,14 +21,13 @@ help: Install `apache-airflow-providers-apache-hdfs>=1.0.0` and use `WebHDFSHook
6 6 | WebHDFSHook()
7 7 | WebHdfsSensor()
AIR302 [*] `airflow.sensors.web_hdfs_sensor.WebHdfsSensor` is moved into `apache-hdfs` provider in Airflow 3.0;
--> AIR302_hdfs.py:7:1
AIR302_hdfs.py:7:1: AIR302 [*] `airflow.sensors.web_hdfs_sensor.WebHdfsSensor` is moved into `apache-hdfs` provider in Airflow 3.0;
|
6 | WebHDFSHook()
7 | WebHdfsSensor()
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-apache-hdfs>=1.0.0` and use `WebHdfsSensor` from `airflow.providers.apache.hdfs.sensors.web_hdfs` instead.
= help: Install `apache-airflow-providers-apache-hdfs>=1.0.0` and use `WebHdfsSensor` from `airflow.providers.apache.hdfs.sensors.web_hdfs` instead.
Unsafe fix
1 1 | from __future__ import annotations

View File

@@ -1,17 +1,16 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR302 [*] `airflow.hooks.hive_hooks.HIVE_QUEUE_PRIORITIES` is moved into `apache-hive` provider in Airflow 3.0;
--> AIR302_hive.py:18:1
AIR302_hive.py:18:1: AIR302 [*] `airflow.hooks.hive_hooks.HIVE_QUEUE_PRIORITIES` is moved into `apache-hive` provider in Airflow 3.0;
|
16 | from airflow.operators.hive_to_samba_operator import HiveToSambaOperator
17 |
18 | HIVE_QUEUE_PRIORITIES
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ AIR302
19 | HiveCliHook()
20 | HiveMetastoreHook()
|
help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HIVE_QUEUE_PRIORITIES` from `airflow.providers.apache.hive.hooks.hive` instead.
= help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HIVE_QUEUE_PRIORITIES` from `airflow.providers.apache.hive.hooks.hive` instead.
Unsafe fix
1 1 | from __future__ import annotations
@@ -30,16 +29,15 @@ help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HIVE_QUEUE_
18 18 | HIVE_QUEUE_PRIORITIES
19 19 | HiveCliHook()
AIR302 [*] `airflow.hooks.hive_hooks.HiveCliHook` is moved into `apache-hive` provider in Airflow 3.0;
--> AIR302_hive.py:19:1
AIR302_hive.py:19:1: AIR302 [*] `airflow.hooks.hive_hooks.HiveCliHook` is moved into `apache-hive` provider in Airflow 3.0;
|
18 | HIVE_QUEUE_PRIORITIES
19 | HiveCliHook()
| ^^^^^^^^^^^
| ^^^^^^^^^^^ AIR302
20 | HiveMetastoreHook()
21 | HiveServer2Hook()
|
help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveCliHook` from `airflow.providers.apache.hive.hooks.hive` instead.
= help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveCliHook` from `airflow.providers.apache.hive.hooks.hive` instead.
Unsafe fix
2 2 |
@@ -58,16 +56,15 @@ help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveCliHook
18 18 | HIVE_QUEUE_PRIORITIES
19 19 | HiveCliHook()
AIR302 [*] `airflow.hooks.hive_hooks.HiveMetastoreHook` is moved into `apache-hive` provider in Airflow 3.0;
--> AIR302_hive.py:20:1
AIR302_hive.py:20:1: AIR302 [*] `airflow.hooks.hive_hooks.HiveMetastoreHook` is moved into `apache-hive` provider in Airflow 3.0;
|
18 | HIVE_QUEUE_PRIORITIES
19 | HiveCliHook()
20 | HiveMetastoreHook()
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ AIR302
21 | HiveServer2Hook()
|
help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveMetastoreHook` from `airflow.providers.apache.hive.hooks.hive` instead.
= help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveMetastoreHook` from `airflow.providers.apache.hive.hooks.hive` instead.
Unsafe fix
3 3 | from airflow.hooks.hive_hooks import (
@@ -86,17 +83,16 @@ help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveMetasto
18 18 | HIVE_QUEUE_PRIORITIES
19 19 | HiveCliHook()
AIR302 [*] `airflow.hooks.hive_hooks.HiveServer2Hook` is moved into `apache-hive` provider in Airflow 3.0;
--> AIR302_hive.py:21:1
AIR302_hive.py:21:1: AIR302 [*] `airflow.hooks.hive_hooks.HiveServer2Hook` is moved into `apache-hive` provider in Airflow 3.0;
|
19 | HiveCliHook()
20 | HiveMetastoreHook()
21 | HiveServer2Hook()
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^ AIR302
22 |
23 | closest_ds_partition()
|
help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveServer2Hook` from `airflow.providers.apache.hive.hooks.hive` instead.
= help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveServer2Hook` from `airflow.providers.apache.hive.hooks.hive` instead.
Unsafe fix
4 4 | HIVE_QUEUE_PRIORITIES,
@@ -115,16 +111,15 @@ help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveServer2
18 18 | HIVE_QUEUE_PRIORITIES
19 19 | HiveCliHook()
AIR302 [*] `airflow.macros.hive.closest_ds_partition` is moved into `apache-hive` provider in Airflow 3.0;
--> AIR302_hive.py:23:1
AIR302_hive.py:23:1: AIR302 [*] `airflow.macros.hive.closest_ds_partition` is moved into `apache-hive` provider in Airflow 3.0;
|
21 | HiveServer2Hook()
22 |
23 | closest_ds_partition()
| ^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^ AIR302
24 | max_partition()
|
help: Install `apache-airflow-providers-apache-hive>=5.1.0` and use `closest_ds_partition` from `airflow.providers.apache.hive.macros.hive` instead.
= help: Install `apache-airflow-providers-apache-hive>=5.1.0` and use `closest_ds_partition` from `airflow.providers.apache.hive.macros.hive` instead.
Unsafe fix
7 7 | HiveServer2Hook,
@@ -142,16 +137,15 @@ help: Install `apache-airflow-providers-apache-hive>=5.1.0` and use `closest_ds_
18 18 | HIVE_QUEUE_PRIORITIES
19 19 | HiveCliHook()
AIR302 [*] `airflow.macros.hive.max_partition` is moved into `apache-hive` provider in Airflow 3.0;
--> AIR302_hive.py:24:1
AIR302_hive.py:24:1: AIR302 [*] `airflow.macros.hive.max_partition` is moved into `apache-hive` provider in Airflow 3.0;
|
23 | closest_ds_partition()
24 | max_partition()
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^ AIR302
25 |
26 | HiveOperator()
|
help: Install `apache-airflow-providers-apache-hive>=5.1.0` and use `max_partition` from `airflow.providers.apache.hive.macros.hive` instead.
= help: Install `apache-airflow-providers-apache-hive>=5.1.0` and use `max_partition` from `airflow.providers.apache.hive.macros.hive` instead.
Unsafe fix
8 8 | )
@@ -168,17 +162,16 @@ help: Install `apache-airflow-providers-apache-hive>=5.1.0` and use `max_partiti
18 18 | HIVE_QUEUE_PRIORITIES
19 19 | HiveCliHook()
AIR302 [*] `airflow.operators.hive_operator.HiveOperator` is moved into `apache-hive` provider in Airflow 3.0;
--> AIR302_hive.py:26:1
AIR302_hive.py:26:1: AIR302 [*] `airflow.operators.hive_operator.HiveOperator` is moved into `apache-hive` provider in Airflow 3.0;
|
24 | max_partition()
25 |
26 | HiveOperator()
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ AIR302
27 | HiveStatsCollectionOperator()
28 | HiveToMySqlOperator()
|
help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveOperator` from `airflow.providers.apache.hive.operators.hive` instead.
= help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveOperator` from `airflow.providers.apache.hive.operators.hive` instead.
Unsafe fix
10 10 | closest_ds_partition,
@@ -193,16 +186,15 @@ help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveOperato
18 18 | HIVE_QUEUE_PRIORITIES
19 19 | HiveCliHook()
AIR302 [*] `airflow.operators.hive_stats_operator.HiveStatsCollectionOperator` is moved into `apache-hive` provider in Airflow 3.0;
--> AIR302_hive.py:27:1
AIR302_hive.py:27:1: AIR302 [*] `airflow.operators.hive_stats_operator.HiveStatsCollectionOperator` is moved into `apache-hive` provider in Airflow 3.0;
|
26 | HiveOperator()
27 | HiveStatsCollectionOperator()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR302
28 | HiveToMySqlOperator()
29 | HiveToSambaOperator()
|
help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveStatsCollectionOperator` from `airflow.providers.apache.hive.operators.hive_stats` instead.
= help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveStatsCollectionOperator` from `airflow.providers.apache.hive.operators.hive_stats` instead.
Unsafe fix
11 11 | max_partition,
@@ -216,16 +208,15 @@ help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveStatsCo
18 18 | HIVE_QUEUE_PRIORITIES
19 19 | HiveCliHook()
AIR302 [*] `airflow.operators.hive_to_mysql.HiveToMySqlOperator` is moved into `apache-hive` provider in Airflow 3.0;
--> AIR302_hive.py:28:1
AIR302_hive.py:28:1: AIR302 [*] `airflow.operators.hive_to_mysql.HiveToMySqlOperator` is moved into `apache-hive` provider in Airflow 3.0;
|
26 | HiveOperator()
27 | HiveStatsCollectionOperator()
28 | HiveToMySqlOperator()
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^ AIR302
29 | HiveToSambaOperator()
|
help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveToMySqlOperator` from `airflow.providers.apache.hive.transfers.hive_to_mysql` instead.
= help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveToMySqlOperator` from `airflow.providers.apache.hive.transfers.hive_to_mysql` instead.
Unsafe fix
12 12 | )
@@ -238,15 +229,14 @@ help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveToMySql
18 18 | HIVE_QUEUE_PRIORITIES
19 19 | HiveCliHook()
AIR302 [*] `airflow.operators.hive_to_samba_operator.HiveToSambaOperator` is moved into `apache-hive` provider in Airflow 3.0;
--> AIR302_hive.py:29:1
AIR302_hive.py:29:1: AIR302 [*] `airflow.operators.hive_to_samba_operator.HiveToSambaOperator` is moved into `apache-hive` provider in Airflow 3.0;
|
27 | HiveStatsCollectionOperator()
28 | HiveToMySqlOperator()
29 | HiveToSambaOperator()
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveToSambaOperator` from `airflow.providers.apache.hive.transfers.hive_to_samba` instead.
= help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveToSambaOperator` from `airflow.providers.apache.hive.transfers.hive_to_samba` instead.
Unsafe fix
13 13 | from airflow.operators.hive_operator import HiveOperator
@@ -258,17 +248,16 @@ help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveToSamba
18 18 | HIVE_QUEUE_PRIORITIES
19 19 | HiveCliHook()
AIR302 [*] `airflow.operators.hive_to_mysql.HiveToMySqlTransfer` is moved into `apache-hive` provider in Airflow 3.0;
--> AIR302_hive.py:34:1
AIR302_hive.py:34:1: AIR302 [*] `airflow.operators.hive_to_mysql.HiveToMySqlTransfer` is moved into `apache-hive` provider in Airflow 3.0;
|
32 | from airflow.operators.hive_to_mysql import HiveToMySqlTransfer
33 |
34 | HiveToMySqlTransfer()
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^ AIR302
35 |
36 | from airflow.operators.mysql_to_hive import MySqlToHiveOperator
|
help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveToMySqlOperator` from `airflow.providers.apache.hive.transfers.hive_to_mysql` instead.
= help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveToMySqlOperator` from `airflow.providers.apache.hive.transfers.hive_to_mysql` instead.
Unsafe fix
30 30 |
@@ -279,17 +268,16 @@ help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HiveToMySql
34 35 | HiveToMySqlTransfer()
35 36 |
AIR302 [*] `airflow.operators.mysql_to_hive.MySqlToHiveOperator` is moved into `apache-hive` provider in Airflow 3.0;
--> AIR302_hive.py:38:1
AIR302_hive.py:38:1: AIR302 [*] `airflow.operators.mysql_to_hive.MySqlToHiveOperator` is moved into `apache-hive` provider in Airflow 3.0;
|
36 | from airflow.operators.mysql_to_hive import MySqlToHiveOperator
37 |
38 | MySqlToHiveOperator()
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^ AIR302
39 |
40 | from airflow.operators.mysql_to_hive import MySqlToHiveTransfer
|
help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `MySqlToHiveOperator` from `airflow.providers.apache.hive.transfers.mysql_to_hive` instead.
= help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `MySqlToHiveOperator` from `airflow.providers.apache.hive.transfers.mysql_to_hive` instead.
Unsafe fix
33 33 |
@@ -301,17 +289,16 @@ help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `MySqlToHive
38 38 | MySqlToHiveOperator()
39 39 |
AIR302 [*] `airflow.operators.mysql_to_hive.MySqlToHiveTransfer` is moved into `apache-hive` provider in Airflow 3.0;
--> AIR302_hive.py:42:1
AIR302_hive.py:42:1: AIR302 [*] `airflow.operators.mysql_to_hive.MySqlToHiveTransfer` is moved into `apache-hive` provider in Airflow 3.0;
|
40 | from airflow.operators.mysql_to_hive import MySqlToHiveTransfer
41 |
42 | MySqlToHiveTransfer()
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^ AIR302
43 |
44 | from airflow.operators.mssql_to_hive import MsSqlToHiveOperator
|
help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `MySqlToHiveOperator` from `airflow.providers.apache.hive.transfers.mysql_to_hive` instead.
= help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `MySqlToHiveOperator` from `airflow.providers.apache.hive.transfers.mysql_to_hive` instead.
Unsafe fix
38 38 | MySqlToHiveOperator()
@@ -322,17 +309,16 @@ help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `MySqlToHive
42 43 | MySqlToHiveTransfer()
43 44 |
AIR302 [*] `airflow.operators.mssql_to_hive.MsSqlToHiveOperator` is moved into `apache-hive` provider in Airflow 3.0;
--> AIR302_hive.py:46:1
AIR302_hive.py:46:1: AIR302 [*] `airflow.operators.mssql_to_hive.MsSqlToHiveOperator` is moved into `apache-hive` provider in Airflow 3.0;
|
44 | from airflow.operators.mssql_to_hive import MsSqlToHiveOperator
45 |
46 | MsSqlToHiveOperator()
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^ AIR302
47 |
48 | from airflow.operators.mssql_to_hive import MsSqlToHiveTransfer
|
help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `MsSqlToHiveOperator` from `airflow.providers.apache.hive.transfers.mssql_to_hive` instead.
= help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `MsSqlToHiveOperator` from `airflow.providers.apache.hive.transfers.mssql_to_hive` instead.
Unsafe fix
41 41 |
@@ -344,17 +330,16 @@ help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `MsSqlToHive
46 46 | MsSqlToHiveOperator()
47 47 |
AIR302 [*] `airflow.operators.mssql_to_hive.MsSqlToHiveTransfer` is moved into `apache-hive` provider in Airflow 3.0;
--> AIR302_hive.py:50:1
AIR302_hive.py:50:1: AIR302 [*] `airflow.operators.mssql_to_hive.MsSqlToHiveTransfer` is moved into `apache-hive` provider in Airflow 3.0;
|
48 | from airflow.operators.mssql_to_hive import MsSqlToHiveTransfer
49 |
50 | MsSqlToHiveTransfer()
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^ AIR302
51 |
52 | from airflow.operators.s3_to_hive_operator import S3ToHiveOperator
|
help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `MsSqlToHiveOperator` from `airflow.providers.apache.hive.transfers.mssql_to_hive` instead.
= help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `MsSqlToHiveOperator` from `airflow.providers.apache.hive.transfers.mssql_to_hive` instead.
Unsafe fix
46 46 | MsSqlToHiveOperator()
@@ -365,17 +350,16 @@ help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `MsSqlToHive
50 51 | MsSqlToHiveTransfer()
51 52 |
AIR302 [*] `airflow.operators.s3_to_hive_operator.S3ToHiveOperator` is moved into `apache-hive` provider in Airflow 3.0;
--> AIR302_hive.py:54:1
AIR302_hive.py:54:1: AIR302 [*] `airflow.operators.s3_to_hive_operator.S3ToHiveOperator` is moved into `apache-hive` provider in Airflow 3.0;
|
52 | from airflow.operators.s3_to_hive_operator import S3ToHiveOperator
53 |
54 | S3ToHiveOperator()
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^ AIR302
55 |
56 | from airflow.operators.s3_to_hive_operator import S3ToHiveTransfer
|
help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `S3ToHiveOperator` from `airflow.providers.apache.hive.transfers.s3_to_hive` instead.
= help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `S3ToHiveOperator` from `airflow.providers.apache.hive.transfers.s3_to_hive` instead.
Unsafe fix
49 49 |
@@ -387,17 +371,16 @@ help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `S3ToHiveOpe
54 54 | S3ToHiveOperator()
55 55 |
AIR302 [*] `airflow.operators.s3_to_hive_operator.S3ToHiveTransfer` is moved into `apache-hive` provider in Airflow 3.0;
--> AIR302_hive.py:58:1
AIR302_hive.py:58:1: AIR302 [*] `airflow.operators.s3_to_hive_operator.S3ToHiveTransfer` is moved into `apache-hive` provider in Airflow 3.0;
|
56 | from airflow.operators.s3_to_hive_operator import S3ToHiveTransfer
57 |
58 | S3ToHiveTransfer()
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^ AIR302
59 |
60 | from airflow.sensors.hive_partition_sensor import HivePartitionSensor
|
help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `S3ToHiveOperator` from `airflow.providers.apache.hive.transfers.s3_to_hive` instead.
= help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `S3ToHiveOperator` from `airflow.providers.apache.hive.transfers.s3_to_hive` instead.
Unsafe fix
54 54 | S3ToHiveOperator()
@@ -408,17 +391,16 @@ help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `S3ToHiveOpe
58 59 | S3ToHiveTransfer()
59 60 |
AIR302 [*] `airflow.sensors.hive_partition_sensor.HivePartitionSensor` is moved into `apache-hive` provider in Airflow 3.0;
--> AIR302_hive.py:62:1
AIR302_hive.py:62:1: AIR302 [*] `airflow.sensors.hive_partition_sensor.HivePartitionSensor` is moved into `apache-hive` provider in Airflow 3.0;
|
60 | from airflow.sensors.hive_partition_sensor import HivePartitionSensor
61 |
62 | HivePartitionSensor()
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^ AIR302
63 |
64 | from airflow.sensors.metastore_partition_sensor import MetastorePartitionSensor
|
help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HivePartitionSensor` from `airflow.providers.apache.hive.sensors.hive_partition` instead.
= help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HivePartitionSensor` from `airflow.providers.apache.hive.sensors.hive_partition` instead.
Unsafe fix
57 57 |
@@ -430,17 +412,16 @@ help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `HivePartiti
62 62 | HivePartitionSensor()
63 63 |
AIR302 [*] `airflow.sensors.metastore_partition_sensor.MetastorePartitionSensor` is moved into `apache-hive` provider in Airflow 3.0;
--> AIR302_hive.py:66:1
AIR302_hive.py:66:1: AIR302 [*] `airflow.sensors.metastore_partition_sensor.MetastorePartitionSensor` is moved into `apache-hive` provider in Airflow 3.0;
|
64 | from airflow.sensors.metastore_partition_sensor import MetastorePartitionSensor
65 |
66 | MetastorePartitionSensor()
| ^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^ AIR302
67 |
68 | from airflow.sensors.named_hive_partition_sensor import NamedHivePartitionSensor
|
help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `MetastorePartitionSensor` from `airflow.providers.apache.hive.sensors.metastore_partition` instead.
= help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `MetastorePartitionSensor` from `airflow.providers.apache.hive.sensors.metastore_partition` instead.
Unsafe fix
61 61 |
@@ -452,15 +433,14 @@ help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `MetastorePa
66 66 | MetastorePartitionSensor()
67 67 |
AIR302 [*] `airflow.sensors.named_hive_partition_sensor.NamedHivePartitionSensor` is moved into `apache-hive` provider in Airflow 3.0;
--> AIR302_hive.py:70:1
AIR302_hive.py:70:1: AIR302 [*] `airflow.sensors.named_hive_partition_sensor.NamedHivePartitionSensor` is moved into `apache-hive` provider in Airflow 3.0;
|
68 | from airflow.sensors.named_hive_partition_sensor import NamedHivePartitionSensor
69 |
70 | NamedHivePartitionSensor()
| ^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `NamedHivePartitionSensor` from `airflow.providers.apache.hive.sensors.named_hive_partition` instead.
= help: Install `apache-airflow-providers-apache-hive>=1.0.0` and use `NamedHivePartitionSensor` from `airflow.providers.apache.hive.sensors.named_hive_partition` instead.
Unsafe fix
65 65 |

View File

@@ -1,17 +1,16 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR302 [*] `airflow.hooks.http_hook.HttpHook` is moved into `http` provider in Airflow 3.0;
--> AIR302_http.py:7:1
AIR302_http.py:7:1: AIR302 [*] `airflow.hooks.http_hook.HttpHook` is moved into `http` provider in Airflow 3.0;
|
5 | from airflow.sensors.http_sensor import HttpSensor
6 |
7 | HttpHook()
| ^^^^^^^^
| ^^^^^^^^ AIR302
8 | SimpleHttpOperator()
9 | HttpSensor()
|
help: Install `apache-airflow-providers-http>=1.0.0` and use `HttpHook` from `airflow.providers.http.hooks.http` instead.
= help: Install `apache-airflow-providers-http>=1.0.0` and use `HttpHook` from `airflow.providers.http.hooks.http` instead.
Unsafe fix
1 1 | from __future__ import annotations
@@ -24,15 +23,14 @@ help: Install `apache-airflow-providers-http>=1.0.0` and use `HttpHook` from `ai
7 7 | HttpHook()
8 8 | SimpleHttpOperator()
AIR302 [*] `airflow.operators.http_operator.SimpleHttpOperator` is moved into `http` provider in Airflow 3.0;
--> AIR302_http.py:8:1
AIR302_http.py:8:1: AIR302 [*] `airflow.operators.http_operator.SimpleHttpOperator` is moved into `http` provider in Airflow 3.0;
|
7 | HttpHook()
8 | SimpleHttpOperator()
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^ AIR302
9 | HttpSensor()
|
help: Install `apache-airflow-providers-http>=5.0.0` and use `HttpOperator` from `airflow.providers.http.operators.http` instead.
= help: Install `apache-airflow-providers-http>=5.0.0` and use `HttpOperator` from `airflow.providers.http.operators.http` instead.
Safe fix
3 3 | from airflow.hooks.http_hook import HttpHook
@@ -45,15 +43,14 @@ help: Install `apache-airflow-providers-http>=5.0.0` and use `HttpOperator` from
9 |+HttpOperator()
9 10 | HttpSensor()
AIR302 [*] `airflow.sensors.http_sensor.HttpSensor` is moved into `http` provider in Airflow 3.0;
--> AIR302_http.py:9:1
AIR302_http.py:9:1: AIR302 [*] `airflow.sensors.http_sensor.HttpSensor` is moved into `http` provider in Airflow 3.0;
|
7 | HttpHook()
8 | SimpleHttpOperator()
9 | HttpSensor()
| ^^^^^^^^^^
| ^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-http>=1.0.0` and use `HttpSensor` from `airflow.providers.http.sensors.http` instead.
= help: Install `apache-airflow-providers-http>=1.0.0` and use `HttpSensor` from `airflow.providers.http.sensors.http` instead.
Unsafe fix
2 2 |

View File

@@ -1,16 +1,15 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR302 [*] `airflow.hooks.jdbc_hook.JdbcHook` is moved into `jdbc` provider in Airflow 3.0;
--> AIR302_jdbc.py:8:1
AIR302_jdbc.py:8:1: AIR302 [*] `airflow.hooks.jdbc_hook.JdbcHook` is moved into `jdbc` provider in Airflow 3.0;
|
6 | )
7 |
8 | JdbcHook()
| ^^^^^^^^
| ^^^^^^^^ AIR302
9 | jaydebeapi()
|
help: Install `apache-airflow-providers-jdbc>=1.0.0` and use `JdbcHook` from `airflow.providers.jdbc.hooks.jdbc` instead.
= help: Install `apache-airflow-providers-jdbc>=1.0.0` and use `JdbcHook` from `airflow.providers.jdbc.hooks.jdbc` instead.
Unsafe fix
1 1 | from __future__ import annotations
@@ -24,14 +23,13 @@ help: Install `apache-airflow-providers-jdbc>=1.0.0` and use `JdbcHook` from `ai
8 8 | JdbcHook()
9 9 | jaydebeapi()
AIR302 [*] `airflow.hooks.jdbc_hook.jaydebeapi` is moved into `jdbc` provider in Airflow 3.0;
--> AIR302_jdbc.py:9:1
AIR302_jdbc.py:9:1: AIR302 [*] `airflow.hooks.jdbc_hook.jaydebeapi` is moved into `jdbc` provider in Airflow 3.0;
|
8 | JdbcHook()
9 | jaydebeapi()
| ^^^^^^^^^^
| ^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-jdbc>=1.0.0` and use `jaydebeapi` from `airflow.providers.jdbc.hooks.jdbc` instead.
= help: Install `apache-airflow-providers-jdbc>=1.0.0` and use `jaydebeapi` from `airflow.providers.jdbc.hooks.jdbc` instead.
Unsafe fix
2 2 |

View File

@@ -1,16 +1,15 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR302 [*] `airflow.executors.kubernetes_executor_types.ALL_NAMESPACES` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:22:1
AIR302_kubernetes.py:22:1: AIR302 [*] `airflow.executors.kubernetes_executor_types.ALL_NAMESPACES` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
20 | )
21 |
22 | ALL_NAMESPACES
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ AIR302
23 | POD_EXECUTOR_DONE_KEY
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `ALL_NAMESPACES` from `airflow.providers.cncf.kubernetes.executors.kubernetes_executor_types` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `ALL_NAMESPACES` from `airflow.providers.cncf.kubernetes.executors.kubernetes_executor_types` instead.
Unsafe fix
1 1 | from __future__ import annotations
@@ -29,16 +28,15 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `ALL_NAM
22 22 | ALL_NAMESPACES
23 23 | POD_EXECUTOR_DONE_KEY
AIR302 [*] `airflow.executors.kubernetes_executor_types.POD_EXECUTOR_DONE_KEY` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:23:1
AIR302_kubernetes.py:23:1: AIR302 [*] `airflow.executors.kubernetes_executor_types.POD_EXECUTOR_DONE_KEY` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
22 | ALL_NAMESPACES
23 | POD_EXECUTOR_DONE_KEY
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ AIR302
24 |
25 | K8SModel()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `POD_EXECUTOR_DONE_KEY` from `airflow.providers.cncf.kubernetes.executors.kubernetes_executor_types` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `POD_EXECUTOR_DONE_KEY` from `airflow.providers.cncf.kubernetes.executors.kubernetes_executor_types` instead.
Unsafe fix
2 2 |
@@ -57,16 +55,15 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `POD_EXE
22 22 | ALL_NAMESPACES
23 23 | POD_EXECUTOR_DONE_KEY
AIR302 [*] `airflow.kubernetes.k8s_model.K8SModel` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:25:1
AIR302_kubernetes.py:25:1: AIR302 [*] `airflow.kubernetes.k8s_model.K8SModel` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
23 | POD_EXECUTOR_DONE_KEY
24 |
25 | K8SModel()
| ^^^^^^^^
| ^^^^^^^^ AIR302
26 | append_to_pod()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `K8SModel` from `airflow.providers.cncf.kubernetes.k8s_model` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `K8SModel` from `airflow.providers.cncf.kubernetes.k8s_model` instead.
Unsafe fix
5 5 | POD_EXECUTOR_DONE_KEY,
@@ -85,16 +82,15 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `K8SMode
22 22 | ALL_NAMESPACES
23 23 | POD_EXECUTOR_DONE_KEY
AIR302 [*] `airflow.kubernetes.k8s_model.append_to_pod` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:26:1
AIR302_kubernetes.py:26:1: AIR302 [*] `airflow.kubernetes.k8s_model.append_to_pod` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
25 | K8SModel()
26 | append_to_pod()
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^ AIR302
27 |
28 | _disable_verify_ssl()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `append_to_pod` from `airflow.providers.cncf.kubernetes.k8s_model` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `append_to_pod` from `airflow.providers.cncf.kubernetes.k8s_model` instead.
Unsafe fix
6 6 | )
@@ -113,17 +109,16 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `append_
22 22 | ALL_NAMESPACES
23 23 | POD_EXECUTOR_DONE_KEY
AIR302 [*] `airflow.kubernetes.kube_client._disable_verify_ssl` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:28:1
AIR302_kubernetes.py:28:1: AIR302 [*] `airflow.kubernetes.kube_client._disable_verify_ssl` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
26 | append_to_pod()
27 |
28 | _disable_verify_ssl()
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^ AIR302
29 | _enable_tcp_keepalive()
30 | get_kube_client()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `_disable_verify_ssl` from `airflow.providers.cncf.kubernetes.kube_client` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `_disable_verify_ssl` from `airflow.providers.cncf.kubernetes.kube_client` instead.
Unsafe fix
9 9 | append_to_pod,
@@ -142,15 +137,14 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `_disabl
22 22 | ALL_NAMESPACES
23 23 | POD_EXECUTOR_DONE_KEY
AIR302 [*] `airflow.kubernetes.kube_client._enable_tcp_keepalive` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:29:1
AIR302_kubernetes.py:29:1: AIR302 [*] `airflow.kubernetes.kube_client._enable_tcp_keepalive` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
28 | _disable_verify_ssl()
29 | _enable_tcp_keepalive()
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ AIR302
30 | get_kube_client()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `_enable_tcp_keepalive` from `airflow.providers.cncf.kubernetes.kube_client` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `_enable_tcp_keepalive` from `airflow.providers.cncf.kubernetes.kube_client` instead.
Unsafe fix
10 10 | )
@@ -169,17 +163,16 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `_enable
22 22 | ALL_NAMESPACES
23 23 | POD_EXECUTOR_DONE_KEY
AIR302 [*] `airflow.kubernetes.kube_client.get_kube_client` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:30:1
AIR302_kubernetes.py:30:1: AIR302 [*] `airflow.kubernetes.kube_client.get_kube_client` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
28 | _disable_verify_ssl()
29 | _enable_tcp_keepalive()
30 | get_kube_client()
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^ AIR302
31 |
32 | add_pod_suffix()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `get_kube_client` from `airflow.providers.cncf.kubernetes.kube_client` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `get_kube_client` from `airflow.providers.cncf.kubernetes.kube_client` instead.
Unsafe fix
11 11 | from airflow.kubernetes.kube_client import (
@@ -197,17 +190,16 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `get_kub
22 22 | ALL_NAMESPACES
23 23 | POD_EXECUTOR_DONE_KEY
AIR302 [*] `airflow.kubernetes.kubernetes_helper_functions.add_pod_suffix` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:32:1
AIR302_kubernetes.py:32:1: AIR302 [*] `airflow.kubernetes.kubernetes_helper_functions.add_pod_suffix` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
30 | get_kube_client()
31 |
32 | add_pod_suffix()
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ AIR302
33 | annotations_for_logging_task_metadata()
34 | create_pod_id()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=10.0.0` and use `add_unique_suffix` from `airflow.providers.cncf.kubernetes.kubernetes_helper_functions` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=10.0.0` and use `add_unique_suffix` from `airflow.providers.cncf.kubernetes.kubernetes_helper_functions` instead.
Safe fix
18 18 | annotations_for_logging_task_metadata,
@@ -227,15 +219,14 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=10.0.0` and use `add_un
34 35 | create_pod_id()
35 36 |
AIR302 [*] `airflow.kubernetes.kubernetes_helper_functions.annotations_for_logging_task_metadata` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:33:1
AIR302_kubernetes.py:33:1: AIR302 [*] `airflow.kubernetes.kubernetes_helper_functions.annotations_for_logging_task_metadata` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
32 | add_pod_suffix()
33 | annotations_for_logging_task_metadata()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR302
34 | create_pod_id()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `annotations_for_logging_task_metadata` from `airflow.providers.cncf.kubernetes.kubernetes_helper_functions` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `annotations_for_logging_task_metadata` from `airflow.providers.cncf.kubernetes.kubernetes_helper_functions` instead.
Unsafe fix
15 15 | )
@@ -249,15 +240,14 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `annotat
22 22 | ALL_NAMESPACES
23 23 | POD_EXECUTOR_DONE_KEY
AIR302 [*] `airflow.kubernetes.kubernetes_helper_functions.create_pod_id` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:34:1
AIR302_kubernetes.py:34:1: AIR302 [*] `airflow.kubernetes.kubernetes_helper_functions.create_pod_id` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
32 | add_pod_suffix()
33 | annotations_for_logging_task_metadata()
34 | create_pod_id()
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-cncf-kubernetes>=10.0.0` and use `create_unique_id` from `airflow.providers.cncf.kubernetes.kubernetes_helper_functions` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=10.0.0` and use `create_unique_id` from `airflow.providers.cncf.kubernetes.kubernetes_helper_functions` instead.
Safe fix
18 18 | annotations_for_logging_task_metadata,
@@ -277,17 +267,16 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=10.0.0` and use `create
36 37 |
37 38 | from airflow.kubernetes.pod_generator import (
AIR302 [*] `airflow.kubernetes.pod_generator.PodDefaults` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:49:1
AIR302_kubernetes.py:49:1: AIR302 [*] `airflow.kubernetes.pod_generator.PodDefaults` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
47 | )
48 |
49 | PodDefaults()
| ^^^^^^^^^^^
| ^^^^^^^^^^^ AIR302
50 | PodGenerator()
51 | add_pod_suffix()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `PodDefaults` from `airflow.providers.cncf.kubernetes.utils.xcom_sidecar` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `PodDefaults` from `airflow.providers.cncf.kubernetes.utils.xcom_sidecar` instead.
Unsafe fix
35 35 |
@@ -306,16 +295,15 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `PodDefa
49 49 | PodDefaults()
50 50 | PodGenerator()
AIR302 [*] `airflow.kubernetes.pod_generator.PodGenerator` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:50:1
AIR302_kubernetes.py:50:1: AIR302 [*] `airflow.kubernetes.pod_generator.PodGenerator` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
49 | PodDefaults()
50 | PodGenerator()
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ AIR302
51 | add_pod_suffix()
52 | datetime_to_label_safe_datestring()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `PodGenerator` from `airflow.providers.cncf.kubernetes.pod_generator` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `PodGenerator` from `airflow.providers.cncf.kubernetes.pod_generator` instead.
Unsafe fix
36 36 |
@@ -334,17 +322,16 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `PodGene
49 49 | PodDefaults()
50 50 | PodGenerator()
AIR302 [*] `airflow.kubernetes.pod_generator.add_pod_suffix` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:51:1
AIR302_kubernetes.py:51:1: AIR302 [*] `airflow.kubernetes.pod_generator.add_pod_suffix` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
49 | PodDefaults()
50 | PodGenerator()
51 | add_pod_suffix()
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ AIR302
52 | datetime_to_label_safe_datestring()
53 | extend_object_field()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=10.0.0` and use `add_unique_suffix` from `airflow.providers.cncf.kubernetes.kubernetes_helper_functions` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=10.0.0` and use `add_unique_suffix` from `airflow.providers.cncf.kubernetes.kubernetes_helper_functions` instead.
Safe fix
45 45 | merge_objects,
@@ -360,17 +347,16 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=10.0.0` and use `add_un
53 54 | extend_object_field()
54 55 | label_safe_datestring_to_datetime()
AIR302 [*] `airflow.kubernetes.pod_generator.datetime_to_label_safe_datestring` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:52:1
AIR302_kubernetes.py:52:1: AIR302 [*] `airflow.kubernetes.pod_generator.datetime_to_label_safe_datestring` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
50 | PodGenerator()
51 | add_pod_suffix()
52 | datetime_to_label_safe_datestring()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR302
53 | extend_object_field()
54 | label_safe_datestring_to_datetime()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `datetime_to_label_safe_datestring` from `airflow.providers.cncf.kubernetes.pod_generator` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `datetime_to_label_safe_datestring` from `airflow.providers.cncf.kubernetes.pod_generator` instead.
Unsafe fix
38 38 | PodDefaults,
@@ -388,17 +374,16 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `datetim
49 49 | PodDefaults()
50 50 | PodGenerator()
AIR302 [*] `airflow.kubernetes.pod_generator.extend_object_field` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:53:1
AIR302_kubernetes.py:53:1: AIR302 [*] `airflow.kubernetes.pod_generator.extend_object_field` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
51 | add_pod_suffix()
52 | datetime_to_label_safe_datestring()
53 | extend_object_field()
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^ AIR302
54 | label_safe_datestring_to_datetime()
55 | make_safe_label_value()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `extend_object_field` from `airflow.providers.cncf.kubernetes.pod_generator` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `extend_object_field` from `airflow.providers.cncf.kubernetes.pod_generator` instead.
Unsafe fix
39 39 | PodGenerator,
@@ -415,17 +400,16 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `extend_
49 49 | PodDefaults()
50 50 | PodGenerator()
AIR302 [*] `airflow.kubernetes.pod_generator.label_safe_datestring_to_datetime` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:54:1
AIR302_kubernetes.py:54:1: AIR302 [*] `airflow.kubernetes.pod_generator.label_safe_datestring_to_datetime` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
52 | datetime_to_label_safe_datestring()
53 | extend_object_field()
54 | label_safe_datestring_to_datetime()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AIR302
55 | make_safe_label_value()
56 | merge_objects()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `label_safe_datestring_to_datetime` from `airflow.providers.cncf.kubernetes.pod_generator` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `label_safe_datestring_to_datetime` from `airflow.providers.cncf.kubernetes.pod_generator` instead.
Unsafe fix
40 40 | add_pod_suffix,
@@ -441,17 +425,16 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `label_s
49 49 | PodDefaults()
50 50 | PodGenerator()
AIR302 [*] `airflow.kubernetes.pod_generator.make_safe_label_value` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:55:1
AIR302_kubernetes.py:55:1: AIR302 [*] `airflow.kubernetes.pod_generator.make_safe_label_value` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
53 | extend_object_field()
54 | label_safe_datestring_to_datetime()
55 | make_safe_label_value()
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ AIR302
56 | merge_objects()
57 | rand_str()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `make_safe_label_value` from `airflow.providers.cncf.kubernetes.pod_generator` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `make_safe_label_value` from `airflow.providers.cncf.kubernetes.pod_generator` instead.
Unsafe fix
41 41 | datetime_to_label_safe_datestring,
@@ -466,16 +449,15 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `make_sa
49 49 | PodDefaults()
50 50 | PodGenerator()
AIR302 [*] `airflow.kubernetes.pod_generator.merge_objects` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:56:1
AIR302_kubernetes.py:56:1: AIR302 [*] `airflow.kubernetes.pod_generator.merge_objects` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
54 | label_safe_datestring_to_datetime()
55 | make_safe_label_value()
56 | merge_objects()
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^ AIR302
57 | rand_str()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `merge_objects` from `airflow.providers.cncf.kubernetes.pod_generator` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `merge_objects` from `airflow.providers.cncf.kubernetes.pod_generator` instead.
Unsafe fix
42 42 | extend_object_field,
@@ -489,17 +471,16 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `merge_o
49 49 | PodDefaults()
50 50 | PodGenerator()
AIR302 [*] `airflow.kubernetes.pod_generator.rand_str` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:57:1
AIR302_kubernetes.py:57:1: AIR302 [*] `airflow.kubernetes.pod_generator.rand_str` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
55 | make_safe_label_value()
56 | merge_objects()
57 | rand_str()
| ^^^^^^^^
| ^^^^^^^^ AIR302
58 |
59 | from airflow.kubernetes.pod_generator_deprecated import (
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `rand_str` from `airflow.providers.cncf.kubernetes.kubernetes_helper_functions` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `rand_str` from `airflow.providers.cncf.kubernetes.kubernetes_helper_functions` instead.
Unsafe fix
43 43 | label_safe_datestring_to_datetime,
@@ -512,17 +493,16 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `rand_st
49 49 | PodDefaults()
50 50 | PodGenerator()
AIR302 [*] `airflow.kubernetes.pod_generator_deprecated.PodDefaults` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:69:1
AIR302_kubernetes.py:69:1: AIR302 [*] `airflow.kubernetes.pod_generator_deprecated.PodDefaults` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
67 | )
68 |
69 | PodDefaults()
| ^^^^^^^^^^^
| ^^^^^^^^^^^ AIR302
70 | PodGenerator()
71 | make_safe_label_value()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `PodDefaults` from `airflow.providers.cncf.kubernetes.utils.xcom_sidecar` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `PodDefaults` from `airflow.providers.cncf.kubernetes.utils.xcom_sidecar` instead.
Unsafe fix
57 57 | rand_str()
@@ -541,15 +521,14 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `PodDefa
69 69 | PodDefaults()
70 70 | PodGenerator()
AIR302 [*] `airflow.kubernetes.pod_generator_deprecated.PodGenerator` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:70:1
AIR302_kubernetes.py:70:1: AIR302 [*] `airflow.kubernetes.pod_generator_deprecated.PodGenerator` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
69 | PodDefaults()
70 | PodGenerator()
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ AIR302
71 | make_safe_label_value()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `PodGenerator` from `airflow.providers.cncf.kubernetes.pod_generator` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `PodGenerator` from `airflow.providers.cncf.kubernetes.pod_generator` instead.
Unsafe fix
58 58 |
@@ -567,17 +546,16 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `PodGene
69 69 | PodDefaults()
70 70 | PodGenerator()
AIR302 [*] `airflow.kubernetes.pod_generator_deprecated.make_safe_label_value` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:71:1
AIR302_kubernetes.py:71:1: AIR302 [*] `airflow.kubernetes.pod_generator_deprecated.make_safe_label_value` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
69 | PodDefaults()
70 | PodGenerator()
71 | make_safe_label_value()
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ AIR302
72 |
73 | PodLauncher()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `make_safe_label_value` from `airflow.providers.cncf.kubernetes.pod_generator` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `make_safe_label_value` from `airflow.providers.cncf.kubernetes.pod_generator` instead.
Unsafe fix
59 59 | from airflow.kubernetes.pod_generator_deprecated import (
@@ -594,16 +572,15 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `make_sa
69 69 | PodDefaults()
70 70 | PodGenerator()
AIR302 [*] `airflow.kubernetes.pod_launcher.PodLauncher` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:73:1
AIR302_kubernetes.py:73:1: AIR302 [*] `airflow.kubernetes.pod_launcher.PodLauncher` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
71 | make_safe_label_value()
72 |
73 | PodLauncher()
| ^^^^^^^^^^^
| ^^^^^^^^^^^ AIR302
74 | PodStatus()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=3.0.0` and use `PodManager` from `airflow.providers.cncf.kubernetes.utils.pod_manager` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=3.0.0` and use `PodManager` from `airflow.providers.cncf.kubernetes.utils.pod_manager` instead.
Safe fix
65 65 | PodLauncher,
@@ -621,16 +598,15 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=3.0.0` and use `PodMana
75 76 |
76 77 | from airflow.kubernetes.pod_launcher_deprecated import (
AIR302 [*] `airflow.kubernetes.pod_launcher.PodStatus` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:74:1
AIR302_kubernetes.py:74:1: AIR302 [*] `airflow.kubernetes.pod_launcher.PodStatus` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
73 | PodLauncher()
74 | PodStatus()
| ^^^^^^^^^
| ^^^^^^^^^ AIR302
75 |
76 | from airflow.kubernetes.pod_launcher_deprecated import (
|
help: Install `apache-airflow-providers-cncf-kubernetes>=3.0.0` and use `PodPhase` from ` airflow.providers.cncf.kubernetes.utils.pod_manager` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=3.0.0` and use `PodPhase` from ` airflow.providers.cncf.kubernetes.utils.pod_manager` instead.
Safe fix
65 65 | PodLauncher,
@@ -649,17 +625,16 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=3.0.0` and use `PodPhas
76 77 | from airflow.kubernetes.pod_launcher_deprecated import (
77 78 | PodDefaults,
AIR302 [*] `airflow.kubernetes.pod_launcher_deprecated.PodDefaults` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:90:1
AIR302_kubernetes.py:90:1: AIR302 [*] `airflow.kubernetes.pod_launcher_deprecated.PodDefaults` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
88 | from airflow.kubernetes.volume_mount import VolumeMount
89 |
90 | PodDefaults()
| ^^^^^^^^^^^
| ^^^^^^^^^^^ AIR302
91 | PodLauncher()
92 | PodStatus()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `PodDefaults` from `airflow.providers.cncf.kubernetes.utils.xcom_sidecar` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `PodDefaults` from `airflow.providers.cncf.kubernetes.utils.xcom_sidecar` instead.
Unsafe fix
74 74 | PodStatus()
@@ -678,16 +653,15 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `PodDefa
90 90 | PodDefaults()
91 91 | PodLauncher()
AIR302 [*] `airflow.kubernetes.pod_launcher_deprecated.PodLauncher` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:91:1
AIR302_kubernetes.py:91:1: AIR302 [*] `airflow.kubernetes.pod_launcher_deprecated.PodLauncher` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
90 | PodDefaults()
91 | PodLauncher()
| ^^^^^^^^^^^
| ^^^^^^^^^^^ AIR302
92 | PodStatus()
93 | get_kube_client()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=3.0.0` and use `PodManager` from `airflow.providers.cncf.kubernetes.utils.pod_manager` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=3.0.0` and use `PodManager` from `airflow.providers.cncf.kubernetes.utils.pod_manager` instead.
Safe fix
86 86 | )
@@ -702,16 +676,15 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=3.0.0` and use `PodMana
93 94 | get_kube_client()
94 95 |
AIR302 [*] `airflow.kubernetes.pod_launcher_deprecated.PodStatus` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:92:1
AIR302_kubernetes.py:92:1: AIR302 [*] `airflow.kubernetes.pod_launcher_deprecated.PodStatus` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
90 | PodDefaults()
91 | PodLauncher()
92 | PodStatus()
| ^^^^^^^^^
| ^^^^^^^^^ AIR302
93 | get_kube_client()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=3.0.0` and use `PodPhase` from ` airflow.providers.cncf.kubernetes.utils.pod_manager` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=3.0.0` and use `PodPhase` from ` airflow.providers.cncf.kubernetes.utils.pod_manager` instead.
Safe fix
86 86 | )
@@ -727,17 +700,16 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=3.0.0` and use `PodPhas
94 95 |
95 96 | PodRuntimeInfoEnv()
AIR302 [*] `airflow.kubernetes.pod_launcher_deprecated.get_kube_client` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:93:1
AIR302_kubernetes.py:93:1: AIR302 [*] `airflow.kubernetes.pod_launcher_deprecated.get_kube_client` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
91 | PodLauncher()
92 | PodStatus()
93 | get_kube_client()
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^ AIR302
94 |
95 | PodRuntimeInfoEnv()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `get_kube_client` from `airflow.providers.cncf.kubernetes.kube_client` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `get_kube_client` from `airflow.providers.cncf.kubernetes.kube_client` instead.
Unsafe fix
77 77 | PodDefaults,
@@ -756,17 +728,16 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `get_kub
90 90 | PodDefaults()
91 91 | PodLauncher()
AIR302 [*] `airflow.kubernetes.pod_runtime_info_env.PodRuntimeInfoEnv` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:95:1
AIR302_kubernetes.py:95:1: AIR302 [*] `airflow.kubernetes.pod_runtime_info_env.PodRuntimeInfoEnv` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
93 | get_kube_client()
94 |
95 | PodRuntimeInfoEnv()
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ AIR302
96 | K8SModel()
97 | Secret()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `V1EnvVar` from `kubernetes.client.models` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `V1EnvVar` from `kubernetes.client.models` instead.
Safe fix
86 86 | )
@@ -785,16 +756,15 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `V1EnvVa
97 98 | Secret()
98 99 | Volume()
AIR302 [*] `airflow.kubernetes.secret.K8SModel` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:96:1
AIR302_kubernetes.py:96:1: AIR302 [*] `airflow.kubernetes.secret.K8SModel` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
95 | PodRuntimeInfoEnv()
96 | K8SModel()
| ^^^^^^^^
| ^^^^^^^^ AIR302
97 | Secret()
98 | Volume()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `K8SModel` from `airflow.providers.cncf.kubernetes.k8s_model` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `K8SModel` from `airflow.providers.cncf.kubernetes.k8s_model` instead.
Unsafe fix
81 81 | )
@@ -810,17 +780,16 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `K8SMode
90 90 | PodDefaults()
91 91 | PodLauncher()
AIR302 [*] `airflow.kubernetes.secret.Secret` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:97:1
AIR302_kubernetes.py:97:1: AIR302 [*] `airflow.kubernetes.secret.Secret` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
95 | PodRuntimeInfoEnv()
96 | K8SModel()
97 | Secret()
| ^^^^^^
| ^^^^^^ AIR302
98 | Volume()
99 | VolumeMount()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `Secret` from `airflow.providers.cncf.kubernetes.secret` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `Secret` from `airflow.providers.cncf.kubernetes.secret` instead.
Unsafe fix
82 82 | from airflow.kubernetes.pod_runtime_info_env import PodRuntimeInfoEnv
@@ -835,16 +804,15 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `Secret`
90 90 | PodDefaults()
91 91 | PodLauncher()
AIR302 [*] `airflow.kubernetes.volume.Volume` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:98:1
AIR302_kubernetes.py:98:1: AIR302 [*] `airflow.kubernetes.volume.Volume` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
96 | K8SModel()
97 | Secret()
98 | Volume()
| ^^^^^^
| ^^^^^^ AIR302
99 | VolumeMount()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `V1Volume` from `kubernetes.client.models` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `V1Volume` from `kubernetes.client.models` instead.
Safe fix
86 86 | )
@@ -864,17 +832,16 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `V1Volum
100 101 |
101 102 | from airflow.kubernetes.kubernetes_helper_functions import (
AIR302 [*] `airflow.kubernetes.volume_mount.VolumeMount` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:99:1
AIR302_kubernetes.py:99:1: AIR302 [*] `airflow.kubernetes.volume_mount.VolumeMount` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
97 | Secret()
98 | Volume()
99 | VolumeMount()
| ^^^^^^^^^^^
| ^^^^^^^^^^^ AIR302
100 |
101 | from airflow.kubernetes.kubernetes_helper_functions import (
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `V1VolumeMount` from `kubernetes.client.models` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `V1VolumeMount` from `kubernetes.client.models` instead.
Safe fix
86 86 | )
@@ -894,17 +861,16 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `V1Volum
101 102 | from airflow.kubernetes.kubernetes_helper_functions import (
102 103 | annotations_to_key,
AIR302 [*] `airflow.kubernetes.kubernetes_helper_functions.annotations_to_key` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:107:1
AIR302_kubernetes.py:107:1: AIR302 [*] `airflow.kubernetes.kubernetes_helper_functions.annotations_to_key` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
105 | )
106 |
107 | annotations_to_key()
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^ AIR302
108 | get_logs_task_metadata()
109 | rand_str()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `annotations_to_key` from `airflow.providers.cncf.kubernetes.kubernetes_helper_functions` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `annotations_to_key` from `airflow.providers.cncf.kubernetes.kubernetes_helper_functions` instead.
Unsafe fix
99 99 | VolumeMount()
@@ -919,15 +885,14 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `annotat
107 107 | annotations_to_key()
108 108 | get_logs_task_metadata()
AIR302 [*] `airflow.kubernetes.kubernetes_helper_functions.get_logs_task_metadata` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:108:1
AIR302_kubernetes.py:108:1: AIR302 [*] `airflow.kubernetes.kubernetes_helper_functions.get_logs_task_metadata` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
107 | annotations_to_key()
108 | get_logs_task_metadata()
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^ AIR302
109 | rand_str()
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `get_logs_task_metadata` from `airflow.providers.cncf.kubernetes.kubernetes_helper_functions` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `get_logs_task_metadata` from `airflow.providers.cncf.kubernetes.kubernetes_helper_functions` instead.
Unsafe fix
100 100 |
@@ -941,17 +906,16 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `get_log
107 107 | annotations_to_key()
108 108 | get_logs_task_metadata()
AIR302 [*] `airflow.kubernetes.kubernetes_helper_functions.rand_str` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:109:1
AIR302_kubernetes.py:109:1: AIR302 [*] `airflow.kubernetes.kubernetes_helper_functions.rand_str` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
107 | annotations_to_key()
108 | get_logs_task_metadata()
109 | rand_str()
| ^^^^^^^^
| ^^^^^^^^ AIR302
110 |
111 | from airflow.kubernetes.pod_generator import PodGeneratorDeprecated
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `rand_str` from `airflow.providers.cncf.kubernetes.kubernetes_helper_functions` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `rand_str` from `airflow.providers.cncf.kubernetes.kubernetes_helper_functions` instead.
Unsafe fix
101 101 | from airflow.kubernetes.kubernetes_helper_functions import (
@@ -964,15 +928,14 @@ help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `rand_st
107 107 | annotations_to_key()
108 108 | get_logs_task_metadata()
AIR302 [*] `airflow.kubernetes.pod_generator.PodGeneratorDeprecated` is moved into `cncf-kubernetes` provider in Airflow 3.0;
--> AIR302_kubernetes.py:113:1
AIR302_kubernetes.py:113:1: AIR302 [*] `airflow.kubernetes.pod_generator.PodGeneratorDeprecated` is moved into `cncf-kubernetes` provider in Airflow 3.0;
|
111 | from airflow.kubernetes.pod_generator import PodGeneratorDeprecated
112 |
113 | PodGeneratorDeprecated()
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `PodGenerator` from `airflow.providers.cncf.kubernetes.pod_generator` instead.
= help: Install `apache-airflow-providers-cncf-kubernetes>=7.4.0` and use `PodGenerator` from `airflow.providers.cncf.kubernetes.pod_generator` instead.
Unsafe fix
109 109 | rand_str()

View File

@@ -1,17 +1,16 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR302 [*] `airflow.hooks.mysql_hook.MySqlHook` is moved into `mysql` provider in Airflow 3.0;
--> AIR302_mysql.py:9:1
AIR302_mysql.py:9:1: AIR302 [*] `airflow.hooks.mysql_hook.MySqlHook` is moved into `mysql` provider in Airflow 3.0;
|
7 | )
8 |
9 | MySqlHook()
| ^^^^^^^^^
| ^^^^^^^^^ AIR302
10 | PrestoToMySqlOperator()
11 | PrestoToMySqlTransfer()
|
help: Install `apache-airflow-providers-mysql>=1.0.0` and use `MySqlHook` from `airflow.providers.mysql.hooks.mysql` instead.
= help: Install `apache-airflow-providers-mysql>=1.0.0` and use `MySqlHook` from `airflow.providers.mysql.hooks.mysql` instead.
Unsafe fix
1 1 | from __future__ import annotations
@@ -26,15 +25,14 @@ help: Install `apache-airflow-providers-mysql>=1.0.0` and use `MySqlHook` from `
9 9 | MySqlHook()
10 10 | PrestoToMySqlOperator()
AIR302 [*] `airflow.operators.presto_to_mysql.PrestoToMySqlOperator` is moved into `mysql` provider in Airflow 3.0;
--> AIR302_mysql.py:10:1
AIR302_mysql.py:10:1: AIR302 [*] `airflow.operators.presto_to_mysql.PrestoToMySqlOperator` is moved into `mysql` provider in Airflow 3.0;
|
9 | MySqlHook()
10 | PrestoToMySqlOperator()
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ AIR302
11 | PrestoToMySqlTransfer()
|
help: Install `apache-airflow-providers-mysql>=1.0.0` and use `PrestoToMySqlOperator` from `airflow.providers.mysql.transfers.presto_to_mysql` instead.
= help: Install `apache-airflow-providers-mysql>=1.0.0` and use `PrestoToMySqlOperator` from `airflow.providers.mysql.transfers.presto_to_mysql` instead.
Unsafe fix
2 2 |
@@ -48,15 +46,14 @@ help: Install `apache-airflow-providers-mysql>=1.0.0` and use `PrestoToMySqlOper
9 9 | MySqlHook()
10 10 | PrestoToMySqlOperator()
AIR302 [*] `airflow.operators.presto_to_mysql.PrestoToMySqlTransfer` is moved into `mysql` provider in Airflow 3.0;
--> AIR302_mysql.py:11:1
AIR302_mysql.py:11:1: AIR302 [*] `airflow.operators.presto_to_mysql.PrestoToMySqlTransfer` is moved into `mysql` provider in Airflow 3.0;
|
9 | MySqlHook()
10 | PrestoToMySqlOperator()
11 | PrestoToMySqlTransfer()
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-mysql>=1.0.0` and use `PrestoToMySqlOperator` from `airflow.providers.mysql.transfers.presto_to_mysql` instead.
= help: Install `apache-airflow-providers-mysql>=1.0.0` and use `PrestoToMySqlOperator` from `airflow.providers.mysql.transfers.presto_to_mysql` instead.
Unsafe fix
2 2 |

View File

@@ -1,15 +1,14 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR302 [*] `airflow.hooks.oracle_hook.OracleHook` is moved into `oracle` provider in Airflow 3.0;
--> AIR302_oracle.py:5:1
AIR302_oracle.py:5:1: AIR302 [*] `airflow.hooks.oracle_hook.OracleHook` is moved into `oracle` provider in Airflow 3.0;
|
3 | from airflow.hooks.oracle_hook import OracleHook
4 |
5 | OracleHook()
| ^^^^^^^^^^
| ^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-oracle>=1.0.0` and use `OracleHook` from `airflow.providers.oracle.hooks.oracle` instead.
= help: Install `apache-airflow-providers-oracle>=1.0.0` and use `OracleHook` from `airflow.providers.oracle.hooks.oracle` instead.
Unsafe fix
1 1 | from __future__ import annotations

View File

@@ -1,15 +1,14 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR302 [*] `airflow.operators.papermill_operator.PapermillOperator` is moved into `papermill` provider in Airflow 3.0;
--> AIR302_papermill.py:5:1
AIR302_papermill.py:5:1: AIR302 [*] `airflow.operators.papermill_operator.PapermillOperator` is moved into `papermill` provider in Airflow 3.0;
|
3 | from airflow.operators.papermill_operator import PapermillOperator
4 |
5 | PapermillOperator()
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-papermill>=1.0.0` and use `PapermillOperator` from `airflow.providers.papermill.operators.papermill` instead.
= help: Install `apache-airflow-providers-papermill>=1.0.0` and use `PapermillOperator` from `airflow.providers.papermill.operators.papermill` instead.
Unsafe fix
1 1 | from __future__ import annotations

View File

@@ -1,16 +1,15 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR302 [*] `airflow.hooks.pig_hook.PigCliHook` is moved into `apache-pig` provider in Airflow 3.0;
--> AIR302_pig.py:6:1
AIR302_pig.py:6:1: AIR302 [*] `airflow.hooks.pig_hook.PigCliHook` is moved into `apache-pig` provider in Airflow 3.0;
|
4 | from airflow.operators.pig_operator import PigOperator
5 |
6 | PigCliHook()
| ^^^^^^^^^^
| ^^^^^^^^^^ AIR302
7 | PigOperator()
|
help: Install `apache-airflow-providers-apache-pig>=1.0.0` and use `PigCliHook` from `airflow.providers.apache.pig.hooks.pig` instead.
= help: Install `apache-airflow-providers-apache-pig>=1.0.0` and use `PigCliHook` from `airflow.providers.apache.pig.hooks.pig` instead.
Unsafe fix
1 1 | from __future__ import annotations
@@ -22,14 +21,13 @@ help: Install `apache-airflow-providers-apache-pig>=1.0.0` and use `PigCliHook`
6 6 | PigCliHook()
7 7 | PigOperator()
AIR302 [*] `airflow.operators.pig_operator.PigOperator` is moved into `apache-pig` provider in Airflow 3.0;
--> AIR302_pig.py:7:1
AIR302_pig.py:7:1: AIR302 [*] `airflow.operators.pig_operator.PigOperator` is moved into `apache-pig` provider in Airflow 3.0;
|
6 | PigCliHook()
7 | PigOperator()
| ^^^^^^^^^^^
| ^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-apache-pig>=1.0.0` and use `PigOperator` from `airflow.providers.apache.pig.operators.pig` instead.
= help: Install `apache-airflow-providers-apache-pig>=1.0.0` and use `PigOperator` from `airflow.providers.apache.pig.operators.pig` instead.
Unsafe fix
1 1 | from __future__ import annotations

View File

@@ -1,16 +1,15 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR302 [*] `airflow.hooks.postgres_hook.PostgresHook` is moved into `postgres` provider in Airflow 3.0;
--> AIR302_postgres.py:6:1
AIR302_postgres.py:6:1: AIR302 [*] `airflow.hooks.postgres_hook.PostgresHook` is moved into `postgres` provider in Airflow 3.0;
|
4 | from airflow.operators.postgres_operator import Mapping
5 |
6 | PostgresHook()
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ AIR302
7 | Mapping()
|
help: Install `apache-airflow-providers-postgres>=1.0.0` and use `PostgresHook` from `airflow.providers.postgres.hooks.postgres` instead.
= help: Install `apache-airflow-providers-postgres>=1.0.0` and use `PostgresHook` from `airflow.providers.postgres.hooks.postgres` instead.
Unsafe fix
1 1 | from __future__ import annotations
@@ -22,10 +21,9 @@ help: Install `apache-airflow-providers-postgres>=1.0.0` and use `PostgresHook`
6 6 | PostgresHook()
7 7 | Mapping()
AIR302 `airflow.operators.postgres_operator.Mapping` is removed in Airflow 3.0
--> AIR302_postgres.py:7:1
AIR302_postgres.py:7:1: AIR302 `airflow.operators.postgres_operator.Mapping` is removed in Airflow 3.0
|
6 | PostgresHook()
7 | Mapping()
| ^^^^^^^
| ^^^^^^^ AIR302
|

View File

@@ -1,15 +1,14 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR302 [*] `airflow.hooks.presto_hook.PrestoHook` is moved into `presto` provider in Airflow 3.0;
--> AIR302_presto.py:5:1
AIR302_presto.py:5:1: AIR302 [*] `airflow.hooks.presto_hook.PrestoHook` is moved into `presto` provider in Airflow 3.0;
|
3 | from airflow.hooks.presto_hook import PrestoHook
4 |
5 | PrestoHook()
| ^^^^^^^^^^
| ^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-presto>=1.0.0` and use `PrestoHook` from `airflow.providers.presto.hooks.presto` instead.
= help: Install `apache-airflow-providers-presto>=1.0.0` and use `PrestoHook` from `airflow.providers.presto.hooks.presto` instead.
Unsafe fix
1 1 | from __future__ import annotations

View File

@@ -1,15 +1,14 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR302 [*] `airflow.hooks.samba_hook.SambaHook` is moved into `samba` provider in Airflow 3.0;
--> AIR302_samba.py:5:1
AIR302_samba.py:5:1: AIR302 [*] `airflow.hooks.samba_hook.SambaHook` is moved into `samba` provider in Airflow 3.0;
|
3 | from airflow.hooks.samba_hook import SambaHook
4 |
5 | SambaHook()
| ^^^^^^^^^
| ^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-samba>=1.0.0` and use `SambaHook` from `airflow.providers.samba.hooks.samba` instead.
= help: Install `apache-airflow-providers-samba>=1.0.0` and use `SambaHook` from `airflow.providers.samba.hooks.samba` instead.
Unsafe fix
1 1 | from __future__ import annotations

View File

@@ -1,17 +1,16 @@
---
source: crates/ruff_linter/src/rules/airflow/mod.rs
---
AIR302 [*] `airflow.hooks.slack_hook.SlackHook` is moved into `slack` provider in Airflow 3.0;
--> AIR302_slack.py:6:1
AIR302_slack.py:6:1: AIR302 [*] `airflow.hooks.slack_hook.SlackHook` is moved into `slack` provider in Airflow 3.0;
|
4 | from airflow.operators.slack_operator import SlackAPIOperator, SlackAPIPostOperator
5 |
6 | SlackHook()
| ^^^^^^^^^
| ^^^^^^^^^ AIR302
7 | SlackAPIOperator()
8 | SlackAPIPostOperator()
|
help: Install `apache-airflow-providers-slack>=1.0.0` and use `SlackHook` from `airflow.providers.slack.hooks.slack` instead.
= help: Install `apache-airflow-providers-slack>=1.0.0` and use `SlackHook` from `airflow.providers.slack.hooks.slack` instead.
Unsafe fix
1 1 | from __future__ import annotations
@@ -23,15 +22,14 @@ help: Install `apache-airflow-providers-slack>=1.0.0` and use `SlackHook` from `
6 6 | SlackHook()
7 7 | SlackAPIOperator()
AIR302 [*] `airflow.operators.slack_operator.SlackAPIOperator` is moved into `slack` provider in Airflow 3.0;
--> AIR302_slack.py:7:1
AIR302_slack.py:7:1: AIR302 [*] `airflow.operators.slack_operator.SlackAPIOperator` is moved into `slack` provider in Airflow 3.0;
|
6 | SlackHook()
7 | SlackAPIOperator()
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^ AIR302
8 | SlackAPIPostOperator()
|
help: Install `apache-airflow-providers-slack>=1.0.0` and use `SlackAPIOperator` from `airflow.providers.slack.operators.slack` instead.
= help: Install `apache-airflow-providers-slack>=1.0.0` and use `SlackAPIOperator` from `airflow.providers.slack.operators.slack` instead.
Unsafe fix
1 1 | from __future__ import annotations
@@ -44,15 +42,14 @@ help: Install `apache-airflow-providers-slack>=1.0.0` and use `SlackAPIOperator`
6 7 | SlackHook()
7 8 | SlackAPIOperator()
AIR302 [*] `airflow.operators.slack_operator.SlackAPIPostOperator` is moved into `slack` provider in Airflow 3.0;
--> AIR302_slack.py:8:1
AIR302_slack.py:8:1: AIR302 [*] `airflow.operators.slack_operator.SlackAPIPostOperator` is moved into `slack` provider in Airflow 3.0;
|
6 | SlackHook()
7 | SlackAPIOperator()
8 | SlackAPIPostOperator()
| ^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^ AIR302
|
help: Install `apache-airflow-providers-slack>=1.0.0` and use `SlackAPIPostOperator` from `airflow.providers.slack.operators.slack` instead.
= help: Install `apache-airflow-providers-slack>=1.0.0` and use `SlackAPIPostOperator` from `airflow.providers.slack.operators.slack` instead.
Unsafe fix
1 1 | from __future__ import annotations

Some files were not shown because too many files have changed in this diff Show More