wxWidgets / Phoenix

wxPython's Project Phoenix. A new implementation of wxPython, better, stronger, faster than he was before.
http://wxpython.org/
2.32k stars 518 forks source link

v4.1.1: Crash in wx.Region(points) constructor on MacOS #1878

Open w3sip opened 3 years ago

w3sip commented 3 years ago

The crash is a regression between 4.1.0 -> 4.1.1, as demonstrated by the sequence of commands below: python -c "import wx; import sys; p=[(0,0), (10,10)]; r=wx.Region(p);" causes the crash with 4.1.1, but runs fine once 4.1.0 is installed.

Last login: Fri Dec 18 23:53:24 on ttys006
alex@mba ~ % which python
/Library/Frameworks/Python.framework/Versions/2.7/bin/python
alex@mba ~ % which pip
/Library/Frameworks/Python.framework/Versions/2.7/bin/pip
alex@mba ~ % pip list installed
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
Package                       Version
----------------------------- -------
astroid                       1.6.6
backports.functools-lru-cache 1.6.1
click                         7.1.2
configparser                  4.0.2
enum34                        1.1.10
futures                       3.3.0
isort                         4.3.21
lazy-object-proxy             1.5.1
mccabe                        0.6.1
numpy                         1.16.6
Pillow                        6.2.2
pip                           19.2.3
pylint                        1.9.5
PyOpenGL                      3.1.0
setuptools                    41.2.0
singledispatch                3.4.0.3
six                           1.15.0
spark-parser                  1.8.9
uncompyle6                    3.7.4
wrapt                         1.12.1
wxPython                      4.1.1
xdis                          5.0.5
WARNING: You are using pip version 19.2.3, however version 20.3.3 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
alex@mba ~ % python -c "import wx; import sys; p=[(0,0), (10,10)]; r=wx.Region(p);"
zsh: segmentation fault  python -c "import wx; import sys; p=[(0,0), (10,10)]; r=wx.Region(p);"
alex@mba ~ % pip install wxPython==4.1.0
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
Collecting wxPython==4.1.0
  Downloading https://files.pythonhosted.org/packages/15/ee/bf5067373201148bc25112f84081e6f64e31ab684d6ee48aa9778bfc6764/wxPython-4.1.0-cp27-cp27m-macosx_10_9_x86_64.whl (18.1MB)
     |████████████████████████████████| 18.1MB 24.0MB/s
Requirement already satisfied: six in ./Library/Python/2.7/lib/python/site-packages (from wxPython==4.1.0) (1.15.0)
Requirement already satisfied: pillow in /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages (from wxPython==4.1.0) (6.2.2)
Requirement already satisfied: numpy<1.17; python_version <= "2.7" in /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages (from wxPython==4.1.0) (1.16.6)
Installing collected packages: wxPython
  Found existing installation: wxPython 4.1.1
    Uninstalling wxPython-4.1.1:
      Successfully uninstalled wxPython-4.1.1
Successfully installed wxPython-4.1.0
WARNING: You are using pip version 19.2.3, however version 20.3.3 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
alex@mba ~ % python -c "import wx; import sys; p=[(0,0), (10,10)]; r=wx.Region(p);"
alex@mba ~ %
swt2c commented 3 years ago

Reproduced, not just a problem on macOS. I think I actually broke this myself. I'll send a fix soon.

RobinD42 commented 3 years ago

This code snippet in the OP still fails, but I'm not sure I can say which is wrong. 4.1.0 for allowing it to work, or 4.1.1 for failing.

Anyway, I expect that what is happening is that an unexpected overload is being chosen for [(0,0), (10,10)]. I'm guessing that what you are expecting to happen is that a wx.Rect will be automatically constructed and then passed on to the wx.Region(rect) version of the constructor, but it may be trying to use one of the other single arg ctors instead, which is failing and you end up with an empty region (also, there needs to be a wx.App before the region is created):

 >  python -c "import wx; app=wx.App(); p=[(0,0), (10,10)]; r=wx.Region(p); print(r.GetBox())"
(0, 0, 0, 0)

However, if you are more specific in what is being passed for the args then it works fine. For example, unpacking p to two tuples will cause the (point, point) constructor to be called:

>  python -c "import wx; app=wx.App(); p=[(0,0), (10,10)]; r=wx.Region(*p); print(r.GetBox())"
(0, 0, 10, 10)

Or creating an actual wx.Rect works too:

 >  python -c "import wx; app=wx.App(); p=[(0,0), (10,10)]; r=wx.Region(wx.Rect(*p)); print(r.GetBox())"
(0, 0, 10, 10)
millerabel commented 3 years ago

The ZetCode tutorial creates a star-shaped clipping region, using...

points = [(0, 85), (75, 75), (100, 10), (125, 75), (200, 85),
            (150, 125), (160, 190), (100, 150), (40, 190), (50, 125)]

region = wx.Region(points)

The work-around of expanding the list using *points will not work. Too many args. This was verified on 4.1.1. I also verified that this code example works fine on 4.1.0 (consistent with the comments).

pauldmccarthy commented 2 years ago

I'm hitting this as well on macOS, with wxpython 4.1.1 installed from conda-forge, via some code in wx/lib/agw/aui/framemanager.py, which boils down to this:

import wx
app = wx.App()
tld = wx.Region([(32, 24), (24, 32), (32, 21)])
psam44 commented 2 years ago

@RobinD42 Could you please remind us why you reopen the issue after the fix, which seems to solve the problem?

I was exposed to this crash on Windows and did these modifications (put in comments): wxPython-4.1.1\sip\cpp\sip_corewxRegion.cpp

        // PyErr_Clear();
        // Py_BEGIN_ALLOW_THREADS
        size_t count;
        wxPoint* array = wxPoint_array_helper(points, &count);
        if ( array != NULL ) {
            sipCpp = new wxRegion(count, array, fillStyle);
            delete [] array;
        }
        if (PyErr_Occurred()) sipIsErr = 1;
        // Py_END_ALLOW_THREADS
        // if (PyErr_Occurred()) sipIsErr = 1;

wxPython-4.1.1\sip\gen\region.sip (not sure if it's really necessary)

    %MethodCode
        //PyErr_Clear();
        //Py_BEGIN_ALLOW_THREADS
        size_t count;
        wxPoint* array = wxPoint_array_helper(points, &count);
        if ( array != NULL ) {
            sipCpp = new wxRegion(count, array, fillStyle);
            delete [] array;
        }
        if (PyErr_Occurred()) sipIsErr = 1;
        //Py_END_ALLOW_THREADS
        //if (PyErr_Occurred()) sipIsErr = 1;
    %End

And after a new build from sources, it works:

(py310wx) C:\tmp>py
Python 3.10.1 (tags/v3.10.1:2cd268a, Dec  6 2021, 19:10:37) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import wx
>>> wx.version()
'4.1.1 msw (phoenix) wxWidgets 3.1.5'
>>> r=wx.Region([10,12])  # just to prove the error management
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Expected a sequence of length-2 sequences or wx.Point objects.
>>> li=[wx.Point(1, 1)]
>>> r=wx.Region(li)
>>> r
<wx._core.Region object at 0x000001679A67DB40>
>>> r.GetBox()
wx.Rect(-1712480944, 359, 1712480944, -359)