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

Narrow down implicit boolean conversion introduced in 0.5.8 #468

Closed
wants to merge 4 commits into from

Conversation

george-zubrienko
Copy link
Collaborator

@george-zubrienko george-zubrienko commented Aug 11, 2023

Fixes #466 (at least the boolean part of it that is defo a bug)

Enhanced builtin instantiation introduced in 0.5.8 had a side effect of converting any int in json to a True boolean value if the destination field has bool type. This PR narrows allowed value range for implicit conversion to boolean

@george-zubrienko george-zubrienko changed the title WIP run matrix tests Narrow down implicit boolean conversion introduced in 0.5.8 Aug 11, 2023
@george-zubrienko george-zubrienko marked this pull request as ready for review August 11, 2023 19:59
@github-actions
Copy link

github-actions bot commented Aug 11, 2023

Coverage

Coverage Report
FileStmtsMissCoverMissing
dataclasses_json
   cfg.py51492%80, 84–86
   core.py2411096%38–41, 51, 64, 66, 81, 83, 169, 197
   mm.py2023085%33–36, 42–45, 53–56, 62–65, 88, 161–162, 167, 171, 175, 180, 184, 188, 196, 202, 207, 216, 221, 226, 235, 244–251
   stringcase.py25388%59, 76, 97
   undefined.py143299%24, 38
   utils.py1283672%11–24, 44–49, 60–64, 74, 99–100, 108–109, 124–132, 158, 177, 202
tests
   entities.py226299%229, 235
   test_annotations.py814248%50–67, 78–102, 106–122
   test_api.py142497%88, 99, 139–140
   test_str_subclass.py22195%9
   test_union.py981090%87–94, 108–115
TOTAL249814494% 

Tests Skipped Failures Errors Time
296 3 💤 0 ❌ 0 🔥 5.547s ⏱️

dataclasses_json/core.py Show resolved Hide resolved
elif _issubclass_safe(field_type, (int, float, str, bool)):
elif _issubclass_safe(field_type, bool):
# issubclass(bool, int) -> True
# thus values >1 will always convert to True in the next clause, unless intercepted
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not see >1 ints being set to true, or am I blind?

Copy link
Collaborator Author

@george-zubrienko george-zubrienko Aug 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Run code from the issue author with 0.5.14 and you will see the 1234 int field being set to True when running from_dict, if target field has bool type.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is that caught by your if-statements below?

Copy link
Collaborator Author

@george-zubrienko george-zubrienko Aug 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not caught, we just do not allow the invocation to happen in the first place, if target type is bool. field_type is the type of a dataclass field.

Copy link
Collaborator

@matt035343 matt035343 Aug 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed offline, None should become False, otherwise I am good

res = False
else:
raise ValueError(f"Value {field_value} of input type {field_type.__name__} cannot be decoded as boolean")
elif _issubclass_safe(field_type, int) or _issubclass_safe(field_type, float) or _issubclass_safe(field_type, str):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep the tuple notation here

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not correct because that method doesn't accept tuple. It was an error in original implementation

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The argument is passed directly to issubclass which accepts a tuple.
https://python-reference.readthedocs.io/en/latest/docs/functions/issubclass.html

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, however, there is one twist there: https://docs.python.org/3.11/library/functions.html#issubclass

Changed in version 3.10: classinfo can be a Union Type.

I'll see if this affects anything

@george-zubrienko
Copy link
Collaborator Author

Closing as this is too risky to integrate, will instead do a separate one for v1

@george-zubrienko george-zubrienko deleted the test-type-regression branch August 14, 2023 19:33
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

Successfully merging this pull request may close these issues.

[BUG] Type coercion since 0.5.9
2 participants