p5py-vibe 0.1.0__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 (200) hide show
  1. p5py_vibe-0.1.0/.github/workflows/ci.yml +41 -0
  2. p5py_vibe-0.1.0/.github/workflows/publish.yml +105 -0
  3. p5py_vibe-0.1.0/.gitignore +226 -0
  4. p5py_vibe-0.1.0/.python-version +1 -0
  5. p5py_vibe-0.1.0/AGENTS.md +349 -0
  6. p5py_vibe-0.1.0/CHANGELOG.md +16 -0
  7. p5py_vibe-0.1.0/Makefile +25 -0
  8. p5py_vibe-0.1.0/PKG-INFO +162 -0
  9. p5py_vibe-0.1.0/README.md +143 -0
  10. p5py_vibe-0.1.0/backlog/010_foundation_runtime/backend_protocols.toml +40 -0
  11. p5py_vibe-0.1.0/backlog/010_foundation_runtime/context_state.toml +33 -0
  12. p5py_vibe-0.1.0/backlog/010_foundation_runtime/package_scaffold.toml +40 -0
  13. p5py_vibe-0.1.0/backlog/010_foundation_runtime/sketch_lifecycle.toml +40 -0
  14. p5py_vibe-0.1.0/backlog/020_api_compatibility/compatibility_matrix.toml +33 -0
  15. p5py_vibe-0.1.0/backlog/020_api_compatibility/errors_and_overloads.toml +33 -0
  16. p5py_vibe-0.1.0/backlog/020_api_compatibility/global_mode_api.toml +33 -0
  17. p5py_vibe-0.1.0/backlog/020_api_compatibility/pythonic_aliases.toml +33 -0
  18. p5py_vibe-0.1.0/backlog/030_rendering_2d/basic_primitives.toml +33 -0
  19. p5py_vibe-0.1.0/backlog/030_rendering_2d/canvas_management.toml +33 -0
  20. p5py_vibe-0.1.0/backlog/030_rendering_2d/headless_pillow_renderer.toml +33 -0
  21. p5py_vibe-0.1.0/backlog/030_rendering_2d/hidpi_pixel_density.toml +68 -0
  22. p5py_vibe-0.1.0/backlog/030_rendering_2d/interactive_backend.toml +40 -0
  23. p5py_vibe-0.1.0/backlog/030_rendering_2d/paths_and_curves.toml +40 -0
  24. p5py_vibe-0.1.0/backlog/031_native_pyglet_renderer/basic_native_primitives.toml +40 -0
  25. p5py_vibe-0.1.0/backlog/031_native_pyglet_renderer/hidpi_native_rendering.toml +40 -0
  26. p5py_vibe-0.1.0/backlog/031_native_pyglet_renderer/migration_and_cleanup.toml +40 -0
  27. p5py_vibe-0.1.0/backlog/031_native_pyglet_renderer/pixels_export_fallbacks.toml +40 -0
  28. p5py_vibe-0.1.0/backlog/031_native_pyglet_renderer/renderer_architecture.toml +40 -0
  29. p5py_vibe-0.1.0/backlog/031_native_pyglet_renderer/transforms_paths_curves.toml +40 -0
  30. p5py_vibe-0.1.0/backlog/040_color_style_transform/color_system.toml +33 -0
  31. p5py_vibe-0.1.0/backlog/040_color_style_transform/constants_modes.toml +33 -0
  32. p5py_vibe-0.1.0/backlog/040_color_style_transform/style_stack.toml +33 -0
  33. p5py_vibe-0.1.0/backlog/040_color_style_transform/transform_stack.toml +33 -0
  34. p5py_vibe-0.1.0/backlog/050_math_vector_noise/math_helpers.toml +33 -0
  35. p5py_vibe-0.1.0/backlog/050_math_vector_noise/random_noise.toml +40 -0
  36. p5py_vibe-0.1.0/backlog/050_math_vector_noise/vector_class.toml +40 -0
  37. p5py_vibe-0.1.0/backlog/060_assets_images_text/data_loading_saving.toml +33 -0
  38. p5py_vibe-0.1.0/backlog/060_assets_images_text/image_loading_drawing.toml +40 -0
  39. p5py_vibe-0.1.0/backlog/060_assets_images_text/image_manipulation.toml +40 -0
  40. p5py_vibe-0.1.0/backlog/060_assets_images_text/text_fonts.toml +33 -0
  41. p5py_vibe-0.1.0/backlog/061_native_pyglet_assets_text_export/docs_examples_capabilities.toml +33 -0
  42. p5py_vibe-0.1.0/backlog/061_native_pyglet_assets_text_export/native_image_drawing.toml +40 -0
  43. p5py_vibe-0.1.0/backlog/061_native_pyglet_assets_text_export/native_save_canvas_pixels.toml +47 -0
  44. p5py_vibe-0.1.0/backlog/061_native_pyglet_assets_text_export/native_text_fonts.toml +40 -0
  45. p5py_vibe-0.1.0/backlog/061_native_pyglet_assets_text_export/renderer_capability_cleanup.toml +33 -0
  46. p5py_vibe-0.1.0/backlog/062_transformed_image_rendering/image_transform_semantics.toml +54 -0
  47. p5py_vibe-0.1.0/backlog/070_input_events/keyboard_events.toml +40 -0
  48. p5py_vibe-0.1.0/backlog/070_input_events/mouse_events.toml +40 -0
  49. p5py_vibe-0.1.0/backlog/070_input_events/touch_events.toml +33 -0
  50. p5py_vibe-0.1.0/backlog/080_pixels_compositing/blend_modes.toml +40 -0
  51. p5py_vibe-0.1.0/backlog/080_pixels_compositing/pixel_buffer.toml +40 -0
  52. p5py_vibe-0.1.0/backlog/080_pixels_compositing/save_export.toml +33 -0
  53. p5py_vibe-0.1.0/backlog/081_native_pyglet_rendering_parity/native_pixels_compositing_parity.toml +75 -0
  54. p5py_vibe-0.1.0/backlog/090_rust_acceleration/accelerated_noise_pixels.toml +40 -0
  55. p5py_vibe-0.1.0/backlog/090_rust_acceleration/maturin_pipeline.toml +40 -0
  56. p5py_vibe-0.1.0/backlog/100_3d_advanced_media/model_shader_strategy.toml +33 -0
  57. p5py_vibe-0.1.0/backlog/100_3d_advanced_media/sound_media_strategy.toml +33 -0
  58. p5py_vibe-0.1.0/backlog/100_3d_advanced_media/webgl_like_renderer.toml +40 -0
  59. p5py_vibe-0.1.0/backlog/101_native_3d_media_implementation/model_loading.toml +40 -0
  60. p5py_vibe-0.1.0/backlog/101_native_3d_media_implementation/sound_playback_analysis.toml +40 -0
  61. p5py_vibe-0.1.0/backlog/101_native_3d_media_implementation/webgl_public_api_primitives.toml +40 -0
  62. p5py_vibe-0.1.0/backlog/101_native_3d_media_implementation/webgl_renderer_activation.toml +40 -0
  63. p5py_vibe-0.1.0/backlog/102_native_gpu_webgl_follow_on/native_pyglet_depth_renderer.toml +33 -0
  64. p5py_vibe-0.1.0/backlog/102_native_gpu_webgl_follow_on/shader_pipeline.toml +40 -0
  65. p5py_vibe-0.1.0/backlog/103_native_media_video_capture/native_media_capture.toml +40 -0
  66. p5py_vibe-0.1.0/backlog/110_quality_docs_release/plugin_architecture.toml +33 -0
  67. p5py_vibe-0.1.0/backlog/110_quality_docs_release/release_packaging.toml +33 -0
  68. p5py_vibe-0.1.0/backlog/110_quality_docs_release/testing_tooling.toml +40 -0
  69. p5py_vibe-0.1.0/backlog/110_quality_docs_release/user_documentation.toml +33 -0
  70. p5py_vibe-0.1.0/crates/p5_accel/Cargo.toml +16 -0
  71. p5py_vibe-0.1.0/crates/p5_accel/src/lib.rs +163 -0
  72. p5py_vibe-0.1.0/docs/README.md +28 -0
  73. p5py_vibe-0.1.0/docs/technical/README.md +12 -0
  74. p5py_vibe-0.1.0/docs/technical/advanced_3d_media_strategy.md +276 -0
  75. p5py_vibe-0.1.0/docs/technical/epic_101_kt.md +126 -0
  76. p5py_vibe-0.1.0/docs/technical/hidpi_rendering.md +62 -0
  77. p5py_vibe-0.1.0/docs/technical/native_pyglet_renderer.md +213 -0
  78. p5py_vibe-0.1.0/docs/technical/project_plan.md +446 -0
  79. p5py_vibe-0.1.0/docs/technical/releasing.md +82 -0
  80. p5py_vibe-0.1.0/docs/technical/rust_acceleration.md +108 -0
  81. p5py_vibe-0.1.0/docs/technical/testing.md +86 -0
  82. p5py_vibe-0.1.0/docs/user/README.md +11 -0
  83. p5py_vibe-0.1.0/docs/user/backends.md +61 -0
  84. p5py_vibe-0.1.0/docs/user/compatibility.md +54 -0
  85. p5py_vibe-0.1.0/docs/user/events.md +61 -0
  86. p5py_vibe-0.1.0/docs/user/getting_started.md +73 -0
  87. p5py_vibe-0.1.0/docs/user/images_and_pixels.md +49 -0
  88. p5py_vibe-0.1.0/docs/user/lifecycle.md +83 -0
  89. p5py_vibe-0.1.0/docs/user/plugins.md +73 -0
  90. p5py_vibe-0.1.0/examples/README.md +41 -0
  91. p5py_vibe-0.1.0/examples/accelerated_noise_pixels.py +135 -0
  92. p5py_vibe-0.1.0/examples/assets/Effects/fire17.png +0 -0
  93. p5py_vibe-0.1.0/examples/assets/Effects/shield3.png +0 -0
  94. p5py_vibe-0.1.0/examples/assets/Lasers/laserBlue01.png +0 -0
  95. p5py_vibe-0.1.0/examples/assets/Meteors/meteorGrey_big1.png +0 -0
  96. p5py_vibe-0.1.0/examples/assets/Meteors/meteorGrey_med1.png +0 -0
  97. p5py_vibe-0.1.0/examples/assets/Meteors/meteorGrey_small1.png +0 -0
  98. p5py_vibe-0.1.0/examples/assets/Power-ups/powerupBlue_shield.png +0 -0
  99. p5py_vibe-0.1.0/examples/assets/coin-drop-4.wav +0 -0
  100. p5py_vibe-0.1.0/examples/assets/playerShip1_blue.png +0 -0
  101. p5py_vibe-0.1.0/examples/assets/playerShip3_green.png +0 -0
  102. p5py_vibe-0.1.0/examples/assets/teapot.obj +9965 -0
  103. p5py_vibe-0.1.0/examples/assets/ufoBlue.png +0 -0
  104. p5py_vibe-0.1.0/examples/asteroids.py +458 -0
  105. p5py_vibe-0.1.0/examples/audio_controls.py +126 -0
  106. p5py_vibe-0.1.0/examples/basic_shapes.py +67 -0
  107. p5py_vibe-0.1.0/examples/bouncing_ball.py +78 -0
  108. p5py_vibe-0.1.0/examples/color_style_filters.py +143 -0
  109. p5py_vibe-0.1.0/examples/custom_shape.py +61 -0
  110. p5py_vibe-0.1.0/examples/image_text_data.py +121 -0
  111. p5py_vibe-0.1.0/examples/pixels_blend_export.py +194 -0
  112. p5py_vibe-0.1.0/examples/plugin_hooks.py +52 -0
  113. p5py_vibe-0.1.0/examples/transforms.py +62 -0
  114. p5py_vibe-0.1.0/examples/vector_noise_flow.py +104 -0
  115. p5py_vibe-0.1.0/examples/video_capture.py +68 -0
  116. p5py_vibe-0.1.0/examples/video_playback.py +102 -0
  117. p5py_vibe-0.1.0/examples/webgl_native_shader.py +117 -0
  118. p5py_vibe-0.1.0/examples/webgl_obj_sound.py +72 -0
  119. p5py_vibe-0.1.0/examples/webgl_primitives_gallery.py +122 -0
  120. p5py_vibe-0.1.0/examples/webgl_texture_orbit.py +78 -0
  121. p5py_vibe-0.1.0/examples/webgl_wireframe_prototype.py +151 -0
  122. p5py_vibe-0.1.0/license.txt +458 -0
  123. p5py_vibe-0.1.0/main.py +6 -0
  124. p5py_vibe-0.1.0/pyproject.toml +70 -0
  125. p5py_vibe-0.1.0/src/p5_py/__init__.py +664 -0
  126. p5py_vibe-0.1.0/src/p5_py/api/__init__.py +1 -0
  127. p5py_vibe-0.1.0/src/p5_py/api/advanced.py +192 -0
  128. p5py_vibe-0.1.0/src/p5_py/api/aliases.py +202 -0
  129. p5py_vibe-0.1.0/src/p5_py/api/compatibility.py +269 -0
  130. p5py_vibe-0.1.0/src/p5_py/api/current.py +38 -0
  131. p5py_vibe-0.1.0/src/p5_py/api/global_mode.py +558 -0
  132. p5py_vibe-0.1.0/src/p5_py/assets/__init__.py +23 -0
  133. p5py_vibe-0.1.0/src/p5_py/assets/data.py +28 -0
  134. p5py_vibe-0.1.0/src/p5_py/assets/image.py +159 -0
  135. p5py_vibe-0.1.0/src/p5_py/assets/media.py +351 -0
  136. p5py_vibe-0.1.0/src/p5_py/assets/model.py +242 -0
  137. p5py_vibe-0.1.0/src/p5_py/assets/shader.py +46 -0
  138. p5py_vibe-0.1.0/src/p5_py/assets/sound.py +149 -0
  139. p5py_vibe-0.1.0/src/p5_py/assets/text.py +37 -0
  140. p5py_vibe-0.1.0/src/p5_py/backends/__init__.py +18 -0
  141. p5py_vibe-0.1.0/src/p5_py/backends/base.py +65 -0
  142. p5py_vibe-0.1.0/src/p5_py/backends/headless.py +75 -0
  143. p5py_vibe-0.1.0/src/p5_py/backends/pillow.py +587 -0
  144. p5py_vibe-0.1.0/src/p5_py/backends/pyglet.py +368 -0
  145. p5py_vibe-0.1.0/src/p5_py/backends/pyglet_renderer.py +579 -0
  146. p5py_vibe-0.1.0/src/p5_py/backends/pyglet_webgl_renderer.py +623 -0
  147. p5py_vibe-0.1.0/src/p5_py/backends/registry.py +49 -0
  148. p5py_vibe-0.1.0/src/p5_py/constants.py +176 -0
  149. p5py_vibe-0.1.0/src/p5_py/context.py +1144 -0
  150. p5py_vibe-0.1.0/src/p5_py/core/__init__.py +0 -0
  151. p5py_vibe-0.1.0/src/p5_py/core/color.py +135 -0
  152. p5py_vibe-0.1.0/src/p5_py/core/geometry.py +88 -0
  153. p5py_vibe-0.1.0/src/p5_py/core/math.py +166 -0
  154. p5py_vibe-0.1.0/src/p5_py/core/random.py +75 -0
  155. p5py_vibe-0.1.0/src/p5_py/core/state.py +101 -0
  156. p5py_vibe-0.1.0/src/p5_py/core/transform.py +71 -0
  157. p5py_vibe-0.1.0/src/p5_py/core/vector.py +308 -0
  158. p5py_vibe-0.1.0/src/p5_py/drawing/__init__.py +0 -0
  159. p5py_vibe-0.1.0/src/p5_py/drawing/prototype3d.py +205 -0
  160. p5py_vibe-0.1.0/src/p5_py/drawing/renderer.py +116 -0
  161. p5py_vibe-0.1.0/src/p5_py/drawing/renderer3d.py +186 -0
  162. p5py_vibe-0.1.0/src/p5_py/drawing/software3d.py +646 -0
  163. p5py_vibe-0.1.0/src/p5_py/events/__init__.py +0 -0
  164. p5py_vibe-0.1.0/src/p5_py/events/input_state.py +104 -0
  165. p5py_vibe-0.1.0/src/p5_py/exceptions.py +33 -0
  166. p5py_vibe-0.1.0/src/p5_py/pixels/__init__.py +0 -0
  167. p5py_vibe-0.1.0/src/p5_py/plugins/__init__.py +25 -0
  168. p5py_vibe-0.1.0/src/p5_py/plugins/base.py +108 -0
  169. p5py_vibe-0.1.0/src/p5_py/plugins/registry.py +214 -0
  170. p5py_vibe-0.1.0/src/p5_py/rust/__init__.py +222 -0
  171. p5py_vibe-0.1.0/src/p5_py/rust/_accelerated.pyi +10 -0
  172. p5py_vibe-0.1.0/src/p5_py/rust/benchmarks.py +123 -0
  173. p5py_vibe-0.1.0/src/p5_py/sketch.py +347 -0
  174. p5py_vibe-0.1.0/src/p5_py/testing/__init__.py +0 -0
  175. p5py_vibe-0.1.0/src/p5_py/testing/resources/__init__.py +1 -0
  176. p5py_vibe-0.1.0/src/p5_py/testing/resources/triangle.obj +5 -0
  177. p5py_vibe-0.1.0/tests/contracts/test_backends.py +14 -0
  178. p5py_vibe-0.1.0/tests/golden/test_basic_shapes_golden.py +24 -0
  179. p5py_vibe-0.1.0/tests/integration/test_drawing.py +46 -0
  180. p5py_vibe-0.1.0/tests/integration/test_webgl_3d.py +82 -0
  181. p5py_vibe-0.1.0/tests/parity/test_backend_alias_parity.py +21 -0
  182. p5py_vibe-0.1.0/tests/unit/test_3d_prototype.py +77 -0
  183. p5py_vibe-0.1.0/tests/unit/test_color_transform.py +19 -0
  184. p5py_vibe-0.1.0/tests/unit/test_compatibility.py +49 -0
  185. p5py_vibe-0.1.0/tests/unit/test_global_api.py +36 -0
  186. p5py_vibe-0.1.0/tests/unit/test_image_transform_semantics.py +75 -0
  187. p5py_vibe-0.1.0/tests/unit/test_input_events.py +79 -0
  188. p5py_vibe-0.1.0/tests/unit/test_lifecycle.py +44 -0
  189. p5py_vibe-0.1.0/tests/unit/test_math_vector_random_assets.py +98 -0
  190. p5py_vibe-0.1.0/tests/unit/test_media_capture.py +150 -0
  191. p5py_vibe-0.1.0/tests/unit/test_model_loading.py +42 -0
  192. p5py_vibe-0.1.0/tests/unit/test_pixel_density.py +65 -0
  193. p5py_vibe-0.1.0/tests/unit/test_pixels_export_blend.py +104 -0
  194. p5py_vibe-0.1.0/tests/unit/test_plugins.py +184 -0
  195. p5py_vibe-0.1.0/tests/unit/test_pyglet_backend.py +245 -0
  196. p5py_vibe-0.1.0/tests/unit/test_pyglet_renderer.py +383 -0
  197. p5py_vibe-0.1.0/tests/unit/test_rust_acceleration.py +128 -0
  198. p5py_vibe-0.1.0/tests/unit/test_sound_playback.py +81 -0
  199. p5py_vibe-0.1.0/tests/unit/test_webgl_api.py +268 -0
  200. p5py_vibe-0.1.0/uv.lock +482 -0
