(attr: PunctuatedNestedMeta, item: &Ident)
| 1754 | } |
| 1755 | |
| 1756 | fn extract_impl_attrs(attr: PunctuatedNestedMeta, item: &Ident) -> Result<ExtractedImplAttrs> { |
| 1757 | let mut withs = Vec::new(); |
| 1758 | let mut with_method_defs = Vec::new(); |
| 1759 | let mut with_slots = Vec::new(); |
| 1760 | let mut flags = vec![quote! { |
| 1761 | { |
| 1762 | #[cfg(not(debug_assertions))] { |
| 1763 | ::rustpython_vm::types::PyTypeFlags::DEFAULT |
| 1764 | } |
| 1765 | #[cfg(debug_assertions)] { |
| 1766 | ::rustpython_vm::types::PyTypeFlags::DEFAULT |
| 1767 | .union(::rustpython_vm::types::PyTypeFlags::_CREATED_WITH_FLAGS) |
| 1768 | } |
| 1769 | } |
| 1770 | }]; |
| 1771 | let mut payload = None; |
| 1772 | let mut itemsize = None; |
| 1773 | |
| 1774 | for attr in attr { |
| 1775 | match attr { |
| 1776 | NestedMeta::Meta(Meta::List(MetaList { path, nested, .. })) => { |
| 1777 | if path.is_ident("with") { |
| 1778 | for meta in nested { |
| 1779 | let NestedMeta::Meta(Meta::Path(path)) = &meta else { |
| 1780 | bail_span!(meta, "#[pyclass(with(...))] arguments must be paths") |
| 1781 | }; |
| 1782 | let (extend_class, method_defs, extend_slots) = if path.is_ident("PyRef") |
| 1783 | || path.is_ident("Py") |
| 1784 | { |
| 1785 | // special handling for PyRef |
| 1786 | ( |
| 1787 | quote!(#path::<Self>::__extend_py_class), |
| 1788 | quote!(#path::<Self>::__OWN_METHOD_DEFS), |
| 1789 | quote!(#path::<Self>::__extend_slots), |
| 1790 | ) |
| 1791 | } else { |
| 1792 | if path.is_ident("DefaultConstructor") { |
| 1793 | bail_span!( |
| 1794 | meta, |
| 1795 | "Try `#[pyclass(with(Constructor, ...))]` instead of `#[pyclass(with(DefaultConstructor, ...))]`. DefaultConstructor implicitly implements Constructor." |
| 1796 | ) |
| 1797 | } |
| 1798 | ( |
| 1799 | quote!(<Self as #path>::__extend_py_class), |
| 1800 | quote!(<Self as #path>::__OWN_METHOD_DEFS), |
| 1801 | quote!(<Self as #path>::__extend_slots), |
| 1802 | ) |
| 1803 | }; |
| 1804 | let item_span = item.span().resolved_at(Span::call_site()); |
| 1805 | withs.push(quote_spanned! { path.span() => |
| 1806 | #extend_class(ctx, class); |
| 1807 | }); |
| 1808 | with_method_defs.push(method_defs); |
| 1809 | // For Initializer and Constructor traits, directly set the slot |
| 1810 | // instead of calling __extend_slots. This ensures that the trait |
| 1811 | // impl's override (e.g., slot_init in impl Initializer) is used, |
| 1812 | // not the trait's default implementation. |
| 1813 | let slot_code = if path.is_ident("Initializer") { |
no test coverage detected