spdx-python-model 0.0.2__py3-none-any.whl → 0.0.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,6 +6,9 @@
6
6
  #
7
7
  # SPDX-License-Identifier: Apache-2.0
8
8
 
9
+ from __future__ import annotations
10
+
11
+ import decimal
9
12
  import functools
10
13
  import hashlib
11
14
  import json
@@ -14,19 +17,38 @@ import sys
14
17
  import threading
15
18
  import time
16
19
  import warnings
20
+ from abc import ABC, abstractmethod
17
21
  from contextlib import contextmanager
18
- from datetime import datetime, timezone, timedelta
22
+ from datetime import datetime, timedelta, timezone
19
23
  from enum import Enum
20
- from abc import ABC, abstractmethod
21
-
22
-
23
- def check_type(obj, types):
24
+ from typing import (
25
+ Any,
26
+ Callable,
27
+ Collection,
28
+ Dict,
29
+ Iterable,
30
+ Iterator,
31
+ List,
32
+ Optional,
33
+ Set,
34
+ Tuple,
35
+ Type,
36
+ TypeVar,
37
+ Union,
38
+ cast,
39
+ overload,
40
+ )
41
+
42
+
43
+ def check_type(obj: Any, types: Union[Type[Any], Tuple[Type[Any], ...]]) -> None:
24
44
  if not isinstance(obj, types):
25
45
  if isinstance(types, (list, tuple)):
26
46
  raise TypeError(
27
- f"Value must be one of type: {', '.join(t.__name__ for t in types)}. Got {type(obj)}"
47
+ f"Value must be one of type: {', '.join(t.__name__ for t in types)}. Got {type(obj).__name__}"
28
48
  )
29
- raise TypeError(f"Value must be of type {types.__name__}. Got {type(obj)}")
49
+ raise TypeError(
50
+ f"Value must be of type {types.__name__}. Got {type(obj).__name__}"
51
+ )
30
52
 
31
53
 
32
54
  class Property(ABC):
@@ -35,13 +57,15 @@ class Property(ABC):
35
57
  class
36
58
  """
37
59
 
38
- def __init__(self, *, pattern=None):
60
+ VALID_TYPES: Union[Tuple, Type] = ()
61
+
62
+ def __init__(self, *, pattern: Optional[str] = None):
39
63
  self.pattern = pattern
40
64
 
41
- def init(self):
65
+ def init(self) -> Any:
42
66
  return None
43
67
 
44
- def validate(self, value):
68
+ def validate(self, value) -> None:
45
69
  check_type(value, self.VALID_TYPES)
46
70
  if self.pattern is not None and not re.search(
47
71
  self.pattern, self.to_string(value)
@@ -50,37 +74,41 @@ class Property(ABC):
50
74
  f"Value is not correctly formatted. Got '{self.to_string(value)}'"
51
75
  )
52
76
 
53
- def set(self, value):
77
+ def set(self, value: Any) -> Any:
54
78
  return value
55
79
 
56
- def check_min_count(self, value, min_count):
80
+ def check_min_count(self, value, min_count: int) -> bool:
57
81
  return min_count == 1
58
82
 
59
- def check_max_count(self, value, max_count):
83
+ def check_max_count(self, value, max_count: int) -> bool:
60
84
  return max_count == 1
61
85
 
62
- def elide(self, value):
86
+ def elide(self, value) -> bool:
63
87
  return value is None
64
88
 
65
- def walk(self, value, callback, path):
89
+ def walk(self, value, callback: Callable, path: List[str]) -> None:
66
90
  callback(value, path)
67
91
 
68
- def iter_objects(self, value, recursive, visited):
92
+ def iter_objects(
93
+ self, value, recursive: bool, visited: Set[SHACLObject]
94
+ ) -> Iterable[Any]:
69
95
  return []
70
96
 
71
- def link_prop(self, value, objectset, missing, visited):
97
+ def link_prop(
98
+ self, value, objectset, missing: Optional[Set[str]], visited: Set[SHACLObject]
99
+ ):
72
100
  return value
73
101
 
74
- def to_string(self, value):
102
+ def to_string(self, value) -> str:
75
103
  return str(value)
76
104
 
77
105
  @abstractmethod
78
- def encode(self, encoder, value, state):
79
- pass
106
+ def encode(self, encoder, value, state) -> None:
107
+ raise NotImplementedError("Subclasses must implement encode method")
80
108
 
81
109
  @abstractmethod
82
- def decode(self, decoder, *, objectset=None):
83
- pass
110
+ def decode(self, decoder, *, objectset: Optional[SHACLObjectSet] = None) -> Any:
111
+ raise NotImplementedError("Subclasses must implement decode method")
84
112
 
85
113
 
86
114
  class StringProp(Property):
@@ -90,21 +118,25 @@ class StringProp(Property):
90
118
 
91
119
  VALID_TYPES = str
92
120
 
93
- def set(self, value):
121
+ def set(self, value) -> str:
94
122
  return str(value)
95
123
 
96
- def encode(self, encoder, value, state):
124
+ def encode(self, encoder, value, state) -> None:
97
125
  encoder.write_string(value)
98
126
 
99
- def decode(self, decoder, *, objectset=None):
127
+ def decode(
128
+ self, decoder, *, objectset: Optional[SHACLObjectSet] = None
129
+ ) -> Optional[str]:
100
130
  return decoder.read_string()
101
131
 
102
132
 
103
133
  class AnyURIProp(StringProp):
104
- def encode(self, encoder, value, state):
134
+ def encode(self, encoder, value, state) -> None:
105
135
  encoder.write_iri(value)
106
136
 
107
- def decode(self, decoder, *, objectset=None):
137
+ def decode(
138
+ self, decoder, *, objectset: Optional[SHACLObjectSet] = None
139
+ ) -> Optional[str]:
108
140
  return decoder.read_iri()
109
141
 
110
142
 
@@ -117,37 +149,52 @@ class DateTimeProp(Property):
117
149
  UTC_FORMAT_STR = "%Y-%m-%dT%H:%M:%SZ"
118
150
  REGEX = r"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|[+-]\d{2}:\d{2})?$"
119
151
 
120
- def set(self, value):
152
+ def set(self, value) -> datetime:
121
153
  return self._normalize(value)
122
154
 
123
- def encode(self, encoder, value, state):
155
+ def encode(self, encoder, value, state) -> None:
124
156
  encoder.write_datetime(self.to_string(value))
125
157
 
126
- def decode(self, decoder, *, objectset=None):
158
+ def decode(
159
+ self, decoder, *, objectset: Optional[SHACLObjectSet] = None
160
+ ) -> Optional[datetime]:
127
161
  s = decoder.read_datetime()
128
162
  if s is None:
129
163
  return None
164
+ if isinstance(s, datetime):
165
+ return self._normalize(s)
130
166
  v = self.from_string(s)
131
167
  return self._normalize(v)
132
168
 
133
- def _normalize(self, value):
169
+ def _normalize(self, value: datetime) -> datetime:
134
170
  if value.utcoffset() is None:
135
171
  value = value.astimezone()
172
+
173
+ # Remove seconds from timezone offset
136
174
  offset = value.utcoffset()
137
- seconds = offset % timedelta(minutes=-1 if offset.total_seconds() < 0 else 1)
138
- if seconds:
139
- offset = offset - seconds
140
- value = value.replace(tzinfo=timezone(offset))
175
+ if offset is not None:
176
+ seconds = offset % timedelta(
177
+ minutes=-1 if offset.total_seconds() < 0 else 1
178
+ )
179
+ if seconds:
180
+ offset = offset - seconds
181
+ value = value.replace(tzinfo=timezone(offset))
182
+
183
+ # Convert 00:00 timezone offset to UTC
184
+ offset = value.utcoffset()
185
+ if offset is not None and offset.seconds == 0:
186
+ value = value.astimezone(timezone.utc)
187
+
141
188
  value = value.replace(microsecond=0)
142
189
  return value
143
190
 
144
- def to_string(self, value):
191
+ def to_string(self, value: datetime) -> str:
145
192
  value = self._normalize(value)
146
193
  if value.tzinfo == timezone.utc:
147
194
  return value.strftime(self.UTC_FORMAT_STR)
148
195
  return value.isoformat()
149
196
 
150
- def from_string(self, value):
197
+ def from_string(self, value: str) -> datetime:
151
198
  if not re.match(self.REGEX, value):
152
199
  raise ValueError(f"'{value}' is not a correctly formatted datetime")
153
200
  if "Z" in value:
@@ -172,25 +219,27 @@ class DateTimeStampProp(DateTimeProp):
172
219
  class IntegerProp(Property):
173
220
  VALID_TYPES = int
174
221
 
175
- def set(self, value):
222
+ def set(self, value) -> int:
176
223
  return int(value)
177
224
 
178
- def encode(self, encoder, value, state):
225
+ def encode(self, encoder, value, state) -> None:
179
226
  encoder.write_integer(value)
180
227
 
181
- def decode(self, decoder, *, objectset=None):
228
+ def decode(
229
+ self, decoder, *, objectset: Optional[SHACLObjectSet] = None
230
+ ) -> Optional[int]:
182
231
  return decoder.read_integer()
183
232
 
184
233
 
185
234
  class PositiveIntegerProp(IntegerProp):
186
- def validate(self, value):
235
+ def validate(self, value) -> None:
187
236
  super().validate(value)
188
237
  if value < 1:
189
238
  raise ValueError(f"Value must be >=1. Got {value}")
190
239
 
191
240
 
192
241
  class NonNegativeIntegerProp(IntegerProp):
193
- def validate(self, value):
242
+ def validate(self, value) -> None:
194
243
  super().validate(value)
195
244
  if value < 0:
196
245
  raise ValueError(f"Value must be >= 0. Got {value}")
@@ -199,41 +248,52 @@ class NonNegativeIntegerProp(IntegerProp):
199
248
  class BooleanProp(Property):
200
249
  VALID_TYPES = bool
201
250
 
202
- def set(self, value):
251
+ def set(self, value) -> bool:
203
252
  return bool(value)
204
253
 
205
- def encode(self, encoder, value, state):
254
+ def encode(self, encoder, value, state) -> None:
206
255
  encoder.write_bool(value)
207
256
 
208
- def decode(self, decoder, *, objectset=None):
257
+ def decode(
258
+ self, decoder, *, objectset: Optional[SHACLObjectSet] = None
259
+ ) -> Optional[bool]:
209
260
  return decoder.read_bool()
210
261
 
211
262
 
212
263
  class FloatProp(Property):
213
264
  VALID_TYPES = (float, int)
214
265
 
215
- def set(self, value):
266
+ def set(self, value) -> float:
216
267
  return float(value)
217
268
 
218
- def encode(self, encoder, value, state):
269
+ def encode(self, encoder, value, state) -> None:
219
270
  encoder.write_float(value)
220
271
 
221
- def decode(self, decoder, *, objectset=None):
272
+ def decode(
273
+ self, decoder, *, objectset: Optional[SHACLObjectSet] = None
274
+ ) -> Optional[float]:
222
275
  return decoder.read_float()
223
276
 
224
277
 
225
278
  class IRIProp(Property):
226
- def __init__(self, context=[], *, pattern=None):
279
+ def __init__(
280
+ self,
281
+ context: Optional[List[Tuple[str, str]]] = None,
282
+ *,
283
+ pattern: Optional[str] = None,
284
+ ):
285
+ if context is None:
286
+ context = []
227
287
  super().__init__(pattern=pattern)
228
288
  self.context = context
229
289
 
230
- def compact(self, value):
290
+ def compact(self, value) -> Optional[str]:
231
291
  for iri, compact in self.context:
232
292
  if value == iri:
233
293
  return compact
234
294
  return None
235
295
 
236
- def expand(self, value):
296
+ def expand(self, value) -> Optional[str]:
237
297
  for iri, compact in self.context:
238
298
  if value == compact:
239
299
  return iri
@@ -248,15 +308,19 @@ class ObjectProp(IRIProp):
248
308
  A scalar SHACL object property of a SHACL object
249
309
  """
250
310
 
251
- def __init__(self, cls, required, context=[]):
311
+ def __init__(
312
+ self, cls, required: bool, context: Optional[List[Tuple[str, str]]] = None
313
+ ):
314
+ if context is None:
315
+ context = []
252
316
  super().__init__(context)
253
317
  self.cls = cls
254
318
  self.required = required
255
319
 
256
- def validate(self, value):
320
+ def validate(self, value) -> None:
257
321
  check_type(value, (self.cls, str))
258
322
 
259
- def walk(self, value, callback, path):
323
+ def walk(self, value, callback: Callable, path: List[str]) -> None:
260
324
  if value is None:
261
325
  return
262
326
 
@@ -265,7 +329,7 @@ class ObjectProp(IRIProp):
265
329
  else:
266
330
  callback(value, path)
267
331
 
268
- def iter_objects(self, value, recursive, visited):
332
+ def iter_objects(self, value, recursive: bool, visited):
269
333
  if value is None or isinstance(value, str):
270
334
  return
271
335
 
@@ -277,7 +341,7 @@ class ObjectProp(IRIProp):
277
341
  for c in value.iter_objects(recursive=True, visited=visited):
278
342
  yield c
279
343
 
280
- def encode(self, encoder, value, state):
344
+ def encode(self, encoder, value, state) -> None:
281
345
  if value is None:
282
346
  raise ValueError("Object cannot be None")
283
347
 
@@ -287,11 +351,12 @@ class ObjectProp(IRIProp):
287
351
 
288
352
  return value.encode(encoder, state)
289
353
 
290
- def decode(self, decoder, *, objectset=None):
291
- iri = decoder.read_iri()
292
- if iri is None:
354
+ def decode(self, decoder, *, objectset: Optional[SHACLObjectSet] = None):
355
+ if decoder.is_object():
293
356
  return self.cls.decode(decoder, objectset=objectset)
294
357
 
358
+ iri = decoder.read_iri()
359
+
295
360
  iri = self.expand(iri) or iri
296
361
 
297
362
  if objectset is None:
@@ -329,41 +394,45 @@ class ObjectProp(IRIProp):
329
394
 
330
395
 
331
396
  class ListProxy(object):
332
- def __init__(self, prop, data=None):
397
+ def __init__(self, prop: Property, data: Optional[List[Any]] = None):
333
398
  if data is None:
334
- self.__data = []
399
+ self.__data: List[Any] = []
335
400
  else:
336
401
  self.__data = data
337
402
  self.__prop = prop
338
403
 
339
- def append(self, value):
404
+ def append(self, value) -> None:
340
405
  self.__prop.validate(value)
341
406
  self.__data.append(self.__prop.set(value))
342
407
 
343
- def insert(self, idx, value):
408
+ def insert(self, idx: int, value) -> None:
344
409
  self.__prop.validate(value)
345
410
  self.__data.insert(idx, self.__prop.set(value))
346
411
 
347
- def extend(self, items):
412
+ def extend(self, items: Iterable[Any]) -> None:
348
413
  for i in items:
349
414
  self.append(i)
350
415
 
351
- def sort(self, *args, **kwargs):
416
+ def sort(self, *args, **kwargs) -> None:
352
417
  self.__data.sort(*args, **kwargs)
353
418
 
354
419
  def __getitem__(self, key):
355
420
  return self.__data[key]
356
421
 
357
- def __setitem__(self, key, value):
422
+ def __setitem__(self, key, value) -> None:
358
423
  if isinstance(key, slice):
359
424
  for v in value:
360
425
  self.__prop.validate(v)
361
426
  self.__data[key] = [self.__prop.set(v) for v in value]
362
- else:
427
+ elif isinstance(key, int):
363
428
  self.__prop.validate(value)
364
429
  self.__data[key] = self.__prop.set(value)
430
+ else:
431
+ raise TypeError(
432
+ f"ListProxy indices must be integers or slices. Got {type(key).__name__}"
433
+ )
365
434
 
366
- def __delitem__(self, key):
435
+ def __delitem__(self, key) -> None:
367
436
  del self.__data[key]
368
437
 
369
438
  def __contains__(self, item):
@@ -372,10 +441,10 @@ class ListProxy(object):
372
441
  def __iter__(self):
373
442
  return iter(self.__data)
374
443
 
375
- def __len__(self):
444
+ def __len__(self) -> int:
376
445
  return len(self.__data)
377
446
 
378
- def __str__(self):
447
+ def __str__(self) -> str:
379
448
  return str(self.__data)
380
449
 
381
450
  def __repr__(self):
@@ -395,43 +464,43 @@ class ListProp(Property):
395
464
 
396
465
  VALID_TYPES = (list, ListProxy)
397
466
 
398
- def __init__(self, prop):
467
+ def __init__(self, prop: Property):
399
468
  super().__init__()
400
469
  self.prop = prop
401
470
 
402
- def init(self):
471
+ def init(self) -> ListProxy:
403
472
  return ListProxy(self.prop)
404
473
 
405
- def validate(self, value):
474
+ def validate(self, value) -> None:
406
475
  super().validate(value)
407
476
 
408
477
  for i in value:
409
478
  self.prop.validate(i)
410
479
 
411
- def set(self, value):
480
+ def set(self, value) -> ListProxy:
412
481
  if isinstance(value, ListProxy):
413
482
  return value
414
483
 
415
484
  return ListProxy(self.prop, [self.prop.set(d) for d in value])
416
485
 
417
- def check_min_count(self, value, min_count):
486
+ def check_min_count(self, value, min_count: int) -> bool:
418
487
  check_type(value, ListProxy)
419
488
  return len(value) >= min_count
420
489
 
421
- def check_max_count(self, value, max_count):
490
+ def check_max_count(self, value, max_count: int) -> bool:
422
491
  check_type(value, ListProxy)
423
492
  return len(value) <= max_count
424
493
 
425
- def elide(self, value):
494
+ def elide(self, value) -> bool:
426
495
  check_type(value, ListProxy)
427
496
  return len(value) == 0
428
497
 
429
- def walk(self, value, callback, path):
498
+ def walk(self, value, callback: Callable, path: List[str]) -> None:
430
499
  callback(value, path)
431
500
  for idx, v in enumerate(value):
432
501
  self.prop.walk(v, callback, path + [f"[{idx}]"])
433
502
 
434
- def iter_objects(self, value, recursive, visited):
503
+ def iter_objects(self, value, recursive: bool, visited):
435
504
  for v in value:
436
505
  for c in self.prop.iter_objects(v, recursive, visited):
437
506
  yield c
@@ -444,7 +513,7 @@ class ListProp(Property):
444
513
 
445
514
  return ListProxy(self.prop, data=data)
446
515
 
447
- def encode(self, encoder, value, state):
516
+ def encode(self, encoder, value, state) -> None:
448
517
  check_type(value, ListProxy)
449
518
 
450
519
  with encoder.write_list() as list_s:
@@ -452,7 +521,9 @@ class ListProp(Property):
452
521
  with list_s.write_list_item() as item_s:
453
522
  self.prop.encode(item_s, v, state)
454
523
 
455
- def decode(self, decoder, *, objectset=None):
524
+ def decode(
525
+ self, decoder, *, objectset: Optional[SHACLObjectSet] = None
526
+ ) -> ListProxy:
456
527
  data = []
457
528
  for val_d in decoder.read_list():
458
529
  v = self.prop.decode(val_d, objectset=objectset)
@@ -465,22 +536,21 @@ class ListProp(Property):
465
536
  class EnumProp(IRIProp):
466
537
  VALID_TYPES = str
467
538
 
468
- def __init__(self, values, *, pattern=None):
539
+ def __init__(self, values, *, pattern: Optional[str] = None):
469
540
  super().__init__(values, pattern=pattern)
470
541
 
471
- def validate(self, value):
542
+ def validate(self, value) -> None:
472
543
  super().validate(value)
473
544
 
474
- valid_values = self.iri_values()
475
- if value not in valid_values:
545
+ if value not in self.iri_values():
476
546
  raise ValueError(
477
- f"'{value}' is not a valid value. Choose one of {' '.join(valid_values)}"
547
+ f"'{value}' is not a valid value. Choose one of {' '.join(self.iri_values())}"
478
548
  )
479
549
 
480
- def encode(self, encoder, value, state):
550
+ def encode(self, encoder, value, state) -> None:
481
551
  encoder.write_enum(value, self, self.compact(value))
482
552
 
483
- def decode(self, decoder, *, objectset=None):
553
+ def decode(self, decoder, *, objectset: Optional[SHACLObjectSet] = None) -> str:
484
554
  v = decoder.read_enum(self)
485
555
  return self.expand(v) or v
486
556
 
@@ -491,7 +561,7 @@ class NodeKind(Enum):
491
561
  BlankNodeOrIRI = 3
492
562
 
493
563
 
494
- def is_IRI(s):
564
+ def is_IRI(s: Any) -> bool:
495
565
  if not isinstance(s, str):
496
566
  return False
497
567
  if s.startswith("_:"):
@@ -501,7 +571,7 @@ def is_IRI(s):
501
571
  return True
502
572
 
503
573
 
504
- def is_blank_node(s):
574
+ def is_blank_node(s: Any) -> bool:
505
575
  if not isinstance(s, str):
506
576
  return False
507
577
  if not s.startswith("_:"):
@@ -509,19 +579,23 @@ def is_blank_node(s):
509
579
  return True
510
580
 
511
581
 
512
- def register(type_iri, *, compact_type=None, abstract=False):
513
- def add_class(key, c):
582
+ def register(
583
+ type_iri: str, *, compact_type: Optional[str] = None, abstract: bool = False
584
+ ):
585
+ def add_class(key: str, c: Type[SHACLObject]) -> None:
514
586
  assert (
515
587
  key not in SHACLObject.CLASSES
516
588
  ), f"{key} already registered to {SHACLObject.CLASSES[key].__name__}"
517
589
  SHACLObject.CLASSES[key] = c
518
590
 
519
- def decorator(c):
591
+ def decorator(c: Type[SHACLObject]) -> Type[SHACLObject]:
592
+ """
593
+ Decorator to register a class as a SHACL object type.
594
+ The class must derive from SHACLObject.
595
+ """
520
596
  global NAMED_INDIVIDUALS
521
597
 
522
- assert issubclass(
523
- c, SHACLObject
524
- ), f"{c.__name__} is not derived from SHACLObject"
598
+ assert issubclass(c, SHACLObject), f"{c} is not derived from SHACLObject"
525
599
 
526
600
  c._OBJ_TYPE = type_iri
527
601
  c.IS_ABSTRACT = abstract
@@ -542,16 +616,32 @@ def register(type_iri, *, compact_type=None, abstract=False):
542
616
 
543
617
 
544
618
  register_lock = threading.Lock()
545
- NAMED_INDIVIDUALS = set()
619
+ NAMED_INDIVIDUALS: Set[str] = set()
620
+ T_SHACLObject = TypeVar("T_SHACLObject", bound="SHACLObject")
546
621
 
547
622
 
548
623
  @functools.total_ordering
549
624
  class SHACLObject(object):
550
- CLASSES = {}
625
+ CLASSES: Dict[str, Type] = {}
626
+ NAMED_INDIVIDUALS: Dict[str, str] = {}
551
627
  NODE_KIND = NodeKind.BlankNodeOrIRI
552
- ID_ALIAS = None
553
- IS_ABSTRACT = True
554
- IS_DEPRECATED = False
628
+ ID_ALIAS: Optional[str] = None
629
+ IS_ABSTRACT: bool = True
630
+ IS_DEPRECATED: bool = False
631
+
632
+ # These will be reinitialized during registration with @register decorator,
633
+ # defined here first to allow visibility at class level
634
+ _OBJ_TYPE: str = ""
635
+ _OBJ_COMPACT_TYPE: Optional[str] = None
636
+ _OBJ_PROPERTIES: Dict[str, Tuple] = {}
637
+ _OBJ_IRIS: Dict[str, str] = {}
638
+ _OBJ_DEPRECATED: Set[str] = set()
639
+ _NEEDS_REG: bool = True
640
+
641
+ # Instance variables
642
+ _id: Optional[str]
643
+ _obj_data: Dict[str, Any]
644
+ _obj_metadata: Dict[str, Any]
555
645
 
556
646
  def __init__(self, **kwargs):
557
647
  if self._is_abstract():
@@ -560,7 +650,9 @@ class SHACLObject(object):
560
650
  )
561
651
 
562
652
  if self.__class__.IS_DEPRECATED:
563
- warnings.warn(f"{self.__class__.__name__} is deprecated", DeprecationWarning)
653
+ warnings.warn(
654
+ f"{self.__class__.__name__} is deprecated", DeprecationWarning
655
+ )
564
656
 
565
657
  with register_lock:
566
658
  cls = self.__class__
@@ -580,24 +672,24 @@ class SHACLObject(object):
580
672
  for k, v in kwargs.items():
581
673
  setattr(self, k, v)
582
674
 
583
- def _is_abstract(self):
675
+ def _is_abstract(self) -> bool:
584
676
  return self.__class__.IS_ABSTRACT
585
677
 
586
678
  @classmethod
587
- def _register_props(cls):
679
+ def _register_props(cls: Type[SHACLObject]) -> None:
588
680
  cls._add_property("_id", StringProp(), iri="@id")
589
681
 
590
682
  @classmethod
591
683
  def _add_property(
592
- cls,
593
- pyname,
594
- prop,
595
- iri,
596
- min_count=None,
597
- max_count=None,
598
- compact=None,
599
- deprecated=False,
600
- ):
684
+ cls: Type[SHACLObject],
685
+ pyname: str,
686
+ prop: Property,
687
+ iri: str,
688
+ min_count: Optional[int] = None,
689
+ max_count: Optional[int] = None,
690
+ compact: Optional[str] = None,
691
+ deprecated: bool = False,
692
+ ) -> None:
601
693
  if pyname in cls._OBJ_IRIS:
602
694
  raise KeyError(f"'{pyname}' is already defined for '{cls.__name__}'")
603
695
  if iri in cls._OBJ_PROPERTIES:
@@ -614,7 +706,7 @@ class SHACLObject(object):
614
706
  if deprecated:
615
707
  cls._OBJ_DEPRECATED.add(iri)
616
708
 
617
- def __setattr__(self, name, value):
709
+ def __setattr__(self, name: str, value) -> None:
618
710
  if name == self.ID_ALIAS:
619
711
  self["@id"] = value
620
712
  return
@@ -627,7 +719,7 @@ class SHACLObject(object):
627
719
  f"'{name}' is not a valid property of {self.__class__.__name__}"
628
720
  )
629
721
 
630
- def __getattr__(self, name):
722
+ def __getattr__(self, name: str):
631
723
  if name in self._OBJ_IRIS:
632
724
  return self.__dict__["_obj_data"][self._OBJ_IRIS[name]]
633
725
 
@@ -650,7 +742,7 @@ class SHACLObject(object):
650
742
  f"'{name}' is not a valid property of {self.__class__.__name__}"
651
743
  )
652
744
 
653
- def __delattr__(self, name):
745
+ def __delattr__(self, name: str) -> None:
654
746
  if name == self.ID_ALIAS:
655
747
  del self["@id"]
656
748
  return
@@ -663,7 +755,9 @@ class SHACLObject(object):
663
755
  f"'{name}' is not a valid property of {self.__class__.__name__}"
664
756
  )
665
757
 
666
- def __get_prop(self, iri):
758
+ def __get_prop(
759
+ self, iri: str
760
+ ) -> Tuple[Property, Optional[int], Optional[int], str, Optional[str]]:
667
761
  if iri not in self._OBJ_PROPERTIES:
