Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

migrate from pkg_resources to importlib_resources #132

Merged
merged 12 commits into from
Dec 6, 2024
55 changes: 36 additions & 19 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# This workflow will lint, run unit tests, test CLI and build with a variety of Python versions
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions

# 06.12.2024: modified slightly with inspiration from:
# https://github.com/marketplace/actions/install-poetry-action#testing-using-a-matrix

name: Test Python package

on:
Expand All @@ -10,6 +13,9 @@ on:
branches: [ master ]

jobs:
#----------------------------------------------
# linting
#----------------------------------------------
linting:
name: Linting
# linting has nothing to do with multiple versions of os and python
Expand All @@ -36,6 +42,9 @@ jobs:
black .
isort .

#----------------------------------------------
# test using a matrix
#----------------------------------------------
testing:
needs: linting
name: Test with Python ${{ matrix.python-version }} on ${{ matrix.os }}
Expand All @@ -44,50 +53,54 @@ jobs:
fail-fast: false
matrix:
os: ["ubuntu-latest"]
python-version: ["3.8", "3.9", "3.10", "3.11"]

python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
steps:
# https://stackoverflow.com/questions/75549995/why-do-the-pyside6-qt-modules-cause-tox-to-fail-during-a-github-action
- name: Install missing libraries on GitHub agent
run: sudo apt update && sudo apt install -y libegl1-mesa-dev
#----------------------------------------------
# check-out repo and set-up python
#----------------------------------------------
- name: Check out repository
uses: actions/checkout@v4
- name: Set up python ${{ matrix.python-version }}
id: setup-python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Load cached Poetry installation
id: cached-poetry
uses: actions/cache@v4
with:
path: ~/.local # the path depends on the OS
key: poetry-0 # increment to reset cache
- name: Install and configure Poetry
# install if not cached. Create venv in project to simplify caching
if: steps.cached-poetry.outputs.cache-hit != 'true'
#----------------------------------------------
# install & configure poetry
#----------------------------------------------
- name: Install Poetry
uses: snok/install-poetry@v1
with:
# Consider specifying version (version: 1.7.1 on Python 3.11)
virtualenvs-create: true
virtualenvs-in-project: true #.venv in current directory
virtualenvs-in-project: true
- name: Install dynamic versioning plugin
run: poetry self add "poetry-dynamic-versioning[plugin]"
#----------------------------------------------
# load cached venv if cache exists
#----------------------------------------------
- name: Load cached venv
id: cached-poetry-dependencies
uses: actions/cache@v4
with:
path: .venv
key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }}
- name: Create venv and install project dependencies
# install if not cached
#----------------------------------------------
# install dependencies if cache does not exist
#----------------------------------------------
- name: Install dependencies
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: poetry install --no-interaction --no-root
#----------------------------------------------
# install root project, if required
#----------------------------------------------
- name: Install project
# required to test the CLI, show working directory for debugging
run: |
poetry install --no-interaction
ls -a
run: poetry install --no-interaction
#----------------------------------------------
# run tests
#----------------------------------------------
- name: Run unit tests
run: |
source .venv/bin/activate
Expand All @@ -107,6 +120,10 @@ jobs:
run: |
source .venv/bin/activate
sphinx-build -b html docs/source docs/_build
#----------------------------------------------
# upload artifacts
# (only done for one of the python versions)
#----------------------------------------------
- name: Upload artifacts
if: ${{ matrix.python-version == '3.11' }}
uses: actions/upload-artifact@v4
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ scipy = [
]
pywin32 = {version = "^306", markers = "platform_system == 'Windows'"} # MUST check the appropriate constraint
pyside6 = "^6.6.0"
importlib-resources = "*"

[tool.poetry.group.dev.dependencies]
pytest = "^7.4.3"
Expand Down
13 changes: 11 additions & 2 deletions qats/app/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from matplotlib.backends.backend_qt5agg import \
NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
from pkg_resources import resource_filename
import importlib_resources, contextlib, atexit
from qtpy import API_NAME as QTPY_API_NAME
from qtpy.QtCore import *
from qtpy.QtGui import *
Expand All @@ -44,12 +44,21 @@
warning=logging.WARNING,
error=logging.ERROR,
)
# define path to settings file
if sys.platform == "win32":
SETTINGS_FILE = os.path.join(os.getenv("APPDATA", os.getenv("USERPROFILE", "")), "qats.settings")
else:
SETTINGS_FILE = os.path.join("~", ".config", "qats.settings")
ICON_FILE = resource_filename("qats.app", "qats.ico")

# create icon file handle
# ref. https://importlib-resources.readthedocs.io/en/latest/migration.html#pkg-resources-resource-filename
icofile_manager = contextlib.ExitStack()
atexit.register(icofile_manager.close)
icoref = importlib_resources.files("qats.app") / "qats.ico"
ICON_PATH = icofile_manager.enter_context(importlib_resources.as_file(icoref))
ICON_FILE = str(ICON_PATH.absolute())

# define statistics to calculate
STATS_ORDER = ["name", "min", "max", "mean", "std", "skew", "kurt", "tz", "wloc", "wscale", "wshape",
"gloc", "gscale", "p_37.00", "p_57.00", "p_90.00"]
STATS_LABELS_TOOLTIPS = {
Expand Down
26 changes: 13 additions & 13 deletions qats/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
import argparse
import os
import sys
import importlib_resources

from pkg_resources import resource_filename
from qtpy.QtWidgets import QApplication

from . import __version__
Expand All @@ -27,8 +27,7 @@ def link_app():
from win32com.client import Dispatch

pkg_name = "qats"
ico_path = resource_filename("qats.app", "qats.ico")
# target = os.path.join(scripts_dir, f"{pkg_name}-app.exe")
ico_ref = importlib_resources.files("qats.app") / "qats.ico"
lnk_name = pkg_name.upper() + ".lnk"

# define target as pythonw.exe (or python.exe if needed)
Expand All @@ -48,16 +47,17 @@ def link_app():
shell = Dispatch("WScript.Shell")

# create shortcuts to gui in desktop folder and start-menu programs
for loc in ("Desktop", "Programs"):
location = shell.SpecialFolders(loc)
path_link = os.path.join(location, lnk_name)
shortcut = shell.CreateShortCut(path_link)
shortcut.Description = f"{pkg_name.upper()} v{__version__}"
shortcut.TargetPath = target
shortcut.Arguments = arguments
shortcut.WorkingDirectory = os.getenv("USERPROFILE")
shortcut.IconLocation = ico_path
shortcut.Save()
with importlib_resources.as_file(ico_ref) as ico_path:
for loc in ("Desktop", "Programs"):
location = shell.SpecialFolders(loc)
path_link = os.path.join(location, lnk_name)
shortcut = shell.CreateShortCut(path_link)
shortcut.Description = f"{pkg_name.upper()} v{__version__}"
shortcut.TargetPath = target
shortcut.Arguments = arguments
shortcut.WorkingDirectory = os.getenv("USERPROFILE")
shortcut.IconLocation = str(ico_path)
shortcut.Save()


def unlink_app():
Expand Down
Loading