pyfa-org / Pyfa

Python fitting assistant, cross-platform fitting tool for EVE Online
GNU General Public License v3.0
1.61k stars 409 forks source link

Error on Arch Linux after upgrade to python 3.10 #2391

Open Klok-e opened 2 years ago

Klok-e commented 2 years ago

Bug Report

Error on Arch Linux after upgrade to python 3.10

Expected behavior:

Pyfa launches successfully launches.

Actual behavior:

Error message is displayed:

Traceback (most recent call last): File "/usr/share/pyfa/pyfa.py", line 150, in mf = MainFrame(options.title) File "/usr/share/pyfa/gui/mainFrame.py", line 172, in init self.additionsPane = AdditionsPane(self.fitting_additions_split, self) File "/usr/share/pyfa/gui/additionsPane.py", line 66, in init self.notebook.AddPage(self.drone, _t("Drones"), image=droneImg, closeable=False) File "/usr/share/pyfa/gui/chrome_tabs.py", line 231, in AddPage self.tabs_container.AddTab(title, image, closeable) File "/usr/share/pyfa/gui/chrome_tabs.py", line 1266, in AddTab tab_renderer = _TabRenderer((200, self.height), title, img, closeable) File "/usr/share/pyfa/gui/chrome_tabs.py", line 385, in init self.InitTab() File "/usr/share/pyfa/gui/chrome_tabs.py", line 479, in InitTab self.InitColors() File "/usr/share/pyfa/gui/chrome_tabs.py", line 563, in InitColors self.inactive_color = color_utils.GetSuitable(self.tab_color, 0.25) File "/usr/share/pyfa/gui/utils/color.py", line 57, in GetSuitable return Brighten(color, factor) File "/usr/share/pyfa/gui/utils/color.py", line 15, in Brighten return wx.Colour(r, g, b, a) TypeError: Colour(): arguments did not match any overloaded call: overload 1: too many arguments overload 2: argument 1 has unexpected type 'float' overload 3: argument 1 has unexpected type 'float' overload 4: argument 1 has unexpected type 'float'

Detailed steps to reproduce:

Fits involved in EFT format (Edit > To Clipboard > EFT):

Release or development git branch? Please note the release version or commit hash:

Operating system and version (eg: Windows 10, OS X 10.9, OS X 10.11, Ubuntu 16.10):

Arch Linux

pyfa v2.39.1 EVE Data Version: 1978193 (2021-12-09 19:05:58)

OS version: Linux-5.15.8-zen1-1-zen-custom-x86_64-with-glibc2.33 Python version: 3.10.1 (main, Dec 11 2021, 17:22:55) [GCC 11.1.0] wxPython version: 4.0.7.post2 (wxWidgets 3.0.5) SQLAlchemy version: 1.4.25 Logbook version: 1.5.3 Requests version: 2.26.0 Dateutil version: 2.8.2

Other relevant information:

Majora320 commented 2 years ago

This is printed to the command line, might have something to do with it:

Warning: Mismatch between the program and library build versions detected.
The library used 3.0 (wchar_t,compiler with C++ ABI 1014,wx containers,compatible with 2.8),
and wxPython used 3.0 (wchar_t,compiler with C++ ABI 1016,wx containers,compatible with 2.8).

E: on second inspection this doesn't seem likely, looks like wxpython just does some typechecking now and we pass it floats when it expects integers. Just have to add in some conversion calls in a few places. I might do a PR later.

njfox commented 2 years ago

@Majora320 have you been able to make any progress on this?

martinpetrus commented 2 years ago

You can try to patch with this, works, but it's not been properly tested or anything. It's bassically a bunch of integer divisions + type casts to integer where floats had been floating about.

From afe446eddb09e5eb6f765de8245d7a35635225a7 Mon Sep 17 00:00:00 2001
From: Martin Petrus <martin.petrus@example.com>
Date: Tue, 4 Jan 2022 13:27:30 +0100
Subject: [PATCH] python 3.10 compatibility

---
 gui/builtinMarketBrowser/pfSearchBox.py     |  6 +++---
 gui/builtinShipBrowser/categoryItem.py      |  4 ++--
 gui/builtinShipBrowser/fitItem.py           | 16 +++++++-------
 gui/builtinShipBrowser/navigationPanel.py   |  6 +++---
 gui/builtinShipBrowser/pfListPane.py        | 12 +++++------
 gui/builtinShipBrowser/pfWidgetContainer.py |  4 ++--
 gui/builtinShipBrowser/raceSelector.py      |  8 +++----
 gui/builtinShipBrowser/sfBrowserItem.py     |  6 +++---
 gui/builtinShipBrowser/shipItem.py          | 18 ++++++++--------
 gui/chrome_tabs.py                          | 24 ++++++++++-----------
 gui/pyfa_gauge.py                           | 12 +++++------
 gui/utils/anim.py                           |  2 +-
 gui/utils/color.py                          | 10 ++++-----
 gui/utils/draw.py                           |  6 +++---
 14 files changed, 67 insertions(+), 67 deletions(-)

