PyDict_Check() static private method

static private PyDict_Check ( IntPtr ob ) : bool
ob IntPtr
return bool
示例#1
0
        /// <summary>
        /// Creates a new managed type derived from a base type with any virtual
        /// methods overridden to call out to python if the associated python
        /// object has overridden the method.
        /// </summary>
        internal static Type CreateDerivedType(string name,
                                               Type baseType,
                                               BorrowedReference dictRef,
                                               string namespaceStr,
                                               string assemblyName,
                                               string moduleName = "Python.Runtime.Dynamic.dll")
        {
            // TODO: clean up
            IntPtr py_dict = dictRef.DangerousGetAddress();

            if (null != namespaceStr)
            {
                name = namespaceStr + "." + name;
            }

            if (null == assemblyName)
            {
                assemblyName = "Python.Runtime.Dynamic";
            }

            ModuleBuilder moduleBuilder = GetModuleBuilder(assemblyName, moduleName);

            Type baseClass  = baseType;
            var  interfaces = new List <Type> {
                typeof(IPythonDerivedType)
            };

            // if the base type is an interface then use System.Object as the base class
            // and add the base type to the list of interfaces this new class will implement.
            if (baseType.IsInterface)
            {
                interfaces.Add(baseType);
                baseClass = typeof(object);
            }

            TypeBuilder typeBuilder = moduleBuilder.DefineType(name,
                                                               TypeAttributes.Public | TypeAttributes.Class,
                                                               baseClass,
                                                               interfaces.ToArray());

            // add a field for storing the python object pointer
            // FIXME: fb not used
            FieldBuilder fb = typeBuilder.DefineField("__pyobj__", typeof(CLRObject), FieldAttributes.Public);

            // override any constructors
            ConstructorInfo[] constructors = baseClass.GetConstructors();
            foreach (ConstructorInfo ctor in constructors)
            {
                AddConstructor(ctor, baseType, typeBuilder);
            }

            // Override any properties explicitly overridden in python
            var pyProperties = new HashSet <string>();

            if (py_dict != IntPtr.Zero && Runtime.PyDict_Check(py_dict))
            {
                Runtime.XIncref(py_dict);
                using (var dict = new PyDict(py_dict))
                    using (PyObject keys = dict.Keys())
                    {
                        foreach (PyObject pyKey in keys)
                        {
                            using (PyObject value = dict[pyKey])
                            {
                                if (value.HasAttr("_clr_property_type_"))
                                {
                                    string propertyName = pyKey.ToString();
                                    pyProperties.Add(propertyName);

                                    // Add the property to the type
                                    AddPythonProperty(propertyName, value, typeBuilder);
                                }
                            }
                        }
                    }
            }

            // override any virtual methods not already overridden by the properties above
            MethodInfo[] methods        = baseType.GetMethods();
            var          virtualMethods = new HashSet <string>();

            foreach (MethodInfo method in methods)
            {
                if (!method.Attributes.HasFlag(MethodAttributes.Virtual) |
                    method.Attributes.HasFlag(MethodAttributes.Final))
                {
                    continue;
                }

                // skip if this property has already been overridden
                if ((method.Name.StartsWith("get_") || method.Name.StartsWith("set_")) &&
                    pyProperties.Contains(method.Name.Substring(4)))
                {
                    continue;
                }

                // keep track of the virtual methods redirected to the python instance
                virtualMethods.Add(method.Name);

                // override the virtual method to call out to the python method, if there is one.
                AddVirtualMethod(method, baseType, typeBuilder);
            }

            // Add any additional methods and properties explicitly exposed from Python.
            if (py_dict != IntPtr.Zero && Runtime.PyDict_Check(py_dict))
            {
                Runtime.XIncref(py_dict);
                using (var dict = new PyDict(py_dict))
                    using (PyObject keys = dict.Keys())
                    {
                        foreach (PyObject pyKey in keys)
                        {
                            using (PyObject value = dict[pyKey])
                            {
                                if (value.HasAttr("_clr_return_type_") && value.HasAttr("_clr_arg_types_"))
                                {
                                    string methodName = pyKey.ToString();

                                    // if this method has already been redirected to the python method skip it
                                    if (virtualMethods.Contains(methodName))
                                    {
                                        continue;
                                    }

                                    // Add the method to the type
                                    AddPythonMethod(methodName, value, typeBuilder);
                                }
                            }
                        }
                    }
            }

            // add the destructor so the python object created in the constructor gets destroyed
            MethodBuilder methodBuilder = typeBuilder.DefineMethod("Finalize",
                                                                   MethodAttributes.Family |
                                                                   MethodAttributes.Virtual |
                                                                   MethodAttributes.HideBySig,
                                                                   CallingConventions.Standard,
                                                                   typeof(void),
                                                                   Type.EmptyTypes);
            ILGenerator il = methodBuilder.GetILGenerator();

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Call, typeof(PythonDerivedType).GetMethod("Finalize"));
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Call, baseClass.GetMethod("Finalize", BindingFlags.NonPublic | BindingFlags.Instance));
            il.Emit(OpCodes.Ret);

            Type type = typeBuilder.CreateType();

            // scan the assembly so the newly added class can be imported
            Assembly assembly = Assembly.GetAssembly(type);

            AssemblyManager.ScanAssembly(assembly);

            // FIXME: assemblyBuilder not used
            AssemblyBuilder assemblyBuilder = assemblyBuilders[assemblyName];

            return(type);
        }
示例#2
0
 /// <summary>
 /// IsDictType Method
 /// </summary>
 ///
 /// <remarks>
 /// Returns true if the given object is a Python dictionary.
 /// </remarks>
 public static bool IsDictType(PyObject value)
 {
     return(Runtime.PyDict_Check(value.obj));
 }