/// <summary> /// target is the newly initialized value. /// args are the arguments to be passed to __init__ /// </summary> public override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args) { DynamicMetaObject codeContext = target; CodeContext context = (CodeContext)codeContext.Value; target = args[0]; args = ArrayUtils.RemoveFirst(args); ValidationInfo valInfo = BindingHelpers.GetValidationInfo(target); Expression res; PythonType instType = DynamicHelpers.GetPythonType(target.Value); BindingRestrictions initRestrictions = BindingRestrictions.Empty; if (IronPython.Modules.Builtin.isinstance(target.Value, _newType) && NeedsInitCall((CodeContext)codeContext.Value, instType, args.Length)) { // resolve __init__ PythonTypeSlot init; instType.TryResolveSlot(context, "__init__", out init); if (init is PythonFunction) { // avoid creating the bound method, just invoke it directly Expression[] allArgs = new Expression[args.Length + 3]; allArgs[0] = codeContext.Expression; allArgs[1] = AstUtils.WeakConstant(init); allArgs[2] = target.Expression; for (int i = 0; i < args.Length; i++) { allArgs[3 + i] = args[i].Expression; } res = DynamicExpression.Dynamic( context.LanguageContext.Invoke(_signature.InsertArgument(Argument.Simple)), typeof(object), allArgs ); } else if (init is BuiltinMethodDescriptor || init is BuiltinFunction) { IList <MethodBase> targets; if (init is BuiltinMethodDescriptor) { targets = ((BuiltinMethodDescriptor)init).Template.Targets; } else { targets = ((BuiltinFunction)init).Targets; } PythonBinder binder = context.LanguageContext.Binder; DynamicMetaObject initInvoke = binder.CallMethod( new PythonOverloadResolver( binder, target, args, _signature, codeContext.Expression ), targets, BindingRestrictions.Empty ); res = initInvoke.Expression; initRestrictions = initInvoke.Restrictions; } else { // some weird descriptor has been put in place for __init__, we need // to call __get__ on it each time. res = MakeDynamicInitInvoke( context, args, Expression.Call( typeof(PythonOps).GetMethod("GetInitSlotMember"), codeContext.Expression, Expression.Convert(AstUtils.WeakConstant(_newType), typeof(PythonType)), Expression.Convert(AstUtils.WeakConstant(init), typeof(PythonTypeSlot)), AstUtils.Convert(target.Expression, typeof(object)) ), codeContext.Expression ); } } else { // returned something that isn't a subclass of the creating type // __init__ will not be run. res = AstUtils.Empty(); } // check for __del__ PythonTypeSlot delSlot; if (instType.TryResolveSlot(context, "__del__", out delSlot)) { res = Expression.Block( res, Expression.Call( typeof(PythonOps).GetMethod("InitializeForFinalization"), codeContext.Expression, AstUtils.Convert(target.Expression, typeof(object)) ) ); } return(BindingHelpers.AddDynamicTestAndDefer( this, new DynamicMetaObject( Expression.Block( res, target.Expression ), target.Restrict(target.LimitType).Restrictions.Merge(initRestrictions) ), args, valInfo )); }