Repository: astral-sh/ruff
File: crates/ruff_linter/src/rules/airflow/rules/function_signature_change_in_3.rs (Rust)

Code before:
/// AIR303
pub(crate) fn airflow_3_incompatible_method_signature_def(
    checker: &Checker,
    function_def: &StmtFunctionDef,
) {
    if !checker.semantic().seen_module(Modules::AIRFLOW) {
        return;
    }

    // Check for deprecated get_link signature in BaseOperatorLink subclasses
    if is_method_in_subclass(function_def, checker.semantic(), "get_link", |segments| {
        matches!(
            segments,
            ["airflow", "models" | "sdk", .., "BaseOperatorLink"]
        )
    }) {
        let parameters = &function_def.parameters;
        let positional_count = parameters.posonlyargs.len() + parameters.args.len();

        let is_valid_signature = match positional_count {
            // check valid signature `def get_link(self, operator, *, ti_key)`
            2 => parameters
                .kwonlyargs
                .iter()
                .any(|p| p.name().as_str() == "ti_key"),
            // check valid signature `def get_link(self, operator, ti_key)`
            3 => parameters
                .posonlyargs
                .iter()
                .chain(parameters.args.iter())
                .nth(2)
                .is_some_and(|p| p.name().as_str() == "ti_key"),
            _ => false,
        };

        if !is_valid_signature {
            checker.report_diagnostic(
                Airflow3IncompatibleFunctionSignature {
                    function_name: "get_link".to_string(),
                    change: FunctionSignatureChange::Message(
                        "Use `def get_link(self, operator, *, ti_key)` or `def get_link(self, operator, ti_key)` as the method signature.",
                    ),
                },
                function_def.name.range(),
            );
        }
    }
}

fn check_method_arguments(
    checker: &Checker,

Review comment (suggestion):
what would happen if we use `def get_link(self, operator, ti_key)`

Code after:
/// AIR303
pub(crate) fn airflow_3_incompatible_method_signature_def(
    checker: &Checker,
    function_def: &StmtFunctionDef,
) {
    if !checker.semantic().seen_module(Modules::AIRFLOW) {
        return;
    }

    // Check for deprecated get_link signature in BaseOperatorLink subclasses
    if is_method_in_subclass(
        function_def,
        checker.semantic(),
        "get_link",
        |qualified_name| {
            matches!(
                qualified_name.segments(),
                ["airflow", "models" | "sdk", .., "BaseOperatorLink"]
            )
        },
    ) {
        let parameters = &function_def.parameters;
        let positional_count = parameters.posonlyargs.len() + parameters.args.len();

        let is_valid_signature = match positional_count {
            // check valid signature `def get_link(self, operator, *, ti_key)`
            2 => parameters
                .kwonlyargs
                .iter()
                .any(|p| p.name().as_str() == "ti_key"),
            // check valid signature `def get_link(self, operator, ti_key)`
            3 => parameters
                .posonlyargs
                .iter()
                .chain(parameters.args.iter())
                .nth(2)
                .is_some_and(|p| p.name().as_str() == "ti_key"),
            _ => false,
        };

        if !is_valid_signature {
            checker.report_diagnostic(
                Airflow3IncompatibleFunctionSignature {
                    function_name: "get_link".to_string(),
                    change: FunctionSignatureChange::Message(
                        "Use `def get_link(self, operator, *, ti_key)` or `def get_link(self, operator, ti_key)` as the method signature.",
                    ),
                },
                function_def.name.range(),
            );
        }