Mercurial > hg-stable
changeset 30106:cb3048746dae
dirs: port PyInt code to work on Python 3
PyIntObject no longer exists in Python 3. Instead, there is
PyLongObject.
Furthermore, PyInt_AS_LONG is a macro referencing a struct member.
PyInt_AS_LONG doesn't exist in Python 3 and PyLong_AS_LONG is a
#define for PyLong_AsLong, which is a function. So assigning to the
return value of PyLong_AS_LONG doesn't work.
This patch introduces a macro for obtaining the value of an
integer-like type that works on Python 2 and Python 3. On
Python 3, we access the struct field of the underlying
PyLongObjet directly, without overflow checking. This is
essentially the same as what Python 2 was doing except using a
PyLong instead of a PyInt.
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Sat, 08 Oct 2016 16:20:21 +0200 |
parents | b2f90d8878ac |
children | da08f4707282 |
files | mercurial/dirs.c |
diffstat | 1 files changed, 13 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/dirs.c Sat Oct 08 14:31:59 2016 +0200 +++ b/mercurial/dirs.c Sat Oct 08 16:20:21 2016 +0200 @@ -11,6 +11,12 @@ #include <Python.h> #include "util.h" +#ifdef IS_PY3K +#define PYLONG_VALUE(o) ((PyLongObject *)o)->ob_digit[1] +#else +#define PYLONG_VALUE(o) PyInt_AS_LONG(o) +#endif + /* * This is a multiset of directory names, built from the files that * appear in a dirstate or manifest. @@ -66,17 +72,21 @@ val = PyDict_GetItem(dirs, key); if (val != NULL) { - PyInt_AS_LONG(val) += 1; + PYLONG_VALUE(val) += 1; break; } /* Force Python to not reuse a small shared int. */ +#ifdef IS_PY3K + val = PyLong_FromLong(0x1eadbeef); +#else val = PyInt_FromLong(0x1eadbeef); +#endif if (val == NULL) goto bail; - PyInt_AS_LONG(val) = 1; + PYLONG_VALUE(val) = 1; ret = PyDict_SetItem(dirs, key, val); Py_DECREF(val); if (ret == -1) @@ -113,7 +123,7 @@ goto bail; } - if (--PyInt_AS_LONG(val) <= 0) { + if (--PYLONG_VALUE(val) <= 0) { if (PyDict_DelItem(dirs, key) == -1) goto bail; } else