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

Always call super in init #113

Closed
NeilGirdhar opened this issue Nov 2, 2015 · 9 comments · Fixed by #174
Closed

Always call super in init #113

NeilGirdhar opened this issue Nov 2, 2015 · 9 comments · Fixed by #174
Milestone

Comments

@NeilGirdhar
Copy link

HasTraits.__init__ does not call super. It must call super if you want to use HasTraits in multiple inheritance.

HasTraits also silently swallows positional arguments. Why does it do that?

Finally, it would be nice if HasTraits.__init__ did not automatically set its keyword arguments onto the object. The problem with this is it means that HasTraits must be the final class in the mro, which is hard to guarantee. Is this behaviour really necessary?

@NeilGirdhar
Copy link
Author

@rmorshea These are bugs that need to be fixed please by the way. This is a basic requirement of multiple inheritance in Python.

@rmorshea
Copy link
Contributor

  1. I think super().__init__ is left out because HasTraits inherits from object.
  2. If I'm right this change in pass *args to __new__ #173 is the positional argument problem you mentioned?
  3. Value setting from kwargs in HasTraits.__init__ isn't something I'm attached to, but others probably are, and I imagine it'd represent a pretty big API breakage that would have to come in v5.0 if it were to come at all.

@NeilGirdhar
Copy link
Author

  1. That doesn't matter. A class can inherit from HasTraits and something else, which is why you must call super. E.g.

    class B:
       def __init__(self, *, x, **kwargs):
           super().__init__(**kwargs)
           self.y = f(x)
    
    class A(HasTraits, B):
        pass
    

    is broken. B.__init__ is never called.

  2. Yes, thank you!

  3. This breaks multiple inheritance. I personally don't think it's good Python. The only class that does this is dict, and I think that was a mistake that's unfortunately too late to fix. However, it is not too late for traitlets.

@rmorshea
Copy link
Contributor

@NeilGirdhar - see #174

@rmorshea
Copy link
Contributor

As for the value setting with kwargs, I'd create a separate issue for it and ping minrk, ellisonbg, and SylvainCorlay. I'm not sure what their reasons have been for keeping it so I can't speak for them on that.

@NeilGirdhar
Copy link
Author

@rmorshea Okay thanks. Note that unless you forward the kwargs to the super call in #174, my example above is still broken since x will be swallowed before it ever reaches B.__init__.

@rmorshea
Copy link
Contributor

@NeilGirdhar, unfortunately you can't do that since object.__init__ doesn't accept any args or kwargs.

@NeilGirdhar
Copy link
Author

@rmorshea You just forward the args and kwargs. If none of the superclasses consume them, then you're right that object.__init__ will raise. If there are none left, then there is no problem. This is how cooperative multiple inheritance works in Python.

@minrk
Copy link
Member

minrk commented Feb 17, 2016

Args are passed through to super in #175

@minrk minrk added this to the 4.2 milestone Feb 17, 2016
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 a pull request may close this issue.

3 participants