I have a rust struct with which I had implemented python's magic methods __iter__
, __next__
, and __call__
.
#[pyclass(name = "PyNRICContainer")]
#[derive(Debug)]
#[pyo3(text_signature = "(cls, value, values)")]
pub struct PyNRICContainer {
#[pyo3(get, set)]
boolean: bool,
}
Here are the implementations:
#[pymethods]
impl PyNRICContainer {
#[new]
#[pyo3(signature = "(cls, value, values)")]
fn new() -> PyResult<PyNRICContainer> {
Ok(PyNRICContainer { boolean: true })
}
fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> {
slf
}
fn __next__(mut slf: PyRefMut<'_, Self>) -> IterNextOutput<PyRefMut<'_, Self>, &'static str> {
if slf.boolean {
slf.boolean = false;
IterNextOutput::Yield(slf)
} else {
IterNextOutput::Return("No Longer Iterable.")
}
}
#[classmethod]
fn __call__(&mut self, py: Python<'_>, value: &PyString, values: Option<&PyDict>) -> PyResult<PyNRIC> {
let v: String = value.extract()?;
PyNRIC::new(v)
}
}
With this, I enabled the behavior of yield
this object through the following python codes.
g = PyNRICContainer()
gs = (
*(g if g else ()),
)
print("gs", gs)
The output of the above snippet is:
gs (<builtins.PyNRICContainer object at 0x0000021250B37650>,)
Now, as inspect.signature
method cannot get a signature out of g
in the above snippet, it raises a ValueError
shown below.
ValueError: callable <builtins.PyNRICContainer object at 0x0000021250B37650> is not supported by signature
In the pyo3's documentations, there is a mention of the macro #[pyo3(text_signature)]
, I tried to implement it above the fn __call__
but it couldn't compile as:
error: `text_signature` cannot be used with `__call__`
My objective is to have a python callable object which is also 'yieldable', i.e. I should be able to yield the object, e.g. yield g
in a function or using to *
operator to unpack the function from which g
was yielded.
E.g.
def yield_g():
yield g
gs = (
*(yield_g() if yield_g else None),
)
And it should output something like (g,)
. I have also tried printing type(g).text_signature but it gives an AttributeError.
Is it possible to make a pyo3::types::PyFunction
a PyIterator
such that it is yieldable?
source https://stackoverflow.com/questions/75574260/pyo3-troubles-with-inspect-signature-method
Comments
Post a Comment