From ce358e3015bc8cafdf949dee624b01f4a38bfad2 Mon Sep 17 00:00:00 2001 From: "Michael W. Hudson" Date: Wed, 6 Mar 2002 17:07:49 +0000 Subject: Apply (my) patch: [ 526072 ] pickling os.stat results round II structseq's constructors can now take "invisible" fields in a dict. Gave the constructors better error messages. their __reduce__ method puts these fields in a dict. (this is all in aid of getting os.stat_result's to pickle portably) Also fixes [ 526039 ] devious code can crash structseqs Thought needed about how much of this counts as a bugfix. Certainly #526039 needs to be fixed. --- Objects/structseq.c | 99 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 76 insertions(+), 23 deletions(-) diff --git a/Objects/structseq.c b/Objects/structseq.c index e5f8e09..9228e0f 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -84,39 +84,79 @@ static PyObject * structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *arg = NULL; + PyObject *dict = NULL; + PyObject *ob; PyStructSequence *res = NULL; - int len, required_len, i; - static char *kwlist[] = {"sequence", 0}; - static char msgbuf[128]; + int len, min_len, max_len, i; + static char *kwlist[] = {"sequence", "dict", 0}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:structseq", - kwlist, &arg)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:structseq", + kwlist, &arg, &dict)) return NULL; - if (!PySequence_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "constructor requires a sequence"); + arg = PySequence_Fast(arg, "constructor requires a sequence"); + + if (!arg) { return NULL; } - len = PySequence_Length(arg); - required_len = REAL_SIZE_TP(type); - if (len != required_len) { - PyOS_snprintf( - msgbuf, sizeof(msgbuf), - "constructor takes exactly %d arguments (%d given)", - required_len, - len); - PyErr_SetString(PyExc_TypeError, msgbuf); + 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); + + if (min_len != max_len) { + if (len < min_len) { + PyErr_Format(PyExc_TypeError, + "%.500s() takes an at least %d-sequence (%d-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 %d-sequence (%d-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 %d-sequence (%d-sequence given)", + type->tp_name, min_len, len); + Py_DECREF(arg); + return NULL; + } + } + res = (PyStructSequence*) PyStructSequence_New(type); for (i = 0; i < len; ++i) { - /* INCREF???? XXXX */ - res->ob_item[i] = PySequence_GetItem(arg, 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].name))) { + } + else { + ob = Py_None; + } + Py_INCREF(ob); + res->ob_item[i] = ob; } + Py_DECREF(arg); return (PyObject*) res; } @@ -192,21 +232,34 @@ static PyObject * structseq_reduce(PyStructSequence* self) { PyObject* tup; - long n_fields; + PyObject* dict; + long n_fields, n_visible_fields; int i; n_fields = REAL_SIZE(self); - tup = PyTuple_New(n_fields); + n_visible_fields = VISIBLE_SIZE(self); + tup = PyTuple_New(n_visible_fields); if (!tup) { return NULL; } - for (i = 0; i < n_fields; i++) { + 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]); } - return Py_BuildValue("(O(O))", self->ob_type, tup); + for (; i < n_fields; i++) { + PyDict_SetItemString(dict, self->ob_type->tp_members[i].name, + self->ob_item[i]); + } + + return Py_BuildValue("(O(OO))", self->ob_type, tup, dict); } static PySequenceMethods structseq_as_sequence = { -- cgit v0.12 /a> 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 57 58 59 60
/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

//! [0]
QGLPixelBuffer pbuffer(...);
...
pbuffer.makeCurrent();
GLuint dynamicTexture = pbuffer.generateDynamicTexture();
pbuffer.bindToDynamicTexture(dynamicTexture);
...
pbuffer.releaseFromDynamicTexture();
//! [0]


//! [1]
QGLPixelBuffer pbuffer(...);
...
pbuffer.makeCurrent();
GLuint dynamicTexture = pbuffer.generateDynamicTexture();
...
pbuffer.updateDynamicTexture(dynamicTexture);
//! [1]