@@ -916,7 +916,7 @@ is_error(double x, int raise_edom)
916916 C89 but for which HUGE_VAL is not an infinity.
917917
918918 For the majority of one-argument functions these rules are enough
919- to ensure that Python's functions behave as specified in ' Annex F'
919+ to ensure that Python's functions behave as specified in Annex F
920920 of the C99 standard, with the 'invalid' and 'divide-by-zero'
921921 floating-point exceptions mapping to Python's ValueError and the
922922 'overflow' floating-point exception mapping to OverflowError.
@@ -1011,12 +1011,11 @@ math_1a(PyObject *arg, double (*func) (double), const char *err_msg)
10111011 The last rule is used to catch overflow on platforms which follow
10121012 C89 but for which HUGE_VAL is not an infinity.
10131013
1014- For most two-argument functions (copysign, fmod, hypot, atan2)
1015- these rules are enough to ensure that Python's functions behave as
1016- specified in 'Annex F' of the C99 standard, with the 'invalid' and
1017- 'divide-by-zero' floating-point exceptions mapping to Python's
1018- ValueError and the 'overflow' floating-point exception mapping to
1019- OverflowError.
1014+ For most two-argument functions (copysign, fmod, hypot) these rules
1015+ are enough to ensure that Python's functions behave as specified in
1016+ Annex F of the C99 standard, with the 'invalid' and 'divide-by-zero'
1017+ floating-point exceptions mapping to Python's ValueError and the
1018+ 'overflow' floating-point exception mapping to OverflowError.
10201019*/
10211020
10221021static PyObject *
@@ -1054,6 +1053,28 @@ math_2(PyObject *const *args, Py_ssize_t nargs,
10541053 return PyFloat_FromDouble (r );
10551054}
10561055
1056+ /* variant of math_2, to be used when the function being wrapped is known NOT
1057+ to need error checking (i.e., no overflow, invalid, or divide-by-zero). */
1058+
1059+ static PyObject *
1060+ math_2ne (PyObject * const * args , Py_ssize_t nargs ,
1061+ double (* func ) (double , double ), const char * funcname )
1062+ {
1063+ double x , y , r ;
1064+ if (!_PyArg_CheckPositional (funcname , nargs , 2 , 2 ))
1065+ return NULL ;
1066+ x = PyFloat_AsDouble (args [0 ]);
1067+ if (x == -1.0 && PyErr_Occurred ()) {
1068+ return NULL ;
1069+ }
1070+ y = PyFloat_AsDouble (args [1 ]);
1071+ if (y == -1.0 && PyErr_Occurred ()) {
1072+ return NULL ;
1073+ }
1074+ r = (* func )(x , y );
1075+ return PyFloat_FromDouble (r );
1076+ }
1077+
10571078#define FUNC1 (funcname , func , can_overflow , docstring ) \
10581079 static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
10591080 return math_1(args, func, can_overflow, NULL); \
@@ -1084,6 +1105,12 @@ math_2(PyObject *const *args, Py_ssize_t nargs,
10841105 }\
10851106 PyDoc_STRVAR(math_##funcname##_doc, docstring);
10861107
1108+ #define FUNC2NE (funcname , func , docstring ) \
1109+ static PyObject * math_##funcname(PyObject *self, PyObject *const *args, Py_ssize_t nargs) { \
1110+ return math_2ne(args, nargs, func, #funcname); \
1111+ }\
1112+ PyDoc_STRVAR(math_##funcname##_doc, docstring);
1113+
10871114FUNC1D (acos , acos , 0 ,
10881115 "acos($module, x, /)\n--\n\n"
10891116 "Return the arc cosine (measured in radians) of x.\n\n"
@@ -1115,11 +1142,11 @@ FUNC1(atan, atan, 0,
11151142 "atan($module, x, /)\n--\n\n"
11161143 "Return the arc tangent (measured in radians) of x.\n\n"
11171144 "The result is between -pi/2 and pi/2." )
1118- FUNC2 (atan2 , atan2 ,
1145+ FUNC2NE (atan2 , atan2 ,
11191146 "atan2($module, y, x, /)\n--\n\n"
11201147 "Return the arc tangent (measured in radians) of y/x.\n\n"
11211148 "Unlike atan(y/x), the signs of both x and y are considered." )
1122- FUNC2 (atan2pi , m_atan2pi ,
1149+ FUNC2NE (atan2pi , m_atan2pi ,
11231150 "atan2pi($module, y, x, /)\n--\n\n"
11241151 "Return the arc tangent (measured in half-turns) of y/x.\n\n"
11251152 "Unlike atanpi(y/x), the signs of both x and y are considered." )
0 commit comments