From a7a53d6c0d191cead307604e407120149a082041 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 20 Nov 2022 14:58:41 +0100 Subject: [PATCH] Add a nox task to rustfmt code in the guide. Also apply it. Two caveats: 1) needs nightly rustfmt to be available 2) not all reformat diffs have been applied; using best judgment for readability. --- guide/pyclass_parameters.md | 4 +- guide/src/building_and_distribution.md | 2 +- .../multiple_python_versions.md | 13 ++-- guide/src/class.md | 21 ++++--- guide/src/class/numeric.md | 1 - guide/src/class/object.md | 14 ++--- guide/src/class/protocols.md | 4 +- guide/src/conversions/traits.md | 59 +++++++++---------- guide/src/ecosystem/async-await.md | 1 - guide/src/exception.md | 8 ++- guide/src/faq.md | 4 +- guide/src/features.md | 4 +- guide/src/function.md | 8 +-- guide/src/function/error_handling.md | 4 +- guide/src/function/signature.md | 9 +-- guide/src/migration.md | 36 +++++------ guide/src/parallelism.md | 4 +- guide/src/python_from_rust.md | 27 ++++++--- guide/src/rust_cpython.md | 2 +- guide/src/trait_bounds.md | 22 ++++--- guide/src/types.md | 6 +- noxfile.py | 53 +++++++++++++++++ 22 files changed, 183 insertions(+), 123 deletions(-) diff --git a/guide/pyclass_parameters.md b/guide/pyclass_parameters.md index 7826960e..8a88c4de 100644 --- a/guide/pyclass_parameters.md +++ b/guide/pyclass_parameters.md @@ -24,12 +24,12 @@ more accompanying `#[pyo3(...)]` annotations, e.g.: ```rust,ignore // Argument supplied directly to the `#[pyclass]` annotation. #[pyclass(name = "SomeName", subclass)] -struct MyClass { } +struct MyClass {} // Argument supplied as a separate annotation. #[pyclass] #[pyo3(name = "SomeName", subclass)] -struct MyClass { } +struct MyClass {} ``` [params-1]: https://docs.rs/pyo3/latest/pyo3/struct.PyAny.html diff --git a/guide/src/building_and_distribution.md b/guide/src/building_and_distribution.md index b708dcf3..95d3ffbc 100644 --- a/guide/src/building_and_distribution.md +++ b/guide/src/building_and_distribution.md @@ -115,7 +115,7 @@ The easiest way to set the correct linker arguments is to add a [`build.rs`](htt ```rust,ignore fn main() { - pyo3_build_config::add_extension_module_link_args(); + pyo3_build_config::add_extension_module_link_args(); } ``` diff --git a/guide/src/building_and_distribution/multiple_python_versions.md b/guide/src/building_and_distribution/multiple_python_versions.md index bb464ced..43203686 100644 --- a/guide/src/building_and_distribution/multiple_python_versions.md +++ b/guide/src/building_and_distribution/multiple_python_versions.md @@ -14,13 +14,13 @@ This allows us to write code like the following ```rust,ignore #[cfg(Py_3_7)] -fn function_only_supported_on_python_3_7_and_up() { } +fn function_only_supported_on_python_3_7_and_up() {} #[cfg(not(Py_3_8))] -fn function_only_supported_before_python_3_8() { } +fn function_only_supported_before_python_3_8() {} #[cfg(not(Py_LIMITED_API))] -fn function_incompatible_with_abi3_feature() { } +fn function_incompatible_with_abi3_feature() {} ``` The following sections first show how to add these `#[cfg]` flags to your build process, and then cover some common patterns flags in a little more detail. @@ -98,11 +98,10 @@ PyO3 provides the APIs [`Python::version()`] and [`Python::version_info()`] to q use pyo3::Python; Python::with_gil(|py| { - // PyO3 supports Python 3.7 and up. - assert!(py.version_info() >= (3, 7)); - assert!(py.version_info() >= (3, 7, 0)); + // PyO3 supports Python 3.7 and up. + assert!(py.version_info() >= (3, 7)); + assert!(py.version_info() >= (3, 7, 0)); }); - ``` [`Python::version()`]: {{#PYO3_DOCS_URL}}/pyo3/struct.Python.html#method.version diff --git a/guide/src/class.md b/guide/src/class.md index 1a19ceb9..4be1899c 100644 --- a/guide/src/class.md +++ b/guide/src/class.md @@ -26,8 +26,8 @@ To define a custom Python class, add the `#[pyclass]` attribute to a Rust struct use pyo3::prelude::*; #[pyclass] -struct Integer{ - inner: i32 +struct Integer { + inner: i32, } // A "tuple" struct @@ -166,7 +166,7 @@ struct MyClass { num: i32, } Python::with_gil(|py| { - let obj = PyCell::new(py, MyClass { num: 3}).unwrap(); + let obj = PyCell::new(py, MyClass { num: 3 }).unwrap(); { let obj_ref = obj.borrow(); // Get PyRef assert_eq!(obj_ref.num, 3); @@ -204,7 +204,7 @@ fn return_myclass() -> Py { let obj = return_myclass(); -Python::with_gil(|py|{ +Python::with_gil(|py| { let cell = obj.as_ref(py); // Py::as_ref returns &PyCell let obj_ref = cell.borrow(); // Get PyRef assert_eq!(obj_ref.num, 1); @@ -279,7 +279,7 @@ impl SubClass { } fn method2(self_: PyRef<'_, Self>) -> PyResult { - let super_ = self_.as_ref(); // Get &BaseClass + let super_ = self_.as_ref(); // Get &BaseClass super_.method().map(|x| x * self_.val2) } } @@ -293,13 +293,12 @@ struct SubSubClass { impl SubSubClass { #[new] fn new() -> PyClassInitializer { - PyClassInitializer::from(SubClass::new()) - .add_subclass(SubSubClass{val3: 20}) + PyClassInitializer::from(SubClass::new()).add_subclass(SubSubClass { val3: 20 }) } fn method3(self_: PyRef<'_, Self>) -> PyResult { let v = self_.val3; - let super_ = self_.into_super(); // Get PyRef<'_, SubClass> + let super_ = self_.into_super(); // Get PyRef<'_, SubClass> SubClass::method2(super_).map(|x| x * v) } } @@ -426,7 +425,7 @@ For simple cases where a member variable is just read and written with no side e #[pyclass] struct MyClass { #[pyo3(get, set)] - num: i32 + num: i32, } ``` @@ -937,7 +936,7 @@ You may not use enums as a base class or let enums inherit from other classes. ```rust,compile_fail # use pyo3::prelude::*; #[pyclass(subclass)] -enum BadBase{ +enum BadBase { Var1, } ``` @@ -949,7 +948,7 @@ enum BadBase{ struct Base; #[pyclass(extends=Base)] -enum BadSubclass{ +enum BadSubclass { Var1, } ``` diff --git a/guide/src/class/numeric.md b/guide/src/class/numeric.md index df3c908f..4e36e69c 100644 --- a/guide/src/class/numeric.md +++ b/guide/src/class/numeric.md @@ -395,7 +395,6 @@ fn my_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> { # Ok(()) # }) # } - ``` ## Appendix: Writing some unsafe code diff --git a/guide/src/class/object.md b/guide/src/class/object.md index d5afe5fd..357fdcd7 100644 --- a/guide/src/class/object.md +++ b/guide/src/class/object.md @@ -40,10 +40,10 @@ print(n) ### String representations It can't even print an user-readable representation of itself! We can fix that by defining the - `__repr__` and `__str__` methods inside a `#[pymethods]` block. We do this by accessing the value - contained inside `Number`. +`__repr__` and `__str__` methods inside a `#[pymethods]` block. We do this by accessing the value +contained inside `Number`. - ```rust +```rust # use pyo3::prelude::*; # # #[pyclass] @@ -114,13 +114,13 @@ impl Number { > ```rust > # use pyo3::prelude::*; > #[pyclass] -> struct NotHashable { } +> struct NotHashable {} > > #[pymethods] > impl NotHashable { -> #[classattr] -> const __hash__: Option> = None; ->} +> #[classattr] +> const __hash__: Option> = None; +> } > ``` ### Comparisons diff --git a/guide/src/class/protocols.md b/guide/src/class/protocols.md index 7fbd0aac..dff7a56d 100644 --- a/guide/src/class/protocols.md +++ b/guide/src/class/protocols.md @@ -48,7 +48,7 @@ given signatures should be interpreted as follows: # use pyo3::prelude::*; # #[pyclass] - struct NotHashable { } + struct NotHashable {} #[pymethods] impl NotHashable { @@ -229,7 +229,7 @@ Use the `#[pyclass(sequence)]` annotation to instruct PyO3 to fill the `sq_lengt # use pyo3::prelude::*; # #[pyclass] - struct NoContains { } + struct NoContains {} #[pymethods] impl NoContains { diff --git a/guide/src/conversions/traits.md b/guide/src/conversions/traits.md index fbfd8e79..6790767c 100644 --- a/guide/src/conversions/traits.md +++ b/guide/src/conversions/traits.md @@ -62,7 +62,7 @@ struct RustyStruct { # "", # "", # )?; -# +# # let class = module.getattr("Foo")?; # let instance = class.call0()?; # let rustystruct: RustyStruct = instance.extract()?; @@ -77,7 +77,6 @@ By setting the `#[pyo3(item)]` attribute on the field, PyO3 will attempt to extr ```rust use pyo3::prelude::*; - #[derive(FromPyObject)] struct RustyStruct { #[pyo3(item)] @@ -89,7 +88,7 @@ struct RustyStruct { # Python::with_gil(|py| -> PyResult<()> { # let dict = PyDict::new(py); # dict.set_item("my_string", "test")?; -# +# # let rustystruct: RustyStruct = dict.extract()?; # assert_eq!(rustystruct.my_string, "test"); # Ok(()) @@ -109,7 +108,7 @@ struct RustyStruct { #[pyo3(attribute("name"))] string_attr: String, } -# +# # fn main() -> PyResult<()> { # Python::with_gil(|py| -> PyResult<()> { # let module = PyModule::from_code( @@ -121,13 +120,13 @@ struct RustyStruct { # "", # "", # )?; -# +# # let class = module.getattr("Foo")?; # let instance = class.call0()?; # let rustystruct: RustyStruct = instance.extract()?; # assert_eq!(rustystruct.string_attr, "test"); # assert_eq!(rustystruct.string_in_mapping, "test2"); -# +# # Ok(()) # }) # } @@ -154,11 +153,11 @@ struct RustyTuple(String, String); # fn main() -> PyResult<()> { # Python::with_gil(|py| -> PyResult<()> { # let tuple = PyTuple::new(py, vec!["test", "test2"]); -# +# # let rustytuple: RustyTuple = tuple.extract()?; # assert_eq!(rustytuple.0, "test"); # assert_eq!(rustytuple.1, "test2"); -# +# # Ok(()) # }) # } @@ -177,10 +176,10 @@ struct RustyTuple((String,)); # fn main() -> PyResult<()> { # Python::with_gil(|py| -> PyResult<()> { # let tuple = PyTuple::new(py, vec!["test"]); -# +# # let rustytuple: RustyTuple = tuple.extract()?; # assert_eq!((rustytuple.0).0, "test"); -# +# # Ok(()) # }) # } @@ -209,13 +208,13 @@ struct RustyTransparentStruct { # fn main() -> PyResult<()> { # Python::with_gil(|py| -> PyResult<()> { # let s = PyString::new(py, "test"); -# +# # let tup: RustyTransparentTupleStruct = s.extract()?; # assert_eq!(tup.0, "test"); -# +# # let stru: RustyTransparentStruct = s.extract()?; # assert_eq!(stru.inner, "test"); -# +# # Ok(()) # }) # } @@ -256,14 +255,14 @@ enum RustyEnum<'a> { #[pyo3(transparent)] CatchAll(&'a PyAny), // This extraction never fails } -# +# # use pyo3::types::{PyBytes, PyString}; # fn main() -> PyResult<()> { # Python::with_gil(|py| -> PyResult<()> { # { # let thing = 42_u8.to_object(py); # let rust_thing: RustyEnum<'_> = thing.extract(py)?; -# +# # assert_eq!( # 42, # match rust_thing { @@ -275,7 +274,7 @@ enum RustyEnum<'a> { # { # let thing = PyString::new(py, "text"); # let rust_thing: RustyEnum<'_> = thing.extract()?; -# +# # assert_eq!( # "text", # match rust_thing { @@ -287,7 +286,7 @@ enum RustyEnum<'a> { # { # let thing = (32_u8, 73_u8).to_object(py); # let rust_thing: RustyEnum<'_> = thing.extract(py)?; -# +# # assert_eq!( # (32, 73), # match rust_thing { @@ -299,7 +298,7 @@ enum RustyEnum<'a> { # { # let thing = ("foo", 73_u8).to_object(py); # let rust_thing: RustyEnum<'_> = thing.extract(py)?; -# +# # assert_eq!( # (String::from("foo"), 73), # match rust_thing { @@ -319,11 +318,11 @@ enum RustyEnum<'a> { # "", # "", # )?; -# +# # let class = module.getattr("Foo")?; # let instance = class.call0()?; # let rust_thing: RustyEnum<'_> = instance.extract()?; -# +# # assert_eq!( # (0, 1, 2), # match rust_thing { @@ -332,7 +331,7 @@ enum RustyEnum<'a> { # } # ); # } -# +# # { # let module = PyModule::from_code( # py, @@ -343,11 +342,11 @@ enum RustyEnum<'a> { # "", # "", # )?; -# +# # let class = module.getattr("Foo")?; # let instance = class.call0()?; # let rust_thing: RustyEnum<'_> = instance.extract()?; -# +# # assert_eq!( # (3, 4), # match rust_thing { @@ -356,11 +355,11 @@ enum RustyEnum<'a> { # } # ); # } -# +# # { # let thing = PyBytes::new(py, b"text"); # let rust_thing: RustyEnum<'_> = thing.extract()?; -# +# # assert_eq!( # b"text", # match rust_thing { @@ -396,7 +395,7 @@ enum RustyEnum { # { # let thing = 42_u8.to_object(py); # let rust_thing: RustyEnum = thing.extract(py)?; -# +# # assert_eq!( # 42, # match rust_thing { @@ -405,11 +404,11 @@ enum RustyEnum { # } # ); # } -# +# # { # let thing = "foo".to_object(py); # let rust_thing: RustyEnum = thing.extract(py)?; -# +# # assert_eq!( # "foo", # match rust_thing { @@ -418,13 +417,13 @@ enum RustyEnum { # } # ); # } -# +# # { # let thing = b"foo".to_object(py); # let error = thing.extract::(py).unwrap_err(); # assert!(error.is_instance_of::(py)); # } -# +# # Ok(()) # }) # } diff --git a/guide/src/ecosystem/async-await.md b/guide/src/ecosystem/async-await.md index 51d209f1..719f7dbe 100644 --- a/guide/src/ecosystem/async-await.md +++ b/guide/src/ecosystem/async-await.md @@ -131,7 +131,6 @@ fn my_async_module(py: Python<'_>, m: &PyModule) -> PyResult<()> { Ok(()) } - ``` If you want to use `tokio` instead, here's what your module should look like: diff --git a/guide/src/exception.md b/guide/src/exception.md index 385be998..7f747304 100644 --- a/guide/src/exception.md +++ b/guide/src/exception.md @@ -25,7 +25,11 @@ create_exception!(mymodule, CustomError, PyException); Python::with_gil(|py| { let ctx = [("CustomError", py.get_type::())].into_py_dict(py); - pyo3::py_run!(py, *ctx, "assert str(CustomError) == \"\""); + pyo3::py_run!( + py, + *ctx, + "assert str(CustomError) == \"\"" + ); pyo3::py_run!(py, *ctx, "assert CustomError('oops').args == ('oops',)"); }); ``` @@ -47,7 +51,6 @@ fn mymodule(py: Python<'_>, m: &PyModule) -> PyResult<()> { Ok(()) } - ``` ## Raising an exception @@ -115,7 +118,6 @@ fn tell(file: &PyAny) -> PyResult { Ok(x) => x.extract::(), } } - ``` [`pyo3::exceptions`]({{#PYO3_DOCS_URL}}/pyo3/exceptions/index.html) diff --git a/guide/src/faq.md b/guide/src/faq.md index 1389f131..b2f89051 100644 --- a/guide/src/faq.md +++ b/guide/src/faq.md @@ -86,7 +86,7 @@ You may have a nested struct similar to this: # use pyo3::prelude::*; #[pyclass] #[derive(Clone)] -struct Inner { /* fields omitted */ } +struct Inner {/* fields omitted */} #[pyclass] struct Outer { @@ -126,7 +126,7 @@ If you don't want that cloning to happen, a workaround is to allocate the field # use pyo3::prelude::*; #[pyclass] #[derive(Clone)] -struct Inner { /* fields omitted */ } +struct Inner {/* fields omitted */} #[pyclass] struct Outer { diff --git a/guide/src/features.md b/guide/src/features.md index 57066429..a60fc09b 100644 --- a/guide/src/features.md +++ b/guide/src/features.md @@ -138,14 +138,14 @@ This allows to use [`#[derive(Serialize, Deserialize)`](https://serde.rs/derive. #[pyclass] #[derive(Serialize, Deserialize)] struct Permission { - name: String + name: String, } #[pyclass] #[derive(Serialize, Deserialize)] struct User { username: String, - permissions: Vec> + permissions: Vec>, } # } ``` diff --git a/guide/src/function.md b/guide/src/function.md index 1821b93d..b0d6c0b0 100644 --- a/guide/src/function.md +++ b/guide/src/function.md @@ -50,7 +50,9 @@ The `#[pyo3]` attribute can be used to modify properties of the generated Python #[pyfunction] #[pyo3(name = "no_args")] - fn no_args_py() -> usize { 42 } + fn no_args_py() -> usize { + 42 + } #[pymodule] fn module_with_functions(py: Python<'_>, m: &PyModule) -> PyResult<()> { @@ -185,8 +187,6 @@ fn add(a: u64, b: u64) -> u64 { /// sub(a, b, /) /// -- -/// -/// #[pyfunction] fn sub(a: u64, b: u64) -> u64 { a - b @@ -255,7 +255,6 @@ use pyo3::prelude::*; #[pymodule] fn my_extension(py: Python<'_>, m: &PyModule) -> PyResult<()> { - #[pyfn(m)] fn double(x: usize) -> usize { x * 2 @@ -273,7 +272,6 @@ use pyo3::prelude::*; #[pymodule] fn my_extension(py: Python<'_>, m: &PyModule) -> PyResult<()> { - #[pyfunction] fn double(x: usize) -> usize { x * 2 diff --git a/guide/src/function/error_handling.md b/guide/src/function/error_handling.md index 9b76b850..899cde6b 100644 --- a/guide/src/function/error_handling.md +++ b/guide/src/function/error_handling.md @@ -112,10 +112,10 @@ impl std::convert::From for PyErr { } } -pub struct Connection { /* ... */} +pub struct Connection {/* ... */} fn bind(addr: String) -> Result { - if &addr == "0.0.0.0"{ + if &addr == "0.0.0.0" { Err(CustomIOError) } else { Ok(Connection{ /* ... */}) diff --git a/guide/src/function/signature.md b/guide/src/function/signature.md index 4275a856..b5f9c418 100644 --- a/guide/src/function/signature.md +++ b/guide/src/function/signature.md @@ -120,7 +120,7 @@ Below are the same examples as above which using the deprecated syntax: use pyo3::prelude::*; use pyo3::types::PyDict; -#[pyfunction(kwds="**")] +#[pyfunction(kwds = "**")] fn num_kwds(kwds: Option<&PyDict>) -> usize { kwds.map_or(0, |dict| dict.len()) } @@ -166,12 +166,7 @@ impl MyClass { MyClass { num } } - #[args( - num = "10", - py_args = "*", - name = "\"Hello\"", - py_kwargs = "**" - )] + #[args(num = "10", py_args = "*", name = "\"Hello\"", py_kwargs = "**")] fn method( &mut self, num: i32, diff --git a/guide/src/migration.md b/guide/src/migration.md index 84e11841..5691e436 100644 --- a/guide/src/migration.md +++ b/guide/src/migration.md @@ -44,7 +44,6 @@ impl Mapping { // ... // truncated implementation of this mapping pyclass - basically a wrapper around a HashMap } - ``` You must register the class with `collections.abc.Mapping` before the downcast will work: @@ -155,7 +154,7 @@ use pyo3::class::{PyBasicProtocol, PyIterProtocol}; use pyo3::types::PyString; #[pyclass] -struct MyClass { } +struct MyClass {} #[pyproto] impl PyBasicProtocol for MyClass { @@ -179,7 +178,7 @@ use pyo3::prelude::*; use pyo3::types::PyString; #[pyclass] -struct MyClass { } +struct MyClass {} #[pymethods] impl MyClass { @@ -343,7 +342,7 @@ use pyo3::prelude::*; use pyo3::class::basic::PyBasicProtocol; #[pyclass] -struct MyClass { } +struct MyClass {} #[pyproto] impl PyBasicProtocol for MyClass { @@ -359,7 +358,7 @@ After: use pyo3::prelude::*; #[pyclass] -struct MyClass { } +struct MyClass {} #[pymethods] impl MyClass { @@ -457,7 +456,10 @@ assert_eq!(err.to_string(), "TypeError: error message"); // Now possible to interact with exception instances, new for PyO3 0.12 let instance: &PyBaseException = err.instance(py); -assert_eq!(instance.getattr("__class__")?, PyTypeError::type_object(py).as_ref()); +assert_eq!( + instance.getattr("__class__")?, + PyTypeError::type_object(py).as_ref() +); # Ok(()) # }).unwrap(); ``` @@ -568,7 +570,7 @@ There can be two fixes: #[pyclass] struct NotThreadSafe { shared_bools: Rc>>, - closure: Box + closure: Box, } ``` @@ -581,7 +583,7 @@ There can be two fixes: #[pyclass] struct ThreadSafe { shared_bools: Arc>>, - closure: Box + closure: Box, } ``` @@ -679,10 +681,10 @@ struct MyClass {} #[pymethods] impl MyClass { - #[new] - fn new(obj: &PyRawObject) { - obj.init(MyClass { }) - } + #[new] + fn new(obj: &PyRawObject) { + obj.init(MyClass {}) + } } ``` @@ -694,10 +696,10 @@ struct MyClass {} #[pymethods] impl MyClass { - #[new] - fn new() -> Self { - MyClass {} - } + #[new] + fn new() -> Self { + MyClass {} + } } ``` @@ -720,7 +722,7 @@ Here is an example. #[pyclass] struct Names { - names: Vec + names: Vec, } #[pymethods] diff --git a/guide/src/parallelism.md b/guide/src/parallelism.md index 2fd9e066..195106b2 100644 --- a/guide/src/parallelism.md +++ b/guide/src/parallelism.md @@ -43,7 +43,7 @@ But let's assume you have a long running Rust function which you would like to e # } # total # } -# +# fn search_sequential(contents: &str, needle: &str) -> usize { contents.lines().map(|line| count_line(line, needle)).sum() } @@ -63,7 +63,7 @@ To enable parallel execution of this function, the [`Python::allow_threads`] met # } # total # } -# +# # fn search_sequential(contents: &str, needle: &str) -> usize { # contents.lines().map(|line| count_line(line, needle)).sum() # } diff --git a/guide/src/python_from_rust.md b/guide/src/python_from_rust.md index 6cccdac4..ffe4e31c 100644 --- a/guide/src/python_from_rust.md +++ b/guide/src/python_from_rust.md @@ -43,7 +43,9 @@ fn main() -> PyResult<()> { print('called with no arguments')", "", "", - )?.getattr("example")?.into(); + )? + .getattr("example")? + .into(); // call object without any arguments fun.call0(py)?; @@ -87,8 +89,9 @@ fn main() -> PyResult<()> { print('called with no arguments')", "", "", - )?.getattr("example")?.into(); - + )? + .getattr("example")? + .into(); // call object with PyDict let kwargs = [(key1, val1)].into_py_dict(py); @@ -104,7 +107,7 @@ fn main() -> PyResult<()> { fun.call(py, (), Some(kwargs.into_py_dict(py)))?; Ok(()) - }) + }) } ``` @@ -124,7 +127,10 @@ use pyo3::prelude::*; fn main() -> PyResult<()> { Python::with_gil(|py| { let builtins = PyModule::import(py, "builtins")?; - let total: i32 = builtins.getattr("sum")?.call1((vec![1, 2, 3],))?.extract()?; + let total: i32 = builtins + .getattr("sum")? + .call1((vec![1, 2, 3],))? + .extract()?; assert_eq!(total, 6); Ok(()) }) @@ -142,9 +148,11 @@ use pyo3::prelude::*; # fn main() -> Result<(), ()> { Python::with_gil(|py| { - let result = py.eval("[i * 10 for i in range(5)]", None, None).map_err(|e| { - e.print_and_set_sys_last_vars(py); - })?; + let result = py + .eval("[i * 10 for i in range(5)]", None, None) + .map_err(|e| { + e.print_and_set_sys_last_vars(py); + })?; let res: Vec = result.extract().unwrap(); assert_eq!(res, vec![0, 10, 20, 30, 40]); Ok(()) @@ -228,7 +236,8 @@ def leaky_relu(x, slope=0.01): let kwargs = [("slope", 0.2)].into_py_dict(py); let lrelu_result: f64 = activators - .getattr("leaky_relu")?.call((-1.0,), Some(kwargs))? + .getattr("leaky_relu")? + .call((-1.0,), Some(kwargs))? .extract()?; assert_eq!(lrelu_result, -0.2); # Ok(()) diff --git a/guide/src/rust_cpython.md b/guide/src/rust_cpython.md index fd3a878b..c8a5cefc 100644 --- a/guide/src/rust_cpython.md +++ b/guide/src/rust_cpython.md @@ -27,7 +27,7 @@ use pyo3::prelude::*; #[pyclass] struct MyClass { - num: u32, + num: u32, } #[pymethods] diff --git a/guide/src/trait_bounds.md b/guide/src/trait_bounds.md index f08749e0..9c39b70a 100644 --- a/guide/src/trait_bounds.md +++ b/guide/src/trait_bounds.md @@ -25,13 +25,13 @@ The argument of the function can be any model that implements the `Model` trait ```rust # #![allow(dead_code)] pub trait Model { - fn set_variables(&mut self, inputs: &Vec); - fn compute(&mut self); - fn get_results(&self) -> Vec; + fn set_variables(&mut self, inputs: &Vec); + fn compute(&mut self); + fn get_results(&self) -> Vec; } pub fn solve(model: &mut T) { - println!("Magic solver that mutates the model into a resolved state"); + println!("Magic solver that mutates the model into a resolved state"); } ``` Let's assume we have the following constraints: @@ -152,7 +152,7 @@ Now we add the PyO3 annotations to the trait implementation: ```rust,ignore #[pymethods] impl Model for UserModel { - // the previous trait implementation + // the previous trait implementation } ``` @@ -411,7 +411,10 @@ impl Model for UserModel { .unwrap(); if py_result.get_type().name().unwrap() != "list" { - panic!("Expected a list for the get_results() method signature, got {}", py_result.get_type().name().unwrap()); + panic!( + "Expected a list for the get_results() method signature, got {}", + py_result.get_type().name().unwrap() + ); } py_result.extract() }) @@ -472,7 +475,7 @@ pub trait Model { } pub fn solve(model: &mut T) { - println!("Magic solver that mutates the model into a resolved state"); + println!("Magic solver that mutates the model into a resolved state"); } #[pyfunction] @@ -538,7 +541,10 @@ impl Model for UserModel { .unwrap(); if py_result.get_type().name().unwrap() != "list" { - panic!("Expected a list for the get_results() method signature, got {}", py_result.get_type().name().unwrap()); + panic!( + "Expected a list for the get_results() method signature, got {}", + py_result.get_type().name().unwrap() + ); } py_result.extract() }) diff --git a/guide/src/types.md b/guide/src/types.md index f75ac554..c7fc11d0 100644 --- a/guide/src/types.md +++ b/guide/src/types.md @@ -89,7 +89,7 @@ For a `&PyAny` object reference `any` where the underlying object is a `#[pyclas # use pyo3::{Py, Python, PyAny, PyResult}; # #[pyclass] #[derive(Clone)] struct MyClass { } # Python::with_gil(|py| -> PyResult<()> { -let obj: &PyAny = Py::new(py, MyClass { })?.into_ref(py); +let obj: &PyAny = Py::new(py, MyClass {})?.into_ref(py); // To &PyCell with PyAny::downcast let _: &PyCell = obj.downcast()?; @@ -238,7 +238,7 @@ so it also exposes all of the methods on `PyAny`. # use pyo3::prelude::*; # #[pyclass] struct MyClass { } # Python::with_gil(|py| -> PyResult<()> { -let cell: &PyCell = PyCell::new(py, MyClass { })?; +let cell: &PyCell = PyCell::new(py, MyClass {})?; // To PyRef with .borrow() or .try_borrow() let py_ref: PyRef<'_, MyClass> = cell.try_borrow()?; @@ -258,7 +258,7 @@ let _: &mut MyClass = &mut *py_ref_mut; # use pyo3::prelude::*; # #[pyclass] struct MyClass { } # Python::with_gil(|py| -> PyResult<()> { -let cell: &PyCell = PyCell::new(py, MyClass { })?; +let cell: &PyCell = PyCell::new(py, MyClass {})?; // Use methods from PyAny on PyCell with Deref implementation let _ = cell.repr()?; diff --git a/noxfile.py b/noxfile.py index ae26becd..c3ecf8d5 100644 --- a/noxfile.py +++ b/noxfile.py @@ -2,6 +2,7 @@ import os import re import subprocess import sys +import tempfile import time from glob import glob from pathlib import Path @@ -231,6 +232,58 @@ def build_guide(session: nox.Session): _run(session, "mdbook", "build", "-d", "../target/guide", "guide", *session.posargs) +@nox.session(name="format-guide", venv_backend="none") +def format_guide(session: nox.Session): + fence_line = "//! ```\n" + + for path in Path("guide").glob("**/*.md"): + session.log("Working on %s", path) + content = path.read_text() + + lines = iter(path.read_text().splitlines(True)) + new_lines = [] + + for line in lines: + new_lines.append(line) + if not re.search("```rust(,.*)?$", line): + continue + + # Found a code block fence, gobble up its lines and write to temp. file + prefix = line[: line.index("```")] + with tempfile.NamedTemporaryFile("w", delete=False) as file: + tempname = file.name + file.write(fence_line) + for line in lines: + if line == prefix + "```\n": + break + file.write(("//! " + line[len(prefix) :]).rstrip() + "\n") + file.write(fence_line) + + # Format it (needs nightly rustfmt for `format_code_in_doc_comments`) + _run( + session, + "rustfmt", + "+nightly", + "--config", + "format_code_in_doc_comments=true", + "--config", + "reorder_imports=false", + tempname, + ) + + # Re-read the formatted file, add its lines, and delete it + with open(tempname, "r") as file: + for line in file: + if line == fence_line: + continue + new_lines.append((prefix + line[4:]).rstrip() + "\n") + os.unlink(tempname) + + new_lines.append(prefix + "```\n") + + path.write_text("".join(new_lines)) + + @nox.session(name="address-sanitizer", venv_backend="none") def address_sanitizer(session: nox.Session): _run(