Closed GuyKh closed 6 months ago
Hi @GuyKh
ResponseWithDescriptor[T].from_dict
is equal to ResponseWithDescriptor.from_dict
at runtime due to type erasure (this is how generic types work in Python). In your example, you just call from_dict
, which belongs to ResponseWithDescriptor[Any]
, so to speak.
if you look at how does it work, you will see that method from_dict
is compiled and set as attribute to your class. You have only one class here — ResponseWithDescriptor
. It’s not possible to set an attribute to ResponseWithDescriptor[T]
because at runtime it’s the same type.
I can see different options for you:
1) Create a subclass of ResponseWithDescriptor
with T
replaced by something specific (see example)
2) Use ResponseWithDescriptor[T]
as a field type in another generic dataclass with parameter T
that will be parametrized later (as above)
3) Use codecs instead of mixins
from mashumaro.codecs import BasicDecoder
data_type_1_decoder = BasicDecoder(ResponseWithDescriptor[DataType1])
# create and reuse this decoder, because it’s expensive to create it from scratch each time you need it
data_type_1_decoder.decode({…})
@Fatal1ty works like a charm. I took the 3rd option, creating for every DataType a member of the class (decoder):
// Contract.py
decoder = BasicDecoder(ResponseWithDescriptor[Contracts])
And then using it as follows:
from contract import Contract, Contracts
from contract import decoder as contract_decoder
...
def get_default_contract(token: JWT, bp_number: str) -> Contract:
return _get_response_with_descriptor(token, url, contract_decoder)
...
def _get_response_with_descriptor(jwt_token: JWT, request_url: str,
decoder: BasicDecoder[ResponseWithDescriptor[T]]) -> T:
...
return decoder.decode(response.json())
Thank you for this quick response - especially with the broad option range. Truly appreciated
Description
I use this module parsing an API response where there's a DataWrapper for the content - e.g.
Where
data
field varies based on the endpoint.I modeled
responseDescriptor
:and the full response object:
but when trying to parse - it doesn't recognize the correct T:
What I Did
see above
I guess I'm doing something wrong here but what should I do otherwise?