@rowstile/cli-linux-x64 0.1.0-alpha.2

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 (565) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +5 -0
  3. package/package.json +26 -0
  4. package/python/bin/python3.13 +0 -0
  5. package/python/bin/python3.13-config +122 -0
  6. package/python/lib/libpython3.13.so.1.0 +0 -0
  7. package/python/lib/libpython3.so +0 -0
  8. package/python/lib/python3.13/LICENSE.txt +277 -0
  9. package/python/lib/python3.13/__future__.py +147 -0
  10. package/python/lib/python3.13/__hello__.py +16 -0
  11. package/python/lib/python3.13/_aix_support.py +108 -0
  12. package/python/lib/python3.13/_android_support.py +192 -0
  13. package/python/lib/python3.13/_apple_support.py +66 -0
  14. package/python/lib/python3.13/_collections_abc.py +1187 -0
  15. package/python/lib/python3.13/_colorize.py +119 -0
  16. package/python/lib/python3.13/_compat_pickle.py +251 -0
  17. package/python/lib/python3.13/_compression.py +162 -0
  18. package/python/lib/python3.13/_ios_support.py +71 -0
  19. package/python/lib/python3.13/_markupbase.py +396 -0
  20. package/python/lib/python3.13/_opcode_metadata.py +343 -0
  21. package/python/lib/python3.13/_osx_support.py +579 -0
  22. package/python/lib/python3.13/_py_abc.py +147 -0
  23. package/python/lib/python3.13/_pydatetime.py +2640 -0
  24. package/python/lib/python3.13/_pydecimal.py +6356 -0
  25. package/python/lib/python3.13/_pyio.py +2714 -0
  26. package/python/lib/python3.13/_pylong.py +363 -0
  27. package/python/lib/python3.13/_pyrepl/__init__.py +19 -0
  28. package/python/lib/python3.13/_pyrepl/__main__.py +10 -0
  29. package/python/lib/python3.13/_pyrepl/_minimal_curses.py +68 -0
  30. package/python/lib/python3.13/_pyrepl/_threading_handler.py +74 -0
  31. package/python/lib/python3.13/_pyrepl/base_eventqueue.py +110 -0
  32. package/python/lib/python3.13/_pyrepl/commands.py +492 -0
  33. package/python/lib/python3.13/_pyrepl/completing_reader.py +295 -0
  34. package/python/lib/python3.13/_pyrepl/console.py +229 -0
  35. package/python/lib/python3.13/_pyrepl/curses.py +33 -0
  36. package/python/lib/python3.13/_pyrepl/fancy_termios.py +82 -0
  37. package/python/lib/python3.13/_pyrepl/historical_reader.py +419 -0
  38. package/python/lib/python3.13/_pyrepl/input.py +114 -0
  39. package/python/lib/python3.13/_pyrepl/keymap.py +213 -0
  40. package/python/lib/python3.13/_pyrepl/main.py +59 -0
  41. package/python/lib/python3.13/_pyrepl/mypy.ini +29 -0
  42. package/python/lib/python3.13/_pyrepl/pager.py +175 -0
  43. package/python/lib/python3.13/_pyrepl/reader.py +764 -0
  44. package/python/lib/python3.13/_pyrepl/readline.py +599 -0
  45. package/python/lib/python3.13/_pyrepl/simple_interact.py +180 -0
  46. package/python/lib/python3.13/_pyrepl/trace.py +21 -0
  47. package/python/lib/python3.13/_pyrepl/types.py +10 -0
  48. package/python/lib/python3.13/_pyrepl/unix_console.py +852 -0
  49. package/python/lib/python3.13/_pyrepl/unix_eventqueue.py +76 -0
  50. package/python/lib/python3.13/_pyrepl/utils.py +83 -0
  51. package/python/lib/python3.13/_pyrepl/windows_console.py +687 -0
  52. package/python/lib/python3.13/_pyrepl/windows_eventqueue.py +42 -0
  53. package/python/lib/python3.13/_sitebuiltins.py +91 -0
  54. package/python/lib/python3.13/_strptime.py +800 -0
  55. package/python/lib/python3.13/_sysconfigdata__linux_x86_64-linux-gnu.py +1079 -0
  56. package/python/lib/python3.13/_threading_local.py +120 -0
  57. package/python/lib/python3.13/_weakrefset.py +205 -0
  58. package/python/lib/python3.13/abc.py +188 -0
  59. package/python/lib/python3.13/antigravity.py +17 -0
  60. package/python/lib/python3.13/argparse.py +2690 -0
  61. package/python/lib/python3.13/ast.py +1865 -0
  62. package/python/lib/python3.13/asyncio/__init__.py +47 -0
  63. package/python/lib/python3.13/asyncio/__main__.py +211 -0
  64. package/python/lib/python3.13/asyncio/base_events.py +2086 -0
  65. package/python/lib/python3.13/asyncio/base_futures.py +67 -0
  66. package/python/lib/python3.13/asyncio/base_subprocess.py +312 -0
  67. package/python/lib/python3.13/asyncio/base_tasks.py +94 -0
  68. package/python/lib/python3.13/asyncio/constants.py +41 -0
  69. package/python/lib/python3.13/asyncio/coroutines.py +109 -0
  70. package/python/lib/python3.13/asyncio/events.py +885 -0
  71. package/python/lib/python3.13/asyncio/exceptions.py +62 -0
  72. package/python/lib/python3.13/asyncio/format_helpers.py +84 -0
  73. package/python/lib/python3.13/asyncio/futures.py +425 -0
  74. package/python/lib/python3.13/asyncio/locks.py +617 -0
  75. package/python/lib/python3.13/asyncio/log.py +7 -0
  76. package/python/lib/python3.13/asyncio/mixins.py +21 -0
  77. package/python/lib/python3.13/asyncio/proactor_events.py +891 -0
  78. package/python/lib/python3.13/asyncio/protocols.py +216 -0
  79. package/python/lib/python3.13/asyncio/queues.py +309 -0
  80. package/python/lib/python3.13/asyncio/runners.py +217 -0
  81. package/python/lib/python3.13/asyncio/selector_events.py +1328 -0
  82. package/python/lib/python3.13/asyncio/sslproto.py +929 -0
  83. package/python/lib/python3.13/asyncio/staggered.py +174 -0
  84. package/python/lib/python3.13/asyncio/streams.py +787 -0
  85. package/python/lib/python3.13/asyncio/subprocess.py +229 -0
  86. package/python/lib/python3.13/asyncio/taskgroups.py +278 -0
  87. package/python/lib/python3.13/asyncio/tasks.py +1121 -0
  88. package/python/lib/python3.13/asyncio/threads.py +26 -0
  89. package/python/lib/python3.13/asyncio/timeouts.py +185 -0
  90. package/python/lib/python3.13/asyncio/transports.py +337 -0
  91. package/python/lib/python3.13/asyncio/trsock.py +98 -0
  92. package/python/lib/python3.13/asyncio/unix_events.py +1550 -0
  93. package/python/lib/python3.13/asyncio/windows_events.py +906 -0
  94. package/python/lib/python3.13/asyncio/windows_utils.py +181 -0
  95. package/python/lib/python3.13/base64.py +628 -0
  96. package/python/lib/python3.13/bdb.py +973 -0
  97. package/python/lib/python3.13/bisect.py +118 -0
  98. package/python/lib/python3.13/bz2.py +352 -0
  99. package/python/lib/python3.13/cProfile.py +197 -0
  100. package/python/lib/python3.13/calendar.py +813 -0
  101. package/python/lib/python3.13/cmd.py +409 -0
  102. package/python/lib/python3.13/code.py +386 -0
  103. package/python/lib/python3.13/codecs.py +1132 -0
  104. package/python/lib/python3.13/codeop.py +155 -0
  105. package/python/lib/python3.13/collections/__init__.py +1603 -0
  106. package/python/lib/python3.13/colorsys.py +166 -0
  107. package/python/lib/python3.13/compileall.py +470 -0
  108. package/python/lib/python3.13/concurrent/__init__.py +1 -0
  109. package/python/lib/python3.13/concurrent/futures/__init__.py +54 -0
  110. package/python/lib/python3.13/concurrent/futures/_base.py +660 -0
  111. package/python/lib/python3.13/concurrent/futures/process.py +892 -0
  112. package/python/lib/python3.13/concurrent/futures/thread.py +240 -0
  113. package/python/lib/python3.13/configparser.py +1396 -0
  114. package/python/lib/python3.13/contextlib.py +814 -0
  115. package/python/lib/python3.13/contextvars.py +4 -0
  116. package/python/lib/python3.13/copy.py +306 -0
  117. package/python/lib/python3.13/copyreg.py +217 -0
  118. package/python/lib/python3.13/csv.py +527 -0
  119. package/python/lib/python3.13/ctypes/__init__.py +605 -0
  120. package/python/lib/python3.13/ctypes/_aix.py +327 -0
  121. package/python/lib/python3.13/ctypes/_endian.py +78 -0
  122. package/python/lib/python3.13/ctypes/macholib/README.ctypes +7 -0
  123. package/python/lib/python3.13/ctypes/macholib/__init__.py +9 -0
  124. package/python/lib/python3.13/ctypes/macholib/dyld.py +165 -0
  125. package/python/lib/python3.13/ctypes/macholib/dylib.py +42 -0
  126. package/python/lib/python3.13/ctypes/macholib/fetch_macholib +2 -0
  127. package/python/lib/python3.13/ctypes/macholib/fetch_macholib.bat +1 -0
  128. package/python/lib/python3.13/ctypes/macholib/framework.py +42 -0
  129. package/python/lib/python3.13/ctypes/util.py +387 -0
  130. package/python/lib/python3.13/ctypes/wintypes.py +202 -0
  131. package/python/lib/python3.13/curses/__init__.py +101 -0
  132. package/python/lib/python3.13/curses/ascii.py +99 -0
  133. package/python/lib/python3.13/curses/has_key.py +192 -0
  134. package/python/lib/python3.13/curses/panel.py +6 -0
  135. package/python/lib/python3.13/curses/textpad.py +236 -0
  136. package/python/lib/python3.13/dataclasses.py +1679 -0
  137. package/python/lib/python3.13/datetime.py +9 -0
  138. package/python/lib/python3.13/dbm/__init__.py +194 -0
  139. package/python/lib/python3.13/dbm/dumb.py +319 -0
  140. package/python/lib/python3.13/dbm/gnu.py +3 -0
  141. package/python/lib/python3.13/dbm/ndbm.py +3 -0
  142. package/python/lib/python3.13/dbm/sqlite3.py +144 -0
  143. package/python/lib/python3.13/decimal.py +109 -0
  144. package/python/lib/python3.13/difflib.py +2058 -0
  145. package/python/lib/python3.13/dis.py +1075 -0
  146. package/python/lib/python3.13/doctest.py +2919 -0
  147. package/python/lib/python3.13/email/__init__.py +61 -0
  148. package/python/lib/python3.13/email/_encoded_words.py +233 -0
  149. package/python/lib/python3.13/email/_header_value_parser.py +3153 -0
  150. package/python/lib/python3.13/email/_parseaddr.py +563 -0
  151. package/python/lib/python3.13/email/_policybase.py +382 -0
  152. package/python/lib/python3.13/email/architecture.rst +216 -0
  153. package/python/lib/python3.13/email/base64mime.py +115 -0
  154. package/python/lib/python3.13/email/charset.py +396 -0
  155. package/python/lib/python3.13/email/contentmanager.py +254 -0
  156. package/python/lib/python3.13/email/encoders.py +65 -0
  157. package/python/lib/python3.13/email/errors.py +117 -0
  158. package/python/lib/python3.13/email/feedparser.py +536 -0
  159. package/python/lib/python3.13/email/generator.py +530 -0
  160. package/python/lib/python3.13/email/header.py +582 -0
  161. package/python/lib/python3.13/email/headerregistry.py +618 -0
  162. package/python/lib/python3.13/email/iterators.py +68 -0
  163. package/python/lib/python3.13/email/message.py +1217 -0
  164. package/python/lib/python3.13/email/mime/__init__.py +0 -0
  165. package/python/lib/python3.13/email/mime/application.py +37 -0
  166. package/python/lib/python3.13/email/mime/audio.py +97 -0
  167. package/python/lib/python3.13/email/mime/base.py +29 -0
  168. package/python/lib/python3.13/email/mime/image.py +152 -0
  169. package/python/lib/python3.13/email/mime/message.py +33 -0
  170. package/python/lib/python3.13/email/mime/multipart.py +47 -0
  171. package/python/lib/python3.13/email/mime/nonmultipart.py +21 -0
  172. package/python/lib/python3.13/email/mime/text.py +40 -0
  173. package/python/lib/python3.13/email/parser.py +127 -0
  174. package/python/lib/python3.13/email/policy.py +232 -0
  175. package/python/lib/python3.13/email/quoprimime.py +300 -0
  176. package/python/lib/python3.13/email/utils.py +497 -0
  177. package/python/lib/python3.13/encodings/__init__.py +179 -0
  178. package/python/lib/python3.13/encodings/__pycache__/__init__.cpython-313.pyc +0 -0
  179. package/python/lib/python3.13/encodings/__pycache__/aliases.cpython-313.pyc +0 -0
  180. package/python/lib/python3.13/encodings/__pycache__/utf_8.cpython-313.pyc +0 -0
  181. package/python/lib/python3.13/encodings/aliases.py +560 -0
  182. package/python/lib/python3.13/encodings/ascii.py +50 -0
  183. package/python/lib/python3.13/encodings/base64_codec.py +55 -0
  184. package/python/lib/python3.13/encodings/big5.py +39 -0
  185. package/python/lib/python3.13/encodings/big5hkscs.py +39 -0
  186. package/python/lib/python3.13/encodings/bz2_codec.py +78 -0
  187. package/python/lib/python3.13/encodings/charmap.py +69 -0
  188. package/python/lib/python3.13/encodings/cp037.py +307 -0
  189. package/python/lib/python3.13/encodings/cp1006.py +307 -0
  190. package/python/lib/python3.13/encodings/cp1026.py +307 -0
  191. package/python/lib/python3.13/encodings/cp1125.py +698 -0
  192. package/python/lib/python3.13/encodings/cp1140.py +307 -0
  193. package/python/lib/python3.13/encodings/cp1250.py +307 -0
  194. package/python/lib/python3.13/encodings/cp1251.py +307 -0
  195. package/python/lib/python3.13/encodings/cp1252.py +307 -0
  196. package/python/lib/python3.13/encodings/cp1253.py +307 -0
  197. package/python/lib/python3.13/encodings/cp1254.py +307 -0
  198. package/python/lib/python3.13/encodings/cp1255.py +307 -0
  199. package/python/lib/python3.13/encodings/cp1256.py +307 -0
  200. package/python/lib/python3.13/encodings/cp1257.py +307 -0
  201. package/python/lib/python3.13/encodings/cp1258.py +307 -0
  202. package/python/lib/python3.13/encodings/cp273.py +307 -0
  203. package/python/lib/python3.13/encodings/cp424.py +307 -0
  204. package/python/lib/python3.13/encodings/cp437.py +698 -0
  205. package/python/lib/python3.13/encodings/cp500.py +307 -0
  206. package/python/lib/python3.13/encodings/cp720.py +309 -0
  207. package/python/lib/python3.13/encodings/cp737.py +698 -0
  208. package/python/lib/python3.13/encodings/cp775.py +697 -0
  209. package/python/lib/python3.13/encodings/cp850.py +698 -0
  210. package/python/lib/python3.13/encodings/cp852.py +698 -0
  211. package/python/lib/python3.13/encodings/cp855.py +698 -0
  212. package/python/lib/python3.13/encodings/cp856.py +307 -0
  213. package/python/lib/python3.13/encodings/cp857.py +694 -0
  214. package/python/lib/python3.13/encodings/cp858.py +698 -0
  215. package/python/lib/python3.13/encodings/cp860.py +698 -0
  216. package/python/lib/python3.13/encodings/cp861.py +698 -0
  217. package/python/lib/python3.13/encodings/cp862.py +698 -0
  218. package/python/lib/python3.13/encodings/cp863.py +698 -0
  219. package/python/lib/python3.13/encodings/cp864.py +690 -0
  220. package/python/lib/python3.13/encodings/cp865.py +698 -0
  221. package/python/lib/python3.13/encodings/cp866.py +698 -0
  222. package/python/lib/python3.13/encodings/cp869.py +689 -0
  223. package/python/lib/python3.13/encodings/cp874.py +307 -0
  224. package/python/lib/python3.13/encodings/cp875.py +307 -0
  225. package/python/lib/python3.13/encodings/cp932.py +39 -0
  226. package/python/lib/python3.13/encodings/cp949.py +39 -0
  227. package/python/lib/python3.13/encodings/cp950.py +39 -0
  228. package/python/lib/python3.13/encodings/euc_jis_2004.py +39 -0
  229. package/python/lib/python3.13/encodings/euc_jisx0213.py +39 -0
  230. package/python/lib/python3.13/encodings/euc_jp.py +39 -0
  231. package/python/lib/python3.13/encodings/euc_kr.py +39 -0
  232. package/python/lib/python3.13/encodings/gb18030.py +39 -0
  233. package/python/lib/python3.13/encodings/gb2312.py +39 -0
  234. package/python/lib/python3.13/encodings/gbk.py +39 -0
  235. package/python/lib/python3.13/encodings/hex_codec.py +55 -0
  236. package/python/lib/python3.13/encodings/hp_roman8.py +314 -0
  237. package/python/lib/python3.13/encodings/hz.py +39 -0
  238. package/python/lib/python3.13/encodings/idna.py +387 -0
  239. package/python/lib/python3.13/encodings/iso2022_jp.py +39 -0
  240. package/python/lib/python3.13/encodings/iso2022_jp_1.py +39 -0
  241. package/python/lib/python3.13/encodings/iso2022_jp_2.py +39 -0
  242. package/python/lib/python3.13/encodings/iso2022_jp_2004.py +39 -0
  243. package/python/lib/python3.13/encodings/iso2022_jp_3.py +39 -0
  244. package/python/lib/python3.13/encodings/iso2022_jp_ext.py +39 -0
  245. package/python/lib/python3.13/encodings/iso2022_kr.py +39 -0
  246. package/python/lib/python3.13/encodings/iso8859_1.py +307 -0
  247. package/python/lib/python3.13/encodings/iso8859_10.py +307 -0
  248. package/python/lib/python3.13/encodings/iso8859_11.py +307 -0
  249. package/python/lib/python3.13/encodings/iso8859_13.py +307 -0
  250. package/python/lib/python3.13/encodings/iso8859_14.py +307 -0
  251. package/python/lib/python3.13/encodings/iso8859_15.py +307 -0
  252. package/python/lib/python3.13/encodings/iso8859_16.py +307 -0
  253. package/python/lib/python3.13/encodings/iso8859_2.py +307 -0
  254. package/python/lib/python3.13/encodings/iso8859_3.py +307 -0
  255. package/python/lib/python3.13/encodings/iso8859_4.py +307 -0
  256. package/python/lib/python3.13/encodings/iso8859_5.py +307 -0
  257. package/python/lib/python3.13/encodings/iso8859_6.py +307 -0
  258. package/python/lib/python3.13/encodings/iso8859_7.py +307 -0
  259. package/python/lib/python3.13/encodings/iso8859_8.py +307 -0
  260. package/python/lib/python3.13/encodings/iso8859_9.py +307 -0
  261. package/python/lib/python3.13/encodings/johab.py +39 -0
  262. package/python/lib/python3.13/encodings/koi8_r.py +307 -0
  263. package/python/lib/python3.13/encodings/koi8_t.py +308 -0
  264. package/python/lib/python3.13/encodings/koi8_u.py +307 -0
  265. package/python/lib/python3.13/encodings/kz1048.py +307 -0
  266. package/python/lib/python3.13/encodings/latin_1.py +50 -0
  267. package/python/lib/python3.13/encodings/mac_arabic.py +698 -0
  268. package/python/lib/python3.13/encodings/mac_croatian.py +307 -0
  269. package/python/lib/python3.13/encodings/mac_cyrillic.py +307 -0
  270. package/python/lib/python3.13/encodings/mac_farsi.py +307 -0
  271. package/python/lib/python3.13/encodings/mac_greek.py +307 -0
  272. package/python/lib/python3.13/encodings/mac_iceland.py +307 -0
  273. package/python/lib/python3.13/encodings/mac_latin2.py +312 -0
  274. package/python/lib/python3.13/encodings/mac_roman.py +307 -0
  275. package/python/lib/python3.13/encodings/mac_romanian.py +307 -0
  276. package/python/lib/python3.13/encodings/mac_turkish.py +307 -0
  277. package/python/lib/python3.13/encodings/mbcs.py +47 -0
  278. package/python/lib/python3.13/encodings/oem.py +41 -0
  279. package/python/lib/python3.13/encodings/palmos.py +308 -0
  280. package/python/lib/python3.13/encodings/ptcp154.py +312 -0
  281. package/python/lib/python3.13/encodings/punycode.py +253 -0
  282. package/python/lib/python3.13/encodings/quopri_codec.py +56 -0
  283. package/python/lib/python3.13/encodings/raw_unicode_escape.py +46 -0
  284. package/python/lib/python3.13/encodings/rot_13.py +113 -0
  285. package/python/lib/python3.13/encodings/shift_jis.py +39 -0
  286. package/python/lib/python3.13/encodings/shift_jis_2004.py +39 -0
  287. package/python/lib/python3.13/encodings/shift_jisx0213.py +39 -0
  288. package/python/lib/python3.13/encodings/tis_620.py +307 -0
  289. package/python/lib/python3.13/encodings/undefined.py +49 -0
  290. package/python/lib/python3.13/encodings/unicode_escape.py +46 -0
  291. package/python/lib/python3.13/encodings/utf_16.py +155 -0
  292. package/python/lib/python3.13/encodings/utf_16_be.py +42 -0
  293. package/python/lib/python3.13/encodings/utf_16_le.py +42 -0
  294. package/python/lib/python3.13/encodings/utf_32.py +150 -0
  295. package/python/lib/python3.13/encodings/utf_32_be.py +37 -0
  296. package/python/lib/python3.13/encodings/utf_32_le.py +37 -0
  297. package/python/lib/python3.13/encodings/utf_7.py +38 -0
  298. package/python/lib/python3.13/encodings/utf_8.py +42 -0
  299. package/python/lib/python3.13/encodings/utf_8_sig.py +130 -0
  300. package/python/lib/python3.13/encodings/uu_codec.py +103 -0
  301. package/python/lib/python3.13/encodings/zlib_codec.py +77 -0
  302. package/python/lib/python3.13/enum.py +2183 -0
  303. package/python/lib/python3.13/filecmp.py +320 -0
  304. package/python/lib/python3.13/fileinput.py +442 -0
  305. package/python/lib/python3.13/fnmatch.py +192 -0
  306. package/python/lib/python3.13/fractions.py +1043 -0
  307. package/python/lib/python3.13/ftplib.py +975 -0
  308. package/python/lib/python3.13/functools.py +1036 -0
  309. package/python/lib/python3.13/genericpath.py +200 -0
  310. package/python/lib/python3.13/getopt.py +215 -0
  311. package/python/lib/python3.13/getpass.py +192 -0
  312. package/python/lib/python3.13/gettext.py +657 -0
  313. package/python/lib/python3.13/glob.py +572 -0
  314. package/python/lib/python3.13/graphlib.py +250 -0
  315. package/python/lib/python3.13/gzip.py +693 -0
  316. package/python/lib/python3.13/hashlib.py +255 -0
  317. package/python/lib/python3.13/heapq.py +603 -0
  318. package/python/lib/python3.13/hmac.py +220 -0
  319. package/python/lib/python3.13/html/__init__.py +132 -0
  320. package/python/lib/python3.13/html/entities.py +2513 -0
  321. package/python/lib/python3.13/html/parser.py +583 -0
  322. package/python/lib/python3.13/http/__init__.py +202 -0
  323. package/python/lib/python3.13/http/client.py +1598 -0
  324. package/python/lib/python3.13/http/cookiejar.py +2122 -0
  325. package/python/lib/python3.13/http/cookies.py +635 -0
  326. package/python/lib/python3.13/http/server.py +1355 -0
  327. package/python/lib/python3.13/imaplib.py +1769 -0
  328. package/python/lib/python3.13/importlib/__init__.py +136 -0
  329. package/python/lib/python3.13/importlib/_abc.py +39 -0
  330. package/python/lib/python3.13/importlib/_bootstrap.py +1559 -0
  331. package/python/lib/python3.13/importlib/_bootstrap_external.py +1826 -0
  332. package/python/lib/python3.13/importlib/abc.py +243 -0
  333. package/python/lib/python3.13/importlib/machinery.py +21 -0
  334. package/python/lib/python3.13/importlib/metadata/__init__.py +1093 -0
  335. package/python/lib/python3.13/importlib/metadata/_adapters.py +89 -0
  336. package/python/lib/python3.13/importlib/metadata/_collections.py +30 -0
  337. package/python/lib/python3.13/importlib/metadata/_functools.py +104 -0
  338. package/python/lib/python3.13/importlib/metadata/_itertools.py +73 -0
  339. package/python/lib/python3.13/importlib/metadata/_meta.py +67 -0
  340. package/python/lib/python3.13/importlib/metadata/_text.py +99 -0
  341. package/python/lib/python3.13/importlib/metadata/diagnose.py +21 -0
  342. package/python/lib/python3.13/importlib/readers.py +12 -0
  343. package/python/lib/python3.13/importlib/resources/__init__.py +43 -0
  344. package/python/lib/python3.13/importlib/resources/_adapters.py +168 -0
  345. package/python/lib/python3.13/importlib/resources/_common.py +211 -0
  346. package/python/lib/python3.13/importlib/resources/_functional.py +81 -0
  347. package/python/lib/python3.13/importlib/resources/_itertools.py +38 -0
  348. package/python/lib/python3.13/importlib/resources/abc.py +173 -0
  349. package/python/lib/python3.13/importlib/resources/readers.py +203 -0
  350. package/python/lib/python3.13/importlib/resources/simple.py +106 -0
  351. package/python/lib/python3.13/importlib/simple.py +14 -0
  352. package/python/lib/python3.13/importlib/util.py +274 -0
  353. package/python/lib/python3.13/inspect.py +3479 -0
  354. package/python/lib/python3.13/io.py +99 -0
  355. package/python/lib/python3.13/ipaddress.py +2440 -0
  356. package/python/lib/python3.13/json/__init__.py +365 -0
  357. package/python/lib/python3.13/json/decoder.py +364 -0
  358. package/python/lib/python3.13/json/encoder.py +446 -0
  359. package/python/lib/python3.13/json/scanner.py +73 -0
  360. package/python/lib/python3.13/json/tool.py +90 -0
  361. package/python/lib/python3.13/keyword.py +64 -0
  362. package/python/lib/python3.13/lib-dynload/.empty +0 -0
  363. package/python/lib/python3.13/lib-dynload/_dbm.cpython-313-x86_64-linux-gnu.so +0 -0
  364. package/python/lib/python3.13/linecache.py +236 -0
  365. package/python/lib/python3.13/locale.py +1987 -0
  366. package/python/lib/python3.13/logging/__init__.py +2330 -0
  367. package/python/lib/python3.13/logging/config.py +1080 -0
  368. package/python/lib/python3.13/logging/handlers.py +1629 -0
  369. package/python/lib/python3.13/lzma.py +364 -0
  370. package/python/lib/python3.13/mailbox.py +2219 -0
  371. package/python/lib/python3.13/mimetypes.py +679 -0
  372. package/python/lib/python3.13/modulefinder.py +671 -0
  373. package/python/lib/python3.13/multiprocessing/__init__.py +37 -0
  374. package/python/lib/python3.13/multiprocessing/connection.py +1216 -0
  375. package/python/lib/python3.13/multiprocessing/context.py +383 -0
  376. package/python/lib/python3.13/multiprocessing/dummy/__init__.py +126 -0
  377. package/python/lib/python3.13/multiprocessing/dummy/connection.py +75 -0
  378. package/python/lib/python3.13/multiprocessing/forkserver.py +373 -0
  379. package/python/lib/python3.13/multiprocessing/heap.py +337 -0
  380. package/python/lib/python3.13/multiprocessing/managers.py +1397 -0
  381. package/python/lib/python3.13/multiprocessing/pool.py +957 -0
  382. package/python/lib/python3.13/multiprocessing/popen_fork.py +97 -0
  383. package/python/lib/python3.13/multiprocessing/popen_forkserver.py +74 -0
  384. package/python/lib/python3.13/multiprocessing/popen_spawn_posix.py +76 -0
  385. package/python/lib/python3.13/multiprocessing/popen_spawn_win32.py +147 -0
  386. package/python/lib/python3.13/multiprocessing/process.py +436 -0
  387. package/python/lib/python3.13/multiprocessing/queues.py +399 -0
  388. package/python/lib/python3.13/multiprocessing/reduction.py +281 -0
  389. package/python/lib/python3.13/multiprocessing/resource_sharer.py +154 -0
  390. package/python/lib/python3.13/multiprocessing/resource_tracker.py +499 -0
  391. package/python/lib/python3.13/multiprocessing/shared_memory.py +544 -0
  392. package/python/lib/python3.13/multiprocessing/sharedctypes.py +240 -0
  393. package/python/lib/python3.13/multiprocessing/spawn.py +307 -0
  394. package/python/lib/python3.13/multiprocessing/synchronize.py +404 -0
  395. package/python/lib/python3.13/multiprocessing/util.py +562 -0
  396. package/python/lib/python3.13/netrc.py +199 -0
  397. package/python/lib/python3.13/ntpath.py +872 -0
  398. package/python/lib/python3.13/nturl2path.py +69 -0
  399. package/python/lib/python3.13/numbers.py +427 -0
  400. package/python/lib/python3.13/opcode.py +115 -0
  401. package/python/lib/python3.13/operator.py +467 -0
  402. package/python/lib/python3.13/optparse.py +1681 -0
  403. package/python/lib/python3.13/os.py +1184 -0
  404. package/python/lib/python3.13/pathlib/__init__.py +12 -0
  405. package/python/lib/python3.13/pathlib/_abc.py +930 -0
  406. package/python/lib/python3.13/pathlib/_local.py +861 -0
  407. package/python/lib/python3.13/pdb.py +2550 -0
  408. package/python/lib/python3.13/pickle.py +1860 -0
  409. package/python/lib/python3.13/pickletools.py +2904 -0
  410. package/python/lib/python3.13/pkgutil.py +529 -0
  411. package/python/lib/python3.13/platform.py +1454 -0
  412. package/python/lib/python3.13/plistlib.py +948 -0
  413. package/python/lib/python3.13/poplib.py +477 -0
  414. package/python/lib/python3.13/posixpath.py +578 -0
  415. package/python/lib/python3.13/pprint.py +658 -0
  416. package/python/lib/python3.13/profile.py +616 -0
  417. package/python/lib/python3.13/pstats.py +778 -0
  418. package/python/lib/python3.13/pty.py +211 -0
  419. package/python/lib/python3.13/py_compile.py +212 -0
  420. package/python/lib/python3.13/pyclbr.py +314 -0
  421. package/python/lib/python3.13/pydoc.py +2861 -0
  422. package/python/lib/python3.13/queue.py +383 -0
  423. package/python/lib/python3.13/quopri.py +237 -0
  424. package/python/lib/python3.13/random.py +1078 -0
  425. package/python/lib/python3.13/re/__init__.py +428 -0
  426. package/python/lib/python3.13/re/_casefix.py +106 -0
  427. package/python/lib/python3.13/re/_compiler.py +768 -0
  428. package/python/lib/python3.13/re/_constants.py +222 -0
  429. package/python/lib/python3.13/re/_parser.py +1081 -0
  430. package/python/lib/python3.13/reprlib.py +230 -0
  431. package/python/lib/python3.13/rlcompleter.py +222 -0
  432. package/python/lib/python3.13/runpy.py +326 -0
  433. package/python/lib/python3.13/sched.py +167 -0
  434. package/python/lib/python3.13/secrets.py +71 -0
  435. package/python/lib/python3.13/selectors.py +603 -0
  436. package/python/lib/python3.13/shelve.py +250 -0
  437. package/python/lib/python3.13/shlex.py +345 -0
  438. package/python/lib/python3.13/shutil.py +1569 -0
  439. package/python/lib/python3.13/signal.py +94 -0
  440. package/python/lib/python3.13/site.py +773 -0
  441. package/python/lib/python3.13/smtplib.py +1123 -0
  442. package/python/lib/python3.13/socket.py +988 -0
  443. package/python/lib/python3.13/socketserver.py +863 -0
  444. package/python/lib/python3.13/sqlite3/__init__.py +70 -0
  445. package/python/lib/python3.13/sqlite3/__main__.py +139 -0
  446. package/python/lib/python3.13/sqlite3/dbapi2.py +108 -0
  447. package/python/lib/python3.13/sqlite3/dump.py +118 -0
  448. package/python/lib/python3.13/sre_compile.py +7 -0
  449. package/python/lib/python3.13/sre_constants.py +7 -0
  450. package/python/lib/python3.13/sre_parse.py +7 -0
  451. package/python/lib/python3.13/ssl.py +1541 -0
  452. package/python/lib/python3.13/stat.py +212 -0
  453. package/python/lib/python3.13/statistics.py +1817 -0
  454. package/python/lib/python3.13/string.py +314 -0
  455. package/python/lib/python3.13/stringprep.py +272 -0
  456. package/python/lib/python3.13/struct.py +15 -0
  457. package/python/lib/python3.13/subprocess.py +2258 -0
  458. package/python/lib/python3.13/symtable.py +414 -0
  459. package/python/lib/python3.13/sysconfig/__init__.py +734 -0
  460. package/python/lib/python3.13/sysconfig/__main__.py +248 -0
  461. package/python/lib/python3.13/tabnanny.py +340 -0
  462. package/python/lib/python3.13/tarfile.py +3136 -0
  463. package/python/lib/python3.13/tempfile.py +958 -0
  464. package/python/lib/python3.13/textwrap.py +497 -0
  465. package/python/lib/python3.13/this.py +28 -0
  466. package/python/lib/python3.13/threading.py +1602 -0
  467. package/python/lib/python3.13/timeit.py +381 -0
  468. package/python/lib/python3.13/token.py +141 -0
  469. package/python/lib/python3.13/tokenize.py +592 -0
  470. package/python/lib/python3.13/tomllib/__init__.py +10 -0
  471. package/python/lib/python3.13/tomllib/_parser.py +703 -0
  472. package/python/lib/python3.13/tomllib/_re.py +107 -0
  473. package/python/lib/python3.13/tomllib/_types.py +10 -0
  474. package/python/lib/python3.13/tomllib/mypy.ini +15 -0
  475. package/python/lib/python3.13/trace.py +754 -0
  476. package/python/lib/python3.13/traceback.py +1639 -0
  477. package/python/lib/python3.13/tracemalloc.py +560 -0
  478. package/python/lib/python3.13/tty.py +73 -0
  479. package/python/lib/python3.13/types.py +346 -0
  480. package/python/lib/python3.13/typing.py +3846 -0
  481. package/python/lib/python3.13/unittest/__init__.py +80 -0
  482. package/python/lib/python3.13/unittest/__main__.py +18 -0
  483. package/python/lib/python3.13/unittest/_log.py +86 -0
  484. package/python/lib/python3.13/unittest/async_case.py +146 -0
  485. package/python/lib/python3.13/unittest/case.py +1478 -0
  486. package/python/lib/python3.13/unittest/loader.py +460 -0
  487. package/python/lib/python3.13/unittest/main.py +280 -0
  488. package/python/lib/python3.13/unittest/mock.py +3189 -0
  489. package/python/lib/python3.13/unittest/result.py +256 -0
  490. package/python/lib/python3.13/unittest/runner.py +292 -0
  491. package/python/lib/python3.13/unittest/signals.py +71 -0
  492. package/python/lib/python3.13/unittest/suite.py +379 -0
  493. package/python/lib/python3.13/unittest/util.py +170 -0
  494. package/python/lib/python3.13/urllib/__init__.py +0 -0
  495. package/python/lib/python3.13/urllib/error.py +74 -0
  496. package/python/lib/python3.13/urllib/parse.py +1264 -0
  497. package/python/lib/python3.13/urllib/request.py +2796 -0
  498. package/python/lib/python3.13/urllib/response.py +84 -0
  499. package/python/lib/python3.13/urllib/robotparser.py +363 -0
  500. package/python/lib/python3.13/uuid.py +784 -0
  501. package/python/lib/python3.13/warnings.py +735 -0
  502. package/python/lib/python3.13/wave.py +665 -0
  503. package/python/lib/python3.13/weakref.py +674 -0
  504. package/python/lib/python3.13/webbrowser.py +724 -0
  505. package/python/lib/python3.13/wsgiref/__init__.py +25 -0
  506. package/python/lib/python3.13/wsgiref/handlers.py +575 -0
  507. package/python/lib/python3.13/wsgiref/headers.py +192 -0
  508. package/python/lib/python3.13/wsgiref/simple_server.py +161 -0
  509. package/python/lib/python3.13/wsgiref/types.py +54 -0
  510. package/python/lib/python3.13/wsgiref/util.py +159 -0
  511. package/python/lib/python3.13/wsgiref/validate.py +438 -0
  512. package/python/lib/python3.13/xml/__init__.py +20 -0
  513. package/python/lib/python3.13/xml/dom/NodeFilter.py +27 -0
  514. package/python/lib/python3.13/xml/dom/__init__.py +140 -0
  515. package/python/lib/python3.13/xml/dom/domreg.py +99 -0
  516. package/python/lib/python3.13/xml/dom/expatbuilder.py +962 -0
  517. package/python/lib/python3.13/xml/dom/minicompat.py +109 -0
  518. package/python/lib/python3.13/xml/dom/minidom.py +2024 -0
  519. package/python/lib/python3.13/xml/dom/pulldom.py +336 -0
  520. package/python/lib/python3.13/xml/dom/xmlbuilder.py +389 -0
  521. package/python/lib/python3.13/xml/etree/ElementInclude.py +186 -0
  522. package/python/lib/python3.13/xml/etree/ElementPath.py +430 -0
  523. package/python/lib/python3.13/xml/etree/ElementTree.py +2116 -0
  524. package/python/lib/python3.13/xml/etree/__init__.py +33 -0
  525. package/python/lib/python3.13/xml/etree/cElementTree.py +3 -0
  526. package/python/lib/python3.13/xml/parsers/__init__.py +8 -0
  527. package/python/lib/python3.13/xml/parsers/expat.py +8 -0
  528. package/python/lib/python3.13/xml/sax/__init__.py +94 -0
  529. package/python/lib/python3.13/xml/sax/_exceptions.py +127 -0
  530. package/python/lib/python3.13/xml/sax/expatreader.py +454 -0
  531. package/python/lib/python3.13/xml/sax/handler.py +387 -0
  532. package/python/lib/python3.13/xml/sax/saxutils.py +369 -0
  533. package/python/lib/python3.13/xml/sax/xmlreader.py +378 -0
  534. package/python/lib/python3.13/xmlrpc/__init__.py +1 -0
  535. package/python/lib/python3.13/xmlrpc/client.py +1503 -0
  536. package/python/lib/python3.13/xmlrpc/server.py +1002 -0
  537. package/python/lib/python3.13/zipapp.py +229 -0
  538. package/python/lib/python3.13/zipfile/__init__.py +2391 -0
  539. package/python/lib/python3.13/zipfile/__main__.py +4 -0
  540. package/python/lib/python3.13/zipfile/_path/__init__.py +452 -0
  541. package/python/lib/python3.13/zipfile/_path/glob.py +113 -0
  542. package/python/lib/python3.13/zipimport.py +803 -0
  543. package/python/lib/python3.13/zoneinfo/__init__.py +34 -0
  544. package/python/lib/python3.13/zoneinfo/_common.py +172 -0
  545. package/python/lib/python3.13/zoneinfo/_tzpath.py +189 -0
  546. package/python/lib/python3.13/zoneinfo/_zoneinfo.py +779 -0
  547. package/python/licenses/LICENSE.bdb.txt +126 -0
  548. package/python/licenses/LICENSE.bzip2.txt +37 -0
  549. package/python/licenses/LICENSE.cpython.txt +771 -0
  550. package/python/licenses/LICENSE.expat.txt +21 -0
  551. package/python/licenses/LICENSE.libX11.txt +942 -0
  552. package/python/licenses/LICENSE.libXau.txt +21 -0
  553. package/python/licenses/LICENSE.libedit.txt +29 -0
  554. package/python/licenses/LICENSE.libffi.txt +21 -0
  555. package/python/licenses/LICENSE.liblzma.txt +13 -0
  556. package/python/licenses/LICENSE.libuuid.txt +27 -0
  557. package/python/licenses/LICENSE.libxcb.txt +30 -0
  558. package/python/licenses/LICENSE.mpdecimal.txt +24 -0
  559. package/python/licenses/LICENSE.ncurses.txt +29 -0
  560. package/python/licenses/LICENSE.openssl-1.1.txt +124 -0
  561. package/python/licenses/LICENSE.openssl-3.txt +177 -0
  562. package/python/licenses/LICENSE.sqlite.txt +23 -0
  563. package/python/licenses/LICENSE.tcl.txt +40 -0
  564. package/python/licenses/LICENSE.tix.txt +54 -0
  565. package/python/licenses/LICENSE.zlib.txt +21 -0
@@ -0,0 +1,2116 @@
1
+ """Lightweight XML support for Python.
2
+
3
+ XML is an inherently hierarchical data format, and the most natural way to
4
+ represent it is with a tree. This module has two classes for this purpose:
5
+
6
+ 1. ElementTree represents the whole XML document as a tree and
7
+
8
+ 2. Element represents a single node in this tree.
9
+
10
+ Interactions with the whole document (reading and writing to/from files) are
11
+ usually done on the ElementTree level. Interactions with a single XML
12
+ element and its sub-elements are done on the Element level.
13
+
14
+ Element is a flexible container object designed to store hierarchical data
15
+ structures in memory. It can be described as a cross between a list and a
16
+ dictionary. Each Element has a number of properties associated with it:
17
+
18
+ 'tag' - a string containing the element's name.
19
+
20
+ 'attributes' - a Python dictionary storing the element's attributes.
21
+
22
+ 'text' - a string containing the element's text content.
23
+
24
+ 'tail' - an optional string containing text after the element's end tag.
25
+
26
+ And a number of child elements stored in a Python sequence.
27
+
28
+ To create an element instance, use the Element constructor,
29
+ or the SubElement factory function.
30
+
31
+ You can also use the ElementTree class to wrap an element structure
32
+ and convert it to and from XML.
33
+
34
+ """
35
+
36
+ #---------------------------------------------------------------------
37
+ # Licensed to PSF under a Contributor Agreement.
38
+ # See https://www.python.org/psf/license for licensing details.
39
+ #
40
+ # ElementTree
41
+ # Copyright (c) 1999-2008 by Fredrik Lundh. All rights reserved.
42
+ #
43
+ # fredrik@pythonware.com
44
+ # http://www.pythonware.com
45
+ # --------------------------------------------------------------------
46
+ # The ElementTree toolkit is
47
+ #
48
+ # Copyright (c) 1999-2008 by Fredrik Lundh
49
+ #
50
+ # By obtaining, using, and/or copying this software and/or its
51
+ # associated documentation, you agree that you have read, understood,
52
+ # and will comply with the following terms and conditions:
53
+ #
54
+ # Permission to use, copy, modify, and distribute this software and
55
+ # its associated documentation for any purpose and without fee is
56
+ # hereby granted, provided that the above copyright notice appears in
57
+ # all copies, and that both that copyright notice and this permission
58
+ # notice appear in supporting documentation, and that the name of
59
+ # Secret Labs AB or the author not be used in advertising or publicity
60
+ # pertaining to distribution of the software without specific, written
61
+ # prior permission.
62
+ #
63
+ # SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
64
+ # TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
65
+ # ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
66
+ # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
67
+ # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
68
+ # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
69
+ # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
70
+ # OF THIS SOFTWARE.
71
+ # --------------------------------------------------------------------
72
+
73
+ __all__ = [
74
+ # public symbols
75
+ "Comment",
76
+ "dump",
77
+ "Element", "ElementTree",
78
+ "fromstring", "fromstringlist",
79
+ "indent", "iselement", "iterparse",
80
+ "parse", "ParseError",
81
+ "PI", "ProcessingInstruction",
82
+ "QName",
83
+ "SubElement",
84
+ "tostring", "tostringlist",
85
+ "TreeBuilder",
86
+ "VERSION",
87
+ "XML", "XMLID",
88
+ "XMLParser", "XMLPullParser",
89
+ "register_namespace",
90
+ "canonicalize", "C14NWriterTarget",
91
+ ]
92
+
93
+ VERSION = "1.3.0"
94
+
95
+ import sys
96
+ import re
97
+ import warnings
98
+ import io
99
+ import collections
100
+ import collections.abc
101
+ import contextlib
102
+ import weakref
103
+
104
+ from . import ElementPath
105
+
106
+
107
+ class ParseError(SyntaxError):
108
+ """An error when parsing an XML document.
109
+
110
+ In addition to its exception value, a ParseError contains
111
+ two extra attributes:
112
+ 'code' - the specific exception code
113
+ 'position' - the line and column of the error
114
+
115
+ """
116
+ pass
117
+
118
+ # --------------------------------------------------------------------
119
+
120
+
121
+ def iselement(element):
122
+ """Return True if *element* appears to be an Element."""
123
+ return hasattr(element, 'tag')
124
+
125
+
126
+ class Element:
127
+ """An XML element.
128
+
129
+ This class is the reference implementation of the Element interface.
130
+
131
+ An element's length is its number of subelements. That means if you
132
+ want to check if an element is truly empty, you should check BOTH
133
+ its length AND its text attribute.
134
+
135
+ The element tag, attribute names, and attribute values can be either
136
+ bytes or strings.
137
+
138
+ *tag* is the element name. *attrib* is an optional dictionary containing
139
+ element attributes. *extra* are additional element attributes given as
140
+ keyword arguments.
141
+
142
+ Example form:
143
+ <tag attrib>text<child/>...</tag>tail
144
+
145
+ """
146
+
147
+ tag = None
148
+ """The element's name."""
149
+
150
+ attrib = None
151
+ """Dictionary of the element's attributes."""
152
+
153
+ text = None
154
+ """
155
+ Text before first subelement. This is either a string or the value None.
156
+ Note that if there is no text, this attribute may be either
157
+ None or the empty string, depending on the parser.
158
+
159
+ """
160
+
161
+ tail = None
162
+ """
163
+ Text after this element's end tag, but before the next sibling element's
164
+ start tag. This is either a string or the value None. Note that if there
165
+ was no text, this attribute may be either None or an empty string,
166
+ depending on the parser.
167
+
168
+ """
169
+
170
+ def __init__(self, tag, attrib={}, **extra):
171
+ if not isinstance(attrib, dict):
172
+ raise TypeError("attrib must be dict, not %s" % (
173
+ attrib.__class__.__name__,))
174
+ self.tag = tag
175
+ self.attrib = {**attrib, **extra}
176
+ self._children = []
177
+
178
+ def __repr__(self):
179
+ return "<%s %r at %#x>" % (self.__class__.__name__, self.tag, id(self))
180
+
181
+ def makeelement(self, tag, attrib):
182
+ """Create a new element with the same type.
183
+
184
+ *tag* is a string containing the element name.
185
+ *attrib* is a dictionary containing the element attributes.
186
+
187
+ Do not call this method, use the SubElement factory function instead.
188
+
189
+ """
190
+ return self.__class__(tag, attrib)
191
+
192
+ def __copy__(self):
193
+ elem = self.makeelement(self.tag, self.attrib)
194
+ elem.text = self.text
195
+ elem.tail = self.tail
196
+ elem[:] = self
197
+ return elem
198
+
199
+ def __len__(self):
200
+ return len(self._children)
201
+
202
+ def __bool__(self):
203
+ warnings.warn(
204
+ "Testing an element's truth value will always return True in "
205
+ "future versions. "
206
+ "Use specific 'len(elem)' or 'elem is not None' test instead.",
207
+ DeprecationWarning, stacklevel=2
208
+ )
209
+ return len(self._children) != 0 # emulate old behaviour, for now
210
+
211
+ def __getitem__(self, index):
212
+ return self._children[index]
213
+
214
+ def __setitem__(self, index, element):
215
+ if isinstance(index, slice):
216
+ for elt in element:
217
+ self._assert_is_element(elt)
218
+ else:
219
+ self._assert_is_element(element)
220
+ self._children[index] = element
221
+
222
+ def __delitem__(self, index):
223
+ del self._children[index]
224
+
225
+ def append(self, subelement):
226
+ """Add *subelement* to the end of this element.
227
+
228
+ The new element will appear in document order after the last existing
229
+ subelement (or directly after the text, if it's the first subelement),
230
+ but before the end tag for this element.
231
+
232
+ """
233
+ self._assert_is_element(subelement)
234
+ self._children.append(subelement)
235
+
236
+ def extend(self, elements):
237
+ """Append subelements from a sequence.
238
+
239
+ *elements* is a sequence with zero or more elements.
240
+
241
+ """
242
+ for element in elements:
243
+ self._assert_is_element(element)
244
+ self._children.append(element)
245
+
246
+ def insert(self, index, subelement):
247
+ """Insert *subelement* at position *index*."""
248
+ self._assert_is_element(subelement)
249
+ self._children.insert(index, subelement)
250
+
251
+ def _assert_is_element(self, e):
252
+ # Need to refer to the actual Python implementation, not the
253
+ # shadowing C implementation.
254
+ if not isinstance(e, _Element_Py):
255
+ raise TypeError('expected an Element, not %s' % type(e).__name__)
256
+
257
+ def remove(self, subelement):
258
+ """Remove matching subelement.
259
+
260
+ Unlike the find methods, this method compares elements based on
261
+ identity, NOT ON tag value or contents. To remove subelements by
262
+ other means, the easiest way is to use a list comprehension to
263
+ select what elements to keep, and then use slice assignment to update
264
+ the parent element.
265
+
266
+ ValueError is raised if a matching element could not be found.
267
+
268
+ """
269
+ # assert iselement(element)
270
+ self._children.remove(subelement)
271
+
272
+ def find(self, path, namespaces=None):
273
+ """Find first matching element by tag name or path.
274
+
275
+ *path* is a string having either an element tag or an XPath,
276
+ *namespaces* is an optional mapping from namespace prefix to full
277
+ name.
278
+
279
+ Return the first matching element, or None if no element was found.
280
+
281
+ """
282
+ return ElementPath.find(self, path, namespaces)
283
+
284
+ def findtext(self, path, default=None, namespaces=None):
285
+ """Find text for first matching element by tag name or path.
286
+
287
+ *path* is a string having either an element tag or an XPath,
288
+ *default* is the value to return if the element was not found,
289
+ *namespaces* is an optional mapping from namespace prefix to full
290
+ name.
291
+
292
+ Return text content of first matching element, or default value if
293
+ none was found. Note that if an element is found having no text
294
+ content, the empty string is returned.
295
+
296
+ """
297
+ return ElementPath.findtext(self, path, default, namespaces)
298
+
299
+ def findall(self, path, namespaces=None):
300
+ """Find all matching subelements by tag name or path.
301
+
302
+ *path* is a string having either an element tag or an XPath,
303
+ *namespaces* is an optional mapping from namespace prefix to full
304
+ name.
305
+
306
+ Returns list containing all matching elements in document order.
307
+
308
+ """
309
+ return ElementPath.findall(self, path, namespaces)
310
+
311
+ def iterfind(self, path, namespaces=None):
312
+ """Find all matching subelements by tag name or path.
313
+
314
+ *path* is a string having either an element tag or an XPath,
315
+ *namespaces* is an optional mapping from namespace prefix to full
316
+ name.
317
+
318
+ Return an iterable yielding all matching elements in document order.
319
+
320
+ """
321
+ return ElementPath.iterfind(self, path, namespaces)
322
+
323
+ def clear(self):
324
+ """Reset element.
325
+
326
+ This function removes all subelements, clears all attributes, and sets
327
+ the text and tail attributes to None.
328
+
329
+ """
330
+ self.attrib.clear()
331
+ self._children = []
332
+ self.text = self.tail = None
333
+
334
+ def get(self, key, default=None):
335
+ """Get element attribute.
336
+
337
+ Equivalent to attrib.get, but some implementations may handle this a
338
+ bit more efficiently. *key* is what attribute to look for, and
339
+ *default* is what to return if the attribute was not found.
340
+
341
+ Returns a string containing the attribute value, or the default if
342
+ attribute was not found.
343
+
344
+ """
345
+ return self.attrib.get(key, default)
346
+
347
+ def set(self, key, value):
348
+ """Set element attribute.
349
+
350
+ Equivalent to attrib[key] = value, but some implementations may handle
351
+ this a bit more efficiently. *key* is what attribute to set, and
352
+ *value* is the attribute value to set it to.
353
+
354
+ """
355
+ self.attrib[key] = value
356
+
357
+ def keys(self):
358
+ """Get list of attribute names.
359
+
360
+ Names are returned in an arbitrary order, just like an ordinary
361
+ Python dict. Equivalent to attrib.keys()
362
+
363
+ """
364
+ return self.attrib.keys()
365
+
366
+ def items(self):
367
+ """Get element attributes as a sequence.
368
+
369
+ The attributes are returned in arbitrary order. Equivalent to
370
+ attrib.items().
371
+
372
+ Return a list of (name, value) tuples.
373
+
374
+ """
375
+ return self.attrib.items()
376
+
377
+ def iter(self, tag=None):
378
+ """Create tree iterator.
379
+
380
+ The iterator loops over the element and all subelements in document
381
+ order, returning all elements with a matching tag.
382
+
383
+ If the tree structure is modified during iteration, new or removed
384
+ elements may or may not be included. To get a stable set, use the
385
+ list() function on the iterator, and loop over the resulting list.
386
+
387
+ *tag* is what tags to look for (default is to return all elements)
388
+
389
+ Return an iterator containing all the matching elements.
390
+
391
+ """
392
+ if tag == "*":
393
+ tag = None
394
+ if tag is None or self.tag == tag:
395
+ yield self
396
+ for e in self._children:
397
+ yield from e.iter(tag)
398
+
399
+ def itertext(self):
400
+ """Create text iterator.
401
+
402
+ The iterator loops over the element and all subelements in document
403
+ order, returning all inner text.
404
+
405
+ """
406
+ tag = self.tag
407
+ if not isinstance(tag, str) and tag is not None:
408
+ return
409
+ t = self.text
410
+ if t:
411
+ yield t
412
+ for e in self:
413
+ yield from e.itertext()
414
+ t = e.tail
415
+ if t:
416
+ yield t
417
+
418
+
419
+ def SubElement(parent, tag, attrib={}, **extra):
420
+ """Subelement factory which creates an element instance, and appends it
421
+ to an existing parent.
422
+
423
+ The element tag, attribute names, and attribute values can be either
424
+ bytes or Unicode strings.
425
+
426
+ *parent* is the parent element, *tag* is the subelements name, *attrib* is
427
+ an optional directory containing element attributes, *extra* are
428
+ additional attributes given as keyword arguments.
429
+
430
+ """
431
+ attrib = {**attrib, **extra}
432
+ element = parent.makeelement(tag, attrib)
433
+ parent.append(element)
434
+ return element
435
+
436
+
437
+ def Comment(text=None):
438
+ """Comment element factory.
439
+
440
+ This function creates a special element which the standard serializer
441
+ serializes as an XML comment.
442
+
443
+ *text* is a string containing the comment string.
444
+
445
+ """
446
+ element = Element(Comment)
447
+ element.text = text
448
+ return element
449
+
450
+
451
+ def ProcessingInstruction(target, text=None):
452
+ """Processing Instruction element factory.
453
+
454
+ This function creates a special element which the standard serializer
455
+ serializes as an XML comment.
456
+
457
+ *target* is a string containing the processing instruction, *text* is a
458
+ string containing the processing instruction contents, if any.
459
+
460
+ """
461
+ element = Element(ProcessingInstruction)
462
+ element.text = target
463
+ if text:
464
+ element.text = element.text + " " + text
465
+ return element
466
+
467
+ PI = ProcessingInstruction
468
+
469
+
470
+ class QName:
471
+ """Qualified name wrapper.
472
+
473
+ This class can be used to wrap a QName attribute value in order to get
474
+ proper namespace handing on output.
475
+
476
+ *text_or_uri* is a string containing the QName value either in the form
477
+ {uri}local, or if the tag argument is given, the URI part of a QName.
478
+
479
+ *tag* is an optional argument which if given, will make the first
480
+ argument (text_or_uri) be interpreted as a URI, and this argument (tag)
481
+ be interpreted as a local name.
482
+
483
+ """
484
+ def __init__(self, text_or_uri, tag=None):
485
+ if tag:
486
+ text_or_uri = "{%s}%s" % (text_or_uri, tag)
487
+ self.text = text_or_uri
488
+ def __str__(self):
489
+ return self.text
490
+ def __repr__(self):
491
+ return '<%s %r>' % (self.__class__.__name__, self.text)
492
+ def __hash__(self):
493
+ return hash(self.text)
494
+ def __le__(self, other):
495
+ if isinstance(other, QName):
496
+ return self.text <= other.text
497
+ return self.text <= other
498
+ def __lt__(self, other):
499
+ if isinstance(other, QName):
500
+ return self.text < other.text
501
+ return self.text < other
502
+ def __ge__(self, other):
503
+ if isinstance(other, QName):
504
+ return self.text >= other.text
505
+ return self.text >= other
506
+ def __gt__(self, other):
507
+ if isinstance(other, QName):
508
+ return self.text > other.text
509
+ return self.text > other
510
+ def __eq__(self, other):
511
+ if isinstance(other, QName):
512
+ return self.text == other.text
513
+ return self.text == other
514
+
515
+ # --------------------------------------------------------------------
516
+
517
+
518
+ class ElementTree:
519
+ """An XML element hierarchy.
520
+
521
+ This class also provides support for serialization to and from
522
+ standard XML.
523
+
524
+ *element* is an optional root element node,
525
+ *file* is an optional file handle or file name of an XML file whose
526
+ contents will be used to initialize the tree with.
527
+
528
+ """
529
+ def __init__(self, element=None, file=None):
530
+ if element is not None and not iselement(element):
531
+ raise TypeError('expected an Element, not %s' %
532
+ type(element).__name__)
533
+ self._root = element # first node
534
+ if file:
535
+ self.parse(file)
536
+
537
+ def getroot(self):
538
+ """Return root element of this tree."""
539
+ return self._root
540
+
541
+ def _setroot(self, element):
542
+ """Replace root element of this tree.
543
+
544
+ This will discard the current contents of the tree and replace it
545
+ with the given element. Use with care!
546
+
547
+ """
548
+ if not iselement(element):
549
+ raise TypeError('expected an Element, not %s'
550
+ % type(element).__name__)
551
+ self._root = element
552
+
553
+ def parse(self, source, parser=None):
554
+ """Load external XML document into element tree.
555
+
556
+ *source* is a file name or file object, *parser* is an optional
557
+ parser instance that defaults to XMLParser.
558
+
559
+ ParseError is raised if the parser fails to parse the document.
560
+
561
+ Returns the root element of the given source document.
562
+
563
+ """
564
+ close_source = False
565
+ if not hasattr(source, "read"):
566
+ source = open(source, "rb")
567
+ close_source = True
568
+ try:
569
+ if parser is None:
570
+ # If no parser was specified, create a default XMLParser
571
+ parser = XMLParser()
572
+ if hasattr(parser, '_parse_whole'):
573
+ # The default XMLParser, when it comes from an accelerator,
574
+ # can define an internal _parse_whole API for efficiency.
575
+ # It can be used to parse the whole source without feeding
576
+ # it with chunks.
577
+ self._root = parser._parse_whole(source)
578
+ return self._root
579
+ while data := source.read(65536):
580
+ parser.feed(data)
581
+ self._root = parser.close()
582
+ return self._root
583
+ finally:
584
+ if close_source:
585
+ source.close()
586
+
587
+ def iter(self, tag=None):
588
+ """Create and return tree iterator for the root element.
589
+
590
+ The iterator loops over all elements in this tree, in document
591
+ order.
592
+
593
+ *tag* is a string with the tag name to iterate over
594
+ (default is to return all elements).
595
+
596
+ """
597
+ # assert self._root is not None
598
+ return self._root.iter(tag)
599
+
600
+ def find(self, path, namespaces=None):
601
+ """Find first matching element by tag name or path.
602
+
603
+ Same as getroot().find(path), which is Element.find()
604
+
605
+ *path* is a string having either an element tag or an XPath,
606
+ *namespaces* is an optional mapping from namespace prefix to full
607
+ name.
608
+
609
+ Return the first matching element, or None if no element was found.
610
+
611
+ """
612
+ # assert self._root is not None
613
+ if path[:1] == "/":
614
+ path = "." + path
615
+ warnings.warn(
616
+ "This search is broken in 1.3 and earlier, and will be "
617
+ "fixed in a future version. If you rely on the current "
618
+ "behaviour, change it to %r" % path,
619
+ FutureWarning, stacklevel=2
620
+ )
621
+ return self._root.find(path, namespaces)
622
+
623
+ def findtext(self, path, default=None, namespaces=None):
624
+ """Find first matching element by tag name or path.
625
+
626
+ Same as getroot().findtext(path), which is Element.findtext()
627
+
628
+ *path* is a string having either an element tag or an XPath,
629
+ *namespaces* is an optional mapping from namespace prefix to full
630
+ name.
631
+
632
+ Return the first matching element, or None if no element was found.
633
+
634
+ """
635
+ # assert self._root is not None
636
+ if path[:1] == "/":
637
+ path = "." + path
638
+ warnings.warn(
639
+ "This search is broken in 1.3 and earlier, and will be "
640
+ "fixed in a future version. If you rely on the current "
641
+ "behaviour, change it to %r" % path,
642
+ FutureWarning, stacklevel=2
643
+ )
644
+ return self._root.findtext(path, default, namespaces)
645
+
646
+ def findall(self, path, namespaces=None):
647
+ """Find all matching subelements by tag name or path.
648
+
649
+ Same as getroot().findall(path), which is Element.findall().
650
+
651
+ *path* is a string having either an element tag or an XPath,
652
+ *namespaces* is an optional mapping from namespace prefix to full
653
+ name.
654
+
655
+ Return list containing all matching elements in document order.
656
+
657
+ """
658
+ # assert self._root is not None
659
+ if path[:1] == "/":
660
+ path = "." + path
661
+ warnings.warn(
662
+ "This search is broken in 1.3 and earlier, and will be "
663
+ "fixed in a future version. If you rely on the current "
664
+ "behaviour, change it to %r" % path,
665
+ FutureWarning, stacklevel=2
666
+ )
667
+ return self._root.findall(path, namespaces)
668
+
669
+ def iterfind(self, path, namespaces=None):
670
+ """Find all matching subelements by tag name or path.
671
+
672
+ Same as getroot().iterfind(path), which is element.iterfind()
673
+
674
+ *path* is a string having either an element tag or an XPath,
675
+ *namespaces* is an optional mapping from namespace prefix to full name.
676
+
677
+ Return an iterable yielding all matching elements in document order.
678
+
679
+ """
680
+ # assert self._root is not None
681
+ if path[:1] == "/":
682
+ path = "." + path
683
+ warnings.warn(
684
+ "This search is broken in 1.3 and earlier, and will be "
685
+ "fixed in a future version. If you rely on the current "
686
+ "behaviour, change it to %r" % path,
687
+ FutureWarning, stacklevel=2
688
+ )
689
+ return self._root.iterfind(path, namespaces)
690
+
691
+ def write(self, file_or_filename,
692
+ encoding=None,
693
+ xml_declaration=None,
694
+ default_namespace=None,
695
+ method=None, *,
696
+ short_empty_elements=True):
697
+ """Write element tree to a file as XML.
698
+
699
+ Arguments:
700
+ *file_or_filename* -- file name or a file object opened for
701
+ writing
702
+
703
+ *encoding* -- the output encoding (default: US-ASCII)
704
+
705
+ *xml_declaration* -- bool indicating if an XML declaration should
706
+ be added to the output. If None, an XML
707
+ declaration is added if encoding IS NOT
708
+ either of: US-ASCII, UTF-8, or Unicode
709
+
710
+ *default_namespace* -- sets the default XML namespace (for
711
+ "xmlns")
712
+
713
+ *method* -- either "xml" (default), "html, "text", or "c14n"
714
+
715
+ *short_empty_elements* -- controls the formatting of elements
716
+ that contain no content. If True
717
+ (default) they are emitted as a single
718
+ self-closed tag, otherwise they are
719
+ emitted as a pair of start/end tags
720
+
721
+ """
722
+ if self._root is None:
723
+ raise TypeError('ElementTree not initialized')
724
+ if not method:
725
+ method = "xml"
726
+ elif method not in _serialize:
727
+ raise ValueError("unknown method %r" % method)
728
+ if not encoding:
729
+ if method == "c14n":
730
+ encoding = "utf-8"
731
+ else:
732
+ encoding = "us-ascii"
733
+ with _get_writer(file_or_filename, encoding) as (write, declared_encoding):
734
+ if method == "xml" and (xml_declaration or
735
+ (xml_declaration is None and
736
+ encoding.lower() != "unicode" and
737
+ declared_encoding.lower() not in ("utf-8", "us-ascii"))):
738
+ write("<?xml version='1.0' encoding='%s'?>\n" % (
739
+ declared_encoding,))
740
+ if method == "text":
741
+ _serialize_text(write, self._root)
742
+ else:
743
+ qnames, namespaces = _namespaces(self._root, default_namespace)
744
+ serialize = _serialize[method]
745
+ serialize(write, self._root, qnames, namespaces,
746
+ short_empty_elements=short_empty_elements)
747
+
748
+ def write_c14n(self, file):
749
+ # lxml.etree compatibility. use output method instead
750
+ return self.write(file, method="c14n")
751
+
752
+ # --------------------------------------------------------------------
753
+ # serialization support
754
+
755
+ @contextlib.contextmanager
756
+ def _get_writer(file_or_filename, encoding):
757
+ # returns text write method and release all resources after using
758
+ try:
759
+ write = file_or_filename.write
760
+ except AttributeError:
761
+ # file_or_filename is a file name
762
+ if encoding.lower() == "unicode":
763
+ encoding="utf-8"
764
+ with open(file_or_filename, "w", encoding=encoding,
765
+ errors="xmlcharrefreplace") as file:
766
+ yield file.write, encoding
767
+ else:
768
+ # file_or_filename is a file-like object
769
+ # encoding determines if it is a text or binary writer
770
+ if encoding.lower() == "unicode":
771
+ # use a text writer as is
772
+ yield write, getattr(file_or_filename, "encoding", None) or "utf-8"
773
+ else:
774
+ # wrap a binary writer with TextIOWrapper
775
+ with contextlib.ExitStack() as stack:
776
+ if isinstance(file_or_filename, io.BufferedIOBase):
777
+ file = file_or_filename
778
+ elif isinstance(file_or_filename, io.RawIOBase):
779
+ file = io.BufferedWriter(file_or_filename)
780
+ # Keep the original file open when the BufferedWriter is
781
+ # destroyed
782
+ stack.callback(file.detach)
783
+ else:
784
+ # This is to handle passed objects that aren't in the
785
+ # IOBase hierarchy, but just have a write method
786
+ file = io.BufferedIOBase()
787
+ file.writable = lambda: True
788
+ file.write = write
789
+ try:
790
+ # TextIOWrapper uses this methods to determine
791
+ # if BOM (for UTF-16, etc) should be added
792
+ file.seekable = file_or_filename.seekable
793
+ file.tell = file_or_filename.tell
794
+ except AttributeError:
795
+ pass
796
+ file = io.TextIOWrapper(file,
797
+ encoding=encoding,
798
+ errors="xmlcharrefreplace",
799
+ newline="\n")
800
+ # Keep the original file open when the TextIOWrapper is
801
+ # destroyed
802
+ stack.callback(file.detach)
803
+ yield file.write, encoding
804
+
805
+ def _namespaces(elem, default_namespace=None):
806
+ # identify namespaces used in this tree
807
+
808
+ # maps qnames to *encoded* prefix:local names
809
+ qnames = {None: None}
810
+
811
+ # maps uri:s to prefixes
812
+ namespaces = {}
813
+ if default_namespace:
814
+ namespaces[default_namespace] = ""
815
+
816
+ def add_qname(qname):
817
+ # calculate serialized qname representation
818
+ try:
819
+ if qname[:1] == "{":
820
+ uri, tag = qname[1:].rsplit("}", 1)
821
+ prefix = namespaces.get(uri)
822
+ if prefix is None:
823
+ prefix = _namespace_map.get(uri)
824
+ if prefix is None:
825
+ prefix = "ns%d" % len(namespaces)
826
+ if prefix != "xml":
827
+ namespaces[uri] = prefix
828
+ if prefix:
829
+ qnames[qname] = "%s:%s" % (prefix, tag)
830
+ else:
831
+ qnames[qname] = tag # default element
832
+ else:
833
+ if default_namespace:
834
+ # FIXME: can this be handled in XML 1.0?
835
+ raise ValueError(
836
+ "cannot use non-qualified names with "
837
+ "default_namespace option"
838
+ )
839
+ qnames[qname] = qname
840
+ except TypeError:
841
+ _raise_serialization_error(qname)
842
+
843
+ # populate qname and namespaces table
844
+ for elem in elem.iter():
845
+ tag = elem.tag
846
+ if isinstance(tag, QName):
847
+ if tag.text not in qnames:
848
+ add_qname(tag.text)
849
+ elif isinstance(tag, str):
850
+ if tag not in qnames:
851
+ add_qname(tag)
852
+ elif tag is not None and tag is not Comment and tag is not PI:
853
+ _raise_serialization_error(tag)
854
+ for key, value in elem.items():
855
+ if isinstance(key, QName):
856
+ key = key.text
857
+ if key not in qnames:
858
+ add_qname(key)
859
+ if isinstance(value, QName) and value.text not in qnames:
860
+ add_qname(value.text)
861
+ text = elem.text
862
+ if isinstance(text, QName) and text.text not in qnames:
863
+ add_qname(text.text)
864
+ return qnames, namespaces
865
+
866
+ def _serialize_xml(write, elem, qnames, namespaces,
867
+ short_empty_elements, **kwargs):
868
+ tag = elem.tag
869
+ text = elem.text
870
+ if tag is Comment:
871
+ write("<!--%s-->" % text)
872
+ elif tag is ProcessingInstruction:
873
+ write("<?%s?>" % text)
874
+ else:
875
+ tag = qnames[tag]
876
+ if tag is None:
877
+ if text:
878
+ write(_escape_cdata(text))
879
+ for e in elem:
880
+ _serialize_xml(write, e, qnames, None,
881
+ short_empty_elements=short_empty_elements)
882
+ else:
883
+ write("<" + tag)
884
+ items = list(elem.items())
885
+ if items or namespaces:
886
+ if namespaces:
887
+ for v, k in sorted(namespaces.items(),
888
+ key=lambda x: x[1]): # sort on prefix
889
+ if k:
890
+ k = ":" + k
891
+ write(" xmlns%s=\"%s\"" % (
892
+ k,
893
+ _escape_attrib(v)
894
+ ))
895
+ for k, v in items:
896
+ if isinstance(k, QName):
897
+ k = k.text
898
+ if isinstance(v, QName):
899
+ v = qnames[v.text]
900
+ else:
901
+ v = _escape_attrib(v)
902
+ write(" %s=\"%s\"" % (qnames[k], v))
903
+ if text or len(elem) or not short_empty_elements:
904
+ write(">")
905
+ if text:
906
+ write(_escape_cdata(text))
907
+ for e in elem:
908
+ _serialize_xml(write, e, qnames, None,
909
+ short_empty_elements=short_empty_elements)
910
+ write("</" + tag + ">")
911
+ else:
912
+ write(" />")
913
+ if elem.tail:
914
+ write(_escape_cdata(elem.tail))
915
+
916
+ _CDATA_CONTENT_ELEMENTS = {"script", "style", "xmp", "iframe", "noembed",
917
+ "noframes", "plaintext"}
918
+
919
+ HTML_EMPTY = {"area", "base", "basefont", "br", "col", "embed", "frame", "hr",
920
+ "img", "input", "isindex", "link", "meta", "param", "source",
921
+ "track", "wbr", "plaintext"}
922
+
923
+ def _serialize_html(write, elem, qnames, namespaces, **kwargs):
924
+ tag = elem.tag
925
+ text = elem.text
926
+ if tag is Comment:
927
+ write("<!--%s-->" % _escape_cdata(text))
928
+ elif tag is ProcessingInstruction:
929
+ write("<?%s?>" % _escape_cdata(text))
930
+ else:
931
+ tag = qnames[tag]
932
+ if tag is None:
933
+ if text:
934
+ write(_escape_cdata(text))
935
+ for e in elem:
936
+ _serialize_html(write, e, qnames, None)
937
+ else:
938
+ write("<" + tag)
939
+ items = list(elem.items())
940
+ if items or namespaces:
941
+ if namespaces:
942
+ for v, k in sorted(namespaces.items(),
943
+ key=lambda x: x[1]): # sort on prefix
944
+ if k:
945
+ k = ":" + k
946
+ write(" xmlns%s=\"%s\"" % (
947
+ k,
948
+ _escape_attrib(v)
949
+ ))
950
+ for k, v in items:
951
+ if isinstance(k, QName):
952
+ k = k.text
953
+ if isinstance(v, QName):
954
+ v = qnames[v.text]
955
+ else:
956
+ v = _escape_attrib_html(v)
957
+ # FIXME: handle boolean attributes
958
+ write(" %s=\"%s\"" % (qnames[k], v))
959
+ write(">")
960
+ ltag = tag.lower()
961
+ if text:
962
+ if ltag in _CDATA_CONTENT_ELEMENTS:
963
+ write(text)
964
+ else:
965
+ write(_escape_cdata(text))
966
+ for e in elem:
967
+ _serialize_html(write, e, qnames, None)
968
+ if ltag not in HTML_EMPTY:
969
+ write("</" + tag + ">")
970
+ if elem.tail:
971
+ write(_escape_cdata(elem.tail))
972
+
973
+ def _serialize_text(write, elem):
974
+ for part in elem.itertext():
975
+ write(part)
976
+ if elem.tail:
977
+ write(elem.tail)
978
+
979
+ _serialize = {
980
+ "xml": _serialize_xml,
981
+ "html": _serialize_html,
982
+ "text": _serialize_text,
983
+ # this optional method is imported at the end of the module
984
+ # "c14n": _serialize_c14n,
985
+ }
986
+
987
+
988
+ def register_namespace(prefix, uri):
989
+ """Register a namespace prefix.
990
+
991
+ The registry is global, and any existing mapping for either the
992
+ given prefix or the namespace URI will be removed.
993
+
994
+ *prefix* is the namespace prefix, *uri* is a namespace uri. Tags and
995
+ attributes in this namespace will be serialized with prefix if possible.
996
+
997
+ ValueError is raised if prefix is reserved or is invalid.
998
+
999
+ """
1000
+ if re.match(r"ns\d+$", prefix):
1001
+ raise ValueError("Prefix format reserved for internal use")
1002
+ for k, v in list(_namespace_map.items()):
1003
+ if k == uri or v == prefix:
1004
+ del _namespace_map[k]
1005
+ _namespace_map[uri] = prefix
1006
+
1007
+ _namespace_map = {
1008
+ # "well-known" namespace prefixes
1009
+ "http://www.w3.org/XML/1998/namespace": "xml",
1010
+ "http://www.w3.org/1999/xhtml": "html",
1011
+ "http://www.w3.org/1999/02/22-rdf-syntax-ns#": "rdf",
1012
+ "http://schemas.xmlsoap.org/wsdl/": "wsdl",
1013
+ # xml schema
1014
+ "http://www.w3.org/2001/XMLSchema": "xs",
1015
+ "http://www.w3.org/2001/XMLSchema-instance": "xsi",
1016
+ # dublin core
1017
+ "http://purl.org/dc/elements/1.1/": "dc",
1018
+ }
1019
+ # For tests and troubleshooting
1020
+ register_namespace._namespace_map = _namespace_map
1021
+
1022
+ def _raise_serialization_error(text):
1023
+ raise TypeError(
1024
+ "cannot serialize %r (type %s)" % (text, type(text).__name__)
1025
+ )
1026
+
1027
+ def _escape_cdata(text):
1028
+ # escape character data
1029
+ try:
1030
+ # it's worth avoiding do-nothing calls for strings that are
1031
+ # shorter than 500 characters, or so. assume that's, by far,
1032
+ # the most common case in most applications.
1033
+ if "&" in text:
1034
+ text = text.replace("&", "&amp;")
1035
+ if "<" in text:
1036
+ text = text.replace("<", "&lt;")
1037
+ if ">" in text:
1038
+ text = text.replace(">", "&gt;")
1039
+ return text
1040
+ except (TypeError, AttributeError):
1041
+ _raise_serialization_error(text)
1042
+
1043
+ def _escape_attrib(text):
1044
+ # escape attribute value
1045
+ try:
1046
+ if "&" in text:
1047
+ text = text.replace("&", "&amp;")
1048
+ if "<" in text:
1049
+ text = text.replace("<", "&lt;")
1050
+ if ">" in text:
1051
+ text = text.replace(">", "&gt;")
1052
+ if "\"" in text:
1053
+ text = text.replace("\"", "&quot;")
1054
+ # Although section 2.11 of the XML specification states that CR or
1055
+ # CR LN should be replaced with just LN, it applies only to EOLNs
1056
+ # which take part of organizing file into lines. Within attributes,
1057
+ # we are replacing these with entity numbers, so they do not count.
1058
+ # http://www.w3.org/TR/REC-xml/#sec-line-ends
1059
+ # The current solution, contained in following six lines, was
1060
+ # discussed in issue 17582 and 39011.
1061
+ if "\r" in text:
1062
+ text = text.replace("\r", "&#13;")
1063
+ if "\n" in text:
1064
+ text = text.replace("\n", "&#10;")
1065
+ if "\t" in text:
1066
+ text = text.replace("\t", "&#09;")
1067
+ return text
1068
+ except (TypeError, AttributeError):
1069
+ _raise_serialization_error(text)
1070
+
1071
+ def _escape_attrib_html(text):
1072
+ # escape attribute value
1073
+ try:
1074
+ if "&" in text:
1075
+ text = text.replace("&", "&amp;")
1076
+ if ">" in text:
1077
+ text = text.replace(">", "&gt;")
1078
+ if "\"" in text:
1079
+ text = text.replace("\"", "&quot;")
1080
+ return text
1081
+ except (TypeError, AttributeError):
1082
+ _raise_serialization_error(text)
1083
+
1084
+ # --------------------------------------------------------------------
1085
+
1086
+ def tostring(element, encoding=None, method=None, *,
1087
+ xml_declaration=None, default_namespace=None,
1088
+ short_empty_elements=True):
1089
+ """Generate string representation of XML element.
1090
+
1091
+ All subelements are included. If encoding is "unicode", a string
1092
+ is returned. Otherwise a bytestring is returned.
1093
+
1094
+ *element* is an Element instance, *encoding* is an optional output
1095
+ encoding defaulting to US-ASCII, *method* is an optional output which
1096
+ can be one of "xml" (default), "html", "text" or "c14n",
1097
+ *default_namespace* sets the default XML namespace (for "xmlns").
1098
+
1099
+ Returns an (optionally) encoded string containing the XML data.
1100
+
1101
+ """
1102
+ stream = io.StringIO() if encoding == 'unicode' else io.BytesIO()
1103
+ ElementTree(element).write(stream, encoding,
1104
+ xml_declaration=xml_declaration,
1105
+ default_namespace=default_namespace,
1106
+ method=method,
1107
+ short_empty_elements=short_empty_elements)
1108
+ return stream.getvalue()
1109
+
1110
+ class _ListDataStream(io.BufferedIOBase):
1111
+ """An auxiliary stream accumulating into a list reference."""
1112
+ def __init__(self, lst):
1113
+ self.lst = lst
1114
+
1115
+ def writable(self):
1116
+ return True
1117
+
1118
+ def seekable(self):
1119
+ return True
1120
+
1121
+ def write(self, b):
1122
+ self.lst.append(b)
1123
+
1124
+ def tell(self):
1125
+ return len(self.lst)
1126
+
1127
+ def tostringlist(element, encoding=None, method=None, *,
1128
+ xml_declaration=None, default_namespace=None,
1129
+ short_empty_elements=True):
1130
+ lst = []
1131
+ stream = _ListDataStream(lst)
1132
+ ElementTree(element).write(stream, encoding,
1133
+ xml_declaration=xml_declaration,
1134
+ default_namespace=default_namespace,
1135
+ method=method,
1136
+ short_empty_elements=short_empty_elements)
1137
+ return lst
1138
+
1139
+
1140
+ def dump(elem):
1141
+ """Write element tree or element structure to sys.stdout.
1142
+
1143
+ This function should be used for debugging only.
1144
+
1145
+ *elem* is either an ElementTree, or a single Element. The exact output
1146
+ format is implementation dependent. In this version, it's written as an
1147
+ ordinary XML file.
1148
+
1149
+ """
1150
+ # debugging
1151
+ if not isinstance(elem, ElementTree):
1152
+ elem = ElementTree(elem)
1153
+ elem.write(sys.stdout, encoding="unicode")
1154
+ tail = elem.getroot().tail
1155
+ if not tail or tail[-1] != "\n":
1156
+ sys.stdout.write("\n")
1157
+
1158
+
1159
+ def indent(tree, space=" ", level=0):
1160
+ """Indent an XML document by inserting newlines and indentation space
1161
+ after elements.
1162
+
1163
+ *tree* is the ElementTree or Element to modify. The (root) element
1164
+ itself will not be changed, but the tail text of all elements in its
1165
+ subtree will be adapted.
1166
+
1167
+ *space* is the whitespace to insert for each indentation level, two
1168
+ space characters by default.
1169
+
1170
+ *level* is the initial indentation level. Setting this to a higher
1171
+ value than 0 can be used for indenting subtrees that are more deeply
1172
+ nested inside of a document.
1173
+ """
1174
+ if isinstance(tree, ElementTree):
1175
+ tree = tree.getroot()
1176
+ if level < 0:
1177
+ raise ValueError(f"Initial indentation level must be >= 0, got {level}")
1178
+ if not len(tree):
1179
+ return
1180
+
1181
+ # Reduce the memory consumption by reusing indentation strings.
1182
+ indentations = ["\n" + level * space]
1183
+
1184
+ def _indent_children(elem, level):
1185
+ # Start a new indentation level for the first child.
1186
+ child_level = level + 1
1187
+ try:
1188
+ child_indentation = indentations[child_level]
1189
+ except IndexError:
1190
+ child_indentation = indentations[level] + space
1191
+ indentations.append(child_indentation)
1192
+
1193
+ if not elem.text or not elem.text.strip():
1194
+ elem.text = child_indentation
1195
+
1196
+ for child in elem:
1197
+ if len(child):
1198
+ _indent_children(child, child_level)
1199
+ if not child.tail or not child.tail.strip():
1200
+ child.tail = child_indentation
1201
+
1202
+ # Dedent after the last child by overwriting the previous indentation.
1203
+ if not child.tail.strip():
1204
+ child.tail = indentations[level]
1205
+
1206
+ _indent_children(tree, 0)
1207
+
1208
+
1209
+ # --------------------------------------------------------------------
1210
+ # parsing
1211
+
1212
+
1213
+ def parse(source, parser=None):
1214
+ """Parse XML document into element tree.
1215
+
1216
+ *source* is a filename or file object containing XML data,
1217
+ *parser* is an optional parser instance defaulting to XMLParser.
1218
+
1219
+ Return an ElementTree instance.
1220
+
1221
+ """
1222
+ tree = ElementTree()
1223
+ tree.parse(source, parser)
1224
+ return tree
1225
+
1226
+
1227
+ def iterparse(source, events=None, parser=None):
1228
+ """Incrementally parse XML document into ElementTree.
1229
+
1230
+ This class also reports what's going on to the user based on the
1231
+ *events* it is initialized with. The supported events are the strings
1232
+ "start", "end", "start-ns" and "end-ns" (the "ns" events are used to get
1233
+ detailed namespace information). If *events* is omitted, only
1234
+ "end" events are reported.
1235
+
1236
+ *source* is a filename or file object containing XML data, *events* is
1237
+ a list of events to report back, *parser* is an optional parser
1238
+ instance.
1239
+
1240
+ Returns an iterator providing (event, elem) pairs.
1241
+
1242
+ """
1243
+ # Use the internal, undocumented _parser argument for now; When the
1244
+ # parser argument of iterparse is removed, this can be killed.
1245
+ pullparser = XMLPullParser(events=events, _parser=parser)
1246
+
1247
+ if not hasattr(source, "read"):
1248
+ source = open(source, "rb")
1249
+ close_source = True
1250
+ else:
1251
+ close_source = False
1252
+
1253
+ def iterator(source):
1254
+ try:
1255
+ while True:
1256
+ yield from pullparser.read_events()
1257
+ # load event buffer
1258
+ data = source.read(16 * 1024)
1259
+ if not data:
1260
+ break
1261
+ pullparser.feed(data)
1262
+ root = pullparser._close_and_return_root()
1263
+ yield from pullparser.read_events()
1264
+ it = wr()
1265
+ if it is not None:
1266
+ it.root = root
1267
+ finally:
1268
+ if close_source:
1269
+ source.close()
1270
+
1271
+ gen = iterator(source)
1272
+ class IterParseIterator(collections.abc.Iterator):
1273
+ __next__ = gen.__next__
1274
+ def close(self):
1275
+ if close_source:
1276
+ source.close()
1277
+ gen.close()
1278
+
1279
+ def __del__(self):
1280
+ # TODO: Emit a ResourceWarning if it was not explicitly closed.
1281
+ # (When the close() method will be supported in all maintained Python versions.)
1282
+ if close_source:
1283
+ source.close()
1284
+
1285
+ it = IterParseIterator()
1286
+ it.root = None
1287
+ wr = weakref.ref(it)
1288
+ return it
1289
+
1290
+
1291
+ class XMLPullParser:
1292
+
1293
+ def __init__(self, events=None, *, _parser=None):
1294
+ # The _parser argument is for internal use only and must not be relied
1295
+ # upon in user code. It will be removed in a future release.
1296
+ # See https://bugs.python.org/issue17741 for more details.
1297
+
1298
+ self._events_queue = collections.deque()
1299
+ self._parser = _parser or XMLParser(target=TreeBuilder())
1300
+ # wire up the parser for event reporting
1301
+ if events is None:
1302
+ events = ("end",)
1303
+ self._parser._setevents(self._events_queue, events)
1304
+
1305
+ def feed(self, data):
1306
+ """Feed encoded data to parser."""
1307
+ if self._parser is None:
1308
+ raise ValueError("feed() called after end of stream")
1309
+ if data:
1310
+ try:
1311
+ self._parser.feed(data)
1312
+ except SyntaxError as exc:
1313
+ self._events_queue.append(exc)
1314
+
1315
+ def _close_and_return_root(self):
1316
+ # iterparse needs this to set its root attribute properly :(
1317
+ root = self._parser.close()
1318
+ self._parser = None
1319
+ return root
1320
+
1321
+ def close(self):
1322
+ """Finish feeding data to parser.
1323
+
1324
+ Unlike XMLParser, does not return the root element. Use
1325
+ read_events() to consume elements from XMLPullParser.
1326
+ """
1327
+ self._close_and_return_root()
1328
+
1329
+ def read_events(self):
1330
+ """Return an iterator over currently available (event, elem) pairs.
1331
+
1332
+ Events are consumed from the internal event queue as they are
1333
+ retrieved from the iterator.
1334
+ """
1335
+ events = self._events_queue
1336
+ while events:
1337
+ event = events.popleft()
1338
+ if isinstance(event, Exception):
1339
+ raise event
1340
+ else:
1341
+ yield event
1342
+
1343
+ def flush(self):
1344
+ if self._parser is None:
1345
+ raise ValueError("flush() called after end of stream")
1346
+ self._parser.flush()
1347
+
1348
+
1349
+ def XML(text, parser=None):
1350
+ """Parse XML document from string constant.
1351
+
1352
+ This function can be used to embed "XML Literals" in Python code.
1353
+
1354
+ *text* is a string containing XML data, *parser* is an
1355
+ optional parser instance, defaulting to the standard XMLParser.
1356
+
1357
+ Returns an Element instance.
1358
+
1359
+ """
1360
+ if not parser:
1361
+ parser = XMLParser(target=TreeBuilder())
1362
+ parser.feed(text)
1363
+ return parser.close()
1364
+
1365
+
1366
+ def XMLID(text, parser=None):
1367
+ """Parse XML document from string constant for its IDs.
1368
+
1369
+ *text* is a string containing XML data, *parser* is an
1370
+ optional parser instance, defaulting to the standard XMLParser.
1371
+
1372
+ Returns an (Element, dict) tuple, in which the
1373
+ dict maps element id:s to elements.
1374
+
1375
+ """
1376
+ if not parser:
1377
+ parser = XMLParser(target=TreeBuilder())
1378
+ parser.feed(text)
1379
+ tree = parser.close()
1380
+ ids = {}
1381
+ for elem in tree.iter():
1382
+ id = elem.get("id")
1383
+ if id:
1384
+ ids[id] = elem
1385
+ return tree, ids
1386
+
1387
+ # Parse XML document from string constant. Alias for XML().
1388
+ fromstring = XML
1389
+
1390
+ def fromstringlist(sequence, parser=None):
1391
+ """Parse XML document from sequence of string fragments.
1392
+
1393
+ *sequence* is a list of other sequence, *parser* is an optional parser
1394
+ instance, defaulting to the standard XMLParser.
1395
+
1396
+ Returns an Element instance.
1397
+
1398
+ """
1399
+ if not parser:
1400
+ parser = XMLParser(target=TreeBuilder())
1401
+ for text in sequence:
1402
+ parser.feed(text)
1403
+ return parser.close()
1404
+
1405
+ # --------------------------------------------------------------------
1406
+
1407
+
1408
+ class TreeBuilder:
1409
+ """Generic element structure builder.
1410
+
1411
+ This builder converts a sequence of start, data, and end method
1412
+ calls to a well-formed element structure.
1413
+
1414
+ You can use this class to build an element structure using a custom XML
1415
+ parser, or a parser for some other XML-like format.
1416
+
1417
+ *element_factory* is an optional element factory which is called
1418
+ to create new Element instances, as necessary.
1419
+
1420
+ *comment_factory* is a factory to create comments to be used instead of
1421
+ the standard factory. If *insert_comments* is false (the default),
1422
+ comments will not be inserted into the tree.
1423
+
1424
+ *pi_factory* is a factory to create processing instructions to be used
1425
+ instead of the standard factory. If *insert_pis* is false (the default),
1426
+ processing instructions will not be inserted into the tree.
1427
+ """
1428
+ def __init__(self, element_factory=None, *,
1429
+ comment_factory=None, pi_factory=None,
1430
+ insert_comments=False, insert_pis=False):
1431
+ self._data = [] # data collector
1432
+ self._elem = [] # element stack
1433
+ self._last = None # last element
1434
+ self._root = None # root element
1435
+ self._tail = None # true if we're after an end tag
1436
+ if comment_factory is None:
1437
+ comment_factory = Comment
1438
+ self._comment_factory = comment_factory
1439
+ self.insert_comments = insert_comments
1440
+ if pi_factory is None:
1441
+ pi_factory = ProcessingInstruction
1442
+ self._pi_factory = pi_factory
1443
+ self.insert_pis = insert_pis
1444
+ if element_factory is None:
1445
+ element_factory = Element
1446
+ self._factory = element_factory
1447
+
1448
+ def close(self):
1449
+ """Flush builder buffers and return toplevel document Element."""
1450
+ assert len(self._elem) == 0, "missing end tags"
1451
+ assert self._root is not None, "missing toplevel element"
1452
+ return self._root
1453
+
1454
+ def _flush(self):
1455
+ if self._data:
1456
+ if self._last is not None:
1457
+ text = "".join(self._data)
1458
+ if self._tail:
1459
+ assert self._last.tail is None, "internal error (tail)"
1460
+ self._last.tail = text
1461
+ else:
1462
+ assert self._last.text is None, "internal error (text)"
1463
+ self._last.text = text
1464
+ self._data = []
1465
+
1466
+ def data(self, data):
1467
+ """Add text to current element."""
1468
+ self._data.append(data)
1469
+
1470
+ def start(self, tag, attrs):
1471
+ """Open new element and return it.
1472
+
1473
+ *tag* is the element name, *attrs* is a dict containing element
1474
+ attributes.
1475
+
1476
+ """
1477
+ self._flush()
1478
+ self._last = elem = self._factory(tag, attrs)
1479
+ if self._elem:
1480
+ self._elem[-1].append(elem)
1481
+ elif self._root is None:
1482
+ self._root = elem
1483
+ self._elem.append(elem)
1484
+ self._tail = 0
1485
+ return elem
1486
+
1487
+ def end(self, tag):
1488
+ """Close and return current Element.
1489
+
1490
+ *tag* is the element name.
1491
+
1492
+ """
1493
+ self._flush()
1494
+ self._last = self._elem.pop()
1495
+ assert self._last.tag == tag,\
1496
+ "end tag mismatch (expected %s, got %s)" % (
1497
+ self._last.tag, tag)
1498
+ self._tail = 1
1499
+ return self._last
1500
+
1501
+ def comment(self, text):
1502
+ """Create a comment using the comment_factory.
1503
+
1504
+ *text* is the text of the comment.
1505
+ """
1506
+ return self._handle_single(
1507
+ self._comment_factory, self.insert_comments, text)
1508
+
1509
+ def pi(self, target, text=None):
1510
+ """Create a processing instruction using the pi_factory.
1511
+
1512
+ *target* is the target name of the processing instruction.
1513
+ *text* is the data of the processing instruction, or ''.
1514
+ """
1515
+ return self._handle_single(
1516
+ self._pi_factory, self.insert_pis, target, text)
1517
+
1518
+ def _handle_single(self, factory, insert, *args):
1519
+ elem = factory(*args)
1520
+ if insert:
1521
+ self._flush()
1522
+ self._last = elem
1523
+ if self._elem:
1524
+ self._elem[-1].append(elem)
1525
+ self._tail = 1
1526
+ return elem
1527
+
1528
+
1529
+ # also see ElementTree and TreeBuilder
1530
+ class XMLParser:
1531
+ """Element structure builder for XML source data based on the expat parser.
1532
+
1533
+ *target* is an optional target object which defaults to an instance of the
1534
+ standard TreeBuilder class, *encoding* is an optional encoding string
1535
+ which if given, overrides the encoding specified in the XML file:
1536
+ http://www.iana.org/assignments/character-sets
1537
+
1538
+ """
1539
+
1540
+ def __init__(self, *, target=None, encoding=None):
1541
+ try:
1542
+ from xml.parsers import expat
1543
+ except ImportError:
1544
+ try:
1545
+ import pyexpat as expat
1546
+ except ImportError:
1547
+ raise ImportError(
1548
+ "No module named expat; use SimpleXMLTreeBuilder instead"
1549
+ )
1550
+ parser = expat.ParserCreate(encoding, "}")
1551
+ if target is None:
1552
+ target = TreeBuilder()
1553
+ # underscored names are provided for compatibility only
1554
+ self.parser = self._parser = parser
1555
+ self.target = self._target = target
1556
+ self._error = expat.error
1557
+ self._names = {} # name memo cache
1558
+ # main callbacks
1559
+ parser.DefaultHandlerExpand = self._default
1560
+ if hasattr(target, 'start'):
1561
+ parser.StartElementHandler = self._start
1562
+ if hasattr(target, 'end'):
1563
+ parser.EndElementHandler = self._end
1564
+ if hasattr(target, 'start_ns'):
1565
+ parser.StartNamespaceDeclHandler = self._start_ns
1566
+ if hasattr(target, 'end_ns'):
1567
+ parser.EndNamespaceDeclHandler = self._end_ns
1568
+ if hasattr(target, 'data'):
1569
+ parser.CharacterDataHandler = target.data
1570
+ # miscellaneous callbacks
1571
+ if hasattr(target, 'comment'):
1572
+ parser.CommentHandler = target.comment
1573
+ if hasattr(target, 'pi'):
1574
+ parser.ProcessingInstructionHandler = target.pi
1575
+ # Configure pyexpat: buffering, new-style attribute handling.
1576
+ parser.buffer_text = 1
1577
+ parser.ordered_attributes = 1
1578
+ self._doctype = None
1579
+ self.entity = {}
1580
+ try:
1581
+ self.version = "Expat %d.%d.%d" % expat.version_info
1582
+ except AttributeError:
1583
+ pass # unknown
1584
+
1585
+ def _setevents(self, events_queue, events_to_report):
1586
+ # Internal API for XMLPullParser
1587
+ # events_to_report: a list of events to report during parsing (same as
1588
+ # the *events* of XMLPullParser's constructor.
1589
+ # events_queue: a list of actual parsing events that will be populated
1590
+ # by the underlying parser.
1591
+ #
1592
+ parser = self._parser
1593
+ append = events_queue.append
1594
+ for event_name in events_to_report:
1595
+ if event_name == "start":
1596
+ parser.ordered_attributes = 1
1597
+ def handler(tag, attrib_in, event=event_name, append=append,
1598
+ start=self._start):
1599
+ append((event, start(tag, attrib_in)))
1600
+ parser.StartElementHandler = handler
1601
+ elif event_name == "end":
1602
+ def handler(tag, event=event_name, append=append,
1603
+ end=self._end):
1604
+ append((event, end(tag)))
1605
+ parser.EndElementHandler = handler
1606
+ elif event_name == "start-ns":
1607
+ # TreeBuilder does not implement .start_ns()
1608
+ if hasattr(self.target, "start_ns"):
1609
+ def handler(prefix, uri, event=event_name, append=append,
1610
+ start_ns=self._start_ns):
1611
+ append((event, start_ns(prefix, uri)))
1612
+ else:
1613
+ def handler(prefix, uri, event=event_name, append=append):
1614
+ append((event, (prefix or '', uri or '')))
1615
+ parser.StartNamespaceDeclHandler = handler
1616
+ elif event_name == "end-ns":
1617
+ # TreeBuilder does not implement .end_ns()
1618
+ if hasattr(self.target, "end_ns"):
1619
+ def handler(prefix, event=event_name, append=append,
1620
+ end_ns=self._end_ns):
1621
+ append((event, end_ns(prefix)))
1622
+ else:
1623
+ def handler(prefix, event=event_name, append=append):
1624
+ append((event, None))
1625
+ parser.EndNamespaceDeclHandler = handler
1626
+ elif event_name == 'comment':
1627
+ def handler(text, event=event_name, append=append, self=self):
1628
+ append((event, self.target.comment(text)))
1629
+ parser.CommentHandler = handler
1630
+ elif event_name == 'pi':
1631
+ def handler(pi_target, data, event=event_name, append=append,
1632
+ self=self):
1633
+ append((event, self.target.pi(pi_target, data)))
1634
+ parser.ProcessingInstructionHandler = handler
1635
+ else:
1636
+ raise ValueError("unknown event %r" % event_name)
1637
+
1638
+ def _raiseerror(self, value):
1639
+ err = ParseError(value)
1640
+ err.code = value.code
1641
+ err.position = value.lineno, value.offset
1642
+ raise err
1643
+
1644
+ def _fixname(self, key):
1645
+ # expand qname, and convert name string to ascii, if possible
1646
+ try:
1647
+ name = self._names[key]
1648
+ except KeyError:
1649
+ name = key
1650
+ if "}" in name:
1651
+ name = "{" + name
1652
+ self._names[key] = name
1653
+ return name
1654
+
1655
+ def _start_ns(self, prefix, uri):
1656
+ return self.target.start_ns(prefix or '', uri or '')
1657
+
1658
+ def _end_ns(self, prefix):
1659
+ return self.target.end_ns(prefix or '')
1660
+
1661
+ def _start(self, tag, attr_list):
1662
+ # Handler for expat's StartElementHandler. Since ordered_attributes
1663
+ # is set, the attributes are reported as a list of alternating
1664
+ # attribute name,value.
1665
+ fixname = self._fixname
1666
+ tag = fixname(tag)
1667
+ attrib = {}
1668
+ if attr_list:
1669
+ for i in range(0, len(attr_list), 2):
1670
+ attrib[fixname(attr_list[i])] = attr_list[i+1]
1671
+ return self.target.start(tag, attrib)
1672
+
1673
+ def _end(self, tag):
1674
+ return self.target.end(self._fixname(tag))
1675
+
1676
+ def _default(self, text):
1677
+ prefix = text[:1]
1678
+ if prefix == "&":
1679
+ # deal with undefined entities
1680
+ try:
1681
+ data_handler = self.target.data
1682
+ except AttributeError:
1683
+ return
1684
+ try:
1685
+ data_handler(self.entity[text[1:-1]])
1686
+ except KeyError:
1687
+ from xml.parsers import expat
1688
+ err = expat.error(
1689
+ "undefined entity %s: line %d, column %d" %
1690
+ (text, self.parser.ErrorLineNumber,
1691
+ self.parser.ErrorColumnNumber)
1692
+ )
1693
+ err.code = 11 # XML_ERROR_UNDEFINED_ENTITY
1694
+ err.lineno = self.parser.ErrorLineNumber
1695
+ err.offset = self.parser.ErrorColumnNumber
1696
+ raise err
1697
+ elif prefix == "<" and text[:9] == "<!DOCTYPE":
1698
+ self._doctype = [] # inside a doctype declaration
1699
+ elif self._doctype is not None:
1700
+ # parse doctype contents
1701
+ if prefix == ">":
1702
+ self._doctype = None
1703
+ return
1704
+ text = text.strip()
1705
+ if not text:
1706
+ return
1707
+ self._doctype.append(text)
1708
+ n = len(self._doctype)
1709
+ if n > 2:
1710
+ type = self._doctype[1]
1711
+ if type == "PUBLIC" and n == 4:
1712
+ name, type, pubid, system = self._doctype
1713
+ if pubid:
1714
+ pubid = pubid[1:-1]
1715
+ elif type == "SYSTEM" and n == 3:
1716
+ name, type, system = self._doctype
1717
+ pubid = None
1718
+ else:
1719
+ return
1720
+ if hasattr(self.target, "doctype"):
1721
+ self.target.doctype(name, pubid, system[1:-1])
1722
+ elif hasattr(self, "doctype"):
1723
+ warnings.warn(
1724
+ "The doctype() method of XMLParser is ignored. "
1725
+ "Define doctype() method on the TreeBuilder target.",
1726
+ RuntimeWarning)
1727
+
1728
+ self._doctype = None
1729
+
1730
+ def feed(self, data):
1731
+ """Feed encoded data to parser."""
1732
+ try:
1733
+ self.parser.Parse(data, False)
1734
+ except self._error as v:
1735
+ self._raiseerror(v)
1736
+
1737
+ def close(self):
1738
+ """Finish feeding data to parser and return element structure."""
1739
+ try:
1740
+ self.parser.Parse(b"", True) # end of data
1741
+ except self._error as v:
1742
+ self._raiseerror(v)
1743
+ try:
1744
+ close_handler = self.target.close
1745
+ except AttributeError:
1746
+ pass
1747
+ else:
1748
+ return close_handler()
1749
+ finally:
1750
+ # get rid of circular references
1751
+ del self.parser, self._parser
1752
+ del self.target, self._target
1753
+
1754
+ def flush(self):
1755
+ was_enabled = self.parser.GetReparseDeferralEnabled()
1756
+ try:
1757
+ self.parser.SetReparseDeferralEnabled(False)
1758
+ self.parser.Parse(b"", False)
1759
+ except self._error as v:
1760
+ self._raiseerror(v)
1761
+ finally:
1762
+ self.parser.SetReparseDeferralEnabled(was_enabled)
1763
+
1764
+ # --------------------------------------------------------------------
1765
+ # C14N 2.0
1766
+
1767
+ def canonicalize(xml_data=None, *, out=None, from_file=None, **options):
1768
+ """Convert XML to its C14N 2.0 serialised form.
1769
+
1770
+ If *out* is provided, it must be a file or file-like object that
1771
+ receives the serialised canonical XML output (text, not bytes) through
1772
+ its ``.write()`` method. To write to a file, open it in text mode with
1773
+ encoding "utf-8". If *out* is not provided, this function returns the
1774
+ output as text string.
1775
+
1776
+ Either *xml_data* (an XML string) or *from_file* (a file path or
1777
+ file-like object) must be provided as input.
1778
+
1779
+ The configuration options are the same as for the ``C14NWriterTarget``.
1780
+ """
1781
+ if xml_data is None and from_file is None:
1782
+ raise ValueError("Either 'xml_data' or 'from_file' must be provided as input")
1783
+ sio = None
1784
+ if out is None:
1785
+ sio = out = io.StringIO()
1786
+
1787
+ parser = XMLParser(target=C14NWriterTarget(out.write, **options))
1788
+
1789
+ if xml_data is not None:
1790
+ parser.feed(xml_data)
1791
+ parser.close()
1792
+ elif from_file is not None:
1793
+ parse(from_file, parser=parser)
1794
+
1795
+ return sio.getvalue() if sio is not None else None
1796
+
1797
+
1798
+ _looks_like_prefix_name = re.compile(r'^\w+:\w+$', re.UNICODE).match
1799
+
1800
+
1801
+ class C14NWriterTarget:
1802
+ """
1803
+ Canonicalization writer target for the XMLParser.
1804
+
1805
+ Serialises parse events to XML C14N 2.0.
1806
+
1807
+ The *write* function is used for writing out the resulting data stream
1808
+ as text (not bytes). To write to a file, open it in text mode with
1809
+ encoding "utf-8" and pass its ``.write`` method.
1810
+
1811
+ Configuration options:
1812
+
1813
+ - *with_comments*: set to true to include comments
1814
+ - *strip_text*: set to true to strip whitespace before and after text
1815
+ content
1816
+ - *rewrite_prefixes*: set to true to replace namespace prefixes by
1817
+ "n{number}"
1818
+ - *qname_aware_tags*: a set of qname aware tag names in which prefixes
1819
+ should be replaced in text content
1820
+ - *qname_aware_attrs*: a set of qname aware attribute names in which
1821
+ prefixes should be replaced in text content
1822
+ - *exclude_attrs*: a set of attribute names that should not be
1823
+ serialised
1824
+ - *exclude_tags*: a set of tag names that should not be serialised
1825
+ """
1826
+ def __init__(self, write, *,
1827
+ with_comments=False, strip_text=False, rewrite_prefixes=False,
1828
+ qname_aware_tags=None, qname_aware_attrs=None,
1829
+ exclude_attrs=None, exclude_tags=None):
1830
+ self._write = write
1831
+ self._data = []
1832
+ self._with_comments = with_comments
1833
+ self._strip_text = strip_text
1834
+ self._exclude_attrs = set(exclude_attrs) if exclude_attrs else None
1835
+ self._exclude_tags = set(exclude_tags) if exclude_tags else None
1836
+
1837
+ self._rewrite_prefixes = rewrite_prefixes
1838
+ if qname_aware_tags:
1839
+ self._qname_aware_tags = set(qname_aware_tags)
1840
+ else:
1841
+ self._qname_aware_tags = None
1842
+ if qname_aware_attrs:
1843
+ self._find_qname_aware_attrs = set(qname_aware_attrs).intersection
1844
+ else:
1845
+ self._find_qname_aware_attrs = None
1846
+
1847
+ # Stack with globally and newly declared namespaces as (uri, prefix) pairs.
1848
+ self._declared_ns_stack = [[
1849
+ ("http://www.w3.org/XML/1998/namespace", "xml"),
1850
+ ]]
1851
+ # Stack with user declared namespace prefixes as (uri, prefix) pairs.
1852
+ self._ns_stack = []
1853
+ if not rewrite_prefixes:
1854
+ self._ns_stack.append(list(_namespace_map.items()))
1855
+ self._ns_stack.append([])
1856
+ self._prefix_map = {}
1857
+ self._preserve_space = [False]
1858
+ self._pending_start = None
1859
+ self._root_seen = False
1860
+ self._root_done = False
1861
+ self._ignored_depth = 0
1862
+
1863
+ def _iter_namespaces(self, ns_stack, _reversed=reversed):
1864
+ for namespaces in _reversed(ns_stack):
1865
+ if namespaces: # almost no element declares new namespaces
1866
+ yield from namespaces
1867
+
1868
+ def _resolve_prefix_name(self, prefixed_name):
1869
+ prefix, name = prefixed_name.split(':', 1)
1870
+ for uri, p in self._iter_namespaces(self._ns_stack):
1871
+ if p == prefix:
1872
+ return f'{{{uri}}}{name}'
1873
+ raise ValueError(f'Prefix {prefix} of QName "{prefixed_name}" is not declared in scope')
1874
+
1875
+ def _qname(self, qname, uri=None):
1876
+ if uri is None:
1877
+ uri, tag = qname[1:].rsplit('}', 1) if qname[:1] == '{' else ('', qname)
1878
+ else:
1879
+ tag = qname
1880
+
1881
+ prefixes_seen = set()
1882
+ for u, prefix in self._iter_namespaces(self._declared_ns_stack):
1883
+ if u == uri and prefix not in prefixes_seen:
1884
+ return f'{prefix}:{tag}' if prefix else tag, tag, uri
1885
+ prefixes_seen.add(prefix)
1886
+
1887
+ # Not declared yet => add new declaration.
1888
+ if self._rewrite_prefixes:
1889
+ if uri in self._prefix_map:
1890
+ prefix = self._prefix_map[uri]
1891
+ else:
1892
+ prefix = self._prefix_map[uri] = f'n{len(self._prefix_map)}'
1893
+ self._declared_ns_stack[-1].append((uri, prefix))
1894
+ return f'{prefix}:{tag}', tag, uri
1895
+
1896
+ if not uri and '' not in prefixes_seen:
1897
+ # No default namespace declared => no prefix needed.
1898
+ return tag, tag, uri
1899
+
1900
+ for u, prefix in self._iter_namespaces(self._ns_stack):
1901
+ if u == uri:
1902
+ self._declared_ns_stack[-1].append((uri, prefix))
1903
+ return f'{prefix}:{tag}' if prefix else tag, tag, uri
1904
+
1905
+ if not uri:
1906
+ # As soon as a default namespace is defined,
1907
+ # anything that has no namespace (and thus, no prefix) goes there.
1908
+ return tag, tag, uri
1909
+
1910
+ raise ValueError(f'Namespace "{uri}" is not declared in scope')
1911
+
1912
+ def data(self, data):
1913
+ if not self._ignored_depth:
1914
+ self._data.append(data)
1915
+
1916
+ def _flush(self, _join_text=''.join):
1917
+ data = _join_text(self._data)
1918
+ del self._data[:]
1919
+ if self._strip_text and not self._preserve_space[-1]:
1920
+ data = data.strip()
1921
+ if self._pending_start is not None:
1922
+ args, self._pending_start = self._pending_start, None
1923
+ qname_text = data if data and _looks_like_prefix_name(data) else None
1924
+ self._start(*args, qname_text)
1925
+ if qname_text is not None:
1926
+ return
1927
+ if data and self._root_seen:
1928
+ self._write(_escape_cdata_c14n(data))
1929
+
1930
+ def start_ns(self, prefix, uri):
1931
+ if self._ignored_depth:
1932
+ return
1933
+ # we may have to resolve qnames in text content
1934
+ if self._data:
1935
+ self._flush()
1936
+ self._ns_stack[-1].append((uri, prefix))
1937
+
1938
+ def start(self, tag, attrs):
1939
+ if self._exclude_tags is not None and (
1940
+ self._ignored_depth or tag in self._exclude_tags):
1941
+ self._ignored_depth += 1
1942
+ return
1943
+ if self._data:
1944
+ self._flush()
1945
+
1946
+ new_namespaces = []
1947
+ self._declared_ns_stack.append(new_namespaces)
1948
+
1949
+ if self._qname_aware_tags is not None and tag in self._qname_aware_tags:
1950
+ # Need to parse text first to see if it requires a prefix declaration.
1951
+ self._pending_start = (tag, attrs, new_namespaces)
1952
+ return
1953
+ self._start(tag, attrs, new_namespaces)
1954
+
1955
+ def _start(self, tag, attrs, new_namespaces, qname_text=None):
1956
+ if self._exclude_attrs is not None and attrs:
1957
+ attrs = {k: v for k, v in attrs.items() if k not in self._exclude_attrs}
1958
+
1959
+ qnames = {tag, *attrs}
1960
+ resolved_names = {}
1961
+
1962
+ # Resolve prefixes in attribute and tag text.
1963
+ if qname_text is not None:
1964
+ qname = resolved_names[qname_text] = self._resolve_prefix_name(qname_text)
1965
+ qnames.add(qname)
1966
+ if self._find_qname_aware_attrs is not None and attrs:
1967
+ qattrs = self._find_qname_aware_attrs(attrs)
1968
+ if qattrs:
1969
+ for attr_name in qattrs:
1970
+ value = attrs[attr_name]
1971
+ if _looks_like_prefix_name(value):
1972
+ qname = resolved_names[value] = self._resolve_prefix_name(value)
1973
+ qnames.add(qname)
1974
+ else:
1975
+ qattrs = None
1976
+ else:
1977
+ qattrs = None
1978
+
1979
+ # Assign prefixes in lexicographical order of used URIs.
1980
+ parse_qname = self._qname
1981
+ parsed_qnames = {n: parse_qname(n) for n in sorted(
1982
+ qnames, key=lambda n: n.split('}', 1))}
1983
+
1984
+ # Write namespace declarations in prefix order ...
1985
+ if new_namespaces:
1986
+ attr_list = [
1987
+ ('xmlns:' + prefix if prefix else 'xmlns', uri)
1988
+ for uri, prefix in new_namespaces
1989
+ ]
1990
+ attr_list.sort()
1991
+ else:
1992
+ # almost always empty
1993
+ attr_list = []
1994
+
1995
+ # ... followed by attributes in URI+name order
1996
+ if attrs:
1997
+ for k, v in sorted(attrs.items()):
1998
+ if qattrs is not None and k in qattrs and v in resolved_names:
1999
+ v = parsed_qnames[resolved_names[v]][0]
2000
+ attr_qname, attr_name, uri = parsed_qnames[k]
2001
+ # No prefix for attributes in default ('') namespace.
2002
+ attr_list.append((attr_qname if uri else attr_name, v))
2003
+
2004
+ # Honour xml:space attributes.
2005
+ space_behaviour = attrs.get('{http://www.w3.org/XML/1998/namespace}space')
2006
+ self._preserve_space.append(
2007
+ space_behaviour == 'preserve' if space_behaviour
2008
+ else self._preserve_space[-1])
2009
+
2010
+ # Write the tag.
2011
+ write = self._write
2012
+ write('<' + parsed_qnames[tag][0])
2013
+ if attr_list:
2014
+ write(''.join([f' {k}="{_escape_attrib_c14n(v)}"' for k, v in attr_list]))
2015
+ write('>')
2016
+
2017
+ # Write the resolved qname text content.
2018
+ if qname_text is not None:
2019
+ write(_escape_cdata_c14n(parsed_qnames[resolved_names[qname_text]][0]))
2020
+
2021
+ self._root_seen = True
2022
+ self._ns_stack.append([])
2023
+
2024
+ def end(self, tag):
2025
+ if self._ignored_depth:
2026
+ self._ignored_depth -= 1
2027
+ return
2028
+ if self._data:
2029
+ self._flush()
2030
+ self._write(f'</{self._qname(tag)[0]}>')
2031
+ self._preserve_space.pop()
2032
+ self._root_done = len(self._preserve_space) == 1
2033
+ self._declared_ns_stack.pop()
2034
+ self._ns_stack.pop()
2035
+
2036
+ def comment(self, text):
2037
+ if not self._with_comments:
2038
+ return
2039
+ if self._ignored_depth:
2040
+ return
2041
+ if self._root_done:
2042
+ self._write('\n')
2043
+ elif self._root_seen and self._data:
2044
+ self._flush()
2045
+ self._write(f'<!--{_escape_cdata_c14n(text)}-->')
2046
+ if not self._root_seen:
2047
+ self._write('\n')
2048
+
2049
+ def pi(self, target, data):
2050
+ if self._ignored_depth:
2051
+ return
2052
+ if self._root_done:
2053
+ self._write('\n')
2054
+ elif self._root_seen and self._data:
2055
+ self._flush()
2056
+ self._write(
2057
+ f'<?{target} {_escape_cdata_c14n(data)}?>' if data else f'<?{target}?>')
2058
+ if not self._root_seen:
2059
+ self._write('\n')
2060
+
2061
+
2062
+ def _escape_cdata_c14n(text):
2063
+ # escape character data
2064
+ try:
2065
+ # it's worth avoiding do-nothing calls for strings that are
2066
+ # shorter than 500 character, or so. assume that's, by far,
2067
+ # the most common case in most applications.
2068
+ if '&' in text:
2069
+ text = text.replace('&', '&amp;')
2070
+ if '<' in text:
2071
+ text = text.replace('<', '&lt;')
2072
+ if '>' in text:
2073
+ text = text.replace('>', '&gt;')
2074
+ if '\r' in text:
2075
+ text = text.replace('\r', '&#xD;')
2076
+ return text
2077
+ except (TypeError, AttributeError):
2078
+ _raise_serialization_error(text)
2079
+
2080
+
2081
+ def _escape_attrib_c14n(text):
2082
+ # escape attribute value
2083
+ try:
2084
+ if '&' in text:
2085
+ text = text.replace('&', '&amp;')
2086
+ if '<' in text:
2087
+ text = text.replace('<', '&lt;')
2088
+ if '"' in text:
2089
+ text = text.replace('"', '&quot;')
2090
+ if '\t' in text:
2091
+ text = text.replace('\t', '&#x9;')
2092
+ if '\n' in text:
2093
+ text = text.replace('\n', '&#xA;')
2094
+ if '\r' in text:
2095
+ text = text.replace('\r', '&#xD;')
2096
+ return text
2097
+ except (TypeError, AttributeError):
2098
+ _raise_serialization_error(text)
2099
+
2100
+
2101
+ # --------------------------------------------------------------------
2102
+
2103
+ # Import the C accelerators
2104
+ try:
2105
+ # Element is going to be shadowed by the C implementation. We need to keep
2106
+ # the Python version of it accessible for some "creative" by external code
2107
+ # (see tests)
2108
+ _Element_Py = Element
2109
+
2110
+ # Element, SubElement, ParseError, TreeBuilder, XMLParser, _set_factories
2111
+ from _elementtree import *
2112
+ from _elementtree import _set_factories
2113
+ except ImportError:
2114
+ pass
2115
+ else:
2116
+ _set_factories(Comment, ProcessingInstruction)