Python Application Development Patterns

August 6, 2026 · View on GitHub

Reference for Python application development in parallel workflows. Covers project detection, toolchain commands, testing strategy, dependency management, parallel conflict scenarios, and error recovery.

Contents

Project Detection

Detect the project type by looking for these files in the project root. The first match determines the toolchain:

File(s)Package ManagerLock FileInstall CommandRun Command
pyproject.toml with [tool.uv] or uv.lockuvuv.lockuv syncuv run
pyproject.toml with [tool.poetry] or poetry.lockPoetrypoetry.lockpoetry installpoetry run
pyproject.toml with [project] (no uv/poetry markers)pip/uv fallbacknone or requirements.lockpip install -e .python -m
PipfilePipenvPipfile.lockpipenv installpipenv run
requirements.txt (no pyproject.toml)pipnonepip install -r requirements.txtpython
setup.py or setup.cfg (legacy)setuptoolsnonepip install -e .python
environment.ymlcondanoneconda env createconda run

Detection priority: check for uv.lock and pyproject.toml first (most modern), then Poetry markers, then legacy files. When both pyproject.toml and requirements.txt exist, pyproject.toml takes precedence.

Virtual Environment Detection

Before running any toolchain command, verify the virtual environment is active:

MarkerMeaning
VIRTUAL_ENV env var setvenv is active
.venv/ directory existsproject-local venv exists (may need activation)
uv run availableuv manages environment automatically (no manual activation needed)

For uv-managed projects, uv run handles environment creation and synchronization transparently. Do not manually activate venvs when using uv.

Toolchain Commands

Type Checking

The type checker is selected based on project configuration. If pyproject.toml specifies a type checker under [tool.<name>], use that. Otherwise, detect availability:

# Check which type checker is configured or available
grep -q '\[tool.mypy\]' pyproject.toml && echo "mypy"
grep -q '\[tool.pyright\]' pyproject.toml && echo "pyright"
command -v mypy && echo "mypy available"
command -v pyright && echo "pyright available"

Run type checking:

# mypy (most common, Python-implemented)
mypy src/ --no-error-summary 2>&1 | head -50

# pyright / basedpyright (TypeScript-implemented, faster)
pyright src/

# ty (Rust-implemented, fastest, Astral ecosystem)
ty check src/

Type checking commands for the Convergent Fix Loop Tier 1:

# For projects using uv
uv run mypy src/

# For projects using poetry
poetry run mypy src/

# For projects using plain venv
python -m mypy src/

Linting

Ruff is the standard linter/formatter for modern Python projects (replaces flake8, isort, black):

# Check only (no modifications)
ruff check src/

# Check and fix auto-fixable issues
ruff check --fix src/

# Format check (no modifications)
ruff format --check src/

# Format and fix
ruff format src/

Legacy projects may use separate tools:

# Legacy stack (only if ruff is not configured)
flake8 src/ --max-line-length=120
isort --check-only src/
black --check src/

Testing

pytest is the standard test runner. Detect configuration:

# Check for pytest configuration
grep -q '\[tool.pytest' pyproject.toml && echo "pytest configured"
ls pytest.ini conftest.py 2>/dev/null

Run tests:

# Full test suite
pytest --tb=short -q

# With coverage
pytest --cov=src --cov-report=term-missing --tb=short -q

# Specific test file
pytest tests/unit/test_service.py -v

# Specific test by keyword
pytest -k "test_create_user" -v

# Stop on first failure (useful during fix loop)
pytest -x --tb=short

# Parallel test execution (if pytest-xdist installed)
pytest -n auto --tb=short

Full Tier 1 Validation Sequence

For the Convergent Fix Loop, run these in order. Stop at the first failure:

# 1. Dependency sync (ensure environment matches lock file)
uv sync 2>/dev/null || poetry install 2>/dev/null || pip install -e ".[dev]" 2>/dev/null

# 2. Type check
uv run mypy src/ 2>/dev/null || mypy src/

# 3. Lint
uv run ruff check src/ 2>/dev/null || ruff check src/

# 4. Format check
uv run ruff format --check src/ 2>/dev/null || ruff format --check src/

# 5. Test suite
uv run pytest --tb=short -q 2>/dev/null || pytest --tb=short -q

Priority for fixes: type errors > lint errors > format errors > test failures. Fix type errors first because they often cause cascading test failures.

Testing Strategy

Test Directory Structure

