11import * as path from 'path' ;
2- import * as fs from 'fs-extra' ;
32import { Uri } from 'vscode' ;
4- import { PythonEnvironment } from '../../api' ;
5- import { traceVerbose , traceWarn } from '../../common/logging' ;
3+ import { traceVerbose } from '../../common/logging' ;
64
75/**
8- * Resolves the site-packages directory path for a given Python environment.
9- * This function handles different platforms and Python versions .
6+ * Resolves the package directory path for a given Python environment based on sysPrefix .
7+ * This is a utility function for environment managers to set the packageFolder property .
108 *
11- * @param environment The Python environment to resolve site-packages for
12- * @returns Promise< Uri | undefined> The Uri to the site-packages directory, or undefined if not found
9+ * @param sysPrefix The sys.prefix of the Python environment
10+ * @returns Uri | undefined The Uri to the package directory, or undefined if it cannot be determined
1311 */
14- export async function resolveSitePackagesPath ( environment : PythonEnvironment ) : Promise < Uri | undefined > {
15- const sysPrefix = environment . sysPrefix ;
12+ export function resolvePackageFolderFromSysPrefix ( sysPrefix : string ) : Uri | undefined {
1613 if ( ! sysPrefix ) {
17- traceWarn ( `No sysPrefix available for environment: ${ environment . displayName } ` ) ;
1814 return undefined ;
1915 }
2016
21- traceVerbose ( `Resolving site-packages for environment: ${ environment . displayName } , sysPrefix: ${ sysPrefix } ` ) ;
17+ traceVerbose ( `Resolving package folder for sysPrefix: ${ sysPrefix } ` ) ;
2218
23- // Common site-packages locations to check
24- const candidates = getSitePackagesCandidates ( sysPrefix ) ;
25-
26- // Check each candidate path
27- for ( const candidate of candidates ) {
28- try {
29- if ( await fs . pathExists ( candidate ) ) {
30- const uri = Uri . file ( candidate ) ;
31- traceVerbose ( `Found site-packages at: ${ candidate } ` ) ;
32- return uri ;
33- }
34- } catch ( error ) {
35- traceVerbose ( `Error checking site-packages candidate ${ candidate } : ${ error } ` ) ;
36- }
37- }
19+ // For most environments, we can use a simple heuristic:
20+ // Windows: {sysPrefix}/Lib/site-packages
21+ // Unix/Linux/macOS: {sysPrefix}/lib/python*/site-packages (we'll use a common pattern)
22+ // Conda: {sysPrefix}/site-packages
3823
39- traceWarn ( `Could not find site-packages directory for environment: ${ environment . displayName } ` ) ;
40- return undefined ;
41- }
24+ let packageFolderPath : string ;
4225
43- /**
44- * Gets candidate site-packages paths for different platforms and Python versions.
45- *
46- * @param sysPrefix The sys.prefix of the Python environment
47- * @returns Array of candidate paths to check
48- */
49- function getSitePackagesCandidates ( sysPrefix : string ) : string [ ] {
50- const candidates : string [ ] = [ ] ;
51-
52- // Windows: typically in Lib/site-packages
5326 if ( process . platform === 'win32' ) {
54- candidates . push ( path . join ( sysPrefix , 'Lib' , 'site-packages' ) ) ;
55- }
56-
57- // Unix-like systems: typically in lib/python*/site-packages
58- // We'll check common Python version patterns
59- const pythonVersions = [
60- 'python3.12' , 'python3.11' , 'python3.10' , 'python3.9' , 'python3.8' , 'python3.7' ,
61- 'python3' , // fallback
62- ] ;
63-
64- for ( const pyVer of pythonVersions ) {
65- candidates . push ( path . join ( sysPrefix , 'lib' , pyVer , 'site-packages' ) ) ;
66- }
67-
68- // Additional locations for conda environments
69- candidates . push ( path . join ( sysPrefix , 'site-packages' ) ) ; // Some minimal environments
70-
71- return candidates ;
72- }
73-
74- /**
75- * Checks if a path is likely a site-packages directory by looking for common markers.
76- *
77- * @param sitePkgPath Path to check
78- * @returns Promise<boolean> True if the path appears to be a site-packages directory
79- */
80- export async function isSitePackagesDirectory ( sitePkgPath : string ) : Promise < boolean > {
81- try {
82- const stat = await fs . stat ( sitePkgPath ) ;
83- if ( ! stat . isDirectory ( ) ) {
84- return false ;
85- }
86-
87- // Check for common site-packages markers
88- const contents = await fs . readdir ( sitePkgPath ) ;
89-
90- // Look for common packages or pip-related files
91- const markers = [
92- 'pip' , 'setuptools' , 'wheel' , // Common packages
93- '__pycache__' , // Python cache directory
94- ] ;
27+ // Windows: typically in Lib/site-packages
28+ packageFolderPath = path . join ( sysPrefix , 'Lib' , 'site-packages' ) ;
29+ } else {
30+ // Unix-like systems: try common locations
31+ // First try conda style
32+ const condaPath = path . join ( sysPrefix , 'site-packages' ) ;
33+ // Then try standard site-packages location (use python3 as a reasonable default)
34+ const standardPath = path . join ( sysPrefix , 'lib' , 'python3' , 'site-packages' ) ;
9535
96- return markers . some ( marker => contents . includes ( marker ) ) || contents . length > 0 ;
97- } catch {
98- return false ;
36+ // For simplicity, we'll prefer the conda style if this looks like a conda environment,
37+ // otherwise use the standard path
38+ if ( sysPrefix . includes ( 'conda' ) || sysPrefix . includes ( 'miniconda' ) || sysPrefix . includes ( 'anaconda' ) ) {
39+ packageFolderPath = condaPath ;
40+ } else {
41+ packageFolderPath = standardPath ;
42+ }
9943 }
44+
45+ const uri = Uri . file ( packageFolderPath ) ;
46+ traceVerbose ( `Resolved package folder to: ${ uri . fsPath } ` ) ;
47+ return uri ;
10048}
0 commit comments