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

Code before:
                return Member::definitely_declared(synthesized_member);
            }
            // The symbol was not found in the class scope. It might still be implicitly defined in `@classmethod`s.
            return Self::implicit_attribute(db, body_scope, name, MethodDecorator::ClassMethod);
        }

        // For enum classes, `nonmember(value)` creates a non-member attribute.
        // At runtime, the enum metaclass unwraps the value, so accessing the attribute
        // returns the inner value, not the `nonmember` wrapper.
        // We only do the expensive enum class check if the type contains a `nonmember`,
        // then look up bindings directly (like enum_metadata does for `member`) to get
        // the inferred type without the `Unknown` union from declared types.
        if member
            .inner
            .place
            .ignore_possibly_undefined()
            .is_some_and(|ty| ty.contains_nonmember(db))
        {
            let is_enum_class = Type::ClassLiteral(self)
                .is_subtype_of(db, KnownClass::Enum.to_subclass_of(db))
                || self
                    .metaclass(db)
                    .is_subtype_of(db, KnownClass::EnumType.to_subclass_of(db));

            if is_enum_class {
                if let Some(nonmember_value_ty) = extract_nonmember_value(db, body_scope, name) {
                    return Member::definitely_declared(nonmember_value_ty);
                }
            }
        }

        member
    }

    /// Returns the type of a synthesized dataclass member like `__init__` or `__lt__`, or
    /// a synthesized `__new__` method for a `NamedTuple`.
    pub(super) fn own_synthesized_member(
        self,
        db: &'db dyn Db,
        specialization: Option<Specialization<'db>>,
        inherited_generic_context: Option<GenericContext<'db>>,
        name: &str,
    ) -> Option<Type<'db>> {
        let dataclass_params = self.dataclass_params(db);

        let field_policy = CodeGeneratorKind::from_class(db, self, specialization)?;

        let mut transformer_params =
            if let CodeGeneratorKind::DataclassLike(Some(transformer_params)) = field_policy {
                Some(DataclassParams::from_transformer_params(
                    db,

Review comment (refactor):
The `member` variable above already has the `Nonmember` type. Looking at the implementation of `extract_nonmember_value`, it seems like we go through a lot of work just to get that same `Nonmember` instance type back again, and then we get its `value` attribute. So why can't we just work directly from the type we already have in hand, without going back to the place table etc?

Code after:
            }
        });

        if member.is_undefined() {
            if let Some(synthesized_member) =
                self.own_synthesized_member(db, specialization, inherited_generic_context, name)
            {
                return Member::definitely_declared(synthesized_member);
            }
            // The symbol was not found in the class scope. It might still be implicitly defined in `@classmethod`s.
            return Self::implicit_attribute(db, body_scope, name, MethodDecorator::ClassMethod);
        }

        // For enum classes, `nonmember(value)` creates a non-member attribute.
        // At runtime, the enum metaclass unwraps the value, so accessing the attribute
        // returns the inner value, not the `nonmember` wrapper.
        if let Some(ty) = member.inner.place.ignore_possibly_undefined() {
            if let Some(value_ty) = try_unwrap_nonmember_value(db, ty) {
                if is_enum_class_by_inheritance(db, self) {
                    return Member::definitely_declared(value_ty);
                }
            }
        }

        member
    }

    /// Returns the type of a synthesized dataclass member like `__init__` or `__lt__`, or
    /// a synthesized `__new__` method for a `NamedTuple`.
    pub(super) fn own_synthesized_member(
        self,
        db: &'db dyn Db,
        specialization: Option<Specialization<'db>>,
        inherited_generic_context: Option<GenericContext<'db>>,
        name: &str,
    ) -> Option<Type<'db>> {
        let dataclass_params = self.dataclass_params(db);

        let field_policy = CodeGeneratorKind::from_class(db, self, specialization)?;

        let mut transformer_params =
            if let CodeGeneratorKind::DataclassLike(Some(transformer_params)) = field_policy {
                Some(DataclassParams::from_transformer_params(
                    db,
                    transformer_params,
                ))
            } else {
                None
            };

        // Dataclass transformer flags can be overwritten using class arguments.