diff --git a/gui/builtinMarketBrowser/pfSearchBox.py b/gui/builtinMarketBrowser/pfSearchBox.py
index d1e8f2f40..ea068a08f 100644
--- a/gui/builtinMarketBrowser/pfSearchBox.py
+++ b/gui/builtinMarketBrowser/pfSearchBox.py
@@ -220,15 +220,15 @@ class PFSearchBox(wx.Window):
         cheight = rect.height

         self.searchButtonX = self.padding
-        self.searchButtonY = (cheight - sh) / 2
+        self.searchButtonY = (cheight - sh) // 2
         self.cancelButtonX = cwidth - self.padding - cw
-        self.cancelButtonY = (cheight - ch) / 2
+        self.cancelButtonY = (cheight - ch) // 2

         self.editX = self.searchButtonX + self.padding + sw

         editWidth, editHeight = self.EditBox.GetSize()

-        self.editY = (cheight - editHeight) / 2
+        self.editY = (cheight - editHeight) // 2
         self.EditBox.SetPosition((self.editX, self.editY))
         self.EditBox.SetSize((self.cancelButtonX - self.padding - self.editX, -1))

diff --git a/gui/builtinShipBrowser/categoryItem.py b/gui/builtinShipBrowser/categoryItem.py
index b88557d22..d5559660a 100644
--- a/gui/builtinShipBrowser/categoryItem.py
+++ b/gui/builtinShipBrowser/categoryItem.py
@@ -85,7 +85,7 @@ class CategoryItem(SFBrowserItem):
     def UpdateElementsPos(self, mdc):
         rect = self.GetRect()
         self.shipBmpx = self.padding
-        self.shipBmpy = (rect.height - self.shipBmp.GetWidth()) / 2
+        self.shipBmpy = (rect.height - self.shipBmp.GetWidth()) // 2

         self.shipBmpx -= self.animCount

@@ -94,7 +94,7 @@ class CategoryItem(SFBrowserItem):
         wtext, htext = mdc.GetTextExtent(categoryName)

         self.catx = self.shipBmpx + self.shipBmp.GetWidth() + self.padding
-        self.caty = (rect.height - htext) / 2
+        self.caty = (rect.height - htext) // 2

     def DrawItem(self, mdc):
         # rect = self.GetRect()
diff --git a/gui/builtinShipBrowser/fitItem.py b/gui/builtinShipBrowser/fitItem.py
index bd37b0b94..3c2fdde5a 100644
--- a/gui/builtinShipBrowser/fitItem.py
+++ b/gui/builtinShipBrowser/fitItem.py
@@ -445,23 +445,23 @@ class FitItem(SFItem.SFBrowserItem):
         rect = self.GetRect()

         self.toolbarx = rect.width - self.toolbar.GetWidth() - self.padding
-        self.toolbary = (rect.height - self.toolbar.GetHeight()) / 2
+        self.toolbary = (rect.height - self.toolbar.GetHeight()) // 2

         self.toolbarx += self.animCount

-        self.shipEffx = self.padding + (rect.height - self.shipEffBk.GetWidth()) / 2
-        self.shipEffy = (rect.height - self.shipEffBk.GetHeight()) / 2
+        self.shipEffx = self.padding + (rect.height - self.shipEffBk.GetWidth()) // 2
+        self.shipEffy = (rect.height - self.shipEffBk.GetHeight()) // 2

         self.shipEffx -= self.animCount

-        self.shipBmpx = self.padding + (rect.height - self.shipBmp.GetWidth()) / 2
-        self.shipBmpy = (rect.height - self.shipBmp.GetHeight()) / 2
+        self.shipBmpx = self.padding + (rect.height - self.shipBmp.GetWidth()) // 2
+        self.shipBmpy = (rect.height - self.shipBmp.GetHeight()) // 2

         self.shipBmpx -= self.animCount

         self.textStartx = self.shipEffx + self.shipEffBk.GetWidth() + self.padding

-        self.fitNamey = (rect.height - self.shipBmp.GetHeight()) / 2
+        self.fitNamey = (rect.height - self.shipBmp.GetHeight()) // 2

         mdc.SetFont(self.fontBig)
         wtext, htext = mdc.GetTextExtent(self.fitName)
@@ -473,7 +473,7 @@ class FitItem(SFItem.SFBrowserItem):
         wlabel, hlabel = mdc.GetTextExtent(self.toolbar.hoverLabel)

         self.thoverx = self.toolbarx - self.padding - wlabel
-        self.thovery = (rect.height - hlabel) / 2
+        self.thovery = (rect.height - hlabel) // 2
         self.thoverw = wlabel

     def DrawItem(self, mdc):
@@ -529,7 +529,7 @@ class FitItem(SFItem.SFBrowserItem):
         fnEditSize = editCtl.GetSize()
         wSize = self.GetSize()
         fnEditPosX = end
