Refonte Learning
Log inGet started
Python developer testing lazy import plugin initialization, first-use behavior, and application readiness on a monitoring dashboard

Your Python App Starts Faster. Will Its Plugins Still Load?

Wed, Sep 16, 2026

A service can become “ready” faster and still be less ready.

That is the failure mode to test with Python 3.15 explicit lazy imports. A plugin module that used to register an exporter during startup may now wait until a name is first touched. An optional package that used to fail during process import may now fail on the first customer request. A worker-only adapter may initialize on whichever thread first reaches a lazy binding. These are changes in when application work happens, and therefore in the boundary where the reliability contract must be proved.

As of the September 15, 2026 research cutoff, Python 3.15.0rc2 was the final planned release candidate, released September 1, and Python 3.15.0 final was scheduled for October 1. The Python Software Foundation explicitly described rc2 as a preview not recommended for production. The release page also reported roughly 144 fixes, build improvements, or documentation changes from 76 contributors since rc1; those counts are release-maintenance context, not lazy-import performance evidence.

This playbook uses that release-candidate window as a controlled lab. The decision is narrower than “upgrade to 3.15”: prove every promised capability is initialized, observable, and recoverable before you promise it.

Define the capability that startup must actually deliver

Treat process launch, liveness, readiness, and first successful business use as different milestones. A PID existing is not evidence that an export plugin is registered. A /health response is not evidence that the PDF export path can load its formatter. A registry containing a name is still not evidence that invoking that plugin will succeed.

The existing Refonte Learning article on Python 3.15 compatibility and wheel readiness is useful background for interpreter, packaging, ABI, container, and rollback qualification; this article deliberately starts downstream, at behavioral initialization.

Use a capability contract before changing any import. The following is a proposed local operating model, not a Python requirement:

Milestone

Evidence required

Primary owner

Gate

Process launched

Entrypoint reached; process remains alive

Platform

Liveness only

Basic readiness

Required infrastructure and bootstrap completed

Platform + backend

May receive limited traffic

report.export.pdf ready

Plugin registered; required dependency validated; worker adapter initialized

Backend + library owner

Capability may be advertised

First invocation

Synthetic export succeeds in a fresh process

QA

Behavioral proof

Steady state

Repeated exports succeed within the declared service budget

Backend + SRE/platform

Experiment acceptance

Write the owner next to each assertion. The library maintainer owns whether importing a plugin has required side effects. The application owner owns when initialization is called. The platform team owns the point at which traffic is admitted. QA owns reproducing the first-use boundary. If nobody owns the gap between “process up” and “capability usable,” lazy imports have only exposed an existing contract problem.

The practical decision is simple: a deferred import is acceptable only when the deferred work still completes before the system promises the capability that depends on it, or when that capability is explicitly optional and reported as unavailable rather than silently accepted.

Freeze the interpreter and the experimental change

Do not compare “Python 3.14 eager” with “Python 3.15 lazy” and call the difference a lazy-import result. That folds interpreter changes, dependency resolution, binary builds, just-in-time compilation settings, filesystem state, and import semantics into one number.

For this lab, use one pinned Python 3.15.0rc2 build for both branches. Record python -VV, the executable or image digest, lockfile hash, operating system and architecture, source revision, container image, and all -X and PYTHON_* settings. Python 3.15.0rc2 was released September 1, 2026; the active schedule listed October 1, 2026 as the expected final release date. That is a future milestone, not a production endorsement.

The surrounding ownership habits belong to normal backend engineering foundations, but the experiment itself should change one thing: eager versus explicitly lazy source behavior.

Experimental field

Eager control

Lazy branch

Must remain identical?

Interpreter build

Pinned rc2 artifact

Same artifact

Yes

Source revision

Control commit

One reviewed lazy-import patch

Except target lines

Dependency lock

Same hash

Same hash

Yes

Optional formatter

Present or intentionally absent per case

Same case

Yes

JIT/runtime switches

Recorded

Same values

Yes

Worker model

Same launch command

Same launch command

Yes

Readiness probe

Same contract initially

Same contract initially

Yes

Keep a change ledger in the test artifact. If a dependency is upgraded because the lazy branch exposed a problem, that becomes a new experiment pair. If the container base changes, start a new pair. If global lazy mode changes from normal to all, that is a separate variable from adding explicit lazy syntax.

