ofplang-validate 0.1.0rc1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (354) hide show
  1. ofplang_validate-0.1.0rc1/.github/workflows/ci.yml +45 -0
  2. ofplang_validate-0.1.0rc1/.github/workflows/publish.yml +78 -0
  3. ofplang_validate-0.1.0rc1/.gitignore +12 -0
  4. ofplang_validate-0.1.0rc1/LICENSE +21 -0
  5. ofplang_validate-0.1.0rc1/PKG-INFO +113 -0
  6. ofplang_validate-0.1.0rc1/README.md +81 -0
  7. ofplang_validate-0.1.0rc1/ofplang/validate/__init__.py +19 -0
  8. ofplang_validate-0.1.0rc1/ofplang/validate/__main__.py +9 -0
  9. ofplang_validate-0.1.0rc1/ofplang/validate/cli.py +178 -0
  10. ofplang_validate-0.1.0rc1/ofplang/validate/contracts.py +531 -0
  11. ofplang_validate-0.1.0rc1/ofplang/validate/diagnostics.py +65 -0
  12. ofplang_validate-0.1.0rc1/ofplang/validate/duplicates.py +61 -0
  13. ofplang_validate-0.1.0rc1/ofplang/validate/entry.py +129 -0
  14. ofplang_validate-0.1.0rc1/ofplang/validate/errors.py +176 -0
  15. ofplang_validate-0.1.0rc1/ofplang/validate/features.py +126 -0
  16. ofplang_validate-0.1.0rc1/ofplang/validate/generics.py +394 -0
  17. ofplang_validate-0.1.0rc1/ofplang/validate/identifiers.py +112 -0
  18. ofplang_validate-0.1.0rc1/ofplang/validate/imports.py +185 -0
  19. ofplang_validate-0.1.0rc1/ofplang/validate/nodes.py +493 -0
  20. ofplang_validate-0.1.0rc1/ofplang/validate/objects.py +577 -0
  21. ofplang_validate-0.1.0rc1/ofplang/validate/phases.py +87 -0
  22. ofplang_validate-0.1.0rc1/ofplang/validate/py.typed +0 -0
  23. ofplang_validate-0.1.0rc1/ofplang/validate/references.py +310 -0
  24. ofplang_validate-0.1.0rc1/ofplang/validate/scheduling.py +187 -0
  25. ofplang_validate-0.1.0rc1/ofplang/validate/script.py +81 -0
  26. ofplang_validate-0.1.0rc1/ofplang/validate/shape.py +311 -0
  27. ofplang_validate-0.1.0rc1/ofplang/validate/traits.py +59 -0
  28. ofplang_validate-0.1.0rc1/ofplang/validate/typecheck.py +132 -0
  29. ofplang_validate-0.1.0rc1/ofplang/validate/types.py +226 -0
  30. ofplang_validate-0.1.0rc1/ofplang/validate/validator.py +166 -0
  31. ofplang_validate-0.1.0rc1/ofplang/validate/views.py +139 -0
  32. ofplang_validate-0.1.0rc1/ofplang/validate/yamlnode.py +241 -0
  33. ofplang_validate-0.1.0rc1/ofplang_validate.egg-info/PKG-INFO +113 -0
  34. ofplang_validate-0.1.0rc1/ofplang_validate.egg-info/SOURCES.txt +352 -0
  35. ofplang_validate-0.1.0rc1/ofplang_validate.egg-info/dependency_links.txt +1 -0
  36. ofplang_validate-0.1.0rc1/ofplang_validate.egg-info/entry_points.txt +2 -0
  37. ofplang_validate-0.1.0rc1/ofplang_validate.egg-info/requires.txt +10 -0
  38. ofplang_validate-0.1.0rc1/ofplang_validate.egg-info/scm_file_list.json +348 -0
  39. ofplang_validate-0.1.0rc1/ofplang_validate.egg-info/scm_version.json +8 -0
  40. ofplang_validate-0.1.0rc1/ofplang_validate.egg-info/top_level.txt +1 -0
  41. ofplang_validate-0.1.0rc1/pyproject.toml +83 -0
  42. ofplang_validate-0.1.0rc1/setup.cfg +4 -0
  43. ofplang_validate-0.1.0rc1/tests/__init__.py +0 -0
  44. ofplang_validate-0.1.0rc1/tests/conformance/README.md +122 -0
  45. ofplang_validate-0.1.0rc1/tests/conformance/__init__.py +0 -0
  46. ofplang_validate-0.1.0rc1/tests/conformance/cases/_baseline.yaml +9 -0
  47. ofplang_validate-0.1.0rc1/tests/conformance/cases/aggregation/multiple_independent_errors.expected.yaml +15 -0
  48. ofplang_validate-0.1.0rc1/tests/conformance/cases/aggregation/multiple_independent_errors.yaml +17 -0
  49. ofplang_validate-0.1.0rc1/tests/conformance/cases/contracts/comparison_chain.expected.yaml +5 -0
  50. ofplang_validate-0.1.0rc1/tests/conformance/cases/contracts/comparison_chain.yaml +13 -0
  51. ofplang_validate-0.1.0rc1/tests/conformance/cases/contracts/missing_view.expected.yaml +4 -0
  52. ofplang_validate-0.1.0rc1/tests/conformance/cases/contracts/missing_view.yaml +13 -0
  53. ofplang_validate-0.1.0rc1/tests/conformance/cases/contracts/parse_error.expected.yaml +4 -0
  54. ofplang_validate-0.1.0rc1/tests/conformance/cases/contracts/parse_error.yaml +13 -0
  55. ofplang_validate-0.1.0rc1/tests/conformance/cases/contracts/requires_references_output.expected.yaml +5 -0
  56. ofplang_validate-0.1.0rc1/tests/conformance/cases/contracts/requires_references_output.yaml +16 -0
  57. ofplang_validate-0.1.0rc1/tests/conformance/cases/contracts/static_false.expected.yaml +4 -0
  58. ofplang_validate-0.1.0rc1/tests/conformance/cases/contracts/static_false.yaml +13 -0
  59. ofplang_validate-0.1.0rc1/tests/conformance/cases/contracts/type_error.expected.yaml +4 -0
  60. ofplang_validate-0.1.0rc1/tests/conformance/cases/contracts/type_error.yaml +13 -0
  61. ofplang_validate-0.1.0rc1/tests/conformance/cases/contracts/unknown_view_field.expected.yaml +5 -0
  62. ofplang_validate-0.1.0rc1/tests/conformance/cases/contracts/unknown_view_field.yaml +26 -0
  63. ofplang_validate-0.1.0rc1/tests/conformance/cases/contracts/valid_ensures.expected.yaml +2 -0
  64. ofplang_validate-0.1.0rc1/tests/conformance/cases/contracts/valid_ensures.yaml +16 -0
  65. ofplang_validate-0.1.0rc1/tests/conformance/cases/contracts/valid_numeric_promotion.expected.yaml +2 -0
  66. ofplang_validate-0.1.0rc1/tests/conformance/cases/contracts/valid_numeric_promotion.yaml +13 -0
  67. ofplang_validate-0.1.0rc1/tests/conformance/cases/contracts/valid_requires.expected.yaml +2 -0
  68. ofplang_validate-0.1.0rc1/tests/conformance/cases/contracts/valid_requires.yaml +13 -0
  69. ofplang_validate-0.1.0rc1/tests/conformance/cases/entry/implicit_main.expected.yaml +2 -0
  70. ofplang_validate-0.1.0rc1/tests/conformance/cases/entry/implicit_main.yaml +6 -0
  71. ofplang_validate-0.1.0rc1/tests/conformance/cases/entry/no_entry.expected.yaml +4 -0
  72. ofplang_validate-0.1.0rc1/tests/conformance/cases/entry/no_entry.yaml +6 -0
  73. ofplang_validate-0.1.0rc1/tests/conformance/cases/entry/recursive_dependency.expected.yaml +4 -0
  74. ofplang_validate-0.1.0rc1/tests/conformance/cases/entry/recursive_dependency.yaml +24 -0
  75. ofplang_validate-0.1.0rc1/tests/conformance/cases/entry/unknown_entry.expected.yaml +5 -0
  76. ofplang_validate-0.1.0rc1/tests/conformance/cases/entry/unknown_entry.yaml +7 -0
  77. ofplang_validate-0.1.0rc1/tests/conformance/cases/extensions/x_feature_tolerant.expected.yaml +3 -0
  78. ofplang_validate-0.1.0rc1/tests/conformance/cases/extensions/x_feature_tolerant.yaml +9 -0
  79. ofplang_validate-0.1.0rc1/tests/conformance/cases/extensions/x_key_strict.expected.yaml +6 -0
  80. ofplang_validate-0.1.0rc1/tests/conformance/cases/extensions/x_key_strict.yaml +8 -0
  81. ofplang_validate-0.1.0rc1/tests/conformance/cases/extensions/x_key_tolerant.expected.yaml +3 -0
  82. ofplang_validate-0.1.0rc1/tests/conformance/cases/extensions/x_key_tolerant.yaml +8 -0
  83. ofplang_validate-0.1.0rc1/tests/conformance/cases/extensions/x_prefer_kind_tolerant.expected.yaml +3 -0
  84. ofplang_validate-0.1.0rc1/tests/conformance/cases/extensions/x_prefer_kind_tolerant.yaml +17 -0
  85. ofplang_validate-0.1.0rc1/tests/conformance/cases/features/derived_ok.expected.yaml +2 -0
  86. ofplang_validate-0.1.0rc1/tests/conformance/cases/features/derived_ok.yaml +19 -0
  87. ofplang_validate-0.1.0rc1/tests/conformance/cases/features/derived_omitted.expected.yaml +2 -0
  88. ofplang_validate-0.1.0rc1/tests/conformance/cases/features/derived_omitted.yaml +28 -0
  89. ofplang_validate-0.1.0rc1/tests/conformance/cases/features/generic_derived_ok.expected.yaml +2 -0
  90. ofplang_validate-0.1.0rc1/tests/conformance/cases/features/generic_derived_ok.yaml +25 -0
  91. ofplang_validate-0.1.0rc1/tests/conformance/cases/features/generic_missing_feature.expected.yaml +5 -0
  92. ofplang_validate-0.1.0rc1/tests/conformance/cases/features/generic_missing_feature.yaml +24 -0
  93. ofplang_validate-0.1.0rc1/tests/conformance/cases/features/missing_required_feature.expected.yaml +5 -0
  94. ofplang_validate-0.1.0rc1/tests/conformance/cases/features/missing_required_feature.yaml +35 -0
  95. ofplang_validate-0.1.0rc1/tests/conformance/cases/features/unknown_feature.expected.yaml +5 -0
  96. ofplang_validate-0.1.0rc1/tests/conformance/cases/features/unknown_feature.yaml +9 -0
  97. ofplang_validate-0.1.0rc1/tests/conformance/cases/generics/conflicting_inference.expected.yaml +6 -0
  98. ofplang_validate-0.1.0rc1/tests/conformance/cases/generics/conflicting_inference.yaml +47 -0
  99. ofplang_validate-0.1.0rc1/tests/conformance/cases/generics/constraint_not_satisfied.expected.yaml +4 -0
  100. ofplang_validate-0.1.0rc1/tests/conformance/cases/generics/constraint_not_satisfied.yaml +54 -0
  101. ofplang_validate-0.1.0rc1/tests/conformance/cases/generics/constraint_on_concrete.expected.yaml +4 -0
  102. ofplang_validate-0.1.0rc1/tests/conformance/cases/generics/constraint_on_concrete.yaml +32 -0
  103. ofplang_validate-0.1.0rc1/tests/conformance/cases/generics/malformed_constraint.expected.yaml +5 -0
  104. ofplang_validate-0.1.0rc1/tests/conformance/cases/generics/malformed_constraint.yaml +27 -0
  105. ofplang_validate-0.1.0rc1/tests/conformance/cases/generics/type_param_not_in_input.expected.yaml +5 -0
  106. ofplang_validate-0.1.0rc1/tests/conformance/cases/generics/type_param_not_in_input.yaml +17 -0
  107. ofplang_validate-0.1.0rc1/tests/conformance/cases/generics/type_param_shadow.expected.yaml +4 -0
  108. ofplang_validate-0.1.0rc1/tests/conformance/cases/generics/type_param_shadow.yaml +26 -0
  109. ofplang_validate-0.1.0rc1/tests/conformance/cases/generics/uninferable_type_param.expected.yaml +8 -0
  110. ofplang_validate-0.1.0rc1/tests/conformance/cases/generics/uninferable_type_param.yaml +33 -0
  111. ofplang_validate-0.1.0rc1/tests/conformance/cases/generics/valid_inference.expected.yaml +5 -0
  112. ofplang_validate-0.1.0rc1/tests/conformance/cases/generics/valid_inference.yaml +38 -0
  113. ofplang_validate-0.1.0rc1/tests/conformance/cases/generics/valid_where.expected.yaml +2 -0
  114. ofplang_validate-0.1.0rc1/tests/conformance/cases/generics/valid_where.yaml +32 -0
  115. ofplang_validate-0.1.0rc1/tests/conformance/cases/identifiers/bad_identifier.expected.yaml +5 -0
  116. ofplang_validate-0.1.0rc1/tests/conformance/cases/identifiers/bad_identifier.yaml +7 -0
  117. ofplang_validate-0.1.0rc1/tests/conformance/cases/identifiers/dot_in_process_name.expected.yaml +5 -0
  118. ofplang_validate-0.1.0rc1/tests/conformance/cases/identifiers/dot_in_process_name.yaml +7 -0
  119. ofplang_validate-0.1.0rc1/tests/conformance/cases/identifiers/duplicate_port_name.expected.yaml +5 -0
  120. ofplang_validate-0.1.0rc1/tests/conformance/cases/identifiers/duplicate_port_name.yaml +13 -0
  121. ofplang_validate-0.1.0rc1/tests/conformance/cases/identifiers/reserved_type_name.expected.yaml +5 -0
  122. ofplang_validate-0.1.0rc1/tests/conformance/cases/identifiers/reserved_type_name.yaml +10 -0
  123. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/basic/expected.yaml +2 -0
  124. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/basic/main.yaml +12 -0
  125. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/basic/types_fragment.yaml +2 -0
  126. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/cycle/a.yaml +1 -0
  127. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/cycle/b.yaml +1 -0
  128. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/cycle/expected.yaml +4 -0
  129. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/cycle/main.yaml +4 -0
  130. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/duplicate_key/expected.yaml +5 -0
  131. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/duplicate_key/frag.yaml +2 -0
  132. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/duplicate_key/main.yaml +11 -0
  133. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/empty_import.expected.yaml +5 -0
  134. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/empty_import.yaml +4 -0
  135. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/invalid_shape/expected.yaml +4 -0
  136. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/invalid_shape/main.yaml +9 -0
  137. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/invalid_shape/seq.yaml +2 -0
  138. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/multidoc/expected.yaml +4 -0
  139. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/multidoc/main.yaml +9 -0
  140. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/multidoc/multi.yaml +5 -0
  141. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/non_string_path/expected.yaml +4 -0
  142. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/non_string_path/main.yaml +9 -0
  143. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/unreadable/expected.yaml +4 -0
  144. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/unreadable/main.yaml +9 -0
  145. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/uri_fragment/expected.yaml +4 -0
  146. ofplang_validate-0.1.0rc1/tests/conformance/cases/imports/uri_fragment/main.yaml +9 -0
  147. ofplang_validate-0.1.0rc1/tests/conformance/cases/linearity/data_indegree_zero.expected.yaml +4 -0
  148. ofplang_validate-0.1.0rc1/tests/conformance/cases/linearity/data_indegree_zero.yaml +17 -0
  149. ofplang_validate-0.1.0rc1/tests/conformance/cases/linearity/object_fanout.expected.yaml +5 -0
  150. ofplang_validate-0.1.0rc1/tests/conformance/cases/linearity/object_fanout.yaml +43 -0
  151. ofplang_validate-0.1.0rc1/tests/conformance/cases/linearity/object_input_no_source.expected.yaml +4 -0
  152. ofplang_validate-0.1.0rc1/tests/conformance/cases/linearity/object_input_no_source.yaml +23 -0
  153. ofplang_validate-0.1.0rc1/tests/conformance/cases/linearity/object_output_unused.expected.yaml +5 -0
  154. ofplang_validate-0.1.0rc1/tests/conformance/cases/linearity/object_output_unused.yaml +23 -0
  155. ofplang_validate-0.1.0rc1/tests/conformance/cases/linearity/valid_object_flow.expected.yaml +2 -0
  156. ofplang_validate-0.1.0rc1/tests/conformance/cases/linearity/valid_object_flow.yaml +38 -0
  157. ofplang_validate-0.1.0rc1/tests/conformance/cases/linearity/valid_return_object.expected.yaml +2 -0
  158. ofplang_validate-0.1.0rc1/tests/conformance/cases/linearity/valid_return_object.yaml +21 -0
  159. ofplang_validate-0.1.0rc1/tests/conformance/cases/metadata/float_spec_version.expected.yaml +5 -0
  160. ofplang_validate-0.1.0rc1/tests/conformance/cases/metadata/float_spec_version.yaml +7 -0
  161. ofplang_validate-0.1.0rc1/tests/conformance/cases/metadata/malformed_spec_version.expected.yaml +5 -0
  162. ofplang_validate-0.1.0rc1/tests/conformance/cases/metadata/malformed_spec_version.yaml +7 -0
  163. ofplang_validate-0.1.0rc1/tests/conformance/cases/metadata/omitted_spec_version.expected.yaml +2 -0
  164. ofplang_validate-0.1.0rc1/tests/conformance/cases/metadata/omitted_spec_version.yaml +6 -0
  165. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/bad_condition_output.expected.yaml +4 -0
  166. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/bad_condition_output.yaml +42 -0
  167. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/branch_common_type_mismatch.expected.yaml +5 -0
  168. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/branch_common_type_mismatch.yaml +44 -0
  169. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/branch_drop_object.expected.yaml +5 -0
  170. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/branch_drop_object.yaml +46 -0
  171. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/branch_implicit_else_not_identity.expected.yaml +5 -0
  172. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/branch_implicit_else_not_identity.yaml +33 -0
  173. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/branch_not_identity_equivalent.expected.yaml +4 -0
  174. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/branch_not_identity_equivalent.yaml +67 -0
  175. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/branch_object_omitted.expected.yaml +5 -0
  176. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/branch_object_omitted.yaml +47 -0
  177. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/branch_one_sided_object.expected.yaml +5 -0
  178. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/branch_one_sided_object.yaml +54 -0
  179. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/dowhile_missing_max_iterations.expected.yaml +5 -0
  180. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/dowhile_missing_max_iterations.yaml +40 -0
  181. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/dowhile_noncarry_object.expected.yaml +4 -0
  182. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/dowhile_noncarry_object.yaml +49 -0
  183. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/fold_carry_not_carry_mode.expected.yaml +5 -0
  184. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/fold_carry_not_carry_mode.yaml +31 -0
  185. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/fold_carry_output_missing.expected.yaml +5 -0
  186. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/fold_carry_output_missing.yaml +44 -0
  187. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/fold_carry_phase_mismatch.expected.yaml +7 -0
  188. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/fold_carry_phase_mismatch.yaml +47 -0
  189. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/fold_carry_type_mismatch.expected.yaml +6 -0
  190. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/fold_carry_type_mismatch.yaml +47 -0
  191. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/fold_invalid_output_mode.expected.yaml +5 -0
  192. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/fold_invalid_output_mode.yaml +31 -0
  193. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/fold_noncarry_object_unlisted.expected.yaml +4 -0
  194. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/fold_noncarry_object_unlisted.yaml +36 -0
  195. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/fold_output_not_listed.expected.yaml +5 -0
  196. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/fold_output_not_listed.yaml +30 -0
  197. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/last_on_empty_fold.expected.yaml +4 -0
  198. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/last_on_empty_fold.yaml +29 -0
  199. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/object_output_last_mode.expected.yaml +4 -0
  200. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/object_output_last_mode.yaml +39 -0
  201. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/ordinary_output_section.expected.yaml +5 -0
  202. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/ordinary_output_section.yaml +17 -0
  203. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/unknown_node_key.expected.yaml +5 -0
  204. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/unknown_node_key.yaml +17 -0
  205. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/valid_branch_common.expected.yaml +2 -0
  206. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/valid_branch_common.yaml +66 -0
  207. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/valid_do_while.expected.yaml +2 -0
  208. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/valid_do_while.yaml +42 -0
  209. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/valid_fold_collect.expected.yaml +2 -0
  210. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/valid_fold_collect.yaml +47 -0
  211. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/valid_map.expected.yaml +2 -0
  212. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/valid_map.yaml +52 -0
  213. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/zip_mismatch.expected.yaml +4 -0
  214. ofplang_validate-0.1.0rc1/tests/conformance/cases/nodes/zip_mismatch.yaml +31 -0
  215. ofplang_validate-0.1.0rc1/tests/conformance/cases/objects/consume_path_not_found.expected.yaml +5 -0
  216. ofplang_validate-0.1.0rc1/tests/conformance/cases/objects/consume_path_not_found.yaml +21 -0
  217. ofplang_validate-0.1.0rc1/tests/conformance/cases/objects/implicit_create_output.expected.yaml +5 -0
  218. ofplang_validate-0.1.0rc1/tests/conformance/cases/objects/implicit_create_output.yaml +18 -0
  219. ofplang_validate-0.1.0rc1/tests/conformance/cases/objects/incomplete_input_fate.expected.yaml +5 -0
  220. ofplang_validate-0.1.0rc1/tests/conformance/cases/objects/incomplete_input_fate.yaml +18 -0
  221. ofplang_validate-0.1.0rc1/tests/conformance/cases/objects/multiple_fates.expected.yaml +5 -0
  222. ofplang_validate-0.1.0rc1/tests/conformance/cases/objects/multiple_fates.yaml +25 -0
  223. ofplang_validate-0.1.0rc1/tests/conformance/cases/objects/multiple_provenances.expected.yaml +4 -0
  224. ofplang_validate-0.1.0rc1/tests/conformance/cases/objects/multiple_provenances.yaml +25 -0
  225. ofplang_validate-0.1.0rc1/tests/conformance/cases/objects/valid_cross_wired_map.expected.yaml +2 -0
  226. ofplang_validate-0.1.0rc1/tests/conformance/cases/objects/valid_cross_wired_map.yaml +30 -0
  227. ofplang_validate-0.1.0rc1/tests/conformance/cases/objects/valid_elidable_iso.expected.yaml +2 -0
  228. ofplang_validate-0.1.0rc1/tests/conformance/cases/objects/valid_elidable_iso.yaml +22 -0
  229. ofplang_validate-0.1.0rc1/tests/conformance/cases/objects/valid_map.expected.yaml +2 -0
  230. ofplang_validate-0.1.0rc1/tests/conformance/cases/objects/valid_map.yaml +23 -0
  231. ofplang_validate-0.1.0rc1/tests/conformance/cases/objects/valid_object_replacement.expected.yaml +2 -0
  232. ofplang_validate-0.1.0rc1/tests/conformance/cases/objects/valid_object_replacement.yaml +25 -0
  233. ofplang_validate-0.1.0rc1/tests/conformance/cases/phases/bad_phase_value.expected.yaml +5 -0
  234. ofplang_validate-0.1.0rc1/tests/conformance/cases/phases/bad_phase_value.yaml +10 -0
  235. ofplang_validate-0.1.0rc1/tests/conformance/cases/phases/invalid_phase_flow.expected.yaml +4 -0
  236. ofplang_validate-0.1.0rc1/tests/conformance/cases/phases/invalid_phase_flow.yaml +29 -0
  237. ofplang_validate-0.1.0rc1/tests/conformance/cases/phases/object_graph_phase.expected.yaml +5 -0
  238. ofplang_validate-0.1.0rc1/tests/conformance/cases/phases/object_graph_phase.yaml +19 -0
  239. ofplang_validate-0.1.0rc1/tests/conformance/cases/phases/valid_object_data_phase.expected.yaml +2 -0
  240. ofplang_validate-0.1.0rc1/tests/conformance/cases/phases/valid_object_data_phase.yaml +19 -0
  241. ofplang_validate-0.1.0rc1/tests/conformance/cases/references/binding_source_both.expected.yaml +4 -0
  242. ofplang_validate-0.1.0rc1/tests/conformance/cases/references/binding_source_both.yaml +25 -0
  243. ofplang_validate-0.1.0rc1/tests/conformance/cases/references/binding_source_neither.expected.yaml +4 -0
  244. ofplang_validate-0.1.0rc1/tests/conformance/cases/references/binding_source_neither.yaml +19 -0
  245. ofplang_validate-0.1.0rc1/tests/conformance/cases/references/object_via_bind.expected.yaml +4 -0
  246. ofplang_validate-0.1.0rc1/tests/conformance/cases/references/object_via_bind.yaml +38 -0
  247. ofplang_validate-0.1.0rc1/tests/conformance/cases/references/return_unknown_ref.expected.yaml +4 -0
  248. ofplang_validate-0.1.0rc1/tests/conformance/cases/references/return_unknown_ref.yaml +23 -0
  249. ofplang_validate-0.1.0rc1/tests/conformance/cases/references/unknown_reference.expected.yaml +4 -0
  250. ofplang_validate-0.1.0rc1/tests/conformance/cases/references/unknown_reference.yaml +29 -0
  251. ofplang_validate-0.1.0rc1/tests/conformance/cases/scheduling/bad_temporal_ref.expected.yaml +4 -0
  252. ofplang_validate-0.1.0rc1/tests/conformance/cases/scheduling/bad_temporal_ref.yaml +25 -0
  253. ofplang_validate-0.1.0rc1/tests/conformance/cases/scheduling/gap_with_object.expected.yaml +5 -0
  254. ofplang_validate-0.1.0rc1/tests/conformance/cases/scheduling/gap_with_object.yaml +34 -0
  255. ofplang_validate-0.1.0rc1/tests/conformance/cases/scheduling/malformed_prefer_payload.expected.yaml +4 -0
  256. ofplang_validate-0.1.0rc1/tests/conformance/cases/scheduling/malformed_prefer_payload.yaml +17 -0
  257. ofplang_validate-0.1.0rc1/tests/conformance/cases/scheduling/non_object_bearing_target.expected.yaml +4 -0
  258. ofplang_validate-0.1.0rc1/tests/conformance/cases/scheduling/non_object_bearing_target.yaml +25 -0
  259. ofplang_validate-0.1.0rc1/tests/conformance/cases/scheduling/on_atomic.expected.yaml +5 -0
  260. ofplang_validate-0.1.0rc1/tests/conformance/cases/scheduling/on_atomic.yaml +18 -0
  261. ofplang_validate-0.1.0rc1/tests/conformance/cases/scheduling/temperature_without_object.expected.yaml +5 -0
  262. ofplang_validate-0.1.0rc1/tests/conformance/cases/scheduling/temperature_without_object.yaml +25 -0
  263. ofplang_validate-0.1.0rc1/tests/conformance/cases/scheduling/unknown_prefer_kind.expected.yaml +4 -0
  264. ofplang_validate-0.1.0rc1/tests/conformance/cases/scheduling/unknown_prefer_kind.yaml +19 -0
  265. ofplang_validate-0.1.0rc1/tests/conformance/cases/scheduling/valid_max_gap.expected.yaml +2 -0
  266. ofplang_validate-0.1.0rc1/tests/conformance/cases/scheduling/valid_max_gap.yaml +31 -0
  267. ofplang_validate-0.1.0rc1/tests/conformance/cases/scheduling/valid_min_gap.expected.yaml +2 -0
  268. ofplang_validate-0.1.0rc1/tests/conformance/cases/scheduling/valid_min_gap.yaml +31 -0
  269. ofplang_validate-0.1.0rc1/tests/conformance/cases/scheduling/valid_temperature.expected.yaml +2 -0
  270. ofplang_validate-0.1.0rc1/tests/conformance/cases/scheduling/valid_temperature.yaml +34 -0
  271. ofplang_validate-0.1.0rc1/tests/conformance/cases/script/has_objects.expected.yaml +4 -0
  272. ofplang_validate-0.1.0rc1/tests/conformance/cases/script/has_objects.yaml +26 -0
  273. ofplang_validate-0.1.0rc1/tests/conformance/cases/script/object_port.expected.yaml +5 -0
  274. ofplang_validate-0.1.0rc1/tests/conformance/cases/script/object_port.yaml +26 -0
  275. ofplang_validate-0.1.0rc1/tests/conformance/cases/script/unsupported_language.expected.yaml +5 -0
  276. ofplang_validate-0.1.0rc1/tests/conformance/cases/script/unsupported_language.yaml +22 -0
  277. ofplang_validate-0.1.0rc1/tests/conformance/cases/script/valid_python.expected.yaml +2 -0
  278. ofplang_validate-0.1.0rc1/tests/conformance/cases/script/valid_python.yaml +26 -0
  279. ofplang_validate-0.1.0rc1/tests/conformance/cases/shape/duplicate_process_name.expected.yaml +5 -0
  280. ofplang_validate-0.1.0rc1/tests/conformance/cases/shape/duplicate_process_name.yaml +11 -0
  281. ofplang_validate-0.1.0rc1/tests/conformance/cases/shape/node_missing_process.expected.yaml +5 -0
  282. ofplang_validate-0.1.0rc1/tests/conformance/cases/shape/node_missing_process.yaml +9 -0
  283. ofplang_validate-0.1.0rc1/tests/conformance/cases/shape/null_phase.expected.yaml +5 -0
  284. ofplang_validate-0.1.0rc1/tests/conformance/cases/shape/null_phase.yaml +10 -0
  285. ofplang_validate-0.1.0rc1/tests/conformance/cases/shape/objects_on_composite.expected.yaml +5 -0
  286. ofplang_validate-0.1.0rc1/tests/conformance/cases/shape/objects_on_composite.yaml +10 -0
  287. ofplang_validate-0.1.0rc1/tests/conformance/cases/shape/port_missing_phase.expected.yaml +5 -0
  288. ofplang_validate-0.1.0rc1/tests/conformance/cases/shape/port_missing_phase.yaml +9 -0
  289. ofplang_validate-0.1.0rc1/tests/conformance/cases/shape/port_missing_type.expected.yaml +5 -0
  290. ofplang_validate-0.1.0rc1/tests/conformance/cases/shape/port_missing_type.yaml +9 -0
  291. ofplang_validate-0.1.0rc1/tests/conformance/cases/shape/reserved_dollar_key.expected.yaml +5 -0
  292. ofplang_validate-0.1.0rc1/tests/conformance/cases/shape/reserved_dollar_key.yaml +8 -0
  293. ofplang_validate-0.1.0rc1/tests/conformance/cases/shape/unknown_top_level_key.expected.yaml +5 -0
  294. ofplang_validate-0.1.0rc1/tests/conformance/cases/shape/unknown_top_level_key.yaml +8 -0
  295. ofplang_validate-0.1.0rc1/tests/conformance/cases/shape/valid_minimal.expected.yaml +2 -0
  296. ofplang_validate-0.1.0rc1/tests/conformance/cases/shape/valid_minimal.yaml +7 -0
  297. ofplang_validate-0.1.0rc1/tests/conformance/cases/traits/implements_numeric.expected.yaml +5 -0
  298. ofplang_validate-0.1.0rc1/tests/conformance/cases/traits/implements_numeric.yaml +12 -0
  299. ofplang_validate-0.1.0rc1/tests/conformance/cases/traits/redeclare_numeric.expected.yaml +5 -0
  300. ofplang_validate-0.1.0rc1/tests/conformance/cases/traits/redeclare_numeric.yaml +9 -0
  301. ofplang_validate-0.1.0rc1/tests/conformance/cases/traits/unknown_trait.expected.yaml +5 -0
  302. ofplang_validate-0.1.0rc1/tests/conformance/cases/traits/unknown_trait.yaml +12 -0
  303. ofplang_validate-0.1.0rc1/tests/conformance/cases/traits/valid_implements.expected.yaml +2 -0
  304. ofplang_validate-0.1.0rc1/tests/conformance/cases/traits/valid_implements.yaml +18 -0
  305. ofplang_validate-0.1.0rc1/tests/conformance/cases/transforms/array_role_not_array.expected.yaml +5 -0
  306. ofplang_validate-0.1.0rc1/tests/conformance/cases/transforms/array_role_not_array.yaml +27 -0
  307. ofplang_validate-0.1.0rc1/tests/conformance/cases/transforms/missing_role.expected.yaml +5 -0
  308. ofplang_validate-0.1.0rc1/tests/conformance/cases/transforms/missing_role.yaml +27 -0
  309. ofplang_validate-0.1.0rc1/tests/conformance/cases/transforms/pure_data_in_transform.expected.yaml +5 -0
  310. ofplang_validate-0.1.0rc1/tests/conformance/cases/transforms/pure_data_in_transform.yaml +24 -0
  311. ofplang_validate-0.1.0rc1/tests/conformance/cases/transforms/role_type_mismatch.expected.yaml +4 -0
  312. ofplang_validate-0.1.0rc1/tests/conformance/cases/transforms/role_type_mismatch.yaml +33 -0
  313. ofplang_validate-0.1.0rc1/tests/conformance/cases/transforms/transform_path_not_found.expected.yaml +7 -0
  314. ofplang_validate-0.1.0rc1/tests/conformance/cases/transforms/transform_path_not_found.yaml +27 -0
  315. ofplang_validate-0.1.0rc1/tests/conformance/cases/transforms/unknown_transform_kind.expected.yaml +5 -0
  316. ofplang_validate-0.1.0rc1/tests/conformance/cases/transforms/unknown_transform_kind.yaml +27 -0
  317. ofplang_validate-0.1.0rc1/tests/conformance/cases/transforms/valid_array_cons.expected.yaml +2 -0
  318. ofplang_validate-0.1.0rc1/tests/conformance/cases/transforms/valid_array_cons.yaml +31 -0
  319. ofplang_validate-0.1.0rc1/tests/conformance/cases/transforms/valid_array_reverse.expected.yaml +2 -0
  320. ofplang_validate-0.1.0rc1/tests/conformance/cases/transforms/valid_array_reverse.yaml +27 -0
  321. ofplang_validate-0.1.0rc1/tests/conformance/cases/transforms/valid_array_uncons.expected.yaml +2 -0
  322. ofplang_validate-0.1.0rc1/tests/conformance/cases/transforms/valid_array_uncons.yaml +31 -0
  323. ofplang_validate-0.1.0rc1/tests/conformance/cases/transforms/valid_nested_uncons.expected.yaml +2 -0
  324. ofplang_validate-0.1.0rc1/tests/conformance/cases/transforms/valid_nested_uncons.yaml +31 -0
  325. ofplang_validate-0.1.0rc1/tests/conformance/cases/types/array_arity.expected.yaml +5 -0
  326. ofplang_validate-0.1.0rc1/tests/conformance/cases/types/array_arity.yaml +13 -0
  327. ofplang_validate-0.1.0rc1/tests/conformance/cases/types/array_arity_zero.expected.yaml +5 -0
  328. ofplang_validate-0.1.0rc1/tests/conformance/cases/types/array_arity_zero.yaml +10 -0
  329. ofplang_validate-0.1.0rc1/tests/conformance/cases/types/array_internal_whitespace.expected.yaml +2 -0
  330. ofplang_validate-0.1.0rc1/tests/conformance/cases/types/array_internal_whitespace.yaml +10 -0
  331. ofplang_validate-0.1.0rc1/tests/conformance/cases/types/malformed_array_space.expected.yaml +5 -0
  332. ofplang_validate-0.1.0rc1/tests/conformance/cases/types/malformed_array_space.yaml +13 -0
  333. ofplang_validate-0.1.0rc1/tests/conformance/cases/types/redeclare_builtin.expected.yaml +5 -0
  334. ofplang_validate-0.1.0rc1/tests/conformance/cases/types/redeclare_builtin.yaml +10 -0
  335. ofplang_validate-0.1.0rc1/tests/conformance/cases/types/type_field_not_string.expected.yaml +4 -0
  336. ofplang_validate-0.1.0rc1/tests/conformance/cases/types/type_field_not_string.yaml +10 -0
  337. ofplang_validate-0.1.0rc1/tests/conformance/cases/types/unknown_type.expected.yaml +5 -0
  338. ofplang_validate-0.1.0rc1/tests/conformance/cases/types/unknown_type.yaml +10 -0
  339. ofplang_validate-0.1.0rc1/tests/conformance/cases/types/valid_user_and_array.expected.yaml +2 -0
  340. ofplang_validate-0.1.0rc1/tests/conformance/cases/types/valid_user_and_array.yaml +16 -0
  341. ofplang_validate-0.1.0rc1/tests/conformance/cases/views/invalid_view_field_type.expected.yaml +4 -0
  342. ofplang_validate-0.1.0rc1/tests/conformance/cases/views/invalid_view_field_type.yaml +15 -0
  343. ofplang_validate-0.1.0rc1/tests/conformance/cases/views/null_static_value.expected.yaml +4 -0
  344. ofplang_validate-0.1.0rc1/tests/conformance/cases/views/null_static_value.yaml +14 -0
  345. ofplang_validate-0.1.0rc1/tests/conformance/cases/views/object_bearing_view_field.expected.yaml +5 -0
  346. ofplang_validate-0.1.0rc1/tests/conformance/cases/views/object_bearing_view_field.yaml +15 -0
  347. ofplang_validate-0.1.0rc1/tests/conformance/cases/views/static_value_type_mismatch.expected.yaml +5 -0
  348. ofplang_validate-0.1.0rc1/tests/conformance/cases/views/static_value_type_mismatch.yaml +14 -0
  349. ofplang_validate-0.1.0rc1/tests/conformance/cases/views/valid_static_value.expected.yaml +2 -0
  350. ofplang_validate-0.1.0rc1/tests/conformance/cases/views/valid_static_value.yaml +14 -0
  351. ofplang_validate-0.1.0rc1/tests/conformance/cases.py +153 -0
  352. ofplang_validate-0.1.0rc1/tests/conformance/test_conformance.py +125 -0
  353. ofplang_validate-0.1.0rc1/tests/test_cli.py +65 -0
  354. ofplang_validate-0.1.0rc1/tests/test_positions.py +106 -0
