OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

How can I change the parameter signature in the help docs of a decorated function?

  • Thread starter Thread starter mipadi
  • Start date Start date
M

mipadi

Guest
I have a class that includes a method that takes two parameters, a and b, like so:

Code:
class Foo:
  def method(self, a, b):
    """Does something"""
    x, y, z = a.x, a.y, b.z
    return do(x, y, z)

When running help(Foo) in the Python REPL, you would see something like this:

Code:
class Foo(builtins.object)
 |  Methods defined here:
 |  
 |  method(self, a, b)
 |      Does something

I have updated the class with a decorator that manipulates the arguments passed into the method so instead of taking a and b and unpacking them, the decorator will do the unpacking and pass x, y, and z into the method:

Code:
def unpack(fn):
  def _unpack(self, a, b):
    x, y, z = a.x, a.y, b.z
    return fn(self, x, y, z)
  return _unpack

class Foo:
  @unpack
  def method(self, x, y, z):
    """Does something"""
    return do(x, y, z)

This works fine except that the help string isn't very helpful anymore:

Code:
class Foo(builtins.object)
 |  Methods defined here:
 |  
 |  method = _unpack(self, a, b)

The standard way to fix this is to use functools.wraps:

Code:
from functools import wraps

def unpack(fn):
  @wraps(fn)
  def _unpack(self, a, b):
    x, y, z = a.x, a.y, b.z
    return fn(self, x, y, z)
  return _unpack

And that works great, too, except that it shows the method as taking x, y, and z as arguments, when really it still takes a and b (that is, 2 arguments instead of 3), so the help doc is a bit misleading:

Code:
class Foo(builtins.object)
 |  Methods defined here:
 |  
 |  method(self, x, y, z)
 |      Does something

Is there a way to modify the function wrapper so it correctly grabs the doc string and other attributes as in functools.wraps but also shows the arguments accepted by the wrapper?

For example, I would like the help string to show:

Code:
class Foo(builtins.object)
 |  Methods defined here:
 |  
 |  method(self, a, b)
 |      Does something

even when the method is wrapped by unpack.

(I have examined the source code of functools.wraps but I could not figure out if that can copy the function signature or not.)
<p>I have a class that includes a method that takes two parameters, <code>a</code> and <code>b</code>, like so:</p>
<pre><code>class Foo:
def method(self, a, b):
"""Does something"""
x, y, z = a.x, a.y, b.z
return do(x, y, z)
</code></pre>
<p>When running <code>help(Foo)</code> in the Python REPL, you would see something like this:</p>
<pre><code>class Foo(builtins.object)
| Methods defined here:
|
| method(self, a, b)
| Does something
</code></pre>
<p>I have updated the class with a decorator that manipulates the arguments passed into the method so instead of taking <code>a</code> and <code>b</code> and unpacking them, the decorator will do the unpacking and pass <code>x</code>, <code>y</code>, and <code>z</code> into the method:</p>
<pre><code>def unpack(fn):
def _unpack(self, a, b):
x, y, z = a.x, a.y, b.z
return fn(self, x, y, z)
return _unpack

class Foo:
@unpack
def method(self, x, y, z):
"""Does something"""
return do(x, y, z)
</code></pre>
<p>This works fine except that the help string isn't very helpful anymore:</p>
<pre><code>class Foo(builtins.object)
| Methods defined here:
|
| method = _unpack(self, a, b)
</code></pre>
<p>The standard way to fix this is to use <code>functools.wraps</code>:</p>
<pre><code>from functools import wraps

def unpack(fn):
@wraps(fn)
def _unpack(self, a, b):
x, y, z = a.x, a.y, b.z
return fn(self, x, y, z)
return _unpack
</code></pre>
<p>And that works great, too, <em>except</em> that it shows the method as taking <code>x</code>, <code>y</code>, and <code>z</code> as arguments, when really it still takes <code>a</code> and <code>b</code> (that is, 2 arguments instead of 3), so the help doc is a bit misleading:</p>
<pre><code>class Foo(builtins.object)
| Methods defined here:
|
| method(self, x, y, z)
| Does something
</code></pre>
<p><strong>Is there a way to modify the function wrapper so it correctly grabs the doc string and other attributes as in <code>functools.wraps</code> <em>but</em> also shows the arguments accepted by the wrapper?</strong></p>
<p>For example, I would like the help string to show:</p>
<pre><code>class Foo(builtins.object)
| Methods defined here:
|
| method(self, a, b)
| Does something
</code></pre>
<p>even when the method is wrapped by <code>unpack</code>.</p>
<p>(I have examined the <a href="https://github.com/python/cpython/blob/13aefd175e3c04529251f175c23cb3ed88451fd0/Lib/functools.py#L65" rel="nofollow noreferrer">source code</a> of <code>functools.wraps</code> but I could not figure out if that can copy the function signature or not.)</p>
 

Latest posts

Top