11/* Fixed size rational numbers exposed to Python */
22
3- #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
3+ #define NPY_NO_DEPRECATED_API NPY_API_VERSION
44
55#include <stdint.h>
66#include <math.h>
77#include <Python.h>
88#include <structmember.h>
99#include <numpy/arrayobject.h>
1010#include <numpy/ufuncobject.h>
11+ #include "numpy/npy_3kcompat.h"
1112
1213/* Relevant arithmetic exceptions */
1314
@@ -501,11 +502,11 @@ static PyObject*
501502pyrational_repr (PyObject * self ) {
502503 rational x = ((PyRational * )self )-> r ;
503504 if (d (x )!= 1 ) {
504- return PyString_FromFormat (
505+ return PyUString_FromFormat (
505506 "rational(%ld,%ld)" ,(long )x .n ,(long )d (x ));
506507 }
507508 else {
508- return PyString_FromFormat (
509+ return PyUString_FromFormat (
509510 "rational(%ld)" ,(long )x .n );
510511 }
511512}
@@ -639,16 +640,24 @@ static PyGetSetDef pyrational_getset[] = {
639640};
640641
641642static PyTypeObject PyRational_Type = {
643+ #if defined(NPY_PY3K )
644+ PyVarObject_HEAD_INIT (& PyType_Type , 0 )
645+ #else
642646 PyObject_HEAD_INIT (& PyType_Type )
643647 0 , /* ob_size */
648+ #endif
644649 "rational" , /* tp_name */
645650 sizeof (PyRational ), /* tp_basicsize */
646651 0 , /* tp_itemsize */
647652 0 , /* tp_dealloc */
648653 0 , /* tp_print */
649654 0 , /* tp_getattr */
650655 0 , /* tp_setattr */
651- 0 , /* tp_compare */
656+ #if defined(NPY_PY3K )
657+ 0 , /* tp_reserved */
658+ #else
659+ 0 , /* tp_compare */
660+ #endif
652661 pyrational_repr , /* tp_repr */
653662 & pyrational_as_number , /* tp_as_number */
654663 0 , /* tp_as_sequence */
@@ -659,7 +668,7 @@ static PyTypeObject PyRational_Type = {
659668 0 , /* tp_getattro */
660669 0 , /* tp_setattro */
661670 0 , /* tp_as_buffer */
662- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES , /* tp_flags */
671+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE , /* tp_flags */
663672 "Fixed precision rational numbers" , /* tp_doc */
664673 0 , /* tp_traverse */
665674 0 , /* tp_clear */
@@ -679,6 +688,16 @@ static PyTypeObject PyRational_Type = {
679688 0 , /* tp_alloc */
680689 pyrational_new , /* tp_new */
681690 0 , /* tp_free */
691+ 0 , /* tp_is_gc */
692+ 0 , /* tp_bases */
693+ 0 , /* tp_mro */
694+ 0 , /* tp_cache */
695+ 0 , /* tp_subclasses */
696+ 0 , /* tp_weaklist */
697+ 0 , /* tp_del */
698+ #if PY_VERSION_HEX >= 0x02060000
699+ 0 , /* tp_version_tag */
700+ #endif
682701};
683702
684703/* Numpy support */
@@ -1022,33 +1041,52 @@ PyMethodDef module_methods[] = {
10221041 {0 } /* sentinel */
10231042};
10241043
1025- PyMODINIT_FUNC
1026- initrational (void ) {
1027- /* Initialize numpy */
1044+ #if defined(NPY_PY3K )
1045+ static struct PyModuleDef moduledef = {
1046+ PyModuleDef_HEAD_INIT ,
1047+ "rational" ,
1048+ NULL ,
1049+ -1 ,
1050+ module_methods ,
1051+ NULL ,
1052+ NULL ,
1053+ NULL ,
1054+ NULL
1055+ };
1056+ #endif
1057+
1058+ #if defined(NPY_PY3K )
1059+ PyMODINIT_FUNC PyInit_rational (void ) {
1060+ #else
1061+ PyMODINIT_FUNC initrational (void ) {
1062+ #endif
1063+
1064+ PyObject * m ;
1065+
10281066 import_array ();
10291067 if (PyErr_Occurred ()) {
1030- return ;
1068+ return NULL ;
10311069 }
10321070 import_umath ();
10331071 if (PyErr_Occurred ()) {
1034- return ;
1072+ return NULL ;
10351073 }
1036- PyObject * numpy_str = PyString_FromString ("numpy" );
1074+ PyObject * numpy_str = PyUString_FromString ("numpy" );
10371075 if (!numpy_str ) {
1038- return ;
1076+ return NULL ;
10391077 }
10401078 PyObject * numpy = PyImport_Import (numpy_str );
10411079 Py_DECREF (numpy_str );
10421080 if (!numpy ) {
1043- return ;
1081+ return NULL ;
10441082 }
10451083
10461084 /* Can't set this until we import numpy */
10471085 PyRational_Type .tp_base = & PyGenericArrType_Type ;
10481086
10491087 /* Initialize rational type object */
10501088 if (PyType_Ready (& PyRational_Type ) < 0 ) {
1051- return ;
1089+ return NULL ;
10521090 }
10531091
10541092 /* Initialize rational descriptor */
@@ -1065,25 +1103,25 @@ initrational(void) {
10651103 npyrational_arrfuncs .fill = npyrational_fill ;
10661104 npyrational_arrfuncs .fillwithscalar = npyrational_fillwithscalar ;
10671105 /* Left undefined: scanfunc, fromstr, sort, argsort */
1068- npyrational_descr . ob_type = & PyArrayDescr_Type ;
1106+ Py_TYPE ( & npyrational_descr ) = & PyArrayDescr_Type ;
10691107 int npy_rational = PyArray_RegisterDataType (& npyrational_descr );
10701108 if (npy_rational < 0 ) {
1071- return ;
1109+ return NULL ;
10721110 }
10731111
10741112 /* Support dtype(rational) syntax */
10751113 if (PyDict_SetItemString (PyRational_Type .tp_dict ,"dtype" ,(PyObject * )& npyrational_descr )< 0 ) {
1076- return ;
1114+ return NULL ;
10771115 }
10781116
10791117 /* Register casts to and from rational */
10801118 #define REGISTER_CAST (From ,To ,from_descr ,to_typenum ,safe ) \
10811119 PyArray_Descr* from_descr_##From##_##To = (from_descr); \
10821120 if (PyArray_RegisterCastFunc(from_descr_##From##_##To,(to_typenum),npycast_##From##_##To)<0) { \
1083- return; \
1121+ return NULL ; \
10841122 } \
10851123 if (safe && PyArray_RegisterCanCast(from_descr_##From##_##To,(to_typenum),NPY_NOSCALAR)<0) { \
1086- return; \
1124+ return NULL ; \
10871125 }
10881126 #define REGISTER_INT_CASTS (bits ) \
10891127 REGISTER_CAST(int##bits##_t,rational,PyArray_DescrFromType(NPY_INT##bits),npy_rational,1) \
@@ -1101,15 +1139,15 @@ initrational(void) {
11011139 #define REGISTER_UFUNC (name ,...) { \
11021140 PyUFuncObject* ufunc = (PyUFuncObject*)PyObject_GetAttrString(numpy,#name); \
11031141 if (!ufunc) { \
1104- return; \
1142+ return NULL ; \
11051143 } \
11061144 int _types[] = __VA_ARGS__; \
11071145 if (sizeof(_types)/sizeof(int)!=ufunc->nargs) { \
11081146 PyErr_Format(PyExc_AssertionError,"ufunc %s takes %d arguments, our loop takes %ld",#name,ufunc->nargs,sizeof(_types)/sizeof(int)); \
1109- return; \
1147+ return NULL ; \
11101148 } \
11111149 if (PyUFunc_RegisterLoopForType((PyUFuncObject*)ufunc,npy_rational,rational_ufunc_##name,_types,0)<0) { \
1112- return; \
1150+ return NULL ; \
11131151 } \
11141152 }
11151153 #define REGISTER_UFUNC_BINARY_RATIONAL (name ) REGISTER_UFUNC(name,{npy_rational,npy_rational,npy_rational})
@@ -1144,10 +1182,14 @@ initrational(void) {
11441182 REGISTER_UFUNC_UNARY (sign )
11451183
11461184 /* Create module */
1147- PyObject * m = Py_InitModule3 ("rational" , module_methods ,
1148- "Fixed precision rational numbers, including numpy support" );
1185+ #if defined(NPY_PY3K )
1186+ m = PyModule_Create (& moduledef );
1187+ #else
1188+ m = Py_InitModule ("rational" , module_methods );
1189+ #endif
1190+
11491191 if (!m ) {
1150- return ;
1192+ return NULL ;
11511193 }
11521194
11531195 /* Add rational type */
@@ -1157,23 +1199,23 @@ initrational(void) {
11571199 /* Create matrix multiply generalized ufunc */
11581200 PyObject * gufunc = PyUFunc_FromFuncAndDataAndSignature (0 ,0 ,0 ,0 ,2 ,1 ,PyUFunc_None ,(char * )"matrix_multiply" ,(char * )"return result of multiplying two matrices of rationals" ,0 ,"(m,n),(n,p)->(m,p)" );
11591201 if (!gufunc ) {
1160- return ;
1202+ return NULL ;
11611203 }
11621204 int types2 [3 ] = {npy_rational ,npy_rational ,npy_rational };
11631205 if (PyUFunc_RegisterLoopForType ((PyUFuncObject * )gufunc ,npy_rational ,rational_gufunc_matrix_multiply ,types2 ,0 ) < 0 ) {
1164- return ;
1206+ return NULL ;
11651207 }
11661208 PyModule_AddObject (m ,"matrix_multiply" ,(PyObject * )gufunc );
11671209
11681210 /* Create numerator and denominator ufuncs */
11691211 #define NEW_UNARY_UFUNC (name ,type ,doc ) { \
11701212 PyObject* ufunc = PyUFunc_FromFuncAndData(0,0,0,0,1,1,PyUFunc_None,(char*)#name,(char*)doc,0); \
11711213 if (!ufunc) { \
1172- return; \
1214+ return NULL ; \
11731215 } \
11741216 int types[2] = {npy_rational,type}; \
11751217 if (PyUFunc_RegisterLoopForType((PyUFuncObject*)ufunc,npy_rational,rational_ufunc_##name,types,0)<0) { \
1176- return; \
1218+ return NULL ; \
11771219 } \
11781220 PyModule_AddObject(m,#name,(PyObject*)ufunc); \
11791221 }
@@ -1187,10 +1229,12 @@ initrational(void) {
11871229 static void* data[1] = {0}; \
11881230 PyObject* ufunc = PyUFunc_FromFuncAndData((PyUFuncGenericFunction*)func,data,(char*)types,1,2,1,PyUFunc_One,(char*)#name,(char*)doc,0); \
11891231 if (!ufunc) { \
1190- return; \
1232+ return NULL ; \
11911233 } \
11921234 PyModule_AddObject(m,#name,(PyObject*)ufunc); \
11931235 }
11941236 GCD_LCM_UFUNC (gcd ,NPY_INT64 ,"greatest common denominator of two integers" );
11951237 GCD_LCM_UFUNC (lcm ,NPY_INT64 ,"least common multiple of two integers" );
1238+
1239+ return m ;
11961240}
0 commit comments