summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1995-01-10 15:24:06 (GMT)
committerGuido van Rossum <guido@python.org>1995-01-10 15:24:06 (GMT)
commit879c581826ec9c0356dbf137cface7a27f51810c (patch)
treecced30d0108a3f49486373a937d0c461905b4a27 /Objects
parentc206c766dd743c635397d5e6be9adfdfc8fb921c (diff)
downloadcpython-879c581826ec9c0356dbf137cface7a27f51810c.zip
cpython-879c581826ec9c0356dbf137cface7a27f51810c.tar.gz
cpython-879c581826ec9c0356dbf137cface7a27f51810c.tar.bz2
implement coercions involving instances properly
Diffstat (limited to 'Objects')
-rw-r--r--Objects/classobject.c54
1 files changed, 53 insertions, 1 deletions
diff --git a/Objects/classobject.c b/Objects/classobject.c
index f18b4fb..1fc5d69 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -924,6 +924,58 @@ halfbinop(v, w, opname, r_result, thisfunc, swapped)
return *r_result == NULL ? -1 : 0;
}
+static int
+instance_coerce(pv, pw)
+ object **pv;
+ object **pw;
+{
+ object *v = *pv;
+ object *w = *pw;
+ object *coerce;
+ object *args;
+ object *coerced;
+
+ coerce = getattr(v, "__coerce__");
+ if (coerce == NULL) {
+ /* No __coerce__ method: always OK */
+ err_clear();
+ INCREF(v);
+ INCREF(w);
+ return 0;
+ }
+ /* Has __coerce__ method: call it */
+ args = mkvalue("(O)", w);
+ if (args == NULL) {
+ return -1;
+ }
+ coerced = call_object(coerce, args);
+ DECREF(args);
+ DECREF(coerce);
+ if (coerced == NULL) {
+ /* __coerce__ call raised an exception */
+ return -1;
+ }
+ if (coerced == None) {
+ /* __coerce__ says "I can't do it" */
+ DECREF(coerced);
+ return 1;
+ }
+ if (!is_tupleobject(coerced) || gettuplesize(coerced) != 2) {
+ /* __coerce__ return value is malformed */
+ DECREF(coerced);
+ err_setstr(TypeError,
+ "coercion should return None or 2-tuple");
+ return -1;
+ }
+ /* __coerce__ returned two new values */
+ *pv = gettupleitem(coerced, 0);
+ *pw = gettupleitem(coerced, 1);
+ INCREF(*pv);
+ INCREF(*pw);
+ DECREF(coerced);
+ return 0;
+}
+
#define UNARY(funcname, methodname) \
static object *funcname(self) instanceobject *self; { \
@@ -1018,7 +1070,7 @@ static number_methods instance_as_number = {
0, /*nb_and*/
0, /*nb_xor*/
0, /*nb_or*/
- 0, /*nb_coerce*/
+ (coercion)instance_coerce, /*nb_coerce*/
(unaryfunc)instance_int, /*nb_int*/
(unaryfunc)instance_long, /*nb_long*/
(unaryfunc)instance_float, /*nb_float*/