-        fnEditPosY = (wSize.height - fnEditSize.height) / 2
+        fnEditPosY = (wSize.height - fnEditSize.height) // 2
         if fnEditPosX < start:
             editCtl.SetSize((self.editWidth + fnEditPosX - start, -1))
             editCtl.SetPosition((start, fnEditPosY))
diff --git a/gui/builtinShipBrowser/navigationPanel.py b/gui/builtinShipBrowser/navigationPanel.py
index 83dff8216..788795fc2 100644
--- a/gui/builtinShipBrowser/navigationPanel.py
+++ b/gui/builtinShipBrowser/navigationPanel.py
@@ -200,19 +200,19 @@ class NavigationPanel(SFItem.SFBrowserItem):
         rect = self.GetRect()

         self.toolbarx = self.padding
-        self.toolbary = (rect.height - self.toolbar.GetHeight()) / 2
+        self.toolbary = (rect.height - self.toolbar.GetHeight()) // 2

         mdc.SetFont(self.fontSmall)

         wlabel, hlabel = mdc.GetTextExtent(self.toolbar.hoverLabel)

         self.thoverx = self.toolbar.GetWidth() + self.padding
-        self.thovery = (rect.height - hlabel) / 2
+        self.thovery = (rect.height - hlabel) // 2
         self.thoverw = wlabel

         self.browserBoxX = self.thoverx
         bEditBoxWidth, bEditBoxHeight = self.BrowserSearchBox.GetSize()
-        self.browserBoxY = (rect.height - bEditBoxHeight) / 2
+        self.browserBoxY = (rect.height - bEditBoxHeight) // 2

         self.bEditBoxWidth = rect.width - self.browserBoxX - self.padding

diff --git a/gui/builtinShipBrowser/pfListPane.py b/gui/builtinShipBrowser/pfListPane.py
index ecb8edb1c..a78336b06 100644
--- a/gui/builtinShipBrowser/pfListPane.py
+++ b/gui/builtinShipBrowser/pfListPane.py
@@ -81,11 +81,11 @@ class PFListPane(wx.ScrolledWindow):

         # is it before the left edge?
         if cr.x < 0 < sppu_x:
