-
Notifications
You must be signed in to change notification settings - Fork 645
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
added cursor api #3246
added cursor api #3246
Conversation
a15ae0b
to
a0f910d
Compare
19027fa
to
5acc1cb
Compare
Nice API, would you take a look at https://github.com/ASEM000/PyTreeClass, I attempted a slightly different API with the same objective as this API. Specifically https://pytreeclass.readthedocs.io/en/latest/notebooks/common_recipes.html#[7]-Use-PyTreeClass-with-Flax/Equinox |
93ce3e1
to
bd0762d
Compare
3f33ba1
to
f79473a
Compare
Codecov Report
@@ Coverage Diff @@
## main #3246 +/- ##
==========================================
+ Coverage 82.35% 82.51% +0.16%
==========================================
Files 54 55 +1
Lines 6087 6183 +96
==========================================
+ Hits 5013 5102 +89
- Misses 1074 1081 +7
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just a few questions
e9a7493
to
cbd7efc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like a good start, we might iterate on a few details/extensions soon.
Continuing from #3236.
Added the Cursor API, which allows for mutability of pytrees. This API provides a more ergonomic solution to making partial-updates of deeply nested immutable data structures, compared to making many nested
dataclasses.replace
calls.To illustrate, consider the example below:
To replace the int 0 using
dataclasses.replace
, we would have to write many nested calls:The equivalent can be achieved much more simply using the Cursor API:
The Cursor object keeps tracks of changes made to it and when
.build
is called, generates a new object with the accumulated changes. Basic usage involves wrapping the object in a Cursor, making changes to the Cursor object and generating a new copy of the original object with the accumulated changes.There are three ways to use the Cursor API:
.build
method.set
method.apply_update
methodOnce you wrap the object in a Cursor and make changes to it, calling the
.build
method will generate a new object with the accumulated changes. For example:Calling the
.set
method will apply a single-line change and call.build
immediately after. Therefore, you don't need to manually call.build
after.set
. For example:Calling
.apply_update
will traverse the Cursor object and apply conditional changes recursively via a filter function.The filter function has a function signature of
(str, Any) -> Any
:update_fn
or same as the input value if the condition wasn’t fulfilled)To generate a copy of the original object with the accumulated changes, call the
.build
method. For example: