Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to #[classmethod] for SpendBundle::py_aggregate #678

Merged
merged 33 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
a4740e8
switch to classmethod for py_aggregate
matt-o-how Aug 26, 2024
d1f02d3
import under cfg feature
matt-o-how Aug 26, 2024
6a7ee09
update stubs
matt-o-how Aug 26, 2024
5985332
add test for derived class returning correctly
matt-o-how Aug 26, 2024
8644b38
change pystreamable macro to use classmethods instead of staticmethods
matt-o-how Aug 27, 2024
7c85ba1
fmt and clippy
matt-o-how Aug 27, 2024
1ab56bf
fix line ending format
matt-o-how Aug 27, 2024
c602f5c
black test
matt-o-how Aug 27, 2024
6c2a324
add tests for the streamable macro functions
matt-o-how Aug 29, 2024
7185a6b
fix tests to actually test what we're expecting
matt-o-how Aug 29, 2024
cfe8665
fix aggregate
matt-o-how Aug 30, 2024
eaa227b
nonworking commit for arvid
matt-o-how Sep 3, 2024
91205ae
fixup
arvidn Sep 3, 2024
5f0bab7
add downcasting step to streamable classmethods that support it
matt-o-how Sep 5, 2024
c256de6
fix tests and remove duplicate imports
matt-o-how Sep 5, 2024
b058c2d
add from_parent for OwnedSpendConditions and OwnedSpendBundleConditions
matt-o-how Sep 6, 2024
2723e1f
fmt
matt-o-how Sep 6, 2024
34ab0f9
fix stubs and use ?
matt-o-how Sep 9, 2024
58bf3ed
pushing broken optional skip to work from laptop
matt-o-how Sep 10, 2024
26bed89
fix
matt-o-how Sep 10, 2024
773be19
update all remaining streamable macros to use check and skip
matt-o-how Sep 10, 2024
6ba0981
update stubs to reflect new Streamable
matt-o-how Sep 10, 2024
dbef1e9
use py as paramter instead of calling with_gil()
matt-o-how Sep 10, 2024
71933f9
Add NotImplemented error for unsupported from_parent() calls
matt-o-how Sep 10, 2024
7f82ad3
re-enable from_parent in SpendBundle
matt-o-how Sep 11, 2024
89888cf
make error messages struct specific
matt-o-how Sep 12, 2024
763c1a7
fmt
matt-o-how Sep 13, 2024
423d41d
fix if statement for from_parent skip
matt-o-how Sep 13, 2024
b62d9d4
clippy fixes
matt-o-how Sep 13, 2024
ef7ecbe
add from_parent skip to aggregate()
matt-o-how Sep 13, 2024
f316c7e
clippy fix
matt-o-how Sep 13, 2024
2448708
Remove final with_gil()
matt-o-how Sep 16, 2024
2ebcd94
fmt
matt-o-how Sep 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions crates/chia-bls/src/public_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,7 @@ mod pytests {
Python::with_gil(|py| {
let string = pk.to_json_dict(py).expect("to_json_dict");
let py_class = py.get_type_bound::<PublicKey>();
let pk2: PublicKey = PublicKey::from_json_dict(&py_class, string.bind(py))
let pk2: PublicKey = PublicKey::from_json_dict(&py_class, py, string.bind(py))
.unwrap()
.extract(py)
.unwrap();
Expand All @@ -769,8 +769,9 @@ mod pytests {
pyo3::prepare_freethreaded_python();
Python::with_gil(|py| {
let py_class = py.get_type_bound::<PublicKey>();
let err = PublicKey::from_json_dict(&py_class, input.to_string().into_py(py).bind(py))
.unwrap_err();
let err =
PublicKey::from_json_dict(&py_class, py, input.to_string().into_py(py).bind(py))
.unwrap_err();
assert_eq!(err.value_bound(py).to_string(), msg.to_string());
});
}
Expand Down
7 changes: 4 additions & 3 deletions crates/chia-bls/src/secret_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ mod pytests {
Python::with_gil(|py| {
let string = sk.to_json_dict(py).expect("to_json_dict");
let py_class = py.get_type_bound::<SecretKey>();
let sk2 = SecretKey::from_json_dict(&py_class, string.bind(py))
let sk2 = SecretKey::from_json_dict(&py_class, py, string.bind(py))
.unwrap()
.extract(py)
.unwrap();
Expand Down Expand Up @@ -605,8 +605,9 @@ mod pytests {
pyo3::prepare_freethreaded_python();
Python::with_gil(|py| {
let py_class = py.get_type_bound::<SecretKey>();
let err = SecretKey::from_json_dict(&py_class, input.to_string().into_py(py).bind(py))
.unwrap_err();
let err =
SecretKey::from_json_dict(&py_class, py, input.to_string().into_py(py).bind(py))
.unwrap_err();
assert_eq!(err.value_bound(py).to_string(), msg.to_string());
});
}
Expand Down
18 changes: 10 additions & 8 deletions crates/chia-bls/src/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,11 +492,12 @@ impl Signature {

#[classmethod]
#[pyo3(name = "from_parent")]
pub fn from_parent(_cls: &Bound<'_, PyType>, instance: Self) -> PyResult<PyObject> {
Python::with_gil(|py| {
// ignore child case
Ok(instance.into_py(py))
})
pub fn from_parent(
_cls: &Bound<'_, PyType>,
py: Python<'_>,
instance: Self,
) -> PyResult<PyObject> {
Ok(instance.into_py(py))
}

#[pyo3(name = "pair")]
Expand Down Expand Up @@ -1272,7 +1273,7 @@ mod pytests {
Python::with_gil(|py| {
let string = sig.to_json_dict(py).expect("to_json_dict");
let py_class = py.get_type_bound::<Signature>();
let sig2 = Signature::from_json_dict(&py_class, string.bind(py))
let sig2 = Signature::from_json_dict(&py_class, py, string.bind(py))
.unwrap()
.extract(py)
.unwrap();
Expand All @@ -1291,8 +1292,9 @@ mod pytests {
pyo3::prepare_freethreaded_python();
Python::with_gil(|py| {
let py_class = py.get_type_bound::<Signature>();
let err = Signature::from_json_dict(&py_class, input.to_string().into_py(py).bind(py))
.unwrap_err();
let err =
Signature::from_json_dict(&py_class, py, input.to_string().into_py(py).bind(py))
.unwrap_err();
assert_eq!(err.value_bound(py).to_string(), msg.to_string());
});
}
Expand Down
100 changes: 48 additions & 52 deletions crates/chia_py_streamable_macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,24 +161,23 @@ pub fn py_streamable_macro(input: proc_macro::TokenStream) -> proc_macro::TokenS
impl #ident {
#[classmethod]
#[pyo3(signature=(json_dict))]
arvidn marked this conversation as resolved.
Show resolved Hide resolved
pub fn from_json_dict(cls: &pyo3::Bound<'_, pyo3::types::PyType>, json_dict: &pyo3::Bound<pyo3::PyAny>) -> pyo3::PyResult<pyo3::PyObject> {
pub fn from_json_dict(cls: &pyo3::Bound<'_, pyo3::types::PyType>, py: pyo3::Python<'_>, json_dict: &pyo3::Bound<pyo3::PyAny>) -> pyo3::PyResult<pyo3::PyObject> {
use pyo3::prelude::PyAnyMethods;
use pyo3::IntoPy;
use pyo3::type_object::PyTypeInfo;
use std::borrow::Borrow;
let rust_obj = <Self as #crate_name::from_json_dict::FromJsonDict>::from_json_dict(json_dict)?;
pyo3::Python::with_gil(|py| {
// Check if python class is different from rust class (in case of child classes)
// if so call the python class's conversion code

let cls_type = cls.borrow().as_ref();
if <Self as PyTypeInfo>::is_exact_type_of_bound(cls_type) {
Ok(rust_obj.into_py(py))
} else {
let instance = cls.call_method1("from_parent", (rust_obj.into_py(py),))?;
Ok(instance.into_py(py))
}
})

// Check if python class is different from rust class (in case of child classes)
// if so call the python class's conversion code

let cls_type = cls.borrow().as_ref();
if <Self as PyTypeInfo>::is_exact_type_of_bound(cls_type) {
Ok(rust_obj.into_py(py))
} else {
let instance = cls.call_method1("from_parent", (rust_obj.into_py(py),))?;
Ok(instance.into_py(py))
}
}

pub fn to_json_dict(&self, py: pyo3::Python) -> pyo3::PyResult<pyo3::PyObject> {
Expand All @@ -192,7 +191,7 @@ pub fn py_streamable_macro(input: proc_macro::TokenStream) -> proc_macro::TokenS
impl #ident {
#[classmethod]
#[pyo3(name = "from_bytes")]
pub fn py_from_bytes(cls: &pyo3::Bound<'_, pyo3::types::PyType>, blob: pyo3::buffer::PyBuffer<u8>) -> pyo3::PyResult<pyo3::PyObject> {
pub fn py_from_bytes(cls: &pyo3::Bound<'_, pyo3::types::PyType>, py: pyo3::Python<'_>, blob: pyo3::buffer::PyBuffer<u8>) -> pyo3::PyResult<pyo3::PyObject> {
use pyo3::prelude::PyAnyMethods;
use pyo3::IntoPy;
use pyo3::type_object::PyTypeInfo;
Expand All @@ -205,23 +204,22 @@ pub fn py_streamable_macro(input: proc_macro::TokenStream) -> proc_macro::TokenS
std::slice::from_raw_parts(blob.buf_ptr() as *const u8, blob.len_bytes())
};
let rust_obj = <Self as #crate_name::Streamable>::from_bytes(slice)?;
pyo3::Python::with_gil(|py| {
// Check if python class is different from rust class (in case of child classes)
// if so call the python class's conversion code

let cls_type = cls.borrow().as_ref();
if <Self as PyTypeInfo>::is_exact_type_of_bound(cls_type) {
Ok(rust_obj.into_py(py))
} else {
let instance = cls.call_method1("from_parent", (rust_obj.into_py(py),))?;
Ok(instance.into_py(py))
}
})

// Check if python class is different from rust class (in case of child classes)
// if so call the python class's conversion code

let cls_type = cls.borrow().as_ref();
if <Self as PyTypeInfo>::is_exact_type_of_bound(cls_type) {
Ok(rust_obj.into_py(py))
} else {
let instance = cls.call_method1("from_parent", (rust_obj.into_py(py),))?;
Ok(instance.into_py(py))
}
}

#[classmethod]
#[pyo3(name = "from_bytes_unchecked")]
pub fn py_from_bytes_unchecked(cls: &pyo3::Bound<'_, pyo3::types::PyType>, blob: pyo3::buffer::PyBuffer<u8>) -> pyo3::PyResult<pyo3::PyObject> {
pub fn py_from_bytes_unchecked(cls: &pyo3::Bound<'_, pyo3::types::PyType>, py: pyo3::Python<'_>, blob: pyo3::buffer::PyBuffer<u8>) -> pyo3::PyResult<pyo3::PyObject> {
use pyo3::prelude::PyAnyMethods;
use pyo3::IntoPy;
use pyo3::type_object::PyTypeInfo;
Expand All @@ -233,24 +231,23 @@ pub fn py_streamable_macro(input: proc_macro::TokenStream) -> proc_macro::TokenS
std::slice::from_raw_parts(blob.buf_ptr() as *const u8, blob.len_bytes())
};
let rust_obj = <Self as #crate_name::Streamable>::from_bytes_unchecked(slice).map_err(|e| <#crate_name::chia_error::Error as Into<pyo3::PyErr>>::into(e))?;
pyo3::Python::with_gil(|py| {
// Check if python class is different from rust class (in case of child classes)
// if so call the python class's conversion code

let cls_type = cls.borrow().as_ref();
if <Self as PyTypeInfo>::is_exact_type_of_bound(cls_type) {
Ok(rust_obj.into_py(py))
} else {
let instance = cls.call_method1("from_parent", (rust_obj.into_py(py),))?;
Ok(instance.into_py(py))
}
})

// Check if python class is different from rust class (in case of child classes)
// if so call the python class's conversion code

let cls_type = cls.borrow().as_ref();
if <Self as PyTypeInfo>::is_exact_type_of_bound(cls_type) {
Ok(rust_obj.into_py(py))
} else {
let instance = cls.call_method1("from_parent", (rust_obj.into_py(py),))?;
Ok(instance.into_py(py))
}
arvidn marked this conversation as resolved.
Show resolved Hide resolved
}

// returns the type as well as the number of bytes read from the buffer
#[classmethod]
#[pyo3(signature= (blob, trusted=false))]
pub fn parse_rust<'p>(cls: &pyo3::Bound<'_, pyo3::types::PyType>, blob: pyo3::buffer::PyBuffer<u8>, trusted: bool) -> pyo3::PyResult<(pyo3::PyObject, u32)> {
pub fn parse_rust<'p>(cls: &pyo3::Bound<'_, pyo3::types::PyType>, py: pyo3::Python<'_>, blob: pyo3::buffer::PyBuffer<u8>, trusted: bool) -> pyo3::PyResult<(pyo3::PyObject, u32)> {
use pyo3::prelude::PyAnyMethods;
use pyo3::IntoPy;
use pyo3::type_object::PyTypeInfo;
Expand All @@ -267,18 +264,17 @@ pub fn py_streamable_macro(input: proc_macro::TokenStream) -> proc_macro::TokenS
} else {
<Self as #crate_name::Streamable>::parse::<false>(&mut input).map_err(|e| <#crate_name::chia_error::Error as Into<pyo3::PyErr>>::into(e)).map(|v| (v, input.position() as u32))
}?;
pyo3::Python::with_gil(|py| {
// Check if python class is different from rust class (in case of child classes)
// if so call the python class's conversion code

let cls_type = cls.borrow().as_ref();
if <Self as PyTypeInfo>::is_exact_type_of_bound(cls_type) {
Ok((rust_obj.0.into_py(py), rust_obj.1))
} else {
let instance = cls.call_method1("from_parent", (rust_obj.0.into_py(py),))?;
Ok((instance.into_py(py), rust_obj.1))
}
})

// Check if python class is different from rust class (in case of child classes)
// if so call the python class's conversion code

let cls_type = cls.borrow().as_ref();
if <Self as PyTypeInfo>::is_exact_type_of_bound(cls_type) {
Ok((rust_obj.0.into_py(py), rust_obj.1))
} else {
let instance = cls.call_method1("from_parent", (rust_obj.0.into_py(py),))?;
Ok((instance.into_py(py), rust_obj.1))
}
}

pub fn get_hash<'p>(&self, py: pyo3::Python<'p>) -> pyo3::PyResult<pyo3::Bound<'p, pyo3::types::PyAny>> {
Expand Down
Loading