nodebpy 520.20.0__tar.gz → 520.21.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 (86) hide show
  1. {nodebpy-520.20.0 → nodebpy-520.21.0}/PKG-INFO +1 -1
  2. {nodebpy-520.20.0 → nodebpy-520.21.0}/pyproject.toml +1 -1
  3. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/assets/__init__.py +6 -2
  4. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/assets/__main__.py +49 -14
  5. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/assets/_library.py +287 -110
  6. nodebpy-520.21.0/src/nodebpy/assets/_pipeline.py +501 -0
  7. {nodebpy-520.20.0 → nodebpy-520.21.0}/README.md +0 -0
  8. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/__init__.py +0 -0
  9. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/assets/_codegen.py +0 -0
  10. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/builder/__init__.py +0 -0
  11. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/builder/_registry.py +0 -0
  12. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/builder/_utils.py +0 -0
  13. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/builder/accessor.py +0 -0
  14. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/builder/asset.py +0 -0
  15. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/builder/items.py +0 -0
  16. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/builder/layout.py +0 -0
  17. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/builder/mixins.py +0 -0
  18. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/builder/node.py +0 -0
  19. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/builder/socket.py +0 -0
  20. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/builder/tree.py +0 -0
  21. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/export/__init__.py +0 -0
  22. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/export/codegen.py +0 -0
  23. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/export/diagram.py +0 -0
  24. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/export/parity.py +0 -0
  25. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/export/plot.py +0 -0
  26. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/export/web_render.py +0 -0
  27. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/lib/nodearrange/VENDORED.md +0 -0
  28. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/lib/nodearrange/__init__.py +0 -0
  29. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/lib/nodearrange/arrange/__init__.py +0 -0
  30. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/lib/nodearrange/arrange/graph.py +0 -0
  31. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/lib/nodearrange/arrange/ordering.py +0 -0
  32. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/lib/nodearrange/arrange/ranking.py +0 -0
  33. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/lib/nodearrange/arrange/realize.py +0 -0
  34. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/lib/nodearrange/arrange/stacking.py +0 -0
  35. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/lib/nodearrange/arrange/structs.py +0 -0
  36. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/lib/nodearrange/arrange/sugiyama.py +0 -0
  37. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/lib/nodearrange/arrange/x_coords.py +0 -0
  38. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/lib/nodearrange/arrange/y_coords.py +0 -0
  39. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/lib/nodearrange/config.py +0 -0
  40. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/lib/nodearrange/utils.py +0 -0
  41. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/__init__.py +0 -0
  42. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/_mixins.py +0 -0
  43. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/compositor/__init__.py +0 -0
  44. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/compositor/assets.py +0 -0
  45. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/compositor/color.py +0 -0
  46. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/compositor/converter.py +0 -0
  47. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/compositor/distort.py +0 -0
  48. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/compositor/filter.py +0 -0
  49. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/compositor/group.py +0 -0
  50. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/compositor/input.py +0 -0
  51. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/compositor/interface.py +0 -0
  52. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/compositor/manual.py +0 -0
  53. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/compositor/matte.py +0 -0
  54. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/compositor/output.py +0 -0
  55. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/compositor/vector.py +0 -0
  56. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/geometry/__init__.py +0 -0
  57. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/geometry/assets.py +0 -0
  58. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/geometry/attribute.py +0 -0
  59. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/geometry/color.py +0 -0
  60. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/geometry/converter.py +0 -0
  61. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/geometry/geometry.py +0 -0
  62. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/geometry/grid.py +0 -0
  63. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/geometry/group.py +0 -0
  64. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/geometry/groups.py +0 -0
  65. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/geometry/input.py +0 -0
  66. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/geometry/interface.py +0 -0
  67. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/geometry/manual.py +0 -0
  68. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/geometry/output.py +0 -0
  69. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/geometry/texture.py +0 -0
  70. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/geometry/utilities.py +0 -0
  71. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/geometry/vector.py +0 -0
  72. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/geometry/zone.py +0 -0
  73. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/shader/__init__.py +0 -0
  74. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/shader/assets.py +0 -0
  75. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/shader/color.py +0 -0
  76. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/shader/converter.py +0 -0
  77. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/shader/grid.py +0 -0
  78. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/shader/group.py +0 -0
  79. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/shader/input.py +0 -0
  80. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/shader/manual.py +0 -0
  81. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/shader/output.py +0 -0
  82. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/shader/script.py +0 -0
  83. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/shader/shader.py +0 -0
  84. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/shader/texture.py +0 -0
  85. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/nodes/shader/vector.py +0 -0
  86. {nodebpy-520.20.0 → nodebpy-520.21.0}/src/nodebpy/types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: nodebpy
