From 2ed38657347c7e965fee1368f13ad6461bf000dd Mon Sep 17 00:00:00 2001 From: JordonPhillips Date: Mon, 27 Jun 2022 17:11:34 +0200 Subject: [PATCH] Add presence tracking to structures --- designs/shapes.md | 61 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/designs/shapes.md b/designs/shapes.md index ccc4a2a55..5f5201cbe 100644 --- a/designs/shapes.md +++ b/designs/shapes.md @@ -252,18 +252,24 @@ Structures are simple python objects with `as_dict` and `from_dict` methods whose constructors only allow keyword arguments. For example: ```python + class ExampleStructure: def __init__( self, *, # This prevents positional arguments required_param: str, struct_param: OtherStructure, - optional_param: Optional[str] = None, + optional_param: Optional[str] = _DEFAULT_STR("foo"), ): self.required_param = required_param self.struct_param = struct_param self.optional_param = optional_param + # Serializers can use this if necessary to determine whether or not to + # serialize. + def is_default(self, property_name): + return property_name in self._defaulted + def as_dict(self) -> Dict: d = { "RequiredParam": self.required_param, @@ -280,6 +286,59 @@ class ExampleStructure: struct_param=OtherStructure.from_dict(d["StructParam"]) optional_param=d.get("OptionalParam"), ) + + +# We need these various default types to be able to track whether a thing was +# set explicitly or not. These will be generated for every service. +class _DEFAULT_INT(int): + pass + + +class _DEFAULT_FLOAT(float): + pass + + +class _DEFAULT_STR(str): + pass + + +class _DEFAULT_BOOL(bool): + pass + + +class _DEFAULT_TIMESTAMP(datetime): + @staticmethod + def from_timestamp(value): + return _DEFAULT_TIMESTAMP( + year=value.year, + month=value.month, + day=value.day, + hour=value.hour, + minute=value.minute, + second=value.second, + microsecond=value.microsecond, + tzinfo=value.tzinfo, + fold=value.fold, + ) + + +# We need to ensure these are immutable +class _DEFAULT_DOCUMENT: + pass + + +class _DEFAULT_LIST(list): + pass + + +_DEFAULT_VALUE = Union[ + _DEFAULT_INT, + _DEFAULT_FLOAT, + _DEFAULT_STR, + _DEFAULT_BOOL, + _DEFAULT_DOCUMENT, + _DEFAULT_LIST, +] ``` Disallowing positional arguments prevents errors from arising when future