tensorbored 2.21.0rc1769983804__py3-none-any.whl

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 (271) hide show
  1. tensorbored/__init__.py +112 -0
  2. tensorbored/_vendor/__init__.py +0 -0
  3. tensorbored/_vendor/bleach/__init__.py +125 -0
  4. tensorbored/_vendor/bleach/_vendor/__init__.py +0 -0
  5. tensorbored/_vendor/bleach/_vendor/html5lib/__init__.py +35 -0
  6. tensorbored/_vendor/bleach/_vendor/html5lib/_ihatexml.py +289 -0
  7. tensorbored/_vendor/bleach/_vendor/html5lib/_inputstream.py +918 -0
  8. tensorbored/_vendor/bleach/_vendor/html5lib/_tokenizer.py +1735 -0
  9. tensorbored/_vendor/bleach/_vendor/html5lib/_trie/__init__.py +5 -0
  10. tensorbored/_vendor/bleach/_vendor/html5lib/_trie/_base.py +40 -0
  11. tensorbored/_vendor/bleach/_vendor/html5lib/_trie/py.py +67 -0
  12. tensorbored/_vendor/bleach/_vendor/html5lib/_utils.py +159 -0
  13. tensorbored/_vendor/bleach/_vendor/html5lib/constants.py +2946 -0
  14. tensorbored/_vendor/bleach/_vendor/html5lib/filters/__init__.py +0 -0
  15. tensorbored/_vendor/bleach/_vendor/html5lib/filters/alphabeticalattributes.py +29 -0
  16. tensorbored/_vendor/bleach/_vendor/html5lib/filters/base.py +12 -0
  17. tensorbored/_vendor/bleach/_vendor/html5lib/filters/inject_meta_charset.py +73 -0
  18. tensorbored/_vendor/bleach/_vendor/html5lib/filters/lint.py +93 -0
  19. tensorbored/_vendor/bleach/_vendor/html5lib/filters/optionaltags.py +207 -0
  20. tensorbored/_vendor/bleach/_vendor/html5lib/filters/sanitizer.py +916 -0
  21. tensorbored/_vendor/bleach/_vendor/html5lib/filters/whitespace.py +38 -0
  22. tensorbored/_vendor/bleach/_vendor/html5lib/html5parser.py +2795 -0
  23. tensorbored/_vendor/bleach/_vendor/html5lib/serializer.py +409 -0
  24. tensorbored/_vendor/bleach/_vendor/html5lib/treeadapters/__init__.py +30 -0
  25. tensorbored/_vendor/bleach/_vendor/html5lib/treeadapters/genshi.py +54 -0
  26. tensorbored/_vendor/bleach/_vendor/html5lib/treeadapters/sax.py +50 -0
  27. tensorbored/_vendor/bleach/_vendor/html5lib/treebuilders/__init__.py +88 -0
  28. tensorbored/_vendor/bleach/_vendor/html5lib/treebuilders/base.py +417 -0
  29. tensorbored/_vendor/bleach/_vendor/html5lib/treebuilders/dom.py +239 -0
  30. tensorbored/_vendor/bleach/_vendor/html5lib/treebuilders/etree.py +343 -0
  31. tensorbored/_vendor/bleach/_vendor/html5lib/treebuilders/etree_lxml.py +392 -0
  32. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/__init__.py +154 -0
  33. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/base.py +252 -0
  34. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/dom.py +43 -0
  35. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/etree.py +131 -0
  36. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/etree_lxml.py +215 -0
  37. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/genshi.py +69 -0
  38. tensorbored/_vendor/bleach/_vendor/parse.py +1078 -0
  39. tensorbored/_vendor/bleach/callbacks.py +32 -0
  40. tensorbored/_vendor/bleach/html5lib_shim.py +757 -0
  41. tensorbored/_vendor/bleach/linkifier.py +633 -0
  42. tensorbored/_vendor/bleach/parse_shim.py +1 -0
  43. tensorbored/_vendor/bleach/sanitizer.py +638 -0
  44. tensorbored/_vendor/bleach/six_shim.py +19 -0
  45. tensorbored/_vendor/webencodings/__init__.py +342 -0
  46. tensorbored/_vendor/webencodings/labels.py +231 -0
  47. tensorbored/_vendor/webencodings/mklabels.py +59 -0
  48. tensorbored/_vendor/webencodings/x_user_defined.py +325 -0
  49. tensorbored/assets.py +36 -0
  50. tensorbored/auth.py +102 -0
  51. tensorbored/backend/__init__.py +0 -0
  52. tensorbored/backend/application.py +604 -0
  53. tensorbored/backend/auth_context_middleware.py +38 -0
  54. tensorbored/backend/client_feature_flags.py +113 -0
  55. tensorbored/backend/empty_path_redirect.py +46 -0
  56. tensorbored/backend/event_processing/__init__.py +0 -0
  57. tensorbored/backend/event_processing/data_ingester.py +276 -0
  58. tensorbored/backend/event_processing/data_provider.py +535 -0
  59. tensorbored/backend/event_processing/directory_loader.py +142 -0
  60. tensorbored/backend/event_processing/directory_watcher.py +272 -0
  61. tensorbored/backend/event_processing/event_accumulator.py +950 -0
  62. tensorbored/backend/event_processing/event_file_inspector.py +463 -0
  63. tensorbored/backend/event_processing/event_file_loader.py +292 -0
  64. tensorbored/backend/event_processing/event_multiplexer.py +521 -0
  65. tensorbored/backend/event_processing/event_util.py +68 -0
  66. tensorbored/backend/event_processing/io_wrapper.py +223 -0
  67. tensorbored/backend/event_processing/plugin_asset_util.py +104 -0
  68. tensorbored/backend/event_processing/plugin_event_accumulator.py +721 -0
  69. tensorbored/backend/event_processing/plugin_event_multiplexer.py +522 -0
  70. tensorbored/backend/event_processing/reservoir.py +266 -0
  71. tensorbored/backend/event_processing/tag_types.py +29 -0
  72. tensorbored/backend/experiment_id.py +71 -0
  73. tensorbored/backend/experimental_plugin.py +51 -0
  74. tensorbored/backend/http_util.py +263 -0
  75. tensorbored/backend/json_util.py +70 -0
  76. tensorbored/backend/path_prefix.py +67 -0
  77. tensorbored/backend/process_graph.py +74 -0
  78. tensorbored/backend/security_validator.py +202 -0
  79. tensorbored/compat/__init__.py +69 -0
  80. tensorbored/compat/proto/__init__.py +0 -0
  81. tensorbored/compat/proto/allocation_description_pb2.py +35 -0
  82. tensorbored/compat/proto/api_def_pb2.py +82 -0
  83. tensorbored/compat/proto/attr_value_pb2.py +80 -0
  84. tensorbored/compat/proto/cluster_pb2.py +58 -0
  85. tensorbored/compat/proto/config_pb2.py +271 -0
  86. tensorbored/compat/proto/coordination_config_pb2.py +45 -0
  87. tensorbored/compat/proto/cost_graph_pb2.py +87 -0
  88. tensorbored/compat/proto/cpp_shape_inference_pb2.py +70 -0
  89. tensorbored/compat/proto/debug_pb2.py +65 -0
  90. tensorbored/compat/proto/event_pb2.py +149 -0
  91. tensorbored/compat/proto/full_type_pb2.py +74 -0
  92. tensorbored/compat/proto/function_pb2.py +157 -0
  93. tensorbored/compat/proto/graph_debug_info_pb2.py +111 -0
  94. tensorbored/compat/proto/graph_pb2.py +41 -0
  95. tensorbored/compat/proto/histogram_pb2.py +39 -0
  96. tensorbored/compat/proto/meta_graph_pb2.py +254 -0
  97. tensorbored/compat/proto/node_def_pb2.py +61 -0
  98. tensorbored/compat/proto/op_def_pb2.py +81 -0
  99. tensorbored/compat/proto/resource_handle_pb2.py +48 -0
  100. tensorbored/compat/proto/rewriter_config_pb2.py +93 -0
  101. tensorbored/compat/proto/rpc_options_pb2.py +35 -0
  102. tensorbored/compat/proto/saved_object_graph_pb2.py +193 -0
  103. tensorbored/compat/proto/saver_pb2.py +38 -0
  104. tensorbored/compat/proto/step_stats_pb2.py +116 -0
  105. tensorbored/compat/proto/struct_pb2.py +144 -0
  106. tensorbored/compat/proto/summary_pb2.py +111 -0
  107. tensorbored/compat/proto/tensor_description_pb2.py +38 -0
  108. tensorbored/compat/proto/tensor_pb2.py +68 -0
  109. tensorbored/compat/proto/tensor_shape_pb2.py +46 -0
  110. tensorbored/compat/proto/tfprof_log_pb2.py +307 -0
  111. tensorbored/compat/proto/trackable_object_graph_pb2.py +90 -0
  112. tensorbored/compat/proto/types_pb2.py +105 -0
  113. tensorbored/compat/proto/variable_pb2.py +62 -0
  114. tensorbored/compat/proto/verifier_config_pb2.py +38 -0
  115. tensorbored/compat/proto/versions_pb2.py +35 -0
  116. tensorbored/compat/tensorflow_stub/__init__.py +38 -0
  117. tensorbored/compat/tensorflow_stub/app.py +124 -0
  118. tensorbored/compat/tensorflow_stub/compat/__init__.py +131 -0
  119. tensorbored/compat/tensorflow_stub/compat/v1/__init__.py +20 -0
  120. tensorbored/compat/tensorflow_stub/dtypes.py +692 -0
  121. tensorbored/compat/tensorflow_stub/error_codes.py +169 -0
  122. tensorbored/compat/tensorflow_stub/errors.py +507 -0
  123. tensorbored/compat/tensorflow_stub/flags.py +124 -0
  124. tensorbored/compat/tensorflow_stub/io/__init__.py +17 -0
  125. tensorbored/compat/tensorflow_stub/io/gfile.py +1011 -0
  126. tensorbored/compat/tensorflow_stub/pywrap_tensorflow.py +285 -0
  127. tensorbored/compat/tensorflow_stub/tensor_shape.py +1035 -0
  128. tensorbored/context.py +129 -0
  129. tensorbored/data/__init__.py +0 -0
  130. tensorbored/data/grpc_provider.py +365 -0
  131. tensorbored/data/ingester.py +46 -0
  132. tensorbored/data/proto/__init__.py +0 -0
  133. tensorbored/data/proto/data_provider_pb2.py +517 -0
  134. tensorbored/data/proto/data_provider_pb2_grpc.py +374 -0
  135. tensorbored/data/provider.py +1365 -0
  136. tensorbored/data/server_ingester.py +301 -0
  137. tensorbored/data_compat.py +159 -0
  138. tensorbored/dataclass_compat.py +224 -0
  139. tensorbored/default.py +124 -0
  140. tensorbored/errors.py +130 -0
  141. tensorbored/lazy.py +99 -0
  142. tensorbored/main.py +48 -0
  143. tensorbored/main_lib.py +62 -0
  144. tensorbored/manager.py +487 -0
  145. tensorbored/notebook.py +441 -0
  146. tensorbored/plugin_util.py +266 -0
  147. tensorbored/plugins/__init__.py +0 -0
  148. tensorbored/plugins/audio/__init__.py +0 -0
  149. tensorbored/plugins/audio/audio_plugin.py +229 -0
  150. tensorbored/plugins/audio/metadata.py +69 -0
  151. tensorbored/plugins/audio/plugin_data_pb2.py +37 -0
  152. tensorbored/plugins/audio/summary.py +230 -0
  153. tensorbored/plugins/audio/summary_v2.py +124 -0
  154. tensorbored/plugins/base_plugin.py +367 -0
  155. tensorbored/plugins/core/__init__.py +0 -0
  156. tensorbored/plugins/core/core_plugin.py +981 -0
  157. tensorbored/plugins/custom_scalar/__init__.py +0 -0
  158. tensorbored/plugins/custom_scalar/custom_scalars_plugin.py +320 -0
  159. tensorbored/plugins/custom_scalar/layout_pb2.py +85 -0
  160. tensorbored/plugins/custom_scalar/metadata.py +35 -0
  161. tensorbored/plugins/custom_scalar/summary.py +79 -0
  162. tensorbored/plugins/debugger_v2/__init__.py +0 -0
  163. tensorbored/plugins/debugger_v2/debug_data_multiplexer.py +631 -0
  164. tensorbored/plugins/debugger_v2/debug_data_provider.py +634 -0
  165. tensorbored/plugins/debugger_v2/debugger_v2_plugin.py +504 -0
  166. tensorbored/plugins/distribution/__init__.py +0 -0
  167. tensorbored/plugins/distribution/compressor.py +158 -0
  168. tensorbored/plugins/distribution/distributions_plugin.py +116 -0
  169. tensorbored/plugins/distribution/metadata.py +19 -0
  170. tensorbored/plugins/graph/__init__.py +0 -0
  171. tensorbored/plugins/graph/graph_util.py +129 -0
  172. tensorbored/plugins/graph/graphs_plugin.py +336 -0
  173. tensorbored/plugins/graph/keras_util.py +328 -0
  174. tensorbored/plugins/graph/metadata.py +42 -0
  175. tensorbored/plugins/histogram/__init__.py +0 -0
  176. tensorbored/plugins/histogram/histograms_plugin.py +144 -0
  177. tensorbored/plugins/histogram/metadata.py +63 -0
  178. tensorbored/plugins/histogram/plugin_data_pb2.py +34 -0
  179. tensorbored/plugins/histogram/summary.py +234 -0
  180. tensorbored/plugins/histogram/summary_v2.py +292 -0
  181. tensorbored/plugins/hparams/__init__.py +14 -0
  182. tensorbored/plugins/hparams/_keras.py +93 -0
  183. tensorbored/plugins/hparams/api.py +130 -0
  184. tensorbored/plugins/hparams/api_pb2.py +208 -0
  185. tensorbored/plugins/hparams/backend_context.py +606 -0
  186. tensorbored/plugins/hparams/download_data.py +158 -0
  187. tensorbored/plugins/hparams/error.py +26 -0
  188. tensorbored/plugins/hparams/get_experiment.py +71 -0
  189. tensorbored/plugins/hparams/hparams_plugin.py +206 -0
  190. tensorbored/plugins/hparams/hparams_util_pb2.py +69 -0
  191. tensorbored/plugins/hparams/json_format_compat.py +38 -0
  192. tensorbored/plugins/hparams/list_metric_evals.py +57 -0
  193. tensorbored/plugins/hparams/list_session_groups.py +1040 -0
  194. tensorbored/plugins/hparams/metadata.py +125 -0
  195. tensorbored/plugins/hparams/metrics.py +41 -0
  196. tensorbored/plugins/hparams/plugin_data_pb2.py +69 -0
  197. tensorbored/plugins/hparams/summary.py +205 -0
  198. tensorbored/plugins/hparams/summary_v2.py +597 -0
  199. tensorbored/plugins/image/__init__.py +0 -0
  200. tensorbored/plugins/image/images_plugin.py +232 -0
  201. tensorbored/plugins/image/metadata.py +65 -0
  202. tensorbored/plugins/image/plugin_data_pb2.py +34 -0
  203. tensorbored/plugins/image/summary.py +159 -0
  204. tensorbored/plugins/image/summary_v2.py +130 -0
  205. tensorbored/plugins/mesh/__init__.py +14 -0
  206. tensorbored/plugins/mesh/mesh_plugin.py +292 -0
  207. tensorbored/plugins/mesh/metadata.py +152 -0
  208. tensorbored/plugins/mesh/plugin_data_pb2.py +37 -0
  209. tensorbored/plugins/mesh/summary.py +251 -0
  210. tensorbored/plugins/mesh/summary_v2.py +214 -0
  211. tensorbored/plugins/metrics/__init__.py +0 -0
  212. tensorbored/plugins/metrics/metadata.py +17 -0
  213. tensorbored/plugins/metrics/metrics_plugin.py +623 -0
  214. tensorbored/plugins/pr_curve/__init__.py +0 -0
  215. tensorbored/plugins/pr_curve/metadata.py +75 -0
  216. tensorbored/plugins/pr_curve/plugin_data_pb2.py +34 -0
  217. tensorbored/plugins/pr_curve/pr_curves_plugin.py +241 -0
  218. tensorbored/plugins/pr_curve/summary.py +574 -0
  219. tensorbored/plugins/profile_redirect/__init__.py +0 -0
  220. tensorbored/plugins/profile_redirect/profile_redirect_plugin.py +49 -0
  221. tensorbored/plugins/projector/__init__.py +67 -0
  222. tensorbored/plugins/projector/metadata.py +26 -0
  223. tensorbored/plugins/projector/projector_config_pb2.py +54 -0
  224. tensorbored/plugins/projector/projector_plugin.py +795 -0
  225. tensorbored/plugins/projector/tf_projector_plugin/index.js +32 -0
  226. tensorbored/plugins/projector/tf_projector_plugin/projector_binary.html +524 -0
  227. tensorbored/plugins/projector/tf_projector_plugin/projector_binary.js +15536 -0
  228. tensorbored/plugins/scalar/__init__.py +0 -0
  229. tensorbored/plugins/scalar/metadata.py +60 -0
  230. tensorbored/plugins/scalar/plugin_data_pb2.py +34 -0
  231. tensorbored/plugins/scalar/scalars_plugin.py +181 -0
  232. tensorbored/plugins/scalar/summary.py +109 -0
  233. tensorbored/plugins/scalar/summary_v2.py +124 -0
  234. tensorbored/plugins/text/__init__.py +0 -0
  235. tensorbored/plugins/text/metadata.py +62 -0
  236. tensorbored/plugins/text/plugin_data_pb2.py +34 -0
  237. tensorbored/plugins/text/summary.py +114 -0
  238. tensorbored/plugins/text/summary_v2.py +124 -0
  239. tensorbored/plugins/text/text_plugin.py +288 -0
  240. tensorbored/plugins/wit_redirect/__init__.py +0 -0
  241. tensorbored/plugins/wit_redirect/wit_redirect_plugin.py +49 -0
  242. tensorbored/program.py +910 -0
  243. tensorbored/summary/__init__.py +35 -0
  244. tensorbored/summary/_output.py +124 -0
  245. tensorbored/summary/_tf/__init__.py +14 -0
  246. tensorbored/summary/_tf/summary/__init__.py +178 -0
  247. tensorbored/summary/_writer.py +105 -0
  248. tensorbored/summary/v1.py +51 -0
  249. tensorbored/summary/v2.py +25 -0
  250. tensorbored/summary/writer/__init__.py +13 -0
  251. tensorbored/summary/writer/event_file_writer.py +291 -0
  252. tensorbored/summary/writer/record_writer.py +50 -0
  253. tensorbored/util/__init__.py +0 -0
  254. tensorbored/util/encoder.py +116 -0
  255. tensorbored/util/grpc_util.py +311 -0
  256. tensorbored/util/img_mime_type_detector.py +40 -0
  257. tensorbored/util/io_util.py +20 -0
  258. tensorbored/util/lazy_tensor_creator.py +110 -0
  259. tensorbored/util/op_evaluator.py +104 -0
  260. tensorbored/util/platform_util.py +20 -0
  261. tensorbored/util/tb_logging.py +24 -0
  262. tensorbored/util/tensor_util.py +617 -0
  263. tensorbored/util/timing.py +122 -0
  264. tensorbored/version.py +21 -0
  265. tensorbored/webfiles.zip +0 -0
  266. tensorbored-2.21.0rc1769983804.dist-info/METADATA +49 -0
  267. tensorbored-2.21.0rc1769983804.dist-info/RECORD +271 -0
  268. tensorbored-2.21.0rc1769983804.dist-info/WHEEL +5 -0
  269. tensorbored-2.21.0rc1769983804.dist-info/entry_points.txt +6 -0
  270. tensorbored-2.21.0rc1769983804.dist-info/licenses/LICENSE +739 -0
  271. tensorbored-2.21.0rc1769983804.dist-info/top_level.txt +1 -0
