Commit ab69e0fa authored by Kirill Smelkov's avatar Kirill Smelkov

@method: Fix it for Python3

There was no test for @method so far and that's why it went unnoticed.
But on Python3 it breaks on f.func_name:

	In [3]: def f(): pass

	In [4]: f.func_name
	---------------------------------------------------------------------------
	AttributeError                            Traceback (most recent call last)
	<ipython-input-4-662dcbac1531> in <module>()
	----> 1 f.func_name

	AttributeError: 'function' object has no attribute 'func_name'

Fix it by using f.__name__ which works on both py2 and py3.

Add test for @method to make sure it doesn't break unnoticed.
parent 69cef96e
...@@ -59,9 +59,9 @@ from golang._pycompat import im_class ...@@ -59,9 +59,9 @@ from golang._pycompat import im_class
def method(cls): def method(cls):
def deco(f): def deco(f):
if isinstance(f, (staticmethod, classmethod)): if isinstance(f, (staticmethod, classmethod)):
func_name = f.__func__.func_name func_name = f.__func__.__name__
else: else:
func_name = f.func_name func_name = f.__name__
setattr(cls, func_name, f) setattr(cls, func_name, f)
return deco return deco
......
...@@ -18,10 +18,10 @@ ...@@ -18,10 +18,10 @@
# See COPYING file for full licensing terms. # See COPYING file for full licensing terms.
# See https://www.nexedi.com/licensing for rationale and options. # See https://www.nexedi.com/licensing for rationale and options.
from golang import go, chan, select, default, _PanicError from golang import go, chan, select, default, _PanicError, method
from pytest import raises from pytest import raises
from os.path import dirname from os.path import dirname
import sys, time, threading, subprocess import sys, time, threading, inspect, subprocess
# tdelay delays a bit. # tdelay delays a bit.
# #
...@@ -324,3 +324,46 @@ def test_select(): ...@@ -324,3 +324,46 @@ def test_select():
done.recv() done.recv()
assert len(ch1._sendq) == len(ch1._recvq) == 0 assert len(ch1._sendq) == len(ch1._recvq) == 0
assert len(ch2._sendq) == len(ch2._recvq) == 0 assert len(ch2._sendq) == len(ch2._recvq) == 0
def test_method():
# test how @method works
class MyClass:
def __init__(self, v):
self.v = v
@method(MyClass)
def zzz(self, v, x=2, **kkkkwww):
assert self.v == v
return v + 1
@method(MyClass)
@staticmethod
def mstatic(v):
assert v == 5
return v + 1
@method(MyClass)
@classmethod
def mcls(cls, v):
assert cls is MyClass
assert v == 7
return v + 1
obj = MyClass(4)
assert obj.zzz(4) == 4 + 1
assert obj.mstatic(5) == 5 + 1
assert obj.mcls(7) == 7 + 1
# this tests that @method preserves decorated function signature
assert inspect.formatargspec(*inspect.getargspec(MyClass.zzz)) == '(self, v, x=2, **kkkkwww)'
assert MyClass.zzz.__module__ == __name__
assert MyClass.zzz.__name__ == 'zzz'
assert MyClass.mstatic.__module__ == __name__
assert MyClass.mstatic.__name__ == 'mstatic'
assert MyClass.mcls.__module__ == __name__
assert MyClass.mcls.__name__ == 'mcls'
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment