okstra 0.108.0 → 0.109.0

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 (642) hide show
  1. package/package.json +1 -1
  2. package/runtime/BUILD.json +2 -2
  3. package/runtime/prompts/profiles/_common-contract.md +1 -1
  4. package/runtime/python/okstra_ctl/graphify_cmd.py +225 -0
  5. package/runtime/python/okstra_ctl/resolve_task_key.py +15 -9
  6. package/runtime/python/okstra_project/__init__.py +2 -0
  7. package/runtime/python/okstra_project/state.py +36 -0
  8. package/runtime/python/okstra_vendor/__init__.py +41 -0
  9. package/runtime/python/okstra_vendor/graphify/.vendored-version +1 -0
  10. package/runtime/python/okstra_vendor/graphify/__init__.py +28 -0
  11. package/runtime/python/okstra_vendor/graphify/__main__.py +1371 -0
  12. package/runtime/python/okstra_vendor/graphify/analyze.py +540 -0
  13. package/runtime/python/okstra_vendor/graphify/benchmark.py +129 -0
  14. package/runtime/python/okstra_vendor/graphify/build.py +107 -0
  15. package/runtime/python/okstra_vendor/graphify/cache.py +169 -0
  16. package/runtime/python/okstra_vendor/graphify/cluster.py +137 -0
  17. package/runtime/python/okstra_vendor/graphify/detect.py +510 -0
  18. package/runtime/python/okstra_vendor/graphify/export.py +1014 -0
  19. package/runtime/python/okstra_vendor/graphify/extract.py +3277 -0
  20. package/runtime/python/okstra_vendor/graphify/hooks.py +220 -0
  21. package/runtime/python/okstra_vendor/graphify/ingest.py +297 -0
  22. package/runtime/python/okstra_vendor/graphify/manifest.py +4 -0
  23. package/runtime/python/okstra_vendor/graphify/report.py +175 -0
  24. package/runtime/python/okstra_vendor/graphify/security.py +203 -0
  25. package/runtime/python/okstra_vendor/graphify/serve.py +373 -0
  26. package/runtime/python/okstra_vendor/graphify/skill-aider.md +1184 -0
  27. package/runtime/python/okstra_vendor/graphify/skill-claw.md +1184 -0
  28. package/runtime/python/okstra_vendor/graphify/skill-codex.md +1242 -0
  29. package/runtime/python/okstra_vendor/graphify/skill-copilot.md +1268 -0
  30. package/runtime/python/okstra_vendor/graphify/skill-droid.md +1239 -0
  31. package/runtime/python/okstra_vendor/graphify/skill-kiro.md +1183 -0
  32. package/runtime/python/okstra_vendor/graphify/skill-opencode.md +1238 -0
  33. package/runtime/python/okstra_vendor/graphify/skill-trae.md +1208 -0
  34. package/runtime/python/okstra_vendor/graphify/skill-vscode.md +253 -0
  35. package/runtime/python/okstra_vendor/graphify/skill-windows.md +1245 -0
  36. package/runtime/python/okstra_vendor/graphify/skill.md +1319 -0
  37. package/runtime/python/okstra_vendor/graphify/transcribe.py +182 -0
  38. package/runtime/python/okstra_vendor/graphify/validate.py +72 -0
  39. package/runtime/python/okstra_vendor/graphify/watch.py +188 -0
  40. package/runtime/python/okstra_vendor/graphify/wiki.py +214 -0
  41. package/runtime/python/okstra_vendor/networkx/__init__.py +62 -0
  42. package/runtime/python/okstra_vendor/networkx/algorithms/__init__.py +134 -0
  43. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/__init__.py +26 -0
  44. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/clique.py +259 -0
  45. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/clustering_coefficient.py +71 -0
  46. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/connectivity.py +412 -0
  47. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/density.py +396 -0
  48. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/distance_measures.py +150 -0
  49. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/dominating_set.py +149 -0
  50. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/kcomponents.py +369 -0
  51. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/matching.py +44 -0
  52. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/maxcut.py +143 -0
  53. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/ramsey.py +53 -0
  54. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/steinertree.py +265 -0
  55. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/__init__.py +0 -0
  56. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_approx_clust_coeff.py +41 -0
  57. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_clique.py +112 -0
  58. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_connectivity.py +199 -0
  59. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_density.py +146 -0
  60. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_distance_measures.py +59 -0
  61. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_dominating_set.py +78 -0
  62. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_kcomponents.py +303 -0
  63. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_matching.py +8 -0
  64. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_maxcut.py +94 -0
  65. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_ramsey.py +31 -0
  66. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_steinertree.py +306 -0
  67. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_traveling_salesman.py +1014 -0
  68. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_treewidth.py +274 -0
  69. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_vertex_cover.py +68 -0
  70. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/traveling_salesman.py +1508 -0
  71. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/treewidth.py +255 -0
  72. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/vertex_cover.py +83 -0
  73. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/__init__.py +5 -0
  74. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/connectivity.py +122 -0
  75. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/correlation.py +302 -0
  76. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/mixing.py +255 -0
  77. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/neighbor_degree.py +160 -0
  78. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/pairs.py +127 -0
  79. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/__init__.py +0 -0
  80. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/base_test.py +81 -0
  81. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/test_connectivity.py +143 -0
  82. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/test_correlation.py +122 -0
  83. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/test_mixing.py +174 -0
  84. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/test_neighbor_degree.py +107 -0
  85. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/test_pairs.py +87 -0
  86. package/runtime/python/okstra_vendor/networkx/algorithms/asteroidal.py +164 -0
  87. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/__init__.py +88 -0
  88. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/basic.py +322 -0
  89. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/centrality.py +290 -0
  90. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/cluster.py +289 -0
  91. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/covering.py +57 -0
  92. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/edgelist.py +360 -0
  93. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/extendability.py +105 -0
  94. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/generators.py +603 -0
  95. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/link_analysis.py +316 -0
  96. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/matching.py +590 -0
  97. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/matrix.py +232 -0
  98. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/projection.py +526 -0
  99. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/redundancy.py +112 -0
  100. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/spectral.py +69 -0
  101. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/__init__.py +0 -0
  102. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_basic.py +125 -0
  103. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_centrality.py +192 -0
  104. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_cluster.py +84 -0
  105. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_covering.py +33 -0
  106. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_edgelist.py +240 -0
  107. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_extendability.py +334 -0
  108. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_generators.py +407 -0
  109. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_link_analysis.py +218 -0
  110. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_matching.py +327 -0
  111. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_matrix.py +138 -0
  112. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_project.py +409 -0
  113. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_redundancy.py +35 -0
  114. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_spectral_bipartivity.py +80 -0
  115. package/runtime/python/okstra_vendor/networkx/algorithms/boundary.py +168 -0
  116. package/runtime/python/okstra_vendor/networkx/algorithms/bridges.py +205 -0
  117. package/runtime/python/okstra_vendor/networkx/algorithms/broadcasting.py +164 -0
  118. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/__init__.py +20 -0
  119. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/betweenness.py +591 -0
  120. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/betweenness_subset.py +236 -0
  121. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/closeness.py +282 -0
  122. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/current_flow_betweenness.py +364 -0
  123. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/current_flow_betweenness_subset.py +227 -0
  124. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/current_flow_closeness.py +96 -0
  125. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/degree_alg.py +150 -0
  126. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/dispersion.py +107 -0
  127. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/eigenvector.py +357 -0
  128. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/flow_matrix.py +130 -0
  129. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/group.py +787 -0
  130. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/harmonic.py +88 -0
  131. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/katz.py +331 -0
  132. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/laplacian.py +150 -0
  133. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/load.py +200 -0
  134. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/percolation.py +128 -0
  135. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/reaching.py +209 -0
  136. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/second_order.py +141 -0
  137. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/subgraph_alg.py +361 -0
  138. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/__init__.py +0 -0
  139. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_betweenness_centrality.py +923 -0
  140. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_betweenness_centrality_subset.py +354 -0
  141. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_closeness_centrality.py +274 -0
  142. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_current_flow_betweenness_centrality.py +259 -0
  143. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_current_flow_betweenness_centrality_subset.py +147 -0
  144. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_current_flow_closeness.py +43 -0
  145. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_degree_centrality.py +144 -0
  146. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_dispersion.py +73 -0
  147. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_eigenvector_centrality.py +186 -0
  148. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_group.py +277 -0
  149. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_harmonic_centrality.py +122 -0
  150. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_katz_centrality.py +345 -0
  151. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_laplacian_centrality.py +220 -0
  152. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_load_centrality.py +344 -0
  153. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_percolation_centrality.py +87 -0
  154. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_reaching.py +140 -0
  155. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_second_order_centrality.py +82 -0
  156. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_subgraph.py +110 -0
  157. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_trophic.py +302 -0
  158. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_voterank.py +64 -0
  159. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/trophic.py +181 -0
  160. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/voterank_alg.py +95 -0
  161. package/runtime/python/okstra_vendor/networkx/algorithms/chains.py +172 -0
  162. package/runtime/python/okstra_vendor/networkx/algorithms/chordal.py +443 -0
  163. package/runtime/python/okstra_vendor/networkx/algorithms/clique.py +818 -0
  164. package/runtime/python/okstra_vendor/networkx/algorithms/cluster.py +732 -0
  165. package/runtime/python/okstra_vendor/networkx/algorithms/coloring/__init__.py +4 -0
  166. package/runtime/python/okstra_vendor/networkx/algorithms/coloring/equitable_coloring.py +505 -0
  167. package/runtime/python/okstra_vendor/networkx/algorithms/coloring/greedy_coloring.py +565 -0
  168. package/runtime/python/okstra_vendor/networkx/algorithms/coloring/tests/__init__.py +0 -0
  169. package/runtime/python/okstra_vendor/networkx/algorithms/coloring/tests/test_coloring.py +863 -0
  170. package/runtime/python/okstra_vendor/networkx/algorithms/communicability_alg.py +163 -0
  171. package/runtime/python/okstra_vendor/networkx/algorithms/community/__init__.py +28 -0
  172. package/runtime/python/okstra_vendor/networkx/algorithms/community/asyn_fluid.py +153 -0
  173. package/runtime/python/okstra_vendor/networkx/algorithms/community/bipartitions.py +354 -0
  174. package/runtime/python/okstra_vendor/networkx/algorithms/community/centrality.py +171 -0
  175. package/runtime/python/okstra_vendor/networkx/algorithms/community/community_utils.py +30 -0
  176. package/runtime/python/okstra_vendor/networkx/algorithms/community/divisive.py +216 -0
  177. package/runtime/python/okstra_vendor/networkx/algorithms/community/kclique.py +79 -0
  178. package/runtime/python/okstra_vendor/networkx/algorithms/community/label_propagation.py +338 -0
  179. package/runtime/python/okstra_vendor/networkx/algorithms/community/leiden.py +162 -0
  180. package/runtime/python/okstra_vendor/networkx/algorithms/community/local.py +220 -0
  181. package/runtime/python/okstra_vendor/networkx/algorithms/community/louvain.py +384 -0
  182. package/runtime/python/okstra_vendor/networkx/algorithms/community/lukes.py +227 -0
  183. package/runtime/python/okstra_vendor/networkx/algorithms/community/modularity_max.py +452 -0
  184. package/runtime/python/okstra_vendor/networkx/algorithms/community/quality.py +347 -0
  185. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/__init__.py +0 -0
  186. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_asyn_fluid.py +147 -0
  187. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_bipartitions.py +157 -0
  188. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_centrality.py +85 -0
  189. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_divisive.py +106 -0
  190. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_kclique.py +91 -0
  191. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_label_propagation.py +241 -0
  192. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_leiden.py +138 -0
  193. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_local.py +76 -0
  194. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_louvain.py +264 -0
  195. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_lukes.py +152 -0
  196. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_modularity_max.py +340 -0
  197. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_quality.py +139 -0
  198. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_utils.py +26 -0
  199. package/runtime/python/okstra_vendor/networkx/algorithms/components/__init__.py +6 -0
  200. package/runtime/python/okstra_vendor/networkx/algorithms/components/attracting.py +115 -0
  201. package/runtime/python/okstra_vendor/networkx/algorithms/components/biconnected.py +394 -0
  202. package/runtime/python/okstra_vendor/networkx/algorithms/components/connected.py +282 -0
  203. package/runtime/python/okstra_vendor/networkx/algorithms/components/semiconnected.py +71 -0
  204. package/runtime/python/okstra_vendor/networkx/algorithms/components/strongly_connected.py +359 -0
  205. package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/__init__.py +0 -0
  206. package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_attracting.py +70 -0
  207. package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_biconnected.py +248 -0
  208. package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_connected.py +138 -0
  209. package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_semiconnected.py +55 -0
  210. package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_strongly_connected.py +193 -0
  211. package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_weakly_connected.py +96 -0
  212. package/runtime/python/okstra_vendor/networkx/algorithms/components/weakly_connected.py +196 -0
  213. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/__init__.py +11 -0
  214. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/connectivity.py +811 -0
  215. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/cuts.py +616 -0
  216. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/disjoint_paths.py +408 -0
  217. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/edge_augmentation.py +1270 -0
  218. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/edge_kcomponents.py +592 -0
  219. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/kcomponents.py +220 -0
  220. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/kcutsets.py +235 -0
  221. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/stoerwagner.py +152 -0
  222. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/__init__.py +0 -0
  223. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_connectivity.py +421 -0
  224. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_cuts.py +309 -0
  225. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_disjoint_paths.py +249 -0
  226. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_edge_augmentation.py +502 -0
  227. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_edge_kcomponents.py +488 -0
  228. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_kcomponents.py +323 -0
  229. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_kcutsets.py +280 -0
  230. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_stoer_wagner.py +102 -0
  231. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/utils.py +88 -0
  232. package/runtime/python/okstra_vendor/networkx/algorithms/core.py +588 -0
  233. package/runtime/python/okstra_vendor/networkx/algorithms/covering.py +142 -0
  234. package/runtime/python/okstra_vendor/networkx/algorithms/cuts.py +416 -0
  235. package/runtime/python/okstra_vendor/networkx/algorithms/cycles.py +1234 -0
  236. package/runtime/python/okstra_vendor/networkx/algorithms/d_separation.py +677 -0
  237. package/runtime/python/okstra_vendor/networkx/algorithms/dag.py +1392 -0
  238. package/runtime/python/okstra_vendor/networkx/algorithms/distance_measures.py +1095 -0
  239. package/runtime/python/okstra_vendor/networkx/algorithms/distance_regular.py +272 -0
  240. package/runtime/python/okstra_vendor/networkx/algorithms/dominance.py +142 -0
  241. package/runtime/python/okstra_vendor/networkx/algorithms/dominating.py +268 -0
  242. package/runtime/python/okstra_vendor/networkx/algorithms/efficiency_measures.py +167 -0
  243. package/runtime/python/okstra_vendor/networkx/algorithms/euler.py +470 -0
  244. package/runtime/python/okstra_vendor/networkx/algorithms/flow/__init__.py +11 -0
  245. package/runtime/python/okstra_vendor/networkx/algorithms/flow/boykovkolmogorov.py +370 -0
  246. package/runtime/python/okstra_vendor/networkx/algorithms/flow/capacityscaling.py +407 -0
  247. package/runtime/python/okstra_vendor/networkx/algorithms/flow/dinitz_alg.py +238 -0
  248. package/runtime/python/okstra_vendor/networkx/algorithms/flow/edmondskarp.py +241 -0
  249. package/runtime/python/okstra_vendor/networkx/algorithms/flow/gomory_hu.py +178 -0
  250. package/runtime/python/okstra_vendor/networkx/algorithms/flow/maxflow.py +611 -0
  251. package/runtime/python/okstra_vendor/networkx/algorithms/flow/mincost.py +356 -0
  252. package/runtime/python/okstra_vendor/networkx/algorithms/flow/networksimplex.py +662 -0
  253. package/runtime/python/okstra_vendor/networkx/algorithms/flow/preflowpush.py +425 -0
  254. package/runtime/python/okstra_vendor/networkx/algorithms/flow/shortestaugmentingpath.py +300 -0
  255. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/__init__.py +0 -0
  256. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/gl1.gpickle.bz2 +0 -0
  257. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/gw1.gpickle.bz2 +0 -0
  258. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/netgen-2.gpickle.bz2 +0 -0
  259. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/test_gomory_hu.py +128 -0
  260. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/test_maxflow.py +573 -0
  261. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/test_maxflow_large_graph.py +155 -0
  262. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/test_mincost.py +475 -0
  263. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/test_networksimplex.py +481 -0
  264. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/wlm3.gpickle.bz2 +0 -0
  265. package/runtime/python/okstra_vendor/networkx/algorithms/flow/utils.py +194 -0
  266. package/runtime/python/okstra_vendor/networkx/algorithms/graph_hashing.py +435 -0
  267. package/runtime/python/okstra_vendor/networkx/algorithms/graphical.py +483 -0
  268. package/runtime/python/okstra_vendor/networkx/algorithms/hierarchy.py +57 -0
  269. package/runtime/python/okstra_vendor/networkx/algorithms/hybrid.py +196 -0
  270. package/runtime/python/okstra_vendor/networkx/algorithms/isolate.py +107 -0
  271. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/__init__.py +7 -0
  272. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/ismags.py +1306 -0
  273. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/isomorph.py +336 -0
  274. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/isomorphvf2.py +1262 -0
  275. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/matchhelpers.py +352 -0
  276. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/temporalisomorphvf2.py +308 -0
  277. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/__init__.py +0 -0
  278. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/iso_r01_s80.A99 +0 -0
  279. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/iso_r01_s80.B99 +0 -0
  280. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/si2_b06_m200.A99 +0 -0
  281. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/si2_b06_m200.B99 +0 -0
  282. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_ismags.py +719 -0
  283. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_isomorphism.py +103 -0
  284. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_isomorphvf2.py +490 -0
  285. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_match_helpers.py +64 -0
  286. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_temporalisomorphvf2.py +212 -0
  287. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_tree_isomorphism.py +202 -0
  288. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_vf2pp.py +1655 -0
  289. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_vf2pp_helpers.py +3118 -0
  290. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_vf2userfunc.py +196 -0
  291. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tree_isomorphism.py +264 -0
  292. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/vf2pp.py +1102 -0
  293. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/vf2userfunc.py +192 -0
  294. package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/__init__.py +2 -0
  295. package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/hits_alg.py +337 -0
  296. package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/pagerank_alg.py +498 -0
  297. package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/tests/__init__.py +0 -0
  298. package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/tests/test_hits.py +77 -0
  299. package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/tests/test_pagerank.py +213 -0
  300. package/runtime/python/okstra_vendor/networkx/algorithms/link_prediction.py +687 -0
  301. package/runtime/python/okstra_vendor/networkx/algorithms/lowest_common_ancestors.py +280 -0
  302. package/runtime/python/okstra_vendor/networkx/algorithms/matching.py +1148 -0
  303. package/runtime/python/okstra_vendor/networkx/algorithms/minors/__init__.py +27 -0
  304. package/runtime/python/okstra_vendor/networkx/algorithms/minors/contraction.py +738 -0
  305. package/runtime/python/okstra_vendor/networkx/algorithms/minors/tests/test_contraction.py +544 -0
  306. package/runtime/python/okstra_vendor/networkx/algorithms/mis.py +78 -0
  307. package/runtime/python/okstra_vendor/networkx/algorithms/moral.py +59 -0
  308. package/runtime/python/okstra_vendor/networkx/algorithms/node_classification.py +219 -0
  309. package/runtime/python/okstra_vendor/networkx/algorithms/non_randomness.py +155 -0
  310. package/runtime/python/okstra_vendor/networkx/algorithms/operators/__init__.py +4 -0
  311. package/runtime/python/okstra_vendor/networkx/algorithms/operators/all.py +324 -0
  312. package/runtime/python/okstra_vendor/networkx/algorithms/operators/binary.py +468 -0
  313. package/runtime/python/okstra_vendor/networkx/algorithms/operators/product.py +633 -0
  314. package/runtime/python/okstra_vendor/networkx/algorithms/operators/tests/__init__.py +0 -0
  315. package/runtime/python/okstra_vendor/networkx/algorithms/operators/tests/test_all.py +328 -0
  316. package/runtime/python/okstra_vendor/networkx/algorithms/operators/tests/test_binary.py +451 -0
  317. package/runtime/python/okstra_vendor/networkx/algorithms/operators/tests/test_product.py +491 -0
  318. package/runtime/python/okstra_vendor/networkx/algorithms/operators/tests/test_unary.py +55 -0
  319. package/runtime/python/okstra_vendor/networkx/algorithms/operators/unary.py +77 -0
  320. package/runtime/python/okstra_vendor/networkx/algorithms/perfect_graph.py +73 -0
  321. package/runtime/python/okstra_vendor/networkx/algorithms/planar_drawing.py +464 -0
  322. package/runtime/python/okstra_vendor/networkx/algorithms/planarity.py +1463 -0
  323. package/runtime/python/okstra_vendor/networkx/algorithms/polynomials.py +306 -0
  324. package/runtime/python/okstra_vendor/networkx/algorithms/reciprocity.py +98 -0
  325. package/runtime/python/okstra_vendor/networkx/algorithms/regular.py +167 -0
  326. package/runtime/python/okstra_vendor/networkx/algorithms/richclub.py +138 -0
  327. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/__init__.py +5 -0
  328. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/astar.py +239 -0
  329. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/dense.py +264 -0
  330. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/generic.py +716 -0
  331. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/__init__.py +0 -0
  332. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_astar.py +254 -0
  333. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_dense.py +212 -0
  334. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_dense_numpy.py +88 -0
  335. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_generic.py +511 -0
  336. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_unweighted.py +149 -0
  337. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_weighted.py +983 -0
  338. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/unweighted.py +625 -0
  339. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/weighted.py +2542 -0
  340. package/runtime/python/okstra_vendor/networkx/algorithms/similarity.py +2107 -0
  341. package/runtime/python/okstra_vendor/networkx/algorithms/simple_paths.py +966 -0
  342. package/runtime/python/okstra_vendor/networkx/algorithms/smallworld.py +404 -0
  343. package/runtime/python/okstra_vendor/networkx/algorithms/smetric.py +30 -0
  344. package/runtime/python/okstra_vendor/networkx/algorithms/sparsifiers.py +296 -0
  345. package/runtime/python/okstra_vendor/networkx/algorithms/structuralholes.py +374 -0
  346. package/runtime/python/okstra_vendor/networkx/algorithms/summarization.py +564 -0
  347. package/runtime/python/okstra_vendor/networkx/algorithms/swap.py +406 -0
  348. package/runtime/python/okstra_vendor/networkx/algorithms/tests/__init__.py +0 -0
  349. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_asteroidal.py +23 -0
  350. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_boundary.py +154 -0
  351. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_bridges.py +144 -0
  352. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_broadcasting.py +109 -0
  353. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_chains.py +136 -0
  354. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_chordal.py +129 -0
  355. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_clique.py +300 -0
  356. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_cluster.py +678 -0
  357. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_communicability.py +80 -0
  358. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_core.py +266 -0
  359. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_covering.py +85 -0
  360. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_cuts.py +171 -0
  361. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_cycles.py +984 -0
  362. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_d_separation.py +340 -0
  363. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_dag.py +835 -0
  364. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_distance_measures.py +831 -0
  365. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_distance_regular.py +85 -0
  366. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_dominance.py +299 -0
  367. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_dominating.py +115 -0
  368. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_efficiency.py +58 -0
  369. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_euler.py +314 -0
  370. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_graph_hashing.py +872 -0
  371. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_graphical.py +163 -0
  372. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_hierarchy.py +46 -0
  373. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_hybrid.py +24 -0
  374. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_isolate.py +26 -0
  375. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_link_prediction.py +615 -0
  376. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_lowest_common_ancestors.py +459 -0
  377. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_matching.py +556 -0
  378. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_max_weight_clique.py +179 -0
  379. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_mis.py +62 -0
  380. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_moral.py +15 -0
  381. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_node_classification.py +140 -0
  382. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_non_randomness.py +60 -0
  383. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_perfect_graph.py +27 -0
  384. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_planar_drawing.py +274 -0
  385. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_planarity.py +556 -0
  386. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_polynomials.py +57 -0
  387. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_reciprocity.py +37 -0
  388. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_regular.py +88 -0
  389. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_richclub.py +149 -0
  390. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_similarity.py +1158 -0
  391. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_simple_paths.py +803 -0
  392. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_smallworld.py +76 -0
  393. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_smetric.py +8 -0
  394. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_sparsifiers.py +138 -0
  395. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_structuralholes.py +191 -0
  396. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_summarization.py +642 -0
  397. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_swap.py +179 -0
  398. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_threshold.py +270 -0
  399. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_time_dependent.py +431 -0
  400. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_tournament.py +161 -0
  401. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_triads.py +248 -0
  402. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_vitality.py +41 -0
  403. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_voronoi.py +103 -0
  404. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_walks.py +54 -0
  405. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_wiener.py +157 -0
  406. package/runtime/python/okstra_vendor/networkx/algorithms/threshold.py +981 -0
  407. package/runtime/python/okstra_vendor/networkx/algorithms/time_dependent.py +142 -0
  408. package/runtime/python/okstra_vendor/networkx/algorithms/tournament.py +406 -0
  409. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/__init__.py +5 -0
  410. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/beamsearch.py +90 -0
  411. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/breadth_first_search.py +576 -0
  412. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/depth_first_search.py +529 -0
  413. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/edgebfs.py +185 -0
  414. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/edgedfs.py +182 -0
  415. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/__init__.py +0 -0
  416. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/test_beamsearch.py +25 -0
  417. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/test_bfs.py +203 -0
  418. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/test_dfs.py +307 -0
  419. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/test_edgebfs.py +147 -0
  420. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/test_edgedfs.py +131 -0
  421. package/runtime/python/okstra_vendor/networkx/algorithms/tree/__init__.py +7 -0
  422. package/runtime/python/okstra_vendor/networkx/algorithms/tree/branchings.py +1042 -0
  423. package/runtime/python/okstra_vendor/networkx/algorithms/tree/coding.py +413 -0
  424. package/runtime/python/okstra_vendor/networkx/algorithms/tree/decomposition.py +88 -0
  425. package/runtime/python/okstra_vendor/networkx/algorithms/tree/distance_measures.py +219 -0
  426. package/runtime/python/okstra_vendor/networkx/algorithms/tree/mst.py +1281 -0
  427. package/runtime/python/okstra_vendor/networkx/algorithms/tree/operations.py +106 -0
  428. package/runtime/python/okstra_vendor/networkx/algorithms/tree/recognition.py +273 -0
  429. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/__init__.py +0 -0
  430. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_branchings.py +624 -0
  431. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_coding.py +114 -0
  432. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_decomposition.py +79 -0
  433. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_distance_measures.py +99 -0
  434. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_mst.py +934 -0
  435. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_operations.py +53 -0
  436. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_recognition.py +174 -0
  437. package/runtime/python/okstra_vendor/networkx/algorithms/triads.py +500 -0
  438. package/runtime/python/okstra_vendor/networkx/algorithms/vitality.py +76 -0
  439. package/runtime/python/okstra_vendor/networkx/algorithms/voronoi.py +86 -0
  440. package/runtime/python/okstra_vendor/networkx/algorithms/walks.py +77 -0
  441. package/runtime/python/okstra_vendor/networkx/algorithms/wiener.py +278 -0
  442. package/runtime/python/okstra_vendor/networkx/classes/__init__.py +13 -0
  443. package/runtime/python/okstra_vendor/networkx/classes/coreviews.py +435 -0
  444. package/runtime/python/okstra_vendor/networkx/classes/digraph.py +1363 -0
  445. package/runtime/python/okstra_vendor/networkx/classes/filters.py +95 -0
  446. package/runtime/python/okstra_vendor/networkx/classes/function.py +1549 -0
  447. package/runtime/python/okstra_vendor/networkx/classes/graph.py +2082 -0
  448. package/runtime/python/okstra_vendor/networkx/classes/graphviews.py +269 -0
  449. package/runtime/python/okstra_vendor/networkx/classes/multidigraph.py +977 -0
  450. package/runtime/python/okstra_vendor/networkx/classes/multigraph.py +1294 -0
  451. package/runtime/python/okstra_vendor/networkx/classes/reportviews.py +1447 -0
  452. package/runtime/python/okstra_vendor/networkx/classes/tests/__init__.py +0 -0
  453. package/runtime/python/okstra_vendor/networkx/classes/tests/dispatch_interface.py +192 -0
  454. package/runtime/python/okstra_vendor/networkx/classes/tests/historical_tests.py +476 -0
  455. package/runtime/python/okstra_vendor/networkx/classes/tests/test_coreviews.py +362 -0
  456. package/runtime/python/okstra_vendor/networkx/classes/tests/test_digraph.py +331 -0
  457. package/runtime/python/okstra_vendor/networkx/classes/tests/test_digraph_historical.py +110 -0
  458. package/runtime/python/okstra_vendor/networkx/classes/tests/test_filters.py +177 -0
  459. package/runtime/python/okstra_vendor/networkx/classes/tests/test_function.py +1045 -0
  460. package/runtime/python/okstra_vendor/networkx/classes/tests/test_graph.py +950 -0
  461. package/runtime/python/okstra_vendor/networkx/classes/tests/test_graph_historical.py +12 -0
  462. package/runtime/python/okstra_vendor/networkx/classes/tests/test_graphviews.py +349 -0
  463. package/runtime/python/okstra_vendor/networkx/classes/tests/test_multidigraph.py +459 -0
  464. package/runtime/python/okstra_vendor/networkx/classes/tests/test_multigraph.py +528 -0
  465. package/runtime/python/okstra_vendor/networkx/classes/tests/test_reportviews.py +1421 -0
  466. package/runtime/python/okstra_vendor/networkx/classes/tests/test_special.py +131 -0
  467. package/runtime/python/okstra_vendor/networkx/classes/tests/test_subgraphviews.py +371 -0
  468. package/runtime/python/okstra_vendor/networkx/conftest.py +261 -0
  469. package/runtime/python/okstra_vendor/networkx/convert.py +502 -0
  470. package/runtime/python/okstra_vendor/networkx/convert_matrix.py +1314 -0
  471. package/runtime/python/okstra_vendor/networkx/drawing/__init__.py +7 -0
  472. package/runtime/python/okstra_vendor/networkx/drawing/layout.py +2036 -0
  473. package/runtime/python/okstra_vendor/networkx/drawing/nx_agraph.py +470 -0
  474. package/runtime/python/okstra_vendor/networkx/drawing/nx_latex.py +570 -0
  475. package/runtime/python/okstra_vendor/networkx/drawing/nx_pydot.py +361 -0
  476. package/runtime/python/okstra_vendor/networkx/drawing/nx_pylab.py +2978 -0
  477. package/runtime/python/okstra_vendor/networkx/drawing/tests/__init__.py +0 -0
  478. package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_display_complex.png +0 -0
  479. package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_display_empty_graph.png +0 -0
  480. package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_display_house_with_colors.png +0 -0
  481. package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_display_labels_and_colors.png +0 -0
  482. package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_display_shortest_path.png +0 -0
  483. package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_house_with_colors.png +0 -0
  484. package/runtime/python/okstra_vendor/networkx/drawing/tests/test_agraph.py +237 -0
  485. package/runtime/python/okstra_vendor/networkx/drawing/tests/test_image_comparison_pylab_mpl.py +229 -0
  486. package/runtime/python/okstra_vendor/networkx/drawing/tests/test_latex.py +285 -0
  487. package/runtime/python/okstra_vendor/networkx/drawing/tests/test_layout.py +631 -0
  488. package/runtime/python/okstra_vendor/networkx/drawing/tests/test_pydot.py +146 -0
  489. package/runtime/python/okstra_vendor/networkx/drawing/tests/test_pylab.py +1582 -0
  490. package/runtime/python/okstra_vendor/networkx/exception.py +131 -0
  491. package/runtime/python/okstra_vendor/networkx/generators/__init__.py +34 -0
  492. package/runtime/python/okstra_vendor/networkx/generators/atlas.dat.gz +0 -0
  493. package/runtime/python/okstra_vendor/networkx/generators/atlas.py +227 -0
  494. package/runtime/python/okstra_vendor/networkx/generators/classic.py +1091 -0
  495. package/runtime/python/okstra_vendor/networkx/generators/cographs.py +68 -0
  496. package/runtime/python/okstra_vendor/networkx/generators/community.py +1070 -0
  497. package/runtime/python/okstra_vendor/networkx/generators/degree_seq.py +886 -0
  498. package/runtime/python/okstra_vendor/networkx/generators/directed.py +572 -0
  499. package/runtime/python/okstra_vendor/networkx/generators/duplication.py +174 -0
  500. package/runtime/python/okstra_vendor/networkx/generators/ego.py +66 -0
  501. package/runtime/python/okstra_vendor/networkx/generators/expanders.py +499 -0
  502. package/runtime/python/okstra_vendor/networkx/generators/geometric.py +1037 -0
  503. package/runtime/python/okstra_vendor/networkx/generators/harary_graph.py +163 -0
  504. package/runtime/python/okstra_vendor/networkx/generators/internet_as_graphs.py +443 -0
  505. package/runtime/python/okstra_vendor/networkx/generators/intersection.py +125 -0
  506. package/runtime/python/okstra_vendor/networkx/generators/interval_graph.py +70 -0
  507. package/runtime/python/okstra_vendor/networkx/generators/joint_degree_seq.py +664 -0
  508. package/runtime/python/okstra_vendor/networkx/generators/lattice.py +405 -0
  509. package/runtime/python/okstra_vendor/networkx/generators/line.py +501 -0
  510. package/runtime/python/okstra_vendor/networkx/generators/mycielski.py +110 -0
  511. package/runtime/python/okstra_vendor/networkx/generators/nonisomorphic_trees.py +259 -0
  512. package/runtime/python/okstra_vendor/networkx/generators/random_clustered.py +117 -0
  513. package/runtime/python/okstra_vendor/networkx/generators/random_graphs.py +1416 -0
  514. package/runtime/python/okstra_vendor/networkx/generators/small.py +1070 -0
  515. package/runtime/python/okstra_vendor/networkx/generators/social.py +554 -0
  516. package/runtime/python/okstra_vendor/networkx/generators/spectral_graph_forge.py +120 -0
  517. package/runtime/python/okstra_vendor/networkx/generators/stochastic.py +54 -0
  518. package/runtime/python/okstra_vendor/networkx/generators/sudoku.py +131 -0
  519. package/runtime/python/okstra_vendor/networkx/generators/tests/__init__.py +0 -0
  520. package/runtime/python/okstra_vendor/networkx/generators/tests/test_atlas.py +75 -0
  521. package/runtime/python/okstra_vendor/networkx/generators/tests/test_classic.py +642 -0
  522. package/runtime/python/okstra_vendor/networkx/generators/tests/test_cographs.py +20 -0
  523. package/runtime/python/okstra_vendor/networkx/generators/tests/test_community.py +362 -0
  524. package/runtime/python/okstra_vendor/networkx/generators/tests/test_degree_seq.py +224 -0
  525. package/runtime/python/okstra_vendor/networkx/generators/tests/test_directed.py +189 -0
  526. package/runtime/python/okstra_vendor/networkx/generators/tests/test_duplication.py +103 -0
  527. package/runtime/python/okstra_vendor/networkx/generators/tests/test_ego.py +39 -0
  528. package/runtime/python/okstra_vendor/networkx/generators/tests/test_expanders.py +182 -0
  529. package/runtime/python/okstra_vendor/networkx/generators/tests/test_geometric.py +488 -0
  530. package/runtime/python/okstra_vendor/networkx/generators/tests/test_harary_graph.py +133 -0
  531. package/runtime/python/okstra_vendor/networkx/generators/tests/test_internet_as_graphs.py +221 -0
  532. package/runtime/python/okstra_vendor/networkx/generators/tests/test_intersection.py +28 -0
  533. package/runtime/python/okstra_vendor/networkx/generators/tests/test_interval_graph.py +144 -0
  534. package/runtime/python/okstra_vendor/networkx/generators/tests/test_joint_degree_seq.py +125 -0
  535. package/runtime/python/okstra_vendor/networkx/generators/tests/test_lattice.py +264 -0
  536. package/runtime/python/okstra_vendor/networkx/generators/tests/test_line.py +316 -0
  537. package/runtime/python/okstra_vendor/networkx/generators/tests/test_mycielski.py +30 -0
  538. package/runtime/python/okstra_vendor/networkx/generators/tests/test_nonisomorphic_trees.py +82 -0
  539. package/runtime/python/okstra_vendor/networkx/generators/tests/test_random_clustered.py +33 -0
  540. package/runtime/python/okstra_vendor/networkx/generators/tests/test_random_graphs.py +495 -0
  541. package/runtime/python/okstra_vendor/networkx/generators/tests/test_small.py +220 -0
  542. package/runtime/python/okstra_vendor/networkx/generators/tests/test_spectral_graph_forge.py +49 -0
  543. package/runtime/python/okstra_vendor/networkx/generators/tests/test_stochastic.py +72 -0
  544. package/runtime/python/okstra_vendor/networkx/generators/tests/test_sudoku.py +92 -0
  545. package/runtime/python/okstra_vendor/networkx/generators/tests/test_time_series.py +64 -0
  546. package/runtime/python/okstra_vendor/networkx/generators/tests/test_trees.py +195 -0
  547. package/runtime/python/okstra_vendor/networkx/generators/tests/test_triads.py +15 -0
  548. package/runtime/python/okstra_vendor/networkx/generators/time_series.py +74 -0
  549. package/runtime/python/okstra_vendor/networkx/generators/trees.py +1070 -0
  550. package/runtime/python/okstra_vendor/networkx/generators/triads.py +94 -0
  551. package/runtime/python/okstra_vendor/networkx/lazy_imports.py +188 -0
  552. package/runtime/python/okstra_vendor/networkx/linalg/__init__.py +13 -0
  553. package/runtime/python/okstra_vendor/networkx/linalg/algebraicconnectivity.py +650 -0
  554. package/runtime/python/okstra_vendor/networkx/linalg/attrmatrix.py +466 -0
  555. package/runtime/python/okstra_vendor/networkx/linalg/bethehessianmatrix.py +77 -0
  556. package/runtime/python/okstra_vendor/networkx/linalg/graphmatrix.py +168 -0
  557. package/runtime/python/okstra_vendor/networkx/linalg/laplacianmatrix.py +512 -0
  558. package/runtime/python/okstra_vendor/networkx/linalg/modularitymatrix.py +166 -0
  559. package/runtime/python/okstra_vendor/networkx/linalg/spectrum.py +186 -0
  560. package/runtime/python/okstra_vendor/networkx/linalg/tests/__init__.py +0 -0
  561. package/runtime/python/okstra_vendor/networkx/linalg/tests/test_algebraic_connectivity.py +400 -0
  562. package/runtime/python/okstra_vendor/networkx/linalg/tests/test_attrmatrix.py +108 -0
  563. package/runtime/python/okstra_vendor/networkx/linalg/tests/test_bethehessian.py +40 -0
  564. package/runtime/python/okstra_vendor/networkx/linalg/tests/test_graphmatrix.py +275 -0
  565. package/runtime/python/okstra_vendor/networkx/linalg/tests/test_laplacian.py +334 -0
  566. package/runtime/python/okstra_vendor/networkx/linalg/tests/test_modularity.py +86 -0
  567. package/runtime/python/okstra_vendor/networkx/linalg/tests/test_spectrum.py +70 -0
  568. package/runtime/python/okstra_vendor/networkx/readwrite/__init__.py +17 -0
  569. package/runtime/python/okstra_vendor/networkx/readwrite/adjlist.py +330 -0
  570. package/runtime/python/okstra_vendor/networkx/readwrite/edgelist.py +489 -0
  571. package/runtime/python/okstra_vendor/networkx/readwrite/gexf.py +1084 -0
  572. package/runtime/python/okstra_vendor/networkx/readwrite/gml.py +879 -0
  573. package/runtime/python/okstra_vendor/networkx/readwrite/graph6.py +427 -0
  574. package/runtime/python/okstra_vendor/networkx/readwrite/graphml.py +1053 -0
  575. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/__init__.py +19 -0
  576. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/adjacency.py +156 -0
  577. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/cytoscape.py +190 -0
  578. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/node_link.py +261 -0
  579. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tests/__init__.py +0 -0
  580. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tests/test_adjacency.py +78 -0
  581. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tests/test_cytoscape.py +78 -0
  582. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tests/test_node_link.py +109 -0
  583. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tests/test_tree.py +48 -0
  584. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tree.py +137 -0
  585. package/runtime/python/okstra_vendor/networkx/readwrite/leda.py +108 -0
  586. package/runtime/python/okstra_vendor/networkx/readwrite/multiline_adjlist.py +393 -0
  587. package/runtime/python/okstra_vendor/networkx/readwrite/p2g.py +113 -0
  588. package/runtime/python/okstra_vendor/networkx/readwrite/pajek.py +286 -0
  589. package/runtime/python/okstra_vendor/networkx/readwrite/sparse6.py +379 -0
  590. package/runtime/python/okstra_vendor/networkx/readwrite/tests/__init__.py +0 -0
  591. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_adjlist.py +354 -0
  592. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_edgelist.py +318 -0
  593. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_gexf.py +612 -0
  594. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_gml.py +744 -0
  595. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_graph6.py +181 -0
  596. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_graphml.py +1531 -0
  597. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_leda.py +30 -0
  598. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_p2g.py +63 -0
  599. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_pajek.py +128 -0
  600. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_sparse6.py +166 -0
  601. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_text.py +1742 -0
  602. package/runtime/python/okstra_vendor/networkx/readwrite/text.py +851 -0
  603. package/runtime/python/okstra_vendor/networkx/relabel.py +285 -0
  604. package/runtime/python/okstra_vendor/networkx/tests/__init__.py +0 -0
  605. package/runtime/python/okstra_vendor/networkx/tests/test_all_random_functions.py +248 -0
  606. package/runtime/python/okstra_vendor/networkx/tests/test_convert.py +321 -0
  607. package/runtime/python/okstra_vendor/networkx/tests/test_convert_numpy.py +531 -0
  608. package/runtime/python/okstra_vendor/networkx/tests/test_convert_pandas.py +349 -0
  609. package/runtime/python/okstra_vendor/networkx/tests/test_convert_scipy.py +281 -0
  610. package/runtime/python/okstra_vendor/networkx/tests/test_exceptions.py +40 -0
  611. package/runtime/python/okstra_vendor/networkx/tests/test_import.py +11 -0
  612. package/runtime/python/okstra_vendor/networkx/tests/test_lazy_imports.py +96 -0
  613. package/runtime/python/okstra_vendor/networkx/tests/test_relabel.py +349 -0
  614. package/runtime/python/okstra_vendor/networkx/tests/test_removed_functions_exception_messages.py +8 -0
  615. package/runtime/python/okstra_vendor/networkx/utils/__init__.py +8 -0
  616. package/runtime/python/okstra_vendor/networkx/utils/backends.py +2171 -0
  617. package/runtime/python/okstra_vendor/networkx/utils/configs.py +396 -0
  618. package/runtime/python/okstra_vendor/networkx/utils/decorators.py +1233 -0
  619. package/runtime/python/okstra_vendor/networkx/utils/heaps.py +338 -0
  620. package/runtime/python/okstra_vendor/networkx/utils/mapped_queue.py +297 -0
  621. package/runtime/python/okstra_vendor/networkx/utils/misc.py +703 -0
  622. package/runtime/python/okstra_vendor/networkx/utils/random_sequence.py +198 -0
  623. package/runtime/python/okstra_vendor/networkx/utils/rcm.py +159 -0
  624. package/runtime/python/okstra_vendor/networkx/utils/tests/__init__.py +0 -0
  625. package/runtime/python/okstra_vendor/networkx/utils/tests/test__init.py +11 -0
  626. package/runtime/python/okstra_vendor/networkx/utils/tests/test_backends.py +225 -0
  627. package/runtime/python/okstra_vendor/networkx/utils/tests/test_config.py +263 -0
  628. package/runtime/python/okstra_vendor/networkx/utils/tests/test_decorators.py +510 -0
  629. package/runtime/python/okstra_vendor/networkx/utils/tests/test_heaps.py +131 -0
  630. package/runtime/python/okstra_vendor/networkx/utils/tests/test_mapped_queue.py +268 -0
  631. package/runtime/python/okstra_vendor/networkx/utils/tests/test_misc.py +393 -0
  632. package/runtime/python/okstra_vendor/networkx/utils/tests/test_random_sequence.py +53 -0
  633. package/runtime/python/okstra_vendor/networkx/utils/tests/test_rcm.py +63 -0
  634. package/runtime/python/okstra_vendor/networkx/utils/tests/test_unionfind.py +55 -0
  635. package/runtime/python/okstra_vendor/networkx/utils/union_find.py +106 -0
  636. package/runtime/skills/okstra-graphify/SKILL.md +161 -0
  637. package/runtime/skills/okstra-inspect/SKILL.md +17 -9
  638. package/runtime/templates/reports/settings.template.json +4 -0
  639. package/src/cli-registry.mjs +7 -0
  640. package/src/commands/graphify.mjs +32 -0
  641. package/src/commands/lifecycle/doctor.mjs +9 -0
  642. package/src/lib/skill-catalog.mjs +1 -0
