elementpath 4.4.0__tar.gz → 4.6.0__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 (136) hide show
  1. {elementpath-4.4.0 → elementpath-4.6.0}/CHANGELOG.rst +15 -0
  2. {elementpath-4.4.0 → elementpath-4.6.0}/MANIFEST.in +1 -0
  3. {elementpath-4.4.0 → elementpath-4.6.0}/PKG-INFO +45 -32
  4. {elementpath-4.4.0 → elementpath-4.6.0}/README.rst +42 -30
  5. {elementpath-4.4.0 → elementpath-4.6.0}/doc/conf.py +2 -2
  6. {elementpath-4.4.0 → elementpath-4.6.0}/doc/xpath_api.rst +3 -0
  7. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/__init__.py +7 -5
  8. elementpath-4.6.0/elementpath/_typing.py +27 -0
  9. elementpath-4.6.0/elementpath/aliases.py +43 -0
  10. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/collations.py +3 -3
  11. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/compare.py +10 -9
  12. elementpath-4.6.0/elementpath/datatypes/__init__.py +61 -0
  13. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/datatypes/atomic_types.py +8 -2
  14. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/datatypes/binary.py +2 -2
  15. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/datatypes/datetime.py +17 -10
  16. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/datatypes/numeric.py +6 -3
  17. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/datatypes/proxies.py +13 -1
  18. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/datatypes/qname.py +5 -2
  19. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/datatypes/string.py +7 -4
  20. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/datatypes/untyped.py +1 -1
  21. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/datatypes/uri.py +2 -2
  22. elementpath-4.6.0/elementpath/decoder.py +176 -0
  23. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/etree.py +4 -3
  24. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/exceptions.py +13 -7
  25. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/helpers.py +71 -23
  26. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/namespaces.py +37 -39
  27. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/protocols.py +52 -6
  28. elementpath-4.6.0/elementpath/regex/__init__.py +25 -0
  29. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/regex/character_classes.py +59 -44
  30. elementpath-4.6.0/elementpath/regex/codepoints.py +206 -0
  31. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/regex/patterns.py +7 -7
  32. elementpath-4.6.0/elementpath/regex/unicode_blocks.py +450 -0
  33. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/regex/unicode_categories.py +418 -5
  34. elementpath-4.6.0/elementpath/regex/unicode_subsets.py +639 -0
  35. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/schema_proxy.py +11 -15
  36. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/sequence_types.py +16 -18
  37. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/serialization.py +9 -7
  38. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/tdop.py +25 -21
  39. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/tree_builders.py +160 -146
  40. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/validators/__init__.py +1 -1
  41. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath1/_xpath1_axes.py +39 -24
  42. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath1/_xpath1_functions.py +90 -63
  43. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath1/_xpath1_operators.py +173 -174
  44. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath1/xpath1_parser.py +88 -27
  45. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath2/_xpath2_constructors.py +147 -89
  46. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath2/_xpath2_functions.py +318 -230
  47. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath2/_xpath2_operators.py +145 -102
  48. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath2/xpath2_parser.py +33 -45
  49. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath30/_xpath30_functions.py +240 -163
  50. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath30/_xpath30_operators.py +45 -23
  51. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath30/xpath30_helpers.py +4 -3
  52. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath30/xpath30_parser.py +3 -4
  53. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath31/_xpath31_functions.py +196 -144
  54. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath31/_xpath31_operators.py +41 -27
  55. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath31/xpath31_parser.py +3 -3
  56. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath_context.py +96 -59
  57. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath_nodes.py +73 -48
  58. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath_selectors.py +10 -14
  59. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath_tokens.py +238 -246
  60. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath.egg-info/PKG-INFO +45 -32
  61. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath.egg-info/SOURCES.txt +6 -1
  62. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath.egg-info/requires.txt +1 -1
  63. {elementpath-4.4.0 → elementpath-4.6.0}/requirements-dev.txt +1 -1
  64. elementpath-4.6.0/scripts/generate_codepoints.py +406 -0
  65. {elementpath-4.4.0 → elementpath-4.6.0}/setup.py +3 -2
  66. {elementpath-4.4.0 → elementpath-4.6.0}/tests/execute_w3c_tests.py +4 -1
  67. elementpath-4.6.0/tests/mypy_tests/advanced.py +30 -0
  68. {elementpath-4.4.0 → elementpath-4.6.0}/tests/mypy_tests/selectors.py +15 -0
  69. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_datatypes.py +5 -4
  70. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_helpers.py +15 -2
  71. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_regex.py +225 -51
  72. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_selectors.py +22 -1
  73. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_tree_builders.py +67 -3
  74. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_typing.py +8 -0
  75. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_xpath1_parser.py +23 -18
  76. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_xpath2_constructors.py +4 -2
  77. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_xpath2_functions.py +10 -5
  78. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_xpath2_parser.py +109 -2
  79. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_xpath30.py +21 -0
  80. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_xpath_context.py +1 -4
  81. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_xpath_nodes.py +23 -0
  82. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_xpath_tokens.py +40 -75
  83. {elementpath-4.4.0 → elementpath-4.6.0}/tests/xpath_test_class.py +2 -0
  84. {elementpath-4.4.0 → elementpath-4.6.0}/tox.ini +29 -17
  85. elementpath-4.4.0/elementpath/datatypes/__init__.py +0 -124
  86. elementpath-4.4.0/elementpath/regex/__init__.py +0 -24
  87. elementpath-4.4.0/elementpath/regex/codepoints.py +0 -124
  88. elementpath-4.4.0/elementpath/regex/generate_categories.py +0 -116
  89. elementpath-4.4.0/elementpath/regex/unicode_subsets.py +0 -518
  90. {elementpath-4.4.0 → elementpath-4.6.0}/.coveragerc +0 -0
  91. {elementpath-4.4.0 → elementpath-4.6.0}/LICENSE +0 -0
  92. {elementpath-4.4.0 → elementpath-4.6.0}/doc/Makefile +0 -0
  93. {elementpath-4.4.0 → elementpath-4.6.0}/doc/advanced.rst +0 -0
  94. {elementpath-4.4.0 → elementpath-4.6.0}/doc/index.rst +0 -0
  95. {elementpath-4.4.0 → elementpath-4.6.0}/doc/introduction.rst +0 -0
  96. {elementpath-4.4.0 → elementpath-4.6.0}/doc/make.bat +0 -0
  97. {elementpath-4.4.0 → elementpath-4.6.0}/doc/pratt_api.rst +0 -0
  98. {elementpath-4.4.0 → elementpath-4.6.0}/doc/requirements.txt +0 -0
  99. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/py.typed +0 -0
  100. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/validators/analyze-string.xsd +0 -0
  101. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/validators/schema-for-json.xsd +0 -0
  102. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath1/__init__.py +0 -0
  103. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath2/__init__.py +0 -0
  104. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath3.py +0 -0
  105. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath30/__init__.py +0 -0
  106. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath30/_translation_maps.py +0 -0
  107. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath/xpath31/__init__.py +0 -0
  108. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath.egg-info/dependency_links.txt +0 -0
  109. {elementpath-4.4.0 → elementpath-4.6.0}/elementpath.egg-info/top_level.txt +0 -0
  110. {elementpath-4.4.0 → elementpath-4.6.0}/mypy.ini +0 -0
  111. {elementpath-4.4.0 → elementpath-4.6.0}/setup.cfg +0 -0
  112. {elementpath-4.4.0 → elementpath-4.6.0}/tests/__init__.py +0 -0
  113. {elementpath-4.4.0 → elementpath-4.6.0}/tests/memory_profiling.py +0 -0
  114. {elementpath-4.4.0 → elementpath-4.6.0}/tests/mypy_tests/protocols.py +0 -0
  115. {elementpath-4.4.0 → elementpath-4.6.0}/tests/resources/analyze-string.xsd +0 -0
  116. {elementpath-4.4.0 → elementpath-4.6.0}/tests/resources/external_entity.xml +0 -0
  117. {elementpath-4.4.0 → elementpath-4.6.0}/tests/resources/sample.xml +0 -0
  118. {elementpath-4.4.0 → elementpath-4.6.0}/tests/resources/schema-for-json.xsd +0 -0
  119. {elementpath-4.4.0 → elementpath-4.6.0}/tests/resources/unparsed_entity.xml +0 -0
  120. {elementpath-4.4.0 → elementpath-4.6.0}/tests/resources/unused_external_entity.xml +0 -0
  121. {elementpath-4.4.0 → elementpath-4.6.0}/tests/resources/unused_unparsed_entity.xml +0 -0
  122. {elementpath-4.4.0 → elementpath-4.6.0}/tests/resources/with_entity.xml +0 -0
  123. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_collations.py +0 -0
  124. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_compare.py +0 -0
  125. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_elementpath.py +0 -0
  126. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_etree.py +0 -0
  127. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_exceptions.py +0 -0
  128. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_namespaces.py +0 -0
  129. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_package.py +0 -0
  130. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_schema_context.py +0 -0
  131. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_schema_proxy.py +0 -0
  132. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_sequence_types.py +0 -0
  133. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_serialization.py +0 -0
  134. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_tdop_parser.py +0 -0
  135. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_validators.py +0 -0
  136. {elementpath-4.4.0 → elementpath-4.6.0}/tests/test_xpath31.py +0 -0
