elementpath 5.0.3__tar.gz → 5.0.4__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 (133) hide show
  1. {elementpath-5.0.3 → elementpath-5.0.4}/CHANGELOG.rst +5 -0
  2. {elementpath-5.0.3/elementpath.egg-info → elementpath-5.0.4}/PKG-INFO +1 -1
  3. {elementpath-5.0.3 → elementpath-5.0.4}/doc/conf.py +1 -1
  4. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/__init__.py +1 -1
  5. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/compare.py +8 -8
  6. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/extras/pathnodes.py +24 -32
  7. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/schema_proxy.py +4 -64
  8. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/serialization.py +6 -6
  9. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/tree_builders.py +1 -1
  10. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath1/_xpath1_functions.py +4 -4
  11. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath1/_xpath1_operators.py +3 -3
  12. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath2/_xpath2_functions.py +13 -13
  13. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath30/_xpath30_functions.py +1 -1
  14. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath31/_xpath31_functions.py +2 -2
  15. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath_context.py +7 -7
  16. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath_nodes.py +194 -154
  17. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath_tokens.py +4 -4
  18. {elementpath-5.0.3 → elementpath-5.0.4/elementpath.egg-info}/PKG-INFO +1 -1
  19. {elementpath-5.0.3 → elementpath-5.0.4}/pyproject.toml +1 -1
  20. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_schema_proxy.py +143 -0
  21. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_xpath_context.py +6 -6
  22. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_xpath_nodes.py +1 -1
  23. {elementpath-5.0.3 → elementpath-5.0.4}/LICENSE +0 -0
  24. {elementpath-5.0.3 → elementpath-5.0.4}/MANIFEST.in +0 -0
  25. {elementpath-5.0.3 → elementpath-5.0.4}/README.rst +0 -0
  26. {elementpath-5.0.3 → elementpath-5.0.4}/doc/Makefile +0 -0
  27. {elementpath-5.0.3 → elementpath-5.0.4}/doc/advanced.rst +0 -0
  28. {elementpath-5.0.3 → elementpath-5.0.4}/doc/index.rst +0 -0
  29. {elementpath-5.0.3 → elementpath-5.0.4}/doc/introduction.rst +0 -0
  30. {elementpath-5.0.3 → elementpath-5.0.4}/doc/make.bat +0 -0
  31. {elementpath-5.0.3 → elementpath-5.0.4}/doc/pratt_api.rst +0 -0
  32. {elementpath-5.0.3 → elementpath-5.0.4}/doc/requirements.txt +0 -0
  33. {elementpath-5.0.3 → elementpath-5.0.4}/doc/xpath_api.rst +0 -0
  34. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/aliases.py +0 -0
  35. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/collations.py +0 -0
  36. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/datatypes/__init__.py +0 -0
  37. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/datatypes/atomic_types.py +0 -0
  38. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/datatypes/binary.py +0 -0
  39. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/datatypes/datetime.py +0 -0
  40. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/datatypes/numeric.py +0 -0
  41. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/datatypes/proxies.py +0 -0
  42. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/datatypes/qname.py +0 -0
  43. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/datatypes/string.py +0 -0
  44. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/datatypes/untyped.py +0 -0
  45. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/datatypes/uri.py +0 -0
  46. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/decoder.py +0 -0
  47. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/etree.py +0 -0
  48. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/exceptions.py +0 -0
  49. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/extras/__init__.py +0 -0
  50. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/helpers.py +0 -0
  51. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/namespaces.py +0 -0
  52. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/protocols.py +0 -0
  53. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/py.typed +0 -0
  54. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/regex/__init__.py +0 -0
  55. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/regex/categories_fallback.py +0 -0
  56. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/regex/character_classes.py +0 -0
  57. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/regex/codepoints.py +0 -0
  58. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/regex/patterns.py +0 -0
  59. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/regex/unicode_blocks.py +0 -0
  60. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/regex/unicode_categories.py +0 -0
  61. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/regex/unicode_subsets.py +0 -0
  62. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/sequence_types.py +0 -0
  63. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/tdop.py +0 -0
  64. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/validators/__init__.py +0 -0
  65. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/validators/analyze-string.xsd +0 -0
  66. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/validators/schema-for-json.xsd +0 -0
  67. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath1/__init__.py +0 -0
  68. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath1/_xpath1_axes.py +0 -0
  69. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath1/xpath1_parser.py +0 -0
  70. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath2/__init__.py +0 -0
  71. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath2/_xpath2_constructors.py +0 -0
  72. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath2/_xpath2_operators.py +0 -0
  73. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath2/xpath2_parser.py +0 -0
  74. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath3.py +0 -0
  75. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath30/__init__.py +0 -0
  76. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath30/_translation_maps.py +0 -0
  77. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath30/_xpath30_operators.py +0 -0
  78. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath30/xpath30_helpers.py +0 -0
  79. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath30/xpath30_parser.py +0 -0
  80. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath31/__init__.py +0 -0
  81. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath31/_xpath31_operators.py +0 -0
  82. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath31/xpath31_parser.py +0 -0
  83. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath/xpath_selectors.py +0 -0
  84. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath.egg-info/SOURCES.txt +0 -0
  85. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath.egg-info/dependency_links.txt +0 -0
  86. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath.egg-info/requires.txt +0 -0
  87. {elementpath-5.0.3 → elementpath-5.0.4}/elementpath.egg-info/top_level.txt +0 -0
  88. {elementpath-5.0.3 → elementpath-5.0.4}/requirements-dev.txt +0 -0
  89. {elementpath-5.0.3 → elementpath-5.0.4}/scripts/generate_codepoints.py +0 -0
  90. {elementpath-5.0.3 → elementpath-5.0.4}/setup.cfg +0 -0
  91. {elementpath-5.0.3 → elementpath-5.0.4}/tests/__init__.py +0 -0
  92. {elementpath-5.0.3 → elementpath-5.0.4}/tests/memory_profiling.py +0 -0
  93. {elementpath-5.0.3 → elementpath-5.0.4}/tests/mypy_tests/advanced.py +0 -0
  94. {elementpath-5.0.3 → elementpath-5.0.4}/tests/mypy_tests/protocols.py +0 -0
  95. {elementpath-5.0.3 → elementpath-5.0.4}/tests/mypy_tests/selectors.py +0 -0
  96. {elementpath-5.0.3 → elementpath-5.0.4}/tests/resources/analyze-string.xsd +0 -0
  97. {elementpath-5.0.3 → elementpath-5.0.4}/tests/resources/external_entity.xml +0 -0
  98. {elementpath-5.0.3 → elementpath-5.0.4}/tests/resources/sample.xml +0 -0
  99. {elementpath-5.0.3 → elementpath-5.0.4}/tests/resources/schema-for-json.xsd +0 -0
  100. {elementpath-5.0.3 → elementpath-5.0.4}/tests/resources/unparsed_entity.xml +0 -0
  101. {elementpath-5.0.3 → elementpath-5.0.4}/tests/resources/unused_external_entity.xml +0 -0
  102. {elementpath-5.0.3 → elementpath-5.0.4}/tests/resources/unused_unparsed_entity.xml +0 -0
  103. {elementpath-5.0.3 → elementpath-5.0.4}/tests/resources/with_entity.xml +0 -0
  104. {elementpath-5.0.3 → elementpath-5.0.4}/tests/run_all_tests.py +0 -0
  105. {elementpath-5.0.3 → elementpath-5.0.4}/tests/run_typing_tests.py +0 -0
  106. {elementpath-5.0.3 → elementpath-5.0.4}/tests/run_w3c_tests.py +0 -0
  107. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_collations.py +0 -0
  108. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_compare.py +0 -0
  109. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_datatypes.py +0 -0
  110. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_decoder.py +0 -0
  111. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_etree.py +0 -0
  112. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_exceptions.py +0 -0
  113. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_helpers.py +0 -0
  114. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_namespaces.py +0 -0
  115. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_package.py +0 -0
  116. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_pathnodes.py +0 -0
  117. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_regex.py +0 -0
  118. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_schema_context.py +0 -0
  119. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_selectors.py +0 -0
  120. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_sequence_types.py +0 -0
  121. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_serialization.py +0 -0
  122. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_tdop_parser.py +0 -0
  123. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_tree_builders.py +0 -0
  124. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_validators.py +0 -0
  125. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_xpath1_parser.py +0 -0
  126. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_xpath2_constructors.py +0 -0
  127. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_xpath2_functions.py +0 -0
  128. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_xpath2_parser.py +0 -0
  129. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_xpath30.py +0 -0
  130. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_xpath31.py +0 -0
  131. {elementpath-5.0.3 → elementpath-5.0.4}/tests/test_xpath_tokens.py +0 -0
  132. {elementpath-5.0.3 → elementpath-5.0.4}/tests/xpath_test_class.py +0 -0
  133. {elementpath-5.0.3 → elementpath-5.0.4}/tox.ini +0 -0
@@ -2,6 +2,10 @@
2
2
  CHANGELOG
3
3
  *********
4
4
 
5
+ `v5.0.4`_ (2025-08-16)
6
+ ======================
7
+ * Fix default/fixed values processing of schema annotated XML data (issue #94)
8
+
5
9
  `v5.0.3`_ (2025-06-28)
6
10
  ======================
7
11
  * Fix for XPath 1.0 processing of schema annotated XML data (issue #93)
@@ -518,3 +522,4 @@ CHANGELOG
518
522
  .. _v5.0.1: https://github.com/sissaschool/elementpath/compare/v5.0.0...v5.0.1
519
523
  .. _v5.0.2: https://github.com/sissaschool/elementpath/compare/v5.0.1...v5.0.2
520
524
  .. _v5.0.3: https://github.com/sissaschool/elementpath/compare/v5.0.2...v5.0.3
525
+ .. _v5.0.4: https://github.com/sissaschool/elementpath/compare/v5.0.3...v5.0.4
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: elementpath
3
- Version: 5.0.3
3
+ Version: 5.0.4
4
4
  Summary: XPath 1.0/2.0/3.0/3.1 parsers and selectors for ElementTree and lxml
5
5
  Author-email: Davide Brunato <brunato@sissa.it>
6
6
  License-Expression: MIT
@@ -31,7 +31,7 @@ author = 'Davide Brunato'
31
31
  # The short X.Y version
32
32
  version = '5.0'
33
33
  # The full version, including alpha/beta/rc tags
34
- release = '5.0.3'
34
+ release = '5.0.4'
35
35
 
36
36
  # -- General configuration ---------------------------------------------------
37
37
 
@@ -7,7 +7,7 @@
7
7
  #
8
8
  # @author Davide Brunato <brunato@sissa.it>
9
9
  #
10
- __version__ = '5.0.3'
10
+ __version__ = '5.0.4'
11
11
  __author__ = "Davide Brunato"
12
12
  __contact__ = "brunato@sissa.it"
13
13
  __copyright__ = "Copyright 2018-2025, SISSA"
@@ -83,7 +83,7 @@ def deep_equal(seq1: Iterable[Any],
83
83
  return False
84
84
  elif isinstance(value1, etree_node_types):
85
85
  assert isinstance(value2, etree_node_types)
86
- if not etree_deep_equal(value1.obj, value2.obj):
86
+ if not etree_deep_equal(value1.value, value2.value):
87
87
  return False
88
88
  elif isinstance(value1, EtreeDocumentNode):
89
89
  assert isinstance(value2, EtreeDocumentNode)
@@ -94,14 +94,14 @@ def deep_equal(seq1: Iterable[Any],
94
94
  return False
95
95
  elif isinstance(child1, etree_node_types):
96
96
  assert isinstance(child2, etree_node_types)
97
- if not etree_deep_equal(child1.obj, child2.obj):
97
+ if not etree_deep_equal(child1.value, child2.value):
98
98
  return False
99
99
  elif isinstance(child1, TextNode):
100
100
  assert isinstance(child2, TextNode)
101
- if cm.ne(child1.obj, child2.obj):
101
+ if cm.ne(child1.value, child2.value):
102
102
  return False
103
103
 
104
- elif cm.ne(value1.obj, value2.obj):
104
+ elif cm.ne(value1.value, value2.value):
105
105
  return False
106
106
  elif isinstance(value1, TextAttributeNode):
107
107
  if cm.ne(value1.name, value2.name):
@@ -257,7 +257,7 @@ def deep_compare(obj1: Any,
257
257
  raise xpath_error('XPTY0004', msg, token=token)
258
258
  elif isinstance(value1, etree_node_types):
259
259
  assert isinstance(value2, etree_node_types)
260
- result = etree_deep_compare(value1.obj, value2.obj)
260
+ result = etree_deep_compare(value1.value, value2.value)
261
261
  if result:
262
262
  return result
263
263
  elif isinstance(value1, EtreeDocumentNode):
@@ -272,19 +272,19 @@ def deep_compare(obj1: Any,
272
272
  raise xpath_error('XPTY0004', msg, token=token)
273
273
  elif isinstance(child1, etree_node_types):
274
274
  assert isinstance(child2, etree_node_types)
275
- result = etree_deep_compare(child1.obj, child2.obj)
275
+ result = etree_deep_compare(child1.value, child2.value)
276
276
  if result:
277
277
  return result
278
278
  elif isinstance(child1, TextNode):
279
279
  assert isinstance(child2, TextNode)
280
280
  result = cm.strcoll(
281
- child1.obj.strip(), child2.obj.strip()
281
+ child1.value.strip(), child2.value.strip()
282
282
  )
283
283
  if result:
284
284
  return result
285
285
  elif isinstance(value1, TextNode):
286
286
  assert isinstance(value2, TextNode)
287
- result = cm.strcoll(value1.obj, value2.obj)
287
+ result = cm.strcoll(value1.value, value2.value)
288
288
  if result:
289
289
  return result
290
290
  elif isinstance(value1, TextAttributeNode):
@@ -24,7 +24,7 @@ from elementpath.datatypes import DateTime, AtomicType
24
24
 
25
25
  class PathElementNode(ElementNode):
26
26
  name: str
27
- obj: Path
27
+ value: Path
28
28
  xsd_element: Optional[XsdElementProtocol]
29
29
 
30
30
  __slots__ = ('stat',)
@@ -53,7 +53,7 @@ class PathElementNode(ElementNode):
53
53
  self.parent = parent
54
54
 
55
55
  self.name = path.name
56
- self.obj = path
56
+ self.value = path
57
57
  self.stat = path.stat()
58
58
  self.position = self.stat.st_ino
59
59
  self.children = []
@@ -63,9 +63,9 @@ class PathElementNode(ElementNode):
63
63
 
64
64
  @property
65
65
  def content(self) -> Path:
66
- return self.obj
66
+ return self.value
67
67
 
68
- elem = value = content
68
+ elem = content
69
69
 
70
70
  @property
71
71
  def attributes(self) -> list[AttributeNode]:
@@ -101,10 +101,10 @@ class PathElementNode(ElementNode):
101
101
 
102
102
  @property
103
103
  def string_value(self) -> str:
104
- if self.obj.is_dir():
104
+ if self.value.is_dir():
105
105
  return ''
106
- if self.obj.is_file():
107
- return self.obj.read_text()
106
+ if self.value.is_file():
107
+ return self.value.read_text()
108
108
  else:
109
109
  return ''
110
110
 
@@ -125,12 +125,12 @@ class PathElementNode(ElementNode):
125
125
  return self.name == f'{{{default_namespace}}}{name}'
126
126
 
127
127
  def get_document_node(self, replace: bool = True, as_parent: bool = True) -> 'DocumentNode':
128
- return PathDocumentNode(Path(self.obj.absolute().root))
128
+ return PathDocumentNode(Path(self.value.absolute().root))
129
129
 
130
130
  def __iter__(self) -> Iterator[ChildNodeType]:
131
131
  if not self.children:
132
- if self.obj.is_dir():
133
- for path in self.obj.iterdir():
132
+ if self.value.is_dir():
133
+ for path in self.value.iterdir():
134
134
  if path in self.tree.elements:
135
135
  self.children.append(self.tree.elements[path])
136
136
  else:
@@ -150,7 +150,7 @@ class PathElementNode(ElementNode):
150
150
 
151
151
 
152
152
  class PathDocumentNode(DocumentNode):
153
- obj: Path
153
+ value: Path
154
154
 
155
155
  __slots__ = ('stat',)
156
156
 
@@ -159,7 +159,7 @@ class PathDocumentNode(DocumentNode):
159
159
  if not document.is_dir() or len(document.parts) > 1 or not document.is_absolute():
160
160
  raise ValueError(f'{document} must be a root directory')
161
161
 
162
- self.obj = document
162
+ self.value = document
163
163
  self.name = None
164
164
  self.parent = None
165
165
  self.position = document.stat().st_ino
@@ -168,15 +168,15 @@ class PathDocumentNode(DocumentNode):
168
168
 
169
169
  @property
170
170
  def document(self) -> Path:
171
- return self.obj
171
+ return self.value
172
172
 
173
173
  @property
174
174
  def string_value(self) -> str:
175
- return self.obj.read_text()
175
+ return self.value.read_text()
176
176
 
177
177
  def __iter__(self) -> Iterator[ChildNodeType]:
178
178
  if not self.children:
179
- for path in self.obj.iterdir():
179
+ for path in self.value.iterdir():
180
180
  if path in self.tree.elements:
181
181
  self.children.append(self.tree.elements[path])
182
182
  else:
@@ -187,7 +187,7 @@ class PathDocumentNode(DocumentNode):
187
187
 
188
188
  class IntAttributeNode(AttributeNode):
189
189
  name: str
190
- obj: int
190
+ value: int
191
191
  parent: Optional['PathElementNode']
192
192
 
193
193
  __slots__ = ()
@@ -198,22 +198,18 @@ class IntAttributeNode(AttributeNode):
198
198
  parent: Optional['PathElementNode'] = None) -> None:
199
199
 
200
200
  self.name = name
201
- self.obj = value
201
+ self.value = value
202
202
  self.parent = parent
203
203
  self.position = parent.position if parent is not None else 1
204
204
  self.xsd_type = None
205
205
 
206
- @property
207
- def value(self) -> int:
208
- return self.obj
209
-
210
206
  @property
211
207
  def string_value(self) -> str:
212
- return str(self.obj)
208
+ return str(self.value)
213
209
 
214
210
  @property
215
211
  def iter_typed_values(self) -> Iterator[AtomicType]:
216
- yield self.obj
212
+ yield self.value
217
213
 
218
214
  @property
219
215
  def type_name(self) -> Optional[str]:
@@ -224,12 +220,12 @@ class ModeAttributeNode(IntAttributeNode):
224
220
 
225
221
  @property
226
222
  def string_value(self) -> str:
227
- return oct(self.obj)
223
+ return oct(self.value)
228
224
 
229
225
 
230
226
  class DatetimeAttributeNode(AttributeNode):
231
227
  name: str
232
- obj: datetime
228
+ value: datetime
233
229
  parent: Optional['PathElementNode']
234
230
 
235
231
  __slots__ = ()
@@ -240,22 +236,18 @@ class DatetimeAttributeNode(AttributeNode):
240
236
  parent: Optional['PathElementNode'] = None) -> None:
241
237
 
242
238
  self.name = name
243
- self.obj = value
239
+ self.value = value
244
240
  self.parent = parent
245
241
  self.position = parent.position if parent is not None else 1
246
242
  self.xsd_type = None
247
243
 
248
- @property
249
- def value(self) -> datetime:
250
- return self.obj
251
-
252
244
  @property
253
245
  def string_value(self) -> str:
254
- return str(self.obj)
246
+ return str(self.value)
255
247
 
256
248
  @property
257
249
  def iter_typed_values(self) -> Iterator[AtomicType]:
258
- yield DateTime.fromdatetime(self.obj)
250
+ yield DateTime.fromdatetime(self.value)
259
251
 
260
252
  @property
261
253
  def type_name(self) -> Optional[str]:
@@ -10,12 +10,11 @@
10
10
  from abc import ABCMeta, abstractmethod
11
11
  from collections.abc import Iterator
12
12
  from functools import lru_cache
13
- from typing import cast, Any, Optional, Union
13
+ from typing import Any, Optional, Union
14
14
 
15
15
  from elementpath.exceptions import ElementPathTypeError
16
16
  from elementpath.protocols import XsdTypeProtocol, XsdAttributeProtocol, \
17
- XsdElementProtocol, XsdSchemaProtocol, XsdAttributeGroupProtocol
18
- from elementpath.namespaces import XSD_ANY_ATOMIC_TYPE
17
+ XsdElementProtocol, XsdSchemaProtocol
19
18
  from elementpath.datatypes import AtomicType
20
19
  from elementpath.etree import is_etree_element
21
20
  from elementpath.xpath_context import XPathSchemaContext
@@ -148,16 +147,14 @@ class AbstractSchemaProxy(metaclass=ABCMeta):
148
147
  Get the XSD global attribute from the schema's scope.
149
148
 
150
149
  :param qname: the fully qualified name of the attribute to retrieve.
151
- :returns: an object that represents an XSD type or `None`.
152
150
  """
153
151
  return self._schema.maps.attributes.get(qname)
154
152
 
155
- def get_element(self, qname: str) -> Optional[XsdElementProtocol]:
153
+ def get_element(self, qname: str,) -> Optional[XsdElementProtocol]:
156
154
  """
157
155
  Get the XSD global element from the schema's scope.
158
156
 
159
- :param qname: the fully qualified name of the element to retrieve.
160
- :returns: an object that represents an XSD type or `None`.
157
+ :param qname: the fully qualified name of the attribute to retrieve.
161
158
  """
162
159
  return self._schema.maps.elements.get(qname)
163
160
 
@@ -171,63 +168,6 @@ class AbstractSchemaProxy(metaclass=ABCMeta):
171
168
  """
172
169
  return self._schema.maps.substitution_groups.get(qname)
173
170
 
174
- def get_attribute_type(self, name: str, parent_type: Optional[XsdTypeProtocol] = None) \
175
- -> Optional[XsdTypeProtocol]:
176
- """
177
- Get the XSD attribute type if the provided name is matching in the scope,
178
- otherwise return None.
179
-
180
- :param name: the name of the attribute to retrieve.
181
- :param parent_type: an optional XSD type that represents the scope where matching \
182
- the attribute name. If not provided, the scope is assumed to be the global scope.
183
- """
184
- if parent_type is None:
185
- try:
186
- return self._schema.maps.attributes[name].type
187
- except KeyError:
188
- return None
189
- elif hasattr(parent_type, 'attributes'):
190
- attributes = cast(XsdAttributeGroupProtocol, parent_type.attributes)
191
- if name in attributes:
192
- return attributes[name].type
193
- elif None in attributes and attributes[None].is_matching(name):
194
- try:
195
- return self._schema.maps.attributes[name].type
196
- except KeyError:
197
- return None
198
- elif name.startswith('{http://www.w3.org/2001/XMLSchema-instance}'):
199
- return self._schema.maps.types.get(XSD_ANY_ATOMIC_TYPE)
200
-
201
- return None
202
-
203
- def get_child_type(self, name: str, parent_type: Optional[XsdTypeProtocol] = None) \
204
- -> Optional[XsdTypeProtocol]:
205
- """
206
- Get the child XSD type if the provided name is matching in the scope,
207
- otherwise return None.
208
-
209
- :param name: the name of the child element to match.
210
- :param parent_type: an optional XSD type that represents the scope where matching \
211
- the child element name. If `None` or not provided the scope is the schema.
212
- """
213
- if parent_type is None:
214
- try:
215
- return self._schema.maps.elements[name].type
216
- except KeyError:
217
- return None
218
- elif (content := parent_type.model_group) is not None:
219
- for xsd_element in content.iter_elements():
220
- if xsd_element.is_matching(name):
221
- if xsd_element.name == name:
222
- return xsd_element.type
223
- else:
224
- # a wildcard or a substitute
225
- try:
226
- return self._schema.maps.elements[name].type
227
- except KeyError:
228
- return None
229
- return None
230
-
231
171
  @abstractmethod
232
172
  def is_instance(self, obj: Any, type_qname: str) -> bool:
233
173
  """
@@ -139,7 +139,7 @@ def get_serialization_params(params: Union[None, ElementNode, XPathMap] = None,
139
139
  kwargs[key] = value
140
140
 
141
141
  elif isinstance(params, ElementNode):
142
- root = cast(Union[EtreeElementProtocol, LxmlElementProtocol], params.obj)
142
+ root = cast(Union[EtreeElementProtocol, LxmlElementProtocol], params.value)
143
143
  if root.tag != SERIALIZATION_PARAMS:
144
144
  msg = 'output:serialization-parameters tag expected'
145
145
  raise xpath_error('XPTY0004', msg, token)
@@ -293,14 +293,14 @@ def serialize_to_xml(elements: Iterable[Any],
293
293
  for item in iter_normalized(elements, item_separator):
294
294
  if isinstance(item, ElementNode):
295
295
  assert isinstance(item, EtreeElementNode)
296
- elem = item.obj
296
+ elem = item.value
297
297
  elif isinstance(item, (AttributeNode, NamespaceNode)):
298
298
  raise xpath_error('SENR0001', token=token)
299
299
  elif isinstance(item, TextNode):
300
300
  if item.parent is not None and item.parent.name in cdata_section:
301
- chunks.append(f'<![CDATA[{item.obj}]]>')
301
+ chunks.append(f'<![CDATA[{item.value}]]>')
302
302
  else:
303
- chunks.append(item.obj)
303
+ chunks.append(item.value)
304
304
  continue
305
305
  elif not isinstance(item, str):
306
306
  raise xpath_error('SENR0001', token=token)
@@ -352,7 +352,7 @@ def serialize_to_json(elements: Iterable[Any],
352
352
  return ''.join(self.default(child) for child in obj)
353
353
  elif isinstance(obj, ElementNode):
354
354
  assert isinstance(obj, EtreeElementNode)
355
- elem = obj.obj
355
+ elem = obj.value
356
356
  assert etree_module is not None
357
357
 
358
358
  try:
@@ -368,7 +368,7 @@ def serialize_to_json(elements: Iterable[Any],
368
368
  elif isinstance(obj, (AttributeNode, NamespaceNode)):
369
369
  return f'{obj.name}="{obj.string_value}"'
370
370
  elif isinstance(obj, TextNode):
371
- return obj.obj
371
+ return obj.value
372
372
  elif isinstance(obj, CommentNode):
373
373
  return f'<!--{obj.string_value}-->'
374
374
  else:
@@ -56,7 +56,7 @@ def get_node_tree(root: RootArgType,
56
56
  return root.getroot()
57
57
  elif fragment is False and \
58
58
  isinstance(root, ElementNode) and \
59
- is_etree_element_instance(root.obj):
59
+ is_etree_element_instance(root.value):
60
60
  return root.get_document_node()
61
61
 
62
62
  return root
@@ -146,7 +146,7 @@ def select_id_function(self: XPathFunction, context: ContextType = None) \
146
146
 
147
147
  if isinstance(item, (ElementNode, DocumentNode)):
148
148
  for element in item.iter_descendants():
149
- if isinstance(element, EtreeElementNode) and element.obj.get(XML_ID) == value:
149
+ if isinstance(element, EtreeElementNode) and element.value.get(XML_ID) == value:
150
150
  yield element
151
151
 
152
152
 
@@ -380,11 +380,11 @@ def evaluate_lang_function(self: XPathFunction, context: ContextType = None) ->
380
380
  return False
381
381
  else:
382
382
  try:
383
- attr = context.item.obj.attrib[XML_LANG]
383
+ attr = context.item.value.attrib[XML_LANG]
384
384
  except KeyError:
385
385
  for e in context.iter_ancestors():
386
- if isinstance(e, EtreeElementNode) and XML_LANG in e.obj.attrib:
387
- lang = e.obj.attrib[XML_LANG]
386
+ if isinstance(e, EtreeElementNode) and XML_LANG in e.value.attrib:
387
+ lang = e.value.attrib[XML_LANG]
388
388
  if not isinstance(lang, str):
389
389
  return False
390
390
  break
@@ -673,7 +673,7 @@ def select_child_path(self: XPathToken, context: ContextType = None) \
673
673
  elif result in items:
674
674
  pass
675
675
  elif isinstance(result, ElementNode):
676
- if result.obj not in items:
676
+ if result.value not in items:
677
677
  items.add(result)
678
678
  yield result
679
679
  else:
@@ -700,7 +700,7 @@ def select_descendant_path(self: XPathToken, context: ContextType = None) \
700
700
  elif result in items:
701
701
  pass
702
702
  elif isinstance(result, ElementNode):
703
- if result.obj not in items:
703
+ if result.value not in items:
704
704
  items.add(result)
705
705
  yield result
706
706
  else:
@@ -723,7 +723,7 @@ def select_descendant_path(self: XPathToken, context: ContextType = None) \
723
723
  elif result in items:
724
724
  pass
725
725
  elif isinstance(result, ElementNode):
726
- if result.obj not in items:
726
+ if result.value not in items:
727
727
  items.add(result)
728
728
  else:
729
729
  items.add(result)
@@ -155,7 +155,7 @@ def evaluate_namespace_uri_for_prefix_function(
155
155
  if not isinstance(elem, EtreeElementNode):
156
156
  return []
157
157
 
158
- ns_uris = {get_namespace(e.tag) for e in elem.obj.iter() if not callable(e.tag)}
158
+ ns_uris = {get_namespace(e.tag) for e in elem.value.iter() if not callable(e.tag)}
159
159
  for p, uri in self.parser.namespaces.items():
160
160
  if uri in ns_uris:
161
161
  if p == prefix:
@@ -180,7 +180,7 @@ def select_in_scope_prefixes_function(self: XPathFunction, context: ContextType
180
180
  if not isinstance(arg, ElementNode):
181
181
  raise self.error('XPTY0004', 'argument %r is not an element node' % arg)
182
182
 
183
- elem = arg.obj
183
+ elem = arg.value
184
184
  if isinstance(context, XPathSchemaContext):
185
185
  # For schema context returns prefixes of static namespaces
186
186
  for pfx, uri in self.parser.namespaces.items():
@@ -1485,15 +1485,15 @@ def evaluate_lang_function(self: XPathFunction, context: ContextType = None) ->
1485
1485
  raise self.error('XPTY0004')
1486
1486
  elif isinstance(item, EtreeElementNode):
1487
1487
  try:
1488
- attr = item.obj.attrib[XML_LANG]
1488
+ attr = item.value.attrib[XML_LANG]
1489
1489
  except KeyError:
1490
1490
  if len(self) > 1 or context is None:
1491
1491
  return False
1492
1492
 
1493
1493
  for elem in context.iter_ancestors():
1494
1494
  if isinstance(elem, EtreeElementNode):
1495
- if XML_LANG in elem.obj.attrib:
1496
- lang = cast(str, elem.obj.attrib[XML_LANG])
1495
+ if XML_LANG in elem.value.attrib:
1496
+ lang = cast(str, elem.value.attrib[XML_LANG])
1497
1497
  break
1498
1498
  else:
1499
1499
  return False
@@ -1551,8 +1551,8 @@ def select_id_function(self: XPathFunction, context: ContextType = None) -> Iter
1551
1551
  if not isinstance(element, EtreeElementNode):
1552
1552
  continue
1553
1553
 
1554
- if element.obj.text in idrefs and element.is_id:
1555
- idrefs.remove(element.obj.text)
1554
+ if element.value.text in idrefs and element.is_id:
1555
+ idrefs.remove(element.value.text)
1556
1556
  if self.symbol == 'id':
1557
1557
  yield element
1558
1558
  else:
@@ -1561,11 +1561,11 @@ def select_id_function(self: XPathFunction, context: ContextType = None) -> Iter
1561
1561
  yield parent
1562
1562
  else:
1563
1563
  for attr in element.attributes:
1564
- if not isinstance(attr.obj, str):
1564
+ if not isinstance(attr.value, str):
1565
1565
  continue
1566
1566
 
1567
- if attr.obj in idrefs and attr.is_id:
1568
- idrefs.remove(attr.obj)
1567
+ if attr.value in idrefs and attr.is_id:
1568
+ idrefs.remove(attr.value)
1569
1569
  yield element
1570
1570
 
1571
1571
 
@@ -1588,7 +1588,7 @@ def select_idref_function(self: XPathFunction, context: ContextType = None) \
1588
1588
  if not isinstance(element, EtreeElementNode):
1589
1589
  continue
1590
1590
 
1591
- text = element.obj.text
1591
+ text = element.value.text
1592
1592
  if text and is_idrefs(text) and \
1593
1593
  any(v in text.split() for x in ids for v in x.split()):
1594
1594
  yield element
@@ -1596,8 +1596,8 @@ def select_idref_function(self: XPathFunction, context: ContextType = None) \
1596
1596
 
1597
1597
  if element.attributes:
1598
1598
  for attr in element.attributes: # pragma: no cover
1599
- if attr.name != XML_ID and isinstance(attr.obj, str) and \
1600
- any(v in attr.obj.split() for x in ids for v in x.split()):
1599
+ if attr.name != XML_ID and isinstance(attr.value, str) and \
1600
+ any(v in attr.value.split() for x in ids for v in x.split()):
1601
1601
  yield element
1602
1602
  break
1603
1603
 
@@ -1107,7 +1107,7 @@ def evaluate_has_children_function(self: XPathFunction, context: ContextType = N
1107
1107
  raise self.error('XPTY0004', 'argument must be a node')
1108
1108
 
1109
1109
  return isinstance(item, DocumentNode) or \
1110
- isinstance(item, EtreeElementNode) and (len(item.obj) > 0 or item.obj.text is not None)
1110
+ isinstance(item, EtreeElementNode) and (len(item.value) > 0 or item.value.text is not None)
1111
1111
 
1112
1112
 
1113
1113
  @method(function('innermost', nargs=1, sequence_types=('node()*', 'node()*')))
@@ -1241,10 +1241,10 @@ def evaluate_xml_to_json_function(self: XPathFunction, context: ContextType = No
1241
1241
  return ','.join(chunks)
1242
1242
 
1243
1243
  if isinstance(input_node, DocumentNode):
1244
- return elem_to_json(child.obj for child in input_node
1244
+ return elem_to_json(child.value for child in input_node
1245
1245
  if isinstance(child, EtreeElementNode))
1246
1246
  elif isinstance(input_node, EtreeElementNode):
1247
- return elem_to_json((input_node.obj,))
1247
+ return elem_to_json((input_node.value,))
1248
1248
  else:
1249
1249
  raise self.error('FOJS0006')
1250
1250
 
@@ -154,7 +154,7 @@ class XPathContext:
154
154
  self.document = self.root
155
155
  elif fragment is None and \
156
156
  isinstance(self.root, ElementNode) and \
157
- is_etree_element_instance(self.root.obj):
157
+ is_etree_element_instance(self.root.value):
158
158
  # Creates a dummy document that will be not included in results
159
159
  self.document = self.root.get_document_node(as_parent=False)
160
160
  else:
@@ -201,9 +201,9 @@ class XPathContext:
201
201
 
202
202
  def __repr__(self) -> str:
203
203
  if self.root is not None:
204
- return f'{self.__class__.__name__}(root={self.root.obj})'
204
+ return f'{self.__class__.__name__}(root={self.root.value})'
205
205
  elif isinstance(self.item, XPathNode):
206
- return f'{self.__class__.__name__}(item={self.item.obj})'
206
+ return f'{self.__class__.__name__}(item={self.item.value})'
207
207
  else:
208
208
  return f'{self.__class__.__name__}(item={self.item!r})'
209
209
 
@@ -223,10 +223,10 @@ class XPathContext:
223
223
  @cached_property
224
224
  def etree(self) -> ModuleType:
225
225
  if isinstance(self.root, (DocumentNode, ElementNode)):
226
- module_name = self.root.obj.__class__.__module__
226
+ module_name = self.root.value.__class__.__module__
227
227
  elif isinstance(self.item, (DocumentNode, ElementNode, CommentNode,
228
228
  ProcessingInstructionNode)):
229
- module_name = self.item.obj.__class__.__module__
229
+ module_name = self.item.value.__class__.__module__
230
230
  else:
231
231
  module_name = 'xml.etree.ElementTree'
232
232
 
@@ -300,12 +300,12 @@ class XPathContext:
300
300
  if isinstance(item, (XPathNode, AnyAtomicType)):
301
301
  return item
302
302
  elif is_etree_document(item):
303
- if self.root is not None and item is self.root.obj:
303
+ if self.root is not None and item is self.root.value:
304
304
  return self.root
305
305
 
306
306
  if self.documents:
307
307
  for doc in self.documents.values():
308
- if doc is not None and item is doc.obj:
308
+ if doc is not None and item is doc.value:
309
309
  return doc
310
310
 
311
311
  elif is_etree_element(item):