Skip to content

Commit 7581009

Browse files
authored
Deterministic default for datetime strings. (#26)
1 parent b76e14c commit 7581009

2 files changed

Lines changed: 35 additions & 1 deletion

File tree

src/py_avro_schema/_schemas.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,15 @@ def _schema_obj(py_type: Type, namespace: Optional[str] = None, options: Option
255255
_UUID_PATTERN = re.compile(r"^[0-9a-f]{8}(?:-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})?$", re.IGNORECASE)
256256

257257

258+
def is_valid_datetime(string: str) -> bool:
259+
"""Checks is a given string is a valid datetime timestamp"""
260+
try:
261+
datetime.datetime.fromisoformat(string)
262+
return True
263+
except ValueError:
264+
return False
265+
266+
258267
def validate_name(value: str) -> str:
259268
"""Validate (and return) whether a given string is a valid Avro name"""
260269
if not re.match(_AVRO_NAME_PATTERN, value):
@@ -1186,7 +1195,7 @@ def data(self, names: NamesType) -> JSONObj:
11861195
if (
11871196
Option.DETERMINISTIC_DEFAULTS in self.options
11881197
and isinstance(default_value, str)
1189-
and _UUID_PATTERN.match(default_value)
1198+
and (_UUID_PATTERN.match(default_value) or is_valid_datetime(default_value))
11901199
):
11911200
default_value = ""
11921201
field_data["default"] = default_value

tests/test_dataclass.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,3 +941,28 @@ class PyType:
941941
],
942942
}
943943
assert_schema(PyType, expected, options=pas.Option.DETERMINISTIC_DEFAULTS)
944+
945+
946+
def test_deterministic_defaults_timestamp():
947+
948+
def timestamp_millis() -> str:
949+
microsecond_time = datetime.datetime.now(tz=datetime.UTC)
950+
microsecond_time = microsecond_time.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
951+
return microsecond_time[:-4] + microsecond_time[-1]
952+
953+
@dataclasses.dataclass
954+
class PyType:
955+
time: str = dataclasses.field(default_factory=lambda: timestamp_millis())
956+
957+
expected = {
958+
"type": "record",
959+
"name": "PyType",
960+
"fields": [
961+
{
962+
"name": "time",
963+
"type": "string",
964+
"default": "",
965+
},
966+
],
967+
}
968+
assert_schema(PyType, expected, options=pas.Option.DETERMINISTIC_DEFAULTS)

0 commit comments

Comments
 (0)