From c4497b151a9208129fcc6c511f3f6d668f36d140 Mon Sep 17 00:00:00 2001 From: "Michael R. Crusoe" Date: Mon, 10 Oct 2022 12:30:14 +0200 Subject: [PATCH] metaschema: enum schemas can have names --- schema_salad/metaschema.py | 74 ++++++++++++++++----- schema_salad/metaschema/metaschema_base.yml | 3 + 2 files changed, 59 insertions(+), 18 deletions(-) diff --git a/schema_salad/metaschema.py b/schema_salad/metaschema.py index 4d17f9d7..928dc0ef 100644 --- a/schema_salad/metaschema.py +++ b/schema_salad/metaschema.py @@ -1181,6 +1181,7 @@ def __init__( self, symbols: Any, type: Any, + name: Optional[Any] = None, extension_fields: Optional[Dict[str, Any]] = None, loadingOptions: Optional[LoadingOptions] = None, ) -> None: @@ -1193,16 +1194,21 @@ def __init__( self.loadingOptions = loadingOptions else: self.loadingOptions = LoadingOptions() + self.name = name self.symbols = symbols self.type = type def __eq__(self, other: Any) -> bool: if isinstance(other, EnumSchema): - return bool(self.symbols == other.symbols and self.type == other.type) + return bool( + self.name == other.name + and self.symbols == other.symbols + and self.type == other.type + ) return False def __hash__(self) -> int: - return hash((self.symbols, self.type)) + return hash((self.name, self.symbols, self.type)) @classmethod def fromDoc( @@ -1217,6 +1223,33 @@ def fromDoc( _doc.lc.data = doc.lc.data _doc.lc.filename = doc.lc.filename _errors__ = [] + if "name" in _doc: + try: + name = load_field( + _doc.get("name"), + uri_union_of_None_type_or_strtype_True_False_None, + baseuri, + loadingOptions, + ) + except ValidationException as e: + _errors__.append( + ValidationException( + "the `name` field is not valid because:", + SourceLine(_doc, "name", str), + [e], + ) + ) + else: + name = None + + __original_name_is_none = name is None + if name is None: + if docRoot is not None: + name = docRoot + else: + name = "_:" + str(_uuid__.uuid4()) + if not __original_name_is_none: + baseuri = name try: symbols = load_field( _doc.get("symbols"), @@ -1258,7 +1291,7 @@ def fromDoc( else: _errors__.append( ValidationException( - "invalid field `{}`, expected one of: `symbols`, `type`".format( + "invalid field `{}`, expected one of: `name`, `symbols`, `type`".format( k ), SourceLine(_doc, k, str), @@ -1269,11 +1302,13 @@ def fromDoc( if _errors__: raise ValidationException("Trying 'EnumSchema'", None, _errors__) _constructed = cls( + name=name, symbols=symbols, type=type, extension_fields=extension_fields, loadingOptions=loadingOptions, ) + loadingOptions.idx[name] = (_constructed, loadingOptions) return _constructed def save( @@ -1287,12 +1322,15 @@ def save( else: for ef in self.extension_fields: r[ef] = self.extension_fields[ef] + if self.name is not None: + u = save_relative_uri(self.name, base_url, True, None, relative_uris) + r["name"] = u if self.symbols is not None: - u = save_relative_uri(self.symbols, base_url, True, None, relative_uris) + u = save_relative_uri(self.symbols, self.name, True, None, relative_uris) r["symbols"] = u if self.type is not None: r["type"] = save( - self.type, top=False, base_url=base_url, relative_uris=relative_uris + self.type, top=False, base_url=self.name, relative_uris=relative_uris ) # top refers to the directory level @@ -1303,7 +1341,7 @@ def save( r["$schemas"] = self.loadingOptions.schemas return r - attrs = frozenset(["symbols", "type"]) + attrs = frozenset(["name", "symbols", "type"]) class ArraySchema(Saveable): @@ -2722,9 +2760,9 @@ class SaladEnumSchema(NamedType, EnumSchema, SchemaDefinedType): def __init__( self, - name: Any, symbols: Any, type: Any, + name: Optional[Any] = None, inVocab: Optional[Any] = None, doc: Optional[Any] = None, docParent: Optional[Any] = None, @@ -2808,7 +2846,7 @@ def fromDoc( try: name = load_field( _doc.get("name"), - uri_strtype_True_False_None, + uri_union_of_None_type_or_strtype_True_False_None, baseuri, loadingOptions, ) @@ -2828,7 +2866,7 @@ def fromDoc( if docRoot is not None: name = docRoot else: - raise ValidationException("Missing name") + name = "_:" + str(_uuid__.uuid4()) if not __original_name_is_none: baseuri = name if "inVocab" in _doc: @@ -3555,6 +3593,15 @@ def save( typedsl_enum_d9cba076fca539106791a4f46d198c7fcfbdb779Loader_2 = _TypeDSLLoader( enum_d9cba076fca539106791a4f46d198c7fcfbdb779Loader, 2 ) +union_of_None_type_or_strtype = _UnionLoader( + ( + None_type, + strtype, + ) +) +uri_union_of_None_type_or_strtype_True_False_None = _URILoader( + union_of_None_type_or_strtype, True, False, None +) uri_array_of_strtype_True_False_None = _URILoader(array_of_strtype, True, False, None) enum_d961d79c225752b9fadb617367615ab176b47d77Loader = _EnumLoader( ("enum",), "enum_d961d79c225752b9fadb617367615ab176b47d77" @@ -3574,15 +3621,6 @@ def save( typedsl_enum_d062602be0b4b8fd33e69e29a841317b6ab665bcLoader_2 = _TypeDSLLoader( enum_d062602be0b4b8fd33e69e29a841317b6ab665bcLoader, 2 ) -union_of_None_type_or_strtype = _UnionLoader( - ( - None_type, - strtype, - ) -) -uri_union_of_None_type_or_strtype_True_False_None = _URILoader( - union_of_None_type_or_strtype, True, False, None -) union_of_None_type_or_booltype = _UnionLoader( ( None_type, diff --git a/schema_salad/metaschema/metaschema_base.yml b/schema_salad/metaschema/metaschema_base.yml index 67008b68..4bdefceb 100644 --- a/schema_salad/metaschema/metaschema_base.yml +++ b/schema_salad/metaschema/metaschema_base.yml @@ -132,6 +132,9 @@ $graph: _type: "@vocab" typeDSL: true refScope: 2 + name: + type: string? + jsonldPredicate: "@id" symbols: type: string[] jsonldPredicate: