Skip to content

Switch packaging from PyInstaller to Nuitka#518

Merged
sdglitched merged 1 commit intomainfrom
nuit
Apr 14, 2026
Merged

Switch packaging from PyInstaller to Nuitka#518
sdglitched merged 1 commit intomainfrom
nuit

Conversation

@gridhead
Copy link
Copy Markdown
Owner

@gridhead gridhead commented Apr 4, 2026

Switch packaging from PyInstaller to Nuitka

Assisted-by: Claude Opus 4.6 noreply@anthropic.com

Summary by Sourcery

Switch project packaging and CI workflows from PyInstaller to Nuitka for building distributable binaries.

Enhancements:

  • Relax application teardown in the Qt front-end by safely handling TypeError when cleaning temporary files under the main window destructor.

Build:

  • Update GNU/Linux and Windows GitHub Actions workflows to install and use Nuitka instead of PyInstaller, standardizing on Python 3.13 and adding required system build dependencies on Linux.
  • Temporarily disable artifact upload steps in both GNU/Linux and Windows binary build workflows.

Chores:

  • Replace PyInstaller with Nuitka in development dependencies and regenerate the uv.lock file accordingly.

@gridhead gridhead requested a review from sdglitched April 4, 2026 12:33
@gridhead gridhead self-assigned this Apr 4, 2026
@gridhead gridhead added the enhancement New feature or request label Apr 4, 2026
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Apr 4, 2026

Reviewer's Guide

Switches the build system from PyInstaller to Nuitka for both Linux and Windows GitHub Actions workflows, updates dev dependencies accordingly, adds manual workflow triggers, adjusts system/compiler prerequisites, and hardens a destructor against TypeError during temp-file cleanup.

Flow diagram for hardened temp file cleanup in destructor

flowchart TD
  A[WindMainWindow___del__] --> B[Call_kill_temp_file]
  B --> C{TypeError_raised?}
  C -->|No| D[Destructor_completes_normally]
  C -->|Yes| E[Catch_TypeError]
  E --> F[Ignore_error_and_continue]
  F --> D
Loading

File-Level Changes

Change Details Files
Migrate CI build workflows from PyInstaller to Nuitka for Linux and Windows, including runtime options and platform-specific flags.
  • Change Python setup to use a single 3.13 version instead of a version range.
  • Replace installation of PyInstaller with Nuitka via pip while keeping uv.
  • Add Linux build prerequisites installation step via dnf (patchelf, ccache, gcc, python-devel).
  • Replace PyInstaller CLI calls with python -m nuitka including PySide6 plugin, onefile mode, output directory/filenames, and Windows-specific flags (no console, icon).
  • Comment out artifact upload steps for both Linux and Windows workflows, effectively disabling artifact publishing for now.
  • Add workflow_dispatch trigger to allow manual runs in addition to scheduled runs.
.github/workflows/gnul.yml
.github/workflows/mswn.yml
Update development dependencies to use Nuitka instead of PyInstaller.
  • Replace PyInstaller dev dependency with a pinned Nuitka version range in the dev optional-dependencies group.
  • Regenerate or update uv.lock to reflect dependency changes.
pyproject.toml
uv.lock
Harden temporary file cleanup in the UI class destructor to avoid errors under Nuitka or different runtime conditions.
  • Wrap kill_temp_file() call in a try/except in the destructor to catch and ignore TypeError, preventing destructor-time crashes.
gi_loadouts/face/wind/main.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • In the Qt window destructor, catching TypeError and silently pass-ing risks hiding real bugs; consider either narrowing the condition (e.g., checking the state before calling kill_temp_file) or at least logging the exception so unexpected failures are visible.
  • The GNU/Linux workflow now assumes a dnf-based environment for system dependencies; if this runs on standard GitHub-hosted Ubuntu runners, you may want to switch to apt or gate this step to avoid failures on non-Fedora images.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In the Qt window destructor, catching `TypeError` and silently `pass`-ing risks hiding real bugs; consider either narrowing the condition (e.g., checking the state before calling `kill_temp_file`) or at least logging the exception so unexpected failures are visible.
- The GNU/Linux workflow now assumes a `dnf`-based environment for system dependencies; if this runs on standard GitHub-hosted Ubuntu runners, you may want to switch to `apt` or gate this step to avoid failures on non-Fedora images.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request replaces PyInstaller with Nuitka as a development dependency and updates the lock file. It also adds a try-except block to the del method in gi_loadouts/face/wind/main.py to handle TypeErrors during cleanup. Feedback suggests that using del for resource management is unreliable and recommends refactoring the cleanup logic to use the atexit module instead.

Comment on lines 26 to +30
def __del__(self) -> None:
kill_temp_file()
try:
kill_temp_file()
except TypeError:
pass
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using __del__ for resource cleanup is generally discouraged as its execution is not guaranteed, especially during interpreter shutdown. This can lead to resource leaks.

A more robust approach is to use the atexit module to register cleanup functions. This ensures that kill_temp_file is called reliably when the program exits.

I recommend this refactoring:

  1. Add import atexit at the top of gi_loadouts/face/wind/main.py.
  2. In the MainWindow.__init__ method, add atexit.register(kill_temp_file).
  3. Remove this __del__ method entirely.

This will make resource cleanup more predictable and robust.

@gridhead gridhead force-pushed the nuit branch 2 times, most recently from e30ce29 to 392d910 Compare April 4, 2026 13:14
@gridhead gridhead added this to the Luna VI milestone Apr 4, 2026
@gridhead gridhead linked an issue Apr 4, 2026 that may be closed by this pull request
@gridhead gridhead force-pushed the nuit branch 10 times, most recently from 4d5617a to 59cc050 Compare April 4, 2026 16:59
Signed-off-by: Akashdeep Dhar <akashdeep.dhar@gmail.com>
Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@sdglitched sdglitched left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🚀

I need to know more about Nuitka before commenting on its usability. As the workflow was fine and the compiled object is running, I'll merge this.

@sdglitched sdglitched merged commit 14756d2 into main Apr 14, 2026
7 checks passed
@gridhead gridhead deleted the nuit branch April 15, 2026 08:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate binary packaging toolset from PyInstaller to Nuitka

2 participants