This discipline matters because PEP 810 changes timing, not the identity of the underlying import machinery after reification. Without a controlled pair, a faster launch tells you almost nothing about whether the semantic change is safe.

Map which imports may defer essential work

Build a module-to-capability map before changing syntax. PEP 810 creates the lazy binding immediately but defers target-module loading and execution to first use; laziness is local and does not recursively spread to dependencies. The language reference also places lazy import-loading failures at first use.

Review “work whose timing matters,” not merely “heavy modules.” Record what importing each module accomplishes beyond binding names.

Import or module

Business capability

Import-time effect

Required by

Initialization owner

plugins.pdf_export

PDF export

Registers pdf handler

Readiness for PDF

Application bootstrap

lab_optional_formatter

PDF formatting

Loads formatter code

First valid PDF export

Plugin owner

worker_adapter

Worker delivery

Establishes process-local adapter state

Worker readiness

Worker bootstrap

Logging extension

Diagnostics

Installs handler/filter

Before first relevant log

Platform/app bootstrap

PEP 810 permits explicit lazy imports at module scope and disallows lazy inside functions, class bodies, try blocks, wildcard imports, and from future imports.

Form

Status in PEP 810

Reliability implication

lazy import package.module

Supported at module scope

Module executes at first use

lazy from package import name

Supported at module scope

Module loads at first access to a bound name

lazy import ... inside a function

Syntax error

Use module-scope lazy import or ordinary inline import

lazy import ... inside try

Syntax error

Do not build optional-dependency handling around this form

lazy from module import *

Syntax error

Wildcard import remains eager

Explicit lazy bindings versus dynamic plugin loading

Do not treat every plugin mechanism as if PEP 810 automatically delays it. The PEP states that import() and importlib.import_module() remain eager and unchanged. A framework that discovers entry points and then calls importlib.import_module() is therefore exercising a different path from a source-level lazy import. A global all experiment can still affect ordinary module-level import statements executed elsewhere, but it does not turn the dynamic API itself into a lazy API.

Trace ordinary source imports, explicit lazy declarations, and dynamic loading calls as separate edges; “plugin loading” does not imply that an entire subsystem is deferred.

Plugin registration and import-time side effects

PEP 810 calls registry patterns risky because decorators, metaclasses, or __init_subclass__ hooks run only when the plugin module executes; it recommends explicit discovery or initialization.

For each side effect record what must exist, by when, what triggers it, and what assertion proves it. Prefer initialize_required_export_plugins() over an arbitrary attribute touch.

Build a minimal side-effect test package

Reduce the problem until you can explain every import edge. The fixture below is synthetic, original, and unexecuted in this article. It is intended for Python 3.15.0rc2 or another build that implements PEP 810 syntax. lab_optional_formatter is a deliberately fictional dependency name; omit it from the environment for the missing-package case.

reporting_lab/
├── init.py
├── registry.py
├── eager_app.py
├── lazy_app.py
├── initializer.py
└── plugins/
    ├── init.py
    └── pdf_export.py

The registry and plugin deliberately model an import-time registration side effect. In reporting_lab/registry.py:

REGISTRY = {}

def register(name):
    def decorate(func):
        REGISTRY[name] = func
        return func
    return decorate

def require(name):
    try:
        return REGISTRY[name]
    except KeyError as exc:
        raise RuntimeError(f"required plugin not registered: {name}") from exc
In reporting_lab/plugins/pdf_export.py:
from reporting_lab.registry import register
lazy import lab_optional_formatter as formatter  # fixture-only dependency

@register("pdf")
def export(report):
    return formatter.format_report(report)
Now make the eager and lazy application branches differ only at the target import. In reporting_lab/eager_app.py:
import reporting_lab.plugins.pdf_export as pdf_plugin
from reporting_lab.registry import REGISTRY, require

def ready_for_pdf():
    return "pdf" in REGISTRY

def export_pdf(report):
    return require("pdf")(report)
In reporting_lab/lazy_app.py:
lazy import reporting_lab.plugins.pdf_export as pdf_plugin
from reporting_lab.registry import REGISTRY, require

def ready_for_pdf():
    return "pdf" in REGISTRY

def export_pdf(report):
    return require("pdf")(report)

The expected difference remains a hypothesis until execution: the eager branch should register pdf during app import, while the lazy branch should not execute that plugin merely because its binding is declared. That expectation follows documented first-use and side-effect timing; the observed result still belongs to your environment.

