python-attrs / python-attrs/attrs

Add `on_change` similar to `on_setattr`, but called after updating the instance.

Open
#1,437 8 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
5.8k
Forks
480
Avg merge
2h 15m
Merged PRs (30d)
2

Description

I have been trying to implement a reactive change notification system on top of attrs using on_setattr handlers. However, on_setattr handlers are called before the value is assigned, in order to allow them to perform data conversion. For a reactive change notification, this is subobtimal: you want the changes to be notified after value assignment, so that handlers can inspect the new state on the object. This is especially important when change handlers chain, e.g. when a change handler on an attribute a potentially triggers a change in b, and a change handler on b may want to inspect a, which would otherwise be inconsistent.

Implementing that using the existing mechanisms in attrs proved quite difficult; you'd need a custom __setattr__. However, that immediately prevents any on_setattr behaviour (such as frozen attributes), which requires an attrs-built __setattr__. Thus, one would have to collect all on_setattr specifications on all fields and replace them with custom metadata, which can then be collected into the handling of the custom __setattr__. Obviously, that is suboptimal.

I therefore propose to add another handler on_change, which behaves similar to on_setattr, but is invoked after the value is assigned to the instance. Preferably, in addition to the values provided to on_setattr handlers, we would also supply the previous value (without making any guarantees for concurrent multi-threaded access).

If there is interest in this, I'm happy to whip up a PR.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the existing on_setattr implementation and its handling of assignment, conversion, and frozen attributes. Define how an on_change handler receives the previous and new values, including chained changes, then validate the API and behavior against the existing attrs mechanisms before implementing it.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
developer-experience
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.