Avatar for the astral-sh user
astral-sh
ruff
BlogDocsChangelog

Performance History

Latest Results

try using the new `promote_singletons` method?
alex/promote-class-literals
5 minutes ago
Exit earlier in lint check
amy/markdown-lsp-early-return
29 minutes ago
[`airflow`] Flag `Variable.get()` calls outside of task execution context (`AIR003`) (#23584) ## Summary Implements a new rule `AIR003` (`airflow-variable-get-outside-task`) that flags `Variable.get()` calls outside of task execution context. Per the [Airflow best practices documentation](https://airflow.apache.org/docs/apache-airflow/stable/best-practices.html#airflow-variables), calling `Variable.get()` at module level or inside operator constructor arguments causes a database query **every time the DAG file is parsed** by the scheduler. This can degrade parsing performance and even cause DAG file timeouts. The recommended alternative is to pass variables via Jinja templates (`{{ var.value.my_var }}`), which defer the lookup until task execution. ### What the rule flags ```python from airflow.sdk import Variable from airflow.operators.bash import BashOperator # Top-level Variable.get() — runs on every DAG parse foo = Variable.get("foo") # Variable.get() in operator constructor args — also runs on every DAG parse BashOperator( task_id="bad", bash_command="echo $FOO", env={"FOO": Variable.get("foo")}, ) # Variable.get() in a regular helper function — not a task execution context def helper(): return Variable.get("foo") ``` ### What it allows `Variable.get()` is fine inside code that only runs during task execution: - `@task`-decorated functions (including `@task()`, `@task.branch`, `@task.short_circuit`, etc.) - `execute()` methods on `BaseOperator` subclasses ### Implementation details - Resolves `Variable.get` via the semantic model, matching both `airflow.models.Variable` and `airflow.sdk.Variable` import paths. - Determines "task execution context" by walking the statement hierarchy (`current_statements()`) looking for a parent `FunctionDef` that is either: - decorated with `@task` / `@task.<variant>` (resolved via `airflow.decorators.task`), or - named `execute` inside a class inheriting from `BaseOperator`. - Handles both `@task` and `@task()` forms via `map_callable`, and attribute-style decorators like `@task.branch` via `Expr::Attribute` resolution. ## Test Plan Added snapshot tests in `AIR005.py` covering: - **Violations**: `Variable.get()` at module level, inside operator constructor keyword arguments, inside f-string interpolation in operator args, and in a regular helper function. Tested both `airflow.models.Variable` and `airflow.sdk.Variable` import paths. - **Non-violations**: `Variable.get()` inside `@task`, `@task()`, `@task.branch` decorated functions, inside a `BaseOperator.execute()` method, and Jinja template usage (no `Variable.get()` call). related: https://github.com/apache/airflow/issues/43176
main
44 minutes ago

Active Branches

Implement a fixer for E402
last run
32 minutes ago
#22212
CodSpeed Performance Gauge
0%
#23894
CodSpeed Performance Gauge
0%
#23701
CodSpeed Performance Gauge
0%
© 2026 CodSpeed Technology
Home Terms Privacy Docs