gh-141004: soft-deprecate Py_INFINITY macro (#141033)

Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
Sergey B Kirpichev
2025-11-12 15:44:49 +03:00
committed by GitHub
parent c6f3dd6a50
commit e2026731f5
13 changed files with 45 additions and 36 deletions

View File

@@ -105,7 +105,7 @@ The following functions provide locale-independent string to number conversions.
If ``s`` represents a value that is too large to store in a float If ``s`` represents a value that is too large to store in a float
(for example, ``"1e500"`` is such a string on many platforms) then (for example, ``"1e500"`` is such a string on many platforms) then
if ``overflow_exception`` is ``NULL`` return ``Py_INFINITY`` (with if ``overflow_exception`` is ``NULL`` return :c:macro:`!INFINITY` (with
an appropriate sign) and don't set any exception. Otherwise, an appropriate sign) and don't set any exception. Otherwise,
``overflow_exception`` must point to a Python exception object; ``overflow_exception`` must point to a Python exception object;
raise that exception and return ``-1.0``. In both cases, set raise that exception and return ``-1.0``. In both cases, set

View File

@@ -83,8 +83,11 @@ Floating-Point Objects
This macro expands a to constant expression of type :c:expr:`double`, that This macro expands a to constant expression of type :c:expr:`double`, that
represents the positive infinity. represents the positive infinity.
On most platforms, this is equivalent to the :c:macro:`!INFINITY` macro from It is equivalent to the :c:macro:`!INFINITY` macro from the C11 standard
the C11 standard ``<math.h>`` header. ``<math.h>`` header.
.. deprecated:: 3.15
The macro is soft deprecated.
.. c:macro:: Py_NAN .. c:macro:: Py_NAN

View File

@@ -3045,7 +3045,7 @@ Deprecated C APIs
----------------- -----------------
* The :c:macro:`!Py_HUGE_VAL` macro is now :term:`soft deprecated`. * The :c:macro:`!Py_HUGE_VAL` macro is now :term:`soft deprecated`.
Use :c:macro:`!Py_INFINITY` instead. Use :c:macro:`!INFINITY` instead.
(Contributed by Sergey B Kirpichev in :gh:`120026`.) (Contributed by Sergey B Kirpichev in :gh:`120026`.)
* The :c:macro:`!Py_IS_NAN`, :c:macro:`!Py_IS_INFINITY`, * The :c:macro:`!Py_IS_NAN`, :c:macro:`!Py_IS_INFINITY`,

View File

@@ -1095,6 +1095,10 @@ Deprecated C APIs
since 3.15 and will be removed in 3.17. since 3.15 and will be removed in 3.17.
(Contributed by Nikita Sobolev in :gh:`136355`.) (Contributed by Nikita Sobolev in :gh:`136355`.)
* :c:macro:`!Py_INFINITY` macro is :term:`soft deprecated`,
use the C11 standard ``<math.h>`` :c:macro:`!INFINITY` instead.
(Contributed by Sergey B Kirpichev in :gh:`141004`.)
* :c:macro:`!Py_MATH_El` and :c:macro:`!Py_MATH_PIl` are deprecated * :c:macro:`!Py_MATH_El` and :c:macro:`!Py_MATH_PIl` are deprecated
since 3.15 and will be removed in 3.20. since 3.15 and will be removed in 3.20.
(Contributed by Sergey B Kirpichev in :gh:`141004`.) (Contributed by Sergey B Kirpichev in :gh:`141004`.)

View File

@@ -21,10 +21,10 @@ PyAPI_DATA(PyTypeObject) PyFloat_Type;
#define Py_RETURN_INF(sign) \ #define Py_RETURN_INF(sign) \
do { \ do { \
if (copysign(1., sign) == 1.) { \ if (copysign(1., sign) == 1.) { \
return PyFloat_FromDouble(Py_INFINITY); \ return PyFloat_FromDouble(INFINITY); \
} \ } \
else { \ else { \
return PyFloat_FromDouble(-Py_INFINITY); \ return PyFloat_FromDouble(-INFINITY); \
} \ } \
} while(0) } while(0)

View File

@@ -33,7 +33,7 @@ extern "C" {
static inline void _Py_ADJUST_ERANGE1(double x) static inline void _Py_ADJUST_ERANGE1(double x)
{ {
if (errno == 0) { if (errno == 0) {
if (x == Py_INFINITY || x == -Py_INFINITY) { if (x == INFINITY || x == -INFINITY) {
errno = ERANGE; errno = ERANGE;
} }
} }
@@ -44,8 +44,8 @@ static inline void _Py_ADJUST_ERANGE1(double x)
static inline void _Py_ADJUST_ERANGE2(double x, double y) static inline void _Py_ADJUST_ERANGE2(double x, double y)
{ {
if (x == Py_INFINITY || x == -Py_INFINITY || if (x == INFINITY || x == -INFINITY ||
y == Py_INFINITY || y == -Py_INFINITY) y == INFINITY || y == -INFINITY)
{ {
if (errno == 0) { if (errno == 0) {
errno = ERANGE; errno = ERANGE;

View File

@@ -45,13 +45,14 @@
#define Py_IS_FINITE(X) isfinite(X) #define Py_IS_FINITE(X) isfinite(X)
// Py_INFINITY: Value that evaluates to a positive double infinity. // Py_INFINITY: Value that evaluates to a positive double infinity.
// Soft deprecated since Python 3.15, use INFINITY instead.
#ifndef Py_INFINITY #ifndef Py_INFINITY
# define Py_INFINITY ((double)INFINITY) # define Py_INFINITY ((double)INFINITY)
#endif #endif
/* Py_HUGE_VAL should always be the same as Py_INFINITY. But historically /* Py_HUGE_VAL should always be the same as Py_INFINITY. But historically
* this was not reliable and Python did not require IEEE floats and C99 * this was not reliable and Python did not require IEEE floats and C99
* conformity. The macro was soft deprecated in Python 3.14, use Py_INFINITY instead. * conformity. The macro was soft deprecated in Python 3.14, use INFINITY instead.
*/ */
#ifndef Py_HUGE_VAL #ifndef Py_HUGE_VAL
# define Py_HUGE_VAL HUGE_VAL # define Py_HUGE_VAL HUGE_VAL

View File

@@ -0,0 +1 @@
The :c:macro:`!Py_INFINITY` macro is :term:`soft deprecated`.

View File

@@ -150,7 +150,7 @@ special_type(double d)
#define P14 0.25*Py_MATH_PI #define P14 0.25*Py_MATH_PI
#define P12 0.5*Py_MATH_PI #define P12 0.5*Py_MATH_PI
#define P34 0.75*Py_MATH_PI #define P34 0.75*Py_MATH_PI
#define INF Py_INFINITY #define INF INFINITY
#define N Py_NAN #define N Py_NAN
#define U -9.5426319407711027e33 /* unlikely value, used as placeholder */ #define U -9.5426319407711027e33 /* unlikely value, used as placeholder */
@@ -1186,11 +1186,11 @@ cmath_exec(PyObject *mod)
if (PyModule_Add(mod, "tau", PyFloat_FromDouble(Py_MATH_TAU)) < 0) { if (PyModule_Add(mod, "tau", PyFloat_FromDouble(Py_MATH_TAU)) < 0) {
return -1; return -1;
} }
if (PyModule_Add(mod, "inf", PyFloat_FromDouble(Py_INFINITY)) < 0) { if (PyModule_Add(mod, "inf", PyFloat_FromDouble(INFINITY)) < 0) {
return -1; return -1;
} }
Py_complex infj = {0.0, Py_INFINITY}; Py_complex infj = {0.0, INFINITY};
if (PyModule_Add(mod, "infj", PyComplex_FromCComplex(infj)) < 0) { if (PyModule_Add(mod, "infj", PyComplex_FromCComplex(infj)) < 0) {
return -1; return -1;
} }

View File

@@ -395,7 +395,7 @@ m_tgamma(double x)
if (x == 0.0) { if (x == 0.0) {
errno = EDOM; errno = EDOM;
/* tgamma(+-0.0) = +-inf, divide-by-zero */ /* tgamma(+-0.0) = +-inf, divide-by-zero */
return copysign(Py_INFINITY, x); return copysign(INFINITY, x);
} }
/* integer arguments */ /* integer arguments */
@@ -426,7 +426,7 @@ m_tgamma(double x)
} }
else { else {
errno = ERANGE; errno = ERANGE;
return Py_INFINITY; return INFINITY;
} }
} }
@@ -490,14 +490,14 @@ m_lgamma(double x)
if (isnan(x)) if (isnan(x))
return x; /* lgamma(nan) = nan */ return x; /* lgamma(nan) = nan */
else else
return Py_INFINITY; /* lgamma(+-inf) = +inf */ return INFINITY; /* lgamma(+-inf) = +inf */
} }
/* integer arguments */ /* integer arguments */
if (x == floor(x) && x <= 2.0) { if (x == floor(x) && x <= 2.0) {
if (x <= 0.0) { if (x <= 0.0) {
errno = EDOM; /* lgamma(n) = inf, divide-by-zero for */ errno = EDOM; /* lgamma(n) = inf, divide-by-zero for */
return Py_INFINITY; /* integers n <= 0 */ return INFINITY; /* integers n <= 0 */
} }
else { else {
return 0.0; /* lgamma(1) = lgamma(2) = 0.0 */ return 0.0; /* lgamma(1) = lgamma(2) = 0.0 */
@@ -633,7 +633,7 @@ m_log(double x)
return log(x); return log(x);
errno = EDOM; errno = EDOM;
if (x == 0.0) if (x == 0.0)
return -Py_INFINITY; /* log(0) = -inf */ return -INFINITY; /* log(0) = -inf */
else else
return Py_NAN; /* log(-ve) = nan */ return Py_NAN; /* log(-ve) = nan */
} }
@@ -676,7 +676,7 @@ m_log2(double x)
} }
else if (x == 0.0) { else if (x == 0.0) {
errno = EDOM; errno = EDOM;
return -Py_INFINITY; /* log2(0) = -inf, divide-by-zero */ return -INFINITY; /* log2(0) = -inf, divide-by-zero */
} }
else { else {
errno = EDOM; errno = EDOM;
@@ -692,7 +692,7 @@ m_log10(double x)
return log10(x); return log10(x);
errno = EDOM; errno = EDOM;
if (x == 0.0) if (x == 0.0)
return -Py_INFINITY; /* log10(0) = -inf */ return -INFINITY; /* log10(0) = -inf */
else else
return Py_NAN; /* log10(-ve) = nan */ return Py_NAN; /* log10(-ve) = nan */
} }
@@ -1500,7 +1500,7 @@ math_ldexp_impl(PyObject *module, double x, PyObject *i)
errno = 0; errno = 0;
} else if (exp > INT_MAX) { } else if (exp > INT_MAX) {
/* overflow */ /* overflow */
r = copysign(Py_INFINITY, x); r = copysign(INFINITY, x);
errno = ERANGE; errno = ERANGE;
} else if (exp < INT_MIN) { } else if (exp < INT_MIN) {
/* underflow to +-0 */ /* underflow to +-0 */
@@ -2983,7 +2983,7 @@ math_ulp_impl(PyObject *module, double x)
if (isinf(x)) { if (isinf(x)) {
return x; return x;
} }
double inf = Py_INFINITY; double inf = INFINITY;
double x2 = nextafter(x, inf); double x2 = nextafter(x, inf);
if (isinf(x2)) { if (isinf(x2)) {
/* special case: x is the largest positive representable float */ /* special case: x is the largest positive representable float */
@@ -3007,7 +3007,7 @@ math_exec(PyObject *module)
if (PyModule_Add(module, "tau", PyFloat_FromDouble(Py_MATH_TAU)) < 0) { if (PyModule_Add(module, "tau", PyFloat_FromDouble(Py_MATH_TAU)) < 0) {
return -1; return -1;
} }
if (PyModule_Add(module, "inf", PyFloat_FromDouble(Py_INFINITY)) < 0) { if (PyModule_Add(module, "inf", PyFloat_FromDouble(INFINITY)) < 0) {
return -1; return -1;
} }
if (PyModule_Add(module, "nan", PyFloat_FromDouble(fabs(Py_NAN))) < 0) { if (PyModule_Add(module, "nan", PyFloat_FromDouble(fabs(Py_NAN))) < 0) {

View File

@@ -139,8 +139,8 @@ _Py_c_prod(Py_complex z, Py_complex w)
recalc = 1; recalc = 1;
} }
if (recalc) { if (recalc) {
r.real = Py_INFINITY*(a*c - b*d); r.real = INFINITY*(a*c - b*d);
r.imag = Py_INFINITY*(a*d + b*c); r.imag = INFINITY*(a*d + b*c);
} }
} }
@@ -229,8 +229,8 @@ _Py_c_quot(Py_complex a, Py_complex b)
{ {
const double x = copysign(isinf(a.real) ? 1.0 : 0.0, a.real); const double x = copysign(isinf(a.real) ? 1.0 : 0.0, a.real);
const double y = copysign(isinf(a.imag) ? 1.0 : 0.0, a.imag); const double y = copysign(isinf(a.imag) ? 1.0 : 0.0, a.imag);
r.real = Py_INFINITY * (x*b.real + y*b.imag); r.real = INFINITY * (x*b.real + y*b.imag);
r.imag = Py_INFINITY * (y*b.real - x*b.imag); r.imag = INFINITY * (y*b.real - x*b.imag);
} }
else if ((isinf(abs_breal) || isinf(abs_bimag)) else if ((isinf(abs_breal) || isinf(abs_bimag))
&& isfinite(a.real) && isfinite(a.imag)) && isfinite(a.real) && isfinite(a.imag))

View File

@@ -2415,7 +2415,7 @@ PyFloat_Unpack2(const char *data, int le)
if (e == 0x1f) { if (e == 0x1f) {
if (f == 0) { if (f == 0) {
/* Infinity */ /* Infinity */
return sign ? -Py_INFINITY : Py_INFINITY; return sign ? -INFINITY : INFINITY;
} }
else { else {
/* NaN */ /* NaN */

View File

@@ -43,7 +43,7 @@ _Py_parse_inf_or_nan(const char *p, char **endptr)
s += 3; s += 3;
if (case_insensitive_match(s, "inity")) if (case_insensitive_match(s, "inity"))
s += 5; s += 5;
retval = negate ? -Py_INFINITY : Py_INFINITY; retval = negate ? -INFINITY : INFINITY;
} }
else if (case_insensitive_match(s, "nan")) { else if (case_insensitive_match(s, "nan")) {
s += 3; s += 3;
@@ -286,7 +286,7 @@ _PyOS_ascii_strtod(const char *nptr, char **endptr)
string, -1.0 is returned and again ValueError is raised. string, -1.0 is returned and again ValueError is raised.
On overflow (e.g., when trying to convert '1e500' on an IEEE 754 machine), On overflow (e.g., when trying to convert '1e500' on an IEEE 754 machine),
if overflow_exception is NULL then +-Py_INFINITY is returned, and no Python if overflow_exception is NULL then +-INFINITY is returned, and no Python
exception is raised. Otherwise, overflow_exception should point to exception is raised. Otherwise, overflow_exception should point to
a Python exception, this exception will be raised, -1.0 will be returned, a Python exception, this exception will be raised, -1.0 will be returned,
and *endptr will point just past the end of the converted value. and *endptr will point just past the end of the converted value.