From 1f059e8999c00dd027b0016548cde864ddea8aa8168472ffff6bc6239633d554 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Fri, 30 Aug 2024 00:55:16 +0000 Subject: [PATCH] - Add Phoenix-pr2580+2591+2592-numpy2.patch * gh#wxWidgets/Phoenix#2580 * gh#wxWidgets/Phoenix#2591 - Update multibuild * Finalize preparation for python313 * Drop obsolete python39 OBS-URL: https://build.opensuse.org/package/show/X11:wxWidgets/python-wxPython?expand=0&rev=57 --- .gitattributes | 23 + .gitignore | 1 + 0001-Check-HSV-values-in-image-test.patch | 26 + ...s-CreateSurface-which-is-only-availa.patch | 33 + ...-Support-building-with-Doxygen-1.9.7.patch | 48 + ...l-OSX-overrides-since-they-re-now-do.patch | 73 + 0001-wxWidgets-Phoenix-integer-division.patch | 25 + 0003-Make-pip-usage-in-wxget-optional.patch | 49 + ...ypedef-extend-DateTime.FromTimeT-tes.patch | 55 + Phoenix-pr2580+2591+2592-numpy2.patch | 382 ++ _constraints | 7 + _multibuild | 7 + drop-py2.patch | 5640 +++++++++++++++++ python-wxPython-rpmlintrc | 3 + python-wxPython.changes | 627 ++ python-wxPython.spec | 337 + repack | 4 + require-numpy.patch | 11 + use_stl_build.patch | 11 + wxPython-4.2.1.tar.gz | 3 + wxwidgets-3.2.5.patch | 34 + 21 files changed, 7399 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 0001-Check-HSV-values-in-image-test.patch create mode 100644 0001-Handle-wxGLCanvas-CreateSurface-which-is-only-availa.patch create mode 100644 0001-Support-building-with-Doxygen-1.9.7.patch create mode 100644 0001-Update-wxTextCtrl-OSX-overrides-since-they-re-now-do.patch create mode 100644 0001-wxWidgets-Phoenix-integer-division.patch create mode 100644 0003-Make-pip-usage-in-wxget-optional.patch create mode 100644 0004-Fix-time_t-ETG-typedef-extend-DateTime.FromTimeT-tes.patch create mode 100644 Phoenix-pr2580+2591+2592-numpy2.patch create mode 100644 _constraints create mode 100644 _multibuild create mode 100644 drop-py2.patch create mode 100644 python-wxPython-rpmlintrc create mode 100644 python-wxPython.changes create mode 100644 python-wxPython.spec create mode 100644 repack create mode 100644 require-numpy.patch create mode 100644 use_stl_build.patch create mode 100644 wxPython-4.2.1.tar.gz create mode 100644 wxwidgets-3.2.5.patch diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9b03811 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,23 @@ +## Default LFS +*.7z filter=lfs diff=lfs merge=lfs -text +*.bsp filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.gem filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.lz filter=lfs diff=lfs merge=lfs -text +*.lzma filter=lfs diff=lfs merge=lfs -text +*.obscpio filter=lfs diff=lfs merge=lfs -text +*.oxt filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.rpm filter=lfs diff=lfs merge=lfs -text +*.tbz filter=lfs diff=lfs merge=lfs -text +*.tbz2 filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.txz filter=lfs diff=lfs merge=lfs -text +*.whl filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57affb6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.osc diff --git a/0001-Check-HSV-values-in-image-test.patch b/0001-Check-HSV-values-in-image-test.patch new file mode 100644 index 0000000..b16aa7d --- /dev/null +++ b/0001-Check-HSV-values-in-image-test.patch @@ -0,0 +1,26 @@ +From 12cb5458cf5c26080158ecbee010ae9073a907e7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20Br=C3=BCns?= +Date: Sun, 4 Oct 2020 21:19:36 +0200 +Subject: [PATCH] Check HSV values in image test + +--- + unittests/test_image.py | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/unittests/test_image.py b/unittests/test_image.py +index 767b36a7..a1dc0d7d 100644 +--- a/unittests/test_image.py ++++ b/unittests/test_image.py +@@ -234,6 +234,9 @@ class image_Tests(wtc.WidgetTestCase): + rgb = wx.Image.RGBValue(1,2,3) + hsv = wx.Image.RGBtoHSV(rgb) + rgb = wx.Image.HSVtoRGB(hsv) ++ self.assertAlmostEqual(hsv.value * 255.0, 3.0) ++ self.assertAlmostEqual(hsv.saturation* 255.0, 170.0) ++ self.assertAlmostEqual(hsv.hue * 360.0, 210.0) + self.assertEqual(rgb.red, 1) + self.assertEqual(rgb.green, 2) + self.assertEqual(rgb.blue, 3) +-- +2.28.0 + diff --git a/0001-Handle-wxGLCanvas-CreateSurface-which-is-only-availa.patch b/0001-Handle-wxGLCanvas-CreateSurface-which-is-only-availa.patch new file mode 100644 index 0000000..e308492 --- /dev/null +++ b/0001-Handle-wxGLCanvas-CreateSurface-which-is-only-availa.patch @@ -0,0 +1,33 @@ +From 371101db7a010d679d214fde617dae9de02008d9 Mon Sep 17 00:00:00 2001 +From: Scott Talbert +Date: Fri, 14 Jul 2023 13:23:03 -0400 +Subject: [PATCH] Handle wxGLCanvas::CreateSurface which is only available on + EGL + +--- + etg/_glcanvas.py | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/etg/_glcanvas.py b/etg/_glcanvas.py +index 52992ed8..2e578645 100644 +--- a/etg/_glcanvas.py ++++ b/etg/_glcanvas.py +@@ -125,6 +125,15 @@ def run(): + sipRes = wxGLCanvas::IsDisplaySupported(attribPtr); + """) + ++ c.find('CreateSurface').setCppCode("""\ ++ #if wxUSE_GLCANVAS_EGL ++ return self->CreateSurface(); ++ #else ++ wxPyRaiseNotImplemented(); ++ return false; ++ #endif ++ """) ++ + #----------------------------------------------------------------- + tools.doCommonTweaks(module) + tools.runGenerators(module) +-- +2.43.0 + diff --git a/0001-Support-building-with-Doxygen-1.9.7.patch b/0001-Support-building-with-Doxygen-1.9.7.patch new file mode 100644 index 0000000..d6a2f42 --- /dev/null +++ b/0001-Support-building-with-Doxygen-1.9.7.patch @@ -0,0 +1,48 @@ +From 6a049ccc0ad96f25c3f7d8540b218ffe8921d8c5 Mon Sep 17 00:00:00 2001 +From: Scott Talbert +Date: Tue, 5 Dec 2023 23:42:21 -0500 +Subject: [PATCH] Support building with Doxygen 1.9.7 + +Doxygen 1.9.7 made some changes whereby some method definitions are now +defined in separate XML files, with a "refid" that links to them. In +order to support this, we need to follow these "refids" to pick up the +method definition from the separate group XML files. +--- + etgtools/extractors.py | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/etgtools/extractors.py b/etgtools/extractors.py +index 8c992cb14..5ae1361f9 100644 +--- a/etgtools/extractors.py ++++ b/etgtools/extractors.py +@@ -62,6 +62,8 @@ def extract(self, element): + # class. Should be overridden in derived classes to get what each one + # needs in addition to the base. + self.name = element.find(self.nameTag).text ++ if self.name is None: ++ self.name = '' + if '::' in self.name: + loc = self.name.rfind('::') + self.name = self.name[loc+2:] +@@ -1574,12 +1576,21 @@ def addElement(self, element): + extractingMsg(kind, element) + for node in element.findall('sectiondef/memberdef'): + self.addElement(node) ++ for node in element.findall('sectiondef/member'): ++ node = self.resolveRefid(node) ++ self.addElement(node) + + else: + raise ExtractorError('Unknown module item kind: %s' % kind) + + return item + ++ def resolveRefid(self, node): ++ from etgtools import XMLSRC ++ refid = node.get('refid') ++ fname = os.path.join(XMLSRC, refid.rsplit('_', 1)[0]) + '.xml' ++ root = et.parse(fname).getroot() ++ return root.find(".//memberdef[@id='{}']".format(refid)) + + + def addCppFunction(self, type, name, argsString, body, doc=None, **kw): diff --git a/0001-Update-wxTextCtrl-OSX-overrides-since-they-re-now-do.patch b/0001-Update-wxTextCtrl-OSX-overrides-since-they-re-now-do.patch new file mode 100644 index 0000000..bee8771 --- /dev/null +++ b/0001-Update-wxTextCtrl-OSX-overrides-since-they-re-now-do.patch @@ -0,0 +1,73 @@ +From 7a198b8cae9a81cec4d25a0c6c5cc65ad8822bb2 Mon Sep 17 00:00:00 2001 +From: Scott Talbert +Date: Mon, 20 Nov 2023 22:12:58 -0500 +Subject: [PATCH] Update wxTextCtrl OSX overrides since they're now documented + +--- + etg/textctrl.py | 48 +++++++++++++++++++++--------------------------- + 1 file changed, 21 insertions(+), 27 deletions(-) + +diff --git a/etg/textctrl.py b/etg/textctrl.py +index af631a53..690d68c4 100644 +--- a/etg/textctrl.py ++++ b/etg/textctrl.py +@@ -114,35 +114,29 @@ def parseAndTweakModule(): + + + # OSX methods for controlling native features +- c.addCppMethod('void', 'OSXEnableAutomaticQuoteSubstitution', '(bool enable)', +- doc="Mac-only method for turning on/off automatic quote substitutions.", +- body="""\ +- #ifdef __WXMAC__ +- self->OSXEnableAutomaticQuoteSubstitution(enable); +- #else +- wxPyRaiseNotImplemented(); +- #endif +- """) ++ c.find('OSXEnableAutomaticQuoteSubstitution').setCppCode("""\ ++ #ifdef __WXMAC__ ++ self->OSXEnableAutomaticQuoteSubstitution(enable); ++ #else ++ wxPyRaiseNotImplemented(); ++ #endif ++ """) + +- c.addCppMethod('void', 'OSXEnableAutomaticDashSubstitution', '(bool enable)', +- doc="Mac-only method for turning on/off automatic dash substitutions.", +- body="""\ +- #ifdef __WXMAC__ +- self->OSXEnableAutomaticDashSubstitution(enable); +- #else +- wxPyRaiseNotImplemented(); +- #endif +- """) ++ c.find('OSXEnableAutomaticDashSubstitution').setCppCode("""\ ++ #ifdef __WXMAC__ ++ self->OSXEnableAutomaticDashSubstitution(enable); ++ #else ++ wxPyRaiseNotImplemented(); ++ #endif ++ """) + +- c.addCppMethod('void', 'OSXDisableAllSmartSubstitutions', '()', +- doc="Mac-only method to disable all automatic text substitutions.", +- body="""\ +- #ifdef __WXMAC__ +- self->OSXDisableAllSmartSubstitutions(); +- #else +- wxPyRaiseNotImplemented(); +- #endif +- """) ++ c.find('OSXDisableAllSmartSubstitutions').setCppCode("""\ ++ #ifdef __WXMAC__ ++ self->OSXDisableAllSmartSubstitutions(); ++ #else ++ wxPyRaiseNotImplemented(); ++ #endif ++ """) + + # TODO: add support for wxTextProofOptions (only supported on MSW/GTK3) + # so will need stubs on other platforms. +-- +2.43.0 + diff --git a/0001-wxWidgets-Phoenix-integer-division.patch b/0001-wxWidgets-Phoenix-integer-division.patch new file mode 100644 index 0000000..6ea13d2 --- /dev/null +++ b/0001-wxWidgets-Phoenix-integer-division.patch @@ -0,0 +1,25 @@ +From 3b042c863f4092f802a877a972fd6eb284451a78 Mon Sep 17 00:00:00 2001 +From: Ben Greiner +Date: Sat, 6 Jan 2024 21:58:29 +0100 +Subject: [PATCH] integer division for randint + +Python 3.12 does not accept floats for random.randint() anymore +--- + unittests/test_dcDrawLists.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/unittests/test_dcDrawLists.py b/unittests/test_dcDrawLists.py +index 9e35e5eaf..6696a79a0 100644 +--- a/unittests/test_dcDrawLists.py ++++ b/unittests/test_dcDrawLists.py +@@ -63,8 +63,8 @@ def makeRandomRectangles(): + rects = [] + + for i in range(num): +- W = random.randint(10, w/2) +- H = random.randint(10, h/2) ++ W = random.randint(10, w//2) ++ H = random.randint(10, h//2) + x = random.randint(0, w - W) + y = random.randint(0, h - H) + rects.append( (x, y, W, H) ) diff --git a/0003-Make-pip-usage-in-wxget-optional.patch b/0003-Make-pip-usage-in-wxget-optional.patch new file mode 100644 index 0000000..f88daa4 --- /dev/null +++ b/0003-Make-pip-usage-in-wxget-optional.patch @@ -0,0 +1,49 @@ +From 00ba66a86f65abb24402427d66bf50e8da477321 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20Br=C3=BCns?= +Date: Tue, 28 Jun 2022 18:16:34 +0200 +Subject: [PATCH 3/4] Make pip usage in wxget optional + +As the code states, using pip to download is abusing it, and as it is +just a fallback in case neither wget nor urllib works. +--- + wx/tools/wxget.py | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/wx/tools/wxget.py b/wx/tools/wxget.py +index c83ced7a..75eb0f47 100644 +--- a/wx/tools/wxget.py ++++ b/wx/tools/wxget.py +@@ -33,7 +33,6 @@ import os + import wx + import subprocess + import ssl +-import pip + + if sys.version_info >= (3,): + from urllib.error import (HTTPError, URLError) +@@ -44,6 +43,11 @@ else: + from urllib2 import (HTTPError, URLError) + import urlparse + ++try: ++ import pip ++except ImportError as e: ++ pip = None ++ + def get_docs_demo_url(demo=False): + """ Get the URL for the docs or demo.""" + if demo: +@@ -196,8 +200,8 @@ def download_file(url, dest=None, force=False, trusted=False): + success = download_wget(url, filename, trusted) # Try wget + if not success: + success = download_urllib(url, filename) # Try urllib +- if not success: +- success = download_pip(url, filename, force, trusted) # Try urllib ++ if not success and pip not None: ++ success = download_pip(url, filename, force, trusted) # Try pip + if not success: + split_url = url.split('/') + msg = '\n'.join([ +-- +2.36.1 + diff --git a/0004-Fix-time_t-ETG-typedef-extend-DateTime.FromTimeT-tes.patch b/0004-Fix-time_t-ETG-typedef-extend-DateTime.FromTimeT-tes.patch new file mode 100644 index 0000000..a7db15b --- /dev/null +++ b/0004-Fix-time_t-ETG-typedef-extend-DateTime.FromTimeT-tes.patch @@ -0,0 +1,55 @@ +From 70ecc1afcdd59bbd3b700d000e8f92740d218245 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20Br=C3=BCns?= +Date: Tue, 28 Jun 2022 18:32:32 +0200 +Subject: [PATCH 4/4] Fix time_t ETG typedef, extend DateTime.FromTimeT tests + +Before c78823549bac ("Ensure time_t is treated as a 64-bit value by SIP") +the typedef used "long" instead of wxInt64, which caused issues on Win64, +as long is 32bit there (LLP64). On the other hand, wxInt64 is wrong on +32 bit Linux (e.g. armv7, i586), and thus the code crashes. + +As SIP_SSIZE_T is 64 bit for both LLP64 (Windows) and LP64 (Linux), but +32 bit on 32bit archs, it matches time_t better (though, according to the +C standard, it could even be a double). +--- + etg/defs.py | 2 +- + unittests/test_wxdatetime.py | 8 +++++++- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/etg/defs.py b/etg/defs.py +index 4445cf93..ceb9e2ef 100644 +--- a/etg/defs.py ++++ b/etg/defs.py +@@ -73,7 +73,7 @@ def run(): + td = module.find('wxUIntPtr') + module.insertItemAfter(td, etgtools.TypedefDef(type='wchar_t', name='wxUChar')) + module.insertItemAfter(td, etgtools.TypedefDef(type='wchar_t', name='wxChar')) +- module.insertItemAfter(td, etgtools.TypedefDef(type='wxInt64', name='time_t')) ++ module.insertItemAfter(td, etgtools.TypedefDef(type='long', name='time_t')) + module.insertItemAfter(td, etgtools.TypedefDef(type='long long', name='wxFileOffset')) + module.insertItemAfter(td, etgtools.TypedefDef(type='SIP_SSIZE_T', name='ssize_t')) + module.insertItemAfter(td, etgtools.TypedefDef(type='unsigned char', name='byte', pyInt=True)) +diff --git a/unittests/test_wxdatetime.py b/unittests/test_wxdatetime.py +index 62e7d141..2f620045 100644 +--- a/unittests/test_wxdatetime.py ++++ b/unittests/test_wxdatetime.py +@@ -25,9 +25,15 @@ class datetime_Tests(wtc.WidgetTestCase): + def test_datetime2(self): + d1 = wx.DateTime.FromHMS(8, 15, 45, 123) + d2 = wx.DateTime.FromJDN(12345.67) +- d3 = wx.DateTime.FromTimeT(int(time.time())) + d4 = wx.DateTime.FromDMY(1, wx.DateTime.Mar, 2012, 8, 15, 45, 123) + ++ def test_datetimeTimeT(self): ++ d1 = wx.DateTime.FromTimeT(0) ++ self.assertEqual(d1.year, 1970) ++ d2 = wx.DateTime.FromTimeT(1643756400) # 2022-02-02 ++ self.assertEqual(d2.year, 2022) ++ d3 = wx.DateTime.FromTimeT(int(time.time())) ++ + def test_datetime3(self): + d1 = wx.DateTime.Today() + d2 = wx.DateTime.Now() +-- +2.36.1 + diff --git a/Phoenix-pr2580+2591+2592-numpy2.patch b/Phoenix-pr2580+2591+2592-numpy2.patch new file mode 100644 index 0000000..4135407 --- /dev/null +++ b/Phoenix-pr2580+2591+2592-numpy2.patch @@ -0,0 +1,382 @@ +From fa9050f865855392e8fa2bc95d53ade24d06e049 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Randy=20D=C3=B6ring?= + <30527984+radoering@users.noreply.github.com> +Date: Fri, 19 Jul 2024 18:00:02 +0200 +Subject: [PATCH 1/2] Fix NumPy 2.0 deprecations via running `ruff check + --select NPY201 --fix --exclude + docs/sphinx/rest_substitutions/snippets/python/converted` + +See https://numpy.org/devdocs/numpy_2_0_migration_guide.html#numpy-2-0-migration-guide +--- + demo/FloatCanvas.py | 14 +++++++------- + samples/floatcanvas/MovingElements.py | 2 +- + samples/floatcanvas/MovingTriangle.py | 4 ++-- + samples/floatcanvas/PolyEditor.py | 2 +- + samples/floatcanvas/ProcessDiagram.py | 2 +- + samples/floatcanvas/TextBox.py | 10 +++++----- + samples/floatcanvas/Tree.py | 2 +- + wx/lib/floatcanvas/FloatCanvas.py | 4 ++-- + wx/lib/plot/examples/demo.py | 2 +- + wx/lib/plot/plotcanvas.py | 2 +- + 10 files changed, 22 insertions(+), 22 deletions(-) + +diff --git a/demo/FloatCanvas.py b/demo/FloatCanvas.py +index 48d971cf3..f797340de 100644 +--- a/demo/FloatCanvas.py ++++ b/demo/FloatCanvas.py +@@ -720,7 +720,7 @@ def TestHitTest(self, event=None): + + x += dx + color = "SEA GREEN" +- Points = N.array(( (x, y), (x, y+2.*h/3), (x+w, y+h), (x+w, y+h/2.), (x + 2.*w/3, y+h/2.), (x + 2.*w/3,y) ), N.float_) ++ Points = N.array(( (x, y), (x, y+2.*h/3), (x+w, y+h), (x+w, y+h/2.), (x + 2.*w/3, y+h/2.), (x + 2.*w/3,y) ), N.float64) + R = Canvas.AddPolygon(Points, LineWidth = 2, FillColor = color) + R.Name = color + " Polygon" + R.Bind(FloatCanvas.EVT_FC_RIGHT_DOWN, self.RectGotHitRight) +@@ -729,7 +729,7 @@ def TestHitTest(self, event=None): + + x += dx + color = "Red" +- Points = N.array(( (x, y), (x, y+2.*h/3), (x+w, y+h), (x+w, y+h/2.), (x + 2.*w/3, y+h/2.), (x + 2.*w/3,y) ), N.float_) ++ Points = N.array(( (x, y), (x, y+2.*h/3), (x+w, y+h), (x+w, y+h/2.), (x + 2.*w/3, y+h/2.), (x + 2.*w/3,y) ), N.float64) + R = Canvas.AddPointSet(Points, Diameter = 4, Color = color) + R.Name = "PointSet" + R.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.PointSetGotHit) +@@ -1139,7 +1139,7 @@ def TestScaledTextBox(self, event= None): + Family = wx.FONTFAMILY_ROMAN, + Alignment = "right" + ) +- Point = N.array((100, -20), N.float_) ++ Point = N.array((100, -20), N.float64) + Box = Canvas.AddScaledTextBox("Here is even more auto wrapped text. This time the line spacing is set to 0.8. \n\nThe Padding is set to 0.", + Point, + Size = 3, +@@ -1153,7 +1153,7 @@ def TestScaledTextBox(self, event= None): + ) + Canvas.AddPoint(Point, "Red", 2) + +- Point = N.array((0, -40), N.float_) ++ Point = N.array((0, -40), N.float64) + # Point = N.array((0, 0), N.float_) + for Position in ["tl", "bl", "tr", "br"]: + # for Position in ["br"]: +@@ -1172,7 +1172,7 @@ def TestScaledTextBox(self, event= None): + ) + Canvas.AddPoint(Point, "Red", 4) + +- Point = N.array((-20, 60), N.float_) ++ Point = N.array((-20, 60), N.float64) + Box = Canvas.AddScaledTextBox("Here is some\ncentered\ntext", + Point, + Size = 4, +@@ -1188,7 +1188,7 @@ def TestScaledTextBox(self, event= None): + LineSpacing = 0.8 + ) + +- Point = N.array((-20, 20), N.float_) ++ Point = N.array((-20, 20), N.float64) + Box = Canvas.AddScaledTextBox("Here is some\nright aligned\ntext", + Point, + Size = 4, +@@ -1203,7 +1203,7 @@ def TestScaledTextBox(self, event= None): + LineSpacing = 0.8 + ) + +- Point = N.array((100, -60), N.float_) ++ Point = N.array((100, -60), N.float64) + Box = Canvas.AddScaledTextBox("Here is some auto wrapped text. This time it is centered, rather than right aligned.\n\nThe Padding is set to 2.", + Point, + Size = 3, +diff --git a/samples/floatcanvas/MovingElements.py b/samples/floatcanvas/MovingElements.py +index 40db28585..75229c07d 100644 +--- a/samples/floatcanvas/MovingElements.py ++++ b/samples/floatcanvas/MovingElements.py +@@ -160,7 +160,7 @@ def CompPoints(self, XY, L): + Points = N.array(((0, c), + ( L/2.0, -c/2.0), + (-L/2.0, -c/2.0)), +- N.float_) ++ N.float64) + + Points += XY + return Points +diff --git a/samples/floatcanvas/MovingTriangle.py b/samples/floatcanvas/MovingTriangle.py +index f3277f212..822662467 100644 +--- a/samples/floatcanvas/MovingTriangle.py ++++ b/samples/floatcanvas/MovingTriangle.py +@@ -64,7 +64,7 @@ def CompPoints(self, XY, L): + Points = N.array(((0, c), + ( L/2.0, -c/2.0), + (-L/2.0, -c/2.0)), +- N.float_) ++ N.float64) + + Points += XY + return Points +@@ -104,7 +104,7 @@ def __init__(self,parent, id,title,position,size): + Points = N.array(((0,0), + (1,0), + (0.5, 1)), +- N.float_) ++ N.float64) + + data = (( (0,0), 1), + ( (3,3), 2), +diff --git a/samples/floatcanvas/PolyEditor.py b/samples/floatcanvas/PolyEditor.py +index 55b1af429..270daa835 100644 +--- a/samples/floatcanvas/PolyEditor.py ++++ b/samples/floatcanvas/PolyEditor.py +@@ -112,7 +112,7 @@ def OnMove(self, event): + dc.SetPen(wx.Pen('WHITE', 2, wx.SHORT_DASH)) + dc.SetLogicalFunction(wx.XOR) + if self.SelectedPointNeighbors is None: +- self.SelectedPointNeighbors = N.zeros((3,2), N.float_) ++ self.SelectedPointNeighbors = N.zeros((3,2), N.float64) + #fixme: This feels very inelegant! + if Index == 0: + self.SelectedPointNeighbors[0] = self.SelectedPoly.Points[-1] +diff --git a/samples/floatcanvas/ProcessDiagram.py b/samples/floatcanvas/ProcessDiagram.py +index cf8609055..f67f89550 100644 +--- a/samples/floatcanvas/ProcessDiagram.py ++++ b/samples/floatcanvas/ProcessDiagram.py +@@ -212,7 +212,7 @@ def CompPoints(self, XY, L): + Points = N.array(((0, c), + ( L/2.0, -c/2.0), + (-L/2.0, -c/2.0)), +- N.float_) ++ N.float64) + + Points += XY + return Points +diff --git a/samples/floatcanvas/TextBox.py b/samples/floatcanvas/TextBox.py +index 5badeb1d0..29db917c9 100644 +--- a/samples/floatcanvas/TextBox.py ++++ b/samples/floatcanvas/TextBox.py +@@ -188,7 +188,7 @@ def __init__(self,parent, id,title,position,size): + Family = wx.ROMAN, + Alignment = "right" + ) +- Point = N.array((100, -20), N.float_) ++ Point = N.array((100, -20), N.float64) + Box = Canvas.AddScaledTextBox("Here is even more auto wrapped text. This time the line spacing is set to 0.8. \n\nThe Padding is set to 0.", + Point, + Size = 3, +@@ -202,7 +202,7 @@ def __init__(self,parent, id,title,position,size): + ) + Canvas.AddPoint(Point, "Red", 2) + +- Point = N.array((0, -40), N.float_) ++ Point = N.array((0, -40), N.float64) + # Point = N.array((0, 0), N.float_) + for Position in ["tl", "bl", "tr", "br"]: + # for Position in ["br"]: +@@ -221,7 +221,7 @@ def __init__(self,parent, id,title,position,size): + ) + Canvas.AddPoint(Point, "Red", 4) + +- Point = N.array((-20, 60), N.float_) ++ Point = N.array((-20, 60), N.float64) + Box = Canvas.AddScaledTextBox("Here is some\ncentered\ntext", + Point, + Size = 4, +@@ -237,7 +237,7 @@ def __init__(self,parent, id,title,position,size): + LineSpacing = 0.8 + ) + +- Point = N.array((-20, 20), N.float_) ++ Point = N.array((-20, 20), N.float64) + Box = Canvas.AddScaledTextBox("Here is some\nright aligned\ntext", + Point, + Size = 4, +@@ -252,7 +252,7 @@ def __init__(self,parent, id,title,position,size): + LineSpacing = 0.8 + ) + +- Point = N.array((100, -60), N.float_) ++ Point = N.array((100, -60), N.float64) + Box = Canvas.AddScaledTextBox("Here is some auto wrapped text. This time it is centered, rather than right aligned.\n\nThe Padding is set to 2.", + Point, + Size = 3, +diff --git a/samples/floatcanvas/Tree.py b/samples/floatcanvas/Tree.py +index 7757651f5..4c75ac6af 100644 +--- a/samples/floatcanvas/Tree.py ++++ b/samples/floatcanvas/Tree.py +@@ -204,7 +204,7 @@ def CompPoints(self, XY, L): + Points = N.array(((0, c), + ( L/2.0, -c/2.0), + (-L/2.0, -c/2.0)), +- N.float_) ++ N.float64) + + Points += XY + return Points +diff --git a/wx/lib/floatcanvas/FloatCanvas.py b/wx/lib/floatcanvas/FloatCanvas.py +index a0c316cd3..7e0d5a4b3 100644 +--- a/wx/lib/floatcanvas/FloatCanvas.py ++++ b/wx/lib/floatcanvas/FloatCanvas.py +@@ -601,7 +601,7 @@ def Draw(self, Force=False): + + """ + +- if N.sometrue(self.PanelSize <= 2 ): ++ if any(self.PanelSize <= 2 ): + # it's possible for this to get called before being properly initialized. + return + if self.Debug: start = clock() +@@ -779,7 +779,7 @@ def ZoomToBB(self, NewBB=None, DrawFlag=True): + BoundingBox = self.BoundingBox + if (BoundingBox is not None) and (not BoundingBox.IsNull()): + self.ViewPortCenter = N.array(((BoundingBox[0,0]+BoundingBox[1,0])/2, +- (BoundingBox[0,1]+BoundingBox[1,1])/2 ),N.float_) ++ (BoundingBox[0,1]+BoundingBox[1,1])/2 ),N.float64) + self.MapProjectionVector = self.ProjectionFun(self.ViewPortCenter) + # Compute the new Scale + BoundingBox = BoundingBox*self.MapProjectionVector # this does need to make a copy! +diff --git a/wx/lib/plot/examples/demo.py b/wx/lib/plot/examples/demo.py +index 74312b772..ce1767b19 100644 +--- a/wx/lib/plot/examples/demo.py ++++ b/wx/lib/plot/examples/demo.py +@@ -231,7 +231,7 @@ def _draw8Objects(): + """ + Box plot + """ +- data1 = np.array([np.NaN, 337, 607, 583, 512, 531, 558, 381, 621, 574, ++ data1 = np.array([np.nan, 337, 607, 583, 512, 531, 558, 381, 621, 574, + 538, 577, 679, 415, 454, 417, 635, 319, 350, 183, + 863, 337, 607, 583, 512, 531, 558, 381, 621, 574, + 538, 577, 679, 415, 454, 417, 635, 319, 350, 97]) +diff --git a/wx/lib/plot/plotcanvas.py b/wx/lib/plot/plotcanvas.py +index 0e1e8a0e2..34ef5f02b 100644 +--- a/wx/lib/plot/plotcanvas.py ++++ b/wx/lib/plot/plotcanvas.py +@@ -2044,7 +2044,7 @@ def UpdatePointLabel(self, mDataDict): + """ + if self.last_PointLabel is not None: + # compare pointXY +- if np.sometrue( ++ if any( + mDataDict["pointXY"] != self.last_PointLabel["pointXY"]): + # closest changed + self._drawPointLabel(self.last_PointLabel) # erase old + +From 4e09cda937140d3c41b39830c55a272943f36aea Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Randy=20D=C3=B6ring?= + <30527984+radoering@users.noreply.github.com> +Date: Sat, 20 Jul 2024 07:46:26 +0200 +Subject: [PATCH 2/2] Use `numpy.any` instead of `any` because the latter does + not work for multidimensional arrays. + +--- + wx/lib/floatcanvas/FloatCanvas.py | 2 +- + wx/lib/plot/plotcanvas.py | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/wx/lib/floatcanvas/FloatCanvas.py b/wx/lib/floatcanvas/FloatCanvas.py +index 7e0d5a4b3..ebdd689fb 100644 +--- a/wx/lib/floatcanvas/FloatCanvas.py ++++ b/wx/lib/floatcanvas/FloatCanvas.py +@@ -601,7 +601,7 @@ def Draw(self, Force=False): + + """ + +- if any(self.PanelSize <= 2 ): ++ if N.any(self.PanelSize <= 2 ): + # it's possible for this to get called before being properly initialized. + return + if self.Debug: start = clock() +diff --git a/wx/lib/plot/plotcanvas.py b/wx/lib/plot/plotcanvas.py +index 34ef5f02b..b9f65d8db 100644 +--- a/wx/lib/plot/plotcanvas.py ++++ b/wx/lib/plot/plotcanvas.py +@@ -2044,7 +2044,7 @@ def UpdatePointLabel(self, mDataDict): + """ + if self.last_PointLabel is not None: + # compare pointXY +- if any( ++ if np.any( + mDataDict["pointXY"] != self.last_PointLabel["pointXY"]): + # closest changed + self._drawPointLabel(self.last_PointLabel) # erase old +From 3871204fd00e821c0ab3a67ec48afde6155b5222 Mon Sep 17 00:00:00 2001 +From: Steve Kowalik +Date: Thu, 29 Aug 2024 15:05:41 +1000 +Subject: [PATCH] Replace N.alltrue() with N.all() + +Building on the excellent work in f7d1d818, replace the two uses of +N.alltrue() with N.all(), since the former has been removed in numpy +2.0. +--- + unittests/test_lib_floatcanvas_bbox.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/unittests/test_lib_floatcanvas_bbox.py b/unittests/test_lib_floatcanvas_bbox.py +index 42ced9c83..11d159534 100644 +--- a/unittests/test_lib_floatcanvas_bbox.py ++++ b/unittests/test_lib_floatcanvas_bbox.py +@@ -460,7 +460,7 @@ class testNullBBox(wtc.WidgetTestCase): + B3 = BBox( ( (1.0, 2.0), (5.0, 10.0) ) ) + + def testValues(self): +- self.assertTrue( N.alltrue(N.isnan(self.B1)) ) ++ self.assertTrue( N.all(N.isnan(self.B1)) ) + + def testIsNull(self): + self.assertTrue( self.B1.IsNull ) +@@ -496,7 +496,7 @@ class testInfBBox(wtc.WidgetTestCase): + NB = NullBBox() + + def testValues(self): +- self.assertTrue( N.alltrue(N.isinf(self.B1)) ) ++ self.assertTrue( N.all(N.isinf(self.B1)) ) + + # def testIsNull(self): + # self.assertTrue( self.B1.IsNull ) +From ad8135462c7d140590e28fc37f9e6cbc263e5b0c Mon Sep 17 00:00:00 2001 +From: Ben Greiner +Date: Thu, 29 Aug 2024 12:27:09 +0200 +Subject: [PATCH] replace old numpy types no longer valid in numpy 2 + +--- + unittests/test_lib_floatcanvas_bbox.py | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/unittests/test_lib_floatcanvas_bbox.py b/unittests/test_lib_floatcanvas_bbox.py +index 42ced9c83..35630a452 100644 +--- a/unittests/test_lib_floatcanvas_bbox.py ++++ b/unittests/test_lib_floatcanvas_bbox.py +@@ -30,7 +30,7 @@ def testShape3(self): + self.assertRaises(ValueError, BBox, (0,0,5,6,7) ) + + def testArrayConstruction(self): +- A = N.array(((4,5),(10,12)), N.float_) ++ A = N.array(((4,5),(10,12)), N.float64) + B = BBox(A) + self.assertTrue(isinstance(B, BBox)) + +@@ -79,7 +79,7 @@ def testPassArray(self): + + def testPassArray2(self): + # same data type -- should be a view +- A = N.array( (((0,0),(5,5))), N.float_ ) ++ A = N.array( (((0,0),(5,5))), N.float64 ) + C = asBBox(A) + A[0,0] = -10 + self.assertTrue(C[0,0] == A[0,0]) +@@ -341,7 +341,7 @@ def testCreate(self): + Pts = N.array( ((5,2), + (3,4), + (1,6), +- ), N.float_ ) ++ ), N.float64 ) + B = fromPoints(Pts) + #B = BBox( ( (1.0, 2.0), (5.0, 10.0) ) ) + self.assertTrue(B[0,0] == 1.0 and +@@ -362,7 +362,7 @@ def testCreateInts(self): + ) + + def testSinglePoint(self): +- Pts = N.array( (5,2), N.float_ ) ++ Pts = N.array( (5,2), N.float64 ) + B = fromPoints(Pts) + self.assertTrue(B[0,0] == 5.0 and + B[0,1] == 2.0 and diff --git a/_constraints b/_constraints new file mode 100644 index 0000000..02387b4 --- /dev/null +++ b/_constraints @@ -0,0 +1,7 @@ + + + + 8 + + + diff --git a/_multibuild b/_multibuild new file mode 100644 index 0000000..592d4a9 --- /dev/null +++ b/_multibuild @@ -0,0 +1,7 @@ + + python3 + python310 + python311 + python312 + python313 + diff --git a/drop-py2.patch b/drop-py2.patch new file mode 100644 index 0000000..18b3bfe --- /dev/null +++ b/drop-py2.patch @@ -0,0 +1,5640 @@ +Index: wxPython-4.2.1/build.py +=================================================================== +--- wxPython-4.2.1.orig/build.py ++++ wxPython-4.2.1/build.py +@@ -13,8 +13,6 @@ + # License: wxWindows License + #---------------------------------------------------------------------- + +-from __future__ import absolute_import +- + import sys + import glob + import hashlib +@@ -51,10 +49,6 @@ from buildtools.config import Config, m + import buildtools.version as version + + +-# which version of Python is running this script +-PY2 = sys.version_info[0] == 2 +-PY3 = sys.version_info[0] == 3 +- + + # defaults + PYVER = '2.7' +@@ -1071,7 +1065,7 @@ def _removeSidebar(path): + tag = soup.find('div', 'document') + if tag: + tag.attrs['class'] = ['document-no-sidebar'] +- text = unicode(soup) if PY2 else str(soup) ++ text = str(soup) + with textfile_open(filename, 'wt') as f: + f.write(text) + +@@ -1481,9 +1475,6 @@ def cmd_build_wx(options, args): + if options.jom: + build_options.append('--jom') + +- if PY2: +- build_options.append('--no_dpi_aware') +- + else: + # Platform is something other than MSW + if options.osx_carbon: +Index: wxPython-4.2.1/buildtools/backports/six.py +=================================================================== +--- wxPython-4.2.1.orig/buildtools/backports/six.py ++++ /dev/null +@@ -1,952 +0,0 @@ +-# Copyright (c) 2010-2018 Benjamin Peterson +-# +-# Permission is hereby granted, free of charge, to any person obtaining a copy +-# of this software and associated documentation files (the "Software"), to deal +-# in the Software without restriction, including without limitation the rights +-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +-# copies of the Software, and to permit persons to whom the Software is +-# furnished to do so, subject to the following conditions: +-# +-# The above copyright notice and this permission notice shall be included in all +-# copies or substantial portions of the Software. +-# +-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +-# SOFTWARE. +- +-"""Utilities for writing code that runs on Python 2 and 3""" +- +-from __future__ import absolute_import +- +-import functools +-import itertools +-import operator +-import sys +-import types +- +-__author__ = "Benjamin Peterson " +-__version__ = "1.12.0" +- +- +-# Useful for very coarse version differentiation. +-PY2 = sys.version_info[0] == 2 +-PY3 = sys.version_info[0] == 3 +-PY34 = sys.version_info[0:2] >= (3, 4) +- +-if PY3: +- string_types = str, +- integer_types = int, +- class_types = type, +- text_type = str +- binary_type = bytes +- +- MAXSIZE = sys.maxsize +-else: +- string_types = basestring, +- integer_types = (int, long) +- class_types = (type, types.ClassType) +- text_type = unicode +- binary_type = str +- +- if sys.platform.startswith("java"): +- # Jython always uses 32 bits. +- MAXSIZE = int((1 << 31) - 1) +- else: +- # It's possible to have sizeof(long) != sizeof(Py_ssize_t). +- class X(object): +- +- def __len__(self): +- return 1 << 31 +- try: +- len(X()) +- except OverflowError: +- # 32-bit +- MAXSIZE = int((1 << 31) - 1) +- else: +- # 64-bit +- MAXSIZE = int((1 << 63) - 1) +- del X +- +- +-def _add_doc(func, doc): +- """Add documentation to a function.""" +- func.__doc__ = doc +- +- +-def _import_module(name): +- """Import module, returning the module after the last dot.""" +- __import__(name) +- return sys.modules[name] +- +- +-class _LazyDescr(object): +- +- def __init__(self, name): +- self.name = name +- +- def __get__(self, obj, tp): +- result = self._resolve() +- setattr(obj, self.name, result) # Invokes __set__. +- try: +- # This is a bit ugly, but it avoids running this again by +- # removing this descriptor. +- delattr(obj.__class__, self.name) +- except AttributeError: +- pass +- return result +- +- +-class MovedModule(_LazyDescr): +- +- def __init__(self, name, old, new=None): +- super(MovedModule, self).__init__(name) +- if PY3: +- if new is None: +- new = name +- self.mod = new +- else: +- self.mod = old +- +- def _resolve(self): +- return _import_module(self.mod) +- +- def __getattr__(self, attr): +- _module = self._resolve() +- value = getattr(_module, attr) +- setattr(self, attr, value) +- return value +- +- +-class _LazyModule(types.ModuleType): +- +- def __init__(self, name): +- super(_LazyModule, self).__init__(name) +- self.__doc__ = self.__class__.__doc__ +- +- def __dir__(self): +- attrs = ["__doc__", "__name__"] +- attrs += [attr.name for attr in self._moved_attributes] +- return attrs +- +- # Subclasses should override this +- _moved_attributes = [] +- +- +-class MovedAttribute(_LazyDescr): +- +- def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): +- super(MovedAttribute, self).__init__(name) +- if PY3: +- if new_mod is None: +- new_mod = name +- self.mod = new_mod +- if new_attr is None: +- if old_attr is None: +- new_attr = name +- else: +- new_attr = old_attr +- self.attr = new_attr +- else: +- self.mod = old_mod +- if old_attr is None: +- old_attr = name +- self.attr = old_attr +- +- def _resolve(self): +- module = _import_module(self.mod) +- return getattr(module, self.attr) +- +- +-class _SixMetaPathImporter(object): +- +- """ +- A meta path importer to import six.moves and its submodules. +- +- This class implements a PEP302 finder and loader. It should be compatible +- with Python 2.5 and all existing versions of Python3 +- """ +- +- def __init__(self, six_module_name): +- self.name = six_module_name +- self.known_modules = {} +- +- def _add_module(self, mod, *fullnames): +- for fullname in fullnames: +- self.known_modules[self.name + "." + fullname] = mod +- +- def _get_module(self, fullname): +- return self.known_modules[self.name + "." + fullname] +- +- def find_module(self, fullname, path=None): +- if fullname in self.known_modules: +- return self +- return None +- +- def __get_module(self, fullname): +- try: +- return self.known_modules[fullname] +- except KeyError: +- raise ImportError("This loader does not know module " + fullname) +- +- def load_module(self, fullname): +- try: +- # in case of a reload +- return sys.modules[fullname] +- except KeyError: +- pass +- mod = self.__get_module(fullname) +- if isinstance(mod, MovedModule): +- mod = mod._resolve() +- else: +- mod.__loader__ = self +- sys.modules[fullname] = mod +- return mod +- +- def is_package(self, fullname): +- """ +- Return true, if the named module is a package. +- +- We need this method to get correct spec objects with +- Python 3.4 (see PEP451) +- """ +- return hasattr(self.__get_module(fullname), "__path__") +- +- def get_code(self, fullname): +- """Return None +- +- Required, if is_package is implemented""" +- self.__get_module(fullname) # eventually raises ImportError +- return None +- get_source = get_code # same as get_code +- +-_importer = _SixMetaPathImporter(__name__) +- +- +-class _MovedItems(_LazyModule): +- +- """Lazy loading of moved objects""" +- __path__ = [] # mark as package +- +- +-_moved_attributes = [ +- MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), +- MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), +- MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), +- MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), +- MovedAttribute("intern", "__builtin__", "sys"), +- MovedAttribute("map", "itertools", "builtins", "imap", "map"), +- MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"), +- MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), +- MovedAttribute("getoutput", "commands", "subprocess"), +- MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), +- MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), +- MovedAttribute("reduce", "__builtin__", "functools"), +- MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), +- MovedAttribute("StringIO", "StringIO", "io"), +- MovedAttribute("UserDict", "UserDict", "collections"), +- MovedAttribute("UserList", "UserList", "collections"), +- MovedAttribute("UserString", "UserString", "collections"), +- MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), +- MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), +- MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), +- MovedModule("builtins", "__builtin__"), +- MovedModule("configparser", "ConfigParser"), +- MovedModule("copyreg", "copy_reg"), +- MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), +- MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), +- MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), +- MovedModule("http_cookies", "Cookie", "http.cookies"), +- MovedModule("html_entities", "htmlentitydefs", "html.entities"), +- MovedModule("html_parser", "HTMLParser", "html.parser"), +- MovedModule("http_client", "httplib", "http.client"), +- MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), +- MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"), +- MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), +- MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), +- MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), +- MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), +- MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), +- MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), +- MovedModule("cPickle", "cPickle", "pickle"), +- MovedModule("queue", "Queue"), +- MovedModule("reprlib", "repr"), +- MovedModule("socketserver", "SocketServer"), +- MovedModule("_thread", "thread", "_thread"), +- MovedModule("tkinter", "Tkinter"), +- MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), +- MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), +- MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), +- MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), +- MovedModule("tkinter_tix", "Tix", "tkinter.tix"), +- MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), +- MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), +- MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), +- MovedModule("tkinter_colorchooser", "tkColorChooser", +- "tkinter.colorchooser"), +- MovedModule("tkinter_commondialog", "tkCommonDialog", +- "tkinter.commondialog"), +- MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), +- MovedModule("tkinter_font", "tkFont", "tkinter.font"), +- MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), +- MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", +- "tkinter.simpledialog"), +- MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), +- MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), +- MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), +- MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), +- MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), +- MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), +-] +-# Add windows specific modules. +-if sys.platform == "win32": +- _moved_attributes += [ +- MovedModule("winreg", "_winreg"), +- ] +- +-for attr in _moved_attributes: +- setattr(_MovedItems, attr.name, attr) +- if isinstance(attr, MovedModule): +- _importer._add_module(attr, "moves." + attr.name) +-del attr +- +-_MovedItems._moved_attributes = _moved_attributes +- +-moves = _MovedItems(__name__ + ".moves") +-_importer._add_module(moves, "moves") +- +- +-class Module_six_moves_urllib_parse(_LazyModule): +- +- """Lazy loading of moved objects in six.moves.urllib_parse""" +- +- +-_urllib_parse_moved_attributes = [ +- MovedAttribute("ParseResult", "urlparse", "urllib.parse"), +- MovedAttribute("SplitResult", "urlparse", "urllib.parse"), +- MovedAttribute("parse_qs", "urlparse", "urllib.parse"), +- MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), +- MovedAttribute("urldefrag", "urlparse", "urllib.parse"), +- MovedAttribute("urljoin", "urlparse", "urllib.parse"), +- MovedAttribute("urlparse", "urlparse", "urllib.parse"), +- MovedAttribute("urlsplit", "urlparse", "urllib.parse"), +- MovedAttribute("urlunparse", "urlparse", "urllib.parse"), +- MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), +- MovedAttribute("quote", "urllib", "urllib.parse"), +- MovedAttribute("quote_plus", "urllib", "urllib.parse"), +- MovedAttribute("unquote", "urllib", "urllib.parse"), +- MovedAttribute("unquote_plus", "urllib", "urllib.parse"), +- MovedAttribute("unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"), +- MovedAttribute("urlencode", "urllib", "urllib.parse"), +- MovedAttribute("splitquery", "urllib", "urllib.parse"), +- MovedAttribute("splittag", "urllib", "urllib.parse"), +- MovedAttribute("splituser", "urllib", "urllib.parse"), +- MovedAttribute("splitvalue", "urllib", "urllib.parse"), +- MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), +- MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), +- MovedAttribute("uses_params", "urlparse", "urllib.parse"), +- MovedAttribute("uses_query", "urlparse", "urllib.parse"), +- MovedAttribute("uses_relative", "urlparse", "urllib.parse"), +-] +-for attr in _urllib_parse_moved_attributes: +- setattr(Module_six_moves_urllib_parse, attr.name, attr) +-del attr +- +-Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes +- +-_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), +- "moves.urllib_parse", "moves.urllib.parse") +- +- +-class Module_six_moves_urllib_error(_LazyModule): +- +- """Lazy loading of moved objects in six.moves.urllib_error""" +- +- +-_urllib_error_moved_attributes = [ +- MovedAttribute("URLError", "urllib2", "urllib.error"), +- MovedAttribute("HTTPError", "urllib2", "urllib.error"), +- MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), +-] +-for attr in _urllib_error_moved_attributes: +- setattr(Module_six_moves_urllib_error, attr.name, attr) +-del attr +- +-Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes +- +-_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), +- "moves.urllib_error", "moves.urllib.error") +- +- +-class Module_six_moves_urllib_request(_LazyModule): +- +- """Lazy loading of moved objects in six.moves.urllib_request""" +- +- +-_urllib_request_moved_attributes = [ +- MovedAttribute("urlopen", "urllib2", "urllib.request"), +- MovedAttribute("install_opener", "urllib2", "urllib.request"), +- MovedAttribute("build_opener", "urllib2", "urllib.request"), +- MovedAttribute("pathname2url", "urllib", "urllib.request"), +- MovedAttribute("url2pathname", "urllib", "urllib.request"), +- MovedAttribute("getproxies", "urllib", "urllib.request"), +- MovedAttribute("Request", "urllib2", "urllib.request"), +- MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), +- MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), +- MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), +- MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), +- MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), +- MovedAttribute("BaseHandler", "urllib2", "urllib.request"), +- MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), +- MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), +- MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), +- MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), +- MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), +- MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), +- MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), +- MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), +- MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), +- MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), +- MovedAttribute("FileHandler", "urllib2", "urllib.request"), +- MovedAttribute("FTPHandler", "urllib2", "urllib.request"), +- MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), +- MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), +- MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), +- MovedAttribute("urlretrieve", "urllib", "urllib.request"), +- MovedAttribute("urlcleanup", "urllib", "urllib.request"), +- MovedAttribute("URLopener", "urllib", "urllib.request"), +- MovedAttribute("FancyURLopener", "urllib", "urllib.request"), +- MovedAttribute("proxy_bypass", "urllib", "urllib.request"), +- MovedAttribute("parse_http_list", "urllib2", "urllib.request"), +- MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"), +-] +-for attr in _urllib_request_moved_attributes: +- setattr(Module_six_moves_urllib_request, attr.name, attr) +-del attr +- +-Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes +- +-_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), +- "moves.urllib_request", "moves.urllib.request") +- +- +-class Module_six_moves_urllib_response(_LazyModule): +- +- """Lazy loading of moved objects in six.moves.urllib_response""" +- +- +-_urllib_response_moved_attributes = [ +- MovedAttribute("addbase", "urllib", "urllib.response"), +- MovedAttribute("addclosehook", "urllib", "urllib.response"), +- MovedAttribute("addinfo", "urllib", "urllib.response"), +- MovedAttribute("addinfourl", "urllib", "urllib.response"), +-] +-for attr in _urllib_response_moved_attributes: +- setattr(Module_six_moves_urllib_response, attr.name, attr) +-del attr +- +-Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes +- +-_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), +- "moves.urllib_response", "moves.urllib.response") +- +- +-class Module_six_moves_urllib_robotparser(_LazyModule): +- +- """Lazy loading of moved objects in six.moves.urllib_robotparser""" +- +- +-_urllib_robotparser_moved_attributes = [ +- MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), +-] +-for attr in _urllib_robotparser_moved_attributes: +- setattr(Module_six_moves_urllib_robotparser, attr.name, attr) +-del attr +- +-Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes +- +-_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), +- "moves.urllib_robotparser", "moves.urllib.robotparser") +- +- +-class Module_six_moves_urllib(types.ModuleType): +- +- """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" +- __path__ = [] # mark as package +- parse = _importer._get_module("moves.urllib_parse") +- error = _importer._get_module("moves.urllib_error") +- request = _importer._get_module("moves.urllib_request") +- response = _importer._get_module("moves.urllib_response") +- robotparser = _importer._get_module("moves.urllib_robotparser") +- +- def __dir__(self): +- return ['parse', 'error', 'request', 'response', 'robotparser'] +- +-_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), +- "moves.urllib") +- +- +-def add_move(move): +- """Add an item to six.moves.""" +- setattr(_MovedItems, move.name, move) +- +- +-def remove_move(name): +- """Remove item from six.moves.""" +- try: +- delattr(_MovedItems, name) +- except AttributeError: +- try: +- del moves.__dict__[name] +- except KeyError: +- raise AttributeError("no such move, %r" % (name,)) +- +- +-if PY3: +- _meth_func = "__func__" +- _meth_self = "__self__" +- +- _func_closure = "__closure__" +- _func_code = "__code__" +- _func_defaults = "__defaults__" +- _func_globals = "__globals__" +-else: +- _meth_func = "im_func" +- _meth_self = "im_self" +- +- _func_closure = "func_closure" +- _func_code = "func_code" +- _func_defaults = "func_defaults" +- _func_globals = "func_globals" +- +- +-try: +- advance_iterator = next +-except NameError: +- def advance_iterator(it): +- return it.next() +-next = advance_iterator +- +- +-try: +- callable = callable +-except NameError: +- def callable(obj): +- return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) +- +- +-if PY3: +- def get_unbound_function(unbound): +- return unbound +- +- create_bound_method = types.MethodType +- +- def create_unbound_method(func, cls): +- return func +- +- Iterator = object +-else: +- def get_unbound_function(unbound): +- return unbound.im_func +- +- def create_bound_method(func, obj): +- return types.MethodType(func, obj, obj.__class__) +- +- def create_unbound_method(func, cls): +- return types.MethodType(func, None, cls) +- +- class Iterator(object): +- +- def next(self): +- return type(self).__next__(self) +- +- callable = callable +-_add_doc(get_unbound_function, +- """Get the function out of a possibly unbound function""") +- +- +-get_method_function = operator.attrgetter(_meth_func) +-get_method_self = operator.attrgetter(_meth_self) +-get_function_closure = operator.attrgetter(_func_closure) +-get_function_code = operator.attrgetter(_func_code) +-get_function_defaults = operator.attrgetter(_func_defaults) +-get_function_globals = operator.attrgetter(_func_globals) +- +- +-if PY3: +- def iterkeys(d, **kw): +- return iter(d.keys(**kw)) +- +- def itervalues(d, **kw): +- return iter(d.values(**kw)) +- +- def iteritems(d, **kw): +- return iter(d.items(**kw)) +- +- def iterlists(d, **kw): +- return iter(d.lists(**kw)) +- +- viewkeys = operator.methodcaller("keys") +- +- viewvalues = operator.methodcaller("values") +- +- viewitems = operator.methodcaller("items") +-else: +- def iterkeys(d, **kw): +- return d.iterkeys(**kw) +- +- def itervalues(d, **kw): +- return d.itervalues(**kw) +- +- def iteritems(d, **kw): +- return d.iteritems(**kw) +- +- def iterlists(d, **kw): +- return d.iterlists(**kw) +- +- viewkeys = operator.methodcaller("viewkeys") +- +- viewvalues = operator.methodcaller("viewvalues") +- +- viewitems = operator.methodcaller("viewitems") +- +-_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") +-_add_doc(itervalues, "Return an iterator over the values of a dictionary.") +-_add_doc(iteritems, +- "Return an iterator over the (key, value) pairs of a dictionary.") +-_add_doc(iterlists, +- "Return an iterator over the (key, [values]) pairs of a dictionary.") +- +- +-if PY3: +- def b(s): +- return s.encode("latin-1") +- +- def u(s): +- return s +- unichr = chr +- import struct +- int2byte = struct.Struct(">B").pack +- del struct +- byte2int = operator.itemgetter(0) +- indexbytes = operator.getitem +- iterbytes = iter +- import io +- StringIO = io.StringIO +- BytesIO = io.BytesIO +- _assertCountEqual = "assertCountEqual" +- if sys.version_info[1] <= 1: +- _assertRaisesRegex = "assertRaisesRegexp" +- _assertRegex = "assertRegexpMatches" +- else: +- _assertRaisesRegex = "assertRaisesRegex" +- _assertRegex = "assertRegex" +-else: +- def b(s): +- return s +- # Workaround for standalone backslash +- +- def u(s): +- return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") +- unichr = unichr +- int2byte = chr +- +- def byte2int(bs): +- return ord(bs[0]) +- +- def indexbytes(buf, i): +- return ord(buf[i]) +- iterbytes = functools.partial(itertools.imap, ord) +- import StringIO +- StringIO = BytesIO = StringIO.StringIO +- _assertCountEqual = "assertItemsEqual" +- _assertRaisesRegex = "assertRaisesRegexp" +- _assertRegex = "assertRegexpMatches" +-_add_doc(b, """Byte literal""") +-_add_doc(u, """Text literal""") +- +- +-def assertCountEqual(self, *args, **kwargs): +- return getattr(self, _assertCountEqual)(*args, **kwargs) +- +- +-def assertRaisesRegex(self, *args, **kwargs): +- return getattr(self, _assertRaisesRegex)(*args, **kwargs) +- +- +-def assertRegex(self, *args, **kwargs): +- return getattr(self, _assertRegex)(*args, **kwargs) +- +- +-if PY3: +- exec_ = getattr(moves.builtins, "exec") +- +- def reraise(tp, value, tb=None): +- try: +- if value is None: +- value = tp() +- if value.__traceback__ is not tb: +- raise value.with_traceback(tb) +- raise value +- finally: +- value = None +- tb = None +- +-else: +- def exec_(_code_, _globs_=None, _locs_=None): +- """Execute code in a namespace.""" +- if _globs_ is None: +- frame = sys._getframe(1) +- _globs_ = frame.f_globals +- if _locs_ is None: +- _locs_ = frame.f_locals +- del frame +- elif _locs_ is None: +- _locs_ = _globs_ +- exec("""exec _code_ in _globs_, _locs_""") +- +- exec_("""def reraise(tp, value, tb=None): +- try: +- raise tp, value, tb +- finally: +- tb = None +-""") +- +- +-if sys.version_info[:2] == (3, 2): +- exec_("""def raise_from(value, from_value): +- try: +- if from_value is None: +- raise value +- raise value from from_value +- finally: +- value = None +-""") +-elif sys.version_info[:2] > (3, 2): +- exec_("""def raise_from(value, from_value): +- try: +- raise value from from_value +- finally: +- value = None +-""") +-else: +- def raise_from(value, from_value): +- raise value +- +- +-print_ = getattr(moves.builtins, "print", None) +-if print_ is None: +- def print_(*args, **kwargs): +- """The new-style print function for Python 2.4 and 2.5.""" +- fp = kwargs.pop("file", sys.stdout) +- if fp is None: +- return +- +- def write(data): +- if not isinstance(data, basestring): +- data = str(data) +- # If the file has an encoding, encode unicode with it. +- if (isinstance(fp, file) and +- isinstance(data, unicode) and +- fp.encoding is not None): +- errors = getattr(fp, "errors", None) +- if errors is None: +- errors = "strict" +- data = data.encode(fp.encoding, errors) +- fp.write(data) +- want_unicode = False +- sep = kwargs.pop("sep", None) +- if sep is not None: +- if isinstance(sep, unicode): +- want_unicode = True +- elif not isinstance(sep, str): +- raise TypeError("sep must be None or a string") +- end = kwargs.pop("end", None) +- if end is not None: +- if isinstance(end, unicode): +- want_unicode = True +- elif not isinstance(end, str): +- raise TypeError("end must be None or a string") +- if kwargs: +- raise TypeError("invalid keyword arguments to print()") +- if not want_unicode: +- for arg in args: +- if isinstance(arg, unicode): +- want_unicode = True +- break +- if want_unicode: +- newline = unicode("\n") +- space = unicode(" ") +- else: +- newline = "\n" +- space = " " +- if sep is None: +- sep = space +- if end is None: +- end = newline +- for i, arg in enumerate(args): +- if i: +- write(sep) +- write(arg) +- write(end) +-if sys.version_info[:2] < (3, 3): +- _print = print_ +- +- def print_(*args, **kwargs): +- fp = kwargs.get("file", sys.stdout) +- flush = kwargs.pop("flush", False) +- _print(*args, **kwargs) +- if flush and fp is not None: +- fp.flush() +- +-_add_doc(reraise, """Reraise an exception.""") +- +-if sys.version_info[0:2] < (3, 4): +- def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, +- updated=functools.WRAPPER_UPDATES): +- def wrapper(f): +- f = functools.wraps(wrapped, assigned, updated)(f) +- f.__wrapped__ = wrapped +- return f +- return wrapper +-else: +- wraps = functools.wraps +- +- +-def with_metaclass(meta, *bases): +- """Create a base class with a metaclass.""" +- # This requires a bit of explanation: the basic idea is to make a dummy +- # metaclass for one level of class instantiation that replaces itself with +- # the actual metaclass. +- class metaclass(type): +- +- def __new__(cls, name, this_bases, d): +- return meta(name, bases, d) +- +- @classmethod +- def __prepare__(cls, name, this_bases): +- return meta.__prepare__(name, bases) +- return type.__new__(metaclass, 'temporary_class', (), {}) +- +- +-def add_metaclass(metaclass): +- """Class decorator for creating a class with a metaclass.""" +- def wrapper(cls): +- orig_vars = cls.__dict__.copy() +- slots = orig_vars.get('__slots__') +- if slots is not None: +- if isinstance(slots, str): +- slots = [slots] +- for slots_var in slots: +- orig_vars.pop(slots_var) +- orig_vars.pop('__dict__', None) +- orig_vars.pop('__weakref__', None) +- if hasattr(cls, '__qualname__'): +- orig_vars['__qualname__'] = cls.__qualname__ +- return metaclass(cls.__name__, cls.__bases__, orig_vars) +- return wrapper +- +- +-def ensure_binary(s, encoding='utf-8', errors='strict'): +- """Coerce **s** to six.binary_type. +- +- For Python 2: +- - `unicode` -> encoded to `str` +- - `str` -> `str` +- +- For Python 3: +- - `str` -> encoded to `bytes` +- - `bytes` -> `bytes` +- """ +- if isinstance(s, text_type): +- return s.encode(encoding, errors) +- elif isinstance(s, binary_type): +- return s +- else: +- raise TypeError("not expecting type '%s'" % type(s)) +- +- +-def ensure_str(s, encoding='utf-8', errors='strict'): +- """Coerce *s* to `str`. +- +- For Python 2: +- - `unicode` -> encoded to `str` +- - `str` -> `str` +- +- For Python 3: +- - `str` -> `str` +- - `bytes` -> decoded to `str` +- """ +- if not isinstance(s, (text_type, binary_type)): +- raise TypeError("not expecting type '%s'" % type(s)) +- if PY2 and isinstance(s, text_type): +- s = s.encode(encoding, errors) +- elif PY3 and isinstance(s, binary_type): +- s = s.decode(encoding, errors) +- return s +- +- +-def ensure_text(s, encoding='utf-8', errors='strict'): +- """Coerce *s* to six.text_type. +- +- For Python 2: +- - `unicode` -> `unicode` +- - `str` -> `unicode` +- +- For Python 3: +- - `str` -> `str` +- - `bytes` -> decoded to `str` +- """ +- if isinstance(s, binary_type): +- return s.decode(encoding, errors) +- elif isinstance(s, text_type): +- return s +- else: +- raise TypeError("not expecting type '%s'" % type(s)) +- +- +- +-def python_2_unicode_compatible(klass): +- """ +- A decorator that defines __unicode__ and __str__ methods under Python 2. +- Under Python 3 it does nothing. +- +- To support Python 2 and 3 with a single code base, define a __str__ method +- returning text and apply this decorator to the class. +- """ +- if PY2: +- if '__str__' not in klass.__dict__: +- raise ValueError("@python_2_unicode_compatible cannot be applied " +- "to %s because it doesn't define __str__()." % +- klass.__name__) +- klass.__unicode__ = klass.__str__ +- klass.__str__ = lambda self: self.__unicode__().encode('utf-8') +- return klass +- +- +-# Complete the moves implementation. +-# This code is at the end of this module to speed up module loading. +-# Turn this module into a package. +-__path__ = [] # required for PEP 302 and PEP 451 +-__package__ = __name__ # see PEP 366 @ReservedAssignment +-if globals().get("__spec__") is not None: +- __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable +-# Remove other six meta path importers, since they cause problems. This can +-# happen if six is removed from sys.modules and then reloaded. (Setuptools does +-# this for some reason.) +-if sys.meta_path: +- for i, importer in enumerate(sys.meta_path): +- # Here's some real nastiness: Another "instance" of the six module might +- # be floating around. Therefore, we can't use isinstance() to check for +- # the six meta path importer, since the other six instance will have +- # inserted an importer with different class. +- if (type(importer).__name__ == "_SixMetaPathImporter" and +- importer.name == __name__): +- del sys.meta_path[i] +- break +- del i, importer +-# Finally, add the importer to the meta path import hook. +-sys.meta_path.append(_importer) +Index: wxPython-4.2.1/buildtools/build_wxwidgets.py +=================================================================== +--- wxPython-4.2.1.orig/buildtools/build_wxwidgets.py ++++ wxPython-4.2.1/buildtools/build_wxwidgets.py +@@ -18,8 +18,6 @@ import subprocess + from buildtools import builder + from buildtools.config import getVisCVersion + +-PY3 = sys.version_info[0] == 3 +- + # builder object + wxBuilder = None + +@@ -421,8 +419,7 @@ def main(wxDir, args): + setupFile = os.path.join(mswIncludeDir, "setup.h") + with open(setupFile, "rb") as f: + setupText = f.read() +- if PY3: +- setupText = setupText.decode('utf-8') ++ setupText = setupText.decode('utf-8') + + for flag in flags: + setupText, subsMade = re.subn(flag + "\s+?\d", "%s %s" % (flag, flags[flag]), setupText) +@@ -431,8 +428,7 @@ def main(wxDir, args): + sys.exit(1) + + with open(setupFile, "wb") as f: +- if PY3: +- setupText = setupText.encode('utf-8') ++ setupText = setupText.encode('utf-8') + f.write(setupText) + + args = [] +Index: wxPython-4.2.1/buildtools/config.py +=================================================================== +--- wxPython-4.2.1.orig/buildtools/config.py ++++ wxPython-4.2.1/buildtools/config.py +@@ -482,18 +482,8 @@ class Configuration(object): + + def build_locale_list(self, srcdir): + # get a list of all files under the srcdir, to be used for install_data +- if sys.version_info[0] == 2: +- def walk_helper(lst, dirname, files): +- for f in files: +- filename = opj(dirname, f) +- if not os.path.isdir(filename): +- lst.append( (dirname, [filename]) ) +- file_list = [] +- os.path.walk(srcdir, walk_helper, file_list) +- return file_list +- else: +- # TODO: Python3 version using os.walk generator +- return [] ++ # TODO: Python3 version using os.walk generator ++ return [] + + + def find_data_files(self, srcdir, *wildcards, **kw): +@@ -897,8 +887,7 @@ def runcmd(cmd, getOutput=False, echoCmd + if getOutput: + outputEncoding = 'cp1252' if sys.platform == 'win32' else 'utf-8' + output = sp.stdout.read() +- if sys.version_info > (3,): +- output = output.decode(outputEncoding) ++ output = output.decode(outputEncoding) + output = output.rstrip() + + rval = sp.wait() +@@ -917,11 +906,8 @@ def runcmd(cmd, getOutput=False, echoCmd + + + def myExecfile(filename, ns): +- if sys.version_info < (3,): +- execfile(filename, ns) +- else: +- with open(filename, 'r') as f: +- exec(f.read(), ns) ++ with open(filename, 'r') as f: ++ exec(f.read(), ns) + + + def textfile_open(filename, mode='rt'): +@@ -931,12 +917,7 @@ def textfile_open(filename, mode='rt'): + mode parameter must include the 't' to put the stream into text mode. + """ + assert 't' in mode +- if sys.version_info < (3,): +- import codecs +- mode = mode.replace('t', '') +- return codecs.open(filename, mode, encoding='utf-8') +- else: +- return open(filename, mode, encoding='utf-8') ++ return open(filename, mode, encoding='utf-8') + + + def getSipFiles(names): +Index: wxPython-4.2.1/buildtools/distutils_hacks.py +=================================================================== +--- wxPython-4.2.1.orig/buildtools/distutils_hacks.py ++++ wxPython-4.2.1/buildtools/distutils_hacks.py +@@ -311,7 +311,7 @@ distutils.cygwinccompiler.CygwinCCompile + # into the .pyd files as expected. So we'll strip out that option via + # a monkey-patch of the msvc9compiler.MSVCCompiler.initialize method. + +-if os.name == 'nt' and sys.version_info >= (2,6): ++if os.name == 'nt': + import distutils.msvc9compiler + _orig_initialize = distutils.msvc9compiler.MSVCCompiler.initialize + +Index: wxPython-4.2.1/demo/AUI_DockingWindowMgr.py +=================================================================== +--- wxPython-4.2.1.orig/demo/AUI_DockingWindowMgr.py ++++ wxPython-4.2.1/demo/AUI_DockingWindowMgr.py +@@ -5,7 +5,7 @@ import wx.grid + import wx.html + import wx.aui as aui + +-from six import BytesIO ++from io import BytesIO + + ID_CreateTree = wx.NewIdRef() + ID_CreateGrid = wx.NewIdRef() +Index: wxPython-4.2.1/demo/ArtProvider.py +=================================================================== +--- wxPython-4.2.1.orig/demo/ArtProvider.py ++++ wxPython-4.2.1/demo/ArtProvider.py +@@ -1,7 +1,7 @@ + #!/usr/bin/env python + # Tags: phoenix-port, py3-port + +-from six import BytesIO ++from io import BytesIO + + import wx + +Index: wxPython-4.2.1/demo/ImageFromStream.py +=================================================================== +--- wxPython-4.2.1.orig/demo/ImageFromStream.py ++++ wxPython-4.2.1/demo/ImageFromStream.py +@@ -1,7 +1,7 @@ + #!/usr/bin/env python + # Tags: phoenix-port, py3-port + +-from six import BytesIO ++from io import BytesIO + + import wx + +Index: wxPython-4.2.1/demo/KeyEvents.py +=================================================================== +--- wxPython-4.2.1.orig/demo/KeyEvents.py ++++ wxPython-4.2.1/demo/KeyEvents.py +@@ -2,7 +2,6 @@ + + import wx + import wx.lib.mixins.listctrl as listmix +-from six import unichr + + #---------------------------------------------------------------------- + +@@ -265,15 +264,15 @@ class KeyLog(wx.ListCtrl, listmix.ListCt + if keycode == 0: + keyname = "NUL" + elif keycode < 27: +- keyname = u"Ctrl-%s" % unichr(ord('A') + keycode-1) ++ keyname = u"Ctrl-%s" % chr(ord('A') + keycode-1) + else: +- keyname = u"\"%s\"" % unichr(keycode) ++ keyname = u"\"%s\"" % chr(keycode) + else: + keyname = u"(%s)" % keycode + + UniChr = '' + if "unicode" in wx.PlatformInfo: +- UniChr = "\"" + unichr(evt.GetUnicodeKey()) + "\"" ++ UniChr = "\"" + chr(evt.GetUnicodeKey()) + "\"" + + modifiers = "" + for mod, ch in [(evt.ControlDown(), 'C'), +Index: wxPython-4.2.1/demo/Main.py +=================================================================== +--- wxPython-4.2.1.orig/demo/Main.py ++++ wxPython-4.2.1/demo/Main.py +@@ -52,8 +52,12 @@ + # Last updated: Andrea Gavana, 20 Oct 2008, 18.00 GMT + + import sys, os, time, traceback ++import pickle + import re + import shutil ++import urllib.error ++import urllib.request ++from io import BytesIO + from threading import Thread + + from distutils.version import LooseVersion +@@ -67,10 +71,6 @@ from wx.adv import TaskBarIcon as TaskBa + from wx.adv import SplashScreen as SplashScreen + import wx.lib.mixins.inspection + +-import six +-from six import exec_, BytesIO +-from six.moves import cPickle +-from six.moves import urllib + + import version + +@@ -418,10 +418,7 @@ class InternetThread(Thread): + try: + url = _docsURL % ReplaceCapitals(self.selectedClass) + with urllib.request.urlopen(url) as fid: +- if six.PY2: +- originalText = fid.read() +- else: +- originalText = fid.read().decode("utf-8") ++ originalText = fid.read().decode("utf-8") + + text = RemoveHTMLTags(originalText).split("\n") + data = FindWindowStyles(text, originalText, self.selectedClass) +@@ -963,9 +960,6 @@ def SearchDemo(name, keyword): + with open(GetOriginalFilename(name), "rt") as fid: + fullText = fid.read() + +- if six.PY2: +- fullText = fullText.decode("iso-8859-1") +- + if fullText.find(keyword) >= 0: + return True + +@@ -1076,10 +1070,9 @@ class DemoModules(object): + self.modules = [[dict(), "" , "" , "" , None], + [dict(), "" , "" , "" , None]] + +- getcwd = os.getcwd if six.PY3 else os.getcwdu + for i in [modOriginal, modModified]: + self.modules[i][0]['__file__'] = \ +- os.path.join(getcwd(), GetOriginalFilename(name)) ++ os.path.join(os.getcwd(), GetOriginalFilename(name)) + + # load original module + self.LoadFromFile(modOriginal, GetOriginalFilename(name)) +@@ -1103,12 +1096,10 @@ class DemoModules(object): + if self.name != __name__: + source = self.modules[modID][1] + description = self.modules[modID][2] +- if six.PY2: +- description = description.encode(sys.getfilesystemencoding()) + + try: + code = compile(source, description, "exec") +- exec_(code, self.modules[modID][0]) ++ exec(code, self.modules[modID][0]) + except: + self.modules[modID][4] = DemoError(sys.exc_info()) + self.modules[modID][0] = None +@@ -1647,7 +1638,7 @@ class wxPythonDemo(wx.Frame): + + with open(pickledFile, "rb") as fid: + try: +- self.pickledData = cPickle.load(fid) ++ self.pickledData = pickle.load(fid) + except: + self.pickledData = {} + +@@ -1688,7 +1679,7 @@ class wxPythonDemo(wx.Frame): + item.Check(self.allowDocs) + self.Bind(wx.EVT_MENU, self.OnAllowDownload, item) + +- item = wx.MenuItem(menu, -1, 'Delete saved docs', 'Deletes the cPickle file where docs are stored') ++ item = wx.MenuItem(menu, -1, 'Delete saved docs', 'Deletes the pickle file where docs are stored') + item.SetBitmap(images.catalog['deletedocs'].GetBitmap()) + menu.Append(item) + self.Bind(wx.EVT_MENU, self.OnDeleteDocs, item) +@@ -2229,10 +2220,6 @@ class wxPythonDemo(wx.Frame): + + self.pickledData[itemText] = data + +- if six.PY2: +- # TODO: verify that this encoding is correct +- text = text.decode('iso8859_1') +- + self.StopDownload() + self.ovr.SetPage(text) + #print("load time: ", time.time() - start) +@@ -2501,7 +2488,7 @@ class wxPythonDemo(wx.Frame): + MakeDocDirs() + pickledFile = GetDocFile() + with open(pickledFile, "wb") as fid: +- cPickle.dump(self.pickledData, fid, cPickle.HIGHEST_PROTOCOL) ++ pickle.dump(self.pickledData, fid, pickle.HIGHEST_PROTOCOL) + + self.Destroy() + +Index: wxPython-4.2.1/demo/MimeTypesManager.py +=================================================================== +--- wxPython-4.2.1.orig/demo/MimeTypesManager.py ++++ wxPython-4.2.1/demo/MimeTypesManager.py +@@ -18,8 +18,7 @@ import images + + # helper function to make sure we don't convert unicode objects to strings + # or vice versa when converting lists and None values to text. +-import six +-convert = six.text_type ++convert = str + + #---------------------------------------------------------------------------- + +Index: wxPython-4.2.1/demo/PropertyGrid.py +=================================================================== +--- wxPython-4.2.1.orig/demo/PropertyGrid.py ++++ wxPython-4.2.1/demo/PropertyGrid.py +@@ -9,7 +9,6 @@ import wx + import wx.adv + import wx.propgrid as wxpg + +-from six import exec_ + _ = wx.GetTranslation + + +@@ -870,7 +869,7 @@ class TestPanel( wx.Panel ): + sandbox = {'obj':ValueObject(), + 'wx':wx, + 'datetime':datetime} +- exec_(dlg.tc.GetValue(), sandbox) ++ exec(dlg.tc.GetValue(), sandbox) + t_start = time.time() + #print(sandbox['obj'].__dict__) + self.pg.SetPropertyValues(sandbox['obj']) +@@ -917,7 +916,7 @@ class TestPanel( wx.Panel ): + with MemoDialog(self,"Enter Content for Object Used for AutoFill",default_object_content1) as dlg: + if dlg.ShowModal() == wx.ID_OK: + sandbox = {'object':ValueObject(),'wx':wx} +- exec_(dlg.tc.GetValue(), sandbox) ++ exec(dlg.tc.GetValue(), sandbox) + t_start = time.time() + self.pg.AutoFill(sandbox['object']) + t_end = time.time() +Index: wxPython-4.2.1/demo/RichTextCtrl.py +=================================================================== +--- wxPython-4.2.1.orig/demo/RichTextCtrl.py ++++ wxPython-4.2.1/demo/RichTextCtrl.py +@@ -1,6 +1,6 @@ + #!/usr/bin/env python + +-from six import BytesIO ++from io import BytesIO + + import wx + import wx.richtext as rt +Index: wxPython-4.2.1/demo/SVGImage_Bitmap.py +=================================================================== +--- wxPython-4.2.1.orig/demo/SVGImage_Bitmap.py ++++ wxPython-4.2.1/demo/SVGImage_Bitmap.py +@@ -2,7 +2,6 @@ + import sys + import os + import glob +-import six + + import wx + from wx.svg import SVGimage +@@ -26,8 +25,6 @@ class SVGBitmapDisplay(wx.Panel): + + + def UpdateSVG(self, svg_filename): +- if six.PY2 and isinstance(svg_filename, unicode): +- svg_filename = svg_filename.encode(sys.getfilesystemencoding()) + img = SVGimage.CreateFromFile(svg_filename) + bmp = img.ConvertToScaledBitmap(self.bmp_size, self) + self.statbmp.SetBitmap(bmp) +Index: wxPython-4.2.1/demo/SVGImage_Render.py +=================================================================== +--- wxPython-4.2.1.orig/demo/SVGImage_Render.py ++++ wxPython-4.2.1/demo/SVGImage_Render.py +@@ -2,7 +2,6 @@ + import sys + import os + import glob +-import six + + import wx + from wx.svg import SVGimage +@@ -26,8 +25,6 @@ class SVGRenderPanel(wx.Panel): + + + def SetSVGFile(self, svg_filename): +- if six.PY2 and isinstance(svg_filename, unicode): +- svg_filename = svg_filename.encode(sys.getfilesystemencoding()) + self._img = SVGimage.CreateFromFile(svg_filename) + self.Refresh() + +Index: wxPython-4.2.1/demo/Threads.py +=================================================================== +--- wxPython-4.2.1.orig/demo/Threads.py ++++ wxPython-4.2.1/demo/Threads.py +@@ -1,6 +1,6 @@ + import random + import time +-from six.moves import _thread ++import _thread + + import wx + import wx.lib.newevent +Index: wxPython-4.2.1/demo/agw/FoldPanelBar.py +=================================================================== +--- wxPython-4.2.1.orig/demo/agw/FoldPanelBar.py ++++ wxPython-4.2.1/demo/agw/FoldPanelBar.py +@@ -5,8 +5,7 @@ import wx + import wx.adv + import os + import sys +- +-from six import BytesIO ++from io import BytesIO + + try: + dirName = os.path.dirname(os.path.abspath(__file__)) +Index: wxPython-4.2.1/demo/agw/HyperTreeList.py +=================================================================== +--- wxPython-4.2.1.orig/demo/agw/HyperTreeList.py ++++ wxPython-4.2.1/demo/agw/HyperTreeList.py +@@ -4,15 +4,13 @@ + import os + import string + import random ++import sys ++from io import BytesIO + + import wx + import wx.lib.colourselect as csel + import wx.lib.colourutils as cutils + +-import sys +- +-from six import BytesIO +- + try: + dirName = os.path.dirname(os.path.abspath(__file__)) + except: +Index: wxPython-4.2.1/demo/agw/Windows7Explorer_Contents.py +=================================================================== +--- wxPython-4.2.1.orig/demo/agw/Windows7Explorer_Contents.py ++++ wxPython-4.2.1/demo/agw/Windows7Explorer_Contents.py +@@ -3,7 +3,6 @@ + import sys + import os + import wx +-import six + import time + import datetime + import operator +@@ -27,12 +26,7 @@ except ImportError: # if it's not there + bitmapDir = os.path.join(dirName, 'bitmaps') + sys.path.append(os.path.split(dirName)[0]) + +-# helper function to make sure we don't convert unicode objects to strings +-# or vice versa when converting lists and None values to text. + convert = str +-if six.PY2: +- if 'unicode' in wx.PlatformInfo: +- convert = unicode + + + def FormatFileSize(size): +Index: wxPython-4.2.1/etg/config.py +=================================================================== +--- wxPython-4.2.1.orig/etg/config.py ++++ wxPython-4.2.1/etg/config.py +@@ -62,10 +62,7 @@ def run(): + return rv; + """) + c.addPyMethod('ReadInt', '(self, key, defaultVal=0)', body="""\ +- import six + rv = self._cpp_ReadInt(key, defaultVal) +- if six.PY2: +- rv = int(rv) + return rv + """) + +Index: wxPython-4.2.1/etg/listctrl.py +=================================================================== +--- wxPython-4.2.1.orig/etg/listctrl.py ++++ wxPython-4.2.1/etg/listctrl.py +@@ -316,10 +316,9 @@ def run(): + sequence with an item for each column''', + body="""\ + if len(entry): +- from six import text_type +- pos = self.InsertItem(self.GetItemCount(), text_type(entry[0])) ++ pos = self.InsertItem(self.GetItemCount(), str(entry[0])) + for i in range(1, len(entry)): +- self.SetItem(pos, i, text_type(entry[i])) ++ self.SetItem(pos, i, str(entry[i])) + return pos + """) + +Index: wxPython-4.2.1/etg/rawbmp.py +=================================================================== +--- wxPython-4.2.1.orig/etg/rawbmp.py ++++ wxPython-4.2.1/etg/rawbmp.py +@@ -122,13 +122,10 @@ def addPixelDataBaseClass(module): + X = property(lambda self: x) + Y = property(lambda self: y) + +- import sys +- rangeFunc = range if sys.version_info >= (3,) else xrange +- + pf = PixelFacade() +- for y in rangeFunc(height): ++ for y in range(height): + pixels.MoveTo(self, 0, y) +- for x in rangeFunc(width): ++ for x in range(width): + # We always generate the same pf instance, but it + # accesses the pixels object which we use to iterate + # over the pixel buffer. +Index: wxPython-4.2.1/etg/wxdatetime.py +=================================================================== +--- wxPython-4.2.1.orig/etg/wxdatetime.py ++++ wxPython-4.2.1/etg/wxdatetime.py +@@ -254,20 +254,16 @@ def run(): + + + c.addPyMethod('__repr__', '(self)', """\ +- from six import PY2 + if self.IsValid(): + f = self.Format() +- if PY2: f = f.encode('utf-8') + return '' % f + else: + return '' + """) + + c.addPyMethod('__str__', '(self)', """\ +- from six import PY2 + if self.IsValid(): + f = self.Format() +- if PY2: f = f.encode('utf-8') + return f + else: + return "INVALID DateTime" +Index: wxPython-4.2.1/etgtools/extractors.py +=================================================================== +--- wxPython-4.2.1.orig/etgtools/extractors.py ++++ wxPython-4.2.1/etgtools/extractors.py +@@ -28,7 +28,7 @@ from sphinxtools.utilities import findDe + # methods, functions and other items in the C/C++ API being wrapped. + #--------------------------------------------------------------------------- + +-class BaseDef(object): ++class BaseDef: + """ + The base class for all element types and provides the common attributes + and functions that they all share. +@@ -1673,11 +1673,7 @@ def flattenNode(node, rstrip=True): + # TODO: can we just use ElementTree.tostring for this function? + if node is None: + return "" +- if sys.version_info < (3,): +- strclass = basestring +- else: +- strclass = str +- if isinstance(node, strclass): ++ if isinstance(node, str): + return node + text = node.text or "" + for n in node: +Index: wxPython-4.2.1/etgtools/generators.py +=================================================================== +--- wxPython-4.2.1.orig/etgtools/generators.py ++++ wxPython-4.2.1/etgtools/generators.py +@@ -97,13 +97,7 @@ def wrapText(text): + # in the StringIO + import io + class Utf8EncodingStream(io.StringIO): +- if sys.version_info < (3,): +- def write(self, text): +- if isinstance(text, str): +- text = text.decode('utf-8') +- return io.StringIO.write(self, text) +- +- ++ pass + + + def textfile_open(filename, mode='rt'): +@@ -113,12 +107,7 @@ def textfile_open(filename, mode='rt'): + mode parameter must include the 't' to put the stream into text mode. + """ + assert 't' in mode +- if sys.version_info < (3,): +- import codecs +- mode = mode.replace('t', '') +- return codecs.open(filename, mode, encoding='utf-8') +- else: +- return open(filename, mode, encoding='utf-8') ++ return open(filename, mode, encoding='utf-8') + + + #--------------------------------------------------------------------------- +Index: wxPython-4.2.1/etgtools/sphinx_generator.py +=================================================================== +--- wxPython-4.2.1.orig/etgtools/sphinx_generator.py ++++ wxPython-4.2.1/etgtools/sphinx_generator.py +@@ -20,12 +20,7 @@ import sys + import shutil + import textwrap + +-if sys.version_info < (3, ): +- from StringIO import StringIO +- string_base = basestring +-else: +- from io import StringIO +- string_base = str ++from io import StringIO + + import xml.etree.ElementTree as et + +@@ -146,7 +141,7 @@ class Node(object): + :returns: The element text for the input `tag_name` or ``None``. + """ + +- if isinstance(self.element, string_base): ++ if isinstance(self.element, str): + return None + + return self.element.get(tag_name) +@@ -268,7 +263,7 @@ class Node(object): + if self.element is None: + return text + +- if isinstance(self.element, string_base): ++ if isinstance(self.element, str): + text = self.element + else: + text, tail = self.element.text, self.element.tail +@@ -1381,7 +1376,7 @@ class Snippet(Node): + if tag == 'sp': + self.snippet += ' ' + +- if isinstance(element, string_base): ++ if isinstance(element, str): + self.snippet += element + else: + if element.text: +@@ -2006,7 +2001,7 @@ class XMLDocString(object): + # Some of the Extractors (xml item) will set deprecated themselves, in which case it is set as a + # non-empty string. In such cases, this branch will insert a deprecated section into the xml tree + # so that the Node Tree (see classes above) will generate the deprecated tag on their own in self.RecurseXML +- if hasattr(xml_item, 'deprecated') and xml_item.deprecated and isinstance(xml_item.deprecated, string_base): ++ if hasattr(xml_item, 'deprecated') and xml_item.deprecated and isinstance(xml_item.deprecated, str): + element = et.Element('deprecated', kind='deprecated') + element.text = xml_item.deprecated + +@@ -2128,7 +2123,7 @@ class XMLDocString(object): + if element is None: + return Node('', parent) + +- if isinstance(element, string_base): ++ if isinstance(element, str): + rest_class = Paragraph(element, parent, self.kind) + return rest_class + +@@ -2754,7 +2749,7 @@ class XMLDocString(object): + name = convertToPython(name) + stream.write('%-80s' % name) + +- if not isinstance(docstrings, string_base): ++ if not isinstance(docstrings, str): + rest_class = self.RecurseXML(docstrings, self.root) + docstrings = rest_class.Join() + +@@ -3394,7 +3389,7 @@ class SphinxGenerator(generators.DocsGen + + brief = memberVar.briefDoc + briefDoc = None +- if not isinstance(brief, string_base): ++ if not isinstance(brief, str): + docstring = XMLDocString(memberVar) + #docstring.current_module = self.current_module + briefDoc = docstring.GetBrief() +@@ -3541,7 +3536,7 @@ class SphinxGenerator(generators.DocsGen + simple_docs = convertToPython(method.pyDocstring) + else: + brief = method.briefDoc +- if not isinstance(brief, string_base): ++ if not isinstance(brief, str): + docstring = XMLDocString(method) + docstring.kind = 'method' + docstring.current_module = self.current_module +Index: wxPython-4.2.1/etgtools/tweaker_tools.py +=================================================================== +--- wxPython-4.2.1.orig/etgtools/tweaker_tools.py ++++ wxPython-4.2.1/etgtools/tweaker_tools.py +@@ -19,8 +19,6 @@ import copy + import textwrap + + +-PY3 = sys.version_info[0] == 3 +- + magicMethods = { + 'operator!=' : '__ne__', + 'operator==' : '__eq__', +@@ -123,12 +121,8 @@ class FixWxPrefix(object): + + names = list() + filename = 'wx/core.pyi' +- if PY3: +- with open(filename, 'rt', encoding='utf-8') as f: +- text = f.read() +- else: +- with open(filename, 'r') as f: +- text = f.read() ++ with open(filename, 'rt', encoding='utf-8') as f: ++ text = f.read() + parseTree = ast.parse(text, filename) + for item in parseTree.body: + _processItem(item, names) +Index: wxPython-4.2.1/samples/doodle/superdoodle.py +=================================================================== +--- wxPython-4.2.1.orig/samples/doodle/superdoodle.py ++++ wxPython-4.2.1/samples/doodle/superdoodle.py +@@ -11,8 +11,7 @@ implemented using an wx.html.HtmlWindow. + + import sys + import os +- +-from six.moves import cPickle as pickle ++import pickle + + import wx + import wx.html +Index: wxPython-4.2.1/samples/floatcanvas/DrawBot.py +=================================================================== +--- wxPython-4.2.1.orig/samples/floatcanvas/DrawBot.py ++++ wxPython-4.2.1/samples/floatcanvas/DrawBot.py +@@ -14,7 +14,6 @@ I think it's easier with FloatCavnas, an + """ + + import wx +-from six import moves + from math import * + + try: # see if there is a local FloatCanvas to use +@@ -54,7 +53,7 @@ class DrawFrame(wx.Frame): + Canvas = self.Canvas + phi = (sqrt(5) + 1)/2 - 1 + oradius = 10.0 +- for i in moves.xrange(720): ++ for i in range(720): + radius = 1.5 * oradius * sin(i * pi/720) + Color = (255*(i / 720.), 255*( i / 720.), 255 * 0.25) + x = oradius + 0.25*i*cos(phi*i*2*pi) +Index: wxPython-4.2.1/samples/html2/webview_sample.py +=================================================================== +--- wxPython-4.2.1.orig/samples/html2/webview_sample.py ++++ wxPython-4.2.1/samples/html2/webview_sample.py +@@ -1,6 +1,6 @@ + import sys + import os +-from six import BytesIO ++from io import BytesIO + + import wx + import wx.html2 as webview +Index: wxPython-4.2.1/samples/printing/printing.py +=================================================================== +--- wxPython-4.2.1.orig/samples/printing/printing.py ++++ wxPython-4.2.1/samples/printing/printing.py +@@ -1,5 +1,4 @@ + import wx +-from six import print_ + import os + + FONTSIZE = 10 +@@ -180,7 +179,7 @@ class PrintFrameworkSample(wx.Frame): + data = dlg.GetPageSetupData() + self.pdata = wx.PrintData(data.GetPrintData()) # force a copy + self.pdata.SetPaperId(data.GetPaperId()) +- #print_("paperID %r, paperSize %r" % (self.pdata.GetPaperId(), self.pdata.GetPaperSize())) ++ #print("paperID %r, paperSize %r" % (self.pdata.GetPaperId(), self.pdata.GetPaperSize())) + self.margins = (data.GetMarginTopLeft(), + data.GetMarginBottomRight()) + dlg.Destroy() +@@ -226,20 +225,20 @@ class PrintFrameworkSample(wx.Frame): + dlg = wx.PrintDialog(self, data) + if dlg.ShowModal() == wx.ID_OK: + data = dlg.GetPrintDialogData() +- print_() +- print_("GetFromPage:", data.GetFromPage()) +- print_("GetToPage:", data.GetToPage()) +- print_("GetMinPage:", data.GetMinPage()) +- print_("GetMaxPage:", data.GetMaxPage()) +- print_("GetNoCopies:", data.GetNoCopies()) +- print_("GetAllPages:", data.GetAllPages()) +- print_("GetSelection:", data.GetSelection()) +- print_("GetCollate:", data.GetCollate()) +- print_("GetPrintToFile:", data.GetPrintToFile()) ++ print() ++ print("GetFromPage:", data.GetFromPage()) ++ print("GetToPage:", data.GetToPage()) ++ print("GetMinPage:", data.GetMinPage()) ++ print("GetMaxPage:", data.GetMaxPage()) ++ print("GetNoCopies:", data.GetNoCopies()) ++ print("GetAllPages:", data.GetAllPages()) ++ print("GetSelection:", data.GetSelection()) ++ print("GetCollate:", data.GetCollate()) ++ print("GetPrintToFile:", data.GetPrintToFile()) + + self.pdata = wx.PrintData(data.GetPrintData()) +- print_() +- print_("GetPrinterName:", self.pdata.GetPrinterName()) ++ print() ++ print("GetPrinterName:", self.pdata.GetPrinterName()) + + dlg.Destroy() + +Index: wxPython-4.2.1/samples/roses/clroses.py +=================================================================== +--- wxPython-4.2.1.orig/samples/roses/clroses.py ++++ wxPython-4.2.1/samples/roses/clroses.py +@@ -37,7 +37,6 @@ + # independence, override defaults, ignore features, etc. + + from math import sin, cos, pi +-from six import print_ + + # Rose class knows about: + # > Generating points and vectors (returning data as a list of points) +@@ -151,7 +150,7 @@ class rose: + # update parameters or stop. + def restart(self): + if self.verbose: +- print_('restart: int_state', self.int_state, 'cmd_state', self.cmd_state) ++ print('restart: int_state', self.int_state, 'cmd_state', self.cmd_state) + try: + tmp = self.sin_table[0] + except: +@@ -192,7 +191,7 @@ class rose: + # before initialization is done. + def repaint(self, delay): + if self.int_state != self.INT_RESIZE: +- # print_('repaint after', delay) ++ # print('repaint after', delay) + self.int_state = self.INT_RESIZE + self.AppCancelTimer() + self.AppAfter(delay, self.clock) +@@ -264,7 +263,7 @@ class rose: + # roses is 0.) + def clock(self): + if self.int_state == self.INT_IDLE: +- # print_('clock called in idle state') ++ # print('clock called in idle state') + delay = 0 + elif self.int_state == self.INT_DRAW: + line, run = self.roselet() +@@ -295,7 +294,7 @@ class rose: + + if delay == 0: + if self.verbose: +- print_('clock: going idle from state', self.int_state) ++ print('clock: going idle from state', self.int_state) + else: + self.AppAfter(delay, self.clock) + +Index: wxPython-4.2.1/samples/roses/wxroses.py +=================================================================== +--- wxPython-4.2.1.orig/samples/roses/wxroses.py ++++ wxPython-4.2.1/samples/roses/wxroses.py +@@ -71,7 +71,6 @@ + import wx + import clroses + import wx.lib.colourselect as cs +-from six import print_ + + # Class SpinPanel creates a control that includes both a StaticText widget + # which holds the the name of a parameter and a SpinCtrl widget which +@@ -109,7 +108,7 @@ class SpinPanel(wx.Panel): + name = self.st.GetLabel() + value = self.sc.GetValue() + if verbose: +- print_('OnSpin', name, '=', value) ++ print('OnSpin', name, '=', value) + self.callback(name, value) # Call MyFrame.OnSpinback to call clroses + + +@@ -372,10 +371,10 @@ class MyFrame(wx.Frame, clroses.rose): + h = max(600, fh) # Change 600 to desired minimum size + w = h + fw - rw + if verbose: +- print_('rose panel size', (rw, rh)) +- print_('side panel size', (sw, sh)) +- print_(' frame size', (fw, fh)) +- print_('Want size', (w,h)) ++ print('rose panel size', (rw, rh)) ++ print('side panel size', (sw, sh)) ++ print(' frame size', (fw, fh)) ++ print('Want size', (w,h)) + self.SetSize((w, h)) + self.SupplyControlValues() # Ask clroses to tell us all the defaults + self.Show() +@@ -386,25 +385,25 @@ class MyFrame(wx.Frame, clroses.rose): + # Go/Stop button + def OnGoStop(self, event): + if verbose: +- print_('OnGoStop') ++ print('OnGoStop') + self.cmd_go_stop() + + # Redraw/Redraw + def OnRedraw(self, event): + if verbose: +- print_('OnRedraw') ++ print('OnRedraw') + self.cmd_redraw() + + # Backward/Reverse + def OnBackward(self, event): + if verbose: +- print_('OnBackward') ++ print('OnBackward') + self.cmd_backward() + + # Forward/Skip + def OnForward(self, event): + if verbose: +- print_('OnForward') ++ print('OnForward') + self.cmd_step() + + +@@ -415,7 +414,7 @@ class MyFrame(wx.Frame, clroses.rose): + + def AppClear(self): + if verbose: +- print_('AppClear: clear screen') ++ print('AppClear: clear screen') + self.rose_panel.Clear() + + def AppCreateLine(self, line): +@@ -467,8 +466,8 @@ class MyFrame(wx.Frame, clroses.rose): + # Method to provide a single callback after some amount of time. + def AppAfter(self, msec, callback): + if self.timer_callback: +- print_('AppAfter: timer_callback already set!') +- # print_('AppAfter:', callback) ++ print('AppAfter: timer_callback already set!') ++ # print('AppAfter:', callback) + self.timer_callback = callback + self.timer.Start(msec, True) + +@@ -476,14 +475,14 @@ class MyFrame(wx.Frame, clroses.rose): + # interest in. + def AppCancelTimer(self): + self.timer.Stop() +- # print_('AppCancelTimer') ++ # print('AppCancelTimer') + self.timer_callback = None + + # When the timer happens, we come here and jump off to clroses internal code. + def OnTimer(self, evt): + callback = self.timer_callback + self.timer_callback = None +- # print_('OnTimer,', callback) ++ # print('OnTimer,', callback) + if callback: + callback() # Often calls AppAfter() and sets the callback + else: +@@ -502,7 +501,7 @@ class MyFrame(wx.Frame, clroses.rose): + # Called when data in spin boxes changes. + def OnSpinback(self, name, value): + if verbose: +- print_('OnSpinback', name, value) ++ print('OnSpinback', name, value) + if name == 'Style': + self.SetStyle(value) + elif name == 'Sincr': +@@ -530,7 +529,7 @@ class MyFrame(wx.Frame, clroses.rose): + elif name == 'Delay': + self.SetWaitDelay(value) + else: +- print_('OnSpinback: Don\'t recognize', name) ++ print('OnSpinback: Don\'t recognize', name) + + verbose = 0 # Need some command line options... + spin_panels = {} # Hooks to get from rose to panel labels +@@ -539,6 +538,6 @@ ctrl_buttons = {} # Button + app = wx.App(False) + MyFrame() + if verbose: +- print_('spin_panels', list(spin_panels)) +- print_('ctrl_buttons', list(ctrl_buttons)) ++ print('spin_panels', list(spin_panels)) ++ print('ctrl_buttons', list(ctrl_buttons)) + app.MainLoop() +Index: wxPython-4.2.1/samples/simple/events.py +=================================================================== +--- wxPython-4.2.1.orig/samples/simple/events.py ++++ wxPython-4.2.1/samples/simple/events.py +@@ -1,9 +1,7 @@ +- + import wx +-from six import print_ + +-print_(wx.version()) +-#import os; print_('PID:', os.getpid()); raw_input('Ready to start, press enter...') ++print(wx.version()) ++#import os; print('PID:', os.getpid()); raw_input('Ready to start, press enter...') + + + class MyFrame(wx.Frame): +@@ -13,21 +11,21 @@ class MyFrame(wx.Frame): + wx.CallAfter(self.after, 1, 2, 3) + + def after(self, a, b, c): +- print_('Called via wx.CallAfter:', a, b, c) ++ print('Called via wx.CallAfter:', a, b, c) + + def onSize(self, evt): +- print_(repr(evt.Size)) ++ print(repr(evt.Size)) + evt.Skip() + + class MyApp(wx.App): + def OnInit(self): +- print_('OnInit') ++ print('OnInit') + frm = MyFrame(None, title="Hello with Events", size=(480,360)) + frm.Show() + return True + + def OnExit(self): +- print_('OnExit') ++ print('OnExit') + return 0 + + app = MyApp() +Index: wxPython-4.2.1/sphinxtools/inheritance.py +=================================================================== +--- wxPython-4.2.1.orig/sphinxtools/inheritance.py ++++ wxPython-4.2.1/sphinxtools/inheritance.py +@@ -24,13 +24,9 @@ from .constants import INHERITANCEROOT + ENOENT = getattr(errno, 'ENOENT', 0) + EPIPE = getattr(errno, 'EPIPE', 0) + +-if sys.version_info < (3, ): +- string_base = basestring +-else: +- string_base = str + + +-class InheritanceDiagram(object): ++class InheritanceDiagram: + """ + Given a list of classes, determines the set of classes that they inherit + from all the way to the root "object", and then is able to generate a +@@ -239,7 +235,7 @@ class InheritanceDiagram(object): + code = self.generate_dot(class_summary) + + # graphviz expects UTF-8 by default +- if isinstance(code, string_base): ++ if isinstance(code, str): + code = code.encode('utf-8') + + dot_args = ['dot'] +Index: wxPython-4.2.1/sphinxtools/librarydescription.py +=================================================================== +--- wxPython-4.2.1.orig/sphinxtools/librarydescription.py ++++ wxPython-4.2.1/sphinxtools/librarydescription.py +@@ -1,25 +1,17 @@ + import sys + import os + import re +- +-if sys.version_info < (3,): +- from StringIO import StringIO +-else: +- from io import StringIO ++from io import StringIO + + from inspect import getmro, getclasstree, getdoc, getcomments + + from .utilities import makeSummary, chopDescription, writeSphinxOutput, PickleFile +-from .utilities import findControlImages, formatExternalLink, isPython3 ++from .utilities import findControlImages, formatExternalLink + from .constants import object_types, MODULE_TO_ICON, DOXY_2_REST, SPHINXROOT + from . import templates + + EPYDOC_PATTERN = re.compile(r'\S+{\S+}', re.DOTALL) + +-if sys.version_info < (3,): +- reload(sys) +- sys.setdefaultencoding('utf-8') +- + + def make_class_tree(tree): + +@@ -1016,12 +1008,7 @@ class Property(ChildrenBase): + class Attribute(ChildrenBase): + + def __init__(self, name, specs, value): +- +- if isPython3(): +- specs = str(specs) +- else: +- specs = unicode(specs) +- ++ specs = str(specs) + start, end = specs.find("'"), specs.rfind("'") + specs = specs[start+1:end] + +Index: wxPython-4.2.1/sphinxtools/modulehunter.py +=================================================================== +--- wxPython-4.2.1.orig/sphinxtools/modulehunter.py ++++ wxPython-4.2.1/sphinxtools/modulehunter.py +@@ -22,18 +22,11 @@ from .librarydescription import Method, + + from . import inheritance + +-from .utilities import isPython3, PickleFile ++from .utilities import PickleFile + from .constants import object_types, EXCLUDED_ATTRS, MODULE_TO_ICON + from .constants import CONSTANT_RE + +-if sys.version_info < (3,): +- reload(sys) +- sys.setdefaultencoding('utf-8') +- +-if isPython3(): +- MethodTypes = (classmethod, types.MethodType, types.ClassMethodDescriptorType) +-else: +- MethodTypes = (classmethod, types.MethodType) ++MethodTypes = (classmethod, types.MethodType, types.ClassMethodDescriptorType) + + try: + import wx +@@ -155,10 +148,7 @@ def analyze_params(obj, signature): + pvalue = pvalue.strip() + if pname in pevals: + try: +- if isPython3(): +- peval = str(pevals[pname]) +- else: +- peval = unicode(pevals[pname]) ++ peval = str(pevals[pname]) + except UnicodeDecodeError: + peval = repr(pevals[pname]) + except TypeError: +@@ -223,7 +213,7 @@ def inspect_source(method_class, obj, so + def is_classmethod(instancemethod): + """ Determine if an instancemethod is a classmethod. """ + +- # attribute = (isPython3() and ['__self__'] or ['im_self'])[0] ++ # attribute = (['__self__'] or ['im_self'])[0] + # if hasattr(instancemethod, attribute): + # return getattr(instancemethod, attribute) is not None + # return False +@@ -291,20 +281,11 @@ def describe_func(obj, parent_class, mod + try: + code = None + if method in [object_types.METHOD, object_types.METHOD_DESCRIPTOR, object_types.INSTANCE_METHOD]: +- if isPython3(): +- code = obj.__func__.__code__ +- else: +- code = obj.im_func.func_code ++ code = obj.__func__.__code__ + elif method == object_types.STATIC_METHOD: +- if isPython3(): +- code = obj.__func__.__code__ +- else: +- code = obj.im_func.func_code ++ code = obj.__func__.__code__ + else: +- if isPython3(): +- code = obj.__code__ +- else: +- code = obj.func_code ++ code = obj.__code__ + except AttributeError: + code = None + +Index: wxPython-4.2.1/sphinxtools/postprocess.py +=================================================================== +--- wxPython-4.2.1.orig/sphinxtools/postprocess.py ++++ wxPython-4.2.1/sphinxtools/postprocess.py +@@ -25,9 +25,6 @@ from .constants import HTML_REPLACE, TOD + from .constants import CONSTANT_INSTANCES, WIDGETS_IMAGES_ROOT, SPHINX_IMAGES_ROOT + from .constants import DOCSTRING_KEY + +-PY2 = sys.version_info[0] == 2 +-PY3 = sys.version_info[0] == 3 +- + # ----------------------------------------------------------------------- # + + +@@ -750,7 +747,7 @@ def removeHeaderImage(text, options): + tag = soup.find('div', 'headerimage') + if tag: + tag.extract() +- text = unicode(soup) if PY2 else str(soup) ++ text = str(soup) + return text + + +@@ -762,7 +759,7 @@ def tweakModuleIndex(text): + href = tag['href'].split('.html#') + if len(href) == 2 and href[0] == href[1]: + tag['href'] = href[0] + '.html' +- return unicode(soup) if PY2 else str(soup) ++ return str(soup) + + + def tooltipsOnInheritance(text, class_summary): +Index: wxPython-4.2.1/sphinxtools/utilities.py +=================================================================== +--- wxPython-4.2.1.orig/sphinxtools/utilities.py ++++ wxPython-4.2.1/sphinxtools/utilities.py +@@ -16,14 +16,8 @@ import codecs + import shutil + import re + +-if sys.version_info < (3,): +- import cPickle as pickle +- from UserDict import UserDict +- string_base = basestring +-else: +- import pickle +- from collections import UserDict +- string_base = str ++import pickle ++from collections import UserDict + + # Phoenix-specific imports + from .templates import TEMPLATE_CONTRIB +@@ -444,7 +438,7 @@ def findControlImages(elementOrString): + """ + from etgtools.tweaker_tools import removeWxPrefix + +- if isinstance(elementOrString, string_base): ++ if isinstance(elementOrString, str): + class_name = py_class_name = elementOrString.lower() + else: + element = elementOrString +@@ -856,12 +850,6 @@ def formatExternalLink(fullname, inherit + return full_page + + +-def isPython3(): +- """ Returns ``True`` if we are using Python 3.x. """ +- +- return sys.version_info >= (3, ) +- +- + def textfile_open(filename, mode='rt'): + """ + Simple wrapper around open() that will use codecs.open on Python2 and +@@ -869,9 +857,4 @@ def textfile_open(filename, mode='rt'): + mode parameter must include the 't' to put the stream into text mode. + """ + assert 't' in mode +- if sys.version_info < (3,): +- import codecs +- mode = mode.replace('t', '') +- return codecs.open(filename, mode, encoding='utf-8') +- else: +- return open(filename, mode, encoding='utf-8') ++ return open(filename, mode, encoding='utf-8') +Index: wxPython-4.2.1/unittests/test_arraystring.py +=================================================================== +--- wxPython-4.2.1.orig/unittests/test_arraystring.py ++++ wxPython-4.2.1/unittests/test_arraystring.py +@@ -1,24 +1,16 @@ + import unittest + import wx +-import six + + #--------------------------------------------------------------------------- + +-if not six.PY3: +- alt = unicode +-else: +- def alt(s): +- return bytes(s, 'utf-8') +- +- + class ArrayString(unittest.TestCase): + + if hasattr(wx, 'testArrayStringTypemap'): + def test_ArrayStringTypemaps(self): + # basic conversion of list or tuples of strings +- seqList = ['a', alt('b'), 'hello world'] ++ seqList = ['a', b'b', 'hello world'] + self.assertEqual(wx.testArrayStringTypemap(seqList), ['a', 'b', 'hello world']) +- seqTuple = ('a', alt('b'), 'hello world') ++ seqTuple = ('a', b'b', 'hello world') + self.assertEqual(wx.testArrayStringTypemap(seqTuple), ['a', 'b', 'hello world']) + + def test_ArrayStringTypemapErrors(self): +@@ -26,7 +18,7 @@ class ArrayString(unittest.TestCase): + with self.assertRaises(TypeError): + wx.testArrayStringTypemap("STRING sequence") + with self.assertRaises(TypeError): +- wx.testArrayStringTypemap(alt("ALT sequence")) ++ wx.testArrayStringTypemap(b"ALT sequence") + with self.assertRaises(TypeError): + wx.testArrayStringTypemap(["list", "with", "non-string", "items", 123]) + +Index: wxPython-4.2.1/unittests/test_bitmap.py +=================================================================== +--- wxPython-4.2.1.orig/unittests/test_bitmap.py ++++ wxPython-4.2.1/unittests/test_bitmap.py +@@ -2,7 +2,6 @@ import unittest + from unittests import wtc + import wx + import os +-import six + + pngFile = os.path.join(os.path.dirname(__file__), 'toucan.png') + +@@ -58,10 +57,7 @@ class BitmapTests(wtc.WidgetTestCase): + self.assertTrue( not b1.IsOk() ) + b2 = wx.Bitmap(5, 10, 24) + self.assertTrue( b2.IsOk() ) +- if six.PY3: +- self.assertTrue( b2.__bool__() == b2.IsOk() ) +- else: +- self.assertTrue( b2.__nonzero__() == b2.IsOk() ) ++ self.assertTrue( b2.__bool__() == b2.IsOk() ) + + # check that the __nonzero__ method can be used with if statements + nzcheck = False +Index: wxPython-4.2.1/unittests/test_cmndata.py +=================================================================== +--- wxPython-4.2.1.orig/unittests/test_cmndata.py ++++ wxPython-4.2.1/unittests/test_cmndata.py +@@ -1,7 +1,6 @@ + import unittest + from unittests import wtc + import wx +-import six + + #--------------------------------------------------------------------------- + +@@ -37,14 +36,9 @@ class cmndata_tests(wtc.WidgetTestCase): + pd = wx.PrintData() + pdd = wx.PrintDialogData() + +- if six.PY3: +- psdd.__bool__() +- pd.__bool__() +- pdd.__bool__() +- else: +- psdd.__nonzero__() +- pd.__nonzero__() +- pdd.__nonzero__() ++ psdd.__bool__() ++ pd.__bool__() ++ pdd.__bool__() + + + def test_PD_PaperSize(self): +Index: wxPython-4.2.1/unittests/test_cursor.py +=================================================================== +--- wxPython-4.2.1.orig/unittests/test_cursor.py ++++ wxPython-4.2.1/unittests/test_cursor.py +@@ -1,7 +1,6 @@ + import unittest + from unittests import wtc + import wx +-import six + import os + + pngFile = os.path.join(os.path.dirname(__file__), 'pointy.png') +@@ -70,10 +69,7 @@ class CursorTests(wtc.WidgetTestCase): + + c2 = wx.Cursor(wx.CURSOR_ARROW) + self.assertTrue( c2.IsOk() ) +- if six.PY3: +- self.assertTrue( c2.__bool__() == c2.IsOk() ) +- else: +- self.assertTrue( c2.__nonzero__() == c2.IsOk() ) ++ self.assertTrue( c2.__bool__() == c2.IsOk() ) + + # check that the __nonzero__ method can be used with if statements + nzcheck = False +Index: wxPython-4.2.1/unittests/test_image.py +=================================================================== +--- wxPython-4.2.1.orig/unittests/test_image.py ++++ wxPython-4.2.1/unittests/test_image.py +@@ -1,8 +1,7 @@ + import unittest + from unittests import wtc + import wx +-import six +-from six import BytesIO as FileLikeObject ++from io import BytesIO as FileLikeObject + import os + + +@@ -136,20 +135,12 @@ class image_Tests(wtc.WidgetTestCase): + self.assertTrue(img.IsOk()) + data = img.GetDataBuffer() + self.assertTrue(isinstance(data, memoryview)) +- if six.PY2: +- data[0] = b'1' +- data[1] = b'2' +- data[2] = b'3' +- self.assertEqual(ord('1'), img.GetRed(0,0)) +- self.assertEqual(ord('2'), img.GetGreen(0,0)) +- self.assertEqual(ord('3'), img.GetBlue(0,0)) +- else: +- data[0] = 1 +- data[1] = 2 +- data[2] = 3 +- self.assertEqual(1, img.GetRed(0,0)) +- self.assertEqual(2, img.GetGreen(0,0)) +- self.assertEqual(3, img.GetBlue(0,0)) ++ data[0] = 1 ++ data[1] = 2 ++ data[2] = 3 ++ self.assertEqual(1, img.GetRed(0,0)) ++ self.assertEqual(2, img.GetGreen(0,0)) ++ self.assertEqual(3, img.GetBlue(0,0)) + + + def test_imageGetAlphaDataBuffer(self): +@@ -159,20 +150,12 @@ class image_Tests(wtc.WidgetTestCase): + self.assertTrue(img.IsOk()) + data = img.GetAlphaBuffer() + self.assertTrue(isinstance(data, memoryview)) +- if six.PY2: +- data[0] = b'1' +- data[1] = b'2' +- data[2] = b'3' +- self.assertEqual(ord('1'), img.GetAlpha(0,0)) +- self.assertEqual(ord('2'), img.GetAlpha(1,0)) +- self.assertEqual(ord('3'), img.GetAlpha(2,0)) +- else: +- data[0] = 1 +- data[1] = 2 +- data[2] = 3 +- self.assertEqual(1, img.GetAlpha(0,0)) +- self.assertEqual(2, img.GetAlpha(1,0)) +- self.assertEqual(3, img.GetAlpha(2,0)) ++ data[0] = 1 ++ data[1] = 2 ++ data[2] = 3 ++ self.assertEqual(1, img.GetAlpha(0,0)) ++ self.assertEqual(2, img.GetAlpha(1,0)) ++ self.assertEqual(3, img.GetAlpha(2,0)) + + + def test_imageSetDataBuffer1(self): +Index: wxPython-4.2.1/unittests/test_lib_cdate.py +=================================================================== +--- wxPython-4.2.1.orig/unittests/test_lib_cdate.py ++++ wxPython-4.2.1/unittests/test_lib_cdate.py +@@ -1,7 +1,6 @@ + import unittest + from unittests import wtc + import wx.lib.CDate as cdate +-import six + import datetime + + class lib_cdate_Tests(wtc.WidgetTestCase): +Index: wxPython-4.2.1/unittests/test_lib_pubsub_defaultlog.py +=================================================================== +--- wxPython-4.2.1.orig/unittests/test_lib_pubsub_defaultlog.py ++++ wxPython-4.2.1/unittests/test_lib_pubsub_defaultlog.py +@@ -7,10 +7,10 @@ + """ + + import unittest ++from io import StringIO + from unittests import wtc + + from wx.lib.pubsub.utils import notification +-from six import StringIO + + #--------------------------------------------------------------------------- + +Index: wxPython-4.2.1/unittests/test_lib_pubsub_listener.py +=================================================================== +--- wxPython-4.2.1.orig/unittests/test_lib_pubsub_listener.py ++++ wxPython-4.2.1/unittests/test_lib_pubsub_listener.py +@@ -5,7 +5,6 @@ + + """ + +-import six + import unittest + from unittests import wtc + +@@ -195,9 +194,6 @@ class lib_pubsub_ArgsInfo(wtc.PubsubTest + def tmpFn(self): + pass + Listener( DOA.tmpFn, ArgsInfoMock() ) +- # Py3 doesn't have unbound methods so this won't throw a ValueError +- if not six.PY3: +- self.assertRaises(ValueError, getListener1) + + # test DOA of tmp callable: + def getListener2(): +Index: wxPython-4.2.1/unittests/test_lib_pubsub_notify.py +=================================================================== +--- wxPython-4.2.1.orig/unittests/test_lib_pubsub_notify.py ++++ wxPython-4.2.1/unittests/test_lib_pubsub_notify.py +@@ -22,7 +22,7 @@ class lib_pubsub_Notify(wtc.PubsubTestCa + from wx.lib.pubsub.utils.notification import useNotifyByWriteFile + + def captureStdout(): +- from six import StringIO ++ from io import StringIO + capture = StringIO() + useNotifyByWriteFile( fileObj = capture ) + return capture +Index: wxPython-4.2.1/unittests/test_lib_pubsub_notify4.py +=================================================================== +--- wxPython-4.2.1.orig/unittests/test_lib_pubsub_notify4.py ++++ wxPython-4.2.1/unittests/test_lib_pubsub_notify4.py +@@ -9,7 +9,6 @@ + import unittest + from unittests import wtc + +-import six + from difflib import ndiff, unified_diff, context_diff + + +@@ -45,7 +44,7 @@ class lib_pubsub_NotifyN(wtc.PubsubTestC + self.pub.setNotificationFlags(all=True) + + def verify(**ref): +- for key, val in six.iteritems(notifiee.counts): ++ for key, val in notifiee.counts.items(): + if key in ref: + self.assertEqual(val, ref[key], "\n%s\n%s" % (notifiee.counts, ref) ) + else: +Index: wxPython-4.2.1/unittests/test_lib_pubsub_topicmgr.py +=================================================================== +--- wxPython-4.2.1.orig/unittests/test_lib_pubsub_topicmgr.py ++++ wxPython-4.2.1/unittests/test_lib_pubsub_topicmgr.py +@@ -359,7 +359,7 @@ r'''\-- Topic "a2" + topicMgr.getOrCreateTopic('a2.b.a') + topicMgr.getOrCreateTopic('a2.b.b') + +- from six import StringIO ++ from io import StringIO + buffer = StringIO() + printTreeDocs(rootTopic=root, width=70, fileObj=buffer) + self.assertEqual( buffer.getvalue(), self.expectedOutput ) +Index: wxPython-4.2.1/unittests/test_pgvariant.py +=================================================================== +--- wxPython-4.2.1.orig/unittests/test_pgvariant.py ++++ wxPython-4.2.1/unittests/test_pgvariant.py +@@ -3,8 +3,6 @@ from unittests import wtc + import wx + import wx.propgrid as pg + +-import six +- + #--------------------------------------------------------------------------- + + class pgvariant_Tests(wtc.WidgetTestCase): +Index: wxPython-4.2.1/unittests/test_stream.py +=================================================================== +--- wxPython-4.2.1.orig/unittests/test_stream.py ++++ wxPython-4.2.1/unittests/test_stream.py +@@ -1,8 +1,7 @@ + import unittest + from unittests import wtc + import wx +-import six +-from six import BytesIO as FileLikeObject ++from io import BytesIO as FileLikeObject + import os + + +Index: wxPython-4.2.1/unittests/test_string.py +=================================================================== +--- wxPython-4.2.1.orig/unittests/test_string.py ++++ wxPython-4.2.1/unittests/test_string.py +@@ -1,6 +1,5 @@ + import unittest + import wx +-import six + from unittests import wtc + + #--------------------------------------------------------------------------- +@@ -10,57 +9,6 @@ from unittests import wtc + class String(unittest.TestCase): + + if hasattr(wx, 'testStringTypemap'): +- if not six.PY3: +- def test_StringTypemapsPy2(self): +- utf = '\xc3\xa9l\xc3\xa9phant' # utf-8 string +- uni = utf.decode('utf-8') # convert to unicode +- iso = uni.encode('iso-8859-1') # make a string with a different encoding +- +- +- # wx.testStringTypemap() will accept a parameter that +- # is a Unicode object or an 'ascii' or 'utf-8' string object, +- # which will then be converted to a wxString. The return +- # value is a Unicode object that has been converted from a +- # wxString that is a copy of the wxString created for the +- # parameter. +- +- # ascii +- result = wx.testStringTypemap('hello') +- self.assertTrue(type(result) == unicode) +- self.assertTrue(result == unicode('hello')) +- +- # unicode should pass through unmodified +- result = wx.testStringTypemap(uni) +- self.assertTrue(result == uni) +- +- # utf-8 is converted +- result = wx.testStringTypemap(utf) +- self.assertTrue(result == uni) +- +- # can't auto-convert this +- with self.assertRaises(UnicodeDecodeError): +- result = wx.testStringTypemap(iso) +- +- # utf-16-be +- val = "\x00\xe9\x00l\x00\xe9\x00p\x00h\x00a\x00n\x00t" +- with self.assertRaises(UnicodeDecodeError): +- result = wx.testStringTypemap(val) +- result = wx.testStringTypemap( val.decode('utf-16-be')) +- self.assertTrue(result == uni) +- +- # utf-32-be +- val = "\x00\x00\x00\xe9\x00\x00\x00l\x00\x00\x00\xe9\x00\x00\x00p\x00\x00\x00h\x00\x00\x00a\x00\x00\x00n\x00\x00\x00t" +- with self.assertRaises(UnicodeDecodeError): +- result = wx.testStringTypemap(val) +- result = wx.testStringTypemap(val.decode('utf-32-be')) +- self.assertTrue(result == uni) +- +- # utf-8 with BOM +- #val = "\xef\xbb\xbfHello" +- #result = wx.testStringTypemap(val) +- #self.assertTrue(result == u'\ufeffHello') +- +- else: + def test_StringTypemapsPy3(self): + utf = b'\xc3\xa9l\xc3\xa9phant' # utf-8 bytes + uni = utf.decode('utf-8') # convert to unicode +Index: wxPython-4.2.1/unittests/test_variant.py +=================================================================== +--- wxPython-4.2.1.orig/unittests/test_variant.py ++++ wxPython-4.2.1/unittests/test_variant.py +@@ -2,8 +2,6 @@ import unittest + from unittests import wtc + import wx + +-import six +- + #--------------------------------------------------------------------------- + + class variant_Tests(wtc.WidgetTestCase): +@@ -11,7 +9,7 @@ class variant_Tests(wtc.WidgetTestCase): + @unittest.skipIf(not hasattr(wx, 'testVariantTypemap'), '') + def test_variant1(self): + n = wx.testVariantTypemap(123) +- self.assertTrue(isinstance(n, six.integer_types)) ++ self.assertTrue(isinstance(n, int)) + self.assertEqual(n, 123) + + +Index: wxPython-4.2.1/unittests/test_window.py +=================================================================== +--- wxPython-4.2.1.orig/unittests/test_window.py ++++ wxPython-4.2.1/unittests/test_window.py +@@ -1,7 +1,6 @@ + import unittest + from unittests import wtc + import wx +-import six + + #--------------------------------------------------------------------------- + +@@ -15,7 +14,7 @@ class WindowTests(wtc.WidgetTestCase): + def test_windowHandle(self): + w = wx.Window(self.frame, -1, (10,10), (50,50)) + hdl = w.GetHandle() +- self.assertTrue(isinstance(hdl, six.integer_types)) ++ self.assertTrue(isinstance(hdl, int)) + + + def test_windowProperties(self): +Index: wxPython-4.2.1/unittests/test_wxdatetime.py +=================================================================== +--- wxPython-4.2.1.orig/unittests/test_wxdatetime.py ++++ wxPython-4.2.1/unittests/test_wxdatetime.py +@@ -1,6 +1,5 @@ + import unittest + import wx +-import six + from unittests import wtc + import datetime + import time +@@ -45,12 +44,8 @@ class datetime_Tests(wtc.WidgetTestCase) + + def test_datetimeGetAmPm(self): + am, pm = wx.DateTime.GetAmPmStrings() +- if six.PY3: +- base = str +- else: +- base = unicode +- self.assertTrue(isinstance(am, base) and am != "") +- self.assertTrue(isinstance(pm, base) and pm != "") ++ self.assertTrue(isinstance(am, str) and am != "") ++ self.assertTrue(isinstance(pm, str) and pm != "") + + + def test_datetimeProperties(self): +Index: wxPython-4.2.1/unittests/wtc.py +=================================================================== +--- wxPython-4.2.1.orig/unittests/wtc.py ++++ wxPython-4.2.1/unittests/wtc.py +@@ -1,7 +1,6 @@ + import unittest + import wx + import sys, os +-import six + + #--------------------------------------------------------------------------- + +@@ -84,12 +83,9 @@ class WidgetTestCase(unittest.TestCase): + + + def myExecfile(self, filename, ns): +- if not six.PY3: +- execfile(filename, ns) +- else: +- with open(filename, 'r') as f: +- source = f.read() +- exec(source, ns) ++ with open(filename, 'r') as f: ++ source = f.read() ++ exec(source, ns) + + + def execSample(self, name): +@@ -109,10 +105,7 @@ class Namespace(object): + #--------------------------------------------------------------------------- + + def mybytes(text): +- if six.PY3: +- return bytes(text, 'utf-8') +- else: +- return str(text) ++ return bytes(text, 'utf-8') + + #--------------------------------------------------------------------------- + +Index: wxPython-4.2.1/wx/lib/CDate.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/CDate.py ++++ wxPython-4.2.1/wx/lib/CDate.py +@@ -15,7 +15,6 @@ + # in a string format, then an error was raised. + # + """Date and calendar classes and date utitility methods.""" +-from __future__ import division + import time + + # I18N +Index: wxPython-4.2.1/wx/lib/activexwrapper.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/activexwrapper.py ++++ wxPython-4.2.1/wx/lib/activexwrapper.py +@@ -24,7 +24,7 @@ except ImportError: + if hasattr(sys, "frozen"): + import os, win32api + dllpath = os.path.join(win32api.GetSystemDirectory(), 'MFC71.DLL') +- if sys.version[:3] >= '2.4' and not os.path.exists(dllpath): ++ if not os.path.exists(dllpath): + message = "%s not found" % dllpath + else: + raise # original error message +Index: wxPython-4.2.1/wx/lib/agw/artmanager.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/agw/artmanager.py ++++ wxPython-4.2.1/wx/lib/agw/artmanager.py +@@ -6,7 +6,7 @@ This module contains drawing routines an + import wx + import random + +-from six import BytesIO ++from io import BytesIO + + from .fmresources import * + +Index: wxPython-4.2.1/wx/lib/agw/customtreectrl.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/agw/customtreectrl.py ++++ wxPython-4.2.1/wx/lib/agw/customtreectrl.py +@@ -349,8 +349,6 @@ License And Version + + Latest Revision: Helio Guilherme @ 09 Aug 2018, 21.35 GMT + +-Version 2.7 +- + """ + + # Version Info +@@ -359,9 +357,6 @@ __version__ = "2.7" + import wx + from wx.lib.expando import ExpandoTextCtrl + +-# Python 2/3 compatibility helper +-import six +- + # ---------------------------------------------------------------------------- + # Constants + # ---------------------------------------------------------------------------- +Index: wxPython-4.2.1/wx/lib/agw/flatmenu.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/agw/flatmenu.py ++++ wxPython-4.2.1/wx/lib/agw/flatmenu.py +@@ -200,8 +200,8 @@ import math + + import wx.lib.colourutils as colourutils + +-import six ++import io + + from .fmcustomizedlg import FMCustomizeDlg + from .artmanager import ArtManager, DCSaver + from .fmresources import * +@@ -590,7 +590,7 @@ class FMRenderer(object): + + else: + +- stream = six.BytesIO(xpm) ++ stream = io.BytesIO(xpm) + img = wx.Image(stream) + + return wx.Bitmap(img) +@@ -2226,7 +2226,7 @@ class MenuEntryInfo(object): + :param integer `cmd`: the menu accelerator identifier. + """ + +- if isinstance(titleOrMenu, six.string_types): ++ if isinstance(titleOrMenu, str): + + self._title = titleOrMenu + self._menu = menu +@@ -3595,7 +3595,7 @@ class FlatMenuBar(wx.Panel): + if self._showCustomize: + if invT + invM > 0: + self._moreMenu.AppendSeparator() +- item = FlatMenuItem(self._moreMenu, self._popupDlgCmdId, _(six.u("Customize..."))) ++ item = FlatMenuItem(self._moreMenu, self._popupDlgCmdId, _("Customize...")) + self._moreMenu.AppendItem(item) + + +Index: wxPython-4.2.1/wx/lib/agw/flatnotebook.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/agw/flatnotebook.py ++++ wxPython-4.2.1/wx/lib/agw/flatnotebook.py +@@ -192,8 +192,6 @@ import math + import weakref + import pickle + +-import six +- + # Used on OSX to get access to carbon api constants + if wx.Platform == '__WXMAC__': + try: +@@ -6550,7 +6548,7 @@ class PageContainer(wx.Panel): + if page < len(self._pagesInfoVec): + return self._pagesInfoVec[page].GetCaption() + else: +- return six.u('') ++ return '' + + + def SetPageText(self, page, text): +Index: wxPython-4.2.1/wx/lib/agw/floatspin.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/agw/floatspin.py ++++ wxPython-4.2.1/wx/lib/agw/floatspin.py +@@ -177,10 +177,7 @@ import wx + import locale + from math import ceil, floor + +-# Python 2/3 compatibility helper +-import six +-if six.PY3: +- long = int ++long = int + + # Set The Styles For The Underline wx.TextCtrl + FS_READONLY = 1 +@@ -1379,7 +1376,7 @@ class FixedPoint(object): + self.n = n + return + +- if isinstance(value, six.integer_types): ++ if isinstance(value, int): + self.n = int(value) * _tento(p) + return + +Index: wxPython-4.2.1/wx/lib/agw/fmcustomizedlg.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/agw/fmcustomizedlg.py ++++ wxPython-4.2.1/wx/lib/agw/fmcustomizedlg.py +@@ -14,14 +14,9 @@ + This module contains a custom dialog class used to personalize the appearance of a + :class:`~wx.lib.agw.flatmenu.FlatMenu` on the fly, allowing also the user of your application to do the same. + """ ++from collections import UserDict + + import wx +-import six +- +-if six.PY2: +- from UserDict import UserDict +-else: +- from collections import UserDict + + from .artmanager import ArtManager + from .fmresources import * +Index: wxPython-4.2.1/wx/lib/agw/hypertreelist.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/agw/hypertreelist.py ++++ wxPython-4.2.1/wx/lib/agw/hypertreelist.py +@@ -302,9 +302,6 @@ from wx.lib.agw.customtreectrl import Dr + from wx.lib.agw.customtreectrl import TreeEditTimer as TreeListEditTimer + from wx.lib.agw.customtreectrl import EVT_TREE_ITEM_CHECKING, EVT_TREE_ITEM_CHECKED, EVT_TREE_ITEM_HYPERLINK + +-# Python 2/3 compatibility helper +-import six +- + # Version Info + __version__ = "1.4" + +@@ -453,7 +450,7 @@ class TreeListColumnInfo(object): + :param `edit`: ``True`` to set the column as editable, ``False`` otherwise. + """ + +- if isinstance(input, six.string_types): ++ if isinstance(input, str): + self._text = input + self._width = width + self._flag = flag +@@ -3662,7 +3659,7 @@ class TreeListMainWindow(CustomTreeCtrl) + if self._curColumn == -1: + self._curColumn = 0 + +- self.SetItemText(self._editItem, six.text_type(value), self._curColumn) ++ self.SetItemText(self._editItem, str(value), self._curColumn) + + + def OnCancelEdit(self): +Index: wxPython-4.2.1/wx/lib/agw/rulerctrl.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/agw/rulerctrl.py ++++ wxPython-4.2.1/wx/lib/agw/rulerctrl.py +@@ -153,6 +153,7 @@ Version 0.4 + + """ + ++import io + import wx + import math + import zlib +@@ -166,9 +167,6 @@ try: + except: + pass + +-# Python 2/3 compatibility helper +-import six +- + # Built-in formats + IntFormat = 1 + """ Integer format. """ +@@ -225,7 +223,7 @@ def GetIndicatorBitmap(): + def GetIndicatorImage(): + """ Returns the image indicator as a :class:`wx.Image`. """ + +- stream = six.BytesIO(GetIndicatorData()) ++ stream = io.BytesIO(GetIndicatorData()) + return wx.Image(stream) + + +Index: wxPython-4.2.1/wx/lib/agw/scrolledthumbnail.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/agw/scrolledthumbnail.py ++++ wxPython-4.2.1/wx/lib/agw/scrolledthumbnail.py +@@ -173,18 +173,15 @@ Version 1.0 + # Beginning Of ThumbnailCtrl wxPython Code + #---------------------------------------------------------------------- + ++import io + import os + import wx +-import six + import zlib + from math import radians + + from wx.lib.embeddedimage import PyEmbeddedImage + +-if six.PY3: +- import _thread as thread +-else: +- import thread ++import _thread as thread + + #---------------------------------------------------------------------- + # Get Default Icon/Data +@@ -308,9 +305,9 @@ b'x\xda\xeb\x0c\xf0s\xe7\xe5\x92\xe2b``\ + def getShadow(): + """ Creates a shadow behind every thumbnail. """ + +- sh_tr = wx.Image(six.BytesIO(getDataTR())).ConvertToBitmap() +- sh_bl = wx.Image(six.BytesIO(getDataBL())).ConvertToBitmap() +- sh_sh = wx.Image(six.BytesIO(getDataSH())).Rescale(500, 500, wx.IMAGE_QUALITY_HIGH) ++ sh_tr = wx.Image(io.BytesIO(getDataTR())).ConvertToBitmap() ++ sh_bl = wx.Image(io.BytesIO(getDataBL())).ConvertToBitmap() ++ sh_sh = wx.Image(io.BytesIO(getDataSH())).Rescale(500, 500, wx.IMAGE_QUALITY_HIGH) + return (sh_tr, sh_bl, sh_sh.ConvertToBitmap()) + + +Index: wxPython-4.2.1/wx/lib/agw/ultimatelistctrl.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/agw/ultimatelistctrl.py ++++ wxPython-4.2.1/wx/lib/agw/ultimatelistctrl.py +@@ -236,11 +236,10 @@ Version 0.8 + import wx + import math + import bisect ++import io + import zlib + from functools import cmp_to_key + +-import six +- + from wx.lib.expando import ExpandoTextCtrl + + # Version Info +@@ -550,7 +549,7 @@ IL_FIXED_SIZE = 0 + IL_VARIABLE_SIZE = 1 + + # Python integers, to make long types to work with CreateListItem +-INTEGER_TYPES = six.integer_types ++INTEGER_TYPES = [int] + + + # ---------------------------------------------------------------------------- +@@ -652,7 +651,7 @@ def GetdragcursorBitmap(): + def GetdragcursorImage(): + """ Returns the drag and drop cursor image as a :class:`wx.Image`. """ + +- stream = six.BytesIO(GetdragcursorData()) ++ stream = io.BytesIO(GetdragcursorData()) + return wx.Image(stream) + + +@@ -13114,9 +13113,9 @@ class UltimateListCtrl(wx.Control): + + if entry: + pos = self.GetItemCount() +- self.InsertStringItem(pos, six.u(entry[0])) ++ self.InsertStringItem(pos, str(entry[0])) + for i in range(1, len(entry)): +- self.SetStringItem(pos, i, six.u(entry[i])) ++ self.SetStringItem(pos, i, str(entry[i])) + + return pos + +Index: wxPython-4.2.1/wx/lib/agw/xlsgrid.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/agw/xlsgrid.py ++++ wxPython-4.2.1/wx/lib/agw/xlsgrid.py +@@ -250,8 +250,6 @@ import string + + import wx.grid as gridlib + +-import six +- + from wx.lib.embeddedimage import PyEmbeddedImage + from wx.lib.wordwrap import wordwrap + +@@ -439,8 +437,8 @@ def SplitThousands(s, tSep=',', dSep='.' + + """ + +- if not isinstance(s, six.string_types): +- s = six.u(s) ++ if not isinstance(s, str): ++ s = str(s) + + cnt = 0 + numChars = dSep + '0123456789' +@@ -837,7 +835,7 @@ class XLSText(object): + value = representation%value + except ValueError: + # Fall back to string +- value = six.u(value) ++ value = str(value) + + if "#," in number_format: + value = SplitThousands(value) +Index: wxPython-4.2.1/wx/lib/agw/zoombar.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/agw/zoombar.py ++++ wxPython-4.2.1/wx/lib/agw/zoombar.py +@@ -133,8 +133,6 @@ Version 0.1 + import wx + import sys + +-import six +- + from wx.lib.embeddedimage import PyEmbeddedImage + + zoombackgrey = PyEmbeddedImage( +@@ -375,7 +373,7 @@ class ZoomBarImage(object): + self._oldHeight = 0 + self._vCenter = 0 + self._hCenter = 0 +- self._oldInc = -six.MAXSIZE ++ self._oldInc = -sys.maxsize + self._isSeparator = False + self._enabled = True + +Index: wxPython-4.2.1/wx/lib/colourchooser/__init__.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/colourchooser/__init__.py ++++ wxPython-4.2.1/wx/lib/colourchooser/__init__.py +@@ -12,8 +12,6 @@ but WITHOUT ANY WARRANTY; without even t + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + """ + +-from __future__ import absolute_import +- + # 12/14/2003 - Jeff Grimmett (grimmtooth@softhome.net) + # + # o 2.5 compatibility update. +Index: wxPython-4.2.1/wx/lib/colourchooser/pycolourchooser.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/colourchooser/pycolourchooser.py ++++ wxPython-4.2.1/wx/lib/colourchooser/pycolourchooser.py +@@ -12,8 +12,6 @@ but WITHOUT ANY WARRANTY; without even t + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + """ + +-from __future__ import absolute_import +- + # 12/14/2003 - Jeff Grimmett (grimmtooth@softhome.net) + # + # o 2.5 compatibility update. +Index: wxPython-4.2.1/wx/lib/colourchooser/pycolourslider.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/colourchooser/pycolourslider.py ++++ wxPython-4.2.1/wx/lib/colourchooser/pycolourslider.py +@@ -16,8 +16,6 @@ but WITHOUT ANY WARRANTY; without even t + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + """ + +-from __future__ import absolute_import +- + # 12/14/2003 - Jeff Grimmett (grimmtooth@softhome.net) + # + # o 2.5 compatibility update. +Index: wxPython-4.2.1/wx/lib/colourchooser/pypalette.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/colourchooser/pypalette.py ++++ wxPython-4.2.1/wx/lib/colourchooser/pypalette.py +@@ -16,8 +16,6 @@ but WITHOUT ANY WARRANTY; without even t + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + """ + +-from __future__ import absolute_import +- + # 12/14/2003 - Jeff Grimmett (grimmtooth@softhome.net) + # + # o 2.5 compatibility update. +Index: wxPython-4.2.1/wx/lib/embeddedimage.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/embeddedimage.py ++++ wxPython-4.2.1/wx/lib/embeddedimage.py +@@ -13,9 +13,9 @@ + #---------------------------------------------------------------------- + + import base64 ++from io import BytesIO + + import wx +-from six import BytesIO + + try: + b64decode = base64.b64decode +@@ -23,7 +23,7 @@ except AttributeError: + b64decode = base64.decodestring + + +-class PyEmbeddedImage(object): ++class PyEmbeddedImage: + """ + PyEmbeddedImage is primarily intended to be used by code generated + by img2py as a means of embedding image data in a python module so +Index: wxPython-4.2.1/wx/lib/fancytext.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/fancytext.py ++++ wxPython-4.2.1/wx/lib/fancytext.py +@@ -58,7 +58,6 @@ import math + import sys + + import wx +-import six + + import xml.parsers.expat + +@@ -255,8 +254,6 @@ class Renderer: + def renderCharacterData(self, data, x, y): + raise NotImplementedError() + +-from six import PY3 +- + def _addGreek(): + alpha = 0xE1 + Alpha = 0xC1 +@@ -265,10 +262,7 @@ def _addGreek(): + for i, name in enumerate(_greek_letters): + def start(self, attrs, code=chr(alpha+i)): + self.start_font({"encoding" : _greekEncoding}) +- if not PY3: +- self.characterData(code.decode('iso8859-7')) +- else: +- self.characterData(code) ++ self.characterData(code) + self.end_font() + setattr(Renderer, "start_%s" % name, start) + setattr(Renderer, "end_%s" % name, end) +@@ -276,10 +270,7 @@ def _addGreek(): + continue # There is no capital for altsigma + def start(self, attrs, code=chr(Alpha+i)): + self.start_font({"encoding" : _greekEncoding}) +- if not PY3: +- self.characterData(code.decode('iso8859-7')) +- else: +- self.characterData(code) ++ self.characterData(code) + self.end_font() + setattr(Renderer, "start_%s" % name.capitalize(), start) + setattr(Renderer, "end_%s" % name.capitalize(), end) +@@ -366,8 +357,6 @@ def RenderToRenderer(str, renderer, encl + if enclose: + str = '%s' % str + p = xml.parsers.expat.ParserCreate() +- if six.PY2: +- p.returns_unicode = 0 + p.StartElementHandler = renderer.startElement + p.EndElementHandler = renderer.endElement + p.CharacterDataHandler = renderer.characterData +Index: wxPython-4.2.1/wx/lib/floatcanvas/FCObjects.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/floatcanvas/FCObjects.py ++++ wxPython-4.2.1/wx/lib/floatcanvas/FCObjects.py +@@ -17,7 +17,6 @@ This is where FloatCanvas defines its dr + import sys + + import wx +-import six + + import numpy as N + +@@ -228,14 +227,8 @@ class DrawObject: + if not self._Canvas.HitColorGenerator: + # first call to prevent the background color from being used. + self._Canvas.HitColorGenerator = _colorGenerator() +- if six.PY3: +- next(self._Canvas.HitColorGenerator) +- else: +- self._Canvas.HitColorGenerator.next() +- if six.PY3: +- self.HitColor = next(self._Canvas.HitColorGenerator) +- else: +- self.HitColor = self._Canvas.HitColorGenerator.next() ++ next(self._Canvas.HitColorGenerator) ++ self.HitColor = next(self._Canvas.HitColorGenerator) + self.SetHitPen(self.HitColor,self.HitLineWidth) + self.SetHitBrush(self.HitColor) + # put the object in the hit dict, indexed by it's color +@@ -2890,15 +2883,9 @@ class Group(DrawObject): + if not self._Canvas.HitColorGenerator: + self._Canvas.HitColorGenerator = _colorGenerator() + # first call to prevent the background color from being used. +- if six.PY2: +- self._Canvas.HitColorGenerator.next() +- else: +- next(self._Canvas.HitColorGenerator) ++ next(self._Canvas.HitColorGenerator) + # Set all contained objects to the same Hit color: +- if six.PY2: +- self.HitColor = self._Canvas.HitColorGenerator.next() +- else: +- self.HitColor = next(self._Canvas.HitColorGenerator) ++ self.HitColor = next(self._Canvas.HitColorGenerator) + self._ChangeChildrenHitColor(self.ObjectList) + # put the object in the hit dict, indexed by it's color + if not self._Canvas.HitDict: +Index: wxPython-4.2.1/wx/lib/floatcanvas/FloatCanvas.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/floatcanvas/FloatCanvas.py ++++ wxPython-4.2.1/wx/lib/floatcanvas/FloatCanvas.py +@@ -42,8 +42,6 @@ Many samples are available in the `wxPho + + """ + +-from __future__ import division +- + import sys + mac = sys.platform.startswith("darwin") + +@@ -53,7 +51,6 @@ try: + except ImportError: + from time import clock + import wx +-import six + + from .FCObjects import * + +Index: wxPython-4.2.1/wx/lib/floatcanvas/Resources.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/floatcanvas/Resources.py ++++ wxPython-4.2.1/wx/lib/floatcanvas/Resources.py +@@ -4,7 +4,7 @@ + from wx import Image as ImageFromStream + from wx import Bitmap as BitmapFromImage + +-from six import BytesIO ++from io import BytesIO + import zlib + + +Index: wxPython-4.2.1/wx/lib/floatcanvas/ScreenShot.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/floatcanvas/ScreenShot.py ++++ wxPython-4.2.1/wx/lib/floatcanvas/ScreenShot.py +@@ -4,7 +4,7 @@ + from wx import Image as ImageFromStream + from wx import BitmapFromImage + +-from six import BytesIO ++from io import BytesIO + import zlib + + +Index: wxPython-4.2.1/wx/lib/graphics.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/graphics.py ++++ wxPython-4.2.1/wx/lib/graphics.py +@@ -38,7 +38,6 @@ the ``wx.GraphicsContext`` classes a lit + """ + + import math +-import six + + import wx + import wx.lib.wxcairo as wxcairo +@@ -1886,7 +1885,7 @@ def _makeColour(colour): + Helper which makes a wx.Colour from any of the allowed typemaps (string, + tuple, etc.) + """ +- if isinstance(colour, (six.string_types, tuple)): ++ if isinstance(colour, (str, tuple)): + return wx.NamedColour(colour) + else: + return colour +Index: wxPython-4.2.1/wx/lib/inspection.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/inspection.py ++++ wxPython-4.2.1/wx/lib/inspection.py +@@ -28,7 +28,6 @@ import wx.py + import wx.stc + #import wx.aui as aui + import wx.lib.agw.aui as aui +-import six + import wx.lib.utils as utils + import sys + import inspect +@@ -635,7 +634,7 @@ class InspectionInfoPanel(wx.stc.StyledT + + + def Fmt(self, name, value): +- if isinstance(value, six.string_types): ++ if isinstance(value, str): + return " %s = '%s'" % (name, value) + else: + return " %s = %s" % (name, value) +Index: wxPython-4.2.1/wx/lib/intctrl.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/intctrl.py ++++ wxPython-4.2.1/wx/lib/intctrl.py +@@ -41,17 +41,12 @@ import string + import types + + import wx +-import six + + #---------------------------------------------------------------------------- + +-MAXSIZE = six.MAXSIZE # (constants should be in upper case) +-MINSIZE = -six.MAXSIZE-1 +- +-if six.PY2: +- LONGTYPE = long +-else: +- LONGTYPE = int ++MAXSIZE = sys.maxsize # (constants should be in upper case) ++MINSIZE = -sys.maxsize-1 ++LONGTYPE = int + + #---------------------------------------------------------------------------- + +@@ -469,10 +464,7 @@ class IntCtrl(wx.TextCtrl): + self.__default_color = wx.BLACK + self.__oob_color = wx.RED + self.__allow_none = 0 +- if six.PY2: +- self.__allow_long = 0 +- else: +- self.__allow_long = 1 ++ self.__allow_long = 1 + self.__oldvalue = None + + if validator == wx.DefaultValidator: +@@ -491,10 +483,7 @@ class IntCtrl(wx.TextCtrl): + self.SetLimited(limited) + self.SetColors(default_color, oob_color) + self.SetNoneAllowed(allow_none) +- if six.PY2: +- self.SetLongAllowed(allow_long) +- else: +- self.SetLongAllowed(1) ++ self.SetLongAllowed(1) + self.ChangeValue(value) + + def OnText( self, event ): +@@ -708,7 +697,7 @@ class IntCtrl(wx.TextCtrl): + value = self.GetValue() + + if( not (value is None and self.IsNoneAllowed()) +- and type(value) not in six.integer_types ): ++ and type(value) is not int ): + raise ValueError ( + 'IntCtrl requires integer values, passed %s'% repr(value) ) + +@@ -820,7 +809,7 @@ class IntCtrl(wx.TextCtrl): + elif type(value) == LONGTYPE and not self.IsLongAllowed(): + raise ValueError ( + 'IntCtrl requires integer value, passed long' ) +- elif type(value) not in six.integer_types: ++ elif type(value) is not int: + raise ValueError ( + 'IntCtrl requires integer value, passed %s'% repr(value) ) + +Index: wxPython-4.2.1/wx/lib/masked/combobox.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/masked/combobox.py ++++ wxPython-4.2.1/wx/lib/masked/combobox.py +@@ -478,7 +478,7 @@ class BaseMaskedComboBox( wx.ComboBox, M + penalty. + """ + if self._mask: +- if not isinstance(choice, six.string_types): ++ if not isinstance(choice, str): + raise TypeError('%s: choices must be a sequence of strings' % str(self._index)) + elif not self.IsValid(choice): + raise ValueError('%s: "%s" is not a valid value for the control as specified.' % (str(self._index), choice)) +@@ -731,7 +731,7 @@ class BaseMaskedComboBox( wx.ComboBox, M + # work around bug in wx 2.5 + wx.CallAfter(self.SetInsertionPoint, 0) + wx.CallAfter(self.SetInsertionPoint, end) +- elif isinstance(match_index, six.string_types): ++ elif isinstance(match_index, str): + ## dbg('CallAfter SetValue') + # Preserve the textbox contents + # See commentary in _OnReturn docstring. +Index: wxPython-4.2.1/wx/lib/masked/ipaddrctrl.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/masked/ipaddrctrl.py ++++ wxPython-4.2.1/wx/lib/masked/ipaddrctrl.py +@@ -23,7 +23,6 @@ user hits '.' when typing. + """ + + import wx +-import six + from wx.lib.masked import BaseMaskedTextCtrl + + # jmg 12/9/03 - when we cut ties with Py 2.2 and earlier, this would +@@ -188,7 +187,7 @@ class IpAddrCtrl( BaseMaskedTextCtrl, Ip + + """ + ## dbg('IpAddrCtrl::SetValue(%s)' % str(value), indent=1) +- if not isinstance(value, six.string_types): ++ if not isinstance(value, str): + ## dbg(indent=0) + raise ValueError('%s must be a string' % str(value)) + +Index: wxPython-4.2.1/wx/lib/masked/maskededit.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/masked/maskededit.py ++++ wxPython-4.2.1/wx/lib/masked/maskededit.py +@@ -813,7 +813,6 @@ import string + import sys + + import wx +-import six + + # jmg 12/9/03 - when we cut ties with Py 2.2 and earlier, this would + # be a good place to implement the 2.3 logger class +@@ -1490,7 +1489,7 @@ class Field: + raise TypeError('%s: choices must be a sequence of strings' % str(self._index)) + elif len( self._choices) > 0: + for choice in self._choices: +- if not isinstance(choice, six.string_types): ++ if not isinstance(choice, str): + ## dbg(indent=0, suspend=0) + raise TypeError('%s: choices must be a sequence of strings' % str(self._index)) + +@@ -1954,7 +1953,7 @@ class MaskedEditMixin: + for key in ('emptyBackgroundColour', 'invalidBackgroundColour', 'validBackgroundColour', + 'foregroundColour', 'signedForegroundColour'): + if key in ctrl_kwargs: +- if isinstance(ctrl_kwargs[key], six.string_types): ++ if isinstance(ctrl_kwargs[key], str): + c = wx.Colour(ctrl_kwargs[key]) + if c.Get() == (-1, -1, -1): + raise TypeError('%s not a legal color specification for %s' % (repr(ctrl_kwargs[key]), key)) +@@ -3062,23 +3061,15 @@ class MaskedEditMixin: + + if key < 256: + char = chr(key) # (must work if we got this far) +- if not six.PY3: +- char = char.decode(self._defaultEncoding) + else: + char = unichr(event.GetUnicodeKey()) + ## dbg('unicode char:', char) + +- excludes = six.text_type() +- if not isinstance(field._excludeChars, six.text_type): +- if six.PY3: +- excludes += field._excludeChars +- else: +- excludes += field._excludeChars.decode(self._defaultEncoding) +- if not isinstance(self._ctrl_constraints, six.text_type): +- if six.PY3: +- excludes += field._excludeChars +- else: +- excludes += self._ctrl_constraints._excludeChars.decode(self._defaultEncoding) ++ excludes = str() ++ if not isinstance(field._excludeChars, str): ++ excludes += field._excludeChars ++ if not isinstance(self._ctrl_constraints, str): ++ excludes += field._excludeChars + else: + excludes += self._ctrl_constraints._excludeChars + +@@ -4634,11 +4625,6 @@ class MaskedEditMixin: + maskChar = self.maskdict[pos] + okchars = self.maskchardict[maskChar] ## entry, get mask approved characters + +- # convert okchars to unicode if required; will force subsequent appendings to +- # result in unicode strings +- if not six.PY3 and not isinstance(okchars, six.text_type): +- okchars = okchars.decode(self._defaultEncoding) +- + field = self._FindField(pos) + if okchars and field._okSpaces: ## Allow spaces? + okchars += " " +@@ -5225,12 +5211,6 @@ class MaskedEditMixin: + left = text[0:pos] + right = text[pos+1:] + +- if not isinstance(char, six.text_type): +- # convert the keyboard constant to a unicode value, to +- # ensure it can be concatenated into the control value: +- if not six.PY3: +- char = char.decode(self._defaultEncoding) +- + newtext = left + char + right + #### dbg('left: "%s"' % left) + #### dbg('right: "%s"' % right) +@@ -5764,8 +5744,6 @@ class MaskedEditMixin: + else: + item = 'selection' + ## dbg('maxlength:', maxlength) +- if not six.PY3 and not isinstance(paste_text, six.text_type): +- paste_text = paste_text.decode(self._defaultEncoding) + + length_considered = len(paste_text) + if length_considered > maxlength: +@@ -5871,9 +5849,6 @@ class MaskedEditMixin: + + if paste_text is not None: + +- if not six.PY3 and not isinstance(paste_text, six.text_type): +- paste_text = paste_text.decode(self._defaultEncoding) +- + ## dbg('paste text: "%s"' % paste_text) + # (conversion will raise ValueError if paste isn't legal) + sel_start, sel_to = self._GetSelection() +Index: wxPython-4.2.1/wx/lib/masked/numctrl.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/masked/numctrl.py ++++ wxPython-4.2.1/wx/lib/masked/numctrl.py +@@ -401,7 +401,6 @@ GetAutoSize() + import copy + + import wx +-import six + + from sys import maxsize + MAXINT = maxsize # (constants should be in upper case) +@@ -1641,7 +1640,7 @@ class NumCtrl(BaseMaskedTextCtrl, NumCtr + ## dbg(indent=0) + return self._template + +- elif isinstance(value, six.string_types): ++ elif isinstance(value, str): + value = self._GetNumValue(value) + ## dbg('cleansed num value: "%s"' % value) + if value == "": +Index: wxPython-4.2.1/wx/lib/masked/timectrl.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/masked/timectrl.py ++++ wxPython-4.2.1/wx/lib/masked/timectrl.py +@@ -281,7 +281,6 @@ IsLimited() + import copy + + import wx +-import six + + from wx.tools.dbg import Logger + from wx.lib.masked import Field, BaseMaskedTextCtrl +@@ -762,8 +761,8 @@ class TimeCtrl(BaseMaskedTextCtrl): + ## dbg('value = "%s"' % value) + + valid = True # assume true +- if isinstance(value, six.string_types): +- value = six.text_type(value) # convert to regular string ++ if isinstance(value, str): ++ value = str(value) # convert to regular string + + # Construct constant wxDateTime, then try to parse the string: + wxdt = wx.DateTime.FromDMY(1, 0, 1970) +@@ -1385,7 +1384,7 @@ class TimeCtrl(BaseMaskedTextCtrl): + if self.IsLimited() and not self.IsInBounds(value): + ## dbg(indent=0) + raise ValueError ( +- 'value %s is not within the bounds of the control' % six.text_type(value) ) ++ 'value %s is not within the bounds of the control' % str(value) ) + ## dbg(indent=0) + return value + +Index: wxPython-4.2.1/wx/lib/mixins/listctrl.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/mixins/listctrl.py ++++ wxPython-4.2.1/wx/lib/mixins/listctrl.py +@@ -33,12 +33,9 @@ + + import locale + import wx +-import six + +-if six.PY3: +- # python 3 lacks cmp: +- def cmp(a, b): +- return (a > b) - (a < b) ++def cmp(a, b): ++ return (a > b) - (a < b) + + #---------------------------------------------------------------------------- + +@@ -161,10 +158,10 @@ class ColumnSorterMixin: + item2 = self.itemDataMap[key2][col] + + #--- Internationalization of string sorting with locale module +- if isinstance(item1, six.text_type) and isinstance(item2, six.text_type): ++ if isinstance(item1, str) and isinstance(item2, str): + # both are unicode (py2) or str (py3) + cmpVal = locale.strcoll(item1, item2) +- elif isinstance(item1, six.binary_type) or isinstance(item2, six.binary_type): ++ elif isinstance(item1, bytes) or isinstance(item2, bytes): + # at least one is a str (py2) or byte (py3) + cmpVal = locale.strcoll(str(item1), str(item2)) + else: +Index: wxPython-4.2.1/wx/lib/multisash.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/multisash.py ++++ wxPython-4.2.1/wx/lib/multisash.py +@@ -21,7 +21,6 @@ + + import wx + +-import six + MV_HOR = 0 + MV_VER = not MV_HOR + +@@ -63,7 +62,7 @@ class MultiSash(wx.Window): + def SetSaveData(self,data): + mod = data['_defChild_mod'] + dChild = mod + '.' + data['_defChild_class'] +- six.exec_('import %s' % mod) ++ exec('import %s' % mod) + self._defChild = eval(dChild) + old = self.child + self.child = MultiSplit(self,self,wx.Point(0,0),self.GetSize()) +@@ -327,7 +326,7 @@ class MultiViewLeaf(wx.Window): + def SetSaveData(self,data): + mod = data['detailClass_mod'] + dChild = mod + '.' + data['detailClass_class'] +- six.exec_('import %s' % mod) ++ exec('import %s' % mod) + detClass = eval(dChild) + self.SetSize(data['x'],data['y'],data['w'],data['h']) + old = self.detail +Index: wxPython-4.2.1/wx/lib/pdfviewer/viewer.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/pdfviewer/viewer.py ++++ wxPython-4.2.1/wx/lib/pdfviewer/viewer.py +@@ -30,7 +30,7 @@ import time + import types + import copy + import shutil +-from six import BytesIO, string_types ++from io import BytesIO + + import wx + +@@ -199,7 +199,7 @@ class pdfViewer(wx.ScrolledWindow): + return BytesIO(stream) + + self.pdfpathname = '' +- if isinstance(pdf_file, string_types): ++ if isinstance(pdf_file, str): + # a filename/path string, save its name + self.pdfpathname = pdf_file + # remove comment from next line to test using a file-like object +@@ -483,7 +483,7 @@ class mupdfProcessor(object): + Could also be a string representing a path to a PDF file. + """ + self.parent = parent +- if isinstance(pdf_file, string_types): ++ if isinstance(pdf_file, str): + # a filename/path string, pass the name to fitz.open + pathname = pdf_file + self.pdfdoc = fitz.open(pathname) +Index: wxPython-4.2.1/wx/lib/printout.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/printout.py ++++ wxPython-4.2.1/wx/lib/printout.py +@@ -27,9 +27,7 @@ import copy + import types + import wx + +-import six +- +-class PrintBase(object): ++class PrintBase: + def SetPrintFont(self, font): # set the DC font parameters + fattr = font["Attr"] + if fattr[0] == 1: +@@ -273,7 +271,7 @@ class PrintTableDraw(wx.ScrolledWindow, + self.column.append(pos_x) + + #module logic expects two dimensional data -- fix input if needed +- if isinstance(self.data, six.string_types): ++ if isinstance(self.data, str): + self.data = [[copy.copy(self.data)]] # a string becomes a single cell + try: + rows = len(self.data) +@@ -282,7 +280,7 @@ class PrintTableDraw(wx.ScrolledWindow, + rows = 1 + first_value = self.data[0] + +- if isinstance(first_value, six.string_types): # a sequence of strings ++ if isinstance(first_value, str): # a sequence of strings + if self.label == [] and self.set_column == []: + data = [] + for x in self.data: #becomes one column +@@ -562,7 +560,7 @@ class PrintTableDraw(wx.ScrolledWindow, + self.col = 0 + max_y = 0 + for vtxt in row_val: +- if not isinstance(vtxt, six.string_types): ++ if not isinstance(vtxt, str): + vtxt = str(vtxt) + self.region = self.column[self.col+1] - self.column[self.col] + self.indent = self.column[self.col] +Index: wxPython-4.2.1/wx/lib/pubsub/core/callables.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/pubsub/core/callables.py ++++ wxPython-4.2.1/wx/lib/pubsub/core/callables.py +@@ -11,13 +11,14 @@ CallArgsInfo regarding its autoTopicArgN + :license: BSD, see LICENSE_BSD_Simple.txt for details. + + """ ++import sys + + from inspect import ismethod, isfunction, signature, Parameter + +-from .. import py2and3 +- + AUTO_TOPIC = '## your listener wants topic name ## (string unlikely to be used by caller)' + ++def getexcobj(): ++ return sys.exc_info()[1] + + def getModule(obj): + """Get the module in which an object was defined. Returns '__main__' +@@ -189,8 +190,7 @@ def getArgs(callable_): + try: + func, firstArgIdx = getRawFunction(callable_) + except ValueError: +- from .. import py2and3 +- exc = py2and3.getexcobj() ++ exc = getexcobj() + raise ListenerMismatchError(str(exc), callable_) + + return CallArgsInfo(func, firstArgIdx) +Index: wxPython-4.2.1/wx/lib/pubsub/core/imp2.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/pubsub/core/imp2.py ++++ wxPython-4.2.1/wx/lib/pubsub/core/imp2.py +@@ -7,14 +7,13 @@ closely. + """ + + import sys +-from .. import py2and3 + + def _resolve_name(name, package, level): + """Return the absolute name of the module to be imported.""" + if not hasattr(package, 'rindex'): + raise ValueError("'package' not set to a string") + dot = len(package) +- for x in py2and3.xrange(level, 1, -1): ++ for x in range(level, 1, -1): + try: + dot = package.rindex('.', 0, dot) + except ValueError: +Index: wxPython-4.2.1/wx/lib/pubsub/core/kwargs/publisher.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/pubsub/core/kwargs/publisher.py ++++ wxPython-4.2.1/wx/lib/pubsub/core/kwargs/publisher.py +@@ -6,7 +6,7 @@ + + from .publisherbase import PublisherBase + from .datamsg import Message +-from .. import (policies, py2and3) ++from .. import (policies) + + + +@@ -42,7 +42,7 @@ class PublisherArg1Stage2(Publisher): + def __init__(self, kwargs, commonArgName): + extra = kwargs.copy() + del extra[commonArgName] +- msg = 'Sender has too many kwargs (%s)' % ( py2and3.keys(extra),) ++ msg = 'Sender has too many kwargs (%s)' % ( extra.keys(),) + RuntimeError.__init__(self, msg) + + class SenderWrongKwargName(RuntimeError): +@@ -60,7 +60,7 @@ class PublisherArg1Stage2(Publisher): + if len(kwarg) > 1: + raise self.SenderTooManyKwargs(kwarg, commonArgName) + elif len(kwarg) == 1 and commonArgName not in kwarg: +- raise self.SenderWrongKwargName( py2and3.keys(kwarg)[0], commonArgName) ++ raise self.SenderWrongKwargName( kwarg.keys()[0], commonArgName) + + data = kwarg.get(commonArgName, None) + kwargs = { commonArgName: self.Msg( _topicName, data) } +Index: wxPython-4.2.1/wx/lib/pubsub/core/kwargs/topicargspecimpl.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/pubsub/core/kwargs/topicargspecimpl.py ++++ wxPython-4.2.1/wx/lib/pubsub/core/kwargs/topicargspecimpl.py +@@ -9,7 +9,6 @@ import weakref + + from .topicutils import (stringize, WeakNone) + from .validatedefnargs import verifySubset +-from .. import py2and3 + + ### Exceptions raised during check() from sendMessage() + +@@ -101,7 +100,7 @@ class ArgsInfo: + """docs is a mapping from arg names to their documentation""" + if not self.isComplete(): + raise +- for arg, doc in py2and3.iteritems(docs): ++ for arg, doc in docs.items(): + self.allDocs[arg] = doc + + def check(self, msgKwargs): +@@ -115,14 +114,14 @@ class ArgsInfo: + hasReqd = (needReqd <= all) + if not hasReqd: + raise SenderMissingReqdMsgDataError( +- self.topicNameTuple, py2and3.keys(msgKwargs), needReqd - all) ++ self.topicNameTuple, msgKwargs.keys(), needReqd - all) + + # check that all other args are among the optional spec + optional = all - needReqd + ok = (optional <= set(self.allOptional)) + if not ok: + raise SenderUnknownMsgDataError( self.topicNameTuple, +- py2and3.keys(msgKwargs), optional - set(self.allOptional) ) ++ msgKwargs.keys(), optional - set(self.allOptional) ) + + def filterArgs(self, msgKwargs): + """Returns a dict which contains only those items of msgKwargs +Index: wxPython-4.2.1/wx/lib/pubsub/core/publisherbase.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/pubsub/core/publisherbase.py ++++ wxPython-4.2.1/wx/lib/pubsub/core/publisherbase.py +@@ -8,8 +8,6 @@ from .topicmgr import ( + TreeConfig + ) + +-from .. import py2and3 +- + + class PublisherBase: + """ +@@ -177,7 +175,7 @@ class PublisherBase: + if topicName is None: + # unsubscribe all listeners from all topics + topicsMap = self.__topicMgr._topicsMap +- for topicName, topicObj in py2and3.iteritems(topicsMap): ++ for topicName, topicObj in topicsMap.items(): + if topicFilter is None or topicFilter(topicName): + tmp = topicObj.unsubscribeAllListeners(listenerFilter) + unsubdListeners.extend(tmp) +Index: wxPython-4.2.1/wx/lib/pubsub/core/topicdefnprovider.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/pubsub/core/topicdefnprovider.py ++++ wxPython-4.2.1/wx/lib/pubsub/core/topicdefnprovider.py +@@ -4,12 +4,11 @@ + """ + + +-import os, re, inspect ++import os, re, inspect, io + from textwrap import TextWrapper, dedent + + from .. import ( + policies, +- py2and3 + ) + from .topicargspec import ( + topicArgsFromCallable, +@@ -129,7 +128,7 @@ class TopicDefnDeserialClass(ITopicDefnD + def getNextTopic(self): + self.__iterStarted = True + try: +- topicNameTuple, topicClassObj = py2and3.nextiter(self.__nextTopic) ++ topicNameTuple, topicClassObj = next(self.__nextTopic) + except StopIteration: + return None + +@@ -357,7 +356,7 @@ class TopicDefnProvider(ITopicDefnProvid + return desc, spec + + def topicNames(self): +- return py2and3.iterkeys(self.__topicDefns) ++ return self.__topicDefns.keys() + + def getTreeDoc(self): + return self.__treeDocs +@@ -428,13 +427,13 @@ def exportTopicTreeSpec(moduleName = Non + if rootTopic is None: + from .. import pub + rootTopic = pub.getDefaultTopicMgr().getRootAllTopics() +- elif py2and3.isstring(rootTopic): ++ elif isintance(rootTopic, str): + from .. import pub + rootTopic = pub.getDefaultTopicMgr().getTopic(rootTopic) + + # create exporter + if moduleName is None: +- capture = py2and3.StringIO() ++ capture = io.StringIO() + TopicTreeSpecPrinter(rootTopic, fileObj=capture, treeDoc=moduleDoc) + return capture.getvalue() + +@@ -485,7 +484,7 @@ class TopicTreeSpecPrinter: + args = dict(width=width, indentStep=indentStep, treeDoc=treeDoc, + footer=footer, fileObj=fileObj) + def fmItem(argName, argVal): +- if py2and3.isstring(argVal): ++ if isinstance(argVal, str): + MIN_OFFSET = 5 + lenAV = width - MIN_OFFSET - len(argName) + if lenAV > 0: +@@ -493,7 +492,7 @@ class TopicTreeSpecPrinter: + elif argName == 'fileObj': + argVal = fileObj.__class__.__name__ + return '# - %s: %s' % (argName, argVal) +- fmtArgs = [fmItem(key, args[key]) for key in sorted(py2and3.iterkeys(args))] ++ fmtArgs = [fmItem(key, args[key]) for key in sorted(args.keys())] + self.__comment = [ + '# Automatically generated by %s(**kwargs).' % self.__class__.__name__, + '# The kwargs were:', +Index: wxPython-4.2.1/wx/lib/pubsub/core/topicmgr.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/pubsub/core/topicmgr.py ++++ wxPython-4.2.1/wx/lib/pubsub/core/topicmgr.py +@@ -40,8 +40,6 @@ from .treeconfig import TreeConfig + from .topicdefnprovider import ITopicDefnProvider + from .topicmgrimpl import getRootTopicSpec + +-from .. import py2and3 +- + + # --------------------------------------------------------- + +@@ -255,7 +253,7 @@ class TopicManager: + def checkAllTopicsHaveMDS(self): + """Check that all topics that have been created for their MDS. + Raise a TopicDefnError if one is found that does not have one.""" +- for topic in py2and3.itervalues(self._topicsMap): ++ for topic in self._topicsMap.values(): + if not topic.hasMDS(): + raise TopicDefnError(topic.getNameTuple()) + +@@ -287,7 +285,7 @@ class TopicManager: + subscribed. Note: the listener can also get messages from any + sub-topic of returned list.""" + assocTopics = [] +- for topicObj in py2and3.itervalues(self._topicsMap): ++ for topicObj in self._topicsMap.values(): + if topicObj.hasListener(listener): + assocTopics.append(topicObj) + return assocTopics +Index: wxPython-4.2.1/wx/lib/pubsub/core/topicobj.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/pubsub/core/topicobj.py ++++ wxPython-4.2.1/wx/lib/pubsub/core/topicobj.py +@@ -4,7 +4,7 @@ Provide the Topic class. + :copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. + :license: BSD, see LICENSE_BSD_Simple.txt for details. + """ +- ++import sys + + from weakref import ref as weakref + +@@ -38,8 +38,8 @@ from .topicargspec import ( + MessageDataSpecError, + ) + +-from .. import py2and3 +- ++def getexcobj(): ++ return sys.exc_info()[1] + + class Topic(PublisherMixin): + """ +@@ -140,7 +140,7 @@ class Topic(PublisherMixin): + self.__parentTopic()._getListenerSpec()) + except MessageDataSpecError: + # discard the lower part of the stack trace +- exc = py2and3.getexcobj() ++ exc = getexcobj() + raise exc + self.__finalize() + +@@ -242,7 +242,7 @@ class Topic(PublisherMixin): + + def getSubtopics(self): + """Get a list of Topic instances that are subtopics of self.""" +- return py2and3.values(self.__subTopics) ++ return list(self.__subTopics.values()) + + def getNumListeners(self): + """Return number of listeners currently subscribed to topic. This is +@@ -262,12 +262,12 @@ class Topic(PublisherMixin): + def getListeners(self): + """Get a copy of list of listeners subscribed to this topic. Safe to iterate over while listeners + get un/subscribed from this topics (such as while sending a message).""" +- return py2and3.keys(self.__listeners) ++ return list(self.__listeners.keys()) + + def getListenersIter(self): + """Get an iterator over listeners subscribed to this topic. Do not use if listeners can be + un/subscribed while iterating. """ +- return py2and3.iterkeys(self.__listeners) ++ return self.__listeners.keys() + + def validate(self, listener): + """Checks whether listener could be subscribed to this topic: +@@ -337,11 +337,11 @@ class Topic(PublisherMixin): + if filter is None: + for listener in self.__listeners: + listener._unlinkFromTopic_() +- unsubd = py2and3.keys(self.__listeners) ++ unsubd = list(self.__listeners.keys()) + self.__listeners = {} + else: + unsubd = [] +- for listener in py2and3.keys(self.__listeners): ++ for listener in list(self.__listeners.keys()): + if filter(listener): + unsubd.append(listener) + listener._unlinkFromTopic_() +@@ -408,7 +408,7 @@ class Topic(PublisherMixin): + handler( listener.name(), topicObj ) + self.__handlingUncaughtListenerExc = False + except Exception: +- exc = py2and3.getexcobj() ++ exc = getexcobj() + #print 'exception raised', exc + self.__handlingUncaughtListenerExc = False + raise ExcHandlerError(listener.name(), topicObj, exc) +@@ -441,7 +441,7 @@ class Topic(PublisherMixin): + self.unsubscribeAllListeners() + self.__parentTopic = None + +- for subName, subObj in py2and3.iteritems(self.__subTopics): ++ for subName, subObj in self.__subTopics.items(): + assert isinstance(subObj, Topic) + #print 'Unlinking %s from parent' % subObj.getName() + subObj.__undefineBranch(topicsMap) +Index: wxPython-4.2.1/wx/lib/pubsub/core/topicutils.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/pubsub/core/topicutils.py ++++ wxPython-4.2.1/wx/lib/pubsub/core/topicutils.py +@@ -5,15 +5,16 @@ Various utilities used by topic-related + :license: BSD, see LICENSE_BSD_Simple.txt for details. + + """ ++import sys + + from textwrap import TextWrapper, dedent + + from .topicexc import TopicNameError + +-from .. import py2and3 +- + __all__ = [] + ++def getexcobj(): ++ return sys.exc_info()[1] + + UNDERSCORE = '_' # topic name can't start with this + # just want something unlikely to clash with user's topic names +@@ -81,7 +82,7 @@ def stringize(topicName): + topic. Otherwise, assume topicName is a tuple and convert it to to a + dotted name i.e. ('a','b','c') => 'a.b.c'. Empty name is not allowed + (ValueError). The reverse operation is tupleize(topicName).""" +- if py2and3.isstring(topicName): ++ if isinstance(topicName, str): + return topicName + + if hasattr(topicName, "msgDataSpec"): +@@ -90,7 +91,7 @@ def stringize(topicName): + try: + name = '.'.join(topicName) + except Exception: +- exc = py2and3.getexcobj() ++ exc = getexcobj() + raise TopicNameError(topicName, str(exc)) + + return name +@@ -105,7 +106,7 @@ def tupleize(topicName): + # then better use isinstance(name, tuple) + if hasattr(topicName, "msgDataSpec"): + topicName = topicName._topicNameStr +- if py2and3.isstring(topicName): ++ if isinstance(topicName, str): + topicTuple = tuple(topicName.split('.')) + else: + topicTuple = tuple(topicName) # assume already tuple of strings +Index: wxPython-4.2.1/wx/lib/pubsub/py2and3.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/pubsub/py2and3.py ++++ /dev/null +@@ -1,608 +0,0 @@ +-"""Utilities for writing code that runs on Python 2 and 3""" +- +-# Copyright (c) 2010-2013 Benjamin Peterson +-# +-# Permission is hereby granted, free of charge, to any person obtaining a copy +-# of this software and associated documentation files (the "Software"), to deal +-# in the Software without restriction, including without limitation the rights +-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +-# copies of the Software, and to permit persons to whom the Software is +-# furnished to do so, subject to the following conditions: +-# +-# The above copyright notice and this permission notice shall be included in all +-# copies or substantial portions of the Software. +-# +-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +-# SOFTWARE. +- +-import operator +-import sys +-import types +- +-__author__ = "Benjamin Peterson " +-__version__ = "1.4.1" +- +- +-# Useful for very coarse version differentiation. +-PY2 = sys.version_info[0] == 2 +-PY3 = sys.version_info[0] == 3 +- +-if PY3: +- string_types = str, +- integer_types = int, +- class_types = type, +- text_type = str +- binary_type = bytes +- +- MAXSIZE = sys.maxsize +-else: +- string_types = basestring, +- integer_types = (int, long) +- class_types = (type, types.ClassType) +- text_type = unicode +- binary_type = str +- +- if sys.platform.startswith("java"): +- # Jython always uses 32 bits. +- MAXSIZE = int((1 << 31) - 1) +- else: +- # It's possible to have sizeof(long) != sizeof(Py_ssize_t). +- class X(object): +- def __len__(self): +- return 1 << 31 +- try: +- len(X()) +- except OverflowError: +- # 32-bit +- MAXSIZE = int((1 << 31) - 1) +- else: +- # 64-bit +- MAXSIZE = int((1 << 63) - 1) +- del X +- +- +-def _add_doc(func, doc): +- """Add documentation to a function.""" +- func.__doc__ = doc +- +- +-def _import_module(name): +- """Import module, returning the module after the last dot.""" +- __import__(name) +- return sys.modules[name] +- +- +-class _LazyDescr(object): +- +- def __init__(self, name): +- self.name = name +- +- def __get__(self, obj, tp): +- result = self._resolve() +- setattr(obj, self.name, result) +- # This is a bit ugly, but it avoids running this again. +- delattr(tp, self.name) +- return result +- +- +-class MovedModule(_LazyDescr): +- +- def __init__(self, name, old, new=None): +- super(MovedModule, self).__init__(name) +- if PY3: +- if new is None: +- new = name +- self.mod = new +- else: +- self.mod = old +- +- def _resolve(self): +- return _import_module(self.mod) +- +- +-class MovedAttribute(_LazyDescr): +- +- def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): +- super(MovedAttribute, self).__init__(name) +- if PY3: +- if new_mod is None: +- new_mod = name +- self.mod = new_mod +- if new_attr is None: +- if old_attr is None: +- new_attr = name +- else: +- new_attr = old_attr +- self.attr = new_attr +- else: +- self.mod = old_mod +- if old_attr is None: +- old_attr = name +- self.attr = old_attr +- +- def _resolve(self): +- module = _import_module(self.mod) +- return getattr(module, self.attr) +- +- +- +-class _MovedItems(types.ModuleType): +- """Lazy loading of moved objects""" +- +- +-_moved_attributes = [ +- MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), +- MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), +- MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), +- MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), +- MovedAttribute("map", "itertools", "builtins", "imap", "map"), +- MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), +- MovedAttribute("reload_module", "__builtin__", "imp", "reload"), +- MovedAttribute("reduce", "__builtin__", "functools"), +- MovedAttribute("StringIO", "StringIO", "io"), +- MovedAttribute("UserString", "UserString", "collections"), +- MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), +- MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), +- MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), +- +- MovedModule("builtins", "__builtin__"), +- MovedModule("configparser", "ConfigParser"), +- MovedModule("copyreg", "copy_reg"), +- MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), +- MovedModule("http_cookies", "Cookie", "http.cookies"), +- MovedModule("html_entities", "htmlentitydefs", "html.entities"), +- MovedModule("html_parser", "HTMLParser", "html.parser"), +- MovedModule("http_client", "httplib", "http.client"), +- MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), +- MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), +- MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), +- MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), +- MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), +- MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), +- MovedModule("cPickle", "cPickle", "pickle"), +- MovedModule("queue", "Queue"), +- MovedModule("reprlib", "repr"), +- MovedModule("socketserver", "SocketServer"), +- MovedModule("tkinter", "Tkinter"), +- MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), +- MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), +- MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), +- MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), +- MovedModule("tkinter_tix", "Tix", "tkinter.tix"), +- MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), +- MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), +- MovedModule("tkinter_colorchooser", "tkColorChooser", +- "tkinter.colorchooser"), +- MovedModule("tkinter_commondialog", "tkCommonDialog", +- "tkinter.commondialog"), +- MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), +- MovedModule("tkinter_font", "tkFont", "tkinter.font"), +- MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), +- MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", +- "tkinter.simpledialog"), +- MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), +- MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), +- MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), +- MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), +- MovedModule("winreg", "_winreg"), +-] +-for attr in _moved_attributes: +- setattr(_MovedItems, attr.name, attr) +-del attr +- +-moves = sys.modules[__name__ + ".moves"] = _MovedItems(__name__ + ".moves") +- +- +- +-class Module_six_moves_urllib_parse(types.ModuleType): +- """Lazy loading of moved objects in six.moves.urllib_parse""" +- +- +-_urllib_parse_moved_attributes = [ +- MovedAttribute("ParseResult", "urlparse", "urllib.parse"), +- MovedAttribute("parse_qs", "urlparse", "urllib.parse"), +- MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), +- MovedAttribute("urldefrag", "urlparse", "urllib.parse"), +- MovedAttribute("urljoin", "urlparse", "urllib.parse"), +- MovedAttribute("urlparse", "urlparse", "urllib.parse"), +- MovedAttribute("urlsplit", "urlparse", "urllib.parse"), +- MovedAttribute("urlunparse", "urlparse", "urllib.parse"), +- MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), +- MovedAttribute("quote", "urllib", "urllib.parse"), +- MovedAttribute("quote_plus", "urllib", "urllib.parse"), +- MovedAttribute("unquote", "urllib", "urllib.parse"), +- MovedAttribute("unquote_plus", "urllib", "urllib.parse"), +- MovedAttribute("urlencode", "urllib", "urllib.parse"), +-] +-for attr in _urllib_parse_moved_attributes: +- setattr(Module_six_moves_urllib_parse, attr.name, attr) +-del attr +- +-sys.modules[__name__ + ".moves.urllib_parse"] = Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse") +-sys.modules[__name__ + ".moves.urllib.parse"] = Module_six_moves_urllib_parse(__name__ + ".moves.urllib.parse") +- +- +-class Module_six_moves_urllib_error(types.ModuleType): +- """Lazy loading of moved objects in six.moves.urllib_error""" +- +- +-_urllib_error_moved_attributes = [ +- MovedAttribute("URLError", "urllib2", "urllib.error"), +- MovedAttribute("HTTPError", "urllib2", "urllib.error"), +- MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), +-] +-for attr in _urllib_error_moved_attributes: +- setattr(Module_six_moves_urllib_error, attr.name, attr) +-del attr +- +-sys.modules[__name__ + ".moves.urllib_error"] = Module_six_moves_urllib_error(__name__ + ".moves.urllib_error") +-sys.modules[__name__ + ".moves.urllib.error"] = Module_six_moves_urllib_error(__name__ + ".moves.urllib.error") +- +- +-class Module_six_moves_urllib_request(types.ModuleType): +- """Lazy loading of moved objects in six.moves.urllib_request""" +- +- +-_urllib_request_moved_attributes = [ +- MovedAttribute("urlopen", "urllib2", "urllib.request"), +- MovedAttribute("install_opener", "urllib2", "urllib.request"), +- MovedAttribute("build_opener", "urllib2", "urllib.request"), +- MovedAttribute("pathname2url", "urllib", "urllib.request"), +- MovedAttribute("url2pathname", "urllib", "urllib.request"), +- MovedAttribute("getproxies", "urllib", "urllib.request"), +- MovedAttribute("Request", "urllib2", "urllib.request"), +- MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), +- MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), +- MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), +- MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), +- MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), +- MovedAttribute("BaseHandler", "urllib2", "urllib.request"), +- MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), +- MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), +- MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), +- MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), +- MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), +- MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), +- MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), +- MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), +- MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), +- MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), +- MovedAttribute("FileHandler", "urllib2", "urllib.request"), +- MovedAttribute("FTPHandler", "urllib2", "urllib.request"), +- MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), +- MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), +- MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), +- MovedAttribute("urlretrieve", "urllib", "urllib.request"), +- MovedAttribute("urlcleanup", "urllib", "urllib.request"), +- MovedAttribute("URLopener", "urllib", "urllib.request"), +- MovedAttribute("FancyURLopener", "urllib", "urllib.request"), +-] +-for attr in _urllib_request_moved_attributes: +- setattr(Module_six_moves_urllib_request, attr.name, attr) +-del attr +- +-sys.modules[__name__ + ".moves.urllib_request"] = Module_six_moves_urllib_request(__name__ + ".moves.urllib_request") +-sys.modules[__name__ + ".moves.urllib.request"] = Module_six_moves_urllib_request(__name__ + ".moves.urllib.request") +- +- +-class Module_six_moves_urllib_response(types.ModuleType): +- """Lazy loading of moved objects in six.moves.urllib_response""" +- +- +-_urllib_response_moved_attributes = [ +- MovedAttribute("addbase", "urllib", "urllib.response"), +- MovedAttribute("addclosehook", "urllib", "urllib.response"), +- MovedAttribute("addinfo", "urllib", "urllib.response"), +- MovedAttribute("addinfourl", "urllib", "urllib.response"), +-] +-for attr in _urllib_response_moved_attributes: +- setattr(Module_six_moves_urllib_response, attr.name, attr) +-del attr +- +-sys.modules[__name__ + ".moves.urllib_response"] = Module_six_moves_urllib_response(__name__ + ".moves.urllib_response") +-sys.modules[__name__ + ".moves.urllib.response"] = Module_six_moves_urllib_response(__name__ + ".moves.urllib.response") +- +- +-class Module_six_moves_urllib_robotparser(types.ModuleType): +- """Lazy loading of moved objects in six.moves.urllib_robotparser""" +- +- +-_urllib_robotparser_moved_attributes = [ +- MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), +-] +-for attr in _urllib_robotparser_moved_attributes: +- setattr(Module_six_moves_urllib_robotparser, attr.name, attr) +-del attr +- +-sys.modules[__name__ + ".moves.urllib_robotparser"] = Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib_robotparser") +-sys.modules[__name__ + ".moves.urllib.robotparser"] = Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser") +- +- +-class Module_six_moves_urllib(types.ModuleType): +- """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" +- parse = sys.modules[__name__ + ".moves.urllib_parse"] +- error = sys.modules[__name__ + ".moves.urllib_error"] +- request = sys.modules[__name__ + ".moves.urllib_request"] +- response = sys.modules[__name__ + ".moves.urllib_response"] +- robotparser = sys.modules[__name__ + ".moves.urllib_robotparser"] +- +- +-sys.modules[__name__ + ".moves.urllib"] = Module_six_moves_urllib(__name__ + ".moves.urllib") +- +- +-def add_move(move): +- """Add an item to six.moves.""" +- setattr(_MovedItems, move.name, move) +- +- +-def remove_move(name): +- """Remove item from six.moves.""" +- try: +- delattr(_MovedItems, name) +- except AttributeError: +- try: +- del moves.__dict__[name] +- except KeyError: +- raise AttributeError("no such move, %r" % (name,)) +- +- +-if PY3: +- _meth_func = "__func__" +- _meth_self = "__self__" +- +- _func_closure = "__closure__" +- _func_code = "__code__" +- _func_defaults = "__defaults__" +- _func_globals = "__globals__" +- +- _iterkeys = "keys" +- _itervalues = "values" +- _iteritems = "items" +- _iterlists = "lists" +-else: +- _meth_func = "im_func" +- _meth_self = "im_self" +- +- _func_closure = "func_closure" +- _func_code = "func_code" +- _func_defaults = "func_defaults" +- _func_globals = "func_globals" +- +- _iterkeys = "iterkeys" +- _itervalues = "itervalues" +- _iteritems = "iteritems" +- _iterlists = "iterlists" +- +- +-try: +- advance_iterator = next +-except NameError: +- def advance_iterator(it): +- return it.next() +-next = advance_iterator +- +- +-try: +- callable = callable +-except NameError: +- def callable(obj): +- return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) +- +- +-if PY3: +- def get_unbound_function(unbound): +- return unbound +- +- create_bound_method = types.MethodType +- +- Iterator = object +-else: +- def get_unbound_function(unbound): +- return unbound.im_func +- +- def create_bound_method(func, obj): +- return types.MethodType(func, obj, obj.__class__) +- +- class Iterator(object): +- +- def next(self): +- return type(self).__next__(self) +- +- callable = callable +-_add_doc(get_unbound_function, +- """Get the function out of a possibly unbound function""") +- +- +-get_method_function = operator.attrgetter(_meth_func) +-get_method_self = operator.attrgetter(_meth_self) +-get_function_closure = operator.attrgetter(_func_closure) +-get_function_code = operator.attrgetter(_func_code) +-get_function_defaults = operator.attrgetter(_func_defaults) +-get_function_globals = operator.attrgetter(_func_globals) +- +- +-def iterkeys(d, **kw): +- """Return an iterator over the keys of a dictionary.""" +- return iter(getattr(d, _iterkeys)(**kw)) +- +-def itervalues(d, **kw): +- """Return an iterator over the values of a dictionary.""" +- return iter(getattr(d, _itervalues)(**kw)) +- +-def iteritems(d, **kw): +- """Return an iterator over the (key, value) pairs of a dictionary.""" +- return iter(getattr(d, _iteritems)(**kw)) +- +-def iterlists(d, **kw): +- """Return an iterator over the (key, [values]) pairs of a dictionary.""" +- return iter(getattr(d, _iterlists)(**kw)) +- +- +-if PY3: +- def b(s): +- return s.encode("latin-1") +- def u(s): +- return s +- unichr = chr +- if sys.version_info[1] <= 1: +- def int2byte(i): +- return bytes((i,)) +- else: +- # This is about 2x faster than the implementation above on 3.2+ +- int2byte = operator.methodcaller("to_bytes", 1, "big") +- byte2int = operator.itemgetter(0) +- indexbytes = operator.getitem +- iterbytes = iter +- import io +- StringIO = io.StringIO +- BytesIO = io.BytesIO +-else: +- def b(s): +- return s +- def u(s): +- return unicode(s, "unicode_escape") +- unichr = unichr +- int2byte = chr +- def byte2int(bs): +- return ord(bs[0]) +- def indexbytes(buf, i): +- return ord(buf[i]) +- def iterbytes(buf): +- return (ord(byte) for byte in buf) +- import StringIO +- StringIO = BytesIO = StringIO.StringIO +-_add_doc(b, """Byte literal""") +-_add_doc(u, """Text literal""") +- +- +-if PY3: +- import builtins +- exec_ = getattr(builtins, "exec") +- +- +- def reraise(tp, value, tb=None): +- if value.__traceback__ is not tb: +- raise value.with_traceback(tb) +- raise value +- +- +- print_ = getattr(builtins, "print") +- del builtins +- +-else: +- def exec_(_code_, _globs_=None, _locs_=None): +- """Execute code in a namespace.""" +- if _globs_ is None: +- frame = sys._getframe(1) +- _globs_ = frame.f_globals +- if _locs_ is None: +- _locs_ = frame.f_locals +- del frame +- elif _locs_ is None: +- _locs_ = _globs_ +- exec("""exec _code_ in _globs_, _locs_""") +- +- +- exec_("""def reraise(tp, value, tb=None): +- raise tp, value, tb +-""") +- +- +- def print_(*args, **kwargs): +- """The new-style print function.""" +- fp = kwargs.pop("file", sys.stdout) +- if fp is None: +- return +- def write(data): +- if not isinstance(data, basestring): +- data = str(data) +- fp.write(data) +- want_unicode = False +- sep = kwargs.pop("sep", None) +- if sep is not None: +- if isinstance(sep, unicode): +- want_unicode = True +- elif not isinstance(sep, str): +- raise TypeError("sep must be None or a string") +- end = kwargs.pop("end", None) +- if end is not None: +- if isinstance(end, unicode): +- want_unicode = True +- elif not isinstance(end, str): +- raise TypeError("end must be None or a string") +- if kwargs: +- raise TypeError("invalid keyword arguments to print()") +- if not want_unicode: +- for arg in args: +- if isinstance(arg, unicode): +- want_unicode = True +- break +- if want_unicode: +- newline = unicode("\n") +- space = unicode(" ") +- else: +- newline = "\n" +- space = " " +- if sep is None: +- sep = space +- if end is None: +- end = newline +- for i, arg in enumerate(args): +- if i: +- write(sep) +- write(arg) +- write(end) +- +-_add_doc(reraise, """Reraise an exception.""") +- +- +-def with_metaclass(meta, *bases): +- """Create a base class with a metaclass.""" +- return meta("NewBase", bases, {}) +- +-def add_metaclass(metaclass): +- """Class decorator for creating a class with a metaclass.""" +- def wrapper(cls): +- orig_vars = cls.__dict__.copy() +- orig_vars.pop('__dict__', None) +- orig_vars.pop('__weakref__', None) +- for slots_var in orig_vars.get('__slots__', ()): +- orig_vars.pop(slots_var) +- return metaclass(cls.__name__, cls.__bases__, orig_vars) +- return wrapper +- +-def getexcobj(): +- return sys.exc_info()[1] +- +-if PY3: +- xrange = range +-else: +- xrange = xrange +- +-if PY3: +- def keys(dictObj): +- return list(dictObj.keys()) +- def values(dictObj): +- return list(dictObj.values()) +- def nextiter(container): +- return next(container) +-else: +- def keys(dictObj): +- return dictObj.keys() +- def values(dictObj): +- return dictObj.values() +- def nextiter(container): +- return container.next() +- +-if PY3: +- def isstring(obj): +- return isinstance(obj, str) +-else: +- def isstring(obj): +- return isinstance(obj, (str, unicode)) +- +Index: wxPython-4.2.1/wx/lib/pubsub/utils/misc.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/pubsub/utils/misc.py ++++ wxPython-4.2.1/wx/lib/pubsub/utils/misc.py +@@ -7,7 +7,6 @@ printTreeDocs and printTreeSpec. + """ + + import sys +-from .. import py2and3 + + __all__ = ('printImported', 'StructMsg', 'Callback', 'Enum' ) + +@@ -16,7 +15,7 @@ def printImported(): + """Output a list of pubsub modules imported so far""" + ll = sorted([mod for mod in sys.modules if mod.find('pubsub') >= 0]) + +- py2and3.print_('\n'.join(ll)) ++ print('\n'.join(ll)) + + + class StructMsg: +Index: wxPython-4.2.1/wx/lib/pubsub/utils/xmltopicdefnprovider.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/pubsub/utils/xmltopicdefnprovider.py ++++ wxPython-4.2.1/wx/lib/pubsub/utils/xmltopicdefnprovider.py +@@ -56,7 +56,6 @@ from ..core.topicdefnprovider import ( + ArgSpecGiven, + TOPIC_TREE_FROM_STRING, + ) +-from .. import py2and3 + + try: + from elementtree import ElementTree as ET +@@ -80,7 +79,7 @@ def _get_elem(elem): + try: + elem = ET.fromstring(elem) + except: +- py2and3.print_("Value Error", elem) ++ print("Value Error", elem) + raise ValueError("Cannot convert to element") + return elem + +@@ -160,7 +159,7 @@ class XmlTopicDefnProvider(ITopicDefnPro + return self._topics.get(topicNameTuple, (None, None)) + + def topicNames(self): +- return py2and3.iterkeys(self._topics) # dict_keys iter in 3, list in 2 ++ return self._topics.keys() + + def getTreeDoc(self): + return self._treeDoc +@@ -257,7 +256,7 @@ def exportTopicTreeSpecXml(moduleName=No + if rootTopic is None: + from .. import pub + rootTopic = pub.getDefaultTopicTreeRoot() +- elif py2and3.isstring(rootTopic): ++ elif isintance(rootTopic, str): + from .. import pub + rootTopic = pub.getTopic(rootTopic) + +Index: wxPython-4.2.1/wx/lib/rcsizer.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/rcsizer.py ++++ wxPython-4.2.1/wx/lib/rcsizer.py +@@ -33,9 +33,7 @@ encouraged to switch. + import operator + import wx + +-import six +-if six.PY3: +- from functools import reduce as reduce ++from functools import reduce as reduce + + # After the lib and demo no longer uses this sizer enable this warning... + +Index: wxPython-4.2.1/wx/lib/softwareupdate.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/softwareupdate.py ++++ wxPython-4.2.1/wx/lib/softwareupdate.py +@@ -30,14 +30,8 @@ import wx + import sys + import os + import atexit +-import six +- +-if six.PY3: +- from urllib.request import urlopen +- from urllib.error import URLError +-else: +- from urllib2 import urlopen +- from urllib2 import URLError ++from urllib.request import urlopen ++from urllib.error import URLError + + from wx.lib.dialogs import MultiMessageBox + +Index: wxPython-4.2.1/wx/lib/wxcairo/wx_pycairo.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/wxcairo/wx_pycairo.py ++++ wxPython-4.2.1/wx/lib/wxcairo/wx_pycairo.py +@@ -16,7 +16,6 @@ wx.lib.wxcairo implementation functions + """ + + import wx +-from six import PY3 + + import cairo + import ctypes +@@ -413,16 +412,10 @@ def _loadPycairoAPI(): + if not hasattr(cairo, 'CAPI'): + return + +- if PY3: +- PyCapsule_GetPointer = ctypes.pythonapi.PyCapsule_GetPointer +- PyCapsule_GetPointer.argtypes = [ctypes.py_object, ctypes.c_char_p] +- PyCapsule_GetPointer.restype = ctypes.c_void_p +- ptr = PyCapsule_GetPointer(cairo.CAPI, b'cairo.CAPI') +- else: +- PyCObject_AsVoidPtr = ctypes.pythonapi.PyCObject_AsVoidPtr +- PyCObject_AsVoidPtr.argtypes = [ctypes.py_object] +- PyCObject_AsVoidPtr.restype = ctypes.c_void_p +- ptr = PyCObject_AsVoidPtr(cairo.CAPI) ++ PyCapsule_GetPointer = ctypes.pythonapi.PyCapsule_GetPointer ++ PyCapsule_GetPointer.argtypes = [ctypes.py_object, ctypes.c_char_p] ++ PyCapsule_GetPointer.restype = ctypes.c_void_p ++ ptr = PyCapsule_GetPointer(cairo.CAPI, b'cairo.CAPI') + pycairoAPI = ctypes.cast(ptr, ctypes.POINTER(Pycairo_CAPI)).contents + + #---------------------------------------------------------------------------- +Index: wxPython-4.2.1/wx/py/filling.py +=================================================================== +--- wxPython-4.2.1.orig/wx/py/filling.py ++++ wxPython-4.2.1/wx/py/filling.py +@@ -2,10 +2,8 @@ + the local namespace or any object.""" + + __author__ = "Patrick K. O'Brien " +-# Tags: py3-port + + import wx +-import six + + from . import dispatcher + from . import editwindow +@@ -115,13 +113,13 @@ class FillingTree(wx.TreeCtrl): + busy = wx.BusyCursor() + otype = type(obj) + if (isinstance(obj, dict) +- or 'BTrees' in six.text_type(otype) ++ or 'BTrees' in str(otype) + and hasattr(obj, 'keys')): + return obj + d = {} + if isinstance(obj, (list, tuple)): + for n in range(len(obj)): +- key = '[' + six.text_type(n) + ']' ++ key = '[' + str(n) + ']' + d[key] = obj[n] + if otype not in COMMONTYPES: + for key in introspect.getAttributeNames(obj): +@@ -140,14 +138,14 @@ class FillingTree(wx.TreeCtrl): + children = self.objGetChildren(obj) + if not children: + return +- keys = sorted(children, key=lambda x: six.text_type(x).lower()) ++ keys = sorted(children, key=lambda x: str(x).lower()) + for key in keys: +- itemtext = six.text_type(key) ++ itemtext = str(key) + # Show string dictionary items with single quotes, except + # for the first level of items, if they represent a + # namespace. + if isinstance(obj, dict) \ +- and isinstance(key, six.string_types) \ ++ and isinstance(key, str) \ + and (item != self.root + or (item == self.root and not self.rootIsNamespace)): + itemtext = repr(key) +@@ -170,12 +168,12 @@ class FillingTree(wx.TreeCtrl): + otype = type(obj) + text = '' + text += self.getFullName(item) +- text += '\n\nType: ' + six.text_type(otype) ++ text += '\n\nType: ' + str(otype) + try: +- value = six.text_type(obj) ++ value = str(obj) + except Exception: + value = '' +- if isinstance(obj, six.string_types): ++ if isinstance(obj, str): + value = repr(obj) + text += u'\n\nValue: ' + value + if otype not in SIMPLETYPES: +@@ -184,7 +182,7 @@ class FillingTree(wx.TreeCtrl): + inspect.getdoc(obj).strip() + '"""' + except Exception: + pass +- if isinstance(obj, six.class_types): ++ if isinstance(obj, type): + try: + text += '\n\nClass Definition:\n\n' + \ + inspect.getsource(obj.__class__) +@@ -209,7 +207,7 @@ class FillingTree(wx.TreeCtrl): + # Apply dictionary syntax to dictionary items, except the root + # and first level children of a namespace. + if ((isinstance(obj, dict) +- or 'BTrees' in six.text_type(type(obj)) ++ or 'BTrees' in str(type(obj)) + and hasattr(obj, 'keys')) + and ((item != self.root and parent != self.root) + or (parent == self.root and not self.rootIsNamespace))): +Index: wxPython-4.2.1/wx/py/images.py +=================================================================== +--- wxPython-4.2.1.orig/wx/py/images.py ++++ wxPython-4.2.1/wx/py/images.py +@@ -3,7 +3,7 @@ + __author__ = "Patrick K. O'Brien / David Mashburn " + + import wx +-from six import BytesIO ++from io import BytesIO + + def getPyIcon(shellName='PyCrust'): + icon = wx.Icon() +Index: wxPython-4.2.1/wx/py/interpreter.py +=================================================================== +--- wxPython-4.2.1.orig/wx/py/interpreter.py ++++ wxPython-4.2.1/wx/py/interpreter.py +@@ -10,7 +10,6 @@ from code import InteractiveInterpreter, + from . import dispatcher + from . import introspect + import wx +-import six + + class Interpreter(InteractiveInterpreter): + """Interpreter based on code.InteractiveInterpreter.""" +@@ -25,7 +24,7 @@ class Interpreter(InteractiveInterpreter + self.stdout = stdout + self.stderr = stderr + if rawin: +- from six.moves import builtins ++ import builtins + builtins.raw_input = rawin + del builtins + if showInterpIntro: +@@ -56,14 +55,6 @@ class Interpreter(InteractiveInterpreter + commandBuffer until we have a complete command. If not, we + delete that last list.""" + +- # In case the command is unicode try encoding it +- if not six.PY3: +- if type(command) == unicode: +- try: +- command = command.encode('utf-8') +- except UnicodeEncodeError: +- pass # otherwise leave it alone +- + if not self.more: + try: del self.commandBuffer[-1] + except IndexError: pass +Index: wxPython-4.2.1/wx/py/introspect.py +=================================================================== +--- wxPython-4.2.1.orig/wx/py/introspect.py ++++ wxPython-4.2.1/wx/py/introspect.py +@@ -9,7 +9,7 @@ import inspect + import tokenize + import types + import wx +-from six import BytesIO, PY3, string_types ++from io import BytesIO + + def getAutoCompleteList(command='', locals=None, includeMagic=1, + includeSingle=1, includeDouble=1): +@@ -179,7 +179,7 @@ def getCallTip(command='', locals=None): + try: + argspec = str(inspect.signature(obj)) # PY35 or later + except AttributeError: +- argspec = inspect.getargspec(obj) if not PY3 else inspect.getfullargspec(obj) ++ argspec = inspect.getfullargspec(obj) + argspec = inspect.formatargspec(*argspec) + if dropSelf: + # The first parameter to a method is a reference to an +@@ -269,7 +269,7 @@ def getRoot(command, terminator=None): + line = token[4] + if tokentype in (tokenize.ENDMARKER, tokenize.NEWLINE): + continue +- if PY3 and tokentype is tokenize.ENCODING: ++ if tokentype is tokenize.ENCODING: + line = lastline + break + if tokentype in (tokenize.NAME, tokenize.STRING, tokenize.NUMBER) \ +@@ -315,7 +315,7 @@ def getTokens(command): + """Return list of token tuples for command.""" + + # In case the command is unicode try encoding it +- if isinstance(command, string_types): ++ if isinstance(command, str): + try: + command = command.encode('utf-8') + except UnicodeEncodeError: +@@ -329,13 +329,8 @@ def getTokens(command): + # tokens = [token for token in tokenize.generate_tokens(f.readline)] + # because of need to append as much as possible before TokenError. + try: +- if not PY3: +- def eater(*args): +- tokens.append(args) +- tokenize.tokenize_loop(f.readline, eater) +- else: +- for t in tokenize.tokenize(f.readline): +- tokens.append(t) ++ for t in tokenize.tokenize(f.readline): ++ tokens.append(t) + except tokenize.TokenError: + # This is due to a premature EOF, which we expect since we are + # feeding in fragments of Python code. +Index: wxPython-4.2.1/wx/py/shell.py +=================================================================== +--- wxPython-4.2.1.orig/wx/py/shell.py ++++ wxPython-4.2.1/wx/py/shell.py +@@ -8,7 +8,6 @@ __author__ = "Patrick K. O'Brien '3': +- output = ' %s' % part +- else: +- output = ' "%s"' % part ++ output = ' %s' % part + if not data: + output += ")" + lines.append(output) +Index: wxPython-4.2.1/wx/tools/pywxrc.py +=================================================================== +--- wxPython-4.2.1.orig/wx/tools/pywxrc.py ++++ wxPython-4.2.1/wx/tools/pywxrc.py +@@ -33,7 +33,9 @@ Usage: python pywxrc.py -h + + import sys, os, getopt, glob, re + import xml.dom.minidom as minidom +-from six import print_, byte2int ++ ++import operator ++byte2int = operator.itemgetter(0) + + #---------------------------------------------------------------------- + +@@ -286,7 +288,7 @@ class XmlResourceCompiler: + gettextStrings += self.FindStringsInNode(resourceDocument.firstChild) + + # now write it all out +- print_(self.templates.FILE_HEADER, file=outputFile) ++ print(self.templates.FILE_HEADER, file=outputFile) + + # Note: Technically it is not legal to have anything other + # than ascii for class and variable names, but since the user +@@ -295,23 +297,23 @@ class XmlResourceCompiler: + # later when they try to run the program. + if subclasses: + subclasses = self.ReplaceBlocks(u"\n".join(subclasses)) +- print_(subclasses, file=outputFile) ++ print(subclasses, file=outputFile) + if classes: + classes = self.ReplaceBlocks(u"\n".join(classes)) +- print_(classes, file=outputFile) ++ print(classes, file=outputFile) + +- print_(self.templates.INIT_RESOURE_HEADER, file=outputFile) ++ print(self.templates.INIT_RESOURE_HEADER, file=outputFile) + if embedResources: +- print_(self.templates.PREPARE_MEMFS, file=outputFile) ++ print(self.templates.PREPARE_MEMFS, file=outputFile) + resources = u"\n".join(resources) +- print_(resources, file=outputFile) ++ print(resources, file=outputFile) + + if generateGetText: + # gettextStrings is a list of unicode strings as returned by ConvertText + conversions = [u' _("%s")' % s for s in gettextStrings] + conversion_block = u"\n".join(conversions) + conversion_func = self.templates.GETTEXT_DUMMY_FUNC % conversion_block +- print_(conversion_func, file=outputFile) ++ print(conversion_func, file=outputFile) + + #------------------------------------------------------------------- + +@@ -327,7 +329,7 @@ class XmlResourceCompiler: + strings = self.FindStringsInNode(resource) + # strings is a list of unicode strings as returned by ConvertText + strings = ['_("%s");' % s for s in strings] +- print_("\n".join(strings), file=outputFile) ++ print("\n".join(strings), file=outputFile) + + #------------------------------------------------------------------- + +@@ -940,10 +942,10 @@ def main(args=None): + + + except IOError as exc: +- print_("%s." % str(exc), file=sys.stderr) ++ print("%s." % str(exc), file=sys.stderr) + else: + if outputFilename != "-": +- print_("Resources written to %s." % outputFilename, file=sys.stderr) ++ print("Resources written to %s." % outputFilename, file=sys.stderr) + + if __name__ == "__main__": + main(sys.argv[1:]) +Index: wxPython-4.2.1/wx/tools/wxget.py +=================================================================== +--- wxPython-4.2.1.orig/wx/tools/wxget.py ++++ wxPython-4.2.1/wx/tools/wxget.py +@@ -26,22 +26,15 @@ Where URL is a file URL and the optional + download to, (default is to prompt the user). + The --trusted option can be used to suppress certificate checks. + """ +-from __future__ import (division, absolute_import, print_function, unicode_literals) +- + import sys + import os + import wx + import subprocess + import ssl + +-if sys.version_info >= (3,): +- from urllib.error import (HTTPError, URLError) +- import urllib.request as urllib2 +- import urllib.parse as urlparse +-else: +- import urllib2 +- from urllib2 import (HTTPError, URLError) +- import urlparse ++from urllib.error import (HTTPError, URLError) ++import urllib.request as urllib2 ++import urllib.parse as urlparse + + try: + import pip +Index: wxPython-4.2.1/wx/tools/wxget_docs_demo.py +=================================================================== +--- wxPython-4.2.1.orig/wx/tools/wxget_docs_demo.py ++++ wxPython-4.2.1/wx/tools/wxget_docs_demo.py +@@ -26,23 +26,15 @@ launch it. + + Use: doc|demo --force to force a fresh download. + """ +-from __future__ import (division, absolute_import, print_function, unicode_literals) +- + import sys + import os + import subprocess + import webbrowser + import tarfile +-if sys.version_info >= (3,): +- from urllib.error import HTTPError +- import urllib.request as urllib2 +- import urllib.parse as urlparse +- from urllib.request import pathname2url +-else: +- import urllib2 +- from urllib2 import HTTPError +- import urlparse +- from urllib import pathname2url ++from urllib.error import HTTPError ++import urllib.request as urllib2 ++import urllib.parse as urlparse ++from urllib.request import pathname2url + + import wx + from wx.tools import wxget +Index: wxPython-4.2.1/wx/lib/agw/aui/aui_constants.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/agw/aui/aui_constants.py ++++ wxPython-4.2.1/wx/lib/agw/aui/aui_constants.py +@@ -2594,16 +2594,7 @@ SWITCHER_TEXT_MARGIN_Y = 1 + if __name__ == '__main__': + # Easy image extraction. + import sys +- if sys.version_info[0] == 2: +- PY2 = True +- PY3 = False +- elif sys.version_info[0] == 3: +- PY2 = False +- PY3 = True +- if PY2: +- answer = int(raw_input('Enter 1 to extract all bitmaps: ')) +- elif PY3: +- answer = int(input('Enter 1 to extract all bitmaps: ')) ++ answer = int(input('Enter 1 to extract all bitmaps: ')) + if answer == 1: + app = wx.App(0) + import os +@@ -2622,7 +2613,4 @@ if __name__ == '__main__': + except Exception: + pass + app.MainLoop() +- if PY2: +- raw_input('Press Enter To Exit.') +- elif PY3: +- input('Press Enter To Exit.') +\ No newline at end of file ++ input('Press Enter To Exit.') +Index: wxPython-4.2.1/wx/lib/agw/aui/auibar.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/agw/aui/auibar.py ++++ wxPython-4.2.1/wx/lib/agw/aui/auibar.py +@@ -31,9 +31,6 @@ import wx + + from .aui_utilities import BitmapFromBits, StepColour, GetLabelSize + from .aui_utilities import GetBaseColour, MakeDisabledBitmap +- +-import six +- + from .aui_constants import * + + +@@ -68,7 +65,7 @@ class CommandToolBarEvent(wx.PyCommandEv + :param integer `win_id`: the window identification number. + """ + +- if type(command_type) in six.integer_types: ++ if type(command_type) is int: + wx.PyCommandEvent.__init__(self, command_type, win_id) + else: + wx.PyCommandEvent.__init__(self, command_type.GetEventType(), command_type.GetId()) +@@ -158,7 +155,7 @@ class AuiToolBarEvent(CommandToolBarEven + + CommandToolBarEvent.__init__(self, command_type, win_id) + +- if type(command_type) in six.integer_types: ++ if type(command_type) is int: + self.notify = wx.NotifyEvent(command_type, win_id) + else: + self.notify = wx.NotifyEvent(command_type.GetEventType(), command_type.GetId()) +Index: wxPython-4.2.1/wx/lib/agw/aui/auibook.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/agw/aui/auibook.py ++++ wxPython-4.2.1/wx/lib/agw/aui/auibook.py +@@ -32,7 +32,6 @@ import wx + import datetime + + from wx.lib.expando import ExpandoTextCtrl +-import six + + from . import tabart as TA + +@@ -392,7 +391,7 @@ class CommandNotebookEvent(wx.PyCommandE + :param integer `win_id`: the window identification number. + """ + +- if type(command_type) in six.integer_types: ++ if type(command_type) is int: + wx.PyCommandEvent.__init__(self, command_type, win_id) + else: + wx.PyCommandEvent.__init__(self, command_type.GetEventType(), command_type.GetId()) +@@ -525,7 +524,7 @@ class AuiNotebookEvent(CommandNotebookEv + + CommandNotebookEvent.__init__(self, command_type, win_id) + +- if type(command_type) in six.integer_types: ++ if type(command_type) is int: + self.notify = wx.NotifyEvent(command_type, win_id) + else: + self.notify = wx.NotifyEvent(command_type.GetEventType(), command_type.GetId()) +@@ -1174,7 +1173,7 @@ class AuiTabContainer(object): + :param `wndOrInt`: an instance of :class:`wx.Window` or an integer specifying a tab index. + """ + +- if type(wndOrInt) in six.integer_types: ++ if type(wndOrInt) is int: + + if wndOrInt >= len(self._pages): + return False +@@ -4080,7 +4079,7 @@ class AuiNotebook(wx.Panel): + if page >= self._tabs.GetPageCount(): + return False + +- if not isinstance(image, six.integer_types): ++ if not isinstance(image, int): + raise Exception("The image parameter must be an integer, you passed " \ + "%s"%repr(image)) + +Index: wxPython-4.2.1/wx/lib/agw/persist/persist_constants.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/agw/persist/persist_constants.py ++++ wxPython-4.2.1/wx/lib/agw/persist/persist_constants.py +@@ -12,7 +12,6 @@ This module contains all the constants u + + import wx + import wx.dataview as dv +-import six + + # ----------------------------------------------------------------------------------- # + # PersistenceManager styles +@@ -33,14 +32,14 @@ BAD_DEFAULT_NAMES = ["widget", "wxSpinBu + for name in dir(wx): + if "NameStr" in name: + val = getattr(wx, name) +- if six.PY3 and isinstance(val, bytes): ++ if isinstance(val, bytes): + val = val.decode('utf-8') + BAD_DEFAULT_NAMES.append(val) + + for name in dir(dv): + if "NameStr" in name: + val = getattr(dv, name) +- if six.PY3 and isinstance(val, bytes): ++ if isinstance(val, bytes): + val = val.decode('utf-8') + BAD_DEFAULT_NAMES.append(val) + +Index: wxPython-4.2.1/wx/lib/agw/persist/persistencemanager.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/agw/persist/persistencemanager.py ++++ wxPython-4.2.1/wx/lib/agw/persist/persistencemanager.py +@@ -35,7 +35,6 @@ import datetime + + import wx + import wx.adv +-import six + + from .persist_handlers import FindHandler, HasCtrlHandler + +@@ -44,7 +43,7 @@ from .persist_constants import PM_DEFAUL + + # ----------------------------------------------------------------------------------- # + +-class PersistentObject(object): ++class PersistentObject: + """ + :class:`PersistentObject`: ABC for anything persistent. + +@@ -785,10 +784,10 @@ class PersistenceManager(object): + kind = repr(value.__class__).split("'")[1] + + if self._customConfigHandler is not None: +- result = self._customConfigHandler.SaveValue(self.GetKey(obj, keyName), repr((kind, six.text_type(value)))) ++ result = self._customConfigHandler.SaveValue(self.GetKey(obj, keyName), repr((kind, str(value)))) + else: + config = self.GetPersistenceFile() +- result = config.Write(self.GetKey(obj, keyName), repr((kind, six.text_type(value)))) ++ result = config.Write(self.GetKey(obj, keyName), repr((kind, str(value)))) + config.Flush() + + return result +Index: wxPython-4.2.1/wx/lib/agw/ribbon/bar.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/agw/ribbon/bar.py ++++ wxPython-4.2.1/wx/lib/agw/ribbon/bar.py +@@ -98,8 +98,6 @@ See Also + import wx + from functools import cmp_to_key + +-import six +- + from .control import RibbonControl + + from .art_internal import RibbonPageTabInfo +@@ -607,7 +605,7 @@ class RibbonBar(RibbonControl): + def SetActivePage(self, page): + """ See comments on :meth:`~RibbonBar.SetActivePageByIndex` and :meth:`~RibbonBar.SetActivePageByPage`. """ + +- if isinstance(page, six.integer_types): ++ if isinstance(page, int): + return self.SetActivePageByIndex(page) + + return self.SetActivePageByPage(page) +Index: wxPython-4.2.1/wx/lib/agw/ribbon/buttonbar.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/agw/ribbon/buttonbar.py ++++ wxPython-4.2.1/wx/lib/agw/ribbon/buttonbar.py +@@ -46,8 +46,6 @@ Event Name + + import wx + +-import six +- + from .control import RibbonControl + from .art import * + +@@ -345,7 +343,7 @@ class RibbonButtonBar(RibbonControl): + if not bitmap.IsOk() and not bitmap_small.IsOk(): + raise Exception("Invalid main bitmap") + +- if not isinstance(help_string, six.string_types): ++ if not isinstance(help_string, str): + raise Exception("Invalid help string parameter") + + if not self._buttons: +Index: wxPython-4.2.1/wx/lib/agw/aui/framemanager.py +=================================================================== +--- wxPython-4.2.1.orig/wx/lib/agw/aui/framemanager.py ++++ wxPython-4.2.1/wx/lib/agw/aui/framemanager.py +@@ -105,8 +105,6 @@ except ImportError: # clock is removed + from time import clock as perf_counter + import warnings + +-import six +- + from . import auibar + from . import auibook + +@@ -987,7 +985,7 @@ class AuiPaneInfo(object): + ret = self.MinSize1(arg1) + elif isinstance(arg1, tuple): + ret = self.MinSize1(wx.Size(*arg1)) +- elif isinstance(arg1, six.integer_types) and arg2 is not None: ++ elif isinstance(arg1, int) and arg2 is not None: + ret = self.MinSize2(arg1, arg2) + else: + raise Exception("Invalid argument passed to `MinSize`: arg1=%s, arg2=%s" % (repr(arg1), repr(arg2))) +@@ -1028,7 +1026,7 @@ class AuiPaneInfo(object): + ret = self.MaxSize1(arg1) + elif isinstance(arg1, tuple): + ret = self.MaxSize1(wx.Size(*arg1)) +- elif isinstance(arg1, six.integer_types) and arg2 is not None: ++ elif isinstance(arg1, int) and arg2 is not None: + ret = self.MaxSize2(arg1, arg2) + else: + raise Exception("Invalid argument passed to `MaxSize`: arg1=%s, arg2=%s" % (repr(arg1), repr(arg2))) +@@ -1071,7 +1069,7 @@ class AuiPaneInfo(object): + ret = self.BestSize1(arg1) + elif isinstance(arg1, tuple): + ret = self.BestSize1(wx.Size(*arg1)) +- elif isinstance(arg1, six.integer_types) and arg2 is not None: ++ elif isinstance(arg1, int) and arg2 is not None: + ret = self.BestSize2(arg1, arg2) + else: + raise Exception("Invalid argument passed to `BestSize`: arg1=%s, arg2=%s" % (repr(arg1), repr(arg2))) +@@ -4123,7 +4121,7 @@ class AuiManager(wx.EvtHandler): + :param `item`: either a pane name or a :class:`wx.Window`. + """ + +- if isinstance(item, six.string_types): ++ if isinstance(item, str): + return self.GetPaneByName(item) + else: + return self.GetPaneByWidget(item) +@@ -6415,7 +6413,7 @@ class AuiManager(wx.EvtHandler): + elif paneInfo.IsNotebookControl() and not paneInfo.window: + paneInfo.window = self._notebooks[paneInfo.notebook_id] + +- for notebook_id, pnp in six.iteritems(pages_and_panes): ++ for notebook_id, pnp in pages_and_panes.items(): + # sort the panes with dock_pos + sorted_pnp = sorted(pnp, key=lambda pane: pane.dock_pos) + notebook = self._notebooks[notebook_id] +@@ -9862,7 +9860,7 @@ class AuiManager(wx.EvtHandler): + target = paneInfo.name + + minimize_toolbar.AddSimpleTool(ID_RESTORE_FRAME, paneInfo.caption, restore_bitmap, +- _(six.u("Restore %s")) % paneInfo.caption, target=target) ++ _("Restore %s") % paneInfo.caption, target=target) + minimize_toolbar.SetAuiManager(self) + minimize_toolbar.Realize() + toolpanelname = paneInfo.name + "_min" diff --git a/python-wxPython-rpmlintrc b/python-wxPython-rpmlintrc new file mode 100644 index 0000000..eb3a8d8 --- /dev/null +++ b/python-wxPython-rpmlintrc @@ -0,0 +1,3 @@ +addFilter("devel-file-in-non-devel-package") +# the multibuild flavors need differently named source packages +addFilter("invalid-spec-name") diff --git a/python-wxPython.changes b/python-wxPython.changes new file mode 100644 index 0000000..4e287da --- /dev/null +++ b/python-wxPython.changes @@ -0,0 +1,627 @@ +------------------------------------------------------------------- +Thu Aug 29 13:57:46 UTC 2024 - Ben Greiner + +- Add Phoenix-pr2580+2591+2592-numpy2.patch + * gh#wxWidgets/Phoenix#2580 + * gh#wxWidgets/Phoenix#2591 +- Update multibuild + * Finalize preparation for python313 + * Drop obsolete python39 + +------------------------------------------------------------------- +Sun Jun 30 20:55:59 UTC 2024 - Dirk Müller + +- prepare for python 3.13 + +------------------------------------------------------------------- +Thu May 30 13:08:43 UTC 2024 - Markéta Machová + +- Add drop-py2.patch to get rid of the six dependency (it will die + with Python 3.13) + +------------------------------------------------------------------- +Sat May 25 09:16:36 UTC 2024 - Jan Engelhardt + +- Add wxwidgets-3.2.5.patch to resolve wxPython FTBFS + +------------------------------------------------------------------- +Fri Feb 23 12:16:15 UTC 2024 - Dominique Leuenberger + +- Use newly supported shrink{} on OBS to exclude python flavors + when all python versions are skipped. + +------------------------------------------------------------------- +Mon Jan 15 16:29:26 UTC 2024 - Dominique Leuenberger + +- Enable python312 as valid multibuild flavor. + +------------------------------------------------------------------- +Sat Jan 6 21:47:42 UTC 2024 - Ben Greiner + +- Update buildset: + * Tumbleweed: Prepare python312, drop python38 + * 15.X: Prepare for "SLE15 Python module pythons" (The repository + does not have all the requirements yet to build) +- Add 0001-wxWidgets-Phoenix-integer-division.patch + * Required for Python 3.12 + * gh#wxWidgets/Phoenix#2508 +- Update requirements: + * This version requires Pillow again. + * Require numpy for all flavors: Add require-numpy.patch + * Upstream goes back and forth, see + https://github.com/wxWidgets/Phoenix/commits/master/requirements/install.txt +- Repack the source: Remove stray wxWidgets-4.1.0 tree + +------------------------------------------------------------------- +Wed Dec 27 07:37:06 UTC 2023 - Antonio Larrosa + +- Add patch from upstream to fix building the package with + doxygen >=1.9.7 (gh#wxWidgets/Phoenix#2497): + * 0001-Support-building-with-Doxygen-1.9.7.patch + +------------------------------------------------------------------- +Wed Dec 13 23:00:29 UTC 2023 - Jan Engelhardt + +- Add 0001-Update-wxTextCtrl-OSX-overrides-since-they-re-now-do.patch + 0001-Handle-wxGLCanvas-CreateSurface-which-is-only-availa.patch + to fix build failures with wx 3.2.4. + +------------------------------------------------------------------- +Mon Sep 11 14:47:53 UTC 2023 - Stefan Brüns + +- Update to release 4.2.1 + * No changelog provided +- Drop upstream patches: + * 0001-pypubsub-Replace-deprecated-inspect.getargspec.patch + * 0001-Fix-overflow-check-for-wxUIntPtr-type.patch + * 0001-Only-import-attrdict-where-needed.patch + * ba0d8cfcec3d3b0112d1c54991853e6003f2fbf6.patch + +------------------------------------------------------------------- +Sat Jan 28 09:38:44 UTC 2023 - Dirk Müller + +- add ba0d8cfcec3d3b0112d1c54991853e6003f2fbf6.patch to resolve + python 3.11 build failure +- add 0001-pypubsub-Replace-deprecated-inspect.getargspec.patch + to fix another python 3.11 build failure + +------------------------------------------------------------------- +Thu Jan 26 09:14:45 UTC 2023 - pgajdos@suse.com + +- add repack script to sources in spec file + +------------------------------------------------------------------- +Tue Jan 17 13:51:03 UTC 2023 - pgajdos@suse.com + +- add repack script, do not include packaging/ dir in sources + [gh#wxWidgets/Phoenix#2105], [bsc#670523] + +------------------------------------------------------------------- +Mon Dec 5 13:07:46 UTC 2022 - Daniel Garcia + +- Add python-pytest-forked as test dependency + * The pytest parameter --forked is provided by python-pytest-forked + which is no longer a transitive build requirement of + python-pytest-xdist + * gh#pytest-dev/pytest-xdist#468, gh#pytest-dev/pytest-xdist#821 + +------------------------------------------------------------------- +Sat Aug 13 23:03:31 UTC 2022 - Stefan Brüns + +- Update to relase 4.2.0, matching wxWidgets 3.2.0 + For a detailed changelog, see + https://www.wxpython.org/news/2022-08-07-wxpython-411-release/index.html +- Drop patch obsoleted by upstream changes: + * 0002-SIP-6.5-compat.patch +- Do not depend on pip for downloading in wxget, add + 0003-Make-pip-usage-in-wxget-optional.patch +- Fix a wrong type size on 32 bit archs, add + 0004-Fix-time_t-ETG-typedef-extend-DateTime.FromTimeT-tes.patch + +------------------------------------------------------------------- +Sun Jun 26 13:46:42 UTC 2022 - Stefan Brüns + +- Update to current git version for wxWidgets 3.1.6/3.1.7 + compatibility. +- Drop upstream patches: + * fix_no_return_in_nonvoid.patch + * wxPython-4.1.1-fix-overrides.patch + * 2039-bunch-py310-fixes.patch + * additional-310-fixes.patch +- Regenerate bindings from wxWidgets 3.1.7 code +- Allow SIP generation with SIP 6.x < 6.6, + * 0001-Only-import-attrdict-where-needed.patch + * 0002-SIP-6.5-compat.patch +- Add patches for test suite (pending): + * 0001-Check-HSV-values-in-image-test.patch + * 0001-Fix-overflow-check-for-wxUIntPtr-type.patch +- Add some more dependencies required for the test suite +- Disable some tests which can not succeed +- Enable test suite by default +- Do not ship copy of wxWidgets locale + +------------------------------------------------------------------- +Wed Jan 5 11:12:25 UTC 2022 - Ben Greiner + +- Reduce complexity by not rewriting subpackages at all. + Multibuild flavors now must be a superset of all existing + python3 flavors. + +------------------------------------------------------------------- +Tue Jan 4 22:28:51 UTC 2022 - Ben Greiner + +- The difference of a single whitespace character is significant + +------------------------------------------------------------------- +Tue Jan 4 13:58:38 UTC 2022 - Ben Greiner + +- Appease factory-auto bot about package src name + +------------------------------------------------------------------- +Tue Jan 4 10:18:08 UTC 2022 - Matej Cepl + +- Add additional patches fixing the situation with Python 3.10 + compatibility: + - 2039-bunch-py310-fixes.patch (from gh#wxWidgets/Phoenix#2039) + - additional-310-fixes.patch (from various commits on master) + +------------------------------------------------------------------- +Wed Dec 29 10:23:20 UTC 2021 - Ben Greiner + +- Split out the TW python3 flavors into multibuild using the + python_subpackage_only mechanism: Multiple python3 flavors + sequentially require too much space and time in one build. + +------------------------------------------------------------------- +Sat Jun 12 16:32:57 UTC 2021 - Antoine Belvire + +- Bump required wxWidgets version to 3.1.5. + +------------------------------------------------------------------- +Fri Jun 11 01:41:18 UTC 2021 - Stanislav Brabec + +- Increase disk space constraint to 15G. + +------------------------------------------------------------------- +Tue Jun 8 17:52:01 UTC 2021 - Antoine Belvire + +- Update to version 4.1.1: + * wxWidgets is now validating the flags passed when adding items + to a sizer, to ensure that they are the correct flags for the + type of the sizer. If the given flags do not make sense, for + example using horizontal alignment flags in a horizontal box + sizer, then a wxAssertionError error is raised. + * Fixed missing binder for wxEVT_STC_AUTOCOMP_SELECTION_CHANGE. + (PR#1613). + * DataViewModel.HasValue can be overridden and will inform the + DataViewCtrl whether or not an item and column has data. If + HasValue returns False, then GetValue for that item/col will + not be called. This allows a distinction between a truly empty + cell, and one that has a value even if it is an empty string. + (PR#1600) + * Added flag that allows blocking of item dragging in the + UltimateListControl class. (PR#1620) + * Add the column index to notification events in + UltimateListControl (PR#1630). + * Added orientation parameter to UltimateListControl.GetScrollPos. + (PR#1632) + * wx.lib.agw.aui.AuiNotebook RemovePage() now hides the removed + page, so it needs to be shown again if it is reused in another + place. (PR#1668) + * Fixed issue that could modify bytes objects under Python. + (PR#1680) + * Added wx.lib.agw.aui.EVT_AUI_PANE_CLOSE event which is sent when + a AUI (the agw version) Pane has been closed (after it has been + closed, not when it is about to be closed, which is when + EVT_AUI_PANE_CLOSE is sent.) (PR#1628) + * Exposed the wx.DC methods GetGraphicsContext and + SetGraphicsContext. Depending on the platform and the type of + the DC, there may be a wx.GraphicsContext used for the + implementation of the DC. If so, the GetGraphicsContext method + enables access to it. Be sure to check that the return value is + not None before trying to use it. + * Simplified the implementation of the wx.App.InitLocale method. + See the MigrationGuide for more information. + * Added wx.lib.agw.aui.AUI_DOCKART_HINT_WINDOW_BORDER_COLOUR + constant so the hint window border color can be themed as well. + * The wx.lib.mixins.listCtrl.CheckListCtrlMixin is now obsolete + because wx.ListCtrl has new functionality which does pretty much + the same thing. In fact there is some overlap in method names + which may trip up some use cases. It is advised to drop the use + of CheckListCtrlMixin and just use the wx.ListBox functionality. + You will need to call EnableCheckBoxes to turn it on, and you + may need to change some event handlers or overloaded methods. + * wx.html2.WebView is now able to use Microsoft's Edge browser + component as its backend renderer. This should improve the + capabilities of the WebView widget on Windows, and be more + consistent with the WebViews on the other platforms, compared to + the original IE 11 backend. Using this backed requires that a + new-ish version of the Edge browser is installed on the end + user's computer. + * Added the wx.Image.ConvertToRegion method. This lets you create + a wx.Region from an image and a specified color or the mask if + the image has one. This was done to workaround a bug in wxMac, + but it seems worthwhile enough to keep it around even after the + bug was fixed. + * Added the missing context manager methods for wx.LogNull. + (PR#1842) + * Refactored ScrolledThumbnail out of agw.ThumbnailCtrl so as to + be usable outside of ThumbnailCtrl. +- Add wxPython-4.1.1-fix-overrides.patch: Fix build with wxWidgets + 3.1.5 (gh#wxWidgets/Phoenix#1909). +- Remove patches merged upstream: + * 0001-Fix-conversion-of-variant-list-members.patch + * 0001-Fix-wxUIActionSimulator-Text-parameter-documentation.patch + * 0003-Use-explicit-wxString-c_str-conversion-for-sipFindTy.patch +- Increase required disk space to 15GB: Fix build failures due to + disk space exhaustion. + +------------------------------------------------------------------- +Wed Mar 31 01:32:34 UTC 2021 - Steve Kowalik + +- Don't build using Python 3.6 for test package, when that gets reenabled. +- Since build.py install helpfully installs every built shared object + under site-package directories, remove those not for that version of + Python. (bsc#1182822) +- Correct python uninstall alternatives to list all of them, not just one. + +------------------------------------------------------------------- +Wed Sep 30 17:48:02 UTC 2020 - Stefan Brüns + +- Use system wxWidgets (wxGTK3) instead of bundling +- Cleanup test dependencies and check section (tests still disabled + due to too many failures) + +------------------------------------------------------------------- +Wed Jul 1 12:55:23 UTC 2020 - Stefan Brüns + +- Wrap all relevant build dependencies when building with system + wxWidgets library. +- Add patches to allow building with STL variant of wxGTK: + * 0001-Fix-conversion-of-variant-list-members.patch + * use_stl_build.patch + * 0001-Fix-wxUIActionSimulator-Text-parameter-documentation.patch + * 0003-Use-explicit-wxString-c_str-conversion-for-sipFindTy.patch + +------------------------------------------------------------------- +Fri May 29 22:21:35 UTC 2020 - Stefan Brüns + +- Add explicit libXtst build dependency, required for Leap 15.1 + (already implicit on Leap 15.2 and TW). + +------------------------------------------------------------------- +Tue Apr 28 09:01:51 UTC 2020 - Guillaume GARDET + +- Update to 4.1.0: + * Add a sample for wx.Font.AddPrivateFont to the demo. + * Added wrappers for the OSXEnableAutomaticQuoteSubstitution, + OSXEnableAutomaticDashSubstitution, and OSXDisableAllSmartSubstitutions + methods in wx.TextCtrl. Also added OSXEnableAutomaticTabbing in wx.App. + * Added wx.ColourDialogEvent, wx.DCTextBgColourChanger, wx.DCTextBgModeChanger, + wx.grid.GridCellDateRenderer, wx.grid.GridCellDateEditor, wx.SystemAppearance, etc. + * Many of the deprecated items in wxWidgets and wxPython are being or have + been removed. Be sure to test your code in a recent 4.0.x release with + warnings enabled so you can see which class, method or function calls + you need to change. + * Bug fixes in wx.lib.calendar: key navigation across month boundaries is + now possible; key navigation now sets the date and fires the EVT_CALENDAR event; + setter APIs now set the date correctly #1230. + * Switch to using a wx.Overlay in the Widget Inspection Tool to highlight + widgets when running on a GTK3 port. + * Fixed issue in wx.lib.agw.customtreectrl where the label editor could + remain stuck forever #1235. + * Grafted on a EnableSystemTheme method to the classes which support it. + This can be used to disable the default system theme on Windows for native + widgets like wx.ListCtrl, wx.TreeCtrl and wx.dataview.DataViewCtrl. + It has no effect on the other platforms. + * The wx.WS_EX_VALIDATE_RECURSIVELY extended style flag is obsolete, + as it is now the default (and only) behavior. The style flag has been added + back into wxPython for compatibility, but with a zero value. You can just + stop using it in your code with no change in behavior. #1278 + * Fix a sometimes crash when using a wx.Overlay by letting the wx.DCOverlay + hold a reference to the DC, to ensure that the DCOverlay is destroyed first. PR#1301 + * Replaced the Vagrant VMs used for building wxPython for various Linux distros + with Docker images. + * Add some missing methods in wx.adv.BitmapComboBox #1307 + * Added the wx.svg package which contains code for parsing SVG + (Scalable Vector Graphics) files, and also code for integrating with + wxPython. It can rasterize the SVG to a wx.Bitmap of any size with no + loss of quality, and it can also render the SVG directly to a + wx.GraphicsContext using the GC's drawing primitives. PR#1323 + * Ported the embedding sample from Classic, which shows how to use wxPython + from a C++ wxWidgets application that embeds Python. PR#1353 + * Fixed wx.GetApp() to use wxWidgets' global wxApp instance instead of + maintaining its own pointer. This way, if the wxApp is created by C++ + code wxPython will still be able to get access to it. #1126 + * Added wrappers for the wx.ActivityIndicator class. + * Added wrappers for the wx.CollapsibleHeaderCtrl class. + * Fixed issues in PlotCanvas around displaying and using scrollbars. #1428 + * Added wx.msw.CHMHelpController, and also a wx.HelpController factory function + that creates an instance of the best Help Controller for the platform. #1536 + * Added wx.adv.GenericAnimationCtrl so the generic version of the animation + classes can be used even on the platforms that have a native version. + Note that due to internal changes to support both types of animations, + some API changes in how the Animation objects are created. See the + AnimationCtrl.py sample in the demo for the various usage patterns #1579 + * Added wrappers for the wx.grid.GridBlockCoords, wx.grid.GridBlocks, and + wx.grid.GridBlockDiffResult classes, as well as associated new methods + in the wx.grid.Grid class. These provide a new way to interact with blocks + of selected cells, including an iterator interface in wx.grid.GridBlocks + which should be a more efficient (time and memory) way to process large + groups of selections. +- Disable Python2 + +------------------------------------------------------------------- +Mon Mar 2 12:41:31 UTC 2020 - Tomáš Chvátal + +- Update to 4.0.7.post2: + * Bugfix to switch to AVFoundation instead of QTKit +- Fix building with new glut (pc file changed) + +------------------------------------------------------------------- +Tue Nov 12 04:15:41 UTC 2019 - Steve Kowalik + +- Update to 4.0.7.post1 + * This post-release just fixes a problem with the numpy dependency constraint + for Python 2.7. (#1415) + * Bug fixes in wx.lib.calendar: key navigation across month boundaries is + now possible; key navigation now sets the date and fires the EVT_CALENDAR + event; setter APIs now set the date correctly (#1230). + * Switch to using a wx.Overlay in the Widget Inspection Tool to highlight + widgets when running on a GTK3 port. + * Fixed issue in wx.lib.agw.customtreectrl where label editor could remain + stuck forever (#1235). + * Fix a sometimes crash when using a wx.Overlay by letting the wx.DCOverlay + hold a reference to the DC, to ensure that the DCOverlay is destroyed + first. (PR#1301) + * Ported the embedding sample from Classic, which shows how to use wxPython + from a C++ wxWidgets application that embeds Python. (PR #1353) + * Fixed wx.GetApp() to use wxWidgets' global wxApp instance instead of + maintaining its own pointer. This way, if the wxApp is created by C++ code + wxPython will still be able to get access to it. (#1126) + * Several other PRs have been backported from the master branch (which will + become wxPython 4.1.0), the full list can be seen here: + https://github.com/wxWidgets/Phoenix/pull/1357 + * Fixed a probably rare, but fatal bug on OSX when calling certain overloaded + virtual methods with implementations in Python. + * Fixed char pointers in generated stub code to have a valid pointer value. + * Reverted the change that loads up install_requires from the contents of + requirements.txt. Split the requirements.txt file into one for install and + one for development. + * Added missing HtmlWindow.ScrollToAnchor method, and also a couple methods + in HtmlCell too. (#1141) + * Added missing setters for the wheel-related properties in wx.MouseEvent. + (#1140) + * Updated wxWidgets commit reference, bringing fixes for #1140, #1086 and + #1147. + * Fix the use of the output parameter in HtmlWindow.OnOpeningURL the same + way it was fixed in HtmlWindowInterface.OnHTMLOpeningURL. (#1068) + * Fixed a crashing bug when using a member of a transient wx.VisualAttributes + object. Also set the attributes to be read-only to simplify the fix. + (#1198). + * Updated the sip being used in wxPython builds to version 4.19.16. + * Added helper functions to check results of wxWidgets configure during the + build of wxPython. Currently used to determine if the wx webview, glcanvas, + and media libraries should be added to the link command. (#1138) + * Fixed scrollbar issue with ListCtrlAutoWidthMixin (#1215) + * Fixed file access in the wx.py and wx.tools.pywxrc packages to be Python 2 + and 3 compatible. (#1193, #1156) + * Fixes for building with Python 3.8 on Linux. (#1227) + +------------------------------------------------------------------- +Thu Feb 7 18:42:42 UTC 2019 - Todd R + +- Update to 4.0.4 + * Fixed an issue where wx.lib.intctrl would erroneously attempt to use long + on Python3. (#898) + * Include the MSVC runtime DLLs for Python 3.7 builds too. + * Clear LIBPATH_PYEXT and LIB_PYEXT for linux builds too. (#904) + * Added a dependency on the Pillow package since it's used in some wx.lib.agw + modules. (PR #908) + * Add flag to hide page in wx.lib.agw.aui.notebook. (#895) + * Switch wx.lib.plot to issue deprecation warnings with PlotPendingDeprecation + so it doesn't have to enable all warnings to get them to be shown by default. + (#902) + * Added a Python 3.7 builder on Fedora 28. (#925) + * Fix the object ownership transfer for wx.Menu.Insert() (#931) + * Added wx.Treebook.GetTreeCtrl, wx.Listbook.GetListView and + wx.Choicebook.GetChoiceCtrl. (#918) + * Removed the wx.BookCtrlBase.RemovePage workaround as it was causing problems + and doesn't seem to be necessary any more. The existing wxWidgets assertions + are catching the out of range error just fine, however if wxWidgets was built + without the debug helpers turned on then it could still cause a crash. (#888) + * Reverted the changes which removed the content of the wx.lib.pubsub package + and encouraged users to switch to the real PyPubSub package instead. Removing + it caused more issues than were expected so it has been restored and the code + updated to PyPubSub v3.3.0. Version 4.0.0 is available upstream, but it is not + compatible with Python 2.7. Now, wx.lib.pubsub is actually deprecated instead + of just trying to pass control over to the upstream PyPubSub library. (#932) + * Improve calltip stability in pyshell. (#941) + * Fix TypeError in wx.lib.throbber. (#924) + * Fix missing parameter tool_id in + wx.lib.agw.ribbon.toolbar.RibbonToolBar.AddToggleTool. (#947) + * Add a step to wx.Config.ReadInt to attempt converting from long to int + under python2. (#384) + * Add virtual behavior for wx.RichTextCtrl and wx.TextCtrl's Copy/Cut/Paste methods + and their Can* counterparts. (#954) + * Fix IO type in wx.lib.agw.thumbnailctrl (#959) + * Fix type error that would occur using pycolourchooser. (#957) + * Optimize line drawing in HyperTreeList. (#973) + * Add wrapper for wx.StaticBox.GetBordersForSizer and use it in the demo to do + platform-specific layout of the items in the StaticBox. (#974) + * Update wx.Point, wx.RealPoint, and wx.Size to use floating + point arithmetic when conducting scalar multiplication (#971) + * Fix load/save bugs in PySlices (PR#978) + * Replace deprecated PIL.Image.tostring (PR#1005) + * Fix rendering and mouse sensitivity in UltimateListCtrl when adding HyperText + items. (#1010) + * Added a parameter to lib.agw.CustomTreeCtrl.SetItemWindow(), to allow + positioning the Window (a small image) on the left of text in a + CustomTreeItem. (#PR886). + * Declared DeleteAllPages in the notebook subclasses, so the proper C++ + implementation will be called. (#972) + * Removed wx.lib.floatbar, which has been deprecated forever and probably + hasn't been working in nearly as long. (#976) + * Updated SIP to version 4.19.13. + * Fix an issue in wx.lib.agw.aui.AuiManager where the orientation of + an AuiToolBar would not be updated when calling LoadPerspective. (#917) + * Fixed a bug in wx.FileSystemHandler.OpenFile where the object ownership was + not being transferred correctly, causing a crash after a premature object + deletion. (#926) + * Fixed wx.ListCtrl.Append when wx.LC_SORT style is used, so appending items out + of order does not lose the data for the remaining columns. (#906) + * Add wx.Accessible, it's Windows-only, will raise a NotImplementedError + exception on the other platforms. (#958) + * Added the ability to generate stub classes for use when optional wxWidgets + features are not part of the build. So far, stubs are available for + wx.Accessible, wx.FileSystemWatcher, wx.glcanvas, wx.media and wx.html2. + * Moved the wxpy_api.h file into the wx package at wx/include/wxPython so it + will be included in the wheel file. (#961) + * Fixed how string data is added to a virtual file-like object in + wx.MemoryFSHandler. All strings are now added to the file as utf-8 encoded data, + in both Python2 and Python3, and will be read from the virtual file the same + way. If you need to use some other encoding for some reason you can first + convert the text to a bytesarray or other buffer protocol compatible object and + then create the virtual file from that data. (#969) + * Performance update for wx.lib.agw.customtreectrl (#1049) + * Ensure that colours set in wx.lib.agw.customtreectrl.TreeItemAttr are + instances of wx.Colour. (#1032) + * Fix drawing of ticks in wx.lib.agw.speedmeter when there are negative bounds + values. (#1013) + * wxWidgets for Mac includes the wxJoystick class now, also update the demo. + (#997) + * Fix wx.html.HtmlPrintout to not be seen as an abstract class, so it can be + instantiated. (#1060) + * Fix wx.aui.AuiNotbook.SetArtProvider to properly transfer ownership of the art + object from Python to C++. This possible double-deletion and related crashing + problems. (#1061) + * Fixed the wrappers for wx.html.HtmlWindow.OnOpeningURL to properly handle the + redirect output parameter. (#1068) This is a backwards-incompatible change, + please see the Migration Guide for details. + * TabNavigatorWindow works similarly to other programs now. It's resizable and + draggable so if user has tons of files with long names, it isn't an irritation + anymore plastered right in the middle of the screen and can't be worked with + easily and ESC now cancels the popup with a proper returnId. (#1096) + * Added missing methods in wx.ListBox, SetItemForegroundColour, + SetItemBackgroundColour and SetItemFont. (#1095) + * Backported a fix in wxWidgets that avoids crashing in hhctrl.ocx when using + context sensitive help in 64-bit builds on Windows. (#1104) +- Update to 4.0.3 + * Fixed a linking problem on macOS. The new waf added an explicit link to the + Python shared library which meant that it would try to load it at runtime, + even if a different Python (such as Anaconda, EDM or Homebrew) was used to + import wxPython. This, of course, caused runtime errors. (#892) + * Sort pages by dock_pos when added to automatic (agw.aui) notebook. (#882) + * Fix a bug in py.introspect.getTokens. (#889) + * Added Vagrant configuration for Fedora-28. Removed Fedora-23 (#884) + * Added wrappers for the wx.WindowIDRef class and added the wx.NewIdRef + function. These will make it possible to create reserved Window IDs using the + same mechanism which is used when passing wx.ID_ANY to a widget constructor. + The object returned by wx.NewIdRef will automatically convert to an int when + passing it to a window constructor, and can also be used as the source in a + Bind(). (#896) + * Fixed issue when sys.prefix is not unicode (Python2) and when its contents + are not translatable to utf-8. +- Update to 4.0.2 + * Fixed wx.html2.EVT_WEBVIEW_NAVIGATING event not being sent on some versions + of Linux. (#741) + * wx.Sizers can now be used as an iterator to iterate over the items within + the sizer. (#738) + * Fix Python3 division in ThumbnailCtrl. (#746) + * Fix leaking image list in CheckListCtrlMixin (#752) + * All items marked as deprecated in the wxWidgets interface (documentation) + files will now throw a DeprecationWarning when used from wxPython. Many of + these items are disappearing in 4.1 so it's important to ensure they are + deprecated at runtime too instead of just in the docs. (#749) + * Ensure that the attribute list given to the GLCanvas constructor is + zero-terminated like it was in Classic. (#770) + * Updated to the wxWidgets 3.0.4 release version. + * Added the wxWidgets version number to the tail end of the string returned by + wx.version(). + * Bind EVT_WINDOW_DESTROY event only to the tree windows in CustomTreeCtrl, + since otherwise it would be caught when child windows are destroyed too, + which causes problems in this case. (#778) + * Fixed a problem where wx.TreeCtrl.OnCompareItems was not being called in + derived classes on Windows. This was due to an optimization that wasn't + compatible with how the classes are wrapped. (#774) + * Added wrappers for wx.ClassInfo and exposed wx.Object.GetClassInfo. This + class is part of wxWidgets' internal type information system and although + it is not very useful for Python applications it is useful for debugging + some internal wxPython issues. + * Removed the wx.lib.pubsub package, and replaced it with code that imports + the standalone PyPubSub in order remain compatible with older code that + still uses wx.lib.pubsub. (#782, #792) + * Fixed bug in wx.lib.intctrl (#790) + * Fixed subclassing of wx.TextCompleter and wx.TextCompleterSimple (#827) + * Fixes for Python3 compatibility in PyCrust. (#823) + * Fix wxGet to be able to use pip v10. (#817) + * Change winid parameter in wx.ScrolledWindow to id, for consistency. (#816) + * Ensure that the page exists in book controls GetPage and RemovePage methods. + At least one of the wx ports do not do this. (#830) + * Added missing wx.NumberEntryDialog + * Change wx.TextCompleterSimple.GetCompletions to send the list of strings + as a return value, rather than a parameter that gets filled. (#836) + * Enabled the wx.GraphicsContext.Create(metaFileDC) wrapper (#811) + * Metafile support is also available on OSX, so wx.msw.Metafile and + wx.msw.MetafileDC have been moved to the core wx module. So they can now be + accessed as wx.Metafile and wx.MetafileDC. + * Updated the waf tool used by the build to version 2.0.7. This fixes problems + with building for Python 3.7. + * Fixed alignment in buttons on MSW which have had foreground or background + colors set. (#815) + * Fix for unexpected assertion inside wx.aui.AuiMDIChildFrame.Close. + * Fix a bug in setting AuiDockingGuide size. (#727) + * Remove unnecessary AUI notebook updating, and use wx.BufferedDC in Repaint() + to mitigate flicker. (wx.lib.agw.aui). (#851, #686) + * Fixed crashing bug when using client data with items in + wx.dataview.DataViewTreeCtrl. (#856) + * Detach wx.Control in AuiToolbar from current sizer before attach to a new + one. (#843) + * Fixed a problem in wx.lib.mixins.listctrl.TextEditMixin where the height of + the editor widget could be set to zero. (See discussion in #849) + * Fix a bug in calculating whether a tool fits into the AuiToolBar. (#863) + * Override SetForegroundColour and SetBackgroundColour in MaskedEditMixin (#808) + * Add an explicit wx.GraphicsContext.Create overload for wx.AutoBufferedPaintDC. (#783) + * Return original AGW window style in AuiToolBar.GetAGWWindowStyleFlag. (#870) + * Fix a bug in group management on wx.lib.masked.numctrl; the previous code used + truediv ('/') to calculate _groupSpace, but in python 3.x this leads to a float + result, instead of an integer as was expected. Using floordiv ('//') instead + to solve the problem. (#865) + * Hide the window when the tool does not fit into AuiToolBar. (#872) + * Fixed the virtual dispatch code for the PGEditor.GetValueFromControl method + to properly pass the parameters to the Python implementation, and also fixed + how the return value is handled. (#742) + * Fixed all implementations of the PGProperty.StringToValue and IntToValue + methods to treat the value parameter as a return value. (#742) + * Add missing wx.adv.EVT_CALENDAR_WEEK_CLICKED (#875) + * Fixed the stock labels to conform to Windows design guidelines. (#787) + * Always reset floating size and style when floating a toolbar in agw.aui. (#880) + +------------------------------------------------------------------- +Fri Jan 18 14:40:11 UTC 2019 - Guillaume GARDET + +- Add _constraints to avoid 'no space left' error + +------------------------------------------------------------------- +Wed Jun 13 03:42:38 UTC 2018 - toddrme2178@gmail.com + +- Add fix_no_return_in_nonvoid.patch + Fix lack of return in non-void function issue in generated sip + bindings. + +------------------------------------------------------------------- +Mon Jun 4 09:11:22 UTC 2018 - petr@cervinka.net + +- Move "wx/*.so" libraries to main package, remove devel package (boo#1095747) +- Add rpmlintrc file to filter devel-file-in-non-devel-package +- Apply spec-cleaner + +------------------------------------------------------------------- +Fri May 18 07:36:08 UTC 2018 - jengelh@inai.de + +- Trim filler wording from description. + +------------------------------------------------------------------- +Wed Feb 28 20:32:18 UTC 2018 - toddrme2178@gmail.com + +- Initial version diff --git a/python-wxPython.spec b/python-wxPython.spec new file mode 100644 index 0000000..6a34830 --- /dev/null +++ b/python-wxPython.spec @@ -0,0 +1,337 @@ +# +# spec file for package python-wxPython +# +# Copyright (c) 2024 SUSE LLC +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# + + +%define X_display ":98" +%bcond_without test +%bcond_without syswx +# We rebuild the ETG and SIP files for two reasons: +# - Fixing a bug in the ETG time_t typedef (see patch) +# - Compatibility with SIP 6.5.x, for Leap 15.x +%bcond_without rebuild_sip + +%if %{with syswx} +%define wx_args --use_syswx --gtk3 -v +%else +%define wx_args --gtk3 -v +%endif + +%global flavor @BUILD_FLAVOR@%{nil} +%if "%flavor" == "" +# factory-auto requires the main build_flavor to match the specfile name +%define pprefix python +%define python_module() no-build-without-multibuild-flavor +ExclusiveArch: donotbuild +%else +%define pprefix %flavor +%if 0%{suse_version} >= 1599 +# Tumbleweed has a varying number of python3 flavors. The flavor +# selection here and in _multibuild must be kept in sync with the Factory +# prjconf definition for pythons. If a skip is missing, all builds fail. +# Extraneous build_flavors and skips are excluded automatically so future +# additions can be included here early and old flavors can be removed some time +# after the global drop in Factory. +%if "%flavor" != "python310" +%define skip_python310 1 +%endif +%if "%flavor" != "python311" +%define skip_python311 1 +%endif +%if "%flavor" != "python312" +%define skip_python312 1 +%endif +%if "%flavor" != "python313" +%define skip_python313 1 +%endif +%else +# SLE/Leap +%if "%flavor" == "python3" +# python3 is the old 3.6 +%define pythons python3 +%define python3_provides %{nil} +%else +%{?sle15_python_module_pythons} +%if "%flavor" != "%pythons" +# sle15_python_module_pythons defines the flavor, otherwise don't build +%define pythons %{nil} +%endif +%endif +%endif +%if "%{shrink:%pythons}" == "" +ExclusiveArch: donotbuild +%define python_module() %flavor-not-enabled-in-buildset-for-suse-%{?suse_version} +%else +%define python_files() -n %flavor-%{**} +%define python_module() %flavor-%{**} +%define python_exec python%{expand:%%%{flavor}_bin_suffix} +%define python_version %{expand:%%%{flavor}_version} +%define python_sitearch %{expand:%%%{flavor}_sitearch} +%define python_provides %{expand:%%%{flavor}_provides} +%endif +%endif + +Name: %{pprefix}-wxPython +Version: 4.2.1 +Release: 0 +Summary: The "Phoenix" variant of the wxWidgets Python bindings +License: GPL-2.0-or-later +Group: System/Libraries +URL: https://github.com/wxWidgets/Phoenix +# repacked https://files.pythonhosted.org/packages/source/w/wxPython/wxPython-%%{version}.tar.gz +Source0: wxPython-%{version}.tar.gz +Source1: python-wxPython-rpmlintrc +Source2: repack +Patch1: 0001-Update-wxTextCtrl-OSX-overrides-since-they-re-now-do.patch +Patch2: 0001-Handle-wxGLCanvas-CreateSurface-which-is-only-availa.patch +# PATCH-FIX-UPSTREAM https://github.com/wxWidgets/Phoenix/pull/2497 +Patch3: 0001-Support-building-with-Doxygen-1.9.7.patch +# PATCH-FIX-UPSTREAM https://github.com/wxWidgets/Phoenix/pull/2508 +Patch4: 0001-wxWidgets-Phoenix-integer-division.patch +# PATCH-FIX-OPENSUSE +Patch12: use_stl_build.patch +# PATCH-FIX-UPSTREAM - https://github.com/wxWidgets/Phoenix/pull/2232 +Patch13: 0003-Make-pip-usage-in-wxget-optional.patch +# PATCH-FIX-OPENSUSE +Patch14: 0004-Fix-time_t-ETG-typedef-extend-DateTime.FromTimeT-tes.patch +# PATCH-FIX-OPENSUSE - Test fixes/additions: +Patch112: 0001-Check-HSV-values-in-image-test.patch +# PATCH-FIX-OPENSUSE - Numpy for Python 3.12 is a thing +Patch113: require-numpy.patch +Patch114: wxwidgets-3.2.5.patch +# PATCH-FIX-UPSTREAM https://github.com/wxWidgets/Phoenix/pull/2540 +Patch115: drop-py2.patch +# PATCH-FIX-UPSTREAM https://github.com/wxWidgets/Phoenix/pull/2580 + 2591 + 2592 +Patch116: Phoenix-pr2580+2591+2592-numpy2.patch +# TODO: Replace deprecated setup.py calls in build.py with PEP517 without building wxWidgets into the wheel +BuildRequires: %{python_module base} +BuildRequires: %{python_module devel} +BuildRequires: %{python_module setuptools} +BuildRequires: c++_compiler +BuildRequires: fdupes +BuildRequires: pkgconfig +BuildRequires: python-rpm-macros +%if %{with syswx} +BuildRequires: %{python_module sip6-devel >= 6.5.1} +BuildRequires: waf +BuildRequires: wxGTK3-devel >= 3.2.0 +BuildRequires: wxWidgets-3_2-doc-xml >= 3.2.0 +%else +BuildRequires: freeglut-devel +BuildRequires: gstreamer-plugins-base-devel +BuildRequires: libjbig-devel +BuildRequires: pkgconfig(gstreamer-1.0) +BuildRequires: pkgconfig(gtk+-3.0) +BuildRequires: pkgconfig(libjpeg) +BuildRequires: pkgconfig(liblzma) +BuildRequires: pkgconfig(libmspack) +BuildRequires: pkgconfig(libnotify) +BuildRequires: pkgconfig(libpng16) +BuildRequires: pkgconfig(libtiff-4) +BuildRequires: pkgconfig(sdl2) +BuildRequires: pkgconfig(sm) +BuildRequires: pkgconfig(webkit2gtk-4.0) +BuildRequires: pkgconfig(x11) +BuildRequires: pkgconfig(xtst) +%endif +Requires: %{pprefix}-Pillow +Requires: %{pprefix}-numpy +Requires(post): update-alternatives +Requires(postun): update-alternatives +Conflicts: %{pprefix}-wxWidgets +Provides: %{pprefix}-wxWidgets = %{version} +%if "%{python_provides}" != "" +# for TW primary flavor provider +Conflicts: %{python_provides}-wxWidgets +Provides: %{python_provides}-wxPython = %{version}-%{release} +Provides: %{python_provides}-wxWidgets = %{version} +Obsoletes: %{python_provides}-wxPython < %{version}-%{release} +%endif +%if %{with test} +BuildRequires: %{python_module Pillow} +BuildRequires: %{python_module numpy} +BuildRequires: %{python_module pytest-forked} +BuildRequires: %{python_module pytest-xdist} +BuildRequires: %{python_module pytest} +BuildRequires: Mesa-dri +# Need at least one font installed +BuildRequires: google-opensans-fonts +# BuildRequires: wxWidgets-lang +BuildRequires: xorg-x11-server +BuildRequires: pkgconfig(cppunit) +%endif + +%description +Phoenix is a reimplementation of wxPython. Like the "classic" +wxPython, Phoenix wraps the wxWidgets C++ toolkit and provides access +to the user interface portions of the wxWidgets API, enabling Python +applications to have a GUI on Windows, macOS or Unix-like systems, +with a native look and feel and requiring very little (if any) +platform specific code. + +%package lang +# We cannot use %%lang_package here. Editra translations use noarch incompatible path. +Summary: Languages for package %{name} +Group: System/Libraries +Requires: %{name} = %{version} +Requires: python(abi) = %python_version +Supplements: (bundle-lang-other and %{name}) +Provides: %{name}-lang-all = %{version} +%if "%{python_provides}" != "" +# for TW primary flavor provider +Provides: %{python_provides}-wxPython-lang = %{version}-%{release} +Obsoletes: %{python_provides}-wxPython-lang < %{version}-%{release} +%endif + +%description lang +Provides translations to the package %{name}. + +%prep +%autosetup -n wxPython-%{version} -p1 +# https://github.com/wxWidgets/Phoenix/issues/2105 +# https://bugzilla.suse.com/show_bug.cgi?id=670523 +find -iname *.dll | grep . && \ + { echo "please run repack script (gh#2105)"; exit 1; } +# Lower minimum Python version +sed -i -e '/check_python_version/ s@3,7,0@3,6,0@' wscript + +# Reuse locale from wxWidgets package +%if %{with syswx} +rm -Rf wx/locale +%endif + +sed -i -e '/^#!\//, 1d' wx/py/*.py +sed -i -e '/^#!\//, 1d' wx/tools/*.py +sed -i -e '/^#!\//, 1d' wx/py/tests/*.py +echo "# empty module" >> wx/lib/pubsub/core/itopicdefnprovider.py + +%build +export CFLAGS="%{optflags}" + +%if %{with rebuild_sip} +# Save LICENSE* files from bundled siplib +mv sip/siplib{,_old} + +export DOXYGEN=%{_bindir}/doxygen +export SIP=%{_bindir}/sip +export WAF=%{_bindir}/waf +mkdir -p /tmp/wxxml/docs/doxygen/out/ +rm -f /tmp/wxxml/docs/doxygen/out/xml +cp ext/wxWidgets/docs/*.txt /tmp/wxxml/docs/ +ln -sf %{_docdir}/wxWidgets*doc-xml /tmp/wxxml/docs/doxygen/out/xml +export WXWIN=/tmp/wxxml/ + +%python_exec build.py touch %{wx_args} +%python_exec build.py etg --nodoc %{wx_args} +%python_exec build.py sip %{wx_args} +cp sip/siplib_old/LICENSE* sip/siplib/ +if [ ! -e sip/siplib/sip_array.c ]; then + cp sip/siplib/{,sip_}array.c + cp sip/siplib/{,sip_}array.h +fi +%endif + +%python_exec build.py build %{wx_args} + +%install +%python_exec build.py install %{wx_args} --destdir=%{buildroot} --extra_setup="-O1 --force" + +%fdupes %{buildroot}%{_libdir} + +%python_clone -a %{buildroot}%{_bindir}/helpviewer +%python_clone -a %{buildroot}%{_bindir}/img2png +%python_clone -a %{buildroot}%{_bindir}/img2py +%python_clone -a %{buildroot}%{_bindir}/img2xpm +%python_clone -a %{buildroot}%{_bindir}/pycrust +%python_clone -a %{buildroot}%{_bindir}/pyshell +%python_clone -a %{buildroot}%{_bindir}/pyslices +%python_clone -a %{buildroot}%{_bindir}/pyslicesshell +%python_clone -a %{buildroot}%{_bindir}/pywxrc +%python_clone -a %{buildroot}%{_bindir}/wxdemo +%python_clone -a %{buildroot}%{_bindir}/wxdocs +%python_clone -a %{buildroot}%{_bindir}/wxget + +%if %{without syswx} +%find_lang wxstd +%endif + +%check +%if %{with test} +############################################# +### Launch a virtual framebuffer X server ### +############################################# +export DISPLAY=%{X_display} +Xvfb %{X_display} >& Xvfb.log & +trap "kill $! || true" EXIT +sleep 5 + +# Make sure "import wx" does not confuse the wx dir with the module +mv wx wx_temp + +# pytest --forked from python-pytest-forked: +# Run each test as a separate process, otherwise multiple app +# instances will corrupt each others static data. +# +# Run UiAction tests one by one +%pytest_arch --forked -n 1 -k 'test_uiaction or test_mousemanager' unittests/ +# Skip Auto ID management test (only enabled on Windows) +# Skip Frame restore (requires a window manager) +# Skip Locale.GetString, we do not ship translations for wxWidgets-3_2 +# Skip wx.lib.pubsub, fails due to PYTHONDONTWRITEBYTECODE, also deprecated for pypubsub +# Skip UiAction tests (already done) +%{pytest_arch --forked -n 4 -k \ + '(not test_newIdRef03) and (not test_uiaction) and (not test_mousemanager) and (not test_frameRestore) and (not test_intlGetString) and (not lib_pubsub_Except) and (not test_xrc7)' \ + unittests/ +} + +mv wx_temp wx +%endif + +%post +%python_install_alternative pywxrc helpviewer img2png img2py img2xpm pycrust pyshell pyslices pyslicesshell wxdemo wxdocs wxget + +%postun +%python_uninstall_alternative pywxrc + +%files +%license LICENSE.txt license/*.txt +%doc CHANGES.rst README.rst TODO.rst +%python_alternative %{_bindir}/helpviewer +%python_alternative %{_bindir}/img2png +%python_alternative %{_bindir}/img2py +%python_alternative %{_bindir}/img2xpm +%python_alternative %{_bindir}/pycrust +%python_alternative %{_bindir}/pyshell +%python_alternative %{_bindir}/pyslices +%python_alternative %{_bindir}/pyslicesshell +%python_alternative %{_bindir}/pywxrc +%python_alternative %{_bindir}/wxdemo +%python_alternative %{_bindir}/wxdocs +%python_alternative %{_bindir}/wxget +%{python_sitearch}/wxPython-%{version}-py*.egg-info +%{python_sitearch}/wx/ +%if %{without syswx} +%exclude %{python_sitearch}/wx/locale/ +%endif + +%if %{without syswx} +%files lang -f wxstd.lang +%dir %{python_sitearch}/wx/locale/ +%dir %{python_sitearch}/wx/locale/* +%dir %{python_sitearch}/wx/locale/*/LC_MESSAGES +%endif + +%changelog diff --git a/repack b/repack new file mode 100644 index 0000000..ec8d3c2 --- /dev/null +++ b/repack @@ -0,0 +1,4 @@ +#!/bin/sh +tar -xzf wxPython-*.gz +rm -r wxPython-*/packaging +tar -czf wxPython-*.gz wxPython-*/ diff --git a/require-numpy.patch b/require-numpy.patch new file mode 100644 index 0000000..c4895d1 --- /dev/null +++ b/require-numpy.patch @@ -0,0 +1,11 @@ +Revert https://github.com/wxWidgets/Phoenix/commit/b1c55639dfb73db3a11307c9de888540cec512df + +--- a/requirements/install.txt 2023-06-07 01:31:16.000000000 +0000 ++++ b/requirements/install.txt 2024-01-06 22:08:26.485981672 +0000 +@@ -1,5 +1,4 @@ + # Runtime dependencies needed when using wxPython Phoenix +-numpy < 1.17 ; python_version <= '2.7' +-numpy ; python_version >= '3.0' and python_version < '3.12' ++numpy + pillow + six diff --git a/use_stl_build.patch b/use_stl_build.patch new file mode 100644 index 0000000..b142338 --- /dev/null +++ b/use_stl_build.patch @@ -0,0 +1,11 @@ +--- wxPython-4.1.0/buildtools/build_wxwidgets.py_orig 2020-05-30 01:24:47.890132236 +0200 ++++ wxPython-4.1.0/buildtools/build_wxwidgets.py 2020-05-30 01:25:59.574988273 +0200 +@@ -370,6 +370,8 @@ + if os.path.exists(frameworkRootDir): + shutil.rmtree(frameworkRootDir) + ++ configure_opts.append("--enable-stl") ++ + print("Configure options: " + repr(configure_opts)) + wxBuilder = builder.AutoconfBuilder() + if not options.no_config and not options.clean: diff --git a/wxPython-4.2.1.tar.gz b/wxPython-4.2.1.tar.gz new file mode 100644 index 0000000..e3b743f --- /dev/null +++ b/wxPython-4.2.1.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aae4cca64cb53ef17f964c75ca8d1aaa1af12f33a0aaf1a483c5989537f6121a +size 72503592 diff --git a/wxwidgets-3.2.5.patch b/wxwidgets-3.2.5.patch new file mode 100644 index 0000000..a004ebb --- /dev/null +++ b/wxwidgets-3.2.5.patch @@ -0,0 +1,34 @@ +Do not fail the wxPython build when using a wxWidgets-3.2.5 base. + +Generated by: +git diff 5622abb73deaa26dc2f6dc4cd8b4b2050396b49a..78938da1218483024b3a7acf55b5fb5513882916 etg/ + + +diff --git etg/window.py etg/window.py +index c388df76..0c035f14 100644 +--- a/etg/window.py ++++ a/etg/window.py +@@ -251,6 +251,23 @@ def run(): + return NULL; + #endif + """) ++ c.find('GetOrCreateAccessible').setCppCode("""\ ++ #if wxUSE_ACCESSIBILITY ++ return self->GetOrCreateAccessible(); ++ #else ++ wxPyRaiseNotImplemented(); ++ return NULL; ++ #endif ++ """) ++ c.find('CreateAccessible').factory = True ++ c.find('CreateAccessible').setCppCode("""\ ++ #if wxUSE_ACCESSIBILITY ++ return self->CreateAccessible(); ++ #else ++ wxPyRaiseNotImplemented(); ++ return NULL; ++ #endif ++ """) + c.find('SetAccessible.accessible').transfer = True + c.find('SetAccessible').setCppCode("""\ + #if wxUSE_ACCESSIBILITY