[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/patstew/pythonnet/python3/src/runtime/pythonexception.cs [Back]  [Original]

// ==========================================================================
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.
// ==========================================================================

using System;

namespace Python.Runtime {

    /// 
    /// Provides a managed interface to exceptions thrown by the Python 
    /// runtime.
    /// 

    public class PythonException : System.Exception {

    private IntPtr _pyType = IntPtr.Zero;
    private IntPtr _pyValue = IntPtr.Zero;
    private IntPtr _pyTB = IntPtr.Zero;
    private string _tb = "";
    private string _message = "";
    private bool disposed = false;

    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;
            using (PyObject pyType = new PyObject(_pyType)) {
                type = pyType.GetAttr("__name__").ToString();
            }
            string message = Runtime.GetManagedString(_pyValue);
            _message = type + " : " + message;
        }
        if (_pyTB != IntPtr.Zero)
        {
            PyObject tb_module = PythonEngine.ImportModule("traceback");
            using (PyObject pyTB = new PyObject(_pyTB)) {
                _tb = tb_module.InvokeMethod("format_tb", pyTB).ToString();
            }
        }
        PythonEngine.ReleaseLock(gs);
    }

    // Ensure that encapsulated Python objects are decref'ed appropriately
    // when the managed exception wrapper is garbage-collected.

    ~PythonException() {
        Dispose();
    }

    /// 
    /// Restores python error.
    /// 
    public void Restore()
    {
        IntPtr gs = PythonEngine.AcquireLock();
        Runtime.PyErr_Restore(_pyType, _pyValue, _pyTB);
        _pyType = IntPtr.Zero;
        _pyValue = IntPtr.Zero;
        _pyTB = IntPtr.Zero;
        PythonEngine.ReleaseLock(gs);
    }

    /// 
    /// PyType Property
    /// 
    ///
    /// 
    /// Returns the exception type as a Python object.
    /// 

    public IntPtr PyType 
    {
        get { return _pyType; }
    }

    /// 
    /// PyValue Property
    /// 
    ///
    /// 
    /// Returns the exception value as a Python object.
    /// 

    public IntPtr PyValue
    {
        get { return _pyValue; }
    }

    /// 
    /// Message Property
    /// 
    ///
    /// 
    /// A string representing the python exception message.
    /// 

    public override string Message
    {
        get { return _message; }
    }

    /// 
    /// StackTrace Property
    /// 
    ///
    /// 
    /// A string representing the python exception stack trace.
    /// 

    public override string StackTrace 
    {
        get { return _tb; }
    }


    /// 
    /// Dispose Method
    /// 
    ///
    /// 
    /// The Dispose method provides a way to explicitly release the 
    /// Python objects represented by a PythonException.
    /// 

    public void Dispose() {
        if (!disposed) {
        if (Runtime.Py_IsInitialized() > 0) {
            IntPtr gs = PythonEngine.AcquireLock();
            Runtime.Decref(_pyType);
            Runtime.Decref(_pyValue);
            // XXX Do we ever get TraceBack? //
            if (_pyTB != IntPtr.Zero) {
                Runtime.Decref(_pyTB);
            }
            PythonEngine.ReleaseLock(gs);
        }
        GC.SuppressFinalize(this);
        disposed = true;
        }
    }

    /// 
    /// Matches Method
    /// 
    ///
    /// 
    /// Returns true if the Python exception type represented by the 
    /// PythonException instance matches the given exception type.
    /// 

    public static bool Matches(IntPtr ob) {
        return Runtime.PyErr_ExceptionMatches(ob) != 0;
    }

    } 
}

Web Proxy Viewer  |  New URL  |  Original Page