Hi all,

I've been working on logilab-common py3k compatibility, by attempting to make
tests go to green. For more details, see http://www.logilab.org/ticket/104047.

Mosts tests will be fixed by http://www.logilab.org/patch/109341, but I've 
isolated
changes related to the @monkeypatch decorator since they are arguable. 
Discussion started
with Aurélien but I think it's worth bringing the subject here.

IMO we've two choices here. First, we could apply the following patch to make 
tests
pass: http://www.logilab.org/patch/109340

Or we could restrict the contract of the monkeypatch decorator. The offending 
test is the 
following:

        class XXX(object):
            def __call__(self, other):
                tester.assertIsInstance(other, MyClass)
                return 12
        monkeypatch(MyClass)(XXX())
        self.assertEqual(MyClass().foo(), 12)

It works in python2 because we added:

        if callable(func):
             if sys.version_info < (3, 0):
                 setattr(klass, name, method_type(func, None, klass))

i.e. turning whatever callable into a method. IMO this was not in the primary 
idea of monkeypatch
which was expected to be a syntactic sugar easing readability, but doing no 
intrusive change
on the "thing" being added to the patched class. In other word, 
monkeypatch(Toto)(tutu) should
be equivalent to Toto.tutu = tutu. Also, reading the test I feel this behaviour 
weird. If I attempt 
to monkeypatch an instance to a class, I don't expect this kind of implicit 
closure.
Aurélien, you added this case, was it theorical only or are you aware of any 
usage of it?

All this leads to the second possibility: declare this test as "out of the 
contract", document
it, and simply get back to :

def monkeypatch(klass, methodname=None):
    def decorator(func):
        try:
            name = methodname or func.__name__
        except AttributeError:
            raise AttributeError('%s has no __name__ attribute: '
                                 'you should provide an explicit `methodname`'
                                 % func)
        setattr(klass, name, func)
        return func
    return decorator

As we've too choose between breaking compat or adding weird boiler plate to keep
py3k forward compat, I would like other's opinion on this. My personal choice
goes to the second solution.

PS: History of discussion on this will be find in 
http://www.logilab.org/patch/104266
which has been splitted in the two patches above
-- 
Sylvain Thénault, LOGILAB, Paris (01.45.32.03.12) - Toulouse (05.62.17.16.42)
Formations Python, Debian, Méth. Agiles: http://www.logilab.fr/formations
Développement logiciel sur mesure:       http://www.logilab.fr/services
CubicWeb, the semantic web framework:    http://www.cubicweb.org
_______________________________________________
Python-Projects mailing list
Python-Projects@lists.logilab.org
http://lists.logilab.org/mailman/listinfo/python-projects

Reply via email to