pyMetaModel 0.6.6__tar.gz → 0.6.9__tar.gz
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.
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/PKG-INFO +1 -1
- pymetamodel-0.6.9/meta/__init__.py +1 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/meta/metamodel.py +68 -75
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/meta/version.py +1 -1
- pymetamodel-0.6.9/tests/test_metamodel.py +81 -0
- pymetamodel-0.6.6/meta/__init__.py +0 -1
- pymetamodel-0.6.6/tests/test_metamodel.py +0 -36
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/.github/workflows/build.yml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/.github/workflows/upload-to-pypi.yml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/.gitignore +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/.project +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/.pydevproject +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/LICENSE +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/README.md +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/docs/index.md +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/ceur-ws/ceur-ws.mermaid +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/ceur-ws/ceur-ws.puml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/ceur-ws/ceur-ws.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/ceur-ws/ceur-ws.sidif +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/ceur-ws/ceur-ws.xlsx +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/ceur-ws/ceur-ws.yaml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/ceur-ws/ceur-ws_puml.txt +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/city/city.mermaid +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/city/city.puml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/city/city.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/city/city.sidif +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/city/city.xlsx +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/city/city.yaml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/city/city_puml.txt +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/family/FamilyContext.mermaid +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/family/FamilyContext.puml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/family/FamilyContext.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/family/FamilyContext.sidif +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/family/FamilyContext.xlsx +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/family/FamilyContext.yaml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/family/FamilyContext_puml.txt +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/infrastructure/infrastructure.mermaid +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/infrastructure/infrastructure.puml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/infrastructure/infrastructure.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/infrastructure/infrastructure.sidif +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/infrastructure/infrastructure.xlsx +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/infrastructure/infrastructure.yaml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/infrastructure/infrastructure_puml.txt +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/metamodel/metamodel.mermaid +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/metamodel/metamodel.puml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/metamodel/metamodel.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/metamodel/metamodel.sidif +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/metamodel/metamodel.xlsx +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/metamodel/metamodel.yaml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/metamodel/metamodel_puml.txt +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/scientific-events/scientific-events.mermaid +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/scientific-events/scientific-events.puml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/scientific-events/scientific-events.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/scientific-events/scientific-events.sidif +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/scientific-events/scientific-events.xlsx +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/scientific-events/scientific-events.yaml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/scientific-events/scientific-events_puml.txt +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/smartRQM/smartRQM.mermaid +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/smartRQM/smartRQM.puml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/smartRQM/smartRQM.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/smartRQM/smartRQM.sidif +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/smartRQM/smartRQM.yaml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/smartRQM/smartRQM_puml.txt +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/smwcon/smwcon.mermaid +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/smwcon/smwcon.puml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/smwcon/smwcon.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/smwcon/smwcon.sidif +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/smwcon/smwcon.xlsx +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/smwcon/smwcon.yaml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/smwcon/smwcon_puml.txt +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/teaching/TeachingSchema.mermaid +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/teaching/TeachingSchema.puml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/teaching/TeachingSchema.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/teaching/TeachingSchema.sidif +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/teaching/TeachingSchema.xlsx +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/teaching/TeachingSchema.yaml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/teaching/TeachingSchema_puml.txt +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/wiki/wiki.mermaid +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/wiki/wiki.puml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/wiki/wiki.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/wiki/wiki.sidif +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/wiki/wiki.xlsx +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/wiki/wiki.yaml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/wiki/wiki_puml.txt +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/meta/metamodel_cmd.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/meta/mw.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/meta/profiler.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/meta/sidif2linkml.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/meta/smw_type.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/meta/uml.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/metamodel.puml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/mkdocs.yml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/pyproject.toml +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/scripts/blackisort +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/scripts/doc +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/scripts/genexamples +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/scripts/install +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/scripts/release +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/scripts/test +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/tests/__init__.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/tests/basemwtest.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/tests/basesmwtest.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/tests/basetest.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/tests/test_generators.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/tests/test_linkml.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/tests/test_mw.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/tests/test_plantuml.py +0 -0
- {pymetamodel-0.6.6 → pymetamodel-0.6.9}/tests/test_sidif.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.6.9"
|
|
@@ -26,18 +26,19 @@ class Context:
|
|
|
26
26
|
A Context groups some topics like a Namespace/Package.
|
|
27
27
|
This class provides helper functions and constants to render a Context to corresponding wiki pages
|
|
28
28
|
"""
|
|
29
|
+
|
|
29
30
|
name: Optional[str] = None
|
|
30
|
-
since: Optional[str] = None
|
|
31
|
-
updated: Optional[str] = None
|
|
31
|
+
since: Optional[str] = None # isodate string
|
|
32
|
+
updated: Optional[str] = None # isodate string
|
|
32
33
|
copyright: Optional[str] = None
|
|
33
34
|
master: Optional[str] = None
|
|
34
35
|
demo: Optional[str] = None
|
|
35
|
-
topics: Dict[str,
|
|
36
|
-
types: Dict[str,
|
|
36
|
+
topics: Dict[str, "Topic"] = field(default_factory=dict)
|
|
37
|
+
types: Dict[str, "Topic"] = field(default_factory=dict)
|
|
37
38
|
errors: List[str] = field(default_factory=list)
|
|
38
39
|
|
|
39
40
|
def __post_init__(self):
|
|
40
|
-
self.log=Log()
|
|
41
|
+
self.log = Log()
|
|
41
42
|
pass
|
|
42
43
|
|
|
43
44
|
@classmethod
|
|
@@ -49,17 +50,17 @@ class Context:
|
|
|
49
50
|
"updated": datetime.strptime("2024-08-07", "%Y-%m-%d"),
|
|
50
51
|
"copyright": "2015-2025 BITPlan GmbH",
|
|
51
52
|
"master": "https://contexts.bitplan.com",
|
|
52
|
-
"demo": "https://wiki.bitplan.com/index.php/List_of_Contexts"
|
|
53
|
+
"demo": "https://wiki.bitplan.com/index.php/List_of_Contexts",
|
|
53
54
|
}
|
|
54
55
|
]
|
|
55
56
|
return samples
|
|
56
57
|
|
|
57
|
-
def sanitize(self,key:str):
|
|
58
|
+
def sanitize(self, key: str):
|
|
58
59
|
"""
|
|
59
60
|
make sure my needed properties exist
|
|
60
61
|
"""
|
|
61
|
-
if not hasattr(self,"name"):
|
|
62
|
-
self.name=key
|
|
62
|
+
if not hasattr(self, "name"):
|
|
63
|
+
self.name = key
|
|
63
64
|
pass
|
|
64
65
|
pass
|
|
65
66
|
|
|
@@ -82,7 +83,7 @@ class Context:
|
|
|
82
83
|
return self.topics[topic_name]
|
|
83
84
|
else:
|
|
84
85
|
self.error(
|
|
85
|
-
f"""topic {topic_name} not found in context {getattr(self,"name","?")} for {purpose}"""
|
|
86
|
+
f"""topic {topic_name} not found in context {getattr(self, "name", "?")} for {purpose}"""
|
|
86
87
|
)
|
|
87
88
|
return None
|
|
88
89
|
|
|
@@ -186,6 +187,7 @@ class Context:
|
|
|
186
187
|
prop.topicLink = tl
|
|
187
188
|
prop.isLink = True
|
|
188
189
|
prop.showInGrid = False
|
|
190
|
+
prop.separator = tl.separator
|
|
189
191
|
return prop
|
|
190
192
|
|
|
191
193
|
@classmethod
|
|
@@ -225,8 +227,8 @@ class Context:
|
|
|
225
227
|
prop.sanitize()
|
|
226
228
|
context.addProperty(prop)
|
|
227
229
|
elif isA == "SMW_Type":
|
|
228
|
-
smw_type=SMW_Type.from_dict2(record)
|
|
229
|
-
context.types[smw_type.type]=smw_type
|
|
230
|
+
smw_type = SMW_Type.from_dict2(record) # @UndefinedVariable
|
|
231
|
+
context.types[smw_type.type] = smw_type
|
|
230
232
|
else: # isA == Topic or in declared topics
|
|
231
233
|
topic = Topic.from_dict2(record)
|
|
232
234
|
topic.sanitize()
|
|
@@ -238,14 +240,16 @@ class Context:
|
|
|
238
240
|
context.error(f"topic {topic.name} has no defined context")
|
|
239
241
|
if hasattr(topic, "name") and topic.name:
|
|
240
242
|
context.topics[topic.name] = topic
|
|
241
|
-
topic.context_obj=context
|
|
243
|
+
topic.context_obj = context
|
|
242
244
|
else:
|
|
243
245
|
# potential foreign or extends declaration
|
|
244
|
-
context.error(
|
|
246
|
+
context.error(
|
|
247
|
+
f"missing name for topic {topic} {key} - foreign declaration?"
|
|
248
|
+
)
|
|
245
249
|
except Exception as ex:
|
|
246
250
|
if context:
|
|
247
|
-
msg=f"invalid dict {record}: {str(ex)}"
|
|
248
|
-
context.log.log("❌","dict",msg)
|
|
251
|
+
msg = f"invalid dict {record}: {str(ex)}"
|
|
252
|
+
context.log.log("❌", "dict", msg)
|
|
249
253
|
else:
|
|
250
254
|
raise ex
|
|
251
255
|
# link topic to concepts and add topicLinks
|
|
@@ -258,7 +262,9 @@ class Context:
|
|
|
258
262
|
return context
|
|
259
263
|
|
|
260
264
|
@classmethod
|
|
261
|
-
def fromSiDIF_input(
|
|
265
|
+
def fromSiDIF_input(
|
|
266
|
+
cls, sidif_input: str, debug: bool = False
|
|
267
|
+
) -> Tuple["Context", str, str]:
|
|
262
268
|
"""
|
|
263
269
|
initialize me from the given SiDIF input which might be a file path
|
|
264
270
|
or url
|
|
@@ -333,7 +339,7 @@ class Context:
|
|
|
333
339
|
error = None
|
|
334
340
|
errMsg = None
|
|
335
341
|
sidif = None
|
|
336
|
-
msg=f"reading sidif for {mw_context.context} from {mw_context.wikiId}"
|
|
342
|
+
msg = f"reading sidif for {mw_context.context} from {mw_context.wikiId}"
|
|
337
343
|
if debug:
|
|
338
344
|
print(msg)
|
|
339
345
|
try:
|
|
@@ -346,17 +352,19 @@ class Context:
|
|
|
346
352
|
sidif=sidif, title=mw_context.wikiId, depth=depth, debug=debug
|
|
347
353
|
)
|
|
348
354
|
else:
|
|
349
|
-
errMsg=f"{msg} failed"
|
|
350
|
-
error=ValueError(msg)
|
|
355
|
+
errMsg = f"{msg} failed"
|
|
356
|
+
error = ValueError(msg)
|
|
351
357
|
return context, error, errMsg
|
|
352
358
|
|
|
359
|
+
|
|
353
360
|
@lod_storable
|
|
354
361
|
class Topic:
|
|
355
362
|
"""
|
|
356
363
|
A Topic is a Concept/Class/Thing/Entity
|
|
357
364
|
"""
|
|
365
|
+
|
|
358
366
|
name: Optional[str] = None
|
|
359
|
-
|
|
367
|
+
pluralName: Optional[str] = None
|
|
360
368
|
icon: Optional[str] = None
|
|
361
369
|
iconUrl: Optional[str] = None
|
|
362
370
|
documentation: Optional[str] = None
|
|
@@ -364,18 +372,24 @@ class Topic:
|
|
|
364
372
|
defaultstoremode: str = "property"
|
|
365
373
|
extends: Optional[str] = None
|
|
366
374
|
listLimit: int = 200
|
|
367
|
-
cargo:bool=False
|
|
368
|
-
headerTabs:bool=False
|
|
375
|
+
cargo: bool = False
|
|
376
|
+
headerTabs: bool = False
|
|
369
377
|
context: Optional[str] = None
|
|
370
|
-
properties: Dict[str,
|
|
371
|
-
sourceTopicLinks: Dict[str,
|
|
372
|
-
targetTopicLinks: Dict[str,
|
|
378
|
+
properties: Dict[str, "Property"] = field(default_factory=dict)
|
|
379
|
+
sourceTopicLinks: Dict[str, "TopicLink"] = field(default_factory=dict)
|
|
380
|
+
targetTopicLinks: Dict[str, "TopicLink"] = field(default_factory=dict)
|
|
373
381
|
# object references
|
|
374
382
|
context_obj: Optional[Context] = None
|
|
375
|
-
conceptProperty: Optional[
|
|
383
|
+
conceptProperty: Optional["Property"] = None
|
|
376
384
|
|
|
385
|
+
def get_primary_key_property(self) -> Optional["Property"]:
|
|
386
|
+
"""Return the first property marked as primaryKey, or None."""
|
|
387
|
+
return next(
|
|
388
|
+
(p for p in self.properties.values() if getattr(p, "primaryKey", False)),
|
|
389
|
+
None,
|
|
390
|
+
)
|
|
377
391
|
|
|
378
|
-
def get_extends_topics(self, l: List[
|
|
392
|
+
def get_extends_topics(self, l: List["Topic"] = None) -> List["Topic"]:
|
|
379
393
|
"""
|
|
380
394
|
Get the topics this topic is extending.
|
|
381
395
|
|
|
@@ -399,7 +413,7 @@ class Topic:
|
|
|
399
413
|
|
|
400
414
|
return l
|
|
401
415
|
|
|
402
|
-
def get_all_properties(self) -> List[
|
|
416
|
+
def get_all_properties(self) -> List["Property"]:
|
|
403
417
|
"""
|
|
404
418
|
Get all properties of the topic, including those inherited from extended topics.
|
|
405
419
|
|
|
@@ -419,18 +433,18 @@ class Topic:
|
|
|
419
433
|
|
|
420
434
|
return all_properties
|
|
421
435
|
|
|
422
|
-
|
|
423
436
|
def sanitize(self):
|
|
424
437
|
"""
|
|
425
438
|
make sure my properties exist note that name is not handled here
|
|
426
439
|
on purpose since it needs special treatment
|
|
427
440
|
"""
|
|
428
|
-
doc=self.documentation if hasattr(self, "documentation") else "?"
|
|
441
|
+
doc = self.documentation if hasattr(self, "documentation") else "?"
|
|
429
442
|
if not hasattr(self, "wikiDocumentation") or not self.wikiDocumentation:
|
|
430
|
-
self.wikiDocumentation=doc
|
|
431
|
-
if not hasattr(self,"defaultstoremode"):
|
|
432
|
-
self.defaultstoremode="property"
|
|
433
|
-
|
|
443
|
+
self.wikiDocumentation = doc
|
|
444
|
+
if not hasattr(self, "defaultstoremode"):
|
|
445
|
+
self.defaultstoremode = "property"
|
|
446
|
+
if not self.pluralName:
|
|
447
|
+
self.pluralName = f"{self.name}s"
|
|
434
448
|
|
|
435
449
|
@classmethod
|
|
436
450
|
def getSamples(cls):
|
|
@@ -455,7 +469,7 @@ class Topic:
|
|
|
455
469
|
set my concept property to any primary key or mandatory property
|
|
456
470
|
"""
|
|
457
471
|
self.conceptProperty = None
|
|
458
|
-
all_properties=self.propertiesByIndex(to_root=True)
|
|
472
|
+
all_properties = self.propertiesByIndex(to_root=True)
|
|
459
473
|
for prop in all_properties:
|
|
460
474
|
mandatory = False
|
|
461
475
|
primaryKey = False
|
|
@@ -467,27 +481,6 @@ class Topic:
|
|
|
467
481
|
self.conceptProperty = prop
|
|
468
482
|
break
|
|
469
483
|
|
|
470
|
-
@property
|
|
471
|
-
def pluralName(self)->str:
|
|
472
|
-
"""
|
|
473
|
-
Getter for pluralName.
|
|
474
|
-
|
|
475
|
-
Returns:
|
|
476
|
-
str: The plural name of the topic.
|
|
477
|
-
"""
|
|
478
|
-
# Default behavior if _pluralName is not explicitly set
|
|
479
|
-
return self._pluralName if self._pluralName is not None else f"{self.name}s"
|
|
480
|
-
|
|
481
|
-
@pluralName.setter
|
|
482
|
-
def pluralName(self, value):
|
|
483
|
-
"""
|
|
484
|
-
Setter for pluralName.
|
|
485
|
-
|
|
486
|
-
Args:
|
|
487
|
-
value (str): The plural name to be set for the topic.
|
|
488
|
-
"""
|
|
489
|
-
self._pluralName = value
|
|
490
|
-
|
|
491
484
|
def getPluralName(self) -> str:
|
|
492
485
|
"""
|
|
493
486
|
get the plural name for this topic
|
|
@@ -513,7 +506,7 @@ class Topic:
|
|
|
513
506
|
list: a list of properties in sort order
|
|
514
507
|
"""
|
|
515
508
|
prop_list = []
|
|
516
|
-
all_properties=self.get_all_properties()
|
|
509
|
+
all_properties = self.get_all_properties()
|
|
517
510
|
for prop in all_properties:
|
|
518
511
|
if hasattr(prop, "sortPos"):
|
|
519
512
|
sortPos = prop.sortPos
|
|
@@ -534,13 +527,12 @@ class Topic:
|
|
|
534
527
|
inheritance_chain = self.get_extends_topics()
|
|
535
528
|
inheritance_chain.append(self)
|
|
536
529
|
for topic in inheritance_chain:
|
|
537
|
-
sorted_props=topic.propertiesByIndex(to_root=False)
|
|
530
|
+
sorted_props = topic.propertiesByIndex(to_root=False)
|
|
538
531
|
properties_dict[topic.name] = sorted_props
|
|
539
532
|
|
|
540
533
|
return properties_dict
|
|
541
534
|
|
|
542
|
-
|
|
543
|
-
def propertiesByIndex(self,to_root:bool=False) -> list:
|
|
535
|
+
def propertiesByIndex(self, to_root: bool = False) -> list:
|
|
544
536
|
"""
|
|
545
537
|
Return the properties by index, considering inheritance chain.
|
|
546
538
|
|
|
@@ -564,7 +556,6 @@ class Topic:
|
|
|
564
556
|
|
|
565
557
|
return sorted_props
|
|
566
558
|
|
|
567
|
-
|
|
568
559
|
def askSort(self) -> str:
|
|
569
560
|
"""
|
|
570
561
|
generate the sort clause for my SMW ask query
|
|
@@ -594,7 +585,7 @@ class Topic:
|
|
|
594
585
|
mainlabel: str = None,
|
|
595
586
|
filterShowInGrid: bool = True,
|
|
596
587
|
listLimit: int = None,
|
|
597
|
-
result_format: str="table"
|
|
588
|
+
result_format: str = "table",
|
|
598
589
|
) -> str:
|
|
599
590
|
"""
|
|
600
591
|
Get the askQuery for the topic, considering inheritance.
|
|
@@ -617,7 +608,7 @@ class Topic:
|
|
|
617
608
|
for topic_name, properties in properties_dict.items():
|
|
618
609
|
for prop in properties:
|
|
619
610
|
if filterShowInGrid:
|
|
620
|
-
show=getattr(prop, "showInGrid",False)
|
|
611
|
+
show = getattr(prop, "showInGrid", False)
|
|
621
612
|
else:
|
|
622
613
|
show = True
|
|
623
614
|
if show:
|
|
@@ -628,11 +619,13 @@ class Topic:
|
|
|
628
619
|
markup += f"""{self.askSort()}}}}}"""
|
|
629
620
|
return markup
|
|
630
621
|
|
|
622
|
+
|
|
631
623
|
@lod_storable
|
|
632
624
|
class Property:
|
|
633
625
|
"""
|
|
634
626
|
Provides helper functions and constants for properties
|
|
635
627
|
"""
|
|
628
|
+
|
|
636
629
|
name: Optional[str] = None
|
|
637
630
|
label: Optional[str] = None
|
|
638
631
|
type: Optional[str] = None
|
|
@@ -645,18 +638,18 @@ class Property:
|
|
|
645
638
|
uploadable: bool = False
|
|
646
639
|
defaultValue: Optional[str] = None
|
|
647
640
|
inputType: Optional[str] = None
|
|
648
|
-
allowedValues: Optional[str]=None
|
|
641
|
+
allowedValues: Optional[str] = None
|
|
649
642
|
documentation: Optional[str] = None
|
|
650
|
-
values_from: Optional[str]=None
|
|
651
|
-
formatterURI: Optional[str] = None
|
|
643
|
+
values_from: Optional[str] = None
|
|
644
|
+
formatterURI: Optional[str] = None # externalFormatterURI
|
|
652
645
|
showInGrid: bool = True
|
|
653
646
|
isLink: bool = False
|
|
654
647
|
nullable: bool = False
|
|
655
648
|
sortAscending: bool = True
|
|
649
|
+
separator: Optional[str] = None
|
|
656
650
|
# Links
|
|
657
651
|
topic: Optional[str] = None
|
|
658
|
-
topicLink: Optional[
|
|
659
|
-
|
|
652
|
+
topicLink: Optional["TopicLink"] = None
|
|
660
653
|
|
|
661
654
|
@classmethod
|
|
662
655
|
def getSamples(cls):
|
|
@@ -698,23 +691,23 @@ class Property:
|
|
|
698
691
|
]
|
|
699
692
|
return samples
|
|
700
693
|
|
|
701
|
-
|
|
702
694
|
def sanitize(self):
|
|
703
695
|
"""
|
|
704
696
|
make sure attributes such as namespace are set properly
|
|
705
697
|
"""
|
|
706
|
-
self.namespace="Property"
|
|
707
|
-
self.topicLink=None
|
|
698
|
+
self.namespace = "Property"
|
|
699
|
+
self.topicLink = None
|
|
708
700
|
if hasattr(self, "scope"):
|
|
709
701
|
pass
|
|
710
702
|
if not hasattr(self, "showInGrid"):
|
|
711
|
-
self.showInGrid=True
|
|
703
|
+
self.showInGrid = True
|
|
712
704
|
if not hasattr(self, "label"):
|
|
713
|
-
self.label=getattr(self,"name")
|
|
705
|
+
self.label = getattr(self, "name")
|
|
714
706
|
if not hasattr(self, "type") or not self.type:
|
|
715
|
-
self.type="Text"
|
|
707
|
+
self.type = "Text"
|
|
716
708
|
pass
|
|
717
709
|
|
|
710
|
+
|
|
718
711
|
@lod_storable
|
|
719
712
|
class TopicLink:
|
|
720
713
|
"""
|
|
@@ -16,7 +16,7 @@ class Version(object):
|
|
|
16
16
|
description = "pyMetaModel: MetaModel for Knowledge Graphs"
|
|
17
17
|
version = meta.__version__
|
|
18
18
|
date = "2022-11-30"
|
|
19
|
-
updated = "
|
|
19
|
+
updated = "2026-07-13"
|
|
20
20
|
authors = "Wolfgang Fahl"
|
|
21
21
|
doc_url = "https://wiki.bitplan.com/index.php/pyMetaModel"
|
|
22
22
|
chat_url = "https://github.com/WolfgangFahl/pyMetaModel/discussions"
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Created on 2023-02-25
|
|
3
|
+
|
|
4
|
+
@author: wf
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from meta.smw_type import SMW_Type
|
|
8
|
+
from tests.basemwtest import BaseMediawikiTest
|
|
9
|
+
from meta.metamodel import Property, Topic
|
|
10
|
+
from tests.basetest import Basetest
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TestMetaModel(BaseMediawikiTest):
|
|
14
|
+
"""
|
|
15
|
+
test round trip meta model handling
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def setUp(self, debug=False, profile=True):
|
|
19
|
+
"""
|
|
20
|
+
setUp
|
|
21
|
+
"""
|
|
22
|
+
BaseMediawikiTest.setUp(self, debug=debug, profile=profile)
|
|
23
|
+
for wikiId in ["wiki"]:
|
|
24
|
+
self.getSMWAccess(wikiId, save=True)
|
|
25
|
+
|
|
26
|
+
def testSMW_Type(self):
|
|
27
|
+
"""
|
|
28
|
+
test SMW_Type handling
|
|
29
|
+
"""
|
|
30
|
+
debug = self.debug
|
|
31
|
+
smwAccess = self.smwAccessMap["wiki"]
|
|
32
|
+
ask_query = SMW_Type.askQuery()
|
|
33
|
+
did = smwAccess.smw.query(ask_query)
|
|
34
|
+
for record in did.values():
|
|
35
|
+
smw_type = SMW_Type.from_dict(record) # @UndefinedVariable
|
|
36
|
+
if debug:
|
|
37
|
+
print(smw_type)
|
|
38
|
+
self.assertIsInstance(smw_type, SMW_Type)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class TestTopic(Basetest):
|
|
42
|
+
"""
|
|
43
|
+
test Topic methods - see https://github.com/WolfgangFahl/pyMetaModel/issues/36
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
def test_get_primary_key_property(self):
|
|
47
|
+
"""test get_primary_key_property returns the primaryKey property or None"""
|
|
48
|
+
topic = Topic()
|
|
49
|
+
topic.properties = {
|
|
50
|
+
"name": Property(name="name", primaryKey=True),
|
|
51
|
+
"at": Property(name="at"),
|
|
52
|
+
}
|
|
53
|
+
pk = topic.get_primary_key_property()
|
|
54
|
+
self.assertIsNotNone(pk)
|
|
55
|
+
self.assertEqual(pk.name, "name")
|
|
56
|
+
|
|
57
|
+
def test_get_primary_key_property_none(self):
|
|
58
|
+
"""test get_primary_key_property returns None when no primaryKey exists"""
|
|
59
|
+
topic = Topic()
|
|
60
|
+
topic.properties = {"at": Property(name="at")}
|
|
61
|
+
self.assertIsNone(topic.get_primary_key_property())
|
|
62
|
+
|
|
63
|
+
def test_pluralName_from_wiki(self):
|
|
64
|
+
"""test that pluralName loaded from SiDIF is used, not the default fallback
|
|
65
|
+
see https://github.com/WolfgangFahl/pyMetaModel/issues/37
|
|
66
|
+
"""
|
|
67
|
+
topic = Topic()
|
|
68
|
+
topic.name = "Property"
|
|
69
|
+
topic.pluralName = "Properties"
|
|
70
|
+
pluralName = topic.getPluralName()
|
|
71
|
+
self.assertEqual(pluralName, "Properties")
|
|
72
|
+
|
|
73
|
+
def test_pluralName_default_fallback(self):
|
|
74
|
+
"""test that getPluralName falls back to name+s when pluralName not set
|
|
75
|
+
see https://github.com/WolfgangFahl/pyMetaModel/issues/37
|
|
76
|
+
"""
|
|
77
|
+
topic = Topic()
|
|
78
|
+
topic.name = "Topic"
|
|
79
|
+
topic.sanitize()
|
|
80
|
+
pluralName = topic.getPluralName()
|
|
81
|
+
self.assertEqual(pluralName, "Topics")
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.6.6"
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Created on 2023-02-25
|
|
3
|
-
|
|
4
|
-
@author: wf
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from meta.smw_type import SMW_Type
|
|
8
|
-
from tests.basemwtest import BaseMediawikiTest
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class TestMetaModel(BaseMediawikiTest):
|
|
12
|
-
"""
|
|
13
|
-
test round trip meta model handling
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
def setUp(self, debug=False, profile=True):
|
|
17
|
-
"""
|
|
18
|
-
setUp
|
|
19
|
-
"""
|
|
20
|
-
BaseMediawikiTest.setUp(self, debug=debug, profile=profile)
|
|
21
|
-
for wikiId in ["wiki"]:
|
|
22
|
-
self.getSMWAccess(wikiId, save=True)
|
|
23
|
-
|
|
24
|
-
def testSMW_Type(self):
|
|
25
|
-
"""
|
|
26
|
-
test SMW_Type handling
|
|
27
|
-
"""
|
|
28
|
-
debug = self.debug
|
|
29
|
-
smwAccess = self.smwAccessMap["wiki"]
|
|
30
|
-
ask_query = SMW_Type.askQuery()
|
|
31
|
-
did = smwAccess.smw.query(ask_query)
|
|
32
|
-
for record in did.values():
|
|
33
|
-
smw_type = SMW_Type.from_dict(record) # @UndefinedVariable
|
|
34
|
-
if debug:
|
|
35
|
-
print(smw_type)
|
|
36
|
-
self.assertIsInstance(smw_type, SMW_Type)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/scientific-events/scientific-events.mermaid
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pymetamodel-0.6.6 → pymetamodel-0.6.9}/examples/scientific-events/scientific-events_puml.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|