[Python-checkins] CVS: python/dist/src/Objects funcobject.c,2.42,2.43
Guido van Rossum
gvanrossum@users.sourceforge.net
Mon, 17 Sep 2001 16:46:58 -0700
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv25161/Objects
Modified Files:
funcobject.c
Log Message:
Rewrite function attributes to use the generic routines properly.
This uses the new "restricted" feature of structmember, and getset
descriptors for some of the type checks.
Index: funcobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/funcobject.c,v
retrieving revision 2.42
retrieving revision 2.43
diff -C2 -d -r2.42 -r2.43
*** funcobject.c 2001/08/29 23:52:31 2.42
--- funcobject.c 2001/09/17 23:46:56 2.43
***************
*** 128,224 ****
#define OFF(x) offsetof(PyFunctionObject, x)
static struct memberlist func_memberlist[] = {
! {"func_code", T_OBJECT, OFF(func_code)},
! {"func_globals", T_OBJECT, OFF(func_globals), READONLY},
{"func_name", T_OBJECT, OFF(func_name), READONLY},
{"__name__", T_OBJECT, OFF(func_name), READONLY},
- {"func_closure", T_OBJECT, OFF(func_closure), READONLY},
- {"func_defaults", T_OBJECT, OFF(func_defaults)},
- {"func_doc", T_OBJECT, OFF(func_doc)},
- {"__doc__", T_OBJECT, OFF(func_doc)},
- {"func_dict", T_OBJECT, OFF(func_dict)},
- {"__dict__", T_OBJECT, OFF(func_dict)},
{NULL} /* Sentinel */
};
static PyObject *
! func_getattro(PyObject *op, PyObject *name)
{
! char *sname = PyString_AsString(name);
!
! if (sname[0] != '_' && PyEval_GetRestricted()) {
! PyErr_SetString(PyExc_RuntimeError,
! "function attributes not accessible in restricted mode");
return NULL;
! }
! /* If func_dict is being accessed but no attribute has been set
! * yet, then initialize it to the empty dictionary.
! */
! if ((!strcmp(sname, "func_dict") || !strcmp(sname, "__dict__"))
! && ((PyFunctionObject*)op)->func_dict == NULL)
! {
! PyFunctionObject* funcop = (PyFunctionObject*)op;
!
! funcop->func_dict = PyDict_New();
! if (funcop->func_dict == NULL)
return NULL;
}
! return PyObject_GenericGetAttr(op, name);
}
static int
! func_setattro(PyObject *op, PyObject *name, PyObject *value)
{
! char *sname = PyString_AsString(name);
! if (PyEval_GetRestricted()) {
! PyErr_SetString(PyExc_RuntimeError,
! "function attributes not settable in restricted mode");
return -1;
}
! if (strcmp(sname, "func_code") == 0) {
! /* not legal to del f.func_code or to set it to anything
! * other than a code object.
! */
! if (value == NULL || !PyCode_Check(value)) {
! PyErr_SetString(
! PyExc_TypeError,
"func_code must be set to a code object");
! return -1;
! }
}
! else if (strcmp(sname, "func_defaults") == 0) {
! /* legal to del f.func_defaults. Can only set
! * func_defaults to NULL or a tuple.
! */
! if (value == Py_None)
! value = NULL;
! if (value != NULL && !PyTuple_Check(value)) {
! PyErr_SetString(
! PyExc_TypeError,
! "func_defaults must be set to a tuple object");
! return -1;
! }
}
! else if (!strcmp(sname, "func_dict") || !strcmp(sname, "__dict__")) {
! /* It is illegal to del f.func_dict. Can only set
! * func_dict to a dictionary.
! */
! if (value == NULL) {
! PyErr_SetString(
! PyExc_TypeError,
! "function's dictionary may not be deleted");
! return -1;
! }
! if (!PyDict_Check(value)) {
! PyErr_SetString(
! PyExc_TypeError,
! "setting function's dictionary to a non-dict");
! return -1;
! }
}
! return PyObject_GenericSetAttr(op, name, value);
}
static void
func_dealloc(PyFunctionObject *op)
--- 128,270 ----
#define OFF(x) offsetof(PyFunctionObject, x)
+ #define RR ()
+
static struct memberlist func_memberlist[] = {
! {"func_closure", T_OBJECT, OFF(func_closure),
! RESTRICTED|READONLY},
! {"func_doc", T_OBJECT, OFF(func_doc), WRITE_RESTRICTED},
! {"__doc__", T_OBJECT, OFF(func_doc), WRITE_RESTRICTED},
! {"func_globals", T_OBJECT, OFF(func_globals),
! RESTRICTED|READONLY},
{"func_name", T_OBJECT, OFF(func_name), READONLY},
{"__name__", T_OBJECT, OFF(func_name), READONLY},
{NULL} /* Sentinel */
};
+ static int
+ restricted(void)
+ {
+ if (!PyEval_GetRestricted())
+ return 0;
+ PyErr_SetString(PyExc_RuntimeError,
+ "function attributes not accessible in restricted mode");
+ return 1;
+ }
+
static PyObject *
! func_get_dict(PyFunctionObject *op)
{
! if (restricted())
return NULL;
! if (op->func_dict == NULL) {
! op->func_dict = PyDict_New();
! if (op->func_dict == NULL)
return NULL;
}
! Py_INCREF(op->func_dict);
! return op->func_dict;
}
static int
! func_set_dict(PyFunctionObject *op, PyObject *value)
{
! PyObject *tmp;
! if (restricted())
! return -1;
! /* It is illegal to del f.func_dict */
! if (value == NULL) {
! PyErr_SetString(PyExc_TypeError,
! "function's dictionary may not be deleted");
return -1;
}
! /* Can only set func_dict to a dictionary */
! if (!PyDict_Check(value)) {
! PyErr_SetString(PyExc_TypeError,
! "setting function's dictionary to a non-dict");
! return -1;
! }
! tmp = op->func_dict;
! Py_INCREF(value);
! op->func_dict = value;
! Py_XDECREF(tmp);
! return 0;
! }
!
! static PyObject *
! func_get_code(PyFunctionObject *op)
! {
! if (restricted())
! return NULL;
! Py_INCREF(op->func_code);
! return op->func_code;
! }
!
! static int
! func_set_code(PyFunctionObject *op, PyObject *value)
! {
! PyObject *tmp;
!
! if (restricted())
! return -1;
! /* Not legal to del f.func_code or to set it to anything
! * other than a code object. */
! if (value == NULL || !PyCode_Check(value)) {
! PyErr_SetString(PyExc_TypeError,
"func_code must be set to a code object");
! return -1;
}
! tmp = op->func_code;
! Py_INCREF(value);
! op->func_code = value;
! Py_DECREF(tmp);
! return 0;
! }
!
! static PyObject *
! func_get_defaults(PyFunctionObject *op)
! {
! if (restricted())
! return NULL;
! if (op->func_defaults == NULL) {
! Py_INCREF(Py_None);
! return Py_None;
}
! Py_INCREF(op->func_defaults);
! return op->func_defaults;
! }
!
! static int
! func_set_defaults(PyFunctionObject *op, PyObject *value)
! {
! PyObject *tmp;
!
! if (restricted())
! return -1;
! /* Legal to del f.func_defaults.
! * Can only set func_defaults to NULL or a tuple. */
! if (value == Py_None)
! value = NULL;
! if (value != NULL && !PyTuple_Check(value)) {
! PyErr_SetString(PyExc_TypeError,
! "func_defaults must be set to a tuple object");
! return -1;
}
! tmp = op->func_defaults;
! Py_XINCREF(value);
! op->func_defaults = value;
! Py_XDECREF(tmp);
! return 0;
}
+ static struct getsetlist func_getsetlist[] = {
+ {"func_code", (getter)func_get_code, (setter)func_set_code},
+ {"func_defaults", (getter)func_get_defaults,
+ (setter)func_set_defaults},
+ {"func_dict", (getter)func_get_dict, (setter)func_set_dict},
+ {"__dict__", (getter)func_get_dict, (setter)func_set_dict},
+ {NULL} /* Sentinel */
+ };
+
static void
func_dealloc(PyFunctionObject *op)
***************
*** 366,371 ****
function_call, /* tp_call */
0, /* tp_str */
! func_getattro, /* tp_getattro */
! func_setattro, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
--- 412,417 ----
function_call, /* tp_call */
0, /* tp_str */
! PyObject_GenericGetAttr, /* tp_getattro */
! PyObject_GenericSetAttr, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
***************
*** 379,383 ****
0, /* tp_methods */
func_memberlist, /* tp_members */
! 0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
--- 425,429 ----
0, /* tp_methods */
func_memberlist, /* tp_members */
! func_getsetlist, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */