Linux wheels for GTK3 are calling GTK2 libraries on Python 2.7?

I suspect something is wrong with the compiling/packaging of wxPython for Linux and python 2.7.

The robotframework library Screenshot was creating a segmentation fault when using the wxPython library, with Python 2.7 (but not with Python 3.7, or when using other libraries like PyGTK or Scrot). I observed the fault on Fedora Core 30 real machine, and also on Linux Mint Debian Edition 3 and Ubuntu 18.0.4 virtual boxes.

I have found the solution to move the wx.App() call, to the global scope. It was being called inside a “private” method in a class. With this solution, the segmentation fault did not occurred.
However, on the console there was errors referring site-packages/gtk2 libraries. I have found this to be really strange because I was using the GTK3 package.
Decided to uninstall wxPython GTK3, and install the GTK2 wheel. This definitely solved the problem.

So, even if Python 2.7 is ending support in less than a month, I wonder if the GTK3 code is calling GTK2 functions or libraries.

I have used versions 4.0.6 and 4.0.7.post2 (GTK3), and then installed 4.0.7.post2 GTK2.
You can see the issue at robotframework, here

Note: I have been using the GTK3 install with RIDE, without any problems. Only when a user reported this situation with Robot Framework’s Screenshot library, needed to use the GTK2 version and my fix.

Thanks.

There could be something wonky on the build VMs. With which actual wheel files did you observe the problem?

I have observed the problem with (“all” GTK3 packages):
https://extras.wxpython.org/wxPython4/extras/linux/gtk3/debian-9/wxPython-4.0.0-cp27-cp27mu-linux_x86_64.whl
https://extras.wxpython.org/wxPython4/extras/linux/gtk3/debian-9/wxPython-4.0.4-cp27-cp27mu-linux_x86_64.whl
https://extras.wxpython.org/wxPython4/extras/linux/gtk3/debian-9/wxPython-4.0.6-cp27-cp27mu-linux_x86_64.whl
https://extras.wxpython.org/wxPython4/extras/linux/gtk3/debian-9/wxPython-4.0.7.post2-cp27-cp27mu-linux_x86_64.whl

This is example of failed case:

I’m not able to duplicate this problem with just wxPython, however it looks like you are using something that is importing and using gtk-2.0 directly. I didn’t notice that when reading your first post. Anyway, it’s not too surprising that there are conflicts between gtk2 and gtk3 when they are both used in the same application. That would be like trying to use both tkinter and wxPython at the same time. If it works with Python3 then perhaps there is something different at a low level there, like better isolation between dynamically loaded libraries or something.

Below I show how I tested, by creating a new virtualenv, installing wxPython into it, and running a simple test from the command-line. Give that a try and see if it works for you. If you want to isolate where the problem comes from then you can incrementally add new packages and try again, also adding imports and test code as needed.

robind@debian:~/tmp$ python -m virtualenv Py27
Running virtualenv with interpreter /usr/bin/python2
New python executable in /home/robind/tmp/Py27/bin/python2
Also creating executable in /home/robind/tmp/Py27/bin/python
Installing setuptools, pkg_resources, pip, wheel...done.
robind@debian:~/tmp$ . Py27/bin/activate
(Py27) robind@debian:~/tmp$ which pip
/home/robind/tmp/Py27/bin/pip
(Py27) robind@debian:~/tmp$ pip install wxPython-4.0.7.post2-cp27-cp27mu-linux_x86_64.whl 
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7. More details about Python 2 support in pip, can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support
Processing ./wxPython-4.0.7.post2-cp27-cp27mu-linux_x86_64.whl
Collecting six
  Downloading https://files.pythonhosted.org/packages/65/26/32b8464df2a97e6dd1b656ed26b2c194606c16fe163c695a992b36c11cdf/six-1.13.0-py2.py3-none-any.whl
Collecting pillow
  Downloading https://files.pythonhosted.org/packages/1b/08/ff620ef5a6128ee6e7a505f5716f81fce7b71f3a69e99646ebe64e0b9984/Pillow-6.2.1-cp27-cp27mu-manylinux1_x86_64.whl (2.1MB)
     |████████████████████████████████| 2.1MB 4.4MB/s 
Collecting numpy<1.17; python_version <= "2.7"
  Downloading https://files.pythonhosted.org/packages/d7/b1/3367ea1f372957f97a6752ec725b87886e12af1415216feec9067e31df70/numpy-1.16.5-cp27-cp27mu-manylinux1_x86_64.whl (17.0MB)
     |████████████████████████████████| 17.0MB 11.5MB/s 
Installing collected packages: six, pillow, numpy, wxPython
Successfully installed numpy-1.16.5 pillow-6.2.1 six-1.13.0 wxPython-4.0.7.post2
(Py27) robind@debian:~/tmp$ 
(Py27) robind@debian:~/tmp$ python -c "import sys,wx; print(sys.version); print(wx.version()); a=wx.App(); wx.Frame(None, title='Hello').Show(); a.MainLoop()"
2.7.13 (default, Sep 26 2018, 18:42:22) 
[GCC 6.3.0 20170516]
4.0.7.post2 gtk3 (phoenix) wxWidgets 3.0.5

I also run your example without problems. See below the adaptation of the code of Screenshot.py, which is working OK with Python 2.7.17 and wxPython 4.0.7.post2 GTK2 (also using gdk) but not with GTK3 (spews gtk2 libraries paths). On Python 3.7.5 works OK with wxPython 4.0.7.post GTK3, but could not make it run with gdk because missing package.

#!/usr/bin/env python
import os
import sys
import wx

wx_app_reference = wx.App(False)

try:
    from gtk import gdk
except ImportError:
    gdk = None


class Screenshot():
    def __init__(self):
        # self._wx_app_reference = None
        pass

    def _wx_screenshot(self, path='wxexample.jpg'):
        #if not self._wx_app_reference:
        #    self._wx_app_reference = wx.App(False)
        context = wx.ScreenDC()
        width, height = context.GetSize()
        if wx.__version__ >= '4':
            bitmap = wx.Bitmap(width, height, -1)
        else:
            bitmap = wx.EmptyBitmap(width, height, -1)
        memory = wx.MemoryDC()
        memory.SelectObject(bitmap)
        memory.Blit(0, 0, width, height, context, -1, -1)
        memory.SelectObject(wx.NullBitmap)
        bitmap.SaveFile(path, wx.BITMAP_TYPE_JPEG)

    def _gtk_screenshot(self, path='gtkexample.jpg'):
        window = gdk.get_default_root_window()
        if not window:
            raise RuntimeError('Taking screenshot failed.')
        width, height = window.get_size()
        pb = gdk.Pixbuf(gdk.COLORSPACE_RGB, False, 8, width, height)
        pb = pb.get_from_drawable(window, window.get_colormap(),
                                  0, 0, 0, 0, width, height)
        if not pb:
            raise RuntimeError('Taking screenshot failed.')
        pb.save(path, 'jpeg')


if __name__ == "__main__":
    if len(sys.argv) not in [2, 3]:
        sys.exit("Usage: %s <path>|test [wx|gtk]"
                 % os.path.basename(sys.argv[0]))
    path = sys.argv[1] if sys.argv[1] != 'test' else 'example.jpg'
    module = sys.argv[2] if len(sys.argv) > 2 else None
    sc = Screenshot()
    if module and module.lower() == 'wx':
        sc._wx_screenshot(path) 
    if module and module.lower() == 'gtk':
        sc._gtk_screenshot(path) 

I expect that even if it seems to be working with Python3, that it would be safest to not use GTK/GDK 2 there either. It can probably be redone using GTK3 via the PyGObject package.