diff --git a/src/builder.rs b/src/builder.rs index 0f85bd1ac..c8c0cdc55 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -3,7 +3,7 @@ use thiserror::Error; #[cfg(feature = "pyo3")] -use pyo3::prelude::*; +use pyo3::{create_exception, exceptions::PyException, PyErr}; use crate::hugr::{HugrError, Node, ValidationError, Wire}; use crate::ops::handle::{BasicBlockID, CfgID, ConditionalID, DfgID, FuncID, TailLoopID}; @@ -78,11 +78,18 @@ pub enum BuildError { CircuitError(#[from] circuit::CircuitBuildError), } +#[cfg(feature = "pyo3")] +create_exception!( + pyrs, + PyBuildError, + PyException, + "Errors that can occur while building a Hugr" +); + #[cfg(feature = "pyo3")] impl From for PyErr { fn from(err: BuildError) -> Self { - // We may want to define more specific python-level errors at some point. - PyErr::new::(err.to_string()) + PyBuildError::new_err(err.to_string()) } } diff --git a/src/hugr.rs b/src/hugr.rs index 648383562..831f16298 100644 --- a/src/hugr.rs +++ b/src/hugr.rs @@ -23,7 +23,7 @@ use portgraph::{Hierarchy, NodeIndex, PortMut, UnmanagedDenseMap}; use thiserror::Error; #[cfg(feature = "pyo3")] -use pyo3::prelude::*; +use pyo3::{create_exception, exceptions::PyException, pyclass, PyErr}; pub use self::views::HugrView; use crate::extension::{ @@ -463,11 +463,18 @@ pub enum HugrError { InvalidNode(Node), } +#[cfg(feature = "pyo3")] +create_exception!( + pyrs, + PyHugrError, + PyException, + "Errors that can occur while manipulating a Hugr" +); + #[cfg(feature = "pyo3")] impl From for PyErr { fn from(err: HugrError) -> Self { - // We may want to define more specific python-level errors at some point. - PyErr::new::(err.to_string()) + PyHugrError::new_err(err.to_string()) } } diff --git a/src/hugr/serialize.rs b/src/hugr/serialize.rs index c75afa2af..53bff8cc6 100644 --- a/src/hugr/serialize.rs +++ b/src/hugr/serialize.rs @@ -6,7 +6,7 @@ use std::collections::HashMap; use thiserror::Error; #[cfg(feature = "pyo3")] -use pyo3::prelude::*; +use pyo3::{create_exception, exceptions::PyException, PyErr}; use crate::extension::ExtensionSet; use crate::hugr::{Hugr, NodeType}; @@ -89,10 +89,18 @@ pub enum HUGRSerializationError { FirstNodeNotRoot(Node), } +#[cfg(feature = "pyo3")] +create_exception!( + pyrs, + PyHUGRSerializationError, + PyException, + "Errors that can occur while serializing a Hugr" +); + #[cfg(feature = "pyo3")] impl From for PyErr { fn from(err: HUGRSerializationError) -> Self { - PyErr::new::(err.to_string()) + PyHUGRSerializationError::new_err(err.to_string()) } } diff --git a/src/hugr/validate.rs b/src/hugr/validate.rs index 9db0a4f7b..281fb80c9 100644 --- a/src/hugr/validate.rs +++ b/src/hugr/validate.rs @@ -10,7 +10,7 @@ use portgraph::{LinkView, PortView}; use thiserror::Error; #[cfg(feature = "pyo3")] -use pyo3::prelude::*; +use pyo3::{create_exception, exceptions::PyException, PyErr}; use crate::extension::SignatureError; use crate::extension::{ @@ -636,11 +636,18 @@ pub enum ValidationError { SignatureError { node: Node, cause: SignatureError }, } +#[cfg(feature = "pyo3")] +create_exception!( + pyrs, + PyValidationError, + PyException, + "Errors that can occur while validating a Hugr" +); + #[cfg(feature = "pyo3")] impl From for PyErr { fn from(err: ValidationError) -> Self { - // We may want to define more specific python-level errors at some point. - PyErr::new::(err.to_string()) + PyValidationError::new_err(err.to_string()) } } diff --git a/src/hugr/views/sibling_subgraph.rs b/src/hugr/views/sibling_subgraph.rs index a48ca2978..6d9e6e67d 100644 --- a/src/hugr/views/sibling_subgraph.rs +++ b/src/hugr/views/sibling_subgraph.rs @@ -26,6 +26,9 @@ use crate::{ use super::HugrView; +#[cfg(feature = "pyo3")] +use pyo3::{create_exception, exceptions::PyException, PyErr}; + /// A non-empty convex subgraph of a HUGR sibling graph. /// /// A HUGR region in which all nodes share the same parent. Unlike @@ -536,6 +539,21 @@ pub enum InvalidReplacement { NonConvexSubgraph, } +#[cfg(feature = "pyo3")] +create_exception!( + pyrs, + PyInvalidReplacementError, + PyException, + "Errors that can occur while constructing a SimpleReplacement" +); + +#[cfg(feature = "pyo3")] +impl From for PyErr { + fn from(err: InvalidReplacement) -> Self { + PyInvalidReplacementError::new_err(err.to_string()) + } +} + /// Errors that can occur while constructing a [`SiblingSubgraph`]. #[derive(Debug, Clone, PartialEq, Eq, Error)] pub enum InvalidSubgraph { diff --git a/src/std_extensions/rotation.rs b/src/std_extensions/rotation.rs index 15e1da725..35b2102b9 100644 --- a/src/std_extensions/rotation.rs +++ b/src/std_extensions/rotation.rs @@ -8,7 +8,7 @@ use num_rational::Rational64; use smol_str::SmolStr; #[cfg(feature = "pyo3")] -use pyo3::prelude::*; +use pyo3::{pyclass, FromPyObject}; use crate::extension::ExtensionId; use crate::types::type_param::TypeArg; diff --git a/src/types.rs b/src/types.rs index 21688d936..86a44a777 100644 --- a/src/types.rs +++ b/src/types.rs @@ -13,6 +13,7 @@ pub use custom::CustomType; pub use signature::{FunctionType, Signature, SignatureDescription}; pub use type_row::TypeRow; +use derive_more::{From, Into}; use itertools::FoldWhile::{Continue, Done}; use itertools::Itertools; use serde::{Deserialize, Serialize}; @@ -24,8 +25,10 @@ use std::fmt::Debug; use self::primitive::PrimType; +#[cfg(feature = "pyo3")] +use pyo3::pyclass; + /// The kinds of edges in a HUGR, excluding Hierarchy. -//#[cfg_attr(feature = "pyo3", pyclass)] # TODO: Manually derive pyclass with non-unit variants #[derive(Clone, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)] #[non_exhaustive] pub enum EdgeKind { @@ -46,6 +49,12 @@ impl EdgeKind { } } +/// Python representation for [`EdgeKind`], the kinds of edges in a HUGR. +#[cfg_attr(feature = "pyo3", pyclass)] +#[repr(transparent)] +#[derive(Clone, PartialEq, Eq, Debug, From, Into)] +pub struct PyEdgeKind(EdgeKind); + #[derive( Copy, Default, Clone, PartialEq, Eq, Hash, Debug, derive_more::Display, Serialize, Deserialize, )] @@ -167,6 +176,7 @@ impl TypeEnum { )] #[display(fmt = "{}", "_0")] #[serde(into = "serialize::SerSimpleType", from = "serialize::SerSimpleType")] +#[cfg_attr(feature = "pyo3", pyclass)] /// A HUGR type - the valid types of [EdgeKind::Value] and [EdgeKind::Static] edges. /// Such an edge is valid if the ports on either end agree on the [Type]. /// Types have an optional [TypeBound] which places limits on the valid diff --git a/src/types/signature.rs b/src/types/signature.rs index 0e83f4037..076ba8815 100644 --- a/src/types/signature.rs +++ b/src/types/signature.rs @@ -1,7 +1,7 @@ //! Abstract and concrete Signature types. #[cfg(feature = "pyo3")] -use pyo3::prelude::*; +use pyo3::{pyclass, pymethods}; use std::ops::Index; diff --git a/src/types/type_row.rs b/src/types/type_row.rs index 055a5ac6d..b3b69bafe 100644 --- a/src/types/type_row.rs +++ b/src/types/type_row.rs @@ -11,9 +11,12 @@ use super::Type; use crate::utils::display_list; use delegate::delegate; +#[cfg(feature = "pyo3")] +use pyo3::pyclass; + /// List of types, used for function signatures. #[derive(Clone, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)] -//#[cfg_attr(feature = "pyo3", pyclass)] +#[cfg_attr(feature = "pyo3", pyclass)] #[non_exhaustive] #[serde(transparent)] pub struct TypeRow {