Skip to content

Commit

Permalink
require a long long data type (closes python#27961)
Browse files Browse the repository at this point in the history
  • Loading branch information
benjaminp committed Sep 6, 2016
1 parent b3b0767 commit ed4aa83
Show file tree
Hide file tree
Showing 32 changed files with 156 additions and 442 deletions.
5 changes: 0 additions & 5 deletions Doc/c-api/unicode.rst
Original file line number Diff line number Diff line change
Expand Up @@ -524,11 +524,6 @@ APIs:
An unrecognized format character causes all the rest of the format string to be
copied as-is to the result string, and any extra arguments discarded.
.. note::
The `"%lld"` and `"%llu"` format specifiers are only available
when :const:`HAVE_LONG_LONG` is defined.
.. note::
The width formatter unit is number of characters rather than bytes.
The precision formatter unit is number of bytes for ``"%s"`` and
Expand Down
2 changes: 0 additions & 2 deletions Include/longobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,12 @@ PyAPI_FUNC(double) PyLong_AsDouble(PyObject *);
PyAPI_FUNC(PyObject *) PyLong_FromVoidPtr(void *);
PyAPI_FUNC(void *) PyLong_AsVoidPtr(PyObject *);

#ifdef HAVE_LONG_LONG
PyAPI_FUNC(PyObject *) PyLong_FromLongLong(PY_LONG_LONG);
PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG);
PyAPI_FUNC(PY_LONG_LONG) PyLong_AsLongLong(PyObject *);
PyAPI_FUNC(unsigned PY_LONG_LONG) PyLong_AsUnsignedLongLong(PyObject *);
PyAPI_FUNC(unsigned PY_LONG_LONG) PyLong_AsUnsignedLongLongMask(PyObject *);
PyAPI_FUNC(PY_LONG_LONG) PyLong_AsLongLongAndOverflow(PyObject *, int *);
#endif /* HAVE_LONG_LONG */

PyAPI_FUNC(PyObject *) PyLong_FromString(const char *, char **, int);
#ifndef Py_LIMITED_API
Expand Down
25 changes: 8 additions & 17 deletions Include/pyport.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,6 @@ HAVE_UINTPTR_T
Meaning: The C9X type uintptr_t is supported by the compiler
Used in: Py_uintptr_t
HAVE_LONG_LONG
Meaning: The compiler supports the C type "long long"
Used in: PY_LONG_LONG
**************************************************************************/

/* typedefs for some C9X-defined synonyms for integral types.
Expand All @@ -53,7 +49,6 @@ Used in: PY_LONG_LONG
* integral synonyms. Only define the ones we actually need.
*/

#ifdef HAVE_LONG_LONG
#ifndef PY_LONG_LONG
#define PY_LONG_LONG long long
#if defined(LLONG_MAX)
Expand All @@ -78,7 +73,6 @@ Used in: PY_LONG_LONG
#define PY_ULLONG_MAX (PY_LLONG_MAX * Py_ULL(2) + 1)
#endif /* LLONG_MAX */
#endif
#endif /* HAVE_LONG_LONG */

/* a build with 30-bit digits for Python integers needs an exact-width
* 32-bit unsigned integer type to store those digits. (We could just use
Expand Down Expand Up @@ -161,7 +155,7 @@ typedef int Py_intptr_t;
typedef unsigned long Py_uintptr_t;
typedef long Py_intptr_t;

#elif defined(HAVE_LONG_LONG) && (SIZEOF_VOID_P <= SIZEOF_LONG_LONG)
#elif SIZEOF_VOID_P <= SIZEOF_LONG_LONG
typedef unsigned PY_LONG_LONG Py_uintptr_t;
typedef PY_LONG_LONG Py_intptr_t;

Expand Down Expand Up @@ -248,19 +242,16 @@ typedef int Py_ssize_clean_t;
#endif

/* PY_FORMAT_LONG_LONG is analogous to PY_FORMAT_SIZE_T above, but for
* the long long type instead of the size_t type. It's only available
* when HAVE_LONG_LONG is defined. The "high level" Python format
* the long long type instead of the size_t type. The "high level" Python format
* functions listed above will interpret "lld" or "llu" correctly on
* all platforms.
*/
#ifdef HAVE_LONG_LONG
# ifndef PY_FORMAT_LONG_LONG
# ifdef MS_WINDOWS
# define PY_FORMAT_LONG_LONG "I64"
# else
# error "This platform's pyconfig.h needs to define PY_FORMAT_LONG_LONG"
# endif
# endif
#ifndef PY_FORMAT_LONG_LONG
# ifdef MS_WINDOWS
# define PY_FORMAT_LONG_LONG "I64"
# else
# error "This platform's pyconfig.h needs to define PY_FORMAT_LONG_LONG"
# endif
#endif

/* Py_LOCAL can be used instead of static to get the fastest possible calling
Expand Down
5 changes: 0 additions & 5 deletions Include/pythread.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,8 @@ PyAPI_FUNC(int) PyThread_acquire_lock(PyThread_type_lock, int);
module exposes a higher-level API, with timeouts expressed in seconds
and floating-point numbers allowed.
*/
#if defined(HAVE_LONG_LONG)
#define PY_TIMEOUT_T PY_LONG_LONG
#define PY_TIMEOUT_MAX PY_LLONG_MAX
#else
#define PY_TIMEOUT_T long
#define PY_TIMEOUT_MAX LONG_MAX
#endif

/* In the NT API, the timeout is a DWORD and is expressed in milliseconds */
#if defined (NT_THREADS)
Expand Down
2 changes: 0 additions & 2 deletions Include/structmember.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,8 @@ typedef struct PyMemberDef {
#define T_OBJECT_EX 16 /* Like T_OBJECT, but raises AttributeError
when the value is NULL, instead of
converting to None. */
#ifdef HAVE_LONG_LONG
#define T_LONGLONG 17
#define T_ULONGLONG 18
#endif /* HAVE_LONG_LONG */

#define T_PYSSIZET 19 /* Py_ssize_t */
#define T_NONE 20 /* Value is always None */
Expand Down
21 changes: 3 additions & 18 deletions Lib/test/test_struct.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,10 @@
def iter_integer_formats(byteorders=byteorders):
for code in integer_codes:
for byteorder in byteorders:
if (byteorder in ('', '@') and code in ('q', 'Q') and
not HAVE_LONG_LONG):
continue
if (byteorder not in ('', '@') and code in ('n', 'N')):
continue
yield code, byteorder

# Native 'q' packing isn't available on systems that don't have the C
# long long type.
try:
struct.pack('q', 5)
except struct.error:
HAVE_LONG_LONG = False
else:
HAVE_LONG_LONG = True

def string_reverse(s):
return s[::-1]

Expand Down Expand Up @@ -159,9 +147,7 @@ def test_calcsize(self):
self.assertEqual(size, expected_size[code])

# native integer sizes
native_pairs = 'bB', 'hH', 'iI', 'lL', 'nN'
if HAVE_LONG_LONG:
native_pairs += 'qQ',
native_pairs = 'bB', 'hH', 'iI', 'lL', 'nN', 'qQ'
for format_pair in native_pairs:
for byteorder in '', '@':
signed_size = struct.calcsize(byteorder + format_pair[0])
Expand All @@ -174,9 +160,8 @@ def test_calcsize(self):
self.assertLessEqual(4, struct.calcsize('l'))
self.assertLessEqual(struct.calcsize('h'), struct.calcsize('i'))
self.assertLessEqual(struct.calcsize('i'), struct.calcsize('l'))
if HAVE_LONG_LONG:
self.assertLessEqual(8, struct.calcsize('q'))
self.assertLessEqual(struct.calcsize('l'), struct.calcsize('q'))
self.assertLessEqual(8, struct.calcsize('q'))
self.assertLessEqual(struct.calcsize('l'), struct.calcsize('q'))
self.assertGreaterEqual(struct.calcsize('n'), struct.calcsize('i'))
self.assertGreaterEqual(struct.calcsize('n'), struct.calcsize('P'))

Expand Down
3 changes: 3 additions & 0 deletions Misc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ What's New in Python 3.6.0 beta 1
Core and Builtins
-----------------

- Issue #27961?: Require platforms to support ``long long``. Python hasn't
compiled without ``long long`` for years, so this is basically a formality.

- Issue #27355: Removed support for Windows CE. It was never finished,
and Windows CE is no longer a relevant platform for Python.

Expand Down
3 changes: 0 additions & 3 deletions Modules/_ctypes/_ctypes_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,6 @@ EXPORT(int) _testfunc_callback_with_pointer(int (*func)(int *))
return (*func)(table);
}

#ifdef HAVE_LONG_LONG
EXPORT(PY_LONG_LONG) _testfunc_q_bhilfdq(signed char b, short h, int i, long l, float f,
double d, PY_LONG_LONG q)
{
Expand Down Expand Up @@ -267,8 +266,6 @@ EXPORT(PY_LONG_LONG) _testfunc_callback_q_qf(PY_LONG_LONG value,
return sum;
}

#endif

typedef struct {
char *name;
char *value;
Expand Down
4 changes: 0 additions & 4 deletions Modules/_ctypes/callproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,6 @@ PyCArg_repr(PyCArgObject *self)
self->tag, self->value.l);
break;

#ifdef HAVE_LONG_LONG
case 'q':
case 'Q':
sprintf(buffer,
Expand All @@ -485,7 +484,6 @@ PyCArg_repr(PyCArgObject *self)
#endif
self->tag, self->value.q);
break;
#endif
case 'd':
sprintf(buffer, "<cparam '%c' (%f)>",
self->tag, self->value.d);
Expand Down Expand Up @@ -593,9 +591,7 @@ union result {
short h;
int i;
long l;
#ifdef HAVE_LONG_LONG
PY_LONG_LONG q;
#endif
long double D;
double d;
float f;
Expand Down
14 changes: 1 addition & 13 deletions Modules/_ctypes/cfield.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,8 +379,6 @@ get_ulong(PyObject *v, unsigned long *p)
return 0;
}

#ifdef HAVE_LONG_LONG

/* Same, but handling native long long. */

static int
Expand Down Expand Up @@ -417,8 +415,6 @@ get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
return 0;
}

#endif

/*****************************************************************
* Integer fields, with bitfield support
*/
Expand Down Expand Up @@ -888,7 +884,6 @@ L_get_sw(void *ptr, Py_ssize_t size)
return PyLong_FromUnsignedLong(val);
}

#ifdef HAVE_LONG_LONG
static PyObject *
q_set(void *ptr, PyObject *value, Py_ssize_t size)
{
Expand Down Expand Up @@ -982,7 +977,6 @@ Q_get_sw(void *ptr, Py_ssize_t size)
GET_BITFIELD(val, size);
return PyLong_FromUnsignedLongLong(val);
}
#endif

/*****************************************************************
* non-integer accessor methods, not supporting bit fields
Expand Down Expand Up @@ -1490,9 +1484,7 @@ P_set(void *ptr, PyObject *value, Py_ssize_t size)
#if SIZEOF_VOID_P <= SIZEOF_LONG
v = (void *)PyLong_AsUnsignedLongMask(value);
#else
#ifndef HAVE_LONG_LONG
# error "PyLong_AsVoidPtr: sizeof(void*) > sizeof(long), but no long long"
#elif SIZEOF_LONG_LONG < SIZEOF_VOID_P
#if SIZEOF_LONG_LONG < SIZEOF_VOID_P
# error "PyLong_AsVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)"
#endif
v = (void *)PyLong_AsUnsignedLongLongMask(value);
Expand Down Expand Up @@ -1538,13 +1530,11 @@ static struct fielddesc formattable[] = {
#else
# error
#endif
#ifdef HAVE_LONG_LONG
#if SIZEOF_LONG_LONG == 8
{ 'q', q_set, q_get, &ffi_type_sint64, q_set_sw, q_get_sw},
{ 'Q', Q_set, Q_get, &ffi_type_uint64, Q_set_sw, Q_get_sw},
#else
# error
#endif
#endif
{ 'P', P_set, P_get, &ffi_type_pointer},
{ 'z', z_set, z_get, &ffi_type_pointer},
Expand Down Expand Up @@ -1635,10 +1625,8 @@ typedef struct { char c; wchar_t *x; } s_wchar_p;
#endif
*/

