Skip to content

Commit b4335dc

Browse files
committed
Merge branch 'master' of https://github.com/RustPython/RustPython into extend-socket
2 parents bd72869 + 124f164 commit b4335dc

File tree

2 files changed

+70
-10
lines changed

2 files changed

+70
-10
lines changed

tests/snippets/json_snippet.py

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from testutils import assert_raises
22
import json
3-
from io import StringIO
3+
from io import StringIO, BytesIO
44

55
def round_trip_test(obj):
66
# serde_json and Python's json module produce slightly differently spaced
@@ -15,7 +15,7 @@ def json_dump(obj):
1515
return f.getvalue()
1616

1717
def json_load(obj):
18-
f = StringIO(obj)
18+
f = StringIO(obj) if isinstance(obj, str) else BytesIO(bytes(obj))
1919
return json.load(f)
2020

2121
assert '"string"' == json.dumps("string")
@@ -70,42 +70,92 @@ def json_load(obj):
7070
assert json.dumps({'3': 'abc'}) == json.dumps({3: 'abc'})
7171

7272
assert 1 == json.loads("1")
73+
assert 1 == json.loads(b"1")
74+
assert 1 == json.loads(bytearray(b"1"))
7375
assert 1 == json_load("1")
76+
assert 1 == json_load(b"1")
77+
assert 1 == json_load(bytearray(b"1"))
7478

7579
assert -1 == json.loads("-1")
80+
assert -1 == json.loads(b"-1")
81+
assert -1 == json.loads(bytearray(b"-1"))
7682
assert -1 == json_load("-1")
83+
assert -1 == json_load(b"-1")
84+
assert -1 == json_load(bytearray(b"-1"))
7785

7886
assert 1.0 == json.loads("1.0")
87+
assert 1.0 == json.loads(b"1.0")
88+
assert 1.0 == json.loads(bytearray(b"1.0"))
7989
assert 1.0 == json_load("1.0")
90+
assert 1.0 == json_load(b"1.0")
91+
assert 1.0 == json_load(bytearray(b"1.0"))
8092

8193
assert -1.0 == json.loads("-1.0")
94+
assert -1.0 == json.loads(b"-1.0")
95+
assert -1.0 == json.loads(bytearray(b"-1.0"))
8296
assert -1.0 == json_load("-1.0")
97+
assert -1.0 == json_load(b"-1.0")
98+
assert -1.0 == json_load(bytearray(b"-1.0"))
8399

84100
assert "str" == json.loads('"str"')
101+
assert "str" == json.loads(b'"str"')
102+
assert "str" == json.loads(bytearray(b'"str"'))
85103
assert "str" == json_load('"str"')
104+
assert "str" == json_load(b'"str"')
105+
assert "str" == json_load(bytearray(b'"str"'))
86106

87107
assert True is json.loads('true')
108+
assert True is json.loads(b'true')
109+
assert True is json.loads(bytearray(b'true'))
88110
assert True is json_load('true')
111+
assert True is json_load(b'true')
112+
assert True is json_load(bytearray(b'true'))
89113

90114
assert False is json.loads('false')
115+
assert False is json.loads(b'false')
116+
assert False is json.loads(bytearray(b'false'))
91117
assert False is json_load('false')
118+
assert False is json_load(b'false')
119+
assert False is json_load(bytearray(b'false'))
92120

93121
assert None is json.loads('null')
122+
assert None is json.loads(b'null')
123+
assert None is json.loads(bytearray(b'null'))
94124
assert None is json_load('null')
125+
assert None is json_load(b'null')
126+
assert None is json_load(bytearray(b'null'))
95127

96128
assert [] == json.loads('[]')
129+
assert [] == json.loads(b'[]')
130+
assert [] == json.loads(bytearray(b'[]'))
97131
assert [] == json_load('[]')
132+
assert [] == json_load(b'[]')
133+
assert [] == json_load(bytearray(b'[]'))
98134

99135
assert ['a'] == json.loads('["a"]')
136+
assert ['a'] == json.loads(b'["a"]')
137+
assert ['a'] == json.loads(bytearray(b'["a"]'))
100138
assert ['a'] == json_load('["a"]')
139+
assert ['a'] == json_load(b'["a"]')
140+
assert ['a'] == json_load(bytearray(b'["a"]'))
101141

102142
assert [['a'], 'b'] == json.loads('[["a"], "b"]')
143+
assert [['a'], 'b'] == json.loads(b'[["a"], "b"]')
144+
assert [['a'], 'b'] == json.loads(bytearray(b'[["a"], "b"]'))
103145
assert [['a'], 'b'] == json_load('[["a"], "b"]')
146+
assert [['a'], 'b'] == json_load(b'[["a"], "b"]')
147+
assert [['a'], 'b'] == json_load(bytearray(b'[["a"], "b"]'))
104148

105149
class String(str): pass
150+
class Bytes(bytes): pass
151+
class ByteArray(bytearray): pass
106152

107153
assert "string" == json.loads(String('"string"'))
154+
assert "string" == json.loads(Bytes(b'"string"'))
155+
assert "string" == json.loads(ByteArray(b'"string"'))
108156
assert "string" == json_load(String('"string"'))
157+
assert "string" == json_load(Bytes(b'"string"'))
158+
assert "string" == json_load(ByteArray(b'"string"'))
109159

110160
assert '"string"' == json.dumps(String("string"))
111161
assert '"string"' == json_dump(String("string"))

vm/src/stdlib/json.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
use crate::obj::objstr::PyStringRef;
1+
use crate::obj::objbytearray::PyByteArray;
2+
use crate::obj::objbytes::PyBytes;
3+
use crate::obj::objstr::PyString;
24
use crate::py_serde;
3-
use crate::pyobject::{ItemProtocol, PyObjectRef, PyResult};
5+
use crate::pyobject::{ItemProtocol, PyObjectRef, PyResult, TypeProtocol};
46
use crate::types::create_type;
57
use crate::VirtualMachine;
68
use serde_json;
@@ -18,11 +20,19 @@ pub fn json_dump(obj: PyObjectRef, fs: PyObjectRef, vm: &VirtualMachine) -> PyRe
1820
}
1921

2022
/// Implement json.loads
21-
pub fn json_loads(string: PyStringRef, vm: &VirtualMachine) -> PyResult {
22-
// TODO: Implement non-trivial deserialization case
23-
let de_result =
24-
py_serde::deserialize(vm, &mut serde_json::Deserializer::from_str(string.as_str()));
25-
23+
pub fn json_loads(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult {
24+
let de_result = match_class!(obj,
25+
s @ PyString => py_serde::deserialize(vm, &mut serde_json::Deserializer::from_str(s.as_str())),
26+
b @ PyBytes => py_serde::deserialize(vm, &mut serde_json::Deserializer::from_slice(&b)),
27+
ba @ PyByteArray => py_serde::deserialize(vm, &mut serde_json::Deserializer::from_slice(&ba.inner.borrow().elements)),
28+
obj => {
29+
let msg = format!(
30+
"the JSON object must be str, bytes or bytearray, not {}",
31+
obj.class().name
32+
);
33+
return Err(vm.new_type_error(msg));
34+
}
35+
);
2636
de_result.map_err(|err| {
2737
let module = vm
2838
.get_attribute(vm.sys_module.clone(), "modules")
@@ -42,7 +52,7 @@ pub fn json_loads(string: PyStringRef, vm: &VirtualMachine) -> PyResult {
4252

4353
pub fn json_load(fp: PyObjectRef, vm: &VirtualMachine) -> PyResult {
4454
let result = vm.call_method(&fp, "read", vec![])?;
45-
json_loads(result.downcast()?, vm)
55+
json_loads(result, vm)
4656
}
4757

4858
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {

0 commit comments

Comments
 (0)