Development Setup¶
This guide walks you through setting up a development environment for contributing to bead. Follow these steps to install dependencies, configure tooling, and verify your setup works correctly.
Prerequisites¶
Required Software¶
bead requires Python 3.13+ for modern type hint syntax (PEP 695 generic type parameters). Check your version:
python3 --version # Should show 3.13.0 or higher
If you need to install Python 3.13:
- macOS:
brew install python@3.13 - Linux: Install from source or use pyenv
- Windows: Download from python.org
Git
Clone the repository and manage version control:
git --version # Any recent version works
Package Manager
uv is required for package management:
uv --version
Platform Compatibility¶
bead development works on macOS, Linux, and Windows. This guide uses Unix-style paths and commands. Windows users should adapt:
- Use backslashes
\for paths (or forward slashes/in PowerShell) - Some bash commands may require Git Bash or WSL
Clone Repository¶
Clone the bead repository from GitHub:
git clone https://github.com/FACTSlab/bead.git
cd bead
Repository Structure¶
After cloning, you'll see this structure:
bead/
├── bead/ # Main package code (14 modules)
├── tests/ # Test suite (143 test files)
├── docs/ # Documentation source
├── gallery/ # Example projects (eng/argument_structure)
├── pyproject.toml # Project configuration
├── README.md # Package overview
├── .pre-commit-config.yaml # Pre-commit hooks
└── .gitignore # Git ignore rules
Development Dependencies¶
Install bead with all development dependencies using uv:
uv sync --all-extras
This command:
- Installs bead in editable mode: Changes to source code take effect immediately
- Installs base dependencies (Pydantic, PyYAML, Click, etc.)
- Installs dev group: pytest, ruff, pyright, pytest-cov, pytest-mock
- Installs api group: openai, anthropic, google-generativeai
- Installs training group: pytorch-lightning, tensorboard
Dependency Groups¶
Base dependencies (required, from pyproject.toml): - pydantic>=2.0.0: Data validation - pyyaml>=6.0.0: Configuration loading - jinja2>=3.0.0: Template rendering - uuid-utils>=0.7.0: UUIDv7 generation - pandas>=2.0.0, polars>=0.19.0: Data manipulation - langcodes>=3.3.0: Language code handling - glazing>=0.2.0: VerbNet, PropBank, FrameNet access - unimorph>=0.0.4: Morphological features - torch>=2.0.0: PyTorch for models - transformers>=4.30.0: HuggingFace models - sentence-transformers>=2.0.0: Sentence embeddings - scikit-learn>=1.3.0: ML utilities - click>=8.0.0: CLI framework - rich>=13.0.0: Rich terminal output - lark>=1.0.0: DSL parser - psutil>=5.9.0: System utilities
dev dependencies (development tools): - pytest>=7.4.0: Test framework - pytest-cov>=4.1.0: Coverage reporting - pytest-mock>=3.11.0: Mocking utilities - ruff>=0.1.0: Linter and formatter - pyright>=1.1.0: Type checker - pandas-stubs>=2.0.0: Type stubs for pandas
api dependencies (external model APIs): - openai>=1.0.0: OpenAI API - anthropic>=0.8.0: Anthropic Claude API - google-generativeai>=0.3.0: Google Gemini API
training dependencies (active learning): - pytorch-lightning>=2.0.0: Training framework - tensorboard>=2.13.0: Visualization
Verify Installation¶
# Check bead CLI installed
uv run bead --version
# Output: bead, version 0.2.0
# Check development tools
uv run pytest --version
# Output: pytest 7.4.x
uv run ruff --version
# Output: ruff 0.x.x
uv run pyright --version
# Output: pyright 1.1.x
If any command fails, the dependency didn't install correctly. Try:
uv sync --all-extras --reinstall
Pre-commit Hooks¶
Install pre-commit hooks to automatically check code quality before commits.
Install Hooks¶
uv run pre-commit install
This installs git hooks in .git/hooks/ that run automatically before each commit.
Configured Hooks¶
The .pre-commit-config.yaml file configures two hooks:
1. pydocstyle (NumPy convention):
- repo: https://github.com/pycqa/pydocstyle
rev: 6.3.0
hooks:
- id: pydocstyle
args:
- --convention=numpy
- --add-ignore=D105,D107 # Ignore magic methods and __init__
exclude: ^(tests/|bead/dsl/parser\.py)
Checks docstrings follow NumPy format (see Documentation Requirements in contributing.md).
2. darglint (signature consistency):
- repo: https://github.com/terrencepreilly/darglint
rev: v1.8.1
hooks:
- id: darglint
args:
- -v
- "2" # Strictness level 2
exclude: ^(tests/|bead/dsl/parser\.py|bead/active_learning/|bead/simulation/)
Checks docstring parameters match function signatures.
Run Hooks Manually¶
Test hooks without making a commit:
uv run pre-commit run --all-files
This runs pydocstyle and darglint on all Python files. Expected output:
pydocstyle...........................................................Passed
darglint.............................................................Passed
If hooks fail, fix the reported issues before committing.
Skip Hooks (not recommended)¶
To bypass hooks for a specific commit:
git commit --no-verify -m "message"
Use this sparingly, as it skips quality checks.
Linting and Type Checking¶
bead uses ruff for linting/formatting and pyright for type checking.
Ruff (Linter and Formatter)¶
Check for issues:
uv run ruff check bead/
This reports: - E errors: PEP 8 violations - F errors: PyFlakes issues (unused imports, undefined names) - I errors: Import sorting - N errors: Naming conventions - D errors: Docstring issues - UP errors: Python version upgrade suggestions - ANN errors: Missing type annotations - B errors: Bugbear (likely bugs) - A errors: Built-in shadowing - C4 errors: Comprehensions - PLC errors: Pylint conventions
Auto-fix issues:
uv run ruff check bead/ --fix
Many issues can be fixed automatically.
Format code:
uv run ruff format bead/
This reformats code to 88-character line length (black-compatible).
Configuration (pyproject.toml):
[tool.ruff]
line-length = 88
target-version = "py313"
[tool.ruff.lint]
select = ["E", "F", "I", "N", "D", "UP", "ANN", "B", "A", "C4", "PLC"]
ignore = ["ANN401"] # Allow Any type in specific cases
[tool.ruff.lint.pydocstyle]
convention = "numpy"
Pyright (Type Checker)¶
Check types:
uv run pyright bead/
This performs static type analysis, catching: - Type mismatches - Missing return types - Incorrect function calls - Undefined variables
Configuration (pyproject.toml):
[tool.pyright]
typeCheckingMode = "strict"
pythonVersion = "3.13"
exclude = [
"tests/**", # Tests don't require full type checking
"bead/active_learning/**",
"bead/resources/adapters/unimorph.py",
"bead/resources/adapters/glazing.py",
"bead/templates/adapters/huggingface.py",
"bead/templates/strategies.py",
"bead/items/adapters/**", # External APIs have dynamic types
"bead/dsl/parser.py",
"bead/deployment/jspsych/ui/components.py",
"bead/simulation/**"
]
Adapters are excluded because external APIs (OpenAI, HuggingFace) have dynamic types.
Fix type errors: Add type hints or adjust type annotations based on error messages.
Run All Checks¶
Run all quality checks before committing:
uv run ruff check bead/ && uv run ruff format bead/ && uv run pyright bead/
Or create a shell alias:
alias bead-lint="uv run ruff check bead/ && uv run ruff format bead/ && uv run pyright bead/"
Running Tests¶
Run tests using uv:
uv run pytest tests/
Run All Tests¶
uv run pytest tests/
This runs all 143 test files. Expected output:
============================= test session starts ==============================
platform darwin -- Python 3.13.0, pytest-7.4.3, pluggy-1.3.0
rootdir: /path/to/bead
configfile: pyproject.toml
plugins: cov-4.1.0, mock-3.11.0
collected 1247 items
tests/data/test_base.py ........ [ 0%]
tests/data/test_identifiers.py ..... [ 0%]
...
tests/resources/test_lexical_item.py ......................... [ 8%]
...
============================== 1247 passed in 45.23s ===============================
Run Specific Module¶
Test a specific module:
uv run pytest tests/resources/
uv run pytest tests/lists/
uv run pytest tests/items/
Test a specific file:
uv run pytest tests/resources/test_lexical_item.py
Test a specific test class or function:
uv run pytest tests/resources/test_lexical_item.py::TestLexicalItemCreation
uv run pytest tests/resources/test_lexical_item.py::TestLexicalItemCreation::test_create_with_all_fields
Run with Verbose Output¶
uv run pytest tests/ -v
Shows each test name as it runs:
tests/data/test_base.py::TestBeadBaseModel::test_default_values PASSED [ 0%]
tests/data/test_base.py::TestBeadBaseModel::test_auto_id PASSED [ 0%]
...
Run with Coverage¶
uv run pytest tests/ --cov=bead --cov-report=term-missing
This shows code coverage with line numbers of uncovered code:
---------- coverage: platform darwin, python 3.13.0 -----------
Name Stmts Miss Cover Missing
--------------------------------------------------------------------
bead/__init__.py 3 0 100%
bead/data/base.py 42 2 95% 67-68
bead/data/identifiers.py 10 0 100%
...
--------------------------------------------------------------------
TOTAL 8547 512 94%
Generate HTML coverage report:
uv run pytest tests/ --cov=bead --cov-report=html
Open htmlcov/index.html in a browser to see visual coverage report.
Stop on First Failure¶
uv run pytest tests/ -x
Stops after the first failing test (useful for debugging).
Run Tests in Parallel¶
uv run pytest tests/ -n auto
Runs tests in parallel using all CPU cores (requires pytest-xdist, not included by default).
Configuration¶
Test configuration in pyproject.toml:
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = ["-ra", "--strict-markers", "--cov=bead", "--cov-report=term-missing"]
-ra: Show summary of all test results--strict-markers: Fail on unknown markers--cov=bead: Measure coverage for bead/ package--cov-report=term-missing: Show uncovered lines
IDE Configuration¶
Configure your IDE for optimal development experience.
VS Code¶
Recommended Extensions: - Python (ms-python.python): Language support - Pylance (ms-python.vscode-pylance): Type checking and IntelliSense - Ruff (charliermarsh.ruff): Linting and formatting - autoDocstring (njpwerner.autodocstring): NumPy docstring generation
Settings (.vscode/settings.json):
{
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
"python.testing.pytestEnabled": true,
"python.testing.pytestArgs": ["tests"],
"python.analysis.typeCheckingMode": "strict",
"editor.formatOnSave": true,
"editor.rulers": [88],
"python.formatting.provider": "none",
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.codeActionsOnSave": {
"source.organizeImports": true
}
},
"ruff.format.args": ["--line-length=88"],
"ruff.lint.args": ["--select=E,F,I,N,D,UP,ANN,B,A,C4,PLC"],
"autoDocstring.docstringFormat": "numpy",
"autoDocstring.startOnNewLine": false
}
PyCharm¶
Configure Interpreter: 1. File → Settings → Project → Python Interpreter 2. Click gear icon → Add 3. Select "Existing environment" 4. Choose .venv/bin/python
Enable Type Checking: 1. File → Settings → Editor → Inspections 2. Enable "Python → Type checker" 3. Set severity to "Error"
Configure Docstring Format: 1. File → Settings → Tools → Python Integrated Tools 2. Set "Docstring format" to "NumPy"
External Tools (ruff, pyright): 1. File → Settings → Tools → External Tools 2. Add tool for "ruff check" 3. Add tool for "ruff format" 4. Add tool for "pyright"
Verify Setup¶
Run these commands to verify your development environment is fully functional:
1. Check CLI¶
uv run bead --version
# Expected: bead, version 0.2.0
2. Run Quick Test¶
uv run pytest tests/data/test_base.py -v
# Expected: All tests pass
3. Check Linting¶
uv run ruff check bead/data/base.py
# Expected: No issues (or minor warnings)
4. Check Types¶
uv run pyright bead/data/base.py
# Expected: 0 errors, 0 warnings
5. Test Pre-commit¶
uv run pre-commit run --all-files
# Expected: pydocstyle and darglint pass
6. Import bead¶
uv run python -c "from bead.resources import LexicalItem; print(LexicalItem.__name__)"
# Expected: LexicalItem
If all checks pass, your development environment is ready.
Troubleshooting¶
Python Version Issues¶
Problem: uv sync fails with "Requires Python >=3.13"
Solution: Install Python 3.13:
# macOS
brew install python@3.13
# Linux (pyenv)
pyenv install 3.13.0
pyenv local 3.13.0
# Windows
# Download from python.org
Module Import Errors¶
Problem: ModuleNotFoundError: No module named 'bead'
Solution: Ensure you are using uv run to execute Python commands:
uv run python -c "import bead"
Pre-commit Hook Failures¶
Problem: Pre-commit hooks fail with "command not found"
Solution: Install pre-commit hooks:
uv run pre-commit install
Pyright Not Found¶
Problem: pyright: command not found
Solution: Run via uv (included in dev dependencies):
uv run pyright bead/
Test Failures on Clean Install¶
Problem: Tests fail immediately after cloning
Solution:
1. Ensure Python 3.13+ is available
2. Reinstall dependencies: uv sync --all-extras --reinstall
3. Clear pytest cache: rm -rf .pytest_cache
4. Run tests again: uv run pytest tests/
Next Steps¶
Now that your development environment is configured:
- Read Architecture: Understand system design in architecture.md
- Learn Testing: Review testing patterns in testing.md
- Start Contributing: Follow guidelines in contributing.md
- Explore Codebase: Run gallery examples in gallery/eng/argument_structure/
- Join Discussions: Open issues or discussions on GitHub
For questions, open an issue or start a discussion on the GitHub repository.