Repository navigation
Restore CLI commands from custom executors and auth managers - #72858
FrankYang0529 wants to merge 2 commits into
Conversation
potiuk
left a comment
There was a problem hiding this comment.
Good catch on the regression, and the reproduction in the description makes it easy to confirm. Adding _exclude_registered_commands so a subclass of a provider executor doesn't re-register the provider's own commands is the right instinct — I think it just needs to go one step further.
provider_command_names is a snapshot taken before the fallback runs (see inline on cli_parser.py:108). It dedupes against commands registered through a provider cli section, but not against commands the fallback loops register themselves. With a provider executor whose provider has no cli section — the population this fallback exists for — plus a custom subclass:
[core]
executor = airflow.providers.celery.executors.celery_executor.CeleryExecutor,my_company.executors.MyCeleryExecutorexecutors_defined_cli is empty so neither is skipped, CeleryExecutor registers celery, and MyCeleryExecutor inherits get_cli_commands() and registers celery a second time against an empty provider_command_names. That hits the duplicate check at cli_parser.py:178 and raises CliConflictError at import time, so every airflow command fails. Before this PR the loop never reached the subclass, so it's newly reachable.
Making the set live inside the helper covers both loops:
result: list[CLICommand] = []
for command in commands:
if command.name in registered_names:
log.debug(
"Skipping CLI command '%s' from %s: already registered by a provider.", command.name, source
)
continue
registered_names.add(command.name)
result.append(command)
return resultSmaller observations
test_cli_parser.py:182— swappingairflow.auth.managersforairflow.api_fastapi.auth.managersis a genuine fix (the old path no longer exists, so that param was passing vacuously). But replacingairflow.executors.executor_loaderwithairflow.executors.base_executordrops the guard #59805 added, becauseExecutorLoadermoved to a module-level import — and the docstring on line 185 still says the test coversexecutor_loader. For what it's worth there's no actual import-cost regression:cli_configalready pullsexecutor_loaderin viafrom airflow.jobs.job import JobState. Keeping that one import lazy where it was preserves the guard for theAIRFLOW_PACKAGE_NAMEdocs path at no cost; if dropping it is deliberate, please update the docstring and say why.- Worth a newsfragment —
airflow-core/newsfragments/72858.bugfix.rst. Custom executors and auth managers silently losing their CLI commands is user-visible, which is what AGENTS.md asks for: "Forairflow-core… user-facing changes, add a newsfragment." cli_parser.py:135and:188—executors_defined_cli/auth_managers_defined_cliare exact complements of the*_not_defined_clidicts built immediately above them, over the same*_without_checkiterable. Deriving them from the dict already computed avoids the second pass and keeps the two from drifting.
Suggested additional reviewers
@dheerajturaga, @henry3260 (CODEOWNERS for airflow-core/src/airflow/cli/) and @vincbeck (CODEOWNERS for airflow-core/src/airflow/api_fastapi/auth/, for the auth-manager half).
This review was drafted by an AI-assisted tool and confirmed by an Airflow maintainer. The findings below are observations, not blockers; an Airflow maintainer — a real person — will take the next look at the PR. If you think a finding is mis-applied, please reply on the PR and a maintainer will weigh in.
More on how Airflow handles maintainer review: contributing-docs/05_pull_requests.rst.
Drafted-by: Claude Code (Opus 5); reviewed by @potiuk before posting
Signed-off-by: PoAn Yang <payang@apache.org>
Signed-off-by: PoAn Yang <payang@apache.org>
9e286f2 to
b12c58d
Compare
|
Hello @FrankYang0529 - thank you for your contributions to Apache Airflow! The Airflow community has introduced a limit of 5 open pull requests at a time for contributors without write access to the repository. You currently have 30 open pull requests, so - as a one-time step of introducing the limit - we closed the ones where maintainers have not engaged yet:
These pull requests stay open because maintainers are already engaged in them - they count towards your limit:
This is not a judgement of you or of your changes. We never told contributors before that opening many pull requests at once was a problem, so there is nothing to feel bad about - and nothing is lost: your branches, commits and the review history stay where they are. What we ask you to do is to make your first prioritization decision: choose which of the pull requests above matter most to you, and reopen them (up to 5 open at a time, including the ones still open) with the "Reopen pull request" button or While your pull requests are waiting for review, the most valuable thing you can do is help in other ways - reviewing other contributors' pull requests, helping with issues, and taking part in the discussions on the devlist and Slack. Why we introduced the limit, what it means for you and how to reopen or restore a pull request is explained in https://github.com/apache/airflow/blob/main/contributing-docs/32_open_pull_request_limit.rst. Drafted-by: Claude Code (Opus 5); reviewed by @potiuk before posting |
|
@potiuk You had reviewed this before #72858 (review). Could you help me review this again when you have time? Thank you. |
Why
get_cli_commands(). The commands are missing with no warning and no error.clisection was introduced (Introduce a "cli" section in provider metadata #59805),cli_parserlooped over every configured executor and called the configured auth manager.core-concepts/executor/index.rstandcore-concepts/auth-manager/index.rststill documentget_cli_commands(), and the auth manager page still shows[core] auth_manager = my_company.auth_managers.MyCustomAuthManageras the way to configure a custom class.How
clisection already covers, skip those, and send everything else through the fallback.get_cli_commands(). Without this, it registers the same names a second time.cli_parserraisesCliConflictErroron a duplicate name and the CLI fails to start.Verification
uv run --project airflow-core pytest airflow-core/tests/unit/cli/test_cli_parser.py -qOn main branch, the count is
0. On this branch, it shows1andpong from MyExecutor.On main branch, the count is
0. On this branch, it shows1andhello from MyCustomAuthManager.These two are regression guards rather than bug demos. On main they also print 1, because the fallback that imports the class and calls
get_cli_commands()never runs there. What they prove is that re-opening that fallback does not start registering duplicate commands.Was generative AI tooling used to co-author this PR?
{pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.