2021-12-03 00:03:32 +00:00
|
|
|
#![cfg(feature = "macros")]
|
|
|
|
|
2019-11-29 20:19:56 +00:00
|
|
|
use pyo3::prelude::*;
|
2022-11-24 22:05:16 +00:00
|
|
|
use pyo3::types::{PyDict, PyTuple};
|
2021-06-24 14:18:48 +00:00
|
|
|
use pyo3::{types::PyType, wrap_pymodule, PyCell};
|
2019-11-29 20:19:56 +00:00
|
|
|
|
|
|
|
mod common;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn class_without_docs_or_signature() {
|
|
|
|
#[pyclass]
|
|
|
|
struct MyClass {}
|
|
|
|
|
2022-07-19 17:34:23 +00:00
|
|
|
Python::with_gil(|py| {
|
|
|
|
let typeobj = py.get_type::<MyClass>();
|
2019-11-29 20:19:56 +00:00
|
|
|
|
2022-07-19 17:34:23 +00:00
|
|
|
py_assert!(py, typeobj, "typeobj.__doc__ is None");
|
|
|
|
py_assert!(py, typeobj, "typeobj.__text_signature__ is None");
|
|
|
|
});
|
2019-11-29 20:19:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn class_with_docs() {
|
|
|
|
/// docs line1
|
|
|
|
#[pyclass]
|
|
|
|
/// docs line2
|
|
|
|
struct MyClass {}
|
|
|
|
|
2022-07-19 17:34:23 +00:00
|
|
|
Python::with_gil(|py| {
|
|
|
|
let typeobj = py.get_type::<MyClass>();
|
2019-11-29 20:19:56 +00:00
|
|
|
|
2022-07-19 17:34:23 +00:00
|
|
|
py_assert!(py, typeobj, "typeobj.__doc__ == 'docs line1\\ndocs line2'");
|
|
|
|
py_assert!(py, typeobj, "typeobj.__text_signature__ is None");
|
|
|
|
});
|
2019-11-29 20:19:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2020-10-11 23:51:27 +00:00
|
|
|
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_10)), ignore)]
|
2023-02-07 21:15:32 +00:00
|
|
|
fn class_with_signature_no_doc() {
|
2019-11-29 20:19:56 +00:00
|
|
|
#[pyclass]
|
|
|
|
struct MyClass {}
|
|
|
|
|
|
|
|
#[pymethods]
|
|
|
|
impl MyClass {
|
|
|
|
#[new]
|
2023-02-07 21:15:32 +00:00
|
|
|
#[pyo3(signature = (a, b=None, *, c=42), text_signature = "(a, b=None, *, c=42)")]
|
2019-12-14 14:16:39 +00:00
|
|
|
fn __new__(a: i32, b: Option<i32>, c: i32) -> Self {
|
2019-11-29 20:19:56 +00:00
|
|
|
let _ = (a, b, c);
|
2019-12-14 14:16:39 +00:00
|
|
|
Self {}
|
2019-11-29 20:19:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-19 17:34:23 +00:00
|
|
|
Python::with_gil(|py| {
|
|
|
|
let typeobj = py.get_type::<MyClass>();
|
2023-02-07 21:15:32 +00:00
|
|
|
py_assert!(py, typeobj, "typeobj.__doc__ == ''");
|
2022-07-19 17:34:23 +00:00
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
typeobj,
|
|
|
|
"typeobj.__text_signature__ == '(a, b=None, *, c=42)'"
|
|
|
|
);
|
|
|
|
});
|
2019-11-29 20:19:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2020-10-11 23:51:27 +00:00
|
|
|
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_10)), ignore)]
|
2023-02-07 21:15:32 +00:00
|
|
|
fn class_with_docs_and_signature() {
|
|
|
|
/// docs line1
|
2019-11-29 20:19:56 +00:00
|
|
|
#[pyclass]
|
2023-02-07 21:15:32 +00:00
|
|
|
/// docs line2
|
2019-11-29 20:19:56 +00:00
|
|
|
struct MyClass {}
|
|
|
|
|
|
|
|
#[pymethods]
|
|
|
|
impl MyClass {
|
|
|
|
#[new]
|
2023-02-07 21:15:32 +00:00
|
|
|
#[pyo3(signature = (a, b=None, *, c=42), text_signature = "(a, b=None, *, c=42)")]
|
2019-12-14 14:16:39 +00:00
|
|
|
fn __new__(a: i32, b: Option<i32>, c: i32) -> Self {
|
2019-11-29 20:19:56 +00:00
|
|
|
let _ = (a, b, c);
|
2019-12-14 14:16:39 +00:00
|
|
|
Self {}
|
2019-11-29 20:19:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-19 17:34:23 +00:00
|
|
|
Python::with_gil(|py| {
|
|
|
|
let typeobj = py.get_type::<MyClass>();
|
|
|
|
|
2023-02-07 21:15:32 +00:00
|
|
|
py_assert!(py, typeobj, "typeobj.__doc__ == 'docs line1\\ndocs line2'");
|
2022-07-19 17:34:23 +00:00
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
typeobj,
|
|
|
|
"typeobj.__text_signature__ == '(a, b=None, *, c=42)'"
|
|
|
|
);
|
|
|
|
});
|
2019-11-29 20:19:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_function() {
|
2022-10-25 06:23:21 +00:00
|
|
|
#[pyfunction(signature = (a, b=None, *, c=42))]
|
2021-06-05 15:28:31 +00:00
|
|
|
#[pyo3(text_signature = "(a, b=None, *, c=42)")]
|
2019-11-29 20:19:56 +00:00
|
|
|
fn my_function(a: i32, b: Option<i32>, c: i32) {
|
|
|
|
let _ = (a, b, c);
|
|
|
|
}
|
|
|
|
|
2022-07-19 17:34:23 +00:00
|
|
|
Python::with_gil(|py| {
|
|
|
|
let f = wrap_pyfunction!(my_function)(py).unwrap();
|
2019-11-29 20:19:56 +00:00
|
|
|
|
2022-07-19 17:34:23 +00:00
|
|
|
py_assert!(py, f, "f.__text_signature__ == '(a, b=None, *, c=42)'");
|
|
|
|
});
|
2019-11-29 20:19:56 +00:00
|
|
|
}
|
|
|
|
|
2022-11-24 22:05:16 +00:00
|
|
|
#[test]
|
|
|
|
fn test_auto_test_signature_function() {
|
|
|
|
#[pyfunction]
|
2023-01-15 10:17:10 +00:00
|
|
|
fn my_function(a: i32, b: i32, c: i32) {
|
2022-11-24 22:05:16 +00:00
|
|
|
let _ = (a, b, c);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[pyfunction(pass_module)]
|
2023-01-15 10:17:10 +00:00
|
|
|
fn my_function_2(module: &PyModule, a: i32, b: i32, c: i32) {
|
2022-11-24 22:05:16 +00:00
|
|
|
let _ = (module, a, b, c);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[pyfunction(signature = (a, /, b = None, *, c = 5))]
|
|
|
|
fn my_function_3(a: i32, b: Option<i32>, c: i32) {
|
|
|
|
let _ = (a, b, c);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[pyfunction(signature = (a, /, b = None, *args, c, d=5, **kwargs))]
|
|
|
|
fn my_function_4(
|
|
|
|
a: i32,
|
|
|
|
b: Option<i32>,
|
|
|
|
args: &PyTuple,
|
|
|
|
c: i32,
|
|
|
|
d: i32,
|
|
|
|
kwargs: Option<&PyDict>,
|
|
|
|
) {
|
|
|
|
let _ = (a, b, args, c, d, kwargs);
|
|
|
|
}
|
|
|
|
|
2023-03-16 02:42:31 +00:00
|
|
|
#[pyfunction(signature = (a = 1, /, b = None, c = 1.5, d=5, e = "pyo3", f = 'f', h = true))]
|
|
|
|
fn my_function_5(a: i32, b: Option<i32>, c: f32, d: i32, e: &str, f: char, h: bool) {
|
|
|
|
let _ = (a, b, c, d, e, f, h);
|
|
|
|
}
|
|
|
|
|
2023-03-26 08:42:34 +00:00
|
|
|
#[pyfunction]
|
|
|
|
fn my_function_6(a: i32, b: Option<i32>, c: Option<i32>) {
|
|
|
|
let _ = (a, b, c);
|
|
|
|
}
|
|
|
|
|
2022-11-24 22:05:16 +00:00
|
|
|
Python::with_gil(|py| {
|
|
|
|
let f = wrap_pyfunction!(my_function)(py).unwrap();
|
2023-03-26 08:42:34 +00:00
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
f,
|
|
|
|
"f.__text_signature__ == '(a, b, c)', f.__text_signature__"
|
|
|
|
);
|
2022-11-24 22:05:16 +00:00
|
|
|
|
|
|
|
let f = wrap_pyfunction!(my_function_2)(py).unwrap();
|
2023-03-26 08:42:34 +00:00
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
f,
|
|
|
|
"f.__text_signature__ == '($module, a, b, c)', f.__text_signature__"
|
|
|
|
);
|
2022-11-24 22:05:16 +00:00
|
|
|
|
|
|
|
let f = wrap_pyfunction!(my_function_3)(py).unwrap();
|
2023-03-26 08:42:34 +00:00
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
f,
|
|
|
|
"f.__text_signature__ == '(a, /, b=None, *, c=5)', f.__text_signature__"
|
|
|
|
);
|
2022-11-24 22:05:16 +00:00
|
|
|
|
|
|
|
let f = wrap_pyfunction!(my_function_4)(py).unwrap();
|
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
f,
|
2023-03-26 08:42:34 +00:00
|
|
|
"f.__text_signature__ == '(a, /, b=None, *args, c, d=5, **kwargs)', f.__text_signature__"
|
2023-03-16 02:42:31 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
let f = wrap_pyfunction!(my_function_5)(py).unwrap();
|
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
f,
|
2023-03-26 08:42:34 +00:00
|
|
|
"f.__text_signature__ == '(a=1, /, b=None, c=1.5, d=5, e=\"pyo3\", f=\\'f\\', h=True)', f.__text_signature__"
|
|
|
|
);
|
|
|
|
|
|
|
|
let f = wrap_pyfunction!(my_function_6)(py).unwrap();
|
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
f,
|
|
|
|
"f.__text_signature__ == '(a, b=None, c=None)', f.__text_signature__"
|
2022-11-24 22:05:16 +00:00
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_auto_test_signature_method() {
|
|
|
|
#[pyclass]
|
|
|
|
struct MyClass {}
|
|
|
|
|
|
|
|
#[pymethods]
|
|
|
|
impl MyClass {
|
2023-02-07 21:15:32 +00:00
|
|
|
#[new]
|
|
|
|
fn new(a: i32, b: i32, c: i32) -> Self {
|
|
|
|
let _ = (a, b, c);
|
|
|
|
Self {}
|
|
|
|
}
|
|
|
|
|
2023-01-15 10:17:10 +00:00
|
|
|
fn method(&self, a: i32, b: i32, c: i32) {
|
2022-11-24 22:05:16 +00:00
|
|
|
let _ = (a, b, c);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[pyo3(signature = (a, /, b = None, *, c = 5))]
|
|
|
|
fn method_2(&self, a: i32, b: Option<i32>, c: i32) {
|
|
|
|
let _ = (a, b, c);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[pyo3(signature = (a, /, b = None, *args, c, d=5, **kwargs))]
|
|
|
|
fn method_3(
|
|
|
|
&self,
|
|
|
|
a: i32,
|
|
|
|
b: Option<i32>,
|
|
|
|
args: &PyTuple,
|
|
|
|
c: i32,
|
|
|
|
d: i32,
|
|
|
|
kwargs: Option<&PyDict>,
|
|
|
|
) {
|
|
|
|
let _ = (a, b, args, c, d, kwargs);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[staticmethod]
|
2023-01-15 10:17:10 +00:00
|
|
|
fn staticmethod(a: i32, b: i32, c: i32) {
|
2022-11-24 22:05:16 +00:00
|
|
|
let _ = (a, b, c);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[classmethod]
|
2023-01-15 10:17:10 +00:00
|
|
|
fn classmethod(cls: &PyType, a: i32, b: i32, c: i32) {
|
2022-11-24 22:05:16 +00:00
|
|
|
let _ = (cls, a, b, c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Python::with_gil(|py| {
|
|
|
|
let cls = py.get_type::<MyClass>();
|
2023-05-04 16:28:43 +00:00
|
|
|
#[cfg(any(not(Py_LIMITED_API), Py_3_10))]
|
2023-02-07 21:15:32 +00:00
|
|
|
py_assert!(py, cls, "cls.__text_signature__ == '(a, b, c)'");
|
2022-11-24 22:05:16 +00:00
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
cls,
|
|
|
|
"cls.method.__text_signature__ == '($self, a, b, c)'"
|
|
|
|
);
|
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
cls,
|
2023-03-26 08:42:34 +00:00
|
|
|
"cls.method_2.__text_signature__ == '($self, a, /, b=None, *, c=5)'"
|
2022-11-24 22:05:16 +00:00
|
|
|
);
|
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
cls,
|
2023-03-26 08:42:34 +00:00
|
|
|
"cls.method_3.__text_signature__ == '($self, a, /, b=None, *args, c, d=5, **kwargs)'"
|
2022-11-24 22:05:16 +00:00
|
|
|
);
|
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
cls,
|
|
|
|
"cls.staticmethod.__text_signature__ == '(a, b, c)'"
|
|
|
|
);
|
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
cls,
|
|
|
|
"cls.classmethod.__text_signature__ == '($cls, a, b, c)'"
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_auto_test_signature_opt_out() {
|
|
|
|
#[pyfunction(text_signature = None)]
|
2023-01-15 10:17:10 +00:00
|
|
|
fn my_function(a: i32, b: i32, c: i32) {
|
2022-11-24 22:05:16 +00:00
|
|
|
let _ = (a, b, c);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[pyfunction(signature = (a, /, b = None, *, c = 5), text_signature = None)]
|
|
|
|
fn my_function_2(a: i32, b: Option<i32>, c: i32) {
|
|
|
|
let _ = (a, b, c);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[pyclass]
|
|
|
|
struct MyClass {}
|
|
|
|
|
|
|
|
#[pymethods]
|
|
|
|
impl MyClass {
|
2023-02-07 21:15:32 +00:00
|
|
|
#[new]
|
|
|
|
#[pyo3(text_signature = None)]
|
|
|
|
fn new(a: i32, b: i32, c: i32) -> Self {
|
|
|
|
let _ = (a, b, c);
|
|
|
|
Self {}
|
|
|
|
}
|
|
|
|
|
2022-11-24 22:05:16 +00:00
|
|
|
#[pyo3(text_signature = None)]
|
2023-01-15 10:17:10 +00:00
|
|
|
fn method(&self, a: i32, b: i32, c: i32) {
|
2022-11-24 22:05:16 +00:00
|
|
|
let _ = (a, b, c);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[pyo3(signature = (a, /, b = None, *, c = 5), text_signature = None)]
|
|
|
|
fn method_2(&self, a: i32, b: Option<i32>, c: i32) {
|
|
|
|
let _ = (a, b, c);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[staticmethod]
|
|
|
|
#[pyo3(text_signature = None)]
|
2023-01-15 10:17:10 +00:00
|
|
|
fn staticmethod(a: i32, b: i32, c: i32) {
|
2022-11-24 22:05:16 +00:00
|
|
|
let _ = (a, b, c);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[classmethod]
|
|
|
|
#[pyo3(text_signature = None)]
|
2023-01-15 10:17:10 +00:00
|
|
|
fn classmethod(cls: &PyType, a: i32, b: i32, c: i32) {
|
2022-11-24 22:05:16 +00:00
|
|
|
let _ = (cls, a, b, c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Python::with_gil(|py| {
|
|
|
|
let f = wrap_pyfunction!(my_function)(py).unwrap();
|
|
|
|
py_assert!(py, f, "f.__text_signature__ == None");
|
|
|
|
|
|
|
|
let f = wrap_pyfunction!(my_function_2)(py).unwrap();
|
|
|
|
py_assert!(py, f, "f.__text_signature__ == None");
|
|
|
|
|
|
|
|
let cls = py.get_type::<MyClass>();
|
2023-02-07 21:15:32 +00:00
|
|
|
py_assert!(py, cls, "cls.__text_signature__ == None");
|
2022-11-24 22:05:16 +00:00
|
|
|
py_assert!(py, cls, "cls.method.__text_signature__ == None");
|
|
|
|
py_assert!(py, cls, "cls.method_2.__text_signature__ == None");
|
|
|
|
py_assert!(py, cls, "cls.staticmethod.__text_signature__ == None");
|
|
|
|
py_assert!(py, cls, "cls.classmethod.__text_signature__ == None");
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-11-29 20:19:56 +00:00
|
|
|
#[test]
|
|
|
|
fn test_pyfn() {
|
|
|
|
#[pymodule]
|
2022-03-23 07:07:28 +00:00
|
|
|
fn my_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
2022-10-25 06:23:21 +00:00
|
|
|
#[pyfn(m, signature = (a, b=None, *, c=42))]
|
2021-06-05 15:28:31 +00:00
|
|
|
#[pyo3(text_signature = "(a, b=None, *, c=42)")]
|
2019-11-29 20:19:56 +00:00
|
|
|
fn my_function(a: i32, b: Option<i32>, c: i32) {
|
|
|
|
let _ = (a, b, c);
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2022-07-19 17:34:23 +00:00
|
|
|
Python::with_gil(|py| {
|
|
|
|
let m = wrap_pymodule!(my_module)(py);
|
2019-11-29 20:19:56 +00:00
|
|
|
|
2022-07-19 17:34:23 +00:00
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
m,
|
|
|
|
"m.my_function.__text_signature__ == '(a, b=None, *, c=42)'"
|
|
|
|
);
|
|
|
|
});
|
2019-11-29 20:19:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_methods() {
|
|
|
|
#[pyclass]
|
|
|
|
struct MyClass {}
|
|
|
|
|
|
|
|
#[pymethods]
|
|
|
|
impl MyClass {
|
2021-06-05 15:28:31 +00:00
|
|
|
#[pyo3(text_signature = "($self, a)")]
|
2019-11-29 20:19:56 +00:00
|
|
|
fn method(&self, a: i32) {
|
|
|
|
let _ = a;
|
|
|
|
}
|
2021-06-05 15:28:31 +00:00
|
|
|
#[pyo3(text_signature = "($self, b)")]
|
2020-02-03 13:25:16 +00:00
|
|
|
fn pyself_method(_this: &PyCell<Self>, b: i32) {
|
2019-11-29 20:19:56 +00:00
|
|
|
let _ = b;
|
|
|
|
}
|
|
|
|
#[classmethod]
|
2021-06-05 15:28:31 +00:00
|
|
|
#[pyo3(text_signature = "($cls, c)")]
|
2019-11-29 20:19:56 +00:00
|
|
|
fn class_method(_cls: &PyType, c: i32) {
|
|
|
|
let _ = c;
|
|
|
|
}
|
|
|
|
#[staticmethod]
|
2021-06-05 15:28:31 +00:00
|
|
|
#[pyo3(text_signature = "(d)")]
|
2019-11-29 20:19:56 +00:00
|
|
|
fn static_method(d: i32) {
|
|
|
|
let _ = d;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-19 17:34:23 +00:00
|
|
|
Python::with_gil(|py| {
|
|
|
|
let typeobj = py.get_type::<MyClass>();
|
|
|
|
|
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
typeobj,
|
|
|
|
"typeobj.method.__text_signature__ == '($self, a)'"
|
|
|
|
);
|
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
typeobj,
|
|
|
|
"typeobj.pyself_method.__text_signature__ == '($self, b)'"
|
|
|
|
);
|
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
typeobj,
|
|
|
|
"typeobj.class_method.__text_signature__ == '($cls, c)'"
|
|
|
|
);
|
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
typeobj,
|
|
|
|
"typeobj.static_method.__text_signature__ == '(d)'"
|
|
|
|
);
|
|
|
|
});
|
2019-11-29 20:19:56 +00:00
|
|
|
}
|
2020-11-19 20:47:30 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_10)), ignore)]
|
|
|
|
fn test_raw_identifiers() {
|
|
|
|
#[pyclass]
|
|
|
|
struct r#MyClass {}
|
|
|
|
|
|
|
|
#[pymethods]
|
|
|
|
impl MyClass {
|
|
|
|
#[new]
|
|
|
|
fn new() -> MyClass {
|
|
|
|
MyClass {}
|
|
|
|
}
|
|
|
|
fn r#method(&self) {}
|
|
|
|
}
|
|
|
|
|
2022-07-19 17:34:23 +00:00
|
|
|
Python::with_gil(|py| {
|
|
|
|
let typeobj = py.get_type::<MyClass>();
|
2020-11-19 20:47:30 +00:00
|
|
|
|
2023-02-07 21:15:32 +00:00
|
|
|
py_assert!(py, typeobj, "typeobj.__text_signature__ == '()'");
|
2020-11-19 20:47:30 +00:00
|
|
|
|
2022-07-19 17:34:23 +00:00
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
typeobj,
|
|
|
|
"typeobj.method.__text_signature__ == '($self)'"
|
|
|
|
);
|
|
|
|
});
|
2020-11-19 20:47:30 +00:00
|
|
|
}
|
2023-02-07 21:15:32 +00:00
|
|
|
|
|
|
|
#[allow(deprecated)]
|
|
|
|
mod deprecated {
|
|
|
|
use crate::py_assert;
|
|
|
|
use pyo3::prelude::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_10)), ignore)]
|
|
|
|
fn class_with_docs_and_signature() {
|
|
|
|
/// docs line1
|
|
|
|
#[pyclass]
|
|
|
|
/// docs line2
|
|
|
|
#[pyo3(text_signature = "(a, b=None, *, c=42)")]
|
|
|
|
/// docs line3
|
|
|
|
struct MyClass {}
|
|
|
|
|
|
|
|
#[pymethods]
|
|
|
|
impl MyClass {
|
|
|
|
#[new]
|
|
|
|
#[pyo3(signature = (a, b=None, *, c=42))]
|
|
|
|
fn __new__(a: i32, b: Option<i32>, c: i32) -> Self {
|
|
|
|
let _ = (a, b, c);
|
|
|
|
Self {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Python::with_gil(|py| {
|
|
|
|
let typeobj = py.get_type::<MyClass>();
|
|
|
|
|
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
typeobj,
|
|
|
|
"typeobj.__doc__ == 'docs line1\\ndocs line2\\ndocs line3'"
|
|
|
|
);
|
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
typeobj,
|
|
|
|
"typeobj.__text_signature__ == '(a, b=None, *, c=42)'"
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_10)), ignore)]
|
|
|
|
fn class_with_deprecated_text_signature() {
|
|
|
|
#[pyclass]
|
|
|
|
#[pyo3(text_signature = "(a, b=None, *, c=42)")]
|
|
|
|
struct MyClass {}
|
|
|
|
|
|
|
|
#[pymethods]
|
|
|
|
impl MyClass {
|
|
|
|
#[new]
|
|
|
|
#[pyo3(signature = (a, b=None, *, c=42))]
|
|
|
|
fn __new__(a: i32, b: Option<i32>, c: i32) -> Self {
|
|
|
|
let _ = (a, b, c);
|
|
|
|
Self {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Python::with_gil(|py| {
|
|
|
|
let typeobj = py.get_type::<MyClass>();
|
|
|
|
|
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
typeobj,
|
|
|
|
"typeobj.__doc__ is None or typeobj.__doc__ == ''"
|
|
|
|
);
|
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
typeobj,
|
|
|
|
"typeobj.__text_signature__ == '(a, b=None, *, c=42)'"
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_10)), ignore)]
|
|
|
|
fn class_with_deprecated_text_signature_and_on_new() {
|
|
|
|
#[pyclass(text_signature = "(a, b=None, *, c=42)")]
|
|
|
|
struct MyClass {}
|
|
|
|
|
|
|
|
#[pymethods]
|
|
|
|
impl MyClass {
|
|
|
|
#[new]
|
|
|
|
#[pyo3(signature = (a, b=None, *, c=42), text_signature = "(NOT, THIS, ONE)")]
|
|
|
|
fn __new__(a: i32, b: Option<i32>, c: i32) -> Self {
|
|
|
|
let _ = (a, b, c);
|
|
|
|
Self {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Python::with_gil(|py| {
|
|
|
|
let typeobj = py.get_type::<MyClass>();
|
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
typeobj,
|
|
|
|
"typeobj.__doc__ is None or typeobj.__doc__ == ''"
|
|
|
|
);
|
|
|
|
// Deprecated `#[pyclass(text_signature)]` attribute will be preferred
|
|
|
|
// for backwards-compatibility.
|
|
|
|
py_assert!(
|
|
|
|
py,
|
|
|
|
typeobj,
|
|
|
|
"typeobj.__text_signature__ == '(a, b=None, *, c=42)'"
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|