From 936fb5c4b4b21f978a57f5db1f3a5e811f567236 Mon Sep 17 00:00:00 2001 From: turulomio Date: Mon, 11 Dec 2023 18:48:13 +0100 Subject: [PATCH] Fixed bug with decimals and date (#31) --- pydicts/casts.py | 4 ++++ pydicts/myjsonencoder.py | 26 +++++++++++--------------- pydicts/tests/test_casts.py | 9 +++++++-- pydicts/tests/test_myjsonencoder.py | 6 +++++- 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/pydicts/casts.py b/pydicts/casts.py index d589915..e8a4212 100644 --- a/pydicts/casts.py +++ b/pydicts/casts.py @@ -357,6 +357,8 @@ def str2dtnaive(s, format): s=f"{date.today().year} {s}" return datetime.strptime(s, '%Y %b %d %H:%M:%S') if format=="JsIso": #2021-08-21T06:27:38.294 + if s.endswith("Z"): + return None s=s.replace("T"," ") dtnaive=str2dtnaive(s,"%Y-%m-%d %H:%M:%S.") return dtnaive @@ -379,6 +381,8 @@ def str2dtaware(s, format, tz_name='UTC'): dt=dt+timedelta(microseconds=micro) return dtaware_changes_tz(dt, tz_name) if format=="JsUtcIso": #2021-08-21T06:27:38.294Z + if not "Z" in s: + return None s=s.replace("T"," ").replace("Z","") dtnaive=str2dtnaive(s,"%Y-%m-%d %H:%M:%S.") dtaware_utc=dtnaive2dtaware(dtnaive, 'UTC') diff --git a/pydicts/myjsonencoder.py b/pydicts/myjsonencoder.py index 646638e..e2e7050 100644 --- a/pydicts/myjsonencoder.py +++ b/pydicts/myjsonencoder.py @@ -6,9 +6,9 @@ # Forma en que debe parsearse los Decimals class DecimalsWay: - Decimal=1 #Uses a String with decimal to detect decimals - String=2 - Float=3 + DecimalString=1 #Uses a String with decimal to detect decimals "Decimal('12.122')" + String=2 #"12.122" + Float=3 # 12.122 ## Usa class MyJSONEncoder(JSONEncoder): @@ -98,7 +98,7 @@ def MyJSONEncoderDecimalsAsFloat_dumps(r, indent=4): def MyJSONEncoder_loads(s): def hooks_MyJSONEncoder(iter_value): - return hooks(iter_value, DecimalsWay.Decimal) + return hooks(iter_value, DecimalsWay.DecimalString) ############################## return loads(s, object_hook=hooks_MyJSONEncoder) @@ -122,21 +122,16 @@ def hooks(iter_value, decimals_way): """ def get_date(s): - try: - return date.fromisoformat(s) - except: - return None + return casts.str2date(s) def get_dtaware(s): try: - print(s, casts.str2dtaware(s,"JsUtcIso")) return casts.str2dtaware(s,"JsUtcIso") except: return None def get_dtnaive(s): try: - print(s, casts.str2dtnaive(s,"JsIso")) return casts.str2dtnaive(s,"JsIso") except: return None @@ -189,16 +184,17 @@ def get_bytes(s): def get_Decimal(s): try: - return eval(s) + return casts.str2decimal(s) except: return None def guess_cast(o, decimal_way): - if decimal_way==DecimalsWay.Decimal: - r=get_Decimal(o) - if r is not None: - return r + if decimal_way==DecimalsWay.DecimalString: + if o.__class__==str and o.startswith("Decimal("): + r=get_Decimal(o) + if r is not None: + return str(r) r=get_date(o) if r is not None: diff --git a/pydicts/tests/test_casts.py b/pydicts/tests/test_casts.py index 403ddea..c7d0b02 100644 --- a/pydicts/tests/test_casts.py +++ b/pydicts/tests/test_casts.py @@ -183,8 +183,9 @@ def test_time2str(): assert casts.time2str(time_, "HH:MM:SS")=="09:05:54" def test_str2date(): -# allowed=["YYYY-MM-DD", "DD/MM/YYYY", "DD.MM.YYYY", "DD/MM"] - + assert casts.str2date(None)==None + assert casts.str2date("2023")==None + assert casts.str2date(2023)==None assert casts.str2date("2023-11-26")==date(2023, 11, 26) assert casts.str2date("2023-11-26", "YYYY-MM-DD")==date(2023, 11, 26) assert casts.str2date("26/11/2023", "DD/MM/YYYY")==date(2023, 11, 26) @@ -199,6 +200,7 @@ def test_str2dtnaive(): # assert casts.str2dtnaive("20231126 1705", "%Y%m%d %H%M")==datetime(2023, 11, 26, 17, 5, 5) assert casts.str2dtnaive("202311261705", "%Y%m%d%H%M")==datetime(2023, 11, 26, 17, 5) assert casts.str2dtnaive("2023-11-26T17:05:05.123456", "JsIso")==datetime(2023, 11, 26, 17, 5, 5, 123456) + assert casts.str2dtnaive("2023-11-26T17:05:05.123456Z", "JsIso")==None assert casts.str2dtnaive("2023-11-26T17:05:05", "JsIso")==datetime(2023, 11, 26, 17, 5, 5) @@ -206,7 +208,10 @@ def test_str2dtaware(): # allowed=["%Y-%m-%d %H:%M:%S%z","%Y-%m-%d %H:%M:%S.%z", "JsUtcIso"] #assert casts.str2dtaware("2023-11-26", "%Y-%m-%d")==datetime(2023, 11, 26, tzinfo=ZoneInfo('UTC')) #assert casts.str2dtaware("202311261705", "%Y%m%d%H%M")==datetime(2023, 11, 26, 17, 5) + + assert casts.str2dtaware("2023-11-26T17:05:05Z", "YYYY-mm-dd")==None assert casts.str2dtaware("2023-11-26T17:05:05Z", "JsUtcIso")==datetime(2023, 11, 26, 17, 5, 5, tzinfo=ZoneInfo('UTC')) + assert casts.str2dtaware("2023-11-26T17:05:05", "JsUtcIso")==None ### epoch is the time from 1,1,1970 in UTC ### return now(timezone(self.name)) diff --git a/pydicts/tests/test_myjsonencoder.py b/pydicts/tests/test_myjsonencoder.py index 8d2bd49..9e71060 100644 --- a/pydicts/tests/test_myjsonencoder.py +++ b/pydicts/tests/test_myjsonencoder.py @@ -14,9 +14,13 @@ d["Bytes"]=b"Byte array" d["Decimal"]=Decimal("12.12123414") + def test_myjsonencoder(): + print(d) json_string=myjsonencoder.MyJSONEncoder_dumps(d) + print("Antes", json_string) json_=myjsonencoder.MyJSONEncoder_loads(json_string) + print("Despues", json_) assert json_["None"]==d["None"] assert json_["Integer"]==d["Integer"] assert json_["Float"]==d["Float"] @@ -24,7 +28,7 @@ def test_myjsonencoder(): assert json_["Datetime"]==d["Datetime"] assert json_["Datetime aware"]==d["Datetime aware"] assert json_["Bytes"]==d["Bytes"] - assert json_["Decimal"]==d["Decimal"] + assert json_["Decimal"]==repr(d["Decimal"]) # assert json_["Time"]==d["Time"] # assert json_["Timedelta"]==d["Timedelta"]