v0.77.0
Spatial media support, initial macOS 27 search & media info support, export performance fix, and bug fixes.
2026-09-20
Added
- Added support for Apple spatial media.
PhotoInfo.spatialreturns the spatial media type of a photo (0 = not spatial, 1 = native spatial capture, 2 = 2D photo converted to spatial via visionOS) and new--spatial/--not-spatialquery options allow filtering for spatial media inquery,export, and other commands (#2171, thanks @Bill-Costa for the idea). - Added initial search and media info support for macOS 27 (Tahoe/dev beta): search info is now read from the new
leo.sqlitesearch database and media analysis captions are read from the new typed caption tables (ZIMAGECAPTIONRESULTand related). - All CLI commands are now wrapped in the crash reporter, so an unexpected error produces a crash log with instructions for filing a bug report instead of a bare traceback (#2172).
Changed
- Migrated packaging to a
uv-compatiblepyproject.toml.setup.py,requirements.txt,dev_requirements.txt,pytest.ini,.isort.cfg,.bumpversion.cfg, andMANIFEST.inhave been removed and their configuration consolidated intopyproject.toml; builds and CI now useuv(#2149, thanks @oPromessa). - Relaxed dependency pins:
wraptnow allows 2.x (#2176, thanks @oPromessa),tenacityallows 9.x,richallows 14.x, andbitmathallows 2.x. - Updated
wheneverdependency to>=0.10.0,<0.11.0. The previous<0.9.0pin dated from #1937 (whenever 0.9.0 removedSystemDateTime); the code was migrated offSystemDateTimein #1939, so the pin was no longer needed. - Migrated off
whenever's deprecatedfrom_py_datetime()andpy_datetime()in favor of the datetime constructor andto_stdlib(). batch-edit --libraryhelp now notes that--libraryselects which library photos are queried from, but edits are always applied to the library currently open in Photos.
Removed
- Removed
setup.py,requirements.txt,dev_requirements.txt,pytest.ini,.isort.cfg,.bumpversion.cfg, andMANIFEST.inin favor ofpyproject.toml(see Changed, above).
Fixed
- Fixed very slow
export --updateon large libraries.get_target_for_file()queriesexport_databyuuid, but the table had no index onuuid, so every call fell back to a full table scan; on a database with ~150k rows this took upwards of 0.6s per call and could turn an update run into hours. An index onexport_data.uuidis now created via a database migration (#2197, thanks @b-spine). - Fixed two photo matching bugs in
sync --import: photos with no match in the import database were added to the match mapping anyway, raising an uncaughtKeyErrorand suppressing the--unmatchedreport; and with--import <library>, metadata was applied to the source library's photos rather than the selected ones. Also tightened the collision-counter fallback so filenames that legitimately end in a number ("Scan 001.jpg", "Vacation 2024.jpg") are left alone (#2183, #2186, thanks @kurt-wink). - Fixed unhandled
PermissionErrorwhen discovering the Photos library;osxphotosnow fails gracefully and falls back to~/Pictureswhen it cannot read the Photos preference plists (#2170, thanks @prashanthgangu). - Fixed
timewarp --timesilently doing nothing when the requested time falls in a daylight saving time gap (e.g. setting a photo to 02:30 on a US spring-forward date). The time is now shifted forward past the gap, as expected. - Fixed crash (
configparser.NoSectionError: No section: 'styles') when running multiple osxphotos commands in parallel. Every invocation rewrote the color theme files in place, so one process could read a theme file another process had just truncated. Theme files are now written atomically and only when missing, corrupt, or out of date; a theme file left truncated by a previous run is repaired automatically (#2201). - Fixed the export database crash callback leaking into the global crash callback registry and not being written to disk when running with
--ramdband the export bypassed the crash reporter.
Contributors
- @oPromessa @oPromessa for code
- @b-spine @b-spine for code
- @kurt-wink @kurt-wink for code
- @prashanthgangu @prashanthgangu for code
- @Bill-Costa @Bill-Costa for ideas
- @RhetTbull @RhetTbull for code