Add an explicit repair in reporting_lab/initializer.py using the standard dynamic importer, which PEP 810 documents as eager:

import importlib

def initialize_required_export_plugins():
    importlib.import_module("reporting_lab.plugins.pdf_export")

Run every case in a fresh subprocess. Reusing an interpreter can leave the plugin in sys.modules and hide first-use behavior. PEP 810 says a lazy module enters sys.modules when reified, after which normal caching applies.

Use this fixture checklist before accepting any result:

  • Same pinned interpreter, source revision, and lockfile for eager and lazy cases.

  • New process for unused-plugin, first-request, missing-dependency, registration-side-effect, and worker cases.

  • No network calls; the formatter is either a local fixture package or intentionally absent.

  • Assert registry state before first access and after explicit initialization.

  • Capture exception type, chain, process ID, thread identity, and exit status.

  • Leave measured-result fields blank until execution; do not paste “expected” text into an “observed” column.

The fixture is intentionally small because production import graphs are deceptive. Prove the timing rule in isolation first, then transplant the same assertions into the real service.

Move error handling to the real failure boundary

Lazy imports move some failures from application import time to first use. PEP 810 explicitly documents that ImportError, ModuleNotFoundError, syntax errors, and related import failures are deferred until the lazy name is resolved, with exception chaining intended to preserve both the declaration and first-use context. If reification fails, the lazy object is not replaced; a later use retries the reification.

That changes who can catch the error. PEP 810 disallows lazy import inside try, so optional-dependency policy belongs at the boundary that invokes or validates the capability, not around the declaration.

Use two negative fixtures. First, omit the fictional lab_optional_formatter package. The PDF plugin can still register when its module loads because the formatter binding itself is lazy; the failure should occur when export() first touches formatter. Second, create a local module that exists but does not export a requested name, then declare a module-scope lazy from... import MissingFormatter; the language’s normal from-import semantics raise ImportError if the name cannot be resolved, but the lazy version moves that failure to first access.

Case

Eager boundary

Lazy boundary to test

Correct owner

Missing module

Application/plugin import

First use of lazy module binding

Capability initializer or request layer

Missing imported name

from import

First use of lazy imported name

Library/application boundary

Plugin body raises

Plugin import

First plugin reification

Bootstrap if required; request path if truly optional

Application catches and returns success

Immediate false success risk

Deferred false success risk

API/application owner

Do not turn a required dependency failure into a successful readiness result. Do not log an exception and return an empty export. For a genuinely optional capability, translate the failure into an explicit “capability unavailable” outcome chosen by the API owner and keep the base service ready only if the published contract allows that degraded mode.

For a required capability, the stronger design is to make readiness execute a named validation path that reaches the dependency before traffic is admitted. The error can still be deferred relative to module import; it just cannot be deferred past the promise boundary.

Your test assertion should examine the whole failure path: exception class, chained cause, log/metric emission, externally visible status, and readiness state. “The exception was raised somewhere” is not enough. The decision is whether the right layer observed it and whether the system stopped promising something it could not provide.

Run the plugin-registration worked example

Carry the reporting service through a state machine: declaration, module execution, registration, validation, then invocation. Find the first divergence from the eager control rather than touching values until the lazy test passes.

These are expected outcomes, not results; keep Observed blank until execution.

Step

Eager-control hypothesis

Explicit-lazy hypothesis

Evidence

Owner

Observed

Import app module

Plugin executes

Lazy binding created

Registry snapshot

QA

Check pdf registration

Present

Absent until plugin reifies

REGISTRY assertion

Plugin owner

Run explicit initializer

Already present/idempotent

Plugin imports and registers

Registry + import event

App owner

Validate formatter present

Pass when fixture installed

Pass only when validation touches it

Validation result

Library owner

Invoke export

Business result

Reifies any remaining lazy binding

Synthetic export

QA

Formatter absent

Fails before promised use if validated

Must fail before promised use if required

Exception + readiness

App/platform

Registration is part of capability initialization when callers discover behavior through the registry. If a dispatcher consults the registry before first access to the lazy binding, the plugin is functionally absent.

A plugin that is declared but never used

In a fresh lazy-branch process, import reporting_lab.lazy_app, then call ready_for_pdf() without touching pdf_plugin. Readiness must not claim PDF capability when pdf is absent from the registry. This tests the invalid assumption that declaration equals registration.

