Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions pyo3-macros-backend/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ pub mod kw {
syn::custom_keyword!(cancel_handle);
syn::custom_keyword!(constructor);
syn::custom_keyword!(dict);
syn::custom_keyword!(doc_mode);
syn::custom_keyword!(eq);
syn::custom_keyword!(eq_int);
syn::custom_keyword!(end_doc_mode);
syn::custom_keyword!(extends);
syn::custom_keyword!(freelist);
syn::custom_keyword!(from_py_with);
Expand Down Expand Up @@ -318,6 +320,7 @@ pub type StrFormatterAttribute = OptionalKeywordAttribute<kw::str, StringFormatt
pub type TextSignatureAttribute = KeywordAttribute<kw::text_signature, TextSignatureAttributeValue>;
pub type SubmoduleAttribute = kw::submodule;
pub type GILUsedAttribute = KeywordAttribute<kw::gil_used, LitBool>;
pub type DocModeAttribute = KeywordAttribute<kw::doc_mode, LitStr>;

impl<K: Parse + std::fmt::Debug, V: Parse> Parse for KeywordAttribute<K, V> {
fn parse(input: ParseStream<'_>) -> Result<Self> {
Expand Down
2 changes: 1 addition & 1 deletion pyo3-macros-backend/src/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -975,7 +975,7 @@ impl<'a> FnSpec<'a> {
}

/// Forwards to [utils::get_doc] with the text signature of this spec.
pub fn get_doc(&self, attrs: &[syn::Attribute], ctx: &Ctx) -> PythonDoc {
pub fn get_doc(&self, attrs: &mut Vec<syn::Attribute>, ctx: &Ctx) -> syn::Result<PythonDoc> {
let text_signature = self
.text_signature_call_signature()
.map(|sig| format!("{}{}", self.python_name, sig));
Expand Down
4 changes: 2 additions & 2 deletions pyo3-macros-backend/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ pub fn pymodule_module_impl(
options.take_pyo3_options(attrs)?;
let ctx = &Ctx::new(&options.krate, None);
let Ctx { pyo3_path, .. } = ctx;
let doc = get_doc(attrs, None, ctx);
let doc = get_doc(attrs, None, ctx)?;
let name = options
.name
.map_or_else(|| ident.unraw(), |name| name.value.0);
Expand Down Expand Up @@ -434,7 +434,7 @@ pub fn pymodule_function_impl(
.name
.map_or_else(|| ident.unraw(), |name| name.value.0);
let vis = &function.vis;
let doc = get_doc(&function.attrs, None, ctx);
let doc = get_doc(&mut function.attrs, None, ctx)?;

let initialization = module_initialization(
&name,
Expand Down
30 changes: 15 additions & 15 deletions pyo3-macros-backend/src/pyclass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ pub fn build_py_class(
args.options.take_pyo3_options(&mut class.attrs)?;

let ctx = &Ctx::new(&args.options.krate, None);
let doc = utils::get_doc(&class.attrs, None, ctx);
let doc = utils::get_doc(&mut class.attrs, None, ctx)?;

if let Some(lt) = class.generics.lifetimes().next() {
bail_spanned!(
Expand Down Expand Up @@ -436,11 +436,11 @@ fn impl_class(
ctx,
)?;

let (default_class_geitem, default_class_geitem_method) =
pyclass_class_geitem(&args.options, &syn::parse_quote!(#cls), ctx)?;
let (default_class_getitem, default_class_getitem_method) =
pyclass_class_getitem(&args.options, &syn::parse_quote!(#cls), ctx)?;

if let Some(default_class_geitem_method) = default_class_geitem_method {
default_methods.push(default_class_geitem_method);
if let Some(default_class_getitem_method) = default_class_getitem_method {
default_methods.push(default_class_getitem_method);
}

let (default_str, default_str_slot) =
Expand Down Expand Up @@ -474,7 +474,7 @@ fn impl_class(
#default_richcmp
#default_hash
#default_str
#default_class_geitem
#default_class_getitem
}
})
}
Expand Down Expand Up @@ -521,7 +521,7 @@ pub fn build_py_enum(
bail_spanned!(generic.span() => "enums do not support #[pyclass(generic)]");
}

let doc = utils::get_doc(&enum_.attrs, None, ctx);
let doc = utils::get_doc(&mut enum_.attrs, None, ctx)?;
let enum_ = PyClassEnum::new(enum_)?;
impl_enum(enum_, &args, doc, method_type, ctx)
}
Expand Down Expand Up @@ -1759,7 +1759,7 @@ fn complex_enum_variant_field_getter<'a>(
let property_type = crate::pymethod::PropertyType::Function {
self_type: &self_type,
spec: &spec,
doc: crate::get_doc(&[], None, ctx),
doc: PythonDoc::empty(ctx),
};

let getter = crate::pymethod::impl_py_getter_def(variant_cls_type, property_type, ctx)?;
Expand Down Expand Up @@ -2027,7 +2027,7 @@ fn pyclass_hash(
}
}

fn pyclass_class_geitem(
fn pyclass_class_getitem(
options: &PyClassPyO3Options,
cls: &syn::Type,
ctx: &Ctx,
Expand All @@ -2036,7 +2036,7 @@ fn pyclass_class_geitem(
match options.generic {
Some(_) => {
let ident = format_ident!("__class_getitem__");
let mut class_geitem_impl: syn::ImplItemFn = {
let mut class_getitem_impl: syn::ImplItemFn = {
parse_quote! {
#[classmethod]
fn #ident<'py>(
Expand All @@ -2049,19 +2049,19 @@ fn pyclass_class_geitem(
};

let spec = FnSpec::parse(
&mut class_geitem_impl.sig,
&mut class_geitem_impl.attrs,
&mut class_getitem_impl.sig,
&mut class_getitem_impl.attrs,
Default::default(),
)?;

let class_geitem_method = crate::pymethod::impl_py_method_def(
let class_getitem_method = crate::pymethod::impl_py_method_def(
cls,
&spec,
&spec.get_doc(&class_geitem_impl.attrs, ctx),
&spec.get_doc(&mut class_getitem_impl.attrs, ctx)?,
Some(quote!(#pyo3_path::ffi::METH_CLASS)),
ctx,
)?;
Ok((Some(class_geitem_impl), Some(class_geitem_method)))
Ok((Some(class_getitem_impl), Some(class_getitem_method)))
}
None => Ok((None, None)),
}
Expand Down
2 changes: 1 addition & 1 deletion pyo3-macros-backend/src/pyfunction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ pub fn impl_wrap_pyfunction(
);
}
let wrapper = spec.get_wrapper_function(&wrapper_ident, None, ctx)?;
let methoddef = spec.get_methoddef(wrapper_ident, &spec.get_doc(&func.attrs, ctx), ctx);
let methoddef = spec.get_methoddef(wrapper_ident, &spec.get_doc(&mut func.attrs, ctx)?, ctx);

let wrapped_pyfunction = quote! {
// Create a module with the same name as the `#[pyfunction]` - this way `use <the function>`
Expand Down
2 changes: 1 addition & 1 deletion pyo3-macros-backend/src/pyimpl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ pub fn impl_methods(
let method = PyMethod::parse(&mut meth.sig, &mut meth.attrs, fun_options)?;
#[cfg(feature = "experimental-inspect")]
extra_fragments.push(method_introspection_code(&method.spec, ty, ctx));
match pymethod::gen_py_method(ty, method, &meth.attrs, ctx)? {
match pymethod::gen_py_method(ty, method, &mut meth.attrs, ctx)? {
GeneratedPyMethod::Method(MethodAndMethodDef {
associated_method,
method_def,
Expand Down
28 changes: 16 additions & 12 deletions pyo3-macros-backend/src/pymethod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ pub fn is_proto_method(name: &str) -> bool {
pub fn gen_py_method(
cls: &syn::Type,
method: PyMethod<'_>,
meth_attrs: &[syn::Attribute],
meth_attrs: &mut Vec<syn::Attribute>,
ctx: &Ctx,
) -> Result<GeneratedPyMethod> {
let spec = &method.spec;
Expand Down Expand Up @@ -236,21 +236,21 @@ pub fn gen_py_method(
(_, FnType::Fn(_)) => GeneratedPyMethod::Method(impl_py_method_def(
cls,
spec,
&spec.get_doc(meth_attrs, ctx),
&spec.get_doc(meth_attrs, ctx)?,
None,
ctx,
)?),
(_, FnType::FnClass(_)) => GeneratedPyMethod::Method(impl_py_method_def(
cls,
spec,
&spec.get_doc(meth_attrs, ctx),
&spec.get_doc(meth_attrs, ctx)?,
Some(quote!(#pyo3_path::ffi::METH_CLASS)),
ctx,
)?),
(_, FnType::FnStatic) => GeneratedPyMethod::Method(impl_py_method_def(
cls,
spec,
&spec.get_doc(meth_attrs, ctx),
&spec.get_doc(meth_attrs, ctx)?,
Some(quote!(#pyo3_path::ffi::METH_STATIC)),
ctx,
)?),
Expand All @@ -264,7 +264,7 @@ pub fn gen_py_method(
PropertyType::Function {
self_type,
spec,
doc: spec.get_doc(meth_attrs, ctx),
doc: spec.get_doc(meth_attrs, ctx)?,
},
ctx,
)?),
Expand All @@ -273,7 +273,7 @@ pub fn gen_py_method(
PropertyType::Function {
self_type,
spec,
doc: spec.get_doc(meth_attrs, ctx),
doc: spec.get_doc(meth_attrs, ctx)?,
},
ctx,
)?),
Expand Down Expand Up @@ -627,7 +627,7 @@ pub fn impl_py_setter_def(
) -> Result<MethodAndMethodDef> {
let Ctx { pyo3_path, .. } = ctx;
let python_name = property_type.null_terminated_python_name(ctx)?;
let doc = property_type.doc(ctx);
let doc = property_type.doc(ctx)?;
let mut holders = Holders::new();
let setter_impl = match property_type {
PropertyType::Descriptor {
Expand Down Expand Up @@ -815,7 +815,7 @@ pub fn impl_py_getter_def(
) -> Result<MethodAndMethodDef> {
let Ctx { pyo3_path, .. } = ctx;
let python_name = property_type.null_terminated_python_name(ctx)?;
let doc = property_type.doc(ctx);
let doc = property_type.doc(ctx)?;

let mut cfg_attrs = TokenStream::new();
if let PropertyType::Descriptor { field, .. } = &property_type {
Expand Down Expand Up @@ -978,13 +978,17 @@ impl PropertyType<'_> {
}
}

fn doc(&self, ctx: &Ctx) -> Cow<'_, PythonDoc> {
match self {
fn doc(&self, ctx: &Ctx) -> Result<Cow<'_, PythonDoc>> {
let doc = match self {
PropertyType::Descriptor { field, .. } => {
Cow::Owned(utils::get_doc(&field.attrs, None, ctx))
// FIXME: due to the clone this will not properly strip Rust documentation, maybe
// need to parse the field and doc earlier in the process?
let mut attrs = field.attrs.clone();
Cow::Owned(utils::get_doc(&mut attrs, None, ctx)?)
}
PropertyType::Function { doc, .. } => Cow::Borrowed(doc),
}
};
Ok(doc)
}
}

Expand Down
Loading
Loading