From e9e347ea56c05e73b99d9faa8851dd033870a75a Mon Sep 17 00:00:00 2001 From: wico-kolmas Date: Wed, 4 Mar 2026 09:29:11 +0100 Subject: [PATCH 1/2] Replace pkg_resources with importlib --- dronecan_gui_tool/widgets/__init__.py | 7 ++--- pip_sizes.py | 38 +++++++++++++++------------ setup.py | 14 ++++++---- 3 files changed, 34 insertions(+), 25 deletions(-) diff --git a/dronecan_gui_tool/widgets/__init__.py b/dronecan_gui_tool/widgets/__init__.py index d93bcd9..ff52c03 100644 --- a/dronecan_gui_tool/widgets/__init__.py +++ b/dronecan_gui_tool/widgets/__init__.py @@ -8,8 +8,8 @@ import os import re -import pkg_resources import queue +from importlib.resources import as_file, files from PyQt5.QtWidgets import QTableWidget, QTableWidgetItem, QAbstractItemView, QHeaderView, QApplication, QWidget, \ QComboBox, QCompleter, QPushButton, QHBoxLayout, QVBoxLayout, QMessageBox from PyQt5.QtCore import Qt, QTimer, QStringListModel @@ -640,8 +640,9 @@ def get_app_icon(): pass # noinspection PyBroadException try: - fn = pkg_resources.resource_filename('dronecan_gui_tool', os.path.join('icons', 'dronecan_gui_tool.png')) - _APP_ICON_OBJECT = QIcon(fn) + icon_resource = files('dronecan_gui_tool').joinpath('icons', 'dronecan_gui_tool.png') + with as_file(icon_resource) as icon_path: + _APP_ICON_OBJECT = QIcon(str(icon_path)) except Exception: logger.error('Could not load icon', exc_info=True) _APP_ICON_OBJECT = QIcon() diff --git a/pip_sizes.py b/pip_sizes.py index e0b5226..dab235a 100644 --- a/pip_sizes.py +++ b/pip_sizes.py @@ -1,7 +1,7 @@ -#!/usr/bin/env python - -import os -import pkg_resources +#!/usr/bin/env python + +import os +from importlib import metadata def calc_container(path): total_size = 0 @@ -13,24 +13,28 @@ def calc_container(path): -dists = [d for d in pkg_resources.working_set] +dists = list(metadata.distributions()) data = {} data2 = [] data3 = {} -for dist in dists: - try: - path = os.path.join(dist.location, dist.project_name) - size = calc_container(path) - if size/1000 > 1.0: - #print (f"{dist}: {size/1000} KB") - data[size] = f"{dist}: {size/1000} KB" - a = f"{dist}" - data2.append(a.split()[0])# first word - data3[a.split()[0]] = f"{dist}: {size/1000} KB" - except OSError: - '{} no longer exists'.format(dist.project_name) +for dist in dists: + try: + dist_name = dist.metadata.get('Name', 'unknown') + path = os.path.join(str(dist.locate_file('')), dist_name) + if not os.path.exists(path): + path = os.path.join(str(dist.locate_file('')), dist_name.replace('-', '_')) + size = calc_container(path) + if size/1000 > 1.0: + #print (f"{dist}: {size/1000} KB") + dist_label = f"{dist_name} {dist.version}" + data[size] = f"{dist_label}: {size/1000} KB" + a = dist_label + data2.append(a.split()[0])# first word + data3[a.split()[0]] = f"{dist_label}: {size/1000} KB" + except OSError: + pass sorted_dict = dict(sorted(data.items())) sorted_dict2 = sorted(data2) diff --git a/setup.py b/setup.py index dea9620..728d21e 100755 --- a/setup.py +++ b/setup.py @@ -10,8 +10,8 @@ import os import sys import shutil -import pkg_resources import glob +from importlib import metadata from setuptools import setup, find_packages from setuptools.archive_util import unpack_archive @@ -130,9 +130,13 @@ except Exception: pass for dep in dependency_eggs_to_unpack: - for egg in pkg_resources.require(dep): - if not os.path.isdir(egg.location): - unpack_archive(egg.location, unpacked_eggs_dir) + try: + dist = metadata.distribution(dep) + except metadata.PackageNotFoundError: + continue + dist_location = str(dist.locate_file('')) + if not os.path.isdir(dist_location): + unpack_archive(dist_location, unpacked_eggs_dir) import qtawesome import qtconsole @@ -153,7 +157,7 @@ args['options'] = { 'build_exe': { 'packages': [ - 'pkg_resources', + 'importlib.metadata', 'zmq', 'pygments', 'jupyter_client', From 9dfc81a756b003005466e3a1081abd81f0228bef Mon Sep 17 00:00:00 2001 From: Troy Benjegerdes Date: Fri, 6 Mar 2026 20:42:37 -0600 Subject: [PATCH 2/2] Fix context has already been set error on Linux This fix suggested by Gemini resolves an error that occurs on some newer versions of python (specifically the one in Debian 13) --- dronecan_gui_tool/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronecan_gui_tool/main.py b/dronecan_gui_tool/main.py index 611ffc2..433594e 100644 --- a/dronecan_gui_tool/main.py +++ b/dronecan_gui_tool/main.py @@ -60,7 +60,7 @@ # Start method must be configured globally, and only once. Using 'spawn' ensures full compatibility with Windoze. # We need to check first if the start mode is already configured, because this code will be re-run for every child. # -if multiprocessing.get_start_method(True) != 'spawn': +if multiprocessing.get_start_method(allow_none=True) is None: multiprocessing.set_start_method('spawn') #