Using my routines as functions AND methods

Guenther Sohler guenther.sohler at gmail.com
Thu Jan 4 06:51:48 EST 2024


Hi list

The approach with defining the methods from python appears to be a very
good idea and it also works for classes, defined in python side.
However, when I try this one:

def mytrans(self):
    print(self)

c=cube()
cls=c.__class__

cls.trans=mytrans

I get this:

Traceback (most recent call last):

File "<string>", line 8, in <module>

TypeError: cannot set 'trans' attribute of immutable type 'PyOpenSCAD'

The Problem is probably that PyOpenSCAD is a class not defined on python
side but on c++ side,
 I fear that I need to solution in c++ side. ...



On Wed, Jan 3, 2024 at 11:47 PM Guenther Sohler <guenther.sohler at gmail.com>
wrote:

> Hi,
>
> In my cpython i have written quite some functions to modify "objects".
> and their python syntax is e.g.\
>
> translate(obj, vec). e.g whereas obj is ALWAYS first argument.
>
> on c side this functions looks like:
> PyObject *python_translate(PyObject *self, PyObject *args, PyObject
> *kwargs)
>
> this works great when specifying a list of functions in PyModuleDef
> structure.
>
> However, I also want to use these functions as class methods without
> having to
> write the function , twice. When using the SAME function as a methos, the
> args tuple must insert/contain "self" in the first location, so i have
> written a function to do that:
>
> PyObject *python_oo_args(PyObject *self, PyObject *args) // returns new
> reference,
> {
>   int i;
>   PyObject *item;
>   int n = PyTuple_Size(args);
>   PyObject *new_args = PyTuple_New(n + 1);
>   PyTuple_SetItem(new_args, 0, self);
>
>   for (i = 0; i < PyTuple_Size(args); i++) {
>     item = PyTuple_GetItem(args, i);
>     PyTuple_SetItem(new_args, i + 1, item);
>   }
>   return new_args;
> }
>
> To fill in method array, i have created a #define like this:
>
> #define OO_METHOD_ENTRY(name,desc) \
>   { #name, (PyCFunction) ( [ ] (PyObject *self, PyObject *args) ->
> PyObject * { \
>   PyObject *new_args = python_oo_args(self, args); \
>   PyObject *result = python_##name(self, new_args, NULL); \
>   return result;  } ),  METH_VARARGS | METH_KEYWORDS, (desc)},
>
> (this uses a lambda function)
>
> and use this in the array as:
>
> PyMethodDef PyOpenSCADMethods[] = {
>   OO_METHOD_ENTRY(translate,"Move Object")
>   OO_METHOD_ENTRY(right,"Right Object")
>
> Using this  i can reuse all the functions as methods,
> but its not 100% stable/bulletproof and crashes sometimes.
> So there is the bug ?
> Is there a better approach to reach my goal ?
>
>
> thank you
>
>


More information about the Python-list mailing list