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

from_dict does not fail when parsing a boolean for an integer field #587

Open
mcobzarenco opened this issue Sep 3, 2024 · 1 comment
Open

Comments

@mcobzarenco
Copy link

mcobzarenco commented Sep 3, 2024

from_dict does not fail when parsing a boolean for an integer field. I would expect the following code to fail. Instead it parses a dataclass where the field a is an bool instead of a int.

import serde

@serde.serde
class Foo:
    a: int

foo = serde.from_dict(Foo, {"a": True})
assert type(foo.a) == bool

PS awesome library btw, I've long wanted something like serde-rs in Python 🙌

EDIT: booleans in Python are implemented as a subclass of integers, so actually this may be expected behaviour

@yukinarit
Copy link
Owner

Hi @mcobzarenco
Thanks for being interested in pyserde!

pyserde relies on beartype for type checking and unfortunately this is the default behavior of beartype. But yeah, you're right, I believe this is not a bug in beartype because python's bool is a subclass of int.

>>> issubclass(bool, int)
True
>>> isinstance(True, int)
True
>>> isinstance(False, int)
True

If you want to be strict about int vs. bool, I would suggest to write a beartype custom validator as a workaround. Hope it helps.

import serde
from beartype.vale import Is
from typing import Annotated

StrictInt = Annotated[int, Is[lambda v: isinstance(v, int) and not isinstance(v, bool)]]

@serde.serde
class Foo:
    a: StrictInt

# raises serde.compat.SerdeError: Method __main__.Foo.__init__() parameter a=True violates type hint typing.Annotated[int, Is[lambda v: isinstance(v, int) and (not isinstance(v, bool))]], as bool True violates validator Is[lambda v: isinstance(v, int) and (not isinstance(v, bool))]:
foo = serde.from_dict(Foo, {"a": True})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants