Esempio n. 1
0
        /// <summary>
        /// For the operator methods of a CLR type, set the special slots of the
        /// corresponding Python type's operator methods.
        /// </summary>
        public static void FixupSlots(BorrowedReference pyType, Type clrType)
        {
            Debug.Assert(_opType != null);

            var operatorCandidates = GetOperatorCandidates(clrType);

            foreach (var method in operatorCandidates)
            {
                // We only want to override slots for operators excluding
                // comparison operators, which are handled by ClassBase.tp_richcompare.
                if (!OpMethodMap.ContainsKey(method.Name))
                {
                    continue;
                }
                int offset = OpMethodMap[method.Name].TypeOffset;
                // Copy the default implementation of e.g. the nb_add slot,
                // which simply calls __add__ on the type.
                IntPtr func = Util.ReadIntPtr(_opType !, offset);
                // Write the slot definition of the target Python type, so
                // that we can later modify __add___ and it will be called
                // when used with a Python operator.
                // https://tenthousandmeters.com/blog/python-behind-the-scenes-6-how-python-object-system-works/
                Util.WriteIntPtr(pyType, offset, func);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// For the operator methods of a CLR type, set the special slots of the
        /// corresponding Python type's operator methods.
        /// </summary>
        /// <param name="pyType"></param>
        /// <param name="clrType"></param>
        public static void FixupSlots(IntPtr pyType, Type clrType)
        {
            const BindingFlags flags = BindingFlags.Public | BindingFlags.Static;

            Debug.Assert(_opType != null);

            var staticMethods =
                clrType.IsEnum ? typeof(EnumOps <>).MakeGenericType(clrType).GetMethods(flags)
                : clrType.GetMethods(flags);

            foreach (var method in staticMethods)
            {
                // We only want to override slots for operators excluding
                // comparison operators, which are handled by ClassBase.tp_richcompare.
                if (!OpMethodMap.ContainsKey(method.Name))
                {
                    continue;
                }
                int offset = OpMethodMap[method.Name].TypeOffset;
                // Copy the default implementation of e.g. the nb_add slot,
                // which simply calls __add__ on the type.
                IntPtr func = Marshal.ReadIntPtr(_opType.Handle, offset);
                // Write the slot definition of the target Python type, so
                // that we can later modify __add___ and it will be called
                // when used with a Python operator.
                // https://tenthousandmeters.com/blog/python-behind-the-scenes-6-how-python-object-system-works/
                Marshal.WriteIntPtr(pyType, offset, func);
            }
        }
Esempio n. 3
0
 public static bool IsOperatorMethod(MethodBase method)
 {
     if (!method.IsSpecialName && !method.IsOpsHelper())
     {
         return(false);
     }
     return(OpMethodMap.ContainsKey(method.Name) || ComparisonOpMap.ContainsKey(method.Name));
 }
Esempio n. 4
0
 public static string GetPyMethodName(string clrName)
 {
     if (OpMethodMap.ContainsKey(clrName))
     {
         return(OpMethodMap[clrName].MethodName);
     }
     else
     {
         return(ComparisonOpMap[clrName]);
     }
 }