Note: I want to prepare a simultaneous PR for fhir-parser, since it will need the same sort of fixes. But that version does not need to maintain backwards compatibility, so it will be a useful comparison for how we might want this to look when we next bump major versions. That's coming shortly.
This commit breaks FHIRDate into four classes:
FHIRDate
FHIRDateTime
FHIRInstant
FHIRTime
BREAKING CHANGES:
If consuming code were inspecting the elementProperties array and doing a check like element_type is FHIRDate, that will now fail for datetime, instant, and time elements. Backwards compatibility is however maintained for checks written like issubclass(element_type, FHIRDate). Instances have a similar resolution: isinstance(obj, FHIRDate) will still work.
If consuming code were manually creating FHIRDate objects themselves with a time component, that will now fail with a ValueError.
Since the first item is unavoidable if we want to fix the bugs listed below and has a workaround that works before and after this change, and the second item is not an expected workflow, I hope that such breaking changes do not cause too much harm for consumers.
BUG FIXES:
FHIR time fields are now correctly parsed. Previously, a time of "10:12:14" would result in a date of "1001-01-01"
Passing too much detail to a date field or too little detail to an instant field will now correctly throw a validation error. For example, a Patient.birthDate field with a time. Or an Observation.issued field with just a year.
Sub-seconds would be incorrectly chopped off of a datetime's .isostring (which the FHIR spec allows us to do) and an instant's .isostring (which the FHIR spec does not allow us to do). The .date Python representation and the .as_json() call would both work correctly and keep the sub-seconds. Only .isostring was affected.
IMPROVEMENTS:
Leap seconds are now half-supported. The FHIR spec says clients "SHOULD accept and handle leap seconds gracefully", which we do... By dropping the leap second on the floor and rolling back to :59. But this is an improvement on previous behavior of a validation error. The .as_json() value will still preserve the leap second.
The .date field is now always the appropriate type (datetime.date for FHIRDate, datetime.datetime for FHIRDateTime and FHIRInstant, and datetime.time for FHIRTime). Previously, a datetime field might result in a datetime.date if only given a date portion. (Which isn't entirely wrong, but consistently providing the same data type is useful.)
The new classes have appropriately named fields in addition to the backwards-compatible .date field -- FHIRDateTime.datetime, FHIRInstant.datetime, and FHIRTime.time. These will always be the same value as .date for now - but in a future major release, the .date alias may be dropped.
The dependency on isodate can now be dropped. It is lightly maintained and the stdlib can handle most of its job nowadays.
Much better class documentation for what sort of things are supported and which are not.
Note: I want to prepare a simultaneous PR for fhir-parser, since it will need the same sort of fixes. But that version does not need to maintain backwards compatibility, so it will be a useful comparison for how we might want this to look when we next bump major versions. That's coming shortly.
This commit breaks FHIRDate into four classes:
BREAKING CHANGES:
element_type is FHIRDate
, that will now fail fordatetime
,instant
, andtime
elements. Backwards compatibility is however maintained for checks written likeissubclass(element_type, FHIRDate)
. Instances have a similar resolution:isinstance(obj, FHIRDate)
will still work.Since the first item is unavoidable if we want to fix the bugs listed below and has a workaround that works before and after this change, and the second item is not an expected workflow, I hope that such breaking changes do not cause too much harm for consumers.
BUG FIXES:
time
fields are now correctly parsed. Previously, a time of "10:12:14" would result in a date of "1001-01-01"date
field or too little detail to aninstant
field will now correctly throw a validation error. For example, a Patient.birthDate field with a time. Or an Observation.issued field with just a year.datetime
's.isostring
(which the FHIR spec allows us to do) and aninstant
's.isostring
(which the FHIR spec does not allow us to do). The.date
Python representation and the.as_json()
call would both work correctly and keep the sub-seconds. Only.isostring
was affected.IMPROVEMENTS:
.as_json()
value will still preserve the leap second..date
field is now always the appropriate type (datetime.date for FHIRDate, datetime.datetime for FHIRDateTime and FHIRInstant, and datetime.time for FHIRTime). Previously, adatetime
field might result in a datetime.date if only given a date portion. (Which isn't entirely wrong, but consistently providing the same data type is useful.).date
field -- FHIRDateTime.datetime, FHIRInstant.datetime, and FHIRTime.time. These will always be the same value as.date
for now - but in a future major release, the.date
alias may be dropped.This is a sister PR (one which maintains some level of backwards compatibility) to the upstream more drastic refactor in fhir-parser.
Fixes: #32 Fixes: #11