Extension type in C / tp_as_number

Joakim Hove hove at phys.ntnu.no
Tue Aug 20 03:20:21 EDT 2002


Hello,

I am writing a simple extension type in C, now this particular type
should support numeric operations mul and div both with itself, and
with a scalar numeric, i.e.

    NewType_Object n1,n2,n3;
    double         scalar;

    n3 = n1 * n2;
    n3 = n1 * scalar;

both the two expression should be ok. This is quite similar to a
matrix, multiplied with a scalar it gives a new matrix, and multiplied
with another matrix (of the correct dimensions) it also gives a new
matrix.

I have implemented the following function in C:

    static PyObject *ETuple_mul(ETuple_Object *self, PyObject *other) {
      double new_value, new_error;
      ETuple_Object *ET;

      if (is_ETupleTypeObject(other)) {
        ET = (ETuple_Object *) other;
        new_value =      ET->value             * self->value;
        new_error = sqrt(self->value  * ET->error   * ET->error + 
                         other->value * self->error * self->value);
      } else {
        fprintf(stderr,"Incorrect type ...");
      }
      return Py_BuildETuple(new_value, new_error);
    }   
    

and registered it along with its "friends" _add/_sub/_div in
PyNumberMethods. Now this compiles and loads nicely, however the
following Python code fails:

   #!/usr/local/bin/python

   import ETuple

   e1 = ETuple.ETuple(1.0,0.25)
   e2 = ETuple.ETuple(1.0,0.75)

   e3 = e1 * e2 # This works ok - as long as e1 and e2 are both of the
                # new type.

   e3 = e1 * 10.0 # This fails


Traceback (most recent call last):
  File "./test.py", line 12, in ?
    e3 = e1 * 10.0
TypeError: unsupported operand type(s) for *: 'ETuple' and 'float'


Personally I thought that for this case the error message "Incorrect
type ..." would be printed to <stderr>, however it seems that the
interpreter raises a TypeError on this *without* calling my ETuple_mul
function. When I first implemented this as a Python class, the __mul__
method would be called with whatever object i decided to put on the
right hand side in the *other variable. 

Is it possible, and in case how, can I achieve this behaviour from a C
extension?

Best Regards 

Joakim Hove


PS: I understand that it might seem like an overkill to implement this
    functionality in C, however the point is that I want access to
    this type of object from C, because I have another C extension
    (which "must" be written in C due to heavy computations) which
    should return objects of this type.



-- 
==== Joakim Hove      www.phys.ntnu.no/~hove/   =======================
|| Institutt for fysikk  (735) 93637 / E3-166  |  Skøyensgate 10D    ||
|| N - 7491 Trondheim    hove at phys.ntnu.no     |  N - 7030 Trondheim ||
================================================= 73 93 31 68 =========



More information about the Python-list mailing list