tests/
  conftest.py          # Shared fixtures (session/module scope)
  unit/                # Unit tests: no external dependencies
    conftest.py        # Unit test fixtures
    test_models.py
    test_services.py
  integration/         # Integration tests: cross-module, database, API
    conftest.py        # Integration fixtures (db connections, test client)
    test_api.py
    test_repository.py

Fixture Scoping Rules for Parallel Development

Fixture scope determines when setup/teardown happens. Incorrect scope causes test pollution between parallel agents:

ScopeLifetimeParallel Safety
functionPer test functionSafe by default
classPer test classSafe if class tests are independent
modulePer test moduleSafe for read-only fixtures
sessionEntire test runUnsafe if mutable — only for immutable shared data

Rules for parallel agents modifying conftest.py:

  • Each agent that adds fixtures should add them in a uniquely named fixture function (not modifying existing fixtures)
  • Session-scoped fixtures must be read-only or use thread-safe mutation
  • If two agents need the same fixture with different configurations, use parametrized fixtures or separate named fixtures

Parametrized Tests as Parallel Contracts

When parallel agents write tests for the same interface (RED phase), parametrized tests serve as the shared contract:

# tests/unit/test_user_service.py
import pytest

@pytest.mark.parametrize("input_data,expected", [
    ({"name": "Alice", "age": 30}, True),
    ({"name": "", "age": 30}, False),       # empty name rejected
    ({"name": "Bob", "age": -1}, False),    # negative age rejected
    ({"name": "Carol", "age": 150}, False), # unreasonable age rejected
])
def test_user_validation(input_data, expected):
    result = validate_user(input_data)
    assert result.is_valid == expected

Each agent independently implements against this contract in GREEN phase.

Test Isolation for Parallel Safety

Tests must not depend on execution order. Violations manifest as: local pass + CI fail, or pass individually but fail in full suite.

Detection:

# Run tests in random order to detect order dependencies
pytest --random-order  # requires pytest-random-order plugin

# Run subset to detect missing dependencies
pytest tests/unit/test_service.py -v

Common causes of order-dependent tests:

  • Module-level mutable state (global variables modified by tests)
  • Shared database rows not cleaned between tests
  • Fixture scope too wide for mutable data

Dependency Management in Parallel Workflows

Dependency File Conflicts

When multiple parallel agents add dependencies simultaneously, the following conflicts occur:

FileConflict RiskResolution
pyproject.toml [project.dependencies]High — multiple agents appending to same arraySerialize: only one agent modifies per turn
pyproject.toml [tool.*] sectionsLow — different tool sections are independentParallel safe if sections differ
uv.lock / poetry.lockHigh — must reflect pyproject.toml stateRegenerate after pyproject.toml converges
requirements.txtHigh — flat file, append conflictsSerialize: only one agent modifies per turn

Lock File Handling

Lock files must be regenerated after any dependency addition. In the scheduling loop:

  1. Mark pyproject.toml and the lock file as files_touched for any task that adds dependencies

  2. Schedule all dependency-adding tasks sequentially (they share pyproject.toml)

  3. After all dependency additions converge, regenerate the lock file once:

    uv lock    # for uv projects
    poetry lock --no-update  # for Poetry projects
    
  4. Then uv sync or poetry install to update the environment

Monorepo / Workspace Projects

uv workspace projects ([tool.uv.sources] with path dependencies) introduce additional constraints:

  • Multiple packages may share a single lock file
  • Changes to one package's dependencies require lock file regeneration that affects all packages
  • Schedule dependency changes to any workspace member sequentially

Parallel Conflict Scenarios

File-Level Conflicts

ConditionConflict?Action
Same .py file in both files_touchedYesSchedule sequentially
Different .py files, no imports between themNoParallel
Different .py files, one imports the otherYesSchedule sequentially (imported module first)
Same pyproject.tomlYesSchedule sequentially
Same uv.lock / poetry.lockYesSchedule sequentially
Same conftest.pyYesSchedule sequentially
Different conftest.py in different directoriesNoParallel
Same __init__.pyYesSchedule sequentially
Different test files in same directoryNoParallel

Database Migration Conflicts

When using Alembic (SQLAlchemy) or Django migrations:

ConditionConflict?Action
Same migration fileYesSchedule sequentially
Different migration files, same app/alembic versionYesMust be sequential — migration order matters
Different migration files, different apps (Django)NoParallel — Django handles cross-app ordering
Migration + model file for same modelYesSchedule sequentially

