Skip to content

Commit

Permalink
use impl_py_slot_def for cimplex tuple enum slots
Browse files Browse the repository at this point in the history
  • Loading branch information
newcomertv committed May 10, 2024
1 parent 98ce858 commit 18f05db
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 42 deletions.
24 changes: 14 additions & 10 deletions pyo3-macros-backend/src/pyclass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::pyfunction::ConstructorAttribute;
use crate::pyimpl::{gen_py_const, PyClassMethodsType};
use crate::pymethod::{
impl_py_getter_def, impl_py_setter_def, MethodAndMethodDef, MethodAndSlotDef, PropertyType,
SlotDef, __INT__, __REPR__, __RICHCMP__,
SlotDef, __GETITEM__, __INT__, __LEN__, __REPR__, __RICHCMP__,
};
use crate::utils::Ctx;
use crate::utils::{self, apply_renaming_rule, PythonDoc};
Expand Down Expand Up @@ -1078,7 +1078,7 @@ fn impl_complex_enum_tuple_variant_field_getters(
let field_type = field.ty;

let field_getter =
complex_enum_variant_field_getter(&variant_cls_type, &field_name, field.span, ctx)?;
complex_enum_variant_field_getter(variant_cls_type, &field_name, field.span, ctx)?;

// Generate the match arms needed to destructure the tuple and access the specific field
let field_access_tokens: Vec<_> = (0..variant.fields.len())
Expand Down Expand Up @@ -1124,7 +1124,7 @@ fn impl_complex_enum_tuple_variant_len(
};

let variant_len =
crate::pymethod::impl_py_slot_def(&variant_cls_type, ctx, &mut len_method_impl.sig)?;
generate_default_protocol_slot(variant_cls_type, &mut len_method_impl, &__LEN__, ctx)?;

Ok((variant_len, len_method_impl))
}
Expand Down Expand Up @@ -1161,8 +1161,12 @@ fn impl_complex_enum_tuple_variant_getitem(
}
};

let variant_getitem =
crate::pymethod::impl_py_slot_def(&variant_cls_type, ctx, &mut get_item_method_impl.sig)?;
let variant_getitem = generate_default_protocol_slot(
variant_cls_type,
&mut get_item_method_impl,
&__GETITEM__,
ctx,
)?;

Ok((variant_getitem, get_item_method_impl))
}
Expand All @@ -1171,7 +1175,7 @@ fn impl_complex_enum_tuple_variant_match_args(
ctx: &Ctx,
variant_cls_type: &syn::Type,
field_names: &mut Vec<Ident>,
) -> Result<(MethodAndMethodDef, syn::ImplItemConst)> {
) -> (MethodAndMethodDef, syn::ImplItemConst) {
let match_args_const_impl: syn::ImplItemConst = match field_names.len() {
// This covers the case where the tuple variant has no fields (valid Rust)
0 => parse_quote! {
Expand Down Expand Up @@ -1210,7 +1214,7 @@ fn impl_complex_enum_tuple_variant_match_args(

let variant_match_args = gen_py_const(variant_cls_type, &spec, ctx);

Ok((variant_match_args, match_args_const_impl))
(variant_match_args, match_args_const_impl)
}

fn impl_complex_enum_tuple_variant_cls(
Expand All @@ -1231,10 +1235,10 @@ fn impl_complex_enum_tuple_variant_cls(

let (mut field_getters, field_getter_impls) = impl_complex_enum_tuple_variant_field_getters(
ctx,
&variant,
variant,
enum_name,
&variant_cls_type,
&variant_ident,
variant_ident,
&mut field_names,
&mut field_types,
)?;
Expand All @@ -1252,7 +1256,7 @@ fn impl_complex_enum_tuple_variant_cls(
slots.push(variant_getitem);

let (variant_match_args, match_args_method_impl) =
impl_complex_enum_tuple_variant_match_args(ctx, &variant_cls_type, &mut field_names)?;
impl_complex_enum_tuple_variant_match_args(ctx, &variant_cls_type, &mut field_names);

field_getters.push(variant_match_args);

Expand Down
35 changes: 3 additions & 32 deletions pyo3-macros-backend/src/pymethod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -735,36 +735,6 @@ fn impl_call_getter(
Ok(fncall)
}

pub fn impl_py_slot_def(
cls: &syn::Type,
ctx: &Ctx,
signature: &mut syn::Signature,
) -> Result<MethodAndSlotDef> {
let spec = FnSpec::parse(
signature,
&mut Vec::new(),
PyFunctionOptions::default(),
ctx,
)?;

let method_name = spec.python_name.to_string();

let slot = match PyMethodKind::from_name(&method_name) {
PyMethodKind::Proto(proto_kind) => {
ensure_no_forbidden_protocol_attributes(&proto_kind, &spec, &method_name)?;
match proto_kind {
PyMethodProtoKind::Slot(slot_def) => slot_def,
_ => {
bail_spanned!(signature.span() => "Only slot methods are supported in #[pyslot]")
}
}
}
_ => bail_spanned!(signature.span() => "Only slot methods are supported in #[pyslot]"),
};

Ok(slot.generate_type_slot(&cls, &spec, &method_name, ctx)?)
}

// Used here for PropertyType::Function, used in pyclass for descriptors.
pub fn impl_py_getter_def(
cls: &syn::Type,
Expand Down Expand Up @@ -960,7 +930,7 @@ const __ANEXT__: SlotDef = SlotDef::new("Py_am_anext", "unaryfunc").return_speci
),
TokenGenerator(|_| quote! { async_iter_tag }),
);
const __LEN__: SlotDef = SlotDef::new("Py_mp_length", "lenfunc").ret_ty(Ty::PySsizeT);
pub const __LEN__: SlotDef = SlotDef::new("Py_mp_length", "lenfunc").ret_ty(Ty::PySsizeT);
const __CONTAINS__: SlotDef = SlotDef::new("Py_sq_contains", "objobjproc")
.arguments(&[Ty::Object])
.ret_ty(Ty::Int);
Expand All @@ -970,7 +940,8 @@ const __INPLACE_CONCAT__: SlotDef =
SlotDef::new("Py_sq_concat", "binaryfunc").arguments(&[Ty::Object]);
const __INPLACE_REPEAT__: SlotDef =
SlotDef::new("Py_sq_repeat", "ssizeargfunc").arguments(&[Ty::PySsizeT]);
const __GETITEM__: SlotDef = SlotDef::new("Py_mp_subscript", "binaryfunc").arguments(&[Ty::Object]);
pub const __GETITEM__: SlotDef =
SlotDef::new("Py_mp_subscript", "binaryfunc").arguments(&[Ty::Object]);

const __POS__: SlotDef = SlotDef::new("Py_nb_positive", "unaryfunc");
const __NEG__: SlotDef = SlotDef::new("Py_nb_negative", "unaryfunc");
Expand Down

0 comments on commit 18f05db

Please sign in to comment.