internal static DynamicMetaObject TranslateArguments(DynamicMetaObjectBinder call, Expression codeContext, DynamicMetaObject function, DynamicMetaObject /*!*/[] args, bool hasSelf, string name) { if (hasSelf) { args = ArrayUtils.RemoveFirst(args); } CallSignature sig = BindingHelpers.GetCallSignature(call); if (sig.HasDictionaryArgument()) { int index = sig.IndexOf(ArgumentType.Dictionary); DynamicMetaObject dict = args[index]; if (!(dict.Value is IDictionary) && dict.Value != null) { // The DefaultBinder only handles types that implement IDictionary. Here we have an // arbitrary user-defined mapping type. We'll convert it into a PythonDictionary // and then have an embedded dynamic site pass that dictionary through to the default // binder. DynamicMetaObject[] dynamicArgs = ArrayUtils.Insert(function, args); dynamicArgs[index + 1] = new DynamicMetaObject( Expression.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.UserMappingToPythonDictionary)), codeContext, args[index].Expression, AstUtils.Constant(name) ), BindingRestrictionsHelpers.GetRuntimeTypeRestriction(dict.Expression, dict.GetLimitType()), PythonOps.UserMappingToPythonDictionary(PythonContext.GetPythonContext(call).SharedContext, dict.Value, name) ); if (call is IPythonSite) { dynamicArgs = ArrayUtils.Insert( new DynamicMetaObject(codeContext, BindingRestrictions.Empty), dynamicArgs ); } return(new DynamicMetaObject( DynamicExpression.Dynamic( call, typeof(object), DynamicUtils.GetExpressions(dynamicArgs) ), BindingRestrictions.Combine(dynamicArgs).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(dict.Expression, dict.GetLimitType())) )); } } if (sig.HasListArgument()) { int index = sig.IndexOf(ArgumentType.List); DynamicMetaObject str = args[index]; // TODO: ANything w/ __iter__ that's not an IList<object> if (!(str.Value is IList <object>) && str.Value is IEnumerable) { // The DefaultBinder only handles types that implement IList<object>. Here we have a // string. We'll convert it into a tuple // and then have an embedded dynamic site pass that tuple through to the default // binder. DynamicMetaObject[] dynamicArgs = ArrayUtils.Insert(function, args); dynamicArgs[index + 1] = new DynamicMetaObject( Expression.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.MakeTupleFromSequence)), Expression.Convert(args[index].Expression, typeof(object)) ), BindingRestrictions.Empty ); if (call is IPythonSite) { dynamicArgs = ArrayUtils.Insert( new DynamicMetaObject(codeContext, BindingRestrictions.Empty), dynamicArgs ); } return(new DynamicMetaObject( DynamicExpression.Dynamic( call, typeof(object), DynamicUtils.GetExpressions(dynamicArgs) ), function.Restrictions.Merge( BindingRestrictions.Combine(args).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(str.Expression, str.GetLimitType())) ) )); } } return(null); }