diff --git a/tests/validators/test_models.py b/tests/validators/test_models.py
index 47a6893f..744f94c2 100644
--- a/tests/validators/test_models.py
+++ b/tests/validators/test_models.py
@@ -11,6 +11,7 @@
"""Tests concerning model groups validation"""
import unittest
import os.path
+import warnings
from textwrap import dedent
from typing import Any, Union, List, Optional
@@ -1076,22 +1077,12 @@ def test_iter_collapsed_content_with_optional_elements(self):
""")
group = schema.types['A_type'].content
- model = ModelVisitor(group)
-
content = [('B3', 10), ('B4', None), ('B5', True), ('B6', 'alpha'), ('B7', 20)]
- model.restart()
- self.assertListEqual(
- list(model.iter_collapsed_content(content)), content
- )
self.assertListEqual(
list(iter_collapsed_content(content, group)), content
)
content = [('B3', 10), ('B5', True), ('B6', 'alpha'), ('B7', 20)] # Missing B4
- model.restart()
- self.assertListEqual(
- list(model.iter_collapsed_content(content)), content
- )
self.assertListEqual(
list(iter_collapsed_content(content, group)), content
)
@@ -1202,6 +1193,64 @@ def test_iter_collapsed_content_with_single_elements(self):
content = [('X', None), ('B1', 'abc'), ('B2', 10), ('B3', False)]
self.assertListEqual(list(iter_collapsed_content(content, group)), content)
+ def test_deprecated_methods(self):
+ schema = self.get_schema("""
+
+
+
+
+
+
+
+ """)
+
+ group = schema.types['A_type'].content
+ model = ModelVisitor(group)
+ default_namespace = 'http://xmlschema.test/ns'
+ content = [('B1', 1), ('B1', 2), ('B2', 3)]
+
+ with warnings.catch_warnings(record=True) as ctx:
+ warnings. simplefilter("always")
+ self.assertListEqual(
+ list(model.iter_collapsed_content(content)),
+ [('B1', 1), ('B2', 3), ('B1', 2)]
+ )
+ self.assertEqual(len(ctx), 1, "Expected one deprecation warning")
+ self.assertIn("use iter_collapsed_content()", str(ctx[0].message))
+ self.assertNotIn("Don't provide default_namespace", str(ctx[0].message))
+
+ with warnings.catch_warnings(record=True) as ctx:
+ warnings.simplefilter("always")
+ self.assertListEqual(
+ list(model.iter_collapsed_content(content, default_namespace)),
+ [('B1', 1), ('B2', 3), ('B1', 2)]
+ )
+ self.assertEqual(len(ctx), 1, "Expected one deprecation warning")
+ self.assertIn("use iter_collapsed_content()", str(ctx[0].message))
+ self.assertIn("Don't provide default_namespace", str(ctx[0].message))
+
+ content = [('B2', 1), ('B1', 2), ('B2', 3), ('B1', 4)]
+
+ with warnings.catch_warnings(record=True) as ctx:
+ warnings. simplefilter("always")
+ self.assertListEqual(
+ list(model.iter_unordered_content(content)),
+ [('B1', 2), ('B2', 1), ('B1', 4), ('B2', 3)]
+ )
+ self.assertEqual(len(ctx), 1, "Expected one deprecation warning")
+ self.assertIn("use iter_unordered_content()", str(ctx[0].message))
+ self.assertNotIn("Don't provide default_namespace", str(ctx[0].message))
+
+ with warnings.catch_warnings(record=True) as ctx:
+ warnings.simplefilter("always")
+ self.assertListEqual(
+ list(model.iter_unordered_content(content, default_namespace)),
+ [('B1', 2), ('B2', 1), ('B1', 4), ('B2', 3)]
+ )
+ self.assertEqual(len(ctx), 1, "Expected one deprecation warning")
+ self.assertIn("use iter_unordered_content()", str(ctx[0].message))
+ self.assertIn("Don't provide default_namespace", str(ctx[0].message))
+
class TestModelPaths(unittest.TestCase):
diff --git a/xmlschema/validators/groups.py b/xmlschema/validators/groups.py
index b17c4d5c..d762bcc3 100644
--- a/xmlschema/validators/groups.py
+++ b/xmlschema/validators/groups.py
@@ -1137,7 +1137,7 @@ def iter_encode(self, obj: ElementData, validation: str = 'lax', **kwargs: Any)
if not obj.content:
content = []
elif isinstance(obj.content, MutableMapping) or kwargs.get('unordered'):
- content = iter_unordered_content(obj.content, self, default_namespace)
+ content = iter_unordered_content(obj.content, self)
elif not isinstance(obj.content, MutableSequence):
wrong_content_type = True
content = []
@@ -1150,7 +1150,7 @@ def iter_encode(self, obj: ElementData, validation: str = 'lax', **kwargs: Any)
elif converter.losslessly:
content = obj.content
else:
- content = iter_collapsed_content(obj.content, self, default_namespace)
+ content = iter_collapsed_content(obj.content, self)
for index, (name, value) in enumerate(content):
if isinstance(name, int):
diff --git a/xmlschema/validators/models.py b/xmlschema/validators/models.py
index 4fbe4d58..b96f6f1a 100644
--- a/xmlschema/validators/models.py
+++ b/xmlschema/validators/models.py
@@ -15,6 +15,7 @@
from operator import attrgetter
from typing import Any, Dict, Iterable, Iterator, List, \
MutableMapping, MutableSequence, Optional, Tuple, Union
+import warnings
from ..exceptions import XMLSchemaValueError
from ..aliases import ModelGroupType, ModelParticleType, SchemaElementType, \
@@ -465,12 +466,26 @@ def _iter_all_model_errors(self, occurs: OccursCounterType) -> Iterator[AdvanceY
def iter_unordered_content(
self, content: EncodedContentType,
default_namespace: Optional[str] = None) -> Iterator[ContentItemType]:
- return iter_unordered_content(content, self.root, default_namespace)
+
+ msg = f"{self.__class__.__name__}.iter_unordered_content() method will " \
+ "be removed in v4.0, use iter_unordered_content() function instead."
+ if default_namespace is not None:
+ msg += " Don't provide default_namespace argument, it's ignored."
+ warnings.warn(msg, DeprecationWarning, stacklevel=2)
+
+ return iter_unordered_content(content, self.root)
def iter_collapsed_content(
self, content: Iterable[ContentItemType],
default_namespace: Optional[str] = None) -> Iterator[ContentItemType]:
- return iter_collapsed_content(content, self.root, default_namespace)
+
+ msg = f"{self.__class__.__name__}.iter_collapsed_content() method will " \
+ "be removed in v4.0, use iter_collapsed_content() function instead."
+ if default_namespace is not None:
+ msg += " Don't provide default_namespace argument, it's ignored."
+ warnings.warn(msg, DeprecationWarning, stacklevel=2)
+
+ return iter_collapsed_content(content, self.root)
class InterleavedModelVisitor(ModelVisitor):
@@ -555,10 +570,8 @@ def advance(self, match: bool = False) -> Iterator[AdvanceYieldedType]:
#
# Functions for manipulating encoded content
-def iter_unordered_content(
- content: EncodedContentType,
- group: ModelGroupType,
- default_namespace: Optional[str] = None) -> Iterator[ContentItemType]:
+def iter_unordered_content(content: EncodedContentType, group: ModelGroupType) \
+ -> Iterator[ContentItemType]:
"""
Takes an unordered content stored in a dictionary of lists and yields the
content elements sorted with the ordering defined by the model group. Character
@@ -574,7 +587,6 @@ def iter_unordered_content(
dictionary the values must be lists where each item is the content \
of a single element.
:param group: the model group related to content.
- :param default_namespace: the default namespace to apply for matching names.
"""
consumable_content: Dict[str, Any]
@@ -624,16 +636,13 @@ def iter_unordered_content(
yield cdata_content.pop()
-def sort_content(content: EncodedContentType,
- group: ModelGroupType,
- default_namespace: Optional[str] = None) -> List[ContentItemType]:
- return [x for x in iter_unordered_content(content, group, default_namespace)]
+def sort_content(content: EncodedContentType, group: ModelGroupType) \
+ -> List[ContentItemType]:
+ return [x for x in iter_unordered_content(content, group)]
-def iter_collapsed_content(
- content: Iterable[ContentItemType],
- group: ModelGroupType,
- default_namespace: Optional[str] = None) -> Iterator[ContentItemType]:
+def iter_collapsed_content(content: Iterable[ContentItemType], group: ModelGroupType) \
+ -> Iterator[ContentItemType]:
"""
Iterates a content stored in a sequence of couples *(name, value)*, yielding
items in the same order of the sequence, except for repetitions of the same
@@ -647,7 +656,6 @@ def iter_collapsed_content(
:param content: an iterable containing couples of names and values.
:param group: the model group related to content.
- :param default_namespace: the default namespace to apply for matching names.
"""
prev_name = None
unordered_content: Dict[str, Any] = defaultdict(deque)
@@ -689,7 +697,7 @@ def iter_collapsed_content(
yield name, value
prev_name = name
- # Add the remaining consumable content onto the end of the data.
+ # Yields the remaining consumable content after the end of the data.
for name, values in unordered_content.items():
for v in values:
yield name, v