Do not repair the test by evaluating pdf_plugin solely to force reification. Repair the contract: bootstrap calls initialize_required_export_plugins(), asserts pdf registration, keeps readiness false on a required failure, and marks only that capability unavailable when it is genuinely optional. An explicit initializer makes ownership reviewable.

A plugin first touched after readiness

Next permit basic readiness and send the first PDF request in two fresh processes: formatter present, then absent. Determine whether first request performs deferred initialization; with the dependency absent, require a visible late failure.

Dependency

Initial readiness contract

First PDF request hypothesis

Revised contract if PDF is required

Observed

Present

Basic service ready only

First request may pay deferred work

Initialize + validate PDF before capability-ready

Absent

Basic service ready only

First request fails visibly

Keep PDF capability unready; fail service readiness if PDF is mandatory

Absent, PDF optional

Base service may be ready

PDF must report unavailable

Advertise degraded capability explicitly

If required work moved behind readiness, move the readiness boundary rather than lowering the evidence bar.

Test first use across workers and threads

PEP 810 says lazy-import reification follows Python’s existing import-lock discipline: one thread performs the import and the importing module’s binding is updated atomically. It also explicitly notes that a module which historically happened to import on the main thread may instead import on another thread if that thread triggers first access. That is an import-safety statement, not a guarantee that your module’s application initialization side effects are valid on every thread.

Separate the two questions. “Can CPython safely reify this import concurrently?” is covered by the import mechanism. “May this adapter initialize from a request worker, callback thread, or child process?” belongs to the adapter’s contract.

Add a fixture-only worker_adapter.initialize() that records os.getpid() and threading.current_thread().name, then establishes process-local state. Do not make import itself responsible for that state. Worker bootstrap should call the initializer explicitly before that worker reports capability readiness.

A proposed bounded concurrency test can use four threads per fresh process; four is only a local lab choice, not a Python threshold. Release them from a barrier so they attempt the same first capability together. Assert that the capability becomes usable, that initialization ownership matches the contract, and that no request receives a false success.

Worker model

First-use trigger

Expected initialization owner

Assertion

Observed

Single process

Main-thread startup

Main bootstrap

Adapter ready before capability-ready

Fresh spawned worker

Worker bootstrap

Worker process

PID-local state exists before traffic

Pre-fork child

Child bootstrap

Each child after fork

No reliance on parent-only initialized state

Thread pool

Concurrent request

Prefer completed bootstrap, not request race

Requests observe initialized adapter

Negative case

First request wins race

Test should reveal late ownership

Failure is visible, not swallowed

For process models, start a brand-new worker for each trial. A parent that previously imported or initialized a module can contaminate assumptions about child state, while a spawned process will build its own import state. The test should record what your launcher actually does rather than generalizing from one worker architecture.

For thread-affine libraries, add a contract assertion that initialization occurs on the required thread. That requirement comes from the library or application, not from PEP 810. If the library has no documented thread affinity, do not invent one merely to make the test dramatic.

The pass condition is therefore not “only one import occurred.” It is “the required capability was initialized by the designated lifecycle owner before any worker advertised or served that capability.” A correct import lock cannot repair a misplaced readiness boundary.

Compare full capability latency, not just launch time

Measure two clocks: process launch to basic readiness, and process launch to the first successful operation for each deferred capability. If PDF export is mandatory, the second clock is decisive.

Hold the interpreter artifact, machine class, CPU allocation, dependency lock, worker count, and payload constant. Record bytecode- and filesystem-cache state; a fresh process alone does not prove a cold filesystem.

Predeclare repeated fresh-process trials. A synthetic local plan might use 30 per condition; that is not a Python recommendation.

Cold launch and first successful request

Define events precisely:

  • T0: launcher starts the Python process.

  • Tready: the service publishes the readiness state under test.

  • Tcap: the first synthetic business operation returns a correct result.

  • A failed first operation has no successful Tcap; record it as failure, not as a long sample to be discarded.

Then compare eager control and lazy branch using the same capability. Keep process-start latency and full-capability latency in separate columns.

Environment

Branch

Repetitions

Launch → ready median (ms)

Launch → ready p95 (ms)

Launch → first success median (ms)

Launch → first success p95 (ms)

Failures

Recorded test environment

Eager

Same test environment

Lazy

Same environment, formatter absent

Eager

N/A

N/A

Same environment, formatter absent

Lazy

N/A

N/A

Blank cells are intentional. PEP 810 benchmarks are not evidence for this service; use only the pinned pair under the declared workload.

Warm behavior and repeated failure attempts

Measure warm requests separately after successful reification. PEP 810 says the binding becomes the real object and later accesses specialize, but it does not predict your request latency.

Also run repeated failure attempts. PEP 810 states that when reification raises, the lazy object is not replaced and subsequent uses retry the whole reification. A missing formatter can therefore produce repeated import attempts unless the application changes state or short-circuits at a higher layer.

Scenario

Attempts

What to count

Why

First successful export

1

Initialization + business latency

Locates deferred work

Warm export

Local fixed count

Business latency only

Establishes steady state

Missing dependency

Local fixed count

Every exception and reification attempt

Detects retry/error amplification

Recovered dependency in new process

Same as success case

Recovery and first success

Proves clean recovery path

Do not assume application-level retry is harmless. Repeated import failures can amplify CPU, I/O, logging, and error-budget cost; measure that before rollout.

Make readiness checks prove required initialization

A readiness check should answer a routing question: may this process receive work that depends on a named capability? It should not be a ceremonial duplicate of liveness.

For lazy imports, the safest pattern is capability-aware readiness. Required plugins are explicitly initialized and validated before their capability becomes ready. Truly optional plugins may remain deferred, but the service must not advertise them as available until their own validation passes. This keeps the cost of readiness proportional to what the service promises.

The distinction also matters for security and telemetry boundaries. Refonte Learning’s discussion of API security and observability is adjacent operational context; the specific lazy-import contract here remains application-defined.

Check

Question answered

May trigger deferred work?

Failure effect

Liveness

Is the process responsive?

Prefer no

Restart policy only

Basic readiness

Can the process accept its minimum supported traffic?

Yes, for mandatory bootstrap

Remove from routing on failure

Capability readiness

Is report.export.pdf initialized and dependency-valid?

Yes, intentionally

Do not advertise/route that capability

Synthetic capability probe

Can a representative operation complete?

Yes

Escalate when required contract fails

Avoid a readiness implementation that simply reads the lazy proxy to make it resolve. That creates a hidden dependency on import semantics and makes future code review harder. Call the explicit initializer, then assert postconditions: registry entry exists, required dependency validation passed, worker-local adapter state exists, and the capability’s own health check succeeds.

For optional features, define the degradation contract before testing. “Optional” must mean the service remains correct without the feature and callers can discover or handle its absence. A feature is not optional merely because someone wrapped its first-use error in except Exception.

For required dependencies, pay the initialization cost before readiness. That can reduce the apparent startup gain, and that is useful information. The experiment is not trying to preserve a headline number; it is deciding whether work can safely move later without crossing the service promise boundary.

Readiness checklist: name each required capability; name its initializer; name the validation assertion; record maximum allowed probe cost as a local service budget; fail closed for required capabilities; expose optional capability status explicitly; and run the check in every fresh worker process that can receive traffic.

Instrument deferred work without exposing secrets

Deferred work needs its own operational signals because the timestamp has moved. A startup log that says “service ready” cannot explain a formatter import that fails thirty seconds later on the first export request.

Use the same principles covered in Refonte Learning’s observability fundamentals, but define a narrow schema for initialization. This schema is a proposed application convention; PEP 810 specifies import behavior, not a vendor-neutral tracing or logging format.

A useful span or structured event can cover capability.initialize and capability.first_use. Keep fields bounded and low-cardinality where possible: capability name, plugin identifier, phase, outcome, exception type, process ID, worker role, thread role, attempt number, and duration in milliseconds. Do not put request bodies, authorization headers, environment dumps, credentials, connection strings, or full configuration objects into these records.

Signal

Minimal fields

Trigger

Operator action

capability.initialize

capability, plugin, outcome, duration

Explicit bootstrap

Block readiness on required failure

capability.first_use

capability, attempt, worker role

First post-ready invocation

Compare with initialization contract

capability.import_failure

exception type, plugin, phase

Reification/import error

Page or degrade according to requirement

capability.registry_missing

capability, registry key

Registry assertion fails

Stop experiment; inspect side-effect timing

capability.fallback_verified

build/source ID, outcome

Eager-revert test

Evidence for recovery approval

