tools-python
tools-python copied to clipboard
ExternalIdentifier identifierLocator property should be optional
The ExternalIdentifier class file identifierLocator property should be optional. It is not clear how the dataclass tagging for Optional and List properties interact, but messages without that property should be valid.
def __init__(
self,
external_identifier_type: ExternalIdentifierType,
identifier: str,
comment: Optional[str] = None,
identifier_locator: List[str] = None,
issuing_authority: Optional[str] = None,
):
identifier_locator = [] if identifier_locator is None else identifier_locator
check_types_and_set_values(self, locals())
This may be related to the init code for lists, which should not treat them specially, they can be None when unset like all other properties and the setter/getter handles validity. The problem is that the logical model has only two variables (minCount and maxCount) to control three things: the optionality of properties and the size of lists.
- If the identifier_locator property is optional (nullable) its value can be either None or an instance of its type. If it is not optional then it must be an instances of its type and None is invalid.
- If the logical value is not None, then it is a List with minCount to maxCount items.
Because the logical model doesn't (yet) define how to serialize a [0..*] property with no value, the data model needs to specify a policy for doing it one way or the other, None must either be valid (property is nullable) or invalid (property must be present even when it is an empty list. For that reason, the JADN policy is to make [0..*] properties nullable and the minimum list count be one item. An individual property can be declared the other way - optional properties must always be present, but that's not what people normally expect to see.
The serialization team should decide which is the default for each data format, but serialization code should be able to handle either policy.
I believe this is related to my answer here, i.e. we chose to treat list properties with "no value" as empty lists because this makes implementation easier. During serialization, there will be some logic that prevents properties with empty lists from being written so that we won't have them in the output.