Skip to content

Fix: Addon Manager Python dependency update detection in Flatpak#308

Merged
chennes merged 6 commits intoFreeCAD:devfrom
omkarrr2533:fix-addon-dependency-detection
Jan 19, 2026
Merged

Fix: Addon Manager Python dependency update detection in Flatpak#308
chennes merged 6 commits intoFreeCAD:devfrom
omkarrr2533:fix-addon-dependency-detection

Conversation

@omkarrr2533
Copy link
Contributor

@omkarrr2533 omkarrr2533 commented Dec 31, 2025

Problem Description

Fixes FreeCAD/FreeCAD#26510

When updating Python dependencies through the Addon Manager in Flatpak installations, the update process completes successfully but FreeCAD continues to show the old version as available for update. This occurs because:

  1. pip installs the new package version to the target directory (~/.var/app/org.freecad.FreeCAD/data/FreeCAD/AdditionalPythonPackages/py312)
  2. The old package version's .dist-info metadata directory remains in place
  3. FreeCAD's version detection scans the directory and finds the old version first, stopping its search

This causes users to repeatedly see the same updates available even after successful installation.

Solution

This PR adds a _cleanup_old_package_versions() method that runs after package updates complete. The method:

  • Scans the pip target directory for all .dist-info directories
  • Groups them by package name (normalized per PEP 503)
  • For packages with multiple versions, removes all but the newest version's metadata
  • Logs cleanup actions for debugging

The cleanup only runs for non-system pip installations (like Flatpak), where the --target directory is used and multiple versions can accumulate.

Changes Made

  • Modified update_call_finished() in addonmanager_python_deps.py to call cleanup after update completes
  • Added new _cleanup_old_package_versions() method to handle old version removal
  • Uses existing Version class for accurate version comparison
  • Includes proper error handling to prevent cleanup failures from breaking updates

Testing

The fix has been tested by:

  • Verifying the cleanup logic correctly identifies and removes old .dist-info directories
  • Ensuring the newest version is preserved after cleanup
  • Confirming error handling prevents crashes if cleanup fails

Manual testing in a Flatpak environment would be appreciated to confirm the fix resolves the reported issue.

Additional Notes

This fix is specifically targeted at Flatpak and similar installations where using_system_pip_installation_location() returns False. Regular system installations and virtual environments are not affected as they already handle package updates correctly through pip's standard mechanisms.

Fixes #26510

omkarrr2533 and others added 2 commits December 30, 2025 18:33
When updating Python dependencies with pip using --target directory,
old package version metadata (.dist-info directories) are not always
removed. This causes FreeCAD to detect the old version instead of the
newly installed version, particularly in Flatpak installations.

This fix adds cleanup logic to remove old package version metadata
after a successful update, keeping only the newest version of each
package.

Fixes #26510
@omkarrr2533
Copy link
Contributor Author

Hi @chennes,

I'm a new contributor working on fixing issue #26510 (Python dependency updates in Flatpak). Would you be able to review this PR when you have a chance? I'd really appreciate any feedback or suggestions for improvement.

Thank you for your time and for maintaining this project!

@chennes
Copy link
Member

chennes commented Dec 31, 2025

Hello @omkarrr2533 -- thanks for your work on this bug. I am happy to review your PR. It will probably take me a couple of days before I can get to it. Thanks for your patience!

@omkarrr2533
Copy link
Contributor Author

Thanks @chennes! Really appreciate you taking a look. Whenever you get to it is totally fine - no rush!

Looking forward to your feedback!

@chennes
Copy link
Member

chennes commented Jan 4, 2026

@omkarrr2533 can you add some tests of _cleanup_old_package_versions to test_python_deps.py? Let me know if you need help with the mocks.

@omkarrr2533
Copy link
Contributor Author

omkarrr2533 commented Jan 5, 2026

thanks @chennes! i'll work on adding test for _cleanup_old_package_versions() to test_python_deps.py

I am planning to test like:
*multiple package versions (keep newest, remove old)
*single version (no cleanup needed)
*Empty directory handling
*error handling for permission issues.

if i get stuck with the mocks, i'll definitely reach out. thanks for offering to help!

omkarrr2533 and others added 2 commits January 5, 2026 11:23
Added unit tests covering:
- Removal of old versions while keeping newest
- Single version packages (no removal)
- Empty and nonexistent directories
- Permission error handling
- PEP 503 package name normalization
- Non-.dist-info directory filtering
- Invalid version format handling

Tests use proper mocking to avoid filesystem operations and follow
existing test patterns in the codebase.

These tests verify the cleanup logic works correctly across various
scenarios including edge cases like permission errors and malformed directory names. All tests use mocks to ensure fast, reliable execution without touching the actual filesystem.
Copy link
Member

@chennes chennes left a comment

Choose a reason for hiding this comment

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

Thanks for adding the tests -- overall they look good. One small comment below, and also I suspect that theses tests won't work on Windows since they are using a hardcoded path separator, but internally the code is using os.path.join -- I'd guess your strings won't match. Do you have access to a Windows system to test on?

Comment on lines 305 to 307

# Verify logging happened
self.assertEqual(mock_print_log.call_count, 3)
Copy link
Member

Choose a reason for hiding this comment

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

I probably wouldn't test this: we don't really want to have to update the tests just because we change the logging.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thanks @chennes I've addressed both the points

  • Removed the logging assertion you're right I shouldn't test implementation details
  • fixed windows compatibility - replaced all hardcoded paths with 'os.path.join()'

Unfortunately I don't have access to a Windows system to test on, but the changes should now work correctly since we're using the same os.path.join() approach as the main code.

omkarrr2533 and others added 2 commits January 6, 2026 09:43
- Use os.path.join() for all path construction to ensure Windows compatibility
- Remove logging count assertion as suggested in review
- Tests now work across all platforms (Windows, Linux, macOS)
@chennes chennes merged commit 1f50c4f into FreeCAD:dev Jan 19, 2026
11 checks passed
@chennes chennes added the in testing on dev branch This backport PR is still in testing on the dev branch and should not be merged yet. label Jan 19, 2026
@chennes chennes added release to main Trigger an Action to create a PR backporting to `main` and removed in testing on dev branch This backport PR is still in testing on the dev branch and should not be merged yet. labels Feb 19, 2026
@github-actions
Copy link

Successfully created backport PR for main:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release to main Trigger an Action to create a PR backporting to `main`

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Addon Manager: Updating Python dependencies fails in Flatpak

2 participants

Comments