-            new_vs_x = vs_x + (cr.x / sppu_x)
+            new_vs_x = vs_x + (cr.x // sppu_x)

         # is it above the top?
         if cr.y < 0 < sppu_y:
-            new_vs_y = vs_y + (cr.y / sppu_y)
+            new_vs_y = vs_y + (cr.y // sppu_y)

         # For the right and bottom edges, scroll enough to show the
         # whole control if possible, but if not just scroll such that
@@ -93,19 +93,19 @@ class PFListPane(wx.ScrolledWindow):

         # is it past the right edge ?
         if cr.right > clntsz.width and sppu_x > 0:
-            diff = (cr.right - clntsz.width + 1) / sppu_x
+            diff = (cr.right - clntsz.width + 1) // sppu_x
             if cr.x - diff * sppu_x > 0:
                 new_vs_x = vs_x + diff
             else:
-                new_vs_x = vs_x + (cr.x / sppu_x)
+                new_vs_x = vs_x + (cr.x // sppu_x)

         # is it below the bottom ?
         if cr.bottom > clntsz.height and sppu_y > 0:
-            diff = (cr.bottom - clntsz.height + 1) / sppu_y
+            diff = (cr.bottom - clntsz.height + 1) // sppu_y
             if cr.y - diff * sppu_y > 0:
                 new_vs_y = vs_y + diff
             else:
-                new_vs_y = vs_y + (cr.y / sppu_y)
+                new_vs_y = vs_y + (cr.y // sppu_y)

         # if we need to adjust
         if new_vs_x != -1 or new_vs_y != -1:
diff --git a/gui/builtinShipBrowser/pfWidgetContainer.py b/gui/builtinShipBrowser/pfWidgetContainer.py
index e3219530a..00c533610 100644
--- a/gui/builtinShipBrowser/pfWidgetContainer.py
+++ b/gui/builtinShipBrowser/pfWidgetContainer.py
@@ -15,8 +15,8 @@ class PFWidgetsContainer(PFListPane):
         if mode:
             aweight, aheight = self.anim.GetSize()
             cweight, cheight = self.GetSize()
-            ax = (cweight - aweight) / 2
-            ay = (cheight - aheight) / 2
+            ax = (cweight - aweight) // 2
+            ay = (cheight - aheight) // 2
             self.anim.SetPosition((ax, ay))
             self.anim.Show()
             self.anim.Play()
diff --git a/gui/builtinShipBrowser/raceSelector.py b/gui/builtinShipBrowser/raceSelector.py
index 809474249..3ec5990f1 100644
--- a/gui/builtinShipBrowser/raceSelector.py
+++ b/gui/builtinShipBrowser/raceSelector.py
@@ -116,8 +116,8 @@ class RaceSelector(wx.Window):
                 width += bmp.GetWidth() + self.buttonsPadding
                 height = max(bmp.GetHeight(), height)

-            posx = (rect.width - width) / 2
-            posy = (rect.height - height) / 2
+            posx = (rect.width - width) // 2
+            posy = (rect.height - height) // 2

             self.buttonsBarPos = (posx, posy)

@@ -208,11 +208,11 @@ class RaceSelector(wx.Window):

         if self.direction < 1:
             if self.layout == wx.VERTICAL:
-                mdc.DrawBitmap(self.bmpArrow, -2, (rect.height - self.bmpArrow.GetHeight()) / 2)
+                mdc.DrawBitmap(self.bmpArrow, -2, (rect.height - self.bmpArrow.GetHeight()) // 2)
             else:
                 mdc.SetPen(wx.Pen(sepColor, 1))
                 mdc.DrawLine(0, 0, rect.width, 0)
-                mdc.DrawBitmap(self.bmpArrow, (rect.width - self.bmpArrow.GetWidth()) / 2, -2)
+                mdc.DrawBitmap(self.bmpArrow, (rect.width - self.bmpArrow.GetWidth()) // 2, -2)

     def OnTimer(self, event):
         if event.GetId() == self.animTimerID:
diff --git a/gui/builtinShipBrowser/sfBrowserItem.py b/gui/builtinShipBrowser/sfBrowserItem.py
index 02fe03218..4e59c6c69 100644
--- a/gui/builtinShipBrowser/sfBrowserItem.py
+++ b/gui/builtinShipBrowser/sfBrowserItem.py
@@ -228,12 +228,12 @@ class PFToolbar:

             if btnState & BTN_PRESSED:
                 bmp = button.GetBitmap()
-                by += self.padding / 2
-                tbx += self.padding / 2
+                by += self.padding // 2
+                tbx += self.padding // 2

             bmpWidth = bmp.GetWidth()

-            pdc.DrawBitmap(dropShadowBmp, bx + self.padding / 2, self.toolbarY + self.padding / 2)
+            pdc.DrawBitmap(dropShadowBmp, bx + self.padding // 2, self.toolbarY + self.padding // 2)
             pdc.DrawBitmap(bmp, tbx, by)

             bx += bmpWidth + self.padding
diff --git a/gui/builtinShipBrowser/shipItem.py b/gui/builtinShipBrowser/shipItem.py
index 7c4d528d7..d220bf99a 100644
--- a/gui/builtinShipBrowser/shipItem.py
+++ b/gui/builtinShipBrowser/shipItem.py
@@ -194,26 +194,26 @@ class ShipItem(SFItem.SFBrowserItem):
         rect = self.GetRect()

         self.toolbarx = rect.width - self.toolbar.GetWidth() - self.padding
-        self.toolbary = (rect.height - self.toolbar.GetHeight()) / 2
+        self.toolbary = (rect.height - self.toolbar.GetHeight()) // 2

         self.toolbarx += self.animCount

-        self.shipEffx = self.padding + (rect.height - self.shipEffBk.GetWidth()) / 2
-        self.shipEffy = (rect.height - self.shipEffBk.GetHeight()) / 2
+        self.shipEffx = self.padding + (rect.height - self.shipEffBk.GetWidth()) // 2
+        self.shipEffy = (rect.height - self.shipEffBk.GetHeight()) // 2

         self.shipEffx -= self.animCount

-        self.shipBmpx = self.padding + (rect.height - self.shipBmp.GetWidth()) / 2
-        self.shipBmpy = (rect.height - self.shipBmp.GetHeight()) / 2
+        self.shipBmpx = self.padding + (rect.height - self.shipBmp.GetWidth()) // 2
+        self.shipBmpy = (rect.height - self.shipBmp.GetHeight()) // 2

         self.shipBmpx -= self.animCount

         self.raceBmpx = self.shipEffx + self.shipEffBk.GetWidth() + self.padding
-        self.raceBmpy = (rect.height - self.raceBmp.GetHeight()) / 2
+        self.raceBmpy = (rect.height - self.raceBmp.GetHeight()) // 2

         self.textStartx = self.raceBmpx + self.raceBmp.GetWidth() + self.padding

-        self.shipNamey = (rect.height - self.shipBmp.GetHeight()) / 2
+        self.shipNamey = (rect.height - self.shipBmp.GetHeight()) // 2

         shipName, shipTrait, fittings = self.shipFittingInfo

@@ -227,7 +227,7 @@ class ShipItem(SFItem.SFBrowserItem):
         wlabel, hlabel = mdc.GetTextExtent(self.toolbar.hoverLabel)

         self.thoverx = self.toolbarx - self.padding - wlabel
-        self.thovery = (rect.height - hlabel) / 2
+        self.thovery = (rect.height - hlabel) // 2
         self.thoverw = wlabel

     def DrawItem(self, mdc):
@@ -283,7 +283,7 @@ class ShipItem(SFItem.SFBrowserItem):
         fnEditSize = editCtl.GetSize()
         wSize = self.GetSize()
         fnEditPosX = end
-        fnEditPosY = (wSize.height - fnEditSize.height) / 2
+        fnEditPosY = (wSize.height - fnEditSize.height) // 2
         if fnEditPosX < start:
             editCtl.SetSize((self.editWidth + fnEditPosX - start, -1))
             editCtl.SetPosition((start, fnEditPosY))
diff --git a/gui/chrome_tabs.py b/gui/chrome_tabs.py
index 89687c33a..1dcdc4820 100644
--- a/gui/chrome_tabs.py
+++ b/gui/chrome_tabs.py
@@ -454,7 +454,7 @@ class _TabRenderer:
         mdc.SelectObject(ebmp)
         mdc.SetFont(self.font)
         textSizeX, textSizeY = mdc.GetTextExtent(self.text)
-        totalSize = self.left_width + self.right_width + textSizeX + self.close_btn_width / 2 + 16 + self.padding * 2
+        totalSize = self.left_width + self.right_width + textSizeX + self.close_btn_width // 2 + 16 + self.padding * 2
         mdc.SelectObject(wx.NullBitmap)
         return totalSize, self.tab_height

@@ -553,8 +553,8 @@ class _TabRenderer:

         x_offset = self.content_width \
             + self.left_width \
-            - self.ctab_close_bmp.GetWidth() / 2
-        y_offset = (self.tab_height - self.ctab_close_bmp.GetHeight()) / 2
+            - self.ctab_close_bmp.GetWidth() // 2
+        y_offset = (self.tab_height - self.ctab_close_bmp.GetHeight()) // 2
         self.close_region.Offset(x_offset, y_offset)

     def InitColors(self):
@@ -590,8 +590,8 @@ class _TabRenderer:
                 # Draw tab icon
                 mdc.DrawBitmap(
                     bmp,
-                    self.left_width + self.padding - bmp.GetWidth() / 2,
-                    (height - bmp.GetHeight()) / 2)
+                    self.left_width + self.padding - bmp.GetWidth() // 2,
+                    (height - bmp.GetHeight()) // 2)

         # draw close button
         if self.closeable:
@@ -604,8 +604,8 @@ class _TabRenderer:

             mdc.DrawBitmap(
                 cbmp,
-                self.content_width + self.left_width - cbmp.GetWidth() / 2,
-                (height - cbmp.GetHeight()) / 2)
+                self.content_width + self.left_width - cbmp.GetWidth() // 2,
+                (height - cbmp.GetHeight()) // 2)

         mdc.SelectObject(wx.NullBitmap)

@@ -625,7 +625,7 @@ class _TabRenderer:
         dc.SetFont(self.font)

         if self.tab_img:
-            text_start = self.left_width + self.padding + self.tab_img.GetWidth() / 2
+            text_start = self.left_width + self.padding + self.tab_img.GetWidth() // 2
         else:
             text_start = self.left_width

@@ -640,7 +640,7 @@ class _TabRenderer:
         # draw text (with no ellipses)
         text = draw.GetPartialText(dc, self.text, maxsize, "")
         tx, ty = dc.GetTextExtent(text)
-        dc.DrawText(text, text_start + self.padding, height / 2 - ty / 2)
+        dc.DrawText(text, text_start + self.padding, height // 2 - ty // 2)

     def __repr__(self):
         return "_TabRenderer(text={}, disabled={}) at {}".format(
@@ -1198,7 +1198,7 @@ class _TabsContainer(wx.Panel):

         if self.show_add_button:
             ax, ay = self.add_button.GetPosition()
-            mdc.DrawBitmap(self.add_button.Render(), ax, ay, True)
+            mdc.DrawBitmap(self.add_button.Render(), int(ax), int(ay), True)

         for i in range(len(self.tabs) - 1, -1, -1):
             tab = self.tabs[i]
@@ -1359,7 +1359,7 @@ class _TabsContainer(wx.Panel):
             # Divide tab container by number of tabs and add inclination. This will
             # return the ideal max size for the containers size
             if self.GetTabsCount() > 0:
-                dx = self.tab_container_width / self.GetTabsCount() + self.inclination * 2
+                dx = self.tab_container_width // self.GetTabsCount() + self.inclination * 2
                 tabWidth = min(dx, max_width)

             # Apply new size to all tabs
@@ -1391,7 +1391,7 @@ class _TabsContainer(wx.Panel):
             selected.SetPosition((selpos, self.container_height - self.height))

         self.add_button.SetPosition((round(tabsWidth) + self.inclination * 2,
-                                     self.container_height - self.height / 2 - self.add_button.GetHeight() / 3))
+                                     self.container_height - self.height // 2 - self.add_button.GetHeight() // 3))

     def OnLeaveWindow(self, event):
         if self.start_drag and not self.dragging:
diff --git a/gui/pyfa_gauge.py b/gui/pyfa_gauge.py
index cd83f3eca..e5542f841 100644
--- a/gui/pyfa_gauge.py
+++ b/gui/pyfa_gauge.py
@@ -255,7 +255,7 @@ class PyGauge(wx.Window):
             if value > 100:
                 w = rect.width
             else:
-                w = rect.width * (float(value) / 100)
+                w = int(rect.width * (float(value) / 100))
             r = copy.copy(rect)
             r.width = w
             dc.DrawRectangle(r)
@@ -267,7 +267,7 @@ class PyGauge(wx.Window):
             if value > 100:
                 w = rect.width
             else:
-                w = rect.width * (float(value) / 100)
+                w = int(rect.width * (float(value) / 100))
             r = copy.copy(rect)
             r.width = w

@@ -275,16 +275,16 @@ class PyGauge(wx.Window):
             # progress between the two transition ranges)
             pv = value
             if pv <= 100:
-                xv = pv / 100
+                xv = int(pv / 100)
                 transition = 0
             elif pv <= 101:
-                xv = pv - 100
+                xv = int(pv - 100)
                 transition = 1
             elif pv <= 103:
-                xv = (pv - 101) / 2
+                xv = int((pv - 101) / 2)
                 transition = 2
             elif pv <= 105:
-                xv = (pv - 103) / 2
+                xv = int((pv - 103) / 2)
                 transition = 3
             else:
                 pv = 106
diff --git a/gui/utils/anim.py b/gui/utils/anim.py
index 55d27c9ef..b9f63d642 100644
--- a/gui/utils/anim.py
+++ b/gui/utils/anim.py
@@ -62,7 +62,7 @@ class LoadAnimation(wx.Window):
         barColor = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT)
         shadeColor = colorUtils.GetSuitable(barColor, 0.75)

-        barWidth = rect.width / self.bars
+        barWidth = rect.width // self.bars
         barHeight = rect.height - self.padding * 2

         x = self.padding
diff --git a/gui/utils/color.py b/gui/utils/color.py
index f89b56d7a..7587cb01d 100644
--- a/gui/utils/color.py
+++ b/gui/utils/color.py
@@ -12,7 +12,7 @@ def Brighten(color, factor):
     b += (255 - b) * factor
     g += (255 - g) * factor

-    return wx.Colour(r, g, b, a)
+    return wx.Colour(int(r), int(g), int(b), a)

 def Darken(color, factor):
@@ -26,9 +26,9 @@ def Darken(color, factor):
     g *= factor
     b *= factor

-    r = min(max(r, 0), 255)
-    b = min(max(b, 0), 255)
-    g = min(max(g, 0), 255)
+    r = int(min(max(r, 0), 255))
+    b = int(min(max(b, 0), 255))
+    g = int(min(max(g, 0), 255))

     return wx.Colour(r, g, b, a)

@@ -70,4 +70,4 @@ def CalculateTransition(s_color, e_color, delta):
     tG = sG + (eG - sG) * delta
     tB = sB + (eB - sB) * delta

-    return wx.Colour(tR, tG, tB, (sA + eA) / 2)
+    return wx.Colour(tR, tG, tB, (sA + eA) // 2)
diff --git a/gui/utils/draw.py b/gui/utils/draw.py
index 4e486afda..95e975f32 100644
--- a/gui/utils/draw.py
+++ b/gui/utils/draw.py
@@ -13,7 +13,7 @@ def RenderGradientBar(windowColor, width, height, sFactor, eFactor, mFactor=None
     if mFactor:
         gMid = color.GetSuitable(windowColor, mFactor)
     else:
-        gMid = color.GetSuitable(windowColor, sFactor + (eFactor - sFactor) / 2)
+        gMid = color.GetSuitable(windowColor, sFactor + (eFactor - sFactor) // 2)

     gEnd = color.GetSuitable(windowColor, eFactor)

@@ -43,14 +43,14 @@ def DrawGradientBar(width, height, gStart, gEnd, gMid=None, fillRatio=4):
     mdc.SelectObject(canvas)

     r = wx.Rect(0, 0, width, height)
-    r.SetHeight(height / fillRatio)
+    r.SetHeight(height // fillRatio)

     if gMid is None:
         gMid = gStart

     mdc.GradientFillLinear(r, gStart, gMid, wx.SOUTH)
     r.SetTop(r.GetHeight())
-    r.SetHeight(height * (fillRatio - 1) / fillRatio + (1 if height % fillRatio != 0 else 0))
+    r.SetHeight(height * (fillRatio - 1) // fillRatio + (1 if height % fillRatio != 0 else 0))

     mdc.GradientFillLinear(r, gMid, gEnd, wx.SOUTH)

--
2.33.1
blitzmann commented 2 years ago

Install Pyfa from https://aur.archlinux.org/packages/pyfa/

Just wanted to issue a blanket statement here: This is not an official package we support. Generally, you'll have to contact the AUR maintainer directly regarding any issues associated with it.

That being said, a couple of things:

Of course, if there's anything that we can change on our side to facilitate support, we're open to PRs. But as of this moment, python 3.10 is unsupported, and anything other than wxPython 4.0.6 is unsupported.

wereii commented 2 years ago

I am the maintainer of the AUR package. I will be looking into solutions soon (within week, can't sooner). Thank you @blitzmann for the clarification.

@martinpetrus Would you mind if that patch of yours was used (after inspection and possibly some update) in the package ? Obviously with proper credit.

PS: Sorry for polluting this issue with basically packaging stuff (if required we can take this debate over to aur)

martinpetrus commented 2 years ago

@wereii well, of course, be my guest. I just have to point out it's not been tested beyond starting the app and creating a basic fit. Nor has it been backwads tested against python 4.0.7

blitzmann commented 2 years ago

@wereii I don't mind discussions happening here :)

I do have a question tho. I'll preface by noting that I know fuckall about Linux packaging, so feel free to put me in my place :P But isn't it possible to have python ~3.7 as a dependency for the package, and then creating a venv using the packages that pyfa specifically needs in requirementss.txt? Is the AUR pyfa package using the default system interpreter and installing packages to the system itself? Isn't that problematic for situations like this (system interpreter updates, can break various things)

I've caught up on the AUR comments. I'm open to PRs if that's what's required, but I want to make sure that, considering this is specific to one Linux distro, it's not something that can be easily solved via the distro's packaging (I also don't want to put the onus on you for trying to maintain a diff file between versions in case something else gets added that requires a tweak)

njfox commented 2 years ago

But isn't it possible to have python ~3.7 as a dependency for the package, and then creating a venv using the packages that pyfa specifically needs in requirementss.txt? Is the AUR pyfa package using the default system interpreter and installing packages to the system itself? Isn't that problematic for situations like this (system interpreter updates, can break various things)

The AUR package uses the system python, which is the standard for linux packages. Things like venvs are possible but considered bad practice--the whole idea is that the distro package manager handles the package instead of pip, so you can install system packages without fear of conflicts or breaking things.

I know a fix has been merged upstream in wxpython, but this is also technically a bug in Pyfa since the wxpython docs explicitly state these functions take integers. IMO it's less of a problem with Arch doing things the way it's supposed to and more a problem with Pyfa (and countless other Python packages I'm sure) relying on incorrect behavior that happened to be accommodated upstream before but stopped. Arch just happened to uncover this bug because of the focus on always using the latest upstream sources for packages.

I think the correct way to address it is to explicitly convert these values to integers on Pyfa's side, which should continue to work for all versions of Python and won't force package maintainers to resort to ugly stuff like using venvs. Some of the work has already been done in the patch earlier in this thread, although it's not fully complete (the graphs pane still has some instances where floats are being passed). I'd recommend reviewing it and considering it for a PR, at least as a WIP for something to build on. I haven't reviewed the patch that closely but I've been using it for awhile and haven't noticed any problems with the app.

blitzmann commented 2 years ago

Things like venvs are possible but considered bad practice.

This boggles my mind, I've always been of the opinion that things like venv were the recommended way so as to avoid compatibility issues like this where the system interpreter / packages update to incompatible versions, which could affect programs.

If someone can put together a PR (@martinpetrus) I can review it and merge it in, and it should be available with the next release. I can also attempt to get python 3.10 going on my machine and help track down any additional calls that might be problematic.

njfox commented 2 years ago

This boggles my mind, I've always been of the opinion that things like venv were the recommended way so as to avoid compatibility issues like this where the system interpreter / packages update to incompatible versions, which could affect programs.

Yeah, this approach is understandable and is the one taken by a lot of modern packaging systems. Arch in particular uses the latest everything, with the idea that when bugs are uncovered they can be fixed, which is exactly the scenario happening here.

@martinpetrus if you don't have time to dig into it, I or someone else can use your patch and then expand it to cover the other elements that need updating (the graphs widget at least), or you can start the PR yourself...just let us know what you'd like.

@blitzmann thanks a lot for your patience and understanding!

wereii commented 2 years ago

Thank you @blitzmann, it's really appreciated here because otherwise I would have to start hacking stuff up to keep Pyfa afloat in Arch.

There isn't much to add to what @njfox already said, from my point of view it's Pyfa's turn to act, not even considering Arch and packaging, if this is ignored it would simply leave Pyfa stuck on 3.8 (3.9?) forever.

Actually, as a python engineer myself, I don't mind helping with this at all.

wereii commented 2 years ago

Update: I dug around and analyzed stuff. It seems there is no released wxPython version that actually fixes problems with python310, though there is a fix commit in wxPy master, so until that is released there will be parts that don't work (Implants tab, or in code GenBitmapButton fails).

For ArchLinux, this will be tracked in https://bugs.archlinux.org/task/73763.

martinpetrus commented 2 years ago

@blitzmann @njfox sorry about replying only now. Please use/expand the patch at your will. Unfortunately, I have no capacity to dig into the issue further atm. Please understand the patch as a starting point of sorts. In good conscience, I cound not sing off on it myself knowing I didn't go the lengths of testig it approprietly.

wereii commented 2 years ago

@martinpetrus No worries I will be expanding on your changes and testing them. I will also patch it into the Arch Package so that people can test it without having to build it manually, the package is partially broken anyway until Arch either updates to some wxPython release that fixes python310 compatibility or backports the fixing commit from wxPython master.

(Though, if they do upgrade the wxPython packages to some of the latest releases then I, or someone else, will have to fixup stuff in pyfa. I was testing it out against latest wxPython and it obviously fell apart even more but that's something I will look at later if needed)

Ricaz commented 2 years ago

Is anybody working on fixing this?

wereii commented 2 years ago

@Ricaz Some bugs are blocked by https://bugs.archlinux.org/task/73763 (current wxPython, main dependency of Pyfa, is not compatible with python3.10).

AUR package has few patches to fix what can be fixed here in code but for example implants can't be fixed until that is resolved. (I keep the patches here: https://github.com/wereii/Pyfa/tree/compat310)

blitzmann commented 2 years ago

The thing about the implants, GenBitmapButton - we could potentially use another widget if that's causing issues. Looks like the only place it's used is in the implant editor.

Unfortunately I don't have the time at the moment to get the dependencies to test these myself

greg2010 commented 2 years ago

If anyone is looking for a way to run pyfa (and have graphs and implants work) while the original issue is being fixed, I've made this Dockerfile and a bash script to run pyfa in docker. https://github.com/greg2010/pyfa-docker It requires docker but otherwise works as if pyfa was installed normally. All of the saved fits etc will show up as well.

wereii commented 2 years ago

FYI: https://aur.archlinux.org/packages/pyfa-appimage

I am not yet sure what to do with pyfa package. I might try backporting (read fixing) some stuff into repository wxPython but that will be a long process and I can't guarantee when I will be able to look at it.

DarkFenX commented 2 years ago

Ran into this issue as well while working on dep_facelift branch. Going to fix it there.

FYI it happened before as well, but only in debug mode: https://github.com/wxWidgets/Phoenix/issues/1442

Kivarnis commented 2 years ago

FYI: https://aur.archlinux.org/packages/pyfa-appimage

Just wanted to say tried the appimage both from aur and directly off git, neither will open module stats page without error anymore.

blitzmann commented 2 years ago

@Kivarnis what does the error say? Can you provide a screenshot? Copy/Paste?

Kivarnis commented 2 years ago

image

There you go, similar things happen all over the place. I also no longer have the top menu for import/export etc.

image

blitzmann commented 2 years ago

Can you paste that error into a comment?

Kivarnis commented 2 years ago

pyfa v2.42.0 EVE Data Version: 2027534 (2022-04-05 07:18:44)

OS version: Linux-5.17.5-zen1-1-zen-x86_64-with-arch Python version: 3.7.13 (default, Mar 31 2022, 19:39:09) [GCC 10.2.1 20210130 (Red Hat 10.2.1-11)] wxPython version: 4.0.6 (wxWidgets 3.0.5) SQLAlchemy version: 1.3.23 Logbook version: 1.5.3 Requests version: 2.27.1 Dateutil version: 2.8.2

####################

Traceback (most recent call last): File "/tmp/.mount_pyfa-vTDcian/opt/pyfa/gui/contextMenu.py", line 174, in handler menuHandler._baseActivate(callingWindow, context, mainItem, selection, i) File "/tmp/.mount_pyfa-vTDcian/opt/pyfa/gui/contextMenu.py", line 307, in _baseActivate return self.activate(callingWindow, fullContext, mainItem, i) File "/tmp/.mount_pyfa-vTDcian/opt/pyfa/gui/builtinContextMenus/itemStats.py", line 74, in activate frame = ItemStatsFrame(stuff, fullContext) File "/tmp/.mount_pyfa-vTDcian/opt/pyfa/gui/itemStats.py", line 101, in init self.container = ItemStatsContainer(self, victim, item, itmContext) File "/tmp/.mount_pyfa-vTDcian/opt/pyfa/gui/itemStats.py", line 174, in init self.desc = ItemDescription(self.nbContainer, stuff, item) File "/tmp/.mount_pyfa-vTDcian/opt/pyfa/gui/builtinItemStatsViews/itemDescription.py", line 30, in init fgcolor.GetAsString(wx.C2S_HTML_SYNTAX), wx._core.wxAssertionError: C++ assertion "isOpaque" failed at /tmp/pip-install-mppfn6j6/wxpython_10bf4e9ea79848a598362eb7ee635c37/ext/wxWidgets/src/common/colourcmn.cpp(228) in GetAsString(): alpha is lost in HTML syntax

Kivarnis commented 2 years ago

I will leave for sanity but I redid my distro install and the problem has vanished mysteriously. So it DOES work and the problem was something odd in my specific situation. I am on the SAME distro and version I was, so.

wereii commented 2 years ago

WxPython was updated on ArchLinux 🎉 quick tests show that Pyfa seems to be working again, though not latest release because it's missing the python3.10 compatibility patches (floats used as ints).

I will be applying that one patch in AUR for now until it's released (probably when dep_facelift branch is merged @Phoenix591 ).