diff --git a/README.md b/README.md index eefd295d..17a1dfa8 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ rustflags = [ ] ``` -For developing, you can copy and rename the shared librar: On macOS, from `libstring_sum.dylib` to `string_sum.so`, on Windows `libstring_sum.dll` to `string_sum.pyd` and on linux from `libstring_sum.so` to `libstring_sum.so`. Then open a python shell in the same folder and you'll be to `import string_sum`. +For developing, you can copy and rename the shared library from the target folder: On mac os, rename `libstring_sum.dylib` to `string_sum.so`, on windows `libstring_sum.dll` to `string_sum.pyd` and on linux `libstring_sum.so` to `libstring_sum.so`. Then open a python shell in the same folder and you'll be able to `import string_sum`. To build, test and publish your crate as python module, you can use [pyo3-pack](https://github.com/PyO3/pyo3-pack) or [setuptools-rust](https://github.com/PyO3/setuptools-rust). You can find an example for setuptools-rust in [examples/word-count](examples/word-count), while pyo3-pack should work on your crate without any configuration. diff --git a/guide/src/class.md b/guide/src/class.md index 5e3fa88e..31e89203 100644 --- a/guide/src/class.md +++ b/guide/src/class.md @@ -19,7 +19,6 @@ struct MyClass { The above example generates implementations for `PyTypeInfo` and `PyTypeObject` for `MyClass`. -If the class has a `PyToken` attribute, implementations for `PyObjectWithToken`, `ToPyObject`, `IntoPyObject` and `ToPyPointer` are also generated. You can only get a `PyToken` instance through the `__new__` method. ## Customizing the class @@ -54,7 +53,6 @@ attribute. Only the python `__new__` method can be specified, `__init__` is not #[pyclass] struct MyClass { num: i32, - token: PyToken, } #[pymethods] @@ -62,10 +60,9 @@ impl MyClass { #[new] fn __new__(obj: &PyRawObject, num: i32) -> PyResult<()> { - obj.init(|token| { + obj.init(|_| { MyClass { num, - token } }) } @@ -151,7 +148,6 @@ attributes. i.e. # #[pyclass] # struct MyClass { # num: i32, -# token: PyToken, # } # #[pymethods] @@ -178,7 +174,6 @@ rust's special keywords like `type`. # #[pyclass] # struct MyClass { # num: i32, -# token: PyToken, # } # #[pymethods] @@ -209,7 +204,6 @@ If parameter is specified, it is used and property name. i.e. # #[pyclass] # struct MyClass { # num: i32, -# token: PyToken, # } # #[pymethods] @@ -259,7 +253,6 @@ class method static methods, etc. # #[pyclass] # struct MyClass { # num: i32, -# token: PyToken, # } # #[pymethods] @@ -290,7 +283,6 @@ get injected by method wrapper. i.e # struct MyClass { # num: i32, # debug: bool, -# token: PyToken, # } #[pymethods] @@ -316,7 +308,6 @@ with`#[classmethod]` attribute. # struct MyClass { # num: i32, # debug: bool, -# token: PyToken, # } #[pymethods] @@ -350,7 +341,6 @@ for some `T` that implements `IntoPyObject`. # struct MyClass { # num: i32, # debug: bool, -# token: PyToken, # } #[pymethods] @@ -375,7 +365,6 @@ with `#[call]` attribute. Arguments of the method are specified same as for inst # struct MyClass { # num: i32, # debug: bool, -# token: PyToken, # } #[pymethods] @@ -383,7 +372,7 @@ impl MyClass { #[call] #[args(args="*")] fn __call__(&self, args: &PyTuple) -> PyResult { - println!("MyCLS has been called"); + println!("MyClass has been called"); Ok(self.num) } } @@ -421,7 +410,6 @@ Example: # struct MyClass { # num: i32, # debug: bool, -# token: PyToken, # } # #[pymethods] @@ -567,11 +555,11 @@ Example: ```rust #![feature(specialization)] + extern crate pyo3; use pyo3::prelude::*; - #[pyclass] struct MyIterator { iter: Box + Send>, diff --git a/pyo3-derive-backend/src/py_class.rs b/pyo3-derive-backend/src/py_class.rs index 7a1f7303..facfd242 100644 --- a/pyo3-derive-backend/src/py_class.rs +++ b/pyo3-derive-backend/src/py_class.rs @@ -382,46 +382,34 @@ fn parse_attribute( syn::TypePath, ) { let mut params = HashMap::new(); + // We need the 0 as value for the constant we're later building using quote for when there + // are no other flags let mut flags = vec![parse_quote! {0}]; let mut base: syn::TypePath = parse_quote! {::pyo3::PyObjectRef}; for expr in args.iter() { match expr { // Match a single flag - syn::Expr::Path(ref exp) if exp.path.segments.len() == 1 => match exp - .path - .segments - .first() - .unwrap() - .value() - .ident - .to_string() - .as_str() - { - "gc" => { - flags.push(syn::Expr::Path( - parse_quote! {::pyo3::typeob::PY_TYPE_FLAG_GC}, - )); - } - "weakref" => { - flags.push(syn::Expr::Path( - parse_quote! {::pyo3::typeob::PY_TYPE_FLAG_WEAKREF}, - )); - } - "subclass" => { - flags.push(syn::Expr::Path( - parse_quote! {::pyo3::typeob::PY_TYPE_FLAG_BASETYPE}, - )); - } - "dict" => { - flags.push(syn::Expr::Path( - parse_quote! {::pyo3::typeob::PY_TYPE_FLAG_DICT}, - )); - } - param => { - println!("Unsupported parameter: {}", param); - } - }, + syn::Expr::Path(ref exp) if exp.path.segments.len() == 1 => { + let flag = exp.path.segments.first().unwrap().value().ident.to_string(); + let path = match flag.as_str() { + "gc" => { + parse_quote! {::pyo3::typeob::PY_TYPE_FLAG_GC} + } + "weakref" => { + parse_quote! {::pyo3::typeob::PY_TYPE_FLAG_WEAKREF} + } + "subclass" => { + parse_quote! {::pyo3::typeob::PY_TYPE_FLAG_BASETYPE} + } + "dict" => { + parse_quote! {::pyo3::typeob::PY_TYPE_FLAG_DICT} + } + param => panic!("Unsupported parameter: {}", param), + }; + + flags.push(syn::Expr::Path(path)); + } // Match a key/value flag syn::Expr::Assign(ref ass) => { @@ -441,7 +429,7 @@ fn parse_attribute( syn::Expr::Path(ref exp) if exp.path.segments.len() == 1 => { params.insert("name", exp.clone().into()); } - _ => println!("Wrong 'name' format: {:?}", *ass.right), + _ => panic!("Wrong 'name' format: {:?}", *ass.right), }, "extends" => match *ass.right { syn::Expr::Path(ref exp) => { @@ -450,10 +438,10 @@ fn parse_attribute( qself: None, }; } - _ => println!("Wrong 'base' format: {:?}", *ass.right), + _ => panic!("Wrong 'base' format: {:?}", *ass.right), }, _ => { - println!("Unsupported parameter: {:?}", key); + panic!("Unsupported parameter: {:?}", key); } } } diff --git a/src/instance.rs b/src/instance.rs index 3170178b..bf41e238 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -23,7 +23,6 @@ impl PyToken { } #[inline] - pub fn py(&self) -> Python { unsafe { Python::assume_gil_acquired() } } diff --git a/tests/test_arithmetics.rs b/tests/test_arithmetics.rs index 9a3dd5b5..9a60ea1a 100644 --- a/tests/test_arithmetics.rs +++ b/tests/test_arithmetics.rs @@ -8,9 +8,7 @@ use pyo3::prelude::*; mod common; #[pyclass] -struct UnaryArithmetic { - token: PyToken, -} +struct UnaryArithmetic {} #[pyproto] impl PyNumberProtocol for UnaryArithmetic { @@ -36,7 +34,7 @@ fn unary_arithmetic() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.init(|t| UnaryArithmetic { token: t }).unwrap(); + let c = py.init(|_| UnaryArithmetic {}).unwrap(); py_run!(py, c, "assert -c == 'neg'"); py_run!(py, c, "assert +c == 'pos'"); py_run!(py, c, "assert abs(c) == 'abs'"); @@ -44,9 +42,7 @@ fn unary_arithmetic() { } #[pyclass] -struct BinaryArithmetic { - token: PyToken, -} +struct BinaryArithmetic {} #[pyproto] impl PyObjectProtocol for BinaryArithmetic { @@ -58,7 +54,6 @@ impl PyObjectProtocol for BinaryArithmetic { #[pyclass] struct InPlaceOperations { value: u32, - token: PyToken, } #[pyproto] @@ -117,7 +112,7 @@ fn inplace_operations() { let py = gil.python(); let init = |value, code| { - let c = py.init(|t| InPlaceOperations { value, token: t }).unwrap(); + let c = py.init(|_| InPlaceOperations { value }).unwrap(); py_run!(py, c, code); }; @@ -171,7 +166,7 @@ fn binary_arithmetic() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.init(|t| BinaryArithmetic { token: t }).unwrap(); + let c = py.init(|_| BinaryArithmetic {}).unwrap(); py_run!(py, c, "assert c + c == 'BA + BA'"); py_run!(py, c, "assert c + 1 == 'BA + 1'"); py_run!(py, c, "assert 1 + c == '1 + BA'"); @@ -193,9 +188,7 @@ fn binary_arithmetic() { } #[pyclass] -struct RichComparisons { - token: PyToken, -} +struct RichComparisons {} #[pyproto] impl PyObjectProtocol for RichComparisons { @@ -226,7 +219,7 @@ impl PyObjectProtocol for RichComparisons2 { Ok("RC2") } - fn __richcmp__(&self, _other: &'p PyObjectRef, op: CompareOp) -> PyResult { + fn __richcmp__(&self, _other: &PyObjectRef, op: CompareOp) -> PyResult { match op { CompareOp::Eq => Ok(true.to_object(self.py())), CompareOp::Ne => Ok(false.to_object(self.py())), @@ -240,7 +233,7 @@ fn rich_comparisons() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.init(|t| RichComparisons { token: t }).unwrap(); + let c = py.init(|_| RichComparisons {}).unwrap(); py_run!(py, c, "assert (c < c) == 'RC < RC'"); py_run!(py, c, "assert (c < 1) == 'RC < 1'"); py_run!(py, c, "assert (1 < c) == 'RC > 1'"); diff --git a/tests/test_class_new.rs b/tests/test_class_new.rs index 6e8d9bd6..981d6692 100644 --- a/tests/test_class_new.rs +++ b/tests/test_class_new.rs @@ -5,15 +5,13 @@ extern crate pyo3; use pyo3::prelude::*; #[pyclass] -struct EmptyClassWithNew { - token: PyToken, -} +struct EmptyClassWithNew {} #[pymethods] impl EmptyClassWithNew { #[__new__] fn __new__(obj: &PyRawObject) -> PyResult<()> { - obj.init(|t| EmptyClassWithNew { token: t }) + obj.init(|_| EmptyClassWithNew {}) } } @@ -34,17 +32,13 @@ fn empty_class_with_new() { #[pyclass] struct NewWithOneArg { _data: i32, - token: PyToken, } #[pymethods] impl NewWithOneArg { #[new] fn __new__(obj: &PyRawObject, arg: i32) -> PyResult<()> { - obj.init(|t| NewWithOneArg { - _data: arg, - token: t, - }) + obj.init(|_| NewWithOneArg { _data: arg }) } } @@ -62,18 +56,15 @@ fn new_with_one_arg() { struct NewWithTwoArgs { _data1: i32, _data2: i32, - - token: PyToken, } #[pymethods] impl NewWithTwoArgs { #[new] fn __new__(obj: &PyRawObject, arg1: i32, arg2: i32) -> PyResult<()> { - obj.init(|t| NewWithTwoArgs { + obj.init(|_| NewWithTwoArgs { _data1: arg1, _data2: arg2, - token: t, }) } } diff --git a/tests/test_methods.rs b/tests/test_methods.rs index 7c6667f0..af57ca0f 100644 --- a/tests/test_methods.rs +++ b/tests/test_methods.rs @@ -72,15 +72,13 @@ fn instance_method_with_args() { } #[pyclass] -struct ClassMethod { - token: PyToken, -} +struct ClassMethod {} #[pymethods] impl ClassMethod { #[new] fn __new__(obj: &PyRawObject) -> PyResult<()> { - obj.init(|t| ClassMethod { token: t }) + obj.init(|_| ClassMethod {}) } #[classmethod]