diff options
| author | Devtools Arcadia <[email protected]> | 2022-02-07 18:08:42 +0300 | 
|---|---|---|
| committer | Devtools Arcadia <[email protected]> | 2022-02-07 18:08:42 +0300 | 
| commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
| tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /contrib/tools/python3/src/Objects/cellobject.c | |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'contrib/tools/python3/src/Objects/cellobject.c')
| -rw-r--r-- | contrib/tools/python3/src/Objects/cellobject.c | 197 | 
1 files changed, 197 insertions, 0 deletions
diff --git a/contrib/tools/python3/src/Objects/cellobject.c b/contrib/tools/python3/src/Objects/cellobject.c new file mode 100644 index 00000000000..86a89f02e60 --- /dev/null +++ b/contrib/tools/python3/src/Objects/cellobject.c @@ -0,0 +1,197 @@ +/* Cell object implementation */ + +#include "Python.h" +#include "pycore_object.h" + +PyObject * +PyCell_New(PyObject *obj) +{ +    PyCellObject *op; + +    op = (PyCellObject *)PyObject_GC_New(PyCellObject, &PyCell_Type); +    if (op == NULL) +        return NULL; +    op->ob_ref = obj; +    Py_XINCREF(obj); + +    _PyObject_GC_TRACK(op); +    return (PyObject *)op; +} + +PyDoc_STRVAR(cell_new_doc, +"cell([contents])\n" +"--\n" +"\n" +"Create a new cell object.\n" +"\n" +"  contents\n" +"    the contents of the cell. If not specified, the cell will be empty,\n" +"    and \n further attempts to access its cell_contents attribute will\n" +"    raise a ValueError."); + + +static PyObject * +cell_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ +    PyObject *return_value = NULL; +    PyObject *obj = NULL; + +    if (!_PyArg_NoKeywords("cell", kwargs)) { +        goto exit; +    } +    /* min = 0: we allow the cell to be empty */ +    if (!PyArg_UnpackTuple(args, "cell", 0, 1, &obj)) { +        goto exit; +    } +    return_value = PyCell_New(obj); + +exit: +    return return_value; +} + +PyObject * +PyCell_Get(PyObject *op) +{ +    if (!PyCell_Check(op)) { +        PyErr_BadInternalCall(); +        return NULL; +    } +    Py_XINCREF(((PyCellObject*)op)->ob_ref); +    return PyCell_GET(op); +} + +int +PyCell_Set(PyObject *op, PyObject *obj) +{ +    PyObject* oldobj; +    if (!PyCell_Check(op)) { +        PyErr_BadInternalCall(); +        return -1; +    } +    oldobj = PyCell_GET(op); +    Py_XINCREF(obj); +    PyCell_SET(op, obj); +    Py_XDECREF(oldobj); +    return 0; +} + +static void +cell_dealloc(PyCellObject *op) +{ +    _PyObject_GC_UNTRACK(op); +    Py_XDECREF(op->ob_ref); +    PyObject_GC_Del(op); +} + +static PyObject * +cell_richcompare(PyObject *a, PyObject *b, int op) +{ +    /* neither argument should be NULL, unless something's gone wrong */ +    assert(a != NULL && b != NULL); + +    /* both arguments should be instances of PyCellObject */ +    if (!PyCell_Check(a) || !PyCell_Check(b)) { +        Py_RETURN_NOTIMPLEMENTED; +    } + +    /* compare cells by contents; empty cells come before anything else */ +    a = ((PyCellObject *)a)->ob_ref; +    b = ((PyCellObject *)b)->ob_ref; +    if (a != NULL && b != NULL) +        return PyObject_RichCompare(a, b, op); + +    Py_RETURN_RICHCOMPARE(b == NULL, a == NULL, op); +} + +static PyObject * +cell_repr(PyCellObject *op) +{ +    if (op->ob_ref == NULL) +        return PyUnicode_FromFormat("<cell at %p: empty>", op); + +    return PyUnicode_FromFormat("<cell at %p: %.80s object at %p>", +                               op, Py_TYPE(op->ob_ref)->tp_name, +                               op->ob_ref); +} + +static int +cell_traverse(PyCellObject *op, visitproc visit, void *arg) +{ +    Py_VISIT(op->ob_ref); +    return 0; +} + +static int +cell_clear(PyCellObject *op) +{ +    Py_CLEAR(op->ob_ref); +    return 0; +} + +static PyObject * +cell_get_contents(PyCellObject *op, void *closure) +{ +    if (op->ob_ref == NULL) +    { +        PyErr_SetString(PyExc_ValueError, "Cell is empty"); +        return NULL; +    } +    Py_INCREF(op->ob_ref); +    return op->ob_ref; +} + +static int +cell_set_contents(PyCellObject *op, PyObject *obj, void *Py_UNUSED(ignored)) +{ +    Py_XINCREF(obj); +    Py_XSETREF(op->ob_ref, obj); +    return 0; +} + +static PyGetSetDef cell_getsetlist[] = { +    {"cell_contents", (getter)cell_get_contents, +                      (setter)cell_set_contents, NULL}, +    {NULL} /* sentinel */ +}; + +PyTypeObject PyCell_Type = { +    PyVarObject_HEAD_INIT(&PyType_Type, 0) +    "cell", +    sizeof(PyCellObject), +    0, +    (destructor)cell_dealloc,                   /* tp_dealloc */ +    0,                                          /* tp_vectorcall_offset */ +    0,                                          /* tp_getattr */ +    0,                                          /* tp_setattr */ +    0,                                          /* tp_as_async */ +    (reprfunc)cell_repr,                        /* tp_repr */ +    0,                                          /* tp_as_number */ +    0,                                          /* tp_as_sequence */ +    0,                                          /* tp_as_mapping */ +    0,                                          /* tp_hash */ +    0,                                          /* tp_call */ +    0,                                          /* tp_str */ +    PyObject_GenericGetAttr,                    /* tp_getattro */ +    0,                                          /* tp_setattro */ +    0,                                          /* tp_as_buffer */ +    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */ +    cell_new_doc,                               /* tp_doc */ +    (traverseproc)cell_traverse,                /* tp_traverse */ +    (inquiry)cell_clear,                        /* tp_clear */ +    cell_richcompare,                           /* tp_richcompare */ +    0,                                          /* tp_weaklistoffset */ +    0,                                          /* tp_iter */ +    0,                                          /* tp_iternext */ +    0,                                          /* tp_methods */ +    0,                                          /* tp_members */ +    cell_getsetlist,                            /* 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 */ +    (newfunc)cell_new,                          /* tp_new */ +    0,                                          /* tp_free */ +};  | 
