public static void RemoveDictionaryValue(IPythonObject self, SymbolId name) { IAttributesCollection dict = self.Dict; if (dict != null) { if (dict.Remove(name)) { return; } } throw PythonOps.AttributeErrorForMissingAttribute(self.PythonType, name); }
internal static IAttributesCollection GetDictionary(IPythonObject self) { IAttributesCollection dict = self.Dict; if (dict == null) { dict = self.SetDict(PythonDictionary.MakeSymbolDictionary()); } return dict; }
private readonly DynamicMetaObject _baseMetaObject; // if we're a subtype of MetaObject this is the base class MO public MetaUserObject(Expression/*!*/ expression, BindingRestrictions/*!*/ restrictions, DynamicMetaObject baseMetaObject, IPythonObject value) : base(expression, restrictions, value) { _baseMetaObject = baseMetaObject; }
public static object SetDictionaryValue(IPythonObject self, SymbolId name, object value) { IAttributesCollection dict = GetDictionary(self); return dict[name] = value; }
private static void MakeDeleteAttrTarget(DeleteBindingInfo/*!*/ info, IPythonObject self, PythonTypeSlot dts) { ParameterExpression tmp = Ast.Variable(typeof(object), "boundVal"); info.Body.AddVariable(tmp); // call __delattr__ info.Body.AddCondition( Ast.Call( TypeInfo._PythonOps.SlotTryGetBoundValue, Ast.Constant(BinderState.GetBinderState(info.Action).Context), AstUtils.Convert(AstUtils.WeakConstant(dts), typeof(PythonTypeSlot)), AstUtils.Convert(info.Args[0].Expression, typeof(object)), AstUtils.Convert(AstUtils.WeakConstant(self.PythonType), typeof(PythonType)), tmp ), Ast.Dynamic( new PythonInvokeBinder( BinderState.GetBinderState(info.Action), new CallSignature(1) ), typeof(object), BinderState.GetCodeContext(info.Action), tmp, Ast.Constant(info.Action.Name) ) ); }
public UserTypeDebugView(IPythonObject userObject) { _userObject = userObject; }
public static object SetDictionaryValue(IPythonObject self, string name, object value) { PythonDictionary dict = GetDictionary(self); return(dict[name] = value); }
/// <summary> /// Makes a rule which calls a user-defined __getattribute__ function and falls back to __getattr__ if that /// raises an AttributeError. /// /// slot is the __getattribute__ method to be called. /// </summary> private DynamicMetaObject/*!*/ MakeGetAttributeRule(GetBindingInfo/*!*/ info, IPythonObject/*!*/ obj, PythonTypeSlot/*!*/ slot, Expression codeContext) { // if the type implements IDynamicObject and we picked up it's __getattribute__ then we want to just // dispatch to the base meta object (or to the default binder). an example of this is: // // class mc(type): // def __getattr__(self, name): // return 42 // // class nc_ga(object): // __metaclass__ = mc // // a = nc_ga.x # here we want to dispatch to the type's rule, not call __getattribute__ directly. CodeContext context = BinderState.GetBinderState(info.Action).Context; Type finalType = PythonTypeOps.GetFinalSystemType(obj.PythonType.UnderlyingSystemType); if (typeof(IDynamicObject).IsAssignableFrom(finalType)) { PythonTypeSlot baseSlot; if (TryGetGetAttribute(context, DynamicHelpers.GetPythonTypeFromType(finalType), out baseSlot) && baseSlot == slot) { return Fallback(info.Action, codeContext); } } // otherwise generate code into a helper function. This will do the slot lookup and exception // handling for both __getattribute__ as well as __getattr__ if it exists. PythonTypeSlot getattr; obj.PythonType.TryResolveSlot(context, Symbols.GetBoundAttr, out getattr); DynamicMetaObject self = Restrict(Value.GetType()); string methodName = BindingHelpers.IsNoThrow(info.Action) ? "GetAttributeNoThrow" : "GetAttribute"; return BindingHelpers.AddDynamicTestAndDefer( info.Action, new DynamicMetaObject( Ast.Call( typeof(UserTypeOps).GetMethod(methodName), Ast.Constant(BinderState.GetBinderState(info.Action).Context), info.Args[0].Expression, Ast.Constant(GetGetMemberName(info.Action)), Ast.Constant(slot, typeof(PythonTypeSlot)), Ast.Constant(getattr, typeof(PythonTypeSlot)), Ast.Constant(new SiteLocalStorage<CallSite<Func<CallSite, CodeContext, object, string, object>>>()) ), self.Restrictions ), info.Args, info.Validation ); }
private readonly DynamicMetaObject _baseMetaObject; // if we're a subtype of MetaObject this is the base class MO public MetaUserObject(Expression /*!*/ expression, BindingRestrictions /*!*/ restrictions, DynamicMetaObject baseMetaObject, IPythonObject value) : base(expression, restrictions, value) { _baseMetaObject = baseMetaObject; }
public static DynamicMetaObject /*!*/ GetMetaObjectHelper(IPythonObject self, Expression /*!*/ parameter, DynamicMetaObject baseMetaObject) { return(new Binding.MetaUserObject(parameter, BindingRestrictions.Empty, baseMetaObject, self)); }
public override T BindDelegate <T>(CallSite <T> site, object[] args) { Debug.Assert(args[1].GetType() == typeof(CodeContext)); IFastGettable fastGet = args[0] as IFastGettable; if (fastGet != null) { T res = fastGet.MakeGetBinding <T>(site, this, (CodeContext)args[1], Name); if (res != null) { PerfTrack.NoteEvent(PerfTrack.Categories.BindingFast, "IFastGettable"); return(res); } PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "IFastGettable"); return(base.BindDelegate <T>(site, args)); } IPythonObject pyObj = args[0] as IPythonObject; if (pyObj != null && !(args[0] is IProxyObject)) { FastBindResult <T> res = UserTypeOps.MakeGetBinding <T>((CodeContext)args[1], site, pyObj, this); if (res.Target != null) { PerfTrack.NoteEvent(PerfTrack.Categories.BindingFast, "IPythonObject"); if (res.ShouldCache) { CacheTarget(res.Target); } return(res.Target); } PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "IPythonObject Get"); return(base.BindDelegate <T>(site, args)); } if (args[0] != null) { if (args[0].GetType() == typeof(PythonModule)) { if (SupportsLightThrow) { return((T)(object)new Func <CallSite, object, CodeContext, object>(new PythonModuleDelegate(_name).LightThrowTarget)); } else if (!IsNoThrow) { return((T)(object)new Func <CallSite, object, CodeContext, object>(new PythonModuleDelegate(_name).Target)); } else { return((T)(object)new Func <CallSite, object, CodeContext, object>(new PythonModuleDelegate(_name).NoThrowTarget)); } } else if (args[0].GetType() == typeof(NamespaceTracker)) { switch (Name) { case "__str__": case "__repr__": case "__doc__": // need to return the built in method descriptor for these... break; case "__file__": return((T)(object)new Func <CallSite, object, CodeContext, object>(new NamespaceTrackerDelegate(_name).GetFile)); case "__dict__": return((T)(object)new Func <CallSite, object, CodeContext, object>(new NamespaceTrackerDelegate(_name).GetDict)); case "__name__": return((T)(object)new Func <CallSite, object, CodeContext, object>(new NamespaceTrackerDelegate(_name).GetName)); default: if (IsNoThrow) { return((T)(object)new Func <CallSite, object, CodeContext, object>(new NamespaceTrackerDelegate(_name).NoThrowTarget)); } else { return((T)(object)new Func <CallSite, object, CodeContext, object>(new NamespaceTrackerDelegate(_name).Target)); } } } } if (args[0] != null && #if FEATURE_COM !Microsoft.Scripting.ComInterop.ComBinder.IsComObject(args[0]) && #endif !(args[0] is IDynamicMetaObjectProvider)) { Type selfType = typeof(T).GetMethod("Invoke").GetParameters()[1].ParameterType; CodeContext context = (CodeContext)args[1]; T res = null; if (selfType == typeof(object)) { res = (T)(object)MakeGetMemberTarget <object>(Name, args[0], context); } else if (selfType == typeof(List)) { res = (T)(object)MakeGetMemberTarget <List>(Name, args[0], context); } else if (selfType == typeof(string)) { res = (T)(object)MakeGetMemberTarget <string>(Name, args[0], context); } if (res != null) { return((T)(object)res); } return(base.BindDelegate <T>(site, args)); } PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "GetNoFast " + IsNoThrow + " " + CompilerHelpers.GetType(args[0])); return(this.LightBind <T>(args, this.Context.Options.CompilationThreshold)); }
public override ICollection <MemberDoc> GetMembers(object value) { List <MemberDoc> res = new List <MemberDoc>(); PythonModule mod = value as PythonModule; if (mod != null) { foreach (var kvp in mod.__dict__) { AddMember(res, kvp, false); } return(res); } NamespaceTracker ns = value as NamespaceTracker; if (ns != null) { foreach (var v in ns) { AddMember( res, new KeyValuePair <object, object>( v.Key, Importer.MemberTrackerToPython(_context.SharedClsContext, v.Value) ), false ); } } else { PythonType pt = value as PythonType; if (pt != null) { foreach (PythonType type in pt.ResolutionOrder) { foreach (var member in type.GetMemberDictionary(_context.SharedContext)) { AddMember(res, member, true); } } } else { pt = DynamicHelpers.GetPythonType(value); foreach (var member in pt.GetMemberDictionary(_context.SharedContext)) { AddMember(res, member, true); } } IPythonObject ipo = value as IPythonObject; if (ipo != null && ipo.Dict != null) { foreach (var member in ipo.Dict) { AddMember(res, member, false); } } } return(res.ToArray()); }
/// <summary> /// Implements the default __reduce_ex__ method as specified by PEP 307 case 3 (new-style instance, protocol 2) /// </summary> private static PythonTuple ReduceProtocol2(CodeContext /*!*/ context, object self) { PythonType myType = DynamicHelpers.GetPythonType(self); object func, state, listIterator, dictIterator; object[] funcArgs; func = context.LanguageContext.NewObject; object getNewArgsCallable; if (PythonOps.TryGetBoundAttr(context, myType, "__getnewargs__", out getNewArgsCallable)) { // TypeError will bubble up if __getnewargs__ isn't callable PythonTuple newArgs = PythonOps.CallWithContext(context, getNewArgsCallable, self) as PythonTuple; if (newArgs == null) { throw PythonOps.TypeError("__getnewargs__ should return a tuple"); } funcArgs = new object[1 + newArgs.Count]; funcArgs[0] = myType; for (int i = 0; i < newArgs.Count; i++) { funcArgs[i + 1] = newArgs[i]; } } else { funcArgs = new object[] { myType }; } if (!PythonTypeOps.TryInvokeUnaryOperator(context, self, "__getstate__", out state)) { object dict; IPythonObject ipo = self as IPythonObject; if (ipo != null) { dict = ipo.Dict; } else if (!PythonOps.TryGetBoundAttr(context, self, "__dict__", out dict)) { dict = null; } PythonDictionary initializedSlotValues = GetInitializedSlotValues(self); if (initializedSlotValues != null && initializedSlotValues.Count == 0) { initializedSlotValues = null; } if (dict == null && initializedSlotValues == null) { state = null; } else if (dict != null && initializedSlotValues == null) { state = dict; } else if (dict != null && initializedSlotValues != null) { state = PythonTuple.MakeTuple(dict, initializedSlotValues); } else /*dict == null && initializedSlotValues != null*/ state {
/// <summary> /// Object.ToString() displays the CLI type name. But we want to display the class name (e.g. /// '<foo object at 0x000000000000002C>' unless we've overridden __repr__ but not __str__ in /// which case we'll display the result of __repr__. /// </summary> public static string ToStringHelper(IPythonObject o) { return ObjectOps.__str__(DefaultContext.Default, o); }
/// <summary> /// Object.ToString() displays the CLI type name. But we want to display the class name (e.g. /// '<foo object at 0x000000000000002C>' unless we've overridden __repr__ but not __str__ in /// which case we'll display the result of __repr__. /// </summary> public static string ToStringHelper(IPythonObject o) { return(ObjectOps.__str__(DefaultContext.Default, o)); }
public static DynamicMetaObject/*!*/ GetMetaObjectHelper(IPythonObject self, Expression/*!*/ parameter, DynamicMetaObject baseMetaObject) { return new Binding.MetaUserObject(parameter, BindingRestrictions.Empty, baseMetaObject, self); }
internal static Binding.FastBindResult <T> MakeGetBinding <T>(CodeContext codeContext, CallSite <T> site, IPythonObject self, Binding.PythonGetMemberBinder getBinder) where T : class { Type finalType = PythonTypeOps.GetFinalSystemType(self.PythonType.UnderlyingSystemType); if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(finalType) && !(self is IFastGettable)) { // very tricky, user is inheriting from a class which implements IDO, we // don't optimize this yet. return(new Binding.FastBindResult <T>()); } return((Binding.FastBindResult <T>)(object) new Binding.MetaUserObject.FastGetBinderHelper( codeContext, (CallSite <Func <CallSite, object, CodeContext, object> >)(object) site, self, getBinder).GetBinding(codeContext, getBinder.Name)); }
private void MakeSetAttrTarget(SetBindingInfo bindingInfo, IPythonObject sdo, PythonTypeSlot dts) { ParameterExpression tmp = Ast.Variable(typeof(object), "boundVal"); bindingInfo.Body.AddVariable(tmp); bindingInfo.Body.AddCondition( Ast.Call( typeof(PythonOps).GetMethod("SlotTryGetValue"), Ast.Constant(BinderState.GetBinderState(bindingInfo.Action).Context), AstUtils.Convert(AstUtils.WeakConstant(dts), typeof(PythonTypeSlot)), AstUtils.Convert(bindingInfo.Args[0].Expression, typeof(object)), AstUtils.Convert(AstUtils.WeakConstant(sdo.PythonType), typeof(PythonType)), tmp ), Ast.Dynamic( new PythonInvokeBinder( BinderState.GetBinderState(bindingInfo.Action), new CallSignature(2) ), typeof(object), BinderState.GetCodeContext(bindingInfo.Action), tmp, Ast.Constant(bindingInfo.Action.Name), bindingInfo.Args[1].Expression ) ); bindingInfo.Body.FinishCondition( FallbackSetError(bindingInfo.Action, bindingInfo.Args[1]).Expression ); }
internal static FastBindResult <T> MakeSetBinding <T>(CodeContext codeContext, CallSite <T> site, IPythonObject self, object value, Binding.PythonSetMemberBinder setBinder) where T : class { if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(self.GetType().BaseType)) { // very tricky, user is inheriting from a class which implements IDO, we // don't optimize this yet. return(new FastBindResult <T>()); } // optimized versions for possible literals that can show up in code. Type setType = typeof(T); if (setType == typeof(Func <CallSite, object, object, object>)) { return((FastBindResult <T>)(object) new Binding.MetaUserObject.FastSetBinderHelper <object>( codeContext, self, value, setBinder).MakeSet()); } else if (setType == typeof(Func <CallSite, object, string, object>)) { return((FastBindResult <T>)(object) new Binding.MetaUserObject.FastSetBinderHelper <string>( codeContext, self, value, setBinder).MakeSet()); } else if (setType == typeof(Func <CallSite, object, int, object>)) { return((FastBindResult <T>)(object) new Binding.MetaUserObject.FastSetBinderHelper <int>( codeContext, self, value, setBinder).MakeSet()); } else if (setType == typeof(Func <CallSite, object, double, object>)) { return((FastBindResult <T>)(object) new Binding.MetaUserObject.FastSetBinderHelper <double>( codeContext, self, value, setBinder).MakeSet()); } else if (setType == typeof(Func <CallSite, object, List, object>)) { return((FastBindResult <T>)(object) new Binding.MetaUserObject.FastSetBinderHelper <List>( codeContext, self, value, setBinder).MakeSet()); } else if (setType == typeof(Func <CallSite, object, PythonTuple, object>)) { return((FastBindResult <T>)(object) new Binding.MetaUserObject.FastSetBinderHelper <PythonTuple>( codeContext, self, value, setBinder).MakeSet()); } else if (setType == typeof(Func <CallSite, object, PythonDictionary, object>)) { return((FastBindResult <T>)(object) new Binding.MetaUserObject.FastSetBinderHelper <PythonDictionary>( codeContext, self, value, setBinder).MakeSet()); } return(new FastBindResult <T>()); }
/// <summary> /// Looks up the associated PythonTypeSlot from the object. Indicates if the result /// came from a standard .NET type in which case we will fallback to the sites binder. /// </summary> private PythonTypeSlot FindSlot(CodeContext/*!*/ context, string/*!*/ name, IPythonObject/*!*/ sdo, out bool isOldStyle, out bool systemTypeResolution) { PythonTypeSlot foundSlot = null; isOldStyle = false; // if we're mixed new-style/old-style we have to do a slower check systemTypeResolution = false; // if we pick up the property from a System type we fallback SymbolId lookingFor = SymbolTable.StringToId(name); foreach (PythonType pt in sdo.PythonType.ResolutionOrder) { if (pt.IsOldClass) { isOldStyle = true; } if (pt.TryLookupSlot(context, lookingFor, out foundSlot)) { // use our built-in binding for ClassMethodDescriptors rather than falling back if (!(foundSlot is ClassMethodDescriptor)) { systemTypeResolution = pt.IsSystemType; } break; } } return foundSlot; }
public static double log10(IPythonObject value) { // CPython tries float first, then double, so we need // an explicit overload which properly matches the order here double val; if (Converter.TryConvertToDouble(value, out val)) { return log10(val); } else { return log10(Converter.ConvertToBigInteger(value)); } }