spdx-python-model 0.0.1__py3-none-any.whl → 0.0.3__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,36 @@ 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
+ Union,
37
+ cast,
38
+ )
39
+
40
+
41
+ def check_type(obj: Any, types: Union[Type[Any], Tuple[Type[Any], ...]]) -> None:
24
42
  if not isinstance(obj, types):
25
43
  if isinstance(types, (list, tuple)):
26
44
  raise TypeError(
27
- f"Value must be one of type: {', '.join(t.__name__ for t in types)}. Got {type(obj)}"
45
+ f"Value must be one of type: {', '.join(t.__name__ for t in types)}. Got {type(obj).__name__}"
28
46
  )
29
- raise TypeError(f"Value must be of type {types.__name__}. Got {type(obj)}")
47
+ raise TypeError(
48
+ f"Value must be of type {types.__name__}. Got {type(obj).__name__}"
49
+ )
30
50
 
31
51
 
32
52
  class Property(ABC):
@@ -35,13 +55,15 @@ class Property(ABC):
35
55
  class
36
56
  """
37
57
 
38
- def __init__(self, *, pattern=None):
58
+ VALID_TYPES: Union[Tuple, Type] = ()
59
+
60
+ def __init__(self, *, pattern: Optional[str] = None):
39
61
  self.pattern = pattern
40
62
 
41
- def init(self):
63
+ def init(self) -> Any:
42
64
  return None
43
65
 
44
- def validate(self, value):
66
+ def validate(self, value) -> None:
45
67
  check_type(value, self.VALID_TYPES)
46
68
  if self.pattern is not None and not re.search(
47
69
  self.pattern, self.to_string(value)
@@ -50,37 +72,41 @@ class Property(ABC):
50
72
  f"Value is not correctly formatted. Got '{self.to_string(value)}'"
51
73
  )
52
74
 
53
- def set(self, value):
75
+ def set(self, value: Any) -> Any:
54
76
  return value
55
77
 
56
- def check_min_count(self, value, min_count):
78
+ def check_min_count(self, value, min_count: int) -> bool:
57
79
  return min_count == 1
58
80
 
59
- def check_max_count(self, value, max_count):
81
+ def check_max_count(self, value, max_count: int) -> bool:
60
82
  return max_count == 1
61
83
 
62
- def elide(self, value):
84
+ def elide(self, value) -> bool:
63
85
  return value is None
64
86
 
65
- def walk(self, value, callback, path):
87
+ def walk(self, value, callback: Callable, path: List[str]) -> None:
66
88
  callback(value, path)
67
89
 
68
- def iter_objects(self, value, recursive, visited):
90
+ def iter_objects(
91
+ self, value, recursive: bool, visited: Set[SHACLObject]
92
+ ) -> Iterable[Any]:
69
93
  return []
70
94
 
71
- def link_prop(self, value, objectset, missing, visited):
95
+ def link_prop(
96
+ self, value, objectset, missing: Optional[Set[str]], visited: Set[SHACLObject]
97
+ ):
72
98
  return value
73
99
 
74
- def to_string(self, value):
100
+ def to_string(self, value) -> str:
75
101
  return str(value)
76
102
 
77
103
  @abstractmethod
78
- def encode(self, encoder, value, state):
79
- pass
104
+ def encode(self, encoder, value, state) -> None:
105
+ raise NotImplementedError("Subclasses must implement encode method")
80
106
 
81
107
  @abstractmethod
82
- def decode(self, decoder, *, objectset=None):
83
- pass
108
+ def decode(self, decoder, *, objectset: Optional[SHACLObjectSet] = None) -> Any:
109
+ raise NotImplementedError("Subclasses must implement decode method")
84
110
 
85
111
 
86
112
  class StringProp(Property):
@@ -90,21 +116,25 @@ class StringProp(Property):
90
116
 
91
117
  VALID_TYPES = str
92
118
 
93
- def set(self, value):
119
+ def set(self, value) -> str:
94
120
  return str(value)
95
121
 
96
- def encode(self, encoder, value, state):
122
+ def encode(self, encoder, value, state) -> None:
97
123
  encoder.write_string(value)
98
124
 
99
- def decode(self, decoder, *, objectset=None):
125
+ def decode(
126
+ self, decoder, *, objectset: Optional[SHACLObjectSet] = None
127
+ ) -> Optional[str]:
100
128
  return decoder.read_string()
101
129
 
102
130
 
103
131
  class AnyURIProp(StringProp):
104
- def encode(self, encoder, value, state):
132
+ def encode(self, encoder, value, state) -> None:
105
133
  encoder.write_iri(value)
106
134
 
107
- def decode(self, decoder, *, objectset=None):
135
+ def decode(
136
+ self, decoder, *, objectset: Optional[SHACLObjectSet] = None
137
+ ) -> Optional[str]:
108
138
  return decoder.read_iri()
109
139
 
110
140
 
@@ -117,37 +147,52 @@ class DateTimeProp(Property):
117
147
  UTC_FORMAT_STR = "%Y-%m-%dT%H:%M:%SZ"
118
148
  REGEX = r"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|[+-]\d{2}:\d{2})?$"
119
149
 
120
- def set(self, value):
150
+ def set(self, value) -> datetime:
121
151
  return self._normalize(value)
122
152
 
123
- def encode(self, encoder, value, state):
153
+ def encode(self, encoder, value, state) -> None:
124
154
  encoder.write_datetime(self.to_string(value))
125
155
 
126
- def decode(self, decoder, *, objectset=None):
156
+ def decode(
157
+ self, decoder, *, objectset: Optional[SHACLObjectSet] = None
158
+ ) -> Optional[datetime]:
127
159
  s = decoder.read_datetime()
128
160
  if s is None:
129
161
  return None
162
+ if isinstance(s, datetime):
163
+ return self._normalize(s)
130
164
  v = self.from_string(s)
131
165
  return self._normalize(v)
132
166
 
133
- def _normalize(self, value):
167
+ def _normalize(self, value: datetime) -> datetime:
134
168
  if value.utcoffset() is None:
135
169
  value = value.astimezone()
170
+
171
+ # Remove seconds from timezone offset
136
172
  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))
173
+ if offset is not None:
174
+ seconds = offset % timedelta(
175
+ minutes=-1 if offset.total_seconds() < 0 else 1
176
+ )
177
+ if seconds:
178
+ offset = offset - seconds
179
+ value = value.replace(tzinfo=timezone(offset))
180
+
181
+ # Convert 00:00 timezone offset to UTC
182
+ offset = value.utcoffset()
183
+ if offset is not None and offset.seconds == 0:
184
+ value = value.astimezone(timezone.utc)
185
+
141
186
  value = value.replace(microsecond=0)
142
187
  return value
143
188
 
144
- def to_string(self, value):
189
+ def to_string(self, value: datetime) -> str:
145
190
  value = self._normalize(value)
146
191
  if value.tzinfo == timezone.utc:
147
192
  return value.strftime(self.UTC_FORMAT_STR)
148
193
  return value.isoformat()
149
194
 
150
- def from_string(self, value):
195
+ def from_string(self, value: str) -> datetime:
151
196
  if not re.match(self.REGEX, value):
152
197
  raise ValueError(f"'{value}' is not a correctly formatted datetime")
153
198
  if "Z" in value:
@@ -172,25 +217,27 @@ class DateTimeStampProp(DateTimeProp):
172
217
  class IntegerProp(Property):
173
218
  VALID_TYPES = int
174
219
 
175
- def set(self, value):
220
+ def set(self, value) -> int:
176
221
  return int(value)
177
222
 
178
- def encode(self, encoder, value, state):
223
+ def encode(self, encoder, value, state) -> None:
179
224
  encoder.write_integer(value)
180
225
 
181
- def decode(self, decoder, *, objectset=None):
226
+ def decode(
227
+ self, decoder, *, objectset: Optional[SHACLObjectSet] = None
228
+ ) -> Optional[int]:
182
229
  return decoder.read_integer()
183
230
 
184
231
 
185
232
  class PositiveIntegerProp(IntegerProp):
186
- def validate(self, value):
233
+ def validate(self, value) -> None:
187
234
  super().validate(value)
188
235
  if value < 1:
189
236
  raise ValueError(f"Value must be >=1. Got {value}")
190
237
 
191
238
 
192
239
  class NonNegativeIntegerProp(IntegerProp):
193
- def validate(self, value):
240
+ def validate(self, value) -> None:
194
241
  super().validate(value)
195
242
  if value < 0:
196
243
  raise ValueError(f"Value must be >= 0. Got {value}")
@@ -199,41 +246,52 @@ class NonNegativeIntegerProp(IntegerProp):
199
246
  class BooleanProp(Property):
200
247
  VALID_TYPES = bool
201
248
 
202
- def set(self, value):
249
+ def set(self, value) -> bool:
203
250
  return bool(value)
204
251
 
205
- def encode(self, encoder, value, state):
252
+ def encode(self, encoder, value, state) -> None:
206
253
  encoder.write_bool(value)
207
254
 
208
- def decode(self, decoder, *, objectset=None):
255
+ def decode(
256
+ self, decoder, *, objectset: Optional[SHACLObjectSet] = None
257
+ ) -> Optional[bool]:
209
258
  return decoder.read_bool()
210
259
 
211
260
 
212
261
  class FloatProp(Property):
213
262
  VALID_TYPES = (float, int)
214
263
 
215
- def set(self, value):
264
+ def set(self, value) -> float:
216
265
  return float(value)
217
266
 
218
- def encode(self, encoder, value, state):
267
+ def encode(self, encoder, value, state) -> None:
219
268
  encoder.write_float(value)
220
269
 
221
- def decode(self, decoder, *, objectset=None):
270
+ def decode(
271
+ self, decoder, *, objectset: Optional[SHACLObjectSet] = None
272
+ ) -> Optional[float]:
222
273
  return decoder.read_float()
223
274
 
224
275
 
225
276
  class IRIProp(Property):
226
- def __init__(self, context=[], *, pattern=None):
277
+ def __init__(
278
+ self,
279
+ context: Optional[List[Tuple[str, str]]] = None,
280
+ *,
281
+ pattern: Optional[str] = None,
282
+ ):
283
+ if context is None:
284
+ context = []
227
285
  super().__init__(pattern=pattern)
228
286
  self.context = context
229
287
 
230
- def compact(self, value):
288
+ def compact(self, value) -> Optional[str]:
231
289
  for iri, compact in self.context:
232
290
  if value == iri:
233
291
  return compact
234
292
  return None
235
293
 
236
- def expand(self, value):
294
+ def expand(self, value) -> Optional[str]:
237
295
  for iri, compact in self.context:
238
296
  if value == compact:
239
297
  return iri
@@ -248,20 +306,19 @@ class ObjectProp(IRIProp):
248
306
  A scalar SHACL object property of a SHACL object
249
307
  """
250
308
 
251
- def __init__(self, cls, required, context=[]):
309
+ def __init__(
310
+ self, cls, required: bool, context: Optional[List[Tuple[str, str]]] = None
311
+ ):
312
+ if context is None:
313
+ context = []
252
314
  super().__init__(context)
253
315
  self.cls = cls
254
316
  self.required = required
255
317
 
256
- def init(self):
257
- if self.required and not self.cls.IS_ABSTRACT:
258
- return self.cls()
259
- return None
260
-
261
- def validate(self, value):
318
+ def validate(self, value) -> None:
262
319
  check_type(value, (self.cls, str))
263
320
 
264
- def walk(self, value, callback, path):
321
+ def walk(self, value, callback: Callable, path: List[str]) -> None:
265
322
  if value is None:
266
323
  return
267
324
 
@@ -270,7 +327,7 @@ class ObjectProp(IRIProp):
270
327
  else:
271
328
  callback(value, path)
272
329
 
273
- def iter_objects(self, value, recursive, visited):
330
+ def iter_objects(self, value, recursive: bool, visited):
274
331
  if value is None or isinstance(value, str):
275
332
  return
276
333
 
@@ -282,7 +339,7 @@ class ObjectProp(IRIProp):
282
339
  for c in value.iter_objects(recursive=True, visited=visited):
283
340
  yield c
284
341
 
285
- def encode(self, encoder, value, state):
342
+ def encode(self, encoder, value, state) -> None:
286
343
  if value is None:
287
344
  raise ValueError("Object cannot be None")
288
345
 
@@ -292,11 +349,12 @@ class ObjectProp(IRIProp):
292
349
 
293
350
  return value.encode(encoder, state)
294
351
 
295
- def decode(self, decoder, *, objectset=None):
296
- iri = decoder.read_iri()
297
- if iri is None:
352
+ def decode(self, decoder, *, objectset: Optional[SHACLObjectSet] = None):
353
+ if decoder.is_object():
298
354
  return self.cls.decode(decoder, objectset=objectset)
299
355
 
356
+ iri = decoder.read_iri()
357
+
300
358
  iri = self.expand(iri) or iri
301
359
 
302
360
  if objectset is None:
@@ -334,41 +392,45 @@ class ObjectProp(IRIProp):
334
392
 
335
393
 
336
394
  class ListProxy(object):
337
- def __init__(self, prop, data=None):
395
+ def __init__(self, prop: Property, data: Optional[List[Any]] = None):
338
396
  if data is None:
339
- self.__data = []
397
+ self.__data: List[Any] = []
340
398
  else:
341
399
  self.__data = data
342
400
  self.__prop = prop
343
401
 
344
- def append(self, value):
402
+ def append(self, value) -> None:
345
403
  self.__prop.validate(value)
346
404
  self.__data.append(self.__prop.set(value))
347
405
 
348
- def insert(self, idx, value):
406
+ def insert(self, idx: int, value) -> None:
349
407
  self.__prop.validate(value)
350
408
  self.__data.insert(idx, self.__prop.set(value))
351
409
 
352
- def extend(self, items):
410
+ def extend(self, items: Iterable[Any]) -> None:
353
411
  for i in items:
354
412
  self.append(i)
355
413
 
356
- def sort(self, *args, **kwargs):
414
+ def sort(self, *args, **kwargs) -> None:
357
415
  self.__data.sort(*args, **kwargs)
358
416
 
359
417
  def __getitem__(self, key):
360
418
  return self.__data[key]
361
419
 
362
- def __setitem__(self, key, value):
420
+ def __setitem__(self, key, value) -> None:
363
421
  if isinstance(key, slice):
364
422
  for v in value:
365
423
  self.__prop.validate(v)
366
424
  self.__data[key] = [self.__prop.set(v) for v in value]
367
- else:
425
+ elif isinstance(key, int):
368
426
  self.__prop.validate(value)
369
427
  self.__data[key] = self.__prop.set(value)
428
+ else:
429
+ raise TypeError(
430
+ f"ListProxy indices must be integers or slices. Got {type(key).__name__}"
431
+ )
370
432
 
371
- def __delitem__(self, key):
433
+ def __delitem__(self, key) -> None:
372
434
  del self.__data[key]
373
435
 
374
436
  def __contains__(self, item):
@@ -377,10 +439,10 @@ class ListProxy(object):
377
439
  def __iter__(self):
378
440
  return iter(self.__data)
379
441
 
380
- def __len__(self):
442
+ def __len__(self) -> int:
381
443
  return len(self.__data)
382
444
 
383
- def __str__(self):
445
+ def __str__(self) -> str:
384
446
  return str(self.__data)
385
447
 
386
448
  def __repr__(self):
@@ -400,43 +462,43 @@ class ListProp(Property):
400
462
 
401
463
  VALID_TYPES = (list, ListProxy)
402
464
 
403
- def __init__(self, prop):
465
+ def __init__(self, prop: Property):
404
466
  super().__init__()
405
467
  self.prop = prop
406
468
 
