drb 2.7.0__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.
- {drb-2.7.0/drb.egg-info → drb-2.7.2}/PKG-INFO +1 -1
- {drb-2.7.0 → drb-2.7.2}/drb/core/_version.py +3 -3
- drb-2.7.2/drb/drivers/xml/factory.py +39 -0
- {drb-2.7.0 → drb-2.7.2}/drb/topics/dao/manager_dao.py +29 -25
- {drb-2.7.0 → drb-2.7.2}/drb/xquery/drb_xquery_res_to_string.py +1 -1
- {drb-2.7.0 → drb-2.7.2/drb.egg-info}/PKG-INFO +1 -1
- {drb-2.7.0 → drb-2.7.2}/drb.egg-info/SOURCES.txt +1 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_factory.py +6 -1
- {drb-2.7.0 → drb-2.7.2}/tests/test_implementation_coupling.py +1 -1
- drb-2.7.2/tests/test_topic_merge_crosspackage.py +62 -0
- drb-2.7.0/drb/drivers/xml/factory.py +0 -27
- {drb-2.7.0 → drb-2.7.2}/LICENCE.txt +0 -0
- {drb-2.7.0 → drb-2.7.2}/MANIFEST.in +0 -0
- {drb-2.7.0 → drb-2.7.2}/README.md +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/addons/addon.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/core/__init__.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/core/auth.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/core/context.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/core/cortex_validator.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/core/events.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/core/factory.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/core/impls.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/core/item.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/core/node.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/core/path.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/core/predicate.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/core/signature.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/drivers/file/__init__.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/drivers/file/cortex.ttl +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/drivers/file/file.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/drivers/xml/__init__.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/drivers/xml/cortex.ttl +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/drivers/xml/node.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/exceptions/core.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/exceptions/file.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/keyring/bitwarden/__init__.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/keyring/bitwarden/bitwarden.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/nodes/abstract_node.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/nodes/logical_node.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/nodes/mutable_node.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/nodes/url_node.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/signatures/core.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/signatures/hierarchy.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/signatures/xquery.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/topics/dao/__init__.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/topics/dao/rdf_dao.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/topics/dao/topic_dao.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/topics/dao/topic_schema.yml +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/topics/dao/xml_dao.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/topics/file/__init__.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/topics/file/cortex.ttl +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/topics/resolver.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/topics/topic.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/topics/xml/__init__.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/topics/xml/cortex.ttl +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/utils/__init__.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/utils/drb_python_script.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/utils/io.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/utils/plugins.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/utils/url_security.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/utils/utils.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/xquery/XQueryLexer.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/xquery/XQueryParser.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/xquery/XQueryParserListener.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/xquery/XQueryParserVisitor.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/xquery/__init__.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/xquery/drb_xquery.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/xquery/drb_xquery_cmd.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/xquery/drb_xquery_context.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/xquery/drb_xquery_func.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/xquery/drb_xquery_item.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/xquery/drb_xquery_utils.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/xquery/drb_xquery_variable.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/xquery/drb_xquery_visitor.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb/xquery/exceptions.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb.egg-info/dependency_links.txt +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb.egg-info/entry_points.txt +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb.egg-info/not-zip-safe +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb.egg-info/requires.txt +0 -0
- {drb-2.7.0 → drb-2.7.2}/drb.egg-info/top_level.txt +0 -0
- {drb-2.7.0 → drb-2.7.2}/pyproject.toml +0 -0
- {drb-2.7.0 → drb-2.7.2}/requirements.txt +0 -0
- {drb-2.7.0 → drb-2.7.2}/setup.cfg +0 -0
- {drb-2.7.0 → drb-2.7.2}/setup.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_abstract_node.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_addon.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_auth.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_children_unresolved.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_core_topic_ttl.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_cortex_validator.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_drb_node_list.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_drb_python_script.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_event.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_factory_resolver.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_finest_multiparent.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_implementation_manager.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_keyring_bitwarden.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_logical_node.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_manager_dao.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_manager_get_dao.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_node_context.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_node_context_manager.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_node_descendant.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_path.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_protocol_dispatch.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_rdf_dao.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_rdf_dao_multi_url.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_rdf_dao_scheme.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_rdf_dao_signatures.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_resolver_auth.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_resolver_format_alias.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_resolver_implicit_file.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_resolver_recursion_guard.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_scheme_force_impl.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_scheme_force_url.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_signature_duplicate_warning.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_signature_exact.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_signature_hierarchy.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_signature_inline_flags.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_signatures.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_topic.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_topic_descriptor_discovery.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_url_node.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_url_security.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_xml_dao.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/tests/test_xml_xquery_import_order.py +0 -0
- {drb-2.7.0 → drb-2.7.2}/versioneer.py +0 -0
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2026-07-
|
|
11
|
+
"date": "2026-07-07T13:58:00+0000",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "2.7.
|
|
14
|
+
"full-revisionid": "0ca7a30d2606890cfee27aa9c615247cf1a7be67",
|
|
15
|
+
"version": "2.7.2"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from drb.core.node import DrbNode
|
|
2
|
+
from drb.nodes.logical_node import DrbLogicalNode
|
|
3
|
+
from drb.core.factory import DrbFactory
|
|
4
|
+
from drb.exceptions.core import DrbFactoryException
|
|
5
|
+
from .node import XmlBaseNode, XmlNode
|
|
6
|
+
from io import BufferedIOBase, StringIO
|
|
7
|
+
from typing import Union
|
|
8
|
+
from xml.etree.ElementTree import ParseError
|
|
9
|
+
import os
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class XmlNodeFactory(DrbFactory):
|
|
13
|
+
def _create(self, node: DrbNode) -> DrbNode:
|
|
14
|
+
if isinstance(node, XmlNode):
|
|
15
|
+
return node
|
|
16
|
+
if node.has_impl(BufferedIOBase):
|
|
17
|
+
try:
|
|
18
|
+
return XmlBaseNode(node, node.get_impl(BufferedIOBase))
|
|
19
|
+
except ParseError as ex:
|
|
20
|
+
# The node was matched as XML (e.g. by a .xml name) but its
|
|
21
|
+
# content is not well-formed. Surface this as a factory
|
|
22
|
+
# failure so the resolver falls back to the raw node instead
|
|
23
|
+
# of aborting a whole listing on a single bad file.
|
|
24
|
+
raise DrbFactoryException(
|
|
25
|
+
f'Not well-formed XML: {node.name}') from ex
|
|
26
|
+
raise DrbFactoryException(f'Invalid node: {type(node)}')
|
|
27
|
+
|
|
28
|
+
def create(self, source: Union[DrbNode, str]) -> DrbNode:
|
|
29
|
+
if isinstance(source, str):
|
|
30
|
+
base_node = DrbLogicalNode("/")
|
|
31
|
+
try:
|
|
32
|
+
if os.path.exists(source):
|
|
33
|
+
return XmlBaseNode(base_node, source)[0]
|
|
34
|
+
return XmlBaseNode(base_node, StringIO(source))[0]
|
|
35
|
+
except ParseError as ex:
|
|
36
|
+
raise DrbFactoryException('Not well-formed XML') from ex
|
|
37
|
+
elif isinstance(source, DrbNode):
|
|
38
|
+
return self._create(source)
|
|
39
|
+
raise DrbFactoryException(f'Invalid parameter type: {type(source)}')
|
|
@@ -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
|
|
|
@@ -32,7 +32,7 @@ class XQueryResToString:
|
|
|
32
32
|
prefix = 'ns' + str(index_ns)
|
|
33
33
|
|
|
34
34
|
dynamic_context.add_namespace(static_context=context,
|
|
35
|
-
prefix=
|
|
35
|
+
prefix=prefix,
|
|
36
36
|
namespace_full=namespace_uri)
|
|
37
37
|
if prefix is None or len(prefix) == 0:
|
|
38
38
|
namespace_def = ' xmlns' + '="' \
|
|
@@ -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
|
|
@@ -44,7 +44,12 @@ class TestFactoryLoader(unittest.TestCase):
|
|
|
44
44
|
'zip',
|
|
45
45
|
]
|
|
46
46
|
factories = loader.get_factories()
|
|
47
|
-
|
|
47
|
+
# The test mock distribution declares 13 ``drb.driver`` entry points.
|
|
48
|
+
# Assert that baseline is present without pinning an exact total: a
|
|
49
|
+
# venv with extra ``drb-driver-*`` packages installed (http, swift,
|
|
50
|
+
# webdav, ...) legitimately loads more factories, and an exact-count
|
|
51
|
+
# assertion would spuriously fail there (drb-testbench).
|
|
52
|
+
self.assertGreaterEqual(len(factories), 13)
|
|
48
53
|
expected = all(
|
|
49
54
|
map(
|
|
50
55
|
lambda x: isinstance(x, DrbFactory),
|
|
@@ -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
|
|
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()
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
from drb.core.node import DrbNode
|
|
2
|
-
from drb.nodes.logical_node import DrbLogicalNode
|
|
3
|
-
from drb.core.factory import DrbFactory
|
|
4
|
-
from drb.exceptions.core import DrbFactoryException
|
|
5
|
-
from .node import XmlBaseNode, XmlNode
|
|
6
|
-
from io import BufferedIOBase, StringIO
|
|
7
|
-
from typing import Union
|
|
8
|
-
import os
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class XmlNodeFactory(DrbFactory):
|
|
12
|
-
def _create(self, node: DrbNode) -> DrbNode:
|
|
13
|
-
if isinstance(node, XmlNode):
|
|
14
|
-
return node
|
|
15
|
-
if node.has_impl(BufferedIOBase):
|
|
16
|
-
return XmlBaseNode(node, node.get_impl(BufferedIOBase))
|
|
17
|
-
raise DrbFactoryException(f'Invalid node: {type(node)}')
|
|
18
|
-
|
|
19
|
-
def create(self, source: Union[DrbNode, str]) -> DrbNode:
|
|
20
|
-
if isinstance(source, str):
|
|
21
|
-
base_node = DrbLogicalNode("/")
|
|
22
|
-
if os.path.exists(source):
|
|
23
|
-
return XmlBaseNode(base_node, source)[0]
|
|
24
|
-
return XmlBaseNode(base_node, StringIO(source))[0]
|
|
25
|
-
elif isinstance(source, DrbNode):
|
|
26
|
-
return self._create(source)
|
|
27
|
-
raise DrbFactoryException(f'Invalid parameter type: {type(source)}')
|
|
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
|
{drb-2.7.0 → drb-2.7.2}/setup.py
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
|