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:
Jeong YunWon authored and GitHub committed 2020-09-30 10:49:05 +09:00
commit 3b2db89d1e
6 files changed
+69

No files matched your search

Generated
+1
View File
@@ -1778,6 +1778,7 @@ dependencies = [
"rustyline",
"schannel",
"serde",
"serde_json",
"sha-1",
"sha2",
"sha3",
+12
View File
@@ -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
+15
View File
@@ -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
+1
View File
@@ -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.*"
+2
View File
@@ -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),
+38
View File
@@ -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)
})
}
}