@@ -2,6 +2,19 @@
2
2
  CHANGELOG
3
3
  *********
4
4
 
5
+ `v4.6.0`_ (2024-10-27)
6
+ ======================
7
+ * Fix XsdAttributeGroupProtocol
8
+ * Improve Unicode support with installable UnicodeData.txt versions
9
+ * Extend names disambiguation with a fix for issue #78
10
+ * Refactor tree builders to fix document position of tails (issue #79)
11
+
12
+ `v4.5.0`_ (2024-09-09)
13
+ ======================
14
+ * Fix and clean node trees iteration methods (issue #72)
15
+ * Fix missing raw string for '[^\r\n]' (pull request #76)
16
+ * Full and more specific type annotations
17
+
5
18
  `v4.4.0`_ (2024-03-11)
6
19
  ======================
7
20
  * Improve stand-alone XPath functions builder (issue #70)
@@ -463,3 +476,5 @@ CHANGELOG
463
476
  .. _v4.2.1: https://github.com/sissaschool/elementpath/compare/v4.2.0...v4.2.1
464
477
  .. _v4.3.0: https://github.com/sissaschool/elementpath/compare/v4.2.1...v4.3.0
465
478
  .. _v4.4.0: https://github.com/sissaschool/elementpath/compare/v4.3.0...v4.4.0
479
+ .. _v4.5.0: https://github.com/sissaschool/elementpath/compare/v4.4.0...v4.5.0
480
+ .. _v4.6.0: https://github.com/sissaschool/elementpath/compare/v4.5.0...v4.6.0
@@ -11,6 +11,7 @@ include mypy.ini
11
11
  include doc/*
12
12
 
13
13
  recursive-include elementpath *
14
+ recursive-include scripts *
14
15
  recursive-include tests *
15
16
  recursive-exclude tests/.mypy_cache *
16
17
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: elementpath
3
- Version: 4.4.0
3
+ Version: 4.6.0
4
4
  Summary: XPath 1.0/2.0/3.0/3.1 parsers and selectors for ElementTree and lxml
5
5
  Home-page: https://github.com/sissaschool/elementpath
6
6
  Author: Davide Brunato
@@ -22,6 +22,7 @@ Classifier: Programming Language :: Python :: 3.10
22
22
  Classifier: Programming Language :: Python :: 3.11
23
23
  Classifier: Programming Language :: Python :: 3.12
24
24
  Classifier: Programming Language :: Python :: 3.13
25
+ Classifier: Programming Language :: Python :: 3.14
25
26
  Classifier: Programming Language :: Python :: Implementation :: CPython
26
27
  Classifier: Programming Language :: Python :: Implementation :: PyPy
27
28
  Classifier: Topic :: Software Development :: Libraries
@@ -32,7 +33,7 @@ Provides-Extra: dev
32
33
  Requires-Dist: tox; extra == "dev"
33
34
  Requires-Dist: coverage; extra == "dev"
34
35
  Requires-Dist: lxml; extra == "dev"
35
- Requires-Dist: xmlschema>=2.0.0; extra == "dev"
36
+ Requires-Dist: xmlschema>=3.3.2; extra == "dev"
36
37
  Requires-Dist: Sphinx; extra == "dev"
37
38
  Requires-Dist: memory-profiler; extra == "dev"
38
39
  Requires-Dist: memray; extra == "dev"
@@ -76,11 +77,13 @@ You can install the package with *pip* in a Python 3.8+ environment::
76
77
 
77
78
  For using it import the package and apply the selectors on ElementTree nodes:
78
79
 
79
- >>> import elementpath
80
- >>> from xml.etree import ElementTree
81
- >>> root = ElementTree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
82
- >>> elementpath.select(root, '/A/B2/*')
83
- [<Element 'C1' at ...>, <Element 'C2' at ...>, <Element 'C3' at ...>]
80
+ .. code-block:: pycon
81
+
82
+ >>> import elementpath
83
+ >>> from xml.etree import ElementTree
84
+ >>> root = ElementTree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
85
+ >>> elementpath.select(root, '/A/B2/*')
86
+ [<Element 'C1' at ...>, <Element 'C2' at ...>, <Element 'C3' at ...>]
84
87
 
85
88
  The *select* API provides the standard XPath result format that is a list or an elementary
86
89
  datatype's value. If you want only to iterate over results you can use the generator function
@@ -89,52 +92,62 @@ datatype's value. If you want only to iterate over results you can use the gener
89
92
  The selectors API works also using XML data trees based on the `lxml.etree <http://lxml.de>`_
90
93
  library:
91
94
 
92
- >>> import elementpath
93
- >>> import lxml.etree as etree
94
- >>> root = etree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
95
- >>> elementpath.select(root, '/A/B2/*')
96
- [<Element C1 at ...>, <Element C2 at ...>, <Element C3 at ...>]
95
+ .. code-block:: pycon
96
+
97
+ >>> import elementpath
98
+ >>> import lxml.etree as etree
99
+ >>> root = etree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
100
+ >>> elementpath.select(root, '/A/B2/*')
101
+ [<Element C1 at ...>, <Element C2 at ...>, <Element C3 at ...>]
97
102
 
98
103
  When you need to apply the same XPath expression to several XML data you can also use the
99
104
  *Selector* class, creating an instance and then using it to apply the path on distinct XML
100
105
  data:
101
106
 
102
- >>> import elementpath
103
- >>> import lxml.etree as etree
104
- >>> selector = elementpath.Selector('/A/*/*')
105
- >>> root = etree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
106
- >>> selector.select(root)
107
- [<Element C1 at ...>, <Element C2 at ...>, <Element C3 at ...>]
108
- >>> root = etree.XML('<A><B1><C0/></B1><B2><C1/><C2/><C3/></B2></A>')
109
- >>> selector.select(root)
110
- [<Element C0 at ...>, <Element C1 at ...>, <Element C2 at ...>, <Element C3 at ...>]
107
+ .. code-block:: pycon
108
+
109
+ >>> import elementpath
110
+ >>> import lxml.etree as etree
111
+ >>> selector = elementpath.Selector('/A/*/*')
112
+ >>> root = etree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
113
+ >>> selector.select(root)
114
+ [<Element C1 at ...>, <Element C2 at ...>, <Element C3 at ...>]
115
+ >>> root = etree.XML('<A><B1><C0/></B1><B2><C1/><C2/><C3/></B2></A>')
116
+ >>> selector.select(root)
117
+ [<Element C0 at ...>, <Element C1 at ...>, <Element C2 at ...>, <Element C3 at ...>]
111
118
 
112
119
  Public API classes and functions are described into the
113
120
  `elementpath manual on the "Read the Docs" site <http://elementpath.readthedocs.io/en/latest/>`_.
114
121
 
115
122
  For default the XPath 2.0 is used. If you need XPath 1.0 parser provide the *parser* argument:
116
123
 
117
- >>> from elementpath import select, XPath1Parser
118
- >>> from xml.etree import ElementTree
119
- >>> root = ElementTree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
120
- >>> select(root, '/A/B2/*', parser=XPath1Parser)
121
- [<Element 'C1' at ...>, <Element 'C2' at ...>, <Element 'C3' at ...>]
124
+ .. code-block:: pycon
125
+
126
+ >>> from elementpath import select, XPath1Parser
127
+ >>> from xml.etree import ElementTree
128
+ >>> root = ElementTree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
129
+ >>> select(root, '/A/B2/*', parser=XPath1Parser)
130
+ [<Element 'C1' at ...>, <Element 'C2' at ...>, <Element 'C3' at ...>]
122
131
 
123
132
  For XPath 3.0/3.1 import the parser from *elementpath.xpath3* subpackage, that is not loaded
124
133
  for default:
125
134
 
126
- >>> from elementpath.xpath3 import XPath3Parser
127
- >>> select(root, 'math:atan(1.0e0)', parser=XPath3Parser)
128
- 0.7853981633974483
135
+ .. code-block:: pycon
136
+
137
+ >>> from elementpath.xpath3 import XPath3Parser
138
+ >>> select(root, 'math:atan(1.0e0)', parser=XPath3Parser)
139
+ 0.7853981633974483
129
140
 
130
141
  Note: *XPath3Parser* is an alias of *XPath31Parser*.
131
142
 
132
143
  If you need only XPath 3.0 you can also use a more specific subpackage,
133
144
  avoiding the loading of XPath 3.1 implementation:
134
145
 
135
- >>> from elementpath.xpath30 import XPath30Parser
136
- >>> select(root, 'math:atan(1.0e0)', parser=XPath30Parser)
137
- 0.7853981633974483
146
+ .. code-block:: pycon
147
+
148
+ >>> from elementpath.xpath30 import XPath30Parser
149
+ >>> select(root, 'math:atan(1.0e0)', parser=XPath30Parser)
150
+ 0.7853981633974483
138
151
 
139
152
 
140
153
  Contributing
@@ -34,11 +34,13 @@ You can install the package with *pip* in a Python 3.8+ environment::
34
34
 
35
35
  For using it import the package and apply the selectors on ElementTree nodes:
36
36
 
37
- >>> import elementpath
38
- >>> from xml.etree import ElementTree
39
- >>> root = ElementTree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
40
- >>> elementpath.select(root, '/A/B2/*')
41
- [<Element 'C1' at ...>, <Element 'C2' at ...>, <Element 'C3' at ...>]
37
+ .. code-block:: pycon
38
+
39
+ >>> import elementpath
40
+ >>> from xml.etree import ElementTree
41
+ >>> root = ElementTree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
42
+ >>> elementpath.select(root, '/A/B2/*')
43
+ [<Element 'C1' at ...>, <Element 'C2' at ...>, <Element 'C3' at ...>]
42
44
 
43
45
  The *select* API provides the standard XPath result format that is a list or an elementary
44
46
  datatype's value. If you want only to iterate over results you can use the generator function
@@ -47,52 +49,62 @@ datatype's value. If you want only to iterate over results you can use the gener
47
49
  The selectors API works also using XML data trees based on the `lxml.etree <http://lxml.de>`_
48
50
  library:
49
51
 
50
- >>> import elementpath
51
- >>> import lxml.etree as etree
52
- >>> root = etree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
53
- >>> elementpath.select(root, '/A/B2/*')
54
- [<Element C1 at ...>, <Element C2 at ...>, <Element C3 at ...>]
52
+ .. code-block:: pycon
53
+
54
+ >>> import elementpath
55
+ >>> import lxml.etree as etree
56
+ >>> root = etree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
57
+ >>> elementpath.select(root, '/A/B2/*')
58
+ [<Element C1 at ...>, <Element C2 at ...>, <Element C3 at ...>]
55
59
 
56
60
  When you need to apply the same XPath expression to several XML data you can also use the
57
61
  *Selector* class, creating an instance and then using it to apply the path on distinct XML
58
62
  data:
59
63
 
60
- >>> import elementpath
61
- >>> import lxml.etree as etree
62
- >>> selector = elementpath.Selector('/A/*/*')
63
- >>> root = etree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
64
- >>> selector.select(root)
65
- [<Element C1 at ...>, <Element C2 at ...>, <Element C3 at ...>]
66
- >>> root = etree.XML('<A><B1><C0/></B1><B2><C1/><C2/><C3/></B2></A>')
67
- >>> selector.select(root)
68
- [<Element C0 at ...>, <Element C1 at ...>, <Element C2 at ...>, <Element C3 at ...>]
64
+ .. code-block:: pycon
65
+
66
+ >>> import elementpath
67
+ >>> import lxml.etree as etree
68
+ >>> selector = elementpath.Selector('/A/*/*')
69
+ >>> root = etree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
70
+ >>> selector.select(root)
71
+ [<Element C1 at ...>, <Element C2 at ...>, <Element C3 at ...>]
72
+ >>> root = etree.XML('<A><B1><C0/></B1><B2><C1/><C2/><C3/></B2></A>')
73
+ >>> selector.select(root)
74
+ [<Element C0 at ...>, <Element C1 at ...>, <Element C2 at ...>, <Element C3 at ...>]
69
75
 
70
76
  Public API classes and functions are described into the
71
77
  `elementpath manual on the "Read the Docs" site <http://elementpath.readthedocs.io/en/latest/>`_.
72
78
 
73
79
  For default the XPath 2.0 is used. If you need XPath 1.0 parser provide the *parser* argument:
74
80
 
75
- >>> from elementpath import select, XPath1Parser
76
- >>> from xml.etree import ElementTree
77
- >>> root = ElementTree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
78
- >>> select(root, '/A/B2/*', parser=XPath1Parser)
79
- [<Element 'C1' at ...>, <Element 'C2' at ...>, <Element 'C3' at ...>]
81
+ .. code-block:: pycon
82
+
83
+ >>> from elementpath import select, XPath1Parser
84
+ >>> from xml.etree import ElementTree
85
+ >>> root = ElementTree.XML('<A><B1/><B2><C1/><C2/><C3/></B2></A>')
86
+ >>> select(root, '/A/B2/*', parser=XPath1Parser)
87
+ [<Element 'C1' at ...>, <Element 'C2' at ...>, <Element 'C3' at ...>]
80
88
 
81
89
  For XPath 3.0/3.1 import the parser from *elementpath.xpath3* subpackage, that is not loaded
82
90
  for default:
83
91
 
84
- >>> from elementpath.xpath3 import XPath3Parser
85
- >>> select(root, 'math:atan(1.0e0)', parser=XPath3Parser)
86
- 0.7853981633974483
92
+ .. code-block:: pycon
93
+
94
+ >>> from elementpath.xpath3 import XPath3Parser
95
+ >>> select(root, 'math:atan(1.0e0)', parser=XPath3Parser)
96
+ 0.7853981633974483
87
97
 
88
98
  Note: *XPath3Parser* is an alias of *XPath31Parser*.
89
99
 
90
100
  If you need only XPath 3.0 you can also use a more specific subpackage,
91
101
  avoiding the loading of XPath 3.1 implementation:
92
102
 
93
- >>> from elementpath.xpath30 import XPath30Parser
94
- >>> select(root, 'math:atan(1.0e0)', parser=XPath30Parser)
95
- 0.7853981633974483
103
+ .. code-block:: pycon
104
+
105
+ >>> from elementpath.xpath30 import XPath30Parser
106
+ >>> select(root, 'math:atan(1.0e0)', parser=XPath30Parser)
107
+ 0.7853981633974483
96
108
 
97
109
 
98
110
  Contributing
@@ -29,9 +29,9 @@ copyright = '2018-2024, SISSA (International School for Advanced Studies)'
29
29
  author = 'Davide Brunato'
30
30
 
31
31
  # The short X.Y version
32
- version = '4.4'
32
+ version = '4.6'
33
33
  # The full version, including alpha/beta/rc tags
34
- release = '4.4.0'
34
+ release = '4.6.0'
35
35
 
36
36
  # -- General configuration ---------------------------------------------------
37
37
 
@@ -147,6 +147,8 @@ XPath regular expressions
147
147
  =========================
148
148
 
149
149
  .. autofunction:: elementpath.translate_pattern
150
+ .. autofunction:: elementpath.install_unicode_data
151
+ .. autofunction:: elementpath.unicode_version
150
152
 
151
153
 
152
154
  Exception classes
@@ -154,6 +156,7 @@ Exception classes
154
156
 
155
157
  .. autoexception:: elementpath.ElementPathError
156
158
  .. autoexception:: elementpath.MissingContextError
159
+ .. autoexception:: elementpath.UnsupportedFeatureError
157
160
  .. autoexception:: elementpath.RegexError
158
161
  .. autoexception:: elementpath.ElementPathLocaleError
159
162
 
@@ -7,7 +7,7 @@
7
7
  #
8
8
  # @author Davide Brunato <brunato@sissa.it>
9
9
  #
10
- __version__ = '4.4.0'
10
+ __version__ = '4.6.0'
11
11
  __author__ = "Davide Brunato"
12
12
  __contact__ = "brunato@sissa.it"
13
13
  __copyright__ = "Copyright 2018-2024, SISSA"
@@ -23,7 +23,7 @@ from . import protocols # Protocols for type annotations
23
23
  from .exceptions import ElementPathError, MissingContextError, ElementPathKeyError, \
24
24
  ElementPathZeroDivisionError, ElementPathNameError, ElementPathOverflowError, \
25
25
  ElementPathRuntimeError, ElementPathSyntaxError, ElementPathTypeError, \
26
- ElementPathValueError, ElementPathLocaleError
26
+ ElementPathValueError, ElementPathLocaleError, UnsupportedFeatureError
27
27
 
28
28
  from .xpath_context import XPathContext, XPathSchemaContext
29
29
  from .xpath_nodes import XPathNode, DocumentNode, ElementNode, AttributeNode, \
@@ -36,10 +36,11 @@ from .xpath1 import XPath1Parser
36
36
  from .xpath2 import XPath2Parser
37
37
  from .xpath_selectors import select, iter_select, Selector
38
38
  from .schema_proxy import AbstractSchemaProxy
39
- from .regex import RegexError, translate_pattern
39
+ from .regex import RegexError, translate_pattern, install_unicode_data, unicode_version
40
40
 
41
41
  __all__ = ['datatypes', 'protocols', 'etree', 'ElementPathError', 'MissingContextError',
42
- 'ElementPathKeyError', 'ElementPathZeroDivisionError', 'ElementPathNameError',
42
+ 'UnsupportedFeatureError', 'ElementPathKeyError',
43
+ 'ElementPathZeroDivisionError', 'ElementPathNameError',
43
44
  'ElementPathOverflowError', 'ElementPathRuntimeError', 'ElementPathSyntaxError',
44
45
  'ElementPathTypeError', 'ElementPathValueError', 'ElementPathLocaleError',
45
46
  'XPathContext', 'XPathSchemaContext', 'XPathNode', 'DocumentNode',
@@ -48,4 +49,5 @@ __all__ = ['datatypes', 'protocols', 'etree', 'ElementPathError', 'MissingContex
48
49
  'SchemaElementNode', 'get_node_tree', 'build_node_tree',
49
50
  'build_lxml_node_tree', 'build_schema_node_tree', 'XPathToken',
50
51
  'XPathFunction', 'XPath1Parser', 'XPath2Parser', 'select', 'iter_select',
51
- 'Selector', 'AbstractSchemaProxy', 'RegexError', 'translate_pattern']
52
+ 'Selector', 'AbstractSchemaProxy', 'RegexError', 'translate_pattern',
53
+ 'install_unicode_data', 'unicode_version']
@@ -0,0 +1,27 @@
1
+ #
2
+ # Copyright (c), 2024, SISSA (International School for Advanced Studies).
3
+ # All rights reserved.
4
+ # This file is distributed under the terms of the MIT License.
5
+ # See the file 'LICENSE' in the root directory of the present
6
+ # distribution, or http://opensource.org/licenses/MIT.
7
+ #
8
+ # @author Davide Brunato <brunato@sissa.it>
9
+ #
10
+ """
11
+ Version related imports for subscriptable types for type annotations (no builtins).
12
+ """
13
+ import sys
14
+
15
+ if sys.version_info < (3, 9):
16
+ from typing import Callable, Counter, Deque, Iterable, Iterator, \
17
+ Mapping, Match, MutableMapping, MutableSequence, MutableSet, Pattern, Sequence
18
+ else:
19
+ from collections import deque as Deque, Counter # noqa
20
+ from collections.abc import Callable, Iterable, Iterator, Mapping, MutableMapping, \
21
+ MutableSequence, MutableSet, Sequence
22
+ from re import Match, Pattern
23
+
24
+
25
+ __all__ = ['Callable', 'Counter', 'Deque', 'Iterable', 'Iterator', 'Match',
26
+ 'Mapping', 'MutableMapping', 'MutableSequence', 'MutableSet',
27
+ 'Pattern', 'Sequence']
@@ -0,0 +1,43 @@
1
+ #
2
+ # Copyright (c), 2021, SISSA (International School for Advanced Studies).
3
+ # All rights reserved.
4
+ # This file is distributed under the terms of the MIT License.
5
+ # See the file 'LICENSE' in the root directory of the present
6
+ # distribution, or http://opensource.org/licenses/MIT.
7
+ #
8
+ # @author Davide Brunato <brunato@sissa.it>
9
+ #
10
+ """
11
+ Common type hints aliases for elementpath.
12
+ """
13
+ from typing import Any, List, Optional, NoReturn, Tuple, Type, TYPE_CHECKING, TypeVar, Union
14
+
15
+ from elementpath._typing import MutableMapping
16
+
17
+ ##
18
+ # Type aliases
19
+ NamespacesType = MutableMapping[str, str]
20
+ NsmapType = MutableMapping[Optional[str], str] # compatible with the nsmap of lxml Element
21
+ AnyNsmapType = Union[NamespacesType, NsmapType, None] # for composition and function arguments
22
+
23
+ NargsType = Optional[Union[int, Tuple[int, Optional[int]]]]
24
+ ClassCheckType = Union[Type[Any], Tuple[Type[Any], ...]]
25
+
26
+ T = TypeVar('T')
27
+ Emptiable = Union[T, List[NoReturn]]
28
+ SequenceType = Union[T, List[T]]
29
+ InputType = Union[None, T, List[T], Tuple[T, ...]]
30
+
31
+ if TYPE_CHECKING:
32
+ from elementpath.datatypes import AtomicType, ArithmeticType, NumericType
33
+ from elementpath.xpath_nodes import ChildNodeType, ParentNodeType
34
+ from elementpath.tree_builders import RootArgType
35
+ from elementpath.xpath_context import ContextType, FunctionArgType, ItemType, \
36
+ ItemArgType, ValueType
37
+ from elementpath.xpath_tokens import XPathParserType, XPathTokenType
38
+
39
+ __all__ = ['NamespacesType', 'NsmapType', 'AnyNsmapType', 'NargsType',
40
+ 'ClassCheckType', 'Emptiable', 'SequenceType', 'InputType',
41
+ 'AtomicType', 'ArithmeticType', 'NumericType', 'ChildNodeType',
42
+ 'ParentNodeType', 'RootArgType', 'ContextType', 'FunctionArgType',
43
+ 'ItemType', 'ItemArgType', 'ValueType', 'XPathParserType', 'XPathTokenType']
@@ -14,7 +14,7 @@ from types import TracebackType
14
14
  from typing import TYPE_CHECKING, Any, Optional, Tuple, Type, Union
15
15
  from urllib.parse import urljoin, urlsplit
16
16
 
17
- from .exceptions import xpath_error
17
+ from elementpath.exceptions import xpath_error
18
18
 
19
19
  if TYPE_CHECKING:
20
20
  from .xpath_tokens import XPathToken
@@ -173,8 +173,8 @@ class CollationManager(context_class_base):
173
173
  def find(self, a: str, b: str) -> int:
174
174
  return self.strxfrm(a).find(self.strxfrm(b))
175
175
 
176
- def startswith(self, a: str, b: str) -> int:
176
+ def startswith(self, a: str, b: str) -> bool:
177
177
  return self.strxfrm(a).startswith(self.strxfrm(b))
178
178
 
179
- def endswith(self, a: str, b: str) -> int:
179
+ def endswith(self, a: str, b: str) -> bool:
180
180
  return self.strxfrm(a).endswith(self.strxfrm(b))
@@ -11,15 +11,16 @@ import math
11
11
  from decimal import Decimal
12
12
  from functools import cmp_to_key
13
13
  from itertools import zip_longest
14
- from typing import Any, Callable, Optional, Iterable, Iterator
15
-
16
- from .protocols import ElementProtocol
17
- from .exceptions import xpath_error
18
- from .datatypes import UntypedAtomic, AnyURI, AbstractQName
19
- from .collations import UNICODE_CODEPOINT_COLLATION, CollationManager
20
- from .xpath_nodes import XPathNode, ElementNode, AttributeNode, NamespaceNode, \
21
- TextNode, CommentNode, ProcessingInstructionNode, DocumentNode
22
- from .xpath_tokens import XPathToken, XPathFunction, XPathMap, XPathArray
14
+ from typing import Any, Optional
15
+
16
+ from elementpath._typing import Callable, Iterable, Iterator
17
+ from elementpath.protocols import ElementProtocol
18
+ from elementpath.exceptions import xpath_error
19
+ from elementpath.datatypes import UntypedAtomic, AnyURI, AbstractQName
20
+ from elementpath.collations import UNICODE_CODEPOINT_COLLATION, CollationManager
21
+ from elementpath.xpath_nodes import XPathNode, ElementNode, AttributeNode, \
22
+ NamespaceNode, TextNode, CommentNode, ProcessingInstructionNode, DocumentNode
23
+ from elementpath.xpath_tokens import XPathToken, XPathFunction, XPathMap, XPathArray
23
24
 
24
25
 
25
26
  def deep_equal(seq1: Iterable[Any],
@@ -0,0 +1,61 @@
1
+ #
2
+ # Copyright (c), 2018-2020, SISSA (International School for Advanced Studies).
3
+ # All rights reserved.
4
+ # This file is distributed under the terms of the MIT License.
5
+ # See the file 'LICENSE' in the root directory of the present
6
+ # distribution, or http://opensource.org/licenses/MIT.
7
+ #
8
+ # @author Davide Brunato <brunato@sissa.it>
9
+ #
10
+ """
11
+ XSD atomic datatypes subpackage. Includes a class for UntypedAtomic data and
12
+ classes for other XSD built-in types. This subpackage raises only built-in
13
+ exceptions in order to be reusable in other packages.
14
+ """
15
+ from decimal import Decimal
16
+ from typing import Union
17
+
18
+ from .atomic_types import xsd10_atomic_types, xsd11_atomic_types, \
19
+ AtomicTypeMeta, AnyAtomicType
20
+ from .untyped import UntypedAtomic
21
+ from .qname import AbstractQName, QName, Notation
22
+ from .numeric import Float10, Float, Integer, Int, NegativeInteger, \
23
+ PositiveInteger, NonNegativeInteger, NonPositiveInteger, Long, \
24
+ Short, Byte, UnsignedByte, UnsignedInt, UnsignedLong, UnsignedShort
25
+ from .string import NormalizedString, XsdToken, Name, NCName, NMToken, Id, \
26
+ Idref, Language, Entity
27
+ from .uri import AnyURI
28
+ from .binary import AbstractBinary, Base64Binary, HexBinary
29
+ from .datetime import AbstractDateTime, DateTime10, DateTime, DateTimeStamp, \
30
+ Date10, Date, GregorianDay, GregorianMonth, GregorianYear, GregorianYear10, \
31
+ GregorianMonthDay, GregorianYearMonth, GregorianYearMonth10, Time, Timezone, \
32
+ Duration, DayTimeDuration, YearMonthDuration, OrderedDateTime
33
+ from .proxies import BooleanProxy, DecimalProxy, DoubleProxy10, DoubleProxy, \
34
+ StringProxy, NumericProxy, ArithmeticProxy
35
+
36
+
37
+ xsd11_atomic_types.update(
38
+ (k, v) for k, v in xsd10_atomic_types.items() if k not in xsd11_atomic_types
39
+ )
40
+
41
+ ###
42
+ # Aliases for type annotations
43
+ AtomicType = Union[str, int, float, Decimal, bool, AnyAtomicType]
44
+ NumericType = Union[int, float, Decimal]
45
+ ArithmeticType = Union[NumericType, AbstractDateTime, Duration, UntypedAtomic]
46
+ DatetimeValueType = AbstractDateTime # keep until v5.0 for backward compatibility
47
+
48
+ __all__ = ['xsd10_atomic_types', 'xsd11_atomic_types',
49
+ 'AtomicTypeMeta', 'AnyAtomicType', 'NumericProxy', 'ArithmeticProxy',
50
+ 'AbstractDateTime', 'DateTime10', 'DateTime', 'DateTimeStamp', 'Date10',
51
+ 'Date', 'Time', 'GregorianDay', 'GregorianMonth', 'GregorianMonthDay',
52
+ 'GregorianYear10', 'GregorianYear', 'GregorianYearMonth10', 'GregorianYearMonth',
53
+ 'Timezone', 'Duration', 'YearMonthDuration', 'DayTimeDuration', 'StringProxy',
54
+ 'NormalizedString', 'XsdToken', 'Language', 'Name', 'NCName', 'Id', 'Idref',
55
+ 'Entity', 'NMToken', 'Base64Binary', 'HexBinary', 'Float10', 'Float',
56
+ 'Integer', 'NonPositiveInteger', 'NegativeInteger', 'Long', 'Int', 'Short',
57
+ 'Byte', 'NonNegativeInteger', 'PositiveInteger', 'UnsignedLong', 'UnsignedInt',
58
+ 'UnsignedShort', 'UnsignedByte', 'AnyURI', 'Notation', 'QName', 'BooleanProxy',
59
+ 'DecimalProxy', 'DoubleProxy10', 'DoubleProxy', 'UntypedAtomic', 'AbstractBinary',
60
+ 'AtomicType', 'DatetimeValueType', 'OrderedDateTime', 'AbstractQName',
61
+ 'NumericType', 'ArithmeticType']
@@ -7,10 +7,12 @@
7
7
  #
8
8
  # @author Davide Brunato <brunato@sissa.it>
9
9
  #
10
- from abc import ABCMeta
11
- from typing import Any, Dict, Optional, Pattern, Tuple, Type
10
+ from abc import ABCMeta, abstractmethod
11
+ from typing import Any, Dict, Optional, Tuple, Type
12
12
  import re
13
13
 
14
+ from elementpath._typing import Pattern
15
+
14
16
  XSD_NAMESPACE = "http://www.w3.org/2001/XMLSchema"
15
17
 
16
18
  ###
@@ -98,3 +100,7 @@ class AtomicTypeMeta(ABCMeta):
98
100
 
99
101
  class AnyAtomicType(metaclass=AtomicTypeMeta):
100
102
  name = 'anyAtomicType'
103
+
104
+ @abstractmethod
105
+ def __init__(self, value: Any) -> None:
106
+ raise NotImplementedError()
@@ -7,12 +7,12 @@
7
7
  #
8
8
  # @author Davide Brunato <brunato@sissa.it>
9
9
  #
10
+ import re
10
11
  from abc import abstractmethod
11
12
  from typing import Any, Callable, Union
12
- import re
13
13
  import codecs
14
14
 
15
- from ..helpers import collapse_white_spaces
15
+ from elementpath.helpers import collapse_white_spaces
16
16
  from .atomic_types import AnyAtomicType
17
17
  from .untyped import UntypedAtomic
18
18