Represents a generic Python object. The methods of this class are generally equivalent to the Python "abstract object API". See http://www.python.org/doc/current/api/object.html for details.
상속: System.Dynamic.DynamicObject, IDisposable
예제 #1
0
    public PythonException() : base()
    {
        IntPtr gs = PythonEngine.AcquireLock();
        Runtime.PyErr_Fetch(ref _pyType, ref _pyValue, ref _pyTB);
        Runtime.Incref(_pyType);
        Runtime.Incref(_pyValue);
        Runtime.Incref(_pyTB);
        if ((_pyType != IntPtr.Zero) && (_pyValue != IntPtr.Zero))
        {
            string type;
            string message;
            Runtime.Incref(_pyType);
            using (PyObject pyType = new PyObject(_pyType))
            using (PyObject pyTypeName = pyType.GetAttr("__name__"))
            {
                    type = pyTypeName.ToString();
            }

            Runtime.Incref(_pyValue);
            using (PyObject pyValue = new PyObject(_pyValue)) 
            {
                message = pyValue.ToString(); 
            }
            _message = type + " : " + message;
        }
        if (_pyTB != IntPtr.Zero)
        {
            PyObject tb_module = PythonEngine.ImportModule("traceback");
            Runtime.Incref(_pyTB);
            using (PyObject pyTB = new PyObject(_pyTB)) {
                _tb = tb_module.InvokeMethod("format_tb", pyTB).ToString();
            }
        }
        PythonEngine.ReleaseLock(gs);
    }
예제 #2
0
파일: pydict.cs 프로젝트: JackHang/Wox
        /// <summary>
        /// PyDict Constructor
        /// </summary>
        ///
        /// <remarks>
        /// Copy constructor - obtain a PyDict from a generic PyObject. An 
        /// ArgumentException will be thrown if the given object is not a
        /// Python dictionary object.
        /// </remarks>

        public PyDict(PyObject o) : base() {
            if (!IsDictType(o)) {
                throw new ArgumentException("object is not a dict");
            }
            Runtime.Incref(o.obj);
            obj = o.obj;
        }
예제 #3
0
파일: pylong.cs 프로젝트: JackHang/Wox
        /// <summary>
        /// PyLong Constructor
        /// </summary>
        ///
        /// <remarks>
        /// Copy constructor - obtain a PyLong from a generic PyObject. An 
        /// ArgumentException will be thrown if the given object is not a
        /// Python long object.
        /// </remarks>

        public PyLong(PyObject o) : base() {
            if (!IsLongType(o)) {
                throw new ArgumentException("object is not a long");
            }
            Runtime.Incref(o.obj);
            obj = o.obj;
        }
예제 #4
0
파일: pytuple.cs 프로젝트: JackHang/Wox
        /// <summary>
        /// PyTuple Constructor
        /// </summary>
        ///
        /// <remarks>
        /// Copy constructor - obtain a PyTuple from a generic PyObject. An 
        /// ArgumentException will be thrown if the given object is not a
        /// Python tuple object.
        /// </remarks>

        public PyTuple(PyObject o) : base() {
            if (!IsTupleType(o)) {
                throw new ArgumentException("object is not a tuple");
            }
            Runtime.Incref(o.obj);
            obj = o.obj;
        }
예제 #5
0
 /// <summary>
 /// Contains Method
 /// </summary>
 ///
 /// <remarks>
 /// Return true if the sequence contains the given item. This method
 /// throws a PythonException if an error occurs during the check.
 /// </remarks>
 public bool Contains(PyObject item)
 {
     int r = Runtime.PySequence_Contains(obj, item.obj);
     if (r < 0) {
         throw new PythonException();
     }
     return (r != 0);
 }
예제 #6
0
 /// <summary>
 /// SetSlice Method
 /// </summary>
 ///
 /// <remarks>
 /// Sets the slice of the sequence with the given indices.
 /// </remarks>
 public void SetSlice(int i1, int i2, PyObject v)
 {
     int r = Runtime.PySequence_SetSlice(obj, i1, i2, v.obj);
     if (r < 0)
     {
         throw new PythonException();
     }
 }
예제 #7
0
 /// <summary>
 /// Concat Method
 /// </summary>
 ///
 /// <remarks>
 /// Return the concatenation of the sequence object with the passed in 
 /// sequence object.
 /// </remarks>
 public PyObject Concat(PyObject other)
 {
     IntPtr op = Runtime.PySequence_Concat(obj, other.obj);
     if (op == IntPtr.Zero) {
         throw new PythonException();
     }
     return new PyObject(op);
 }
예제 #8
0
파일: pyint.cs 프로젝트: fdanny/pythonnet
 /// <summary>
 /// PyInt Constructor
 /// </summary>
 ///
 /// <remarks>
 /// Copy constructor - obtain a PyInt from a generic PyObject. An
 /// ArgumentException will be thrown if the given object is not a
 /// Python int object.
 /// </remarks>
 public PyInt(PyObject o)
     : base()
 {
     if (!IsIntType(o))
     {
         throw new ArgumentException("object is not an int");
     }
     Runtime.XIncref(o.obj);
     obj = o.obj;
 }
예제 #9
0
 /// <summary>
 /// PyString Constructor
 /// </summary>
 ///
 /// <remarks>
 /// Copy constructor - obtain a PyAnsiString from a generic PyObject.
 /// An ArgumentException will be thrown if the given object is not
 /// a Python string object.
 /// </remarks>
 public PyAnsiString(PyObject o)
     : base()
 {
     if (!IsStringType(o))
     {
         throw new ArgumentException("object is not a string");
     }
     Runtime.XIncref(o.obj);
     obj = o.obj;
 }
예제 #10
0
파일: pytuple.cs 프로젝트: JackHang/Wox
        /// <summary>
        /// PyTuple Constructor
        /// </summary>
        ///
        /// <remarks>
        /// Creates a new PyTuple from an array of PyObject instances.
        /// </remarks>

        public PyTuple(PyObject[] items) : base() {
            int count = items.Length;
            obj = Runtime.PyTuple_New(count);
            for (int i = 0; i < count; i++) {
                IntPtr ptr = items[i].obj;
                Runtime.Incref(ptr);
                int r = Runtime.PyTuple_SetItem(obj, i, ptr);
                if (r < 0) {
                    throw new PythonException();
                }
            }
        }
예제 #11
0
        //===================================================================
        // Return the clr python module (new reference)
        //===================================================================
        public static IntPtr GetCLRModule(IntPtr? fromList = null)
        {
            root.InitializePreload();
            #if (PYTHON32 || PYTHON33 || PYTHON34 || PYTHON35)
            // update the module dictionary with the contents of the root dictionary
            root.LoadNames();
            IntPtr py_mod_dict = Runtime.PyModule_GetDict(py_clr_module);
            IntPtr clr_dict = Runtime._PyObject_GetDictPtr(root.pyHandle); // PyObject**
            clr_dict = (IntPtr)Marshal.PtrToStructure(clr_dict, typeof(IntPtr));
            Runtime.PyDict_Update(py_mod_dict, clr_dict);

            // find any items from the fromlist and get them from the root if they're not
            // aleady in the module dictionary
            if (fromList != null && fromList != IntPtr.Zero) {
                if (Runtime.PyTuple_Check(fromList.GetValueOrDefault()))
                {
                    Runtime.XIncref(py_mod_dict);
                    using(PyDict mod_dict = new PyDict(py_mod_dict)) {
                        Runtime.XIncref(fromList.GetValueOrDefault());
                        using (PyTuple from = new PyTuple(fromList.GetValueOrDefault())) {
                            foreach (PyObject item in from) {
                                if (mod_dict.HasKey(item))
                                    continue;

                                string s = item.AsManagedObject(typeof(string)) as string;
                                if (null == s)
                                    continue;

                                ManagedType attr = root.GetAttribute(s, true);
                                if (null == attr)
                                    continue;

                                Runtime.XIncref(attr.pyHandle);
                                using (PyObject obj = new PyObject(attr.pyHandle)) {
                                    mod_dict.SetItem(s, obj);
                                }
                            }
                        }
                    }
                }
            }

            Runtime.XIncref(py_clr_module);
            return py_clr_module;
            #else
            Runtime.XIncref(root.pyHandle);
            return root.pyHandle;
            #endif
        }
예제 #12
0
	// This method calls back into the CPython runtime - tests
	// call this from Python to check that we don't hang on 
	// nested transitions from managed to Python code and back.

	public static string CallEchoString(string arg) {
	    IntPtr gs = PythonEngine.AcquireLock();
	    if (module == null) {
		module = PythonEngine.ModuleFromString("tt", testmod);
	    }
	    PyObject func = module.GetAttr("echostring");
	    PyString parg = new PyString(arg);
	    PyObject temp = func.Invoke(parg);
	    string result = (string)temp.AsManagedObject(typeof(String));
	    func.Dispose();
	    parg.Dispose();
	    temp.Dispose();
	    PythonEngine.ReleaseLock(gs);
	    return result;
	}
예제 #13
0
        private void LoadScripts(string directory)
        {
            log.Info("Loading Python scripts...");

            string[] files = Directory.GetFiles(directory, "*.py");
            var sb = new StringBuilder();
            foreach (string file in files)
            {
                try
                {
                    string script = System.IO.File.ReadAllText(file);
                    sb.Append(script);
                }
                catch (Exception e)
                {
                    log.Error("Failed to load script file \"" + file + "\"", e);
                }
            }

            IntPtr ptr = PythonEngine.AcquireLock();
            module = PythonEngine.ModuleFromString("bot", sb.ToString());
            PythonEngine.ReleaseLock(ptr);
        }
예제 #14
0
        internal static IntPtr ToPython(Object value, Type type)
        {
            IntPtr result = IntPtr.Zero;

            // Null always converts to None in Python.

            if (value == null)
            {
                result = Runtime.PyNone;
                Runtime.Incref(result);
                return(result);
            }

            // it the type is a python subclass of a managed type then return the
            // underying python object rather than construct a new wrapper object.
            IPythonDerivedType pyderived = value as IPythonDerivedType;

            if (null != pyderived)
            {
                return(ClassDerivedObject.ToPython(pyderived));
            }

            // hmm - from Python, we almost never care what the declared
            // type is. we'd rather have the object bound to the actual
            // implementing class.

            type = value.GetType();

            TypeCode tc = Type.GetTypeCode(type);

            switch (tc)
            {
            case TypeCode.Object:
                result = CLRObject.GetInstHandle(value, type);

                // XXX - hack to make sure we convert new-style class based
                // managed exception instances to wrappers ;(
                if (Runtime.wrap_exceptions)
                {
                    Exception e = value as Exception;
                    if (e != null)
                    {
                        return(Exceptions.GetExceptionInstanceWrapper(result));
                    }
                }

                return(result);

            case TypeCode.String:
                return(Runtime.PyUnicode_FromString((string)value));

            case TypeCode.Int32:
                return(Runtime.PyInt_FromInt32((int)value));

            case TypeCode.Boolean:
                if ((bool)value)
                {
                    Runtime.Incref(Runtime.PyTrue);
                    return(Runtime.PyTrue);
                }
                Runtime.Incref(Runtime.PyFalse);
                return(Runtime.PyFalse);

            case TypeCode.Byte:
                return(Runtime.PyInt_FromInt32((int)((byte)value)));

            case TypeCode.Char:
                return(Runtime.PyUnicode_FromOrdinal((int)((char)value)));

            case TypeCode.Int16:
                return(Runtime.PyInt_FromInt32((int)((short)value)));

            case TypeCode.Int64:
                return(Runtime.PyLong_FromLongLong((long)value));

            case TypeCode.Single:
                // return Runtime.PyFloat_FromDouble((double)((float)value));
                string ss = ((float)value).ToString(nfi);
                IntPtr ps = Runtime.PyString_FromString(ss);
                IntPtr op = Runtime.PyFloat_FromString(ps, IntPtr.Zero);
                Runtime.Decref(ps);
                return(op);

            case TypeCode.Double:
                return(Runtime.PyFloat_FromDouble((double)value));

            case TypeCode.SByte:
                return(Runtime.PyInt_FromInt32((int)((sbyte)value)));

            case TypeCode.UInt16:
                return(Runtime.PyInt_FromInt32((int)((ushort)value)));

            case TypeCode.UInt32:
                return(Runtime.PyLong_FromUnsignedLong((uint)value));

            case TypeCode.UInt64:
                return(Runtime.PyLong_FromUnsignedLongLong((ulong)value));

            default:
                if (value is IEnumerable)
                {
                    using (var resultlist = new PyList()) {
                        foreach (object o in (IEnumerable)value)
                        {
                            using (var p = new PyObject(ToPython(o, o.GetType())))
                                resultlist.Append(p);
                        }
                        Runtime.Incref(resultlist.Handle);
                        return(resultlist.Handle);
                    }
                }
                result = CLRObject.GetInstHandle(value, type);
                return(result);
            }
        }
예제 #15
0
 public static T T <T>(PyObject obj)
 {
     return(obj.As <T>());
 }
예제 #16
0
        /// <summary>
        /// Return the clr python module (new reference)
        /// </summary>
        public static IntPtr GetCLRModule(IntPtr?fromList = null)
        {
            root.InitializePreload();

            if (Runtime.IsPython2)
            {
                Runtime.XIncref(py_clr_module);
                return(py_clr_module);
            }

            // Python 3
            // update the module dictionary with the contents of the root dictionary
            root.LoadNames();
            IntPtr py_mod_dict = Runtime.PyModule_GetDict(py_clr_module);
            IntPtr clr_dict    = Runtime._PyObject_GetDictPtr(root.pyHandle); // PyObject**

            clr_dict = (IntPtr)Marshal.PtrToStructure(clr_dict, typeof(IntPtr));
            Runtime.PyDict_Update(py_mod_dict, clr_dict);

            // find any items from the from list and get them from the root if they're not
            // already in the module dictionary
            if (fromList != null && fromList != IntPtr.Zero)
            {
                if (Runtime.PyTuple_Check(fromList.GetValueOrDefault()))
                {
                    Runtime.XIncref(py_mod_dict);
                    using (var mod_dict = new PyDict(py_mod_dict))
                    {
                        Runtime.XIncref(fromList.GetValueOrDefault());
                        using (var from = new PyTuple(fromList.GetValueOrDefault()))
                        {
                            foreach (PyObject item in from)
                            {
                                if (mod_dict.HasKey(item))
                                {
                                    continue;
                                }

                                var s = item.AsManagedObject(typeof(string)) as string;
                                if (s == null)
                                {
                                    continue;
                                }

                                ManagedType attr = root.GetAttribute(s, true);
                                if (attr == null)
                                {
                                    continue;
                                }

                                Runtime.XIncref(attr.pyHandle);
                                using (var obj = new PyObject(attr.pyHandle))
                                {
                                    mod_dict.SetItem(s, obj);
                                }
                            }
                        }
                    }
                }
            }
            Runtime.XIncref(py_clr_module);
            return(py_clr_module);
        }
예제 #17
0
        /// <summary>
        /// The actual import hook that ties Python to the managed world.
        /// </summary>
        public static IntPtr __import__(IntPtr self, IntPtr args, IntPtr kw)
        {
            // Replacement for the builtin __import__. The original import
            // hook is saved as this.py_import. This version handles CLR
            // import and defers to the normal builtin for everything else.

            var num_args = Runtime.PyTuple_Size(args);

            if (num_args < 1)
            {
                return(Exceptions.RaiseTypeError("__import__() takes at least 1 argument (0 given)"));
            }

            // borrowed reference
            IntPtr py_mod_name = Runtime.PyTuple_GetItem(args, 0);

            if (py_mod_name == IntPtr.Zero ||
                !Runtime.IsStringType(py_mod_name))
            {
                return(Exceptions.RaiseTypeError("string expected"));
            }

            // Check whether the import is of the form 'from x import y'.
            // This determines whether we return the head or tail module.

            IntPtr fromList = IntPtr.Zero;
            var    fromlist = false;

            if (num_args >= 4)
            {
                fromList = Runtime.PyTuple_GetItem(args, 3);
                if (fromList != IntPtr.Zero &&
                    Runtime.PyObject_IsTrue(fromList) == 1)
                {
                    fromlist = true;
                }
            }

            string mod_name = Runtime.GetManagedString(py_mod_name);

            // Check these BEFORE the built-in import runs; may as well
            // do the Incref()ed return here, since we've already found
            // the module.
            if (mod_name == "clr" || mod_name == "CLR")
            {
                if (mod_name == "CLR")
                {
                    Exceptions.deprecation("The CLR module is deprecated. Please use 'clr'.");
                }
                IntPtr clr_module = GetCLRModule(fromList);
                if (clr_module != IntPtr.Zero)
                {
                    IntPtr sys_modules = Runtime.PyImport_GetModuleDict();
                    if (sys_modules != IntPtr.Zero)
                    {
                        Runtime.PyDict_SetItemString(sys_modules, "clr", clr_module);
                    }
                }
                return(clr_module);
            }

            string realname   = mod_name;
            string clr_prefix = null;

            if (mod_name.StartsWith("CLR."))
            {
                clr_prefix = "CLR."; // prepend when adding the module to sys.modules
                realname   = mod_name.Substring(4);
                string msg = $"Importing from the CLR.* namespace is deprecated. Please import '{realname}' directly.";
                Exceptions.deprecation(msg);
            }
            else
            {
                // 2010-08-15: Always seemed smart to let python try first...
                // This shaves off a few tenths of a second on test_module.py
                // and works around a quirk where 'sys' is found by the
                // LoadImplicit() deprecation logic.
                // Turns out that the AssemblyManager.ResolveHandler() checks to see if any
                // Assembly's FullName.ToLower().StartsWith(name.ToLower()), which makes very
                // little sense to me.
                IntPtr res = Runtime.PyObject_Call(py_import, args, kw);
                if (res != IntPtr.Zero)
                {
                    // There was no error.
                    if (fromlist && IsLoadAll(fromList))
                    {
                        var mod = ManagedType.GetManagedObject(res) as ModuleObject;
                        mod?.LoadNames();
                    }
                    return(res);
                }
                // There was an error
                if (!Exceptions.ExceptionMatches(Exceptions.ImportError))
                {
                    // and it was NOT an ImportError; bail out here.
                    return(IntPtr.Zero);
                }

                if (mod_name == string.Empty)
                {
                    // Most likely a missing relative import.
                    // For example site-packages\bs4\builder\__init__.py uses it to check if a package exists:
                    //     from . import _html5lib
                    // We don't support them anyway
                    return(IntPtr.Zero);
                }
                // Otherwise,  just clear the it.
                Exceptions.Clear();
            }

            string[] names = realname.Split('.');

            // Now we need to decide if the name refers to a CLR module,
            // and may have to do an implicit load (for b/w compatibility)
            // using the AssemblyManager. The assembly manager tries
            // really hard not to use Python objects or APIs, because
            // parts of it can run recursively and on strange threads.
            //
            // It does need an opportunity from time to time to check to
            // see if sys.path has changed, in a context that is safe. Here
            // we know we have the GIL, so we'll let it update if needed.

            AssemblyManager.UpdatePath();
            if (!AssemblyManager.IsValidNamespace(realname))
            {
                var loadExceptions = new List <Exception>();
                if (!AssemblyManager.LoadImplicit(realname, assemblyLoadErrorHandler: loadExceptions.Add))
                {
                    // May be called when a module being imported imports a module.
                    // In particular, I've seen decimal import copy import org.python.core
                    IntPtr importResult = Runtime.PyObject_Call(py_import, args, kw);
                    // TODO: use ModuleNotFoundError in Python 3.6+
                    if (importResult == IntPtr.Zero && loadExceptions.Count > 0 &&
                        Exceptions.ExceptionMatches(Exceptions.ImportError))
                    {
                        loadExceptions.Add(new PythonException());
                        var importError = new PyObject(new BorrowedReference(Exceptions.ImportError));
                        importError.SetAttr("__cause__", new AggregateException(loadExceptions).ToPython());
                        Runtime.PyErr_SetObject(new BorrowedReference(Exceptions.ImportError), importError.Reference);
                    }
                    return(importResult);
                }
            }

            // See if sys.modules for this interpreter already has the
            // requested module. If so, just return the existing module.
            IntPtr modules = Runtime.PyImport_GetModuleDict();
            IntPtr module  = Runtime.PyDict_GetItem(modules, py_mod_name);

            if (module != IntPtr.Zero)
            {
                if (fromlist)
                {
                    if (IsLoadAll(fromList))
                    {
                        var mod = ManagedType.GetManagedObject(module) as ModuleObject;
                        mod?.LoadNames();
                    }
                    Runtime.XIncref(module);
                    return(module);
                }
                if (clr_prefix != null)
                {
                    return(GetCLRModule(fromList));
                }
                module = Runtime.PyDict_GetItemString(modules, names[0]);
                Runtime.XIncref(module);
                return(module);
            }
            Exceptions.Clear();

            // Traverse the qualified module name to get the named module
            // and place references in sys.modules as we go. Note that if
            // we are running in interactive mode we pre-load the names in
            // each module, which is often useful for introspection. If we
            // are not interactive, we stick to just-in-time creation of
            // objects at lookup time, which is much more efficient.
            // NEW: The clr got a new module variable preload. You can
            // enable preloading in a non-interactive python processing by
            // setting clr.preload = True

            ModuleObject head = mod_name == realname ? null : root;
            ModuleObject tail = root;

            root.InitializePreload();

            foreach (string name in names)
            {
                ManagedType mt = tail.GetAttribute(name, true);
                if (!(mt is ModuleObject))
                {
                    Exceptions.SetError(Exceptions.ImportError, $"No module named {name}");
                    return(IntPtr.Zero);
                }
                if (head == null)
                {
                    head = (ModuleObject)mt;
                }
                tail = (ModuleObject)mt;
                if (CLRModule.preload)
                {
                    tail.LoadNames();
                }

                // Add the module to sys.modules
                Runtime.PyDict_SetItemString(modules, tail.moduleName, tail.pyHandle);

                // If imported from CLR add CLR.<modulename> to sys.modules as well
                if (clr_prefix != null)
                {
                    Runtime.PyDict_SetItemString(modules, clr_prefix + tail.moduleName, tail.pyHandle);
                }
            }

            {
                var mod = fromlist ? tail : head;

                if (fromlist && IsLoadAll(fromList))
                {
                    mod.LoadNames();
                }

                Runtime.XIncref(mod.pyHandle);
                return(mod.pyHandle);
            }
        }
