drb 2.7.1__tar.gz → 2.7.2__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.
Files changed (126) hide show
  1. {drb-2.7.1/drb.egg-info → drb-2.7.2}/PKG-INFO +1 -1
  2. {drb-2.7.1 → drb-2.7.2}/drb/core/_version.py +3 -3
  3. {drb-2.7.1 → drb-2.7.2}/drb/topics/dao/manager_dao.py +29 -25
  4. {drb-2.7.1 → drb-2.7.2/drb.egg-info}/PKG-INFO +1 -1
  5. {drb-2.7.1 → drb-2.7.2}/drb.egg-info/SOURCES.txt +1 -0
  6. {drb-2.7.1 → drb-2.7.2}/tests/test_implementation_coupling.py +1 -1
  7. drb-2.7.2/tests/test_topic_merge_crosspackage.py +62 -0
  8. {drb-2.7.1 → drb-2.7.2}/LICENCE.txt +0 -0
  9. {drb-2.7.1 → drb-2.7.2}/MANIFEST.in +0 -0
  10. {drb-2.7.1 → drb-2.7.2}/README.md +0 -0
  11. {drb-2.7.1 → drb-2.7.2}/drb/addons/addon.py +0 -0
  12. {drb-2.7.1 → drb-2.7.2}/drb/core/__init__.py +0 -0
  13. {drb-2.7.1 → drb-2.7.2}/drb/core/auth.py +0 -0
  14. {drb-2.7.1 → drb-2.7.2}/drb/core/context.py +0 -0
  15. {drb-2.7.1 → drb-2.7.2}/drb/core/cortex_validator.py +0 -0
  16. {drb-2.7.1 → drb-2.7.2}/drb/core/events.py +0 -0
  17. {drb-2.7.1 → drb-2.7.2}/drb/core/factory.py +0 -0
  18. {drb-2.7.1 → drb-2.7.2}/drb/core/impls.py +0 -0
  19. {drb-2.7.1 → drb-2.7.2}/drb/core/item.py +0 -0
  20. {drb-2.7.1 → drb-2.7.2}/drb/core/node.py +0 -0
  21. {drb-2.7.1 → drb-2.7.2}/drb/core/path.py +0 -0
  22. {drb-2.7.1 → drb-2.7.2}/drb/core/predicate.py +0 -0
  23. {drb-2.7.1 → drb-2.7.2}/drb/core/signature.py +0 -0
  24. {drb-2.7.1 → drb-2.7.2}/drb/drivers/file/__init__.py +0 -0
  25. {drb-2.7.1 → drb-2.7.2}/drb/drivers/file/cortex.ttl +0 -0
  26. {drb-2.7.1 → drb-2.7.2}/drb/drivers/file/file.py +0 -0
  27. {drb-2.7.1 → drb-2.7.2}/drb/drivers/xml/__init__.py +0 -0
  28. {drb-2.7.1 → drb-2.7.2}/drb/drivers/xml/cortex.ttl +0 -0
  29. {drb-2.7.1 → drb-2.7.2}/drb/drivers/xml/factory.py +0 -0
  30. {drb-2.7.1 → drb-2.7.2}/drb/drivers/xml/node.py +0 -0
  31. {drb-2.7.1 → drb-2.7.2}/drb/exceptions/core.py +0 -0
  32. {drb-2.7.1 → drb-2.7.2}/drb/exceptions/file.py +0 -0
  33. {drb-2.7.1 → drb-2.7.2}/drb/keyring/bitwarden/__init__.py +0 -0
  34. {drb-2.7.1 → drb-2.7.2}/drb/keyring/bitwarden/bitwarden.py +0 -0
  35. {drb-2.7.1 → drb-2.7.2}/drb/nodes/abstract_node.py +0 -0
  36. {drb-2.7.1 → drb-2.7.2}/drb/nodes/logical_node.py +0 -0
  37. {drb-2.7.1 → drb-2.7.2}/drb/nodes/mutable_node.py +0 -0
  38. {drb-2.7.1 → drb-2.7.2}/drb/nodes/url_node.py +0 -0
  39. {drb-2.7.1 → drb-2.7.2}/drb/signatures/core.py +0 -0
  40. {drb-2.7.1 → drb-2.7.2}/drb/signatures/hierarchy.py +0 -0
  41. {drb-2.7.1 → drb-2.7.2}/drb/signatures/xquery.py +0 -0
  42. {drb-2.7.1 → drb-2.7.2}/drb/topics/dao/__init__.py +0 -0
  43. {drb-2.7.1 → drb-2.7.2}/drb/topics/dao/rdf_dao.py +0 -0
  44. {drb-2.7.1 → drb-2.7.2}/drb/topics/dao/topic_dao.py +0 -0
  45. {drb-2.7.1 → drb-2.7.2}/drb/topics/dao/topic_schema.yml +0 -0
  46. {drb-2.7.1 → drb-2.7.2}/drb/topics/dao/xml_dao.py +0 -0
  47. {drb-2.7.1 → drb-2.7.2}/drb/topics/file/__init__.py +0 -0
  48. {drb-2.7.1 → drb-2.7.2}/drb/topics/file/cortex.ttl +0 -0
  49. {drb-2.7.1 → drb-2.7.2}/drb/topics/resolver.py +0 -0
  50. {drb-2.7.1 → drb-2.7.2}/drb/topics/topic.py +0 -0
  51. {drb-2.7.1 → drb-2.7.2}/drb/topics/xml/__init__.py +0 -0
  52. {drb-2.7.1 → drb-2.7.2}/drb/topics/xml/cortex.ttl +0 -0
  53. {drb-2.7.1 → drb-2.7.2}/drb/utils/__init__.py +0 -0
  54. {drb-2.7.1 → drb-2.7.2}/drb/utils/drb_python_script.py +0 -0
  55. {drb-2.7.1 → drb-2.7.2}/drb/utils/io.py +0 -0
  56. {drb-2.7.1 → drb-2.7.2}/drb/utils/plugins.py +0 -0
  57. {drb-2.7.1 → drb-2.7.2}/drb/utils/url_security.py +0 -0
  58. {drb-2.7.1 → drb-2.7.2}/drb/utils/utils.py +0 -0
  59. {drb-2.7.1 → drb-2.7.2}/drb/xquery/XQueryLexer.py +0 -0
  60. {drb-2.7.1 → drb-2.7.2}/drb/xquery/XQueryParser.py +0 -0
  61. {drb-2.7.1 → drb-2.7.2}/drb/xquery/XQueryParserListener.py +0 -0
  62. {drb-2.7.1 → drb-2.7.2}/drb/xquery/XQueryParserVisitor.py +0 -0
  63. {drb-2.7.1 → drb-2.7.2}/drb/xquery/__init__.py +0 -0
  64. {drb-2.7.1 → drb-2.7.2}/drb/xquery/drb_xquery.py +0 -0
  65. {drb-2.7.1 → drb-2.7.2}/drb/xquery/drb_xquery_cmd.py +0 -0
  66. {drb-2.7.1 → drb-2.7.2}/drb/xquery/drb_xquery_context.py +0 -0
  67. {drb-2.7.1 → drb-2.7.2}/drb/xquery/drb_xquery_func.py +0 -0
  68. {drb-2.7.1 → drb-2.7.2}/drb/xquery/drb_xquery_item.py +0 -0
  69. {drb-2.7.1 → drb-2.7.2}/drb/xquery/drb_xquery_res_to_string.py +0 -0
  70. {drb-2.7.1 → drb-2.7.2}/drb/xquery/drb_xquery_utils.py +0 -0
  71. {drb-2.7.1 → drb-2.7.2}/drb/xquery/drb_xquery_variable.py +0 -0
  72. {drb-2.7.1 → drb-2.7.2}/drb/xquery/drb_xquery_visitor.py +0 -0
  73. {drb-2.7.1 → drb-2.7.2}/drb/xquery/exceptions.py +0 -0
  74. {drb-2.7.1 → drb-2.7.2}/drb.egg-info/dependency_links.txt +0 -0
  75. {drb-2.7.1 → drb-2.7.2}/drb.egg-info/entry_points.txt +0 -0
  76. {drb-2.7.1 → drb-2.7.2}/drb.egg-info/not-zip-safe +0 -0
  77. {drb-2.7.1 → drb-2.7.2}/drb.egg-info/requires.txt +0 -0
  78. {drb-2.7.1 → drb-2.7.2}/drb.egg-info/top_level.txt +0 -0
  79. {drb-2.7.1 → drb-2.7.2}/pyproject.toml +0 -0
  80. {drb-2.7.1 → drb-2.7.2}/requirements.txt +0 -0
  81. {drb-2.7.1 → drb-2.7.2}/setup.cfg +0 -0
  82. {drb-2.7.1 → drb-2.7.2}/setup.py +0 -0
  83. {drb-2.7.1 → drb-2.7.2}/tests/test_abstract_node.py +0 -0
  84. {drb-2.7.1 → drb-2.7.2}/tests/test_addon.py +0 -0
  85. {drb-2.7.1 → drb-2.7.2}/tests/test_auth.py +0 -0
  86. {drb-2.7.1 → drb-2.7.2}/tests/test_children_unresolved.py +0 -0
  87. {drb-2.7.1 → drb-2.7.2}/tests/test_core_topic_ttl.py +0 -0
  88. {drb-2.7.1 → drb-2.7.2}/tests/test_cortex_validator.py +0 -0
  89. {drb-2.7.1 → drb-2.7.2}/tests/test_drb_node_list.py +0 -0
  90. {drb-2.7.1 → drb-2.7.2}/tests/test_drb_python_script.py +0 -0
  91. {drb-2.7.1 → drb-2.7.2}/tests/test_event.py +0 -0
  92. {drb-2.7.1 → drb-2.7.2}/tests/test_factory.py +0 -0
  93. {drb-2.7.1 → drb-2.7.2}/tests/test_factory_resolver.py +0 -0
  94. {drb-2.7.1 → drb-2.7.2}/tests/test_finest_multiparent.py +0 -0
  95. {drb-2.7.1 → drb-2.7.2}/tests/test_implementation_manager.py +0 -0
  96. {drb-2.7.1 → drb-2.7.2}/tests/test_keyring_bitwarden.py +0 -0
  97. {drb-2.7.1 → drb-2.7.2}/tests/test_logical_node.py +0 -0
  98. {drb-2.7.1 → drb-2.7.2}/tests/test_manager_dao.py +0 -0
  99. {drb-2.7.1 → drb-2.7.2}/tests/test_manager_get_dao.py +0 -0
  100. {drb-2.7.1 → drb-2.7.2}/tests/test_node_context.py +0 -0
  101. {drb-2.7.1 → drb-2.7.2}/tests/test_node_context_manager.py +0 -0
  102. {drb-2.7.1 → drb-2.7.2}/tests/test_node_descendant.py +0 -0
  103. {drb-2.7.1 → drb-2.7.2}/tests/test_path.py +0 -0
  104. {drb-2.7.1 → drb-2.7.2}/tests/test_protocol_dispatch.py +0 -0
  105. {drb-2.7.1 → drb-2.7.2}/tests/test_rdf_dao.py +0 -0
  106. {drb-2.7.1 → drb-2.7.2}/tests/test_rdf_dao_multi_url.py +0 -0
  107. {drb-2.7.1 → drb-2.7.2}/tests/test_rdf_dao_scheme.py +0 -0
  108. {drb-2.7.1 → drb-2.7.2}/tests/test_rdf_dao_signatures.py +0 -0
  109. {drb-2.7.1 → drb-2.7.2}/tests/test_resolver_auth.py +0 -0
  110. {drb-2.7.1 → drb-2.7.2}/tests/test_resolver_format_alias.py +0 -0
  111. {drb-2.7.1 → drb-2.7.2}/tests/test_resolver_implicit_file.py +0 -0
  112. {drb-2.7.1 → drb-2.7.2}/tests/test_resolver_recursion_guard.py +0 -0
  113. {drb-2.7.1 → drb-2.7.2}/tests/test_scheme_force_impl.py +0 -0
  114. {drb-2.7.1 → drb-2.7.2}/tests/test_scheme_force_url.py +0 -0
  115. {drb-2.7.1 → drb-2.7.2}/tests/test_signature_duplicate_warning.py +0 -0
  116. {drb-2.7.1 → drb-2.7.2}/tests/test_signature_exact.py +0 -0
  117. {drb-2.7.1 → drb-2.7.2}/tests/test_signature_hierarchy.py +0 -0
  118. {drb-2.7.1 → drb-2.7.2}/tests/test_signature_inline_flags.py +0 -0
  119. {drb-2.7.1 → drb-2.7.2}/tests/test_signatures.py +0 -0
  120. {drb-2.7.1 → drb-2.7.2}/tests/test_topic.py +0 -0
  121. {drb-2.7.1 → drb-2.7.2}/tests/test_topic_descriptor_discovery.py +0 -0
  122. {drb-2.7.1 → drb-2.7.2}/tests/test_url_node.py +0 -0
  123. {drb-2.7.1 → drb-2.7.2}/tests/test_url_security.py +0 -0
  124. {drb-2.7.1 → drb-2.7.2}/tests/test_xml_dao.py +0 -0
  125. {drb-2.7.1 → drb-2.7.2}/tests/test_xml_xquery_import_order.py +0 -0
  126. {drb-2.7.1 → drb-2.7.2}/versioneer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drb
3
- Version: 2.7.1
3
+ Version: 2.7.2
4
4
  Summary: Data Request Broker
5
5
  Author: GAEL Systems
6
6
  Author-email: drb-python@gael.fr
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2026-07-06T11:05:37+0000",
11
+ "date": "2026-07-07T13:58:00+0000",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "0338f29e3674f5a414b3d7134870f85a717e9cb3",
15
- "version": "2.7.1"
14
+ "full-revisionid": "0ca7a30d2606890cfee27aa9c615247cf1a7be67",
15
+ "version": "2.7.2"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -55,13 +55,20 @@ def _implementation_available(topic: DrbTopic) -> bool:
55
55
 
56
56
  def _load_all_drb_topic_dao() -> Dict[uuid.UUID, DrbTopicDao]:
57
57
  """
58
- Loads topics defined in the Python context
58
+ Loads topics defined in the Python context.
59
+
60
+ All installed ``drb.topic`` descriptors are merged into a single RDF graph
61
+ before discovery, so a topic whose ``rdfs:subClassOf`` chain to
62
+ ``drb:item`` crosses a package/file boundary still resolves -- matching the
63
+ Java classpath, which loads every ``*-topics.ttl`` into one model. See
64
+ drb-testbench#19.
59
65
  """
60
66
  entry_point_group = 'drb.topic'
61
- result = {}
67
+ result: Dict[uuid.UUID, DrbTopicDao] = {}
62
68
 
69
+ # Collect every installed descriptor path first.
70
+ paths: List[str] = []
63
71
  for ep in drb.utils.plugins.get_entry_points(entry_point_group):
64
- # load module
65
72
  try:
66
73
  module = importlib.import_module(ep.value)
67
74
  except ModuleNotFoundError as ex:
@@ -73,29 +80,26 @@ def _load_all_drb_topic_dao() -> Dict[uuid.UUID, DrbTopicDao]:
73
80
  logger.warning(
74
81
  f'No topic descriptor (cortex.ttl/.owl) for {ep.name}')
75
82
  continue
83
+ paths.append(path)
84
+
85
+ if not paths:
86
+ return result
87
+
88
+ # One merged graph across all descriptors (cross-package resolution).
89
+ try:
90
+ dao = RDFDao(paths)
91
+ for topic in dao.read_all():
92
+ if not _implementation_available(topic):
93
+ logger.warning(
94
+ "Topic %s (%s) skipped: no installed driver "
95
+ "implementation '%s' (drb.driver). Descriptor present "
96
+ "but implementation required.",
97
+ topic.label, topic.uri, topic.factory)
98
+ continue
99
+ result[topic.id] = dao
100
+ except (FileNotFoundError, ValidationError) as ex:
101
+ logger.warning(f'Invalid topic description(s): {ex}')
76
102
 
77
- try:
78
- dao = DaoFactory().create(path)
79
- topics = dao.read_all()
80
- for topic in topics:
81
- if not _implementation_available(topic):
82
- logger.warning(
83
- "Topic %s (%s) skipped: no installed driver "
84
- "implementation '%s' (drb.driver). Descriptor present "
85
- "but implementation required.",
86
- topic.label, topic.uri, topic.factory)
87
- continue
88
- if topic.id in result:
89
- logger.warning(
90
- f'Topic definition conflict: id ({topic.id}) defined '
91
- f'in {result[topic.id]} and {dao}')
92
- else:
93
- result[topic.id] = dao
94
-
95
- except (FileNotFoundError, ValidationError) as ex:
96
- logger.warning(
97
- f'Invalid topic description(s) from {ep.name}: {ex.msg}')
98
- continue
99
103
  return result
100
104
 
101
105
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drb
3
- Version: 2.7.1
3
+ Version: 2.7.2
4
4
  Summary: Data Request Broker
5
5
  Author: GAEL Systems
6
6
  Author-email: drb-python@gael.fr
@@ -118,6 +118,7 @@ tests/test_signature_inline_flags.py
118
118
  tests/test_signatures.py
119
119
  tests/test_topic.py
120
120
  tests/test_topic_descriptor_discovery.py
121
+ tests/test_topic_merge_crosspackage.py
121
122
  tests/test_url_node.py
122
123
  tests/test_url_security.py
123
124
  tests/test_xml_dao.py
@@ -39,7 +39,7 @@ class TestLoadSkipsTopicsWithoutImplementation(unittest.TestCase):
39
39
  return_value=MagicMock(__path__=['/tmp'])), \
40
40
  patch.object(md, '_find_topic_descriptor',
41
41
  return_value='/tmp/cortex.ttl'), \
42
- patch.object(md.DaoFactory, 'create', return_value=dao):
42
+ patch.object(md, 'RDFDao', return_value=dao):
43
43
  result = md._load_all_drb_topic_dao()
44
44
  self.assertIn(present.id, result)
45
45
  self.assertNotIn(absent.id, result)
@@ -0,0 +1,62 @@
1
+ """Cross-package descriptor merge at topic discovery (drb-testbench#19).
2
+
3
+ A dependent topic whose ``rdfs:subClassOf`` chain to ``drb:item`` runs through
4
+ a parent class defined in a *separate* descriptor must still be discovered
5
+ when both descriptors are installed -- matching the Java classpath, which
6
+ merges all ``*-topics.ttl`` into one model. ``_load_all_drb_topic_dao`` now
7
+ builds a single merged ``RDFDao`` over every installed descriptor; these tests
8
+ pin the merge semantics it relies on.
9
+ """
10
+ import os
11
+ import tempfile
12
+ import unittest
13
+
14
+ from drb.topics.dao.rdf_dao import RDFDao
15
+
16
+ _PARENT_TTL = """\
17
+ @prefix owl: <http://www.w3.org/2002/07/owl#> .
18
+ @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
19
+ @prefix drb: <http://www.gael.fr/drb#> .
20
+ @prefix ex: <http://example.org/drb-test#> .
21
+
22
+ ex:parent a owl:Class ; rdfs:subClassOf drb:item ; rdfs:label "Test Parent" .
23
+ """
24
+
25
+ _CHILD_TTL = """\
26
+ @prefix owl: <http://www.w3.org/2002/07/owl#> .
27
+ @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
28
+ @prefix ex: <http://example.org/drb-test#> .
29
+
30
+ ex:child a owl:Class ; rdfs:subClassOf ex:parent ; rdfs:label "Test Child" .
31
+ """
32
+
33
+
34
+ class TestCrossPackageMerge(unittest.TestCase):
35
+ def setUp(self):
36
+ self.dir = tempfile.mkdtemp()
37
+ self.parent = os.path.join(self.dir, 'parent.ttl')
38
+ self.child = os.path.join(self.dir, 'child.ttl')
39
+ with open(self.parent, 'w') as f:
40
+ f.write(_PARENT_TTL)
41
+ with open(self.child, 'w') as f:
42
+ f.write(_CHILD_TTL)
43
+
44
+ @staticmethod
45
+ def _labels(dao):
46
+ return {t.label for t in dao.read_all()}
47
+
48
+ def test_child_absent_when_parent_in_separate_graph(self):
49
+ # Per-file: the child's chain to drb:item is broken because its parent
50
+ # lives in another descriptor -> it must NOT be discovered alone.
51
+ self.assertNotIn('Test Child', self._labels(RDFDao(self.child)))
52
+
53
+ def test_child_surfaces_when_descriptors_merged(self):
54
+ # Merged graph (what _load_all_drb_topic_dao now does): the chain
55
+ # child -> parent -> drb:item resolves, so the child is discovered.
56
+ labels = self._labels(RDFDao([self.parent, self.child]))
57
+ self.assertIn('Test Child', labels)
58
+ self.assertIn('Test Parent', labels)
59
+
60
+
61
+ if __name__ == '__main__':
62
+ unittest.main()
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
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