@@ -0,0 +1,392 @@
1
+ """Module for supporting the lxml.etree library. The idea here is to use as much
2
+ of the native library as possible, without using fragile hacks like custom element
3
+ names that break between releases. The downside of this is that we cannot represent
4
+ all possible trees; specifically the following are known to cause problems:
5
+
6
+ Text or comments as siblings of the root element
7
+ Docypes with no name
8
+
9
+ When any of these things occur, we emit a DataLossWarning
10
+ """
11
+
12
+ from __future__ import absolute_import, division, unicode_literals
13
+ # pylint:disable=protected-access
14
+
15
+ import warnings
16
+ import re
17
+ import sys
18
+
19
+ try:
20
+ from collections.abc import MutableMapping
21
+ except ImportError:
22
+ from collections import MutableMapping
23
+
24
+ from . import base
25
+ from ..constants import DataLossWarning
26
+ from .. import constants
27
+ from . import etree as etree_builders
28
+ from .. import _ihatexml
29
+
30
+ import lxml.etree as etree
31
+ from tensorbored._vendor.bleach.six_shim import PY3, binary_type
32
+
33
+
34
+ fullTree = True
35
+ tag_regexp = re.compile("{([^}]*)}(.*)")
36
+
37
+ comment_type = etree.Comment("asd").tag
38
+
39
+
40
+ class DocumentType(object):
41
+ def __init__(self, name, publicId, systemId):
42
+ self.name = name
43
+ self.publicId = publicId
44
+ self.systemId = systemId
45
+
46
+
47
+ class Document(object):
48
+ def __init__(self):
49
+ self._elementTree = None
50
+ self._childNodes = []
51
+
52
+ def appendChild(self, element):
53
+ last = self._elementTree.getroot()
54
+ for last in self._elementTree.getroot().itersiblings():
55
+ pass
56
+
57
+ last.addnext(element._element)
58
+
59
+ def _getChildNodes(self):
60
+ return self._childNodes
61
+
62
+ childNodes = property(_getChildNodes)
63
+
64
+
65
+ def testSerializer(element):
66
+ rv = []
67
+ infosetFilter = _ihatexml.InfosetFilter(preventDoubleDashComments=True)
68
+
69
+ def serializeElement(element, indent=0):
70
+ if not hasattr(element, "tag"):
71
+ if hasattr(element, "getroot"):
72
+ # Full tree case
73
+ rv.append("#document")
74
+ if element.docinfo.internalDTD:
75
+ if not (element.docinfo.public_id or
76
+ element.docinfo.system_url):
77
+ dtd_str = "<!DOCTYPE %s>" % element.docinfo.root_name
78
+ else:
79
+ dtd_str = """<!DOCTYPE %s "%s" "%s">""" % (
80
+ element.docinfo.root_name,
81
+ element.docinfo.public_id,
82
+ element.docinfo.system_url)
83
+ rv.append("|%s%s" % (' ' * (indent + 2), dtd_str))
84
+ next_element = element.getroot()
85
+ while next_element.getprevious() is not None:
86
+ next_element = next_element.getprevious()
87
+ while next_element is not None:
88
+ serializeElement(next_element, indent + 2)
89
+ next_element = next_element.getnext()
90
+ elif isinstance(element, str) or isinstance(element, bytes):
91
+ # Text in a fragment
92
+ assert isinstance(element, str) or sys.version_info[0] == 2
93
+ rv.append("|%s\"%s\"" % (' ' * indent, element))
94
+ else:
95
+ # Fragment case
96
+ rv.append("#document-fragment")
97
+ for next_element in element:
98
+ serializeElement(next_element, indent + 2)
99
+ elif element.tag == comment_type:
100
+ rv.append("|%s<!-- %s -->" % (' ' * indent, element.text))
101
+ if hasattr(element, "tail") and element.tail:
102
+ rv.append("|%s\"%s\"" % (' ' * indent, element.tail))
103
+ else:
104
+ assert isinstance(element, etree._Element)
105
+ nsmatch = etree_builders.tag_regexp.match(element.tag)
106
+ if nsmatch is not None:
107
+ ns = nsmatch.group(1)
108
+ tag = nsmatch.group(2)
109
+ prefix = constants.prefixes[ns]
110
+ rv.append("|%s<%s %s>" % (' ' * indent, prefix,
111
+ infosetFilter.fromXmlName(tag)))
112
+ else:
113
+ rv.append("|%s<%s>" % (' ' * indent,
114
+ infosetFilter.fromXmlName(element.tag)))
115
+
116
+ if hasattr(element, "attrib"):
117
+ attributes = []
118
+ for name, value in element.attrib.items():
119
+ nsmatch = tag_regexp.match(name)
120
+ if nsmatch is not None:
121
+ ns, name = nsmatch.groups()
122
+ name = infosetFilter.fromXmlName(name)
123
+ prefix = constants.prefixes[ns]
124
+ attr_string = "%s %s" % (prefix, name)
125
+ else:
126
+ attr_string = infosetFilter.fromXmlName(name)
127
+ attributes.append((attr_string, value))
128
+
129
+ for name, value in sorted(attributes):
130
+ rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value))
131
+
132
+ if element.text:
133
+ rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text))
134
+ indent += 2
135
+ for child in element:
136
+ serializeElement(child, indent)
137
+ if hasattr(element, "tail") and element.tail:
138
+ rv.append("|%s\"%s\"" % (' ' * (indent - 2), element.tail))
139
+ serializeElement(element, 0)
140
+
141
+ return "\n".join(rv)
142
+
143
+
144
+ def tostring(element):
145
+ """Serialize an element and its child nodes to a string"""
146
+ rv = []
147
+
148
+ def serializeElement(element):
149
+ if not hasattr(element, "tag"):
150
+ if element.docinfo.internalDTD:
151
+ if element.docinfo.doctype:
152
+ dtd_str = element.docinfo.doctype
153
+ else:
154
+ dtd_str = "<!DOCTYPE %s>" % element.docinfo.root_name
155
+ rv.append(dtd_str)
156
+ serializeElement(element.getroot())
157
+
158
+ elif element.tag == comment_type:
159
+ rv.append("<!--%s-->" % (element.text,))
160
+
161
+ else:
162
+ # This is assumed to be an ordinary element
163
+ if not element.attrib:
164
+ rv.append("<%s>" % (element.tag,))
165
+ else:
166
+ attr = " ".join(["%s=\"%s\"" % (name, value)
167
+ for name, value in element.attrib.items()])
168
+ rv.append("<%s %s>" % (element.tag, attr))
169
+ if element.text:
170
+ rv.append(element.text)
171
+
172
+ for child in element:
173
+ serializeElement(child)
174
+
175
+ rv.append("</%s>" % (element.tag,))
176
+
177
+ if hasattr(element, "tail") and element.tail:
178
+ rv.append(element.tail)
179
+
180
+ serializeElement(element)
181
+
182
+ return "".join(rv)
183
+
184
+
185
+ class TreeBuilder(base.TreeBuilder):
186
+ documentClass = Document
187
+ doctypeClass = DocumentType
188
+ elementClass = None
189
+ commentClass = None
190
+ fragmentClass = Document
191
+ implementation = etree
192
+
193
+ def __init__(self, namespaceHTMLElements, fullTree=False):
194
+ builder = etree_builders.getETreeModule(etree, fullTree=fullTree)
195
+ infosetFilter = self.infosetFilter = _ihatexml.InfosetFilter(preventDoubleDashComments=True)
196
+ self.namespaceHTMLElements = namespaceHTMLElements
197
+
198
+ class Attributes(MutableMapping):
199
+ def __init__(self, element):
200
+ self._element = element
201
+
202
+ def _coerceKey(self, key):
203
+ if isinstance(key, tuple):
204
+ name = "{%s}%s" % (key[2], infosetFilter.coerceAttribute(key[1]))
205
+ else:
206
+ name = infosetFilter.coerceAttribute(key)
207
+ return name
208
+
209
+ def __getitem__(self, key):
210
+ value = self._element._element.attrib[self._coerceKey(key)]
211
+ if not PY3 and isinstance(value, binary_type):
212
+ value = value.decode("ascii")
213
+ return value
214
+
215
+ def __setitem__(self, key, value):
216
+ self._element._element.attrib[self._coerceKey(key)] = value
217
+
218
+ def __delitem__(self, key):
219
+ del self._element._element.attrib[self._coerceKey(key)]
220
+
221
+ def __iter__(self):
222
+ return iter(self._element._element.attrib)
223
+
224
+ def __len__(self):
225
+ return len(self._element._element.attrib)
226
+
227
+ def clear(self):
228
+ return self._element._element.attrib.clear()
229
+
230
+ class Element(builder.Element):
231
+ def __init__(self, name, namespace):
232
+ name = infosetFilter.coerceElement(name)
233
+ builder.Element.__init__(self, name, namespace=namespace)
234
+ self._attributes = Attributes(self)
235
+
236
+ def _setName(self, name):
237
+ self._name = infosetFilter.coerceElement(name)
238
+ self._element.tag = self._getETreeTag(
239
+ self._name, self._namespace)
240
+
241
+ def _getName(self):
242
+ return infosetFilter.fromXmlName(self._name)
243
+
244
+ name = property(_getName, _setName)
245
+
246
+ def _getAttributes(self):
247
+ return self._attributes
248
+
249
+ def _setAttributes(self, value):
250
+ attributes = self.attributes
251
+ attributes.clear()
252
+ attributes.update(value)
253
+
254
+ attributes = property(_getAttributes, _setAttributes)
255
+
256
+ def insertText(self, data, insertBefore=None):
257
+ data = infosetFilter.coerceCharacters(data)
258
+ builder.Element.insertText(self, data, insertBefore)
259
+
260
+ def cloneNode(self):
261
+ element = type(self)(self.name, self.namespace)
262
+ if self._element.attrib:
263
+ element._element.attrib.update(self._element.attrib)
264
+ return element
265
+
266
+ class Comment(builder.Comment):
267
+ def __init__(self, data):
268
+ data = infosetFilter.coerceComment(data)
269
+ builder.Comment.__init__(self, data)
270
+
271
+ def _setData(self, data):
272
+ data = infosetFilter.coerceComment(data)
273
+ self._element.text = data
274
+
275
+ def _getData(self):
276
+ return self._element.text
277
+
278
+ data = property(_getData, _setData)
279
+
280
+ self.elementClass = Element
281
+ self.commentClass = Comment
282
+ # self.fragmentClass = builder.DocumentFragment
283
+ base.TreeBuilder.__init__(self, namespaceHTMLElements)
284
+
285
+ def reset(self):
286
+ base.TreeBuilder.reset(self)
287
+ self.insertComment = self.insertCommentInitial
288
+ self.initial_comments = []
289
+ self.doctype = None
290
+
291
+ def testSerializer(self, element):
292
+ return testSerializer(element)
293
+
294
+ def getDocument(self):
295
+ if fullTree:
296
+ return self.document._elementTree
297
+ else:
298
+ return self.document._elementTree.getroot()
299
+
300
+ def getFragment(self):
301
+ fragment = []
302
+ element = self.openElements[0]._element
303
+ if element.text:
304
+ fragment.append(element.text)
305
+ fragment.extend(list(element))
306
+ if element.tail:
307
+ fragment.append(element.tail)
308
+ return fragment
309
+
310
+ def insertDoctype(self, token):
311
+ name = token["name"]
312
+ publicId = token["publicId"]
313
+ systemId = token["systemId"]
314
+
315
+ if not name:
316
+ warnings.warn("lxml cannot represent empty doctype", DataLossWarning)
317
+ self.doctype = None
318
+ else:
319
+ coercedName = self.infosetFilter.coerceElement(name)
320
+ if coercedName != name:
321
+ warnings.warn("lxml cannot represent non-xml doctype", DataLossWarning)
322
+
323
+ doctype = self.doctypeClass(coercedName, publicId, systemId)
324
+ self.doctype = doctype
325
+
326
+ def insertCommentInitial(self, data, parent=None):
327
+ assert parent is None or parent is self.document
328
+ assert self.document._elementTree is None
329
+ self.initial_comments.append(data)
330
+
331
+ def insertCommentMain(self, data, parent=None):
332
+ if (parent == self.document and
333
+ self.document._elementTree.getroot()[-1].tag == comment_type):
334
+ warnings.warn("lxml cannot represent adjacent comments beyond the root elements", DataLossWarning)
335
+ super(TreeBuilder, self).insertComment(data, parent)
336
+
337
+ def insertRoot(self, token):
338
+ # Because of the way libxml2 works, it doesn't seem to be possible to
339
+ # alter information like the doctype after the tree has been parsed.
340
+ # Therefore we need to use the built-in parser to create our initial
341
+ # tree, after which we can add elements like normal
342
+ docStr = ""
343
+ if self.doctype:
344
+ assert self.doctype.name
345
+ docStr += "<!DOCTYPE %s" % self.doctype.name
346
+ if (self.doctype.publicId is not None or
347
+ self.doctype.systemId is not None):
348
+ docStr += (' PUBLIC "%s" ' %
349
+ (self.infosetFilter.coercePubid(self.doctype.publicId or "")))
350
+ if self.doctype.systemId:
351
+ sysid = self.doctype.systemId
352
+ if sysid.find("'") >= 0 and sysid.find('"') >= 0:
353
+ warnings.warn("DOCTYPE system cannot contain single and double quotes", DataLossWarning)
354
+ sysid = sysid.replace("'", 'U00027')
355
+ if sysid.find("'") >= 0:
356
+ docStr += '"%s"' % sysid
357
+ else:
358
+ docStr += "'%s'" % sysid
359
+ else:
360
+ docStr += "''"
361
+ docStr += ">"
362
+ if self.doctype.name != token["name"]:
363
+ warnings.warn("lxml cannot represent doctype with a different name to the root element", DataLossWarning)
364
+ docStr += "<THIS_SHOULD_NEVER_APPEAR_PUBLICLY/>"
365
+ root = etree.fromstring(docStr)
366
+
367
+ # Append the initial comments:
368
+ for comment_token in self.initial_comments:
369
+ comment = self.commentClass(comment_token["data"])
370
+ root.addprevious(comment._element)
371
+
372
+ # Create the root document and add the ElementTree to it
373
+ self.document = self.documentClass()
374
+ self.document._elementTree = root.getroottree()
375
+
376
+ # Give the root element the right name
377
+ name = token["name"]
378
+ namespace = token.get("namespace", self.defaultNamespace)
379
+ if namespace is None:
380
+ etree_tag = name
381
+ else:
382
+ etree_tag = "{%s}%s" % (namespace, name)
383
+ root.tag = etree_tag
384
+
385
+ # Add the root element to the internal child/open data structures
386
+ root_element = self.elementClass(name, namespace)
387
+ root_element._element = root
388
+ self.document._childNodes.append(root_element)
389
+ self.openElements.append(root_element)
390
+
391
+ # Reset to the default insert comment function
392
+ self.insertComment = self.insertCommentMain
@@ -0,0 +1,154 @@
1
+ """A collection of modules for iterating through different kinds of
2
+ tree, generating tokens identical to those produced by the tokenizer
3
+ module.
4
+
5
+ To create a tree walker for a new type of tree, you need to
6
+ implement a tree walker object (called TreeWalker by convention) that
7
+ implements a 'serialize' method which takes a tree as sole argument and
8
+ returns an iterator which generates tokens.
9
+ """
10
+
11
+ from __future__ import absolute_import, division, unicode_literals
12
+
13
+ from .. import constants
14
+ from .._utils import default_etree
15
+
16
+ __all__ = ["getTreeWalker", "pprint"]
17
+
18
+ treeWalkerCache = {}
19
+
20
+
21
+ def getTreeWalker(treeType, implementation=None, **kwargs):
22
+ """Get a TreeWalker class for various types of tree with built-in support
23
+
24
+ :arg str treeType: the name of the tree type required (case-insensitive).
25
+ Supported values are:
26
+
27
+ * "dom": The xml.dom.minidom DOM implementation
28
+ * "etree": A generic walker for tree implementations exposing an
29
+ elementtree-like interface (known to work with ElementTree,
30
+ cElementTree and lxml.etree).
31
+ * "lxml": Optimized walker for lxml.etree
32
+ * "genshi": a Genshi stream
33
+
34
+ :arg implementation: A module implementing the tree type e.g.
35
+ xml.etree.ElementTree or cElementTree (Currently applies to the "etree"
36
+ tree type only).
37
+
38
+ :arg kwargs: keyword arguments passed to the etree walker--for other
39
+ walkers, this has no effect
40
+
41
+ :returns: a TreeWalker class
42
+
43
+ """
44
+
45
+ treeType = treeType.lower()
46
+ if treeType not in treeWalkerCache:
47
+ if treeType == "dom":
48
+ from . import dom
49
+ treeWalkerCache[treeType] = dom.TreeWalker
50
+ elif treeType == "genshi":
51
+ from . import genshi
52
+ treeWalkerCache[treeType] = genshi.TreeWalker
53
+ elif treeType == "lxml":
54
+ from . import etree_lxml
55
+ treeWalkerCache[treeType] = etree_lxml.TreeWalker
56
+ elif treeType == "etree":
57
+ from . import etree
58
+ if implementation is None:
59
+ implementation = default_etree
60
+ # XXX: NEVER cache here, caching is done in the etree submodule
61
+ return etree.getETreeModule(implementation, **kwargs).TreeWalker
62
+ return treeWalkerCache.get(treeType)
63
+
64
+
65
+ def concatenateCharacterTokens(tokens):
66
+ pendingCharacters = []
67
+ for token in tokens:
68
+ type = token["type"]
69
+ if type in ("Characters", "SpaceCharacters"):
70
+ pendingCharacters.append(token["data"])
71
+ else:
72
+ if pendingCharacters:
73
+ yield {"type": "Characters", "data": "".join(pendingCharacters)}
74
+ pendingCharacters = []
75
+ yield token
76
+ if pendingCharacters:
77
+ yield {"type": "Characters", "data": "".join(pendingCharacters)}
78
+
79
+
80
+ def pprint(walker):
81
+ """Pretty printer for tree walkers
82
+
83
+ Takes a TreeWalker instance and pretty prints the output of walking the tree.
84
+
85
+ :arg walker: a TreeWalker instance
86
+
87
+ """
88
+ output = []
89
+ indent = 0
90
+ for token in concatenateCharacterTokens(walker):
91
+ type = token["type"]
92
+ if type in ("StartTag", "EmptyTag"):
93
+ # tag name
94
+ if token["namespace"] and token["namespace"] != constants.namespaces["html"]:
95
+ if token["namespace"] in constants.prefixes:
96
+ ns = constants.prefixes[token["namespace"]]
97
+ else:
98
+ ns = token["namespace"]
99
+ name = "%s %s" % (ns, token["name"])
100
+ else:
101
+ name = token["name"]
102
+ output.append("%s<%s>" % (" " * indent, name))
103
+ indent += 2
104
+ # attributes (sorted for consistent ordering)
105
+ attrs = token["data"]
106
+ for (namespace, localname), value in sorted(attrs.items()):
107
+ if namespace:
108
+ if namespace in constants.prefixes:
109
+ ns = constants.prefixes[namespace]
110
+ else:
111
+ ns = namespace
112
+ name = "%s %s" % (ns, localname)
113
+ else:
114
+ name = localname
115
+ output.append("%s%s=\"%s\"" % (" " * indent, name, value))
116
+ # self-closing
117
+ if type == "EmptyTag":
118
+ indent -= 2
119
+
120
+ elif type == "EndTag":
121
+ indent -= 2
122
+
123
+ elif type == "Comment":
124
+ output.append("%s<!-- %s -->" % (" " * indent, token["data"]))
125
+
126
+ elif type == "Doctype":
127
+ if token["name"]:
128
+ if token["publicId"]:
129
+ output.append("""%s<!DOCTYPE %s "%s" "%s">""" %
130
+ (" " * indent,
131
+ token["name"],
132
+ token["publicId"],
133
+ token["systemId"] if token["systemId"] else ""))
134
+ elif token["systemId"]:
135
+ output.append("""%s<!DOCTYPE %s "" "%s">""" %
136
+ (" " * indent,
137
+ token["name"],
138
+ token["systemId"]))
139
+ else:
140
+ output.append("%s<!DOCTYPE %s>" % (" " * indent,
141
+ token["name"]))
142
+ else:
143
+ output.append("%s<!DOCTYPE >" % (" " * indent,))
144
+
145
+ elif type == "Characters":
146
+ output.append("%s\"%s\"" % (" " * indent, token["data"]))
147
+
148
+ elif type == "SpaceCharacters":
149
+ assert False, "concatenateCharacterTokens should have got rid of all Space tokens"
150
+
151
+ else:
152
+ raise ValueError("Unknown token type, %s" % type)
153
+
154
+ return "\n".join(output)