Skip to content

Commit

Permalink
Fixed the bug that a string was unintentionally parsed as a datetime. (
Browse files Browse the repository at this point in the history
…#171)

Co-authored-by: Ramon <p8u7wAPC5Pg9HYkkCkzA>
  • Loading branch information
ramonhagenaars authored Jun 9, 2022
1 parent 0b4b777 commit 9abbf3a
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 3 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ list_of_tuples = jsons.load(some_dict, List[Tuple[AClass, AnotherClass]])

## Recent updates

### 1.6.3

- Bugfix: a string was sometimes unintentionally parsed into a datetime.

### 1.6.2

- Bugfix: `fork_inst`s were not propagated in `default_list_deserializer` (thanks to patrickguenther).
Expand Down
6 changes: 4 additions & 2 deletions jsons/_load_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ def load(
return json_obj
if isinstance(cls, str):
cls = get_cls_from_str(cls, json_obj, fork_inst)
original_cls = cls
cls, meta_hints = _check_and_get_cls_and_meta_hints(
json_obj, cls, fork_inst, kwargs.get('_inferred_cls', False))

Expand All @@ -88,12 +89,13 @@ def load(
initial = kwargs.get('_initial', True)

kwargs_ = {
'meta_hints': meta_hints, # Overridable by kwargs.
**kwargs,
'strict': strict,
'fork_inst': fork_inst,
'attr_getters': attr_getters,
'meta_hints': meta_hints,
'_initial': False,
**kwargs
'_inferred_cls': cls is not original_cls,
}

return _do_load(json_obj, deserializer, cls, initial, **kwargs_)
Expand Down
2 changes: 1 addition & 1 deletion jsons/_package_info.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__title__ = 'jsons'
__version__ = '1.6.2'
__version__ = '1.6.3'
__author__ = 'Ramon Hagenaars'
__author_email__ = '[email protected]'
__description__ = 'For serializing Python objects to JSON (dicts) and back'
Expand Down
3 changes: 3 additions & 0 deletions jsons/deserializers/default_string.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ def default_string_deserializer(obj: str,
:param kwargs: any keyword arguments.
:return: the deserialized obj.
"""
target_is_str = cls is str and not kwargs.get('_inferred_cls')
if target_is_str:
return str(obj)
try:
result = load(obj, datetime, **kwargs)
except DeserializationError:
Expand Down
33 changes: 33 additions & 0 deletions tests/test_str.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from datetime import datetime
from unittest import TestCase

import jsons


class TestStr(TestCase):
def test_string_is_loaded_as_string(self):

class C:
def __init__(self, x: str):
self.x = x

fork = jsons.fork()
jsons.set_deserializer(lambda obj, _, **kwargs: datetime.strptime(obj, '%Y'), datetime, fork_inst=fork)
loaded = jsons.load({'x': '1025'}, C, strict=True, fork_inst=fork)

self.assertIsInstance(loaded.x, str)

def test_string_is_loaded_as_datetime(self):

class C:
def __init__(self, x):
# x has no hint, so the type will be inferred. Since x is not
# explicitly targeted as str, it may get parsed as a datetime.
# And in this test, it should.
self.x = x

fork = jsons.fork()
jsons.set_deserializer(lambda obj, _, **kwargs: datetime.strptime(obj, '%Y'), datetime, fork_inst=fork)
loaded = jsons.load({'x': '1025'}, C, strict=True, fork_inst=fork)

self.assertIsInstance(loaded.x, datetime)

0 comments on commit 9abbf3a

Please sign in to comment.