[Python-Dev] PyNumber_*() binary operations & coercion (original) (raw)

M.-A. Lemburg mal@lemburg.com
Thu, 24 Aug 2000 13:22:32 +0200


Thomas Wouters wrote:

On Wed, Aug 23, 2000 at 06:28:03PM -0500, Guido van Rossum wrote: > > Now, I'm not sure how coercion is supposed to work, but I see one > > problem here: 'v' can be changed by PyNumberCoerce(), and the new > > object's tpasnumber pointer could be NULL. I bet it's pretty unlikely > > that (numeric) coercion of a numeric object and an unspecified object > > turns up a non-numeric object, but I don't see anything guaranteeing it > > won't, either. > I think this currently can't happen because coercions never return > non-numeric objects, but it sounds like a good sanity check to add. > Please check this in as a separate patch (not as part of the huge > augmented assignment patch). Alright, checking it in after 'make test' finishes. I'm also removing some redundant PyInstanceCheck() calls in PyNumberMultiply: the first thing in that function is a BINOP call, which expands to _if (PyInstanceCheck(v) || PyInstanceCheck(w)) _ return PyInstanceDoBinOp(v, w, opname, ropname, thisfunc) So after the BINOP call, neither argument can be an instance, anyway. Also, I'll take this opportunity to explain what I'm doing with the PyNumberInPlace* functions, for those that are interested. The comment I'm placing in the code should be enough information: /* The in-place operators are defined to fall back to the 'normal', non in-place operations, if the in-place methods are not in place, and to take class instances into account. This is how it is supposed to work: - If the left-hand-side object (the first argument) is an instance object, let PyInstanceDoInPlaceOp() handle it. Pass the non in-place variant of the function as callback, because it will only be used if any kind of coercion has been done, and if an object has been coerced, it's a new object and shouldn't be modified in-place. - Otherwise, if the object has the appropriate struct members, and they are filled, call that function and return the result. No coercion is done on the arguments; the left-hand object is the one the operation is performed on, and it's up to the function to deal with the right-hand object. - Otherwise, if the second argument is an Instance, let PyInstanceDoBinOp() handle it, but not in-place. Again, pass the non in-place function as callback. - Otherwise, both arguments are C objects. Try to coerce them and call the ordinary (not in-place) function-pointer from the type struct. - Otherwise, we are out of options: raise a type error. */ If anyone sees room for unexpected behaviour under these rules, let me know and you'll get an XS4ALL shirt! (Sorry, only ones I can offer ;)

I just hope that with all these new operators you haven't closed the door for switching to argument based handling of coercion.

One of these days (probably for 2.1), I would like to write up the proposal I made on my Python Pages about a new coercion mechanism as PEP. The idea behind it is to only use centralized coercion as fall-back solution in case the arguments can't handle the operation with the given type combination.

To implement this, all builtin types will have to be changed to support mixed type argument slot functions (this ability will be signalled to the interpreter using a type flag).

More infos on the proposal page at:

http://starship.python.net/crew/lemburg/CoercionProposal.html

Is this still possible under the new code you've added ?

-- Marc-Andre Lemburg


Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/