After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 503668 - Unable to implement virtual method using the same name
Unable to implement virtual method using the same name
Status: RESOLVED OBSOLETE
Product: pygobject
Classification: Bindings
Component: codegen
2.15.x
Other Linux
: Normal normal
: ---
Assigned To: Nobody's working on this now (help wanted and appreciated)
Python bindings maintainers
Depends on:
Blocks:
 
 
Reported: 2007-12-14 22:05 UTC by Sébastien Granjoux
Modified: 2012-02-10 08:21 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
one proposal for fixing this (5.03 KB, patch)
2007-12-18 21:48 UTC, Sébastien Granjoux
reviewed Details | Review
Same than previous but without renaming virtual into vmethod (3.98 KB, patch)
2007-12-19 18:29 UTC, Sébastien Granjoux
none Details | Review

Description Sébastien Granjoux 2007-12-14 22:05:59 UTC
A object can implement several interfaces. But there is a problem if several interfaces have functions having the same name and must be implement by one python object.

In C, each interface has one private structure and the function name correspond to one member of this structure. The same name can be used in several interfaces.

In python each interface function is redirected to a python method named "do_" followed by the interface function name. So, if one python object implements several interfaces having a function with the same name, both function will use the same python method.

This can be avoided in the virtual function wrapper by overriding it and use a different function name. But, the "do_" name is used in the initialization of the interface (the function named __*__interface_init) and I think it is not possible to change or override it here.

Fixing this needs a change in codegen.py. I can write something but I don't know what is the best way to handle this issue.

It could be possible to generate a more complex "do_" name, by example "do_" + interface_name + method_name.
Else, it could be possible to add an additional parameter in the .defs file giving a additional name to use instead of the "do_" name, like the vtable argument.
And there are probably other solutions.
Comment 1 Paul Pogonyshev 2007-12-14 22:43:26 UTC
Are there any practical problems with this?  In which libraries?

This is a common problems and I don't see why in Python it should be different.  Any OOP language (so C is rather an exception than a norm) will have this problem.  Except that in language with argument type based overriden functions it is less severe.
Comment 2 Gian Mario Tagliaretti 2007-12-14 22:59:48 UTC
Any solution cannot go into codegen anyway, until PyGTK 3.0 (or equivalent)
Comment 3 Sébastien Granjoux 2007-12-15 09:51:55 UTC
(In reply to comment #1)
> Are there any practical problems with this?  In which libraries?

In gtk and gnome libraries that I know, interfaces are not used very often and in most of these cases, an object has to implement only one interface. So, I don't think I can find a problem here.

But, I'm working on Anjuta, and here interfaces are heavily used. You can see a list of defined interfaces here: 
www.anjuta.org/documentations/subpage/documents/libanjuta/index.html

And by example the editor plugin implements:
IAnjutaFile, IAnjutaFileSavable, IAnjutaDocument, IAnjutaEditor, IAnjutaEditorLineMode, IAnjutaEditorSelection, IAnjutaEditorConvert, IAnjutaEditorAssist, IAnjutaEditorLanguage, IAnjutaEditorView, IAnjutaEditorFolds, IAnjutaBookmark, IAnjutaMarkable, IAnjutaIndicable, IAnjutaPrint, IAnjutaEditorComment, IAnjutaEditorZoom, IAnjutaEditorGoto, IAnjutaEditorSearch.

With such a list of interfaces, I can find a problem by example clear is defined in IAnjutaIndicable and in IAnjutaDocument.

So, I would say yes, there is already some practical problems. Then, perhaps it's better to fix this in Anjuta than in codegen even if I think the same problem could happen with another project.

> This is a common problems and I don't see why in Python it should be different.
>  Any OOP language (so C is rather an exception than a norm) will have this
> problem.  Except that in language with argument type based overriden functions
> it is less severe.

For me, the problem is worst in C, because as it is not an OOP language so you have even conflicts between methods in different classes. But as the problem is so big, it has been fixed by adding the interface or the class name in the method name. This is true for every method in gtk and makes all names quite long. The same solution can be used in python and in any language.
Comment 4 Paul Pogonyshev 2007-12-16 11:14:01 UTC
Can you propose a real solution without breaking backward compatibility (I guess that would be unacceptable even for 3.0) and with more or less nice method names? Preferably, something similar must be doable in other languages too, because otherwise PyGTK would promote a solution making other binding partially unusable.

Otherwise I'm tempted to close this as "won't fix", though jdahlin or gjc input is needed first.
Comment 5 Sébastien Granjoux 2007-12-16 14:42:31 UTC
It's obvious for me too that it cannot break the backward compatibility.


Then, it could be possible to add a new optional parameter in define-virtual block, by example vfunction to define the name of the C field corresponding to the function. It would be similar to the vtable member in define-interface block. It will work like c-name but for virtual function, allowing to have a different name in C and in other language. In my case, I could write in the .defs file something like

(define-virtual clear_indicable
  (of-object "IAnjutaIndicable")
  (c-name "ianjuta_indicable_clear")
  (vfunction "clear")
  (return-type "none")
  (parameters
    '("GError**" "err")
  )
)

(define-virtual clear_document
  (of-object "IAnjutaDocument")
  (c-name "ianjuta_document_clear")
  (vfunction "clear")
  (return-type "none")
  (parameters
    '("GError**" "err")
  )
)

In codegen, if vfunction is defined, this name must be used each time it access to the C iface structure else it uses the function name as now. This change keeps the compatibility and will work in any language. The function name can be nice as it is chosen by the writer of the .defs file.


Another solution that doesn't need any change in the .defs file, is to look for "do_interface_name_function_name" and "do_function_name" function in the python object and take the first one found. In the example above, it means that I can define in the python object a function do_i_anjuta_document_clear and do_i_anjuta_indicable_clear, and they will be used instead of do_clear. This keeps the compatibility but could be difficult to implement in a language where it's not possible to test if a function exists or not. Anyway, I think the first solution is better.


Doing nothing is a last option. It's not the best one for me, so I'm trying to push another one but that's ok. I don't know how this will be solved.
Comment 6 Paul Pogonyshev 2007-12-16 14:48:52 UTC
I don't like the second proposal too, as it introduces ambiguity for programmers. First one is quite good. Though my vote doesn't count much, I don't mind accepting it if someone writes a patch.
Comment 7 Sébastien Granjoux 2007-12-16 15:08:15 UTC
This last comment is more encouraging.

I will see how it can be implemented and I will probably propose a patch later.
Comment 8 Sébastien Granjoux 2007-12-18 21:48:15 UTC
Created attachment 101223 [details] [review]
one proposal for fixing this

Here is a patch to fix this problem. I have added a new keyword vmethod which can be used in virtual and method definition like in the following example:
(define-virtual clear_indicable
  (of-object "IAnjutaIndicable")
  (c-name "ianjuta_indicable_clear")
  (vmethod "clear")
  (return-type "none")
  (parameters
    '("GError**" "err")
  )
)

For method it's rather useless because an object implements only one set of methods and all names must be different. It could be used to have a different name in python and in C though.

I have used the name vmethod instead of virtual in all templates in order to be more consistent, but it's not needed.

The change seems quite small and straight forward to me. I have checked that it doesn't changed anything in the pygtk C files generated by codegen (gdk.c, gtk.c, gtkunixprint.c, libglade.c).
Comment 9 Gustavo Carneiro 2007-12-19 00:06:18 UTC
I don't like the gratuitous s/virtual/vmethod/ substitutions.  Even if we considered the name 'vmethod' slightly better, why needlessly complicate the patch for a simple name change?

Other than that, sounds ok to me, I guess.  It's simple and unintrusive.  OTOH there is a danger of obfuscation; changing the virtual method name from C to Python makes it harder to discover... so I would advise against abusing this feature; IMHO it should only be used as last resort.
Comment 10 Sébastien Granjoux 2007-12-19 18:29:12 UTC
Created attachment 101271 [details] [review]
Same than previous but without renaming virtual into vmethod

This makes the name in the .defs file and in codegen.py different. I find it slightly annoying. Perhaps it will be better to use virtual instead of vmethod in the .defs file too. But in this case, there will be "define-virtual" and "virtual" keywords which have close name but quite different meaning.
Comment 11 Naba Kumar 2008-03-20 20:34:08 UTC
Any update on this? This fix is really important for getting anjuta python binding working. As Sebastien pointed out, anjuta uses interfaces heavily and this fix would benefit it very much.
Comment 12 Martin Pitt 2012-02-10 08:19:59 UTC
codegen and the static bindings are obsolete since pygobject 3.0, which is GI only.

In the GI version, signal overriding works fine, and has test cases.

Thanks!
Comment 13 Martin Pitt 2012-02-10 08:21:01 UTC
Sorry, the previous comment was intended for a different bug. But the first sentence still applies, codegen is gone.