Hacking On A super Alternative

Python’s super built-in has always bugged me. I’m talking about something much more superficial than James Knight’s thoughts on it being harmful. I’m talking out its signature. I dislike the fact that it requires the current class and instance to be passed in. For example:

class SubClass(BaseClass):
def method(self, arg, this=that):
    super(SubClass, self).method(arg, this)

To avoid doing an real work I hacked together an alternative implementation. I was able to get something that appears to work correctly, but I can’t guarantee it. With my new super the code would look like:

from better_super import super

class SubClass(BaseClass):
def method(self, arg, this=that):
    super().method(arg, this)

This should not be used in any real production code. There are likely bugs lurking in corner cases and strange failure modes. It’s also four times slower than the built-in super.

It was still interesting to explore the implementation and I learned a bit about frames in the process.

My hacky implementation:

better_super.py

import inspect as _inspect from __builtin__ import super as _builtin_super def _what_class_am_i_in(mro, func_name, func_code): for c in mro: if getattr(c, func_name).func_code is func_code: return c return None def super(): frame = _inspect.currentframe().f_back arg_info = _inspect.getargvalues(frame) self = arg_info[3][arg_info[0][0]] mro = _inspect.getmro(self.__class__) method_name = frame.f_code.co_name code_obj = frame.f_code cls = _what_class_am_i_in(mro, method_name, code_obj) return _builtin_super(cls, self)

I’d love to hear about other ways to implement this. Have you tried yet?

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Reddit
  • Technorati

Comments

  • Very neat solution. Not saying I'd use it (it would probably confuse the hell out of anyone who saw it unless they knew that super() was overridden), but cool nonetheless. :-)


    @Hanno, that's very cool and I hadn't heard about it. One thing that seems poor about it is how you can freely call methods through super() implicitly. For instance, if I have a method foo() and I call super() in it, it'll call the foo() in the supercalss without having to specify super().foo(). The implicit nature of this specific case seems like it could be counter-productive.

  • Err... that was @Hanno, not @dstanek

  • I was mulling over something like this the other day too. Cool to see that I was on the right track (but missing some of the implementation details...)


    @dstanek: nice! I was hoping that it was one of the warts that would get fixed, although I haven't actually tried Python 3 yet...

  • @Joshua: No, it would not break anything.


    @Hanno: Very cool. Maybe I should start looking and seeing what other goodness awaits me. So far I have considered 3.x to be in the land of fairies and unicorns.

  • Hanno Schlichting

    How about you look at http://www.python.org/dev/peps/pep-3135 ? This exact change has long been implemented in Python 3 ;-)

  • Knowing absolutely nothing about Python internals: is this simply Python compliant, or will it break on anything besides CPython?

blog comments powered by Disqus