-
Notifications
You must be signed in to change notification settings - Fork 220
Open
Description
Is this in or out of scope?
# requires Python 3.7
from dataclasses import dataclass
from voluptuous import Schema, Object, All, Range
from voluptuous.schema_builder import PREVENT_EXTRA
@dataclass
class InventoryItem:
name: str
unit_price: float
quantity_on_hand: int = 0
def total_cost(self) -> float:
return self.unit_price * self.quantity_on_hand
class DataClassSchema(Schema):
@staticmethod
def dataClassSchema(x):
return {
fieldName: fieldValues.type
for fieldName, fieldValues in (x.__dataclass_fields__).items()
}
@staticmethod
def merge_constraints_of_key(a, b):
return All(a, b)
def merge_constraints_of_schema(self, dclsSchema, addSchema):
result = dict()
for k, v in dclsSchema.items():
if k in addSchema:
result[k] = self.merge_constraints_of_key(v, addSchema[k])
else:
result[k] = v
return result
def __init__(self, dcls, schema, required=False, extra=PREVENT_EXTRA):
return super(DataClassSchema, self).__init__(
Object(
self.merge_constraints_of_schema(self.dataClassSchema(dcls), schema),
cls=dcls,
),
required,
extra,
)
s1 = Schema(
Object(
{"name": str, "unit_price": All(float, Range(min=5)), "quantity_on_hand": int}
),
InventoryItem,
)
s2 = DataClassSchema(InventoryItem, {"unit_price": Range(min=5)})
# assert s1 == s2 # fails due to bug: Schema({'a': All(float)}) == Schema({'a': All(float)})
# however, s1 and s2 operate equivalently:
# s1(InventoryItem('nails', 3.33, 4))
# s2(InventoryItem('nails', 3.33, 4))Metadata
Metadata
Assignees
Labels
No labels