mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-15 16:10:17 +00:00
[ty] Support dataclasses.KW_ONLY
(#18677)
This commit is contained in:
parent
c3aa965546
commit
2b15f1d240
2 changed files with 71 additions and 2 deletions
|
@ -1313,9 +1313,21 @@ impl<'db> ClassLiteral<'db> {
|
|||
let field_policy = CodeGeneratorKind::from_class(db, self)?;
|
||||
|
||||
let signature_from_fields = |mut parameters: Vec<_>| {
|
||||
let mut kw_only_field_seen = false;
|
||||
for (name, (mut attr_ty, mut default_ty)) in
|
||||
self.fields(db, specialization, field_policy)
|
||||
{
|
||||
if attr_ty
|
||||
.into_nominal_instance()
|
||||
.is_some_and(|instance| instance.class.is_known(db, KnownClass::KwOnly))
|
||||
{
|
||||
// Attributes annotated with `dataclass.KW_ONLY` are not present in the synthesized
|
||||
// `__init__` method, ; they only used to indicate that the parameters after this are
|
||||
// keyword-only.
|
||||
kw_only_field_seen = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// The descriptor handling below is guarded by this fully-static check, because dynamic
|
||||
// types like `Any` are valid (data) descriptors: since they have all possible attributes,
|
||||
// they also have a (callable) `__set__` method. The problem is that we can't determine
|
||||
|
@ -1360,8 +1372,12 @@ impl<'db> ClassLiteral<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
let mut parameter =
|
||||
Parameter::positional_or_keyword(name).with_annotated_type(attr_ty);
|
||||
let mut parameter = if kw_only_field_seen {
|
||||
Parameter::keyword_only(name)
|
||||
} else {
|
||||
Parameter::positional_or_keyword(name)
|
||||
}
|
||||
.with_annotated_type(attr_ty);
|
||||
|
||||
if let Some(default_ty) = default_ty {
|
||||
parameter = parameter.with_default_type(default_ty);
|
||||
|
@ -2149,6 +2165,7 @@ pub enum KnownClass {
|
|||
NotImplementedType,
|
||||
// dataclasses
|
||||
Field,
|
||||
KwOnly,
|
||||
// _typeshed._type_checker_internals
|
||||
NamedTupleFallback,
|
||||
}
|
||||
|
@ -2234,6 +2251,7 @@ impl<'db> KnownClass {
|
|||
| Self::NotImplementedType
|
||||
| Self::Classmethod
|
||||
| Self::Field
|
||||
| Self::KwOnly
|
||||
| Self::NamedTupleFallback => Truthiness::Ambiguous,
|
||||
}
|
||||
}
|
||||
|
@ -2309,6 +2327,7 @@ impl<'db> KnownClass {
|
|||
| Self::NotImplementedType
|
||||
| Self::UnionType
|
||||
| Self::Field
|
||||
| Self::KwOnly
|
||||
| Self::NamedTupleFallback => false,
|
||||
}
|
||||
}
|
||||
|
@ -2385,6 +2404,7 @@ impl<'db> KnownClass {
|
|||
}
|
||||
Self::NotImplementedType => "_NotImplementedType",
|
||||
Self::Field => "Field",
|
||||
Self::KwOnly => "KW_ONLY",
|
||||
Self::NamedTupleFallback => "NamedTupleFallback",
|
||||
}
|
||||
}
|
||||
|
@ -2615,6 +2635,7 @@ impl<'db> KnownClass {
|
|||
| Self::Deque
|
||||
| Self::OrderedDict => KnownModule::Collections,
|
||||
Self::Field => KnownModule::Dataclasses,
|
||||
Self::KwOnly => KnownModule::Dataclasses,
|
||||
Self::NamedTupleFallback => KnownModule::TypeCheckerInternals,
|
||||
}
|
||||
}
|
||||
|
@ -2679,6 +2700,7 @@ impl<'db> KnownClass {
|
|||
| Self::NamedTuple
|
||||
| Self::NewType
|
||||
| Self::Field
|
||||
| Self::KwOnly
|
||||
| Self::NamedTupleFallback => false,
|
||||
}
|
||||
}
|
||||
|
@ -2745,6 +2767,7 @@ impl<'db> KnownClass {
|
|||
| Self::NamedTuple
|
||||
| Self::NewType
|
||||
| Self::Field
|
||||
| Self::KwOnly
|
||||
| Self::NamedTupleFallback => false,
|
||||
}
|
||||
}
|
||||
|
@ -2818,6 +2841,7 @@ impl<'db> KnownClass {
|
|||
}
|
||||
"_NotImplementedType" => Self::NotImplementedType,
|
||||
"Field" => Self::Field,
|
||||
"KW_ONLY" => Self::KwOnly,
|
||||
"NamedTupleFallback" => Self::NamedTupleFallback,
|
||||
_ => return None,
|
||||
};
|
||||
|
@ -2874,6 +2898,7 @@ impl<'db> KnownClass {
|
|||
| Self::AsyncGeneratorType
|
||||
| Self::WrapperDescriptorType
|
||||
| Self::Field
|
||||
| Self::KwOnly
|
||||
| Self::NamedTupleFallback => module == self.canonical_module(db),
|
||||
Self::NoneType => matches!(module, KnownModule::Typeshed | KnownModule::Types),
|
||||
Self::SpecialForm
|
||||
|
@ -3079,6 +3104,7 @@ mod tests {
|
|||
KnownClass::UnionType => PythonVersion::PY310,
|
||||
KnownClass::BaseExceptionGroup | KnownClass::ExceptionGroup => PythonVersion::PY311,
|
||||
KnownClass::GenericAlias => PythonVersion::PY39,
|
||||
KnownClass::KwOnly => PythonVersion::PY310,
|
||||
_ => PythonVersion::PY37,
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue