drb 2.4.0__tar.gz → 2.4.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.4.0/drb.egg-info → drb-2.4.2}/PKG-INFO +1 -1
- {drb-2.4.0 → drb-2.4.2}/drb/core/_version.py +3 -3
- {drb-2.4.0 → drb-2.4.2}/drb/topics/file/cortex.ttl +1 -0
- {drb-2.4.0 → drb-2.4.2}/drb/topics/resolver.py +68 -20
- {drb-2.4.0 → drb-2.4.2/drb.egg-info}/PKG-INFO +1 -1
- {drb-2.4.0 → drb-2.4.2}/drb.egg-info/SOURCES.txt +1 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_core_topic_ttl.py +8 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_protocol_dispatch.py +3 -0
- drb-2.4.2/tests/test_scheme_force_impl.py +170 -0
- {drb-2.4.0 → drb-2.4.2}/LICENCE.txt +0 -0
- {drb-2.4.0 → drb-2.4.2}/MANIFEST.in +0 -0
- {drb-2.4.0 → drb-2.4.2}/README.md +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/addons/addon.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/core/__init__.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/core/context.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/core/cortex_validator.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/core/events.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/core/factory.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/core/impls.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/core/item.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/core/node.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/core/path.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/core/predicate.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/core/signature.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/drivers/file/__init__.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/drivers/file/cortex.ttl +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/drivers/file/file.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/drivers/xml/__init__.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/drivers/xml/cortex.ttl +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/drivers/xml/factory.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/drivers/xml/node.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/exceptions/core.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/exceptions/file.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/keyring/bitwarden/__init__.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/keyring/bitwarden/bitwarden.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/nodes/abstract_node.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/nodes/logical_node.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/nodes/mutable_node.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/nodes/url_node.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/signatures/core.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/signatures/hierarchy.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/signatures/xquery.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/topics/dao/__init__.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/topics/dao/manager_dao.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/topics/dao/rdf_dao.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/topics/dao/topic_dao.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/topics/dao/topic_schema.yml +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/topics/dao/xml_dao.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/topics/file/__init__.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/topics/topic.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/topics/xml/__init__.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/topics/xml/cortex.ttl +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/utils/__init__.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/utils/drb_python_script.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/utils/plugins.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/utils/url_security.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/utils/utils.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/xquery/XQueryLexer.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/xquery/XQueryParser.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/xquery/XQueryParserListener.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/xquery/XQueryParserVisitor.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/xquery/__init__.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/xquery/drb_xquery.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/xquery/drb_xquery_cmd.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/xquery/drb_xquery_context.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/xquery/drb_xquery_func.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/xquery/drb_xquery_item.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/xquery/drb_xquery_res_to_string.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/xquery/drb_xquery_utils.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/xquery/drb_xquery_variable.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/xquery/drb_xquery_visitor.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb/xquery/exceptions.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb.egg-info/dependency_links.txt +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb.egg-info/entry_points.txt +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb.egg-info/not-zip-safe +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb.egg-info/requires.txt +0 -0
- {drb-2.4.0 → drb-2.4.2}/drb.egg-info/top_level.txt +0 -0
- {drb-2.4.0 → drb-2.4.2}/pyproject.toml +0 -0
- {drb-2.4.0 → drb-2.4.2}/requirements.txt +0 -0
- {drb-2.4.0 → drb-2.4.2}/setup.cfg +0 -0
- {drb-2.4.0 → drb-2.4.2}/setup.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_abstract_node.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_addon.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_children_unresolved.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_cortex_validator.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_drb_node_list.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_drb_python_script.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_event.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_factory.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_factory_resolver.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_implementation_coupling.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_implementation_manager.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_keyring_bitwarden.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_logical_node.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_manager_dao.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_manager_get_dao.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_node_context.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_node_descendant.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_path.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_rdf_dao.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_rdf_dao_multi_url.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_rdf_dao_scheme.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_rdf_dao_signatures.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_signature_exact.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_signature_hierarchy.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_signatures.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_topic.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_topic_descriptor_discovery.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_url_node.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_url_security.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/tests/test_xml_dao.py +0 -0
- {drb-2.4.0 → drb-2.4.2}/versioneer.py +0 -0
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2026-06-
|
|
11
|
+
"date": "2026-06-26T17:44:46+0000",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "2.4.
|
|
14
|
+
"full-revisionid": "d6abeea9ba11991cf33d5cc12fc33405c6032658",
|
|
15
|
+
"version": "2.4.2"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -8,5 +8,6 @@ drb:file
|
|
|
8
8
|
drb:category "PROTOCOL" ;
|
|
9
9
|
rdfs:subClassOf drb:item ;
|
|
10
10
|
rdfs:label "file" ;
|
|
11
|
+
drb:scheme "file" ;
|
|
11
12
|
drb:signature [ drb:pythonTest "return node.path.scheme is None or '' == node.path.scheme or 'file' == node.path.scheme" ] ;
|
|
12
13
|
drb:implementationIdentifier "file" .
|
|
@@ -53,14 +53,59 @@ def _create_via_factory(topic: DrbTopic, node: DrbNode) -> DrbNode:
|
|
|
53
53
|
|
|
54
54
|
|
|
55
55
|
def _topic_by_factory(name: str):
|
|
56
|
-
"""The
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
"""The topic (any category) whose implementationIdentifier == name.
|
|
57
|
+
|
|
58
|
+
Returns ``None`` when no topic declares that factory."""
|
|
59
|
+
for topic in ManagerDao().get_all_drb_topics():
|
|
59
60
|
if topic.factory == name:
|
|
60
61
|
return topic
|
|
61
62
|
return None
|
|
62
63
|
|
|
63
64
|
|
|
65
|
+
def _topic_by_scheme_any(scheme: str):
|
|
66
|
+
"""The topic (any category) declaring ``scheme`` in its ``drb:scheme``.
|
|
67
|
+
|
|
68
|
+
Unlike :func:`_topic_by_scheme` (PROTOCOL-only, for transport detection),
|
|
69
|
+
this searches every category so a forced token can resolve to a
|
|
70
|
+
CONTAINER/FORMATTING topic. Raises :class:`DrbFactoryException` when two
|
|
71
|
+
distinct topics declare the same scheme (ambiguity)."""
|
|
72
|
+
matches = [t for t in ManagerDao().get_all_drb_topics()
|
|
73
|
+
if scheme in (t.scheme or [])]
|
|
74
|
+
if len(matches) > 1:
|
|
75
|
+
raise DrbFactoryException(
|
|
76
|
+
f'Ambiguous scheme token "{scheme}": '
|
|
77
|
+
f'{[getattr(t, "label", t) for t in matches]}')
|
|
78
|
+
return matches[0] if matches else None
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _resolve_token(token: str):
|
|
82
|
+
"""Resolve a forced scheme token to ``(topic, factory)``.
|
|
83
|
+
|
|
84
|
+
Primary: a topic declaring ``token`` in ``drb:scheme`` (any category),
|
|
85
|
+
with its installed factory. Fallback: ``token`` as a driver entry-point
|
|
86
|
+
name (topic via :func:`_topic_by_factory`). Raises
|
|
87
|
+
:class:`DrbFactoryException` when neither resolves or the matched topic's
|
|
88
|
+
factory is not installed."""
|
|
89
|
+
topic = _topic_by_scheme_any(token)
|
|
90
|
+
if topic is not None:
|
|
91
|
+
factory = FactoryLoader().get_factory(topic.factory)
|
|
92
|
+
if factory is None:
|
|
93
|
+
raise DrbFactoryException(
|
|
94
|
+
f"No driver implementation '{topic.factory}' installed for "
|
|
95
|
+
f'forced scheme token "{token}"')
|
|
96
|
+
return topic, factory
|
|
97
|
+
factory = FactoryLoader().get_factory(token)
|
|
98
|
+
if factory is None:
|
|
99
|
+
raise DrbFactoryException(
|
|
100
|
+
f'No driver registered for forced scheme "+{token}"')
|
|
101
|
+
topic = _topic_by_factory(token)
|
|
102
|
+
if topic is None:
|
|
103
|
+
raise DrbFactoryException(
|
|
104
|
+
f'Driver "{token}" is registered but declares no topic; '
|
|
105
|
+
f'cannot classify forced scheme token')
|
|
106
|
+
return topic, factory
|
|
107
|
+
|
|
108
|
+
|
|
64
109
|
def _topic_by_scheme(scheme: str):
|
|
65
110
|
"""The PROTOCOL topic declaring this scheme (drb:scheme), or None."""
|
|
66
111
|
for topic in ManagerDao().get_drb_topics_by_category(
|
|
@@ -107,35 +152,38 @@ class _DrbFactoryResolver(DrbFactory):
|
|
|
107
152
|
return None
|
|
108
153
|
|
|
109
154
|
def __dispatch_scheme(self, node):
|
|
110
|
-
"""Dispatch a root URL by drb:scheme, then apply
|
|
111
|
-
|
|
112
|
-
topic declares the base scheme or its factory is not
|
|
113
|
-
(caller falls back to signature matching).
|
|
155
|
+
"""Dispatch a root URL by drb:scheme, then apply an ordered stack of
|
|
156
|
+
+<token> forced drivers. Returns (topic, node), or None when no
|
|
157
|
+
PROTOCOL topic declares the base scheme or its factory is not
|
|
158
|
+
installed (caller falls back to signature matching). Raises on an
|
|
159
|
+
empty scheme segment."""
|
|
114
160
|
scheme = node.path.scheme
|
|
115
161
|
if not scheme:
|
|
116
162
|
return None
|
|
117
|
-
parts = scheme.split('+'
|
|
163
|
+
parts = scheme.split('+')
|
|
118
164
|
base = parts[0]
|
|
119
|
-
|
|
165
|
+
tokens = parts[1:]
|
|
166
|
+
if base == '' or any(t == '' for t in tokens):
|
|
167
|
+
raise DrbFactoryException(
|
|
168
|
+
f'Invalid scheme "{scheme}": empty segment')
|
|
120
169
|
base_topic = _topic_by_scheme(base)
|
|
121
170
|
if base_topic is None:
|
|
122
171
|
return None
|
|
123
172
|
base_factory = FactoryLoader().get_factory(base_topic.factory)
|
|
124
173
|
if base_factory is None:
|
|
125
174
|
return None
|
|
126
|
-
if
|
|
127
|
-
# Strip
|
|
128
|
-
# <base>:// URL (
|
|
129
|
-
clean_url = base + node.path.name[len(
|
|
175
|
+
if tokens:
|
|
176
|
+
# Strip every +token so the base factory receives a clean
|
|
177
|
+
# <base>:// URL (https+odata+xml://h/x -> https://h/x).
|
|
178
|
+
clean_url = base + node.path.name[len(scheme):]
|
|
130
179
|
node = UrlNode(clean_url)
|
|
131
180
|
created = base_factory.create(node)
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
return _topic_by_factory(forced), forced_factory.create(created)
|
|
181
|
+
topic = base_topic
|
|
182
|
+
for token in tokens:
|
|
183
|
+
token_topic, token_factory = _resolve_token(token)
|
|
184
|
+
created = token_factory.create(created)
|
|
185
|
+
topic = token_topic
|
|
186
|
+
return topic, created
|
|
139
187
|
|
|
140
188
|
def __retrieve_container(
|
|
141
189
|
self, node: DrbNode) -> Tuple[Optional[DrbTopic], DrbNode]:
|
|
@@ -100,6 +100,7 @@ tests/test_rdf_dao.py
|
|
|
100
100
|
tests/test_rdf_dao_multi_url.py
|
|
101
101
|
tests/test_rdf_dao_scheme.py
|
|
102
102
|
tests/test_rdf_dao_signatures.py
|
|
103
|
+
tests/test_scheme_force_impl.py
|
|
103
104
|
tests/test_signature_exact.py
|
|
104
105
|
tests/test_signature_hierarchy.py
|
|
105
106
|
tests/test_signatures.py
|
|
@@ -40,3 +40,11 @@ class TestCoreTopicTtl(unittest.TestCase):
|
|
|
40
40
|
self.assertTrue(any(s.matches(_Node(scheme='')) for s in sigs))
|
|
41
41
|
self.assertTrue(any(s.matches(_Node(scheme=None)) for s in sigs))
|
|
42
42
|
self.assertFalse(any(s.matches(_Node(scheme='http')) for s in sigs))
|
|
43
|
+
|
|
44
|
+
def test_file_topic_declares_file_scheme(self):
|
|
45
|
+
# drb:scheme "file" makes 'file' a routable base scheme for the
|
|
46
|
+
# dispatcher, enabling forced drivers such as ``file+zip://`` on
|
|
47
|
+
# paths whose extension does not match the container signature.
|
|
48
|
+
dao = RDFDao(_FILE_TTL)
|
|
49
|
+
topic = next(t for t in dao.read_all() if t.label == 'file')
|
|
50
|
+
self.assertEqual(['file'], topic.scheme)
|
|
@@ -89,6 +89,7 @@ class TestSchemeDispatch(unittest.TestCase):
|
|
|
89
89
|
patch.object(resolver_mod, '_topic_by_factory',
|
|
90
90
|
return_value=forced):
|
|
91
91
|
md.return_value.get_drb_topics_by_category.return_value = [base]
|
|
92
|
+
md.return_value.get_all_drb_topics.return_value = [base]
|
|
92
93
|
facs = {'http': _BaseFactory(), 'odata': _ForcedFactory()}
|
|
93
94
|
gf.side_effect = lambda name: facs.get(name)
|
|
94
95
|
t, n = r._DrbFactoryResolver__dispatch_scheme(
|
|
@@ -104,6 +105,7 @@ class TestSchemeDispatch(unittest.TestCase):
|
|
|
104
105
|
with patch.object(resolver_mod, 'ManagerDao') as md, \
|
|
105
106
|
patch.object(resolver_mod.FactoryLoader, 'get_factory') as gf:
|
|
106
107
|
md.return_value.get_drb_topics_by_category.return_value = [base]
|
|
108
|
+
md.return_value.get_all_drb_topics.return_value = [base]
|
|
107
109
|
gf.side_effect = lambda name: (
|
|
108
110
|
{'http': _BaseFactory()}).get(name)
|
|
109
111
|
with self.assertRaises(DrbFactoryException):
|
|
@@ -121,6 +123,7 @@ class TestSchemeDispatch(unittest.TestCase):
|
|
|
121
123
|
patch.object(resolver_mod, '_topic_by_factory',
|
|
122
124
|
return_value=forced_topic):
|
|
123
125
|
md.return_value.get_drb_topics_by_category.return_value = [base]
|
|
126
|
+
md.return_value.get_all_drb_topics.return_value = [base]
|
|
124
127
|
facs = {
|
|
125
128
|
'http': _RecordingBaseFactory(),
|
|
126
129
|
'odata': _ForcedFactory(),
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
from unittest.mock import patch, MagicMock
|
|
3
|
+
|
|
4
|
+
import drb.topics.resolver as resolver_mod
|
|
5
|
+
from drb.core.factory import DrbFactory
|
|
6
|
+
from drb.nodes.logical_node import DrbLogicalNode
|
|
7
|
+
from drb.exceptions.core import DrbFactoryException
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _topic(factory, scheme, label='t'):
|
|
11
|
+
t = MagicMock()
|
|
12
|
+
t.factory = factory
|
|
13
|
+
t.scheme = scheme
|
|
14
|
+
t.label = label
|
|
15
|
+
return t
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class TestTopicBySchemeAny(unittest.TestCase):
|
|
19
|
+
def _call(self, scheme, topics):
|
|
20
|
+
with patch.object(resolver_mod, 'ManagerDao') as md:
|
|
21
|
+
md.return_value.get_all_drb_topics.return_value = topics
|
|
22
|
+
return resolver_mod._topic_by_scheme_any(scheme)
|
|
23
|
+
|
|
24
|
+
def test_returns_topic_any_category(self):
|
|
25
|
+
zip_t = _topic('zip', ['zip'])
|
|
26
|
+
result = self._call('zip', [_topic('aws3', ['s3']), zip_t])
|
|
27
|
+
self.assertIs(result, zip_t)
|
|
28
|
+
|
|
29
|
+
def test_returns_none_when_absent(self):
|
|
30
|
+
self.assertIsNone(self._call('nope', [_topic('aws3', ['s3'])]))
|
|
31
|
+
|
|
32
|
+
def test_raises_on_ambiguity(self):
|
|
33
|
+
a = _topic('f1', ['x'], 'A')
|
|
34
|
+
b = _topic('f2', ['x'], 'B')
|
|
35
|
+
with self.assertRaises(DrbFactoryException):
|
|
36
|
+
self._call('x', [a, b])
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class TestResolveToken(unittest.TestCase):
|
|
40
|
+
def test_via_scheme_index(self):
|
|
41
|
+
zip_t = _topic('zip', ['zip'])
|
|
42
|
+
fac = object()
|
|
43
|
+
with patch.object(resolver_mod, '_topic_by_scheme_any',
|
|
44
|
+
return_value=zip_t), \
|
|
45
|
+
patch.object(resolver_mod.FactoryLoader, 'get_factory',
|
|
46
|
+
return_value=fac) as gf:
|
|
47
|
+
topic, factory = resolver_mod._resolve_token('zip')
|
|
48
|
+
self.assertIs(topic, zip_t)
|
|
49
|
+
self.assertIs(factory, fac)
|
|
50
|
+
gf.assert_called_with('zip') # looked up by topic.factory
|
|
51
|
+
|
|
52
|
+
def test_factory_name_fallback(self):
|
|
53
|
+
forced_t = _topic('odata', [])
|
|
54
|
+
fac = object()
|
|
55
|
+
with patch.object(resolver_mod, '_topic_by_scheme_any',
|
|
56
|
+
return_value=None), \
|
|
57
|
+
patch.object(resolver_mod, '_topic_by_factory',
|
|
58
|
+
return_value=forced_t), \
|
|
59
|
+
patch.object(resolver_mod.FactoryLoader, 'get_factory',
|
|
60
|
+
return_value=fac):
|
|
61
|
+
topic, factory = resolver_mod._resolve_token('odata')
|
|
62
|
+
self.assertIs(topic, forced_t)
|
|
63
|
+
self.assertIs(factory, fac)
|
|
64
|
+
|
|
65
|
+
def test_factory_name_fallback_non_protocol_topic(self):
|
|
66
|
+
"""Fallback path must accept a non-PROTOCOL (e.g. CONTAINER) topic."""
|
|
67
|
+
container_t = _topic('zip', [], 'ZipContainer')
|
|
68
|
+
fac = object()
|
|
69
|
+
with patch.object(resolver_mod, '_topic_by_scheme_any',
|
|
70
|
+
return_value=None), \
|
|
71
|
+
patch.object(resolver_mod, '_topic_by_factory',
|
|
72
|
+
return_value=container_t), \
|
|
73
|
+
patch.object(resolver_mod.FactoryLoader, 'get_factory',
|
|
74
|
+
return_value=fac):
|
|
75
|
+
topic, factory = resolver_mod._resolve_token('zip')
|
|
76
|
+
self.assertIs(topic, container_t)
|
|
77
|
+
self.assertIs(factory, fac)
|
|
78
|
+
|
|
79
|
+
def test_factory_registered_but_no_topic_raises(self):
|
|
80
|
+
"""When factory is registered but _topic_by_factory returns None,
|
|
81
|
+
a clear DrbFactoryException must be raised."""
|
|
82
|
+
fac = object()
|
|
83
|
+
with patch.object(resolver_mod, '_topic_by_scheme_any',
|
|
84
|
+
return_value=None), \
|
|
85
|
+
patch.object(resolver_mod, '_topic_by_factory',
|
|
86
|
+
return_value=None), \
|
|
87
|
+
patch.object(resolver_mod.FactoryLoader, 'get_factory',
|
|
88
|
+
return_value=fac):
|
|
89
|
+
with self.assertRaises(DrbFactoryException):
|
|
90
|
+
resolver_mod._resolve_token('orphan')
|
|
91
|
+
|
|
92
|
+
def test_unknown_raises(self):
|
|
93
|
+
with patch.object(resolver_mod, '_topic_by_scheme_any',
|
|
94
|
+
return_value=None), \
|
|
95
|
+
patch.object(resolver_mod.FactoryLoader, 'get_factory',
|
|
96
|
+
return_value=None):
|
|
97
|
+
with self.assertRaises(DrbFactoryException):
|
|
98
|
+
resolver_mod._resolve_token('nosuch')
|
|
99
|
+
|
|
100
|
+
def test_scheme_topic_factory_not_installed_raises(self):
|
|
101
|
+
zip_t = _topic('zip', ['zip'])
|
|
102
|
+
with patch.object(resolver_mod, '_topic_by_scheme_any',
|
|
103
|
+
return_value=zip_t), \
|
|
104
|
+
patch.object(resolver_mod.FactoryLoader, 'get_factory',
|
|
105
|
+
return_value=None):
|
|
106
|
+
with self.assertRaises(DrbFactoryException):
|
|
107
|
+
resolver_mod._resolve_token('zip')
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class _TagFactory(DrbFactory):
|
|
111
|
+
"""Records call order via a shared list; returns a tagged node."""
|
|
112
|
+
def __init__(self, tag, order):
|
|
113
|
+
self.tag = tag
|
|
114
|
+
self.order = order
|
|
115
|
+
|
|
116
|
+
def _create(self, node):
|
|
117
|
+
self.order.append(self.tag)
|
|
118
|
+
return DrbLogicalNode(self.tag)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class TestMultiTokenDispatch(unittest.TestCase):
|
|
122
|
+
def test_ordered_stack(self):
|
|
123
|
+
order = []
|
|
124
|
+
base = _topic('http', ['https'])
|
|
125
|
+
oda = _topic('odata', ['odata'])
|
|
126
|
+
xml = _topic('xml', ['xml'])
|
|
127
|
+
tok = {'odata': oda, 'xml': xml}
|
|
128
|
+
facs = {
|
|
129
|
+
'http': _TagFactory('http', order),
|
|
130
|
+
'odata': _TagFactory('odata', order),
|
|
131
|
+
'xml': _TagFactory('xml', order),
|
|
132
|
+
}
|
|
133
|
+
r = resolver_mod._DrbFactoryResolver()
|
|
134
|
+
with patch.object(resolver_mod, '_topic_by_scheme',
|
|
135
|
+
return_value=base), \
|
|
136
|
+
patch.object(resolver_mod, '_topic_by_scheme_any',
|
|
137
|
+
side_effect=lambda s: tok.get(s)), \
|
|
138
|
+
patch.object(resolver_mod.FactoryLoader, 'get_factory',
|
|
139
|
+
side_effect=lambda n: facs.get(n)):
|
|
140
|
+
t, n = r._DrbFactoryResolver__dispatch_scheme(
|
|
141
|
+
DrbLogicalNode('https+odata+xml://host/x'))
|
|
142
|
+
self.assertEqual(order, ['http', 'odata', 'xml'])
|
|
143
|
+
self.assertIs(t, xml)
|
|
144
|
+
self.assertEqual(n.name, 'xml')
|
|
145
|
+
|
|
146
|
+
def test_empty_segment_raises(self):
|
|
147
|
+
r = resolver_mod._DrbFactoryResolver()
|
|
148
|
+
with self.assertRaises(DrbFactoryException):
|
|
149
|
+
r._DrbFactoryResolver__dispatch_scheme(
|
|
150
|
+
DrbLogicalNode('https++xml://host'))
|
|
151
|
+
|
|
152
|
+
def test_unknown_base_returns_none(self):
|
|
153
|
+
r = resolver_mod._DrbFactoryResolver()
|
|
154
|
+
with patch.object(resolver_mod, '_topic_by_scheme',
|
|
155
|
+
return_value=None):
|
|
156
|
+
self.assertIsNone(
|
|
157
|
+
r._DrbFactoryResolver__dispatch_scheme(
|
|
158
|
+
DrbLogicalNode('ftp://host')))
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
class TestTopicByFactory(unittest.TestCase):
|
|
162
|
+
def test_finds_container_category_topic(self):
|
|
163
|
+
"""_topic_by_factory must find topics from any category, not just
|
|
164
|
+
PROTOCOL. Regression for the bug where only PROTOCOL topics were
|
|
165
|
+
searched."""
|
|
166
|
+
zip_t = _topic('zip', ['zip'], 'ZipContainer')
|
|
167
|
+
with patch.object(resolver_mod, 'ManagerDao') as md:
|
|
168
|
+
md.return_value.get_all_drb_topics.return_value = [zip_t]
|
|
169
|
+
result = resolver_mod._topic_by_factory('zip')
|
|
170
|
+
self.assertIs(result, zip_t)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
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.4.0 → drb-2.4.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
|