diff options
author | Guido van Rossum <guido@python.org> | 1995-01-10 15:24:06 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1995-01-10 15:24:06 (GMT) |
commit | 879c581826ec9c0356dbf137cface7a27f51810c (patch) | |
tree | cced30d0108a3f49486373a937d0c461905b4a27 /Objects/classobject.c | |
parent | c206c766dd743c635397d5e6be9adfdfc8fb921c (diff) | |
download | cpython-879c581826ec9c0356dbf137cface7a27f51810c.zip cpython-879c581826ec9c0356dbf137cface7a27f51810c.tar.gz cpython-879c581826ec9c0356dbf137cface7a27f51810c.tar.bz2 |
implement coercions involving instances properly
Diffstat (limited to 'Objects/classobject.c')
-rw-r--r-- | Objects/classobject.c | 54 |
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*/ |