## 2.2.5 Abstract Protocol Support

        tp_as_number;
        tp_as_sequence;
        tp_as_mapping;

If you wish your object to be able to act like a number, a sequence, or a mapping object, then you place the address of a structure that implements the C type `PyNumberMethods`, `PySequenceMethods`, or `PyMappingMethods`, respectively. It is up to you to fill in this structure with appropriate values. You can find examples of the use of each of these in the Objects directory of the Python source distribution.

          hashfunc tp_hash;

This function, if you choose to provide it, should return a hash number for an instance of your datatype. Here is a moderately pointless example:

      static long
      newdatatype_hash(newdatatypeobject *obj)
      {
          long result;
          result = obj->obj_UnderlyingDatatypePtr->size;
          result = result * 3;
          return result;
      }

          ternaryfunc tp_call;

This function is called when an instance of your datatype is "called", for example, if `obj1` is an instance of your datatype and the Python script contains `obj1('hello')`, the `tp_call` handler is invoked.

This function takes three arguments:

1. arg1 is the instance of the datatype which is the subject of the call. If the call is `obj1('hello')`, then arg1 is `obj1`.

2. arg2 is a tuple containing the arguments to the call. You can use `PyArg_ParseTuple()` to extract the arguments.

3. arg3 is a dictionary of keyword arguments that were passed. If this is non-`NULL` and you support keyword arguments, use `PyArg_ParseTupleAndKeywords()` to extract the arguments. If you do not want to support keyword arguments and this is non-`NULL`, raise a `TypeError` with a message saying that keyword arguments are not supported.

Here is a desultory example of the implementation of call function.

      /* Implement the call function.
       *    obj1 is the instance receiving the call.
       *    obj2 is a tuple containing the arguments to the call, in this
       *         case 3 strings.
       */
      static PyObject *
      newdatatype_call(newdatatypeobject *obj, PyObject *args, PyObject *other)
      {
          PyObject *result;
          char *arg1;
          char *arg2;
          char *arg3;

          if (!PyArg_ParseTuple(args, "sss:call", &arg1, &arg2, &arg3)) {
              return NULL;
          }
          result = PyString_FromFormat(
              "Returning -- value: [\%d] arg1: [\%s] arg2: [\%s] arg3: [\%s]\n",
              obj->obj_UnderlyingDatatypePtr->size,
              arg1, arg2, arg3);
          printf("\%s", PyString_AS_STRING(result));
          return result;
      }