diff --git a/python/pydantic_core/_pydantic_core.pyi b/python/pydantic_core/_pydantic_core.pyi index 8ed3092a9..72c5338f0 100644 --- a/python/pydantic_core/_pydantic_core.pyi +++ b/python/pydantic_core/_pydantic_core.pyi @@ -41,6 +41,7 @@ __all__ = [ 'PydanticUndefinedType', 'Some', 'to_json', + 'from_json', 'to_jsonable_python', 'list_all_errors', 'TzInfo', @@ -384,6 +385,22 @@ def to_json( JSON bytes. """ +def from_json(data: str | bytes | bytearray) -> Any: + """ + Deserialize JSON data to a Python object. + + This is effectively a faster version of [`json.loads()`][json.loads]. + + Arguments: + data: The JSON data to deserialize. + + Raises: + ValueError: If deserialization fails. + + Returns: + The deserialized Python object. + """ + def to_jsonable_python( value: Any, *, diff --git a/src/lib.rs b/src/lib.rs index 768212ead..faccd6188 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,8 @@ extern crate core; use std::sync::OnceLock; +use pyo3::exceptions::PyTypeError; +use pyo3::types::{PyByteArray, PyBytes, PyString}; use pyo3::{prelude::*, sync::GILOnceCell}; // parse this first to get access to the contained macro @@ -35,6 +37,19 @@ pub use serializers::{ }; pub use validators::{validate_core_schema, PySome, SchemaValidator}; +#[pyfunction] +pub fn from_json(py: Python, obj: &PyAny) -> PyResult { + if let Ok(py_bytes) = obj.downcast::() { + jiter::python_parse(py, py_bytes.as_bytes()) + } else if let Ok(py_str) = obj.downcast::() { + jiter::python_parse(py, py_str.to_str()?.as_bytes()) + } else if let Ok(py_byte_array) = obj.downcast::() { + jiter::python_parse(py, &py_byte_array.to_vec()) + } else { + Err(PyTypeError::new_err("Expected bytes, bytearray or str")) + } +} + pub fn get_pydantic_core_version() -> &'static str { static PYDANTIC_CORE_VERSION: OnceLock = OnceLock::new(); @@ -94,6 +109,7 @@ fn _pydantic_core(py: Python, m: &PyModule) -> PyResult<()> { m.add_class::()?; m.add_class::()?; m.add_function(wrap_pyfunction!(to_json, m)?)?; + m.add_function(wrap_pyfunction!(from_json, m)?)?; m.add_function(wrap_pyfunction!(to_jsonable_python, m)?)?; m.add_function(wrap_pyfunction!(list_all_errors, m)?)?; m.add_function(wrap_pyfunction!(validate_core_schema, m)?)?;