[Python-porting] python 2/3 compatibility of function call

Radostin Stoyanov rstoyanov1 at gmail.com
Fri Sep 29 04:17:46 EDT 2017


Hello all,

I am working on a patch series for virt-manager [1] which aims to
resolve compatibility issues with Python 3. However I stuck with the
following issue:

1. When I run the tests with Python 3 some of them fail with:

    TypeError: set_memory_cb() takes 4 positional arguments but 5 were given

These errors are coming from this function call
<https://github.com/virt-manager/virt-manager/blob/master/virtinst/cli.py#L927>:

    self.cb(parser, inst, self.val, self)

Where `self.cb` is assigned to `ParserMemory.set_memory_cb`.

I found that the concept of “unbound methods” has been removed in Python
3. [2]
When referencing a method as a class attribute, you now get a plain
function object.

Example:

- Python 2                                

    >>> class X:                            
    ...     def foo(self): return 1         
    ...                                     
    >>> bar = X.foo                         
    >>> type(bar)                           
    <type 'instancemethod'>                 
    >>> X.foo(X())                          
    1                                       
    >>> X.foo(0)                            
    Traceback (most recent call last):      
      File "<stdin>", line 1, in <module>   
    TypeError: unbound method foo() must be c
    alled with X instance as first argument (
    got int instance instead)

- Pyhton 3

   >>> class X:
    ...     def foo(self): return 1
    ...
    >>> bar = X.foo
    >>> type(bar)
    <class 'function'>
    >>> X.foo(X())
    1
    >>> X.foo(0)
    1

However, I could not reproduce the issue causing TypeError as above. One
hacky solution could be to change functions like `set_memory_cb` in the
following way:

from

    def set_memory_cb(self, inst, val, virtarg):
        setattr(inst, virtarg.cliname, int(val) * 1024)

to

    def set_memory_cb(self, inst, val, virtarg, ignore=None):
        if ignore:
            self, inst, val, virtarg = inst, val, virtarg, ignore
         setattr(inst, virtarg.cliname, int(val) * 1024)

However,  I would like to ask for suggestions on how this issue could be
resolved properly?

[1] https://github.com/virt-manager/virt-manager
[2]
https://docs.python.org/release/3.0.1/whatsnew/3.0.html#operators-and-special-methods

Kind Regards,
Radostin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-porting/attachments/20170929/76a7f41d/attachment.html>


More information about the Python-porting mailing list