예제 #18
0
 /// <summary>
 /// IsTupleType Method
 /// </summary>
 /// <remarks>
 /// Returns true if the given object is a Python tuple.
 /// </remarks>
 public static bool IsTupleType(PyObject value)
 {
     return(Runtime.PyTuple_Check(value.obj));
 }
예제 #19
0
 /// <summary>
 /// SetItem Method
 /// </summary>
 ///
 /// <remarks>
 /// For objects that support the Python sequence or mapping protocols,
 /// set the item at the given string index to the given value. This 
 /// method raises a PythonException if the set operation fails.
 /// </remarks>
 public virtual void SetItem(string key, PyObject value)
 {
     SetItem(new PyString(key), value);
 }
예제 #20
0
        /// <summary>
        /// Eval Method
        /// </summary>
        /// <remarks>
        /// Evaluate a Python expression and returns the result.
        /// It's a subset of Python eval function.
        /// </remarks>
        public static PyObject Eval(string code, IntPtr?globals = null, IntPtr?locals = null)
        {
            PyObject result = RunString(code, globals, locals, RunFlagType.Eval);

            return(result);
        }
예제 #21
0
        /// <summary>
        /// Initialize Method
        /// </summary>
        /// <remarks>
        /// Initialize the Python runtime. It is safe to call this method
        /// more than once, though initialization will only happen on the
        /// first call. It is *not* necessary to hold the Python global
        /// interpreter lock (GIL) to call this method.
        /// initSigs can be set to 1 to do default python signal configuration. This will override the way signals are handled by the application.
        /// </remarks>
        public static void Initialize(IEnumerable <string> args, bool setSysArgv = true, bool initSigs = false)
        {
            if (!initialized)
            {
                // Creating the delegateManager MUST happen before Runtime.Initialize
                // is called. If it happens afterwards, DelegateManager's CodeGenerator
                // throws an exception in its ctor.  This exception is eaten somehow
                // during an initial "import clr", and the world ends shortly thereafter.
                // This is probably masking some bad mojo happening somewhere in Runtime.Initialize().
                delegateManager = new DelegateManager();
                Runtime.Initialize(initSigs);
                initialized = true;
                Exceptions.Clear();

                // Make sure we clean up properly on app domain unload.
                AppDomain.CurrentDomain.DomainUnload += OnDomainUnload;

                // Remember to shut down the runtime.
                AddShutdownHandler(Runtime.Shutdown);

                // The global scope gets used implicitly quite early on, remember
                // to clear it out when we shut down.
                AddShutdownHandler(PyScopeManager.Global.Clear);

                if (setSysArgv)
                {
                    Py.SetArgv(args);
                }

                // register the atexit callback (this doesn't use Py_AtExit as the C atexit
                // callbacks are called after python is fully finalized but the python ones
                // are called while the python engine is still running).
                string code =
                    "import atexit, clr\n" +
                    "atexit.register(clr._AtExit)\n";
                PythonEngine.Exec(code);

                // Load the clr.py resource into the clr module
                IntPtr clr      = Python.Runtime.ImportHook.GetCLRModule();
                IntPtr clr_dict = Runtime.PyModule_GetDict(clr);

                var locals = new PyDict();
                try
                {
                    IntPtr module         = Runtime.PyImport_AddModule("clr._extras");
                    IntPtr module_globals = Runtime.PyModule_GetDict(module);
                    IntPtr builtins       = Runtime.PyEval_GetBuiltins();
                    Runtime.PyDict_SetItemString(module_globals, "__builtins__", builtins);

                    Assembly assembly = Assembly.GetExecutingAssembly();
                    using (Stream stream = assembly.GetManifestResourceStream("clr.py"))
                        using (var reader = new StreamReader(stream))
                        {
                            // add the contents of clr.py to the module
                            string clr_py = reader.ReadToEnd();
                            Exec(clr_py, module_globals, locals.Handle);
                        }

                    // add the imported module to the clr module, and copy the API functions
                    // and decorators into the main clr module.
                    Runtime.PyDict_SetItemString(clr_dict, "_extras", module);
                    foreach (PyObject key in locals.Keys())
                    {
                        if (!key.ToString().StartsWith("_") || key.ToString().Equals("__version__"))
                        {
                            PyObject value = locals[key];
                            Runtime.PyDict_SetItem(clr_dict, key.Handle, value.Handle);
                            value.Dispose();
                        }
                        key.Dispose();
                    }
                }
                finally
                {
                    locals.Dispose();
                }
            }
        }
예제 #22
0
 /// <summary>
 /// PyObject Indexer
 /// </summary>
 /// <remarks>
 /// Provides a shorthand for the object versions of the GetItem and
 /// SetItem methods.
 /// </remarks>
 public virtual PyObject this[PyObject key]
 {
     get { return(GetItem(key)); }
     set { SetItem(key, value); }
 }
예제 #23
0
 /// <summary>
 /// HasAttr Method
 /// </summary>
 /// <remarks>
 /// Returns true if the object has an attribute with the given name,
 /// where name is a PyObject wrapping a string or unicode object.
 /// </remarks>
 public bool HasAttr(PyObject name)
 {
     return(Runtime.Interop.PyObject_HasAttr(obj, name.obj) != 0);
 }
예제 #24
0
 /// <summary>
 /// TypeCheck Method
 /// </summary>
 /// <remarks>
 /// Returns true if the object o is of type typeOrClass or a subtype
 /// of typeOrClass.
 /// </remarks>
 public bool TypeCheck(PyObject typeOrClass)
 {
     return(Runtime.PyObject_TypeCheck(obj, typeOrClass.obj));
 }
예제 #25
0
        /// <summary>
        /// IsNumberType Method
        /// </summary>
        ///
        /// <remarks>
        /// Returns true if the given object is a Python numeric type.
        /// </remarks>

        public static bool IsNumberType(PyObject value)
        {
            return(Runtime.PyNumber_Check(value.obj));
        }
예제 #26
0
 protected Dispatcher(IntPtr target, Type dtype)
 {
     this.target = new PyObject(new BorrowedReference(target));
     this.dtype  = dtype;
 }
예제 #27
0
 /// <summary>
 /// SetAttr Method
 /// </summary>
 ///
 /// <remarks>
 /// Set an attribute of the object with the given name and value, 
 /// where the name is a Python string or unicode object. This method
 /// throws a PythonException if the attribute set fails.
 /// </remarks>
 public void SetAttr(PyObject name, PyObject value)
 {
     int r = Runtime.PyObject_SetAttr(obj, name.obj, value.obj);
     if (r < 0) {
     throw new PythonException();
     }
 }
