SIGN IN SIGN UP

Migrate to `pathlib.Path` instead of `str` (first phase) (#3350)

* fix path resolution on network drives. Replace  Path(..).resolve() with Path(..).absolute()

* Add safe_resolve helper for path resolution

* replace str with pathlib.Path

* fix redundant resolution of resolved path in memory_replay.py

* fix open -> os.stat

* replace os.stat -> open for files, listdir for dirs.

* fix TestReadConfigProjectPath

* Update deeplabcut/utils/auxiliaryfunctions.py

* additional replacements: str ->Path

* Update function signatures str -> str | Path

* Add ruff linting rule PTH

* Open dataset file directly using Path.open

Fix path handling when loading the dataset pickle. The code previously attempted Path(project_path) / file_name even though file_name already included the project path, resulting in an incorrect path. This changes the context manager to call file_name.open('rb') directly, removing the redundant join and preventing path errors when loading the pickle.

* Use context manager when writing pose_cfg.yaml

Replace direct ruamel_file.dump(...open('w')) call with a with-statement to open pose_cfg.yaml. This ensures the file handle is properly closed after writing and avoids potential resource leaks.

* Pass string path to cv2.VideoCapture

Convert video_path to str when constructing cv2.VideoCapture to ensure pathlib.Path objects are handled correctly and avoid type errors when opening videos. This makes VideoReader more robust when given Path instances.

* Use explicit loop to unlink frame files

Replace the list-comprehension side-effect used to delete temporary frame files with an explicit for-loop that checks p.is_file() before calling unlink. This avoids building an unused list, prevents errors from trying to unlink non-file entries (e.g., directories), and improves readability and safety.

* Fix CircleCI failure

* fix Matplotlib Path import shadowing ->MPLPath

* use pathlib consistently in `metrics`

* use safe_resolve in export

* remove redundant defensive block for windows paths on python 3.6

* remove unused `get_immediate_subdirectories`

* use Path in plot_edge_affinity_distributions

* remove PTH enforcement in linting

* use safe_resolve instead of resolve in `training` and `auxiliaryfunctions`

* Update GUI assets import (#3370)

* Add GUI asset helper utilities

Introduce deeplabcut.gui.gui_assets module providing utilities to load bundled GUI assets. It locates the package assets directory via importlib.resources, and exposes resource_bytes, resource_text, get_assets_dir, get_style_qss, pixmap_from_resource and icon_from_resource helpers (using PySide6 QPixmap/QIcon). Includes error handling when image data cannot be loaded and uses type annotations for clarity.

* Use gui_assets for icons and pixmaps

Replace direct filesystem asset loading (BASE_DIR/assets and manual Path lookups) with centralized gui_assets helpers (icon_from_resource, pixmap_from_resource, get_style_qss/get_assets_dir) across multiple GUI modules. Updated imports and calls in components, launch_script, create_project, modelzoo, open_project, train_network, and window to use the new resource functions and remove redundant logo path handling, improving resource access and packaging robustness.

* fix path concatenation in `make_labeled_images_from_dataframe`

---------

Co-authored-by: Jaap de Ruyter van Steveninck <32810691+deruyter92@users.noreply.github.com>

* Adjust config path tests for Path objects

Update `test_auxiliaryfunctions.py` to assert `project_path` as a `pathlib.Path` instead of a string. The tests now cast to `str` only for the `"Volume{"` check, use `.exists()` for filesystem validation, and compare against `project_dir.absolute()` directly.

* Fix os import in safe_resolve

Import `os` inside `safe_resolve` before calling `os.listdir` so directory resolution no longer risks a `NameError`. This also removes an unused `os` import in `test_auxiliaryfunctions.py` and a stray blank line in `video_processor.py`.

* address remaining `.resolve()` cases: prefer `.absolute()`, or otherwise `safe_resolve()`

* update `safe_resolve`: add logging, use os.stat (more efficient)

* update test safe_resolve: allow fallback and test open/closing instead

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* fix remaining Path.resolve()

* fix reintroduced pathlib `resolve()` occurences (see #3349)

* use pathlib Path in GUI codebase

* use pathlib Path in memory replay

* GUI rename field `config` to `config_path`

* GUI use os.fspath for str conversions where required

* use pathlib Path in create_project

* use pathlib Path across pose_estimation_pytorch internally

* use centralized yaml dumper (which normalizes Path -> str)

* fix materialize.py downstream old str.split -> Path

* fix testsscripts str usage

* fix old str usage in  trainingsetmanipulation

* allow str type at TF boundary

* allow str formatting in tensorflow code

* fix config update in train_from_coco.py

PoseConfig.model.backbone is currently a dict-type but freeze_bn_stats were set as attribute. This commit fixes that and treats backbone correctly as dict.

---------

Co-authored-by: Cyril Achard <cyril.achard@epfl.ch>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
J
Jaap de Ruyter van Steveninck committed
30a8155d4d27984b272cedcf4a7b0a45b5951a42
Parent: 89aa023
Committed by GitHub <noreply@github.com> on 7/15/2026, 3:53:14 PM