diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md deleted file mode 100644 index 9572470e..00000000 --- a/.github/copilot-instructions.md +++ /dev/null @@ -1,153 +0,0 @@ -# QuantEcon.py Development Instructions - -QuantEcon.py is a high-performance, open-source Python library for quantitative economics. The library provides tools for economics research including Markov chains, dynamic programming, game theory, quadrature, and optimization algorithms. - -Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here. - -## Working Effectively - -### Environment Setup (REQUIRED) -- **ALWAYS use conda environment**: `conda env create -f environment.yml` - - Takes 3-5 minutes to complete. NEVER CANCEL. Set timeout to 10+ minutes. - - Creates environment named 'qe' with Python 3.13 and all dependencies -- **Activate environment**: `eval "$(conda shell.bash hook)" && conda activate qe` -- **Development install**: `flit install` - - Installs package in development mode for testing changes - - Takes < 30 seconds - -### Build and Test Workflow -- **Linting**: `flake8 --select F401,F405,E231 quantecon` - - Takes < 30 seconds - - Note: Repository has some existing style violations - this is expected -- **Full test suite**: `coverage run -m pytest quantecon` - - Takes 5 minutes 11 seconds. NEVER CANCEL. Set timeout to 15+ minutes. - - Runs 536 tests across all modules - - All tests should pass with 2 warnings (expected) -- **Quick smoke test**: `python -c "import quantecon as qe; print('Version:', qe.__version__)"` -- **Package build**: `flit build` - - Creates wheel and source distributions in dist/ - - Takes < 1 minute - -### Validation Scenarios -After making changes, ALWAYS run these validation steps: -1. **Import test**: `python -c "import quantecon as qe; print('Import successful, version:', qe.__version__)"` -2. **Basic functionality test**: -```python -python -c " -from quantecon.markov import DiscreteDP -import numpy as np -R = np.array([[10, 8], [6, 4]]) -Q = np.array([[[0.9, 0.1], [0.8, 0.2]], [[0.7, 0.3], [0.6, 0.4]]]) -ddp = DiscreteDP(R, Q, 0.95) -result = ddp.solve(method='policy_iteration') -print('DiscreteDP test successful, policy:', result.sigma) -" -``` -3. **Run relevant tests**: `pytest quantecon/tests/test_[module].py -v` for specific modules -4. **Run flake8 linting** before committing - -## Key Project Structure - -### Core Modules -- `quantecon/` - Main package source code - - `markov/` - Markov chain and dynamic programming tools - - `game_theory/` - Game theory algorithms and utilities - - `optimize/` - Optimization algorithms - - `random/` - Random number generation utilities - - `tests/` - Main test suite (536 tests total) - -### Configuration Files -- `pyproject.toml` - Main project configuration using flit build system -- `environment.yml` - Conda environment specification with all dependencies -- `.github/workflows/ci.yml` - CI pipeline (tests on Python 3.11, 3.12, 3.13) -- `pytest.ini` - Test configuration including slow test markers - -### Dependencies -Core runtime dependencies (auto-installed in conda env): -- `numba>=0.49.0` - JIT compilation for performance -- `numpy>=1.17.0` - Array operations -- `scipy>=1.5.0` - Scientific computing -- `sympy` - Symbolic mathematics -- `requests` - HTTP library - -## Timing Expectations and Timeouts - -**CRITICAL TIMING INFORMATION:** -- **Conda environment creation**: 3-5 minutes (timeout: 10+ minutes) -- **Full test suite**: 5 minutes 11 seconds (timeout: 15+ minutes) -- **Package build**: < 30 seconds (timeout: 2 minutes) -- **Development install**: < 30 seconds (timeout: 2 minutes) -- **Linting**: < 30 seconds (timeout: 2 minutes) - -**NEVER CANCEL these operations** - they may appear to hang but are processing large dependency trees or running comprehensive tests. - -## Common Tasks - -### Making Code Changes -1. Ensure conda environment is active: `conda activate qe` -2. Make your changes to files in `quantecon/` -3. Run development install: `flit install` -4. Test imports: `python -c "import quantecon as qe; print('Import OK')"` -5. Run relevant tests: `pytest quantecon/tests/test_[relevant_module].py` -6. Run linting: `flake8 --select F401,F405,E231 quantecon` - -### Adding New Features -1. Add code to appropriate module in `quantecon/` -2. Add tests to `quantecon/tests/test_[module].py` -3. Update `quantecon/__init__.py` if exposing new public API -4. Run full test suite to ensure no regressions -5. Validate with example usage - -### Debugging Failed Tests -1. Run specific test: `pytest quantecon/tests/test_[module].py::test_function -v` -2. Use pytest markers: `pytest -m "not slow"` to skip long-running tests -3. Check test output and traceback for specific failure modes -4. Many tests use numerical algorithms - check for convergence issues - -## Important Notes - -### CI/CD Pipeline -- GitHub Actions runs tests on Windows, Ubuntu, and macOS -- Tests Python 3.11, 3.12, and 3.13 -- Includes flake8 linting and coverage reporting -- Publishing to PyPI is automated on git tags - -### Network Limitations -- **pip install from PyPI may fail** due to network timeouts in sandboxed environments -- **Always use conda environment** for reliable dependency management -- Documentation building may fail due to missing dependencies - focus on code functionality - -### Performance Considerations -- Many algorithms use numba JIT compilation - first run may be slower -- Test suite includes performance-sensitive numerical algorithms -- Some tests marked as "slow" - use `pytest -m "not slow"` to skip them during development - -### Repository Status -- Current version: Check `quantecon/__init__.py` for `__version__` variable -- Build system: flit (modern Python packaging) -- License: MIT -- Documentation: ReadTheDocs (quanteconpy.readthedocs.io) - -### Maintenance Notes -- When creating new releases, verify that timing expectations and test counts in these instructions remain accurate -- Version information is dynamically referenced to avoid hardcoded values - -## Quick Reference Commands - -```bash -# Setup (do once) -conda env create -f environment.yml -eval "$(conda shell.bash hook)" && conda activate qe - -# Development workflow -flit install # Install in development mode -python -c "import quantecon as qe; print(qe.__version__)" # Test import -pytest quantecon/tests/test_[module].py # Test specific module -flake8 --select F401,F405,E231 quantecon # Lint code - -# Full validation (before committing) -coverage run -m pytest quantecon # Full test suite (5+ minutes) -flit build # Build packages -``` - -Remember: This is a numerical computing library with complex dependencies. Always use the conda environment and expect longer build/test times than typical Python projects. \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..eaea0e34 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,34 @@ +# Agent instructions for QuantEcon.py + +Guidance for AI coding agents working in this repository. Human contributors should start from +[CONTRIBUTING.md](CONTRIBUTING.md) and the rendered guide it links to; everything there applies to +agents too — this file only adds the essentials and repo-specific conventions. + +## Quickstart + +- Environment: `conda env create -f environment.yml` (creates `qe`), activate it, then + `flit install --symlink`. Environment creation takes several minutes — let it finish. +- Tests: `pytest quantecon` (bare `pytest` also works — `pytest.ini` scopes collection to + `quantecon/`). The full suite takes minutes; run `pytest quantecon//tests/...` while + iterating. Much of the library is Numba-jitted, so the first call of anything compiled is slow — + don't mistake JIT compilation for a hang. Slow tests can be skipped with `-m "not slow"`. +- Lint (same selects as CI): `flake8 --select=F401,F405,E231 quantecon` +- The `ci/` directory holds CI-only assets (for example the WASM smoke suite in `ci/wasm/`). They + are not part of the shipped package and are run by explicit path in workflows — keep imports of + CI-only dependencies (such as `playwright`) out of anything bare `pytest` collects. + +## Working procedure + +- Make small, self-contained pull requests against `main`; each must be green in CI and safe to + release on its own. Do not create long-lived feature branches — multi-phase work merges to `main` + incrementally. See "Multi-phase projects and releases" in + [docs/source/contributing.rst](docs/source/contributing.rst) for the full procedure and its + rationale. +- Keep `main` releasable: publishing to PyPI is automated on `v*` tags, so anything merged can ship + at any time. Do not change default behaviour of library functions unless that is the reviewed + purpose of the change. +- Larger campaigns are tracked as an umbrella issue plus sub-issues under a milestone; read the + umbrella issue before working on a sub-issue, and record findings in the issues — they are the + durable record. +- Release notes live on [GitHub releases](https://github.com/QuantEcon/QuantEcon.py/releases); + `CHANGELOG.md` only points there. Do not add per-PR changelog entries. diff --git a/docs/source/contributing.rst b/docs/source/contributing.rst index d3d521ca..92d80c3d 100644 --- a/docs/source/contributing.rst +++ b/docs/source/contributing.rst @@ -80,6 +80,34 @@ The rendered pages are written to ``docs/build/html``. Once you open a pull requ documentation is also built automatically by `Read the Docs `_ and linked from the pull request checks. +Multi-phase projects and releases +--------------------------------- + +Some improvements are too large for a single pull request — for example a compatibility campaign that +touches CI, library code and packaging. We organise this kind of work as follows (the JupyterLite/WASM +browser-support campaign, `#925 `_, is the +reference example): + +- **Track the work on GitHub.** Open an umbrella issue holding the plan, with one sub-issue per + deliverable, all grouped under a milestone. Write enough context into the issue bodies that the + issues themselves are the durable record. + +- **Merge to** ``main`` **as you go — do not use long-lived feature branches.** Each pull request + should be small, individually reviewed, green in CI and safe to release on its own. Integration + branches rot as ``main`` moves, their pull requests bypass the required CI contexts configured for + ``main``, and workflows only become ``workflow_dispatch``-able once they exist on the default + branch. + +- **Keep** ``main`` **releasable after every merge.** Publishing to PyPI is automated on ``v*`` tags, + so anything merged can ship at any time. Library changes must leave default behaviour unchanged + unless that change is the reviewed purpose of the pull request. CI and test scaffolding (workflows, + the ``ci/`` directory) is not part of the shipped package, so it can land freely. + +- **Cut an intermediate release when a later phase depends on shipped fixes.** Downstream consumers + (conda-forge, emscripten-forge, the lecture repositories) only see released versions, so don't hold + the release until a campaign is finished — release as soon as the milestone's library fixes have + landed, and treat the milestone as the release checklist. + Further questions -----------------