gedcom-x 0.5.8__py3-none-any.whl → 0.5.9__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.
- {gedcom_x-0.5.8.dist-info → gedcom_x-0.5.9.dist-info}/METADATA +1 -1
- gedcom_x-0.5.9.dist-info/RECORD +56 -0
- gedcomx/Extensions/rs10/rsLink.py +109 -59
- gedcomx/__init__.py +1 -1
- gedcomx/address.py +102 -16
- gedcomx/agent.py +81 -24
- gedcomx/attribution.py +52 -28
- gedcomx/conclusion.py +97 -45
- gedcomx/converter.py +209 -79
- gedcomx/coverage.py +10 -1
- gedcomx/date.py +42 -8
- gedcomx/document.py +37 -7
- gedcomx/event.py +77 -20
- gedcomx/evidence_reference.py +9 -0
- gedcomx/fact.py +53 -54
- gedcomx/gedcom.py +10 -0
- gedcomx/gedcom5x.py +30 -20
- gedcomx/gedcom7/__init__.py +1 -1
- gedcomx/gedcomx.py +95 -93
- gedcomx/gender.py +21 -9
- gedcomx/group.py +9 -0
- gedcomx/identifier.py +47 -20
- gedcomx/logging_hub.py +19 -0
- gedcomx/mutations.py +10 -5
- gedcomx/name.py +74 -33
- gedcomx/note.py +50 -18
- gedcomx/online_account.py +9 -0
- gedcomx/person.py +44 -26
- gedcomx/place_description.py +54 -8
- gedcomx/place_reference.py +30 -8
- gedcomx/qualifier.py +19 -3
- gedcomx/relationship.py +55 -14
- gedcomx/resource.py +45 -18
- gedcomx/serialization.py +400 -421
- gedcomx/source_citation.py +16 -4
- gedcomx/source_description.py +181 -94
- gedcomx/source_reference.py +51 -16
- gedcomx/subject.py +59 -14
- gedcomx/textvalue.py +66 -12
- gedcomx/translation.py +3 -3
- gedcomx/uri.py +155 -3
- gedcom_x-0.5.8.dist-info/RECORD +0 -56
- {gedcom_x-0.5.8.dist-info → gedcom_x-0.5.9.dist-info}/WHEEL +0 -0
- {gedcom_x-0.5.8.dist-info → gedcom_x-0.5.9.dist-info}/top_level.txt +0 -0
- /gedcomx/gedcom7/{Gedcom7.py → gedcom7.py} +0 -0
gedcomx/relationship.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
from enum import Enum
|
2
|
-
from typing import
|
2
|
+
from typing import Any, Dict, Optional, List
|
3
3
|
"""
|
4
4
|
======================================================================
|
5
5
|
Project: Gedcom-X
|
@@ -10,6 +10,7 @@ from typing import List, Optional
|
|
10
10
|
Created: 2025-08-25
|
11
11
|
Updated:
|
12
12
|
- 2025-09-31: filename PEP8 standard
|
13
|
+
- 2025-09-03: _from_json_ refactor
|
13
14
|
|
14
15
|
======================================================================
|
15
16
|
"""
|
@@ -22,13 +23,22 @@ GEDCOM Module Types
|
|
22
23
|
from .attribution import Attribution
|
23
24
|
from .conclusion import ConfidenceLevel
|
24
25
|
from .evidence_reference import EvidenceReference
|
26
|
+
from .Extensions.rs10.rsLink import _rsLinks #new
|
25
27
|
from .fact import Fact
|
26
|
-
from .identifier import Identifier
|
28
|
+
from .identifier import Identifier, make_uid
|
27
29
|
from .note import Note
|
28
30
|
from .person import Person
|
29
31
|
from .resource import Resource
|
30
32
|
from .source_reference import SourceReference
|
31
33
|
from .subject import Subject
|
34
|
+
from .logging_hub import hub, logging
|
35
|
+
"""
|
36
|
+
======================================================================
|
37
|
+
Logging
|
38
|
+
======================================================================
|
39
|
+
"""
|
40
|
+
log = logging.getLogger("gedcomx")
|
41
|
+
serial_log = "gedcomx.serialization"
|
32
42
|
#=====================================================================
|
33
43
|
|
34
44
|
|
@@ -74,18 +84,20 @@ class Relationship(Subject):
|
|
74
84
|
media: Optional[List[SourceReference]] = None,
|
75
85
|
identifiers: Optional[List[Identifier]] = None,
|
76
86
|
type: Optional[RelationshipType] = None,
|
87
|
+
links: Optional[_rsLinks] = None,
|
77
88
|
) -> None:
|
78
89
|
|
79
90
|
# Call superclass initializer if required
|
80
|
-
super().__init__(id, lang, sources, analysis, notes, confidence, attribution, extracted, evidence, media, identifiers)
|
91
|
+
super().__init__(id, lang, sources, analysis, notes, confidence, attribution, extracted, evidence, media, identifiers,links=links)
|
81
92
|
|
93
|
+
self.id = id if id else make_uid()
|
82
94
|
self.type = type
|
83
95
|
self.person1 = person1
|
84
96
|
self.person2 = person2
|
85
97
|
self.facts = facts if facts else []
|
86
98
|
|
87
99
|
def add_fact(self,fact: Fact):
|
88
|
-
if fact is not None and isinstance(fact,Fact):
|
100
|
+
if (fact is not None) and isinstance(fact,Fact):
|
89
101
|
for existing_fact in self.facts:
|
90
102
|
if fact == existing_fact:
|
91
103
|
return
|
@@ -96,20 +108,49 @@ class Relationship(Subject):
|
|
96
108
|
@property
|
97
109
|
def _as_dict_(self):
|
98
110
|
from .serialization import Serialization
|
99
|
-
|
100
|
-
|
101
|
-
|
111
|
+
return Serialization.serialize(self)
|
112
|
+
|
113
|
+
type_as_dict = (super()._as_dict_ or {}).copy()
|
114
|
+
|
115
|
+
extras = {
|
116
|
+
"type": getattr(self.type, "value", None),
|
102
117
|
"person1": Resource(target=self.person1)._as_dict_ if self.person1 else None,
|
103
|
-
"person2": Resource(target=self.
|
104
|
-
"facts": [
|
105
|
-
}
|
106
|
-
|
118
|
+
"person2": Resource(target=self.person2)._as_dict_ if self.person2 else None,
|
119
|
+
"facts": [f._as_dict_ for f in self.facts if f] if getattr(self, "facts", None) else None,
|
120
|
+
}
|
121
|
+
|
122
|
+
# only keep non-empty values
|
123
|
+
type_as_dict.update({k: v for k, v in extras.items() if v not in (None, [], {}, ())})
|
124
|
+
|
125
|
+
return type_as_dict or None
|
107
126
|
|
108
127
|
@classmethod
|
109
|
-
def _from_json_(cls, data:
|
128
|
+
def _from_json_(cls, data: Dict[str, Any], context: Any = None) -> "Relationship":
|
110
129
|
"""
|
111
130
|
Create a Person instance from a JSON-dict (already parsed).
|
112
131
|
"""
|
113
|
-
|
114
|
-
|
132
|
+
if not isinstance(data, dict):
|
133
|
+
raise TypeError(f"{cls.__name__}._from_json_ expected dict, got {type(data)}")
|
134
|
+
|
135
|
+
relationship_data: Dict[str, Any] = {}
|
136
|
+
relationship_data = Subject._dict_from_json_(data,context)
|
137
|
+
|
138
|
+
if (id_ := data.get("id")) is not None:
|
139
|
+
relationship_data["id"] = id_
|
140
|
+
|
141
|
+
if (type_ := data.get("type")) is not None:
|
142
|
+
relationship_data["type"] = RelationshipType(type_)
|
143
|
+
|
144
|
+
# person1 / person2
|
145
|
+
if (p1 := data.get("person1")) is not None:
|
146
|
+
relationship_data["person1"] = Resource._from_json_(p1,context)
|
147
|
+
|
148
|
+
if (p2 := data.get("person2")) is not None:
|
149
|
+
relationship_data["person2"] = Resource._from_json_(p2,context)
|
150
|
+
|
151
|
+
# facts
|
152
|
+
if (facts := data.get("facts")) is not None:
|
153
|
+
relationship_data["facts"] = [Fact._from_json_(f, context) for f in facts]
|
154
|
+
|
155
|
+
return cls(**relationship_data)
|
115
156
|
|
gedcomx/resource.py
CHANGED
@@ -10,6 +10,7 @@ from typing import Optional
|
|
10
10
|
Created: 2025-08-25
|
11
11
|
Updated:
|
12
12
|
- 2025-08-31: working on target=Resource and deserialization issues
|
13
|
+
- 2025-09-03: _from_json_ refactor, arguments changed
|
13
14
|
|
14
15
|
======================================================================
|
15
16
|
"""
|
@@ -21,6 +22,15 @@ GEDCOM Module Types
|
|
21
22
|
"""
|
22
23
|
|
23
24
|
from .uri import URI
|
25
|
+
from .logging_hub import hub, logging
|
26
|
+
"""
|
27
|
+
======================================================================
|
28
|
+
Logging
|
29
|
+
======================================================================
|
30
|
+
"""
|
31
|
+
log = logging.getLogger("gedcomx")
|
32
|
+
serial_log = "gedcomx.serialization"
|
33
|
+
#=====================================================================
|
24
34
|
|
25
35
|
class Resource:
|
26
36
|
"""
|
@@ -35,10 +45,14 @@ class Resource:
|
|
35
45
|
If `id` is not a valid UUID.
|
36
46
|
"""
|
37
47
|
# TODO, Deal with a resouce being passed, as it may be unresolved.
|
38
|
-
def __init__(self,
|
48
|
+
def __init__(self,resource: URI | None = None,resourceId: str | None = None, target: object = None) -> None:
|
39
49
|
|
40
|
-
|
41
|
-
|
50
|
+
#if (resource is None) and (target is None): #TODO
|
51
|
+
# raise ValueError('Resource object must point to something.')
|
52
|
+
|
53
|
+
self.resource = resource
|
54
|
+
self.resourceId = resourceId
|
55
|
+
self.Id = None
|
42
56
|
|
43
57
|
self.type = None
|
44
58
|
self.resolved = False
|
@@ -48,12 +62,15 @@ class Resource:
|
|
48
62
|
if target:
|
49
63
|
if isinstance(target,Resource):
|
50
64
|
self.resource = target.resource
|
51
|
-
self.
|
65
|
+
self.resourceId = target.resourceId
|
52
66
|
self.target = target.target
|
53
67
|
else:
|
54
|
-
|
55
|
-
|
56
|
-
|
68
|
+
log.debug(f"Target of type: {type(target)}, {target}")
|
69
|
+
if hasattr(target,'uri'):
|
70
|
+
self.resource = target.uri
|
71
|
+
else:
|
72
|
+
self.resourceId = URI(fragment=target.id)
|
73
|
+
self.resourceId = target.id
|
57
74
|
|
58
75
|
@property
|
59
76
|
def uri(self):
|
@@ -62,24 +79,34 @@ class Resource:
|
|
62
79
|
@property
|
63
80
|
def _as_dict_(self):
|
64
81
|
from .serialization import Serialization
|
82
|
+
return Serialization.serialize(self)
|
65
83
|
typ_as_dict = {}
|
66
|
-
if self.resource:
|
67
|
-
typ_as_dict[
|
68
|
-
if self.
|
69
|
-
typ_as_dict[
|
70
|
-
|
84
|
+
if self.resource is not None:
|
85
|
+
typ_as_dict["resource"] = self.resource
|
86
|
+
if self.resourceId is not None:
|
87
|
+
typ_as_dict["resourceId"] = self.resourceId,
|
88
|
+
|
89
|
+
return typ_as_dict or None
|
90
|
+
|
91
|
+
|
71
92
|
|
72
93
|
@classmethod
|
73
|
-
def _from_json_(cls,data):
|
74
|
-
|
75
|
-
|
76
|
-
|
94
|
+
def _from_json_(cls, data: dict, context=None) -> "Resource":
|
95
|
+
if not isinstance(data, dict):
|
96
|
+
raise TypeError(f"{cls.__name__}._from_json_ expected dict, got {type(data)} {data}")
|
97
|
+
resource = {}
|
98
|
+
|
99
|
+
# Scalars
|
100
|
+
if (res := data.get("resource")) is not None:
|
101
|
+
resource["resource"] = res
|
102
|
+
|
103
|
+
return cls(**resource)
|
77
104
|
|
78
105
|
def __repr__(self) -> str:
|
79
|
-
return f"Resource(
|
106
|
+
return f"Resource(resource={self.resource}, resourceId={self.resourceId}, target={self.target})"
|
80
107
|
|
81
108
|
def __str__(self) -> str:
|
82
|
-
return f"{self.resource}{f',
|
109
|
+
return f"resource={self.resource}{f', resourceId={self.resourceId}' if self.resourceId else ''}"
|
83
110
|
|
84
111
|
|
85
112
|
|