Add empty InlineScriptEnvManager skeleton behind internal flag (PEP 723 PR 4/16)#1610
Merged
StellaHuang95 merged 1 commit intoJun 24, 2026
Merged
Conversation
… 4/16)
First PR in Phase 2 of the inline-script roadmap. Lands the empty
manager class and a registration helper gated behind an INTERNAL
flag, so the plumbing for PRs 5-16 can land incrementally without
any user-visible surface.
What is in:
- src/managers/builtin/inlineScriptEnvManager.ts (new)
Class implementing EnvironmentManager: name="inline-script",
displayName="Inline script environments", iconPath=file-code,
preferredPackageManagerId="ms-python.python:pip". Every method is
a sentinel: getEnvironments returns [], get returns undefined,
set / refresh are no-ops, resolve returns undefined. Optional
methods (create, remove, quickCreateConfig) are deliberately
omitted so the UI hides their entry points until PR 5 lands them.
- src/managers/builtin/inlineScriptMain.ts (new)
registerInlineScriptFeatures(disposables, log) -- gated
registration helper. Reads isInlineScriptsFeatureEnabled() and
returns early (with a traceVerbose, not traceInfo, so no per-
activation log noise for default users) when the flag is false.
When true, constructs the manager and registers it.
- src/helpers.ts
isInlineScriptsFeatureEnabled(): boolean -- reads
python-envs.inlineScripts.enabled via getConfiguration().get(...).
The setting is INTENTIONALLY NOT DECLARED in package.json, so:
- it does not appear in Settings UI
- it does not appear in JSON autocomplete
- it does not appear in settings search
- end users never discover it
Devs / CI can still opt in by manually adding it to settings.json
(VS Code will mark it as an unknown setting with a yellow squiggle
-- that is a feature, not a bug; signals you are on an internal
flag). The whole gate goes away in PR 16 when the feature ships
for real.
- src/extension.ts
Wires registerInlineScriptFeatures into the existing
Promise.all of manager-registration tasks, alongside system,
conda, pyenv, pipenv, poetry, and shellStartupVars.
- src/test/managers/builtin/inlineScriptEnvManager.unit.test.ts (new)
19 tests pinning the skeleton's no-op contract: static metadata,
all five EnvironmentManager methods, optional methods correctly
omitted, events exposed but never fired, dispose() is idempotent.
- src/test/managers/builtin/inlineScriptMain.unit.test.ts (new)
2 tests pinning the gate itself: flag false -> no register call,
no getPythonApi call, no disposable pushed; flag true -> exactly
one register call, two disposables pushed (mgr + registration
handle). These guard the entire "zero user impact" promise
against future refactors.
- src/test/helpers.inlineScriptsFeature.unit.test.ts (new)
3 tests covering the feature-flag helper: defaults to false,
returns true on user-set, reads from the python-envs section.
User impact
Zero. No setting in package.json, so:
- No setting visible in Settings UI search
- No autocomplete entry when typing "python-envs..." in settings.json
- No "Preview" badge or any indication the feature exists
- No empty picker section, no commands, no status-bar changes
- No log output on the default log level
PR 5-15 will land on top of this gate; PR 16 removes the gate and
declares the public setting for real.
Design context
Implements PR 4 in Phase 2 of pep723_design_questions.md. The
internal-flag approach (undeclared setting) is the strictest
interpretation of "zero user impact during incremental rollout" --
discussed in the planning conversation as the alternative to a
declared-but-default-false setting (which would still show in
autocomplete and confuse early adopters).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
edvilme
approved these changes
Jun 24, 2026
Contributor
There was a problem hiding this comment.
Can we maybe have it under src/managers/builtin/inlineScriptEnvManager/inlineScriptEnvManager.ts and src/managers/builtin/inlineScriptEnvManager/main.ts ?
| l10n.t('Environments built from PEP 723 inline script metadata.'), | ||
| true, | ||
| ); | ||
| public readonly iconPath: IconPath = new ThemeIcon('file-code'); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Roadmap context — where this PR sits
This is PR 4 of 16 in the PEP 723 inline-script roadmap. The full plan lives in #1602; here's a one-line summary of where each PR sits relative to this one:
meta.jsonsidecarrequires-python→ interpreter selectionInlineScriptEnvManagerskeletoncreate()happy pathcreate()uv-install fallbackget/set+ MementoAfter PRs 1–4 merge, PR 7 unlocks the largest downstream wave (PR 8, 9, 13, 17, 19) — see the ordering comment on #1602 for the full timeline.
Why a skeleton
The roadmap rolls out across 16 PRs. Landing each one behind a feature gate keeps
mainshippable at every step and lets reviewers see one concern at a time. This PR is the smallest possible mount point for that gate: anEnvironmentManagerimplementation that satisfies the interface contract and registers cleanly, but otherwise does nothing.Every subsequent PR (5–8) replaces one of the no-ops in this skeleton with the real thing.
What this PR does
Adds
InlineScriptEnvManager(src/managers/builtin/inlineScriptEnvManager.ts) — implementsEnvironmentManager:name = "inline-script",displayName = "Inline script environments",iconPath = file-code,preferredPackageManagerId = "ms-python.python:pip".getEnvironmentsreturns[],get/resolvereturnundefined,set/refreshare no-ops.create,remove,quickCreateConfigare deliberately not declared so the picker UI hides their entry points until PR 5 lands them.onDidChangeEnvironmentsandonDidChangeEnvironmentexposed and disposed correctly; never fired by this skeleton.Adds
registerInlineScriptFeatures(src/managers/builtin/inlineScriptMain.ts) — a gated registration helper that reads the internal flag and registers the manager only when on. Wired into the existingPromise.allof manager-registration tasks inextension.ts(alongside system, conda, pyenv, pipenv, poetry, shellStartupVars).Adds
isInlineScriptsFeatureEnabled(src/helpers.ts) — readspython-envs.inlineScripts.enabled. The setting is intentionally NOT declared inpackage.json, so it does not appear in Settings UI, JSON autocomplete, or settings search. End users never discover it. Devs / CI can opt in by manually adding it tosettings.json. Default valuefalse. Gate goes away in PR 16.User impact
Zero. The feature flag is undeclared in
package.json, so:python-envs.insettings.json.traceVerbose).PR 5–15 will all land behind the same gate; PR 16 removes the gate and declares the public setting for real.