Skip to content

Commit

Permalink
v0.3.6 fix input mode issue
Browse files Browse the repository at this point in the history
  • Loading branch information
voidZXL committed Dec 2, 2023
1 parent 8954c2f commit 5f3337d
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 13 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
utype is a data types declaration & parsing library based on Python type annotations,
enforce types and constraints for classes and functions at runtime

* Version: `0.3.5` [test]
* Version: `0.3.6` [test]
* Author: [@voidZXL](https://github.com/voidZXL)
* License: Apache 2.0
* Source Code: [https://github.com/utilmeta/utype](https://github.com/utilmeta/utype)
Expand Down
2 changes: 1 addition & 1 deletion docs/en/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

utype is a data type declaration and parsing library based on Python type annotations, enforce types and constraints for classes and functions at runtime

* Version: `0.3.5` [Test]
* Version: `0.3.6` [Test]
* Author: <a href="https://github.com/voidZXL" target="_blank">@voidZXL</a>
* License: Apache 2.0
* Code Repository: <a href="https://github.com/utilmeta/utype" target="_blank">https://github.com/utilmeta/utype</a>
Expand Down
2 changes: 1 addition & 1 deletion docs/zh/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

utype 是一个基于 Python 类型注解的数据类型声明与解析库,能够在运行时根据你的声明对类与函数的参数进行解析转化

* 版本:`0.3.5`【测试】
* 版本:`0.3.6`【测试】
* 作者:<a href="https://github.com/voidZXL" target="_blank">@voidZXL</a>
* 协议:Apache 2.0
* 代码:<a href="https://github.com/utilmeta/utype" target="_blank">https://github.com/utilmeta/utype</a>
Expand Down
13 changes: 12 additions & 1 deletion tests/test_cls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from datetime import date, datetime
from typing import Any, Dict, List, Optional, Set, Tuple, Type, Union
from uuid import UUID

from decimal import Decimal
import pytest # noqa

import utype
Expand Down Expand Up @@ -476,6 +476,11 @@ class s(Schema):
assert s(a=bool).a == bool
assert s(a=int).a == int

class s(Schema):
d: Decimal = utype.Field(ge=0, round=2)

assert s(d=0.1234).d == Decimal('0.12')

def test_generic_types(self):
import sys
if sys.version_info >= (3, 8):
Expand Down Expand Up @@ -824,6 +829,12 @@ def __validate__(self):
'updated_at': {'type': 'string', 'format': 'date-time'}},
'required': ['title', 'updated_at']}

class t(Schema):
__options__ = Options(mode='a')
a: int = Field(mode='rw', no_input='w')

assert 'a' not in t()

def test_schema_dict(self, dfs):
class T(Schema):
__options__ = Options(data_first_search=dfs, addition=True)
Expand Down
11 changes: 11 additions & 0 deletions tests/test_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,13 @@ def trans_my(trans, d, t):
("-1.24", -1, False, False),
(Decimal("0.14"), 0, True, False),
(timedelta(hours=1), 3600, False, True),
('-2169770310306829106111111111111111111111111.12',
-2169770310306829106111111111111111111111111, False, False),
('-2169770310306829106111111111111111111111111',
-2169770310306829106111111111111111111111111, False, True),
# big float is already lost
# (2169770310306829106111111111111111111111111.12,
# 2169770310306829106111111111111111111111111, True, False),
([10], 10, False, True),
([10, 11], 10, False, False),
((-1.3 + 0j), -1, False, False),
Expand Down Expand Up @@ -262,6 +269,10 @@ def trans_my(trans, d, t):
datetime(2023, 3, 10, 17, 25, 8, tzinfo=timezone(timedelta(seconds=28800))),
True, True
),
('2023-10-09T20:41:59+08:00',
datetime(2023, 10, 9, 20, 41, 59, tzinfo=timezone(timedelta(seconds=28800))),
True, True
),
("2022-01-02", datetime(2022, 1, 2), True, True),
# ('10:20:30', datetime(1900, 1, 1, 10, 20, 30), True, True), # no standard behaviour
(dt.date(), datetime(2022, 1, 2), True, True),
Expand Down
2 changes: 1 addition & 1 deletion utype/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
register_transformer = TypeTransformer.registry.register


VERSION = (0, 3, 5, None)
VERSION = (0, 3, 6, None)


def _get_version():
Expand Down
6 changes: 4 additions & 2 deletions utype/parser/field.py
Original file line number Diff line number Diff line change
Expand Up @@ -808,7 +808,8 @@ def always_no_input(self, options: Options):
if callable(self.no_input):
return False
if isinstance(self.no_input, (str, list, set, tuple)):
return options.mode in self.no_input
if options.mode in self.no_input:
return True
if self.mode:
return options.mode not in self.mode
return False
Expand All @@ -822,7 +823,8 @@ def always_no_output(self, options: Options):
if callable(self.no_output):
return False
if isinstance(self.no_output, (str, list, set, tuple)):
return options.mode in self.no_output
if options.mode in self.no_output:
return True
if self.mode:
return options.mode not in self.mode
return False
Expand Down
3 changes: 2 additions & 1 deletion utype/parser/rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
NUM_TYPES = (int, float, Decimal)
SEQ_TYPES = (list, tuple, set, frozenset, deque, Iterator)
MAP_TYPES = (dict, Mapping)
TYPE_EXACT_TOLERANCE = ({int, float},)
TYPE_EXACT_TOLERANCE = ({int, float}, {int, Decimal}, (float, Decimal))

OPERATOR_NAMES = {
"&": "AllOf",
"|": "AnyOf",
Expand Down
29 changes: 28 additions & 1 deletion utype/utils/encode.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,41 @@ def from_uuid(data: uuid.UUID):

@register_encoder(decimal.Decimal)
def from_decimal(data: decimal.Decimal):
return float(data) if data.is_normal() else str(data)
if data.is_normal():
if js_unsafe(data):
return str(data)
return float(data)
return str(data)


# TODO?
# @register_encoder(float)
# def from_float(data: float):
# if js_unsafe(data):
# return str(data)
# return data
#
#
# @register_encoder(int)
# def from_int(data: int):
# if js_unsafe(data):
# return str(data)
# return data


@register_encoder(Enum)
def from_enum(en: Enum):
return en.value


MAX_SAFE_NUMBER = 9007199254740991
MIN_SAFE_NUMBER = -9007199254740991


def js_unsafe(num: Union[int, float, decimal.Decimal]):
return num > MAX_SAFE_NUMBER or num < MIN_SAFE_NUMBER


# @register_encoder(attr="__iter__")
# def from_iterable(encoder, data):
# return list(data)
19 changes: 15 additions & 4 deletions utype/utils/transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class DateFormat:
DATETIME_PS = "%a %b %d %H:%M:%S %Y"
DATETIME_GMT = "%b %d %H:%M:%S %Y"
DATE = "%Y-%m-%d"
DATE_HM = "%Y-%m-%d %H:%M"
# TIME = '%H:%M:%S'


Expand All @@ -53,7 +54,8 @@ class TypeTransformer:
DateFormat.DATETIME_HTTP,
DateFormat.DATETIME_PS,
DateFormat.DATETIME_GMT,
DateFormat.DATE
DateFormat.DATE,
DateFormat.DATE_HM
]
EPOCH = datetime(1970, 1, 1)
MS_WATERSHED = int(2e10)
Expand Down Expand Up @@ -156,6 +158,10 @@ def _attempt_from_number(self, data):
elif isinstance(data, complex) and not self.no_data_loss:
if not data.imag:
return data.real
elif not data:
# convert ''. None and others to 0
# might be a questionable feature?
return 0
return data

# ---------------------
Expand Down Expand Up @@ -395,10 +401,14 @@ def to_integer(self, data, t: Type[int] = int) -> int:
if data.lower() in self.TRUE_VALUES:
return 1

data = float(data)
data = Decimal(data)
# !!
# FOR number > 1e+16, int(float()) will not get accurate result, use decimal instead

if self.no_data_loss:
if not data.is_integer():
if not data.is_normal():
raise TypeError
if data.as_tuple().exponent:
raise TypeError

return t(data)
Expand Down Expand Up @@ -507,7 +517,8 @@ def to_datetime(self, data, t: Type[datetime] = datetime) -> datetime:
if '+' in str(data):
for f in self.DATETIME_FORMATS:
try:
val = t.strptime(data, f + ' %z')
# val = t.strptime(data, f + ' %z')
val = t.strptime(data, f + (' %z' if ' +' in str(data) else '%z'))
if is_utc:
val = val.replace(tzinfo=timezone.utc)
return val
Expand Down

0 comments on commit 5f3337d

Please sign in to comment.