Author vstinner
Recipients njs, vstinner
Date 2021-02-18.11:21:34
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1613647294.57.0.745628645388.issue43250@roundup.psfhosted.org>
In-reply-to
Content
In Python 3.6, there was a WANT_SIGFPE_HANDLER macro defined if Python was built with ./configure --with-fpectl. By default, the macro was not defined. The fpectl module installed a SIGFPE signal handler which uses longjmp(). If the WANT_SIGFPE_HANDLER macro was defined, PyFPE_START_PROTECT() and PyFPE_END_PROTECT() macros used setjmp() to catch SIGFPE.

All of this machinery was removed by bpo-29137 to fix ABI issues:

commit 735ae8d139a673b30b321dc10acfd3d14f0d633b
Author: Nathaniel J. Smith <njs@pobox.com>
Date:   Fri Jan 5 23:15:34 2018 -0800

    bpo-29137: Remove fpectl module (#4789)
    
    This module has never been enabled by default, never worked correctly
    on x86-64, and caused ABI problems that caused C extension
    compatibility. See bpo-29137 for details/discussion.

The PyFPE_START_PROTECT() and PyFPE_END_PROTECT() macros still exist for backward compatibility with Python 3.6 and older. Python/pyfpe.c contains the comment:

/* These variables used to be used when Python was built with --with-fpectl,
 * but support for that was dropped in 3.7. We continue to define them,
 * though, because they may be referenced by extensions using the stable ABI.
 */

I'm not convinced that these macros are part of the stable ABI. The PEP 384 doesn't exclude pyfpe.h explicitly, but it's also unclear if it's part of the stable ABI or not. "PyFPE_START_PROTECT" and "PyFPE_END_PROTECT" symbols are not part of the stable ABI at least: they are missing from PC/python3dll.c and Doc/data/stable_abi.dat. Well, these are macros which emitted directly code rather than calling an opaque function. That sounds really bad in term of stable ABI :-(

Python 3.6 macros, when WANT_SIGFPE_HANDLER macro is defined:

---
#include <signal.h>
#include <setjmp.h>
#include <math.h>
extern jmp_buf PyFPE_jbuf;
extern int PyFPE_counter;
extern double PyFPE_dummy(void *);

#define PyFPE_START_PROTECT(err_string, leave_stmt) \
if (!PyFPE_counter++ && setjmp(PyFPE_jbuf)) { \
	PyErr_SetString(PyExc_FloatingPointError, err_string); \
	PyFPE_counter = 0; \
	leave_stmt; \
}

#define PyFPE_END_PROTECT(v) PyFPE_counter -= (int)PyFPE_dummy(&(v));
---

I propose to either deprecate these macros or remove them. These macros are not documented.

In Python 3.6, the PyFPE macros were used in the Python stdlib, by files:

Doc/library/fpectl.rst
Include/pyfpe.h
Modules/_tkinter.c
Modules/clinic/cmathmodule.c.h
Modules/cmathmodule.c
Modules/fpetestmodule.c
Modules/mathmodule.c
Objects/complexobject.c
Objects/floatobject.c
Python/bltinmodule.c
Python/pystrtod.c

But it doesn't seem to be used outside Python.

Note: In master, they are not used anywhere, they are only defined by Include/pyfpe.h.
History
Date User Action Args
2021-02-18 11:21:34vstinnersetrecipients: + vstinner, njs
2021-02-18 11:21:34vstinnersetmessageid: <1613647294.57.0.745628645388.issue43250@roundup.psfhosted.org>
2021-02-18 11:21:34vstinnerlinkissue43250 messages
2021-02-18 11:21:34vstinnercreate