예제 #28
0
        internal static IntPtr ToPython(object value, Type type)
        {
            if (value is PyObject)
            {
                IntPtr handle = ((PyObject)value).Handle;
                Runtime.XIncref(handle);
                return(handle);
            }
            IntPtr result = IntPtr.Zero;

            // Null always converts to None in Python.

            if (value == null)
            {
                result = Runtime.PyNone;
                Runtime.XIncref(result);
                return(result);
            }

            if (Type.GetTypeCode(type) == TypeCode.Object && value.GetType() != typeof(object))
            {
                var encoded = PyObjectConversions.TryEncode(value, type);
                if (encoded != null)
                {
                    result = encoded.Handle;
                    Runtime.XIncref(result);
                    return(result);
                }
            }

            if (value is IList && !(value is INotifyPropertyChanged) && value.GetType().IsGenericType)
            {
                using (var resultlist = new PyList())
                {
                    foreach (object o in (IEnumerable)value)
                    {
                        using (var p = new PyObject(ToPython(o, o?.GetType())))
                        {
                            resultlist.Append(p);
                        }
                    }
                    Runtime.XIncref(resultlist.Handle);
                    return(resultlist.Handle);
                }
            }

            if (type.IsInterface)
            {
                var ifaceObj = (InterfaceObject)ClassManager.GetClass(type);
                return(ifaceObj.WrapObject(value));
            }

            // We need to special case interface array handling to ensure we
            // produce the correct type. Value may be an array of some concrete
            // type (FooImpl[]), but we want access to go via the interface type
            // (IFoo[]).
            if (type.IsArray && type.GetElementType().IsInterface)
            {
                return(CLRObject.GetInstHandle(value, type));
            }

            // it the type is a python subclass of a managed type then return the
            // underlying python object rather than construct a new wrapper object.
            var pyderived = value as IPythonDerivedType;

            if (null != pyderived)
            {
                if (!IsTransparentProxy(pyderived))
                {
                    return(ClassDerivedObject.ToPython(pyderived));
                }
            }

            // hmm - from Python, we almost never care what the declared
            // type is. we'd rather have the object bound to the actual
            // implementing class.

            type = value.GetType();

            TypeCode tc = Type.GetTypeCode(type);

            switch (tc)
            {
            case TypeCode.Object:
                return(CLRObject.GetInstHandle(value, type));

            case TypeCode.String:
                return(Runtime.PyUnicode_FromString((string)value));

            case TypeCode.Int32:
                return(Runtime.PyInt_FromInt32((int)value));

            case TypeCode.Boolean:
                if ((bool)value)
                {
                    Runtime.XIncref(Runtime.PyTrue);
                    return(Runtime.PyTrue);
                }
                Runtime.XIncref(Runtime.PyFalse);
                return(Runtime.PyFalse);

            case TypeCode.Byte:
                return(Runtime.PyInt_FromInt32((int)((byte)value)));

            case TypeCode.Char:
                return(Runtime.PyUnicode_FromOrdinal((int)((char)value)));

            case TypeCode.Int16:
                return(Runtime.PyInt_FromInt32((int)((short)value)));

            case TypeCode.Int64:
                return(Runtime.PyLong_FromLongLong((long)value));

            case TypeCode.Single:
                // return Runtime.PyFloat_FromDouble((double)((float)value));
                string       ss = ((float)value).ToString(nfi);
                IntPtr       ps = Runtime.PyString_FromString(ss);
                NewReference op = Runtime.PyFloat_FromString(new BorrowedReference(ps));;
                Runtime.XDecref(ps);
                return(op.DangerousMoveToPointerOrNull());

            case TypeCode.Double:
                return(Runtime.PyFloat_FromDouble((double)value));

            case TypeCode.SByte:
                return(Runtime.PyInt_FromInt32((int)((sbyte)value)));

            case TypeCode.UInt16:
                return(Runtime.PyInt_FromInt32((int)((ushort)value)));

            case TypeCode.UInt32:
                return(Runtime.PyLong_FromUnsignedLong((uint)value));

            case TypeCode.UInt64:
                return(Runtime.PyLong_FromUnsignedLongLong((ulong)value));

            default:
                if (value is IEnumerable)
                {
                    using (var resultlist = new PyList())
                    {
                        foreach (object o in (IEnumerable)value)
                        {
                            using (var p = new PyObject(ToPython(o, o?.GetType())))
                            {
                                resultlist.Append(p);
                            }
                        }
                        Runtime.XIncref(resultlist.Handle);
                        return(resultlist.Handle);
                    }
                }
                result = CLRObject.GetInstHandle(value, type);
                return(result);
            }
        }
예제 #29
0
        public override bool TryBinaryOperation(BinaryOperationBinder binder, Object arg, out Object result)
        {
            IntPtr res;
            if (!(arg is PyObject))
            arg = arg.ToPython();

            switch (binder.Operation)
            {
            case ExpressionType.Add:
                res = Runtime.PyNumber_Add(this.obj, ((PyObject)arg).obj);
                break;
            case ExpressionType.AddAssign:
                res = Runtime.PyNumber_InPlaceAdd(this.obj, ((PyObject)arg).obj);
                break;
            case ExpressionType.Subtract:
                res = Runtime.PyNumber_Subtract(this.obj, ((PyObject)arg).obj);
                break;
            case ExpressionType.SubtractAssign:
                res = Runtime.PyNumber_InPlaceSubtract(this.obj, ((PyObject)arg).obj);
                break;
            case ExpressionType.Multiply:
                res = Runtime.PyNumber_Multiply(this.obj, ((PyObject)arg).obj);
                break;
            case ExpressionType.MultiplyAssign:
                res = Runtime.PyNumber_InPlaceMultiply(this.obj, ((PyObject)arg).obj);
                break;
            case ExpressionType.Divide:
                res = Runtime.PyNumber_Divide(this.obj, ((PyObject)arg).obj);
                break;
            case ExpressionType.DivideAssign:
                res = Runtime.PyNumber_InPlaceDivide(this.obj, ((PyObject)arg).obj);
                break;
            case ExpressionType.And:
                res = Runtime.PyNumber_And(this.obj, ((PyObject)arg).obj);
                break;
            case ExpressionType.AndAssign:
                res = Runtime.PyNumber_InPlaceAnd(this.obj, ((PyObject)arg).obj);
                break;
            case ExpressionType.ExclusiveOr:
                res = Runtime.PyNumber_Xor(this.obj, ((PyObject)arg).obj);
                break;
            case ExpressionType.ExclusiveOrAssign:
                res = Runtime.PyNumber_InPlaceXor(this.obj, ((PyObject)arg).obj);
                break;
            case ExpressionType.GreaterThan:
                result = Runtime.PyObject_Compare(this.obj, ((PyObject)arg).obj) > 0;
                return true;
            case ExpressionType.GreaterThanOrEqual:
                result = Runtime.PyObject_Compare(this.obj, ((PyObject)arg).obj) >= 0;
                return true;
            case ExpressionType.LeftShift:
                res = Runtime.PyNumber_Lshift(this.obj, ((PyObject)arg).obj);
                break;
            case ExpressionType.LeftShiftAssign:
                res = Runtime.PyNumber_InPlaceLshift(this.obj, ((PyObject)arg).obj);
                break;
            case ExpressionType.LessThan:
                result = Runtime.PyObject_Compare(this.obj, ((PyObject)arg).obj) < 0;
                return true;
            case ExpressionType.LessThanOrEqual:
                result = Runtime.PyObject_Compare(this.obj, ((PyObject)arg).obj) <= 0;
                return true;
            case ExpressionType.Modulo:
                res = Runtime.PyNumber_Remainder(this.obj, ((PyObject)arg).obj);
                break;
            case ExpressionType.ModuloAssign:
                res = Runtime.PyNumber_InPlaceRemainder(this.obj, ((PyObject)arg).obj);
                break;
            case ExpressionType.NotEqual:
                result = Runtime.PyObject_Compare(this.obj, ((PyObject)arg).obj) != 0;
                return true;
            case ExpressionType.Or:
                res = Runtime.PyNumber_Or(this.obj, ((PyObject)arg).obj);
                break;
            case ExpressionType.OrAssign:
                res = Runtime.PyNumber_InPlaceOr(this.obj, ((PyObject)arg).obj);
                break;
            case ExpressionType.Power:
                res = Runtime.PyNumber_Power(this.obj, ((PyObject)arg).obj);
                break;
            case ExpressionType.RightShift:
                res = Runtime.PyNumber_Rshift(this.obj, ((PyObject)arg).obj);
                break;
            case ExpressionType.RightShiftAssign:
                res = Runtime.PyNumber_InPlaceRshift(this.obj, ((PyObject)arg).obj);
                break;
            default:
                result = null;
                return false;
            }
            result = new PyObject(res);
            return true;
        }
예제 #30
0
        internal static bool ToManagedValue(IntPtr value, Type obType,
                                            out object result, bool setError)
        {
            if (obType == typeof(PyObject))
            {
                Runtime.XIncref(value); // PyObject() assumes ownership
                result = new PyObject(value);
                return(true);
            }

            // Common case: if the Python value is a wrapped managed object
            // instance, just return the wrapped object.
            ManagedType mt = ManagedType.GetManagedObject(value);

            result = null;

            if (mt != null)
            {
                if (mt is CLRObject co)
                {
                    object tmp = co.inst;
                    if (obType.IsInstanceOfType(tmp))
                    {
                        result = tmp;
                        return(true);
                    }
                    if (setError)
                    {
                        string typeString = tmp is null ? "null" : tmp.GetType().ToString();
                        Exceptions.SetError(Exceptions.TypeError, $"{typeString} value cannot be converted to {obType}");
                    }
                    return(false);
                }
                if (mt is ClassBase cb)
                {
                    if (!cb.type.Valid)
                    {
                        Exceptions.SetError(Exceptions.TypeError, cb.type.DeletedMessage);
                        return(false);
                    }
                    result = cb.type.Value;
                    return(true);
                }
                // shouldn't happen
                return(false);
            }

            if (value == Runtime.PyNone && !obType.IsValueType)
            {
                result = null;
                return(true);
            }

            if (obType.IsGenericType && obType.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                if (value == Runtime.PyNone)
                {
                    result = null;
                    return(true);
                }
                // Set type to underlying type
                obType = obType.GetGenericArguments()[0];
            }

            if (obType.ContainsGenericParameters)
            {
                if (setError)
                {
                    Exceptions.SetError(Exceptions.TypeError, $"Cannot create an instance of the open generic type {obType}");
                }
                return(false);
            }

            if (obType.IsArray)
            {
                return(ToArray(value, obType, out result, setError));
            }

            if (obType.IsEnum)
            {
                return(ToEnum(value, obType, out result, setError));
            }

            // Conversion to 'Object' is done based on some reasonable default
            // conversions (Python string -> managed string, Python int -> Int32 etc.).
            if (obType == objectType)
            {
                if (Runtime.IsStringType(value))
                {
                    return(ToPrimitive(value, stringType, out result, setError));
                }

                if (Runtime.PyBool_Check(value))
                {
                    return(ToPrimitive(value, boolType, out result, setError));
                }

                if (Runtime.PyInt_Check(value))
                {
                    return(ToPrimitive(value, int32Type, out result, setError));
                }

                if (Runtime.PyLong_Check(value))
                {
                    return(ToPrimitive(value, int64Type, out result, setError));
                }

                if (Runtime.PyFloat_Check(value))
                {
                    return(ToPrimitive(value, doubleType, out result, setError));
                }

                // give custom codecs a chance to take over conversion of sequences
                IntPtr pyType = Runtime.PyObject_TYPE(value);
                if (PyObjectConversions.TryDecode(value, pyType, obType, out result))
                {
                    return(true);
                }

                if (Runtime.PySequence_Check(value))
                {
                    return(ToArray(value, typeof(object[]), out result, setError));
                }

                Runtime.XIncref(value); // PyObject() assumes ownership
                result = new PyObject(value);
                return(true);
            }

            // Conversion to 'Type' is done using the same mappings as above for objects.
            if (obType == typeType)
            {
                if (value == Runtime.PyStringType)
                {
                    result = stringType;
                    return(true);
                }

                if (value == Runtime.PyBoolType)
                {
                    result = boolType;
                    return(true);
                }

                if (value == Runtime.PyIntType)
                {
                    result = int32Type;
                    return(true);
                }

                if (value == Runtime.PyLongType)
                {
                    result = int64Type;
                    return(true);
                }

                if (value == Runtime.PyFloatType)
                {
                    result = doubleType;
                    return(true);
                }

                if (value == Runtime.PyListType || value == Runtime.PyTupleType)
                {
                    result = typeof(object[]);
                    return(true);
                }

                if (setError)
                {
                    Exceptions.SetError(Exceptions.TypeError, "value cannot be converted to Type");
                }

                return(false);
            }

            TypeCode typeCode = Type.GetTypeCode(obType);

            if (typeCode == TypeCode.Object)
            {
                IntPtr pyType = Runtime.PyObject_TYPE(value);
                if (PyObjectConversions.TryDecode(value, pyType, obType, out result))
                {
                    return(true);
                }
            }

            return(ToPrimitive(value, obType, out result, setError));
        }
예제 #31
0
 /// <summary>
 /// IsFloatType Method
 /// </summary>
 /// <remarks>
 /// Returns true if the given object is a Python float.
 /// </remarks>
 public static bool IsFloatType(PyObject value)
 {
     return(Runtime.PyFloat_Check(value.obj));
 }
예제 #32
0
        internal static IntPtr ToPython(object value, Type type)
        {
            if (value is PyObject)
            {
                IntPtr handle = ((PyObject)value).Handle;
                Runtime.XIncref(handle);
                return(handle);
            }
            IntPtr result = IntPtr.Zero;

            // Null always converts to None in Python.

            if (value == null)
            {
                result = Runtime.PyNone;
                Runtime.XIncref(result);
                return(result);
            }

            if (value is IList && value.GetType().IsGenericType)
            {
                using (var resultlist = new PyList())
                {
                    foreach (object o in (IEnumerable)value)
                    {
                        using (var p = new PyObject(ToPython(o, o?.GetType())))
                        {
                            resultlist.Append(p);
                        }
                    }
                    Runtime.XIncref(resultlist.Handle);
                    return(resultlist.Handle);
                }
            }

            // it the type is a python subclass of a managed type then return the
            // underlying python object rather than construct a new wrapper object.
            var pyderived = value as IPythonDerivedType;

            if (null != pyderived)
            {
                #if NETSTANDARD
                return(ClassDerivedObject.ToPython(pyderived));
                #else
                // if object is remote don't do this
                if (!System.Runtime.Remoting.RemotingServices.IsTransparentProxy(pyderived))
                {
                    return(ClassDerivedObject.ToPython(pyderived));
                }
                #endif
            }

            // hmm - from Python, we almost never care what the declared
            // type is. we'd rather have the object bound to the actual
            // implementing class.

            type = value.GetType();

            TypeCode tc = Type.GetTypeCode(type);

            switch (tc)
            {
            case TypeCode.Object:
                return(CLRObject.GetInstHandle(value, type));

            case TypeCode.String:
                return(Runtime.PyUnicode_FromString((string)value));

            case TypeCode.Int32:
                return(Runtime.PyInt_FromInt32((int)value));

            case TypeCode.Boolean:
                if ((bool)value)
                {
                    Runtime.XIncref(Runtime.PyTrue);
                    return(Runtime.PyTrue);
                }
                Runtime.XIncref(Runtime.PyFalse);
                return(Runtime.PyFalse);

            case TypeCode.Byte:
                return(Runtime.PyInt_FromInt32((int)((byte)value)));

            case TypeCode.Char:
                return(Runtime.PyUnicode_FromOrdinal((int)((char)value)));

            case TypeCode.Int16:
                return(Runtime.PyInt_FromInt32((int)((short)value)));

            case TypeCode.Int64:
                return(Runtime.PyLong_FromLongLong((long)value));

            case TypeCode.Single:
                // return Runtime.PyFloat_FromDouble((double)((float)value));
                string ss = ((float)value).ToString(nfi);
                IntPtr ps = Runtime.PyString_FromString(ss);
                IntPtr op = Runtime.PyFloat_FromString(ps, IntPtr.Zero);
                Runtime.XDecref(ps);
                return(op);

            case TypeCode.Double:
                return(Runtime.PyFloat_FromDouble((double)value));

            case TypeCode.SByte:
                return(Runtime.PyInt_FromInt32((int)((sbyte)value)));

            case TypeCode.UInt16:
                return(Runtime.PyInt_FromInt32((int)((ushort)value)));

            case TypeCode.UInt32:
                return(Runtime.PyLong_FromUnsignedLong((uint)value));

            case TypeCode.UInt64:
                return(Runtime.PyLong_FromUnsignedLongLong((ulong)value));

            default:
                if (value is IEnumerable)
                {
                    using (var resultlist = new PyList())
                    {
                        foreach (object o in (IEnumerable)value)
                        {
                            using (var p = new PyObject(ToPython(o, o?.GetType())))
                            {
                                resultlist.Append(p);
                            }
                        }
                        Runtime.XIncref(resultlist.Handle);
                        return(resultlist.Handle);
                    }
                }
                result = CLRObject.GetInstHandle(value, type);
                return(result);
            }
        }
예제 #33
0
 /// <summary>
 /// PyObject Indexer
 /// </summary>
 ///
 /// <remarks>
 /// Provides a shorthand for the object versions of the GetItem and 
 /// SetItem methods.
 /// </remarks>
 public virtual PyObject this[PyObject key]
 {
     get { return GetItem(key); }
     set { SetItem(key, value); }
 }
예제 #34
0
 /// <summary>
 /// DelItem Method
 /// </summary>
 ///
 /// <remarks>
 /// For objects that support the Python sequence or mapping protocols,
 /// delete the item at the given object index. This method raises a 
 /// PythonException if the delete operation fails.
 /// </remarks>
 public virtual void DelItem(PyObject key)
 {
     int r = Runtime.PyObject_DelItem(obj, key.obj);
     if (r < 0) {
     throw new PythonException();
     }
 }
예제 #35
0
 /// <summary>
 /// HasKey Method
 /// </summary>
 /// <remarks>
 /// Returns true if the object key appears in the dictionary.
 /// </remarks>
 public bool HasKey(PyObject key)
 {
     return(Runtime.PyMapping_HasKey(obj, key.obj) != 0);
 }
예제 #36
0
 /// <summary>
 /// GetAttr Method
 /// </summary>
 ///
 /// <remarks>
 /// Returns the named attribute of the Python object, or the given
 /// default object if the attribute access fails. The name argument 
 /// is a PyObject wrapping a Python string or unicode object.
 /// </remarks>
 public PyObject GetAttr(PyObject name, PyObject _default)
 {
     IntPtr op = Runtime.PyObject_GetAttr(obj, name.obj);
     if (op == IntPtr.Zero) {
     Runtime.PyErr_Clear();
     return _default;
     }
     return new PyObject(op);
 }
