void throwPythonException()
{
  PyObject* error = PyErr_Occurred(); // Borrowed reference
  if(error != NULL)
  {
    PyObject* ptype, * pvalue, * ptraceback;
    PyErr_Fetch(&ptype, &pvalue, &ptraceback);

    // Exception type
    PyObjectPtr pyexception = makePyObjectPtr(PyObject_GetAttrString(
        ptype, (char*)"__name__"));
    std::string type = PyString_AsString(pyexception.get());

    // Message
    PyObjectPtr pymessage = makePyObjectPtr(PyObject_Str(pvalue));
    std::string message = PyString_AsString(pymessage.get());

    // Traceback
    PyObjectPtr tracebackModule = makePyObjectPtr(PyImport_ImportModule("traceback"));
    std::string traceback;
    if (tracebackModule != NULL) {
        PyObjectPtr tbList = makePyObjectPtr(
            PyObject_CallMethod(
                tracebackModule.get(), (char*)"format_exception",
                (char*)"OOO", ptype, pvalue == NULL ? Py_None : pvalue,
                ptraceback == NULL ? Py_None : ptraceback));

        PyObjectPtr emptyString = makePyObjectPtr(PyString_FromString(""));
        PyObjectPtr strRetval = makePyObjectPtr(
            PyObject_CallMethod(emptyString.get(), (char*)"join", (char*)"O",
                                tbList.get()));

        traceback = PyString_AsString(strRetval.get());
    }
    else
    {
        traceback = "Empty traceback";
    }

    Py_XDECREF(ptype);
    Py_XDECREF(pvalue);
    Py_XDECREF(ptraceback);

    std::string error_message = "Python exception (" + type + "): " + message;
    if(traceback != (type + ": " + message + "\n"))
        error_message += "\n" + traceback;
    throw std::runtime_error(error_message);
  }
}
Esempio n. 2
0
static PyObject*
_BoundSignal_New( PyObject* owner, PyObject* objref )
{
    PyObjectPtr ownerptr( owner, true );
    PyObjectPtr objrefptr( objref, true );
    PyObjectPtr bsigptr;
    if( numfree > 0 )
    {
        PyObject* o = reinterpret_cast<PyObject*>( freelist[ --numfree ] );
        _Py_NewReference( o );
        bsigptr = o;
    }
    else
    {
        bsigptr = PyType_GenericAlloc( &BoundSignal_Type, 0 );
        if( !bsigptr )
            return 0;
    }
    BoundSignal* bsig = reinterpret_cast<BoundSignal*>( bsigptr.get() );
    bsig->owner = ownerptr.release();
    bsig->objref = objrefptr.release();
    return bsigptr.release();
}
Esempio n. 3
0
static PyObject*
_CAtom_unobserve_2( CAtom* self, PyObject* topic, PyObject* callback )
{
    if( PyString_Check( topic ) )
    {
        if( !self->unobserve( topic, callback ) )
            return 0;
    }
    else
    {
        PyObjectPtr iterator( PyObject_GetIter( topic ) );
        if( !iterator )
            return 0;
        PyObjectPtr topicptr;
        while( ( topicptr = PyIter_Next( iterator.get() ) ) )
        {
            if( !self->unobserve( topicptr.get(), callback ) )
                return 0;
        }
        if( PyErr_Occurred() )
            return 0;
    }
    Py_RETURN_NONE;
}
 const unsigned size() { return PyTuple_Size(obj.get()); }
 const int ndim() { return PyArray_NDIM(obj.get()); }
Esempio n. 6
0
static int
slot_handler( Member* member, CAtom* atom, PyObject* value )
{
    if( member->index >= atom->get_slot_count() )
    {
        py_no_attr_fail( pyobject_cast( atom ), (char *)Py23Str_AS_STRING( member->name ) );
        return -1;
    }
    if( atom->is_frozen() )
    {
        PyErr_SetString( PyExc_AttributeError, "can't set attribute of frozen Atom" );
        return -1;
    }
    PyObjectPtr oldptr( atom->get_slot( member->index ) );
    PyObjectPtr newptr( newref( value ) );
    if( oldptr == newptr )
        return 0;
    bool valid_old = oldptr.get() != 0;
    if( !valid_old )
        oldptr.set( newref( Py_None ) );
    newptr = member->full_validate( atom, oldptr.get(), newptr.get() );
    if( !newptr )
        return -1;
    atom->set_slot( member->index, newptr.get() );
    if( member->get_post_setattr_mode() )
    {
        if( member->post_setattr( atom, oldptr.get(), newptr.get() ) < 0 )
            return -1;
    }
    if( ( !valid_old || oldptr != newptr ) && atom->get_notifications_enabled() )
    {
        PyObjectPtr argsptr;
        if( member->has_observers() )
        {
            if( valid_old && oldptr.richcompare( newptr, Py_EQ ) )
                return 0;
            if( valid_old )
                argsptr = updated_args( atom, member, oldptr.get(), newptr.get() );
            else
                argsptr = created_args( atom, member, newptr.get() );
            if( !argsptr )
                return -1;
            if( !member->notify( atom, argsptr.get(), 0 ) )
                return -1;
        }
        if( atom->has_observers( member->name ) )
        {
            if( !argsptr )
            {
                if( valid_old && oldptr.richcompare( newptr, Py_EQ ) )
                    return 0;
                if( valid_old )
                    argsptr = updated_args( atom, member, oldptr.get(), newptr.get() );
                else
                    argsptr = created_args( atom, member, newptr.get() );
                if( !argsptr )
                    return -1;
            }
            if( !atom->notify( member->name, argsptr.get(), 0 ) )
                return -1;
        }
    }
    return 0;
}
 const bool get() { return (bool)PyObject_IsTrue(obj.get()); }
 const std::string get() { return PyString_AsString(obj.get()); }
 const double get() { return (int)PyInt_AsLong(obj.get()); }
 const double get() { return PyFloat_AsDouble(obj.get()); }
Esempio n. 11
0
static PyObject*
load_dynamic_attr( PyObject* obj, PyObject* name, PyObject* tracer=0 )
{
    PyTypeObject* tp;
    PyObject** dictptr;
    PyObjectPtr descr;
    descrgetfunc descr_f;
    PyObjectPtr objptr( newref( obj ) );

    // The body of this loop is PyObject_GenericGetAttr, modified to
    // use smart pointers and _PyObject_GetDictPtr, and run a tracer.
    while( objptr.get() != Py_None )
    {
        tp = Py_TYPE( objptr.get() );

        // Data descriptor
        descr_f = 0;
        descr = xnewref( _PyType_Lookup( tp, name ) );
        if( descr && PyType_HasFeature( descr.get()->ob_type, Py_TPFLAGS_HAVE_CLASS ) )
        {
            descr_f = descr.get()->ob_type->tp_descr_get;
            if( descr_f && PyDescr_IsData( descr.get() ) )
            {
                PyObjectPtr res(
                    descr_f( descr.get(), objptr.get(), pyobject_cast( tp ) )
                );
                if( !res )
                    maybe_translate_key_error();
                else if( tracer && !run_tracer( tracer, objptr.get(), name, res.get() ) )
                    return 0;
                return res.release();
            }
        }

        // Instance dictionary
        dictptr = _PyObject_GetDictPtr( objptr.get() );
        if( dictptr && *dictptr )
        {
            PyObject* item = PyDict_GetItem( *dictptr, name );
            if( item )
            {
                if( tracer && !run_tracer( tracer, objptr.get(), name, item ) )
                    return 0;
                return newref( item );
            }
        }

        // Non-data descriptor
        if( descr_f )
        {
            PyObjectPtr res(
                descr_f( descr.get(), objptr.get(), pyobject_cast( tp ) )
            );
            if( !res )
                maybe_translate_key_error();
            else if( tracer && !run_tracer( tracer, objptr.get(), name, res.get() ) )
                return 0;
            return res.release();
        }

        // Non-readable descriptor
        if( descr )
        {
            if( tracer && !run_tracer( tracer, objptr.get(), name, descr.get() ) )
                return 0;
            return descr.release();
        }

        // Step up to the parent object
        objptr = PyObject_GetAttr( objptr.get(), parent_str );
        if( !objptr )
            return 0;
    }

    return 0;
}
 const unsigned size() { return PyArray_Size(obj.get()); }
 static const bool check(PyObjectPtr obj) { return PyTuple_Check(obj.get()); }
 bool append(PyObjectPtr item) { return PyList_Append(obj.get(), item.get()) == 0; }
 const unsigned size() { return PyList_Size(obj.get()); }
 const double get(unsigned i) { return *((double*)PyArray_GETPTR1(obj.get(), (npy_intp)i)); }
 const bool isDouble() { return PyArray_TYPE(obj.get()) == NPY_DOUBLE; }
Esempio n. 18
0
static int
set_dynamic_attr( PyObject* obj, PyObject* name, PyObject* value )
{
    PyTypeObject* tp;
    PyObject* dict;
    PyObject** dictptr;
    PyObjectPtr descr;
    descrsetfunc descr_f;
    PyObjectPtr objptr( newref( obj ) );

    // The body of this loop is PyObject_GenericGetAttr, modified to
    // use smart pointers.
    while( objptr.get() != Py_None )
    {
        tp = Py_TYPE( objptr.get() );

        // Data desciptor
        descr_f = 0;
        descr = xnewref( _PyType_Lookup( tp, name ) );
        if( descr && PyType_HasFeature( descr.get()->ob_type, Py_TPFLAGS_HAVE_CLASS ) )
        {
            descr_f = descr.get()->ob_type->tp_descr_set;
            if( descr_f && PyDescr_IsData( descr.get() ) )
                return descr_f( descr.get(), objptr.get(), value );
        }

        // Instance dictionary
        dict = 0;
        dictptr = _PyObject_GetDictPtr( obj );
        if( dictptr )
        {
            dict = *dictptr;
            if( !dict && value )
            {
                dict = PyDict_New();
                if( !dict )
                    return -1;
                *dictptr = dict;
            }
        }
        if( dict )
        {
            if( value )
                return PyDict_SetItem( dict, name, value );
            if( PyDict_DelItem( dict, name ) == 0 )
                return 0;
            if( !PyErr_ExceptionMatches( PyExc_KeyError ) )
                return -1;
            PyErr_Clear();
        }

        // Non-data descriptor
        if( descr_f )
            return descr_f( descr.get(), objptr.get(), value );

        // Read-only descriptor
        if( descr )
            PyErr_Format(
                PyExc_AttributeError,
                "'%.50s' object attribute '%.400s' is read-only",
                tp->tp_name, PyString_AS_STRING( name )
            );

        // Step up to the parent object
        objptr = PyObject_GetAttr( objptr.get(), parent_str );
        if( !objptr )
            return -1;
    }

    return -1;
}
 const bool isDouble(unsigned i) { return PyFloat_Check(PyTuple_GetItem(obj.get(), i)); }