summaryrefslogtreecommitdiffstats
path: root/Objects/classobject.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2002-08-19 21:43:18 (GMT)
committerGuido van Rossum <guido@python.org>2002-08-19 21:43:18 (GMT)
commit45ec02aed14685c353e55841b5acbc0dadee76f8 (patch)
tree0c146fdf0d488f279f0baf64b0f1fa0484274a73 /Objects/classobject.c
parentd8dbf847b6a819ef73d7bf0c05eafbdb9aee9956 (diff)
downloadcpython-45ec02aed14685c353e55841b5acbc0dadee76f8.zip
cpython-45ec02aed14685c353e55841b5acbc0dadee76f8.tar.gz
cpython-45ec02aed14685c353e55841b5acbc0dadee76f8.tar.bz2
SF patch 576101, by Oren Tirosh: alternative implementation of
interning. I modified Oren's patch significantly, but the basic idea and most of the implementation is unchanged. Interned strings created with PyString_InternInPlace() are now mortal, and you must keep a reference to the resulting string around; use the new function PyString_InternImmortal() to create immortal interned strings.
Diffstat (limited to 'Objects/classobject.c')
-rw-r--r--Objects/classobject.c44
1 files changed, 24 insertions, 20 deletions
diff --git a/Objects/classobject.c b/Objects/classobject.c
index 32e8d2a..cbbb3c4 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -2300,37 +2300,38 @@ instancemethod_traverse(PyMethodObject *im, visitproc visit, void *arg)
return 0;
}
-static char *
-getclassname(PyObject *class)
+static void
+getclassname(PyObject *class, char *buf, int bufsize)
{
PyObject *name;
+ assert(bufsize > 1);
+ strcpy(buf, "?"); /* Default outcome */
if (class == NULL)
- name = NULL;
- else
- name = PyObject_GetAttrString(class, "__name__");
+ return;
+ name = PyObject_GetAttrString(class, "__name__");
if (name == NULL) {
/* This function cannot return an exception */
PyErr_Clear();
- return "?";
+ return;
}
- if (!PyString_Check(name)) {
- Py_DECREF(name);
- return "?";
+ if (PyString_Check(name)) {
+ strncpy(buf, PyString_AS_STRING(name), bufsize);
+ buf[bufsize-1] = '\0';
}
- PyString_InternInPlace(&name);
Py_DECREF(name);
- return PyString_AS_STRING(name);
}
-static char *
-getinstclassname(PyObject *inst)
+static void
+getinstclassname(PyObject *inst, char *buf, int bufsize)
{
PyObject *class;
- char *name;
- if (inst == NULL)
- return "nothing";
+ if (inst == NULL) {
+ assert(bufsize > strlen("nothing"));
+ strcpy(buf, "nothing");
+ return;
+ }
class = PyObject_GetAttrString(inst, "__class__");
if (class == NULL) {
@@ -2339,9 +2340,8 @@ getinstclassname(PyObject *inst)
class = (PyObject *)(inst->ob_type);
Py_INCREF(class);
}
- name = getclassname(class);
+ getclassname(class, buf, bufsize);
Py_XDECREF(class);
- return name;
}
static PyObject *
@@ -2366,14 +2366,18 @@ instancemethod_call(PyObject *func, PyObject *arg, PyObject *kw)
return NULL;
}
if (!ok) {
+ char clsbuf[256];
+ char instbuf[256];
+ getclassname(class, clsbuf, sizeof(clsbuf));
+ getinstclassname(self, instbuf, sizeof(instbuf));
PyErr_Format(PyExc_TypeError,
"unbound method %s%s must be called with "
"%s instance as first argument "
"(got %s%s instead)",
PyEval_GetFuncName(func),
PyEval_GetFuncDesc(func),
- getclassname(class),
- getinstclassname(self),
+ clsbuf,
+ instbuf,
self == NULL ? "" : " instance");
return NULL;
}