# 5. Case 3 - Non-DBo Standalone Classe — Coriolis 2 documentation

# 5. Case 3 - Non-DBo Standalone Classe

Let’s have a look at the encapsulation of `Hurricane::Point`.

Non-BDo derived classes do not support the bi-directionnal communication. So each Python object is associated with one C++ object. The C++ object is created and deleted along with the Python one. This behavior implies that the C++ object is copy constructible (which should be the case).

## 5.1 Class Header

Changes from 3.1 Class Associated Header File:

- There is no `PyPoint_Link()` function, as it’s related to the bi-directional communication mechanism.

Note

About the _object attribute of the PyPoint. As the C++ object life span (`Point`) is linked to the Python (`PyPoint`) one, we may have used a value instead of a pointer. It is best to keep a pointer as the macros written for `DBo` derived classes will remain usables.

    #ifndef ISOBAR_PY_POINT_H
    #define ISOBAR_PY_POINT_H

    #include "hurricane/isobar/PyHurricane.h"
    #include "hurricane/Point.h"

    namespace  Isobar {
      extern "C" {

        typedef struct {
            PyObject_HEAD
            Hurricane::Point* _object;
        } PyPoint;

        extern  PyTypeObject  PyTypePoint;
        extern  PyMethodDef   PyPoint_Methods[];
        extern  void          PyPoint_LinkPyType();

    #define IsPyPoint(v)    ( (v)->ob_type == &PyTypePoint )
    #define PYPOINT(v)      ( (PyPoint*)(v) )
    #define PYPOINT_O(v)    ( PYPOINT(v)->_object )

      }  // extern "C".
    }  // Isobar namespace.

    #endif  // ISOBAR_PY_POINT_H

## 5.2 Class File

Changes from 3.2 Class Associated File:

- As there is no `PyPoint_Link()` function, there is no call to any flavor of the `DBoLinkcreatemethod()` macro (obvious as it’s not a `DBo`).
- To use the standard Python constructor, we have to define `PyPoint_NEW()` and `PyPoint_Init()` functions, I’m not absolutely certain that the later needs to be defined (that part is still not clear to me from the Python doc).
- As it’s not a `DBo` there is no `destroy()` method, so no call to `DirectDestroyMethod()`
- Lastly, as this object has a `PyPoint_NEW()` (field `tp_new`) and a `PyPoint_Init()` (field `tp_init`) we have to use the macro `PyTypeObjectLinkPyTypeNewInit()` to define `PyPoint_LinkPyType()`.

    #include "hurricane/isobar/PyPoint.h"

    namespace Isobar {
      using namespace Hurricane;

      extern "C" {

    #define METHOD_HEAD(function)   GENERIC_METHOD_HEAD(Point,point,function)

    #if defined(__PYTHON_MODULE__)

        static PyObject* PyPoint_NEW ( PyObject* module, PyObject *args )
        {
          Point* point = NULL;
          HTRY
            PyObject* arg0 = NULL;
            PyObject* arg1 = NULL;

            __cs.init( "Point.Point" );
            if (not PyArg_ParseTuple( args,"|O&O&:Point.Point"
                                    , Converter,&arg0
                                    , Converter,&arg1 )) {
              PyErr_SetString ( ConstructorError
                              , "invalid number of parameters for Point constructor." );
              return NULL;
            }

            if      (__cs.getObjectIds() == "")
                    { point = new Point()); }
            else if (__cs.getObjectIds() == ":point")
                    { point = new Point( *PYPOINT_O(arg0) ); }
            else if (__cs.getObjectIds() == ":int:int")
                    { point = new Point( PyAny_AsLong(arg0), PyAny_AsLong(arg1) ); }
            else {
              PyErr_SetString ( ConstructorError
                              , "invalid number of parameters for Point constructor." );
              return NULL;
            }

            PyPoint* pyPoint = PyObject_NEW( PyPoint, &PyTypePoint );
            if (pyPoint == NULL) { delete point; return NULL; }
            pyPoint->_object = point;
          HCATCH

          return (PyObject*)pyPoint;
        }

        static int  PyPoint_Init ( PyPoint* self, PyObject* args, PyObject* kwargs )
        { return 0; }

        DirectGetLongAttribute(PyPoint_getX,getX,PyPoint,Point)
        DirectGetLongAttribute(PyPoint_getY,getY,PyPoint,Point)
        DirectSetLongAttribute(PyPoint_SetX,setX,PyPoint,Point)
        DirectSetLongAttribute(PyPoint_SetY,setY,PyPoint,Point)

        PyMethodDef PyPoint_Methods[] =
          { { "getX"   , (PyCFunction)PyPoint_getX     , METH_NOARGS
                       , "Return the Point X value." }
          , { "getY"   , (PyCFunction)PyPoint_getY     , METH_NOARGS
                       , "Return the Point Y value." }
          , { "setX"   , (PyCFunction)PyPoint_SetX     , METH_VARARGS
                       , "Modify the Point X value." }
          , { "setY"   , (PyCFunction)PyPoint_SetY     , METH_VARARGS
                       , "Modify the Point Y value." }
          , {NULL, NULL, 0, NULL}  /* sentinel */
          };

        DirectDeleteMethod(PyPoint_DeAlloc,PyPoint)
        PyTypeObjectLinkPyTypeNewInit(Point)

    #else  // Python Module Code Part.

        PyTypeObjectDefinitions(Point)

    #endif  // Shared Library Code Part.

      }  // extern "C".
    }  // Isobar namespace.

## 5.2 Class File

To put it bluntly, there is no difference in the Python module for a standalone `DBo` class and a non-`DBo` class.