Skip to content

Commit b1e4b45

Browse files
Merge pull request #215 from Distributive-Network/philippe/fix/211
Philippe/fix/211
2 parents 71a0483 + d4b4db6 commit b1e4b45

18 files changed

+2372
-94
lines changed

include/JSArrayIterProxy.hh

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/**
2+
* @file JSArrayIterProxy.hh
3+
* @author Philippe Laporte ([email protected])
4+
* @brief JSArrayIterProxy is a custom C-implemented python type that derives from PyListIter
5+
* @version 0.1
6+
* @date 2024-01-15
7+
*
8+
* Copyright (c) 2024 Distributive Corp.
9+
*
10+
*/
11+
12+
#ifndef PythonMonkey_JSArrayIterProxy_
13+
#define PythonMonkey_JSArrayIterProxy_
14+
15+
16+
#include <jsapi.h>
17+
18+
#include <Python.h>
19+
20+
21+
// redeclare hidden type
22+
typedef struct {
23+
PyObject_HEAD
24+
int it_index;
25+
bool reversed;
26+
PyListObject *it_seq; /* Set to NULL when iterator is exhausted */
27+
} PyListIterObject;
28+
29+
/**
30+
* @brief The typedef for the backing store that will be used by JSArrayIterProxy objects.
31+
*
32+
*/
33+
typedef struct {
34+
PyListIterObject it;
35+
} JSArrayIterProxy;
36+
37+
/**
38+
* @brief This struct is a bundle of methods used by the JSArrayProxy type
39+
*
40+
*/
41+
struct JSArrayIterProxyMethodDefinitions {
42+
public:
43+
/**
44+
* @brief Deallocation method (.tp_dealloc), removes the reference to the underlying JSObject before freeing the JSArrayProxy
45+
*
46+
* @param self - The JSArrayIterProxy to be free'd
47+
*/
48+
static void JSArrayIterProxy_dealloc(JSArrayIterProxy *self);
49+
50+
/**
51+
* @brief .tp_traverse method
52+
*
53+
* @param self - The JSArrayIterProxy
54+
* @param visitproc - The function to be applied on each element of the list
55+
* @param arg - The argument to the visit function
56+
* @return 0 on success
57+
*/
58+
static int JSArrayIterProxy_traverse(JSArrayIterProxy *self, visitproc visit, void *arg);
59+
60+
/**
61+
* @brief .tp_iter method
62+
*
63+
* @param self - The JSArrayIterProxy
64+
* @return PyObject* - an interator over the iterator
65+
*/
66+
static PyObject *JSArrayIterProxy_iter(JSArrayIterProxy *self);
67+
68+
/**
69+
* @brief .tp_next method
70+
*
71+
* @param self - The JSArrayIterProxy
72+
* @return PyObject* - next object in iteration
73+
*/
74+
static PyObject *JSArrayIterProxy_next(JSArrayIterProxy *self);
75+
76+
/**
77+
* @brief length method
78+
*
79+
* @param self - The JSArrayIterProxy
80+
* @return PyObject* - number of objects left to iterate over in iteration
81+
*/
82+
static PyObject *JSArrayIterProxy_len(JSArrayIterProxy *self);
83+
};
84+
85+
86+
PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
87+
88+
/**
89+
* @brief Struct for the other methods
90+
*
91+
*/
92+
static PyMethodDef JSArrayIterProxy_methods[] = {
93+
{"__length_hint__", (PyCFunction)JSArrayIterProxyMethodDefinitions::JSArrayIterProxy_len, METH_NOARGS, length_hint_doc},
94+
{NULL, NULL} /* sentinel */
95+
};
96+
97+
/**
98+
* @brief Struct for the JSArrayProxyType, used by all JSArrayProxy objects
99+
*/
100+
extern PyTypeObject JSArrayIterProxyType;
101+
102+
#endif

include/JSArrayProxy.hh

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,14 @@ public:
115115
*/
116116
static PyObject *JSArrayProxy_iter(JSArrayProxy *self);
117117

118+
/**
119+
* @brief Return a reverse iterator object to make JSArrayProxy backwards iterable
120+
*
121+
* @param self - The JSArrayProxy
122+
* @return PyObject* - iterator object
123+
*/
124+
static PyObject *JSArrayProxy_iter_reverse(JSArrayProxy *self);
125+
118126
/**
119127
* @brief Compute a string representation of the JSArrayProxy
120128
*
@@ -393,13 +401,18 @@ PyDoc_STRVAR(list_sort__doc__,
393401
"\n"
394402
"The reverse flag can be set to sort in descending order.");
395403

396-
404+
PyDoc_STRVAR(list___reversed____doc__,
405+
"__reversed__($self, /)\n"
406+
"--\n"
407+
"\n"
408+
"Return a reverse iterator over the list.");
397409

398410
/**
399411
* @brief Struct for the other methods
400412
*
401413
*/
402414
static PyMethodDef JSArrayProxy_methods[] = {
415+
{"__reversed__", (PyCFunction)JSArrayProxyMethodDefinitions::JSArrayProxy_iter_reverse, METH_NOARGS, list___reversed____doc__},
403416
{"clear", (PyCFunction)JSArrayProxyMethodDefinitions::JSArrayProxy_clear, METH_NOARGS, py_list_clear__doc__},
404417
{"copy", (PyCFunction)JSArrayProxyMethodDefinitions::JSArrayProxy_copy, METH_NOARGS, list_copy__doc__},
405418
{"append", (PyCFunction)JSArrayProxyMethodDefinitions::JSArrayProxy_append, METH_O, list_append__doc__},

include/JSObjectItemsProxy.hh

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/**
2+
* @file JSObjectItemsProxy.hh
3+
* @author Philippe Laporte ([email protected])
4+
* @brief JSObjectItemsProxy is a custom C-implemented python type that derives from dict items
5+
* @version 0.1
6+
* @date 2024-01-19
7+
*
8+
* Copyright (c) 2024 Distributive Corp.
9+
*
10+
*/
11+
12+
#ifndef PythonMonkey_JSObjectItemsProxy_
13+
#define PythonMonkey_JSObjectItemsProxy_
14+
15+
#include <jsapi.h>
16+
17+
#include <Python.h>
18+
19+
20+
/**
21+
* @brief The typedef for the backing store that will be used by JSObjectItemsProxy objects
22+
*
23+
*/
24+
typedef struct {
25+
_PyDictViewObject dv;
26+
} JSObjectItemsProxy;
27+
28+
/**
29+
* @brief This struct is a bundle of methods used by the JSObjectItemsProxy type
30+
*
31+
*/
32+
struct JSObjectItemsProxyMethodDefinitions {
33+
public:
34+
/**
35+
* @brief Deallocation method (.tp_dealloc), removes the reference to the underlying JSObject before freeing the JSObjectItemsProxy
36+
*
37+
* @param self - The JSObjectItemsProxy to be free'd
38+
*/
39+
static void JSObjectItemsProxy_dealloc(JSObjectItemsProxy *self);
40+
41+
/**
42+
* @brief .tp_traverse method
43+
*
44+
* @param self - The JSObjectItemsProxy
45+
* @param visitproc - The function to be applied on each element of the list
46+
* @param arg - The argument to the visit function
47+
* @return 0 on success
48+
*/
49+
static int JSObjectItemsProxy_traverse(JSObjectItemsProxy *self, visitproc visit, void *arg);
50+
51+
/**
52+
* @brief Length method (.sq_length), returns the number of key-value pairs in the JSObject, used by the python len() method
53+
*
54+
* @param self - The JSObjectProxy
55+
* @return Py_ssize_t The length of the JSObjectProxy
56+
*/
57+
static Py_ssize_t JSObjectItemsProxy_length(JSObjectItemsProxy *self);
58+
59+
/**
60+
* @brief Return an iterator object to make JSObjectItemsProxy iterable, emitting (key, value) tuples
61+
*
62+
* @param self - The JSObjectItemsProxy
63+
* @return PyObject* - iterator object
64+
*/
65+
static PyObject *JSObjectItemsProxy_iter(JSObjectItemsProxy *self);
66+
67+
/**
68+
* @brief Compute a string representation of the JSObjectItemsProxy
69+
*
70+
* @param self - The JSObjectItemsProxy
71+
* @return the string representation (a PyUnicodeObject) on success, NULL on failure
72+
*/
73+
static PyObject *JSObjectItemsProxy_repr(JSObjectItemsProxy *self);
74+
75+
/**
76+
* @brief reverse iterator method
77+
*
78+
* @param self - The JSObjectItemsProxy
79+
* @return PyObject* The resulting new dict
80+
*/
81+
static PyObject *JSObjectItemsProxy_iter_reverse(JSObjectItemsProxy *self);
82+
83+
/**
84+
* @brief mapping method
85+
*
86+
* @param self - The JSObjectItemsProxy
87+
* @return PyObject* The resulting new dict
88+
*/
89+
static PyObject *JSObjectItemsProxy_mapping(PyObject *self, void *Py_UNUSED(ignored));
90+
};
91+
92+
/**
93+
* @brief Struct for the methods that define the Sequence protocol
94+
*
95+
*/
96+
static PySequenceMethods JSObjectItemsProxy_sequence_methods = {
97+
.sq_length = (lenfunc)JSObjectItemsProxyMethodDefinitions::JSObjectItemsProxy_length,
98+
// .sq_contains = TODO tuple support
99+
};
100+
101+
PyDoc_STRVAR(items_reversed_keys_doc,
102+
"Return a reverse iterator over the dict keys.");
103+
104+
/**
105+
* @brief Struct for the other methods
106+
*
107+
*/
108+
static PyMethodDef JSObjectItemsProxy_methods[] = {
109+
// {"isdisjoint"}, // TODO tuple support
110+
{"__reversed__", (PyCFunction)JSObjectItemsProxyMethodDefinitions::JSObjectItemsProxy_iter_reverse, METH_NOARGS, items_reversed_keys_doc},
111+
{NULL, NULL} /* sentinel */
112+
};
113+
114+
static PyGetSetDef JSObjectItemsProxy_getset[] = {
115+
{"mapping", JSObjectItemsProxyMethodDefinitions::JSObjectItemsProxy_mapping, (setter)NULL, "dictionary that this view refers to", NULL},
116+
{0}
117+
};
118+
119+
/**
120+
* @brief Struct for the JSObjectItemsProxyType, used by all JSObjectItemsProxy objects
121+
*/
122+
extern PyTypeObject JSObjectItemsProxyType;
123+
124+
#endif

include/JSObjectIterProxy.hh

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/**
2+
* @file JSObjectIterProxy.hh
3+
* @author Philippe Laporte ([email protected])
4+
* @brief JSObjectIterProxy is a custom C-implemented python type that derives from PyDictIterKey
5+
* @version 0.1
6+
* @date 2024-01-17
7+
*
8+
* Copyright (c) 2024 Distributive Corp.
9+
*
10+
*/
11+
12+
#ifndef PythonMonkey_JSObjectIterProxy_
13+
#define PythonMonkey_JSObjectIterProxy_
14+
15+
16+
#include <jsapi.h>
17+
18+
#include <Python.h>
19+
20+
#define KIND_KEYS 0
21+
#define KIND_VALUES 1
22+
#define KIND_ITEMS 2
23+
24+
25+
/**
26+
* @brief The typedef for the backing store that will be used by JSObjectIterProxy objects.
27+
*
28+
*/
29+
30+
typedef struct {
31+
PyObject_HEAD
32+
JS::RootedIdVector *props;
33+
int it_index;
34+
bool reversed;
35+
int kind;
36+
PyDictObject *di_dict; /* Set to NULL when iterator is exhausted */
37+
} dictiterobject;
38+
39+
40+
typedef struct {
41+
dictiterobject it;
42+
} JSObjectIterProxy;
43+
44+
/**
45+
* @brief This struct is a bundle of methods used by the JSArrayProxy type
46+
*
47+
*/
48+
struct JSObjectIterProxyMethodDefinitions {
49+
public:
50+
/**
51+
* @brief Deallocation method (.tp_dealloc), removes the reference to the underlying JSObject before freeing the JSArrayProxy
52+
*
53+
* @param self - The JSObjectIterProxy to be free'd
54+
*/
55+
static void JSObjectIterProxy_dealloc(JSObjectIterProxy *self);
56+
57+
/**
58+
* @brief .tp_traverse method
59+
*
60+
* @param self - The JSObjectIterProxy
61+
* @param visitproc - The function to be applied on each element of the list
62+
* @param arg - The argument to the visit function
63+
* @return 0 on success
64+
*/
65+
static int JSObjectIterProxy_traverse(JSObjectIterProxy *self, visitproc visit, void *arg);
66+
67+
/**
68+
* @brief .tp_iter method
69+
*
70+
* @param self - The JSObjectIterProxy
71+
* @return PyObject* - an interator over the iterator
72+
*/
73+
static PyObject *JSObjectIterProxy_iter(JSObjectIterProxy *self);
74+
75+
/**
76+
* @brief .tp_next method
77+
*
78+
* @param self - The JSObjectIterProxy
79+
* @return PyObject* - next object in iteration
80+
*/
81+
static PyObject *JSObjectIterProxy_nextkey(JSObjectIterProxy *self);
82+
83+
/**
84+
* @brief length method
85+
*
86+
* @param self - The JSObjectIterProxy
87+
* @return PyObject* - number of objects left to iterate over in iteration
88+
*/
89+
static PyObject *JSObjectIterProxy_len(JSObjectIterProxy *self);
90+
};
91+
92+
93+
PyDoc_STRVAR(dict_length_hint_doc, "Private method returning an estimate of len(list(it)).");
94+
95+
/**
96+
* @brief Struct for the other methods
97+
*
98+
*/
99+
static PyMethodDef JSObjectIterProxy_methods[] = {
100+
{"__length_hint__", (PyCFunction)JSObjectIterProxyMethodDefinitions::JSObjectIterProxy_len, METH_NOARGS, dict_length_hint_doc},
101+
{NULL, NULL} /* sentinel */
102+
};
103+
104+
/**
105+
* @brief Struct for the JSArrayProxyType, used by all JSArrayProxy objects
106+
*/
107+
extern PyTypeObject JSObjectIterProxyType;
108+
109+
#endif

0 commit comments

Comments
 (0)