From 772c1720f575f8e03a9b5cbc6d948d6e90105b45 Mon Sep 17 00:00:00 2001 From: Nijat Date: Sun, 5 Nov 2023 01:43:25 -0400 Subject: [PATCH] Default to str() for Unknown objects when using OPT_NON_STR_KEYS --- src/serialize/per_type/dict.rs | 14 ++++++++++++-- test/test_non_str_keys.py | 18 +++++------------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/serialize/per_type/dict.rs b/src/serialize/per_type/dict.rs index 89f7ca00..4790b9b9 100644 --- a/src/serialize/per_type/dict.rs +++ b/src/serialize/per_type/dict.rs @@ -346,14 +346,24 @@ impl DictNonStrKey { Ok(CompactString::from(uni.unwrap())) } } + ObType::Unknown => { + let key_str_obj = ffi!(PyObject_Str(key)); + debug_assert!(ffi!(Py_REFCNT(key_str_obj)) >= 2); + if unlikely!(key_str_obj.is_null()) { + Err(SerializeError::DictKeyInvalidType) + } else { + let ret = Self::pyobject_to_string(key_str_obj, opts); + ffi!(Py_DECREF(key_str_obj)); + ret + } + } ObType::Tuple | ObType::NumpyScalar | ObType::NumpyArray | ObType::Dict | ObType::List | ObType::Dataclass - | ObType::Fragment - | ObType::Unknown => Err(SerializeError::DictKeyInvalidType), + | ObType::Fragment => Err(SerializeError::DictKeyInvalidType), } } } diff --git a/test/test_non_str_keys.py b/test/test_non_str_keys.py index fad13486..7cdec4b1 100644 --- a/test/test_non_str_keys.py +++ b/test/test_non_str_keys.py @@ -244,13 +244,6 @@ def test_dict_keys_str(self): orjson.dumps({"1": True}, option=orjson.OPT_NON_STR_KEYS) == b'{"1":true}' ) - def test_dict_keys_type(self): - class Obj: - a: str - - val = Obj() - with pytest.raises(orjson.JSONEncodeError): - orjson.dumps({val: True}, option=orjson.OPT_NON_STR_KEYS) @pytest.mark.skipif(numpy is None, reason="numpy is not installed") def test_dict_keys_array(self): @@ -290,11 +283,8 @@ def test_dict_keys_tuple(self): with pytest.raises(orjson.JSONEncodeError): orjson.dumps(obj, option=orjson.OPT_NON_STR_KEYS) - def test_dict_keys_unknown(self): - with pytest.raises(orjson.JSONEncodeError): - orjson.dumps({frozenset(): True}, option=orjson.OPT_NON_STR_KEYS) - def test_dict_keys_no_str_call(self): + def test_dict_keys_str_call(self): class Obj: a: str @@ -302,5 +292,7 @@ def __str__(self): return "Obj" val = Obj() - with pytest.raises(orjson.JSONEncodeError): - orjson.dumps({val: True}, option=orjson.OPT_NON_STR_KEYS) + assert ( + orjson.dumps({val: True}, option=orjson.OPT_NON_STR_KEYS) == b'{"Obj":true}' + ) +