Managing ref-counting is a complex and error prone business. If you choose C++ to extend or embed Python, you can simply use a modification on std::auto_ptr. Instead of calling delete on the managed pointer, it will decref it.
So now you can do:
auto_pyptr pyHelloStr(PyStr_FromString("Hello World!"));
and forget about having to decref it altogether! Just like auto_ptr you can get the PyObject * with get(), release it from managed control with release(), and rebind it with reset(new_ptr). You can also incref it by calling inc(), but be cautious as you can easily create a leak by increfing once to much.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56  | /*
 * auto_pyptr.h
 *
 * Originally from
 * http://code.activestate.com/recipes/528875-automatic-ref-count-management-in-c-using-a-smart-/
 */
#ifndef AUTO_PYPTR_H_
#define AUTO_PYPTR_H_
#include <Python.h>
#include <memory>
typedef std::auto_ptr<PyObject> auto_pyptr_base;
/**
 * An auto_ptr that, instead of deleting, decrements the reference count
 * of a PyObject pointer.
 *
 * Make sure to only use this when you get a *new* reference (Py_INCREF or
 * getting the result of any function that says it returns a new reference
 * to a PyObject), NOT for "borrowed" references.
 */
class auto_pyptr : public auto_pyptr_base {
public:
    auto_pyptr(PyObject * obj = NULL) : auto_pyptr_base(obj) {
    }
    ~auto_pyptr() {
        reset();
    }
    void reset(PyObject * obj = NULL) {
        if(obj != get()) {
            PyObject * old = release(); // Avoid the delete call
            Py_XDECREF(old);
            auto_pyptr_base::reset(obj);
        }
    }
    void inc() {
        PyObject * ptr = get();
        if(ptr)
            Py_INCREF(ptr);
    }
    /*
     * Implement cast to PyObject pointer so you don't have to call var.get()
     * every time you use the object.
     *
     * You still have to use get() in certain cases, notably varargs
     * (i.e. "..."). GCC will warn you that this will abort at runtime.
     */
    operator PyObject*() {
        return this->get();
    }
};
#endif /* AUTO_PYPTR_H_ */
 | 
I forked this recipe to add a cast to PyObject *; this allows me to pass the pointer to other functions without calling get() every time.
If you think this is a bad idea for some reason (e.g. some way I'm likely to shoot myself in the foot), feel free to let me know.
Download
Copy to clipboard