Skip to content

Commit 7474800

Browse files
committed
Fix use of PyContext* APIs in 3.7.1
See https://bugs.python.org/issue34762 for details.
1 parent 9fc3ca2 commit 7474800

File tree

4 files changed

+51
-33
lines changed

4 files changed

+51
-33
lines changed

Diff for: uvloop/cbhandles.pyx

+6-20
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,9 @@ cdef class Handle:
1515
self._source_traceback = extract_stack()
1616

1717
cdef inline _set_context(self, object context):
18-
cdef PyContext* current_context
19-
2018
if PY37:
2119
if context is None:
22-
context = copy_current_context()
20+
context = Context_CopyCurrent()
2321
self.context = context
2422
else:
2523
if context is not None:
@@ -54,7 +52,7 @@ cdef class Handle:
5452
try:
5553
if PY37:
5654
assert self.context is not None
57-
PyContext_Enter(<PyContext*>self.context)
55+
Context_Enter(self.context)
5856

5957
if cb_type == 1:
6058
callback = self.arg1
@@ -103,7 +101,7 @@ cdef class Handle:
103101
context = self.context
104102
Py_DECREF(self)
105103
if PY37:
106-
PyContext_Exit(<PyContext*>context)
104+
Context_Exit(context)
107105

108106
cdef _cancel(self):
109107
self._cancelled = 1
@@ -181,7 +179,7 @@ cdef class TimerHandle:
181179

182180
if PY37:
183181
if context is None:
184-
context = copy_current_context()
182+
context = Context_CopyCurrent()
185183
self.context = context
186184
else:
187185
if context is not None:
@@ -239,7 +237,7 @@ cdef class TimerHandle:
239237
try:
240238
if PY37:
241239
assert self.context is not None
242-
PyContext_Enter(<PyContext*>self.context)
240+
Context_Enter(self.context)
243241

244242
if args is not None:
245243
callback(*args)
@@ -267,7 +265,7 @@ cdef class TimerHandle:
267265
context = self.context
268266
Py_DECREF(self)
269267
if PY37:
270-
PyContext_Exit(<PyContext*>context)
268+
Context_Exit(context)
271269

272270
# Public API
273271

@@ -402,15 +400,3 @@ cdef extract_stack():
402400

403401
stack.reverse()
404402
return stack
405-
406-
407-
cdef copy_current_context():
408-
cdef PyContext* current_context
409-
410-
if PY37:
411-
current_context = PyContext_CopyCurrent()
412-
py_context = <object>current_context
413-
Py_XDECREF(<PyObject*>current_context)
414-
return py_context
415-
416-
raise NotImplementedError('"contextvars" support requires Python 3.7+')

Diff for: uvloop/includes/compat.h

+38-9
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,53 @@ int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) {};
3131

3232

3333
#if PY_VERSION_HEX < 0x03070000
34-
typedef struct {
35-
PyObject_HEAD
36-
} PyContext;
3734

38-
PyContext * PyContext_CopyCurrent(void) {
39-
abort();
35+
PyObject * Context_CopyCurrent(void) {
36+
PyErr_SetString(PyExc_NotImplementedError,
37+
'"contextvars" support requires Python 3.7+');
4038
return NULL;
4139
};
4240

43-
int PyContext_Enter(PyContext *ctx) {
44-
abort();
41+
int Context_Enter(PyObject *ctx) {
42+
PyErr_SetString(PyExc_NotImplementedError,
43+
'"contextvars" support requires Python 3.7+');
4544
return -1;
4645
}
4746

48-
int PyContext_Exit(PyContext *ctx) {
49-
abort();
47+
int Context_Exit(PyObject *ctx) {
48+
PyErr_SetString(PyExc_NotImplementedError,
49+
'"contextvars" support requires Python 3.7+');
5050
return -1;
5151
}
52+
53+
#elif PY_VERSION_HEX < 0x03070100
54+
55+
PyObject * Context_CopyCurrent(void) {
56+
return (PyObject *)PyContext_CopyCurrent();
57+
};
58+
59+
int Context_Enter(PyObject *ctx) {
60+
return PyContext_Enter((PyContext *)ctx);
61+
}
62+
63+
int Context_Exit(PyObject *ctx) {
64+
return PyContext_Exit((PyContext *)ctx);
65+
}
66+
67+
#else
68+
69+
PyObject * Context_CopyCurrent(void) {
70+
return PyContext_CopyCurrent();
71+
};
72+
73+
int Context_Enter(PyObject *ctx) {
74+
return PyContext_Enter(ctx);
75+
}
76+
77+
int Context_Exit(PyObject *ctx) {
78+
return PyContext_Exit(ctx);
79+
}
80+
5281
#endif
5382

5483

Diff for: uvloop/includes/python.pxd

+4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ cdef extern from "includes/compat.h":
1818
int PyContext_Enter(PyContext *) except -1
1919
int PyContext_Exit(PyContext *) except -1
2020

21+
object Context_CopyCurrent()
22+
int Context_Enter(object) except -1
23+
int Context_Exit(object) except -1
24+
2125
void PyOS_BeforeFork()
2226
void PyOS_AfterFork_Parent()
2327
void PyOS_AfterFork_Child()

Diff for: uvloop/loop.pyx

+3-4
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@ from .includes.python cimport PY_VERSION_HEX, \
1212
PyUnicode_EncodeFSDefault, \
1313
PyErr_SetInterrupt, \
1414
_Py_RestoreSignals, \
15-
PyContext, \
16-
PyContext_CopyCurrent, \
17-
PyContext_Enter, \
18-
PyContext_Exit, \
15+
Context_CopyCurrent, \
16+
Context_Enter, \
17+
Context_Exit, \
1918
PyOS_AfterFork_Parent, PyOS_AfterFork_Child, \
2019
PyOS_BeforeFork
2120

0 commit comments

Comments
 (0)