A decorator to call super()
Hi, I find this type of code quite often: class MyOverridedClass(MyBaseClass): def mymethod(self, foo, **kwargs): # Do something return super().mymethod(**kwargs) What about creating a decorator to call super() after/before the overrided method? Something like that: class MyOverridedClass(MyBaseClass): @extendsuper def mymethod(self, foo): # Do something Sorry if this has already been proposed, I have not found anything similar in the list. Best regards, Roberto
Hi Roberto, On 31.01.2017 08:13, Roberto Martínez wrote:
class MyOverridedClass(MyBaseClass): def mymethod(self, foo, **kwargs): # Do something return super().mymethod(**kwargs)
What about creating a decorator to call super() after/before the overrided method? Something like that:
class MyOverridedClass(MyBaseClass): @extendsuper def mymethod(self, foo): # Do something
I could find this useful. There's just on bikeshedding issue: When should "super().mymethod(**kwargs)" be called: *before*, *after* or inbetween my specialized code? Depending on the baseclass either of those three is necessary. As far as I can tell, we encounter all of them regularly. Best, Sven
I think both are useful. I would make this configurable with a flag: class MyOverridedClass(MyBaseClass): @extendsuper(after=True) def mymethod(self, foo): ... Or maybe a pair of decorator is a better option: @pre_super and @post_super El mar., 31 ene. 2017 a las 13:07, Sven R. Kunze (<srkunze@mail.de>) escribió:
Hi Roberto,
On 31.01.2017 08:13, Roberto Martínez wrote:
class MyOverridedClass(MyBaseClass): def mymethod(self, foo, **kwargs): # Do something return super().mymethod(**kwargs)
What about creating a decorator to call super() after/before the overrided method? Something like that:
class MyOverridedClass(MyBaseClass): @extendsuper def mymethod(self, foo): # Do something
I could find this useful. There's just on bikeshedding issue:
When should "super().mymethod(**kwargs)" be called: *before*, *after* or inbetween my specialized code?
Depending on the baseclass either of those three is necessary. As far as I can tell, we encounter all of them regularly.
Best, Sven
Roberto Martínez writes:
What about creating a decorator to call super() after/before the overrided method?
I think this is a reasonable idea, but you can do it yourself in a few lines, can't you? Are there any "gotchas" that make it hard to do correctly? Like Sven Kunze, I'm concerned about trying to standardize in the stdlib because a single method has ambiguous semantics (before, after, "during", asynchronously, ...) and the arguments to the decorated method are restricted so people will inevitably get it wrong. Alternatively, if you specify the semantics with an argument you end up with something like Lisp's "advice" function, which is a big hairball, or multiple decorators, to disambiguate. Personally, I don't think the explicit invocation is such a big deal to need a standardized decorator in the stdlib. YMMV, just expressing a few ideas. Steve
On Tue, Jan 31, 2017, at 02:32 PM, Stephen J. Turnbull wrote:
Personally, I don't think the explicit invocation is such a big deal to need a standardized decorator in the stdlib.
+1. It's one line either way, and the explicit call to super() seems clearer for people reading the code.
On 31 January 2017 at 13:05, Thomas Kluyver <thomas@kluyver.me.uk> wrote:
On Tue, Jan 31, 2017, at 02:32 PM, Stephen J. Turnbull wrote:
Personally, I don't think the explicit invocation is such a big deal to need a standardized decorator in the stdlib.
+1. It's one line either way, and the explicit call to super() seems clearer for people reading the code.
I agree that the explict call to super() is clear and concise enough - moreover you are in full control of where to call, plus what parameters to forward. BUT - no, it is _not_ an easy decorator to craft - and I don't think it can be made to work cleanly without depending on implementation details of cPython. I've been hitting the Python shell for 40+ minutes now, trying to get, in pure Python, a way for a method decorator to get a reference to the superclass in the way "super" does - it is not feasible without a metaclass. (I mean...it may be feasable, but one will be tough - one does not have a reference to the superclasses inside a class body as it is being parsed - I tried to trick the Python runtime into creating an empty __class__ cell in the decorator body for a decorator defined outside the class, and have that filled in, but it does not work as well). Still, such @pre_super and @post_super decorators might be something cute to have around - and can't be made in a trivial way either on the code base or on a pure-python 3rd party package. I would say I am +0 to "+0.5" on them. js -><-
BTW, if one can come up with a pure-Python implementation for these, I'd like to take a peek at the code, please. On 31 January 2017 at 13:57, Joao S. O. Bueno <jsbueno@python.org.br> wrote:
On 31 January 2017 at 13:05, Thomas Kluyver <thomas@kluyver.me.uk> wrote:
On Tue, Jan 31, 2017, at 02:32 PM, Stephen J. Turnbull wrote:
Personally, I don't think the explicit invocation is such a big deal to need a standardized decorator in the stdlib.
+1. It's one line either way, and the explicit call to super() seems clearer for people reading the code.
I agree that the explict call to super() is clear and concise enough - moreover you are in full control of where to call, plus what parameters to forward.
BUT - no, it is _not_ an easy decorator to craft - and I don't think it can be made to work cleanly without depending on implementation details of cPython.
I've been hitting the Python shell for 40+ minutes now, trying to get, in pure Python, a way for a method decorator to get a reference to the superclass in the way "super" does - it is not feasible without a metaclass. (I mean...it may be feasable, but one will be tough - one does not have a reference to the superclasses inside a class body as it is being parsed - I tried to trick the Python runtime into creating an empty __class__ cell in the decorator body for a decorator defined outside the class, and have that filled in, but it does not work as well).
Still, such @pre_super and @post_super decorators might be something cute to have around - and can't be made in a trivial way either on the code base or on a pure-python 3rd party package.
I would say I am +0 to "+0.5" on them.
js -><-
https://github.com/kirbyfan64/mirasu \-- Ryan (ライアン) Yoko Shimomura > ryo (supercell/EGOIST) > Hiroyuki Sawano >> everyone else <http://refi64.com/>
On 2017-01-31 10:57 AM, Joao S. O. Bueno wrote:
BUT - no, it is_not_ an easy decorator to craft - and I don't think it can be made to work cleanly without depending on implementation details of cPython.
Pure Python version is certainly possible with descriptor protocol. PoC: https://gist.github.com/1st1/ebee935256c7cc35c38cc3f73f00461d -1 on having a built-in like this. Yury
On 1/31/17 2:13 AM, Roberto Martínez wrote:
Hi,
I find this type of code quite often:
class MyOverridedClass(MyBaseClass): def mymethod(self, foo, **kwargs): # Do something return super().mymethod(**kwargs)
What about creating a decorator to call super() after/before the overrided method? Something like that:
class MyOverridedClass(MyBaseClass): @extendsuper def mymethod(self, foo): # Do something
Sorry if this has already been proposed, I have not found anything similar in the list. With all of the possible details that need to be covered (before/after, what args to pass along, what to do with the return value), this doesn't seem like a good idea to me. The most common use of super is in __init__, where the value should not be returned, and the example given here returns the value, so right off the bat, the example is at odds with common usage.
The super call is just one line, and the decorator would be one line, so there's no savings, no improvement to expressivitiy, and a loss of clarity: -1. --Ned.
Sure - thanks - I did not even consider the descriptor mechanism, as I got focused in getting the equivalent from the __class__ cell inside the decorator code. And of course, now there is the "__init_subclass__" mechanism - a mixin version using that was as straight forward as it can be as well. On 31 January 2017 at 17:33, Ned Batchelder <ned@nedbatchelder.com> wrote:
On 1/31/17 2:13 AM, Roberto Martínez wrote:
Hi,
I find this type of code quite often:
class MyOverridedClass(MyBaseClass): def mymethod(self, foo, **kwargs): # Do something return super().mymethod(**kwargs)
What about creating a decorator to call super() after/before the overrided method? Something like that:
class MyOverridedClass(MyBaseClass): @extendsuper def mymethod(self, foo): # Do something
Sorry if this has already been proposed, I have not found anything similar in the list. With all of the possible details that need to be covered (before/after, what args to pass along, what to do with the return value), this doesn't seem like a good idea to me. The most common use of super is in __init__, where the value should not be returned, and the example given here returns the value, so right off the bat, the example is at odds with common usage.
The super call is just one line, and the decorator would be one line, so there's no savings, no improvement to expressivitiy, and a loss of clarity: -1.
--Ned. _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
On 31 January 2017 at 21:55, Joao S. O. Bueno <jsbueno@python.org.br> wrote:
Sure - thanks - I did not even consider the descriptor mechanism, as I got focused in getting the equivalent from the __class__ cell inside the decorator code.
And of course, now there is the "__init_subclass__" mechanism - a mixin version using that was as straight forward as it can be as well.
Folks that are interested in these kinds of ideas may also want to take a look at Fraser Tweedale's "Elk" project and see what would be involved in porting the "method modifiers" feature to Python 3: https://frasertweedale.github.io/elk/modifiers.html Cheers, Nick. P.S. I don't know of anyone actually using Elk in production, but it's a good project to explore for anyone interested in more structured approaches to managing method overrides -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
participants (9)
-
Joao S. O. Bueno
-
Ned Batchelder
-
Nick Coghlan
-
Roberto Martínez
-
Ryan Gonzalez
-
Stephen J. Turnbull
-
Sven R. Kunze
-
Thomas Kluyver
-
Yury Selivanov