Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion linkml_model/annotations.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Auto generated from annotations.yaml by pythongen.py version: 0.0.1
# Generation date: 2026-08-12T09:42:07
# Generation date: 2026-08-31T23:36:26
# Schema: annotations
#
# id: https://w3id.org/linkml/annotations
Expand Down
2 changes: 1 addition & 1 deletion linkml_model/array.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Auto generated from array.yaml by pythongen.py version: 0.0.1
# Generation date: 2026-08-12T09:42:08
# Generation date: 2026-08-31T23:36:27
# Schema: arrays
#
# id: https://w3id.org/linkml/lib/arrays
Expand Down
2 changes: 1 addition & 1 deletion linkml_model/datasets.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Auto generated from datasets.yaml by pythongen.py version: 0.0.1
# Generation date: 2026-08-12T09:42:09
# Generation date: 2026-08-31T23:36:28
# Schema: datasets
#
# id: https://w3id.org/linkml/datasets
Expand Down
Binary file modified linkml_model/excel/meta.xlsx
Binary file not shown.
2 changes: 1 addition & 1 deletion linkml_model/extensions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Auto generated from extensions.yaml by pythongen.py version: 0.0.1
# Generation date: 2026-08-12T09:42:10
# Generation date: 2026-08-31T23:36:29
# Schema: extensions
#
# id: https://w3id.org/linkml/extensions
Expand Down
5 changes: 4 additions & 1 deletion linkml_model/graphql/meta.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ type AnonymousClassExpression implements ClassExpression
rank: Int
categories: [String]
keywords: [String]
isA: Definition
isA: ClassDefinition
anyOf: [AnonymousClassExpression]
exactlyOneOf: [AnonymousClassExpression]
noneOf: [AnonymousClassExpression]
Expand All @@ -112,6 +112,7 @@ type AnonymousEnumExpression implements EnumExpression
codeSetVersion: String
pvFormula: PvFormulaOptions
permissibleValues: [PermissibleValue]
isOpen: Boolean
include: [AnonymousEnumExpression]
minus: [AnonymousEnumExpression]
inherits: [EnumDefinition]
Expand Down Expand Up @@ -708,6 +709,7 @@ type EnumDefinition implements EnumExpression
codeSetVersion: String
pvFormula: PvFormulaOptions
permissibleValues: [PermissibleValue]
isOpen: Boolean
include: [AnonymousEnumExpression]
minus: [AnonymousEnumExpression]
inherits: [EnumDefinition]
Expand All @@ -723,6 +725,7 @@ type EnumExpression
codeSetVersion: String
pvFormula: PvFormulaOptions
permissibleValues: [PermissibleValue]
isOpen: Boolean
include: [AnonymousEnumExpression]
minus: [AnonymousEnumExpression]
inherits: [EnumDefinition]
Expand Down
4 changes: 4 additions & 0 deletions linkml_model/jsonld/meta.context.jsonld
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,10 @@
"@type": "xsd:boolean",
"@id": "is_grouping_slot"
},
"is_open": {
"@type": "xsd:boolean",
"@id": "is_open"
},
"is_usage_slot": {
"@type": "xsd:boolean",
"@id": "is_usage_slot"
Expand Down
64 changes: 60 additions & 4 deletions linkml_model/jsonld/meta.jsonld
Original file line number Diff line number Diff line change
Expand Up @@ -1637,6 +1637,33 @@
"inlined": true,
"@type": "SlotDefinition"
},
{
"name": "is_open",
"definition_uri": "https://w3id.org/linkml/is_open",
"description": "Whether the enumeration is open, meaning that values outside of the set of permissible values are allowed. If true, the enumeration is open and data values that are not in the set of permissible values are permitted (though they SHOULD be drawn from the permissible values if available). If false (runtime default), the enumeration is closed and data values MUST be drawn from the set of permissible values.",
"comments": [
"An open enumeration is analogous to the `allow-other=\"yes\"` construct in the OSCAL Metamodel.",
"When an enum is open, the permissible value set is not exhaustive - they document the advised, recommended, or expected values but allow values outside the permissible set."
],
"in_subset": [
"SpecificationSubset"
],
"from_schema": "https://w3id.org/linkml/meta",
"see_also": [
"https://pages.nist.gov/metaschema/specification/syntax/constraints/#allow-other",
"https://github.com/linkml/linkml/issues/127",
"https://github.com/linkml/linkml/pull/3712"
],
"status": "testing",
"domain": "EnumExpression",
"slot_uri": "https://w3id.org/linkml/is_open",
"owner": "EnumExpression",
"domain_of": [
"EnumExpression"
],
"range": "boolean",
"@type": "SlotDefinition"
},
{
"name": "enum_uri",
"definition_uri": "https://w3id.org/linkml/enum_uri",
Expand Down Expand Up @@ -6495,6 +6522,32 @@
"inlined_as_list": true,
"@type": "SlotDefinition"
},
{
"name": "anonymous_class_expression_is_a",
"definition_uri": "https://w3id.org/linkml/is_a",
"description": "A class that any instance satisfying this expression must also be an instance of",
"in_subset": [
"SpecificationSubset",
"BasicSubset",
"ObjectOrientedProfile",
"OwlProfile"
],
"from_schema": "https://w3id.org/linkml/meta",
"rank": 11,
"is_a": "is_a",
"abstract": true,
"domain": "AnonymousClassExpression",
"slot_uri": "https://w3id.org/linkml/is_a",
"alias": "is_a",
"owner": "AnonymousClassExpression",
"domain_of": [
"AnonymousClassExpression"
],
"is_usage_slot": true,
"usage_slot_name": "is_a",
"range": "ClassDefinition",
"@type": "SlotDefinition"
},
{
"name": "class_definition_is_a",
"definition_uri": "https://w3id.org/linkml/is_a",
Expand Down Expand Up @@ -7274,6 +7327,7 @@
"code_set_version",
"pv_formula",
"permissible_values",
"is_open",
"include",
"minus",
"inherits",
Expand All @@ -7299,6 +7353,7 @@
"code_set_version",
"pv_formula",
"permissible_values",
"is_open",
"include",
"minus",
"inherits",
Expand Down Expand Up @@ -7404,6 +7459,7 @@
"code_set_version",
"pv_formula",
"permissible_values",
"is_open",
"include",
"minus",
"inherits",
Expand Down Expand Up @@ -8028,7 +8084,7 @@
"rank",
"categories",
"keywords",
"is_a",
"anonymous_class_expression_is_a",
"class_expression_any_of",
"class_expression_exactly_one_of",
"class_expression_none_of",
Expand Down Expand Up @@ -8873,9 +8929,9 @@
],
"metamodel_version": "1.11.0",
"source_file": "meta.yaml",
"source_file_date": "2026-08-12T09:39:08",
"source_file_size": 101875,
"generation_date": "2026-08-12T09:43:11",
"source_file_date": "2026-08-31T23:35:12",
"source_file_size": 103143,
"generation_date": "2026-08-31T23:37:20",
"@type": "SchemaDefinition",
"@context": [
"staging/jsonld/meta.context.jsonld",
Expand Down
30 changes: 29 additions & 1 deletion linkml_model/jsonschema/meta.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@
]
},
"is_a": {
"description": "A primary parent class or slot from which inheritable metaslots are propagated from. While multiple inheritance is not allowed, mixins can be provided effectively providing the same thing. The semantics are the same when translated to formalisms that allow MI (e.g. RDFS/OWL). When translating to a SI framework (e.g. java classes, python classes) then is a is used. When translating a framework without polymorphism (e.g. json-schema, solr document schema) then is a and mixins are recursively unfolded",
"description": "A class that any instance satisfying this expression must also be an instance of",
"type": [
"string",
"null"
Expand Down Expand Up @@ -646,6 +646,13 @@
"null"
]
},
"is_open": {
"description": "Whether the enumeration is open, meaning that values outside of the set of permissible values are allowed. If true, the enumeration is open and data values that are not in the set of permissible values are permitted (though they SHOULD be drawn from the permissible values if available). If false (runtime default), the enumeration is closed and data values MUST be drawn from the set of permissible values.",
"type": [
"boolean",
"null"
]
},
"matches": {
"anyOf": [
{
Expand Down Expand Up @@ -6322,6 +6329,13 @@
"null"
]
},
"is_open": {
"description": "Whether the enumeration is open, meaning that values outside of the set of permissible values are allowed. If true, the enumeration is open and data values that are not in the set of permissible values are permitted (though they SHOULD be drawn from the permissible values if available). If false (runtime default), the enumeration is closed and data values MUST be drawn from the set of permissible values.",
"type": [
"boolean",
"null"
]
},
"keywords": {
"description": "Keywords or tags used to describe the element",
"items": {
Expand Down Expand Up @@ -6907,6 +6921,13 @@
"null"
]
},
"is_open": {
"description": "Whether the enumeration is open, meaning that values outside of the set of permissible values are allowed. If true, the enumeration is open and data values that are not in the set of permissible values are permitted (though they SHOULD be drawn from the permissible values if available). If false (runtime default), the enumeration is closed and data values MUST be drawn from the set of permissible values.",
"type": [
"boolean",
"null"
]
},
"keywords": {
"description": "Keywords or tags used to describe the element",
"items": {
Expand Down Expand Up @@ -7198,6 +7219,13 @@
"null"
]
},
"is_open": {
"description": "Whether the enumeration is open, meaning that values outside of the set of permissible values are allowed. If true, the enumeration is open and data values that are not in the set of permissible values are permitted (though they SHOULD be drawn from the permissible values if available). If false (runtime default), the enumeration is closed and data values MUST be drawn from the set of permissible values.",
"type": [
"boolean",
"null"
]
},
"matches": {
"anyOf": [
{
Expand Down
2 changes: 1 addition & 1 deletion linkml_model/mappings.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Auto generated from mappings.yaml by pythongen.py version: 0.0.1
# Generation date: 2026-08-12T09:42:11
# Generation date: 2026-08-31T23:36:30
# Schema: mappings
#
# id: https://w3id.org/linkml/mappings
Expand Down
26 changes: 22 additions & 4 deletions linkml_model/meta.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Auto generated from meta.yaml by pythongen.py version: 0.0.1
# Generation date: 2026-08-12T09:42:13
# Generation date: 2026-08-31T23:36:32
# Schema: meta
#
# id: https://w3id.org/linkml/meta
Expand Down Expand Up @@ -906,6 +906,7 @@ class AnonymousEnumExpression(YAMLRoot):
code_set_version: Optional[str] = None
pv_formula: Optional[Union[str, "PvFormulaOptions"]] = None
permissible_values: Optional[Union[dict[Union[str, PermissibleValueText], Union[dict, "PermissibleValue"]], list[Union[dict, "PermissibleValue"]]]] = empty_dict()
is_open: Optional[Union[bool, Bool]] = None
include: Optional[Union[Union[dict, "AnonymousEnumExpression"], list[Union[dict, "AnonymousEnumExpression"]]]] = empty_list()
minus: Optional[Union[Union[dict, "AnonymousEnumExpression"], list[Union[dict, "AnonymousEnumExpression"]]]] = empty_list()
inherits: Optional[Union[Union[str, EnumDefinitionName], list[Union[str, EnumDefinitionName]]]] = empty_list()
Expand All @@ -928,6 +929,9 @@ def __post_init__(self, *_: str, **kwargs: Any):

self._normalize_inlined_as_dict(slot_name="permissible_values", slot_type=PermissibleValue, key_name="text", keyed=True)

if self.is_open is not None and not isinstance(self.is_open, Bool):
self.is_open = Bool(self.is_open)

if not isinstance(self.include, list):
self.include = [self.include] if self.include is not None else []
self.include = [v if isinstance(v, AnonymousEnumExpression) else AnonymousEnumExpression(**as_dict(v)) for v in self.include]
Expand Down Expand Up @@ -972,6 +976,7 @@ class EnumDefinition(Definition):
code_set_version: Optional[str] = None
pv_formula: Optional[Union[str, "PvFormulaOptions"]] = None
permissible_values: Optional[Union[dict[Union[str, PermissibleValueText], Union[dict, "PermissibleValue"]], list[Union[dict, "PermissibleValue"]]]] = empty_dict()
is_open: Optional[Union[bool, Bool]] = None
include: Optional[Union[Union[dict, AnonymousEnumExpression], list[Union[dict, AnonymousEnumExpression]]]] = empty_list()
minus: Optional[Union[Union[dict, AnonymousEnumExpression], list[Union[dict, AnonymousEnumExpression]]]] = empty_list()
inherits: Optional[Union[Union[str, EnumDefinitionName], list[Union[str, EnumDefinitionName]]]] = empty_list()
Expand Down Expand Up @@ -1002,6 +1007,9 @@ def __post_init__(self, *_: str, **kwargs: Any):

self._normalize_inlined_as_dict(slot_name="permissible_values", slot_type=PermissibleValue, key_name="text", keyed=True)

if self.is_open is not None and not isinstance(self.is_open, Bool):
self.is_open = Bool(self.is_open)

if not isinstance(self.include, list):
self.include = [self.include] if self.include is not None else []
self.include = [v if isinstance(v, AnonymousEnumExpression) else AnonymousEnumExpression(**as_dict(v)) for v in self.include]
Expand Down Expand Up @@ -1564,6 +1572,7 @@ class EnumExpression(Expression):
code_set_version: Optional[str] = None
pv_formula: Optional[Union[str, "PvFormulaOptions"]] = None
permissible_values: Optional[Union[dict[Union[str, PermissibleValueText], Union[dict, "PermissibleValue"]], list[Union[dict, "PermissibleValue"]]]] = empty_dict()
is_open: Optional[Union[bool, Bool]] = None
include: Optional[Union[Union[dict, AnonymousEnumExpression], list[Union[dict, AnonymousEnumExpression]]]] = empty_list()
minus: Optional[Union[Union[dict, AnonymousEnumExpression], list[Union[dict, AnonymousEnumExpression]]]] = empty_list()
inherits: Optional[Union[Union[str, EnumDefinitionName], list[Union[str, EnumDefinitionName]]]] = empty_list()
Expand All @@ -1586,6 +1595,9 @@ def __post_init__(self, *_: str, **kwargs: Any):

self._normalize_inlined_as_dict(slot_name="permissible_values", slot_type=PermissibleValue, key_name="text", keyed=True)

if self.is_open is not None and not isinstance(self.is_open, Bool):
self.is_open = Bool(self.is_open)

if not isinstance(self.include, list):
self.include = [self.include] if self.include is not None else []
self.include = [v if isinstance(v, AnonymousEnumExpression) else AnonymousEnumExpression(**as_dict(v)) for v in self.include]
Expand Down Expand Up @@ -2614,16 +2626,16 @@ class AnonymousClassExpression(AnonymousExpression):
class_name: ClassVar[str] = "anonymous_class_expression"
class_model_uri: ClassVar[URIRef] = LINKML.AnonymousClassExpression

is_a: Optional[Union[str, DefinitionName]] = None
is_a: Optional[Union[str, ClassDefinitionName]] = None
any_of: Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]] = empty_list()
exactly_one_of: Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]] = empty_list()
none_of: Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]] = empty_list()
all_of: Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]] = empty_list()
slot_conditions: Optional[Union[dict[Union[str, SlotDefinitionName], Union[dict, SlotDefinition]], list[Union[dict, SlotDefinition]]]] = empty_dict()

def __post_init__(self, *_: str, **kwargs: Any):
if self.is_a is not None and not isinstance(self.is_a, DefinitionName):
self.is_a = DefinitionName(self.is_a)
if self.is_a is not None and not isinstance(self.is_a, ClassDefinitionName):
self.is_a = ClassDefinitionName(self.is_a)

if not isinstance(self.any_of, list):
self.any_of = [self.any_of] if self.any_of is not None else []
Expand Down Expand Up @@ -4706,6 +4718,9 @@ class slots:
slots.permissible_values = Slot(uri=LINKML.permissible_values, name="permissible_values", curie=LINKML.curie('permissible_values'),
model_uri=LINKML.permissible_values, domain=EnumExpression, range=Optional[Union[dict[Union[str, PermissibleValueText], Union[dict, "PermissibleValue"]], list[Union[dict, "PermissibleValue"]]]])

slots.is_open = Slot(uri=LINKML.is_open, name="is_open", curie=LINKML.curie('is_open'),
model_uri=LINKML.is_open, domain=EnumExpression, range=Optional[Union[bool, Bool]])

slots.enum_uri = Slot(uri=LINKML.enum_uri, name="enum_uri", curie=LINKML.curie('enum_uri'),
model_uri=LINKML.enum_uri, domain=EnumDefinition, range=Optional[Union[str, URIorCURIE]])

