mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Merge pull request #2245 from RustPython/coolreader18/serde_json-opt
Make serde_json an optional optimization for the json module
This commit is contained in:
6 files changed
+69
No files matched your search
Generated
+1
@@ -1778,6 +1778,7 @@ dependencies = [
|
||||
"rustyline",
|
||||
"schannel",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha-1",
|
||||
"sha2",
|
||||
"sha3",
|
||||
|
||||
@@ -107,6 +107,11 @@ from .decoder import JSONDecoder, JSONDecodeError
|
||||
from .encoder import JSONEncoder
|
||||
import codecs
|
||||
|
||||
_use_serde_json = False
|
||||
def use_serde_json(x=True):
|
||||
global _use_serde_json
|
||||
_use_serde_json = x
|
||||
|
||||
_default_encoder = JSONEncoder(
|
||||
skipkeys=False,
|
||||
ensure_ascii=True,
|
||||
@@ -354,6 +359,13 @@ def loads(s, *, cls=None, object_hook=None, parse_float=None,
|
||||
if (cls is None and object_hook is None and
|
||||
parse_int is None and parse_float is None and
|
||||
parse_constant is None and object_pairs_hook is None and not kw):
|
||||
if _use_serde_json:
|
||||
try:
|
||||
import _serde_json
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
return _serde_json.decode(s)
|
||||
return _default_decoder.decode(s)
|
||||
if cls is None:
|
||||
cls = JSONDecoder
|
||||
|
||||
@@ -27,6 +27,21 @@ class JSONDecodeError(ValueError):
|
||||
colno: The column corresponding to pos
|
||||
|
||||
"""
|
||||
# RUSTPYTHON SPECIFIC
|
||||
@classmethod
|
||||
def _from_serde(cls, msg, doc, line, col):
|
||||
pos = 0
|
||||
# 0-indexed
|
||||
line -= 1
|
||||
col -= 1
|
||||
while line > 0:
|
||||
i = doc.index('\n', pos)
|
||||
line -= 1
|
||||
pos = i
|
||||
pos += col
|
||||
return cls(msg, doc, pos)
|
||||
|
||||
|
||||
# Note that this exception is used from _json
|
||||
def __init__(self, msg, doc, pos):
|
||||
lineno = doc.count('\n', 0, pos) + 1
|
||||
|
||||
@@ -47,6 +47,7 @@ rustpython-bytecode = { path = "../bytecode", version = "0.1.2" }
|
||||
rustpython-jit = { path = "../jit", optional = true, version = "0.1.2" }
|
||||
rustpython-pylib = { path = "pylib-crate", optional = true, version = "0.1.0" }
|
||||
serde = { version = "1.0.66", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
byteorder = "1.2.6"
|
||||
regex = "1"
|
||||
rustc_version_runtime = "0.1.*"
|
||||
|
||||
@@ -26,6 +26,7 @@ mod platform;
|
||||
mod pystruct;
|
||||
mod random;
|
||||
mod re;
|
||||
mod serde_json;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub mod socket;
|
||||
mod string;
|
||||
@@ -91,6 +92,7 @@ pub fn get_module_inits() -> HashMap<String, StdlibInitFunc> {
|
||||
"_platform".to_owned() => Box::new(platform::make_module),
|
||||
"regex_crate".to_owned() => Box::new(re::make_module),
|
||||
"_random".to_owned() => Box::new(random::make_module),
|
||||
"_serde_json".to_owned() => Box::new(serde_json::make_module),
|
||||
"_string".to_owned() => Box::new(string::make_module),
|
||||
"_struct".to_owned() => Box::new(pystruct::make_module),
|
||||
"time".to_owned() => Box::new(time_module::make_module),
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
pub(crate) use _serde_json::make_module;
|
||||
|
||||
#[pymodule]
|
||||
mod _serde_json {
|
||||
use crate::common::borrow::BorrowValue;
|
||||
use crate::obj::objstr::PyStrRef;
|
||||
use crate::py_serde;
|
||||
use crate::pyobject::{PyResult, TryFromObject};
|
||||
use crate::VirtualMachine;
|
||||
|
||||
#[pyfunction]
|
||||
fn decode(s: PyStrRef, vm: &VirtualMachine) -> PyResult {
|
||||
let res = (|| -> serde_json::Result<_> {
|
||||
let mut de = serde_json::Deserializer::from_str(s.borrow_value());
|
||||
let res = py_serde::deserialize(vm, &mut de)?;
|
||||
de.end()?;
|
||||
Ok(res)
|
||||
})();
|
||||
|
||||
res.or_else(|err| {
|
||||
let decode_error = vm.try_class("json", "JSONDecodeError")?;
|
||||
let from_serde = vm.get_attribute(decode_error.into_object(), "_from_serde")?;
|
||||
let mut err_msg = err.to_string();
|
||||
let pos = err_msg.rfind(" at line ").unwrap();
|
||||
err_msg.truncate(pos);
|
||||
let decode_error = vm.invoke(
|
||||
&from_serde,
|
||||
vec![
|
||||
vm.ctx.new_str(err_msg),
|
||||
s.into_object(),
|
||||
vm.ctx.new_int(err.line()),
|
||||
vm.ctx.new_int(err.column()),
|
||||
],
|
||||
)?;
|
||||
TryFromObject::try_from_object(vm, decode_error)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user