add NonPositive/NonNegative Int/Float (#1987)

fix #1975

* add NonPositive/NonNegative Int/Float

* delete data.json file
This commit is contained in:
Matthew Davis
2020-11-30 03:07:51 +11:00
committed by GitHub
parent 31bc2435d7
commit 9cb7ca744b
7 changed files with 117 additions and 16 deletions
+1
View File
@@ -0,0 +1 @@
Add `NonNegativeInt`, `NonPositiveInt`, `NonNegativeFloat`, `NonPositiveFloat`
+28
View File
@@ -382,6 +382,20 @@ table = [
'JSON Schema Validation',
''
],
[
'NonNegativeInt',
'integer',
{'minimum': 0},
'JSON Schema Validation',
''
],
[
'NonPositiveInt',
'integer',
{'maximum': 0},
'JSON Schema Validation',
''
],
[
'ConstrainedFloat',
'number',
@@ -413,6 +427,20 @@ table = [
'JSON Schema Validation',
''
],
[
'NonNegativeFloat',
'number',
{'minimum': 0},
'JSON Schema Validation',
''
],
[
'NonPositiveFloat',
'number',
{'maximum': 0},
'JSON Schema Validation',
''
],
[
'ConstrainedDecimal',
'number',
+8
View File
@@ -6,6 +6,10 @@ from pydantic import (
NegativeInt,
PositiveFloat,
PositiveInt,
NonNegativeFloat,
NonNegativeInt,
NonPositiveFloat,
NonPositiveInt,
conbytes,
condecimal,
confloat,
@@ -29,12 +33,16 @@ class Model(BaseModel):
mod_int: conint(multiple_of=5)
pos_int: PositiveInt
neg_int: NegativeInt
non_neg_int: NonNegativeInt
non_pos_int: NonPositiveInt
big_float: confloat(gt=1000, lt=1024)
unit_interval: confloat(ge=0, le=1)
mod_float: confloat(multiple_of=0.5)
pos_float: PositiveFloat
neg_float: NegativeFloat
non_neg_float: NonNegativeFloat
non_pos_float: NonPositiveFloat
short_list: conlist(int, min_items=1, max_items=4)
short_set: conset(int, min_items=1, max_items=4)
+4
View File
@@ -76,10 +76,14 @@ __all__ = [
'conint',
'PositiveInt',
'NegativeInt',
'NonNegativeInt',
'NonPositiveInt',
'ConstrainedFloat',
'confloat',
'PositiveFloat',
'NegativeFloat',
'NonNegativeFloat',
'NonPositiveFloat',
'ConstrainedDecimal',
'condecimal',
'UUID1',
+20
View File
@@ -63,10 +63,14 @@ __all__ = [
'conint',
'PositiveInt',
'NegativeInt',
'NonNegativeInt',
'NonPositiveInt',
'ConstrainedFloat',
'confloat',
'PositiveFloat',
'NegativeFloat',
'NonNegativeFloat',
'NonPositiveFloat',
'ConstrainedDecimal',
'condecimal',
'UUID1',
@@ -379,6 +383,14 @@ class NegativeInt(ConstrainedInt):
lt = 0
class NonPositiveInt(ConstrainedInt):
le = 0
class NonNegativeInt(ConstrainedInt):
ge = 0
class StrictInt(ConstrainedInt):
strict = True
@@ -440,6 +452,14 @@ class NegativeFloat(ConstrainedFloat):
lt = 0
class NonPositiveFloat(ConstrainedFloat):
le = 0
class NonNegativeFloat(ConstrainedFloat):
ge = 0
class StrictFloat(ConstrainedFloat):
strict = True
+8
View File
@@ -42,6 +42,10 @@ from pydantic.types import (
NoneBytes,
NoneStr,
NoneStrBytes,
NonNegativeFloat,
NonNegativeInt,
NonPositiveFloat,
NonPositiveInt,
PositiveFloat,
PositiveInt,
PyObject,
@@ -754,6 +758,8 @@ def test_secret_types(field_type, inner_type):
(conint(multiple_of=5), {'multipleOf': 5}),
(PositiveInt, {'exclusiveMinimum': 0}),
(NegativeInt, {'exclusiveMaximum': 0}),
(NonNegativeInt, {'minimum': 0}),
(NonPositiveInt, {'maximum': 0}),
],
)
def test_special_int_types(field_type, expected_schema):
@@ -780,6 +786,8 @@ def test_special_int_types(field_type, expected_schema):
(confloat(multiple_of=5), {'multipleOf': 5}),
(PositiveFloat, {'exclusiveMinimum': 0}),
(NegativeFloat, {'exclusiveMaximum': 0}),
(NonNegativeFloat, {'minimum': 0}),
(NonPositiveFloat, {'maximum': 0}),
(ConstrainedDecimal, {}),
(condecimal(gt=5, lt=10), {'exclusiveMinimum': 5, 'exclusiveMaximum': 10}),
(condecimal(ge=5, le=10), {'minimum': 5, 'maximum': 10}),
+48 -16
View File
@@ -43,6 +43,10 @@ from pydantic import (
NameEmail,
NegativeFloat,
NegativeInt,
NonNegativeFloat,
NonNegativeInt,
NonPositiveFloat,
NonPositiveInt,
PositiveFloat,
PositiveInt,
PyObject,
@@ -1178,15 +1182,17 @@ def test_int_validation():
class Model(BaseModel):
a: PositiveInt = None
b: NegativeInt = None
c: conint(gt=4, lt=10) = None
d: conint(ge=0, le=10) = None
e: conint(multiple_of=5) = None
c: NonNegativeInt = None
d: NonPositiveInt = None
e: conint(gt=4, lt=10) = None
f: conint(ge=0, le=10) = None
g: conint(multiple_of=5) = None
m = Model(a=5, b=-5, c=5, d=0, e=25)
assert m == {'a': 5, 'b': -5, 'c': 5, 'd': 0, 'e': 25}
m = Model(a=5, b=-5, c=0, d=0, e=5, f=0, g=25)
assert m == {'a': 5, 'b': -5, 'c': 0, 'd': 0, 'e': 5, 'f': 0, 'g': 25}
with pytest.raises(ValidationError) as exc_info:
Model(a=-5, b=5, c=-5, d=11, e=42)
Model(a=-5, b=5, c=-5, d=5, e=-5, f=11, g=42)
assert exc_info.value.errors() == [
{
'loc': ('a',),
@@ -1202,18 +1208,30 @@ def test_int_validation():
},
{
'loc': ('c',),
'msg': 'ensure this value is greater than or equal to 0',
'type': 'value_error.number.not_ge',
'ctx': {'limit_value': 0},
},
{
'loc': ('d',),
'msg': 'ensure this value is less than or equal to 0',
'type': 'value_error.number.not_le',
'ctx': {'limit_value': 0},
},
{
'loc': ('e',),
'msg': 'ensure this value is greater than 4',
'type': 'value_error.number.not_gt',
'ctx': {'limit_value': 4},
},
{
'loc': ('d',),
'loc': ('f',),
'msg': 'ensure this value is less than or equal to 10',
'type': 'value_error.number.not_le',
'ctx': {'limit_value': 10},
},
{
'loc': ('e',),
'loc': ('g',),
'msg': 'ensure this value is a multiple of 5',
'type': 'value_error.number.not_multiple',
'ctx': {'multiple_of': 5},
@@ -1225,15 +1243,17 @@ def test_float_validation():
class Model(BaseModel):
a: PositiveFloat = None
b: NegativeFloat = None
c: confloat(gt=4, lt=12.2) = None
d: confloat(ge=0, le=9.9) = None
e: confloat(multiple_of=0.5) = None
c: NonNegativeFloat = None
d: NonPositiveFloat = None
e: confloat(gt=4, lt=12.2) = None
f: confloat(ge=0, le=9.9) = None
g: confloat(multiple_of=0.5) = None
m = Model(a=5.1, b=-5.2, c=5.3, d=9.9, e=2.5)
assert m.dict() == {'a': 5.1, 'b': -5.2, 'c': 5.3, 'd': 9.9, 'e': 2.5}
m = Model(a=5.1, b=-5.2, c=0, d=0, e=5.3, f=9.9, g=2.5)
assert m.dict() == {'a': 5.1, 'b': -5.2, 'c': 0, 'd': 0, 'e': 5.3, 'f': 9.9, 'g': 2.5}
with pytest.raises(ValidationError) as exc_info:
Model(a=-5.1, b=5.2, c=-5.3, d=9.91, e=4.2)
Model(a=-5.1, b=5.2, c=-5.1, d=5.1, e=-5.3, f=9.91, g=4.2)
assert exc_info.value.errors() == [
{
'loc': ('a',),
@@ -1249,18 +1269,30 @@ def test_float_validation():
},
{
'loc': ('c',),
'msg': 'ensure this value is greater than or equal to 0',
'type': 'value_error.number.not_ge',
'ctx': {'limit_value': 0},
},
{
'loc': ('d',),
'msg': 'ensure this value is less than or equal to 0',
'type': 'value_error.number.not_le',
'ctx': {'limit_value': 0},
},
{
'loc': ('e',),
'msg': 'ensure this value is greater than 4',
'type': 'value_error.number.not_gt',
'ctx': {'limit_value': 4},
},
{
'loc': ('d',),
'loc': ('f',),
'msg': 'ensure this value is less than or equal to 9.9',
'type': 'value_error.number.not_le',
'ctx': {'limit_value': 9.9},
},
{
'loc': ('e',),
'loc': ('g',),
'msg': 'ensure this value is a multiple of 0.5',
'type': 'value_error.number.not_multiple',
'ctx': {'multiple_of': 0.5},