diff --git a/CHANGELOG b/CHANGELOG index 22084b2..e4c2730 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +0.15.10 + - ref: migrate from pkg_resources to importlib.resources (#33) 0.15.9 - build: fix installation directory - build: disable unsigned installer diff --git a/pyjibe/__main__.py b/pyjibe/__main__.py index 2e45e2e..7f8dbb5 100644 --- a/pyjibe/__main__.py +++ b/pyjibe/__main__.py @@ -1,23 +1,18 @@ def main(splash=True): - import os - import pkg_resources + import importlib.resources import sys from PyQt5.QtWidgets import QApplication from PyQt5.QtCore import QEventLoop app = QApplication(sys.argv) - # Note: - # Having the image file *not* in a submodule of PyJibe - # seems to cause the splash to display earlier, because - # presumably `pkg_resources` internally imports modules. - imdir = pkg_resources.resource_filename("pyjibe", "img") if splash: from PyQt5.QtWidgets import QSplashScreen from PyQt5.QtGui import QPixmap - splash_path = os.path.join(imdir, "splash.png") - splash_pix = QPixmap(splash_path) + ref = importlib.resources.files("pyjibe.img") / "splash.png" + with importlib.resources.as_file(ref) as splash_path: + splash_pix = QPixmap(str(splash_path)) splash = QSplashScreen(splash_pix) splash.setMask(splash_pix.mask()) splash.show() @@ -28,8 +23,9 @@ def main(splash=True): from .head import PyJibe # Set Application Icon - icon_path = os.path.join(imdir, "icon.png") - app.setWindowIcon(QtGui.QIcon(icon_path)) + ref = importlib.resources.files("pyjibe.img") / "icon.png" + with importlib.resources.as_file(ref) as icon_path: + app.setWindowIcon(QtGui.QIcon(str(icon_path))) # Use dots as decimal separators QtCore.QLocale.setDefault(QtCore.QLocale(QtCore.QLocale.C)) diff --git a/pyjibe/fd/dlg_export_vals.py b/pyjibe/fd/dlg_export_vals.py index 8ed5528..6fe9370 100644 --- a/pyjibe/fd/dlg_export_vals.py +++ b/pyjibe/fd/dlg_export_vals.py @@ -1,4 +1,4 @@ -import pkg_resources +import importlib.resources from PyQt5 import uic, QtWidgets @@ -11,9 +11,10 @@ class ExportDialog(QtWidgets.QDialog): def __init__(self, parent, fdist_list, identifier, *args, **kwargs): """Base class for force-indentation analysis""" super(ExportDialog, self).__init__(parent=parent, *args, **kwargs) - path_ui = pkg_resources.resource_filename("pyjibe.fd", - "dlg_export_vals.ui") - uic.loadUi(path_ui, self) + + ref = importlib.resources.files("pyjibe.fd") / "dlg_export_vals.ui" + with importlib.resources.as_file(ref) as path_ui: + uic.loadUi(path_ui, self) self.fdist_list = fdist_list self.identifier = identifier diff --git a/pyjibe/fd/main.py b/pyjibe/fd/main.py index c6af6e8..f40fa94 100644 --- a/pyjibe/fd/main.py +++ b/pyjibe/fd/main.py @@ -2,7 +2,7 @@ import io import os import pathlib -import pkg_resources +import importlib.resources import time import afmformats.errors @@ -22,9 +22,9 @@ # load QWidget from ui file -dlg_autosave_path = pkg_resources.resource_filename("pyjibe.fd", - "dlg_autosave_design.ui") -DlgAutosave = uic.loadUiType(dlg_autosave_path)[0] +dlg_ref = importlib.resources.files("pyjibe.fd") / "dlg_autosave_design.ui" +with importlib.resources.as_file(dlg_ref) as dlg_autosave_path: + DlgAutosave = uic.loadUiType(dlg_autosave_path)[0] class UiForceDistance(QtWidgets.QWidget): @@ -33,8 +33,9 @@ class UiForceDistance(QtWidgets.QWidget): def __init__(self, *args, **kwargs): """Base class for force-indentation analysis""" super(UiForceDistance, self).__init__(*args, **kwargs) - path_ui = pkg_resources.resource_filename("pyjibe.fd", "main.ui") - uic.loadUi(path_ui, self) + ref = importlib.resources.files("pyjibe.fd") / "main.ui" + with importlib.resources.as_file(ref) as path_ui: + uic.loadUi(path_ui, self) self.settings = QtCore.QSettings() self.settings.setIniCodec("utf-8") diff --git a/pyjibe/fd/rating_iface.py b/pyjibe/fd/rating_iface.py index e0dfd46..1090786 100644 --- a/pyjibe/fd/rating_iface.py +++ b/pyjibe/fd/rating_iface.py @@ -1,15 +1,15 @@ import os import pathlib -import pkg_resources +import importlib.resources from nanite.rate import io as nio from PyQt5 import uic, QtCore, QtWidgets # load QWidget from ui file -ui_path = pkg_resources.resource_filename("pyjibe.fd", - "rating_iface.ui") -UiUserRatingBase = uic.loadUiType(ui_path)[0] +ui_ref = importlib.resources.files("pyjibe.fd") / "rating_iface.ui" +with importlib.resources.as_file(ui_ref) as path_ui: + UiUserRatingBase = uic.loadUiType(path_ui)[0] class Rater(QtWidgets.QWidget, UiUserRatingBase): diff --git a/pyjibe/fd/tab_edelta.py b/pyjibe/fd/tab_edelta.py index 6e9f93c..5735d1a 100644 --- a/pyjibe/fd/tab_edelta.py +++ b/pyjibe/fd/tab_edelta.py @@ -1,4 +1,4 @@ -import pkg_resources +import importlib.resources import numpy as np from PyQt5 import uic, QtCore, QtWidgets @@ -10,9 +10,9 @@ class TabEdelta(QtWidgets.QWidget): def __init__(self, *args, **kwargs): super(TabEdelta, self).__init__(*args, **kwargs) - path_ui = pkg_resources.resource_filename("pyjibe.fd", - "tab_edelta.ui") - uic.loadUi(path_ui, self) + ref = importlib.resources.files("pyjibe.fd") / "tab_edelta.ui" + with importlib.resources.as_file(ref) as path_ui: + uic.loadUi(path_ui, self) self.mpl_edelta_setup() diff --git a/pyjibe/fd/tab_fit.py b/pyjibe/fd/tab_fit.py index 99a1094..2b91d21 100644 --- a/pyjibe/fd/tab_fit.py +++ b/pyjibe/fd/tab_fit.py @@ -1,4 +1,4 @@ -import pkg_resources +import importlib.resources import nanite.model as nmodel import numpy as np @@ -10,9 +10,10 @@ class TabFit(QtWidgets.QWidget): def __init__(self, *args, **kwargs): super(TabFit, self).__init__(*args, **kwargs) - path_ui = pkg_resources.resource_filename("pyjibe.fd", - "tab_fit.ui") - uic.loadUi(path_ui, self) + + ref = importlib.resources.files("pyjibe.fd") / "tab_fit.ui" + with importlib.resources.as_file(ref) as path_ui: + uic.loadUi(path_ui, self) # Setup the fitting tab id_para = 0 diff --git a/pyjibe/fd/tab_info.py b/pyjibe/fd/tab_info.py index cad44c0..cf9fb20 100644 --- a/pyjibe/fd/tab_info.py +++ b/pyjibe/fd/tab_info.py @@ -1,5 +1,5 @@ import numbers -import pkg_resources +import importlib.resources from afmformats import meta from nanite import model @@ -12,9 +12,9 @@ class TabInfo(QtWidgets.QWidget): def __init__(self, *args, **kwargs): super(TabInfo, self).__init__(*args, **kwargs) - path_ui = pkg_resources.resource_filename("pyjibe.fd", - "tab_info.ui") - uic.loadUi(path_ui, self) + ref = importlib.resources.files("pyjibe.fd") / "tab_info.ui" + with importlib.resources.as_file(ref) as path_ui: + uic.loadUi(path_ui, self) def update_info(self, fdist): hr_info = {} diff --git a/pyjibe/fd/tab_preprocess.py b/pyjibe/fd/tab_preprocess.py index 00bdc52..1a0253d 100644 --- a/pyjibe/fd/tab_preprocess.py +++ b/pyjibe/fd/tab_preprocess.py @@ -1,4 +1,4 @@ -import pkg_resources +import importlib.resources from nanite import preproc from PyQt5 import uic, QtCore, QtWidgets @@ -9,9 +9,9 @@ class TabPreprocess(QtWidgets.QWidget): def __init__(self, *args, **kwargs): super(TabPreprocess, self).__init__(*args, **kwargs) - path_ui = pkg_resources.resource_filename("pyjibe.fd", - "tab_preprocess.ui") - uic.loadUi(path_ui, self) + ref = importlib.resources.files("pyjibe.fd") / "tab_preprocess.ui" + with importlib.resources.as_file(ref) as path_ui: + uic.loadUi(path_ui, self) # Setup everything necessary for the preprocessing tab: # Get list of preprocessing methods diff --git a/pyjibe/fd/tab_qmap.py b/pyjibe/fd/tab_qmap.py index 8d66406..ab1d55f 100644 --- a/pyjibe/fd/tab_qmap.py +++ b/pyjibe/fd/tab_qmap.py @@ -1,4 +1,4 @@ -import pkg_resources +import importlib.resources import nanite from PyQt5 import uic, QtCore, QtWidgets @@ -23,9 +23,9 @@ def get_qmap(fdist_group): class TabQMap(QtWidgets.QWidget): def __init__(self, *args, **kwargs): super(TabQMap, self).__init__(*args, **kwargs) - path_ui = pkg_resources.resource_filename("pyjibe.fd", - "tab_qmap.ui") - uic.loadUi(path_ui, self) + ref = importlib.resources.files("pyjibe.fd") / "tab_qmap.ui" + with importlib.resources.as_file(ref) as path_ui: + uic.loadUi(path_ui, self) # Setup the matplotlib interface for 2D map plotting self.mpl_qmap = MPLQMap() diff --git a/pyjibe/fd/widget_preprocess_item.py b/pyjibe/fd/widget_preprocess_item.py index 987e858..2c10498 100644 --- a/pyjibe/fd/widget_preprocess_item.py +++ b/pyjibe/fd/widget_preprocess_item.py @@ -1,4 +1,4 @@ -import pkg_resources +import importlib.resources from nanite import preproc from PyQt5 import QtCore, QtWidgets, uic @@ -12,10 +12,10 @@ def __init__(self, identifier, *args, **kwargs): """Special widget for preprocessing options""" self.identifier = identifier super(WidgetPreprocessItem, self).__init__(*args, **kwargs) - - path_ui = pkg_resources.resource_filename("pyjibe.fd", - "widget_preprocess_item.ui") - uic.loadUi(path_ui, self) + ref = (importlib.resources.files("pyjibe.fd") / + "widget_preprocess_item.ui") + with importlib.resources.as_file(ref) as path_ui: + uic.loadUi(path_ui, self) # set label text name = preproc.get_name(identifier) diff --git a/pyjibe/head/custom_widgets/mpl_navigation_toolbar_icons.py b/pyjibe/head/custom_widgets/mpl_navigation_toolbar_icons.py index 1b9a892..808c222 100644 --- a/pyjibe/head/custom_widgets/mpl_navigation_toolbar_icons.py +++ b/pyjibe/head/custom_widgets/mpl_navigation_toolbar_icons.py @@ -1,5 +1,5 @@ import os -import pkg_resources +import importlib.resources from PyQt5 import QtCore, QtGui, QtWidgets @@ -19,11 +19,16 @@ def __init__(self, *args, **kwargs): def _icon(self, name, color=None): """Override matplotlibs `_icon` function to get custom icons""" name = name.replace('.png', '_large.png') - impath = str(cbook._get_data_path('images', name)) - if not os.path.exists(impath): - imdir = pkg_resources.resource_filename("pyjibe", "img") - impath = os.path.join(imdir, name) - pm = QtGui.QPixmap(impath) + impath = cbook._get_data_path('images', name) + pm = None # Initialize pm to None + if os.path.exists(impath): + pm = QtGui.QPixmap(str(impath)) + else: + ref = importlib.resources.files("pyjibe.img") / name + with importlib.resources.as_file(ref) as ref_path: + pm = QtGui.QPixmap(str(ref_path)) + if pm is None or pm.isNull(): + raise ValueError(f"Could not find image '{name}'") pm.setDevicePixelRatio(self.devicePixelRatioF() or 1) if self.palette().color(self.backgroundRole()).value() < 128: icon_color = self.palette().color(self.foregroundRole()) diff --git a/pyjibe/head/dlg_tool_convert.py b/pyjibe/head/dlg_tool_convert.py index 0944bad..8647ae4 100644 --- a/pyjibe/head/dlg_tool_convert.py +++ b/pyjibe/head/dlg_tool_convert.py @@ -1,7 +1,7 @@ import codecs import hashlib import pathlib -import pkg_resources +import importlib.resources import afmformats import h5py @@ -14,9 +14,9 @@ class ConvertDialog(QtWidgets.QDialog): def __init__(self, parent, *args, **kwargs): """Data conversion dialog""" super(ConvertDialog, self).__init__(parent=parent, *args, **kwargs) - path_ui = pkg_resources.resource_filename("pyjibe.head", - "dlg_tool_convert.ui") - uic.loadUi(path_ui, self) + ref = importlib.resources.files("pyjibe.head") / "dlg_tool_convert.ui" + with importlib.resources.as_file(ref) as path_ui: + uic.loadUi(path_ui, self) self._file_list = [] diff --git a/pyjibe/head/main.py b/pyjibe/head/main.py index 0bc7286..cad6e6a 100644 --- a/pyjibe/head/main.py +++ b/pyjibe/head/main.py @@ -1,7 +1,7 @@ # flake8: noqa: E402 (matplotlib.use has to be right after the import) import os.path as os_path import pathlib -import pkg_resources +import importlib.resources import signal import sys import traceback @@ -66,8 +66,9 @@ def __init__(self, *args, **kwargs): self._update_worker = None # load ui files - path_ui = pkg_resources.resource_filename("pyjibe.head", "main.ui") - uic.loadUi(path_ui, self) + ref = importlib.resources.files("pyjibe.head") / "main.ui" + with importlib.resources.as_file(ref) as path_ui: + uic.loadUi(path_ui, self) self.setWindowTitle("PyJibe {}".format(__version__)) # Disable native menubar (e.g. on Mac) diff --git a/pyjibe/head/preferences.py b/pyjibe/head/preferences.py index 736e619..76e9aa3 100644 --- a/pyjibe/head/preferences.py +++ b/pyjibe/head/preferences.py @@ -1,5 +1,5 @@ import os.path as os_path -import pkg_resources +import importlib.resources import traceback import nanite @@ -35,9 +35,9 @@ class Preferences(QtWidgets.QDialog): def __init__(self, parent, *args, **kwargs): QtWidgets.QWidget.__init__(self, parent=parent, *args, **kwargs) - path_ui = pkg_resources.resource_filename( - "pyjibe.head", "preferences.ui") - uic.loadUi(path_ui, self) + ref = importlib.resources.files("pyjibe.head") / "preferences.ui" + with importlib.resources.as_file(ref) as path_ui: + uic.loadUi(path_ui, self) self.settings = QtCore.QSettings() self.parent = parent diff --git a/pyproject.toml b/pyproject.toml index 5653100..e883657 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,8 +2,7 @@ # Defined by PEP 518: requires = [ # for version management - "setuptools>=45", - "setuptools_scm[toml]>=6.2", + "setuptools_scm[toml]>=6.2" ] build-backend = "setuptools.build_meta"