Skip to content
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

Attribute changed notification hooks #622

Closed
danieljfarrell opened this issue Jan 31, 2020 · 9 comments
Closed

Attribute changed notification hooks #622

danieljfarrell opened this issue Jan 31, 2020 · 9 comments
Labels

Comments

@danieljfarrell
Copy link

I'm interested in extending attrs to provide change notifications. Or at least making my classes generated with attrs emit notifications when an attribute changes.

How would you go about doing this?

I'm wondering if attrs could generate an 'x'_did_change method/notification hook when synthesizing the attributes. This is similar to traitlets trait change notifications/observations although that's more dynamic as observers can be added and removed at runtime.

import attr
import typing

@attr.s(auto_attribs=True)
class SomeClass:
    a_number: int = 42
    list_of_numbers: typing.List[int] = attr.Factory(list)

    def _a_number_did_change(self, info):
        old = info['old']
        new = info['new']

    def _list_of_numbers_did_change(self, info):
        added = info['added']
        removed = info['removed']
@hynek
Copy link
Member

hynek commented Feb 1, 2020

What you're asking for is attrs to start writing a __setattr__ for you too. This could happen and allow us to add setter-validation too by adding our own hooks (which people have been asking for forever). 🤔

You should be able to implement it yourself for now: put the hooks into the attribute's meta field and write a __setattr__ that runs them.

@hynek hynek added the Feature label Feb 1, 2020
@altendky
Copy link
Contributor

If I remember correctly it's a pile (of bad stuff) and maybe I shouldn't share it here... but I wrote up an implementation of this idea for use in my PyQt applications. It definitely needs to be rewritten. It went the route of generating @properties that implement on-change pyqtSignal emission as well as conversion/validation. The classes processed by this are used to back Qt models in my GUIs.

code: https://github.com/altendky/stlib/blob/fc519e561adddb930c1dc7cdc6a74bd5290d3c95/epyqlib/utils/qt.py#L914
tests: https://github.com/altendky/stlib/blob/fc519e561adddb930c1dc7cdc6a74bd5290d3c95/epyqlib/tests/utils/test_qt.py

Anyways, hopefully this doesn't waste someone else's time. Figured I'd share something rather than just clicking the subscribe button.

@gshaikov
Copy link

gshaikov commented Apr 6, 2020

@danieljfarrell hi Daniel, are you planning to work on it? Otherwise I can pick this up. This feature will be handy in our org.

@danieljfarrell
Copy link
Author

@gshaikov I’m afraid I had to move on to other things. I’ve not made any progress with this.

@gshaikov
Copy link

gshaikov commented Apr 6, 2020

@hynek I saw your comment from 2017 about __setattr__, what prompted you to abandon it?
#233 (comment)

@hynek
Copy link
Member

hynek commented Apr 18, 2020

I literally wrote it in the next sentence. :). I didn't want to touch another dunder method but that reason has fallen away since we do touch __setattr__ now for frozen classes. If I had the time, I'd put it back.

@hynek
Copy link
Member

hynek commented Apr 18, 2020

I guess I could imagine an API similar to this:

x = attr.ib(set_hook=validate_if_has_validator)

with the usual syntactic sugar for combination using lists.

@hynek
Copy link
Member

hynek commented Jul 10, 2020

Please have a look at #660.

@hynek
Copy link
Member

hynek commented Jul 22, 2020

I believe this is fixed.

@hynek hynek closed this as completed Jul 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants