PyO3 / PyO3/pyo3

`#[pyclass]` with `__call__` raises `ValueError` with `inspect.signature`

Open
#2,992 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

blocked
Dominant language
Rust
Stars
16.2k
Forks
1k
Avg merge
2d 6h
Merged PRs (30d)
66

Description

I implemented the PyNRICContainer struct in Rust with the following methods __iter__, __next__ and __call__. I have also annotated PyNRICContainer with the #[pyo3(text_signature=...)] macro with an appropriate text_signature. The __call__ method is not allowed to have a text_signature annotation but I annotated it with a #[pyo3(signature=...)] annotation. The error I got from passing the callable object into the function signature of the inspect module (i.e. inspect.signature(pycallableobj)) is a ValueError that reads ''callable <builtins.PyNRICContainer object> is not supported by signature'"

Here are the codes:

#[pyclass(name = "PyNRICContainer")]
#[derive(Debug)]
#[pyo3(text_signature = "(cls, value, values, config, field)")]
pub struct PyNRICContainer {
    #[pyo3(get, set)]
    boolean: bool,
}

#[pymethods]
impl PyNRICContainer {

    #[new]
    pub fn new() -> PyResult<PyNRICContainer> {
        Ok(PyNRICContainer { boolean: true })
    }

    pub fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> {
        slf
    }

    pub 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.")
        }
    }

    #[pyo3(signature="(cls, value, values, config, field)")]
    pub fn __call__(value: &PyString, values: &PyDict, config: &PyAny, field: &PyAny) -> PyResult<PyNRIC> {
        let v: String = value.extract()?;
        PyNRIC::new(v)
    }
    
}

My question is, how to make callable objects compatible with the inspect.signature function? Or rather, is there a way to force the __call__ method implemented in rust to have a text_signature?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the failure with the shown PyNRICContainer definition and Python's inspect.signature on the callable object. Read the #[pyclass], #[pymethods], and #[pyo3(signature=...)] handling involved in generating callable metadata; done means a Rust call method can expose its signature to inspect.signature without the ValueError.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, rust
Domain
api
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.