static PropertyDescriptor[] GetPropertiesImpl(object self, Attribute[] attributes)
        {
            IList <object>            attrNames = PythonOps.GetAttrNames(DefaultContext.DefaultCLS, self);
            List <PropertyDescriptor> descrs    = new List <PropertyDescriptor>();

            if (attrNames != null)
            {
                foreach (object o in attrNames)
                {
                    string s = o as string;
                    if (s == null)
                    {
                        continue;
                    }

                    PythonTypeSlot attrSlot;
                    PythonType     dt = DynamicHelpers.GetPythonType(self);
                    dt.TryResolveSlot(DefaultContext.DefaultCLS, s, out attrSlot);
                    object attrVal = ObjectOps.__getattribute__(DefaultContext.DefaultCLS, self, s);

                    Type attrType = (attrVal == null) ? typeof(NoneTypeOps) : attrVal.GetType();

                    if ((attrSlot != null && ShouldIncludeProperty(attrSlot, attributes)) ||
                        (attrSlot == null && ShouldIncludeInstanceMember(s, attributes)))
                    {
                        descrs.Add(new SuperDynamicObjectPropertyDescriptor(s, attrType, self.GetType()));
                    }
                }
            }

            return(descrs.ToArray());
        }
        private static bool IsBuiltinConversion(CodeContext /*!*/ context, PythonTypeSlot /*!*/ pts, string name, PythonType /*!*/ selfType)
        {
            Type baseType = selfType.UnderlyingSystemType.BaseType;
            Type tmpType  = baseType;

            do
            {
                if (tmpType.IsGenericType && tmpType.GetGenericTypeDefinition() == typeof(Extensible <>))
                {
                    baseType = tmpType.GetGenericArguments()[0];
                    break;
                }
                tmpType = tmpType.BaseType;
            } while (tmpType != null);

            PythonType     ptBase = DynamicHelpers.GetPythonTypeFromType(baseType);
            PythonTypeSlot baseSlot;

            if (ptBase.TryResolveSlot(context, name, out baseSlot) && pts == baseSlot)
            {
                return(true);
            }

            return(false);
        }
Beispiel #3
0
        internal static DynamicMetaObject ConvertToIEnumerator(DynamicMetaObjectBinder /*!*/ conversion, DynamicMetaObject /*!*/ metaUserObject)
        {
            PythonType     pt      = MetaPythonObject.GetPythonType(metaUserObject);
            PythonContext  state   = PythonContext.GetPythonContext(conversion);
            CodeContext    context = state.SharedContext;
            PythonTypeSlot pts;


            if (pt.TryResolveSlot(context, "__iter__", out pts))
            {
                ParameterExpression tmp = Ast.Parameter(typeof(object), "iterVal");

                return(new DynamicMetaObject(
                           Expression.Block(
                               new[] { tmp },
                               Expression.Call(
                                   typeof(PythonOps).GetMethod("CreatePythonEnumerator"),
                                   Ast.Block(
                                       MetaPythonObject.MakeTryGetTypeMember(
                                           state,
                                           pts,
                                           metaUserObject.Expression,
                                           tmp
                                           ),
                                       Ast.Dynamic(
                                           new PythonInvokeBinder(
                                               state,
                                               new CallSignature(0)
                                               ),
                                           typeof(object),
                                           AstUtils.Constant(context),
                                           tmp
                                           )
                                       )
                                   )
                               ),
                           metaUserObject.Restrictions
                           ));
            }
            else if (pt.TryResolveSlot(context, "__getitem__", out pts))
            {
                return(MakeGetItemIterable(metaUserObject, state, pts, "CreateItemEnumerator"));
            }

            return(null);
        }
Beispiel #4
0
        internal static DynamicMetaObject ConvertToIEnumerable(DynamicMetaObjectBinder /*!*/ conversion, DynamicMetaObject /*!*/ metaUserObject)
        {
            PythonType     pt        = MetaPythonObject.GetPythonType(metaUserObject);
            PythonContext  pyContext = PythonContext.GetPythonContext(conversion);
            CodeContext    context   = pyContext.SharedContext;
            PythonTypeSlot pts;

            if (pt.TryResolveSlot(context, "__iter__", out pts))
            {
                return(MakeIterRule(metaUserObject, "CreatePythonEnumerable"));
            }
            else if (pt.TryResolveSlot(context, "__getitem__", out pts))
            {
                return(MakeGetItemIterable(metaUserObject, pyContext, pts, "CreateItemEnumerable"));
            }

            return(null);
        }
