From 994f04dbf576f4ebafb9de2bc6821e15cb0de0ea Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 27 Dec 2016 15:09:36 +0200 Subject: [PATCH] Issue #28998: More APIs now support longs as well as ints. --- Lib/asynchat.py | 2 +- Lib/compiler/pyassem.py | 2 +- Lib/compiler/transformer.py | 2 +- Lib/idlelib/PyShell.py | 4 ++-- Lib/imaplib.py | 2 +- Lib/lib-tk/Tkinter.py | 4 ++-- Lib/lib-tk/turtle.py | 4 ++-- Lib/lib2to3/pgen2/pgen.py | 2 +- Lib/logging/__init__.py | 2 +- Lib/multiprocessing/pool.py | 2 +- Lib/multiprocessing/process.py | 6 +++--- Lib/multiprocessing/util.py | 2 +- Lib/pickletools.py | 4 ++-- Lib/subprocess.py | 12 ++++++------ Lib/unittest/signals.py | 2 +- Lib/warnings.py | 8 ++++---- Misc/NEWS | 2 ++ Modules/_csv.c | 17 ++++++++++++----- Modules/_cursesmodule.c | 14 +++++++++++--- Modules/dlmodule.c | 5 ++++- Modules/svmodule.c | 4 ++-- Modules/termios.c | 5 ++++- Objects/intobject.c | 7 +++++-- 23 files changed, 70 insertions(+), 44 deletions(-) diff --git a/Lib/asynchat.py b/Lib/asynchat.py index 57459a0821b..392ee61a450 100644 --- a/Lib/asynchat.py +++ b/Lib/asynchat.py @@ -133,7 +133,7 @@ class async_chat (asyncore.dispatcher): # no terminator, collect it all self.collect_incoming_data (self.ac_in_buffer) self.ac_in_buffer = '' - elif isinstance(terminator, int) or isinstance(terminator, long): + elif isinstance(terminator, (int, long)): # numeric terminator n = terminator if lb < n: diff --git a/Lib/compiler/pyassem.py b/Lib/compiler/pyassem.py index f52f7d079f3..b82073e4d1a 100644 --- a/Lib/compiler/pyassem.py +++ b/Lib/compiler/pyassem.py @@ -581,7 +581,7 @@ def getArgCount(args): def twobyte(val): """Convert an int argument into high and low bytes""" - assert isinstance(val, int) + assert isinstance(val, (int, long)) return divmod(val, 256) class LineAddrTable: diff --git a/Lib/compiler/transformer.py b/Lib/compiler/transformer.py index d4f4613f480..ba5c03ce754 100644 --- a/Lib/compiler/transformer.py +++ b/Lib/compiler/transformer.py @@ -1526,7 +1526,7 @@ for k, v in token.tok_name.items(): def debug_tree(tree): l = [] for elt in tree: - if isinstance(elt, int): + if isinstance(elt, (int, long)): l.append(_names.get(elt, elt)) elif isinstance(elt, str): l.append(elt) diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py index 3ea1a7d8c8d..fdd7cb1c4e8 100755 --- a/Lib/idlelib/PyShell.py +++ b/Lib/idlelib/PyShell.py @@ -1370,7 +1370,7 @@ class PseudoInputFile(PseudoFile): raise ValueError("read from closed file") if size is None: size = -1 - elif not isinstance(size, int): + elif not isinstance(size, (int, long)): raise TypeError('must be int, not ' + type(size).__name__) result = self._line_buffer self._line_buffer = '' @@ -1393,7 +1393,7 @@ class PseudoInputFile(PseudoFile): raise ValueError("read from closed file") if size is None: size = -1 - elif not isinstance(size, int): + elif not isinstance(size, (int, long)): raise TypeError('must be int, not ' + type(size).__name__) line = self._line_buffer or self.shell.readline() if size < 0: diff --git a/Lib/imaplib.py b/Lib/imaplib.py index 826eea25248..f813ece8bd4 100644 --- a/Lib/imaplib.py +++ b/Lib/imaplib.py @@ -1409,7 +1409,7 @@ def Time2Internaldate(date_time): be in the correct format. """ - if isinstance(date_time, (int, float)): + if isinstance(date_time, (int, long, float)): tt = time.localtime(date_time) elif isinstance(date_time, (tuple, time.struct_time)): tt = date_time diff --git a/Lib/lib-tk/Tkinter.py b/Lib/lib-tk/Tkinter.py index 64e99247cfd..365f4203160 100644 --- a/Lib/lib-tk/Tkinter.py +++ b/Lib/lib-tk/Tkinter.py @@ -1174,9 +1174,9 @@ class Misc: elif isinstance(v, (tuple, list)): nv = [] for item in v: - if not isinstance(item, (basestring, int)): + if not isinstance(item, (basestring, int, long)): break - elif isinstance(item, int): + elif isinstance(item, (int, long)): nv.append('%d' % item) else: # format it to proper Tcl code if it contains space diff --git a/Lib/lib-tk/turtle.py b/Lib/lib-tk/turtle.py index 264318effc3..52e669b4824 100644 --- a/Lib/lib-tk/turtle.py +++ b/Lib/lib-tk/turtle.py @@ -276,7 +276,7 @@ class Vec2D(tuple): return self[0]*other[0]+self[1]*other[1] return Vec2D(self[0]*other, self[1]*other) def __rmul__(self, other): - if isinstance(other, int) or isinstance(other, float): + if isinstance(other, (int, long, float)): return Vec2D(self[0]*other, self[1]*other) def __sub__(self, other): return Vec2D(self[0]-other[0], self[1]-other[1]) @@ -2352,7 +2352,7 @@ class TPen(object): self._resizemode = p["resizemode"] if "stretchfactor" in p: sf = p["stretchfactor"] - if isinstance(sf, (int, float)): + if isinstance(sf, (int, long, float)): sf = (sf, sf) self._stretchfactor = sf if "outline" in p: diff --git a/Lib/lib2to3/pgen2/pgen.py b/Lib/lib2to3/pgen2/pgen.py index ed16992a203..be4fcad65c5 100644 --- a/Lib/lib2to3/pgen2/pgen.py +++ b/Lib/lib2to3/pgen2/pgen.py @@ -74,7 +74,7 @@ class ParserGenerator(object): else: # A named token (NAME, NUMBER, STRING) itoken = getattr(token, label, None) - assert isinstance(itoken, int), label + assert isinstance(itoken, (int, long)), label assert itoken in token.tok_name, label if itoken in c.tokens: return c.tokens[itoken] diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index caf151d1537..22205825f3f 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -1222,7 +1222,7 @@ class Logger(Filterer): logger.log(level, "We have a %s", "mysterious problem", exc_info=1) """ - if not isinstance(level, int): + if not isinstance(level, (int, long)): if raiseExceptions: raise TypeError("level must be an integer") else: diff --git a/Lib/multiprocessing/pool.py b/Lib/multiprocessing/pool.py index 991f87f2f1b..ceb93aab862 100644 --- a/Lib/multiprocessing/pool.py +++ b/Lib/multiprocessing/pool.py @@ -86,7 +86,7 @@ class MaybeEncodingError(Exception): def worker(inqueue, outqueue, initializer=None, initargs=(), maxtasks=None): - assert maxtasks is None or (type(maxtasks) == int and maxtasks > 0) + assert maxtasks is None or (type(maxtasks) in (int, long) and maxtasks > 0) put = outqueue.put get = inqueue.get if hasattr(inqueue, '_writer'): diff --git a/Lib/multiprocessing/process.py b/Lib/multiprocessing/process.py index 44c1e44242f..f6b03b192ae 100644 --- a/Lib/multiprocessing/process.py +++ b/Lib/multiprocessing/process.py @@ -227,7 +227,7 @@ class Process(object): else: status = 'started' - if type(status) is int: + if type(status) in (int, long): if status == 0: status = 'stopped' else: @@ -262,8 +262,8 @@ class Process(object): except SystemExit, e: if not e.args: exitcode = 1 - elif isinstance(e.args[0], int): - exitcode = e.args[0] + elif isinstance(e.args[0], (int, long)): + exitcode = int(e.args[0]) else: sys.stderr.write(str(e.args[0]) + '\n') sys.stderr.flush() diff --git a/Lib/multiprocessing/util.py b/Lib/multiprocessing/util.py index 092b61ce090..394cc44a334 100644 --- a/Lib/multiprocessing/util.py +++ b/Lib/multiprocessing/util.py @@ -174,7 +174,7 @@ class Finalize(object): Class which supports object finalization using weakrefs ''' def __init__(self, obj, callback, args=(), kwargs=None, exitpriority=None): - assert exitpriority is None or type(exitpriority) is int + assert exitpriority is None or type(exitpriority) in (int, long) if obj is not None: self._weakref = weakref.ref(obj, self) diff --git a/Lib/pickletools.py b/Lib/pickletools.py index 8de53dd2507..c9366c8ce3e 100644 --- a/Lib/pickletools.py +++ b/Lib/pickletools.py @@ -185,7 +185,7 @@ class ArgumentDescriptor(object): assert isinstance(name, str) self.name = name - assert isinstance(n, int) and (n >= 0 or + assert isinstance(n, (int, long)) and (n >= 0 or n in (UP_TO_NEWLINE, TAKEN_FROM_ARGUMENT1, TAKEN_FROM_ARGUMENT4)) @@ -873,7 +873,7 @@ class OpcodeInfo(object): assert isinstance(x, StackObject) self.stack_after = stack_after - assert isinstance(proto, int) and 0 <= proto <= 2 + assert isinstance(proto, (int, long)) and 0 <= proto <= 2 self.proto = proto assert isinstance(doc, str) diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 2022e978f79..407141e25d4 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -507,7 +507,7 @@ class Popen(object): p2cread, _ = _subprocess.CreatePipe(None, 0) elif stdin == PIPE: p2cread, p2cwrite = _subprocess.CreatePipe(None, 0) - elif isinstance(stdin, int): + elif isinstance(stdin, (int, long)): p2cread = msvcrt.get_osfhandle(stdin) else: # Assuming file-like object @@ -524,7 +524,7 @@ class Popen(object): _, c2pwrite = _subprocess.CreatePipe(None, 0) elif stdout == PIPE: c2pread, c2pwrite = _subprocess.CreatePipe(None, 0) - elif isinstance(stdout, int): + elif isinstance(stdout, (int, long)): c2pwrite = msvcrt.get_osfhandle(stdout) else: # Assuming file-like object @@ -543,7 +543,7 @@ class Popen(object): errread, errwrite = _subprocess.CreatePipe(None, 0) elif stderr == STDOUT: errwrite = c2pwrite - elif isinstance(stderr, int): + elif isinstance(stderr, (int, long)): errwrite = msvcrt.get_osfhandle(stderr) else: # Assuming file-like object @@ -800,7 +800,7 @@ class Popen(object): elif stdin == PIPE: p2cread, p2cwrite = self.pipe_cloexec() to_close.update((p2cread, p2cwrite)) - elif isinstance(stdin, int): + elif isinstance(stdin, (int, long)): p2cread = stdin else: # Assuming file-like object @@ -811,7 +811,7 @@ class Popen(object): elif stdout == PIPE: c2pread, c2pwrite = self.pipe_cloexec() to_close.update((c2pread, c2pwrite)) - elif isinstance(stdout, int): + elif isinstance(stdout, (int, long)): c2pwrite = stdout else: # Assuming file-like object @@ -827,7 +827,7 @@ class Popen(object): errwrite = c2pwrite else: # child's stdout is not set, use parent's stdout errwrite = sys.__stdout__.fileno() - elif isinstance(stderr, int): + elif isinstance(stderr, (int, long)): errwrite = stderr else: # Assuming file-like object diff --git a/Lib/unittest/signals.py b/Lib/unittest/signals.py index e6a5fc52439..9fbcc9ff856 100644 --- a/Lib/unittest/signals.py +++ b/Lib/unittest/signals.py @@ -10,7 +10,7 @@ class _InterruptHandler(object): def __init__(self, default_handler): self.called = False self.original_handler = default_handler - if isinstance(default_handler, int): + if isinstance(default_handler, (int, long)): if default_handler == signal.SIG_DFL: # Pretend it's signal.default_int_handler instead. default_handler = signal.default_int_handler diff --git a/Lib/warnings.py b/Lib/warnings.py index b0d53aa0321..41f700b7a05 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -84,10 +84,10 @@ def filterwarnings(action, message="", category=Warning, module="", lineno=0, "category must be a class" assert issubclass(category, Warning), "category must be a Warning subclass" assert isinstance(module, basestring), "module must be a string" - assert isinstance(lineno, int) and lineno >= 0, \ + assert isinstance(lineno, (int, long)) and lineno >= 0, \ "lineno must be an int >= 0" item = (action, re.compile(message, re.I), category, - re.compile(module), lineno) + re.compile(module), int(lineno)) if append: filters.append(item) else: @@ -105,9 +105,9 @@ def simplefilter(action, category=Warning, lineno=0, append=0): """ assert action in ("error", "ignore", "always", "default", "module", "once"), "invalid action: %r" % (action,) - assert isinstance(lineno, int) and lineno >= 0, \ + assert isinstance(lineno, (int, long)) and lineno >= 0, \ "lineno must be an int >= 0" - item = (action, None, category, None, lineno) + item = (action, None, category, None, int(lineno)) if append: filters.append(item) else: diff --git a/Misc/NEWS b/Misc/NEWS index 97d77a65d61..da87000be28 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -15,6 +15,8 @@ Core and Builtins Library ------- +- Issue #28998: More APIs now support longs as well as ints. + - Issue 28923: Remove editor artifacts from Tix.py, including encoding not recognized by codecs.lookup. diff --git a/Modules/_csv.c b/Modules/_csv.c index 4589f06dec3..c39c0f10c3c 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -220,15 +220,19 @@ _set_bool(const char *name, int *target, PyObject *src, int dflt) static int _set_int(const char *name, int *target, PyObject *src, int dflt) { + int value; if (src == NULL) *target = dflt; else { - if (!PyInt_Check(src)) { + if (!PyInt_Check(src) && !PyLong_Check(src)) { PyErr_Format(PyExc_TypeError, "\"%s\" must be an integer", name); return -1; } - *target = PyInt_AsLong(src); + value = PyInt_AsLong(src); + if (value == -1 && PyErr_Occurred()) + return -1; + *target = value; } return 0; } @@ -1443,17 +1447,20 @@ static PyObject * csv_field_size_limit(PyObject *module, PyObject *args) { PyObject *new_limit = NULL; - long old_limit = field_limit; + long old_limit = field_limit, limit; if (!PyArg_UnpackTuple(args, "field_size_limit", 0, 1, &new_limit)) return NULL; if (new_limit != NULL) { - if (!PyInt_Check(new_limit)) { + if (!PyInt_Check(new_limit) && !PyLong_Check(new_limit)) { PyErr_Format(PyExc_TypeError, "limit must be an integer"); return NULL; } - field_limit = PyInt_AsLong(new_limit); + limit = PyInt_AsLong(new_limit); + if (limit == -1 && PyErr_Occurred()) + return NULL; + field_limit = limit; } return PyInt_FromLong(old_limit); } diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index e478a579482..9eab741a01d 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -194,8 +194,10 @@ PyCursesCheckERR(int code, char *fname) static int PyCurses_ConvertToChtype(PyObject *obj, chtype *ch) { - if (PyInt_Check(obj)) { + if (PyInt_Check(obj) || PyLong_Check(obj)) { *ch = (chtype) PyInt_AsLong(obj); + if (*ch == (chtype) -1 && PyErr_Occurred()) + return 0; } else if(PyString_Check(obj) && (PyString_Size(obj) == 1)) { *ch = (chtype) *PyString_AsString(obj); @@ -2576,8 +2578,11 @@ PyCurses_UnCtrl(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args,"O;ch or int",&temp)) return NULL; - if (PyInt_Check(temp)) + if (PyInt_Check(temp) || PyLong_Check(temp)) { ch = (chtype) PyInt_AsLong(temp); + if (ch == (chtype) -1 && PyErr_Occurred()) + return NULL; + } else if (PyString_Check(temp)) ch = (chtype) *PyString_AsString(temp); else { @@ -2598,8 +2603,11 @@ PyCurses_UngetCh(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args,"O;ch or int",&temp)) return NULL; - if (PyInt_Check(temp)) + if (PyInt_Check(temp) || PyLong_Check(temp)) { ch = (int) PyInt_AsLong(temp); + if (ch == -1 && PyErr_Occurred()) + return NULL; + } else if (PyString_Check(temp)) ch = (int) *PyString_AsString(temp); else { diff --git a/Modules/dlmodule.c b/Modules/dlmodule.c index dfecf9d33bd..7a6686e3a6d 100644 --- a/Modules/dlmodule.c +++ b/Modules/dlmodule.c @@ -107,8 +107,11 @@ dl_call(dlobject *xp, PyObject *args) } for (i = 1; i < n; i++) { PyObject *v = PyTuple_GetItem(args, i); - if (PyInt_Check(v)) + if (PyInt_Check(v) || PyLong_Check(v)) { alist[i-1] = PyInt_AsLong(v); + if (alist[i-1] == -1 && PyErr_Occurred()) + return NULL; + } else if (PyString_Check(v)) alist[i-1] = (long)PyString_AsString(v); else if (v == Py_None) diff --git a/Modules/svmodule.c b/Modules/svmodule.c index 1519065666b..42c49c853a0 100644 --- a/Modules/svmodule.c +++ b/Modules/svmodule.c @@ -686,7 +686,7 @@ sv_LoadMap(svobject *self, PyObject *args) if (!cell) goto finally; - if (!PyInt_Check(cell)) { + if (!PyInt_Check(cell) && !PyLong_Check(cell)) { PyErr_BadArgument(); goto finally; } @@ -757,7 +757,7 @@ doParams(svobject *self, PyObject *args, if (!v) goto finally; - if (!PyInt_Check(v)) { + if (!PyInt_Check(v) && !PyLong_Check(v)) { PyErr_BadArgument(); goto finally; } diff --git a/Modules/termios.c b/Modules/termios.c index 57f30dc4cda..9d4d780dca2 100644 --- a/Modules/termios.c +++ b/Modules/termios.c @@ -185,8 +185,11 @@ termios_tcsetattr(PyObject *self, PyObject *args) if (PyString_Check(v) && PyString_Size(v) == 1) mode.c_cc[i] = (cc_t) * PyString_AsString(v); - else if (PyInt_Check(v)) + else if (PyInt_Check(v) || PyLong_Check(v)) { mode.c_cc[i] = (cc_t) PyInt_AsLong(v); + if (mode.c_cc[i] == (cc_t) -1 && PyErr_Occurred()) + return NULL; + } else { PyErr_SetString(PyExc_TypeError, "tcsetattr: elements of attributes must be characters or integers"); diff --git a/Objects/intobject.c b/Objects/intobject.c index 0c5ea65ac02..04e4d299169 100644 --- a/Objects/intobject.c +++ b/Objects/intobject.c @@ -155,6 +155,11 @@ PyInt_AsLong(register PyObject *op) return -1; } + if (PyLong_CheckExact(op)) { + /* avoid creating temporary int object */ + return PyLong_AsLong(op); + } + io = (PyIntObject*) (*nb->nb_int) (op); if (io == NULL) return -1; @@ -163,8 +168,6 @@ PyInt_AsLong(register PyObject *op) /* got a long? => retry int conversion */ val = PyLong_AsLong((PyObject *)io); Py_DECREF(io); - if ((val == -1) && PyErr_Occurred()) - return -1; return val; } else