1717using System . Collections . Generic ;
1818using System . IO ;
1919using System . Linq ;
20+ using Microsoft . Python . Analysis . Core . DependencyResolution ;
2021using Microsoft . Python . Analysis . Core . Interpreter ;
2122using Microsoft . Python . Analysis . Modules ;
2223using Microsoft . Python . Analysis . Types ;
@@ -39,8 +40,9 @@ public static string GetUniqueId(string moduleName, string filePath, ModuleType
3940
4041 var interpreter = services . GetService < IPythonInterpreter > ( ) ;
4142 var fs = services . GetService < IFileSystem > ( ) ;
42-
43- var modulePathType = GetModulePathType ( filePath , interpreter . ModuleResolution . LibraryPaths , fs ) ;
43+
44+ var moduleResolution = interpreter . ModuleResolution ;
45+ var modulePathType = GetModulePathType ( filePath , moduleResolution . LibraryPaths , fs ) ;
4446 switch ( modulePathType ) {
4547 case PythonLibraryPathType . Site when cachingLevel < AnalysisCachingLevel . Library :
4648 return null ;
@@ -82,19 +84,28 @@ public static string GetUniqueId(string moduleName, string filePath, ModuleType
8284 return $ "{ moduleName } ({ config . Version . Major } .{ config . Version . Minor } )";
8385 }
8486
85- // If all else fails, hash module data.
86- return $ "{ moduleName } .{ HashModuleContent ( Path . GetDirectoryName ( filePath ) , fs ) } ";
87+ var parent = moduleResolution . CurrentPathResolver . GetModuleParentFromModuleName ( moduleName ) ;
88+ var hash = HashModuleFileSizes ( parent ) ;
89+ // If all else fails, hash modules file sizes.
90+ return $ "{ moduleName } .{ ( ulong ) hash } ";
8791 }
8892
89- private static string HashModuleContent ( string moduleFolder , IFileSystem fs ) {
90- // Hash file sizes
91- var total = fs
92- . GetFileSystemEntries ( moduleFolder , "*.*" , SearchOption . AllDirectories )
93- . Where ( fs . FileExists )
94- . Select ( fs . FileSize )
95- . Aggregate ( ( hash , e ) => unchecked ( hash * 31 ^ e . GetHashCode ( ) ) ) ;
93+ private static long HashModuleFileSizes ( IImportChildrenSource source ) {
94+ var hash = 0L ;
95+ var names = source . GetChildrenNames ( ) ;
96+ foreach ( var name in names ) {
97+ if ( source . TryGetChildImport ( name , out var child ) ) {
98+ if ( child is ModuleImport moduleImport ) {
99+ hash = unchecked ( hash * 31 ^ moduleImport . ModuleFileSize ) ;
100+ }
101+
102+ if ( child is IImportChildrenSource childSource ) {
103+ hash = unchecked ( hash * 31 ^ HashModuleFileSizes ( childSource ) ) ;
104+ }
105+ }
106+ }
96107
97- return ( ( uint ) total ) . ToString ( ) ;
108+ return hash ;
98109 }
99110
100111 private static PythonLibraryPathType GetModulePathType ( string modulePath , IEnumerable < PythonLibraryPath > libraryPaths , IFileSystem fs ) {
0 commit comments