Skip to content

Commit 57056dd

Browse files
committed
Merge branch 'main' of https://github.com/hed-standard/hed-python into fix_extras
2 parents 8bd61be + 04b42b6 commit 57056dd

12 files changed

Lines changed: 538 additions & 0 deletions

File tree

.context/ideas.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# HED Python Design Ideas
2+
3+
## Purpose
4+
5+
Capture design decisions, architectural ideas, and feature concepts before implementation.
6+
7+
## Architecture Decisions
8+
9+
<!-- Document key decisions with rationale. Example:
10+
### Decision: Unified CLI (hedpy)
11+
- Replaced 8 separate script entry points with single Click-based CLI
12+
- Subcommand groups: validate, schema, extract
13+
- Legacy commands kept as deprecated aliases in pyproject.toml
14+
-->
15+
16+
## Feature Ideas
17+
18+
<!-- Describe proposed features with user value and complexity. Example:
19+
### Feature: Batch validation mode
20+
**User Value:** Process many files without repeated schema loading
21+
**Complexity:** Medium
22+
**Priority:** Nice-to-have
23+
-->

.context/plan.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# HED Python Development Plan
2+
3+
<!-- PLAN ROTATION POLICY:
4+
- Only active/in-progress plans belong in "Active Tasks" below.
5+
- When a plan is fully executed, collapse it to 1-2 summary lines
6+
under "Completed" (include date and PR/issue number if applicable).
7+
- Delete detailed steps of completed plans; do not let this file grow
8+
into an archive. If historical detail is needed, link to the PR or
9+
issue instead.
10+
- Review this file at the start of each session; prune anything stale.
11+
-->
12+
13+
## Active Tasks
14+
15+
<!-- Add current tasks and phases here -->
16+
17+
## Completed
18+
19+
<!-- One-line summaries of finished plans, newest first -->
20+
21+
<!-- Example: 2026-02-20 - Added CLI unified entry point (hedpy) - PR #1200 -->

