summaryrefslogtreecommitdiffstats
path: root/Objects/classobject.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1991-10-20 20:11:48 (GMT)
committerGuido van Rossum <guido@python.org>1991-10-20 20:11:48 (GMT)
commit9430839accd5920b3a503a8ac02c5de1ae2449a8 (patch)
treee03f4df8f2e1de1187d91554c53a74c3b58ff3c4 /Objects/classobject.c
parentdc8a108a36a55b480e302c556c773a2de17ec76a (diff)
downloadcpython-9430839accd5920b3a503a8ac02c5de1ae2449a8.zip
cpython-9430839accd5920b3a503a8ac02c5de1ae2449a8.tar.gz
cpython-9430839accd5920b3a503a8ac02c5de1ae2449a8.tar.bz2
Add several secret __*__ attributes
Diffstat (limited to 'Objects/classobject.c')
-rw-r--r--Objects/classobject.c59
1 files changed, 50 insertions, 9 deletions
diff --git a/Objects/classobject.c b/Objects/classobject.c
index 6b38dfc..ad4f627 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -32,22 +32,25 @@ typedef struct {
OB_HEAD
object *cl_bases; /* A tuple */
object *cl_methods; /* A dictionary */
+ object *cl_name; /* A string */
} classobject;
object *
-newclassobject(bases, methods)
+newclassobject(bases, methods, name)
object *bases; /* NULL or tuple of classobjects! */
object *methods;
+ object *name; /* String; NULL if unknown */
{
classobject *op;
op = NEWOBJ(classobject, &Classtype);
if (op == NULL)
return NULL;
- if (bases != NULL)
- INCREF(bases);
+ XINCREF(bases);
op->cl_bases = bases;
INCREF(methods);
op->cl_methods = methods;
+ XINCREF(name);
+ op->cl_name = name;
return (object *) op;
}
@@ -58,9 +61,9 @@ class_dealloc(op)
classobject *op;
{
int i;
- if (op->cl_bases != NULL)
- DECREF(op->cl_bases);
+ XDECREF(op->cl_bases);
DECREF(op->cl_methods);
+ XDECREF(op->cl_name);
free((ANY *)op);
}
@@ -70,6 +73,24 @@ class_getattr(op, name)
register char *name;
{
register object *v;
+ if (strcmp(name, "__dict__") == 0) {
+ INCREF(op->cl_methods);
+ return op->cl_methods;
+ }
+ if (strcmp(name, "__bases__") == 0) {
+ if (op->cl_bases == NULL)
+ return newtupleobject(0);
+ INCREF(op->cl_bases);
+ return op->cl_bases;
+ }
+ if (strcmp(name, "__name__") == 0) {
+ if (op->cl_name == NULL)
+ v = None;
+ else
+ v = op->cl_name;
+ INCREF(v);
+ return v;
+ }
v = dictlookup(op->cl_methods, name);
if (v != NULL) {
INCREF(v);
@@ -89,6 +110,18 @@ class_getattr(op, name)
return NULL;
}
+static int
+class_setattr(op, name, v)
+ classobject *op;
+ char *name;
+ object *v;
+{
+ if (v == NULL)
+ return dictremove(op->cl_methods, name);
+ else
+ return dictinsert(op->cl_methods, name, v);
+}
+
typeobject Classtype = {
OB_HEAD_INIT(&Typetype)
0,
@@ -98,7 +131,7 @@ typeobject Classtype = {
class_dealloc, /*tp_dealloc*/
0, /*tp_print*/
class_getattr, /*tp_getattr*/
- 0, /*tp_setattr*/
+ class_setattr, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
@@ -154,7 +187,16 @@ instance_getattr(inst, name)
register instanceobject *inst;
register char *name;
{
- register object *v = dictlookup(inst->in_attr, name);
+ register object *v;
+ if (strcmp(name, "__dict__") == 0) {
+ INCREF(inst->in_attr);
+ return inst->in_attr;
+ }
+ if (strcmp(name, "__class__") == 0) {
+ INCREF(inst->in_class);
+ return (object *)inst->in_class;
+ }
+ v = dictlookup(inst->in_attr, name);
if (v != NULL) {
INCREF(v);
return v;
@@ -202,8 +244,7 @@ typeobject Instancetype = {
};
-/* And finally, here are instance method objects
- (accidentally called class methods) */
+/* And finally, here are instance method objects */
typedef struct {
OB_HEAD