3
- Version: 520.20.0
3
+ Version: 520.21.0
4
4
  Summary: Build nodes trees in Blender more elegantly with code
5
5
  Author: Brady Johnston
6
6
  Author-email: Brady Johnston <brady.johnston@me.com>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "nodebpy"
3
- version = "520.20.0"
3
+ version = "520.21.0"
4
4
  description = "Build nodes trees in Blender more elegantly with code"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -10,8 +10,12 @@ compositor}.assets`` and are re-exported alongside the built-in nodes.
10
10
  ``dump_library`` and ``build_library`` round-trip a ``.blend`` asset library
11
11
  through Python source: every asset is dumped to its own ``.py`` file (the
12
12
  version-controlled source of truth) and the ``.blend`` is rebuilt from them
13
- (``python -m nodebpy.assets dump/build``). ``plot_library`` renders node
14
- groups from a ``.blend`` to PNG images by name or wildcard
13
+ (``python -m nodebpy.assets dump/build``). The CLI adds ``ensure`` (rebuild
14
+ only when the ``.blend`` or its fingerprint stamp is stale) and ``check``
15
+ (verify that build → dump reproduces the sources byte-for-byte), and reads
16
+ its arguments from a ``[tool.nodebpy.assets]`` pyproject table — see
17
+ :mod:`nodebpy.assets._pipeline`. ``plot_library`` renders node groups from a
18
+ ``.blend`` to PNG images by name or wildcard
15
19
  (``python -m nodebpy.assets plot``), for review outside Blender.
16
20
  """
17
21
 
@@ -7,8 +7,17 @@ available alongside the built-in nodes (e.g. ``g.SmoothByAngle()``). Run *before
7
7
  ``python -m gen`` and through the ruff/ty post-processing (see the Makefile).
8
8
 
9
9
  ``python -m nodebpy.assets dump <blend> <dir>`` and ``… build <dir> <blend>``
10
- instead round-trip a ``.blend`` asset library through per-asset Python sources
11
- (see :mod:`nodebpy.assets._library`).
10
+ instead round-trip a ``.blend`` asset library through per-asset Python sources;
11
+ ``… ensure`` rebuilds only when the ``.blend`` is missing or stale, and
12
+ ``… check`` verifies that build → dump reproduces the sources byte-for-byte
13
+ (see :mod:`nodebpy.assets._library` and :mod:`nodebpy.assets._pipeline` — the
14
+ latter also documents the ``[tool.nodebpy.assets]`` pyproject table these
15
+ subcommands read their arguments from).
16
+
17
+ Under a full Blender (no ``bpy`` module) any invocation runs this file as a
18
+ script, with the arguments after Blender's ``--`` separator::
19
+
20
+ blender -b --factory-startup -P <.../nodebpy/assets/__main__.py> -- ensure
12
21
  """
13
22
 
14
23
  from __future__ import annotations
@@ -18,8 +27,14 @@ import os
18
27
  import sys
19
28
  from pathlib import Path
20
29
 
