@@ -196,7 +196,7 @@ public IMember GetValueFromFunctionType(IPythonFunctionType fn, IPythonInstance
196
196
// make sense to evaluate stubs since they already should be annotated.
197
197
if ( fn . DeclaringModule is IDocument doc && fd ? . Ast == doc . GetAnyAst ( ) ) {
198
198
// Stubs are coming from another module.
199
- return TryEvaluateWithArguments ( fn . DeclaringModule , fd , args ) ;
199
+ return TryEvaluateWithArguments ( fn , args ) ;
200
200
}
201
201
return UnknownType ;
202
202
}
@@ -207,9 +207,26 @@ public IMember GetValueFromProperty(IPythonPropertyType p, IPythonInstance insta
207
207
return instance . Call ( p . Name , ArgumentSet . Empty ) ;
208
208
}
209
209
210
- private IMember TryEvaluateWithArguments ( IPythonModule module , FunctionDefinition fd , IArgumentSet args ) {
210
+
211
+ private readonly Dictionary < int , IMember > _argEvalCache = new Dictionary < int , IMember > ( ) ;
212
+
213
+ private IMember TryEvaluateWithArguments ( IPythonFunctionType fn , IArgumentSet args ) {
214
+ var name = fn . DeclaringType != null ? $ "{ fn . DeclaringModule . Name } .{ fn . Name } " : fn . Name ;
215
+ var argHash = args
216
+ . Arguments
217
+ . Select ( a => a . Name . GetHashCode ( ) ^ 397 * ( a . Value ? . GetHashCode ( ) ?? 0 ) )
218
+ . Aggregate ( 0 , ( current , d ) => 31 * current ^ d ) ;
219
+ var key = fn . DeclaringModule . Name . GetHashCode ( ) ^ name . GetHashCode ( ) ^ ( 397 * argHash ) ;
220
+
221
+ if ( _argEvalCache . TryGetValue ( key , out var result ) ) {
222
+ return result ;
223
+ }
224
+
225
+ var fd = fn . FunctionDefinition ;
226
+ var module = fn . DeclaringModule ;
227
+
211
228
// Attempt to evaluate with specific arguments but prevent recursion.
212
- IMember result = UnknownType ;
229
+ result = UnknownType ;
213
230
if ( fd != null && ! _callEvalStack . Contains ( fd ) ) {
214
231
using ( OpenScope ( module , fd . Parent , out _ ) ) {
215
232
_callEvalStack . Push ( fd ) ;
@@ -222,6 +239,8 @@ private IMember TryEvaluateWithArguments(IPythonModule module, FunctionDefinitio
222
239
}
223
240
}
224
241
}
242
+
243
+ _argEvalCache [ key ] = result ;
225
244
return result ;
226
245
}
227
246
0 commit comments