Skip to content

Commit 91cc3e0

Browse files
committed
Improve IO: YAML errors, logging, and glob use
Add notes about potential refactor of write_hdf/config I/O and improve robustness: use stdlib glob.has_magic instead of a custom _has_glob_magic helper, add YAML error handling/logging in load_config (logs and re-raises yaml.YAMLError), and emit a warning in write_hdf when multiindex normalization fails (before attempting to harmonize indices). These changes standardize glob handling, surface YAML parse issues in logs, and improve diagnostics for HDF writes.
1 parent 0405b0a commit 91cc3e0

1 file changed

Lines changed: 21 additions & 9 deletions

File tree

  • src/napari_deeplabcut/core

src/napari_deeplabcut/core/io.py

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@
77
- Lazy image reading with Dask support
88
- Video reading with OpenCV and optional PyAV fallback
99
- Superkeypoints diagram and JSON loading
10+
11+
NOTE: write_hdf could use some refactoring to split responsibilities more cleanly
12+
A potentially interesting direction could be to move toward a more schema-centric
13+
architecture, where objects own and guarantee their own validity, and writing
14+
is just a translation of already-valid objects to disk. This would also make
15+
validation more consistent across reads and writes.
16+
Config I/O is an especially good candidate for this, the logic is a bit spread right now
17+
(here, config_sync.py, and the sidecar JSON)
1018
"""
1119
# src/napari_deeplabcut/core/io.py
1220

@@ -17,6 +25,7 @@
1725
import logging
1826
import os
1927
from collections.abc import Callable
28+
from glob import has_magic
2029
from importlib import resources
2130
from pathlib import Path
2231
from typing import Any
@@ -61,25 +70,23 @@
6170
# -----------------------------------------------------------------------------
6271
# Supported formats (shared by image/video readers)
6372
# -----------------------------------------------------------------------------
64-
_GLOB_MAGIC = set("*?[")
6573
_SUPPORTED_SUFFIXES = {ext.lower() for ext in SUPPORTED_IMAGES}
6674
DLC_CANONICAL_H5_KEY = "df_with_missing" # TODO use this key instead of str literal in all places
6775
FALLBACK_H5_KEYS = ["keypoints"]
6876

69-
70-
def _has_glob_magic(name: str) -> bool:
71-
return any(ch in name for ch in _GLOB_MAGIC)
72-
73-
7477
# =============================================================================
7578
# CONFIG (YAML)
7679
# =============================================================================
7780

7881

7982
def load_config(config_path: str):
8083
# NOTE: intentionally minimal; callers own error handling
81-
with open(config_path) as file:
82-
return yaml.safe_load(file)
84+
try:
85+
with open(config_path) as file:
86+
return yaml.safe_load(file)
87+
except yaml.YAMLError as e:
88+
logger.warning(f"Invalid YAML in config file {config_path}: {e}")
89+
raise e
8390

8491

8592
# Read config file and create keypoint layer metadata
@@ -492,6 +499,11 @@ def writer(path: str, data: Any, attributes: dict) -> List[str]
492499
guarantee_multiindex_rows(df_new)
493500
guarantee_multiindex_rows(df_old)
494501
except Exception:
502+
logger.warning(
503+
"Could not guarantee multiindex rows for new or existing data; "
504+
"attempting to harmonize indices for merge.",
505+
exc_info=True,
506+
)
495507
pass
496508

497509
df_new, df_old = harmonize_keypoint_row_index(df_new, df_old)
@@ -639,7 +651,7 @@ def _expand_image_paths(path: str | Path | list[str | Path] | tuple[str | Path,
639651
expanded.extend(files)
640652
continue
641653

642-
if not _has_glob_magic(p.name):
654+
if not has_magic(p.name):
643655
if p.is_file() and p.suffix.lower() in _SUPPORTED_SUFFIXES:
644656
expanded.append(p)
645657
continue

0 commit comments

Comments
 (0)