codeplain 0.2.16__tar.gz → 0.2.18__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 (199) hide show
  1. {codeplain-0.2.16 → codeplain-0.2.18}/PKG-INFO +1 -1
  2. codeplain-0.2.18/_version.py +1 -0
  3. {codeplain-0.2.16 → codeplain-0.2.18}/examples/example_hello_world_python/hello_world_python.plain +0 -2
  4. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/render_utils.py +31 -8
  5. codeplain-0.2.16/_version.py +0 -1
  6. codeplain-0.2.16/examples/example_hello_world_python/python-console-app-boilerplate.plain +0 -13
  7. {codeplain-0.2.16 → codeplain-0.2.18}/.claude/settings.local.json +0 -0
  8. {codeplain-0.2.16 → codeplain-0.2.18}/.flake8 +0 -0
  9. {codeplain-0.2.16 → codeplain-0.2.18}/.github/workflows/lint-and-test.yml +0 -0
  10. {codeplain-0.2.16 → codeplain-0.2.18}/.github/workflows/nofity-slack-on-main-merge.yml +0 -0
  11. {codeplain-0.2.16 → codeplain-0.2.18}/.github/workflows/publish-install-script.yml +0 -0
  12. {codeplain-0.2.16 → codeplain-0.2.18}/.github/workflows/publish-to-pypi.yml +0 -0
  13. {codeplain-0.2.16 → codeplain-0.2.18}/.gitignore +0 -0
  14. {codeplain-0.2.16 → codeplain-0.2.18}/.vscode/launch.json +0 -0
  15. {codeplain-0.2.16 → codeplain-0.2.18}/.vscode/settings.json +0 -0
  16. {codeplain-0.2.16 → codeplain-0.2.18}/LICENSE +0 -0
  17. {codeplain-0.2.16 → codeplain-0.2.18}/README.md +0 -0
  18. {codeplain-0.2.16 → codeplain-0.2.18}/codeplain_REST_api.py +0 -0
  19. {codeplain-0.2.16 → codeplain-0.2.18}/concept_utils.py +0 -0
  20. {codeplain-0.2.16 → codeplain-0.2.18}/config/__init__.py +0 -0
  21. {codeplain-0.2.16 → codeplain-0.2.18}/config/system_config.yaml +0 -0
  22. {codeplain-0.2.16 → codeplain-0.2.18}/diff_utils.py +0 -0
  23. {codeplain-0.2.16 → codeplain-0.2.18}/docs/generate_cli.py +0 -0
  24. {codeplain-0.2.16 → codeplain-0.2.18}/docs/plain2code_cli.md +0 -0
  25. {codeplain-0.2.16 → codeplain-0.2.18}/docs/starting_a_plain_project_from_scratch.md +0 -0
  26. {codeplain-0.2.16 → codeplain-0.2.18}/event_bus.py +0 -0
  27. {codeplain-0.2.16 → codeplain-0.2.18}/examples/example_hello_world_golang/config.yaml +0 -0
  28. {codeplain-0.2.16 → codeplain-0.2.18}/examples/example_hello_world_golang/harness_tests/hello_world_test.go +0 -0
  29. {codeplain-0.2.16 → codeplain-0.2.18}/examples/example_hello_world_golang/hello_world_golang.plain +0 -0
  30. {codeplain-0.2.16 → codeplain-0.2.18}/examples/example_hello_world_golang/run.sh +0 -0
  31. {codeplain-0.2.16 → codeplain-0.2.18}/examples/example_hello_world_python/config.yaml +0 -0
  32. {codeplain-0.2.16 → codeplain-0.2.18}/examples/example_hello_world_python/harness_tests/hello_world_display/test_hello_world.py +0 -0
  33. {codeplain-0.2.16 → codeplain-0.2.18}/examples/example_hello_world_python/run.sh +0 -0
  34. {codeplain-0.2.16 → codeplain-0.2.18}/examples/example_hello_world_react/config.yaml +0 -0
  35. {codeplain-0.2.16 → codeplain-0.2.18}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/e2e/hello_world.cy.ts +0 -0
  36. {codeplain-0.2.16 → codeplain-0.2.18}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/support/e2e.ts +0 -0
  37. {codeplain-0.2.16 → codeplain-0.2.18}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress.config.ts +0 -0
  38. {codeplain-0.2.16 → codeplain-0.2.18}/examples/example_hello_world_react/harness_tests/hello_world_display/package.json +0 -0
  39. {codeplain-0.2.16 → codeplain-0.2.18}/examples/example_hello_world_react/harness_tests/hello_world_display/tsconfig.json +0 -0
  40. {codeplain-0.2.16 → codeplain-0.2.18}/examples/example_hello_world_react/hello_world_react.plain +0 -0
  41. {codeplain-0.2.16 → codeplain-0.2.18}/examples/example_hello_world_react/run.sh +0 -0
  42. {codeplain-0.2.16 → codeplain-0.2.18}/examples/run.sh +0 -0
  43. {codeplain-0.2.16 → codeplain-0.2.18}/file_utils.py +0 -0
  44. {codeplain-0.2.16 → codeplain-0.2.18}/git_utils.py +0 -0
  45. {codeplain-0.2.16 → codeplain-0.2.18}/hash_key.py +0 -0
  46. {codeplain-0.2.16 → codeplain-0.2.18}/install/bash/examples.sh +0 -0
  47. {codeplain-0.2.16 → codeplain-0.2.18}/install/bash/install.sh +0 -0
  48. {codeplain-0.2.16 → codeplain-0.2.18}/install/bash/walkthrough.sh +0 -0
  49. {codeplain-0.2.16 → codeplain-0.2.18}/install/powershell/examples.ps1 +0 -0
  50. {codeplain-0.2.16 → codeplain-0.2.18}/install/powershell/install.ps1 +0 -0
  51. {codeplain-0.2.16 → codeplain-0.2.18}/install/powershell/walkthrough.ps1 +0 -0
  52. {codeplain-0.2.16 → codeplain-0.2.18}/memory_management.py +0 -0
  53. {codeplain-0.2.16 → codeplain-0.2.18}/module_renderer.py +0 -0
  54. {codeplain-0.2.16 → codeplain-0.2.18}/plain2code.py +0 -0
  55. {codeplain-0.2.16 → codeplain-0.2.18}/plain2code_arguments.py +0 -0
  56. {codeplain-0.2.16 → codeplain-0.2.18}/plain2code_console.py +0 -0
  57. {codeplain-0.2.16 → codeplain-0.2.18}/plain2code_events.py +0 -0
  58. {codeplain-0.2.16 → codeplain-0.2.18}/plain2code_exceptions.py +0 -0
  59. {codeplain-0.2.16 → codeplain-0.2.18}/plain2code_logger.py +0 -0
  60. {codeplain-0.2.16 → codeplain-0.2.18}/plain2code_nodes.py +0 -0
  61. {codeplain-0.2.16 → codeplain-0.2.18}/plain2code_read_config.py +0 -0
  62. {codeplain-0.2.16 → codeplain-0.2.18}/plain2code_state.py +0 -0
  63. {codeplain-0.2.16 → codeplain-0.2.18}/plain2code_utils.py +0 -0
  64. {codeplain-0.2.16 → codeplain-0.2.18}/plain_file.py +0 -0
  65. {codeplain-0.2.16 → codeplain-0.2.18}/plain_modules.py +0 -0
  66. {codeplain-0.2.16 → codeplain-0.2.18}/plain_spec.py +0 -0
  67. {codeplain-0.2.16 → codeplain-0.2.18}/pyproject.toml +0 -0
  68. {codeplain-0.2.16 → codeplain-0.2.18}/pytest.ini +0 -0
  69. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/__init__.py +0 -0
  70. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/actions/analyze_specification_ambiguity.py +0 -0
  71. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/actions/base_action.py +0 -0
  72. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/actions/commit_conformance_tests_changes.py +0 -0
  73. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/actions/commit_implementation_code_changes.py +0 -0
  74. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/actions/create_dist.py +0 -0
  75. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/actions/exit_with_error.py +0 -0
  76. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/actions/finish_functional_requirement.py +0 -0
  77. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/actions/fix_conformance_test.py +0 -0
  78. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/actions/fix_unit_tests.py +0 -0
  79. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/actions/prepare_repositories.py +0 -0
  80. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/actions/prepare_testing_environment.py +0 -0
  81. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/actions/refactor_code.py +0 -0
  82. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/actions/render_conformance_tests.py +0 -0
  83. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/actions/render_functional_requirement.py +0 -0
  84. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/actions/run_conformance_tests.py +0 -0
  85. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/actions/run_unit_tests.py +0 -0
  86. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/actions/summarize_conformance_tests.py +0 -0
  87. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/code_renderer.py +0 -0
  88. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/conformance_test_helpers.py +0 -0
  89. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/conformance_tests.py +0 -0
  90. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/implementation_code_helpers.py +0 -0
  91. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/render_context.py +0 -0
  92. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/render_types.py +0 -0
  93. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/state_machine_config.py +0 -0
  94. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/states.py +0 -0
  95. {codeplain-0.2.16 → codeplain-0.2.18}/render_machine/triggers.py +0 -0
  96. {codeplain-0.2.16 → codeplain-0.2.18}/requirements.txt +0 -0
  97. {codeplain-0.2.16 → codeplain-0.2.18}/resources/codeplain_overview.png +0 -0
  98. {codeplain-0.2.16 → codeplain-0.2.18}/resources/plain_example.png +0 -0
  99. {codeplain-0.2.16 → codeplain-0.2.18}/standard_template_library/__init__.py +0 -0
  100. {codeplain-0.2.16 → codeplain-0.2.18}/standard_template_library/golang-console-app-template.plain +0 -0
  101. {codeplain-0.2.16 → codeplain-0.2.18}/standard_template_library/python-console-app-template.plain +0 -0
  102. {codeplain-0.2.16 → codeplain-0.2.18}/standard_template_library/typescript-react-app-boilerplate.plain +0 -0
  103. {codeplain-0.2.16 → codeplain-0.2.18}/standard_template_library/typescript-react-app-template.plain +0 -0
  104. {codeplain-0.2.16 → codeplain-0.2.18}/system_config.py +0 -0
  105. {codeplain-0.2.16 → codeplain-0.2.18}/test_scripts/run_conformance_tests_cypress.sh +0 -0
  106. {codeplain-0.2.16 → codeplain-0.2.18}/test_scripts/run_conformance_tests_golang.sh +0 -0
  107. {codeplain-0.2.16 → codeplain-0.2.18}/test_scripts/run_conformance_tests_python.sh +0 -0
  108. {codeplain-0.2.16 → codeplain-0.2.18}/test_scripts/run_unittests_golang.sh +0 -0
  109. {codeplain-0.2.16 → codeplain-0.2.18}/test_scripts/run_unittests_python.sh +0 -0
  110. {codeplain-0.2.16 → codeplain-0.2.18}/test_scripts/run_unittests_react.sh +0 -0
  111. {codeplain-0.2.16 → codeplain-0.2.18}/tests/__init__.py +0 -0
  112. {codeplain-0.2.16 → codeplain-0.2.18}/tests/conftest.py +0 -0
  113. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/imports/circular_imports_1.plain +0 -0
  114. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/imports/circular_imports_2.plain +0 -0
  115. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/imports/circular_imports_main.plain +0 -0
  116. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/imports/diamond_import_1.plain +0 -0
  117. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/imports/diamond_import_2.plain +0 -0
  118. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/imports/diamond_import_common.plain +0 -0
  119. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/imports/diamond_imports_main.plain +0 -0
  120. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/imports/non_existent_import.plain +0 -0
  121. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfile/duplicate_specification_heading.plain +0 -0
  122. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfile/invalid_specification_order.plain +0 -0
  123. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfile/missing_non_functional_requirements.plain +0 -0
  124. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfile/plain_source_with_absolute_link.plain +0 -0
  125. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfile/plain_source_with_url_link.plain +0 -0
  126. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfile/task_manager_with_reference_links.plain +0 -0
  127. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfile/without_non_functional_requirement.plain +0 -0
  128. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/concept_validation_acceptance_tests.plain +0 -0
  129. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/concept_validation_acceptance_tests_nondefined.plain +0 -0
  130. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/concept_validation_defined_nondefined.plain +0 -0
  131. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/concept_validation_defined_nondefined_2.plain +0 -0
  132. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/concept_validation_definition.plain +0 -0
  133. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/concept_validation_noconcepts.plain +0 -0
  134. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/concept_validation_nonconcept.plain +0 -0
  135. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/concept_validation_nondefined.plain +0 -0
  136. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/concept_validation_redefinition.plain +0 -0
  137. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/concept_validation_several_concepts.plain +0 -0
  138. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/concept_validation_valid.plain +0 -0
  139. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/exported_concepts.plain +0 -0
  140. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/exported_concepts_base.plain +0 -0
  141. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/exported_concepts_example.plain +0 -0
  142. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/exported_concepts_missing.plain +0 -0
  143. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/exported_concepts_missing_example.plain +0 -0
  144. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/exported_concepts_nested.plain +0 -0
  145. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/exported_concepts_nested_example.plain +0 -0
  146. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/exported_concepts_transitive_example.plain +0 -0
  147. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/exported_concepts_transitive_l1.plain +0 -0
  148. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/exported_concepts_transitive_l2.plain +0 -0
  149. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/plain_file_parser_with_comments.plain +0 -0
  150. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/plain_file_with_comments_indented.plain +0 -0
  151. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/regular_plain_source.plain +0 -0
  152. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/required_concepts.plain +0 -0
  153. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/required_concepts_defs.plain +0 -0
  154. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/required_concepts_example.plain +0 -0
  155. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/required_concepts_l1.plain +0 -0
  156. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/required_concepts_l2.plain +0 -0
  157. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/required_concepts_missing.plain +0 -0
  158. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/required_concepts_module.plain +0 -0
  159. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/required_concepts_partial.plain +0 -0
  160. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/required_concepts_partial_duplicate.plain +0 -0
  161. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/topological_sort.plain +0 -0
  162. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/plainfileparser/topological_sort_not_referenced.plain +0 -0
  163. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/requires/circular_requires_main.plain +0 -0
  164. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/requires/circular_requires_sub.plain +0 -0
  165. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/requires/diamond_requires_1.plain +0 -0
  166. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/requires/diamond_requires_2.plain +0 -0
  167. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/requires/diamond_requires_common.plain +0 -0
  168. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/requires/diamond_requires_main.plain +0 -0
  169. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/requires/independent_requires_1.plain +0 -0
  170. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/requires/independent_requires_2.plain +0 -0
  171. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/requires/independent_requires_main.plain +0 -0
  172. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/requires/non_existent_require.plain +0 -0
  173. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/requires/normal_requires_1.plain +0 -0
  174. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/requires/normal_requires_2.plain +0 -0
  175. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/requires/normal_requires_common.plain +0 -0
  176. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/requires/normal_requires_main.plain +0 -0
  177. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/simple.plain +0 -0
  178. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/templates/block_level_include.plain +0 -0
  179. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/templates/code_variables.plain +0 -0
  180. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/templates/header.plain +0 -0
  181. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/templates/implement.plain +0 -0
  182. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/templates/implement_2.plain +0 -0
  183. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/templates/template_include.plain +0 -0
  184. {codeplain-0.2.16 → codeplain-0.2.18}/tests/data/templates/test_hardest_problem.plain +0 -0
  185. {codeplain-0.2.16 → codeplain-0.2.18}/tests/test_git_utils.py +0 -0
  186. {codeplain-0.2.16 → codeplain-0.2.18}/tests/test_imports.py +0 -0
  187. {codeplain-0.2.16 → codeplain-0.2.18}/tests/test_plainfile.py +0 -0
  188. {codeplain-0.2.16 → codeplain-0.2.18}/tests/test_plainfileparser.py +0 -0
  189. {codeplain-0.2.16 → codeplain-0.2.18}/tests/test_plainspec.py +0 -0
  190. {codeplain-0.2.16 → codeplain-0.2.18}/tests/test_requires.py +0 -0
  191. {codeplain-0.2.16 → codeplain-0.2.18}/tests/test_resolve_config_file.py +0 -0
  192. {codeplain-0.2.16 → codeplain-0.2.18}/tui/__init__.py +0 -0
  193. {codeplain-0.2.16 → codeplain-0.2.18}/tui/components.py +0 -0
  194. {codeplain-0.2.16 → codeplain-0.2.18}/tui/models.py +0 -0
  195. {codeplain-0.2.16 → codeplain-0.2.18}/tui/plain2code_tui.py +0 -0
  196. {codeplain-0.2.16 → codeplain-0.2.18}/tui/spinner.py +0 -0
  197. {codeplain-0.2.16 → codeplain-0.2.18}/tui/state_handlers.py +0 -0
  198. {codeplain-0.2.16 → codeplain-0.2.18}/tui/styles.css +0 -0
  199. {codeplain-0.2.16 → codeplain-0.2.18}/tui/widget_helpers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codeplain