21
- from ..builder import BundledLibrary, PackageLibrary
22
- from ._codegen import generate_asset_api, generate_asset_modules
30
+ # ``blender ... -P .../nodebpy/assets/__main__.py`` runs this file as a plain
31
+ # script (no package context): put the package root on sys.path so the
32
+ # absolute imports resolve — a no-op under ``python -m nodebpy.assets``.
33
+ if not __package__:
34
+ sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
35
+
36
+ from nodebpy.assets._codegen import generate_asset_api, generate_asset_modules
37
+ from nodebpy.builder import BundledLibrary, PackageLibrary
23
38
 
24
39
  # Bundled libraries shipped with Blender, grouped by output module. Each library
25
40
  # holds node groups of a single tree type.
@@ -62,7 +77,9 @@ def generate_essentials(
62
77
  return written
63
78
 
64
79
 
65
- def parse_args() -> argparse.Namespace: # pragma: no cover - CLI wrapper
80
+ def parse_args(
81
+ argv: list[str] | None = None,
82
+ ) -> argparse.Namespace: # pragma: no cover - CLI wrapper
66
83
  parser = argparse.ArgumentParser(
67
84
  prog="python -m nodebpy.assets",
68
85
  description=(
@@ -77,10 +94,21 @@ def parse_args() -> argparse.Namespace: # pragma: no cover - CLI wrapper
77
94
  ".blend to per-asset .py source files\n"
78
95
  " build <source-dir> <blend> rebuild the .blend asset library "
79
96
  "from dumped .py source files\n"
97
+ " ensure <source-dir> <blend> rebuild only when the .blend or "
98
+ "its fingerprint stamp is missing or stale\n"
99
+ " check <source-dir> <blend> verify that build -> dump "
100
+ "reproduces the sources byte-for-byte\n"
80
101
  " plot <blend> <output-dir> [names ...]\n"
81
102
  " render node groups (wildcards "
82
103
  "supported) to PNG images\n"
83
104
  "\n"
105
+ "These subcommands can read their positionals and flags from a "
106
+ "[tool.nodebpy.assets] table\n"
107
+ "in the nearest pyproject.toml. Inside a full Blender (no bpy "
108
+ "module), run any of them as\n"
109
+ " blender -b --factory-startup -P <.../nodebpy/assets/"
110
+ "__main__.py> -- <subcommand ...>\n"
111
+ "\n"
84
112
  "See 'python -m nodebpy.assets dump --help', '… build --help' "
85
113
  "and '… plot --help' for their options."
86
114
  ),
@@ -123,20 +151,27 @@ def parse_args() -> argparse.Namespace: # pragma: no cover - CLI wrapper
123
151
  "Inputs, Outputs) and emit a terser module."
124
152
  ),
125
153
  )
126
- return parser.parse_args()
154
+ return parser.parse_args(argv)
127
155
 
128
156
 
129
157
  def main() -> None: # pragma: no cover - CLI wrapper
130
- # The dump/build/plot subcommands (blend ↔ .py round-trip, PNG renders)
131
- # have their own parser; everything else keeps the original flag-based
132
- # interface.
133
- if len(sys.argv) > 1 and sys.argv[1] in ("dump", "build", "plot"):
134
- from ._library import main as library_main
135
-
136
- library_main(sys.argv[1:])
158
+ # Blender passes script arguments after a ``--`` separator (``blender -b
159
+ # --factory-startup -P .../__main__.py -- build``): strip everything up
160
+ # to and including it, so the same subcommands work there too.
161
+ argv = sys.argv[1:]
162
+ if "--" in sys.argv:
163
+ argv = sys.argv[sys.argv.index("--") + 1 :]
164
+
165
+ # The dump/build/ensure/check/plot subcommands (blend ↔ .py round-trip,
166
+ # staleness stamping, roundtrip verification, PNG renders) have their own
167
+ # parser; everything else keeps the original flag-based interface.
168
+ if argv and argv[0] in ("dump", "build", "ensure", "check", "plot"):
169
+ from nodebpy.assets._library import main as library_main
170
+
171
+ library_main(argv)
137
172
  return
138
173
 
139
- args = parse_args()
174
+ args = parse_args(argv)
140
175
  output = (
141
176
  args.output
142
177
  if args.output