Separate “import began” from “capability became usable.” A successful module import can still precede a missing initialization step, while a registered plugin can still have an unresolved dependency. Instrument contract stages, not just import events.

Also distinguish first use by process from first use by request. A worker bootstrap probe may intentionally consume the first use before traffic, which is desirable for a required capability. Record that it happened during bootstrap so an operator does not misread the absence of a customer-visible first-use event.

PEP 810’s error model makes retry visibility particularly important: failed reification can be attempted again on subsequent use. Add a bounded counter at the application layer if repeated attempts matter to operations, but do not change retry semantics merely to simplify a dashboard. The test should first reveal what the application actually does.

Keep source/build identity in deployment or experiment metadata rather than every request. During an incident, answer without secrets: which capability initialized, in which phase, on which worker, and what happened?

Prove an eager fallback on the exact build

Do not write “set lazy imports to none” in a rollback runbook until the exact interpreter build proves that control works.

There is a documentation discrepancy at the September 15 research cutoff. PEP 810 describes three global modes: normal, all, and none. It says none forces potentially lazy imports to behave eagerly. The inspected Python 3.15 command-line and environment documentation, however, lists only all and normal for both -X lazy_imports and PYTHON_LAZY_IMPORTS. PEP 810 still documents none in the specification.

Record the mismatch instead of smoothing it over:

Control surface

PEP 810

Inspected CLI docs

Recovery status

Default/normal

Explicit lazy syntax remains lazy

Documented

Not a full eager rollback

all

Makes eligible module-level imports potentially lazy

Documented

Experiment-only here

none

Described as forcing eager behavior

Not listed on inspected CLI page

Conditional until exact-build test

Reviewed eager source/build

Remove explicit lazy declarations and global-all configuration

Independent of mode discrepancy

Required fallback

A binary-level diagnostic may be as small as the following, but it is unexecuted here and must not become a production instruction until it passes on the pinned artifact:

"$PYTHON315" -X lazy_imports=none -c \
'import sys; print(sys.get_lazy_imports())'

Then run the registration and missing-dependency fixtures, not just the mode printout. A string saying none is weaker evidence than observing that the same source now performs the intended eager initialization.

The unconditional recovery design is a reviewed eager source/build path. Revert the explicit lazy changes, remove any experiment-only all setting, restore intentionally removed dependencies, rebuild from the pinned lock, and start fresh processes. The command-line documentation describes environment configuration as startup input; changing a deployment environment variable does not retroactively reinitialize workers that are already running.

Recovery checklist: stop traffic to the experiment cohort; restore the reviewed eager revision; remove lazy-mode experiment configuration; restore dependency fixtures to production state; build and identify the fallback artifact; terminate old workers; start new workers; run registry, dependency, worker-initialization, and capability-readiness probes; compare with the eager control; only then return traffic.

Stop the experiment immediately if the eager fallback cannot be demonstrated. A rollback that exists only as an untested configuration idea is not a recovery mechanism.

Set acceptance gates for the experiment

Set gates before seeing results. Stop when a required capability is missing at readiness, a dependency or initialization failure is swallowed, a required registration step is skipped, or the eager fallback cannot be demonstrated. Classify everything else under a local policy agreed by application, QA, and platform owners.

Evidence area

Accept

Investigate

Stop

Required capability

Ready only after initialization proof

Timing/owner unclear but no false readiness yet

Missing after readiness

Error visibility

Failure propagated/translated as designed

Duplicate or noisy reporting

Swallowed or returned as success

Plugin registration

Deterministic in fresh processes

Order-sensitive result

Required step skipped

Worker initialization

Correct process/thread owner

Intermittent first-use owner

Traffic admitted before required init

Full-capability latency

Within predeclared service budget

Outside target but correct

Correctness sacrificed for launch time

Fallback

Fresh-process eager path passes

Artifact/process steps unclear

Cannot demonstrate revert

Do not inherit numerical gates from another benchmark. Predeclare any service number as a local threshold with an owner and rationale, using a locally approved p95 full-capability budget and rationale.

Run the non-production sequence as normal software development practices applied to a runtime semantic change.

Phase

Owner

Artifact

Approval question

Freeze control pair

Python lead

Change ledger

Did only laziness change?

Execute isolated fixtures

QA

Raw subprocess results

Are first-use boundaries reproducible?

Run worker/readiness tests

Backend + platform

State and telemetry matrix

