Skip to content

feat: import autocti without arcticpy (lazy arcticpy import) #117

Closed

Description

@Jammy2211

Overview

Make import autocti work on a machine without arcticpy. arcticpy is a source-only C++ package that needs GSL and a compiler. Docs builds, PyAutoEyes, the assistant and new users therefore all fail at import autocti, even when they never clock any charge. This is cti-upkeep phase 2c, ruling R2.

Plan

  • import autocti works without arcticpy: datasets, layouts, masks, plotting and aggregator loading all keep working.
  • The nine arcticpy names autocti re-exports (ac.TrapInstantCapture, ac.CCDPhase, ac.ROE, …) still resolve to the real arcticpy classes when it is installed, so nothing changes for workspace scripts.
  • Without arcticpy, touching one of those names, or clocking, raises a clear ImportError that names the install recipe (PyAutoHeart install_arcticpy.sh).
  • Evidence: a test with arcticpy hidden, the full test_autocti suite unchanged, and the 10 phase-0b likelihood pins exact.
  • Tier: judge — merge mode: human /prm
Detailed implementation plan

Affected Repositories

  • PyAutoLabs/PyAutoCTI (primary)

Branch Survey

Repository Current Branch Dirty?
./cti/PyAutoCTI main clean

Suggested branch: feature/arcticpy-lazy-import

Implementation Steps

  1. New autocti/_arcticpy.py: an arcticpy() accessor that imports and returns the module, or raises ImportError with the recipe text and link. It also holds the tuple of the 9 re-exported names.
  2. autocti/__init__.py: drop the 9 module-level from arcticpy import ... lines and add a PEP 562 __getattr__ / __dir__ for those names. from autocti import TrapInstantCapture keeps working.
  3. autocti/clocker/{abstract,one_d,two_d}.py: add from __future__ import annotations and TYPE_CHECKING imports for the type hints. ROE(), CCD(...), add_cti and remove_cti are fetched through the accessor inside the methods.
  4. autocti/model/model_util.py, autocti/model/settings.py, autocti/charge_injection/ou_sim_ci.py: these use arcticpy only in type hints, so the imports move under TYPE_CHECKING.
  5. New test_autocti/test_lazy_arcticpy.py: a subprocess with sys.modules["arcticpy"] = None checks that import autocti works, that ac.Dataset1D and ac.Layout2DCI build, and that ac.TrapInstantCapture and a clocker raise the recipe error. Control: it must fail on current main.
  6. Checks: the full test_autocti suite, the autocti_workspace_test scripts/*/likelihood/pins.py, the 3 autocti_workspace release smoke scripts, and a search of autocti_visualization / autocti_assistant for direct re-export use.
  7. pyproject comment: arcticpy is optional at import time.

If the factor-graph or aggregator path cannot be kept clean this way, stop and record why (R2).

Key Files

  • autocti/__init__.py: the re-exports
  • autocti/clocker/*.py: the runtime arcticpy calls
  • autocti/model/*.py, autocti/charge_injection/ou_sim_ci.py: imports used only in type hints

Original Prompt

Click to expand starting prompt

autocti: import autocti works without arcticpy (lazy arcticpy import)

Type: feature
Target: autocti
Repos:

  • @PyAutoCTI
    Themes:
  • cti
  • install
    Difficulty: medium
    Autonomy: human-required
    Priority: normal
    Status: formalised
    Consequence: judge
    Review-minutes: 15
    Unattended: never
    Epic: cti-upkeep
    Phase: 2c

Ruling R2 (human, 2026-11-04): make import autocti succeed without arcticpy
installed. Anything that needs arcticpy should raise a clear error that names
the install recipe (PyAutoHeart install_arcticpy.sh). Drop the idea only if
the test suite or the factor-graph path cannot stay clean that way, and record
why.

Facts (2026-11-05 survey)

  • autocti/__init__.py re-exports nine arcticpy names as public API (ROE,
    ROEChargeInjection, CCD, CCDPhase, TrapInstantCapture,
    TrapSlowCapture, TrapInstantCaptureContinuum, TrapSlowCaptureContinuum,
    PixelBounce). Workspace scripts use them as ac.TrapInstantCapture inside
    af.Model(...).
  • Module-level from arcticpy import ... statements:
    • clocker/abstract.py, clocker/one_d.py, clocker/two_d.py (add_cti, remove_cti, ROE, PixelBounce, CCD, CCDPhase)
    • model/model_util.py, model/settings.py
    • charge_injection/ou_sim_ci.py
  • arcticpy's trap, CCD, ROE and pixel-bounce classes are pure Python, but
    arcticpy/__init__.py always imports the compiled wrapper extension. That
    means autocti cannot import just the pure-Python parts; it has to defer the
    whole arcticpy import.
  • pyproject already excludes arcticpy from the pip dependencies (its sdist is
    source-only and needs GSL and a C++ toolchain).

Approach to evaluate

  • Use a module-level __getattr__ in autocti/__init__.py (PEP 562) for the
    nine re-exports. Accessing one of them imports arcticpy on first use, and if
    arcticpy is missing it raises an ImportError that names the recipe.
  • Move the clocker, model and simulation imports into function bodies, or
    behind a single autocti/_arcticpy.py accessor.
  • Type hints use string annotations or TYPE_CHECKING.
  • Witness: in a venv with arcticpy hidden (for example a sys.modules
    None stub in a test), import autocti succeeds, ac.Dataset1D / ac.Layout2DCI
    build, and ac.TrapInstantCapture raises the recipe error. The full
    test_autocti suite and the 0b likelihood pins (autocti_workspace_test
    scripts/*/likelihood/pins.py) stay unchanged with arcticpy installed.

Activity

  1. Jammy2211 commented on Nov 5, 2026

    @Jammy2211
    CollaboratorAuthor

    Library PR created: #118. Workspace impact: none (smoke 3/3 pass, the 0b likelihood pins are exact). It awaits human /prm (judge tier).

    🤖 Generated with Claude Code

  2. Jammy2211 commented on Nov 5, 2026

    @Jammy2211
    CollaboratorAuthor

    Shipped 2026-11-05

    #118 merged (d36f307). import autocti now works without arcticpy. Using a re-exported arcticpy class or clocking raises an ImportError that names the install recipe. With arcticpy installed, nothing changes.

    CI: unittest 3.12, 3.13 and nojax all green. Pending release: this rides the next lockstep release (autocti is in the train as of PyAutoHands#333).

    🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions