cellpycore 0.2.4__tar.gz → 0.2.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cellpycore-0.2.4/.issueflows/02-partly-solved-issues → cellpycore-0.2.5/.issueflows/03-solved-issues}/issue100_status.md +1 -1
- cellpycore-0.2.5/.issueflows/03-solved-issues/issue142_original.md +48 -0
- cellpycore-0.2.5/.issueflows/03-solved-issues/issue142_plan.md +86 -0
- cellpycore-0.2.5/.issueflows/03-solved-issues/issue142_status.md +20 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/04-designs-and-guides/cellpy-core-integration-roadmap.md +14 -10
- cellpycore-0.2.5/.vscode/settings.json +14 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/HISTORY.md +2 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/PKG-INFO +2 -2
- {cellpycore-0.2.4 → cellpycore-0.2.5}/pyproject.toml +1 -1
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/cell_core.py +40 -18
- {cellpycore-0.2.4 → cellpycore-0.2.5}/uv.lock +1 -1
- cellpycore-0.2.4/.vscode/settings.json +0 -7
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.aliases +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/rules/cellpy-core-migration.mdc +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/rules/graphify.mdc +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/rules/issueflow-rules.mdc +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/rules/kiss.mdc +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/rules/this-project.mdc +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/skills/caveman/SKILL.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/skills/grill-me/SKILL.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/skills/iflow/SKILL.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/skills/iflow-archive/SKILL.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/skills/iflow-cleanup/SKILL.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/skills/iflow-close/SKILL.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/skills/iflow-comments/SKILL.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/skills/iflow-cycle/SKILL.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/skills/iflow-epic/SKILL.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/skills/iflow-fix/SKILL.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/skills/iflow-graphify/SKILL.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/skills/iflow-history-update/SKILL.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/skills/iflow-init/SKILL.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/skills/iflow-pause/SKILL.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/skills/iflow-pick/SKILL.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/skills/iflow-plan/SKILL.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/skills/iflow-start/SKILL.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/skills/iflow-status/SKILL.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/skills/iflow-version-bump/SKILL.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.cursor/skills/iflow-yolo/SKILL.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.gitattributes +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.gitignore +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/00-tools/.gitkeep +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/00-tools/README.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/01-current-issues/.gitkeep +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/02-partly-solved-issues/.gitkeep +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/.gitkeep +0 -0
- {cellpycore-0.2.4/.issueflows/02-partly-solved-issues → cellpycore-0.2.5/.issueflows/03-solved-issues}/issue100_original.md +0 -0
- {cellpycore-0.2.4/.issueflows/02-partly-solved-issues → cellpycore-0.2.5/.issueflows/03-solved-issues}/issue100_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue10_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue10_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue10_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue110_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue110_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue110_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue112_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue112_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue112_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue114_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue114_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue114_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue115_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue115_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue115_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue116_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue116_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue116_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue117_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue117_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue117_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue118_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue118_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue118_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue121_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue121_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue121_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue12_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue12_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue12_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue136_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue136_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue136_status.md +0 -0
- {cellpycore-0.2.4/.issueflows/01-current-issues → cellpycore-0.2.5/.issueflows/03-solved-issues}/issue138_original.md +0 -0
- {cellpycore-0.2.4/.issueflows/01-current-issues → cellpycore-0.2.5/.issueflows/03-solved-issues}/issue138_plan.md +0 -0
- {cellpycore-0.2.4/.issueflows/01-current-issues → cellpycore-0.2.5/.issueflows/03-solved-issues}/issue138_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue139_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue139_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue139_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue13_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue13_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue13_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue21_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue21_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue21_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue22_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue22_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue22_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue23_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue23_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue23_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue24_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue24_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue29_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue29_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue29_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue30_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue30_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue30_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue32_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue32_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue32_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue34_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue34_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue36_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue36_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue39_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue39_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue39_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue40_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue40_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue40_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue41_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue41_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue41_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue42_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue42_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue42_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue43_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue43_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue43_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue44_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue44_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue45_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue45_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue45_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue50_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue50_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue50_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue54_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue54_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue54_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue55_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue55_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue55_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue56_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue56_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue56_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue62_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue62_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue62_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue64_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue64_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue64_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue66_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue66_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue66_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue67_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue67_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue67_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue68_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue68_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue68_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue69_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue69_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue69_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue70_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue70_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue70_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue72_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue72_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue77_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue77_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue77_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue82_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue82_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue84_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue84_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue84_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue86_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue86_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue86_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue91_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue91_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue91_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue95_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue95_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue95_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue96_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue96_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue96_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue97_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue97_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue97_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue98_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue98_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue98_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue99_original.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue99_plan.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/03-solved-issues/issue99_status.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/04-designs-and-guides/.gitkeep +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/04-designs-and-guides/bdf-io-placement.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/04-designs-and-guides/cellpy-core-integration-into-cellpy.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/04-designs-and-guides/cellpy-core-migration.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/04-designs-and-guides/code-review-2026-07.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/04-designs-and-guides/column-headers-review.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/04-designs-and-guides/legacy-bridge-test-id.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/04-designs-and-guides/legacy-raw-energy-mapping.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/04-designs-and-guides/metadata-scaffolding.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/04-designs-and-guides/nom-cap-naming.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/04-designs-and-guides/rawcols-dtype-map.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/04-designs-and-guides/release-procedure.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/04-designs-and-guides/selector-dead-code-deferral.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/04-designs-and-guides/step-c-rate-split.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/04-designs-and-guides/step-table-polars-migration.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/04-designs-and-guides/summary-extractors.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/04-designs-and-guides/test-data-and-fixtures.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/04-designs-and-guides/test-metadata-and-merging.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/04-designs-and-guides/this-project.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/04-designs-and-guides/zensical-docs.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/05-epics/.gitkeep +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.issueflows/config.toml +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.pre-commit-config.yaml +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.python-version +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/.readthedocs.yaml +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/AGENTS.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/LICENSE +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/README.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/ROADMAP.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/SCRATCHPAD.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/graphify-out/.graphify_labels.json +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/graphify-out/.graphify_root +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/graphify-out/GRAPH_REPORT.md +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/graphify-out/graph.html +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/graphify-out/graph.json +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/graphify-out/manifest.json +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/__init__.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/config.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/curves.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/exceptions.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/extractors.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/legacy/__init__.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/legacy/headers.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/legacy/limits.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/legacy/mapping.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/legacy/meta.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/legacy/meta_mapping.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/legacy/mock_core.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/legacy/selectors.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/merge.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/metadata/__init__.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/metadata/io.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/metadata/models.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/py.typed +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/settings_base.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/summarizers.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/testing/__init__.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/testing/mock_data.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/timestamps.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/units/__init__.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/units/converters.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/src/cellpycore/units/spec.py +0 -0
- {cellpycore-0.2.4 → cellpycore-0.2.5}/zensical.toml +0 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Issue #142: Harden cycle_mode unwrapping in OldCellpyCellCore / _cycle_mode_to_test_mode
|
|
2
|
+
|
|
3
|
+
Source: https://github.com/cellpy/cellpy-core/issues/142
|
|
4
|
+
|
|
5
|
+
## Original issue text
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
Found while working **jepegit/cellpy#668** (v1.x batch notebook): after a custom `update_cell` → `make_step_table()` → `make_summary()`, the legacy bridge crashes with:
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
AttributeError: 'list' object has no attribute 'strip'
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
in `cellpycore.cell_core._cycle_mode_to_test_mode` when `OldCellpyCellCore.cycle_mode` is still list-shaped (often double-nested from cellpy-file meta, e.g. `[['anode']]`).
|
|
16
|
+
|
|
17
|
+
### Why this is a core issue (not just v1.x)
|
|
18
|
+
|
|
19
|
+
- `cellpy` **master** already mitigates on the **consumer load path** via recursive `test_meta._unwrap` after `meta_test_dependent.update(as_list=True, …)` (and has unit tests).
|
|
20
|
+
- The **engine/bridge** still assumes a scalar string:
|
|
21
|
+
- `OldCellpyCellCore.cycle_mode` getter only does one-level `m[0]`
|
|
22
|
+
- setter **keeps** list values (`[x.lower() for x in cycle_mode]`) instead of storing a scalar
|
|
23
|
+
- `_cycle_mode_to_test_mode` calls `cycle_mode.strip()` with no list/tuple handling
|
|
24
|
+
|
|
25
|
+
Any path that skips consumer unwrap (legacy loads, in-memory meta mutation, older cellpy pins) can still hit this. v1.x (#668) will add a consumer-side unwrap backport; core should still be defensive.
|
|
26
|
+
|
|
27
|
+
## What to do
|
|
28
|
+
|
|
29
|
+
1. **Getter** (`OldCellpyCellCore.cycle_mode`): recursively unwrap 1-element `list`/`tuple` to a scalar (same semantics as cellpy `test_meta._unwrap`).
|
|
30
|
+
2. **Setter**: unwrap first, then store a **scalar** string (or `None`) — do not persist a list of lowered strings.
|
|
31
|
+
3. **`_cycle_mode_to_test_mode`**: if given a list/tuple, unwrap before `.strip()`; keep existing string / `None` / unknown-spelling behaviour.
|
|
32
|
+
4. **Tests** covering at least:
|
|
33
|
+
- `'anode'` / `'full_cell'`
|
|
34
|
+
- `['anode']`
|
|
35
|
+
- `[['anode']]`
|
|
36
|
+
- `None`
|
|
37
|
+
- make_summary / make_core_summary does not raise on nested list meta
|
|
38
|
+
|
|
39
|
+
## Acceptance
|
|
40
|
+
|
|
41
|
+
- Nested list `cycle_mode` no longer crashes summarization through the legacy bridge.
|
|
42
|
+
- Existing CE / inverted-convention tests (issue #129 era) stay green.
|
|
43
|
+
- No API break for callers that already pass a plain string.
|
|
44
|
+
|
|
45
|
+
## Links
|
|
46
|
+
|
|
47
|
+
- Downstream report: https://github.com/jepegit/cellpy/issues/668
|
|
48
|
+
- Related consumer mitigation on master: unwrap in `cellpy.readers.cellpy_file.read` / `test_meta._unwrap`
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Issue #142 — plan: harden `cycle_mode` unwrapping
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Stop nested list-shaped `cycle_mode` (e.g. `[['anode']]`) from crashing
|
|
6
|
+
`_cycle_mode_to_test_mode` / summarization on the legacy bridge; store and
|
|
7
|
+
expose a scalar string (or `None`) from the `cycle_mode` property.
|
|
8
|
+
|
|
9
|
+
## Constraints
|
|
10
|
+
|
|
11
|
+
- Back-compat: plain string callers unchanged; issue #127 spelling tables and
|
|
12
|
+
issue #129 bridge CE polarity tests stay green.
|
|
13
|
+
- KISS: no new package/module; private helper next to existing translator in
|
|
14
|
+
`cell_core.py`. No numpy dependency (cellpy’s `_unwrap` also peels numpy
|
|
15
|
+
scalars / NaN — out of scope here; meta on the bridge is Python
|
|
16
|
+
`list`/`tuple`/`str`/`None`).
|
|
17
|
+
- Metadata boundary unchanged: still optional; only normalize this one field
|
|
18
|
+
at the property / translator edge.
|
|
19
|
+
- Scope: getter, setter, `_cycle_mode_to_test_mode` (+ tests). No cellpy
|
|
20
|
+
consumer changes (jepegit/cellpy#668 stays separate).
|
|
21
|
+
|
|
22
|
+
### Prior art
|
|
23
|
+
|
|
24
|
+
- `cellpy.readers.test_meta._unwrap` — recursive peel of 1-element
|
|
25
|
+
`list`/`tuple`; multi-element left as-is. **Mirror** that rule in core
|
|
26
|
+
(list/tuple only).
|
|
27
|
+
- `_cycle_mode_to_test_mode` + `#127` tests in `tests/test_schema.py` —
|
|
28
|
+
spelling / warning contract; **extend**, don’t rewrite.
|
|
29
|
+
- `CellpyCellCore.cycle_mode` getter already does one-level `m[0]`; setter
|
|
30
|
+
wrongly keeps a lowered **list**. `OldCellpyCellCore` inherits this
|
|
31
|
+
property (no override).
|
|
32
|
+
- `test_bridge_summary_respects_cycle_mode` (`tests/test_golden.py`) — CE
|
|
33
|
+
polarity regression for string `"anode"`; keep green; add a nested-list
|
|
34
|
+
smoke if cheap.
|
|
35
|
+
- Toolbox: empty (nothing reusable). Graph: `cycle_mode` /
|
|
36
|
+
`_cycle_mode_to_test_mode` / `OldCellpyCellCore` communities confirm the
|
|
37
|
+
change set is `cell_core.py` + `test_schema.py`.
|
|
38
|
+
|
|
39
|
+
## Approach
|
|
40
|
+
|
|
41
|
+
1. Add `_unwrap_meta_scalar(value)` in `cell_core.py` (module-private):
|
|
42
|
+
while `list`/`tuple` and `len == 1`, recurse; else return value.
|
|
43
|
+
2. **Getter:** unwrap `meta_test_dependent.cycle_mode`; if still
|
|
44
|
+
`list`/`tuple`, take `[0]` when non-empty else `None` (preserves today’s
|
|
45
|
+
first-element behaviour for multi-element placeholders).
|
|
46
|
+
3. **Setter:** unwrap first; if still sequence, take first or `None`; then
|
|
47
|
+
store **scalar** `str.lower()` or `None` on both meta and `_cycle_mode`
|
|
48
|
+
(never a list of lowered strings). Handle `None` without calling `.lower()`.
|
|
49
|
+
4. **`_cycle_mode_to_test_mode`:** unwrap (+ first-element if still sequence)
|
|
50
|
+
before `.strip()`; keep existing `None` / empty / known / unknown+warn
|
|
51
|
+
behaviour. Type hint can widen to `Optional[str | list | tuple]` or stay
|
|
52
|
+
loose — behaviour matters more than the annotation.
|
|
53
|
+
5. No public API export of the helper.
|
|
54
|
+
|
|
55
|
+
Multi-element lists (`['anode','cathode']`) are not a real cellpy-file shape
|
|
56
|
+
today; taking `[0]` matches the old getter and avoids a new failure mode.
|
|
57
|
+
|
|
58
|
+
## Files to touch
|
|
59
|
+
|
|
60
|
+
| Path | Change |
|
|
61
|
+
|------|--------|
|
|
62
|
+
| [`src/cellpycore/cell_core.py`](../../src/cellpycore/cell_core.py) | `_unwrap_meta_scalar`; harden getter / setter / `_cycle_mode_to_test_mode` |
|
|
63
|
+
| [`tests/test_schema.py`](../../tests/test_schema.py) | Parametrize unwrap cases next to `#127` block; nested-list → INVERTED; setter stores scalar; optional `make_core_summary` / `make_summary` smoke with nested meta |
|
|
64
|
+
|
|
65
|
+
## Test strategy
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
uv run pytest tests/test_schema.py -k cycle_mode
|
|
69
|
+
uv run pytest # full suite before close
|
|
70
|
+
uv run ruff check && uv run ruff format --check
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
New coverage (minimum from issue):
|
|
74
|
+
|
|
75
|
+
- `_cycle_mode_to_test_mode`: `'anode'`, `'full_cell'`, `['anode']`,
|
|
76
|
+
`[['anode']]`, `None` (and keep existing spelling params green).
|
|
77
|
+
- Getter/setter: set `[['anode']]` or assign list → property returns
|
|
78
|
+
`"anode"`; stored meta is a `str`, not a list.
|
|
79
|
+
- Smoke: `OldCellpyCellCore` (or `CellpyCellCore`) with nested list on
|
|
80
|
+
`meta_test_dependent.cycle_mode` → `make_core_summary` / `make_summary`
|
|
81
|
+
does not raise.
|
|
82
|
+
|
|
83
|
+
## Open questions
|
|
84
|
+
|
|
85
|
+
None blocking — defaults above match the issue + cellpy `_unwrap`. Say if
|
|
86
|
+
you want multi-element lists to warn instead of silently taking `[0]`.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Issue #142 — status
|
|
2
|
+
|
|
3
|
+
- [x] Done
|
|
4
|
+
|
|
5
|
+
## What's done
|
|
6
|
+
|
|
7
|
+
- Plan confirmed (`issue142_plan.md`).
|
|
8
|
+
- Added `_unwrap_meta_scalar` / `_as_cycle_mode_scalar` in `cell_core.py`.
|
|
9
|
+
- Hardened `CellpyCellCore.cycle_mode` getter/setter to store/return scalar
|
|
10
|
+
(or `None`); nested lists no longer persist as lowered lists.
|
|
11
|
+
- `_cycle_mode_to_test_mode` unwraps list/tuple before `.strip()`.
|
|
12
|
+
- Tests in `tests/test_schema.py` (issue #142 block): translator shapes,
|
|
13
|
+
setter scalar store, getter unwrap, `OldCellpyCellCore.make_core_summary`
|
|
14
|
+
smoke with `[['anode']]` meta.
|
|
15
|
+
- Full suite: 281 passed; ruff green.
|
|
16
|
+
- `HISTORY.md` Unreleased bullet added.
|
|
17
|
+
|
|
18
|
+
## Remaining work
|
|
19
|
+
|
|
20
|
+
- None (close / PR).
|
|
@@ -46,7 +46,7 @@ Reconciled against the actual repo state on **2026-06-26**. Status legend: ✅ d
|
|
|
46
46
|
| STEP-09 Harmonize headers | ✅ done | `config.Cols` + spec tests; `legacy/mapping.py` gives lossless/total `config.Cols` ↔ legacy `Headers*` round-trip (`tests/test_header_mapping.py`) (#34/#35) |
|
|
47
47
|
| STEP-10 Metadata scaffolding | ✅ done | `cellpycore.metadata` (`models.py`/`io.py`); `TestMeta`/`CellMeta`/`TestMetaCollection` + (de)serialize/merge; graceful-degradation guard (`tests/test_metadata.py`) (#37) |
|
|
48
48
|
| STEP-11 Timestamp representation | ✅ done | `epoch_time_utc` + `first/last_epoch_time_utc` are int64-ns UTC; `cellpycore.timestamps` conversion helpers + fixture regenerated (`tests/test_timestamps.py`) (#32, PR #38) |
|
|
49
|
-
| STEP-12 Unit-handling boundary |
|
|
49
|
+
| STEP-12 Unit-handling boundary | ✅ done | `CellpyUnits` schema in `units/spec.py` (#40/#112) + `units.py` tooling behind the optional `units` extra; factors cross the seam by value; `cellpy` now delegates `get_converter_to_specific` / `nominal_capacity_as_absolute` to `cellpycore.units` (jepegit/cellpy #451) — the duplicate converters are retired |
|
|
50
50
|
|
|
51
51
|
Per-step `Status:` lines below repeat this for context; this table is the quick reference.
|
|
52
52
|
The forward work beyond these twelve steps (STEP-13+) is enumerated in
|
|
@@ -266,12 +266,15 @@ Adopt the internal int64-ns timestamp representation.
|
|
|
266
266
|
|
|
267
267
|
## STEP-12 Unit-handling boundary (scaffolding/tooling in core; population & policy upstream)
|
|
268
268
|
|
|
269
|
-
**Status:**
|
|
269
|
+
**Status:** ✅ done — the `CellpyUnits` schema lives in `cellpycore.units.spec`
|
|
270
270
|
(#40, #112) and the pint-based conversion tooling (`cellpycore.units`:
|
|
271
271
|
`get_converter_to_specific`, `nominal_capacity_as_absolute`, `Q`, output-unit defaults)
|
|
272
|
-
|
|
273
|
-
bridge, and conversion factors
|
|
274
|
-
|
|
272
|
+
exists behind the optional `units` extra, attached to the `OldCellpyCellCore`
|
|
273
|
+
bridge, and conversion factors cross the seam **by value**. The final cellpy-side move
|
|
274
|
+
has landed: `CellpyCell.get_converter_to_specific` / `nominal_capacity_as_absolute`
|
|
275
|
+
(and `convert_value` / `calculate_scaler`) now delegate to `cellpycore.units`
|
|
276
|
+
(jepegit/cellpy #451, unit plan Phase 2), guarded by converter-parity fixtures on both
|
|
277
|
+
sides — the duplicated converters are retired.
|
|
275
278
|
|
|
276
279
|
**Codebase:** `cellpy-core` (scaffolding/tooling — `legacy.py` + `units.py`); population
|
|
277
280
|
(`raw_units` from loaders) and the decision to delegate are `cellpy`'s opt-in.
|
|
@@ -299,8 +302,9 @@ already did for headers and the step engine).
|
|
|
299
302
|
|
|
300
303
|
## Remaining work (STEP-13+) — finalized 2026-06-28 (issue #39)
|
|
301
304
|
|
|
302
|
-
The original twelve steps are complete except for the
|
|
303
|
-
|
|
305
|
+
The original twelve steps are complete except for the one intentionally-continuous
|
|
306
|
+
one (STEP-06 golden fixtures); STEP-12 (unit boundary) closed once the cellpy-side
|
|
307
|
+
converter delegation landed (jepegit/cellpy #451). Going through the
|
|
304
308
|
roadmap and the companion design docs surfaced the remaining work below. Each item is now
|
|
305
309
|
tracked as its own **cellpy-core** GitHub issue (the cellpy-side delegation work stays on
|
|
306
310
|
jepegit/cellpy). Captured under issue #39.
|
|
@@ -339,12 +343,12 @@ flowchart TD
|
|
|
339
343
|
S08 --> S09["STEP-09 Harmonize headers ✅"]
|
|
340
344
|
S08 --> S10["STEP-10 Metadata scaffolding ✅"]
|
|
341
345
|
S08 --> S11["STEP-11 Timestamp representation ✅"]
|
|
342
|
-
S03 --> S12["STEP-12 Unit-handling boundary
|
|
346
|
+
S03 --> S12["STEP-12 Unit-handling boundary ✅"]
|
|
343
347
|
S07["STEP-07 Build-backend swap ✅"] -.independent.-> S08
|
|
344
348
|
|
|
345
349
|
classDef done fill:#d4edda,stroke:#28a745,color:#155724;
|
|
346
350
|
classDef partly fill:#fff3cd,stroke:#ffc107,color:#856404;
|
|
347
351
|
classDef todo fill:#f8d7da,stroke:#dc3545,color:#721c24;
|
|
348
|
-
class S01,S02,S03,S04,S05,S07,S08,S09,S10,S11 done;
|
|
349
|
-
class S06
|
|
352
|
+
class S01,S02,S03,S04,S05,S07,S08,S09,S10,S11,S12 done;
|
|
353
|
+
class S06 partly;
|
|
350
354
|
```
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"python.testing.pytestArgs": [
|
|
3
|
+
"tests"
|
|
4
|
+
],
|
|
5
|
+
"python.testing.unittestEnabled": false,
|
|
6
|
+
"python.testing.pytestEnabled": true,
|
|
7
|
+
"python-envs.pythonProjects": [
|
|
8
|
+
{
|
|
9
|
+
"path": ".",
|
|
10
|
+
"envManager": "ms-python.python:venv",
|
|
11
|
+
"packageManager": "ms-python.python:pip"
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
}
|
|
@@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
- Harden `cycle_mode` unwrapping in `OldCellpyCellCore` / `_cycle_mode_to_test_mode`. (#142)
|
|
8
|
+
|
|
7
9
|
## [0.2.4] - 2026-07-23
|
|
8
10
|
|
|
9
11
|
- Add Equivalent Full Cycles (EFC) utilities (#138). `summarizers.throughput_to_raw`
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import datetime
|
|
2
2
|
import logging
|
|
3
3
|
import time
|
|
4
|
-
from typing import Callable, Iterable, List, Optional, Sequence, TypeVar, Union
|
|
4
|
+
from typing import Any, Callable, Iterable, List, Optional, Sequence, TypeVar, Union
|
|
5
5
|
|
|
6
6
|
from cellpycore import config
|
|
7
7
|
from cellpycore.exceptions import NoDataFound
|
|
@@ -24,7 +24,31 @@ _NORMAL_CYCLE_MODES = frozenset(
|
|
|
24
24
|
)
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
def
|
|
27
|
+
def _unwrap_meta_scalar(value: Any) -> Any:
|
|
28
|
+
"""Recursively peel 1-element ``list``/``tuple`` wrappers.
|
|
29
|
+
|
|
30
|
+
Mirrors cellpy's ``test_meta._unwrap`` for the shapes that show up in
|
|
31
|
+
cellpy-file meta (often nested once, e.g. ``[['anode']]``). Multi-element
|
|
32
|
+
sequences are left unchanged.
|
|
33
|
+
"""
|
|
34
|
+
if isinstance(value, (list, tuple)) and len(value) == 1:
|
|
35
|
+
return _unwrap_meta_scalar(value[0])
|
|
36
|
+
return value
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _as_cycle_mode_scalar(value: Any) -> Optional[str]:
|
|
40
|
+
"""Normalize ``cycle_mode`` to a scalar string or ``None``.
|
|
41
|
+
|
|
42
|
+
Unwraps 1-element list/tuple nesting, then takes the first element of any
|
|
43
|
+
remaining multi-element sequence (legacy getter behaviour).
|
|
44
|
+
"""
|
|
45
|
+
value = _unwrap_meta_scalar(value)
|
|
46
|
+
if isinstance(value, (list, tuple)):
|
|
47
|
+
return value[0] if value else None
|
|
48
|
+
return value
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _cycle_mode_to_test_mode(cycle_mode: Any) -> config.TestMode:
|
|
28
52
|
"""Map a legacy ``cycle_mode`` string to a :class:`config.TestMode`.
|
|
29
53
|
|
|
30
54
|
The inverted (anode half-cell) convention is selected by any of ``"anode"``
|
|
@@ -33,16 +57,19 @@ def _cycle_mode_to_test_mode(cycle_mode: Optional[str]) -> config.TestMode:
|
|
|
33
57
|
``None`` and the recognized normal-convention spellings map to
|
|
34
58
|
``TestMode.NORMAL``.
|
|
35
59
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
``
|
|
60
|
+
Nested 1-element ``list``/``tuple`` wrappers (cellpy-file meta shape) are
|
|
61
|
+
unwrapped before matching. An *unrecognized* non-empty value also maps to
|
|
62
|
+
``NORMAL`` but logs a warning, so a mistyped or unmapped mode fails loudly
|
|
63
|
+
instead of silently flipping the ``coulombic_efficiency`` /
|
|
64
|
+
``coulombic_difference`` sign conventions.
|
|
39
65
|
|
|
40
66
|
Args:
|
|
41
|
-
cycle_mode: Legacy mode string, or ``None``.
|
|
67
|
+
cycle_mode: Legacy mode string, nested list/tuple wrappers, or ``None``.
|
|
42
68
|
|
|
43
69
|
Returns:
|
|
44
70
|
The corresponding ``TestMode`` for summary sign conventions.
|
|
45
71
|
"""
|
|
72
|
+
cycle_mode = _as_cycle_mode_scalar(cycle_mode)
|
|
46
73
|
if cycle_mode is None:
|
|
47
74
|
return config.TestMode.NORMAL
|
|
48
75
|
key = cycle_mode.strip().lower()
|
|
@@ -370,23 +397,18 @@ class CellpyCellCore:
|
|
|
370
397
|
# TODO: v2.0 edit this from scalar to list
|
|
371
398
|
try:
|
|
372
399
|
data = self.data
|
|
373
|
-
|
|
374
|
-
#
|
|
375
|
-
|
|
376
|
-
# Temporary fix to make sure that cycle_mode is a scalar:
|
|
377
|
-
if isinstance(m, (tuple, list)):
|
|
378
|
-
return m[0]
|
|
379
|
-
return m
|
|
400
|
+
# cellpy-file meta often stores 1-element (sometimes nested) lists;
|
|
401
|
+
# expose a scalar for the current engine.
|
|
402
|
+
return _as_cycle_mode_scalar(data.meta_test_dependent.cycle_mode)
|
|
380
403
|
except NoDataFound:
|
|
381
404
|
return self._cycle_mode
|
|
382
405
|
|
|
383
406
|
@cycle_mode.setter
|
|
384
|
-
def cycle_mode(self, cycle_mode:
|
|
385
|
-
if isinstance(cycle_mode, (tuple, list)):
|
|
386
|
-
cycle_mode = [cycle_mode.lower() for cycle_mode in cycle_mode]
|
|
387
|
-
else:
|
|
388
|
-
cycle_mode = cycle_mode.lower()
|
|
407
|
+
def cycle_mode(self, cycle_mode: Any):
|
|
389
408
|
# TODO: v2.0 edit this from scalar to list
|
|
409
|
+
cycle_mode = _as_cycle_mode_scalar(cycle_mode)
|
|
410
|
+
if cycle_mode is not None:
|
|
411
|
+
cycle_mode = cycle_mode.lower()
|
|
390
412
|
logger.debug(f"-> cycle_mode: {cycle_mode}")
|
|
391
413
|
try:
|
|
392
414
|
data = self.data
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|