Skip to content

Commit 98d810e

Browse files
kngwyudavidhewitt
andcommitted
Apply suggestions from davidhewitt's review
Co-Authored-By: David Hewitt <[email protected]>
1 parent daca04e commit 98d810e

File tree

6 files changed

+25
-30
lines changed

6 files changed

+25
-30
lines changed

guide/src/class.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ from Rust code (e.g., for testing it).
116116
`PyCell<T: PyClass>` is always allocated in the Python heap, so we don't have the ownership of it.
117117
We can get `&PyCell<T>`, not `PyCell<T>`.
118118

119-
Thus, to mutate data behind `&PyCell` safely, we employs
119+
Thus, to mutate data behind `&PyCell` safely, we employ the
120120
[Interior Mutability Pattern](https://doc.rust-lang.org/book/ch15-05-interior-mutability.html)
121121
like [std::cell::RefCell](https://doc.rust-lang.org/std/cell/struct.RefCell.html).
122122

@@ -145,13 +145,13 @@ let obj = PyCell::new(py, MyClass { num: 3, debug: true }).unwrap();
145145
{
146146
let obj_ref = obj.borrow(); // Get PyRef
147147
assert_eq!(obj_ref.num, 3);
148-
// You cannot get PyRefMut unless all PyRef drop
148+
// You cannot get PyRefMut unless all PyRefs are dropped
149149
assert!(obj.try_borrow_mut().is_err());
150150
}
151151
{
152152
let mut obj_mut = obj.borrow_mut(); // Get PyRefMut
153153
obj_mut.num = 5;
154-
// You cannot get PyRef unless all PyRefMut drop
154+
// You cannot get any other refs until the PyRefMut is dropped
155155
assert!(obj.try_borrow().is_err());
156156
}
157157
// You can convert `&PyCell` to Python object

pyo3-derive-backend/src/module.rs

+13-20
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@ pub fn py_init(fnname: &Ident, name: &Ident, doc: syn::LitStr) -> TokenStream {
2828
}
2929

3030
/// Finds and takes care of the #[pyfn(...)] in `#[pymodule]`
31-
pub fn process_functions_in_module(func: &mut syn::ItemFn) {
31+
pub fn process_functions_in_module(func: &mut syn::ItemFn) -> syn::Result<()> {
3232
let mut stmts: Vec<syn::Stmt> = Vec::new();
3333

3434
for stmt in func.block.stmts.iter_mut() {
3535
if let syn::Stmt::Item(syn::Item::Fn(ref mut func)) = stmt {
3636
if let Some((module_name, python_name, pyfn_attrs)) =
3737
extract_pyfn_attrs(&mut func.attrs)
3838
{
39-
let function_to_python = add_fn_to_module(func, python_name, pyfn_attrs);
39+
let function_to_python = add_fn_to_module(func, python_name, pyfn_attrs)?;
4040
let function_wrapper_ident = function_wrapper_ident(&func.sig.ident);
4141
let item: syn::ItemFn = syn::parse_quote! {
4242
fn block_wrapper() {
@@ -51,26 +51,27 @@ pub fn process_functions_in_module(func: &mut syn::ItemFn) {
5151
}
5252

5353
func.block.stmts = stmts;
54+
Ok(())
5455
}
5556

5657
/// Transforms a rust fn arg parsed with syn into a method::FnArg
57-
fn wrap_fn_argument<'a>(cap: &'a syn::PatType, name: &'a Ident) -> method::FnArg<'a> {
58+
fn wrap_fn_argument<'a>(cap: &'a syn::PatType, name: &'a Ident) -> syn::Result<method::FnArg<'a>> {
5859
let (mutability, by_ref, ident) = match *cap.pat {
5960
syn::Pat::Ident(ref patid) => (&patid.mutability, &patid.by_ref, &patid.ident),
60-
_ => panic!("unsupported argument: {:?}", cap.pat),
61+
_ => return Err(syn::Error::new_spanned(&cap.pat, "Unsupported argument")),
6162
};
6263

6364
let py = crate::utils::if_type_is_python(&cap.ty);
6465
let opt = method::check_arg_ty_and_optional(&name, &cap.ty);
65-
method::FnArg {
66+
Ok(method::FnArg {
6667
name: ident,
6768
mutability,
6869
by_ref,
6970
ty: &cap.ty,
7071
optional: opt,
7172
py,
7273
reference: method::is_ref(&name, &cap.ty),
73-
}
74+
})
7475
}
7576

7677
/// Extracts the data from the #[pyfn(...)] attribute of a function
@@ -131,7 +132,7 @@ pub fn add_fn_to_module(
131132
func: &mut syn::ItemFn,
132133
python_name: Ident,
133134
pyfn_attrs: Vec<pyfunction::Argument>,
134-
) -> TokenStream {
135+
) -> syn::Result<TokenStream> {
135136
let mut arguments = Vec::new();
136137
let mut self_ = None;
137138

@@ -141,21 +142,15 @@ pub fn add_fn_to_module(
141142
self_ = Some(recv.mutability.is_some());
142143
}
143144
syn::FnArg::Typed(ref cap) => {
144-
arguments.push(wrap_fn_argument(cap, &func.sig.ident));
145+
arguments.push(wrap_fn_argument(cap, &func.sig.ident)?);
145146
}
146147
}
147148
}
148149

149150
let ty = method::get_return_info(&func.sig.output);
150151

151-
let text_signature = match utils::parse_text_signature_attrs(&mut func.attrs, &python_name) {
152-
Ok(text_signature) => text_signature,
153-
Err(err) => return err.to_compile_error(),
154-
};
155-
let doc = match utils::get_doc(&func.attrs, text_signature, true) {
156-
Ok(doc) => doc,
157-
Err(err) => return err.to_compile_error(),
158-
};
152+
let text_signature = utils::parse_text_signature_attrs(&mut func.attrs, &python_name)?;
153+
let doc = utils::get_doc(&func.attrs, text_signature, true)?;
159154

160155
let function_wrapper_ident = function_wrapper_ident(&func.sig.ident);
161156

@@ -176,7 +171,7 @@ pub fn add_fn_to_module(
176171

177172
let wrapper = function_c_wrapper(&func.sig.ident, &spec);
178173

179-
let tokens = quote! {
174+
Ok(quote! {
180175
fn #function_wrapper_ident(py: pyo3::Python) -> pyo3::PyObject {
181176
#wrapper
182177

@@ -199,9 +194,7 @@ pub fn add_fn_to_module(
199194

200195
function
201196
}
202-
};
203-
204-
tokens
197+
})
205198
}
206199

207200
/// Generate static function wrapper (PyCFunction, PyCFunctionWithKeywords)

pyo3-derive-backend/src/pyfunction.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ pub fn parse_name_attribute(attrs: &mut Vec<syn::Attribute>) -> syn::Result<Opti
234234
pub fn build_py_function(ast: &mut syn::ItemFn, args: PyFunctionAttr) -> syn::Result<TokenStream> {
235235
let python_name =
236236
parse_name_attribute(&mut ast.attrs)?.unwrap_or_else(|| ast.sig.ident.unraw());
237-
Ok(add_fn_to_module(ast, python_name, args.arguments))
237+
add_fn_to_module(ast, python_name, args.arguments)
238238
}
239239

240240
#[cfg(test)]

pyo3cls/src/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ pub fn pymodule(attr: TokenStream, input: TokenStream) -> TokenStream {
2323
parse_macro_input!(attr as syn::Ident)
2424
};
2525

26-
process_functions_in_module(&mut ast);
26+
if let Err(err) = process_functions_in_module(&mut ast) {
27+
return err.to_compile_error().into();
28+
}
2729

2830
let doc = match get_doc(&ast.attrs, None, false) {
2931
Ok(doc) => doc,

src/derive_utils.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ impl GetPropertyValue for PyObject {
219219
}
220220
}
221221

222-
/// Utitlities for basetype
222+
/// Utilities for basetype
223223
pub trait PyBaseTypeUtils {
224224
type Dict;
225225
type WeakRef;

src/objectprotocol.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,10 @@ pub trait ObjectProtocol {
171171
fn get_type_ptr(&self) -> *mut ffi::PyTypeObject;
172172

173173
/// Gets the Python base object for this object.
174-
fn get_base<'py>(&'py self) -> &'py <Self as PyTypeInfo>::BaseType
174+
fn get_base(&self) -> &<Self as PyTypeInfo>::BaseType
175175
where
176176
Self: PyTypeInfo,
177-
<Self as PyTypeInfo>::BaseType: FromPyPointer<'py>;
177+
<Self as PyTypeInfo>::BaseType: for<'py> FromPyPointer<'py>;
178178

179179
/// Casts the PyObject to a concrete Python object type.
180180
fn cast_as<'a, D>(&'a self) -> Result<&'a D, PyDowncastError>
@@ -445,10 +445,10 @@ where
445445
unsafe { (*self.as_ptr()).ob_type }
446446
}
447447

448-
fn get_base<'py>(&'py self) -> &'py <Self as PyTypeInfo>::BaseType
448+
fn get_base(&self) -> &<Self as PyTypeInfo>::BaseType
449449
where
450450
Self: PyTypeInfo,
451-
<Self as PyTypeInfo>::BaseType: FromPyPointer<'py>,
451+
<Self as PyTypeInfo>::BaseType: for<'py> FromPyPointer<'py>,
452452
{
453453
unsafe { self.py().from_borrowed_ptr(self.as_ptr()) }
454454
}

0 commit comments

Comments
 (0)