Open w3sip opened 3 years ago
Reproduced, not just a problem on macOS. I think I actually broke this myself. I'll send a fix soon.
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)
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).
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)])
@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)
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.