Releases: NikkeTryHard/tach-core
v0.3.1
SQLAlchemy Support
This release adds SQLAlchemy 0.3.1 support with savepoint-based transaction isolation.
Session Management
- Hook into
Session.commit()to prevent actual commits - Wrap sessions in nested transactions (savepoints)
- Handle
Session.rollback()within tests - Support scoped session patterns
- Handle session-per-request patterns
Engine Configuration
- Detect SQLAlchemy engine configuration
- Apply connection pooling optimizations
- Handle multiple engines (read replicas, etc.)
- Support async SQLAlchemy (asyncpg, aiosqlite)
- Handle engine disposal (dispose pattern after fork)
Alembic Integration
- Detect Alembic migration configuration
- Verify migration state matches expected
New Functions
_apply_sqlalchemy_isolation(engine, session_factory)_cleanup_sqlalchemy_isolation(isolation_context)_apply_sqlalchemy_isolation_async(engine, session_factory)_cleanup_sqlalchemy_isolation_async(isolation_context)_apply_sqlalchemy_isolation_scoped(engine, scoped_session)_apply_sqlalchemy_isolation_multi(engines)_detect_sqlalchemy()_detect_alembic()_verify_alembic_head(alembic_cfg)
Rust Integration
- Added
SqlAlchemyDbSetupHookEffect variant
v0.3.0
🎉 Django Database Integration
This release adds comprehensive Django database support for Tach, enabling proper test isolation for database-heavy test suites.
New Features
CLI Flags (#37)
--reuse-db- Reuse existing test database between runs (speeds up repeated test runs)--create-db- Force recreation of test database (use after schema changes)
Transaction Support (#40)
transaction=Truemarker support with table truncation cleanup- New v2 isolation API (
_apply_django_db_isolation_v2,_cleanup_django_db_isolation_v2) - Proper flush-based cleanup for
TransactionTestCasestyle tests
Connection Management (#22)
_dispose_all_connections()- Fork-safe connection disposal before snapshots_get_database_aliases()- Multi-database iteration helper- Prevents SSL/MAC errors and stale connection issues after fork
Files Changed
src/core/config.rs- CLI flags + MergedConfigsrc/core/protocol.rs- IPC protocol fieldssrc/tach_harness.py- 10 new database functions (+309 lines)- New test files in
tests/gauntlet_django/
Closed Issues
- Closes #22 - Django Database Support
- Closes #37 - --reuse-db and --create-db CLI flags
- Closes #40 - transaction=True support
Full Changelog: v0.2.5...v0.3.0
v0.2.5
Plugin Stabilization
Final release of the 0.2.x Plugin Compatibility phase.
Features
- Plugin Compatibility Test Suite: Comprehensive tests for all supported plugins
- External Project Tests: Integration tests against FastAPI and real Django projects
- Conftest Parsing Cache: Disk-based cache with SHA-256 content hashing
- Lazy Plugin Loading: Plugin shims loaded on-demand to reduce startup overhead
- Plugin Overhead Benchmarks: Criterion benchmarks for registry operations
Plugin Compatibility Matrix
| Plugin | Status |
|---|---|
| pytest-django | ✅ Full Support |
| pytest-asyncio | ✅ Full Support |
| pytest-mock | ✅ Full Support |
| pytest-env | ✅ Full Support |
| pytest-timeout | ✅ Full Support |
| pytest-xdist | ⚡ Superseded (native parallelism) |
| pytest-cov | ⚡ Superseded (PEP 669 coverage) |
Phase 2 Complete
This release marks the completion of the Plugin Compatibility phase. Development now moves to Phase 3: Database Integration (0.3.x).
Full Changelog
v0.2.4
Landlock V4-V6 Network Isolation (Kernel 6.7+)
Features
- Runtime ABI Detection:
detect_landlock_abi()probes ABI V1-V6 at startup - TCP Bind Restrictions: Per-worker port binding rules via
AccessNet::BindTcp - TCP Connect Restrictions: Outbound connection filtering via
AccessNet::ConnectTcp - Graceful Fallback: Falls back to
CLONE_NEWNETorSeccompOnlyon older kernels
Configuration
[tool.tach.network]
allow_localhost = true
allow_connect = ["api.example.com:443"]
allow_bind_ports = [8000, 8080]Full Changelog
v0.2.3
Features
Django URL and Template Markers (#35)
@pytest.mark.urls('myapp.test_urls')- Override ROOT_URLCONF per test@pytest.mark.ignore_template_errors- Suppress template errors- Positional argument extraction in Rust scanner
pytest-mock Support
- Native
mockerfixture compatibility via pytest's fixture resolution mocker.patch(),mocker.patch.object(),mocker.patch.dict()mocker.spy()andmocker.stub()support- Automatic mock cleanup between tests
pytest-env Support
{VAR}variable expansion for pytest-env values- Double braces
{{VAR}}escape to literal braces - Variables expanded from current environment at load time
pytest-timeout Support
- Supervisor-level timeout enforcement via SIGTERM/SIGKILL
pytest-asyncio Improvements
- Fix AsyncioSetup effect conversion in Zygote (#46)
- Event loop scope transition cleanup (#43)
- Proper cleanup for module/class/session scoped loops
Bug Fixes
- #41: Include integration tests in CI
- #42: Use
pytest.importorskip()instead of silent pass pattern - #43: Event loop scope transition cleanup
- #44: Use public properties in EventLoopManager tests
- #45: Add debug logging to cleanup exception handlers
- #46: Handle AsyncioSetup in convert_py_effects_to_rust
Deferred to 0.3.0 (#49)
transaction=Truemarker optionreset_sequences=Truemarker option- Multi-database support (
databases=[...])
Full Changelog: v0.2.2...v0.2.3
v0.2.2
pytest-asyncio Support
Full async test and fixture support for pytest-asyncio compatibility.
Added
-
Async Detection: Track async fixtures throughout the pipeline
is_asyncfield in FixtureInfo, FixtureDefinition, ResolvedFixture- Async fixture detection based on
async defparsing - Support for sync tests using async fixtures
-
Event Loop Management: Scoped event loop lifecycle
EventLoopManagersingleton class with function/class/module/session scopesLoopScopeenum for loop scope configuration- Custom event loop policy support (uvloop integration)
- Proper loop cleanup and asyncio.run() compatibility
-
Marker Support: Full
@pytest.mark.asynciohandlingloop_scopeparameter parsing (function, class, module, session)- Automatic async test detection mode
AsyncioSetupHookEffect for Rust→Python configuration propagation
-
Coroutine Execution: Robust async test execution
- Async-aware timeout with proper task cancellation
- TaskGroup and gather cleanup support
- Nested event loop handling
Changed
- Updated roadmap to mark 0.2.2 as complete (21/21 items)
Full Changelog: v0.2.0...v0.2.2
v0.2.1
pytest-django Support (Core Infrastructure)
Foundation for Django test support with marker-aware database isolation.
Added
-
Marker Detection: Static parsing of
@pytest.mark.django_dbmarkers- Marker arguments extracted during discovery (
transaction,reset_sequences,databases) MarkerInfostructure in protocol for IPC propagation- Marker-aware test scheduling
- Marker arguments extracted during discovery (
-
Database Isolation: SAVEPOINT-based transaction rollback
DjangoDbSetupHookEffect variant for database configuration_apply_django_db_isolation()in Python harness wraps tests in savepoints_cleanup_django_db_isolation()ensures rollback on success or failure- Worker process reuse without database pollution
-
Plugin Registry: pytest-django registered as "Supported" plugin
- Tach shims core pytest-django responsibilities
- Compatible with zygote/fork execution model
-
Integration Tests: Django isolation verification
tests/gauntlet_django/test suite- Marker isolation, parallel isolation, savepoint cleanup tests
Not Yet Implemented
The following features are deferred to 0.3.x (Database Integration phase):
transaction=Trueargument supportreset_sequences=Trueargument support- Multi-database (
databases=[...]) support - Django fixtures (
client,rf,admin_client,live_server, etc.) --reuse-dband--create-dbCLI flags@pytest.mark.urlsand@pytest.mark.ignore_template_errorsmarkers
See GitHub issues for tracking.
Full Changelog: v0.2.0...v0.2.1
v0.2.0
Hook Interception Framework
Introduces the complete pytest plugin compatibility system, laying the foundation for seamless integration with the pytest ecosystem.
Added
- Hook Interception Framework: Complete infrastructure for intercepting and replaying pytest hooks
- Hook discovery in conftest.py files with toxicity integration
- Conftest inheritance resolution (root-to-leaf hook ordering)
- Effect recording for pytest_configure (env vars, sys.path modifications)
- Effect replay in workers before test execution
- IPC protocol extension with hooks, cached_effects, markers fields in TestPayload
- Plugin detection and warning system using importlib.metadata
- HookResult type and aggregation strategies: FirstResult, AllResults, NoReturn
- HookCaller with PyO3 bridge: Rust-side hook orchestration
- HookDependencyGraph: Conftest hierarchy ordering (root to leaf)
- PluginRegistry: Plugin status tracking (Supported, Partial, Superseded, Incompatible)
- Plugin configuration: Via pyproject.toml (disabled plugins, priority ordering)
- call_hook_impl(): Python function for loading conftest and calling hooks
- Hook support: pytest_configure, pytest_collection_modifyitems, pytest_runtest_setup/teardown, pytest_runtest_makereport, pytest_sessionfinish
- Hook Registry: Foundation for pytest plugin compatibility
- HookSpec, Hook, HookEffect types with Serde derives for IPC serialization
- HookRegistry for tracking discovered hooks
- builtin_hook_specs() for 10 known pytest hooks
- file_has_toxic_hooks() for toxicity graph integration
- resolve_hooks_for_path() for conftest inheritance
- get_session_effects() for session-level hook effects
- Marker Detection: Extract pytest markers from test decorators
- Markers included in
tach list --jsonoutput - Markers propagated to workers via TestPayload
- Excludes decorator-only markers (parametrize, usefixtures, filterwarnings)
- Markers included in
- Plugin Detection: Detect installed pytest plugins at startup
- Warn about unsupported plugins (pytest-parallel, pytest-forked, etc.)
- Log info about unknown plugins that may or may not work
- Supported plugins list includes pytest-mock, pytest-env, pytest-randomly, etc.
- Effect Recording: Capture side effects from session-level hooks
- Environment variable changes (SetEnv effect)
- sys.path modifications (ModifySysPath effect with prepend/append/remove)
- Effects transmitted from Zygote to Supervisor to Workers
- Autouse Fixture Detection: Parse autouse=True from @pytest.fixture
Changed
- TestModule now includes hooks field
- TestCase now includes markers field
- FixtureDefinition now includes autouse field
- RunnableTest now includes markers field for worker propagation
- TestPayload now includes hooks, cached_effects, and markers fields
- JsonTestInfo now includes markers field for JSON discovery output
- ToxicityGraph::build() now accepts HookRegistry parameter for hook-based toxicity
Full Changelog: v0.1.5...v0.2.0
v0.1.5
Tooling Integration Research
Completes the 0.1.x Foundation phase with tooling ecosystem documentation, container compatibility research, and developer experience improvements.
Added
- Docker Development Environment: Full containerized dev setup with Dockerfile, docker-compose.yml, VS Code devcontainer.json, and post-create.sh script
--no-ignoreCLI Flag: Bypass.ignore/.gitignorefiles during test discovery.ignorePattern Warnings: Detect and warn when.ignorepatterns block Python file discovery- Research Documentation: Container compatibility matrix, tooling conflicts analysis, and test discovery edge case catalogue
Changed
- CI Coverage Threshold: Enforced 90% coverage as hard failure
- Golden Tests: Now opt-in via
GOLDEN_TESTS=1environment variable - MSRV: Updated minimum supported Rust version to 1.88
Fixed
- Python 3.14 Support: Handle immortalization behavior in refcount tests
- Landlock Security: Restrict project_root access, remove excessive /run access, fix symlink escape paths
- CI Stability: Prioritize release binary in tests, fix coverage parsing, add missing test directories
Security
- Restricted Landlock access for project_root (write access only where needed for OverlayFS)
- Removed excessive /run filesystem access from Landlock rules
- Added mknod blocking test for Landlock enforcement
Documentation
- Consolidated research topics into single archive
- Merged errors.md into troubleshooting.md, wsl2-setup.md into quickstart.md
- Added container compatibility research with empirical testing
- Removed volatile data (test counts, line numbers) from documentation
Full Changelog: v0.1.4...v0.1.5
v0.1.4
Foundation Phase Complete
This release consolidates the 0.1.x Foundation phase, completing all planned work:
0.1.1 - Documentation and Polish
- Created
examples/directory with sample projects (simple, django, async, parametrized, markers, conftest) - Quick-start tutorial in
docs/quickstart.md - Inline code comments for complex algorithms
- CLI improvements (
--help,--version --verbose,--dry-run,--collect-only) - Bug fixes for AST discovery, conftest handling, symlinks, long names
0.1.2 - Test Compatibility
- Full assertion handling (
pytest.raises,pytest.warns,pytest.approx,pytest.fail,pytest.skip,pytest.xfail,pytest.importorskip) - pytest-compatible traceback formatting with
--tb=short/long/line/native - Timeout handling with per-test markers and global configuration
- Worker lifecycle improvements (cleanup, health checks, recycling)
0.1.3 - Error Handling and Diagnostics
- Error categorization (user vs system errors) with codes E001-E020
--diagnoseflag for troubleshooting kernel capabilities--debugand--traceflags for verbose logging- Common failure suggestions with remediation hints
0.1.4 - Dependency Updates
- Updated to Rust 2024 Edition
- PyO3 0.27.2, tokio 1.49, clap 4.5
- Tested against Python 3.10-3.14
- PyPy experimental support documented
- PEP 703 (Free-Threading) research completed
Note: Versions 0.1.1-0.1.4 were developed in parallel during the Foundation phase.
See CHANGELOG.md for release notes and docs/research/roadmap.md for the complete development roadmap.