Is capability ready before traffic?

Run latency comparison

Performance/QA owner

Blank-to-filled result sheet

Did full capability meet its budget?

Prove fallback

Release/platform owner

Eager-revert evidence

Can we recover with fresh processes?

Review

Service owner

Signed decision record

Is the branch safe for continued evaluation?

At the September 15 cutoff, rc2 remained a preview not recommended for production. Passing this lab is therefore pre-production evidence. Re-run on the final artifact before a production decision; PEP 790 scheduled final for October 1, 2026.

Turn the initialization contract into a reviewable portfolio

The useful output is a small evidence package another engineer can rerun without reconstructing your assumptions.

Keep fixture code, interpreter identity, source diff, side-effect ledger, raw outputs, result templates, readiness assertions, and eager-fallback proof together. This connects Python developer foundations to operational behavior.

Portfolio artifact

What a reviewer should be able to answer

Import and side-effect ledger

Which imports can defer required work, and who owns initialization?

Minimal reporting fixture

Can the first-use timing be reproduced without production dependencies?

Failure matrix

Where do missing modules, missing names, and plugin failures surface?

Worker/readiness matrix

Does every process establish required state before traffic?

Latency result sheet

Was launch time separated from first successful capability use?

Fallback proof

Can the reviewed eager path be restored in fresh processes?

Decision record

Why was each capability accepted, investigated, or blocked?

Reject the package if expected and observed results are mixed, the eager baseline differs in interpreter or dependencies, errors are hidden, or rollback evidence is only configuration.

For readers who want structured practice around the surrounding engineering disciplines, Refonte Learning’s Software Engineering Program currently lists a three-month commitment of 12–14 hours per week and covers software development lifecycle, performance optimization, application security, cloud computing and microservices, real-time processing, and scalable systems; its page states a requirement of pursuing or completing a related bachelor’s degree. The page does not verify Python 3.15, PEP 810, or a lazy-import plugin lab as curriculum content.

Reviewer checklist: reproduce unused-plugin and missing-dependency cases; inspect readiness; verify worker-local initialization; ensure failures are not successful latency samples; run eager recovery from a clean process.

Resolve the remaining lazy-import decisions

Close semantic questions before debating rollout. PEP 810 keeps lazy behavior opt-in, leaves dynamic import APIs eager, and moves errors and side effects to first use for lazy bindings.

Use this decision register:

Open decision

Evidence required

Owner

Release effect

Which capabilities may initialize after basic readiness?

Capability contract

Service owner

Defines safe deferral

Which registries rely on import side effects?

Side-effect ledger + fresh-process tests

Library/app owner

May require explicit initializer

Which optional dependencies may fail after startup?

API degradation contract + negative fixtures

Backend/API owner

Defines error boundary

Can every worker initialize required local state?

Worker matrix

Platform + backend

Blocks readiness if unproved

Is eager recovery real?

Clean-process fallback run

Release owner

Blocks experiment if unproved

Do all imports change automatically? No. PEP 810 leaves normal imports eager by default. normal still respects explicit lazy syntax, while dynamic import() and importlib.import_module() calls remain eager.

Why can registry setup be delayed? A registration decorator or other module-level side effect does not execute until the lazy plugin module executes. PEP 810 identifies registry patterns as a risk and recommends explicit discovery or initialization where timing matters. Test systems whose registries depend on import execution; do not generalize to every plugin framework.

Where do failures surface? At the access that reifies the lazy binding. The language reference places module-loading errors at first use, while PEP 810 describes exception chaining and retry after failed reification. Your application decides whether that boundary is bootstrap, readiness validation, or a genuinely optional request path.

Is removing a flag sufficient? No. The CLI docs say normal respects explicit lazy, so removing global all leaves explicit lazy declarations lazy. PEP 810 describes none, but the inspected CLI page does not list it; verify it on the exact build. The unconditional fallback is reviewed eager source plus fresh-process restart.

What blocks production adoption? At this cutoff, rc2 is a preview the Python Software Foundation does not recommend for production, and final is scheduled for October 1, 2026. Local blockers include any unproved required capability, hidden first-use failure, nondeterministic registration, worker initialization ambiguity, unacceptable full-capability latency, or unproved eager recovery.

Execute both branches on the pinned rc2 artifact, fill every measured cell, preserve raw outputs, then repeat the qualifying suite on final before a production decision.