mirror of
https://github.com/python/cpython.git
synced 2025-09-03 15:31:08 +00:00
implement coercions involving instances properly
This commit is contained in:
parent
c206c766dd
commit
879c581826
1 changed files with 53 additions and 1 deletions
|
@ -924,6 +924,58 @@ halfbinop(v, w, opname, r_result, thisfunc, swapped)
|
||||||
return *r_result == NULL ? -1 : 0;
|
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) \
|
#define UNARY(funcname, methodname) \
|
||||||
static object *funcname(self) instanceobject *self; { \
|
static object *funcname(self) instanceobject *self; { \
|
||||||
|
@ -1018,7 +1070,7 @@ static number_methods instance_as_number = {
|
||||||
0, /*nb_and*/
|
0, /*nb_and*/
|
||||||
0, /*nb_xor*/
|
0, /*nb_xor*/
|
||||||
0, /*nb_or*/
|
0, /*nb_or*/
|
||||||
0, /*nb_coerce*/
|
(coercion)instance_coerce, /*nb_coerce*/
|
||||||
(unaryfunc)instance_int, /*nb_int*/
|
(unaryfunc)instance_int, /*nb_int*/
|
||||||
(unaryfunc)instance_long, /*nb_long*/
|
(unaryfunc)instance_long, /*nb_long*/
|
||||||
(unaryfunc)instance_float, /*nb_float*/
|
(unaryfunc)instance_float, /*nb_float*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue