From 956f0fde6178100925e79d5d894e531e2a73ec2f Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Mon, 2 May 2022 06:44:32 -0400 Subject: [PATCH] fix: fix compilation errors on latest 3.11.0 --- .github/workflows/coverage.yml | 2 +- .github/workflows/kit.yml | 2 +- CHANGES.rst | 5 ++++- README.rst | 2 +- coverage/ctracer/tracer.c | 21 +++++++++++++++------ coverage/ctracer/util.h | 18 +++++++++++++++--- doc/index.rst | 2 +- 7 files changed, 38 insertions(+), 14 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index bbb7d4a1e..6749622fd 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -39,7 +39,7 @@ jobs: - "3.8" - "3.9" - "3.10" - - "3.11.0-alpha.5" + - "3.11.0-beta.1" - "pypy-3.7" exclude: # Windows PyPy doesn't seem to work? diff --git a/.github/workflows/kit.yml b/.github/workflows/kit.yml index d0c8af5c5..84c1893d9 100644 --- a/.github/workflows/kit.yml +++ b/.github/workflows/kit.yml @@ -239,7 +239,7 @@ jobs: py: # PYVERSIONS. Available versions: # https://github.com/actions/python-versions/blob/main/versions-manifest.json - - "3.11.0-alpha.5" + - "3.11.0-beta.1" fail-fast: false steps: diff --git a/CHANGES.rst b/CHANGES.rst index f7c5b6bb5..16b6712d5 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -20,7 +20,10 @@ development at the same time, such as 4.5.x and 5.0. Unreleased ---------- -Nothing yet. +- Fix: Coverage.py now builds successfully on CPython 3.11 (3.11.0b1) again. + Closes `issue 1367`_. Some results for generators may have changed. + +.. _issue 1367: https://github.com/nedbat/coveragepy/issues/1367 .. _changes_632: diff --git a/README.rst b/README.rst index 06e6d93b8..d5195db9b 100644 --- a/README.rst +++ b/README.rst @@ -27,7 +27,7 @@ Coverage.py runs on these versions of Python: .. PYVERSIONS -* CPython 3.7 through 3.11.0a5. +* CPython 3.7 through 3.11.0b1. * PyPy3 7.3.8. Documentation is on `Read the Docs`_. Code repository and issue tracker are on diff --git a/coverage/ctracer/tracer.c b/coverage/ctracer/tracer.c index 80d24b3f7..442ea514f 100644 --- a/coverage/ctracer/tracer.c +++ b/coverage/ctracer/tracer.c @@ -307,6 +307,9 @@ CTracer_handle_call(CTracer *self, PyFrameObject *frame) PyObject * plugin = NULL; PyObject * plugin_name = NULL; PyObject * next_tracename = NULL; +#ifdef RESUME + PyObject * pCode = NULL; +#endif /* Borrowed references. */ PyObject * filename = NULL; @@ -526,16 +529,16 @@ CTracer_handle_call(CTracer *self, PyFrameObject *frame) */ BOOL real_call = FALSE; -#ifdef RESUME // 3.11.0a4 +#ifdef RESUME /* * The current opcode is guaranteed to be RESUME. The argument * determines what kind of resume it is. */ - PyObject * pCode = MyFrame_GetCode(frame)->co_code; - real_call = (PyBytes_AS_STRING(pCode)[MyFrame_lasti(frame) + 1] == 0); + pCode = MyCode_GetCode(MyFrame_GetCode(frame)); + real_call = (PyBytes_AS_STRING(pCode)[MyFrame_GetLasti(frame) + 1] == 0); #else // f_lasti is -1 for a true call, and a real byte offset for a generator re-entry. - real_call = (MyFrame_lasti(frame) < 0); + real_call = (MyFrame_GetLasti(frame) < 0); #endif if (real_call) { @@ -549,6 +552,9 @@ CTracer_handle_call(CTracer *self, PyFrameObject *frame) ret = RET_OK; error: +#ifdef RESUME + MyCode_FreeCode(pCode); +#endif Py_XDECREF(next_tracename); Py_XDECREF(disposition); Py_XDECREF(plugin); @@ -689,6 +695,8 @@ CTracer_handle_return(CTracer *self, PyFrameObject *frame) { int ret = RET_ERROR; + PyObject * pCode = NULL; + STATS( self->stats.returns++; ) /* A near-copy of this code is above in the missing-return handler. */ if (CTracer_set_pdata_stack(self) < 0) { @@ -699,8 +707,8 @@ CTracer_handle_return(CTracer *self, PyFrameObject *frame) if (self->pdata_stack->depth >= 0) { if (self->tracing_arcs && self->pcur_entry->file_data) { BOOL real_return = FALSE; - PyObject * pCode = MyFrame_GetCode(frame)->co_code; - int lasti = MyFrame_lasti(frame); + pCode = MyCode_GetCode(MyFrame_GetCode(frame)); + int lasti = MyFrame_GetLasti(frame); Py_ssize_t code_size = PyBytes_GET_SIZE(pCode); unsigned char * code_bytes = (unsigned char *)PyBytes_AS_STRING(pCode); #ifdef RESUME @@ -760,6 +768,7 @@ CTracer_handle_return(CTracer *self, PyFrameObject *frame) error: + MyCode_FreeCode(pCode); return ret; } diff --git a/coverage/ctracer/util.h b/coverage/ctracer/util.h index 58fa1d490..be49a9610 100644 --- a/coverage/ctracer/util.h +++ b/coverage/ctracer/util.h @@ -17,13 +17,17 @@ // to make this work, but it's all I've got until https://bugs.python.org/issue40421 // is resolved. #include -#define MyFrame_lasti(f) ((f)->f_frame->f_lasti * 2) +#if PY_VERSION_HEX >= 0x030B00A7 +#define MyFrame_GetLasti(f) (PyFrame_GetLasti(f)) +#else +#define MyFrame_GetLasti(f) ((f)->f_frame->f_lasti * 2) +#endif #elif PY_VERSION_HEX >= 0x030A00A7 // The f_lasti field changed meaning in 3.10.0a7. It had been bytes, but // now is instructions, so we need to adjust it to use it as a byte index. -#define MyFrame_lasti(f) ((f)->f_lasti * 2) +#define MyFrame_GetLasti(f) ((f)->f_lasti * 2) #else -#define MyFrame_lasti(f) ((f)->f_lasti) +#define MyFrame_GetLasti(f) ((f)->f_lasti) #endif // Access f_code should be done through a helper starting in 3.9. @@ -33,6 +37,14 @@ #define MyFrame_GetCode(f) ((f)->f_code) #endif +#if PY_VERSION_HEX >= 0x030B00A7 +#define MyCode_GetCode(co) (PyObject_GetAttrString((PyObject *)(co), "co_code")) +#define MyCode_FreeCode(code) Py_XDECREF(code) +#else +#define MyCode_GetCode(co) ((co)->co_code) +#define MyCode_FreeCode(code) +#endif + /* The values returned to indicate ok or error. */ #define RET_OK 0 #define RET_ERROR -1 diff --git a/doc/index.rst b/doc/index.rst index d296fc9cc..bbfe48096 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -18,7 +18,7 @@ supported on: .. PYVERSIONS -* Python versions 3.7 through 3.11.0a5. +* Python versions 3.7 through 3.11.0b1. * PyPy3 7.3.8.