-
Notifications
You must be signed in to change notification settings - Fork 153
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
Consider adding Python annotation support #352
Comments
I had an idea that can help us avoid duplication and make type annotations manageable. Here is what I thought: IdeaThe idea is to make class PyGraph:
def has_edge(self, node_a: int, node_b: int, /) -> bool: ... In Rust, we would load the text signature using a constant to reuse the definition originally in #[pyo3(text_signature = annotation::PYGRAPH_HAS_EDGE)]
pub fn has_edge(&self, node_a: usize, node_b: usize) -> bool { Possibly we could also use an #[pyo3(text_signature = annotation!("PyGraph.has_edge"))]
pub fn has_edge(&self, node_a: usize, node_b: usize) -> bool { That way, we do not need two worry about conflicting text signatures and annotations. All annotations would "magically" come from ImplementationA Possible implementation for the idea is: 1. Create a Python script that parses the
|
Sorry for coming late into this, especially since you have done a lot of work in #401. We can leverage the procedural attribute macros of Rust [1] together with the parsing capabilities of the syn crate to automatically generate the
In our rust code we will write something like: #[pyfunction]
#[cfg_attr(feature = "mypy", pyhints)]
pub fn algo(graph: PyGraph, node: usize) -> usize { ... } The downside is that this approach does not work for the functions defined in |
Coming back with a more detailed approach (works for functions but not for classes) that is slightly different from what I had in mind in the previous comment:
I have an initial working implementation https://github.com/georgios-ts/stubgen (it's not fully ready to use it in retworkx). |
This is a remarkable progress! I think if you post it on the PyO3 thread they would be very interested. You have the best idea/proof-of-concept code since the debate started. I did not have time to post earlier, but the main challenge is with class PyDiGraph(Generic[S, T]):
def compose(node_map_func: Optional[Callable[[S], int]]): ... We can try replacing it with |
Yeah, that's true, using For example, as a weight function in the shortest path algorithms, we could define struct EdgeWeightFunc(PyObject);
impl ToPyHint for EdgeWeightFunc {
fn convert() -> String {
String::from("Callable[[EWeight], float]")
}
} with the convention that: impl ToPyHint for PyDiGraph {
fn convert() -> String {
String::from("PyDiGraph[NWeight, EWeight]")
}
} and in NWeight = TypeVar('NWeight')
EWeight = TypeVar('EWeight') Admittedly, it's getting a bit ugly. |
Just to play devil's advocate: would it be that bad to manually maintain |
It is not bad to maintain Maintaining So if we had autogenerated annotations, it would make it easier to contribute & also keep the |
Would running MyPy on your tests help? That way if they forget they get an explicit error saying type annotations are missing for xyz method. |
Running |
This effort was concluded by #1061, now that we are enforcing that new changes will need to add type annotations. |
What is the expected enhancement?
Users are able to execute mypy to run a static type check in code that uses retworkx.
Python annotations are becoming more popular, and we should consider supporting them. Supporting annotations can help make retworkx more popular in codebases that have adopted mypy. Also, many popular libraries that do not support annotations yet have tickets claiming for them.
Suggested Implementation
Create
.pyi
stubs containing the type annotations for the existing code. See typeshed for some inspiration on how this is done. Another useful inspiration is orjson, they are another Python library that uses Rust/PyO3 and they also use the.pyi
stub approach.Challenges
.pyi
stubs, we will have to duplicate all the functions signatures in the stubs files; ideally PyO3 would generate all the stubs but Feature request: Generate stub files along during compile PyO3/pyo3#510 is far from being closedNon-Goals
Use mypy internally within retworkx. The emphasis is: we want users to be able to run mypy when checking code that uses retworkx.
The text was updated successfully, but these errors were encountered: