diff --git a/Doc/conf.py b/Doc/conf.py index 8b1514bae9e..0cfbea60bfa 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -95,6 +95,9 @@ html_static_path = ['tools/sphinxext/static'] # Output file base name for HTML help builder. htmlhelp_basename = 'python' + release.replace('.', '') +# Split the index +html_split_index = True + # Options for LaTeX output # ------------------------ diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index 3bdfab46000..bd0b02a8fc5 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -636,9 +636,9 @@ Or, where the user fails to pass a value at all:: option involved in the error; be sure to do the same when calling ``parser.error()`` from your application code. -If :mod:`optparse`'s default error-handling behaviour does not suite your needs, -you'll need to subclass OptionParser and override ``exit()`` and/or -:meth:`error`. +If :mod:`optparse`'s default error-handling behaviour does not suit your needs, +you'll need to subclass OptionParser and override its :meth:`exit` and/or +:meth:`error` methods. .. _optparse-putting-it-all-together: diff --git a/Doc/whatsnew/2.6.rst b/Doc/whatsnew/2.6.rst index c4c909379a9..f3b03e760fd 100644 --- a/Doc/whatsnew/2.6.rst +++ b/Doc/whatsnew/2.6.rst @@ -521,6 +521,21 @@ environment variable. .. ====================================================================== +.. _pep-0371: + +PEP 371: The ``multiprocessing`` Package +===================================================== + +XXX write this. + +.. seealso:: + + :pep:`371` - Per-user ``site-packages`` Directory + PEP written by Jesse Noller and Richard Oudkerk; + implemented by Jesse Noller. + +.. ====================================================================== + .. _pep-3101: PEP 3101: Advanced String Formatting diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index 742eac2682b..9727d4f091a 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -731,7 +731,7 @@ class StreamHandler(Handler): """ Flushes the stream. """ - if self.stream: + if self.stream and hasattr(self.stream, "flush"): self.stream.flush() def emit(self, record): @@ -787,7 +787,8 @@ class FileHandler(StreamHandler): """ if self.stream: self.flush() - self.stream.close() + if hasattr(self.stream, "close"): + self.stream.close() StreamHandler.close(self) self.stream = None diff --git a/Lib/platform.py b/Lib/platform.py index 8447d41f67a..33033ff0e0b 100755 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -1066,23 +1066,30 @@ def uname(): """ global _uname_cache + no_os_uname = 0 if _uname_cache is not None: return _uname_cache + processor = '' + # Get some infos from the builtin os.uname API... try: system,node,release,version,machine = os.uname() - except AttributeError: - # Hmm, no uname... we'll have to poke around the system then. - system = sys.platform - release = '' - version = '' - node = _node() - machine = '' - processor = '' - use_syscmd_ver = 1 + no_os_uname = 1 + + if no_os_uname or not filter(None, (system, node, release, version, machine)): + # Hmm, no there is either no uname or uname has returned + #'unknowns'... we'll have to poke around the system then. + if no_os_uname: + system = sys.platform + release = '' + version = '' + node = _node() + machine = '' + + use_syscmd_ver = 01 # Try win32_ver() on win32 platforms if system == 'win32': @@ -1093,8 +1100,10 @@ def uname(): # available on Win XP and later; see # http://support.microsoft.com/kb/888731 and # http://www.geocities.com/rick_lively/MANUALS/ENV/MSWIN/PROCESSI.HTM - machine = os.environ.get('PROCESSOR_ARCHITECTURE', '') - processor = os.environ.get('PROCESSOR_IDENTIFIER', machine) + if not machine: + machine = os.environ.get('PROCESSOR_ARCHITECTURE', '') + if not processor: + processor = os.environ.get('PROCESSOR_IDENTIFIER', machine) # Try the 'ver' system command available on some # platforms @@ -1136,30 +1145,28 @@ def uname(): release,(version,stage,nonrel),machine = mac_ver() system = 'MacOS' - else: - # System specific extensions - if system == 'OpenVMS': - # OpenVMS seems to have release and version mixed up - if not release or release == '0': - release = version - version = '' - # Get processor information - try: - import vms_lib - except ImportError: - pass - else: - csid, cpu_number = vms_lib.getsyi('SYI$_CPU',0) - if (cpu_number >= 128): - processor = 'Alpha' - else: - processor = 'VAX' + # System specific extensions + if system == 'OpenVMS': + # OpenVMS seems to have release and version mixed up + if not release or release == '0': + release = version + version = '' + # Get processor information + try: + import vms_lib + except ImportError: + pass else: - # Get processor information from the uname system command - processor = _syscmd_uname('-p','') + csid, cpu_number = vms_lib.getsyi('SYI$_CPU',0) + if (cpu_number >= 128): + processor = 'Alpha' + else: + processor = 'VAX' + if not processor: + # Get processor information from the uname system command + processor = _syscmd_uname('-p','') - # 'unknown' is not really any useful as information; we'll convert - # it to '' which is more portable + #If any unknowns still exist, replace them with ''s, which are more portable if system == 'unknown': system = '' if node == 'unknown': diff --git a/Lib/test/crashers/loosing_mro_ref.py b/Lib/test/crashers/loosing_mro_ref.py index 5ecde638208..a8c6e63ee2b 100644 --- a/Lib/test/crashers/loosing_mro_ref.py +++ b/Lib/test/crashers/loosing_mro_ref.py @@ -27,10 +27,9 @@ class Base(object): class Base2(object): mykey = 'from Base2' -class X(Base): - # you can't add a non-string key to X.__dict__, but it can be - # there from the beginning :-) - locals()[MyKey()] = 5 +# you can't add a non-string key to X.__dict__, but it can be +# there from the beginning :-) +X = type('X', (Base,), {MyKey(): 5}) print(X.mykey) # I get a segfault, or a slightly wrong assertion error in a debug build. diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index 1a34ff8b74d..acfe1f15733 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -335,6 +335,7 @@ class GrammarTests(unittest.TestCase): self.assertEquals(l5(1, 2), 5) self.assertEquals(l5(1, 2, 3), 6) check_syntax_error(self, "lambda x: x = 2") + check_syntax_error(self, "lambda (None,): None") l6 = lambda x, y, *, k=20: x+y+k self.assertEquals(l6(1,2), 1+2+20) self.assertEquals(l6(1,2,k=10), 1+2+10) diff --git a/Lib/test/test_heapq.py b/Lib/test/test_heapq.py index 1c7c97fa48e..fba4fd71f85 100644 --- a/Lib/test/test_heapq.py +++ b/Lib/test/test_heapq.py @@ -211,10 +211,11 @@ class TestHeapC(TestHeap): class LE: def __init__(self, x): self.x = x - def __lt__(self, other): + def __le__(self, other): return self.x >= other.x data = [random.random() for i in range(100)] target = sorted(data, reverse=True) + print("HASATTR", hasattr(LE(0), "__lt__"), LE(0).__lt__) self.assertEqual(hsort(data, LT), target) self.assertEqual(hsort(data, LE), target) diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index 917f62695bc..616e6658d54 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -8,6 +8,7 @@ from test.support import TestFailed, verbose, run_unittest, catch_warning import sys ISBIGENDIAN = sys.byteorder == "big" +IS32BIT = sys.maxsize == 0x7fffffff del sys try: @@ -580,6 +581,11 @@ class StructTest(unittest.TestCase): for c in [b'\x01', b'\x7f', b'\xff', b'\x0f', b'\xf0']: self.assertTrue(struct.unpack('>?', c)[0]) + if IS32BIT: + def test_crasher(self): + self.assertRaises(MemoryError, struct.pack, "357913941b", "a") + + def test_main(): run_unittest(StructTest) diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 40498029693..08fc909dcab 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -520,6 +520,9 @@ class SizeofTest(unittest.TestCase): self.check_sizeof(32768, h + self.align(2) + 2) self.check_sizeof(32768*32768-1, h + self.align(2) + 2) self.check_sizeof(32768*32768, h + self.align(2) + 4) + # tuple + self.check_sizeof((), h) + self.check_sizeof((1,2,3), h + 3*p) def test_main(): diff --git a/Misc/ACKS b/Misc/ACKS index f34163ae004..31fd5d398ab 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -486,6 +486,7 @@ Samuel Nicolary Gustavo Niemeyer Oscar Nierstrasz Hrvoje Niksic +Jesse Noller Bill Noon Stefan Norberg Tim Northover @@ -502,6 +503,7 @@ Jason Orendorff Douglas Orr Denis S. Otkidach Michael Otteneder +R. M. Oudkerk Russel Owen Ondrej Palkovsky Mike Pall @@ -673,6 +675,7 @@ Steven Taschuk Monty Taylor Amy Taylor Tobias Thelen +James Thomas Robin Thomas Eric Tiedemann Tracy Tims diff --git a/Misc/developers.txt b/Misc/developers.txt index 2904a6840a5..9db80fb3589 100644 --- a/Misc/developers.txt +++ b/Misc/developers.txt @@ -17,6 +17,9 @@ the format to accommodate documentation needs as they arise. Permissions History ------------------- +- Jesse Noller was given SVN access on 16 June 2008 by Georg Brandl, + for work on the multiprocessing module. + - Gregor Lingl was given SVN access on 10 June 2008 by MvL, for work on the turtle module. diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 53677c066a1..0a305ed89de 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -1815,6 +1815,8 @@ buffer_info(PyObject *self, PyObject *arg) return NULL; } shape = PyTuple_New(dict->ndim); + if (shape == NULL) + return NULL; for (i = 0; i < (int)dict->ndim; ++i) PyTuple_SET_ITEM(shape, i, PyLong_FromSsize_t(dict->shape[i])); diff --git a/Modules/_struct.c b/Modules/_struct.c index e7cbd4bf11d..6be4557acf9 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -1383,6 +1383,12 @@ prepare_s(PyStructObject *self) } } + /* check for overflow */ + if ((len + 1) > (PY_SSIZE_T_MAX / sizeof(formatcode))) { + PyErr_NoMemory(); + return -1; + } + self->s_size = size; self->s_len = len; codes = PyMem_MALLOC((len + 1) * sizeof(formatcode)); diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index da2e9c2ceb9..3e263695999 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -421,6 +421,9 @@ newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr) if (op == NULL) { return NULL; } + op->ob_descr = descr; + op->allocated = size; + op->weakreflist = NULL; Py_SIZE(op) = size; if (size <= 0) { op->ob_item = NULL; @@ -428,13 +431,10 @@ newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr) else { op->ob_item = PyMem_NEW(char, nbytes); if (op->ob_item == NULL) { - PyObject_Del(op); + Py_DECREF(op); return PyErr_NoMemory(); } } - op->ob_descr = descr; - op->allocated = size; - op->weakreflist = NULL; op->ob_exports = 0; return (PyObject *) op; } @@ -808,11 +808,15 @@ array_do_extend(arrayobject *self, PyObject *bb) "can only extend with array of same kind"); return -1; } + if ((Py_SIZE(self) > PY_SSIZE_T_MAX - Py_SIZE(b)) || + ((Py_SIZE(self) + Py_SIZE(b)) > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) { + PyErr_NoMemory(); + return -1; + } size = Py_SIZE(self) + Py_SIZE(b); PyMem_RESIZE(self->ob_item, char, size*self->ob_descr->itemsize); if (self->ob_item == NULL) { - PyObject_Del(self); - PyErr_NoMemory(); + PyErr_NoMemory(); return -1; } memcpy(self->ob_item + Py_SIZE(self)*self->ob_descr->itemsize, diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 819253c7c44..7ff957e6660 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -683,13 +683,25 @@ tuple_getnewargs(PyTupleObject *v) } +static PyObject * +tuple_sizeof(PyTupleObject *self) +{ + Py_ssize_t res; + + res = PyTuple_Type.tp_basicsize + Py_SIZE(self) * sizeof(PyObject *); + return PyLong_FromSsize_t(res); +} + PyDoc_STRVAR(index_doc, "T.index(value, [start, [stop]]) -> integer -- return first index of value"); PyDoc_STRVAR(count_doc, "T.count(value) -> integer -- return number of occurrences of value"); +PyDoc_STRVAR(sizeof_doc, +"T.__sizeof__() -- size of T in memory, in bytes"); static PyMethodDef tuple_methods[] = { {"__getnewargs__", (PyCFunction)tuple_getnewargs, METH_NOARGS}, + {"__sizeof__", (PyCFunction)tuple_sizeof, METH_NOARGS, sizeof_doc}, {"index", (PyCFunction)tupleindex, METH_VARARGS, index_doc}, {"count", (PyCFunction)tuplecount, METH_O, count_doc}, {NULL, NULL} /* sentinel */ diff --git a/Python/marshal.c b/Python/marshal.c index d4755c9d672..e3619a64aff 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -70,7 +70,7 @@ w_more(int c, WFILE *p) size = PyBytes_Size(p->str); newsize = size + size + 1024; if (newsize > 32*1024*1024) { - newsize = size + 1024*1024; + newsize = size + (size >> 3); /* 12.5% overallocation */ } if (_PyBytes_Resize(&p->str, newsize) != 0) { p->ptr = p->end = NULL; diff --git a/Tools/msi/msilib.py b/Tools/msi/msilib.py index 9245a22986f..6b8a2b52894 100644 --- a/Tools/msi/msilib.py +++ b/Tools/msi/msilib.py @@ -284,7 +284,8 @@ def add_stream(db, name, path): def init_database(name, schema, ProductName, ProductCode, ProductVersion, - Manufacturer): + Manufacturer, + request_uac = False): try: os.unlink(name) except OSError: @@ -306,7 +307,11 @@ def init_database(name, schema, si.SetProperty(PID_AUTHOR, Manufacturer) si.SetProperty(PID_TEMPLATE, msi_type) si.SetProperty(PID_REVNUMBER, gen_uuid()) - si.SetProperty(PID_WORDCOUNT, 2) # long file names, compressed, original media + if request_uac: + wc = 2 # long file names, compressed, original media + else: + wc = 2 | 8 # +never invoke UAC + si.SetProperty(PID_WORDCOUNT, wc) si.SetProperty(PID_PAGECOUNT, 200) si.SetProperty(PID_APPNAME, "Python MSI Library") # XXX more properties