#ifdef HAVE_LONG_LONG
typedef struct { char c; PY_LONG_LONG x; } s_long_long;
#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
#endif

/* from ffi.h:
typedef struct _ffi_type
Expand Down
4 changes: 0 additions & 4 deletions Modules/_ctypes/ctypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ union value {
long l;
float f;
double d;
#ifdef HAVE_LONG_LONG
PY_LONG_LONG ll;
#endif
long double D;
};

Expand Down Expand Up @@ -303,9 +301,7 @@ struct tagPyCArgObject {
short h;
int i;
long l;
#ifdef HAVE_LONG_LONG
PY_LONG_LONG q;
#endif
long double D;
double d;
float f;
Expand Down
2 changes: 1 addition & 1 deletion Modules/_io/_iomodule.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ typedef off_t Py_off_t;
# define PY_OFF_T_MIN PY_SSIZE_T_MIN
# define PY_OFF_T_COMPAT Py_ssize_t
# define PY_PRIdOFF "zd"
#elif (HAVE_LONG_LONG && SIZEOF_OFF_T == SIZEOF_LONG_LONG)
#elif (SIZEOF_OFF_T == SIZEOF_LONG_LONG)
# define PyLong_AsOff_t PyLong_AsLongLong
# define PyLong_FromOff_t PyLong_FromLongLong
# define PY_OFF_T_MAX PY_LLONG_MAX
Expand Down
4 changes: 0 additions & 4 deletions Modules/_lsprof.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@
#include "frameobject.h"
#include "rotatingtree.h"

#if !defined(HAVE_LONG_LONG)
#error "This module requires long longs!"
#endif

/*** Selection of a high-precision timer ***/

#ifdef MS_WINDOWS
Expand Down
2 changes: 1 addition & 1 deletion Modules/_multiprocessing/multiprocessing.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
#if SIZEOF_VOID_P == SIZEOF_LONG
# define F_POINTER "k"
# define T_POINTER T_ULONG
#elif defined(HAVE_LONG_LONG) && (SIZEOF_VOID_P == SIZEOF_LONG_LONG)
#elif SIZEOF_VOID_P == SIZEOF_LONG_LONG
# define F_POINTER "K"
# define T_POINTER T_ULONGLONG
#else
Expand Down
19 changes: 0 additions & 19 deletions Modules/_sqlite/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st)
PyObject *
_pysqlite_long_from_int64(sqlite_int64 value)
{
#ifdef HAVE_LONG_LONG
# if SIZEOF_LONG_LONG < 8
if (value > PY_LLONG_MAX || value < PY_LLONG_MIN) {
return _PyLong_FromByteArray(&value, sizeof(value),
Expand All @@ -124,38 +123,20 @@ _pysqlite_long_from_int64(sqlite_int64 value)
if (value > LONG_MAX || value < LONG_MIN)
return PyLong_FromLongLong(value);
# endif
#else
# if SIZEOF_LONG < 8
if (value > LONG_MAX || value < LONG_MIN) {
return _PyLong_FromByteArray(&value, sizeof(value),
IS_LITTLE_ENDIAN, 1 /* signed */);
}
# endif
#endif
return PyLong_FromLong(Py_SAFE_DOWNCAST(value, sqlite_int64, long));
}

sqlite_int64
_pysqlite_long_as_int64(PyObject * py_val)
{
int overflow;
#ifdef HAVE_LONG_LONG
PY_LONG_LONG value = PyLong_AsLongLongAndOverflow(py_val, &overflow);
#else
long value = PyLong_AsLongAndOverflow(py_val, &overflow);
#endif
if (value == -1 && PyErr_Occurred())
return -1;
if (!overflow) {
#ifdef HAVE_LONG_LONG
# if SIZEOF_LONG_LONG > 8
if (-0x8000000000000000LL <= value && value <= 0x7FFFFFFFFFFFFFFFLL)
# endif
#else
# if SIZEOF_LONG > 8
if (-0x8000000000000000L <= value && value <= 0x7FFFFFFFFFFFFFFFL)
# endif
#endif
return value;
}
else if (sizeof(value) < sizeof(sqlite_int64)) {
Expand Down
Loading

0 comments on commit ed4aa83

Please sign in to comment.