Skip to content

Deprecate nodes, robust object tracking and attribute validation - #74

Merged
BradyAJohnston merged 16 commits into
mainfrom
deprecate-nodes
Sep 27, 2026
Merged

BradyAJohnston merged 16 commits into
mainfrom
deprecate-nodes

Conversation

@BradyAJohnston

Copy link
Copy Markdown
Owner

Robustness pass ahead of wider use in other projects. See docs/changelog.qmd (0.9.0) for the full list.

  • Deprecate databpy.nodes (moving to nodebpy) and register()/unregister() with FutureWarning, removal in 0.11.0. unregister() is now a no-op so it can't break other add-ons.
  • Track objects by session_uid within a session and a persistent obj["_databpy_uuid"] across file loads. Legacy Object.uuid values are migrated.
  • AttributeArray syncs all in-place modifications and no longer holds direct references.
  • Validate attribute writes: no silent integer wrapping or lossy casts, clear errors for uninferable data, empty geometry supported.
  • Add DatabpyError and AttributeNotFoundError (also a KeyError).
  • Fix object creation edge cases (mixed face sizes, point clouds, curves, centroid masks).
  • Code passes ruff and ty.

Node functionality is moving to nodebpy. Public functions and classes in
databpy.nodes now emit a FutureWarning and will be removed in 0.11.0.
BlenderObject resolves its object by session_uid within a session and by a
persistent uuid (obj["_databpy_uuid"]) after a file load. Removed objects
now raise LinkedObjectError instead of resolving to a duplicate.

register() and unregister() are deprecated; unregister() is a no-op so it
can't break other add-ons. Legacy Object.uuid values are migrated and kept
in sync until 0.11.0.

Fix create_bob(uuid=...) raising LinkedObjectError.
- Store 1D unsigned ints as INT and unsigned 2D as INT32_2D instead of
  wrapping in INT8 / INT16_2D.
- Raise AttributeMismatchError for integer overflow, NaN/inf into ints and
  complex data instead of casting silently.
- Raise a clear ValueError when no attribute type can be inferred.
- Accept array-like data.
- Writing to an existing attribute uses its type and domain when atype or
  domain is omitted; an explicit domain mismatch raises.
- Replace the vertex reassignment workaround with update_tag(), fixing
  writes to empty geometry.
AttributeArray syncs through __array_ufunc__ and __array_function__, so
every in-place operator, out= and ufunc.at write reaches Blender, along
with fill, sort, put, partition, np.copyto, np.place, np.putmask and
np.fill_diagonal. Augmented assignment on a view syncs once instead of
twice.

The object is tracked by session_uid rather than a direct reference, and
syncing raises LinkedObjectError if it was removed or a file was loaded.
- Support faces with mixed sizes and raise on out-of-range edge/face
  indices in create_mesh_object and new_from_pydata.
- Create point clouds with PointCloud.resize() instead of converting a
  mesh, which failed in unlinked collections and left an orphan mesh.
- create_curves_object raises if only one of positions and curve_sizes
  is given.
- centroid() accepts boolean masks and unsigned indices, and raises on
  unsupported dtypes.
- All databpy errors subclass DatabpyError.
- Missing attributes raise AttributeNotFoundError, a NamedAttributeError
  that is also a KeyError, including bob["name"] which previously raised
  a bare KeyError.
- NamedAttributeError still subclasses AttributeError until 0.11.0.
- Removing a required attribute raises NamedAttributeError instead of
  Blender's RuntimeError.
- The string attribute warning points at the caller, so it shows once per
  call site.
- ObjectTracker detects new objects by session_uid, so renamed objects
  aren't reported as new, and latest() returns the newest object.
- Add py.typed.
- Remove the databpy.nodes.utils import that the utils export shadowed.
- Remove duplicate polars dev dependency.
- Apply ruff fixes and formatting.
- Keep ValueError/AttributeError for invalid types (TRY004) for backwards
  compatibility.
- Configure ruff: ignore SIM118 (bpy collections iterate over items),
  allow B018/BLE001 in tests and exclude the generated README.md.
- Format README.qmd code and silence a polars deprecation warning in the
  rendered README.
- Widen annotations to match accepted input: array-likes for attribute
  data, object constructors and lerp; any sequence for
  move_to_collection; the base bpy.types.Attribute for Attribute().
- AttributeArray raises TypeError for objects without attributes.
- Fix lerp with list inputs and tests/run.py when pytest returns an int.
- Configure ty: exclude the deprecated databpy.nodes, and ignore rules in
  tests that come from optional and union types in the bpy stubs.
Resolves conflicts with the ruff/ty pass in #73: adopt its TypeError for
invalid types, zero-suppression typing and narrowing helpers, deprecate
its new node helpers, and merge the 0.9.0 changelog sections.
@codecov

codecov Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.79874% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.35%. Comparing base (3bed26e) to head (f557673).

Files with missing lines Patch % Lines
src/databpy/addon.py 92.30% 4 Missing ⚠️
src/databpy/array.py 96.70% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #74      +/-   ##
==========================================
+ Coverage   93.99%   95.35%   +1.36%     
==========================================
  Files          14       16       +2     
  Lines         999     1141     +142     
==========================================
+ Hits          939     1088     +149     
+ Misses         60       53       -7     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Within a session, BlenderObject now also checks the object's uuid after
finding it by session_uid, raising LinkedObjectError when another wrapper
has stored its own uuid on the object. This restores the previous
behaviour MolecularNodes relies on when reloading an entity.
0.9.0 has been released, so these changes go in a new 0.10.0 changelog
section and deprecations are removed in 0.12.0 to keep a two minor release
window.
bpy 5.2 only has cp313 wheels, so allowing Python 3.14 breaks installs on
environments that pick the newest Python, such as CI.

Point BLENDER_USER_EXTENSIONS at a temporary directory in the tests, so
packages from extensions installed in the user's Blender (including other
copies of databpy) don't shadow this project.
@BradyAJohnston
BradyAJohnston merged commit 5a7c8e7 into main Sep 27, 2026
18 checks passed
@BradyAJohnston
BradyAJohnston deleted the deprecate-nodes branch September 27, 2026 16:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant