{"id":4452,"date":"2014-03-30T11:10:13","date_gmt":"2014-03-30T11:10:13","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2014\/03\/30\/how-to-avoid-boilerplate-when-usign-super-in-python-2-6-collection-of-common-programming-errors\/"},"modified":"2014-03-30T11:10:13","modified_gmt":"2014-03-30T11:10:13","slug":"how-to-avoid-boilerplate-when-usign-super-in-python-2-6-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2014\/03\/30\/how-to-avoid-boilerplate-when-usign-super-in-python-2-6-collection-of-common-programming-errors\/","title":{"rendered":"How to avoid boilerplate when usign super(&hellip;) in Python 2.6+?-Collection of common programming errors"},"content":{"rendered":"<p><strong>tl;dr<\/strong><\/p>\n<p>As the OP said &#8220;Is it possible in Python 2.6+ without overt hacks?&#8221;, the answer is: <strong>No<\/strong><\/p>\n<p><strong>Long version<\/strong><\/p>\n<p><strike>You can make a simple decorator that will call the next parent with this method. The problem is that you will not have control on the arguments you want to pass.<\/strike><\/p>\n<p><strong>Edit:<\/strong> This will not work for a subclass already using <code>autosuper<\/code> because it&#8217;ll chose the wrong class and make an infinite loop.<\/p>\n<pre><code>def autosuper(fn):\n    def f(self, *args, **kw):\n        cl = super(type(self), self)\n        getattr(cl, fn.__name__)(*args, **kw)\n        return fn(self, *args, **kw)\n    return f\n<\/code><\/pre>\n<p><strong>How could this be done? Python 3.x do have a <code>super<\/code> function that takes no arguments!<\/strong><\/p>\n<p>Unfortunally, the Python 3.x&#8217;s <code>super<\/code> is a <em>class<\/em> and at the same time a <em>keyword<\/em>, because just the presence of its name will change the current environment to unveil a variable named <code>__class__<\/code> that is the right class you need to use!<\/p>\n<p>If you check the frame inside a function declared in a class, there&#8217;s no <code>__class__<\/code> variable and the <code>co_freevars<\/code> attribute of the frame&#8217;s <code>f_code<\/code> attribute is empty. When you write the name <code>super<\/code> (do not need to call it), the <code>__class__<\/code> string will appear in <code>co_freevars<\/code> meaning it comes from another closure. Also, if you try to access the <code>__class__<\/code> variable without using super, it&#8217;ll use the <code>LOAD_DEFER<\/code> bytecode for this same reason instead of <code>LOAD_GLOBAL<\/code> like would be normal to every undefined name.<\/p>\n<p>This is so crazy that you cannot just do <code>hyper = super<\/code> and call this new <code>hyper<\/code> variable without arguments (that is exactly the same object as <code>super<\/code>).<\/p>\n<p>As I cannot compete with this much of black magic inside the Python Interpreter, and because the <code>autosuper<\/code> decorator is not declared inside a class (so it can never access the <code>__class__<\/code> variable even if that was possible in Python 2.x), I will not try to write a new decorator and will leave this answer here as a warn for other people who want to do that.<\/p>\n<p>It is probably possible to make some hackeries to find the right class to use, but I will not dig that far. Things to consider:<\/p>\n<ul>\n<li>When the decorator is applied, the class do not exist yet, so this should be done when the decorated function is called.<\/li>\n<li>The function being decorated is not yet an <code>unbound method<\/code> (that were removed anyway from Py3k) so you cannot check the <code>im_class<\/code> attribute.<\/li>\n<li>The frame does not seem to hold any information of the class used to make this call (unless of course the <code>__class__<\/code> variable do exist and it is possible to get a reference to it)<\/li>\n<li>This answer provided by OP is also quite broken because it makes a lot of bad assumptions and has problems with decorated functions.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>tl;dr As the OP said &#8220;Is it possible in Python 2.6+ without overt hacks?&#8221;, the answer is: No Long version You can make a simple decorator that will call the next parent with this method. The problem is that you will not have control on the arguments you want to pass. Edit: This will not [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-4452","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/4452","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=4452"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/4452\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=4452"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=4452"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=4452"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}