Open nightan42643 opened 2 years ago
Hi @nightan42643,
The reason for .json
to return an object and not a dict is a bit theoretical. One could be writing a class that is not to be represented as a dict when turned into json, for example a custom collection class:
class MyCollection(list, JsonSerializable):
...
c = MyCollection((1, 2, 3))
c.json # <-- this results in a list, not a dict.
MyCollection
could not override .json
to hint the right type (list
instead of dict
) as that would be a violation of the Liskov Substitution Principle. But since JsonSerializable
hints .json
as returning an object
, it is possible to override and hint list
(or dict
in your case) since that is a subtype of object
. Liskov can rest assured.
In your case, you could override as follows:
@dataclass
class Person(JsonSerializable
.with_dump(key_transformer=KEY_TRANSFORMER_CAMELCASE)
.with_load(key_transformer=KEY_TRANSFORMER_SNAKECASE)):
first_name: str
last_name: str
@property
def json(self) -> dict[str, str]:
return JsonSerializable.json.fget(self)
Or maybe even like this:
@dataclass
class Person(JsonSerializable
.with_dump(key_transformer=KEY_TRANSFORMER_CAMELCASE)
.with_load(key_transformer=KEY_TRANSFORMER_SNAKECASE)):
first_name: str
last_name: str
json: dict[str, str] = field(init=False, repr=False, compare=False)
Alternatively, you could use typing.cast
:
arno_json = typing.cast(dict[str, str], arno.json)
I hope this helps.
@ramonhagenaars Very clear, thanks!
Hey
When I defined a
dataclass
as a subclass ofJsonSerializable
, I can access itsjson
method. Butjson
method returns an objectarno_json
is an object that lint thinks. If I want let lint think it is adict
, I need to ...I am not sure if my understanding was correct: If I use
JsonSerializable
like above, I mean create a subclass of it. In this case, the objectjson
returned always is adict
? But I must do anisInstance
judgment, it looks a little weird.Is it possible to let the
json
method return adict
not anobject
?