Get rid of a bunch of PyTokens

This commit is contained in:
konstin 2018-09-02 23:33:45 +02:00
parent a5ab5661a2
commit f58549f1d8
7 changed files with 43 additions and 86 deletions

View file

@ -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.

View file

@ -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<i32> {
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<Iterator<Item=PyObject> + Send>,

View file

@ -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);
}
}
}

View file

@ -23,7 +23,6 @@ impl PyToken {
}
#[inline]
pub fn py(&self) -> Python {
unsafe { Python::assume_gil_acquired() }
}

View file

@ -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<PyObject> {
fn __richcmp__(&self, _other: &PyObjectRef, op: CompareOp) -> PyResult<PyObject> {
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'");

View file

@ -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,
})
}
}

View file

@ -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]