668
762
  raise KeyError(
669
763
  f"'{iri}' is not a valid property of {self.__class__.__name__}"
@@ -671,45 +765,51 @@ class SHACLObject(object):
671
765
 
672
766
  return self._OBJ_PROPERTIES[iri]
673
767
 
674
- def __iter_props(self):
768
+ def __iter_props(
769
+ self,
770
+ ) -> Iterator[
771
+ Tuple[str, Property, Optional[int], Optional[int], str, Optional[str]]
772
+ ]:
675
773
  for iri, v in self._OBJ_PROPERTIES.items():
676
774
  yield iri, *v
677
775
 
678
- def __getitem__(self, iri):
776
+ def __getitem__(self, iri: str) -> Any:
679
777
  return self.__dict__["_obj_data"][iri]
680
778
 
681
- def __setitem__(self, iri, value):
779
+ def __setitem__(self, iri: str, value) -> None:
682
780
  if iri == "@id":
683
781
  if self.NODE_KIND == NodeKind.BlankNode:
684
782
  if not is_blank_node(value):
685
783
  raise ValueError(
686
- f"{self.__class__.__name__} ({id(self)}) can only have local reference. Property '{iri}' cannot be set to '{value}' and must start with '_:'"
784
+ f"{self.__class__.__name__} ({id(self)}) can only have local reference. Property '{iri}' cannot be set to {value!r} and must start with '_:'"
687
785
  )
688
786
  elif self.NODE_KIND == NodeKind.IRI:
689
787
  if not is_IRI(value):
690
788
  raise ValueError(
691
- f"{self.__class__.__name__} ({id(self)}) can only have an IRI value. Property '{iri}' cannot be set to '{value}'"
789
+ f"{self.__class__.__name__} ({id(self)}) can only have an IRI value. Property '{iri}' cannot be set to {value!r}"
692
790
  )
693
791
  else:
694
792
  if not is_blank_node(value) and not is_IRI(value):
695
793
  raise ValueError(
696
- f"{self.__class__.__name__} ({id(self)}) Has invalid Property '{iri}' '{value}'. Must be a blank node or IRI"
794
+ f"{self.__class__.__name__} ({id(self)}) Has invalid Property '{iri}' {value!r}. Must be a blank node or IRI"
697
795
  )
698
796
 
699
797
  prop, _, _, pyname, _ = self.__get_prop(iri)
700
798
  prop.validate(value)
701
799
  if iri in self._OBJ_DEPRECATED:
702
- warnings.warn(f"{self.__class__.__name__}.{pyname} is deprecated", DeprecationWarning)
800
+ warnings.warn(
801
+ f"{self.__class__.__name__}.{pyname} is deprecated", DeprecationWarning
802
+ )
703
803
  self.__dict__["_obj_data"][iri] = prop.set(value)
704
804
 
705
- def __delitem__(self, iri):
805
+ def __delitem__(self, iri: str) -> None:
706
806
  prop, _, _, _, _ = self.__get_prop(iri)
707
807
  self.__dict__["_obj_data"][iri] = prop.init()
708
808
 
709
- def __iter__(self):
710
- return self._OBJ_PROPERTIES.keys()
809
+ def __iter__(self) -> Iterator[str]:
810
+ return iter(self._OBJ_PROPERTIES.keys())
711
811
 
712
- def walk(self, callback, path=None):
812
+ def walk(self, callback: Callable, path: Optional[List[str]] = None) -> None:
713
813
  """
714
814
  Walk object tree, invoking the callback for each item
715
815
 
@@ -724,13 +824,13 @@ class SHACLObject(object):
724
824
  for iri, prop, _, _, _, _ in self.__iter_props():
725
825
  prop.walk(self.__dict__["_obj_data"][iri], callback, path + [f".{iri}"])
726
826
 
727
- def property_keys(self):
827
+ def property_keys(self) -> Iterator[Tuple[Optional[str], str, Optional[str]]]:
728
828
  for iri, _, _, _, pyname, compact in self.__iter_props():
729
829
  if iri == "@id":
730
830
  compact = self.ID_ALIAS
731
831
  yield pyname, iri, compact
732
832
 
733
- def iter_objects(self, *, recursive=False, visited=None):
833
+ def iter_objects(self, *, recursive: bool = False, visited=None):
734
834
  """
735
835
  Iterate of all objects that are a child of this one
736
836
  """
@@ -743,7 +843,7 @@ class SHACLObject(object):
743
843
  ):
744
844
  yield c
745
845
 
746
- def encode(self, encoder, state):
846
+ def encode(self, encoder, state) -> None:
747
847
  idname = self.ID_ALIAS or self._OBJ_IRIS["_id"]
748
848
  if not self._id and self.NODE_KIND == NodeKind.IRI:
749
849
  raise ValueError(
@@ -763,7 +863,7 @@ class SHACLObject(object):
763
863
  ) as obj_s:
764
864
  self._encode_properties(obj_s, state)
765
865
 
766
- def _encode_properties(self, encoder, state):
866
+ def _encode_properties(self, encoder, state) -> None:
767
867
  for iri, prop, min_count, max_count, pyname, compact in self.__iter_props():
768
868
  value = self.__dict__["_obj_data"][iri]
769
869
  if prop.elide(value):
@@ -792,52 +892,45 @@ class SHACLObject(object):
792
892
  prop.encode(prop_s, value, state)
793
893
 
794
894
  @classmethod
795
- def _make_object(cls, typ):
895
+ def _make_object(cls: Type["SHACLObject"], typ: str) -> "SHACLObject":
796
896
  if typ not in cls.CLASSES:
797
897
  raise TypeError(f"Unknown type {typ}")
798
898
 
799
899
  return cls.CLASSES[typ]()
800
900
 
801
901
  @classmethod
802
- def decode(cls, decoder, *, objectset=None):
902
+ def decode(cls, decoder, *, objectset: Optional[SHACLObjectSet] = None):
803
903
  typ, obj_d = decoder.read_object()
804
904
  if typ is None:
805
905
  raise TypeError("Unable to determine type for object")
806
906
 
807
907
  obj = cls._make_object(typ)
808
- for key in (obj.ID_ALIAS, obj._OBJ_IRIS["_id"]):
809
- with obj_d.read_property(key) as prop_d:
810
- if prop_d is None:
811
- continue
812
-
813
- _id = prop_d.read_iri()
814
- if _id is None:
815
- raise TypeError(f"Object key '{key}' is the wrong type")
816
-
817
- obj._id = _id
818
- break
908
+ _id = obj_d.read_object_id(obj.ID_ALIAS)
909
+ if _id is not None:
910
+ obj._id = _id
819
911
 
820
912
  if obj.NODE_KIND == NodeKind.IRI and not obj._id:
821
913
  raise ValueError("Object is missing required IRI")
822
914
 
823
915
  if objectset is not None:
824
916
  if obj._id:
825
- v = objectset.find_by_id(_id)
917
+ v = objectset.find_by_id(obj._id)
826
918
  if v is not None:
827
919
  return v
920
+ objectset.add_index(obj)
828
921
 
829
922
  obj._decode_properties(obj_d, objectset=objectset)
830
923
 
831
- if objectset is not None:
832
- objectset.add_index(obj)
833
924
  return obj
834
925
 
835
- def _decode_properties(self, decoder, objectset=None):
926
+ def _decode_properties(
927
+ self, decoder, objectset: Optional[SHACLObjectSet] = None
928
+ ) -> None:
836
929
  for key in decoder.object_keys():
837
930
  if not self._decode_prop(decoder, key, objectset=objectset):
838
931
  raise KeyError(f"Unknown property '{key}'")
839
932
 
840
- def _decode_prop(self, decoder, key, objectset=None):
933
+ def _decode_prop(self, decoder, key, objectset: Optional[SHACLObjectSet] = None):
841
934
  if key in (self._OBJ_IRIS["_id"], self.ID_ALIAS):
842
935
  return True
843
936
 
@@ -857,7 +950,9 @@ class SHACLObject(object):
857
950
 
858
951
  return False
859
952
 
860
- def link_helper(self, objectset, missing, visited):
953
+ def link_helper(
954
+ self, objectset: Optional[SHACLObjectSet], missing, visited
955
+ ) -> None:
861
956
  if self in visited:
862
957
  return
863
958
 
@@ -900,7 +995,7 @@ class SHACLObject(object):
900
995
  return sort_key(self) < sort_key(other)
901
996
 
902
997
 
903
- class SHACLExtensibleObject(object):
998
+ class SHACLExtensibleObject(SHACLObject):
904
999
  CLOSED = False
905
1000
 
906
1001
  def __init__(self, typ=None, **kwargs):
@@ -910,7 +1005,7 @@ class SHACLExtensibleObject(object):
910
1005
  self.__dict__["_obj_TYPE"] = (self._OBJ_TYPE, self._OBJ_COMPACT_TYPE)
911
1006
  super().__init__(**kwargs)
912
1007
 
913
- def _is_abstract(self):
1008
+ def _is_abstract(self) -> bool:
914
1009
  # Unknown classes are assumed to not be abstract so that they can be
915
1010
  # deserialized
916
1011
  typ = self.__dict__["_obj_TYPE"][0]
@@ -928,7 +1023,9 @@ class SHACLExtensibleObject(object):
928
1023
  obj = cls(typ)
929
1024
  return obj
930
1025
 
931
- def _decode_properties(self, decoder, objectset=None):
1026
+ def _decode_properties(
1027
+ self, decoder, objectset: Optional[SHACLObjectSet] = None
1028
+ ) -> None:
932
1029
  def decode_value(d):
933
1030
  if not d.is_list():
934
1031
  return d.read_value()
@@ -951,26 +1048,7 @@ class SHACLExtensibleObject(object):
951
1048
  with decoder.read_property(key) as prop_d:
952
1049
  self.__dict__["_obj_data"][key] = decode_value(prop_d)
953
1050
 
954
- def _encode_properties(self, encoder, state):
955
- def encode_value(encoder, v):
956
- if isinstance(v, bool):
957
- encoder.write_bool(v)
958
- elif isinstance(v, str):
959
- encoder.write_string(v)
960
- elif isinstance(v, int):
961
- encoder.write_integer(v)
962
- elif isinstance(v, float):
963
- encoder.write_float(v)
964
- elif isinstance(v, list):
965
- with encoder.write_list() as list_s:
966
- for i in v:
967
- with list_s.write_list_item() as item_s:
968
- encode_value(item_s, i)
969
- else:
970
- raise TypeError(
971
- f"Unsupported serialized type {type(v)} with value '{v}'"
972
- )
973
-
1051
+ def _encode_properties(self, encoder, state) -> None:
974
1052
  super()._encode_properties(encoder, state)
975
1053
  if self.CLOSED:
976
1054
  return
@@ -980,9 +1058,27 @@ class SHACLExtensibleObject(object):
980
1058
  continue
981
1059
 
982
1060
  with encoder.write_property(iri) as prop_s:
983
- encode_value(prop_s, value)
984
-
985
- def __setitem__(self, iri, value):
1061
+ if isinstance(value, list):
1062
+ v = value
1063
+ else:
1064
+ v = [value]
1065
+ with prop_s.write_list() as list_s:
1066
+ for i in v:
1067
+ with list_s.write_list_item() as item_s:
1068
+ if isinstance(i, bool):
1069
+ item_s.write_bool(i)
1070
+ elif isinstance(i, str):
1071
+ item_s.write_string(i)
1072
+ elif isinstance(i, int):
1073
+ item_s.write_integer(i)
1074
+ elif isinstance(i, float):
1075
+ item_s.write_float(i)
1076
+ else:
1077
+ raise TypeError(
1078
+ f"Unsupported serialized type {type(i)} with value {i!r}"
1079
+ )
1080
+
1081
+ def __setitem__(self, iri: str, value) -> None:
986
1082
  try:
987
1083
  super().__setitem__(iri, value)
988
1084
  except KeyError:
@@ -991,9 +1087,10 @@ class SHACLExtensibleObject(object):
991
1087
 
992
1088
  if not is_IRI(iri):
993
1089
  raise KeyError(f"Key '{iri}' must be an IRI")
1090
+ obj_data = self.__dict__["_obj_data"]
994
1091
  self.__dict__["_obj_data"][iri] = value
995
1092
 
996
- def __delitem__(self, iri):
1093
+ def __delitem__(self, iri: str) -> None:
997
1094
  try:
998
1095
  super().__delitem__(iri)
999
1096
  except KeyError:
@@ -1011,8 +1108,8 @@ class SHACLExtensibleObject(object):
1011
1108
  return self.__dict__["_obj_TYPE"][1]
1012
1109
  return super().__getattr__(name)
1013
1110
 
1014
- def property_keys(self):
1015
- iris = set()
1111
+ def property_keys(self) -> Iterator[Tuple[Optional[str], str, Optional[str]]]:
1112
+ iris: Set[str] = set()
1016
1113
  for pyname, iri, compact in super().property_keys():
1017
1114
  iris.add(iri)
1018
1115
  yield pyname, iri, compact
@@ -1026,16 +1123,16 @@ class SHACLExtensibleObject(object):
1026
1123
 
1027
1124
 
1028
1125
  class SHACLObjectSet(object):
1029
- def __init__(self, objects=[], *, link=False):
1030
- self.objects = set()
1031
- self.missing_ids = set()
1032
- for o in objects:
1033
- self.objects.add(o)
1126
+ def __init__(self, objects: Collection[SHACLObject] = [], *, link: bool = False):
1127
+ self.objects: Set[SHACLObject] = set(objects)
1128
+ self.missing_ids: Set[str] = set()
1129
+ self.obj_by_id: Dict[str, SHACLObject] = {}
1130
+ self.obj_by_type: Dict[str, Set[Tuple[bool, SHACLObject]]] = {}
1034
1131
  self.create_index()
1035
1132
  if link:
1036
1133
  self._link()
1037
1134
 
1038
- def create_index(self):
1135
+ def create_index(self) -> None:
1039
1136
  """
1040
1137
  (re)Create object index
1041
1138
 
@@ -1047,7 +1144,7 @@ class SHACLObjectSet(object):
1047
1144
  for o in self.foreach():
1048
1145
  self.add_index(o)
1049
1146
 
1050
- def add_index(self, obj):
1147
+ def add_index(self, obj: SHACLObject) -> None:
1051
1148
  """
1052
1149
  Add object to index
1053
1150
 
@@ -1081,7 +1178,7 @@ class SHACLObjectSet(object):
1081
1178
 
1082
1179
  self.obj_by_id[obj._id] = obj
1083
1180
 
1084
- def add(self, obj):
1181
+ def add(self, obj: SHACLObject) -> SHACLObject:
1085
1182
  """
1086
1183
  Add object to object set
1087
1184
 
@@ -1097,7 +1194,7 @@ class SHACLObjectSet(object):
1097
1194
  self.add_index(obj)
1098
1195
  return obj
1099
1196
 
1100
- def update(self, *others):
1197
+ def update(self, *others) -> None:
1101
1198
  """
1102
1199
  Update object set adding all objects in each other iterable
1103
1200
  """
@@ -1105,13 +1202,13 @@ class SHACLObjectSet(object):
1105
1202
  for obj in o:
1106
1203
  self.add(obj)
1107
1204
 
1108
- def __contains__(self, item):
1205
+ def __contains__(self, item: SHACLObject) -> bool:
1109
1206
  """
1110
1207
  Returns True if the item is in the object set
1111
1208
  """
1112
1209
  return item in self.objects
1113
1210
 
1114
- def link(self):
1211
+ def link(self) -> Set[str]:
1115
1212
  """
1116
1213
  Link object set
1117
1214
 
@@ -1127,24 +1224,24 @@ class SHACLObjectSet(object):
1127
1224
  self.create_index()
1128
1225
  return self._link()
1129
1226
 
1130
- def _link(self):
1227
+ def _link(self) -> Set[str]:
1131
1228
  global NAMED_INDIVIDUALS
1132
1229
 
1133
1230
  self.missing_ids = set()
1134
- visited = set()
1231
+ visited: Set[SHACLObject] = set()
1135
1232
 
1136
- new_objects = set()
1233
+ new_objects: Set[SHACLObject] = set()
1137
1234
 
1138
1235
  for o in self.objects:
1139
1236
  if o._id:
1140
- o = self.find_by_id(o._id, o)
1237
+ o = cast(SHACLObject, self.find_by_id(o._id, o))
1141
1238
  o.link_helper(self, self.missing_ids, visited)
1142
1239
  new_objects.add(o)
1143
1240
 
1144
1241
  self.objects = new_objects
1145
1242
 
1146
1243
  # Remove blank nodes
1147
- obj_by_id = {}
1244
+ obj_by_id: Dict[str, SHACLObject] = {}
1148
1245
  for _id, obj in self.obj_by_id.items():
1149
1246
  if _id.startswith("_:"):
1150
1247
  del obj._id
@@ -1157,7 +1254,9 @@ class SHACLObjectSet(object):
1157
1254
 
1158
1255
  return self.missing_ids
1159
1256
 
1160
- def find_by_id(self, _id, default=None):
1257
+ def find_by_id(
1258
+ self, _id: str, default: Optional[SHACLObject] = None
1259
+ ) -> Optional[SHACLObject]:
1161
1260
  """
1162
1261
  Find object by ID
1163
1262
 
@@ -1168,7 +1267,7 @@ class SHACLObjectSet(object):
1168
1267
  return default
1169
1268
  return self.obj_by_id[_id]
1170
1269
 
1171
- def foreach(self):
1270
+ def foreach(self) -> Iterable[SHACLObject]:
1172
1271
  """
1173
1272
  Iterate over every object in the object set, and all child objects
1174
1273
  """
@@ -1181,7 +1280,18 @@ class SHACLObjectSet(object):
1181
1280
  for child in o.iter_objects(recursive=True, visited=visited):
1182
1281
  yield child
1183
1282
 
1184
- def foreach_type(self, typ, *, match_subclass=True):
1283
+ @overload
1284
+ def foreach_type(
1285
+ self, typ: str, *, match_subclass: bool = True
1286
+ ) -> Iterator[SHACLObject]: ...
1287
+ @overload
1288
+ def foreach_type(
1289
+ self, typ: Type[T_SHACLObject], *, match_subclass: bool = True
1290
+ ) -> Iterator[T_SHACLObject]: ...
1291
+
1292
+ def foreach_type(
1293
+ self, typ: Union[str, Type[T_SHACLObject]], *, match_subclass: bool = True
1294
+ ) -> Iterable[SHACLObject]:
1185
1295
  """
1186
1296
  Iterate over each object of a specified type (or subclass there of)
1187
1297
 
@@ -1190,18 +1300,20 @@ class SHACLObjectSet(object):
1190
1300
  returned
1191
1301
  """
1192
1302
  if not isinstance(typ, str):
1193
- if not issubclass(typ, SHACLObject):
1303
+ if not isinstance(typ, type) or not issubclass(typ, SHACLObject):
1194
1304
  raise TypeError(f"Type must be derived from SHACLObject, got {typ}")
1195
- typ = typ._OBJ_TYPE
1305
+ # This intermediate step is necessary for pyrefly...
1306
+ typ_class: Type[SHACLObject] = typ
1307
+ typ = typ_class._OBJ_TYPE
1196
1308
 
1197
1309
  if typ not in self.obj_by_type:
1198
1310
  return
1199
1311
 
1200
1312
  for exact, o in self.obj_by_type[typ]:
1201
1313
  if match_subclass or exact:
1202
- yield o
1314
+ yield cast(T_SHACLObject, o)
1203
1315
 
1204
- def merge(self, *objectsets):
1316
+ def merge(self, *objectsets) -> "SHACLObjectSet":
1205
1317
  """
1206
1318
  Merge object sets
1207
1319
 
@@ -1215,16 +1327,59 @@ class SHACLObjectSet(object):
1215
1327
 
1216
1328
  return SHACLObjectSet(new_objects, link=True)
1217
1329
 
1218
- def encode(self, encoder, force_list=False, *, key=None):
1330
+ def inline_blank_nodes(self) -> None:
1331
+ """
1332
+ Removes (inlines) blank node objects from the root object set if they
1333
+ are referenced in only one other location besides the root.
1334
+
1335
+ Deserializers that do not preserve the tree-like structure of the
1336
+ objects (e.g. RDF) should call this to ensure that blank nodes are
1337
+ inline correctly
1338
+ """
1339
+ ref_counts: Dict[SHACLObject, int] = {}
1340
+
1341
+ def walk_callback(value: SHACLObject, path: List[str]) -> bool:
1342
+ nonlocal ref_counts
1343
+
1344
+ if not isinstance(value, SHACLObject):
1345
+ return True
1346
+
1347
+ ref_counts.setdefault(value, 0)
1348
+ ref_counts[value] += 1
1349
+ if ref_counts[value] > 1:
1350
+ return False
1351
+
1352
+ return True
1353
+
1354
+ for o in self.objects:
1355
+ # Note that every object in the root object set gets at least one
1356
+ # reference
1357
+ o.walk(walk_callback)
1358
+
1359
+ new_objects = set()
1360
+ for o in self.objects:
1361
+ if is_IRI(o._id):
1362
+ new_objects.add(o)
1363
+ # If the object is a blank node and is only referenced by this
1364
+ # root list and one other location, remove it from the root list
1365
+ #
1366
+ # A count of 1 means the object is only referenced by the root, and
1367
+ # therefore must be kept
1368
+ elif ref_counts[o] != 2:
1369
+ new_objects.add(o)
1370
+
1371
+ self.objects = new_objects
1372
+
1373
+ def encode(self, encoder, force_list: bool = False, *, key=None) -> None:
1219
1374
  """
1220
1375
  Serialize a list of objects to a serialization encoder
1221
1376
 
1222
1377
  If force_list is true, a list will always be written using the encoder.
1223
1378
  """
1224
- ref_counts = {}
1379
+ ref_counts: Dict[SHACLObject, int] = {}
1225
1380
  state = EncodeState()
1226
1381
 
1227
- def walk_callback(value, path):
1382
+ def walk_callback(value: SHACLObject, path: List[str]) -> bool:
1228
1383
  nonlocal state
1229
1384
  nonlocal ref_counts
1230
1385
 
@@ -1232,7 +1387,7 @@ class SHACLObjectSet(object):
1232
1387
  return True
1233
1388
 
1234
1389
  # Remove blank node ID for re-assignment
1235
- if value._id and value._id.startswith("_:"):
1390
+ if is_blank_node(value._id):
1236
1391
  del value._id
1237
1392
 
1238
1393
  if value._id:
@@ -1290,7 +1445,7 @@ class SHACLObjectSet(object):
1290
1445
  self.create_index()
1291
1446
 
1292
1447
  for obj_d in decoder.read_list():
1293
- o = SHACLObject.decode(obj_d, objectset=self)
1448
+ o = SHACLExtensibleObject.decode(obj_d, objectset=self)
1294
1449
  self.objects.add(o)
1295
1450
 
1296
1451
  self._link()
@@ -1312,13 +1467,13 @@ class EncodeState(object):
1312
1467
 
1313
1468
  return self.blank_objects[o]
1314
1469
 
1315
- def is_refed(self, o):
1470
+ def is_refed(self, o) -> bool:
1316
1471
  return o in self.ref_objects
1317
1472
 
1318
- def add_refed(self, o):
1473
+ def add_refed(self, o) -> None:
1319
1474
  self.ref_objects.add(o)
1320
1475
 
1321
- def is_written(self, o):
1476
+ def is_written(self, o) -> bool:
1322
1477
  return o in self.written_objects
1323
1478
 
1324
1479
  def add_written(self, o):
@@ -1327,26 +1482,26 @@ class EncodeState(object):
1327
1482
 
1328
1483
  class Decoder(ABC):
1329
1484
  @abstractmethod
1330
- def read_value(self):
1485
+ def read_value(self) -> Optional[Any]:
1331
1486
  """
1332
1487
  Consume next item
1333
1488
 
1334
1489
  Consumes the next item of any type
1335
1490
  """
1336
- pass
1491
+ raise NotImplementedError("Subclasses must implement read_value method")
1337
1492
 
1338
1493
  @abstractmethod
1339
- def read_string(self):
1494
+ def read_string(self) -> Optional[str]:
1340
1495
  """
1341
1496
  Consume the next item as a string.
1342
1497
 
1343
1498
  Returns the string value of the next item, or `None` if the next item
1344
1499
  is not a string
1345
1500
  """
1346
- pass
1501
+ raise NotImplementedError("Subclasses must implement read_string method")
1347
1502
 
1348
1503
  @abstractmethod
1349
- def read_datetime(self):
1504
+ def read_datetime(self) -> Optional[str]:
1350
1505
  """
1351
1506
  Consumes the next item as a date & time string
1352
1507
 
@@ -1357,20 +1512,20 @@ class Decoder(ABC):
1357
1512
  implementation can just check if the next item is a string without
1358
1513
  worrying about the format
1359
1514
  """
1360
- pass
1515
+ raise NotImplementedError("Subclasses must implement read_datetime method")
1361
1516
 
1362
1517
  @abstractmethod
1363
- def read_integer(self):
1518
+ def read_integer(self) -> Optional[int]:
1364
1519
  """
1365
1520
  Consumes the next item as an integer
1366
1521
 
1367
1522
  Returns the integer value of the next item, or `None` if the next item
1368
1523
  is not an integer
1369
1524
  """
1370
- pass
1525
+ raise NotImplementedError("Subclasses must implement read_integer method")
1371
1526
 
1372
1527
  @abstractmethod
1373
- def read_iri(self):
1528
+ def read_iri(self) -> Optional[str]:
1374
1529
  """
1375
1530
  Consumes the next item as an IRI string
1376
1531
 
@@ -1380,10 +1535,10 @@ class Decoder(ABC):
1380
1535
  The returned string should be either a fully-qualified IRI, or a blank
1381
1536
  node ID
1382
1537
  """
1383
- pass
1538
+ raise NotImplementedError("Subclasses must implement read_iri method")
1384
1539
 
1385
1540
  @abstractmethod
1386
- def read_enum(self, e):
1541
+ def read_enum(self, e) -> Optional[str]:
1387
1542
  """
1388
1543
  Consumes the next item as an Enum value string
1389
1544
 
@@ -1394,30 +1549,30 @@ class Decoder(ABC):
1394
1549
  actually a member of the specified Enum, so the `Decoder` does not need
1395
1550
  to check that, but can if it wishes
1396
1551
  """
1397
- pass
1552
+ raise NotImplementedError("Subclasses must implement read_enum method")
1398
1553
 
1399
1554
  @abstractmethod
1400
- def read_bool(self):
1555
+ def read_bool(self) -> Optional[bool]:
1401
1556
  """
1402
1557
  Consume the next item as a boolean value
1403
1558
 
1404
1559
  Returns the boolean value of the next item, or `None` if the next item
1405
1560
  is not a boolean
1406
1561
  """
1407
- pass
1562
+ raise NotImplementedError("Subclasses must implement read_bool method")
1408
1563
 
1409
1564
  @abstractmethod
1410
- def read_float(self):
1565
+ def read_float(self) -> Optional[float]:
1411
1566
  """
1412
1567
  Consume the next item as a float value
1413
1568
 
1414
1569
  Returns the float value of the next item, or `None` if the next item is
1415
1570
  not a float
1416
1571
  """
1417
- pass
1572
+ raise NotImplementedError("Subclasses must implement read_float method")
1418
1573
 
1419
1574
  @abstractmethod
1420
- def read_list(self):
1575
+ def read_list(self) -> Iterator["Decoder"]:
1421
1576
  """
1422
1577
  Consume the next item as a list generator
1423
1578
 
@@ -1425,19 +1580,19 @@ class Decoder(ABC):
1425
1580
  generated `Decoder` can be used to read the corresponding item from the
1426
1581
  list
1427
1582
  """
1428
- pass
1583
+ raise NotImplementedError("Subclasses must implement read_list method")
1429
1584
 
1430
1585
  @abstractmethod
1431
- def is_list(self):
1586
+ def is_list(self) -> bool:
1432
1587
  """
1433
1588
  Checks if the next item is a list
1434
1589
 
1435
1590
  Returns True if the next item is a list, or False if it is a scalar
1436
1591
  """
1437
- pass
1592
+ raise NotImplementedError("Subclasses must implement is_list method")
1438
1593
 
1439
1594
  @abstractmethod
1440
- def read_object(self):
1595
+ def read_object(self) -> Tuple[Any, "Decoder"]:
1441
1596
  """
1442
1597
  Consume next item as an object
1443
1598
 
@@ -1448,11 +1603,11 @@ class Decoder(ABC):
1448
1603
  Properties will be read out of the object using `read_property` and
1449
1604
  `read_object_id`
1450
1605
  """
1451
- pass
1606
+ raise NotImplementedError("Subclasses must implement read_object method")
1452
1607
 
1453
1608
  @abstractmethod
1454
1609
  @contextmanager
1455
- def read_property(self, key):
1610
+ def read_property(self, key) -> Iterator[Optional["Decoder"]]:
1456
1611
  """
1457
1612
  Read property from object
1458
1613
 
@@ -1460,19 +1615,28 @@ class Decoder(ABC):
1460
1615
  value of the property with the given key in current object, or `None`
1461
1616
  if the property does not exist in the current object.
1462
1617
  """
1463
- pass
1618
+ raise NotImplementedError("Subclasses must implement read_property method")
1619
+
1620
+ @abstractmethod
1621
+ def is_object(self) -> bool:
1622
+ """
1623
+ Checks if the item is an object
1624
+
1625
+ Returns True if the item is an object, or False if is not
1626
+ """
1627
+ raise NotImplementedError("Subclasses must implement is_object method")
1464
1628
 
1465
1629
  @abstractmethod
1466
- def object_keys(self):
1630
+ def object_keys(self) -> Iterator[str]:
1467
1631
  """
1468
1632
  Read property keys from an object
1469
1633
 
1470
1634
  Iterates over all the serialized keys for the current object
1471
1635
  """
1472
- pass
1636
+ raise NotImplementedError("Subclasses must implement object_keys method")
1473
1637
 
1474
1638
  @abstractmethod
1475
- def read_object_id(self, alias=None):
1639
+ def read_object_id(self, alias=None) -> Optional[Any]:
1476
1640
  """
1477
1641
  Read current object ID property
1478
1642
 
@@ -1484,15 +1648,15 @@ class Decoder(ABC):
1484
1648
  If `alias` is provided, is is a hint as to another name by which the ID
1485
1649
  might be found, if the `Decoder` supports aliases for an ID
1486
1650
  """
1487
- pass
1651
+ raise NotImplementedError("Subclasses must implement read_object_id method")
1488
1652
 
1489
1653
 
1490
1654
  class JSONLDDecoder(Decoder):
1491
- def __init__(self, data, root=False):
1655
+ def __init__(self, data, root: bool = False):
1492
1656
  self.data = data
1493
1657
  self.root = root
1494
1658
 
1495
- def read_value(self):
1659
+ def read_value(self) -> Optional[Any]:
1496
1660
  if isinstance(self.data, str):
1497
1661
  try:
1498
1662
  return float(self.data)
@@ -1500,47 +1664,47 @@ class JSONLDDecoder(Decoder):
1500
1664
  pass
1501
1665
  return self.data
1502
1666
 
1503
- def read_string(self):
1667
+ def read_string(self) -> Optional[str]:
1504
1668
  if isinstance(self.data, str):
1505
1669
  return self.data
1506
1670
  return None
1507
1671
 
1508
- def read_datetime(self):
1672
+ def read_datetime(self) -> Optional[str]:
1509
1673
  return self.read_string()
1510
1674
 
1511
- def read_integer(self):
1675
+ def read_integer(self) -> Optional[int]:
1512
1676
  if isinstance(self.data, int):
1513
1677
  return self.data
1514
1678
  return None
1515
1679
 
1516
- def read_bool(self):
1680
+ def read_bool(self) -> Optional[bool]:
1517
1681
  if isinstance(self.data, bool):
1518
1682
  return self.data
1519
1683
  return None
1520
1684
 
1521
- def read_float(self):
1685
+ def read_float(self) -> Optional[float]:
1522
1686
  if isinstance(self.data, (int, float, str)):
1523
1687
  return float(self.data)
1524
1688
  return None
1525
1689
 
1526
- def read_iri(self):
1690
+ def read_iri(self) -> Optional[str]:
1527
1691
  if isinstance(self.data, str):
1528
1692
  return self.data
1529
1693
  return None
1530
1694
 
1531
- def read_enum(self, e):
1695
+ def read_enum(self, e) -> Optional[str]:
1532
1696
  if isinstance(self.data, str):
1533
1697
  return self.data
1534
1698
  return None
1535
1699
 
1536
- def read_list(self):
1700
+ def read_list(self) -> Iterator["JSONLDDecoder"]:
1537
1701
  if self.is_list():
1538
1702
  for v in self.data:
1539
1703
  yield self.__class__(v)
1540
1704
  else:
1541
1705
  yield self
1542
1706
 
1543
- def is_list(self):
1707
+ def is_list(self) -> bool:
1544
1708
  return isinstance(self.data, (list, tuple, set))
1545
1709
 
1546
1710
  def __get_value(self, *keys):
@@ -1550,14 +1714,17 @@ class JSONLDDecoder(Decoder):
1550
1714
  return None
1551
1715
 
1552
1716
  @contextmanager
1553
- def read_property(self, key):
1717
+ def read_property(self, key) -> Iterator[Optional["JSONLDDecoder"]]:
1554
1718
  v = self.__get_value(key)
1555
1719
  if v is not None:
1556
1720
  yield self.__class__(v)
1557
1721
  else:
1558
1722
  yield None
1559
1723
 
1560
- def object_keys(self):
1724
+ def is_object(self) -> bool:
1725
+ return isinstance(self.data, dict)
1726
+
1727
+ def object_keys(self) -> Iterator[str]:
1561
1728
  for key in self.data.keys():
1562
1729
  if key in ("@type", "type"):
1563
1730
  continue
@@ -1565,19 +1732,19 @@ class JSONLDDecoder(Decoder):
1565
1732
  continue
1566
1733
  yield key
1567
1734
 
1568
- def read_object(self):
1735
+ def read_object(self) -> Tuple[Any, "JSONLDDecoder"]:
1569
1736
  typ = self.__get_value("@type", "type")
1570
1737
  if typ is not None:
1571
1738
  return typ, self
1572
1739
 
1573
1740
  return None, self
1574
1741
 
1575
- def read_object_id(self, alias=None):
1742
+ def read_object_id(self, alias=None) -> Optional[Any]:
1576
1743
  return self.__get_value(alias, "@id")
1577
1744
 
1578
1745
 
1579
1746
  class JSONLDDeserializer(object):
1580
- def deserialize_data(self, data, objectset: SHACLObjectSet):
1747
+ def deserialize_data(self, data, objectset: SHACLObjectSet) -> None:
1581
1748
  if "@graph" in data:
1582
1749
  h = JSONLDDecoder(data["@graph"], True)
1583
1750
  else:
@@ -1585,23 +1752,23 @@ class JSONLDDeserializer(object):
1585
1752
 
1586
1753
  objectset.decode(h)
1587
1754
 
1588
- def read(self, f, objectset: SHACLObjectSet):
1755
+ def read(self, f, objectset: SHACLObjectSet) -> None:
1589
1756
  data = json.load(f)
1590
1757
  self.deserialize_data(data, objectset)
1591
1758
 
1592
1759
 
1593
1760
  class Encoder(ABC):
1594
1761
  @abstractmethod
1595
- def write_string(self, v):
1762
+ def write_string(self, v) -> None:
1596
1763
  """
1597
1764
  Write a string value
1598
1765
 
1599
1766
  Encodes the value as a string in the output
1600
1767
  """
1601
- pass
1768
+ raise NotImplementedError("Subclasses must implement write_string method")
1602
1769
 
1603
1770
  @abstractmethod
1604
- def write_datetime(self, v):
1771
+ def write_datetime(self, v) -> None:
1605
1772
  """
1606
1773
  Write a date & time string
1607
1774
 
@@ -1609,19 +1776,19 @@ class Encoder(ABC):
1609
1776
 
1610
1777
  Note: The provided string is already correctly encoded as an ISO datetime
1611
1778
  """
1612
- pass
1779
+ raise NotImplementedError("Subclasses must implement write_datetime method")
1613
1780
 
1614
1781
  @abstractmethod
1615
- def write_integer(self, v):
1782
+ def write_integer(self, v) -> None:
1616
1783
  """
1617
1784
  Write an integer value
1618
1785
 
1619
1786
  Encodes the value as an integer in the output
1620
1787
  """
1621
- pass
1788
+ raise NotImplementedError("Subclasses must implement write_integer method")
1622
1789
 
1623
1790
  @abstractmethod
1624
- def write_iri(self, v, compact=None):
1791
+ def write_iri(self, v, compact=None) -> None:
1625
1792
  """
1626
1793
  Write IRI
1627
1794
 
@@ -1630,10 +1797,10 @@ class Encoder(ABC):
1630
1797
  the serialization supports compacted IRIs, it should be preferred to
1631
1798
  the full IRI
1632
1799
  """
1633
- pass
1800
+ raise NotImplementedError("Subclasses must implement write_iri method")
1634
1801
 
1635
1802
  @abstractmethod
1636
- def write_enum(self, v, e, compact=None):
1803
+ def write_enum(self, v, e, compact=None) -> None:
1637
1804
  """
1638
1805
  Write enum value IRI
1639
1806
 
@@ -1641,29 +1808,29 @@ class Encoder(ABC):
1641
1808
  qualified IRI. If `compact` is provided and the serialization supports
1642
1809
  compacted IRIs, it should be preferred to the full IRI.
1643
1810
  """
1644
- pass
1811
+ raise NotImplementedError("Subclasses must implement write_enum method")
1645
1812
 
1646
1813
  @abstractmethod
1647
- def write_bool(self, v):
1814
+ def write_bool(self, v) -> None:
1648
1815
  """
1649
1816
  Write boolean
1650
1817
 
1651
1818
  Encodes the value as a boolean in the output
1652
1819
  """
1653
- pass
1820
+ raise NotImplementedError("Subclasses must implement write_bool method")
1654
1821
 
1655
1822
  @abstractmethod
1656
- def write_float(self, v):
1823
+ def write_float(self, v) -> None:
1657
1824
  """
1658
1825
  Write float
1659
1826
 
1660
1827
  Encodes the value as a floating point number in the output
1661
1828
  """
1662
- pass
1829
+ raise NotImplementedError("Subclasses must implement write_float method")
1663
1830
 
1664
1831
  @abstractmethod
1665
1832
  @contextmanager
1666
- def write_object(self, o, _id, needs_id):
1833
+ def write_object(self, o: SHACLObject, _id: str, needs_id: bool):
1667
1834
  """
1668
1835
  Write object
1669
1836
 
@@ -1681,11 +1848,11 @@ class Encoder(ABC):
1681
1848
 
1682
1849
  Properties will be written the object using `write_property`
1683
1850
  """
1684
- pass
1851
+ raise NotImplementedError("Subclasses must implement write_object method")
1685
1852
 
1686
1853
  @abstractmethod
1687
1854
  @contextmanager
1688
- def write_property(self, iri, compact=None):
1855
+ def write_property(self, iri: str, compact: Optional[str] = None):
1689
1856
  """
1690
1857
  Write object property
1691
1858
 
@@ -1696,7 +1863,7 @@ class Encoder(ABC):
1696
1863
  the serialization supports compacted IRIs, it should be preferred to
1697
1864
  the full IRI.
1698
1865
  """
1699
- pass
1866
+ raise NotImplementedError("Subclasses must implement write_property method")
1700
1867
 
1701
1868
  @abstractmethod
1702
1869
  @contextmanager
@@ -1709,7 +1876,7 @@ class Encoder(ABC):
1709
1876
 
1710
1877
  Each item of the list will be added using `write_list_item`
1711
1878
  """
1712
- pass
1879
+ raise NotImplementedError("Subclasses must implement write_list method")
1713
1880
 
1714
1881
  @abstractmethod
1715
1882
  @contextmanager
@@ -1720,7 +1887,7 @@ class Encoder(ABC):
1720
1887
  A context manager that yields an `Encoder` that can be used to encode
1721
1888
  the value for a list item
1722
1889
  """
1723
- pass
1890
+ raise NotImplementedError("Subclasses must implement write_list_item method")
1724
1891
 
1725
1892
 
1726
1893
  class JSONLDEncoder(Encoder):
@@ -1749,14 +1916,14 @@ class JSONLDEncoder(Encoder):
1749
1916
  self.data = str(v)
1750
1917
 
1751
1918
  @contextmanager
1752
- def write_property(self, iri, compact=None):
1919
+ def write_property(self, iri: str, compact: Optional[str] = None):
1753
1920
  s = self.__class__(None)
1754
1921
  yield s
1755
1922
  if s.data is not None:
1756
- self.data[compact or iri] = s.data
1923
+ self.data[compact or iri] = s.data # type: ignore # within write_object() context, self.data is always dict or None
1757
1924
 
1758
1925
  @contextmanager
1759
- def write_object(self, o, _id, needs_id):
1926
+ def write_object(self, o: SHACLObject, _id: str, needs_id: bool):
1760
1927
  self.data = {
1761
1928
  "type": o.COMPACT_TYPE or o.TYPE,
1762
1929
  }
@@ -1776,7 +1943,7 @@ class JSONLDEncoder(Encoder):
1776
1943
  s = self.__class__(None)
1777
1944
  yield s
1778
1945
  if s.data is not None:
1779
- self.data.append(s.data)
1946
+ self.data.append(s.data) # type: ignore # within write_list() context, self.data is always list or None
1780
1947
 
1781
1948
 
1782
1949
  class JSONLDSerializer(object):
@@ -1786,11 +1953,11 @@ class JSONLDSerializer(object):
1786
1953
  def serialize_data(
1787
1954
  self,
1788
1955
  objectset: SHACLObjectSet,
1789
- force_at_graph=False,
1956
+ force_at_graph: bool = False,
1790
1957
  ):
1791
1958
  h = JSONLDEncoder()
1792
1959
  objectset.encode(h, force_at_graph)
1793
- data = {}
1960
+ data: Dict[str, Any] = {}
1794
1961
  if len(CONTEXT_URLS) == 1:
1795
1962
  data["@context"] = CONTEXT_URLS[0]
1796
1963
  elif CONTEXT_URLS:
@@ -1798,9 +1965,11 @@ class JSONLDSerializer(object):
1798
1965
 
1799
1966
  if isinstance(h.data, list):
1800
1967
  data["@graph"] = h.data
1801
- else:
1968
+ elif isinstance(h.data, dict):
1802
1969
  for k, v in h.data.items():
1803
1970
  data[k] = v
1971
+ # elif h.data is not None: # str, int, float, bool
1972
+ # data["value"] = h.data
1804
1973
 
1805
1974
  return data
1806
1975
 
@@ -1808,13 +1977,16 @@ class JSONLDSerializer(object):
1808
1977
  self,
1809
1978
  objectset: SHACLObjectSet,
1810
1979
  f,
1811
- force_at_graph=False,
1980
+ force_at_graph: bool = False,
1812
1981
  **kwargs,
1813
1982
  ):
1814
1983
  """
1815
1984
  Write a SHACLObjectSet to a JSON LD file
1816
1985
 
1817
1986
  If force_at_graph is True, a @graph node will always be written
1987
+
1988
+ Note that f should be a file-like object that supports the `write`
1989
+ method, and that opens in binary mode (e.g. `open("file.json", "wb")`).
1818
1990
  """
1819
1991
  data = self.serialize_data(objectset, force_at_graph)
1820
1992
 
@@ -1822,9 +1994,9 @@ class JSONLDSerializer(object):
1822
1994
 
1823
1995
  sha1 = hashlib.sha1()
1824
1996
  for chunk in json.JSONEncoder(**args).iterencode(data):
1825
- chunk = chunk.encode("utf-8")
1826
- f.write(chunk)
1827
- sha1.update(chunk)
1997
+ chunk_bytes = chunk.encode("utf-8")
1998
+ f.write(chunk_bytes)
1999
+ sha1.update(chunk_bytes)
1828
2000
 
1829
2001
  return sha1.hexdigest()
1830
2002
 
@@ -1870,7 +2042,7 @@ class JSONLDInlineEncoder(Encoder):
1870
2042
  self.write(json.dumps(str(v)))
1871
2043
 
1872
2044
  @contextmanager
1873
- def write_property(self, iri, compact=None):
2045
+ def write_property(self, iri: str, compact: Optional[str] = None):
1874
2046
  self._write_comma()
1875
2047
  self.write_string(compact or iri)
1876
2048
  self.write(":")
@@ -1878,7 +2050,7 @@ class JSONLDInlineEncoder(Encoder):
1878
2050
  self.comma = True
1879
2051
 
1880
2052
  @contextmanager
1881
- def write_object(self, o, _id, needs_id):
2053
+ def write_object(self, o: SHACLObject, _id: str, needs_id: bool):
1882
2054
  self._write_comma()
1883
2055
 
1884
2056
  self.write("{")
@@ -1920,7 +2092,7 @@ class JSONLDInlineSerializer(object):
1920
2092
  self,
1921
2093
  objectset: SHACLObjectSet,
1922
2094
  f,
1923
- force_at_graph=False,
2095
+ force_at_graph: bool = False,
1924
2096
  ):
1925
2097
  """
1926
2098
  Write a SHACLObjectSet to a JSON LD file
@@ -1946,13 +2118,256 @@ class JSONLDInlineSerializer(object):
1946
2118
  return sha1.hexdigest()
1947
2119
 
1948
2120
 
1949
- def print_tree(objects, all_fields=False):
2121
+ try:
2122
+ import rdflib
2123
+ import rdflib.term
2124
+ from rdflib.namespace import RDF
2125
+
2126
+ class RDFDecoder(Decoder):
2127
+ def __init__(
2128
+ self,
2129
+ graph: rdflib.Graph,
2130
+ subject: Optional[rdflib.term.Node] = None,
2131
+ predicate: Optional[rdflib.term.Node] = None,
2132
+ value: Optional[rdflib.term.Node] = None,
2133
+ ):
2134
+ self.graph = graph
2135
+ self.subject = subject
2136
+ self.predicate = predicate
2137
+ self.value = value
2138
+
2139
+ def __read_node(self):
2140
+ if self.value is not None:
2141
+ return self.value
2142
+ if self.predicate is None:
2143
+ return None
2144
+ return self.graph.value(self.subject, self.predicate)
2145
+
2146
+ def read_value(self) -> Optional[Any]:
2147
+ v = self.__read_node()
2148
+ if isinstance(v, rdflib.term.Literal):
2149
+ return v.toPython()
2150
+ return None
2151
+
2152
+ def read_string(self) -> Optional[str]:
2153
+ v = self.read_value()
2154
+ if isinstance(v, str):
2155
+ return v
2156
+ return None
2157
+
2158
+ def read_datetime(self) -> Optional[str]:
2159
+ return self.read_value()
2160
+
2161
+ def read_integer(self) -> Optional[int]:
2162
+ v = self.read_value()
2163
+ if isinstance(v, (int, decimal.Decimal)):
2164
+ return int(v)
2165
+ return None
2166
+
2167
+ def read_bool(self) -> Optional[bool]:
2168
+ v = self.read_value()
2169
+ if isinstance(v, bool):
2170
+ return v
2171
+ return None
2172
+
2173
+ def read_float(self) -> Optional[float]:
2174
+ v = self.read_value()
2175
+ if isinstance(v, (int, float, str, decimal.Decimal)):
2176
+ return float(v)
2177
+ return None
2178
+
2179
+ def read_iri(self) -> Optional[str]:
2180
+ v = self.__read_node()
2181
+ if isinstance(v, rdflib.term.URIRef):
2182
+ return v.toPython()
2183
+ elif isinstance(v, rdflib.term.Literal):
2184
+ v = v.toPython()
2185
+ if isinstance(v, str):
2186
+ return v
2187
+ elif isinstance(v, rdflib.term.BNode):
2188
+ return v.n3()
2189
+ return None
2190
+
2191
+ def read_enum(self, e) -> Optional[str]:
2192
+ v = self.__read_node()
2193
+ if isinstance(v, rdflib.term.URIRef):
2194
+ return v.toPython()
2195
+ return None
2196
+
2197
+ def read_list(self) -> Iterator["RDFDecoder"]:
2198
+ if not self.subject:
2199
+ blank_nodes = set()
2200
+ for s in self.graph.subjects(unique=True):
2201
+ # type: ignore # RDF.type is dynamic
2202
+ if (s, RDF.type, None) not in self.graph:
2203
+ continue
2204
+
2205
+ if isinstance(s, rdflib.term.BNode):
2206
+ blank_nodes.add(s)
2207
+ continue
2208
+ yield self.__class__(self.graph, s)
2209
+
2210
+ for s in blank_nodes:
2211
+ yield self.__class__(self.graph, s)
2212
+ else:
2213
+ for o in self.graph.objects(self.subject, self.predicate):
2214
+ # type: ignore # RDF.type is dynamic
2215
+ if (o, RDF.type, None) in self.graph:
2216
+ yield self.__class__(self.graph, o)
2217
+ else:
2218
+ yield self.__class__(
2219
+ self.graph,
2220
+ self.subject,
2221
+ self.predicate,
2222
+ o,
2223
+ )
2224
+
2225
+ def is_list(self) -> bool:
2226
+ if not self.subject:
2227
+ return True
2228
+ if self.value is not None:
2229
+ return False
2230
+ return len(list(self.graph.objects(self.subject, self.predicate))) > 1
2231
+
2232
+ @contextmanager
2233
+ def read_property(self, key) -> Iterator[Optional["RDFDecoder"]]:
2234
+ if key == "@id":
2235
+ yield self.__class__(self.graph, value=self.subject)
2236
+ else:
2237
+ yield self.__class__(self.graph, self.subject, rdflib.term.URIRef(key))
2238
+
2239
+ def is_object(self) -> bool:
2240
+ n = self.__read_node() or self.subject
2241
+ # type: ignore # RDF.type is dynamic
2242
+ return (n, RDF.type, None) in self.graph
2243
+
2244
+ def object_keys(self) -> Iterator[str]:
2245
+ for p in self.graph.predicates(self.subject, unique=True):
2246
+ # type: ignore # RDF.type is dynamic
2247
+ if p == RDF.type:
2248
+ continue
2249
+
2250
+ if not isinstance(p, rdflib.term.IdentifiedNode):
2251
+ raise TypeError(f"Predicate is of unknown type {type(p)}")
2252
+
2253
+ yield p.toPython()
2254
+
2255
+ def read_object(self) -> Tuple[Any, "RDFDecoder"]:
2256
+ s = self.__read_node()
2257
+ if s is None:
2258
+ s = self.subject
2259
+
2260
+ # type: ignore # RDF.type is dynamic
2261
+ typ = self.graph.value(s, RDF.type)
2262
+ if typ is None:
2263
+ return None, self
2264
+
2265
+ if not isinstance(typ, rdflib.term.IdentifiedNode):
2266
+ raise TypeError(f"Type value is of unknown type {type(typ)}")
2267
+
2268
+ return typ.toPython(), self.__class__(self.graph, s)
2269
+
2270
+ def read_object_id(self, alias=None) -> Optional[Any]:
2271
+ if isinstance(self.subject, rdflib.term.BNode):
2272
+ return self.subject.n3()
2273
+ if not isinstance(self.subject, rdflib.term.IdentifiedNode):
2274
+ raise TypeError(f"Subject is of unknown type {type(self.subject)}")
2275
+ return self.subject.toPython()
2276
+
2277
+ class RDFDeserializer(object):
2278
+ def read(self, graph: rdflib.Graph, objset: SHACLObjectSet) -> None:
2279
+ d = RDFDecoder(graph)
2280
+ objset.decode(d)
2281
+ objset.inline_blank_nodes()
2282
+
2283
+ class RDFEncoder(Encoder):
2284
+ def __init__(
2285
+ self,
2286
+ graph: rdflib.Graph,
2287
+ subject: Optional[rdflib.term.Node] = None,
2288
+ predicate: Optional[rdflib.term.Node] = None,
2289
+ ):
2290
+ self.graph = graph
2291
+ self.subject = subject
2292
+ self.predicate = predicate
2293
+
2294
+ def __add_literal(self, v):
2295
+ if self.subject is None or self.predicate is None:
2296
+ raise TypeError()
2297
+ self.graph.add((self.subject, self.predicate, rdflib.Literal(v)))
2298
+
2299
+ def __add_uriref(self, v):
2300
+ if self.subject is None or self.predicate is None:
2301
+ raise TypeError()
2302
+ self.graph.add((self.subject, self.predicate, rdflib.URIRef(v)))
2303
+
2304
+ def write_string(self, v):
2305
+ self.__add_literal(v)
2306
+
2307
+ def write_datetime(self, v):
2308
+ self.__add_literal(v)
2309
+
2310
+ def write_integer(self, v):
2311
+ self.__add_literal(v)
2312
+
2313
+ def write_iri(self, v, compact=None):
2314
+ self.__add_uriref(v)
2315
+
2316
+ def write_enum(self, v, e, compact=None):
2317
+ self.__add_uriref(v)
2318
+
2319
+ def write_bool(self, v):
2320
+ self.__add_literal(v)
2321
+
2322
+ def write_float(self, v):
2323
+ self.__add_literal(v)
2324
+
2325
+ @contextmanager
2326
+ def write_property(self, iri: str, compact: Optional[str] = None):
2327
+ yield self.__class__(self.graph, self.subject, rdflib.URIRef(iri))
2328
+
2329
+ @contextmanager
2330
+ def write_object(self, o, _id, needs_id: bool):
2331
+ obj: rdflib.term.Node
2332
+ if _id.startswith("_:"):
2333
+ obj = rdflib.BNode(_id[2:])
2334
+ else:
2335
+ obj = rdflib.URIRef(_id)
2336
+
2337
+ if self.subject is not None:
2338
+ if self.predicate is None:
2339
+ raise TypeError()
2340
+ self.graph.add((self.subject, self.predicate, obj))
2341
+ self.graph.add((obj, RDF.type, rdflib.URIRef(o.TYPE))) # type: ignore # RDF.type is dynamic
2342
+ yield self.__class__(self.graph, obj)
2343
+
2344
+ @contextmanager
2345
+ def write_list(self):
2346
+ yield self
2347
+
2348
+ @contextmanager
2349
+ def write_list_item(self):
2350
+ yield self
2351
+
2352
+ class RDFSerializer(object):
2353
+ def write(self, objset: SHACLObjectSet, g: rdflib.Graph):
2354
+ """
2355
+ Write a SHACLObjectSet to an RDF graph
2356
+ """
2357
+ e = RDFEncoder(g)
2358
+ objset.encode(e)
2359
+
2360
+ except ImportError:
2361
+ pass
2362
+
2363
+
2364
+ def print_tree(objects, all_fields: bool = False) -> None:
1950
2365
  """
1951
2366
  Print object tree
1952
2367
  """
1953
2368
  seen = set()
1954
2369
 
1955
- def callback(value, path):
2370
+ def callback(value, path: List[str]):
1956
2371
  nonlocal seen
1957
2372
 
1958
2373
  s = (" " * (len(path) - 1)) + f"{path[-1]}"
@@ -1986,7 +2401,7 @@ def print_tree(objects, all_fields=False):
1986
2401
  """Format Guard"""
1987
2402
 
1988
2403
 
1989
- CONTEXT_URLS = [
2404
+ CONTEXT_URLS: List[str] = [
1990
2405
  "https://spdx.org/rdf/3.0.1/spdx-context.jsonld",
1991
2406
  ]
1992
2407
 
@@ -1998,7 +2413,7 @@ CONTEXT_URLS = [
1998
2413
  class ai_EnergyConsumption(SHACLObject):
1999
2414
  NODE_KIND = NodeKind.BlankNodeOrIRI
2000
2415
  IS_DEPRECATED = False
2001
- NAMED_INDIVIDUALS = {
2416
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2002
2417
  }
2003
2418
 
2004
2419
  @classmethod
@@ -2039,7 +2454,7 @@ class ai_EnergyConsumption(SHACLObject):
2039
2454
  class ai_EnergyConsumptionDescription(SHACLObject):
2040
2455
  NODE_KIND = NodeKind.BlankNodeOrIRI
2041
2456
  IS_DEPRECATED = False
2042
- NAMED_INDIVIDUALS = {
2457
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2043
2458
  }
2044
2459
 
2045
2460
  @classmethod
@@ -2074,7 +2489,7 @@ class ai_EnergyConsumptionDescription(SHACLObject):
2074
2489
  class ai_EnergyUnitType(SHACLObject):
2075
2490
  NODE_KIND = NodeKind.BlankNodeOrIRI
2076
2491
  IS_DEPRECATED = False
2077
- NAMED_INDIVIDUALS = {
2492
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2078
2493
  "kilowattHour": "https://spdx.org/rdf/3.0.1/terms/AI/EnergyUnitType/kilowattHour",
2079
2494
  "megajoule": "https://spdx.org/rdf/3.0.1/terms/AI/EnergyUnitType/megajoule",
2080
2495
  "other": "https://spdx.org/rdf/3.0.1/terms/AI/EnergyUnitType/other",
@@ -2092,7 +2507,7 @@ class ai_EnergyUnitType(SHACLObject):
2092
2507
  class ai_SafetyRiskAssessmentType(SHACLObject):
2093
2508
  NODE_KIND = NodeKind.BlankNodeOrIRI
2094
2509
  IS_DEPRECATED = False
2095
- NAMED_INDIVIDUALS = {
2510
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2096
2511
  "high": "https://spdx.org/rdf/3.0.1/terms/AI/SafetyRiskAssessmentType/high",
2097
2512
  "low": "https://spdx.org/rdf/3.0.1/terms/AI/SafetyRiskAssessmentType/low",
2098
2513
  "medium": "https://spdx.org/rdf/3.0.1/terms/AI/SafetyRiskAssessmentType/medium",
@@ -2113,7 +2528,7 @@ class ai_SafetyRiskAssessmentType(SHACLObject):
2113
2528
  class AnnotationType(SHACLObject):
2114
2529
  NODE_KIND = NodeKind.BlankNodeOrIRI
2115
2530
  IS_DEPRECATED = False
2116
- NAMED_INDIVIDUALS = {
2531
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2117
2532
  "other": "https://spdx.org/rdf/3.0.1/terms/Core/AnnotationType/other",
2118
2533
  "review": "https://spdx.org/rdf/3.0.1/terms/Core/AnnotationType/review",
2119
2534
  }
@@ -2128,7 +2543,7 @@ class AnnotationType(SHACLObject):
2128
2543
  class CreationInfo(SHACLObject):
2129
2544
  NODE_KIND = NodeKind.BlankNodeOrIRI
2130
2545
  IS_DEPRECATED = False
2131
- NAMED_INDIVIDUALS = {
2546
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2132
2547
  }
2133
2548
 
2134
2549
  @classmethod
@@ -2188,7 +2603,7 @@ class CreationInfo(SHACLObject):
2188
2603
  class DictionaryEntry(SHACLObject):
2189
2604
  NODE_KIND = NodeKind.BlankNodeOrIRI
2190
2605
  IS_DEPRECATED = False
2191
- NAMED_INDIVIDUALS = {
2606
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2192
2607
  }
2193
2608
 
2194
2609
  @classmethod
@@ -2219,7 +2634,7 @@ class Element(SHACLObject):
2219
2634
  NODE_KIND = NodeKind.IRI
2220
2635
  ID_ALIAS = "spdxId"
2221
2636
  IS_DEPRECATED = False
2222
- NAMED_INDIVIDUALS = {
2637
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2223
2638
  }
2224
2639
 
2225
2640
  @classmethod
@@ -2310,7 +2725,7 @@ class ElementCollection(Element):
2310
2725
  NODE_KIND = NodeKind.IRI
2311
2726
  ID_ALIAS = "spdxId"
2312
2727
  IS_DEPRECATED = False
2313
- NAMED_INDIVIDUALS = {
2728
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2314
2729
  }
2315
2730
 
2316
2731
  @classmethod
@@ -2371,7 +2786,7 @@ class ElementCollection(Element):
2371
2786
  class ExternalIdentifier(SHACLObject):
2372
2787
  NODE_KIND = NodeKind.BlankNodeOrIRI
2373
2788
  IS_DEPRECATED = False
2374
- NAMED_INDIVIDUALS = {
2789
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2375
2790
  }
2376
2791
 
2377
2792
  @classmethod
@@ -2439,7 +2854,7 @@ class ExternalIdentifier(SHACLObject):
2439
2854
  class ExternalIdentifierType(SHACLObject):
2440
2855
  NODE_KIND = NodeKind.BlankNodeOrIRI
2441
2856
  IS_DEPRECATED = False
2442
- NAMED_INDIVIDUALS = {
2857
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2443
2858
  "cpe22": "https://spdx.org/rdf/3.0.1/terms/Core/ExternalIdentifierType/cpe22",
2444
2859
  "cpe23": "https://spdx.org/rdf/3.0.1/terms/Core/ExternalIdentifierType/cpe23",
2445
2860
  "cve": "https://spdx.org/rdf/3.0.1/terms/Core/ExternalIdentifierType/cve",
@@ -2482,7 +2897,7 @@ class ExternalIdentifierType(SHACLObject):
2482
2897
  class ExternalMap(SHACLObject):
2483
2898
  NODE_KIND = NodeKind.BlankNodeOrIRI
2484
2899
  IS_DEPRECATED = False
2485
- NAMED_INDIVIDUALS = {
2900
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2486
2901
  }
2487
2902
 
2488
2903
  @classmethod
@@ -2531,7 +2946,7 @@ class ExternalMap(SHACLObject):
2531
2946
  class ExternalRef(SHACLObject):
2532
2947
  NODE_KIND = NodeKind.BlankNodeOrIRI
2533
2948
  IS_DEPRECATED = False
2534
- NAMED_INDIVIDUALS = {
2949
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2535
2950
  }
2536
2951
 
2537
2952
  @classmethod
@@ -2624,7 +3039,7 @@ class ExternalRef(SHACLObject):
2624
3039
  class ExternalRefType(SHACLObject):
2625
3040
  NODE_KIND = NodeKind.BlankNodeOrIRI
2626
3041
  IS_DEPRECATED = False
2627
- NAMED_INDIVIDUALS = {
3042
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2628
3043
  "altDownloadLocation": "https://spdx.org/rdf/3.0.1/terms/Core/ExternalRefType/altDownloadLocation",
2629
3044
  "altWebPage": "https://spdx.org/rdf/3.0.1/terms/Core/ExternalRefType/altWebPage",
2630
3045
  "binaryArtifact": "https://spdx.org/rdf/3.0.1/terms/Core/ExternalRefType/binaryArtifact",
@@ -2771,7 +3186,7 @@ class ExternalRefType(SHACLObject):
2771
3186
  class HashAlgorithm(SHACLObject):
2772
3187
  NODE_KIND = NodeKind.BlankNodeOrIRI
2773
3188
  IS_DEPRECATED = False
2774
- NAMED_INDIVIDUALS = {
3189
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2775
3190
  "adler32": "https://spdx.org/rdf/3.0.1/terms/Core/HashAlgorithm/adler32",
2776
3191
  "blake2b256": "https://spdx.org/rdf/3.0.1/terms/Core/HashAlgorithm/blake2b256",
2777
3192
  "blake2b384": "https://spdx.org/rdf/3.0.1/terms/Core/HashAlgorithm/blake2b384",
@@ -2848,7 +3263,7 @@ class IndividualElement(Element):
2848
3263
  NODE_KIND = NodeKind.IRI
2849
3264
  ID_ALIAS = "spdxId"
2850
3265
  IS_DEPRECATED = False
2851
- NAMED_INDIVIDUALS = {
3266
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2852
3267
  "NoAssertionElement": "https://spdx.org/rdf/3.0.1/terms/Core/NoAssertionElement",
2853
3268
  "NoneElement": "https://spdx.org/rdf/3.0.1/terms/Core/NoneElement",
2854
3269
  }
@@ -2865,7 +3280,7 @@ class IndividualElement(Element):
2865
3280
  class IntegrityMethod(SHACLObject):
2866
3281
  NODE_KIND = NodeKind.BlankNodeOrIRI
2867
3282
  IS_DEPRECATED = False
2868
- NAMED_INDIVIDUALS = {
3283
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2869
3284
  }
2870
3285
 
2871
3286
  @classmethod
@@ -2887,7 +3302,7 @@ class IntegrityMethod(SHACLObject):
2887
3302
  class LifecycleScopeType(SHACLObject):
2888
3303
  NODE_KIND = NodeKind.BlankNodeOrIRI
2889
3304
  IS_DEPRECATED = False
2890
- NAMED_INDIVIDUALS = {
3305
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2891
3306
  "build": "https://spdx.org/rdf/3.0.1/terms/Core/LifecycleScopeType/build",
2892
3307
  "design": "https://spdx.org/rdf/3.0.1/terms/Core/LifecycleScopeType/design",
2893
3308
  "development": "https://spdx.org/rdf/3.0.1/terms/Core/LifecycleScopeType/development",
@@ -2914,7 +3329,7 @@ class LifecycleScopeType(SHACLObject):
2914
3329
  class NamespaceMap(SHACLObject):
2915
3330
  NODE_KIND = NodeKind.BlankNodeOrIRI
2916
3331
  IS_DEPRECATED = False
2917
- NAMED_INDIVIDUALS = {
3332
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2918
3333
  }
2919
3334
 
2920
3335
  @classmethod
@@ -2946,7 +3361,7 @@ class NamespaceMap(SHACLObject):
2946
3361
  class PackageVerificationCode(IntegrityMethod):
2947
3362
  NODE_KIND = NodeKind.BlankNodeOrIRI
2948
3363
  IS_DEPRECATED = False
2949
- NAMED_INDIVIDUALS = {
3364
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2950
3365
  }
2951
3366
 
2952
3367
  @classmethod
@@ -3009,7 +3424,7 @@ class PackageVerificationCode(IntegrityMethod):
3009
3424
  class PositiveIntegerRange(SHACLObject):
3010
3425
  NODE_KIND = NodeKind.BlankNodeOrIRI
3011
3426
  IS_DEPRECATED = False
3012
- NAMED_INDIVIDUALS = {
3427
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3013
3428
  }
3014
3429
 
3015
3430
  @classmethod
@@ -3040,7 +3455,7 @@ class PositiveIntegerRange(SHACLObject):
3040
3455
  class PresenceType(SHACLObject):
3041
3456
  NODE_KIND = NodeKind.BlankNodeOrIRI
3042
3457
  IS_DEPRECATED = False
3043
- NAMED_INDIVIDUALS = {
3458
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3044
3459
  "no": "https://spdx.org/rdf/3.0.1/terms/Core/PresenceType/no",
3045
3460
  "noAssertion": "https://spdx.org/rdf/3.0.1/terms/Core/PresenceType/noAssertion",
3046
3461
  "yes": "https://spdx.org/rdf/3.0.1/terms/Core/PresenceType/yes",
@@ -3058,7 +3473,7 @@ class PresenceType(SHACLObject):
3058
3473
  class ProfileIdentifierType(SHACLObject):
3059
3474
  NODE_KIND = NodeKind.BlankNodeOrIRI
3060
3475
  IS_DEPRECATED = False
3061
- NAMED_INDIVIDUALS = {
3476
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3062
3477
  "ai": "https://spdx.org/rdf/3.0.1/terms/Core/ProfileIdentifierType/ai",
3063
3478
  "build": "https://spdx.org/rdf/3.0.1/terms/Core/ProfileIdentifierType/build",
3064
3479
  "core": "https://spdx.org/rdf/3.0.1/terms/Core/ProfileIdentifierType/core",
@@ -3098,7 +3513,7 @@ class Relationship(Element):
3098
3513
  NODE_KIND = NodeKind.IRI
3099
3514
  ID_ALIAS = "spdxId"
3100
3515
  IS_DEPRECATED = False
3101
- NAMED_INDIVIDUALS = {
3516
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3102
3517
  }
3103
3518
 
3104
3519
  @classmethod
@@ -3238,7 +3653,7 @@ class Relationship(Element):
3238
3653
  class RelationshipCompleteness(SHACLObject):
3239
3654
  NODE_KIND = NodeKind.BlankNodeOrIRI
3240
3655
  IS_DEPRECATED = False
3241
- NAMED_INDIVIDUALS = {
3656
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3242
3657
  "complete": "https://spdx.org/rdf/3.0.1/terms/Core/RelationshipCompleteness/complete",
3243
3658
  "incomplete": "https://spdx.org/rdf/3.0.1/terms/Core/RelationshipCompleteness/incomplete",
3244
3659
  "noAssertion": "https://spdx.org/rdf/3.0.1/terms/Core/RelationshipCompleteness/noAssertion",
@@ -3256,7 +3671,7 @@ class RelationshipCompleteness(SHACLObject):
3256
3671
  class RelationshipType(SHACLObject):
3257
3672
  NODE_KIND = NodeKind.BlankNodeOrIRI
3258
3673
  IS_DEPRECATED = False
3259
- NAMED_INDIVIDUALS = {
3674
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3260
3675
  "affects": "https://spdx.org/rdf/3.0.1/terms/Core/RelationshipType/affects",
3261
3676
  "amendedBy": "https://spdx.org/rdf/3.0.1/terms/Core/RelationshipType/amendedBy",
3262
3677
  "ancestorOf": "https://spdx.org/rdf/3.0.1/terms/Core/RelationshipType/ancestorOf",
@@ -3443,7 +3858,7 @@ class SpdxDocument(ElementCollection):
3443
3858
  NODE_KIND = NodeKind.IRI
3444
3859
  ID_ALIAS = "spdxId"
3445
3860
  IS_DEPRECATED = False
3446
- NAMED_INDIVIDUALS = {
3861
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3447
3862
  }
3448
3863
 
3449
3864
  @classmethod
@@ -3484,7 +3899,7 @@ class SpdxDocument(ElementCollection):
3484
3899
  class SupportType(SHACLObject):
3485
3900
  NODE_KIND = NodeKind.BlankNodeOrIRI
3486
3901
  IS_DEPRECATED = False
3487
- NAMED_INDIVIDUALS = {
3902
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3488
3903
  "deployed": "https://spdx.org/rdf/3.0.1/terms/Core/SupportType/deployed",
3489
3904
  "development": "https://spdx.org/rdf/3.0.1/terms/Core/SupportType/development",
3490
3905
  "endOfSupport": "https://spdx.org/rdf/3.0.1/terms/Core/SupportType/endOfSupport",
@@ -3515,7 +3930,7 @@ class Tool(Element):
3515
3930
  NODE_KIND = NodeKind.IRI
3516
3931
  ID_ALIAS = "spdxId"
3517
3932
  IS_DEPRECATED = False
3518
- NAMED_INDIVIDUALS = {
3933
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3519
3934
  }
3520
3935
 
3521
3936
 
@@ -3524,7 +3939,7 @@ class Tool(Element):
3524
3939
  class dataset_ConfidentialityLevelType(SHACLObject):
3525
3940
  NODE_KIND = NodeKind.BlankNodeOrIRI
3526
3941
  IS_DEPRECATED = False
3527
- NAMED_INDIVIDUALS = {
3942
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3528
3943
  "amber": "https://spdx.org/rdf/3.0.1/terms/Dataset/ConfidentialityLevelType/amber",
3529
3944
  "clear": "https://spdx.org/rdf/3.0.1/terms/Dataset/ConfidentialityLevelType/clear",
3530
3945
  "green": "https://spdx.org/rdf/3.0.1/terms/Dataset/ConfidentialityLevelType/green",
@@ -3545,7 +3960,7 @@ class dataset_ConfidentialityLevelType(SHACLObject):
3545
3960
  class dataset_DatasetAvailabilityType(SHACLObject):
3546
3961
  NODE_KIND = NodeKind.BlankNodeOrIRI
3547
3962
  IS_DEPRECATED = False
3548
- NAMED_INDIVIDUALS = {
3963
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3549
3964
  "clickthrough": "https://spdx.org/rdf/3.0.1/terms/Dataset/DatasetAvailabilityType/clickthrough",
3550
3965
  "directDownload": "https://spdx.org/rdf/3.0.1/terms/Dataset/DatasetAvailabilityType/directDownload",
3551
3966
  "query": "https://spdx.org/rdf/3.0.1/terms/Dataset/DatasetAvailabilityType/query",
@@ -3569,7 +3984,7 @@ class dataset_DatasetAvailabilityType(SHACLObject):
3569
3984
  class dataset_DatasetType(SHACLObject):
3570
3985
  NODE_KIND = NodeKind.BlankNodeOrIRI
3571
3986
  IS_DEPRECATED = False
3572
- NAMED_INDIVIDUALS = {
3987
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3573
3988
  "audio": "https://spdx.org/rdf/3.0.1/terms/Dataset/DatasetType/audio",
3574
3989
  "categorical": "https://spdx.org/rdf/3.0.1/terms/Dataset/DatasetType/categorical",
3575
3990
  "graph": "https://spdx.org/rdf/3.0.1/terms/Dataset/DatasetType/graph",
@@ -3622,7 +4037,7 @@ class expandedlicensing_LicenseAddition(Element):
3622
4037
  NODE_KIND = NodeKind.IRI
3623
4038
  ID_ALIAS = "spdxId"
3624
4039
  IS_DEPRECATED = False
3625
- NAMED_INDIVIDUALS = {
4040
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3626
4041
  }
3627
4042
 
3628
4043
  @classmethod
@@ -3687,7 +4102,7 @@ class expandedlicensing_ListedLicenseException(expandedlicensing_LicenseAddition
3687
4102
  NODE_KIND = NodeKind.IRI
3688
4103
  ID_ALIAS = "spdxId"
3689
4104
  IS_DEPRECATED = False
3690
- NAMED_INDIVIDUALS = {
4105
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3691
4106
  }
3692
4107
 
3693
4108
  @classmethod
@@ -3718,7 +4133,7 @@ class expandedlicensing_ListedLicenseException(expandedlicensing_LicenseAddition
3718
4133
  class extension_CdxPropertyEntry(SHACLObject):
3719
4134
  NODE_KIND = NodeKind.BlankNodeOrIRI
3720
4135
  IS_DEPRECATED = False
3721
- NAMED_INDIVIDUALS = {
4136
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3722
4137
  }
3723
4138
 
3724
4139
  @classmethod
@@ -3748,7 +4163,7 @@ class extension_CdxPropertyEntry(SHACLObject):
3748
4163
  class extension_Extension(SHACLExtensibleObject, SHACLObject):
3749
4164
  NODE_KIND = NodeKind.BlankNodeOrIRI
3750
4165
  IS_DEPRECATED = False
3751
- NAMED_INDIVIDUALS = {
4166
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3752
4167
  }
3753
4168
 
3754
4169
 
@@ -3757,7 +4172,7 @@ class extension_Extension(SHACLExtensibleObject, SHACLObject):
3757
4172
  class security_CvssSeverityType(SHACLObject):
3758
4173
  NODE_KIND = NodeKind.BlankNodeOrIRI
3759
4174
  IS_DEPRECATED = False
3760
- NAMED_INDIVIDUALS = {
4175
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3761
4176
  "critical": "https://spdx.org/rdf/3.0.1/terms/Security/CvssSeverityType/critical",
3762
4177
  "high": "https://spdx.org/rdf/3.0.1/terms/Security/CvssSeverityType/high",
3763
4178
  "low": "https://spdx.org/rdf/3.0.1/terms/Security/CvssSeverityType/low",
@@ -3781,7 +4196,7 @@ class security_CvssSeverityType(SHACLObject):
3781
4196
  class security_ExploitCatalogType(SHACLObject):
3782
4197
  NODE_KIND = NodeKind.BlankNodeOrIRI
3783
4198
  IS_DEPRECATED = False
3784
- NAMED_INDIVIDUALS = {
4199
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3785
4200
  "kev": "https://spdx.org/rdf/3.0.1/terms/Security/ExploitCatalogType/kev",
3786
4201
  "other": "https://spdx.org/rdf/3.0.1/terms/Security/ExploitCatalogType/other",
3787
4202
  }
@@ -3796,7 +4211,7 @@ class security_ExploitCatalogType(SHACLObject):
3796
4211
  class security_SsvcDecisionType(SHACLObject):
3797
4212
  NODE_KIND = NodeKind.BlankNodeOrIRI
3798
4213
  IS_DEPRECATED = False
3799
- NAMED_INDIVIDUALS = {
4214
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3800
4215
  "act": "https://spdx.org/rdf/3.0.1/terms/Security/SsvcDecisionType/act",
3801
4216
  "attend": "https://spdx.org/rdf/3.0.1/terms/Security/SsvcDecisionType/attend",
3802
4217
  "track": "https://spdx.org/rdf/3.0.1/terms/Security/SsvcDecisionType/track",
@@ -3817,7 +4232,7 @@ class security_SsvcDecisionType(SHACLObject):
3817
4232
  class security_VexJustificationType(SHACLObject):
3818
4233
  NODE_KIND = NodeKind.BlankNodeOrIRI
3819
4234
  IS_DEPRECATED = False
3820
- NAMED_INDIVIDUALS = {
4235
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3821
4236
  "componentNotPresent": "https://spdx.org/rdf/3.0.1/terms/Security/VexJustificationType/componentNotPresent",
3822
4237
  "inlineMitigationsAlreadyExist": "https://spdx.org/rdf/3.0.1/terms/Security/VexJustificationType/inlineMitigationsAlreadyExist",
3823
4238
  "vulnerableCodeCannotBeControlledByAdversary": "https://spdx.org/rdf/3.0.1/terms/Security/VexJustificationType/vulnerableCodeCannotBeControlledByAdversary",
@@ -3842,7 +4257,7 @@ class security_VulnAssessmentRelationship(Relationship):
3842
4257
  NODE_KIND = NodeKind.IRI
3843
4258
  ID_ALIAS = "spdxId"
3844
4259
  IS_DEPRECATED = False
3845
- NAMED_INDIVIDUALS = {
4260
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3846
4261
  }
3847
4262
 
3848
4263
  @classmethod
@@ -3900,7 +4315,7 @@ class simplelicensing_AnyLicenseInfo(Element):
3900
4315
  NODE_KIND = NodeKind.IRI
3901
4316
  ID_ALIAS = "spdxId"
3902
4317
  IS_DEPRECATED = False
3903
- NAMED_INDIVIDUALS = {
4318
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3904
4319
  }
3905
4320
 
3906
4321
 
@@ -3910,7 +4325,7 @@ class simplelicensing_LicenseExpression(simplelicensing_AnyLicenseInfo):
3910
4325
  NODE_KIND = NodeKind.IRI
3911
4326
  ID_ALIAS = "spdxId"
3912
4327
  IS_DEPRECATED = False
3913
- NAMED_INDIVIDUALS = {
4328
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3914
4329
  }
3915
4330
 
3916
4331
  @classmethod
@@ -3950,7 +4365,7 @@ class simplelicensing_SimpleLicensingText(Element):
3950
4365
  NODE_KIND = NodeKind.IRI
3951
4366
  ID_ALIAS = "spdxId"
3952
4367
  IS_DEPRECATED = False
3953
- NAMED_INDIVIDUALS = {
4368
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3954
4369
  }
3955
4370
 
3956
4371
  @classmethod
@@ -3972,7 +4387,7 @@ class simplelicensing_SimpleLicensingText(Element):
3972
4387
  class software_ContentIdentifier(IntegrityMethod):
3973
4388
  NODE_KIND = NodeKind.BlankNodeOrIRI
3974
4389
  IS_DEPRECATED = False
3975
- NAMED_INDIVIDUALS = {
4390
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3976
4391
  }
3977
4392
 
3978
4393
  @classmethod
@@ -4006,7 +4421,7 @@ class software_ContentIdentifier(IntegrityMethod):
4006
4421
  class software_ContentIdentifierType(SHACLObject):
4007
4422
  NODE_KIND = NodeKind.BlankNodeOrIRI
4008
4423
  IS_DEPRECATED = False
4009
- NAMED_INDIVIDUALS = {
4424
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4010
4425
  "gitoid": "https://spdx.org/rdf/3.0.1/terms/Software/ContentIdentifierType/gitoid",
4011
4426
  "swhid": "https://spdx.org/rdf/3.0.1/terms/Software/ContentIdentifierType/swhid",
4012
4427
  }
@@ -4021,7 +4436,7 @@ class software_ContentIdentifierType(SHACLObject):
4021
4436
  class software_FileKindType(SHACLObject):
4022
4437
  NODE_KIND = NodeKind.BlankNodeOrIRI
4023
4438
  IS_DEPRECATED = False
4024
- NAMED_INDIVIDUALS = {
4439
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4025
4440
  "directory": "https://spdx.org/rdf/3.0.1/terms/Software/FileKindType/directory",
4026
4441
  "file": "https://spdx.org/rdf/3.0.1/terms/Software/FileKindType/file",
4027
4442
  }
@@ -4037,7 +4452,7 @@ class software_FileKindType(SHACLObject):
4037
4452
  class software_SbomType(SHACLObject):
4038
4453
  NODE_KIND = NodeKind.BlankNodeOrIRI
4039
4454
  IS_DEPRECATED = False
4040
- NAMED_INDIVIDUALS = {
4455
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4041
4456
  "analyzed": "https://spdx.org/rdf/3.0.1/terms/Software/SbomType/analyzed",
4042
4457
  "build": "https://spdx.org/rdf/3.0.1/terms/Software/SbomType/build",
4043
4458
  "deployed": "https://spdx.org/rdf/3.0.1/terms/Software/SbomType/deployed",
@@ -4064,7 +4479,7 @@ class software_SbomType(SHACLObject):
4064
4479
  class software_SoftwarePurpose(SHACLObject):
4065
4480
  NODE_KIND = NodeKind.BlankNodeOrIRI
4066
4481
  IS_DEPRECATED = False
4067
- NAMED_INDIVIDUALS = {
4482
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4068
4483
  "application": "https://spdx.org/rdf/3.0.1/terms/Software/SoftwarePurpose/application",
4069
4484
  "archive": "https://spdx.org/rdf/3.0.1/terms/Software/SoftwarePurpose/archive",
4070
4485
  "bom": "https://spdx.org/rdf/3.0.1/terms/Software/SoftwarePurpose/bom",
@@ -4161,7 +4576,7 @@ class build_Build(Element):
4161
4576
  NODE_KIND = NodeKind.IRI
4162
4577
  ID_ALIAS = "spdxId"
4163
4578
  IS_DEPRECATED = False
4164
- NAMED_INDIVIDUALS = {
4579
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4165
4580
  }
4166
4581
 
4167
4582
  @classmethod
@@ -4251,7 +4666,7 @@ class Agent(Element):
4251
4666
  NODE_KIND = NodeKind.IRI
4252
4667
  ID_ALIAS = "spdxId"
4253
4668
  IS_DEPRECATED = False
4254
- NAMED_INDIVIDUALS = {
4669
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4255
4670
  }
4256
4671
 
4257
4672
 
@@ -4261,7 +4676,7 @@ class Annotation(Element):
4261
4676
  NODE_KIND = NodeKind.IRI
4262
4677
  ID_ALIAS = "spdxId"
4263
4678
  IS_DEPRECATED = False
4264
- NAMED_INDIVIDUALS = {
4679
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4265
4680
  }
4266
4681
 
4267
4682
  @classmethod
@@ -4318,7 +4733,7 @@ class Artifact(Element):
4318
4733
  NODE_KIND = NodeKind.IRI
4319
4734
  ID_ALIAS = "spdxId"
4320
4735
  IS_DEPRECATED = False
4321
- NAMED_INDIVIDUALS = {
4736
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4322
4737
  }
4323
4738
 
4324
4739
  @classmethod
@@ -4402,7 +4817,7 @@ class Bundle(ElementCollection):
4402
4817
  NODE_KIND = NodeKind.IRI
4403
4818
  ID_ALIAS = "spdxId"
4404
4819
  IS_DEPRECATED = False
4405
- NAMED_INDIVIDUALS = {
4820
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4406
4821
  }
4407
4822
 
4408
4823
  @classmethod
@@ -4424,7 +4839,7 @@ class Bundle(ElementCollection):
4424
4839
  class Hash(IntegrityMethod):
4425
4840
  NODE_KIND = NodeKind.BlankNodeOrIRI
4426
4841
  IS_DEPRECATED = False
4427
- NAMED_INDIVIDUALS = {
4842
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4428
4843
  }
4429
4844
 
4430
4845
  @classmethod
@@ -4479,7 +4894,7 @@ class LifecycleScopedRelationship(Relationship):
4479
4894
  NODE_KIND = NodeKind.IRI
4480
4895
  ID_ALIAS = "spdxId"
4481
4896
  IS_DEPRECATED = False
4482
- NAMED_INDIVIDUALS = {
4897
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4483
4898
  }
4484
4899
 
4485
4900
  @classmethod
@@ -4508,7 +4923,7 @@ class Organization(Agent):
4508
4923
  NODE_KIND = NodeKind.IRI
4509
4924
  ID_ALIAS = "spdxId"
4510
4925
  IS_DEPRECATED = False
4511
- NAMED_INDIVIDUALS = {
4926
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4512
4927
  "SpdxOrganization": "https://spdx.org/rdf/3.0.1/terms/Core/SpdxOrganization",
4513
4928
  }
4514
4929
  # An Organization representing the SPDX Project.
@@ -4521,7 +4936,7 @@ class Person(Agent):
4521
4936
  NODE_KIND = NodeKind.IRI
4522
4937
  ID_ALIAS = "spdxId"
4523
4938
  IS_DEPRECATED = False
4524
- NAMED_INDIVIDUALS = {
4939
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4525
4940
  }
4526
4941
 
4527
4942
 
@@ -4531,7 +4946,7 @@ class SoftwareAgent(Agent):
4531
4946
  NODE_KIND = NodeKind.IRI
4532
4947
  ID_ALIAS = "spdxId"
4533
4948
  IS_DEPRECATED = False
4534
- NAMED_INDIVIDUALS = {
4949
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4535
4950
  }
4536
4951
 
4537
4952
 
@@ -4542,7 +4957,7 @@ class expandedlicensing_ConjunctiveLicenseSet(simplelicensing_AnyLicenseInfo):
4542
4957
  NODE_KIND = NodeKind.IRI
4543
4958
  ID_ALIAS = "spdxId"
4544
4959
  IS_DEPRECATED = False
4545
- NAMED_INDIVIDUALS = {
4960
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4546
4961
  }
4547
4962
 
4548
4963
  @classmethod
@@ -4568,7 +4983,7 @@ class expandedlicensing_CustomLicenseAddition(expandedlicensing_LicenseAddition)
4568
4983
  NODE_KIND = NodeKind.IRI
4569
4984
  ID_ALIAS = "spdxId"
4570
4985
  IS_DEPRECATED = False
4571
- NAMED_INDIVIDUALS = {
4986
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4572
4987
  }
4573
4988
 
4574
4989
 
@@ -4579,7 +4994,7 @@ class expandedlicensing_DisjunctiveLicenseSet(simplelicensing_AnyLicenseInfo):
4579
4994
  NODE_KIND = NodeKind.IRI
4580
4995
  ID_ALIAS = "spdxId"
4581
4996
  IS_DEPRECATED = False
4582
- NAMED_INDIVIDUALS = {
4997
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4583
4998
  }
4584
4999
 
4585
5000
  @classmethod
@@ -4605,7 +5020,7 @@ class expandedlicensing_ExtendableLicense(simplelicensing_AnyLicenseInfo):
4605
5020
  NODE_KIND = NodeKind.IRI
4606
5021
  ID_ALIAS = "spdxId"
4607
5022
  IS_DEPRECATED = False
4608
- NAMED_INDIVIDUALS = {
5023
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4609
5024
  }
4610
5025
 
4611
5026
 
@@ -4616,7 +5031,7 @@ class expandedlicensing_IndividualLicensingInfo(simplelicensing_AnyLicenseInfo):
4616
5031
  NODE_KIND = NodeKind.IRI
4617
5032
  ID_ALIAS = "spdxId"
4618
5033
  IS_DEPRECATED = False
4619
- NAMED_INDIVIDUALS = {
5034
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4620
5035
  "NoAssertionLicense": "https://spdx.org/rdf/3.0.1/terms/ExpandedLicensing/NoAssertionLicense",
4621
5036
  "NoneLicense": "https://spdx.org/rdf/3.0.1/terms/ExpandedLicensing/NoneLicense",
4622
5037
  }
@@ -4634,7 +5049,7 @@ class expandedlicensing_License(expandedlicensing_ExtendableLicense):
4634
5049
  NODE_KIND = NodeKind.IRI
4635
5050
  ID_ALIAS = "spdxId"
4636
5051
  IS_DEPRECATED = False
4637
- NAMED_INDIVIDUALS = {
5052
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4638
5053
  }
4639
5054
 
4640
5055
  @classmethod
@@ -4727,7 +5142,7 @@ class expandedlicensing_ListedLicense(expandedlicensing_License):
4727
5142
  NODE_KIND = NodeKind.IRI
4728
5143
  ID_ALIAS = "spdxId"
4729
5144
  IS_DEPRECATED = False
4730
- NAMED_INDIVIDUALS = {
5145
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4731
5146
  }
4732
5147
 
4733
5148
  @classmethod
@@ -4760,7 +5175,7 @@ class expandedlicensing_OrLaterOperator(expandedlicensing_ExtendableLicense):
4760
5175
  NODE_KIND = NodeKind.IRI
4761
5176
  ID_ALIAS = "spdxId"
4762
5177
  IS_DEPRECATED = False
4763
- NAMED_INDIVIDUALS = {
5178
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4764
5179
  }
4765
5180
 
4766
5181
  @classmethod
@@ -4784,7 +5199,7 @@ class expandedlicensing_WithAdditionOperator(simplelicensing_AnyLicenseInfo):
4784
5199
  NODE_KIND = NodeKind.IRI
4785
5200
  ID_ALIAS = "spdxId"
4786
5201
  IS_DEPRECATED = False
4787
- NAMED_INDIVIDUALS = {
5202
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4788
5203
  }
4789
5204
 
4790
5205
  @classmethod
@@ -4815,7 +5230,7 @@ class expandedlicensing_WithAdditionOperator(simplelicensing_AnyLicenseInfo):
4815
5230
  class extension_CdxPropertiesExtension(extension_Extension):
4816
5231
  NODE_KIND = NodeKind.BlankNodeOrIRI
4817
5232
  IS_DEPRECATED = False
4818
- NAMED_INDIVIDUALS = {
5233
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4819
5234
  }
4820
5235
 
4821
5236
  @classmethod
@@ -4838,7 +5253,7 @@ class security_CvssV2VulnAssessmentRelationship(security_VulnAssessmentRelations
4838
5253
  NODE_KIND = NodeKind.IRI
4839
5254
  ID_ALIAS = "spdxId"
4840
5255
  IS_DEPRECATED = False
4841
- NAMED_INDIVIDUALS = {
5256
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4842
5257
  }
4843
5258
 
4844
5259
  @classmethod
@@ -4870,7 +5285,7 @@ class security_CvssV3VulnAssessmentRelationship(security_VulnAssessmentRelations
4870
5285
  NODE_KIND = NodeKind.IRI
4871
5286
  ID_ALIAS = "spdxId"
4872
5287
  IS_DEPRECATED = False
4873
- NAMED_INDIVIDUALS = {
5288
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4874
5289
  }
4875
5290
 
4876
5291
  @classmethod
@@ -4917,7 +5332,7 @@ class security_CvssV4VulnAssessmentRelationship(security_VulnAssessmentRelations
4917
5332
  NODE_KIND = NodeKind.IRI
4918
5333
  ID_ALIAS = "spdxId"
4919
5334
  IS_DEPRECATED = False
4920
- NAMED_INDIVIDUALS = {
5335
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4921
5336
  }
4922
5337
 
4923
5338
  @classmethod
@@ -4964,7 +5379,7 @@ class security_EpssVulnAssessmentRelationship(security_VulnAssessmentRelationshi
4964
5379
  NODE_KIND = NodeKind.IRI
4965
5380
  ID_ALIAS = "spdxId"
4966
5381
  IS_DEPRECATED = False
4967
- NAMED_INDIVIDUALS = {
5382
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4968
5383
  }
4969
5384
 
4970
5385
  @classmethod
@@ -4996,7 +5411,7 @@ class security_ExploitCatalogVulnAssessmentRelationship(security_VulnAssessmentR
4996
5411
  NODE_KIND = NodeKind.IRI
4997
5412
  ID_ALIAS = "spdxId"
4998
5413
  IS_DEPRECATED = False
4999
- NAMED_INDIVIDUALS = {
5414
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5000
5415
  }
5001
5416
 
5002
5417
  @classmethod
@@ -5040,7 +5455,7 @@ class security_SsvcVulnAssessmentRelationship(security_VulnAssessmentRelationshi
5040
5455
  NODE_KIND = NodeKind.IRI
5041
5456
  ID_ALIAS = "spdxId"
5042
5457
  IS_DEPRECATED = False
5043
- NAMED_INDIVIDUALS = {
5458
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5044
5459
  }
5045
5460
 
5046
5461
  @classmethod
@@ -5069,7 +5484,7 @@ class security_VexVulnAssessmentRelationship(security_VulnAssessmentRelationship
5069
5484
  NODE_KIND = NodeKind.IRI
5070
5485
  ID_ALIAS = "spdxId"
5071
5486
  IS_DEPRECATED = False
5072
- NAMED_INDIVIDUALS = {
5487
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5073
5488
  }
5074
5489
 
5075
5490
  @classmethod
@@ -5099,7 +5514,7 @@ class security_Vulnerability(Artifact):
5099
5514
  NODE_KIND = NodeKind.IRI
5100
5515
  ID_ALIAS = "spdxId"
5101
5516
  IS_DEPRECATED = False
5102
- NAMED_INDIVIDUALS = {
5517
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5103
5518
  }
5104
5519
 
5105
5520
  @classmethod
@@ -5137,7 +5552,7 @@ class software_SoftwareArtifact(Artifact):
5137
5552
  NODE_KIND = NodeKind.IRI
5138
5553
  ID_ALIAS = "spdxId"
5139
5554
  IS_DEPRECATED = False
5140
- NAMED_INDIVIDUALS = {
5555
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5141
5556
  }
5142
5557
 
5143
5558
  @classmethod
@@ -5255,7 +5670,7 @@ class Bom(Bundle):
5255
5670
  NODE_KIND = NodeKind.IRI
5256
5671
  ID_ALIAS = "spdxId"
5257
5672
  IS_DEPRECATED = False
5258
- NAMED_INDIVIDUALS = {
5673
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5259
5674
  }
5260
5675
 
5261
5676
 
@@ -5265,7 +5680,7 @@ class expandedlicensing_CustomLicense(expandedlicensing_License):
5265
5680
  NODE_KIND = NodeKind.IRI
5266
5681
  ID_ALIAS = "spdxId"
5267
5682
  IS_DEPRECATED = False
5268
- NAMED_INDIVIDUALS = {
5683
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5269
5684
  }
5270
5685
 
5271
5686
 
@@ -5276,7 +5691,7 @@ class security_VexAffectedVulnAssessmentRelationship(security_VexVulnAssessmentR
5276
5691
  NODE_KIND = NodeKind.IRI
5277
5692
  ID_ALIAS = "spdxId"
5278
5693
  IS_DEPRECATED = False
5279
- NAMED_INDIVIDUALS = {
5694
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5280
5695
  }
5281
5696
 
5282
5697
  @classmethod
@@ -5310,7 +5725,7 @@ class security_VexFixedVulnAssessmentRelationship(security_VexVulnAssessmentRela
5310
5725
  NODE_KIND = NodeKind.IRI
5311
5726
  ID_ALIAS = "spdxId"
5312
5727
  IS_DEPRECATED = False
5313
- NAMED_INDIVIDUALS = {
5728
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5314
5729
  }
5315
5730
 
5316
5731
 
@@ -5321,7 +5736,7 @@ class security_VexNotAffectedVulnAssessmentRelationship(security_VexVulnAssessme
5321
5736
  NODE_KIND = NodeKind.IRI
5322
5737
  ID_ALIAS = "spdxId"
5323
5738
  IS_DEPRECATED = False
5324
- NAMED_INDIVIDUALS = {
5739
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5325
5740
  }
5326
5741
 
5327
5742
  @classmethod
@@ -5370,7 +5785,7 @@ class security_VexUnderInvestigationVulnAssessmentRelationship(security_VexVulnA
5370
5785
  NODE_KIND = NodeKind.IRI
5371
5786
  ID_ALIAS = "spdxId"
5372
5787
  IS_DEPRECATED = False
5373
- NAMED_INDIVIDUALS = {
5788
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5374
5789
  }
5375
5790
 
5376
5791
 
@@ -5380,7 +5795,7 @@ class software_File(software_SoftwareArtifact):
5380
5795
  NODE_KIND = NodeKind.IRI
5381
5796
  ID_ALIAS = "spdxId"
5382
5797
  IS_DEPRECATED = False
5383
- NAMED_INDIVIDUALS = {
5798
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5384
5799
  }
5385
5800
 
5386
5801
  @classmethod
@@ -5414,7 +5829,7 @@ class software_Package(software_SoftwareArtifact):
5414
5829
  NODE_KIND = NodeKind.IRI
5415
5830
  ID_ALIAS = "spdxId"
5416
5831
  IS_DEPRECATED = False
5417
- NAMED_INDIVIDUALS = {
5832
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5418
5833
  }
5419
5834
 
5420
5835
  @classmethod
@@ -5472,7 +5887,7 @@ class software_Sbom(Bom):
5472
5887
  NODE_KIND = NodeKind.IRI
5473
5888
  ID_ALIAS = "spdxId"
5474
5889
  IS_DEPRECATED = False
5475
- NAMED_INDIVIDUALS = {
5890
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5476
5891
  }
5477
5892
 
5478
5893
  @classmethod
@@ -5501,7 +5916,7 @@ class software_Snippet(software_SoftwareArtifact):
5501
5916
  NODE_KIND = NodeKind.IRI
5502
5917
  ID_ALIAS = "spdxId"
5503
5918
  IS_DEPRECATED = False
5504
- NAMED_INDIVIDUALS = {
5919
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5505
5920
  }
5506
5921
 
5507
5922
  @classmethod
@@ -5542,7 +5957,7 @@ class ai_AIPackage(software_Package):
5542
5957
  NODE_KIND = NodeKind.IRI
5543
5958
  ID_ALIAS = "spdxId"
5544
5959
  IS_DEPRECATED = False
5545
- NAMED_INDIVIDUALS = {
5960
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5546
5961
  }
5547
5962
 
5548
5963
  @classmethod
@@ -5695,7 +6110,7 @@ class dataset_DatasetPackage(software_Package):
5695
6110
  NODE_KIND = NodeKind.IRI
5696
6111
  ID_ALIAS = "spdxId"
5697
6112
  IS_DEPRECATED = False
5698
- NAMED_INDIVIDUALS = {
6113
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5699
6114
  }
5700
6115
 
5701
6116
  @classmethod