Expand Down Expand Up @@ -5297,6 +5312,9 @@ class slots:
slots.class_expression_none_of = Slot(uri=LINKML.none_of, name="class_expression_none_of", curie=LINKML.curie('none_of'),
model_uri=LINKML.class_expression_none_of, domain=None, range=Optional[Union[Union[dict, "AnonymousClassExpression"], list[Union[dict, "AnonymousClassExpression"]]]])

slots.anonymous_class_expression_is_a = Slot(uri=LINKML.is_a, name="anonymous_class_expression_is_a", curie=LINKML.curie('is_a'),
model_uri=LINKML.anonymous_class_expression_is_a, domain=AnonymousClassExpression, range=Optional[Union[str, ClassDefinitionName]])

slots.class_definition_is_a = Slot(uri=LINKML.is_a, name="class_definition_is_a", curie=LINKML.curie('is_a'),
model_uri=LINKML.class_definition_is_a, domain=ClassDefinition, range=Optional[Union[str, ClassDefinitionName]])

Expand Down
22 changes: 22 additions & 0 deletions linkml_model/model/schema/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,27 @@ slots:
exact_mappings:
- cdisc:PermissibleValue

is_open:
Comment thread
noelmcloughlin marked this conversation as resolved.
Comment thread
amc-corey-cox marked this conversation as resolved.
domain: enum_expression
Comment thread
noelmcloughlin marked this conversation as resolved.
range: boolean
description: >-
Whether the enumeration is open, meaning that values outside of the set of
permissible values are allowed. If true, the enumeration is open and data values
that are not in the set of permissible values are permitted (though they SHOULD be
drawn from the permissible values if available). If false (runtime default), the
enumeration is closed and data values MUST be drawn from the set of permissible values.
comments:
Comment thread
noelmcloughlin marked this conversation as resolved.
- An open enumeration is analogous to the `allow-other="yes"` construct in the OSCAL Metamodel.
- When an enum is open, the permissible value set is not exhaustive - they document the
advised, recommended, or expected values but allow values outside the permissible set.
see_also:
- https://pages.nist.gov/metaschema/specification/syntax/constraints/#allow-other
- https://github.com/linkml/linkml/issues/127
- https://github.com/linkml/linkml/pull/3712
in_subset:
- SpecificationSubset
status: testing
Comment thread
amc-corey-cox marked this conversation as resolved.

enum_uri:
aliases:
- public ID
Expand Down Expand Up @@ -2785,6 +2806,7 @@ classes:
- code_set_version
- pv_formula
- permissible_values
- is_open
- include
- minus
- inherits
Expand Down
Loading
Loading