Skip to content

Poetry: {cache-dir} placeholder not properly resolved in virtualenvs.path #1184

@karthiknadig

Description

@karthiknadig

Problem

When querying poetry config virtualenvs.path, Poetry may return a path containing the {cache-dir} placeholder (e.g., {cache-dir}/virtualenvs). The extension doesn't properly resolve this placeholder.

Current Code

// poetryUtils.ts L157-164
const { stdout } = await exec(`"${poetry}" config virtualenvs.path`);
if (stdout) {
    const venvPath = stdout.trim();
    // Poetry might return the path with placeholders like {cache-dir}
    // If it doesn't start with / or C:\ etc., assume it's using default
    if (!path.isAbsolute(venvPath) || venvPath.includes('{')) {
        const home = getUserHomeDir();
        if (home) {
            poetryVirtualenvsPath = path.join(home, '.cache', 'pypoetry', 'virtualenvs');
        }
    }

Issue

  1. When {cache-dir} is detected, the code falls back to a hardcoded path that's incorrect on Windows (see Poetry: Incorrect default virtualenvs path on Windows and macOS #1182)
  2. The {cache-dir} placeholder should be properly resolved to Poetry's actual cache directory

PET Server Reference

The PET server properly resolves this in pet-poetry/src/config.rs:

fn resolve_virtualenvs_path(virtualenvs_path: &Path, cache_dir: &Option<PathBuf>) -> PathBuf {
    if virtualenvs_path
        .to_string_lossy()
        .to_lowercase()
        .contains("{cache-dir}")
    {
        if let Some(cache_dir) = &cache_dir {
            let virtualenvs_path = PathBuf::from(
                virtualenvs_path
                    .to_string_lossy()
                    .replace("{cache-dir}", cache_dir.to_string_lossy().as_ref()),
            );
            return virtualenvs_path;
        }
    }
    virtualenvs_path.to_path_buf()
}

Suggested Fix

  1. Query Poetry's cache directory: poetry config cache-dir
  2. Replace {cache-dir} in the virtualenvs path with the actual cache directory
  3. If cache-dir query fails, use platform-specific defaults
async function resolveVirtualenvsPath(poetry: string, virtualenvsPath: string): Promise<string> {
    if (virtualenvsPath.includes('{cache-dir}')) {
        try {
            const { stdout } = await exec(`"${poetry}" config cache-dir`);
            const cacheDir = stdout.trim();
            return virtualenvsPath.replace('{cache-dir}', cacheDir);
        } catch {
            // Fall back to platform-specific default cache dir
            return virtualenvsPath.replace('{cache-dir}', getDefaultCacheDir());
        }
    }
    return virtualenvsPath;
}

Affected File

src/managers/poetry/poetryUtils.ts

Metadata

Metadata

Assignees

Labels

bugIssue identified by VS Code Team member as probable bugneeds PR

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions