Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SerializationStragey of Dialect does not work correctly #95

Closed
QSHolzner opened this issue Jan 10, 2023 · 1 comment
Closed

SerializationStragey of Dialect does not work correctly #95

QSHolzner opened this issue Jan 10, 2023 · 1 comment
Labels
duplicate This issue or pull request already exists

Comments

@QSHolzner
Copy link

QSHolzner commented Jan 10, 2023

  • mashumaro version: 3.3
  • Python version: 3.11
  • Operating System: Linux

Description

We ues a Dialect with special Handling for the date Type. We don't want to get it serialized to string. Therefore we use the
pass_throug serialization strategy. But this strategy is only used for the first appeareance of the configured typ.

What I Did

import datetime
from dataclasses import dataclass

from mashumaro import DataClassDictMixin, pass_through
from mashumaro.config import ADD_DIALECT_SUPPORT, BaseConfig
from mashumaro.dialect import Dialect


class MyDialect(Dialect):
    serialization_strategy = {
        datetime.date: pass_through,
    }


class MyModel(DataClassDictMixin):
    class Config(BaseConfig):
        debug = False
        dialect = MyDialect
        code_generation_options = [ADD_DIALECT_SUPPORT]


@dataclass()
class ModelA(MyModel):
    from_date: datetime.date
    to_date: datetime.date


m = ModelA(datetime.date.today(), datetime.date.today())
print(m.to_dict())

Output: {'from_date': datetime.date(2023, 1, 10), 'to_date': '2023-01-10'}

Expected Output: : {'from_date': datetime.date(2023, 1, 10), 'to_date': datetime.date(2023, 1, 10)}

I debugged into the mashumaro sourcecode and found out that in builder.py CodeBuilder you use an lru_cache() decorator for this generator function.

    @lru_cache()
    @typing.no_type_check
    def __iter_serialization_strategies(
        self, ftype: typing.Type
    ) -> typing.Iterator[SerializationStrategyValueType]:

In this case the cache does not hold an SerializationStrategyValueType Object, which is returend in subsequent calls. It holds an generator_function object. So each corresponding call of __iter_serialization_strategies with the same type parameter tries to iterate the generator_object. If this has reached its end no further value is returned.
In our case this means that the pass_through serialization strategy for date is only used for the fist time __iter_serialization_strategies is called. In all other cases the default serialization strategy for date is used - which means it is converted to iso date string.

If I omit the lru_cache decorator from __iter_serialization_strategies it works as expected.
Could you please check this.

Thank You

@Fatal1ty
Copy link
Owner

Fatal1ty commented Jan 10, 2023

It's a duplicate of #93. I published 3.3.1 version an hour ago that fixed this :)

@QSHolzner QSHolzner changed the title SerializationStragey of Dialect does not work correc SerializationStragey of Dialect does not work correctly Jan 10, 2023
@Fatal1ty Fatal1ty added the duplicate This issue or pull request already exists label Jan 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

2 participants