public void __set__(CodeContext context, object instance, object value) { TrySetValue(context, instance, DynamicHelpers.GetPythonType(instance), value); }
internal override bool TrySetValue(CodeContext context, object instance, PythonType owner, object value) { if (instance == null) { return(false); } IPythonObject sdo = instance as IPythonObject; if (sdo == null) { throw PythonOps.TypeError("__class__ assignment: only for user defined types"); } PythonType dt = value as PythonType; if (dt == null) { throw PythonOps.TypeError("__class__ must be set to new-style class, not '{0}' object", DynamicHelpers.GetPythonType(value).Name); } if (dt.UnderlyingSystemType != DynamicHelpers.GetPythonType(instance).UnderlyingSystemType) { throw PythonOps.TypeErrorForIncompatibleObjectLayout("__class__ assignment", DynamicHelpers.GetPythonType(instance), dt.UnderlyingSystemType); } sdo.SetPythonType(dt); return(true); }
// *** END GENERATED CODE *** #endregion public override T BindDelegate <T>(CallSite <T> site, object[] args) { if (args.Length <= MaxFastLateBoundInitArgs) { CodeContext context = (CodeContext)args[0]; object inst = args[1]; PythonType instType = DynamicHelpers.GetPythonType(inst); PythonTypeSlot delSlot; PythonFunction initFunc = null; string callTarget = null; if (!instType.TryResolveSlot(context, "__del__", out delSlot)) // we don't have fast code for classes w/ finalizers { if (IronPython.Modules.Builtin.isinstance(inst, _newType) && NeedsInitCall((CodeContext)context, instType, args.Length)) { PythonTypeSlot init; instType.TryResolveSlot(context, "__init__", out init); if (init is PythonFunction) { // we can do a fast bind callTarget = "CallTarget"; initFunc = (PythonFunction)init; } } else { // we need no initialization, we can do a fast bind callTarget = "EmptyCallTarget"; } } if (callTarget != null) { int genArgCount = args.Length - 2; PythonInvokeBinder binder = context.LanguageContext.Invoke(_signature.InsertArgument(Argument.Simple)); if (genArgCount == 0) { FastInitSite fastSite = new FastInitSite(instType.Version, binder, initFunc); if (callTarget == "CallTarget") { return((T)(object)new Func <CallSite, CodeContext, object, object>(fastSite.CallTarget)); } else { return((T)(object)new Func <CallSite, CodeContext, object, object>(fastSite.EmptyCallTarget)); } } else { Type[] genArgs = ArrayUtils.ConvertAll(typeof(T).GetMethod("Invoke").GetParameters(), x => x.ParameterType); Type initSiteType; switch (args.Length - 2) { #region Generated Python Fast Init Switch // *** BEGIN GENERATED CODE *** // generated by function: gen_fast_init_switch from: generate_calls.py case 1: initSiteType = typeof(FastInitSite <>); break; case 2: initSiteType = typeof(FastInitSite <,>); break; case 3: initSiteType = typeof(FastInitSite <, ,>); break; case 4: initSiteType = typeof(FastInitSite <, , ,>); break; case 5: initSiteType = typeof(FastInitSite <, , , ,>); break; // *** END GENERATED CODE *** #endregion default: throw new InvalidOperationException(); } Type genType = initSiteType.MakeGenericType(ArrayUtils.ShiftLeft(genArgs, 3)); object initSiteInst = Activator.CreateInstance(genType, instType.Version, binder, initFunc); return((T)(object)genType.GetMethod(callTarget).CreateDelegate(typeof(T), initSiteInst)); } } } return(base.BindDelegate(site, args)); }
public void __set__(CodeContext context, object instance, object value) { // TODO: Throw? currently we have a test that verifies we never throw when this is called directly. TrySetValue(context, instance, DynamicHelpers.GetPythonType(instance), value); }
/// <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 )); }