diff options
author | Guido van Rossum <guido@python.org> | 1992-08-14 12:06:52 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1992-08-14 12:06:52 (GMT) |
commit | e6eefc22313e7f2da5918ecd608fbb0b7a7a1610 (patch) | |
tree | 2896ab6358835d67083251ca911ff6d29a1138bf /Python | |
parent | 70d7a310a9844d1a3f80c110f1acd3d6059939b4 (diff) | |
download | cpython-e6eefc22313e7f2da5918ecd608fbb0b7a7a1610.zip cpython-e6eefc22313e7f2da5918ecd608fbb0b7a7a1610.tar.gz cpython-e6eefc22313e7f2da5918ecd608fbb0b7a7a1610.tar.bz2 |
* classobject.[ch], {float,long,int}object.c, bltinmodule.c:
coercion is now completely generic.
* ceval.c: for instances, don't coerce for + and *; * reverses
arguments if left one is non-instance numeric and right one sequence.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/bltinmodule.c | 42 | ||||
-rw-r--r-- | Python/ceval.c | 25 |
2 files changed, 31 insertions, 36 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index cce19e1..86deac3 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -781,10 +781,7 @@ initbuiltin() Increment the reference count on each argument. Return -1 and raise an exception if no coercion is possible (and then no reference count is incremented). - XXX This should be distributed over the various numeric types, - XXX but for now I don't see how to implement that. - XXX So, for now, if you add a new numeric type, - XXX you must add to this function as well. */ +*/ int coerce(pv, pw) @@ -792,36 +789,23 @@ coerce(pv, pw) { register object *v = *pv; register object *w = *pw; + int res; + if (v->ob_type == w->ob_type) { INCREF(v); INCREF(w); return 0; } - if (is_instanceobject(v) || is_instanceobject(w)) - return instance_coerce(pv, pw); - if (v->ob_type->tp_as_number == NULL || - w->ob_type->tp_as_number == NULL) { - err_setstr(TypeError, "mixing number and non-number"); - return -1; - } - if (is_floatobject(v) || is_floatobject(w)) { - v = builtin_float((object *)0, v); - w = builtin_float((object *)0, w); - } - else if (is_longobject(v) || is_longobject(w)) { - v = builtin_long((object *)0, v); - w = builtin_long((object *)0, w); - } - else { - err_setstr(TypeError, "can't coerce numeric types?!?!?"); - return -1; + if (v->ob_type->tp_as_number && v->ob_type->tp_as_number->nb_coerce) { + res = (*v->ob_type->tp_as_number->nb_coerce)(pv, pw); + if (res <= 0) + return res; } - if (v == NULL || w == NULL) { - XDECREF(v); - XDECREF(w); - return -1; + if (w->ob_type->tp_as_number && w->ob_type->tp_as_number->nb_coerce) { + res = (*w->ob_type->tp_as_number->nb_coerce)(pw, pv); + if (res <= 0) + return res; } - *pv = v; - *pw = w; - return 0; + err_setstr(TypeError, "number coercion failed"); + return -1; } diff --git a/Python/ceval.c b/Python/ceval.c index ad679a6..5b72d8e 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1532,7 +1532,9 @@ static object * add(v, w) object *v, *w; { - if (v->ob_type->tp_as_number != NULL) { + if (v->ob_type->tp_as_sequence != NULL) + return (*v->ob_type->tp_as_sequence->sq_concat)(v, w); + else if (v->ob_type->tp_as_number != NULL) { object *x; if (coerce(&v, &w) != 0) return NULL; @@ -1541,8 +1543,6 @@ add(v, w) DECREF(w); return x; } - else if (v->ob_type->tp_as_sequence != NULL) - return (*v->ob_type->tp_as_sequence->sq_concat)(v, w); else { err_setstr(TypeError, "+ not supported by operands"); return NULL; @@ -1571,16 +1571,27 @@ mul(v, w) object *v, *w; { typeobject *tp; - if (is_intobject(v) && w->ob_type->tp_as_sequence != NULL) { - /* int*sequence -- swap v and w */ + tp = v->ob_type; + if (tp->tp_as_number != NULL && + w->ob_type->tp_as_sequence != NULL && + !is_instanceobject(v)) { + /* number*sequence -- swap v and w */ object *tmp = v; v = w; w = tmp; + tp = v->ob_type; } - tp = v->ob_type; if (tp->tp_as_number != NULL) { object *x; - if (coerce(&v, &w) != 0) + if (is_instanceobject(v)) { + /* Instances of user-defined classes get their + other argument uncoerced, so they may + implement sequence*number as well as + number*number. */ + INCREF(v); + INCREF(w); + } + else if (coerce(&v, &w) != 0) return NULL; x = (*v->ob_type->tp_as_number->nb_multiply)(v, w); DECREF(v); |