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 70178 - Gtk+-2.0 bindings conflict with 1.2
Gtk+-2.0 bindings conflict with 1.2
Status: RESOLVED FIXED
Product: gnome-python
Classification: Deprecated
Component: general
1.99.x
Other All
: Normal normal
: ---
Assigned To: Python bindings maintainers
Python bindings maintainers
Depends on:
Blocks:
 
 
Reported: 2002-01-31 14:40 UTC by Thomas Leonard
Modified: 2004-12-22 21:47 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Possible patch (5.32 KB, patch)
2002-06-24 14:23 UTC, Thomas Leonard
none Details | Review
patch for pygtk 2.0 head (2.72 KB, text/plain)
2002-08-15 16:21 UTC, Johan (not receiving bugmail) Dahlin
  Details
patch for pygtk 0.6.x head (3.62 KB, patch)
2002-08-15 16:22 UTC, Johan (not receiving bugmail) Dahlin
none Details | Review

Description Thomas Leonard 2002-01-31 14:40:12 UTC
As Gtk+-2.0 is a major API change, the developers allow both Gtk+-1.2 and
Gtk+-2.0 to co-exist peacefully on the same machine. Good.

However, gnome-python (which introduces even more radical API changes)
uses the same module name ('gtk') for both. This means that installing
any 2.0 python program will stop all existing 1.2 applications from working!

The module should be named 'gtk2'. That way, a program can just do, 'from
gtk2 import gtk, gdk' if it wants the new bindings and old programs will
continue working.

Thanks -- looking forward to migrating my apps to 2.0 :-)
Comment 1 James Henstridge 2002-02-04 07:42:49 UTC
Your arguments w.r.t. the gtk libraries are not very meaningful.  In a
single process, the two gtk versions are mutually exclusive (things
die if you link to both of them, as many gdkxft users found out).

The same is true with python.  Even if the library was renamed, it
would still be an error to do "import gtk, gtk2" (or import two
modules which used different versions of pygtk).  It would also
require big changes to pygtk programs (I know there is already a lot
of changes in pygtk, but these are not expected to be as big in the
future -- much cruft is gone).

If you want to have both versions on your system, the recommended
method is to install to different directories, and set PYTHONPATH
appropriately before running apps.

Marking resolved as WONTFIX.
Comment 2 Thomas Leonard 2002-02-04 11:28:25 UTC
Using both versions within a single process isn't what I meant at all!

I mean, I want to be able to install both the 1.2 bindings and the 2.0
bindings on the same system and be able to use both old and new
programs together, in the way that I can with C programs.

Setting PYTHONPATH is a totally unacceptable solution! ("OK mum, if
you want to run these programs here, set the PYTHONPATH environment
variable to this directory, but if you want to run these other ones,
set it *there* instead. What do you mean "What's an environment
variable?" No, you can't just click on the program you want!").

Comment 3 James Henstridge 2002-02-05 00:33:35 UTC
marking resolved WONTFIX.

If setting PYTHONPATH manually is too difficult, I recommend using a
shell script wrapper, which sets PYTHONPATH and exec's python.
Comment 4 Thomas Leonard 2002-02-05 11:22:51 UTC
Sets PYTHONPATH to what exactly? How do I know where the user has
installed the old version?

Could you give an example of a shell script that hacks into every
computer in the world with the 1.2 bindings installed and modifies
every python program using it so it won't break when 2.0 is
installed?

Or, do I have to do the shell script hack only for new programs that
use 2.0? In that case, it would be easier just to rename the module.

1.2 and 2.0 are totally different. They link against different
libraries. They have completely different APIs. They cannot use
the same module name!

For example, why don't you just call the module 'curses'. After all,
no program will want to use both gtk and curses at the same time!
Of course, installing it would break every existing curses
application, but hey, there are probably less curses python
programs than gtk ones, so less will break!

Is there any reason at all NOT to make this change? I can't see why
you're so reluctant to fix this...
Comment 5 James Henstridge 2002-02-06 08:44:06 UTC
Renaming all the modules is not an option.  If you can think of a
solution that does not involve this, I look forward to seeing it.
Comment 6 Thomas Leonard 2002-02-06 12:15:33 UTC
Could everything be moved one level down into a new module?
Eg,

from gtk2 import gtk
w = gtk.Window()
...

That way, the gtk modules themselves can continue to refer to 'gtk',
'gdk', etc.

Another approach would be to get gtk2 to do the module path tricks
(since it knows where it's installed):

import gtk2
gtk2.fix_up_path()
import gtk
w = gtk.Window()

Seems ugly, though. (of course, fix_up_path could be done within
gtk2's init...)

Yet another way is to define a symbol in __main__, eg:

use_gtk2 = 1
import gtk

What's the problem with renaming the gtk module, though?
(gdk, etc can keep the same names as they're inside the other one).

Comment 7 Thomas Leonard 2002-03-15 15:27:13 UTC
How about making 'gtk2' an alias for 'gtk'? Then at least programs
written for a (hypothetical) version of the package which doesn't
break existing apps will still work with the main trunk version?

[ Note: unassigning myself from this bug as I don't have CVS access
and thus can't fix it ]
Comment 8 James Henstridge 2002-05-05 11:54:54 UTC
Started a gtk.compat module to help with porting apps over.  Still
needs a fair bit of work though.
Comment 9 Thomas Leonard 2002-05-05 12:02:41 UTC
Well, OK. As long as existing software will run without modification.

Actually porting apps isn't much of a problem for me (in fact, I'm
looking forward to it ;-). It's the stuff that's already installed and 
which, therefore, I have no control over which was my worry.

Still don't understand the problem with using 'import gtk2 as gtk',
though (or even, 'import gtk2 as g' if you want to recoup the extra
typing at the start ;-).

Comment 10 Thomas Leonard 2002-06-24 14:23:13 UTC
Created attachment 9425 [details] [review]
Possible patch
Comment 11 Thomas Leonard 2002-06-24 14:28:08 UTC
The above patch is the one I'm currently using to allow me to install
both versions at once. Seems to be working OK so far. I've only
included the patch for one of the example files since the changes are
easy to do with a simple script.

The other possibility is to move everything down one level
(eg, import gtk.gtk.gdk rather than import gtk2.gdk) which might make
for less changes in the source code. Also, it means a small bit of
code can update sys.path and then 'import gtk.gdk' works as before.

I'm going to put this code in ROX-Lib, so hopefully it can detect
whether the ROX version of pygtk is installed or the GNOME version,
and adjust sys.path to work correctly for either case...
Comment 12 James Henstridge 2002-08-04 13:48:30 UTC
For the final solution, I would like to have a system where only one
version of pygtk is reachable in the Python path at one time.

My current idea is to spin new releases of stable and devel pygtk that
install into a subdir --  $(pythondir)/gtk-1.2 and
$(pythondir)/gtk-2.0 respectively (where pythondir is the
site-packages directory of the python installation).  Each version
would also install pygtk.pth pointing at their respective directory. 
This would make parallel installation a lot easier, and distributors
could decide which version would be the default version.

A new module (identical for both stable and devel versions, and not
likely to change ever) could be added that allowed an app to request a
particular version.  It's use would look like this:
    try:
        import pygtk
        pygtk.require("2.0")
    except ImportError: pass

(or something similar).  The require() function would search for a
gtk-2.0 directory under all the paths in sys.path, and prepend the
gtk-2.0 dir to the path if found, and raise an exception otherwise. 
It would also raise an exception if the requested version did not
exist.  Maybe also raise an exception on a second call to require() if
it requests a different version.

This solution is similar to the __future__ system in recent Python's,
and the Perl "require 5.6.1;" meta-statements.  I don't want to have
to handle cases where people accidentally load two versions of pygtk
in the same process.  It also provides a good way to handle this sort
of issue going forward.

What do you think of this?  Matt: how does this sound from a
packager's perspective?
Comment 13 Thomas Leonard 2002-08-04 13:59:54 UTC
Providing the same file in multiple packages sounds problematic.
How about this to stop people importing both:

>>> import gtk2
>>> sys.modules['gtk'] = gtk2    # do this in gtk2.__init__.py

>>> import gtk
>>> gtk.Window

Or, in gtk2.__init.py:

>>> import gtk2.dummy
>>> sys.modules['gtk'] = gtk2.dummy

Then:

>>> import gtk2
>>> import gtk
>>> dir(gtk)
[]

I intend to do something like this in my version, if noone can see any
problems...
Comment 14 James Henstridge 2002-08-04 14:25:06 UTC
I know that RPM allows multiple packages to contain a file provided
that the file is identical (as they would be in this case). 
Alternatively, the packager could only include the version from the
newer pygtk and make the 1.2 version depend on the newer one (or vice
versa ...).

If it was just a single module this might be workable.  However, we
have a collection of modules.  I would prefer a solution where I can
keep the entire set of modules mutually exclusive, to reduce the
likelyhood of a conflict.  It would also make it easier for addon
packages (such as gnome-python) to install in such a way that their
code won't be used with the wrong pygtk version).
Comment 15 James Henstridge 2002-08-14 14:09:23 UTC
After a little discussion and prototyping with Johan, we came up with
this system:
  http://www.daa.com.au/~james/files/pygtk-version-jh.tar.gz

Here is a small summary:

1. each major version of pygtk (1.2, 2.0, etc) installs under:
      $(prefix)/lib/python?.?/site-packages/gtk-x.y

2. each version of pygtk installs a file called pygtk.pth into:
      $(prefix)/lib/python?.?/site-packages
   containing a single line: gtk-x.y

3. each version of pygtk installs the file pygtk.py into
      $(prefix)/lib/python?.?/site-packages
   This file is identical for all pygtk versions.

Addon packages install into the appropriate gtk-x.y directory.


Results are:
a. Files for individual pygtk "platforms" are kept separate, and
   prevented from being imported together.

b. sysadmins and/or distributors can decide which version of pygtk
   is the default by adjusting pygtk.pth

c. Programs can request a particular major version of pygtk with:
      import pygtk ; pygtk.require('x.y')
   If they want a particular version, this can be followed with an
   assert:
      import pygtk ; pygtk.require('2.0')
      import gtk
      assert gtk.pygtk_version >= (1,99,12), 'pygtk version too old'
Comment 16 Johan (not receiving bugmail) Dahlin 2002-08-15 16:21:14 UTC
Created attachment 10509 [details]
patch for pygtk 2.0 head
Comment 17 Johan (not receiving bugmail) Dahlin 2002-08-15 16:22:51 UTC
Created attachment 10510 [details] [review]
patch for pygtk 0.6.x head
Comment 18 James Henstridge 2002-08-18 10:27:16 UTC
Checked in the parallel install patch on both branches.  The next
releases of each branch should parallel install with each other
without problem.
Comment 19 Thomas Leonard 2002-10-06 13:21:06 UTC
There is a slight problem if, eg, pygtk is installed in /usr and
gnome-python in /usr/local... only one of the directories gets
added to the path...

Eg, if Debian has installed the python-gtk2 package then installing
gnome-python2 from source breaks it (also, make uninstall doesn't
remove the directory, so it stays broken!).

Thanks,
Comment 20 James Henstridge 2002-11-20 13:42:14 UTC
mass reassign of open pygtk and gnome-python bugs.
Comment 21 Johan (not receiving bugmail) Dahlin 2002-12-08 23:07:40 UTC
Consider this closed, Thomas, open up a new bug for the different
prefix bug (found in debian) if needed.