فهرست منبع

make `json.loads` accept `bytes`

blueloveTH 2 سال پیش
والد
کامیت
a7448b7fa0
5فایلهای تغییر یافته به همراه19 افزوده شده و 7 حذف شده
  1. 7 2
      3rd/cjson/src/cJSONw.cpp
  2. 2 2
      docs/modules/json.md
  3. 1 1
      include/typings/cjson.pyi
  4. 7 2
      src/pocketpy.cpp
  5. 2 0
      tests/80_json.py

+ 7 - 2
3rd/cjson/src/cJSONw.cpp

@@ -112,8 +112,13 @@ void add_module_cjson(VM* vm){
     cJSON_InitHooks(&hooks);
 
     vm->bind_func<1>(mod, "loads", [](VM* vm, ArgsView args){
-        const Str& string = CAST(Str&, args[0]);
-        cJSON *json = cJSON_ParseWithLength(string.data, string.size);
+        std::string_view sv;
+        if(is_non_tagged_type(args[0], vm->tp_bytes)){
+            sv = PK_OBJ_GET(Bytes, args[0]).sv();
+        }else{
+            sv = CAST(Str&, args[0]).sv();
+        }
+        cJSON *json = cJSON_ParseWithLength(sv.data(), sv.size());
         if(json == NULL){
             const char* start = cJSON_GetErrorPtr();
             const char* end = start;

+ 2 - 2
docs/modules/json.md

@@ -9,11 +9,11 @@ pkpy has two JSON modules.
 
 **Their interfaces are the same.** `cjson` is faster while the built-in `json` is more stable since it was developed earlier.
 
-### `json.loads(s)`
+### `json.loads(data: str | bytes)`
 
 Decode a JSON string into a python object.
 
-### `json.dumps(obj)`
+### `json.dumps(obj) -> str`
 
 Encode a python object into a JSON string.
 

+ 1 - 1
include/typings/cjson.pyi

@@ -1,2 +1,2 @@
-def loads(string: str) -> object: ...
+def loads(data: str | bytes) -> object: ...
 def dumps(obj: object) -> str: ...

+ 7 - 2
src/pocketpy.cpp

@@ -1509,8 +1509,13 @@ void add_module_sys(VM* vm){
 void add_module_json(VM* vm){
     PyObject* mod = vm->new_module("json");
     vm->bind_func<1>(mod, "loads", [](VM* vm, ArgsView args) {
-        const Str& expr = CAST(Str&, args[0]);
-        CodeObject_ code = vm->compile(expr, "<json>", JSON_MODE);
+        std::string_view sv;
+        if(is_non_tagged_type(args[0], vm->tp_bytes)){
+            sv = PK_OBJ_GET(Bytes, args[0]).sv();
+        }else{
+            sv = CAST(Str&, args[0]).sv();
+        }
+        CodeObject_ code = vm->compile(sv, "<json>", JSON_MODE);
         return vm->_exec(code, vm->top_frame()->_module);
     });
 

+ 2 - 0
tests/80_json.py

@@ -29,6 +29,8 @@ assert json.loads("true") == True
 assert json.loads("false") == False
 assert json.loads("{}") == {}
 
+assert json.loads(b"false") == False
+
 _j = json.dumps(a)
 _a = json.loads(_j)