@@ -55,13 +55,14 @@ raised for division by zero and mod by zero.
5555#ifndef Py_BUILD_CORE_BUILTIN
5656# define Py_BUILD_CORE_MODULE 1
5757#endif
58- #define NEEDS_PY_IDENTIFIER
5958
6059#include "Python.h"
6160#include "pycore_bitutils.h" // _Py_bit_length()
6261#include "pycore_call.h" // _PyObject_CallNoArgs()
6362#include "pycore_dtoa.h" // _Py_dg_infinity()
6463#include "pycore_long.h" // _PyLong_GetZero()
64+ #include "pycore_moduleobject.h" // _PyModule_GetState()
65+ #include "pycore_object.h" // _PyObject_LookupSpecial()
6566#include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR
6667/* For DBL_EPSILON in _math.h */
6768#include <float.h>
@@ -76,6 +77,20 @@ module math
7677/*[clinic end generated code: output=da39a3ee5e6b4b0d input=76bc7002685dd942]*/
7778
7879
80+ typedef struct {
81+ PyObject * str___ceil__ ;
82+ PyObject * str___floor__ ;
83+ PyObject * str___trunc__ ;
84+ } math_module_state ;
85+
86+ static inline math_module_state *
87+ get_math_module_state (PyObject * module )
88+ {
89+ void * state = _PyModule_GetState (module );
90+ assert (state != NULL );
91+ return (math_module_state * )state ;
92+ }
93+
7994/*
8095 sin(pi*x), giving accurate results for all finite x (especially x
8196 integral or close to an integer). This is here for use in the
@@ -1215,10 +1230,10 @@ static PyObject *
12151230math_ceil (PyObject * module , PyObject * number )
12161231/*[clinic end generated code: output=6c3b8a78bc201c67 input=2725352806399cab]*/
12171232{
1218- _Py_IDENTIFIER (__ceil__ );
12191233
12201234 if (!PyFloat_CheckExact (number )) {
1221- PyObject * method = _PyObject_LookupSpecialId (number , & PyId___ceil__ );
1235+ math_module_state * state = get_math_module_state (module );
1236+ PyObject * method = _PyObject_LookupSpecial (number , state -> str___ceil__ );
12221237 if (method != NULL ) {
12231238 PyObject * result = _PyObject_CallNoArgs (method );
12241239 Py_DECREF (method );
@@ -1283,14 +1298,13 @@ math_floor(PyObject *module, PyObject *number)
12831298{
12841299 double x ;
12851300
1286- _Py_IDENTIFIER (__floor__ );
1287-
12881301 if (PyFloat_CheckExact (number )) {
12891302 x = PyFloat_AS_DOUBLE (number );
12901303 }
12911304 else
12921305 {
1293- PyObject * method = _PyObject_LookupSpecialId (number , & PyId___floor__ );
1306+ math_module_state * state = get_math_module_state (module );
1307+ PyObject * method = _PyObject_LookupSpecial (number , state -> str___floor__ );
12941308 if (method != NULL ) {
12951309 PyObject * result = _PyObject_CallNoArgs (method );
12961310 Py_DECREF (method );
@@ -2156,7 +2170,6 @@ static PyObject *
21562170math_trunc (PyObject * module , PyObject * x )
21572171/*[clinic end generated code: output=34b9697b707e1031 input=2168b34e0a09134d]*/
21582172{
2159- _Py_IDENTIFIER (__trunc__ );
21602173 PyObject * trunc , * result ;
21612174
21622175 if (PyFloat_CheckExact (x )) {
@@ -2168,7 +2181,8 @@ math_trunc(PyObject *module, PyObject *x)
21682181 return NULL ;
21692182 }
21702183
2171- trunc = _PyObject_LookupSpecialId (x , & PyId___trunc__ );
2184+ math_module_state * state = get_math_module_state (module );
2185+ trunc = _PyObject_LookupSpecial (x , state -> str___trunc__ );
21722186 if (trunc == NULL ) {
21732187 if (!PyErr_Occurred ())
21742188 PyErr_Format (PyExc_TypeError ,
@@ -3825,6 +3839,20 @@ math_ulp_impl(PyObject *module, double x)
38253839static int
38263840math_exec (PyObject * module )
38273841{
3842+
3843+ math_module_state * state = get_math_module_state (module );
3844+ state -> str___ceil__ = PyUnicode_InternFromString ("__ceil__" );
3845+ if (state -> str___ceil__ == NULL ) {
3846+ return -1 ;
3847+ }
3848+ state -> str___floor__ = PyUnicode_InternFromString ("__floor__" );
3849+ if (state -> str___floor__ == NULL ) {
3850+ return -1 ;
3851+ }
3852+ state -> str___trunc__ = PyUnicode_InternFromString ("__trunc__" );
3853+ if (state -> str___trunc__ == NULL ) {
3854+ return -1 ;
3855+ }
38283856 if (PyModule_AddObject (module , "pi" , PyFloat_FromDouble (Py_MATH_PI )) < 0 ) {
38293857 return -1 ;
38303858 }
@@ -3846,6 +3874,22 @@ math_exec(PyObject *module)
38463874 return 0 ;
38473875}
38483876
3877+ static int
3878+ math_clear (PyObject * module )
3879+ {
3880+ math_module_state * state = get_math_module_state (module );
3881+ Py_CLEAR (state -> str___ceil__ );
3882+ Py_CLEAR (state -> str___floor__ );
3883+ Py_CLEAR (state -> str___trunc__ );
3884+ return 0 ;
3885+ }
3886+
3887+ static void
3888+ math_free (void * module )
3889+ {
3890+ math_clear ((PyObject * )module );
3891+ }
3892+
38493893static PyMethodDef math_methods [] = {
38503894 {"acos" , math_acos , METH_O , math_acos_doc },
38513895 {"acosh" , math_acosh , METH_O , math_acosh_doc },
@@ -3918,9 +3962,11 @@ static struct PyModuleDef mathmodule = {
39183962 PyModuleDef_HEAD_INIT ,
39193963 .m_name = "math" ,
39203964 .m_doc = module_doc ,
3921- .m_size = 0 ,
3965+ .m_size = sizeof ( math_module_state ) ,
39223966 .m_methods = math_methods ,
39233967 .m_slots = math_slots ,
3968+ .m_clear = math_clear ,
3969+ .m_free = math_free ,
39243970};
39253971
39263972PyMODINIT_FUNC
0 commit comments