From b087fd91eafc667bddc75a936cd6abdb5c2f62b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marta=20Marczykowska-G=C3=B3recka?= Date: Mon, 6 May 2024 17:37:47 +0200 Subject: [PATCH 1/3] Remove deprecated pkg_resources, replace with importlib references QubesOS/qubes-issues#9195 --- qubesappmenus/__init__.py | 21 +++++---- qubesappmenus/receive.py | 9 ++-- qubesappmenus/tests.py | 89 ++++++++++++++++++++++++--------------- 3 files changed, 71 insertions(+), 48 deletions(-) diff --git a/qubesappmenus/__init__.py b/qubesappmenus/__init__.py index 2e89ae3..a8bf14e 100644 --- a/qubesappmenus/__init__.py +++ b/qubesappmenus/__init__.py @@ -30,7 +30,7 @@ import logging import itertools -import pkg_resources +import importlib.resources import xdg.BaseDirectory import qubesadmin @@ -345,11 +345,11 @@ def _appmenus_create_onedir(self, vm, force=False, refresh_cache=True, anything_changed = False directory_changed = False directory_file = self._directory_path(vm, dispvm=dispvm) + data = importlib.resources.files(__name__).joinpath( + self.directory_template_name(vm, dispvm)).read_text() if self.write_desktop_file( vm, - pkg_resources.resource_string( - __name__, - self.directory_template_name(vm, dispvm)).decode(), + data, directory_file, dispvm): anything_changed = True @@ -384,12 +384,11 @@ def _appmenus_create_onedir(self, vm, force=False, refresh_cache=True, if not dispvm: vm_settings_fname = os.path.join( appmenus_dir, self.settings_name(vm)) + data = importlib.resources.files(__name__).joinpath( + 'qubes-vm-settings.desktop.template').read_text() if self.write_desktop_file( vm, - pkg_resources.resource_string( - __name__, - 'qubes-vm-settings.desktop.template' - ).decode(), + data, vm_settings_fname): changed_appmenus.append(vm_settings_fname) target_appmenus.append(os.path.basename(vm_settings_fname)) @@ -598,9 +597,9 @@ def appmenus_init(self, vm, src=None): with open( os.path.join(own_templates_dir, 'qubes-start.desktop'), 'wb') as qubes_start_f: - qubes_start_f.write(pkg_resources.resource_string( - __name__, - 'qubes-start.desktop.template')) + data = importlib.resources.files(__name__).joinpath( + 'qubes-start.desktop.template').read_bytes() + qubes_start_f.write(data) source_whitelist_filename = 'vm-' + AppmenusSubdirs.whitelist if src and ('default-menu-items' in src.features or os.path.exists( diff --git a/qubesappmenus/receive.py b/qubesappmenus/receive.py index e7ef4ef..98be373 100755 --- a/qubesappmenus/receive.py +++ b/qubesappmenus/receive.py @@ -27,7 +27,7 @@ import os import sys import shlex -import pkg_resources +import importlib.resources import qubesimgconverter import qubesadmin.exc @@ -305,9 +305,10 @@ def process_appmenus_templates(appmenusext, vm, appmenus): if not os.path.exists(qubes_start_fname): with open(qubes_start_fname, 'wb') as qubes_start_f: vm.log.info("Creating Start") - qubes_start_f.write(pkg_resources.resource_string( - __name__, - 'qubes-start.desktop.template')) + template_data = importlib.resources.files( + __name__).joinpath( + 'qubes-start.desktop.template').read_bytes() + qubes_start_f.write(template_data) # Do not create reserved Start entry appmenus.pop('qubes-start', None) diff --git a/qubesappmenus/tests.py b/qubesappmenus/tests.py index 945b23a..0035c26 100644 --- a/qubesappmenus/tests.py +++ b/qubesappmenus/tests.py @@ -31,7 +31,7 @@ import unittest.mock import logging -import pkg_resources +import importlib.resources import qubesappmenus import qubesappmenus.receive @@ -247,16 +247,19 @@ def test_005_created_appvm(self): self.ext.appmenus_init(appvm) with open(os.path.join(self.ext.templates_dirs(tpl)[0], 'evince.desktop'), 'wb') as f: - f.write(pkg_resources.resource_string(__name__, - 'test-data/evince.desktop.template')) + f.write(importlib.resources.files( + anchor=__name__).joinpath( + 'test-data/evince.desktop.template').read_bytes()) self.ext.appmenus_create(appvm, refresh_cache=False) self.ext.appicons_create(appvm) evince_path = self._make_desktop_name(appvm, 'evince.desktop') self.assertPathExists(evince_path) with open(evince_path, 'rb') as f: + new_file_bytes = importlib.resources.files( + anchor=__name__).joinpath( + 'test-data/evince.desktop').read_bytes() self.assertEqual( - pkg_resources.resource_string(__name__, - 'test-data/evince.desktop').replace(b'%BASEDIR%', + new_file_bytes.replace(b'%BASEDIR%', qubesappmenus.basedir.encode()), f.read() ) @@ -279,27 +282,34 @@ def test_006_created_appvm_custom(self): self.ext.appmenus_init(appvm) with open(os.path.join(self.ext.templates_dirs(tpl)[0], 'evince.desktop'), 'wb') as f: - f.write(pkg_resources.resource_string(__name__, - 'test-data/evince.desktop.template')) + evince_data = importlib.resources.files( + anchor=__name__).joinpath( + 'test-data/evince.desktop.template').read_bytes() + f.write(evince_data) self.ext.appmenus_create(appvm, refresh_cache=False) self.ext.appicons_create(appvm) with open(os.path.join(self.ext.templates_dirs(tpl)[0], 'xterm.desktop'), 'wb') as f: - f.write(pkg_resources.resource_string(__name__, - 'test-data/xterm.desktop.template')) + xterm_data = importlib.resources.files( + anchor=__name__).joinpath( + 'test-data/xterm.desktop.template').read_bytes() + f.write(xterm_data) with open(os.path.join(self.ext.templates_dirs(tpl)[0], 'evince.desktop'), 'wb') as f: - f.write(pkg_resources.resource_string(__name__, - 'test-data/evince.desktop.template'). - replace(b'Document Viewer', b'Random Viewer')) + evince_data = importlib.resources.files( + anchor=__name__).joinpath( + 'test-data/evince.desktop.template').read_bytes() + f.write(evince_data.replace(b'Document Viewer', b'Random Viewer')) self.ext.appmenus_update(appvm) evince_path = self._make_desktop_name(appvm, 'evince.desktop') self.assertPathExists(evince_path) with open(evince_path, 'rb') as f: + evince_data = importlib.resources.files( + anchor=__name__).joinpath( + 'test-data/evince.desktop').read_bytes() self.assertEqual( - pkg_resources.resource_string(__name__, - 'test-data/evince.desktop') + evince_data .replace(b'%BASEDIR%', qubesappmenus.basedir.encode()) .replace(b'Document Viewer', b'Random Viewer'), f.read() @@ -308,9 +318,10 @@ def test_006_created_appvm_custom(self): xterm_path = self._make_desktop_name(appvm, 'xterm.desktop') self.assertPathExists(xterm_path) with open(xterm_path, 'rb') as f: - self.assertEqual( - pkg_resources.resource_string(__name__, - 'test-data/xterm.desktop') + xterm_data = importlib.resources.files( + anchor=__name__).joinpath( + 'test-data/xterm.desktop').read_bytes() + self.assertEqual(xterm_data .replace(b'%BASEDIR%', qubesappmenus.basedir.encode()), f.read() ) @@ -335,8 +346,10 @@ def test_007_created_dispvm(self): self.ext.appmenus_init(appvm) with open(os.path.join(self.ext.templates_dirs(tpl)[0], 'evince.desktop'), 'wb') as f: - f.write(pkg_resources.resource_string(__name__, - 'test-data/evince.desktop.template')) + evince_data = importlib.resources.files( + anchor=__name__).joinpath( + 'test-data/evince.desktop.template').read_bytes() + f.write(evince_data) self.ext.appmenus_create(appvm, refresh_cache=False) self.ext.appicons_create(appvm) appmenus_dir = self.ext.appmenus_dir(appvm) @@ -386,8 +399,8 @@ class PopenMockup(object): pass self.assertEqual(service, 'qubes.GetAppmenus') p = PopenMockup() - p.stdout = pkg_resources.resource_stream(__name__, - 'test-data/appmenus.input') + p.stdout = importlib.resources.files( + anchor=__name__).joinpath('test-data/appmenus.input').open(mode='rb') p.wait = lambda: None p.returncode = 0 return p @@ -509,8 +522,10 @@ def test_120_create_appvm(self, mock_subprocess): old_path = os.path.join(self.ext.templates_dirs(tpl)[0], 'evince.desktop') with open(old_path, 'wb') as f: - f.write(pkg_resources.resource_string(__name__, - 'test-data/evince.desktop.template')) + evince_data = importlib.resources.files( + anchor=__name__).joinpath( + 'test-data/evince.desktop.template').read_bytes() + f.write(evince_data) appvm = TestVM('test-inst-app', klass='AppVM', template=tpl, @@ -536,10 +551,12 @@ def test_120_create_appvm(self, mock_subprocess): evince_path = self._make_desktop_name(appvm, 'evince.desktop') self.assertPathExists(evince_path) with open(evince_path, 'rb') as f: + evince_data = importlib.resources.files( + anchor=__name__).joinpath( + 'test-data/evince.desktop').read_bytes() self.assertEqual( - pkg_resources.resource_string(__name__, - 'test-data/evince.desktop').replace(b'%BASEDIR%', - qubesappmenus.basedir.encode()), + evince_data.replace(b'%BASEDIR%', + qubesappmenus.basedir.encode()), f.read() ) @@ -583,8 +600,10 @@ def test_121_create_appvm_with_whitelist(self, mock_subprocess): self.ext.appmenus_init(tpl) with open(os.path.join(self.ext.templates_dirs(tpl)[0], 'evince.desktop'), 'wb') as f: - f.write(pkg_resources.resource_string(__name__, - 'test-data/evince.desktop.template')) + evince_data = importlib.resources.files( + anchor=__name__).joinpath( + 'test-data/evince.desktop.template').read_bytes() + f.write(evince_data) with open(os.path.join(self.basedir, tpl.name, 'vm-whitelisted-appmenus.list'), 'wb') as f: @@ -601,10 +620,12 @@ def test_121_create_appvm_with_whitelist(self, mock_subprocess): evince_path = self._make_desktop_name(appvm, 'evince.desktop') self.assertPathExists(evince_path) with open(evince_path, 'rb') as f: + evince_data = importlib.resources.files( + anchor=__name__).joinpath( + 'test-data/evince.desktop').read_bytes() self.assertEqual( - pkg_resources.resource_string(__name__, - 'test-data/evince.desktop').replace(b'%BASEDIR%', - qubesappmenus.basedir.encode()), + evince_data.replace(b'%BASEDIR%', + qubesappmenus.basedir.encode()), f.read() ) @@ -666,9 +687,11 @@ class PopenMockup(object): 'evince.desktop') self.assertPathExists(evince_path) with open(evince_path, 'rb') as f: + evince_data = importlib.resources.files( + anchor=__name__).joinpath( + 'test-data/evince.desktop.template').read_bytes() self.assertEqual( - pkg_resources.resource_string(__name__, - 'test-data/evince.desktop.template'), + evince_data, f.read() ) self.assertCountEqual(self.appvm.log.mock_calls, [ From 48b332d4abf00c316b56b078a8c02fcac0bce61e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marta=20Marczykowska-G=C3=B3recka?= Date: Fri, 3 Jan 2025 18:39:14 +0100 Subject: [PATCH 2/3] Backwards compatibility for importlib Use parameter format compatible with Python <= 3.10 --- qubesappmenus/__init__.py | 6 +++--- qubesappmenus/receive.py | 2 +- qubesappmenus/tests.py | 28 ++++++++++++++-------------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/qubesappmenus/__init__.py b/qubesappmenus/__init__.py index a8bf14e..c6ead61 100644 --- a/qubesappmenus/__init__.py +++ b/qubesappmenus/__init__.py @@ -345,7 +345,7 @@ def _appmenus_create_onedir(self, vm, force=False, refresh_cache=True, anything_changed = False directory_changed = False directory_file = self._directory_path(vm, dispvm=dispvm) - data = importlib.resources.files(__name__).joinpath( + data = importlib.resources.files(__package__).joinpath( self.directory_template_name(vm, dispvm)).read_text() if self.write_desktop_file( vm, @@ -384,7 +384,7 @@ def _appmenus_create_onedir(self, vm, force=False, refresh_cache=True, if not dispvm: vm_settings_fname = os.path.join( appmenus_dir, self.settings_name(vm)) - data = importlib.resources.files(__name__).joinpath( + data = importlib.resources.files(__package__).joinpath( 'qubes-vm-settings.desktop.template').read_text() if self.write_desktop_file( vm, @@ -597,7 +597,7 @@ def appmenus_init(self, vm, src=None): with open( os.path.join(own_templates_dir, 'qubes-start.desktop'), 'wb') as qubes_start_f: - data = importlib.resources.files(__name__).joinpath( + data = importlib.resources.files(__package__).joinpath( 'qubes-start.desktop.template').read_bytes() qubes_start_f.write(data) diff --git a/qubesappmenus/receive.py b/qubesappmenus/receive.py index 98be373..1071e59 100755 --- a/qubesappmenus/receive.py +++ b/qubesappmenus/receive.py @@ -306,7 +306,7 @@ def process_appmenus_templates(appmenusext, vm, appmenus): with open(qubes_start_fname, 'wb') as qubes_start_f: vm.log.info("Creating Start") template_data = importlib.resources.files( - __name__).joinpath( + __package__).joinpath( 'qubes-start.desktop.template').read_bytes() qubes_start_f.write(template_data) diff --git a/qubesappmenus/tests.py b/qubesappmenus/tests.py index 0035c26..2fb3714 100644 --- a/qubesappmenus/tests.py +++ b/qubesappmenus/tests.py @@ -248,7 +248,7 @@ def test_005_created_appvm(self): with open(os.path.join(self.ext.templates_dirs(tpl)[0], 'evince.desktop'), 'wb') as f: f.write(importlib.resources.files( - anchor=__name__).joinpath( + __package__).joinpath( 'test-data/evince.desktop.template').read_bytes()) self.ext.appmenus_create(appvm, refresh_cache=False) self.ext.appicons_create(appvm) @@ -256,7 +256,7 @@ def test_005_created_appvm(self): self.assertPathExists(evince_path) with open(evince_path, 'rb') as f: new_file_bytes = importlib.resources.files( - anchor=__name__).joinpath( + __package__).joinpath( 'test-data/evince.desktop').read_bytes() self.assertEqual( new_file_bytes.replace(b'%BASEDIR%', @@ -283,7 +283,7 @@ def test_006_created_appvm_custom(self): with open(os.path.join(self.ext.templates_dirs(tpl)[0], 'evince.desktop'), 'wb') as f: evince_data = importlib.resources.files( - anchor=__name__).joinpath( + __package__).joinpath( 'test-data/evince.desktop.template').read_bytes() f.write(evince_data) self.ext.appmenus_create(appvm, refresh_cache=False) @@ -292,13 +292,13 @@ def test_006_created_appvm_custom(self): with open(os.path.join(self.ext.templates_dirs(tpl)[0], 'xterm.desktop'), 'wb') as f: xterm_data = importlib.resources.files( - anchor=__name__).joinpath( + __package__).joinpath( 'test-data/xterm.desktop.template').read_bytes() f.write(xterm_data) with open(os.path.join(self.ext.templates_dirs(tpl)[0], 'evince.desktop'), 'wb') as f: evince_data = importlib.resources.files( - anchor=__name__).joinpath( + __package__).joinpath( 'test-data/evince.desktop.template').read_bytes() f.write(evince_data.replace(b'Document Viewer', b'Random Viewer')) self.ext.appmenus_update(appvm) @@ -306,7 +306,7 @@ def test_006_created_appvm_custom(self): self.assertPathExists(evince_path) with open(evince_path, 'rb') as f: evince_data = importlib.resources.files( - anchor=__name__).joinpath( + __package__).joinpath( 'test-data/evince.desktop').read_bytes() self.assertEqual( evince_data @@ -319,7 +319,7 @@ def test_006_created_appvm_custom(self): self.assertPathExists(xterm_path) with open(xterm_path, 'rb') as f: xterm_data = importlib.resources.files( - anchor=__name__).joinpath( + __package__).joinpath( 'test-data/xterm.desktop').read_bytes() self.assertEqual(xterm_data .replace(b'%BASEDIR%', qubesappmenus.basedir.encode()), @@ -347,7 +347,7 @@ def test_007_created_dispvm(self): with open(os.path.join(self.ext.templates_dirs(tpl)[0], 'evince.desktop'), 'wb') as f: evince_data = importlib.resources.files( - anchor=__name__).joinpath( + __package__).joinpath( 'test-data/evince.desktop.template').read_bytes() f.write(evince_data) self.ext.appmenus_create(appvm, refresh_cache=False) @@ -400,7 +400,7 @@ class PopenMockup(object): self.assertEqual(service, 'qubes.GetAppmenus') p = PopenMockup() p.stdout = importlib.resources.files( - anchor=__name__).joinpath('test-data/appmenus.input').open(mode='rb') + __package__).joinpath('test-data/appmenus.input').open(mode='rb') p.wait = lambda: None p.returncode = 0 return p @@ -523,7 +523,7 @@ def test_120_create_appvm(self, mock_subprocess): 'evince.desktop') with open(old_path, 'wb') as f: evince_data = importlib.resources.files( - anchor=__name__).joinpath( + __package__).joinpath( 'test-data/evince.desktop.template').read_bytes() f.write(evince_data) appvm = TestVM('test-inst-app', @@ -552,7 +552,7 @@ def test_120_create_appvm(self, mock_subprocess): self.assertPathExists(evince_path) with open(evince_path, 'rb') as f: evince_data = importlib.resources.files( - anchor=__name__).joinpath( + __package__).joinpath( 'test-data/evince.desktop').read_bytes() self.assertEqual( evince_data.replace(b'%BASEDIR%', @@ -601,7 +601,7 @@ def test_121_create_appvm_with_whitelist(self, mock_subprocess): with open(os.path.join(self.ext.templates_dirs(tpl)[0], 'evince.desktop'), 'wb') as f: evince_data = importlib.resources.files( - anchor=__name__).joinpath( + __package__).joinpath( 'test-data/evince.desktop.template').read_bytes() f.write(evince_data) with open(os.path.join(self.basedir, @@ -621,7 +621,7 @@ def test_121_create_appvm_with_whitelist(self, mock_subprocess): self.assertPathExists(evince_path) with open(evince_path, 'rb') as f: evince_data = importlib.resources.files( - anchor=__name__).joinpath( + __package__).joinpath( 'test-data/evince.desktop').read_bytes() self.assertEqual( evince_data.replace(b'%BASEDIR%', @@ -688,7 +688,7 @@ class PopenMockup(object): self.assertPathExists(evince_path) with open(evince_path, 'rb') as f: evince_data = importlib.resources.files( - anchor=__name__).joinpath( + __package__).joinpath( 'test-data/evince.desktop.template').read_bytes() self.assertEqual( evince_data, From 42def0686aa6b8d737eda02d7cdf4023b830a760 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marta=20Marczykowska-G=C3=B3recka?= Date: Fri, 3 Jan 2025 18:51:43 +0100 Subject: [PATCH 3/3] Fix pylint complaint --- qubesappmenus/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qubesappmenus/__init__.py b/qubesappmenus/__init__.py index c6ead61..a7e3ae8 100644 --- a/qubesappmenus/__init__.py +++ b/qubesappmenus/__init__.py @@ -324,7 +324,7 @@ def appmenus_create(self, vm, force=False, refresh_cache=True): self._appmenus_create_onedir( vm, force=force, refresh_cache=refresh_cache, dispvm=True) - def _appmenus_create_onedir(self, vm, force=False, refresh_cache=True, + def _appmenus_create_onedir(self, vm, *, force=False, refresh_cache=True, dispvm=False, keep_dispvm=False): """Create/update .desktop files