Alembic migration files contain chain references (revision and down_revision). Two agents creating migrations simultaneously will produce conflicting chain links. Solution:

  1. Serialize all migration-creating tasks
  2. After migrations converge, run alembic upgrade head to verify chain integrity
  3. If chain is broken, merge migrations: alembic merge heads -m "merge"

Django's migration system is more parallel-friendly: migrations in different apps have independent chains. Only same-app migrations need serialization.

conftest.py Conflicts

conftest.py files follow pytest's hierarchical discovery model. Conflicts occur when:

  • Two agents add fixtures to the same conftest.py
  • One agent adds a fixture that another agent's test depends on (implicit dependency)

Mitigation:

  • Agents should add fixtures to their own test subdirectory's conftest.py when possible
  • Only truly shared fixtures belong in the top-level conftest.py
  • When modifying top-level conftest.py is necessary, serialize those modifications

init.py Conflicts

__init__.py files serve dual roles: package markers and public API exports. Conflicts when:

  • Multiple agents add exports to the same __init__.py
  • One agent creates a subpackage that another agent's code imports from

Mitigation:

  • Mark __init__.py of shared packages as files_touched when agents modify exports
  • Prefer explicit imports (from package.module import X) over package-level re-exports during development
  • Reconcile __init__.py exports in the integration phase after parallel agents complete

Common Framework Patterns

FastAPI

Project structure:

app/
  __init__.py
  main.py              # FastAPI app instance
  api/
    deps.py            # Dependency injection (Depends)
    v1/
      router_users.py
      router_items.py
  models/              # SQLAlchemy models
  schemas/             # Pydantic models (request/response)
  services/            # Business logic
  tests/
    conftest.py        # TestClient fixture
    test_api/

Test pattern:

# tests/conftest.py
from fastapi.testclient import TestClient
from app.main import app

@pytest.fixture
def client():
    return TestClient(app)

# tests/test_api/test_users.py
def test_create_user(client):
    response = client.post("/api/v1/users", json={"name": "Alice"})
    assert response.status_code == 201

Parallel safety: routers in app/api/v1/ are independent files. Each agent can implement a router with its tests, models, and schemas in parallel. The app/main.py that includes all routers is the shared file — serialize modifications to it.

Dependency injection with Depends() creates natural boundaries between parallel agents. Each agent implements its own dependency chain. Shared dependencies (database session, auth) are defined once in api/deps.py and consumed by all.

Django

Project structure:

project/
  manage.py
  project/             # Django project config
    settings.py
    urls.py
  apps/
    users/             # Django app
      models.py
      views.py
      tests.py
      migrations/
    orders/            # Django app
      models.py
      views.py
      tests.py
      migrations/

Parallel safety: Django apps are natural parallel boundaries. Each agent works on a separate app with its own models, views, tests, and migrations. Shared files requiring serialization:

  • project/settings.py (when adding apps or middleware)
  • project/urls.py (when adding URL patterns)
  • Shared template directories
  • Shared static files

Test pattern:

# apps/users/tests/test_models.py
from django.test import TestCase
from apps.users.models import User

class UserModelTest(TestCase):
    def test_create_user(self):
        user = User.objects.create_user(email="test@example.com")
        self.assertEqual(user.email, "test@example.com")

Django's TestCase wraps each test in a database transaction and rolls back after the test. This provides test isolation by default. For read-only tests, use SimpleTestCase (no database overhead).

Flask

Project structure:

app/
  __init__.py           # create_app factory
  extensions.py         # Extension instances (db, migrate, etc.)
  blueprints/
    auth/
      __init__.py
      routes.py
      models.py
      tests/
    api/
      __init__.py
      routes.py
      models.py
      tests/

Parallel safety: Flask blueprints are independent modules. Each agent can implement a blueprint with its routes, models, and tests in parallel. Shared files:

  • app/__init__.py (blueprint registration)
  • app/extensions.py (shared extension instances)
  • migrations/ (if using Flask-Migrate/Alembic)

Error Recovery

Virtual Environment Corruption

Symptoms: ModuleNotFoundError for installed packages, ImportError, or unexpected SyntaxError in third-party code.

Recovery:

# For uv-managed projects
rm -rf .venv
uv sync

# For poetry-managed projects
poetry env remove python
poetry install

# For pip-managed projects
rm -rf .venv
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

This is a transient failure — auto-retry once after rebuilding the environment before reporting to the user.

Dependency Version Conflicts

Symptoms: ResolutionImpossible (pip), SolverProblemError (poetry), or inconsistent pip check output.

Recovery:

  1. Check if lock file matches pyproject.toml: uv lock --check or poetry lock --check
  2. If mismatched, regenerate: uv lock or poetry lock
  3. If resolution fails, check for conflicting constraints in dependency groups
  4. Report unresolved conflicts to user with the conflicting packages and version ranges

Import Cycle Detection

Symptoms: ImportError or AttributeError at import time, often appearing only when the full test suite runs.

Detection:

# Use pylint to detect import cycles
pylint --disable=all --enable=cyclic-import src/

# Or use pydeps for visualization
pydeps src/ --max-bacon=2

Import cycles often emerge after parallel agents independently add cross-module imports. Resolution requires understanding the dependency direction and breaking the cycle by extracting shared code into a separate module.

Test Environment Mismatches

Symptoms: tests pass locally but fail in CI, or vice versa.

Diagnosis:

# Check Python version
python --version

# Check installed packages
pip list | grep -i <package>

# Compare environments
pip freeze > local.txt
# Compare with CI's pip freeze output

Common causes: different Python versions, missing dev dependencies, OS-specific behavior (path separators, file system case sensitivity). Use requires-python in pyproject.toml and pin dev dependencies to prevent drift.

Architecture Phase Artifacts

When Phase 2 (Architecture) runs for a Python project, the architect must produce these artifacts before Phase 5 parallel implementation begins. Without them, parallel agents lack the constraints needed to avoid conflicting implementations.

Required Artifacts

  1. API Boundary Map: Which router/module owns which endpoints. Prevents two agents from implementing the same route or modifying the same router file.

    FastAPI example:

    app/api/v1/
      users.py       → Agent A: GET/POST /api/v1/users, GET /api/v1/users/{id}
      orders.py      → Agent B: GET/POST /api/v1/orders, GET /api/v1/orders/{id}
      auth.py        → Agent C: POST /api/v1/auth/login, POST /api/v1/auth/refresh
    

    Django example:

    apps/
      users/         → Agent A: /api/users/ (entire app owns this URL namespace)
      orders/        → Agent B: /api/orders/ (entire app owns this URL namespace)
    
  2. Model Ownership: Which service owns which database models. Determines migration serialization order.

    app/models/
      user.py        → Agent A (UserService owns User, UserProfile)
      order.py       → Agent B (OrderService owns Order, OrderItem)
    Shared: app/models/base.py → serialize modifications
    
  3. Migration Plan: Ordered list of migrations with serialization markers. Migrations within the same Alembic chain or Django app must be sequential.

    Sequential: 001_create_users → 002_create_orders → 003_create_order_items
    Reason: Orders depend on Users (FK), OrderItems depend on Orders (FK)
    
  4. Shared Dependency Inventory: Files that multiple agents need to modify, requiring serialization.

    Shared files (serialize all modifications):
    - app/main.py          (router registration)
    - app/api/deps.py      (shared dependency injection)
    - app/database.py      (engine/session factory)
    - tests/conftest.py    (shared fixtures)
    - pyproject.toml       (dependency additions)
    
  5. Import Direction Declaration: Explicit dependency direction between modules to prevent circular imports. The import graph must be a DAG — if module A imports module B, module B must not import module A.

    Allowed direction:  api.v1.users → services.user_service → models.user
    Forbidden:          models.user → services.user_service (upward import)
    
    For type-checking-only imports, use:
    from typing import TYPE_CHECKING
    if TYPE_CHECKING:
        from app.services import UserService  # no runtime import
    

When Architecture Phase Can Be Skipped

For single-agent tasks (bug fixes, small features), these artifacts are unnecessary overhead. Skip when:

  • Only one agent will implement (no parallelism)
  • No new models or migrations needed
  • No shared files will be modified

For deeper domain context on API design and database patterns, consult the wiki pages listed in Knowledge Source Index.

Performance Regression Detection

For the Convergent Fix Loop Tier 2 (code review), performance regression detection requires knowing which tools to use and what patterns to flag. Unlike iOS which has Instruments as a unified profiler, Python has specialized tools for different performance dimensions.

Profiling Tools

ToolTypeOverheadBest For
cProfileDeterministic (stdlib)2-5× slowdownDevelopment: per-function call counts and cumulative time
py-spySampling (OS-level)<5%Production: attach to running process, flame graph generation
ScaleneHybrid (CPU+mem+GPU)ModerateLine-level analysis distinguishing Python vs native time
MemrayAllocation trackingModerateMemory: peak allocation call stacks, flame graphs
tracemallocstdlib memoryLowQuick diagnosis of Python object leaks
pytest-benchmarkRegression benchmarkLowAutomated performance regression tests in CI

Detection Patterns for Tier 2 Review

The code-reviewer agent should flag these performance anti-patterns:

  1. N+1 Queries: Loop body makes a database query per iteration. Detection:

    # Anti-pattern: N+1 query
    for user in users:
        orders = session.query(Order).filter(Order.user_id == user.id).all()
    
    # Fix: eager loading
    users = session.query(User).options(selectinload(User.orders)).all()
    
  2. Synchronous I/O in async context: Blocking the event loop.

    # Anti-pattern: blocks event loop
    result = requests.get(url)  # synchronous HTTP in async handler
    
    # Fix: async HTTP client
    result = await httpx.AsyncClient().get(url)
    
  3. Unbounded memory growth: Loading entire datasets into memory.

    # Anti-pattern: loads all rows
    all_records = session.query(Record).all()
    
    # Fix: streaming with yield_per
    for record in session.query(Record).yield_per(1000):
        process(record)
    
  4. Unnecessary serialization: Converting between formats in hot paths.

    # Anti-pattern: double-parse
    data = json.loads(json.dumps(obj))  # JSON roundtrip for deep copy
    
    # Fix: copy.deepcopy or model_copy
    data = obj.model_copy(deep=True)  # Pydantic native
    

Running Performance Checks

When Tier 2 flags a potential performance issue, verify with profiling:

# Quick CPU profile of specific test
uv run python -m cProfile -s cumulate tests/test_performance.py

# Memory check for leak detection
uv run python -m tracemalloc --nb-frames 25 src/app.py

# Benchmark a specific operation
uv run pytest tests/test_performance.py --benchmark-only

For deeper performance engineering context, consult the wiki page listed in Knowledge Source Index.

Modularization & Parallel Strategy

How the project's module structure affects parallel execution opportunities. The choice between feature-based and layer-based modularization determines how many agents can work simultaneously without conflicts.

Each feature is a vertical slice containing its own router/controller, models, schemas, services, and tests. Agents own entire features with zero file overlap.

FastAPI feature-based:

app/
  features/
    users/
      router.py          # Agent A owns this directory
      models.py
      schemas.py
      service.py
      tests/
        test_router.py
        test_service.py
    orders/
      router.py          # Agent B owns this directory
      models.py
      schemas.py
      service.py
      tests/
  shared/                # Shared infrastructure (serialize modifications)
    database.py
    auth.py
    deps.py

Django feature-based (standard — Django apps ARE feature modules):

apps/
  users/                 # Agent A owns this app
    models.py
    views.py
    serializers.py
    urls.py
    tests/
  orders/                # Agent B owns this app
    models.py
    views.py
    serializers.py
    urls.py
    tests/

Flask feature-based:

app/
  blueprints/
    users/               # Agent A owns this blueprint
      __init__.py
      routes.py
      models.py
      services.py
      tests/
    orders/              # Agent B owns this blueprint
      routes.py
      models.py
      tests/

Layer-Based Modularization (Requires More Serialization)

Shared directories for each layer (models/, schemas/, services/). Agents working on different features may touch the same files within a shared layer.

app/
  models/
    user.py              # Agent A
    order.py             # Agent B
    __init__.py          # CONFLICT: both agents may add imports
  schemas/
    user.py              # Agent A
    order.py             # Agent B
  services/
    user_service.py      # Agent A
    order_service.py     # Agent B
  api/
    v1/
      users.py           # Agent A
      orders.py          # Agent B

Layer-based is safe when each agent works on distinct files within each layer. Conflicts arise in __init__.py files (re-exports) and shared configuration files. The conflict matrix in Parallel Conflict Scenarios covers these cases.

Hybrid Strategy

Large projects often use a hybrid: feature-based for new features, layer-based for legacy code. The orchestrator should:

  1. Detect the project's modularization style from directory structure
  2. Assign agents to feature slices where possible (zero overlap)
  3. For layer-based code, use files_touched to serialize shared file modifications

Natural Parallel Boundaries by Framework

FrameworkNatural Parallel UnitShared Files Requiring Serialization
FastAPIRouter file + its schemas/modelsapp/main.py, app/api/deps.py, conftest.py
DjangoDjango app (entire directory)project/settings.py, project/urls.py, shared templates
FlaskBlueprint (entire directory)app/init.py, app/extensions.py, shared templates
Generic PythonIndependent module/packageinit.py, pyproject.toml, conftest.py

Knowledge Source Index

This skill's operational reference covers toolchain commands, conflict scenarios, and framework patterns. For deeper domain understanding, if the fedaot-wiki MCP is wired into your environment, agents can consult it via mcp__fedaot-wiki__get_page(name="<page-name>", wiki="common") — a private internal wiki, not bundled with this skill. Its pages contain cross-linked knowledge graphs that provide conceptual depth beyond what this file covers.

When to Consult

Load wiki pages when the task requires design decisions, debugging complex issues, or understanding trade-offs — not for routine operations (toolchain commands, conflict checks, test writing) which this file already covers.

Mapping Table

Skill Phase / OperationWiki PageConsult When
Phase 2: Architecturepython-web-api-framework-designDesigning API schema boundaries, choosing between FastAPI/Django/Flask patterns, understanding ASGI/WSGI differences
Phase 2: Architecturepython-database-patternsDesigning model ownership, repository pattern, Session lifecycle, migration strategy (expand-and-contract)
Phase 2: Architecturepython-module-import-systemDesigning import direction to prevent circular imports, understanding __init__.py role in parallel conflicts
Phase 4: RED (Test Writing)python-testing-architectureFixture scoping strategy beyond basic rules, mock layer selection, property-based testing with Hypothesis
Phase 5: GREEN (Implementation)python-async-concurrency-modelImplementing async endpoints/services, event loop constraints, debugging async deadlocks
Phase 5: GREEN (Implementation)python-serialization-validationPydantic V2 validation modes, model_validate_json() optimization, TypeAdapter reuse
Phase 5: GREEN (Implementation)python-data-modelImplementing Protocol-based interfaces, dataclass patterns, operator overloading for domain models
Tier 1: Validationpython-type-checker-landscapeSelecting between mypy/pyright/ty, configuring strictness, understanding coverage trade-offs
Tier 1: Validationpython-project-toolchain-architectureTool configuration in pyproject.toml, understanding Ruff's rule categories, LSP integration
Tier 2: Code Reviewpython-performance-engineeringProfiling tools selection (cProfile/py-spy/Scalene/Memray), identifying optimization targets
Tier 2: Code Reviewpython-security-architectureSecurity vulnerability patterns beyond ast-grep checks, input validation, authentication patterns
Error Recoverypython-error-handlingDesigning exception hierarchies, error recovery patterns, distinguishing recoverable vs fatal errors
Error Recoverypython-concurrency-strategySelecting between threading/multiprocessing/asyncio for the project's workload type
Refactoringpython-language-evolutionMigration patterns (sync→async, old→new API), deprecation awareness across Python versions
Advanced: Concurrencypython-gil-free-threadingFree-threading compatibility auditing, C extension thread safety, ABI implications
Advanced: Data Pipelinespython-functional-programmingComposable generator pipelines, structural pattern matching for event dispatch, itertools composition
Advanced: Extensibilitypython-plugin-architectureDesigning plugin systems with entry points or hook specifications, plugin isolation models
Advanced: Performancepython-native-interopWhen to use C extensions/PyO3/Cython, FFI selection, ABI compatibility
Advanced: Networkpython-network-programmingHTTP client patterns (HTTPX sync/async), WebSocket handling, retry and resilience patterns

Architecture-Contract Gate (Python)

The inner-ring architecture-contract gate for Python. Run at the inner convergence point (after the Fast Gate is clean, before the outer ring). Script: arch_contract_python.py; semantics in arch-contracts.md. Emits a 越权日志; non-zero exit = Blocker.

python3 .claude/parallel-dev/scripts/arch_contract_python.py [package]   # package defaults to .

Checks:

  • Layer / forbidden import contracts — import-linter. Configure via .importlinter.ini (template in infra/templates/). The gate passes --config .importlinter.ini so the file is discovered regardless of name.

    lint-imports --config .importlinter.ini
    
  • Cyclic imports — pylint:

    pylint --disable=all --enable=cyclic-import <package>
    
  • Concurrency baseline — a stdlib ast scan for blocking calls (time.sleep, synchronous requests.*, synchronous file reads) directly inside async def, plus unbounded ThreadPoolExecutor. No external tool needed.

A missing tool degrades that check to a no-op pass with an explicit coverage note — the gate is never silently green.