Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Python 3.10 #238

Merged
merged 3 commits into from May 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 10 additions & 3 deletions .github/workflows/tests.yml
Expand Up @@ -23,7 +23,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: [2.7, 3.5, 3.6, 3.7, 3.8, 3.9]
python-version: [2.7, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10.0-beta.1]
os: [ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@v2
Expand Down Expand Up @@ -77,7 +77,7 @@ jobs:
strategy:
matrix:
python-version: [3.9]
image: [manylinux2010_x86_64, manylinux2014_aarch64, manylinux2014_ppc64le]
image: [manylinux2010_x86_64, manylinux2014_aarch64, manylinux2014_ppc64le, manylinux2014_x86_64]

steps:
- name: checkout
Expand All @@ -95,10 +95,17 @@ jobs:
#run: |
# docker run --rm --privileged multiarch/qemu-user-static:register --reset
- name: Build and test greenlet
if: matrix.image == 'manylinux2010_x86_64'
# An alternate way to do this is to run the container directly with a uses:
# and then the script runs inside it. That may work better with caching.
# See https://github.com/pyca/bcrypt/blob/f6b5ee2eda76d077c531362ac65e16f045cf1f29/.github/workflows/wheel-builder.yml
# The 2010 image is the last one that comes with Python 2.7.
# The 2010 image is the last one that comes with Python 2.7,
# and only up through the tag 2021-02-06-3d322a5
env:
DOCKER_IMAGE: quay.io/pypa/${{ matrix.image }}:2021-02-06-3d322a5
run: bash ./make-manylinux
- name: Build and test greenlet (other)
if: matrix.image != 'manylinux2010_x86_64'
env:
DOCKER_IMAGE: quay.io/pypa/${{ matrix.image }}
run: bash ./make-manylinux
Expand Down
5 changes: 3 additions & 2 deletions CHANGES.rst
Expand Up @@ -2,10 +2,11 @@
Changes
=========

1.0.1 (unreleased)
1.1.0 (unreleased)
==================

- Nothing changed yet.
- Add support for Python 3.10. Pre-built binary wheels are not
currently available for 3.10.


1.0.0 (2021-01-13)
Expand Down
2 changes: 1 addition & 1 deletion make-manylinux
Expand Up @@ -27,7 +27,7 @@ if [ -d /greenlet -a -d /opt/python ]; then
mkdir -p /greenlet/wheelhouse
OPATH="$PATH"
which auditwheel
for variant in `ls -d /opt/python/cp{27,35,36,37,38,39}*`; do
for variant in `ls -d /opt/python/cp{27,35,36,37,38,39,310}*`; do
export PATH="$variant/bin:$OPATH"
echo "Building $variant $(python --version)"

Expand Down
1 change: 1 addition & 0 deletions setup.py
Expand Up @@ -138,6 +138,7 @@ def get_greenlet_version():
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Operating System :: OS Independent',
'Topic :: Software Development :: Libraries :: Python Modules'
],
Expand Down
34 changes: 30 additions & 4 deletions src/greenlet/greenlet.c
Expand Up @@ -96,6 +96,19 @@ extern PyTypeObject PyGreenlet_Type;
# define GREENLET_PY37 0
#endif

#if PY_VERSION_HEX >= 0x30A00B1
/*
Python 3.10 beta 1 changed tstate->use_tracing to a nested cframe member.
See https://github.com/python/cpython/pull/25276
We have to save and restore this as well.
*/
#define TSTATE_USE_TRACING(tstate) (tstate->cframe->use_tracing)
#define GREENLET_USE_CFRAME 1
#else
#define TSTATE_USE_TRACING(tstate) (tstate->use_tracing)
#define GREENLET_USE_CFRAME 0
#endif

#ifndef Py_SET_REFCNT
/* Py_REFCNT and Py_SIZE macros are converted to functions
https://bugs.python.org/issue39573 */
Expand Down Expand Up @@ -504,6 +517,9 @@ g_switchstack(void)
current->exc_type = tstate->exc_type;
current->exc_value = tstate->exc_value;
current->exc_traceback = tstate->exc_traceback;
#endif
#if GREENLET_USE_CFRAME
current->cframe = tstate->cframe;
#endif
}
err = slp_switch();
Expand Down Expand Up @@ -548,6 +564,10 @@ g_switchstack(void)
#endif
green_clear_exc(target);

#if GREENLET_USE_CFRAME
tstate->cframe = target->cframe;
#endif

assert(ts_origin == NULL);
Py_INCREF(target);
ts_current = target;
Expand All @@ -567,10 +587,10 @@ g_calltrace(PyObject* tracefunc, PyObject* event, PyGreenlet* origin,
PyErr_Fetch(&exc_type, &exc_val, &exc_tb);
tstate = PyThreadState_GET();
tstate->tracing++;
tstate->use_tracing = 0;
TSTATE_USE_TRACING(tstate) = 0;
retval = PyObject_CallFunction(tracefunc, "O(OO)", event, origin, target);
tstate->tracing--;
tstate->use_tracing =
TSTATE_USE_TRACING(tstate) =
(tstate->tracing <= 0 &&
((tstate->c_tracefunc != NULL) || (tstate->c_profilefunc != NULL)));
if (retval == NULL) {
Expand Down Expand Up @@ -897,6 +917,9 @@ green_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
}
Py_INCREF(ts_current);
((PyGreenlet*)o)->parent = ts_current;
#if GREENLET_USE_CFRAME
((PyGreenlet*)o)->cframe = &PyThreadState_GET()->root_cframe;
#endif
}
return o;
}
Expand Down Expand Up @@ -1601,8 +1624,9 @@ PyGreenlet_SetParent(PyGreenlet* g, PyGreenlet* nparent)
static PyGreenlet*
PyGreenlet_New(PyObject* run, PyGreenlet* parent)
{
/* XXX: Why doesn't this call green_new()? There's some duplicate
code. */
PyGreenlet* g = NULL;

g = (PyGreenlet*)PyType_GenericAlloc(&PyGreenlet_Type, 0);
if (g == NULL) {
return NULL;
Expand All @@ -1625,7 +1649,9 @@ PyGreenlet_New(PyObject* run, PyGreenlet* parent)
return NULL;
}
}

#if GREENLET_USE_CFRAME
g->cframe = &PyThreadState_GET()->root_cframe;
#endif
return g;
}

Expand Down
3 changes: 3 additions & 0 deletions src/greenlet/greenlet.h
Expand Up @@ -38,6 +38,9 @@ typedef struct _greenlet {
#if PY_VERSION_HEX >= 0x030700A3
PyObject* context;
#endif
#if PY_VERSION_HEX >= 0x30A00B1
CFrame* cframe;
#endif
} PyGreenlet;

#define PyGreenlet_Check(op) PyObject_TypeCheck(op, &PyGreenlet_Type)
Expand Down
3 changes: 3 additions & 0 deletions src/greenlet/tests/test_extension_interface.py
Expand Up @@ -72,3 +72,6 @@ def foo():
str(seen[0]),
'take that sucka!',
"message doesn't match")

if __name__ == '__main__':
unittest.main()
2 changes: 1 addition & 1 deletion tox.ini
@@ -1,6 +1,6 @@
[tox]
envlist =
py27,py35,py36,py37,py38,py39,docs
py27,py35,py36,py37,py38,py39,py310,docs

[testenv]
commands =
Expand Down