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); } }
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(); }
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()); }
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()); }
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; }
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)); }