[Zope-Checkins] CVS: Zope/lib/python/ExtensionClass -
ExtensionClass.h:1.1.2.4 _ExtensionClass.c:1.1.2.4 tests.py:1.1.2.3
Jim Fulton
cvs-admin at zope.org
Wed Oct 29 06:09:18 EST 2003
Update of /cvs-repository/Zope/lib/python/ExtensionClass
In directory cvs.zope.org:/tmp/cvs-serv31621
Modified Files:
Tag: zodb33-devel-branch
ExtensionClass.h _ExtensionClass.c tests.py
Log Message:
allowe setting attributes of extension types if the attributes don't
seem to be slots.
=== Zope/lib/python/ExtensionClass/ExtensionClass.h 1.1.2.3 => 1.1.2.4 ===
--- Zope/lib/python/ExtensionClass/ExtensionClass.h:1.1.2.3 Tue Oct 28 13:46:51 2003
+++ Zope/lib/python/ExtensionClass/ExtensionClass.h Wed Oct 29 06:09:17 2003
@@ -175,7 +175,7 @@
/* The following macro checks whether a type is an extension class: */
#define PyExtensionClass_Check(TYPE) \
- ((PyObject*)(TYPE)->ob_type == ECExtensionClassType)
+ (((PyObject*)(TYPE))->ob_type == ECExtensionClassType)
/* The following macro checks whether an instance is an extension instance: */
#define PyExtensionInstance_Check(INST) \
=== Zope/lib/python/ExtensionClass/_ExtensionClass.c 1.1.2.3 => 1.1.2.4 ===
--- Zope/lib/python/ExtensionClass/_ExtensionClass.c:1.1.2.3 Tue Oct 28 13:46:51 2003
+++ Zope/lib/python/ExtensionClass/_ExtensionClass.c Wed Oct 29 06:09:17 2003
@@ -551,6 +551,55 @@
return 0;
}
+static int
+EC_setattro(PyTypeObject *type, PyObject *name, PyObject *value)
+{
+ /* We want to allow setting attributes of builti-in types, because
+ EC did in the past and there's code that relies on it.
+
+ We can't really set slots though, but I don't think we need to.
+ There's no good way to spot slots. We could use a lame rule like
+ names that begin and end with __s and have just 4 _s smell too
+ much like slots.
+
+
+ */
+ if (! (type->tp_flags & Py_TPFLAGS_HEAPTYPE))
+ {
+ char *cname;
+ int l;
+
+ cname = PyString_AsString(name);
+ if (cname == NULL)
+ return -1;
+ l = PyString_GET_SIZE(name);
+ if (l > 4
+ && cname[0] == '_' && cname[1] == '_'
+ && cname[l-1] == '_' && cname[l-2] == '_'
+ )
+ {
+ char *c;
+
+ c = strchr(cname+2, '_');
+ if (c != NULL && (c - cname) >= (l-2))
+ {
+ PyErr_Format
+ (PyExc_TypeError,
+ "can't set attributes of built-in/extension type '%s' if the "
+ "attribute name begins and ends with __ and contains only "
+ "4 _ characters",
+ type->tp_name
+ );
+ return -1;
+ }
+ }
+
+ return PyObject_GenericSetAttr(OBJECT(type), name, value);
+ }
+ return PyType_Type.tp_setattro(OBJECT(type), name, value);
+}
+
+
static PyObject *
inheritedAttribute(PyTypeObject *self, PyObject *name)
{
@@ -604,7 +653,7 @@
/* tp_call */ (ternaryfunc)0,
/* tp_str */ (reprfunc)0,
/* tp_getattro */ (getattrofunc)0,
- /* tp_setattro */ (setattrofunc)0,
+ /* tp_setattro */ (setattrofunc)EC_setattro,
/* tp_as_buffer */ 0,
/* tp_flags */ Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
@@ -660,7 +709,7 @@
}
static PyObject *
-ec_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+ec_new_for_custom_dealloc(PyTypeObject *type, PyObject *args, PyObject *kw)
{
/* This is for EC's that have deallocs. For these, we need to
incref the type when we create an instance, because the deallocs
@@ -748,7 +797,7 @@
| Py_TPFLAGS_BASETYPE;
if (typ->tp_dealloc != NULL)
- typ->tp_new = ec_new;
+ typ->tp_new = ec_new_for_custom_dealloc;
}
typ->ob_type = ECExtensionClassType;
=== Zope/lib/python/ExtensionClass/tests.py 1.1.2.2 => 1.1.2.3 ===
--- Zope/lib/python/ExtensionClass/tests.py:1.1.2.2 Tue Oct 28 13:46:51 2003
+++ Zope/lib/python/ExtensionClass/tests.py Wed Oct 29 06:09:17 2003
@@ -375,7 +375,49 @@
"""
+def test_setattr_on_extension_type():
+ """
+ >>> for name in 'x', '_x', 'x_', '__x_y__', '___x__', '__x___', '_x_':
+ ... setattr(Base, name, 1)
+ ... print getattr(Base, name)
+ ... delattr(Base, name)
+ ... print getattr(Base, name, 0)
+ 1
+ 0
+ 1
+ 0
+ 1
+ 0
+ 1
+ 0
+ 1
+ 0
+ 1
+ 0
+ 1
+ 0
+ >>> Base.__foo__ = 1
+ Traceback (most recent call last):
+ ...
+ TypeError: can't set attributes of built-in/extension type """ \
+ """'ExtensionClass.Base' if the attribute name begins """ \
+ """and ends with __ and contains only 4 _ characters
+
+ >>> Base.__foo__
+ Traceback (most recent call last):
+ ...
+ AttributeError: type object 'ExtensionClass.Base' """ \
+ """has no attribute '__foo__'
+
+ >>> del Base.__foo__
+ Traceback (most recent call last):
+ ...
+ TypeError: can't set attributes of built-in/extension type """ \
+ """'ExtensionClass.Base' if the attribute name begins """ \
+ """and ends with __ and contains only 4 _ characters
+
+ """
from doctest import DocTestSuite
More information about the Zope-Checkins
mailing list