@@ -55,13 +55,14 @@ raised for division by zero and mod by zero.
55
55
#ifndef Py_BUILD_CORE_BUILTIN
56
56
# define Py_BUILD_CORE_MODULE 1
57
57
#endif
58
- #define NEEDS_PY_IDENTIFIER
59
58
60
59
#include "Python.h"
61
60
#include "pycore_bitutils.h" // _Py_bit_length()
62
61
#include "pycore_call.h" // _PyObject_CallNoArgs()
63
62
#include "pycore_dtoa.h" // _Py_dg_infinity()
64
63
#include "pycore_long.h" // _PyLong_GetZero()
64
+ #include "pycore_moduleobject.h" // _PyModule_GetState()
65
+ #include "pycore_object.h" // _PyObject_LookupSpecial()
65
66
#include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR
66
67
/* For DBL_EPSILON in _math.h */
67
68
#include <float.h>
@@ -76,6 +77,20 @@ module math
76
77
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=76bc7002685dd942]*/
77
78
78
79
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
+
79
94
/*
80
95
sin(pi*x), giving accurate results for all finite x (especially x
81
96
integral or close to an integer). This is here for use in the
@@ -1215,10 +1230,10 @@ static PyObject *
1215
1230
math_ceil (PyObject * module , PyObject * number )
1216
1231
/*[clinic end generated code: output=6c3b8a78bc201c67 input=2725352806399cab]*/
1217
1232
{
1218
- _Py_IDENTIFIER (__ceil__ );
1219
1233
1220
1234
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__ );
1222
1237
if (method != NULL ) {
1223
1238
PyObject * result = _PyObject_CallNoArgs (method );
1224
1239
Py_DECREF (method );
@@ -1283,14 +1298,13 @@ math_floor(PyObject *module, PyObject *number)
1283
1298
{
1284
1299
double x ;
1285
1300
1286
- _Py_IDENTIFIER (__floor__ );
1287
-
1288
1301
if (PyFloat_CheckExact (number )) {
1289
1302
x = PyFloat_AS_DOUBLE (number );
1290
1303
}
1291
1304
else
1292
1305
{
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__ );
1294
1308
if (method != NULL ) {
1295
1309
PyObject * result = _PyObject_CallNoArgs (method );
1296
1310
Py_DECREF (method );
@@ -2156,7 +2170,6 @@ static PyObject *
2156
2170
math_trunc (PyObject * module , PyObject * x )
2157
2171
/*[clinic end generated code: output=34b9697b707e1031 input=2168b34e0a09134d]*/
2158
2172
{
2159
- _Py_IDENTIFIER (__trunc__ );
2160
2173
PyObject * trunc , * result ;
2161
2174
2162
2175
if (PyFloat_CheckExact (x )) {
@@ -2168,7 +2181,8 @@ math_trunc(PyObject *module, PyObject *x)
2168
2181
return NULL ;
2169
2182
}
2170
2183
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__ );
2172
2186
if (trunc == NULL ) {
2173
2187
if (!PyErr_Occurred ())
2174
2188
PyErr_Format (PyExc_TypeError ,
@@ -3825,6 +3839,20 @@ math_ulp_impl(PyObject *module, double x)
3825
3839
static int
3826
3840
math_exec (PyObject * module )
3827
3841
{
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
+ }
3828
3856
if (PyModule_AddObject (module , "pi" , PyFloat_FromDouble (Py_MATH_PI )) < 0 ) {
3829
3857
return -1 ;
3830
3858
}
@@ -3846,6 +3874,22 @@ math_exec(PyObject *module)
3846
3874
return 0 ;
3847
3875
}
3848
3876
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
+
3849
3893
static PyMethodDef math_methods [] = {
3850
3894
{"acos" , math_acos , METH_O , math_acos_doc },
3851
3895
{"acosh" , math_acosh , METH_O , math_acosh_doc },
@@ -3918,9 +3962,11 @@ static struct PyModuleDef mathmodule = {
3918
3962
PyModuleDef_HEAD_INIT ,
3919
3963
.m_name = "math" ,
3920
3964
.m_doc = module_doc ,
3921
- .m_size = 0 ,
3965
+ .m_size = sizeof ( math_module_state ) ,
3922
3966
.m_methods = math_methods ,
3923
3967
.m_slots = math_slots ,
3968
+ .m_clear = math_clear ,
3969
+ .m_free = math_free ,
3924
3970
};
3925
3971
3926
3972
PyMODINIT_FUNC
0 commit comments