예제 #37
0
        public override bool TryBinaryOperation(BinaryOperationBinder binder, Object arg, out Object result)
        {
            IntPtr res;

            if (!(arg is PyObject))
            {
                arg = arg.ToPython();
            }

            switch (binder.Operation)
            {
            case ExpressionType.Add:
                res = Runtime.PyNumber_Add(this.obj, ((PyObject)arg).obj);
                break;

            case ExpressionType.AddAssign:
                res = Runtime.PyNumber_InPlaceAdd(this.obj, ((PyObject)arg).obj);
                break;

            case ExpressionType.Subtract:
                res = Runtime.PyNumber_Subtract(this.obj, ((PyObject)arg).obj);
                break;

            case ExpressionType.SubtractAssign:
                res = Runtime.PyNumber_InPlaceSubtract(this.obj, ((PyObject)arg).obj);
                break;

            case ExpressionType.Multiply:
                res = Runtime.PyNumber_Multiply(this.obj, ((PyObject)arg).obj);
                break;

            case ExpressionType.MultiplyAssign:
                res = Runtime.PyNumber_InPlaceMultiply(this.obj, ((PyObject)arg).obj);
                break;

            case ExpressionType.Divide:
                res = Runtime.PyNumber_Divide(this.obj, ((PyObject)arg).obj);
                break;

            case ExpressionType.DivideAssign:
                res = Runtime.PyNumber_InPlaceDivide(this.obj, ((PyObject)arg).obj);
                break;

            case ExpressionType.And:
                res = Runtime.PyNumber_And(this.obj, ((PyObject)arg).obj);
                break;

            case ExpressionType.AndAssign:
                res = Runtime.PyNumber_InPlaceAnd(this.obj, ((PyObject)arg).obj);
                break;

            case ExpressionType.ExclusiveOr:
                res = Runtime.PyNumber_Xor(this.obj, ((PyObject)arg).obj);
                break;

            case ExpressionType.ExclusiveOrAssign:
                res = Runtime.PyNumber_InPlaceXor(this.obj, ((PyObject)arg).obj);
                break;

            case ExpressionType.GreaterThan:
                result = Runtime.PyObject_Compare(this.obj, ((PyObject)arg).obj) > 0;
                return(true);

            case ExpressionType.GreaterThanOrEqual:
                result = Runtime.PyObject_Compare(this.obj, ((PyObject)arg).obj) >= 0;
                return(true);

            case ExpressionType.LeftShift:
                res = Runtime.PyNumber_Lshift(this.obj, ((PyObject)arg).obj);
                break;

            case ExpressionType.LeftShiftAssign:
                res = Runtime.PyNumber_InPlaceLshift(this.obj, ((PyObject)arg).obj);
                break;

            case ExpressionType.LessThan:
                result = Runtime.PyObject_Compare(this.obj, ((PyObject)arg).obj) < 0;
                return(true);

            case ExpressionType.LessThanOrEqual:
                result = Runtime.PyObject_Compare(this.obj, ((PyObject)arg).obj) <= 0;
                return(true);

            case ExpressionType.Modulo:
                res = Runtime.PyNumber_Remainder(this.obj, ((PyObject)arg).obj);
                break;

            case ExpressionType.ModuloAssign:
                res = Runtime.PyNumber_InPlaceRemainder(this.obj, ((PyObject)arg).obj);
                break;

            case ExpressionType.NotEqual:
                result = Runtime.PyObject_Compare(this.obj, ((PyObject)arg).obj) != 0;
                return(true);

            case ExpressionType.Or:
                res = Runtime.PyNumber_Or(this.obj, ((PyObject)arg).obj);
                break;

            case ExpressionType.OrAssign:
                res = Runtime.PyNumber_InPlaceOr(this.obj, ((PyObject)arg).obj);
                break;

            case ExpressionType.Power:
                res = Runtime.PyNumber_Power(this.obj, ((PyObject)arg).obj);
                break;

            case ExpressionType.RightShift:
                res = Runtime.PyNumber_Rshift(this.obj, ((PyObject)arg).obj);
                break;

            case ExpressionType.RightShiftAssign:
                res = Runtime.PyNumber_InPlaceRshift(this.obj, ((PyObject)arg).obj);
                break;

            default:
                result = null;
                return(false);
            }
            result = new PyObject(res);
            return(true);
        }
예제 #38
0
 /// <summary>
 /// HasAttr Method
 /// </summary>
 ///
 /// <remarks>
 /// Returns true if the object has an attribute with the given name,
 /// where name is a PyObject wrapping a string or unicode object.
 /// </remarks>
 public bool HasAttr(PyObject name)
 {
     return (Runtime.PyObject_HasAttr(obj, name.obj) != 0);
 }
예제 #39
0
 /// <summary>
 /// PyFloat Constructor
 /// </summary>
 /// <remarks>
 /// Copy constructor - obtain a PyFloat from a generic PyObject. An
 /// ArgumentException will be thrown if the given object is not a
 /// Python float object.
 /// </remarks>
 public PyFloat(PyObject o) : base(FromObject(o))
 {
 }
예제 #40
0
 /// <summary>
 /// InvokeMethod Method
 /// </summary>
 ///
 /// <remarks>
 /// Invoke the named method of the object with the given arguments 
 /// and keyword arguments. Keyword args are passed as a PyDict object.
 /// A PythonException is raised if the invokation is unsuccessful.
 /// </remarks>
 public PyObject InvokeMethod(string name, PyObject[] args, PyDict kw)
 {
     PyObject method = GetAttr(name);
     PyObject result = method.Invoke(args, kw);
     method.Dispose();
     return result;
 }
예제 #41
0
 public static void Initialize()
 {
     _opType = GetOperatorType();
 }
예제 #42
0
        internal static bool ToManagedValue(IntPtr value, Type obType,
                                            out object result, bool setError)
        {
            if (obType == typeof(PyObject))
            {
                Runtime.XIncref(value); // PyObject() assumes ownership
                result = new PyObject(value);
                return(true);
            }

            // Common case: if the Python value is a wrapped managed object
            // instance, just return the wrapped object.
            ManagedType mt = ManagedType.GetManagedObject(value);

            result = null;

            if (mt != null)
            {
                if (mt is CLRObject)
                {
                    object tmp = ((CLRObject)mt).inst;
                    if (obType.IsInstanceOfType(tmp))
                    {
                        result = tmp;
                        return(true);
                    }
                    Exceptions.SetError(Exceptions.TypeError, $"value cannot be converted to {obType}");
                    return(false);
                }
                if (mt is ClassBase)
                {
                    result = ((ClassBase)mt).type;
                    return(true);
                }
                // shouldn't happen
                return(false);
            }

            if (value == Runtime.PyNone && !obType.IsValueType)
            {
                result = null;
                return(true);
            }

            if (obType.IsGenericType && obType.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                if (value == Runtime.PyNone)
                {
                    result = null;
                    return(true);
                }
                // Set type to underlying type
                obType = obType.GetGenericArguments()[0];
            }

            if (obType.IsArray)
            {
                return(ToArray(value, obType, out result, setError));
            }

            if (obType.IsEnum)
            {
                return(ToEnum(value, obType, out result, setError));
            }

            // Conversion to 'Object' is done based on some reasonable default
            // conversions (Python string -> managed string, Python int -> Int32 etc.).
            if (obType == objectType)
            {
                if (Runtime.IsStringType(value))
                {
                    return(ToPrimitive(value, stringType, out result, setError));
                }

                if (Runtime.PyBool_Check(value))
                {
                    return(ToPrimitive(value, boolType, out result, setError));
                }

                if (Runtime.PyInt_Check(value))
                {
                    return(ToPrimitive(value, int32Type, out result, setError));
                }

                if (Runtime.PyLong_Check(value))
                {
                    return(ToPrimitive(value, int64Type, out result, setError));
                }

                if (Runtime.PyFloat_Check(value))
                {
                    return(ToPrimitive(value, doubleType, out result, setError));
                }

                if (Runtime.PySequence_Check(value))
                {
                    return(ToArray(value, typeof(object[]), out result, setError));
                }

                if (setError)
                {
                    Exceptions.SetError(Exceptions.TypeError, "value cannot be converted to Object");
                }

                return(false);
            }

            // Conversion to 'Type' is done using the same mappings as above for objects.
            if (obType == typeType)
            {
                if (value == Runtime.PyStringType)
                {
                    result = stringType;
                    return(true);
                }

                if (value == Runtime.PyBoolType)
                {
                    result = boolType;
                    return(true);
                }

                if (value == Runtime.PyIntType)
                {
                    result = int32Type;
                    return(true);
                }

                if (value == Runtime.PyLongType)
                {
                    result = int64Type;
                    return(true);
                }

                if (value == Runtime.PyFloatType)
                {
                    result = doubleType;
                    return(true);
                }

                if (value == Runtime.PyListType || value == Runtime.PyTupleType)
                {
                    result = typeof(object[]);
                    return(true);
                }

                if (setError)
                {
                    Exceptions.SetError(Exceptions.TypeError, "value cannot be converted to Type");
                }

                return(false);
            }

            return(ToPrimitive(value, obType, out result, setError));
        }
예제 #43
0
 /// <summary>
 /// TypeCheck Method
 /// </summary>
 ///
 /// <remarks>
 /// Returns true if the object o is of type typeOrClass or a subtype 
 /// of typeOrClass.
 /// </remarks>
 public bool TypeCheck(PyObject typeOrClass)
 {
     return Runtime.PyObject_TypeCheck(obj, typeOrClass.obj);
 }
예제 #44
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,
                                               IntPtr py_dict,
                                               string namespaceStr,
                                               string assemblyName,
                                               string moduleName = "Python.Runtime.Dynamic.dll")
        {
            if (null != namespaceStr)
            {
                name = namespaceStr + "." + name;
            }

            if (null == assemblyName)
            {
                assemblyName = Assembly.GetExecutingAssembly().FullName;
            }

            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);
        }
예제 #45
0
 /// <summary>
 /// DelAttr Method
 /// </summary>
 ///
 /// <remarks>
 /// Delete the named attribute of the Python object, where name is a 
 /// PyObject wrapping a Python string or unicode object. This method 
 /// throws a PythonException if the attribute set fails.
 /// </remarks>
 public void DelAttr(PyObject name)
 {
     int r = Runtime.PyObject_SetAttr(obj, name.obj, IntPtr.Zero);
     if (r < 0) {
     throw new PythonException();
     }
 }
예제 #46
0
        /// <summary>
        /// Python method may have the following function attributes set to control how they're exposed:
        /// - _clr_return_type_    - method return type (required)
        /// - _clr_arg_types_      - list of method argument types (required)
        /// - _clr_method_name_    - method name, if different from the python method name (optional)
        /// </summary>
        /// <param name="methodName">Method name to add to the type</param>
        /// <param name="func">Python callable object</param>
        /// <param name="typeBuilder">TypeBuilder for the new type the method/property is to be added to</param>
        private static void AddPythonMethod(string methodName, PyObject func, TypeBuilder typeBuilder)
        {
            if (func.HasAttr("_clr_method_name_"))
            {
                using (PyObject pyMethodName = func.GetAttr("_clr_method_name_"))
                {
                    methodName = pyMethodName.ToString();
                }
            }

            using (PyObject pyReturnType = func.GetAttr("_clr_return_type_"))
                using (PyObject pyArgTypes = func.GetAttr("_clr_arg_types_"))
                {
                    var returnType = pyReturnType.AsManagedObject(typeof(Type)) as Type;
                    if (returnType == null)
                    {
                        returnType = typeof(void);
                    }

                    if (!pyArgTypes.IsIterable())
                    {
                        throw new ArgumentException("_clr_arg_types_ must be a list or tuple of CLR types");
                    }

                    var argTypes = new List <Type>();
                    foreach (PyObject pyArgType in pyArgTypes)
                    {
                        var argType = pyArgType.AsManagedObject(typeof(Type)) as Type;
                        if (argType == null)
                        {
                            throw new ArgumentException("_clr_arg_types_ must be a list or tuple of CLR types");
                        }
                        argTypes.Add(argType);
                    }

                    // add the method to call back into python
                    MethodAttributes methodAttribs = MethodAttributes.Public |
                                                     MethodAttributes.Virtual |
                                                     MethodAttributes.ReuseSlot |
                                                     MethodAttributes.HideBySig;

                    MethodBuilder methodBuilder = typeBuilder.DefineMethod(methodName,
                                                                           methodAttribs,
                                                                           returnType,
                                                                           argTypes.ToArray());

                    ILGenerator il = methodBuilder.GetILGenerator();
                    il.DeclareLocal(typeof(object[]));
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldstr, methodName);
                    il.Emit(OpCodes.Ldnull); // don't fall back to the base type's method
                    il.Emit(OpCodes.Ldc_I4, argTypes.Count);
                    il.Emit(OpCodes.Newarr, typeof(object));
                    il.Emit(OpCodes.Stloc_0);
                    for (var i = 0; i < argTypes.Count; ++i)
                    {
                        il.Emit(OpCodes.Ldloc_0);
                        il.Emit(OpCodes.Ldc_I4, i);
                        il.Emit(OpCodes.Ldarg, i + 1);
                        if (argTypes[i].IsValueType)
                        {
                            il.Emit(OpCodes.Box, argTypes[i]);
                        }
                        il.Emit(OpCodes.Stelem, typeof(object));
                    }
                    il.Emit(OpCodes.Ldloc_0);
                    if (returnType == typeof(void))
                    {
                        il.Emit(OpCodes.Call, typeof(PythonDerivedType).GetMethod("InvokeMethodVoid"));
                    }
                    else
                    {
                        il.Emit(OpCodes.Call,
                                typeof(PythonDerivedType).GetMethod("InvokeMethod").MakeGenericMethod(returnType));
                    }
                    il.Emit(OpCodes.Ret);
                }
        }
예제 #47
0
 /// <summary>
 /// GetAttr Method
 /// </summary>
 ///
 /// <remarks>
 /// Returns the named attribute of the Python object or raises a 
 /// PythonException if the attribute access fails. The name argument 
 /// is a PyObject wrapping a Python string or unicode object.
 /// </remarks>
 public PyObject GetAttr(PyObject name)
 {
     IntPtr op = Runtime.PyObject_GetAttr(obj, name.obj);
     if (op == IntPtr.Zero) {
     throw new PythonException();
     }
     return new PyObject(op);
 }
예제 #48
0
        /// <summary>
        /// Python properties may have the following function attributes set to control how they're exposed:
        /// - _clr_property_type_     - property type (required)
        /// </summary>
        /// <param name="propertyName">Property name to add to the type</param>
        /// <param name="func">Python property object</param>
        /// <param name="typeBuilder">TypeBuilder for the new type the method/property is to be added to</param>
        private static void AddPythonProperty(string propertyName, PyObject func, TypeBuilder typeBuilder)
        {
            // add the method to call back into python
            MethodAttributes methodAttribs = MethodAttributes.Public |
                                             MethodAttributes.Virtual |
                                             MethodAttributes.ReuseSlot |
                                             MethodAttributes.HideBySig |
                                             MethodAttributes.SpecialName;

            using (PyObject pyPropertyType = func.GetAttr("_clr_property_type_"))
            {
                var propertyType = pyPropertyType.AsManagedObject(typeof(Type)) as Type;
                if (propertyType == null)
                {
                    throw new ArgumentException("_clr_property_type must be a CLR type");
                }

                PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName,
                                                                             PropertyAttributes.None,
                                                                             propertyType,
                                                                             null);

                if (func.HasAttr("fget"))
                {
                    using (PyObject pyfget = func.GetAttr("fget"))
                    {
                        if (pyfget.IsTrue())
                        {
                            MethodBuilder methodBuilder = typeBuilder.DefineMethod("get_" + propertyName,
                                                                                   methodAttribs,
                                                                                   propertyType,
                                                                                   null);

                            ILGenerator il = methodBuilder.GetILGenerator();
                            il.Emit(OpCodes.Ldarg_0);
                            il.Emit(OpCodes.Ldstr, propertyName);
                            il.Emit(OpCodes.Call,
                                    typeof(PythonDerivedType).GetMethod("InvokeGetProperty").MakeGenericMethod(propertyType));
                            il.Emit(OpCodes.Ret);

                            propertyBuilder.SetGetMethod(methodBuilder);
                        }
                    }
                }

                if (func.HasAttr("fset"))
                {
                    using (PyObject pyset = func.GetAttr("fset"))
                    {
                        if (pyset.IsTrue())
                        {
                            MethodBuilder methodBuilder = typeBuilder.DefineMethod("set_" + propertyName,
                                                                                   methodAttribs,
                                                                                   null,
                                                                                   new[] { propertyType });

                            ILGenerator il = methodBuilder.GetILGenerator();
                            il.Emit(OpCodes.Ldarg_0);
                            il.Emit(OpCodes.Ldstr, propertyName);
                            il.Emit(OpCodes.Ldarg_1);
                            il.Emit(OpCodes.Call,
                                    typeof(PythonDerivedType).GetMethod("InvokeSetProperty").MakeGenericMethod(propertyType));
                            il.Emit(OpCodes.Ret);

                            propertyBuilder.SetSetMethod(methodBuilder);
                        }
                    }
                }
            }
        }
예제 #49
0
 /// <summary>
 /// GetItem Method
 /// </summary>
 ///
 /// <remarks>
 /// For objects that support the Python sequence or mapping protocols,
 /// return the item at the given object index. This method raises a 
 /// PythonException if the indexing operation fails.
 /// </remarks>
 public virtual PyObject GetItem(PyObject key)
 {
     IntPtr op = Runtime.PyObject_GetItem(obj, key.obj);
     if (op == IntPtr.Zero) {
     throw new PythonException();
     }
     return new PyObject(op);
 }
예제 #50
0
        public static void InvokeMethodVoid(IPythonDerivedType obj, string methodName, string origMethodName,
                                            object[] args)
        {
            FieldInfo fi   = obj.GetType().GetField("__pyobj__");
            var       self = (CLRObject)fi.GetValue(obj);

            if (null != self)
            {
                var    disposeList = new List <PyObject>();
                IntPtr gs          = Runtime.PyGILState_Ensure();
                try
                {
                    Runtime.XIncref(self.pyHandle);
                    var pyself = new PyObject(self.pyHandle);
                    disposeList.Add(pyself);

                    Runtime.XIncref(Runtime.PyNone);
                    var pynone = new PyObject(Runtime.PyNone);
                    disposeList.Add(pynone);

                    PyObject method = pyself.GetAttr(methodName, pynone);
                    disposeList.Add(method);
                    if (method.Handle != Runtime.PyNone)
                    {
                        // if the method hasn't been overridden then it will be a managed object
                        ManagedType managedMethod = ManagedType.GetManagedObject(method.Handle);
                        if (null == managedMethod)
                        {
                            var pyargs = new PyObject[args.Length];
                            for (var i = 0; i < args.Length; ++i)
                            {
                                pyargs[i] = new PyObject(Converter.ToPythonImplicit(args[i]));
                                disposeList.Add(pyargs[i]);
                            }

                            PyObject py_result = method.Invoke(pyargs);
                            disposeList.Add(py_result);
                            return;
                        }
                    }
                }
                finally
                {
                    foreach (PyObject x in disposeList)
                    {
                        x?.Dispose();
                    }
                    Runtime.PyGILState_Release(gs);
                }
            }

            if (origMethodName == null)
            {
                throw new NotImplementedException($"Python object does not have a '{methodName}' method");
            }

            obj.GetType().InvokeMember(origMethodName,
                                       BindingFlags.InvokeMethod,
                                       null,
                                       obj,
                                       args);
        }
예제 #51
0
 /// <summary>
 /// Invoke Method
 /// </summary>
 ///
 /// <remarks>
 /// Invoke the callable object with the given positional and keyword
 /// arguments. A PythonException is raised if the invokation fails.
 /// </remarks>
 public PyObject Invoke(PyObject[] args, PyDict kw)
 {
     PyTuple t = new PyTuple(args);
     IntPtr r = Runtime.PyObject_Call(obj, t.obj, kw != null ? kw.obj : IntPtr.Zero);
     t.Dispose();
     if (r == IntPtr.Zero) {
     throw new PythonException();
     }
     return new PyObject(r);
 }
예제 #52
0
        public static void InvokeCtor(IPythonDerivedType obj, string origCtorName, object[] args)
        {
            // call the base constructor
            obj.GetType().InvokeMember(origCtorName,
                                       BindingFlags.InvokeMethod,
                                       null,
                                       obj,
                                       args);

            var       disposeList = new List <PyObject>();
            CLRObject self        = null;
            IntPtr    gs          = Runtime.PyGILState_Ensure();

            try
            {
                // create the python object
                IntPtr type = TypeManager.GetTypeHandle(obj.GetType());
                self = new CLRObject(obj, type);

                // set __pyobj__ to self and deref the python object which will allow this
                // object to be collected.
                FieldInfo fi = obj.GetType().GetField("__pyobj__");
                fi.SetValue(obj, self);

                Runtime.XIncref(self.pyHandle);
                var pyself = new PyObject(self.pyHandle);
                disposeList.Add(pyself);

                Runtime.XIncref(Runtime.PyNone);
                var pynone = new PyObject(Runtime.PyNone);
                disposeList.Add(pynone);

                // call __init__
                PyObject init = pyself.GetAttr("__init__", pynone);
                disposeList.Add(init);
                if (init.Handle != Runtime.PyNone)
                {
                    // if __init__ hasn't been overridden then it will be a managed object
                    ManagedType managedMethod = ManagedType.GetManagedObject(init.Handle);
                    if (null == managedMethod)
                    {
                        var pyargs = new PyObject[args.Length];
                        for (var i = 0; i < args.Length; ++i)
                        {
                            pyargs[i] = new PyObject(Converter.ToPython(args[i], args[i]?.GetType()));
                            disposeList.Add(pyargs[i]);
                        }

                        disposeList.Add(init.Invoke(pyargs));
                    }
                }
            }
            finally
            {
                foreach (PyObject x in disposeList)
                {
                    x?.Dispose();
                }

                // Decrement the python object's reference count.
                // This doesn't actually destroy the object, it just sets the reference to this object
                // to be a weak reference and it will be destroyed when the C# object is destroyed.
                if (null != self)
                {
                    Runtime.XDecref(self.pyHandle);
                }

                Runtime.PyGILState_Release(gs);
            }
        }
예제 #53
0
 /// <summary>
 /// IsSubclass Method
 /// </summary>
 ///
 /// <remarks>
 /// Return true if the object is identical to or derived from the 
 /// given Python type or class. This method always succeeds.
 /// </remarks>
 public bool IsSubclass(PyObject typeOrClass)
 {
     int r = Runtime.PyObject_IsSubclass(obj, typeOrClass.obj);
     if (r < 0) {
     Runtime.PyErr_Clear();
     return false;
     }
     return (r != 0);
 }
예제 #54
0
 /// <summary>
 /// IsLongType Method
 /// </summary>
 /// <remarks>
 /// Returns true if the given object is a Python long.
 /// </remarks>
 public static bool IsLongType(PyObject value)
 {
     return(Runtime.PyLong_Check(value.obj));
 }
예제 #55
0
 /// <summary>
 /// SetItem Method
 /// </summary>
 ///
 /// <remarks>
 /// For objects that support the Python sequence or mapping protocols,
 /// set the item at the given object index to the given value. This 
 /// method raises a PythonException if the set operation fails.
 /// </remarks>
 public virtual void SetItem(PyObject key, PyObject value)
 {
     int r = Runtime.PyObject_SetItem(obj, key.obj, value.obj);
     if (r < 0) {
     throw new PythonException();
     }
 }
예제 #56
0
 /// <summary>
 /// PyLong Constructor
 /// </summary>
 /// <remarks>
 /// Copy constructor - obtain a PyLong from a generic PyObject. An
 /// ArgumentException will be thrown if the given object is not a
 /// Python long object.
 /// </remarks>
 public PyLong(PyObject o) : base(FromObject(o))
 {
 }
예제 #57
0
 /// <summary>
 /// SetItem Method
 /// </summary>
 ///
 /// <remarks>
 /// For objects that support the Python sequence or mapping protocols,
 /// set the item at the given numeric index to the given value. This 
 /// method raises a PythonException if the set operation fails.
 /// </remarks>
 public virtual void SetItem(int index, PyObject value)
 {
     SetItem(new PyInt(index), value);
 }
예제 #58
0
        internal static IntPtr CreateSubType(IntPtr py_name, IntPtr py_base_type, IntPtr py_dict)
        {
            // Utility to create a subtype of a managed type with the ability for the
            // a python subtype able to override the managed implementation
            string name = Runtime.GetManagedString(py_name);

            // the derived class can have class attributes __assembly__ and __module__ which
            // control the name of the assembly and module the new type is created in.
            object assembly     = null;
            object namespaceStr = null;

            var disposeList = new List <PyObject>();

            try
            {
                var assemblyKey = new PyObject(Converter.ToPython("__assembly__", typeof(string)));
                disposeList.Add(assemblyKey);
                if (0 != Runtime.PyMapping_HasKey(py_dict, assemblyKey.Handle))
                {
                    var pyAssembly = new PyObject(Runtime.PyDict_GetItem(py_dict, assemblyKey.Handle));
                    Runtime.XIncref(pyAssembly.Handle);
                    disposeList.Add(pyAssembly);
                    if (!Converter.ToManagedValue(pyAssembly.Handle, typeof(string), out assembly, false))
                    {
                        throw new InvalidCastException("Couldn't convert __assembly__ value to string");
                    }
                }

                var namespaceKey = new PyObject(Converter.ToPythonImplicit("__namespace__"));
                disposeList.Add(namespaceKey);
                if (0 != Runtime.PyMapping_HasKey(py_dict, namespaceKey.Handle))
                {
                    var pyNamespace = new PyObject(Runtime.PyDict_GetItem(py_dict, namespaceKey.Handle));
                    Runtime.XIncref(pyNamespace.Handle);
                    disposeList.Add(pyNamespace);
                    if (!Converter.ToManagedValue(pyNamespace.Handle, typeof(string), out namespaceStr, false))
                    {
                        throw new InvalidCastException("Couldn't convert __namespace__ value to string");
                    }
                }
            }
            finally
            {
                foreach (PyObject o in disposeList)
                {
                    o.Dispose();
                }
            }

            // create the new managed type subclassing the base managed type
            var baseClass = ManagedType.GetManagedObject(py_base_type) as ClassBase;

            if (null == baseClass)
            {
                return(Exceptions.RaiseTypeError("invalid base class, expected CLR class type"));
            }

            try
            {
                Type subType = ClassDerivedObject.CreateDerivedType(name,
                                                                    baseClass.type,
                                                                    py_dict,
                                                                    (string)namespaceStr,
                                                                    (string)assembly);

                // create the new ManagedType and python type
                ClassBase subClass = ClassManager.GetClass(subType);
                IntPtr    py_type  = GetTypeHandle(subClass, subType);

                // by default the class dict will have all the C# methods in it, but as this is a
                // derived class we want the python overrides in there instead if they exist.
                IntPtr cls_dict = Marshal.ReadIntPtr(py_type, TypeOffset.tp_dict);
                Runtime.PyDict_Update(cls_dict, py_dict);

                return(py_type);
            }
            catch (Exception e)
            {
                return(Exceptions.RaiseTypeError(e.Message));
            }
        }
예제 #59
0
 public override bool TryUnaryOperation(UnaryOperationBinder binder, out Object result)
 {
     int r;
     IntPtr res;
     switch (binder.Operation)
     {
     case ExpressionType.Negate:
         res = Runtime.PyNumber_Negative(this.obj);
         break;
     case ExpressionType.UnaryPlus:
         res = Runtime.PyNumber_Positive(this.obj);
         break;
     case ExpressionType.OnesComplement:
         res = Runtime.PyNumber_Invert(this.obj);
         break;
     case ExpressionType.Not:
         r = Runtime.PyObject_Not(this.obj);
         result = r == 1;
         return r != -1;
     case ExpressionType.IsFalse:
         r = Runtime.PyObject_IsTrue(this.obj);
         result = r == 0;
         return r != -1;
     case ExpressionType.IsTrue:
         r = Runtime.PyObject_IsTrue(this.obj);
         result = r == 1;
         return r != -1;
     case ExpressionType.Decrement:
     case ExpressionType.Increment:
     default:
         result = null;
         return false;
     }
     result = new PyObject(res);
     return true;
 }
예제 #60
0
파일: PyType.cs 프로젝트: mcneel/pythonnet
 /// <summary>Wraps an existing type object.</summary>
 public PyType(PyObject o) : base(FromObject(o))
 {
 }