@@ -53,23 +53,30 @@ in which case a new Go object is constructed first
5353 g .pywrap .Printf ("if len(kwargs) == 1 and 'handle' in kwargs:\n " )
5454 g .pywrap .Indent ()
5555 g .pywrap .Printf ("self.handle = kwargs['handle']\n " )
56+ g .pywrap .Printf ("_%s.IncRef(self.handle)\n " , g .outname )
5657 g .pywrap .Outdent ()
5758 g .pywrap .Printf ("elif len(args) == 1 and isinstance(args[0], go.GoClass):\n " )
5859 g .pywrap .Indent ()
5960 g .pywrap .Printf ("self.handle = args[0].handle\n " )
61+ g .pywrap .Printf ("_%s.IncRef(self.handle)\n " , g .outname )
6062 g .pywrap .Outdent ()
6163 g .pywrap .Printf ("else:\n " )
6264 g .pywrap .Indent ()
6365 g .pywrap .Printf ("self.handle = _%s.%s_CTor()\n " , pkgname , s .ID ())
66+ g .pywrap .Printf ("_%s.IncRef(self.handle)\n " , g .outname )
6467
6568 for i := 0 ; i < numFields ; i ++ {
6669 f := s .Struct ().Field (i )
6770 if _ , err := isPyCompatField (f ); err != nil {
6871 continue
6972 }
70- // TODO: this will accept int args for any handles / object fields
71- // need some kind of additional type-checking logic to prevent that in way
72- // that also allows valid handles to be used..
73+ // NOTE: this will accept int args for any handles / object fields so
74+ // some kind of additional type-checking logic to prevent that in a way
75+ // that also allows valid handles to be used as required. This is
76+ // achieved in the per-field setters (see below) with checks to ensure
77+ // that a struct field that is a gopy managed object is only
78+ // assigned gopy managed objects. Fields of basic types (e.g int, string)
79+ // etc can be assigned to directly.
7380 g .pywrap .Printf ("if %[1]d < len(args):\n " , i )
7481 g .pywrap .Indent ()
7582 g .pywrap .Printf ("self.%s = args[%d]\n " , f .Name (), i )
@@ -82,6 +89,11 @@ in which case a new Go object is constructed first
8289 g .pywrap .Outdent ()
8390 g .pywrap .Outdent ()
8491
92+ g .pywrap .Printf ("def __del__(self):\n " )
93+ g .pywrap .Indent ()
94+ g .pywrap .Printf ("_%s.DecRef(self.handle)\n " , s .Package ().Name ())
95+ g .pywrap .Outdent ()
96+
8597 if s .prots & ProtoStringer != 0 {
8698 for _ , m := range s .meths {
8799 if ! isStringer (m .obj ) {
@@ -223,7 +235,14 @@ func (g *pyGen) genStructMemberSetter(s *Struct, i int, f types.Object) {
223235 g .pywrap .Outdent ()
224236 g .pywrap .Printf ("else:\n " )
225237 g .pywrap .Indent ()
226- g .pywrap .Printf ("_%s.%s(self.handle, value)\n " , pkgname , cgoFn )
238+ // See comment in genStructInit about ensuring that gopy managed
239+ // objects are only assigned to from gopy managed objects.
240+ switch f .Type ().(type ) {
241+ case * types.Basic :
242+ g .pywrap .Printf ("_%s.%s(self.handle, value)\n " , pkgname , cgoFn )
243+ default :
244+ g .pywrap .Printf ("raise TypeError(\" supplied argument type {t} is not a go.GoClass\" .format(t=type(value)))\n " )
245+ }
227246 g .pywrap .Outdent ()
228247 g .pywrap .Outdent ()
229248
@@ -279,10 +298,12 @@ handle=A Go-side object is always initialized with an explicit handle=arg
279298 g .pywrap .Printf ("if len(kwargs) == 1 and 'handle' in kwargs:\n " )
280299 g .pywrap .Indent ()
281300 g .pywrap .Printf ("self.handle = kwargs['handle']\n " )
301+ g .pywrap .Printf ("_%s.IncRef(self.handle)\n " , g .outname )
282302 g .pywrap .Outdent ()
283303 g .pywrap .Printf ("elif len(args) == 1 and isinstance(args[0], go.GoClass):\n " )
284304 g .pywrap .Indent ()
285305 g .pywrap .Printf ("self.handle = args[0].handle\n " )
306+ g .pywrap .Printf ("_%s.IncRef(self.handle)\n " , g .outname )
286307 g .pywrap .Outdent ()
287308 g .pywrap .Printf ("else:\n " )
288309 g .pywrap .Indent ()
0 commit comments