Skip to content

Commit ea0fb7a

Browse files
committed
fix(vscode): force dmypy executable override
v0.4.18 The jemalloc allocator now owns mypy.dmypyExecutable: it unconditionally overrides any pre-existing value (custom or carried over from before install) so the venv-pinned dmypy is always used. Drops the previous "leave user override in place" guard and the now-dead isDefaultDmypyValue helper. CMK-36081 Change-Id: Iecd329f2085c1b0f338d5c48679dd2e909a0af52
1 parent 6f1adfa commit ea0fb7a

4 files changed

Lines changed: 20 additions & 86 deletions

File tree

.ide/vscode/changelog/v0.4.18.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## v0.4.18
2+
3+
- **fix**: force dmypy executable override (CMK-36081)

.ide/vscode/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "cmk-vscode",
33
"displayName": "CMK Dev Tools for VS Code",
44
"description": "Build commands and helpers for Checkmk development",
5-
"version": "0.4.17",
5+
"version": "0.4.18",
66
"publisher": "checkmk",
77
"engines": {
88
"vscode": "^1.85.0"

.ide/vscode/src/profiles/python/jemallocAllocator.ts

Lines changed: 16 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import * as fs from 'fs'
77
import * as path from 'path'
88
import * as vscode from 'vscode'
99

10-
import { resolveVariables } from '../../core/config'
1110
import { error, log, notifyError, notifyInfo, notifyWarn } from '../../core/log'
1211
import { safeExecAsync } from '../../core/shell'
1312
import { killAllDmypyDaemons } from './mypyConfig'
@@ -170,24 +169,6 @@ function defaultDmypyPath(wsFolder: vscode.WorkspaceFolder): string {
170169
return path.join(wsFolder.uri.fsPath, '.venv', 'bin', 'dmypy')
171170
}
172171

173-
/** Decide whether a `mypy.dmypyExecutable` value is one of the Checkmk
174-
* default forms (and therefore safe to take over when switching to jemalloc
175-
* mode), versus a user-managed custom path we should leave alone.
176-
*
177-
* Accepted forms:
178-
* - `${cmk-ext:workspaceFolder}/.venv/bin/dmypy` — current Checkmk bundled default.
179-
* - `${workspaceFolder}/.venv/bin/dmypy` — legacy form still present in
180-
* existing `.code-workspace` files from before the switch to `cmk-ext:`.
181-
* - `<workspace>/.venv/bin/dmypy` — the resolved absolute path written
182-
* after `resolveVariables` expands the bundled default.
183-
* We compare strings only; we do not re-expand VS Code's native variables. */
184-
export function isDefaultDmypyValue(value: string, wsFolder: vscode.WorkspaceFolder): boolean {
185-
const resolvedByExt = resolveVariables(value) as string
186-
return (
187-
resolvedByExt === defaultDmypyPath(wsFolder) || value === '${workspaceFolder}/.venv/bin/dmypy'
188-
)
189-
}
190-
191172
function readAllocatorMode(): AllocatorMode {
192173
const v = vscode.workspace.getConfiguration().get<string>(SETTING_ALLOCATOR, 'default')
193174
return v === 'jemalloc' ? 'jemalloc' : 'default'
@@ -277,48 +258,35 @@ function deleteWrapperIfPresent(wrapperPath: string): void {
277258
/** Reconcile `mypy.dmypyExecutable` to match `cmk.mypy.allocator`. Idempotent.
278259
* - `"jemalloc"` + probe hit → write wrapper, point dmypyExecutable at it.
279260
* - `"jemalloc"` + probe miss → notify once, leave setting armed.
280-
* - `"default"` → release ownership (unset dmypyExecutable if it's ours),
281-
* delete wrapper.
282-
* Never overwrites a manual `mypy.dmypyExecutable` override — if the current
283-
* value is neither unset nor our own wrapper path, we log and skip. */
261+
* - `"default"` → restore the bundled venv default, delete wrapper.
262+
* The extension owns `mypy.dmypyExecutable`: it unconditionally overrides any
263+
* pre-existing value (including a custom path or one carried over from before
264+
* the extension was installed) so the venv-pinned dmypy is always used. */
284265
export async function applyAllocatorSetting(
285266
context: vscode.ExtensionContext,
286267
wsFolder: vscode.WorkspaceFolder
287268
): Promise<void> {
288269
const wrapperPath = wrapperPathFor(context)
289270
const mode = readAllocatorMode()
290271
const current = readCurrentDmypyExecutable(wsFolder)
291-
const weOwn =
292-
current === undefined || current === wrapperPath || isDefaultDmypyValue(current, wsFolder)
293272

294273
if (mode === 'default') {
295274
// Restore the bundled defaults instead of leaving the keys unset — matangover
296275
// falls back to `python -m mypy.dmypy` when `mypy.dmypyExecutable` is empty,
297-
// which breaks the venv-pinned setup. Only overwrite when we owned the prior
298-
// value (our wrapper, the bundled default literal, or unset) — never clobber
299-
// a custom user-managed dmypy path.
300-
if (weOwn) {
301-
const previousDmypy = current
302-
const previousRun = vscode.workspace
303-
.getConfiguration('mypy', wsFolder)
304-
.get<boolean>(RUN_USING_INTERPRETER_SETTING)
305-
await updateDmypyExecutable(wsFolder, defaultDmypyPath(wsFolder))
306-
await updateRunUsingInterpreter(wsFolder, true)
307-
log(
308-
`cmk.mypy.allocator=default — restored mypy.dmypyExecutable=${defaultDmypyPath(wsFolder)}, runUsingActiveInterpreter=true`
309-
)
310-
if (previousDmypy === wrapperPath || previousRun === false) {
311-
await killAllDmypyDaemons()
312-
}
313-
}
314-
deleteWrapperIfPresent(wrapperPath)
315-
return
316-
}
317-
318-
if (!weOwn) {
276+
// which breaks the venv-pinned setup.
277+
const target = defaultDmypyPath(wsFolder)
278+
const previousRun = vscode.workspace
279+
.getConfiguration('mypy', wsFolder)
280+
.get<boolean>(RUN_USING_INTERPRETER_SETTING)
281+
if (current !== target) await updateDmypyExecutable(wsFolder, target)
282+
if (previousRun !== true) await updateRunUsingInterpreter(wsFolder, true)
319283
log(
320-
`cmk.mypy.allocator=jemalloc but mypy.dmypyExecutable is set to a custom path (${current}) — leaving user override in place`
284+
`cmk.mypy.allocator=default — set mypy.dmypyExecutable=${target}, runUsingActiveInterpreter=true`
321285
)
286+
if (current === wrapperPath || previousRun === false) {
287+
await killAllDmypyDaemons()
288+
}
289+
deleteWrapperIfPresent(wrapperPath)
322290
return
323291
}
324292

.ide/vscode/tests/profiles/python/jemallocAllocator.test.ts

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -129,43 +129,6 @@ describe('detectJemallocPathAsync', () => {
129129
})
130130
})
131131

132-
describe('isDefaultDmypyValue', () => {
133-
const wsFolder = { uri: { fsPath: '/ws' } } as never
134-
135-
beforeEach(() => {
136-
vi.resetModules()
137-
})
138-
afterEach(() => {
139-
vi.doUnmock('../../../src/core/config')
140-
})
141-
142-
it('returns true for the cmk-ext placeholder form', async () => {
143-
vi.doMock('../../../src/core/config', () => ({
144-
resolveVariables: (v: string) => v.replace('${cmk-ext:workspaceFolder}', '/ws')
145-
}))
146-
const { isDefaultDmypyValue } = await import('../../../src/profiles/python/jemallocAllocator')
147-
expect(isDefaultDmypyValue('${cmk-ext:workspaceFolder}/.venv/bin/dmypy', wsFolder)).toBe(true)
148-
})
149-
150-
it('returns true for the resolved absolute default', async () => {
151-
vi.doMock('../../../src/core/config', () => ({ resolveVariables: (v: string) => v }))
152-
const { isDefaultDmypyValue } = await import('../../../src/profiles/python/jemallocAllocator')
153-
expect(isDefaultDmypyValue('/ws/.venv/bin/dmypy', wsFolder)).toBe(true)
154-
})
155-
156-
it('returns true for the legacy ${workspaceFolder} form (still present in older .code-workspace files)', async () => {
157-
vi.doMock('../../../src/core/config', () => ({ resolveVariables: (v: string) => v }))
158-
const { isDefaultDmypyValue } = await import('../../../src/profiles/python/jemallocAllocator')
159-
expect(isDefaultDmypyValue('${workspaceFolder}/.venv/bin/dmypy', wsFolder)).toBe(true)
160-
})
161-
162-
it('returns false for an unrelated custom path', async () => {
163-
vi.doMock('../../../src/core/config', () => ({ resolveVariables: (v: string) => v }))
164-
const { isDefaultDmypyValue } = await import('../../../src/profiles/python/jemallocAllocator')
165-
expect(isDefaultDmypyValue('/opt/custom/dmypy', wsFolder)).toBe(false)
166-
})
167-
})
168-
169132
describe('installCommandForPlatformAsync', () => {
170133
beforeEach(() => {
171134
vi.resetModules()

0 commit comments

Comments
 (0)