@@ -356,6 +356,59 @@ LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
356356 return 0 ;
357357}
358358
359+ #ifdef HAVE_LONG_LONG
360+
361+ static PyObject *
362+ q_getitem (arrayobject * ap , Py_ssize_t i )
363+ {
364+ return PyLong_FromLongLong (((PY_LONG_LONG * )ap -> ob_item )[i ]);
365+ }
366+
367+ static int
368+ q_setitem (arrayobject * ap , Py_ssize_t i , PyObject * v )
369+ {
370+ PY_LONG_LONG x ;
371+ if (!PyArg_Parse (v , "L;array item must be integer" , & x ))
372+ return -1 ;
373+ if (i >= 0 )
374+ ((PY_LONG_LONG * )ap -> ob_item )[i ] = x ;
375+ return 0 ;
376+ }
377+
378+ static PyObject *
379+ QQ_getitem (arrayobject * ap , Py_ssize_t i )
380+ {
381+ return PyLong_FromUnsignedLongLong (
382+ ((unsigned PY_LONG_LONG * )ap -> ob_item )[i ]);
383+ }
384+
385+ static int
386+ QQ_setitem (arrayobject * ap , Py_ssize_t i , PyObject * v )
387+ {
388+ unsigned PY_LONG_LONG x ;
389+ if (PyLong_Check (v )) {
390+ x = PyLong_AsUnsignedLongLong (v );
391+ if (x == (unsigned PY_LONG_LONG ) -1 && PyErr_Occurred ())
392+ return -1 ;
393+ }
394+ else {
395+ PY_LONG_LONG y ;
396+ if (!PyArg_Parse (v , "L;array item must be integer" , & y ))
397+ return -1 ;
398+ if (y < 0 ) {
399+ PyErr_SetString (PyExc_OverflowError ,
400+ "unsigned long long is less than minimum" );
401+ return -1 ;
402+ }
403+ x = (unsigned PY_LONG_LONG )y ;
404+ }
405+
406+ if (i >= 0 )
407+ ((unsigned PY_LONG_LONG * )ap -> ob_item )[i ] = x ;
408+ return 0 ;
409+ }
410+ #endif
411+
359412static PyObject *
360413f_getitem (arrayobject * ap , Py_ssize_t i )
361414{
@@ -406,6 +459,10 @@ static struct arraydescr descriptors[] = {
406459 {'I' , sizeof (int ), II_getitem , II_setitem , "I" , 1 , 0 },
407460 {'l' , sizeof (long ), l_getitem , l_setitem , "l" , 1 , 1 },
408461 {'L' , sizeof (long ), LL_getitem , LL_setitem , "L" , 1 , 0 },
462+ #ifdef HAVE_LONG_LONG
463+ {'q' , sizeof (PY_LONG_LONG ), q_getitem , q_setitem , "q" , 1 , 1 },
464+ {'Q' , sizeof (PY_LONG_LONG ), QQ_getitem , QQ_setitem , "Q" , 1 , 0 },
465+ #endif
409466 {'f' , sizeof (float ), f_getitem , f_setitem , "f" , 0 , 0 },
410467 {'d' , sizeof (double ), d_getitem , d_setitem , "d" , 0 , 0 },
411468 {'\0' , 0 , 0 , 0 , 0 , 0 , 0 } /* Sentinel */
@@ -1655,6 +1712,16 @@ typecode_to_mformat_code(int typecode)
16551712 intsize = sizeof (long );
16561713 is_signed = 0 ;
16571714 break ;
1715+ #if HAVE_LONG_LONG
1716+ case 'q' :
1717+ intsize = sizeof (PY_LONG_LONG );
1718+ is_signed = 1 ;
1719+ break ;
1720+ case 'Q' :
1721+ intsize = sizeof (PY_LONG_LONG );
1722+ is_signed = 0 ;
1723+ break ;
1724+ #endif
16581725 default :
16591726 return UNKNOWN_FORMAT ;
16601727 }
@@ -2501,7 +2568,11 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
25012568 }
25022569 }
25032570 PyErr_SetString (PyExc_ValueError ,
2571+ #ifdef HAVE_LONG_LONG
2572+ "bad typecode (must be b, B, u, h, H, i, I, l, L, q, Q, f or d)" );
2573+ #else
25042574 "bad typecode (must be b, B, u, h, H, i, I, l, L, f or d)" );
2575+ #endif
25052576 return NULL ;
25062577}
25072578
@@ -2524,12 +2595,18 @@ is a single character. The following type codes are defined:\n\
25242595 'I' unsigned integer 2 \n\
25252596 'l' signed integer 4 \n\
25262597 'L' unsigned integer 4 \n\
2598+ 'q' signed integer 8 (see note) \n\
2599+ 'Q' unsigned integer 8 (see note) \n\
25272600 'f' floating point 4 \n\
25282601 'd' floating point 8 \n\
25292602\n\
2530- NOTE: The 'u' typecode corresponds to Python's unicode character. On \n\
2603+ NOTE: The 'u' type code corresponds to Python's unicode character. On \n\
25312604narrow builds this is 2-bytes on wide builds this is 4-bytes.\n\
25322605\n\
2606+ NOTE: The 'q' and 'Q' type codes are only available if the platform \n\
2607+ C compiler used to build Python supports 'long long', or, on Windows, \n\
2608+ '__int64'.\n\
2609+ \n\
25332610The constructor is:\n\
25342611\n\
25352612array(typecode [, initializer]) -- create a new array\n\
0 commit comments