Π·Π΅ΡΠΊΠ°Π»ΠΎ ΠΈΠ· https://github.com/microsoft/electionguard-python.git
π Resolve datetime deserialization issue (#627)
* π¦ Add python-dateutil * β Fix datetime in serialize and tests
This commit is contained in:
Π ΠΎΠ΄ΠΈΡΠ΅Π»Ρ
40e68eeadf
ΠΠΎΠΌΠΌΠΈΡ
7c116ec6ad
|
@ -1258,7 +1258,7 @@ testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.
|
|||
name = "python-dateutil"
|
||||
version = "2.8.2"
|
||||
description = "Extensions to the standard Python datetime module"
|
||||
category = "dev"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
|
||||
|
||||
|
@ -1399,7 +1399,7 @@ jeepney = ">=0.6"
|
|||
name = "six"
|
||||
version = "1.16.0"
|
||||
description = "Python 2 and 3 compatibility utilities"
|
||||
category = "dev"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
|
||||
|
@ -1503,6 +1503,14 @@ rfc3986 = ">=1.4.0"
|
|||
rich = ">=12.0.0"
|
||||
urllib3 = ">=1.26.0"
|
||||
|
||||
[[package]]
|
||||
name = "types-python-dateutil"
|
||||
version = "2.8.14"
|
||||
description = "Typing stubs for python-dateutil"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.1.1"
|
||||
|
@ -1621,7 +1629,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-
|
|||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.9.5"
|
||||
content-hash = "9bd2777ce600469494106f880daad6ce7feb021f972be4dc84882cd6afbab16e"
|
||||
content-hash = "c12ec8697662c27437657ed080232d15294f4556c959bca91343d97275da7594"
|
||||
|
||||
[metadata.files]
|
||||
appnope = [
|
||||
|
@ -2566,6 +2574,10 @@ twine = [
|
|||
{file = "twine-4.0.0-py3-none-any.whl", hash = "sha256:6f7496cf14a3a8903474552d5271c79c71916519edb42554f23f42a8563498a9"},
|
||||
{file = "twine-4.0.0.tar.gz", hash = "sha256:817aa0c0bdc02a5ebe32051e168e23c71a0608334e624c793011f120dbbc05b7"},
|
||||
]
|
||||
types-python-dateutil = [
|
||||
{file = "types-python-dateutil-2.8.14.tar.gz", hash = "sha256:367c1ffa1a52a4b2a534c9b30b40b01f2b7f2ea47a97fd821f6c76d1c7ae3129"},
|
||||
{file = "types_python_dateutil-2.8.14-py3-none-any.whl", hash = "sha256:6ac40f66cf23a5200bd179b78d6be52e81a7750e4f8e45d7cfaf3ddda60ff01f"},
|
||||
]
|
||||
typing-extensions = [
|
||||
{file = "typing_extensions-4.1.1-py3-none-any.whl", hash = "sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2"},
|
||||
{file = "typing_extensions-4.1.1.tar.gz", hash = "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42"},
|
||||
|
|
|
@ -40,6 +40,8 @@ psutil = ">=5.7.2"
|
|||
pydantic = "1.9.0"
|
||||
click = "^8.1.0"
|
||||
dacite = "^1.6.0"
|
||||
python-dateutil = "^2.8.2"
|
||||
types-python-dateutil = "^2.8.14"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
atomicwrites = "*"
|
||||
|
|
|
@ -6,9 +6,12 @@ import os
|
|||
from pathlib import Path
|
||||
from typing import Any, List, Type, TypeVar, Union
|
||||
|
||||
|
||||
from dacite import Config, from_dict
|
||||
from dateutil import parser
|
||||
from pydantic.json import pydantic_encoder
|
||||
from pydantic.tools import schema_json_of, parse_raw_as
|
||||
from pydantic.tools import schema_json_of
|
||||
|
||||
|
||||
from .big_integer import BigInteger
|
||||
from .ballot_box import BallotBoxState
|
||||
|
@ -41,7 +44,7 @@ _config = Config(
|
|||
VoteVariationType,
|
||||
ProofUsage,
|
||||
],
|
||||
type_hooks={datetime: datetime.fromisoformat},
|
||||
type_hooks={datetime: parser.parse},
|
||||
)
|
||||
|
||||
|
||||
|
@ -103,8 +106,6 @@ def construct_path(
|
|||
def from_raw(type_: Type[_T], raw: Union[str, bytes]) -> _T:
|
||||
"""Deserialize raw json string as type."""
|
||||
|
||||
if type_ is datetime:
|
||||
return parse_raw_as(type_, raw)
|
||||
return from_dict(type_, json.loads(raw), _config)
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
|
||||
from tests.base_test_case import BaseTestCase
|
||||
|
@ -55,16 +56,31 @@ class TestManifest(BaseTestCase):
|
|||
def test_manifest_hash_is_consistent_regardless_of_format(self) -> None:
|
||||
|
||||
# Act
|
||||
@dataclass
|
||||
class DateType:
|
||||
"""Temp date class for testing"""
|
||||
|
||||
date: datetime
|
||||
|
||||
subject1 = election_factory.get_simple_manifest_from_file()
|
||||
subject1.start_date = from_raw(datetime, '"2020-03-01T08:00:00-05:00"')
|
||||
subject1.start_date = from_raw(
|
||||
DateType, '{"date":"2020-03-01T08:00:00-05:00"}'
|
||||
).date
|
||||
|
||||
subject2 = election_factory.get_simple_manifest_from_file()
|
||||
subject2.start_date = from_raw(datetime, '"2020-03-01T13:00:00-00:00"')
|
||||
subject2.start_date = from_raw(
|
||||
DateType, '{"date":"2020-03-01T13:00:00-00:00"}'
|
||||
).date
|
||||
|
||||
subject3 = election_factory.get_simple_manifest_from_file()
|
||||
subject3.start_date = from_raw(datetime, '"2020-03-01T13:00:00.000-00:00"')
|
||||
subject3.start_date = from_raw(
|
||||
DateType, '{"date":"2020-03-01T13:00:00.000-00:00"}'
|
||||
).date
|
||||
|
||||
subjects = [subject1, subject2, subject3]
|
||||
subject4 = election_factory.get_simple_manifest_from_file()
|
||||
subject4.start_date = from_raw(DateType, '{"date":"2020-03-01T13:00:00Z"}').date
|
||||
|
||||
subjects = [subject1, subject2, subject3, subject4]
|
||||
|
||||
# Assert
|
||||
hashes = [subject.crypto_hash() for subject in subjects]
|
||||
|
|
ΠΠ°Π³ΡΡΠ·ΠΊΠ°β¦
Π‘ΡΡΠ»ΠΊΠ° Π² Π½ΠΎΠ²ΠΎΠΉ Π·Π°Π΄Π°ΡΠ΅