mirror of
https://github.com/kennethreitz/pydantic.git
synced 2026-06-05 23:00:18 +00:00
add NonPositive/NonNegative Int/Float (#1987)
fix #1975 * add NonPositive/NonNegative Int/Float * delete data.json file
This commit is contained in:
@@ -0,0 +1 @@
|
||||
Add `NonNegativeInt`, `NonPositiveInt`, `NonNegativeFloat`, `NonPositiveFloat`
|
||||
Vendored
+28
@@ -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',
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -76,10 +76,14 @@ __all__ = [
|
||||
'conint',
|
||||
'PositiveInt',
|
||||
'NegativeInt',
|
||||
'NonNegativeInt',
|
||||
'NonPositiveInt',
|
||||
'ConstrainedFloat',
|
||||
'confloat',
|
||||
'PositiveFloat',
|
||||
'NegativeFloat',
|
||||
'NonNegativeFloat',
|
||||
'NonPositiveFloat',
|
||||
'ConstrainedDecimal',
|
||||
'condecimal',
|
||||
'UUID1',
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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},
|
||||
|
||||
Reference in New Issue
Block a user