maxml 1.0.3__tar.gz → 1.0.5__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.
- {maxml-1.0.3 → maxml-1.0.5}/PKG-INFO +20 -7
- {maxml-1.0.3 → maxml-1.0.5}/README.md +17 -4
- {maxml-1.0.3 → maxml-1.0.5}/requirements.development.txt +1 -1
- {maxml-1.0.3 → maxml-1.0.5}/requirements.txt +1 -1
- {maxml-1.0.3 → maxml-1.0.5}/source/maxml/element/__init__.py +9 -6
- {maxml-1.0.3 → maxml-1.0.5}/source/maxml/namespace/__init__.py +7 -2
- maxml-1.0.5/source/maxml/version.txt +1 -0
- {maxml-1.0.3 → maxml-1.0.5}/source/maxml.egg-info/PKG-INFO +20 -7
- {maxml-1.0.3 → maxml-1.0.5}/source/maxml.egg-info/requires.txt +2 -2
- {maxml-1.0.3 → maxml-1.0.5}/tests/test_element.py +96 -0
- maxml-1.0.3/source/maxml/version.txt +0 -1
- {maxml-1.0.3 → maxml-1.0.5}/pyproject.toml +0 -0
- {maxml-1.0.3 → maxml-1.0.5}/requirements.distribution.txt +0 -0
- {maxml-1.0.3 → maxml-1.0.5}/setup.cfg +0 -0
- {maxml-1.0.3 → maxml-1.0.5}/source/maxml/__init__.py +0 -0
- {maxml-1.0.3 → maxml-1.0.5}/source/maxml/enumerations/__init__.py +0 -0
- {maxml-1.0.3 → maxml-1.0.5}/source/maxml/exceptions/__init__.py +0 -0
- {maxml-1.0.3 → maxml-1.0.5}/source/maxml/logging/__init__.py +0 -0
- {maxml-1.0.3 → maxml-1.0.5}/source/maxml.egg-info/SOURCES.txt +0 -0
- {maxml-1.0.3 → maxml-1.0.5}/source/maxml.egg-info/dependency_links.txt +0 -0
- {maxml-1.0.3 → maxml-1.0.5}/source/maxml.egg-info/top_level.txt +0 -0
- {maxml-1.0.3 → maxml-1.0.5}/source/maxml.egg-info/zip-safe +0 -0
- {maxml-1.0.3 → maxml-1.0.5}/tests/test_namespace.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: maxml
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.5
|
|
4
4
|
Summary: A streamlined pure Python XML serializer.
|
|
5
5
|
Author: Daniel Sissman
|
|
6
6
|
License-Expression: MIT
|
|
@@ -19,9 +19,9 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
19
19
|
Requires-Python: >=3.10
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
Requires-Dist: classicist==1.0.*
|
|
22
|
-
Requires-Dist: enumerific==1.
|
|
22
|
+
Requires-Dist: enumerific==1.1.*
|
|
23
23
|
Provides-Extra: development
|
|
24
|
-
Requires-Dist: black==
|
|
24
|
+
Requires-Dist: black==26.1.*; extra == "development"
|
|
25
25
|
Requires-Dist: pytest==8.3.*; extra == "development"
|
|
26
26
|
Requires-Dist: pytest-codeblocks==0.17.0; extra == "development"
|
|
27
27
|
Provides-Extra: distribution
|
|
@@ -115,10 +115,10 @@ The `Element` class constructor `Element(...)` takes the following arguments:
|
|
|
115
115
|
|
|
116
116
|
The `Element` class provides the following methods:
|
|
117
117
|
|
|
118
|
-
* `register_namespace(prefix: str, uri: str
|
|
119
|
-
supports registering namespaces globally for the
|
|
120
|
-
on whether the method is called on the class
|
|
121
|
-
specific instance of the class.
|
|
118
|
+
* `register_namespace(prefix: str, uri: str, promoted: bool = False)` –
|
|
119
|
+
The `register_namespace()` method supports registering namespaces globally for the
|
|
120
|
+
module or per instance depending on whether the method is called on the class
|
|
121
|
+
directly or whether it is called on a specific instance of the class.
|
|
122
122
|
|
|
123
123
|
If a namespace is registered globally for the module, the registered namespaces
|
|
124
124
|
become available for use by any instance of the class created within the program
|
|
@@ -132,6 +132,16 @@ The `Element` class provides the following methods:
|
|
|
132
132
|
|
|
133
133
|
Each namespace consists of a prefix which can be used to prefix element names
|
|
134
134
|
and the URI associated with that namespace prefix.
|
|
135
|
+
|
|
136
|
+
Optionally, a namespace can be marked as being promoted during registration, which
|
|
137
|
+
will result in the namespace being serialized into the XML before any attributes on
|
|
138
|
+
the element. Namespaces that are not marked as being promoted will appear after any
|
|
139
|
+
attributes on the element. Namespace promotion can be enabled for a given namespace
|
|
140
|
+
during registration by passing the optional `promoted` keyword argument with the
|
|
141
|
+
value of `True`. Whether a namespace is marked as promoted or not can be changed
|
|
142
|
+
after registration by changing a `Namespace` entity's `promoted` property value or
|
|
143
|
+
by using the `promote()` and `unpromote()` methods. See the **Namespace Class** for
|
|
144
|
+
more information.
|
|
135
145
|
|
|
136
146
|
For example, the 'rdf' prefix is associated with the following canonical URI:
|
|
137
147
|
"http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
@@ -278,6 +288,9 @@ The `Namespace` class constructor `Namespace(...)` takes the following arguments
|
|
|
278
288
|
|
|
279
289
|
* `prefix` (`str`) – The required `prefix` argument sets the namespace prefix.
|
|
280
290
|
* `uri` (`str`) – The required `uri` argument sets the namespace URI.
|
|
291
|
+
* `promoted` (`bool`) – The optional `promoted` argument sets whether the namespace is
|
|
292
|
+
marked as being promoted or not. Promoted namespaces result in the namespace being
|
|
293
|
+
serialized into the XML before any attributes on their associated element.
|
|
281
294
|
|
|
282
295
|
The `Namespace` class provides the following methods:
|
|
283
296
|
|
|
@@ -84,10 +84,10 @@ The `Element` class constructor `Element(...)` takes the following arguments:
|
|
|
84
84
|
|
|
85
85
|
The `Element` class provides the following methods:
|
|
86
86
|
|
|
87
|
-
* `register_namespace(prefix: str, uri: str
|
|
88
|
-
supports registering namespaces globally for the
|
|
89
|
-
on whether the method is called on the class
|
|
90
|
-
specific instance of the class.
|
|
87
|
+
* `register_namespace(prefix: str, uri: str, promoted: bool = False)` –
|
|
88
|
+
The `register_namespace()` method supports registering namespaces globally for the
|
|
89
|
+
module or per instance depending on whether the method is called on the class
|
|
90
|
+
directly or whether it is called on a specific instance of the class.
|
|
91
91
|
|
|
92
92
|
If a namespace is registered globally for the module, the registered namespaces
|
|
93
93
|
become available for use by any instance of the class created within the program
|
|
@@ -101,6 +101,16 @@ The `Element` class provides the following methods:
|
|
|
101
101
|
|
|
102
102
|
Each namespace consists of a prefix which can be used to prefix element names
|
|
103
103
|
and the URI associated with that namespace prefix.
|
|
104
|
+
|
|
105
|
+
Optionally, a namespace can be marked as being promoted during registration, which
|
|
106
|
+
will result in the namespace being serialized into the XML before any attributes on
|
|
107
|
+
the element. Namespaces that are not marked as being promoted will appear after any
|
|
108
|
+
attributes on the element. Namespace promotion can be enabled for a given namespace
|
|
109
|
+
during registration by passing the optional `promoted` keyword argument with the
|
|
110
|
+
value of `True`. Whether a namespace is marked as promoted or not can be changed
|
|
111
|
+
after registration by changing a `Namespace` entity's `promoted` property value or
|
|
112
|
+
by using the `promote()` and `unpromote()` methods. See the **Namespace Class** for
|
|
113
|
+
more information.
|
|
104
114
|
|
|
105
115
|
For example, the 'rdf' prefix is associated with the following canonical URI:
|
|
106
116
|
"http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
@@ -247,6 +257,9 @@ The `Namespace` class constructor `Namespace(...)` takes the following arguments
|
|
|
247
257
|
|
|
248
258
|
* `prefix` (`str`) – The required `prefix` argument sets the namespace prefix.
|
|
249
259
|
* `uri` (`str`) – The required `uri` argument sets the namespace URI.
|
|
260
|
+
* `promoted` (`bool`) – The optional `promoted` argument sets whether the namespace is
|
|
261
|
+
marked as being promoted or not. Promoted namespaces result in the namespace being
|
|
262
|
+
serialized into the XML before any attributes on their associated element.
|
|
250
263
|
|
|
251
264
|
The `Namespace` class provides the following methods:
|
|
252
265
|
|
|
@@ -28,7 +28,7 @@ class Element(object):
|
|
|
28
28
|
_mixed: bool = False
|
|
29
29
|
|
|
30
30
|
@hybridmethod
|
|
31
|
-
def register_namespace(self, prefix: str, uri: str):
|
|
31
|
+
def register_namespace(self, prefix: str, uri: str, promoted: bool = False):
|
|
32
32
|
"""Supports registering namespaces globally for the module or per instance
|
|
33
33
|
depending on whether the method is called on the class directly or whether it is
|
|
34
34
|
called on a specific instance of the class.
|
|
@@ -74,6 +74,9 @@ class Element(object):
|
|
|
74
74
|
if not isinstance(uri, str):
|
|
75
75
|
raise TypeError("The 'uri' argument must have a string value!")
|
|
76
76
|
|
|
77
|
+
if not isinstance(promoted, bool):
|
|
78
|
+
raise TypeError("The 'promoted' argument must have a boolean value!")
|
|
79
|
+
|
|
77
80
|
for namespace in self._namespaces:
|
|
78
81
|
if namespace.prefix == prefix:
|
|
79
82
|
if namespace.uri == uri:
|
|
@@ -88,7 +91,7 @@ class Element(object):
|
|
|
88
91
|
% (prefix, uri, namespace.uri)
|
|
89
92
|
)
|
|
90
93
|
else:
|
|
91
|
-
if namespace := Namespace(prefix=prefix, uri=uri):
|
|
94
|
+
if namespace := Namespace(prefix=prefix, uri=uri, promoted=promoted):
|
|
92
95
|
self._namespaces.add(namespace)
|
|
93
96
|
|
|
94
97
|
def __init__(
|
|
@@ -119,7 +122,7 @@ class Element(object):
|
|
|
119
122
|
prefix: str = None
|
|
120
123
|
|
|
121
124
|
if ":" in name:
|
|
122
|
-
|
|
125
|
+
prefix, basename = name.split(":", maxsplit=1)
|
|
123
126
|
|
|
124
127
|
self._prefix: str = prefix
|
|
125
128
|
|
|
@@ -186,7 +189,7 @@ class Element(object):
|
|
|
186
189
|
if namespace.uri == uri:
|
|
187
190
|
break
|
|
188
191
|
else:
|
|
189
|
-
namespace = Namespace(prefix=prefix, uri=uri)
|
|
192
|
+
namespace = Namespace(prefix=prefix, uri=uri, promoted=False)
|
|
190
193
|
|
|
191
194
|
self.__class__._namespaces.add(namespace)
|
|
192
195
|
|
|
@@ -662,7 +665,7 @@ class Element(object):
|
|
|
662
665
|
# Add any promoted namespaces (those which should proceed any attributes)
|
|
663
666
|
count = len(element.namespaced)
|
|
664
667
|
for index, namespace in enumerate(element.namespaced, start=1):
|
|
665
|
-
if
|
|
668
|
+
if namespace.promoted is False:
|
|
666
669
|
continue
|
|
667
670
|
|
|
668
671
|
if pretty and count > 1 and (newline or (index > 1 and index <= count)):
|
|
@@ -691,7 +694,7 @@ class Element(object):
|
|
|
691
694
|
newline = True
|
|
692
695
|
|
|
693
696
|
for index, namespace in enumerate(element.namespaced, start=1):
|
|
694
|
-
if namespace.promoted:
|
|
697
|
+
if namespace.promoted is True:
|
|
695
698
|
continue
|
|
696
699
|
|
|
697
700
|
if pretty and count > 1 and (newline or (index > 1 and index <= count)):
|
|
@@ -14,7 +14,7 @@ class Namespace(object):
|
|
|
14
14
|
_uri: str = None
|
|
15
15
|
_promoted: bool = False
|
|
16
16
|
|
|
17
|
-
def __init__(self, prefix: str, uri: str):
|
|
17
|
+
def __init__(self, prefix: str, uri: str, promoted: bool = False):
|
|
18
18
|
"""Initialize the Namespace class"""
|
|
19
19
|
|
|
20
20
|
if not isinstance(prefix, str):
|
|
@@ -27,6 +27,11 @@ class Namespace(object):
|
|
|
27
27
|
|
|
28
28
|
self._uri = uri
|
|
29
29
|
|
|
30
|
+
if not isinstance(promoted, bool):
|
|
31
|
+
raise TypeError("The 'promoted' argument must have a boolean value!")
|
|
32
|
+
|
|
33
|
+
self._promoted = promoted
|
|
34
|
+
|
|
30
35
|
def __str__(self) -> str:
|
|
31
36
|
"""Return a string representation of the class for debugging purposes."""
|
|
32
37
|
|
|
@@ -89,7 +94,7 @@ class Namespace(object):
|
|
|
89
94
|
def copy(self) -> Namespace:
|
|
90
95
|
"""Create an independent copy of the current Namespace instance."""
|
|
91
96
|
|
|
92
|
-
return Namespace(prefix=self.prefix, uri=self.uri)
|
|
97
|
+
return Namespace(prefix=self.prefix, uri=self.uri, promoted=self.promoted)
|
|
93
98
|
|
|
94
99
|
@property
|
|
95
100
|
def promoted(self) -> bool:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.0.5
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: maxml
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.5
|
|
4
4
|
Summary: A streamlined pure Python XML serializer.
|
|
5
5
|
Author: Daniel Sissman
|
|
6
6
|
License-Expression: MIT
|
|
@@ -19,9 +19,9 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
19
19
|
Requires-Python: >=3.10
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
Requires-Dist: classicist==1.0.*
|
|
22
|
-
Requires-Dist: enumerific==1.
|
|
22
|
+
Requires-Dist: enumerific==1.1.*
|
|
23
23
|
Provides-Extra: development
|
|
24
|
-
Requires-Dist: black==
|
|
24
|
+
Requires-Dist: black==26.1.*; extra == "development"
|
|
25
25
|
Requires-Dist: pytest==8.3.*; extra == "development"
|
|
26
26
|
Requires-Dist: pytest-codeblocks==0.17.0; extra == "development"
|
|
27
27
|
Provides-Extra: distribution
|
|
@@ -115,10 +115,10 @@ The `Element` class constructor `Element(...)` takes the following arguments:
|
|
|
115
115
|
|
|
116
116
|
The `Element` class provides the following methods:
|
|
117
117
|
|
|
118
|
-
* `register_namespace(prefix: str, uri: str
|
|
119
|
-
supports registering namespaces globally for the
|
|
120
|
-
on whether the method is called on the class
|
|
121
|
-
specific instance of the class.
|
|
118
|
+
* `register_namespace(prefix: str, uri: str, promoted: bool = False)` –
|
|
119
|
+
The `register_namespace()` method supports registering namespaces globally for the
|
|
120
|
+
module or per instance depending on whether the method is called on the class
|
|
121
|
+
directly or whether it is called on a specific instance of the class.
|
|
122
122
|
|
|
123
123
|
If a namespace is registered globally for the module, the registered namespaces
|
|
124
124
|
become available for use by any instance of the class created within the program
|
|
@@ -132,6 +132,16 @@ The `Element` class provides the following methods:
|
|
|
132
132
|
|
|
133
133
|
Each namespace consists of a prefix which can be used to prefix element names
|
|
134
134
|
and the URI associated with that namespace prefix.
|
|
135
|
+
|
|
136
|
+
Optionally, a namespace can be marked as being promoted during registration, which
|
|
137
|
+
will result in the namespace being serialized into the XML before any attributes on
|
|
138
|
+
the element. Namespaces that are not marked as being promoted will appear after any
|
|
139
|
+
attributes on the element. Namespace promotion can be enabled for a given namespace
|
|
140
|
+
during registration by passing the optional `promoted` keyword argument with the
|
|
141
|
+
value of `True`. Whether a namespace is marked as promoted or not can be changed
|
|
142
|
+
after registration by changing a `Namespace` entity's `promoted` property value or
|
|
143
|
+
by using the `promote()` and `unpromote()` methods. See the **Namespace Class** for
|
|
144
|
+
more information.
|
|
135
145
|
|
|
136
146
|
For example, the 'rdf' prefix is associated with the following canonical URI:
|
|
137
147
|
"http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
@@ -278,6 +288,9 @@ The `Namespace` class constructor `Namespace(...)` takes the following arguments
|
|
|
278
288
|
|
|
279
289
|
* `prefix` (`str`) – The required `prefix` argument sets the namespace prefix.
|
|
280
290
|
* `uri` (`str`) – The required `uri` argument sets the namespace URI.
|
|
291
|
+
* `promoted` (`bool`) – The optional `promoted` argument sets whether the namespace is
|
|
292
|
+
marked as being promoted or not. Promoted namespaces result in the namespace being
|
|
293
|
+
serialized into the XML before any attributes on their associated element.
|
|
281
294
|
|
|
282
295
|
The `Namespace` class provides the following methods:
|
|
283
296
|
|
|
@@ -461,3 +461,99 @@ def test_maxml_special_tostring(data: callable):
|
|
|
461
461
|
assert isinstance(compare, str)
|
|
462
462
|
|
|
463
463
|
assert string == compare
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
def test_maxml_namespace_promotion(data: callable):
|
|
467
|
+
"""Check promotion of registered namespaces works as expected"""
|
|
468
|
+
|
|
469
|
+
# Register a class level namespace
|
|
470
|
+
maxml.Element.register_namespace(
|
|
471
|
+
prefix="xy", uri="http://namespace.example.org/xy", promoted=True
|
|
472
|
+
)
|
|
473
|
+
|
|
474
|
+
# Create a new top-level element
|
|
475
|
+
element = maxml.Element(name="xy:test")
|
|
476
|
+
|
|
477
|
+
# Ensure that the Element object's type is as expected
|
|
478
|
+
assert isinstance(element, maxml.Element)
|
|
479
|
+
|
|
480
|
+
# Ensure that the Element object's namespace type is as expected
|
|
481
|
+
assert isinstance(element.namespace, maxml.Namespace)
|
|
482
|
+
assert element.namespace.prefix == "xy"
|
|
483
|
+
assert element.namespace.uri == "http://namespace.example.org/xy"
|
|
484
|
+
assert element.namespace.promoted is True
|
|
485
|
+
|
|
486
|
+
# Set an element attribute
|
|
487
|
+
element.set("xy:id", "1")
|
|
488
|
+
|
|
489
|
+
# Serialise the element to a string
|
|
490
|
+
string: str = element.tostring(pretty=True)
|
|
491
|
+
|
|
492
|
+
assert isinstance(string, str)
|
|
493
|
+
|
|
494
|
+
# Confirm that the promoted namespace was serialised before the attributes
|
|
495
|
+
compare: str = """<xy:test xmlns:xy="http://namespace.example.org/xy" xy:id="1"/>"""
|
|
496
|
+
|
|
497
|
+
assert string == compare
|
|
498
|
+
|
|
499
|
+
# Now mark the namespace as not being promoted to re-test the serialisation below
|
|
500
|
+
element.namespace.promoted = False
|
|
501
|
+
|
|
502
|
+
# Ensure that the promoted status has changed
|
|
503
|
+
assert element.namespace.promoted is False
|
|
504
|
+
|
|
505
|
+
# Serialise the element to a string
|
|
506
|
+
string: str = element.tostring(pretty=True)
|
|
507
|
+
|
|
508
|
+
assert isinstance(string, str)
|
|
509
|
+
|
|
510
|
+
# Confirm that the non-promoted namespace was serialised after the attributes
|
|
511
|
+
compare: str = """<xy:test xy:id="1" xmlns:xy="http://namespace.example.org/xy"/>"""
|
|
512
|
+
|
|
513
|
+
assert string == compare
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
def test_maxml_namespace_promotion_non_promoted_namespace(data: callable):
|
|
517
|
+
"""Check promotion of registered namespaces works as expected"""
|
|
518
|
+
|
|
519
|
+
maxml.Element.register_namespace(
|
|
520
|
+
prefix="my1", uri="http://namespace.example.org/my1", promoted=False
|
|
521
|
+
)
|
|
522
|
+
|
|
523
|
+
element = maxml.Element(name="my1:test")
|
|
524
|
+
|
|
525
|
+
# Ensure that the element object's type is as expected
|
|
526
|
+
assert isinstance(element, maxml.Element)
|
|
527
|
+
|
|
528
|
+
element.set("my1:attribute", "1234")
|
|
529
|
+
|
|
530
|
+
string: str = element.tostring(pretty=True)
|
|
531
|
+
|
|
532
|
+
assert isinstance(string, str)
|
|
533
|
+
|
|
534
|
+
compare: str = data("examples/example04namespace-unpromoted.xml")
|
|
535
|
+
|
|
536
|
+
assert string == compare
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
def test_maxml_namespace_promotion_promoted_namespace(data: callable):
|
|
540
|
+
"""Check promotion of registered namespaces works as expected"""
|
|
541
|
+
|
|
542
|
+
maxml.Element.register_namespace(
|
|
543
|
+
prefix="my2", uri="http://namespace.example.org/my2", promoted=True
|
|
544
|
+
)
|
|
545
|
+
|
|
546
|
+
element = maxml.Element(name="my2:test")
|
|
547
|
+
|
|
548
|
+
# Ensure that the element object's type is as expected
|
|
549
|
+
assert isinstance(element, maxml.Element)
|
|
550
|
+
|
|
551
|
+
element.set("my2:attribute", "1234")
|
|
552
|
+
|
|
553
|
+
string: str = element.tostring(pretty=True)
|
|
554
|
+
|
|
555
|
+
assert isinstance(string, str)
|
|
556
|
+
|
|
557
|
+
compare: str = data("examples/example04namespace-promoted.xml")
|
|
558
|
+
|
|
559
|
+
assert string == compare
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
1.0.3
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|