gedcom-x 0.5.9__py3-none-any.whl → 0.5.11__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.
Files changed (48) hide show
  1. {gedcom_x-0.5.9.dist-info → gedcom_x-0.5.11.dist-info}/METADATA +1 -1
  2. gedcom_x-0.5.11.dist-info/RECORD +57 -0
  3. gedcomx/Extensions/rs10/rsLink.py +2 -1
  4. gedcomx/__init__.py +8 -3
  5. gedcomx/address.py +3 -0
  6. gedcomx/agent.py +11 -6
  7. gedcomx/attribution.py +3 -1
  8. gedcomx/conclusion.py +10 -6
  9. gedcomx/converter.py +92 -27
  10. gedcomx/coverage.py +3 -1
  11. gedcomx/date.py +3 -0
  12. gedcomx/document.py +3 -1
  13. gedcomx/event.py +3 -0
  14. gedcomx/evidence_reference.py +30 -3
  15. gedcomx/extensible.py +86 -0
  16. gedcomx/fact.py +6 -2
  17. gedcomx/gedcom5x.py +21 -3
  18. gedcomx/gedcom7/GedcomStructure.py +1 -3
  19. gedcomx/gedcom7/__init__.py +1 -1
  20. gedcomx/gedcom7/gedcom7.py +3 -3
  21. gedcomx/gedcom7/specification.py +4817 -0
  22. gedcomx/gedcomx.py +3 -0
  23. gedcomx/gender.py +5 -1
  24. gedcomx/group.py +11 -2
  25. gedcomx/identifier.py +5 -2
  26. gedcomx/logging_hub.py +132 -22
  27. gedcomx/name.py +15 -6
  28. gedcomx/note.py +25 -10
  29. gedcomx/online_account.py +20 -0
  30. gedcomx/person.py +8 -6
  31. gedcomx/place_description.py +3 -1
  32. gedcomx/place_reference.py +5 -2
  33. gedcomx/qualifier.py +2 -0
  34. gedcomx/relationship.py +8 -5
  35. gedcomx/resource.py +20 -6
  36. gedcomx/schemas.py +530 -0
  37. gedcomx/serialization.py +36 -16
  38. gedcomx/source_citation.py +22 -0
  39. gedcomx/source_description.py +22 -18
  40. gedcomx/source_reference.py +25 -3
  41. gedcomx/subject.py +2 -3
  42. gedcomx/textvalue.py +19 -4
  43. gedcomx/uri.py +8 -6
  44. gedcom_x-0.5.9.dist-info/RECORD +0 -56
  45. gedcomx/Logging.py +0 -19
  46. gedcomx/gedcom7/Specification.py +0 -347
  47. {gedcom_x-0.5.9.dist-info → gedcom_x-0.5.11.dist-info}/WHEEL +0 -0
  48. {gedcom_x-0.5.9.dist-info → gedcom_x-0.5.11.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,29 @@
1
- from typing import Optional
1
+ from typing import Optional, TYPE_CHECKING
2
+ """
3
+ ======================================================================
4
+ Project: Gedcom-X
5
+ File: evidence_reference.py
6
+ Author: David J. Cartwright
7
+ Purpose:
8
+
9
+ Created: 2025-08-25
10
+ Updated:
11
+ - 2025-09-09: added schema_class
12
+
13
+
14
+ ======================================================================
15
+ """
2
16
 
17
+ """
18
+ ======================================================================
19
+ GEDCOM Module Type Imports
20
+ ======================================================================
21
+ """
3
22
  from .attribution import Attribution
4
23
  from .resource import Resource
24
+ from .schemas import schema_class
25
+ if TYPE_CHECKING:
26
+ from .subject import Subject
5
27
  from .logging_hub import hub, logging
6
28
  """
7
29
  ======================================================================
@@ -12,9 +34,14 @@ log = logging.getLogger("gedcomx")
12
34
  serial_log = "gedcomx.serialization"
13
35
  #=====================================================================
14
36
 
37
+ @schema_class()
15
38
  class EvidenceReference:
16
39
  identifier = 'http://gedcomx.org/v1/EvidenceReference'
17
40
  version = 'http://gedcomx.org/conceptual-model/v1'
18
41
 
19
- def __init__(self, resource: Resource, attribution: Optional[Attribution]) -> None:
20
- pass
42
+ def __init__(self, resource: "Resource | Subject", attribution: Optional[Attribution]) -> None:
43
+ self.resource = resource
44
+ self.attribution: Attribution = attribution
45
+
46
+ def _validate(self):
47
+ raise NotImplemented
gedcomx/extensible.py ADDED
@@ -0,0 +1,86 @@
1
+ # extensible.py
2
+ from __future__ import annotations
3
+ from dataclasses import dataclass, field
4
+ from typing import Any, Dict, Optional, Callable
5
+
6
+ from .schemas import SCHEMA
7
+ # If you're using the earlier schema registry:
8
+ #from .serialization_schema import SCHEMA
9
+
10
+
11
+
12
+ class Extensible:
13
+ # class-level registry of declared extras
14
+ _declared_extras: Dict[str, Any] = {}
15
+
16
+ def __init_subclass__(cls, **kw):
17
+ super().__init_subclass__(**kw)
18
+ # each subclass gets its own dict (copy, not shared)
19
+ cls._declared_extras = dict(getattr(cls, "_declared_extras", {}))
20
+
21
+ def __init__(self, *args, **kwargs):
22
+ super().__init__(*args, **kwargs) # cooperative
23
+ self.extras: Dict[str, Any] = {}
24
+ # seed declared defaults
25
+ for k, default in type(self)._declared_extras.items():
26
+ self.extras[k] = _copy_default(default)
27
+
28
+ @classmethod
29
+ def define_ext(
30
+ cls,
31
+ name: str,
32
+ *,
33
+ typ: type | None = None,
34
+ default: Any = None,
35
+ overwrite: bool = False,
36
+ ) -> None:
37
+ """
38
+ Declare an extra field on the CLASS.
39
+
40
+ Args:
41
+ name: field name
42
+ typ: Python type (used to update schema registry)
43
+ default: default value for new instances
44
+ overwrite: if True, replaces existing definition
45
+ """
46
+ if name in getattr(cls, "__dataclass_fields__", {}):
47
+ raise AttributeError(f"{name!r} already exists on {cls.__name__}")
48
+
49
+ already = hasattr(cls, name)
50
+ if already and not overwrite:
51
+ return
52
+
53
+ # Attach descriptor
54
+ setattr(cls, name, _ExtraField(name, default))
55
+ cls._declared_extras[name] = default
56
+
57
+ # Register with schema
58
+ if typ is None and default is not None:
59
+ typ = type(default)
60
+ SCHEMA.register_extra(cls, name, typ or type(None))
61
+
62
+ @classmethod
63
+ def declared_extras(cls) -> Dict[str, Any]:
64
+ return dict(getattr(cls, "_declared_extras", {}))
65
+
66
+
67
+ class _ExtraField:
68
+ def __init__(self, name: str, default: Any):
69
+ self.name = name
70
+ self.default = default
71
+ def __get__(self, obj, owner):
72
+ if obj is None:
73
+ return self
74
+ return obj.extras.get(self.name, self.default)
75
+ def __set__(self, obj, value):
76
+ obj.extras[self.name] = value
77
+
78
+
79
+ def _copy_default(v: Any) -> Any:
80
+ if isinstance(v, (list, dict, set)):
81
+ return v.copy()
82
+ return v
83
+ # avoid shared mutable defaults
84
+ if isinstance(v, (list, dict, set)):
85
+ return v.copy()
86
+ return v
gedcomx/fact.py CHANGED
@@ -2,7 +2,7 @@ import difflib
2
2
  import re
3
3
 
4
4
  from enum import Enum
5
- from typing import List, Optional, Dict, Any
5
+ from typing import List, Optional, Dict, Any, Union, TYPE_CHECKING
6
6
  """
7
7
  ======================================================================
8
8
  Project: Gedcom-X
@@ -13,6 +13,7 @@ from typing import List, Optional, Dict, Any
13
13
  Created: 2025-08-25
14
14
  Updated:
15
15
  - 2025-09-03: _from_json_ refactor
16
+ - 2025-09-09: added schema_class
16
17
 
17
18
  ======================================================================
18
19
  """
@@ -31,6 +32,7 @@ from .note import Note
31
32
  from .place_reference import PlaceReference
32
33
  from .qualifier import Qualifier
33
34
  from .resource import Resource
35
+ from .schemas import schema_class
34
36
  from .source_reference import SourceReference
35
37
  from .logging_hub import hub, logging
36
38
  """
@@ -406,6 +408,7 @@ class FactQualifier(Enum):
406
408
  }
407
409
  return descriptions.get(self, "No description available.")
408
410
 
411
+ @schema_class()
409
412
  class Fact(Conclusion):
410
413
  identifier = 'http://gedcomx.org/v1/Fact'
411
414
  version = 'http://gedcomx.org/conceptual-model/v1'
@@ -414,7 +417,7 @@ class Fact(Conclusion):
414
417
  id: Optional[str] = None,
415
418
  lang: Optional[str] = None,
416
419
  sources: Optional[List[SourceReference]] = None,
417
- analysis: Optional[Resource | Document] = None,
420
+ analysis: Optional[Union[Resource,Document]] = None,
418
421
  notes: Optional[List[Note]] = None,
419
422
  confidence: Optional[ConfidenceLevel] = None,
420
423
  attribution: Optional[Attribution] = None,
@@ -430,6 +433,7 @@ class Fact(Conclusion):
430
433
  self.place = place
431
434
  self.value = value
432
435
  self._qualifiers = qualifiers if qualifiers else []
436
+ self.id = id if id else None # No need for id on 'Fact' unless provided
433
437
 
434
438
 
435
439
  @property
gedcomx/gedcom5x.py CHANGED
@@ -7,10 +7,28 @@ from typing import List, Optional, Tuple, Any
7
7
  import re
8
8
  from collections import defaultdict
9
9
  from typing import Iterable, Iterator, List, Optional, Tuple, Union
10
+ """
11
+ ======================================================================
12
+ Project: Gedcom-X
13
+ File: gedcom5x.py
14
+ Author: David J. Cartwright
15
+ Purpose:
16
+
17
+ Created: 2025-08-25
18
+ Updated:
19
+ - 2025-09-03:
20
+
21
+ ======================================================================
22
+ """
23
+
24
+ """
25
+ ======================================================================
26
+ GEDCOM Module Types
27
+ ======================================================================
28
+ """
29
+ #import logging
30
+ from .logging_hub import hub, ChannelConfig, logging
10
31
 
11
- import logging
12
- from .logging_hub import hub, ChannelConfig
13
- from .logging_hub import hub, logging
14
32
  """
15
33
  ======================================================================
16
34
  Logging
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from typing import Dict, Any
4
4
  import warnings
5
- from . import Specification as g7
5
+ from . import specification as g7
6
6
 
7
7
  from typing import Dict, List,Optional,Any
8
8
 
@@ -19,8 +19,6 @@ gedcom_top_level_terms = ['https://gedcom.io/terms/v7/CONT',
19
19
  'https://gedcom.io/terms/v7/record-SOUR']
20
20
 
21
21
 
22
-
23
-
24
22
  class GedcomStructure:
25
23
  version = 'v7'
26
24
 
@@ -21,6 +21,6 @@ GEDCOM Module Types
21
21
  """
22
22
  from .GedcomStructure import GedcomStructure
23
23
  from .logger import get_logger
24
- from .Specification import structure_specs
24
+ from .specification import g7_structure_specs
25
25
  from .gedcom7 import Gedcom7
26
26
  __all__ = ["Gedcom7"]
@@ -5,7 +5,7 @@ from collections import defaultdict
5
5
 
6
6
 
7
7
  from .GedcomStructure import GedcomStructure
8
- from . import Specification as g7specs
8
+ from . import specification as g7specs
9
9
  from .logger import get_logger
10
10
 
11
11
 
@@ -114,8 +114,8 @@ class Gedcom7:
114
114
 
115
115
  if tag == 'TAG':
116
116
  xtag, uri = value.split()
117
- g7specs.structure_specs[xtag] = uri
118
- g7specs.structure_specs[uri] = {'label': 'Extension_' + xtag}
117
+ g7specs.g7_structure_specs[xtag] = uri
118
+ g7specs.g7_structure_specs[uri] = {'label': 'Extension_' + xtag}
119
119
 
120
120
  return {
121
121
  "level": level,