123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738 |
- /*
- * Copyright (C) 2020,2023 Weber Yann
- *
- * This file is part of pyrpn.
- *
- * pyrpn is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * pyrpn is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with pyrpn. If not, see <http://www.gnu.org/licenses/>.
- */
- #include "python_rpnexpr.h"
-
- /**@file python_rpnexpr.c
- * @brief Python module & type definition
- * @ingroup python_ext
- * @ingroup python_pyrpn_RPNExpr
- */
-
- /**@brief @ref pymod_pyrpn_RPNExpr methods definition
- * @ingroup python_pyrpn_RPNExpr */
- static PyMethodDef RPNExpr_methods[] = {
- PYRPN_method("random", rpnexpr_random,
- METH_CLASS | METH_VARARGS | METH_KEYWORDS,
- "cls, args_count, token_count=10",
- "Return a new random RPN expression string"),
- PYRPN_method("default_mutation_params", rpnexpr_default_mutation_params,
- METH_CLASS | METH_FASTCALL,
- "cls, /",
- "Return the default mutation parameters"),
- PYRPN_method("eval", rpnexpr_eval, METH_FASTCALL,
- "self, /, *args",
- "Evaluate an expression"),
- PYRPN_method("mutate", rpnexpr_mutate,
- METH_VARARGS | METH_KEYWORDS,
- "self, n_mutations=1, params=None",
- "Mutate an expression"),
- PYRPN_method("reset_stack", rpnexpr_reset_stack,
- METH_NOARGS,
- "self, /",
- "Reset the stack (set all items to 0)"),
- PYRPN_method("__getstate__", rpnexpr_getstate,
- METH_NOARGS,
- "self, /",
- "Pickling method (see pickle module).\n"
- "Return a bytes representation of the expression state."),
- PYRPN_method("__setstate__", rpnexpr_setstate,
- METH_O,
- "self, state, /",
- "Unpickling method (see pickle module)."),
- PYRPN_method("__copy__", rpnexpr_copy,
- METH_NOARGS,
- "self, /",
- "Return a new equivalent instance (see copy module)"),
- PYRPN_method("uid", rpnexpr_getexprstate,
- METH_NOARGS,
- "self, /",
- "Return a base64 uid for expression"),
- {NULL} //Sentinel
- };
-
- /**@brief @ref pymod_pyrpn_RPNExpr members definition
- * @ingroup python_pyrpn_RPNExpr */
- static PyMemberDef RPNExpr_members[] = {
- {NULL}
- };
-
- /**@brief @ref pymod_pyrpn_RPNExpr methods definition
- * @todo Continue sequence implementation with contains, concat, repeat etc.
- * @ingroup python_pyrpn_RPNExpr */
- static PySequenceMethods RPNExpr_seq_methods = {
- .sq_length = rpnexpr_len,
- .sq_item = rpnexpr_token_item,
- .sq_ass_item = rpnexpr_token_ass_item,
- };
-
-
- PyTypeObject RPNExprType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "pyrpn.RPNExpr",
- .tp_doc = "RPN expression evaluator\n\
- \n\
- Instanciation :\n\
- RPNExpr(expression:str, args_count:int, stack_size:int=16)",
- .tp_basicsize = sizeof(PyRPNExpr_t),
- .tp_itemsize = 0,
- .tp_del = rpnexpr_del,
- .tp_repr = rpnexpr_repr,
- .tp_str = rpnexpr_str,
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_richcompare = rpnexpr_richcompare,
- .tp_methods = RPNExpr_methods,
- .tp_as_sequence = &RPNExpr_seq_methods,
- .tp_members = RPNExpr_members,
- .tp_init = rpnexpr_init,
- .tp_new = rpnexpr_new,
- };
-
- PyObject* rpnexpr_new(PyTypeObject *subtype, PyObject *args, PyObject* kwds)
- {
- PyObject *ret, *err;
- PyRPNExpr_t *expr;
- ret = PyType_GenericNew(subtype, args, kwds);
- if((err = PyErr_Occurred()))
- {
- Py_DECREF(err);
- return ret;
- }
- expr = (PyRPNExpr_t*)ret;
- expr->rpn = NULL;
- expr->args = NULL;
- expr->borrowed_expr = 0;
- return ret;
- }
-
- int rpnexpr_init(PyObject *self, PyObject *args, PyObject *kwds)
- {
- PyRPNExpr_t *expr_self;
- char *names[] = {"expression", "args_count", "stack_size", NULL};
- char err_str[256];
- const char *expr;
- long long int args_count, stack_size;
-
- expr_self = (PyRPNExpr_t*)self;
-
- stack_size = 16;
- expr_self->rpn = NULL;
-
- if(!PyArg_ParseTupleAndKeywords(args, kwds, "sL|L:RPNExpr.__init__", names, &expr,
- &args_count, &stack_size))
- {
- return -1;
- }
-
- if(args_count < 0 || args_count > 255)
- {
- snprintf(err_str, 128,
- "Argument count should be in [4..255] but %lld given",
- args_count);
- PyErr_SetString(PyExc_ValueError, err_str);
- return -1;
- }
-
- if(stack_size < 4 || stack_size > 255)
- {
- snprintf(err_str, 128,
- "Stack size should be in [0..255] but %lld given",
- stack_size);
- PyErr_SetString(PyExc_ValueError, err_str);
- return -1;
- }
-
- expr_self->rpn = malloc(sizeof(rpn_expr_t));
- if(!expr_self->rpn)
- {
- snprintf(err_str, 256,
- "Expression memory allocation error : %s",
- strerror(errno));
- }
- bzero(expr_self->rpn, sizeof(rpn_expr_t));
-
- if(rpn_expr_init(expr_self->rpn, stack_size, args_count) < 0)
- {
- snprintf(err_str, 256,
- "Expression init error : %s",
- expr_self->rpn->err_reason);
- PyErr_SetString(PyExc_ValueError, err_str);
- return -1;
- }
-
- expr_self->args = malloc(sizeof(rpn_value_t) * args_count);
- if(!expr_self->args)
- {
- snprintf(err_str, 256,
- "Error allocating arguments memory : %s",
- strerror(errno));
- return -1;
- }
-
- if(rpn_expr_compile(expr_self->rpn, expr))
- {
- PyErr_SetString(PyExc_ValueError, expr_self->rpn->err_reason);
- return -1;
- }
-
- return 0;
- }
-
- PyObject* rpnexpr_init_borrowing(rpn_expr_t *borrowed)
- {
- PyObject *args, *ret;
- PyRPNExpr_t *instance;
-
- args = Py_BuildValue("sLL", "", borrowed->args_count,
- borrowed->stack_sz);
- if(!args || PyErr_Occurred())
- {
- return NULL;
- }
-
- ret = PyObject_CallObject((PyObject*)&RPNExprType, args);
- if(!ret || PyErr_Occurred())
- {
- Py_DECREF(args);
- return NULL;
- }
-
- Py_DECREF(args);
-
- instance = (PyRPNExpr_t*)ret;
-
- rpn_expr_close(instance->rpn);
- free(instance->rpn);
-
- instance->borrowed_expr = 1;
- instance->rpn = borrowed;
-
- return ret;
- }
-
- void rpnexpr_del(PyObject *self)
- {
- PyRPNExpr_t *expr_self;
-
- expr_self = (PyRPNExpr_t*)self;
- if(expr_self->rpn && !expr_self->borrowed_expr)
- {
- rpn_expr_close(expr_self->rpn);
- free(expr_self->rpn);
- expr_self->rpn = NULL;
- }
- if(expr_self->args)
- {
- free(expr_self->args);
- expr_self->args = NULL;
- }
- }
-
-
- PyObject* rpnexpr_getexprstate(PyObject *self, PyObject *noargs)
- {
- /**@todo check if usefull */
- PyErr_SetString(PyExc_NotImplementedError, "Not implemented...");
- return NULL;
- }
-
- PyObject* rpnexpr_getstate(PyObject *self, PyObject *noargs)
- {
- PyObject *res;
- PyRPNExpr_t *expr_self;
- size_t total_sz;
- char err_str[128];
-
- expr_self = (PyRPNExpr_t*)self;
-
- if(expr_self->rpn->state != RPN_READY)
- {
- snprintf(err_str, 128,
- "RPNExpr.__getstate__() instance in bad state : %s",
- expr_self->rpn->state==RPN_ERROR?"error":"init");
- PyErr_SetString(PyExc_ValueError, err_str);
- return NULL;
- }
-
- total_sz = rpn_expr_serialize(expr_self->rpn, NULL, 0);
-
- char serial[total_sz];
-
- rpn_expr_serialize(expr_self->rpn, serial, total_sz);
- if(!(res = PyBytes_FromStringAndSize(serial, total_sz)))
- {
- return NULL;
- }
- return res;
- }
-
- PyObject* rpnexpr_setstate(PyObject *self, PyObject *state_bytes)
- {
- PyObject *tmp, *tmp2;
- PyRPNExpr_t *expr_self;
- const char *data;
- size_t bsize;
- int err;
- char err_str[256];
-
- expr_self = (PyRPNExpr_t*)self;
-
- if(!PyBytes_Check(state_bytes)) /* Arg check */
- {
- tmp2 = NULL;
- tmp = PyObject_Type(state_bytes);
- if(tmp)
- {
- tmp2 = PyObject_Str(tmp);
- }
- if(tmp2)
- {
- snprintf(err_str, 128,
- "RPNExpr.__setstate__() expected a bytes as \
- argument but %s found",
- PyUnicode_AsUTF8(tmp2));
- PyErr_SetString(PyExc_ValueError, err_str);
- }
- else
- {
- PyErr_SetString(PyExc_RuntimeError,
- "Failing to fetch arguments type will \
- generating exception message !");
- }
- return NULL;
- }
- if(expr_self->rpn || expr_self->args) /* checking instance state */
- {
- PyErr_SetString(PyExc_ValueError,
- "RPNExpr.__setstate__() instance in bad state : \
- should not be initialized");
- return NULL;
- }
-
- /* Checking data size */
- bsize = PyBytes_GET_SIZE(state_bytes);
- data = PyBytes_AS_STRING(state_bytes);
-
- if(bsize < sizeof(size_t))
- {
- PyErr_SetString(PyExc_ValueError, "Invalid argument");
- return NULL;
- }
-
- //alloc & init
- if(!(expr_self->rpn = malloc(sizeof(rpn_expr_t))))
- {
- err = errno;
- snprintf(err_str, 128,
- "RPNExpr.__setstate__() failed to allocate memory for \
- rpn_expr_t : %s",
- strerror(err));
- PyErr_SetString(PyExc_MemoryError, err_str);
- return NULL;
- }
- bzero(expr_self->rpn, sizeof(rpn_expr_t));
-
- if(rpn_expr_deserialize(expr_self->rpn, data, bsize) < 0)
- {
- PyErr_Format(PyExc_ValueError,
- "RPNExpr.__setstate__() fails to deserialize (%s)) %s",
- strerror(errno), expr_self->rpn->err_reason);
- return NULL;
- }
-
- if(!(expr_self->args = malloc(sizeof(rpn_value_t)*expr_self->rpn->args_count)))
- {
- err = errno;
- snprintf(err_str, 128,
- "RPNExpr.__setstate__() failed to allocate memory for \
- args buffer : %s",
- strerror(err));
- PyErr_SetString(PyExc_MemoryError, err_str);
- return NULL;
- }
-
- Py_RETURN_NONE;
- }
-
-
- PyObject* rpnexpr_copy(PyObject *self, PyObject *noargs)
- {
- PyRPNExpr_t *copy;
- PyObject *ret, *state, *setret;
-
- ret = PyObject_CallMethod((PyObject*)&RPNExprType, "__new__", "O", &RPNExprType);
- copy = (PyRPNExpr_t*)ret;
-
- state = PyObject_CallMethod(self, "__getstate__", NULL);
- if(PyErr_Occurred()) {
- goto err;
- }
- setret = PyObject_CallMethod(ret, "__setstate__", "O", state);
- if(PyErr_Occurred()) {
- Py_DECREF(state);
- goto err;
- }
-
- Py_DECREF(state);
- Py_DECREF(setret);
-
- return ret;
- err:
- PyObject_Del(copy);
- return NULL;
- }
-
-
- Py_ssize_t rpnexpr_len(PyObject *self)
- {
- PyRPNExpr_t *expr_self = (PyRPNExpr_t*)self;
- return (Py_ssize_t)expr_self->rpn->toks.tokens_sz;
- }
-
-
- PyObject* rpnexpr_token_item(PyObject *self, Py_ssize_t idx)
- {
- PyRPNExpr_t *expr_self = (PyRPNExpr_t*)self;
- Py_ssize_t _idx = idx;
- if(idx < 0)
- {
- idx = expr_self->rpn->toks.tokens_sz - 1 + idx;
- }
- if(idx < 0 || (size_t)idx >= expr_self->rpn->toks.tokens_sz)
- {
- PyErr_Format(PyExc_IndexError,
- "No token %ld in expression of size %ld",
- _idx, expr_self->rpn->toks.tokens_sz);
- return NULL;
-
- }
- return rpntoken_from_token(&expr_self->rpn->toks.tokens[idx]);
- }
-
-
- int rpnexpr_token_ass_item(PyObject *self, Py_ssize_t idx, PyObject* elt)
- {
- PyRPNExpr_t *expr_self = (PyRPNExpr_t*)self;
- Py_ssize_t _idx = idx;
- if(idx < 0)
- {
- idx = expr_self->rpn->toks.tokens_sz - 1 + idx;
- }
- if(idx < 0 || (size_t)idx > expr_self->rpn->toks.tokens_sz)
- {
- PyErr_Format(PyExc_IndexError,
- "Cannot set token %ld in expression of size %ld",
- _idx, expr_self->rpn->toks.tokens_sz);
- return -1;
- }
-
- if(!PyObject_IsInstance(elt, (PyObject*)&RPNTokenType))
- {
- PyErr_Format(PyExc_TypeError,
- "Given element in not RPNToken subtype");
- return -1;
- }
-
- short new_elt = 0;
- if((size_t)idx == expr_self->rpn->toks.tokens_sz)
- {
- new_elt = 1;
- expr_self->rpn->toks.tokens_sz++;
- size_t new_sz = expr_self->rpn->toks.tokens_sz*sizeof(rpn_token_t);
- rpn_token_t *tmp = realloc(expr_self->rpn->toks.tokens, new_sz);
- if(!tmp)
- {
- PyErr_Format(PyExc_MemoryError,
- "Error reallocation tokenized expression : %s",
- strerror(errno));
- return -1;
- }
- expr_self->rpn->toks.tokens = tmp;
- }
-
- rpn_token_t original = expr_self->rpn->toks.tokens[idx];
-
- RPNToken_t *token = (RPNToken_t*)elt;
- expr_self->rpn->toks.tokens[idx] = token->value;
- if(rpn_expr_tokens_updated(expr_self->rpn) < 0)
- {
- PyErr_Format(PyExc_ValueError,
- "Unable to update expression : %s",
- strerror(errno));
- goto rollback;
- }
- return 0;
-
- rollback:
- if(new_elt)
- {
- expr_self->rpn->toks.tokens_sz--;
- }
- else
- {
- expr_self->rpn->toks.tokens[idx] = original;
- if(rpn_expr_tokens_updated(expr_self->rpn) < 0)
- {
- PyErr_Format(PyExc_RuntimeError,
- "Unable to rollback expression : %s",
- strerror(errno));
- goto rollback;
- }
- }
- return -1;
- }
-
-
- PyObject* rpnexpr_eval(PyObject* self, PyObject** argv, Py_ssize_t argc)
- {
- PyRPNExpr_t *expr_self;
- unsigned long res;
- char err_str[128];
- Py_ssize_t i;
- PyObject *cur, *ret;
-
-
- expr_self = (PyRPNExpr_t*)self;
-
- if((unsigned long)argc != expr_self->rpn->args_count)
- {
- snprintf(err_str, 128,
- "RPNExpr expected %ld arguments but %ld given",
- expr_self->rpn->args_count,
- argc);
- PyErr_SetString(PyExc_ValueError, err_str);
- return NULL;
- }
-
- for(i=0; i<argc; i++)
- {
- cur = argv[i];
- if(!PyLong_Check(cur))
- {
- snprintf(err_str, 128,
- "RpnExpr.__call__ expect int as arguments but argument %ld is not",
- i+1);
- PyErr_SetString(PyExc_ValueError, err_str);
- return NULL;
- }
- expr_self->args[i] = PyLong_AsUnsignedLong(argv[i]);
- if((ret = PyErr_Occurred()))
- {
- Py_DECREF(ret);
- return NULL;
- }
- }
-
- res = rpn_expr_eval(expr_self->rpn, expr_self->args);
-
- return PyLong_FromUnsignedLong(res);
- }
-
-
- PyObject* rpnexpr_mutate(PyObject* slf, PyObject *args, PyObject *kwds)
- {
- PyRPNExpr_t *self = (PyRPNExpr_t*)slf;
-
- char *str_args = "|IO:RPNExpr.mutate";
- char *names[] = {"n_mutations", "params", NULL};
-
- PyObject *py_params = NULL;
- unsigned int n_mutations = 1;
- rpn_mutation_params_t params;
-
- if(!PyArg_ParseTupleAndKeywords(args, kwds, str_args, names,
- &n_mutations, &py_params))
- {
- return NULL;
- }
-
- if(!py_params || py_params == Py_None)
- {
- if(py_params == Py_None) { Py_DECREF(Py_None); }
- memcpy(¶ms, &rpn_mutation_params_default,
- sizeof(rpn_mutation_params_t));
- }
- else
- {
- if(pyrpn_pyobj_to_mutation_params(py_params, ¶ms) < 0)
- {
- PyErr_SetString(PyExc_ValueError, "Bad value for params arguments");
- return NULL;
- }
- }
-
- for(size_t i=0; i<n_mutations; i++)
- {
- if(rpn_mutation(&(self->rpn->toks), ¶ms) < 0)
- {
- PyErr_Format(PyExc_RuntimeError, "Mutation failed : %s",
- strerror(errno));
- return NULL;
- }
- }
-
- rpn_expr_tokens_updated(self->rpn);
- Py_RETURN_NONE;
- }
-
- PyObject* rpnexpr_reset_stack(PyObject *self, PyObject *noargs)
- {
- rpn_expr_reset_stack(((PyRPNExpr_t*)self)->rpn);
- Py_RETURN_NONE;
- }
-
- PyObject* rpnexpr_str(PyObject *self)
- {
- PyRPNExpr_t *expr_self;
- PyObject *res;
-
- expr_self = (PyRPNExpr_t*)self;
- res = Py_BuildValue("s", expr_self->rpn->expr);
- return res;
- }
-
- PyObject* rpnexpr_repr(PyObject *self)
- {
- PyRPNExpr_t *expr_self;
- PyObject *res;
- size_t sz;
- char *buff, err_str[128];
-
- expr_self = (PyRPNExpr_t*)self;
- sz = snprintf(NULL, 0, "<RPNExpr argc:%ld stck_sz:%d '%s'>",
- expr_self->rpn->args_count, expr_self->rpn->stack_sz,
- expr_self->rpn->expr);
- buff = malloc(sizeof(char) * (sz + 1));
- if(!buff)
- {
- snprintf(err_str, 128,
- "Error allocating repr : %s",
- strerror(errno));
- PyErr_SetString(PyExc_RuntimeError, err_str);
- return NULL;
- }
- snprintf(buff, sz+1, "<RPNExpr argc:%ld stck_sz:%d '%s'>",
- expr_self->rpn->args_count, expr_self->rpn->stack_sz,
- expr_self->rpn->expr);
- res = Py_BuildValue("s", buff);
- free(buff);
- return res;
- }
-
-
- PyObject* rpnexpr_richcompare(PyObject *_self, PyObject *other, int op)
- {
- PyObject *sta, *stb, *res;
-
- if(!PyObject_IsInstance(other, (PyObject*)&RPNExprType))
- {
- PyErr_Format(PyExc_TypeError,
- "Can only be compared with RPNExpr");
- return NULL;
- }
-
- sta = rpnexpr_getstate(_self, NULL);
- stb = rpnexpr_getstate(other, NULL);
-
- res = PyObject_RichCompare(sta, stb, op);
-
- Py_DECREF(sta);
- Py_DECREF(stb);
-
- return res;
- }
-
-
- PyObject* rpnexpr_random(PyObject *cls, PyObject *args, PyObject *kwds)
- {
- long long int args_count, expr_sz;
- char *expr, err_str[128];
- PyObject *res;
- char *names[] = {"args_count", "token_count", NULL};
-
- expr_sz = 10;
- if(!PyArg_ParseTupleAndKeywords(args, kwds, "L|L:pyrpn.random_expr", names,
- &args_count, &expr_sz))
- {
- return NULL;
- }
-
- expr = rpn_random(expr_sz, args_count);
- if(!expr)
- {
- snprintf(err_str, 128,
- "Error generating random expression : %s",
- strerror(errno));
- PyErr_SetString(PyExc_RuntimeError, err_str);
- return NULL;
- }
- res = Py_BuildValue("s", expr);
- //free(expr);
- return res;
- }
-
- PyObject* rpnexpr_default_mutation_params(PyObject *cls, PyObject **argv, Py_ssize_t argc)
- {
- PyObject *res, *wtypes;
-
- if(!(wtypes = PyStructSequence_New(&rpn_token_types_SeqDesc)))
- {
- return NULL;
- }
-
- if(!(res = PyStructSequence_New(&rpn_mutation_params_SeqDesc)))
- {
- return NULL;
- }
-
- // wtypes filled with 1.0
- PyObject *one = PyFloat_FromDouble(1.0);
- for(size_t i=0; i<3; i++)
- {
- PyStructSequence_SET_ITEM(wtypes, i, one);
- }
-
-
- // max_len
- PyStructSequence_SET_ITEM(res, 0,
- PyLong_FromLong(rpn_mutation_params_default.min_len));
- // weight_add
- PyStructSequence_SET_ITEM(res, 1,
- PyFloat_FromDouble(rpn_mutation_params_default.w_add));
- // weight_del
- PyStructSequence_SET_ITEM(res, 2,
- PyFloat_FromDouble(rpn_mutation_params_default.w_del));
- // weight_mut
- PyStructSequence_SET_ITEM(res, 3,
- PyFloat_FromDouble(rpn_mutation_params_default.w_mut));
- // weight_mut_soft
- PyStructSequence_SET_ITEM(res, 4,
- PyFloat_FromDouble(rpn_mutation_params_default.w_mut_soft));
-
- /** TODO use rpn_mutation_params_default instead of wtypes [1,1,1] */
- // weight_add_elt
- PyStructSequence_SET_ITEM(res, 5, wtypes);
- Py_INCREF(wtypes);
- // weight_mut_elt
- PyStructSequence_SET_ITEM(res, 6, wtypes);
- Py_INCREF(wtypes);
-
- return res;
-
- }
|