@@ -0,0 +1,45 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ - uses: actions/setup-python@v5
19
+ with:
20
+ python-version: ${{ matrix.python-version }}
21
+ cache: pip
22
+ - run: pip install -e ".[test]"
23
+ - run: pytest
24
+
25
+ lint:
26
+ runs-on: ubuntu-latest
27
+ steps:
28
+ - uses: actions/checkout@v4
29
+ - uses: actions/setup-python@v5
30
+ with:
31
+ python-version: "3.12"
32
+ cache: pip
33
+ - run: pip install -e ".[dev]"
34
+ - run: ruff check ofplang tests
35
+
36
+ typecheck:
37
+ runs-on: ubuntu-latest
38
+ steps:
39
+ - uses: actions/checkout@v4
40
+ - uses: actions/setup-python@v5
41
+ with:
42
+ python-version: "3.12"
43
+ cache: pip
44
+ - run: pip install -e ".[dev]"
45
+ - run: mypy
@@ -0,0 +1,78 @@
1
+ name: Publish
2
+
3
+ # Tag-driven release via PyPI Trusted Publishing (OIDC) — no API tokens.
4
+ #
5
+ # Version comes from the pushed git tag via setuptools-scm (`v0.1.0` -> 0.1.0).
6
+ # Routing:
7
+ # - a pre-release tag containing `rc` (e.g. v0.1.0rc1) -> TestPyPI (rehearsal)
8
+ # - any other `v*` tag (e.g. v0.1.0) -> PyPI (production)
9
+ # - manual workflow_dispatch -> choose the target explicitly (run it from a
10
+ # tagged commit, else setuptools-scm yields a dev+local version PyPI rejects)
11
+ #
12
+ # PyPI-side setup (done once, by the project owner): register a Trusted Publisher
13
+ # for owner=ofplang, repo=validate, workflow=publish.yml, environment=pypi
14
+ # (and environment=testpypi on TestPyPI). First release: register as "pending".
15
+
16
+ on:
17
+ push:
18
+ tags: ["v*"]
19
+ workflow_dispatch:
20
+ inputs:
21
+ target:
22
+ description: "Publish target"
23
+ type: choice
24
+ options: [testpypi, pypi]
25
+ default: testpypi
26
+
27
+ jobs:
28
+ build:
29
+ runs-on: ubuntu-latest
30
+ steps:
31
+ - uses: actions/checkout@v4
32
+ with:
33
+ # setuptools-scm derives the version from tags + history.
34
+ fetch-depth: 0
35
+ - uses: actions/setup-python@v5
36
+ with:
37
+ python-version: "3.12"
38
+ - run: python -m pip install --upgrade build twine
39
+ - run: python -m build
40
+ - run: twine check dist/*
41
+ - uses: actions/upload-artifact@v4
42
+ with:
43
+ name: dist
44
+ path: dist/
45
+
46
+ publish-testpypi:
47
+ needs: build
48
+ if: >-
49
+ github.event_name == 'workflow_dispatch' && inputs.target == 'testpypi'
50
+ || (github.event_name == 'push' && contains(github.ref_name, 'rc'))
51
+ runs-on: ubuntu-latest
52
+ environment: testpypi
53
+ permissions:
54
+ id-token: write
55
+ steps:
56
+ - uses: actions/download-artifact@v4
57
+ with:
58
+ name: dist
59
+ path: dist/
60
+ - uses: pypa/gh-action-pypi-publish@release/v1
61
+ with:
62
+ repository-url: https://test.pypi.org/legacy/
63
+
64
+ publish-pypi:
65
+ needs: build
66
+ if: >-
67
+ github.event_name == 'workflow_dispatch' && inputs.target == 'pypi'
68
+ || (github.event_name == 'push' && !contains(github.ref_name, 'rc'))
69
+ runs-on: ubuntu-latest
70
+ environment: pypi
71
+ permissions:
72
+ id-token: write
73
+ steps:
74
+ - uses: actions/download-artifact@v4
75
+ with:
76
+ name: dist
77
+ path: dist/
78
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,12 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .pytest_cache/
4
+ *.egg-info/
5
+ build/
6
+ dist/
7
+ .venv/
8
+ venv/
9
+
10
+ # Local working notes, not part of the published project (until explicitly committed).
11
+ CLAUDE.md
12
+ dev-notes/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kazunari Kaizu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,113 @@
1
+ Metadata-Version: 2.4
2
+ Name: ofplang-validate
3
+ Version: 0.1.0rc1
4
+ Summary: Object-flow programming language v0 validator
5
+ Author-email: Kazunari Kaizu <kwaizu@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/ofplang/validate
8
+ Project-URL: Repository, https://github.com/ofplang/validate
9
+ Keywords: ofplang,dataflow,workflow,validator,yaml
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Software Development :: Compilers
19
+ Classifier: Typing :: Typed
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: PyYAML>=6.0
24
+ Provides-Extra: test
25
+ Requires-Dist: pytest>=7.0; extra == "test"
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest>=7.0; extra == "dev"
28
+ Requires-Dist: ruff>=0.16; extra == "dev"
29
+ Requires-Dist: mypy>=1.11; extra == "dev"
30
+ Requires-Dist: types-PyYAML; extra == "dev"
31
+ Dynamic: license-file
32
+
33
+ # ofplang validate
34
+
35
+ [![CI](https://github.com/ofplang/validate/actions/workflows/ci.yml/badge.svg)](https://github.com/ofplang/validate/actions/workflows/ci.yml)
36
+
37
+ A validator for **Object-flow Programming Language v0** — a YAML-based dataflow
38
+ workflow IR with linear Object tracking. The language is defined in the
39
+ [ofplang/spec](https://github.com/ofplang/spec) repository.
40
+
41
+ The validator checks that a document is well-formed portable v0: structure and
42
+ types, the feature model, linear Object tracking, structured nodes, contracts,
43
+ and scheduling policies. It reports findings as stable **error codes** rather
44
+ than free text, so results are easy to consume in tests and tooling.
45
+
46
+ ## Install
47
+
48
+ ```sh
49
+ pip install -e ".[test]"
50
+ ```
51
+
52
+ Requires Python 3.10+. The only runtime dependency is PyYAML.
53
+
54
+ ## Command line
55
+
56
+ ```sh
57
+ ofp-validate <file>... # or: python -m ofplang.validate <file>...
58
+ ofp-validate --mode extension-tolerant doc.yaml
59
+ ofp-validate --format json doc.yaml
60
+ ```
61
+
62
+ Options: `--mode {strict,extension-tolerant}`, `--format {text,json}`,
63
+ `-q/--quiet`, `--no-color`.
64
+
65
+ Exit codes: `0` all valid, `1` validation errors found, `2` usage/input error.
66
+
67
+ ```
68
+ $ ofp-validate workflow.yaml
69
+ workflow.yaml:7:15: error unknown_type processes.main.inputs.x.type unknown type in 'Foo'
70
+ 1 error in 1 of 1 file
71
+ ```
72
+
73
+ Diagnostics carry a `file:line:col` source position (an imported fragment's own
74
+ file when the problem is inside an `$import`); `--format json` includes
75
+ `file`/`line`/`col` fields.
76
+
77
+ This tool is also intended to be exposed as the `validate` subcommand of the
78
+ umbrella `ofp` CLI (a separate repository in the `ofplang` organization).
79
+
80
+ ## Library
81
+
82
+ ```python
83
+ from ofplang.validate import validate
84
+
85
+ result = validate("workflow.yaml", mode="strict")
86
+ if not result.ok:
87
+ for d in result.diagnostics:
88
+ print(d.code, d.path, d.message)
89
+ ```
90
+
91
+ `validate(source, *, mode="strict")` returns a `ValidationResult` with `.ok` and
92
+ `.diagnostics` (each a `Diagnostic(code, message, path, file, line, col)`). The
93
+ validator collects all independent findings rather than stopping at the first;
94
+ only a YAML parse or `$import` resolution failure is terminal.
95
+
96
+ The package lives under the `ofplang` PEP 420 namespace (`ofplang.validate`),
97
+ shared across the organization's tools.
98
+
99
+ ## Scope
100
+
101
+ Covers graph-time validation of portable v0. Runtime failures, and run/data-phase
102
+ preflight checks, are out of scope (spec §6.2, §25). Two modes are supported:
103
+ `strict` (portable v0) and `extension-tolerant` (accepts `x-` extension keys).
104
+
105
+ ## Tests
106
+
107
+ The behavior is pinned by a spec-derived conformance suite that matches on error
108
+ codes (see [tests/conformance/README.md](tests/conformance/README.md)).
109
+
110
+ ```sh
111
+ pytest # run everything
112
+ OFPLANG_STRICT_TESTS=1 pytest # full contract, no pending escapes
113
+ ```
@@ -0,0 +1,81 @@
1
+ # ofplang validate
2
+
3
+ [![CI](https://github.com/ofplang/validate/actions/workflows/ci.yml/badge.svg)](https://github.com/ofplang/validate/actions/workflows/ci.yml)
4
+
5
+ A validator for **Object-flow Programming Language v0** — a YAML-based dataflow
6
+ workflow IR with linear Object tracking. The language is defined in the
7
+ [ofplang/spec](https://github.com/ofplang/spec) repository.
8
+
9
+ The validator checks that a document is well-formed portable v0: structure and
10
+ types, the feature model, linear Object tracking, structured nodes, contracts,
11
+ and scheduling policies. It reports findings as stable **error codes** rather
12
+ than free text, so results are easy to consume in tests and tooling.
13
+
14
+ ## Install
15
+
16
+ ```sh
17
+ pip install -e ".[test]"
18
+ ```
19
+
20
+ Requires Python 3.10+. The only runtime dependency is PyYAML.
21
+
22
+ ## Command line
23
+
24
+ ```sh
25
+ ofp-validate <file>... # or: python -m ofplang.validate <file>...
26
+ ofp-validate --mode extension-tolerant doc.yaml
27
+ ofp-validate --format json doc.yaml
28
+ ```
29
+
30
+ Options: `--mode {strict,extension-tolerant}`, `--format {text,json}`,
31
+ `-q/--quiet`, `--no-color`.
32
+
33
+ Exit codes: `0` all valid, `1` validation errors found, `2` usage/input error.
34
+
35
+ ```
36
+ $ ofp-validate workflow.yaml
37
+ workflow.yaml:7:15: error unknown_type processes.main.inputs.x.type unknown type in 'Foo'
38
+ 1 error in 1 of 1 file
39
+ ```
40
+
41
+ Diagnostics carry a `file:line:col` source position (an imported fragment's own
42
+ file when the problem is inside an `$import`); `--format json` includes
43
+ `file`/`line`/`col` fields.
44
+
45
+ This tool is also intended to be exposed as the `validate` subcommand of the
46
+ umbrella `ofp` CLI (a separate repository in the `ofplang` organization).
47
+
48
+ ## Library
49
+
50
+ ```python
51
+ from ofplang.validate import validate
52
+
53
+ result = validate("workflow.yaml", mode="strict")
54
+ if not result.ok:
55
+ for d in result.diagnostics:
56
+ print(d.code, d.path, d.message)
57
+ ```
58
+
59
+ `validate(source, *, mode="strict")` returns a `ValidationResult` with `.ok` and
60
+ `.diagnostics` (each a `Diagnostic(code, message, path, file, line, col)`). The
61
+ validator collects all independent findings rather than stopping at the first;
62
+ only a YAML parse or `$import` resolution failure is terminal.
63
+
64
+ The package lives under the `ofplang` PEP 420 namespace (`ofplang.validate`),
65
+ shared across the organization's tools.
66
+
67
+ ## Scope
68
+
69
+ Covers graph-time validation of portable v0. Runtime failures, and run/data-phase
70
+ preflight checks, are out of scope (spec §6.2, §25). Two modes are supported:
71
+ `strict` (portable v0) and `extension-tolerant` (accepts `x-` extension keys).
72
+
73
+ ## Tests
74
+
75
+ The behavior is pinned by a spec-derived conformance suite that matches on error
76
+ codes (see [tests/conformance/README.md](tests/conformance/README.md)).
77
+
78
+ ```sh
79
+ pytest # run everything
80
+ OFPLANG_STRICT_TESTS=1 pytest # full contract, no pending escapes
81
+ ```
@@ -0,0 +1,19 @@
1
+ """ofplang.validate -- validator for Object-flow Programming Language v0."""
2
+
3
+ from ofplang.validate.validator import (
4
+ EXTENSION_TOLERANT,
5
+ MODES,
6
+ STRICT,
7
+ Diagnostic,
8
+ ValidationResult,
9
+ validate,
10
+ )
11
+
12
+ __all__ = [
13
+ "Diagnostic",
14
+ "ValidationResult",
15
+ "validate",
16
+ "STRICT",
17
+ "EXTENSION_TOLERANT",
18
+ "MODES",
19
+ ]
@@ -0,0 +1,9 @@
1
+ """Enable `python -m ofplang <file>...`.
2
+
3
+ Intent: mirror the console-script entry point so the CLI is reachable without an
4
+ installed script, which is convenient in dev checkouts and CI.
5
+ """
6
+
7
+ from ofplang.validate.cli import main
8
+
9
+ raise SystemExit(main())
@@ -0,0 +1,178 @@
1
+ """Command-line interface for the ofplang v0 validator.
2
+
3
+ Intent: this is a thin presentation layer over :func:`ofplang.validate.validate` — it
4
+ does no validation itself, it only parses arguments, drives the library over one
5
+ or more files, and renders results. Keeping all logic in the library means the
6
+ CLI cannot drift from the conformance-tested behavior.
7
+
8
+ Usage:
9
+ ofp-validate [--mode {strict,extension-tolerant}] [--format {text,json}]
10
+ [-q/--quiet] [--no-color] <file>...
11
+
12
+ Also invocable as `python -m ofplang.validate`, and (once installed) as the
13
+ `validate` subcommand of the umbrella `ofp` CLI.
14
+
15
+ Exit codes (linter convention):
16
+ 0 every file is valid
17
+ 1 at least one file has validation errors
18
+ 2 usage / input error (bad arguments, missing input file)
19
+ """
20
+
21
+ from __future__ import annotations
22
+
23
+ import argparse
24
+ import json
25
+ import sys
26
+ from pathlib import Path
27
+
28
+ from ofplang.validate import validate
29
+ from ofplang.validate.validator import EXTENSION_TOLERANT, STRICT, ValidationResult
30
+
31
+ # Exit codes are part of the CLI contract (scripts/CI depend on them).
32
+ EXIT_OK = 0
33
+ EXIT_INVALID = 1
34
+ EXIT_USAGE = 2
35
+
36
+ # ANSI colors, applied only when writing to a TTY and not disabled.
37
+ _RED = "\033[31m"
38
+ _GREEN = "\033[32m"
39
+ _DIM = "\033[2m"
40
+ _RESET = "\033[0m"
41
+
42
+
43
+ def _build_parser() -> argparse.ArgumentParser:
44
+ parser = argparse.ArgumentParser(
45
+ prog="ofp-validate",
46
+ description="Validate ofplang v0 documents.",
47
+ )
48
+ parser.add_argument("paths", nargs="+", metavar="FILE", help="document(s) to validate")
49
+ parser.add_argument(
50
+ "--mode",
51
+ choices=[STRICT, EXTENSION_TOLERANT],
52
+ default=STRICT,
53
+ help="validation mode (default: strict)",
54
+ )
55
+ parser.add_argument(
56
+ "--format",
57
+ choices=["text", "json"],
58
+ default="text",
59
+ help="output format (default: text)",
60
+ )
61
+ parser.add_argument(
62
+ "-q",
63
+ "--quiet",
64
+ action="store_true",
65
+ help="suppress per-diagnostic lines; show only the summary",
66
+ )
67
+ parser.add_argument("--no-color", action="store_true", help="disable ANSI color output")
68
+ return parser
69
+
70
+
71
+ def _color_enabled(no_color: bool) -> bool:
72
+ # Color only when explicitly allowed AND attached to a terminal, so piped or
73
+ # redirected output stays clean and parseable.
74
+ return not no_color and sys.stdout.isatty()
75
+
76
+
77
+ def _render_text(results: list[tuple[str, ValidationResult]], quiet: bool, color: bool) -> str:
78
+ """Human-oriented report. One block per file, then a one-line summary."""
79
+ def c(text: str, code: str) -> str:
80
+ return f"{code}{text}{_RESET}" if color else text
81
+
82
+ lines: list[str] = []
83
+ total_errors = 0
84
+ invalid_files = 0
85
+ multi = len(results) > 1
86
+
87
+ for path, result in results:
88
+ if result.ok:
89
+ # Only announce OK files explicitly when validating several, so
90
+ # single-file runs stay terse.
91
+ if not quiet and multi:
92
+ lines.append(f"{path}: {c('OK', _GREEN)}")
93
+ continue
94
+ invalid_files += 1
95
+ total_errors += len(result.diagnostics)
96
+ if multi:
97
+ lines.append(f"{path}:")
98
+ if not quiet:
99
+ for d in result.diagnostics:
100
+ # Prefer a concrete source position as the locator; fall back to
101
+ # the logical path. When both exist, show the path as a dim
102
+ # trailing detail (position primary, path for context).
103
+ if d.location:
104
+ locator = d.location
105
+ detail = f" {c(d.path, _DIM)}" if d.path else ""
106
+ else:
107
+ locator = d.path or "<root>"
108
+ detail = ""
109
+ msg = f" {d.message}" if d.message else ""
110
+ indent = " " if multi else ""
111
+ lines.append(f"{indent}{locator}: {c('error', _RED)} {d.code}{detail}{msg}")
112
+
113
+ if total_errors == 0:
114
+ lines.append(
115
+ c(f"all valid ({len(results)} file{'s' if len(results) != 1 else ''})", _GREEN)
116
+ )
117
+ else:
118
+ lines.append(
119
+ c(f"{total_errors} error{'s' if total_errors != 1 else ''} in "
120
+ f"{invalid_files} of {len(results)} file{'s' if len(results) != 1 else ''}", _RED)
121
+ )
122
+ return "\n".join(lines)
123
+
124
+
125
+ def _render_json(results: list[tuple[str, ValidationResult]]) -> str:
126
+ """Machine-readable report for CI/editor integration."""
127
+ payload = {
128
+ "ok": all(r.ok for _, r in results),
129
+ "results": [
130
+ {
131
+ "file": path,
132
+ "ok": result.ok,
133
+ "diagnostics": [
134
+ {
135
+ "code": d.code,
136
+ "path": d.path,
137
+ "message": d.message,
138
+ "file": d.file,
139
+ "line": d.line,
140
+ "col": d.col,
141
+ }
142
+ for d in result.diagnostics
143
+ ],
144
+ }
145
+ for path, result in results
146
+ ],
147
+ }
148
+ return json.dumps(payload, indent=2, ensure_ascii=False)
149
+
150
+
151
+ def main(argv: list[str] | None = None) -> int:
152
+ parser = _build_parser()
153
+ args = parser.parse_args(argv)
154
+
155
+ # Pre-check inputs so a mistyped/missing path is a usage error (exit 2)
156
+ # rather than being reported as an in-document diagnostic.
157
+ missing = [p for p in args.paths if not Path(p).is_file()]
158
+ if missing:
159
+ for p in missing:
160
+ print(f"ofp-validate: cannot open {p!r}: no such file", file=sys.stderr)
161
+ return EXIT_USAGE
162
+
163
+ # Validate each file via the library (the sole source of truth).
164
+ results: list[tuple[str, ValidationResult]] = [
165
+ (p, validate(p, mode=args.mode)) for p in args.paths
166
+ ]
167
+
168
+ if args.format == "json":
169
+ print(_render_json(results))
170
+ else:
171
+ print(_render_text(results, args.quiet, _color_enabled(args.no_color)))
172
+
173
+ # Exit code reflects the worst outcome across all inputs.
174
+ return EXIT_OK if all(r.ok for _, r in results) else EXIT_INVALID
175
+
176
+
177
+ if __name__ == "__main__": # pragma: no cover - module entry
178
+ raise SystemExit(main())