Repository: astral-sh/ruff
File: crates/ty_python_semantic/src/types/overrides.rs (Rust)

Code before:
///
/// `NamedTuple` classes have certain synthesized attributes (like `_asdict`, `_make`, etc.)
/// that cannot be overwritten. Attempting to assign to these attributes (without type
/// annotations) or define methods with these names will raise an `AttributeError` at runtime.
fn check_prohibited_namedtuple_attrs<'db>(
    context: &InferContext<'db, '_>,
    own_class_members: &FxHashSet<MemberWithDefinition<'db>>,
) {
    let db = context.db();
    let module = context.module();

    for member in own_class_members {
        if !PROHIBITED_NAMEDTUPLE_ATTRS.contains(&member.member.name.as_str()) {
            continue;
        }

        let Some(definition) = member.definition else {
            continue;
        };

        // Only annotated assignments are allowed (they become fields).
        // Everything else (assignments, method definitions, etc.) is an error.
        if !matches!(definition.kind(db), DefinitionKind::AnnotatedAssignment(_)) {
            if let Some(builder) = context.report_lint(
                &OVERRIDE_OF_PROHIBITED_NAMED_TUPLE_ATTRIBUTE,
                definition.full_range(db, module),
            ) {
                builder.into_diagnostic(format_args!(
                    "Cannot overwrite NamedTuple attribute `{}`",
                    member.member.name
                ));
            }
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub(super) enum MethodKind<'db> {
    Synthesized(CodeGeneratorKind<'db>),
    #[default]
    NotSynthesized,
}

bitflags! {
    /// Bitflags representing which override-related rules have been enabled.
    #[derive(Default, Debug, Copy, Clone)]
    struct OverrideRulesConfig: u8 {
        const LISKOV_METHODS = 1 << 0;
        const EXPLICIT_OVERRIDE = 1 << 1;
        const FINAL_METHOD_OVERRIDDEN = 1 << 2;
        const PROHIBITED_NAMED_TUPLE_ATTR = 1 << 3;

Review comment (suggestion):
we should use `.focus_range()` here rather than `.full_range()` -- the full range might be huge!

Code after:

    if let Some((superclass, superclass_method)) = overridden_final_method {
        report_overridden_final_method(
            context,
            &member.name,
            *definition,
            member.ty,
            superclass,
            class,
            &superclass_method,
        );
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub(super) enum MethodKind<'db> {
    Synthesized(CodeGeneratorKind<'db>),
    #[default]
    NotSynthesized,
}

bitflags! {
    /// Bitflags representing which override-related rules have been enabled.
    #[derive(Default, Debug, Copy, Clone)]
    struct OverrideRulesConfig: u8 {
        const LISKOV_METHODS = 1 << 0;
        const EXPLICIT_OVERRIDE = 1 << 1;
        const FINAL_METHOD_OVERRIDDEN = 1 << 2;
        const PROHIBITED_NAMED_TUPLE_ATTR = 1 << 3;
    }
}

impl From<&InferContext<'_, '_>> for OverrideRulesConfig {
    fn from(value: &InferContext<'_, '_>) -> Self {
        let db = value.db();
        let rule_selection = db.rule_selection(value.file());

        let mut config = OverrideRulesConfig::empty();

        if rule_selection.is_enabled(LintId::of(&INVALID_METHOD_OVERRIDE)) {
            config |= OverrideRulesConfig::LISKOV_METHODS;
        }
        if rule_selection.is_enabled(LintId::of(&INVALID_EXPLICIT_OVERRIDE)) {
            config |= OverrideRulesConfig::EXPLICIT_OVERRIDE;
        }
        if rule_selection.is_enabled(LintId::of(&OVERRIDE_OF_FINAL_METHOD)) {
            config |= OverrideRulesConfig::FINAL_METHOD_OVERRIDDEN;
        }
        if rule_selection.is_enabled(LintId::of(&INVALID_NAMED_TUPLE)) {
            config |= OverrideRulesConfig::PROHIBITED_NAMED_TUPLE_ATTR;
        }