@@ -0,0 +1,1531 @@
1
+ import io
2
+
3
+ import pytest
4
+
5
+ import networkx as nx
6
+ from networkx.readwrite.graphml import GraphMLWriter
7
+ from networkx.utils import edges_equal, nodes_equal
8
+
9
+
10
+ class BaseGraphML:
11
+ @classmethod
12
+ def setup_class(cls):
13
+ cls.simple_directed_data = """<?xml version="1.0" encoding="UTF-8"?>
14
+ <!-- This file was written by the JAVA GraphML Library.-->
15
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
16
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
17
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
18
+ http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
19
+ <graph id="G" edgedefault="directed">
20
+ <node id="n0"/>
21
+ <node id="n1"/>
22
+ <node id="n2"/>
23
+ <node id="n3"/>
24
+ <node id="n4"/>
25
+ <node id="n5"/>
26
+ <node id="n6"/>
27
+ <node id="n7"/>
28
+ <node id="n8"/>
29
+ <node id="n9"/>
30
+ <node id="n10"/>
31
+ <edge id="foo" source="n0" target="n2"/>
32
+ <edge source="n1" target="n2"/>
33
+ <edge source="n2" target="n3"/>
34
+ <edge source="n3" target="n5"/>
35
+ <edge source="n3" target="n4"/>
36
+ <edge source="n4" target="n6"/>
37
+ <edge source="n6" target="n5"/>
38
+ <edge source="n5" target="n7"/>
39
+ <edge source="n6" target="n8"/>
40
+ <edge source="n8" target="n7"/>
41
+ <edge source="n8" target="n9"/>
42
+ </graph>
43
+ </graphml>"""
44
+ cls.simple_directed_graph = nx.DiGraph()
45
+ cls.simple_directed_graph.add_node("n10")
46
+ cls.simple_directed_graph.add_edge("n0", "n2", id="foo")
47
+ cls.simple_directed_graph.add_edge("n0", "n2")
48
+ cls.simple_directed_graph.add_edges_from(
49
+ [
50
+ ("n1", "n2"),
51
+ ("n2", "n3"),
52
+ ("n3", "n5"),
53
+ ("n3", "n4"),
54
+ ("n4", "n6"),
55
+ ("n6", "n5"),
56
+ ("n5", "n7"),
57
+ ("n6", "n8"),
58
+ ("n8", "n7"),
59
+ ("n8", "n9"),
60
+ ]
61
+ )
62
+ cls.simple_directed_fh = io.BytesIO(cls.simple_directed_data.encode("UTF-8"))
63
+
64
+ cls.attribute_data = """<?xml version="1.0" encoding="UTF-8"?>
65
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
66
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
67
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
68
+ http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
69
+ <key id="d0" for="node" attr.name="color" attr.type="string">
70
+ <default>yellow</default>
71
+ </key>
72
+ <key id="d1" for="edge" attr.name="weight" attr.type="double"/>
73
+ <graph id="G" edgedefault="directed">
74
+ <node id="n0">
75
+ <data key="d0">green</data>
76
+ </node>
77
+ <node id="n1"/>
78
+ <node id="n2">
79
+ <data key="d0">blue</data>
80
+ </node>
81
+ <node id="n3">
82
+ <data key="d0">red</data>
83
+ </node>
84
+ <node id="n4"/>
85
+ <node id="n5">
86
+ <data key="d0">turquoise</data>
87
+ </node>
88
+ <edge id="e0" source="n0" target="n2">
89
+ <data key="d1">1.0</data>
90
+ </edge>
91
+ <edge id="e1" source="n0" target="n1">
92
+ <data key="d1">1.0</data>
93
+ </edge>
94
+ <edge id="e2" source="n1" target="n3">
95
+ <data key="d1">2.0</data>
96
+ </edge>
97
+ <edge id="e3" source="n3" target="n2"/>
98
+ <edge id="e4" source="n2" target="n4"/>
99
+ <edge id="e5" source="n3" target="n5"/>
100
+ <edge id="e6" source="n5" target="n4">
101
+ <data key="d1">1.1</data>
102
+ </edge>
103
+ </graph>
104
+ </graphml>
105
+ """
106
+ cls.attribute_graph = nx.DiGraph(id="G")
107
+ cls.attribute_graph.graph["node_default"] = {"color": "yellow"}
108
+ cls.attribute_graph.add_node("n0", color="green")
109
+ cls.attribute_graph.add_node("n2", color="blue")
110
+ cls.attribute_graph.add_node("n3", color="red")
111
+ cls.attribute_graph.add_node("n4")
112
+ cls.attribute_graph.add_node("n5", color="turquoise")
113
+ cls.attribute_graph.add_edge("n0", "n2", id="e0", weight=1.0)
114
+ cls.attribute_graph.add_edge("n0", "n1", id="e1", weight=1.0)
115
+ cls.attribute_graph.add_edge("n1", "n3", id="e2", weight=2.0)
116
+ cls.attribute_graph.add_edge("n3", "n2", id="e3")
117
+ cls.attribute_graph.add_edge("n2", "n4", id="e4")
118
+ cls.attribute_graph.add_edge("n3", "n5", id="e5")
119
+ cls.attribute_graph.add_edge("n5", "n4", id="e6", weight=1.1)
120
+ cls.attribute_fh = io.BytesIO(cls.attribute_data.encode("UTF-8"))
121
+
122
+ cls.node_attribute_default_data = """<?xml version="1.0" encoding="UTF-8"?>
123
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
124
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
125
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
126
+ http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
127
+ <key id="d0" for="node" attr.name="boolean_attribute" attr.type="boolean"><default>false</default></key>
128
+ <key id="d1" for="node" attr.name="int_attribute" attr.type="int"><default>0</default></key>
129
+ <key id="d2" for="node" attr.name="long_attribute" attr.type="long"><default>0</default></key>
130
+ <key id="d3" for="node" attr.name="float_attribute" attr.type="float"><default>0.0</default></key>
131
+ <key id="d4" for="node" attr.name="double_attribute" attr.type="double"><default>0.0</default></key>
132
+ <key id="d5" for="node" attr.name="string_attribute" attr.type="string"><default>Foo</default></key>
133
+ <graph id="G" edgedefault="directed">
134
+ <node id="n0"/>
135
+ <node id="n1"/>
136
+ <edge id="e0" source="n0" target="n1"/>
137
+ </graph>
138
+ </graphml>
139
+ """
140
+ cls.node_attribute_default_graph = nx.DiGraph(id="G")
141
+ cls.node_attribute_default_graph.graph["node_default"] = {
142
+ "boolean_attribute": False,
143
+ "int_attribute": 0,
144
+ "long_attribute": 0,
145
+ "float_attribute": 0.0,
146
+ "double_attribute": 0.0,
147
+ "string_attribute": "Foo",
148
+ }
149
+ cls.node_attribute_default_graph.add_node("n0")
150
+ cls.node_attribute_default_graph.add_node("n1")
151
+ cls.node_attribute_default_graph.add_edge("n0", "n1", id="e0")
152
+ cls.node_attribute_default_fh = io.BytesIO(
153
+ cls.node_attribute_default_data.encode("UTF-8")
154
+ )
155
+
156
+ cls.attribute_named_key_ids_data = """<?xml version='1.0' encoding='utf-8'?>
157
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
158
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
159
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
160
+ http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
161
+ <key id="edge_prop" for="edge" attr.name="edge_prop" attr.type="string"/>
162
+ <key id="prop2" for="node" attr.name="prop2" attr.type="string"/>
163
+ <key id="prop1" for="node" attr.name="prop1" attr.type="string"/>
164
+ <graph edgedefault="directed">
165
+ <node id="0">
166
+ <data key="prop1">val1</data>
167
+ <data key="prop2">val2</data>
168
+ </node>
169
+ <node id="1">
170
+ <data key="prop1">val_one</data>
171
+ <data key="prop2">val2</data>
172
+ </node>
173
+ <edge source="0" target="1">
174
+ <data key="edge_prop">edge_value</data>
175
+ </edge>
176
+ </graph>
177
+ </graphml>
178
+ """
179
+ cls.attribute_named_key_ids_graph = nx.DiGraph()
180
+ cls.attribute_named_key_ids_graph.add_node("0", prop1="val1", prop2="val2")
181
+ cls.attribute_named_key_ids_graph.add_node("1", prop1="val_one", prop2="val2")
182
+ cls.attribute_named_key_ids_graph.add_edge("0", "1", edge_prop="edge_value")
183
+ fh = io.BytesIO(cls.attribute_named_key_ids_data.encode("UTF-8"))
184
+ cls.attribute_named_key_ids_fh = fh
185
+
186
+ cls.attribute_numeric_type_data = """<?xml version='1.0' encoding='utf-8'?>
187
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
188
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
189
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
190
+ http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
191
+ <key attr.name="weight" attr.type="double" for="node" id="d1" />
192
+ <key attr.name="weight" attr.type="double" for="edge" id="d0" />
193
+ <graph edgedefault="directed">
194
+ <node id="n0">
195
+ <data key="d1">1</data>
196
+ </node>
197
+ <node id="n1">
198
+ <data key="d1">2.0</data>
199
+ </node>
200
+ <edge source="n0" target="n1">
201
+ <data key="d0">1</data>
202
+ </edge>
203
+ <edge source="n1" target="n0">
204
+ <data key="d0">k</data>
205
+ </edge>
206
+ <edge source="n1" target="n1">
207
+ <data key="d0">1.0</data>
208
+ </edge>
209
+ </graph>
210
+ </graphml>
211
+ """
212
+ cls.attribute_numeric_type_graph = nx.DiGraph()
213
+ cls.attribute_numeric_type_graph.add_node("n0", weight=1)
214
+ cls.attribute_numeric_type_graph.add_node("n1", weight=2.0)
215
+ cls.attribute_numeric_type_graph.add_edge("n0", "n1", weight=1)
216
+ cls.attribute_numeric_type_graph.add_edge("n1", "n1", weight=1.0)
217
+ fh = io.BytesIO(cls.attribute_numeric_type_data.encode("UTF-8"))
218
+ cls.attribute_numeric_type_fh = fh
219
+
220
+ cls.simple_undirected_data = """<?xml version="1.0" encoding="UTF-8"?>
221
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
222
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
223
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
224
+ http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
225
+ <graph id="G">
226
+ <node id="n0"/>
227
+ <node id="n1"/>
228
+ <node id="n2"/>
229
+ <node id="n10"/>
230
+ <edge id="foo" source="n0" target="n2"/>
231
+ <edge source="n1" target="n2"/>
232
+ <edge source="n2" target="n3"/>
233
+ </graph>
234
+ </graphml>"""
235
+ # <edge source="n8" target="n10" directed="false"/>
236
+ cls.simple_undirected_graph = nx.Graph()
237
+ cls.simple_undirected_graph.add_node("n10")
238
+ cls.simple_undirected_graph.add_edge("n0", "n2", id="foo")
239
+ cls.simple_undirected_graph.add_edges_from([("n1", "n2"), ("n2", "n3")])
240
+ fh = io.BytesIO(cls.simple_undirected_data.encode("UTF-8"))
241
+ cls.simple_undirected_fh = fh
242
+
243
+ cls.undirected_multigraph_data = """<?xml version="1.0" encoding="UTF-8"?>
244
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
245
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
246
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
247
+ http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
248
+ <graph id="G">
249
+ <node id="n0"/>
250
+ <node id="n1"/>
251
+ <node id="n2"/>
252
+ <node id="n10"/>
253
+ <edge id="e0" source="n0" target="n2"/>
254
+ <edge id="e1" source="n1" target="n2"/>
255
+ <edge id="e2" source="n2" target="n1"/>
256
+ </graph>
257
+ </graphml>"""
258
+ cls.undirected_multigraph = nx.MultiGraph()
259
+ cls.undirected_multigraph.add_node("n10")
260
+ cls.undirected_multigraph.add_edge("n0", "n2", id="e0")
261
+ cls.undirected_multigraph.add_edge("n1", "n2", id="e1")
262
+ cls.undirected_multigraph.add_edge("n2", "n1", id="e2")
263
+ fh = io.BytesIO(cls.undirected_multigraph_data.encode("UTF-8"))
264
+ cls.undirected_multigraph_fh = fh
265
+
266
+ cls.undirected_multigraph_no_multiedge_data = """<?xml version="1.0" encoding="UTF-8"?>
267
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
268
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
269
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
270
+ http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
271
+ <graph id="G">
272
+ <node id="n0"/>
273
+ <node id="n1"/>
274
+ <node id="n2"/>
275
+ <node id="n10"/>
276
+ <edge id="e0" source="n0" target="n2"/>
277
+ <edge id="e1" source="n1" target="n2"/>
278
+ <edge id="e2" source="n2" target="n3"/>
279
+ </graph>
280
+ </graphml>"""
281
+ cls.undirected_multigraph_no_multiedge = nx.MultiGraph()
282
+ cls.undirected_multigraph_no_multiedge.add_node("n10")
283
+ cls.undirected_multigraph_no_multiedge.add_edge("n0", "n2", id="e0")
284
+ cls.undirected_multigraph_no_multiedge.add_edge("n1", "n2", id="e1")
285
+ cls.undirected_multigraph_no_multiedge.add_edge("n2", "n3", id="e2")
286
+ fh = io.BytesIO(cls.undirected_multigraph_no_multiedge_data.encode("UTF-8"))
287
+ cls.undirected_multigraph_no_multiedge_fh = fh
288
+
289
+ cls.multigraph_only_ids_for_multiedges_data = """<?xml version="1.0" encoding="UTF-8"?>
290
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
291
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
292
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
293
+ http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
294
+ <graph id="G">
295
+ <node id="n0"/>
296
+ <node id="n1"/>
297
+ <node id="n2"/>
298
+ <node id="n10"/>
299
+ <edge source="n0" target="n2"/>
300
+ <edge id="e1" source="n1" target="n2"/>
301
+ <edge id="e2" source="n2" target="n1"/>
302
+ </graph>
303
+ </graphml>"""
304
+ cls.multigraph_only_ids_for_multiedges = nx.MultiGraph()
305
+ cls.multigraph_only_ids_for_multiedges.add_node("n10")
306
+ cls.multigraph_only_ids_for_multiedges.add_edge("n0", "n2")
307
+ cls.multigraph_only_ids_for_multiedges.add_edge("n1", "n2", id="e1")
308
+ cls.multigraph_only_ids_for_multiedges.add_edge("n2", "n1", id="e2")
309
+ fh = io.BytesIO(cls.multigraph_only_ids_for_multiedges_data.encode("UTF-8"))
310
+ cls.multigraph_only_ids_for_multiedges_fh = fh
311
+
312
+
313
+ class TestReadGraphML(BaseGraphML):
314
+ def test_read_simple_directed_graphml(self):
315
+ G = self.simple_directed_graph
316
+ H = nx.read_graphml(self.simple_directed_fh)
317
+ assert sorted(G.nodes()) == sorted(H.nodes())
318
+ assert sorted(G.edges()) == sorted(H.edges())
319
+ assert sorted(G.edges(data=True)) == sorted(H.edges(data=True))
320
+ self.simple_directed_fh.seek(0)
321
+
322
+ PG = nx.parse_graphml(self.simple_directed_data)
323
+ assert sorted(G.nodes()) == sorted(PG.nodes())
324
+ assert sorted(G.edges()) == sorted(PG.edges())
325
+ assert sorted(G.edges(data=True)) == sorted(PG.edges(data=True))
326
+
327
+ def test_read_simple_undirected_graphml(self):
328
+ G = self.simple_undirected_graph
329
+ H = nx.read_graphml(self.simple_undirected_fh)
330
+ assert nodes_equal(G.nodes(), H.nodes())
331
+ assert edges_equal(G.edges(), H.edges())
332
+ self.simple_undirected_fh.seek(0)
333
+
334
+ PG = nx.parse_graphml(self.simple_undirected_data)
335
+ assert nodes_equal(G.nodes(), PG.nodes())
336
+ assert edges_equal(G.edges(), PG.edges())
337
+
338
+ def test_read_undirected_multigraph_graphml(self):
339
+ G = self.undirected_multigraph
340
+ H = nx.read_graphml(self.undirected_multigraph_fh)
341
+ assert nodes_equal(G.nodes(), H.nodes())
342
+ assert edges_equal(G.edges(), H.edges())
343
+ self.undirected_multigraph_fh.seek(0)
344
+
345
+ PG = nx.parse_graphml(self.undirected_multigraph_data)
346
+ assert nodes_equal(G.nodes(), PG.nodes())
347
+ assert edges_equal(G.edges(), PG.edges())
348
+
349
+ def test_read_undirected_multigraph_no_multiedge_graphml(self):
350
+ G = self.undirected_multigraph_no_multiedge
351
+ H = nx.read_graphml(self.undirected_multigraph_no_multiedge_fh)
352
+ assert nodes_equal(G.nodes(), H.nodes())
353
+ assert edges_equal(G.edges(), H.edges())
354
+ self.undirected_multigraph_no_multiedge_fh.seek(0)
355
+
356
+ PG = nx.parse_graphml(self.undirected_multigraph_no_multiedge_data)
357
+ assert nodes_equal(G.nodes(), PG.nodes())
358
+ assert edges_equal(G.edges(), PG.edges())
359
+
360
+ def test_read_undirected_multigraph_only_ids_for_multiedges_graphml(self):
361
+ G = self.multigraph_only_ids_for_multiedges
362
+ H = nx.read_graphml(self.multigraph_only_ids_for_multiedges_fh)
363
+ assert nodes_equal(G.nodes(), H.nodes())
364
+ assert edges_equal(G.edges(), H.edges())
365
+ self.multigraph_only_ids_for_multiedges_fh.seek(0)
366
+
367
+ PG = nx.parse_graphml(self.multigraph_only_ids_for_multiedges_data)
368
+ assert nodes_equal(G.nodes(), PG.nodes())
369
+ assert edges_equal(G.edges(), PG.edges())
370
+
371
+ def test_read_attribute_graphml(self):
372
+ G = self.attribute_graph
373
+ H = nx.read_graphml(self.attribute_fh)
374
+ assert nodes_equal(G.nodes(True), sorted(H.nodes(data=True)))
375
+ ge = sorted(G.edges(data=True))
376
+ he = sorted(H.edges(data=True))
377
+ for a, b in zip(ge, he):
378
+ assert a == b
379
+ self.attribute_fh.seek(0)
380
+
381
+ PG = nx.parse_graphml(self.attribute_data)
382
+ assert sorted(G.nodes(True)) == sorted(PG.nodes(data=True))
383
+ ge = sorted(G.edges(data=True))
384
+ he = sorted(PG.edges(data=True))
385
+ for a, b in zip(ge, he):
386
+ assert a == b
387
+
388
+ def test_node_default_attribute_graphml(self):
389
+ G = self.node_attribute_default_graph
390
+ H = nx.read_graphml(self.node_attribute_default_fh)
391
+ assert G.graph["node_default"] == H.graph["node_default"]
392
+
393
+ def test_directed_edge_in_undirected(self):
394
+ s = """<?xml version="1.0" encoding="UTF-8"?>
395
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
396
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
397
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
398
+ http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
399
+ <graph id="G">
400
+ <node id="n0"/>
401
+ <node id="n1"/>
402
+ <node id="n2"/>
403
+ <edge source="n0" target="n1"/>
404
+ <edge source="n1" target="n2" directed='true'/>
405
+ </graph>
406
+ </graphml>"""
407
+ fh = io.BytesIO(s.encode("UTF-8"))
408
+ pytest.raises(nx.NetworkXError, nx.read_graphml, fh)
409
+ pytest.raises(nx.NetworkXError, nx.parse_graphml, s)
410
+
411
+ def test_undirected_edge_in_directed(self):
412
+ s = """<?xml version="1.0" encoding="UTF-8"?>
413
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
414
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
415
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
416
+ http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
417
+ <graph id="G" edgedefault='directed'>
418
+ <node id="n0"/>
419
+ <node id="n1"/>
420
+ <node id="n2"/>
421
+ <edge source="n0" target="n1"/>
422
+ <edge source="n1" target="n2" directed='false'/>
423
+ </graph>
424
+ </graphml>"""
425
+ fh = io.BytesIO(s.encode("UTF-8"))
426
+ pytest.raises(nx.NetworkXError, nx.read_graphml, fh)
427
+ pytest.raises(nx.NetworkXError, nx.parse_graphml, s)
428
+
429
+ def test_key_raise(self):
430
+ s = """<?xml version="1.0" encoding="UTF-8"?>
431
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
432
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
433
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
434
+ http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
435
+ <key id="d0" for="node" attr.name="color" attr.type="string">
436
+ <default>yellow</default>
437
+ </key>
438
+ <key id="d1" for="edge" attr.name="weight" attr.type="double"/>
439
+ <graph id="G" edgedefault="directed">
440
+ <node id="n0">
441
+ <data key="d0">green</data>
442
+ </node>
443
+ <node id="n1"/>
444
+ <node id="n2">
445
+ <data key="d0">blue</data>
446
+ </node>
447
+ <edge id="e0" source="n0" target="n2">
448
+ <data key="d2">1.0</data>
449
+ </edge>
450
+ </graph>
451
+ </graphml>
452
+ """
453
+ fh = io.BytesIO(s.encode("UTF-8"))
454
+ pytest.raises(nx.NetworkXError, nx.read_graphml, fh)
455
+ pytest.raises(nx.NetworkXError, nx.parse_graphml, s)
456
+
457
+ def test_hyperedge_raise(self):
458
+ s = """<?xml version="1.0" encoding="UTF-8"?>
459
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
460
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
461
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
462
+ http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
463
+ <key id="d0" for="node" attr.name="color" attr.type="string">
464
+ <default>yellow</default>
465
+ </key>
466
+ <key id="d1" for="edge" attr.name="weight" attr.type="double"/>
467
+ <graph id="G" edgedefault="directed">
468
+ <node id="n0">
469
+ <data key="d0">green</data>
470
+ </node>
471
+ <node id="n1"/>
472
+ <node id="n2">
473
+ <data key="d0">blue</data>
474
+ </node>
475
+ <hyperedge id="e0" source="n0" target="n2">
476
+ <endpoint node="n0"/>
477
+ <endpoint node="n1"/>
478
+ <endpoint node="n2"/>
479
+ </hyperedge>
480
+ </graph>
481
+ </graphml>
482
+ """
483
+ fh = io.BytesIO(s.encode("UTF-8"))
484
+ pytest.raises(nx.NetworkXError, nx.read_graphml, fh)
485
+ pytest.raises(nx.NetworkXError, nx.parse_graphml, s)
486
+
487
+ def test_multigraph_keys(self):
488
+ # Test that reading multigraphs uses edge id attributes as keys
489
+ s = """<?xml version="1.0" encoding="UTF-8"?>
490
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
491
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
492
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
493
+ http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
494
+ <graph id="G" edgedefault="directed">
495
+ <node id="n0"/>
496
+ <node id="n1"/>
497
+ <edge id="e0" source="n0" target="n1"/>
498
+ <edge id="e1" source="n0" target="n1"/>
499
+ </graph>
500
+ </graphml>
501
+ """
502
+ fh = io.BytesIO(s.encode("UTF-8"))
503
+ G = nx.read_graphml(fh)
504
+ expected = [("n0", "n1", "e0"), ("n0", "n1", "e1")]
505
+ assert sorted(G.edges(keys=True)) == expected
506
+ fh.seek(0)
507
+ H = nx.parse_graphml(s)
508
+ assert sorted(H.edges(keys=True)) == expected
509
+
510
+ def test_preserve_multi_edge_data(self):
511
+ """
512
+ Test that data and keys of edges are preserved on consequent
513
+ write and reads
514
+ """
515
+ G = nx.MultiGraph()
516
+ G.add_node(1)
517
+ G.add_node(2)
518
+ G.add_edges_from(
519
+ [
520
+ # edges with no data, no keys:
521
+ (1, 2),
522
+ # edges with only data:
523
+ (1, 2, {"key": "data_key1"}),
524
+ (1, 2, {"id": "data_id2"}),
525
+ (1, 2, {"key": "data_key3", "id": "data_id3"}),
526
+ # edges with both data and keys:
527
+ (1, 2, 103, {"key": "data_key4"}),
528
+ (1, 2, 104, {"id": "data_id5"}),
529
+ (1, 2, 105, {"key": "data_key6", "id": "data_id7"}),
530
+ ]
531
+ )
532
+ fh = io.BytesIO()
533
+ nx.write_graphml(G, fh)
534
+ fh.seek(0)
535
+ H = nx.read_graphml(fh, node_type=int)
536
+ assert edges_equal(G.edges(data=True, keys=True), H.edges(data=True, keys=True))
537
+ assert G._adj == H._adj
538
+
539
+ Gadj = {
540
+ str(node): {
541
+ str(nbr): {str(ekey): dd for ekey, dd in key_dict.items()}
542
+ for nbr, key_dict in nbr_dict.items()
543
+ }
544
+ for node, nbr_dict in G._adj.items()
545
+ }
546
+ fh.seek(0)
547
+ HH = nx.read_graphml(fh, node_type=str, edge_key_type=str)
548
+ assert Gadj == HH._adj
549
+
550
+ fh.seek(0)
551
+ string_fh = fh.read()
552
+ HH = nx.parse_graphml(string_fh, node_type=str, edge_key_type=str)
553
+ assert Gadj == HH._adj
554
+
555
+ def test_yfiles_extension(self):
556
+ data = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
557
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
558
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
559
+ xmlns:y="http://www.yworks.com/xml/graphml"
560
+ xmlns:yed="http://www.yworks.com/xml/yed/3"
561
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
562
+ http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
563
+ <!--Created by yFiles for Java 2.7-->
564
+ <key for="graphml" id="d0" yfiles.type="resources"/>
565
+ <key attr.name="url" attr.type="string" for="node" id="d1"/>
566
+ <key attr.name="description" attr.type="string" for="node" id="d2"/>
567
+ <key for="node" id="d3" yfiles.type="nodegraphics"/>
568
+ <key attr.name="Description" attr.type="string" for="graph" id="d4">
569
+ <default/>
570
+ </key>
571
+ <key attr.name="url" attr.type="string" for="edge" id="d5"/>
572
+ <key attr.name="description" attr.type="string" for="edge" id="d6"/>
573
+ <key for="edge" id="d7" yfiles.type="edgegraphics"/>
574
+ <graph edgedefault="directed" id="G">
575
+ <node id="n0">
576
+ <data key="d3">
577
+ <y:ShapeNode>
578
+ <y:Geometry height="30.0" width="30.0" x="125.0" y="100.0"/>
579
+ <y:Fill color="#FFCC00" transparent="false"/>
580
+ <y:BorderStyle color="#000000" type="line" width="1.0"/>
581
+ <y:NodeLabel alignment="center" autoSizePolicy="content"
582
+ borderDistance="0.0" fontFamily="Dialog" fontSize="13"
583
+ fontStyle="plain" hasBackgroundColor="false" hasLineColor="false"
584
+ height="19.1328125" modelName="internal" modelPosition="c"
585
+ textColor="#000000" visible="true" width="12.27099609375"
586
+ x="8.864501953125" y="5.43359375">1</y:NodeLabel>
587
+ <y:Shape type="rectangle"/>
588
+ </y:ShapeNode>
589
+ </data>
590
+ </node>
591
+ <node id="n1">
592
+ <data key="d3">
593
+ <y:ShapeNode>
594
+ <y:Geometry height="30.0" width="30.0" x="183.0" y="205.0"/>
595
+ <y:Fill color="#FFCC00" transparent="false"/>
596
+ <y:BorderStyle color="#000000" type="line" width="1.0"/>
597
+ <y:NodeLabel alignment="center" autoSizePolicy="content"
598
+ borderDistance="0.0" fontFamily="Dialog" fontSize="13"
599
+ fontStyle="plain" hasBackgroundColor="false" hasLineColor="false"
600
+ height="19.1328125" modelName="internal" modelPosition="c"
601
+ textColor="#000000" visible="true" width="12.27099609375"
602
+ x="8.864501953125" y="5.43359375">2</y:NodeLabel>
603
+ <y:Shape type="rectangle"/>
604
+ </y:ShapeNode>
605
+ </data>
606
+ </node>
607
+ <node id="n2">
608
+ <data key="d6" xml:space="preserve"><![CDATA[description
609
+ line1
610
+ line2]]></data>
611
+ <data key="d3">
612
+ <y:GenericNode configuration="com.yworks.flowchart.terminator">
613
+ <y:Geometry height="40.0" width="80.0" x="950.0" y="286.0"/>
614
+ <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
615
+ <y:BorderStyle color="#000000" type="line" width="1.0"/>
616
+ <y:NodeLabel alignment="center" autoSizePolicy="content"
617
+ fontFamily="Dialog" fontSize="12" fontStyle="plain"
618
+ hasBackgroundColor="false" hasLineColor="false" height="17.96875"
619
+ horizontalTextPosition="center" iconTextGap="4" modelName="custom"
620
+ textColor="#000000" verticalTextPosition="bottom" visible="true"
621
+ width="67.984375" x="6.0078125" xml:space="preserve"
622
+ y="11.015625">3<y:LabelModel>
623
+ <y:SmartNodeLabelModel distance="4.0"/></y:LabelModel>
624
+ <y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0"
625
+ labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0"
626
+ offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
627
+ </y:GenericNode>
628
+ </data>
629
+ </node>
630
+ <edge id="e0" source="n0" target="n1">
631
+ <data key="d7">
632
+ <y:PolyLineEdge>
633
+ <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
634
+ <y:LineStyle color="#000000" type="line" width="1.0"/>
635
+ <y:Arrows source="none" target="standard"/>
636
+ <y:BendStyle smoothed="false"/>
637
+ </y:PolyLineEdge>
638
+ </data>
639
+ </edge>
640
+ </graph>
641
+ <data key="d0">
642
+ <y:Resources/>
643
+ </data>
644
+ </graphml>
645
+ """
646
+ fh = io.BytesIO(data.encode("UTF-8"))
647
+ G = nx.read_graphml(fh, force_multigraph=True)
648
+ assert list(G.edges()) == [("n0", "n1")]
649
+ assert G.has_edge("n0", "n1", key="e0")
650
+ assert G.nodes["n0"]["label"] == "1"
651
+ assert G.nodes["n1"]["label"] == "2"
652
+ assert G.nodes["n2"]["label"] == "3"
653
+ assert G.nodes["n0"]["shape_type"] == "rectangle"
654
+ assert G.nodes["n1"]["shape_type"] == "rectangle"
655
+ assert G.nodes["n2"]["shape_type"] == "com.yworks.flowchart.terminator"
656
+ assert G.nodes["n2"]["description"] == "description\nline1\nline2"
657
+ fh.seek(0)
658
+ G = nx.read_graphml(fh)
659
+ assert list(G.edges()) == [("n0", "n1")]
660
+ assert G["n0"]["n1"]["id"] == "e0"
661
+ assert G.nodes["n0"]["label"] == "1"
662
+ assert G.nodes["n1"]["label"] == "2"
663
+ assert G.nodes["n2"]["label"] == "3"
664
+ assert G.nodes["n0"]["shape_type"] == "rectangle"
665
+ assert G.nodes["n1"]["shape_type"] == "rectangle"
666
+ assert G.nodes["n2"]["shape_type"] == "com.yworks.flowchart.terminator"
667
+ assert G.nodes["n2"]["description"] == "description\nline1\nline2"
668
+
669
+ H = nx.parse_graphml(data, force_multigraph=True)
670
+ assert list(H.edges()) == [("n0", "n1")]
671
+ assert H.has_edge("n0", "n1", key="e0")
672
+ assert H.nodes["n0"]["label"] == "1"
673
+ assert H.nodes["n1"]["label"] == "2"
674
+ assert H.nodes["n2"]["label"] == "3"
675
+
676
+ H = nx.parse_graphml(data)
677
+ assert list(H.edges()) == [("n0", "n1")]
678
+ assert H["n0"]["n1"]["id"] == "e0"
679
+ assert H.nodes["n0"]["label"] == "1"
680
+ assert H.nodes["n1"]["label"] == "2"
681
+ assert H.nodes["n2"]["label"] == "3"
682
+
683
+ def test_bool(self):
684
+ s = """<?xml version="1.0" encoding="UTF-8"?>
685
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
686
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
687
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
688
+ http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
689
+ <key id="d0" for="node" attr.name="test" attr.type="boolean">
690
+ <default>false</default>
691
+ </key>
692
+ <graph id="G" edgedefault="directed">
693
+ <node id="n0">
694
+ <data key="d0">true</data>
695
+ </node>
696
+ <node id="n1"/>
697
+ <node id="n2">
698
+ <data key="d0">false</data>
699
+ </node>
700
+ <node id="n3">
701
+ <data key="d0">FaLsE</data>
702
+ </node>
703
+ <node id="n4">
704
+ <data key="d0">True</data>
705
+ </node>
706
+ <node id="n5">
707
+ <data key="d0">0</data>
708
+ </node>
709
+ <node id="n6">
710
+ <data key="d0">1</data>
711
+ </node>
712
+ </graph>
713
+ </graphml>
714
+ """
715
+ fh = io.BytesIO(s.encode("UTF-8"))
716
+ G = nx.read_graphml(fh)
717
+ H = nx.parse_graphml(s)
718
+ for graph in [G, H]:
719
+ assert graph.nodes["n0"]["test"]
720
+ assert not graph.nodes["n2"]["test"]
721
+ assert not graph.nodes["n3"]["test"]
722
+ assert graph.nodes["n4"]["test"]
723
+ assert not graph.nodes["n5"]["test"]
724
+ assert graph.nodes["n6"]["test"]
725
+
726
+ def test_graphml_header_line(self):
727
+ good = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
728
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
729
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
730
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
731
+ http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
732
+ <key id="d0" for="node" attr.name="test" attr.type="boolean">
733
+ <default>false</default>
734
+ </key>
735
+ <graph id="G">
736
+ <node id="n0">
737
+ <data key="d0">true</data>
738
+ </node>
739
+ </graph>
740
+ </graphml>
741
+ """
742
+ bad = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
743
+ <graphml>
744
+ <key id="d0" for="node" attr.name="test" attr.type="boolean">
745
+ <default>false</default>
746
+ </key>
747
+ <graph id="G">
748
+ <node id="n0">
749
+ <data key="d0">true</data>
750
+ </node>
751
+ </graph>
752
+ </graphml>
753
+ """
754
+ ugly = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
755
+ <graphml xmlns="https://ghghgh">
756
+ <key id="d0" for="node" attr.name="test" attr.type="boolean">
757
+ <default>false</default>
758
+ </key>
759
+ <graph id="G">
760
+ <node id="n0">
761
+ <data key="d0">true</data>
762
+ </node>
763
+ </graph>
764
+ </graphml>
765
+ """
766
+ for s in (good, bad):
767
+ fh = io.BytesIO(s.encode("UTF-8"))
768
+ G = nx.read_graphml(fh)
769
+ H = nx.parse_graphml(s)
770
+ for graph in [G, H]:
771
+ assert graph.nodes["n0"]["test"]
772
+
773
+ fh = io.BytesIO(ugly.encode("UTF-8"))
774
+ pytest.raises(nx.NetworkXError, nx.read_graphml, fh)
775
+ pytest.raises(nx.NetworkXError, nx.parse_graphml, ugly)
776
+
777
+ def test_read_attributes_with_groups(self):
778
+ data = """\
779
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
780
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
781
+ <!--Created by yEd 3.17-->
782
+ <key attr.name="Description" attr.type="string" for="graph" id="d0"/>
783
+ <key for="port" id="d1" yfiles.type="portgraphics"/>
784
+ <key for="port" id="d2" yfiles.type="portgeometry"/>
785
+ <key for="port" id="d3" yfiles.type="portuserdata"/>
786
+ <key attr.name="CustomProperty" attr.type="string" for="node" id="d4">
787
+ <default/>
788
+ </key>
789
+ <key attr.name="url" attr.type="string" for="node" id="d5"/>
790
+ <key attr.name="description" attr.type="string" for="node" id="d6"/>
791
+ <key for="node" id="d7" yfiles.type="nodegraphics"/>
792
+ <key for="graphml" id="d8" yfiles.type="resources"/>
793
+ <key attr.name="url" attr.type="string" for="edge" id="d9"/>
794
+ <key attr.name="description" attr.type="string" for="edge" id="d10"/>
795
+ <key for="edge" id="d11" yfiles.type="edgegraphics"/>
796
+ <graph edgedefault="directed" id="G">
797
+ <data key="d0"/>
798
+ <node id="n0">
799
+ <data key="d4"><![CDATA[CustomPropertyValue]]></data>
800
+ <data key="d6"/>
801
+ <data key="d7">
802
+ <y:ShapeNode>
803
+ <y:Geometry height="30.0" width="30.0" x="125.0" y="-255.4611111111111"/>
804
+ <y:Fill color="#FFCC00" transparent="false"/>
805
+ <y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
806
+ <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="11.634765625" x="9.1826171875" y="6.015625">2<y:LabelModel>
807
+ <y:SmartNodeLabelModel distance="4.0"/>
808
+ </y:LabelModel>
809
+ <y:ModelParameter>
810
+ <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
811
+ </y:ModelParameter>
812
+ </y:NodeLabel>
813
+ <y:Shape type="rectangle"/>
814
+ </y:ShapeNode>
815
+ </data>
816
+ </node>
817
+ <node id="n1" yfiles.foldertype="group">
818
+ <data key="d4"><![CDATA[CustomPropertyValue]]></data>
819
+ <data key="d5"/>
820
+ <data key="d6"/>
821
+ <data key="d7">
822
+ <y:ProxyAutoBoundsNode>
823
+ <y:Realizers active="0">
824
+ <y:GroupNode>
825
+ <y:Geometry height="250.38333333333333" width="140.0" x="-30.0" y="-330.3833333333333"/>
826
+ <y:Fill color="#F5F5F5" transparent="false"/>
827
+ <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
828
+ <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.4609375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="140.0" x="0.0" y="0.0">Group 3</y:NodeLabel>
829
+ <y:Shape type="roundrectangle"/>
830
+ <y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
831
+ <y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
832
+ <y:BorderInsets bottom="1" bottomF="1.0" left="0" leftF="0.0" right="0" rightF="0.0" top="1" topF="1.0001736111111086"/>
833
+ </y:GroupNode>
834
+ <y:GroupNode>
835
+ <y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
836
+ <y:Fill color="#F5F5F5" transparent="false"/>
837
+ <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
838
+ <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.4609375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="65.201171875" x="-7.6005859375" y="0.0">Folder 3</y:NodeLabel>
839
+ <y:Shape type="roundrectangle"/>
840
+ <y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
841
+ <y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
842
+ <y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
843
+ </y:GroupNode>
844
+ </y:Realizers>
845
+ </y:ProxyAutoBoundsNode>
846
+ </data>
847
+ <graph edgedefault="directed" id="n1:">
848
+ <node id="n1::n0" yfiles.foldertype="group">
849
+ <data key="d4"><![CDATA[CustomPropertyValue]]></data>
850
+ <data key="d5"/>
851
+ <data key="d6"/>
852
+ <data key="d7">
853
+ <y:ProxyAutoBoundsNode>
854
+ <y:Realizers active="0">
855
+ <y:GroupNode>
856
+ <y:Geometry height="83.46111111111111" width="110.0" x="-15.0" y="-292.9222222222222"/>
857
+ <y:Fill color="#F5F5F5" transparent="false"/>
858
+ <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
859
+ <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.4609375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="110.0" x="0.0" y="0.0">Group 1</y:NodeLabel>
860
+ <y:Shape type="roundrectangle"/>
861
+ <y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
862
+ <y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
863
+ <y:BorderInsets bottom="1" bottomF="1.0" left="0" leftF="0.0" right="0" rightF="0.0" top="1" topF="1.0001736111111086"/>
864
+ </y:GroupNode>
865
+ <y:GroupNode>
866
+ <y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
867
+ <y:Fill color="#F5F5F5" transparent="false"/>
868
+ <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
869
+ <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.4609375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="65.201171875" x="-7.6005859375" y="0.0">Folder 1</y:NodeLabel>
870
+ <y:Shape type="roundrectangle"/>
871
+ <y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
872
+ <y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
873
+ <y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
874
+ </y:GroupNode>
875
+ </y:Realizers>
876
+ </y:ProxyAutoBoundsNode>
877
+ </data>
878
+ <graph edgedefault="directed" id="n1::n0:">
879
+ <node id="n1::n0::n0">
880
+ <data key="d4"><![CDATA[CustomPropertyValue]]></data>
881
+ <data key="d6"/>
882
+ <data key="d7">
883
+ <y:ShapeNode>
884
+ <y:Geometry height="30.0" width="30.0" x="50.0" y="-255.4611111111111"/>
885
+ <y:Fill color="#FFCC00" transparent="false"/>
886
+ <y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
887
+ <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="11.634765625" x="9.1826171875" y="6.015625">1<y:LabelModel>
888
+ <y:SmartNodeLabelModel distance="4.0"/>
889
+ </y:LabelModel>
890
+ <y:ModelParameter>
891
+ <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
892
+ </y:ModelParameter>
893
+ </y:NodeLabel>
894
+ <y:Shape type="rectangle"/>
895
+ </y:ShapeNode>
896
+ </data>
897
+ </node>
898
+ <node id="n1::n0::n1">
899
+ <data key="d4"><![CDATA[CustomPropertyValue]]></data>
900
+ <data key="d6"/>
901
+ <data key="d7">
902
+ <y:ShapeNode>
903
+ <y:Geometry height="30.0" width="30.0" x="0.0" y="-255.4611111111111"/>
904
+ <y:Fill color="#FFCC00" transparent="false"/>
905
+ <y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
906
+ <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="11.634765625" x="9.1826171875" y="6.015625">3<y:LabelModel>
907
+ <y:SmartNodeLabelModel distance="4.0"/>
908
+ </y:LabelModel>
909
+ <y:ModelParameter>
910
+ <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
911
+ </y:ModelParameter>
912
+ </y:NodeLabel>
913
+ <y:Shape type="rectangle"/>
914
+ </y:ShapeNode>
915
+ </data>
916
+ </node>
917
+ </graph>
918
+ </node>
919
+ <node id="n1::n1" yfiles.foldertype="group">
920
+ <data key="d4"><![CDATA[CustomPropertyValue]]></data>
921
+ <data key="d5"/>
922
+ <data key="d6"/>
923
+ <data key="d7">
924
+ <y:ProxyAutoBoundsNode>
925
+ <y:Realizers active="0">
926
+ <y:GroupNode>
927
+ <y:Geometry height="83.46111111111111" width="110.0" x="-15.0" y="-179.4611111111111"/>
928
+ <y:Fill color="#F5F5F5" transparent="false"/>
929
+ <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
930
+ <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.4609375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="110.0" x="0.0" y="0.0">Group 2</y:NodeLabel>
931
+ <y:Shape type="roundrectangle"/>
932
+ <y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
933
+ <y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
934
+ <y:BorderInsets bottom="1" bottomF="1.0" left="0" leftF="0.0" right="0" rightF="0.0" top="1" topF="1.0001736111111086"/>
935
+ </y:GroupNode>
936
+ <y:GroupNode>
937
+ <y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
938
+ <y:Fill color="#F5F5F5" transparent="false"/>
939
+ <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
940
+ <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.4609375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="65.201171875" x="-7.6005859375" y="0.0">Folder 2</y:NodeLabel>
941
+ <y:Shape type="roundrectangle"/>
942
+ <y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
943
+ <y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
944
+ <y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
945
+ </y:GroupNode>
946
+ </y:Realizers>
947
+ </y:ProxyAutoBoundsNode>
948
+ </data>
949
+ <graph edgedefault="directed" id="n1::n1:">
950
+ <node id="n1::n1::n0">
951
+ <data key="d4"><![CDATA[CustomPropertyValue]]></data>
952
+ <data key="d6"/>
953
+ <data key="d7">
954
+ <y:ShapeNode>
955
+ <y:Geometry height="30.0" width="30.0" x="0.0" y="-142.0"/>
956
+ <y:Fill color="#FFCC00" transparent="false"/>
957
+ <y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
958
+ <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="11.634765625" x="9.1826171875" y="6.015625">5<y:LabelModel>
959
+ <y:SmartNodeLabelModel distance="4.0"/>
960
+ </y:LabelModel>
961
+ <y:ModelParameter>
962
+ <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
963
+ </y:ModelParameter>
964
+ </y:NodeLabel>
965
+ <y:Shape type="rectangle"/>
966
+ </y:ShapeNode>
967
+ </data>
968
+ </node>
969
+ <node id="n1::n1::n1">
970
+ <data key="d4"><![CDATA[CustomPropertyValue]]></data>
971
+ <data key="d6"/>
972
+ <data key="d7">
973
+ <y:ShapeNode>
974
+ <y:Geometry height="30.0" width="30.0" x="50.0" y="-142.0"/>
975
+ <y:Fill color="#FFCC00" transparent="false"/>
976
+ <y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
977
+ <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="11.634765625" x="9.1826171875" y="6.015625">6<y:LabelModel>
978
+ <y:SmartNodeLabelModel distance="4.0"/>
979
+ </y:LabelModel>
980
+ <y:ModelParameter>
981
+ <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
982
+ </y:ModelParameter>
983
+ </y:NodeLabel>
984
+ <y:Shape type="rectangle"/>
985
+ </y:ShapeNode>
986
+ </data>
987
+ </node>
988
+ </graph>
989
+ </node>
990
+ </graph>
991
+ </node>
992
+ <node id="n2">
993
+ <data key="d4"><![CDATA[CustomPropertyValue]]></data>
994
+ <data key="d6"/>
995
+ <data key="d7">
996
+ <y:ShapeNode>
997
+ <y:Geometry height="30.0" width="30.0" x="125.0" y="-142.0"/>
998
+ <y:Fill color="#FFCC00" transparent="false"/>
999
+ <y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
1000
+ <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="11.634765625" x="9.1826171875" y="6.015625">9<y:LabelModel>
1001
+ <y:SmartNodeLabelModel distance="4.0"/>
1002
+ </y:LabelModel>
1003
+ <y:ModelParameter>
1004
+ <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
1005
+ </y:ModelParameter>
1006
+ </y:NodeLabel>
1007
+ <y:Shape type="rectangle"/>
1008
+ </y:ShapeNode>
1009
+ </data>
1010
+ </node>
1011
+ <edge id="n1::n1::e0" source="n1::n1::n0" target="n1::n1::n1">
1012
+ <data key="d10"/>
1013
+ <data key="d11">
1014
+ <y:PolyLineEdge>
1015
+ <y:Path sx="15.0" sy="-0.0" tx="-15.0" ty="-0.0"/>
1016
+ <y:LineStyle color="#000000" type="line" width="1.0"/>
1017
+ <y:Arrows source="none" target="standard"/>
1018
+ <y:BendStyle smoothed="false"/>
1019
+ </y:PolyLineEdge>
1020
+ </data>
1021
+ </edge>
1022
+ <edge id="n1::n0::e0" source="n1::n0::n1" target="n1::n0::n0">
1023
+ <data key="d10"/>
1024
+ <data key="d11">
1025
+ <y:PolyLineEdge>
1026
+ <y:Path sx="15.0" sy="-0.0" tx="-15.0" ty="-0.0"/>
1027
+ <y:LineStyle color="#000000" type="line" width="1.0"/>
1028
+ <y:Arrows source="none" target="standard"/>
1029
+ <y:BendStyle smoothed="false"/>
1030
+ </y:PolyLineEdge>
1031
+ </data>
1032
+ </edge>
1033
+ <edge id="e0" source="n1::n0::n0" target="n0">
1034
+ <data key="d10"/>
1035
+ <data key="d11">
1036
+ <y:PolyLineEdge>
1037
+ <y:Path sx="15.0" sy="-0.0" tx="-15.0" ty="-0.0"/>
1038
+ <y:LineStyle color="#000000" type="line" width="1.0"/>
1039
+ <y:Arrows source="none" target="standard"/>
1040
+ <y:BendStyle smoothed="false"/>
1041
+ </y:PolyLineEdge>
1042
+ </data>
1043
+ </edge>
1044
+ <edge id="e1" source="n1::n1::n1" target="n2">
1045
+ <data key="d10"/>
1046
+ <data key="d11">
1047
+ <y:PolyLineEdge>
1048
+ <y:Path sx="15.0" sy="-0.0" tx="-15.0" ty="-0.0"/>
1049
+ <y:LineStyle color="#000000" type="line" width="1.0"/>
1050
+ <y:Arrows source="none" target="standard"/>
1051
+ <y:BendStyle smoothed="false"/>
1052
+ </y:PolyLineEdge>
1053
+ </data>
1054
+ </edge>
1055
+ </graph>
1056
+ <data key="d8">
1057
+ <y:Resources/>
1058
+ </data>
1059
+ </graphml>
1060
+ """
1061
+ # verify that nodes / attributes are correctly read when part of a group
1062
+ fh = io.BytesIO(data.encode("UTF-8"))
1063
+ G = nx.read_graphml(fh)
1064
+ data = [x for _, x in G.nodes(data=True)]
1065
+ assert len(data) == 9
1066
+ for node_data in data:
1067
+ assert node_data["CustomProperty"] != ""
1068
+
1069
+ def test_long_attribute_type(self):
1070
+ # test that graphs with attr.type="long" (as produced by botch and
1071
+ # dose3) can be parsed
1072
+ s = """<?xml version='1.0' encoding='utf-8'?>
1073
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
1074
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1075
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
1076
+ http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
1077
+ <key attr.name="cudfversion" attr.type="long" for="node" id="d6" />
1078
+ <graph edgedefault="directed">
1079
+ <node id="n1">
1080
+ <data key="d6">4284</data>
1081
+ </node>
1082
+ </graph>
1083
+ </graphml>"""
1084
+ fh = io.BytesIO(s.encode("UTF-8"))
1085
+ G = nx.read_graphml(fh)
1086
+ expected = [("n1", {"cudfversion": 4284})]
1087
+ assert sorted(G.nodes(data=True)) == expected
1088
+ fh.seek(0)
1089
+ H = nx.parse_graphml(s)
1090
+ assert sorted(H.nodes(data=True)) == expected
1091
+
1092
+
1093
+ class TestWriteGraphML(BaseGraphML):
1094
+ writer = staticmethod(nx.write_graphml_lxml)
1095
+
1096
+ @classmethod
1097
+ def setup_class(cls):
1098
+ BaseGraphML.setup_class()
1099
+ _ = pytest.importorskip("lxml.etree")
1100
+
1101
+ def test_write_interface(self):
1102
+ try:
1103
+ import lxml.etree
1104
+
1105
+ assert nx.write_graphml == nx.write_graphml_lxml
1106
+ except ImportError:
1107
+ assert nx.write_graphml == nx.write_graphml_xml
1108
+
1109
+ def test_write_read_simple_directed_graphml(self):
1110
+ G = self.simple_directed_graph
1111
+ G.graph["hi"] = "there"
1112
+ fh = io.BytesIO()
1113
+ self.writer(G, fh)
1114
+ fh.seek(0)
1115
+ H = nx.read_graphml(fh)
1116
+ assert sorted(G.nodes()) == sorted(H.nodes())
1117
+ assert sorted(G.edges()) == sorted(H.edges())
1118
+ assert sorted(G.edges(data=True)) == sorted(H.edges(data=True))
1119
+ self.simple_directed_fh.seek(0)
1120
+
1121
+ def test_GraphMLWriter_add_graphs(self):
1122
+ gmlw = GraphMLWriter()
1123
+ G = self.simple_directed_graph
1124
+ H = G.copy()
1125
+ gmlw.add_graphs([G, H])
1126
+
1127
+ def test_write_read_simple_no_prettyprint(self):
1128
+ G = self.simple_directed_graph
1129
+ G.graph["hi"] = "there"
1130
+ G.graph["id"] = "1"
1131
+ fh = io.BytesIO()
1132
+ self.writer(G, fh, prettyprint=False)
1133
+ fh.seek(0)
1134
+ H = nx.read_graphml(fh)
1135
+ assert sorted(G.nodes()) == sorted(H.nodes())
1136
+ assert sorted(G.edges()) == sorted(H.edges())
1137
+ assert sorted(G.edges(data=True)) == sorted(H.edges(data=True))
1138
+ self.simple_directed_fh.seek(0)
1139
+
1140
+ def test_write_read_attribute_named_key_ids_graphml(self):
1141
+ from xml.etree.ElementTree import parse
1142
+
1143
+ G = self.attribute_named_key_ids_graph
1144
+ fh = io.BytesIO()
1145
+ self.writer(G, fh, named_key_ids=True)
1146
+ fh.seek(0)
1147
+ H = nx.read_graphml(fh)
1148
+ fh.seek(0)
1149
+
1150
+ assert nodes_equal(G.nodes(), H.nodes())
1151
+ assert edges_equal(G.edges(), H.edges(), directed=True)
1152
+ assert edges_equal(G.edges(data=True), H.edges(data=True), directed=True)
1153
+ self.attribute_named_key_ids_fh.seek(0)
1154
+
1155
+ xml = parse(fh)
1156
+ # Children are the key elements, and the graph element
1157
+ children = list(xml.getroot())
1158
+ assert len(children) == 4
1159
+
1160
+ keys = [child.items() for child in children[:3]]
1161
+
1162
+ assert len(keys) == 3
1163
+ assert ("id", "edge_prop") in keys[0]
1164
+ assert ("attr.name", "edge_prop") in keys[0]
1165
+ assert ("id", "prop2") in keys[1]
1166
+ assert ("attr.name", "prop2") in keys[1]
1167
+ assert ("id", "prop1") in keys[2]
1168
+ assert ("attr.name", "prop1") in keys[2]
1169
+
1170
+ # Confirm the read graph nodes/edge are identical when compared to
1171
+ # default writing behavior.
1172
+ default_behavior_fh = io.BytesIO()
1173
+ nx.write_graphml(G, default_behavior_fh)
1174
+ default_behavior_fh.seek(0)
1175
+ H = nx.read_graphml(default_behavior_fh)
1176
+
1177
+ named_key_ids_behavior_fh = io.BytesIO()
1178
+ nx.write_graphml(G, named_key_ids_behavior_fh, named_key_ids=True)
1179
+ named_key_ids_behavior_fh.seek(0)
1180
+ J = nx.read_graphml(named_key_ids_behavior_fh)
1181
+
1182
+ assert all(n1 == n2 for (n1, n2) in zip(H.nodes, J.nodes))
1183
+ assert all(e1 == e2 for (e1, e2) in zip(H.edges, J.edges))
1184
+
1185
+ def test_write_read_attribute_numeric_type_graphml(self):
1186
+ from xml.etree.ElementTree import parse
1187
+
1188
+ G = self.attribute_numeric_type_graph
1189
+ fh = io.BytesIO()
1190
+ self.writer(G, fh, infer_numeric_types=True)
1191
+ fh.seek(0)
1192
+ H = nx.read_graphml(fh)
1193
+ fh.seek(0)
1194
+
1195
+ assert nodes_equal(G.nodes(), H.nodes())
1196
+ assert edges_equal(G.edges(), H.edges(), directed=True)
1197
+ assert edges_equal(G.edges(data=True), H.edges(data=True), directed=True)
1198
+ self.attribute_numeric_type_fh.seek(0)
1199
+
1200
+ xml = parse(fh)
1201
+ # Children are the key elements, and the graph element
1202
+ children = list(xml.getroot())
1203
+ assert len(children) == 3
1204
+
1205
+ keys = [child.items() for child in children[:2]]
1206
+
1207
+ assert len(keys) == 2
1208
+ assert ("attr.type", "double") in keys[0]
1209
+ assert ("attr.type", "double") in keys[1]
1210
+
1211
+ def test_more_multigraph_keys(self, tmp_path):
1212
+ """Writing keys as edge id attributes means keys become strings.
1213
+ The original keys are stored as data, so read them back in
1214
+ if `str(key) == edge_id`
1215
+ This allows the adjacency to remain the same.
1216
+ """
1217
+ G = nx.MultiGraph()
1218
+ G.add_edges_from([("a", "b", 2), ("a", "b", 3)])
1219
+ fname = tmp_path / "test.graphml"
1220
+ self.writer(G, fname)
1221
+ H = nx.read_graphml(fname)
1222
+ assert H.is_multigraph()
1223
+ assert edges_equal(G.edges(keys=True), H.edges(keys=True))
1224
+ assert G._adj == H._adj
1225
+
1226
+ def test_default_attribute(self):
1227
+ G = nx.Graph(name="Fred")
1228
+ G.add_node(1, label=1, color="green")
1229
+ nx.add_path(G, [0, 1, 2, 3])
1230
+ G.add_edge(1, 2, weight=3)
1231
+ G.graph["node_default"] = {"color": "yellow"}
1232
+ G.graph["edge_default"] = {"weight": 7}
1233
+ fh = io.BytesIO()
1234
+ self.writer(G, fh)
1235
+ fh.seek(0)
1236
+ H = nx.read_graphml(fh, node_type=int)
1237
+ assert nodes_equal(G.nodes(), H.nodes())
1238
+ assert edges_equal(G.edges(), H.edges())
1239
+ assert G.graph == H.graph
1240
+
1241
+ def test_mixed_type_attributes(self):
1242
+ G = nx.MultiGraph()
1243
+ G.add_node("n0", special=False)
1244
+ G.add_node("n1", special=0)
1245
+ G.add_edge("n0", "n1", special=False)
1246
+ G.add_edge("n0", "n1", special=0)
1247
+ fh = io.BytesIO()
1248
+ self.writer(G, fh)
1249
+ fh.seek(0)
1250
+ H = nx.read_graphml(fh)
1251
+ assert not H.nodes["n0"]["special"]
1252
+ assert H.nodes["n1"]["special"] == 0
1253
+ assert not H.edges["n0", "n1", 0]["special"]
1254
+ assert H.edges["n0", "n1", 1]["special"] == 0
1255
+
1256
+ def test_str_number_mixed_type_attributes(self):
1257
+ G = nx.MultiGraph()
1258
+ G.add_node("n0", special="hello")
1259
+ G.add_node("n1", special=0)
1260
+ G.add_edge("n0", "n1", special="hello")
1261
+ G.add_edge("n0", "n1", special=0)
1262
+ fh = io.BytesIO()
1263
+ self.writer(G, fh)
1264
+ fh.seek(0)
1265
+ H = nx.read_graphml(fh)
1266
+ assert H.nodes["n0"]["special"] == "hello"
1267
+ assert H.nodes["n1"]["special"] == 0
1268
+ assert H.edges["n0", "n1", 0]["special"] == "hello"
1269
+ assert H.edges["n0", "n1", 1]["special"] == 0
1270
+
1271
+ def test_mixed_int_type_number_attributes(self):
1272
+ np = pytest.importorskip("numpy")
1273
+ G = nx.MultiGraph()
1274
+ G.add_node("n0", special=np.int64(0))
1275
+ G.add_node("n1", special=1)
1276
+ G.add_edge("n0", "n1", special=np.int64(2))
1277
+ G.add_edge("n0", "n1", special=3)
1278
+ fh = io.BytesIO()
1279
+ self.writer(G, fh)
1280
+ fh.seek(0)
1281
+ H = nx.read_graphml(fh)
1282
+ assert H.nodes["n0"]["special"] == 0
1283
+ assert H.nodes["n1"]["special"] == 1
1284
+ assert H.edges["n0", "n1", 0]["special"] == 2
1285
+ assert H.edges["n0", "n1", 1]["special"] == 3
1286
+
1287
+ def test_multigraph_to_graph(self, tmp_path):
1288
+ # test converting multigraph to graph if no parallel edges found
1289
+ G = nx.MultiGraph()
1290
+ G.add_edges_from([("a", "b", 2), ("b", "c", 3)]) # no multiedges
1291
+ fname = tmp_path / "test.graphml"
1292
+ self.writer(G, fname)
1293
+ H = nx.read_graphml(fname)
1294
+ assert not H.is_multigraph()
1295
+ H = nx.read_graphml(fname, force_multigraph=True)
1296
+ assert H.is_multigraph()
1297
+
1298
+ # add a multiedge
1299
+ G.add_edge("a", "b", "e-id")
1300
+ fname = tmp_path / "test.graphml"
1301
+ self.writer(G, fname)
1302
+ H = nx.read_graphml(fname)
1303
+ assert H.is_multigraph()
1304
+ H = nx.read_graphml(fname, force_multigraph=True)
1305
+ assert H.is_multigraph()
1306
+
1307
+ def test_write_generate_edge_id_from_attribute(self, tmp_path):
1308
+ from xml.etree.ElementTree import parse
1309
+
1310
+ G = nx.Graph()
1311
+ G.add_edges_from([("a", "b"), ("b", "c"), ("a", "c")])
1312
+ edge_attributes = {e: str(e) for e in G.edges}
1313
+ nx.set_edge_attributes(G, edge_attributes, "eid")
1314
+ fname = tmp_path / "test.graphml"
1315
+ # set edge_id_from_attribute e.g. "eid" for write_graphml()
1316
+ self.writer(G, fname, edge_id_from_attribute="eid")
1317
+ # set edge_id_from_attribute e.g. "eid" for generate_graphml()
1318
+ generator = nx.generate_graphml(G, edge_id_from_attribute="eid")
1319
+
1320
+ H = nx.read_graphml(fname)
1321
+ assert nodes_equal(G.nodes(), H.nodes())
1322
+ assert edges_equal(G.edges(), H.edges())
1323
+ # NetworkX adds explicit edge "id" from file as attribute
1324
+ nx.set_edge_attributes(G, edge_attributes, "id")
1325
+ assert edges_equal(G.edges(data=True), H.edges(data=True))
1326
+
1327
+ tree = parse(fname)
1328
+ children = list(tree.getroot())
1329
+ assert len(children) == 2
1330
+ edge_ids = [
1331
+ edge.attrib["id"]
1332
+ for edge in tree.getroot().findall(
1333
+ ".//{http://graphml.graphdrawing.org/xmlns}edge"
1334
+ )
1335
+ ]
1336
+ # verify edge id value is equal to specified attribute value
1337
+ assert sorted(edge_ids) == sorted(edge_attributes.values())
1338
+
1339
+ # check graphml generated from generate_graphml()
1340
+ data = "".join(generator)
1341
+ J = nx.parse_graphml(data)
1342
+ assert sorted(G.nodes()) == sorted(J.nodes())
1343
+ assert sorted(G.edges()) == sorted(J.edges())
1344
+ # NetworkX adds explicit edge "id" from file as attribute
1345
+ nx.set_edge_attributes(G, edge_attributes, "id")
1346
+ assert edges_equal(G.edges(data=True), J.edges(data=True))
1347
+
1348
+ def test_multigraph_write_generate_edge_id_from_attribute(self, tmp_path):
1349
+ from xml.etree.ElementTree import parse
1350
+
1351
+ G = nx.MultiGraph()
1352
+ G.add_edges_from([("a", "b"), ("b", "c"), ("a", "c"), ("a", "b")])
1353
+ edge_attributes = {e: str(e) for e in G.edges}
1354
+ nx.set_edge_attributes(G, edge_attributes, "eid")
1355
+ fname = tmp_path / "test.graphml"
1356
+ # set edge_id_from_attribute e.g. "eid" for write_graphml()
1357
+ self.writer(G, fname, edge_id_from_attribute="eid")
1358
+ # set edge_id_from_attribute e.g. "eid" for generate_graphml()
1359
+ generator = nx.generate_graphml(G, edge_id_from_attribute="eid")
1360
+
1361
+ H = nx.read_graphml(fname)
1362
+ assert H.is_multigraph()
1363
+ H = nx.read_graphml(fname, force_multigraph=True)
1364
+ assert H.is_multigraph()
1365
+
1366
+ assert nodes_equal(G.nodes(), H.nodes())
1367
+ assert edges_equal(G.edges(), H.edges())
1368
+ assert sorted(data.get("eid") for u, v, data in H.edges(data=True)) == sorted(
1369
+ edge_attributes.values()
1370
+ )
1371
+ # NetworkX uses edge_ids as keys in multigraphs if no key
1372
+ assert sorted(key for u, v, key in H.edges(keys=True)) == sorted(
1373
+ edge_attributes.values()
1374
+ )
1375
+
1376
+ tree = parse(fname)
1377
+ children = list(tree.getroot())
1378
+ assert len(children) == 2
1379
+ edge_ids = [
1380
+ edge.attrib["id"]
1381
+ for edge in tree.getroot().findall(
1382
+ ".//{http://graphml.graphdrawing.org/xmlns}edge"
1383
+ )
1384
+ ]
1385
+ # verify edge id value is equal to specified attribute value
1386
+ assert sorted(edge_ids) == sorted(edge_attributes.values())
1387
+
1388
+ # check graphml generated from generate_graphml()
1389
+ graphml_data = "".join(generator)
1390
+ J = nx.parse_graphml(graphml_data)
1391
+ assert J.is_multigraph()
1392
+
1393
+ assert nodes_equal(G.nodes(), J.nodes())
1394
+ assert edges_equal(G.edges(), J.edges())
1395
+ assert sorted(data.get("eid") for u, v, data in J.edges(data=True)) == sorted(
1396
+ edge_attributes.values()
1397
+ )
1398
+ # NetworkX uses edge_ids as keys in multigraphs if no key
1399
+ assert sorted(key for u, v, key in J.edges(keys=True)) == sorted(
1400
+ edge_attributes.values()
1401
+ )
1402
+
1403
+ def test_numpy_float64(self, tmp_path):
1404
+ np = pytest.importorskip("numpy")
1405
+ wt = np.float64(3.4)
1406
+ G = nx.Graph([(1, 2, {"weight": wt})])
1407
+ fname = tmp_path / "test.graphml"
1408
+ self.writer(G, fname)
1409
+ H = nx.read_graphml(fname, node_type=int)
1410
+ assert G.edges == H.edges
1411
+ wtG = G[1][2]["weight"]
1412
+ wtH = H[1][2]["weight"]
1413
+ assert wtG == pytest.approx(wtH, abs=1e-6)
1414
+ assert type(wtG) is np.float64
1415
+ assert type(wtH) is float
1416
+
1417
+ def test_numpy_float32(self, tmp_path):
1418
+ np = pytest.importorskip("numpy")
1419
+ wt = np.float32(3.4)
1420
+ G = nx.Graph([(1, 2, {"weight": wt})])
1421
+ fname = tmp_path / "test.graphml"
1422
+ self.writer(G, fname)
1423
+ H = nx.read_graphml(fname, node_type=int)
1424
+ assert G.edges == H.edges
1425
+ wtG = G[1][2]["weight"]
1426
+ wtH = H[1][2]["weight"]
1427
+ assert wtG == pytest.approx(wtH, abs=1e-6)
1428
+ assert type(wtG) is np.float32
1429
+ assert type(wtH) is float
1430
+
1431
+ def test_numpy_float64_inference(self, tmp_path):
1432
+ np = pytest.importorskip("numpy")
1433
+ G = self.attribute_numeric_type_graph
1434
+ G.edges[("n1", "n1")]["weight"] = np.float64(1.1)
1435
+ fname = tmp_path / "test.graphml"
1436
+ self.writer(G, fname, infer_numeric_types=True)
1437
+ H = nx.read_graphml(fname)
1438
+ assert G._adj == H._adj
1439
+
1440
+ def test_unicode_attributes(self, tmp_path):
1441
+ G = nx.Graph()
1442
+ name1 = chr(2344) + chr(123) + chr(6543)
1443
+ name2 = chr(5543) + chr(1543) + chr(324)
1444
+ node_type = str
1445
+ G.add_edge(name1, "Radiohead", foo=name2)
1446
+ fname = tmp_path / "test.graphml"
1447
+ self.writer(G, fname)
1448
+ H = nx.read_graphml(fname, node_type=node_type)
1449
+ assert G._adj == H._adj
1450
+
1451
+ def test_unicode_escape(self):
1452
+ # test for handling json escaped strings in python 2 Issue #1880
1453
+ import json
1454
+
1455
+ a = {"a": '{"a": "123"}'} # an object with many chars to escape
1456
+ sa = json.dumps(a)
1457
+ G = nx.Graph()
1458
+ G.graph["test"] = sa
1459
+ fh = io.BytesIO()
1460
+ self.writer(G, fh)
1461
+ fh.seek(0)
1462
+ H = nx.read_graphml(fh)
1463
+ assert G.graph["test"] == H.graph["test"]
1464
+
1465
+
1466
+ class TestXMLGraphML(TestWriteGraphML):
1467
+ writer = staticmethod(nx.write_graphml_xml)
1468
+
1469
+ @classmethod
1470
+ def setup_class(cls):
1471
+ TestWriteGraphML.setup_class()
1472
+
1473
+
1474
+ def test_exception_for_unsupported_datatype_node_attr():
1475
+ """Test that a detailed exception is raised when an attribute is of a type
1476
+ not supported by GraphML, e.g. a list"""
1477
+ pytest.importorskip("lxml.etree")
1478
+ # node attribute
1479
+ G = nx.Graph()
1480
+ G.add_node(0, my_list_attribute=[0, 1, 2])
1481
+ fh = io.BytesIO()
1482
+ with pytest.raises(TypeError, match="GraphML does not support"):
1483
+ nx.write_graphml(G, fh)
1484
+
1485
+
1486
+ def test_exception_for_unsupported_datatype_edge_attr():
1487
+ """Test that a detailed exception is raised when an attribute is of a type
1488
+ not supported by GraphML, e.g. a list"""
1489
+ pytest.importorskip("lxml.etree")
1490
+ # edge attribute
1491
+ G = nx.Graph()
1492
+ G.add_edge(0, 1, my_list_attribute=[0, 1, 2])
1493
+ fh = io.BytesIO()
1494
+ with pytest.raises(TypeError, match="GraphML does not support"):
1495
+ nx.write_graphml(G, fh)
1496
+
1497
+
1498
+ def test_exception_for_unsupported_datatype_graph_attr():
1499
+ """Test that a detailed exception is raised when an attribute is of a type
1500
+ not supported by GraphML, e.g. a list"""
1501
+ pytest.importorskip("lxml.etree")
1502
+ # graph attribute
1503
+ G = nx.Graph()
1504
+ G.graph["my_list_attribute"] = [0, 1, 2]
1505
+ fh = io.BytesIO()
1506
+ with pytest.raises(TypeError, match="GraphML does not support"):
1507
+ nx.write_graphml(G, fh)
1508
+
1509
+
1510
+ def test_empty_attribute():
1511
+ """Tests that a GraphML string with an empty attribute can be parsed
1512
+ correctly."""
1513
+ s = """<?xml version='1.0' encoding='utf-8'?>
1514
+ <graphml>
1515
+ <key id="d1" for="node" attr.name="foo" attr.type="string"/>
1516
+ <key id="d2" for="node" attr.name="bar" attr.type="string"/>
1517
+ <graph>
1518
+ <node id="0">
1519
+ <data key="d1">aaa</data>
1520
+ <data key="d2">bbb</data>
1521
+ </node>
1522
+ <node id="1">
1523
+ <data key="d1">ccc</data>
1524
+ <data key="d2"></data>
1525
+ </node>
1526
+ </graph>
1527
+ </graphml>"""
1528
+ fh = io.BytesIO(s.encode("UTF-8"))
1529
+ G = nx.read_graphml(fh)
1530
+ assert G.nodes["0"] == {"foo": "aaa", "bar": "bbb"}
1531
+ assert G.nodes["1"] == {"foo": "ccc", "bar": ""}