407
- def init(self):
469
+ def init(self) -> ListProxy:
408
470
  return ListProxy(self.prop)
409
471
 
410
- def validate(self, value):
472
+ def validate(self, value) -> None:
411
473
  super().validate(value)
412
474
 
413
475
  for i in value:
414
476
  self.prop.validate(i)
415
477
 
416
- def set(self, value):
478
+ def set(self, value) -> ListProxy:
417
479
  if isinstance(value, ListProxy):
418
480
  return value
419
481
 
420
482
  return ListProxy(self.prop, [self.prop.set(d) for d in value])
421
483
 
422
- def check_min_count(self, value, min_count):
484
+ def check_min_count(self, value, min_count: int) -> bool:
423
485
  check_type(value, ListProxy)
424
486
  return len(value) >= min_count
425
487
 
426
- def check_max_count(self, value, max_count):
488
+ def check_max_count(self, value, max_count: int) -> bool:
427
489
  check_type(value, ListProxy)
428
490
  return len(value) <= max_count
429
491
 
430
- def elide(self, value):
492
+ def elide(self, value) -> bool:
431
493
  check_type(value, ListProxy)
432
494
  return len(value) == 0
433
495
 
434
- def walk(self, value, callback, path):
496
+ def walk(self, value, callback: Callable, path: List[str]) -> None:
435
497
  callback(value, path)
436
498
  for idx, v in enumerate(value):
437
499
  self.prop.walk(v, callback, path + [f"[{idx}]"])
438
500
 
439
- def iter_objects(self, value, recursive, visited):
501
+ def iter_objects(self, value, recursive: bool, visited):
440
502
  for v in value:
441
503
  for c in self.prop.iter_objects(v, recursive, visited):
442
504
  yield c
@@ -449,7 +511,7 @@ class ListProp(Property):
449
511
 
450
512
  return ListProxy(self.prop, data=data)
451
513
 
452
- def encode(self, encoder, value, state):
514
+ def encode(self, encoder, value, state) -> None:
453
515
  check_type(value, ListProxy)
454
516
 
455
517
  with encoder.write_list() as list_s:
@@ -457,7 +519,9 @@ class ListProp(Property):
457
519
  with list_s.write_list_item() as item_s:
458
520
  self.prop.encode(item_s, v, state)
459
521
 
460
- def decode(self, decoder, *, objectset=None):
522
+ def decode(
523
+ self, decoder, *, objectset: Optional[SHACLObjectSet] = None
524
+ ) -> ListProxy:
461
525
  data = []
462
526
  for val_d in decoder.read_list():
463
527
  v = self.prop.decode(val_d, objectset=objectset)
@@ -470,10 +534,10 @@ class ListProp(Property):
470
534
  class EnumProp(IRIProp):
471
535
  VALID_TYPES = str
472
536
 
473
- def __init__(self, values, *, pattern=None):
537
+ def __init__(self, values, *, pattern: Optional[str] = None):
474
538
  super().__init__(values, pattern=pattern)
475
539
 
476
- def validate(self, value):
540
+ def validate(self, value) -> None:
477
541
  super().validate(value)
478
542
 
479
543
  valid_values = self.iri_values()
@@ -482,10 +546,10 @@ class EnumProp(IRIProp):
482
546
  f"'{value}' is not a valid value. Choose one of {' '.join(valid_values)}"
483
547
  )
484
548
 
485
- def encode(self, encoder, value, state):
549
+ def encode(self, encoder, value, state) -> None:
486
550
  encoder.write_enum(value, self, self.compact(value))
487
551
 
488
- def decode(self, decoder, *, objectset=None):
552
+ def decode(self, decoder, *, objectset: Optional[SHACLObjectSet] = None) -> str:
489
553
  v = decoder.read_enum(self)
490
554
  return self.expand(v) or v
491
555
 
@@ -496,7 +560,7 @@ class NodeKind(Enum):
496
560
  BlankNodeOrIRI = 3
497
561
 
498
562
 
499
- def is_IRI(s):
563
+ def is_IRI(s: Any) -> bool:
500
564
  if not isinstance(s, str):
501
565
  return False
502
566
  if s.startswith("_:"):
@@ -506,7 +570,7 @@ def is_IRI(s):
506
570
  return True
507
571
 
508
572
 
509
- def is_blank_node(s):
573
+ def is_blank_node(s: Any) -> bool:
510
574
  if not isinstance(s, str):
511
575
  return False
512
576
  if not s.startswith("_:"):
@@ -514,19 +578,23 @@ def is_blank_node(s):
514
578
  return True
515
579
 
516
580
 
517
- def register(type_iri, *, compact_type=None, abstract=False):
518
- def add_class(key, c):
581
+ def register(
582
+ type_iri: str, *, compact_type: Optional[str] = None, abstract: bool = False
583
+ ):
584
+ def add_class(key: str, c: Type[SHACLObject]) -> None:
519
585
  assert (
520
586
  key not in SHACLObject.CLASSES
521
587
  ), f"{key} already registered to {SHACLObject.CLASSES[key].__name__}"
522
588
  SHACLObject.CLASSES[key] = c
523
589
 
524
- def decorator(c):
590
+ def decorator(c: Type[SHACLObject]) -> Type[SHACLObject]:
591
+ """
592
+ Decorator to register a class as a SHACL object type.
593
+ The class must derive from SHACLObject.
594
+ """
525
595
  global NAMED_INDIVIDUALS
526
596
 
527
- assert issubclass(
528
- c, SHACLObject
529
- ), f"{c.__name__} is not derived from SHACLObject"
597
+ assert issubclass(c, SHACLObject), f"{c} is not derived from SHACLObject"
530
598
 
531
599
  c._OBJ_TYPE = type_iri
532
600
  c.IS_ABSTRACT = abstract
@@ -547,16 +615,31 @@ def register(type_iri, *, compact_type=None, abstract=False):
547
615
 
548
616
 
549
617
  register_lock = threading.Lock()
550
- NAMED_INDIVIDUALS = set()
618
+ NAMED_INDIVIDUALS: Set[str] = set()
551
619
 
552
620
 
553
621
  @functools.total_ordering
554
622
  class SHACLObject(object):
555
- CLASSES = {}
623
+ CLASSES: Dict[str, Type] = {}
624
+ NAMED_INDIVIDUALS: Dict[str, str] = {}
556
625
  NODE_KIND = NodeKind.BlankNodeOrIRI
557
- ID_ALIAS = None
558
- IS_ABSTRACT = True
559
- IS_DEPRECATED = False
626
+ ID_ALIAS: Optional[str] = None
627
+ IS_ABSTRACT: bool = True
628
+ IS_DEPRECATED: bool = False
629
+
630
+ # These will be reinitialized during registration with @register decorator,
631
+ # defined here first to allow visibility at class level
632
+ _OBJ_TYPE: str = ""
633
+ _OBJ_COMPACT_TYPE: Optional[str] = None
634
+ _OBJ_PROPERTIES: Dict[str, Tuple] = {}
635
+ _OBJ_IRIS: Dict[str, str] = {}
636
+ _OBJ_DEPRECATED: Set[str] = set()
637
+ _NEEDS_REG: bool = True
638
+
639
+ # Instance variables
640
+ _id: Optional[str]
641
+ _obj_data: Dict[str, Any]
642
+ _obj_metadata: Dict[str, Any]
560
643
 
561
644
  def __init__(self, **kwargs):
562
645
  if self._is_abstract():
@@ -565,7 +648,9 @@ class SHACLObject(object):
565
648
  )
566
649
 
567
650
  if self.__class__.IS_DEPRECATED:
568
- warnings.warn(f"{self.__class__.__name__} is deprecated", DeprecationWarning)
651
+ warnings.warn(
652
+ f"{self.__class__.__name__} is deprecated", DeprecationWarning
653
+ )
569
654
 
570
655
  with register_lock:
571
656
  cls = self.__class__
@@ -585,24 +670,24 @@ class SHACLObject(object):
585
670
  for k, v in kwargs.items():
586
671
  setattr(self, k, v)
587
672
 
588
- def _is_abstract(self):
673
+ def _is_abstract(self) -> bool:
589
674
  return self.__class__.IS_ABSTRACT
590
675
 
591
676
  @classmethod
592
- def _register_props(cls):
677
+ def _register_props(cls: Type[SHACLObject]) -> None:
593
678
  cls._add_property("_id", StringProp(), iri="@id")
594
679
 
595
680
  @classmethod
596
681
  def _add_property(
597
- cls,
598
- pyname,
599
- prop,
600
- iri,
601
- min_count=None,
602
- max_count=None,
603
- compact=None,
604
- deprecated=False,
605
- ):
682
+ cls: Type[SHACLObject],
683
+ pyname: str,
684
+ prop: Property,
685
+ iri: str,
686
+ min_count: Optional[int] = None,
687
+ max_count: Optional[int] = None,
688
+ compact: Optional[str] = None,
689
+ deprecated: bool = False,
690
+ ) -> None:
606
691
  if pyname in cls._OBJ_IRIS:
607
692
  raise KeyError(f"'{pyname}' is already defined for '{cls.__name__}'")
608
693
  if iri in cls._OBJ_PROPERTIES:
@@ -619,7 +704,7 @@ class SHACLObject(object):
619
704
  if deprecated:
620
705
  cls._OBJ_DEPRECATED.add(iri)
621
706
 
622
- def __setattr__(self, name, value):
707
+ def __setattr__(self, name: str, value) -> None:
623
708
  if name == self.ID_ALIAS:
624
709
  self["@id"] = value
625
710
  return
@@ -632,7 +717,7 @@ class SHACLObject(object):
632
717
  f"'{name}' is not a valid property of {self.__class__.__name__}"
633
718
  )
634
719
 
635
- def __getattr__(self, name):
720
+ def __getattr__(self, name: str):
636
721
  if name in self._OBJ_IRIS:
637
722
  return self.__dict__["_obj_data"][self._OBJ_IRIS[name]]
638
723
 
@@ -655,7 +740,7 @@ class SHACLObject(object):
655
740
  f"'{name}' is not a valid property of {self.__class__.__name__}"
656
741
  )
657
742
 
658
- def __delattr__(self, name):
743
+ def __delattr__(self, name: str) -> None:
659
744
  if name == self.ID_ALIAS:
660
745
  del self["@id"]
661
746
  return
@@ -668,7 +753,9 @@ class SHACLObject(object):
668
753
  f"'{name}' is not a valid property of {self.__class__.__name__}"
669
754
  )
670
755
 
671
- def __get_prop(self, iri):
756
+ def __get_prop(
757
+ self, iri: str
758
+ ) -> Tuple[Property, Optional[int], Optional[int], str, Optional[str]]:
672
759
  if iri not in self._OBJ_PROPERTIES:
673
760
  raise KeyError(
674
761
  f"'{iri}' is not a valid property of {self.__class__.__name__}"
@@ -676,45 +763,51 @@ class SHACLObject(object):
676
763
 
677
764
  return self._OBJ_PROPERTIES[iri]
678
765
 
679
- def __iter_props(self):
766
+ def __iter_props(
767
+ self,
768
+ ) -> Iterator[
769
+ Tuple[str, Property, Optional[int], Optional[int], str, Optional[str]]
770
+ ]:
680
771
  for iri, v in self._OBJ_PROPERTIES.items():
681
772
  yield iri, *v
682
773
 
683
- def __getitem__(self, iri):
774
+ def __getitem__(self, iri: str) -> Any:
684
775
  return self.__dict__["_obj_data"][iri]
685
776
 
686
- def __setitem__(self, iri, value):
777
+ def __setitem__(self, iri: str, value) -> None:
687
778
  if iri == "@id":
688
779
  if self.NODE_KIND == NodeKind.BlankNode:
689
780
  if not is_blank_node(value):
690
781
  raise ValueError(
691
- f"{self.__class__.__name__} ({id(self)}) can only have local reference. Property '{iri}' cannot be set to '{value}' and must start with '_:'"
782
+ f"{self.__class__.__name__} ({id(self)}) can only have local reference. Property '{iri}' cannot be set to {value!r} and must start with '_:'"
692
783
  )
693
784
  elif self.NODE_KIND == NodeKind.IRI:
694
785
  if not is_IRI(value):
695
786
  raise ValueError(
696
- f"{self.__class__.__name__} ({id(self)}) can only have an IRI value. Property '{iri}' cannot be set to '{value}'"
787
+ f"{self.__class__.__name__} ({id(self)}) can only have an IRI value. Property '{iri}' cannot be set to {value!r}"
697
788
  )
698
789
  else:
699
790
  if not is_blank_node(value) and not is_IRI(value):
700
791
  raise ValueError(
701
- f"{self.__class__.__name__} ({id(self)}) Has invalid Property '{iri}' '{value}'. Must be a blank node or IRI"
792
+ f"{self.__class__.__name__} ({id(self)}) Has invalid Property '{iri}' {value!r}. Must be a blank node or IRI"
702
793
  )
703
794
 
704
795
  prop, _, _, pyname, _ = self.__get_prop(iri)
705
796
  prop.validate(value)
706
797
  if iri in self._OBJ_DEPRECATED:
707
- warnings.warn(f"{self.__class__.__name__}.{pyname} is deprecated", DeprecationWarning)
798
+ warnings.warn(
799
+ f"{self.__class__.__name__}.{pyname} is deprecated", DeprecationWarning
800
+ )
708
801
  self.__dict__["_obj_data"][iri] = prop.set(value)
709
802
 
710
- def __delitem__(self, iri):
803
+ def __delitem__(self, iri: str) -> None:
711
804
  prop, _, _, _, _ = self.__get_prop(iri)
712
805
  self.__dict__["_obj_data"][iri] = prop.init()
713
806
 
714
- def __iter__(self):
715
- return self._OBJ_PROPERTIES.keys()
807
+ def __iter__(self) -> Iterator[str]:
808
+ return iter(self._OBJ_PROPERTIES.keys())
716
809
 
717
- def walk(self, callback, path=None):
810
+ def walk(self, callback: Callable, path: Optional[List[str]] = None) -> None:
718
811
  """
719
812
  Walk object tree, invoking the callback for each item
720
813
 
@@ -729,13 +822,13 @@ class SHACLObject(object):
729
822
  for iri, prop, _, _, _, _ in self.__iter_props():
730
823
  prop.walk(self.__dict__["_obj_data"][iri], callback, path + [f".{iri}"])
731
824
 
732
- def property_keys(self):
825
+ def property_keys(self) -> Iterator[Tuple[Optional[str], str, Optional[str]]]:
733
826
  for iri, _, _, _, pyname, compact in self.__iter_props():
734
827
  if iri == "@id":
735
828
  compact = self.ID_ALIAS
736
829
  yield pyname, iri, compact
737
830
 
738
- def iter_objects(self, *, recursive=False, visited=None):
831
+ def iter_objects(self, *, recursive: bool = False, visited=None):
739
832
  """
740
833
  Iterate of all objects that are a child of this one
741
834
  """
@@ -748,7 +841,7 @@ class SHACLObject(object):
748
841
  ):
749
842
  yield c
750
843
 
751
- def encode(self, encoder, state):
844
+ def encode(self, encoder, state) -> None:
752
845
  idname = self.ID_ALIAS or self._OBJ_IRIS["_id"]
753
846
  if not self._id and self.NODE_KIND == NodeKind.IRI:
754
847
  raise ValueError(
@@ -797,52 +890,43 @@ class SHACLObject(object):
797
890
  prop.encode(prop_s, value, state)
798
891
 
799
892
  @classmethod
800
- def _make_object(cls, typ):
893
+ def _make_object(cls: Type["SHACLObject"], typ: str) -> "SHACLObject":
801
894
  if typ not in cls.CLASSES:
802
895
  raise TypeError(f"Unknown type {typ}")
803
896
 
804
897
  return cls.CLASSES[typ]()
805
898
 
806
899
  @classmethod
807
- def decode(cls, decoder, *, objectset=None):
900
+ def decode(cls, decoder, *, objectset: Optional[SHACLObjectSet] = None):
808
901
  typ, obj_d = decoder.read_object()
809
902
  if typ is None:
810
903
  raise TypeError("Unable to determine type for object")
811
904
 
812
905
  obj = cls._make_object(typ)
813
- for key in (obj.ID_ALIAS, obj._OBJ_IRIS["_id"]):
814
- with obj_d.read_property(key) as prop_d:
815
- if prop_d is None:
816
- continue
817
-
818
- _id = prop_d.read_iri()
819
- if _id is None:
820
- raise TypeError(f"Object key '{key}' is the wrong type")
821
-
822
- obj._id = _id
823
- break
906
+ _id = obj_d.read_object_id(obj.ID_ALIAS)
907
+ if _id is not None:
908
+ obj._id = _id
824
909
 
825
910
  if obj.NODE_KIND == NodeKind.IRI and not obj._id:
826
911
  raise ValueError("Object is missing required IRI")
827
912
 
828
913
  if objectset is not None:
829
914
  if obj._id:
830
- v = objectset.find_by_id(_id)
915
+ v = objectset.find_by_id(obj._id)
831
916
  if v is not None:
832
917
  return v
918
+ objectset.add_index(obj)
833
919
 
834
920
  obj._decode_properties(obj_d, objectset=objectset)
835
921
 
836
- if objectset is not None:
837
- objectset.add_index(obj)
838
922
  return obj
839
923
 
840
- def _decode_properties(self, decoder, objectset=None):
924
+ def _decode_properties(self, decoder, objectset: Optional[SHACLObjectSet] = None):
841
925
  for key in decoder.object_keys():
842
926
  if not self._decode_prop(decoder, key, objectset=objectset):
843
927
  raise KeyError(f"Unknown property '{key}'")
844
928
 
845
- def _decode_prop(self, decoder, key, objectset=None):
929
+ def _decode_prop(self, decoder, key, objectset: Optional[SHACLObjectSet] = None):
846
930
  if key in (self._OBJ_IRIS["_id"], self.ID_ALIAS):
847
931
  return True
848
932
 
@@ -862,7 +946,9 @@ class SHACLObject(object):
862
946
 
863
947
  return False
864
948
 
865
- def link_helper(self, objectset, missing, visited):
949
+ def link_helper(
950
+ self, objectset: Optional[SHACLObjectSet], missing, visited
951
+ ) -> None:
866
952
  if self in visited:
867
953
  return
868
954
 
@@ -905,7 +991,7 @@ class SHACLObject(object):
905
991
  return sort_key(self) < sort_key(other)
906
992
 
907
993
 
908
- class SHACLExtensibleObject(object):
994
+ class SHACLExtensibleObject(SHACLObject):
909
995
  CLOSED = False
910
996
 
911
997
  def __init__(self, typ=None, **kwargs):
@@ -915,7 +1001,7 @@ class SHACLExtensibleObject(object):
915
1001
  self.__dict__["_obj_TYPE"] = (self._OBJ_TYPE, self._OBJ_COMPACT_TYPE)
916
1002
  super().__init__(**kwargs)
917
1003
 
918
- def _is_abstract(self):
1004
+ def _is_abstract(self) -> bool:
919
1005
  # Unknown classes are assumed to not be abstract so that they can be
920
1006
  # deserialized
921
1007
  typ = self.__dict__["_obj_TYPE"][0]
@@ -933,7 +1019,7 @@ class SHACLExtensibleObject(object):
933
1019
  obj = cls(typ)
934
1020
  return obj
935
1021
 
936
- def _decode_properties(self, decoder, objectset=None):
1022
+ def _decode_properties(self, decoder, objectset: Optional[SHACLObjectSet] = None):
937
1023
  def decode_value(d):
938
1024
  if not d.is_list():
939
1025
  return d.read_value()
@@ -957,25 +1043,6 @@ class SHACLExtensibleObject(object):
957
1043
  self.__dict__["_obj_data"][key] = decode_value(prop_d)
958
1044
 
959
1045
  def _encode_properties(self, encoder, state):
960
- def encode_value(encoder, v):
961
- if isinstance(v, bool):
962
- encoder.write_bool(v)
963
- elif isinstance(v, str):
964
- encoder.write_string(v)
965
- elif isinstance(v, int):
966
- encoder.write_integer(v)
967
- elif isinstance(v, float):
968
- encoder.write_float(v)
969
- elif isinstance(v, list):
970
- with encoder.write_list() as list_s:
971
- for i in v:
972
- with list_s.write_list_item() as item_s:
973
- encode_value(item_s, i)
974
- else:
975
- raise TypeError(
976
- f"Unsupported serialized type {type(v)} with value '{v}'"
977
- )
978
-
979
1046
  super()._encode_properties(encoder, state)
980
1047
  if self.CLOSED:
981
1048
  return
@@ -985,9 +1052,27 @@ class SHACLExtensibleObject(object):
985
1052
  continue
986
1053
 
987
1054
  with encoder.write_property(iri) as prop_s:
988
- encode_value(prop_s, value)
989
-
990
- def __setitem__(self, iri, value):
1055
+ if isinstance(value, list):
1056
+ v = value
1057
+ else:
1058
+ v = [value]
1059
+ with prop_s.write_list() as list_s:
1060
+ for i in v:
1061
+ with list_s.write_list_item() as item_s:
1062
+ if isinstance(i, bool):
1063
+ item_s.write_bool(i)
1064
+ elif isinstance(i, str):
1065
+ item_s.write_string(i)
1066
+ elif isinstance(i, int):
1067
+ item_s.write_integer(i)
1068
+ elif isinstance(i, float):
1069
+ item_s.write_float(i)
1070
+ else:
1071
+ raise TypeError(
1072
+ f"Unsupported serialized type {type(i)} with value {i!r}"
1073
+ )
1074
+
1075
+ def __setitem__(self, iri: str, value) -> None:
991
1076
  try:
992
1077
  super().__setitem__(iri, value)
993
1078
  except KeyError:
@@ -996,9 +1081,10 @@ class SHACLExtensibleObject(object):
996
1081
 
997
1082
  if not is_IRI(iri):
998
1083
  raise KeyError(f"Key '{iri}' must be an IRI")
1084
+ obj_data = self.__dict__["_obj_data"]
999
1085
  self.__dict__["_obj_data"][iri] = value
1000
1086
 
1001
- def __delitem__(self, iri):
1087
+ def __delitem__(self, iri: str) -> None:
1002
1088
  try:
1003
1089
  super().__delitem__(iri)
1004
1090
  except KeyError:
@@ -1016,8 +1102,8 @@ class SHACLExtensibleObject(object):
1016
1102
  return self.__dict__["_obj_TYPE"][1]
1017
1103
  return super().__getattr__(name)
1018
1104
 
1019
- def property_keys(self):
1020
- iris = set()
1105
+ def property_keys(self) -> Iterator[Tuple[Optional[str], str, Optional[str]]]:
1106
+ iris: Set[str] = set()
1021
1107
  for pyname, iri, compact in super().property_keys():
1022
1108
  iris.add(iri)
1023
1109
  yield pyname, iri, compact
@@ -1031,16 +1117,16 @@ class SHACLExtensibleObject(object):
1031
1117
 
1032
1118
 
1033
1119
  class SHACLObjectSet(object):
1034
- def __init__(self, objects=[], *, link=False):
1035
- self.objects = set()
1036
- self.missing_ids = set()
1037
- for o in objects:
1038
- self.objects.add(o)
1120
+ def __init__(self, objects: Collection[SHACLObject] = [], *, link: bool = False):
1121
+ self.objects: Set[SHACLObject] = set(objects)
1122
+ self.missing_ids: Set[str] = set()
1123
+ self.obj_by_id: Dict[str, SHACLObject] = {}
1124
+ self.obj_by_type: Dict[str, Set[Tuple[bool, SHACLObject]]] = {}
1039
1125
  self.create_index()
1040
1126
  if link:
1041
1127
  self._link()
1042
1128
 
1043
- def create_index(self):
1129
+ def create_index(self) -> None:
1044
1130
  """
1045
1131
  (re)Create object index
1046
1132
 
@@ -1052,7 +1138,7 @@ class SHACLObjectSet(object):
1052
1138
  for o in self.foreach():
1053
1139
  self.add_index(o)
1054
1140
 
1055
- def add_index(self, obj):
1141
+ def add_index(self, obj: SHACLObject) -> None:
1056
1142
  """
1057
1143
  Add object to index
1058
1144
 
@@ -1086,7 +1172,7 @@ class SHACLObjectSet(object):
1086
1172
 
1087
1173
  self.obj_by_id[obj._id] = obj
1088
1174
 
1089
- def add(self, obj):
1175
+ def add(self, obj: SHACLObject) -> SHACLObject:
1090
1176
  """
1091
1177
  Add object to object set
1092
1178
 
@@ -1102,7 +1188,7 @@ class SHACLObjectSet(object):
1102
1188
  self.add_index(obj)
1103
1189
  return obj
1104
1190
 
1105
- def update(self, *others):
1191
+ def update(self, *others) -> None:
1106
1192
  """
1107
1193
  Update object set adding all objects in each other iterable
1108
1194
  """
@@ -1110,13 +1196,13 @@ class SHACLObjectSet(object):
1110
1196
  for obj in o:
1111
1197
  self.add(obj)
1112
1198
 
1113
- def __contains__(self, item):
1199
+ def __contains__(self, item: SHACLObject) -> bool:
1114
1200
  """
1115
1201
  Returns True if the item is in the object set
1116
1202
  """
1117
1203
  return item in self.objects
1118
1204
 
1119
- def link(self):
1205
+ def link(self) -> Set[str]:
1120
1206
  """
1121
1207
  Link object set
1122
1208
 
@@ -1132,24 +1218,24 @@ class SHACLObjectSet(object):
1132
1218
  self.create_index()
1133
1219
  return self._link()
1134
1220
 
1135
- def _link(self):
1221
+ def _link(self) -> Set[str]:
1136
1222
  global NAMED_INDIVIDUALS
1137
1223
 
1138
1224
  self.missing_ids = set()
1139
- visited = set()
1225
+ visited: Set[SHACLObject] = set()
1140
1226
 
1141
- new_objects = set()
1227
+ new_objects: Set[SHACLObject] = set()
1142
1228
 
1143
1229
  for o in self.objects:
1144
1230
  if o._id:
1145
- o = self.find_by_id(o._id, o)
1231
+ o = cast(SHACLObject, self.find_by_id(o._id, o))
1146
1232
  o.link_helper(self, self.missing_ids, visited)
1147
1233
  new_objects.add(o)
1148
1234
 
1149
1235
  self.objects = new_objects
1150
1236
 
1151
1237
  # Remove blank nodes
1152
- obj_by_id = {}
1238
+ obj_by_id: Dict[str, SHACLObject] = {}
1153
1239
  for _id, obj in self.obj_by_id.items():
1154
1240
  if _id.startswith("_:"):
1155
1241
  del obj._id
@@ -1162,7 +1248,9 @@ class SHACLObjectSet(object):
1162
1248
 
1163
1249
  return self.missing_ids
1164
1250
 
1165
- def find_by_id(self, _id, default=None):
1251
+ def find_by_id(
1252
+ self, _id: str, default: Optional[SHACLObject] = None
1253
+ ) -> Optional[SHACLObject]:
1166
1254
  """
1167
1255
  Find object by ID
1168
1256
 
@@ -1173,7 +1261,7 @@ class SHACLObjectSet(object):
1173
1261
  return default
1174
1262
  return self.obj_by_id[_id]
1175
1263
 
1176
- def foreach(self):
1264
+ def foreach(self) -> Iterable[SHACLObject]:
1177
1265
  """
1178
1266
  Iterate over every object in the object set, and all child objects
1179
1267
  """
@@ -1186,7 +1274,9 @@ class SHACLObjectSet(object):
1186
1274
  for child in o.iter_objects(recursive=True, visited=visited):
1187
1275
  yield child
1188
1276
 
1189
- def foreach_type(self, typ, *, match_subclass=True):
1277
+ def foreach_type(
1278
+ self, typ: Union[str, SHACLObject], *, match_subclass: bool = True
1279
+ ) -> Iterable[SHACLObject]:
1190
1280
  """
1191
1281
  Iterate over each object of a specified type (or subclass there of)
1192
1282
 
@@ -1195,8 +1285,9 @@ class SHACLObjectSet(object):
1195
1285
  returned
1196
1286
  """
1197
1287
  if not isinstance(typ, str):
1198
- if not issubclass(typ, SHACLObject):
1288
+ if not isinstance(typ, type) or not issubclass(typ, SHACLObject):
1199
1289
  raise TypeError(f"Type must be derived from SHACLObject, got {typ}")
1290
+ typ = cast(SHACLObject, typ)
1200
1291
  typ = typ._OBJ_TYPE
1201
1292
 
1202
1293
  if typ not in self.obj_by_type:
@@ -1206,7 +1297,7 @@ class SHACLObjectSet(object):
1206
1297
  if match_subclass or exact:
1207
1298
  yield o
1208
1299
 
1209
- def merge(self, *objectsets):
1300
+ def merge(self, *objectsets) -> "SHACLObjectSet":
1210
1301
  """
1211
1302
  Merge object sets
1212
1303
 
@@ -1220,16 +1311,59 @@ class SHACLObjectSet(object):
1220
1311
 
1221
1312
  return SHACLObjectSet(new_objects, link=True)
1222
1313
 
1223
- def encode(self, encoder, force_list=False, *, key=None):
1314
+ def inline_blank_nodes(self) -> None:
1315
+ """
1316
+ Removes (inlines) blank node objects from the root object set if they
1317
+ are referenced in only one other location besides the root.
1318
+
1319
+ Deserializers that do not preserve the tree-like structure of the
1320
+ objects (e.g. RDF) should call this to ensure that blank nodes are
1321
+ inline correctly
1322
+ """
1323
+ ref_counts: Dict[SHACLObject, int] = {}
1324
+
1325
+ def walk_callback(value: SHACLObject, path: List[str]) -> bool:
1326
+ nonlocal ref_counts
1327
+
1328
+ if not isinstance(value, SHACLObject):
1329
+ return True
1330
+
1331
+ ref_counts.setdefault(value, 0)
1332
+ ref_counts[value] += 1
1333
+ if ref_counts[value] > 1:
1334
+ return False
1335
+
1336
+ return True
1337
+
1338
+ for o in self.objects:
1339
+ # Note that every object in the root object set gets at least one
1340
+ # reference
1341
+ o.walk(walk_callback)
1342
+
1343
+ new_objects = set()
1344
+ for o in self.objects:
1345
+ if is_IRI(o._id):
1346
+ new_objects.add(o)
1347
+ # If the object is a blank node and is only referenced by this
1348
+ # root list and one other location, remove it from the root list
1349
+ #
1350
+ # A count of 1 means the object is only referenced by the root, and
1351
+ # therefore must be kept
1352
+ elif ref_counts[o] != 2:
1353
+ new_objects.add(o)
1354
+
1355
+ self.objects = new_objects
1356
+
1357
+ def encode(self, encoder, force_list: bool = False, *, key=None) -> None:
1224
1358
  """
1225
1359
  Serialize a list of objects to a serialization encoder
1226
1360
 
1227
1361
  If force_list is true, a list will always be written using the encoder.
1228
1362
  """
1229
- ref_counts = {}
1363
+ ref_counts: Dict[SHACLObject, int] = {}
1230
1364
  state = EncodeState()
1231
1365
 
1232
- def walk_callback(value, path):
1366
+ def walk_callback(value: SHACLObject, path: List[str]) -> bool:
1233
1367
  nonlocal state
1234
1368
  nonlocal ref_counts
1235
1369
 
@@ -1237,7 +1371,7 @@ class SHACLObjectSet(object):
1237
1371
  return True
1238
1372
 
1239
1373
  # Remove blank node ID for re-assignment
1240
- if value._id and value._id.startswith("_:"):
1374
+ if is_blank_node(value._id):
1241
1375
  del value._id
1242
1376
 
1243
1377
  if value._id:
@@ -1295,7 +1429,7 @@ class SHACLObjectSet(object):
1295
1429
  self.create_index()
1296
1430
 
1297
1431
  for obj_d in decoder.read_list():
1298
- o = SHACLObject.decode(obj_d, objectset=self)
1432
+ o = SHACLExtensibleObject.decode(obj_d, objectset=self)
1299
1433
  self.objects.add(o)
1300
1434
 
1301
1435
  self._link()
@@ -1317,13 +1451,13 @@ class EncodeState(object):
1317
1451
 
1318
1452
  return self.blank_objects[o]
1319
1453
 
1320
- def is_refed(self, o):
1454
+ def is_refed(self, o) -> bool:
1321
1455
  return o in self.ref_objects
1322
1456
 
1323
- def add_refed(self, o):
1457
+ def add_refed(self, o) -> None:
1324
1458
  self.ref_objects.add(o)
1325
1459
 
1326
- def is_written(self, o):
1460
+ def is_written(self, o) -> bool:
1327
1461
  return o in self.written_objects
1328
1462
 
1329
1463
  def add_written(self, o):
@@ -1332,26 +1466,26 @@ class EncodeState(object):
1332
1466
 
1333
1467
  class Decoder(ABC):
1334
1468
  @abstractmethod
1335
- def read_value(self):
1469
+ def read_value(self) -> Optional[Any]:
1336
1470
  """
1337
1471
  Consume next item
1338
1472
 
1339
1473
  Consumes the next item of any type
1340
1474
  """
1341
- pass
1475
+ raise NotImplementedError("Subclasses must implement read_value method")
1342
1476
 
1343
1477
  @abstractmethod
1344
- def read_string(self):
1478
+ def read_string(self) -> Optional[str]:
1345
1479
  """
1346
1480
  Consume the next item as a string.
1347
1481
 
1348
1482
  Returns the string value of the next item, or `None` if the next item
1349
1483
  is not a string
1350
1484
  """
1351
- pass
1485
+ raise NotImplementedError("Subclasses must implement read_string method")
1352
1486
 
1353
1487
  @abstractmethod
1354
- def read_datetime(self):
1488
+ def read_datetime(self) -> Optional[str]:
1355
1489
  """
1356
1490
  Consumes the next item as a date & time string
1357
1491
 
@@ -1362,20 +1496,20 @@ class Decoder(ABC):
1362
1496
  implementation can just check if the next item is a string without
1363
1497
  worrying about the format
1364
1498
  """
1365
- pass
1499
+ raise NotImplementedError("Subclasses must implement read_datetime method")
1366
1500
 
1367
1501
  @abstractmethod
1368
- def read_integer(self):
1502
+ def read_integer(self) -> Optional[int]:
1369
1503
  """
1370
1504
  Consumes the next item as an integer
1371
1505
 
1372
1506
  Returns the integer value of the next item, or `None` if the next item
1373
1507
  is not an integer
1374
1508
  """
1375
- pass
1509
+ raise NotImplementedError("Subclasses must implement read_integer method")
1376
1510
 
1377
1511
  @abstractmethod
1378
- def read_iri(self):
1512
+ def read_iri(self) -> Optional[str]:
1379
1513
  """
1380
1514
  Consumes the next item as an IRI string
1381
1515
 
@@ -1385,10 +1519,10 @@ class Decoder(ABC):
1385
1519
  The returned string should be either a fully-qualified IRI, or a blank
1386
1520
  node ID
1387
1521
  """
1388
- pass
1522
+ raise NotImplementedError("Subclasses must implement read_iri method")
1389
1523
 
1390
1524
  @abstractmethod
1391
- def read_enum(self, e):
1525
+ def read_enum(self, e) -> Optional[str]:
1392
1526
  """
1393
1527
  Consumes the next item as an Enum value string
1394
1528
 
@@ -1399,30 +1533,30 @@ class Decoder(ABC):
1399
1533
  actually a member of the specified Enum, so the `Decoder` does not need
1400
1534
  to check that, but can if it wishes
1401
1535
  """
1402
- pass
1536
+ raise NotImplementedError("Subclasses must implement read_enum method")
1403
1537
 
1404
1538
  @abstractmethod
1405
- def read_bool(self):
1539
+ def read_bool(self) -> Optional[bool]:
1406
1540
  """
1407
1541
  Consume the next item as a boolean value
1408
1542
 
1409
1543
  Returns the boolean value of the next item, or `None` if the next item
1410
1544
  is not a boolean
1411
1545
  """
1412
- pass
1546
+ raise NotImplementedError("Subclasses must implement read_bool method")
1413
1547
 
1414
1548
  @abstractmethod
1415
- def read_float(self):
1549
+ def read_float(self) -> Optional[float]:
1416
1550
  """
1417
1551
  Consume the next item as a float value
1418
1552
 
1419
1553
  Returns the float value of the next item, or `None` if the next item is
1420
1554
  not a float
1421
1555
  """
1422
- pass
1556
+ raise NotImplementedError("Subclasses must implement read_float method")
1423
1557
 
1424
1558
  @abstractmethod
1425
- def read_list(self):
1559
+ def read_list(self) -> Iterator["Decoder"]:
1426
1560
  """
1427
1561
  Consume the next item as a list generator
1428
1562
 
@@ -1430,19 +1564,19 @@ class Decoder(ABC):
1430
1564
  generated `Decoder` can be used to read the corresponding item from the
1431
1565
  list
1432
1566
  """
1433
- pass
1567
+ raise NotImplementedError("Subclasses must implement read_list method")
1434
1568
 
1435
1569
  @abstractmethod
1436
- def is_list(self):
1570
+ def is_list(self) -> bool:
1437
1571
  """
1438
1572
  Checks if the next item is a list
1439
1573
 
1440
1574
  Returns True if the next item is a list, or False if it is a scalar
1441
1575
  """
1442
- pass
1576
+ raise NotImplementedError("Subclasses must implement is_list method")
1443
1577
 
1444
1578
  @abstractmethod
1445
- def read_object(self):
1579
+ def read_object(self) -> Tuple[Any, "Decoder"]:
1446
1580
  """
1447
1581
  Consume next item as an object
1448
1582
 
@@ -1453,11 +1587,11 @@ class Decoder(ABC):
1453
1587
  Properties will be read out of the object using `read_property` and
1454
1588
  `read_object_id`
1455
1589
  """
1456
- pass
1590
+ raise NotImplementedError("Subclasses must implement read_object method")
1457
1591
 
1458
1592
  @abstractmethod
1459
1593
  @contextmanager
1460
- def read_property(self, key):
1594
+ def read_property(self, key) -> Iterator[Optional["Decoder"]]:
1461
1595
  """
1462
1596
  Read property from object
1463
1597
 
@@ -1465,19 +1599,28 @@ class Decoder(ABC):
1465
1599
  value of the property with the given key in current object, or `None`
1466
1600
  if the property does not exist in the current object.
1467
1601
  """
1468
- pass
1602
+ raise NotImplementedError("Subclasses must implement read_property method")
1603
+
1604
+ @abstractmethod
1605
+ def is_object(self) -> bool:
1606
+ """
1607
+ Checks if the item is an object
1608
+
1609
+ Returns True if the item is an object, or False if is not
1610
+ """
1611
+ raise NotImplementedError("Subclasses must implement is_object method")
1469
1612
 
1470
1613
  @abstractmethod
1471
- def object_keys(self):
1614
+ def object_keys(self) -> Iterator[str]:
1472
1615
  """
1473
1616
  Read property keys from an object
1474
1617
 
1475
1618
  Iterates over all the serialized keys for the current object
1476
1619
  """
1477
- pass
1620
+ raise NotImplementedError("Subclasses must implement object_keys method")
1478
1621
 
1479
1622
  @abstractmethod
1480
- def read_object_id(self, alias=None):
1623
+ def read_object_id(self, alias=None) -> Optional[Any]:
1481
1624
  """
1482
1625
  Read current object ID property
1483
1626
 
@@ -1489,15 +1632,15 @@ class Decoder(ABC):
1489
1632
  If `alias` is provided, is is a hint as to another name by which the ID
1490
1633
  might be found, if the `Decoder` supports aliases for an ID
1491
1634
  """
1492
- pass
1635
+ raise NotImplementedError("Subclasses must implement read_object_id method")
1493
1636
 
1494
1637
 
1495
1638
  class JSONLDDecoder(Decoder):
1496
- def __init__(self, data, root=False):
1639
+ def __init__(self, data, root: bool = False):
1497
1640
  self.data = data
1498
1641
  self.root = root
1499
1642
 
1500
- def read_value(self):
1643
+ def read_value(self) -> Optional[Any]:
1501
1644
  if isinstance(self.data, str):
1502
1645
  try:
1503
1646
  return float(self.data)
@@ -1505,47 +1648,47 @@ class JSONLDDecoder(Decoder):
1505
1648
  pass
1506
1649
  return self.data
1507
1650
 
1508
- def read_string(self):
1651
+ def read_string(self) -> Optional[str]:
1509
1652
  if isinstance(self.data, str):
1510
1653
  return self.data
1511
1654
  return None
1512
1655
 
1513
- def read_datetime(self):
1656
+ def read_datetime(self) -> Optional[str]:
1514
1657
  return self.read_string()
1515
1658
 
1516
- def read_integer(self):
1659
+ def read_integer(self) -> Optional[int]:
1517
1660
  if isinstance(self.data, int):
1518
1661
  return self.data
1519
1662
  return None
1520
1663
 
1521
- def read_bool(self):
1664
+ def read_bool(self) -> Optional[bool]:
1522
1665
  if isinstance(self.data, bool):
1523
1666
  return self.data
1524
1667
  return None
1525
1668
 
1526
- def read_float(self):
1669
+ def read_float(self) -> Optional[float]:
1527
1670
  if isinstance(self.data, (int, float, str)):
1528
1671
  return float(self.data)
1529
1672
  return None
1530
1673
 
1531
- def read_iri(self):
1674
+ def read_iri(self) -> Optional[str]:
1532
1675
  if isinstance(self.data, str):
1533
1676
  return self.data
1534
1677
  return None
1535
1678
 
1536
- def read_enum(self, e):
1679
+ def read_enum(self, e) -> Optional[str]:
1537
1680
  if isinstance(self.data, str):
1538
1681
  return self.data
1539
1682
  return None
1540
1683
 
1541
- def read_list(self):
1684
+ def read_list(self) -> Iterator["JSONLDDecoder"]:
1542
1685
  if self.is_list():
1543
1686
  for v in self.data:
1544
1687
  yield self.__class__(v)
1545
1688
  else:
1546
1689
  yield self
1547
1690
 
1548
- def is_list(self):
1691
+ def is_list(self) -> bool:
1549
1692
  return isinstance(self.data, (list, tuple, set))
1550
1693
 
1551
1694
  def __get_value(self, *keys):
@@ -1555,14 +1698,17 @@ class JSONLDDecoder(Decoder):
1555
1698
  return None
1556
1699
 
1557
1700
  @contextmanager
1558
- def read_property(self, key):
1701
+ def read_property(self, key) -> Iterator[Optional["JSONLDDecoder"]]:
1559
1702
  v = self.__get_value(key)
1560
1703
  if v is not None:
1561
1704
  yield self.__class__(v)
1562
1705
  else:
1563
1706
  yield None
1564
1707
 
1565
- def object_keys(self):
1708
+ def is_object(self) -> bool:
1709
+ return isinstance(self.data, dict)
1710
+
1711
+ def object_keys(self) -> Iterator[str]:
1566
1712
  for key in self.data.keys():
1567
1713
  if key in ("@type", "type"):
1568
1714
  continue
@@ -1570,19 +1716,19 @@ class JSONLDDecoder(Decoder):
1570
1716
  continue
1571
1717
  yield key
1572
1718
 
1573
- def read_object(self):
1719
+ def read_object(self) -> Tuple[Any, "JSONLDDecoder"]:
1574
1720
  typ = self.__get_value("@type", "type")
1575
1721
  if typ is not None:
1576
1722
  return typ, self
1577
1723
 
1578
1724
  return None, self
1579
1725
 
1580
- def read_object_id(self, alias=None):
1726
+ def read_object_id(self, alias=None) -> Optional[Any]:
1581
1727
  return self.__get_value(alias, "@id")
1582
1728
 
1583
1729
 
1584
1730
  class JSONLDDeserializer(object):
1585
- def deserialize_data(self, data, objectset: SHACLObjectSet):
1731
+ def deserialize_data(self, data, objectset: SHACLObjectSet) -> None:
1586
1732
  if "@graph" in data:
1587
1733
  h = JSONLDDecoder(data["@graph"], True)
1588
1734
  else:
@@ -1590,23 +1736,23 @@ class JSONLDDeserializer(object):
1590
1736
 
1591
1737
  objectset.decode(h)
1592
1738
 
1593
- def read(self, f, objectset: SHACLObjectSet):
1739
+ def read(self, f, objectset: SHACLObjectSet) -> None:
1594
1740
  data = json.load(f)
1595
1741
  self.deserialize_data(data, objectset)
1596
1742
 
1597
1743
 
1598
1744
  class Encoder(ABC):
1599
1745
  @abstractmethod
1600
- def write_string(self, v):
1746
+ def write_string(self, v) -> None:
1601
1747
  """
1602
1748
  Write a string value
1603
1749
 
1604
1750
  Encodes the value as a string in the output
1605
1751
  """
1606
- pass
1752
+ raise NotImplementedError("Subclasses must implement write_string method")
1607
1753
 
1608
1754
  @abstractmethod
1609
- def write_datetime(self, v):
1755
+ def write_datetime(self, v) -> None:
1610
1756
  """
1611
1757
  Write a date & time string
1612
1758
 
@@ -1614,19 +1760,19 @@ class Encoder(ABC):
1614
1760
 
1615
1761
  Note: The provided string is already correctly encoded as an ISO datetime
1616
1762
  """
1617
- pass
1763
+ raise NotImplementedError("Subclasses must implement write_datetime method")
1618
1764
 
1619
1765
  @abstractmethod
1620
- def write_integer(self, v):
1766
+ def write_integer(self, v) -> None:
1621
1767
  """
1622
1768
  Write an integer value
1623
1769
 
1624
1770
  Encodes the value as an integer in the output
1625
1771
  """
1626
- pass
1772
+ raise NotImplementedError("Subclasses must implement write_integer method")
1627
1773
 
1628
1774
  @abstractmethod
1629
- def write_iri(self, v, compact=None):
1775
+ def write_iri(self, v, compact=None) -> None:
1630
1776
  """
1631
1777
  Write IRI
1632
1778
 
@@ -1635,10 +1781,10 @@ class Encoder(ABC):
1635
1781
  the serialization supports compacted IRIs, it should be preferred to
1636
1782
  the full IRI
1637
1783
  """
1638
- pass
1784
+ raise NotImplementedError("Subclasses must implement write_iri method")
1639
1785
 
1640
1786
  @abstractmethod
1641
- def write_enum(self, v, e, compact=None):
1787
+ def write_enum(self, v, e, compact=None) -> None:
1642
1788
  """
1643
1789
  Write enum value IRI
1644
1790
 
@@ -1646,29 +1792,29 @@ class Encoder(ABC):
1646
1792
  qualified IRI. If `compact` is provided and the serialization supports
1647
1793
  compacted IRIs, it should be preferred to the full IRI.
1648
1794
  """
1649
- pass
1795
+ raise NotImplementedError("Subclasses must implement write_enum method")
1650
1796
 
1651
1797
  @abstractmethod
1652
- def write_bool(self, v):
1798
+ def write_bool(self, v) -> None:
1653
1799
  """
1654
1800
  Write boolean
1655
1801
 
1656
1802
  Encodes the value as a boolean in the output
1657
1803
  """
1658
- pass
1804
+ raise NotImplementedError("Subclasses must implement write_bool method")
1659
1805
 
1660
1806
  @abstractmethod
1661
- def write_float(self, v):
1807
+ def write_float(self, v) -> None:
1662
1808
  """
1663
1809
  Write float
1664
1810
 
1665
1811
  Encodes the value as a floating point number in the output
1666
1812
  """
1667
- pass
1813
+ raise NotImplementedError("Subclasses must implement write_float method")
1668
1814
 
1669
1815
  @abstractmethod
1670
1816
  @contextmanager
1671
- def write_object(self, o, _id, needs_id):
1817
+ def write_object(self, o: SHACLObject, _id: str, needs_id: bool):
1672
1818
  """
1673
1819
  Write object
1674
1820
 
@@ -1686,11 +1832,11 @@ class Encoder(ABC):
1686
1832
 
1687
1833
  Properties will be written the object using `write_property`
1688
1834
  """
1689
- pass
1835
+ raise NotImplementedError("Subclasses must implement write_object method")
1690
1836
 
1691
1837
  @abstractmethod
1692
1838
  @contextmanager
1693
- def write_property(self, iri, compact=None):
1839
+ def write_property(self, iri: str, compact: Optional[str] = None):
1694
1840
  """
1695
1841
  Write object property
1696
1842
 
@@ -1701,7 +1847,7 @@ class Encoder(ABC):
1701
1847
  the serialization supports compacted IRIs, it should be preferred to
1702
1848
  the full IRI.
1703
1849
  """
1704
- pass
1850
+ raise NotImplementedError("Subclasses must implement write_property method")
1705
1851
 
1706
1852
  @abstractmethod
1707
1853
  @contextmanager
@@ -1714,7 +1860,7 @@ class Encoder(ABC):
1714
1860
 
1715
1861
  Each item of the list will be added using `write_list_item`
1716
1862
  """
1717
- pass
1863
+ raise NotImplementedError("Subclasses must implement write_list method")
1718
1864
 
1719
1865
  @abstractmethod
1720
1866
  @contextmanager
@@ -1725,7 +1871,7 @@ class Encoder(ABC):
1725
1871
  A context manager that yields an `Encoder` that can be used to encode
1726
1872
  the value for a list item
1727
1873
  """
1728
- pass
1874
+ raise NotImplementedError("Subclasses must implement write_list_item method")
1729
1875
 
1730
1876
 
1731
1877
  class JSONLDEncoder(Encoder):
@@ -1754,14 +1900,14 @@ class JSONLDEncoder(Encoder):
1754
1900
  self.data = str(v)
1755
1901
 
1756
1902
  @contextmanager
1757
- def write_property(self, iri, compact=None):
1903
+ def write_property(self, iri: str, compact: Optional[str] = None):
1758
1904
  s = self.__class__(None)
1759
1905
  yield s
1760
1906
  if s.data is not None:
1761
- self.data[compact or iri] = s.data
1907
+ self.data[compact or iri] = s.data # type: ignore # within write_object() context, self.data is always dict or None
1762
1908
 
1763
1909
  @contextmanager
1764
- def write_object(self, o, _id, needs_id):
1910
+ def write_object(self, o: SHACLObject, _id: str, needs_id: bool):
1765
1911
  self.data = {
1766
1912
  "type": o.COMPACT_TYPE or o.TYPE,
1767
1913
  }
@@ -1781,7 +1927,7 @@ class JSONLDEncoder(Encoder):
1781
1927
  s = self.__class__(None)
1782
1928
  yield s
1783
1929
  if s.data is not None:
1784
- self.data.append(s.data)
1930
+ self.data.append(s.data) # type: ignore # within write_list() context, self.data is always list or None
1785
1931
 
1786
1932
 
1787
1933
  class JSONLDSerializer(object):
@@ -1791,11 +1937,11 @@ class JSONLDSerializer(object):
1791
1937
  def serialize_data(
1792
1938
  self,
1793
1939
  objectset: SHACLObjectSet,
1794
- force_at_graph=False,
1940
+ force_at_graph: bool = False,
1795
1941
  ):
1796
1942
  h = JSONLDEncoder()
1797
1943
  objectset.encode(h, force_at_graph)
1798
- data = {}
1944
+ data: Dict[str, Any] = {}
1799
1945
  if len(CONTEXT_URLS) == 1:
1800
1946
  data["@context"] = CONTEXT_URLS[0]
1801
1947
  elif CONTEXT_URLS:
@@ -1803,9 +1949,11 @@ class JSONLDSerializer(object):
1803
1949
 
1804
1950
  if isinstance(h.data, list):
1805
1951
  data["@graph"] = h.data
1806
- else:
1952
+ elif isinstance(h.data, dict):
1807
1953
  for k, v in h.data.items():
1808
1954
  data[k] = v
1955
+ # elif h.data is not None: # str, int, float, bool
1956
+ # data["value"] = h.data
1809
1957
 
1810
1958
  return data
1811
1959
 
@@ -1813,13 +1961,16 @@ class JSONLDSerializer(object):
1813
1961
  self,
1814
1962
  objectset: SHACLObjectSet,
1815
1963
  f,
1816
- force_at_graph=False,
1964
+ force_at_graph: bool = False,
1817
1965
  **kwargs,
1818
1966
  ):
1819
1967
  """
1820
1968
  Write a SHACLObjectSet to a JSON LD file
1821
1969
 
1822
1970
  If force_at_graph is True, a @graph node will always be written
1971
+
1972
+ Note that f should be a file-like object that supports the `write`
1973
+ method, and that opens in binary mode (e.g. `open("file.json", "wb")`).
1823
1974
  """
1824
1975
  data = self.serialize_data(objectset, force_at_graph)
1825
1976
 
@@ -1827,9 +1978,9 @@ class JSONLDSerializer(object):
1827
1978
 
1828
1979
  sha1 = hashlib.sha1()
1829
1980
  for chunk in json.JSONEncoder(**args).iterencode(data):
1830
- chunk = chunk.encode("utf-8")
1831
- f.write(chunk)
1832
- sha1.update(chunk)
1981
+ chunk_bytes = chunk.encode("utf-8")
1982
+ f.write(chunk_bytes)
1983
+ sha1.update(chunk_bytes)
1833
1984
 
1834
1985
  return sha1.hexdigest()
1835
1986
 
@@ -1875,7 +2026,7 @@ class JSONLDInlineEncoder(Encoder):
1875
2026
  self.write(json.dumps(str(v)))
1876
2027
 
1877
2028
  @contextmanager
1878
- def write_property(self, iri, compact=None):
2029
+ def write_property(self, iri: str, compact: Optional[str] = None):
1879
2030
  self._write_comma()
1880
2031
  self.write_string(compact or iri)
1881
2032
  self.write(":")
@@ -1883,7 +2034,7 @@ class JSONLDInlineEncoder(Encoder):
1883
2034
  self.comma = True
1884
2035
 
1885
2036
  @contextmanager
1886
- def write_object(self, o, _id, needs_id):
2037
+ def write_object(self, o: SHACLObject, _id: str, needs_id: bool):
1887
2038
  self._write_comma()
1888
2039
 
1889
2040
  self.write("{")
@@ -1925,7 +2076,7 @@ class JSONLDInlineSerializer(object):
1925
2076
  self,
1926
2077
  objectset: SHACLObjectSet,
1927
2078
  f,
1928
- force_at_graph=False,
2079
+ force_at_graph: bool = False,
1929
2080
  ):
1930
2081
  """
1931
2082
  Write a SHACLObjectSet to a JSON LD file
@@ -1951,13 +2102,256 @@ class JSONLDInlineSerializer(object):
1951
2102
  return sha1.hexdigest()
1952
2103
 
1953
2104
 
1954
- def print_tree(objects, all_fields=False):
2105
+ try:
2106
+ import rdflib
2107
+ import rdflib.term
2108
+ from rdflib.namespace import RDF
2109
+
2110
+ class RDFDecoder(Decoder):
2111
+ def __init__(
2112
+ self,
2113
+ graph: rdflib.Graph,
2114
+ subject: Optional[rdflib.term.Node] = None,
2115
+ predicate: Optional[rdflib.term.Node] = None,
2116
+ value: Optional[rdflib.term.Node] = None,
2117
+ ):
2118
+ self.graph = graph
2119
+ self.subject = subject
2120
+ self.predicate = predicate
2121
+ self.value = value
2122
+
2123
+ def __read_node(self):
2124
+ if self.value is not None:
2125
+ return self.value
2126
+ if self.predicate is None:
2127
+ return None
2128
+ return self.graph.value(self.subject, self.predicate)
2129
+
2130
+ def read_value(self) -> Optional[Any]:
2131
+ v = self.__read_node()
2132
+ if isinstance(v, rdflib.term.Literal):
2133
+ return v.toPython()
2134
+ return None
2135
+
2136
+ def read_string(self) -> Optional[str]:
2137
+ v = self.read_value()
2138
+ if isinstance(v, str):
2139
+ return v
2140
+ return None
2141
+
2142
+ def read_datetime(self) -> Optional[str]:
2143
+ return self.read_value()
2144
+
2145
+ def read_integer(self) -> Optional[int]:
2146
+ v = self.read_value()
2147
+ if isinstance(v, (int, decimal.Decimal)):
2148
+ return int(v)
2149
+ return None
2150
+
2151
+ def read_bool(self) -> Optional[bool]:
2152
+ v = self.read_value()
2153
+ if isinstance(v, bool):
2154
+ return v
2155
+ return None
2156
+
2157
+ def read_float(self) -> Optional[float]:
2158
+ v = self.read_value()
2159
+ if isinstance(v, (int, float, str, decimal.Decimal)):
2160
+ return float(v)
2161
+ return None
2162
+
2163
+ def read_iri(self) -> Optional[str]:
2164
+ v = self.__read_node()
2165
+ if isinstance(v, rdflib.term.URIRef):
2166
+ return v.toPython()
2167
+ elif isinstance(v, rdflib.term.Literal):
2168
+ v = v.toPython()
2169
+ if isinstance(v, str):
2170
+ return v
2171
+ elif isinstance(v, rdflib.term.BNode):
2172
+ return v.n3()
2173
+ return None
2174
+
2175
+ def read_enum(self, e) -> Optional[str]:
2176
+ v = self.__read_node()
2177
+ if isinstance(v, rdflib.term.URIRef):
2178
+ return v.toPython()
2179
+ return None
2180
+
2181
+ def read_list(self) -> Iterator["RDFDecoder"]:
2182
+ if not self.subject:
2183
+ blank_nodes = set()
2184
+ for s in self.graph.subjects(unique=True):
2185
+ # type: ignore # RDF.type is dynamic
2186
+ if (s, RDF.type, None) not in self.graph:
2187
+ continue
2188
+
2189
+ if isinstance(s, rdflib.term.BNode):
2190
+ blank_nodes.add(s)
2191
+ continue
2192
+ yield self.__class__(self.graph, s)
2193
+
2194
+ for s in blank_nodes:
2195
+ yield self.__class__(self.graph, s)
2196
+ else:
2197
+ for o in self.graph.objects(self.subject, self.predicate):
2198
+ # type: ignore # RDF.type is dynamic
2199
+ if (o, RDF.type, None) in self.graph:
2200
+ yield self.__class__(self.graph, o)
2201
+ else:
2202
+ yield self.__class__(
2203
+ self.graph,
2204
+ self.subject,
2205
+ self.predicate,
2206
+ o,
2207
+ )
2208
+
2209
+ def is_list(self) -> bool:
2210
+ if not self.subject:
2211
+ return True
2212
+ if self.value is not None:
2213
+ return False
2214
+ return len(list(self.graph.objects(self.subject, self.predicate))) > 1
2215
+
2216
+ @contextmanager
2217
+ def read_property(self, key) -> Iterator[Optional["RDFDecoder"]]:
2218
+ if key == "@id":
2219
+ yield self.__class__(self.graph, value=self.subject)
2220
+ else:
2221
+ yield self.__class__(self.graph, self.subject, rdflib.term.URIRef(key))
2222
+
2223
+ def is_object(self) -> bool:
2224
+ n = self.__read_node() or self.subject
2225
+ # type: ignore # RDF.type is dynamic
2226
+ return (n, RDF.type, None) in self.graph
2227
+
2228
+ def object_keys(self) -> Iterator[str]:
2229
+ for p in self.graph.predicates(self.subject, unique=True):
2230
+ # type: ignore # RDF.type is dynamic
2231
+ if p == RDF.type:
2232
+ continue
2233
+
2234
+ if not isinstance(p, rdflib.term.IdentifiedNode):
2235
+ raise TypeError(f"Predicate is of unknown type {type(p)}")
2236
+
2237
+ yield p.toPython()
2238
+
2239
+ def read_object(self) -> Tuple[Any, "RDFDecoder"]:
2240
+ s = self.__read_node()
2241
+ if s is None:
2242
+ s = self.subject
2243
+
2244
+ # type: ignore # RDF.type is dynamic
2245
+ typ = self.graph.value(s, RDF.type)
2246
+ if typ is None:
2247
+ return None, self
2248
+
2249
+ if not isinstance(typ, rdflib.term.IdentifiedNode):
2250
+ raise TypeError(f"Type value is of unknown type {type(typ)}")
2251
+
2252
+ return typ.toPython(), self.__class__(self.graph, s)
2253
+
2254
+ def read_object_id(self, alias=None) -> Optional[Any]:
2255
+ if isinstance(self.subject, rdflib.term.BNode):
2256
+ return self.subject.n3()
2257
+ if not isinstance(self.subject, rdflib.term.IdentifiedNode):
2258
+ raise TypeError(f"Subject is of unknown type {type(self.subject)}")
2259
+ return self.subject.toPython()
2260
+
2261
+ class RDFDeserializer(object):
2262
+ def read(self, graph: rdflib.Graph, objset: SHACLObjectSet) -> None:
2263
+ d = RDFDecoder(graph)
2264
+ objset.decode(d)
2265
+ objset.inline_blank_nodes()
2266
+
2267
+ class RDFEncoder(Encoder):
2268
+ def __init__(
2269
+ self,
2270
+ graph: rdflib.Graph,
2271
+ subject: Optional[rdflib.term.Node] = None,
2272
+ predicate: Optional[rdflib.term.Node] = None,
2273
+ ):
2274
+ self.graph = graph
2275
+ self.subject = subject
2276
+ self.predicate = predicate
2277
+
2278
+ def __add_literal(self, v):
2279
+ if self.subject is None or self.predicate is None:
2280
+ raise TypeError()
2281
+ self.graph.add((self.subject, self.predicate, rdflib.Literal(v)))
2282
+
2283
+ def __add_uriref(self, v):
2284
+ if self.subject is None or self.predicate is None:
2285
+ raise TypeError()
2286
+ self.graph.add((self.subject, self.predicate, rdflib.URIRef(v)))
2287
+
2288
+ def write_string(self, v):
2289
+ self.__add_literal(v)
2290
+
2291
+ def write_datetime(self, v):
2292
+ self.__add_literal(v)
2293
+
2294
+ def write_integer(self, v):
2295
+ self.__add_literal(v)
2296
+
2297
+ def write_iri(self, v, compact=None):
2298
+ self.__add_uriref(v)
2299
+
2300
+ def write_enum(self, v, e, compact=None):
2301
+ self.__add_uriref(v)
2302
+
2303
+ def write_bool(self, v):
2304
+ self.__add_literal(v)
2305
+
2306
+ def write_float(self, v):
2307
+ self.__add_literal(v)
2308
+
2309
+ @contextmanager
2310
+ def write_property(self, iri: str, compact: Optional[str] = None):
2311
+ yield self.__class__(self.graph, self.subject, rdflib.URIRef(iri))
2312
+
2313
+ @contextmanager
2314
+ def write_object(self, o, _id, needs_id: bool):
2315
+ obj: rdflib.term.Node
2316
+ if _id.startswith("_:"):
2317
+ obj = rdflib.BNode(_id[2:])
2318
+ else:
2319
+ obj = rdflib.URIRef(_id)
2320
+
2321
+ if self.subject is not None:
2322
+ if self.predicate is None:
2323
+ raise TypeError()
2324
+ self.graph.add((self.subject, self.predicate, obj))
2325
+ self.graph.add((obj, RDF.type, rdflib.URIRef(o.TYPE))) # type: ignore # RDF.type is dynamic
2326
+ yield self.__class__(self.graph, obj)
2327
+
2328
+ @contextmanager
2329
+ def write_list(self):
2330
+ yield self
2331
+
2332
+ @contextmanager
2333
+ def write_list_item(self):
2334
+ yield self
2335
+
2336
+ class RDFSerializer(object):
2337
+ def write(self, objset: SHACLObjectSet, g: rdflib.Graph):
2338
+ """
2339
+ Write a SHACLObjectSet to an RDF graph
2340
+ """
2341
+ e = RDFEncoder(g)
2342
+ objset.encode(e)
2343
+
2344
+ except ImportError:
2345
+ pass
2346
+
2347
+
2348
+ def print_tree(objects, all_fields: bool = False) -> None:
1955
2349
  """
1956
2350
  Print object tree
1957
2351
  """
1958
2352
  seen = set()
1959
2353
 
1960
- def callback(value, path):
2354
+ def callback(value, path: List[str]):
1961
2355
  nonlocal seen
1962
2356
 
1963
2357
  s = (" " * (len(path) - 1)) + f"{path[-1]}"
@@ -1991,7 +2385,7 @@ def print_tree(objects, all_fields=False):
1991
2385
  """Format Guard"""
1992
2386
 
1993
2387
 
1994
- CONTEXT_URLS = [
2388
+ CONTEXT_URLS: List[str] = [
1995
2389
  "https://spdx.org/rdf/3.0.1/spdx-context.jsonld",
1996
2390
  ]
1997
2391
 
@@ -2003,7 +2397,7 @@ CONTEXT_URLS = [
2003
2397
  class ai_EnergyConsumption(SHACLObject):
2004
2398
  NODE_KIND = NodeKind.BlankNodeOrIRI
2005
2399
  IS_DEPRECATED = False
2006
- NAMED_INDIVIDUALS = {
2400
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2007
2401
  }
2008
2402
 
2009
2403
  @classmethod
@@ -2044,7 +2438,7 @@ class ai_EnergyConsumption(SHACLObject):
2044
2438
  class ai_EnergyConsumptionDescription(SHACLObject):
2045
2439
  NODE_KIND = NodeKind.BlankNodeOrIRI
2046
2440
  IS_DEPRECATED = False
2047
- NAMED_INDIVIDUALS = {
2441
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2048
2442
  }
2049
2443
 
2050
2444
  @classmethod
@@ -2079,7 +2473,7 @@ class ai_EnergyConsumptionDescription(SHACLObject):
2079
2473
  class ai_EnergyUnitType(SHACLObject):
2080
2474
  NODE_KIND = NodeKind.BlankNodeOrIRI
2081
2475
  IS_DEPRECATED = False
2082
- NAMED_INDIVIDUALS = {
2476
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2083
2477
  "kilowattHour": "https://spdx.org/rdf/3.0.1/terms/AI/EnergyUnitType/kilowattHour",
2084
2478
  "megajoule": "https://spdx.org/rdf/3.0.1/terms/AI/EnergyUnitType/megajoule",
2085
2479
  "other": "https://spdx.org/rdf/3.0.1/terms/AI/EnergyUnitType/other",
@@ -2097,7 +2491,7 @@ class ai_EnergyUnitType(SHACLObject):
2097
2491
  class ai_SafetyRiskAssessmentType(SHACLObject):
2098
2492
  NODE_KIND = NodeKind.BlankNodeOrIRI
2099
2493
  IS_DEPRECATED = False
2100
- NAMED_INDIVIDUALS = {
2494
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2101
2495
  "high": "https://spdx.org/rdf/3.0.1/terms/AI/SafetyRiskAssessmentType/high",
2102
2496
  "low": "https://spdx.org/rdf/3.0.1/terms/AI/SafetyRiskAssessmentType/low",
2103
2497
  "medium": "https://spdx.org/rdf/3.0.1/terms/AI/SafetyRiskAssessmentType/medium",
@@ -2118,7 +2512,7 @@ class ai_SafetyRiskAssessmentType(SHACLObject):
2118
2512
  class AnnotationType(SHACLObject):
2119
2513
  NODE_KIND = NodeKind.BlankNodeOrIRI
2120
2514
  IS_DEPRECATED = False
2121
- NAMED_INDIVIDUALS = {
2515
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2122
2516
  "other": "https://spdx.org/rdf/3.0.1/terms/Core/AnnotationType/other",
2123
2517
  "review": "https://spdx.org/rdf/3.0.1/terms/Core/AnnotationType/review",
2124
2518
  }
@@ -2133,7 +2527,7 @@ class AnnotationType(SHACLObject):
2133
2527
  class CreationInfo(SHACLObject):
2134
2528
  NODE_KIND = NodeKind.BlankNodeOrIRI
2135
2529
  IS_DEPRECATED = False
2136
- NAMED_INDIVIDUALS = {
2530
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2137
2531
  }
2138
2532
 
2139
2533
  @classmethod
@@ -2193,7 +2587,7 @@ class CreationInfo(SHACLObject):
2193
2587
  class DictionaryEntry(SHACLObject):
2194
2588
  NODE_KIND = NodeKind.BlankNodeOrIRI
2195
2589
  IS_DEPRECATED = False
2196
- NAMED_INDIVIDUALS = {
2590
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2197
2591
  }
2198
2592
 
2199
2593
  @classmethod
@@ -2224,7 +2618,7 @@ class Element(SHACLObject):
2224
2618
  NODE_KIND = NodeKind.IRI
2225
2619
  ID_ALIAS = "spdxId"
2226
2620
  IS_DEPRECATED = False
2227
- NAMED_INDIVIDUALS = {
2621
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2228
2622
  }
2229
2623
 
2230
2624
  @classmethod
@@ -2315,7 +2709,7 @@ class ElementCollection(Element):
2315
2709
  NODE_KIND = NodeKind.IRI
2316
2710
  ID_ALIAS = "spdxId"
2317
2711
  IS_DEPRECATED = False
2318
- NAMED_INDIVIDUALS = {
2712
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2319
2713
  }
2320
2714
 
2321
2715
  @classmethod
@@ -2376,7 +2770,7 @@ class ElementCollection(Element):
2376
2770
  class ExternalIdentifier(SHACLObject):
2377
2771
  NODE_KIND = NodeKind.BlankNodeOrIRI
2378
2772
  IS_DEPRECATED = False
2379
- NAMED_INDIVIDUALS = {
2773
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2380
2774
  }
2381
2775
 
2382
2776
  @classmethod
@@ -2444,7 +2838,7 @@ class ExternalIdentifier(SHACLObject):
2444
2838
  class ExternalIdentifierType(SHACLObject):
2445
2839
  NODE_KIND = NodeKind.BlankNodeOrIRI
2446
2840
  IS_DEPRECATED = False
2447
- NAMED_INDIVIDUALS = {
2841
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2448
2842
  "cpe22": "https://spdx.org/rdf/3.0.1/terms/Core/ExternalIdentifierType/cpe22",
2449
2843
  "cpe23": "https://spdx.org/rdf/3.0.1/terms/Core/ExternalIdentifierType/cpe23",
2450
2844
  "cve": "https://spdx.org/rdf/3.0.1/terms/Core/ExternalIdentifierType/cve",
@@ -2487,7 +2881,7 @@ class ExternalIdentifierType(SHACLObject):
2487
2881
  class ExternalMap(SHACLObject):
2488
2882
  NODE_KIND = NodeKind.BlankNodeOrIRI
2489
2883
  IS_DEPRECATED = False
2490
- NAMED_INDIVIDUALS = {
2884
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2491
2885
  }
2492
2886
 
2493
2887
  @classmethod
@@ -2536,7 +2930,7 @@ class ExternalMap(SHACLObject):
2536
2930
  class ExternalRef(SHACLObject):
2537
2931
  NODE_KIND = NodeKind.BlankNodeOrIRI
2538
2932
  IS_DEPRECATED = False
2539
- NAMED_INDIVIDUALS = {
2933
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2540
2934
  }
2541
2935
 
2542
2936
  @classmethod
@@ -2629,7 +3023,7 @@ class ExternalRef(SHACLObject):
2629
3023
  class ExternalRefType(SHACLObject):
2630
3024
  NODE_KIND = NodeKind.BlankNodeOrIRI
2631
3025
  IS_DEPRECATED = False
2632
- NAMED_INDIVIDUALS = {
3026
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2633
3027
  "altDownloadLocation": "https://spdx.org/rdf/3.0.1/terms/Core/ExternalRefType/altDownloadLocation",
2634
3028
  "altWebPage": "https://spdx.org/rdf/3.0.1/terms/Core/ExternalRefType/altWebPage",
2635
3029
  "binaryArtifact": "https://spdx.org/rdf/3.0.1/terms/Core/ExternalRefType/binaryArtifact",
@@ -2776,7 +3170,7 @@ class ExternalRefType(SHACLObject):
2776
3170
  class HashAlgorithm(SHACLObject):
2777
3171
  NODE_KIND = NodeKind.BlankNodeOrIRI
2778
3172
  IS_DEPRECATED = False
2779
- NAMED_INDIVIDUALS = {
3173
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2780
3174
  "adler32": "https://spdx.org/rdf/3.0.1/terms/Core/HashAlgorithm/adler32",
2781
3175
  "blake2b256": "https://spdx.org/rdf/3.0.1/terms/Core/HashAlgorithm/blake2b256",
2782
3176
  "blake2b384": "https://spdx.org/rdf/3.0.1/terms/Core/HashAlgorithm/blake2b384",
@@ -2853,7 +3247,7 @@ class IndividualElement(Element):
2853
3247
  NODE_KIND = NodeKind.IRI
2854
3248
  ID_ALIAS = "spdxId"
2855
3249
  IS_DEPRECATED = False
2856
- NAMED_INDIVIDUALS = {
3250
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2857
3251
  "NoAssertionElement": "https://spdx.org/rdf/3.0.1/terms/Core/NoAssertionElement",
2858
3252
  "NoneElement": "https://spdx.org/rdf/3.0.1/terms/Core/NoneElement",
2859
3253
  }
@@ -2870,7 +3264,7 @@ class IndividualElement(Element):
2870
3264
  class IntegrityMethod(SHACLObject):
2871
3265
  NODE_KIND = NodeKind.BlankNodeOrIRI
2872
3266
  IS_DEPRECATED = False
2873
- NAMED_INDIVIDUALS = {
3267
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2874
3268
  }
2875
3269
 
2876
3270
  @classmethod
@@ -2892,7 +3286,7 @@ class IntegrityMethod(SHACLObject):
2892
3286
  class LifecycleScopeType(SHACLObject):
2893
3287
  NODE_KIND = NodeKind.BlankNodeOrIRI
2894
3288
  IS_DEPRECATED = False
2895
- NAMED_INDIVIDUALS = {
3289
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2896
3290
  "build": "https://spdx.org/rdf/3.0.1/terms/Core/LifecycleScopeType/build",
2897
3291
  "design": "https://spdx.org/rdf/3.0.1/terms/Core/LifecycleScopeType/design",
2898
3292
  "development": "https://spdx.org/rdf/3.0.1/terms/Core/LifecycleScopeType/development",
@@ -2919,7 +3313,7 @@ class LifecycleScopeType(SHACLObject):
2919
3313
  class NamespaceMap(SHACLObject):
2920
3314
  NODE_KIND = NodeKind.BlankNodeOrIRI
2921
3315
  IS_DEPRECATED = False
2922
- NAMED_INDIVIDUALS = {
3316
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2923
3317
  }
2924
3318
 
2925
3319
  @classmethod
@@ -2951,7 +3345,7 @@ class NamespaceMap(SHACLObject):
2951
3345
  class PackageVerificationCode(IntegrityMethod):
2952
3346
  NODE_KIND = NodeKind.BlankNodeOrIRI
2953
3347
  IS_DEPRECATED = False
2954
- NAMED_INDIVIDUALS = {
3348
+ NAMED_INDIVIDUALS: Dict[str, str] = {
2955
3349
  }
2956
3350
 
2957
3351
  @classmethod
@@ -3014,7 +3408,7 @@ class PackageVerificationCode(IntegrityMethod):
3014
3408
  class PositiveIntegerRange(SHACLObject):
3015
3409
  NODE_KIND = NodeKind.BlankNodeOrIRI
3016
3410
  IS_DEPRECATED = False
3017
- NAMED_INDIVIDUALS = {
3411
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3018
3412
  }
3019
3413
 
3020
3414
  @classmethod
@@ -3045,7 +3439,7 @@ class PositiveIntegerRange(SHACLObject):
3045
3439
  class PresenceType(SHACLObject):
3046
3440
  NODE_KIND = NodeKind.BlankNodeOrIRI
3047
3441
  IS_DEPRECATED = False
3048
- NAMED_INDIVIDUALS = {
3442
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3049
3443
  "no": "https://spdx.org/rdf/3.0.1/terms/Core/PresenceType/no",
3050
3444
  "noAssertion": "https://spdx.org/rdf/3.0.1/terms/Core/PresenceType/noAssertion",
3051
3445
  "yes": "https://spdx.org/rdf/3.0.1/terms/Core/PresenceType/yes",
@@ -3063,7 +3457,7 @@ class PresenceType(SHACLObject):
3063
3457
  class ProfileIdentifierType(SHACLObject):
3064
3458
  NODE_KIND = NodeKind.BlankNodeOrIRI
3065
3459
  IS_DEPRECATED = False
3066
- NAMED_INDIVIDUALS = {
3460
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3067
3461
  "ai": "https://spdx.org/rdf/3.0.1/terms/Core/ProfileIdentifierType/ai",
3068
3462
  "build": "https://spdx.org/rdf/3.0.1/terms/Core/ProfileIdentifierType/build",
3069
3463
  "core": "https://spdx.org/rdf/3.0.1/terms/Core/ProfileIdentifierType/core",
@@ -3103,7 +3497,7 @@ class Relationship(Element):
3103
3497
  NODE_KIND = NodeKind.IRI
3104
3498
  ID_ALIAS = "spdxId"
3105
3499
  IS_DEPRECATED = False
3106
- NAMED_INDIVIDUALS = {
3500
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3107
3501
  }
3108
3502
 
3109
3503
  @classmethod
@@ -3243,7 +3637,7 @@ class Relationship(Element):
3243
3637
  class RelationshipCompleteness(SHACLObject):
3244
3638
  NODE_KIND = NodeKind.BlankNodeOrIRI
3245
3639
  IS_DEPRECATED = False
3246
- NAMED_INDIVIDUALS = {
3640
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3247
3641
  "complete": "https://spdx.org/rdf/3.0.1/terms/Core/RelationshipCompleteness/complete",
3248
3642
  "incomplete": "https://spdx.org/rdf/3.0.1/terms/Core/RelationshipCompleteness/incomplete",
3249
3643
  "noAssertion": "https://spdx.org/rdf/3.0.1/terms/Core/RelationshipCompleteness/noAssertion",
@@ -3261,7 +3655,7 @@ class RelationshipCompleteness(SHACLObject):
3261
3655
  class RelationshipType(SHACLObject):
3262
3656
  NODE_KIND = NodeKind.BlankNodeOrIRI
3263
3657
  IS_DEPRECATED = False
3264
- NAMED_INDIVIDUALS = {
3658
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3265
3659
  "affects": "https://spdx.org/rdf/3.0.1/terms/Core/RelationshipType/affects",
3266
3660
  "amendedBy": "https://spdx.org/rdf/3.0.1/terms/Core/RelationshipType/amendedBy",
3267
3661
  "ancestorOf": "https://spdx.org/rdf/3.0.1/terms/Core/RelationshipType/ancestorOf",
@@ -3448,7 +3842,7 @@ class SpdxDocument(ElementCollection):
3448
3842
  NODE_KIND = NodeKind.IRI
3449
3843
  ID_ALIAS = "spdxId"
3450
3844
  IS_DEPRECATED = False
3451
- NAMED_INDIVIDUALS = {
3845
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3452
3846
  }
3453
3847
 
3454
3848
  @classmethod
@@ -3489,7 +3883,7 @@ class SpdxDocument(ElementCollection):
3489
3883
  class SupportType(SHACLObject):
3490
3884
  NODE_KIND = NodeKind.BlankNodeOrIRI
3491
3885
  IS_DEPRECATED = False
3492
- NAMED_INDIVIDUALS = {
3886
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3493
3887
  "deployed": "https://spdx.org/rdf/3.0.1/terms/Core/SupportType/deployed",
3494
3888
  "development": "https://spdx.org/rdf/3.0.1/terms/Core/SupportType/development",
3495
3889
  "endOfSupport": "https://spdx.org/rdf/3.0.1/terms/Core/SupportType/endOfSupport",
@@ -3520,7 +3914,7 @@ class Tool(Element):
3520
3914
  NODE_KIND = NodeKind.IRI
3521
3915
  ID_ALIAS = "spdxId"
3522
3916
  IS_DEPRECATED = False
3523
- NAMED_INDIVIDUALS = {
3917
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3524
3918
  }
3525
3919
 
3526
3920
 
@@ -3529,7 +3923,7 @@ class Tool(Element):
3529
3923
  class dataset_ConfidentialityLevelType(SHACLObject):
3530
3924
  NODE_KIND = NodeKind.BlankNodeOrIRI
3531
3925
  IS_DEPRECATED = False
3532
- NAMED_INDIVIDUALS = {
3926
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3533
3927
  "amber": "https://spdx.org/rdf/3.0.1/terms/Dataset/ConfidentialityLevelType/amber",
3534
3928
  "clear": "https://spdx.org/rdf/3.0.1/terms/Dataset/ConfidentialityLevelType/clear",
3535
3929
  "green": "https://spdx.org/rdf/3.0.1/terms/Dataset/ConfidentialityLevelType/green",
@@ -3550,7 +3944,7 @@ class dataset_ConfidentialityLevelType(SHACLObject):
3550
3944
  class dataset_DatasetAvailabilityType(SHACLObject):
3551
3945
  NODE_KIND = NodeKind.BlankNodeOrIRI
3552
3946
  IS_DEPRECATED = False
3553
- NAMED_INDIVIDUALS = {
3947
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3554
3948
  "clickthrough": "https://spdx.org/rdf/3.0.1/terms/Dataset/DatasetAvailabilityType/clickthrough",
3555
3949
  "directDownload": "https://spdx.org/rdf/3.0.1/terms/Dataset/DatasetAvailabilityType/directDownload",
3556
3950
  "query": "https://spdx.org/rdf/3.0.1/terms/Dataset/DatasetAvailabilityType/query",
@@ -3574,7 +3968,7 @@ class dataset_DatasetAvailabilityType(SHACLObject):
3574
3968
  class dataset_DatasetType(SHACLObject):
3575
3969
  NODE_KIND = NodeKind.BlankNodeOrIRI
3576
3970
  IS_DEPRECATED = False
3577
- NAMED_INDIVIDUALS = {
3971
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3578
3972
  "audio": "https://spdx.org/rdf/3.0.1/terms/Dataset/DatasetType/audio",
3579
3973
  "categorical": "https://spdx.org/rdf/3.0.1/terms/Dataset/DatasetType/categorical",
3580
3974
  "graph": "https://spdx.org/rdf/3.0.1/terms/Dataset/DatasetType/graph",
@@ -3627,7 +4021,7 @@ class expandedlicensing_LicenseAddition(Element):
3627
4021
  NODE_KIND = NodeKind.IRI
3628
4022
  ID_ALIAS = "spdxId"
3629
4023
  IS_DEPRECATED = False
3630
- NAMED_INDIVIDUALS = {
4024
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3631
4025
  }
3632
4026
 
3633
4027
  @classmethod
@@ -3692,7 +4086,7 @@ class expandedlicensing_ListedLicenseException(expandedlicensing_LicenseAddition
3692
4086
  NODE_KIND = NodeKind.IRI
3693
4087
  ID_ALIAS = "spdxId"
3694
4088
  IS_DEPRECATED = False
3695
- NAMED_INDIVIDUALS = {
4089
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3696
4090
  }
3697
4091
 
3698
4092
  @classmethod
@@ -3723,7 +4117,7 @@ class expandedlicensing_ListedLicenseException(expandedlicensing_LicenseAddition
3723
4117
  class extension_CdxPropertyEntry(SHACLObject):
3724
4118
  NODE_KIND = NodeKind.BlankNodeOrIRI
3725
4119
  IS_DEPRECATED = False
3726
- NAMED_INDIVIDUALS = {
4120
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3727
4121
  }
3728
4122
 
3729
4123
  @classmethod
@@ -3753,7 +4147,7 @@ class extension_CdxPropertyEntry(SHACLObject):
3753
4147
  class extension_Extension(SHACLExtensibleObject, SHACLObject):
3754
4148
  NODE_KIND = NodeKind.BlankNodeOrIRI
3755
4149
  IS_DEPRECATED = False
3756
- NAMED_INDIVIDUALS = {
4150
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3757
4151
  }
3758
4152
 
3759
4153
 
@@ -3762,7 +4156,7 @@ class extension_Extension(SHACLExtensibleObject, SHACLObject):
3762
4156
  class security_CvssSeverityType(SHACLObject):
3763
4157
  NODE_KIND = NodeKind.BlankNodeOrIRI
3764
4158
  IS_DEPRECATED = False
3765
- NAMED_INDIVIDUALS = {
4159
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3766
4160
  "critical": "https://spdx.org/rdf/3.0.1/terms/Security/CvssSeverityType/critical",
3767
4161
  "high": "https://spdx.org/rdf/3.0.1/terms/Security/CvssSeverityType/high",
3768
4162
  "low": "https://spdx.org/rdf/3.0.1/terms/Security/CvssSeverityType/low",
@@ -3786,7 +4180,7 @@ class security_CvssSeverityType(SHACLObject):
3786
4180
  class security_ExploitCatalogType(SHACLObject):
3787
4181
  NODE_KIND = NodeKind.BlankNodeOrIRI
3788
4182
  IS_DEPRECATED = False
3789
- NAMED_INDIVIDUALS = {
4183
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3790
4184
  "kev": "https://spdx.org/rdf/3.0.1/terms/Security/ExploitCatalogType/kev",
3791
4185
  "other": "https://spdx.org/rdf/3.0.1/terms/Security/ExploitCatalogType/other",
3792
4186
  }
@@ -3801,7 +4195,7 @@ class security_ExploitCatalogType(SHACLObject):
3801
4195
  class security_SsvcDecisionType(SHACLObject):
3802
4196
  NODE_KIND = NodeKind.BlankNodeOrIRI
3803
4197
  IS_DEPRECATED = False
3804
- NAMED_INDIVIDUALS = {
4198
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3805
4199
  "act": "https://spdx.org/rdf/3.0.1/terms/Security/SsvcDecisionType/act",
3806
4200
  "attend": "https://spdx.org/rdf/3.0.1/terms/Security/SsvcDecisionType/attend",
3807
4201
  "track": "https://spdx.org/rdf/3.0.1/terms/Security/SsvcDecisionType/track",
@@ -3822,7 +4216,7 @@ class security_SsvcDecisionType(SHACLObject):
3822
4216
  class security_VexJustificationType(SHACLObject):
3823
4217
  NODE_KIND = NodeKind.BlankNodeOrIRI
3824
4218
  IS_DEPRECATED = False
3825
- NAMED_INDIVIDUALS = {
4219
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3826
4220
  "componentNotPresent": "https://spdx.org/rdf/3.0.1/terms/Security/VexJustificationType/componentNotPresent",
3827
4221
  "inlineMitigationsAlreadyExist": "https://spdx.org/rdf/3.0.1/terms/Security/VexJustificationType/inlineMitigationsAlreadyExist",
3828
4222
  "vulnerableCodeCannotBeControlledByAdversary": "https://spdx.org/rdf/3.0.1/terms/Security/VexJustificationType/vulnerableCodeCannotBeControlledByAdversary",
@@ -3847,7 +4241,7 @@ class security_VulnAssessmentRelationship(Relationship):
3847
4241
  NODE_KIND = NodeKind.IRI
3848
4242
  ID_ALIAS = "spdxId"
3849
4243
  IS_DEPRECATED = False
3850
- NAMED_INDIVIDUALS = {
4244
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3851
4245
  }
3852
4246
 
3853
4247
  @classmethod
@@ -3905,7 +4299,7 @@ class simplelicensing_AnyLicenseInfo(Element):
3905
4299
  NODE_KIND = NodeKind.IRI
3906
4300
  ID_ALIAS = "spdxId"
3907
4301
  IS_DEPRECATED = False
3908
- NAMED_INDIVIDUALS = {
4302
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3909
4303
  }
3910
4304
 
3911
4305
 
@@ -3915,7 +4309,7 @@ class simplelicensing_LicenseExpression(simplelicensing_AnyLicenseInfo):
3915
4309
  NODE_KIND = NodeKind.IRI
3916
4310
  ID_ALIAS = "spdxId"
3917
4311
  IS_DEPRECATED = False
3918
- NAMED_INDIVIDUALS = {
4312
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3919
4313
  }
3920
4314
 
3921
4315
  @classmethod
@@ -3955,7 +4349,7 @@ class simplelicensing_SimpleLicensingText(Element):
3955
4349
  NODE_KIND = NodeKind.IRI
3956
4350
  ID_ALIAS = "spdxId"
3957
4351
  IS_DEPRECATED = False
3958
- NAMED_INDIVIDUALS = {
4352
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3959
4353
  }
3960
4354
 
3961
4355
  @classmethod
@@ -3977,7 +4371,7 @@ class simplelicensing_SimpleLicensingText(Element):
3977
4371
  class software_ContentIdentifier(IntegrityMethod):
3978
4372
  NODE_KIND = NodeKind.BlankNodeOrIRI
3979
4373
  IS_DEPRECATED = False
3980
- NAMED_INDIVIDUALS = {
4374
+ NAMED_INDIVIDUALS: Dict[str, str] = {
3981
4375
  }
3982
4376
 
3983
4377
  @classmethod
@@ -4011,7 +4405,7 @@ class software_ContentIdentifier(IntegrityMethod):
4011
4405
  class software_ContentIdentifierType(SHACLObject):
4012
4406
  NODE_KIND = NodeKind.BlankNodeOrIRI
4013
4407
  IS_DEPRECATED = False
4014
- NAMED_INDIVIDUALS = {
4408
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4015
4409
  "gitoid": "https://spdx.org/rdf/3.0.1/terms/Software/ContentIdentifierType/gitoid",
4016
4410
  "swhid": "https://spdx.org/rdf/3.0.1/terms/Software/ContentIdentifierType/swhid",
4017
4411
  }
@@ -4026,7 +4420,7 @@ class software_ContentIdentifierType(SHACLObject):
4026
4420
  class software_FileKindType(SHACLObject):
4027
4421
  NODE_KIND = NodeKind.BlankNodeOrIRI
4028
4422
  IS_DEPRECATED = False
4029
- NAMED_INDIVIDUALS = {
4423
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4030
4424
  "directory": "https://spdx.org/rdf/3.0.1/terms/Software/FileKindType/directory",
4031
4425
  "file": "https://spdx.org/rdf/3.0.1/terms/Software/FileKindType/file",
4032
4426
  }
@@ -4042,7 +4436,7 @@ class software_FileKindType(SHACLObject):
4042
4436
  class software_SbomType(SHACLObject):
4043
4437
  NODE_KIND = NodeKind.BlankNodeOrIRI
4044
4438
  IS_DEPRECATED = False
4045
- NAMED_INDIVIDUALS = {
4439
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4046
4440
  "analyzed": "https://spdx.org/rdf/3.0.1/terms/Software/SbomType/analyzed",
4047
4441
  "build": "https://spdx.org/rdf/3.0.1/terms/Software/SbomType/build",
4048
4442
  "deployed": "https://spdx.org/rdf/3.0.1/terms/Software/SbomType/deployed",
@@ -4069,7 +4463,7 @@ class software_SbomType(SHACLObject):
4069
4463
  class software_SoftwarePurpose(SHACLObject):
4070
4464
  NODE_KIND = NodeKind.BlankNodeOrIRI
4071
4465
  IS_DEPRECATED = False
4072
- NAMED_INDIVIDUALS = {
4466
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4073
4467
  "application": "https://spdx.org/rdf/3.0.1/terms/Software/SoftwarePurpose/application",
4074
4468
  "archive": "https://spdx.org/rdf/3.0.1/terms/Software/SoftwarePurpose/archive",
4075
4469
  "bom": "https://spdx.org/rdf/3.0.1/terms/Software/SoftwarePurpose/bom",
@@ -4166,7 +4560,7 @@ class build_Build(Element):
4166
4560
  NODE_KIND = NodeKind.IRI
4167
4561
  ID_ALIAS = "spdxId"
4168
4562
  IS_DEPRECATED = False
4169
- NAMED_INDIVIDUALS = {
4563
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4170
4564
  }
4171
4565
 
4172
4566
  @classmethod
@@ -4256,7 +4650,7 @@ class Agent(Element):
4256
4650
  NODE_KIND = NodeKind.IRI
4257
4651
  ID_ALIAS = "spdxId"
4258
4652
  IS_DEPRECATED = False
4259
- NAMED_INDIVIDUALS = {
4653
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4260
4654
  }
4261
4655
 
4262
4656
 
@@ -4266,7 +4660,7 @@ class Annotation(Element):
4266
4660
  NODE_KIND = NodeKind.IRI
4267
4661
  ID_ALIAS = "spdxId"
4268
4662
  IS_DEPRECATED = False
4269
- NAMED_INDIVIDUALS = {
4663
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4270
4664
  }
4271
4665
 
4272
4666
  @classmethod
@@ -4323,7 +4717,7 @@ class Artifact(Element):
4323
4717
  NODE_KIND = NodeKind.IRI
4324
4718
  ID_ALIAS = "spdxId"
4325
4719
  IS_DEPRECATED = False
4326
- NAMED_INDIVIDUALS = {
4720
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4327
4721
  }
4328
4722
 
4329
4723
  @classmethod
@@ -4407,7 +4801,7 @@ class Bundle(ElementCollection):
4407
4801
  NODE_KIND = NodeKind.IRI
4408
4802
  ID_ALIAS = "spdxId"
4409
4803
  IS_DEPRECATED = False
4410
- NAMED_INDIVIDUALS = {
4804
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4411
4805
  }
4412
4806
 
4413
4807
  @classmethod
@@ -4429,7 +4823,7 @@ class Bundle(ElementCollection):
4429
4823
  class Hash(IntegrityMethod):
4430
4824
  NODE_KIND = NodeKind.BlankNodeOrIRI
4431
4825
  IS_DEPRECATED = False
4432
- NAMED_INDIVIDUALS = {
4826
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4433
4827
  }
4434
4828
 
4435
4829
  @classmethod
@@ -4484,7 +4878,7 @@ class LifecycleScopedRelationship(Relationship):
4484
4878
  NODE_KIND = NodeKind.IRI
4485
4879
  ID_ALIAS = "spdxId"
4486
4880
  IS_DEPRECATED = False
4487
- NAMED_INDIVIDUALS = {
4881
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4488
4882
  }
4489
4883
 
4490
4884
  @classmethod
@@ -4513,7 +4907,7 @@ class Organization(Agent):
4513
4907
  NODE_KIND = NodeKind.IRI
4514
4908
  ID_ALIAS = "spdxId"
4515
4909
  IS_DEPRECATED = False
4516
- NAMED_INDIVIDUALS = {
4910
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4517
4911
  "SpdxOrganization": "https://spdx.org/rdf/3.0.1/terms/Core/SpdxOrganization",
4518
4912
  }
4519
4913
  # An Organization representing the SPDX Project.
@@ -4526,7 +4920,7 @@ class Person(Agent):
4526
4920
  NODE_KIND = NodeKind.IRI
4527
4921
  ID_ALIAS = "spdxId"
4528
4922
  IS_DEPRECATED = False
4529
- NAMED_INDIVIDUALS = {
4923
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4530
4924
  }
4531
4925
 
4532
4926
 
@@ -4536,7 +4930,7 @@ class SoftwareAgent(Agent):
4536
4930
  NODE_KIND = NodeKind.IRI
4537
4931
  ID_ALIAS = "spdxId"
4538
4932
  IS_DEPRECATED = False
4539
- NAMED_INDIVIDUALS = {
4933
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4540
4934
  }
4541
4935
 
4542
4936
 
@@ -4547,7 +4941,7 @@ class expandedlicensing_ConjunctiveLicenseSet(simplelicensing_AnyLicenseInfo):
4547
4941
  NODE_KIND = NodeKind.IRI
4548
4942
  ID_ALIAS = "spdxId"
4549
4943
  IS_DEPRECATED = False
4550
- NAMED_INDIVIDUALS = {
4944
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4551
4945
  }
4552
4946
 
4553
4947
  @classmethod
@@ -4573,7 +4967,7 @@ class expandedlicensing_CustomLicenseAddition(expandedlicensing_LicenseAddition)
4573
4967
  NODE_KIND = NodeKind.IRI
4574
4968
  ID_ALIAS = "spdxId"
4575
4969
  IS_DEPRECATED = False
4576
- NAMED_INDIVIDUALS = {
4970
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4577
4971
  }
4578
4972
 
4579
4973
 
@@ -4584,7 +4978,7 @@ class expandedlicensing_DisjunctiveLicenseSet(simplelicensing_AnyLicenseInfo):
4584
4978
  NODE_KIND = NodeKind.IRI
4585
4979
  ID_ALIAS = "spdxId"
4586
4980
  IS_DEPRECATED = False
4587
- NAMED_INDIVIDUALS = {
4981
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4588
4982
  }
4589
4983
 
4590
4984
  @classmethod
@@ -4610,7 +5004,7 @@ class expandedlicensing_ExtendableLicense(simplelicensing_AnyLicenseInfo):
4610
5004
  NODE_KIND = NodeKind.IRI
4611
5005
  ID_ALIAS = "spdxId"
4612
5006
  IS_DEPRECATED = False
4613
- NAMED_INDIVIDUALS = {
5007
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4614
5008
  }
4615
5009
 
4616
5010
 
@@ -4621,7 +5015,7 @@ class expandedlicensing_IndividualLicensingInfo(simplelicensing_AnyLicenseInfo):
4621
5015
  NODE_KIND = NodeKind.IRI
4622
5016
  ID_ALIAS = "spdxId"
4623
5017
  IS_DEPRECATED = False
4624
- NAMED_INDIVIDUALS = {
5018
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4625
5019
  "NoAssertionLicense": "https://spdx.org/rdf/3.0.1/terms/ExpandedLicensing/NoAssertionLicense",
4626
5020
  "NoneLicense": "https://spdx.org/rdf/3.0.1/terms/ExpandedLicensing/NoneLicense",
4627
5021
  }
@@ -4639,7 +5033,7 @@ class expandedlicensing_License(expandedlicensing_ExtendableLicense):
4639
5033
  NODE_KIND = NodeKind.IRI
4640
5034
  ID_ALIAS = "spdxId"
4641
5035
  IS_DEPRECATED = False
4642
- NAMED_INDIVIDUALS = {
5036
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4643
5037
  }
4644
5038
 
4645
5039
  @classmethod
@@ -4732,7 +5126,7 @@ class expandedlicensing_ListedLicense(expandedlicensing_License):
4732
5126
  NODE_KIND = NodeKind.IRI
4733
5127
  ID_ALIAS = "spdxId"
4734
5128
  IS_DEPRECATED = False
4735
- NAMED_INDIVIDUALS = {
5129
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4736
5130
  }
4737
5131
 
4738
5132
  @classmethod
@@ -4765,7 +5159,7 @@ class expandedlicensing_OrLaterOperator(expandedlicensing_ExtendableLicense):
4765
5159
  NODE_KIND = NodeKind.IRI
4766
5160
  ID_ALIAS = "spdxId"
4767
5161
  IS_DEPRECATED = False
4768
- NAMED_INDIVIDUALS = {
5162
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4769
5163
  }
4770
5164
 
4771
5165
  @classmethod
@@ -4789,7 +5183,7 @@ class expandedlicensing_WithAdditionOperator(simplelicensing_AnyLicenseInfo):
4789
5183
  NODE_KIND = NodeKind.IRI
4790
5184
  ID_ALIAS = "spdxId"
4791
5185
  IS_DEPRECATED = False
4792
- NAMED_INDIVIDUALS = {
5186
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4793
5187
  }
4794
5188
 
4795
5189
  @classmethod
@@ -4820,7 +5214,7 @@ class expandedlicensing_WithAdditionOperator(simplelicensing_AnyLicenseInfo):
4820
5214
  class extension_CdxPropertiesExtension(extension_Extension):
4821
5215
  NODE_KIND = NodeKind.BlankNodeOrIRI
4822
5216
  IS_DEPRECATED = False
4823
- NAMED_INDIVIDUALS = {
5217
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4824
5218
  }
4825
5219
 
4826
5220
  @classmethod
@@ -4843,7 +5237,7 @@ class security_CvssV2VulnAssessmentRelationship(security_VulnAssessmentRelations
4843
5237
  NODE_KIND = NodeKind.IRI
4844
5238
  ID_ALIAS = "spdxId"
4845
5239
  IS_DEPRECATED = False
4846
- NAMED_INDIVIDUALS = {
5240
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4847
5241
  }
4848
5242
 
4849
5243
  @classmethod
@@ -4875,7 +5269,7 @@ class security_CvssV3VulnAssessmentRelationship(security_VulnAssessmentRelations
4875
5269
  NODE_KIND = NodeKind.IRI
4876
5270
  ID_ALIAS = "spdxId"
4877
5271
  IS_DEPRECATED = False
4878
- NAMED_INDIVIDUALS = {
5272
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4879
5273
  }
4880
5274
 
4881
5275
  @classmethod
@@ -4922,7 +5316,7 @@ class security_CvssV4VulnAssessmentRelationship(security_VulnAssessmentRelations
4922
5316
  NODE_KIND = NodeKind.IRI
4923
5317
  ID_ALIAS = "spdxId"
4924
5318
  IS_DEPRECATED = False
4925
- NAMED_INDIVIDUALS = {
5319
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4926
5320
  }
4927
5321
 
4928
5322
  @classmethod
@@ -4969,7 +5363,7 @@ class security_EpssVulnAssessmentRelationship(security_VulnAssessmentRelationshi
4969
5363
  NODE_KIND = NodeKind.IRI
4970
5364
  ID_ALIAS = "spdxId"
4971
5365
  IS_DEPRECATED = False
4972
- NAMED_INDIVIDUALS = {
5366
+ NAMED_INDIVIDUALS: Dict[str, str] = {
4973
5367
  }
4974
5368
 
4975
5369
  @classmethod
@@ -5001,7 +5395,7 @@ class security_ExploitCatalogVulnAssessmentRelationship(security_VulnAssessmentR
5001
5395
  NODE_KIND = NodeKind.IRI
5002
5396
  ID_ALIAS = "spdxId"
5003
5397
  IS_DEPRECATED = False
5004
- NAMED_INDIVIDUALS = {
5398
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5005
5399
  }
5006
5400
 
5007
5401
  @classmethod
@@ -5045,7 +5439,7 @@ class security_SsvcVulnAssessmentRelationship(security_VulnAssessmentRelationshi
5045
5439
  NODE_KIND = NodeKind.IRI
5046
5440
  ID_ALIAS = "spdxId"
5047
5441
  IS_DEPRECATED = False
5048
- NAMED_INDIVIDUALS = {
5442
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5049
5443
  }
5050
5444
 
5051
5445
  @classmethod
@@ -5074,7 +5468,7 @@ class security_VexVulnAssessmentRelationship(security_VulnAssessmentRelationship
5074
5468
  NODE_KIND = NodeKind.IRI
5075
5469
  ID_ALIAS = "spdxId"
5076
5470
  IS_DEPRECATED = False
5077
- NAMED_INDIVIDUALS = {
5471
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5078
5472
  }
5079
5473
 
5080
5474
  @classmethod
@@ -5104,7 +5498,7 @@ class security_Vulnerability(Artifact):
5104
5498
  NODE_KIND = NodeKind.IRI
5105
5499
  ID_ALIAS = "spdxId"
5106
5500
  IS_DEPRECATED = False
5107
- NAMED_INDIVIDUALS = {
5501
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5108
5502
  }
5109
5503
 
5110
5504
  @classmethod
@@ -5142,7 +5536,7 @@ class software_SoftwareArtifact(Artifact):
5142
5536
  NODE_KIND = NodeKind.IRI
5143
5537
  ID_ALIAS = "spdxId"
5144
5538
  IS_DEPRECATED = False
5145
- NAMED_INDIVIDUALS = {
5539
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5146
5540
  }
5147
5541
 
5148
5542
  @classmethod
@@ -5260,7 +5654,7 @@ class Bom(Bundle):
5260
5654
  NODE_KIND = NodeKind.IRI
5261
5655
  ID_ALIAS = "spdxId"
5262
5656
  IS_DEPRECATED = False
5263
- NAMED_INDIVIDUALS = {
5657
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5264
5658
  }
5265
5659
 
5266
5660
 
@@ -5270,7 +5664,7 @@ class expandedlicensing_CustomLicense(expandedlicensing_License):
5270
5664
  NODE_KIND = NodeKind.IRI
5271
5665
  ID_ALIAS = "spdxId"
5272
5666
  IS_DEPRECATED = False
5273
- NAMED_INDIVIDUALS = {
5667
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5274
5668
  }
5275
5669
 
5276
5670
 
@@ -5281,7 +5675,7 @@ class security_VexAffectedVulnAssessmentRelationship(security_VexVulnAssessmentR
5281
5675
  NODE_KIND = NodeKind.IRI
5282
5676
  ID_ALIAS = "spdxId"
5283
5677
  IS_DEPRECATED = False
5284
- NAMED_INDIVIDUALS = {
5678
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5285
5679
  }
5286
5680
 
5287
5681
  @classmethod
@@ -5315,7 +5709,7 @@ class security_VexFixedVulnAssessmentRelationship(security_VexVulnAssessmentRela
5315
5709
  NODE_KIND = NodeKind.IRI
5316
5710
  ID_ALIAS = "spdxId"
5317
5711
  IS_DEPRECATED = False
5318
- NAMED_INDIVIDUALS = {
5712
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5319
5713
  }
5320
5714
 
5321
5715
 
@@ -5326,7 +5720,7 @@ class security_VexNotAffectedVulnAssessmentRelationship(security_VexVulnAssessme
5326
5720
  NODE_KIND = NodeKind.IRI
5327
5721
  ID_ALIAS = "spdxId"
5328
5722
  IS_DEPRECATED = False
5329
- NAMED_INDIVIDUALS = {
5723
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5330
5724
  }
5331
5725
 
5332
5726
  @classmethod
@@ -5375,7 +5769,7 @@ class security_VexUnderInvestigationVulnAssessmentRelationship(security_VexVulnA
5375
5769
  NODE_KIND = NodeKind.IRI
5376
5770
  ID_ALIAS = "spdxId"
5377
5771
  IS_DEPRECATED = False
5378
- NAMED_INDIVIDUALS = {
5772
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5379
5773
  }
5380
5774
 
5381
5775
 
@@ -5385,7 +5779,7 @@ class software_File(software_SoftwareArtifact):
5385
5779
  NODE_KIND = NodeKind.IRI
5386
5780
  ID_ALIAS = "spdxId"
5387
5781
  IS_DEPRECATED = False
5388
- NAMED_INDIVIDUALS = {
5782
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5389
5783
  }
5390
5784
 
5391
5785
  @classmethod
@@ -5419,7 +5813,7 @@ class software_Package(software_SoftwareArtifact):
5419
5813
  NODE_KIND = NodeKind.IRI
5420
5814
  ID_ALIAS = "spdxId"
5421
5815
  IS_DEPRECATED = False
5422
- NAMED_INDIVIDUALS = {
5816
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5423
5817
  }
5424
5818
 
5425
5819
  @classmethod
@@ -5477,7 +5871,7 @@ class software_Sbom(Bom):
5477
5871
  NODE_KIND = NodeKind.IRI
5478
5872
  ID_ALIAS = "spdxId"
5479
5873
  IS_DEPRECATED = False
5480
- NAMED_INDIVIDUALS = {
5874
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5481
5875
  }
5482
5876
 
5483
5877
  @classmethod
@@ -5506,7 +5900,7 @@ class software_Snippet(software_SoftwareArtifact):
5506
5900
  NODE_KIND = NodeKind.IRI
5507
5901
  ID_ALIAS = "spdxId"
5508
5902
  IS_DEPRECATED = False
5509
- NAMED_INDIVIDUALS = {
5903
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5510
5904
  }
5511
5905
 
5512
5906
  @classmethod
@@ -5547,7 +5941,7 @@ class ai_AIPackage(software_Package):
5547
5941
  NODE_KIND = NodeKind.IRI
5548
5942
  ID_ALIAS = "spdxId"
5549
5943
  IS_DEPRECATED = False
5550
- NAMED_INDIVIDUALS = {
5944
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5551
5945
  }
5552
5946
 
5553
5947
  @classmethod
@@ -5700,7 +6094,7 @@ class dataset_DatasetPackage(software_Package):
5700
6094
  NODE_KIND = NodeKind.IRI
5701
6095
  ID_ALIAS = "spdxId"
5702
6096
  IS_DEPRECATED = False
5703
- NAMED_INDIVIDUALS = {
6097
+ NAMED_INDIVIDUALS: Dict[str, str] = {
5704
6098
  }
5705
6099
 
5706
6100
  @classmethod