diff -r 46e2755b022c Doc/c-api/arg.rst --- a/Doc/c-api/arg.rst Fri Nov 25 11:59:52 2016 +0100 +++ b/Doc/c-api/arg.rst Fri Nov 25 13:29:08 2016 +0100 @@ -275,6 +275,11 @@ Numbers ``n`` (:class:`int`) [Py_ssize_t] Convert a Python integer to a C :c:type:`Py_ssize_t`. +``m`` (:class:`int`) [intmax_t] + Convert a Python integer to a C :c:type:`intmax_t`. + + .. versionadded:: 3.7 + ``c`` (:class:`bytes` or :class:`bytearray` of length 1) [char] Convert a Python byte, represented as a :class:`bytes` or :class:`bytearray` object of length 1, to a C :c:type:`char`. @@ -600,6 +605,9 @@ Building values ``n`` (:class:`int`) [Py_ssize_t] Convert a C :c:type:`Py_ssize_t` to a Python integer. + ``m`` (:class:`int`) [intmax_t] + Convert a C :c:type:`intmax_t` to a Python integer. + ``c`` (:class:`bytes` of length 1) [char] Convert a C :c:type:`int` representing a byte to a Python :class:`bytes` object of length 1. @@ -653,6 +661,11 @@ Building values If there is an error in the format string, the :exc:`SystemError` exception is set and *NULL* returned. + .. versionchanged:: 3.7 + + Added ``m`` format for ``intmax_t``. + + .. c:function:: PyObject* Py_VaBuildValue(const char *format, va_list vargs) Identical to :c:func:`Py_BuildValue`, except that it accepts a va_list diff -r 46e2755b022c Include/longobject.h --- a/Include/longobject.h Fri Nov 25 11:59:52 2016 +0100 +++ b/Include/longobject.h Fri Nov 25 13:29:08 2016 +0100 @@ -17,14 +17,19 @@ PyAPI_DATA(PyTypeObject) PyLong_Type; PyAPI_FUNC(PyObject *) PyLong_FromLong(long); PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLong(unsigned long); +PyAPI_FUNC(PyObject *) PyLong_FromIntMax(intmax_t); +PyAPI_FUNC(PyObject *) PyLong_FromUIntMax(uintmax_t); PyAPI_FUNC(PyObject *) PyLong_FromSize_t(size_t); PyAPI_FUNC(PyObject *) PyLong_FromSsize_t(Py_ssize_t); PyAPI_FUNC(PyObject *) PyLong_FromDouble(double); PyAPI_FUNC(long) PyLong_AsLong(PyObject *); PyAPI_FUNC(long) PyLong_AsLongAndOverflow(PyObject *, int *); +PyAPI_FUNC(intmax_t) PyLong_AsIntMax(PyObject *); +PyAPI_FUNC(intmax_t) PyLong_AsIntMaxAndOverflow(PyObject *, int *); PyAPI_FUNC(Py_ssize_t) PyLong_AsSsize_t(PyObject *); PyAPI_FUNC(size_t) PyLong_AsSize_t(PyObject *); PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLong(PyObject *); +PyAPI_FUNC(uintmax_t) PyLong_AsUIntMax(PyObject *); PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLongMask(PyObject *); #ifndef Py_LIMITED_API PyAPI_FUNC(int) _PyLong_AsInt(PyObject *); diff -r 46e2755b022c Lib/test/test_getargs2.py --- a/Lib/test/test_getargs2.py Fri Nov 25 11:59:52 2016 +0100 +++ b/Lib/test/test_getargs2.py Fri Nov 25 13:29:08 2016 +0100 @@ -3,7 +3,7 @@ import math import sys from test import support # Skip this test if the _testcapi module isn't available. -support.import_module('_testcapi') +_testcapi = support.import_module('_testcapi') from _testcapi import getargs_keywords, getargs_keyword_only # > How about the following counterproposal. This also changes some of @@ -128,222 +128,120 @@ class DictSubclass(dict): pass -class Unsigned_TestCase(unittest.TestCase): - def test_b(self): - from _testcapi import getargs_b - # b returns 'unsigned char', and does range checking (0 ... UCHAR_MAX) - self.assertRaises(TypeError, getargs_b, 3.14) - self.assertEqual(99, getargs_b(Int())) - self.assertEqual(0, getargs_b(IntSubclass())) - self.assertRaises(TypeError, getargs_b, BadInt()) - with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_b(BadInt2())) - self.assertEqual(0, getargs_b(BadInt3())) +class UnsignedLong_TestCase: + getargs = None + MIN = 0 + MAX = 1 + SUPPORT_INT = False - self.assertRaises(OverflowError, getargs_b, -1) - self.assertEqual(0, getargs_b(0)) - self.assertEqual(UCHAR_MAX, getargs_b(UCHAR_MAX)) - self.assertRaises(OverflowError, getargs_b, UCHAR_MAX + 1) + def test_basic(self): + self.assertEqual(42, self.getargs(42)) + self.assertEqual(self.MIN, self.getargs(self.MIN)) + self.assertEqual(self.MAX, self.getargs(self.MAX)) - self.assertEqual(42, getargs_b(42)) - self.assertRaises(OverflowError, getargs_b, VERY_LARGE) + def test_types(self): + self.assertRaises(TypeError, self.getargs, 3.14) + self.assertRaises(TypeError, self.getargs, "Hello") + self.assertEqual(0, self.getargs(IntSubclass())) - def test_B(self): - from _testcapi import getargs_B - # B returns 'unsigned char', no range checking - self.assertRaises(TypeError, getargs_B, 3.14) - self.assertEqual(99, getargs_B(Int())) - self.assertEqual(0, getargs_B(IntSubclass())) - self.assertRaises(TypeError, getargs_B, BadInt()) - with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_B(BadInt2())) - self.assertEqual(0, getargs_B(BadInt3())) + def test_int(self): + if self.SUPPORT_INT: + self.assertEqual(99, self.getargs(Int())) + self.assertRaises(TypeError, self.getargs, BadInt()) + with self.assertWarns(DeprecationWarning): + self.assertEqual(1, self.getargs(BadInt2())) + else: + self.assertRaises(TypeError, self.getargs, Int()) + self.assertRaises(TypeError, self.getargs, BadInt()) + self.assertRaises(TypeError, self.getargs, BadInt2()) - self.assertEqual(UCHAR_MAX, getargs_B(-1)) - self.assertEqual(0, getargs_B(0)) - self.assertEqual(UCHAR_MAX, getargs_B(UCHAR_MAX)) - self.assertEqual(0, getargs_B(UCHAR_MAX+1)) + self.assertEqual(0, self.getargs(BadInt3())) - self.assertEqual(42, getargs_B(42)) - self.assertEqual(UCHAR_MAX & VERY_LARGE, getargs_B(VERY_LARGE)) + def test_overflow(self): + for value in (self.MIN - 1, self.MAX + 1): + self.assertEqual(value & self.MAX, self.getargs(value)) + self.assertEqual(VERY_LARGE & self.MAX, self.getargs(VERY_LARGE)) - def test_H(self): - from _testcapi import getargs_H - # H returns 'unsigned short', no range checking - self.assertRaises(TypeError, getargs_H, 3.14) - self.assertEqual(99, getargs_H(Int())) - self.assertEqual(0, getargs_H(IntSubclass())) - self.assertRaises(TypeError, getargs_H, BadInt()) - with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_H(BadInt2())) - self.assertEqual(0, getargs_H(BadInt3())) - self.assertEqual(USHRT_MAX, getargs_H(-1)) - self.assertEqual(0, getargs_H(0)) - self.assertEqual(USHRT_MAX, getargs_H(USHRT_MAX)) - self.assertEqual(0, getargs_H(USHRT_MAX+1)) +class SignedLong_TestCase(UnsignedLong_TestCase): + MIN = -1 + SUPPORT_INT = True - self.assertEqual(42, getargs_H(42)) + def test_overflow(self): + self.assertRaises(OverflowError, self.getargs, self.MIN - 1) + self.assertRaises(OverflowError, self.getargs, self.MAX + 1) + self.assertRaises(OverflowError, self.getargs, VERY_LARGE) - self.assertEqual(VERY_LARGE & USHRT_MAX, getargs_H(VERY_LARGE)) - def test_I(self): - from _testcapi import getargs_I - # I returns 'unsigned int', no range checking - self.assertRaises(TypeError, getargs_I, 3.14) - self.assertEqual(99, getargs_I(Int())) - self.assertEqual(0, getargs_I(IntSubclass())) - self.assertRaises(TypeError, getargs_I, BadInt()) - with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_I(BadInt2())) - self.assertEqual(0, getargs_I(BadInt3())) +class Long_b(SignedLong_TestCase, unittest.TestCase): + getargs = _testcapi.getargs_b + MIN = 0 + MAX = UCHAR_MAX - self.assertEqual(UINT_MAX, getargs_I(-1)) - self.assertEqual(0, getargs_I(0)) - self.assertEqual(UINT_MAX, getargs_I(UINT_MAX)) - self.assertEqual(0, getargs_I(UINT_MAX+1)) - self.assertEqual(42, getargs_I(42)) +class Long_h(SignedLong_TestCase, unittest.TestCase): + getargs = _testcapi.getargs_h + MIN = SHRT_MIN + MAX = SHRT_MAX - self.assertEqual(VERY_LARGE & UINT_MAX, getargs_I(VERY_LARGE)) - def test_k(self): - from _testcapi import getargs_k - # k returns 'unsigned long', no range checking - # it does not accept float, or instances with __int__ - self.assertRaises(TypeError, getargs_k, 3.14) - self.assertRaises(TypeError, getargs_k, Int()) - self.assertEqual(0, getargs_k(IntSubclass())) - self.assertRaises(TypeError, getargs_k, BadInt()) - self.assertRaises(TypeError, getargs_k, BadInt2()) - self.assertEqual(0, getargs_k(BadInt3())) +class Long_i(SignedLong_TestCase, unittest.TestCase): + getargs = _testcapi.getargs_i + MIN = INT_MIN + MAX = INT_MAX - self.assertEqual(ULONG_MAX, getargs_k(-1)) - self.assertEqual(0, getargs_k(0)) - self.assertEqual(ULONG_MAX, getargs_k(ULONG_MAX)) - self.assertEqual(0, getargs_k(ULONG_MAX+1)) - self.assertEqual(42, getargs_k(42)) +class Long_l(SignedLong_TestCase, unittest.TestCase): + getargs = _testcapi.getargs_l + MIN = LONG_MIN + MAX = LONG_MAX - self.assertEqual(VERY_LARGE & ULONG_MAX, getargs_k(VERY_LARGE)) -class Signed_TestCase(unittest.TestCase): - def test_h(self): - from _testcapi import getargs_h - # h returns 'short', and does range checking (SHRT_MIN ... SHRT_MAX) - self.assertRaises(TypeError, getargs_h, 3.14) - self.assertEqual(99, getargs_h(Int())) - self.assertEqual(0, getargs_h(IntSubclass())) - self.assertRaises(TypeError, getargs_h, BadInt()) - with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_h(BadInt2())) - self.assertEqual(0, getargs_h(BadInt3())) +class LongLong_L(SignedLong_TestCase, unittest.TestCase): + getargs = _testcapi.getargs_L + MIN = LLONG_MIN + MAX = LLONG_MAX - self.assertRaises(OverflowError, getargs_h, SHRT_MIN-1) - self.assertEqual(SHRT_MIN, getargs_h(SHRT_MIN)) - self.assertEqual(SHRT_MAX, getargs_h(SHRT_MAX)) - self.assertRaises(OverflowError, getargs_h, SHRT_MAX+1) - self.assertEqual(42, getargs_h(42)) - self.assertRaises(OverflowError, getargs_h, VERY_LARGE) +class Long_n(SignedLong_TestCase, unittest.TestCase): + getargs = _testcapi.getargs_n + MIN = PY_SSIZE_T_MIN + MAX = PY_SSIZE_T_MAX + SUPPORT_INT = False - def test_i(self): - from _testcapi import getargs_i - # i returns 'int', and does range checking (INT_MIN ... INT_MAX) - self.assertRaises(TypeError, getargs_i, 3.14) - self.assertEqual(99, getargs_i(Int())) - self.assertEqual(0, getargs_i(IntSubclass())) - self.assertRaises(TypeError, getargs_i, BadInt()) - with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_i(BadInt2())) - self.assertEqual(0, getargs_i(BadInt3())) - self.assertRaises(OverflowError, getargs_i, INT_MIN-1) - self.assertEqual(INT_MIN, getargs_i(INT_MIN)) - self.assertEqual(INT_MAX, getargs_i(INT_MAX)) - self.assertRaises(OverflowError, getargs_i, INT_MAX+1) +class Long_B(UnsignedLong_TestCase, unittest.TestCase): + getargs = _testcapi.getargs_B + MAX = UCHAR_MAX + SUPPORT_INT = True - self.assertEqual(42, getargs_i(42)) - self.assertRaises(OverflowError, getargs_i, VERY_LARGE) - def test_l(self): - from _testcapi import getargs_l - # l returns 'long', and does range checking (LONG_MIN ... LONG_MAX) - self.assertRaises(TypeError, getargs_l, 3.14) - self.assertEqual(99, getargs_l(Int())) - self.assertEqual(0, getargs_l(IntSubclass())) - self.assertRaises(TypeError, getargs_l, BadInt()) - with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_l(BadInt2())) - self.assertEqual(0, getargs_l(BadInt3())) +class Long_H(UnsignedLong_TestCase, unittest.TestCase): + getargs = _testcapi.getargs_H + MAX = USHRT_MAX + SUPPORT_INT = True - self.assertRaises(OverflowError, getargs_l, LONG_MIN-1) - self.assertEqual(LONG_MIN, getargs_l(LONG_MIN)) - self.assertEqual(LONG_MAX, getargs_l(LONG_MAX)) - self.assertRaises(OverflowError, getargs_l, LONG_MAX+1) - self.assertEqual(42, getargs_l(42)) - self.assertRaises(OverflowError, getargs_l, VERY_LARGE) +class Long_I(UnsignedLong_TestCase, unittest.TestCase): + getargs = _testcapi.getargs_I + MAX = UINT_MAX + SUPPORT_INT = True - def test_n(self): - from _testcapi import getargs_n - # n returns 'Py_ssize_t', and does range checking - # (PY_SSIZE_T_MIN ... PY_SSIZE_T_MAX) - self.assertRaises(TypeError, getargs_n, 3.14) - self.assertRaises(TypeError, getargs_n, Int()) - self.assertEqual(0, getargs_n(IntSubclass())) - self.assertRaises(TypeError, getargs_n, BadInt()) - self.assertRaises(TypeError, getargs_n, BadInt2()) - self.assertEqual(0, getargs_n(BadInt3())) - self.assertRaises(OverflowError, getargs_n, PY_SSIZE_T_MIN-1) - self.assertEqual(PY_SSIZE_T_MIN, getargs_n(PY_SSIZE_T_MIN)) - self.assertEqual(PY_SSIZE_T_MAX, getargs_n(PY_SSIZE_T_MAX)) - self.assertRaises(OverflowError, getargs_n, PY_SSIZE_T_MAX+1) +class Long_k(UnsignedLong_TestCase, unittest.TestCase): + getargs = _testcapi.getargs_k + MAX = ULONG_MAX - self.assertEqual(42, getargs_n(42)) - self.assertRaises(OverflowError, getargs_n, VERY_LARGE) +class LongLong_K(UnsignedLong_TestCase, unittest.TestCase): + getargs = _testcapi.getargs_K + MAX = ULLONG_MAX -class LongLong_TestCase(unittest.TestCase): - def test_L(self): - from _testcapi import getargs_L - # L returns 'long long', and does range checking (LLONG_MIN - # ... LLONG_MAX) - self.assertRaises(TypeError, getargs_L, 3.14) - self.assertRaises(TypeError, getargs_L, "Hello") - self.assertEqual(99, getargs_L(Int())) - self.assertEqual(0, getargs_L(IntSubclass())) - self.assertRaises(TypeError, getargs_L, BadInt()) - with self.assertWarns(DeprecationWarning): - self.assertEqual(1, getargs_L(BadInt2())) - self.assertEqual(0, getargs_L(BadInt3())) - self.assertRaises(OverflowError, getargs_L, LLONG_MIN-1) - self.assertEqual(LLONG_MIN, getargs_L(LLONG_MIN)) - self.assertEqual(LLONG_MAX, getargs_L(LLONG_MAX)) - self.assertRaises(OverflowError, getargs_L, LLONG_MAX+1) - - self.assertEqual(42, getargs_L(42)) - self.assertRaises(OverflowError, getargs_L, VERY_LARGE) - - def test_K(self): - from _testcapi import getargs_K - # K return 'unsigned long long', no range checking - self.assertRaises(TypeError, getargs_K, 3.14) - self.assertRaises(TypeError, getargs_K, Int()) - self.assertEqual(0, getargs_K(IntSubclass())) - self.assertRaises(TypeError, getargs_K, BadInt()) - self.assertRaises(TypeError, getargs_K, BadInt2()) - self.assertEqual(0, getargs_K(BadInt3())) - - self.assertEqual(ULLONG_MAX, getargs_K(ULLONG_MAX)) - self.assertEqual(0, getargs_K(0)) - self.assertEqual(0, getargs_K(ULLONG_MAX+1)) - - self.assertEqual(42, getargs_K(42)) - - self.assertEqual(VERY_LARGE & ULLONG_MAX, getargs_K(VERY_LARGE)) +class Long_IntMax_m(SignedLong_TestCase, unittest.TestCase): + getargs = _testcapi.getargs_m + MIN = _testcapi.INTMAX_MIN + MAX = _testcapi.INTMAX_MAX class Float_TestCase(unittest.TestCase): diff -r 46e2755b022c Modules/_lzmamodule.c --- a/Modules/_lzmamodule.c Fri Nov 25 11:59:52 2016 +0100 +++ b/Modules/_lzmamodule.c Fri Nov 25 13:29:08 2016 +0100 @@ -1442,9 +1442,9 @@ static PyModuleDef _lzmamodule = { /* Some of our constants are more than 32 bits wide, so PyModule_AddIntConstant would not work correctly on platforms with 32-bit longs. */ static int -module_add_int_constant(PyObject *m, const char *name, long long value) +module_add_int_constant(PyObject *m, const char *name, intmax_t value) { - PyObject *o = PyLong_FromLongLong(value); + PyObject *o = PyLong_FromIntMax(value); if (o == NULL) return -1; if (PyModule_AddObject(m, name, o) == 0) diff -r 46e2755b022c Modules/_testcapimodule.c --- a/Modules/_testcapimodule.c Fri Nov 25 11:59:52 2016 +0100 +++ b/Modules/_testcapimodule.c Fri Nov 25 13:29:08 2016 +0100 @@ -61,6 +61,7 @@ test_config(PyObject *self) CHECK_SIZEOF(SIZEOF_VOID_P, void*); CHECK_SIZEOF(SIZEOF_TIME_T, time_t); CHECK_SIZEOF(SIZEOF_LONG_LONG, long long); + CHECK_SIZEOF(SIZEOF_INTMAX_T, intmax_t); #undef CHECK_SIZEOF @@ -392,6 +393,7 @@ raise_test_long_error(const char* msg) #define TESTNAME test_long_api_inner #define TYPENAME long +#define UTYPENAME unsigned long #define F_S_TO_PY PyLong_FromLong #define F_PY_TO_S PyLong_AsLong #define F_U_TO_PY PyLong_FromUnsignedLong @@ -407,11 +409,46 @@ test_long_api(PyObject* self) #undef TESTNAME #undef TYPENAME +#undef UTYPENAME #undef F_S_TO_PY #undef F_PY_TO_S #undef F_U_TO_PY #undef F_PY_TO_U +/* intmax_t */ + +static PyObject * +raise_test_long_intmax_error(const char* msg) +{ + return raiseTestError("test_long_intmax_api", msg); +} + +#define TESTNAME test_long_intmax_api_inner +#define TYPENAME intmax_t +#define UTYPENAME uintmax_t +#define F_S_TO_PY PyLong_FromIntMax +#define F_PY_TO_S PyLong_AsIntMax +#define F_U_TO_PY PyLong_FromUIntMax +#define F_PY_TO_U PyLong_AsUIntMax + +#include "testcapi_long.h" + +static PyObject * +test_long_intmax_api(PyObject* self, PyObject *args) +{ + return TESTNAME(raise_test_long_intmax_error); +} + +#undef TESTNAME +#undef TYPENAME +#undef UTYPENAME +#undef F_S_TO_PY +#undef F_PY_TO_S +#undef F_U_TO_PY +#undef F_PY_TO_U + +/* long long */ + static PyObject * raise_test_longlong_error(const char* msg) { @@ -420,6 +457,7 @@ raise_test_longlong_error(const char* ms #define TESTNAME test_longlong_api_inner #define TYPENAME long long +#define UTYPENAME unsigned long long #define F_S_TO_PY PyLong_FromLongLong #define F_PY_TO_S PyLong_AsLongLong #define F_U_TO_PY PyLong_FromUnsignedLongLong @@ -435,6 +473,7 @@ test_longlong_api(PyObject* self, PyObje #undef TESTNAME #undef TYPENAME +#undef UTYPENAME #undef F_S_TO_PY #undef F_PY_TO_S #undef F_U_TO_PY @@ -1160,6 +1199,15 @@ getargs_K(PyObject *self, PyObject *args return PyLong_FromUnsignedLongLong(value); } +static PyObject * +getargs_m(PyObject *self, PyObject *args) +{ + intmax_t value; + if (!PyArg_ParseTuple(args, "m", &value)) + return NULL; + return PyLong_FromIntMax(value); +} + /* This function not only tests the 'k' getargs code, but also the PyLong_AsUnsignedLongMask() and PyLong_AsUnsignedLongMask() functions. */ static PyObject * @@ -4018,6 +4066,7 @@ static PyMethodDef TestMethods[] = { {"dict_getitem_knownhash", dict_getitem_knownhash, METH_VARARGS}, {"test_lazy_hash_inheritance", (PyCFunction)test_lazy_hash_inheritance,METH_NOARGS}, {"test_long_api", (PyCFunction)test_long_api, METH_NOARGS}, + {"test_long_intmax_api", (PyCFunction)test_long_intmax_api, METH_NOARGS}, {"test_xincref_doesnt_leak",(PyCFunction)test_xincref_doesnt_leak, METH_NOARGS}, {"test_incref_doesnt_leak", (PyCFunction)test_incref_doesnt_leak, METH_NOARGS}, {"test_xdecref_doesnt_leak",(PyCFunction)test_xdecref_doesnt_leak, METH_NOARGS}, @@ -4066,6 +4115,7 @@ static PyMethodDef TestMethods[] = { {"getargs_p", getargs_p, METH_VARARGS}, {"getargs_L", getargs_L, METH_VARARGS}, {"getargs_K", getargs_K, METH_VARARGS}, + {"getargs_m", getargs_m, METH_VARARGS}, {"test_longlong_api", test_longlong_api, METH_NOARGS}, {"test_long_long_and_overflow", (PyCFunction)test_long_long_and_overflow, METH_NOARGS}, @@ -4603,7 +4653,10 @@ PyInit__testcapi(void) PyModule_AddObject(m, "UINT_MAX", PyLong_FromUnsignedLong(UINT_MAX)); PyModule_AddObject(m, "LONG_MAX", PyLong_FromLong(LONG_MAX)); PyModule_AddObject(m, "LONG_MIN", PyLong_FromLong(LONG_MIN)); + PyModule_AddObject(m, "INTMAX_MAX", PyLong_FromIntMax(INTMAX_MAX)); + PyModule_AddObject(m, "INTMAX_MIN", PyLong_FromIntMax(INTMAX_MIN)); PyModule_AddObject(m, "ULONG_MAX", PyLong_FromUnsignedLong(ULONG_MAX)); + PyModule_AddObject(m, "UINTMAX_MAX", PyLong_FromUIntMax(UINTMAX_MAX)); PyModule_AddObject(m, "FLT_MAX", PyFloat_FromDouble(FLT_MAX)); PyModule_AddObject(m, "FLT_MIN", PyFloat_FromDouble(FLT_MIN)); PyModule_AddObject(m, "DBL_MAX", PyFloat_FromDouble(DBL_MAX)); diff -r 46e2755b022c Modules/_tkinter.c --- a/Modules/_tkinter.c Fri Nov 25 11:59:52 2016 +0100 +++ b/Modules/_tkinter.c Fri Nov 25 13:29:08 2016 +0100 @@ -1182,8 +1182,9 @@ fromWideIntObj(PyObject* tkapp, Tcl_Obj { Tcl_WideInt wideValue; if (Tcl_GetWideIntFromObj(Tkapp_Interp(tkapp), value, &wideValue) == TCL_OK) { - if (sizeof(wideValue) <= SIZEOF_LONG_LONG) - return PyLong_FromLongLong(wideValue); + if (sizeof(wideValue) <= SIZEOF_INTMAX_T) { + return PyLong_FromIntMax(wideValue); + } return _PyLong_FromByteArray((unsigned char *)(void *)&wideValue, sizeof(wideValue), PY_LITTLE_ENDIAN, diff -r 46e2755b022c Modules/clinic/posixmodule.c.h --- a/Modules/clinic/posixmodule.c.h Fri Nov 25 11:59:52 2016 +0100 +++ b/Modules/clinic/posixmodule.c.h Fri Nov 25 13:29:08 2016 +0100 @@ -3533,7 +3533,7 @@ os_lseek(PyObject *module, PyObject *arg if ((_return_value == -1) && PyErr_Occurred()) { goto exit; } - return_value = PyLong_FromPy_off_t(_return_value); + return_value = PyLong_FromIntMax(_return_value); exit: return return_value; @@ -6352,4 +6352,4 @@ exit: #ifndef OS_GETRANDOM_METHODDEF #define OS_GETRANDOM_METHODDEF #endif /* !defined(OS_GETRANDOM_METHODDEF) */ -/*[clinic end generated code: output=61abf6df195aa5f1 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=949da9b5a6eceeab input=a9049054013a1b77]*/ diff -r 46e2755b022c Modules/mmapmodule.c --- a/Modules/mmapmodule.c Fri Nov 25 11:59:52 2016 +0100 +++ b/Modules/mmapmodule.c Fri Nov 25 13:29:08 2016 +0100 @@ -433,7 +433,7 @@ mmap_size_method(mmap_object *self, #ifdef MS_WINDOWS if (self->file_handle != INVALID_HANDLE_VALUE) { DWORD low,high; - long long size; + intmax_t size; low = GetFileSize(self->file_handle, &high); if (low == INVALID_FILE_SIZE) { /* It might be that the function appears to have failed, @@ -444,8 +444,8 @@ mmap_size_method(mmap_object *self, } if (!high && low < LONG_MAX) return PyLong_FromLong((long)low); - size = (((long long)high)<<32) + low; - return PyLong_FromLongLong(size); + size = (((intmax_t)high)<<32) + low; + return PyLong_FromIntMax(size); } else { return PyLong_FromSsize_t(self->size); } @@ -456,11 +456,7 @@ mmap_size_method(mmap_object *self, struct _Py_stat_struct status; if (_Py_fstat(self->fd, &status) == -1) return NULL; -#ifdef HAVE_LARGEFILE_SUPPORT - return PyLong_FromLongLong(status.st_size); -#else - return PyLong_FromLong(status.st_size); -#endif + return PyLong_FromIntMax(status.st_size); } #endif /* UNIX */ } diff -r 46e2755b022c Modules/posixmodule.c --- a/Modules/posixmodule.c Fri Nov 25 11:59:52 2016 +0100 +++ b/Modules/posixmodule.c Fri Nov 25 13:29:08 2016 +0100 @@ -649,7 +649,7 @@ fail: #endif /* MS_WINDOWS */ -#define _PyLong_FromDev PyLong_FromLongLong +#define _PyLong_FromDev PyLong_FromIntMax #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) @@ -1168,16 +1168,6 @@ Py_off_t_converter(PyObject *arg, void * return 1; } -static PyObject * -PyLong_FromPy_off_t(Py_off_t offset) -{ -#ifdef HAVE_LARGEFILE_SUPPORT - return PyLong_FromLongLong(offset); -#else - return PyLong_FromLong(offset); -#endif -} - #ifdef MS_WINDOWS static int @@ -1929,12 +1919,7 @@ static PyObject* return NULL; PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode)); -#ifdef HAVE_LARGEFILE_SUPPORT - PyStructSequence_SET_ITEM(v, 1, - PyLong_FromLongLong((long long)st->st_ino)); -#else - PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino)); -#endif + PyStructSequence_SET_ITEM(v, 1, PyLong_FromIntMax(st->st_ino)); #ifdef MS_WINDOWS PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev)); #else @@ -1948,12 +1933,7 @@ static PyObject* PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid)); PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid)); #endif -#ifdef HAVE_LARGEFILE_SUPPORT - PyStructSequence_SET_ITEM(v, 6, - PyLong_FromLongLong((long long)st->st_size)); -#else - PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size)); -#endif + PyStructSequence_SET_ITEM(v, 6, PyLong_FromIntMax(st->st_size)); #if defined(HAVE_STAT_TV_NSEC) ansec = st->st_atim.tv_nsec; @@ -2358,7 +2338,7 @@ class Py_off_t_converter(CConverter): class Py_off_t_return_converter(long_return_converter): type = 'Py_off_t' - conversion_fn = 'PyLong_FromPy_off_t' + conversion_fn = 'PyLong_FromIntMax' class path_confname_converter(CConverter): type="int" @@ -2376,7 +2356,7 @@ class sched_param_converter(CConverter): impl_by_reference = True; [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=6810f54d2201a416]*/ /*[clinic input] @@ -9156,18 +9136,12 @@ static PyObject* #else PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize)); PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize)); - PyStructSequence_SET_ITEM(v, 2, - PyLong_FromLongLong((long long) st.f_blocks)); - PyStructSequence_SET_ITEM(v, 3, - PyLong_FromLongLong((long long) st.f_bfree)); - PyStructSequence_SET_ITEM(v, 4, - PyLong_FromLongLong((long long) st.f_bavail)); - PyStructSequence_SET_ITEM(v, 5, - PyLong_FromLongLong((long long) st.f_files)); - PyStructSequence_SET_ITEM(v, 6, - PyLong_FromLongLong((long long) st.f_ffree)); - PyStructSequence_SET_ITEM(v, 7, - PyLong_FromLongLong((long long) st.f_favail)); + PyStructSequence_SET_ITEM(v, 2, PyLong_FromIntMax(st.f_blocks)); + PyStructSequence_SET_ITEM(v, 3, PyLong_FromIntMax(st.f_bfree)); + PyStructSequence_SET_ITEM(v, 4, PyLong_FromIntMax(st.f_bavail)); + PyStructSequence_SET_ITEM(v, 5, PyLong_FromIntMax(st.f_files)); + PyStructSequence_SET_ITEM(v, 6, PyLong_FromIntMax(st.f_ffree)); + PyStructSequence_SET_ITEM(v, 7, PyLong_FromIntMax(st.f_favail)); PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); #endif @@ -11409,13 +11383,9 @@ os_DirEntry_inode_impl(DirEntry *self) self->win32_file_index = stat.st_ino; self->got_file_index = 1; } - return PyLong_FromLongLong((long long)self->win32_file_index); + return PyLong_FromIntMax(self->win32_file_index); #else /* POSIX */ -#ifdef HAVE_LARGEFILE_SUPPORT - return PyLong_FromLongLong((long long)self->d_ino); -#else - return PyLong_FromLong((long)self->d_ino); -#endif + return PyLong_FromIntMax(self->d_ino); #endif } diff -r 46e2755b022c Modules/resource.c --- a/Modules/resource.c Fri Nov 25 11:59:52 2016 +0100 +++ b/Modules/resource.c Fri Nov 25 13:29:08 2016 +0100 @@ -436,12 +436,7 @@ PyInit_resource(void) PyModule_AddIntMacro(m, RLIMIT_NPTS); #endif - if (sizeof(RLIM_INFINITY) > sizeof(long)) { - v = PyLong_FromLongLong((long long) RLIM_INFINITY); - } else - { - v = PyLong_FromLong((long) RLIM_INFINITY); - } + v = PyLong_FromIntMax(RLIM_INFINITY); if (v) { PyModule_AddObject(m, "RLIM_INFINITY", v); } diff -r 46e2755b022c Modules/testcapi_long.h --- a/Modules/testcapi_long.h Fri Nov 25 11:59:52 2016 +0100 +++ b/Modules/testcapi_long.h Fri Nov 25 13:29:08 2016 +0100 @@ -1,6 +1,7 @@ /* Poor-man's template. Macros used: TESTNAME name of the test (like test_long_api_inner) TYPENAME the signed type (like long) + UTYPENAME the unsigned type (like unsigned long) F_S_TO_PY convert signed to pylong; TYPENAME -> PyObject* F_PY_TO_S convert pylong to signed; PyObject* -> TYPENAME F_U_TO_PY convert unsigned to pylong; unsigned TYPENAME -> PyObject* @@ -11,7 +12,7 @@ static PyObject * TESTNAME(PyObject *error(const char*)) { const int NBITS = sizeof(TYPENAME) * 8; - unsigned TYPENAME base; + UTYPENAME base; PyObject *pyresult; int i; @@ -30,7 +31,7 @@ TESTNAME(PyObject *error(const char*)) int j; for (j = 0; j < 6; ++j) { TYPENAME in, out; - unsigned TYPENAME uin, uout; + UTYPENAME uin, uout; /* For 0, 1, 2 use base; for 3, 4, 5 use -base */ uin = j < 3 ? base : 0U - base; @@ -39,7 +40,7 @@ TESTNAME(PyObject *error(const char*)) * For 1 & 4, leave alone. * For 2 & 5, add 1. */ - uin += (unsigned TYPENAME)(TYPENAME)(j % 3 - 1); + uin += (UTYPENAME)(TYPENAME)(j % 3 - 1); pyresult = F_U_TO_PY(uin); if (pyresult == NULL) @@ -47,7 +48,7 @@ TESTNAME(PyObject *error(const char*)) "unsigned unexpected null result"); uout = F_PY_TO_U(pyresult); - if (uout == (unsigned TYPENAME)-1 && PyErr_Occurred()) + if (uout == (UTYPENAME)-1 && PyErr_Occurred()) return error( "unsigned unexpected -1 result"); if (uout != uin) @@ -79,7 +80,7 @@ TESTNAME(PyObject *error(const char*)) { PyObject *one, *x, *y; TYPENAME out; - unsigned TYPENAME uout; + UTYPENAME uout; one = PyLong_FromLong(1); if (one == NULL) @@ -93,7 +94,7 @@ TESTNAME(PyObject *error(const char*)) "unexpected NULL from PyNumber_Negative"); uout = F_PY_TO_U(x); - if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred()) + if (uout != (UTYPENAME)-1 || !PyErr_Occurred()) return error( "PyLong_AsUnsignedXXX(-1) didn't complain"); if (!PyErr_ExceptionMatches(PyExc_OverflowError)) @@ -116,7 +117,7 @@ TESTNAME(PyObject *error(const char*)) "unexpected NULL from PyNumber_Lshift"); uout = F_PY_TO_U(x); - if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred()) + if (uout != (UTYPENAME)-1 || !PyErr_Occurred()) return error( "PyLong_AsUnsignedXXX(2**NBITS) didn't " "complain"); @@ -179,7 +180,7 @@ TESTNAME(PyObject *error(const char*)) /* Test F_PY_TO_{S,U} on non-pylong input. This should raise a TypeError. */ { TYPENAME out; - unsigned TYPENAME uout; + UTYPENAME uout; Py_INCREF(Py_None); @@ -192,7 +193,7 @@ TESTNAME(PyObject *error(const char*)) PyErr_Clear(); uout = F_PY_TO_U(Py_None); - if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred()) + if (uout != (UTYPENAME)-1 || !PyErr_Occurred()) return error("PyLong_AsXXX(None) didn't complain"); if (!PyErr_ExceptionMatches(PyExc_TypeError)) return error("PyLong_AsXXX(None) raised " diff -r 46e2755b022c Objects/longobject.c --- a/Objects/longobject.c Fri Nov 25 11:59:52 2016 +0100 +++ b/Objects/longobject.c Fri Nov 25 13:29:08 2016 +0100 @@ -295,6 +295,76 @@ PyLong_FromLong(long ival) return (PyObject *)v; } +/* Create a new int object from a C intmax_t */ + +PyObject * +PyLong_FromIntMax(intmax_t ival) +{ + PyLongObject *v; + uintmax_t abs_ival; + uintmax_t t; /* unsigned so >> doesn't propagate sign bit */ + int ndigits = 0; + int sign; + + CHECK_SMALL_INT(ival); + + if (ival < 0) { + /* negate: can't write this as abs_ival = -ival since that + invokes undefined behaviour when ival is LONG_MIN */ + abs_ival = 0U-(uintmax_t)ival; + sign = -1; + } + else { + abs_ival = (uintmax_t)ival; + sign = ival == 0 ? 0 : 1; + } + + /* Fast path for single-digit ints */ + if (!(abs_ival >> PyLong_SHIFT)) { + v = _PyLong_New(1); + if (v) { + Py_SIZE(v) = sign; + v->ob_digit[0] = Py_SAFE_DOWNCAST( + abs_ival, uintmax_t, digit); + } + return (PyObject*)v; + } + +#if PyLong_SHIFT==15 + /* 2 digits */ + if (!(abs_ival >> 2*PyLong_SHIFT)) { + v = _PyLong_New(2); + if (v) { + Py_SIZE(v) = 2*sign; + v->ob_digit[0] = Py_SAFE_DOWNCAST( + abs_ival & PyLong_MASK, uintmax_t, digit); + v->ob_digit[1] = Py_SAFE_DOWNCAST( + abs_ival >> PyLong_SHIFT, uintmax_t, digit); + } + return (PyObject*)v; + } +#endif + + /* Larger numbers: loop to determine number of digits */ + t = abs_ival; + while (t) { + ++ndigits; + t >>= PyLong_SHIFT; + } + v = _PyLong_New(ndigits); + if (v != NULL) { + digit *p = v->ob_digit; + Py_SIZE(v) = ndigits*sign; + t = abs_ival; + while (t) { + *p++ = Py_SAFE_DOWNCAST( + t & PyLong_MASK, uintmax_t, digit); + t >>= PyLong_SHIFT; + } + } + return (PyObject *)v; +} + /* Create a new int object from a C unsigned long int */ PyObject * @@ -306,12 +376,44 @@ PyLong_FromUnsignedLong(unsigned long iv if (ival < PyLong_BASE) return PyLong_FromLong(ival); + /* Count the number of Python digits. */ - t = (unsigned long)ival; + t = ival; while (t) { ++ndigits; t >>= PyLong_SHIFT; } + + v = _PyLong_New(ndigits); + if (v != NULL) { + digit *p = v->ob_digit; + while (ival) { + *p++ = (digit)(ival & PyLong_MASK); + ival >>= PyLong_SHIFT; + } + } + return (PyObject *)v; +} + +/* Create a new int object from a C intmax_t */ + +PyObject * +PyLong_FromUIntMax(uintmax_t ival) +{ + PyLongObject *v; + uintmax_t t; + int ndigits = 0; + + if (ival < PyLong_BASE) + return PyLong_FromLong(ival); + + /* Count the number of Python digits. */ + t = ival; + while (t) { + ++ndigits; + t >>= PyLong_SHIFT; + } + v = _PyLong_New(ndigits); if (v != NULL) { digit *p = v->ob_digit; @@ -463,7 +565,104 @@ PyLong_AsLongAndOverflow(PyObject *vv, i return res; } +/* Checking for overflow in PyLong_AsIntMax is a PITA since C doesn't define + * anything about what happens when a signed integer operation overflows, + * and some compilers think they're doing you a favor by being "clever" + * then. The bit pattern for the largest positive signed long is + * (unsigned long)INTMAX_MAX, and for the smallest negative signed long + * it is abs(INTMAX_MIN), which we could write -(unsigned long)INTMAX_MIN. + * However, some other compilers warn about applying unary minus to an + * unsigned operand. Hence the weird "0-". + */ +#define PY_ABS_INTMAX_MIN (0-(uintmax_t)INTMAX_MIN) + /* Get a C long int from an int object or any object that has an __int__ + method. + + On overflow, return -1 and set *overflow to 1 or -1 depending on the sign of + the result. Otherwise *overflow is 0. + + For other errors (e.g., TypeError), return -1 and set an error condition. + In this case *overflow will be 0. +*/ + +intmax_t +PyLong_AsIntMaxAndOverflow(PyObject *vv, int *overflow) +{ + /* This version by Tim Peters */ + PyLongObject *v; + uintmax_t x, prev; + intmax_t res; + Py_ssize_t i; + int sign; + int do_decref = 0; /* if nb_int was called */ + + *overflow = 0; + if (vv == NULL) { + PyErr_BadInternalCall(); + return -1; + } + + if (PyLong_Check(vv)) { + v = (PyLongObject *)vv; + } + else { + v = _PyLong_FromNbInt(vv); + if (v == NULL) + return -1; + do_decref = 1; + } + + res = -1; + i = Py_SIZE(v); + + switch (i) { + case -1: + res = -(sdigit)v->ob_digit[0]; + break; + case 0: + res = 0; + break; + case 1: + res = v->ob_digit[0]; + break; + default: + sign = 1; + x = 0; + if (i < 0) { + sign = -1; + i = -(i); + } + while (--i >= 0) { + prev = x; + x = (x << PyLong_SHIFT) | v->ob_digit[i]; + if ((x >> PyLong_SHIFT) != prev) { + *overflow = sign; + goto exit; + } + } + /* Haven't lost any bits, but casting to intmax_t requires extra + * care (see comment above). + */ + if (x <= (uintmax_t)INTMAX_MAX) { + res = (intmax_t)x * sign; + } + else if (sign < 0 && x == PY_ABS_INTMAX_MIN) { + res = INTMAX_MIN; + } + else { + *overflow = sign; + /* res is already set to -1 */ + } + } + exit: + if (do_decref) { + Py_DECREF(v); + } + return res; +} + +/* Get a C long int from a Python int object or any object that has an __int__ method. Return -1 and set an error if overflow occurs. */ long @@ -480,6 +679,23 @@ PyLong_AsLong(PyObject *obj) return result; } +/* Get a C intmax_t from a Python int object or any object that has an __int__ + method. Return -1 and set an error if overflow occurs. */ + +long +PyLong_AsIntMax(PyObject *obj) +{ + int overflow; + long result = PyLong_AsIntMaxAndOverflow(obj, &overflow); + if (overflow) { + /* XXX: could be cute and give a different + message for overflow == -1 */ + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C long"); + } + return result; +} + /* Get a C int from an int object or any object that has an __int__ method. Return -1 and set an error if overflow occurs. */ @@ -553,7 +769,7 @@ PyLong_AsSsize_t(PyObject *vv) { return -1; } -/* Get a C unsigned long int from an int object. +/* Get a C unsigned long int from a Python int object. Returns -1 and sets an error condition if overflow occurs. */ unsigned long @@ -597,6 +813,50 @@ PyLong_AsUnsignedLong(PyObject *vv) return x; } +/* Get a C uintmax_t int from a Python int object. + Returns -1 and sets an error condition if overflow occurs. */ + +uintmax_t +PyLong_AsUIntMax(PyObject *vv) +{ + PyLongObject *v; + uintmax_t x, prev; + Py_ssize_t i; + + if (vv == NULL) { + PyErr_BadInternalCall(); + return (uintmax_t)-1; + } + if (!PyLong_Check(vv)) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return (uintmax_t)-1; + } + + v = (PyLongObject *)vv; + i = Py_SIZE(v); + x = 0; + if (i < 0) { + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to uintmax_t"); + return (uintmax_t) -1; + } + switch (i) { + case 0: return 0; + case 1: return v->ob_digit[0]; + } + while (--i >= 0) { + prev = x; + x = (x << PyLong_SHIFT) | v->ob_digit[i]; + if ((x >> PyLong_SHIFT) != prev) { + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert " + "to C uintmax_t"); + return (uintmax_t) -1; + } + } + return x; +} + /* Get a C size_t from an int object. Returns (size_t)-1 and sets an error condition if overflow occurs. */ @@ -1007,16 +1267,7 @@ int PyObject * PyLong_FromVoidPtr(void *p) { -#if SIZEOF_VOID_P <= SIZEOF_LONG - return PyLong_FromUnsignedLong((unsigned long)(uintptr_t)p); -#else - -#if SIZEOF_LONG_LONG < SIZEOF_VOID_P -# error "PyLong_FromVoidPtr: sizeof(long long) < sizeof(void*)" -#endif - return PyLong_FromUnsignedLongLong((unsigned long long)(uintptr_t)p); -#endif /* SIZEOF_VOID_P <= SIZEOF_LONG */ - + return PyLong_FromUIntMax((uintptr_t)p); } /* Get a C pointer from an int object. */ @@ -1024,30 +1275,27 @@ PyLong_FromVoidPtr(void *p) void * PyLong_AsVoidPtr(PyObject *vv) { -#if SIZEOF_VOID_P <= SIZEOF_LONG - long x; - - if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0) - x = PyLong_AsLong(vv); - else - x = PyLong_AsUnsignedLong(vv); -#else - -#if SIZEOF_LONG_LONG < SIZEOF_VOID_P -# error "PyLong_AsVoidPtr: sizeof(long long) < sizeof(void*)" -#endif - long long x; - - if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0) - x = PyLong_AsLongLong(vv); - else - x = PyLong_AsUnsignedLongLong(vv); - -#endif /* SIZEOF_VOID_P <= SIZEOF_LONG */ - - if (x == -1 && PyErr_Occurred()) - return NULL; - return (void *)x; + uintptr_t u; + + if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0) { + intmax_t x = PyLong_AsIntMax(vv); + if (x == -1 && PyErr_Occurred()) { + return NULL; + } + + Py_BUILD_ASSERT(sizeof(uintptr_t) == sizeof(intmax_t)); + u = (uintptr_t)x; + } + else { + uintmax_t x = PyLong_AsUIntMax(vv); + if (x == (uintmax_t)-1 && PyErr_Occurred()) { + return NULL; + } + + Py_BUILD_ASSERT(sizeof(uintptr_t) == sizeof(uintmax_t)); + u = (uintptr_t)x; + } + return (void *)u; } /* Initial long long support by Chris Herborth (chrish@qnx.com), later diff -r 46e2755b022c PC/pyconfig.h --- a/PC/pyconfig.h Fri Nov 25 11:59:52 2016 +0100 +++ b/PC/pyconfig.h Fri Nov 25 13:29:08 2016 +0100 @@ -346,6 +346,7 @@ Py_NO_ENABLE_SHARED to find out. Also s #define SIZEOF_LONG_LONG 8 #define SIZEOF_DOUBLE 8 #define SIZEOF_FLOAT 4 +#define SIZEOF_INTMAX_T 8 /* VC 7.1 has them and VC 6.0 does not. VC 6.0 has a version number of 1200. Microsoft eMbedded Visual C++ 4.0 has a version number of 1201 and doesn't diff -r 46e2755b022c Python/getargs.c --- a/Python/getargs.c Fri Nov 25 11:59:52 2016 +0100 +++ b/Python/getargs.c Fri Nov 25 13:29:08 2016 +0100 @@ -757,6 +757,7 @@ convertsimple(PyObject *arg, const char *p = ival; break; } + case 'l': {/* long int */ long *p = va_arg(*p_va, long *); long ival; @@ -805,6 +806,22 @@ convertsimple(PyObject *arg, const char break; } + case 'm': { /* intmax_t */ + intmax_t *p = va_arg(*p_va, intmax_t *); + intmax_t ival; + if (float_argument_error(arg)) { + RETURN_ERR_OCCURRED; + } + ival = PyLong_AsIntMax(arg); + if (ival == -1 && PyErr_Occurred()) { + RETURN_ERR_OCCURRED; + } + else { + *p = ival; + } + break; + } + case 'f': {/* float */ float *p = va_arg(*p_va, float *); double dval = PyFloat_AsDouble(arg); @@ -2237,6 +2254,7 @@ skipitem(const char **p_format, va_list case 'L': /* long long */ case 'K': /* long long sized bitfield */ case 'n': /* Py_ssize_t */ + case 'm': /* intmax_t */ case 'f': /* float */ case 'd': /* double */ case 'D': /* complex double */ diff -r 46e2755b022c Python/modsupport.c --- a/Python/modsupport.c Fri Nov 25 11:59:52 2016 +0100 +++ b/Python/modsupport.c Fri Nov 25 13:29:08 2016 +0100 @@ -253,6 +253,9 @@ do_mkvalue(const char **p_format, va_lis case 'l': return PyLong_FromLong(va_arg(*p_va, long)); + case 'm': + return PyLong_FromIntMax(va_arg(*p_va, intmax_t)); + case 'k': { unsigned long n; diff -r 46e2755b022c Python/pytime.c --- a/Python/pytime.c Fri Nov 25 11:59:52 2016 +0100 +++ b/Python/pytime.c Fri Nov 25 13:29:08 2016 +0100 @@ -38,31 +38,28 @@ error_time_t_overflow(void) time_t _PyLong_AsTime_t(PyObject *obj) { -#if SIZEOF_TIME_T == SIZEOF_LONG_LONG - long long val; - val = PyLong_AsLongLong(obj); -#else - long val; - Py_BUILD_ASSERT(sizeof(time_t) <= sizeof(long)); - val = PyLong_AsLong(obj); -#endif + intmax_t val; + time_t t; + + val = PyLong_AsIntMax(obj); if (val == -1 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) error_time_t_overflow(); return -1; } - return (time_t)val; + + t = (time_t)val; + if ((intmax_t)t != val) { + error_time_t_overflow(); + return -1; + } + return t; } PyObject * _PyLong_FromTime_t(time_t t) { -#if SIZEOF_TIME_T == SIZEOF_LONG_LONG - return PyLong_FromLongLong((long long)t); -#else - Py_BUILD_ASSERT(sizeof(time_t) <= sizeof(long)); - return PyLong_FromLong((long)t); -#endif + return PyLong_FromIntMax(t); } /* Round to nearest with ties going to nearest even integer @@ -358,8 +355,7 @@ double PyObject * _PyTime_AsNanosecondsObject(_PyTime_t t) { - Py_BUILD_ASSERT(sizeof(long long) >= sizeof(_PyTime_t)); - return PyLong_FromLongLong((long long)t); + return PyLong_FromIntMax(t); } static _PyTime_t diff -r 46e2755b022c configure --- a/configure Fri Nov 25 11:59:52 2016 +0100 +++ b/configure Fri Nov 25 13:29:08 2016 +0100 @@ -784,7 +784,6 @@ infodir docdir oldincludedir includedir -runstatedir localstatedir sharedstatedir sysconfdir @@ -895,7 +894,6 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1148,15 +1146,6 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; - -runstatedir | --runstatedir | --runstatedi | --runstated \ - | --runstate | --runstat | --runsta | --runst | --runs \ - | --run | --ru | --r) - ac_prev=runstatedir ;; - -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ - | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ - | --run=* | --ru=* | --r=*) - runstatedir=$ac_optarg ;; - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1294,7 +1283,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir runstatedir + libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1447,7 +1436,6 @@ Fine tuning of the installation director --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -8738,6 +8726,39 @@ cat >>confdefs.h <<_ACEOF _ACEOF +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of intmax_t" >&5 +$as_echo_n "checking size of intmax_t... " >&6; } +if ${ac_cv_sizeof_intmax_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (intmax_t))" "ac_cv_sizeof_intmax_t" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_intmax_t" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (intmax_t) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_intmax_t=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_intmax_t" >&5 +$as_echo "$ac_cv_sizeof_intmax_t" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_INTMAX_T $ac_cv_sizeof_intmax_t +_ACEOF + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long double support" >&5 $as_echo_n "checking for long double support... " >&6; } diff -r 46e2755b022c configure.ac --- a/configure.ac Fri Nov 25 11:59:52 2016 +0100 +++ b/configure.ac Fri Nov 25 13:29:08 2016 +0100 @@ -2203,6 +2203,7 @@ AC_CHECK_SIZEOF(fpos_t, 4) AC_CHECK_SIZEOF(size_t, 4) AC_CHECK_SIZEOF(pid_t, 4) AC_CHECK_SIZEOF(uintptr_t) +AC_CHECK_SIZEOF(intmax_t) AC_MSG_CHECKING(for long double support) have_long_double=no diff -r 46e2755b022c pyconfig.h.in --- a/pyconfig.h.in Fri Nov 25 11:59:52 2016 +0100 +++ b/pyconfig.h.in Fri Nov 25 13:29:08 2016 +0100 @@ -1278,6 +1278,9 @@ /* The size of `int', as computed by sizeof. */ #undef SIZEOF_INT +/* The size of `intmax_t', as computed by sizeof. */ +#undef SIZEOF_INTMAX_T + /* The size of `long', as computed by sizeof. */ #undef SIZEOF_LONG