From c4ba09c19681c6d20a54f95a9b3077673a7baf7c Mon Sep 17 00:00:00 2001 From: Axel Beckert Date: Wed, 11 Sep 2019 01:13:04 +0200 Subject: [PATCH 1/7] Fix some execution paths in setup.py for Python 3 Mostly adds additionally thrown Exceptions and str vs bytes conversions. --- setup.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/setup.py b/setup.py index 3489d31..7cb237a 100755 --- a/setup.py +++ b/setup.py @@ -231,36 +231,36 @@ class configure(Command): pmtemp = subprocess.Popen(["pkg-config", "--variable=pm_sleephooks", "pm-utils"], stdout=subprocess.PIPE) returncode = pmtemp.wait() # let it finish, and get the exit code - pmutils_candidate = pmtemp.stdout.readline().strip() # read stdout + pmutils_candidate = str(pmtemp.stdout.readline().strip()) # read stdout if len(pmutils_candidate) == 0 or returncode != 0 or \ not os.path.isabs(pmutils_candidate): raise ValueError else: self.pmutils = pmutils_candidate - except (OSError, ValueError): + except (OSError, ValueError, FileNotFoundError): pass # use our default try: kdetemp = subprocess.Popen(["kde-config","--prefix"], stdout=subprocess.PIPE) returncode = kdetemp.wait() # let it finish, and get the exit code - kdedir_candidate = kdetemp.stdout.readline().strip() # read stdout + kdedir_candidate = str(kdetemp.stdout.readline().strip()) # read stdout if len(kdedir_candidate) == 0 or returncode != 0 or \ not os.path.isabs(kdedir_candidate): raise ValueError else: self.kdedir = kdedir_candidate + '/share/autostart' - except (OSError, ValueError): + except (OSError, ValueError, FileNotFoundError): # If kde-config isn't present, we'll check for kde-4.x try: kde4temp = subprocess.Popen(["kde4-config","--prefix"], stdout=subprocess.PIPE) returncode = kde4temp.wait() # let it finish, and get the exit code - kde4dir_candidate = kde4temp.stdout.readline().strip() # read stdout + kde4dir_candidate = str(kde4temp.stdout.readline().strip()) # read stdout if len(kde4dir_candidate) == 0 or returncode != 0 or \ not os.path.isabs(kde4dir_candidate): raise ValueError else: self.kdedir = kde4dir_candidate + '/share/autostart' - except (OSError, ValueError): + except (OSError, ValueError, FileNotFoundError): # If neither kde-config nor kde4-config are not present or # return an error, then we can assume that kde isn't installed # on the user's system @@ -339,9 +339,9 @@ class configure(Command): # if the option is not python (which is not a directory) if not argument[0][:-1] == "python": # see if it ends with a / - if not value.endswith("/"): + if not str(value).endswith("/"): # if it doesn't, slap one on - setattr(self, argument_name, value + "/") + setattr(self, argument_name, str(value) + "/") else: # as stated above, the python entry defines the beginning # of the files section @@ -636,7 +636,7 @@ class compile_translations(Command): print(len(output), returncode) raise ValueError else: - m = re.match('(\d+) translated messages(?:, (\d+) fuzzy translation)?(?:, (\d+) untranslated messages)?.', output) + m = re.match(b'(\d+) translated messages(?:, (\d+) fuzzy translation)?(?:, (\d+) untranslated messages)?.', output) if m: done, fuzzy, missing = m.groups() fuzzy = int(fuzzy) if fuzzy else 0 From 187f85f6a0508a1a837d54828b55bb0969d66aff Mon Sep 17 00:00:00 2001 From: Axel Beckert Date: Wed, 11 Sep 2019 01:16:58 +0200 Subject: [PATCH 2/7] More Python 3 fixes needed to also install the packages Daemon still does not start. It fails as follows: Traceback (most recent call last): File "/usr/share/wicd/daemon/wicd-daemon.py", line 62, in from wicd.logfile import ManagedStdio File "/usr/lib/python3/dist-packages/wicd/logfile.py", line 32, in class LogFile(file): NameError: name 'file' is not defined --- curses/curses_misc.py | 2 +- curses/wicd-curses.py | 2 +- gtk/gui.py | 2 +- gtk/prefs.py | 2 +- gtk/wicd-client.py | 2 +- wicd/monitor.py | 2 +- wicd/wicd-daemon.py | 6 ++++-- wicd/wnettools.py | 2 +- 8 files changed, 11 insertions(+), 9 deletions(-) diff --git a/curses/curses_misc.py b/curses/curses_misc.py index 1f69ce7..0e80b57 100644 --- a/curses/curses_misc.py +++ b/curses/curses_misc.py @@ -707,7 +707,7 @@ class OptCols(urwid.WidgetWrap): # callbacks map the text contents to its assigned callback. self.callbacks = [] for cmd in tuples: - key = reduce(lambda s, (f, t): s.replace(f, t), [ + key = reduce(lambda s, tuple: s.replace(tuple[0], tuple[1]), [ ('ctrl ', 'Ctrl+'), ('meta ', 'Alt+'), ('left', '<-'), ('right', '->'), ('page up', 'Page Up'), ('page down', 'Page Down'), diff --git a/curses/wicd-curses.py b/curses/wicd-curses.py index 5bf4cf4..2ab2539 100755 --- a/curses/wicd-curses.py +++ b/curses/wicd-curses.py @@ -46,7 +46,7 @@ import urwid # DBus communication stuff from dbus import DBusException # It took me a while to figure out that I have to use this. -import gobject +from gi.repository import GObject as gobject # Other important wicd-related stuff from wicd import wpath diff --git a/gtk/gui.py b/gtk/gui.py index ea9f4c9..b02ff8a 100644 --- a/gtk/gui.py +++ b/gtk/gui.py @@ -26,7 +26,7 @@ Module containing the code for the main wicd GUI. import os import sys import time -import gobject +from gi.repository import GObject as gobject import gtk from itertools import chain from dbus import DBusException diff --git a/gtk/prefs.py b/gtk/prefs.py index f34a559..fbd5446 100644 --- a/gtk/prefs.py +++ b/gtk/prefs.py @@ -25,7 +25,7 @@ handles recieving/sendings the settings from/to the daemon. # import gtk -import gobject +from gi.repository import GObject as gobject import os from wicd import misc diff --git a/gtk/wicd-client.py b/gtk/wicd-client.py index 39fe339..e008912 100644 --- a/gtk/wicd-client.py +++ b/gtk/wicd-client.py @@ -39,7 +39,7 @@ class TrayIcon() -- Parent class of TrayIconGUI and IconConnectionInfo. import sys import gtk -import gobject +from gi.repository import GObject as gobject import getopt import os import pango diff --git a/wicd/monitor.py b/wicd/monitor.py index 38def57..88642eb 100755 --- a/wicd/monitor.py +++ b/wicd/monitor.py @@ -24,7 +24,7 @@ when appropriate. # along with this program. If not, see . # -import gobject +from gi.repository import GObject as gobject import time from dbus import DBusException diff --git a/wicd/wicd-daemon.py b/wicd/wicd-daemon.py index 0b30312..a5b22c1 100644 --- a/wicd/wicd-daemon.py +++ b/wicd/wicd-daemon.py @@ -44,7 +44,7 @@ from subprocess import Popen from operator import itemgetter # DBUS -import gobject +from gi.repository import GObject as gobject import dbus import dbus.service if getattr(dbus, 'version', (0, 0, 0)) < (0, 80, 0): @@ -1950,5 +1950,7 @@ if __name__ == '__main__': print(("Root privileges are required for the daemon to run properly." + " Exiting.")) sys.exit(1) - gobject.threads_init() + # No more needed since PyGObject 3.11, c.f. + # https://wiki.gnome.org/PyGObject/Threading + #gobject.threads_init() main(sys.argv) diff --git a/wicd/wnettools.py b/wicd/wnettools.py index 1424062..bfa290b 100644 --- a/wicd/wnettools.py +++ b/wicd/wnettools.py @@ -39,7 +39,7 @@ import dbus import socket, fcntl import shutil -import wpath +from . import wpath from . import misc from .misc import find_path From fef2a43a59ec4c5da24c9809841e7f7aed80d8d2 Mon Sep 17 00:00:00 2001 From: Axel Beckert Date: Wed, 11 Sep 2019 01:24:27 +0200 Subject: [PATCH 3/7] Fix LogFile class by using io.FileIO instead of file Thanks to Frank Hofmann for the right pointer to https://stackoverflow.com/questions/47838405/porting-a-sub-class-of-python2-file-class-to-python3 Now at least "/usr/sbin/wicd -c -f -e -o" keeps running. Still throws errors and warnings, though: /usr/share/wicd/daemon/wicd-daemon.py:1925: PyGIDeprecationWarning: GObject.MainLoop is deprecated; use GLib.MainLoop instead mainloop = gobject.MainLoop() /usr/share/wicd/daemon/monitor.py:392: PyGIDeprecationWarning: GObject.MainLoop is deprecated; use GLib.MainLoop instead mainloop = gobject.MainLoop() Exception in thread Thread-1: Traceback (most recent call last): File "/usr/lib/python3.7/threading.py", line 926, in _bootstrap_inner self.run() File "/usr/lib/python3.7/threading.py", line 870, in run self._target(*self._args, **self._kwargs) File "/usr/share/wicd/daemon/wicd-daemon.py", line 1020, in _async_scan self._sync_scan() File "/usr/share/wicd/daemon/wicd-daemon.py", line 1024, in _sync_scan scan = self.wifi.Scan(str(self.hidden_essid)) File "/usr/lib/python3/dist-packages/wicd/networking.py", line 673, in Scan aps = wiface.GetNetworks(essid) File "/usr/lib/python3/dist-packages/wicd/wnettools.py", line 227, in newfunc return func(self, *args, **kwargs) File "/usr/lib/python3/dist-packages/wicd/wnettools.py", line 1392, in GetNetworks entry = self._ParseAccessPoint(cell, ralink_info) File "/usr/lib/python3/dist-packages/wicd/wnettools.py", line 1447, in _ParseAccessPoint ap['bitrates'] = sorted(m, lambda x, y: int(float(x) - float(y))) TypeError: sorted expected 1 arguments, got 2 --- wicd/logfile.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/wicd/logfile.py b/wicd/logfile.py index c6bf67e..65a3f03 100644 --- a/wicd/logfile.py +++ b/wicd/logfile.py @@ -24,20 +24,21 @@ rotates itself when a maximum size is reached. import sys import os import time +import io class SizeError(IOError): """ Custom error class. """ pass -class LogFile: +class LogFile(io.FileIO): """LogFile(name, [mode="w"], [maxsize=360000]) Opens a new file object. After writing bytes a SizeError will be raised. """ - def __init__(self, name, mode="a", maxsize=360000): - super(LogFile, self).__init__(name, mode) + def __init__(self, name, mode="a", maxsize=360000, *args, **kwargs): + super(LogFile, self).__init__(name, mode, maxsize, *args, **kwargs) self.maxsize = maxsize self.eol = True try: From c2789eb46700e9c5b4c7a17d4cd7f80cd37e712f Mon Sep 17 00:00:00 2001 From: Axel Beckert Date: Wed, 11 Sep 2019 01:29:07 +0200 Subject: [PATCH 4/7] Fix "TypeError: sorted expected 1 arguments, got 2" --- wicd/wnettools.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wicd/wnettools.py b/wicd/wnettools.py index bfa290b..cb9d125 100644 --- a/wicd/wnettools.py +++ b/wicd/wnettools.py @@ -38,6 +38,7 @@ import time import dbus import socket, fcntl import shutil +from functools import cmp_to_key from . import wpath from . import misc @@ -1444,7 +1445,7 @@ class BaseWirelessInterface(BaseInterface): m = re.findall(bitrates_pattern, bitrates) if m: # numeric sort - ap['bitrates'] = sorted(m, lambda x, y: int(float(x) - float(y))) + ap['bitrates'] = sorted(m, key=cmp_to_key(lambda x, y: int(float(x) - float(y)))) else: ap['bitrates'] = None From 9587c52c8854d31053910cf6e63744fc35c64136 Mon Sep 17 00:00:00 2001 From: Axel Beckert Date: Wed, 11 Sep 2019 01:33:03 +0200 Subject: [PATCH 5/7] Fix "TypeError: cmp is an invalid keyword argument for sort()" --- wicd/networking.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wicd/networking.py b/wicd/networking.py index 97edc8b..87867f0 100644 --- a/wicd/networking.py +++ b/wicd/networking.py @@ -48,6 +48,7 @@ import time import threading import os from signal import SIGTERM +from functools import cmp_to_key # wicd imports from . import misc @@ -663,7 +664,7 @@ class Wireless(Controller): time.sleep(1) aps = wiface.GetNetworks(essid) - aps.sort(cmp=comp, reverse=True) + aps.sort(key=cmp_to_key(comp), reverse=True) return aps From c238d26a9e342ce88527844eca7975ececeb6849 Mon Sep 17 00:00:00 2001 From: Axel Beckert Date: Wed, 11 Sep 2019 01:40:43 +0200 Subject: [PATCH 6/7] Fix "NameError: name 'cmp' is not defined" Source: https://codegolf.stackexchange.com/questions/49778/how-can-i-use-cmpa-b-with-python3 Now the wicd daemon starts as "/usr/sbin/wicd -c -f -e -o" wihout errors, only warnings are left. wicd-curses also runs but spews warnings into the status line, too. --- wicd/networking.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wicd/networking.py b/wicd/networking.py index 87867f0..fb9149d 100644 --- a/wicd/networking.py +++ b/wicd/networking.py @@ -644,7 +644,8 @@ class Wireless(Controller): key = 'quality' else: key = 'strength' - return cmp(x[key], y[key]) + return ((x[key] > y[key]) - (x[key] < y[key])) # cmp(x[key], y[key]) + if not self.wiface: return [] From c1c26d81121457b18ec42b3eac342f51d7587512 Mon Sep 17 00:00:00 2001 From: Axel Beckert Date: Wed, 11 Sep 2019 02:43:20 +0200 Subject: [PATCH 7/7] Remaining needed changes to get the daemon running with Python 3 --- wicd/logfile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wicd/logfile.py b/wicd/logfile.py index 65a3f03..9a38687 100644 --- a/wicd/logfile.py +++ b/wicd/logfile.py @@ -53,7 +53,7 @@ class LogFile(io.FileIO): if len(data) <= 0: return if self.eol: - super(LogFile, self).write(self.get_time() + ' :: ') + super(LogFile, self).write(self.get_time().encode("utf-8") + b' :: ') self.eol = False if data[-1] == '\n': @@ -61,7 +61,7 @@ class LogFile(io.FileIO): data = data[:-1] super(LogFile, self).write(data.replace( - '\n', '\n' + self.get_time() + ' :: ')) + b'\n', b'\n' + self.get_time().encode("utf-8") + b' :: ')) if self.eol: super(LogFile, self).write('\n')