forked from pydantic/pydantic-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
argument_markers.rs
105 lines (91 loc) · 2.94 KB
/
argument_markers.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use pyo3::basic::CompareOp;
use pyo3::exceptions::PyNotImplementedError;
use pyo3::prelude::*;
use pyo3::sync::GILOnceCell;
use pyo3::types::{PyDict, PyTuple};
use crate::tools::safe_repr;
#[pyclass(module = "pydantic_core._pydantic_core", get_all, frozen, freelist = 100)]
#[derive(Debug, Clone)]
pub struct ArgsKwargs {
pub(crate) args: Py<PyTuple>,
pub(crate) kwargs: Option<Py<PyDict>>,
}
impl ArgsKwargs {
fn eq(&self, py: Python, other: &Self) -> PyResult<bool> {
if self.args.bind(py).eq(other.args.bind(py))? {
match (&self.kwargs, &other.kwargs) {
(Some(d1), Some(d2)) => d1.bind(py).eq(d2.bind(py)),
(None, None) => Ok(true),
_ => Ok(false),
}
} else {
Ok(false)
}
}
}
#[pymethods]
impl ArgsKwargs {
#[new]
#[pyo3(signature = (args, kwargs = None))]
fn py_new(py: Python, args: &Bound<'_, PyTuple>, kwargs: Option<&Bound<'_, PyDict>>) -> Self {
Self {
args: args.into_py(py),
kwargs: match kwargs {
Some(d) if !d.is_empty() => Some(d.to_owned().unbind()),
_ => None,
},
}
}
fn __richcmp__(&self, other: &Self, op: CompareOp, py: Python<'_>) -> PyObject {
match op {
CompareOp::Eq => match self.eq(py, other) {
Ok(b) => b.into_py(py),
Err(e) => e.into_py(py),
},
CompareOp::Ne => match self.eq(py, other) {
Ok(b) => (!b).into_py(py),
Err(e) => e.into_py(py),
},
_ => py.NotImplemented(),
}
}
pub fn __repr__(&self, py: Python) -> String {
let args = safe_repr(self.args.bind(py));
match self.kwargs {
Some(ref d) => format!("ArgsKwargs({args}, {})", safe_repr(d.bind(py))),
None => format!("ArgsKwargs({args})"),
}
}
}
static UNDEFINED_CELL: GILOnceCell<Py<PydanticUndefinedType>> = GILOnceCell::new();
#[pyclass(module = "pydantic_core._pydantic_core", frozen)]
#[derive(Debug)]
pub struct PydanticUndefinedType {}
#[pymethods]
impl PydanticUndefinedType {
#[new]
pub fn py_new(_py: Python) -> PyResult<Self> {
Err(PyNotImplementedError::new_err(
"Creating instances of \"UndefinedType\" is not supported",
))
}
#[staticmethod]
pub fn new(py: Python) -> Py<Self> {
UNDEFINED_CELL
.get_or_init(py, || PydanticUndefinedType {}.into_py(py).extract(py).unwrap())
.clone()
}
fn __repr__(&self) -> &'static str {
"PydanticUndefined"
}
fn __copy__(&self, py: Python) -> Py<Self> {
UNDEFINED_CELL.get(py).unwrap().clone()
}
#[pyo3(signature = (_memo, /))]
fn __deepcopy__(&self, py: Python, _memo: &Bound<'_, PyAny>) -> Py<Self> {
self.__copy__(py)
}
fn __reduce__(&self) -> &'static str {
"PydanticUndefined"
}
}