voc icon indicating copy to clipboard operation
voc copied to clipboard

Derived class doesn't inherit some magic(dunder) methods from the parent class

Open dibyadas opened this issue 8 years ago • 2 comments

The user-defined functions are inherited as expected , but overriden dunder methods like __str__() or __mul__() or __rmul_()_are not. Whereas __le__() , __lt__(), __eq__() works

class stu:
	def __init__(self,phy=0):
		self.phy=phy
	def __str__(self):
		return "testing"
    def test(self):
		print("user defined methods working")
	def __mul__(self,x):
		print("working ",  x)
class cstu(stu):
	def __init__(self,phy=0,math=0):
		stu.__init__(self,phy)
		self.math=math

a = cstu(30)
print(a)
a.test()
a*4

this gives me the expected output in python

testing
user defined methods working
working 4

while in voc i get,

<cstu object at 0x621be5d1>
user defined methods working
Exception in thread "main" TypeError: unsupported operand type(s) for *: 'cstu' and 'int'
	at org.python.types.Object.__mul__(Object.java:566)
	at python.inher.__init__.module$import(inher.py:39)
	at python.inher.__init__.main(inher.py)

dibyadas avatar Mar 17 '17 17:03 dibyadas

Confirmed here. This is so because in Java cstu inherits from org.python.types.Object, not from stu, and the * operator calls __mul__ on that cstu object, which is resolved to org.python.types.Object.__mul__.

As @cflee has mentioned in #363, one way to make it right is to getattribute and do Callable.invoke, and this should be the most straightforward solution.

And I just came up with another solution: how about making all the dunder methods delegates i.e. By leveraging Strategy Pattern? I guess this would avoid the getattribute and Callable.invoke, so as to boost performance and reduce generated code size (well, with static method helpers we won't worry about code size, though: #363). This solution would require a major reorg of current code and need some serious discussion, IMHO. What do you think? @cflee @freakboy3742 @eliasdorneles

leasunhy avatar Mar 21 '17 05:03 leasunhy

@eliasdorneles How about, whenever voc encounters a binop method , we convert it into a call node and pass it to the visit_Call() where it will be processed accordingly? I modified the visit_BinOp() ast.py file (this is just a test modification) :-

 def visit_BinOp(self, node):
        # expr left, operator op, expr right):
        #print(node.left.ctx)
        if isinstance(node.op, ast.Pow):
            self.visit(node.left)
            self.visit(node.right)
            self.context.add_opcodes(
                JavaOpcodes.ACONST_NULL(),
                JavaOpcodes.INVOKEINTERFACE(
                    'org/python/Object',
                    '__pow__',
                    args=['Lorg/python/Object;', 'Lorg/python/Object;'],
                    returns='Lorg/python/Object;'
                ),
            )
        elif isinstance(node.left,ast.Name):          #this is the part that i added
            self.visit(node.left)
            self.visit(node.right)
            attr2 = ast.Attribute(value=node.left,attr="__mul__",ctx=ast.Load())
            node.func = attr2
            node.args = [node.right]
            node.keywords = []
            self.visit_Call(node)
            print("passed to visit_call")
            return                                                ####
        else:
            self.visit(node.left)
            self.visit(node.right)
            self.context.add_opcodes(
                JavaOpcodes.INVOKEINTERFACE(
                  ....

this is the test example:-

class stu:
	def __init__(self,phy=0):
		self.phy=phy
	def __str__(self):
		return "testing"
    def test(self):
		print("user defined methods working")
	def __mul__(self,x):
		print("working ",  x)
class cstu(stu):
	def __init__(self,phy=0):
		stu.__init__(self,phy)

a = cstu(30)
print(a)
a.test()
a*4

this gives the correct output for the __mul__() in voc after the modification:-

<cstu object at 0x4ee285c6>
user defined methods working
mul working  4

I am still working on the print method.

dibyadas avatar Mar 22 '17 10:03 dibyadas