3
- Version: 0.2.16
3
+ Version: 0.2.18
4
4
  Summary: Transform plain language specifications into working code
5
5
  License-File: LICENSE
6
6
  Classifier: Environment :: Console
@@ -0,0 +1 @@
1
+ __version__ = "0.2.18"
@@ -2,8 +2,6 @@
2
2
  description: '"hello, world" in Plain (Python version)'
3
3
  import:
4
4
  - python-console-app-template
5
- requires:
6
- - python-console-app-boilerplate
7
5
  ---
8
6
 
9
7
  ***implementation reqs***
@@ -19,7 +19,7 @@ SCRIPT_EXECUTION_TIMEOUT = 120
19
19
  TIMEOUT_ERROR_EXIT_CODE = 124
20
20
  POLL_INTERVAL_SECONDS = 0.2
21
21
  SIGTERM_GRACE_PERIOD_SECONDS = 0.2
22
- STDOUT_READ_TIMEOUT_SECONDS = 5
22
+ STDOUT_READ_TIMEOUT_SECONDS = 2
23
23
  F_SETPIPE_SIZE = 1031 # Linux-only constant
24
24
  PIPE_SIZE_KB = 1024 # 1MB
25
25
 
@@ -120,11 +120,27 @@ def execute_script( # noqa: C901
120
120
  # Set the pipe size to 1MB to avoid buffer overflows
121
121
  fcntl.fcntl(proc.stdout.fileno(), F_SETPIPE_SIZE, PIPE_SIZE_KB * 1024) # 1MB
122
122
 
123
+ # Drain stdout in a background thread to prevent pipe buffer deadlock.
124
+ # macOS has a 64KB pipe buffer; without continuous draining, scripts that produce
125
+ # more output than that block on write and never exit, causing spurious timeouts.
126
+ output_chunks: list[str] = []
127
+
128
+ def _drain_stdout() -> None:
129
+ try:
130
+ for chunk in iter(lambda: proc.stdout.read(8192), ""):
131
+ output_chunks.append(chunk)
132
+ except (OSError, ValueError):
133
+ pass
134
+
135
+ reader = threading.Thread(target=_drain_stdout, daemon=True)
136
+ reader.start()
137
+
123
138
  try:
124
139
  while proc.poll() is None:
125
140
  if time.time() - start_time >= script_timeout:
126
141
  _kill_process(proc)
127
- partial_stdout = proc.stdout.read()
142
+ reader.join(timeout=2)
143
+ partial_stdout = "".join(output_chunks)
128
144
  exc = subprocess.TimeoutExpired(cmd, script_timeout)
129
145
  exc.stdout = partial_stdout
130
146
  raise exc
@@ -136,12 +152,13 @@ def execute_script( # noqa: C901
136
152
  else:
137
153
  time.sleep(POLL_INTERVAL_SECONDS)
138
154
 
139
- # Use communicate() with a timeout because child processes may hold the pipe open after the main process exits.
140
- try:
141
- stdout, _ = proc.communicate(timeout=STDOUT_READ_TIMEOUT_SECONDS)
142
- except subprocess.TimeoutExpired:
155
+ # Wait for the reader to finish draining remaining output.
156
+ # Close stdout if child processes keep the pipe open beyond the grace period.
157
+ reader.join(timeout=STDOUT_READ_TIMEOUT_SECONDS)
158
+ if reader.is_alive():
143
159
  proc.stdout.close()
144
- stdout = ""
160
+ reader.join(timeout=1)
161
+ stdout = "".join(output_chunks)
145
162
  elapsed_time = time.time() - start_time
146
163
 
147
164
  sanitized_script_output = _sanitize_script_output(stdout)
@@ -201,8 +218,14 @@ def execute_script( # noqa: C901
201
218
  f"The {script_type} script timed out after {script_timeout} seconds. {script_type} script output stored in: {temp_file_path}"
202
219
  )
203
220
 
221
+ partial_output = ""
222
+ if e.stdout:
223
+ decoded = e.stdout.decode("utf-8") if isinstance(e.stdout, bytes) else e.stdout
224
+ sanitized = _sanitize_script_output(decoded)
225
+ if sanitized:
226
+ partial_output = f"\nPartial test script output:\n{sanitized}"
204
227
  return (
205
228
  TIMEOUT_ERROR_EXIT_CODE,
206
- f"{script_type} script did not finish in {script_timeout} seconds.",
229
+ f"{script_type} script did not finish in {script_timeout} seconds.{partial_output}",
207
230
  temp_file_path,
208
231
  )
@@ -1 +0,0 @@
1
- __version__ = "0.2.16"
@@ -1,13 +0,0 @@
1
- ---
2
- import:
3
- - python-console-app-template
4
- ---
5
-
6
- ***implementation reqs***
7
-
8
- - :Implementation: should be in Python.
9
-
10
- ***functional specs***
11
-
12
- - Implement the entrypoint of :App:.
13
-
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes