Back to index

python3.2  3.2.2
Defines | Functions | Variables
structseq.c File Reference
#include "Python.h"
#include "structmember.h"

Go to the source code of this file.

Defines

#define VISIBLE_SIZE(op)   Py_SIZE(op)
#define VISIBLE_SIZE_TP(tp)
#define REAL_SIZE_TP(tp)
#define REAL_SIZE(op)   REAL_SIZE_TP(Py_TYPE(op))
#define UNNAMED_FIELDS_TP(tp)
#define UNNAMED_FIELDS(op)   UNNAMED_FIELDS_TP(Py_TYPE(op))
#define REPR_BUFFER_SIZE   512
#define TYPE_MAXSIZE   100
#define SET_DICT_FROM_INT(key, value)

Functions

PyObjectPyStructSequence_New (PyTypeObject *type)
void PyStructSequence_SetItem (PyObject *op, Py_ssize_t i, PyObject *v)
PyObjectPyStructSequence_GetItem (PyObject *op, Py_ssize_t i)
static void structseq_dealloc (PyStructSequence *obj)
static PyObjectstructseq_new (PyTypeObject *type, PyObject *args, PyObject *kwds)
static PyObjectstructseq_repr (PyStructSequence *obj)
static PyObjectstructseq_reduce (PyStructSequence *self)
void PyStructSequence_InitType (PyTypeObject *type, PyStructSequence_Desc *desc)
PyTypeObjectPyStructSequence_NewType (PyStructSequence_Desc *desc)

Variables

static char visible_length_key [] = "n_sequence_fields"
static char real_length_key [] = "n_fields"
static char unnamed_fields_key [] = "n_unnamed_fields"
char * PyStructSequence_UnnamedField = "unnamed field"
static PyMethodDef structseq_methods []
static PyTypeObject _struct_sequence_template

Define Documentation

#define REAL_SIZE (   op)    REAL_SIZE_TP(Py_TYPE(op))

Definition at line 21 of file structseq.c.

#define REAL_SIZE_TP (   tp)
Value:

Definition at line 19 of file structseq.c.

#define REPR_BUFFER_SIZE   512
#define SET_DICT_FROM_INT (   key,
  value 
)
Value:
do {                                                        \
        PyObject *v = PyLong_FromLong((long) value);            \
        if (v != NULL) {                                        \
            PyDict_SetItemString(dict, key, v);                 \
            Py_DECREF(v);                                       \
        }                                                       \
    } while (0)
#define TYPE_MAXSIZE   100
#define UNNAMED_FIELDS (   op)    UNNAMED_FIELDS_TP(Py_TYPE(op))

Definition at line 25 of file structseq.c.

#define UNNAMED_FIELDS_TP (   tp)
Value:

Definition at line 23 of file structseq.c.

#define VISIBLE_SIZE (   op)    Py_SIZE(op)

Definition at line 15 of file structseq.c.

#define VISIBLE_SIZE_TP (   tp)
Value:

Definition at line 16 of file structseq.c.


Function Documentation

Definition at line 53 of file structseq.c.

{
    return PyStructSequence_GET_ITEM(op, i);
}

Definition at line 318 of file structseq.c.

{
    PyObject *dict;
    PyMemberDef* members;
    int n_members, n_unnamed_members, i, k;

#ifdef Py_TRACE_REFS
    /* if the type object was chained, unchain it first
       before overwriting its storage */
    if (type->ob_base.ob_base._ob_next) {
        _Py_ForgetReference((PyObject*)type);
    }
#endif

    n_unnamed_members = 0;
    for (i = 0; desc->fields[i].name != NULL; ++i)
        if (desc->fields[i].name == PyStructSequence_UnnamedField)
            n_unnamed_members++;
    n_members = i;

    memcpy(type, &_struct_sequence_template, sizeof(PyTypeObject));
    type->tp_base = &PyTuple_Type;
    type->tp_name = desc->name;
    type->tp_doc = desc->doc;

    members = PyMem_NEW(PyMemberDef, n_members-n_unnamed_members+1);
    if (members == NULL)
        return;

    for (i = k = 0; i < n_members; ++i) {
        if (desc->fields[i].name == PyStructSequence_UnnamedField)
            continue;
        members[k].name = desc->fields[i].name;
        members[k].type = T_OBJECT;
        members[k].offset = offsetof(PyStructSequence, ob_item)
          + i * sizeof(PyObject*);
        members[k].flags = READONLY;
        members[k].doc = desc->fields[i].doc;
        k++;
    }
    members[k].name = NULL;

    type->tp_members = members;

    if (PyType_Ready(type) < 0)
        return;
    Py_INCREF(type);

    dict = type->tp_dict;
#define SET_DICT_FROM_INT(key, value)                           \
    do {                                                        \
        PyObject *v = PyLong_FromLong((long) value);            \
        if (v != NULL) {                                        \
            PyDict_SetItemString(dict, key, v);                 \
            Py_DECREF(v);                                       \
        }                                                       \
    } while (0)

    SET_DICT_FROM_INT(visible_length_key, desc->n_in_sequence);
    SET_DICT_FROM_INT(real_length_key, n_members);
    SET_DICT_FROM_INT(unnamed_fields_key, n_unnamed_members);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 29 of file structseq.c.

{
    PyStructSequence *obj;
    Py_ssize_t size = REAL_SIZE_TP(type), i;

    obj = PyObject_GC_NewVar(PyStructSequence, type, size);
    if (obj == NULL)
        return NULL;
    /* Hack the size of the variable object, so invisible fields don't appear
     to Python code. */
    Py_SIZE(obj) = VISIBLE_SIZE_TP(type);
    for (i = 0; i < size; i++)
        obj->ob_item[i] = NULL;

    return (PyObject*)obj;
}

Here is the caller graph for this function:

Definition at line 382 of file structseq.c.

Here is the call graph for this function:

Definition at line 47 of file structseq.c.

static void structseq_dealloc ( PyStructSequence obj) [static]

Definition at line 59 of file structseq.c.

{
    Py_ssize_t i, size;
    
    size = REAL_SIZE(obj);
    for (i = 0; i < size; ++i) {
        Py_XDECREF(obj->ob_item[i]);
    }
    PyObject_GC_Del(obj);
}

Here is the call graph for this function:

static PyObject* structseq_new ( PyTypeObject type,
PyObject args,
PyObject kwds 
) [static]

Definition at line 71 of file structseq.c.

{
    PyObject *arg = NULL;
    PyObject *dict = NULL;
    PyObject *ob;
    PyStructSequence *res = NULL;
    Py_ssize_t len, min_len, max_len, i, n_unnamed_fields;
    static char *kwlist[] = {"sequence", "dict", 0};

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:structseq",
                                     kwlist, &arg, &dict))
        return NULL;

    arg = PySequence_Fast(arg, "constructor requires a sequence");

    if (!arg) {
        return NULL;
    }

    if (dict && !PyDict_Check(dict)) {
        PyErr_Format(PyExc_TypeError,
                     "%.500s() takes a dict as second arg, if any",
                     type->tp_name);
        Py_DECREF(arg);
        return NULL;
    }

    len = PySequence_Fast_GET_SIZE(arg);
    min_len = VISIBLE_SIZE_TP(type);
    max_len = REAL_SIZE_TP(type);
    n_unnamed_fields = UNNAMED_FIELDS_TP(type);

    if (min_len != max_len) {
        if (len < min_len) {
            PyErr_Format(PyExc_TypeError,
           "%.500s() takes an at least %zd-sequence (%zd-sequence given)",
                                 type->tp_name, min_len, len);
                    Py_DECREF(arg);
                    return NULL;
        }

        if (len > max_len) {
            PyErr_Format(PyExc_TypeError,
           "%.500s() takes an at most %zd-sequence (%zd-sequence given)",
                                 type->tp_name, max_len, len);
                    Py_DECREF(arg);
                    return NULL;
        }
    }
    else {
        if (len != min_len) {
            PyErr_Format(PyExc_TypeError,
           "%.500s() takes a %zd-sequence (%zd-sequence given)",
                                 type->tp_name, min_len, len);
                    Py_DECREF(arg);
                    return NULL;
        }
    }

    res = (PyStructSequence*) PyStructSequence_New(type);
    if (res == NULL) {
        return NULL;
    }
    for (i = 0; i < len; ++i) {
        PyObject *v = PySequence_Fast_GET_ITEM(arg, i);
        Py_INCREF(v);
        res->ob_item[i] = v;
    }
    for (; i < max_len; ++i) {
        if (dict && (ob = PyDict_GetItemString(
            dict, type->tp_members[i-n_unnamed_fields].name))) {
        }
        else {
            ob = Py_None;
        }
        Py_INCREF(ob);
        res->ob_item[i] = ob;
    }

    Py_DECREF(arg);
    return (PyObject*) res;
}

Here is the call graph for this function:

static PyObject* structseq_reduce ( PyStructSequence self) [static]

Definition at line 230 of file structseq.c.

{
    PyObject* tup;
    PyObject* dict;
    PyObject* result;
    Py_ssize_t n_fields, n_visible_fields, n_unnamed_fields;
    int i;

    n_fields = REAL_SIZE(self);
    n_visible_fields = VISIBLE_SIZE(self);
    n_unnamed_fields = UNNAMED_FIELDS(self);
    tup = PyTuple_New(n_visible_fields);
    if (!tup) {
        return NULL;
    }

    dict = PyDict_New();
    if (!dict) {
        Py_DECREF(tup);
        return NULL;
    }

    for (i = 0; i < n_visible_fields; i++) {
        Py_INCREF(self->ob_item[i]);
        PyTuple_SET_ITEM(tup, i, self->ob_item[i]);
    }

    for (; i < n_fields; i++) {
        char *n = Py_TYPE(self)->tp_members[i-n_unnamed_fields].name;
        PyDict_SetItemString(dict, n,
                             self->ob_item[i]);
    }

    result = Py_BuildValue("(O(OO))", Py_TYPE(self), tup, dict);

    Py_DECREF(tup);
    Py_DECREF(dict);

    return result;
}

Here is the call graph for this function:

static PyObject* structseq_repr ( PyStructSequence obj) [static]

Definition at line 156 of file structseq.c.

{
    /* buffer and type size were chosen well considered. */
#define REPR_BUFFER_SIZE 512
#define TYPE_MAXSIZE 100

    PyTypeObject *typ = Py_TYPE(obj);
    int i, removelast = 0;
    Py_ssize_t len;
    char buf[REPR_BUFFER_SIZE];
    char *endofbuf, *pbuf = buf;

    /* pointer to end of writeable buffer; safes space for "...)\0" */
    endofbuf= &buf[REPR_BUFFER_SIZE-5];

    /* "typename(", limited to  TYPE_MAXSIZE */
    len = strlen(typ->tp_name) > TYPE_MAXSIZE ? TYPE_MAXSIZE :
                            strlen(typ->tp_name);
    strncpy(pbuf, typ->tp_name, len);
    pbuf += len;
    *pbuf++ = '(';

    for (i=0; i < VISIBLE_SIZE(obj); i++) {
        PyObject *val, *repr;
        char *cname, *crepr;

        cname = typ->tp_members[i].name;
        if (cname == NULL) {
            PyErr_Format(PyExc_SystemError, "In structseq_repr(), member %d name is NULL"
                         " for type %.500s", i, typ->tp_name);
            return NULL;
        }
        val = PyStructSequence_GET_ITEM(obj, i);
        repr = PyObject_Repr(val);
        if (repr == NULL)
            return NULL;
        crepr = _PyUnicode_AsString(repr);
        if (crepr == NULL) {
            Py_DECREF(repr);
            return NULL;
        }

        /* + 3: keep space for "=" and ", " */
        len = strlen(cname) + strlen(crepr) + 3;
        if ((pbuf+len) <= endofbuf) {
            strcpy(pbuf, cname);
            pbuf += strlen(cname);
            *pbuf++ = '=';
            strcpy(pbuf, crepr);
            pbuf += strlen(crepr);
            *pbuf++ = ',';
            *pbuf++ = ' ';
            removelast = 1;
            Py_DECREF(repr);
        }
        else {
            strcpy(pbuf, "...");
            pbuf += 3;
            removelast = 0;
            Py_DECREF(repr);
            break;
        }
    }
    if (removelast) {
        /* overwrite last ", " */
        pbuf-=2;
    }
    *pbuf++ = ')';
    *pbuf = '\0';

    return PyUnicode_FromString(buf);
}

Here is the call graph for this function:


Variable Documentation

Definition at line 276 of file structseq.c.

char* PyStructSequence_UnnamedField = "unnamed field"

Definition at line 13 of file structseq.c.

char real_length_key[] = "n_fields" [static]

Definition at line 8 of file structseq.c.

Initial value:
 {
    {"__reduce__", (PyCFunction)structseq_reduce, METH_NOARGS, NULL},
    {NULL, NULL}
}

Definition at line 271 of file structseq.c.

char unnamed_fields_key[] = "n_unnamed_fields" [static]

Definition at line 9 of file structseq.c.

char visible_length_key[] = "n_sequence_fields" [static]

Definition at line 7 of file structseq.c.