-
Notifications
You must be signed in to change notification settings - Fork 783
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
Prototype: Runtime inspection and Pyi generation #2447
base: main
Are you sure you want to change the base?
Conversation
80d8e1a
to
84788ff
Compare
… will be able to import them
This will enable run-time code to generate dynamic interface structures, for example to generate a custom .pyi file
Current state of this prototype:
Current generation: #[pyclass]
struct Complicated {
#[pyo3(get, set)]
value: usize,
}
#[allow(unused_variables)]
#[pymethods]
impl Complicated {
#[new]
fn new(foo: PyObject, parent: PyObject) -> Self {
unreachable!("This is just a stub")
}
#[pyo3(name = "staticmeth")]
#[staticmethod]
fn static_method(input: PyObject) -> Complicated {
unreachable!("This is just a stub")
}
#[pyo3(name = "classmeth")]
#[classmethod]
fn class_method(cls: &PyType, input: ClassMethodInput) -> Complicated {
unreachable!("This is just a stub")
}
}
#[derive(FromPyObject)]
enum ClassMethodInput {
// Complicated(PyCell<Complicated>),
String(String),
Int(usize),
} generates: class Complicated:
@property
def value(self) -> int: ...
@value.setter
def value(self, value: int) -> None: ...
def __new__(cls, /, foo: PyAny, parent: PyAny) -> None: ...
@staticmethod
def staticmeth(input: PyAny) -> Any: ...
@classmethod
def classmeth(cls, /, input: Any) -> Any: ... |
Hi @davidhewitt! I opened #2454 to discuss the various ideas of this prototype. I think it's is good enough to show what the steps needed are, but it's far from perfect so I'd like your feedback on what the good/bad parts, so I can refactor out the good parts into independent PRs so we can finally stabilize this :) |
I think class C:
def __new__(cls, a: int) -> None:
...
c = C(3)
reveal_type(c) # Type of "c" is "None" It might be better to translate Rust's |
The goal of this PR is to add a new
inspect
feature to PyO3.When this feature is enabled, the PyO3 macros extract information about the Python data structures.
The generated information can be accessed at runtime.
This feature can be used to implement Rust functions that behave the same as
dict(...)
, etc.In particular, this feature enables the automatic generation of Interface files (.pyi) which can be used for type checking (via MyPy, PyCharm…) or documentation (after small modifications, they can be fed to Sphinx or other tools).
Current status:
PyDict
->dict
,PyAny
->Any
…) (no generics information available)Vec<Foo>
->List[Foo]
,u16
->int
…) (generic information is available)#[pyclass]
and the#[pymethods]
blocks at runtime into a singleinspect()
methodinspect
feature and gate all new behaviors behind it&'static
lifetimes with normal lifetimes, so objects can be constructed at runtime (useful for editing the .pyi?)Future possible enhancements:
multiple-pymethods
(the current implementation only works for a single#[pymethods]
block)