@@ -0,0 +1,41 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ jobs:
8
+ quality:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ - uses: astral-sh/setup-uv@v6
13
+ - uses: actions/setup-python@v5
14
+ with:
15
+ python-version-file: .python-version
16
+ - run: uv sync --dev
17
+ - run: uv run ruff check .
18
+ - run: uv run mypy src
19
+ - run: uv run pytest
20
+ - run: uv run python examples/basic_shapes.py --backend headless --frames 1
21
+
22
+ build-python:
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+ - uses: astral-sh/setup-uv@v6
27
+ - uses: actions/setup-python@v5
28
+ with:
29
+ python-version-file: .python-version
30
+ - run: uv build
31
+
32
+ build-rust:
33
+ runs-on: ubuntu-latest
34
+ steps:
35
+ - uses: actions/checkout@v4
36
+ - uses: astral-sh/setup-uv@v6
37
+ - uses: actions/setup-python@v5
38
+ with:
39
+ python-version-file: .python-version
40
+ - uses: dtolnay/rust-toolchain@stable
41
+ - run: uvx maturin build --release
@@ -0,0 +1,105 @@
1
+ name: Publish
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ repository:
7
+ description: Package index to publish to
8
+ required: true
9
+ type: choice
10
+ options:
11
+ - testpypi
12
+ - pypi
13
+ default: testpypi
14
+ push:
15
+ tags:
16
+ - "v*"
17
+
18
+ permissions: {}
19
+
20
+ jobs:
21
+ build:
22
+ name: Build distributions
23
+ runs-on: ubuntu-latest
24
+ permissions:
25
+ contents: read
26
+ steps:
27
+ - uses: actions/checkout@v4
28
+
29
+ - uses: astral-sh/setup-uv@v6
30
+
31
+ - uses: actions/setup-python@v5
32
+ with:
33
+ python-version-file: .python-version
34
+
35
+ - name: Install dev dependencies
36
+ run: uv sync --dev
37
+
38
+ - name: Lint
39
+ run: uv run ruff check .
40
+
41
+ - name: Type check
42
+ run: uv run mypy src
43
+
44
+ - name: Run tests
45
+ run: uv run pytest
46
+
47
+ - name: Smoke test headless example
48
+ run: uv run python examples/basic_shapes.py --backend headless --frames 1
49
+
50
+ - name: Build sdist and wheel
51
+ run: uv build
52
+
53
+ - name: Verify distribution metadata
54
+ run: uv tool run twine check dist/*
55
+
56
+ - name: Upload distributions
57
+ uses: actions/upload-artifact@v4
58
+ with:
59
+ name: python-dist
60
+ path: dist/
61
+
62
+ publish-testpypi:
63
+ name: Publish to TestPyPI
64
+ if: github.event_name == 'workflow_dispatch' && inputs.repository == 'testpypi'
65
+ needs: build
66
+ runs-on: ubuntu-latest
67
+ environment:
68
+ name: testpypi
69
+ url: https://test.pypi.org/p/p5-py
70
+ permissions:
71
+ id-token: write
72
+ steps:
73
+ - name: Download distributions
74
+ uses: actions/download-artifact@v4
75
+ with:
76
+ name: python-dist
77
+ path: dist/
78
+
79
+ - name: Publish package distributions to TestPyPI
80
+ uses: pypa/gh-action-pypi-publish@release/v1
81
+ with:
82
+ repository-url: https://test.pypi.org/legacy/
83
+ packages-dir: dist/
84
+
85
+ publish-pypi:
86
+ name: Publish to PyPI
87
+ if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.repository == 'pypi')
88
+ needs: build
89
+ runs-on: ubuntu-latest
90
+ environment:
91
+ name: pypi
92
+ url: https://pypi.org/p/p5-py
93
+ permissions:
94
+ id-token: write
95
+ steps:
96
+ - name: Download distributions
97
+ uses: actions/download-artifact@v4
98
+ with:
99
+ name: python-dist
100
+ path: dist/
101
+
102
+ - name: Publish package distributions to PyPI
103
+ uses: pypa/gh-action-pypi-publish@release/v1
104
+ with:
105
+ packages-dir: dist/
@@ -0,0 +1,226 @@
1
+ examples/output/
2
+
3
+ # Created by https://www.toptal.com/developers/gitignore/api/python,macos,rust
4
+ # Edit at https://www.toptal.com/developers/gitignore?templates=python,macos,rust
5
+
6
+ ### macOS ###
7
+ # General
8
+ .DS_Store
9
+ .AppleDouble
10
+ .LSOverride
11
+
12
+ # Icon must end with two \r
13
+ Icon
14
+
15
+
16
+ # Thumbnails
17
+ ._*
18
+
19
+ # Files that might appear in the root of a volume
20
+ .DocumentRevisions-V100
21
+ .fseventsd
22
+ .Spotlight-V100
23
+ .TemporaryItems
24
+ .Trashes
25
+ .VolumeIcon.icns
26
+ .com.apple.timemachine.donotpresent
27
+
28
+ # Directories potentially created on remote AFP share
29
+ .AppleDB
30
+ .AppleDesktop
31
+ Network Trash Folder
32
+ Temporary Items
33
+ .apdisk
34
+
35
+ ### macOS Patch ###
36
+ # iCloud generated files
37
+ *.icloud
38
+
39
+ ### Python ###
40
+ # Byte-compiled / optimized / DLL files
41
+ __pycache__/
42
+ *.py[cod]
43
+ *$py.class
44
+
45
+ # C extensions
46
+ *.so
47
+
48
+ # Distribution / packaging
49
+ .Python
50
+ build/
51
+ develop-eggs/
52
+ dist/
53
+ downloads/
54
+ eggs/
55
+ .eggs/
56
+ lib/
57
+ lib64/
58
+ parts/
59
+ sdist/
60
+ var/
61
+ wheels/
62
+ share/python-wheels/
63
+ *.egg-info/
64
+ .installed.cfg
65
+ *.egg
66
+ MANIFEST
67
+
68
+ # PyInstaller
69
+ # Usually these files are written by a python script from a template
70
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
71
+ *.manifest
72
+ *.spec
73
+
74
+ # Installer logs
75
+ pip-log.txt
76
+ pip-delete-this-directory.txt
77
+
78
+ # Unit test / coverage reports
79
+ htmlcov/
80
+ .tox/
81
+ .nox/
82
+ .coverage
83
+ .coverage.*
84
+ .cache
85
+ nosetests.xml
86
+ coverage.xml
87
+ *.cover
88
+ *.py,cover
89
+ .hypothesis/
90
+ .pytest_cache/
91
+ cover/
92
+
93
+ # Translations
94
+ *.mo
95
+ *.pot
96
+
97
+ # Django stuff:
98
+ *.log
99
+ local_settings.py
100
+ db.sqlite3
101
+ db.sqlite3-journal
102
+
103
+ # Flask stuff:
104
+ instance/
105
+ .webassets-cache
106
+
107
+ # Scrapy stuff:
108
+ .scrapy
109
+
110
+ # Sphinx documentation
111
+ docs/_build/
112
+
113
+ # PyBuilder
114
+ .pybuilder/
115
+ target/
116
+
117
+ # Jupyter Notebook
118
+ .ipynb_checkpoints
119
+
120
+ # IPython
121
+ profile_default/
122
+ ipython_config.py
123
+
124
+ # pyenv
125
+ # For a library or package, you might want to ignore these files since the code is
126
+ # intended to run in multiple environments; otherwise, check them in:
127
+ # .python-version
128
+
129
+ # pipenv
130
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
131
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
132
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
133
+ # install all needed dependencies.
134
+ #Pipfile.lock
135
+
136
+ # poetry
137
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
138
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
139
+ # commonly ignored for libraries.
140
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
141
+ #poetry.lock
142
+
143
+ # pdm
144
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
145
+ #pdm.lock
146
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
147
+ # in version control.
148
+ # https://pdm.fming.dev/#use-with-ide
149
+ .pdm.toml
150
+
151
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
152
+ __pypackages__/
153
+
154
+ # Celery stuff
155
+ celerybeat-schedule
156
+ celerybeat.pid
157
+
158
+ # SageMath parsed files
159
+ *.sage.py
160
+
161
+ # Environments
162
+ .env
163
+ .venv
164
+ env/
165
+ venv/
166
+ ENV/
167
+ env.bak/
168
+ venv.bak/
169
+
170
+ # Spyder project settings
171
+ .spyderproject
172
+ .spyproject
173
+
174
+ # Rope project settings
175
+ .ropeproject
176
+
177
+ # mkdocs documentation
178
+ /site
179
+
180
+ # mypy
181
+ .mypy_cache/
182
+ .dmypy.json
183
+ dmypy.json
184
+
185
+ # Pyre type checker
186
+ .pyre/
187
+
188
+ # pytype static type analyzer
189
+ .pytype/
190
+
191
+ # Cython debug symbols
192
+ cython_debug/
193
+
194
+ # PyCharm
195
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
196
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
197
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
198
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
199
+ #.idea/
200
+
201
+ ### Python Patch ###
202
+ # Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
203
+ poetry.toml
204
+
205
+ # ruff
206
+ .ruff_cache/
207
+
208
+ # LSP config files
209
+ pyrightconfig.json
210
+
211
+ ### Rust ###
212
+ # Generated by Cargo
213
+ # will have compiled files and executables
214
+ debug/
215
+
216
+ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
217
+ # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
218
+ Cargo.lock
219
+
220
+ # These are backup files generated by rustfmt
221
+ **/*.rs.bk
222
+
223
+ # MSVC Windows builds of rustc generate these, which store debugging information
224
+ *.pdb
225
+
226
+ # End of https://www.toptal.com/developers/gitignore/api/python,macos,rust
@@ -0,0 +1 @@
1
+ 3.12
@@ -0,0 +1,349 @@
1
+ # AGENTS.md
2
+
3
+ Guidance for AI coding agents working in this repository.
4
+
5
+ ## Project overview
6
+
7
+ This repository contains `p5-py`, a Pythonic creative-coding package inspired by p5.js.
8
+
9
+ The goal is to provide a familiar p5-style sketching model for Python while keeping the implementation idiomatic, maintainable, typed, testable, and backend-agnostic.
10
+
11
+ The package must remain native Python. Do not add JavaScript or HTML code.
12
+
13
+ ## Package workflow
14
+
15
+ This project uses `uv`.
16
+
17
+ Use `uv` for dependency and command execution:
18
+
19
+ ```sh
20
+ uv sync --dev
21
+ uv run pytest
22
+ uv run ruff check .
23
+ uv run ruff format .
24
+ uv run python examples/basic_shapes.py --backend headless --frames 1
25
+ ```
26
+
27
+ Do not use raw `pip install` or unmanaged virtual environments unless explicitly requested.
28
+
29
+ The active Python version is defined by `.python-version` and `pyproject.toml`.
30
+
31
+ ## Source layout
32
+
33
+ Primary package code lives under:
34
+
35
+ ```text
36
+ src/p5_py/
37
+ ```
38
+
39
+ Important areas:
40
+
41
+ ```text
42
+ src/p5_py/api/ global-mode API, p5.js aliases, compatibility stubs
43
+ src/p5_py/backends/ backend implementations and backend registry
44
+ src/p5_py/core/ color, geometry, state, transforms, math-like core systems
45
+ src/p5_py/drawing/ renderer protocol and drawing abstractions
46
+ src/p5_py/events/ normalized input/event state
47
+ src/p5_py/pixels/ future pixel-buffer functionality
48
+ src/p5_py/plugins/ future plugin architecture
49
+ src/p5_py/rust/ future Rust acceleration integration
50
+ src/p5_py/testing/ future testing helpers
51
+ ```
52
+
53
+ Tests live under:
54
+
55
+ ```text
56
+ tests/
57
+ ```
58
+
59
+ Examples live under:
60
+
61
+ ```text
62
+ examples/
63
+ ```
64
+
65
+ Docs live under:
66
+
67
+ ```text
68
+ docs/
69
+ ```
70
+
71
+ Backlog items live under:
72
+
73
+ ```text
74
+ backlog/<three_digit_epic_name>/<pbi_name>.toml
75
+ ```
76
+
77
+ ## Architecture principles
78
+
79
+ ### Keep public API backend-agnostic
80
+
81
+ The public p5-py API must not directly depend on Pillow, Pyglet, or any future renderer.
82
+
83
+ The intended layering is:
84
+
85
+ ```text
86
+ user sketch
87
+
88
+ p5_py public API
89
+
90
+ Sketch / SketchContext
91
+
92
+ Renderer + Backend protocols
93
+
94
+ Concrete backend / renderer
95
+ ```
96
+
97
+ ### Separate backend responsibilities from renderer responsibilities
98
+
99
+ Backends own platform/window/runtime concerns.
100
+
101
+ Renderers own drawing.
102
+
103
+ For example:
104
+
105
+ - `PygletBackend` should own window creation, the event loop, input normalization, frame scheduling, and shutdown.
106
+ - A future `PygletRenderer` should own native Pyglet drawing.
107
+ - `PillowRenderer` should remain the deterministic headless/export renderer.
108
+
109
+ Do not push sketch lifecycle, p5.js aliasing, or argument parsing into backend-specific code.
110
+
111
+ ### Preserve custom backend support
112
+
113
+ Future custom backends should be able to integrate by implementing the backend and renderer protocols and registering themselves through the backend registry.
114
+
115
+ Avoid hardcoding backend classes outside `p5_py.backends.registry` and backend selection logic.
116
+
117
+ ### Keep p5 compatibility and Pythonic API together
118
+
119
+ Canonical Python APIs should use `snake_case`, for example:
120
+
121
+ ```python
122
+ create_canvas()
123
+ frame_rate()
124
+ no_loop()
125
+ pixel_density()
126
+ ```
127
+
128
+ p5.js-style aliases may be provided where useful:
129
+
130
+ ```python
131
+ createCanvas()
132
+ frameRate()
133
+ noLoop()
134
+ pixelDensity()
135
+ ```
136
+
137
+ Aliases must delegate to the same implementation. Do not duplicate behavior.
138
+
139
+ ### Keep exports type-checker friendly
140
+
141
+ `src/p5_py/__init__.py` should use explicit imports for public APIs. Avoid dynamic wildcard export machinery that makes Zed/Pyright unable to see package attributes.
142
+
143
+ ## Rendering guidance
144
+
145
+ ### Current rendering state
146
+
147
+ The current Pyglet backend is a bridge backend:
148
+
149
+ ```text
150
+ PillowRenderer renders the frame
151
+ PygletBackend presents that image in a native Pyglet window
152
+ ```
153
+
154
+ This is intentional for now. See:
155
+
156
+ ```text
157
+ docs/technical/native_pyglet_renderer.md
158
+ ```
159
+
160
+ The planned next rendering milestone is a native `PygletRenderer`.
161
+
162
+ ### HiDPI and pixel density
163
+
164
+ p5-py distinguishes logical canvas dimensions from physical backing-buffer dimensions.
165
+
166
+ - `width()` and `height()` are logical p5 dimensions.
167
+ - `pixel_density()` controls physical backing scale.
168
+ - `display_density()` reports native display scale when the backend supports it.
169
+ - `load_pixels()` and `update_pixels()` currently operate on physical RGBA buffers.
170
+
171
+ See:
172
+
173
+ ```text
174
+ docs/technical/hidpi_rendering.md
175
+ ```
176
+
177
+ Do not regress Retina/HiDPI behavior when changing renderers or backends.
178
+
179
+ ## Exclusions
180
+
181
+ Do not add:
182
+
183
+ - JavaScript code
184
+ - HTML code
185
+ - DOM APIs
186
+ - browser-only APIs
187
+ - `p5.XML`
188
+ - `p5.Table`
189
+ - `p5.TableRow`
190
+
191
+ Excluded APIs should raise clear package-specific errors when exposed as compatibility stubs.
192
+
193
+ ## Backlog conventions
194
+
195
+ Backlog epics use a three-digit prefix to allow insertion between epics, for example:
196
+
197
+ ```text
198
+ 010_foundation_runtime
199
+ 020_api_compatibility
200
+ 030_rendering_2d
201
+ 031_native_pyglet_renderer
202
+ 040_color_style_transform
203
+ ```
204
+
205
+ Each PBI file must use this TOML layout:
206
+
207
+ ```toml
208
+ [my_pbi]
209
+ title = "..."
210
+ description = '''
211
+ As a ...,
212
+ I want ...,
213
+ So that ...
214
+ '''
215
+ acceptance_criteria = '''
216
+ ...
217
+ '''
218
+ priotity = 'high|medium|low'
219
+ status = 'TODO|IN_PROGRESS|DONE'
220
+
221
+ [my_pbi.task_1]
222
+ order = 1
223
+ status = 'TODO|IN_PROGRESS|DONE'
224
+ description = '''
225
+ ...
226
+ '''
227
+ ```
228
+
229
+ Note: the existing schema intentionally uses the misspelled key `priotity`. Preserve it unless the user explicitly requests a schema migration.
230
+
231
+ When completing work that corresponds to backlog items, update both PBI and task statuses.
232
+
233
+ Allowed status values are:
234
+
235
+ ```text
236
+ TODO
237
+ IN_PROGRESS
238
+ DONE
239
+ ```
240
+
241
+ Validate backlog TOML after edits:
242
+
243
+ ```sh
244
+ python - <<'PY'
245
+ from pathlib import Path
246
+ import tomllib
247
+ for path in sorted(Path('backlog').glob('**/*.toml')):
248
+ with path.open('rb') as f:
249
+ tomllib.load(f)
250
+ print('Backlog TOML parsed successfully')
251
+ PY
252
+ ```
253
+
254
+ ## Testing and validation
255
+
256
+ Before finishing code changes, run:
257
+
258
+ ```sh
259
+ uv run ruff check .
260
+ uv run pytest
261
+ ```
262
+
263
+ If formatting changes are needed, run:
264
+
265
+ ```sh
266
+ uv run ruff format .
267
+ ```
268
+
269
+ Also check Zed diagnostics when practical.
270
+
271
+ For rendering changes, run at least one headless example smoke test, such as:
272
+
273
+ ```sh
274
+ uv run python examples/basic_shapes.py --backend headless --frames 1
275
+ ```
276
+
277
+ If examples generate output files, do not accidentally commit generated artifacts unless the user explicitly wants them tracked.
278
+
279
+ ## Test expectations
280
+
281
+ Add or update tests when changing behavior.
282
+
283
+ Current useful test areas:
284
+
285
+ ```text
286
+ tests/contracts/ backend and renderer contract behavior
287
+ tests/integration/ end-to-end sketch rendering behavior
288
+ tests/unit/ API, lifecycle, color, transforms, density, backend details
289
+ ```
290
+
291
+ Prefer deterministic headless tests for renderer behavior where possible.
292
+
293
+ For interactive Pyglet behavior, use focused unit tests with fake window/module objects when possible, and document any manual smoke tests.
294
+
295
+ ## Documentation expectations
296
+
297
+ Update docs when changing architecture, public APIs, rendering behavior, backend behavior, or compatibility status.
298
+
299
+ Relevant docs include:
300
+
301
+ ```text
302
+ docs/technical/project_plan.md
303
+ docs/technical/hidpi_rendering.md
304
+ docs/technical/native_pyglet_renderer.md
305
+ ```
306
+
307
+ ## Rust guidance
308
+
309
+ Rust acceleration is planned but should remain optional and contained.
310
+
311
+ Future Rust code should live under:
312
+
313
+ ```text
314
+ crates/
315
+ ```
316
+
317
+ Rust should be used only for pure computational hot paths such as:
318
+
319
+ - noise generation
320
+ - pixel filters
321
+ - blend modes
322
+ - color conversion
323
+ - geometry tessellation
324
+ - path flattening
325
+
326
+ Every Rust-accelerated feature must have a Python fallback unless the user explicitly changes this requirement.
327
+
328
+ ## Dependency guidance
329
+
330
+ Prefer existing dependencies already in `pyproject.toml`.
331
+
332
+ Current core dependencies include:
333
+
334
+ - Pillow
335
+ - Pyglet
336
+
337
+ Current dev dependencies include:
338
+
339
+ - pytest
340
+ - ruff
341
+
342
+ Add new dependencies only when justified by the task, and use `uv add` or `uv add --dev` so `pyproject.toml` and `uv.lock` stay in sync.
343
+
344
+ ## Safety notes
345
+
346
+ - Do not modify the sibling `p5.js` repository unless the user explicitly asks.
347
+ - Do not commit changes unless the user explicitly asks.
348
+ - Do not remove or overwrite generated/user files unless you are sure they are artifacts from your own validation commands.
349
+ - Keep changes focused on the requested task.