.context/research.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# HED Python Research Notes
2+
3+
## Purpose
4+
5+
Track technical solutions, explored approaches, and references during development.
6+
7+
## Research Log
8+
9+
<!-- Document problems explored, solutions considered, and decisions made. Example:
10+
### Problem: Schema cache corruption on concurrent access
11+
**Date:** 2026-01-15
12+
**Solution:** portalocker for file locking
13+
**Reference:** https://github.com/WoLpH/portalocker
14+
-->
15+
16+
## References
17+
18+
- [HED Specification](https://hed-specification.readthedocs.io)
19+
- [HED Python API Docs](https://www.hedtags.org/hed-python/)
20+
- [HED Resources](https://www.hed-resources.org)
21+
- [BIDS Specification](https://bids-specification.readthedocs.io)

.context/scratch_history.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# HED Python Scratch History
2+
3+
## Purpose
4+
5+
Document failed attempts, dead ends, and lessons learned to prevent repeating mistakes.
6+
7+
## Failed Attempts Log
8+
9+
<!-- Record what was tried, why it failed, and what worked instead. Example:
10+
### Attempt: Using stdlib xml.etree for schema parsing
11+
**Date:** 2025-xx-xx
12+
**Issue:** XML bomb vulnerability (billion laughs attack)
13+
**Solution:** Switched to defusedxml
14+
-->
15+
16+
## Common Pitfalls
17+
18+
<!-- Document recurring issues and how to avoid them. Example:
19+
### Pitfall: Tests failing without submodule init
20+
**Symptoms:** FileNotFoundError in spec_tests
21+
**Fix:** Run `git submodule update --init --recursive`
22+
-->
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Claude Code Review
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize, ready_for_review, reopened]
6+
# Optional: Only run on specific file changes
7+
# paths:
8+
# - "src/**/*.ts"
9+
# - "src/**/*.tsx"
10+
# - "src/**/*.js"
11+
# - "src/**/*.jsx"
12+
13+
jobs:
14+
claude-review:
15+
# Optional: Filter by PR author
16+
# if: |
17+
# github.event.pull_request.user.login == 'external-contributor' ||
18+
# github.event.pull_request.user.login == 'new-developer' ||
19+
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
20+
21+
runs-on: ubuntu-latest
22+
permissions:
23+
contents: read
24+
pull-requests: read
25+
issues: read
26+
id-token: write
27+
28+
steps:
29+
- name: Checkout repository
30+
uses: actions/checkout@v4
31+
with:
32+
fetch-depth: 1
33+
34+
- name: Run Claude Code Review
35+
id: claude-review
36+
uses: anthropics/claude-code-action@v1
37+
with:
38+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
39+
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
40+
plugins: 'code-review@claude-code-plugins'
41+
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
42+
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
43+
# or https://code.claude.com/docs/en/cli-reference for available options
44+

.github/workflows/claude.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Claude Code
2+
3+
on:
4+
issue_comment:
5+
types: [created]
6+
pull_request_review_comment:
7+
types: [created]
8+
issues:
9+
types: [opened, assigned]
10+
pull_request_review:
11+
types: [submitted]
12+
13+
jobs:
14+
claude:
15+
if: |
16+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
17+
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
18+
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
19+
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
20+
runs-on: ubuntu-latest
21+
permissions:
22+
contents: read
23+
pull-requests: read
24+
issues: read
25+
id-token: write
26+
actions: read # Required for Claude to read CI results on PRs
27+
steps:
28+
- name: Checkout repository
29+
uses: actions/checkout@v4
30+
with:
31+
fetch-depth: 1
32+
33+
- name: Run Claude Code
34+
id: claude
35+
uses: anthropics/claude-code-action@v1
36+
with:
37+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
38+
39+
# This is an optional setting that allows Claude to read CI results on PRs
40+
additional_permissions: |
41+
actions: read
42+
43+
# Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
44+
# prompt: 'Update the pull request description to include a summary of changes.'
45+
46+
# Optional: Add claude_args to customize behavior and configuration
47+
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
48+
# or https://code.claude.com/docs/en/cli-reference for available options
49+
# claude_args: '--allowed-tools Bash(gh pr:*)'
50+

.rules/ci_cd.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# CI/CD Configuration
2+
3+
## GitHub Actions Workflows (.github/workflows/)
4+
5+
### Core Testing
6+
7+
| Workflow | Triggers | Python | Description |
8+
| --------------------- | ------------------------ | ------------------------------------------------ | ----------------------------------------------------------------------------- |
9+
| `ci.yaml` | Push + PR (all branches) | 3.10-3.14 (main/PR to main); 3.10, 3.13 (others) | Matrix-based unit + spec tests; continue-on-error for spec_tests |
10+
| `ci_cov.yaml` | Push to main | 3.10 | Coverage reporting; uploads to Qlty |
11+
| `ci_windows.yaml` | Push + PR to main | 3.10-3.12 | Windows-specific tests; skips submodules |
12+
| `spec_tests.yaml` | Push + PR (all branches) | 3.10 | test_errors, test_bids_datasets, test_hed_cache; fails if any spec test fails |
13+
| `test_installer.yaml` | Push + PR to main | 3.10, 3.13 | Fresh venv pip install; imports HedString to verify |
14+
15+
### Code Quality
16+
17+
| Workflow | Triggers | Python | Description |
18+
| ---------------- | ------------------------ | ------ | -------------------------------------------- |
19+
| `ruff.yaml` | Push + PR to main | 3.12 | Ruff linter (>=0.8.0) |
20+
| `black.yaml` | Push + PR (all branches) | 3.12 | Black formatter check (>=24.0.0) |
21+
| `codespell.yaml` | Push + PR to main | 3.10 | Spelling check |
22+
| `mdformat.yaml` | Push + PR to main | 3.12 | Markdown format check (docs/ and root \*.md) |
23+
24+
### Documentation
25+
26+
| Workflow | Triggers | Python | Description |
27+
| --------------------- | ------------------------------------------------------------------------- | ---------- | ------------------------------------------------- |
28+
| `docs.yaml` | Push + PR to main | 3.10 | Sphinx build; GitHub Pages deploy on push to main |
29+
| `links.yaml` | Weekly (Sun 3am UTC) + manual | 3.12 | Sphinx build + Lychee link checker on HTML output |
30+
| `notebook_tests.yaml` | Push + PR to main (path-filtered: examples/\*\*, tests/test_notebooks.py) | 3.10, 3.13 | Notebook structure and import tests |
31+
32+
## Dependabot
33+
34+
- Monitors GitHub Actions versions and git submodules for updates
35+
36+
## All CI Must Pass Before Merge
37+
38+
- Tests across Python 3.10-3.14
39+
- Linting (ruff), formatting (black), spelling (codespell), markdown (mdformat)
40+
- Documentation builds successfully
41+
- Package installs correctly in fresh environment

.rules/code_review.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Code Review Process
2+
3+
## Before Creating a PR
4+
5+
1. All tests pass: `pytest tests/ --cov` and `pytest spec_tests/`
6+
2. Linting clean: `ruff check hed/ tests/`
7+
3. Formatting clean: `black --check hed/ tests/`
8+
4. Spelling clean: `codespell`
9+
5. New functionality has tests (real data, no mocks)
10+
11+
## PR Review with pr-review-toolkit
12+
13+
Run `/review-pr` with all subagents in parallel:
14+
15+
- **Code reviewer:** bugs, logic errors, security vulnerabilities, code quality, project conventions
16+
- **Silent failure hunter:** error handling, catch blocks, fallback behavior
17+
- **Code simplifier:** unnecessary complexity
18+
- **Comment analyzer:** comment accuracy and maintainability
19+
- **Test analyzer:** test coverage quality and completeness
20+
- **Type design analyzer:** type design quality (encapsulation, invariants)
21+
22+
## Review Standards
23+
24+
- Address all critical and important findings (fix or explain why skipped)
25+
- Consider nice-to-haves if they improve quality without major effort
26+
- Document unaddressed items in PR comments
27+
- All 12 CI workflows must be green before merge

.rules/git.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Git Workflow
2+
3+
## Branch Strategy
4+
5+
- `stable`: Released versions on PyPI
6+
- `main`/`master`: Most recent usable version
7+
- `develop`: Experimental, evolving features
8+
- Feature branches: `feature/<issue-number>-short-description`
9+
- PRs target `develop` branch
10+
11+
## Commits
12+
13+
- Atomic, focused changes
14+
- Messages \<50 chars, no emojis
15+
- No AI attribution in commits or PRs
16+
- Pre-commit hook runs ruff check + format on staged .py files
17+
18+
## Submodules
19+
20+
Three submodules under `spec_tests/`, all tracking `main`:
21+
22+
- `hed-tests` - Official HED specification tests
23+
- `hed-examples` - Example BIDS datasets
24+
- `hed-schemas` - Official HED schema repository
25+
- Initialize: `git submodule update --init --recursive`
26+
27+
## PR Process
28+
29+
1. Create issue (except for minor fixes)
30+
2. Use `gh issue develop` to create branch from `develop`
31+
3. Implement with atomic commits
32+
4. Run tests: `pytest tests/ --cov` and `pytest spec_tests/`
33+
5. Run linting: `ruff check hed/ tests/` and `black --check hed/ tests/`
34+
6. Create PR targeting `develop`
35+
7. Run `/review-pr` for code review
36+
8. Address all critical/important findings
37+
9. Merge when all CI (12 workflows) is green
38+
39+
## Release Process (see RELEASE_GUIDE.md)
40+
41+
1. Update CHANGELOG.md
42+
2. Run code quality checks (black, ruff, codespell)
43+
3. Run all tests (unit + spec)
44+
4. Push CHANGELOG PR, merge to main
45+
5. Create git tag (semantic versioning: MAJOR.MINOR.PATCH)
46+
6. Build: `python -m build`; check: `twine check dist/*`
47+
7. Upload to PyPI: `twine upload dist/*`
48+
8. Verify Zenodo DOI generation
49+
9. setuptools-scm derives version from git tags automatically

.rules/python.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Python Code Standards
2+
3+
## Style
4+
5+
- PEP 8 compliant with 127-char line length (configured in pyproject.toml)
6+
- Google-style docstrings for all public classes and functions
7+
- Type hints where appropriate
8+
9+
## Formatting and Linting
10+
11+
- **ruff:** Lint (`ruff check --fix --unsafe-fixes hed/ tests/`)
12+
- Rules enabled: E (pycodestyle errors), W (warnings), F (pyflakes), N (pep8-naming), B (bugbear), C4 (comprehensions)
13+
- Max McCabe complexity: 10
14+
- Excludes: .git, .venv, __pycache__, build, dist, hed/\_version.py, spec_tests submodules
15+
- Per-file: F401 ignored in `__init__.py` (unused imports are re-exports)
16+
- **black:** Format (`black hed/ tests/`); 127-char line, targets py310-py314
17+
- **codespell:** Spell checking; skips binary/data files, ignores domain-specific words (hed, parms, etc.)
18+
19+
## Naming Conventions
20+
21+
- Classes: PascalCase (e.g., `HedString`, `HedSchema`, `TabularInput`)
22+
- Functions/methods: snake_case
23+
- Constants: UPPER_SNAKE_CASE
24+
- Private members: leading underscore
25+
- Test methods: may use camelCase (legacy convention; N802 ignored by ruff)
26+
27+
## Import Order (ruff isort)
28+
29+
1. Standard library
30+
2. Third-party packages
31+
3. Local `hed` package (`known-first-party = ["hed"]`)
32+
33+
## Dependencies
34+
35+
- **Core:** click, click-option-group, pandas (\<3.0), numpy (>=2.0.2), openpyxl, defusedxml, inflect, semantic-version, portalocker
36+
- **Dev:** ruff (>=0.8.0), codespell, black[jupyter], mdformat, mdformat-myst
37+
- **Docs:** sphinx (\<10), furo, sphinx-copybutton, myst-parser, sphinx-autodoc-typehints, linkify-it-py
38+
- **Test:** coverage
39+
- **Examples:** jupyter, notebook, nbformat, nbconvert, ipykernel
40+
- **Target:** Python 3.10+
41+
42+
## Common Patterns
43+
44+
- `defusedxml` for XML parsing (security; never use stdlib xml directly)
45+
- DataFrames for tabular data (pandas)
46+
- `portalocker` for file locking (schema cache at `~/.hedtools/`)
47+
- `semantic-version` for schema version comparison
48+
- `click` + `click-option-group` for CLI with grouped options
49+
50+
## Quality Metrics (qlty.toml)
51+
52+
- Max argument count: 4
53+
- Max method complexity: 5
54+
- Max method lines: 50
55+
- Max file lines: 300
56+
- Max method count per class: 20
57+
- Max nested control flow: 4
58+
- Max return statements: 4
59+
- Similar/identical code detection enabled

0 commit comments

Comments
 (0)