[2.7] bpo-36126: Fix ref count leakage in structseq_repr by zasdfgbnm · Pull Request #12035 · python/cpython

Not sure if I need to open an issue for this one line fix.

This fixes the ref count leakage of structseq_repr on Python 2.7. To reproduce the bug, create a new project:

# coding=utf8
# this example is modified from https://gist.github.com/saghul/2473614

from distutils.core import setup, Extension

setup(name             = "foo",
      version          = "0.0.1",
      author           = "Saúl Ibarra Corretgé",
      author_email     = "saghul@gmail.com",
      description      = "PyStructSequence example",
      ext_modules      = [Extension('foo',
                                sources = ['test_pystructsequence.c'],
                         )]
     )
#include "Python.h"
#include "structmember.h"
#include "structseq.h"

static PyTypeObject FooResultType = {0, 0, 0, 0, 0, 0};

static PyStructSequence_Field foo_result_fields[] = {
    {"field_1", "This is field 1"},
    {"field_2", "This is field 2"},
    {"field_3", "This is field 3"},
    {NULL}
};

static PyStructSequence_Desc foo_result_desc = {
    "foo_result",
    NULL,
    foo_result_fields,
    3
};

#if PY_MAJOR_VERSION >= 3
static struct PyModuleDef moduledef = {
        PyModuleDef_HEAD_INIT,
        "foo",
        NULL,
        0,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL
};

PyMODINIT_FUNC
PyInit_foo(void)
#else
initfoo(void)
#endif
{
#if PY_MAJOR_VERSION >= 3
    PyObject *foo = PyModule_Create(&moduledef);
#else
    PyObject *foo = Py_InitModule("foo", NULL);
#endif

    if (FooResultType.tp_name == 0)
        PyStructSequence_InitType(&FooResultType, &foo_result_desc);
    Py_INCREF((PyObject *) &FooResultType);
    PyModule_AddObject(foo, "foo_result", (PyObject *) &FooResultType);

    // create a new object
    PyObject* obj = PyStructSequence_New(&FooResultType);
    Py_INCREF(obj);
    PyStructSequence_SET_ITEM(obj, 0, Py_None);
    PyStructSequence_SET_ITEM(obj, 1, Py_None);
    PyStructSequence_SET_ITEM(obj, 2, Py_None);
    PyModule_AddObject(foo, "obj", obj);

    FooResultType.tp_members[1].name = NULL;

#if PY_MAJOR_VERSION >= 3
    return foo;
#endif
}