Skip to content
This repository has been archived by the owner on Oct 14, 2024. It is now read-only.

Commit

Permalink
Merge pull request #348 from microsoft/shem/fix_pendulum_conversion_p…
Browse files Browse the repository at this point in the history
…roblem

Fix Numeric strings being converted to Datetime objects
  • Loading branch information
baywet authored Aug 23, 2024
2 parents b4de602 + 27e639a commit 98c8b17
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 2 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).


## [1.3.1] - 2024-08-23

### Added

- Fixed 4-digit numeric strings from being parsed as Datetime objects to being parsed as strings.


## [1.3.0] - 2024-07-26

### Added
Expand Down
2 changes: 1 addition & 1 deletion kiota_serialization_json/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VERSION: str = '1.3.0'
VERSION: str = '1.3.1'
11 changes: 10 additions & 1 deletion kiota_serialization_json/json_parse_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from uuid import UUID

import pendulum
import re

from kiota_abstractions.serialization import Parsable, ParsableFactory, ParseNode

T = TypeVar("T")
Expand Down Expand Up @@ -291,6 +293,10 @@ def _assign_field_values(self, item: U) -> None:
deserialize but the model doesn't support additional data"
)

def is_four_digit_number(self, value: str) -> bool:
pattern = r'^\d{4}$'
return bool(re.match(pattern, value))

def try_get_anything(self, value: Any) -> Any:
if isinstance(value, (int, float, bool)) or value is None:
return value
Expand All @@ -300,11 +306,14 @@ def try_get_anything(self, value: Any) -> Any:
return dict(map(lambda x: (x[0], self.try_get_anything(x[1])), value.items()))
if isinstance(value, str):
try:
if self.is_four_digit_number(value):
return value

datetime_obj = pendulum.parse(value)
if isinstance(datetime_obj, pendulum.Duration):
return datetime_obj.as_timedelta()
return datetime_obj
except:
except ValueError:
pass
try:
return UUID(value)
Expand Down
18 changes: 18 additions & 0 deletions tests/unit/test_json_parse_node.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import json
from datetime import date, datetime, time, timedelta
from uuid import UUID
import pendulum

import pytest
from pendulum import DateTime, FixedTimezone
Expand Down Expand Up @@ -54,17 +55,20 @@ def test_get_float_value(value: int):
assert isinstance(result, float)
assert result == float(value)


def test_get_uuid_value():
parse_node = JsonParseNode("f58411c7-ae78-4d3c-bb0d-3f24d948de41")
result = parse_node.get_uuid_value()
assert result == UUID("f58411c7-ae78-4d3c-bb0d-3f24d948de41")


@pytest.mark.parametrize("value", ["", " ", " ", "2022-01-0"])
def test_get_datetime_value_returns_none_with_invalid_str(value: str):
parse_node = JsonParseNode(value)
result = parse_node.get_datetime_value()
assert result is None


def test_get_datetime_value():
parse_node = JsonParseNode('2022-01-27T12:59:45.596117')
result = parse_node.get_datetime_value()
Expand Down Expand Up @@ -130,6 +134,20 @@ def test_get_enum_value_for_key_not_found():
assert result is None


def test_get_anythin_does_not_convert_numeric_chars_to_datetime():
parse_node = JsonParseNode("1212")
result = parse_node.try_get_anything("1212")
assert isinstance(result, str)
assert result == "1212"


def test_get_anythin_does_convert_date_string_to_datetime():
parse_node = JsonParseNode("2023-10-05T14:48:00.000Z")
result = parse_node.try_get_anything("2023-10-05T14:48:00.000Z")
assert isinstance(result, pendulum.DateTime)
assert result == pendulum.parse("2023-10-05T14:48:00.000Z")


def test_get_object_value(user1_json):
parse_node = JsonParseNode(json.loads(user1_json))
result = parse_node.get_object_value(User)
Expand Down

0 comments on commit 98c8b17

Please # to comment.