zope.hookable 5.4__cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl → 7.0__cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
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.
Potentially problematic release.
This version of zope.hookable might be problematic. Click here for more details.
- zope/hookable/__init__.py +8 -4
- zope/hookable/_zope_hookable.c +191 -182
- zope/hookable/_zope_hookable.cpython-39-aarch64-linux-gnu.so +0 -0
- zope/hookable/tests/test_hookable.py +13 -8
- zope.hookable-7.0-py3.9-nspkg.pth +1 -0
- {zope.hookable-5.4.dist-info → zope.hookable-7.0.dist-info}/METADATA +27 -7
- zope.hookable-7.0.dist-info/RECORD +13 -0
- {zope.hookable-5.4.dist-info → zope.hookable-7.0.dist-info}/WHEEL +1 -1
- zope.hookable-5.4-py3.9-nspkg.pth +0 -1
- zope.hookable-5.4.dist-info/RECORD +0 -13
- {zope.hookable-5.4.dist-info → zope.hookable-7.0.dist-info}/LICENSE.txt +0 -0
- {zope.hookable-5.4.dist-info → zope.hookable-7.0.dist-info}/namespace_packages.txt +0 -0
- {zope.hookable-5.4.dist-info → zope.hookable-7.0.dist-info}/top_level.txt +0 -0
zope/hookable/__init__.py
CHANGED
|
@@ -17,11 +17,15 @@ import os
|
|
|
17
17
|
import platform
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
# Keep these two flags separate: we want the `_PURE_PYTHON` one
|
|
21
|
+
# to represent that the flag is explicitly set to '1' in the environment,
|
|
22
|
+
# since our 'tox.ini' sets it to '0' for its environments which expect
|
|
23
|
+
# to test the C extension.
|
|
24
|
+
_PYPY_OR_JAVA = platform.python_implementation() in ('PyPy', 'Jython')
|
|
25
|
+
_PURE_PYTHON = os.environ.get('PURE_PYTHON') == '1'
|
|
22
26
|
|
|
23
27
|
|
|
24
|
-
class _py_hookable
|
|
28
|
+
class _py_hookable:
|
|
25
29
|
__slots__ = ('_original', '_implementation')
|
|
26
30
|
|
|
27
31
|
def __init__(self, *args, **kw):
|
|
@@ -69,7 +73,7 @@ try:
|
|
|
69
73
|
except ImportError: # pragma: no cover
|
|
70
74
|
_c_hookable = None
|
|
71
75
|
|
|
72
|
-
if _PURE_PYTHON or _c_hookable is None:
|
|
76
|
+
if _PYPY_OR_JAVA or _PURE_PYTHON or _c_hookable is None:
|
|
73
77
|
hookable = _py_hookable
|
|
74
78
|
else: # pragma: no cover
|
|
75
79
|
hookable = _c_hookable
|
zope/hookable/_zope_hookable.c
CHANGED
|
@@ -12,149 +12,113 @@
|
|
|
12
12
|
#
|
|
13
13
|
############################################################################*/
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
*/
|
|
15
|
+
static char module__doc__[] = (
|
|
16
|
+
"Provide an efficient implementation for hookable objects"
|
|
17
|
+
);
|
|
20
18
|
|
|
21
19
|
#include "Python.h"
|
|
22
20
|
#include "structmember.h"
|
|
23
21
|
|
|
24
|
-
typedef struct
|
|
22
|
+
typedef struct
|
|
23
|
+
{
|
|
25
24
|
PyObject_HEAD
|
|
26
|
-
PyObject
|
|
27
|
-
PyObject
|
|
25
|
+
PyObject* original;
|
|
26
|
+
PyObject* implementation;
|
|
28
27
|
} hookable;
|
|
29
28
|
|
|
30
29
|
static int
|
|
31
|
-
hookable_init(hookable
|
|
30
|
+
hookable_init(hookable* self, PyObject* args, PyObject* kwds)
|
|
32
31
|
{
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
32
|
+
static char* kwlist[] = { "implementation", NULL };
|
|
33
|
+
PyObject* implementation;
|
|
34
|
+
|
|
35
|
+
if (!PyArg_ParseTupleAndKeywords(
|
|
36
|
+
args, kwds, "O:hookable", kwlist, &implementation))
|
|
37
|
+
return -1;
|
|
38
|
+
|
|
39
|
+
/* Both 'self->original' and 'self->implementation' are originally
|
|
40
|
+
* set to the passed-in 'implementation', hence the need for
|
|
41
|
+
* two increfs.
|
|
42
|
+
*/
|
|
43
|
+
Py_INCREF(implementation);
|
|
44
|
+
Py_XDECREF(self->original);
|
|
45
|
+
self->original = implementation;
|
|
46
|
+
|
|
47
|
+
Py_INCREF(implementation);
|
|
48
|
+
Py_XDECREF(self->implementation);
|
|
49
|
+
self->implementation = implementation;
|
|
50
|
+
|
|
51
|
+
return 0;
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
static int
|
|
51
|
-
hookable_traverse(hookable
|
|
55
|
+
hookable_traverse(hookable* self, visitproc visit, void* arg)
|
|
52
56
|
{
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
return -1;
|
|
60
|
-
|
|
61
|
-
return 0;
|
|
57
|
+
#if PY_VERSION_HEX >= 0x03090000
|
|
58
|
+
Py_VISIT(Py_TYPE(self));
|
|
59
|
+
#endif
|
|
60
|
+
Py_VISIT(self->implementation);
|
|
61
|
+
Py_VISIT(self->original);
|
|
62
|
+
return 0;
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
static int
|
|
65
|
-
hookable_clear(hookable
|
|
66
|
+
hookable_clear(hookable* self)
|
|
66
67
|
{
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
Py_XDECREF(self->implementation);
|
|
70
|
-
self->implementation = NULL;
|
|
71
|
-
return 0;
|
|
72
|
-
}
|
|
68
|
+
Py_XDECREF(self->original);
|
|
69
|
+
self->original = NULL;
|
|
73
70
|
|
|
71
|
+
Py_XDECREF(self->implementation);
|
|
72
|
+
self->implementation = NULL;
|
|
74
73
|
|
|
75
|
-
|
|
76
|
-
hookable_dealloc(hookable *self)
|
|
77
|
-
{
|
|
78
|
-
PyObject_GC_UnTrack((PyObject *)self);
|
|
79
|
-
Py_XDECREF(self->old);
|
|
80
|
-
Py_XDECREF(self->implementation);
|
|
81
|
-
Py_TYPE(self)->tp_free((PyObject*)self);
|
|
74
|
+
return 0;
|
|
82
75
|
}
|
|
83
76
|
|
|
84
|
-
static
|
|
85
|
-
|
|
77
|
+
static void
|
|
78
|
+
hookable_dealloc(hookable* self)
|
|
86
79
|
{
|
|
87
|
-
|
|
80
|
+
PyObject_GC_UnTrack((PyObject*)self);
|
|
81
|
+
PyTypeObject* tp = Py_TYPE(self);
|
|
88
82
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
self->implementation = implementation;
|
|
83
|
+
Py_XDECREF(self->original);
|
|
84
|
+
Py_XDECREF(self->implementation);
|
|
92
85
|
|
|
93
|
-
|
|
94
|
-
{
|
|
95
|
-
Py_INCREF(Py_None);
|
|
96
|
-
return Py_None;
|
|
97
|
-
}
|
|
86
|
+
tp->tp_free((PyObject*)self);
|
|
98
87
|
|
|
99
|
-
|
|
88
|
+
/* heap types must decref their type when dealloc'ed */
|
|
89
|
+
Py_DECREF(tp);
|
|
100
90
|
}
|
|
101
91
|
|
|
102
|
-
static PyObject
|
|
103
|
-
|
|
92
|
+
static PyObject*
|
|
93
|
+
hookable_call(hookable* self, PyObject* args, PyObject* kw)
|
|
104
94
|
{
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
self->implementation = self->old;
|
|
108
|
-
Py_INCREF(Py_None);
|
|
109
|
-
return Py_None;
|
|
110
|
-
}
|
|
95
|
+
if (self->implementation != NULL)
|
|
96
|
+
return PyObject_Call(self->implementation, args, kw);
|
|
111
97
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
"Set the hook implementation for the hookable object"},
|
|
115
|
-
{"reset", (PyCFunction)hookable_reset, METH_NOARGS,
|
|
116
|
-
"Reset the hook to the original value"},
|
|
117
|
-
{NULL, NULL} /* sentinel */
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
static PyObject *
|
|
122
|
-
hookable_call(hookable *self, PyObject *args, PyObject *kw)
|
|
123
|
-
{
|
|
124
|
-
if (self->implementation != NULL)
|
|
125
|
-
return PyObject_Call(self->implementation, args, kw);
|
|
126
|
-
PyErr_SetString(PyExc_TypeError, "Hookable has no implementation");
|
|
127
|
-
return NULL;
|
|
98
|
+
PyErr_SetString(PyExc_TypeError, "Hookable has no implementation");
|
|
99
|
+
return NULL;
|
|
128
100
|
}
|
|
129
101
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
hookable_getattro(hookable *self, PyObject *name)
|
|
102
|
+
static PyObject*
|
|
103
|
+
hookable_getattro(hookable* self, PyObject* name)
|
|
133
104
|
{
|
|
134
|
-
PyObject
|
|
135
|
-
const char
|
|
105
|
+
PyObject* result = NULL;
|
|
106
|
+
const char* name_as_string;
|
|
136
107
|
int maybe_special_name;
|
|
137
108
|
|
|
138
|
-
#if PY_MAJOR_VERSION < 3
|
|
139
|
-
name_as_string = PyString_AsString(name);
|
|
140
|
-
#else
|
|
141
109
|
name_as_string = PyUnicode_AsUTF8(name);
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
if (name_as_string == NULL) {
|
|
145
|
-
return NULL;
|
|
146
|
-
}
|
|
110
|
+
if (name_as_string == NULL) { return NULL; }
|
|
147
111
|
|
|
148
112
|
maybe_special_name = name_as_string[0] == '_' && name_as_string[1] == '_';
|
|
149
113
|
|
|
150
114
|
if (maybe_special_name) {
|
|
151
115
|
/* pass through __doc__ to the original implementation */
|
|
152
116
|
if (strcmp("__doc__", name_as_string) == 0) {
|
|
153
|
-
return PyObject_GetAttr(self->
|
|
117
|
+
return PyObject_GetAttr(self->original, name);
|
|
154
118
|
}
|
|
155
|
-
/* synthesize
|
|
119
|
+
/* synthesize __bases__ and __dict__ if the original fails */
|
|
156
120
|
if (strcmp("__bases__", name_as_string) == 0) {
|
|
157
|
-
result = PyObject_GetAttr(self->
|
|
121
|
+
result = PyObject_GetAttr(self->original, name);
|
|
158
122
|
if (result == NULL) {
|
|
159
123
|
PyErr_Clear();
|
|
160
124
|
result = PyTuple_New(0);
|
|
@@ -162,7 +126,7 @@ hookable_getattro(hookable *self, PyObject *name)
|
|
|
162
126
|
return result;
|
|
163
127
|
}
|
|
164
128
|
if (strcmp("__dict__", name_as_string) == 0) {
|
|
165
|
-
result = PyObject_GetAttr(self->
|
|
129
|
+
result = PyObject_GetAttr(self->original, name);
|
|
166
130
|
if (result == NULL) {
|
|
167
131
|
PyErr_Clear();
|
|
168
132
|
result = PyDict_New();
|
|
@@ -174,103 +138,148 @@ hookable_getattro(hookable *self, PyObject *name)
|
|
|
174
138
|
return PyObject_GenericGetAttr((PyObject*)self, name);
|
|
175
139
|
}
|
|
176
140
|
|
|
141
|
+
static char hookable_sethook__doc__[] = (
|
|
142
|
+
"Set the hook implementation for the hookable object\n\n"
|
|
143
|
+
"Return the previous hook implementation, or None."
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
static PyObject*
|
|
147
|
+
hookable_sethook(hookable* self, PyObject* implementation)
|
|
148
|
+
{
|
|
149
|
+
PyObject* current;
|
|
150
|
+
|
|
151
|
+
current = self->implementation;
|
|
152
|
+
Py_INCREF(implementation);
|
|
153
|
+
self->implementation = implementation;
|
|
154
|
+
|
|
155
|
+
if (current == NULL) {
|
|
156
|
+
Py_INCREF(Py_None);
|
|
157
|
+
return Py_None;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return current;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
static char hookable_reset__doc__[] = (
|
|
164
|
+
"Reset the hook to the original value"
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
static PyObject*
|
|
168
|
+
hookable_reset(hookable* self)
|
|
169
|
+
{
|
|
170
|
+
Py_XINCREF(self->original);
|
|
171
|
+
Py_XDECREF(self->implementation);
|
|
172
|
+
|
|
173
|
+
self->implementation = self->original;
|
|
174
|
+
|
|
175
|
+
Py_INCREF(Py_None);
|
|
176
|
+
return Py_None;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
static struct PyMethodDef hookable_methods[] = {
|
|
180
|
+
{ "sethook",
|
|
181
|
+
(PyCFunction)hookable_sethook, METH_O, hookable_sethook__doc__ },
|
|
182
|
+
{ "reset",
|
|
183
|
+
(PyCFunction)hookable_reset, METH_NOARGS, hookable_reset__doc__},
|
|
184
|
+
{ NULL, NULL } /* sentinel */
|
|
185
|
+
};
|
|
186
|
+
|
|
177
187
|
static PyMemberDef hookable_members[] = {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
188
|
+
{ "original",
|
|
189
|
+
T_OBJECT_EX, offsetof(hookable, original), READONLY },
|
|
190
|
+
{ "implementation",
|
|
191
|
+
T_OBJECT_EX, offsetof(hookable, implementation), READONLY },
|
|
192
|
+
{ NULL } /* Sentinel */
|
|
181
193
|
};
|
|
182
194
|
|
|
195
|
+
static char hookable__name__[] = "zope.hookable.hookable";
|
|
196
|
+
static char hookable__doc__[] =
|
|
197
|
+
"Callable objects that support being overridden";
|
|
183
198
|
|
|
184
|
-
static char Hookabletype__doc__[] =
|
|
185
|
-
"Callable objects that support being overridden"
|
|
186
|
-
;
|
|
187
|
-
|
|
188
|
-
static PyTypeObject hookabletype = {
|
|
189
|
-
PyVarObject_HEAD_INIT(NULL, 0)
|
|
190
|
-
/* tp_name */ "zope.hookable."
|
|
191
|
-
"hookable",
|
|
192
|
-
/* tp_basicsize */ sizeof(hookable),
|
|
193
|
-
/* tp_itemsize */ 0,
|
|
194
|
-
/* tp_dealloc */ (destructor)&hookable_dealloc,
|
|
195
|
-
/* tp_print */ (printfunc)0,
|
|
196
|
-
/* tp_getattr */ (getattrfunc)0,
|
|
197
|
-
/* tp_setattr */ (setattrfunc)0,
|
|
198
|
-
/* tp_compare */ 0,
|
|
199
|
-
/* tp_repr */ (reprfunc)0,
|
|
200
|
-
/* tp_as_number */ 0,
|
|
201
|
-
/* tp_as_sequence */ 0,
|
|
202
|
-
/* tp_as_mapping */ 0,
|
|
203
|
-
/* tp_hash */ (hashfunc)0,
|
|
204
|
-
/* tp_call */ (ternaryfunc)hookable_call,
|
|
205
|
-
/* tp_str */ (reprfunc)0,
|
|
206
|
-
/* tp_getattro */ (getattrofunc)hookable_getattro,
|
|
207
|
-
/* tp_setattro */ (setattrofunc)0,
|
|
208
|
-
/* tp_as_buffer */ 0,
|
|
209
|
-
/* tp_flags */ Py_TPFLAGS_DEFAULT
|
|
210
|
-
| Py_TPFLAGS_BASETYPE
|
|
211
|
-
| Py_TPFLAGS_HAVE_GC,
|
|
212
|
-
/* tp_doc */ Hookabletype__doc__,
|
|
213
|
-
/* tp_traverse */ (traverseproc)hookable_traverse,
|
|
214
|
-
/* tp_clear */ (inquiry)hookable_clear,
|
|
215
|
-
/* tp_richcompare */ (richcmpfunc)0,
|
|
216
|
-
/* tp_weaklistoffset */ (long)0,
|
|
217
|
-
/* tp_iter */ (getiterfunc)0,
|
|
218
|
-
/* tp_iternext */ (iternextfunc)0,
|
|
219
|
-
/* tp_methods */ hookable_methods,
|
|
220
|
-
/* tp_members */ hookable_members,
|
|
221
|
-
/* tp_getset */ 0,
|
|
222
|
-
/* tp_base */ 0,
|
|
223
|
-
/* tp_dict */ 0, /* internal use */
|
|
224
|
-
/* tp_descr_get */ (descrgetfunc)0,
|
|
225
|
-
/* tp_descr_set */ (descrsetfunc)0,
|
|
226
|
-
/* tp_dictoffset */ 0,
|
|
227
|
-
/* tp_init */ (initproc)hookable_init,
|
|
228
|
-
/* tp_alloc */ (allocfunc)0,
|
|
229
|
-
/* tp_new */ (newfunc)0 /*PyType_GenericNew*/,
|
|
230
|
-
/* tp_free */ 0/*PyObject_GC_Del*/,
|
|
231
|
-
};
|
|
232
199
|
|
|
200
|
+
/*
|
|
201
|
+
* Heap type: hookable
|
|
202
|
+
*/
|
|
203
|
+
static PyType_Slot hookable_type_slots[] = {
|
|
204
|
+
{Py_tp_doc, hookable__doc__},
|
|
205
|
+
{Py_tp_init, hookable_init},
|
|
206
|
+
{Py_tp_call, hookable_call},
|
|
207
|
+
{Py_tp_getattro, hookable_getattro},
|
|
208
|
+
{Py_tp_traverse, hookable_traverse},
|
|
209
|
+
{Py_tp_clear, hookable_clear},
|
|
210
|
+
{Py_tp_dealloc, hookable_dealloc},
|
|
211
|
+
{Py_tp_members, hookable_members},
|
|
212
|
+
{Py_tp_methods, hookable_methods},
|
|
213
|
+
{0, NULL}
|
|
214
|
+
};
|
|
233
215
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
ob = PyModule_Create(&moduledef);
|
|
242
|
-
#else
|
|
243
|
-
#define MOD_ERROR_VAL
|
|
244
|
-
#define MOD_SUCCESS_VAL(val)
|
|
245
|
-
#define MOD_INIT(name) void init##name(void)
|
|
246
|
-
#define MOD_DEF(ob, name, doc, methods) \
|
|
247
|
-
ob = Py_InitModule3(name, methods, doc);
|
|
216
|
+
static PyType_Spec hookable_type_spec = {
|
|
217
|
+
.name = hookable__name__,
|
|
218
|
+
.basicsize = sizeof(hookable),
|
|
219
|
+
.flags = Py_TPFLAGS_DEFAULT |
|
|
220
|
+
Py_TPFLAGS_BASETYPE |
|
|
221
|
+
#if PY_VERSION_HEX >= 0x030c0000
|
|
222
|
+
Py_TPFLAGS_MANAGED_WEAKREF |
|
|
248
223
|
#endif
|
|
224
|
+
Py_TPFLAGS_HAVE_GC,
|
|
225
|
+
.slots = hookable_type_slots
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
/*
|
|
229
|
+
* Module initialization
|
|
230
|
+
*/
|
|
249
231
|
|
|
250
|
-
static struct PyMethodDef
|
|
251
|
-
{NULL, NULL}
|
|
232
|
+
static struct PyMethodDef hookable_module_methods[] = {
|
|
233
|
+
{ NULL, NULL } /* sentinel */
|
|
252
234
|
};
|
|
253
235
|
|
|
254
|
-
|
|
236
|
+
|
|
237
|
+
/* Handler for the 'execute' phase of multi-phase initialization
|
|
238
|
+
*
|
|
239
|
+
* See: https://docs.python.org/3/c-api/module.html#multi-phase-initialization
|
|
240
|
+
* and: https://peps.python.org/pep-0489/#module-execution-phase
|
|
241
|
+
*/
|
|
242
|
+
static int
|
|
243
|
+
hookable_module_exec(PyObject* module)
|
|
255
244
|
{
|
|
256
|
-
|
|
245
|
+
PyObject* hookable_type;
|
|
246
|
+
|
|
247
|
+
hookable_type = PyType_FromSpec(&hookable_type_spec);
|
|
248
|
+
if (hookable_type == NULL) { return -1; }
|
|
257
249
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
module_methods)
|
|
250
|
+
if (PyModule_AddObject(module, "hookable", hookable_type) < 0)
|
|
251
|
+
return -1;
|
|
261
252
|
|
|
262
|
-
|
|
263
|
-
|
|
253
|
+
return 0;
|
|
254
|
+
}
|
|
264
255
|
|
|
265
|
-
hookabletype.tp_new = PyType_GenericNew;
|
|
266
|
-
hookabletype.tp_free = PyObject_GC_Del;
|
|
267
256
|
|
|
268
|
-
|
|
269
|
-
|
|
257
|
+
/* Slot definitions for multi-phase initialization
|
|
258
|
+
*
|
|
259
|
+
* See: https://docs.python.org/3/c-api/module.html#multi-phase-initialization
|
|
260
|
+
* and: https://peps.python.org/pep-0489
|
|
261
|
+
*/
|
|
262
|
+
static PyModuleDef_Slot hookable_module_slots[] = {
|
|
263
|
+
{Py_mod_exec, hookable_module_exec},
|
|
264
|
+
{0, NULL}
|
|
265
|
+
};
|
|
270
266
|
|
|
271
|
-
|
|
272
|
-
|
|
267
|
+
static struct PyModuleDef hookable_module_def = {
|
|
268
|
+
PyModuleDef_HEAD_INIT,
|
|
269
|
+
.m_name = "_zope_hookable",
|
|
270
|
+
.m_doc = module__doc__,
|
|
271
|
+
.m_methods = hookable_module_methods,
|
|
272
|
+
.m_slots = hookable_module_slots
|
|
273
|
+
};
|
|
273
274
|
|
|
274
|
-
|
|
275
|
+
static PyObject*
|
|
276
|
+
init(void)
|
|
277
|
+
{
|
|
278
|
+
return PyModuleDef_Init(&hookable_module_def);
|
|
279
|
+
}
|
|
275
280
|
|
|
281
|
+
PyMODINIT_FUNC
|
|
282
|
+
PyInit__zope_hookable(void)
|
|
283
|
+
{
|
|
284
|
+
return init();
|
|
276
285
|
}
|
|
Binary file
|
|
@@ -28,14 +28,14 @@ def not_called():
|
|
|
28
28
|
raise AssertionError("This should not be called")
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
class PyHookableMixin
|
|
31
|
+
class PyHookableMixin:
|
|
32
32
|
|
|
33
33
|
def _callFUT(self, *args, **kw):
|
|
34
34
|
from zope.hookable import _py_hookable
|
|
35
35
|
return _py_hookable(*args, **kw)
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
class HookableMixin
|
|
38
|
+
class HookableMixin:
|
|
39
39
|
|
|
40
40
|
def _callFUT(self, *args, **kw):
|
|
41
41
|
from zope.hookable import _py_hookable
|
|
@@ -50,10 +50,15 @@ class PyHookableTests(PyHookableMixin,
|
|
|
50
50
|
|
|
51
51
|
def test_pure_python(self):
|
|
52
52
|
from zope.hookable import _PURE_PYTHON
|
|
53
|
+
from zope.hookable import _PYPY_OR_JAVA
|
|
53
54
|
from zope.hookable import _c_hookable
|
|
54
55
|
from zope.hookable import _py_hookable
|
|
55
56
|
from zope.hookable import hookable
|
|
56
|
-
|
|
57
|
+
|
|
58
|
+
if _PYPY_OR_JAVA or _PURE_PYTHON:
|
|
59
|
+
self.assertIs(hookable, _py_hookable)
|
|
60
|
+
else:
|
|
61
|
+
self.assertIs(hookable, _c_hookable)
|
|
57
62
|
|
|
58
63
|
def test_before_hook(self):
|
|
59
64
|
hooked = self._callFUT(return_foo)
|
|
@@ -107,7 +112,7 @@ class PyHookableTests(PyHookableMixin,
|
|
|
107
112
|
self._callFUT(nonesuch=42)
|
|
108
113
|
|
|
109
114
|
def test_class(self):
|
|
110
|
-
class C
|
|
115
|
+
class C:
|
|
111
116
|
pass
|
|
112
117
|
|
|
113
118
|
hooked = self._callFUT(C)
|
|
@@ -137,7 +142,7 @@ class TestIssue6Py(PyHookableMixin,
|
|
|
137
142
|
self._check_preserves_doc(docs)
|
|
138
143
|
|
|
139
144
|
def test_preserves_doc_class(self):
|
|
140
|
-
class Docs
|
|
145
|
+
class Docs:
|
|
141
146
|
"""I have some docs"""
|
|
142
147
|
|
|
143
148
|
self._check_preserves_doc(Docs)
|
|
@@ -151,14 +156,14 @@ class TestIssue6Py(PyHookableMixin,
|
|
|
151
156
|
self.assertEqual({}, hooked.__dict__)
|
|
152
157
|
|
|
153
158
|
def test_bases_class(self):
|
|
154
|
-
class C
|
|
159
|
+
class C:
|
|
155
160
|
pass
|
|
156
161
|
self.assertEqual(C.__bases__, (object,))
|
|
157
162
|
hooked = self._callFUT(C)
|
|
158
163
|
self.assertEqual(hooked.__bases__, (object,))
|
|
159
164
|
|
|
160
165
|
def test_dict_class(self):
|
|
161
|
-
class C
|
|
166
|
+
class C:
|
|
162
167
|
pass
|
|
163
168
|
|
|
164
169
|
hooked = self._callFUT(C)
|
|
@@ -176,7 +181,7 @@ class TestIssue6Py(PyHookableMixin,
|
|
|
176
181
|
def test_unicode_attribute_name(self):
|
|
177
182
|
# Specifically for the C implementation, which has to deal with this
|
|
178
183
|
hooked = self._callFUT(return_foo)
|
|
179
|
-
result = hooked.__getattribute__(
|
|
184
|
+
result = hooked.__getattribute__('__bases__')
|
|
180
185
|
self.assertEqual(result, ())
|
|
181
186
|
|
|
182
187
|
def test_short_name(self):
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import sys, types, os;p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('zope',));importlib = __import__('importlib.util');__import__('importlib.machinery');m = sys.modules.setdefault('zope', importlib.util.module_from_spec(importlib.machinery.PathFinder.find_spec('zope', [os.path.dirname(p)])));m = m or sys.modules.setdefault('zope', types.ModuleType('zope'));mp = (m or []) and m.__dict__.setdefault('__path__',[]);(p not in mp) and mp.append(p)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: zope.hookable
|
|
3
|
-
Version:
|
|
3
|
+
Version: 7.0
|
|
4
4
|
Summary: Zope hookable
|
|
5
5
|
Home-page: http://github.com/zopefoundation/zope.hookable
|
|
6
6
|
Author: Zope Foundation and Contributors
|
|
@@ -12,25 +12,23 @@ Classifier: Intended Audience :: Developers
|
|
|
12
12
|
Classifier: License :: OSI Approved :: Zope Public License
|
|
13
13
|
Classifier: Operating System :: OS Independent
|
|
14
14
|
Classifier: Programming Language :: Python
|
|
15
|
-
Classifier: Programming Language :: Python :: 2
|
|
16
|
-
Classifier: Programming Language :: Python :: 2.7
|
|
17
15
|
Classifier: Programming Language :: Python :: 3
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.5
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.6
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
21
16
|
Classifier: Programming Language :: Python :: 3.8
|
|
22
17
|
Classifier: Programming Language :: Python :: 3.9
|
|
23
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
24
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
25
22
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
26
23
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
27
24
|
Classifier: Framework :: Zope :: 3
|
|
28
25
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
29
|
-
Requires-Python: >=
|
|
26
|
+
Requires-Python: >=3.8
|
|
30
27
|
License-File: LICENSE.txt
|
|
31
28
|
Requires-Dist: setuptools
|
|
32
29
|
Provides-Extra: docs
|
|
33
30
|
Requires-Dist: Sphinx ; extra == 'docs'
|
|
31
|
+
Requires-Dist: sphinx-rtd-theme ; extra == 'docs'
|
|
34
32
|
Provides-Extra: test
|
|
35
33
|
Requires-Dist: zope.testing ; extra == 'test'
|
|
36
34
|
Requires-Dist: zope.testrunner ; extra == 'test'
|
|
@@ -77,6 +75,28 @@ Documentation is hosted at https://zopehookable.readthedocs.io
|
|
|
77
75
|
Changes
|
|
78
76
|
=========
|
|
79
77
|
|
|
78
|
+
7.0 (2024-09-17)
|
|
79
|
+
================
|
|
80
|
+
|
|
81
|
+
- C extension now enables multi-phase module initialization (PEP 489).
|
|
82
|
+
For CPython >= 3.11, the ``hookable`` type is now a heap-allocated
|
|
83
|
+
type. See:
|
|
84
|
+
https://docs.python.org/3.13/howto/isolating-extensions.html
|
|
85
|
+
|
|
86
|
+
- Drop support for Python 3.7.
|
|
87
|
+
|
|
88
|
+
- Add support for Python 3.13.
|
|
89
|
+
|
|
90
|
+
- Build windows wheels on GHA.
|
|
91
|
+
|
|
92
|
+
6.0 (2023-10-05)
|
|
93
|
+
================
|
|
94
|
+
|
|
95
|
+
- Drop support for Python 2.7, 3.5, 3.6.
|
|
96
|
+
|
|
97
|
+
- Add support for Python 3.12.
|
|
98
|
+
|
|
99
|
+
|
|
80
100
|
5.4 (2022-11-17)
|
|
81
101
|
================
|
|
82
102
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
zope.hookable-7.0-py3.9-nspkg.pth,sha256=_l6EZJaefCi1yytmDbFQGX_jfS2gAtFyaDmlK1uFLec,457
|
|
2
|
+
zope.hookable-7.0.dist-info/namespace_packages.txt,sha256=QpUHvpO4wIuZDeEgKY8qZCtD-tAukB0fn_f6utzlb98,5
|
|
3
|
+
zope.hookable-7.0.dist-info/METADATA,sha256=ME_ifGrs1PRetGtNQEXQdxX76U5nPoeCoIciUaGre14,6175
|
|
4
|
+
zope.hookable-7.0.dist-info/top_level.txt,sha256=QpUHvpO4wIuZDeEgKY8qZCtD-tAukB0fn_f6utzlb98,5
|
|
5
|
+
zope.hookable-7.0.dist-info/RECORD,,
|
|
6
|
+
zope.hookable-7.0.dist-info/WHEEL,sha256=zw3m_8TS5Ligqz7c1oaFc6d0ApnSUTui8wLygn7hFqw,149
|
|
7
|
+
zope.hookable-7.0.dist-info/LICENSE.txt,sha256=PmcdsR32h1FswdtbPWXkqjg-rKPCDOo_r1Og9zNdCjw,2070
|
|
8
|
+
zope/hookable/_zope_hookable.cpython-39-aarch64-linux-gnu.so,sha256=7i8gvNzNcysAEh18kAeYjKyPI6AjJ2FhcPQrYGuFsXU,93152
|
|
9
|
+
zope/hookable/__init__.py,sha256=MCERh1crK21EutC4dfGTpE3-IkeiJ-UV7NQZnHj860Q,2452
|
|
10
|
+
zope/hookable/_zope_hookable.c,sha256=N9LOxTLZ-fZN8o_iNg8mjUNCX4na4UoGO0eDrkIqLic,7452
|
|
11
|
+
zope/hookable/tests/test_hookable.py,sha256=3FdXSprA60j5eX3LftT6MZG80moqG-0tTwQn_KjNLQc,6330
|
|
12
|
+
zope/hookable/tests/test_compile_flags.py,sha256=91siNUs2kotDUYpVV1vAZ_opWhZ50X4_DYkIiNMh6h0,1289
|
|
13
|
+
zope/hookable/tests/__init__.py,sha256=Z9EJNKBQorYcdV6oaIRTRgF41SMRZEEoLltZCKyVPI8,47
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import sys, types, os;has_mfs = sys.version_info > (3, 5);p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('zope',));importlib = has_mfs and __import__('importlib.util');has_mfs and __import__('importlib.machinery');m = has_mfs and sys.modules.setdefault('zope', importlib.util.module_from_spec(importlib.machinery.PathFinder.find_spec('zope', [os.path.dirname(p)])));m = m or sys.modules.setdefault('zope', types.ModuleType('zope'));mp = (m or []) and m.__dict__.setdefault('__path__',[]);(p not in mp) and mp.append(p)
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
zope.hookable-5.4-py3.9-nspkg.pth,sha256=SWEVH-jEWsKYrL0qoC6GBJaStx_iKxGoAY9PQycFVC4,529
|
|
2
|
-
zope/hookable/_zope_hookable.c,sha256=rnXI_8dreoBTWz15HB-WW69WDtcE-4tpODtb-_R0eVQ,7751
|
|
3
|
-
zope/hookable/_zope_hookable.cpython-39-aarch64-linux-gnu.so,sha256=7mKBM9Owd1SduRqiKqC_MIuNfxst7hJvme0Ugv04P88,91336
|
|
4
|
-
zope/hookable/__init__.py,sha256=2Ti7Bb9moOaABz-5j3068ILhZnjE10nwXEAuBzVH7kE,2198
|
|
5
|
-
zope/hookable/tests/test_hookable.py,sha256=juJLN3MLc369HF3VQE9njjEI2E2NPdzLDuz2vxYQ1KY,6254
|
|
6
|
-
zope/hookable/tests/test_compile_flags.py,sha256=91siNUs2kotDUYpVV1vAZ_opWhZ50X4_DYkIiNMh6h0,1289
|
|
7
|
-
zope/hookable/tests/__init__.py,sha256=Z9EJNKBQorYcdV6oaIRTRgF41SMRZEEoLltZCKyVPI8,47
|
|
8
|
-
zope.hookable-5.4.dist-info/LICENSE.txt,sha256=PmcdsR32h1FswdtbPWXkqjg-rKPCDOo_r1Og9zNdCjw,2070
|
|
9
|
-
zope.hookable-5.4.dist-info/top_level.txt,sha256=QpUHvpO4wIuZDeEgKY8qZCtD-tAukB0fn_f6utzlb98,5
|
|
10
|
-
zope.hookable-5.4.dist-info/namespace_packages.txt,sha256=QpUHvpO4wIuZDeEgKY8qZCtD-tAukB0fn_f6utzlb98,5
|
|
11
|
-
zope.hookable-5.4.dist-info/WHEEL,sha256=SIpKeEMEn5d6wEWNi6guiW3hSiu5nA1wuuKXWVovQCE,150
|
|
12
|
-
zope.hookable-5.4.dist-info/RECORD,,
|
|
13
|
-
zope.hookable-5.4.dist-info/METADATA,sha256=RaXfq9Dxa_r6tktciVzwIfjk7wpPtquBhD3NFVn2ENE,5852
|
|
File without changes
|
|
File without changes
|
|
File without changes
|