Beispiel #5
0
        private static void AddFinalizer(CodeContext /*!*/ context, PythonType dt, object newObject)
        {
            // check if object has finalizer...
            if (dt.TryResolveSlot(context, "__del__", out _))
            {
                IWeakReferenceable iwr = context.LanguageContext.ConvertToWeakReferenceable(newObject);
                Debug.Assert(iwr != null);

                InstanceFinalizer nif = new InstanceFinalizer(context, newObject);
                iwr.SetFinalizer(new WeakRefTracker(iwr, nif, nif));
            }
        }
Beispiel #6
0
        internal static bool TryGetOperator(CodeContext context, object o, string name, out object callable)
        {
            PythonType pt = DynamicHelpers.GetPythonType(o);

            if (pt.TryResolveSlot(context, name, out PythonTypeSlot pts) &&
                pts.TryGetValue(context, o, pt, out callable))
            {
                return(true);
            }

            callable = default;
            return(false);
        }
Beispiel #7
0
        /// <summary>
        /// Determines if a type member can be imported.  This is used to treat static types like modules.
        /// </summary>
        private static bool IsStaticTypeMemberInAll(CodeContext /*!*/ context, PythonType /*!*/ pt, string name, out object res)
        {
            PythonTypeSlot pts;

            res = null;
            if (pt.TryResolveSlot(context, name, out pts))
            {
                if (name == "__doc__" || name == "__class__")
                {
                    // these exist but we don't want to clobber __doc__ on import * or bring in __class__
                    return(false);
                }
                else if (pts is ReflectedGetterSetter)
                {
                    // property or indexer, these fetch the value at runtime, the user needs to explicitly
                    // import them using from type import property
                    return(false);
                }

                ReflectedField rf = pts as ReflectedField;
                if (rf != null && !rf._info.IsInitOnly && !rf._info.IsLiteral)
                {
                    // only bring in read-only fields, if the value can change the user needs to explicitly
                    // import by name
                    return(false);
                }

                BuiltinMethodDescriptor method = pts as BuiltinMethodDescriptor;
                if (method != null && (!method.DeclaringType.IsSealed() || !method.DeclaringType.IsAbstract()))
                {
                    // inherited object member on a static class (GetHashCode, Equals, etc...)
                    return(false);
                }

                BuiltinFunction bf = pts as BuiltinFunction;
                if (bf != null && (!bf.DeclaringType.IsSealed() || !bf.DeclaringType.IsAbstract()))
                {
                    // __new__/ReferenceEquals inherited from object
                    return(false);
                }

                if (pts.TryGetValue(context, null, pt, out res))
                {
                    return(true);
                }
            }

            res = null;
            return(false);
        }
        private static object GetTypeNew(CodeContext /*!*/ context, PythonType dt)
        {
            PythonTypeSlot dts;

            if (!dt.TryResolveSlot(context, "__new__", out dts))
            {
                throw PythonOps.TypeError("cannot create instances of {0}", dt.Name);
            }

            object newInst;
            bool   res = dts.TryGetValue(context, dt, dt, out newInst);

            Debug.Assert(res);

            return(newInst);
        }
        static PropertyDescriptor[] GetPropertiesImpl(object self, Attribute[] attributes)
        {
            IList <object>            attrNames = PythonOps.GetAttrNames(DefaultContext.DefaultCLS, self);
            List <PropertyDescriptor> descrs    = new List <PropertyDescriptor>();

            if (attrNames != null)
            {
                foreach (object o in attrNames)
                {
                    if (!(o is string s))
                    {
                        continue;
                    }

                    PythonTypeSlot attrSlot = null;
                    object         attrVal;

                    if (self is OldInstance)
                    {
                        if (((OldInstance)self)._class.TryLookupSlot(s, out attrVal))
                        {
                            attrSlot = attrVal as PythonTypeSlot;
                        }
                        else if (!((OldInstance)self).Dictionary.TryGetValue(s, out attrVal))
                        {
                            attrVal = ObjectOps.__getattribute__(DefaultContext.DefaultCLS, self, s);
                        }
                    }
                    else
                    {
                        PythonType dt = DynamicHelpers.GetPythonType(self);
                        dt.TryResolveSlot(DefaultContext.DefaultCLS, s, out attrSlot);
                        attrVal = ObjectOps.__getattribute__(DefaultContext.DefaultCLS, self, s);
                    }

                    Type attrType = (attrVal == null) ? typeof(NoneTypeOps) : attrVal.GetType();

                    if ((attrSlot != null && ShouldIncludeProperty(attrSlot, attributes)) ||
                        (attrSlot == null && ShouldIncludeInstanceMember(s, attributes)))
                    {
                        descrs.Add(new SuperDynamicObjectPropertyDescriptor(s, attrType, self.GetType()));
                    }
                }
            }

            return(descrs.ToArray());
        }
Beispiel #10
0
        internal static bool TryInvokeTernaryOperator(CodeContext context, object o, object arg1, object arg2, string name, out object value)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Temporary, "TernaryOp " + CompilerHelpers.GetType(o).Name + " " + name);

            PythonTypeSlot pts;
            PythonType     pt = DynamicHelpers.GetPythonType(o);
            object         callable;

            if (pt.TryResolveSlot(context, name, out pts) &&
                pts.TryGetValue(context, o, pt, out callable))
            {
                value = PythonCalls.Call(context, callable, arg1, arg2);
                return(true);
            }

            value = null;
            return(false);
        }
Beispiel #11
0
        /// <summary>
        /// Tries to get the BuiltinFunction for the given name on the type of the provided MetaObject.
        ///
        /// Succeeds if the MetaObject is a BuiltinFunction or BuiltinMethodDescriptor.
        /// </summary>
        internal static bool TryGetStaticFunction(PythonContext /*!*/ state, string op, DynamicMetaObject /*!*/ mo, out BuiltinFunction function)
        {
            PythonType type = MetaPythonObject.GetPythonType(mo);

            function = null;
            if (!String.IsNullOrEmpty(op))
            {
                PythonTypeSlot xSlot;
                object         val;
                if (type.TryResolveSlot(state.SharedContext, op, out xSlot) &&
                    xSlot.TryGetValue(state.SharedContext, null, type, out val))
                {
                    function = TryConvertToBuiltinFunction(val);
                    if (function == null)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
        private DynamicMetaObject /*!*/ MakeConvertRuleForCall(DynamicMetaObjectBinder /*!*/ convertToAction, Type toType, DynamicMetaObject /*!*/ self, string name, string returner, Func <DynamicMetaObject> fallback, Func <Expression, Expression> resultConverter)
        {
            PythonType     pt = ((IPythonObject)self.Value).PythonType;
            PythonTypeSlot pts;
            CodeContext    context = PythonContext.GetPythonContext(convertToAction).SharedContext;
            ValidationInfo valInfo = BindingHelpers.GetValidationInfo(this, pt);

            if (pt.TryResolveSlot(context, name, out pts) && !IsBuiltinConversion(context, pts, name, pt))
            {
                ParameterExpression tmp = Ast.Variable(typeof(object), "func");

                Expression callExpr = resultConverter(
                    Ast.Call(
                        PythonOps.GetConversionHelper(returner, GetResultKind(convertToAction)),
                        Ast.Dynamic(
                            PythonContext.GetPythonContext(convertToAction).InvokeNone,
                            typeof(object),
                            PythonContext.GetCodeContext(convertToAction),
                            tmp
                            )
                        )
                    );

                if (typeof(Extensible <>).MakeGenericType(toType).IsAssignableFrom(self.GetLimitType()))
                {
                    // if we're doing a conversion to the underlying type and we're an
                    // Extensible<T> of that type:

                    // if an extensible type returns it's self in a conversion, then we need
                    // to actually return the underlying value.  If an extensible just keeps
                    // returning more instances  of it's self a stack overflow occurs - both
                    // behaviors match CPython.
                    callExpr = AstUtils.Convert(AddExtensibleSelfCheck(convertToAction, toType, self, callExpr), typeof(object));
                }

                return(BindingHelpers.AddDynamicTestAndDefer(
                           convertToAction,
                           new DynamicMetaObject(
                               Ast.Condition(
                                   MakeTryGetTypeMember(
                                       PythonContext.GetPythonContext(convertToAction),
                                       pts,
                                       self.Expression,
                                       tmp
                                       ),
                                   callExpr,
                                   AstUtils.Convert(
                                       ConversionFallback(convertToAction),
                                       typeof(object)
                                       )
                                   ),
                               self.Restrict(self.GetRuntimeType()).Restrictions
                               ),
                           new DynamicMetaObject[] { this },
                           valInfo,
                           tmp
                           ));
            }

            return(fallback());
        }
            public TResult MakeTypeGetMember()
            {
                PythonTypeSlot pts;

                bool        isFinal = false, metaOnly = false;
                CodeContext lookupContext = _context.LanguageContext.SharedClsContext;

                // first look in the meta-class to see if we have a get/set descriptor
                PythonType metaType = DynamicHelpers.GetPythonType(Value);

                foreach (PythonType pt in metaType.ResolutionOrder)
                {
                    if (pt.TryLookupSlot(lookupContext, _name, out pts) && pts.IsSetDescriptor(lookupContext, metaType))
                    {
                        if (AddMetaSlotAccess(metaType, pts))
                        {
                            metaOnly = isFinal = true;
                            break;
                        }
                    }
                }

                if (!isFinal)
                {
                    // then search the MRO to see if we have the value
                    foreach (PythonType pt in Value.ResolutionOrder)
                    {
                        if (pt.IsOldClass)
                        {
                            // mixed new-style/old-style class, search the one slot in it's MRO for the member
                            AddOldClassAccess(pt);
                        }
                        else if (pt.TryLookupSlot(lookupContext, _name, out pts))
                        {
                            if (AddSlotAccess(pt, pts))
                            {
                                isFinal = true;
                                break;
                            }
                        }
                    }
                }

                if (!isFinal)
                {
                    // then go back to the meta class to see if we have a normal attribute
                    foreach (PythonType pt in metaType.ResolutionOrder)
                    {
                        if (pt.OldClass != null)
                        {
                            // mixed new-style/old-style class, just call our version of __getattribute__
                            // and let it sort it out at runtime.
                            AddMetaOldClassAccess();
                            isFinal = true;
                            break;
                        }
                        else if (pt.TryLookupSlot(lookupContext, _name, out pts))
                        {
                            if (AddMetaSlotAccess(metaType, pts))
                            {
                                isFinal = true;
                                break;
                            }
                        }
                    }
                }

                if (!isFinal)
                {
                    // the member doesn't exist anywhere in the type hierarchy, see if
                    // we define __getattr__ on our meta type.
                    if (metaType.TryResolveSlot(_context, "__getattr__", out pts) &&
                        !pts.IsSetDescriptor(lookupContext, metaType))   // we tried get/set descriptors initially

                    {
                        AddMetaGetAttribute(metaType, pts);
                        isFinal = pts.GetAlwaysSucceeds;
                    }
                }

                if (!isFinal)
                {
                    AddError();
                }

                return(Finish(metaOnly));
            }
Beispiel #14
0
        internal static DynamicMetaObject Call(DynamicMetaObjectBinder /*!*/ call, DynamicMetaObject target, DynamicMetaObject /*!*/[] /*!*/ args)
        {
            Assert.NotNull(call, args);
            Assert.NotNullItems(args);

            if (target.NeedsDeferral())
            {
                return(call.Defer(ArrayUtils.Insert(target, args)));
            }

            foreach (DynamicMetaObject mo in args)
            {
                if (mo.NeedsDeferral())
                {
                    RestrictTypes(args);

                    return(call.Defer(
                               ArrayUtils.Insert(target, args)
                               ));
                }
            }

            DynamicMetaObject self = target.Restrict(target.GetLimitType());

            ValidationInfo valInfo   = BindingHelpers.GetValidationInfo(target);
            PythonType     pt        = DynamicHelpers.GetPythonType(target.Value);
            PythonContext  pyContext = PythonContext.GetPythonContext(call);

            // look for __call__, if it's present dispatch to it.  Otherwise fall back to the
            // default binder
            PythonTypeSlot callSlot;

            if (!typeof(Delegate).IsAssignableFrom(target.GetLimitType()) &&
                pt.TryResolveSlot(pyContext.SharedContext, "__call__", out callSlot))
            {
                ConditionalBuilder cb = new ConditionalBuilder(call);

                callSlot.MakeGetExpression(
                    pyContext.Binder,
                    PythonContext.GetCodeContext(call),
                    self,
                    GetPythonType(self),
                    cb
                    );

                if (!cb.IsFinal)
                {
                    cb.FinishCondition(GetCallError(call, self));
                }

                Expression[] callArgs = ArrayUtils.Insert(
                    PythonContext.GetCodeContext(call),
                    cb.GetMetaObject().Expression,
                    DynamicUtils.GetExpressions(args)
                    );

                Expression body = DynamicExpression.Dynamic(
                    PythonContext.GetPythonContext(call).Invoke(
                        BindingHelpers.GetCallSignature(call)
                        ),
                    typeof(object),
                    callArgs
                    );

                body = Ast.TryFinally(
                    Ast.Block(
                        Ast.Call(typeof(PythonOps).GetMethod(nameof(PythonOps.FunctionPushFrame)), Ast.Constant(pyContext)),
                        body
                        ),
                    Ast.Call(typeof(PythonOps).GetMethod(nameof(PythonOps.FunctionPopFrame)))
                    );

                return(BindingHelpers.AddDynamicTestAndDefer(
                           call,
                           new DynamicMetaObject(body, self.Restrictions.Merge(BindingRestrictions.Combine(args))),
                           args,
                           valInfo
                           ));
            }

            return(null);
        }
Beispiel #15
0
            public TResult MakeTypeGetMember()
            {
                PythonTypeSlot pts;

                bool        isFinal = false, metaOnly = false;
                CodeContext lookupContext = PythonContext.GetContext(_context).SharedClsContext;

                // first look in the meta-class to see if we have a get/set descriptor
                PythonType metaType = DynamicHelpers.GetPythonType(Value);

                foreach (PythonType pt in metaType.ResolutionOrder)
                {
                    if (pt.TryLookupSlot(lookupContext, _name, out pts) && pts.IsSetDescriptor(lookupContext, metaType))
                    {
                        if (AddMetaSlotAccess(metaType, pts))
                        {
                            metaOnly = isFinal = true;
                            break;
                        }
                    }
                }

                if (!isFinal)
                {
                    // then search the MRO to see if we have the value
                    foreach (PythonType pt in Value.ResolutionOrder)
                    {
                        if (pt.TryLookupSlot(lookupContext, _name, out pts))
                        {
                            if (AddSlotAccess(pt, pts))
                            {
                                isFinal = true;
                                break;
                            }
                        }
                    }
                }

                if (!isFinal)
                {
                    // then go back to the meta class to see if we have a normal attribute
                    foreach (PythonType pt in metaType.ResolutionOrder)
                    {
                        if (pt.TryLookupSlot(lookupContext, _name, out pts))
                        {
                            if (AddMetaSlotAccess(metaType, pts))
                            {
                                isFinal = true;
                                break;
                            }
                        }
                    }
                }

                if (!isFinal)
                {
                    // the member doesn't exist anywhere in the type hierarchy, see if
                    // we define __getattr__ on our meta type.
                    if (metaType.TryResolveSlot(_context, "__getattr__", out pts) &&
                        !pts.IsSetDescriptor(lookupContext, metaType))   // we tried get/set descriptors initially

                    {
                        AddMetaGetAttribute(metaType, pts);
                        isFinal = pts.GetAlwaysSucceeds;
                    }
                }

                if (!isFinal)
                {
                    AddError();
                }

                return(Finish(metaOnly));
            }