Skip to content

Commit 6f75fc8

Browse files
committed
more macro hygiene cleanup: test #[pymethods] and more arg parsing and protos
1 parent a6d6367 commit 6f75fc8

File tree

9 files changed

+106
-47
lines changed

9 files changed

+106
-47
lines changed

pyo3-macros-backend/src/defs.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ impl SlotDef {
143143

144144
pub const OBJECT: Proto = Proto {
145145
name: "Object",
146-
module: "pyo3::class::basic",
146+
module: "::pyo3::class::basic",
147147
methods: &[
148148
MethodProto::new("__getattr__", "PyObjectGetAttrProtocol")
149149
.args(&["Name"])
@@ -189,7 +189,7 @@ pub const OBJECT: Proto = Proto {
189189

190190
pub const ASYNC: Proto = Proto {
191191
name: "Async",
192-
module: "pyo3::class::pyasync",
192+
module: "::pyo3::class::pyasync",
193193
methods: &[
194194
MethodProto::new("__await__", "PyAsyncAwaitProtocol").args(&["Receiver"]),
195195
MethodProto::new("__aiter__", "PyAsyncAiterProtocol").args(&["Receiver"]),
@@ -212,7 +212,7 @@ pub const ASYNC: Proto = Proto {
212212

213213
pub const BUFFER: Proto = Proto {
214214
name: "Buffer",
215-
module: "pyo3::class::buffer",
215+
module: "::pyo3::class::buffer",
216216
methods: &[
217217
MethodProto::new("bf_getbuffer", "PyBufferGetBufferProtocol").has_self(),
218218
MethodProto::new("bf_releasebuffer", "PyBufferReleaseBufferProtocol").has_self(),
@@ -230,7 +230,7 @@ pub const BUFFER: Proto = Proto {
230230

231231
pub const CONTEXT: Proto = Proto {
232232
name: "Context",
233-
module: "pyo3::class::context",
233+
module: "::pyo3::class::context",
234234
methods: &[
235235
MethodProto::new("__enter__", "PyContextEnterProtocol").has_self(),
236236
MethodProto::new("__exit__", "PyContextExitProtocol")
@@ -246,7 +246,7 @@ pub const CONTEXT: Proto = Proto {
246246

247247
pub const GC: Proto = Proto {
248248
name: "GC",
249-
module: "pyo3::class::gc",
249+
module: "::pyo3::class::gc",
250250
methods: &[
251251
MethodProto::new("__traverse__", "PyGCTraverseProtocol")
252252
.has_self()
@@ -264,7 +264,7 @@ pub const GC: Proto = Proto {
264264

265265
pub const DESCR: Proto = Proto {
266266
name: "Descr",
267-
module: "pyo3::class::descr",
267+
module: "::pyo3::class::descr",
268268
methods: &[
269269
MethodProto::new("__get__", "PyDescrGetProtocol").args(&["Receiver", "Inst", "Owner"]),
270270
MethodProto::new("__set__", "PyDescrSetProtocol").args(&["Receiver", "Inst", "Value"]),
@@ -287,7 +287,7 @@ pub const DESCR: Proto = Proto {
287287

288288
pub const ITER: Proto = Proto {
289289
name: "Iter",
290-
module: "pyo3::class::iter",
290+
module: "::pyo3::class::iter",
291291
py_methods: &[],
292292
methods: &[
293293
MethodProto::new("__iter__", "PyIterIterProtocol").args(&["Receiver"]),
@@ -301,7 +301,7 @@ pub const ITER: Proto = Proto {
301301

302302
pub const MAPPING: Proto = Proto {
303303
name: "Mapping",
304-
module: "pyo3::class::mapping",
304+
module: "::pyo3::class::mapping",
305305
methods: &[
306306
MethodProto::new("__len__", "PyMappingLenProtocol").has_self(),
307307
MethodProto::new("__getitem__", "PyMappingGetItemProtocol")
@@ -334,7 +334,7 @@ pub const MAPPING: Proto = Proto {
334334

335335
pub const SEQ: Proto = Proto {
336336
name: "Sequence",
337-
module: "pyo3::class::sequence",
337+
module: "::pyo3::class::sequence",
338338
methods: &[
339339
MethodProto::new("__len__", "PySequenceLenProtocol").has_self(),
340340
MethodProto::new("__getitem__", "PySequenceGetItemProtocol")
@@ -391,7 +391,7 @@ pub const SEQ: Proto = Proto {
391391

392392
pub const NUM: Proto = Proto {
393393
name: "Number",
394-
module: "pyo3::class::number",
394+
module: "::pyo3::class::number",
395395
methods: &[
396396
MethodProto::new("__add__", "PyNumberAddProtocol").args(&["Left", "Right"]),
397397
MethodProto::new("__sub__", "PyNumberSubProtocol").args(&["Left", "Right"]),

pyo3-macros-backend/src/deprecations.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ impl ToTokens for Deprecations {
3939
let ident = deprecation.ident(*span);
4040
quote_spanned!(
4141
*span =>
42-
let _ = pyo3::impl_::deprecations::#ident;
42+
let _ = ::pyo3::impl_::deprecations::#ident;
4343
)
4444
.to_tokens(tokens)
4545
}

pyo3-macros-backend/src/method.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -484,11 +484,10 @@ impl<'a> FnSpec<'a> {
484484
#deprecations
485485
::pyo3::callback::handle_panic(|#py| {
486486
#self_conversion
487-
use ::std::option::Option;
488-
let _kwnames: Option<&::pyo3::types::PyTuple> = #py.from_borrowed_ptr_or_opt(_kwnames);
487+
let _kwnames: ::std::option::Option<&::pyo3::types::PyTuple> = #py.from_borrowed_ptr_or_opt(_kwnames);
489488
// Safety: &PyAny has the same memory layout as `*mut ffi::PyObject`
490489
let _args = _args as *const &::pyo3::PyAny;
491-
let _kwargs = if let Option::Some(kwnames) = _kwnames {
490+
let _kwargs = if let ::std::option::Option::Some(kwnames) = _kwnames {
492491
::std::slice::from_raw_parts(_args.offset(_nargs), kwnames.len())
493492
} else {
494493
&[]
@@ -537,7 +536,7 @@ impl<'a> FnSpec<'a> {
537536
let result = #arg_convert_and_rust_call;
538537
let initializer: ::pyo3::PyClassInitializer::<#cls> = result.convert(#py)?;
539538
let cell = initializer.create_cell_from_subtype(#py, subtype)?;
540-
Ok(cell as *mut ::pyo3::ffi::PyObject)
539+
::std::result::Result::Ok(cell as *mut ::pyo3::ffi::PyObject)
541540
})
542541
}
543542
}

pyo3-macros-backend/src/params.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ pub fn impl_arg_params(
9191

9292
if kwonly {
9393
keyword_only_parameters.push(quote! {
94-
pyo3::derive_utils::KeywordOnlyParameterDescription {
94+
::pyo3::derive_utils::KeywordOnlyParameterDescription {
9595
name: #name,
9696
required: #required,
9797
}
@@ -123,7 +123,7 @@ pub fn impl_arg_params(
123123
let (accept_args, accept_kwargs) = accept_args_kwargs(&spec.attrs);
124124

125125
let cls_name = if let Some(cls) = self_ {
126-
quote! { ::std::option::Option::Some(<#cls as pyo3::type_object::PyTypeInfo>::NAME) }
126+
quote! { ::std::option::Option::Some(<#cls as ::pyo3::type_object::PyTypeInfo>::NAME) }
127127
} else {
128128
quote! { ::std::option::Option::None }
129129
};
@@ -236,12 +236,22 @@ fn impl_arg_param(
236236

237237
let arg_value_or_default = match (spec.default_value(name), arg.optional.is_some()) {
238238
(Some(default), true) if default.to_string() != "None" => {
239-
quote_arg_span! { #arg_value.map_or_else(|| Ok(Some(#default)), |_obj| #extract)? }
239+
quote_arg_span! {
240+
#arg_value.map_or_else(|| ::std::result::Result::Ok(::std::option::Option::Some(#default)),
241+
|_obj| #extract)?
242+
}
240243
}
241244
(Some(default), _) => {
242-
quote_arg_span! { #arg_value.map_or_else(|| Ok(#default), |_obj| #extract)? }
245+
quote_arg_span! {
246+
#arg_value.map_or_else(|| ::std::result::Result::Ok(#default), |_obj| #extract)?
247+
}
248+
}
249+
(None, true) => {
250+
quote_arg_span! {
251+
#arg_value.map_or(::std::result::Result::Ok(::std::option::Option::None),
252+
|_obj| #extract)?
253+
}
243254
}
244-
(None, true) => quote_arg_span! { #arg_value.map_or(Ok(None), |_obj| #extract)? },
245255
(None, false) => {
246256
quote_arg_span! {
247257
{
@@ -257,7 +267,7 @@ fn impl_arg_param(
257267
let (target_ty, borrow_tmp) = if arg.optional.is_some() {
258268
// Get Option<&T> from Option<PyRef<T>>
259269
(
260-
quote_arg_span! { Option<<#tref as pyo3::derive_utils::ExtractExt<'_>>::Target> },
270+
quote_arg_span! { ::std::option::Option<<#tref as ::pyo3::derive_utils::ExtractExt<'_>>::Target> },
261271
if mut_.is_some() {
262272
quote_arg_span! { _tmp.as_deref_mut() }
263273
} else {
@@ -267,7 +277,7 @@ fn impl_arg_param(
267277
} else {
268278
// Get &T from PyRef<T>
269279
(
270-
quote_arg_span! { <#tref as pyo3::derive_utils::ExtractExt<'_>>::Target },
280+
quote_arg_span! { <#tref as ::pyo3::derive_utils::ExtractExt<'_>>::Target },
271281
quote_arg_span! { &#mut_ *_tmp },
272282
)
273283
};

pyo3-macros-backend/src/proto_method.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ pub(crate) fn impl_method_proto(
9595
};
9696

9797
Ok(quote! {
98-
impl<'p> ::#module::#proto<'p> for #cls {
98+
impl<'p> #module::#proto<'p> for #cls {
9999
#(#impl_types)*
100100
#res_type_def
101101
}

pyo3-macros-backend/src/pyimpl.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,13 @@ fn gen_py_const(cls: &syn::Type, spec: &ConstSpec) -> TokenStream {
9494
let deprecations = &spec.attributes.deprecations;
9595
let python_name = &spec.null_terminated_python_name();
9696
quote! {
97-
pyo3::class::PyMethodDefType::ClassAttribute({
98-
pyo3::class::PyClassAttributeDef::new(
97+
::pyo3::class::PyMethodDefType::ClassAttribute({
98+
::pyo3::class::PyClassAttributeDef::new(
9999
#python_name,
100-
pyo3::class::methods::PyClassAttributeFactory({
101-
fn __wrap(py: pyo3::Python<'_>) -> pyo3::PyObject {
100+
::pyo3::class::methods::PyClassAttributeFactory({
101+
fn __wrap(py: ::pyo3::Python<'_>) -> ::pyo3::PyObject {
102102
#deprecations
103-
pyo3::IntoPy::into_py(#cls::#member, py)
103+
::pyo3::IntoPy::into_py(#cls::#member, py)
104104
}
105105
__wrap
106106
})
@@ -111,11 +111,11 @@ fn gen_py_const(cls: &syn::Type, spec: &ConstSpec) -> TokenStream {
111111

112112
fn impl_py_methods(ty: &syn::Type, methods: Vec<TokenStream>) -> TokenStream {
113113
quote! {
114-
impl pyo3::class::impl_::PyMethods<#ty>
115-
for pyo3::class::impl_::PyClassImplCollector<#ty>
114+
impl ::pyo3::class::impl_::PyMethods<#ty>
115+
for ::pyo3::class::impl_::PyClassImplCollector<#ty>
116116
{
117-
fn py_methods(self) -> &'static [pyo3::class::methods::PyMethodDefType] {
118-
static METHODS: &[pyo3::class::methods::PyMethodDefType] = &[#(#methods),*];
117+
fn py_methods(self) -> &'static [::pyo3::class::methods::PyMethodDefType] {
118+
static METHODS: &[::pyo3::class::methods::PyMethodDefType] = &[#(#methods),*];
119119
METHODS
120120
}
121121
}
@@ -128,10 +128,10 @@ fn submit_methods_inventory(ty: &syn::Type, methods: Vec<TokenStream>) -> TokenS
128128
}
129129

130130
quote! {
131-
pyo3::inventory::submit! {
132-
#![crate = pyo3] {
133-
type Inventory = <#ty as pyo3::class::impl_::HasMethodsInventory>::Methods;
134-
<Inventory as pyo3::class::impl_::PyMethodsInventory>::new(vec![#(#methods),*])
131+
::pyo3::inventory::submit! {
132+
#![crate = ::pyo3] {
133+
type Inventory = <#ty as ::pyo3::class::impl_::HasMethodsInventory>::Methods;
134+
<Inventory as ::pyo3::class::impl_::PyMethodsInventory>::new(::std::vec![#(#methods),*])
135135
}
136136
}
137137
}

pyo3-macros-backend/src/pymethod.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ pub fn gen_py_method(
3636
FnType::FnClass => GeneratedPyMethod::Method(impl_py_method_def(
3737
cls,
3838
&spec,
39-
Some(quote!(pyo3::ffi::METH_CLASS)),
39+
Some(quote!(::pyo3::ffi::METH_CLASS)),
4040
)?),
4141
FnType::FnStatic => GeneratedPyMethod::Method(impl_py_method_def(
4242
cls,
4343
&spec,
44-
Some(quote!(pyo3::ffi::METH_STATIC)),
44+
Some(quote!(::pyo3::ffi::METH_STATIC)),
4545
)?),
4646
// special prototypes
4747
FnType::FnNew => GeneratedPyMethod::New(impl_py_method_def_new(cls, &spec)?),
@@ -111,8 +111,8 @@ fn impl_py_method_def_new(cls: &syn::Type, spec: &FnSpec) -> Result<TokenStream>
111111
let wrapper = spec.get_wrapper_function(&wrapper_ident, Some(cls))?;
112112
Ok(quote! {
113113
impl ::pyo3::class::impl_::PyClassNewImpl<#cls> for ::pyo3::class::impl_::PyClassImplCollector<#cls> {
114-
fn new_impl(self) -> Option<pyo3::ffi::newfunc> {
115-
Some({
114+
fn new_impl(self) -> ::std::option::Option<::pyo3::ffi::newfunc> {
115+
::std::option::Option::Some({
116116
#wrapper
117117
#wrapper_ident
118118
})
@@ -126,8 +126,8 @@ fn impl_py_method_def_call(cls: &syn::Type, spec: &FnSpec) -> Result<TokenStream
126126
let wrapper = spec.get_wrapper_function(&wrapper_ident, Some(cls))?;
127127
Ok(quote! {
128128
impl ::pyo3::class::impl_::PyClassCallImpl<#cls> for ::pyo3::class::impl_::PyClassImplCollector<#cls> {
129-
fn call_impl(self) -> Option<pyo3::ffi::PyCFunctionWithKeywords> {
130-
Some({
129+
fn call_impl(self) -> ::std::option::Option<::pyo3::ffi::PyCFunctionWithKeywords> {
130+
::std::option::Option::Some({
131131
#wrapper
132132
#wrapper_ident
133133
})

pyo3-macros-backend/src/pyproto.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,13 @@ fn impl_proto_methods(
144144
{
145145
fn buffer_procs(
146146
self
147-
) -> Option<&'static ::pyo3::class::impl_::PyBufferProcs> {
147+
) -> ::std::option::Option<&'static ::pyo3::class::impl_::PyBufferProcs> {
148148
static PROCS: ::pyo3::class::impl_::PyBufferProcs
149149
= ::pyo3::class::impl_::PyBufferProcs {
150-
bf_getbuffer: Some(pyo3::class::buffer::getbuffer::<#ty>),
151-
bf_releasebuffer: Some(pyo3::class::buffer::releasebuffer::<#ty>),
150+
bf_getbuffer: ::std::option::Option::Some(::pyo3::class::buffer::getbuffer::<#ty>),
151+
bf_releasebuffer: ::std::option::Option::Some(::pyo3::class::buffer::releasebuffer::<#ty>),
152152
};
153-
Some(&PROCS)
153+
::std::option::Option::Some(&PROCS)
154154
}
155155
}
156156
});
@@ -164,7 +164,7 @@ fn impl_proto_methods(
164164
quote! {{
165165
::pyo3::ffi::PyType_Slot {
166166
slot: ::pyo3::ffi::#slot,
167-
pfunc: ::#module::#slot_impl::<#ty> as _
167+
pfunc: #module::#slot_impl::<#ty> as _
168168
}
169169
}}
170170
})

tests/test_proc_macro_hygiene.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,43 @@ pub struct Bar {
2626
c: ::std::option::Option<::pyo3::Py<Foo2>>,
2727
}
2828

29+
#[::pyo3::proc_macro::pymethods]
30+
impl Bar {
31+
#[args(x = "1", "*", _z = "2")]
32+
fn test(&self, _y: &Bar, _z: i32) {}
33+
#[staticmethod]
34+
fn staticmethod() {}
35+
#[classmethod]
36+
fn clsmethod(_: &::pyo3::types::PyType) {}
37+
#[call]
38+
#[args(args = "*", kwds = "**")]
39+
fn __call__(
40+
&self,
41+
_args: &::pyo3::types::PyTuple,
42+
_kwds: ::std::option::Option<&::pyo3::types::PyDict>,
43+
) -> ::pyo3::PyResult<i32> {
44+
::std::unimplemented!()
45+
}
46+
#[new]
47+
fn new(a: u8) -> Self {
48+
Bar {
49+
a,
50+
b: Foo,
51+
c: ::std::option::Option::None,
52+
}
53+
}
54+
#[getter]
55+
fn get(&self) -> i32 {
56+
0
57+
}
58+
#[setter]
59+
fn set(&self, _v: i32) {}
60+
#[classattr]
61+
fn class_attr() -> i32 {
62+
0
63+
}
64+
}
65+
2966
#[::pyo3::proc_macro::pyproto]
3067
impl ::pyo3::class::gc::PyGCProtocol for Bar {
3168
fn __traverse__(
@@ -43,6 +80,19 @@ impl ::pyo3::class::gc::PyGCProtocol for Bar {
4380
}
4481
}
4582

83+
#[cfg(not(Py_LIMITED_API))]
84+
#[::pyo3::proc_macro::pyproto]
85+
impl ::pyo3::class::PyBufferProtocol for Bar {
86+
fn bf_getbuffer(
87+
_s: ::pyo3::PyRefMut<Self>,
88+
_v: *mut ::pyo3::ffi::Py_buffer,
89+
_f: ::std::os::raw::c_int,
90+
) -> ::pyo3::PyResult<()> {
91+
::std::unimplemented!()
92+
}
93+
fn bf_releasebuffer(_s: ::pyo3::PyRefMut<Self>, _v: *mut ::pyo3::ffi::Py_buffer) {}
94+
}
95+
4696
#[::pyo3::proc_macro::pyfunction]
4797
fn do_something(x: i32) -> ::pyo3::PyResult<i32> {
4898
::std::result::Result::Ok(x)

0 commit comments

Comments
 (0)