Add simple PySwigObject to handle the C/C++ instance pointers,

instead of using PyCObject or plain strings.

The new PySwigObject is even safer than PyCObject, and
more friendly than plain strings:

now you can do

  print a.this
  <Swig Object at _00691608_p_A>

  print str(a.this)
  _00691608_p_A

  print long(a.this)
  135686400

  print "%s 0x%x" % (a.this, a.this)
  _00691608_p_A 0x8166900


the last one is very useful when debugging the C/C++ side, since
is the pointer value you will usually get from the debugger.

Also, if you have some old code that uses the string representation
"_00691608_p_A", you can use it now again by calling str(ptr), or
maybe nothing special by just calling PyString_AsString(..).

This change is mainly for nostalgic swig users that miss the
string representation, but also allows to say again

  if a.this == b.this:
    return "a is b"

and well, since the change were really simple, maybe in the future
we will be able to do

    next = a.this + 1

or add native python iteration over native C/C++ arrays, ie, no
need to create/copy new tuples when returning and array or vector.


git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@6759 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Marcelo Matus 2004-11-19 20:40:20 +00:00
commit 121d73d58c
6 changed files with 384 additions and 44 deletions

View file

@ -0,0 +1,20 @@
%module swigobject
%inline
{
struct A {
char name[4];
};
const char* pointer_str(A *a){
static char result[1024];
sprintf(result,"%x",a);
return result;
}
A *a_ptr(A *a){
return a;
}
}

View file

@ -0,0 +1,69 @@
# This file was created automatically by SWIG.
# Don't modify this file, modify the SWIG interface instead.
# This file is compatible with both classic and new-style classes.
import _swigobject
def _swig_setattr_nondynamic(self,class_type,name,value,static=1):
if (name == "this"):
if isinstance(value, class_type):
self.__dict__[name] = value.this
if hasattr(value,"thisown"): self.__dict__["thisown"] = value.thisown
del value.thisown
return
method = class_type.__swig_setmethods__.get(name,None)
if method: return method(self,value)
if (not static) or hasattr(self,name) or (name == "thisown"):
self.__dict__[name] = value
else:
raise AttributeError("You cannot add attributes to %s" % self)
def _swig_setattr(self,class_type,name,value):
return _swig_setattr_nondynamic(self,class_type,name,value,0)
def _swig_getattr(self,class_type,name):
method = class_type.__swig_getmethods__.get(name,None)
if method: return method(self)
raise AttributeError,name
import types
try:
_object = types.ObjectType
_newclass = 1
except AttributeError:
class _object : pass
_newclass = 0
del types
class A(_object):
__swig_setmethods__ = {}
__setattr__ = lambda self, name, value: _swig_setattr(self, A, name, value)
__swig_getmethods__ = {}
__getattr__ = lambda self, name: _swig_getattr(self, A, name)
def __repr__(self):
return "<%s.%s; proxy of C++ A instance at %s>" % (self.__class__.__module__, self.__class__.__name__, self.this,)
__swig_setmethods__["name"] = _swigobject.A_name_set
__swig_getmethods__["name"] = _swigobject.A_name_get
if _newclass:name = property(_swigobject.A_name_get, _swigobject.A_name_set)
def __init__(self, *args):
_swig_setattr(self, A, 'this', _swigobject.new_A(*args))
_swig_setattr(self, A, 'thisown', 1)
def __del__(self, destroy=_swigobject.delete_A):
try:
if self.thisown: destroy(self)
except: pass
class APtr(A):
def __init__(self, this):
_swig_setattr(self, A, 'this', this)
if not hasattr(self,"thisown"): _swig_setattr(self, A, 'thisown', 0)
_swig_setattr(self, A,self.__class__,A)
_swigobject.A_swigregister(APtr)
pointer_str = _swigobject.pointer_str
a_ptr = _swigobject.a_ptr

View file

@ -0,0 +1,21 @@
from swigobject import *
a = A()
a1 = a_ptr(a)
a2 = a_ptr(a)
if a1.this != a2.this:
raise RuntimeError
lthis = long(a.this)
xstr1 = "%x" % (lthis,)
xstr2 = pointer_str(a)
if xstr1 != xstr2:
raise RuntimeError
s = str(a.this)
r = repr(a.this)

View file

@ -169,8 +169,8 @@ SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int
/* Install Constants */ /* Install Constants */
static void static void
SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) { SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) {
int i; PyObject *obj = 0;
PyObject *obj; size_t i;
for (i = 0; constants[i].type; i++) { for (i = 0; constants[i].type; i++) {
switch(constants[i].type) { switch(constants[i].type) {
case SWIG_PY_INT: case SWIG_PY_INT:
@ -213,7 +213,7 @@ SWIG_Python_FixMethods(PyMethodDef *methods,
swig_const_info *const_table, swig_const_info *const_table,
swig_type_info **types, swig_type_info **types,
swig_type_info **types_initial) { swig_type_info **types_initial) {
int i; size_t i;
for (i = 0; methods[i].ml_name; ++i) { for (i = 0; methods[i].ml_name; ++i) {
char *c = methods[i].ml_doc; char *c = methods[i].ml_doc;
if (c && (c = strstr(c, "swig_ptr: "))) { if (c && (c = strstr(c, "swig_ptr: "))) {
@ -239,7 +239,7 @@ SWIG_Python_FixMethods(PyMethodDef *methods,
buff += ldoc; buff += ldoc;
strncpy(buff, "swig_ptr: ", 10); strncpy(buff, "swig_ptr: ", 10);
buff += 10; buff += 10;
SWIG_Python_PointerStr(buff, ptr, ty->name, lptr); SWIG_PackVoidPtr(buff, ptr, ty->name, lptr);
methods[i].ml_doc = ndoc; methods[i].ml_doc = ndoc;
} }
} }

View file

@ -39,6 +39,230 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* -----------------------------------------------------------------------------
* Create a new pointer string
* ----------------------------------------------------------------------------- */
#if defined(SWIG_COBJECT_TYPES)
#if !defined(SWIG_COBJECT_PYTHON)
/* -----------------------------------------------------------------------------
* Implements a simple Swig Object type, and use it instead of PyCObject
* ----------------------------------------------------------------------------- */
typedef struct {
PyObject_HEAD
void *ptr;
char *desc;
} PySwigObject;
/* Declarations for objects of type PySwigObject */
SWIGRUNTIME int
PySwigObject_print(PySwigObject *v, FILE *fp, int flags)
{
char result[1024];
if (SWIG_PackVoidPtr(result, v->ptr, v->desc, 1024)) {
fputs("<Swig Object at ", fp); fputs(result, fp); fputs(">", fp);
return 0;
} else {
return 1;
}
}
SWIGRUNTIME PyObject *
PySwigObject_repr(PySwigObject *v)
{
char result[1024];
return SWIG_PackVoidPtr(result, v->ptr, v->desc, 1024) ?
PyString_FromFormat("<Swig Object at %s>", result) : 0;
}
SWIGRUNTIME PyObject *
PySwigObject_str(PySwigObject *v)
{
char result[1024];
return SWIG_PackVoidPtr(result, v->ptr, v->desc, 1024) ?
PyString_FromString(result) : 0;
}
SWIGRUNTIME PyObject *
PySwigObject_long(PySwigObject *v)
{
return PyLong_FromUnsignedLong((unsigned long) v->ptr);
}
SWIGRUNTIME int
PySwigObject_compare(PySwigObject *v, PySwigObject *w)
{
int c = strcmp(v->desc, w->desc);
if (c) {
return c;
} else {
void *i = v->ptr;
void *j = w->ptr;
return (i < j) ? -1 : (i > j) ? 1 : 0;
}
}
SWIGRUNTIME void
PySwigObject_dealloc(PySwigObject *self)
{
PyObject_DEL(self);
}
SWIGRUNTIME PyTypeObject*
PySwigObject_GetType() {
static char PySwigObject_Type__doc__[] =
"Swig object carries a C/C++ instance pointer";
static PyNumberMethods PySwigObject_as_number = {
(binaryfunc)0, /*nb_add*/
(binaryfunc)0, /*nb_subtract*/
(binaryfunc)0, /*nb_multiply*/
(binaryfunc)0, /*nb_divide*/
(binaryfunc)0, /*nb_remainder*/
(binaryfunc)0, /*nb_divmod*/
(ternaryfunc)0,/*nb_power*/
(unaryfunc)0, /*nb_negative*/
(unaryfunc)0, /*nb_positive*/
(unaryfunc)0, /*nb_absolute*/
(inquiry)0, /*nb_nonzero*/
0, /*nb_invert*/
0, /*nb_lshift*/
0, /*nb_rshift*/
0, /*nb_and*/
0, /*nb_xor*/
0, /*nb_or*/
(coercion)0, /*nb_coerce*/
(unaryfunc)PySwigObject_long, /*nb_int*/
(unaryfunc)PySwigObject_long, /*nb_long*/
(unaryfunc)0, /*nb_float*/
0, /* nb_oct */
0, /* nb_hex */
0, /* nb_inplace_add */
0, /* nb_inplace_subtract */
0, /* nb_inplace_multiply */
0, /* nb_inplace_divide */
0, /* nb_inplace_remainder */
0, /* nb_inplace_power */
0, /* nb_inplace_lshift */
0, /* nb_inplace_rshift */
0, /* nb_inplace_and */
0, /* nb_inplace_xor */
0, /* nb_inplace_or */
0, /* nb_floor_divide */
0, /* nb_true_divide */
0, /* nb_inplace_floor_divide */
0, /* nb_inplace_true_divide */
};
static PyTypeObject PySwigObject_Type = {
PyObject_HEAD_INIT(&PyType_Type)
0, /*ob_size*/
"PySwigObject", /*tp_name*/
sizeof(PySwigObject), /*tp_basicsize*/
0, /*tp_itemsize*/
/* methods */
(destructor)PySwigObject_dealloc, /*tp_dealloc*/
(printfunc)PySwigObject_print, /*tp_print*/
(getattrfunc)0, /*tp_getattr*/
(setattrfunc)0, /*tp_setattr*/
(cmpfunc)PySwigObject_compare, /*tp_compare*/
(reprfunc)PySwigObject_repr, /*tp_repr*/
&PySwigObject_as_number, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
(hashfunc)0, /*tp_hash*/
(ternaryfunc)0, /*tp_call*/
(reprfunc)PySwigObject_str, /*tp_str*/
/* Space for future expansion */
0L,0L,0L,0L,
PySwigObject_Type__doc__, /* Documentation string */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
#if PY_VERSION_HEX >= 0x02020000
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
0, /* tp_mro */
0, /* tp_cache */
0, /* tp_subclasses */
0, /* tp_weaklist */
#endif
#if PY_VERSION_HEX >= 0x02030000
0, /* tp_del */
#endif
#ifdef COUNT_ALLOCS
/* these must be last */
0, /* tp_alloc */
0, /* tp_free */
0, /* tp_maxalloc */
0, /* tp_next */
#endif
};
return &PySwigObject_Type;
}
SWIGRUNTIME PyObject *
PySwigObject_FromVoidPtrAndDesc(void *ptr, char *desc)
{
PySwigObject *self = PyObject_NEW(PySwigObject, PySwigObject_GetType());
if (self == NULL) return NULL;
self->ptr = ptr;
self->desc = desc;
return (PyObject *)self;
}
SWIGRUNTIMEINLINE void *
PySwigObject_AsVoidPtr(PyObject *self)
{
return ((PySwigObject *)self)->ptr;
}
SWIGRUNTIMEINLINE char *
PySwigObject_GetDesc(PyObject *self)
{
return ((PySwigObject *)self)->desc;
}
SWIGRUNTIMEINLINE int
PySwigObject_Check(PyObject *op) {
return ((op)->ob_type == PySwigObject_GetType())
|| (strcmp((op)->ob_type->tp_name,"PySwigObject") == 0);
}
#else
/* -----------------------------------------------------------------------------
* Use the old and original Python PyCObject instead of PySwigObject
* ----------------------------------------------------------------------------- */
#define PySwigObject_GetDesc(obj) PyCObject_GetDesc(obj)
#define PySwigObject_Check(obj) PyCObject_Check(obj)
#define PySwigObject_AsVoidPtr(obj) PyCObject_AsVoidPtr(obj)
#define PySwigObject_FromVoidPtrAndDesc(p, d) PyCObject_FromVoidPtrAndDesc(p, d, NULL)
#endif
#endif
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* errors manipulation * errors manipulation
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
@ -47,7 +271,7 @@ SWIGRUNTIME void
SWIG_Python_TypeError(const char *type, PyObject *obj) SWIG_Python_TypeError(const char *type, PyObject *obj)
{ {
if (type) { if (type) {
if (!PyCObject_Check(obj)) { if (!PySwigObject_Check(obj)) {
const char *otype = (obj ? obj->ob_type->tp_name : 0); const char *otype = (obj ? obj->ob_type->tp_name : 0);
if (otype) { if (otype) {
PyObject *str = PyObject_Str(obj); PyObject *str = PyObject_Str(obj);
@ -63,21 +287,20 @@ SWIG_Python_TypeError(const char *type, PyObject *obj)
return; return;
} }
} else { } else {
const char *otype = (char *) PyCObject_GetDesc(obj); const char *otype = (char *) PySwigObject_GetDesc(obj);
if (otype) { if (otype) {
PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'PyCObject(%s)' is received", PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'PySwigObject(%s)' is received",
type, otype); type, otype);
return; return;
} }
} }
PyErr_Format(PyExc_TypeError, "a '%s' is expected", type); PyErr_Format(PyExc_TypeError, "a '%s' is expected", type);
} else { } else {
PyErr_Format(PyExc_TypeError, "unexpected type is received"); PyErr_Format(PyExc_TypeError, "unexpected type is received");
} }
} }
SWIGRUNTIME void SWIGRUNTIMEINLINE void
SWIG_Python_NullRef(const char *type) SWIG_Python_NullRef(const char *type)
{ {
if (type) { if (type) {
@ -147,21 +370,21 @@ SWIG_Python_ConvertPtr(PyObject *obj, void **ptr, swig_type_info *ty, int flags)
} }
#ifdef SWIG_COBJECT_TYPES #ifdef SWIG_COBJECT_TYPES
if (!(PyCObject_Check(obj))) { if (!(PySwigObject_Check(obj))) {
if (!SWIG_this) if (!SWIG_this)
SWIG_this = PyString_FromString("this"); SWIG_this = PyString_FromString("this");
pyobj = obj; pyobj = obj;
obj = PyObject_GetAttr(obj,SWIG_this); obj = PyObject_GetAttr(obj,SWIG_this);
newref = 1; newref = 1;
if (!obj) goto type_error; if (!obj) goto type_error;
if (!PyCObject_Check(obj)) { if (!PySwigObject_Check(obj)) {
Py_DECREF(obj); Py_DECREF(obj);
goto type_error; goto type_error;
} }
} }
vptr = PyCObject_AsVoidPtr(obj); vptr = PySwigObject_AsVoidPtr(obj);
c = (char *) PyCObject_GetDesc(obj); c = (char *) PySwigObject_GetDesc(obj);
if (newref) Py_DECREF(obj); if (newref) { Py_DECREF(obj); }
goto type_check; goto type_check;
#else #else
if (!(PyString_Check(obj))) { if (!(PyString_Check(obj))) {
@ -279,36 +502,23 @@ type_error:
} }
} }
return -1; return -1;
} }
/* Create a new pointer string */ /* Create a new array object */
SWIGRUNTIME char *
SWIG_Python_PointerStr(char *buff, void *ptr, const char *name, size_t bsz) {
char *r = buff;
if ((2*sizeof(void *) + 2) > bsz) return 0;
*(r++) = '_';
r = SWIG_PackData(r,&ptr,sizeof(void *));
if (strlen(name) + 1 > (bsz - (r - buff))) return 0;
strcpy(r,name);
return buff;
}
/* Create a new pointer object */
SWIGRUNTIME PyObject * SWIGRUNTIME PyObject *
SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int own) { SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int own) {
PyObject *robj; PyObject *robj = 0;
if (!ptr) { if (!ptr) {
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
} }
#ifdef SWIG_COBJECT_TYPES #ifdef SWIG_COBJECT_TYPES
robj = PyCObject_FromVoidPtrAndDesc((void *) ptr, (char *) type->name, NULL); robj = PySwigObject_FromVoidPtrAndDesc((void *) ptr, (char *)type->name);
#else #else
{ {
char result[1024]; char result[1024];
SWIG_Python_PointerStr(result, ptr, type->name, 1024); robj = SWIG_PackVoidPtr(result, ptr, type->name, 1024) ?
robj = PyString_FromString(result); PyString_FromString(result) : 0;
} }
#endif #endif
if (!robj || (robj == Py_None)) return robj; if (!robj || (robj == Py_None)) return robj;
@ -369,7 +579,7 @@ SWIG_Python_GetTypeListHandle() {
/* /*
Search for a swig_type_info structure Search for a swig_type_info structure
*/ */
SWIGRUNTIME swig_type_info * SWIGRUNTIMEINLINE swig_type_info *
SWIG_Python_GetTypeList() { SWIG_Python_GetTypeList() {
swig_type_info **type_list_handle = SWIG_Python_GetTypeListHandle(); swig_type_info **type_list_handle = SWIG_Python_GetTypeListHandle();
return type_list_handle ? *type_list_handle : (swig_type_info *)0; return type_list_handle ? *type_list_handle : (swig_type_info *)0;
@ -379,25 +589,25 @@ SWIG_Python_GetTypeList() {
* Standard SWIG API * Standard SWIG API
* -----------------------------------------------------------------------------*/ * -----------------------------------------------------------------------------*/
SWIGRUNTIME swig_type_info * SWIGRUNTIMEINLINE swig_type_info *
SWIG_Python_TypeQuery(const char *name) { SWIG_Python_TypeQuery(const char *name) {
swig_type_info *tl = SWIG_Python_GetTypeList(); swig_type_info *tl = SWIG_Python_GetTypeList();
return SWIG_TypeQueryTL(tl, name); return SWIG_TypeQueryTL(tl, name);
} }
SWIGRUNTIME swig_type_info * SWIGRUNTIMEINLINE swig_type_info *
SWIG_Python_TypeRegister(swig_type_info *ti) { SWIG_Python_TypeRegister(swig_type_info *ti) {
swig_type_info **tlh = SWIG_Python_GetTypeListHandle(); swig_type_info **tlh = SWIG_Python_GetTypeListHandle();
return SWIG_TypeRegisterTL(tlh, ti); return SWIG_TypeRegisterTL(tlh, ti);
} }
SWIGRUNTIME void SWIGRUNTIMEINLINE void
SWIG_Python_TypeClientData(swig_type_info *ti, void *clientdata) { SWIG_Python_TypeClientData(swig_type_info *ti, void *clientdata) {
swig_type_info *tl = SWIG_Python_GetTypeList(); swig_type_info *tl = SWIG_Python_GetTypeList();
SWIG_TypeClientDataTL(tl, ti, clientdata); SWIG_TypeClientDataTL(tl, ti, clientdata);
} }
SWIGRUNTIME void SWIGRUNTIMEINLINE void
SWIG_Python_PropagateClientData(swig_type_info *type) { SWIG_Python_PropagateClientData(swig_type_info *type) {
swig_type_info *tl = SWIG_Python_GetTypeList(); swig_type_info *tl = SWIG_Python_GetTypeList();
SWIG_PropagateClientDataTL(tl, type); SWIG_PropagateClientDataTL(tl, type);

View file

@ -30,12 +30,19 @@
#endif #endif
/* /*
You can use this macro for creating a static or dynamic library. You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for
Swig just needs to use it as 'static' creating a static or dynamic library from the swig runtime code.
In 99.9% of the cases, swig just needs to declare them as 'static'.
But only do this if is strictly necessary, ie, if you have problems
with your compiler or so.
*/ */
#ifndef SWIGRUNTIME #ifndef SWIGRUNTIME
#define SWIGRUNTIME static #define SWIGRUNTIME static
#endif #endif
#ifndef SWIGRUNTIMEINLINE
#define SWIGRUNTIMEINLINE static SWIGINLINE
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -172,10 +179,9 @@ SWIG_TypeCheck(char *c, swig_type_info *ty) {
/* /*
Cast a pointer up an inheritance hierarchy Cast a pointer up an inheritance hierarchy
*/ */
SWIGRUNTIME SWIGINLINE void * SWIGRUNTIMEINLINE void *
SWIG_TypeCast(swig_type_info *ty, void *ptr) { SWIG_TypeCast(swig_type_info *ty, void *ptr) {
if ((!ty) || (!ty->converter)) return ptr; return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr);
return (*ty->converter)(ptr);
} }
/* /*
@ -195,7 +201,7 @@ SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) {
/* /*
Return the name associated with this type Return the name associated with this type
*/ */
SWIGRUNTIME SWIGINLINE const char * SWIGRUNTIMEINLINE const char *
SWIG_TypeName(const swig_type_info *ty) { SWIG_TypeName(const swig_type_info *ty) {
return ty->name; return ty->name;
} }
@ -327,6 +333,20 @@ SWIG_PropagateClientDataTL(swig_type_info *tl, swig_type_info *type) {
} }
} }
/*
Pack 'void *' into a string buffer.
*/
SWIGRUNTIME char *
SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) {
char *r = buff;
if ((2*sizeof(void *) + 2) > bsz) return 0;
*(r++) = '_';
r = SWIG_PackData(r,&ptr,sizeof(void *));
if (strlen(name) + 1 > (bsz - (r - buff))) return 0;
strcpy(r,name);
return buff;
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif