Deprecate on_trait_change and magic change handlers#61
Deprecate on_trait_change and magic change handlers#61ellisonbg merged 8 commits intoipython:masterfrom
Conversation
2a2c45e to
fa4c133
Compare
|
PS: To handle the removal of the wrapped callbacks, I needed to write the wrapper to be comparable with the original function with |
traitlets/traitlets.py
Outdated
|
@ellisonbg @sccolbert as per earlier discussion. |
|
@SylvainCorlay, tested both constructs, 👍 |
|
The old constructs worked too, but I didn't get any warnings when run in an IPython console. |
|
Hum, I am seeing the warnings in the notebook. |
|
For whatever reason my session is not printing |
|
By default, deprecation warnings are not printed in python. You have to either manually set the warnings filter to allow them, or start python with a special switch. |
traitlets/traitlets.py
Outdated
There was a problem hiding this comment.
Can we make this _CallbackWrapper? It feels more pythonic than using abbreviations.
traitlets/traitlets.py
Outdated
There was a problem hiding this comment.
Are the keys really optional?
|
@minrk, @ellisonbg - when you guys have a minute, it'd be great to hear your comments. |
|
Let me know what you think.
|
|
OK I see this one and will have a look... On Sun, Aug 9, 2015 at 1:49 PM, Sylvain Corlay notifications@github.com
Brian E. Granger |
|
I think the name of the key in the change dict of |
|
Good point! On Thu, Aug 27, 2015 at 8:43 AM, Sylvain Corlay notifications@github.com
Brian E. Granger |
|
So are we moving to 'emitter'? |
|
Hmm, yeah, I can see how "emitter" has a "signal oriented" connotation On Thu, Aug 27, 2015 at 8:49 AM, Sylvain Corlay notifications@github.com
Brian E. Granger |
|
Although in the signaling PR, there are two bridges between traits and signaling:
In the latter case especially, mixing two systems where one uses |
|
+1 on emitter because it's more like source :) |
|
Pushed |
|
To clarify @minrk I think you are the right person to make this call. In I am personally 50/50 on owner versus emitter. On Thu, Aug 27, 2015 at 11:10 AM, Sylvain Corlay notifications@github.com
Brian E. Granger |
|
'source' sounded generic and ambiguous, 'emitter' seems better. |
|
Owner also seems slightly preferable to emitter, but both seem just fine. I'm okay with letting the current state of this PR make the choice.
|
|
We are getting @jdfreder to weigh in right now... On Thu, Aug 27, 2015 at 11:54 AM, Min RK notifications@github.com wrote:
Brian E. Granger |
|
@jdfreder voted for emitter. I am still 50/50. On Thu, Aug 27, 2015 at 11:58 AM, Brian Granger ellisonbg@gmail.com wrote:
Brian E. Granger |
|
@ellisonbg I updated the PR as per what we agreed on during the call. |
|
Just to update the community - on a phone call we reached consensus on using owner for this as this usage of more about a property pattern than a signaling one. If we ever have a signally abstraction we all agree that emitter would be good in that context. |
Deprecate on_trait_change and magic change handlers
|
And great work! |
There was a problem hiding this comment.
It turns out that since this is being registered in the metaclass. The ObserveHandler is preventing the function from being registered as a method at runtime like it normally would. instance_init should instead read:
def instance_init(self, inst):
self.func = types.MethodType(self.func, inst)
setattr(inst, self.name, self.func)
for name in self.names:
inst.observe(self.func, name= name)|
@rmorshea you are right. We should make it a bound method. Do you want to open a PR? |
|
Yep, I didn't see that No worries though, simply reimplement def __get__(self, inst, cls):
if inst is None:
return self
return MethodType(self.func, inst)The way it currently sits, it allocates a new bound method for each function for each instance. It then also consumes more space by storing the method on the instance, plus circular ref, etc. That's pretty wasteful and can cause some undue pain when people start creating lots of objects. |
|
I think that's a cleaner way to do it. What's the "circular ref" though, wouldn't the ObserveHander instance be garbage collected? |
|
The circular ref would be caused by the bound method holding a reference to the instance, and instance holding a reference to the bound method. It's not the end of the world, and the garbage collector would probably get to it eventually (unless the instance has a |
|
Gotcha, wasn't looking for it in the right place. |
Deprecation of
on_trait_changeand the signature of change handlersAs of now, this PR deprecates
on_trait_changeand the magic_*foo*_changedhandlers, to the benefit of newobserveandunobservemethod. The signature of the handlers passed toobserveis eitherdictargument containing 'name', 'old', 'new' and 'owner', the HasTraits instance emitting the event.See the examples below.
Implementation of an
observedecorator like in Atom:On the other side, atom implements a
observedecoratorThe problem is that the registration of the callback requires access
selfattribute, which is not available when the decorator is called. The way it works in atom is that the@observe('age')decorator replaces thedebug_printmethod with a placeholder objectObserveHandlerholding the method to be registered, which is to be picked up and unwrapped by theAtomMetametaclass when instantiating the instance of (the counterpart to) HasTraits.Rather than augmenting the metaclass, I could achieve the same result by making our
ObserveHandlerinherit fromBaseDescriptor, and implement the custom logic ininstance_init.Example with traitlets: