Skip to content

Conversation

emar-kar
Copy link

Hello there, first of all, thank you for this amazing project!

While experimenting with it, I came across something that seems like unusual behavior when passing arguments into a Python class constructor.

I wrote a small code in go:

package lib

import "fmt"

type Test struct {
	Name string
}

func (t *Test) Print() {
	fmt.Printf("%#v\n", t)
}

After bindings generation, init looks like this:

class Test(go.GoClass):
	def __init__(self, *args, **kwargs):
		if len(kwargs) == 1 and 'handle' in kwargs:
			self.handle = kwargs['handle']
			_ginit.IncRef(self.handle)
		elif len(args) == 1 and isinstance(args[0], go.GoClass):
			self.handle = args[0].handle
			_ginit.IncRef(self.handle)
		else:
			self.handle = _ginit.lib_Test_CTor()
			_ginit.IncRef(self.handle)
			if  0 < len(args):
				self.Name = args[0]
			if "Name" in kwargs:
				self.Name = kwargs["Name"]

And works as intended:

>>> t = lib.Test(Name="Name")
>>> t
lib.Test ( Name=Name, handle=1, )
>>> t.Print()
&lib.Test{Name:"Name"}
>>> t.Name = "New name"
>>> t
lib.Test ( Name=New name, handle=1, )
>>> t.Print()
&lib.Test{Name:"New name"}

But as soon as I pass -rename=true flag, magic is happening. Init function does not change and gopy generates setter/getter for renamed name field:

>>> t = lib.Test()
>>> t
lib.Test ( handle=2, name=, )
>>> del t
>>> t = lib.Test(Name="Name")
>>> t
lib.Test ( Name=Name, handle=1, name=, )
>>> t.print()
&lib.Test{Name:""}
>>> t.name = "Name"
>>> t
lib.Test ( Name=Name, handle=1, name=Name, )
>>> t.print()
&lib.Test{Name:"Name"}
>>> del t
>>> t = lib.Test(name="Name")
>>> t
lib.Test ( handle=3, name=, )
>>> t.print()
&lib.Test{Name:""}
>>> del t
>>> t = lib.Test("Name")
>>> t
lib.Test ( Name=Name, handle=4, name=, )
>>> t.print()
&lib.Test{Name:""}

Instead of assigning the value to name in constructor, it creates a new property inside the Python class that is never actually used. Even if I pass a string as an argument or try using the newly created snake-cased name nothing changes. The only way is to use setter/getter methods after the class is created.

This change adds snake-case conversion of struct fields, in __init__ the way it allows to pass variables into constructor.

>>> t = lib.Test("Name")
>>> t
lib.Test ( handle=1, name=Name, )
>>> t.print()
&lib.Test{Name:"Name"}
>>> del t 
>>> t = lib.Test(name="Name")
>>> t
lib.Test ( handle=2, name=Name, )
>>> t.print()
&lib.Test{Name:"Name"}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant