omlish-cext 0.0.0.dev493__tar.gz → 0.0.0.dev510__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {omlish_cext-0.0.0.dev493/omlish_cext.egg-info → omlish_cext-0.0.0.dev510}/PKG-INFO +4 -4
- {omlish_cext-0.0.0.dev493 → omlish_cext-0.0.0.dev510}/README.md +2 -2
- omlish_cext-0.0.0.dev510/omlish/_check.cc +209 -0
- omlish_cext-0.0.0.dev510/omlish/collections/hamt/_hamt.c +3656 -0
- omlish_cext-0.0.0.dev510/omlish/typedvalues/_collection.cc +479 -0
- {omlish_cext-0.0.0.dev493 → omlish_cext-0.0.0.dev510/omlish_cext.egg-info}/PKG-INFO +4 -4
- {omlish_cext-0.0.0.dev493 → omlish_cext-0.0.0.dev510}/omlish_cext.egg-info/SOURCES.txt +3 -0
- omlish_cext-0.0.0.dev510/omlish_cext.egg-info/requires.txt +1 -0
- {omlish_cext-0.0.0.dev493 → omlish_cext-0.0.0.dev510}/pyproject.toml +2 -2
- omlish_cext-0.0.0.dev510/setup.py +32 -0
- omlish_cext-0.0.0.dev493/omlish_cext.egg-info/requires.txt +0 -1
- omlish_cext-0.0.0.dev493/setup.py +0 -17
- {omlish_cext-0.0.0.dev493 → omlish_cext-0.0.0.dev510}/LICENSE +0 -0
- {omlish_cext-0.0.0.dev493 → omlish_cext-0.0.0.dev510}/omlish/lang/_asyncs.cc +0 -0
- {omlish_cext-0.0.0.dev493 → omlish_cext-0.0.0.dev510}/omlish/lang/imports/_capture.cc +0 -0
- {omlish_cext-0.0.0.dev493 → omlish_cext-0.0.0.dev510}/omlish_cext.egg-info/dependency_links.txt +0 -0
- {omlish_cext-0.0.0.dev493 → omlish_cext-0.0.0.dev510}/omlish_cext.egg-info/top_level.txt +0 -0
- {omlish_cext-0.0.0.dev493 → omlish_cext-0.0.0.dev510}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: omlish-cext
|
|
3
|
-
Version: 0.0.0.
|
|
3
|
+
Version: 0.0.0.dev510
|
|
4
4
|
Summary: omlish
|
|
5
5
|
Author: wrmsr
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -14,7 +14,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
14
14
|
Requires-Python: >=3.13
|
|
15
15
|
Description-Content-Type: text/markdown
|
|
16
16
|
License-File: LICENSE
|
|
17
|
-
Requires-Dist: omlish==0.0.0.
|
|
17
|
+
Requires-Dist: omlish==0.0.0.dev510
|
|
18
18
|
Dynamic: license-file
|
|
19
19
|
|
|
20
20
|
# Overview
|
|
@@ -158,8 +158,8 @@ dependencies of any kind**.
|
|
|
158
158
|
- **[plugins](https://github.com/wrmsr/omlish/blob/master/omlish/testing/pytest/plugins)** - Various other plugins.
|
|
159
159
|
|
|
160
160
|
- **[typedvalues](https://github.com/wrmsr/omlish/blob/master/omlish/typedvalues)** - A little toolkit around 'boxed'
|
|
161
|
-
values, whose 'box' types convey more information than the bare values themselves. A rebellion against kwargs
|
|
162
|
-
vars: instead of `foo(bar=1, baz=2)`, you do `foo(Bar(1), Baz(2))`.
|
|
161
|
+
values, whose 'box' types convey more information than the bare values themselves. A rebellion against kwargs / env
|
|
162
|
+
vars / giant config objects: instead of `foo(bar=1, baz=2)`, you do `foo(Bar(1), Baz(2))`.
|
|
163
163
|
|
|
164
164
|
- **[lite](https://github.com/wrmsr/omlish/blob/master/omlish/lite)** - The standard library of 'lite' code. This is the
|
|
165
165
|
only package beneath `lang`, and parts of it are re-exported by it for deduplication. On top of miscellaneous
|
|
@@ -139,8 +139,8 @@ dependencies of any kind**.
|
|
|
139
139
|
- **[plugins](https://github.com/wrmsr/omlish/blob/master/omlish/testing/pytest/plugins)** - Various other plugins.
|
|
140
140
|
|
|
141
141
|
- **[typedvalues](https://github.com/wrmsr/omlish/blob/master/omlish/typedvalues)** - A little toolkit around 'boxed'
|
|
142
|
-
values, whose 'box' types convey more information than the bare values themselves. A rebellion against kwargs
|
|
143
|
-
vars: instead of `foo(bar=1, baz=2)`, you do `foo(Bar(1), Baz(2))`.
|
|
142
|
+
values, whose 'box' types convey more information than the bare values themselves. A rebellion against kwargs / env
|
|
143
|
+
vars / giant config objects: instead of `foo(bar=1, baz=2)`, you do `foo(Bar(1), Baz(2))`.
|
|
144
144
|
|
|
145
145
|
- **[lite](https://github.com/wrmsr/omlish/blob/master/omlish/lite)** - The standard library of 'lite' code. This is the
|
|
146
146
|
only package beneath `lang`, and parts of it are re-exported by it for deduplication. On top of miscellaneous
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
// @omlish-cext
|
|
2
|
+
#define PY_SSIZE_T_CLEAN
|
|
3
|
+
#include "Python.h"
|
|
4
|
+
#include "structmember.h"
|
|
5
|
+
|
|
6
|
+
#include <vector>
|
|
7
|
+
|
|
8
|
+
//
|
|
9
|
+
|
|
10
|
+
#define _MODULE_NAME "_check"
|
|
11
|
+
#define _PACKAGE_NAME "omlish"
|
|
12
|
+
#define _MODULE_FULL_NAME _PACKAGE_NAME "." _MODULE_NAME
|
|
13
|
+
|
|
14
|
+
typedef struct check_state {
|
|
15
|
+
PyObject *typing_any;
|
|
16
|
+
PyTypeObject *nonetype;
|
|
17
|
+
} check_state;
|
|
18
|
+
|
|
19
|
+
static inline check_state * get_check_state(PyObject *module)
|
|
20
|
+
{
|
|
21
|
+
void *state = PyModule_GetState(module);
|
|
22
|
+
assert(state != NULL);
|
|
23
|
+
return (check_state *)state;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
//
|
|
27
|
+
|
|
28
|
+
PyDoc_STRVAR(unpack_isinstance_spec_doc, "unpack_isinstance_spec(spec)");
|
|
29
|
+
|
|
30
|
+
static PyObject * unpack_isinstance_spec(PyObject *module, PyObject *spec)
|
|
31
|
+
{
|
|
32
|
+
check_state *state = get_check_state(module);
|
|
33
|
+
|
|
34
|
+
// If spec is a type, return (spec,)
|
|
35
|
+
if (PyType_Check(spec)) {
|
|
36
|
+
return PyTuple_Pack(1, spec);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
PyObject *tuple_spec = nullptr;
|
|
40
|
+
|
|
41
|
+
// If not a tuple, wrap it in a tuple
|
|
42
|
+
if (!PyTuple_Check(spec)) {
|
|
43
|
+
tuple_spec = PyTuple_Pack(1, spec);
|
|
44
|
+
if (tuple_spec == nullptr) {
|
|
45
|
+
return nullptr;
|
|
46
|
+
}
|
|
47
|
+
} else {
|
|
48
|
+
// It's already a tuple, so we'll work with it
|
|
49
|
+
tuple_spec = spec;
|
|
50
|
+
Py_INCREF(tuple_spec);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Check if None is in spec
|
|
54
|
+
Py_ssize_t size = PyTuple_Size(tuple_spec);
|
|
55
|
+
if (size < 0) {
|
|
56
|
+
Py_DECREF(tuple_spec);
|
|
57
|
+
return nullptr;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
bool has_none = false;
|
|
61
|
+
bool has_any = false;
|
|
62
|
+
|
|
63
|
+
for (Py_ssize_t i = 0; i < size; i++) {
|
|
64
|
+
PyObject *item = PyTuple_GetItem(tuple_spec, i); // borrowed reference
|
|
65
|
+
if (item == nullptr) {
|
|
66
|
+
Py_DECREF(tuple_spec);
|
|
67
|
+
return nullptr;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (item == Py_None) {
|
|
71
|
+
has_none = true;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Check if item is typing.Any
|
|
75
|
+
if (state->typing_any != nullptr) {
|
|
76
|
+
int cmp = PyObject_RichCompareBool(item, state->typing_any, Py_EQ);
|
|
77
|
+
if (cmp < 0) {
|
|
78
|
+
Py_DECREF(tuple_spec);
|
|
79
|
+
return nullptr;
|
|
80
|
+
}
|
|
81
|
+
if (cmp) {
|
|
82
|
+
has_any = true;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// If typing.Any is in spec, return (object,)
|
|
88
|
+
if (has_any) {
|
|
89
|
+
Py_DECREF(tuple_spec);
|
|
90
|
+
return PyTuple_Pack(1, &PyBaseObject_Type);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// If None is in spec, filter it out and add NoneType
|
|
94
|
+
if (has_none) {
|
|
95
|
+
std::vector<PyObject*> filtered;
|
|
96
|
+
filtered.reserve(size);
|
|
97
|
+
|
|
98
|
+
for (Py_ssize_t i = 0; i < size; i++) {
|
|
99
|
+
PyObject *item = PyTuple_GetItem(tuple_spec, i); // borrowed reference
|
|
100
|
+
if (item != Py_None) {
|
|
101
|
+
filtered.push_back(item);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Add NoneType
|
|
106
|
+
filtered.push_back((PyObject *)state->nonetype);
|
|
107
|
+
|
|
108
|
+
// Create new tuple
|
|
109
|
+
PyObject *result = PyTuple_New(filtered.size());
|
|
110
|
+
if (result == nullptr) {
|
|
111
|
+
Py_DECREF(tuple_spec);
|
|
112
|
+
return nullptr;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
for (size_t i = 0; i < filtered.size(); i++) {
|
|
116
|
+
Py_INCREF(filtered[i]);
|
|
117
|
+
PyTuple_SET_ITEM(result, i, filtered[i]);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
Py_DECREF(tuple_spec);
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Return the tuple as-is
|
|
125
|
+
return tuple_spec;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
//
|
|
129
|
+
|
|
130
|
+
PyDoc_STRVAR(check_doc, "Native C++ implementations for omlish.lite.check");
|
|
131
|
+
|
|
132
|
+
static int check_exec(PyObject *module)
|
|
133
|
+
{
|
|
134
|
+
check_state *state = get_check_state(module);
|
|
135
|
+
|
|
136
|
+
// Get typing.Any
|
|
137
|
+
PyObject *typing_module = PyImport_ImportModule("typing");
|
|
138
|
+
if (typing_module == nullptr) {
|
|
139
|
+
// If typing module is not available, just set to nullptr
|
|
140
|
+
PyErr_Clear();
|
|
141
|
+
state->typing_any = nullptr;
|
|
142
|
+
} else {
|
|
143
|
+
state->typing_any = PyObject_GetAttrString(typing_module, "Any");
|
|
144
|
+
Py_DECREF(typing_module);
|
|
145
|
+
if (state->typing_any == nullptr) {
|
|
146
|
+
PyErr_Clear();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Get NoneType (type(None))
|
|
151
|
+
state->nonetype = Py_TYPE(Py_None);
|
|
152
|
+
Py_INCREF(state->nonetype);
|
|
153
|
+
|
|
154
|
+
return 0;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
static int check_traverse(PyObject *module, visitproc visit, void *arg)
|
|
158
|
+
{
|
|
159
|
+
check_state *state = get_check_state(module);
|
|
160
|
+
Py_VISIT(state->typing_any);
|
|
161
|
+
Py_VISIT(state->nonetype);
|
|
162
|
+
return 0;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
static int check_clear(PyObject *module)
|
|
166
|
+
{
|
|
167
|
+
check_state *state = get_check_state(module);
|
|
168
|
+
Py_CLEAR(state->typing_any);
|
|
169
|
+
Py_CLEAR(state->nonetype);
|
|
170
|
+
return 0;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
static void check_free(void *module)
|
|
174
|
+
{
|
|
175
|
+
check_clear((PyObject *)module);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
static PyMethodDef check_methods[] = {
|
|
179
|
+
{"unpack_isinstance_spec", (PyCFunction)unpack_isinstance_spec, METH_O, unpack_isinstance_spec_doc},
|
|
180
|
+
{NULL, NULL, 0, NULL}
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
static struct PyModuleDef_Slot check_slots[] = {
|
|
184
|
+
{Py_mod_exec, (void *) check_exec},
|
|
185
|
+
{Py_mod_gil, Py_MOD_GIL_NOT_USED},
|
|
186
|
+
{Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED},
|
|
187
|
+
{0, NULL}
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
static struct PyModuleDef check_module = {
|
|
191
|
+
.m_base = PyModuleDef_HEAD_INIT,
|
|
192
|
+
.m_name = _MODULE_NAME,
|
|
193
|
+
.m_doc = check_doc,
|
|
194
|
+
.m_size = sizeof(check_state),
|
|
195
|
+
.m_methods = check_methods,
|
|
196
|
+
.m_slots = check_slots,
|
|
197
|
+
.m_traverse = check_traverse,
|
|
198
|
+
.m_clear = check_clear,
|
|
199
|
+
.m_free = check_free,
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
extern "C" {
|
|
203
|
+
|
|
204
|
+
PyMODINIT_FUNC PyInit__check(void)
|
|
205
|
+
{
|
|
206
|
+
return PyModuleDef_Init(&check_module);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
}
|