From python-3000-checkins at python.org Tue Jan 1 05:06:48 2008 From: python-3000-checkins at python.org (guido.van.rossum) Date: Tue, 1 Jan 2008 05:06:48 +0100 (CET) Subject: [Python-3000-checkins] r59636 - python/branches/py3k/Objects/typeobject.c Message-ID: <20080101040648.B0CE71E400D@bag.python.org> Author: guido.van.rossum Date: Tue Jan 1 05:06:48 2008 New Revision: 59636 Modified: python/branches/py3k/Objects/typeobject.c Log: Merge changes from 59576 from trunk to p3yk branch; these were skipped in the regular merge. Fixes issue #1693. Modified: python/branches/py3k/Objects/typeobject.c ============================================================================== --- python/branches/py3k/Objects/typeobject.c (original) +++ python/branches/py3k/Objects/typeobject.c Tue Jan 1 05:06:48 2008 @@ -3167,28 +3167,22 @@ type->tp_flags |= Py_TPFLAGS_DICT_SUBCLASS; } -/* Map rich comparison operators to their __xx__ namesakes */ -static char *name_op[] = { - "__lt__", - "__le__", +static char *hash_name_op[] = { "__eq__", - "__ne__", - "__gt__", - "__ge__", - /* These are only for overrides_cmp_or_hash(): */ "__cmp__", "__hash__", + NULL }; static int -overrides_cmp_or_hash(PyTypeObject *type) +overrides_hash(PyTypeObject *type) { - int i; + char **p; PyObject *dict = type->tp_dict; assert(dict != NULL); - for (i = 0; i < 8; i++) { - if (PyDict_GetItemString(dict, name_op[i]) != NULL) + for (p = hash_name_op; *p; p++) { + if (PyDict_GetItemString(dict, *p) != NULL) return 1; } return 0; @@ -3314,7 +3308,7 @@ if (type->tp_compare == NULL && type->tp_richcompare == NULL && type->tp_hash == NULL && - !overrides_cmp_or_hash(type)) + !overrides_hash(type)) { type->tp_compare = base->tp_compare; type->tp_richcompare = base->tp_richcompare; @@ -4739,6 +4733,15 @@ return 0; } +static char *name_op[] = { + "__lt__", + "__le__", + "__eq__", + "__ne__", + "__gt__", + "__ge__", +}; + static PyObject * half_richcompare(PyObject *self, PyObject *other, int op) { From python-3000-checkins at python.org Tue Jan 1 15:42:16 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Tue, 1 Jan 2008 15:42:16 +0100 (CET) Subject: [Python-3000-checkins] r59642 - in python/branches/py3k: Lib/distutils/sysconfig.py Lib/sqlite3/test/types.py Objects/descrobject.c PC/VS7.1/_ssl.mak PC/VS7.1/make_buildinfo.c Tools/msi/msi.py Message-ID: <20080101144216.4AD181E400E@bag.python.org> Author: christian.heimes Date: Tue Jan 1 15:42:15 2008 New Revision: 59642 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/sysconfig.py python/branches/py3k/Lib/sqlite3/test/types.py python/branches/py3k/Objects/descrobject.c python/branches/py3k/PC/VS7.1/_ssl.mak python/branches/py3k/PC/VS7.1/make_buildinfo.c python/branches/py3k/Tools/msi/msi.py Log: Merged revisions 59628-59641 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r59631 | christian.heimes | 2007-12-31 20:16:56 +0100 (Mon, 31 Dec 2007) | 1 line Fixed path ........ r59632 | christian.heimes | 2007-12-31 20:20:57 +0100 (Mon, 31 Dec 2007) | 1 line Fixed path to _ssl.c in Windows make file ........ r59633 | christian.heimes | 2007-12-31 20:23:22 +0100 (Mon, 31 Dec 2007) | 1 line Fixed path to _ssl.c in Windows make file, take two ........ r59634 | christian.heimes | 2007-12-31 20:25:22 +0100 (Mon, 31 Dec 2007) | 1 line Fixed path to _ssl.c in Windows make file, take three ... ........ r59635 | neal.norwitz | 2008-01-01 00:48:47 +0100 (Tue, 01 Jan 2008) | 1 line Fix refleak ........ r59637 | guido.van.rossum | 2008-01-01 05:15:29 +0100 (Tue, 01 Jan 2008) | 5 lines Fix an odd error which would only occur close to new year's eve, due to use of datetime.datetime.now() instead of utcnow() for comparison. (I think the test can still fail if it's executed pretty much *at* new year's eve, but that's not worth fixing.) ........ r59638 | christian.heimes | 2008-01-01 14:40:26 +0100 (Tue, 01 Jan 2008) | 1 line MSI uses back slashes as path separators ........ r59639 | christian.heimes | 2008-01-01 14:52:57 +0100 (Tue, 01 Jan 2008) | 1 line Added new wininst files to msi.py and adjusted some paths ........ r59640 | christian.heimes | 2008-01-01 14:58:16 +0100 (Tue, 01 Jan 2008) | 1 line The root of the project is two levels up from PC/VS7.1 ........ r59641 | christian.heimes | 2008-01-01 15:37:32 +0100 (Tue, 01 Jan 2008) | 1 line Added support for new Windows build dirs in PC/ to distutils.sysconfig ........ Modified: python/branches/py3k/Lib/distutils/sysconfig.py ============================================================================== --- python/branches/py3k/Lib/distutils/sysconfig.py (original) +++ python/branches/py3k/Lib/distutils/sysconfig.py Tue Jan 1 15:42:15 2008 @@ -27,6 +27,10 @@ project_base = os.path.dirname(os.path.abspath(sys.executable)) if os.name == "nt" and "pcbuild" in project_base[-8:].lower(): project_base = os.path.abspath(os.path.join(project_base, os.path.pardir)) +# PC/VS7.1 +if os.name == "nt" and "\\pc\\v" in project_base[-10:].lower(): + project_base = os.path.abspath(os.path.join(project_base, os.path.pardir, + os.path.pardir)) # python_build: (Boolean) if true, we're either building Python or # building an extension with an un-installed Python, so we use Modified: python/branches/py3k/Lib/sqlite3/test/types.py ============================================================================== --- python/branches/py3k/Lib/sqlite3/test/types.py (original) +++ python/branches/py3k/Lib/sqlite3/test/types.py Tue Jan 1 15:42:15 2008 @@ -341,8 +341,7 @@ if sqlite.sqlite_version_info < (3, 1): return - # SQLite's current_timestamp uses UTC time, while datetime.datetime.now() uses local time. - now = datetime.datetime.now() + now = datetime.datetime.utcnow() self.cur.execute("insert into test(ts) values (current_timestamp)") self.cur.execute("select ts from test") ts = self.cur.fetchone()[0] Modified: python/branches/py3k/Objects/descrobject.c ============================================================================== --- python/branches/py3k/Objects/descrobject.c (original) +++ python/branches/py3k/Objects/descrobject.c Tue Jan 1 15:42:15 2008 @@ -1204,6 +1204,7 @@ } new = PyObject_CallFunction(type, "OOOO", get, set, del, doc); + Py_DECREF(type); if (new == NULL) return NULL; pnew = (propertyobject *)new; Modified: python/branches/py3k/PC/VS7.1/_ssl.mak ============================================================================== --- python/branches/py3k/PC/VS7.1/_ssl.mak (original) +++ python/branches/py3k/PC/VS7.1/_ssl.mak Tue Jan 1 15:42:15 2008 @@ -12,25 +12,25 @@ SSL_LIB_DIR=$(SSL_DIR)/out32 !ENDIF -INCLUDES=-I ../Include -I ../PC -I $(SSL_DIR)/inc32 +INCLUDES=-I ../../Include -I ../../PC -I $(SSL_DIR)/inc32 SSL_LIBS=gdi32.lib wsock32.lib user32.lib advapi32.lib /LIBPATH:$(SSL_LIB_DIR) libeay32.lib ssleay32.lib -SSL_SOURCE=../Modules/_ssl.c +SSL_SOURCE=../../Modules/_ssl.c HASH_LIBS=gdi32.lib user32.lib advapi32.lib /libpath:$(SSL_LIB_DIR) libeay32.lib -HASH_SOURCE=../Modules/_hashopenssl.c +HASH_SOURCE=../../Modules/_hashopenssl.c all: _ssl$(SUFFIX) _hashlib$(SUFFIX) # Split compile/link into two steps to better support VSExtComp -_ssl$(SUFFIX): $(SSL_SOURCE) $(SSL_LIB_DIR)/libeay32.lib $(SSL_LIB_DIR)/ssleay32.lib ../PC/*.h ../Include/*.h +_ssl$(SUFFIX): $(SSL_SOURCE) $(SSL_LIB_DIR)/libeay32.lib $(SSL_LIB_DIR)/ssleay32.lib ../../PC/*.h ../../Include/*.h @if not exist "$(TEMP)/_ssl/." mkdir "$(TEMP)/_ssl" cl /nologo /c $(SSL_SOURCE) $(CFLAGS) /Fo$(TEMP)\_ssl\$*.obj $(INCLUDES) link /nologo @<< /dll /out:_ssl$(SUFFIX) $(TEMP)\_ssl\$*.obj $(SSL_LIBS) $(EXTRA_LIBS) << -_hashlib$(SUFFIX): $(HASH_SOURCE) $(SSL_LIB_DIR)/libeay32.lib ../PC/*.h ../Include/*.h +_hashlib$(SUFFIX): $(HASH_SOURCE) $(SSL_LIB_DIR)/libeay32.lib ../../PC/*.h ../../Include/*.h @if not exist "$(TEMP)/_hashlib/." mkdir "$(TEMP)/_hashlib" cl /nologo /c $(HASH_SOURCE) $(CFLAGS) $(EXTRA_CFLAGS) /Fo$(TEMP)\_hashlib\$*.obj $(INCLUDES) link /nologo @<< Modified: python/branches/py3k/PC/VS7.1/make_buildinfo.c ============================================================================== --- python/branches/py3k/PC/VS7.1/make_buildinfo.c (original) +++ python/branches/py3k/PC/VS7.1/make_buildinfo.c Tue Jan 1 15:42:15 2008 @@ -5,9 +5,9 @@ /* This file creates the getbuildinfo.o object, by first invoking subwcrev.exe (if found), and then invoking cl.exe. - As a side effect, it might generate PCBuild\getbuildinfo2.c + As a side effect, it might generate PC\VS7.1\getbuildinfo2.c also. If this isn't a subversion checkout, or subwcrev isn't - found, it compiles ..\\Modules\\getbuildinfo.c instead. + found, it compiles ..\\..\\Modules\\getbuildinfo.c instead. Currently, subwcrev.exe is found from the registry entries of TortoiseSVN. @@ -44,7 +44,7 @@ if (_stat(command+1, &st) < 0) /* subwcrev.exe not part of the release */ return 0; - strcat(command, "\" .. ..\\Modules\\getbuildinfo.c getbuildinfo2.c"); + strcat(command, "\" ..\\.. ..\\..\\Modules\\getbuildinfo.c getbuildinfo2.c"); puts(command); fflush(stdout); if (system(command) < 0) return 0; @@ -80,8 +80,8 @@ if ((do_unlink = make_buildinfo2())) strcat(command, "getbuildinfo2.c -DSUBWCREV "); else - strcat(command, "..\\Modules\\getbuildinfo.c"); - strcat(command, " -Fogetbuildinfo.o -I..\\Include -I..\\PC"); + strcat(command, "..\\..\\Modules\\getbuildinfo.c"); + strcat(command, " -Fogetbuildinfo.o -I..\\..\\Include -I..\\..\\PC"); puts(command); fflush(stdout); result = system(command); if (do_unlink) @@ -89,4 +89,4 @@ if (result < 0) return EXIT_FAILURE; return 0; -} \ No newline at end of file +} Modified: python/branches/py3k/Tools/msi/msi.py ============================================================================== --- python/branches/py3k/Tools/msi/msi.py (original) +++ python/branches/py3k/Tools/msi/msi.py Tue Jan 1 15:42:15 2008 @@ -27,8 +27,8 @@ # Where is sqlite3.dll located, relative to srcdir? sqlite_dir = "../sqlite-source-3.3.4" # path to PCbuild directory -PCBUILD="PC/VS7.1" -#PCBUILD="PCbuild9" +PCBUILD="PC\\VS7.1" +#PCBUILD="PCbuild" # msvcrt version MSVCR = "71" #MSVCR = "90" @@ -335,7 +335,7 @@ if not os.path.exists(srcdir+r"\PC\python_icon.exe"): raise "Run icons.mak in PC directory" add_data(db, "Binary", - [("PythonWin", msilib.Binary(r"%s\%s\installer.bmp" % (srcdir, PCBUILD))), # 152x328 pixels + [("PythonWin", msilib.Binary(r"%s\PCbuild\installer.bmp" % srcdir)), # 152x328 pixels ("py.ico",msilib.Binary(srcdir+r"\PC\py.ico")), ]) add_data(db, "Icon", @@ -990,8 +990,10 @@ lib.glob("*.gif") lib.add_file("idle.icns") if dir=="command" and parent.physical=="distutils": - lib.add_file("wininst-6.exe") + lib.add_file("wininst-6.0.exe") lib.add_file("wininst-7.1.exe") + lib.add_file("wininst-8.0.exe") + lib.add_file("wininst-9.0.exe") if dir=="setuptools": lib.add_file("cli.exe") lib.add_file("gui.exe") @@ -1009,8 +1011,8 @@ # Add DLLs default_feature.set_current() lib = PyDirectory(db, cab, root, srcdir + "/" + PCBUILD, "DLLs", "DLLS|DLLs") - lib.add_file("py.ico", src="../PC/py.ico") - lib.add_file("pyc.ico", src="../PC/pyc.ico") + lib.add_file("py.ico", src=srcdir+"/PC/py.ico") + lib.add_file("pyc.ico", src=srcdir+"/PC/pyc.ico") dlls = [] tclfiles = [] for f in extensions: From guido at python.org Tue Jan 1 17:27:53 2008 From: guido at python.org (Guido van Rossum) Date: Tue, 1 Jan 2008 08:27:53 -0800 Subject: [Python-3000-checkins] r59602 - python/branches/py3k/Lib/io.py In-Reply-To: <20071228012423.0FEE31E4015@bag.python.org> References: <20071228012423.0FEE31E4015@bag.python.org> Message-ID: Where's the unittest for this fix? On Dec 27, 2007 5:24 PM, alexandre.vassalotti wrote: > Author: alexandre.vassalotti > Date: Fri Dec 28 02:24:22 2007 > New Revision: 59602 > > Modified: > python/branches/py3k/Lib/io.py > Log: > Fix the reset() method of IncrementalNewlineDecoder to > also reset self.seennl. > > > Modified: python/branches/py3k/Lib/io.py > ============================================================================== > --- python/branches/py3k/Lib/io.py (original) > +++ python/branches/py3k/Lib/io.py Fri Dec 28 02:24:22 2007 > @@ -1116,6 +1116,7 @@ > self.decoder.setstate((buf, flag)) > > def reset(self): > + self.seennl = 0 > self.buffer = b'' > self.decoder.reset() > > _______________________________________________ > Python-3000-checkins mailing list > Python-3000-checkins at python.org > http://mail.python.org/mailman/listinfo/python-3000-checkins > -- --Guido van Rossum (home page: http://www.python.org/~guido/) From python-3000-checkins at python.org Tue Jan 1 17:30:47 2008 From: python-3000-checkins at python.org (guido.van.rossum) Date: Tue, 1 Jan 2008 17:30:47 +0100 (CET) Subject: [Python-3000-checkins] r59646 - python/branches/py3k/Lib/getpass.py Message-ID: <20080101163047.D7EB21E4002@bag.python.org> Author: guido.van.rossum Date: Tue Jan 1 17:30:47 2008 New Revision: 59646 Modified: python/branches/py3k/Lib/getpass.py Log: Patch #1703 by Philip Jenvey -- getpass() should flush after writing prompt. Modified: python/branches/py3k/Lib/getpass.py ============================================================================== --- python/branches/py3k/Lib/getpass.py (original) +++ python/branches/py3k/Lib/getpass.py Tue Jan 1 17:30:47 2008 @@ -78,6 +78,7 @@ prompt = str(prompt) if prompt: stream.write(prompt) + stream.flush() line = sys.stdin.readline() if not line: raise EOFError From python-3000-checkins at python.org Tue Jan 1 19:49:31 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Tue, 1 Jan 2008 19:49:31 +0100 (CET) Subject: [Python-3000-checkins] r59647 - python/branches/py3k-grandrenaming Message-ID: <20080101184931.2D7931E4004@bag.python.org> Author: christian.heimes Date: Tue Jan 1 19:49:30 2008 New Revision: 59647 Added: python/branches/py3k-grandrenaming/ - copied from r59646, python/branches/py3k/ Log: Create branch for API and file renaming From python-3000-checkins at python.org Tue Jan 1 19:52:02 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Tue, 1 Jan 2008 19:52:02 +0100 (CET) Subject: [Python-3000-checkins] r59648 - python/branches/py3k-grandrenaming Message-ID: <20080101185202.73A291E4002@bag.python.org> Author: christian.heimes Date: Tue Jan 1 19:52:02 2008 New Revision: 59648 Modified: python/branches/py3k-grandrenaming/ (props changed) Log: svnmerge init From guido at python.org Tue Jan 1 20:00:09 2008 From: guido at python.org (Guido van Rossum) Date: Tue, 1 Jan 2008 11:00:09 -0800 Subject: [Python-3000-checkins] r59647 - python/branches/py3k-grandrenaming In-Reply-To: <20080101184931.2D7931E4004@bag.python.org> References: <20080101184931.2D7931E4004@bag.python.org> Message-ID: Before you put too much effort in this, let's talk. I'm worried that some of the renamings would complicate merging from the trunk... On Jan 1, 2008 10:49 AM, christian.heimes wrote: > Author: christian.heimes > Date: Tue Jan 1 19:49:30 2008 > New Revision: 59647 > > Added: > python/branches/py3k-grandrenaming/ > - copied from r59646, python/branches/py3k/ > Log: > Create branch for API and file renaming > _______________________________________________ > Python-3000-checkins mailing list > Python-3000-checkins at python.org > http://mail.python.org/mailman/listinfo/python-3000-checkins > -- --Guido van Rossum (home page: http://www.python.org/~guido/) From python-3000-checkins at python.org Tue Jan 1 20:13:48 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Tue, 1 Jan 2008 20:13:48 +0100 (CET) Subject: [Python-3000-checkins] r59649 - python/branches/py3k-grandrenaming/Objects/bytesobject.c python/branches/py3k-grandrenaming/Objects/stringobject.c Message-ID: <20080101191348.332051E4002@bag.python.org> Author: christian.heimes Date: Tue Jan 1 20:13:47 2008 New Revision: 59649 Modified: python/branches/py3k-grandrenaming/Objects/bytesobject.c python/branches/py3k-grandrenaming/Objects/stringobject.c Log: bytes_ -> bytearray_; string_ -> bytes_ Modified: python/branches/py3k-grandrenaming/Objects/bytesobject.c ============================================================================== --- python/branches/py3k-grandrenaming/Objects/bytesobject.c (original) +++ python/branches/py3k-grandrenaming/Objects/bytesobject.c Tue Jan 1 20:13:47 2008 @@ -50,7 +50,7 @@ } static int -bytes_getbuffer(PyBytesObject *obj, Py_buffer *view, int flags) +bytearray_getbuffer(PyBytesObject *obj, Py_buffer *view, int flags) { int ret; void *ptr; @@ -70,7 +70,7 @@ } static void -bytes_releasebuffer(PyBytesObject *obj, Py_buffer *view) +bytearray_releasebuffer(PyBytesObject *obj, Py_buffer *view) { obj->ob_exports--; } @@ -246,13 +246,13 @@ /* Functions stuffed into the type object */ static Py_ssize_t -bytes_length(PyBytesObject *self) +bytearray_length(PyBytesObject *self) { return Py_SIZE(self); } static PyObject * -bytes_iconcat(PyBytesObject *self, PyObject *other) +bytearray_iconcat(PyBytesObject *self, PyObject *other) { Py_ssize_t mysize; Py_ssize_t size; @@ -285,7 +285,7 @@ } static PyObject * -bytes_repeat(PyBytesObject *self, Py_ssize_t count) +bytearray_repeat(PyBytesObject *self, Py_ssize_t count) { PyBytesObject *result; Py_ssize_t mysize; @@ -311,7 +311,7 @@ } static PyObject * -bytes_irepeat(PyBytesObject *self, Py_ssize_t count) +bytearray_irepeat(PyBytesObject *self, Py_ssize_t count) { Py_ssize_t mysize; Py_ssize_t size; @@ -342,7 +342,7 @@ } static PyObject * -bytes_getitem(PyBytesObject *self, Py_ssize_t i) +bytearray_getitem(PyBytesObject *self, Py_ssize_t i) { if (i < 0) i += Py_SIZE(self); @@ -354,7 +354,7 @@ } static PyObject * -bytes_subscript(PyBytesObject *self, PyObject *item) +bytearray_subscript(PyBytesObject *self, PyObject *item) { if (PyIndex_Check(item)) { Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); @@ -409,7 +409,7 @@ } static int -bytes_setslice(PyBytesObject *self, Py_ssize_t lo, Py_ssize_t hi, +bytearray_setslice(PyBytesObject *self, Py_ssize_t lo, Py_ssize_t hi, PyObject *values) { Py_ssize_t avail, needed; @@ -424,7 +424,7 @@ values = PyBytes_FromObject(values); if (values == NULL) return -1; - err = bytes_setslice(self, lo, hi, values); + err = bytearray_setslice(self, lo, hi, values); Py_DECREF(values); return err; } @@ -495,7 +495,7 @@ } static int -bytes_setitem(PyBytesObject *self, Py_ssize_t i, PyObject *value) +bytearray_setitem(PyBytesObject *self, Py_ssize_t i, PyObject *value) { Py_ssize_t ival; @@ -508,7 +508,7 @@ } if (value == NULL) - return bytes_setslice(self, i, i+1, NULL); + return bytearray_setslice(self, i, i+1, NULL); ival = PyNumber_AsSsize_t(value, PyExc_ValueError); if (ival == -1 && PyErr_Occurred()) @@ -524,7 +524,7 @@ } static int -bytes_ass_subscript(PyBytesObject *self, PyObject *item, PyObject *values) +bytearray_ass_subscript(PyBytesObject *self, PyObject *item, PyObject *values) { Py_ssize_t start, stop, step, slicelen, needed; char *bytes; @@ -585,7 +585,7 @@ values = PyBytes_FromObject(values); if (values == NULL) return -1; - err = bytes_ass_subscript(self, item, values); + err = bytearray_ass_subscript(self, item, values); Py_DECREF(values); return err; } @@ -682,7 +682,7 @@ } static int -bytes_init(PyBytesObject *self, PyObject *args, PyObject *kwds) +bytearray_init(PyBytesObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"source", "encoding", "errors", 0}; PyObject *arg = NULL; @@ -725,7 +725,7 @@ if (encoded == NULL) return -1; assert(PyString_Check(encoded)); - new = bytes_iconcat(self, encoded); + new = bytearray_iconcat(self, encoded); Py_DECREF(encoded); if (new == NULL) return -1; @@ -832,7 +832,7 @@ /* Mostly copied from string_repr, but without the "smart quote" functionality. */ static PyObject * -bytes_repr(PyBytesObject *self) +bytearray_repr(PyBytesObject *self) { static const char *hexdigits = "0123456789abcdef"; const char *quote_prefix = "bytearray(b"; @@ -917,18 +917,18 @@ } static PyObject * -bytes_str(PyObject *op) +bytearray_str(PyObject *op) { if (Py_BytesWarningFlag) { if (PyErr_WarnEx(PyExc_BytesWarning, "str() on a bytearray instance", 1)) return NULL; } - return bytes_repr((PyBytesObject*)op); + return bytearray_repr((PyBytesObject*)op); } static PyObject * -bytes_richcompare(PyObject *self, PyObject *other, int op) +bytearray_richcompare(PyObject *self, PyObject *other, int op) { Py_ssize_t self_size, other_size; Py_buffer self_bytes, other_bytes; @@ -1003,7 +1003,7 @@ } static void -bytes_dealloc(PyBytesObject *self) +bytearray_dealloc(PyBytesObject *self) { if (self->ob_bytes != 0) { PyMem_Free(self->ob_bytes); @@ -1052,7 +1052,7 @@ Py_LOCAL_INLINE(Py_ssize_t) -bytes_find_internal(PyBytesObject *self, PyObject *args, int dir) +bytearray_find_internal(PyBytesObject *self, PyObject *args, int dir) { PyObject *subobj; Py_buffer subbuf; @@ -1086,9 +1086,9 @@ Return -1 on failure."); static PyObject * -bytes_find(PyBytesObject *self, PyObject *args) +bytearray_find(PyBytesObject *self, PyObject *args) { - Py_ssize_t result = bytes_find_internal(self, args, +1); + Py_ssize_t result = bytearray_find_internal(self, args, +1); if (result == -2) return NULL; return PyLong_FromSsize_t(result); @@ -1102,7 +1102,7 @@ as in slice notation."); static PyObject * -bytes_count(PyBytesObject *self, PyObject *args) +bytearray_count(PyBytesObject *self, PyObject *args) { PyObject *sub_obj; const char *str = PyBytes_AS_STRING(self); @@ -1133,9 +1133,9 @@ Like B.find() but raise ValueError when the subsection is not found."); static PyObject * -bytes_index(PyBytesObject *self, PyObject *args) +bytearray_index(PyBytesObject *self, PyObject *args) { - Py_ssize_t result = bytes_find_internal(self, args, +1); + Py_ssize_t result = bytearray_find_internal(self, args, +1); if (result == -2) return NULL; if (result == -1) { @@ -1157,9 +1157,9 @@ Return -1 on failure."); static PyObject * -bytes_rfind(PyBytesObject *self, PyObject *args) +bytearray_rfind(PyBytesObject *self, PyObject *args) { - Py_ssize_t result = bytes_find_internal(self, args, -1); + Py_ssize_t result = bytearray_find_internal(self, args, -1); if (result == -2) return NULL; return PyLong_FromSsize_t(result); @@ -1172,9 +1172,9 @@ Like B.rfind() but raise ValueError when the subsection is not found."); static PyObject * -bytes_rindex(PyBytesObject *self, PyObject *args) +bytearray_rindex(PyBytesObject *self, PyObject *args) { - Py_ssize_t result = bytes_find_internal(self, args, -1); + Py_ssize_t result = bytearray_find_internal(self, args, -1); if (result == -2) return NULL; if (result == -1) { @@ -1187,7 +1187,7 @@ static int -bytes_contains(PyObject *self, PyObject *arg) +bytearray_contains(PyObject *self, PyObject *arg) { Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError); if (ival == -1 && PyErr_Occurred()) { @@ -1262,7 +1262,7 @@ prefix can also be a tuple of strings to try."); static PyObject * -bytes_startswith(PyBytesObject *self, PyObject *args) +bytearray_startswith(PyBytesObject *self, PyObject *args) { Py_ssize_t start = 0; Py_ssize_t end = PY_SSIZE_T_MAX; @@ -1302,7 +1302,7 @@ suffix can also be a tuple of strings to try."); static PyObject * -bytes_endswith(PyBytesObject *self, PyObject *args) +bytearray_endswith(PyBytesObject *self, PyObject *args) { Py_ssize_t start = 0; Py_ssize_t end = PY_SSIZE_T_MAX; @@ -1343,7 +1343,7 @@ table, which must be a bytes object of length 256."); static PyObject * -bytes_translate(PyBytesObject *self, PyObject *args) +bytearray_translate(PyBytesObject *self, PyObject *args) { register char *input, *output; register const char *table; @@ -2040,7 +2040,7 @@ given, only the first count occurrences are replaced."); static PyObject * -bytes_replace(PyBytesObject *self, PyObject *args) +bytearray_replace(PyBytesObject *self, PyObject *args) { Py_ssize_t count = -1; PyObject *from, *to, *res; @@ -2191,7 +2191,7 @@ If maxsplit is given, at most maxsplit splits are done."); static PyObject * -bytes_split(PyBytesObject *self, PyObject *args) +bytearray_split(PyBytesObject *self, PyObject *args) { Py_ssize_t len = PyBytes_GET_SIZE(self), n, i, j; Py_ssize_t maxsplit = -1, count = 0; @@ -2295,7 +2295,7 @@ found, returns B and two empty bytearray objects."); static PyObject * -bytes_partition(PyBytesObject *self, PyObject *sep_obj) +bytearray_partition(PyBytesObject *self, PyObject *sep_obj) { PyObject *bytesep, *result; @@ -2323,7 +2323,7 @@ bytearray objects and B."); static PyObject * -bytes_rpartition(PyBytesObject *self, PyObject *sep_obj) +bytearray_rpartition(PyBytesObject *self, PyObject *sep_obj) { PyObject *bytesep, *result; @@ -2426,7 +2426,7 @@ If maxsplit is given, at most maxsplit splits are done."); static PyObject * -bytes_rsplit(PyBytesObject *self, PyObject *args) +bytearray_rsplit(PyBytesObject *self, PyObject *args) { Py_ssize_t len = PyBytes_GET_SIZE(self), n, i, j; Py_ssize_t maxsplit = -1, count = 0; @@ -2492,7 +2492,7 @@ \n\ Reverse the order of the values in B in place."); static PyObject * -bytes_reverse(PyBytesObject *self, PyObject *unused) +bytearray_reverse(PyBytesObject *self, PyObject *unused) { char swap, *head, *tail; Py_ssize_t i, j, n = Py_SIZE(self); @@ -2514,7 +2514,7 @@ \n\ Insert a single item into the bytearray before the given index."); static PyObject * -bytes_insert(PyBytesObject *self, PyObject *args) +bytearray_insert(PyBytesObject *self, PyObject *args) { int value; Py_ssize_t where, n = Py_SIZE(self); @@ -2553,7 +2553,7 @@ \n\ Append a single item to the end of B."); static PyObject * -bytes_append(PyBytesObject *self, PyObject *arg) +bytearray_append(PyBytesObject *self, PyObject *arg) { int value; Py_ssize_t n = Py_SIZE(self); @@ -2579,7 +2579,7 @@ Append all the elements from the iterator or sequence to the\n\ end of B."); static PyObject * -bytes_extend(PyBytesObject *self, PyObject *arg) +bytearray_extend(PyBytesObject *self, PyObject *arg) { PyObject *it, *item, *tmp, *res; Py_ssize_t buf_size = 0, len = 0; @@ -2588,7 +2588,7 @@ /* bytes_setslice code only accepts something supporting PEP 3118. */ if (PyObject_CheckBuffer(arg)) { - if (bytes_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1) + if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1) return NULL; Py_RETURN_NONE; @@ -2626,7 +2626,7 @@ /* XXX: Is possible to avoid a full copy of the buffer? */ tmp = PyBytes_FromStringAndSize(buf, len); - res = bytes_extend(self, tmp); + res = bytearray_extend(self, tmp); Py_DECREF(tmp); PyMem_Free(buf); @@ -2639,7 +2639,7 @@ Remove and return a single item from B. If no index\n\ argument is give, will pop the last value."); static PyObject * -bytes_pop(PyBytesObject *self, PyObject *args) +bytearray_pop(PyBytesObject *self, PyObject *args) { int value; Py_ssize_t where = -1, n = Py_SIZE(self); @@ -2672,7 +2672,7 @@ \n\ Remove the first occurance of a value in B."); static PyObject * -bytes_remove(PyBytesObject *self, PyObject *arg) +bytearray_remove(PyBytesObject *self, PyObject *arg) { int value; Py_ssize_t where, n = Py_SIZE(self); @@ -2724,7 +2724,7 @@ Strip leading and trailing bytes contained in the argument.\n\ If the argument is omitted, strip ASCII whitespace."); static PyObject * -bytes_strip(PyBytesObject *self, PyObject *args) +bytearray_strip(PyBytesObject *self, PyObject *args) { Py_ssize_t left, right, mysize, argsize; void *myptr, *argptr; @@ -2760,7 +2760,7 @@ Strip leading bytes contained in the argument.\n\ If the argument is omitted, strip leading ASCII whitespace."); static PyObject * -bytes_lstrip(PyBytesObject *self, PyObject *args) +bytearray_lstrip(PyBytesObject *self, PyObject *args) { Py_ssize_t left, right, mysize, argsize; void *myptr, *argptr; @@ -2793,7 +2793,7 @@ Strip trailing bytes contained in the argument.\n\ If the argument is omitted, strip trailing ASCII whitespace."); static PyObject * -bytes_rstrip(PyBytesObject *self, PyObject *args) +bytearray_rstrip(PyBytesObject *self, PyObject *args) { Py_ssize_t left, right, mysize, argsize; void *myptr, *argptr; @@ -2831,7 +2831,7 @@ able to handle UnicodeDecodeErrors."); static PyObject * -bytes_decode(PyObject *self, PyObject *args) +bytearray_decode(PyObject *self, PyObject *args) { const char *encoding = NULL; const char *errors = NULL; @@ -2849,7 +2849,7 @@ Returns the number of bytes actually allocated."); static PyObject * -bytes_alloc(PyBytesObject *self) +bytearray_alloc(PyBytesObject *self) { return PyLong_FromSsize_t(self->ob_alloc); } @@ -2860,7 +2860,7 @@ Concatenates any number of bytearray objects, with B in between each pair."); static PyObject * -bytes_join(PyBytesObject *self, PyObject *it) +bytearray_join(PyBytesObject *self, PyObject *it) { PyObject *seq; Py_ssize_t mysize = Py_SIZE(self); @@ -2953,7 +2953,7 @@ } static PyObject * -bytes_fromhex(PyObject *cls, PyObject *args) +bytearray_fromhex(PyObject *cls, PyObject *args) { PyObject *newbytes, *hexobj; char *buf; @@ -2999,7 +2999,7 @@ PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); static PyObject * -bytes_reduce(PyBytesObject *self) +bytearray_reduce(PyBytesObject *self) { PyObject *latin1, *dict; if (self->ob_bytes) @@ -3018,49 +3018,49 @@ return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict); } -static PySequenceMethods bytes_as_sequence = { - (lenfunc)bytes_length, /* sq_length */ +static PySequenceMethods bytearray_as_sequence = { + (lenfunc)bytearray_length, /* sq_length */ (binaryfunc)PyBytes_Concat, /* sq_concat */ - (ssizeargfunc)bytes_repeat, /* sq_repeat */ - (ssizeargfunc)bytes_getitem, /* sq_item */ + (ssizeargfunc)bytearray_repeat, /* sq_repeat */ + (ssizeargfunc)bytearray_getitem, /* sq_item */ 0, /* sq_slice */ - (ssizeobjargproc)bytes_setitem, /* sq_ass_item */ + (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */ 0, /* sq_ass_slice */ - (objobjproc)bytes_contains, /* sq_contains */ - (binaryfunc)bytes_iconcat, /* sq_inplace_concat */ - (ssizeargfunc)bytes_irepeat, /* sq_inplace_repeat */ + (objobjproc)bytearray_contains, /* sq_contains */ + (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */ + (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */ }; -static PyMappingMethods bytes_as_mapping = { - (lenfunc)bytes_length, - (binaryfunc)bytes_subscript, - (objobjargproc)bytes_ass_subscript, +static PyMappingMethods bytearray_as_mapping = { + (lenfunc)bytearray_length, + (binaryfunc)bytearray_subscript, + (objobjargproc)bytearray_ass_subscript, }; -static PyBufferProcs bytes_as_buffer = { - (getbufferproc)bytes_getbuffer, - (releasebufferproc)bytes_releasebuffer, +static PyBufferProcs bytearray_as_buffer = { + (getbufferproc)bytearray_getbuffer, + (releasebufferproc)bytearray_releasebuffer, }; static PyMethodDef -bytes_methods[] = { - {"__alloc__", (PyCFunction)bytes_alloc, METH_NOARGS, alloc_doc}, - {"__reduce__", (PyCFunction)bytes_reduce, METH_NOARGS, reduce_doc}, - {"append", (PyCFunction)bytes_append, METH_O, append__doc__}, +bytearray_methods[] = { + {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc}, + {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc}, + {"append", (PyCFunction)bytearray_append, METH_O, append__doc__}, {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS, _Py_capitalize__doc__}, {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__}, - {"count", (PyCFunction)bytes_count, METH_VARARGS, count__doc__}, - {"decode", (PyCFunction)bytes_decode, METH_VARARGS, decode_doc}, - {"endswith", (PyCFunction)bytes_endswith, METH_VARARGS, endswith__doc__}, + {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__}, + {"decode", (PyCFunction)bytearray_decode, METH_VARARGS, decode_doc}, + {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__}, {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS, expandtabs__doc__}, - {"extend", (PyCFunction)bytes_extend, METH_O, extend__doc__}, - {"find", (PyCFunction)bytes_find, METH_VARARGS, find__doc__}, - {"fromhex", (PyCFunction)bytes_fromhex, METH_VARARGS|METH_CLASS, + {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__}, + {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__}, + {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS, fromhex_doc}, - {"index", (PyCFunction)bytes_index, METH_VARARGS, index__doc__}, - {"insert", (PyCFunction)bytes_insert, METH_VARARGS, insert__doc__}, + {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__}, + {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__}, {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS, _Py_isalnum__doc__}, {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS, @@ -3075,38 +3075,38 @@ _Py_istitle__doc__}, {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS, _Py_isupper__doc__}, - {"join", (PyCFunction)bytes_join, METH_O, join_doc}, + {"join", (PyCFunction)bytearray_join, METH_O, join_doc}, {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__}, {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__}, - {"lstrip", (PyCFunction)bytes_lstrip, METH_VARARGS, lstrip__doc__}, - {"partition", (PyCFunction)bytes_partition, METH_O, partition__doc__}, - {"pop", (PyCFunction)bytes_pop, METH_VARARGS, pop__doc__}, - {"remove", (PyCFunction)bytes_remove, METH_O, remove__doc__}, - {"replace", (PyCFunction)bytes_replace, METH_VARARGS, replace__doc__}, - {"reverse", (PyCFunction)bytes_reverse, METH_NOARGS, reverse__doc__}, - {"rfind", (PyCFunction)bytes_rfind, METH_VARARGS, rfind__doc__}, - {"rindex", (PyCFunction)bytes_rindex, METH_VARARGS, rindex__doc__}, + {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__}, + {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__}, + {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__}, + {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__}, + {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__}, + {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__}, + {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__}, + {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__}, {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__}, - {"rpartition", (PyCFunction)bytes_rpartition, METH_O, rpartition__doc__}, - {"rsplit", (PyCFunction)bytes_rsplit, METH_VARARGS, rsplit__doc__}, - {"rstrip", (PyCFunction)bytes_rstrip, METH_VARARGS, rstrip__doc__}, - {"split", (PyCFunction)bytes_split, METH_VARARGS, split__doc__}, + {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__}, + {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__}, + {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__}, + {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__}, {"splitlines", (PyCFunction)stringlib_splitlines, METH_VARARGS, splitlines__doc__}, - {"startswith", (PyCFunction)bytes_startswith, METH_VARARGS , + {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS , startswith__doc__}, - {"strip", (PyCFunction)bytes_strip, METH_VARARGS, strip__doc__}, + {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__}, {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS, _Py_swapcase__doc__}, {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, - {"translate", (PyCFunction)bytes_translate, METH_VARARGS, + {"translate", (PyCFunction)bytearray_translate, METH_VARARGS, translate__doc__}, {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__}, {NULL} }; -PyDoc_STRVAR(bytes_doc, +PyDoc_STRVAR(bytearray_doc, "bytearray(iterable_of_ints) -> bytearray.\n\ bytearray(string, encoding[, errors]) -> bytearray.\n\ bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray.\n\ @@ -3123,37 +3123,37 @@ Construct a zero-initialized bytearray of the given length."); -static PyObject *bytes_iter(PyObject *seq); +static PyObject *bytearray_iter(PyObject *seq); PyTypeObject PyBytes_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "bytearray", sizeof(PyBytesObject), 0, - (destructor)bytes_dealloc, /* tp_dealloc */ + (destructor)bytearray_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ - (reprfunc)bytes_repr, /* tp_repr */ + (reprfunc)bytearray_repr, /* tp_repr */ 0, /* tp_as_number */ - &bytes_as_sequence, /* tp_as_sequence */ - &bytes_as_mapping, /* tp_as_mapping */ + &bytearray_as_sequence, /* tp_as_sequence */ + &bytearray_as_mapping, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ - bytes_str, /* tp_str */ + bytearray_str, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ - &bytes_as_buffer, /* tp_as_buffer */ + &bytearray_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - bytes_doc, /* tp_doc */ + bytearray_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ - (richcmpfunc)bytes_richcompare, /* tp_richcompare */ + (richcmpfunc)bytearray_richcompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ - bytes_iter, /* tp_iter */ + bytearray_iter, /* tp_iter */ 0, /* tp_iternext */ - bytes_methods, /* tp_methods */ + bytearray_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ @@ -3161,7 +3161,7 @@ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - (initproc)bytes_init, /* tp_init */ + (initproc)bytearray_init, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ PyObject_Del, /* tp_free */ @@ -3176,7 +3176,7 @@ } bytesiterobject; static void -bytesiter_dealloc(bytesiterobject *it) +bytearrayiter_dealloc(bytesiterobject *it) { _PyObject_GC_UNTRACK(it); Py_XDECREF(it->it_seq); @@ -3184,14 +3184,14 @@ } static int -bytesiter_traverse(bytesiterobject *it, visitproc visit, void *arg) +bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg) { Py_VISIT(it->it_seq); return 0; } static PyObject * -bytesiter_next(bytesiterobject *it) +bytearrayiter_next(bytesiterobject *it) { PyBytesObject *seq; PyObject *item; @@ -3216,7 +3216,7 @@ } static PyObject * -bytesiter_length_hint(bytesiterobject *it) +bytearrayiter_length_hint(bytesiterobject *it) { Py_ssize_t len = 0; if (it->it_seq) @@ -3228,7 +3228,7 @@ "Private method returning an estimate of len(list(it))."); static PyMethodDef bytesiter_methods[] = { - {"__length_hint__", (PyCFunction)bytesiter_length_hint, METH_NOARGS, + {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS, length_hint_doc}, {NULL, NULL} /* sentinel */ }; @@ -3239,7 +3239,7 @@ sizeof(bytesiterobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ - (destructor)bytesiter_dealloc, /* tp_dealloc */ + (destructor)bytearrayiter_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -3256,18 +3256,18 @@ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ - (traverseproc)bytesiter_traverse, /* tp_traverse */ + (traverseproc)bytearrayiter_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ - (iternextfunc)bytesiter_next, /* tp_iternext */ + (iternextfunc)bytearrayiter_next, /* tp_iternext */ bytesiter_methods, /* tp_methods */ 0, }; static PyObject * -bytes_iter(PyObject *seq) +bytearray_iter(PyObject *seq) { bytesiterobject *it; Modified: python/branches/py3k-grandrenaming/Objects/stringobject.c ============================================================================== --- python/branches/py3k-grandrenaming/Objects/stringobject.c (original) +++ python/branches/py3k-grandrenaming/Objects/stringobject.c Tue Jan 1 20:13:47 2008 @@ -349,7 +349,7 @@ } static void -string_dealloc(PyObject *op) +bytes_dealloc(PyObject *op) { Py_TYPE(op)->tp_free(op); } @@ -495,7 +495,7 @@ /* object api */ static Py_ssize_t -string_getsize(register PyObject *op) +bytes_getsize(register PyObject *op) { char *s; Py_ssize_t len; @@ -508,7 +508,7 @@ PyString_Size(register PyObject *op) { if (!PyString_Check(op)) - return string_getsize(op); + return bytes_getsize(op); return Py_SIZE(op); } @@ -649,31 +649,31 @@ } static PyObject * -string_repr(PyObject *op) +bytes_repr(PyObject *op) { return PyString_Repr(op, 1); } static PyObject * -string_str(PyObject *op) +bytes_str(PyObject *op) { if (Py_BytesWarningFlag) { if (PyErr_WarnEx(PyExc_BytesWarning, "str() on a bytes instance", 1)) return NULL; } - return string_repr(op); + return bytes_repr(op); } static Py_ssize_t -string_length(PyStringObject *a) +bytes_length(PyStringObject *a) { return Py_SIZE(a); } /* This is also used by PyString_Concat() */ static PyObject * -string_concat(PyObject *a, PyObject *b) +bytes_concat(PyObject *a, PyObject *b) { Py_ssize_t size; Py_buffer va, vb; @@ -721,7 +721,7 @@ } static PyObject * -string_repeat(register PyStringObject *a, register Py_ssize_t n) +bytes_repeat(register PyStringObject *a, register Py_ssize_t n) { register Py_ssize_t i; register Py_ssize_t j; @@ -774,7 +774,7 @@ } static int -string_contains(PyObject *self, PyObject *arg) +bytes_contains(PyObject *self, PyObject *arg) { Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError); if (ival == -1 && PyErr_Occurred()) { @@ -797,7 +797,7 @@ } static PyObject * -string_item(PyStringObject *a, register Py_ssize_t i) +bytes_item(PyStringObject *a, register Py_ssize_t i) { if (i < 0 || i >= Py_SIZE(a)) { PyErr_SetString(PyExc_IndexError, "string index out of range"); @@ -807,7 +807,7 @@ } static PyObject* -string_richcompare(PyStringObject *a, PyStringObject *b, int op) +bytes_richcompare(PyStringObject *a, PyStringObject *b, int op) { int c; Py_ssize_t len_a, len_b; @@ -878,7 +878,7 @@ } static long -string_hash(PyStringObject *a) +bytes_hash(PyStringObject *a) { register Py_ssize_t len; register unsigned char *p; @@ -899,7 +899,7 @@ } static PyObject* -string_subscript(PyStringObject* self, PyObject* item) +bytes_subscript(PyStringObject* self, PyObject* item) { if (PyIndex_Check(item)) { Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); @@ -966,31 +966,31 @@ } static int -string_buffer_getbuffer(PyStringObject *self, Py_buffer *view, int flags) +bytes_buffer_getbuffer(PyStringObject *self, Py_buffer *view, int flags) { return PyBuffer_FillInfo(view, (void *)self->ob_sval, Py_SIZE(self), 0, flags); } -static PySequenceMethods string_as_sequence = { - (lenfunc)string_length, /*sq_length*/ - (binaryfunc)string_concat, /*sq_concat*/ - (ssizeargfunc)string_repeat, /*sq_repeat*/ - (ssizeargfunc)string_item, /*sq_item*/ +static PySequenceMethods bytes_as_sequence = { + (lenfunc)bytes_length, /*sq_length*/ + (binaryfunc)bytes_concat, /*sq_concat*/ + (ssizeargfunc)bytes_repeat, /*sq_repeat*/ + (ssizeargfunc)bytes_item, /*sq_item*/ 0, /*sq_slice*/ 0, /*sq_ass_item*/ 0, /*sq_ass_slice*/ - (objobjproc)string_contains /*sq_contains*/ + (objobjproc)bytes_contains /*sq_contains*/ }; -static PyMappingMethods string_as_mapping = { - (lenfunc)string_length, - (binaryfunc)string_subscript, +static PyMappingMethods bytes_as_mapping = { + (lenfunc)bytes_length, + (binaryfunc)bytes_subscript, 0, }; -static PyBufferProcs string_as_buffer = { - (getbufferproc)string_buffer_getbuffer, +static PyBufferProcs bytes_as_buffer = { + (getbufferproc)bytes_buffer_getbuffer, NULL, }; @@ -1140,7 +1140,7 @@ If maxsplit is given, at most maxsplit splits are done."); static PyObject * -string_split(PyStringObject *self, PyObject *args) +bytes_split(PyStringObject *self, PyObject *args) { Py_ssize_t len = PyString_GET_SIZE(self), n, i, j; Py_ssize_t maxsplit = -1, count=0; @@ -1217,7 +1217,7 @@ found, returns B and two empty bytes objects."); static PyObject * -string_partition(PyStringObject *self, PyObject *sep_obj) +bytes_partition(PyStringObject *self, PyObject *sep_obj) { const char *sep; Py_ssize_t sep_len; @@ -1245,7 +1245,7 @@ bytes objects and B."); static PyObject * -string_rpartition(PyStringObject *self, PyObject *sep_obj) +bytes_rpartition(PyStringObject *self, PyObject *sep_obj) { const char *sep; Py_ssize_t sep_len; @@ -1359,7 +1359,7 @@ static PyObject * -string_rsplit(PyStringObject *self, PyObject *args) +bytes_rsplit(PyStringObject *self, PyObject *args) { Py_ssize_t len = PyString_GET_SIZE(self), n, i, j; Py_ssize_t maxsplit = -1, count=0; @@ -1431,7 +1431,7 @@ Example: b'.'.join([b'ab', b'pq', b'rs']) -> b'ab.pq.rs'."); static PyObject * -string_join(PyObject *self, PyObject *orig) +bytes_join(PyObject *self, PyObject *orig) { char *sep = PyString_AS_STRING(self); const Py_ssize_t seplen = PyString_GET_SIZE(self); @@ -1526,11 +1526,11 @@ { assert(sep != NULL && PyString_Check(sep)); assert(x != NULL); - return string_join(sep, x); + return bytes_join(sep, x); } Py_LOCAL_INLINE(void) -string_adjust_indices(Py_ssize_t *start, Py_ssize_t *end, Py_ssize_t len) +bytes_adjust_indices(Py_ssize_t *start, Py_ssize_t *end, Py_ssize_t len) { if (*end > len) *end = len; @@ -1545,7 +1545,7 @@ } Py_LOCAL_INLINE(Py_ssize_t) -string_find_internal(PyStringObject *self, PyObject *args, int dir) +bytes_find_internal(PyStringObject *self, PyObject *args, int dir) { PyObject *subobj; const char *sub; @@ -1596,9 +1596,9 @@ Return -1 on failure."); static PyObject * -string_find(PyStringObject *self, PyObject *args) +bytes_find(PyStringObject *self, PyObject *args) { - Py_ssize_t result = string_find_internal(self, args, +1); + Py_ssize_t result = bytes_find_internal(self, args, +1); if (result == -2) return NULL; return PyLong_FromSsize_t(result); @@ -1611,9 +1611,9 @@ Like B.find() but raise ValueError when the substring is not found."); static PyObject * -string_index(PyStringObject *self, PyObject *args) +bytes_index(PyStringObject *self, PyObject *args) { - Py_ssize_t result = string_find_internal(self, args, +1); + Py_ssize_t result = bytes_find_internal(self, args, +1); if (result == -2) return NULL; if (result == -1) { @@ -1635,9 +1635,9 @@ Return -1 on failure."); static PyObject * -string_rfind(PyStringObject *self, PyObject *args) +bytes_rfind(PyStringObject *self, PyObject *args) { - Py_ssize_t result = string_find_internal(self, args, -1); + Py_ssize_t result = bytes_find_internal(self, args, -1); if (result == -2) return NULL; return PyLong_FromSsize_t(result); @@ -1650,9 +1650,9 @@ Like B.rfind() but raise ValueError when the substring is not found."); static PyObject * -string_rindex(PyStringObject *self, PyObject *args) +bytes_rindex(PyStringObject *self, PyObject *args) { - Py_ssize_t result = string_find_internal(self, args, -1); + Py_ssize_t result = bytes_find_internal(self, args, -1); if (result == -2) return NULL; if (result == -1) { @@ -1756,7 +1756,7 @@ Strip leading and trailing bytes contained in the argument.\n\ If the argument is omitted, strip trailing ASCII whitespace."); static PyObject * -string_strip(PyStringObject *self, PyObject *args) +bytes_strip(PyStringObject *self, PyObject *args) { if (PyTuple_GET_SIZE(args) == 0) return do_strip(self, BOTHSTRIP); /* Common case */ @@ -1771,7 +1771,7 @@ Strip leading bytes contained in the argument.\n\ If the argument is omitted, strip leading ASCII whitespace."); static PyObject * -string_lstrip(PyStringObject *self, PyObject *args) +bytes_lstrip(PyStringObject *self, PyObject *args) { if (PyTuple_GET_SIZE(args) == 0) return do_strip(self, LEFTSTRIP); /* Common case */ @@ -1786,7 +1786,7 @@ Strip trailing bytes contained in the argument.\n\ If the argument is omitted, strip trailing ASCII whitespace."); static PyObject * -string_rstrip(PyStringObject *self, PyObject *args) +bytes_rstrip(PyStringObject *self, PyObject *args) { if (PyTuple_GET_SIZE(args) == 0) return do_strip(self, RIGHTSTRIP); /* Common case */ @@ -1803,7 +1803,7 @@ as in slice notation."); static PyObject * -string_count(PyStringObject *self, PyObject *args) +bytes_count(PyStringObject *self, PyObject *args) { PyObject *sub_obj; const char *str = PyString_AS_STRING(self), *sub; @@ -1821,7 +1821,7 @@ else if (PyObject_AsCharBuffer(sub_obj, &sub, &sub_len)) return NULL; - string_adjust_indices(&start, &end, PyString_GET_SIZE(self)); + bytes_adjust_indices(&start, &end, PyString_GET_SIZE(self)); return PyLong_FromSsize_t( stringlib_count(str + start, end - start, sub, sub_len) @@ -1838,7 +1838,7 @@ table, which must be a bytes object of length 256."); static PyObject * -string_translate(PyStringObject *self, PyObject *args) +bytes_translate(PyStringObject *self, PyObject *args) { register char *input, *output; const char *table; @@ -1979,7 +1979,7 @@ } Py_LOCAL(Py_ssize_t) -findstring(const char *target, Py_ssize_t target_len, +findbytes(const char *target, Py_ssize_t target_len, const char *pattern, Py_ssize_t pattern_len, Py_ssize_t start, Py_ssize_t end, @@ -2017,7 +2017,7 @@ } Py_LOCAL_INLINE(Py_ssize_t) -countstring(const char *target, Py_ssize_t target_len, +countbytes(const char *target, Py_ssize_t target_len, const char *pattern, Py_ssize_t pattern_len, Py_ssize_t start, Py_ssize_t end, @@ -2174,7 +2174,7 @@ /* len(self)>=1, len(from)>=2, to="", maxcount>=1 */ Py_LOCAL(PyStringObject *) -replace_delete_substring(PyStringObject *self, +replace_delete_subbytes(PyStringObject *self, const char *from_s, Py_ssize_t from_len, Py_ssize_t maxcount) { char *self_s, *result_s; @@ -2186,7 +2186,7 @@ self_len = PyString_GET_SIZE(self); self_s = PyString_AS_STRING(self); - count = countstring(self_s, self_len, + count = countbytes(self_s, self_len, from_s, from_len, 0, self_len, 1, maxcount); @@ -2208,7 +2208,7 @@ start = self_s; end = self_s + self_len; while (count-- > 0) { - offset = findstring(start, end-start, + offset = findbytes(start, end-start, from_s, from_len, 0, end-start, FORWARD); if (offset == -1) @@ -2286,7 +2286,7 @@ self_s = PyString_AS_STRING(self); self_len = PyString_GET_SIZE(self); - offset = findstring(self_s, self_len, + offset = findbytes(self_s, self_len, from_s, from_len, 0, self_len, FORWARD); if (offset == -1) { @@ -2308,7 +2308,7 @@ end = result_s + self_len; while ( --maxcount > 0) { - offset = findstring(start, end-start, + offset = findbytes(start, end-start, from_s, from_len, 0, end-start, FORWARD); if (offset==-1) @@ -2391,7 +2391,7 @@ /* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */ Py_LOCAL(PyStringObject *) -replace_substring(PyStringObject *self, +replace_subbytes(PyStringObject *self, const char *from_s, Py_ssize_t from_len, const char *to_s, Py_ssize_t to_len, Py_ssize_t maxcount) { @@ -2404,7 +2404,7 @@ self_s = PyString_AS_STRING(self); self_len = PyString_GET_SIZE(self); - count = countstring(self_s, self_len, + count = countbytes(self_s, self_len, from_s, from_len, 0, self_len, FORWARD, maxcount); if (count == 0) { @@ -2435,7 +2435,7 @@ start = self_s; end = self_s + self_len; while (count-- > 0) { - offset = findstring(start, end-start, + offset = findbytes(start, end-start, from_s, from_len, 0, end-start, FORWARD); if (offset == -1) @@ -2503,7 +2503,7 @@ return replace_delete_single_character( self, from_s[0], maxcount); } else { - return replace_delete_substring(self, from_s, + return replace_delete_subbytes(self, from_s, from_len, maxcount); } } @@ -2530,7 +2530,7 @@ to_s, to_len, maxcount); } else { /* len('from')>=2, len('to')>=1 */ - return replace_substring(self, from_s, from_len, to_s, to_len, + return replace_subbytes(self, from_s, from_len, to_s, to_len, maxcount); } } @@ -2543,7 +2543,7 @@ given, only the first count occurrences are replaced."); static PyObject * -string_replace(PyStringObject *self, PyObject *args) +bytes_replace(PyStringObject *self, PyObject *args) { Py_ssize_t count = -1; PyObject *from, *to; @@ -2595,7 +2595,7 @@ return -1; str = PyString_AS_STRING(self); - string_adjust_indices(&start, &end, len); + bytes_adjust_indices(&start, &end, len); if (direction < 0) { /* startswith */ @@ -2624,7 +2624,7 @@ prefix can also be a tuple of strings to try."); static PyObject * -string_startswith(PyStringObject *self, PyObject *args) +bytes_startswith(PyStringObject *self, PyObject *args) { Py_ssize_t start = 0; Py_ssize_t end = PY_SSIZE_T_MAX; @@ -2665,7 +2665,7 @@ suffix can also be a tuple of strings to try."); static PyObject * -string_endswith(PyStringObject *self, PyObject *args) +bytes_endswith(PyStringObject *self, PyObject *args) { Py_ssize_t start = 0; Py_ssize_t end = PY_SSIZE_T_MAX; @@ -2708,7 +2708,7 @@ able to handle UnicodeDecodeErrors."); static PyObject * -string_decode(PyObject *self, PyObject *args) +bytes_decode(PyObject *self, PyObject *args) { const char *encoding = NULL; const char *errors = NULL; @@ -2745,7 +2745,7 @@ } static PyObject * -string_fromhex(PyObject *cls, PyObject *args) +bytes_fromhex(PyObject *cls, PyObject *args) { PyObject *newstring, *hexobj; char *buf; @@ -2790,28 +2790,28 @@ static PyObject * -string_getnewargs(PyStringObject *v) +bytes_getnewargs(PyStringObject *v) { return Py_BuildValue("(s#)", v->ob_sval, Py_SIZE(v)); } static PyMethodDef -string_methods[] = { - {"__getnewargs__", (PyCFunction)string_getnewargs, METH_NOARGS}, +bytes_methods[] = { + {"__getnewargs__", (PyCFunction)bytes_getnewargs, METH_NOARGS}, {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS, _Py_capitalize__doc__}, {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__}, - {"count", (PyCFunction)string_count, METH_VARARGS, count__doc__}, - {"decode", (PyCFunction)string_decode, METH_VARARGS, decode__doc__}, - {"endswith", (PyCFunction)string_endswith, METH_VARARGS, + {"count", (PyCFunction)bytes_count, METH_VARARGS, count__doc__}, + {"decode", (PyCFunction)bytes_decode, METH_VARARGS, decode__doc__}, + {"endswith", (PyCFunction)bytes_endswith, METH_VARARGS, endswith__doc__}, {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS, expandtabs__doc__}, - {"find", (PyCFunction)string_find, METH_VARARGS, find__doc__}, - {"fromhex", (PyCFunction)string_fromhex, METH_VARARGS|METH_CLASS, + {"find", (PyCFunction)bytes_find, METH_VARARGS, find__doc__}, + {"fromhex", (PyCFunction)bytes_fromhex, METH_VARARGS|METH_CLASS, fromhex_doc}, - {"index", (PyCFunction)string_index, METH_VARARGS, index__doc__}, + {"index", (PyCFunction)bytes_index, METH_VARARGS, index__doc__}, {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS, _Py_isalnum__doc__}, {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS, @@ -2826,29 +2826,29 @@ _Py_istitle__doc__}, {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS, _Py_isupper__doc__}, - {"join", (PyCFunction)string_join, METH_O, join__doc__}, + {"join", (PyCFunction)bytes_join, METH_O, join__doc__}, {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__}, {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__}, - {"lstrip", (PyCFunction)string_lstrip, METH_VARARGS, lstrip__doc__}, - {"partition", (PyCFunction)string_partition, METH_O, partition__doc__}, - {"replace", (PyCFunction)string_replace, METH_VARARGS, replace__doc__}, - {"rfind", (PyCFunction)string_rfind, METH_VARARGS, rfind__doc__}, - {"rindex", (PyCFunction)string_rindex, METH_VARARGS, rindex__doc__}, + {"lstrip", (PyCFunction)bytes_lstrip, METH_VARARGS, lstrip__doc__}, + {"partition", (PyCFunction)bytes_partition, METH_O, partition__doc__}, + {"replace", (PyCFunction)bytes_replace, METH_VARARGS, replace__doc__}, + {"rfind", (PyCFunction)bytes_rfind, METH_VARARGS, rfind__doc__}, + {"rindex", (PyCFunction)bytes_rindex, METH_VARARGS, rindex__doc__}, {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__}, - {"rpartition", (PyCFunction)string_rpartition, METH_O, + {"rpartition", (PyCFunction)bytes_rpartition, METH_O, rpartition__doc__}, - {"rsplit", (PyCFunction)string_rsplit, METH_VARARGS, rsplit__doc__}, - {"rstrip", (PyCFunction)string_rstrip, METH_VARARGS, rstrip__doc__}, - {"split", (PyCFunction)string_split, METH_VARARGS, split__doc__}, + {"rsplit", (PyCFunction)bytes_rsplit, METH_VARARGS, rsplit__doc__}, + {"rstrip", (PyCFunction)bytes_rstrip, METH_VARARGS, rstrip__doc__}, + {"split", (PyCFunction)bytes_split, METH_VARARGS, split__doc__}, {"splitlines", (PyCFunction)stringlib_splitlines, METH_VARARGS, splitlines__doc__}, - {"startswith", (PyCFunction)string_startswith, METH_VARARGS, + {"startswith", (PyCFunction)bytes_startswith, METH_VARARGS, startswith__doc__}, - {"strip", (PyCFunction)string_strip, METH_VARARGS, strip__doc__}, + {"strip", (PyCFunction)bytes_strip, METH_VARARGS, strip__doc__}, {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS, _Py_swapcase__doc__}, {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, - {"translate", (PyCFunction)string_translate, METH_VARARGS, + {"translate", (PyCFunction)bytes_translate, METH_VARARGS, translate__doc__}, {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__}, @@ -2859,7 +2859,7 @@ str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds); static PyObject * -string_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *x = NULL, *it; const char *encoding = NULL; @@ -3014,7 +3014,7 @@ Py_ssize_t n; assert(PyType_IsSubtype(type, &PyString_Type)); - tmp = string_new(&PyString_Type, args, kwds); + tmp = bytes_new(&PyString_Type, args, kwds); if (tmp == NULL) return NULL; assert(PyString_CheckExact(tmp)); @@ -3030,7 +3030,7 @@ return pnew; } -PyDoc_STRVAR(string_doc, +PyDoc_STRVAR(bytes_doc, "bytes(iterable_of_ints) -> bytes.\n\ bytes(string, encoding[, errors]) -> bytes\n\ bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer.\n\ @@ -3042,38 +3042,38 @@ - a bytes or a buffer object\n\ - any object implementing the buffer API."); -static PyObject *str_iter(PyObject *seq); +static PyObject *bytes_iter(PyObject *seq); PyTypeObject PyString_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "bytes", sizeof(PyStringObject), sizeof(char), - string_dealloc, /* tp_dealloc */ + bytes_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ - (reprfunc)string_repr, /* tp_repr */ + (reprfunc)bytes_repr, /* tp_repr */ 0, /* tp_as_number */ - &string_as_sequence, /* tp_as_sequence */ - &string_as_mapping, /* tp_as_mapping */ - (hashfunc)string_hash, /* tp_hash */ + &bytes_as_sequence, /* tp_as_sequence */ + &bytes_as_mapping, /* tp_as_mapping */ + (hashfunc)bytes_hash, /* tp_hash */ 0, /* tp_call */ - string_str, /* tp_str */ + bytes_str, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ - &string_as_buffer, /* tp_as_buffer */ + &bytes_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_STRING_SUBCLASS, /* tp_flags */ - string_doc, /* tp_doc */ + bytes_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ - (richcmpfunc)string_richcompare, /* tp_richcompare */ + (richcmpfunc)bytes_richcompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ - str_iter, /* tp_iter */ + bytes_iter, /* tp_iter */ 0, /* tp_iternext */ - string_methods, /* tp_methods */ + bytes_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ &PyBaseObject_Type, /* tp_base */ @@ -3083,7 +3083,7 @@ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - string_new, /* tp_new */ + bytes_new, /* tp_new */ PyObject_Del, /* tp_free */ }; @@ -3099,7 +3099,7 @@ *pv = NULL; return; } - v = string_concat(*pv, w); + v = bytes_concat(*pv, w); Py_DECREF(*pv); *pv = v; } @@ -3411,7 +3411,7 @@ }; static PyObject * -str_iter(PyObject *seq) +bytes_iter(PyObject *seq) { striterobject *it; From python-3000-checkins at python.org Tue Jan 1 20:14:45 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Tue, 1 Jan 2008 20:14:45 +0100 (CET) Subject: [Python-3000-checkins] r59650 - in python/branches/py3k-grandrenaming: Include/bytesobject.h Include/pythonrun.h Modules/_bsddb.c Modules/_ctypes/_ctypes.c Modules/_ctypes/cfield.c Modules/_sqlite/cursor.c Modules/_ssl.c Modules/_struct.c Modules/arraymodule.c Modules/dbmmodule.c Modules/gdbmmodule.c Modules/mmapmodule.c Modules/ossaudiodev.c Modules/pyexpat.c Modules/zipimport.c Modules/zlibmodule.c Objects/bytesobject.c Objects/longobject.c Objects/memoryobject.c Objects/object.c Objects/stringobject.c Objects/unicodeobject.c PC/_winreg.c Parser/tokenizer.c Python/bltinmodule.c Python/codecs.c Python/getargs.c Python/import.c Python/mactoolboxglue.c Python/marshal.c Python/pythonrun.c Message-ID: <20080101191445.7AEA81E4002@bag.python.org> Author: christian.heimes Date: Tue Jan 1 20:14:44 2008 New Revision: 59650 Modified: python/branches/py3k-grandrenaming/Include/bytesobject.h python/branches/py3k-grandrenaming/Include/pythonrun.h python/branches/py3k-grandrenaming/Modules/_bsddb.c python/branches/py3k-grandrenaming/Modules/_ctypes/_ctypes.c python/branches/py3k-grandrenaming/Modules/_ctypes/cfield.c python/branches/py3k-grandrenaming/Modules/_sqlite/cursor.c python/branches/py3k-grandrenaming/Modules/_ssl.c python/branches/py3k-grandrenaming/Modules/_struct.c python/branches/py3k-grandrenaming/Modules/arraymodule.c python/branches/py3k-grandrenaming/Modules/dbmmodule.c python/branches/py3k-grandrenaming/Modules/gdbmmodule.c python/branches/py3k-grandrenaming/Modules/mmapmodule.c python/branches/py3k-grandrenaming/Modules/ossaudiodev.c python/branches/py3k-grandrenaming/Modules/pyexpat.c python/branches/py3k-grandrenaming/Modules/zipimport.c python/branches/py3k-grandrenaming/Modules/zlibmodule.c python/branches/py3k-grandrenaming/Objects/bytesobject.c python/branches/py3k-grandrenaming/Objects/longobject.c python/branches/py3k-grandrenaming/Objects/memoryobject.c python/branches/py3k-grandrenaming/Objects/object.c python/branches/py3k-grandrenaming/Objects/stringobject.c python/branches/py3k-grandrenaming/Objects/unicodeobject.c python/branches/py3k-grandrenaming/PC/_winreg.c python/branches/py3k-grandrenaming/Parser/tokenizer.c python/branches/py3k-grandrenaming/Python/bltinmodule.c python/branches/py3k-grandrenaming/Python/codecs.c python/branches/py3k-grandrenaming/Python/getargs.c python/branches/py3k-grandrenaming/Python/import.c python/branches/py3k-grandrenaming/Python/mactoolboxglue.c python/branches/py3k-grandrenaming/Python/marshal.c python/branches/py3k-grandrenaming/Python/pythonrun.c Log: find -name '*.c' -or -name '*.h' -or -name '*.rst' | xargs sed -i s/PyBytes_/PyByteArray_/g Modified: python/branches/py3k-grandrenaming/Include/bytesobject.h ============================================================================== --- python/branches/py3k-grandrenaming/Include/bytesobject.h (original) +++ python/branches/py3k-grandrenaming/Include/bytesobject.h Tue Jan 1 20:14:44 2008 @@ -28,24 +28,24 @@ } PyBytesObject; /* Type object */ -PyAPI_DATA(PyTypeObject) PyBytes_Type; +PyAPI_DATA(PyTypeObject) PyByteArray_Type; PyAPI_DATA(PyTypeObject) PyBytesIter_Type; /* Type check macros */ -#define PyBytes_Check(self) PyObject_TypeCheck(self, &PyBytes_Type) -#define PyBytes_CheckExact(self) (Py_TYPE(self) == &PyBytes_Type) +#define PyByteArray_Check(self) PyObject_TypeCheck(self, &PyByteArray_Type) +#define PyByteArray_CheckExact(self) (Py_TYPE(self) == &PyByteArray_Type) /* Direct API functions */ -PyAPI_FUNC(PyObject *) PyBytes_FromObject(PyObject *); -PyAPI_FUNC(PyObject *) PyBytes_Concat(PyObject *, PyObject *); -PyAPI_FUNC(PyObject *) PyBytes_FromStringAndSize(const char *, Py_ssize_t); -PyAPI_FUNC(Py_ssize_t) PyBytes_Size(PyObject *); -PyAPI_FUNC(char *) PyBytes_AsString(PyObject *); -PyAPI_FUNC(int) PyBytes_Resize(PyObject *, Py_ssize_t); +PyAPI_FUNC(PyObject *) PyByteArray_FromObject(PyObject *); +PyAPI_FUNC(PyObject *) PyByteArray_Concat(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyByteArray_FromStringAndSize(const char *, Py_ssize_t); +PyAPI_FUNC(Py_ssize_t) PyByteArray_Size(PyObject *); +PyAPI_FUNC(char *) PyByteArray_AsString(PyObject *); +PyAPI_FUNC(int) PyByteArray_Resize(PyObject *, Py_ssize_t); /* Macros, trading safety for speed */ -#define PyBytes_AS_STRING(self) (assert(PyBytes_Check(self)),((PyBytesObject *)(self))->ob_bytes) -#define PyBytes_GET_SIZE(self) (assert(PyBytes_Check(self)),Py_SIZE(self)) +#define PyByteArray_AS_STRING(self) (assert(PyByteArray_Check(self)),((PyBytesObject *)(self))->ob_bytes) +#define PyByteArray_GET_SIZE(self) (assert(PyByteArray_Check(self)),Py_SIZE(self)) #ifdef __cplusplus } Modified: python/branches/py3k-grandrenaming/Include/pythonrun.h ============================================================================== --- python/branches/py3k-grandrenaming/Include/pythonrun.h (original) +++ python/branches/py3k-grandrenaming/Include/pythonrun.h Tue Jan 1 20:14:44 2008 @@ -126,7 +126,7 @@ PyAPI_FUNC(void) _PyImportHooks_Init(void); PyAPI_FUNC(int) _PyFrame_Init(void); PyAPI_FUNC(void) _PyFloat_Init(void); -PyAPI_FUNC(int) PyBytes_Init(void); +PyAPI_FUNC(int) PyByteArray_Init(void); /* Various internal finalizers */ PyAPI_FUNC(void) _PyExc_Fini(void); @@ -138,7 +138,7 @@ PyAPI_FUNC(void) PyList_Fini(void); PyAPI_FUNC(void) PySet_Fini(void); PyAPI_FUNC(void) PyString_Fini(void); -PyAPI_FUNC(void) PyBytes_Fini(void); +PyAPI_FUNC(void) PyByteArray_Fini(void); PyAPI_FUNC(void) PyFloat_Fini(void); PyAPI_FUNC(void) PyOS_FiniInterrupts(void); Modified: python/branches/py3k-grandrenaming/Modules/_bsddb.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/_bsddb.c (original) +++ python/branches/py3k-grandrenaming/Modules/_bsddb.c Tue Jan 1 20:14:44 2008 @@ -1171,14 +1171,14 @@ else if (PyLong_Check(result)) { retval = PyLong_AsLong(result); } - else if (PyBytes_Check(result) || PyString_Check(result)) { + else if (PyByteArray_Check(result) || PyString_Check(result)) { char* data; Py_ssize_t size; CLEAR_DBT(*secKey); size = Py_SIZE(result); - if (PyBytes_Check(result)) - data = PyBytes_AS_STRING(result); + if (PyByteArray_Check(result)) + data = PyByteArray_AS_STRING(result); else data = PyString_AS_STRING(result); secKey->flags = DB_DBT_APPMALLOC; /* DB will free */ Modified: python/branches/py3k-grandrenaming/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k-grandrenaming/Modules/_ctypes/_ctypes.c Tue Jan 1 20:14:44 2008 @@ -1284,7 +1284,7 @@ return (PyObject *)parg; } /* bytes */ - if (PyBytes_Check(value)) { + if (PyByteArray_Check(value)) { PyCArgObject *parg; struct fielddesc *fd = getentry("z"); Modified: python/branches/py3k-grandrenaming/Modules/_ctypes/cfield.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/_ctypes/cfield.c (original) +++ python/branches/py3k-grandrenaming/Modules/_ctypes/cfield.c Tue Jan 1 20:14:44 2008 @@ -1174,8 +1174,8 @@ *(char *)ptr = PyString_AS_STRING(value)[0]; _RET(value); } - if (PyBytes_Check(value) && PyBytes_GET_SIZE(value) == 1) { - *(char *)ptr = PyBytes_AS_STRING(value)[0]; + if (PyByteArray_Check(value) && PyByteArray_GET_SIZE(value) == 1) { + *(char *)ptr = PyByteArray_AS_STRING(value)[0]; _RET(value); } if (PyLong_Check(value)) Modified: python/branches/py3k-grandrenaming/Modules/_sqlite/cursor.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/_sqlite/cursor.c (original) +++ python/branches/py3k-grandrenaming/Modules/_sqlite/cursor.c Tue Jan 1 20:14:44 2008 @@ -367,8 +367,8 @@ } } else if (self->connection->text_factory == (PyObject*)&PyString_Type) { converted = PyString_FromString(val_str); - } else if (self->connection->text_factory == (PyObject*)&PyBytes_Type) { - converted = PyBytes_FromStringAndSize(val_str, strlen(val_str)); + } else if (self->connection->text_factory == (PyObject*)&PyByteArray_Type) { + converted = PyByteArray_FromStringAndSize(val_str, strlen(val_str)); } else { converted = PyObject_CallFunction(self->connection->text_factory, "y", val_str); } Modified: python/branches/py3k-grandrenaming/Modules/_ssl.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/_ssl.c (original) +++ python/branches/py3k-grandrenaming/Modules/_ssl.c Tue Jan 1 20:14:44 2008 @@ -1263,16 +1263,16 @@ if (!PyArg_ParseTuple(args, "|Oi:read", &buf, &count)) return NULL; if ((buf == NULL) || (buf == Py_None)) { - if (!(buf = PyBytes_FromStringAndSize((char *) 0, len))) + if (!(buf = PyByteArray_FromStringAndSize((char *) 0, len))) return NULL; } else if (PyLong_Check(buf)) { len = PyLong_AS_LONG(buf); - if (!(buf = PyBytes_FromStringAndSize((char *) 0, len))) + if (!(buf = PyByteArray_FromStringAndSize((char *) 0, len))) return NULL; } else { - if (!PyBytes_Check(buf)) + if (!PyByteArray_Check(buf)) return NULL; - len = PyBytes_Size(buf); + len = PyByteArray_Size(buf); if ((count > 0) && (count <= len)) len = count; buf_passed = 1; @@ -1313,7 +1313,7 @@ do { err = 0; PySSL_BEGIN_ALLOW_THREADS - count = SSL_read(self->ssl, PyBytes_AsString(buf), len); + count = SSL_read(self->ssl, PyByteArray_AsString(buf), len); err = SSL_get_error(self->ssl, count); PySSL_END_ALLOW_THREADS if(PyErr_CheckSignals()) { @@ -1357,7 +1357,7 @@ done: if (!buf_passed) { PyObject *res = PyString_FromStringAndSize( - PyBytes_AS_STRING(buf), count); + PyByteArray_AS_STRING(buf), count); Py_DECREF(buf); return res; } else { Modified: python/branches/py3k-grandrenaming/Modules/_struct.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/_struct.c (original) +++ python/branches/py3k-grandrenaming/Modules/_struct.c Tue Jan 1 20:14:44 2008 @@ -1629,7 +1629,7 @@ return -1; } isstring = PyString_Check(v); - if (!isstring && !PyBytes_Check(v)) { + if (!isstring && !PyByteArray_Check(v)) { PyErr_SetString(StructError, "argument for 's' must be a string"); return -1; @@ -1639,8 +1639,8 @@ p = PyString_AS_STRING(v); } else { - n = PyBytes_GET_SIZE(v); - p = PyBytes_AS_STRING(v); + n = PyByteArray_GET_SIZE(v); + p = PyByteArray_AS_STRING(v); } if (n > code->size) n = code->size; @@ -1655,7 +1655,7 @@ return -1; } isstring = PyString_Check(v); - if (!isstring && !PyBytes_Check(v)) { + if (!isstring && !PyByteArray_Check(v)) { PyErr_SetString(StructError, "argument for 'p' must be a string"); return -1; @@ -1665,8 +1665,8 @@ p = PyString_AS_STRING(v); } else { - n = PyBytes_GET_SIZE(v); - p = PyBytes_AS_STRING(v); + n = PyByteArray_GET_SIZE(v); + p = PyByteArray_AS_STRING(v); } if (n > (code->size - 1)) n = code->size - 1; Modified: python/branches/py3k-grandrenaming/Modules/arraymodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/arraymodule.c (original) +++ python/branches/py3k-grandrenaming/Modules/arraymodule.c Tue Jan 1 20:14:44 2008 @@ -1860,7 +1860,7 @@ return NULL; if (!(initial == NULL || PyList_Check(initial) - || PyBytes_Check(initial) + || PyByteArray_Check(initial) || PyString_Check(initial) || PyTuple_Check(initial) || ((c=='u') && PyUnicode_Check(initial)))) { @@ -1906,7 +1906,7 @@ Py_DECREF(v); } } - else if (initial != NULL && (PyBytes_Check(initial) || + else if (initial != NULL && (PyByteArray_Check(initial) || PyString_Check(initial))) { PyObject *t_initial, *v; t_initial = PyTuple_Pack(1, initial); Modified: python/branches/py3k-grandrenaming/Modules/dbmmodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/dbmmodule.c (original) +++ python/branches/py3k-grandrenaming/Modules/dbmmodule.c Tue Jan 1 20:14:44 2008 @@ -111,7 +111,7 @@ PyErr_SetString(DbmError, ""); return NULL; } - return PyBytes_FromStringAndSize(drec.dptr, drec.dsize); + return PyByteArray_FromStringAndSize(drec.dptr, drec.dsize); } static int @@ -188,7 +188,7 @@ return NULL; for (key = dbm_firstkey(dp->di_dbm); key.dptr; key = dbm_nextkey(dp->di_dbm)) { - item = PyBytes_FromStringAndSize(key.dptr, key.dsize); + item = PyByteArray_FromStringAndSize(key.dptr, key.dsize); if (item == NULL) { Py_DECREF(v); return NULL; @@ -260,7 +260,7 @@ check_dbmobject_open(dp); val = dbm_fetch(dp->di_dbm, key); if (val.dptr != NULL) - return PyBytes_FromStringAndSize(val.dptr, val.dsize); + return PyByteArray_FromStringAndSize(val.dptr, val.dsize); else { Py_INCREF(defvalue); return defvalue; @@ -283,9 +283,9 @@ check_dbmobject_open(dp); val = dbm_fetch(dp->di_dbm, key); if (val.dptr != NULL) - return PyBytes_FromStringAndSize(val.dptr, val.dsize); + return PyByteArray_FromStringAndSize(val.dptr, val.dsize); if (defvalue == NULL) { - defvalue = PyBytes_FromStringAndSize(NULL, 0); + defvalue = PyByteArray_FromStringAndSize(NULL, 0); if (defvalue == NULL) return NULL; val.dptr = NULL; Modified: python/branches/py3k-grandrenaming/Modules/gdbmmodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/gdbmmodule.c (original) +++ python/branches/py3k-grandrenaming/Modules/gdbmmodule.c Tue Jan 1 20:14:44 2008 @@ -130,7 +130,7 @@ PyErr_SetObject(PyExc_KeyError, key); return NULL; } - v = PyBytes_FromStringAndSize(drec.dptr, drec.dsize); + v = PyByteArray_FromStringAndSize(drec.dptr, drec.dsize); free(drec.dptr); return v; } @@ -220,7 +220,7 @@ key = gdbm_firstkey(dp->di_dbm); while (key.dptr) { - item = PyBytes_FromStringAndSize(key.dptr, key.dsize); + item = PyByteArray_FromStringAndSize(key.dptr, key.dsize); if (item == NULL) { free(key.dptr); Py_DECREF(v); @@ -291,7 +291,7 @@ check_dbmobject_open(dp); key = gdbm_firstkey(dp->di_dbm); if (key.dptr) { - v = PyBytes_FromStringAndSize(key.dptr, key.dsize); + v = PyByteArray_FromStringAndSize(key.dptr, key.dsize); free(key.dptr); return v; } @@ -323,7 +323,7 @@ check_dbmobject_open(dp); nextkey = gdbm_nextkey(dp->di_dbm, key); if (nextkey.dptr) { - v = PyBytes_FromStringAndSize(nextkey.dptr, nextkey.dsize); + v = PyByteArray_FromStringAndSize(nextkey.dptr, nextkey.dsize); free(nextkey.dptr); return v; } Modified: python/branches/py3k-grandrenaming/Modules/mmapmodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/mmapmodule.c (original) +++ python/branches/py3k-grandrenaming/Modules/mmapmodule.c Tue Jan 1 20:14:44 2008 @@ -228,7 +228,7 @@ else ++eol; /* we're interested in the position after the newline. */ - result = PyBytes_FromStringAndSize(start, (eol - start)); + result = PyByteArray_FromStringAndSize(start, (eol - start)); self->pos += (eol - start); return result; } @@ -248,7 +248,7 @@ if ((self->pos + num_bytes) > self->size) { num_bytes -= (self->pos+num_bytes) - self->size; } - result = PyBytes_FromStringAndSize(self->data+self->pos, num_bytes); + result = PyByteArray_FromStringAndSize(self->data+self->pos, num_bytes); self->pos += num_bytes; return result; } @@ -658,7 +658,7 @@ PyErr_SetString(PyExc_IndexError, "mmap index out of range"); return NULL; } - return PyBytes_FromStringAndSize(self->data + i, 1); + return PyByteArray_FromStringAndSize(self->data + i, 1); } static PyObject * @@ -748,14 +748,14 @@ "mmap object doesn't support item deletion"); return -1; } - if (! (PyBytes_Check(v) && PyBytes_Size(v)==1) ) { + if (! (PyByteArray_Check(v) && PyByteArray_Size(v)==1) ) { PyErr_SetString(PyExc_IndexError, "mmap assignment must be length-1 bytes()"); return -1; } if (!is_writable(self)) return -1; - buf = PyBytes_AsString(v); + buf = PyByteArray_AsString(v); self->data[i] = buf[0]; return 0; } Modified: python/branches/py3k-grandrenaming/Modules/ossaudiodev.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/ossaudiodev.c (original) +++ python/branches/py3k-grandrenaming/Modules/ossaudiodev.c Tue Jan 1 20:14:44 2008 @@ -366,10 +366,10 @@ if (!PyArg_ParseTuple(args, "i:read", &size)) return NULL; - rv = PyBytes_FromStringAndSize(NULL, size); + rv = PyByteArray_FromStringAndSize(NULL, size); if (rv == NULL) return NULL; - cp = PyBytes_AS_STRING(rv); + cp = PyByteArray_AS_STRING(rv); Py_BEGIN_ALLOW_THREADS count = read(self->fd, cp, size); @@ -381,7 +381,7 @@ return NULL; } self->icount += count; - PyBytes_Resize(rv, count); + PyByteArray_Resize(rv, count); return rv; } Modified: python/branches/py3k-grandrenaming/Modules/pyexpat.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/pyexpat.c (original) +++ python/branches/py3k-grandrenaming/Modules/pyexpat.c Tue Jan 1 20:14:44 2008 @@ -866,8 +866,8 @@ if (PyString_Check(str)) ptr = PyString_AS_STRING(str); - else if (PyBytes_Check(str)) - ptr = PyBytes_AS_STRING(str); + else if (PyByteArray_Check(str)) + ptr = PyByteArray_AS_STRING(str); else { PyErr_Format(PyExc_TypeError, "read() did not return a bytes object (type=%.400s)", Modified: python/branches/py3k-grandrenaming/Modules/zipimport.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/zipimport.c (original) +++ python/branches/py3k-grandrenaming/Modules/zipimport.c Tue Jan 1 20:14:44 2008 @@ -467,7 +467,7 @@ toc_entry = PyDict_GetItemString(self->files, path); if (toc_entry != NULL) { PyObject *bytes = get_data(PyUnicode_AsString(self->archive), toc_entry); - PyObject *res = PyUnicode_FromString(PyBytes_AsString(bytes)); + PyObject *res = PyUnicode_FromString(PyByteArray_AsString(bytes)); Py_XDECREF(bytes); return res; } @@ -829,13 +829,13 @@ bytes_size = compress == 0 ? data_size : data_size + 1; if (bytes_size == 0) bytes_size++; - raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size); + raw_data = PyByteArray_FromStringAndSize((char *)NULL, bytes_size); if (raw_data == NULL) { fclose(fp); return NULL; } - buf = PyBytes_AsString(raw_data); + buf = PyByteArray_AsString(raw_data); err = fseek(fp, file_offset, 0); if (err == 0) @@ -855,7 +855,7 @@ buf[data_size] = '\0'; if (compress == 0) { /* data is not compressed */ - data = PyBytes_FromStringAndSize(buf, data_size); + data = PyByteArray_FromStringAndSize(buf, data_size); Py_DECREF(raw_data); return data; } @@ -896,8 +896,8 @@ unmarshal_code(char *pathname, PyObject *data, time_t mtime) { PyObject *code; - char *buf = PyBytes_AsString(data); - Py_ssize_t size = PyBytes_Size(data); + char *buf = PyByteArray_AsString(data); + Py_ssize_t size = PyByteArray_Size(data); if (size <= 9) { PyErr_SetString(ZipImportError, @@ -942,16 +942,16 @@ static PyObject * normalize_line_endings(PyObject *source) { - char *buf, *q, *p = PyBytes_AsString(source); + char *buf, *q, *p = PyByteArray_AsString(source); PyObject *fixed_source; int len = 0; if (!p) { - return PyBytes_FromStringAndSize("\n\0", 2); + return PyByteArray_FromStringAndSize("\n\0", 2); } /* one char extra for trailing \n and one for terminating \0 */ - buf = (char *)PyMem_Malloc(PyBytes_Size(source) + 2); + buf = (char *)PyMem_Malloc(PyByteArray_Size(source) + 2); if (buf == NULL) { PyErr_SetString(PyExc_MemoryError, "zipimport: no memory to allocate " @@ -971,7 +971,7 @@ } *q++ = '\n'; /* add trailing \n */ *q = '\0'; - fixed_source = PyBytes_FromStringAndSize(buf, len + 2); + fixed_source = PyByteArray_FromStringAndSize(buf, len + 2); PyMem_Free(buf); return fixed_source; } @@ -987,7 +987,7 @@ if (fixed_source == NULL) return NULL; - code = Py_CompileString(PyBytes_AsString(fixed_source), pathname, + code = Py_CompileString(PyByteArray_AsString(fixed_source), pathname, Py_file_input); Py_DECREF(fixed_source); return code; Modified: python/branches/py3k-grandrenaming/Modules/zlibmodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/zlibmodule.c (original) +++ python/branches/py3k-grandrenaming/Modules/zlibmodule.c Tue Jan 1 20:14:44 2008 @@ -96,12 +96,12 @@ if (self == NULL) return NULL; self->is_initialised = 0; - self->unused_data = PyBytes_FromStringAndSize("", 0); + self->unused_data = PyByteArray_FromStringAndSize("", 0); if (self->unused_data == NULL) { Py_DECREF(self); return NULL; } - self->unconsumed_tail = PyBytes_FromStringAndSize("", 0); + self->unconsumed_tail = PyByteArray_FromStringAndSize("", 0); if (self->unconsumed_tail == NULL) { Py_DECREF(self); return NULL; @@ -174,7 +174,7 @@ err=deflateEnd(&zst); if (err == Z_OK) - ReturnVal = PyBytes_FromStringAndSize((char *)output, + ReturnVal = PyByteArray_FromStringAndSize((char *)output, zst.total_out); else zlib_error(zst, err, "while finishing compression"); @@ -211,12 +211,12 @@ zst.avail_in = length; zst.avail_out = r_strlen; - if (!(result_str = PyBytes_FromStringAndSize(NULL, r_strlen))) + if (!(result_str = PyByteArray_FromStringAndSize(NULL, r_strlen))) return NULL; zst.zalloc = (alloc_func)NULL; zst.zfree = (free_func)Z_NULL; - zst.next_out = (Byte *)PyBytes_AS_STRING(result_str); + zst.next_out = (Byte *)PyByteArray_AS_STRING(result_str); zst.next_in = (Byte *)input; err = inflateInit2(&zst, wsize); @@ -256,12 +256,12 @@ /* fall through */ case(Z_OK): /* need more memory */ - if (PyBytes_Resize(result_str, r_strlen << 1) < 0) { + if (PyByteArray_Resize(result_str, r_strlen << 1) < 0) { inflateEnd(&zst); goto error; } zst.next_out = - (unsigned char *)PyBytes_AS_STRING(result_str) + r_strlen; + (unsigned char *)PyByteArray_AS_STRING(result_str) + r_strlen; zst.avail_out = r_strlen; r_strlen = r_strlen << 1; break; @@ -278,7 +278,7 @@ goto error; } - if (PyBytes_Resize(result_str, zst.total_out) < 0) + if (PyByteArray_Resize(result_str, zst.total_out) < 0) goto error; return result_str; @@ -402,7 +402,7 @@ if (!PyArg_ParseTuple(args, "s#:compress", &input, &inplen)) return NULL; - if (!(RetVal = PyBytes_FromStringAndSize(NULL, length))) + if (!(RetVal = PyByteArray_FromStringAndSize(NULL, length))) return NULL; ENTER_ZLIB @@ -411,7 +411,7 @@ self->zst.avail_in = inplen; self->zst.next_in = input; self->zst.avail_out = length; - self->zst.next_out = (unsigned char *)PyBytes_AS_STRING(RetVal); + self->zst.next_out = (unsigned char *)PyByteArray_AS_STRING(RetVal); Py_BEGIN_ALLOW_THREADS err = deflate(&(self->zst), Z_NO_FLUSH); @@ -420,13 +420,13 @@ /* while Z_OK and the output buffer is full, there might be more output, so extend the output buffer and try again */ while (err == Z_OK && self->zst.avail_out == 0) { - if (PyBytes_Resize(RetVal, length << 1) < 0) { + if (PyByteArray_Resize(RetVal, length << 1) < 0) { Py_DECREF(RetVal); RetVal = NULL; goto error; } self->zst.next_out = - (unsigned char *)PyBytes_AS_STRING(RetVal) + length; + (unsigned char *)PyByteArray_AS_STRING(RetVal) + length; self->zst.avail_out = length; length = length << 1; @@ -445,7 +445,7 @@ RetVal = NULL; goto error; } - if (PyBytes_Resize(RetVal, self->zst.total_out - start_total_out) < 0) { + if (PyByteArray_Resize(RetVal, self->zst.total_out - start_total_out) < 0) { Py_DECREF(RetVal); RetVal = NULL; } @@ -487,7 +487,7 @@ /* limit amount of data allocated to max_length */ if (max_length && length > max_length) length = max_length; - if (!(RetVal = PyBytes_FromStringAndSize(NULL, length))) + if (!(RetVal = PyByteArray_FromStringAndSize(NULL, length))) return NULL; ENTER_ZLIB @@ -496,7 +496,7 @@ self->zst.avail_in = inplen; self->zst.next_in = input; self->zst.avail_out = length; - self->zst.next_out = (unsigned char *)PyBytes_AS_STRING(RetVal); + self->zst.next_out = (unsigned char *)PyByteArray_AS_STRING(RetVal); Py_BEGIN_ALLOW_THREADS err = inflate(&(self->zst), Z_SYNC_FLUSH); @@ -518,13 +518,13 @@ if (max_length && length > max_length) length = max_length; - if (PyBytes_Resize(RetVal, length) < 0) { + if (PyByteArray_Resize(RetVal, length) < 0) { Py_DECREF(RetVal); RetVal = NULL; goto error; } self->zst.next_out = - (unsigned char *)PyBytes_AS_STRING(RetVal) + old_length; + (unsigned char *)PyByteArray_AS_STRING(RetVal) + old_length; self->zst.avail_out = length - old_length; Py_BEGIN_ALLOW_THREADS @@ -536,7 +536,7 @@ of specified size. Return the unconsumed tail in an attribute.*/ if(max_length) { Py_DECREF(self->unconsumed_tail); - self->unconsumed_tail = PyBytes_FromStringAndSize((char *)self->zst.next_in, + self->unconsumed_tail = PyByteArray_FromStringAndSize((char *)self->zst.next_in, self->zst.avail_in); if(!self->unconsumed_tail) { Py_DECREF(RetVal); @@ -553,7 +553,7 @@ */ if (err == Z_STREAM_END) { Py_XDECREF(self->unused_data); /* Free original empty string */ - self->unused_data = PyBytes_FromStringAndSize( + self->unused_data = PyByteArray_FromStringAndSize( (char *)self->zst.next_in, self->zst.avail_in); if (self->unused_data == NULL) { Py_DECREF(RetVal); @@ -570,7 +570,7 @@ goto error; } - if (PyBytes_Resize(RetVal, self->zst.total_out - start_total_out) < 0) { + if (PyByteArray_Resize(RetVal, self->zst.total_out - start_total_out) < 0) { Py_DECREF(RetVal); RetVal = NULL; } @@ -603,10 +603,10 @@ /* Flushing with Z_NO_FLUSH is a no-op, so there's no point in doing any work at all; just return an empty string. */ if (flushmode == Z_NO_FLUSH) { - return PyBytes_FromStringAndSize(NULL, 0); + return PyByteArray_FromStringAndSize(NULL, 0); } - if (!(RetVal = PyBytes_FromStringAndSize(NULL, length))) + if (!(RetVal = PyByteArray_FromStringAndSize(NULL, length))) return NULL; ENTER_ZLIB @@ -614,7 +614,7 @@ start_total_out = self->zst.total_out; self->zst.avail_in = 0; self->zst.avail_out = length; - self->zst.next_out = (unsigned char *)PyBytes_AS_STRING(RetVal); + self->zst.next_out = (unsigned char *)PyByteArray_AS_STRING(RetVal); Py_BEGIN_ALLOW_THREADS err = deflate(&(self->zst), flushmode); @@ -623,13 +623,13 @@ /* while Z_OK and the output buffer is full, there might be more output, so extend the output buffer and try again */ while (err == Z_OK && self->zst.avail_out == 0) { - if (PyBytes_Resize(RetVal, length << 1) < 0) { + if (PyByteArray_Resize(RetVal, length << 1) < 0) { Py_DECREF(RetVal); RetVal = NULL; goto error; } self->zst.next_out = - (unsigned char *)PyBytes_AS_STRING(RetVal) + length; + (unsigned char *)PyByteArray_AS_STRING(RetVal) + length; self->zst.avail_out = length; length = length << 1; @@ -663,7 +663,7 @@ goto error; } - if (PyBytes_Resize(RetVal, self->zst.total_out - start_total_out) < 0) { + if (PyByteArray_Resize(RetVal, self->zst.total_out - start_total_out) < 0) { Py_DECREF(RetVal); RetVal = NULL; } @@ -794,7 +794,7 @@ if (!PyArg_ParseTuple(args, "|i:flush", &length)) return NULL; - if (!(retval = PyBytes_FromStringAndSize(NULL, length))) + if (!(retval = PyByteArray_FromStringAndSize(NULL, length))) return NULL; @@ -802,7 +802,7 @@ start_total_out = self->zst.total_out; self->zst.avail_out = length; - self->zst.next_out = (Byte *)PyBytes_AS_STRING(retval); + self->zst.next_out = (Byte *)PyByteArray_AS_STRING(retval); Py_BEGIN_ALLOW_THREADS err = inflate(&(self->zst), Z_FINISH); @@ -811,12 +811,12 @@ /* while Z_OK and the output buffer is full, there might be more output, so extend the output buffer and try again */ while ((err == Z_OK || err == Z_BUF_ERROR) && self->zst.avail_out == 0) { - if (PyBytes_Resize(retval, length << 1) < 0) { + if (PyByteArray_Resize(retval, length << 1) < 0) { Py_DECREF(retval); retval = NULL; goto error; } - self->zst.next_out = (Byte *)PyBytes_AS_STRING(retval) + length; + self->zst.next_out = (Byte *)PyByteArray_AS_STRING(retval) + length; self->zst.avail_out = length; length = length << 1; @@ -838,7 +838,7 @@ goto error; } } - if (PyBytes_Resize(retval, self->zst.total_out - start_total_out) < 0) { + if (PyByteArray_Resize(retval, self->zst.total_out - start_total_out) < 0) { Py_DECREF(retval); retval = NULL; } Modified: python/branches/py3k-grandrenaming/Objects/bytesobject.c ============================================================================== --- python/branches/py3k-grandrenaming/Objects/bytesobject.c (original) +++ python/branches/py3k-grandrenaming/Objects/bytesobject.c Tue Jan 1 20:14:44 2008 @@ -8,15 +8,15 @@ static PyBytesObject *nullbytes = NULL; void -PyBytes_Fini(void) +PyByteArray_Fini(void) { Py_CLEAR(nullbytes); } int -PyBytes_Init(void) +PyByteArray_Init(void) { - nullbytes = PyObject_New(PyBytesObject, &PyBytes_Type); + nullbytes = PyObject_New(PyBytesObject, &PyByteArray_Type); if (nullbytes == NULL) return 0; nullbytes->ob_bytes = NULL; @@ -96,21 +96,21 @@ /* Direct API functions */ PyObject * -PyBytes_FromObject(PyObject *input) +PyByteArray_FromObject(PyObject *input) { - return PyObject_CallFunctionObjArgs((PyObject *)&PyBytes_Type, + return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type, input, NULL); } PyObject * -PyBytes_FromStringAndSize(const char *bytes, Py_ssize_t size) +PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size) { PyBytesObject *new; Py_ssize_t alloc; assert(size >= 0); - new = PyObject_New(PyBytesObject, &PyBytes_Type); + new = PyObject_New(PyBytesObject, &PyByteArray_Type); if (new == NULL) return NULL; @@ -137,31 +137,31 @@ } Py_ssize_t -PyBytes_Size(PyObject *self) +PyByteArray_Size(PyObject *self) { assert(self != NULL); - assert(PyBytes_Check(self)); + assert(PyByteArray_Check(self)); - return PyBytes_GET_SIZE(self); + return PyByteArray_GET_SIZE(self); } char * -PyBytes_AsString(PyObject *self) +PyByteArray_AsString(PyObject *self) { assert(self != NULL); - assert(PyBytes_Check(self)); + assert(PyByteArray_Check(self)); - return PyBytes_AS_STRING(self); + return PyByteArray_AS_STRING(self); } int -PyBytes_Resize(PyObject *self, Py_ssize_t size) +PyByteArray_Resize(PyObject *self, Py_ssize_t size) { void *sval; Py_ssize_t alloc = ((PyBytesObject *)self)->ob_alloc; assert(self != NULL); - assert(PyBytes_Check(self)); + assert(PyByteArray_Check(self)); assert(size >= 0); if (size < alloc / 2) { @@ -208,7 +208,7 @@ } PyObject * -PyBytes_Concat(PyObject *a, PyObject *b) +PyByteArray_Concat(PyObject *a, PyObject *b) { Py_ssize_t size; Py_buffer va, vb; @@ -229,7 +229,7 @@ goto done; } - result = (PyBytesObject *) PyBytes_FromStringAndSize(NULL, size); + result = (PyBytesObject *) PyByteArray_FromStringAndSize(NULL, size); if (result != NULL) { memcpy(result->ob_bytes, va.buf, va.len); memcpy(result->ob_bytes + va.len, vb.buf, vb.len); @@ -274,7 +274,7 @@ Py_SIZE(self) = size; self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */ } - else if (PyBytes_Resize((PyObject *)self, size) < 0) { + else if (PyByteArray_Resize((PyObject *)self, size) < 0) { PyObject_ReleaseBuffer(other, &vo); return NULL; } @@ -297,7 +297,7 @@ size = mysize * count; if (count != 0 && size / count != mysize) return PyErr_NoMemory(); - result = (PyBytesObject *)PyBytes_FromStringAndSize(NULL, size); + result = (PyBytesObject *)PyByteArray_FromStringAndSize(NULL, size); if (result != NULL && size != 0) { if (mysize == 1) memset(result->ob_bytes, self->ob_bytes[0], size); @@ -326,7 +326,7 @@ Py_SIZE(self) = size; self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */ } - else if (PyBytes_Resize((PyObject *)self, size) < 0) + else if (PyByteArray_Resize((PyObject *)self, size) < 0) return NULL; if (mysize == 1) @@ -363,7 +363,7 @@ return NULL; if (i < 0) - i += PyBytes_GET_SIZE(self); + i += PyByteArray_GET_SIZE(self); if (i < 0 || i >= Py_SIZE(self)) { PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); @@ -374,19 +374,19 @@ else if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength, cur, i; if (PySlice_GetIndicesEx((PySliceObject *)item, - PyBytes_GET_SIZE(self), + PyByteArray_GET_SIZE(self), &start, &stop, &step, &slicelength) < 0) { return NULL; } if (slicelength <= 0) - return PyBytes_FromStringAndSize("", 0); + return PyByteArray_FromStringAndSize("", 0); else if (step == 1) { - return PyBytes_FromStringAndSize(self->ob_bytes + start, + return PyByteArray_FromStringAndSize(self->ob_bytes + start, slicelength); } else { - char *source_buf = PyBytes_AS_STRING(self); + char *source_buf = PyByteArray_AS_STRING(self); char *result_buf = (char *)PyMem_Malloc(slicelength); PyObject *result; @@ -397,7 +397,7 @@ cur += step, i++) { result_buf[i] = source_buf[cur]; } - result = PyBytes_FromStringAndSize(result_buf, slicelength); + result = PyByteArray_FromStringAndSize(result_buf, slicelength); PyMem_Free(result_buf); return result; } @@ -421,7 +421,7 @@ if (values == (PyObject *)self) { /* Make a copy and call this function recursively */ int err; - values = PyBytes_FromObject(values); + values = PyByteArray_FromObject(values); if (values == NULL) return -1; err = bytearray_setslice(self, lo, hi, values); @@ -467,7 +467,7 @@ Py_SIZE(self) - hi); } /* XXX(nnorwitz): need to verify this can't overflow! */ - if (PyBytes_Resize((PyObject *)self, + if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self) + needed - avail) < 0) { res = -1; goto finish; @@ -536,7 +536,7 @@ return -1; if (i < 0) - i += PyBytes_GET_SIZE(self); + i += PyByteArray_GET_SIZE(self); if (i < 0 || i >= Py_SIZE(self)) { PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); @@ -565,7 +565,7 @@ } else if (PySlice_Check(item)) { if (PySlice_GetIndicesEx((PySliceObject *)item, - PyBytes_GET_SIZE(self), + PyByteArray_GET_SIZE(self), &start, &stop, &step, &slicelen) < 0) { return -1; } @@ -579,10 +579,10 @@ bytes = NULL; needed = 0; } - else if (values == (PyObject *)self || !PyBytes_Check(values)) { + else if (values == (PyObject *)self || !PyByteArray_Check(values)) { /* Make a copy an call this function recursively */ int err; - values = PyBytes_FromObject(values); + values = PyByteArray_FromObject(values); if (values == NULL) return -1; err = bytearray_ass_subscript(self, item, values); @@ -590,7 +590,7 @@ return err; } else { - assert(PyBytes_Check(values)); + assert(PyByteArray_Check(values)); bytes = ((PyBytesObject *)values)->ob_bytes; needed = Py_SIZE(values); } @@ -610,7 +610,7 @@ memmove(self->ob_bytes + start + needed, self->ob_bytes + stop, Py_SIZE(self) - stop); } - if (PyBytes_Resize((PyObject *)self, + if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self) + needed - slicelen) < 0) return -1; if (slicelen < needed) { @@ -644,21 +644,21 @@ i < slicelen; cur += step, i++) { Py_ssize_t lim = step - 1; - if (cur + step >= PyBytes_GET_SIZE(self)) - lim = PyBytes_GET_SIZE(self) - cur - 1; + if (cur + step >= PyByteArray_GET_SIZE(self)) + lim = PyByteArray_GET_SIZE(self) - cur - 1; memmove(self->ob_bytes + cur - i, self->ob_bytes + cur + 1, lim); } /* Move the tail of the bytes, in one chunk */ cur = start + slicelen*step; - if (cur < PyBytes_GET_SIZE(self)) { + if (cur < PyByteArray_GET_SIZE(self)) { memmove(self->ob_bytes + cur - slicelen, self->ob_bytes + cur, - PyBytes_GET_SIZE(self) - cur); + PyByteArray_GET_SIZE(self) - cur); } - if (PyBytes_Resize((PyObject *)self, - PyBytes_GET_SIZE(self) - slicelen) < 0) + if (PyByteArray_Resize((PyObject *)self, + PyByteArray_GET_SIZE(self) - slicelen) < 0) return -1; return 0; @@ -694,7 +694,7 @@ if (Py_SIZE(self) != 0) { /* Empty previous contents (yes, do this first of all!) */ - if (PyBytes_Resize((PyObject *)self, 0) < 0) + if (PyByteArray_Resize((PyObject *)self, 0) < 0) return -1; } @@ -750,7 +750,7 @@ return -1; } if (count > 0) { - if (PyBytes_Resize((PyObject *)self, count)) + if (PyByteArray_Resize((PyObject *)self, count)) return -1; memset(self->ob_bytes, 0, count); } @@ -764,7 +764,7 @@ if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0) return -1; size = view.len; - if (PyBytes_Resize((PyObject *)self, size) < 0) goto fail; + if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail; if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0) goto fail; PyObject_ReleaseBuffer(arg, &view); @@ -814,7 +814,7 @@ /* Append the byte */ if (Py_SIZE(self) < self->ob_alloc) Py_SIZE(self)++; - else if (PyBytes_Resize((PyObject *)self, Py_SIZE(self)+1) < 0) + else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0) goto error; self->ob_bytes[Py_SIZE(self)-1] = value; } @@ -860,7 +860,7 @@ quote = '\''; { char *test, *start; - start = PyBytes_AS_STRING(self); + start = PyByteArray_AS_STRING(self); for (test = start; test < start+length; ++test) { if (*test == '"') { quote = '\''; /* back to single */ @@ -1017,11 +1017,11 @@ #define STRINGLIB_CHAR char #define STRINGLIB_CMP memcmp -#define STRINGLIB_LEN PyBytes_GET_SIZE -#define STRINGLIB_STR PyBytes_AS_STRING -#define STRINGLIB_NEW PyBytes_FromStringAndSize +#define STRINGLIB_LEN PyByteArray_GET_SIZE +#define STRINGLIB_STR PyByteArray_AS_STRING +#define STRINGLIB_NEW PyByteArray_FromStringAndSize #define STRINGLIB_EMPTY nullbytes -#define STRINGLIB_CHECK_EXACT PyBytes_CheckExact +#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact #define STRINGLIB_MUTABLE 1 #include "stringlib/fastsearch.h" @@ -1066,11 +1066,11 @@ return -2; if (dir > 0) res = stringlib_find_slice( - PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), + PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), subbuf.buf, subbuf.len, start, end); else res = stringlib_rfind_slice( - PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), + PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), subbuf.buf, subbuf.len, start, end); PyObject_ReleaseBuffer(subobj, &subbuf); return res; @@ -1105,7 +1105,7 @@ bytearray_count(PyBytesObject *self, PyObject *args) { PyObject *sub_obj; - const char *str = PyBytes_AS_STRING(self); + const char *str = PyByteArray_AS_STRING(self); Py_ssize_t start = 0, end = PY_SSIZE_T_MAX; Py_buffer vsub; PyObject *count_obj; @@ -1117,7 +1117,7 @@ if (_getbuffer(sub_obj, &vsub) < 0) return NULL; - _adjust_indices(&start, &end, PyBytes_GET_SIZE(self)); + _adjust_indices(&start, &end, PyByteArray_GET_SIZE(self)); count_obj = PyLong_FromSsize_t( stringlib_count(str + start, end - start, vsub.buf, vsub.len) @@ -1196,7 +1196,7 @@ PyErr_Clear(); if (_getbuffer(arg, &varg) < 0) return -1; - pos = stringlib_find(PyBytes_AS_STRING(self), Py_SIZE(self), + pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self), varg.buf, varg.len, 0); PyObject_ReleaseBuffer(arg, &varg); return pos >= 0; @@ -1206,7 +1206,7 @@ return -1; } - return memchr(PyBytes_AS_STRING(self), ival, Py_SIZE(self)) != NULL; + return memchr(PyByteArray_AS_STRING(self), ival, Py_SIZE(self)) != NULL; } @@ -1218,12 +1218,12 @@ _bytes_tailmatch(PyBytesObject *self, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction) { - Py_ssize_t len = PyBytes_GET_SIZE(self); + Py_ssize_t len = PyByteArray_GET_SIZE(self); const char* str; Py_buffer vsubstr; int rv = 0; - str = PyBytes_AS_STRING(self); + str = PyByteArray_AS_STRING(self); if (_getbuffer(substr, &vsubstr) < 0) return -1; @@ -1382,12 +1382,12 @@ } table = (const char *)vtable.buf; - inlen = PyBytes_GET_SIZE(input_obj); - result = PyBytes_FromStringAndSize((char *)NULL, inlen); + inlen = PyByteArray_GET_SIZE(input_obj); + result = PyByteArray_FromStringAndSize((char *)NULL, inlen); if (result == NULL) goto done; - output_start = output = PyBytes_AsString(result); - input = PyBytes_AS_STRING(input_obj); + output_start = output = PyByteArray_AsString(result); + input = PyByteArray_AS_STRING(input_obj); if (vdel.len == 0) { /* If no deletions are required, use faster code */ @@ -1396,7 +1396,7 @@ if (Py_CHARMASK((*output++ = table[c])) != c) changed = 1; } - if (changed || !PyBytes_CheckExact(input_obj)) + if (changed || !PyByteArray_CheckExact(input_obj)) goto done; Py_DECREF(result); Py_INCREF(input_obj); @@ -1417,7 +1417,7 @@ continue; changed = 1; } - if (!changed && PyBytes_CheckExact(input_obj)) { + if (!changed && PyByteArray_CheckExact(input_obj)) { Py_DECREF(result); Py_INCREF(input_obj); result = input_obj; @@ -1425,7 +1425,7 @@ } /* Fix the size of the resulting string */ if (inlen > 0) - PyBytes_Resize(result, output - output_start); + PyByteArray_Resize(result, output - output_start); done: PyObject_ReleaseBuffer(tableobj, &vtable); @@ -1455,13 +1455,13 @@ Py_LOCAL(PyBytesObject *) return_self(PyBytesObject *self) { - if (PyBytes_CheckExact(self)) { + if (PyByteArray_CheckExact(self)) { Py_INCREF(self); return (PyBytesObject *)self; } - return (PyBytesObject *)PyBytes_FromStringAndSize( - PyBytes_AS_STRING(self), - PyBytes_GET_SIZE(self)); + return (PyBytesObject *)PyByteArray_FromStringAndSize( + PyByteArray_AS_STRING(self), + PyByteArray_GET_SIZE(self)); } Py_LOCAL_INLINE(Py_ssize_t) @@ -1581,7 +1581,7 @@ Py_ssize_t count, i, product; PyBytesObject *result; - self_len = PyBytes_GET_SIZE(self); + self_len = PyByteArray_GET_SIZE(self); /* 1 at the end plus 1 after every character */ count = self_len+1; @@ -1604,11 +1604,11 @@ } if (! (result = (PyBytesObject *) - PyBytes_FromStringAndSize(NULL, result_len)) ) + PyByteArray_FromStringAndSize(NULL, result_len)) ) return NULL; - self_s = PyBytes_AS_STRING(self); - result_s = PyBytes_AS_STRING(result); + self_s = PyByteArray_AS_STRING(self); + result_s = PyByteArray_AS_STRING(result); /* TODO: special case single character, which doesn't need memcpy */ @@ -1641,8 +1641,8 @@ Py_ssize_t count; PyBytesObject *result; - self_len = PyBytes_GET_SIZE(self); - self_s = PyBytes_AS_STRING(self); + self_len = PyByteArray_GET_SIZE(self); + self_s = PyByteArray_AS_STRING(self); count = countchar(self_s, self_len, from_c, maxcount); if (count == 0) { @@ -1653,9 +1653,9 @@ assert(result_len>=0); if ( (result = (PyBytesObject *) - PyBytes_FromStringAndSize(NULL, result_len)) == NULL) + PyByteArray_FromStringAndSize(NULL, result_len)) == NULL) return NULL; - result_s = PyBytes_AS_STRING(result); + result_s = PyByteArray_AS_STRING(result); start = self_s; end = self_s + self_len; @@ -1685,8 +1685,8 @@ Py_ssize_t count, offset; PyBytesObject *result; - self_len = PyBytes_GET_SIZE(self); - self_s = PyBytes_AS_STRING(self); + self_len = PyByteArray_GET_SIZE(self); + self_s = PyByteArray_AS_STRING(self); count = countstring(self_s, self_len, from_s, from_len, @@ -1702,10 +1702,10 @@ assert (result_len>=0); if ( (result = (PyBytesObject *) - PyBytes_FromStringAndSize(NULL, result_len)) == NULL ) + PyByteArray_FromStringAndSize(NULL, result_len)) == NULL ) return NULL; - result_s = PyBytes_AS_STRING(result); + result_s = PyByteArray_AS_STRING(result); start = self_s; end = self_s + self_len; @@ -1737,8 +1737,8 @@ PyBytesObject *result; /* The result string will be the same size */ - self_s = PyBytes_AS_STRING(self); - self_len = PyBytes_GET_SIZE(self); + self_s = PyByteArray_AS_STRING(self); + self_len = PyByteArray_GET_SIZE(self); next = findchar(self_s, self_len, from_c); @@ -1748,10 +1748,10 @@ } /* Need to make a new bytes */ - result = (PyBytesObject *) PyBytes_FromStringAndSize(NULL, self_len); + result = (PyBytesObject *) PyByteArray_FromStringAndSize(NULL, self_len); if (result == NULL) return NULL; - result_s = PyBytes_AS_STRING(result); + result_s = PyByteArray_AS_STRING(result); Py_MEMCPY(result_s, self_s, self_len); /* change everything in-place, starting with this one */ @@ -1785,8 +1785,8 @@ /* The result bytes will be the same size */ - self_s = PyBytes_AS_STRING(self); - self_len = PyBytes_GET_SIZE(self); + self_s = PyByteArray_AS_STRING(self); + self_len = PyByteArray_GET_SIZE(self); offset = findstring(self_s, self_len, from_s, from_len, @@ -1797,10 +1797,10 @@ } /* Need to make a new bytes */ - result = (PyBytesObject *) PyBytes_FromStringAndSize(NULL, self_len); + result = (PyBytesObject *) PyByteArray_FromStringAndSize(NULL, self_len); if (result == NULL) return NULL; - result_s = PyBytes_AS_STRING(result); + result_s = PyByteArray_AS_STRING(result); Py_MEMCPY(result_s, self_s, self_len); /* change everything in-place, starting with this one */ @@ -1835,8 +1835,8 @@ Py_ssize_t count, product; PyBytesObject *result; - self_s = PyBytes_AS_STRING(self); - self_len = PyBytes_GET_SIZE(self); + self_s = PyByteArray_AS_STRING(self); + self_len = PyByteArray_GET_SIZE(self); count = countchar(self_s, self_len, from_c, maxcount); if (count == 0) { @@ -1858,9 +1858,9 @@ } if ( (result = (PyBytesObject *) - PyBytes_FromStringAndSize(NULL, result_len)) == NULL) + PyByteArray_FromStringAndSize(NULL, result_len)) == NULL) return NULL; - result_s = PyBytes_AS_STRING(result); + result_s = PyByteArray_AS_STRING(result); start = self_s; end = self_s + self_len; @@ -1902,8 +1902,8 @@ Py_ssize_t count, offset, product; PyBytesObject *result; - self_s = PyBytes_AS_STRING(self); - self_len = PyBytes_GET_SIZE(self); + self_s = PyByteArray_AS_STRING(self); + self_len = PyByteArray_GET_SIZE(self); count = countstring(self_s, self_len, from_s, from_len, @@ -1927,9 +1927,9 @@ } if ( (result = (PyBytesObject *) - PyBytes_FromStringAndSize(NULL, result_len)) == NULL) + PyByteArray_FromStringAndSize(NULL, result_len)) == NULL) return NULL; - result_s = PyBytes_AS_STRING(result); + result_s = PyByteArray_AS_STRING(result); start = self_s; end = self_s + self_len; @@ -1969,7 +1969,7 @@ { if (maxcount < 0) { maxcount = PY_SSIZE_T_MAX; - } else if (maxcount == 0 || PyBytes_GET_SIZE(self) == 0) { + } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) { /* nothing to do; return the original bytes */ return return_self(self); } @@ -1992,7 +1992,7 @@ /* Except for "".replace("", "A") == "A" there is no way beyond this */ /* point for an empty self bytes to generate a non-empty bytes */ /* Special case so the remaining code always gets a non-empty bytes */ - if (PyBytes_GET_SIZE(self) == 0) { + if (PyByteArray_GET_SIZE(self) == 0) { return return_self(self); } @@ -2080,7 +2080,7 @@ (maxsplit >= MAX_PREALLOC ? MAX_PREALLOC : maxsplit+1) #define SPLIT_APPEND(data, left, right) \ - str = PyBytes_FromStringAndSize((data) + (left), \ + str = PyByteArray_FromStringAndSize((data) + (left), \ (right) - (left)); \ if (str == NULL) \ goto onError; \ @@ -2092,7 +2092,7 @@ Py_DECREF(str); #define SPLIT_ADD(data, left, right) { \ - str = PyBytes_FromStringAndSize((data) + (left), \ + str = PyByteArray_FromStringAndSize((data) + (left), \ (right) - (left)); \ if (str == NULL) \ goto onError; \ @@ -2193,9 +2193,9 @@ static PyObject * bytearray_split(PyBytesObject *self, PyObject *args) { - Py_ssize_t len = PyBytes_GET_SIZE(self), n, i, j; + Py_ssize_t len = PyByteArray_GET_SIZE(self), n, i, j; Py_ssize_t maxsplit = -1, count = 0; - const char *s = PyBytes_AS_STRING(self), *sub; + const char *s = PyByteArray_AS_STRING(self), *sub; PyObject *list, *str, *subobj = Py_None; Py_buffer vsub; #ifdef USE_FAST @@ -2273,7 +2273,7 @@ assert(PyTuple_GET_SIZE(result) == 3); for (i = 0; i < 3; i++) { if (PyTuple_GET_ITEM(result, i) == (PyObject *)nullbytes) { - PyObject *new = PyBytes_FromStringAndSize(NULL, 0); + PyObject *new = PyByteArray_FromStringAndSize(NULL, 0); if (new == NULL) { Py_DECREF(result); result = NULL; @@ -2299,15 +2299,15 @@ { PyObject *bytesep, *result; - bytesep = PyBytes_FromObject(sep_obj); + bytesep = PyByteArray_FromObject(sep_obj); if (! bytesep) return NULL; result = stringlib_partition( (PyObject*) self, - PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), + PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), bytesep, - PyBytes_AS_STRING(bytesep), PyBytes_GET_SIZE(bytesep) + PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep) ); Py_DECREF(bytesep); @@ -2327,15 +2327,15 @@ { PyObject *bytesep, *result; - bytesep = PyBytes_FromObject(sep_obj); + bytesep = PyByteArray_FromObject(sep_obj); if (! bytesep) return NULL; result = stringlib_rpartition( (PyObject*) self, - PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), + PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), bytesep, - PyBytes_AS_STRING(bytesep), PyBytes_GET_SIZE(bytesep) + PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep) ); Py_DECREF(bytesep); @@ -2428,9 +2428,9 @@ static PyObject * bytearray_rsplit(PyBytesObject *self, PyObject *args) { - Py_ssize_t len = PyBytes_GET_SIZE(self), n, i, j; + Py_ssize_t len = PyByteArray_GET_SIZE(self), n, i, j; Py_ssize_t maxsplit = -1, count = 0; - const char *s = PyBytes_AS_STRING(self), *sub; + const char *s = PyByteArray_AS_STRING(self), *sub; PyObject *list, *str, *subobj = Py_None; Py_buffer vsub; @@ -2532,7 +2532,7 @@ "byte must be in range(0, 256)"); return NULL; } - if (PyBytes_Resize((PyObject *)self, n + 1) < 0) + if (PyByteArray_Resize((PyObject *)self, n + 1) < 0) return NULL; if (where < 0) { @@ -2565,7 +2565,7 @@ "cannot add more objects to bytes"); return NULL; } - if (PyBytes_Resize((PyObject *)self, n + 1) < 0) + if (PyByteArray_Resize((PyObject *)self, n + 1) < 0) return NULL; self->ob_bytes[n] = value; @@ -2625,7 +2625,7 @@ Py_DECREF(it); /* XXX: Is possible to avoid a full copy of the buffer? */ - tmp = PyBytes_FromStringAndSize(buf, len); + tmp = PyByteArray_FromStringAndSize(buf, len); res = bytearray_extend(self, tmp); Py_DECREF(tmp); PyMem_Free(buf); @@ -2661,7 +2661,7 @@ value = self->ob_bytes[where]; memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where); - if (PyBytes_Resize((PyObject *)self, n - 1) < 0) + if (PyByteArray_Resize((PyObject *)self, n - 1) < 0) return NULL; return PyLong_FromLong(value); @@ -2690,7 +2690,7 @@ } memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where); - if (PyBytes_Resize((PyObject *)self, n - 1) < 0) + if (PyByteArray_Resize((PyObject *)self, n - 1) < 0) return NULL; Py_RETURN_NONE; @@ -2751,7 +2751,7 @@ right = rstrip_helper(myptr, mysize, argptr, argsize); if (arg != Py_None) PyObject_ReleaseBuffer(arg, &varg); - return PyBytes_FromStringAndSize(self->ob_bytes + left, right - left); + return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left); } PyDoc_STRVAR(lstrip__doc__, @@ -2784,7 +2784,7 @@ right = mysize; if (arg != Py_None) PyObject_ReleaseBuffer(arg, &varg); - return PyBytes_FromStringAndSize(self->ob_bytes + left, right - left); + return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left); } PyDoc_STRVAR(rstrip__doc__, @@ -2817,7 +2817,7 @@ right = rstrip_helper(myptr, mysize, argptr, argsize); if (arg != Py_None) PyObject_ReleaseBuffer(arg, &varg); - return PyBytes_FromStringAndSize(self->ob_bytes + left, right - left); + return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left); } PyDoc_STRVAR(decode_doc, @@ -2881,7 +2881,7 @@ /* XXX Shouldn't we use _getbuffer() on these items instead? */ for (i = 0; i < n; i++) { PyObject *obj = items[i]; - if (!PyBytes_Check(obj) && !PyString_Check(obj)) { + if (!PyByteArray_Check(obj) && !PyString_Check(obj)) { PyErr_Format(PyExc_TypeError, "can only join an iterable of bytes " "(item %ld has type '%.100s')", @@ -2899,16 +2899,16 @@ } /* Allocate the result, and copy the bytes */ - result = PyBytes_FromStringAndSize(NULL, totalsize); + result = PyByteArray_FromStringAndSize(NULL, totalsize); if (result == NULL) goto error; - dest = PyBytes_AS_STRING(result); + dest = PyByteArray_AS_STRING(result); for (i = 0; i < n; i++) { PyObject *obj = items[i]; Py_ssize_t size = Py_SIZE(obj); char *buf; - if (PyBytes_Check(obj)) - buf = PyBytes_AS_STRING(obj); + if (PyByteArray_Check(obj)) + buf = PyByteArray_AS_STRING(obj); else buf = PyString_AS_STRING(obj); if (i) { @@ -2967,10 +2967,10 @@ hexlen = PyUnicode_GET_SIZE(hexobj); hex = PyUnicode_AS_UNICODE(hexobj); byteslen = hexlen/2; /* This overestimates if there are spaces */ - newbytes = PyBytes_FromStringAndSize(NULL, byteslen); + newbytes = PyByteArray_FromStringAndSize(NULL, byteslen); if (!newbytes) return NULL; - buf = PyBytes_AS_STRING(newbytes); + buf = PyByteArray_AS_STRING(newbytes); for (i = j = 0; i < hexlen; i += 2) { /* skip over spaces in the input */ while (hex[i] == ' ') @@ -2987,7 +2987,7 @@ } buf[j++] = (top << 4) + bot; } - if (PyBytes_Resize(newbytes, j) < 0) + if (PyByteArray_Resize(newbytes, j) < 0) goto error; return newbytes; @@ -3020,7 +3020,7 @@ static PySequenceMethods bytearray_as_sequence = { (lenfunc)bytearray_length, /* sq_length */ - (binaryfunc)PyBytes_Concat, /* sq_concat */ + (binaryfunc)PyByteArray_Concat, /* sq_concat */ (ssizeargfunc)bytearray_repeat, /* sq_repeat */ (ssizeargfunc)bytearray_getitem, /* sq_item */ 0, /* sq_slice */ @@ -3125,7 +3125,7 @@ static PyObject *bytearray_iter(PyObject *seq); -PyTypeObject PyBytes_Type = { +PyTypeObject PyByteArray_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "bytearray", sizeof(PyBytesObject), @@ -3200,9 +3200,9 @@ seq = it->it_seq; if (seq == NULL) return NULL; - assert(PyBytes_Check(seq)); + assert(PyByteArray_Check(seq)); - if (it->it_index < PyBytes_GET_SIZE(seq)) { + if (it->it_index < PyByteArray_GET_SIZE(seq)) { item = PyLong_FromLong( (unsigned char)seq->ob_bytes[it->it_index]); if (item != NULL) @@ -3220,7 +3220,7 @@ { Py_ssize_t len = 0; if (it->it_seq) - len = PyBytes_GET_SIZE(it->it_seq) - it->it_index; + len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index; return PyLong_FromSsize_t(len); } @@ -3271,7 +3271,7 @@ { bytesiterobject *it; - if (!PyBytes_Check(seq)) { + if (!PyByteArray_Check(seq)) { PyErr_BadInternalCall(); return NULL; } Modified: python/branches/py3k-grandrenaming/Objects/longobject.c ============================================================================== --- python/branches/py3k-grandrenaming/Objects/longobject.c (original) +++ python/branches/py3k-grandrenaming/Objects/longobject.c Tue Jan 1 20:14:44 2008 @@ -3461,13 +3461,13 @@ return PyLong_FromUnicode(PyUnicode_AS_UNICODE(x), PyUnicode_GET_SIZE(x), base); - else if (PyBytes_Check(x) || PyString_Check(x)) { + else if (PyByteArray_Check(x) || PyString_Check(x)) { /* Since PyLong_FromString doesn't have a length parameter, * check here for possible NULs in the string. */ char *string; int size = Py_SIZE(x); - if (PyBytes_Check(x)) - string = PyBytes_AS_STRING(x); + if (PyByteArray_Check(x)) + string = PyByteArray_AS_STRING(x); else string = PyString_AS_STRING(x); if (strlen(string) != size) { Modified: python/branches/py3k-grandrenaming/Objects/memoryobject.c ============================================================================== --- python/branches/py3k-grandrenaming/Objects/memoryobject.c (original) +++ python/branches/py3k-grandrenaming/Objects/memoryobject.c Tue Jan 1 20:14:44 2008 @@ -254,12 +254,12 @@ "for a non-contiguousobject."); return NULL; } - bytes = PyBytes_FromStringAndSize(NULL, view->len); + bytes = PyByteArray_FromStringAndSize(NULL, view->len); if (bytes == NULL) { PyObject_ReleaseBuffer(obj, view); return NULL; } - dest = PyBytes_AS_STRING(bytes); + dest = PyByteArray_AS_STRING(bytes); /* different copying strategy depending on whether or not any pointer de-referencing is needed */ @@ -382,7 +382,7 @@ static PyObject * memory_tobytes(PyMemoryViewObject *mem, PyObject *noargs) { - return PyBytes_FromObject((PyObject *)mem); + return PyByteArray_FromObject((PyObject *)mem); } static PyObject * @@ -451,8 +451,8 @@ if (PyObject_GetBuffer((PyObject *)self, &view, PyBUF_FULL) < 0) return NULL; - res = PyBytes_FromStringAndSize(NULL, view.len); - PyBuffer_ToContiguous(PyBytes_AS_STRING(res), &view, view.len, 'C'); + res = PyByteArray_FromStringAndSize(NULL, view.len); + PyBuffer_ToContiguous(PyByteArray_AS_STRING(res), &view, view.len, 'C'); PyObject_ReleaseBuffer((PyObject *)self, &view); return res; } @@ -522,7 +522,7 @@ { ptr = *((char **)ptr) + view->suboffsets[0]; } - return PyBytes_FromStringAndSize(ptr, view->itemsize); + return PyByteArray_FromStringAndSize(ptr, view->itemsize); } else { /* Return a new memory-view object */ Modified: python/branches/py3k-grandrenaming/Objects/object.c ============================================================================== --- python/branches/py3k-grandrenaming/Objects/object.c (original) +++ python/branches/py3k-grandrenaming/Objects/object.c Tue Jan 1 20:14:44 2008 @@ -1486,7 +1486,7 @@ if (PyType_Ready(&PyBool_Type) < 0) Py_FatalError("Can't initialize 'bool'"); - if (PyType_Ready(&PyBytes_Type) < 0) + if (PyType_Ready(&PyByteArray_Type) < 0) Py_FatalError("Can't initialize 'bytes'"); if (PyType_Ready(&PyString_Type) < 0) Modified: python/branches/py3k-grandrenaming/Objects/stringobject.c ============================================================================== --- python/branches/py3k-grandrenaming/Objects/stringobject.c (original) +++ python/branches/py3k-grandrenaming/Objects/stringobject.c Tue Jan 1 20:14:44 2008 @@ -1470,7 +1470,7 @@ for (i = 0; i < seqlen; i++) { const size_t old_sz = sz; item = PySequence_Fast_GET_ITEM(seq, i); - if (!PyString_Check(item) && !PyBytes_Check(item)) { + if (!PyString_Check(item) && !PyByteArray_Check(item)) { PyErr_Format(PyExc_TypeError, "sequence item %zd: expected bytes," " %.80s found", @@ -1512,7 +1512,7 @@ if (PyString_Check(item)) q = PyString_AS_STRING(item); else - q = PyBytes_AS_STRING(item); + q = PyByteArray_AS_STRING(item); Py_MEMCPY(p, q, n); p += n; } Modified: python/branches/py3k-grandrenaming/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k-grandrenaming/Objects/unicodeobject.c (original) +++ python/branches/py3k-grandrenaming/Objects/unicodeobject.c Tue Jan 1 20:14:44 2008 @@ -1688,11 +1688,11 @@ if (size == 0) return PyString_FromStringAndSize(NULL, 0); - v = PyBytes_FromStringAndSize(NULL, cbAllocated); + v = PyByteArray_FromStringAndSize(NULL, cbAllocated); if (v == NULL) return NULL; - start = out = PyBytes_AS_STRING(v); + start = out = PyByteArray_AS_STRING(v); for (;i < size; ++i) { Py_UNICODE ch = s[i]; @@ -1758,7 +1758,7 @@ *out++ = '-'; } - result = PyString_FromStringAndSize(PyBytes_AS_STRING(v), out - start); + result = PyString_FromStringAndSize(PyByteArray_AS_STRING(v), out - start); Py_DECREF(v); return result; } @@ -2309,12 +2309,12 @@ 0xDC00 <= s[i+1] && s[i+1] <= 0xDFFF) pairs++; #endif - v = PyBytes_FromStringAndSize(NULL, + v = PyByteArray_FromStringAndSize(NULL, 4 * (size - pairs + (byteorder == 0))); if (v == NULL) return NULL; - p = (unsigned char *)PyBytes_AS_STRING(v); + p = (unsigned char *)PyByteArray_AS_STRING(v); if (byteorder == 0) STORECHAR(0xFEFF); if (size == 0) @@ -2351,7 +2351,7 @@ } done: - result = PyString_FromStringAndSize(PyBytes_AS_STRING(v), Py_SIZE(v)); + result = PyString_FromStringAndSize(PyByteArray_AS_STRING(v), Py_SIZE(v)); Py_DECREF(v); return result; #undef STORECHAR @@ -2578,12 +2578,12 @@ if (s[i] >= 0x10000) pairs++; #endif - v = PyBytes_FromStringAndSize(NULL, + v = PyByteArray_FromStringAndSize(NULL, 2 * (size + pairs + (byteorder == 0))); if (v == NULL) return NULL; - p = (unsigned char *)PyBytes_AS_STRING(v); + p = (unsigned char *)PyByteArray_AS_STRING(v); if (byteorder == 0) STORECHAR(0xFEFF); if (size == 0) @@ -2615,7 +2615,7 @@ } done: - result = PyString_FromStringAndSize(PyBytes_AS_STRING(v), Py_SIZE(v)); + result = PyString_FromStringAndSize(PyByteArray_AS_STRING(v), Py_SIZE(v)); Py_DECREF(v); return result; #undef STORECHAR @@ -2928,7 +2928,7 @@ escape. */ - repr = PyBytes_FromStringAndSize(NULL, + repr = PyByteArray_FromStringAndSize(NULL, #ifdef Py_UNICODE_WIDE + 10*size #else @@ -2938,7 +2938,7 @@ if (repr == NULL) return NULL; - p = PyBytes_AS_STRING(repr); + p = PyByteArray_AS_STRING(repr); while (size-- > 0) { Py_UNICODE ch = *s++; @@ -3030,8 +3030,8 @@ *p++ = (char) ch; } - result = PyString_FromStringAndSize(PyBytes_AS_STRING(repr), - p - PyBytes_AS_STRING(repr)); + result = PyString_FromStringAndSize(PyByteArray_AS_STRING(repr), + p - PyByteArray_AS_STRING(repr)); Py_DECREF(repr); return result; } @@ -3048,8 +3048,8 @@ if (!s) return NULL; - result = PyString_FromStringAndSize(PyBytes_AS_STRING(s), - PyBytes_GET_SIZE(s)); + result = PyString_FromStringAndSize(PyByteArray_AS_STRING(s), + PyByteArray_GET_SIZE(s)); Py_DECREF(s); return result; } @@ -3169,16 +3169,16 @@ char *q; #ifdef Py_UNICODE_WIDE - repr = PyBytes_FromStringAndSize(NULL, 10 * size); + repr = PyByteArray_FromStringAndSize(NULL, 10 * size); #else - repr = PyBytes_FromStringAndSize(NULL, 6 * size); + repr = PyByteArray_FromStringAndSize(NULL, 6 * size); #endif if (repr == NULL) return NULL; if (size == 0) goto done; - p = q = PyBytes_AS_STRING(repr); + p = q = PyByteArray_AS_STRING(repr); while (size-- > 0) { Py_UNICODE ch = *s++; #ifdef Py_UNICODE_WIDE @@ -3213,7 +3213,7 @@ size = p - q; done: - result = PyString_FromStringAndSize(PyBytes_AS_STRING(repr), size); + result = PyString_FromStringAndSize(PyByteArray_AS_STRING(repr), size); Py_DECREF(repr); return result; } @@ -3230,8 +3230,8 @@ if (!s) return NULL; - result = PyString_FromStringAndSize(PyBytes_AS_STRING(s), - PyBytes_GET_SIZE(s)); + result = PyString_FromStringAndSize(PyByteArray_AS_STRING(s), + PyByteArray_GET_SIZE(s)); Py_DECREF(s); return result; } @@ -3464,10 +3464,10 @@ replacements, if we need more, we'll resize */ if (size == 0) return PyString_FromStringAndSize(NULL, 0); - res = PyBytes_FromStringAndSize(NULL, size); + res = PyByteArray_FromStringAndSize(NULL, size); if (res == NULL) return NULL; - str = PyBytes_AS_STRING(res); + str = PyByteArray_AS_STRING(res); ressize = size; while (p ressize) { if (requiredsize<2*ressize) requiredsize = 2*ressize; - if (PyBytes_Resize(res, requiredsize)) + if (PyByteArray_Resize(res, requiredsize)) goto onError; - str = PyBytes_AS_STRING(res) + respos; + str = PyByteArray_AS_STRING(res) + respos; ressize = requiredsize; } /* generate replacement (temporarily (mis)uses p) */ @@ -3564,17 +3564,17 @@ /* need more space? (at least enough for what we have+the replacement+the rest of the string, so we won't have to check space for encodable characters) */ - respos = str - PyBytes_AS_STRING(res); + respos = str - PyByteArray_AS_STRING(res); repsize = PyUnicode_GET_SIZE(repunicode); requiredsize = respos+repsize+(endp-collend); if (requiredsize > ressize) { if (requiredsize<2*ressize) requiredsize = 2*ressize; - if (PyBytes_Resize(res, requiredsize)) { + if (PyByteArray_Resize(res, requiredsize)) { Py_DECREF(repunicode); goto onError; } - str = PyBytes_AS_STRING(res) + respos; + str = PyByteArray_AS_STRING(res) + respos; ressize = requiredsize; } /* check if there is anything unencodable in the replacement @@ -3594,8 +3594,8 @@ } } } - result = PyString_FromStringAndSize(PyBytes_AS_STRING(res), - str - PyBytes_AS_STRING(res)); + result = PyString_FromStringAndSize(PyByteArray_AS_STRING(res), + str - PyByteArray_AS_STRING(res)); onError: Py_DECREF(res); Py_XDECREF(errorHandler); Modified: python/branches/py3k-grandrenaming/PC/_winreg.c ============================================================================== --- python/branches/py3k-grandrenaming/PC/_winreg.c (original) +++ python/branches/py3k-grandrenaming/PC/_winreg.c Tue Jan 1 20:14:44 2008 @@ -870,7 +870,7 @@ obData = Py_None; } else - obData = PyBytes_FromStringAndSize( + obData = PyByteArray_FromStringAndSize( (char *)retDataBuf, retDataSize); break; } Modified: python/branches/py3k-grandrenaming/Parser/tokenizer.c ============================================================================== --- python/branches/py3k-grandrenaming/Parser/tokenizer.c (original) +++ python/branches/py3k-grandrenaming/Parser/tokenizer.c Tue Jan 1 20:14:44 2008 @@ -406,17 +406,17 @@ } else { - buf = PyBytes_AsString(bufobj); + buf = PyByteArray_AsString(bufobj); if (buf == NULL) { goto error; } - buflen = PyBytes_GET_SIZE(bufobj); + buflen = PyByteArray_GET_SIZE(bufobj); } Py_XDECREF(tok->decoding_buffer); if (buflen > size) { /* Too many chars, the rest goes into tok->decoding_buffer */ - tok->decoding_buffer = PyBytes_FromStringAndSize(buf+size, + tok->decoding_buffer = PyByteArray_FromStringAndSize(buf+size, buflen-size); if (tok->decoding_buffer == NULL) goto error; Modified: python/branches/py3k-grandrenaming/Python/bltinmodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Python/bltinmodule.c (original) +++ python/branches/py3k-grandrenaming/Python/bltinmodule.c Tue Jan 1 20:14:44 2008 @@ -1148,11 +1148,11 @@ } #endif } - else if (PyBytes_Check(obj)) { + else if (PyByteArray_Check(obj)) { /* XXX Hopefully this is temporary */ - size = PyBytes_GET_SIZE(obj); + size = PyByteArray_GET_SIZE(obj); if (size == 1) { - ord = (long)((unsigned char)*PyBytes_AS_STRING(obj)); + ord = (long)((unsigned char)*PyByteArray_AS_STRING(obj)); return PyLong_FromLong(ord); } } @@ -1628,7 +1628,7 @@ Py_DECREF(iter); return NULL; } - if (PyBytes_Check(result)) { + if (PyByteArray_Check(result)) { PyErr_SetString(PyExc_TypeError, "sum() can't sum bytes [use b''.join(seq) instead]"); Py_DECREF(iter); @@ -1911,7 +1911,7 @@ SETBUILTIN("True", Py_True); SETBUILTIN("bool", &PyBool_Type); SETBUILTIN("memoryview", &PyMemoryView_Type); - SETBUILTIN("bytearray", &PyBytes_Type); + SETBUILTIN("bytearray", &PyByteArray_Type); SETBUILTIN("bytes", &PyString_Type); SETBUILTIN("classmethod", &PyClassMethod_Type); #ifndef WITHOUT_COMPLEX Modified: python/branches/py3k-grandrenaming/Python/codecs.c ============================================================================== --- python/branches/py3k-grandrenaming/Python/codecs.c (original) +++ python/branches/py3k-grandrenaming/Python/codecs.c Tue Jan 1 20:14:44 2008 @@ -345,7 +345,7 @@ goto onError; } v = PyTuple_GET_ITEM(result, 0); - if (PyBytes_Check(v)) { + if (PyByteArray_Check(v)) { char msg[100]; PyOS_snprintf(msg, sizeof(msg), "encoder %s returned buffer instead of bytes", @@ -354,7 +354,7 @@ v = NULL; goto onError; } - v = PyString_FromStringAndSize(PyBytes_AS_STRING(v), Py_SIZE(v)); + v = PyString_FromStringAndSize(PyByteArray_AS_STRING(v), Py_SIZE(v)); } else if (PyString_Check(v)) Py_INCREF(v); Modified: python/branches/py3k-grandrenaming/Python/getargs.c ============================================================================== --- python/branches/py3k-grandrenaming/Python/getargs.c (original) +++ python/branches/py3k-grandrenaming/Python/getargs.c Tue Jan 1 20:14:44 2008 @@ -968,7 +968,7 @@ /* Encode object */ if (!recode_strings && - (PyString_Check(arg) || PyBytes_Check(arg))) { + (PyString_Check(arg) || PyByteArray_Check(arg))) { s = arg; Py_INCREF(s); if (PyObject_AsCharBuffer(s, &ptr, &size) < 0) @@ -1122,7 +1122,7 @@ case 'Y': { /* PyBytes object */ PyObject **p = va_arg(*p_va, PyObject **); - if (PyBytes_Check(arg)) + if (PyByteArray_Check(arg)) *p = arg; else return converterr("buffer", arg, msgbuf, bufsize); Modified: python/branches/py3k-grandrenaming/Python/import.c ============================================================================== --- python/branches/py3k-grandrenaming/Python/import.c (original) +++ python/branches/py3k-grandrenaming/Python/import.c Tue Jan 1 20:14:44 2008 @@ -2599,7 +2599,7 @@ buf[2] = (char) ((pyc_magic >> 16) & 0xff); buf[3] = (char) ((pyc_magic >> 24) & 0xff); - return PyBytes_FromStringAndSize(buf, 4); + return PyByteArray_FromStringAndSize(buf, 4); } static PyObject * Modified: python/branches/py3k-grandrenaming/Python/mactoolboxglue.c ============================================================================== --- python/branches/py3k-grandrenaming/Python/mactoolboxglue.c (original) +++ python/branches/py3k-grandrenaming/Python/mactoolboxglue.c Tue Jan 1 20:14:44 2008 @@ -170,9 +170,9 @@ str = PyString_AS_STRING(v); len = PyString_GET_SIZE(v); } - else if (PyBytes_Check(v)) { - str = PyBytes_AS_STRING(v); - len = PyBytes_GET_SIZE(v); + else if (PyByteArray_Check(v)) { + str = PyByteArray_AS_STRING(v); + len = PyByteArray_GET_SIZE(v); } else { PyErr_SetString(PyExc_TypeError, @@ -221,9 +221,9 @@ ptr = PyString_AS_STRING(v); len = PyString_GET_SIZE(v); } - else if (PyBytes_Check(v)) { - ptr = PyBytes_AS_STRING(v); - len = PyBytes_GET_SIZE(v); + else if (PyByteArray_Check(v)) { + ptr = PyByteArray_AS_STRING(v); + len = PyByteArray_GET_SIZE(v); } if (len > 255) { PyErr_SetString(PyExc_TypeError, Modified: python/branches/py3k-grandrenaming/Python/marshal.c ============================================================================== --- python/branches/py3k-grandrenaming/Python/marshal.c (original) +++ python/branches/py3k-grandrenaming/Python/marshal.c Tue Jan 1 20:14:44 2008 @@ -1095,7 +1095,7 @@ } if (wf.str != NULL) { /* XXX Quick hack -- need to do this differently */ - res = PyBytes_FromObject(wf.str); + res = PyByteArray_FromObject(wf.str); Py_DECREF(wf.str); } return res; @@ -1136,9 +1136,9 @@ rf.ptr = PyString_AS_STRING(data); rf.end = rf.ptr + PyString_GET_SIZE(data); } - else if (PyBytes_Check(data)) { - rf.ptr = PyBytes_AS_STRING(data); - rf.end = rf.ptr + PyBytes_GET_SIZE(data); + else if (PyByteArray_Check(data)) { + rf.ptr = PyByteArray_AS_STRING(data); + rf.end = rf.ptr + PyByteArray_GET_SIZE(data); } else { PyErr_Format(PyExc_TypeError, Modified: python/branches/py3k-grandrenaming/Python/pythonrun.c ============================================================================== --- python/branches/py3k-grandrenaming/Python/pythonrun.c (original) +++ python/branches/py3k-grandrenaming/Python/pythonrun.c Tue Jan 1 20:14:44 2008 @@ -194,7 +194,7 @@ if (!_PyLong_Init()) Py_FatalError("Py_Initialize: can't init longs"); - if (!PyBytes_Init()) + if (!PyByteArray_Init()) Py_FatalError("Py_Initialize: can't init bytes"); _PyFloat_Init(); @@ -495,7 +495,7 @@ PyList_Fini(); PySet_Fini(); PyString_Fini(); - PyBytes_Fini(); + PyByteArray_Fini(); PyLong_Fini(); PyFloat_Fini(); From python-3000-checkins at python.org Tue Jan 1 20:16:56 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Tue, 1 Jan 2008 20:16:56 +0100 (CET) Subject: [Python-3000-checkins] r59651 - in python/branches/py3k-grandrenaming: Doc/c-api/concrete.rst Doc/c-api/exceptions.rst Doc/c-api/intro.rst Doc/c-api/memory.rst Doc/c-api/newtypes.rst Doc/extending/embedding.rst Doc/extending/newtypes.rst Doc/whatsnew/2.3.rst Include/py_curses.h Include/pyport.h Include/pythonrun.h Include/stringobject.h Mac/Modules/MacOS.c Mac/Modules/Nav.c Mac/Modules/ae/_AEmodule.c Mac/Modules/cf/_CFmodule.c Mac/Modules/cf/pycfbridge.c Mac/Modules/file/_Filemodule.c Mac/Modules/qd/_Qdmodule.c Mac/Modules/qdoffs/_Qdoffsmodule.c Mac/Modules/res/_Resmodule.c Mac/Modules/scrap/_Scrapmodule.c Mac/Modules/snd/_Sndihooks.c Modules/_bsddb.c Modules/_codecsmodule.c Modules/_ctypes/_ctypes.c Modules/_ctypes/callbacks.c Modules/_ctypes/callproc.c Modules/_ctypes/cfield.c Modules/_cursesmodule.c Modules/_elementtree.c Modules/_fileio.c Modules/_hashopenssl.c Modules/_sqlite/connection.c Modules/_sqlite/connection.h Modules/_sqlite/cursor.c Modules/_sre.c Modules/_ssl.c Modules/_struct.c Modules/_tkinter.c Modules/arraymodule.c Modules/audioop.c Modules/binascii.c Modules/bz2module.c Modules/cStringIO.c Modules/cjkcodecs/multibytecodec.c Modules/datetimemodule.c Modules/dbmmodule.c Modules/fcntlmodule.c Modules/gdbmmodule.c Modules/md5module.c Modules/mmapmodule.c Modules/posixmodule.c Modules/pyexpat.c Modules/sha1module.c Modules/sha256module.c Modules/sha512module.c Modules/socketmodule.c Modules/termios.c Objects/bytes_methods.c Objects/bytesobject.c Objects/codeobject.c Objects/exceptions.c Objects/fileobject.c Objects/frameobject.c Objects/longobject.c Objects/object.c Objects/stringlib/stringdefs.h Objects/stringobject.c Objects/tupleobject.c Objects/typeobject.c Objects/unicodeobject.c PC/_msi.c PC/msvcrtmodule.c Parser/tokenizer.c Python/ast.c Python/bltinmodule.c Python/ceval.c Python/codecs.c Python/compile.c Python/getargs.c Python/import.c Python/mactoolboxglue.c Python/marshal.c Python/modsupport.c Python/peephole.c Python/pythonrun.c Python/traceback.c Message-ID: <20080101191656.51BA21E4004@bag.python.org> Author: christian.heimes Date: Tue Jan 1 20:16:52 2008 New Revision: 59651 Modified: python/branches/py3k-grandrenaming/Doc/c-api/concrete.rst python/branches/py3k-grandrenaming/Doc/c-api/exceptions.rst python/branches/py3k-grandrenaming/Doc/c-api/intro.rst python/branches/py3k-grandrenaming/Doc/c-api/memory.rst python/branches/py3k-grandrenaming/Doc/c-api/newtypes.rst python/branches/py3k-grandrenaming/Doc/extending/embedding.rst python/branches/py3k-grandrenaming/Doc/extending/newtypes.rst python/branches/py3k-grandrenaming/Doc/whatsnew/2.3.rst python/branches/py3k-grandrenaming/Include/py_curses.h python/branches/py3k-grandrenaming/Include/pyport.h python/branches/py3k-grandrenaming/Include/pythonrun.h python/branches/py3k-grandrenaming/Include/stringobject.h python/branches/py3k-grandrenaming/Mac/Modules/MacOS.c python/branches/py3k-grandrenaming/Mac/Modules/Nav.c python/branches/py3k-grandrenaming/Mac/Modules/ae/_AEmodule.c python/branches/py3k-grandrenaming/Mac/Modules/cf/_CFmodule.c python/branches/py3k-grandrenaming/Mac/Modules/cf/pycfbridge.c python/branches/py3k-grandrenaming/Mac/Modules/file/_Filemodule.c python/branches/py3k-grandrenaming/Mac/Modules/qd/_Qdmodule.c python/branches/py3k-grandrenaming/Mac/Modules/qdoffs/_Qdoffsmodule.c python/branches/py3k-grandrenaming/Mac/Modules/res/_Resmodule.c python/branches/py3k-grandrenaming/Mac/Modules/scrap/_Scrapmodule.c python/branches/py3k-grandrenaming/Mac/Modules/snd/_Sndihooks.c python/branches/py3k-grandrenaming/Modules/_bsddb.c python/branches/py3k-grandrenaming/Modules/_codecsmodule.c python/branches/py3k-grandrenaming/Modules/_ctypes/_ctypes.c python/branches/py3k-grandrenaming/Modules/_ctypes/callbacks.c python/branches/py3k-grandrenaming/Modules/_ctypes/callproc.c python/branches/py3k-grandrenaming/Modules/_ctypes/cfield.c python/branches/py3k-grandrenaming/Modules/_cursesmodule.c python/branches/py3k-grandrenaming/Modules/_elementtree.c python/branches/py3k-grandrenaming/Modules/_fileio.c python/branches/py3k-grandrenaming/Modules/_hashopenssl.c python/branches/py3k-grandrenaming/Modules/_sqlite/connection.c python/branches/py3k-grandrenaming/Modules/_sqlite/connection.h python/branches/py3k-grandrenaming/Modules/_sqlite/cursor.c python/branches/py3k-grandrenaming/Modules/_sre.c python/branches/py3k-grandrenaming/Modules/_ssl.c python/branches/py3k-grandrenaming/Modules/_struct.c python/branches/py3k-grandrenaming/Modules/_tkinter.c python/branches/py3k-grandrenaming/Modules/arraymodule.c python/branches/py3k-grandrenaming/Modules/audioop.c python/branches/py3k-grandrenaming/Modules/binascii.c python/branches/py3k-grandrenaming/Modules/bz2module.c python/branches/py3k-grandrenaming/Modules/cStringIO.c python/branches/py3k-grandrenaming/Modules/cjkcodecs/multibytecodec.c python/branches/py3k-grandrenaming/Modules/datetimemodule.c python/branches/py3k-grandrenaming/Modules/dbmmodule.c python/branches/py3k-grandrenaming/Modules/fcntlmodule.c python/branches/py3k-grandrenaming/Modules/gdbmmodule.c python/branches/py3k-grandrenaming/Modules/md5module.c python/branches/py3k-grandrenaming/Modules/mmapmodule.c python/branches/py3k-grandrenaming/Modules/posixmodule.c python/branches/py3k-grandrenaming/Modules/pyexpat.c python/branches/py3k-grandrenaming/Modules/sha1module.c python/branches/py3k-grandrenaming/Modules/sha256module.c python/branches/py3k-grandrenaming/Modules/sha512module.c python/branches/py3k-grandrenaming/Modules/socketmodule.c python/branches/py3k-grandrenaming/Modules/termios.c python/branches/py3k-grandrenaming/Objects/bytes_methods.c python/branches/py3k-grandrenaming/Objects/bytesobject.c python/branches/py3k-grandrenaming/Objects/codeobject.c python/branches/py3k-grandrenaming/Objects/exceptions.c python/branches/py3k-grandrenaming/Objects/fileobject.c python/branches/py3k-grandrenaming/Objects/frameobject.c python/branches/py3k-grandrenaming/Objects/longobject.c python/branches/py3k-grandrenaming/Objects/object.c python/branches/py3k-grandrenaming/Objects/stringlib/stringdefs.h python/branches/py3k-grandrenaming/Objects/stringobject.c python/branches/py3k-grandrenaming/Objects/tupleobject.c python/branches/py3k-grandrenaming/Objects/typeobject.c python/branches/py3k-grandrenaming/Objects/unicodeobject.c python/branches/py3k-grandrenaming/PC/_msi.c python/branches/py3k-grandrenaming/PC/msvcrtmodule.c python/branches/py3k-grandrenaming/Parser/tokenizer.c python/branches/py3k-grandrenaming/Python/ast.c python/branches/py3k-grandrenaming/Python/bltinmodule.c python/branches/py3k-grandrenaming/Python/ceval.c python/branches/py3k-grandrenaming/Python/codecs.c python/branches/py3k-grandrenaming/Python/compile.c python/branches/py3k-grandrenaming/Python/getargs.c python/branches/py3k-grandrenaming/Python/import.c python/branches/py3k-grandrenaming/Python/mactoolboxglue.c python/branches/py3k-grandrenaming/Python/marshal.c python/branches/py3k-grandrenaming/Python/modsupport.c python/branches/py3k-grandrenaming/Python/peephole.c python/branches/py3k-grandrenaming/Python/pythonrun.c python/branches/py3k-grandrenaming/Python/traceback.c Log: find -name '*.c' -or -name '*.h' -or -name '*.rst' | xargs sed -i s/PyString_/PyBytes_/g Modified: python/branches/py3k-grandrenaming/Doc/c-api/concrete.rst ============================================================================== --- python/branches/py3k-grandrenaming/Doc/c-api/concrete.rst (original) +++ python/branches/py3k-grandrenaming/Doc/c-api/concrete.rst Tue Jan 1 20:16:52 2008 @@ -602,7 +602,7 @@ This subtype of :ctype:`PyObject` represents a Python string object. -.. cvar:: PyTypeObject PyString_Type +.. cvar:: PyTypeObject PyBytes_Type .. index:: single: StringType (in module types) @@ -610,33 +610,33 @@ the same object as ``str`` and ``types.StringType`` in the Python layer. . -.. cfunction:: int PyString_Check(PyObject *o) +.. cfunction:: int PyBytes_Check(PyObject *o) Return true if the object *o* is a string object or an instance of a subtype of the string type. -.. cfunction:: int PyString_CheckExact(PyObject *o) +.. cfunction:: int PyBytes_CheckExact(PyObject *o) Return true if the object *o* is a string object, but not an instance of a subtype of the string type. -.. cfunction:: PyObject* PyString_FromString(const char *v) +.. cfunction:: PyObject* PyBytes_FromString(const char *v) Return a new string object with a copy of the string *v* as value on success, and *NULL* on failure. The parameter *v* must not be *NULL*; it will not be checked. -.. cfunction:: PyObject* PyString_FromStringAndSize(const char *v, Py_ssize_t len) +.. cfunction:: PyObject* PyBytes_FromStringAndSize(const char *v, Py_ssize_t len) Return a new string object with a copy of the string *v* as value and length *len* on success, and *NULL* on failure. If *v* is *NULL*, the contents of the string are uninitialized. -.. cfunction:: PyObject* PyString_FromFormat(const char *format, ...) +.. cfunction:: PyObject* PyBytes_FromFormat(const char *format, ...) Take a C :cfunc:`printf`\ -style *format* string and a variable number of arguments, calculate the size of the resulting Python string and return a string @@ -699,40 +699,40 @@ copied as-is to the result string, and any extra arguments discarded. -.. cfunction:: PyObject* PyString_FromFormatV(const char *format, va_list vargs) +.. cfunction:: PyObject* PyBytes_FromFormatV(const char *format, va_list vargs) - Identical to :func:`PyString_FromFormat` except that it takes exactly two + Identical to :func:`PyBytes_FromFormat` except that it takes exactly two arguments. -.. cfunction:: Py_ssize_t PyString_Size(PyObject *string) +.. cfunction:: Py_ssize_t PyBytes_Size(PyObject *string) Return the length of the string in string object *string*. -.. cfunction:: Py_ssize_t PyString_GET_SIZE(PyObject *string) +.. cfunction:: Py_ssize_t PyBytes_GET_SIZE(PyObject *string) - Macro form of :cfunc:`PyString_Size` but without error checking. + Macro form of :cfunc:`PyBytes_Size` but without error checking. -.. cfunction:: char* PyString_AsString(PyObject *string) +.. cfunction:: char* PyBytes_AsString(PyObject *string) Return a NUL-terminated representation of the contents of *string*. The pointer refers to the internal buffer of *string*, not a copy. The data must not be modified in any way, unless the string was just created using - ``PyString_FromStringAndSize(NULL, size)``. It must not be deallocated. If + ``PyBytes_FromStringAndSize(NULL, size)``. It must not be deallocated. If *string* is a Unicode object, this function computes the default encoding of *string* and operates on that. If *string* is not a string object at all, - :cfunc:`PyString_AsString` returns *NULL* and raises :exc:`TypeError`. + :cfunc:`PyBytes_AsString` returns *NULL* and raises :exc:`TypeError`. -.. cfunction:: char* PyString_AS_STRING(PyObject *string) +.. cfunction:: char* PyBytes_AS_STRING(PyObject *string) - Macro form of :cfunc:`PyString_AsString` but without error checking. Only + Macro form of :cfunc:`PyBytes_AsString` but without error checking. Only string objects are supported; no Unicode objects should be passed. -.. cfunction:: int PyString_AsStringAndSize(PyObject *obj, char **buffer, Py_ssize_t *length) +.. cfunction:: int PyBytes_AsStringAndSize(PyObject *obj, char **buffer, Py_ssize_t *length) Return a NUL-terminated representation of the contents of the object *obj* through the output variables *buffer* and *length*. @@ -744,13 +744,13 @@ The buffer refers to an internal string buffer of *obj*, not a copy. The data must not be modified in any way, unless the string was just created using - ``PyString_FromStringAndSize(NULL, size)``. It must not be deallocated. If + ``PyBytes_FromStringAndSize(NULL, size)``. It must not be deallocated. If *string* is a Unicode object, this function computes the default encoding of *string* and operates on that. If *string* is not a string object at all, - :cfunc:`PyString_AsStringAndSize` returns ``-1`` and raises :exc:`TypeError`. + :cfunc:`PyBytes_AsStringAndSize` returns ``-1`` and raises :exc:`TypeError`. -.. cfunction:: void PyString_Concat(PyObject **string, PyObject *newpart) +.. cfunction:: void PyBytes_Concat(PyObject **string, PyObject *newpart) Create a new string object in *\*string* containing the contents of *newpart* appended to *string*; the caller will own the new reference. The reference to @@ -759,13 +759,13 @@ *\*string* will be set to *NULL*; the appropriate exception will be set. -.. cfunction:: void PyString_ConcatAndDel(PyObject **string, PyObject *newpart) +.. cfunction:: void PyBytes_ConcatAndDel(PyObject **string, PyObject *newpart) Create a new string object in *\*string* containing the contents of *newpart* appended to *string*. This version decrements the reference count of *newpart*. -.. cfunction:: int _PyString_Resize(PyObject **string, Py_ssize_t newsize) +.. cfunction:: int _PyBytes_Resize(PyObject **string, Py_ssize_t newsize) A way to resize a string object even though it is "immutable". Only use this to build up a brand new string object; don't use this if the string may already be @@ -778,13 +778,13 @@ set to *NULL*, a memory exception is set, and ``-1`` is returned. -.. cfunction:: PyObject* PyString_Format(PyObject *format, PyObject *args) +.. cfunction:: PyObject* PyBytes_Format(PyObject *format, PyObject *args) Return a new string object from *format* and *args*. Analogous to ``format % args``. The *args* argument must be a tuple. -.. cfunction:: void PyString_InternInPlace(PyObject **string) +.. cfunction:: void PyBytes_InternInPlace(PyObject **string) Intern the argument *\*string* in place. The argument must be the address of a pointer variable pointing to a Python string object. If there is an existing @@ -797,15 +797,15 @@ owned it before the call.) -.. cfunction:: PyObject* PyString_InternFromString(const char *v) +.. cfunction:: PyObject* PyBytes_InternFromString(const char *v) - A combination of :cfunc:`PyString_FromString` and - :cfunc:`PyString_InternInPlace`, returning either a new string object that has + A combination of :cfunc:`PyBytes_FromString` and + :cfunc:`PyBytes_InternInPlace`, returning either a new string object that has been interned, or a new ("owned") reference to an earlier interned string object with the same value. -.. cfunction:: PyObject* PyString_Decode(const char *s, Py_ssize_t size, const char *encoding, const char *errors) +.. cfunction:: PyObject* PyBytes_Decode(const char *s, Py_ssize_t size, const char *encoding, const char *errors) Create an object by decoding *size* bytes of the encoded buffer *s* using the codec registered for *encoding*. *encoding* and *errors* have the same meaning @@ -814,7 +814,7 @@ *NULL* if an exception was raised by the codec. -.. cfunction:: PyObject* PyString_AsDecodedObject(PyObject *str, const char *encoding, const char *errors) +.. cfunction:: PyObject* PyBytes_AsDecodedObject(PyObject *str, const char *encoding, const char *errors) Decode a string object by passing it to the codec registered for *encoding* and return the result as Python object. *encoding* and *errors* have the same @@ -823,7 +823,7 @@ if an exception was raised by the codec. -.. cfunction:: PyObject* PyString_AsEncodedObject(PyObject *str, const char *encoding, const char *errors) +.. cfunction:: PyObject* PyBytes_AsEncodedObject(PyObject *str, const char *encoding, const char *errors) Encode a string object using the codec registered for *encoding* and return the result as Python object. *encoding* and *errors* have the same meaning as the @@ -2178,10 +2178,10 @@ .. cfunction:: int PyDict_SetItemString(PyObject *p, const char *key, PyObject *val) - .. index:: single: PyString_FromString() + .. index:: single: PyBytes_FromString() Insert *value* into the dictionary *p* using *key* as a key. *key* should be a - :ctype:`char\*`. The key object is created using ``PyString_FromString(key)``. + :ctype:`char\*`. The key object is created using ``PyBytes_FromString(key)``. Return ``0`` on success or ``-1`` on failure. Modified: python/branches/py3k-grandrenaming/Doc/c-api/exceptions.rst ============================================================================== --- python/branches/py3k-grandrenaming/Doc/c-api/exceptions.rst (original) +++ python/branches/py3k-grandrenaming/Doc/c-api/exceptions.rst Tue Jan 1 20:16:52 2008 @@ -142,7 +142,7 @@ containing format codes, similar to :cfunc:`printf`. The ``width.precision`` before a format code is parsed, but the width part is ignored. - .. % This should be exactly the same as the table in PyString_FromFormat. + .. % This should be exactly the same as the table in PyBytes_FromFormat. .. % One should just refer to the other. .. % The descriptions for %zd and %zu are wrong, but the truth is complicated .. % because not all compilers support the %z width modifier -- we fake it Modified: python/branches/py3k-grandrenaming/Doc/c-api/intro.rst ============================================================================== --- python/branches/py3k-grandrenaming/Doc/c-api/intro.rst (original) +++ python/branches/py3k-grandrenaming/Doc/c-api/intro.rst Tue Jan 1 20:16:52 2008 @@ -210,7 +210,7 @@ t = PyTuple_New(3); PyTuple_SetItem(t, 0, PyLong_FromLong(1L)); PyTuple_SetItem(t, 1, PyLong_FromLong(2L)); - PyTuple_SetItem(t, 2, PyString_FromString("three")); + PyTuple_SetItem(t, 2, PyBytes_FromString("three")); Here, :cfunc:`PyLong_FromLong` returns a new reference which is immediately stolen by :cfunc:`PyTuple_SetItem`. When you want to keep using an object Modified: python/branches/py3k-grandrenaming/Doc/c-api/memory.rst ============================================================================== --- python/branches/py3k-grandrenaming/Doc/c-api/memory.rst (original) +++ python/branches/py3k-grandrenaming/Doc/c-api/memory.rst Tue Jan 1 20:16:52 2008 @@ -61,7 +61,7 @@ if (buf == NULL) return PyErr_NoMemory(); ...Do some I/O operation involving buf... - res = PyString_FromString(buf); + res = PyBytes_FromString(buf); free(buf); /* malloc'ed */ return res; @@ -167,7 +167,7 @@ if (buf == NULL) return PyErr_NoMemory(); /* ...Do some I/O operation involving buf... */ - res = PyString_FromString(buf); + res = PyBytes_FromString(buf); PyMem_Free(buf); /* allocated with PyMem_Malloc */ return res; @@ -179,7 +179,7 @@ if (buf == NULL) return PyErr_NoMemory(); /* ...Do some I/O operation involving buf... */ - res = PyString_FromString(buf); + res = PyBytes_FromString(buf); PyMem_Del(buf); /* allocated with PyMem_New */ return res; Modified: python/branches/py3k-grandrenaming/Doc/c-api/newtypes.rst ============================================================================== --- python/branches/py3k-grandrenaming/Doc/c-api/newtypes.rst (original) +++ python/branches/py3k-grandrenaming/Doc/c-api/newtypes.rst Tue Jan 1 20:16:52 2008 @@ -1631,7 +1631,7 @@ The third slot is :attr:`bf_getsegcount`, with type :ctype:`getsegcountproc`. This slot must not be *NULL* and is used to inform the caller how many segments - the object contains. Simple objects such as :ctype:`PyString_Type` and + the object contains. Simple objects such as :ctype:`PyBytes_Type` and :ctype:`PyBuffer_Type` objects contain a single segment. .. index:: single: PyType_HasFeature() Modified: python/branches/py3k-grandrenaming/Doc/extending/embedding.rst ============================================================================== --- python/branches/py3k-grandrenaming/Doc/extending/embedding.rst (original) +++ python/branches/py3k-grandrenaming/Doc/extending/embedding.rst Tue Jan 1 20:16:52 2008 @@ -158,13 +158,13 @@ interesting part with respect to embedding Python starts with :: Py_Initialize(); - pName = PyString_FromString(argv[1]); + pName = PyBytes_FromString(argv[1]); /* Error checking of pName left out */ pModule = PyImport_Import(pName); After initializing the interpreter, the script is loaded using :cfunc:`PyImport_Import`. This routine needs a Python string as its argument, -which is constructed using the :cfunc:`PyString_FromString` data conversion +which is constructed using the :cfunc:`PyBytes_FromString` data conversion routine. :: pFunc = PyObject_GetAttrString(pModule, argv[2]); Modified: python/branches/py3k-grandrenaming/Doc/extending/newtypes.rst ============================================================================== --- python/branches/py3k-grandrenaming/Doc/extending/newtypes.rst (original) +++ python/branches/py3k-grandrenaming/Doc/extending/newtypes.rst Tue Jan 1 20:16:52 2008 @@ -304,14 +304,14 @@ self = (Noddy *)type->tp_alloc(type, 0); if (self != NULL) { - self->first = PyString_FromString(""); + self->first = PyBytes_FromString(""); if (self->first == NULL) { Py_DECREF(self); return NULL; } - self->last = PyString_FromString(""); + self->last = PyBytes_FromString(""); if (self->last == NULL) { Py_DECREF(self); @@ -466,7 +466,7 @@ PyObject *args, *result; if (format == NULL) { - format = PyString_FromString("%s %s"); + format = PyBytes_FromString("%s %s"); if (format == NULL) return NULL; } @@ -485,7 +485,7 @@ if (args == NULL) return NULL; - result = PyString_Format(format, args); + result = PyBytes_Format(format, args); Py_DECREF(args); return result; @@ -574,7 +574,7 @@ return -1; } - if (! PyString_Check(value)) { + if (! PyBytes_Check(value)) { PyErr_SetString(PyExc_TypeError, "The first attribute value must be a string"); return -1; @@ -1039,7 +1039,7 @@ static PyObject * newdatatype_repr(newdatatypeobject * obj) { - return PyString_FromFormat("Repr-ified_newdatatype{{size:\%d}}", + return PyBytes_FromFormat("Repr-ified_newdatatype{{size:\%d}}", obj->obj_UnderlyingDatatypePtr->size); } @@ -1059,7 +1059,7 @@ static PyObject * newdatatype_str(newdatatypeobject * obj) { - return PyString_FromFormat("Stringified_newdatatype{{size:\%d}}", + return PyBytes_FromFormat("Stringified_newdatatype{{size:\%d}}", obj->obj_UnderlyingDatatypePtr->size); } @@ -1387,11 +1387,11 @@ if (!PyArg_ParseTuple(args, "sss:call", &arg1, &arg2, &arg3)) { return NULL; } - result = PyString_FromFormat( + result = PyBytes_FromFormat( "Returning -- value: [\%d] arg1: [\%s] arg2: [\%s] arg3: [\%s]\n", obj->obj_UnderlyingDatatypePtr->size, arg1, arg2, arg3); - printf("\%s", PyString_AS_STRING(result)); + printf("\%s", PyBytes_AS_STRING(result)); return result; } Modified: python/branches/py3k-grandrenaming/Doc/whatsnew/2.3.rst ============================================================================== --- python/branches/py3k-grandrenaming/Doc/whatsnew/2.3.rst (original) +++ python/branches/py3k-grandrenaming/Doc/whatsnew/2.3.rst Tue Jan 1 20:16:52 2008 @@ -1901,7 +1901,7 @@ long long`. * A new function, :cfunc:`PyObject_DelItemString(mapping, char \*key)` was added - as shorthand for ``PyObject_DelItem(mapping, PyString_New(key))``. + as shorthand for ``PyObject_DelItem(mapping, PyBytes_New(key))``. * File objects now manage their internal string buffer differently, increasing it exponentially when needed. This results in the benchmark tests in Modified: python/branches/py3k-grandrenaming/Include/py_curses.h ============================================================================== --- python/branches/py3k-grandrenaming/Include/py_curses.h (original) +++ python/branches/py3k-grandrenaming/Include/py_curses.h Tue Jan 1 20:16:52 2008 @@ -146,7 +146,7 @@ static PyObject *PyCurses_ ## X (PyObject *self) \ { \ PyCursesInitialised \ - return PyString_FromString(X()); } + return PyBytes_FromString(X()); } #define NoArgTrueFalseFunction(X) \ static PyObject *PyCurses_ ## X (PyObject *self) \ Modified: python/branches/py3k-grandrenaming/Include/pyport.h ============================================================================== --- python/branches/py3k-grandrenaming/Include/pyport.h (original) +++ python/branches/py3k-grandrenaming/Include/pyport.h Tue Jan 1 20:16:52 2008 @@ -120,9 +120,9 @@ * all platforms (Python interprets the format string itself, and does whatever * the platform C requires to convert a size_t/Py_ssize_t argument): * - * PyString_FromFormat + * PyBytes_FromFormat * PyErr_Format - * PyString_FromFormatV + * PyBytes_FromFormatV * PyUnicode_FromFormatV * * Lower-level uses require that you interpolate the correct format modifier Modified: python/branches/py3k-grandrenaming/Include/pythonrun.h ============================================================================== --- python/branches/py3k-grandrenaming/Include/pythonrun.h (original) +++ python/branches/py3k-grandrenaming/Include/pythonrun.h Tue Jan 1 20:16:52 2008 @@ -137,7 +137,7 @@ PyAPI_FUNC(void) PyTuple_Fini(void); PyAPI_FUNC(void) PyList_Fini(void); PyAPI_FUNC(void) PySet_Fini(void); -PyAPI_FUNC(void) PyString_Fini(void); +PyAPI_FUNC(void) PyBytes_Fini(void); PyAPI_FUNC(void) PyByteArray_Fini(void); PyAPI_FUNC(void) PyFloat_Fini(void); PyAPI_FUNC(void) PyOS_FiniInterrupts(void); Modified: python/branches/py3k-grandrenaming/Include/stringobject.h ============================================================================== --- python/branches/py3k-grandrenaming/Include/stringobject.h (original) +++ python/branches/py3k-grandrenaming/Include/stringobject.h Tue Jan 1 20:16:52 2008 @@ -39,47 +39,47 @@ */ } PyStringObject; -PyAPI_DATA(PyTypeObject) PyString_Type; +PyAPI_DATA(PyTypeObject) PyBytes_Type; PyAPI_DATA(PyTypeObject) PyStringIter_Type; -#define PyString_Check(op) \ +#define PyBytes_Check(op) \ PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_STRING_SUBCLASS) -#define PyString_CheckExact(op) (Py_TYPE(op) == &PyString_Type) +#define PyBytes_CheckExact(op) (Py_TYPE(op) == &PyBytes_Type) -PyAPI_FUNC(PyObject *) PyString_FromStringAndSize(const char *, Py_ssize_t); -PyAPI_FUNC(PyObject *) PyString_FromString(const char *); -PyAPI_FUNC(PyObject *) PyString_FromFormatV(const char*, va_list) +PyAPI_FUNC(PyObject *) PyBytes_FromStringAndSize(const char *, Py_ssize_t); +PyAPI_FUNC(PyObject *) PyBytes_FromString(const char *); +PyAPI_FUNC(PyObject *) PyBytes_FromFormatV(const char*, va_list) Py_GCC_ATTRIBUTE((format(printf, 1, 0))); -PyAPI_FUNC(PyObject *) PyString_FromFormat(const char*, ...) +PyAPI_FUNC(PyObject *) PyBytes_FromFormat(const char*, ...) Py_GCC_ATTRIBUTE((format(printf, 1, 2))); -PyAPI_FUNC(Py_ssize_t) PyString_Size(PyObject *); -PyAPI_FUNC(char *) PyString_AsString(PyObject *); -PyAPI_FUNC(PyObject *) PyString_Repr(PyObject *, int); -PyAPI_FUNC(void) PyString_Concat(PyObject **, PyObject *); -PyAPI_FUNC(void) PyString_ConcatAndDel(PyObject **, PyObject *); -PyAPI_FUNC(int) _PyString_Resize(PyObject **, Py_ssize_t); -PyAPI_FUNC(PyObject *) PyString_Format(PyObject *, PyObject *); -PyAPI_FUNC(PyObject *) _PyString_FormatLong(PyObject*, int, int, +PyAPI_FUNC(Py_ssize_t) PyBytes_Size(PyObject *); +PyAPI_FUNC(char *) PyBytes_AsString(PyObject *); +PyAPI_FUNC(PyObject *) PyBytes_Repr(PyObject *, int); +PyAPI_FUNC(void) PyBytes_Concat(PyObject **, PyObject *); +PyAPI_FUNC(void) PyBytes_ConcatAndDel(PyObject **, PyObject *); +PyAPI_FUNC(int) _PyBytes_Resize(PyObject **, Py_ssize_t); +PyAPI_FUNC(PyObject *) PyBytes_Format(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyBytes_FormatLong(PyObject*, int, int, int, char**, int*); -PyAPI_FUNC(PyObject *) PyString_DecodeEscape(const char *, Py_ssize_t, +PyAPI_FUNC(PyObject *) PyBytes_DecodeEscape(const char *, Py_ssize_t, const char *, Py_ssize_t, const char *); /* Macro, trading safety for speed */ -#define PyString_AS_STRING(op) (assert(PyString_Check(op)), \ +#define PyBytes_AS_STRING(op) (assert(PyBytes_Check(op)), \ (((PyStringObject *)(op))->ob_sval)) -#define PyString_GET_SIZE(op) (assert(PyString_Check(op)),Py_SIZE(op)) +#define PyBytes_GET_SIZE(op) (assert(PyBytes_Check(op)),Py_SIZE(op)) -/* _PyString_Join(sep, x) is like sep.join(x). sep must be PyStringObject*, +/* _PyBytes_Join(sep, x) is like sep.join(x). sep must be PyStringObject*, x must be an iterable object. */ -PyAPI_FUNC(PyObject *) _PyString_Join(PyObject *sep, PyObject *x); +PyAPI_FUNC(PyObject *) _PyBytes_Join(PyObject *sep, PyObject *x); /* Provides access to the internal data buffer and size of a string object or the default encoded version of an Unicode object. Passing NULL as *len parameter will force the string buffer to be 0-terminated (passing a string with embedded NULL characters will cause an exception). */ -PyAPI_FUNC(int) PyString_AsStringAndSize( +PyAPI_FUNC(int) PyBytes_AsStringAndSize( register PyObject *obj, /* string or Unicode object */ register char **s, /* pointer to buffer variable */ register Py_ssize_t *len /* pointer to length variable or NULL Modified: python/branches/py3k-grandrenaming/Mac/Modules/MacOS.c ============================================================================== --- python/branches/py3k-grandrenaming/Mac/Modules/MacOS.c (original) +++ python/branches/py3k-grandrenaming/Mac/Modules/MacOS.c Tue Jan 1 20:16:52 2008 @@ -77,17 +77,17 @@ if (!PyArg_ParseTuple(args, "l", &n)) return NULL; - v = PyString_FromStringAndSize((char *)NULL, n); + v = PyBytes_FromStringAndSize((char *)NULL, n); if (v == NULL) return NULL; - err = FSRead(self->fRefNum, &n, PyString_AsString(v)); + err = FSRead(self->fRefNum, &n, PyBytes_AsString(v)); if (err && err != eofErr) { PyMac_Error(err); Py_DECREF(v); return NULL; } - _PyString_Resize(&v, n); + _PyBytes_Resize(&v, n); return v; } @@ -300,8 +300,8 @@ return NULL; if ((err = FSpGetFInfo(&fss, &info)) != noErr) return PyErr_Mac(MacOS_Error, err); - creator = PyString_FromStringAndSize((char *)&info.fdCreator, 4); - type = PyString_FromStringAndSize((char *)&info.fdType, 4); + creator = PyBytes_FromStringAndSize((char *)&info.fdCreator, 4); + type = PyBytes_FromStringAndSize((char *)&info.fdType, 4); res = Py_BuildValue("OO", creator, type); Py_DECREF(creator); Py_DECREF(type); Modified: python/branches/py3k-grandrenaming/Mac/Modules/Nav.c ============================================================================== --- python/branches/py3k-grandrenaming/Mac/Modules/Nav.c (original) +++ python/branches/py3k-grandrenaming/Mac/Modules/Nav.c Tue Jan 1 20:16:52 2008 @@ -139,11 +139,11 @@ NavGetDefaultDialogOptions(opt); while ( PyDict_Next(d, &pos, &key, &value) ) { - if ( !key || !value || !PyString_Check(key) ) { + if ( !key || !value || !PyBytes_Check(key) ) { PyErr_SetString(ErrorObject, "DialogOption has non-string key"); return 0; } - keystr = PyString_AsString(key); + keystr = PyBytes_AsString(key); if( strcmp(keystr, "defaultLocation") == 0 ) { if ( (defaultLocation_storage = PyMem_NEW(AEDesc, 1)) == NULL ) { PyErr_NoMemory(); @@ -928,7 +928,7 @@ /* Add some symbolic constants to the module */ d = PyModule_GetDict(m); - ErrorObject = PyString_FromString("Nav.error"); + ErrorObject = PyBytes_FromString("Nav.error"); PyDict_SetItemString(d, "error", ErrorObject); /* XXXX Add constants here */ Modified: python/branches/py3k-grandrenaming/Mac/Modules/ae/_AEmodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Mac/Modules/ae/_AEmodule.c (original) +++ python/branches/py3k-grandrenaming/Mac/Modules/ae/_AEmodule.c Tue Jan 1 20:16:52 2008 @@ -835,9 +835,9 @@ OSErr err; size = AEGetDescDataSize(&self->ob_itself); - if ( (res = PyString_FromStringAndSize(NULL, size)) == NULL ) + if ( (res = PyBytes_FromStringAndSize(NULL, size)) == NULL ) return NULL; - if ( (ptr = PyString_AS_STRING(res)) == NULL ) + if ( (ptr = PyBytes_AS_STRING(res)) == NULL ) return NULL; if ( (err=AEGetDescData(&self->ob_itself, ptr, size)) < 0 ) return PyMac_Error(err); Modified: python/branches/py3k-grandrenaming/Mac/Modules/cf/_CFmodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Mac/Modules/cf/_CFmodule.c (original) +++ python/branches/py3k-grandrenaming/Mac/Modules/cf/_CFmodule.c Tue Jan 1 20:16:52 2008 @@ -1322,10 +1322,10 @@ { if (v == Py_None) { *p_itself = NULL; return 1; } - if (PyString_Check(v)) { + if (PyBytes_Check(v)) { char *cStr; Py_ssize_t cLen; - if( PyString_AsStringAndSize(v, &cStr, &cLen) < 0 ) return 0; + if( PyBytes_AsStringAndSize(v, &cStr, &cLen) < 0 ) return 0; *p_itself = CFDataCreate((CFAllocatorRef)NULL, (unsigned char *)cStr, cLen); return 1; } @@ -1400,7 +1400,7 @@ int size = CFDataGetLength(_self->ob_itself); char *data = (char *)CFDataGetBytePtr(_self->ob_itself); - _res = (PyObject *)PyString_FromStringAndSize(data, size); + _res = (PyObject *)PyBytes_FromStringAndSize(data, size); return _res; } @@ -1816,7 +1816,7 @@ { if (v == Py_None) { *p_itself = NULL; return 1; } - if (PyString_Check(v)) { + if (PyBytes_Check(v)) { char *cStr; if (!PyArg_Parse(v, "es", "ascii", &cStr)) return 0; @@ -2337,7 +2337,7 @@ if( data == NULL ) return PyErr_NoMemory(); if ( CFStringGetCString(_self->ob_itself, data, size, 0) ) { - _res = (PyObject *)PyString_FromString(data); + _res = (PyObject *)PyBytes_FromString(data); } else { PyErr_SetString(PyExc_RuntimeError, "CFStringGetCString could not fit the string"); _res = NULL; Modified: python/branches/py3k-grandrenaming/Mac/Modules/cf/pycfbridge.c ============================================================================== --- python/branches/py3k-grandrenaming/Mac/Modules/cf/pycfbridge.c (original) +++ python/branches/py3k-grandrenaming/Mac/Modules/cf/pycfbridge.c Tue Jan 1 20:16:52 2008 @@ -146,7 +146,7 @@ int PyCF_Python2CF(PyObject *src, CFTypeRef *dst) { - if (PyString_Check(src) || PyUnicode_Check(src)) + if (PyBytes_Check(src) || PyUnicode_Check(src)) return PyCF_Python2CF_simple(src, dst); if (PySequence_Check(src)) return PyCF_Python2CF_sequence(src, (CFArrayRef *)dst); @@ -249,7 +249,7 @@ return (*dst != NULL); } #endif - if (PyString_Check(src) || PyUnicode_Check(src)) + if (PyBytes_Check(src) || PyUnicode_Check(src)) return PyCF_Python2CF_string(src, (CFStringRef *)dst); if (PyBool_Check(src)) { if (src == Py_True) @@ -281,7 +281,7 @@ CFIndex size; UniChar *unichars; - if (PyString_Check(src)) { + if (PyBytes_Check(src)) { if (!PyArg_Parse(src, "es", "ascii", &chars)) return 0; /* This error is more descriptive than the general one below */ *dst = CFStringCreateWithCString((CFAllocatorRef)NULL, chars, kCFStringEncodingASCII); Modified: python/branches/py3k-grandrenaming/Mac/Modules/file/_Filemodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Mac/Modules/file/_Filemodule.c (original) +++ python/branches/py3k-grandrenaming/Mac/Modules/file/_Filemodule.c Tue Jan 1 20:16:52 2008 @@ -913,7 +913,7 @@ size = GetHandleSize((Handle)self->ob_itself); HLock((Handle)self->ob_itself); - rv = PyString_FromStringAndSize(*(Handle)self->ob_itself, size); + rv = PyBytes_FromStringAndSize(*(Handle)self->ob_itself, size); HUnlock((Handle)self->ob_itself); return rv; @@ -1369,7 +1369,7 @@ static PyObject *FSSpec_get_data(FSSpecObject *self, void *closure) { - return PyString_FromStringAndSize((char *)&self->ob_itself, sizeof(self->ob_itself)); + return PyBytes_FromStringAndSize((char *)&self->ob_itself, sizeof(self->ob_itself)); } #define FSSpec_set_data NULL @@ -1921,7 +1921,7 @@ static PyObject *FSRef_get_data(FSRefObject *self, void *closure) { - return PyString_FromStringAndSize((char *)&self->ob_itself, sizeof(self->ob_itself)); + return PyBytes_FromStringAndSize((char *)&self->ob_itself, sizeof(self->ob_itself)); } #define FSRef_set_data NULL @@ -3033,7 +3033,7 @@ if (!PyArg_ParseTuple(_args, "O", &obj)) return NULL; - if (PyString_Check(obj) || PyUnicode_Check(obj)) + if (PyBytes_Check(obj) || PyUnicode_Check(obj)) return PyUnicode_FromObject(obj); _res = PyObject_CallMethod(obj, "as_pathname", NULL); return _res; @@ -3192,7 +3192,7 @@ } /* On OSX we now try a pathname */ - if ( PyString_Check(v) || PyUnicode_Check(v)) { + if ( PyBytes_Check(v) || PyUnicode_Check(v)) { unsigned char *path = NULL; if (!PyArg_Parse(v, "et", Py_FileSystemDefaultEncoding, &path)) return 0; Modified: python/branches/py3k-grandrenaming/Mac/Modules/qd/_Qdmodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Mac/Modules/qd/_Qdmodule.c (original) +++ python/branches/py3k-grandrenaming/Mac/Modules/qd/_Qdmodule.c Tue Jan 1 20:16:52 2008 @@ -1456,7 +1456,7 @@ if ( !PyArg_ParseTuple(_args, "ii", &from, &length) ) return NULL; cp = _self->ob_itself->baseAddr+from; - _res = PyString_FromStringAndSize(cp, length); + _res = PyBytes_FromStringAndSize(cp, length); return _res; } @@ -1509,14 +1509,14 @@ static PyObject *BMObj_get_bitmap_data(BitMapObject *self, void *closure) { - return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(BitMap)); + return PyBytes_FromStringAndSize((char *)self->ob_itself, sizeof(BitMap)); } #define BMObj_set_bitmap_data NULL static PyObject *BMObj_get_pixmap_data(BitMapObject *self, void *closure) { - return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(PixMap)); + return PyBytes_FromStringAndSize((char *)self->ob_itself, sizeof(PixMap)); } #define BMObj_set_pixmap_data NULL @@ -6498,10 +6498,10 @@ int rowbytes; char *data; - if ( !PyArg_ParseTuple(_args, "O!iO&", &PyString_Type, &source, &rowbytes, PyMac_GetRect, + if ( !PyArg_ParseTuple(_args, "O!iO&", &PyBytes_Type, &source, &rowbytes, PyMac_GetRect, &bounds) ) return NULL; - data = PyString_AsString(source); + data = PyBytes_AsString(source); if ((ptr=(BitMap *)malloc(sizeof(BitMap))) == NULL ) return PyErr_NoMemory(); ptr->baseAddr = (Ptr)data; @@ -6525,15 +6525,15 @@ BitMap *ptr; PyObject *source; - if ( !PyArg_ParseTuple(_args, "O!", &PyString_Type, &source) ) + if ( !PyArg_ParseTuple(_args, "O!", &PyBytes_Type, &source) ) return NULL; - if ( PyString_Size(source) != sizeof(BitMap) && PyString_Size(source) != sizeof(PixMap) ) { + if ( PyBytes_Size(source) != sizeof(BitMap) && PyBytes_Size(source) != sizeof(PixMap) ) { PyErr_Format(PyExc_TypeError, "Argument size was %ld, should be %lu (sizeof BitMap) or %lu (sizeof PixMap)", - PyString_Size(source), sizeof(BitMap), sizeof(PixMap)); + PyBytes_Size(source), sizeof(BitMap), sizeof(PixMap)); return NULL; } - ptr = (BitMapPtr)PyString_AsString(source); + ptr = (BitMapPtr)PyBytes_AsString(source); if ( (_res = BMObj_New(ptr)) == NULL ) { return NULL; } Modified: python/branches/py3k-grandrenaming/Mac/Modules/qdoffs/_Qdoffsmodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Mac/Modules/qdoffs/_Qdoffsmodule.c (original) +++ python/branches/py3k-grandrenaming/Mac/Modules/qdoffs/_Qdoffsmodule.c Tue Jan 1 20:16:52 2008 @@ -607,7 +607,7 @@ if ( !PyArg_ParseTuple(_args, "O&ii", ResObj_Convert, &pm, &from, &length) ) return NULL; cp = GetPixBaseAddr(pm)+from; - _res = PyString_FromStringAndSize(cp, length); + _res = PyBytes_FromStringAndSize(cp, length); return _res; } Modified: python/branches/py3k-grandrenaming/Mac/Modules/res/_Resmodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Mac/Modules/res/_Resmodule.c (original) +++ python/branches/py3k-grandrenaming/Mac/Modules/res/_Resmodule.c Tue Jan 1 20:16:52 2008 @@ -520,7 +520,7 @@ state = HGetState(self->ob_itself); HLock(self->ob_itself); - res = PyString_FromStringAndSize( + res = PyBytes_FromStringAndSize( *self->ob_itself, GetHandleSize(self->ob_itself)); HUnlock(self->ob_itself); @@ -537,10 +537,10 @@ if ( v == NULL ) return -1; - if ( !PyString_Check(v) ) + if ( !PyBytes_Check(v) ) return -1; - size = PyString_Size(v); - data = PyString_AsString(v); + size = PyBytes_Size(v); + data = PyBytes_AsString(v); /* XXXX Do I need the GetState/SetState calls? */ SetHandleSize(self->ob_itself, size); if ( MemError()) Modified: python/branches/py3k-grandrenaming/Mac/Modules/scrap/_Scrapmodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Mac/Modules/scrap/_Scrapmodule.c (original) +++ python/branches/py3k-grandrenaming/Mac/Modules/scrap/_Scrapmodule.c Tue Jan 1 20:16:52 2008 @@ -105,12 +105,12 @@ flavorType, &byteCount); if (_err != noErr) return PyMac_Error(_err); - _res = PyString_FromStringAndSize(NULL, (int)byteCount); + _res = PyBytes_FromStringAndSize(NULL, (int)byteCount); if ( _res == NULL ) return NULL; _err = GetScrapFlavorData(_self->ob_itself, flavorType, &byteCount, - PyString_AS_STRING(_res)); + PyBytes_AS_STRING(_res)); if (_err != noErr) { Py_XDECREF(_res); return PyMac_Error(_err); Modified: python/branches/py3k-grandrenaming/Mac/Modules/snd/_Sndihooks.c ============================================================================== --- python/branches/py3k-grandrenaming/Mac/Modules/snd/_Sndihooks.c (original) +++ python/branches/py3k-grandrenaming/Mac/Modules/snd/_Sndihooks.c Tue Jan 1 20:16:52 2008 @@ -500,7 +500,7 @@ /* Add some symbolic constants to the module */ d = PyModule_GetDict(m); - ErrorObject = PyString_FromString("Sndihooks.error"); + ErrorObject = PyBytes_FromString("Sndihooks.error"); PyDict_SetItemString(d, "error", ErrorObject); /* XXXX Add constants here */ Modified: python/branches/py3k-grandrenaming/Modules/_bsddb.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/_bsddb.c (original) +++ python/branches/py3k-grandrenaming/Modules/_bsddb.c Tue Jan 1 20:16:52 2008 @@ -1171,7 +1171,7 @@ else if (PyLong_Check(result)) { retval = PyLong_AsLong(result); } - else if (PyByteArray_Check(result) || PyString_Check(result)) { + else if (PyByteArray_Check(result) || PyBytes_Check(result)) { char* data; Py_ssize_t size; @@ -1180,7 +1180,7 @@ if (PyByteArray_Check(result)) data = PyByteArray_AS_STRING(result); else - data = PyString_AS_STRING(result); + data = PyBytes_AS_STRING(result); secKey->flags = DB_DBT_APPMALLOC; /* DB will free */ secKey->data = malloc(size); /* TODO, check this */ if (secKey->data) { @@ -1520,7 +1520,7 @@ retval = Py_BuildValue("y#y#", key.data, key.size, data.data, data.size); else /* return just the data */ - retval = PyString_FromStringAndSize((char*)data.data, data.size); + retval = PyBytes_FromStringAndSize((char*)data.data, data.size); free_dbt(&data); } FREE_DBT_VIEW(key, keyobj, key_buf_view); @@ -1590,13 +1590,13 @@ else if (!err) { PyObject *pkeyObj; PyObject *dataObj; - dataObj = PyString_FromStringAndSize(data.data, data.size); + dataObj = PyBytes_FromStringAndSize(data.data, data.size); if (self->primaryDBType == DB_RECNO || self->primaryDBType == DB_QUEUE) pkeyObj = PyLong_FromLong(*(int *)pkey.data); else - pkeyObj = PyString_FromStringAndSize(pkey.data, pkey.size); + pkeyObj = PyBytes_FromStringAndSize(pkey.data, pkey.size); if (flags & DB_SET_RECNO) /* return key , pkey and data */ { @@ -1605,7 +1605,7 @@ if (type == DB_RECNO || type == DB_QUEUE) keyObj = PyLong_FromLong(*(int *)key.data); else - keyObj = PyString_FromStringAndSize(key.data, key.size); + keyObj = PyBytes_FromStringAndSize(key.data, key.size); #if (PY_VERSION_HEX >= 0x02040000) retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj); #else @@ -1733,7 +1733,7 @@ /* XXX(nnorwitz): can we do: retval = dataobj; Py_INCREF(retval); */ /* XXX(gps) I think not: buffer API input vs. bytes object output. */ /* XXX(guido) But what if the input is PyString? */ - retval = PyString_FromStringAndSize((char*)data.data, data.size); + retval = PyBytes_FromStringAndSize((char*)data.data, data.size); /* Even though the flags require DB_DBT_MALLOC, data is not always allocated. 4.4: allocated, 4.5: *not* allocated. :-( */ @@ -2777,7 +2777,7 @@ retval = NULL; } else { - retval = PyString_FromStringAndSize((char*)data.data, data.size); + retval = PyBytes_FromStringAndSize((char*)data.data, data.size); free_dbt(&data); } @@ -2932,7 +2932,7 @@ case DB_BTREE: case DB_HASH: default: - item = PyString_FromStringAndSize((char*)key.data, key.size); + item = PyBytes_FromStringAndSize((char*)key.data, key.size); break; case DB_RECNO: case DB_QUEUE: @@ -2942,7 +2942,7 @@ break; case _VALUES_LIST: - item = PyString_FromStringAndSize((char*)data.data, data.size); + item = PyBytes_FromStringAndSize((char*)data.data, data.size); break; case _ITEMS_LIST: @@ -3290,13 +3290,13 @@ else { PyObject *pkeyObj; PyObject *dataObj; - dataObj = PyString_FromStringAndSize(data.data, data.size); + dataObj = PyBytes_FromStringAndSize(data.data, data.size); if (self->mydb->primaryDBType == DB_RECNO || self->mydb->primaryDBType == DB_QUEUE) pkeyObj = PyLong_FromLong(*(int *)pkey.data); else - pkeyObj = PyString_FromStringAndSize(pkey.data, pkey.size); + pkeyObj = PyBytes_FromStringAndSize(pkey.data, pkey.size); if (key.data && key.size) /* return key, pkey and data */ { @@ -3305,7 +3305,7 @@ if (type == DB_RECNO || type == DB_QUEUE) keyObj = PyLong_FromLong(*(int *)key.data); else - keyObj = PyString_FromStringAndSize(key.data, key.size); + keyObj = PyBytes_FromStringAndSize(key.data, key.size); retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj); Py_DECREF(keyObj); } @@ -4913,7 +4913,7 @@ MYDB_END_ALLOW_THREADS if (!err) - retval = PyString_FromStringAndSize(key.data, key.size); + retval = PyBytes_FromStringAndSize(key.data, key.size); free_dbt(&key); RETURN_IF_ERR(); Modified: python/branches/py3k-grandrenaming/Modules/_codecsmodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/_codecsmodule.c (original) +++ python/branches/py3k-grandrenaming/Modules/_codecsmodule.c Tue Jan 1 20:16:52 2008 @@ -154,7 +154,7 @@ if (!PyArg_ParseTuple(args, "s#|z:escape_decode", &data, &size, &errors)) return NULL; - return codec_tuple(PyString_DecodeEscape(data, size, errors, 0, NULL), + return codec_tuple(PyBytes_DecodeEscape(data, size, errors, 0, NULL), size); } @@ -170,17 +170,17 @@ PyObject *v; if (!PyArg_ParseTuple(args, "O!|z:escape_encode", - &PyString_Type, &str, &errors)) + &PyBytes_Type, &str, &errors)) return NULL; - size = PyString_GET_SIZE(str); + size = PyBytes_GET_SIZE(str); newsize = 4*size; if (newsize > PY_SSIZE_T_MAX || newsize / 4 != size) { PyErr_SetString(PyExc_OverflowError, "string is too large to encode"); return NULL; } - v = PyString_FromStringAndSize(NULL, newsize); + v = PyBytes_FromStringAndSize(NULL, newsize); if (v == NULL) { return NULL; @@ -188,12 +188,12 @@ else { register Py_ssize_t i; register char c; - register char *p = PyString_AS_STRING(v); + register char *p = PyBytes_AS_STRING(v); for (i = 0; i < size; i++) { /* There's at least enough room for a hex escape */ - assert(newsize - (p - PyString_AS_STRING(v)) >= 4); - c = PyString_AS_STRING(str)[i]; + assert(newsize - (p - PyBytes_AS_STRING(v)) >= 4); + c = PyBytes_AS_STRING(str)[i]; if (c == '\'' || c == '\\') *p++ = '\\', *p++ = c; else if (c == '\t') @@ -212,12 +212,12 @@ *p++ = c; } *p = '\0'; - if (_PyString_Resize(&v, (p - PyString_AS_STRING(v)))) { + if (_PyBytes_Resize(&v, (p - PyBytes_AS_STRING(v)))) { return NULL; } } - return codec_tuple(v, PyString_Size(v)); + return codec_tuple(v, PyBytes_Size(v)); } /* --- Decoder ------------------------------------------------------------ */ @@ -660,7 +660,7 @@ &data, &size, &errors)) return NULL; - return codec_tuple(PyString_FromStringAndSize(data, size), size); + return codec_tuple(PyBytes_FromStringAndSize(data, size), size); } static PyObject * @@ -675,7 +675,7 @@ &data, &size, &errors)) return NULL; - return codec_tuple(PyString_FromStringAndSize(data, size), size); + return codec_tuple(PyBytes_FromStringAndSize(data, size), size); } static PyObject * @@ -694,12 +694,12 @@ if (PyUnicode_Check(obj)) { data = PyUnicode_AS_DATA(obj); size = PyUnicode_GET_DATA_SIZE(obj); - return codec_tuple(PyString_FromStringAndSize(data, size), size); + return codec_tuple(PyBytes_FromStringAndSize(data, size), size); } else { if (PyObject_AsReadBuffer(obj, (const void **)&data, &size)) return NULL; - return codec_tuple(PyString_FromStringAndSize(data, size), size); + return codec_tuple(PyBytes_FromStringAndSize(data, size), size); } } Modified: python/branches/py3k-grandrenaming/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k-grandrenaming/Modules/_ctypes/_ctypes.c Tue Jan 1 20:16:52 2008 @@ -763,7 +763,7 @@ static PyObject * CharArray_get_raw(CDataObject *self) { - return PyString_FromStringAndSize(self->b_ptr, self->b_size); + return PyBytes_FromStringAndSize(self->b_ptr, self->b_size); } static PyObject * @@ -774,7 +774,7 @@ for (i = 0; i < self->b_size; ++i) if (*ptr++ == '\0') break; - return PyString_FromStringAndSize(self->b_ptr, i); + return PyBytes_FromStringAndSize(self->b_ptr, i); } static int @@ -795,14 +795,14 @@ conversion_mode_errors); if (!value) return -1; - } else if (!PyString_Check(value)) { + } else if (!PyBytes_Check(value)) { PyErr_Format(PyExc_TypeError, "str/bytes expected instead of %s instance", Py_TYPE(value)->tp_name); return -1; } else Py_INCREF(value); - size = PyString_GET_SIZE(value); + size = PyBytes_GET_SIZE(value); if (size > self->b_size) { PyErr_SetString(PyExc_ValueError, "string too long"); @@ -810,7 +810,7 @@ return -1; } - ptr = PyString_AS_STRING(value); + ptr = PyBytes_AS_STRING(value); memcpy(self->b_ptr, ptr, size); if (size < self->b_size) self->b_ptr[size] = '\0'; @@ -849,7 +849,7 @@ "can't delete attribute"); return -1; } - if (PyString_Check(value)) { + if (PyBytes_Check(value)) { value = PyUnicode_FromEncodedObject(value, conversion_mode_encoding, conversion_mode_errors); @@ -1122,7 +1122,7 @@ Py_INCREF(Py_None); return Py_None; } - if (PyUnicode_Check(value) || PyString_Check(value)) { + if (PyUnicode_Check(value) || PyBytes_Check(value)) { PyCArgObject *parg; struct fielddesc *fd = getentry("Z"); @@ -1183,7 +1183,7 @@ Py_INCREF(Py_None); return Py_None; } - if (PyString_Check(value) || PyUnicode_Check(value)) { + if (PyBytes_Check(value) || PyUnicode_Check(value)) { PyCArgObject *parg; struct fielddesc *fd = getentry("z"); @@ -1267,7 +1267,7 @@ } /* XXX struni: remove later */ /* string */ - if (PyString_Check(value)) { + if (PyBytes_Check(value)) { PyCArgObject *parg; struct fielddesc *fd = getentry("z"); @@ -1516,8 +1516,8 @@ PyObject *v = _PyUnicode_AsDefaultEncodedString(proto, NULL); if (!v) goto error; - proto_str = PyString_AS_STRING(v); - proto_len = PyString_GET_SIZE(v); + proto_str = PyBytes_AS_STRING(v); + proto_len = PyBytes_GET_SIZE(v); } else { PyErr_SetString(PyExc_TypeError, "class must define a '_type_' string attribute"); @@ -2721,8 +2721,8 @@ return 1; } #endif - if (PyString_Check(obj)) { - *pname = PyString_AS_STRING(obj); + if (PyBytes_Check(obj)) { + *pname = PyBytes_AS_STRING(obj); return *pname ? 1 : 0; } if (PyUnicode_Check(obj)) { @@ -3750,9 +3750,9 @@ char *dest; if (slicelen <= 0) - return PyString_FromStringAndSize("", 0); + return PyBytes_FromStringAndSize("", 0); if (step == 1) { - return PyString_FromStringAndSize(ptr + start, + return PyBytes_FromStringAndSize(ptr + start, slicelen); } dest = (char *)PyMem_Malloc(slicelen); @@ -3765,7 +3765,7 @@ dest[i] = ptr[cur]; } - np = PyString_FromStringAndSize(dest, slicelen); + np = PyBytes_FromStringAndSize(dest, slicelen); PyMem_Free(dest); return np; } @@ -4432,9 +4432,9 @@ char *dest; if (len <= 0) - return PyString_FromStringAndSize("", 0); + return PyBytes_FromStringAndSize("", 0); if (step == 1) { - return PyString_FromStringAndSize(ptr + start, + return PyBytes_FromStringAndSize(ptr + start, len); } dest = (char *)PyMem_Malloc(len); @@ -4443,7 +4443,7 @@ for (cur = start, i = 0; i < len; cur += step, i++) { dest[i] = ptr[cur]; } - np = PyString_FromStringAndSize(dest, len); + np = PyBytes_FromStringAndSize(dest, len); PyMem_Free(dest); return np; } @@ -4678,8 +4678,8 @@ string_at(const char *ptr, int size) { if (size == -1) - return PyString_FromStringAndSize(ptr, strlen(ptr)); - return PyString_FromStringAndSize(ptr, size); + return PyBytes_FromStringAndSize(ptr, strlen(ptr)); + return PyBytes_FromStringAndSize(ptr, size); } static int Modified: python/branches/py3k-grandrenaming/Modules/_ctypes/callbacks.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/_ctypes/callbacks.c (original) +++ python/branches/py3k-grandrenaming/Modules/_ctypes/callbacks.c Tue Jan 1 20:16:52 2008 @@ -42,7 +42,7 @@ if (!py_globals) goto bad; empty_tuple = PyTuple_New(0); if (!empty_tuple) goto bad; - empty_string = PyString_FromString(""); + empty_string = PyBytes_FromString(""); if (!empty_string) goto bad; py_code = PyCode_New( 0, /*int argcount,*/ Modified: python/branches/py3k-grandrenaming/Modules/_ctypes/callproc.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/_ctypes/callproc.c (original) +++ python/branches/py3k-grandrenaming/Modules/_ctypes/callproc.c Tue Jan 1 20:16:52 2008 @@ -507,9 +507,9 @@ return 0; } - if (PyString_Check(obj)) { + if (PyBytes_Check(obj)) { pa->ffi_type = &ffi_type_pointer; - pa->value.p = PyString_AsString(obj); + pa->value.p = PyBytes_AsString(obj); Py_INCREF(obj); pa->keep = obj; return 0; Modified: python/branches/py3k-grandrenaming/Modules/_ctypes/cfield.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/_ctypes/cfield.c (original) +++ python/branches/py3k-grandrenaming/Modules/_ctypes/cfield.c Tue Jan 1 20:16:52 2008 @@ -1162,16 +1162,16 @@ conversion_mode_errors); if (value == NULL) return NULL; - if (PyString_GET_SIZE(value) != 1) { + if (PyBytes_GET_SIZE(value) != 1) { Py_DECREF(value); goto error; } - *(char *)ptr = PyString_AS_STRING(value)[0]; + *(char *)ptr = PyBytes_AS_STRING(value)[0]; Py_DECREF(value); _RET(value); } - if (PyString_Check(value) && PyString_GET_SIZE(value) == 1) { - *(char *)ptr = PyString_AS_STRING(value)[0]; + if (PyBytes_Check(value) && PyBytes_GET_SIZE(value) == 1) { + *(char *)ptr = PyBytes_AS_STRING(value)[0]; _RET(value); } if (PyByteArray_Check(value) && PyByteArray_GET_SIZE(value) == 1) { @@ -1196,7 +1196,7 @@ static PyObject * c_get(void *ptr, Py_ssize_t size) { - return PyString_FromStringAndSize((char *)ptr, 1); + return PyBytes_FromStringAndSize((char *)ptr, 1); } #ifdef CTYPES_UNICODE @@ -1205,7 +1205,7 @@ u_set(void *ptr, PyObject *value, Py_ssize_t size) { Py_ssize_t len; - if (PyString_Check(value)) { + if (PyBytes_Check(value)) { value = PyUnicode_FromEncodedObject(value, conversion_mode_encoding, conversion_mode_errors); @@ -1280,7 +1280,7 @@ /* It's easier to calculate in characters than in bytes */ length /= sizeof(wchar_t); - if (PyString_Check(value)) { + if (PyBytes_Check(value)) { value = PyUnicode_FromEncodedObject(value, conversion_mode_encoding, conversion_mode_errors); @@ -1336,8 +1336,8 @@ conversion_mode_errors); if (value == NULL) return NULL; - assert(PyString_Check(value)); - } else if(PyString_Check(value)) { + assert(PyBytes_Check(value)); + } else if(PyBytes_Check(value)) { Py_INCREF(value); } else { PyErr_Format(PyExc_TypeError, @@ -1346,7 +1346,7 @@ return NULL; } - data = PyString_AS_STRING(value); + data = PyBytes_AS_STRING(value); if (!data) return NULL; size = strlen(data); /* XXX Why not Py_SIZE(value)? */ @@ -1377,8 +1377,8 @@ Py_INCREF(value); return value; } - if (PyString_Check(value)) { - *(char **)ptr = PyString_AsString(value); + if (PyBytes_Check(value)) { + *(char **)ptr = PyBytes_AsString(value); Py_INCREF(value); return value; } else if (PyUnicode_Check(value)) { @@ -1387,7 +1387,7 @@ conversion_mode_errors); if (str == NULL) return NULL; - *(char **)ptr = PyString_AS_STRING(str); + *(char **)ptr = PyBytes_AS_STRING(str); return str; } else if (PyLong_Check(value)) { #if SIZEOF_VOID_P == SIZEOF_LONG_LONG @@ -1441,7 +1441,7 @@ Py_INCREF(Py_None); return Py_None; } - if (PyString_Check(value)) { + if (PyBytes_Check(value)) { value = PyUnicode_FromEncodedObject(value, conversion_mode_encoding, conversion_mode_errors); @@ -1524,7 +1524,7 @@ /* convert value into a PyUnicodeObject or NULL */ if (Py_None == value) { value = NULL; - } else if (PyString_Check(value)) { + } else if (PyBytes_Check(value)) { value = PyUnicode_FromEncodedObject(value, conversion_mode_encoding, conversion_mode_errors); Modified: python/branches/py3k-grandrenaming/Modules/_cursesmodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/_cursesmodule.c (original) +++ python/branches/py3k-grandrenaming/Modules/_cursesmodule.c Tue Jan 1 20:16:52 2008 @@ -203,9 +203,9 @@ *ch = (chtype) PyLong_AsLongAndOverflow(obj, &overflow); if (overflow) return 0; - } else if(PyString_Check(obj) - && (PyString_Size(obj) == 1)) { - *ch = (chtype) *PyString_AsString(obj); + } else if(PyBytes_Check(obj) + && (PyBytes_Size(obj) == 1)) { + *ch = (chtype) *PyBytes_AsString(obj); } else if (PyUnicode_Check(obj) && PyUnicode_GetSize(obj) == 1) { *ch = (chtype) *PyUnicode_AS_UNICODE(obj); } else { @@ -906,7 +906,7 @@ } if (rtn2 == ERR) rtn[0] = 0; - return PyString_FromString(rtn); + return PyBytes_FromString(rtn); } static PyObject * @@ -1052,7 +1052,7 @@ } if (rtn2 == ERR) rtn[0] = 0; - return PyString_FromString(rtn); + return PyBytes_FromString(rtn); } static PyObject * @@ -1723,7 +1723,7 @@ ch = erasechar(); - return PyString_FromStringAndSize(&ch, 1); + return PyBytes_FromStringAndSize(&ch, 1); } static PyObject * @@ -1801,7 +1801,7 @@ remove(fn); return NULL; } - if (!PyString_Check(data)) { + if (!PyBytes_Check(data)) { PyErr_Format(PyExc_TypeError, "f.read() returned %.100s instead of bytes", data->ob_type->tp_name); @@ -1810,7 +1810,7 @@ remove(fn); return NULL; } - fwrite(PyString_AS_STRING(data), 1, PyString_GET_SIZE(data), fp); + fwrite(PyBytes_AS_STRING(data), 1, PyBytes_GET_SIZE(data), fp); Py_DECREF(data); fseek(fp, 0, 0); win = getwin(fp); @@ -2107,7 +2107,7 @@ } knp = keyname(ch); - return PyString_FromString((knp == NULL) ? "" : (char *)knp); + return PyBytes_FromString((knp == NULL) ? "" : (char *)knp); } #endif @@ -2118,7 +2118,7 @@ ch = killchar(); - return PyString_FromStringAndSize(&ch, 1); + return PyBytes_FromStringAndSize(&ch, 1); } static PyObject * @@ -2489,7 +2489,7 @@ Py_INCREF(Py_None); return Py_None; } - return PyString_FromString( capname ); + return PyBytes_FromString( capname ); } static PyObject * @@ -2513,7 +2513,7 @@ return NULL; } - return PyString_FromString(result); + return PyBytes_FromString(result); } static PyObject * @@ -2543,7 +2543,7 @@ return NULL; } - return PyString_FromString(unctrl(ch)); + return PyBytes_FromString(unctrl(ch)); } static PyObject * @@ -2738,7 +2738,7 @@ PyDict_SetItemString(d, "error", PyCursesError); /* Make the version available */ - v = PyString_FromString(PyCursesVersion); + v = PyBytes_FromString(PyCursesVersion); PyDict_SetItemString(d, "version", v); PyDict_SetItemString(d, "__version__", v); Py_DECREF(v); Modified: python/branches/py3k-grandrenaming/Modules/_elementtree.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/_elementtree.c (original) +++ python/branches/py3k-grandrenaming/Modules/_elementtree.c Tue Jan 1 20:16:52 2008 @@ -152,7 +152,7 @@ switch (PyList_GET_SIZE(list)) { case 0: Py_DECREF(list); - return PyString_FromString(""); + return PyBytes_FromString(""); case 1: result = PyList_GET_ITEM(list, 0); Py_INCREF(result); @@ -715,9 +715,9 @@ } return 0; } - if (PyString_Check(tag)) { - char *p = PyString_AS_STRING(tag); - for (i = 0; i < PyString_GET_SIZE(tag); i++) { + if (PyBytes_Check(tag)) { + char *p = PyBytes_AS_STRING(tag); + for (i = 0; i < PyBytes_GET_SIZE(tag); i++) { if (p[i] == '{') check = 0; else if (p[i] == '}') @@ -785,7 +785,7 @@ if (Element_CheckExact(item) && !PyObject_Compare(item->tag, tag)) { PyObject* text = element_get_text(item); if (text == Py_None) - return PyString_FromString(""); + return PyBytes_FromString(""); Py_XINCREF(text); return text; } @@ -1574,14 +1574,14 @@ Py_INCREF(data); self->data = data; } else { /* more than one item; use a list to collect items */ - if (PyString_CheckExact(self->data) && Py_REFCNT(self->data) == 1 && - PyString_CheckExact(data) && PyString_GET_SIZE(data) == 1) { + if (PyBytes_CheckExact(self->data) && Py_REFCNT(self->data) == 1 && + PyBytes_CheckExact(data) && PyBytes_GET_SIZE(data) == 1) { /* expat often generates single character data sections; handle the most common case by resizing the existing string... */ - Py_ssize_t size = PyString_GET_SIZE(self->data); - if (_PyString_Resize(&self->data, size + 1) < 0) + Py_ssize_t size = PyBytes_GET_SIZE(self->data); + if (_PyBytes_Resize(&self->data, size + 1) < 0) return NULL; - PyString_AS_STRING(self->data)[size] = PyString_AS_STRING(data)[0]; + PyBytes_AS_STRING(self->data)[size] = PyBytes_AS_STRING(data)[0]; } else if (PyList_CheckExact(self->data)) { if (PyList_Append(self->data, data) < 0) return NULL; @@ -1838,7 +1838,7 @@ PyObject* value; /* look the 'raw' name up in the names dictionary */ - key = PyString_FromStringAndSize(string, size); + key = PyBytes_FromStringAndSize(string, size); if (!key) return NULL; @@ -1860,8 +1860,8 @@ break; if (i != size) { /* convert to universal name */ - tag = PyString_FromStringAndSize(NULL, size+1); - p = PyString_AS_STRING(tag); + tag = PyBytes_FromStringAndSize(NULL, size+1); + p = PyBytes_AS_STRING(tag); p[0] = '{'; memcpy(p+1, string, size); size++; @@ -1872,7 +1872,7 @@ } /* decode universal name */ - p = PyString_AS_STRING(tag); + p = PyBytes_AS_STRING(tag); value = PyUnicode_DecodeUTF8(p, size, "strict"); Py_DECREF(tag); if (!value) { @@ -1925,7 +1925,7 @@ } else { PyErr_Format( PyExc_SyntaxError, "undefined entity &%s;: line %ld, column %ld", - PyString_AS_STRING(key), + PyBytes_AS_STRING(key), EXPAT(GetErrorLineNumber)(self->parser), EXPAT(GetErrorColumnNumber)(self->parser) ); @@ -2352,13 +2352,13 @@ return NULL; } - if (!PyString_CheckExact(buffer) || PyString_GET_SIZE(buffer) == 0) { + if (!PyBytes_CheckExact(buffer) || PyBytes_GET_SIZE(buffer) == 0) { Py_DECREF(buffer); break; } res = expat_parse( - self, PyString_AS_STRING(buffer), PyString_GET_SIZE(buffer), 0 + self, PyBytes_AS_STRING(buffer), PyBytes_GET_SIZE(buffer), 0 ); Py_DECREF(buffer); @@ -2420,7 +2420,7 @@ if (event_set == Py_None) { /* default is "end" only */ - target->end_event_obj = PyString_FromString("end"); + target->end_event_obj = PyBytes_FromString("end"); Py_RETURN_NONE; } @@ -2430,9 +2430,9 @@ for (i = 0; i < PyTuple_GET_SIZE(event_set); i++) { PyObject* item = PyTuple_GET_ITEM(event_set, i); char* event; - if (!PyString_Check(item)) + if (!PyBytes_Check(item)) goto error; - event = PyString_AS_STRING(item); + event = PyBytes_AS_STRING(item); if (strcmp(event, "start") == 0) { Py_INCREF(item); target->start_event_obj = item; @@ -2504,7 +2504,7 @@ char buffer[100]; sprintf(buffer, "Expat %d.%d.%d", XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION); - return PyString_FromString(buffer); + return PyBytes_FromString(buffer); } else { PyErr_SetString(PyExc_AttributeError, name); return NULL; Modified: python/branches/py3k-grandrenaming/Modules/_fileio.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/_fileio.c (original) +++ python/branches/py3k-grandrenaming/Modules/_fileio.c Tue Jan 1 20:16:52 2008 @@ -400,14 +400,14 @@ Py_ssize_t total = 0; int n; - result = PyString_FromStringAndSize(NULL, DEFAULT_BUFFER_SIZE); + result = PyBytes_FromStringAndSize(NULL, DEFAULT_BUFFER_SIZE); if (result == NULL) return NULL; while (1) { Py_ssize_t newsize = total + DEFAULT_BUFFER_SIZE; - if (PyString_GET_SIZE(result) < newsize) { - if (_PyString_Resize(&result, newsize) < 0) { + if (PyBytes_GET_SIZE(result) < newsize) { + if (_PyBytes_Resize(&result, newsize) < 0) { if (total == 0) { Py_DECREF(result); return NULL; @@ -419,7 +419,7 @@ Py_BEGIN_ALLOW_THREADS errno = 0; n = read(self->fd, - PyString_AS_STRING(result) + total, + PyBytes_AS_STRING(result) + total, newsize - total); Py_END_ALLOW_THREADS if (n == 0) @@ -438,8 +438,8 @@ total += n; } - if (PyString_GET_SIZE(result) > total) { - if (_PyString_Resize(&result, total) < 0) { + if (PyBytes_GET_SIZE(result) > total) { + if (_PyBytes_Resize(&result, total) < 0) { /* This should never happen, but just in case */ Py_DECREF(result); return NULL; @@ -468,10 +468,10 @@ return fileio_readall(self); } - bytes = PyString_FromStringAndSize(NULL, size); + bytes = PyBytes_FromStringAndSize(NULL, size); if (bytes == NULL) return NULL; - ptr = PyString_AS_STRING(bytes); + ptr = PyBytes_AS_STRING(bytes); Py_BEGIN_ALLOW_THREADS errno = 0; @@ -486,7 +486,7 @@ } if (n != size) { - if (_PyString_Resize(&bytes, n) < 0) { + if (_PyBytes_Resize(&bytes, n) < 0) { Py_DECREF(bytes); return NULL; } Modified: python/branches/py3k-grandrenaming/Modules/_hashopenssl.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/_hashopenssl.c (original) +++ python/branches/py3k-grandrenaming/Modules/_hashopenssl.c Tue Jan 1 20:16:52 2008 @@ -108,7 +108,7 @@ digest_size = EVP_MD_CTX_size(&temp_ctx); EVP_DigestFinal(&temp_ctx, digest, NULL); - retval = PyString_FromStringAndSize((const char *)digest, digest_size); + retval = PyBytes_FromStringAndSize((const char *)digest, digest_size); EVP_MD_CTX_cleanup(&temp_ctx); return retval; } Modified: python/branches/py3k-grandrenaming/Modules/_sqlite/connection.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/_sqlite/connection.c (original) +++ python/branches/py3k-grandrenaming/Modules/_sqlite/connection.c Tue Jan 1 20:16:52 2008 @@ -475,7 +475,7 @@ break; case SQLITE_BLOB: buflen = sqlite3_value_bytes(cur_value); - cur_py_value = PyString_FromStringAndSize( + cur_py_value = PyBytes_FromStringAndSize( sqlite3_value_blob(cur_value), buflen); break; case SQLITE_NULL: Modified: python/branches/py3k-grandrenaming/Modules/_sqlite/connection.h ============================================================================== --- python/branches/py3k-grandrenaming/Modules/_sqlite/connection.h (original) +++ python/branches/py3k-grandrenaming/Modules/_sqlite/connection.h Tue Jan 1 20:16:52 2008 @@ -80,7 +80,7 @@ /* Determines how bytestrings from SQLite are converted to Python objects: * - PyUnicode_Type: Python Unicode objects are constructed from UTF-8 bytestrings * - OptimizedUnicode: Like before, but for ASCII data, only PyStrings are created. - * - PyString_Type: PyStrings are created as-is. + * - PyBytes_Type: PyStrings are created as-is. * - Any custom callable: Any object returned from the callable called with the bytestring * as single parameter. */ Modified: python/branches/py3k-grandrenaming/Modules/_sqlite/cursor.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/_sqlite/cursor.c (original) +++ python/branches/py3k-grandrenaming/Modules/_sqlite/cursor.c Tue Jan 1 20:16:52 2008 @@ -322,7 +322,7 @@ Py_INCREF(Py_None); converted = Py_None; } else { - item = PyString_FromStringAndSize(val_str, nbytes); + item = PyBytes_FromStringAndSize(val_str, nbytes); if (!item) { return NULL; } @@ -365,8 +365,8 @@ colname , val_str); PyErr_SetString(pysqlite_OperationalError, buf); } - } else if (self->connection->text_factory == (PyObject*)&PyString_Type) { - converted = PyString_FromString(val_str); + } else if (self->connection->text_factory == (PyObject*)&PyBytes_Type) { + converted = PyBytes_FromString(val_str); } else if (self->connection->text_factory == (PyObject*)&PyByteArray_Type) { converted = PyByteArray_FromStringAndSize(val_str, strlen(val_str)); } else { @@ -375,7 +375,7 @@ } else { /* coltype == SQLITE_BLOB */ nbytes = sqlite3_column_bytes(self->statement->st, i); - buffer = PyString_FromStringAndSize( + buffer = PyBytes_FromStringAndSize( sqlite3_column_blob(self->statement->st, i), nbytes); if (!buffer) { break; Modified: python/branches/py3k-grandrenaming/Modules/_sre.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/_sre.c (original) +++ python/branches/py3k-grandrenaming/Modules/_sre.c Tue Jan 1 20:16:52 2008 @@ -1709,7 +1709,7 @@ /* determine character size */ size = PyObject_Size(string); - if (PyString_Check(string) || bytes == size) + if (PyBytes_Check(string) || bytes == size) charsize = 1; #if defined(HAVE_UNICODE) else if (bytes == (Py_ssize_t) (size * sizeof(Py_UNICODE))) Modified: python/branches/py3k-grandrenaming/Modules/_ssl.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/_ssl.c (original) +++ python/branches/py3k-grandrenaming/Modules/_ssl.c Tue Jan 1 20:16:52 2008 @@ -599,8 +599,8 @@ /* fprintf(stderr, "RDN level %d, attribute %s: %s\n", entry->set, - PyString_AS_STRING(PyTuple_GET_ITEM(attr, 0)), - PyString_AS_STRING(PyTuple_GET_ITEM(attr, 1))); + PyBytes_AS_STRING(PyTuple_GET_ITEM(attr, 0)), + PyBytes_AS_STRING(PyTuple_GET_ITEM(attr, 1))); */ if (attr == NULL) goto fail1; @@ -987,7 +987,7 @@ return NULL; } /* this is actually an immutable bytes sequence */ - retval = PyString_FromStringAndSize + retval = PyBytes_FromStringAndSize ((const char *) bytes_buf, len); OPENSSL_free(bytes_buf); return retval; @@ -1356,7 +1356,7 @@ } done: if (!buf_passed) { - PyObject *res = PyString_FromStringAndSize( + PyObject *res = PyBytes_FromStringAndSize( PyByteArray_AS_STRING(buf), count); Py_DECREF(buf); return res; Modified: python/branches/py3k-grandrenaming/Modules/_struct.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/_struct.c (original) +++ python/branches/py3k-grandrenaming/Modules/_struct.c Tue Jan 1 20:16:52 2008 @@ -439,7 +439,7 @@ static PyObject * nu_char(const char *p, const formatdef *f) { - return PyString_FromStringAndSize(p, 1); + return PyBytes_FromStringAndSize(p, 1); } static PyObject * @@ -608,12 +608,12 @@ if (v == NULL) return -1; } - if (!PyString_Check(v) || PyString_Size(v) != 1) { + if (!PyBytes_Check(v) || PyBytes_Size(v) != 1) { PyErr_SetString(StructError, "char format requires string of length 1"); return -1; } - *p = *PyString_AsString(v); + *p = *PyBytes_AsString(v); return 0; } @@ -1333,7 +1333,7 @@ char c; Py_ssize_t size, len, num, itemsize, x; - fmt = PyString_AS_STRING(self->s_format); + fmt = PyBytes_AS_STRING(self->s_format); f = whichtable((char **)&fmt); @@ -1501,12 +1501,12 @@ const formatdef *e = code->fmtdef; const char *res = startfrom + code->offset; if (e->format == 's') { - v = PyString_FromStringAndSize(res, code->size); + v = PyBytes_FromStringAndSize(res, code->size); } else if (e->format == 'p') { Py_ssize_t n = *(unsigned char*)res; if (n >= code->size) n = code->size - 1; - v = PyString_FromStringAndSize(res + 1, n); + v = PyBytes_FromStringAndSize(res + 1, n); } else { v = e->unpack(res, e); } @@ -1628,15 +1628,15 @@ if (v == NULL) return -1; } - isstring = PyString_Check(v); + isstring = PyBytes_Check(v); if (!isstring && !PyByteArray_Check(v)) { PyErr_SetString(StructError, "argument for 's' must be a string"); return -1; } if (isstring) { - n = PyString_GET_SIZE(v); - p = PyString_AS_STRING(v); + n = PyBytes_GET_SIZE(v); + p = PyBytes_AS_STRING(v); } else { n = PyByteArray_GET_SIZE(v); @@ -1654,15 +1654,15 @@ if (v == NULL) return -1; } - isstring = PyString_Check(v); + isstring = PyBytes_Check(v); if (!isstring && !PyByteArray_Check(v)) { PyErr_SetString(StructError, "argument for 'p' must be a string"); return -1; } if (isstring) { - n = PyString_GET_SIZE(v); - p = PyString_AS_STRING(v); + n = PyBytes_GET_SIZE(v); + p = PyBytes_AS_STRING(v); } else { n = PyByteArray_GET_SIZE(v); @@ -1714,12 +1714,12 @@ } /* Allocate a new string */ - result = PyString_FromStringAndSize((char *)NULL, soself->s_size); + result = PyBytes_FromStringAndSize((char *)NULL, soself->s_size); if (result == NULL) return NULL; /* Call the guts */ - if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) { + if ( s_pack_internal(soself, args, 0, PyBytes_AS_STRING(result)) != 0 ) { Py_DECREF(result); return NULL; } Modified: python/branches/py3k-grandrenaming/Modules/_tkinter.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/_tkinter.c (original) +++ python/branches/py3k-grandrenaming/Modules/_tkinter.c Tue Jan 1 20:16:52 2008 @@ -335,8 +335,8 @@ static char * AsString(PyObject *value, PyObject *tmp) { - if (PyString_Check(value)) - return PyString_AsString(value); + if (PyBytes_Check(value)) + return PyBytes_AsString(value); else if (PyUnicode_Check(value)) { PyObject *v = PyUnicode_AsUTF8String(value); if (v == NULL) @@ -346,7 +346,7 @@ return NULL; } Py_DECREF(v); - return PyString_AsString(v); + return PyBytes_AsString(v); } else { PyObject *v = PyObject_Str(value); @@ -357,7 +357,7 @@ return NULL; } Py_DECREF(v); - return PyString_AsString(v); + return PyBytes_AsString(v); } } @@ -528,10 +528,10 @@ return result; /* Fall through, returning arg. */ } - else if (PyString_Check(arg)) { + else if (PyBytes_Check(arg)) { int argc; char **argv; - char *list = PyString_AsString(arg); + char *list = PyBytes_AsString(arg); if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) { Py_INCREF(arg); @@ -539,7 +539,7 @@ } Tcl_Free(FREECAST argv); if (argc > 1) - return Split(PyString_AsString(arg)); + return Split(PyBytes_AsString(arg)); /* Fall through, returning arg. */ } Py_INCREF(arg); @@ -866,9 +866,9 @@ long longVal; int overflow; - if (PyString_Check(value)) - return Tcl_NewStringObj(PyString_AS_STRING(value), - PyString_GET_SIZE(value)); + if (PyBytes_Check(value)) + return Tcl_NewStringObj(PyBytes_AS_STRING(value), + PyBytes_GET_SIZE(value)); else if (PyBool_Check(value)) return Tcl_NewBooleanObj(PyObject_IsTrue(value)); else if (PyLong_CheckExact(value) && @@ -959,7 +959,7 @@ if (value->typePtr == app->ByteArrayType) { int size; char *data = (char*)Tcl_GetByteArrayFromObj(value, &size); - return PyString_FromStringAndSize(data, size); + return PyBytes_FromStringAndSize(data, size); } if (value->typePtr == app->DoubleType) { @@ -1417,8 +1417,8 @@ varname_converter(PyObject *in, void *_out) { char **out = (char**)_out; - if (PyString_Check(in)) { - *out = PyString_AsString(in); + if (PyBytes_Check(in)) { + *out = PyBytes_AsString(in); return 1; } if (PyUnicode_Check(in)) { Modified: python/branches/py3k-grandrenaming/Modules/arraymodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/arraymodule.c (original) +++ python/branches/py3k-grandrenaming/Modules/arraymodule.c Tue Jan 1 20:16:52 2008 @@ -1212,14 +1212,14 @@ if (b == NULL) return NULL; - if (!PyString_Check(b)) { + if (!PyBytes_Check(b)) { PyErr_SetString(PyExc_TypeError, "read() didn't return bytes"); Py_DECREF(b); return NULL; } - if (PyString_GET_SIZE(b) != nbytes) { + if (PyBytes_GET_SIZE(b) != nbytes) { PyErr_SetString(PyExc_EOFError, "read() didn't return enough bytes"); Py_DECREF(b); @@ -1263,7 +1263,7 @@ PyObject *bytes, *res; if (i*BLOCKSIZE + size > nbytes) size = nbytes - i*BLOCKSIZE; - bytes = PyString_FromStringAndSize(ptr, size); + bytes = PyBytes_FromStringAndSize(ptr, size); if (bytes == NULL) return NULL; res = PyObject_CallMethod(f, "write", "O", bytes); @@ -1395,7 +1395,7 @@ static PyObject * array_tostring(arrayobject *self, PyObject *unused) { - return PyString_FromStringAndSize(self->ob_item, + return PyBytes_FromStringAndSize(self->ob_item, Py_SIZE(self) * self->ob_descr->itemsize); } @@ -1861,7 +1861,7 @@ if (!(initial == NULL || PyList_Check(initial) || PyByteArray_Check(initial) - || PyString_Check(initial) + || PyBytes_Check(initial) || PyTuple_Check(initial) || ((c=='u') && PyUnicode_Check(initial)))) { it = PyObject_GetIter(initial); @@ -1907,7 +1907,7 @@ } } else if (initial != NULL && (PyByteArray_Check(initial) || - PyString_Check(initial))) { + PyBytes_Check(initial))) { PyObject *t_initial, *v; t_initial = PyTuple_Pack(1, initial); if (t_initial == NULL) { Modified: python/branches/py3k-grandrenaming/Modules/audioop.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/audioop.c (original) +++ python/branches/py3k-grandrenaming/Modules/audioop.c Tue Jan 1 20:16:52 2008 @@ -759,10 +759,10 @@ return 0; } - rv = PyString_FromStringAndSize(NULL, len); + rv = PyBytes_FromStringAndSize(NULL, len); if ( rv == 0 ) return 0; - ncp = (signed char *)PyString_AsString(rv); + ncp = (signed char *)PyBytes_AsString(rv); for ( i=0; i < len; i += size ) { @@ -801,10 +801,10 @@ return 0; } - rv = PyString_FromStringAndSize(NULL, len/2); + rv = PyBytes_FromStringAndSize(NULL, len/2); if ( rv == 0 ) return 0; - ncp = (signed char *)PyString_AsString(rv); + ncp = (signed char *)PyBytes_AsString(rv); for ( i=0; i < len; i += size*2 ) { @@ -846,10 +846,10 @@ return 0; } - rv = PyString_FromStringAndSize(NULL, len*2); + rv = PyBytes_FromStringAndSize(NULL, len*2); if ( rv == 0 ) return 0; - ncp = (signed char *)PyString_AsString(rv); + ncp = (signed char *)PyBytes_AsString(rv); for ( i=0; i < len; i += size ) { @@ -903,10 +903,10 @@ return 0; } - rv = PyString_FromStringAndSize(NULL, len1); + rv = PyBytes_FromStringAndSize(NULL, len1); if ( rv == 0 ) return 0; - ncp = (signed char *)PyString_AsString(rv); + ncp = (signed char *)PyBytes_AsString(rv); for ( i=0; i < len1; i += size ) { if ( size == 1 ) val1 = (int)*CHARP(cp1, i); @@ -949,10 +949,10 @@ return 0; } - rv = PyString_FromStringAndSize(NULL, len); + rv = PyBytes_FromStringAndSize(NULL, len); if ( rv == 0 ) return 0; - ncp = (signed char *)PyString_AsString(rv); + ncp = (signed char *)PyBytes_AsString(rv); for ( i=0; i < len; i += size ) { @@ -985,10 +985,10 @@ return 0; } - rv = PyString_FromStringAndSize(NULL, len); + rv = PyBytes_FromStringAndSize(NULL, len); if ( rv == 0 ) return 0; - ncp = (unsigned char *)PyString_AsString(rv); + ncp = (unsigned char *)PyBytes_AsString(rv); for ( i=0; i < len; i += size ) { if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8; @@ -1023,10 +1023,10 @@ return 0; } - rv = PyString_FromStringAndSize(NULL, (len/size)*size2); + rv = PyBytes_FromStringAndSize(NULL, (len/size)*size2); if ( rv == 0 ) return 0; - ncp = (unsigned char *)PyString_AsString(rv); + ncp = (unsigned char *)PyBytes_AsString(rv); for ( i=0, j=0; i < len; i += size, j += size2 ) { if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8; @@ -1157,7 +1157,7 @@ nbytes / bytes_per_frame != ceiling) str = NULL; else - str = PyString_FromStringAndSize(NULL, nbytes); + str = PyBytes_FromStringAndSize(NULL, nbytes); if (str == NULL) { PyErr_SetString(PyExc_MemoryError, @@ -1165,7 +1165,7 @@ goto exit; } } - ncp = PyString_AsString(str); + ncp = PyBytes_AsString(str); for (;;) { while (d < 0) { @@ -1182,9 +1182,9 @@ goto exit; /* We have checked before that the length * of the string fits into int. */ - len = (int)(ncp - PyString_AsString(str)); - rv = PyString_FromStringAndSize - (PyString_AsString(str), len); + len = (int)(ncp - PyBytes_AsString(str)); + rv = PyBytes_FromStringAndSize + (PyBytes_AsString(str), len); Py_DECREF(str); str = rv; if (str == NULL) @@ -1254,10 +1254,10 @@ return 0; } - rv = PyString_FromStringAndSize(NULL, len/size); + rv = PyBytes_FromStringAndSize(NULL, len/size); if ( rv == 0 ) return 0; - ncp = (unsigned char *)PyString_AsString(rv); + ncp = (unsigned char *)PyBytes_AsString(rv); for ( i=0; i < len; i += size ) { if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8; @@ -1288,10 +1288,10 @@ return 0; } - rv = PyString_FromStringAndSize(NULL, len*size); + rv = PyBytes_FromStringAndSize(NULL, len*size); if ( rv == 0 ) return 0; - ncp = (signed char *)PyString_AsString(rv); + ncp = (signed char *)PyBytes_AsString(rv); for ( i=0; i < len*size; i += size ) { cval = *cp++; @@ -1322,10 +1322,10 @@ return 0; } - rv = PyString_FromStringAndSize(NULL, len/size); + rv = PyBytes_FromStringAndSize(NULL, len/size); if ( rv == 0 ) return 0; - ncp = (unsigned char *)PyString_AsString(rv); + ncp = (unsigned char *)PyBytes_AsString(rv); for ( i=0; i < len; i += size ) { if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8; @@ -1356,10 +1356,10 @@ return 0; } - rv = PyString_FromStringAndSize(NULL, len*size); + rv = PyBytes_FromStringAndSize(NULL, len*size); if ( rv == 0 ) return 0; - ncp = (signed char *)PyString_AsString(rv); + ncp = (signed char *)PyBytes_AsString(rv); for ( i=0; i < len*size; i += size ) { cval = *cp++; @@ -1392,10 +1392,10 @@ return 0; } - str = PyString_FromStringAndSize(NULL, len/(size*2)); + str = PyBytes_FromStringAndSize(NULL, len/(size*2)); if ( str == 0 ) return 0; - ncp = (signed char *)PyString_AsString(str); + ncp = (signed char *)PyBytes_AsString(str); /* Decode state, should have (value, step) */ if ( state == Py_None ) { @@ -1508,10 +1508,10 @@ } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) ) return 0; - str = PyString_FromStringAndSize(NULL, len*size*2); + str = PyBytes_FromStringAndSize(NULL, len*size*2); if ( str == 0 ) return 0; - ncp = (signed char *)PyString_AsString(str); + ncp = (signed char *)PyBytes_AsString(str); step = stepsizeTable[index]; bufferstep = 0; Modified: python/branches/py3k-grandrenaming/Modules/binascii.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/binascii.c (original) +++ python/branches/py3k-grandrenaming/Modules/binascii.c Tue Jan 1 20:16:52 2008 @@ -200,9 +200,9 @@ ascii_len--; /* Allocate the buffer */ - if ( (rv=PyString_FromStringAndSize(NULL, bin_len)) == NULL ) + if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) return NULL; - bin_data = (unsigned char *)PyString_AS_STRING(rv); + bin_data = (unsigned char *)PyBytes_AS_STRING(rv); for( ; bin_len > 0 ; ascii_len--, ascii_data++ ) { /* XXX is it really best to add NULs if there's no more data */ @@ -277,9 +277,9 @@ } /* We're lazy and allocate to much (fixed up later) */ - if ( (rv=PyString_FromStringAndSize(NULL, bin_len*2+2)) == NULL ) + if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len*2+2)) == NULL ) return NULL; - ascii_data = (unsigned char *)PyString_AS_STRING(rv); + ascii_data = (unsigned char *)PyBytes_AS_STRING(rv); /* Store the length */ *ascii_data++ = ' ' + (bin_len & 077); @@ -301,9 +301,9 @@ } *ascii_data++ = '\n'; /* Append a courtesy newline */ - if (_PyString_Resize(&rv, + if (_PyBytes_Resize(&rv, (ascii_data - - (unsigned char *)PyString_AS_STRING(rv))) < 0) { + (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { Py_DECREF(rv); rv = NULL; } @@ -355,9 +355,9 @@ bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */ /* Allocate the buffer */ - if ( (rv=PyString_FromStringAndSize(NULL, bin_len)) == NULL ) + if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) return NULL; - bin_data = (unsigned char *)PyString_AS_STRING(rv); + bin_data = (unsigned char *)PyBytes_AS_STRING(rv); bin_len = 0; for( ; ascii_len > 0; ascii_len--, ascii_data++) { @@ -416,17 +416,17 @@ /* And set string size correctly. If the result string is empty ** (because the input was all invalid) return the shared empty - ** string instead; _PyString_Resize() won't do this for us. + ** string instead; _PyBytes_Resize() won't do this for us. */ if (bin_len > 0) { - if (_PyString_Resize(&rv, bin_len) < 0) { + if (_PyBytes_Resize(&rv, bin_len) < 0) { Py_DECREF(rv); rv = NULL; } } else { Py_DECREF(rv); - rv = PyString_FromStringAndSize("", 0); + rv = PyBytes_FromStringAndSize("", 0); } return rv; } @@ -453,9 +453,9 @@ /* We're lazy and allocate too much (fixed up later). "+3" leaves room for up to two pad characters and a trailing newline. Note that 'b' gets encoded as 'Yg==\n' (1 in, 5 out). */ - if ( (rv=PyString_FromStringAndSize(NULL, bin_len*2 + 3)) == NULL ) + if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len*2 + 3)) == NULL ) return NULL; - ascii_data = (unsigned char *)PyString_AS_STRING(rv); + ascii_data = (unsigned char *)PyBytes_AS_STRING(rv); for( ; bin_len > 0 ; bin_len--, bin_data++ ) { /* Shift the data into our buffer */ @@ -479,9 +479,9 @@ } *ascii_data++ = '\n'; /* Append a courtesy newline */ - if (_PyString_Resize(&rv, + if (_PyBytes_Resize(&rv, (ascii_data - - (unsigned char *)PyString_AS_STRING(rv))) < 0) { + (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { Py_DECREF(rv); rv = NULL; } @@ -507,9 +507,9 @@ /* Allocate a string that is too big (fixed later) Add two to the initial length to prevent interning which would preclude subsequent resizing. */ - if ( (rv=PyString_FromStringAndSize(NULL, len+2)) == NULL ) + if ( (rv=PyBytes_FromStringAndSize(NULL, len+2)) == NULL ) return NULL; - bin_data = (unsigned char *)PyString_AS_STRING(rv); + bin_data = (unsigned char *)PyBytes_AS_STRING(rv); for( ; len > 0 ; len--, ascii_data++ ) { /* Get the byte and look it up */ @@ -543,9 +543,9 @@ Py_DECREF(rv); return NULL; } - if (_PyString_Resize(&rv, + if (_PyBytes_Resize(&rv, (bin_data - - (unsigned char *)PyString_AS_STRING(rv))) < 0) { + (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { Py_DECREF(rv); rv = NULL; } @@ -572,9 +572,9 @@ return NULL; /* Worst case: output is twice as big as input (fixed later) */ - if ( (rv=PyString_FromStringAndSize(NULL, len*2+2)) == NULL ) + if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) return NULL; - out_data = (unsigned char *)PyString_AS_STRING(rv); + out_data = (unsigned char *)PyBytes_AS_STRING(rv); for( in=0; in 0 ; len--, bin_data++ ) { /* Shift into our buffer, and output any 6bits ready */ @@ -644,9 +644,9 @@ leftchar <<= (6-leftbits); *ascii_data++ = table_b2a_hqx[leftchar & 0x3f]; } - if (_PyString_Resize(&rv, + if (_PyBytes_Resize(&rv, (ascii_data - - (unsigned char *)PyString_AS_STRING(rv))) < 0) { + (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { Py_DECREF(rv); rv = NULL; } @@ -668,14 +668,14 @@ /* Empty string is a special case */ if ( in_len == 0 ) - return PyString_FromStringAndSize("", 0); + return PyBytes_FromStringAndSize("", 0); /* Allocate a buffer of reasonable size. Resized when needed */ out_len = in_len*2; - if ( (rv=PyString_FromStringAndSize(NULL, out_len)) == NULL ) + if ( (rv=PyBytes_FromStringAndSize(NULL, out_len)) == NULL ) return NULL; out_len_left = out_len; - out_data = (unsigned char *)PyString_AS_STRING(rv); + out_data = (unsigned char *)PyBytes_AS_STRING(rv); /* ** We need two macros here to get/put bytes and handle @@ -694,9 +694,9 @@ #define OUTBYTE(b) \ do { \ if ( --out_len_left < 0 ) { \ - if (_PyString_Resize(&rv, 2*out_len) < 0) \ + if (_PyBytes_Resize(&rv, 2*out_len) < 0) \ { Py_DECREF(rv); return NULL; } \ - out_data = (unsigned char *)PyString_AS_STRING(rv) \ + out_data = (unsigned char *)PyBytes_AS_STRING(rv) \ + out_len; \ out_len_left = out_len-1; \ out_len = out_len * 2; \ @@ -744,9 +744,9 @@ OUTBYTE(in_byte); } } - if (_PyString_Resize(&rv, + if (_PyBytes_Resize(&rv, (out_data - - (unsigned char *)PyString_AS_STRING(rv))) < 0) { + (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { Py_DECREF(rv); rv = NULL; } @@ -940,10 +940,10 @@ if (!PyArg_ParseTuple(args, "s#:b2a_hex", &argbuf, &arglen)) return NULL; - retval = PyString_FromStringAndSize(NULL, arglen*2); + retval = PyBytes_FromStringAndSize(NULL, arglen*2); if (!retval) return NULL; - retbuf = PyString_AS_STRING(retval); + retbuf = PyBytes_AS_STRING(retval); /* make hex version of string, taken from shamodule.c */ for (i=j=0; i < arglen; i++) { @@ -1000,10 +1000,10 @@ return NULL; } - retval = PyString_FromStringAndSize(NULL, (arglen/2)); + retval = PyBytes_FromStringAndSize(NULL, (arglen/2)); if (!retval) return NULL; - retbuf = PyString_AS_STRING(retval); + retbuf = PyBytes_AS_STRING(retval); for (i=j=0; i < arglen; i += 2) { int top = to_int(Py_CHARMASK(argbuf[i])); @@ -1115,7 +1115,7 @@ out++; } } - if ((rv = PyString_FromStringAndSize((char *)odata, out)) == NULL) { + if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) { PyMem_Free(odata); return NULL; } @@ -1315,7 +1315,7 @@ } } } - if ((rv = PyString_FromStringAndSize((char *)odata, out)) == NULL) { + if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) { PyMem_Free(odata); return NULL; } Modified: python/branches/py3k-grandrenaming/Modules/bz2module.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/bz2module.c (original) +++ python/branches/py3k-grandrenaming/Modules/bz2module.c Tue Jan 1 20:16:52 2008 @@ -34,7 +34,7 @@ #error "Large file support, but neither off_t nor fpos_t is large enough." #endif -#define BUF(v) PyString_AS_STRING(v) +#define BUF(v) PyBytes_AS_STRING(v) #define MODE_CLOSED 0 #define MODE_READ 1 @@ -232,7 +232,7 @@ int bytes_read; total_v_size = n > 0 ? n : 100; - v = PyString_FromStringAndSize((char *)NULL, total_v_size); + v = PyBytes_FromStringAndSize((char *)NULL, total_v_size); if (v == NULL) return NULL; @@ -272,7 +272,7 @@ Py_DECREF(v); return NULL; } - if (_PyString_Resize(&v, total_v_size) < 0) { + if (_PyBytes_Resize(&v, total_v_size) < 0) { return NULL; } buf = BUF(v) + used_v_size; @@ -281,7 +281,7 @@ used_v_size = buf - BUF(v); if (used_v_size != total_v_size) { - if (_PyString_Resize(&v, used_v_size) < 0) { + if (_PyBytes_Resize(&v, used_v_size) < 0) { v = NULL; } } @@ -353,16 +353,16 @@ len = f->f_bufend - f->f_bufptr; if (len == 0) return (PyStringObject *) - PyString_FromStringAndSize(NULL, skip); + PyBytes_FromStringAndSize(NULL, skip); bufptr = memchr(f->f_bufptr, '\n', len); if (bufptr != NULL) { bufptr++; /* Count the '\n' */ len = bufptr - f->f_bufptr; s = (PyStringObject *) - PyString_FromStringAndSize(NULL, skip+len); + PyBytes_FromStringAndSize(NULL, skip+len); if (s == NULL) return NULL; - memcpy(PyString_AS_STRING(s)+skip, f->f_bufptr, len); + memcpy(PyBytes_AS_STRING(s)+skip, f->f_bufptr, len); f->f_bufptr = bufptr; if (bufptr == f->f_bufend) Util_DropReadAhead(f); @@ -376,7 +376,7 @@ PyMem_Free(buf); return NULL; } - memcpy(PyString_AS_STRING(s)+skip, bufptr, len); + memcpy(PyBytes_AS_STRING(s)+skip, bufptr, len); PyMem_Free(buf); } return s; @@ -409,7 +409,7 @@ case MODE_READ: break; case MODE_READ_EOF: - ret = PyString_FromStringAndSize("", 0); + ret = PyBytes_FromStringAndSize("", 0); goto cleanup; case MODE_CLOSED: PyErr_SetString(PyExc_ValueError, @@ -431,7 +431,7 @@ "more than a Python string can hold"); goto cleanup; } - ret = PyString_FromStringAndSize((char *)NULL, buffersize); + ret = PyBytes_FromStringAndSize((char *)NULL, buffersize); if (ret == NULL || buffersize == 0) goto cleanup; bytesread = 0; @@ -456,7 +456,7 @@ } if (bytesrequested < 0) { buffersize = Util_NewBufferSize(buffersize); - if (_PyString_Resize(&ret, buffersize) < 0) { + if (_PyBytes_Resize(&ret, buffersize) < 0) { ret = NULL; goto cleanup; } @@ -465,7 +465,7 @@ } } if (bytesread != buffersize) { - if (_PyString_Resize(&ret, bytesread) < 0) { + if (_PyBytes_Resize(&ret, bytesread) < 0) { ret = NULL; } } @@ -498,7 +498,7 @@ case MODE_READ: break; case MODE_READ_EOF: - ret = PyString_FromStringAndSize("", 0); + ret = PyBytes_FromStringAndSize("", 0); goto cleanup; case MODE_CLOSED: PyErr_SetString(PyExc_ValueError, @@ -511,7 +511,7 @@ } if (sizehint == 0) - ret = PyString_FromStringAndSize("", 0); + ret = PyBytes_FromStringAndSize("", 0); else ret = Util_GetLine(self, (sizehint < 0) ? 0 : sizehint); @@ -604,20 +604,20 @@ } if (big_buffer == NULL) { /* Create the big buffer */ - big_buffer = PyString_FromStringAndSize( + big_buffer = PyBytes_FromStringAndSize( NULL, buffersize); if (big_buffer == NULL) goto error; - buffer = PyString_AS_STRING(big_buffer); + buffer = PyBytes_AS_STRING(big_buffer); memcpy(buffer, small_buffer, nfilled); } else { /* Grow the big buffer */ - if (_PyString_Resize(&big_buffer, buffersize) < 0){ + if (_PyBytes_Resize(&big_buffer, buffersize) < 0){ big_buffer = NULL; goto error; } - buffer = PyString_AS_STRING(big_buffer); + buffer = PyBytes_AS_STRING(big_buffer); } continue; } @@ -626,7 +626,7 @@ while (p != NULL) { /* Process complete lines */ p++; - line = PyString_FromStringAndSize(q, p-q); + line = PyBytes_FromStringAndSize(q, p-q); if (line == NULL) goto error; err = PyList_Append(list, line); @@ -649,7 +649,7 @@ } if (nfilled != 0) { /* Partial last line */ - line = PyString_FromStringAndSize(buffer, nfilled); + line = PyBytes_FromStringAndSize(buffer, nfilled); if (line == NULL) goto error; if (sizehint > 0) { @@ -659,7 +659,7 @@ Py_DECREF(line); goto error; } - PyString_Concat(&line, rest); + PyBytes_Concat(&line, rest); Py_DECREF(rest); if (line == NULL) goto error; @@ -812,7 +812,7 @@ could potentially execute Python code. */ for (i = 0; i < j; i++) { PyObject *v = PyList_GET_ITEM(list, i); - if (!PyString_Check(v)) { + if (!PyBytes_Check(v)) { const char *buffer; Py_ssize_t len; if (PyObject_AsCharBuffer(v, &buffer, &len)) { @@ -823,7 +823,7 @@ "bytes objects"); goto error; } - line = PyString_FromStringAndSize(buffer, + line = PyBytes_FromStringAndSize(buffer, len); if (line == NULL) goto error; @@ -837,9 +837,9 @@ Py_BEGIN_ALLOW_THREADS for (i = 0; i < j; i++) { line = PyList_GET_ITEM(list, i); - len = PyString_GET_SIZE(line); + len = PyBytes_GET_SIZE(line); BZ2_bzWrite (&bzerror, self->fp, - PyString_AS_STRING(line), len); + PyBytes_AS_STRING(line), len); if (bzerror != BZ_OK) { Py_BLOCK_THREADS Util_CatchBZ2Error(bzerror); @@ -1270,7 +1270,7 @@ } ret = Util_ReadAheadGetLineSkip(self, 0, READAHEAD_BUFSIZE); RELEASE_LOCK(self); - if (ret == NULL || PyString_GET_SIZE(ret) == 0) { + if (ret == NULL || PyBytes_GET_SIZE(ret) == 0) { Py_XDECREF(ret); return NULL; } @@ -1363,7 +1363,7 @@ return NULL; if (datasize == 0) - return PyString_FromStringAndSize("", 0); + return PyBytes_FromStringAndSize("", 0); ACQUIRE_LOCK(self); if (!self->running) { @@ -1372,7 +1372,7 @@ goto error; } - ret = PyString_FromStringAndSize(NULL, bufsize); + ret = PyBytes_FromStringAndSize(NULL, bufsize); if (!ret) goto error; @@ -1395,7 +1395,7 @@ break; /* no more input data */ if (bzs->avail_out == 0) { bufsize = Util_NewBufferSize(bufsize); - if (_PyString_Resize(&ret, bufsize) < 0) { + if (_PyBytes_Resize(&ret, bufsize) < 0) { BZ2_bzCompressEnd(bzs); goto error; } @@ -1405,7 +1405,7 @@ } } - if (_PyString_Resize(&ret, + if (_PyBytes_Resize(&ret, (Py_ssize_t)(BZS_TOTAL_OUT(bzs) - totalout)) < 0) goto error; @@ -1442,7 +1442,7 @@ } self->running = 0; - ret = PyString_FromStringAndSize(NULL, bufsize); + ret = PyBytes_FromStringAndSize(NULL, bufsize); if (!ret) goto error; @@ -1463,7 +1463,7 @@ } if (bzs->avail_out == 0) { bufsize = Util_NewBufferSize(bufsize); - if (_PyString_Resize(&ret, bufsize) < 0) + if (_PyBytes_Resize(&ret, bufsize) < 0) goto error; bzs->next_out = BUF(ret); bzs->next_out = BUF(ret) + (BZS_TOTAL_OUT(bzs) @@ -1473,7 +1473,7 @@ } if (bzs->avail_out != 0) { - if (_PyString_Resize(&ret, + if (_PyBytes_Resize(&ret, (Py_ssize_t)(BZS_TOTAL_OUT(bzs) - totalout)) < 0) goto error; } @@ -1658,7 +1658,7 @@ goto error; } - ret = PyString_FromStringAndSize(NULL, bufsize); + ret = PyBytes_FromStringAndSize(NULL, bufsize); if (!ret) goto error; @@ -1677,7 +1677,7 @@ if (bzs->avail_in != 0) { Py_DECREF(self->unused_data); self->unused_data = - PyString_FromStringAndSize(bzs->next_in, + PyBytes_FromStringAndSize(bzs->next_in, bzs->avail_in); } self->running = 0; @@ -1691,7 +1691,7 @@ break; /* no more input data */ if (bzs->avail_out == 0) { bufsize = Util_NewBufferSize(bufsize); - if (_PyString_Resize(&ret, bufsize) < 0) { + if (_PyBytes_Resize(&ret, bufsize) < 0) { BZ2_bzDecompressEnd(bzs); goto error; } @@ -1703,7 +1703,7 @@ } if (bzs->avail_out != 0) { - if (_PyString_Resize(&ret, + if (_PyBytes_Resize(&ret, (Py_ssize_t)(BZS_TOTAL_OUT(bzs) - totalout)) < 0) goto error; } @@ -1742,7 +1742,7 @@ } #endif - self->unused_data = PyString_FromStringAndSize("", 0); + self->unused_data = PyBytes_FromStringAndSize("", 0); if (!self->unused_data) goto error; @@ -1875,7 +1875,7 @@ * data in one shot. We will check it later anyway. */ bufsize = datasize + (datasize/100+1) + 600; - ret = PyString_FromStringAndSize(NULL, bufsize); + ret = PyBytes_FromStringAndSize(NULL, bufsize); if (!ret) return NULL; @@ -1907,7 +1907,7 @@ } if (bzs->avail_out == 0) { bufsize = Util_NewBufferSize(bufsize); - if (_PyString_Resize(&ret, bufsize) < 0) { + if (_PyBytes_Resize(&ret, bufsize) < 0) { BZ2_bzCompressEnd(bzs); return NULL; } @@ -1917,7 +1917,7 @@ } if (bzs->avail_out != 0) { - if (_PyString_Resize(&ret, (Py_ssize_t)BZS_TOTAL_OUT(bzs)) < 0) { + if (_PyBytes_Resize(&ret, (Py_ssize_t)BZS_TOTAL_OUT(bzs)) < 0) { ret = NULL; } } @@ -1948,9 +1948,9 @@ return NULL; if (datasize == 0) - return PyString_FromStringAndSize("", 0); + return PyBytes_FromStringAndSize("", 0); - ret = PyString_FromStringAndSize(NULL, bufsize); + ret = PyBytes_FromStringAndSize(NULL, bufsize); if (!ret) return NULL; @@ -1989,7 +1989,7 @@ } if (bzs->avail_out == 0) { bufsize = Util_NewBufferSize(bufsize); - if (_PyString_Resize(&ret, bufsize) < 0) { + if (_PyBytes_Resize(&ret, bufsize) < 0) { BZ2_bzDecompressEnd(bzs); return NULL; } @@ -1999,7 +1999,7 @@ } if (bzs->avail_out != 0) { - if (_PyString_Resize(&ret, (Py_ssize_t)BZS_TOTAL_OUT(bzs)) < 0) { + if (_PyBytes_Resize(&ret, (Py_ssize_t)BZS_TOTAL_OUT(bzs)) < 0) { ret = NULL; } } Modified: python/branches/py3k-grandrenaming/Modules/cStringIO.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/cStringIO.c (original) +++ python/branches/py3k-grandrenaming/Modules/cStringIO.c Tue Jan 1 20:16:52 2008 @@ -118,7 +118,7 @@ static PyObject * IO_cgetval(PyObject *self) { if (!IO__opencheck(IOOOBJECT(self))) return NULL; - return PyString_FromStringAndSize(((IOobject*)self)->buf, + return PyBytes_FromStringAndSize(((IOobject*)self)->buf, ((IOobject*)self)->pos); } @@ -136,7 +136,7 @@ } else s=self->string_size; - return PyString_FromStringAndSize(self->buf, s); + return PyBytes_FromStringAndSize(self->buf, s); } PyDoc_STRVAR(IO_isatty__doc__, "isatty(): always returns 0"); @@ -176,7 +176,7 @@ if ( (n=IO_cread((PyObject*)self,&output,n)) < 0) return NULL; - return PyString_FromStringAndSize(output, n); + return PyBytes_FromStringAndSize(output, n); } PyDoc_STRVAR(IO_readline__doc__, "readline() -- Read one line"); @@ -214,7 +214,7 @@ n -= m; self->pos -= m; } - return PyString_FromStringAndSize(output, n); + return PyBytes_FromStringAndSize(output, n); } PyDoc_STRVAR(IO_readlines__doc__, "readlines() -- Read all lines"); @@ -237,7 +237,7 @@ goto err; if (n == 0) break; - line = PyString_FromStringAndSize (output, n); + line = PyBytes_FromStringAndSize (output, n); if (!line) goto err; if (PyList_Append (result, line) == -1) { @@ -314,7 +314,7 @@ next = IO_readline((IOobject *)self, NULL); if (!next) return NULL; - if (!PyString_GET_SIZE(next)) { + if (!PyBytes_GET_SIZE(next)) { Py_DECREF(next); PyErr_SetNone(PyExc_StopIteration); return NULL; @@ -455,7 +455,7 @@ while ((s = PyIter_Next(it)) != NULL) { Py_ssize_t n; char *c; - if (PyString_AsStringAndSize(s, &c, &n) == -1) { + if (PyBytes_AsStringAndSize(s, &c, &n) == -1) { Py_DECREF(it); Py_DECREF(s); return NULL; Modified: python/branches/py3k-grandrenaming/Modules/cjkcodecs/multibytecodec.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/cjkcodecs/multibytecodec.c (original) +++ python/branches/py3k-grandrenaming/Modules/cjkcodecs/multibytecodec.c Tue Jan 1 20:16:52 2008 @@ -175,15 +175,15 @@ Py_ssize_t orgpos, orgsize; orgpos = (Py_ssize_t)((char *)buf->outbuf - - PyString_AS_STRING(buf->outobj)); - orgsize = PyString_GET_SIZE(buf->outobj); - if (_PyString_Resize(&buf->outobj, orgsize + ( + PyBytes_AS_STRING(buf->outobj)); + orgsize = PyBytes_GET_SIZE(buf->outobj); + if (_PyBytes_Resize(&buf->outobj, orgsize + ( esize < (orgsize >> 1) ? (orgsize >> 1) | 1 : esize)) == -1) return -1; - buf->outbuf = (unsigned char *)PyString_AS_STRING(buf->outobj) +orgpos; - buf->outbuf_end = (unsigned char *)PyString_AS_STRING(buf->outobj) - + PyString_GET_SIZE(buf->outobj); + buf->outbuf = (unsigned char *)PyBytes_AS_STRING(buf->outobj) +orgpos; + buf->outbuf_end = (unsigned char *)PyBytes_AS_STRING(buf->outobj) + + PyBytes_GET_SIZE(buf->outobj); return 0; } @@ -330,11 +330,11 @@ goto errorexit; } - assert(PyString_Check(retstr)); - retstrsize = PyString_GET_SIZE(retstr); + assert(PyBytes_Check(retstr)); + retstrsize = PyBytes_GET_SIZE(retstr); REQUIRE_ENCODEBUFFER(buf, retstrsize); - memcpy(buf->outbuf, PyString_AS_STRING(retstr), retstrsize); + memcpy(buf->outbuf, PyBytes_AS_STRING(retstr), retstrsize); buf->outbuf += retstrsize; newpos = PyLong_AsSsize_t(PyTuple_GET_ITEM(retobj, 1)); @@ -476,16 +476,16 @@ Py_ssize_t finalsize, r = 0; if (datalen == 0) - return PyString_FromStringAndSize(NULL, 0); + return PyBytes_FromStringAndSize(NULL, 0); buf.excobj = NULL; buf.inbuf = buf.inbuf_top = *data; buf.inbuf_end = buf.inbuf_top + datalen; - buf.outobj = PyString_FromStringAndSize(NULL, datalen * 2 + 16); + buf.outobj = PyBytes_FromStringAndSize(NULL, datalen * 2 + 16); if (buf.outobj == NULL) goto errorexit; - buf.outbuf = (unsigned char *)PyString_AS_STRING(buf.outobj); - buf.outbuf_end = buf.outbuf + PyString_GET_SIZE(buf.outobj); + buf.outbuf = (unsigned char *)PyBytes_AS_STRING(buf.outobj); + buf.outbuf_end = buf.outbuf + PyBytes_GET_SIZE(buf.outobj); while (buf.inbuf < buf.inbuf_end) { Py_ssize_t inleft, outleft; @@ -520,10 +520,10 @@ } finalsize = (Py_ssize_t)((char *)buf.outbuf - - PyString_AS_STRING(buf.outobj)); + PyBytes_AS_STRING(buf.outobj)); - if (finalsize != PyString_GET_SIZE(buf.outobj)) - if (_PyString_Resize(&buf.outobj, finalsize) == -1) + if (finalsize != PyBytes_GET_SIZE(buf.outobj)) + if (_PyBytes_Resize(&buf.outobj, finalsize) == -1) goto errorexit; Py_XDECREF(buf.excobj); @@ -1230,7 +1230,7 @@ if (cres == NULL) goto errorexit; - if (!PyString_Check(cres)) { + if (!PyBytes_Check(cres)) { PyErr_Format(PyExc_TypeError, "stream function returned a " "non-bytes object (%.100s)", @@ -1238,28 +1238,28 @@ goto errorexit; } - endoffile = (PyString_GET_SIZE(cres) == 0); + endoffile = (PyBytes_GET_SIZE(cres) == 0); if (self->pendingsize > 0) { PyObject *ctr; char *ctrdata; - rsize = PyString_GET_SIZE(cres) + self->pendingsize; - ctr = PyString_FromStringAndSize(NULL, rsize); + rsize = PyBytes_GET_SIZE(cres) + self->pendingsize; + ctr = PyBytes_FromStringAndSize(NULL, rsize); if (ctr == NULL) goto errorexit; - ctrdata = PyString_AS_STRING(ctr); + ctrdata = PyBytes_AS_STRING(ctr); memcpy(ctrdata, self->pending, self->pendingsize); memcpy(ctrdata + self->pendingsize, - PyString_AS_STRING(cres), - PyString_GET_SIZE(cres)); + PyBytes_AS_STRING(cres), + PyBytes_GET_SIZE(cres)); Py_DECREF(cres); cres = ctr; self->pendingsize = 0; } - rsize = PyString_GET_SIZE(cres); - if (decoder_prepare_buffer(&buf, PyString_AS_STRING(cres), + rsize = PyBytes_GET_SIZE(cres); + if (decoder_prepare_buffer(&buf, PyBytes_AS_STRING(cres), rsize) != 0) goto errorexit; @@ -1603,8 +1603,8 @@ if (pwrt == NULL) return NULL; - assert(PyString_Check(pwrt)); - if (PyString_Size(pwrt) > 0) { + assert(PyBytes_Check(pwrt)); + if (PyBytes_Size(pwrt) > 0) { PyObject *wr; wr = PyObject_CallMethod(self->stream, "write", "O", pwrt); if (wr == NULL) { Modified: python/branches/py3k-grandrenaming/Modules/datetimemodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/datetimemodule.c (original) +++ python/branches/py3k-grandrenaming/Modules/datetimemodule.c Tue Jan 1 20:16:52 2008 @@ -1237,9 +1237,9 @@ * is expensive, don't unless they're actually used. */ totalnew = flen + 1; /* realistic if no %z/%Z */ - newfmt = PyString_FromStringAndSize(NULL, totalnew); + newfmt = PyBytes_FromStringAndSize(NULL, totalnew); if (newfmt == NULL) goto Done; - pnew = PyString_AsString(newfmt); + pnew = PyBytes_AsString(newfmt); usednew = 0; while ((ch = *pin++) != '\0') { @@ -1259,7 +1259,7 @@ /* format utcoffset */ char buf[100]; PyObject *tzinfo = get_tzinfo_member(object); - zreplacement = PyString_FromStringAndSize("", 0); + zreplacement = PyBytes_FromStringAndSize("", 0); if (zreplacement == NULL) goto Done; if (tzinfo != Py_None && tzinfo != NULL) { assert(tzinfoarg != NULL); @@ -1271,15 +1271,15 @@ goto Done; Py_DECREF(zreplacement); zreplacement = - PyString_FromStringAndSize(buf, + PyBytes_FromStringAndSize(buf, strlen(buf)); if (zreplacement == NULL) goto Done; } } assert(zreplacement != NULL); - ptoappend = PyString_AS_STRING(zreplacement); - ntoappend = PyString_GET_SIZE(zreplacement); + ptoappend = PyBytes_AS_STRING(zreplacement); + ntoappend = PyBytes_GET_SIZE(zreplacement); } else if (ch == 'Z') { /* format tzname */ @@ -1314,10 +1314,10 @@ PyErr_NoMemory(); goto Done; } - if (_PyString_Resize(&newfmt, bigger) < 0) + if (_PyBytes_Resize(&newfmt, bigger) < 0) goto Done; totalnew = bigger; - pnew = PyString_AsString(newfmt) + usednew; + pnew = PyBytes_AsString(newfmt) + usednew; } memcpy(pnew, ptoappend, ntoappend); pnew += ntoappend; @@ -1325,14 +1325,14 @@ assert(usednew <= totalnew); } /* end while() */ - if (_PyString_Resize(&newfmt, usednew) < 0) + if (_PyBytes_Resize(&newfmt, usednew) < 0) goto Done; { PyObject *format; PyObject *time = PyImport_ImportModule("time"); if (time == NULL) goto Done; - format = PyUnicode_FromString(PyString_AS_STRING(newfmt)); + format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt)); if (format != NULL) { result = PyObject_CallMethod(time, "strftime", "OO", format, timetuple); @@ -2186,15 +2186,15 @@ /* Check for invocation from pickle with __getstate__ state */ if (PyTuple_GET_SIZE(args) == 1 && - PyString_Check(state = PyTuple_GET_ITEM(args, 0)) && - PyString_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE && - MONTH_IS_SANE(PyString_AS_STRING(state)[2])) + PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) && + PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE && + MONTH_IS_SANE(PyBytes_AS_STRING(state)[2])) { PyDateTime_Date *me; me = (PyDateTime_Date *) (type->tp_alloc(type, 0)); if (me != NULL) { - char *pdata = PyString_AS_STRING(state); + char *pdata = PyBytes_AS_STRING(state); memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE); me->hashcode = -1; } @@ -2582,7 +2582,7 @@ date_getstate(PyDateTime_Date *self) { PyObject* field; - field = PyString_FromStringAndSize((char*)self->data, + field = PyBytes_FromStringAndSize((char*)self->data, _PyDateTime_DATE_DATASIZE); return Py_BuildValue("(N)", field); } @@ -3035,9 +3035,9 @@ /* Check for invocation from pickle with __getstate__ state */ if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2 && - PyString_Check(state = PyTuple_GET_ITEM(args, 0)) && - PyString_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE && - ((unsigned char) (PyString_AS_STRING(state)[0])) < 24) + PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) && + PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE && + ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24) { PyDateTime_Time *me; char aware; @@ -3053,7 +3053,7 @@ aware = (char)(tzinfo != Py_None); me = (PyDateTime_Time *) (type->tp_alloc(type, aware)); if (me != NULL) { - char *pdata = PyString_AS_STRING(state); + char *pdata = PyBytes_AS_STRING(state); memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE); me->hashcode = -1; @@ -3385,7 +3385,7 @@ PyObject *basestate; PyObject *result = NULL; - basestate = PyString_FromStringAndSize((char *)self->data, + basestate = PyBytes_FromStringAndSize((char *)self->data, _PyDateTime_TIME_DATASIZE); if (basestate != NULL) { if (! HASTZINFO(self) || self->tzinfo == Py_None) @@ -3569,9 +3569,9 @@ /* Check for invocation from pickle with __getstate__ state */ if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2 && - PyString_Check(state = PyTuple_GET_ITEM(args, 0)) && - PyString_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE && - MONTH_IS_SANE(PyString_AS_STRING(state)[2])) + PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) && + PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE && + MONTH_IS_SANE(PyBytes_AS_STRING(state)[2])) { PyDateTime_DateTime *me; char aware; @@ -3587,7 +3587,7 @@ aware = (char)(tzinfo != Py_None); me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware)); if (me != NULL) { - char *pdata = PyString_AS_STRING(state); + char *pdata = PyBytes_AS_STRING(state); memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE); me->hashcode = -1; @@ -4435,7 +4435,7 @@ PyObject *basestate; PyObject *result = NULL; - basestate = PyString_FromStringAndSize((char *)self->data, + basestate = PyBytes_FromStringAndSize((char *)self->data, _PyDateTime_DATETIME_DATASIZE); if (basestate != NULL) { if (! HASTZINFO(self) || self->tzinfo == Py_None) Modified: python/branches/py3k-grandrenaming/Modules/dbmmodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/dbmmodule.c (original) +++ python/branches/py3k-grandrenaming/Modules/dbmmodule.c Tue Jan 1 20:16:52 2008 @@ -219,14 +219,14 @@ if (arg == NULL) return -1; } - if (!PyString_Check(arg)) { + if (!PyBytes_Check(arg)) { PyErr_Format(PyExc_TypeError, "dbm key must be string, not %.100s", arg->ob_type->tp_name); return -1; } - key.dptr = PyString_AS_STRING(arg); - key.dsize = PyString_GET_SIZE(arg); + key.dptr = PyBytes_AS_STRING(arg); + key.dsize = PyBytes_GET_SIZE(arg); val = dbm_fetch(dp->di_dbm, key); return val.dptr != NULL; } Modified: python/branches/py3k-grandrenaming/Modules/fcntlmodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/fcntlmodule.c (original) +++ python/branches/py3k-grandrenaming/Modules/fcntlmodule.c Tue Jan 1 20:16:52 2008 @@ -55,7 +55,7 @@ PyErr_SetFromErrno(PyExc_IOError); return NULL; } - return PyString_FromStringAndSize(buf, len); + return PyBytes_FromStringAndSize(buf, len); } PyErr_Clear(); @@ -155,7 +155,7 @@ return PyLong_FromLong(ret); } else { - return PyString_FromStringAndSize(buf, len); + return PyBytes_FromStringAndSize(buf, len); } } @@ -176,7 +176,7 @@ PyErr_SetFromErrno(PyExc_IOError); return NULL; } - return PyString_FromStringAndSize(buf, len); + return PyBytes_FromStringAndSize(buf, len); } PyErr_Clear(); Modified: python/branches/py3k-grandrenaming/Modules/gdbmmodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/gdbmmodule.c (original) +++ python/branches/py3k-grandrenaming/Modules/gdbmmodule.c Tue Jan 1 20:16:52 2008 @@ -251,14 +251,14 @@ "GDBM object has already been closed"); return -1; } - if (!PyString_Check(arg)) { + if (!PyBytes_Check(arg)) { PyErr_Format(PyExc_TypeError, "gdbm key must be bytes, not %.100s", arg->ob_type->tp_name); return -1; } - key.dptr = PyString_AS_STRING(arg); - key.dsize = PyString_GET_SIZE(arg); + key.dptr = PyBytes_AS_STRING(arg); + key.dsize = PyBytes_GET_SIZE(arg); return gdbm_exists(dp->di_dbm, key); } Modified: python/branches/py3k-grandrenaming/Modules/md5module.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/md5module.c (original) +++ python/branches/py3k-grandrenaming/Modules/md5module.c Tue Jan 1 20:16:52 2008 @@ -363,7 +363,7 @@ temp = self->hash_state; md5_done(&temp, digest); - return PyString_FromStringAndSize((const char *)digest, MD5_DIGESTSIZE); + return PyBytes_FromStringAndSize((const char *)digest, MD5_DIGESTSIZE); } PyDoc_STRVAR(MD5_hexdigest__doc__, Modified: python/branches/py3k-grandrenaming/Modules/mmapmodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/mmapmodule.c (original) +++ python/branches/py3k-grandrenaming/Modules/mmapmodule.c Tue Jan 1 20:16:52 2008 @@ -687,9 +687,9 @@ } if (slicelen <= 0) - return PyString_FromStringAndSize("", 0); + return PyBytes_FromStringAndSize("", 0); else if (step == 1) - return PyString_FromStringAndSize(self->data + start, + return PyBytes_FromStringAndSize(self->data + start, slicelen); else { char *result_buf = (char *)PyMem_Malloc(slicelen); @@ -702,7 +702,7 @@ cur += step, i++) { result_buf[i] = self->data[cur]; } - result = PyString_FromStringAndSize(result_buf, + result = PyBytes_FromStringAndSize(result_buf, slicelen); PyMem_Free(result_buf); return result; Modified: python/branches/py3k-grandrenaming/Modules/posixmodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/posixmodule.c (original) +++ python/branches/py3k-grandrenaming/Modules/posixmodule.c Tue Jan 1 20:16:52 2008 @@ -425,13 +425,13 @@ rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH); if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */ - PyObject *v = PyString_FromString(buffer); + PyObject *v = PyBytes_FromString(buffer); PyDict_SetItemString(d, "BEGINLIBPATH", v); Py_DECREF(v); } rc = DosQueryExtLIBPATH(buffer, END_LIBPATH); if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */ - PyObject *v = PyString_FromString(buffer); + PyObject *v = PyBytes_FromString(buffer); PyDict_SetItemString(d, "ENDLIBPATH", v); Py_DECREF(v); } @@ -2197,7 +2197,7 @@ /* Skip over . and .. */ if (strcmp(FileData.cFileName, ".") != 0 && strcmp(FileData.cFileName, "..") != 0) { - v = PyString_FromString(FileData.cFileName); + v = PyBytes_FromString(FileData.cFileName); if (v == NULL) { Py_DECREF(d); d = NULL; @@ -2289,7 +2289,7 @@ /* Leave Case of Name Alone -- In Native Form */ /* (Removed Forced Lowercasing Code) */ - v = PyString_FromString(namebuf); + v = PyBytes_FromString(namebuf); if (v == NULL) { Py_DECREF(d); d = NULL; @@ -2340,7 +2340,7 @@ (NAMLEN(ep) == 1 || (ep->d_name[1] == '.' && NAMLEN(ep) == 2))) continue; - v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep)); + v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep)); if (v == NULL) { Py_DECREF(d); d = NULL; @@ -2423,7 +2423,7 @@ return PyUnicode_Decode(outbuf, strlen(outbuf), Py_FileSystemDefaultEncoding, NULL); } - return PyString_FromString(outbuf); + return PyBytes_FromString(outbuf); } /* end of posix__getfullpathname */ #endif /* MS_WINDOWS */ @@ -4440,7 +4440,7 @@ return posix_error_with_allocated_filename(path); PyMem_Free(path); - v = PyString_FromStringAndSize(buf, n); + v = PyBytes_FromStringAndSize(buf, n); if (arg_is_unicode) { PyObject *w; @@ -4823,18 +4823,18 @@ errno = EINVAL; return posix_error(); } - buffer = PyString_FromStringAndSize((char *)NULL, size); + buffer = PyBytes_FromStringAndSize((char *)NULL, size); if (buffer == NULL) return NULL; Py_BEGIN_ALLOW_THREADS - n = read(fd, PyString_AS_STRING(buffer), size); + n = read(fd, PyBytes_AS_STRING(buffer), size); Py_END_ALLOW_THREADS if (n < 0) { Py_DECREF(buffer); return posix_error(); } if (n != size) - _PyString_Resize(&buffer, n); + _PyBytes_Resize(&buffer, n); return buffer; } @@ -5134,13 +5134,13 @@ #endif /* XXX This can leak memory -- not easy to fix :-( */ /* len includes space for a trailing \0; the size arg to - PyString_FromStringAndSize does not count that */ + PyBytes_FromStringAndSize does not count that */ #ifdef MS_WINDOWS len = wcslen(s1) + wcslen(s2) + 2; newstr = PyUnicode_FromUnicode(NULL, (int)len - 1); #else len = strlen(s1) + strlen(s2) + 2; - newstr = PyString_FromStringAndSize(NULL, (int)len - 1); + newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1); #endif if (newstr == NULL) return PyErr_NoMemory(); @@ -5153,7 +5153,7 @@ return NULL; } #else - newenv = PyString_AS_STRING(newstr); + newenv = PyBytes_AS_STRING(newstr); PyOS_snprintf(newenv, len, "%s=%s", s1, s2); if (putenv(newenv)) { Py_DECREF(newstr); @@ -6645,11 +6645,11 @@ } /* Allocate bytes */ - result = PyString_FromStringAndSize(NULL, howMany); + result = PyBytes_FromStringAndSize(NULL, howMany); if (result != NULL) { /* Get random data */ if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*) - PyString_AS_STRING(result))) { + PyBytes_AS_STRING(result))) { Py_DECREF(result); return win32_error("CryptGenRandom", NULL); } @@ -6716,11 +6716,11 @@ "negative argument not allowed"); /* Allocate bytes */ - result = PyString_FromStringAndSize(NULL, howMany); + result = PyBytes_FromStringAndSize(NULL, howMany); if (result != NULL) { /* Get random data */ if (RAND_pseudo_bytes((unsigned char*) - PyString_AS_STRING(result), + PyBytes_AS_STRING(result), howMany) < 0) { Py_DECREF(result); return PyErr_Format(PyExc_ValueError, Modified: python/branches/py3k-grandrenaming/Modules/pyexpat.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/pyexpat.c (original) +++ python/branches/py3k-grandrenaming/Modules/pyexpat.c Tue Jan 1 20:16:52 2008 @@ -215,7 +215,7 @@ PyObject *filename = NULL; if (handler_info[slot].tb_code == NULL) { - code = PyString_FromString(""); + code = PyBytes_FromString(""); if (code == NULL) goto failed; name = PyUnicode_FromString(func_name); @@ -864,8 +864,8 @@ if (str == NULL) goto finally; - if (PyString_Check(str)) - ptr = PyString_AS_STRING(str); + if (PyBytes_Check(str)) + ptr = PyBytes_AS_STRING(str); else if (PyByteArray_Check(str)) ptr = PyByteArray_AS_STRING(str); else { @@ -988,7 +988,7 @@ = XML_GetInputContext(self->itself, &offset, &size); if (buffer != NULL) - return PyString_FromStringAndSize(buffer + offset, + return PyBytes_FromStringAndSize(buffer + offset, size - offset); else Py_RETURN_NONE; Modified: python/branches/py3k-grandrenaming/Modules/sha1module.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/sha1module.c (original) +++ python/branches/py3k-grandrenaming/Modules/sha1module.c Tue Jan 1 20:16:52 2008 @@ -339,7 +339,7 @@ temp = self->hash_state; sha1_done(&temp, digest); - return PyString_FromStringAndSize((const char *)digest, SHA1_DIGESTSIZE); + return PyBytes_FromStringAndSize((const char *)digest, SHA1_DIGESTSIZE); } PyDoc_STRVAR(SHA1_hexdigest__doc__, Modified: python/branches/py3k-grandrenaming/Modules/sha256module.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/sha256module.c (original) +++ python/branches/py3k-grandrenaming/Modules/sha256module.c Tue Jan 1 20:16:52 2008 @@ -432,7 +432,7 @@ SHAcopy(self, &temp); sha_final(digest, &temp); - return PyString_FromStringAndSize((const char *)digest, self->digestsize); + return PyBytes_FromStringAndSize((const char *)digest, self->digestsize); } PyDoc_STRVAR(SHA256_hexdigest__doc__, Modified: python/branches/py3k-grandrenaming/Modules/sha512module.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/sha512module.c (original) +++ python/branches/py3k-grandrenaming/Modules/sha512module.c Tue Jan 1 20:16:52 2008 @@ -498,7 +498,7 @@ SHAcopy(self, &temp); sha512_final(digest, &temp); - return PyString_FromStringAndSize((const char *)digest, self->digestsize); + return PyBytes_FromStringAndSize((const char *)digest, self->digestsize); } PyDoc_STRVAR(SHA512_hexdigest__doc__, Modified: python/branches/py3k-grandrenaming/Modules/socketmodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/socketmodule.c (original) +++ python/branches/py3k-grandrenaming/Modules/socketmodule.c Tue Jan 1 20:16:52 2008 @@ -947,7 +947,7 @@ #ifdef linux if (a->sun_path[0] == 0) { /* Linux abstract namespace */ addrlen -= (sizeof(*a) - sizeof(a->sun_path)); - return PyString_FromStringAndSize(a->sun_path, addrlen); + return PyBytes_FromStringAndSize(a->sun_path, addrlen); } else #endif /* linux */ @@ -1273,12 +1273,12 @@ addr = (struct sockaddr_sco *)addr_ret; _BT_SCO_MEMB(addr, family) = AF_BLUETOOTH; - if (!PyString_Check(args)) { + if (!PyBytes_Check(args)) { PyErr_SetString(socket_error, "getsockaddrarg: " "wrong format"); return 0; } - straddr = PyString_AS_STRING(args); + straddr = PyBytes_AS_STRING(args); if (setbdaddr(straddr, &_BT_SCO_MEMB(addr, bdaddr)) < 0) return 0; @@ -1662,16 +1662,16 @@ "getsockopt buflen out of range"); return NULL; } - buf = PyString_FromStringAndSize((char *)NULL, buflen); + buf = PyBytes_FromStringAndSize((char *)NULL, buflen); if (buf == NULL) return NULL; res = getsockopt(s->sock_fd, level, optname, - (void *)PyString_AS_STRING(buf), &buflen); + (void *)PyBytes_AS_STRING(buf), &buflen); if (res < 0) { Py_DECREF(buf); return s->errorhandler(); } - _PyString_Resize(&buf, buflen); + _PyBytes_Resize(&buf, buflen); return buf; } @@ -2094,12 +2094,12 @@ } /* Allocate a new string. */ - buf = PyString_FromStringAndSize((char *) 0, recvlen); + buf = PyBytes_FromStringAndSize((char *) 0, recvlen); if (buf == NULL) return NULL; /* Call the guts */ - outlen = sock_recv_guts(s, PyString_AS_STRING(buf), recvlen, flags); + outlen = sock_recv_guts(s, PyBytes_AS_STRING(buf), recvlen, flags); if (outlen < 0) { /* An error occurred, release the string and return an error. */ @@ -2109,7 +2109,7 @@ if (outlen != recvlen) { /* We did not read as many bytes as we anticipated, resize the string if possible and be successful. */ - _PyString_Resize(&buf, outlen); + _PyBytes_Resize(&buf, outlen); } return buf; @@ -2265,11 +2265,11 @@ return NULL; } - buf = PyString_FromStringAndSize((char *) 0, recvlen); + buf = PyBytes_FromStringAndSize((char *) 0, recvlen); if (buf == NULL) return NULL; - outlen = sock_recvfrom_guts(s, PyString_AS_STRING(buf), + outlen = sock_recvfrom_guts(s, PyBytes_AS_STRING(buf), recvlen, flags, &addr); if (outlen < 0) { goto finally; @@ -2278,7 +2278,7 @@ if (outlen != recvlen) { /* We did not read as many bytes as we anticipated, resize the string if possible and be succesful. */ - if (_PyString_Resize(&buf, outlen) < 0) + if (_PyBytes_Resize(&buf, outlen) < 0) /* Oopsy, not so succesful after all. */ goto finally; } @@ -3377,7 +3377,7 @@ if (inet_aton != NULL) { #endif if (inet_aton(ip_addr, &buf)) - return PyString_FromStringAndSize((char *)(&buf), + return PyBytes_FromStringAndSize((char *)(&buf), sizeof(buf)); PyErr_SetString(socket_error, @@ -3406,7 +3406,7 @@ return NULL; } } - return PyString_FromStringAndSize((char *) &packed_addr, + return PyBytes_FromStringAndSize((char *) &packed_addr, sizeof(packed_addr)); #ifdef USE_INET_ATON_WEAKLINK @@ -3483,11 +3483,11 @@ "illegal IP address string passed to inet_pton"); return NULL; } else if (af == AF_INET) { - return PyString_FromStringAndSize(packed, + return PyBytes_FromStringAndSize(packed, sizeof(struct in_addr)); #ifdef ENABLE_IPV6 } else if (af == AF_INET6) { - return PyString_FromStringAndSize(packed, + return PyBytes_FromStringAndSize(packed, sizeof(struct in6_addr)); #endif } else { @@ -3586,10 +3586,10 @@ idna = PyObject_CallMethod(hobj, "encode", "s", "idna"); if (!idna) return NULL; - assert(PyString_Check(idna)); - hptr = PyString_AS_STRING(idna); - } else if (PyString_Check(hobj)) { - hptr = PyString_AsString(hobj); + assert(PyBytes_Check(idna)); + hptr = PyBytes_AS_STRING(idna); + } else if (PyBytes_Check(hobj)) { + hptr = PyBytes_AsString(hobj); } else { PyErr_SetString(PyExc_TypeError, "getaddrinfo() argument 1 must be string or None"); @@ -3603,8 +3603,8 @@ pptr = pbuf; } else if (PyUnicode_Check(pobj)) { pptr = PyUnicode_AsString(pobj); - } else if (PyString_Check(pobj)) { - pptr = PyString_AsString(pobj); + } else if (PyBytes_Check(pobj)) { + pptr = PyBytes_AsString(pobj); } else if (pobj == Py_None) { pptr = (char *)NULL; } else { Modified: python/branches/py3k-grandrenaming/Modules/termios.c ============================================================================== --- python/branches/py3k-grandrenaming/Modules/termios.c (original) +++ python/branches/py3k-grandrenaming/Modules/termios.c Tue Jan 1 20:16:52 2008 @@ -91,7 +91,7 @@ return NULL; for (i = 0; i < NCCS; i++) { ch = (char)mode.c_cc[i]; - v = PyString_FromStringAndSize(&ch, 1); + v = PyBytes_FromStringAndSize(&ch, 1); if (v == NULL) goto err; PyList_SetItem(cc, i, v); @@ -183,8 +183,8 @@ for (i = 0; i < NCCS; i++) { v = PyList_GetItem(cc, i); - if (PyString_Check(v) && PyString_Size(v) == 1) - mode.c_cc[i] = (cc_t) * PyString_AsString(v); + if (PyBytes_Check(v) && PyBytes_Size(v) == 1) + mode.c_cc[i] = (cc_t) * PyBytes_AsString(v); else if (PyLong_Check(v)) mode.c_cc[i] = (cc_t) PyLong_AsLong(v); else { Modified: python/branches/py3k-grandrenaming/Objects/bytes_methods.c ============================================================================== --- python/branches/py3k-grandrenaming/Objects/bytes_methods.c (original) +++ python/branches/py3k-grandrenaming/Objects/bytes_methods.c Tue Jan 1 20:16:52 2008 @@ -462,11 +462,11 @@ Py_ssize_t i; /* - newobj = PyString_FromStringAndSize(NULL, len); + newobj = PyBytes_FromStringAndSize(NULL, len); if (!newobj) return NULL; - s = PyString_AS_STRING(newobj); + s = PyBytes_AS_STRING(newobj); */ Py_MEMCPY(result, cptr, len); @@ -490,11 +490,11 @@ Py_ssize_t i; /* - newobj = PyString_FromStringAndSize(NULL, len); + newobj = PyBytes_FromStringAndSize(NULL, len); if (!newobj) return NULL; - s = PyString_AS_STRING(newobj); + s = PyBytes_AS_STRING(newobj); */ Py_MEMCPY(result, cptr, len); @@ -520,10 +520,10 @@ int previous_is_cased = 0; /* - newobj = PyString_FromStringAndSize(NULL, len); + newobj = PyBytes_FromStringAndSize(NULL, len); if (newobj == NULL) return NULL; - s_new = PyString_AsString(newobj); + s_new = PyBytes_AsString(newobj); */ for (i = 0; i < len; i++) { int c = Py_CHARMASK(*s++); @@ -553,10 +553,10 @@ Py_ssize_t i; /* - newobj = PyString_FromStringAndSize(NULL, len); + newobj = PyBytes_FromStringAndSize(NULL, len); if (newobj == NULL) return NULL; - s_new = PyString_AsString(newobj); + s_new = PyBytes_AsString(newobj); */ if (0 < len) { int c = Py_CHARMASK(*s++); @@ -589,10 +589,10 @@ Py_ssize_t i; /* - newobj = PyString_FromStringAndSize(NULL, len); + newobj = PyBytes_FromStringAndSize(NULL, len); if (newobj == NULL) return NULL; - s_new = PyString_AsString(newobj); + s_new = PyBytes_AsString(newobj); */ for (i = 0; i < len; i++) { int c = Py_CHARMASK(*s++); Modified: python/branches/py3k-grandrenaming/Objects/bytesobject.c ============================================================================== --- python/branches/py3k-grandrenaming/Objects/bytesobject.c (original) +++ python/branches/py3k-grandrenaming/Objects/bytesobject.c Tue Jan 1 20:16:52 2008 @@ -724,7 +724,7 @@ encoded = PyCodec_Encode(arg, encoding, errors); if (encoded == NULL) return -1; - assert(PyString_Check(encoded)); + assert(PyBytes_Check(encoded)); new = bytearray_iconcat(self, encoded); Py_DECREF(encoded); if (new == NULL) @@ -2881,7 +2881,7 @@ /* XXX Shouldn't we use _getbuffer() on these items instead? */ for (i = 0; i < n; i++) { PyObject *obj = items[i]; - if (!PyByteArray_Check(obj) && !PyString_Check(obj)) { + if (!PyByteArray_Check(obj) && !PyBytes_Check(obj)) { PyErr_Format(PyExc_TypeError, "can only join an iterable of bytes " "(item %ld has type '%.100s')", @@ -2910,7 +2910,7 @@ if (PyByteArray_Check(obj)) buf = PyByteArray_AS_STRING(obj); else - buf = PyString_AS_STRING(obj); + buf = PyBytes_AS_STRING(obj); if (i) { memcpy(dest, self->ob_bytes, mysize); dest += mysize; Modified: python/branches/py3k-grandrenaming/Objects/codeobject.c ============================================================================== --- python/branches/py3k-grandrenaming/Objects/codeobject.c (original) +++ python/branches/py3k-grandrenaming/Objects/codeobject.c Tue Jan 1 20:16:52 2008 @@ -63,7 +63,7 @@ cellvars == NULL || !PyTuple_Check(cellvars) || name == NULL || !PyUnicode_Check(name) || filename == NULL || !PyUnicode_Check(filename) || - lnotab == NULL || !PyString_Check(lnotab) || + lnotab == NULL || !PyBytes_Check(lnotab) || !PyObject_CheckReadBuffer(code)) { PyErr_BadInternalCall(); return NULL; @@ -477,8 +477,8 @@ int PyCode_Addr2Line(PyCodeObject *co, int addrq) { - int size = PyString_Size(co->co_lnotab) / 2; - unsigned char *p = (unsigned char*)PyString_AsString(co->co_lnotab); + int size = PyBytes_Size(co->co_lnotab) / 2; + unsigned char *p = (unsigned char*)PyBytes_AsString(co->co_lnotab); int line = co->co_firstlineno; int addr = 0; while (--size >= 0) { @@ -573,8 +573,8 @@ int size, addr, line; unsigned char* p; - p = (unsigned char*)PyString_AS_STRING(co->co_lnotab); - size = PyString_GET_SIZE(co->co_lnotab) / 2; + p = (unsigned char*)PyBytes_AS_STRING(co->co_lnotab); + size = PyBytes_GET_SIZE(co->co_lnotab) / 2; addr = 0; line = co->co_firstlineno; Modified: python/branches/py3k-grandrenaming/Objects/exceptions.c ============================================================================== --- python/branches/py3k-grandrenaming/Objects/exceptions.c (original) +++ python/branches/py3k-grandrenaming/Objects/exceptions.c Tue Jan 1 20:16:52 2008 @@ -1056,7 +1056,7 @@ return NULL; } - if (!PyString_Check(attr)) { + if (!PyBytes_Check(attr)) { PyErr_Format(PyExc_TypeError, "%.200s attribute must be bytes", name); return NULL; } @@ -1148,7 +1148,7 @@ PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object, "object"); if (!obj) return -1; - size = PyString_GET_SIZE(obj); + size = PyBytes_GET_SIZE(obj); *start = ((PyUnicodeErrorObject *)exc)->start; if (*start<0) *start = 0; @@ -1216,7 +1216,7 @@ PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object, "object"); if (!obj) return -1; - size = PyString_GET_SIZE(obj); + size = PyBytes_GET_SIZE(obj); *end = ((PyUnicodeErrorObject *)exc)->end; if (*end<1) *end = 1; @@ -1463,12 +1463,12 @@ return -1; } - if (!PyString_Check(ude->object)) { + if (!PyBytes_Check(ude->object)) { if (PyObject_AsReadBuffer(ude->object, (const void **)&data, &size)) { ude->encoding = ude->object = ude->reason = NULL; return -1; } - ude->object = PyString_FromStringAndSize(data, size); + ude->object = PyBytes_FromStringAndSize(data, size); } else { Py_INCREF(ude->object); @@ -1486,7 +1486,7 @@ PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self; if (uself->end==uself->start+1) { - int byte = (int)(PyString_AS_STRING(((PyUnicodeErrorObject *)self)->object)[uself->start]&0xff); + int byte = (int)(PyBytes_AS_STRING(((PyUnicodeErrorObject *)self)->object)[uself->start]&0xff); return PyUnicode_FromFormat( "'%U' codec can't decode byte 0x%02x in position %zd: %U", ((PyUnicodeErrorObject *)self)->encoding, Modified: python/branches/py3k-grandrenaming/Objects/fileobject.c ============================================================================== --- python/branches/py3k-grandrenaming/Objects/fileobject.c (original) +++ python/branches/py3k-grandrenaming/Objects/fileobject.c Tue Jan 1 20:16:52 2008 @@ -81,7 +81,7 @@ result = PyEval_CallObject(reader, args); Py_DECREF(reader); Py_DECREF(args); - if (result != NULL && !PyString_Check(result) && + if (result != NULL && !PyBytes_Check(result) && !PyUnicode_Check(result)) { Py_DECREF(result); result = NULL; @@ -90,9 +90,9 @@ } } - if (n < 0 && result != NULL && PyString_Check(result)) { - char *s = PyString_AS_STRING(result); - Py_ssize_t len = PyString_GET_SIZE(result); + if (n < 0 && result != NULL && PyBytes_Check(result)) { + char *s = PyBytes_AS_STRING(result); + Py_ssize_t len = PyBytes_GET_SIZE(result); if (len == 0) { Py_DECREF(result); result = NULL; @@ -101,10 +101,10 @@ } else if (s[len-1] == '\n') { if (result->ob_refcnt == 1) - _PyString_Resize(&result, len-1); + _PyBytes_Resize(&result, len-1); else { PyObject *v; - v = PyString_FromStringAndSize(s, len-1); + v = PyBytes_FromStringAndSize(s, len-1); Py_DECREF(result); result = v; } Modified: python/branches/py3k-grandrenaming/Objects/frameobject.c ============================================================================== --- python/branches/py3k-grandrenaming/Objects/frameobject.c (original) +++ python/branches/py3k-grandrenaming/Objects/frameobject.c Tue Jan 1 20:16:52 2008 @@ -128,7 +128,7 @@ /* Find the bytecode offset for the start of the given line, or the * first code-owning line after it. */ - PyString_AsStringAndSize(f->f_code->co_lnotab, &lnotab, &lnotab_len); + PyBytes_AsStringAndSize(f->f_code->co_lnotab, &lnotab, &lnotab_len); addr = 0; line = f->f_code->co_firstlineno; new_lasti = -1; @@ -151,7 +151,7 @@ } /* We're now ready to look at the bytecode. */ - PyString_AsStringAndSize(f->f_code->co_code, (char **)&code, &code_len); + PyBytes_AsStringAndSize(f->f_code->co_code, (char **)&code, &code_len); min_addr = MIN(new_lasti, f->f_lasti); max_addr = MAX(new_lasti, f->f_lasti); Modified: python/branches/py3k-grandrenaming/Objects/longobject.c ============================================================================== --- python/branches/py3k-grandrenaming/Objects/longobject.c (original) +++ python/branches/py3k-grandrenaming/Objects/longobject.c Tue Jan 1 20:16:52 2008 @@ -3461,7 +3461,7 @@ return PyLong_FromUnicode(PyUnicode_AS_UNICODE(x), PyUnicode_GET_SIZE(x), base); - else if (PyByteArray_Check(x) || PyString_Check(x)) { + else if (PyByteArray_Check(x) || PyBytes_Check(x)) { /* Since PyLong_FromString doesn't have a length parameter, * check here for possible NULs in the string. */ char *string; @@ -3469,7 +3469,7 @@ if (PyByteArray_Check(x)) string = PyByteArray_AS_STRING(x); else - string = PyString_AS_STRING(x); + string = PyBytes_AS_STRING(x); if (strlen(string) != size) { /* We only see this if there's a null byte in x, x is a bytes or buffer, *and* a base is given. */ Modified: python/branches/py3k-grandrenaming/Objects/object.c ============================================================================== --- python/branches/py3k-grandrenaming/Objects/object.c (original) +++ python/branches/py3k-grandrenaming/Objects/object.c Tue Jan 1 20:16:52 2008 @@ -291,9 +291,9 @@ s = PyObject_Repr(op); if (s == NULL) ret = -1; - else if (PyString_Check(s)) { - fwrite(PyString_AS_STRING(s), 1, - PyString_GET_SIZE(s), fp); + else if (PyBytes_Check(s)) { + fwrite(PyBytes_AS_STRING(s), 1, + PyBytes_GET_SIZE(s), fp); } else if (PyUnicode_Check(s)) { PyObject *t; @@ -301,8 +301,8 @@ if (t == NULL) ret = 0; else { - fwrite(PyString_AS_STRING(t), 1, - PyString_GET_SIZE(t), fp); + fwrite(PyBytes_AS_STRING(t), 1, + PyBytes_GET_SIZE(t), fp); } } else { @@ -1489,7 +1489,7 @@ if (PyType_Ready(&PyByteArray_Type) < 0) Py_FatalError("Can't initialize 'bytes'"); - if (PyType_Ready(&PyString_Type) < 0) + if (PyType_Ready(&PyBytes_Type) < 0) Py_FatalError("Can't initialize 'str'"); if (PyType_Ready(&PyList_Type) < 0) Modified: python/branches/py3k-grandrenaming/Objects/stringlib/stringdefs.h ============================================================================== --- python/branches/py3k-grandrenaming/Objects/stringlib/stringdefs.h (original) +++ python/branches/py3k-grandrenaming/Objects/stringlib/stringdefs.h Tue Jan 1 20:16:52 2008 @@ -13,11 +13,11 @@ #define STRINGLIB_ISDECIMAL(x) ((x >= '0') && (x <= '9')) #define STRINGLIB_TODECIMAL(x) (STRINGLIB_ISDECIMAL(x) ? (x - '0') : -1) #define STRINGLIB_FILL memset -#define STRINGLIB_STR PyString_AS_STRING -#define STRINGLIB_LEN PyString_GET_SIZE -#define STRINGLIB_NEW PyString_FromStringAndSize -#define STRINGLIB_RESIZE _PyString_Resize -#define STRINGLIB_CHECK PyString_Check +#define STRINGLIB_STR PyBytes_AS_STRING +#define STRINGLIB_LEN PyBytes_GET_SIZE +#define STRINGLIB_NEW PyBytes_FromStringAndSize +#define STRINGLIB_RESIZE _PyBytes_Resize +#define STRINGLIB_CHECK PyBytes_Check #define STRINGLIB_CMP memcmp #define STRINGLIB_TOSTR PyObject_Str Modified: python/branches/py3k-grandrenaming/Objects/stringobject.c ============================================================================== --- python/branches/py3k-grandrenaming/Objects/stringobject.c (original) +++ python/branches/py3k-grandrenaming/Objects/stringobject.c Tue Jan 1 20:16:52 2008 @@ -35,19 +35,19 @@ static PyStringObject *nullstring; /* - For both PyString_FromString() and PyString_FromStringAndSize(), the + For both PyBytes_FromString() and PyBytes_FromStringAndSize(), the parameter `size' denotes number of characters to allocate, not counting any null terminating character. - For PyString_FromString(), the parameter `str' points to a null-terminated + For PyBytes_FromString(), the parameter `str' points to a null-terminated string containing exactly `size' bytes. - For PyString_FromStringAndSize(), the parameter the parameter `str' is + For PyBytes_FromStringAndSize(), the parameter the parameter `str' is either NULL or else points to a string containing at least `size' bytes. - For PyString_FromStringAndSize(), the string in the `str' parameter does + For PyBytes_FromStringAndSize(), the string in the `str' parameter does not have to be null-terminated. (Therefore it is safe to construct a - substring by calling `PyString_FromStringAndSize(origstring, substrlen)'.) - If `str' is NULL then PyString_FromStringAndSize() will allocate `size+1' + substring by calling `PyBytes_FromStringAndSize(origstring, substrlen)'.) + If `str' is NULL then PyBytes_FromStringAndSize() will allocate `size+1' bytes (setting the last byte to the null terminating character) and you can fill in the data yourself. If `str' is non-NULL then the resulting PyString object must be treated as immutable and you must not fill in nor @@ -57,11 +57,11 @@ items" in a variable-size object, will contain the number of bytes allocated for string data, not counting the null terminating character. It is therefore equal to the equal to the `size' parameter (for - PyString_FromStringAndSize()) or the length of the string in the `str' - parameter (for PyString_FromString()). + PyBytes_FromStringAndSize()) or the length of the string in the `str' + parameter (for PyBytes_FromString()). */ PyObject * -PyString_FromStringAndSize(const char *str, Py_ssize_t size) +PyBytes_FromStringAndSize(const char *str, Py_ssize_t size) { register PyStringObject *op; assert(size >= 0); @@ -86,7 +86,7 @@ op = (PyStringObject *)PyObject_MALLOC(sizeof(PyStringObject) + size); if (op == NULL) return PyErr_NoMemory(); - PyObject_INIT_VAR(op, &PyString_Type, size); + PyObject_INIT_VAR(op, &PyBytes_Type, size); op->ob_shash = -1; if (str != NULL) Py_MEMCPY(op->ob_sval, str, size); @@ -103,7 +103,7 @@ } PyObject * -PyString_FromString(const char *str) +PyBytes_FromString(const char *str) { register size_t size; register PyStringObject *op; @@ -134,7 +134,7 @@ op = (PyStringObject *)PyObject_MALLOC(sizeof(PyStringObject) + size); if (op == NULL) return PyErr_NoMemory(); - PyObject_INIT_VAR(op, &PyString_Type, size); + PyObject_INIT_VAR(op, &PyBytes_Type, size); op->ob_shash = -1; Py_MEMCPY(op->ob_sval, str, size+1); /* share short strings */ @@ -149,7 +149,7 @@ } PyObject * -PyString_FromFormatV(const char *format, va_list vargs) +PyBytes_FromFormatV(const char *format, va_list vargs) { va_list count; Py_ssize_t n = 0; @@ -224,11 +224,11 @@ /* step 2: fill the buffer */ /* Since we've analyzed how much space we need for the worst case, use sprintf directly instead of the slower PyOS_snprintf. */ - string = PyString_FromStringAndSize(NULL, n); + string = PyBytes_FromStringAndSize(NULL, n); if (!string) return NULL; - s = PyString_AsString(string); + s = PyBytes_AsString(string); for (f = format; *f; f++) { if (*f == '%') { @@ -328,12 +328,12 @@ } end: - _PyString_Resize(&string, s - PyString_AS_STRING(string)); + _PyBytes_Resize(&string, s - PyBytes_AS_STRING(string)); return string; } PyObject * -PyString_FromFormat(const char *format, ...) +PyBytes_FromFormat(const char *format, ...) { PyObject* ret; va_list vargs; @@ -343,7 +343,7 @@ #else va_start(vargs); #endif - ret = PyString_FromFormatV(format, vargs); + ret = PyBytes_FromFormatV(format, vargs); va_end(vargs); return ret; } @@ -359,7 +359,7 @@ the string is UTF-8 encoded and should be re-encoded in the specified encoding. */ -PyObject *PyString_DecodeEscape(const char *s, +PyObject *PyBytes_DecodeEscape(const char *s, Py_ssize_t len, const char *errors, Py_ssize_t unicode, @@ -370,10 +370,10 @@ const char *end; PyObject *v; Py_ssize_t newlen = recode_encoding ? 4*len:len; - v = PyString_FromStringAndSize((char *)NULL, newlen); + v = PyBytes_FromStringAndSize((char *)NULL, newlen); if (v == NULL) return NULL; - p = buf = PyString_AsString(v); + p = buf = PyBytes_AsString(v); end = s + len; while (s < end) { if (*s != '\\') { @@ -396,9 +396,9 @@ if (!w) goto failed; /* Append bytes to output buffer. */ - assert(PyString_Check(w)); - r = PyString_AS_STRING(w); - rn = PyString_GET_SIZE(w); + assert(PyBytes_Check(w)); + r = PyBytes_AS_STRING(w); + rn = PyBytes_GET_SIZE(w); Py_MEMCPY(p, r, rn); p += rn; Py_DECREF(w); @@ -484,7 +484,7 @@ } } if (p-buf < newlen) - _PyString_Resize(&v, p - buf); + _PyBytes_Resize(&v, p - buf); return v; failed: Py_DECREF(v); @@ -499,23 +499,23 @@ { char *s; Py_ssize_t len; - if (PyString_AsStringAndSize(op, &s, &len)) + if (PyBytes_AsStringAndSize(op, &s, &len)) return -1; return len; } Py_ssize_t -PyString_Size(register PyObject *op) +PyBytes_Size(register PyObject *op) { - if (!PyString_Check(op)) + if (!PyBytes_Check(op)) return bytes_getsize(op); return Py_SIZE(op); } /*const*/ char * -PyString_AsString(register PyObject *op) +PyBytes_AsString(register PyObject *op) { - if (!PyString_Check(op)) { + if (!PyBytes_Check(op)) { PyErr_Format(PyExc_TypeError, "expected bytes, %.200s found", Py_TYPE(op)->tp_name); return NULL; @@ -524,7 +524,7 @@ } int -PyString_AsStringAndSize(register PyObject *obj, +PyBytes_AsStringAndSize(register PyObject *obj, register char **s, register Py_ssize_t *len) { @@ -533,16 +533,16 @@ return -1; } - if (!PyString_Check(obj)) { + if (!PyBytes_Check(obj)) { PyErr_Format(PyExc_TypeError, "expected bytes, %.200s found", Py_TYPE(obj)->tp_name); return -1; } - *s = PyString_AS_STRING(obj); + *s = PyBytes_AS_STRING(obj); if (len != NULL) - *len = PyString_GET_SIZE(obj); - else if (strlen(*s) != (size_t)PyString_GET_SIZE(obj)) { + *len = PyBytes_GET_SIZE(obj); + else if (strlen(*s) != (size_t)PyBytes_GET_SIZE(obj)) { PyErr_SetString(PyExc_TypeError, "expected bytes with no null"); return -1; @@ -556,13 +556,13 @@ #define STRINGLIB_CHAR char #define STRINGLIB_CMP memcmp -#define STRINGLIB_LEN PyString_GET_SIZE -#define STRINGLIB_NEW PyString_FromStringAndSize -#define STRINGLIB_STR PyString_AS_STRING +#define STRINGLIB_LEN PyBytes_GET_SIZE +#define STRINGLIB_NEW PyBytes_FromStringAndSize +#define STRINGLIB_STR PyBytes_AS_STRING /* #define STRINGLIB_WANT_CONTAINS_OBJ 1 */ #define STRINGLIB_EMPTY nullstring -#define STRINGLIB_CHECK_EXACT PyString_CheckExact +#define STRINGLIB_CHECK_EXACT PyBytes_CheckExact #define STRINGLIB_MUTABLE 0 #include "stringlib/fastsearch.h" @@ -575,7 +575,7 @@ PyObject * -PyString_Repr(PyObject *obj, int smartquotes) +PyBytes_Repr(PyObject *obj, int smartquotes) { static const char *hexdigits = "0123456789abcdef"; register PyStringObject* op = (PyStringObject*) obj; @@ -601,7 +601,7 @@ quote = '\''; if (smartquotes) { char *test, *start; - start = PyString_AS_STRING(op); + start = PyBytes_AS_STRING(op); for (test = start; test < start+length; ++test) { if (*test == '"') { quote = '\''; /* back to single */ @@ -651,7 +651,7 @@ static PyObject * bytes_repr(PyObject *op) { - return PyString_Repr(op, 1); + return PyBytes_Repr(op, 1); } static PyObject * @@ -671,7 +671,7 @@ return Py_SIZE(a); } -/* This is also used by PyString_Concat() */ +/* This is also used by PyBytes_Concat() */ static PyObject * bytes_concat(PyObject *a, PyObject *b) { @@ -689,12 +689,12 @@ } /* Optimize end cases */ - if (va.len == 0 && PyString_CheckExact(b)) { + if (va.len == 0 && PyBytes_CheckExact(b)) { result = b; Py_INCREF(result); goto done; } - if (vb.len == 0 && PyString_CheckExact(a)) { + if (vb.len == 0 && PyBytes_CheckExact(a)) { result = a; Py_INCREF(result); goto done; @@ -706,10 +706,10 @@ goto done; } - result = PyString_FromStringAndSize(NULL, size); + result = PyBytes_FromStringAndSize(NULL, size); if (result != NULL) { - memcpy(PyString_AS_STRING(result), va.buf, va.len); - memcpy(PyString_AS_STRING(result) + va.len, vb.buf, vb.len); + memcpy(PyBytes_AS_STRING(result), va.buf, va.len); + memcpy(PyBytes_AS_STRING(result) + va.len, vb.buf, vb.len); } done: @@ -739,7 +739,7 @@ "repeated string is too long"); return NULL; } - if (size == Py_SIZE(a) && PyString_CheckExact(a)) { + if (size == Py_SIZE(a) && PyBytes_CheckExact(a)) { Py_INCREF(a); return (PyObject *)a; } @@ -753,7 +753,7 @@ PyObject_MALLOC(sizeof(PyStringObject) + nbytes); if (op == NULL) return PyErr_NoMemory(); - PyObject_INIT_VAR(op, &PyString_Type, size); + PyObject_INIT_VAR(op, &PyBytes_Type, size); op->ob_shash = -1; op->ob_sval[size] = '\0'; if (Py_SIZE(a) == 1 && n > 0) { @@ -783,7 +783,7 @@ PyErr_Clear(); if (_getbuffer(arg, &varg) < 0) return -1; - pos = stringlib_find(PyString_AS_STRING(self), Py_SIZE(self), + pos = stringlib_find(PyBytes_AS_STRING(self), Py_SIZE(self), varg.buf, varg.len, 0); PyObject_ReleaseBuffer(arg, &varg); return pos >= 0; @@ -793,7 +793,7 @@ return -1; } - return memchr(PyString_AS_STRING(self), ival, Py_SIZE(self)) != NULL; + return memchr(PyBytes_AS_STRING(self), ival, Py_SIZE(self)) != NULL; } static PyObject * @@ -815,7 +815,7 @@ PyObject *result; /* Make sure both arguments are strings. */ - if (!(PyString_Check(a) && PyString_Check(b))) { + if (!(PyBytes_Check(a) && PyBytes_Check(b))) { if (Py_BytesWarningFlag && (op == Py_EQ) && (PyObject_IsInstance((PyObject*)a, (PyObject*)&PyUnicode_Type) || @@ -906,8 +906,8 @@ if (i == -1 && PyErr_Occurred()) return NULL; if (i < 0) - i += PyString_GET_SIZE(self); - if (i < 0 || i >= PyString_GET_SIZE(self)) { + i += PyBytes_GET_SIZE(self); + if (i < 0 || i >= PyBytes_GET_SIZE(self)) { PyErr_SetString(PyExc_IndexError, "string index out of range"); return NULL; @@ -921,27 +921,27 @@ PyObject* result; if (PySlice_GetIndicesEx((PySliceObject*)item, - PyString_GET_SIZE(self), + PyBytes_GET_SIZE(self), &start, &stop, &step, &slicelength) < 0) { return NULL; } if (slicelength <= 0) { - return PyString_FromStringAndSize("", 0); + return PyBytes_FromStringAndSize("", 0); } else if (start == 0 && step == 1 && - slicelength == PyString_GET_SIZE(self) && - PyString_CheckExact(self)) { + slicelength == PyBytes_GET_SIZE(self) && + PyBytes_CheckExact(self)) { Py_INCREF(self); return (PyObject *)self; } else if (step == 1) { - return PyString_FromStringAndSize( - PyString_AS_STRING(self) + start, + return PyBytes_FromStringAndSize( + PyBytes_AS_STRING(self) + start, slicelength); } else { - source_buf = PyString_AsString((PyObject*)self); + source_buf = PyBytes_AsString((PyObject*)self); result_buf = (char *)PyMem_Malloc(slicelength); if (result_buf == NULL) return PyErr_NoMemory(); @@ -951,7 +951,7 @@ result_buf[i] = source_buf[cur]; } - result = PyString_FromStringAndSize(result_buf, + result = PyBytes_FromStringAndSize(result_buf, slicelength); PyMem_Free(result_buf); return result; @@ -1026,7 +1026,7 @@ (maxsplit >= MAX_PREALLOC ? MAX_PREALLOC : maxsplit+1) #define SPLIT_ADD(data, left, right) { \ - str = PyString_FromStringAndSize((data) + (left), \ + str = PyBytes_FromStringAndSize((data) + (left), \ (right) - (left)); \ if (str == NULL) \ goto onError; \ @@ -1053,7 +1053,7 @@ Py_LOCAL_INLINE(PyObject *) split_whitespace(PyStringObject *self, Py_ssize_t len, Py_ssize_t maxsplit) { - const char *s = PyString_AS_STRING(self); + const char *s = PyBytes_AS_STRING(self); Py_ssize_t i, j, count=0; PyObject *str; PyObject *list = PyList_New(PREALLOC_SIZE(maxsplit)); @@ -1068,7 +1068,7 @@ if (i==len) break; j = i; i++; SKIP_NONSPACE(s, i, len); - if (j == 0 && i == len && PyString_CheckExact(self)) { + if (j == 0 && i == len && PyBytes_CheckExact(self)) { /* No whitespace in self, so just use it as list[0] */ Py_INCREF(self); PyList_SET_ITEM(list, 0, (PyObject *)self); @@ -1095,7 +1095,7 @@ Py_LOCAL_INLINE(PyObject *) split_char(PyStringObject *self, Py_ssize_t len, char ch, Py_ssize_t maxcount) { - const char *s = PyString_AS_STRING(self); + const char *s = PyBytes_AS_STRING(self); register Py_ssize_t i, j, count=0; PyObject *str; PyObject *list = PyList_New(PREALLOC_SIZE(maxcount)); @@ -1114,7 +1114,7 @@ } } } - if (i == 0 && count == 0 && PyString_CheckExact(self)) { + if (i == 0 && count == 0 && PyBytes_CheckExact(self)) { /* ch not in self, so just use self as list[0] */ Py_INCREF(self); PyList_SET_ITEM(list, 0, (PyObject *)self); @@ -1142,9 +1142,9 @@ static PyObject * bytes_split(PyStringObject *self, PyObject *args) { - Py_ssize_t len = PyString_GET_SIZE(self), n, i, j; + Py_ssize_t len = PyBytes_GET_SIZE(self), n, i, j; Py_ssize_t maxsplit = -1, count=0; - const char *s = PyString_AS_STRING(self), *sub; + const char *s = PyBytes_AS_STRING(self), *sub; Py_buffer vsub; PyObject *list, *str, *subobj = Py_None; #ifdef USE_FAST @@ -1222,16 +1222,16 @@ const char *sep; Py_ssize_t sep_len; - if (PyString_Check(sep_obj)) { - sep = PyString_AS_STRING(sep_obj); - sep_len = PyString_GET_SIZE(sep_obj); + if (PyBytes_Check(sep_obj)) { + sep = PyBytes_AS_STRING(sep_obj); + sep_len = PyBytes_GET_SIZE(sep_obj); } else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len)) return NULL; return stringlib_partition( (PyObject*) self, - PyString_AS_STRING(self), PyString_GET_SIZE(self), + PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), sep_obj, sep, sep_len ); } @@ -1250,16 +1250,16 @@ const char *sep; Py_ssize_t sep_len; - if (PyString_Check(sep_obj)) { - sep = PyString_AS_STRING(sep_obj); - sep_len = PyString_GET_SIZE(sep_obj); + if (PyBytes_Check(sep_obj)) { + sep = PyBytes_AS_STRING(sep_obj); + sep_len = PyBytes_GET_SIZE(sep_obj); } else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len)) return NULL; return stringlib_rpartition( (PyObject*) self, - PyString_AS_STRING(self), PyString_GET_SIZE(self), + PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), sep_obj, sep, sep_len ); } @@ -1267,7 +1267,7 @@ Py_LOCAL_INLINE(PyObject *) rsplit_whitespace(PyStringObject *self, Py_ssize_t len, Py_ssize_t maxsplit) { - const char *s = PyString_AS_STRING(self); + const char *s = PyBytes_AS_STRING(self); Py_ssize_t i, j, count=0; PyObject *str; PyObject *list = PyList_New(PREALLOC_SIZE(maxsplit)); @@ -1282,7 +1282,7 @@ if (i<0) break; j = i; i--; RSKIP_NONSPACE(s, i); - if (j == len-1 && i < 0 && PyString_CheckExact(self)) { + if (j == len-1 && i < 0 && PyBytes_CheckExact(self)) { /* No whitespace in self, so just use it as list[0] */ Py_INCREF(self); PyList_SET_ITEM(list, 0, (PyObject *)self); @@ -1311,7 +1311,7 @@ Py_LOCAL_INLINE(PyObject *) rsplit_char(PyStringObject *self, Py_ssize_t len, char ch, Py_ssize_t maxcount) { - const char *s = PyString_AS_STRING(self); + const char *s = PyBytes_AS_STRING(self); register Py_ssize_t i, j, count=0; PyObject *str; PyObject *list = PyList_New(PREALLOC_SIZE(maxcount)); @@ -1329,7 +1329,7 @@ } } } - if (i < 0 && count == 0 && PyString_CheckExact(self)) { + if (i < 0 && count == 0 && PyBytes_CheckExact(self)) { /* ch not in self, so just use self as list[0] */ Py_INCREF(self); PyList_SET_ITEM(list, 0, (PyObject *)self); @@ -1361,7 +1361,7 @@ static PyObject * bytes_rsplit(PyStringObject *self, PyObject *args) { - Py_ssize_t len = PyString_GET_SIZE(self), n, i, j; + Py_ssize_t len = PyBytes_GET_SIZE(self), n, i, j; Py_ssize_t maxsplit = -1, count=0; const char *s, *sub; Py_buffer vsub; @@ -1395,7 +1395,7 @@ j = len; i = j - n; - s = PyString_AS_STRING(self); + s = PyBytes_AS_STRING(self); while ( (i >= 0) && (maxsplit-- > 0) ) { for (; i>=0; i--) { if (Py_STRING_MATCH(s, i, sub, n)) { @@ -1433,8 +1433,8 @@ static PyObject * bytes_join(PyObject *self, PyObject *orig) { - char *sep = PyString_AS_STRING(self); - const Py_ssize_t seplen = PyString_GET_SIZE(self); + char *sep = PyBytes_AS_STRING(self); + const Py_ssize_t seplen = PyBytes_GET_SIZE(self); PyObject *res = NULL; char *p; Py_ssize_t seqlen = 0; @@ -1450,11 +1450,11 @@ seqlen = PySequence_Size(seq); if (seqlen == 0) { Py_DECREF(seq); - return PyString_FromString(""); + return PyBytes_FromString(""); } if (seqlen == 1) { item = PySequence_Fast_GET_ITEM(seq, 0); - if (PyString_CheckExact(item)) { + if (PyBytes_CheckExact(item)) { Py_INCREF(item); Py_DECREF(seq); return item; @@ -1470,7 +1470,7 @@ for (i = 0; i < seqlen; i++) { const size_t old_sz = sz; item = PySequence_Fast_GET_ITEM(seq, i); - if (!PyString_Check(item) && !PyByteArray_Check(item)) { + if (!PyBytes_Check(item) && !PyByteArray_Check(item)) { PyErr_Format(PyExc_TypeError, "sequence item %zd: expected bytes," " %.80s found", @@ -1490,7 +1490,7 @@ } /* Allocate result space. */ - res = PyString_FromStringAndSize((char*)NULL, sz); + res = PyBytes_FromStringAndSize((char*)NULL, sz); if (res == NULL) { Py_DECREF(seq); return NULL; @@ -1499,7 +1499,7 @@ /* Catenate everything. */ /* I'm not worried about a PyBytes item growing because there's nowhere in this function where we release the GIL. */ - p = PyString_AS_STRING(res); + p = PyBytes_AS_STRING(res); for (i = 0; i < seqlen; ++i) { size_t n; char *q; @@ -1509,8 +1509,8 @@ } item = PySequence_Fast_GET_ITEM(seq, i); n = Py_SIZE(item); - if (PyString_Check(item)) - q = PyString_AS_STRING(item); + if (PyBytes_Check(item)) + q = PyBytes_AS_STRING(item); else q = PyByteArray_AS_STRING(item); Py_MEMCPY(p, q, n); @@ -1522,9 +1522,9 @@ } PyObject * -_PyString_Join(PyObject *sep, PyObject *x) +_PyBytes_Join(PyObject *sep, PyObject *x) { - assert(sep != NULL && PyString_Check(sep)); + assert(sep != NULL && PyBytes_Check(sep)); assert(x != NULL); return bytes_join(sep, x); } @@ -1566,9 +1566,9 @@ if (!_PyEval_SliceIndex(obj_end, &end)) return -2; - if (PyString_Check(subobj)) { - sub = PyString_AS_STRING(subobj); - sub_len = PyString_GET_SIZE(subobj); + if (PyBytes_Check(subobj)) { + sub = PyBytes_AS_STRING(subobj); + sub_len = PyBytes_GET_SIZE(subobj); } else if (PyObject_AsCharBuffer(subobj, &sub, &sub_len)) /* XXX - the "expected a character buffer object" is pretty @@ -1577,11 +1577,11 @@ if (dir > 0) return stringlib_find_slice( - PyString_AS_STRING(self), PyString_GET_SIZE(self), + PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), sub, sub_len, start, end); else return stringlib_rfind_slice( - PyString_AS_STRING(self), PyString_GET_SIZE(self), + PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), sub, sub_len, start, end); } @@ -1668,8 +1668,8 @@ do_xstrip(PyStringObject *self, int striptype, PyObject *sepobj) { Py_buffer vsep; - char *s = PyString_AS_STRING(self); - Py_ssize_t len = PyString_GET_SIZE(self); + char *s = PyBytes_AS_STRING(self); + Py_ssize_t len = PyBytes_GET_SIZE(self); char *sep; Py_ssize_t seplen; Py_ssize_t i, j; @@ -1696,20 +1696,20 @@ PyObject_ReleaseBuffer(sepobj, &vsep); - if (i == 0 && j == len && PyString_CheckExact(self)) { + if (i == 0 && j == len && PyBytes_CheckExact(self)) { Py_INCREF(self); return (PyObject*)self; } else - return PyString_FromStringAndSize(s+i, j-i); + return PyBytes_FromStringAndSize(s+i, j-i); } Py_LOCAL_INLINE(PyObject *) do_strip(PyStringObject *self, int striptype) { - char *s = PyString_AS_STRING(self); - Py_ssize_t len = PyString_GET_SIZE(self), i, j; + char *s = PyBytes_AS_STRING(self); + Py_ssize_t len = PyBytes_GET_SIZE(self), i, j; i = 0; if (striptype != RIGHTSTRIP) { @@ -1726,12 +1726,12 @@ j++; } - if (i == 0 && j == len && PyString_CheckExact(self)) { + if (i == 0 && j == len && PyBytes_CheckExact(self)) { Py_INCREF(self); return (PyObject*)self; } else - return PyString_FromStringAndSize(s+i, j-i); + return PyBytes_FromStringAndSize(s+i, j-i); } @@ -1806,7 +1806,7 @@ bytes_count(PyStringObject *self, PyObject *args) { PyObject *sub_obj; - const char *str = PyString_AS_STRING(self), *sub; + const char *str = PyBytes_AS_STRING(self), *sub; Py_ssize_t sub_len; Py_ssize_t start = 0, end = PY_SSIZE_T_MAX; @@ -1814,14 +1814,14 @@ _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end)) return NULL; - if (PyString_Check(sub_obj)) { - sub = PyString_AS_STRING(sub_obj); - sub_len = PyString_GET_SIZE(sub_obj); + if (PyBytes_Check(sub_obj)) { + sub = PyBytes_AS_STRING(sub_obj); + sub_len = PyBytes_GET_SIZE(sub_obj); } else if (PyObject_AsCharBuffer(sub_obj, &sub, &sub_len)) return NULL; - bytes_adjust_indices(&start, &end, PyString_GET_SIZE(self)); + bytes_adjust_indices(&start, &end, PyBytes_GET_SIZE(self)); return PyLong_FromSsize_t( stringlib_count(str + start, end - start, sub, sub_len) @@ -1854,9 +1854,9 @@ &tableobj, &delobj)) return NULL; - if (PyString_Check(tableobj)) { - table = PyString_AS_STRING(tableobj); - tablen = PyString_GET_SIZE(tableobj); + if (PyBytes_Check(tableobj)) { + table = PyBytes_AS_STRING(tableobj); + tablen = PyBytes_GET_SIZE(tableobj); } else if (tableobj == Py_None) { table = NULL; @@ -1872,9 +1872,9 @@ } if (delobj != NULL) { - if (PyString_Check(delobj)) { - del_table = PyString_AS_STRING(delobj); - dellen = PyString_GET_SIZE(delobj); + if (PyBytes_Check(delobj)) { + del_table = PyBytes_AS_STRING(delobj); + dellen = PyBytes_GET_SIZE(delobj); } else if (PyUnicode_Check(delobj)) { PyErr_SetString(PyExc_TypeError, @@ -1889,12 +1889,12 @@ dellen = 0; } - inlen = PyString_GET_SIZE(input_obj); - result = PyString_FromStringAndSize((char *)NULL, inlen); + inlen = PyBytes_GET_SIZE(input_obj); + result = PyBytes_FromStringAndSize((char *)NULL, inlen); if (result == NULL) return NULL; - output_start = output = PyString_AsString(result); - input = PyString_AS_STRING(input_obj); + output_start = output = PyBytes_AsString(result); + input = PyBytes_AS_STRING(input_obj); if (dellen == 0 && table != NULL) { /* If no deletions are required, use faster code */ @@ -1903,7 +1903,7 @@ if (Py_CHARMASK((*output++ = table[c])) != c) changed = 1; } - if (changed || !PyString_CheckExact(input_obj)) + if (changed || !PyBytes_CheckExact(input_obj)) return result; Py_DECREF(result); Py_INCREF(input_obj); @@ -1928,14 +1928,14 @@ continue; changed = 1; } - if (!changed && PyString_CheckExact(input_obj)) { + if (!changed && PyBytes_CheckExact(input_obj)) { Py_DECREF(result); Py_INCREF(input_obj); return input_obj; } /* Fix the size of the resulting string */ if (inlen > 0) - _PyString_Resize(&result, output - output_start); + _PyBytes_Resize(&result, output - output_start); return result; } @@ -1953,13 +1953,13 @@ Py_LOCAL(PyStringObject *) return_self(PyStringObject *self) { - if (PyString_CheckExact(self)) { + if (PyBytes_CheckExact(self)) { Py_INCREF(self); return self; } - return (PyStringObject *)PyString_FromStringAndSize( - PyString_AS_STRING(self), - PyString_GET_SIZE(self)); + return (PyStringObject *)PyBytes_FromStringAndSize( + PyBytes_AS_STRING(self), + PyBytes_GET_SIZE(self)); } Py_LOCAL_INLINE(Py_ssize_t) @@ -2080,7 +2080,7 @@ Py_ssize_t count, i, product; PyStringObject *result; - self_len = PyString_GET_SIZE(self); + self_len = PyBytes_GET_SIZE(self); /* 1 at the end plus 1 after every character */ count = self_len+1; @@ -2103,11 +2103,11 @@ } if (! (result = (PyStringObject *) - PyString_FromStringAndSize(NULL, result_len)) ) + PyBytes_FromStringAndSize(NULL, result_len)) ) return NULL; - self_s = PyString_AS_STRING(self); - result_s = PyString_AS_STRING(result); + self_s = PyBytes_AS_STRING(self); + result_s = PyBytes_AS_STRING(result); /* TODO: special case single character, which doesn't need memcpy */ @@ -2140,8 +2140,8 @@ Py_ssize_t count; PyStringObject *result; - self_len = PyString_GET_SIZE(self); - self_s = PyString_AS_STRING(self); + self_len = PyBytes_GET_SIZE(self); + self_s = PyBytes_AS_STRING(self); count = countchar(self_s, self_len, from_c, maxcount); if (count == 0) { @@ -2152,9 +2152,9 @@ assert(result_len>=0); if ( (result = (PyStringObject *) - PyString_FromStringAndSize(NULL, result_len)) == NULL) + PyBytes_FromStringAndSize(NULL, result_len)) == NULL) return NULL; - result_s = PyString_AS_STRING(result); + result_s = PyBytes_AS_STRING(result); start = self_s; end = self_s + self_len; @@ -2183,8 +2183,8 @@ Py_ssize_t count, offset; PyStringObject *result; - self_len = PyString_GET_SIZE(self); - self_s = PyString_AS_STRING(self); + self_len = PyBytes_GET_SIZE(self); + self_s = PyBytes_AS_STRING(self); count = countbytes(self_s, self_len, from_s, from_len, @@ -2200,10 +2200,10 @@ assert (result_len>=0); if ( (result = (PyStringObject *) - PyString_FromStringAndSize(NULL, result_len)) == NULL ) + PyBytes_FromStringAndSize(NULL, result_len)) == NULL ) return NULL; - result_s = PyString_AS_STRING(result); + result_s = PyBytes_AS_STRING(result); start = self_s; end = self_s + self_len; @@ -2235,8 +2235,8 @@ PyStringObject *result; /* The result string will be the same size */ - self_s = PyString_AS_STRING(self); - self_len = PyString_GET_SIZE(self); + self_s = PyBytes_AS_STRING(self); + self_len = PyBytes_GET_SIZE(self); next = findchar(self_s, self_len, from_c); @@ -2246,10 +2246,10 @@ } /* Need to make a new string */ - result = (PyStringObject *) PyString_FromStringAndSize(NULL, self_len); + result = (PyStringObject *) PyBytes_FromStringAndSize(NULL, self_len); if (result == NULL) return NULL; - result_s = PyString_AS_STRING(result); + result_s = PyBytes_AS_STRING(result); Py_MEMCPY(result_s, self_s, self_len); /* change everything in-place, starting with this one */ @@ -2283,8 +2283,8 @@ /* The result string will be the same size */ - self_s = PyString_AS_STRING(self); - self_len = PyString_GET_SIZE(self); + self_s = PyBytes_AS_STRING(self); + self_len = PyBytes_GET_SIZE(self); offset = findbytes(self_s, self_len, from_s, from_len, @@ -2295,10 +2295,10 @@ } /* Need to make a new string */ - result = (PyStringObject *) PyString_FromStringAndSize(NULL, self_len); + result = (PyStringObject *) PyBytes_FromStringAndSize(NULL, self_len); if (result == NULL) return NULL; - result_s = PyString_AS_STRING(result); + result_s = PyBytes_AS_STRING(result); Py_MEMCPY(result_s, self_s, self_len); /* change everything in-place, starting with this one */ @@ -2333,8 +2333,8 @@ Py_ssize_t count, product; PyStringObject *result; - self_s = PyString_AS_STRING(self); - self_len = PyString_GET_SIZE(self); + self_s = PyBytes_AS_STRING(self); + self_len = PyBytes_GET_SIZE(self); count = countchar(self_s, self_len, from_c, maxcount); if (count == 0) { @@ -2358,9 +2358,9 @@ } if ( (result = (PyStringObject *) - PyString_FromStringAndSize(NULL, result_len)) == NULL) + PyBytes_FromStringAndSize(NULL, result_len)) == NULL) return NULL; - result_s = PyString_AS_STRING(result); + result_s = PyBytes_AS_STRING(result); start = self_s; end = self_s + self_len; @@ -2401,8 +2401,8 @@ Py_ssize_t count, offset, product; PyStringObject *result; - self_s = PyString_AS_STRING(self); - self_len = PyString_GET_SIZE(self); + self_s = PyBytes_AS_STRING(self); + self_len = PyBytes_GET_SIZE(self); count = countbytes(self_s, self_len, from_s, from_len, @@ -2428,9 +2428,9 @@ } if ( (result = (PyStringObject *) - PyString_FromStringAndSize(NULL, result_len)) == NULL) + PyBytes_FromStringAndSize(NULL, result_len)) == NULL) return NULL; - result_s = PyString_AS_STRING(result); + result_s = PyBytes_AS_STRING(result); start = self_s; end = self_s + self_len; @@ -2470,7 +2470,7 @@ { if (maxcount < 0) { maxcount = PY_SSIZE_T_MAX; - } else if (maxcount == 0 || PyString_GET_SIZE(self) == 0) { + } else if (maxcount == 0 || PyBytes_GET_SIZE(self) == 0) { /* nothing to do; return the original string */ return return_self(self); } @@ -2493,7 +2493,7 @@ /* Except for "".replace("", "A") == "A" there is no way beyond this */ /* point for an empty self string to generate a non-empty string */ /* Special case so the remaining code always gets a non-empty string */ - if (PyString_GET_SIZE(self) == 0) { + if (PyBytes_GET_SIZE(self) == 0) { return return_self(self); } @@ -2553,16 +2553,16 @@ if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count)) return NULL; - if (PyString_Check(from)) { - from_s = PyString_AS_STRING(from); - from_len = PyString_GET_SIZE(from); + if (PyBytes_Check(from)) { + from_s = PyBytes_AS_STRING(from); + from_len = PyBytes_GET_SIZE(from); } else if (PyObject_AsCharBuffer(from, &from_s, &from_len)) return NULL; - if (PyString_Check(to)) { - to_s = PyString_AS_STRING(to); - to_len = PyString_GET_SIZE(to); + if (PyBytes_Check(to)) { + to_s = PyBytes_AS_STRING(to); + to_len = PyBytes_GET_SIZE(to); } else if (PyObject_AsCharBuffer(to, &to_s, &to_len)) return NULL; @@ -2582,18 +2582,18 @@ _string_tailmatch(PyStringObject *self, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction) { - Py_ssize_t len = PyString_GET_SIZE(self); + Py_ssize_t len = PyBytes_GET_SIZE(self); Py_ssize_t slen; const char* sub; const char* str; - if (PyString_Check(substr)) { - sub = PyString_AS_STRING(substr); - slen = PyString_GET_SIZE(substr); + if (PyBytes_Check(substr)) { + sub = PyBytes_AS_STRING(substr); + slen = PyBytes_GET_SIZE(substr); } else if (PyObject_AsCharBuffer(substr, &sub, &slen)) return -1; - str = PyString_AS_STRING(self); + str = PyBytes_AS_STRING(self); bytes_adjust_indices(&start, &end, len); @@ -2759,10 +2759,10 @@ hexlen = PyUnicode_GET_SIZE(hexobj); hex = PyUnicode_AS_UNICODE(hexobj); byteslen = hexlen/2; /* This overestimates if there are spaces */ - newstring = PyString_FromStringAndSize(NULL, byteslen); + newstring = PyBytes_FromStringAndSize(NULL, byteslen); if (!newstring) return NULL; - buf = PyString_AS_STRING(newstring); + buf = PyBytes_AS_STRING(newstring); for (i = j = 0; i < hexlen; i += 2) { /* skip over spaces in the input */ while (hex[i] == ' ') @@ -2779,7 +2779,7 @@ } buf[j++] = (top << 4) + bot; } - if (_PyString_Resize(&newstring, j) < 0) + if (_PyBytes_Resize(&newstring, j) < 0) goto error; return newstring; @@ -2868,7 +2868,7 @@ Py_ssize_t i, size; static char *kwlist[] = {"source", "encoding", "errors", 0}; - if (type != &PyString_Type) + if (type != &PyBytes_Type) return str_subtype_new(type, args, kwds); if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytes", kwlist, &x, &encoding, &errors)) @@ -2880,7 +2880,7 @@ "argument"); return NULL; } - return PyString_FromString(""); + return PyBytes_FromString(""); } if (PyUnicode_Check(x)) { @@ -2893,7 +2893,7 @@ new = PyCodec_Encode(x, encoding, errors); if (new == NULL) return NULL; - assert(PyString_Check(new)); + assert(PyBytes_Check(new)); return new; } @@ -2914,7 +2914,7 @@ PyErr_SetString(PyExc_ValueError, "negative count"); return NULL; } - new = PyString_FromStringAndSize(NULL, size); + new = PyBytes_FromStringAndSize(NULL, size); if (new == NULL) { return NULL; } @@ -2929,7 +2929,7 @@ Py_buffer view; if (PyObject_GetBuffer(x, &view, PyBUF_FULL_RO) < 0) return NULL; - new = PyString_FromStringAndSize(NULL, view.len); + new = PyBytes_FromStringAndSize(NULL, view.len); if (!new) goto fail; // XXX(brett.cannon): Better way to get to internal buffer? @@ -2949,7 +2949,7 @@ /* XXX(guido): perhaps use Pysequence_Fast() -- I can't imagine the input being a truly long iterator. */ size = 64; - new = PyString_FromStringAndSize(NULL, size); + new = PyBytes_FromStringAndSize(NULL, size); if (new == NULL) return NULL; @@ -2989,12 +2989,12 @@ /* Append the byte */ if (i >= size) { size *= 2; - if (_PyString_Resize(&new, size) < 0) + if (_PyBytes_Resize(&new, size) < 0) goto error; } ((PyStringObject *)new)->ob_sval[i] = value; } - _PyString_Resize(&new, i); + _PyBytes_Resize(&new, i); /* Clean up and return success */ Py_DECREF(it); @@ -3013,16 +3013,16 @@ PyObject *tmp, *pnew; Py_ssize_t n; - assert(PyType_IsSubtype(type, &PyString_Type)); - tmp = bytes_new(&PyString_Type, args, kwds); + assert(PyType_IsSubtype(type, &PyBytes_Type)); + tmp = bytes_new(&PyBytes_Type, args, kwds); if (tmp == NULL) return NULL; - assert(PyString_CheckExact(tmp)); - n = PyString_GET_SIZE(tmp); + assert(PyBytes_CheckExact(tmp)); + n = PyBytes_GET_SIZE(tmp); pnew = type->tp_alloc(type, n); if (pnew != NULL) { - Py_MEMCPY(PyString_AS_STRING(pnew), - PyString_AS_STRING(tmp), n+1); + Py_MEMCPY(PyBytes_AS_STRING(pnew), + PyBytes_AS_STRING(tmp), n+1); ((PyStringObject *)pnew)->ob_shash = ((PyStringObject *)tmp)->ob_shash; } @@ -3044,7 +3044,7 @@ static PyObject *bytes_iter(PyObject *seq); -PyTypeObject PyString_Type = { +PyTypeObject PyBytes_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "bytes", sizeof(PyStringObject), @@ -3088,7 +3088,7 @@ }; void -PyString_Concat(register PyObject **pv, register PyObject *w) +PyBytes_Concat(register PyObject **pv, register PyObject *w) { register PyObject *v; assert(pv != NULL); @@ -3105,9 +3105,9 @@ } void -PyString_ConcatAndDel(register PyObject **pv, register PyObject *w) +PyBytes_ConcatAndDel(register PyObject **pv, register PyObject *w) { - PyString_Concat(pv, w); + PyBytes_Concat(pv, w); Py_XDECREF(w); } @@ -3127,12 +3127,12 @@ */ int -_PyString_Resize(PyObject **pv, Py_ssize_t newsize) +_PyBytes_Resize(PyObject **pv, Py_ssize_t newsize) { register PyObject *v; register PyStringObject *sv; v = *pv; - if (!PyString_Check(v) || Py_REFCNT(v) != 1 || newsize < 0) { + if (!PyBytes_Check(v) || Py_REFCNT(v) != 1 || newsize < 0) { *pv = 0; Py_DECREF(v); PyErr_BadInternalCall(); @@ -3156,7 +3156,7 @@ return 0; } -/* _PyString_FormatLong emulates the format codes d, u, o, x and X, and +/* _PyBytes_FormatLong emulates the format codes d, u, o, x and X, and * the F_ALT flag, for Python's long (unbounded) ints. It's not used for * Python's regular ints. * Return value: a new PyString*, or NULL if error. @@ -3178,7 +3178,7 @@ * produce a '-' sign, but can for Python's unbounded ints. */ PyObject* -_PyString_FormatLong(PyObject *val, int flags, int prec, int type, +_PyBytes_FormatLong(PyObject *val, int flags, int prec, int type, char **pbuf, int *plen) { PyObject *result = NULL; @@ -3235,7 +3235,7 @@ llen = PyUnicode_GetSize(result); if (llen > INT_MAX) { PyErr_SetString(PyExc_ValueError, - "string too large in _PyString_FormatLong"); + "string too large in _PyBytes_FormatLong"); return NULL; } len = (int)llen; @@ -3265,14 +3265,14 @@ /* Fill with leading zeroes to meet minimum width. */ if (prec > numdigits) { - PyObject *r1 = PyString_FromStringAndSize(NULL, + PyObject *r1 = PyBytes_FromStringAndSize(NULL, numnondigits + prec); char *b1; if (!r1) { Py_DECREF(result); return NULL; } - b1 = PyString_AS_STRING(r1); + b1 = PyBytes_AS_STRING(r1); for (i = 0; i < numnondigits; ++i) *b1++ = *buf++; for (i = 0; i < prec - numdigits; i++) @@ -3282,7 +3282,7 @@ *b1 = '\0'; Py_DECREF(result); result = r1; - buf = PyString_AS_STRING(result); + buf = PyBytes_AS_STRING(result); len = numnondigits + prec; } @@ -3300,7 +3300,7 @@ } void -PyString_Fini(void) +PyBytes_Fini(void) { int i; for (i = 0; i < UCHAR_MAX + 1; i++) { @@ -3344,9 +3344,9 @@ seq = it->it_seq; if (seq == NULL) return NULL; - assert(PyString_Check(seq)); + assert(PyBytes_Check(seq)); - if (it->it_index < PyString_GET_SIZE(seq)) { + if (it->it_index < PyBytes_GET_SIZE(seq)) { item = PyLong_FromLong( (unsigned char)seq->ob_sval[it->it_index]); if (item != NULL) @@ -3364,7 +3364,7 @@ { Py_ssize_t len = 0; if (it->it_seq) - len = PyString_GET_SIZE(it->it_seq) - it->it_index; + len = PyBytes_GET_SIZE(it->it_seq) - it->it_index; return PyLong_FromSsize_t(len); } @@ -3415,7 +3415,7 @@ { striterobject *it; - if (!PyString_Check(seq)) { + if (!PyBytes_Check(seq)) { PyErr_BadInternalCall(); return NULL; } Modified: python/branches/py3k-grandrenaming/Objects/tupleobject.c ============================================================================== --- python/branches/py3k-grandrenaming/Objects/tupleobject.c (original) +++ python/branches/py3k-grandrenaming/Objects/tupleobject.c Tue Jan 1 20:16:52 2008 @@ -201,7 +201,7 @@ possible within a type. */ i = Py_ReprEnter((PyObject *)v); if (i != 0) { - return i > 0 ? PyString_FromString("(...)") : NULL; + return i > 0 ? PyBytes_FromString("(...)") : NULL; } pieces = PyTuple_New(n); Modified: python/branches/py3k-grandrenaming/Objects/typeobject.c ============================================================================== --- python/branches/py3k-grandrenaming/Objects/typeobject.c (original) +++ python/branches/py3k-grandrenaming/Objects/typeobject.c Tue Jan 1 20:16:52 2008 @@ -3155,7 +3155,7 @@ type->tp_flags |= Py_TPFLAGS_TYPE_SUBCLASS; else if (PyType_IsSubtype(base, &PyLong_Type)) type->tp_flags |= Py_TPFLAGS_LONG_SUBCLASS; - else if (PyType_IsSubtype(base, &PyString_Type)) + else if (PyType_IsSubtype(base, &PyBytes_Type)) type->tp_flags |= Py_TPFLAGS_STRING_SUBCLASS; else if (PyType_IsSubtype(base, &PyUnicode_Type)) type->tp_flags |= Py_TPFLAGS_UNICODE_SUBCLASS; Modified: python/branches/py3k-grandrenaming/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k-grandrenaming/Objects/unicodeobject.c (original) +++ python/branches/py3k-grandrenaming/Objects/unicodeobject.c Tue Jan 1 20:16:52 2008 @@ -1024,9 +1024,9 @@ } /* Coerce object */ - if (PyString_Check(obj)) { - s = PyString_AS_STRING(obj); - len = PyString_GET_SIZE(obj); + if (PyBytes_Check(obj)) { + s = PyBytes_AS_STRING(obj); + len = PyBytes_GET_SIZE(obj); } else if (PyObject_AsCharBuffer(obj, &s, &len)) { /* Overwrite the error message with something more useful in @@ -1222,7 +1222,7 @@ v = PyCodec_Encode(unicode, encoding, errors); if (v == NULL) goto onError; - assert(PyString_Check(v)); + assert(PyBytes_Check(v)); return v; onError: @@ -1291,8 +1291,8 @@ if (bytes == NULL) return NULL; if (psize != NULL) - *psize = PyString_GET_SIZE(bytes); - return PyString_AS_STRING(bytes); + *psize = PyBytes_GET_SIZE(bytes); + return PyBytes_AS_STRING(bytes); } char* @@ -1404,11 +1404,11 @@ inputobj = PyUnicodeDecodeError_GetObject(*exceptionObject); if (!inputobj) goto onError; - if (!PyString_Check(inputobj)) { + if (!PyBytes_Check(inputobj)) { PyErr_Format(PyExc_TypeError, "exception attribute object must be bytes"); } - *input = PyString_AS_STRING(inputobj); - insize = PyString_GET_SIZE(inputobj); + *input = PyBytes_AS_STRING(inputobj); + insize = PyBytes_GET_SIZE(inputobj); *inend = *input + insize; /* we can DECREF safely, as the exception has another reference, so the object won't go away. */ @@ -1686,7 +1686,7 @@ char * start; if (size == 0) - return PyString_FromStringAndSize(NULL, 0); + return PyBytes_FromStringAndSize(NULL, 0); v = PyByteArray_FromStringAndSize(NULL, cbAllocated); if (v == NULL) @@ -1758,7 +1758,7 @@ *out++ = '-'; } - result = PyString_FromStringAndSize(PyByteArray_AS_STRING(v), out - start); + result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(v), out - start); Py_DECREF(v); return result; } @@ -2024,10 +2024,10 @@ nallocated = size * 4; if (nallocated / 4 != size) /* overflow! */ return PyErr_NoMemory(); - result = PyString_FromStringAndSize(NULL, nallocated); + result = PyBytes_FromStringAndSize(NULL, nallocated); if (result == NULL) return NULL; - p = PyString_AS_STRING(result); + p = PyBytes_AS_STRING(result); } for (i = 0; i < size;) { @@ -2075,13 +2075,13 @@ /* This was stack allocated. */ nneeded = p - stackbuf; assert(nneeded <= nallocated); - result = PyString_FromStringAndSize(stackbuf, nneeded); + result = PyBytes_FromStringAndSize(stackbuf, nneeded); } else { /* Cut back to size actually needed. */ - nneeded = p - PyString_AS_STRING(result); + nneeded = p - PyBytes_AS_STRING(result); assert(nneeded <= nallocated); - _PyString_Resize(&result, nneeded); + _PyBytes_Resize(&result, nneeded); } return result; @@ -2351,7 +2351,7 @@ } done: - result = PyString_FromStringAndSize(PyByteArray_AS_STRING(v), Py_SIZE(v)); + result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(v), Py_SIZE(v)); Py_DECREF(v); return result; #undef STORECHAR @@ -2615,7 +2615,7 @@ } done: - result = PyString_FromStringAndSize(PyByteArray_AS_STRING(v), Py_SIZE(v)); + result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(v), Py_SIZE(v)); Py_DECREF(v); return result; #undef STORECHAR @@ -3030,7 +3030,7 @@ *p++ = (char) ch; } - result = PyString_FromStringAndSize(PyByteArray_AS_STRING(repr), + result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(repr), p - PyByteArray_AS_STRING(repr)); Py_DECREF(repr); return result; @@ -3048,7 +3048,7 @@ if (!s) return NULL; - result = PyString_FromStringAndSize(PyByteArray_AS_STRING(s), + result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(s), PyByteArray_GET_SIZE(s)); Py_DECREF(s); return result; @@ -3213,7 +3213,7 @@ size = p - q; done: - result = PyString_FromStringAndSize(PyByteArray_AS_STRING(repr), size); + result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(repr), size); Py_DECREF(repr); return result; } @@ -3230,7 +3230,7 @@ if (!s) return NULL; - result = PyString_FromStringAndSize(PyByteArray_AS_STRING(s), + result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(s), PyByteArray_GET_SIZE(s)); Py_DECREF(s); return result; @@ -3463,7 +3463,7 @@ /* allocate enough for a simple encoding without replacements, if we need more, we'll resize */ if (size == 0) - return PyString_FromStringAndSize(NULL, 0); + return PyBytes_FromStringAndSize(NULL, 0); res = PyByteArray_FromStringAndSize(NULL, size); if (res == NULL) return NULL; @@ -3594,7 +3594,7 @@ } } } - result = PyString_FromStringAndSize(PyByteArray_AS_STRING(res), + result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(res), str - PyByteArray_AS_STRING(res)); onError: Py_DECREF(res); @@ -3846,20 +3846,20 @@ if (*repr == NULL) { /* Create string object */ - *repr = PyString_FromStringAndSize(NULL, mbcssize); + *repr = PyBytes_FromStringAndSize(NULL, mbcssize); if (*repr == NULL) return -1; } else { /* Extend string object */ - n = PyString_Size(*repr); - if (_PyString_Resize(repr, n + mbcssize) < 0) + n = PyBytes_Size(*repr); + if (_PyBytes_Resize(repr, n + mbcssize) < 0) return -1; } /* Do the conversion */ if (size > 0) { - char *s = PyString_AS_STRING(*repr) + n; + char *s = PyBytes_AS_STRING(*repr) + n; if (0 == WideCharToMultiByte(CP_ACP, 0, p, size, s, mbcssize, NULL, NULL)) { PyErr_SetFromWindowsErrWithFilename(0, NULL); return -1; @@ -4326,7 +4326,7 @@ } return x; } - else if (PyString_Check(x)) + else if (PyBytes_Check(x)) return x; else { /* wrong return value */ @@ -4341,11 +4341,11 @@ static int charmapencode_resize(PyObject **outobj, Py_ssize_t *outpos, Py_ssize_t requiredsize) { - Py_ssize_t outsize = PyString_GET_SIZE(*outobj); + Py_ssize_t outsize = PyBytes_GET_SIZE(*outobj); /* exponentially overallocate to minimize reallocations */ if (requiredsize < 2*outsize) requiredsize = 2*outsize; - if (_PyString_Resize(outobj, requiredsize)) + if (_PyBytes_Resize(outobj, requiredsize)) return -1; return 0; } @@ -4365,7 +4365,7 @@ { PyObject *rep; char *outstart; - Py_ssize_t outsize = PyString_GET_SIZE(*outobj); + Py_ssize_t outsize = PyBytes_GET_SIZE(*outobj); if (Py_TYPE(mapping) == &EncodingMapType) { int res = encoding_map_lookup(c, mapping); @@ -4375,7 +4375,7 @@ if (outsizeiCab); if (result == NULL) return -1; - if (!PyString_Check(result)) { + if (!PyBytes_Check(result)) { PyErr_Format(PyExc_TypeError, "Incorrect return type %s from getnextcabinet", result->ob_type->tp_name); Py_DECREF(result); return FALSE; } - strncpy(pccab->szCab, PyString_AsString(result), sizeof(pccab->szCab)); + strncpy(pccab->szCab, PyBytes_AsString(result), sizeof(pccab->szCab)); return TRUE; } return FALSE; @@ -507,7 +507,7 @@ PyErr_SetString(PyExc_NotImplementedError, "FILETIME result"); return NULL; case VT_LPSTR: - result = PyString_FromStringAndSize(sval, ssize); + result = PyBytes_FromStringAndSize(sval, ssize); if (sval != sbuf) free(sval); return result; @@ -539,9 +539,9 @@ if (!PyArg_ParseTuple(args, "iO:SetProperty", &field, &data)) return NULL; - if (PyString_Check(data)) { + if (PyBytes_Check(data)) { status = MsiSummaryInfoSetProperty(si->h, field, VT_LPSTR, - 0, NULL, PyString_AsString(data)); + 0, NULL, PyBytes_AsString(data)); } else if (PyLong_CheckExact(data)) { long value = PyLong_AsLong(data); if (value == -1 && PyErr_Occurred()) { Modified: python/branches/py3k-grandrenaming/PC/msvcrtmodule.c ============================================================================== --- python/branches/py3k-grandrenaming/PC/msvcrtmodule.c (original) +++ python/branches/py3k-grandrenaming/PC/msvcrtmodule.c Tue Jan 1 20:16:52 2008 @@ -142,7 +142,7 @@ ch = _getch(); Py_END_ALLOW_THREADS s[0] = ch; - return PyString_FromStringAndSize(s, 1); + return PyBytes_FromStringAndSize(s, 1); } static PyObject * @@ -174,7 +174,7 @@ ch = _getche(); Py_END_ALLOW_THREADS s[0] = ch; - return PyString_FromStringAndSize(s, 1); + return PyBytes_FromStringAndSize(s, 1); } static PyObject * Modified: python/branches/py3k-grandrenaming/Parser/tokenizer.c ============================================================================== --- python/branches/py3k-grandrenaming/Parser/tokenizer.c (original) +++ python/branches/py3k-grandrenaming/Parser/tokenizer.c Tue Jan 1 20:16:52 2008 @@ -651,7 +651,7 @@ utf8 = translate_into_utf8(str, tok->enc); if (utf8 == NULL) return error_ret(tok); - str = PyString_AsString(utf8); + str = PyBytes_AsString(utf8); } for (s = str;; s++) { if (*s == '\0') break; @@ -671,7 +671,7 @@ "unknown encoding: %s", tok->enc); return error_ret(tok); } - str = PyString_AS_STRING(utf8); + str = PyBytes_AS_STRING(utf8); } assert(tok->decoding_buffer == NULL); tok->decoding_buffer = utf8; /* CAUTION */ @@ -790,8 +790,8 @@ tok->done = E_DECODE; return EOF; } - buflen = PyString_GET_SIZE(u); - buf = PyString_AS_STRING(u); + buflen = PyBytes_GET_SIZE(u); + buf = PyBytes_AS_STRING(u); if (!buf) { Py_DECREF(u); tok->done = E_DECODE; @@ -1571,7 +1571,7 @@ PyErr_Clear(); } else { - assert(PyString_Check(ret)); + assert(PyBytes_Check(ret)); } return ret; } @@ -1584,8 +1584,8 @@ /* convert source to original encondig */ PyObject *lineobj = dec_utf8(tok->encoding, tok->buf, len); if (lineobj != NULL) { - int linelen = PyString_GET_SIZE(lineobj); - const char *line = PyString_AS_STRING(lineobj); + int linelen = PyBytes_GET_SIZE(lineobj); + const char *line = PyBytes_AS_STRING(lineobj); text = PyObject_MALLOC(linelen + 1); if (text != NULL && line != NULL) { if (linelen) Modified: python/branches/py3k-grandrenaming/Python/ast.c ============================================================================== --- python/branches/py3k-grandrenaming/Python/ast.c (original) +++ python/branches/py3k-grandrenaming/Python/ast.c Tue Jan 1 20:16:52 2008 @@ -2276,10 +2276,10 @@ /* length of string plus one for the dot */ len += strlen(STR(CHILD(n, i))) + 1; len--; /* the last name doesn't have a dot */ - str = PyString_FromStringAndSize(NULL, len); + str = PyBytes_FromStringAndSize(NULL, len); if (!str) return NULL; - s = PyString_AS_STRING(str); + s = PyBytes_AS_STRING(str); if (!s) return NULL; for (i = 0; i < NCH(n); i += 2) { @@ -2290,8 +2290,8 @@ } --s; *s = '\0'; - uni = PyUnicode_DecodeUTF8(PyString_AS_STRING(str), - PyString_GET_SIZE(str), + uni = PyUnicode_DecodeUTF8(PyBytes_AS_STRING(str), + PyBytes_GET_SIZE(str), NULL); Py_DECREF(str); if (!uni) @@ -3133,10 +3133,10 @@ u = NULL; } else { /* "\XX" may become "\u005c\uHHLL" (12 bytes) */ - u = PyString_FromStringAndSize((char *)NULL, len * 4); + u = PyBytes_FromStringAndSize((char *)NULL, len * 4); if (u == NULL) return NULL; - p = buf = PyString_AsString(u); + p = buf = PyBytes_AsString(u); end = s + len; while (s < end) { if (*s == '\\') { @@ -3155,7 +3155,7 @@ Py_DECREF(u); return NULL; } - r = PyString_AS_STRING(w); + r = PyBytes_AS_STRING(w); rn = Py_SIZE(w); assert(rn % 2 == 0); for (i = 0; i < rn; i += 2) { @@ -3252,7 +3252,7 @@ Py_DECREF(u); return v; } else if (*bytesmode) { - return PyString_FromStringAndSize(s, len); + return PyBytes_FromStringAndSize(s, len); } else if (strcmp(encoding, "utf-8") == 0) { return PyUnicode_FromStringAndSize(s, len); } else { @@ -3260,7 +3260,7 @@ } } - return PyString_DecodeEscape(s, len, NULL, 1, + return PyBytes_DecodeEscape(s, len, NULL, 1, need_encoding ? encoding : NULL); } @@ -3287,8 +3287,8 @@ ast_error(n, "cannot mix bytes and nonbytes literals"); goto onError; } - if (PyString_Check(v) && PyString_Check(s)) { - PyString_ConcatAndDel(&v, s); + if (PyBytes_Check(v) && PyBytes_Check(s)) { + PyBytes_ConcatAndDel(&v, s); if (v == NULL) goto onError; } Modified: python/branches/py3k-grandrenaming/Python/bltinmodule.c ============================================================================== --- python/branches/py3k-grandrenaming/Python/bltinmodule.c (original) +++ python/branches/py3k-grandrenaming/Python/bltinmodule.c Tue Jan 1 20:16:52 2008 @@ -1121,10 +1121,10 @@ long ord; Py_ssize_t size; - if (PyString_Check(obj)) { - size = PyString_GET_SIZE(obj); + if (PyBytes_Check(obj)) { + size = PyBytes_GET_SIZE(obj); if (size == 1) { - ord = (long)((unsigned char)*PyString_AS_STRING(obj)); + ord = (long)((unsigned char)*PyBytes_AS_STRING(obj)); return PyLong_FromLong(ord); } } @@ -1912,7 +1912,7 @@ SETBUILTIN("bool", &PyBool_Type); SETBUILTIN("memoryview", &PyMemoryView_Type); SETBUILTIN("bytearray", &PyByteArray_Type); - SETBUILTIN("bytes", &PyString_Type); + SETBUILTIN("bytes", &PyBytes_Type); SETBUILTIN("classmethod", &PyClassMethod_Type); #ifndef WITHOUT_COMPLEX SETBUILTIN("complex", &PyComplex_Type); Modified: python/branches/py3k-grandrenaming/Python/ceval.c ============================================================================== --- python/branches/py3k-grandrenaming/Python/ceval.c (original) +++ python/branches/py3k-grandrenaming/Python/ceval.c Tue Jan 1 20:16:52 2008 @@ -742,7 +742,7 @@ consts = co->co_consts; fastlocals = f->f_localsplus; freevars = f->f_localsplus + co->co_nlocals; - first_instr = (unsigned char*) PyString_AS_STRING(co->co_code); + first_instr = (unsigned char*) PyBytes_AS_STRING(co->co_code); /* An explanation is in order for the next line. f->f_lasti now refers to the index of the last instruction Modified: python/branches/py3k-grandrenaming/Python/codecs.c ============================================================================== --- python/branches/py3k-grandrenaming/Python/codecs.c (original) +++ python/branches/py3k-grandrenaming/Python/codecs.c Tue Jan 1 20:16:52 2008 @@ -354,9 +354,9 @@ v = NULL; goto onError; } - v = PyString_FromStringAndSize(PyByteArray_AS_STRING(v), Py_SIZE(v)); + v = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(v), Py_SIZE(v)); } - else if (PyString_Check(v)) + else if (PyBytes_Check(v)) Py_INCREF(v); else { PyErr_SetString(PyExc_TypeError, Modified: python/branches/py3k-grandrenaming/Python/compile.c ============================================================================== --- python/branches/py3k-grandrenaming/Python/compile.c (original) +++ python/branches/py3k-grandrenaming/Python/compile.c Tue Jan 1 20:16:52 2008 @@ -1185,8 +1185,8 @@ PyOS_snprintf(buf, sizeof(buf), "unknown scope for %.100s in %.100s(%s) in %s\n" "symbols: %s\nlocals: %s\nglobals: %s\n", - PyString_AS_STRING(name), - PyString_AS_STRING(c->u->u_name), + PyBytes_AS_STRING(name), + PyBytes_AS_STRING(c->u->u_name), PyObject_REPR(c->u->u_ste->ste_id), c->c_filename, PyObject_REPR(c->u->u_ste->ste_symbols), @@ -1245,7 +1245,7 @@ "lookup %s in %s %d %d\n" "freevars of %s: %s\n", PyObject_REPR(name), - PyString_AS_STRING(c->u->u_name), + PyBytes_AS_STRING(c->u->u_name), reftype, arg, PyUnicode_AsString(co->co_name), PyObject_REPR(co->co_freevars)); @@ -2996,7 +2996,7 @@ return PyObject_IsTrue(e->v.Str.s); case Name_kind: /* optimize away names that can't be reassigned */ - id = PyString_AS_STRING( + id = PyBytes_AS_STRING( _PyUnicode_AsDefaultEncodedString(e->v.Name.id, NULL)); if (strcmp(id, "True") == 0) return 1; if (strcmp(id, "False") == 0) return 0; @@ -3618,10 +3618,10 @@ { memset(a, 0, sizeof(struct assembler)); a->a_lineno = firstlineno; - a->a_bytecode = PyString_FromStringAndSize(NULL, DEFAULT_CODE_SIZE); + a->a_bytecode = PyBytes_FromStringAndSize(NULL, DEFAULT_CODE_SIZE); if (!a->a_bytecode) return 0; - a->a_lnotab = PyString_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE); + a->a_lnotab = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE); if (!a->a_lnotab) return 0; a->a_postorder = (basicblock **)PyObject_Malloc( @@ -3733,17 +3733,17 @@ if (d_bytecode > 255) { int j, nbytes, ncodes = d_bytecode / 255; nbytes = a->a_lnotab_off + 2 * ncodes; - len = PyString_GET_SIZE(a->a_lnotab); + len = PyBytes_GET_SIZE(a->a_lnotab); if (nbytes >= len) { if (len * 2 < nbytes) len = nbytes; else len *= 2; - if (_PyString_Resize(&a->a_lnotab, len) < 0) + if (_PyBytes_Resize(&a->a_lnotab, len) < 0) return 0; } lnotab = (unsigned char *) - PyString_AS_STRING(a->a_lnotab) + a->a_lnotab_off; + PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off; for (j = 0; j < ncodes; j++) { *lnotab++ = 255; *lnotab++ = 0; @@ -3755,17 +3755,17 @@ if (d_lineno > 255) { int j, nbytes, ncodes = d_lineno / 255; nbytes = a->a_lnotab_off + 2 * ncodes; - len = PyString_GET_SIZE(a->a_lnotab); + len = PyBytes_GET_SIZE(a->a_lnotab); if (nbytes >= len) { if (len * 2 < nbytes) len = nbytes; else len *= 2; - if (_PyString_Resize(&a->a_lnotab, len) < 0) + if (_PyBytes_Resize(&a->a_lnotab, len) < 0) return 0; } lnotab = (unsigned char *) - PyString_AS_STRING(a->a_lnotab) + a->a_lnotab_off; + PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off; *lnotab++ = d_bytecode; *lnotab++ = 255; d_bytecode = 0; @@ -3777,13 +3777,13 @@ a->a_lnotab_off += ncodes * 2; } - len = PyString_GET_SIZE(a->a_lnotab); + len = PyBytes_GET_SIZE(a->a_lnotab); if (a->a_lnotab_off + 2 >= len) { - if (_PyString_Resize(&a->a_lnotab, len * 2) < 0) + if (_PyBytes_Resize(&a->a_lnotab, len * 2) < 0) return 0; } lnotab = (unsigned char *) - PyString_AS_STRING(a->a_lnotab) + a->a_lnotab_off; + PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off; a->a_lnotab_off += 2; if (d_bytecode) { @@ -3808,7 +3808,7 @@ assemble_emit(struct assembler *a, struct instr *i) { int size, arg = 0, ext = 0; - Py_ssize_t len = PyString_GET_SIZE(a->a_bytecode); + Py_ssize_t len = PyBytes_GET_SIZE(a->a_bytecode); char *code; size = instrsize(i); @@ -3819,10 +3819,10 @@ if (i->i_lineno && !assemble_lnotab(a, i)) return 0; if (a->a_offset + size >= len) { - if (_PyString_Resize(&a->a_bytecode, len * 2) < 0) + if (_PyBytes_Resize(&a->a_bytecode, len * 2) < 0) return 0; } - code = PyString_AS_STRING(a->a_bytecode) + a->a_offset; + code = PyBytes_AS_STRING(a->a_bytecode) + a->a_offset; a->a_offset += size; if (size == 6) { assert(i->i_hasarg); @@ -4116,9 +4116,9 @@ goto error; } - if (_PyString_Resize(&a.a_lnotab, a.a_lnotab_off) < 0) + if (_PyBytes_Resize(&a.a_lnotab, a.a_lnotab_off) < 0) goto error; - if (_PyString_Resize(&a.a_bytecode, a.a_offset) < 0) + if (_PyBytes_Resize(&a.a_bytecode, a.a_offset) < 0) goto error; co = makecode(c, &a); Modified: python/branches/py3k-grandrenaming/Python/getargs.c ============================================================================== --- python/branches/py3k-grandrenaming/Python/getargs.c (original) +++ python/branches/py3k-grandrenaming/Python/getargs.c Tue Jan 1 20:16:52 2008 @@ -418,7 +418,7 @@ n++; } - if (!PySequence_Check(arg) || PyString_Check(arg)) { + if (!PySequence_Check(arg) || PyBytes_Check(arg)) { levels[0] = 0; PyOS_snprintf(msgbuf, bufsize, toplevel ? "expected %d arguments, not %.50s" : @@ -763,8 +763,8 @@ case 'c': {/* char */ char *p = va_arg(*p_va, char *); - if (PyString_Check(arg) && PyString_Size(arg) == 1) - *p = PyString_AS_STRING(arg)[0]; + if (PyBytes_Check(arg) && PyBytes_Size(arg) == 1) + *p = PyBytes_AS_STRING(arg)[0]; else if (PyUnicode_Check(arg) && PyUnicode_GET_SIZE(arg) == 1 && PyUnicode_AS_UNICODE(arg)[0] < 256) @@ -776,8 +776,8 @@ case 'C': {/* unicode char */ int *p = va_arg(*p_va, int *); - if (PyString_Check(arg) && PyString_Size(arg) == 1) - *p = PyString_AS_STRING(arg)[0]; + if (PyBytes_Check(arg) && PyBytes_Size(arg) == 1) + *p = PyBytes_AS_STRING(arg)[0]; else if (PyUnicode_Check(arg) && PyUnicode_GET_SIZE(arg) == 1) *p = PyUnicode_AS_UNICODE(arg)[0]; @@ -799,8 +799,8 @@ if (uarg == NULL) return converterr(CONV_UNICODE, arg, msgbuf, bufsize); - *p = PyString_AS_STRING(uarg); - STORE_SIZE(PyString_GET_SIZE(uarg)); + *p = PyBytes_AS_STRING(uarg); + STORE_SIZE(PyBytes_GET_SIZE(uarg)); } else { /* any buffer-like object */ /* XXX Really? */ @@ -819,7 +819,7 @@ if (uarg == NULL) return converterr(CONV_UNICODE, arg, msgbuf, bufsize); - *p = PyString_AS_STRING(uarg); + *p = PyBytes_AS_STRING(uarg); } else return converterr("string", arg, msgbuf, bufsize); @@ -858,8 +858,8 @@ if (uarg == NULL) return converterr(CONV_UNICODE, arg, msgbuf, bufsize); - *p = PyString_AS_STRING(uarg); - STORE_SIZE(PyString_GET_SIZE(uarg)); + *p = PyBytes_AS_STRING(uarg); + STORE_SIZE(PyBytes_GET_SIZE(uarg)); } else { /* any buffer-like object */ /* XXX Really? */ @@ -875,14 +875,14 @@ if (arg == Py_None) *p = 0; - else if (PyString_Check(arg)) - *p = PyString_AS_STRING(arg); + else if (PyBytes_Check(arg)) + *p = PyBytes_AS_STRING(arg); else if (PyUnicode_Check(arg)) { uarg = UNICODE_DEFAULT_ENCODING(arg); if (uarg == NULL) return converterr(CONV_UNICODE, arg, msgbuf, bufsize); - *p = PyString_AS_STRING(uarg); + *p = PyBytes_AS_STRING(uarg); } else return converterr("string or None", @@ -894,7 +894,7 @@ STORE_SIZE(0); } else { - STORE_SIZE(PyString_Size(arg)); + STORE_SIZE(PyBytes_Size(arg)); } format++; } @@ -968,7 +968,7 @@ /* Encode object */ if (!recode_strings && - (PyString_Check(arg) || PyByteArray_Check(arg))) { + (PyBytes_Check(arg) || PyByteArray_Check(arg))) { s = arg; Py_INCREF(s); if (PyObject_AsCharBuffer(s, &ptr, &size) < 0) @@ -993,14 +993,14 @@ if (s == NULL) return converterr("(encoding failed)", arg, msgbuf, bufsize); - if (!PyString_Check(s)) { + if (!PyBytes_Check(s)) { Py_DECREF(s); return converterr( "(encoder failed to return bytes)", arg, msgbuf, bufsize); } - size = PyString_GET_SIZE(s); - ptr = PyString_AS_STRING(s); + size = PyBytes_GET_SIZE(s); + ptr = PyBytes_AS_STRING(s); if (ptr == NULL) ptr = ""; } @@ -1113,7 +1113,7 @@ case 'S': { /* PyString object */ PyObject **p = va_arg(*p_va, PyObject **); - if (PyString_Check(arg)) + if (PyBytes_Check(arg)) *p = arg; else return converterr("bytes", arg, msgbuf, bufsize); @@ -1591,7 +1591,7 @@ while (PyDict_Next(keywords, &pos, &key, &value)) { int match = 0; char *ks; - if (!PyString_Check(key) && !PyUnicode_Check(key)) { + if (!PyBytes_Check(key) && !PyUnicode_Check(key)) { PyErr_SetString(PyExc_TypeError, "keywords must be strings"); return cleanreturn(0, freelist); Modified: python/branches/py3k-grandrenaming/Python/import.c ============================================================================== --- python/branches/py3k-grandrenaming/Python/import.c (original) +++ python/branches/py3k-grandrenaming/Python/import.c Tue Jan 1 20:16:52 2008 @@ -1273,10 +1273,10 @@ if (v == NULL) return NULL; } - if (!PyString_Check(v)) + if (!PyBytes_Check(v)) continue; - base = PyString_AS_STRING(v); - size = PyString_GET_SIZE(v); + base = PyBytes_AS_STRING(v); + size = PyBytes_GET_SIZE(v); len = size; if (len + 2 + namelen + MAXSUFFIXSIZE >= buflen) { continue; /* Too long */ @@ -2294,7 +2294,7 @@ PyErr_SetString(PyExc_ValueError, "Cannot encode path item"); return 0; } - subname = PyString_AS_STRING(item8); + subname = PyBytes_AS_STRING(item8); if (buflen + strlen(subname) >= MAXPATHLEN) { PyErr_SetString(PyExc_ValueError, "Module name too long"); Modified: python/branches/py3k-grandrenaming/Python/mactoolboxglue.c ============================================================================== --- python/branches/py3k-grandrenaming/Python/mactoolboxglue.c (original) +++ python/branches/py3k-grandrenaming/Python/mactoolboxglue.c Tue Jan 1 20:16:52 2008 @@ -52,7 +52,7 @@ buf[0] = '\0'; } else { - char *input = PyString_AsString(rv); + char *input = PyBytes_AsString(rv); if (!input) { PyErr_Clear(); buf[0] = '\0'; @@ -124,7 +124,7 @@ if (!rv) goto error; - input = PyString_AsString(rv); + input = PyBytes_AsString(rv); if (!input) goto error; @@ -166,9 +166,9 @@ if (v == NULL) return 0; } - if (PyString_Check(v)) { - str = PyString_AS_STRING(v); - len = PyString_GET_SIZE(v); + if (PyBytes_Check(v)) { + str = PyBytes_AS_STRING(v); + len = PyBytes_GET_SIZE(v); } else if (PyByteArray_Check(v)) { str = PyByteArray_AS_STRING(v); @@ -194,7 +194,7 @@ PyMac_BuildOSType(OSType t) { uint32_t tmp = htonl((uint32_t)t); - return PyString_FromStringAndSize((char *)&tmp, 4); + return PyBytes_FromStringAndSize((char *)&tmp, 4); } /* Convert an NumVersion value to a 4-element tuple */ @@ -217,9 +217,9 @@ if (v == NULL) return 0; } - if (PyString_Check(v)) { - ptr = PyString_AS_STRING(v); - len = PyString_GET_SIZE(v); + if (PyBytes_Check(v)) { + ptr = PyBytes_AS_STRING(v); + len = PyBytes_GET_SIZE(v); } else if (PyByteArray_Check(v)) { ptr = PyByteArray_AS_STRING(v); @@ -243,7 +243,7 @@ PyErr_SetString(PyExc_SystemError, "Str255 pointer is NULL"); return NULL; } - return PyString_FromStringAndSize((char *)&s[1], (int)s[0]); + return PyBytes_FromStringAndSize((char *)&s[1], (int)s[0]); } PyObject * @@ -253,7 +253,7 @@ Py_INCREF(Py_None); return Py_None; } - return PyString_FromStringAndSize((char *)&s[1], (int)s[0]); + return PyBytes_FromStringAndSize((char *)&s[1], (int)s[0]); } Modified: python/branches/py3k-grandrenaming/Python/marshal.c ============================================================================== --- python/branches/py3k-grandrenaming/Python/marshal.c (original) +++ python/branches/py3k-grandrenaming/Python/marshal.c Tue Jan 1 20:16:52 2008 @@ -67,15 +67,15 @@ Py_ssize_t size, newsize; if (p->str == NULL) return; /* An error already occurred */ - size = PyString_Size(p->str); + size = PyBytes_Size(p->str); newsize = size + 1024; - if (_PyString_Resize(&p->str, newsize) != 0) { + if (_PyBytes_Resize(&p->str, newsize) != 0) { p->ptr = p->end = NULL; } else { - p->ptr = PyString_AS_STRING((PyStringObject *)p->str) + size; + p->ptr = PyBytes_AS_STRING((PyStringObject *)p->str) + size; p->end = - PyString_AS_STRING((PyStringObject *)p->str) + newsize; + PyBytes_AS_STRING((PyStringObject *)p->str) + newsize; *p->ptr++ = Py_SAFE_DOWNCAST(c, int, char); } } @@ -228,9 +228,9 @@ } } #endif - else if (PyString_CheckExact(v)) { + else if (PyBytes_CheckExact(v)) { w_byte(TYPE_STRING, p); - n = PyString_GET_SIZE(v); + n = PyBytes_GET_SIZE(v); if (n > INT_MAX) { /* huge strings are not supported */ p->depth--; @@ -238,7 +238,7 @@ return; } w_long((long)n, p); - w_string(PyString_AS_STRING(v), (int)n, p); + w_string(PyBytes_AS_STRING(v), (int)n, p); } else if (PyUnicode_CheckExact(v)) { PyObject *utf8; @@ -249,14 +249,14 @@ return; } w_byte(TYPE_UNICODE, p); - n = PyString_GET_SIZE(utf8); + n = PyBytes_GET_SIZE(utf8); if (n > INT_MAX) { p->depth--; p->error = 1; return; } w_long((long)n, p); - w_string(PyString_AS_STRING(utf8), (int)n, p); + w_string(PyBytes_AS_STRING(utf8), (int)n, p); Py_DECREF(utf8); } else if (PyTuple_CheckExact(v)) { @@ -683,12 +683,12 @@ retval = NULL; break; } - v = PyString_FromStringAndSize((char *)NULL, n); + v = PyBytes_FromStringAndSize((char *)NULL, n); if (v == NULL) { retval = NULL; break; } - if (r_string(PyString_AS_STRING(v), (int)n, p) != n) { + if (r_string(PyBytes_AS_STRING(v), (int)n, p) != n) { Py_DECREF(v); PyErr_SetString(PyExc_EOFError, "EOF read where object expected"); @@ -1064,11 +1064,11 @@ PyObject *res = NULL; wf.fp = NULL; - wf.str = PyString_FromStringAndSize((char *)NULL, 50); + wf.str = PyBytes_FromStringAndSize((char *)NULL, 50); if (wf.str == NULL) return NULL; - wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str); - wf.end = wf.ptr + PyString_Size(wf.str); + wf.ptr = PyBytes_AS_STRING((PyStringObject *)wf.str); + wf.end = wf.ptr + PyBytes_Size(wf.str); wf.error = 0; wf.depth = 0; wf.version = version; @@ -1076,14 +1076,14 @@ w_object(x, &wf); Py_XDECREF(wf.strings); if (wf.str != NULL) { - char *base = PyString_AS_STRING((PyStringObject *)wf.str); + char *base = PyBytes_AS_STRING((PyStringObject *)wf.str); if (wf.ptr - base > PY_SSIZE_T_MAX) { Py_DECREF(wf.str); PyErr_SetString(PyExc_OverflowError, "too much marshal data for a string"); return NULL; } - if (_PyString_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)) < 0) + if (_PyBytes_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)) < 0) return NULL; } if (wf.error) { @@ -1132,9 +1132,9 @@ if (data == NULL) return NULL; rf.fp = NULL; - if (PyString_Check(data)) { - rf.ptr = PyString_AS_STRING(data); - rf.end = rf.ptr + PyString_GET_SIZE(data); + if (PyBytes_Check(data)) { + rf.ptr = PyBytes_AS_STRING(data); + rf.end = rf.ptr + PyBytes_GET_SIZE(data); } else if (PyByteArray_Check(data)) { rf.ptr = PyByteArray_AS_STRING(data); Modified: python/branches/py3k-grandrenaming/Python/modsupport.c ============================================================================== --- python/branches/py3k-grandrenaming/Python/modsupport.c (original) +++ python/branches/py3k-grandrenaming/Python/modsupport.c Tue Jan 1 20:16:52 2008 @@ -498,7 +498,7 @@ } n = (Py_ssize_t)m; } - v = PyString_FromStringAndSize(str, n); + v = PyBytes_FromStringAndSize(str, n); } return v; } Modified: python/branches/py3k-grandrenaming/Python/peephole.c ============================================================================== --- python/branches/py3k-grandrenaming/Python/peephole.c (original) +++ python/branches/py3k-grandrenaming/Python/peephole.c Tue Jan 1 20:16:52 2008 @@ -325,15 +325,15 @@ goto exitUnchanged; /* Bypass optimization when the lineno table is too complex */ - assert(PyString_Check(lineno_obj)); - lineno = (unsigned char*)PyString_AS_STRING(lineno_obj); - tabsiz = PyString_GET_SIZE(lineno_obj); + assert(PyBytes_Check(lineno_obj)); + lineno = (unsigned char*)PyBytes_AS_STRING(lineno_obj); + tabsiz = PyBytes_GET_SIZE(lineno_obj); if (memchr(lineno, 255, tabsiz) != NULL) goto exitUnchanged; /* Avoid situations where jump retargeting could overflow */ - assert(PyString_Check(code)); - codelen = PyString_GET_SIZE(code); + assert(PyBytes_Check(code)); + codelen = PyBytes_GET_SIZE(code); if (codelen > 32700) goto exitUnchanged; @@ -342,7 +342,7 @@ if (codestr == NULL) goto exitUnchanged; codestr = (unsigned char *)memcpy(codestr, - PyString_AS_STRING(code), codelen); + PyBytes_AS_STRING(code), codelen); /* Verify that RETURN_VALUE terminates the codestring. This allows the various transformation patterns to look ahead several @@ -632,7 +632,7 @@ } assert(h + nops == codelen); - code = PyString_FromStringAndSize((char *)codestr, h); + code = PyBytes_FromStringAndSize((char *)codestr, h); PyMem_Free(addrmap); PyMem_Free(codestr); PyMem_Free(blocks); Modified: python/branches/py3k-grandrenaming/Python/pythonrun.c ============================================================================== --- python/branches/py3k-grandrenaming/Python/pythonrun.c (original) +++ python/branches/py3k-grandrenaming/Python/pythonrun.c Tue Jan 1 20:16:52 2008 @@ -494,7 +494,7 @@ PyTuple_Fini(); PyList_Fini(); PySet_Fini(); - PyString_Fini(); + PyBytes_Fini(); PyByteArray_Fini(); PyLong_Fini(); PyFloat_Fini(); @@ -1103,7 +1103,7 @@ goto finally; if (v == Py_None) *filename = NULL; - else if (! (*filename = PyString_AsString(v))) + else if (! (*filename = PyBytes_AsString(v))) goto finally; Py_DECREF(v); Modified: python/branches/py3k-grandrenaming/Python/traceback.c ============================================================================== --- python/branches/py3k-grandrenaming/Python/traceback.c (original) +++ python/branches/py3k-grandrenaming/Python/traceback.c Tue Jan 1 20:16:52 2008 @@ -160,12 +160,12 @@ PyErr_Clear(); break; } - if (PyString_Check(v)) { + if (PyBytes_Check(v)) { size_t len; - len = PyString_GET_SIZE(v); + len = PyBytes_GET_SIZE(v); if (len + 1 + taillen >= MAXPATHLEN) continue; /* Too long */ - strcpy(namebuf, PyString_AsString(v)); + strcpy(namebuf, PyBytes_AsString(v)); if (strlen(namebuf) != len) continue; /* v contains '\0' */ if (len > 0 && namebuf[len-1] != SEP) From python-3000-checkins at python.org Tue Jan 1 20:48:25 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Tue, 1 Jan 2008 20:48:25 +0100 (CET) Subject: [Python-3000-checkins] r59652 - in python/branches/py3k-grandrenaming: Include/Python.h Include/bytearrayobject.h Include/bytesobject.h Makefile.pre.in Objects/bytearrayobject.c Objects/bytesobject.c PCbuild/pythoncore.vcproj PCbuild8/pythoncore/pythoncore.vcproj Message-ID: <20080101194825.282831E4002@bag.python.org> Author: christian.heimes Date: Tue Jan 1 20:48:23 2008 New Revision: 59652 Added: python/branches/py3k-grandrenaming/Include/bytearrayobject.h - copied unchanged from r59650, python/branches/py3k-grandrenaming/Include/bytesobject.h python/branches/py3k-grandrenaming/Objects/bytearrayobject.c - copied unchanged from r59651, python/branches/py3k-grandrenaming/Objects/bytesobject.c Removed: python/branches/py3k-grandrenaming/Include/bytesobject.h python/branches/py3k-grandrenaming/Objects/bytesobject.c Modified: python/branches/py3k-grandrenaming/Include/Python.h python/branches/py3k-grandrenaming/Makefile.pre.in python/branches/py3k-grandrenaming/PCbuild/pythoncore.vcproj python/branches/py3k-grandrenaming/PCbuild8/pythoncore/pythoncore.vcproj Log: Renamed bytesobject.c/h to bytearray.c/h Modified: python/branches/py3k-grandrenaming/Include/Python.h ============================================================================== --- python/branches/py3k-grandrenaming/Include/Python.h (original) +++ python/branches/py3k-grandrenaming/Include/Python.h Tue Jan 1 20:48:23 2008 @@ -64,7 +64,7 @@ #include "pydebug.h" -#include "bytesobject.h" +#include "bytearrayobject.h" #include "unicodeobject.h" #include "longobject.h" #include "longintrepr.h" Deleted: /python/branches/py3k-grandrenaming/Include/bytesobject.h ============================================================================== --- /python/branches/py3k-grandrenaming/Include/bytesobject.h Tue Jan 1 20:48:23 2008 +++ (empty file) @@ -1,53 +0,0 @@ -/* Bytes object interface */ - -#ifndef Py_BYTESOBJECT_H -#define Py_BYTESOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -#include - -/* Type PyBytesObject represents a mutable array of bytes. - * The Python API is that of a sequence; - * the bytes are mapped to ints in [0, 256). - * Bytes are not characters; they may be used to encode characters. - * The only way to go between bytes and str/unicode is via encoding - * and decoding. - * For the convenience of C programmers, the bytes type is considered - * to contain a char pointer, not an unsigned char pointer. - */ - -/* Object layout */ -typedef struct { - PyObject_VAR_HEAD - /* XXX(nnorwitz): should ob_exports be Py_ssize_t? */ - int ob_exports; /* how many buffer exports */ - Py_ssize_t ob_alloc; /* How many bytes allocated */ - char *ob_bytes; -} PyBytesObject; - -/* Type object */ -PyAPI_DATA(PyTypeObject) PyByteArray_Type; -PyAPI_DATA(PyTypeObject) PyBytesIter_Type; - -/* Type check macros */ -#define PyByteArray_Check(self) PyObject_TypeCheck(self, &PyByteArray_Type) -#define PyByteArray_CheckExact(self) (Py_TYPE(self) == &PyByteArray_Type) - -/* Direct API functions */ -PyAPI_FUNC(PyObject *) PyByteArray_FromObject(PyObject *); -PyAPI_FUNC(PyObject *) PyByteArray_Concat(PyObject *, PyObject *); -PyAPI_FUNC(PyObject *) PyByteArray_FromStringAndSize(const char *, Py_ssize_t); -PyAPI_FUNC(Py_ssize_t) PyByteArray_Size(PyObject *); -PyAPI_FUNC(char *) PyByteArray_AsString(PyObject *); -PyAPI_FUNC(int) PyByteArray_Resize(PyObject *, Py_ssize_t); - -/* Macros, trading safety for speed */ -#define PyByteArray_AS_STRING(self) (assert(PyByteArray_Check(self)),((PyBytesObject *)(self))->ob_bytes) -#define PyByteArray_GET_SIZE(self) (assert(PyByteArray_Check(self)),Py_SIZE(self)) - -#ifdef __cplusplus -} -#endif -#endif /* !Py_BYTESOBJECT_H */ Modified: python/branches/py3k-grandrenaming/Makefile.pre.in ============================================================================== --- python/branches/py3k-grandrenaming/Makefile.pre.in (original) +++ python/branches/py3k-grandrenaming/Makefile.pre.in Tue Jan 1 20:48:23 2008 @@ -290,7 +290,7 @@ Objects/abstract.o \ Objects/boolobject.o \ Objects/bytes_methods.o \ - Objects/bytesobject.o \ + Objects/bytearrayobject.o \ Objects/cellobject.o \ Objects/classobject.o \ Objects/cobject.o \ @@ -523,7 +523,7 @@ Objects/stringobject.o: $(srcdir)/Objects/stringobject.c $(BYTESTR_DEPS) -Objects/bytesobject.o: $(srcdir)/Objects/bytesobject.c $(BYTESTR_DEPS) +Objects/bytearrayobject.o: $(srcdir)/Objects/bytearrayobject.c $(BYTESTR_DEPS) Objects/unicodeobject.o: $(srcdir)/Objects/unicodeobject.c \ $(srcdir)/Objects/stringlib/string_format.h \ @@ -548,7 +548,7 @@ Include/abstract.h \ Include/boolobject.h \ Include/bytes_methods.h \ - Include/bytesobject.h \ + Include/bytearrayobject.h \ Include/ceval.h \ Include/classobject.h \ Include/cobject.h \ Deleted: /python/branches/py3k-grandrenaming/Objects/bytesobject.c ============================================================================== --- /python/branches/py3k-grandrenaming/Objects/bytesobject.c Tue Jan 1 20:48:23 2008 +++ (empty file) @@ -1,3286 +0,0 @@ -/* PyBytes (bytearray) implementation */ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#include "structmember.h" -#include "bytes_methods.h" - -static PyBytesObject *nullbytes = NULL; - -void -PyByteArray_Fini(void) -{ - Py_CLEAR(nullbytes); -} - -int -PyByteArray_Init(void) -{ - nullbytes = PyObject_New(PyBytesObject, &PyByteArray_Type); - if (nullbytes == NULL) - return 0; - nullbytes->ob_bytes = NULL; - Py_SIZE(nullbytes) = nullbytes->ob_alloc = 0; - nullbytes->ob_exports = 0; - return 1; -} - -/* end nullbytes support */ - -/* Helpers */ - -static int -_getbytevalue(PyObject* arg, int *value) -{ - long face_value; - - if (PyLong_Check(arg)) { - face_value = PyLong_AsLong(arg); - if (face_value < 0 || face_value >= 256) { - PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); - return 0; - } - } else { - PyErr_Format(PyExc_TypeError, "an integer is required"); - return 0; - } - - *value = face_value; - return 1; -} - -static int -bytearray_getbuffer(PyBytesObject *obj, Py_buffer *view, int flags) -{ - int ret; - void *ptr; - if (view == NULL) { - obj->ob_exports++; - return 0; - } - if (obj->ob_bytes == NULL) - ptr = ""; - else - ptr = obj->ob_bytes; - ret = PyBuffer_FillInfo(view, ptr, Py_SIZE(obj), 0, flags); - if (ret >= 0) { - obj->ob_exports++; - } - return ret; -} - -static void -bytearray_releasebuffer(PyBytesObject *obj, Py_buffer *view) -{ - obj->ob_exports--; -} - -static Py_ssize_t -_getbuffer(PyObject *obj, Py_buffer *view) -{ - PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer; - - if (buffer == NULL || buffer->bf_getbuffer == NULL) - { - PyErr_Format(PyExc_TypeError, - "Type %.100s doesn't support the buffer API", - Py_TYPE(obj)->tp_name); - return -1; - } - - if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0) - return -1; - return view->len; -} - -/* Direct API functions */ - -PyObject * -PyByteArray_FromObject(PyObject *input) -{ - return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type, - input, NULL); -} - -PyObject * -PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size) -{ - PyBytesObject *new; - Py_ssize_t alloc; - - assert(size >= 0); - - new = PyObject_New(PyBytesObject, &PyByteArray_Type); - if (new == NULL) - return NULL; - - if (size == 0) { - new->ob_bytes = NULL; - alloc = 0; - } - else { - alloc = size + 1; - new->ob_bytes = PyMem_Malloc(alloc); - if (new->ob_bytes == NULL) { - Py_DECREF(new); - return PyErr_NoMemory(); - } - if (bytes != NULL) - memcpy(new->ob_bytes, bytes, size); - new->ob_bytes[size] = '\0'; /* Trailing null byte */ - } - Py_SIZE(new) = size; - new->ob_alloc = alloc; - new->ob_exports = 0; - - return (PyObject *)new; -} - -Py_ssize_t -PyByteArray_Size(PyObject *self) -{ - assert(self != NULL); - assert(PyByteArray_Check(self)); - - return PyByteArray_GET_SIZE(self); -} - -char * -PyByteArray_AsString(PyObject *self) -{ - assert(self != NULL); - assert(PyByteArray_Check(self)); - - return PyByteArray_AS_STRING(self); -} - -int -PyByteArray_Resize(PyObject *self, Py_ssize_t size) -{ - void *sval; - Py_ssize_t alloc = ((PyBytesObject *)self)->ob_alloc; - - assert(self != NULL); - assert(PyByteArray_Check(self)); - assert(size >= 0); - - if (size < alloc / 2) { - /* Major downsize; resize down to exact size */ - alloc = size + 1; - } - else if (size < alloc) { - /* Within allocated size; quick exit */ - Py_SIZE(self) = size; - ((PyBytesObject *)self)->ob_bytes[size] = '\0'; /* Trailing null */ - return 0; - } - else if (size <= alloc * 1.125) { - /* Moderate upsize; overallocate similar to list_resize() */ - alloc = size + (size >> 3) + (size < 9 ? 3 : 6); - } - else { - /* Major upsize; resize up to exact size */ - alloc = size + 1; - } - - if (((PyBytesObject *)self)->ob_exports > 0) { - /* - fprintf(stderr, "%d: %s", ((PyBytesObject *)self)->ob_exports, - ((PyBytesObject *)self)->ob_bytes); - */ - PyErr_SetString(PyExc_BufferError, - "Existing exports of data: object cannot be re-sized"); - return -1; - } - - sval = PyMem_Realloc(((PyBytesObject *)self)->ob_bytes, alloc); - if (sval == NULL) { - PyErr_NoMemory(); - return -1; - } - - ((PyBytesObject *)self)->ob_bytes = sval; - Py_SIZE(self) = size; - ((PyBytesObject *)self)->ob_alloc = alloc; - ((PyBytesObject *)self)->ob_bytes[size] = '\0'; /* Trailing null byte */ - - return 0; -} - -PyObject * -PyByteArray_Concat(PyObject *a, PyObject *b) -{ - Py_ssize_t size; - Py_buffer va, vb; - PyBytesObject *result = NULL; - - va.len = -1; - vb.len = -1; - if (_getbuffer(a, &va) < 0 || - _getbuffer(b, &vb) < 0) { - PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s", - Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name); - goto done; - } - - size = va.len + vb.len; - if (size < 0) { - return PyErr_NoMemory(); - goto done; - } - - result = (PyBytesObject *) PyByteArray_FromStringAndSize(NULL, size); - if (result != NULL) { - memcpy(result->ob_bytes, va.buf, va.len); - memcpy(result->ob_bytes + va.len, vb.buf, vb.len); - } - - done: - if (va.len != -1) - PyObject_ReleaseBuffer(a, &va); - if (vb.len != -1) - PyObject_ReleaseBuffer(b, &vb); - return (PyObject *)result; -} - -/* Functions stuffed into the type object */ - -static Py_ssize_t -bytearray_length(PyBytesObject *self) -{ - return Py_SIZE(self); -} - -static PyObject * -bytearray_iconcat(PyBytesObject *self, PyObject *other) -{ - Py_ssize_t mysize; - Py_ssize_t size; - Py_buffer vo; - - if (_getbuffer(other, &vo) < 0) { - PyErr_Format(PyExc_TypeError, "can't concat bytes to %.100s", - Py_TYPE(self)->tp_name); - return NULL; - } - - mysize = Py_SIZE(self); - size = mysize + vo.len; - if (size < 0) { - PyObject_ReleaseBuffer(other, &vo); - return PyErr_NoMemory(); - } - if (size < self->ob_alloc) { - Py_SIZE(self) = size; - self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */ - } - else if (PyByteArray_Resize((PyObject *)self, size) < 0) { - PyObject_ReleaseBuffer(other, &vo); - return NULL; - } - memcpy(self->ob_bytes + mysize, vo.buf, vo.len); - PyObject_ReleaseBuffer(other, &vo); - Py_INCREF(self); - return (PyObject *)self; -} - -static PyObject * -bytearray_repeat(PyBytesObject *self, Py_ssize_t count) -{ - PyBytesObject *result; - Py_ssize_t mysize; - Py_ssize_t size; - - if (count < 0) - count = 0; - mysize = Py_SIZE(self); - size = mysize * count; - if (count != 0 && size / count != mysize) - return PyErr_NoMemory(); - result = (PyBytesObject *)PyByteArray_FromStringAndSize(NULL, size); - if (result != NULL && size != 0) { - if (mysize == 1) - memset(result->ob_bytes, self->ob_bytes[0], size); - else { - Py_ssize_t i; - for (i = 0; i < count; i++) - memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize); - } - } - return (PyObject *)result; -} - -static PyObject * -bytearray_irepeat(PyBytesObject *self, Py_ssize_t count) -{ - Py_ssize_t mysize; - Py_ssize_t size; - - if (count < 0) - count = 0; - mysize = Py_SIZE(self); - size = mysize * count; - if (count != 0 && size / count != mysize) - return PyErr_NoMemory(); - if (size < self->ob_alloc) { - Py_SIZE(self) = size; - self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */ - } - else if (PyByteArray_Resize((PyObject *)self, size) < 0) - return NULL; - - if (mysize == 1) - memset(self->ob_bytes, self->ob_bytes[0], size); - else { - Py_ssize_t i; - for (i = 1; i < count; i++) - memcpy(self->ob_bytes + i*mysize, self->ob_bytes, mysize); - } - - Py_INCREF(self); - return (PyObject *)self; -} - -static PyObject * -bytearray_getitem(PyBytesObject *self, Py_ssize_t i) -{ - if (i < 0) - i += Py_SIZE(self); - if (i < 0 || i >= Py_SIZE(self)) { - PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); - return NULL; - } - return PyLong_FromLong((unsigned char)(self->ob_bytes[i])); -} - -static PyObject * -bytearray_subscript(PyBytesObject *self, PyObject *item) -{ - if (PyIndex_Check(item)) { - Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); - - if (i == -1 && PyErr_Occurred()) - return NULL; - - if (i < 0) - i += PyByteArray_GET_SIZE(self); - - if (i < 0 || i >= Py_SIZE(self)) { - PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); - return NULL; - } - return PyLong_FromLong((unsigned char)(self->ob_bytes[i])); - } - else if (PySlice_Check(item)) { - Py_ssize_t start, stop, step, slicelength, cur, i; - if (PySlice_GetIndicesEx((PySliceObject *)item, - PyByteArray_GET_SIZE(self), - &start, &stop, &step, &slicelength) < 0) { - return NULL; - } - - if (slicelength <= 0) - return PyByteArray_FromStringAndSize("", 0); - else if (step == 1) { - return PyByteArray_FromStringAndSize(self->ob_bytes + start, - slicelength); - } - else { - char *source_buf = PyByteArray_AS_STRING(self); - char *result_buf = (char *)PyMem_Malloc(slicelength); - PyObject *result; - - if (result_buf == NULL) - return PyErr_NoMemory(); - - for (cur = start, i = 0; i < slicelength; - cur += step, i++) { - result_buf[i] = source_buf[cur]; - } - result = PyByteArray_FromStringAndSize(result_buf, slicelength); - PyMem_Free(result_buf); - return result; - } - } - else { - PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers"); - return NULL; - } -} - -static int -bytearray_setslice(PyBytesObject *self, Py_ssize_t lo, Py_ssize_t hi, - PyObject *values) -{ - Py_ssize_t avail, needed; - void *bytes; - Py_buffer vbytes; - int res = 0; - - vbytes.len = -1; - if (values == (PyObject *)self) { - /* Make a copy and call this function recursively */ - int err; - values = PyByteArray_FromObject(values); - if (values == NULL) - return -1; - err = bytearray_setslice(self, lo, hi, values); - Py_DECREF(values); - return err; - } - if (values == NULL) { - /* del b[lo:hi] */ - bytes = NULL; - needed = 0; - } - else { - if (_getbuffer(values, &vbytes) < 0) { - PyErr_Format(PyExc_TypeError, - "can't set bytes slice from %.100s", - Py_TYPE(values)->tp_name); - return -1; - } - needed = vbytes.len; - bytes = vbytes.buf; - } - - if (lo < 0) - lo = 0; - if (hi < lo) - hi = lo; - if (hi > Py_SIZE(self)) - hi = Py_SIZE(self); - - avail = hi - lo; - if (avail < 0) - lo = hi = avail = 0; - - if (avail != needed) { - if (avail > needed) { - /* - 0 lo hi old_size - | |<----avail----->|<-----tomove------>| - | |<-needed->|<-----tomove------>| - 0 lo new_hi new_size - */ - memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi, - Py_SIZE(self) - hi); - } - /* XXX(nnorwitz): need to verify this can't overflow! */ - if (PyByteArray_Resize((PyObject *)self, - Py_SIZE(self) + needed - avail) < 0) { - res = -1; - goto finish; - } - if (avail < needed) { - /* - 0 lo hi old_size - | |<-avail->|<-----tomove------>| - | |<----needed---->|<-----tomove------>| - 0 lo new_hi new_size - */ - memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi, - Py_SIZE(self) - lo - needed); - } - } - - if (needed > 0) - memcpy(self->ob_bytes + lo, bytes, needed); - - - finish: - if (vbytes.len != -1) - PyObject_ReleaseBuffer(values, &vbytes); - return res; -} - -static int -bytearray_setitem(PyBytesObject *self, Py_ssize_t i, PyObject *value) -{ - Py_ssize_t ival; - - if (i < 0) - i += Py_SIZE(self); - - if (i < 0 || i >= Py_SIZE(self)) { - PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); - return -1; - } - - if (value == NULL) - return bytearray_setslice(self, i, i+1, NULL); - - ival = PyNumber_AsSsize_t(value, PyExc_ValueError); - if (ival == -1 && PyErr_Occurred()) - return -1; - - if (ival < 0 || ival >= 256) { - PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); - return -1; - } - - self->ob_bytes[i] = ival; - return 0; -} - -static int -bytearray_ass_subscript(PyBytesObject *self, PyObject *item, PyObject *values) -{ - Py_ssize_t start, stop, step, slicelen, needed; - char *bytes; - - if (PyIndex_Check(item)) { - Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); - - if (i == -1 && PyErr_Occurred()) - return -1; - - if (i < 0) - i += PyByteArray_GET_SIZE(self); - - if (i < 0 || i >= Py_SIZE(self)) { - PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); - return -1; - } - - if (values == NULL) { - /* Fall through to slice assignment */ - start = i; - stop = i + 1; - step = 1; - slicelen = 1; - } - else { - Py_ssize_t ival = PyNumber_AsSsize_t(values, PyExc_ValueError); - if (ival == -1 && PyErr_Occurred()) - return -1; - if (ival < 0 || ival >= 256) { - PyErr_SetString(PyExc_ValueError, - "byte must be in range(0, 256)"); - return -1; - } - self->ob_bytes[i] = (char)ival; - return 0; - } - } - else if (PySlice_Check(item)) { - if (PySlice_GetIndicesEx((PySliceObject *)item, - PyByteArray_GET_SIZE(self), - &start, &stop, &step, &slicelen) < 0) { - return -1; - } - } - else { - PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer"); - return -1; - } - - if (values == NULL) { - bytes = NULL; - needed = 0; - } - else if (values == (PyObject *)self || !PyByteArray_Check(values)) { - /* Make a copy an call this function recursively */ - int err; - values = PyByteArray_FromObject(values); - if (values == NULL) - return -1; - err = bytearray_ass_subscript(self, item, values); - Py_DECREF(values); - return err; - } - else { - assert(PyByteArray_Check(values)); - bytes = ((PyBytesObject *)values)->ob_bytes; - needed = Py_SIZE(values); - } - /* Make sure b[5:2] = ... inserts before 5, not before 2. */ - if ((step < 0 && start < stop) || - (step > 0 && start > stop)) - stop = start; - if (step == 1) { - if (slicelen != needed) { - if (slicelen > needed) { - /* - 0 start stop old_size - | |<---slicelen--->|<-----tomove------>| - | |<-needed->|<-----tomove------>| - 0 lo new_hi new_size - */ - memmove(self->ob_bytes + start + needed, self->ob_bytes + stop, - Py_SIZE(self) - stop); - } - if (PyByteArray_Resize((PyObject *)self, - Py_SIZE(self) + needed - slicelen) < 0) - return -1; - if (slicelen < needed) { - /* - 0 lo hi old_size - | |<-avail->|<-----tomove------>| - | |<----needed---->|<-----tomove------>| - 0 lo new_hi new_size - */ - memmove(self->ob_bytes + start + needed, self->ob_bytes + stop, - Py_SIZE(self) - start - needed); - } - } - - if (needed > 0) - memcpy(self->ob_bytes + start, bytes, needed); - - return 0; - } - else { - if (needed == 0) { - /* Delete slice */ - Py_ssize_t cur, i; - - if (step < 0) { - stop = start + 1; - start = stop + step * (slicelen - 1) - 1; - step = -step; - } - for (cur = start, i = 0; - i < slicelen; cur += step, i++) { - Py_ssize_t lim = step - 1; - - if (cur + step >= PyByteArray_GET_SIZE(self)) - lim = PyByteArray_GET_SIZE(self) - cur - 1; - - memmove(self->ob_bytes + cur - i, - self->ob_bytes + cur + 1, lim); - } - /* Move the tail of the bytes, in one chunk */ - cur = start + slicelen*step; - if (cur < PyByteArray_GET_SIZE(self)) { - memmove(self->ob_bytes + cur - slicelen, - self->ob_bytes + cur, - PyByteArray_GET_SIZE(self) - cur); - } - if (PyByteArray_Resize((PyObject *)self, - PyByteArray_GET_SIZE(self) - slicelen) < 0) - return -1; - - return 0; - } - else { - /* Assign slice */ - Py_ssize_t cur, i; - - if (needed != slicelen) { - PyErr_Format(PyExc_ValueError, - "attempt to assign bytes of size %zd " - "to extended slice of size %zd", - needed, slicelen); - return -1; - } - for (cur = start, i = 0; i < slicelen; cur += step, i++) - self->ob_bytes[cur] = bytes[i]; - return 0; - } - } -} - -static int -bytearray_init(PyBytesObject *self, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"source", "encoding", "errors", 0}; - PyObject *arg = NULL; - const char *encoding = NULL; - const char *errors = NULL; - Py_ssize_t count; - PyObject *it; - PyObject *(*iternext)(PyObject *); - - if (Py_SIZE(self) != 0) { - /* Empty previous contents (yes, do this first of all!) */ - if (PyByteArray_Resize((PyObject *)self, 0) < 0) - return -1; - } - - /* Parse arguments */ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytes", kwlist, - &arg, &encoding, &errors)) - return -1; - - /* Make a quick exit if no first argument */ - if (arg == NULL) { - if (encoding != NULL || errors != NULL) { - PyErr_SetString(PyExc_TypeError, - "encoding or errors without sequence argument"); - return -1; - } - return 0; - } - - if (PyUnicode_Check(arg)) { - /* Encode via the codec registry */ - PyObject *encoded, *new; - if (encoding == NULL) { - PyErr_SetString(PyExc_TypeError, - "string argument without an encoding"); - return -1; - } - encoded = PyCodec_Encode(arg, encoding, errors); - if (encoded == NULL) - return -1; - assert(PyBytes_Check(encoded)); - new = bytearray_iconcat(self, encoded); - Py_DECREF(encoded); - if (new == NULL) - return -1; - Py_DECREF(new); - return 0; - } - - /* If it's not unicode, there can't be encoding or errors */ - if (encoding != NULL || errors != NULL) { - PyErr_SetString(PyExc_TypeError, - "encoding or errors without a string argument"); - return -1; - } - - /* Is it an int? */ - count = PyNumber_AsSsize_t(arg, PyExc_ValueError); - if (count == -1 && PyErr_Occurred()) - PyErr_Clear(); - else { - if (count < 0) { - PyErr_SetString(PyExc_ValueError, "negative count"); - return -1; - } - if (count > 0) { - if (PyByteArray_Resize((PyObject *)self, count)) - return -1; - memset(self->ob_bytes, 0, count); - } - return 0; - } - - /* Use the buffer API */ - if (PyObject_CheckBuffer(arg)) { - Py_ssize_t size; - Py_buffer view; - if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0) - return -1; - size = view.len; - if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail; - if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0) - goto fail; - PyObject_ReleaseBuffer(arg, &view); - return 0; - fail: - PyObject_ReleaseBuffer(arg, &view); - return -1; - } - - /* XXX Optimize this if the arguments is a list, tuple */ - - /* Get the iterator */ - it = PyObject_GetIter(arg); - if (it == NULL) - return -1; - iternext = *Py_TYPE(it)->tp_iternext; - - /* Run the iterator to exhaustion */ - for (;;) { - PyObject *item; - Py_ssize_t value; - - /* Get the next item */ - item = iternext(it); - if (item == NULL) { - if (PyErr_Occurred()) { - if (!PyErr_ExceptionMatches(PyExc_StopIteration)) - goto error; - PyErr_Clear(); - } - break; - } - - /* Interpret it as an int (__index__) */ - value = PyNumber_AsSsize_t(item, PyExc_ValueError); - Py_DECREF(item); - if (value == -1 && PyErr_Occurred()) - goto error; - - /* Range check */ - if (value < 0 || value >= 256) { - PyErr_SetString(PyExc_ValueError, - "bytes must be in range(0, 256)"); - goto error; - } - - /* Append the byte */ - if (Py_SIZE(self) < self->ob_alloc) - Py_SIZE(self)++; - else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0) - goto error; - self->ob_bytes[Py_SIZE(self)-1] = value; - } - - /* Clean up and return success */ - Py_DECREF(it); - return 0; - - error: - /* Error handling when it != NULL */ - Py_DECREF(it); - return -1; -} - -/* Mostly copied from string_repr, but without the - "smart quote" functionality. */ -static PyObject * -bytearray_repr(PyBytesObject *self) -{ - static const char *hexdigits = "0123456789abcdef"; - const char *quote_prefix = "bytearray(b"; - const char *quote_postfix = ")"; - Py_ssize_t length = Py_SIZE(self); - /* 14 == strlen(quote_prefix) + 2 + strlen(quote_postfix) */ - size_t newsize = 14 + 4 * length; - PyObject *v; - if (newsize > PY_SSIZE_T_MAX || newsize / 4 - 3 != length) { - PyErr_SetString(PyExc_OverflowError, - "bytearray object is too large to make repr"); - return NULL; - } - v = PyUnicode_FromUnicode(NULL, newsize); - if (v == NULL) { - return NULL; - } - else { - register Py_ssize_t i; - register Py_UNICODE c; - register Py_UNICODE *p; - int quote; - - /* Figure out which quote to use; single is preferred */ - quote = '\''; - { - char *test, *start; - start = PyByteArray_AS_STRING(self); - for (test = start; test < start+length; ++test) { - if (*test == '"') { - quote = '\''; /* back to single */ - goto decided; - } - else if (*test == '\'') - quote = '"'; - } - decided: - ; - } - - p = PyUnicode_AS_UNICODE(v); - while (*quote_prefix) - *p++ = *quote_prefix++; - *p++ = quote; - - for (i = 0; i < length; i++) { - /* There's at least enough room for a hex escape - and a closing quote. */ - assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 5); - c = self->ob_bytes[i]; - if (c == '\'' || c == '\\') - *p++ = '\\', *p++ = c; - else if (c == '\t') - *p++ = '\\', *p++ = 't'; - else if (c == '\n') - *p++ = '\\', *p++ = 'n'; - else if (c == '\r') - *p++ = '\\', *p++ = 'r'; - else if (c == 0) - *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0'; - else if (c < ' ' || c >= 0x7f) { - *p++ = '\\'; - *p++ = 'x'; - *p++ = hexdigits[(c & 0xf0) >> 4]; - *p++ = hexdigits[c & 0xf]; - } - else - *p++ = c; - } - assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 1); - *p++ = quote; - while (*quote_postfix) { - *p++ = *quote_postfix++; - } - *p = '\0'; - if (PyUnicode_Resize(&v, (p - PyUnicode_AS_UNICODE(v)))) { - Py_DECREF(v); - return NULL; - } - return v; - } -} - -static PyObject * -bytearray_str(PyObject *op) -{ - if (Py_BytesWarningFlag) { - if (PyErr_WarnEx(PyExc_BytesWarning, - "str() on a bytearray instance", 1)) - return NULL; - } - return bytearray_repr((PyBytesObject*)op); -} - -static PyObject * -bytearray_richcompare(PyObject *self, PyObject *other, int op) -{ - Py_ssize_t self_size, other_size; - Py_buffer self_bytes, other_bytes; - PyObject *res; - Py_ssize_t minsize; - int cmp; - - /* Bytes can be compared to anything that supports the (binary) - buffer API. Except that a comparison with Unicode is always an - error, even if the comparison is for equality. */ - if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) || - PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) { - if (Py_BytesWarningFlag && op == Py_EQ) { - if (PyErr_WarnEx(PyExc_BytesWarning, - "Comparsion between bytearray and string", 1)) - return NULL; - } - - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - - self_size = _getbuffer(self, &self_bytes); - if (self_size < 0) { - PyErr_Clear(); - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - - other_size = _getbuffer(other, &other_bytes); - if (other_size < 0) { - PyErr_Clear(); - PyObject_ReleaseBuffer(self, &self_bytes); - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - - if (self_size != other_size && (op == Py_EQ || op == Py_NE)) { - /* Shortcut: if the lengths differ, the objects differ */ - cmp = (op == Py_NE); - } - else { - minsize = self_size; - if (other_size < minsize) - minsize = other_size; - - cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize); - /* In ISO C, memcmp() guarantees to use unsigned bytes! */ - - if (cmp == 0) { - if (self_size < other_size) - cmp = -1; - else if (self_size > other_size) - cmp = 1; - } - - switch (op) { - case Py_LT: cmp = cmp < 0; break; - case Py_LE: cmp = cmp <= 0; break; - case Py_EQ: cmp = cmp == 0; break; - case Py_NE: cmp = cmp != 0; break; - case Py_GT: cmp = cmp > 0; break; - case Py_GE: cmp = cmp >= 0; break; - } - } - - res = cmp ? Py_True : Py_False; - PyObject_ReleaseBuffer(self, &self_bytes); - PyObject_ReleaseBuffer(other, &other_bytes); - Py_INCREF(res); - return res; -} - -static void -bytearray_dealloc(PyBytesObject *self) -{ - if (self->ob_bytes != 0) { - PyMem_Free(self->ob_bytes); - } - Py_TYPE(self)->tp_free((PyObject *)self); -} - - -/* -------------------------------------------------------------------- */ -/* Methods */ - -#define STRINGLIB_CHAR char -#define STRINGLIB_CMP memcmp -#define STRINGLIB_LEN PyByteArray_GET_SIZE -#define STRINGLIB_STR PyByteArray_AS_STRING -#define STRINGLIB_NEW PyByteArray_FromStringAndSize -#define STRINGLIB_EMPTY nullbytes -#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact -#define STRINGLIB_MUTABLE 1 - -#include "stringlib/fastsearch.h" -#include "stringlib/count.h" -#include "stringlib/find.h" -#include "stringlib/partition.h" -#include "stringlib/ctype.h" -#include "stringlib/transmogrify.h" - - -/* The following Py_LOCAL_INLINE and Py_LOCAL functions -were copied from the old char* style string object. */ - -Py_LOCAL_INLINE(void) -_adjust_indices(Py_ssize_t *start, Py_ssize_t *end, Py_ssize_t len) -{ - if (*end > len) - *end = len; - else if (*end < 0) - *end += len; - if (*end < 0) - *end = 0; - if (*start < 0) - *start += len; - if (*start < 0) - *start = 0; -} - - -Py_LOCAL_INLINE(Py_ssize_t) -bytearray_find_internal(PyBytesObject *self, PyObject *args, int dir) -{ - PyObject *subobj; - Py_buffer subbuf; - Py_ssize_t start=0, end=PY_SSIZE_T_MAX; - Py_ssize_t res; - - if (!PyArg_ParseTuple(args, "O|O&O&:find/rfind/index/rindex", &subobj, - _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end)) - return -2; - if (_getbuffer(subobj, &subbuf) < 0) - return -2; - if (dir > 0) - res = stringlib_find_slice( - PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), - subbuf.buf, subbuf.len, start, end); - else - res = stringlib_rfind_slice( - PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), - subbuf.buf, subbuf.len, start, end); - PyObject_ReleaseBuffer(subobj, &subbuf); - return res; -} - -PyDoc_STRVAR(find__doc__, -"B.find(sub [,start [,end]]) -> int\n\ -\n\ -Return the lowest index in B where subsection sub is found,\n\ -such that sub is contained within s[start,end]. Optional\n\ -arguments start and end are interpreted as in slice notation.\n\ -\n\ -Return -1 on failure."); - -static PyObject * -bytearray_find(PyBytesObject *self, PyObject *args) -{ - Py_ssize_t result = bytearray_find_internal(self, args, +1); - if (result == -2) - return NULL; - return PyLong_FromSsize_t(result); -} - -PyDoc_STRVAR(count__doc__, -"B.count(sub [,start [,end]]) -> int\n\ -\n\ -Return the number of non-overlapping occurrences of subsection sub in\n\ -bytes B[start:end]. Optional arguments start and end are interpreted\n\ -as in slice notation."); - -static PyObject * -bytearray_count(PyBytesObject *self, PyObject *args) -{ - PyObject *sub_obj; - const char *str = PyByteArray_AS_STRING(self); - Py_ssize_t start = 0, end = PY_SSIZE_T_MAX; - Py_buffer vsub; - PyObject *count_obj; - - if (!PyArg_ParseTuple(args, "O|O&O&:count", &sub_obj, - _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end)) - return NULL; - - if (_getbuffer(sub_obj, &vsub) < 0) - return NULL; - - _adjust_indices(&start, &end, PyByteArray_GET_SIZE(self)); - - count_obj = PyLong_FromSsize_t( - stringlib_count(str + start, end - start, vsub.buf, vsub.len) - ); - PyObject_ReleaseBuffer(sub_obj, &vsub); - return count_obj; -} - - -PyDoc_STRVAR(index__doc__, -"B.index(sub [,start [,end]]) -> int\n\ -\n\ -Like B.find() but raise ValueError when the subsection is not found."); - -static PyObject * -bytearray_index(PyBytesObject *self, PyObject *args) -{ - Py_ssize_t result = bytearray_find_internal(self, args, +1); - if (result == -2) - return NULL; - if (result == -1) { - PyErr_SetString(PyExc_ValueError, - "subsection not found"); - return NULL; - } - return PyLong_FromSsize_t(result); -} - - -PyDoc_STRVAR(rfind__doc__, -"B.rfind(sub [,start [,end]]) -> int\n\ -\n\ -Return the highest index in B where subsection sub is found,\n\ -such that sub is contained within s[start,end]. Optional\n\ -arguments start and end are interpreted as in slice notation.\n\ -\n\ -Return -1 on failure."); - -static PyObject * -bytearray_rfind(PyBytesObject *self, PyObject *args) -{ - Py_ssize_t result = bytearray_find_internal(self, args, -1); - if (result == -2) - return NULL; - return PyLong_FromSsize_t(result); -} - - -PyDoc_STRVAR(rindex__doc__, -"B.rindex(sub [,start [,end]]) -> int\n\ -\n\ -Like B.rfind() but raise ValueError when the subsection is not found."); - -static PyObject * -bytearray_rindex(PyBytesObject *self, PyObject *args) -{ - Py_ssize_t result = bytearray_find_internal(self, args, -1); - if (result == -2) - return NULL; - if (result == -1) { - PyErr_SetString(PyExc_ValueError, - "subsection not found"); - return NULL; - } - return PyLong_FromSsize_t(result); -} - - -static int -bytearray_contains(PyObject *self, PyObject *arg) -{ - Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError); - if (ival == -1 && PyErr_Occurred()) { - Py_buffer varg; - int pos; - PyErr_Clear(); - if (_getbuffer(arg, &varg) < 0) - return -1; - pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self), - varg.buf, varg.len, 0); - PyObject_ReleaseBuffer(arg, &varg); - return pos >= 0; - } - if (ival < 0 || ival >= 256) { - PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); - return -1; - } - - return memchr(PyByteArray_AS_STRING(self), ival, Py_SIZE(self)) != NULL; -} - - -/* Matches the end (direction >= 0) or start (direction < 0) of self - * against substr, using the start and end arguments. Returns - * -1 on error, 0 if not found and 1 if found. - */ -Py_LOCAL(int) -_bytes_tailmatch(PyBytesObject *self, PyObject *substr, Py_ssize_t start, - Py_ssize_t end, int direction) -{ - Py_ssize_t len = PyByteArray_GET_SIZE(self); - const char* str; - Py_buffer vsubstr; - int rv = 0; - - str = PyByteArray_AS_STRING(self); - - if (_getbuffer(substr, &vsubstr) < 0) - return -1; - - _adjust_indices(&start, &end, len); - - if (direction < 0) { - /* startswith */ - if (start+vsubstr.len > len) { - goto done; - } - } else { - /* endswith */ - if (end-start < vsubstr.len || start > len) { - goto done; - } - - if (end-vsubstr.len > start) - start = end - vsubstr.len; - } - if (end-start >= vsubstr.len) - rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len); - -done: - PyObject_ReleaseBuffer(substr, &vsubstr); - return rv; -} - - -PyDoc_STRVAR(startswith__doc__, -"B.startswith(prefix [,start [,end]]) -> bool\n\ -\n\ -Return True if B starts with the specified prefix, False otherwise.\n\ -With optional start, test B beginning at that position.\n\ -With optional end, stop comparing B at that position.\n\ -prefix can also be a tuple of strings to try."); - -static PyObject * -bytearray_startswith(PyBytesObject *self, PyObject *args) -{ - Py_ssize_t start = 0; - Py_ssize_t end = PY_SSIZE_T_MAX; - PyObject *subobj; - int result; - - if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &subobj, - _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end)) - return NULL; - if (PyTuple_Check(subobj)) { - Py_ssize_t i; - for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) { - result = _bytes_tailmatch(self, - PyTuple_GET_ITEM(subobj, i), - start, end, -1); - if (result == -1) - return NULL; - else if (result) { - Py_RETURN_TRUE; - } - } - Py_RETURN_FALSE; - } - result = _bytes_tailmatch(self, subobj, start, end, -1); - if (result == -1) - return NULL; - else - return PyBool_FromLong(result); -} - -PyDoc_STRVAR(endswith__doc__, -"B.endswith(suffix [,start [,end]]) -> bool\n\ -\n\ -Return True if B ends with the specified suffix, False otherwise.\n\ -With optional start, test B beginning at that position.\n\ -With optional end, stop comparing B at that position.\n\ -suffix can also be a tuple of strings to try."); - -static PyObject * -bytearray_endswith(PyBytesObject *self, PyObject *args) -{ - Py_ssize_t start = 0; - Py_ssize_t end = PY_SSIZE_T_MAX; - PyObject *subobj; - int result; - - if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &subobj, - _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end)) - return NULL; - if (PyTuple_Check(subobj)) { - Py_ssize_t i; - for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) { - result = _bytes_tailmatch(self, - PyTuple_GET_ITEM(subobj, i), - start, end, +1); - if (result == -1) - return NULL; - else if (result) { - Py_RETURN_TRUE; - } - } - Py_RETURN_FALSE; - } - result = _bytes_tailmatch(self, subobj, start, end, +1); - if (result == -1) - return NULL; - else - return PyBool_FromLong(result); -} - - -PyDoc_STRVAR(translate__doc__, -"B.translate(table[, deletechars]) -> bytearray\n\ -\n\ -Return a copy of B, where all characters occurring in the\n\ -optional argument deletechars are removed, and the remaining\n\ -characters have been mapped through the given translation\n\ -table, which must be a bytes object of length 256."); - -static PyObject * -bytearray_translate(PyBytesObject *self, PyObject *args) -{ - register char *input, *output; - register const char *table; - register Py_ssize_t i, c, changed = 0; - PyObject *input_obj = (PyObject*)self; - const char *output_start; - Py_ssize_t inlen; - PyObject *result; - int trans_table[256]; - PyObject *tableobj, *delobj = NULL; - Py_buffer vtable, vdel; - - if (!PyArg_UnpackTuple(args, "translate", 1, 2, - &tableobj, &delobj)) - return NULL; - - if (_getbuffer(tableobj, &vtable) < 0) - return NULL; - - if (vtable.len != 256) { - PyErr_SetString(PyExc_ValueError, - "translation table must be 256 characters long"); - result = NULL; - goto done; - } - - if (delobj != NULL) { - if (_getbuffer(delobj, &vdel) < 0) { - result = NULL; - goto done; - } - } - else { - vdel.buf = NULL; - vdel.len = 0; - } - - table = (const char *)vtable.buf; - inlen = PyByteArray_GET_SIZE(input_obj); - result = PyByteArray_FromStringAndSize((char *)NULL, inlen); - if (result == NULL) - goto done; - output_start = output = PyByteArray_AsString(result); - input = PyByteArray_AS_STRING(input_obj); - - if (vdel.len == 0) { - /* If no deletions are required, use faster code */ - for (i = inlen; --i >= 0; ) { - c = Py_CHARMASK(*input++); - if (Py_CHARMASK((*output++ = table[c])) != c) - changed = 1; - } - if (changed || !PyByteArray_CheckExact(input_obj)) - goto done; - Py_DECREF(result); - Py_INCREF(input_obj); - result = input_obj; - goto done; - } - - for (i = 0; i < 256; i++) - trans_table[i] = Py_CHARMASK(table[i]); - - for (i = 0; i < vdel.len; i++) - trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1; - - for (i = inlen; --i >= 0; ) { - c = Py_CHARMASK(*input++); - if (trans_table[c] != -1) - if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c) - continue; - changed = 1; - } - if (!changed && PyByteArray_CheckExact(input_obj)) { - Py_DECREF(result); - Py_INCREF(input_obj); - result = input_obj; - goto done; - } - /* Fix the size of the resulting string */ - if (inlen > 0) - PyByteArray_Resize(result, output - output_start); - -done: - PyObject_ReleaseBuffer(tableobj, &vtable); - if (delobj != NULL) - PyObject_ReleaseBuffer(delobj, &vdel); - return result; -} - - -#define FORWARD 1 -#define REVERSE -1 - -/* find and count characters and substrings */ - -#define findchar(target, target_len, c) \ - ((char *)memchr((const void *)(target), c, target_len)) - -/* Don't call if length < 2 */ -#define Py_STRING_MATCH(target, offset, pattern, length) \ - (target[offset] == pattern[0] && \ - target[offset+length-1] == pattern[length-1] && \ - !memcmp(target+offset+1, pattern+1, length-2) ) - - -/* Bytes ops must return a string. */ -/* If the object is subclass of bytes, create a copy */ -Py_LOCAL(PyBytesObject *) -return_self(PyBytesObject *self) -{ - if (PyByteArray_CheckExact(self)) { - Py_INCREF(self); - return (PyBytesObject *)self; - } - return (PyBytesObject *)PyByteArray_FromStringAndSize( - PyByteArray_AS_STRING(self), - PyByteArray_GET_SIZE(self)); -} - -Py_LOCAL_INLINE(Py_ssize_t) -countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount) -{ - Py_ssize_t count=0; - const char *start=target; - const char *end=target+target_len; - - while ( (start=findchar(start, end-start, c)) != NULL ) { - count++; - if (count >= maxcount) - break; - start += 1; - } - return count; -} - -Py_LOCAL(Py_ssize_t) -findstring(const char *target, Py_ssize_t target_len, - const char *pattern, Py_ssize_t pattern_len, - Py_ssize_t start, - Py_ssize_t end, - int direction) -{ - if (start < 0) { - start += target_len; - if (start < 0) - start = 0; - } - if (end > target_len) { - end = target_len; - } else if (end < 0) { - end += target_len; - if (end < 0) - end = 0; - } - - /* zero-length substrings always match at the first attempt */ - if (pattern_len == 0) - return (direction > 0) ? start : end; - - end -= pattern_len; - - if (direction < 0) { - for (; end >= start; end--) - if (Py_STRING_MATCH(target, end, pattern, pattern_len)) - return end; - } else { - for (; start <= end; start++) - if (Py_STRING_MATCH(target, start, pattern, pattern_len)) - return start; - } - return -1; -} - -Py_LOCAL_INLINE(Py_ssize_t) -countstring(const char *target, Py_ssize_t target_len, - const char *pattern, Py_ssize_t pattern_len, - Py_ssize_t start, - Py_ssize_t end, - int direction, Py_ssize_t maxcount) -{ - Py_ssize_t count=0; - - if (start < 0) { - start += target_len; - if (start < 0) - start = 0; - } - if (end > target_len) { - end = target_len; - } else if (end < 0) { - end += target_len; - if (end < 0) - end = 0; - } - - /* zero-length substrings match everywhere */ - if (pattern_len == 0 || maxcount == 0) { - if (target_len+1 < maxcount) - return target_len+1; - return maxcount; - } - - end -= pattern_len; - if (direction < 0) { - for (; (end >= start); end--) - if (Py_STRING_MATCH(target, end, pattern, pattern_len)) { - count++; - if (--maxcount <= 0) break; - end -= pattern_len-1; - } - } else { - for (; (start <= end); start++) - if (Py_STRING_MATCH(target, start, pattern, pattern_len)) { - count++; - if (--maxcount <= 0) - break; - start += pattern_len-1; - } - } - return count; -} - - -/* Algorithms for different cases of string replacement */ - -/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */ -Py_LOCAL(PyBytesObject *) -replace_interleave(PyBytesObject *self, - const char *to_s, Py_ssize_t to_len, - Py_ssize_t maxcount) -{ - char *self_s, *result_s; - Py_ssize_t self_len, result_len; - Py_ssize_t count, i, product; - PyBytesObject *result; - - self_len = PyByteArray_GET_SIZE(self); - - /* 1 at the end plus 1 after every character */ - count = self_len+1; - if (maxcount < count) - count = maxcount; - - /* Check for overflow */ - /* result_len = count * to_len + self_len; */ - product = count * to_len; - if (product / to_len != count) { - PyErr_SetString(PyExc_OverflowError, - "replace string is too long"); - return NULL; - } - result_len = product + self_len; - if (result_len < 0) { - PyErr_SetString(PyExc_OverflowError, - "replace string is too long"); - return NULL; - } - - if (! (result = (PyBytesObject *) - PyByteArray_FromStringAndSize(NULL, result_len)) ) - return NULL; - - self_s = PyByteArray_AS_STRING(self); - result_s = PyByteArray_AS_STRING(result); - - /* TODO: special case single character, which doesn't need memcpy */ - - /* Lay the first one down (guaranteed this will occur) */ - Py_MEMCPY(result_s, to_s, to_len); - result_s += to_len; - count -= 1; - - for (i=0; i=1, len(from)==1, to="", maxcount>=1 */ -Py_LOCAL(PyBytesObject *) -replace_delete_single_character(PyBytesObject *self, - char from_c, Py_ssize_t maxcount) -{ - char *self_s, *result_s; - char *start, *next, *end; - Py_ssize_t self_len, result_len; - Py_ssize_t count; - PyBytesObject *result; - - self_len = PyByteArray_GET_SIZE(self); - self_s = PyByteArray_AS_STRING(self); - - count = countchar(self_s, self_len, from_c, maxcount); - if (count == 0) { - return return_self(self); - } - - result_len = self_len - count; /* from_len == 1 */ - assert(result_len>=0); - - if ( (result = (PyBytesObject *) - PyByteArray_FromStringAndSize(NULL, result_len)) == NULL) - return NULL; - result_s = PyByteArray_AS_STRING(result); - - start = self_s; - end = self_s + self_len; - while (count-- > 0) { - next = findchar(start, end-start, from_c); - if (next == NULL) - break; - Py_MEMCPY(result_s, start, next-start); - result_s += (next-start); - start = next+1; - } - Py_MEMCPY(result_s, start, end-start); - - return result; -} - -/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */ - -Py_LOCAL(PyBytesObject *) -replace_delete_substring(PyBytesObject *self, - const char *from_s, Py_ssize_t from_len, - Py_ssize_t maxcount) -{ - char *self_s, *result_s; - char *start, *next, *end; - Py_ssize_t self_len, result_len; - Py_ssize_t count, offset; - PyBytesObject *result; - - self_len = PyByteArray_GET_SIZE(self); - self_s = PyByteArray_AS_STRING(self); - - count = countstring(self_s, self_len, - from_s, from_len, - 0, self_len, 1, - maxcount); - - if (count == 0) { - /* no matches */ - return return_self(self); - } - - result_len = self_len - (count * from_len); - assert (result_len>=0); - - if ( (result = (PyBytesObject *) - PyByteArray_FromStringAndSize(NULL, result_len)) == NULL ) - return NULL; - - result_s = PyByteArray_AS_STRING(result); - - start = self_s; - end = self_s + self_len; - while (count-- > 0) { - offset = findstring(start, end-start, - from_s, from_len, - 0, end-start, FORWARD); - if (offset == -1) - break; - next = start + offset; - - Py_MEMCPY(result_s, start, next-start); - - result_s += (next-start); - start = next+from_len; - } - Py_MEMCPY(result_s, start, end-start); - return result; -} - -/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */ -Py_LOCAL(PyBytesObject *) -replace_single_character_in_place(PyBytesObject *self, - char from_c, char to_c, - Py_ssize_t maxcount) -{ - char *self_s, *result_s, *start, *end, *next; - Py_ssize_t self_len; - PyBytesObject *result; - - /* The result string will be the same size */ - self_s = PyByteArray_AS_STRING(self); - self_len = PyByteArray_GET_SIZE(self); - - next = findchar(self_s, self_len, from_c); - - if (next == NULL) { - /* No matches; return the original bytes */ - return return_self(self); - } - - /* Need to make a new bytes */ - result = (PyBytesObject *) PyByteArray_FromStringAndSize(NULL, self_len); - if (result == NULL) - return NULL; - result_s = PyByteArray_AS_STRING(result); - Py_MEMCPY(result_s, self_s, self_len); - - /* change everything in-place, starting with this one */ - start = result_s + (next-self_s); - *start = to_c; - start++; - end = result_s + self_len; - - while (--maxcount > 0) { - next = findchar(start, end-start, from_c); - if (next == NULL) - break; - *next = to_c; - start = next+1; - } - - return result; -} - -/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */ -Py_LOCAL(PyBytesObject *) -replace_substring_in_place(PyBytesObject *self, - const char *from_s, Py_ssize_t from_len, - const char *to_s, Py_ssize_t to_len, - Py_ssize_t maxcount) -{ - char *result_s, *start, *end; - char *self_s; - Py_ssize_t self_len, offset; - PyBytesObject *result; - - /* The result bytes will be the same size */ - - self_s = PyByteArray_AS_STRING(self); - self_len = PyByteArray_GET_SIZE(self); - - offset = findstring(self_s, self_len, - from_s, from_len, - 0, self_len, FORWARD); - if (offset == -1) { - /* No matches; return the original bytes */ - return return_self(self); - } - - /* Need to make a new bytes */ - result = (PyBytesObject *) PyByteArray_FromStringAndSize(NULL, self_len); - if (result == NULL) - return NULL; - result_s = PyByteArray_AS_STRING(result); - Py_MEMCPY(result_s, self_s, self_len); - - /* change everything in-place, starting with this one */ - start = result_s + offset; - Py_MEMCPY(start, to_s, from_len); - start += from_len; - end = result_s + self_len; - - while ( --maxcount > 0) { - offset = findstring(start, end-start, - from_s, from_len, - 0, end-start, FORWARD); - if (offset==-1) - break; - Py_MEMCPY(start+offset, to_s, from_len); - start += offset+from_len; - } - - return result; -} - -/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */ -Py_LOCAL(PyBytesObject *) -replace_single_character(PyBytesObject *self, - char from_c, - const char *to_s, Py_ssize_t to_len, - Py_ssize_t maxcount) -{ - char *self_s, *result_s; - char *start, *next, *end; - Py_ssize_t self_len, result_len; - Py_ssize_t count, product; - PyBytesObject *result; - - self_s = PyByteArray_AS_STRING(self); - self_len = PyByteArray_GET_SIZE(self); - - count = countchar(self_s, self_len, from_c, maxcount); - if (count == 0) { - /* no matches, return unchanged */ - return return_self(self); - } - - /* use the difference between current and new, hence the "-1" */ - /* result_len = self_len + count * (to_len-1) */ - product = count * (to_len-1); - if (product / (to_len-1) != count) { - PyErr_SetString(PyExc_OverflowError, "replace bytes is too long"); - return NULL; - } - result_len = self_len + product; - if (result_len < 0) { - PyErr_SetString(PyExc_OverflowError, "replace bytes is too long"); - return NULL; - } - - if ( (result = (PyBytesObject *) - PyByteArray_FromStringAndSize(NULL, result_len)) == NULL) - return NULL; - result_s = PyByteArray_AS_STRING(result); - - start = self_s; - end = self_s + self_len; - while (count-- > 0) { - next = findchar(start, end-start, from_c); - if (next == NULL) - break; - - if (next == start) { - /* replace with the 'to' */ - Py_MEMCPY(result_s, to_s, to_len); - result_s += to_len; - start += 1; - } else { - /* copy the unchanged old then the 'to' */ - Py_MEMCPY(result_s, start, next-start); - result_s += (next-start); - Py_MEMCPY(result_s, to_s, to_len); - result_s += to_len; - start = next+1; - } - } - /* Copy the remainder of the remaining bytes */ - Py_MEMCPY(result_s, start, end-start); - - return result; -} - -/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */ -Py_LOCAL(PyBytesObject *) -replace_substring(PyBytesObject *self, - const char *from_s, Py_ssize_t from_len, - const char *to_s, Py_ssize_t to_len, - Py_ssize_t maxcount) -{ - char *self_s, *result_s; - char *start, *next, *end; - Py_ssize_t self_len, result_len; - Py_ssize_t count, offset, product; - PyBytesObject *result; - - self_s = PyByteArray_AS_STRING(self); - self_len = PyByteArray_GET_SIZE(self); - - count = countstring(self_s, self_len, - from_s, from_len, - 0, self_len, FORWARD, maxcount); - if (count == 0) { - /* no matches, return unchanged */ - return return_self(self); - } - - /* Check for overflow */ - /* result_len = self_len + count * (to_len-from_len) */ - product = count * (to_len-from_len); - if (product / (to_len-from_len) != count) { - PyErr_SetString(PyExc_OverflowError, "replace bytes is too long"); - return NULL; - } - result_len = self_len + product; - if (result_len < 0) { - PyErr_SetString(PyExc_OverflowError, "replace bytes is too long"); - return NULL; - } - - if ( (result = (PyBytesObject *) - PyByteArray_FromStringAndSize(NULL, result_len)) == NULL) - return NULL; - result_s = PyByteArray_AS_STRING(result); - - start = self_s; - end = self_s + self_len; - while (count-- > 0) { - offset = findstring(start, end-start, - from_s, from_len, - 0, end-start, FORWARD); - if (offset == -1) - break; - next = start+offset; - if (next == start) { - /* replace with the 'to' */ - Py_MEMCPY(result_s, to_s, to_len); - result_s += to_len; - start += from_len; - } else { - /* copy the unchanged old then the 'to' */ - Py_MEMCPY(result_s, start, next-start); - result_s += (next-start); - Py_MEMCPY(result_s, to_s, to_len); - result_s += to_len; - start = next+from_len; - } - } - /* Copy the remainder of the remaining bytes */ - Py_MEMCPY(result_s, start, end-start); - - return result; -} - - -Py_LOCAL(PyBytesObject *) -replace(PyBytesObject *self, - const char *from_s, Py_ssize_t from_len, - const char *to_s, Py_ssize_t to_len, - Py_ssize_t maxcount) -{ - if (maxcount < 0) { - maxcount = PY_SSIZE_T_MAX; - } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) { - /* nothing to do; return the original bytes */ - return return_self(self); - } - - if (maxcount == 0 || - (from_len == 0 && to_len == 0)) { - /* nothing to do; return the original bytes */ - return return_self(self); - } - - /* Handle zero-length special cases */ - - if (from_len == 0) { - /* insert the 'to' bytes everywhere. */ - /* >>> "Python".replace("", ".") */ - /* '.P.y.t.h.o.n.' */ - return replace_interleave(self, to_s, to_len, maxcount); - } - - /* Except for "".replace("", "A") == "A" there is no way beyond this */ - /* point for an empty self bytes to generate a non-empty bytes */ - /* Special case so the remaining code always gets a non-empty bytes */ - if (PyByteArray_GET_SIZE(self) == 0) { - return return_self(self); - } - - if (to_len == 0) { - /* delete all occurances of 'from' bytes */ - if (from_len == 1) { - return replace_delete_single_character( - self, from_s[0], maxcount); - } else { - return replace_delete_substring(self, from_s, from_len, maxcount); - } - } - - /* Handle special case where both bytes have the same length */ - - if (from_len == to_len) { - if (from_len == 1) { - return replace_single_character_in_place( - self, - from_s[0], - to_s[0], - maxcount); - } else { - return replace_substring_in_place( - self, from_s, from_len, to_s, to_len, maxcount); - } - } - - /* Otherwise use the more generic algorithms */ - if (from_len == 1) { - return replace_single_character(self, from_s[0], - to_s, to_len, maxcount); - } else { - /* len('from')>=2, len('to')>=1 */ - return replace_substring(self, from_s, from_len, to_s, to_len, maxcount); - } -} - - -PyDoc_STRVAR(replace__doc__, -"B.replace(old, new[, count]) -> bytes\n\ -\n\ -Return a copy of B with all occurrences of subsection\n\ -old replaced by new. If the optional argument count is\n\ -given, only the first count occurrences are replaced."); - -static PyObject * -bytearray_replace(PyBytesObject *self, PyObject *args) -{ - Py_ssize_t count = -1; - PyObject *from, *to, *res; - Py_buffer vfrom, vto; - - if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count)) - return NULL; - - if (_getbuffer(from, &vfrom) < 0) - return NULL; - if (_getbuffer(to, &vto) < 0) { - PyObject_ReleaseBuffer(from, &vfrom); - return NULL; - } - - res = (PyObject *)replace((PyBytesObject *) self, - vfrom.buf, vfrom.len, - vto.buf, vto.len, count); - - PyObject_ReleaseBuffer(from, &vfrom); - PyObject_ReleaseBuffer(to, &vto); - return res; -} - - -/* Overallocate the initial list to reduce the number of reallocs for small - split sizes. Eg, "A A A A A A A A A A".split() (10 elements) has three - resizes, to sizes 4, 8, then 16. Most observed string splits are for human - text (roughly 11 words per line) and field delimited data (usually 1-10 - fields). For large strings the split algorithms are bandwidth limited - so increasing the preallocation likely will not improve things.*/ - -#define MAX_PREALLOC 12 - -/* 5 splits gives 6 elements */ -#define PREALLOC_SIZE(maxsplit) \ - (maxsplit >= MAX_PREALLOC ? MAX_PREALLOC : maxsplit+1) - -#define SPLIT_APPEND(data, left, right) \ - str = PyByteArray_FromStringAndSize((data) + (left), \ - (right) - (left)); \ - if (str == NULL) \ - goto onError; \ - if (PyList_Append(list, str)) { \ - Py_DECREF(str); \ - goto onError; \ - } \ - else \ - Py_DECREF(str); - -#define SPLIT_ADD(data, left, right) { \ - str = PyByteArray_FromStringAndSize((data) + (left), \ - (right) - (left)); \ - if (str == NULL) \ - goto onError; \ - if (count < MAX_PREALLOC) { \ - PyList_SET_ITEM(list, count, str); \ - } else { \ - if (PyList_Append(list, str)) { \ - Py_DECREF(str); \ - goto onError; \ - } \ - else \ - Py_DECREF(str); \ - } \ - count++; } - -/* Always force the list to the expected size. */ -#define FIX_PREALLOC_SIZE(list) Py_SIZE(list) = count - - -Py_LOCAL_INLINE(PyObject *) -split_char(const char *s, Py_ssize_t len, char ch, Py_ssize_t maxcount) -{ - register Py_ssize_t i, j, count = 0; - PyObject *str; - PyObject *list = PyList_New(PREALLOC_SIZE(maxcount)); - - if (list == NULL) - return NULL; - - i = j = 0; - while ((j < len) && (maxcount-- > 0)) { - for(; j < len; j++) { - /* I found that using memchr makes no difference */ - if (s[j] == ch) { - SPLIT_ADD(s, i, j); - i = j = j + 1; - break; - } - } - } - if (i <= len) { - SPLIT_ADD(s, i, len); - } - FIX_PREALLOC_SIZE(list); - return list; - - onError: - Py_DECREF(list); - return NULL; -} - - -Py_LOCAL_INLINE(PyObject *) -split_whitespace(const char *s, Py_ssize_t len, Py_ssize_t maxcount) -{ - register Py_ssize_t i, j, count = 0; - PyObject *str; - PyObject *list = PyList_New(PREALLOC_SIZE(maxcount)); - - if (list == NULL) - return NULL; - - for (i = j = 0; i < len; ) { - /* find a token */ - while (i < len && ISSPACE(s[i])) - i++; - j = i; - while (i < len && !ISSPACE(s[i])) - i++; - if (j < i) { - if (maxcount-- <= 0) - break; - SPLIT_ADD(s, j, i); - while (i < len && ISSPACE(s[i])) - i++; - j = i; - } - } - if (j < len) { - SPLIT_ADD(s, j, len); - } - FIX_PREALLOC_SIZE(list); - return list; - - onError: - Py_DECREF(list); - return NULL; -} - -PyDoc_STRVAR(split__doc__, -"B.split([sep[, maxsplit]]) -> list of bytearray\n\ -\n\ -Return a list of the sections in B, using sep as the delimiter.\n\ -If sep is not given, B is split on ASCII whitespace characters\n\ -(space, tab, return, newline, formfeed, vertical tab).\n\ -If maxsplit is given, at most maxsplit splits are done."); - -static PyObject * -bytearray_split(PyBytesObject *self, PyObject *args) -{ - Py_ssize_t len = PyByteArray_GET_SIZE(self), n, i, j; - Py_ssize_t maxsplit = -1, count = 0; - const char *s = PyByteArray_AS_STRING(self), *sub; - PyObject *list, *str, *subobj = Py_None; - Py_buffer vsub; -#ifdef USE_FAST - Py_ssize_t pos; -#endif - - if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit)) - return NULL; - if (maxsplit < 0) - maxsplit = PY_SSIZE_T_MAX; - - if (subobj == Py_None) - return split_whitespace(s, len, maxsplit); - - if (_getbuffer(subobj, &vsub) < 0) - return NULL; - sub = vsub.buf; - n = vsub.len; - - if (n == 0) { - PyErr_SetString(PyExc_ValueError, "empty separator"); - PyObject_ReleaseBuffer(subobj, &vsub); - return NULL; - } - if (n == 1) - return split_char(s, len, sub[0], maxsplit); - - list = PyList_New(PREALLOC_SIZE(maxsplit)); - if (list == NULL) { - PyObject_ReleaseBuffer(subobj, &vsub); - return NULL; - } - -#ifdef USE_FAST - i = j = 0; - while (maxsplit-- > 0) { - pos = fastsearch(s+i, len-i, sub, n, FAST_SEARCH); - if (pos < 0) - break; - j = i+pos; - SPLIT_ADD(s, i, j); - i = j + n; - } -#else - i = j = 0; - while ((j+n <= len) && (maxsplit-- > 0)) { - for (; j+n <= len; j++) { - if (Py_STRING_MATCH(s, j, sub, n)) { - SPLIT_ADD(s, i, j); - i = j = j + n; - break; - } - } - } -#endif - SPLIT_ADD(s, i, len); - FIX_PREALLOC_SIZE(list); - PyObject_ReleaseBuffer(subobj, &vsub); - return list; - - onError: - Py_DECREF(list); - PyObject_ReleaseBuffer(subobj, &vsub); - return NULL; -} - -/* stringlib's partition shares nullbytes in some cases. - undo this, we don't want the nullbytes to be shared. */ -static PyObject * -make_nullbytes_unique(PyObject *result) -{ - if (result != NULL) { - int i; - assert(PyTuple_Check(result)); - assert(PyTuple_GET_SIZE(result) == 3); - for (i = 0; i < 3; i++) { - if (PyTuple_GET_ITEM(result, i) == (PyObject *)nullbytes) { - PyObject *new = PyByteArray_FromStringAndSize(NULL, 0); - if (new == NULL) { - Py_DECREF(result); - result = NULL; - break; - } - Py_DECREF(nullbytes); - PyTuple_SET_ITEM(result, i, new); - } - } - } - return result; -} - -PyDoc_STRVAR(partition__doc__, -"B.partition(sep) -> (head, sep, tail)\n\ -\n\ -Searches for the separator sep in B, and returns the part before it,\n\ -the separator itself, and the part after it. If the separator is not\n\ -found, returns B and two empty bytearray objects."); - -static PyObject * -bytearray_partition(PyBytesObject *self, PyObject *sep_obj) -{ - PyObject *bytesep, *result; - - bytesep = PyByteArray_FromObject(sep_obj); - if (! bytesep) - return NULL; - - result = stringlib_partition( - (PyObject*) self, - PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), - bytesep, - PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep) - ); - - Py_DECREF(bytesep); - return make_nullbytes_unique(result); -} - -PyDoc_STRVAR(rpartition__doc__, -"B.rpartition(sep) -> (tail, sep, head)\n\ -\n\ -Searches for the separator sep in B, starting at the end of B,\n\ -and returns the part before it, the separator itself, and the\n\ -part after it. If the separator is not found, returns two empty\n\ -bytearray objects and B."); - -static PyObject * -bytearray_rpartition(PyBytesObject *self, PyObject *sep_obj) -{ - PyObject *bytesep, *result; - - bytesep = PyByteArray_FromObject(sep_obj); - if (! bytesep) - return NULL; - - result = stringlib_rpartition( - (PyObject*) self, - PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), - bytesep, - PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep) - ); - - Py_DECREF(bytesep); - return make_nullbytes_unique(result); -} - -Py_LOCAL_INLINE(PyObject *) -rsplit_char(const char *s, Py_ssize_t len, char ch, Py_ssize_t maxcount) -{ - register Py_ssize_t i, j, count=0; - PyObject *str; - PyObject *list = PyList_New(PREALLOC_SIZE(maxcount)); - - if (list == NULL) - return NULL; - - i = j = len - 1; - while ((i >= 0) && (maxcount-- > 0)) { - for (; i >= 0; i--) { - if (s[i] == ch) { - SPLIT_ADD(s, i + 1, j + 1); - j = i = i - 1; - break; - } - } - } - if (j >= -1) { - SPLIT_ADD(s, 0, j + 1); - } - FIX_PREALLOC_SIZE(list); - if (PyList_Reverse(list) < 0) - goto onError; - - return list; - - onError: - Py_DECREF(list); - return NULL; -} - -Py_LOCAL_INLINE(PyObject *) -rsplit_whitespace(const char *s, Py_ssize_t len, Py_ssize_t maxcount) -{ - register Py_ssize_t i, j, count = 0; - PyObject *str; - PyObject *list = PyList_New(PREALLOC_SIZE(maxcount)); - - if (list == NULL) - return NULL; - - for (i = j = len - 1; i >= 0; ) { - /* find a token */ - while (i >= 0 && Py_UNICODE_ISSPACE(s[i])) - i--; - j = i; - while (i >= 0 && !Py_UNICODE_ISSPACE(s[i])) - i--; - if (j > i) { - if (maxcount-- <= 0) - break; - SPLIT_ADD(s, i + 1, j + 1); - while (i >= 0 && Py_UNICODE_ISSPACE(s[i])) - i--; - j = i; - } - } - if (j >= 0) { - SPLIT_ADD(s, 0, j + 1); - } - FIX_PREALLOC_SIZE(list); - if (PyList_Reverse(list) < 0) - goto onError; - - return list; - - onError: - Py_DECREF(list); - return NULL; -} - -PyDoc_STRVAR(rsplit__doc__, -"B.rsplit(sep[, maxsplit]) -> list of bytearray\n\ -\n\ -Return a list of the sections in B, using sep as the delimiter,\n\ -starting at the end of B and working to the front.\n\ -If sep is not given, B is split on ASCII whitespace characters\n\ -(space, tab, return, newline, formfeed, vertical tab).\n\ -If maxsplit is given, at most maxsplit splits are done."); - -static PyObject * -bytearray_rsplit(PyBytesObject *self, PyObject *args) -{ - Py_ssize_t len = PyByteArray_GET_SIZE(self), n, i, j; - Py_ssize_t maxsplit = -1, count = 0; - const char *s = PyByteArray_AS_STRING(self), *sub; - PyObject *list, *str, *subobj = Py_None; - Py_buffer vsub; - - if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit)) - return NULL; - if (maxsplit < 0) - maxsplit = PY_SSIZE_T_MAX; - - if (subobj == Py_None) - return rsplit_whitespace(s, len, maxsplit); - - if (_getbuffer(subobj, &vsub) < 0) - return NULL; - sub = vsub.buf; - n = vsub.len; - - if (n == 0) { - PyErr_SetString(PyExc_ValueError, "empty separator"); - PyObject_ReleaseBuffer(subobj, &vsub); - return NULL; - } - else if (n == 1) - return rsplit_char(s, len, sub[0], maxsplit); - - list = PyList_New(PREALLOC_SIZE(maxsplit)); - if (list == NULL) { - PyObject_ReleaseBuffer(subobj, &vsub); - return NULL; - } - - j = len; - i = j - n; - - while ( (i >= 0) && (maxsplit-- > 0) ) { - for (; i>=0; i--) { - if (Py_STRING_MATCH(s, i, sub, n)) { - SPLIT_ADD(s, i + n, j); - j = i; - i -= n; - break; - } - } - } - SPLIT_ADD(s, 0, j); - FIX_PREALLOC_SIZE(list); - if (PyList_Reverse(list) < 0) - goto onError; - PyObject_ReleaseBuffer(subobj, &vsub); - return list; - -onError: - Py_DECREF(list); - PyObject_ReleaseBuffer(subobj, &vsub); - return NULL; -} - -PyDoc_STRVAR(reverse__doc__, -"B.reverse() -> None\n\ -\n\ -Reverse the order of the values in B in place."); -static PyObject * -bytearray_reverse(PyBytesObject *self, PyObject *unused) -{ - char swap, *head, *tail; - Py_ssize_t i, j, n = Py_SIZE(self); - - j = n / 2; - head = self->ob_bytes; - tail = head + n - 1; - for (i = 0; i < j; i++) { - swap = *head; - *head++ = *tail; - *tail-- = swap; - } - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(insert__doc__, -"B.insert(index, int) -> None\n\ -\n\ -Insert a single item into the bytearray before the given index."); -static PyObject * -bytearray_insert(PyBytesObject *self, PyObject *args) -{ - int value; - Py_ssize_t where, n = Py_SIZE(self); - - if (!PyArg_ParseTuple(args, "ni:insert", &where, &value)) - return NULL; - - if (n == PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, - "cannot add more objects to bytes"); - return NULL; - } - if (value < 0 || value >= 256) { - PyErr_SetString(PyExc_ValueError, - "byte must be in range(0, 256)"); - return NULL; - } - if (PyByteArray_Resize((PyObject *)self, n + 1) < 0) - return NULL; - - if (where < 0) { - where += n; - if (where < 0) - where = 0; - } - if (where > n) - where = n; - memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where); - self->ob_bytes[where] = value; - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(append__doc__, -"B.append(int) -> None\n\ -\n\ -Append a single item to the end of B."); -static PyObject * -bytearray_append(PyBytesObject *self, PyObject *arg) -{ - int value; - Py_ssize_t n = Py_SIZE(self); - - if (! _getbytevalue(arg, &value)) - return NULL; - if (n == PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, - "cannot add more objects to bytes"); - return NULL; - } - if (PyByteArray_Resize((PyObject *)self, n + 1) < 0) - return NULL; - - self->ob_bytes[n] = value; - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(extend__doc__, -"B.extend(iterable int) -> None\n\ -\n\ -Append all the elements from the iterator or sequence to the\n\ -end of B."); -static PyObject * -bytearray_extend(PyBytesObject *self, PyObject *arg) -{ - PyObject *it, *item, *tmp, *res; - Py_ssize_t buf_size = 0, len = 0; - int value; - char *buf; - - /* bytes_setslice code only accepts something supporting PEP 3118. */ - if (PyObject_CheckBuffer(arg)) { - if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1) - return NULL; - - Py_RETURN_NONE; - } - - it = PyObject_GetIter(arg); - if (it == NULL) - return NULL; - - /* Try to determine the length of the argument. 32 is abitrary. */ - buf_size = _PyObject_LengthHint(arg, 32); - - buf = (char *)PyMem_Malloc(buf_size * sizeof(char)); - if (buf == NULL) - return PyErr_NoMemory(); - - while ((item = PyIter_Next(it)) != NULL) { - if (! _getbytevalue(item, &value)) { - Py_DECREF(item); - Py_DECREF(it); - return NULL; - } - buf[len++] = value; - Py_DECREF(item); - if (len >= buf_size) { - buf_size = len + (len >> 1) + 1; - buf = (char *)PyMem_Realloc(buf, buf_size * sizeof(char)); - if (buf == NULL) { - Py_DECREF(it); - return PyErr_NoMemory(); - } - } - } - Py_DECREF(it); - - /* XXX: Is possible to avoid a full copy of the buffer? */ - tmp = PyByteArray_FromStringAndSize(buf, len); - res = bytearray_extend(self, tmp); - Py_DECREF(tmp); - PyMem_Free(buf); - - return res; -} - -PyDoc_STRVAR(pop__doc__, -"B.pop([index]) -> int\n\ -\n\ -Remove and return a single item from B. If no index\n\ -argument is give, will pop the last value."); -static PyObject * -bytearray_pop(PyBytesObject *self, PyObject *args) -{ - int value; - Py_ssize_t where = -1, n = Py_SIZE(self); - - if (!PyArg_ParseTuple(args, "|n:pop", &where)) - return NULL; - - if (n == 0) { - PyErr_SetString(PyExc_OverflowError, - "cannot pop an empty bytes"); - return NULL; - } - if (where < 0) - where += Py_SIZE(self); - if (where < 0 || where >= Py_SIZE(self)) { - PyErr_SetString(PyExc_IndexError, "pop index out of range"); - return NULL; - } - - value = self->ob_bytes[where]; - memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where); - if (PyByteArray_Resize((PyObject *)self, n - 1) < 0) - return NULL; - - return PyLong_FromLong(value); -} - -PyDoc_STRVAR(remove__doc__, -"B.remove(int) -> None\n\ -\n\ -Remove the first occurance of a value in B."); -static PyObject * -bytearray_remove(PyBytesObject *self, PyObject *arg) -{ - int value; - Py_ssize_t where, n = Py_SIZE(self); - - if (! _getbytevalue(arg, &value)) - return NULL; - - for (where = 0; where < n; where++) { - if (self->ob_bytes[where] == value) - break; - } - if (where == n) { - PyErr_SetString(PyExc_ValueError, "value not found in bytes"); - return NULL; - } - - memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where); - if (PyByteArray_Resize((PyObject *)self, n - 1) < 0) - return NULL; - - Py_RETURN_NONE; -} - -/* XXX These two helpers could be optimized if argsize == 1 */ - -static Py_ssize_t -lstrip_helper(unsigned char *myptr, Py_ssize_t mysize, - void *argptr, Py_ssize_t argsize) -{ - Py_ssize_t i = 0; - while (i < mysize && memchr(argptr, myptr[i], argsize)) - i++; - return i; -} - -static Py_ssize_t -rstrip_helper(unsigned char *myptr, Py_ssize_t mysize, - void *argptr, Py_ssize_t argsize) -{ - Py_ssize_t i = mysize - 1; - while (i >= 0 && memchr(argptr, myptr[i], argsize)) - i--; - return i + 1; -} - -PyDoc_STRVAR(strip__doc__, -"B.strip([bytes]) -> bytearray\n\ -\n\ -Strip leading and trailing bytes contained in the argument.\n\ -If the argument is omitted, strip ASCII whitespace."); -static PyObject * -bytearray_strip(PyBytesObject *self, PyObject *args) -{ - Py_ssize_t left, right, mysize, argsize; - void *myptr, *argptr; - PyObject *arg = Py_None; - Py_buffer varg; - if (!PyArg_ParseTuple(args, "|O:strip", &arg)) - return NULL; - if (arg == Py_None) { - argptr = "\t\n\r\f\v "; - argsize = 6; - } - else { - if (_getbuffer(arg, &varg) < 0) - return NULL; - argptr = varg.buf; - argsize = varg.len; - } - myptr = self->ob_bytes; - mysize = Py_SIZE(self); - left = lstrip_helper(myptr, mysize, argptr, argsize); - if (left == mysize) - right = left; - else - right = rstrip_helper(myptr, mysize, argptr, argsize); - if (arg != Py_None) - PyObject_ReleaseBuffer(arg, &varg); - return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left); -} - -PyDoc_STRVAR(lstrip__doc__, -"B.lstrip([bytes]) -> bytearray\n\ -\n\ -Strip leading bytes contained in the argument.\n\ -If the argument is omitted, strip leading ASCII whitespace."); -static PyObject * -bytearray_lstrip(PyBytesObject *self, PyObject *args) -{ - Py_ssize_t left, right, mysize, argsize; - void *myptr, *argptr; - PyObject *arg = Py_None; - Py_buffer varg; - if (!PyArg_ParseTuple(args, "|O:lstrip", &arg)) - return NULL; - if (arg == Py_None) { - argptr = "\t\n\r\f\v "; - argsize = 6; - } - else { - if (_getbuffer(arg, &varg) < 0) - return NULL; - argptr = varg.buf; - argsize = varg.len; - } - myptr = self->ob_bytes; - mysize = Py_SIZE(self); - left = lstrip_helper(myptr, mysize, argptr, argsize); - right = mysize; - if (arg != Py_None) - PyObject_ReleaseBuffer(arg, &varg); - return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left); -} - -PyDoc_STRVAR(rstrip__doc__, -"B.rstrip([bytes]) -> bytearray\n\ -\n\ -Strip trailing bytes contained in the argument.\n\ -If the argument is omitted, strip trailing ASCII whitespace."); -static PyObject * -bytearray_rstrip(PyBytesObject *self, PyObject *args) -{ - Py_ssize_t left, right, mysize, argsize; - void *myptr, *argptr; - PyObject *arg = Py_None; - Py_buffer varg; - if (!PyArg_ParseTuple(args, "|O:rstrip", &arg)) - return NULL; - if (arg == Py_None) { - argptr = "\t\n\r\f\v "; - argsize = 6; - } - else { - if (_getbuffer(arg, &varg) < 0) - return NULL; - argptr = varg.buf; - argsize = varg.len; - } - myptr = self->ob_bytes; - mysize = Py_SIZE(self); - left = 0; - right = rstrip_helper(myptr, mysize, argptr, argsize); - if (arg != Py_None) - PyObject_ReleaseBuffer(arg, &varg); - return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left); -} - -PyDoc_STRVAR(decode_doc, -"B.decode([encoding[, errors]]) -> unicode object.\n\ -\n\ -Decodes B using the codec registered for encoding. encoding defaults\n\ -to the default encoding. errors may be given to set a different error\n\ -handling scheme. Default is 'strict' meaning that encoding errors raise\n\ -a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\ -as well as any other name registered with codecs.register_error that is\n\ -able to handle UnicodeDecodeErrors."); - -static PyObject * -bytearray_decode(PyObject *self, PyObject *args) -{ - const char *encoding = NULL; - const char *errors = NULL; - - if (!PyArg_ParseTuple(args, "|ss:decode", &encoding, &errors)) - return NULL; - if (encoding == NULL) - encoding = PyUnicode_GetDefaultEncoding(); - return PyCodec_Decode(self, encoding, errors); -} - -PyDoc_STRVAR(alloc_doc, -"B.__alloc__() -> int\n\ -\n\ -Returns the number of bytes actually allocated."); - -static PyObject * -bytearray_alloc(PyBytesObject *self) -{ - return PyLong_FromSsize_t(self->ob_alloc); -} - -PyDoc_STRVAR(join_doc, -"B.join(iterable_of_bytes) -> bytes\n\ -\n\ -Concatenates any number of bytearray objects, with B in between each pair."); - -static PyObject * -bytearray_join(PyBytesObject *self, PyObject *it) -{ - PyObject *seq; - Py_ssize_t mysize = Py_SIZE(self); - Py_ssize_t i; - Py_ssize_t n; - PyObject **items; - Py_ssize_t totalsize = 0; - PyObject *result; - char *dest; - - seq = PySequence_Fast(it, "can only join an iterable"); - if (seq == NULL) - return NULL; - n = PySequence_Fast_GET_SIZE(seq); - items = PySequence_Fast_ITEMS(seq); - - /* Compute the total size, and check that they are all bytes */ - /* XXX Shouldn't we use _getbuffer() on these items instead? */ - for (i = 0; i < n; i++) { - PyObject *obj = items[i]; - if (!PyByteArray_Check(obj) && !PyBytes_Check(obj)) { - PyErr_Format(PyExc_TypeError, - "can only join an iterable of bytes " - "(item %ld has type '%.100s')", - /* XXX %ld isn't right on Win64 */ - (long)i, Py_TYPE(obj)->tp_name); - goto error; - } - if (i > 0) - totalsize += mysize; - totalsize += Py_SIZE(obj); - if (totalsize < 0) { - PyErr_NoMemory(); - goto error; - } - } - - /* Allocate the result, and copy the bytes */ - result = PyByteArray_FromStringAndSize(NULL, totalsize); - if (result == NULL) - goto error; - dest = PyByteArray_AS_STRING(result); - for (i = 0; i < n; i++) { - PyObject *obj = items[i]; - Py_ssize_t size = Py_SIZE(obj); - char *buf; - if (PyByteArray_Check(obj)) - buf = PyByteArray_AS_STRING(obj); - else - buf = PyBytes_AS_STRING(obj); - if (i) { - memcpy(dest, self->ob_bytes, mysize); - dest += mysize; - } - memcpy(dest, buf, size); - dest += size; - } - - /* Done */ - Py_DECREF(seq); - return result; - - /* Error handling */ - error: - Py_DECREF(seq); - return NULL; -} - -PyDoc_STRVAR(fromhex_doc, -"bytearray.fromhex(string) -> bytearray\n\ -\n\ -Create a bytearray object from a string of hexadecimal numbers.\n\ -Spaces between two numbers are accepted.\n\ -Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')."); - -static int -hex_digit_to_int(Py_UNICODE c) -{ - if (c >= 128) - return -1; - if (ISDIGIT(c)) - return c - '0'; - else { - if (ISUPPER(c)) - c = TOLOWER(c); - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - } - return -1; -} - -static PyObject * -bytearray_fromhex(PyObject *cls, PyObject *args) -{ - PyObject *newbytes, *hexobj; - char *buf; - Py_UNICODE *hex; - Py_ssize_t hexlen, byteslen, i, j; - int top, bot; - - if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj)) - return NULL; - assert(PyUnicode_Check(hexobj)); - hexlen = PyUnicode_GET_SIZE(hexobj); - hex = PyUnicode_AS_UNICODE(hexobj); - byteslen = hexlen/2; /* This overestimates if there are spaces */ - newbytes = PyByteArray_FromStringAndSize(NULL, byteslen); - if (!newbytes) - return NULL; - buf = PyByteArray_AS_STRING(newbytes); - for (i = j = 0; i < hexlen; i += 2) { - /* skip over spaces in the input */ - while (hex[i] == ' ') - i++; - if (i >= hexlen) - break; - top = hex_digit_to_int(hex[i]); - bot = hex_digit_to_int(hex[i+1]); - if (top == -1 || bot == -1) { - PyErr_Format(PyExc_ValueError, - "non-hexadecimal number found in " - "fromhex() arg at position %zd", i); - goto error; - } - buf[j++] = (top << 4) + bot; - } - if (PyByteArray_Resize(newbytes, j) < 0) - goto error; - return newbytes; - - error: - Py_DECREF(newbytes); - return NULL; -} - -PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); - -static PyObject * -bytearray_reduce(PyBytesObject *self) -{ - PyObject *latin1, *dict; - if (self->ob_bytes) - latin1 = PyUnicode_DecodeLatin1(self->ob_bytes, - Py_SIZE(self), NULL); - else - latin1 = PyUnicode_FromString(""); - - dict = PyObject_GetAttrString((PyObject *)self, "__dict__"); - if (dict == NULL) { - PyErr_Clear(); - dict = Py_None; - Py_INCREF(dict); - } - - return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict); -} - -static PySequenceMethods bytearray_as_sequence = { - (lenfunc)bytearray_length, /* sq_length */ - (binaryfunc)PyByteArray_Concat, /* sq_concat */ - (ssizeargfunc)bytearray_repeat, /* sq_repeat */ - (ssizeargfunc)bytearray_getitem, /* sq_item */ - 0, /* sq_slice */ - (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */ - 0, /* sq_ass_slice */ - (objobjproc)bytearray_contains, /* sq_contains */ - (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */ - (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */ -}; - -static PyMappingMethods bytearray_as_mapping = { - (lenfunc)bytearray_length, - (binaryfunc)bytearray_subscript, - (objobjargproc)bytearray_ass_subscript, -}; - -static PyBufferProcs bytearray_as_buffer = { - (getbufferproc)bytearray_getbuffer, - (releasebufferproc)bytearray_releasebuffer, -}; - -static PyMethodDef -bytearray_methods[] = { - {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc}, - {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc}, - {"append", (PyCFunction)bytearray_append, METH_O, append__doc__}, - {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS, - _Py_capitalize__doc__}, - {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__}, - {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__}, - {"decode", (PyCFunction)bytearray_decode, METH_VARARGS, decode_doc}, - {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__}, - {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS, - expandtabs__doc__}, - {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__}, - {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__}, - {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS, - fromhex_doc}, - {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__}, - {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__}, - {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS, - _Py_isalnum__doc__}, - {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS, - _Py_isalpha__doc__}, - {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS, - _Py_isdigit__doc__}, - {"islower", (PyCFunction)stringlib_islower, METH_NOARGS, - _Py_islower__doc__}, - {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS, - _Py_isspace__doc__}, - {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS, - _Py_istitle__doc__}, - {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS, - _Py_isupper__doc__}, - {"join", (PyCFunction)bytearray_join, METH_O, join_doc}, - {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__}, - {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__}, - {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__}, - {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__}, - {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__}, - {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__}, - {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__}, - {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__}, - {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__}, - {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__}, - {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__}, - {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__}, - {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__}, - {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__}, - {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__}, - {"splitlines", (PyCFunction)stringlib_splitlines, METH_VARARGS, - splitlines__doc__}, - {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS , - startswith__doc__}, - {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__}, - {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS, - _Py_swapcase__doc__}, - {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, - {"translate", (PyCFunction)bytearray_translate, METH_VARARGS, - translate__doc__}, - {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, - {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__}, - {NULL} -}; - -PyDoc_STRVAR(bytearray_doc, -"bytearray(iterable_of_ints) -> bytearray.\n\ -bytearray(string, encoding[, errors]) -> bytearray.\n\ -bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray.\n\ -bytearray(memory_view) -> bytearray.\n\ -\n\ -Construct an mutable bytearray object from:\n\ - - an iterable yielding integers in range(256)\n\ - - a text string encoded using the specified encoding\n\ - - a bytes or a bytearray object\n\ - - any object implementing the buffer API.\n\ -\n\ -bytearray(int) -> bytearray.\n\ -\n\ -Construct a zero-initialized bytearray of the given length."); - - -static PyObject *bytearray_iter(PyObject *seq); - -PyTypeObject PyByteArray_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "bytearray", - sizeof(PyBytesObject), - 0, - (destructor)bytearray_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - (reprfunc)bytearray_repr, /* tp_repr */ - 0, /* tp_as_number */ - &bytearray_as_sequence, /* tp_as_sequence */ - &bytearray_as_mapping, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - bytearray_str, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - &bytearray_as_buffer, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - bytearray_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - (richcmpfunc)bytearray_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - bytearray_iter, /* tp_iter */ - 0, /* tp_iternext */ - bytearray_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)bytearray_init, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ - PyObject_Del, /* tp_free */ -}; - -/*********************** Bytes Iterator ****************************/ - -typedef struct { - PyObject_HEAD - Py_ssize_t it_index; - PyBytesObject *it_seq; /* Set to NULL when iterator is exhausted */ -} bytesiterobject; - -static void -bytearrayiter_dealloc(bytesiterobject *it) -{ - _PyObject_GC_UNTRACK(it); - Py_XDECREF(it->it_seq); - PyObject_GC_Del(it); -} - -static int -bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg) -{ - Py_VISIT(it->it_seq); - return 0; -} - -static PyObject * -bytearrayiter_next(bytesiterobject *it) -{ - PyBytesObject *seq; - PyObject *item; - - assert(it != NULL); - seq = it->it_seq; - if (seq == NULL) - return NULL; - assert(PyByteArray_Check(seq)); - - if (it->it_index < PyByteArray_GET_SIZE(seq)) { - item = PyLong_FromLong( - (unsigned char)seq->ob_bytes[it->it_index]); - if (item != NULL) - ++it->it_index; - return item; - } - - Py_DECREF(seq); - it->it_seq = NULL; - return NULL; -} - -static PyObject * -bytearrayiter_length_hint(bytesiterobject *it) -{ - Py_ssize_t len = 0; - if (it->it_seq) - len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index; - return PyLong_FromSsize_t(len); -} - -PyDoc_STRVAR(length_hint_doc, - "Private method returning an estimate of len(list(it))."); - -static PyMethodDef bytesiter_methods[] = { - {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS, - length_hint_doc}, - {NULL, NULL} /* sentinel */ -}; - -PyTypeObject PyBytesIter_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "bytearray_iterator", /* tp_name */ - sizeof(bytesiterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)bytearrayiter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)bytearrayiter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)bytearrayiter_next, /* tp_iternext */ - bytesiter_methods, /* tp_methods */ - 0, -}; - -static PyObject * -bytearray_iter(PyObject *seq) -{ - bytesiterobject *it; - - if (!PyByteArray_Check(seq)) { - PyErr_BadInternalCall(); - return NULL; - } - it = PyObject_GC_New(bytesiterobject, &PyBytesIter_Type); - if (it == NULL) - return NULL; - it->it_index = 0; - Py_INCREF(seq); - it->it_seq = (PyBytesObject *)seq; - _PyObject_GC_TRACK(it); - return (PyObject *)it; -} Modified: python/branches/py3k-grandrenaming/PCbuild/pythoncore.vcproj ============================================================================== --- python/branches/py3k-grandrenaming/PCbuild/pythoncore.vcproj (original) +++ python/branches/py3k-grandrenaming/PCbuild/pythoncore.vcproj Tue Jan 1 20:48:23 2008 @@ -655,7 +655,7 @@ > Author: guido.van.rossum Date: Wed Jan 2 03:55:27 2008 New Revision: 59659 Modified: python/branches/py3k/Lib/code.py Log: Fix issue #1707. When raw_input() was removed, it was incorrectly replaced with sys.stdin.readline(). I wonder how many other places are affected by the same bug? Modified: python/branches/py3k/Lib/code.py ============================================================================== --- python/branches/py3k/Lib/code.py (original) +++ python/branches/py3k/Lib/code.py Wed Jan 2 03:55:27 2008 @@ -253,13 +253,12 @@ The returned line does not include the trailing newline. When the user enters the EOF key sequence, EOFError is raised. - The base implementation uses sys.stdin.readline(); a subclass - may replace this with a different implementation. + The base implementation uses the built-in function + input(); a subclass may replace this with a different + implementation. """ - sys.stdout.write(prompt) - sys.stdout.flush() - return sys.stdin.readline() + return input(prompt) From python-3000-checkins at python.org Wed Jan 2 04:52:38 2008 From: python-3000-checkins at python.org (guido.van.rossum) Date: Wed, 2 Jan 2008 04:52:38 +0100 (CET) Subject: [Python-3000-checkins] r59660 - python/branches/py3k/Lib/pydoc.py Message-ID: <20080102035238.E04641E4002@bag.python.org> Author: guido.van.rossum Date: Wed Jan 2 04:52:38 2008 New Revision: 59660 Modified: python/branches/py3k/Lib/pydoc.py Log: Get rid of raw_input() emulation, use its reincarnation as input(). See Issue 1707. Modified: python/branches/py3k/Lib/pydoc.py ============================================================================== --- python/branches/py3k/Lib/pydoc.py (original) +++ python/branches/py3k/Lib/pydoc.py Wed Jan 2 04:52:38 2008 @@ -1532,11 +1532,6 @@ writedoc(modname) return -def raw_input(prompt): - sys.stdout.write(prompt) - sys.stdout.flush() - return sys.stdin.readline() - class Helper: keywords = { 'and': 'BOOLEAN', @@ -1706,9 +1701,9 @@ self.help(request) def getline(self, prompt): - """Read one line, using raw_input when available.""" + """Read one line, using input() when appropriate.""" if self.input is sys.stdin: - return raw_input(prompt) + return input(prompt) else: self.output.write(prompt) self.output.flush() From python-3000-checkins at python.org Wed Jan 2 12:42:46 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Wed, 2 Jan 2008 12:42:46 +0100 (CET) Subject: [Python-3000-checkins] r59663 - python/branches/py3k-grandrenaming/Objects/memoryobject.c Message-ID: <20080102114246.1277E1E4002@bag.python.org> Author: christian.heimes Date: Wed Jan 2 12:42:45 2008 New Revision: 59663 Modified: python/branches/py3k-grandrenaming/Objects/memoryobject.c Log: memory -> memoryview Modified: python/branches/py3k-grandrenaming/Objects/memoryobject.c ============================================================================== --- python/branches/py3k-grandrenaming/Objects/memoryobject.c (original) +++ python/branches/py3k-grandrenaming/Objects/memoryobject.c Wed Jan 2 12:42:45 2008 @@ -4,7 +4,7 @@ #include "Python.h" static int -memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags) +memoryview_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags) { if (view != NULL) *view = self->view; @@ -15,13 +15,13 @@ } static void -memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view) +memoryview_releasebuf(PyMemoryViewObject *self, Py_buffer *view) { if (self->base != NULL) PyObject_ReleaseBuffer(self->base, NULL); } -PyDoc_STRVAR(memory_doc, +PyDoc_STRVAR(memoryview_doc, "memoryview(object)\n\ \n\ Create a new memoryview object which references the given object."); @@ -67,7 +67,7 @@ } static PyObject * -memory_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) +memoryview_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) { PyObject *obj; static char *kwlist[] = {"object", 0}; @@ -295,13 +295,13 @@ static PyObject * -memory_format_get(PyMemoryViewObject *self) +memoryview_format_get(PyMemoryViewObject *self) { return PyUnicode_FromString(self->view.format); } static PyObject * -memory_itemsize_get(PyMemoryViewObject *self) +memoryview_itemsize_get(PyMemoryViewObject *self) { return PyLong_FromSsize_t(self->view.itemsize); } @@ -331,62 +331,62 @@ } static PyObject * -memory_shape_get(PyMemoryViewObject *self) +memoryview_shape_get(PyMemoryViewObject *self) { return _IntTupleFromSsizet(self->view.ndim, self->view.shape); } static PyObject * -memory_strides_get(PyMemoryViewObject *self) +memoryview_strides_get(PyMemoryViewObject *self) { return _IntTupleFromSsizet(self->view.ndim, self->view.strides); } static PyObject * -memory_suboffsets_get(PyMemoryViewObject *self) +memoryview_suboffsets_get(PyMemoryViewObject *self) { return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets); } static PyObject * -memory_size_get(PyMemoryViewObject *self) +memoryview_size_get(PyMemoryViewObject *self) { return PyLong_FromSsize_t(self->view.len); } static PyObject * -memory_readonly_get(PyMemoryViewObject *self) +memoryview_readonly_get(PyMemoryViewObject *self) { return PyBool_FromLong(self->view.readonly); } static PyObject * -memory_ndim_get(PyMemoryViewObject *self) +memoryview_ndim_get(PyMemoryViewObject *self) { return PyLong_FromLong(self->view.ndim); } -static PyGetSetDef memory_getsetlist[] ={ - {"format", (getter)memory_format_get, NULL, NULL}, - {"itemsize", (getter)memory_itemsize_get, NULL, NULL}, - {"shape", (getter)memory_shape_get, NULL, NULL}, - {"strides", (getter)memory_strides_get, NULL, NULL}, - {"suboffsets", (getter)memory_suboffsets_get, NULL, NULL}, - {"size", (getter)memory_size_get, NULL, NULL}, - {"readonly", (getter)memory_readonly_get, NULL, NULL}, - {"ndim", (getter)memory_ndim_get, NULL, NULL}, +static PyGetSetDef memoryview_getsetlist[] ={ + {"format", (getter)memoryview_format_get, NULL, NULL}, + {"itemsize", (getter)memoryview_itemsize_get, NULL, NULL}, + {"shape", (getter)memoryview_shape_get, NULL, NULL}, + {"strides", (getter)memoryview_strides_get, NULL, NULL}, + {"suboffsets", (getter)memoryview_suboffsets_get, NULL, NULL}, + {"size", (getter)memoryview_size_get, NULL, NULL}, + {"readonly", (getter)memoryview_readonly_get, NULL, NULL}, + {"ndim", (getter)memoryview_ndim_get, NULL, NULL}, {NULL, NULL, NULL, NULL}, }; static PyObject * -memory_tobytes(PyMemoryViewObject *mem, PyObject *noargs) +memoryview_tobytes(PyMemoryViewObject *mem, PyObject *noargs) { return PyByteArray_FromObject((PyObject *)mem); } static PyObject * -memory_tolist(PyMemoryViewObject *mem, PyObject *noargs) +memoryview_tolist(PyMemoryViewObject *mem, PyObject *noargs) { /* This should construct a (nested) list of unpacked objects possibly using the struct module. @@ -397,15 +397,15 @@ -static PyMethodDef memory_methods[] = { - {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, NULL}, - {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, NULL}, +static PyMethodDef memoryview_methods[] = { + {"tobytes", (PyCFunction)memoryview_tobytes, METH_NOARGS, NULL}, + {"tolist", (PyCFunction)memoryview_tolist, METH_NOARGS, NULL}, {NULL, NULL} /* sentinel */ }; static void -memory_dealloc(PyMemoryViewObject *self) +memoryview_dealloc(PyMemoryViewObject *self) { if (self->base != NULL) { if (PyTuple_Check(self->base)) { @@ -436,14 +436,14 @@ } static PyObject * -memory_repr(PyMemoryViewObject *self) +memoryview_repr(PyMemoryViewObject *self) { return PyUnicode_FromFormat("", self); } static PyObject * -memory_str(PyMemoryViewObject *self) +memoryview_str(PyMemoryViewObject *self) { Py_buffer view; PyObject *res; @@ -460,7 +460,7 @@ /* Sequence methods */ static Py_ssize_t -memory_length(PyMemoryViewObject *self) +memoryview_length(PyMemoryViewObject *self) { Py_buffer view; @@ -479,7 +479,7 @@ not with anything else. */ static PyObject * -memory_subscript(PyMemoryViewObject *self, PyObject *key) +memoryview_subscript(PyMemoryViewObject *self, PyObject *key) { Py_buffer *view; view = &(self->view); @@ -543,24 +543,24 @@ /* Need to support assigning memory if we can */ static int -memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value) +memoryview_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value) { return 0; } /* As mapping */ -static PyMappingMethods memory_as_mapping = { - (lenfunc)memory_length, /*mp_length*/ - (binaryfunc)memory_subscript, /*mp_subscript*/ - (objobjargproc)memory_ass_sub, /*mp_ass_subscript*/ +static PyMappingMethods memoryview_as_mapping = { + (lenfunc)memoryview_length, /*mp_length*/ + (binaryfunc)memoryview_subscript, /*mp_subscript*/ + (objobjargproc)memoryview_ass_sub, /*mp_ass_subscript*/ }; /* Buffer methods */ -static PyBufferProcs memory_as_buffer = { - (getbufferproc)memory_getbuf, /* bf_getbuffer */ - (releasebufferproc)memory_releasebuf, /* bf_releasebuffer */ +static PyBufferProcs memoryview_as_buffer = { + (getbufferproc)memoryview_getbuf, /* bf_getbuffer */ + (releasebufferproc)memoryview_releasebuf, /* bf_releasebuffer */ }; @@ -569,32 +569,32 @@ "memoryview", sizeof(PyMemoryViewObject), 0, - (destructor)memory_dealloc, /* tp_dealloc */ + (destructor)memoryview_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ - (reprfunc)memory_repr, /* tp_repr */ + (reprfunc)memoryview_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ - &memory_as_mapping, /* tp_as_mapping */ + &memoryview_as_mapping, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ - (reprfunc)memory_str, /* tp_str */ + (reprfunc)memoryview_str, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ - &memory_as_buffer, /* tp_as_buffer */ + &memoryview_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ - memory_doc, /* tp_doc */ + memoryview_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - memory_methods, /* tp_methods */ + memoryview_methods, /* tp_methods */ 0, /* tp_members */ - memory_getsetlist, /* tp_getset */ + memoryview_getsetlist, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ @@ -602,5 +602,5 @@ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - memory_new, /* tp_new */ + memoryview_new, /* tp_new */ }; From python-3000-checkins at python.org Wed Jan 2 12:45:47 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Wed, 2 Jan 2008 12:45:47 +0100 (CET) Subject: [Python-3000-checkins] r59664 - python/branches/py3k/PC/VS7.1/pythoncore.vcproj Message-ID: <20080102114547.45F361E401E@bag.python.org> Author: christian.heimes Date: Wed Jan 2 12:45:46 2008 New Revision: 59664 Modified: python/branches/py3k/PC/VS7.1/pythoncore.vcproj Log: Fixed merge accident Modified: python/branches/py3k/PC/VS7.1/pythoncore.vcproj ============================================================================== --- python/branches/py3k/PC/VS7.1/pythoncore.vcproj (original) +++ python/branches/py3k/PC/VS7.1/pythoncore.vcproj Wed Jan 2 12:45:46 2008 @@ -3,7 +3,7 @@ ProjectType="Visual C++" Version="7.10" Name="pythoncore" - ProjectGUID="{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}" + ProjectGUID="{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA30}" RootNamespace="pythoncore" SccProjectName="pythoncore" SccLocalPath=".."> @@ -39,15 +39,15 @@ @@ -99,15 +99,15 @@ @@ -166,15 +166,15 @@ Name="VCLinkerTool" AdditionalOptions=" /MACHINE:IA64 /USELINK:MS_SDK" AdditionalDependencies="getbuildinfo.o" - OutputFile="./python26.dll" + OutputFile="./python30.dll" LinkIncremental="1" SuppressStartupBanner="FALSE" IgnoreDefaultLibraryNames="libc" GenerateDebugInformation="TRUE" - ProgramDatabaseFile=".\./python26.pdb" + ProgramDatabaseFile=".\./python30.pdb" SubSystem="2" BaseAddress="0x1e000000" - ImportLibrary=".\./python26.lib" + ImportLibrary=".\./python30.lib" TargetMachine="0"/> @@ -233,15 +233,15 @@ Name="VCLinkerTool" AdditionalOptions=" /MACHINE:AMD64 /USELINK:MS_SDK" AdditionalDependencies="getbuildinfo.o" - OutputFile="./python26.dll" + OutputFile="./python30.dll" LinkIncremental="1" SuppressStartupBanner="TRUE" IgnoreDefaultLibraryNames="libc" GenerateDebugInformation="TRUE" - ProgramDatabaseFile=".\./python26.pdb" + ProgramDatabaseFile=".\./python30.pdb" SubSystem="2" BaseAddress="0x1e000000" - ImportLibrary=".\./python26.lib" + ImportLibrary=".\./python30.lib" TargetMachine="0"/> @@ -368,13 +368,13 @@ RelativePath="..\..\Modules\_csv.c"> + RelativePath="..\..\Modules\_fileio.c"> + RelativePath="..\..\Modules\_functoolsmodule.c"> + RelativePath="..\..\Modules\_heapqmodule.c"> @@ -419,6 +419,9 @@ RelativePath="..\..\Python\ast.c"> + + + RelativePath="..\..\Objects\bytes_methods.c"> + + @@ -470,9 +476,6 @@ RelativePath="..\..\PC\config.c"> - - - @@ -518,6 +518,9 @@ RelativePath="..\..\Objects\frameobject.c"> + + - - - - - - + RelativePath="..\..\Parser\metagrammar.c"> + RelativePath="..\..\Objects\memoryobject.c"> @@ -732,7 +726,7 @@ RelativePath="..\..\Modules\sha512module.c"> + RelativePath="..\..\Modules\sha1module.c"> @@ -744,9 +738,6 @@ RelativePath="..\..\Objects\stringobject.c"> - - Author: christian.heimes Date: Wed Jan 2 19:30:52 2008 New Revision: 59667 Added: python/branches/py3k/PC/VS8.0/ (props changed) - copied from r59665, python/trunk/PC/VS8.0/ python/branches/py3k/PCbuild/vs9to8.py - copied, changed from r59665, python/trunk/PCbuild/vs9to8.py Removed: python/branches/py3k/PCbuild8/ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/lib-tk/Tkinter.py python/branches/py3k/Lib/test/test_urllib.py python/branches/py3k/Lib/urllib.py python/branches/py3k/Modules/_tkinter.c python/branches/py3k/PC/VS8.0/pyproject.vsprops python/branches/py3k/PC/VS8.0/pythoncore.vcproj python/branches/py3k/PCbuild/pyproject.vsprops python/branches/py3k/PCbuild/readme.txt python/branches/py3k/Tools/buildbot/build.bat python/branches/py3k/Tools/buildbot/buildmsi.bat python/branches/py3k/Tools/buildbot/clean.bat python/branches/py3k/Tools/buildbot/external.bat python/branches/py3k/Tools/buildbot/kill_python.c python/branches/py3k/Tools/buildbot/test.bat Log: Merged revisions 59642-59665 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r59653 | martin.v.loewis | 2008-01-01 22:05:17 +0100 (Tue, 01 Jan 2008) | 3 lines Return results from Python callbacks to Tcl as Tcl objects. Fixes Tk issue #1851526 ........ r59654 | martin.v.loewis | 2008-01-01 22:08:18 +0100 (Tue, 01 Jan 2008) | 4 lines Always convert Text.index result to string. This improves compatibility with Tcl 8.5, which would otherwise return textindex objects. ........ r59655 | martin.v.loewis | 2008-01-01 22:09:07 +0100 (Tue, 01 Jan 2008) | 2 lines News item for r59653. ........ r59656 | martin.v.loewis | 2008-01-02 00:00:00 +0100 (Wed, 02 Jan 2008) | 1 line Don't link with Tix; Tix is loaded dynamically by Tcl. ........ r59657 | martin.v.loewis | 2008-01-02 00:00:48 +0100 (Wed, 02 Jan 2008) | 1 line Use Visual Studio 2009 on the build slaves. ........ r59658 | martin.v.loewis | 2008-01-02 00:36:24 +0100 (Wed, 02 Jan 2008) | 1 line Test in PCbuild directory. ........ r59661 | kurt.kaiser | 2008-01-02 05:11:28 +0100 (Wed, 02 Jan 2008) | 6 lines Issue1177 r58207 and r58247 patch logic is reversed. I noticed this when I tried to use urllib to retrieve a file which required auth. Fix that and add a test for 401 error to verify. ........ r59662 | kurt.kaiser | 2008-01-02 06:23:38 +0100 (Wed, 02 Jan 2008) | 2 lines Change docstrings to comments so test output will display normally. ........ r59665 | christian.heimes | 2008-01-02 18:43:40 +0100 (Wed, 02 Jan 2008) | 5 lines Removed PCbuild8/ directory and added a new build directory for VS 2005 based on the VS 2008 build directory to PC/VS8.0. The script PCbuild/vs8to9.py was added to sync changes from PCbuild to PC/VS8.0. Kristjan, the initial creator of the PCbuild8 directory is fine with the replacement. I've moved the new version of the VS 2005 build directory next to the other legacy build directories. The new sync script is based on the work of wreck and syncs changes in the project, property and solution files. ........ Modified: python/branches/py3k/Lib/lib-tk/Tkinter.py ============================================================================== --- python/branches/py3k/Lib/lib-tk/Tkinter.py (original) +++ python/branches/py3k/Lib/lib-tk/Tkinter.py Wed Jan 2 19:30:52 2008 @@ -2977,7 +2977,7 @@ return self.tk.call(self._w, "image", "names") def index(self, index): """Return the index in the form line.char for INDEX.""" - return self.tk.call(self._w, 'index', index) + return str(self.tk.call(self._w, 'index', index)) def insert(self, index, chars, *args): """Insert CHARS before the characters at INDEX. An additional tag can be given in ARGS. Additional CHARS and tags can follow in ARGS.""" Modified: python/branches/py3k/Lib/test/test_urllib.py ============================================================================== --- python/branches/py3k/Lib/test/test_urllib.py (original) +++ python/branches/py3k/Lib/test/test_urllib.py Wed Jan 2 19:30:52 2008 @@ -126,10 +126,23 @@ finally: self.unfakehttp() + def test_read_bogus(self): + # urlopen() should raise IOError for many error codes. + self.fakehttp(b'''HTTP/1.1 401 Authentication Required +Date: Wed, 02 Jan 2008 03:03:54 GMT +Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e +Connection: close +Content-Type: text/html; charset=iso-8859-1 +''') + try: + self.assertRaises(IOError, urllib.urlopen, "http://python.org/") + finally: + self.unfakehttp() + def test_empty_socket(self): # urlopen() raises IOError if the underlying socket does not send any # data. (#1680230) - self.fakehttp(b"") + self.fakehttp(b'') try: self.assertRaises(IOError, urllib.urlopen, "http://something") finally: Modified: python/branches/py3k/Lib/urllib.py ============================================================================== --- python/branches/py3k/Lib/urllib.py (original) +++ python/branches/py3k/Lib/urllib.py Wed Jan 2 19:30:52 2008 @@ -359,7 +359,7 @@ # According to RFC 2616, "2xx" code indicates that the client's # request was successfully received, understood, and accepted. - if not (200 <= response.status < 300): + if (200 <= response.status < 300): return addinfourl(response.fp, response.msg, "http:" + url) else: return self.http_error( @@ -402,6 +402,77 @@ """Use HTTPS protocol.""" return self._open_generic_http(self._https_connection, url, data) + import httplib + user_passwd = None + proxy_passwd = None + if isinstance(url, str): + host, selector = splithost(url) + if host: + user_passwd, host = splituser(host) + host = unquote(host) + realhost = host + else: + host, selector = url + # here, we determine, whether the proxy contains authorization information + proxy_passwd, host = splituser(host) + urltype, rest = splittype(selector) + url = rest + user_passwd = None + if urltype.lower() != 'https': + realhost = None + else: + realhost, rest = splithost(rest) + if realhost: + user_passwd, realhost = splituser(realhost) + if user_passwd: + selector = "%s://%s%s" % (urltype, realhost, rest) + #print "proxy via https:", host, selector + if not host: raise IOError('https error', 'no host given') + if proxy_passwd: + import base64 + proxy_auth = base64.b64encode(proxy_passwd).strip() + else: + proxy_auth = None + if user_passwd: + import base64 + auth = base64.b64encode(user_passwd).strip() + else: + auth = None + h = httplib.HTTPS(host, 0, + key_file=self.key_file, + cert_file=self.cert_file) + if data is not None: + h.putrequest('POST', selector) + h.putheader('Content-Type', + 'application/x-www-form-urlencoded') + h.putheader('Content-Length', '%d' % len(data)) + else: + h.putrequest('GET', selector) + if proxy_auth: h.putheader('Proxy-Authorization', 'Basic %s' % proxy_auth) + if auth: h.putheader('Authorization', 'Basic %s' % auth) + if realhost: h.putheader('Host', realhost) + for args in self.addheaders: h.putheader(*args) + h.endheaders() + if data is not None: + h.send(data) + errcode, errmsg, headers = h.getreply() + fp = h.getfile() + if errcode == -1: + if fp: fp.close() + # something went wrong with the HTTP status line + raise IOError('http protocol error', 0, + 'got a bad status line', None) + # According to RFC 2616, "2xx" code indicates that the client's + # request was successfully received, understood, and accepted. + if (200 <= errcode < 300): + return addinfourl(fp, headers, "https:" + url) + else: + if data is None: + return self.http_error(url, fp, errcode, errmsg, headers) + else: + return self.http_error(url, fp, errcode, errmsg, headers, + data) + def open_file(self, url): """Use local file or FTP depending on form of URL.""" if not isinstance(url, str): Modified: python/branches/py3k/Modules/_tkinter.c ============================================================================== --- python/branches/py3k/Modules/_tkinter.c (original) +++ python/branches/py3k/Modules/_tkinter.c Wed Jan 2 19:30:52 2008 @@ -1906,7 +1906,7 @@ PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData; PyObject *self, *func, *arg, *res, *s; int i, rv; - Tcl_Obj *tres; + Tcl_Obj *obj_res; ENTER_PYTHON @@ -1939,13 +1939,13 @@ if (res == NULL) return PythonCmd_Error(interp); - tres = AsObj(res); - if (tres == NULL) { + obj_res = AsObj(res); + if (obj_res == NULL) { Py_DECREF(res); return PythonCmd_Error(interp); } else { - Tcl_SetObjResult(Tkapp_Interp(self), tres); + Tcl_SetObjResult(Tkapp_Interp(self), obj_res); rv = TCL_OK; } Modified: python/branches/py3k/PC/VS8.0/pyproject.vsprops ============================================================================== --- python/trunk/PC/VS8.0/pyproject.vsprops (original) +++ python/branches/py3k/PC/VS8.0/pyproject.vsprops Wed Jan 2 19:30:52 2008 @@ -38,7 +38,7 @@ /> + + + + @@ -979,15 +987,15 @@ > - - @@ -1071,14 +1075,6 @@ > - - - - @@ -1107,15 +1103,15 @@ > - - @@ -1339,7 +1331,11 @@ > + + - @@ -1415,10 +1407,6 @@ > - - @@ -1431,6 +1419,10 @@ > + + @@ -1635,6 +1627,10 @@ > + + Modified: python/branches/py3k/PCbuild/pyproject.vsprops ============================================================================== --- python/branches/py3k/PCbuild/pyproject.vsprops (original) +++ python/branches/py3k/PCbuild/pyproject.vsprops Wed Jan 2 19:30:52 2008 @@ -70,10 +70,10 @@ /> Modified: python/branches/py3k/PCbuild/readme.txt ============================================================================== --- python/branches/py3k/PCbuild/readme.txt (original) +++ python/branches/py3k/PCbuild/readme.txt Wed Jan 2 19:30:52 2008 @@ -1,5 +1,6 @@ Building Python using VC++ 9.0 ------------------------------ + This directory is used to build Python for Win32 platforms, e.g. Windows 2000, XP and Vista. It requires Microsoft Visual C++ 9.0 (a.k.a. Visual Studio .NET 2008). @@ -36,6 +37,36 @@ land in the amd64 subfolder. The PGI and PGO builds for profile guided optimization end up in their own folders, too. +Legacy support +-------------- + +You can find build directories for older versions of Visual Studio and +Visual C++ in the PC directory. The legacy build directories are no longer +actively maintained and may not work out of the box. + +PC/VC6/ + Visual C++ 6.0 +PC/VS7.1/ + Visual Studio 2003 (7.1) +PCbuild8/ + Visual Studio 2005 (8.0) + + +C RUNTIME +--------- + +Visual Studio 2008 uses version 9 of the C runtime (MSVCRT9). The executables +are linked to a CRT "side by side" assembly which must be present on the target +machine. This is avalible under the VC/Redist folder of your visual studio +distribution. On XP and later operating systems that support +side-by-side assemblies it is not enough to have the msvcrt80.dll present, +it has to be there as a whole assembly, that is, a folder with the .dll +and a .manifest. Also, a check is made for the correct version. +Therefore, one should distribute this assembly with the dlls, and keep +it in the same directory. For compatibility with older systems, one should +also set the PATH to this directory so that the dll can be found. +For more info, see the Readme in the VC/Redist folder. + SUBPROJECTS ----------- These subprojects should build out of the box. Subprojects other than the Copied: python/branches/py3k/PCbuild/vs9to8.py (from r59665, python/trunk/PCbuild/vs9to8.py) ============================================================================== --- python/trunk/PCbuild/vs9to8.py (original) +++ python/branches/py3k/PCbuild/vs9to8.py Wed Jan 2 19:30:52 2008 @@ -11,7 +11,7 @@ destname = os.path.normpath(os.path.join(dest, name)) print("%s -> %s" % (filename, destname)) - with open(filename, 'r') as fin: + with open(filename, 'rU') as fin: lines = fin.read() lines = lines.replace('Version="9,00"', 'Version="8.00"') lines = lines.replace('Version="9.00"', 'Version="8.00"') @@ -22,8 +22,9 @@ lines = lines.replace('..\\', '..\\..\\') lines = lines.replace('..\\..\\..\\..\\', '..\\..\\..\\') - with open(destname, 'w') as fout: + with open(destname, 'wb') as fout: + lines = lines.replace("\n", "\r\n").encode() fout.write(lines) if __name__ == "__main__": - vs9to8(src=".", dest="..\PC\VS8.0") + vs9to8(src=".", dest="../PC/VS8.0") Modified: python/branches/py3k/Tools/buildbot/build.bat ============================================================================== --- python/branches/py3k/Tools/buildbot/build.bat (original) +++ python/branches/py3k/Tools/buildbot/build.bat Wed Jan 2 19:30:52 2008 @@ -1,5 +1,6 @@ @rem Used by the buildbot "compile" step. cmd /c Tools\buildbot\external.bat -call "%VS71COMNTOOLS%vsvars32.bat" +call "%VS90COMNTOOLS%vsvars32.bat" cmd /q/c Tools\buildbot\kill_python.bat -devenv.com /useenv /build Debug PC\VS7.1\pcbuild.sln +vcbuild /useenv PCbuild\pcbuild.sln "Debug|Win32" + Modified: python/branches/py3k/Tools/buildbot/buildmsi.bat ============================================================================== --- python/branches/py3k/Tools/buildbot/buildmsi.bat (original) +++ python/branches/py3k/Tools/buildbot/buildmsi.bat Wed Jan 2 19:30:52 2008 @@ -2,14 +2,14 @@ cmd /c Tools\buildbot\external.bat @rem build release versions of things -call "%VS71COMNTOOLS%vsvars32.bat" +call "%VS90COMNTOOLS%vsvars32.bat" if not exist ..\db-4.4.20\build_win32\release\libdb44s.lib ( devenv ..\db-4.4.20\build_win32\Berkeley_DB.sln /build Release /project db_static ) @rem build Python cmd /q/c Tools\buildbot\kill_python.bat -devenv.com /useenv /build Release PC\VS7.1\pcbuild.sln +devenv.com /useenv /build Release PCbuild\pcbuild.sln @rem build the documentation bash.exe -c 'cd Doc;make PYTHON=python2.5 update htmlhelp' Modified: python/branches/py3k/Tools/buildbot/clean.bat ============================================================================== --- python/branches/py3k/Tools/buildbot/clean.bat (original) +++ python/branches/py3k/Tools/buildbot/clean.bat Wed Jan 2 19:30:52 2008 @@ -1,7 +1,7 @@ @rem Used by the buildbot "clean" step. -call "%VS71COMNTOOLS%vsvars32.bat" -cd PC\VS7.1 +call "%VS90COMNTOOLS%vsvars32.bat" +cd PCbuild @echo Deleting .pyc/.pyo files ... del /s Lib\*.pyc Lib\*.pyo -devenv.com /clean Release pcbuild.sln -devenv.com /clean Debug pcbuild.sln +vcbuild /clean pcbuild.sln "Release|Win32" +vcbuild /clean pcbuild.sln "Debug|Win32" Modified: python/branches/py3k/Tools/buildbot/external.bat ============================================================================== --- python/branches/py3k/Tools/buildbot/external.bat (original) +++ python/branches/py3k/Tools/buildbot/external.bat Wed Jan 2 19:30:52 2008 @@ -2,7 +2,7 @@ @rem Assume we start inside the Python source directory cd .. -call "%VS71COMNTOOLS%vsvars32.bat" +call "%VS90COMNTOOLS%vsvars32.bat" @rem bzip if not exist bzip2-1.0.3 svn export http://svn.python.org/projects/external/bzip2-1.0.3 @@ -10,24 +10,29 @@ @rem Sleepycat db if not exist db-4.4.20 svn export http://svn.python.org/projects/external/db-4.4.20 if not exist db-4.4.20\build_win32\debug\libdb44sd.lib ( - devenv db-4.4.20\build_win32\Berkeley_DB.sln /build Debug /project db_static + vcbuild db-4.4.20\build_win32\Berkeley_DB.sln /build Debug /project db_static ) @rem OpenSSL -if not exist openssl-0.9.8a svn export http://svn.python.org/projects/external/openssl-0.9.8a +if not exist openssl-0.9.8g ( + if exist openssl-0.9.8a rd /s/q openssl-0.9.8a + svn export http://svn.python.org/projects/external/openssl-0.9.8g +) @rem tcltk -if not exist tcl8.4.12 ( +if not exist tcl8.4.16 ( if exist tcltk rd /s/q tcltk - svn export http://svn.python.org/projects/external/tcl8.4.12 - svn export http://svn.python.org/projects/external/tk8.4.12 - cd tcl8.4.12\win - nmake -f makefile.vc - nmake -f makefile.vc INSTALLDIR=..\..\tcltk install + if exist tcl8.4.12 rd /s/q tcl8.4.12 + if exist tk8.4.12 rd /s/q tk8.4.12 + svn export http://svn.python.org/projects/external/tcl8.4.16 + svn export http://svn.python.org/projects/external/tk8.4.16 + cd tcl8.4.16\win + nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 + nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 INSTALLDIR=..\..\tcltk install cd ..\.. - cd tk8.4.12\win - nmake -f makefile.vc TCLDIR=..\..\tcl8.4.12 - nmake -f makefile.vc TCLDIR=..\..\tcl8.4.12 INSTALLDIR=..\..\tcltk install + cd tk8.4.16\win + nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 TCLDIR=..\..\tcl8.4.16 + nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 TCLDIR=..\..\tcl8.4.16 INSTALLDIR=..\..\tcltk install cd ..\.. ) Modified: python/branches/py3k/Tools/buildbot/kill_python.c ============================================================================== --- python/branches/py3k/Tools/buildbot/kill_python.c (original) +++ python/branches/py3k/Tools/buildbot/kill_python.c Wed Jan 2 19:30:52 2008 @@ -1,4 +1,4 @@ -/* This program looks for processes which have build\PC\VS7.1\python.exe +/* This program looks for processes which have build\PCbuild\python.exe in their path and terminates them. */ #include #include @@ -46,14 +46,14 @@ /* Check if we are running a buildbot version of Python. On Windows, this will always be a debug build from the - PC\VS7.1 directory. build\\PC\\VS7.1\\python_d.exe + PCbuild directory. build\\PCbuild\\python_d.exe On Cygwin, the pathname is similar to other Unixes. Use \\build\\python.exe to ensure we don't match - PC\\VS7.1\\python.exe which could be a normal instance + PCbuild\\python.exe which could be a normal instance of Python running on vanilla Windows. */ - if ((strstr(path, "build\\pc\\vs7.1\\python_d.exe") != NULL) || + if ((strstr(path, "pcbuild\\python_d.exe") != NULL) || (strstr(path, "\\build\\python.exe") != NULL)) { printf("Terminating %s (pid %d)\n", path, pids[i]); if (!TerminateProcess(hProcess, 1)) { Modified: python/branches/py3k/Tools/buildbot/test.bat ============================================================================== --- python/branches/py3k/Tools/buildbot/test.bat (original) +++ python/branches/py3k/Tools/buildbot/test.bat Wed Jan 2 19:30:52 2008 @@ -1,3 +1,3 @@ @rem Used by the buildbot "test" step. -cd PC\VS7.1 +cd PCbuild call rt.bat -d -q -uall -rw -n From python-3000-checkins at python.org Thu Jan 3 00:19:14 2008 From: python-3000-checkins at python.org (guido.van.rossum) Date: Thu, 3 Jan 2008 00:19:14 +0100 (CET) Subject: [Python-3000-checkins] r59670 - python/branches/py3k/Include/patchlevel.h Message-ID: <20080102231914.109F21E4005@bag.python.org> Author: guido.van.rossum Date: Thu Jan 3 00:19:13 2008 New Revision: 59670 Modified: python/branches/py3k/Include/patchlevel.h Log: Show in the sys.version string (bot not elsewhere) that this is more than the 3.0a2 release. Modified: python/branches/py3k/Include/patchlevel.h ============================================================================== --- python/branches/py3k/Include/patchlevel.h (original) +++ python/branches/py3k/Include/patchlevel.h Thu Jan 3 00:19:13 2008 @@ -22,7 +22,7 @@ #define PY_RELEASE_SERIAL 2 /* Version as a string */ -#define PY_VERSION "3.0a2" +#define PY_VERSION "3.0a2+" /* Subversion Revision number of this file (not of the repository) */ #define PY_PATCHLEVEL_REVISION "$Revision$" From python-3000-checkins at python.org Fri Jan 4 00:01:05 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Fri, 4 Jan 2008 00:01:05 +0100 (CET) Subject: [Python-3000-checkins] r59680 - in python/branches/py3k: Doc/c-api/utilities.rst Doc/library/functions.rst Doc/library/math.rst Doc/library/numbers.rst Doc/library/numeric.rst Doc/reference/datamodel.rst Doc/reference/expressions.rst Include/import.h Include/py_curses.h Include/pyport.h Lib/distutils/command/build_scripts.py Lib/sre_compile.py Lib/test/test_math.py Lib/test/test_re.py Mac/Modules/MacOS.c Modules/_ctypes/callbacks.c Modules/_cursesmodule.c Modules/cjkcodecs/cjkcodecs.h Modules/datetimemodule.c Modules/gcmodule.c Modules/mathmodule.c Modules/parsermodule.c Modules/posixmodule.c Modules/socketmodule.h Modules/timemodule.c Modules/zipimport.c Objects/unicodeobject.c PC/VS8.0/pythoncore.vcproj PCbuild/pythoncore.vcproj Python/errors.c Python/import.c Python/mactoolboxglue.c Message-ID: <20080103230105.943971E4006@bag.python.org> Author: christian.heimes Date: Fri Jan 4 00:01:04 2008 New Revision: 59680 Added: python/branches/py3k/Doc/library/numbers.rst - copied unchanged from r59679, python/trunk/Doc/library/numbers.rst Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/c-api/utilities.rst python/branches/py3k/Doc/library/functions.rst python/branches/py3k/Doc/library/math.rst python/branches/py3k/Doc/library/numeric.rst python/branches/py3k/Doc/reference/datamodel.rst python/branches/py3k/Doc/reference/expressions.rst python/branches/py3k/Include/import.h python/branches/py3k/Include/py_curses.h python/branches/py3k/Include/pyport.h python/branches/py3k/Lib/distutils/command/build_scripts.py python/branches/py3k/Lib/sre_compile.py python/branches/py3k/Lib/test/test_math.py python/branches/py3k/Lib/test/test_re.py python/branches/py3k/Mac/Modules/MacOS.c python/branches/py3k/Modules/_ctypes/callbacks.c python/branches/py3k/Modules/_cursesmodule.c python/branches/py3k/Modules/cjkcodecs/cjkcodecs.h python/branches/py3k/Modules/datetimemodule.c python/branches/py3k/Modules/gcmodule.c python/branches/py3k/Modules/mathmodule.c python/branches/py3k/Modules/parsermodule.c python/branches/py3k/Modules/posixmodule.c python/branches/py3k/Modules/socketmodule.h python/branches/py3k/Modules/timemodule.c python/branches/py3k/Modules/zipimport.c python/branches/py3k/Objects/unicodeobject.c python/branches/py3k/PC/VS8.0/pythoncore.vcproj python/branches/py3k/PCbuild/pythoncore.vcproj python/branches/py3k/Python/errors.c python/branches/py3k/Python/import.c python/branches/py3k/Python/mactoolboxglue.c Log: Merged revisions 59666-59679 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r59666 | christian.heimes | 2008-01-02 19:28:32 +0100 (Wed, 02 Jan 2008) | 1 line Made vs9to8 Unix compatible ........ r59669 | guido.van.rossum | 2008-01-02 20:00:46 +0100 (Wed, 02 Jan 2008) | 2 lines Patch #1696. Don't attempt to close None in dry-run mode. ........ r59671 | jeffrey.yasskin | 2008-01-03 03:21:52 +0100 (Thu, 03 Jan 2008) | 6 lines Backport PEP 3141 from the py3k branch to the trunk. This includes r50877 (just the complex_pow part), r56649, r56652, r56715, r57296, r57302, r57359, r57361, r57372, r57738, r57739, r58017, r58039, r58040, and r59390, and new documentation. The only significant difference is that round(x) returns a float to preserve backward-compatibility. See http://bugs.python.org/issue1689. ........ r59672 | christian.heimes | 2008-01-03 16:41:30 +0100 (Thu, 03 Jan 2008) | 1 line Issue #1726: Remove Python/atof.c from PCBuild/pythoncore.vcproj ........ r59675 | guido.van.rossum | 2008-01-03 20:12:44 +0100 (Thu, 03 Jan 2008) | 4 lines Issue #1700, reported by Nguyen Quan Son, fix by Fredruk Lundh: Regular Expression inline flags not handled correctly for some unicode characters. (Forward port from 2.5.2.) ........ r59676 | christian.heimes | 2008-01-03 21:23:15 +0100 (Thu, 03 Jan 2008) | 1 line Added math.isinf() and math.isnan() ........ r59677 | christian.heimes | 2008-01-03 22:14:48 +0100 (Thu, 03 Jan 2008) | 1 line Some build bots don't compile mathmodule. There is an issue with the long definition of pi and euler ........ r59678 | christian.heimes | 2008-01-03 23:16:32 +0100 (Thu, 03 Jan 2008) | 2 lines Modified PyImport_Import and PyImport_ImportModule to always use absolute imports by calling __import__ with an explicit level of 0 Added a new API function PyImport_ImportModuleNoBlock. It solves the problem with dead locks when mixing threads and imports ........ r59679 | christian.heimes | 2008-01-03 23:32:26 +0100 (Thu, 03 Jan 2008) | 1 line Added copysign(x, y) function to the math module ........ Modified: python/branches/py3k/Doc/c-api/utilities.rst ============================================================================== --- python/branches/py3k/Doc/c-api/utilities.rst (original) +++ python/branches/py3k/Doc/c-api/utilities.rst Fri Jan 4 00:01:04 2008 @@ -184,7 +184,8 @@ single: modules (in module sys) This is a simplified interface to :cfunc:`PyImport_ImportModuleEx` below, - leaving the *globals* and *locals* arguments set to *NULL*. When the *name* + leaving the *globals* and *locals* arguments set to *NULL* and *level* set + to 0. When the *name* argument contains a dot (when it specifies a submodule of a package), the *fromlist* argument is set to the list ``['*']`` so that the return value is the named module rather than the top-level package containing it as would otherwise @@ -196,6 +197,27 @@ to find out. Starting with Python 2.4, a failing import of a module no longer leaves the module in ``sys.modules``. + .. versionchanged:: 2.6 + always use absolute imports + + .. index:: single: modules (in module sys) + + +.. cfunction:: PyObject* PyImport_ImportModuleNoBlock(const char *name) + + .. index:: + single: `cfunc:PyImport_ImportModule` + + This version of `cfunc:PyImport_ImportModule` does not block. It's intended + to be used in C function which import other modules to execute a function. + The import may block if another thread holds the import lock. The function + `cfunc:PyImport_ImportModuleNoBlock` doesn't block. It first tries to fetch + the module from sys.modules and falls back to `cfunc:PyImport_ImportModule` + unless the the lock is hold. In the latter case the function raises an + ImportError. + + .. versionadded:: 2.6 + .. cfunction:: PyObject* PyImport_ImportModuleEx(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist) @@ -214,6 +236,24 @@ Failing imports remove incomplete module objects, like with :cfunc:`PyImport_ImportModule`. + .. versionchanged:: 2.6 + The function is an alias for `cfunc:PyImport_ImportModuleLevel` with + -1 as level, meaning relative import. + + +.. cfunction:: PyObject* PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level) + + Import a module. This is best described by referring to the built-in Python + function :func:`__import__`, as the standard :func:`__import__` function calls + this function directly. + + The return value is a new reference to the imported module or top-level package, + or *NULL* with an exception set on failure. Like for :func:`__import__`, + the return value when a submodule of a package was requested is normally the + top-level package, unless a non-empty *fromlist* was given. + + ..versionadded:: 2.5 + .. cfunction:: PyObject* PyImport_Import(PyObject *name) @@ -222,6 +262,9 @@ current globals. This means that the import is done using whatever import hooks are installed in the current environment. + .. versionchanged:: 2.6 + always use absolute imports + .. cfunction:: PyObject* PyImport_ReloadModule(PyObject *m) Modified: python/branches/py3k/Doc/library/functions.rst ============================================================================== --- python/branches/py3k/Doc/library/functions.rst (original) +++ python/branches/py3k/Doc/library/functions.rst Fri Jan 4 00:01:04 2008 @@ -915,10 +915,13 @@ .. function:: round(x[, n]) Return the floating point value *x* rounded to *n* digits after the decimal - point. If *n* is omitted, it defaults to zero. The result is a floating point - number. Values are rounded to the closest multiple of 10 to the power minus - *n*; if two multiples are equally close, rounding is done away from 0 (so. for - example, ``round(0.5)`` is ``1.0`` and ``round(-0.5)`` is ``-1.0``). + point. If *n* is omitted, it defaults to zero. Values are rounded to the + closest multiple of 10 to the power minus *n*; if two multiples are equally + close, rounding is done toward the even choice (so, for example, both + ``round(0.5)`` and ``round(-0.5)`` are ``0``, and ``round(1.5)`` is + ``2``). Delegates to ``x.__round__(n)``. + + .. versionchanged:: 2.6 .. function:: set([iterable]) @@ -1064,6 +1067,14 @@ operators such as ``super(C, self)[name]``. +.. function:: trunc(x) + + Return the :class:`Real` value *x* truncated to an :class:`Integral` (usually + a long integer). Delegates to ``x.__trunc__()``. + + .. versionadded:: 2.6 + + .. function:: tuple([iterable]) Return a tuple whose items are the same and in the same order as *iterable*'s Modified: python/branches/py3k/Doc/library/math.rst ============================================================================== --- python/branches/py3k/Doc/library/math.rst (original) +++ python/branches/py3k/Doc/library/math.rst Fri Jan 4 00:01:04 2008 @@ -26,8 +26,17 @@ .. function:: ceil(x) - Return the ceiling of *x* as a float, the smallest integer value greater than or - equal to *x*. + Return the ceiling of *x* as a float, the smallest integer value greater than + or equal to *x*. If *x* is not a float, delegates to ``x.__ceil__()``, which + should return an :class:`Integral` value. + + +.. function:: copysign(x, y) + + Return *x* with the sign of *y*. ``copysign`` copies the sign bit of an IEEE + 754 float, ``copysign(1, -0.0)`` returns *-1.0*. + + ..versionadded:: 2.6 .. function:: fabs(x) @@ -37,8 +46,9 @@ .. function:: floor(x) - Return the floor of *x* as a float, the largest integer value less than or equal - to *x*. + Return the floor of *x* as a float, the largest integer value less than or + equal to *x*. If *x* is not a float, delegates to ``x.__floor__()``, which + should return an :class:`Integral` value. .. function:: fmod(x, y) @@ -64,6 +74,23 @@ apart" the internal representation of a float in a portable way. +.. function:: isinf(x) + + Checks if the float *x* is positive or negative infinite. + + ..versionadded:: 2.6 + + +.. function:: isnan(x) + + Checks if the float *x* is a NaN (not a number). NaNs are part of the + IEEE 754 standards. Operation like but not limited to ``inf * 0``, + ``inf / inf`` or any operation involving a NaN, e.g. ``nan * 1``, return + a NaN. + + ..versionadded:: 2.6 + + .. function:: ldexp(x, i) Return ``x * (2**i)``. This is essentially the inverse of function Modified: python/branches/py3k/Doc/library/numeric.rst ============================================================================== --- python/branches/py3k/Doc/library/numeric.rst (original) +++ python/branches/py3k/Doc/library/numeric.rst Fri Jan 4 00:01:04 2008 @@ -6,16 +6,18 @@ ******************************** The modules described in this chapter provide numeric and math-related functions -and data types. The :mod:`math` and :mod:`cmath` contain various mathematical -functions for floating-point and complex numbers. For users more interested in -decimal accuracy than in speed, the :mod:`decimal` module supports exact -representations of decimal numbers. +and data types. The :mod:`numbers` module defines an abstract hierarchy of +numeric types. The :mod:`math` and :mod:`cmath` modules contain various +mathematical functions for floating-point and complex numbers. For users more +interested in decimal accuracy than in speed, the :mod:`decimal` module supports +exact representations of decimal numbers. The following modules are documented in this chapter: .. toctree:: + numbers.rst math.rst cmath.rst decimal.rst Modified: python/branches/py3k/Doc/reference/datamodel.rst ============================================================================== --- python/branches/py3k/Doc/reference/datamodel.rst (original) +++ python/branches/py3k/Doc/reference/datamodel.rst Fri Jan 4 00:01:04 2008 @@ -152,7 +152,7 @@ object is accessed through the literal ``...`` or the built-in name ``Ellipsis``. Its truth value is true. -Numbers +:class:`numbers.Number` .. index:: object: numeric These are created by numeric literals and returned as results by arithmetic @@ -164,7 +164,7 @@ Python distinguishes between integers, floating point numbers, and complex numbers: - Integers + :class:`numbers.Integral` .. index:: object: integer These represent elements from the mathematical set of integers (positive and @@ -202,7 +202,7 @@ operation except left shift, if it yields a result in the plain integer domain without causing overflow, will yield the same result when using mixed operands. - Floating point numbers + :class:`numbers.Real` (:class:`float`) .. index:: object: floating point pair: floating point; number @@ -217,7 +217,7 @@ overhead of using objects in Python, so there is no reason to complicate the language with two kinds of floating point numbers. - Complex numbers + :class:`numbers.Complex` .. index:: object: complex pair: complex; number Modified: python/branches/py3k/Doc/reference/expressions.rst ============================================================================== --- python/branches/py3k/Doc/reference/expressions.rst (original) +++ python/branches/py3k/Doc/reference/expressions.rst Fri Jan 4 00:01:04 2008 @@ -768,7 +768,8 @@ ``10**-2`` returns ``0.01``. Raising ``0.0`` to a negative power results in a :exc:`ZeroDivisionError`. -Raising a negative number to a fractional power results in a :exc:`ValueError`. +Raising a negative number to a fractional power results in a :class:`complex` +number. (Since Python 2.6. In earlier versions it raised a :exc:`ValueError`.) .. _unary: Modified: python/branches/py3k/Include/import.h ============================================================================== --- python/branches/py3k/Include/import.h (original) +++ python/branches/py3k/Include/import.h Fri Jan 4 00:01:04 2008 @@ -14,13 +14,10 @@ PyAPI_FUNC(PyObject *) PyImport_GetModuleDict(void); PyAPI_FUNC(PyObject *) PyImport_AddModule(const char *name); PyAPI_FUNC(PyObject *) PyImport_ImportModule(const char *name); +PyAPI_FUNC(PyObject *) PyImport_ImportModuleNoBlock(const char *); PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level); -/* For DLL compatibility */ -#undef PyImport_ImportModuleEx -PyAPI_FUNC(PyObject *) PyImport_ImportModuleEx( - char *name, PyObject *globals, PyObject *locals, PyObject *fromlist); #define PyImport_ImportModuleEx(n, g, l, f) \ PyImport_ImportModuleLevel(n, g, l, f, -1) Modified: python/branches/py3k/Include/py_curses.h ============================================================================== --- python/branches/py3k/Include/py_curses.h (original) +++ python/branches/py3k/Include/py_curses.h Fri Jan 4 00:01:04 2008 @@ -90,7 +90,7 @@ #define import_curses() \ { \ - PyObject *module = PyImport_ImportModule("_curses"); \ + PyObject *module = PyImport_ImportModuleNoBlock("_curses"); \ if (module != NULL) { \ PyObject *module_dict = PyModule_GetDict(module); \ PyObject *c_api_object = PyDict_GetItemString(module_dict, "_C_API"); \ Modified: python/branches/py3k/Include/pyport.h ============================================================================== --- python/branches/py3k/Include/pyport.h (original) +++ python/branches/py3k/Include/pyport.h Fri Jan 4 00:01:04 2008 @@ -335,12 +335,19 @@ /* High precision defintion of pi and e (Euler) * The values are taken from libc6's math.h. */ +#ifndef Py_MATH_PIl +#define Py_MATH_PIl 3.1415926535897932384626433832795029L +#endif #ifndef Py_MATH_PI -#define Py_MATH_PI 3.1415926535897932384626433832795029L +#define Py_MATH_PI 3.14159265358979323846 +#endif + +#ifndef Py_MATH_El +#define Py_MATH_El 2.7182818284590452353602874713526625L #endif #ifndef Py_MATH_E -#define Py_MATH_E 2.7182818284590452353602874713526625L +#define Py_MATH_E 2.7182818284590452354 #endif /* Py_IS_NAN(X) Modified: python/branches/py3k/Lib/distutils/command/build_scripts.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/build_scripts.py (original) +++ python/branches/py3k/Lib/distutils/command/build_scripts.py Fri Jan 4 00:01:04 2008 @@ -110,7 +110,8 @@ if f: f.close() else: - f.close() + if f: + f.close() self.copy_file(script, outfile) if os.name == 'posix': Modified: python/branches/py3k/Lib/sre_compile.py ============================================================================== --- python/branches/py3k/Lib/sre_compile.py (original) +++ python/branches/py3k/Lib/sre_compile.py Fri Jan 4 00:01:04 2008 @@ -516,7 +516,7 @@ indexgroup[i] = k return _sre.compile( - pattern, flags, code, + pattern, flags | p.pattern.flags, code, p.pattern.groups-1, groupindex, indexgroup ) Modified: python/branches/py3k/Lib/test/test_math.py ============================================================================== --- python/branches/py3k/Lib/test/test_math.py (original) +++ python/branches/py3k/Lib/test/test_math.py Fri Jan 4 00:01:04 2008 @@ -231,6 +231,29 @@ self.ftest('tanh(0)', math.tanh(0), 0) self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0) + def testCopysign(self): + self.assertEqual(math.copysign(1, 42), 1.0) + self.assertEqual(math.copysign(0., 42), 0.0) + self.assertEqual(math.copysign(1., -42), -1.0) + self.assertEqual(math.copysign(3, 0.), 3.0) + self.assertEqual(math.copysign(4., -0.), -4.0) + + def testIsnan(self): + self.assert_(math.isnan(float("nan"))) + self.assert_(math.isnan(float("inf")* 0.)) + self.failIf(math.isnan(float("inf"))) + self.failIf(math.isnan(0.)) + self.failIf(math.isnan(1.)) + + def testIsinf(self): + self.assert_(math.isinf(float("inf"))) + self.assert_(math.isinf(float("-inf"))) + self.assert_(math.isinf(1E400)) + self.assert_(math.isinf(-1E400)) + self.failIf(math.isinf(float("nan"))) + self.failIf(math.isinf(0.)) + self.failIf(math.isinf(1.)) + # RED_FLAG 16-Oct-2000 Tim # While 2.0 is more consistent about exceptions than previous releases, it # still fails this part of the test on some platforms. For now, we only Modified: python/branches/py3k/Lib/test/test_re.py ============================================================================== --- python/branches/py3k/Lib/test/test_re.py (original) +++ python/branches/py3k/Lib/test/test_re.py Fri Jan 4 00:01:04 2008 @@ -632,6 +632,36 @@ self.assertEqual(re.compile("bla").match(a), None) self.assertEqual(re.compile("").match(a).groups(), ()) + def test_inline_flags(self): + # Bug #1700 + upper_char = unichr(0x1ea0) # Latin Capital Letter A with Dot Bellow + lower_char = unichr(0x1ea1) # Latin Small Letter A with Dot Bellow + + p = re.compile(upper_char, re.I | re.U) + q = p.match(lower_char) + self.assertNotEqual(q, None) + + p = re.compile(lower_char, re.I | re.U) + q = p.match(upper_char) + self.assertNotEqual(q, None) + + p = re.compile('(?i)' + upper_char, re.U) + q = p.match(lower_char) + self.assertNotEqual(q, None) + + p = re.compile('(?i)' + lower_char, re.U) + q = p.match(upper_char) + self.assertNotEqual(q, None) + + p = re.compile('(?iu)' + upper_char) + q = p.match(lower_char) + self.assertNotEqual(q, None) + + p = re.compile('(?iu)' + lower_char) + q = p.match(upper_char) + self.assertNotEqual(q, None) + + def run_re_tests(): from test.re_tests import benchmarks, tests, SUCCEED, FAIL, SYNTAX_ERROR if verbose: Modified: python/branches/py3k/Mac/Modules/MacOS.c ============================================================================== --- python/branches/py3k/Mac/Modules/MacOS.c (original) +++ python/branches/py3k/Mac/Modules/MacOS.c Fri Jan 4 00:01:04 2008 @@ -356,7 +356,7 @@ PyObject *m, *rv; errors_loaded = 1; - m = PyImport_ImportModule("macresource"); + m = PyImport_ImportModuleNoBlock("macresource"); if (!m) { if (Py_VerboseFlag) PyErr_Print(); Modified: python/branches/py3k/Modules/_ctypes/callbacks.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/callbacks.c (original) +++ python/branches/py3k/Modules/_ctypes/callbacks.c Fri Jan 4 00:01:04 2008 @@ -367,7 +367,7 @@ if (context == NULL) context = PyUnicode_FromString("_ctypes.DllGetClassObject"); - mod = PyImport_ImportModule("ctypes"); + mod = PyImport_ImportModuleNoBlock("ctypes"); if (!mod) { PyErr_WriteUnraisable(context ? context : Py_None); /* There has been a warning before about this already */ @@ -446,7 +446,7 @@ if (context == NULL) context = PyUnicode_FromString("_ctypes.DllCanUnloadNow"); - mod = PyImport_ImportModule("ctypes"); + mod = PyImport_ImportModuleNoBlock("ctypes"); if (!mod) { /* OutputDebugString("Could not import ctypes"); */ /* We assume that this error can only occur when shutting Modified: python/branches/py3k/Modules/_cursesmodule.c ============================================================================== --- python/branches/py3k/Modules/_cursesmodule.c (original) +++ python/branches/py3k/Modules/_cursesmodule.c Fri Jan 4 00:01:04 2008 @@ -2316,7 +2316,7 @@ update_lines_cols(void) { PyObject *o; - PyObject *m = PyImport_ImportModule("curses"); + PyObject *m = PyImport_ImportModuleNoBlock("curses"); if (!m) return 0; Modified: python/branches/py3k/Modules/cjkcodecs/cjkcodecs.h ============================================================================== --- python/branches/py3k/Modules/cjkcodecs/cjkcodecs.h (original) +++ python/branches/py3k/Modules/cjkcodecs/cjkcodecs.h Fri Jan 4 00:01:04 2008 @@ -245,7 +245,7 @@ static PyObject *cofunc = NULL; if (cofunc == NULL) { - PyObject *mod = PyImport_ImportModule("_multibytecodec"); + PyObject *mod = PyImport_ImportModuleNoBlock("_multibytecodec"); if (mod == NULL) return NULL; cofunc = PyObject_GetAttrString(mod, "__create_codec"); Modified: python/branches/py3k/Modules/datetimemodule.c ============================================================================== --- python/branches/py3k/Modules/datetimemodule.c (original) +++ python/branches/py3k/Modules/datetimemodule.c Fri Jan 4 00:01:04 2008 @@ -1329,7 +1329,7 @@ goto Done; { PyObject *format; - PyObject *time = PyImport_ImportModule("time"); + PyObject *time = PyImport_ImportModuleNoBlock("time"); if (time == NULL) goto Done; format = PyUnicode_FromString(PyString_AS_STRING(newfmt)); @@ -1357,7 +1357,7 @@ time_time(void) { PyObject *result = NULL; - PyObject *time = PyImport_ImportModule("time"); + PyObject *time = PyImport_ImportModuleNoBlock("time"); if (time != NULL) { result = PyObject_CallMethod(time, "time", "()"); @@ -1375,7 +1375,7 @@ PyObject *time; PyObject *result = NULL; - time = PyImport_ImportModule("time"); + time = PyImport_ImportModuleNoBlock("time"); if (time != NULL) { result = PyObject_CallMethod(time, "struct_time", "((iiiiiiiii))", @@ -3821,7 +3821,7 @@ if (!PyArg_ParseTuple(args, "uu:strptime", &string, &format)) return NULL; - if ((module = PyImport_ImportModule("time")) == NULL) + if ((module = PyImport_ImportModuleNoBlock("time")) == NULL) return NULL; obj = PyObject_CallMethod(module, "strptime", "uu", string, format); Py_DECREF(module); Modified: python/branches/py3k/Modules/gcmodule.c ============================================================================== --- python/branches/py3k/Modules/gcmodule.c (original) +++ python/branches/py3k/Modules/gcmodule.c Fri Jan 4 00:01:04 2008 @@ -1199,7 +1199,7 @@ * the import and triggers an assertion. */ if (tmod == NULL) { - tmod = PyImport_ImportModule("time"); + tmod = PyImport_ImportModuleNoBlock("time"); if (tmod == NULL) PyErr_Clear(); } Modified: python/branches/py3k/Modules/mathmodule.c ============================================================================== --- python/branches/py3k/Modules/mathmodule.c (original) +++ python/branches/py3k/Modules/mathmodule.c Fri Jan 4 00:01:04 2008 @@ -133,6 +133,14 @@ "cos(x)\n\nReturn the cosine of x (measured in radians).") FUNC1(cosh, cosh, "cosh(x)\n\nReturn the hyperbolic cosine of x.") +#if defined(MS_WINDOWS) || defined(HAVE_COPYSIGN) +#ifdef MS_WINDOWS +FUNC2(copysign, _copysign, +#else +FUNC2(copysign, copysign, +#endif + "copysign(x,y)\n\nReturn x with the sign of y."); +#endif FUNC1(exp, exp, "exp(x)\n\nReturn e raised to the power of x.") FUNC1(fabs, fabs, @@ -315,9 +323,8 @@ PyDoc_STRVAR(math_log10_doc, "log10(x) -> the base 10 logarithm of x."); -/* XXX(nnorwitz): Should we use the platform M_PI or something more accurate - like: 3.14159265358979323846264338327950288 */ -static const double degToRad = 3.141592653589793238462643383 / 180.0; +static const double degToRad = Py_MATH_PI / 180.0; +static const double radToDeg = 180.0 / Py_MATH_PI; static PyObject * math_degrees(PyObject *self, PyObject *arg) @@ -325,7 +332,7 @@ double x = PyFloat_AsDouble(arg); if (x == -1.0 && PyErr_Occurred()) return NULL; - return PyFloat_FromDouble(x / degToRad); + return PyFloat_FromDouble(x * radToDeg); } PyDoc_STRVAR(math_degrees_doc, @@ -343,12 +350,42 @@ PyDoc_STRVAR(math_radians_doc, "radians(x) -> converts angle x from degrees to radians"); +static PyObject * +math_isnan(PyObject *self, PyObject *arg) +{ + double x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) + return NULL; + return PyBool_FromLong((long)Py_IS_NAN(x)); +} + +PyDoc_STRVAR(math_isnan_doc, +"isnan(x) -> bool\n\ +Checks if float x is not a number (NaN)"); + +static PyObject * +math_isinf(PyObject *self, PyObject *arg) +{ + double x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) + return NULL; + return PyBool_FromLong((long)Py_IS_INFINITY(x)); +} + +PyDoc_STRVAR(math_isinf_doc, +"isinf(x) -> bool\n\ +Checks if float x is infinite (positive or negative)"); + + static PyMethodDef math_methods[] = { {"acos", math_acos, METH_O, math_acos_doc}, {"asin", math_asin, METH_O, math_asin_doc}, {"atan", math_atan, METH_O, math_atan_doc}, {"atan2", math_atan2, METH_VARARGS, math_atan2_doc}, {"ceil", math_ceil, METH_O, math_ceil_doc}, +#if defined(MS_WINDOWS) || defined(HAVE_COPYSIGN) + {"copysign", math_copysign, METH_VARARGS, math_copysign_doc}, +#endif {"cos", math_cos, METH_O, math_cos_doc}, {"cosh", math_cosh, METH_O, math_cosh_doc}, {"degrees", math_degrees, METH_O, math_degrees_doc}, @@ -358,6 +395,8 @@ {"fmod", math_fmod, METH_VARARGS, math_fmod_doc}, {"frexp", math_frexp, METH_O, math_frexp_doc}, {"hypot", math_hypot, METH_VARARGS, math_hypot_doc}, + {"isinf", math_isinf, METH_O, math_isinf_doc}, + {"isnan", math_isnan, METH_O, math_isnan_doc}, {"ldexp", math_ldexp, METH_VARARGS, math_ldexp_doc}, {"log", math_log, METH_VARARGS, math_log_doc}, {"log10", math_log10, METH_O, math_log10_doc}, @@ -389,13 +428,13 @@ if (d == NULL) goto finally; - if (!(v = PyFloat_FromDouble(atan(1.0) * 4.0))) + if (!(v = PyFloat_FromDouble(Py_MATH_PI))) goto finally; if (PyDict_SetItemString(d, "pi", v) < 0) goto finally; Py_DECREF(v); - if (!(v = PyFloat_FromDouble(exp(1.0)))) + if (!(v = PyFloat_FromDouble(Py_MATH_E))) goto finally; if (PyDict_SetItemString(d, "e", v) < 0) goto finally; Modified: python/branches/py3k/Modules/parsermodule.c ============================================================================== --- python/branches/py3k/Modules/parsermodule.c (original) +++ python/branches/py3k/Modules/parsermodule.c Fri Jan 4 00:01:04 2008 @@ -3093,7 +3093,7 @@ * If this fails, the import of this module will fail because an * exception will be raised here; should we clear the exception? */ - copyreg = PyImport_ImportModule("copy_reg"); + copyreg = PyImport_ImportModuleNoBlock("copy_reg"); if (copyreg != NULL) { PyObject *func, *pickler; Modified: python/branches/py3k/Modules/posixmodule.c ============================================================================== --- python/branches/py3k/Modules/posixmodule.c (original) +++ python/branches/py3k/Modules/posixmodule.c Fri Jan 4 00:01:04 2008 @@ -4217,7 +4217,7 @@ return posix_error(); if (struct_rusage == NULL) { - PyObject *m = PyImport_ImportModule("resource"); + PyObject *m = PyImport_ImportModuleNoBlock("resource"); if (m == NULL) return NULL; struct_rusage = PyObject_GetAttrString(m, "struct_rusage"); Modified: python/branches/py3k/Modules/socketmodule.h ============================================================================== --- python/branches/py3k/Modules/socketmodule.h (original) +++ python/branches/py3k/Modules/socketmodule.h Fri Jan 4 00:01:04 2008 @@ -222,7 +222,7 @@ void *api; DPRINTF("Importing the %s C API...\n", apimodule); - mod = PyImport_ImportModule(apimodule); + mod = PyImport_ImportModuleNoBlock(apimodule); if (mod == NULL) goto onError; DPRINTF(" %s package found\n", apimodule); Modified: python/branches/py3k/Modules/timemodule.c ============================================================================== --- python/branches/py3k/Modules/timemodule.c (original) +++ python/branches/py3k/Modules/timemodule.c Fri Jan 4 00:01:04 2008 @@ -556,7 +556,7 @@ static PyObject * time_strptime(PyObject *self, PyObject *args) { - PyObject *strptime_module = PyImport_ImportModule("_strptime"); + PyObject *strptime_module = PyImport_ImportModuleNoBlock("_strptime"); PyObject *strptime_result; if (!strptime_module) @@ -668,7 +668,7 @@ { PyObject* m; - m = PyImport_ImportModule("time"); + m = PyImport_ImportModuleNoBlock("time"); if (m == NULL) { return NULL; } Modified: python/branches/py3k/Modules/zipimport.c ============================================================================== --- python/branches/py3k/Modules/zipimport.c (original) +++ python/branches/py3k/Modules/zipimport.c Fri Jan 4 00:01:04 2008 @@ -766,7 +766,7 @@ let's avoid a stack overflow. */ return NULL; importing_zlib = 1; - zlib = PyImport_ImportModule("zlib"); /* import zlib */ + zlib = PyImport_ImportModuleNoBlock("zlib"); importing_zlib = 0; if (zlib != NULL) { decompress = PyObject_GetAttrString(zlib, Modified: python/branches/py3k/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k/Objects/unicodeobject.c (original) +++ python/branches/py3k/Objects/unicodeobject.c Fri Jan 4 00:01:04 2008 @@ -2800,7 +2800,7 @@ if (ucnhash_CAPI == NULL) { /* load the unicode data module */ PyObject *m, *api; - m = PyImport_ImportModule("unicodedata"); + m = PyImport_ImportModuleNoBlock("unicodedata"); if (m == NULL) goto ucnhashError; api = PyObject_GetAttrString(m, "ucnhash_CAPI"); Modified: python/branches/py3k/PC/VS8.0/pythoncore.vcproj ============================================================================== --- python/branches/py3k/PC/VS8.0/pythoncore.vcproj (original) +++ python/branches/py3k/PC/VS8.0/pythoncore.vcproj Fri Jan 4 00:01:04 2008 @@ -1599,10 +1599,6 @@ > - - Modified: python/branches/py3k/PCbuild/pythoncore.vcproj ============================================================================== --- python/branches/py3k/PCbuild/pythoncore.vcproj (original) +++ python/branches/py3k/PCbuild/pythoncore.vcproj Fri Jan 4 00:01:04 2008 @@ -1599,10 +1599,6 @@ > - - Modified: python/branches/py3k/Python/errors.c ============================================================================== --- python/branches/py3k/Python/errors.c (original) +++ python/branches/py3k/Python/errors.c Fri Jan 4 00:01:04 2008 @@ -711,7 +711,7 @@ { PyObject *mod, *dict, *func = NULL; - mod = PyImport_ImportModule("warnings"); + mod = PyImport_ImportModuleNoBlock("warnings"); if (mod != NULL) { dict = PyModule_GetDict(mod); func = PyDict_GetItemString(dict, "warn_explicit"); Modified: python/branches/py3k/Python/import.c ============================================================================== --- python/branches/py3k/Python/import.c (original) +++ python/branches/py3k/Python/import.c Fri Jan 4 00:01:04 2008 @@ -1896,6 +1896,53 @@ return result; } +/* Import a module without blocking + * + * At first it tries to fetch the module from sys.modules. If the module was + * never loaded before it loads it with PyImport_ImportModule() unless another + * thread holds the import lock. In the latter case the function raises an + * ImportError instead of blocking. + * + * Returns the module object with incremented ref count. + */ +PyObject * +PyImport_ImportModuleNoBlock(const char *name) +{ + PyObject *result; + PyObject *modules; + long me; + + /* Try to get the module from sys.modules[name] */ + modules = PyImport_GetModuleDict(); + if (modules == NULL) + return NULL; + + result = PyDict_GetItemString(modules, name); + if (result != NULL) { + Py_INCREF(result); + return result; + } + else { + PyErr_Clear(); + } + + /* check the import lock + * me might be -1 but I ignore the error here, the lock function + * takes care of the problem */ + me = PyThread_get_thread_ident(); + if (import_lock_thread == -1 || import_lock_thread == me) { + /* no thread or me is holding the lock */ + return PyImport_ImportModule(name); + } + else { + PyErr_Format(PyExc_ImportError, + "Failed to import %.200s because the import lock" + "is held by another thread.", + name); + return NULL; + } +} + /* Forward declarations for helper routines */ static PyObject *get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level); @@ -1965,26 +2012,6 @@ return tail; } -/* For DLL compatibility */ -#undef PyImport_ImportModuleEx -PyObject * -PyImport_ImportModuleEx(char *name, PyObject *globals, PyObject *locals, - PyObject *fromlist) -{ - PyObject *result; - lock_import(); - result = import_module_level(name, globals, locals, fromlist, -1); - if (unlock_import() < 0) { - Py_XDECREF(result); - PyErr_SetString(PyExc_RuntimeError, - "not holding the import lock"); - return NULL; - } - return result; -} -#define PyImport_ImportModuleEx(n, g, l, f) \ - PyImport_ImportModuleLevel(n, g, l, f, -1); - PyObject * PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level) @@ -2572,9 +2599,10 @@ if (import == NULL) goto err; - /* Call the __import__ function with the proper argument list */ - r = PyObject_CallFunctionObjArgs(import, module_name, globals, - globals, silly_list, NULL); + /* Call the __import__ function with the proper argument list + * Always use absolute import here. */ + r = PyObject_CallFunction(import, "OOOOi", module_name, globals, + globals, silly_list, 0, NULL); err: Py_XDECREF(globals); Modified: python/branches/py3k/Python/mactoolboxglue.c ============================================================================== --- python/branches/py3k/Python/mactoolboxglue.c (original) +++ python/branches/py3k/Python/mactoolboxglue.c Fri Jan 4 00:01:04 2008 @@ -36,7 +36,7 @@ PyObject *m; PyObject *rv; - m = PyImport_ImportModule("MacOS"); + m = PyImport_ImportModuleNoBlock("MacOS"); if (!m) { if (Py_VerboseFlag) PyErr_Print(); From python-3000-checkins at python.org Fri Jan 4 00:05:47 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Fri, 4 Jan 2008 00:05:47 +0100 (CET) Subject: [Python-3000-checkins] r59681 - in python/branches/py3k: Parser/tokenizer.c Python/ast.c Python/bltinmodule.c Python/codecs.c Message-ID: <20080103230547.AFCB41E4018@bag.python.org> Author: christian.heimes Date: Fri Jan 4 00:05:47 2008 New Revision: 59681 Modified: python/branches/py3k/Parser/tokenizer.c python/branches/py3k/Python/ast.c python/branches/py3k/Python/bltinmodule.c python/branches/py3k/Python/codecs.c Log: More PyImport_ImportModule -> PyImport_ImportModuleNoBlock Modified: python/branches/py3k/Parser/tokenizer.c ============================================================================== --- python/branches/py3k/Parser/tokenizer.c (original) +++ python/branches/py3k/Parser/tokenizer.c Fri Jan 4 00:05:47 2008 @@ -452,7 +452,7 @@ { PyObject *readline = NULL, *stream = NULL, *io = NULL; - io = PyImport_ImportModule("io"); + io = PyImport_ImportModuleNoBlock("io"); if (io == NULL) goto cleanup; Modified: python/branches/py3k/Python/ast.c ============================================================================== --- python/branches/py3k/Python/ast.c (original) +++ python/branches/py3k/Python/ast.c Fri Jan 4 00:05:47 2008 @@ -56,7 +56,7 @@ identifier; if so, normalize to NFKC. */ for (; *u; u++) { if (*u >= 128) { - PyObject *m = PyImport_ImportModule("unicodedata"); + PyObject *m = PyImport_ImportModuleNoBlock("unicodedata"); PyObject *id2; if (!m) return NULL; Modified: python/branches/py3k/Python/bltinmodule.c ============================================================================== --- python/branches/py3k/Python/bltinmodule.c (original) +++ python/branches/py3k/Python/bltinmodule.c Fri Jan 4 00:05:47 2008 @@ -281,7 +281,7 @@ builtin_filter(PyObject *self, PyObject *args) { PyObject *itertools, *ifilter, *result; - itertools = PyImport_ImportModule("itertools"); + itertools = PyImport_ImportModuleNoBlock("itertools"); if (itertools == NULL) return NULL; ifilter = PyObject_GetAttrString(itertools, "ifilter"); @@ -796,7 +796,7 @@ builtin_map(PyObject *self, PyObject *args) { PyObject *itertools, *imap, *result; - itertools = PyImport_ImportModule("itertools"); + itertools = PyImport_ImportModuleNoBlock("itertools"); if (itertools == NULL) return NULL; imap = PyObject_GetAttrString(itertools, "imap"); Modified: python/branches/py3k/Python/codecs.c ============================================================================== --- python/branches/py3k/Python/codecs.c (original) +++ python/branches/py3k/Python/codecs.c Fri Jan 4 00:05:47 2008 @@ -850,7 +850,7 @@ interp->codec_error_registry == NULL) Py_FatalError("can't initialize codec registry"); - mod = PyImport_ImportModuleLevel("encodings", NULL, NULL, NULL, 0); + mod = PyImport_ImportModuleNoBlock("encodings"); if (mod == NULL) { if (PyErr_ExceptionMatches(PyExc_ImportError)) { /* Ignore ImportErrors... this is done so that From python-3000-checkins at python.org Fri Jan 4 00:42:13 2008 From: python-3000-checkins at python.org (amaury.forgeotdarc) Date: Fri, 4 Jan 2008 00:42:13 +0100 (CET) Subject: [Python-3000-checkins] r59682 - python/branches/py3k/Python/dynload_win.c Message-ID: <20080103234213.738211E4006@bag.python.org> Author: amaury.forgeotdarc Date: Fri Jan 4 00:42:13 2008 New Revision: 59682 Modified: python/branches/py3k/Python/dynload_win.c Log: On Windows, when import fails to load a dll module, the message says "error code 193" instead of a more informative text. It turns out that FormatMessage needs additional parameters for some error codes. For example: 193 means "%1 is not a valid Win32 application". Since it is impossible to know which parameter to pass, we use FORMAT_MESSAGE_IGNORE_INSERTS to get the raw message, which is still better than the number. Also use the Unicode version of the API, to deal with accented letters. Modified: python/branches/py3k/Python/dynload_win.c ============================================================================== --- python/branches/py3k/Python/dynload_win.c (original) +++ python/branches/py3k/Python/dynload_win.c Fri Jan 4 00:42:13 2008 @@ -183,33 +183,35 @@ hDLL = LoadLibraryEx(pathname, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); if (hDLL==NULL){ - char errBuf[256]; + PyObject *message; unsigned int errorCode; /* Get an error string from Win32 error code */ - char theInfo[256]; /* Pointer to error text + wchar_t theInfo[256]; /* Pointer to error text from system */ int theLength; /* Length of error text */ errorCode = GetLastError(); - theLength = FormatMessage( - FORMAT_MESSAGE_FROM_SYSTEM, /* flags */ + theLength = FormatMessageW( + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, /* flags */ NULL, /* message source */ errorCode, /* the message (error) ID */ - 0, /* default language environment */ - (LPTSTR) theInfo, /* the buffer */ + MAKELANGID(LANG_NEUTRAL, + SUBLANG_DEFAULT), + /* Default language */ + theInfo, /* the buffer */ sizeof(theInfo), /* the buffer size */ NULL); /* no additional format args. */ /* Problem: could not get the error message. This should not happen if called correctly. */ if (theLength == 0) { - PyOS_snprintf(errBuf, sizeof(errBuf), - "DLL load failed with error code %d", - errorCode); + message = PyUnicode_FromFormat( + "DLL load failed with error code %d", + errorCode); } else { - size_t len; /* For some reason a \r\n is appended to the text */ if (theLength >= 2 && @@ -218,13 +220,16 @@ theLength -= 2; theInfo[theLength] = '\0'; } - strcpy(errBuf, "DLL load failed: "); - len = strlen(errBuf); - strncpy(errBuf+len, theInfo, - sizeof(errBuf)-len); - errBuf[sizeof(errBuf)-1] = '\0'; + message = PyUnicode_FromString( + "DLL load failed: "); + + PyUnicode_AppendAndDel(&message, + PyUnicode_FromUnicode( + theInfo, + theLength)); } - PyErr_SetString(PyExc_ImportError, errBuf); + PyErr_SetObject(PyExc_ImportError, message); + Py_XDECREF(message); return NULL; } else { char buffer[256]; From guido at python.org Fri Jan 4 00:44:05 2008 From: guido at python.org (Guido van Rossum) Date: Thu, 3 Jan 2008 15:44:05 -0800 Subject: [Python-3000-checkins] r59682 - python/branches/py3k/Python/dynload_win.c In-Reply-To: <20080103234213.738211E4006@bag.python.org> References: <20080103234213.738211E4006@bag.python.org> Message-ID: Is this Py3k specific? On Jan 3, 2008 3:42 PM, amaury.forgeotdarc wrote: > Author: amaury.forgeotdarc > Date: Fri Jan 4 00:42:13 2008 > New Revision: 59682 > > Modified: > python/branches/py3k/Python/dynload_win.c > Log: > On Windows, when import fails to load a dll module, the message says > "error code 193" instead of a more informative text. > > It turns out that FormatMessage needs additional parameters for some error codes. > For example: 193 means "%1 is not a valid Win32 application". > Since it is impossible to know which parameter to pass, we use > FORMAT_MESSAGE_IGNORE_INSERTS to get the raw message, which is still better > than the number. > > Also use the Unicode version of the API, to deal with accented letters. > > > > Modified: python/branches/py3k/Python/dynload_win.c > ============================================================================== > --- python/branches/py3k/Python/dynload_win.c (original) > +++ python/branches/py3k/Python/dynload_win.c Fri Jan 4 00:42:13 2008 > @@ -183,33 +183,35 @@ > hDLL = LoadLibraryEx(pathname, NULL, > LOAD_WITH_ALTERED_SEARCH_PATH); > if (hDLL==NULL){ > - char errBuf[256]; > + PyObject *message; > unsigned int errorCode; > > /* Get an error string from Win32 error code */ > - char theInfo[256]; /* Pointer to error text > + wchar_t theInfo[256]; /* Pointer to error text > from system */ > int theLength; /* Length of error text */ > > errorCode = GetLastError(); > > - theLength = FormatMessage( > - FORMAT_MESSAGE_FROM_SYSTEM, /* flags */ > + theLength = FormatMessageW( > + FORMAT_MESSAGE_FROM_SYSTEM | > + FORMAT_MESSAGE_IGNORE_INSERTS, /* flags */ > NULL, /* message source */ > errorCode, /* the message (error) ID */ > - 0, /* default language environment */ > - (LPTSTR) theInfo, /* the buffer */ > + MAKELANGID(LANG_NEUTRAL, > + SUBLANG_DEFAULT), > + /* Default language */ > + theInfo, /* the buffer */ > sizeof(theInfo), /* the buffer size */ > NULL); /* no additional format args. */ > > /* Problem: could not get the error message. > This should not happen if called correctly. */ > if (theLength == 0) { > - PyOS_snprintf(errBuf, sizeof(errBuf), > - "DLL load failed with error code %d", > - errorCode); > + message = PyUnicode_FromFormat( > + "DLL load failed with error code %d", > + errorCode); > } else { > - size_t len; > /* For some reason a \r\n > is appended to the text */ > if (theLength >= 2 && > @@ -218,13 +220,16 @@ > theLength -= 2; > theInfo[theLength] = '\0'; > } > - strcpy(errBuf, "DLL load failed: "); > - len = strlen(errBuf); > - strncpy(errBuf+len, theInfo, > - sizeof(errBuf)-len); > - errBuf[sizeof(errBuf)-1] = '\0'; > + message = PyUnicode_FromString( > + "DLL load failed: "); > + > + PyUnicode_AppendAndDel(&message, > + PyUnicode_FromUnicode( > + theInfo, > + theLength)); > } > - PyErr_SetString(PyExc_ImportError, errBuf); > + PyErr_SetObject(PyExc_ImportError, message); > + Py_XDECREF(message); > return NULL; > } else { > char buffer[256]; > _______________________________________________ > Python-3000-checkins mailing list > Python-3000-checkins at python.org > http://mail.python.org/mailman/listinfo/python-3000-checkins > -- --Guido van Rossum (home page: http://www.python.org/~guido/) From python-3000-checkins at python.org Fri Jan 4 01:47:51 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Fri, 4 Jan 2008 01:47:51 +0100 (CET) Subject: [Python-3000-checkins] r59690 - python/branches/py3k/Lib/test/test_re.py Message-ID: <20080104004751.9EE751E4006@bag.python.org> Author: christian.heimes Date: Fri Jan 4 01:47:51 2008 New Revision: 59690 Modified: python/branches/py3k/Lib/test/test_re.py Log: Fixed unichr() -> chr() Modified: python/branches/py3k/Lib/test/test_re.py ============================================================================== --- python/branches/py3k/Lib/test/test_re.py (original) +++ python/branches/py3k/Lib/test/test_re.py Fri Jan 4 01:47:51 2008 @@ -634,8 +634,8 @@ def test_inline_flags(self): # Bug #1700 - upper_char = unichr(0x1ea0) # Latin Capital Letter A with Dot Bellow - lower_char = unichr(0x1ea1) # Latin Small Letter A with Dot Bellow + upper_char = chr(0x1ea0) # Latin Capital Letter A with Dot Bellow + lower_char = chr(0x1ea1) # Latin Small Letter A with Dot Bellow p = re.compile(upper_char, re.I | re.U) q = p.match(lower_char) From lists at cheimes.de Fri Jan 4 01:51:35 2008 From: lists at cheimes.de (Christian Heimes) Date: Fri, 04 Jan 2008 01:51:35 +0100 Subject: [Python-3000-checkins] r59682 - python/branches/py3k/Python/dynload_win.c In-Reply-To: <20080103234213.738211E4006@bag.python.org> References: <20080103234213.738211E4006@bag.python.org> Message-ID: <477D8317.10400@cheimes.de> amaury.forgeotdarc wrote: > Author: amaury.forgeotdarc > Date: Fri Jan 4 00:42:13 2008 > New Revision: 59682 > > Modified: > python/branches/py3k/Python/dynload_win.c > Log: > On Windows, when import fails to load a dll module, the message says > "error code 193" instead of a more informative text. I don't see Misc/NEWS in the modified list ... From python-3000-checkins at python.org Fri Jan 4 02:21:27 2008 From: python-3000-checkins at python.org (amaury.forgeotdarc) Date: Fri, 4 Jan 2008 02:21:27 +0100 (CET) Subject: [Python-3000-checkins] r59693 - python/branches/py3k/Misc/NEWS Message-ID: <20080104012127.D38681E4006@bag.python.org> Author: amaury.forgeotdarc Date: Fri Jan 4 02:21:27 2008 New Revision: 59693 Modified: python/branches/py3k/Misc/NEWS Log: NEWS entry for r59682. Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Jan 4 02:21:27 2008 @@ -12,6 +12,11 @@ Core and Builtins ----------------- +- Improve some exception messages when Windows fails to load an extension + module. Now we get for example '%1 is not a valid Win32 application' instead + of 'error code 193'. Also use Unicode strings to deal with non-English + locales. + - Issue #1587: Added instancemethod wrapper for PyCFunctions. The Python C API has gained a new type *PyInstanceMethod_Type* and the functions *PyInstanceMethod_Check(o)*, *PyInstanceMethod_New(func)* and From amauryfa at gmail.com Fri Jan 4 02:20:52 2008 From: amauryfa at gmail.com (Amaury Forgeot d'Arc) Date: Fri, 4 Jan 2008 02:20:52 +0100 Subject: [Python-3000-checkins] r59682 - python/branches/py3k/Python/dynload_win.c Message-ID: > > Log: > > On Windows, when import fails to load a dll module, the message says > > "error code 193" instead of a more informative text. > > I don't see Misc/NEWS in the modified list ... Oops, I always write a paragraph in it but I forgot to check in... Thanks for reminding me. -- Amaury Forgeot d'Arc From amauryfa at gmail.com Fri Jan 4 02:33:19 2008 From: amauryfa at gmail.com (Amaury Forgeot d'Arc) Date: Fri, 4 Jan 2008 02:33:19 +0100 Subject: [Python-3000-checkins] r59682 - python/branches/py3k/Python/dynload_win.c Message-ID: Guido van Rossum wrote: > Is this Py3k specific? It is reproducible with all python versions. in python 2.x, the patch is just one line (the FORMAT_MESSAGE_IGNORE_INSERTS flag) I will include it as soon as I can compile the trunk version. At the moment there seem to be a problem with mathmodule.c. -- Amaury Forgeot d'Arc From guido at python.org Fri Jan 4 02:42:46 2008 From: guido at python.org (Guido van Rossum) Date: Thu, 3 Jan 2008 17:42:46 -0800 Subject: [Python-3000-checkins] r59682 - python/branches/py3k/Python/dynload_win.c In-Reply-To: References: Message-ID: On Jan 3, 2008 5:33 PM, Amaury Forgeot d'Arc wrote: > Guido van Rossum wrote: > > Is this Py3k specific? > > It is reproducible with all python versions. > in python 2.x, the patch is just one line (the > FORMAT_MESSAGE_IGNORE_INSERTS flag) > > I will include it as soon as I can compile the trunk version. > At the moment there seem to be a problem with mathmodule.c. Christian will have to deal with that. But a general suggestion: changes that apply to both 2.6 and 3.0 ought to be applied to 2.6 first; then we can use the (semi- :-) automatic merge to get it ported to 3.0. Unless the code in 2.6 looks very different from 3.0. -- --Guido van Rossum (home page: http://www.python.org/~guido/) From lists at cheimes.de Fri Jan 4 02:50:13 2008 From: lists at cheimes.de (Christian Heimes) Date: Fri, 04 Jan 2008 02:50:13 +0100 Subject: [Python-3000-checkins] r59682 - python/branches/py3k/Python/dynload_win.c In-Reply-To: References: Message-ID: <477D90D5.3020509@cheimes.de> Guido van Rossum wrote: > Christian will have to deal with that. I've fixed it on Windows and I'm going to merge it to 3.0 ASAP. > But a general suggestion: changes that apply to both 2.6 and 3.0 ought > to be applied to 2.6 first; then we can use the (semi- :-) automatic > merge to get it ported to 3.0. Unless the code in 2.6 looks very > different from 3.0. Semi is my second Christian name *scnr* Christian From amauryfa at gmail.com Fri Jan 4 02:52:59 2008 From: amauryfa at gmail.com (Amaury Forgeot d'Arc) Date: Fri, 4 Jan 2008 02:52:59 +0100 Subject: [Python-3000-checkins] r59682 - python/branches/py3k/Python/dynload_win.c In-Reply-To: References: Message-ID: Guido van Rossum wrote: > On Jan 3, 2008 5:33 PM, Amaury Forgeot d'Arc wrote: > > Guido van Rossum wrote: > > > Is this Py3k specific? > > > > It is reproducible with all python versions. > > in python 2.x, the patch is just one line (the > > FORMAT_MESSAGE_IGNORE_INSERTS flag) > > > > I will include it as soon as I can compile the trunk version. > > At the moment there seem to be a problem with mathmodule.c. > > Christian will have to deal with that. > > But a general suggestion: changes that apply to both 2.6 and 3.0 ought > to be applied to 2.6 first; then we can use the (semi- :-) automatic > merge to get it ported to 3.0. Unless the code in 2.6 looks very > different from 3.0. Agreed. In this case, the motivation of the fix was a unicode py3k-specific problem. I only realized afterwards that there were two problems stacking in the same block. -- Amaury Forgeot d'Arc From python-3000-checkins at python.org Fri Jan 4 04:06:11 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Fri, 4 Jan 2008 04:06:11 +0100 (CET) Subject: [Python-3000-checkins] r59702 - in python/branches/py3k: Doc/library/msvcrt.rst Doc/whatsnew/2.6.rst Lib/plat-mac/plistlib.py Lib/test/regrtest.py Lib/test/test_long.py Modules/_struct.c Modules/_tkinter.c Modules/mathmodule.c Objects/longobject.c Message-ID: <20080104030611.6297C1E4015@bag.python.org> Author: christian.heimes Date: Fri Jan 4 04:06:10 2008 New Revision: 59702 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/msvcrt.rst python/branches/py3k/Doc/whatsnew/2.6.rst python/branches/py3k/Lib/plat-mac/plistlib.py python/branches/py3k/Lib/test/regrtest.py python/branches/py3k/Lib/test/test_long.py python/branches/py3k/Modules/_struct.c python/branches/py3k/Modules/_tkinter.c python/branches/py3k/Modules/mathmodule.c python/branches/py3k/Objects/longobject.c Log: Merged revisions 59680-59695 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r59686 | guido.van.rossum | 2008-01-04 00:54:04 +0100 (Fri, 04 Jan 2008) | 2 lines Bug #1301: fixed a bad assert in _tkinter. ........ r59687 | raymond.hettinger | 2008-01-04 01:01:15 +0100 (Fri, 04 Jan 2008) | 3 lines Finish-up the struct module optimizations started at the Iceland NFS sprint. ........ r59688 | christian.heimes | 2008-01-04 01:04:52 +0100 (Fri, 04 Jan 2008) | 1 line Fixed #1687: plistlib.py restricts to Python int when writing ........ r59689 | christian.heimes | 2008-01-04 01:37:34 +0100 (Fri, 04 Jan 2008) | 1 line Bug #1481296: Fixed long(float('nan'))!=0L. ........ r59691 | andrew.kuchling | 2008-01-04 02:15:50 +0100 (Fri, 04 Jan 2008) | 1 line Markup fixes; grammar tweaks ........ r59692 | andrew.kuchling | 2008-01-04 02:16:12 +0100 (Fri, 04 Jan 2008) | 1 line Add items ........ r59694 | christian.heimes | 2008-01-04 02:48:50 +0100 (Fri, 04 Jan 2008) | 1 line Fixed math.copysign() on Windows ........ r59695 | christian.heimes | 2008-01-04 03:03:25 +0100 (Fri, 04 Jan 2008) | 1 line Filled in some XXX comments ........ Modified: python/branches/py3k/Doc/library/msvcrt.rst ============================================================================== --- python/branches/py3k/Doc/library/msvcrt.rst (original) +++ python/branches/py3k/Doc/library/msvcrt.rst Fri Jan 4 04:06:10 2008 @@ -101,9 +101,9 @@ .. function:: getwch() - Wide char variant of `func:getch`, returns unicode. + Wide char variant of :func:`getch`, returning a Unicode value. - ..versionadded:: 2.6 + .. versionadded:: 2.6 .. function:: getche() @@ -114,9 +114,9 @@ .. function:: getwche() - Wide char variant of `func:getche`, returns unicode. + Wide char variant of :func:`getche`, returning a Unicode value. - ..versionadded:: 2.6 + .. versionadded:: 2.6 .. function:: putch(char) @@ -126,9 +126,9 @@ .. function:: putwch(unicode_char) - Wide char variant of `func:putch`, accepts unicode. + Wide char variant of :func:`putch`, accepting a Unicode value. - ..versionadded:: 2.6 + .. versionadded:: 2.6 .. function:: ungetch(char) @@ -139,9 +139,9 @@ .. function:: ungetwch(unicode_char) - Wide char variant of `func:ungetch`, accepts unicode. + Wide char variant of :func:`ungetch`, accepting a Unicode value. - ..versionadded:: 2.6 + .. versionadded:: 2.6 .. _msvcrt-other: Modified: python/branches/py3k/Doc/whatsnew/2.6.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/2.6.rst (original) +++ python/branches/py3k/Doc/whatsnew/2.6.rst Fri Jan 4 04:06:10 2008 @@ -552,6 +552,14 @@ .. Patch 1507 +* More floating-point features were also added. The :func:`float` function + will now turn the strings ``+nan`` and ``-nan`` into the corresponding + IEEE 754 Not a Number values, and ``+inf`` and ``-inf`` into + positive or negative infinity. This works on any platform with + IEEE 754 semantics. (Contributed by Christian Heimes.) + + .. Patch 1635. + * Changes to the :class:`Exception` interface as dictated by :pep:`352` continue to be made. For 2.6, the :attr:`message` attribute is being deprecated in favor of the @@ -1055,14 +1063,35 @@ ``"mant_dig"`` (number of digits in the mantissa), ``"epsilon"`` (smallest difference between 1.0 and the next largest value representable), and several others. + (Contributed by Christian Heimes.) .. Issue 1534 +* Python's C API now includes two functions for case-insensitive string + comparisions, ``PyOS_stricmp(char*, char*)`` + and ``PyOS_strnicmp(char*, char*, Py_ssize_t)``. + (Contributed by Christian Heimes.) + + .. Issue 1635 + +* Some macros were renamed. :cmacro:`Py_Size()` became :cmacro:`Py_SIZE()`, + :cmacro:`Py_Type()` became :cmacro:`Py_TYPE()`, and + :cmacro:`Py_Refcnt()` became :cmacro:`Py_REFCNT()`. Macros for backward + compatibility are still available for Python 2.6. + + .. Issue 1629: XXX why was this done? + .. ====================================================================== -Port-Specific Changes ---------------------- +Port-Specific Changes: Windows +----------------------------------- + +* The :mod:`msvcrt` module now supports + both the normal and wide char variants of the console I/O + API. The :func:`getwch` function reads a keypress and returns a Unicode + value, as does the :func:`getwche` function. The :func:`putwch` function + takes a Unicode character and writes it to the console. Platform-specific changes go here. @@ -1089,9 +1118,15 @@ Porting to Python 2.6 ===================== -This section lists previously described changes that may require changes to your +This section lists previously described changes, and a few +esoteric bugfixes, that may require changes to your code: +* The :method:`__init__` method of :class:`collections.deque` + now clears any existing contents of the deque + before adding elements from the iterable. This change makes the + behavior match that of ``list.__init__()``. + * The :mod:`socket` module exception :exc:`socket.error` now inherits from :exc:`IOError`. Previously it wasn't a subclass of :exc:`StandardError` but now it is, through :exc:`IOError`. Modified: python/branches/py3k/Lib/plat-mac/plistlib.py ============================================================================== --- python/branches/py3k/Lib/plat-mac/plistlib.py (original) +++ python/branches/py3k/Lib/plat-mac/plistlib.py Fri Jan 4 04:06:10 2008 @@ -242,8 +242,8 @@ self.simpleElement("true") else: self.simpleElement("false") - elif isinstance(value, int): - self.simpleElement("integer", str(value)) + elif isinstance(value, (int, long)): + self.simpleElement("integer", "%d" % value) elif isinstance(value, float): self.simpleElement("real", repr(value)) elif isinstance(value, dict): Modified: python/branches/py3k/Lib/test/regrtest.py ============================================================================== --- python/branches/py3k/Lib/test/regrtest.py (original) +++ python/branches/py3k/Lib/test/regrtest.py Fri Jan 4 04:06:10 2008 @@ -771,8 +771,8 @@ dircache.reset() linecache.clearcache() mimetypes._default_mime_types() - struct._cache.clear() filecmp._cache.clear() + struct._clearcache() doctest.master = None # Collect cyclic trash. Modified: python/branches/py3k/Lib/test/test_long.py ============================================================================== --- python/branches/py3k/Lib/test/test_long.py (original) +++ python/branches/py3k/Lib/test/test_long.py Fri Jan 4 04:06:10 2008 @@ -537,6 +537,10 @@ # conversion to string should fail self.assertRaises(ValueError, format, 3, "s") + def test_nan_inf(self): + self.assertRaises(OverflowError, long, float('inf')) + self.assertEqual(long(float('nan')), 0L) + def test_main(): test_support.run_unittest(LongTest) Modified: python/branches/py3k/Modules/_struct.c ============================================================================== --- python/branches/py3k/Modules/_struct.c (original) +++ python/branches/py3k/Modules/_struct.c Fri Jan 4 04:06:10 2008 @@ -1464,11 +1464,28 @@ assert(PyStruct_Check(self)); - if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:Struct", kwlist, &o_format)) return -1; - Py_INCREF(o_format); + if (PyUnicode_Check(o_format)) { + o_format = PyUnicode_AsASCIIString(o_format); + if (o_format == NULL) + return -1; + } + /* XXX support buffer interface, too */ + else { + Py_INCREF(o_format); + } + + if (!PyString_Check(o_format)) { + Py_DECREF(o_format); + PyErr_Format(PyExc_TypeError, + "Struct() argument 1 must be bytes, not %.200s", + Py_TYPE(o_format)->tp_name); + return -1; + } + Py_XDECREF(soself->s_format); soself->s_format = o_format; @@ -1861,12 +1878,226 @@ PyObject_Del, /* tp_free */ }; + +/* ---- Standalone functions ---- */ + +#define MAXCACHE 100 +static PyObject *cache = NULL; + +static PyObject * +cache_struct(PyObject *fmt) +{ + PyObject * s_object; + + if (cache == NULL) { + cache = PyDict_New(); + if (cache == NULL) + return NULL; + } + + s_object = PyDict_GetItem(cache, fmt); + if (s_object != NULL) { + Py_INCREF(s_object); + return s_object; + } + + s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL); + if (s_object != NULL) { + if (PyDict_Size(cache) >= MAXCACHE) + PyDict_Clear(cache); + /* Attempt to cache the result */ + if (PyDict_SetItem(cache, fmt, s_object) == -1) + PyErr_Clear(); + } + return s_object; +} + +PyDoc_STRVAR(clearcache_doc, +"Clear the internal cache."); + +static PyObject * +clearcache(PyObject *self) +{ + if (cache != NULL) + PyDict_Clear(cache); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(calcsize_doc, +"Return size of C struct described by format string fmt."); + +static PyObject * +calcsize(PyObject *self, PyObject *fmt) +{ + Py_ssize_t n; + PyObject *s_object = cache_struct(fmt); + if (s_object == NULL) + return NULL; + n = ((PyStructObject *)s_object)->s_size; + Py_DECREF(s_object); + return PyLong_FromSsize_t(n); +} + +PyDoc_STRVAR(pack_doc, +"Return string containing values v1, v2, ... packed according to fmt."); + +static PyObject * +pack(PyObject *self, PyObject *args) +{ + PyObject *s_object, *fmt, *newargs, *result; + Py_ssize_t n = PyTuple_GET_SIZE(args); + + if (n == 0) { + PyErr_SetString(PyExc_TypeError, "missing format argument"); + return NULL; + } + fmt = PyTuple_GET_ITEM(args, 0); + newargs = PyTuple_GetSlice(args, 1, n); + if (newargs == NULL) + return NULL; + + s_object = cache_struct(fmt); + if (s_object == NULL) { + Py_DECREF(newargs); + return NULL; + } + result = s_pack(s_object, newargs); + Py_DECREF(newargs); + Py_DECREF(s_object); + return result; +} + +PyDoc_STRVAR(pack_into_doc, +"Pack the values v1, v2, ... according to fmt.\n\ +Write the packed bytes into the writable buffer buf starting at offset."); + +static PyObject * +pack_into(PyObject *self, PyObject *args) +{ + PyObject *s_object, *fmt, *newargs, *result; + Py_ssize_t n = PyTuple_GET_SIZE(args); + + if (n == 0) { + PyErr_SetString(PyExc_TypeError, "missing format argument"); + return NULL; + } + fmt = PyTuple_GET_ITEM(args, 0); + newargs = PyTuple_GetSlice(args, 1, n); + if (newargs == NULL) + return NULL; + + s_object = cache_struct(fmt); + if (s_object == NULL) { + Py_DECREF(newargs); + return NULL; + } + result = s_pack_into(s_object, newargs); + Py_DECREF(newargs); + Py_DECREF(s_object); + return result; +} + +PyDoc_STRVAR(unpack_doc, +"Unpack the string containing packed C structure data, according to fmt.\n\ +Requires len(string) == calcsize(fmt)."); + +static PyObject * +unpack(PyObject *self, PyObject *args) +{ + PyObject *s_object, *fmt, *inputstr, *result; + + if (!PyArg_UnpackTuple(args, "unpack", 2, 2, &fmt, &inputstr)) + return NULL; + + s_object = cache_struct(fmt); + if (s_object == NULL) + return NULL; + result = s_unpack(s_object, inputstr); + Py_DECREF(s_object); + return result; +} + +PyDoc_STRVAR(unpack_from_doc, +"Unpack the buffer, containing packed C structure data, according to\n\ +fmt, starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt)."); + +static PyObject * +unpack_from(PyObject *self, PyObject *args, PyObject *kwds) +{ + PyObject *s_object, *fmt, *newargs, *result; + Py_ssize_t n = PyTuple_GET_SIZE(args); + + if (n == 0) { + PyErr_SetString(PyExc_TypeError, "missing format argument"); + return NULL; + } + fmt = PyTuple_GET_ITEM(args, 0); + newargs = PyTuple_GetSlice(args, 1, n); + if (newargs == NULL) + return NULL; + + s_object = cache_struct(fmt); + if (s_object == NULL) { + Py_DECREF(newargs); + return NULL; + } + result = s_unpack_from(s_object, newargs, kwds); + Py_DECREF(newargs); + Py_DECREF(s_object); + return result; +} + +static struct PyMethodDef module_functions[] = { + {"_clearcache", (PyCFunction)clearcache, METH_NOARGS, clearcache_doc}, + {"calcsize", calcsize, METH_O, calcsize_doc}, + {"pack", pack, METH_VARARGS, pack_doc}, + {"pack_into", pack_into, METH_VARARGS, pack_into_doc}, + {"unpack", unpack, METH_VARARGS, unpack_doc}, + {"unpack_from", (PyCFunction)unpack_from, + METH_VARARGS|METH_KEYWORDS, unpack_from_doc}, + {NULL, NULL} /* sentinel */ +}; + + /* Module initialization */ +PyDoc_STRVAR(module_doc, +"Functions to convert between Python values and C structs.\n\ +Python strings are used to hold the data representing the C struct\n\ +and also as format strings to describe the layout of data in the C struct.\n\ +\n\ +The optional first format char indicates byte order, size and alignment:\n\ + @: native order, size & alignment (default)\n\ + =: native order, std. size & alignment\n\ + <: little-endian, std. size & alignment\n\ + >: big-endian, std. size & alignment\n\ + !: same as >\n\ +\n\ +The remaining chars indicate types of args and must match exactly;\n\ +these can be preceded by a decimal repeat count:\n\ + x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\ + h:short; H:unsigned short; i:int; I:unsigned int;\n\ + l:long; L:unsigned long; f:float; d:double.\n\ +Special cases (preceding decimal count indicates length):\n\ + s:string (array of char); p: pascal string (with count byte).\n\ +Special case (only available in native format):\n\ + P:an integer type that is wide enough to hold a pointer.\n\ +Special case (not in native mode unless 'long long' in platform C):\n\ + q:long long; Q:unsigned long long\n\ +Whitespace between formats is ignored.\n\ +\n\ +The variable struct.error is an exception raised on errors.\n"); + PyMODINIT_FUNC init_struct(void) { - PyObject *m = Py_InitModule("_struct", NULL); + PyObject *ver, *m; + + ver = PyString_FromString("0.2"); + if (ver == NULL) + return; + + m = Py_InitModule3("_struct", module_functions, module_doc); if (m == NULL) return; @@ -1947,6 +2178,8 @@ Py_INCREF((PyObject*)&PyStructType); PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType); + PyModule_AddObject(m, "__version__", ver); + PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1); #ifdef PY_STRUCT_OVERFLOW_MASKING PyModule_AddIntConstant(m, "_PY_STRUCT_OVERFLOW_MASKING", 1); Modified: python/branches/py3k/Modules/_tkinter.c ============================================================================== --- python/branches/py3k/Modules/_tkinter.c (original) +++ python/branches/py3k/Modules/_tkinter.c Fri Jan 4 04:06:10 2008 @@ -898,10 +898,12 @@ /* This #ifdef assumes that Tcl uses UCS-2. See TCL_UTF_MAX test above. */ #if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX == 3 - Tcl_UniChar *outbuf; + Tcl_UniChar *outbuf = NULL; Py_ssize_t i; - assert(size < size * sizeof(Tcl_UniChar)); - outbuf = (Tcl_UniChar*)ckalloc(size * sizeof(Tcl_UniChar)); + size_t allocsize = ((size_t)size) * sizeof(Tcl_UniChar); + if (allocsize >= size) + outbuf = (Tcl_UniChar*)ckalloc(allocsize); + /* Else overflow occurred, and we take the next exit */ if (!outbuf) { PyErr_NoMemory(); return NULL; Modified: python/branches/py3k/Modules/mathmodule.c ============================================================================== --- python/branches/py3k/Modules/mathmodule.c (original) +++ python/branches/py3k/Modules/mathmodule.c Fri Jan 4 04:06:10 2008 @@ -133,14 +133,16 @@ "cos(x)\n\nReturn the cosine of x (measured in radians).") FUNC1(cosh, cosh, "cosh(x)\n\nReturn the hyperbolic cosine of x.") -#if defined(MS_WINDOWS) || defined(HAVE_COPYSIGN) + #ifdef MS_WINDOWS -FUNC2(copysign, _copysign, -#else -FUNC2(copysign, copysign, +# define copysign _copysign +# define HAVE_COPYSIGN 1 #endif - "copysign(x,y)\n\nReturn x with the sign of y."); +#ifdef HAVE_COPYSIGN +FUNC2(copysign, copysign, + "copysign(x,y)\n\nReturn x with the sign of y."); #endif + FUNC1(exp, exp, "exp(x)\n\nReturn e raised to the power of x.") FUNC1(fabs, fabs, @@ -383,7 +385,7 @@ {"atan", math_atan, METH_O, math_atan_doc}, {"atan2", math_atan2, METH_VARARGS, math_atan2_doc}, {"ceil", math_ceil, METH_O, math_ceil_doc}, -#if defined(MS_WINDOWS) || defined(HAVE_COPYSIGN) +#ifdef HAVE_COPYSIGN {"copysign", math_copysign, METH_VARARGS, math_copysign_doc}, #endif {"cos", math_cos, METH_O, math_cos_doc}, Modified: python/branches/py3k/Objects/longobject.c ============================================================================== --- python/branches/py3k/Objects/longobject.c (original) +++ python/branches/py3k/Objects/longobject.c Fri Jan 4 04:06:10 2008 @@ -254,6 +254,9 @@ "cannot convert float infinity to int"); return NULL; } + if (Py_IS_NAN(dval)) { + return PyLong_FromLong(0L); + } if (dval < 0.0) { neg = 1; dval = -dval; From python-3000-checkins at python.org Fri Jan 4 04:08:34 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Fri, 4 Jan 2008 04:08:34 +0100 (CET) Subject: [Python-3000-checkins] r59703 - in python/branches/py3k: Doc/whatsnew/2.6.rst Lib/struct.py Message-ID: <20080104030834.139491E4006@bag.python.org> Author: christian.heimes Date: Fri Jan 4 04:08:33 2008 New Revision: 59703 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/whatsnew/2.6.rst python/branches/py3k/Lib/struct.py Log: Merged revisions 59696-59702 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r59696 | amaury.forgeotdarc | 2008-01-04 03:04:15 +0100 (Fri, 04 Jan 2008) | 11 lines Partial port of r59682 from py3k. On Windows, when import fails to load a dll module, the message says "error code 193" instead of a more informative text. It turns out that FormatMessage needs additional parameters for some error codes. For example: 193 means "%1 is not a valid Win32 application". Since it is impossible to know which parameter to pass, we use FORMAT_MESSAGE_IGNORE_INSERTS to get the raw message, which is still better than the number. ........ r59698 | andrew.kuchling | 2008-01-04 03:26:00 +0100 (Fri, 04 Jan 2008) | 1 line Typo fix ........ r59699 | andrew.kuchling | 2008-01-04 03:31:40 +0100 (Fri, 04 Jan 2008) | 1 line Add math items; other edits ........ r59700 | christian.heimes | 2008-01-04 03:46:19 +0100 (Fri, 04 Jan 2008) | 1 line Fixed refleak tests for _struct changes ........ r59701 | christian.heimes | 2008-01-04 03:54:42 +0100 (Fri, 04 Jan 2008) | 1 line Added _struct._clearcache() for regression tests ........ Modified: python/branches/py3k/Doc/whatsnew/2.6.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/2.6.rst (original) +++ python/branches/py3k/Doc/whatsnew/2.6.rst Fri Jan 4 04:08:33 2008 @@ -483,6 +483,32 @@ XXX +How to identify a file object? + +ABCs are a collection of classes describing various interfaces. +Classes can derive from an ABC to indicate they support that ABC's +interface. Concrete classes should obey the semantics specified by +an ABC, but Python can't check this; it's up to the implementor. + +A metaclass lets you declare that an existing class or type +derives from a particular ABC. You can even + +class AppendableSequence: + __metaclass__ = ABCMeta + +AppendableSequence.register(list) +assert issubclass(list, AppendableSequence) +assert isinstance([], AppendableSequence) + + at abstractmethod decorator -- you can't instantiate classes w/ +an abstract method. + + at abstractproperty decorator + at abstractproperty +def readonly(self): + return self._x + + .. seealso:: :pep:`3119` - Introducing Abstract Base Classes @@ -554,12 +580,22 @@ * More floating-point features were also added. The :func:`float` function will now turn the strings ``+nan`` and ``-nan`` into the corresponding - IEEE 754 Not a Number values, and ``+inf`` and ``-inf`` into + IEEE 754 Not A Number values, and ``+inf`` and ``-inf`` into positive or negative infinity. This works on any platform with IEEE 754 semantics. (Contributed by Christian Heimes.) .. Patch 1635. + Other functions in the :mod:`math` module, :func:`isinf` and + :func:`isnan`, return true if their floating-point argument is + infinite or Not A Number. + .. Patch 1640 + The ``math.copysign(x, y)`` function + copies the sign bit of an IEEE 754 number, returning the absolute + value of *x* combined with the sign bit of *y*. For example, + ``math.copysign(1, -0.0)`` returns -1.0. (Contributed by Christian + Heimes.) + * Changes to the :class:`Exception` interface as dictated by :pep:`352` continue to be made. For 2.6, the :attr:`message` attribute is being deprecated in favor of the @@ -612,6 +648,10 @@ Optimizations ------------- +* All of the functions in the :mod:`struct` module have been rewritten in + C, thanks to work at the Need For Speed sprint. + (Contributed by Raymond Hettinger.) + * Internally, a bit is now set in type objects to indicate some of the standard built-in types. This speeds up checking if an object is a subclass of one of these types. (Contributed by Neal Norwitz.) @@ -1074,12 +1114,13 @@ .. Issue 1635 -* Some macros were renamed. :cmacro:`Py_Size()` became :cmacro:`Py_SIZE()`, +* Some macros were renamed to make it clearer that they are macros, + not functions. :cmacro:`Py_Size()` became :cmacro:`Py_SIZE()`, :cmacro:`Py_Type()` became :cmacro:`Py_TYPE()`, and :cmacro:`Py_Refcnt()` became :cmacro:`Py_REFCNT()`. Macros for backward compatibility are still available for Python 2.6. - .. Issue 1629: XXX why was this done? + .. Issue 1629 .. ====================================================================== Modified: python/branches/py3k/Lib/struct.py ============================================================================== --- python/branches/py3k/Lib/struct.py (original) +++ python/branches/py3k/Lib/struct.py Fri Jan 4 04:08:33 2008 @@ -1,109 +1,2 @@ -""" -Functions to convert between Python values and C structs. -Python strings are used to hold the data representing the C struct -and also as format strings to describe the layout of data in the C struct. - -The optional first format char indicates byte order, size and alignment: - @: native order, size & alignment (default) - =: native order, std. size & alignment - <: little-endian, std. size & alignment - >: big-endian, std. size & alignment - !: same as > - -The remaining chars indicate types of args and must match exactly; -these can be preceded by a decimal repeat count: - x: pad byte (no data); c:char; b:signed byte; B:unsigned byte; - h:short; H:unsigned short; i:int; I:unsigned int; - l:long; L:unsigned long; f:float; d:double. -Special cases (preceding decimal count indicates length): - s:string (array of char); p: pascal string (with count byte). -Special case (only available in native format): - P:an integer type that is wide enough to hold a pointer. -Special case (not in native mode unless 'long long' in platform C): - q:long long; Q:unsigned long long -Whitespace between formats is ignored. - -The variable struct.error is an exception raised on errors. -""" - -__version__ = '3.0' - - -from _struct import Struct as _Struct, error - -class Struct(_Struct): - def __init__(self, fmt): - if isinstance(fmt, str): - fmt = bytes(fmt, 'ascii') - elif isinstance(fmt, buffer): - fmt = bytes(fmt) - _Struct.__init__(self, fmt) - -_MAXCACHE = 100 -_cache = {} - -def _compile(fmt): - # Internal: compile struct pattern - if len(_cache) >= _MAXCACHE: - _cache.clear() - s = Struct(fmt) - _cache[fmt] = s - return s - -def calcsize(fmt): - """ - Return size of C struct described by format string fmt. - See struct.__doc__ for more on format strings. - """ - try: - o = _cache[fmt] - except KeyError: - o = _compile(fmt) - return o.size - -def pack(fmt, *args): - """ - Return string containing values v1, v2, ... packed according to fmt. - See struct.__doc__ for more on format strings. - """ - try: - o = _cache[fmt] - except KeyError: - o = _compile(fmt) - return bytes(o.pack(*args)) - -def pack_into(fmt, buf, offset, *args): - """ - Pack the values v1, v2, ... according to fmt, write - the packed bytes into the writable buffer buf starting at offset. - See struct.__doc__ for more on format strings. - """ - try: - o = _cache[fmt] - except KeyError: - o = _compile(fmt) - o.pack_into(buf, offset, *args) - -def unpack(fmt, s): - """ - Unpack the string, containing packed C structure data, according - to fmt. Requires len(string)==calcsize(fmt). - See struct.__doc__ for more on format strings. - """ - try: - o = _cache[fmt] - except KeyError: - o = _compile(fmt) - return o.unpack(s) - -def unpack_from(fmt, buf, offset=0): - """ - Unpack the buffer, containing packed C structure data, according to - fmt starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt). - See struct.__doc__ for more on format strings. - """ - try: - o = _cache[fmt] - except KeyError: - o = _compile(fmt) - return o.unpack_from(buf, offset) +from _struct import * +from _struct import _clearcache From python-3000-checkins at python.org Fri Jan 4 04:22:53 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Fri, 4 Jan 2008 04:22:53 +0100 (CET) Subject: [Python-3000-checkins] r59705 - python/branches/py3k/Lib/test/test_long.py Message-ID: <20080104032253.84DAC1E4006@bag.python.org> Author: christian.heimes Date: Fri Jan 4 04:22:53 2008 New Revision: 59705 Modified: python/branches/py3k/Lib/test/test_long.py Log: Fixed test_long Modified: python/branches/py3k/Lib/test/test_long.py ============================================================================== --- python/branches/py3k/Lib/test/test_long.py (original) +++ python/branches/py3k/Lib/test/test_long.py Fri Jan 4 04:22:53 2008 @@ -538,8 +538,8 @@ self.assertRaises(ValueError, format, 3, "s") def test_nan_inf(self): - self.assertRaises(OverflowError, long, float('inf')) - self.assertEqual(long(float('nan')), 0L) + self.assertRaises(OverflowError, int, float('inf')) + self.assertEqual(int(float('nan')), 0) def test_main(): test_support.run_unittest(LongTest) From python-3000-checkins at python.org Fri Jan 4 13:57:11 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Fri, 4 Jan 2008 13:57:11 +0100 (CET) Subject: [Python-3000-checkins] r59708 - python/branches/py3k/PC/VS7.1/pythoncore.vcproj Message-ID: <20080104125711.5E4121E400E@bag.python.org> Author: christian.heimes Date: Fri Jan 4 13:57:11 2008 New Revision: 59708 Modified: python/branches/py3k/PC/VS7.1/pythoncore.vcproj Log: Fixed #1733: Maybe PC/VS7.1/pythoncore.vcproj is missing Modules/md5module.c Modified: python/branches/py3k/PC/VS7.1/pythoncore.vcproj ============================================================================== --- python/branches/py3k/PC/VS7.1/pythoncore.vcproj (original) +++ python/branches/py3k/PC/VS7.1/pythoncore.vcproj Fri Jan 4 13:57:11 2008 @@ -625,6 +625,9 @@ + + From python-3000-checkins at python.org Fri Jan 4 14:33:01 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Fri, 4 Jan 2008 14:33:01 +0100 (CET) Subject: [Python-3000-checkins] r59711 - in python/branches/py3k: Include/abstract.h Modules/errnomodule.c Modules/selectmodule.c Modules/socketmodule.h Objects/longobject.c PC/msvcrtmodule.c Message-ID: <20080104133301.045E91E400E@bag.python.org> Author: christian.heimes Date: Fri Jan 4 14:33:00 2008 New Revision: 59711 Modified: python/branches/py3k/Include/abstract.h python/branches/py3k/Modules/errnomodule.c python/branches/py3k/Modules/selectmodule.c python/branches/py3k/Modules/socketmodule.h python/branches/py3k/Objects/longobject.c python/branches/py3k/PC/msvcrtmodule.c Log: Some VS 6.0 compatibility fixes from Hirokazu Yamamoto which are also useful for later versions of MSVC. VS6 claims that fortran is a reserved word Modified: python/branches/py3k/Include/abstract.h ============================================================================== --- python/branches/py3k/Include/abstract.h (original) +++ python/branches/py3k/Include/abstract.h Fri Jan 4 14:33:00 2008 @@ -570,11 +570,11 @@ error (i.e. the object does not have a buffer interface or it is not working). - If fortran is 'F', then if the object is multi-dimensional, + If fort is 'F', then if the object is multi-dimensional, then the data will be copied into the array in Fortran-style (first dimension varies the fastest). If - fortran is 'C', then the data will be copied into the array - in C-style (last dimension varies the fastest). If fortran + fort is 'C', then the data will be copied into the array + in C-style (last dimension varies the fastest). If fort is 'A', then it does not matter and the copy will be made in whatever way is more efficient. @@ -585,7 +585,7 @@ /* Copy the data from the src buffer to the buffer of destination */ - PyAPI_FUNC(int) PyBuffer_IsContiguous(Py_buffer *view, char fortran); + PyAPI_FUNC(int) PyBuffer_IsContiguous(Py_buffer *view, char fort); PyAPI_FUNC(void) PyBuffer_FillContiguousStrides(int ndims, @@ -595,7 +595,7 @@ char fort); /* Fill the strides array with byte-strides of a contiguous - (Fortran-style if fortran is 'F' or C-style otherwise) + (Fortran-style if fort is 'F' or C-style otherwise) array of the given shape with the given number of bytes per element. */ Modified: python/branches/py3k/Modules/errnomodule.c ============================================================================== --- python/branches/py3k/Modules/errnomodule.c (original) +++ python/branches/py3k/Modules/errnomodule.c Fri Jan 4 14:33:00 2008 @@ -5,6 +5,7 @@ /* Windows socket errors (WSA*) */ #ifdef MS_WINDOWS +#define WIN32_LEAN_AND_MEAN #include #endif Modified: python/branches/py3k/Modules/selectmodule.c ============================================================================== --- python/branches/py3k/Modules/selectmodule.c (original) +++ python/branches/py3k/Modules/selectmodule.c Fri Jan 4 14:33:00 2008 @@ -44,6 +44,7 @@ #endif #ifdef MS_WINDOWS +# define WIN32_LEAN_AND_MEAN # include #else # define SOCKET int Modified: python/branches/py3k/Modules/socketmodule.h ============================================================================== --- python/branches/py3k/Modules/socketmodule.h (original) +++ python/branches/py3k/Modules/socketmodule.h Fri Jan 4 14:33:00 2008 @@ -22,6 +22,7 @@ # define HAVE_GETNAMEINFO # define ENABLE_IPV6 #else +# define WIN32_LEAN_AND_MEAN # include #endif #endif Modified: python/branches/py3k/Objects/longobject.c ============================================================================== --- python/branches/py3k/Objects/longobject.c (original) +++ python/branches/py3k/Objects/longobject.c Fri Jan 4 14:33:00 2008 @@ -3530,7 +3530,7 @@ static PyObject * long_getN(PyLongObject *v, void *context) { - return PyLong_FromLong((intptr_t)context); + return PyLong_FromLong((Py_intptr_t)context); } static PyObject * Modified: python/branches/py3k/PC/msvcrtmodule.c ============================================================================== --- python/branches/py3k/PC/msvcrtmodule.c (original) +++ python/branches/py3k/PC/msvcrtmodule.c Fri Jan 4 14:33:00 2008 @@ -145,6 +145,7 @@ return PyString_FromStringAndSize(s, 1); } +#if _MSC_VER >= 1300 static PyObject * msvcrt_getwch(PyObject *self, PyObject *args) { @@ -160,6 +161,7 @@ u[0] = ch; return PyUnicode_FromUnicode(u, 1); } +#endif static PyObject * msvcrt_getche(PyObject *self, PyObject *args) @@ -177,6 +179,7 @@ return PyString_FromStringAndSize(s, 1); } +#if _MSC_VER >= 1300 static PyObject * msvcrt_getwche(PyObject *self, PyObject *args) { @@ -192,6 +195,7 @@ s[0] = ch; return PyUnicode_FromUnicode(s, 1); } +#endif static PyObject * msvcrt_putch(PyObject *self, PyObject *args) @@ -207,6 +211,7 @@ } +#if _MSC_VER >= 1300 static PyObject * msvcrt_putwch(PyObject *self, PyObject *args) { @@ -225,6 +230,7 @@ Py_RETURN_NONE; } +#endif static PyObject * msvcrt_ungetch(PyObject *self, PyObject *args) @@ -240,6 +246,7 @@ return Py_None; } +#if _MSC_VER >= 1300 static PyObject * msvcrt_ungetwch(PyObject *self, PyObject *args) { @@ -253,6 +260,7 @@ Py_INCREF(Py_None); return Py_None; } +#endif static void insertint(PyObject *d, char *name, int value) @@ -341,10 +349,12 @@ {"CrtSetReportMode", msvcrt_setreportmode, METH_VARARGS}, {"set_error_mode", msvcrt_seterrormode, METH_VARARGS}, #endif +#if _MSC_VER >= 1300 {"getwch", msvcrt_getwch, METH_VARARGS}, {"getwche", msvcrt_getwche, METH_VARARGS}, {"putwch", msvcrt_putwch, METH_VARARGS}, {"ungetwch", msvcrt_ungetwch, METH_VARARGS}, +#endif {NULL, NULL} }; From python-3000-checkins at python.org Fri Jan 4 16:35:06 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Fri, 4 Jan 2008 16:35:06 +0100 (CET) Subject: [Python-3000-checkins] r59720 - python/branches/py3k/PC/VC6/_msi.dsp python/branches/py3k/PC/VC6/build_ssl.py python/branches/py3k/PC/VC6/pcbuild.dsw python/branches/py3k/PC/VC6/python.dsp python/branches/py3k/PC/VC6/pythoncore.dsp python/branches/py3k/PC/VC6/readme.txt Message-ID: <20080104153506.C9A3D1E4010@bag.python.org> Author: christian.heimes Date: Fri Jan 4 16:35:04 2008 New Revision: 59720 Added: python/branches/py3k/PC/VC6/_msi.dsp (contents, props changed) Modified: python/branches/py3k/PC/VC6/build_ssl.py python/branches/py3k/PC/VC6/pcbuild.dsw python/branches/py3k/PC/VC6/python.dsp python/branches/py3k/PC/VC6/pythoncore.dsp python/branches/py3k/PC/VC6/readme.txt Log: And here is the rest of Hirokazu Yamamoto's patch for VS6.0 support. Thanks Hiro! (This time, it's the correct branch :) Added: python/branches/py3k/PC/VC6/_msi.dsp ============================================================================== --- (empty file) +++ python/branches/py3k/PC/VC6/_msi.dsp Fri Jan 4 16:35:04 2008 @@ -0,0 +1,99 @@ +# Microsoft Developer Studio Project File - Name="_msi" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=_msi - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "_msi.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "_msi.mak" CFG="_msi - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "_msi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "_msi - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "_msi" +# PROP Scc_LocalPath ".." +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "_msi - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "." +# PROP Intermediate_Dir "x86-temp-release\_msi" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +F90=df.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\..\Include" /I ".." /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib fci.lib msi.lib rpcrt4.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib fci.lib msi.lib rpcrt4.lib /nologo /base:"0x1d1a0000" /subsystem:windows /dll /debug /machine:I386 /out:"./_msi.pyd" +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "_msi - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "x86-temp-debug\_msi" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +F90=df.exe +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\Include" /I ".." /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib fci.lib msi.lib rpcrt4.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib fci.lib msi.lib rpcrt4.lib /nologo /base:"0x1d1a0000" /subsystem:windows /dll /debug /machine:I386 /out:"./_msi_d.pyd" /pdbtype:sept +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "_msi - Win32 Release" +# Name "_msi - Win32 Debug" +# Begin Source File + +SOURCE=..\..\PC\_msi.c +# End Source File +# End Target +# End Project Modified: python/branches/py3k/PC/VC6/build_ssl.py ============================================================================== --- python/branches/py3k/PC/VC6/build_ssl.py (original) +++ python/branches/py3k/PC/VC6/build_ssl.py Fri Jan 4 16:35:04 2008 @@ -8,7 +8,7 @@ # directory. It is likely you will already find the zlib library and # any other external packages there. # * Install ActivePerl and ensure it is somewhere on your path. -# * Run this script from the PCBuild directory. +# * Run this script from the PC/VC6 directory. # # it should configure and build SSL, then build the ssl Python extension # without intervention. Modified: python/branches/py3k/PC/VC6/pcbuild.dsw ============================================================================== --- python/branches/py3k/PC/VC6/pcbuild.dsw (original) +++ python/branches/py3k/PC/VC6/pcbuild.dsw Fri Jan 4 16:35:04 2008 @@ -57,6 +57,21 @@ ############################################################################### +Project: "_msi"=".\_msi.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name pythoncore + End Project Dependency +}}} + +############################################################################### + Project: "_socket"=".\_socket.dsp" - Package Owner=<4> Package=<5> @@ -288,3 +303,4 @@ ############################################################################### + Modified: python/branches/py3k/PC/VC6/python.dsp ============================================================================== --- python/branches/py3k/PC/VC6/python.dsp (original) +++ python/branches/py3k/PC/VC6/python.dsp Fri Jan 4 16:35:04 2008 @@ -77,6 +77,11 @@ # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept # ADD LINK32 odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /base:"0x1d000000" /subsystem:console /debug /machine:I386 /out:"./python_d.exe" /pdbtype:sept # SUBTRACT LINK32 /pdb:none +# Begin Special Build Tool +SOURCE="$(InputPath)" +PostBuild_Desc=Changing stack size... +PostBuild_Cmds=editbin /STACK:0x200000 python_d.exe +# End Special Build Tool !ENDIF Modified: python/branches/py3k/PC/VC6/pythoncore.dsp ============================================================================== --- python/branches/py3k/PC/VC6/pythoncore.dsp (original) +++ python/branches/py3k/PC/VC6/pythoncore.dsp Fri Jan 4 16:35:04 2008 @@ -54,7 +54,7 @@ # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 -# ADD LINK32 largeint.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x1e000000" /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"libc" /out:"./python26.dll" +# ADD LINK32 largeint.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x1e000000" /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"libc" /out:"./python30.dll" # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "pythoncore - Win32 Debug" @@ -82,7 +82,7 @@ # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 largeint.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x1e000000" /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"libc" /out:"./python26_d.dll" /pdbtype:sept +# ADD LINK32 largeint.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x1e000000" /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"libc" /out:"./python30_d.dll" /pdbtype:sept # SUBTRACT LINK32 /pdb:none !ENDIF @@ -129,6 +129,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Modules\_fileio.c +# End Source File +# Begin Source File + SOURCE=..\..\Modules\_functoolsmodule.c # End Source File # Begin Source File @@ -197,6 +201,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Modules\atexitmodule.c +# End Source File +# Begin Source File + SOURCE=..\..\Modules\audioop.c # End Source File # Begin Source File @@ -217,6 +225,14 @@ # End Source File # Begin Source File +SOURCE=..\..\Objects\bytes_methods.c +# End Source File +# Begin Source File + +SOURCE=..\..\Objects\bytesobject.c +# End Source File +# Begin Source File + SOURCE=..\..\Objects\cellobject.c # End Source File # Begin Source File @@ -245,7 +261,7 @@ # End Source File # Begin Source File -SOURCE=..\..\Modules\collectionsmodule.c +SOURCE=..\..\Modules\_collectionsmodule.c # End Source File # Begin Source File @@ -281,6 +297,14 @@ # End Source File # Begin Source File +SOURCE=..\..\Modules\zlib\gzio.c +# End Source File +# Begin Source File + +SOURCE=..\..\Modules\zlib\infback.c +# End Source File +# Begin Source File + SOURCE=..\..\Objects\descrobject.c # End Source File # Begin Source File @@ -317,6 +341,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Parser\firstsets.c +# End Source File +# Begin Source File + SOURCE=..\..\Objects\floatobject.c # End Source File # Begin Source File @@ -325,6 +353,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Python\formatter_unicode.c +# End Source File +# Begin Source File + SOURCE=..\..\Python\frozen.c # End Source File # Begin Source File @@ -386,11 +418,11 @@ # End Source File # Begin Source File -SOURCE=..\..\Parser\grammar1.c +SOURCE=..\..\Parser\grammar.c # End Source File # Begin Source File -SOURCE=..\..\Modules\imageop.c +SOURCE=..\..\Parser\grammar1.c # End Source File # Begin Source File @@ -451,15 +483,15 @@ # End Source File # Begin Source File -SOURCE=..\..\Modules\md5.c +SOURCE=..\..\Modules\md5module.c # End Source File # Begin Source File -SOURCE=..\..\Modules\md5module.c +SOURCE=..\..\Parser\metagrammar.c # End Source File # Begin Source File -SOURCE=..\..\Parser\metagrammar.c +SOURCE=..\..\Objects\memoryobject.c # End Source File # Begin Source File @@ -547,6 +579,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Python\pystrcmp.c +# End Source File +# Begin Source File + SOURCE=..\..\Python\pystrtod.c # End Source File # Begin Source File @@ -567,10 +603,6 @@ # End Source File # Begin Source File -SOURCE=..\..\Modules\rgbimgmodule.c -# End Source File -# Begin Source File - SOURCE=..\..\Modules\rotatingtree.c # End Source File # Begin Source File @@ -587,7 +619,7 @@ # End Source File # Begin Source File -SOURCE=..\..\Modules\shamodule.c +SOURCE=..\..\Modules\sha1module.c # End Source File # Begin Source File @@ -647,6 +679,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Modules\zlib\uncompr.c +# End Source File +# Begin Source File + SOURCE=..\..\Objects\tupleobject.c # End Source File # Begin Source File Modified: python/branches/py3k/PC/VC6/readme.txt ============================================================================== --- python/branches/py3k/PC/VC6/readme.txt (original) +++ python/branches/py3k/PC/VC6/readme.txt Fri Jan 4 16:35:04 2008 @@ -199,12 +199,10 @@ http://www.activestate.com/Products/ActivePerl/ as this is used by the OpenSSL build process. Complain to them . - The MSVC project simply invokes PCBuild/build_ssl.py to perform + The MSVC project simply invokes PC/VC6/build_ssl.py to perform the build. This Python script locates and builds your OpenSSL installation, then invokes a simple makefile to build the final .pyd. - Win9x users: see "Win9x note" below. - build_ssl.py attempts to catch the most common errors (such as not being able to find OpenSSL sources, or not being able to find a Perl that works with OpenSSL) and give a reasonable error message. @@ -216,30 +214,6 @@ build_ssl.py/MSVC isn't clever enough to clean OpenSSL - you must do this by hand. - Win9x note: If, near the start of the build process, you see - something like - - C:\Code\openssl-0.9.6g>set OPTS=no-asm - Out of environment space - - then you're in trouble, and will probably also see these errors near - the end of the process: - - NMAKE : fatal error U1073: don't know how to make - 'crypto\md5\asm\m5_win32.asm' - Stop. - NMAKE : fatal error U1073: don't know how to make - 'C:\Code\openssl-0.9.6g/out32/libeay32.lib' - Stop. - - You need more environment space. Win9x only has room for 256 bytes - by default, and especially after installing ActivePerl (which fiddles - the PATH envar), you're likely to run out. KB Q230205 - - http://support.microsoft.com/default.aspx?scid=KB;en-us;q230205 - - explains how to edit CONFIG.SYS to cure this. - YOUR OWN EXTENSION DLLs ----------------------- From python-3000-checkins at python.org Sat Jan 5 05:32:23 2008 From: python-3000-checkins at python.org (kurt.kaiser) Date: Sat, 5 Jan 2008 05:32:23 +0100 (CET) Subject: [Python-3000-checkins] r59729 - in python/branches/py3k: Misc/NEWS Python/pythonrun.c Message-ID: <20080105043223.5EC5F1E4008@bag.python.org> Author: kurt.kaiser Date: Sat Jan 5 05:32:22 2008 New Revision: 59729 Modified: python/branches/py3k/Misc/NEWS python/branches/py3k/Python/pythonrun.c Log: Interpreter wasn't displaying the location of a SyntaxError Issue1692 Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Jan 5 05:32:22 2008 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #1692: Interpreter was not displaying location of SyntaxError + - Improve some exception messages when Windows fails to load an extension module. Now we get for example '%1 is not a valid Win32 application' instead of 'error code 193'. Also use Unicode strings to deal with non-English Modified: python/branches/py3k/Python/pythonrun.c ============================================================================== --- python/branches/py3k/Python/pythonrun.c (original) +++ python/branches/py3k/Python/pythonrun.c Sat Jan 5 05:32:22 2008 @@ -1103,7 +1103,7 @@ goto finally; if (v == Py_None) *filename = NULL; - else if (! (*filename = PyString_AsString(v))) + else if (! (*filename = PyUnicode_AsString(v))) goto finally; Py_DECREF(v); From python-3000-checkins at python.org Sat Jan 5 17:46:23 2008 From: python-3000-checkins at python.org (guido.van.rossum) Date: Sat, 5 Jan 2008 17:46:23 +0100 (CET) Subject: [Python-3000-checkins] r59737 - python/branches/py3k/Lib/plat-mac/plistlib.py Message-ID: <20080105164623.AAA6E1E4009@bag.python.org> Author: guido.van.rossum Date: Sat Jan 5 17:46:23 2008 New Revision: 59737 Modified: python/branches/py3k/Lib/plat-mac/plistlib.py Log: Fix merge glitch. Modified: python/branches/py3k/Lib/plat-mac/plistlib.py ============================================================================== --- python/branches/py3k/Lib/plat-mac/plistlib.py (original) +++ python/branches/py3k/Lib/plat-mac/plistlib.py Sat Jan 5 17:46:23 2008 @@ -242,7 +242,7 @@ self.simpleElement("true") else: self.simpleElement("false") - elif isinstance(value, (int, long)): + elif isinstance(value, int): self.simpleElement("integer", "%d" % value) elif isinstance(value, float): self.simpleElement("real", repr(value)) From python-3000-checkins at python.org Sat Jan 5 20:03:18 2008 From: python-3000-checkins at python.org (kurt.kaiser) Date: Sat, 5 Jan 2008 20:03:18 +0100 (CET) Subject: [Python-3000-checkins] r59740 - python/branches/py3k/Lib/urllib.py Message-ID: <20080105190318.C9C521E400C@bag.python.org> Author: kurt.kaiser Date: Sat Jan 5 20:03:18 2008 New Revision: 59740 Modified: python/branches/py3k/Lib/urllib.py Log: Remove dead code brought in by merge glitch @ r59667 Modified: python/branches/py3k/Lib/urllib.py ============================================================================== --- python/branches/py3k/Lib/urllib.py (original) +++ python/branches/py3k/Lib/urllib.py Sat Jan 5 20:03:18 2008 @@ -402,77 +402,6 @@ """Use HTTPS protocol.""" return self._open_generic_http(self._https_connection, url, data) - import httplib - user_passwd = None - proxy_passwd = None - if isinstance(url, str): - host, selector = splithost(url) - if host: - user_passwd, host = splituser(host) - host = unquote(host) - realhost = host - else: - host, selector = url - # here, we determine, whether the proxy contains authorization information - proxy_passwd, host = splituser(host) - urltype, rest = splittype(selector) - url = rest - user_passwd = None - if urltype.lower() != 'https': - realhost = None - else: - realhost, rest = splithost(rest) - if realhost: - user_passwd, realhost = splituser(realhost) - if user_passwd: - selector = "%s://%s%s" % (urltype, realhost, rest) - #print "proxy via https:", host, selector - if not host: raise IOError('https error', 'no host given') - if proxy_passwd: - import base64 - proxy_auth = base64.b64encode(proxy_passwd).strip() - else: - proxy_auth = None - if user_passwd: - import base64 - auth = base64.b64encode(user_passwd).strip() - else: - auth = None - h = httplib.HTTPS(host, 0, - key_file=self.key_file, - cert_file=self.cert_file) - if data is not None: - h.putrequest('POST', selector) - h.putheader('Content-Type', - 'application/x-www-form-urlencoded') - h.putheader('Content-Length', '%d' % len(data)) - else: - h.putrequest('GET', selector) - if proxy_auth: h.putheader('Proxy-Authorization', 'Basic %s' % proxy_auth) - if auth: h.putheader('Authorization', 'Basic %s' % auth) - if realhost: h.putheader('Host', realhost) - for args in self.addheaders: h.putheader(*args) - h.endheaders() - if data is not None: - h.send(data) - errcode, errmsg, headers = h.getreply() - fp = h.getfile() - if errcode == -1: - if fp: fp.close() - # something went wrong with the HTTP status line - raise IOError('http protocol error', 0, - 'got a bad status line', None) - # According to RFC 2616, "2xx" code indicates that the client's - # request was successfully received, understood, and accepted. - if (200 <= errcode < 300): - return addinfourl(fp, headers, "https:" + url) - else: - if data is None: - return self.http_error(url, fp, errcode, errmsg, headers) - else: - return self.http_error(url, fp, errcode, errmsg, headers, - data) - def open_file(self, url): """Use local file or FTP depending on form of URL.""" if not isinstance(url, str): From python-3000-checkins at python.org Sat Jan 5 20:25:53 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sat, 5 Jan 2008 20:25:53 +0100 (CET) Subject: [Python-3000-checkins] r59741 - python/branches/py3k/Doc/library/collections.rst Message-ID: <20080105192553.D044B1E400C@bag.python.org> Author: georg.brandl Date: Sat Jan 5 20:25:53 2008 New Revision: 59741 Modified: python/branches/py3k/Doc/library/collections.rst Log: Typo. Modified: python/branches/py3k/Doc/library/collections.rst ============================================================================== --- python/branches/py3k/Doc/library/collections.rst (original) +++ python/branches/py3k/Doc/library/collections.rst Sat Jan 5 20:25:53 2008 @@ -53,7 +53,7 @@ :class:`collections.Sized` Defines ``__len__()`` ===================================== ======================================== -.. XXX Have not included them all and the notes are imcomplete +.. XXX Have not included them all and the notes are incomplete .. Deliberately did one row wide to get a neater output These ABCs allow us to ask classes or instances if they provide From python-3000-checkins at python.org Sat Jan 5 21:00:56 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sat, 5 Jan 2008 21:00:56 +0100 (CET) Subject: [Python-3000-checkins] r59746 - in python/branches/py3k/Lib: logging/__init__.py logging/config.py logging/handlers.py pdb.py platform.py site.py test/regex_tests.py Message-ID: <20080105200056.1FDF81E400C@bag.python.org> Author: georg.brandl Date: Sat Jan 5 21:00:55 2008 New Revision: 59746 Modified: python/branches/py3k/Lib/logging/__init__.py python/branches/py3k/Lib/logging/config.py python/branches/py3k/Lib/logging/handlers.py python/branches/py3k/Lib/pdb.py python/branches/py3k/Lib/platform.py python/branches/py3k/Lib/site.py python/branches/py3k/Lib/test/regex_tests.py Log: Remove several mentions of old Python versions that don't apply anymore. Modified: python/branches/py3k/Lib/logging/__init__.py ============================================================================== --- python/branches/py3k/Lib/logging/__init__.py (original) +++ python/branches/py3k/Lib/logging/__init__.py Sat Jan 5 21:00:55 2008 @@ -18,9 +18,6 @@ Logging package for Python. Based on PEP 282 and comments thereto in comp.lang.python, and influenced by Apache's log4j system. -Should work under Python versions >= 1.5.2, except that source line -information is not available unless 'sys._getframe()' is. - Copyright (C) 2001-2007 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! Modified: python/branches/py3k/Lib/logging/config.py ============================================================================== --- python/branches/py3k/Lib/logging/config.py (original) +++ python/branches/py3k/Lib/logging/config.py Sat Jan 5 21:00:55 2008 @@ -19,9 +19,6 @@ is based on PEP 282 and comments thereto in comp.lang.python, and influenced by Apache's log4j system. -Should work under Python versions >= 1.5.2, except that source line -information is not available unless 'sys._getframe()' is. - Copyright (C) 2001-2007 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! Modified: python/branches/py3k/Lib/logging/handlers.py ============================================================================== --- python/branches/py3k/Lib/logging/handlers.py (original) +++ python/branches/py3k/Lib/logging/handlers.py Sat Jan 5 21:00:55 2008 @@ -19,9 +19,6 @@ based on PEP 282 and comments thereto in comp.lang.python, and influenced by Apache's log4j system. -Should work under Python versions >= 1.5.2, except that source line -information is not available unless 'sys._getframe()' is. - Copyright (C) 2001-2007 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! Modified: python/branches/py3k/Lib/pdb.py ============================================================================== --- python/branches/py3k/Lib/pdb.py (original) +++ python/branches/py3k/Lib/pdb.py Sat Jan 5 21:00:55 2008 @@ -909,12 +909,7 @@ With a space separated list of breakpoint numbers, clear those breakpoints. Without argument, clear all breaks (but first ask confirmation). With a filename:lineno argument, -clear all breaks at that line in that file. - -Note that the argument is different from previous versions of -the debugger (in python distributions 1.5.1 and before) where -a linenumber was used instead of either filename:lineno or -breakpoint numbers.""", file=self.stdout) +clear all breaks at that line in that file.""", file=self.stdout) def help_tbreak(self): print("""tbreak same arguments as break, but breakpoint is Modified: python/branches/py3k/Lib/platform.py ============================================================================== --- python/branches/py3k/Lib/platform.py (original) +++ python/branches/py3k/Lib/platform.py Sat Jan 5 21:00:55 2008 @@ -12,8 +12,6 @@ # If you find problems, please submit bug reports/patches via the # Python SourceForge Project Page and assign them to "lemburg". # -# Note: Please keep this module compatible to Python 1.5.2. -# # Still needed: # * more support for WinCE # * support for MS-DOS (PythonDX ?) @@ -857,22 +855,6 @@ # Still not working... return default -# os.path.abspath is new in Python 1.5.2: -if not hasattr(os.path,'abspath'): - - def _abspath(path, - - isabs=os.path.isabs,join=os.path.join,getcwd=os.getcwd, - normpath=os.path.normpath): - - if not isabs(path): - path = join(getcwd(), path) - return normpath(path) - -else: - - _abspath = os.path.abspath - def _follow_symlinks(filepath): """ In case filepath is a symlink, follow it until a Modified: python/branches/py3k/Lib/site.py ============================================================================== --- python/branches/py3k/Lib/site.py (original) +++ python/branches/py3k/Lib/site.py Sat Jan 5 21:00:55 2008 @@ -4,12 +4,6 @@ * This module is automatically imported during initialization. * **************************************************************** -In earlier versions of Python (up to 1.5a3), scripts or modules that -needed to use site-specific modules would place ``import site'' -somewhere near the top of their code. Because of the automatic -import, this is no longer necessary (but code that does it still -works). - This will append site-specific paths to the module search path. On Unix (including Mac OSX), it starts with sys.prefix and sys.exec_prefix (if different) and appends Modified: python/branches/py3k/Lib/test/regex_tests.py ============================================================================== --- python/branches/py3k/Lib/test/regex_tests.py (original) +++ python/branches/py3k/Lib/test/regex_tests.py Sat Jan 5 21:00:55 2008 @@ -1,6 +1,4 @@ # Regex test suite and benchmark suite v1.5a2 -# Due to the use of r"aw" strings, this file will -# only work with Python 1.5 or higher. # The 3 possible outcomes for each pattern [SUCCEED, FAIL, SYNTAX_ERROR] = range(3) From python-3000-checkins at python.org Sat Jan 5 21:03:13 2008 From: python-3000-checkins at python.org (jeffrey.yasskin) Date: Sat, 5 Jan 2008 21:03:13 +0100 (CET) Subject: [Python-3000-checkins] r59747 - in python/branches/py3k: Lib/test/test_math.py Modules/mathmodule.c Message-ID: <20080105200313.220231E400C@bag.python.org> Author: jeffrey.yasskin Date: Sat Jan 5 21:03:11 2008 New Revision: 59747 Modified: python/branches/py3k/Lib/test/test_math.py python/branches/py3k/Modules/mathmodule.c Log: Make math.floor and math.ceil return ints instead of floats. Modified: python/branches/py3k/Lib/test/test_math.py ============================================================================== --- python/branches/py3k/Lib/test/test_math.py (original) +++ python/branches/py3k/Lib/test/test_math.py Sat Jan 5 21:03:11 2008 @@ -51,6 +51,7 @@ def testCeil(self): self.assertRaises(TypeError, math.ceil) + self.assertEquals(int, type(math.ceil(0.5))) self.ftest('ceil(0.5)', math.ceil(0.5), 1) self.ftest('ceil(1.0)', math.ceil(1.0), 1) self.ftest('ceil(1.5)', math.ceil(1.5), 2) @@ -103,6 +104,7 @@ def testFloor(self): self.assertRaises(TypeError, math.floor) + self.assertEquals(int, type(math.floor(0.5))) self.ftest('floor(0.5)', math.floor(0.5), 0) self.ftest('floor(1.0)', math.floor(1.0), 1) self.ftest('floor(1.5)', math.floor(1.5), 1) Modified: python/branches/py3k/Modules/mathmodule.c ============================================================================== --- python/branches/py3k/Modules/mathmodule.c (original) +++ python/branches/py3k/Modules/mathmodule.c Sat Jan 5 21:03:11 2008 @@ -48,7 +48,8 @@ } static PyObject * -math_1(PyObject *arg, double (*func) (double)) +math_1_to_whatever(PyObject *arg, double (*func) (double), + PyObject *(*from_double_func) (double)) { double x = PyFloat_AsDouble(arg); if (x == -1.0 && PyErr_Occurred()) @@ -61,7 +62,19 @@ if (errno && is_error(x)) return NULL; else - return PyFloat_FromDouble(x); + return (*from_double_func)(x); +} + +static PyObject * +math_1(PyObject *arg, double (*func) (double)) +{ + return math_1_to_whatever(arg, func, PyFloat_FromDouble); +} + +static PyObject * +math_1_to_int(PyObject *arg, double (*func) (double)) +{ + return math_1_to_whatever(arg, func, PyLong_FromDouble); } static PyObject * @@ -120,13 +133,13 @@ method = _PyType_Lookup(Py_TYPE(number), ceil_str); if (method == NULL) - return math_1(number, ceil); + return math_1_to_int(number, ceil); else return PyObject_CallFunction(method, "O", number); } PyDoc_STRVAR(math_ceil_doc, - "ceil(x)\n\nReturn the ceiling of x as a float.\n" + "ceil(x)\n\nReturn the ceiling of x as an int.\n" "This is the smallest integral value >= x."); FUNC1(cos, cos, @@ -160,13 +173,13 @@ method = _PyType_Lookup(Py_TYPE(number), floor_str); if (method == NULL) - return math_1(number, floor); + return math_1_to_int(number, floor); else return PyObject_CallFunction(method, "O", number); } PyDoc_STRVAR(math_floor_doc, - "floor(x)\n\nReturn the floor of x as a float.\n" + "floor(x)\n\nReturn the floor of x as an int.\n" "This is the largest integral value <= x."); FUNC2(fmod, fmod, From python-3000-checkins at python.org Sat Jan 5 21:11:14 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sat, 5 Jan 2008 21:11:14 +0100 (CET) Subject: [Python-3000-checkins] r59748 - in python/branches/py3k/Doc: c-api/utilities.rst library/collections.rst library/difflib.rst library/functions.rst library/math.rst library/msvcrt.rst library/stdtypes.rst library/sys.rst Message-ID: <20080105201114.471021E400C@bag.python.org> Author: georg.brandl Date: Sat Jan 5 21:11:13 2008 New Revision: 59748 Modified: python/branches/py3k/Doc/c-api/utilities.rst python/branches/py3k/Doc/library/collections.rst python/branches/py3k/Doc/library/difflib.rst python/branches/py3k/Doc/library/functions.rst python/branches/py3k/Doc/library/math.rst python/branches/py3k/Doc/library/msvcrt.rst python/branches/py3k/Doc/library/stdtypes.rst python/branches/py3k/Doc/library/sys.rst Log: Remove versionadded/changed directives merged as an oversight. Modified: python/branches/py3k/Doc/c-api/utilities.rst ============================================================================== --- python/branches/py3k/Doc/c-api/utilities.rst (original) +++ python/branches/py3k/Doc/c-api/utilities.rst Sat Jan 5 21:11:13 2008 @@ -197,9 +197,6 @@ to find out. Starting with Python 2.4, a failing import of a module no longer leaves the module in ``sys.modules``. - .. versionchanged:: 2.6 - always use absolute imports - .. index:: single: modules (in module sys) @@ -216,8 +213,6 @@ unless the the lock is hold. In the latter case the function raises an ImportError. - .. versionadded:: 2.6 - .. cfunction:: PyObject* PyImport_ImportModuleEx(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist) @@ -236,9 +231,8 @@ Failing imports remove incomplete module objects, like with :cfunc:`PyImport_ImportModule`. - .. versionchanged:: 2.6 - The function is an alias for `cfunc:PyImport_ImportModuleLevel` with - -1 as level, meaning relative import. + The function is an alias for `cfunc:PyImport_ImportModuleLevel` with -1 as + *level*, meaning relative import. .. cfunction:: PyObject* PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level) @@ -252,18 +246,14 @@ the return value when a submodule of a package was requested is normally the top-level package, unless a non-empty *fromlist* was given. - ..versionadded:: 2.5 - .. cfunction:: PyObject* PyImport_Import(PyObject *name) - This is a higher-level interface that calls the current "import hook function". - It invokes the :func:`__import__` function from the ``__builtins__`` of the - current globals. This means that the import is done using whatever import hooks - are installed in the current environment. - - .. versionchanged:: 2.6 - always use absolute imports + This is a higher-level interface that calls the current "import hook + function" (with an explicit *level* of 0, meaning absolute import). It + invokes the :func:`__import__` function from the ``__builtins__`` of the + current globals. This means that the import is done using whatever import + hooks are installed in the current environment. .. cfunction:: PyObject* PyImport_ReloadModule(PyObject *m) @@ -1096,16 +1086,12 @@ Case insensitive comparsion of strings. The functions works almost identical to :cfunc:`strcmp` except that it ignores the case. - .. versionadded:: 2.6 - .. cfunction:: char * PyOS_strnicmp(char *s1, char *s2, Py_ssize_t size) Case insensitive comparsion of strings. The functions works almost identical to :cfunc:`strncmp` except that it ignores the case. - .. versionadded:: 2.6 - .. _reflection: Modified: python/branches/py3k/Doc/library/collections.rst ============================================================================== --- python/branches/py3k/Doc/library/collections.rst (original) +++ python/branches/py3k/Doc/library/collections.rst Sat Jan 5 21:11:13 2008 @@ -99,8 +99,6 @@ Unix. They are also useful for tracking transactions and other pools of data where only the most recent activity is of interest. - .. versionchanged:: 2.6 - Added *maxlen* parameter. Deque objects support the following methods: Modified: python/branches/py3k/Doc/library/difflib.rst ============================================================================== --- python/branches/py3k/Doc/library/difflib.rst (original) +++ python/branches/py3k/Doc/library/difflib.rst Sat Jan 5 21:11:13 2008 @@ -380,10 +380,6 @@ .. XXX Explain why a dummy is used! - .. versionchanged:: 2.5 - The guarantee that adjacent triples always describe non-adjacent blocks was - implemented. - :: >>> s = SequenceMatcher(None, "abxcd", "abcd") Modified: python/branches/py3k/Doc/library/functions.rst ============================================================================== --- python/branches/py3k/Doc/library/functions.rst (original) +++ python/branches/py3k/Doc/library/functions.rst Sat Jan 5 21:11:13 2008 @@ -921,8 +921,6 @@ ``round(0.5)`` and ``round(-0.5)`` are ``0``, and ``round(1.5)`` is ``2``). Delegates to ``x.__round__(n)``. - .. versionchanged:: 2.6 - .. function:: set([iterable]) :noindex: @@ -1072,8 +1070,6 @@ Return the :class:`Real` value *x* truncated to an :class:`Integral` (usually a long integer). Delegates to ``x.__trunc__()``. - .. versionadded:: 2.6 - .. function:: tuple([iterable]) Modified: python/branches/py3k/Doc/library/math.rst ============================================================================== --- python/branches/py3k/Doc/library/math.rst (original) +++ python/branches/py3k/Doc/library/math.rst Sat Jan 5 21:11:13 2008 @@ -36,8 +36,6 @@ Return *x* with the sign of *y*. ``copysign`` copies the sign bit of an IEEE 754 float, ``copysign(1, -0.0)`` returns *-1.0*. - ..versionadded:: 2.6 - .. function:: fabs(x) @@ -78,8 +76,6 @@ Checks if the float *x* is positive or negative infinite. - ..versionadded:: 2.6 - .. function:: isnan(x) @@ -88,8 +84,6 @@ ``inf / inf`` or any operation involving a NaN, e.g. ``nan * 1``, return a NaN. - ..versionadded:: 2.6 - .. function:: ldexp(x, i) Modified: python/branches/py3k/Doc/library/msvcrt.rst ============================================================================== --- python/branches/py3k/Doc/library/msvcrt.rst (original) +++ python/branches/py3k/Doc/library/msvcrt.rst Sat Jan 5 21:11:13 2008 @@ -103,8 +103,6 @@ Wide char variant of :func:`getch`, returning a Unicode value. - .. versionadded:: 2.6 - .. function:: getche() @@ -116,8 +114,6 @@ Wide char variant of :func:`getche`, returning a Unicode value. - .. versionadded:: 2.6 - .. function:: putch(char) @@ -128,8 +124,6 @@ Wide char variant of :func:`putch`, accepting a Unicode value. - .. versionadded:: 2.6 - .. function:: ungetch(char) @@ -141,8 +135,6 @@ Wide char variant of :func:`ungetch`, accepting a Unicode value. - .. versionadded:: 2.6 - .. _msvcrt-other: Modified: python/branches/py3k/Doc/library/stdtypes.rst ============================================================================== --- python/branches/py3k/Doc/library/stdtypes.rst (original) +++ python/branches/py3k/Doc/library/stdtypes.rst Sat Jan 5 21:11:13 2008 @@ -351,8 +351,6 @@ float also accepts the strings "nan" and "inf" with an optional prefix "+" or "-" for Not a Number (NaN) and positive or negative infinity. - .. versionadded:: 2.6 - .. XXXJH exceptions: overflow (when? what operations?) zerodivision @@ -2017,9 +2015,6 @@ Note that not all file objects are seekable. - .. versionchanged:: 2.6 - Passing float values as offset has been deprecated. - .. method:: file.tell() Modified: python/branches/py3k/Doc/library/sys.rst ============================================================================== --- python/branches/py3k/Doc/library/sys.rst (original) +++ python/branches/py3k/Doc/library/sys.rst Sat Jan 5 21:11:13 2008 @@ -371,8 +371,6 @@ take. It's usually ``2**31 - 1`` on a 32-bit platform and ``2**63 - 1`` on a 64-bit platform. - .. versionadded:: 3.0 - .. data:: maxunicode From python-3000-checkins at python.org Sat Jan 5 21:41:28 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sat, 5 Jan 2008 21:41:28 +0100 (CET) Subject: [Python-3000-checkins] r59751 - in python/branches/py3k/Doc: ACKS.txt Makefile README.txt TODO.txt about.rst bugs.rst c-api/abstract.rst c-api/concrete.rst c-api/exceptions.rst c-api/index.rst c-api/init.rst c-api/intro.rst c-api/memory.rst c-api/newtypes.rst c-api/refcounting.rst c-api/utilities.rst c-api/veryhigh.rst conf.py contents.rst copyright.rst distutils/apiref.rst distutils/builtdist.rst distutils/commandref.rst distutils/configfile.rst distutils/examples.rst distutils/extending.rst distutils/index.rst distutils/introduction.rst distutils/packageindex.rst distutils/setupscript.rst distutils/sourcedist.rst distutils/uploading.rst documenting/fromlatex.rst documenting/index.rst documenting/intro.rst documenting/markup.rst documenting/rest.rst documenting/sphinx.rst documenting/style.rst extending/building.rst extending/embedding.rst extending/extending.rst extending/index.rst extending/newtypes.rst extending/windows.rst howto/advocacy.rst howto/curses.rst howto/doanddont.rst howto/functional.rst howto/index.rst howto/regex.rst howto/sockets.rst howto/unicode.rst howto/urllib2.rst includes/email-dir.py includes/email-mime.py includes/email-simple.py includes/email-unpack.py includes/minidom-example.py includes/setup.py includes/sqlite3/adapter_datetime.py includes/sqlite3/adapter_point_1.py includes/sqlite3/adapter_point_2.py includes/sqlite3/collation_reverse.py includes/sqlite3/complete_statement.py includes/sqlite3/connect_db_1.py includes/sqlite3/connect_db_2.py includes/sqlite3/converter_point.py includes/sqlite3/countcursors.py includes/sqlite3/createdb.py includes/sqlite3/execsql_fetchonerow.py includes/sqlite3/execsql_printall_1.py includes/sqlite3/execute_1.py includes/sqlite3/execute_2.py includes/sqlite3/execute_3.py includes/sqlite3/executemany_1.py includes/sqlite3/executemany_2.py includes/sqlite3/executescript.py includes/sqlite3/insert_more_people.py includes/sqlite3/md5func.py includes/sqlite3/mysumaggr.py includes/sqlite3/parse_colnames.py includes/sqlite3/pysqlite_datetime.py includes/sqlite3/row_factory.py includes/sqlite3/rowclass.py includes/sqlite3/shared_cache.py includes/sqlite3/shortcut_methods.py includes/sqlite3/simple_tableprinter.py includes/sqlite3/text_factory.py includes/test.py includes/tzinfo-examples.py install/index.rst library/__future__.rst library/__main__.rst library/_ast.rst library/_winreg.rst library/abc.rst library/aepack.rst library/aetools.rst library/aetypes.rst library/aifc.rst library/allos.rst library/anydbm.rst library/archiving.rst library/array.rst library/asynchat.rst library/asyncore.rst library/atexit.rst library/audioop.rst library/autogil.rst library/base64.rst library/basehttpserver.rst library/bdb.rst library/binascii.rst library/binhex.rst library/bisect.rst library/bsddb.rst library/builtins.rst library/bz2.rst library/calendar.rst library/carbon.rst library/cgi.rst library/cgihttpserver.rst library/cgitb.rst library/chunk.rst library/cmath.rst library/cmd.rst library/code.rst library/codecs.rst library/codeop.rst library/collections.rst library/colorpicker.rst library/colorsys.rst library/commands.rst library/compileall.rst library/configparser.rst library/constants.rst library/contextlib.rst library/cookie.rst library/cookielib.rst library/copy.rst library/copy_reg.rst library/crypt.rst library/crypto.rst library/csv.rst library/ctypes.rst library/curses.ascii.rst library/curses.panel.rst library/curses.rst library/custominterp.rst library/datatypes.rst library/datetime.rst library/dbhash.rst library/dbm.rst library/debug.rst library/decimal.rst library/development.rst library/difflib.rst library/dircache.rst library/dis.rst library/distutils.rst library/dl.rst library/doctest.rst library/docxmlrpcserver.rst library/dumbdbm.rst library/dummy_thread.rst library/dummy_threading.rst library/easydialogs.rst library/email-examples.rst library/email.charset.rst library/email.encoders.rst library/email.errors.rst library/email.generator.rst library/email.header.rst library/email.iterators.rst library/email.message.rst library/email.mime.rst library/email.parser.rst library/email.rst library/email.util.rst library/errno.rst library/exceptions.rst library/fcntl.rst library/filecmp.rst library/fileformats.rst library/fileinput.rst library/filesys.rst library/fnmatch.rst library/formatter.rst library/fpectl.rst library/fpformat.rst library/framework.rst library/frameworks.rst library/ftplib.rst library/functions.rst library/functools.rst library/gc.rst library/gdbm.rst library/gensuitemodule.rst library/getopt.rst library/getpass.rst library/gettext.rst library/glob.rst library/grp.rst library/gzip.rst library/hashlib.rst library/heapq.rst library/hmac.rst library/htmllib.rst library/htmlparser.rst library/httplib.rst library/i18n.rst library/ic.rst library/idle.rst library/imaplib.rst library/imghdr.rst library/imp.rst library/imputil.rst library/index.rst library/inspect.rst library/internet.rst library/intro.rst library/ipc.rst library/itertools.rst library/keyword.rst library/language.rst library/linecache.rst library/locale.rst library/logging.rst library/mac.rst library/macos.rst library/macosa.rst library/macostools.rst library/macpath.rst library/mailbox.rst library/mailcap.rst library/markup.rst library/marshal.rst library/math.rst library/mhlib.rst library/mimetools.rst library/mimetypes.rst library/miniaeframe.rst library/misc.rst library/mm.rst library/mmap.rst library/modulefinder.rst library/modules.rst library/msilib.rst library/msvcrt.rst library/multifile.rst library/mutex.rst library/netdata.rst library/netrc.rst library/nis.rst library/nntplib.rst library/numbers.rst library/numeric.rst library/objects.rst library/operator.rst library/optparse.rst library/os.path.rst library/os.rst library/ossaudiodev.rst library/othergui.rst library/parser.rst library/pdb.rst library/persistence.rst library/pickle.rst library/pickletools.rst library/pipes.rst library/pkgutil.rst library/platform.rst library/poplib.rst library/posix.rst library/pprint.rst library/profile.rst library/pty.rst library/pwd.rst library/py_compile.rst library/pyclbr.rst library/pydoc.rst library/pyexpat.rst library/python.rst library/queue.rst library/quopri.rst library/random.rst library/re.rst library/readline.rst library/repr.rst library/resource.rst library/rfc822.rst library/rlcompleter.rst library/robotparser.rst library/runpy.rst library/sched.rst library/scrolledtext.rst library/select.rst library/sgmllib.rst library/shelve.rst library/shlex.rst library/shutil.rst library/signal.rst library/simplehttpserver.rst library/simplexmlrpcserver.rst library/site.rst library/smtpd.rst library/smtplib.rst library/sndhdr.rst library/socket.rst library/socketserver.rst library/someos.rst library/spwd.rst library/sqlite3.rst library/stat.rst library/statvfs.rst library/stdtypes.rst library/string.rst library/stringio.rst library/stringprep.rst library/strings.rst library/struct.rst library/subprocess.rst library/sunau.rst library/symbol.rst library/sys.rst library/syslog.rst library/tabnanny.rst library/tarfile.rst library/telnetlib.rst library/tempfile.rst library/termios.rst library/test.rst library/textwrap.rst library/thread.rst library/threading.rst library/time.rst library/timeit.rst library/tix.rst library/tk.rst library/tkinter.rst library/token.rst library/tokenize.rst library/trace.rst library/traceback.rst library/tty.rst library/turtle.rst library/types.rst library/undoc.rst library/unicodedata.rst library/unittest.rst library/unix.rst library/urllib.rst library/urllib2.rst library/urlparse.rst library/user.rst library/userdict.rst library/uu.rst library/uuid.rst library/warnings.rst library/wave.rst library/weakref.rst library/webbrowser.rst library/whichdb.rst library/windows.rst library/winsound.rst library/wsgiref.rst library/xdrlib.rst library/xml.dom.minidom.rst library/xml.dom.pulldom.rst library/xml.dom.rst library/xml.etree.elementtree.rst library/xml.etree.rst library/xml.sax.handler.rst library/xml.sax.reader.rst library/xml.sax.rst library/xml.sax.utils.rst library/xmlrpclib.rst library/zipfile.rst library/zipimport.rst library/zlib.rst license.rst reference/compound_stmts.rst reference/datamodel.rst reference/executionmodel.rst reference/expressions.rst reference/index.rst reference/introduction.rst reference/lexical_analysis.rst reference/simple_stmts.rst reference/toplevel_components.rst tools/sphinx-build.py tools/sphinx-web.py tutorial/appetite.rst tutorial/classes.rst tutorial/controlflow.rst tutorial/datastructures.rst tutorial/errors.rst tutorial/floatingpoint.rst tutorial/index.rst tutorial/inputoutput.rst tutorial/interactive.rst tutorial/interpreter.rst tutorial/introduction.rst tutorial/modules.rst tutorial/stdlib.rst tutorial/stdlib2.rst tutorial/whatnow.rst using/cmdline.rst using/index.rst using/mac.rst using/unix.rst using/windows.rst whatsnew/2.0.rst whatsnew/2.1.rst whatsnew/2.2.rst whatsnew/2.3.rst whatsnew/2.4.rst whatsnew/2.5.rst whatsnew/2.6.rst whatsnew/3.0.rst Message-ID: <20080105204128.24D7B1E400C@bag.python.org> Author: georg.brandl Date: Sat Jan 5 21:41:27 2008 New Revision: 59751 Modified: python/branches/py3k/Doc/ACKS.txt (props changed) python/branches/py3k/Doc/Makefile (props changed) python/branches/py3k/Doc/README.txt (props changed) python/branches/py3k/Doc/TODO.txt (props changed) python/branches/py3k/Doc/about.rst (props changed) python/branches/py3k/Doc/bugs.rst (props changed) python/branches/py3k/Doc/c-api/abstract.rst (props changed) python/branches/py3k/Doc/c-api/concrete.rst (props changed) python/branches/py3k/Doc/c-api/exceptions.rst (props changed) python/branches/py3k/Doc/c-api/index.rst (props changed) python/branches/py3k/Doc/c-api/init.rst (props changed) python/branches/py3k/Doc/c-api/intro.rst (props changed) python/branches/py3k/Doc/c-api/memory.rst (props changed) python/branches/py3k/Doc/c-api/newtypes.rst (props changed) python/branches/py3k/Doc/c-api/refcounting.rst (props changed) python/branches/py3k/Doc/c-api/utilities.rst (props changed) python/branches/py3k/Doc/c-api/veryhigh.rst (props changed) python/branches/py3k/Doc/conf.py (props changed) python/branches/py3k/Doc/contents.rst (props changed) python/branches/py3k/Doc/copyright.rst (props changed) python/branches/py3k/Doc/distutils/apiref.rst (props changed) python/branches/py3k/Doc/distutils/builtdist.rst (props changed) python/branches/py3k/Doc/distutils/commandref.rst (props changed) python/branches/py3k/Doc/distutils/configfile.rst (props changed) python/branches/py3k/Doc/distutils/examples.rst (props changed) python/branches/py3k/Doc/distutils/extending.rst (props changed) python/branches/py3k/Doc/distutils/index.rst (props changed) python/branches/py3k/Doc/distutils/introduction.rst (props changed) python/branches/py3k/Doc/distutils/packageindex.rst (props changed) python/branches/py3k/Doc/distutils/setupscript.rst (props changed) python/branches/py3k/Doc/distutils/sourcedist.rst (props changed) python/branches/py3k/Doc/distutils/uploading.rst (props changed) python/branches/py3k/Doc/documenting/fromlatex.rst (props changed) python/branches/py3k/Doc/documenting/index.rst (props changed) python/branches/py3k/Doc/documenting/intro.rst (props changed) python/branches/py3k/Doc/documenting/markup.rst (props changed) python/branches/py3k/Doc/documenting/rest.rst (props changed) python/branches/py3k/Doc/documenting/sphinx.rst (props changed) python/branches/py3k/Doc/documenting/style.rst (props changed) python/branches/py3k/Doc/extending/building.rst (props changed) python/branches/py3k/Doc/extending/embedding.rst (props changed) python/branches/py3k/Doc/extending/extending.rst (props changed) python/branches/py3k/Doc/extending/index.rst (props changed) python/branches/py3k/Doc/extending/newtypes.rst (props changed) python/branches/py3k/Doc/extending/windows.rst (props changed) python/branches/py3k/Doc/howto/advocacy.rst (props changed) python/branches/py3k/Doc/howto/curses.rst (props changed) python/branches/py3k/Doc/howto/doanddont.rst (props changed) python/branches/py3k/Doc/howto/functional.rst (props changed) python/branches/py3k/Doc/howto/index.rst (props changed) python/branches/py3k/Doc/howto/regex.rst (props changed) python/branches/py3k/Doc/howto/sockets.rst (props changed) python/branches/py3k/Doc/howto/unicode.rst (props changed) python/branches/py3k/Doc/howto/urllib2.rst (props changed) python/branches/py3k/Doc/includes/email-dir.py (props changed) python/branches/py3k/Doc/includes/email-mime.py (props changed) python/branches/py3k/Doc/includes/email-simple.py (props changed) python/branches/py3k/Doc/includes/email-unpack.py (props changed) python/branches/py3k/Doc/includes/minidom-example.py (props changed) python/branches/py3k/Doc/includes/setup.py (props changed) python/branches/py3k/Doc/includes/sqlite3/adapter_datetime.py (props changed) python/branches/py3k/Doc/includes/sqlite3/adapter_point_1.py (props changed) python/branches/py3k/Doc/includes/sqlite3/adapter_point_2.py (props changed) python/branches/py3k/Doc/includes/sqlite3/collation_reverse.py (props changed) python/branches/py3k/Doc/includes/sqlite3/complete_statement.py (props changed) python/branches/py3k/Doc/includes/sqlite3/connect_db_1.py (props changed) python/branches/py3k/Doc/includes/sqlite3/connect_db_2.py (props changed) python/branches/py3k/Doc/includes/sqlite3/converter_point.py (props changed) python/branches/py3k/Doc/includes/sqlite3/countcursors.py (props changed) python/branches/py3k/Doc/includes/sqlite3/createdb.py (props changed) python/branches/py3k/Doc/includes/sqlite3/execsql_fetchonerow.py (props changed) python/branches/py3k/Doc/includes/sqlite3/execsql_printall_1.py (props changed) python/branches/py3k/Doc/includes/sqlite3/execute_1.py (props changed) python/branches/py3k/Doc/includes/sqlite3/execute_2.py (props changed) python/branches/py3k/Doc/includes/sqlite3/execute_3.py (props changed) python/branches/py3k/Doc/includes/sqlite3/executemany_1.py (props changed) python/branches/py3k/Doc/includes/sqlite3/executemany_2.py (props changed) python/branches/py3k/Doc/includes/sqlite3/executescript.py (props changed) python/branches/py3k/Doc/includes/sqlite3/insert_more_people.py (props changed) python/branches/py3k/Doc/includes/sqlite3/md5func.py (props changed) python/branches/py3k/Doc/includes/sqlite3/mysumaggr.py (props changed) python/branches/py3k/Doc/includes/sqlite3/parse_colnames.py (props changed) python/branches/py3k/Doc/includes/sqlite3/pysqlite_datetime.py (props changed) python/branches/py3k/Doc/includes/sqlite3/row_factory.py (props changed) python/branches/py3k/Doc/includes/sqlite3/rowclass.py (props changed) python/branches/py3k/Doc/includes/sqlite3/shared_cache.py (props changed) python/branches/py3k/Doc/includes/sqlite3/shortcut_methods.py (props changed) python/branches/py3k/Doc/includes/sqlite3/simple_tableprinter.py (props changed) python/branches/py3k/Doc/includes/sqlite3/text_factory.py (props changed) python/branches/py3k/Doc/includes/test.py (props changed) python/branches/py3k/Doc/includes/tzinfo-examples.py (props changed) python/branches/py3k/Doc/install/index.rst (props changed) python/branches/py3k/Doc/library/__future__.rst (props changed) python/branches/py3k/Doc/library/__main__.rst (props changed) python/branches/py3k/Doc/library/_ast.rst (props changed) python/branches/py3k/Doc/library/_winreg.rst (props changed) python/branches/py3k/Doc/library/abc.rst (props changed) python/branches/py3k/Doc/library/aepack.rst (props changed) python/branches/py3k/Doc/library/aetools.rst (props changed) python/branches/py3k/Doc/library/aetypes.rst (props changed) python/branches/py3k/Doc/library/aifc.rst (props changed) python/branches/py3k/Doc/library/allos.rst (props changed) python/branches/py3k/Doc/library/anydbm.rst (props changed) python/branches/py3k/Doc/library/archiving.rst (props changed) python/branches/py3k/Doc/library/array.rst (props changed) python/branches/py3k/Doc/library/asynchat.rst (props changed) python/branches/py3k/Doc/library/asyncore.rst (props changed) python/branches/py3k/Doc/library/atexit.rst (props changed) python/branches/py3k/Doc/library/audioop.rst (props changed) python/branches/py3k/Doc/library/autogil.rst (props changed) python/branches/py3k/Doc/library/base64.rst (props changed) python/branches/py3k/Doc/library/basehttpserver.rst (props changed) python/branches/py3k/Doc/library/bdb.rst (props changed) python/branches/py3k/Doc/library/binascii.rst (props changed) python/branches/py3k/Doc/library/binhex.rst (props changed) python/branches/py3k/Doc/library/bisect.rst (props changed) python/branches/py3k/Doc/library/bsddb.rst (props changed) python/branches/py3k/Doc/library/builtins.rst (props changed) python/branches/py3k/Doc/library/bz2.rst (props changed) python/branches/py3k/Doc/library/calendar.rst (props changed) python/branches/py3k/Doc/library/carbon.rst (props changed) python/branches/py3k/Doc/library/cgi.rst (props changed) python/branches/py3k/Doc/library/cgihttpserver.rst (props changed) python/branches/py3k/Doc/library/cgitb.rst (props changed) python/branches/py3k/Doc/library/chunk.rst (props changed) python/branches/py3k/Doc/library/cmath.rst (props changed) python/branches/py3k/Doc/library/cmd.rst (props changed) python/branches/py3k/Doc/library/code.rst (props changed) python/branches/py3k/Doc/library/codecs.rst (props changed) python/branches/py3k/Doc/library/codeop.rst (props changed) python/branches/py3k/Doc/library/collections.rst (props changed) python/branches/py3k/Doc/library/colorpicker.rst (props changed) python/branches/py3k/Doc/library/colorsys.rst (props changed) python/branches/py3k/Doc/library/commands.rst (props changed) python/branches/py3k/Doc/library/compileall.rst (props changed) python/branches/py3k/Doc/library/configparser.rst (props changed) python/branches/py3k/Doc/library/constants.rst (props changed) python/branches/py3k/Doc/library/contextlib.rst (props changed) python/branches/py3k/Doc/library/cookie.rst (props changed) python/branches/py3k/Doc/library/cookielib.rst (props changed) python/branches/py3k/Doc/library/copy.rst (props changed) python/branches/py3k/Doc/library/copy_reg.rst (props changed) python/branches/py3k/Doc/library/crypt.rst (props changed) python/branches/py3k/Doc/library/crypto.rst (props changed) python/branches/py3k/Doc/library/csv.rst (props changed) python/branches/py3k/Doc/library/ctypes.rst (props changed) python/branches/py3k/Doc/library/curses.ascii.rst (props changed) python/branches/py3k/Doc/library/curses.panel.rst (props changed) python/branches/py3k/Doc/library/curses.rst (props changed) python/branches/py3k/Doc/library/custominterp.rst (props changed) python/branches/py3k/Doc/library/datatypes.rst (props changed) python/branches/py3k/Doc/library/datetime.rst (props changed) python/branches/py3k/Doc/library/dbhash.rst (props changed) python/branches/py3k/Doc/library/dbm.rst (props changed) python/branches/py3k/Doc/library/debug.rst (props changed) python/branches/py3k/Doc/library/decimal.rst (props changed) python/branches/py3k/Doc/library/development.rst (props changed) python/branches/py3k/Doc/library/difflib.rst (props changed) python/branches/py3k/Doc/library/dircache.rst (props changed) python/branches/py3k/Doc/library/dis.rst (props changed) python/branches/py3k/Doc/library/distutils.rst (props changed) python/branches/py3k/Doc/library/dl.rst (props changed) python/branches/py3k/Doc/library/doctest.rst (props changed) python/branches/py3k/Doc/library/docxmlrpcserver.rst (props changed) python/branches/py3k/Doc/library/dumbdbm.rst (props changed) python/branches/py3k/Doc/library/dummy_thread.rst (props changed) python/branches/py3k/Doc/library/dummy_threading.rst (props changed) python/branches/py3k/Doc/library/easydialogs.rst (props changed) python/branches/py3k/Doc/library/email-examples.rst (props changed) python/branches/py3k/Doc/library/email.charset.rst (props changed) python/branches/py3k/Doc/library/email.encoders.rst (props changed) python/branches/py3k/Doc/library/email.errors.rst (props changed) python/branches/py3k/Doc/library/email.generator.rst (props changed) python/branches/py3k/Doc/library/email.header.rst (props changed) python/branches/py3k/Doc/library/email.iterators.rst (props changed) python/branches/py3k/Doc/library/email.message.rst (props changed) python/branches/py3k/Doc/library/email.mime.rst (props changed) python/branches/py3k/Doc/library/email.parser.rst (props changed) python/branches/py3k/Doc/library/email.rst (props changed) python/branches/py3k/Doc/library/email.util.rst (props changed) python/branches/py3k/Doc/library/errno.rst (props changed) python/branches/py3k/Doc/library/exceptions.rst (props changed) python/branches/py3k/Doc/library/fcntl.rst (props changed) python/branches/py3k/Doc/library/filecmp.rst (props changed) python/branches/py3k/Doc/library/fileformats.rst (props changed) python/branches/py3k/Doc/library/fileinput.rst (props changed) python/branches/py3k/Doc/library/filesys.rst (props changed) python/branches/py3k/Doc/library/fnmatch.rst (props changed) python/branches/py3k/Doc/library/formatter.rst (props changed) python/branches/py3k/Doc/library/fpectl.rst (props changed) python/branches/py3k/Doc/library/fpformat.rst (props changed) python/branches/py3k/Doc/library/framework.rst (props changed) python/branches/py3k/Doc/library/frameworks.rst (props changed) python/branches/py3k/Doc/library/ftplib.rst (props changed) python/branches/py3k/Doc/library/functions.rst (props changed) python/branches/py3k/Doc/library/functools.rst (props changed) python/branches/py3k/Doc/library/gc.rst (props changed) python/branches/py3k/Doc/library/gdbm.rst (props changed) python/branches/py3k/Doc/library/gensuitemodule.rst (props changed) python/branches/py3k/Doc/library/getopt.rst (props changed) python/branches/py3k/Doc/library/getpass.rst (props changed) python/branches/py3k/Doc/library/gettext.rst (props changed) python/branches/py3k/Doc/library/glob.rst (props changed) python/branches/py3k/Doc/library/grp.rst (props changed) python/branches/py3k/Doc/library/gzip.rst (props changed) python/branches/py3k/Doc/library/hashlib.rst (props changed) python/branches/py3k/Doc/library/heapq.rst (props changed) python/branches/py3k/Doc/library/hmac.rst (props changed) python/branches/py3k/Doc/library/htmllib.rst (props changed) python/branches/py3k/Doc/library/htmlparser.rst (props changed) python/branches/py3k/Doc/library/httplib.rst (props changed) python/branches/py3k/Doc/library/i18n.rst (props changed) python/branches/py3k/Doc/library/ic.rst (props changed) python/branches/py3k/Doc/library/idle.rst (props changed) python/branches/py3k/Doc/library/imaplib.rst (props changed) python/branches/py3k/Doc/library/imghdr.rst (props changed) python/branches/py3k/Doc/library/imp.rst (props changed) python/branches/py3k/Doc/library/imputil.rst (props changed) python/branches/py3k/Doc/library/index.rst (props changed) python/branches/py3k/Doc/library/inspect.rst (props changed) python/branches/py3k/Doc/library/internet.rst (props changed) python/branches/py3k/Doc/library/intro.rst (props changed) python/branches/py3k/Doc/library/ipc.rst (props changed) python/branches/py3k/Doc/library/itertools.rst (props changed) python/branches/py3k/Doc/library/keyword.rst (props changed) python/branches/py3k/Doc/library/language.rst (props changed) python/branches/py3k/Doc/library/linecache.rst (props changed) python/branches/py3k/Doc/library/locale.rst (props changed) python/branches/py3k/Doc/library/logging.rst (props changed) python/branches/py3k/Doc/library/mac.rst (props changed) python/branches/py3k/Doc/library/macos.rst (props changed) python/branches/py3k/Doc/library/macosa.rst (props changed) python/branches/py3k/Doc/library/macostools.rst (props changed) python/branches/py3k/Doc/library/macpath.rst (props changed) python/branches/py3k/Doc/library/mailbox.rst (props changed) python/branches/py3k/Doc/library/mailcap.rst (props changed) python/branches/py3k/Doc/library/markup.rst (props changed) python/branches/py3k/Doc/library/marshal.rst (props changed) python/branches/py3k/Doc/library/math.rst (props changed) python/branches/py3k/Doc/library/mhlib.rst (props changed) python/branches/py3k/Doc/library/mimetools.rst (props changed) python/branches/py3k/Doc/library/mimetypes.rst (props changed) python/branches/py3k/Doc/library/miniaeframe.rst (props changed) python/branches/py3k/Doc/library/misc.rst (props changed) python/branches/py3k/Doc/library/mm.rst (props changed) python/branches/py3k/Doc/library/mmap.rst (props changed) python/branches/py3k/Doc/library/modulefinder.rst (props changed) python/branches/py3k/Doc/library/modules.rst (props changed) python/branches/py3k/Doc/library/msilib.rst (props changed) python/branches/py3k/Doc/library/msvcrt.rst (props changed) python/branches/py3k/Doc/library/multifile.rst (props changed) python/branches/py3k/Doc/library/mutex.rst (props changed) python/branches/py3k/Doc/library/netdata.rst (props changed) python/branches/py3k/Doc/library/netrc.rst (props changed) python/branches/py3k/Doc/library/nis.rst (props changed) python/branches/py3k/Doc/library/nntplib.rst (props changed) python/branches/py3k/Doc/library/numbers.rst (props changed) python/branches/py3k/Doc/library/numeric.rst (props changed) python/branches/py3k/Doc/library/objects.rst (props changed) python/branches/py3k/Doc/library/operator.rst (props changed) python/branches/py3k/Doc/library/optparse.rst (props changed) python/branches/py3k/Doc/library/os.path.rst (props changed) python/branches/py3k/Doc/library/os.rst (props changed) python/branches/py3k/Doc/library/ossaudiodev.rst (props changed) python/branches/py3k/Doc/library/othergui.rst (props changed) python/branches/py3k/Doc/library/parser.rst (props changed) python/branches/py3k/Doc/library/pdb.rst (props changed) python/branches/py3k/Doc/library/persistence.rst (props changed) python/branches/py3k/Doc/library/pickle.rst (props changed) python/branches/py3k/Doc/library/pickletools.rst (props changed) python/branches/py3k/Doc/library/pipes.rst (props changed) python/branches/py3k/Doc/library/pkgutil.rst (props changed) python/branches/py3k/Doc/library/platform.rst (props changed) python/branches/py3k/Doc/library/poplib.rst (props changed) python/branches/py3k/Doc/library/posix.rst (props changed) python/branches/py3k/Doc/library/pprint.rst (props changed) python/branches/py3k/Doc/library/profile.rst (props changed) python/branches/py3k/Doc/library/pty.rst (props changed) python/branches/py3k/Doc/library/pwd.rst (props changed) python/branches/py3k/Doc/library/py_compile.rst (props changed) python/branches/py3k/Doc/library/pyclbr.rst (props changed) python/branches/py3k/Doc/library/pydoc.rst (props changed) python/branches/py3k/Doc/library/pyexpat.rst (props changed) python/branches/py3k/Doc/library/python.rst (props changed) python/branches/py3k/Doc/library/queue.rst (props changed) python/branches/py3k/Doc/library/quopri.rst (props changed) python/branches/py3k/Doc/library/random.rst (props changed) python/branches/py3k/Doc/library/re.rst (props changed) python/branches/py3k/Doc/library/readline.rst (props changed) python/branches/py3k/Doc/library/repr.rst (props changed) python/branches/py3k/Doc/library/resource.rst (props changed) python/branches/py3k/Doc/library/rfc822.rst (props changed) python/branches/py3k/Doc/library/rlcompleter.rst (props changed) python/branches/py3k/Doc/library/robotparser.rst (props changed) python/branches/py3k/Doc/library/runpy.rst (props changed) python/branches/py3k/Doc/library/sched.rst (props changed) python/branches/py3k/Doc/library/scrolledtext.rst (props changed) python/branches/py3k/Doc/library/select.rst (props changed) python/branches/py3k/Doc/library/sgmllib.rst (props changed) python/branches/py3k/Doc/library/shelve.rst (props changed) python/branches/py3k/Doc/library/shlex.rst (props changed) python/branches/py3k/Doc/library/shutil.rst (props changed) python/branches/py3k/Doc/library/signal.rst (props changed) python/branches/py3k/Doc/library/simplehttpserver.rst (props changed) python/branches/py3k/Doc/library/simplexmlrpcserver.rst (props changed) python/branches/py3k/Doc/library/site.rst (props changed) python/branches/py3k/Doc/library/smtpd.rst (props changed) python/branches/py3k/Doc/library/smtplib.rst (props changed) python/branches/py3k/Doc/library/sndhdr.rst (props changed) python/branches/py3k/Doc/library/socket.rst (props changed) python/branches/py3k/Doc/library/socketserver.rst (props changed) python/branches/py3k/Doc/library/someos.rst (props changed) python/branches/py3k/Doc/library/spwd.rst (props changed) python/branches/py3k/Doc/library/sqlite3.rst (props changed) python/branches/py3k/Doc/library/stat.rst (props changed) python/branches/py3k/Doc/library/statvfs.rst (props changed) python/branches/py3k/Doc/library/stdtypes.rst (props changed) python/branches/py3k/Doc/library/string.rst (props changed) python/branches/py3k/Doc/library/stringio.rst (props changed) python/branches/py3k/Doc/library/stringprep.rst (props changed) python/branches/py3k/Doc/library/strings.rst (props changed) python/branches/py3k/Doc/library/struct.rst (props changed) python/branches/py3k/Doc/library/subprocess.rst (props changed) python/branches/py3k/Doc/library/sunau.rst (props changed) python/branches/py3k/Doc/library/symbol.rst (props changed) python/branches/py3k/Doc/library/sys.rst (props changed) python/branches/py3k/Doc/library/syslog.rst (props changed) python/branches/py3k/Doc/library/tabnanny.rst (props changed) python/branches/py3k/Doc/library/tarfile.rst (props changed) python/branches/py3k/Doc/library/telnetlib.rst (props changed) python/branches/py3k/Doc/library/tempfile.rst (props changed) python/branches/py3k/Doc/library/termios.rst (props changed) python/branches/py3k/Doc/library/test.rst (props changed) python/branches/py3k/Doc/library/textwrap.rst (props changed) python/branches/py3k/Doc/library/thread.rst (props changed) python/branches/py3k/Doc/library/threading.rst (props changed) python/branches/py3k/Doc/library/time.rst (props changed) python/branches/py3k/Doc/library/timeit.rst (props changed) python/branches/py3k/Doc/library/tix.rst (props changed) python/branches/py3k/Doc/library/tk.rst (props changed) python/branches/py3k/Doc/library/tkinter.rst (props changed) python/branches/py3k/Doc/library/token.rst (props changed) python/branches/py3k/Doc/library/tokenize.rst (props changed) python/branches/py3k/Doc/library/trace.rst (props changed) python/branches/py3k/Doc/library/traceback.rst (props changed) python/branches/py3k/Doc/library/tty.rst (props changed) python/branches/py3k/Doc/library/turtle.rst (props changed) python/branches/py3k/Doc/library/types.rst (props changed) python/branches/py3k/Doc/library/undoc.rst (props changed) python/branches/py3k/Doc/library/unicodedata.rst (props changed) python/branches/py3k/Doc/library/unittest.rst (props changed) python/branches/py3k/Doc/library/unix.rst (props changed) python/branches/py3k/Doc/library/urllib.rst (props changed) python/branches/py3k/Doc/library/urllib2.rst (props changed) python/branches/py3k/Doc/library/urlparse.rst (props changed) python/branches/py3k/Doc/library/user.rst (props changed) python/branches/py3k/Doc/library/userdict.rst (props changed) python/branches/py3k/Doc/library/uu.rst (props changed) python/branches/py3k/Doc/library/uuid.rst (props changed) python/branches/py3k/Doc/library/warnings.rst (props changed) python/branches/py3k/Doc/library/wave.rst (props changed) python/branches/py3k/Doc/library/weakref.rst (props changed) python/branches/py3k/Doc/library/webbrowser.rst (props changed) python/branches/py3k/Doc/library/whichdb.rst (props changed) python/branches/py3k/Doc/library/windows.rst (props changed) python/branches/py3k/Doc/library/winsound.rst (props changed) python/branches/py3k/Doc/library/wsgiref.rst (props changed) python/branches/py3k/Doc/library/xdrlib.rst (props changed) python/branches/py3k/Doc/library/xml.dom.minidom.rst (props changed) python/branches/py3k/Doc/library/xml.dom.pulldom.rst (props changed) python/branches/py3k/Doc/library/xml.dom.rst (props changed) python/branches/py3k/Doc/library/xml.etree.elementtree.rst (props changed) python/branches/py3k/Doc/library/xml.etree.rst (props changed) python/branches/py3k/Doc/library/xml.sax.handler.rst (props changed) python/branches/py3k/Doc/library/xml.sax.reader.rst (props changed) python/branches/py3k/Doc/library/xml.sax.rst (props changed) python/branches/py3k/Doc/library/xml.sax.utils.rst (props changed) python/branches/py3k/Doc/library/xmlrpclib.rst (props changed) python/branches/py3k/Doc/library/zipfile.rst (props changed) python/branches/py3k/Doc/library/zipimport.rst (props changed) python/branches/py3k/Doc/library/zlib.rst (props changed) python/branches/py3k/Doc/license.rst (props changed) python/branches/py3k/Doc/reference/compound_stmts.rst (props changed) python/branches/py3k/Doc/reference/datamodel.rst (props changed) python/branches/py3k/Doc/reference/executionmodel.rst (props changed) python/branches/py3k/Doc/reference/expressions.rst (props changed) python/branches/py3k/Doc/reference/index.rst (props changed) python/branches/py3k/Doc/reference/introduction.rst (props changed) python/branches/py3k/Doc/reference/lexical_analysis.rst (props changed) python/branches/py3k/Doc/reference/simple_stmts.rst (props changed) python/branches/py3k/Doc/reference/toplevel_components.rst (props changed) python/branches/py3k/Doc/tools/sphinx-build.py (props changed) python/branches/py3k/Doc/tools/sphinx-web.py (props changed) python/branches/py3k/Doc/tutorial/appetite.rst (props changed) python/branches/py3k/Doc/tutorial/classes.rst (props changed) python/branches/py3k/Doc/tutorial/controlflow.rst (props changed) python/branches/py3k/Doc/tutorial/datastructures.rst (props changed) python/branches/py3k/Doc/tutorial/errors.rst (props changed) python/branches/py3k/Doc/tutorial/floatingpoint.rst (props changed) python/branches/py3k/Doc/tutorial/index.rst (props changed) python/branches/py3k/Doc/tutorial/inputoutput.rst (props changed) python/branches/py3k/Doc/tutorial/interactive.rst (props changed) python/branches/py3k/Doc/tutorial/interpreter.rst (props changed) python/branches/py3k/Doc/tutorial/introduction.rst (props changed) python/branches/py3k/Doc/tutorial/modules.rst (props changed) python/branches/py3k/Doc/tutorial/stdlib.rst (props changed) python/branches/py3k/Doc/tutorial/stdlib2.rst (props changed) python/branches/py3k/Doc/tutorial/whatnow.rst (props changed) python/branches/py3k/Doc/using/cmdline.rst (props changed) python/branches/py3k/Doc/using/index.rst (props changed) python/branches/py3k/Doc/using/mac.rst (props changed) python/branches/py3k/Doc/using/unix.rst (props changed) python/branches/py3k/Doc/using/windows.rst (props changed) python/branches/py3k/Doc/whatsnew/2.0.rst (props changed) python/branches/py3k/Doc/whatsnew/2.1.rst (props changed) python/branches/py3k/Doc/whatsnew/2.2.rst (props changed) python/branches/py3k/Doc/whatsnew/2.3.rst (props changed) python/branches/py3k/Doc/whatsnew/2.4.rst (props changed) python/branches/py3k/Doc/whatsnew/2.5.rst (props changed) python/branches/py3k/Doc/whatsnew/2.6.rst (props changed) python/branches/py3k/Doc/whatsnew/3.0.rst (props changed) Log: Set native svn:eol-style property for text files. From python-3000-checkins at python.org Sat Jan 5 22:16:34 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sat, 5 Jan 2008 22:16:34 +0100 (CET) Subject: [Python-3000-checkins] r59755 - python/branches/py3k/Doc/c-api/concrete.rst Message-ID: <20080105211634.0FFE41E400B@bag.python.org> Author: georg.brandl Date: Sat Jan 5 22:16:33 2008 New Revision: 59755 Modified: python/branches/py3k/Doc/c-api/concrete.rst Log: Big fat todo. Modified: python/branches/py3k/Doc/c-api/concrete.rst ============================================================================== --- python/branches/py3k/Doc/c-api/concrete.rst (original) +++ python/branches/py3k/Doc/c-api/concrete.rst Sat Jan 5 22:16:33 2008 @@ -585,6 +585,7 @@ this section deals with the specific kinds of sequence objects that are intrinsic to the Python language. +.. XXX sort out unicode, str, bytes and bytearray .. _stringobjects: From python-3000-checkins at python.org Sat Jan 5 22:20:19 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sat, 5 Jan 2008 22:20:19 +0100 (CET) Subject: [Python-3000-checkins] r59756 - python/branches/py3k/Lib/platform.py Message-ID: <20080105212019.B6ED71E401D@bag.python.org> Author: georg.brandl Date: Sat Jan 5 22:20:19 2008 New Revision: 59756 Modified: python/branches/py3k/Lib/platform.py Log: Fix bug introduced by r59746. Modified: python/branches/py3k/Lib/platform.py ============================================================================== --- python/branches/py3k/Lib/platform.py (original) +++ python/branches/py3k/Lib/platform.py Sat Jan 5 22:20:19 2008 @@ -860,7 +860,7 @@ """ In case filepath is a symlink, follow it until a real file is reached. """ - filepath = _abspath(filepath) + filepath = os.path.abspath(filepath) while os.path.islink(filepath): filepath = os.path.normpath( os.path.join(filepath,os.readlink(filepath))) From python-3000-checkins at python.org Sun Jan 6 01:09:12 2008 From: python-3000-checkins at python.org (guido.van.rossum) Date: Sun, 6 Jan 2008 01:09:12 +0100 (CET) Subject: [Python-3000-checkins] r59761 - in python/branches/py3k: Lib/test/test_compare.py Misc/NEWS Objects/typeobject.c Message-ID: <20080106000912.196A31E400B@bag.python.org> Author: guido.van.rossum Date: Sun Jan 6 01:09:11 2008 New Revision: 59761 Modified: python/branches/py3k/Lib/test/test_compare.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/typeobject.c Log: Issue #1393: object_richcompare() returns NotImplemented instead of False if the objects aren't equal, to give the other side a chance. Modified: python/branches/py3k/Lib/test/test_compare.py ============================================================================== --- python/branches/py3k/Lib/test/test_compare.py (original) +++ python/branches/py3k/Lib/test/test_compare.py Sun Jan 6 01:09:11 2008 @@ -16,6 +16,13 @@ def __eq__(self, other): return self.arg == other +class Anything: + def __eq__(self, other): + return True + + def __ne__(self, other): + return False + class ComparisonTest(unittest.TestCase): set1 = [2, 2.0, 2, 2+0j, Cmp(2.0)] set2 = [[1], (3,), None, Empty()] @@ -45,6 +52,15 @@ self.assertTrue(a == b) self.assertFalse(a != b) + def test_issue_1393(self): + x = lambda: None + self.assertEqual(x, Anything()) + self.assertEqual(Anything(), x) + y = object() + self.assertEqual(y, Anything()) + self.assertEqual(Anything(), y) + + def test_main(): test_support.run_unittest(ComparisonTest) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Jan 6 01:09:11 2008 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #1393: object_richcompare() returns NotImplemented instead of + False if the objects aren't equal, to give the other side a chance. + - Issue #1692: Interpreter was not displaying location of SyntaxError - Improve some exception messages when Windows fails to load an extension Modified: python/branches/py3k/Objects/typeobject.c ============================================================================== --- python/branches/py3k/Objects/typeobject.c (original) +++ python/branches/py3k/Objects/typeobject.c Sun Jan 6 01:09:11 2008 @@ -2484,7 +2484,10 @@ switch (op) { case Py_EQ: - res = (self == other) ? Py_True : Py_False; + /* Return NotImplemented instead of False, so if two + objects are compared, both get a chance at the + comparison. See issue #1393. */ + res = (self == other) ? Py_True : Py_NotImplemented; Py_INCREF(res); break; From python-3000-checkins at python.org Sun Jan 6 01:34:32 2008 From: python-3000-checkins at python.org (alexandre.vassalotti) Date: Sun, 6 Jan 2008 01:34:32 +0100 (CET) Subject: [Python-3000-checkins] r59762 - python/branches/py3k/Lib/test/test_io.py Message-ID: <20080106003432.722E01E400B@bag.python.org> Author: alexandre.vassalotti Date: Sun Jan 6 01:34:32 2008 New Revision: 59762 Modified: python/branches/py3k/Lib/test/test_io.py Log: Add unit tests for the newlines property of IncrementalNewlineDecoder. Modified: python/branches/py3k/Lib/test/test_io.py ============================================================================== --- python/branches/py3k/Lib/test/test_io.py (original) +++ python/branches/py3k/Lib/test/test_io.py Sun Jan 6 01:34:32 2008 @@ -911,6 +911,22 @@ self.assertEquals(decoder.decode(b'\xe8\xa2\x88\r'), "\u8888") self.assertEquals(decoder.decode(b'\n'), "\n") + decoder = codecs.getincrementaldecoder("utf-8")() + decoder = io.IncrementalNewlineDecoder(decoder, translate=True) + self.assertEquals(decoder.newlines, None) + decoder.decode(b"abc\n\r") + self.assertEquals(decoder.newlines, '\n') + decoder.decode(b"\nabc") + self.assertEquals(decoder.newlines, ('\n', '\r\n')) + decoder.decode(b"abc\r") + self.assertEquals(decoder.newlines, ('\n', '\r\n')) + decoder.decode(b"abc") + self.assertEquals(decoder.newlines, ('\r', '\n', '\r\n')) + decoder.decode(b"abc\r") + decoder.reset() + self.assertEquals(decoder.decode(b"abc"), "abc") + self.assertEquals(decoder.newlines, None) + # XXX Tests for open() class MiscIOTest(unittest.TestCase): From alexandre at peadrop.com Sun Jan 6 01:35:07 2008 From: alexandre at peadrop.com (Alexandre Vassalotti) Date: Sat, 5 Jan 2008 19:35:07 -0500 Subject: [Python-3000-checkins] r59602 - python/branches/py3k/Lib/io.py In-Reply-To: References: <20071228012423.0FEE31E4015@bag.python.org> Message-ID: On Jan 1, 2008 11:27 AM, Guido van Rossum wrote: > Where's the unittest for this fix? > Added in r59762. From python-3000-checkins at python.org Sun Jan 6 01:44:21 2008 From: python-3000-checkins at python.org (guido.van.rossum) Date: Sun, 6 Jan 2008 01:44:21 +0100 (CET) Subject: [Python-3000-checkins] r59763 - python/branches/py3k/Misc/NEWS Message-ID: <20080106004421.382CD1E400B@bag.python.org> Author: guido.van.rossum Date: Sun Jan 6 01:44:20 2008 New Revision: 59763 Modified: python/branches/py3k/Misc/NEWS Log: Add some missing news. Add some periods. Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Jan 6 01:44:20 2008 @@ -15,7 +15,7 @@ - Issue #1393: object_richcompare() returns NotImplemented instead of False if the objects aren't equal, to give the other side a chance. -- Issue #1692: Interpreter was not displaying location of SyntaxError +- Issue #1692: Interpreter was not displaying location of SyntaxError. - Improve some exception messages when Windows fails to load an extension module. Now we get for example '%1 is not a valid Win32 application' instead @@ -35,10 +35,10 @@ "Floating-Point Printer Sample Code", by Robert G. Burger. For example repr(11./5) now returns '2.2' instead of '2.2000000000000002'. -- Issue #1573: Improper use of the keyword-only syntax makes the parser crash +- Issue #1573: Improper use of the keyword-only syntax makes the parser crash. - Issue #1564: The set implementation should special-case PyUnicode instead - of PyString + of PyString. Extension Modules @@ -48,9 +48,21 @@ Library ------- -- Issue #1585: IDLE uses non-existent xrange() function +- Issue #1703: getpass() should flush after writing prompt. -- Issue #1578: Problems in win_getpass +- Issue #1585: IDLE uses non-existent xrange() function. + +- Issue #1578: Problems in win_getpass. + + +C API +----- + +- Issue #1629: Renamed Py_Size, Py_Type and Py_Refcnt to Py_SIZE, + Py_TYPE and Py_REFCNT. + +- New API PyImport_ImportModuleNoBlock(), works like PyImport_ImportModule() + but won't block on the import lock (returning an error instead). What's New in Python 3.0a2? From python-3000-checkins at python.org Sun Jan 6 17:59:21 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Sun, 6 Jan 2008 17:59:21 +0100 (CET) Subject: [Python-3000-checkins] r59783 - in python/branches/py3k: Doc/ACKS.txt Doc/c-api/newtypes.rst Doc/c-api/utilities.rst Doc/library/collections.rst Doc/library/contextlib.rst Doc/library/decimal.rst Doc/library/fcntl.rst Doc/library/functions.rst Doc/library/msilib.rst Doc/library/msvcrt.rst Doc/library/numbers.rst Doc/library/os.rst Doc/library/socket.rst Doc/library/stdtypes.rst Doc/library/thread.rst Doc/library/threading.rst Doc/library/winsound.rst Doc/reference/compound_stmts.rst Doc/reference/datamodel.rst Doc/reference/expressions.rst Doc/reference/simple_stmts.rst Doc/whatsnew/2.6.rst Lib/collections.py Lib/ntpath.py Lib/posixpath.py Lib/tarfile.py Lib/test/test_collections.py Lib/test/test_doctest.py Lib/test/test_ntpath.py Lib/test/test_posixpath.py Lib/test/test_socket.py Lib/test/test_tarfile.py Lib/test/test_urlparse.py Lib/urlparse.py Misc/ACKS Modules/fcntlmodule.c Modules/socketmodule.c Modules/socketmodule.h PCbuild/build_tkinter.py Python/dynload_win.c Python/pystrtod.c Tools/buildbot/buildmsi.bat Tools/msi/msi.py Message-ID: <20080106165921.6769F1E4012@bag.python.org> Author: christian.heimes Date: Sun Jan 6 17:59:19 2008 New Revision: 59783 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/ACKS.txt python/branches/py3k/Doc/c-api/newtypes.rst python/branches/py3k/Doc/c-api/utilities.rst python/branches/py3k/Doc/library/collections.rst python/branches/py3k/Doc/library/contextlib.rst python/branches/py3k/Doc/library/decimal.rst python/branches/py3k/Doc/library/fcntl.rst python/branches/py3k/Doc/library/functions.rst python/branches/py3k/Doc/library/msilib.rst python/branches/py3k/Doc/library/msvcrt.rst python/branches/py3k/Doc/library/numbers.rst python/branches/py3k/Doc/library/os.rst python/branches/py3k/Doc/library/socket.rst python/branches/py3k/Doc/library/stdtypes.rst python/branches/py3k/Doc/library/thread.rst python/branches/py3k/Doc/library/threading.rst python/branches/py3k/Doc/library/winsound.rst python/branches/py3k/Doc/reference/compound_stmts.rst python/branches/py3k/Doc/reference/datamodel.rst python/branches/py3k/Doc/reference/expressions.rst python/branches/py3k/Doc/reference/simple_stmts.rst python/branches/py3k/Doc/whatsnew/2.6.rst python/branches/py3k/Lib/collections.py python/branches/py3k/Lib/ntpath.py python/branches/py3k/Lib/posixpath.py python/branches/py3k/Lib/tarfile.py python/branches/py3k/Lib/test/test_collections.py python/branches/py3k/Lib/test/test_doctest.py python/branches/py3k/Lib/test/test_ntpath.py python/branches/py3k/Lib/test/test_posixpath.py python/branches/py3k/Lib/test/test_socket.py python/branches/py3k/Lib/test/test_tarfile.py python/branches/py3k/Lib/test/test_urlparse.py python/branches/py3k/Lib/urlparse.py python/branches/py3k/Misc/ACKS python/branches/py3k/Modules/fcntlmodule.c python/branches/py3k/Modules/socketmodule.c python/branches/py3k/Modules/socketmodule.h python/branches/py3k/PCbuild/build_tkinter.py python/branches/py3k/Python/dynload_win.c python/branches/py3k/Python/pystrtod.c python/branches/py3k/Tools/buildbot/buildmsi.bat python/branches/py3k/Tools/msi/msi.py Log: Merged revisions 59703-59773 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r59704 | christian.heimes | 2008-01-04 04:15:05 +0100 (Fri, 04 Jan 2008) | 1 line Moved include "Python.h" in front of other imports to silence a warning. ........ r59706 | raymond.hettinger | 2008-01-04 04:22:53 +0100 (Fri, 04 Jan 2008) | 10 lines Minor fix-ups to named tuples: * Make the _replace() method respect subclassing. * Using property() to make _fields read-only wasn't a good idea. It caused len(Point._fields) to fail. * Add note to _cast() about length checking and alternative with the star-operator. ........ r59707 | jeffrey.yasskin | 2008-01-04 09:01:23 +0100 (Fri, 04 Jan 2008) | 3 lines Make math.{floor,ceil}({int,long}) return float again for backwards compatibility after r59671 made them return integral types. ........ r59709 | christian.heimes | 2008-01-04 14:21:07 +0100 (Fri, 04 Jan 2008) | 1 line Bug #1713: posixpath.ismount() claims symlink to a mountpoint is a mountpoint. ........ r59712 | lars.gustaebel | 2008-01-04 15:00:33 +0100 (Fri, 04 Jan 2008) | 5 lines Issue #1735: TarFile.extractall() now correctly sets directory permissions and times. (will backport to 2.5) ........ r59714 | andrew.kuchling | 2008-01-04 15:47:17 +0100 (Fri, 04 Jan 2008) | 1 line Update links to bug/patch tracker ........ r59716 | christian.heimes | 2008-01-04 16:23:30 +0100 (Fri, 04 Jan 2008) | 1 line Added interface to Windows' WSAIoctl and a simple example for a network sniffer. ........ r59717 | christian.heimes | 2008-01-04 16:29:00 +0100 (Fri, 04 Jan 2008) | 1 line And here is the rest of Hirokazu Yamamoto's patch for VS6.0 support. Thanks Hiro! ........ r59719 | christian.heimes | 2008-01-04 16:34:06 +0100 (Fri, 04 Jan 2008) | 1 line Reverted last transaction. It's the wrong branch. ........ r59721 | christian.heimes | 2008-01-04 16:48:06 +0100 (Fri, 04 Jan 2008) | 1 line socket.ioctl is only available on Windows ........ r59722 | andrew.kuchling | 2008-01-04 19:24:41 +0100 (Fri, 04 Jan 2008) | 1 line Fix markup ........ r59723 | andrew.kuchling | 2008-01-04 19:25:05 +0100 (Fri, 04 Jan 2008) | 1 line Fix markup ........ r59725 | guido.van.rossum | 2008-01-05 01:59:59 +0100 (Sat, 05 Jan 2008) | 3 lines Patch #1725 by Mark Dickinson, fixes incorrect conversion of -1e1000 and adds errors for -0x. ........ r59726 | guido.van.rossum | 2008-01-05 02:21:57 +0100 (Sat, 05 Jan 2008) | 2 lines Patch #1698 by Senthil: allow '@' in username when parsed by urlparse.py. ........ r59727 | raymond.hettinger | 2008-01-05 02:35:43 +0100 (Sat, 05 Jan 2008) | 1 line Improve namedtuple's _cast() method with a docstring, new name, and error-checking. ........ r59728 | raymond.hettinger | 2008-01-05 03:17:24 +0100 (Sat, 05 Jan 2008) | 1 line Add error-checking to namedtuple's _replace() method. ........ r59730 | fred.drake | 2008-01-05 05:38:38 +0100 (Sat, 05 Jan 2008) | 2 lines clean up a comment ........ r59731 | jeffrey.yasskin | 2008-01-05 09:47:13 +0100 (Sat, 05 Jan 2008) | 11 lines Continue rolling back pep-3141 changes that changed behavior from 2.5. This round included: * Revert round to its 2.6 behavior (half away from 0). * Because round, floor, and ceil always return float again, it's no longer necessary to have them delegate to __xxx___, so I've ripped that out of their implementations and the Real ABC. This also helps in implementing types that work in both 2.6 and 3.0: you return int from the __xxx__ methods, and let it get enabled by the version upgrade. * Make pow(-1, .5) raise a ValueError again. ........ r59736 | andrew.kuchling | 2008-01-05 16:13:49 +0100 (Sat, 05 Jan 2008) | 1 line Fix comment typo ........ r59738 | thomas.heller | 2008-01-05 18:15:44 +0100 (Sat, 05 Jan 2008) | 1 line Add myself. ........ r59739 | georg.brandl | 2008-01-05 18:49:17 +0100 (Sat, 05 Jan 2008) | 2 lines Fix C++-style comment. ........ r59742 | georg.brandl | 2008-01-05 20:28:16 +0100 (Sat, 05 Jan 2008) | 2 lines Remove with_statement future imports from 2.6 docs. ........ r59743 | georg.brandl | 2008-01-05 20:29:45 +0100 (Sat, 05 Jan 2008) | 2 lines Simplify index entries; fix #1712. ........ r59744 | georg.brandl | 2008-01-05 20:44:22 +0100 (Sat, 05 Jan 2008) | 2 lines Doc patch #1730 from Robin Stocker; minor corrections mostly to os.rst. ........ r59749 | georg.brandl | 2008-01-05 21:29:13 +0100 (Sat, 05 Jan 2008) | 2 lines Revert socket.rst to unix-eol. ........ r59750 | georg.brandl | 2008-01-05 21:33:46 +0100 (Sat, 05 Jan 2008) | 2 lines Set native svn:eol-style property for text files. ........ r59752 | georg.brandl | 2008-01-05 21:46:29 +0100 (Sat, 05 Jan 2008) | 2 lines #1719: capitalization error in "UuidCreate". ........ r59753 | georg.brandl | 2008-01-05 22:02:25 +0100 (Sat, 05 Jan 2008) | 2 lines Repair markup. ........ r59754 | georg.brandl | 2008-01-05 22:10:50 +0100 (Sat, 05 Jan 2008) | 2 lines Use markup. ........ r59757 | christian.heimes | 2008-01-05 22:35:52 +0100 (Sat, 05 Jan 2008) | 1 line Final adjustments for #1601 ........ r59758 | guido.van.rossum | 2008-01-05 23:19:06 +0100 (Sat, 05 Jan 2008) | 3 lines Patch #1637: fix urlparse for URLs like 'http://x.com?arg=/foo'. Fix by John Nagle. ........ r59759 | guido.van.rossum | 2008-01-05 23:20:01 +0100 (Sat, 05 Jan 2008) | 2 lines Add John Nagle (of issue #1637). ........ r59765 | raymond.hettinger | 2008-01-06 10:02:24 +0100 (Sun, 06 Jan 2008) | 1 line Small code simplification. Forgot that classmethods can be called from intances. ........ r59766 | martin.v.loewis | 2008-01-06 11:09:48 +0100 (Sun, 06 Jan 2008) | 2 lines Use vcbuild for VS 2009. ........ r59767 | martin.v.loewis | 2008-01-06 12:03:43 +0100 (Sun, 06 Jan 2008) | 2 lines Package using VS 2008. ........ r59768 | martin.v.loewis | 2008-01-06 12:13:16 +0100 (Sun, 06 Jan 2008) | 2 lines Don't try to package msvcr90 for the moment. ........ r59769 | georg.brandl | 2008-01-06 15:17:36 +0100 (Sun, 06 Jan 2008) | 4 lines #1696393: don't check for '.' and '..' in ntpath.walk since they aren't returned from os.listdir anymore. Reported by Michael Haggerty. ........ r59770 | georg.brandl | 2008-01-06 15:27:15 +0100 (Sun, 06 Jan 2008) | 3 lines #1742: don't raise exception on os.path.relpath("a", "a"), but return os.curdir. Reported by Jesse Towner. ........ r59771 | georg.brandl | 2008-01-06 15:33:52 +0100 (Sun, 06 Jan 2008) | 2 lines #1591: Clarify docstring of Popen3. ........ r59772 | georg.brandl | 2008-01-06 16:30:34 +0100 (Sun, 06 Jan 2008) | 2 lines #1680: fix context manager example function name. ........ r59773 | georg.brandl | 2008-01-06 16:34:57 +0100 (Sun, 06 Jan 2008) | 2 lines #1755097: document default values for [].sort() and sorted(). ........ Modified: python/branches/py3k/Doc/ACKS.txt ============================================================================== --- python/branches/py3k/Doc/ACKS.txt (original) +++ python/branches/py3k/Doc/ACKS.txt Sun Jan 6 17:59:19 2008 @@ -73,6 +73,7 @@ * Travis B. Hartwell * Tim Hatch * Janko Hauser + * Thomas Heller * Bernhard Herzog * Magnus L. Hetland * Konrad Hinsen Modified: python/branches/py3k/Doc/c-api/newtypes.rst ============================================================================== --- python/branches/py3k/Doc/c-api/newtypes.rst (original) +++ python/branches/py3k/Doc/c-api/newtypes.rst Sun Jan 6 17:59:19 2008 @@ -729,7 +729,7 @@ indicated by the :const:`Py_TPFLAGS_HAVE_RICHCOMPARE` flag bit) and have *NULL* values. - The following bit masks are currently defined; these can be or-ed together using + The following bit masks are currently defined; these can be ORed together using the ``|`` operator to form the value of the :attr:`tp_flags` field. The macro :cfunc:`PyType_HasFeature` takes a type and a flags value, *tp* and *f*, and checks whether ``tp->tp_flags & f`` is non-zero. Modified: python/branches/py3k/Doc/c-api/utilities.rst ============================================================================== --- python/branches/py3k/Doc/c-api/utilities.rst (original) +++ python/branches/py3k/Doc/c-api/utilities.rst Sun Jan 6 17:59:19 2008 @@ -197,19 +197,14 @@ to find out. Starting with Python 2.4, a failing import of a module no longer leaves the module in ``sys.modules``. - .. index:: single: modules (in module sys) - .. cfunction:: PyObject* PyImport_ImportModuleNoBlock(const char *name) - .. index:: - single: `cfunc:PyImport_ImportModule` - - This version of `cfunc:PyImport_ImportModule` does not block. It's intended + This version of :cfunc:`PyImport_ImportModule` does not block. It's intended to be used in C function which import other modules to execute a function. The import may block if another thread holds the import lock. The function - `cfunc:PyImport_ImportModuleNoBlock` doesn't block. It first tries to fetch - the module from sys.modules and falls back to `cfunc:PyImport_ImportModule` + :cfunc:`PyImport_ImportModuleNoBlock` doesn't block. It first tries to fetch + the module from sys.modules and falls back to :cfunc:`PyImport_ImportModule` unless the the lock is hold. In the latter case the function raises an ImportError. @@ -231,9 +226,6 @@ Failing imports remove incomplete module objects, like with :cfunc:`PyImport_ImportModule`. - The function is an alias for `cfunc:PyImport_ImportModuleLevel` with -1 as - *level*, meaning relative import. - .. cfunction:: PyObject* PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level) @@ -286,9 +278,9 @@ :func:`compile`, load the module. Return a new reference to the module object, or *NULL* with an exception set if an error occurred. Before Python 2.4, the module could still be created in error cases. Starting with Python 2.4, *name* - is removed from ``sys.modules`` in error cases, and even if *name* was already - in ``sys.modules`` on entry to :cfunc:`PyImport_ExecCodeModule`. Leaving - incompletely initialized modules in ``sys.modules`` is dangerous, as imports of + is removed from :attr:`sys.modules` in error cases, and even if *name* was already + in :attr:`sys.modules` on entry to :cfunc:`PyImport_ExecCodeModule`. Leaving + incompletely initialized modules in :attr:`sys.modules` is dangerous, as imports of such modules have no way to know that the module object is an unknown (and probably damaged with respect to the module author's intents) state. Modified: python/branches/py3k/Doc/library/collections.rst ============================================================================== --- python/branches/py3k/Doc/library/collections.rst (original) +++ python/branches/py3k/Doc/library/collections.rst Sun Jan 6 17:59:19 2008 @@ -419,10 +419,18 @@ __slots__ = () + _fields = ('x', 'y') + def __new__(cls, x, y): return tuple.__new__(cls, (x, y)) - _cast = classmethod(tuple.__new__) + @classmethod + def _make(cls, iterable): + 'Make a new Point object from a sequence or iterable' + result = tuple.__new__(cls, iterable) + if len(result) != 2: + raise TypeError('Expected 2 arguments, got %d' % len(result)) + return result def __repr__(self): return 'Point(x=%r, y=%r)' % self @@ -433,11 +441,10 @@ def _replace(self, **kwds): 'Return a new Point object replacing specified fields with new values' - return Point._cast(map(kwds.get, ('x', 'y'), self)) - - @property - def _fields(self): - return ('x', 'y') + result = self._make(map(kwds.pop, ('x', 'y'), self)) + if kwds: + raise ValueError('Got unexpected field names: %r' % kwds.keys()) + return result x = property(itemgetter(0)) y = property(itemgetter(1)) @@ -459,29 +466,28 @@ EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade') import csv - for emp in map(EmployeeRecord._cast, csv.reader(open("employees.csv", "rb"))): + for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))): print(emp.name, emp.title) import sqlite3 conn = sqlite3.connect('/companydata') cursor = conn.cursor() cursor.execute('SELECT name, age, title, department, paygrade FROM employees') - for emp in map(EmployeeRecord._cast, cursor.fetchall()): + for emp in map(EmployeeRecord._make, cursor.fetchall()): print emp.name, emp.title In addition to the methods inherited from tuples, named tuples support -three additonal methods and a read-only attribute. +three additional methods and one attribute. -.. method:: namedtuple._cast(iterable) +.. method:: namedtuple._make(iterable) - Class method returning a new instance taking the positional arguments from the *iterable*. - Useful for casting existing sequences and iterables to named tuples: + Class method that makes a new instance from an existing sequence or iterable. :: - >>> t = [11, 22] - >>> Point._cast(t) - Point(x=11, y=22) + >>> t = [11, 22] + >>> Point._make(t) + Point(x=11, y=22) .. method:: somenamedtuple._asdict() @@ -507,7 +513,7 @@ .. attribute:: somenamedtuple._fields - Return a tuple of strings listing the field names. This is useful for introspection + Tuple of strings listing the field names. This is useful for introspection and for creating new named tuple types from existing named tuples. :: Modified: python/branches/py3k/Doc/library/contextlib.rst ============================================================================== --- python/branches/py3k/Doc/library/contextlib.rst (original) +++ python/branches/py3k/Doc/library/contextlib.rst Sun Jan 6 17:59:19 2008 @@ -21,7 +21,6 @@ A simple example (this is not recommended as a real way of generating HTML!):: - from __future__ import with_statement from contextlib import contextmanager @contextmanager @@ -98,7 +97,6 @@ And lets you write code like this:: - from __future__ import with_statement from contextlib import closing import urllib Modified: python/branches/py3k/Doc/library/decimal.rst ============================================================================== --- python/branches/py3k/Doc/library/decimal.rst (original) +++ python/branches/py3k/Doc/library/decimal.rst Sun Jan 6 17:59:19 2008 @@ -794,7 +794,6 @@ For example, the following code sets the current decimal precision to 42 places, performs a calculation, and then automatically restores the previous context:: - from __future__ import with_statement from decimal import localcontext with localcontext() as ctx: Modified: python/branches/py3k/Doc/library/fcntl.rst ============================================================================== --- python/branches/py3k/Doc/library/fcntl.rst (original) +++ python/branches/py3k/Doc/library/fcntl.rst Sun Jan 6 17:59:19 2008 @@ -109,7 +109,7 @@ * :const:`LOCK_EX` -- acquire an exclusive lock When *operation* is :const:`LOCK_SH` or :const:`LOCK_EX`, it can also be - bit-wise OR'd with :const:`LOCK_NB` to avoid blocking on lock acquisition. + bitwise ORed with :const:`LOCK_NB` to avoid blocking on lock acquisition. If :const:`LOCK_NB` is used and the lock cannot be acquired, an :exc:`IOError` will be raised and the exception will have an *errno* attribute set to :const:`EACCES` or :const:`EAGAIN` (depending on the Modified: python/branches/py3k/Doc/library/functions.rst ============================================================================== --- python/branches/py3k/Doc/library/functions.rst (original) +++ python/branches/py3k/Doc/library/functions.rst Sun Jan 6 17:59:19 2008 @@ -227,7 +227,7 @@ the *flags* argument is it -- the future statements in effect around the call to compile are ignored. - Future statements are specified by bits which can be bitwise or-ed together to + Future statements are specified by bits which can be bitwise ORed together to specify multiple statements. The bitfield required to specify a given feature can be found as the :attr:`compiler_flag` attribute on the :class:`_Feature` instance in the :mod:`__future__` module. @@ -966,10 +966,11 @@ *cmp* specifies a custom comparison function of two arguments (iterable elements) which should return a negative, zero or positive number depending on whether the first argument is considered smaller than, equal to, or larger than - the second argument: ``cmp=lambda x,y: cmp(x.lower(), y.lower())`` + the second argument: ``cmp=lambda x,y: cmp(x.lower(), y.lower())``. The default + value is ``None``. *key* specifies a function of one argument that is used to extract a comparison - key from each list element: ``key=str.lower`` + key from each list element: ``key=str.lower``. The default value is ``None``. *reverse* is a boolean value. If set to ``True``, then the list elements are sorted as if each comparison were reversed. Modified: python/branches/py3k/Doc/library/msilib.rst ============================================================================== --- python/branches/py3k/Doc/library/msilib.rst (original) +++ python/branches/py3k/Doc/library/msilib.rst Sun Jan 6 17:59:19 2008 @@ -40,7 +40,7 @@ exposed. -.. function:: UUIDCreate() +.. function:: UuidCreate() Return the string representation of a new unique identifier. This wraps the Windows API functions :cfunc:`UuidCreate` and :cfunc:`UuidToString`. Modified: python/branches/py3k/Doc/library/msvcrt.rst ============================================================================== --- python/branches/py3k/Doc/library/msvcrt.rst (original) +++ python/branches/py3k/Doc/library/msvcrt.rst Sun Jan 6 17:59:19 2008 @@ -67,7 +67,7 @@ .. function:: open_osfhandle(handle, flags) Create a C runtime file descriptor from the file handle *handle*. The *flags* - parameter should be a bit-wise OR of :const:`os.O_APPEND`, :const:`os.O_RDONLY`, + parameter should be a bitwise OR of :const:`os.O_APPEND`, :const:`os.O_RDONLY`, and :const:`os.O_TEXT`. The returned file descriptor may be used as a parameter to :func:`os.fdopen` to create a file object. Modified: python/branches/py3k/Doc/library/numbers.rst ============================================================================== --- python/branches/py3k/Doc/library/numbers.rst (original) +++ python/branches/py3k/Doc/library/numbers.rst Sun Jan 6 17:59:19 2008 @@ -1,10 +1,10 @@ - :mod:`numbers` --- Numeric abstract base classes ================================================ .. module:: numbers :synopsis: Numeric abstract base classes (Complex, Real, Integral, etc.). + The :mod:`numbers` module (:pep:`3141`) defines a hierarchy of numeric abstract base classes which progressively define more operations. These concepts also provide a way to distinguish exact from inexact types. None of the types defined Modified: python/branches/py3k/Doc/library/os.rst ============================================================================== --- python/branches/py3k/Doc/library/os.rst (original) +++ python/branches/py3k/Doc/library/os.rst Sun Jan 6 17:59:19 2008 @@ -7,7 +7,7 @@ This module provides a more portable way of using operating system dependent -functionality than importing a operating system dependent built-in module like +functionality than importing an operating system dependent built-in module like :mod:`posix` or :mod:`nt`. If you just want to read or write a file see :func:`open`, if you want to manipulate paths, see the :mod:`os.path` module, and if you want to read all the lines in all the files on the @@ -17,7 +17,7 @@ This module searches for an operating system dependent built-in module like :mod:`mac` or :mod:`posix` and exports the same functions and data as found -there. The design of all Python's built-in operating system dependent modules +there. The design of all built-in operating system dependent modules of Python is such that as long as the same functionality is available, it uses the same interface; for example, the function ``os.stat(path)`` returns stat information about *path* in the same format (which happens to have originated with the POSIX @@ -132,7 +132,7 @@ .. function:: getegid() Return the effective group id of the current process. This corresponds to the - 'set id' bit on the file being executed in the current process. Availability: + "set id" bit on the file being executed in the current process. Availability: Unix. @@ -140,7 +140,7 @@ .. index:: single: user; effective id - Return the current process' effective user id. Availability: Unix. + Return the current process's effective user id. Availability: Unix. .. function:: getgid() @@ -162,7 +162,7 @@ process. For most purposes, it is more useful to use the environment variable :envvar:`LOGNAME` to find out who the user is, or ``pwd.getpwuid(os.getuid())[0]`` to get the login name of the currently - effective user ID. Availability: Unix. + effective user id. Availability: Unix. .. function:: getpgid(pid) @@ -196,7 +196,7 @@ .. index:: single: user; id - Return the current process' user id. Availability: Unix. + Return the current process's user id. Availability: Unix. .. function:: getenv(varname[, value]) @@ -245,20 +245,20 @@ Set the list of supplemental group ids associated with the current process to *groups*. *groups* must be a sequence, and each element must be an integer - identifying a group. This operation is typical available only to the superuser. + identifying a group. This operation is typically available only to the superuser. Availability: Unix. .. function:: setpgrp() - Calls the system call :cfunc:`setpgrp` or :cfunc:`setpgrp(0, 0)` depending on + Call the system call :cfunc:`setpgrp` or :cfunc:`setpgrp(0, 0)` depending on which version is implemented (if any). See the Unix manual for the semantics. Availability: Unix. .. function:: setpgid(pid, pgrp) - Calls the system call :cfunc:`setpgid` to set the process group id of the + Call the system call :cfunc:`setpgid` to set the process group id of the process with id *pid* to the process group with id *pgrp*. See the Unix manual for the semantics. Availability: Unix. @@ -275,13 +275,13 @@ .. function:: getsid(pid) - Calls the system call :cfunc:`getsid`. See the Unix manual for the semantics. + Call the system call :cfunc:`getsid`. See the Unix manual for the semantics. Availability: Unix. .. function:: setsid() - Calls the system call :cfunc:`setsid`. See the Unix manual for the semantics. + Call the system call :cfunc:`setsid`. See the Unix manual for the semantics. Availability: Unix. @@ -289,7 +289,7 @@ .. index:: single: user; id, setting - Set the current process' user id. Availability: Unix. + Set the current process's user id. Availability: Unix. .. placed in this section since it relates to errno.... a little weak @@ -301,7 +301,7 @@ .. function:: umask(mask) - Set the current numeric umask and returns the previous umask. Availability: + Set the current numeric umask and return the previous umask. Availability: Unix, Windows. @@ -491,9 +491,10 @@ .. function:: lseek(fd, pos, how) - Set the current position of file descriptor *fd* to position *pos*, modified by - *how*: ``0`` to set the position relative to the beginning of the file; ``1`` to - set it relative to the current position; ``2`` to set it relative to the end of + Set the current position of file descriptor *fd* to position *pos*, modified + by *how*: :const:`SEEK_SET` or ``0`` to set the position relative to the + beginning of the file; :const:`SEEK_CUR` or ``1`` to set it relative to the + current position; :const:`os.SEEK_END` or ``2`` to set it relative to the end of the file. Availability: Macintosh, Unix, Windows. @@ -522,7 +523,7 @@ Open a new pseudo-terminal pair. Return a pair of file descriptors ``(master, slave)`` for the pty and the tty, respectively. For a (slightly) more portable - approach, use the :mod:`pty` module. Availability: Macintosh, Some flavors of + approach, use the :mod:`pty` module. Availability: Macintosh, some flavors of Unix. @@ -543,7 +544,7 @@ This function is intended for low-level I/O and must be applied to a file descriptor as returned by :func:`open` or :func:`pipe`. To read a "file object" returned by the built-in function :func:`open` or by :func:`popen` or - :func:`fdopen`, or ``sys.stdin``, use its :meth:`read` or :meth:`readline` + :func:`fdopen`, or :data:`sys.stdin`, use its :meth:`read` or :meth:`readline` methods. @@ -576,7 +577,7 @@ This function is intended for low-level I/O and must be applied to a file descriptor as returned by :func:`open` or :func:`pipe`. To write a "file object" returned by the built-in function :func:`open` or by :func:`popen` or - :func:`fdopen`, or ``sys.stdout`` or ``sys.stderr``, use its :meth:`write` + :func:`fdopen`, or :data:`sys.stdout` or :data:`sys.stderr`, use its :meth:`write` method. The following data items are available for use in constructing the *flags* @@ -594,7 +595,7 @@ O_TRUNC Options for the *flag* argument to the :func:`open` function. These can be - bit-wise OR'd together. Availability: Macintosh, Unix, Windows. + combined using the bitwise OR operator ``|``. Availability: Macintosh, Unix, Windows. .. data:: O_DSYNC @@ -619,7 +620,7 @@ O_TEXT Options for the *flag* argument to the :func:`open` function. These can be - bit-wise OR'd together. Availability: Windows. + combined using the bitwise OR operator ``|``. Availability: Windows. .. data:: O_DIRECT @@ -749,7 +750,7 @@ .. function:: chmod(path, mode) Change the mode of *path* to the numeric *mode*. *mode* may take one of the - following values (as defined in the :mod:`stat` module) or bitwise or-ed + following values (as defined in the :mod:`stat` module) or bitwise ORed combinations of them: * ``stat.S_ISUID`` @@ -803,7 +804,7 @@ .. function:: lchown(path, uid, gid) - Change the owner and group id of *path* to the numeric *uid* and gid. This + Change the owner and group id of *path* to the numeric *uid* and *gid*. This function will not follow symbolic links. Availability: Macintosh, Unix. @@ -857,19 +858,19 @@ .. function:: major(device) - Extracts the device major number from a raw device number (usually the + Extract the device major number from a raw device number (usually the :attr:`st_dev` or :attr:`st_rdev` field from :ctype:`stat`). .. function:: minor(device) - Extracts the device minor number from a raw device number (usually the + Extract the device minor number from a raw device number (usually the :attr:`st_dev` or :attr:`st_rdev` field from :ctype:`stat`). .. function:: makedev(major, minor) - Composes a raw device number from the major and minor device numbers. + Compose a raw device number from the major and minor device numbers. .. function:: mkdir(path[, mode]) @@ -897,7 +898,7 @@ .. note:: :func:`makedirs` will become confused if the path elements to create include - *os.pardir*. + :data:`os.pardir`. This function handles UNC paths correctly. @@ -954,7 +955,7 @@ .. index:: single: directory; deleting - Removes directories recursively. Works like :func:`rmdir` except that, if the + Remove directories recursively. Works like :func:`rmdir` except that, if the leaf directory is successfully removed, :func:`removedirs` tries to successively remove every parent directory mentioned in *path* until an error is raised (which is ignored, because it generally means that a parent directory @@ -968,7 +969,7 @@ Rename the file or directory *src* to *dst*. If *dst* is a directory, :exc:`OSError` will be raised. On Unix, if *dst* exists and is a file, it will - be removed silently if the user has permission. The operation may fail on some + be replaced silently if the user has permission. The operation may fail on some Unix flavors if *src* and *dst* are on different filesystems. If successful, the renaming will be an atomic operation (this is a POSIX requirement). On Windows, if *dst* already exists, :exc:`OSError` will be raised even if it is a @@ -1000,7 +1001,7 @@ object whose attributes correspond to the members of the :ctype:`stat` structure, namely: :attr:`st_mode` (protection bits), :attr:`st_ino` (inode number), :attr:`st_dev` (device), :attr:`st_nlink` (number of hard links), - :attr:`st_uid` (user ID of owner), :attr:`st_gid` (group ID of owner), + :attr:`st_uid` (user id of owner), :attr:`st_gid` (group id of owner), :attr:`st_size` (size of file, in bytes), :attr:`st_atime` (time of most recent access), :attr:`st_mtime` (time of most recent content modification), :attr:`st_ctime` (platform dependent; time of most recent metadata change on @@ -1014,10 +1015,6 @@ 926L >>> - If :func:`stat_float_times` returns true, the time values are floats, measuring - seconds. Fractions of a second may be reported if the system supports that. On - Mac OS, the times are always floats. See :func:`stat_float_times` for further - discussion. On some Unix systems (such as Linux), the following attributes may also be available: :attr:`st_blocks` (number of blocks allocated for file), @@ -1131,8 +1128,8 @@ single: directory; walking single: directory; traversal - :func:`walk` generates the file names in a directory tree, by walking the tree - either top down or bottom up. For each directory in the tree rooted at directory + Generate the file names in a directory tree by walking the tree + either top-down or bottom-up. For each directory in the tree rooted at directory *top* (including *top* itself), it yields a 3-tuple ``(dirpath, dirnames, filenames)``. @@ -1143,34 +1140,34 @@ (which begins with *top*) to a file or directory in *dirpath*, do ``os.path.join(dirpath, name)``. - If optional argument *topdown* is true or not specified, the triple for a + If optional argument *topdown* is ``True`` or not specified, the triple for a directory is generated before the triples for any of its subdirectories - (directories are generated top down). If *topdown* is false, the triple for a + (directories are generated top-down). If *topdown* is ``False``, the triple for a directory is generated after the triples for all of its subdirectories - (directories are generated bottom up). + (directories are generated bottom-up). - When *topdown* is true, the caller can modify the *dirnames* list in-place + When *topdown* is ``True``, the caller can modify the *dirnames* list in-place (perhaps using :keyword:`del` or slice assignment), and :func:`walk` will only recurse into the subdirectories whose names remain in *dirnames*; this can be used to prune the search, impose a specific order of visiting, or even to inform :func:`walk` about directories the caller creates or renames before it resumes - :func:`walk` again. Modifying *dirnames* when *topdown* is false is + :func:`walk` again. Modifying *dirnames* when *topdown* is ``False`` is ineffective, because in bottom-up mode the directories in *dirnames* are generated before *dirpath* itself is generated. - By default errors from the ``os.listdir()`` call are ignored. If optional + By default errors from the :func:`listdir` call are ignored. If optional argument *onerror* is specified, it should be a function; it will be called with one argument, an :exc:`OSError` instance. It can report the error to continue with the walk, or raise the exception to abort the walk. Note that the filename is available as the ``filename`` attribute of the exception object. By default, :func:`walk` will not walk down into symbolic links that resolve to - directories. Set *followlinks* to True to visit directories pointed to by + directories. Set *followlinks* to ``True`` to visit directories pointed to by symlinks, on systems that support them. .. note:: - Be aware that setting *followlinks* to true can lead to infinite recursion if a + Be aware that setting *followlinks* to ``True`` can lead to infinite recursion if a link points to a parent directory of itself. :func:`walk` does not keep track of the directories it visited already. @@ -1193,10 +1190,10 @@ if 'CVS' in dirs: dirs.remove('CVS') # don't visit CVS directories - In the next example, walking the tree bottom up is essential: :func:`rmdir` + In the next example, walking the tree bottom-up is essential: :func:`rmdir` doesn't allow deleting a directory before the directory is empty:: - # Delete everything reachable from the directory named in 'top', + # Delete everything reachable from the directory named in "top", # assuming there are no symbolic links. # CAUTION: This is dangerous! For example, if top == '/', it # could delete all your disk files. @@ -1244,19 +1241,19 @@ These functions all execute a new program, replacing the current process; they do not return. On Unix, the new executable is loaded into the current process, - and will have the same process ID as the caller. Errors will be reported as + and will have the same process id as the caller. Errors will be reported as :exc:`OSError` exceptions. - The ``'l'`` and ``'v'`` variants of the :func:`exec\*` functions differ in how - command-line arguments are passed. The ``'l'`` variants are perhaps the easiest + The "l" and "v" variants of the :func:`exec\*` functions differ in how + command-line arguments are passed. The "l" variants are perhaps the easiest to work with if the number of parameters is fixed when the code is written; the individual parameters simply become additional parameters to the :func:`execl\*` - functions. The ``'v'`` variants are good when the number of parameters is + functions. The "v" variants are good when the number of parameters is variable, with the arguments being passed in a list or tuple as the *args* parameter. In either case, the arguments to the child process should start with the name of the command being run, but this is not enforced. - The variants which include a ``'p'`` near the end (:func:`execlp`, + The variants which include a "p" near the end (:func:`execlp`, :func:`execlpe`, :func:`execvp`, and :func:`execvpe`) will use the :envvar:`PATH` environment variable to locate the program *file*. When the environment is being replaced (using one of the :func:`exec\*e` variants, @@ -1267,7 +1264,7 @@ path. For :func:`execle`, :func:`execlpe`, :func:`execve`, and :func:`execvpe` (note - that these all end in ``'e'``), the *env* parameter must be a mapping which is + that these all end in "e"), the *env* parameter must be a mapping which is used to define the environment variables for the new process; the :func:`execl`, :func:`execlp`, :func:`execv`, and :func:`execvp` all cause the new process to inherit the environment of the current process. Availability: Macintosh, Unix, @@ -1284,7 +1281,7 @@ The standard way to exit is ``sys.exit(n)``. :func:`_exit` should normally only be used in the child process after a :func:`fork`. -The following exit codes are a defined, and can be used with :func:`_exit`, +The following exit codes are defined and can be used with :func:`_exit`, although they are not required. These are typically used for system programs written in Python, such as a mail server's external command delivery program. @@ -1400,7 +1397,7 @@ .. function:: fork() - Fork a child process. Return ``0`` in the child, the child's process id in the + Fork a child process. Return ``0`` in the child and the child's process id in the parent. Availability: Macintosh, Unix. @@ -1410,7 +1407,7 @@ terminal. Return a pair of ``(pid, fd)``, where *pid* is ``0`` in the child, the new child's process id in the parent, and *fd* is the file descriptor of the master end of the pseudo-terminal. For a more portable approach, use the - :mod:`pty` module. Availability: Macintosh, Some flavors of Unix. + :mod:`pty` module. Availability: Macintosh, some flavors of Unix. .. function:: kill(pid, sig) @@ -1469,22 +1466,22 @@ spawning new processes and retrieving their results; using that module is preferable to using these functions.) - If *mode* is :const:`P_NOWAIT`, this function returns the process ID of the new + If *mode* is :const:`P_NOWAIT`, this function returns the process id of the new process; if *mode* is :const:`P_WAIT`, returns the process's exit code if it exits normally, or ``-signal``, where *signal* is the signal that killed the - process. On Windows, the process ID will actually be the process handle, so can + process. On Windows, the process id will actually be the process handle, so can be used with the :func:`waitpid` function. - The ``'l'`` and ``'v'`` variants of the :func:`spawn\*` functions differ in how - command-line arguments are passed. The ``'l'`` variants are perhaps the easiest + The "l" and "v" variants of the :func:`spawn\*` functions differ in how + command-line arguments are passed. The "l" variants are perhaps the easiest to work with if the number of parameters is fixed when the code is written; the individual parameters simply become additional parameters to the - :func:`spawnl\*` functions. The ``'v'`` variants are good when the number of + :func:`spawnl\*` functions. The "v" variants are good when the number of parameters is variable, with the arguments being passed in a list or tuple as the *args* parameter. In either case, the arguments to the child process must start with the name of the command being run. - The variants which include a second ``'p'`` near the end (:func:`spawnlp`, + The variants which include a second "p" near the end (:func:`spawnlp`, :func:`spawnlpe`, :func:`spawnvp`, and :func:`spawnvpe`) will use the :envvar:`PATH` environment variable to locate the program *file*. When the environment is being replaced (using one of the :func:`spawn\*e` variants, @@ -1495,7 +1492,7 @@ appropriate absolute or relative path. For :func:`spawnle`, :func:`spawnlpe`, :func:`spawnve`, and :func:`spawnvpe` - (note that these all end in ``'e'``), the *env* parameter must be a mapping + (note that these all end in "e"), the *env* parameter must be a mapping which is used to define the environment variables for the new process; the :func:`spawnl`, :func:`spawnlp`, :func:`spawnv`, and :func:`spawnvp` all cause the new process to inherit the environment of the current process. @@ -1518,7 +1515,7 @@ Possible values for the *mode* parameter to the :func:`spawn\*` family of functions. If either of these values is given, the :func:`spawn\*` functions - will return as soon as the new process has been created, with the process ID as + will return as soon as the new process has been created, with the process id as the return value. Availability: Macintosh, Unix, Windows. @@ -1569,8 +1566,8 @@ Execute the command (a string) in a subshell. This is implemented by calling the Standard C function :cfunc:`system`, and has the same limitations. Changes - to ``posix.environ``, ``sys.stdin``, etc. are not reflected in the environment - of the executed command. + to :data:`os.environ`, :data:`sys.stdin`, etc. are not reflected in the + environment of the executed command. On Unix, the return value is the exit status of the process encoded in the format specified for :func:`wait`. Note that POSIX does not specify the meaning @@ -1681,32 +1678,32 @@ .. function:: WCOREDUMP(status) - Returns ``True`` if a core dump was generated for the process, otherwise it - returns ``False``. Availability: Macintosh, Unix. + Return ``True`` if a core dump was generated for the process, otherwise + return ``False``. Availability: Macintosh, Unix. .. function:: WIFCONTINUED(status) - Returns ``True`` if the process has been continued from a job control stop, - otherwise it returns ``False``. Availability: Unix. + Return ``True`` if the process has been continued from a job control stop, + otherwise return ``False``. Availability: Unix. .. function:: WIFSTOPPED(status) - Returns ``True`` if the process has been stopped, otherwise it returns + Return ``True`` if the process has been stopped, otherwise return ``False``. Availability: Unix. .. function:: WIFSIGNALED(status) - Returns ``True`` if the process exited due to a signal, otherwise it returns + Return ``True`` if the process exited due to a signal, otherwise return ``False``. Availability: Macintosh, Unix. .. function:: WIFEXITED(status) - Returns ``True`` if the process exited using the :manpage:`exit(2)` system call, - otherwise it returns ``False``. Availability: Macintosh, Unix. + Return ``True`` if the process exited using the :manpage:`exit(2)` system call, + otherwise return ``False``. Availability: Macintosh, Unix. .. function:: WEXITSTATUS(status) @@ -1783,7 +1780,7 @@ defined for those names by the host operating system. This can be used to determine the set of names known to the system. Availability: Macintosh, Unix. -The follow data values are used to support path manipulation operations. These +The following data values are used to support path manipulation operations. These are defined for all platforms. Higher-level operations on pathnames are defined in the :mod:`os.path` module. Modified: python/branches/py3k/Doc/library/socket.rst ============================================================================== --- python/branches/py3k/Doc/library/socket.rst (original) +++ python/branches/py3k/Doc/library/socket.rst Sun Jan 6 17:59:19 2008 @@ -155,6 +155,12 @@ in the Unix header files are defined; for a few symbols, default values are provided. +.. data:: SIO_* + RCVALL_* + + Constants for Windows' WSAIoctl(). The constants are used as arguments to the + :meth:`ioctl` method of socket objects. + .. data:: has_ipv6 @@ -524,6 +530,14 @@ contents of the buffer (see the optional built-in module :mod:`struct` for a way to decode C structures encoded as strings). + +.. method:: socket.ioctl(control, option) + + :platform: Windows + + The `meth:ioctl` method is a limited interface to the WSAIoctl system + interface. Please refer to the MSDN documentation for more information. + .. method:: socket.listen(backlog) @@ -822,3 +836,28 @@ s.close() print('Received', repr(data)) + +The last example shows how to write a very simple network sniffer with raw +sockets on Windows. The example requires administrator priviliges to modify +the interface:: + + import socket + + # the public network interface + HOST = socket.gethostbyname(socket.gethostname()) + + # create a raw socket and bind it to the public interface + s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP) + s.bind((HOST, 0)) + + # Include IP headers + s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) + + # receive all packages + s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON) + + # receive a package + print s.recvfrom(65565) + + # disabled promiscous mode + s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF) Modified: python/branches/py3k/Doc/library/stdtypes.rst ============================================================================== --- python/branches/py3k/Doc/library/stdtypes.rst (original) +++ python/branches/py3k/Doc/library/stdtypes.rst Sun Jan 6 17:59:19 2008 @@ -352,6 +352,23 @@ or "-" for Not a Number (NaN) and positive or negative infinity. +All :class:`numbers.Real` types (:class:`int` and +:class:`float`) also include the following operations: + ++--------------------+--------------------------------+--------+ +| Operation | Result | Notes | ++====================+================================+========+ +| ``trunc(x)`` | *x* truncated to Integral | | ++--------------------+--------------------------------+--------+ +| ``round(x[, n])`` | *x* rounded to n digits, | | +| | rounding half to even. If n is | | +| | omitted, it defaults to 0. | | ++--------------------+--------------------------------+--------+ +| ``math.floor(x)`` | the greatest Integral <= *x* | | ++--------------------+--------------------------------+--------+ +| ``math.ceil(x)`` | the least Integral >= *x* | | ++--------------------+--------------------------------+--------+ + .. XXXJH exceptions: overflow (when? what operations?) zerodivision @@ -366,7 +383,7 @@ Negative numbers are treated as their 2's complement value (this assumes a sufficiently large number of bits that no overflow occurs during the operation). -The priorities of the binary bit-wise operations are all lower than the numeric +The priorities of the binary bitwise operations are all lower than the numeric operations and higher than the comparisons; the unary operation ``~`` has the same priority as the other unary numeric operations (``+`` and ``-``). @@ -1319,10 +1336,11 @@ *cmp* specifies a custom comparison function of two arguments (list items) which should return a negative, zero or positive number depending on whether the first argument is considered smaller than, equal to, or larger than the second - argument: ``cmp=lambda x,y: cmp(x.lower(), y.lower())`` + argument: ``cmp=lambda x,y: cmp(x.lower(), y.lower())``. The default value + is ``None``. *key* specifies a function of one argument that is used to extract a comparison - key from each list element: ``key=str.lower`` + key from each list element: ``key=str.lower``. The default value is ``None``. *reverse* is a boolean value. If set to ``True``, then the list elements are sorted as if each comparison were reversed. @@ -2005,7 +2023,12 @@ argument is optional and defaults to ``os.SEEK_SET`` or ``0`` (absolute file positioning); other values are ``os.SEEK_CUR`` or ``1`` (seek relative to the current position) and ``os.SEEK_END`` or ``2`` (seek relative to the file's - end). There is no return value. Note that if the file is opened for appending + end). There is no return value. + + For example, ``f.seek(2, os.SEEK_CUR)`` advances the position by two and + ``f.seek(-3, os.SEEK_END)`` sets the position to the third to last. + + Note that if the file is opened for appending (mode ``'a'`` or ``'a+'``), any :meth:`seek` operations will be undone at the next write. If the file is only opened for writing in append mode (mode ``'a'``), this method is essentially a no-op, but it remains useful for files @@ -2138,7 +2161,7 @@ the context expression in a :keyword:`with` statement. An example of a context manager that returns a related object is the one - returned by ``decimal.Context.get_manager()``. These managers set the active + returned by :func:`decimal.localcontext`. These managers set the active decimal context to a copy of the original decimal context and then return the copy. This allows changes to be made to the current decimal context in the body of the :keyword:`with` statement without affecting code outside the Modified: python/branches/py3k/Doc/library/thread.rst ============================================================================== --- python/branches/py3k/Doc/library/thread.rst (original) +++ python/branches/py3k/Doc/library/thread.rst Sun Jan 6 17:59:19 2008 @@ -132,7 +132,6 @@ In addition to these methods, lock objects can also be used via the :keyword:`with` statement, e.g.:: - from __future__ import with_statement import thread a_lock = thread.allocate_lock() Modified: python/branches/py3k/Doc/library/threading.rst ============================================================================== --- python/branches/py3k/Doc/library/threading.rst (original) +++ python/branches/py3k/Doc/library/threading.rst Sun Jan 6 17:59:19 2008 @@ -716,7 +716,6 @@ :class:`Semaphore`, and :class:`BoundedSemaphore` objects may be used as :keyword:`with` statement context managers. For example:: - from __future__ import with_statement import threading some_rlock = threading.RLock() Modified: python/branches/py3k/Doc/library/winsound.rst ============================================================================== --- python/branches/py3k/Doc/library/winsound.rst (original) +++ python/branches/py3k/Doc/library/winsound.rst Sun Jan 6 17:59:19 2008 @@ -32,7 +32,7 @@ Call the underlying :cfunc:`PlaySound` function from the Platform API. The *sound* parameter may be a filename, audio data as a string, or ``None``. Its - interpretation depends on the value of *flags*, which can be a bit-wise ORed + interpretation depends on the value of *flags*, which can be a bitwise ORed combination of the constants described below. If the system indicates an error, :exc:`RuntimeError` is raised. Modified: python/branches/py3k/Doc/reference/compound_stmts.rst ============================================================================== --- python/branches/py3k/Doc/reference/compound_stmts.rst (original) +++ python/branches/py3k/Doc/reference/compound_stmts.rst Sun Jan 6 17:59:19 2008 @@ -78,7 +78,10 @@ The :keyword:`if` statement =========================== -.. index:: statement: if +.. index:: + statement: if + keyword: elif + keyword: else keyword: elif keyword: else @@ -105,6 +108,7 @@ statement: while keyword: else pair: loop; statement + keyword: else The :keyword:`while` statement is used for repeated execution as long as an expression is true: @@ -139,6 +143,9 @@ keyword: else pair: target; list pair: loop; statement + keyword: in + keyword: else + pair: target; list object: sequence The :keyword:`for` statement is used to iterate over the elements of a sequence @@ -208,7 +215,10 @@ The :keyword:`try` statement ============================ -.. index:: statement: try +.. index:: + statement: try + keyword: except + keyword: finally .. index:: keyword: except The :keyword:`try` statement specifies exception handlers and/or cleanup code @@ -223,7 +233,8 @@ try2_stmt: "try" ":" `suite` : "finally" ":" `suite` -The :keyword:`except` clause(s) specify one or more exception handlers. When no + +The :keyword:`except` clause(s) specify one or more exception handlers. When no exception occurs in the :keyword:`try` clause, no exception handler is executed. When an exception occurs in the :keyword:`try` suite, a search for an exception handler is started. This search inspects the except clauses in turn until one @@ -379,6 +390,10 @@ location for the kind of exit that was taken. + In Python 2.5, the :keyword:`with` statement is only allowed when the + ``with_statement`` feature has been enabled. It is always enabled in + Python 2.6. + .. seealso:: :pep:`0343` - The "with" statement @@ -393,8 +408,10 @@ ==================== .. index:: - pair: function; definition statement: def + pair: function; definition + pair: function; name + pair: name; binding object: user-defined function object: function pair: function; name @@ -513,13 +530,13 @@ ================= .. index:: - pair: class; definition - statement: class object: class - single: inheritance + statement: class + pair: class; definition pair: class; name pair: name; binding pair: execution; frame + single: inheritance A class definition defines a class object (see section :ref:`types`): @@ -554,13 +571,13 @@ Foo = f1(arg)(f2(Foo)) **Programmer's note:** Variables defined in the class definition are class -variables; they are shared by all instances. To define instance variables, they -must be given a value in the :meth:`__init__` method or in another method. Both -class and instance variables are accessible through the notation -"``self.name``", and an instance variable hides a class variable with the same -name when accessed in this way. Class variables with immutable values can be -used as defaults for instance variables. Descriptors can be used to create -instance variables with different implementation details. +can be set in a method with ``self.name = value``. Both class and instance +variables are accessible through the notation "``self.name``", and an instance +variable hides a class variable with the same name when accessed in this way. +Class variables can be used as defaults for instance variables, but using +mutable values there can lead to unexpected results. For :term:`new-style +class`\es, descriptors can be used to create instance variables with different +implementation details. .. XXX add link to descriptor docs above Modified: python/branches/py3k/Doc/reference/datamodel.rst ============================================================================== --- python/branches/py3k/Doc/reference/datamodel.rst (original) +++ python/branches/py3k/Doc/reference/datamodel.rst Sun Jan 6 17:59:19 2008 @@ -1011,16 +1011,17 @@ in case of multiple inheritance. This manual is not up-to-date with respect to new-style classes. For now, -please see http://www.python.org/doc/newstyle.html for more information. +please see http://www.python.org/doc/newstyle/ for more information. .. index:: - single: class - single: class - single: class + single: class; new-style + single: class; classic + single: class; old-style The plan is to eventually drop old-style classes, leaving only the semantics of new-style classes. This change will probably only be feasible in Python 3.0. -new-style classic old-style + +XXX Remove old style classes from docs .. _specialnames: @@ -1902,6 +1903,18 @@ .. rubric:: Footnotes +.. [#] Since Python 2.2, a gradual merging of types and classes has been started that + makes this and a few other assertions made in this manual not 100% accurate and + complete: for example, it *is* now possible in some cases to change an object's + type, under certain controlled conditions. Until this manual undergoes + extensive revision, it must now be taken as authoritative only regarding + "classic classes", that are still the default, for compatibility purposes, in + Python 2.2 and 2.3. For more information, see + http://www.python.org/doc/newstyle/. + +.. [#] This, and other statements, are only roughly true for instances of new-style + classes. + .. [#] A descriptor can define any combination of :meth:`__get__`, :meth:`__set__` and :meth:`__delete__`. If it does not define :meth:`__get__`, then accessing the attribute even on an instance will return the descriptor Modified: python/branches/py3k/Doc/reference/expressions.rst ============================================================================== --- python/branches/py3k/Doc/reference/expressions.rst (original) +++ python/branches/py3k/Doc/reference/expressions.rst Sun Jan 6 17:59:19 2008 @@ -769,7 +769,7 @@ Raising ``0.0`` to a negative power results in a :exc:`ZeroDivisionError`. Raising a negative number to a fractional power results in a :class:`complex` -number. (Since Python 2.6. In earlier versions it raised a :exc:`ValueError`.) +number. (In earlier versions it raised a :exc:`ValueError`.) .. _unary: @@ -779,9 +779,9 @@ .. index:: triple: unary; arithmetic; operation - triple: unary; bit-wise; operation + triple: unary; bitwise; operation -All unary arithmetic (and bit-wise) operations have the same priority: +All unary arithmetic (and bitwise) operations have the same priority: .. productionlist:: u_expr: `power` | "-" `u_expr` | "+" `u_expr` | "~" `u_expr` @@ -798,9 +798,10 @@ .. index:: single: inversion -The unary ``~`` (invert) operator yields the bit-wise inversion of its integer -argument. The bit-wise inversion of ``x`` is defined as ``-(x+1)``. It only -applies to integral numbers. + +The unary ``~`` (invert) operator yields the bitwise inversion of its plain or +long integer argument. The bitwise inversion of ``x`` is defined as +``-(x+1)``. It only applies to integral numbers. .. index:: exception: TypeError @@ -905,10 +906,10 @@ .. _bitwise: -Binary bit-wise operations -========================== +Binary bitwise operations +========================= -.. index:: triple: binary; bit-wise; operation +.. index:: triple: binary; bitwise; operation Each of the three bitwise operations has a different priority level: @@ -917,20 +918,20 @@ xor_expr: `and_expr` | `xor_expr` "^" `and_expr` or_expr: `xor_expr` | `or_expr` "|" `xor_expr` -.. index:: pair: bit-wise; and +.. index:: pair: bitwise; and The ``&`` operator yields the bitwise AND of its arguments, which must be integers. .. index:: - pair: bit-wise; xor + pair: bitwise; xor pair: exclusive; or The ``^`` operator yields the bitwise XOR (exclusive OR) of its arguments, which must be integers. .. index:: - pair: bit-wise; or + pair: bitwise; or pair: inclusive; or The ``|`` operator yields the bitwise (inclusive) OR of its arguments, which Modified: python/branches/py3k/Doc/reference/simple_stmts.rst ============================================================================== --- python/branches/py3k/Doc/reference/simple_stmts.rst (original) +++ python/branches/py3k/Doc/reference/simple_stmts.rst Sun Jan 6 17:59:19 2008 @@ -33,7 +33,9 @@ Expression statements ===================== -.. index:: pair: expression; statement +.. index:: + pair: expression; statement + pair: expression; list .. index:: pair: expression; list Expression statements are used (mostly interactively) to compute and write a @@ -327,7 +329,9 @@ The :keyword:`pass` statement ============================= -.. index:: statement: pass +.. index:: + statement: pass + pair: null; operation pair: null; operation .. productionlist:: @@ -347,9 +351,10 @@ The :keyword:`del` statement ============================ -.. index:: statement: del - pair: deletion; target - triple: deletion; target; list +.. index:: + statement: del + pair: deletion; target + triple: deletion; target; list .. productionlist:: del_stmt: "del" `target_list` @@ -386,9 +391,10 @@ The :keyword:`return` statement =============================== -.. index:: statement: return - pair: function; definition - pair: class; definition +.. index:: + statement: return + pair: function; definition + pair: class; definition .. productionlist:: return_stmt: "return" [`expression_list`] @@ -418,23 +424,34 @@ The :keyword:`yield` statement ============================== +.. index:: + statement: yield + single: generator; function + single: generator; iterator + single: function; generator + exception: StopIteration + .. productionlist:: yield_stmt: `yield_expression` -The yield statement is nothing but a yield expression used as a statement, -see :ref:`yieldexpr`. - +The :keyword:`yield` statement is only used when defining a generator function, +and is only used in the body of the generator function. Using a :keyword:`yield` +statement in a function definition is sufficient to cause that definition to +create a generator function instead of a normal function. +>>>>>>> .merge-right.r59773 .. _raise: The :keyword:`raise` statement ============================== -.. index:: statement: raise - pair: raising; exception +.. index:: + statement: raise + single: exception + pair: raising; exception .. productionlist:: - raise_stmt: "raise" [`expression` ["from" `expression`]] + raise_stmt: "raise" [`expression` ["," `expression` ["," `expression`]]] If no expressions are present, :keyword:`raise` re-raises the last exception that was active in the current scope. If no exception is active in the current @@ -476,10 +493,11 @@ The :keyword:`break` statement ============================== -.. index:: statement: break - statement: for - statement: while - pair: loop; statement +.. index:: + statement: break + statement: for + statement: while + pair: loop; statement .. productionlist:: break_stmt: "break" @@ -509,11 +527,12 @@ The :keyword:`continue` statement ================================= -.. index:: statement: continue - statement: for - statement: while - pair: loop; statement - keyword: finally +.. index:: + statement: continue + statement: for + statement: while + pair: loop; statement + keyword: finally .. productionlist:: continue_stmt: "continue" @@ -631,6 +650,7 @@ .. index:: keyword: from + statement: from triple: hierarchical; module; names single: packages single: __init__.py @@ -731,13 +751,13 @@ The :keyword:`global` statement =============================== -.. index:: statement: global +.. index:: + statement: global + triple: global; name; binding .. productionlist:: global_stmt: "global" `identifier` ("," `identifier`)* -.. index:: triple: global; name; binding - The :keyword:`global` statement is a declaration which holds for the entire current code block. It means that the listed identifiers are to be interpreted as globals. It would be impossible to assign to a global variable without @@ -789,11 +809,6 @@ first. The statement allows encapsulated code to rebind variables outside of the local scope besides the global (module) scope. -.. note:: - - The outer scope for :keyword:`nonlocal` statements cannot be the module - scope. - .. XXX not implemented The :keyword:`nonlocal` statement may prepend an assignment or augmented assignment, but not an expression. Modified: python/branches/py3k/Doc/whatsnew/2.6.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/2.6.rst (original) +++ python/branches/py3k/Doc/whatsnew/2.6.rst Sun Jan 6 17:59:19 2008 @@ -503,10 +503,12 @@ @abstractmethod decorator -- you can't instantiate classes w/ an abstract method. - at abstractproperty decorator - at abstractproperty -def readonly(self): - return self._x +:: + + @abstractproperty decorator + @abstractproperty + def readonly(self): + return self._x .. seealso:: @@ -1163,7 +1165,7 @@ esoteric bugfixes, that may require changes to your code: -* The :method:`__init__` method of :class:`collections.deque` +* The :meth:`__init__` method of :class:`collections.deque` now clears any existing contents of the deque before adding elements from the iterable. This change makes the behavior match that of ``list.__init__()``. Modified: python/branches/py3k/Lib/collections.py ============================================================================== --- python/branches/py3k/Lib/collections.py (original) +++ python/branches/py3k/Lib/collections.py Sun Jan 6 17:59:19 2008 @@ -54,15 +54,23 @@ seen_names.add(name) # Create and fill-in the class template + numfields = len(field_names) argtxt = repr(field_names).replace("'", "")[1:-1] # tuple repr without parens or quotes reprtxt = ', '.join('%s=%%r' % name for name in field_names) dicttxt = ', '.join('%r: t[%d]' % (name, pos) for pos, name in enumerate(field_names)) template = '''class %(typename)s(tuple): '%(typename)s(%(argtxt)s)' \n __slots__ = () \n + _fields = %(field_names)r \n def __new__(cls, %(argtxt)s): return tuple.__new__(cls, (%(argtxt)s)) \n - _cast = classmethod(tuple.__new__) \n + @classmethod + def _make(cls, iterable): + 'Make a new %(typename)s object from a sequence or iterable' + result = tuple.__new__(cls, iterable) + if len(result) != %(numfields)d: + raise TypeError('Expected %(numfields)d arguments, got %%d' %% len(result)) + return result \n def __repr__(self): return '%(typename)s(%(reprtxt)s)' %% self \n def _asdict(t): @@ -70,10 +78,10 @@ return {%(dicttxt)s} \n def _replace(self, **kwds): 'Return a new %(typename)s object replacing specified fields with new values' - return %(typename)s._cast(map(kwds.get, %(field_names)r, self)) \n - @property - def _fields(self): - return %(field_names)r \n\n''' % locals() + result = self._make(map(kwds.pop, %(field_names)r, self)) + if kwds: + raise ValueError('Got unexpected field names: %%r' %% kwds.keys()) + return result \n\n''' % locals() for i, name in enumerate(field_names): template += ' %s = property(itemgetter(%d))\n' % (name, i) if verbose: Modified: python/branches/py3k/Lib/ntpath.py ============================================================================== --- python/branches/py3k/Lib/ntpath.py (original) +++ python/branches/py3k/Lib/ntpath.py Sun Jan 6 17:59:19 2008 @@ -254,12 +254,10 @@ except os.error: return func(arg, top, names) - exceptions = ('.', '..') for name in names: - if name not in exceptions: - name = join(top, name) - if isdir(name): - walk(name, func, arg) + name = join(top, name) + if isdir(name): + walk(name, func, arg) # Expand paths beginning with '~' or '~user'. @@ -492,4 +490,6 @@ i += 1 rel_list = [pardir] * (len(start_list)-i) + path_list[i:] + if not rel_list: + return curdir return join(*rel_list) Modified: python/branches/py3k/Lib/posixpath.py ============================================================================== --- python/branches/py3k/Lib/posixpath.py (original) +++ python/branches/py3k/Lib/posixpath.py Sun Jan 6 17:59:19 2008 @@ -178,8 +178,8 @@ def ismount(path): """Test whether a path is a mount point""" try: - s1 = os.stat(path) - s2 = os.stat(join(path, '..')) + s1 = os.lstat(path) + s2 = os.lstat(join(path, '..')) except os.error: return False # It doesn't exist -- so not a mount point :-) dev1 = s1.st_dev @@ -398,4 +398,6 @@ i = len(commonprefix([start_list, path_list])) rel_list = [pardir] * (len(start_list)-i) + path_list[i:] + if not rel_list: + return curdir return join(*rel_list) Modified: python/branches/py3k/Lib/tarfile.py ============================================================================== --- python/branches/py3k/Lib/tarfile.py (original) +++ python/branches/py3k/Lib/tarfile.py Sun Jan 6 17:59:19 2008 @@ -2021,11 +2021,11 @@ # Set correct owner, mtime and filemode on directories. for tarinfo in directories: - path = os.path.join(path, tarinfo.name) + dirpath = os.path.join(path, tarinfo.name) try: - self.chown(tarinfo, path) - self.utime(tarinfo, path) - self.chmod(tarinfo, path) + self.chown(tarinfo, dirpath) + self.utime(tarinfo, dirpath) + self.chmod(tarinfo, dirpath) except ExtractError as e: if self.errorlevel > 1: raise Modified: python/branches/py3k/Lib/test/test_collections.py ============================================================================== --- python/branches/py3k/Lib/test/test_collections.py (original) +++ python/branches/py3k/Lib/test/test_collections.py Sun Jan 6 17:59:19 2008 @@ -20,6 +20,7 @@ self.assertEqual(Point.__slots__, ()) self.assertEqual(Point.__module__, __name__) self.assertEqual(Point.__getitem__, tuple.__getitem__) + self.assertEqual(Point._fields, ('x', 'y')) self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword @@ -34,6 +35,9 @@ namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names namedtuple('_', 'a b c') # Test leading underscores in a typename + self.assertRaises(TypeError, Point._make, [11]) # catch too few args + self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args + def test_instance(self): Point = namedtuple('Point', 'x y') p = Point(11, 22) @@ -49,18 +53,17 @@ self.assertEqual(repr(p), 'Point(x=11, y=22)') self.assert_('__dict__' not in dir(p)) # verify instance has no dict self.assert_('__weakref__' not in dir(p)) - self.assertEqual(p, Point._cast([11, 22])) # test _cast classmethod + self.assertEqual(p, Point._make([11, 22])) # test _make classmethod self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method - # Verify that _fields is read-only try: - p._fields = ('F1' ,'F2') - except AttributeError: + p._replace(x=1, error=2) + except ValueError: pass else: - self.fail('The _fields attribute needs to be read-only') + self._fail('Did not detect an incorrect fieldname') # verify that field string can have commas Point = namedtuple('Point', 'x, y') @@ -94,14 +97,14 @@ def test_odd_sizes(self): Zero = namedtuple('Zero', '') self.assertEqual(Zero(), ()) - self.assertEqual(Zero._cast([]), ()) + self.assertEqual(Zero._make([]), ()) self.assertEqual(repr(Zero()), 'Zero()') self.assertEqual(Zero()._asdict(), {}) self.assertEqual(Zero()._fields, ()) Dot = namedtuple('Dot', 'd') self.assertEqual(Dot(1), (1,)) - self.assertEqual(Dot._cast([1]), (1,)) + self.assertEqual(Dot._make([1]), (1,)) self.assertEqual(Dot(1).d, 1) self.assertEqual(repr(Dot(1)), 'Dot(d=1)') self.assertEqual(Dot(1)._asdict(), {'d':1}) @@ -115,7 +118,7 @@ Big = namedtuple('Big', names) b = Big(*range(n)) self.assertEqual(b, tuple(range(n))) - self.assertEqual(Big._cast(range(n)), tuple(range(n))) + self.assertEqual(Big._make(range(n)), tuple(range(n))) for pos, name in enumerate(names): self.assertEqual(getattr(b, name), pos) repr(b) # make sure repr() doesn't blow-up Modified: python/branches/py3k/Lib/test/test_doctest.py ============================================================================== --- python/branches/py3k/Lib/test/test_doctest.py (original) +++ python/branches/py3k/Lib/test/test_doctest.py Sun Jan 6 17:59:19 2008 @@ -909,7 +909,7 @@ Several option flags can be used to customize the behavior of the test runner. These are defined as module constants in doctest, and passed -to the DocTestRunner constructor (multiple constants should be or-ed +to the DocTestRunner constructor (multiple constants should be ORed together). The DONT_ACCEPT_TRUE_FOR_1 flag disables matches between True/False Modified: python/branches/py3k/Lib/test/test_ntpath.py ============================================================================== --- python/branches/py3k/Lib/test/test_ntpath.py (original) +++ python/branches/py3k/Lib/test/test_ntpath.py Sun Jan 6 17:59:19 2008 @@ -166,6 +166,7 @@ tester('ntpath.relpath("a/b", "../c")', '..\\'+currentdir+'\\a\\b') tester('ntpath.relpath("a", "b/c")', '..\\..\\a') tester('ntpath.relpath("//conky/mountpoint/a", "//conky/mountpoint/b/c")', '..\\..\\a') +tester('ntpath.relpath("a", "a")', '.') if errors: raise TestFailed(str(errors) + " errors.") Modified: python/branches/py3k/Lib/test/test_posixpath.py ============================================================================== --- python/branches/py3k/Lib/test/test_posixpath.py (original) +++ python/branches/py3k/Lib/test/test_posixpath.py Sun Jan 6 17:59:19 2008 @@ -501,6 +501,7 @@ self.assertEqual(posixpath.relpath("a", "../b"), "../"+curdir+"/a") self.assertEqual(posixpath.relpath("a/b", "../c"), "../"+curdir+"/a/b") self.assertEqual(posixpath.relpath("a", "b/c"), "../../a") + self.assertEqual(posixpath.relpath("a", "a"), ".") finally: os.getcwd = real_getcwd Modified: python/branches/py3k/Lib/test/test_socket.py ============================================================================== --- python/branches/py3k/Lib/test/test_socket.py (original) +++ python/branches/py3k/Lib/test/test_socket.py Sun Jan 6 17:59:19 2008 @@ -9,6 +9,8 @@ import thread, threading import Queue import sys +import os +import array from weakref import proxy import signal @@ -508,6 +510,15 @@ self.assertEqual(sock.proto, 0) sock.close() + def test_sock_ioctl(self): + if os.name != "nt": + return + self.assert_(hasattr(socket.socket, 'ioctl')) + self.assert_(hasattr(socket, 'SIO_RCVALL')) + self.assert_(hasattr(socket, 'RCVALL_ON')) + self.assert_(hasattr(socket, 'RCVALL_OFF')) + + class BasicTCPTest(SocketConnectedTest): def __init__(self, methodName='runTest'): Modified: python/branches/py3k/Lib/test/test_tarfile.py ============================================================================== --- python/branches/py3k/Lib/test/test_tarfile.py (original) +++ python/branches/py3k/Lib/test/test_tarfile.py Sun Jan 6 17:59:19 2008 @@ -243,6 +243,23 @@ data = open(os.path.join(TEMPDIR, "ustar/symtype"), "rb").read() self.assertEqual(md5sum(data), md5_regtype) + def test_extractall(self): + # Test if extractall() correctly restores directory permissions + # and times (see issue1735). + if sys.platform == "win32": + # Win32 has no support for utime() on directories or + # fine grained permissions. + return + + tar = tarfile.open(tarname, encoding="iso8859-1") + directories = [t for t in tar if t.isdir()] + tar.extractall(TEMPDIR, directories) + for tarinfo in directories: + path = os.path.join(TEMPDIR, tarinfo.name) + self.assertEqual(tarinfo.mode & 0o777, os.stat(path).st_mode & 0o777) + self.assertEqual(tarinfo.mtime, os.path.getmtime(path)) + tar.close() + class StreamReadTest(ReadTest): Modified: python/branches/py3k/Lib/test/test_urlparse.py ============================================================================== --- python/branches/py3k/Lib/test/test_urlparse.py (original) +++ python/branches/py3k/Lib/test/test_urlparse.py Sun Jan 6 17:59:19 2008 @@ -254,6 +254,24 @@ self.assertEqual(p.port, 80) self.assertEqual(p.geturl(), url) + # Addressing issue1698, which suggests Username can contain + # "@" characters. Though not RFC compliant, many ftp sites allow + # and request email addresses as usernames. + + url = "http://User at example.com:Pass at www.python.org:080/doc/?query=yes#frag" + p = urlparse.urlsplit(url) + self.assertEqual(p.scheme, "http") + self.assertEqual(p.netloc, "User at example.com:Pass at www.python.org:080") + self.assertEqual(p.path, "/doc/") + self.assertEqual(p.query, "query=yes") + self.assertEqual(p.fragment, "frag") + self.assertEqual(p.username, "User at example.com") + self.assertEqual(p.password, "Pass") + self.assertEqual(p.hostname, "www.python.org") + self.assertEqual(p.port, 80) + self.assertEqual(p.geturl(), url) + + def test_attributes_bad_port(self): """Check handling of non-integer ports.""" p = urlparse.urlsplit("http://www.example.net:foo") @@ -287,6 +305,11 @@ self.assertEqual(p.port, None) self.assertEqual(p.geturl(), uri) + def test_noslash(self): + # Issue 1637: http://foo.com?query is legal + self.assertEqual(urlparse.urlparse("http://example.com?blahblah=/foo"), + ('http', 'example.com', '', '', 'blahblah=/foo', '')) + def test_main(): test_support.run_unittest(UrlParseTestCase) Modified: python/branches/py3k/Lib/urlparse.py ============================================================================== --- python/branches/py3k/Lib/urlparse.py (original) +++ python/branches/py3k/Lib/urlparse.py Sun Jan 6 17:59:19 2008 @@ -82,7 +82,7 @@ def username(self): netloc = self.netloc if "@" in netloc: - userinfo = netloc.split("@", 1)[0] + userinfo = netloc.rsplit("@", 1)[0] if ":" in userinfo: userinfo = userinfo.split(":", 1)[0] return userinfo @@ -92,7 +92,7 @@ def password(self): netloc = self.netloc if "@" in netloc: - userinfo = netloc.split("@", 1)[0] + userinfo = netloc.rsplit("@", 1)[0] if ":" in userinfo: return userinfo.split(":", 1)[1] return None @@ -101,7 +101,7 @@ def hostname(self): netloc = self.netloc if "@" in netloc: - netloc = netloc.split("@", 1)[1] + netloc = netloc.rsplit("@", 1)[1] if ":" in netloc: netloc = netloc.split(":", 1)[0] return netloc.lower() or None @@ -110,7 +110,7 @@ def port(self): netloc = self.netloc if "@" in netloc: - netloc = netloc.split("@", 1)[1] + netloc = netloc.rsplit("@", 1)[1] if ":" in netloc: port = netloc.split(":", 1)[1] return int(port, 10) @@ -169,13 +169,12 @@ return url[:i], url[i+1:] def _splitnetloc(url, start=0): - for c in '/?#': # the order is important! - delim = url.find(c, start) - if delim >= 0: - break - else: - delim = len(url) - return url[start:delim], url[delim:] + delim = len(url) # position of end of domain part of url, default is end + for c in '/?#': # look for delimiters; the order is NOT important + wdelim = url.find(c, start) # find first of this delim + if wdelim >= 0: # if found + delim = min(delim, wdelim) # use earliest delim position + return url[start:delim], url[delim:] # return (domain, rest) def urlsplit(url, scheme='', allow_fragments=True): """Parse a URL into 5 components: Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Sun Jan 6 17:59:19 2008 @@ -463,6 +463,7 @@ Sape Mullender Sjoerd Mullender Michael Muller +John Nagle Takahiro Nakayama Travers Naran Fredrik Nehr Modified: python/branches/py3k/Modules/fcntlmodule.c ============================================================================== --- python/branches/py3k/Modules/fcntlmodule.c (original) +++ python/branches/py3k/Modules/fcntlmodule.c Sun Jan 6 17:59:19 2008 @@ -378,7 +378,7 @@ LOCK_SH - acquire a shared lock\n\ LOCK_EX - acquire an exclusive lock\n\ \n\ -When operation is LOCK_SH or LOCK_EX, it can also be bit-wise OR'd with\n\ +When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with\n\ LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the\n\ lock cannot be acquired, an IOError will be raised and the exception will\n\ have an errno attribute set to EACCES or EAGAIN (depending on the operating\n\ Modified: python/branches/py3k/Modules/socketmodule.c ============================================================================== --- python/branches/py3k/Modules/socketmodule.c (original) +++ python/branches/py3k/Modules/socketmodule.c Sun Jan 6 17:59:19 2008 @@ -2510,6 +2510,31 @@ Shut down the reading side of the socket (flag == SHUT_RD), the writing side\n\ of the socket (flag == SHUT_WR), or both ends (flag == SHUT_RDWR)."); +#ifdef MS_WINDOWS +static PyObject* +sock_ioctl(PySocketSockObject *s, PyObject *arg) +{ + unsigned long cmd = SIO_RCVALL; + unsigned int option = RCVALL_ON; + DWORD recv; + + if (!PyArg_ParseTuple(arg, "kI:ioctl", &cmd, &option)) + return NULL; + + if (WSAIoctl(s->sock_fd, cmd, &option, sizeof(option), + NULL, 0, &recv, NULL, NULL) == SOCKET_ERROR) { + return set_error(); + } + return PyLong_FromUnsignedLong(recv); +} +PyDoc_STRVAR(sock_ioctl_doc, +"ioctl(cmd, option) -> long\n\ +\n\ +Control the socket with WSAIoctl syscall. Currently only socket.SIO_RCVALL\n\ +is supported as control. Options must be one of the socket.RCVALL_*\n\ +constants."); + +#endif /* List of methods for socket objects */ @@ -2534,6 +2559,10 @@ METH_NOARGS, getsockname_doc}, {"getsockopt", (PyCFunction)sock_getsockopt, METH_VARARGS, getsockopt_doc}, +#ifdef MS_WINDOWS + {"ioctl", (PyCFunction)sock_ioctl, METH_VARARGS, + sock_ioctl_doc}, +#endif {"listen", (PyCFunction)sock_listen, METH_O, listen_doc}, {"recv", (PyCFunction)sock_recv, METH_VARARGS, @@ -3957,7 +3986,7 @@ PyMODINIT_FUNC init_socket(void) { - PyObject *m, *has_ipv6; + PyObject *m, *has_ipv6, *tmp; if (!os_init()) return; @@ -4794,6 +4823,18 @@ PyModule_AddIntConstant(m, "SHUT_RDWR", 2); #endif +#ifdef SIO_RCVALL + tmp = PyLong_FromUnsignedLong(SIO_RCVALL); + if (tmp == NULL) + return; + PyModule_AddObject(m, "SIO_RCVALL", tmp); + PyModule_AddIntConstant(m, "RCVALL_OFF", RCVALL_OFF); + PyModule_AddIntConstant(m, "RCVALL_ON", RCVALL_ON); + PyModule_AddIntConstant(m, "RCVALL_SOCKETLEVELONLY", RCVALL_SOCKETLEVELONLY); + PyModule_AddIntConstant(m, "RCVALL_IPLEVEL", RCVALL_IPLEVEL); + PyModule_AddIntConstant(m, "RCVALL_MAX", RCVALL_MAX); +#endif /* _MSTCPIP_ */ + /* Initialize gethostbyname lock */ #if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK) netdb_lock = PyThread_allocate_lock(); Modified: python/branches/py3k/Modules/socketmodule.h ============================================================================== --- python/branches/py3k/Modules/socketmodule.h (original) +++ python/branches/py3k/Modules/socketmodule.h Sun Jan 6 17:59:19 2008 @@ -16,6 +16,7 @@ #if _MSC_VER >= 1300 # include # include +# include /* for SIO_RCVALL */ # define HAVE_ADDRINFO # define HAVE_SOCKADDR_STORAGE # define HAVE_GETADDRINFO Modified: python/branches/py3k/PCbuild/build_tkinter.py ============================================================================== --- python/branches/py3k/PCbuild/build_tkinter.py (original) +++ python/branches/py3k/PCbuild/build_tkinter.py Sun Jan 6 17:59:19 2008 @@ -24,7 +24,9 @@ ROOT = os.path.abspath(os.path.join(here, par, par)) # Windows 2000 compatibility: WINVER 0x0500 # http://msdn2.microsoft.com/en-us/library/aa383745.aspx -NMAKE = "nmake /nologo /f %s COMPILERFLAGS=-DWINVER=0x0500 %s %s" +NMAKE = ('nmake /nologo /f %s ' + 'COMPILERFLAGS=\"-DWINVER=0x0500 -D_WIN32_WINNT=0x0500 -DNTDDI_VERSION=NTDDI_WIN2KSP4\"' + '%s %s') def nmake(makefile, command="", **kw): defines = ' '.join(k+'='+v for k, v in kw.items()) Modified: python/branches/py3k/Python/dynload_win.c ============================================================================== --- python/branches/py3k/Python/dynload_win.c (original) +++ python/branches/py3k/Python/dynload_win.c Sun Jan 6 17:59:19 2008 @@ -1,12 +1,13 @@ /* Support for dynamic loading of extension modules */ +#include "Python.h" + #ifdef HAVE_DIRECT_H #include #endif #include -#include "Python.h" #include "importdl.h" #include Modified: python/branches/py3k/Python/pystrtod.c ============================================================================== --- python/branches/py3k/Python/pystrtod.c (original) +++ python/branches/py3k/Python/pystrtod.c Sun Jan 6 17:59:19 2008 @@ -48,6 +48,8 @@ size_t decimal_point_len; const char *p, *decimal_point_pos; const char *end = NULL; /* Silence gcc */ + const char *digits_pos = NULL; + int negate = 0; assert(nptr != NULL); @@ -60,18 +62,41 @@ assert(decimal_point_len != 0); decimal_point_pos = NULL; + + /* We process any leading whitespace and the optional sign manually, + then pass the remainder to the system strtod. This ensures that + the result of an underflow has the correct sign. (bug #1725) */ + + p = nptr; + /* Skip leading space */ + while (ISSPACE(*p)) + p++; + + /* Process leading sign, if present */ + if (*p == '-') { + negate = 1; + p++; + } else if (*p == '+') { + p++; + } + + /* What's left should begin with a digit, a decimal point, or one of + the letters i, I, n, N. It should not begin with 0x or 0X */ + if ((!ISDIGIT(*p) && + *p != '.' && *p != 'i' && *p != 'I' && *p != 'n' && *p != 'N') + || + (*p == '0' && (p[1] == 'x' || p[1] == 'X'))) + { + if (endptr) + *endptr = (char*)nptr; + errno = EINVAL; + return val; + } + digits_pos = p; + if (decimal_point[0] != '.' || decimal_point[1] != 0) { - p = nptr; - /* Skip leading space */ - while (ISSPACE(*p)) - p++; - - /* Skip leading optional sign */ - if (*p == '+' || *p == '-') - p++; - while (ISDIGIT(*p)) p++; @@ -93,7 +118,8 @@ else if (strncmp(p, decimal_point, decimal_point_len) == 0) { /* Python bug #1417699 */ - *endptr = (char*)nptr; + if (endptr) + *endptr = (char*)nptr; errno = EINVAL; return val; } @@ -109,7 +135,8 @@ char *copy, *c; /* We need to convert the '.' to the locale specific decimal point */ - copy = (char *)PyMem_MALLOC(end - nptr + 1 + decimal_point_len); + copy = (char *)PyMem_MALLOC(end - digits_pos + + 1 + decimal_point_len); if (copy == NULL) { if (endptr) *endptr = (char *)nptr; @@ -118,8 +145,8 @@ } c = copy; - memcpy(c, nptr, decimal_point_pos - nptr); - c += decimal_point_pos - nptr; + memcpy(c, digits_pos, decimal_point_pos - digits_pos); + c += decimal_point_pos - digits_pos; memcpy(c, decimal_point, decimal_point_len); c += decimal_point_len; memcpy(c, decimal_point_pos + 1, end - (decimal_point_pos + 1)); @@ -131,24 +158,27 @@ if (fail_pos) { if (fail_pos > decimal_point_pos) - fail_pos = (char *)nptr + (fail_pos - copy) - (decimal_point_len - 1); + fail_pos = (char *)digits_pos + + (fail_pos - copy) - + (decimal_point_len - 1); else - fail_pos = (char *)nptr + (fail_pos - copy); + fail_pos = (char *)digits_pos + + (fail_pos - copy); } PyMem_FREE(copy); } else { - unsigned i = 0; - if (nptr[i] == '-') - i++; - if (nptr[i] == '0' && (nptr[i+1] == 'x' || nptr[i+1] == 'X')) - fail_pos = (char*)nptr; - else - val = strtod(nptr, &fail_pos); + val = strtod(digits_pos, &fail_pos); } + if (fail_pos == digits_pos) + fail_pos = (char *)nptr; + + if (negate && fail_pos != nptr) + val = -val; + if (endptr) *endptr = fail_pos; Modified: python/branches/py3k/Tools/buildbot/buildmsi.bat ============================================================================== --- python/branches/py3k/Tools/buildbot/buildmsi.bat (original) +++ python/branches/py3k/Tools/buildbot/buildmsi.bat Sun Jan 6 17:59:19 2008 @@ -4,12 +4,12 @@ @rem build release versions of things call "%VS90COMNTOOLS%vsvars32.bat" if not exist ..\db-4.4.20\build_win32\release\libdb44s.lib ( - devenv ..\db-4.4.20\build_win32\Berkeley_DB.sln /build Release /project db_static + vcbuild db-4.4.20\build_win32\Berkeley_DB.sln /build Release /project db_static ) @rem build Python cmd /q/c Tools\buildbot\kill_python.bat -devenv.com /useenv /build Release PCbuild\pcbuild.sln +vcbuild /useenv PCbuild\pcbuild.sln "Release|Win32" @rem build the documentation bash.exe -c 'cd Doc;make PYTHON=python2.5 update htmlhelp' Modified: python/branches/py3k/Tools/msi/msi.py ============================================================================== --- python/branches/py3k/Tools/msi/msi.py (original) +++ python/branches/py3k/Tools/msi/msi.py Sun Jan 6 17:59:19 2008 @@ -27,11 +27,10 @@ # Where is sqlite3.dll located, relative to srcdir? sqlite_dir = "../sqlite-source-3.3.4" # path to PCbuild directory -PCBUILD="PC\\VS7.1" -#PCBUILD="PCbuild" +PCBUILD="PCbuild" # msvcrt version -MSVCR = "71" -#MSVCR = "90" +#MSVCR = "71" +MSVCR = "90" try: from config import * @@ -904,12 +903,15 @@ language=installer.FileVersion(pydllsrc, 1)) # XXX determine dependencies if MSVCR == "90": - version, lang = extract_msvcr90() - dlldir.start_component("msvcr90", flags=8, keyfile="msvcr90.dll", - uuid=msvcr90_uuid) - dlldir.add_file("msvcr90.dll", src=os.path.abspath("msvcr90.dll"), - version=version, language=lang) - tmpfiles.append("msvcr90.dll") + # XXX don't package the CRT for the moment; + # this should probably use the merge module in the long run. + pass + #version, lang = extract_msvcr90() + #dlldir.start_component("msvcr90", flags=8, keyfile="msvcr90.dll", + # uuid=msvcr90_uuid) + #dlldir.add_file("msvcr90.dll", src=os.path.abspath("msvcr90.dll"), + # version=version, language=lang) + #tmpfiles.append("msvcr90.dll") else: version, lang = extract_msvcr71() dlldir.start_component("msvcr71", flags=8, keyfile="msvcr71.dll", From python-3000-checkins at python.org Sun Jan 6 18:05:41 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Sun, 6 Jan 2008 18:05:41 +0100 (CET) Subject: [Python-3000-checkins] r59784 - in python/branches/py3k: Doc/ACKS.txt Doc/library/csv.rst Doc/library/functions.rst Doc/library/inspect.rst Doc/library/shutil.rst Doc/library/stdtypes.rst Doc/library/subprocess.rst Doc/library/tempfile.rst Doc/library/zipimport.rst Doc/reference/datamodel.rst Lib/test/test_zipimport.py Message-ID: <20080106170541.29D8B1E4012@bag.python.org> Author: christian.heimes Date: Sun Jan 6 18:05:40 2008 New Revision: 59784 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/ACKS.txt python/branches/py3k/Doc/library/csv.rst python/branches/py3k/Doc/library/functions.rst python/branches/py3k/Doc/library/inspect.rst python/branches/py3k/Doc/library/shutil.rst python/branches/py3k/Doc/library/stdtypes.rst python/branches/py3k/Doc/library/subprocess.rst python/branches/py3k/Doc/library/tempfile.rst python/branches/py3k/Doc/library/zipimport.rst python/branches/py3k/Doc/reference/datamodel.rst python/branches/py3k/Lib/test/test_zipimport.py Log: Merged revisions 59774-59783 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r59774 | georg.brandl | 2008-01-06 16:41:50 +0100 (Sun, 06 Jan 2008) | 2 lines #1501: document that 0**0 == 1. ........ r59775 | georg.brandl | 2008-01-06 16:48:20 +0100 (Sun, 06 Jan 2008) | 2 lines #759525: document that dir() doesn't return metaclass attrs when given a class as arg. ........ r59776 | georg.brandl | 2008-01-06 16:55:26 +0100 (Sun, 06 Jan 2008) | 2 lines #1615275: clarify return object types of different tempfile factories. ........ r59777 | georg.brandl | 2008-01-06 17:01:26 +0100 (Sun, 06 Jan 2008) | 2 lines #1727024: document that Popen.returncode is set by Popen.poll/wait. ........ r59778 | georg.brandl | 2008-01-06 17:04:56 +0100 (Sun, 06 Jan 2008) | 2 lines #1686390: add example for csv.Sniffer use. ........ r59779 | georg.brandl | 2008-01-06 17:12:39 +0100 (Sun, 06 Jan 2008) | 2 lines #1559684: document that shutil.copy* doesn't copy all metadata on Posix and Windows too. ........ r59780 | georg.brandl | 2008-01-06 17:17:56 +0100 (Sun, 06 Jan 2008) | 2 lines #1582: document __reversed__, patch by Mark Russell. ........ r59781 | georg.brandl | 2008-01-06 17:22:56 +0100 (Sun, 06 Jan 2008) | 2 lines #1499: Document compile() exceptions. ........ r59782 | georg.brandl | 2008-01-06 17:49:50 +0100 (Sun, 06 Jan 2008) | 2 lines #1325: Add docs and tests for zipimporter.archive and zipimporter.prefix. ........ Modified: python/branches/py3k/Doc/ACKS.txt ============================================================================== --- python/branches/py3k/Doc/ACKS.txt (original) +++ python/branches/py3k/Doc/ACKS.txt Sun Jan 6 18:05:40 2008 @@ -158,6 +158,7 @@ * Jim Roskind * Guido van Rossum * Donald Wallace Rouse II + * Mark Russell * Nick Russo * Chris Ryland * Constantina S. Modified: python/branches/py3k/Doc/library/csv.rst ============================================================================== --- python/branches/py3k/Doc/library/csv.rst (original) +++ python/branches/py3k/Doc/library/csv.rst Sun Jan 6 18:05:40 2008 @@ -211,7 +211,6 @@ The :class:`Sniffer` class provides two methods: - .. method:: Sniffer.sniff(sample[, delimiters=None]) Analyze the given *sample* and return a :class:`Dialect` subclass reflecting the @@ -224,9 +223,17 @@ Analyze the sample text (presumed to be in CSV format) and return :const:`True` if the first row appears to be a series of column headers. -The :mod:`csv` module defines the following constants: +An example for :class:`Sniffer` use:: + + csvfile = open("example.csv") + dialect = csv.Sniffer().sniff(csvfile.read(1024)) + csvfile.seek(0) + reader = csv.reader(csvfile, dialect) + # ... process CSV file contents here ... +The :mod:`csv` module defines the following constants: + .. data:: QUOTE_ALL Instructs :class:`writer` objects to quote all fields. Modified: python/branches/py3k/Doc/library/functions.rst ============================================================================== --- python/branches/py3k/Doc/library/functions.rst (original) +++ python/branches/py3k/Doc/library/functions.rst Sun Jan 6 18:05:40 2008 @@ -232,6 +232,9 @@ can be found as the :attr:`compiler_flag` attribute on the :class:`_Feature` instance in the :mod:`__future__` module. + This function raises :exc:`SyntaxError` if the compiled source is invalid, + and :exc:`TypeError` if the source contains null bytes. + .. function:: complex([real[, imag]]) @@ -313,7 +316,8 @@ Because :func:`dir` is supplied primarily as a convenience for use at an interactive prompt, it tries to supply an interesting set of names more than it tries to supply a rigorously or consistently defined set of names, and its - detailed behavior may change across releases. + detailed behavior may change across releases. For example, metaclass attributes + are not in the result list when the argument is a class. .. function:: divmod(a, b) @@ -907,9 +911,10 @@ .. function:: reversed(seq) - Return a reverse :term:`iterator`. *seq* must be an object which supports - the sequence protocol (the :meth:`__len__` method and the :meth:`__getitem__` - method with integer arguments starting at ``0``). + Return a reverse :term:`iterator`. *seq* must be an object which has + a :meth:`__reversed__` method or supports the sequence protocol (the + :meth:`__len__` method and the :meth:`__getitem__` method with integer + arguments starting at ``0``). .. function:: round(x[, n]) Modified: python/branches/py3k/Doc/library/inspect.rst ============================================================================== --- python/branches/py3k/Doc/library/inspect.rst (original) +++ python/branches/py3k/Doc/library/inspect.rst Sun Jan 6 18:05:40 2008 @@ -180,6 +180,11 @@ name. If the optional *predicate* argument is supplied, only members for which the predicate returns a true value are included. + .. note:: + + :func:`getmembers` does not return metaclass attributes when the argument + is a class (this behavior is inherited from the :func:`dir` function). + .. function:: getmoduleinfo(path) Modified: python/branches/py3k/Doc/library/shutil.rst ============================================================================== --- python/branches/py3k/Doc/library/shutil.rst (original) +++ python/branches/py3k/Doc/library/shutil.rst Sun Jan 6 18:05:40 2008 @@ -17,16 +17,21 @@ :mod:`os` module. .. warning:: + + Even the higher-level file copying functions (:func:`copy`, :func:`copy2`) + can't copy all file metadata. - On MacOS, the resource fork and other metadata are not used. For file copies, - this means that resources will be lost and file type and creator codes will - not be correct. + On POSIX platforms, this means that file owner and group are lost as well + as ACLs. On MacOS, the resource fork and other metadata are not used. + This means that resources will be lost and file type and creator codes will + not be correct. On Windows, file owners, ACLs and alternate data streams + are not copied. .. function:: copyfile(src, dst) - Copy the contents of the file named *src* to a file named *dst*. The - destination location must be writable; otherwise, an :exc:`IOError` exception + Copy the contents (no metadata) of the file named *src* to a file named *dst*. + The destination location must be writable; otherwise, an :exc:`IOError` exception will be raised. If *dst* already exists, it will be replaced. Special files such as character or block devices and pipes cannot be copied with this function. *src* and *dst* are path names given as strings. @@ -106,13 +111,13 @@ Recursively move a file or directory to another location. - If the destination is on our current filesystem, then simply use rename. + If the destination is on the current filesystem, then simply use rename. Otherwise, copy src to the dst and then remove src. .. exception:: Error - This exception collects exceptions that raised during a mult-file operation. For + This exception collects exceptions that raised during a multi-file operation. For :func:`copytree`, the exception argument is a list of 3-tuples (*srcname*, *dstname*, *exception*). Modified: python/branches/py3k/Doc/library/stdtypes.rst ============================================================================== --- python/branches/py3k/Doc/library/stdtypes.rst (original) +++ python/branches/py3k/Doc/library/stdtypes.rst Sun Jan 6 18:05:40 2008 @@ -314,9 +314,9 @@ +---------------------+---------------------------------+-------+--------------------+ | ``divmod(x, y)`` | the pair ``(x // y, x % y)`` | \(2) | :func:`divmod` | +---------------------+---------------------------------+-------+--------------------+ -| ``pow(x, y)`` | *x* to the power *y* | | :func:`pow` | +| ``pow(x, y)`` | *x* to the power *y* | (7) | :func:`pow` | +---------------------+---------------------------------+-------+--------------------+ -| ``x ** y`` | *x* to the power *y* | | | +| ``x ** y`` | *x* to the power *y* | (7) | | +---------------------+---------------------------------+-------+--------------------+ .. index:: @@ -350,6 +350,11 @@ (6) float also accepts the strings "nan" and "inf" with an optional prefix "+" or "-" for Not a Number (NaN) and positive or negative infinity. + +(7) + Python defines ``pow(0, 0)`` and ``0 ** 0`` to be ``1``, as is common for + programming languages. + All :class:`numbers.Real` types (:class:`int` and Modified: python/branches/py3k/Doc/library/subprocess.rst ============================================================================== --- python/branches/py3k/Doc/library/subprocess.rst (original) +++ python/branches/py3k/Doc/library/subprocess.rst Sun Jan 6 18:05:40 2008 @@ -172,12 +172,14 @@ .. method:: Popen.poll() - Check if child process has terminated. Returns returncode attribute. + Check if child process has terminated. Set and return :attr:`returncode` + attribute. .. method:: Popen.wait() - Wait for child process to terminate. Returns returncode attribute. + Wait for child process to terminate. Set and return :attr:`returncode` + attribute. .. method:: Popen.communicate(input=None) @@ -187,20 +189,20 @@ *input* argument should be a string to be sent to the child process, or ``None``, if no data should be sent to the child. - communicate() returns a tuple (stdout, stderr). + :meth:`communicate` returns a tuple ``(stdout, stderr)``. Note that if you want to send data to the process's stdin, you need to create the Popen object with ``stdin=PIPE``. Similarly, to get anything other than ``None`` in the result tuple, you need to give ``stdout=PIPE`` and/or ``stderr=PIPE`` too. -.. note:: + .. note:: - The data read is buffered in memory, so do not use this method if the data size - is large or unlimited. + The data read is buffered in memory, so do not use this method if the data + size is large or unlimited. -The following attributes are also available: +The following attributes are also available: .. attribute:: Popen.stdin @@ -227,9 +229,12 @@ .. attribute:: Popen.returncode - The child return code. A ``None`` value indicates that the process hasn't - terminated yet. A negative value -N indicates that the child was terminated by - signal N (Unix only). + The child return code, set by :meth:`poll` and :meth:`wait` (and indirectly + by :meth:`communicate`). A ``None`` value indicates that the process + hasn't terminated yet. + + A negative value ``-N`` indicates that the child was terminated by signal + ``N`` (Unix only). Replacing Older Functions with the subprocess Module Modified: python/branches/py3k/Doc/library/tempfile.rst ============================================================================== --- python/branches/py3k/Doc/library/tempfile.rst (original) +++ python/branches/py3k/Doc/library/tempfile.rst Sun Jan 6 18:05:40 2008 @@ -34,7 +34,7 @@ .. function:: TemporaryFile([mode='w+b'[, bufsize=-1[, suffix[, prefix[, dir]]]]]) - Return a file (or file-like) object that can be used as a temporary storage + Return a file-like object that can be used as a temporary storage area. The file is created using :func:`mkstemp`. It will be destroyed as soon as it is closed (including an implicit close when the object is garbage collected). Under Unix, the directory entry for the file is removed immediately @@ -49,6 +49,10 @@ The *dir*, *prefix* and *suffix* parameters are passed to :func:`mkstemp`. + The returned object is a true file object on POSIX platforms. On other + platforms, it is a file-like object whose :attr:`file` attribute is the + underlying true file object. + .. function:: NamedTemporaryFile([mode='w+b'[, bufsize=-1[, suffix[, prefix[, dir[, delete]]]]]]) @@ -59,6 +63,8 @@ the file a second time, while the named temporary file is still open, varies across platforms (it can be so used on Unix; it cannot on Windows NT or later). If *delete* is true (the default), the file is deleted as soon as it is closed. + The returned object is always a file-like object whose :attr:`file` attribute + is the underlying true file object. .. function:: SpooledTemporaryFile([max_size=0, [mode='w+b'[, bufsize=-1[, suffix[, prefix[, dir]]]]]]) @@ -71,6 +77,10 @@ The resulting file has one additional method, :func:`rollover`, which causes the file to roll over to an on-disk file regardless of its size. + The returned object is a file-like object whose :attr:`_file` attribute + is either a :class:`StringIO` object or a true file object, depending on + whether :func:`rollover` has been called. + .. function:: mkstemp([suffix[, prefix[, dir[, text]]]]) Modified: python/branches/py3k/Doc/library/zipimport.rst ============================================================================== --- python/branches/py3k/Doc/library/zipimport.rst (original) +++ python/branches/py3k/Doc/library/zipimport.rst Sun Jan 6 18:05:40 2008 @@ -27,21 +27,6 @@ corresponding :file:`.pyc` or :file:`.pyo` file, meaning that if a ZIP archive doesn't contain :file:`.pyc` files, importing may be rather slow. -The available attributes of this module are: - - -.. exception:: ZipImportError - - Exception raised by zipimporter objects. It's a subclass of :exc:`ImportError`, - so it can be caught as :exc:`ImportError`, too. - - -.. class:: zipimporter - - The class for importing ZIP files. See section :ref:`zipimporter-objects` - for constructor details. - - .. seealso:: `PKZIP Application Note `_ @@ -57,18 +42,33 @@ The PEP to add the import hooks that help this module work. +This module defines an exception: + +.. exception:: ZipImportError + + Exception raised by zipimporter objects. It's a subclass of :exc:`ImportError`, + so it can be caught as :exc:`ImportError`, too. + + .. _zipimporter-objects: zipimporter Objects ------------------- +:class:`zipimporter` is the class for importing ZIP files. .. class:: zipimporter(archivepath) - Create a new zipimporter instance. *archivepath* must be a path to a zipfile. + Create a new zipimporter instance. *archivepath* must be a path to a ZIP file. :exc:`ZipImportError` is raised if *archivepath* doesn't point to a valid ZIP archive. + *archivepath* can also contain a path within the ZIP file -- the importer + object will then look under that path instead of the ZIP file root. For + example, an *archivepath* of :file:`foo/bar.zip/lib` will look for modules + in the :file:`lib` directory inside the ZIP file :file:`foo/bar.zip` + (provided that it exists). + .. method:: zipimporter.find_module(fullname[, path]) @@ -110,11 +110,22 @@ :exc:`ZipImportError` if it wasn't found. -Examples --------- +.. attribute:: zipimporter.archive + + The file name of the importer's associated ZIP file. + + +.. attribute:: zipimporter.prefix + + The path within the ZIP file where modules are searched; see + :class:`zipimporter` for details. + .. _zipimport-examples: +Examples +-------- + Here is an example that imports a module from a ZIP archive - note that the :mod:`zipimport` module is not explicitly used. :: Modified: python/branches/py3k/Doc/reference/datamodel.rst ============================================================================== --- python/branches/py3k/Doc/reference/datamodel.rst (original) +++ python/branches/py3k/Doc/reference/datamodel.rst Sun Jan 6 18:05:40 2008 @@ -1688,6 +1688,20 @@ Iterator objects also need to implement this method; they are required to return themselves. For more information on iterator objects, see :ref:`typeiter`. + +.. method:: object.__reversed__(self) + + Called (if present) by the :func:`reversed` builtin to implement + reverse iteration. It should return a new iterator object that iterates + over all the objects in the container in reverse order. + + If the :meth:`__reversed__` method is not provided, the + :func:`reversed` builtin will fall back to using the sequence protocol + (:meth:`__len__` and :meth:`__getitem__`). Objects should normally + only provide :meth:`__reversed__` if they do not support the sequence + protocol and an efficient implementation of reverse iteration is possible. + + The membership test operators (:keyword:`in` and :keyword:`not in`) are normally implemented as an iteration through a sequence. However, container objects can supply the following special method with a more efficient implementation, which Modified: python/branches/py3k/Lib/test/test_zipimport.py ============================================================================== --- python/branches/py3k/Lib/test/test_zipimport.py (original) +++ python/branches/py3k/Lib/test/test_zipimport.py Sun Jan 6 18:05:40 2008 @@ -220,6 +220,11 @@ mod = __import__(module_path_to_dotted_name(mod_name)) self.assertEquals(zi.get_source(TESTPACK), None) self.assertEquals(zi.get_source(mod_name), None) + + # test prefix and archivepath members + zi2 = zipimport.zipimporter(TEMP_ZIP + os.sep + TESTPACK) + self.assertEquals(zi2.archive, TEMP_ZIP) + self.assertEquals(zi2.prefix, TESTPACK + os.sep) finally: z.close() os.remove(TEMP_ZIP) From python-3000-checkins at python.org Sun Jan 6 18:25:36 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sun, 6 Jan 2008 18:25:36 +0100 (CET) Subject: [Python-3000-checkins] r59787 - python/branches/py3k/Doc/tutorial/controlflow.rst Message-ID: <20080106172536.8BF091E4012@bag.python.org> Author: georg.brandl Date: Sun Jan 6 18:25:36 2008 New Revision: 59787 Modified: python/branches/py3k/Doc/tutorial/controlflow.rst Log: Clarify sentence in tutorial. Thanks to Marek Kubica. Modified: python/branches/py3k/Doc/tutorial/controlflow.rst ============================================================================== --- python/branches/py3k/Doc/tutorial/controlflow.rst (original) +++ python/branches/py3k/Doc/tutorial/controlflow.rst Sun Jan 6 18:25:36 2008 @@ -457,10 +457,9 @@ shopkeeper : Michael Palin sketch : Cheese Shop Sketch -Note that the :meth:`sort` method of the list of keyword argument names is -called before printing the contents of the ``keywords`` dictionary; if this is -not done, the order in which the arguments are printed is undefined. - +Note that the list of keyword argument names is created by sorting the result +of the keywords dictionary's ``keys()`` method before printing its contents; +if this is not done, the order in which the arguments are printed is undefined. .. _tut-arbitraryargs: From python-3000-checkins at python.org Sun Jan 6 18:39:50 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sun, 6 Jan 2008 18:39:50 +0100 (CET) Subject: [Python-3000-checkins] r59789 - python/branches/py3k/Doc/library/stdtypes.rst Message-ID: <20080106173950.525C91E4012@bag.python.org> Author: georg.brandl Date: Sun Jan 6 18:39:49 2008 New Revision: 59789 Modified: python/branches/py3k/Doc/library/stdtypes.rst Log: Use consistent note numbers. Modified: python/branches/py3k/Doc/library/stdtypes.rst ============================================================================== --- python/branches/py3k/Doc/library/stdtypes.rst (original) +++ python/branches/py3k/Doc/library/stdtypes.rst Sun Jan 6 18:39:49 2008 @@ -303,7 +303,7 @@ +---------------------+---------------------------------+-------+--------------------+ | ``int(x)`` | *x* converted to integer | \(3) | :func:`int` | +---------------------+---------------------------------+-------+--------------------+ -| ``float(x)`` | *x* converted to floating point | \(6) | :func:`float` | +| ``float(x)`` | *x* converted to floating point | \(4) | :func:`float` | +---------------------+---------------------------------+-------+--------------------+ | ``complex(re, im)`` | a complex number with real part | | :func:`complex` | | | *re*, imaginary part *im*. | | | @@ -314,9 +314,9 @@ +---------------------+---------------------------------+-------+--------------------+ | ``divmod(x, y)`` | the pair ``(x // y, x % y)`` | \(2) | :func:`divmod` | +---------------------+---------------------------------+-------+--------------------+ -| ``pow(x, y)`` | *x* to the power *y* | (7) | :func:`pow` | +| ``pow(x, y)`` | *x* to the power *y* | (5) | :func:`pow` | +---------------------+---------------------------------+-------+--------------------+ -| ``x ** y`` | *x* to the power *y* | (7) | | +| ``x ** y`` | *x* to the power *y* | (5) | | +---------------------+---------------------------------+-------+--------------------+ .. index:: @@ -347,11 +347,11 @@ as in C; see functions :func:`floor` and :func:`ceil` in the :mod:`math` module for well-defined conversions. -(6) +(4) float also accepts the strings "nan" and "inf" with an optional prefix "+" or "-" for Not a Number (NaN) and positive or negative infinity. -(7) +(5) Python defines ``pow(0, 0)`` and ``0 ** 0`` to be ``1``, as is common for programming languages. From python-3000-checkins at python.org Sun Jan 6 19:23:30 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sun, 6 Jan 2008 19:23:30 +0100 (CET) Subject: [Python-3000-checkins] r59790 - python/branches/py3k/Lib/asyncore.py Message-ID: <20080106182330.BB9E01E4013@bag.python.org> Author: georg.brandl Date: Sun Jan 6 19:23:30 2008 New Revision: 59790 Modified: python/branches/py3k/Lib/asyncore.py Log: Fix exception slicing. Modified: python/branches/py3k/Lib/asyncore.py ============================================================================== --- python/branches/py3k/Lib/asyncore.py (original) +++ python/branches/py3k/Lib/asyncore.py Sun Jan 6 19:23:30 2008 @@ -321,7 +321,7 @@ conn, addr = self.socket.accept() return conn, addr except socket.error as why: - if why[0] == EWOULDBLOCK: + if why.args[0] == EWOULDBLOCK: pass else: raise @@ -331,7 +331,7 @@ result = self.socket.send(data) return result except socket.error as why: - if why[0] == EWOULDBLOCK: + if why.args[0] == EWOULDBLOCK: return 0 else: raise @@ -349,7 +349,7 @@ return data except socket.error as why: # winsock sometimes throws ENOTCONN - if why[0] in [ECONNRESET, ENOTCONN, ESHUTDOWN]: + if why.args[0] in [ECONNRESET, ENOTCONN, ESHUTDOWN]: self.handle_close() return b'' else: From python-3000-checkins at python.org Sun Jan 6 22:13:43 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sun, 6 Jan 2008 22:13:43 +0100 (CET) Subject: [Python-3000-checkins] r59793 - in python/branches/py3k: Demo/pdist/cvslock.py Demo/scripts/toaiff.py Lib/distutils/file_util.py Lib/distutils/spawn.py Lib/filecmp.py Lib/plat-mac/EasyDialogs.py Lib/plat-mac/aetools.py Lib/plat-mac/gensuitemodule.py Lib/plat-mac/terminalcommand.py Message-ID: <20080106211343.77F221E4014@bag.python.org> Author: georg.brandl Date: Sun Jan 6 22:13:42 2008 New Revision: 59793 Modified: python/branches/py3k/Demo/pdist/cvslock.py python/branches/py3k/Demo/scripts/toaiff.py python/branches/py3k/Lib/distutils/file_util.py python/branches/py3k/Lib/distutils/spawn.py python/branches/py3k/Lib/filecmp.py python/branches/py3k/Lib/plat-mac/EasyDialogs.py python/branches/py3k/Lib/plat-mac/aetools.py python/branches/py3k/Lib/plat-mac/gensuitemodule.py python/branches/py3k/Lib/plat-mac/terminalcommand.py Log: Fix more exception slicing. Modified: python/branches/py3k/Demo/pdist/cvslock.py ============================================================================== --- python/branches/py3k/Demo/pdist/cvslock.py (original) +++ python/branches/py3k/Demo/pdist/cvslock.py Sun Jan 6 22:13:42 2008 @@ -131,7 +131,7 @@ return except os.error as msg: self.lockdir = None - if msg[0] == EEXIST: + if msg.args[0] == EEXIST: try: st = os.stat(self.cvslck) except os.error: Modified: python/branches/py3k/Demo/scripts/toaiff.py ============================================================================== --- python/branches/py3k/Demo/scripts/toaiff.py (original) +++ python/branches/py3k/Demo/scripts/toaiff.py Sun Jan 6 22:13:42 2008 @@ -89,8 +89,8 @@ ftype = ftype[0] # All we're interested in except IOError as msg: if type(msg) == type(()) and len(msg) == 2 and \ - type(msg[0]) == type(0) and type(msg[1]) == type(''): - msg = msg[1] + type(msg.args[0]) == type(0) and type(msg.args[1]) == type(''): + msg = msg.args[1] if type(msg) != type(''): msg = repr(msg) raise error(filename + ': ' + msg) Modified: python/branches/py3k/Lib/distutils/file_util.py ============================================================================== --- python/branches/py3k/Lib/distutils/file_util.py (original) +++ python/branches/py3k/Lib/distutils/file_util.py Sun Jan 6 22:13:42 2008 @@ -139,7 +139,7 @@ macostools.copy(src, dst, 0, preserve_times) except os.error as exc: raise DistutilsFileError( - "could not copy '%s' to '%s': %s" % (src, dst, exc[-1])) + "could not copy '%s' to '%s': %s" % (src, dst, exc.args[-1])) # If linking (hard or symbolic), use the appropriate system call # (Unix only, of course, but that's the caller's responsibility) Modified: python/branches/py3k/Lib/distutils/spawn.py ============================================================================== --- python/branches/py3k/Lib/distutils/spawn.py (original) +++ python/branches/py3k/Lib/distutils/spawn.py Sun Jan 6 22:13:42 2008 @@ -67,7 +67,7 @@ except OSError as exc: # this seems to happen when the command isn't found raise DistutilsExecError( - "command '%s' failed: %s" % (cmd[0], exc[-1])) + "command '%s' failed: %s" % (cmd[0], exc.args[-1])) if rc != 0: # and this reflects the command running but failing raise DistutilsExecError( @@ -88,7 +88,7 @@ except OSError as exc: # this seems to happen when the command isn't found raise DistutilsExecError( - "command '%s' failed: %s" % (cmd[0], exc[-1])) + "command '%s' failed: %s" % (cmd[0], exc.args[-1])) if rc != 0: # and this reflects the command running but failing print("command '%s' failed with exit status %d" % (cmd[0], rc)) @@ -124,7 +124,7 @@ if exc.errno == errno.EINTR: continue raise DistutilsExecError( - "command '%s' failed: %s" % (cmd[0], exc[-1])) + "command '%s' failed: %s" % (cmd[0], exc.args[-1])) if os.WIFSIGNALED(status): raise DistutilsExecError( "command '%s' terminated by signal %d" Modified: python/branches/py3k/Lib/filecmp.py ============================================================================== --- python/branches/py3k/Lib/filecmp.py (original) +++ python/branches/py3k/Lib/filecmp.py Sun Jan 6 22:13:42 2008 @@ -149,12 +149,12 @@ try: a_stat = os.stat(a_path) except os.error as why: - # print 'Can\'t stat', a_path, ':', why[1] + # print('Can\'t stat', a_path, ':', why.args[1]) ok = 0 try: b_stat = os.stat(b_path) except os.error as why: - # print 'Can\'t stat', b_path, ':', why[1] + # print('Can\'t stat', b_path, ':', why.args[1]) ok = 0 if ok: Modified: python/branches/py3k/Lib/plat-mac/EasyDialogs.py ============================================================================== --- python/branches/py3k/Lib/plat-mac/EasyDialogs.py (original) +++ python/branches/py3k/Lib/plat-mac/EasyDialogs.py Sun Jan 6 22:13:42 2008 @@ -651,7 +651,7 @@ rr = Nav.NavChooseFile(args) good = 1 except Nav.error as arg: - if arg[0] != -128: # userCancelledErr + if arg.args[0] != -128: # userCancelledErr raise Nav.error(arg) return None if not rr.validRecord or not rr.selection: @@ -704,7 +704,7 @@ rr = Nav.NavPutFile(args) good = 1 except Nav.error as arg: - if arg[0] != -128: # userCancelledErr + if arg.args[0] != -128: # userCancelledErr raise Nav.error(arg) return None if not rr.validRecord or not rr.selection: @@ -764,7 +764,7 @@ rr = Nav.NavChooseFolder(args) good = 1 except Nav.error as arg: - if arg[0] != -128: # userCancelledErr + if arg.args[0] != -128: # userCancelledErr raise Nav.error(arg) return None if not rr.validRecord or not rr.selection: Modified: python/branches/py3k/Lib/plat-mac/aetools.py ============================================================================== --- python/branches/py3k/Lib/plat-mac/aetools.py (original) +++ python/branches/py3k/Lib/plat-mac/aetools.py Sun Jan 6 22:13:42 2008 @@ -86,7 +86,7 @@ try: desc = ae.AEGetAttributeDesc(key, '****') except (AE.Error, MacOS.Error) as msg: - if msg[0] != -1701 and msg[0] != -1704: + if msg.args[0] not in (-1701, -1704): raise continue attributes[key] = unpack(desc, formodulename) Modified: python/branches/py3k/Lib/plat-mac/gensuitemodule.py ============================================================================== --- python/branches/py3k/Lib/plat-mac/gensuitemodule.py (original) +++ python/branches/py3k/Lib/plat-mac/gensuitemodule.py Sun Jan 6 22:13:42 2008 @@ -191,7 +191,7 @@ try: aedescobj, launched = OSATerminology.GetAppTerminology(fullname) except MacOS.Error as arg: - if arg[0] in (-1701, -192): # errAEDescNotFound, resNotFound + if arg.args[0] in (-1701, -192): # errAEDescNotFound, resNotFound if verbose: print("GetAppTerminology failed with errAEDescNotFound/resNotFound, trying manually", file=verbose) aedata, sig = getappterminology(fullname, verbose=verbose) Modified: python/branches/py3k/Lib/plat-mac/terminalcommand.py ============================================================================== --- python/branches/py3k/Lib/plat-mac/terminalcommand.py (original) +++ python/branches/py3k/Lib/plat-mac/terminalcommand.py Sun Jan 6 22:13:42 2008 @@ -36,7 +36,7 @@ try: theEvent.AESend(SEND_MODE, kAENormalPriority, kAEDefaultTimeout) except AE.Error as why: - if why[0] != -600: # Terminal.app not yet running + if why.args[0] != -600: # Terminal.app not yet running raise os.system(START_TERMINAL) time.sleep(1) From python-3000-checkins at python.org Sun Jan 6 22:38:55 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sun, 6 Jan 2008 22:38:55 +0100 (CET) Subject: [Python-3000-checkins] r59794 - in python/branches/py3k/Lib: pstats.py test/test_file.py test/test_fileio.py Message-ID: <20080106213855.42E721E4014@bag.python.org> Author: georg.brandl Date: Sun Jan 6 22:38:54 2008 New Revision: 59794 Modified: python/branches/py3k/Lib/pstats.py python/branches/py3k/Lib/test/test_file.py python/branches/py3k/Lib/test/test_fileio.py Log: The final occurrences of exception slicing. Modified: python/branches/py3k/Lib/pstats.py ============================================================================== --- python/branches/py3k/Lib/pstats.py (original) +++ python/branches/py3k/Lib/pstats.py Sun Jan 6 22:38:54 2008 @@ -617,8 +617,8 @@ if line: try: self.stats = Stats(line) - except IOError as args: - print(args[1], file=self.stream) + except IOError as err: + print(err.args[1], file=self.stream) return self.prompt = line + "% " elif len(self.prompt) > 2: Modified: python/branches/py3k/Lib/test/test_file.py ============================================================================== --- python/branches/py3k/Lib/test/test_file.py (original) +++ python/branches/py3k/Lib/test/test_file.py Sun Jan 6 22:38:54 2008 @@ -157,7 +157,7 @@ s = str(msg) if s.find(TESTFN) != -1 or s.find(bad_mode) == -1: self.fail("bad error message for invalid mode: %s" % s) - # if msg[0] == 0, we're probably on Windows where there may be + # if msg.args[0] == 0, we're probably on Windows where there may be # no obvious way to discover why open() failed. else: f.close() Modified: python/branches/py3k/Lib/test/test_fileio.py ============================================================================== --- python/branches/py3k/Lib/test/test_fileio.py (original) +++ python/branches/py3k/Lib/test/test_fileio.py Sun Jan 6 22:38:54 2008 @@ -172,7 +172,7 @@ s = str(msg) if s.find(TESTFN) != -1 or s.find(bad_mode) == -1: self.fail("bad error message for invalid mode: %s" % s) - # if msg[0] == 0, we're probably on Windows where there may be + # if msg.args[0] == 0, we're probably on Windows where there may be # no obvious way to discover why open() failed. else: f.close() From python-3000-checkins at python.org Sun Jan 6 22:41:49 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sun, 6 Jan 2008 22:41:49 +0100 (CET) Subject: [Python-3000-checkins] r59795 - python/branches/py3k/Lib/distutils/util.py Message-ID: <20080106214149.DB2031E4028@bag.python.org> Author: georg.brandl Date: Sun Jan 6 22:41:49 2008 New Revision: 59795 Modified: python/branches/py3k/Lib/distutils/util.py Log: Missed one because of indirection. Modified: python/branches/py3k/Lib/distutils/util.py ============================================================================== --- python/branches/py3k/Lib/distutils/util.py (original) +++ python/branches/py3k/Lib/distutils/util.py Sun Jan 6 22:41:49 2008 @@ -269,7 +269,7 @@ # include the filename in the exception object! error = prefix + "%s" % exc.strerror else: - error = prefix + str(exc[-1]) + error = prefix + str(exc.args[-1]) return error From guido at python.org Mon Jan 7 00:40:50 2008 From: guido at python.org (Guido van Rossum) Date: Sun, 6 Jan 2008 15:40:50 -0800 Subject: [Python-3000-checkins] r59789 - python/branches/py3k/Doc/library/stdtypes.rst In-Reply-To: <20080106173950.525C91E4012@bag.python.org> References: <20080106173950.525C91E4012@bag.python.org> Message-ID: Why do have some note numbers a \ and others don't? On Jan 6, 2008 9:39 AM, georg.brandl wrote: > Author: georg.brandl > Date: Sun Jan 6 18:39:49 2008 > New Revision: 59789 > > Modified: > python/branches/py3k/Doc/library/stdtypes.rst > Log: > Use consistent note numbers. > > > Modified: python/branches/py3k/Doc/library/stdtypes.rst > ============================================================================== > --- python/branches/py3k/Doc/library/stdtypes.rst (original) > +++ python/branches/py3k/Doc/library/stdtypes.rst Sun Jan 6 18:39:49 2008 > @@ -303,7 +303,7 @@ > +---------------------+---------------------------------+-------+--------------------+ > | ``int(x)`` | *x* converted to integer | \(3) | :func:`int` | > +---------------------+---------------------------------+-------+--------------------+ > -| ``float(x)`` | *x* converted to floating point | \(6) | :func:`float` | > +| ``float(x)`` | *x* converted to floating point | \(4) | :func:`float` | > +---------------------+---------------------------------+-------+--------------------+ > | ``complex(re, im)`` | a complex number with real part | | :func:`complex` | > | | *re*, imaginary part *im*. | | | > @@ -314,9 +314,9 @@ > +---------------------+---------------------------------+-------+--------------------+ > | ``divmod(x, y)`` | the pair ``(x // y, x % y)`` | \(2) | :func:`divmod` | > +---------------------+---------------------------------+-------+--------------------+ > -| ``pow(x, y)`` | *x* to the power *y* | (7) | :func:`pow` | > +| ``pow(x, y)`` | *x* to the power *y* | (5) | :func:`pow` | > +---------------------+---------------------------------+-------+--------------------+ > -| ``x ** y`` | *x* to the power *y* | (7) | | > +| ``x ** y`` | *x* to the power *y* | (5) | | > +---------------------+---------------------------------+-------+--------------------+ > > .. index:: > @@ -347,11 +347,11 @@ > as in C; see functions :func:`floor` and :func:`ceil` in the :mod:`math` module > for well-defined conversions. > > -(6) > +(4) > float also accepts the strings "nan" and "inf" with an optional prefix "+" > or "-" for Not a Number (NaN) and positive or negative infinity. > > -(7) > +(5) > Python defines ``pow(0, 0)`` and ``0 ** 0`` to be ``1``, as is common for > programming languages. > > _______________________________________________ > Python-3000-checkins mailing list > Python-3000-checkins at python.org > http://mail.python.org/mailman/listinfo/python-3000-checkins > -- --Guido van Rossum (home page: http://www.python.org/~guido/) From python-3000-checkins at python.org Mon Jan 7 03:06:10 2008 From: python-3000-checkins at python.org (alexandre.vassalotti) Date: Mon, 7 Jan 2008 03:06:10 +0100 (CET) Subject: [Python-3000-checkins] r59806 - python/branches/py3k/Objects/stringobject.c Message-ID: <20080107020610.84DF71E4015@bag.python.org> Author: alexandre.vassalotti Date: Mon Jan 7 03:06:10 2008 New Revision: 59806 Modified: python/branches/py3k/Objects/stringobject.c Log: Clean up PyString_Size(). Removed string_getsize(), since it was only useful when PyString_AsStringAndSize was able to convert an (ascii) Unicode object to a C string. Modified: python/branches/py3k/Objects/stringobject.c ============================================================================== --- python/branches/py3k/Objects/stringobject.c (original) +++ python/branches/py3k/Objects/stringobject.c Mon Jan 7 03:06:10 2008 @@ -494,25 +494,18 @@ /* -------------------------------------------------------------------- */ /* object api */ -static Py_ssize_t -string_getsize(register PyObject *op) -{ - char *s; - Py_ssize_t len; - if (PyString_AsStringAndSize(op, &s, &len)) - return -1; - return len; -} - Py_ssize_t PyString_Size(register PyObject *op) { - if (!PyString_Check(op)) - return string_getsize(op); + if (!PyString_Check(op)) { + PyErr_Format(PyExc_TypeError, + "expected bytes, %.200s found", Py_TYPE(op)->tp_name); + return -1; + } return Py_SIZE(op); } -/*const*/ char * +char * PyString_AsString(register PyObject *op) { if (!PyString_Check(op)) { @@ -520,7 +513,7 @@ "expected bytes, %.200s found", Py_TYPE(op)->tp_name); return NULL; } - return ((PyStringObject *)op) -> ob_sval; + return ((PyStringObject *)op)->ob_sval; } int From python-3000-checkins at python.org Mon Jan 7 10:13:04 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Mon, 7 Jan 2008 10:13:04 +0100 (CET) Subject: [Python-3000-checkins] r59812 - python/branches/py3k/Doc/library/stdtypes.rst Message-ID: <20080107091304.3568A1E4015@bag.python.org> Author: georg.brandl Date: Mon Jan 7 10:13:03 2008 New Revision: 59812 Modified: python/branches/py3k/Doc/library/stdtypes.rst Log: Remove obsolete note. Modified: python/branches/py3k/Doc/library/stdtypes.rst ============================================================================== --- python/branches/py3k/Doc/library/stdtypes.rst (original) +++ python/branches/py3k/Doc/library/stdtypes.rst Mon Jan 7 10:13:03 2008 @@ -141,43 +141,25 @@ This table summarizes the comparison operations: -+------------+-------------------------+-------+ -| Operation | Meaning | Notes | -+============+=========================+=======+ -| ``<`` | strictly less than | | -+------------+-------------------------+-------+ -| ``<=`` | less than or equal | | -+------------+-------------------------+-------+ -| ``>`` | strictly greater than | | -+------------+-------------------------+-------+ -| ``>=`` | greater than or equal | | -+------------+-------------------------+-------+ -| ``==`` | equal | | -+------------+-------------------------+-------+ -| ``!=`` | not equal | | -+------------+-------------------------+-------+ -| ``is`` | object identity | | -+------------+-------------------------+-------+ -| ``is not`` | negated object identity | | -+------------+-------------------------+-------+ - -.. index:: - pair: operator; comparison - operator: == - operator: < - operator: <= - operator: > - operator: >= - operator: != - operator: is - operator: is not - -Notes: - -(1) - ``!=`` can also be written ``<>``, but this is an obsolete usage - kept for backwards compatibility only. New code should always use - ``!=``. ++------------+-------------------------+ +| Operation | Meaning | ++============+=========================+ +| ``<`` | strictly less than | ++------------+-------------------------+ +| ``<=`` | less than or equal | ++------------+-------------------------+ +| ``>`` | strictly greater than | ++------------+-------------------------+ +| ``>=`` | greater than or equal | ++------------+-------------------------+ +| ``==`` | equal | ++------------+-------------------------+ +| ``!=`` | not equal | ++------------+-------------------------+ +| ``is`` | object identity | ++------------+-------------------------+ +| ``is not`` | negated object identity | ++------------+-------------------------+ .. index:: pair: object; numeric From python-3000-checkins at python.org Mon Jan 7 10:16:46 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Mon, 7 Jan 2008 10:16:46 +0100 (CET) Subject: [Python-3000-checkins] r59814 - python/branches/py3k/Doc/library/stdtypes.rst Message-ID: <20080107091646.A04361E4022@bag.python.org> Author: georg.brandl Date: Mon Jan 7 10:16:46 2008 New Revision: 59814 Modified: python/branches/py3k/Doc/library/stdtypes.rst Log: Fix note markup. Modified: python/branches/py3k/Doc/library/stdtypes.rst ============================================================================== --- python/branches/py3k/Doc/library/stdtypes.rst (original) +++ python/branches/py3k/Doc/library/stdtypes.rst Mon Jan 7 10:16:46 2008 @@ -296,9 +296,9 @@ +---------------------+---------------------------------+-------+--------------------+ | ``divmod(x, y)`` | the pair ``(x // y, x % y)`` | \(2) | :func:`divmod` | +---------------------+---------------------------------+-------+--------------------+ -| ``pow(x, y)`` | *x* to the power *y* | (5) | :func:`pow` | +| ``pow(x, y)`` | *x* to the power *y* | \(5) | :func:`pow` | +---------------------+---------------------------------+-------+--------------------+ -| ``x ** y`` | *x* to the power *y* | (5) | | +| ``x ** y`` | *x* to the power *y* | \(5) | | +---------------------+---------------------------------+-------+--------------------+ .. index:: From g.brandl at gmx.net Mon Jan 7 10:19:16 2008 From: g.brandl at gmx.net (Georg Brandl) Date: Mon, 07 Jan 2008 10:19:16 +0100 Subject: [Python-3000-checkins] r59789 - python/branches/py3k/Doc/library/stdtypes.rst In-Reply-To: References: <20080106173950.525C91E4012@bag.python.org> Message-ID: That's an oversight. I've corrected it now. Guido van Rossum schrieb: > Why do have some note numbers a \ and others don't? > > On Jan 6, 2008 9:39 AM, georg.brandl wrote: >> Author: georg.brandl >> Date: Sun Jan 6 18:39:49 2008 >> New Revision: 59789 >> >> Modified: >> python/branches/py3k/Doc/library/stdtypes.rst >> Log: >> Use consistent note numbers. >> >> >> Modified: python/branches/py3k/Doc/library/stdtypes.rst >> ============================================================================== >> --- python/branches/py3k/Doc/library/stdtypes.rst (original) >> +++ python/branches/py3k/Doc/library/stdtypes.rst Sun Jan 6 18:39:49 2008 >> @@ -303,7 +303,7 @@ >> +---------------------+---------------------------------+-------+--------------------+ >> | ``int(x)`` | *x* converted to integer | \(3) | :func:`int` | >> +---------------------+---------------------------------+-------+--------------------+ >> -| ``float(x)`` | *x* converted to floating point | \(6) | :func:`float` | >> +| ``float(x)`` | *x* converted to floating point | \(4) | :func:`float` | >> +---------------------+---------------------------------+-------+--------------------+ >> | ``complex(re, im)`` | a complex number with real part | | :func:`complex` | >> | | *re*, imaginary part *im*. | | | >> @@ -314,9 +314,9 @@ >> +---------------------+---------------------------------+-------+--------------------+ >> | ``divmod(x, y)`` | the pair ``(x // y, x % y)`` | \(2) | :func:`divmod` | >> +---------------------+---------------------------------+-------+--------------------+ >> -| ``pow(x, y)`` | *x* to the power *y* | (7) | :func:`pow` | >> +| ``pow(x, y)`` | *x* to the power *y* | (5) | :func:`pow` | >> +---------------------+---------------------------------+-------+--------------------+ >> -| ``x ** y`` | *x* to the power *y* | (7) | | >> +| ``x ** y`` | *x* to the power *y* | (5) | | >> +---------------------+---------------------------------+-------+--------------------+ >> >> .. index:: >> @@ -347,11 +347,11 @@ >> as in C; see functions :func:`floor` and :func:`ceil` in the :mod:`math` module >> for well-defined conversions. >> >> -(6) >> +(4) >> float also accepts the strings "nan" and "inf" with an optional prefix "+" >> or "-" for Not a Number (NaN) and positive or negative infinity. >> >> -(7) >> +(5) >> Python defines ``pow(0, 0)`` and ``0 ** 0`` to be ``1``, as is common for >> programming languages. >> >> _______________________________________________ >> Python-3000-checkins mailing list >> Python-3000-checkins at python.org >> http://mail.python.org/mailman/listinfo/python-3000-checkins >> > > > From python-3000-checkins at python.org Mon Jan 7 10:27:37 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Mon, 7 Jan 2008 10:27:37 +0100 (CET) Subject: [Python-3000-checkins] r59816 - python/branches/py3k/Doc/reference/datamodel.rst Message-ID: <20080107092737.169831E4015@bag.python.org> Author: georg.brandl Date: Mon Jan 7 10:27:36 2008 New Revision: 59816 Modified: python/branches/py3k/Doc/reference/datamodel.rst Log: Fix reverse Ximenez symptom. Modified: python/branches/py3k/Doc/reference/datamodel.rst ============================================================================== --- python/branches/py3k/Doc/reference/datamodel.rst (original) +++ python/branches/py3k/Doc/reference/datamodel.rst Mon Jan 7 10:27:36 2008 @@ -170,7 +170,7 @@ These represent elements from the mathematical set of integers (positive and negative). - There are three types of integers: + There are two types of integers: Plain integers .. index:: From python-3000-checkins at python.org Mon Jan 7 10:29:35 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Mon, 7 Jan 2008 10:29:35 +0100 (CET) Subject: [Python-3000-checkins] r59817 - python/branches/py3k/Doc/reference/datamodel.rst Message-ID: <20080107092935.122CD1E4015@bag.python.org> Author: georg.brandl Date: Mon Jan 7 10:29:34 2008 New Revision: 59817 Modified: python/branches/py3k/Doc/reference/datamodel.rst Log: Remove paragraph about old-style classes. Modified: python/branches/py3k/Doc/reference/datamodel.rst ============================================================================== --- python/branches/py3k/Doc/reference/datamodel.rst (original) +++ python/branches/py3k/Doc/reference/datamodel.rst Mon Jan 7 10:29:34 2008 @@ -1013,15 +1013,7 @@ This manual is not up-to-date with respect to new-style classes. For now, please see http://www.python.org/doc/newstyle/ for more information. -.. index:: - single: class; new-style - single: class; classic - single: class; old-style - -The plan is to eventually drop old-style classes, leaving only the semantics of -new-style classes. This change will probably only be feasible in Python 3.0. - -XXX Remove old style classes from docs +.. XXX remove old style classes from docs .. _specialnames: From python-3000-checkins at python.org Mon Jan 7 18:13:10 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Mon, 7 Jan 2008 18:13:10 +0100 (CET) Subject: [Python-3000-checkins] r59825 - in python/branches/py3k: Lib/test/test_imp.py Lib/test/test_import.py Python/import.c Message-ID: <20080107171310.5E76C1E4027@bag.python.org> Author: christian.heimes Date: Mon Jan 7 18:13:09 2008 New Revision: 59825 Modified: python/branches/py3k/Lib/test/test_imp.py python/branches/py3k/Lib/test/test_import.py python/branches/py3k/Python/import.c Log: Issue #1762972: Readded the reload() function as imp.reload() Modified: python/branches/py3k/Lib/test/test_imp.py ============================================================================== --- python/branches/py3k/Lib/test/test_imp.py (original) +++ python/branches/py3k/Lib/test/test_imp.py Mon Jan 7 18:13:09 2008 @@ -60,6 +60,14 @@ '"""Tokenization help for Python programs.\n') fp.close() + def test_reload(self): + import marshal + imp.reload(marshal) + import string + imp.reload(string) + ## import sys + ## self.assertRaises(ImportError, reload, sys) + def test_main(): test_support.run_unittest( Modified: python/branches/py3k/Lib/test/test_import.py ============================================================================== --- python/branches/py3k/Lib/test/test_import.py (original) +++ python/branches/py3k/Lib/test/test_import.py Mon Jan 7 18:13:09 2008 @@ -7,6 +7,7 @@ import sys import py_compile import warnings +import imp from test.test_support import unlink, TESTFN, unload @@ -160,6 +161,45 @@ warnings.simplefilter('error', ImportWarning) self.assertRaises(ImportWarning, __import__, "site-packages") + def test_failing_reload(self): + # A failing reload should leave the module object in sys.modules. + source = TESTFN + ".py" + with open(source, "w") as f: + f.write("a = 1\nb=2\n") + + sys.path.insert(0, os.curdir) + try: + mod = __import__(TESTFN) + self.assert_(TESTFN in sys.modules, "expected module in sys.modules") + self.assertEquals(mod.a, 1, "module has wrong attribute values") + self.assertEquals(mod.b, 2, "module has wrong attribute values") + + # On WinXP, just replacing the .py file wasn't enough to + # convince reload() to reparse it. Maybe the timestamp didn't + # move enough. We force it to get reparsed by removing the + # compiled file too. + remove_files(TESTFN) + + # Now damage the module. + with open(source, "w") as f: + f.write("a = 10\nb=20//0\n") + + self.assertRaises(ZeroDivisionError, imp.reload, mod) + # But we still expect the module to be in sys.modules. + mod = sys.modules.get(TESTFN) + self.failIf(mod is None, "expected module to still be in sys.modules") + + # We should have replaced a w/ 10, but the old b value should + # stick. + self.assertEquals(mod.a, 10, "module has wrong attribute values") + self.assertEquals(mod.b, 2, "module has wrong attribute values") + + finally: + sys.path.pop(0) + remove_files(TESTFN) + if TESTFN in sys.modules: + del sys.modules[TESTFN] + class PathsTests(unittest.TestCase): SAMPLES = ('test', 'test\u00e4\u00f6\u00fc\u00df', 'test\u00e9\u00e8', 'test\u00b0\u00b3\u00b2') Modified: python/branches/py3k/Python/import.c ============================================================================== --- python/branches/py3k/Python/import.c (original) +++ python/branches/py3k/Python/import.c Mon Jan 7 18:13:09 2008 @@ -2931,6 +2931,17 @@ return PyModule_New(name); } +static PyObject * +imp_reload(PyObject *self, PyObject *v) +{ + return PyImport_ReloadModule(v); +} + +PyDoc_STRVAR(doc_reload, +"reload(module) -> module\n\ +\n\ +Reload the module. The module must have been successfully imported before."); + /* Doc strings */ PyDoc_STRVAR(doc_imp, @@ -2989,6 +3000,7 @@ {"lock_held", imp_lock_held, METH_NOARGS, doc_lock_held}, {"acquire_lock", imp_acquire_lock, METH_NOARGS, doc_acquire_lock}, {"release_lock", imp_release_lock, METH_NOARGS, doc_release_lock}, + {"reload", imp_reload, METH_O, doc_reload}, /* The rest are obsolete */ {"get_frozen_object", imp_get_frozen_object, METH_VARARGS}, {"init_builtin", imp_init_builtin, METH_VARARGS}, From python-3000-checkins at python.org Mon Jan 7 18:19:17 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Mon, 7 Jan 2008 18:19:17 +0100 (CET) Subject: [Python-3000-checkins] r59826 - in python/branches/py3k: Doc/library/collections.rst Doc/library/getopt.rst Doc/library/imp.rst Doc/library/logging.rst Doc/library/socket.rst Doc/library/stdtypes.rst Doc/tutorial/controlflow.rst Doc/tutorial/introduction.rst Lib/abc.py Lib/collections.py Lib/test/test_abc.py Lib/test/test_socket.py Misc/NEWS Misc/developers.txt Modules/socketmodule.c Modules/socketmodule.h Python/future.c configure configure.in pyconfig.h.in Message-ID: <20080107171917.88B801E4002@bag.python.org> Author: christian.heimes Date: Mon Jan 7 18:19:16 2008 New Revision: 59826 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/collections.rst python/branches/py3k/Doc/library/getopt.rst python/branches/py3k/Doc/library/imp.rst python/branches/py3k/Doc/library/logging.rst python/branches/py3k/Doc/library/socket.rst python/branches/py3k/Doc/library/stdtypes.rst python/branches/py3k/Doc/tutorial/controlflow.rst python/branches/py3k/Doc/tutorial/introduction.rst python/branches/py3k/Lib/abc.py python/branches/py3k/Lib/collections.py python/branches/py3k/Lib/test/test_abc.py python/branches/py3k/Lib/test/test_socket.py python/branches/py3k/Misc/NEWS python/branches/py3k/Misc/developers.txt python/branches/py3k/Modules/socketmodule.c python/branches/py3k/Modules/socketmodule.h python/branches/py3k/Python/future.c python/branches/py3k/configure python/branches/py3k/configure.in python/branches/py3k/pyconfig.h.in Log: Copied doc for reload() from trunk's function.rst to imp.rst Modified: python/branches/py3k/Doc/library/collections.rst ============================================================================== --- python/branches/py3k/Doc/library/collections.rst (original) +++ python/branches/py3k/Doc/library/collections.rst Mon Jan 7 18:19:16 2008 @@ -489,7 +489,7 @@ >>> Point._make(t) Point(x=11, y=22) -.. method:: somenamedtuple._asdict() +.. method:: namedtuple._asdict() Return a new dict which maps field names to their corresponding values: @@ -498,7 +498,7 @@ >>> p._asdict() {'x': 11, 'y': 22} -.. method:: somenamedtuple._replace(kwargs) +.. method:: namedtuple._replace(kwargs) Return a new instance of the named tuple replacing specified fields with new values: @@ -511,7 +511,7 @@ >>> for partnum, record in inventory.items(): ... inventory[partnum] = record._replace(price=newprices[partnum], updated=time.now()) -.. attribute:: somenamedtuple._fields +.. attribute:: namedtuple._fields Tuple of strings listing the field names. This is useful for introspection and for creating new named tuple types from existing named tuples. @@ -541,15 +541,28 @@ Point(x=11, y=22) Since a named tuple is a regular Python class, it is easy to add or change -functionality. For example, the display format can be changed by overriding -the :meth:`__repr__` method: +functionality with a subclass. Here is how to add a calculated field and +a fixed-width print format:: -:: - - >>> Point = namedtuple('Point', 'x y') - >>> Point.__repr__ = lambda self: 'Point(%.3f, %.3f)' % self - >>> Point(x=11, y=22) - Point(11.000, 22.000) + >>> class Point(namedtuple('Point', 'x y')): + @property + def hypot(self): + return (self.x ** 2 + self.y ** 2) ** 0.5 + def __repr__(self): + return 'Point(x=%.3f, y=%.3f, hypot=%.3f)' % (self.x, self.y, self.hypot) + + >>> print Point(3, 4),'\n', Point(2, 5), '\n', Point(9./7, 6) + Point(x=3.000, y=4.000, hypot=5.000) + Point(x=2.000, y=5.000, hypot=5.385) + Point(x=1.286, y=6.000, hypot=6.136) + +Another use for subclassing is to replace performance critcal methods with +faster versions that bypass error-checking and localize variable access:: + + >>> class Point(namedtuple('Point', 'x y')): + _make = classmethod(tuple.__new__) + def _replace(self, _map=map, **kwds): + return self._make(_map(kwds.pop, ('x', 'y'), self)) Default values can be implemented by starting with a prototype instance and customizing it with :meth:`_replace`: Modified: python/branches/py3k/Doc/library/getopt.rst ============================================================================== --- python/branches/py3k/Doc/library/getopt.rst (original) +++ python/branches/py3k/Doc/library/getopt.rst Mon Jan 7 18:19:16 2008 @@ -11,7 +11,7 @@ It supports the same conventions as the Unix :cfunc:`getopt` function (including the special meanings of arguments of the form '``-``' and '``--``'). Long options similar to those supported by GNU software may be used as well via an -optional third argument. This module provides a single function and an +optional third argument. This module provides two functions and an exception: Modified: python/branches/py3k/Doc/library/imp.rst ============================================================================== --- python/branches/py3k/Doc/library/imp.rst (original) +++ python/branches/py3k/Doc/library/imp.rst Mon Jan 7 18:19:16 2008 @@ -123,6 +123,68 @@ function does nothing. +.. function:: reload(module) + + Reload a previously imported *module*. The argument must be a module object, so + it must have been successfully imported before. This is useful if you have + edited the module source file using an external editor and want to try out the + new version without leaving the Python interpreter. The return value is the + module object (the same as the *module* argument). + + When ``reload(module)`` is executed: + + * Python modules' code is recompiled and the module-level code reexecuted, + defining a new set of objects which are bound to names in the module's + dictionary. The ``init`` function of extension modules is not called a second + time. + + * As with all other objects in Python the old objects are only reclaimed after + their reference counts drop to zero. + + * The names in the module namespace are updated to point to any new or changed + objects. + + * Other references to the old objects (such as names external to the module) are + not rebound to refer to the new objects and must be updated in each namespace + where they occur if that is desired. + + There are a number of other caveats: + + If a module is syntactically correct but its initialization fails, the first + :keyword:`import` statement for it does not bind its name locally, but does + store a (partially initialized) module object in ``sys.modules``. To reload the + module you must first :keyword:`import` it again (this will bind the name to the + partially initialized module object) before you can :func:`reload` it. + + When a module is reloaded, its dictionary (containing the module's global + variables) is retained. Redefinitions of names will override the old + definitions, so this is generally not a problem. If the new version of a module + does not define a name that was defined by the old version, the old definition + remains. This feature can be used to the module's advantage if it maintains a + global table or cache of objects --- with a :keyword:`try` statement it can test + for the table's presence and skip its initialization if desired:: + + try: + cache + except NameError: + cache = {} + + It is legal though generally not very useful to reload built-in or dynamically + loaded modules, except for :mod:`sys`, :mod:`__main__` and :mod:`__builtin__`. + In many cases, however, extension modules are not designed to be initialized + more than once, and may fail in arbitrary ways when reloaded. + + If a module imports objects from another module using :keyword:`from` ... + :keyword:`import` ..., calling :func:`reload` for the other module does not + redefine the objects imported from it --- one way around this is to re-execute + the :keyword:`from` statement, another is to use :keyword:`import` and qualified + names (*module*.*name*) instead. + + If a module instantiates instances of a class, reloading the module that defines + the class does not affect the method definitions of the instances --- they + continue to use the old class definition. The same is true for derived classes. + + The following constants with integer values, defined in this module, are used to indicate the search result of :func:`find_module`. Modified: python/branches/py3k/Doc/library/logging.rst ============================================================================== --- python/branches/py3k/Doc/library/logging.rst (original) +++ python/branches/py3k/Doc/library/logging.rst Mon Jan 7 18:19:16 2008 @@ -688,7 +688,8 @@ Does basic configuration for the logging system by creating a :class:`StreamHandler` with a default :class:`Formatter` and adding it to the - root logger. The functions :func:`debug`, :func:`info`, :func:`warning`, + root logger. The function does nothing if any handlers have been defined for + the root logger. The functions :func:`debug`, :func:`info`, :func:`warning`, :func:`error` and :func:`critical` will call :func:`basicConfig` automatically if no handlers are defined for the root logger. @@ -2384,24 +2385,24 @@ The output looks like this:: - 2005-03-23 23:47:11,663 - spam_application - INFO - + 2005-03-23 23:47:11,663 - spam_application - INFO - creating an instance of auxiliary_module.Auxiliary - 2005-03-23 23:47:11,665 - spam_application.auxiliary.Auxiliary - INFO - + 2005-03-23 23:47:11,665 - spam_application.auxiliary.Auxiliary - INFO - creating an instance of Auxiliary - 2005-03-23 23:47:11,665 - spam_application - INFO - + 2005-03-23 23:47:11,665 - spam_application - INFO - created an instance of auxiliary_module.Auxiliary - 2005-03-23 23:47:11,668 - spam_application - INFO - + 2005-03-23 23:47:11,668 - spam_application - INFO - calling auxiliary_module.Auxiliary.do_something - 2005-03-23 23:47:11,668 - spam_application.auxiliary.Auxiliary - INFO - + 2005-03-23 23:47:11,668 - spam_application.auxiliary.Auxiliary - INFO - doing something - 2005-03-23 23:47:11,669 - spam_application.auxiliary.Auxiliary - INFO - + 2005-03-23 23:47:11,669 - spam_application.auxiliary.Auxiliary - INFO - done doing something - 2005-03-23 23:47:11,670 - spam_application - INFO - + 2005-03-23 23:47:11,670 - spam_application - INFO - finished auxiliary_module.Auxiliary.do_something - 2005-03-23 23:47:11,671 - spam_application - INFO - + 2005-03-23 23:47:11,671 - spam_application - INFO - calling auxiliary_module.some_function() - 2005-03-23 23:47:11,672 - spam_application.auxiliary - INFO - + 2005-03-23 23:47:11,672 - spam_application.auxiliary - INFO - received a call to "some_function" - 2005-03-23 23:47:11,673 - spam_application - INFO - + 2005-03-23 23:47:11,673 - spam_application - INFO - done with auxiliary_module.some_function() Modified: python/branches/py3k/Doc/library/socket.rst ============================================================================== --- python/branches/py3k/Doc/library/socket.rst (original) +++ python/branches/py3k/Doc/library/socket.rst Mon Jan 7 18:19:16 2008 @@ -65,6 +65,27 @@ AF_NETLINK sockets are represented as pairs ``pid, groups``. + +Linux-only support for TIPC is also available using the :const:`AF_TIPC` +address family. TIPC is an open, non-IP based networked protocol designed +for use in clustered computer environments. Addresses are represented by a +tuple, and the fields depend on the address type. The general tuple form is +``(addr_type, v1, v2, v3 [, scope])``, where: + + - *addr_type* is one of TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME, or + TIPC_ADDR_ID. + - *scope* is one of TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE, and + TIPC_NODE_SCOPE. + - If *addr_type* is TIPC_ADDR_NAME, then *v1* is the server type, *v2* is + the port identifier, and *v3* should be 0. + + If *addr_type* is TIPC_ADDR_NAMESEQ, then *v1* is the server type, *v2* + is the lower port number, and *v3* is the upper port number. + + If *addr_type* is TIPC_ADDR_ID, then *v1* is the node, *v2* is the + reference, and *v3* should be set to 0. + + All errors raise exceptions. The normal exceptions for invalid argument types and out-of-memory conditions can be raised; errors related to socket or address semantics raise the error :exc:`socket.error`. @@ -162,6 +183,12 @@ :meth:`ioctl` method of socket objects. +.. data:: TIPC_* + + TIPC related constants, matching the ones exported by the C socket API. See + the TIPC documentation for more information. + + .. data:: has_ipv6 This constant contains a boolean value which indicates if IPv6 is supported on Modified: python/branches/py3k/Doc/library/stdtypes.rst ============================================================================== --- python/branches/py3k/Doc/library/stdtypes.rst (original) +++ python/branches/py3k/Doc/library/stdtypes.rst Mon Jan 7 18:19:16 2008 @@ -389,9 +389,9 @@ | ``x & y`` | bitwise :dfn:`and` of *x* and | | | | *y* | | +------------+--------------------------------+----------+ -| ``x << n`` | *x* shifted left by *n* bits | (1), (2) | +| ``x << n`` | *x* shifted left by *n* bits | (1)(2) | +------------+--------------------------------+----------+ -| ``x >> n`` | *x* shifted right by *n* bits | (1), (3) | +| ``x >> n`` | *x* shifted right by *n* bits | (1)(3) | +------------+--------------------------------+----------+ | ``~x`` | the bits of *x* inverted | | +------------+--------------------------------+----------+ @@ -436,7 +436,7 @@ support: -.. method:: container.__iter__() +.. method:: object.__iter__() Return an iterator object. The object is required to support the iterator protocol described below. If a container supports different types of @@ -537,7 +537,7 @@ Most sequence types support the following operations. The ``in`` and ``not in`` operations have the same priorities as the comparison operations. The ``+`` and ``*`` operations have the same priority as the corresponding numeric operations. -[#]_ +[#]_ Additional methods are provided for :ref:`typesseq-mutable`. This table lists the sequence operations sorted in ascending priority (operations in the same box have the same priority). In the table, *s* and *t* @@ -560,9 +560,9 @@ +------------------+--------------------------------+----------+ | ``s[i]`` | *i*'th item of *s*, origin 0 | \(3) | +------------------+--------------------------------+----------+ -| ``s[i:j]`` | slice of *s* from *i* to *j* | (3), (4) | +| ``s[i:j]`` | slice of *s* from *i* to *j* | (3)(4) | +------------------+--------------------------------+----------+ -| ``s[i:j:k]`` | slice of *s* from *i* to *j* | (3), (5) | +| ``s[i:j:k]`` | slice of *s* from *i* to *j* | (3)(5) | | | with step *k* | | +------------------+--------------------------------+----------+ | ``len(s)`` | length of *s* | | Modified: python/branches/py3k/Doc/tutorial/controlflow.rst ============================================================================== --- python/branches/py3k/Doc/tutorial/controlflow.rst (original) +++ python/branches/py3k/Doc/tutorial/controlflow.rst Mon Jan 7 18:19:16 2008 @@ -595,10 +595,57 @@ No, really, it doesn't do anything. +.. _tut-codingstyle: + +Intermezzo: Coding Style +======================== + +.. sectionauthor:: Georg Brandl +.. index:: pair: coding; style + +Now that you are about to write longer, more complex pieces of Python, it is a +good time to talk about *coding style*. Most languages can be written (or more +concise, *formatted*) in different styles; some are more readable than others. +Making it easy for others to read your code is always a good idea, and adopting +a nice coding style helps tremendously for that. + +For Python, :pep:`8` has emerged as the style guide that most projects adher to; +it promotes a very readable and eye-pleasing coding style. Every Python +developer should read it at some point; here are the most important points +extracted for you: + +* Use 4-space indentation, and no tabs. + + 4 spaces are a good compromise between small indentation (allows greater + nesting depth) and large indentation (easier to read). Tabs introduce + confusion, and are best left out. + +* Wrap lines so that they don't exceed 79 characters. + + This helps users with small displays and makes it possible to have several + code files side-by-side on larger displays. + +* Use blank lines to separate functions and classes, and larger blocks of + code inside functions. + +* When possible, put comments on a line of their own. + +* Use docstrings. + +* Use spaces around operators and after commas, but not directly inside + bracketing constructs: ``a = f(1, 2) + g(3, 4)``. + +* Name your classes and functions consistently; the convention is to use + ``CamelCase`` for classes and ``lower_case_with_underscores`` for functions + and methods. Always use ``self`` as the name for the first method argument. + +* Don't use fancy encodings if your code is meant to be used in international + environments. Plain ASCII works best in any case. + .. rubric:: Footnotes -.. [#] Actually, *call by object reference* would be a better description, since if a - mutable object is passed, the caller will see any changes the callee makes to it - (items inserted into a list). +.. [#] Actually, *call by object reference* would be a better description, + since if a mutable object is passed, the caller will see any changes the + callee makes to it (items inserted into a list). Modified: python/branches/py3k/Doc/tutorial/introduction.rst ============================================================================== --- python/branches/py3k/Doc/tutorial/introduction.rst (original) +++ python/branches/py3k/Doc/tutorial/introduction.rst Mon Jan 7 18:19:16 2008 @@ -548,7 +548,7 @@ ... # the sum of two elements defines the next ... a, b = 0, 1 >>> while b < 10: - ... print(b) + ... print b ... a, b = b, a+b ... 1 Modified: python/branches/py3k/Lib/abc.py ============================================================================== --- python/branches/py3k/Lib/abc.py (original) +++ python/branches/py3k/Lib/abc.py Mon Jan 7 18:19:16 2008 @@ -187,7 +187,7 @@ cls._abc_negative_cache.add(subclass) return ok # Check if it's a direct subclass - if cls in subclass.__mro__: + if cls in getattr(subclass, '__mro__', ()): cls._abc_cache.add(subclass) return True # Check if it's a subclass of a registered class (recursive) Modified: python/branches/py3k/Lib/collections.py ============================================================================== --- python/branches/py3k/Lib/collections.py (original) +++ python/branches/py3k/Lib/collections.py Mon Jan 7 18:19:16 2008 @@ -65,9 +65,9 @@ def __new__(cls, %(argtxt)s): return tuple.__new__(cls, (%(argtxt)s)) \n @classmethod - def _make(cls, iterable): + def _make(cls, iterable, new=tuple.__new__, len=len): 'Make a new %(typename)s object from a sequence or iterable' - result = tuple.__new__(cls, iterable) + result = new(cls, iterable) if len(result) != %(numfields)d: raise TypeError('Expected %(numfields)d arguments, got %%d' %% len(result)) return result \n @@ -115,8 +115,22 @@ assert p == loads(dumps(p)) # test and demonstrate ability to override methods - Point.__repr__ = lambda self: 'Point(%.3f, %.3f)' % self - print(p) + class Point(namedtuple('Point', 'x y')): + @property + def hypot(self): + return (self.x ** 2 + self.y ** 2) ** 0.5 + def __repr__(self): + return 'Point(x=%.3f, y=%.3f, hypot=%.3f)' % (self.x, self.y, self.hypot) + + print(Point(3, 4),'\n', Point(2, 5), '\n', Point(9./7, 6)) + + class Point(namedtuple('Point', 'x y')): + 'Point class with optimized _make() and _replace() without error-checking' + _make = classmethod(tuple.__new__) + def _replace(self, _map=map, **kwds): + return self._make(_map(kwds.pop, ('x', 'y'), self)) + + print(Point(11, 22)._replace(x=100)) import doctest TestResults = namedtuple('TestResults', 'failed attempted') Modified: python/branches/py3k/Lib/test/test_abc.py ============================================================================== --- python/branches/py3k/Lib/test/test_abc.py (original) +++ python/branches/py3k/Lib/test/test_abc.py Mon Jan 7 18:19:16 2008 @@ -56,10 +56,18 @@ self.assertEqual(F.__abstractmethods__, {"bar"}) self.assertRaises(TypeError, F) # because bar is abstract now + def test_subclass_oldstyle_class(self): + class A: + __metaclass__ = abc.ABCMeta + class OldstyleClass: + pass + self.assertFalse(issubclass(OldstyleClass, A)) + self.assertFalse(issubclass(A, OldstyleClass)) + def test_registration_basics(self): class A(metaclass=abc.ABCMeta): pass - class B: + class B(object): pass b = B() self.assertEqual(issubclass(B, A), False) @@ -94,7 +102,7 @@ class A1(A): pass self.assertRaises(RuntimeError, A1.register, A) # cycles not allowed - class B: + class B(object): pass A1.register(B) # ok A1.register(B) # should pass silently @@ -135,7 +143,7 @@ def test_all_new_methods_are_called(self): class A(metaclass=abc.ABCMeta): pass - class B: + class B(object): counter = 0 def __new__(cls): B.counter += 1 Modified: python/branches/py3k/Lib/test/test_socket.py ============================================================================== --- python/branches/py3k/Lib/test/test_socket.py (original) +++ python/branches/py3k/Lib/test/test_socket.py Mon Jan 7 18:19:16 2008 @@ -1114,6 +1114,85 @@ buf = bytes(MSG) self.serv_conn.send(buf) + +TIPC_STYPE = 2000 +TIPC_LOWER = 200 +TIPC_UPPER = 210 + +def isTipcAvailable(): + """Check if the TIPC module is loaded + + The TIPC module is not loaded automatically on Ubuntu and probably + other Linux distros. + """ + if not hasattr(socket, "AF_TIPC"): + return False + if not os.path.isfile("/proc/modules"): + return False + with open("/proc/modules") as f: + for line in f: + if line.startswith("tipc "): + return True + if test_support.debug: + print("TIPC module is not loaded, please 'sudo modprobe tipc'") + return False + +class TIPCTest (unittest.TestCase): + def testRDM(self): + srv = socket.socket(socket.AF_TIPC, socket.SOCK_RDM) + cli = socket.socket(socket.AF_TIPC, socket.SOCK_RDM) + + srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + srvaddr = (socket.TIPC_ADDR_NAMESEQ, TIPC_STYPE, + TIPC_LOWER, TIPC_UPPER) + srv.bind(srvaddr) + + sendaddr = (socket.TIPC_ADDR_NAME, TIPC_STYPE, + TIPC_LOWER + int((TIPC_UPPER - TIPC_LOWER) / 2), 0) + cli.sendto(MSG, sendaddr) + + msg, recvaddr = srv.recvfrom(1024) + + self.assertEqual(cli.getsockname(), recvaddr) + self.assertEqual(msg, MSG) + + +class TIPCThreadableTest (unittest.TestCase, ThreadableTest): + def __init__(self, methodName = 'runTest'): + unittest.TestCase.__init__(self, methodName = methodName) + ThreadableTest.__init__(self) + + def setUp(self): + self.srv = socket.socket(socket.AF_TIPC, socket.SOCK_STREAM) + self.srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + srvaddr = (socket.TIPC_ADDR_NAMESEQ, TIPC_STYPE, + TIPC_LOWER, TIPC_UPPER) + self.srv.bind(srvaddr) + self.srv.listen(5) + self.serverExplicitReady() + self.conn, self.connaddr = self.srv.accept() + + def clientSetUp(self): + # The is a hittable race between serverExplicitReady() and the + # accept() call; sleep a little while to avoid it, otherwise + # we could get an exception + time.sleep(0.1) + self.cli = socket.socket(socket.AF_TIPC, socket.SOCK_STREAM) + addr = (socket.TIPC_ADDR_NAME, TIPC_STYPE, + TIPC_LOWER + int((TIPC_UPPER - TIPC_LOWER) / 2), 0) + self.cli.connect(addr) + self.cliaddr = self.cli.getsockname() + + def testStream(self): + msg = self.conn.recv(1024) + self.assertEqual(msg, MSG) + self.assertEqual(self.cliaddr, self.connaddr) + + def _testStream(self): + self.cli.send(MSG) + self.cli.close() + + def test_main(): tests = [GeneralModuleTests, BasicTCPTest, TCPCloserTest, TCPTimeoutTest, TestExceptions, BufferIOTest, BasicTCPTest2] @@ -1134,6 +1213,9 @@ tests.append(BasicSocketPairTest) if sys.platform == 'linux2': tests.append(TestLinuxAbstractNamespace) + if isTipcAvailable(): + tests.append(TIPCTest) + tests.append(TIPCThreadableTest) thread_info = test_support.threading_setup() test_support.run_unittest(*tests) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Jan 7 18:19:16 2008 @@ -44,6 +44,7 @@ Extension Modules ----------------- +- Issue #1762972: Readded the reload() function as imp.reload() Library ------- Modified: python/branches/py3k/Misc/developers.txt ============================================================================== --- python/branches/py3k/Misc/developers.txt (original) +++ python/branches/py3k/Misc/developers.txt Mon Jan 7 18:19:16 2008 @@ -17,6 +17,9 @@ Permissions History ------------------- +- Mark Dickinson was given SVN access on 6 January 2008 by Facundo + Batista for his work on mathemathics and number related issues. + - Amaury Forgeot d'Arc was given SVN access on 9 November 2007 by MvL, for general contributions to Python. Modified: python/branches/py3k/Modules/socketmodule.c ============================================================================== --- python/branches/py3k/Modules/socketmodule.c (original) +++ python/branches/py3k/Modules/socketmodule.c Mon Jan 7 18:19:16 2008 @@ -7,7 +7,8 @@ Limitations: - Only AF_INET, AF_INET6 and AF_UNIX address families are supported in a - portable manner, though AF_PACKET and AF_NETLINK are supported under Linux. + portable manner, though AF_PACKET, AF_NETLINK and AF_TIPC are supported + under Linux. - No read/write operations (use sendall/recv or makefile instead). - Additional restrictions apply on some non-Unix platforms (compensated for by socket.py). @@ -51,6 +52,25 @@ the Ethernet protocol number to be received. For example: ("eth0",0x1234). Optional 3rd,4th,5th elements in the tuple specify packet-type and ha-type/addr. +- an AF_TIPC socket address is expressed as + (addr_type, v1, v2, v3 [, scope]); where addr_type can be one of: + TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME, and TIPC_ADDR_ID; + and scope can be one of: + TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE, and TIPC_NODE_SCOPE. + The meaning of v1, v2 and v3 depends on the value of addr_type: + if addr_type is TIPC_ADDR_NAME: + v1 is the server type + v2 is the port identifier + v3 is ignored + if addr_type is TIPC_ADDR_NAMESEQ: + v1 is the server type + v2 is the lower port number + v3 is the upper port number + if addr_type is TIPC_ADDR_ID: + v1 is the node + v2 is the ref + v3 is ignored + Local naming conventions: @@ -1058,6 +1078,39 @@ } #endif +#ifdef HAVE_LINUX_TIPC_H + case AF_TIPC: + { + struct sockaddr_tipc *a = (struct sockaddr_tipc *) addr; + if (a->addrtype == TIPC_ADDR_NAMESEQ) { + return Py_BuildValue("IIIII", + a->addrtype, + a->addr.nameseq.type, + a->addr.nameseq.lower, + a->addr.nameseq.upper, + a->scope); + } else if (a->addrtype == TIPC_ADDR_NAME) { + return Py_BuildValue("IIIII", + a->addrtype, + a->addr.name.name.type, + a->addr.name.name.instance, + a->addr.name.name.instance, + a->scope); + } else if (a->addrtype == TIPC_ADDR_ID) { + return Py_BuildValue("IIIII", + a->addrtype, + a->addr.id.node, + a->addr.id.ref, + 0, + a->scope); + } else { + PyErr_SetString(PyExc_TypeError, + "Invalid address type"); + return NULL; + } + } +#endif + /* More cases here... */ default: @@ -1343,6 +1396,56 @@ } #endif +#ifdef HAVE_LINUX_TIPC_H + case AF_TIPC: + { + unsigned int atype, v1, v2, v3; + unsigned int scope = TIPC_CLUSTER_SCOPE; + struct sockaddr_tipc *addr; + + if (!PyTuple_Check(args)) { + PyErr_Format( + PyExc_TypeError, + "getsockaddrarg: " + "AF_TIPC address must be tuple, not %.500s", + Py_TYPE(args)->tp_name); + return 0; + } + + if (!PyArg_ParseTuple(args, + "IIII|I;Invalid TIPC address format", + &atype, &v1, &v2, &v3, &scope)) + return 0; + + addr = (struct sockaddr_tipc *) addr_ret; + memset(addr, 0, sizeof(struct sockaddr_tipc)); + + addr->family = AF_TIPC; + addr->scope = scope; + addr->addrtype = atype; + + if (atype == TIPC_ADDR_NAMESEQ) { + addr->addr.nameseq.type = v1; + addr->addr.nameseq.lower = v2; + addr->addr.nameseq.upper = v3; + } else if (atype == TIPC_ADDR_NAME) { + addr->addr.name.name.type = v1; + addr->addr.name.name.instance = v2; + } else if (atype == TIPC_ADDR_ID) { + addr->addr.id.node = v1; + addr->addr.id.ref = v2; + } else { + /* Shouldn't happen */ + PyErr_SetString(PyExc_TypeError, "Invalid address type"); + return 0; + } + + *len_ret = sizeof(*addr); + + return 1; + } +#endif + /* More cases here... */ default: @@ -1428,6 +1531,14 @@ } #endif +#ifdef HAVE_LINUX_TIPC_H + case AF_TIPC: + { + *len_ret = sizeof (struct sockaddr_tipc); + return 1; + } +#endif + /* More cases here... */ default: @@ -4211,6 +4322,47 @@ PyModule_AddIntConstant(m, "PACKET_FASTROUTE", PACKET_FASTROUTE); #endif +#ifdef HAVE_LINUX_TIPC_H + PyModule_AddIntConstant(m, "AF_TIPC", AF_TIPC); + + /* for addresses */ + PyModule_AddIntConstant(m, "TIPC_ADDR_NAMESEQ", TIPC_ADDR_NAMESEQ); + PyModule_AddIntConstant(m, "TIPC_ADDR_NAME", TIPC_ADDR_NAME); + PyModule_AddIntConstant(m, "TIPC_ADDR_ID", TIPC_ADDR_ID); + + PyModule_AddIntConstant(m, "TIPC_ZONE_SCOPE", TIPC_ZONE_SCOPE); + PyModule_AddIntConstant(m, "TIPC_CLUSTER_SCOPE", TIPC_CLUSTER_SCOPE); + PyModule_AddIntConstant(m, "TIPC_NODE_SCOPE", TIPC_NODE_SCOPE); + + /* for setsockopt() */ + PyModule_AddIntConstant(m, "SOL_TIPC", SOL_TIPC); + PyModule_AddIntConstant(m, "TIPC_IMPORTANCE", TIPC_IMPORTANCE); + PyModule_AddIntConstant(m, "TIPC_SRC_DROPPABLE", TIPC_SRC_DROPPABLE); + PyModule_AddIntConstant(m, "TIPC_DEST_DROPPABLE", + TIPC_DEST_DROPPABLE); + PyModule_AddIntConstant(m, "TIPC_CONN_TIMEOUT", TIPC_CONN_TIMEOUT); + + PyModule_AddIntConstant(m, "TIPC_LOW_IMPORTANCE", + TIPC_LOW_IMPORTANCE); + PyModule_AddIntConstant(m, "TIPC_MEDIUM_IMPORTANCE", + TIPC_MEDIUM_IMPORTANCE); + PyModule_AddIntConstant(m, "TIPC_HIGH_IMPORTANCE", + TIPC_HIGH_IMPORTANCE); + PyModule_AddIntConstant(m, "TIPC_CRITICAL_IMPORTANCE", + TIPC_CRITICAL_IMPORTANCE); + + /* for subscriptions */ + PyModule_AddIntConstant(m, "TIPC_SUB_PORTS", TIPC_SUB_PORTS); + PyModule_AddIntConstant(m, "TIPC_SUB_SERVICE", TIPC_SUB_SERVICE); + PyModule_AddIntConstant(m, "TIPC_SUB_CANCEL", TIPC_SUB_CANCEL); + PyModule_AddIntConstant(m, "TIPC_WAIT_FOREVER", TIPC_WAIT_FOREVER); + PyModule_AddIntConstant(m, "TIPC_PUBLISHED", TIPC_PUBLISHED); + PyModule_AddIntConstant(m, "TIPC_WITHDRAWN", TIPC_WITHDRAWN); + PyModule_AddIntConstant(m, "TIPC_SUBSCR_TIMEOUT", TIPC_SUBSCR_TIMEOUT); + PyModule_AddIntConstant(m, "TIPC_CFG_SRV", TIPC_CFG_SRV); + PyModule_AddIntConstant(m, "TIPC_TOP_SRV", TIPC_TOP_SRV); +#endif + /* Socket types */ PyModule_AddIntConstant(m, "SOCK_STREAM", SOCK_STREAM); PyModule_AddIntConstant(m, "SOCK_DGRAM", SOCK_DGRAM); Modified: python/branches/py3k/Modules/socketmodule.h ============================================================================== --- python/branches/py3k/Modules/socketmodule.h (original) +++ python/branches/py3k/Modules/socketmodule.h Mon Jan 7 18:19:16 2008 @@ -61,6 +61,10 @@ # include #endif +#ifdef HAVE_LINUX_TIPC_H +# include +#endif + #ifndef Py__SOCKET_H #define Py__SOCKET_H #ifdef __cplusplus Modified: python/branches/py3k/Python/future.c ============================================================================== --- python/branches/py3k/Python/future.c (original) +++ python/branches/py3k/Python/future.c Mon Jan 7 18:19:16 2008 @@ -65,7 +65,7 @@ /* A subsequent pass will detect future imports that don't appear at the beginning of the file. There's one case, - however, that is easier to handl here: A series of imports + however, that is easier to handle here: A series of imports joined by semi-colons, where the first import is a future statement but some subsequent import has the future form but is preceded by a regular import. Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Mon Jan 7 18:19:16 2008 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 59558 . +# From configure.in Revision: 59625 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.0. # @@ -5390,6 +5390,7 @@ + for ac_header in asm/types.h conio.h curses.h direct.h dlfcn.h errno.h \ fcntl.h grp.h \ io.h langinfo.h libintl.h ncurses.h poll.h process.h pthread.h \ @@ -5401,7 +5402,7 @@ sys/time.h \ sys/times.h sys/types.h sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \ -bluetooth/bluetooth.h +bluetooth/bluetooth.h linux/tipc.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Mon Jan 7 18:19:16 2008 @@ -1082,7 +1082,7 @@ sys/time.h \ sys/times.h sys/types.h sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \ -bluetooth/bluetooth.h) +bluetooth/bluetooth.h linux/tipc.h) AC_HEADER_DIRENT AC_HEADER_MAJOR Modified: python/branches/py3k/pyconfig.h.in ============================================================================== --- python/branches/py3k/pyconfig.h.in (original) +++ python/branches/py3k/pyconfig.h.in Mon Jan 7 18:19:16 2008 @@ -351,6 +351,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_NETLINK_H +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_TIPC_H + /* Define this if you have the type long double. */ #undef HAVE_LONG_DOUBLE @@ -1046,4 +1049,3 @@ #endif /*Py_PYCONFIG_H*/ - From lists at cheimes.de Mon Jan 7 18:22:59 2008 From: lists at cheimes.de (Christian Heimes) Date: Mon, 07 Jan 2008 18:22:59 +0100 Subject: [Python-3000-checkins] r59826 - in python/branches/py3k: Doc/library/collections.rst Doc/library/getopt.rst Doc/library/imp.rst Doc/library/logging.rst Doc/library/socket.rst Doc/library/stdtypes.rst Doc/tutorial/controlflow.rst Doc/tutorial/introduction.rst Lib/abc.py Lib/collections.py Lib/test/test_abc.py Lib/test/test_socket.py Misc/NEWS Misc/developers.txt Modules/socketmodule.c Modules/socketmodule.h Python/future.c configure configure.in pyconfig.h.in In-Reply-To: <20080107171917.88B801E4002@bag.python.org> References: <20080107171917.88B801E4002@bag.python.org> Message-ID: <47825FF3.7030504@cheimes.de> christian.heimes wrote: > Author: christian.heimes > Date: Mon Jan 7 18:19:16 2008 > New Revision: 59826 > > Modified: > python/branches/py3k/ (props changed) > python/branches/py3k/Doc/library/collections.rst > python/branches/py3k/Doc/library/getopt.rst > python/branches/py3k/Doc/library/imp.rst > python/branches/py3k/Doc/library/logging.rst > python/branches/py3k/Doc/library/socket.rst > python/branches/py3k/Doc/library/stdtypes.rst > python/branches/py3k/Doc/tutorial/controlflow.rst > python/branches/py3k/Doc/tutorial/introduction.rst > python/branches/py3k/Lib/abc.py > python/branches/py3k/Lib/collections.py > python/branches/py3k/Lib/test/test_abc.py > python/branches/py3k/Lib/test/test_socket.py > python/branches/py3k/Misc/NEWS > python/branches/py3k/Misc/developers.txt > python/branches/py3k/Modules/socketmodule.c > python/branches/py3k/Modules/socketmodule.h > python/branches/py3k/Python/future.c > python/branches/py3k/configure > python/branches/py3k/configure.in > python/branches/py3k/pyconfig.h.in > Log: > Copied doc for reload() from trunk's function.rst to imp.rst Make that a merge from the trunk, too Merged revisions 59784-59821 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: svnmerge-commit-message.txt Url: http://mail.python.org/pipermail/python-3000-checkins/attachments/20080107/ca617593/attachment.txt From python-3000-checkins at python.org Mon Jan 7 18:32:13 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Mon, 7 Jan 2008 18:32:13 +0100 (CET) Subject: [Python-3000-checkins] r59828 - python/branches/py3k/Doc/tutorial/introduction.rst Message-ID: <20080107173213.725641E4002@bag.python.org> Author: georg.brandl Date: Mon Jan 7 18:32:13 2008 New Revision: 59828 Modified: python/branches/py3k/Doc/tutorial/introduction.rst Log: Fix merge glitch. Modified: python/branches/py3k/Doc/tutorial/introduction.rst ============================================================================== --- python/branches/py3k/Doc/tutorial/introduction.rst (original) +++ python/branches/py3k/Doc/tutorial/introduction.rst Mon Jan 7 18:32:13 2008 @@ -548,8 +548,8 @@ ... # the sum of two elements defines the next ... a, b = 0, 1 >>> while b < 10: - ... print b - ... a, b = b, a+b + ... print(b) + ... a, b = b, a+b ... 1 1 From python-3000-checkins at python.org Mon Jan 7 19:10:25 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Mon, 7 Jan 2008 19:10:25 +0100 (CET) Subject: [Python-3000-checkins] r59829 - in python/branches/py3k: Doc/library/codecs.rst Makefile.pre.in Misc/NEWS PC/os2emx/pyconfig.h PC/os2vacpp/pyconfig.h Parser/parsetok.c configure configure.in pyconfig.h.in Message-ID: <20080107181025.8A4891E4018@bag.python.org> Author: georg.brandl Date: Mon Jan 7 19:10:24 2008 New Revision: 59829 Modified: python/branches/py3k/Doc/library/codecs.rst python/branches/py3k/Makefile.pre.in python/branches/py3k/Misc/NEWS python/branches/py3k/PC/os2emx/pyconfig.h python/branches/py3k/PC/os2vacpp/pyconfig.h python/branches/py3k/Parser/parsetok.c python/branches/py3k/configure python/branches/py3k/configure.in python/branches/py3k/pyconfig.h.in Log: Remove traces of Py_USING_UNICODE and Unicode-specific conditionals in configure. Rename --enable-unicode to --with-wide-unicode; the default is still not wide. Modified: python/branches/py3k/Doc/library/codecs.rst ============================================================================== --- python/branches/py3k/Doc/library/codecs.rst (original) +++ python/branches/py3k/Doc/library/codecs.rst Mon Jan 7 19:10:24 2008 @@ -751,7 +751,7 @@ Unicode strings are stored internally as sequences of codepoints (to be precise as :ctype:`Py_UNICODE` arrays). Depending on the way Python is compiled (either -via :option:`--enable-unicode=ucs2` or :option:`--enable-unicode=ucs4`, with the +via :option:`--without-wide-unicode` or :option:`--with-wide-unicode`, with the former being the default) :ctype:`Py_UNICODE` is either a 16-bit or 32-bit data type. Once a Unicode object is used outside of CPU and memory, CPU endianness and how these arrays are stored as bytes become an issue. Transforming a Modified: python/branches/py3k/Makefile.pre.in ============================================================================== --- python/branches/py3k/Makefile.pre.in (original) +++ python/branches/py3k/Makefile.pre.in Mon Jan 7 19:10:24 2008 @@ -171,7 +171,6 @@ MACHDEP_OBJS= @MACHDEP_OBJS@ LIBOBJDIR= Python/ LIBOBJS= @LIBOBJS@ -UNICODE_OBJS= @UNICODE_OBJS@ PYTHON= python$(EXE) BUILDPYTHON= python$(BUILDEXE) @@ -320,8 +319,9 @@ Objects/structseq.o \ Objects/tupleobject.o \ Objects/typeobject.o \ - Objects/weakrefobject.o \ - $(UNICODE_OBJS) + Objects/unicodeobject.o \ + Objects/unicodectype.o \ + Objects/weakrefobject.o ########################################################################## Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Jan 7 19:10:24 2008 @@ -7,7 +7,7 @@ What's New in Python 3.0a3? =========================== -*Release data: XX-XXX-2008* +*Release date: XX-XXX-2008* Core and Builtins ----------------- @@ -46,6 +46,7 @@ - Issue #1762972: Readded the reload() function as imp.reload() + Library ------- @@ -56,6 +57,13 @@ - Issue #1578: Problems in win_getpass. +Build +----- + +- Renamed --enable-unicode configure flag to --with-wide-unicode, since + Unicode strings can't be disabled anymore. + + C API ----- @@ -143,12 +151,12 @@ - Removed all types from the 'types' module that are easily accessable through builtins. + What's New in Python 3.0a1? ========================== *Release date: 31-Aug-2007* - Core and Builtins ----------------- Modified: python/branches/py3k/PC/os2emx/pyconfig.h ============================================================================== --- python/branches/py3k/PC/os2emx/pyconfig.h (original) +++ python/branches/py3k/PC/os2emx/pyconfig.h Mon Jan 7 19:10:24 2008 @@ -58,7 +58,6 @@ #define WITH_DOC_STRINGS 1 /* Unicode related */ -#define Py_USING_UNICODE 1 #define PY_UNICODE_TYPE wchar_t #define Py_UNICODE_SIZE SIZEOF_SHORT Modified: python/branches/py3k/PC/os2vacpp/pyconfig.h ============================================================================== --- python/branches/py3k/PC/os2vacpp/pyconfig.h (original) +++ python/branches/py3k/PC/os2vacpp/pyconfig.h Mon Jan 7 19:10:24 2008 @@ -80,7 +80,6 @@ /* #define SIZEOF_LONG_LONG 8 */ /* Count of Bytes in a (long long) */ /* unicode definines */ -#define Py_USING_UNICODE #define PY_UNICODE_TYPE wchar_t #define Py_UNICODE_SIZE SIZEOF_SHORT Modified: python/branches/py3k/Parser/parsetok.c ============================================================================== --- python/branches/py3k/Parser/parsetok.c (original) +++ python/branches/py3k/Parser/parsetok.c Mon Jan 7 19:10:24 2008 @@ -218,10 +218,7 @@ assert(tok->cur - tok->buf < INT_MAX); err_ret->offset = (int)(tok->cur - tok->buf); len = tok->inp - tok->buf; -#ifdef Py_USING_UNICODE text = PyTokenizer_RestoreEncoding(tok, len, &err_ret->offset); - -#endif if (text == NULL) { text = (char *) PyObject_MALLOC(len + 1); if (text != NULL) { Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Mon Jan 7 19:10:24 2008 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 59625 . +# From configure.in Revision: 59826 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.0. # @@ -728,7 +728,6 @@ HAVE_GETHOSTBYNAME LIBM LIBC -UNICODE_OBJS THREADHEADERS SRCDIRS LTLIBOBJS' @@ -1321,8 +1320,6 @@ --enable-toolbox-glue disable/enable MacOSX glue code for extensions --enable-ipv6 Enable ipv6 (with ipv4) support --disable-ipv6 Disable ipv6 support - --enable-unicode[=ucs[24]] - Enable Unicode strings (default is yes) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -1349,6 +1346,7 @@ --with-fpectl enable SIGFPE catching --with-libm=STRING math library --with-libc=STRING C library + --with-wide-unicode Use 4-byte Unicode characters (default is 2 bytes) Some influential environment variables: CC C compiler command @@ -21481,95 +21479,76 @@ echo "${ECHO_T}$ac_cv_wchar_t_signed" >&6; } fi -{ echo "$as_me:$LINENO: checking what type to use for unicode" >&5 -echo $ECHO_N "checking what type to use for unicode... $ECHO_C" >&6; } -# Check whether --enable-unicode was given. -if test "${enable_unicode+set}" = set; then - enableval=$enable_unicode; -else - enable_unicode=yes +{ echo "$as_me:$LINENO: checking what type to use for str" >&5 +echo $ECHO_N "checking what type to use for str... $ECHO_C" >&6; } + +# Check whether --with-wide-unicode was given. +if test "${with_wide_unicode+set}" = set; then + withval=$with_wide_unicode; +if test "$withval" != no +then unicode_size="4" +else unicode_size="2" fi +else + +case "$have_ucs4_tcl" in + yes) unicode_size="4" ;; + *) unicode_size="2" ;; +esac -if test $enable_unicode = yes -then - # Without any arguments, Py_UNICODE defaults to two-byte mode - case "$have_ucs4_tcl" in - yes) enable_unicode="ucs4" - ;; - *) enable_unicode="ucs2" - ;; - esac fi -case "$enable_unicode" in -ucs2) unicode_size="2" - cat >>confdefs.h <<\_ACEOF -#define Py_UNICODE_SIZE 2 -_ACEOF - ;; -ucs4) unicode_size="4" - cat >>confdefs.h <<\_ACEOF +case "$unicode_size" in + 4) cat >>confdefs.h <<\_ACEOF #define Py_UNICODE_SIZE 4 _ACEOF - - ;; + ;; + *) cat >>confdefs.h <<\_ACEOF +#define Py_UNICODE_SIZE 2 +_ACEOF + ;; esac - -if test "$enable_unicode" = "no" -then - UNICODE_OBJS="" - { echo "$as_me:$LINENO: result: not used" >&5 -echo "${ECHO_T}not used" >&6; } -else - UNICODE_OBJS="Objects/unicodeobject.o Objects/unicodectype.o" - -cat >>confdefs.h <<\_ACEOF -#define Py_USING_UNICODE 1 -_ACEOF - - - # wchar_t is only usable if it maps to an unsigned type - if test "$unicode_size" = "$ac_cv_sizeof_wchar_t" \ +# wchar_t is only usable if it maps to an unsigned type +if test "$unicode_size" = "$ac_cv_sizeof_wchar_t" \ -a "$ac_cv_wchar_t_signed" = "no" - then - PY_UNICODE_TYPE="wchar_t" +then + PY_UNICODE_TYPE="wchar_t" cat >>confdefs.h <<\_ACEOF #define HAVE_USABLE_WCHAR_T 1 _ACEOF - cat >>confdefs.h <<\_ACEOF + cat >>confdefs.h <<\_ACEOF #define PY_UNICODE_TYPE wchar_t _ACEOF - elif test "$ac_cv_sizeof_short" = "$unicode_size" - then - PY_UNICODE_TYPE="unsigned short" - cat >>confdefs.h <<\_ACEOF +elif test "$ac_cv_sizeof_short" = "$unicode_size" +then + PY_UNICODE_TYPE="unsigned short" + cat >>confdefs.h <<\_ACEOF #define PY_UNICODE_TYPE unsigned short _ACEOF - elif test "$ac_cv_sizeof_long" = "$unicode_size" - then - PY_UNICODE_TYPE="unsigned long" - cat >>confdefs.h <<\_ACEOF +elif test "$ac_cv_sizeof_long" = "$unicode_size" +then + PY_UNICODE_TYPE="unsigned long" + cat >>confdefs.h <<\_ACEOF #define PY_UNICODE_TYPE unsigned long _ACEOF - else - PY_UNICODE_TYPE="no type found" - fi - { echo "$as_me:$LINENO: result: $PY_UNICODE_TYPE" >&5 -echo "${ECHO_T}$PY_UNICODE_TYPE" >&6; } +else + PY_UNICODE_TYPE="no type found" fi +{ echo "$as_me:$LINENO: result: $PY_UNICODE_TYPE" >&5 +echo "${ECHO_T}$PY_UNICODE_TYPE" >&6; } # check for endianness { echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 @@ -24432,13 +24411,12 @@ HAVE_GETHOSTBYNAME!$HAVE_GETHOSTBYNAME$ac_delim LIBM!$LIBM$ac_delim LIBC!$LIBC$ac_delim -UNICODE_OBJS!$UNICODE_OBJS$ac_delim THREADHEADERS!$THREADHEADERS$ac_delim SRCDIRS!$SRCDIRS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 19; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 18; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Mon Jan 7 19:10:24 2008 @@ -3003,72 +3003,55 @@ ac_cv_wchar_t_signed=yes)]) AC_MSG_RESULT($ac_cv_wchar_t_signed) fi - -AC_MSG_CHECKING(what type to use for unicode) -dnl quadrigraphs "@<:@" and "@:>@" produce "[" and "]" in the output -AC_ARG_ENABLE(unicode, - AC_HELP_STRING(--enable-unicode@<:@=ucs@<:@24@:>@@:>@, Enable Unicode strings (default is yes)), - [], - [enable_unicode=yes]) - -if test $enable_unicode = yes -then - # Without any arguments, Py_UNICODE defaults to two-byte mode - case "$have_ucs4_tcl" in - yes) enable_unicode="ucs4" - ;; - *) enable_unicode="ucs2" - ;; - esac + +AC_MSG_CHECKING(what type to use for str) +AC_ARG_WITH(wide-unicode, + AC_HELP_STRING(--with-wide-unicode, Use 4-byte Unicode characters (default is 2 bytes)), +[ +if test "$withval" != no +then unicode_size="4" +else unicode_size="2" fi +], +[ +case "$have_ucs4_tcl" in + yes) unicode_size="4" ;; + *) unicode_size="2" ;; +esac +]) AH_TEMPLATE(Py_UNICODE_SIZE, [Define as the size of the unicode type.]) -case "$enable_unicode" in -ucs2) unicode_size="2" - AC_DEFINE(Py_UNICODE_SIZE,2) - ;; -ucs4) unicode_size="4" - AC_DEFINE(Py_UNICODE_SIZE,4) - ;; +case "$unicode_size" in + 4) AC_DEFINE(Py_UNICODE_SIZE, 4) ;; + *) AC_DEFINE(Py_UNICODE_SIZE, 2) ;; esac AH_TEMPLATE(PY_UNICODE_TYPE, [Define as the integral type used for Unicode representation.]) -AC_SUBST(UNICODE_OBJS) -if test "$enable_unicode" = "no" +# wchar_t is only usable if it maps to an unsigned type +if test "$unicode_size" = "$ac_cv_sizeof_wchar_t" \ + -a "$ac_cv_wchar_t_signed" = "no" +then + PY_UNICODE_TYPE="wchar_t" + AC_DEFINE(HAVE_USABLE_WCHAR_T, 1, + [Define if you have a useable wchar_t type defined in wchar.h; useable + means wchar_t must be an unsigned type with at least 16 bits. (see + Include/unicodeobject.h).]) + AC_DEFINE(PY_UNICODE_TYPE,wchar_t) +elif test "$ac_cv_sizeof_short" = "$unicode_size" +then + PY_UNICODE_TYPE="unsigned short" + AC_DEFINE(PY_UNICODE_TYPE,unsigned short) +elif test "$ac_cv_sizeof_long" = "$unicode_size" then - UNICODE_OBJS="" - AC_MSG_RESULT(not used) + PY_UNICODE_TYPE="unsigned long" + AC_DEFINE(PY_UNICODE_TYPE,unsigned long) else - UNICODE_OBJS="Objects/unicodeobject.o Objects/unicodectype.o" - AC_DEFINE(Py_USING_UNICODE, 1, - [Define if you want to have a Unicode type.]) - - # wchar_t is only usable if it maps to an unsigned type - if test "$unicode_size" = "$ac_cv_sizeof_wchar_t" \ - -a "$ac_cv_wchar_t_signed" = "no" - then - PY_UNICODE_TYPE="wchar_t" - AC_DEFINE(HAVE_USABLE_WCHAR_T, 1, - [Define if you have a useable wchar_t type defined in wchar.h; useable - means wchar_t must be an unsigned type with at least 16 bits. (see - Include/unicodeobject.h).]) - AC_DEFINE(PY_UNICODE_TYPE,wchar_t) - elif test "$ac_cv_sizeof_short" = "$unicode_size" - then - PY_UNICODE_TYPE="unsigned short" - AC_DEFINE(PY_UNICODE_TYPE,unsigned short) - elif test "$ac_cv_sizeof_long" = "$unicode_size" - then - PY_UNICODE_TYPE="unsigned long" - AC_DEFINE(PY_UNICODE_TYPE,unsigned long) - else - PY_UNICODE_TYPE="no type found" - fi - AC_MSG_RESULT($PY_UNICODE_TYPE) + PY_UNICODE_TYPE="no type found" fi +AC_MSG_RESULT($PY_UNICODE_TYPE) # check for endianness AC_C_BIGENDIAN Modified: python/branches/py3k/pyconfig.h.in ============================================================================== --- python/branches/py3k/pyconfig.h.in (original) +++ python/branches/py3k/pyconfig.h.in Mon Jan 7 19:10:24 2008 @@ -821,9 +821,6 @@ /* Define as the size of the unicode type. */ #undef Py_UNICODE_SIZE -/* Define if you want to have a Unicode type. */ -#undef Py_USING_UNICODE - /* Define as the return type of signal handlers (`int' or `void'). */ #undef RETSIGTYPE From python-3000-checkins at python.org Mon Jan 7 19:30:48 2008 From: python-3000-checkins at python.org (alexandre.vassalotti) Date: Mon, 7 Jan 2008 19:30:48 +0100 (CET) Subject: [Python-3000-checkins] r59832 - in python/branches/py3k/Lib: io.py test/test_io.py Message-ID: <20080107183048.EB3571E401E@bag.python.org> Author: alexandre.vassalotti Date: Mon Jan 7 19:30:48 2008 New Revision: 59832 Modified: python/branches/py3k/Lib/io.py python/branches/py3k/Lib/test/test_io.py Log: Fix issue1753: TextIOWrapper.write writes utf BOM for every string. Patch by Erick Tryzelaar, with slight modifications by me. Modified: python/branches/py3k/Lib/io.py ============================================================================== --- python/branches/py3k/Lib/io.py (original) +++ python/branches/py3k/Lib/io.py Mon Jan 7 19:30:48 2008 @@ -1182,6 +1182,7 @@ self._readnl = newline self._writetranslate = newline != '' self._writenl = newline or os.linesep + self._encoder = None self._decoder = None self._pending = "" self._snapshot = None @@ -1240,8 +1241,9 @@ haslf = (self._writetranslate or self._line_buffering) and "\n" in s if haslf and self._writetranslate and self._writenl != "\n": s = s.replace("\n", self._writenl) + encoder = self._encoder or self._get_encoder() # XXX What if we were just reading? - b = s.encode(self._encoding, self._errors) + b = encoder.encode(s) self.buffer.write(b) if self._line_buffering and (haslf or "\r" in s): self.flush() @@ -1250,11 +1252,13 @@ self._decoder.reset() return length + def _get_encoder(self): + make_encoder = codecs.getincrementalencoder(self._encoding) + self._encoder = make_encoder(self._errors) + return self._encoder + def _get_decoder(self): make_decoder = codecs.getincrementaldecoder(self._encoding) - if make_decoder is None: - raise IOError("Can't find an incremental decoder for encoding %s" % - self._encoding) decoder = make_decoder(self._errors) if self._readuniversal: decoder = IncrementalNewlineDecoder(decoder, self._readtranslate) Modified: python/branches/py3k/Lib/test/test_io.py ============================================================================== --- python/branches/py3k/Lib/test/test_io.py (original) +++ python/branches/py3k/Lib/test/test_io.py Mon Jan 7 19:30:48 2008 @@ -765,6 +765,24 @@ f.readline() f.tell() + def testEncodedWrites(self): + data = "1234567890" + tests = ("utf-16", + "utf-16-le", + "utf-16-be", + "utf-32", + "utf-32-le", + "utf-32-be") + for encoding in tests: + buf = io.BytesIO() + f = io.TextIOWrapper(buf, encoding=encoding) + # Check if the BOM is written only once (see issue1753). + f.write(data) + f.write(data) + f.seek(0) + self.assertEquals(f.read(), data * 2) + self.assertEquals(buf.getvalue(), (data * 2).encode(encoding)) + def timingTest(self): timer = time.time enc = "utf8" From python-3000-checkins at python.org Mon Jan 7 21:12:45 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Mon, 7 Jan 2008 21:12:45 +0100 (CET) Subject: [Python-3000-checkins] r59841 - in python/branches/py3k: Lib/test/test_import.py Misc/NEWS Python/import.c Message-ID: <20080107201245.3E2EC1E4002@bag.python.org> Author: christian.heimes Date: Mon Jan 7 21:12:44 2008 New Revision: 59841 Modified: python/branches/py3k/Lib/test/test_import.py python/branches/py3k/Misc/NEWS python/branches/py3k/Python/import.c Log: Another patch for #1762972: __file__ points to the py file instead pyo/pyc file Modified: python/branches/py3k/Lib/test/test_import.py ============================================================================== --- python/branches/py3k/Lib/test/test_import.py (original) +++ python/branches/py3k/Lib/test/test_import.py Mon Jan 7 21:12:44 2008 @@ -1,4 +1,4 @@ -?from test.test_support import TESTFN, run_unittest, catch_warning +from test.test_support import TESTFN, run_unittest, catch_warning import unittest import os @@ -200,6 +200,27 @@ if TESTFN in sys.modules: del sys.modules[TESTFN] + def test_file_to_source(self): + # check if __file__ points to the source file where available + source = TESTFN + ".py" + with open(source, "w") as f: + f.write("test = None\n") + + sys.path.insert(0, os.curdir) + try: + mod = __import__(TESTFN) + self.failUnless(mod.__file__.endswith('.py')) + os.remove(source) + del sys.modules[TESTFN] + mod = __import__(TESTFN) + self.failUnless(mod.__file__.endswith('.pyc')) + finally: + sys.path.pop(0) + remove_files(TESTFN) + if TESTFN in sys.modules: + del sys.modules[TESTFN] + + class PathsTests(unittest.TestCase): SAMPLES = ('test', 'test\u00e4\u00f6\u00fc\u00df', 'test\u00e9\u00e8', 'test\u00b0\u00b3\u00b2') Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Jan 7 21:12:44 2008 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #1762972: __file__ points to the source file instead of the pyc/pyo + file if the py file exists. + - Issue #1393: object_richcompare() returns NotImplemented instead of False if the objects aren't equal, to give the other side a chance. Modified: python/branches/py3k/Python/import.c ============================================================================== --- python/branches/py3k/Python/import.c (original) +++ python/branches/py3k/Python/import.c Mon Jan 7 21:12:44 2008 @@ -78,9 +78,10 @@ 3080 (PEP 3137 make __file__ and __name__ unicode) 3090 (kill str8 interning) 3100 (merge from 2.6a0, see 62151) + 3102 (__file__ points to source file) . */ -#define MAGIC (3100 | ((long)'\r'<<16) | ((long)'\n'<<24)) +#define MAGIC (3102 | ((long)'\r'<<16) | ((long)'\n'<<24)) /* Magic word as global; note that _PyImport_Init() can change the value of this global to accommodate for alterations of how the @@ -624,6 +625,8 @@ "sys.modules failed"); } +static PyObject * get_sourcefile(const char *file); + /* Execute a code object in a module and return the module object * WITH INCREMENTED REFERENCE COUNT. If an error occurs, name is * removed from sys.modules, to avoid leaving damaged module objects @@ -657,7 +660,7 @@ /* Remember the filename as the __file__ attribute */ v = NULL; if (pathname != NULL) { - v = PyUnicode_DecodeFSDefault(pathname); + v = get_sourcefile(pathname); if (v == NULL) PyErr_Clear(); } @@ -960,12 +963,43 @@ return m; } +/* Get source file -> unicode or None + * Returns the path to the py file if available, else the given path + */ +static PyObject * +get_sourcefile(const char *file) +{ + char py[MAXPATHLEN + 1]; + Py_ssize_t len; + PyObject *u; + struct stat statbuf; + + if (!file || !*file) { + Py_RETURN_NONE; + } + + len = strlen(file); + if (len > MAXPATHLEN || PyOS_stricmp(&file[len-4], ".pyc") != 0) { + return PyUnicode_DecodeFSDefault(file); + } + + strncpy(py, file, len-1); + py[len] = '\0'; + if (stat(py, &statbuf) == 0 && + S_ISREG(statbuf.st_mode)) { + u = PyUnicode_DecodeFSDefault(py); + } + else { + u = PyUnicode_DecodeFSDefault(file); + } + return u; +} /* Forward */ static PyObject *load_module(char *, FILE *, char *, int, PyObject *); static struct filedescr *find_module(char *, char *, PyObject *, char *, size_t, FILE **, PyObject **); -static struct _frozen *find_frozen(char *name); +static struct _frozen * find_frozen(char *); /* Load a package and return its module object WITH INCREMENTED REFERENCE COUNT */ @@ -988,7 +1022,7 @@ PySys_WriteStderr("import %s # directory %s\n", name, pathname); d = PyModule_GetDict(m); - file = PyUnicode_DecodeFSDefault(pathname); + file = get_sourcefile(pathname); if (file == NULL) goto error; path = Py_BuildValue("[O]", file); From python-3000-checkins at python.org Mon Jan 7 22:04:22 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Mon, 7 Jan 2008 22:04:22 +0100 (CET) Subject: [Python-3000-checkins] r59845 - python/branches/py3k/Include/unicodeobject.h Message-ID: <20080107210422.16BF41E4015@bag.python.org> Author: christian.heimes Date: Mon Jan 7 22:04:21 2008 New Revision: 59845 Modified: python/branches/py3k/Include/unicodeobject.h Log: Always define Py_USING_UNICODE, 3rd party software may depend on it. A missing declaration can lead to strange bugs as I had to learn the hard way in the upcoming merge Modified: python/branches/py3k/Include/unicodeobject.h ============================================================================== --- python/branches/py3k/Include/unicodeobject.h (original) +++ python/branches/py3k/Include/unicodeobject.h Mon Jan 7 22:04:21 2008 @@ -58,6 +58,9 @@ /* --- Internal Unicode Format -------------------------------------------- */ +/* Python 3.x requires unicode */ +#define Py_USING_UNICODE + /* FIXME: MvL's new implementation assumes that Py_UNICODE_SIZE is properly set, but the default rules below doesn't set it. I'll sort this out some other day -- fredrik at pythonware.com */ From python-3000-checkins at python.org Mon Jan 7 22:14:24 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Mon, 7 Jan 2008 22:14:24 +0100 (CET) Subject: [Python-3000-checkins] r59846 - in python/branches/py3k: Doc/library/collections.rst Doc/library/logging.rst Doc/library/stdtypes.rst Doc/library/sys.rst Doc/library/urllib.rst Doc/library/zipfile.rst Doc/reference/datamodel.rst Doc/using/cmdline.rst Include/pydebug.h Lib/collections.py Lib/test/output/test_cProfile Lib/test/output/test_profile Lib/test/test_socket.py Lib/test/test_zipfile.py Lib/zipfile.py Misc/NEWS Modules/main.c Python/import.c Python/pythonrun.c Python/sysmodule.c Python/thread.c Message-ID: <20080107211424.556EA1E4015@bag.python.org> Author: christian.heimes Date: Mon Jan 7 22:14:23 2008 New Revision: 59846 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/collections.rst python/branches/py3k/Doc/library/logging.rst python/branches/py3k/Doc/library/stdtypes.rst python/branches/py3k/Doc/library/sys.rst python/branches/py3k/Doc/library/urllib.rst python/branches/py3k/Doc/library/zipfile.rst python/branches/py3k/Doc/reference/datamodel.rst python/branches/py3k/Doc/using/cmdline.rst python/branches/py3k/Include/pydebug.h python/branches/py3k/Lib/collections.py python/branches/py3k/Lib/test/output/test_cProfile python/branches/py3k/Lib/test/output/test_profile python/branches/py3k/Lib/test/test_socket.py python/branches/py3k/Lib/test/test_zipfile.py python/branches/py3k/Lib/zipfile.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/main.c python/branches/py3k/Python/import.c python/branches/py3k/Python/pythonrun.c python/branches/py3k/Python/sysmodule.c python/branches/py3k/Python/thread.c Log: Merged revisions 59822-59841 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r59822 | georg.brandl | 2008-01-07 17:43:47 +0100 (Mon, 07 Jan 2008) | 2 lines Restore "somenamedtuple" as the "class" for named tuple attrs. ........ r59824 | georg.brandl | 2008-01-07 18:09:35 +0100 (Mon, 07 Jan 2008) | 2 lines Patch #602345 by Neal Norwitz and me: add -B option and PYTHONDONTWRITEBYTECODE envvar to skip writing bytecode. ........ r59827 | georg.brandl | 2008-01-07 18:25:53 +0100 (Mon, 07 Jan 2008) | 2 lines patch #1668: clarify envvar docs; rename THREADDEBUG to PYTHONTHREADDEBUG. ........ r59830 | georg.brandl | 2008-01-07 19:16:36 +0100 (Mon, 07 Jan 2008) | 2 lines Make Python compile with --disable-unicode. ........ r59831 | georg.brandl | 2008-01-07 19:23:27 +0100 (Mon, 07 Jan 2008) | 2 lines Restructure urllib doc structure. ........ r59833 | georg.brandl | 2008-01-07 19:41:34 +0100 (Mon, 07 Jan 2008) | 2 lines Fix #define ordering. ........ r59834 | georg.brandl | 2008-01-07 19:47:44 +0100 (Mon, 07 Jan 2008) | 2 lines #467924, patch by Alan McIntyre: Add ZipFile.extract and ZipFile.extractall. ........ r59835 | raymond.hettinger | 2008-01-07 19:52:19 +0100 (Mon, 07 Jan 2008) | 1 line Fix inconsistent title levels -- it made the whole doc build crash horribly. ........ r59836 | georg.brandl | 2008-01-07 19:57:03 +0100 (Mon, 07 Jan 2008) | 2 lines Fix two further doc build warnings. ........ r59837 | georg.brandl | 2008-01-07 20:17:10 +0100 (Mon, 07 Jan 2008) | 2 lines Clarify metaclass docs and add example. ........ r59838 | vinay.sajip | 2008-01-07 20:40:10 +0100 (Mon, 07 Jan 2008) | 1 line Added section about adding contextual information to log output. ........ r59839 | christian.heimes | 2008-01-07 20:58:41 +0100 (Mon, 07 Jan 2008) | 1 line Fixed indention problem that caused the second TIPC test to run on systems without TIPC ........ r59840 | raymond.hettinger | 2008-01-07 21:07:38 +0100 (Mon, 07 Jan 2008) | 1 line Cleanup named tuple subclassing example. ........ Modified: python/branches/py3k/Doc/library/collections.rst ============================================================================== --- python/branches/py3k/Doc/library/collections.rst (original) +++ python/branches/py3k/Doc/library/collections.rst Mon Jan 7 22:14:23 2008 @@ -382,7 +382,7 @@ .. _named-tuple-factory: :func:`namedtuple` Factory Function for Tuples with Named Fields ------------------------------------------------------------------ +---------------------------------------------------------------- Named tuples assign meaning to each position in a tuple and allow for more readable, self-documenting code. They can be used wherever regular tuples are used, and @@ -398,7 +398,7 @@ The *fieldnames* are a single string with each fieldname separated by whitespace and/or commas (for example 'x y' or 'x, y'). Alternatively, the *fieldnames* - can be specified as a list of strings (such as ['x', 'y']). + can be specified with a sequence of strings (such as ['x', 'y']). Any valid Python identifier may be used for a fieldname except for names starting with an underscore. Valid identifiers consist of letters, digits, @@ -479,7 +479,7 @@ In addition to the methods inherited from tuples, named tuples support three additional methods and one attribute. -.. method:: namedtuple._make(iterable) +.. method:: somenamedtuple._make(iterable) Class method that makes a new instance from an existing sequence or iterable. @@ -489,7 +489,7 @@ >>> Point._make(t) Point(x=11, y=22) -.. method:: namedtuple._asdict() +.. method:: somenamedtuple._asdict() Return a new dict which maps field names to their corresponding values: @@ -498,7 +498,7 @@ >>> p._asdict() {'x': 11, 'y': 22} -.. method:: namedtuple._replace(kwargs) +.. method:: somenamedtuple._replace(kwargs) Return a new instance of the named tuple replacing specified fields with new values: @@ -509,9 +509,9 @@ Point(x=33, y=22) >>> for partnum, record in inventory.items(): - ... inventory[partnum] = record._replace(price=newprices[partnum], updated=time.now()) + inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now()) -.. attribute:: namedtuple._fields +.. attribute:: somenamedtuple._fields Tuple of strings listing the field names. This is useful for introspection and for creating new named tuple types from existing named tuples. @@ -527,9 +527,7 @@ Pixel(x=11, y=22, red=128, green=255, blue=0)' To retrieve a field whose name is stored in a string, use the :func:`getattr` -function: - -:: +function:: >>> getattr(p, 'x') 11 @@ -548,13 +546,15 @@ @property def hypot(self): return (self.x ** 2 + self.y ** 2) ** 0.5 - def __repr__(self): - return 'Point(x=%.3f, y=%.3f, hypot=%.3f)' % (self.x, self.y, self.hypot) + def __str__(self): + return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) + + >>> for p in Point(3,4), Point(14,5), Point(9./7,6): + print p - >>> print Point(3, 4),'\n', Point(2, 5), '\n', Point(9./7, 6) - Point(x=3.000, y=4.000, hypot=5.000) - Point(x=2.000, y=5.000, hypot=5.385) - Point(x=1.286, y=6.000, hypot=6.136) + Point: x= 3.000 y= 4.000 hypot= 5.000 + Point: x=14.000 y= 5.000 hypot=14.866 + Point: x= 1.286 y= 6.000 hypot= 6.136 Another use for subclassing is to replace performance critcal methods with faster versions that bypass error-checking and localize variable access:: @@ -564,10 +564,8 @@ def _replace(self, _map=map, **kwds): return self._make(_map(kwds.pop, ('x', 'y'), self)) -Default values can be implemented by starting with a prototype instance -and customizing it with :meth:`_replace`: - -:: +Default values can be implemented by using :meth:`_replace`:: to +customize a prototype instance:: >>> Account = namedtuple('Account', 'owner balance transaction_count') >>> model_account = Account('', 0.0, 0) Modified: python/branches/py3k/Doc/library/logging.rst ============================================================================== --- python/branches/py3k/Doc/library/logging.rst (original) +++ python/branches/py3k/Doc/library/logging.rst Mon Jan 7 22:14:23 2008 @@ -1118,6 +1118,52 @@ combination of handlers you choose. +.. _context-info: + +Adding contextual information to your logging output +---------------------------------------------------- + +Sometimes you want logging output to contain contextual information in +addition to the parameters passed to the logging call. For example, in a +networked application, it may be desirable to log client-specific information +in the log (e.g. remote client's username, or IP address). Although you could +use the *extra* parameter to achieve this, it's not always convenient to pass +the information in this way. While it might be tempting to create +:class:`Logger` instances on a per-connection basis, this is not a good idea +because these instances are not garbage collected. While this is not a problem +in practice, when the number of :class:`Logger` instances is dependent on the +level of granularity you want to use in logging an application, it could +be hard to manage if the number of :class:`Logger` instances becomes +effectively unbounded. + +There are a number of other ways you can pass contextual information to be +output along with logging event information. + +* Use an adapter class which has access to the contextual information and + which defines methods :meth:`debug`, :meth:`info` etc. with the same + signatures as used by :class:`Logger`. You instantiate the adapter with a + name, which will be used to create an underlying :class:`Logger` with that + name. In each adpater method, the passed-in message is modified to include + whatever contextual information you want. + +* Use something other than a string to pass the message. Although normally + the first argument to a logger method such as :meth:`debug`, :meth:`info` + etc. is usually a string, it can in fact be any object. This object is the + argument to a :func:`str()` call which is made, in + :meth:`LogRecord.getMessage`, to obtain the actual message string. You can + use this behavior to pass an instance which may be initialized with a + logging message, which redefines :meth:__str__ to return a modified version + of that message with the contextual information added. + +* Use a specialized :class:`Formatter` subclass to add additional information + to the formatted output. The subclass could, for instance, merge some thread + local contextual information (or contextual information obtained in some + other way) with the output generated by the base :class:`Formatter`. + +In each of these three approaches, thread locals can sometimes be a useful way +of passing contextual information without undue coupling between different +parts of your code. + .. _network-logging: Sending and receiving logging events across a network Modified: python/branches/py3k/Doc/library/stdtypes.rst ============================================================================== --- python/branches/py3k/Doc/library/stdtypes.rst (original) +++ python/branches/py3k/Doc/library/stdtypes.rst Mon Jan 7 22:14:23 2008 @@ -435,8 +435,9 @@ One method needs to be defined for container objects to provide iteration support: +.. XXX duplicated in reference/datamodel! -.. method:: object.__iter__() +.. method:: container.__iter__() Return an iterator object. The object is required to support the iterator protocol described below. If a container supports different types of Modified: python/branches/py3k/Doc/library/sys.rst ============================================================================== --- python/branches/py3k/Doc/library/sys.rst (original) +++ python/branches/py3k/Doc/library/sys.rst Mon Jan 7 22:14:23 2008 @@ -438,6 +438,17 @@ implement a dynamic prompt. +.. data:: dont_write_bytecode + + If this is true, Python won't try to write ``.pyc`` or ``.pyo`` files on the + import of source modules. This value is initially set to ``True`` or ``False`` + depending on the ``-B`` command line option and the ``PYTHONDONTWRITEBYTECODE`` + environment variable, but you can set it yourself to control bytecode file + generation. + + .. versionadded:: 2.6 + + .. function:: setcheckinterval(interval) Set the interpreter's "check interval". This integer value determines how often Modified: python/branches/py3k/Doc/library/urllib.rst ============================================================================== --- python/branches/py3k/Doc/library/urllib.rst (original) +++ python/branches/py3k/Doc/library/urllib.rst Mon Jan 7 22:14:23 2008 @@ -1,4 +1,3 @@ - :mod:`urllib` --- Open arbitrary resources by URL ================================================= @@ -17,8 +16,8 @@ instead of filenames. Some restrictions apply --- it can only open URLs for reading, and no seek operations are available. -It defines the following public functions: - +High-level interface +-------------------- .. function:: urlopen(url[, data[, proxies]]) @@ -174,6 +173,9 @@ :func:`urlretrieve`. +Utility functions +----------------- + .. function:: quote(string[, safe]) Replace special characters in *string* using the ``%xx`` escape. Letters, @@ -235,6 +237,9 @@ to decode *path*. +URL Opener objects +------------------ + .. class:: URLopener([proxies[, **x509]]) Base class for opening and reading URLs. Unless you need to support opening @@ -260,6 +265,48 @@ :class:`URLopener` objects will raise an :exc:`IOError` exception if the server returns an error code. + .. method:: open(fullurl[, data]) + + Open *fullurl* using the appropriate protocol. This method sets up cache and + proxy information, then calls the appropriate open method with its input + arguments. If the scheme is not recognized, :meth:`open_unknown` is called. + The *data* argument has the same meaning as the *data* argument of + :func:`urlopen`. + + + .. method:: open_unknown(fullurl[, data]) + + Overridable interface to open unknown URL types. + + + .. method:: retrieve(url[, filename[, reporthook[, data]]]) + + Retrieves the contents of *url* and places it in *filename*. The return value + is a tuple consisting of a local filename and either a + :class:`mimetools.Message` object containing the response headers (for remote + URLs) or ``None`` (for local URLs). The caller must then open and read the + contents of *filename*. If *filename* is not given and the URL refers to a + local file, the input filename is returned. If the URL is non-local and + *filename* is not given, the filename is the output of :func:`tempfile.mktemp` + with a suffix that matches the suffix of the last path component of the input + URL. If *reporthook* is given, it must be a function accepting three numeric + parameters. It will be called after each chunk of data is read from the + network. *reporthook* is ignored for local URLs. + + If the *url* uses the :file:`http:` scheme identifier, the optional *data* + argument may be given to specify a ``POST`` request (normally the request type + is ``GET``). The *data* argument must in standard + :mimetype:`application/x-www-form-urlencoded` format; see the :func:`urlencode` + function below. + + + .. attribute:: version + + Variable that specifies the user agent of the opener object. To get + :mod:`urllib` to tell servers that it is a particular user agent, set this in a + subclass as a class variable or in the constructor before calling the base + constructor. + .. class:: FancyURLopener(...) @@ -289,6 +336,18 @@ users for the required information on the controlling terminal. A subclass may override this method to support more appropriate behavior if needed. + The :class:`FancyURLopener` class offers one additional method that should be + overloaded to provide the appropriate behavior: + + .. method:: prompt_user_passwd(host, realm) + + Return information needed to authenticate the user at the given host in the + specified security realm. The return value should be a tuple, ``(user, + password)``, which can be used for basic authentication. + + The implementation prompts for this information on the terminal; an application + should override this method to use an appropriate interaction model in the local + environment. .. exception:: ContentTooShortError(msg[, content]) @@ -297,7 +356,9 @@ *Content-Length* header). The :attr:`content` attribute stores the downloaded (and supposedly truncated) data. -Restrictions: + +:mod:`urllib` Restrictions +-------------------------- .. index:: pair: HTTP; protocol @@ -358,75 +419,6 @@ module :mod:`urlparse`. -.. _urlopener-objs: - -URLopener Objects ------------------ - -.. sectionauthor:: Skip Montanaro - - -:class:`URLopener` and :class:`FancyURLopener` objects have the following -attributes. - - -.. method:: URLopener.open(fullurl[, data]) - - Open *fullurl* using the appropriate protocol. This method sets up cache and - proxy information, then calls the appropriate open method with its input - arguments. If the scheme is not recognized, :meth:`open_unknown` is called. - The *data* argument has the same meaning as the *data* argument of - :func:`urlopen`. - - -.. method:: URLopener.open_unknown(fullurl[, data]) - - Overridable interface to open unknown URL types. - - -.. method:: URLopener.retrieve(url[, filename[, reporthook[, data]]]) - - Retrieves the contents of *url* and places it in *filename*. The return value - is a tuple consisting of a local filename and either a - :class:`mimetools.Message` object containing the response headers (for remote - URLs) or ``None`` (for local URLs). The caller must then open and read the - contents of *filename*. If *filename* is not given and the URL refers to a - local file, the input filename is returned. If the URL is non-local and - *filename* is not given, the filename is the output of :func:`tempfile.mktemp` - with a suffix that matches the suffix of the last path component of the input - URL. If *reporthook* is given, it must be a function accepting three numeric - parameters. It will be called after each chunk of data is read from the - network. *reporthook* is ignored for local URLs. - - If the *url* uses the :file:`http:` scheme identifier, the optional *data* - argument may be given to specify a ``POST`` request (normally the request type - is ``GET``). The *data* argument must in standard - :mimetype:`application/x-www-form-urlencoded` format; see the :func:`urlencode` - function below. - - -.. attribute:: URLopener.version - - Variable that specifies the user agent of the opener object. To get - :mod:`urllib` to tell servers that it is a particular user agent, set this in a - subclass as a class variable or in the constructor before calling the base - constructor. - -The :class:`FancyURLopener` class offers one additional method that should be -overloaded to provide the appropriate behavior: - - -.. method:: FancyURLopener.prompt_user_passwd(host, realm) - - Return information needed to authenticate the user at the given host in the - specified security realm. The return value should be a tuple, ``(user, - password)``, which can be used for basic authentication. - - The implementation prompts for this information on the terminal; an application - should override this method to use an appropriate interaction model in the local - environment. - - .. _urllib-examples: Examples Modified: python/branches/py3k/Doc/library/zipfile.rst ============================================================================== --- python/branches/py3k/Doc/library/zipfile.rst (original) +++ python/branches/py3k/Doc/library/zipfile.rst Mon Jan 7 22:14:23 2008 @@ -173,6 +173,27 @@ operate independently of the ZipFile. +.. method:: ZipFile.extract(member[, path[, pwd]]) + + Extract a member from the archive to the current working directory, using its + full name. Its file information is extracted as accurately as possible. + *path* specifies a different directory to extract to. *member* can be a + filename or a :class:`ZipInfo` object. *pwd* is the password used for + encrypted files. + + .. versionadded:: 2.6 + + +.. method:: ZipFile.extractall([path[, members[, pwd]]]) + + Extract all members from the archive to the current working directory. *path* + specifies a different directory to extract to. *members* is optional and must + be a subset of the list returned by :meth:`namelist`. *pwd* is the password + used for encrypted files. + + .. versionadded:: 2.6 + + .. method:: ZipFile.printdir() Print a table of contents for the archive to ``sys.stdout``. @@ -237,6 +258,13 @@ created with mode ``'r'`` will raise a :exc:`RuntimeError`. Calling :meth:`writestr` on a closed ZipFile will raise a :exc:`RuntimeError`. + .. note:: + + When passing a :class:`ZipInfo` instance as the *zinfo_or_acrname* parameter, + the compression method used will be that specified in the *compress_type* + member of the given :class:`ZipInfo` instance. By default, the + :class:`ZipInfo` constructor sets this member to :const:`ZIP_STORED`. + The following data attribute is also available: Modified: python/branches/py3k/Doc/reference/datamodel.rst ============================================================================== --- python/branches/py3k/Doc/reference/datamodel.rst (original) +++ python/branches/py3k/Doc/reference/datamodel.rst Mon Jan 7 22:14:23 2008 @@ -1086,7 +1086,8 @@ :meth:`__init__` method will not be invoked. :meth:`__new__` is intended mainly to allow subclasses of immutable types (like - int, str, or tuple) to customize instance creation. + int, str, or tuple) to customize instance creation. It is also commonly + overridden in custom metaclasses in order to customize class creation. .. method:: object.__init__(self[, ...]) @@ -1527,7 +1528,7 @@ result of ``type(name, bases, dict)``. When the class definition is read, if *__metaclass__* is defined then the -callable assigned to it will be called instead of :func:`type`. The allows +callable assigned to it will be called instead of :func:`type`. This allows classes or functions to be written which monitor or alter the class creation process: @@ -1536,7 +1537,21 @@ * Returning an instance of another class -- essentially performing the role of a factory function. -.. XXX needs to be updated for the "new metaclasses" PEP +These steps will have to be performed in the metaclass's :meth:`__new__` method +-- :meth:`type.__new__` can then be called from this method to create a class +with different properties. This example adds a new element to the class +dictionary before creating the class:: + + class metacls(type): + def __new__(mcs, name, bases, dict): + dict['foo'] = 'metacls was here' + return type.__new__(mcs, name, bases, dict) + +You can of course also override other class methods (or add new methods); for +example defining a custom :meth:`__call__` method in the metaclass allows custom +behavior when the class is called, e.g. not always creating a new instance. + + .. data:: __metaclass__ This variable can be any callable accepting arguments for ``name``, ``bases``, Modified: python/branches/py3k/Doc/using/cmdline.rst ============================================================================== --- python/branches/py3k/Doc/using/cmdline.rst (original) +++ python/branches/py3k/Doc/using/cmdline.rst Mon Jan 7 22:14:23 2008 @@ -142,6 +142,14 @@ option is given twice (:option:`-bb`). +.. cmdoption:: -B + + If given, Python won't try to write ``.pyc`` or ``.pyo`` files on the + import of source modules. See also :envvar:`PYTHONDONTWRITEBYTECODE`. + + .. versionadded:: 2.6 + + .. cmdoption:: -d Turn on parser debugging output (for wizards only, depending on compilation @@ -284,6 +292,8 @@ Environment variables --------------------- +These environment variables influence Python's behavior. + .. envvar:: PYTHONHOME Change the location of the standard Python libraries. By default, the @@ -299,7 +309,7 @@ .. envvar:: PYTHONPATH - Augments the default search path for module files. The format is the same as + Augment the default search path for module files. The format is the same as the shell's :envvar:`PATH`: one or more directory pathnames separated by colons. Non-existent directories are silently ignored. @@ -349,6 +359,9 @@ If this is set to a non-empty string it is equivalent to specifying the :option:`-i` option. + This variable can also be modified by Python code using :data:`os.environ` + to force inspect mode on program termination. + .. envvar:: PYTHONUNBUFFERED @@ -368,3 +381,43 @@ If this is set, Python ignores case in :keyword:`import` statements. This only works on Windows. + +.. envvar:: PYTHONDONTWRITEBYTECODE + + If this is set, Python won't try to write ``.pyc`` or ``.pyo`` files on the + import of source modules. + + .. versionadded:: 2.6 + + +.. envvar:: PYTHONEXECUTABLE + + If this environment variable is set, ``sys.argv[0]`` will be set to its + value instead of the value got through the C runtime. Only works on + MacOS X. + + +Debug-mode variables +~~~~~~~~~~~~~~~~~~~~ + +Setting these variables only has an effect in a debug build of Python, that is, +if Python was configured with the :option:`--with-pydebug` build option. + +.. envvar:: PYTHONTHREADDEBUG + + If set, Python will print debug threading debug info. + + .. versionchanged:: 2.6 + Previously, this variable was called ``THREADDEBUG``. + +.. envvar:: PYTHONDUMPREFS + + If set, Python will dump objects and reference counts still alive after + shutting down the interpreter. + + +.. envvar:: PYTHONMALLOCSTATS + + If set, Python will print memory allocation statistics every time a new + object arena is created, and on shutdown. + Modified: python/branches/py3k/Include/pydebug.h ============================================================================== --- python/branches/py3k/Include/pydebug.h (original) +++ python/branches/py3k/Include/pydebug.h Mon Jan 7 22:14:23 2008 @@ -17,6 +17,7 @@ PyAPI_DATA(int) Py_TabcheckFlag; PyAPI_DATA(int) Py_IgnoreEnvironmentFlag; PyAPI_DATA(int) Py_DivisionWarningFlag; +PyAPI_DATA(int) Py_DontWriteBytecodeFlag; /* this is a wrapper around getenv() that pays attention to Py_IgnoreEnvironmentFlag. It should be used for getting variables like Modified: python/branches/py3k/Lib/collections.py ============================================================================== --- python/branches/py3k/Lib/collections.py (original) +++ python/branches/py3k/Lib/collections.py Mon Jan 7 22:14:23 2008 @@ -119,10 +119,11 @@ @property def hypot(self): return (self.x ** 2 + self.y ** 2) ** 0.5 - def __repr__(self): - return 'Point(x=%.3f, y=%.3f, hypot=%.3f)' % (self.x, self.y, self.hypot) + def __str__(self): + return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) - print(Point(3, 4),'\n', Point(2, 5), '\n', Point(9./7, 6)) + for p in Point(3,4), Point(14,5), Point(9./7,6): + print (p) class Point(namedtuple('Point', 'x y')): 'Point class with optimized _make() and _replace() without error-checking' Modified: python/branches/py3k/Lib/test/output/test_cProfile ============================================================================== --- python/branches/py3k/Lib/test/output/test_cProfile (original) +++ python/branches/py3k/Lib/test/output/test_cProfile Mon Jan 7 22:14:23 2008 @@ -5,7 +5,7 @@ ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 1.000 1.000 :1() - 2 0.000 0.000 0.000 0.000 io.py:1212(flush) + 2 0.000 0.000 0.000 0.000 io.py:1213(flush) 1 0.000 0.000 0.000 0.000 io.py:269(flush) 1 0.000 0.000 0.000 0.000 io.py:656(closed) 1 0.000 0.000 0.000 0.000 io.py:874(flush) @@ -30,7 +30,7 @@ Function called... ncalls tottime cumtime :1() -> 1 0.270 1.000 test_cProfile.py:30(testfunc) -io.py:1212(flush) -> 1 0.000 0.000 io.py:269(flush) +io.py:1213(flush) -> 1 0.000 0.000 io.py:269(flush) 1 0.000 0.000 io.py:874(flush) io.py:269(flush) -> io.py:656(closed) -> @@ -53,7 +53,7 @@ test_cProfile.py:93(helper2) -> 8 0.064 0.080 test_cProfile.py:103(subhelper) 8 0.000 0.008 {hasattr} {exec} -> 1 0.000 1.000 :1() - 2 0.000 0.000 io.py:1212(flush) + 2 0.000 0.000 io.py:1213(flush) {hasattr} -> 12 0.012 0.012 test_cProfile.py:115(__getattr__) {method 'append' of 'list' objects} -> {method 'disable' of '_lsprof.Profiler' objects} -> @@ -65,10 +65,10 @@ Function was called by... ncalls tottime cumtime :1() <- 1 0.000 1.000 {exec} -io.py:1212(flush) <- 2 0.000 0.000 {exec} -io.py:269(flush) <- 1 0.000 0.000 io.py:1212(flush) +io.py:1213(flush) <- 2 0.000 0.000 {exec} +io.py:269(flush) <- 1 0.000 0.000 io.py:1213(flush) io.py:656(closed) <- 1 0.000 0.000 io.py:874(flush) -io.py:874(flush) <- 1 0.000 0.000 io.py:1212(flush) +io.py:874(flush) <- 1 0.000 0.000 io.py:1213(flush) test_cProfile.py:103(subhelper) <- 8 0.064 0.080 test_cProfile.py:93(helper2) test_cProfile.py:115(__getattr__) <- 16 0.016 0.016 test_cProfile.py:103(subhelper) 12 0.012 0.012 {hasattr} Modified: python/branches/py3k/Lib/test/output/test_profile ============================================================================== --- python/branches/py3k/Lib/test/output/test_profile (original) +++ python/branches/py3k/Lib/test/output/test_profile Mon Jan 7 22:14:23 2008 @@ -10,7 +10,7 @@ 12 0.000 0.000 0.012 0.001 :0(hasattr) 1 0.000 0.000 0.000 0.000 :0(setprofile) 1 0.000 0.000 1.000 1.000 :1() - 2 0.000 0.000 0.000 0.000 io.py:1212(flush) + 2 0.000 0.000 0.000 0.000 io.py:1213(flush) 1 0.000 0.000 0.000 0.000 io.py:269(flush) 1 0.000 0.000 0.000 0.000 io.py:656(closed) 1 0.000 0.000 0.000 0.000 io.py:874(flush) @@ -33,11 +33,11 @@ :0(append) -> :0(exc_info) -> :0(exec) -> :1()(1) 1.000 - io.py:1212(flush)(2) 0.000 + io.py:1213(flush)(2) 0.000 :0(hasattr) -> test_profile.py:115(__getattr__)(12) 0.028 :0(setprofile) -> :1() -> test_profile.py:30(testfunc)(1) 1.000 -io.py:1212(flush) -> io.py:269(flush)(1) 0.000 +io.py:1213(flush) -> io.py:269(flush)(1) 0.000 io.py:874(flush)(1) 0.000 io.py:269(flush) -> io.py:656(closed) -> @@ -74,10 +74,10 @@ test_profile.py:93(helper2)(8) 0.400 :0(setprofile) <- profile:0(testfunc())(1) 1.000 :1() <- :0(exec)(1) 1.000 -io.py:1212(flush) <- :0(exec)(2) 1.000 -io.py:269(flush) <- io.py:1212(flush)(1) 0.000 +io.py:1213(flush) <- :0(exec)(2) 1.000 +io.py:269(flush) <- io.py:1213(flush)(1) 0.000 io.py:656(closed) <- io.py:874(flush)(1) 0.000 -io.py:874(flush) <- io.py:1212(flush)(1) 0.000 +io.py:874(flush) <- io.py:1213(flush)(1) 0.000 profile:0(profiler) <- profile:0(testfunc()) <- profile:0(profiler)(1) 0.000 test_profile.py:103(subhelper) <- test_profile.py:93(helper2)(8) 0.400 Modified: python/branches/py3k/Lib/test/test_socket.py ============================================================================== --- python/branches/py3k/Lib/test/test_socket.py (original) +++ python/branches/py3k/Lib/test/test_socket.py Mon Jan 7 22:14:23 2008 @@ -1215,7 +1215,7 @@ tests.append(TestLinuxAbstractNamespace) if isTipcAvailable(): tests.append(TIPCTest) - tests.append(TIPCThreadableTest) + tests.append(TIPCThreadableTest) thread_info = test_support.threading_setup() test_support.run_unittest(*tests) Modified: python/branches/py3k/Lib/test/test_zipfile.py ============================================================================== --- python/branches/py3k/Lib/test/test_zipfile.py (original) +++ python/branches/py3k/Lib/test/test_zipfile.py Mon Jan 7 22:14:23 2008 @@ -14,6 +14,11 @@ TESTFN2 = TESTFN + "2" FIXEDTEST_SIZE = 1000 +SMALL_TEST_DATA = [('_ziptest1', '1q2w3e4r5t'), + ('ziptest2dir/_ziptest2', 'qawsedrftg'), + ('/ziptest2dir/ziptest3dir/_ziptest3', 'azsxdcfvgb'), + ('ziptest2dir/ziptest3dir/ziptest4dir/_ziptest3', '6y7u8i9o0p')] + class TestsWithSourceFile(unittest.TestCase): def setUp(self): self.line_gen = (bytes("Zipfile test line %d. random float: %f" % @@ -289,6 +294,57 @@ self.assertRaises(RuntimeError, zipf.write, TESTFN) zipf.close() + def testExtract(self): + zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) + for fpath, fdata in SMALL_TEST_DATA: + zipfp.writestr(fpath, fdata) + zipfp.close() + + zipfp = zipfile.ZipFile(TESTFN2, "r") + for fpath, fdata in SMALL_TEST_DATA: + writtenfile = zipfp.extract(fpath) + + # make sure it was written to the right place + if os.path.isabs(fpath): + correctfile = os.path.join(os.getcwd(), fpath[1:]) + else: + correctfile = os.path.join(os.getcwd(), fpath) + + self.assertEqual(writtenfile, correctfile) + + # make sure correct data is in correct file + self.assertEqual(fdata.encode(), open(writtenfile, "rb").read()) + + os.remove(writtenfile) + + zipfp.close() + + # remove the test file subdirectories + shutil.rmtree(os.path.join(os.getcwd(), 'ziptest2dir')) + + def testExtractAll(self): + zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) + for fpath, fdata in SMALL_TEST_DATA: + zipfp.writestr(fpath, fdata) + zipfp.close() + + zipfp = zipfile.ZipFile(TESTFN2, "r") + zipfp.extractall() + for fpath, fdata in SMALL_TEST_DATA: + if os.path.isabs(fpath): + outfile = os.path.join(os.getcwd(), fpath[1:]) + else: + outfile = os.path.join(os.getcwd(), fpath) + + self.assertEqual(fdata.encode(), open(outfile, "rb").read()) + + os.remove(outfile) + + zipfp.close() + + # remove the test file subdirectories + shutil.rmtree(os.path.join(os.getcwd(), 'ziptest2dir')) + def tearDown(self): os.remove(TESTFN) os.remove(TESTFN2) Modified: python/branches/py3k/Lib/zipfile.py ============================================================================== --- python/branches/py3k/Lib/zipfile.py (original) +++ python/branches/py3k/Lib/zipfile.py Mon Jan 7 22:14:23 2008 @@ -3,7 +3,7 @@ XXX references to utf-8 need further investigation. """ -import struct, os, time, sys +import struct, os, time, sys, shutil import binascii, io try: @@ -817,6 +817,62 @@ zef.set_univ_newlines(True) return zef + def extract(self, member, path=None, pwd=None): + """Extract a member from the archive to the current working directory, + using its full name. Its file information is extracted as accurately + as possible. `member' may be a filename or a ZipInfo object. You can + specify a different directory using `path'. + """ + if not isinstance(member, ZipInfo): + member = self.getinfo(member) + + if path is None: + path = os.getcwd() + + return self._extract_member(member, path, pwd) + + def extractall(self, path=None, members=None, pwd=None): + """Extract all members from the archive to the current working + directory. `path' specifies a different directory to extract to. + `members' is optional and must be a subset of the list returned + by namelist(). + """ + if members is None: + members = self.namelist() + + for zipinfo in members: + self.extract(zipinfo, path, pwd) + + def _extract_member(self, member, targetpath, pwd): + """Extract the ZipInfo object 'member' to a physical + file on the path targetpath. + """ + # build the destination pathname, replacing + # forward slashes to platform specific separators. + if targetpath[-1:] == "/": + targetpath = targetpath[:-1] + + # don't include leading "/" from file name if present + if os.path.isabs(member.filename): + targetpath = os.path.join(targetpath, member.filename[1:]) + else: + targetpath = os.path.join(targetpath, member.filename) + + targetpath = os.path.normpath(targetpath) + + # Create all upper directories if necessary. + upperdirs = os.path.dirname(targetpath) + if upperdirs and not os.path.exists(upperdirs): + os.makedirs(upperdirs) + + source = self.open(member.filename, pwd=pwd) + target = open(targetpath, "wb") + shutil.copyfileobj(source, target) + source.close() + target.close() + + return targetpath + def _writecheck(self, zinfo): """Check for errors before writing a file to the archive.""" if zinfo.filename in self.NameToInfo: Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Jan 7 22:14:23 2008 @@ -12,8 +12,20 @@ Core and Builtins ----------------- +<<<<<<< .working - Issue #1762972: __file__ points to the source file instead of the pyc/pyo file if the py file exists. +======= +- Patch #1668: renamed THREADDEBUG envvar to PYTHONTHREADDEBUG. + +- Patch #602345: Add -B command line option, PYTHONDONTWRITEBYTECODE envvar + and sys.dont_write_bytecode attribute. All these can be set to forbid Python + to attempt to write compiled bytecode files. + +- Improve some exception messages when Windows fails to load an extension + module. Now we get for example '%1 is not a valid Win32 application' instead + of 'error code 193'. +>>>>>>> .merge-right.r59840 - Issue #1393: object_richcompare() returns NotImplemented instead of False if the objects aren't equal, to give the other side a chance. @@ -44,6 +56,890 @@ of PyString. +<<<<<<< .working +======= +- Issue #1534: Added ``PyFloat_GetMax()``, ``PyFloat_GetMin()`` and + ``PyFloat_GetInfo()`` to the float API. + +- Issue #1521: On 64bit platforms, using PyArgs_ParseTuple with the t# of w# + format code incorrectly truncated the length to an int, even when + PY_SSIZE_T_CLEAN is set. The str.decode method used to return incorrect + results with huge strings. + +- Issue #1402: Fix a crash on exit, when another thread is still running, and + if the deallocation of its frames somehow calls the PyGILState_Ensure() / + PyGILState_Release() functions. + +- Expose the Py_Py3kWarningFlag as sys.py3kwarning. + +- Issue #1445: Fix a SystemError when accessing the ``cell_contents`` + attribute of an empty cell object. + +- Issue #1460: The utf-7 incremental decoder did not accept truncated input. + It now correctly saves its state between chunks of data. + +- Patch #1739468: Directories and zipfiles containing a __main__.py file can + now be directly executed by passing their name to the interpreter. The + directory/zipfile is automatically inserted as the first entry in sys.path. + +- Issue #1265: Fix a problem with sys.settrace, if the tracing function uses a + generator expression when at the same time the executed code is closing a + paused generator. + +- sets and frozensets now have an isdisjoint() method. + +- optimize the performance of builtin.sum(). + +- Fix warnings found by the new version of the Coverity checker. + +- The enumerate() builtin function is no longer bounded to sequences smaller + than LONG_MAX. Formerly, it raised an OverflowError. Now, automatically + shifts from ints to longs. + +- Issue #1686386: Tuple's tp_repr did not take into account the possibility of + having a self-referential tuple, which is possible from C code. Nor did + object's tp_str consider that a type's tp_str could do something that could + lead to an inifinite recursion. Py_ReprEnter() and Py_EnterRecursiveCall(), + respectively, fixed the issues. + +- Issue #1164: It was possible to trigger deadlock when using the 'print' + statement to write to a file since the GIL was not released as needed. Now + PyObject_Print() does the right thing along with various tp_print + implementations of the built-in types and those in the collections module. + +- Issue #1147: Exceptions were directly allowing string exceptions in their + throw() method even though string exceptions no longer allowed. + +- Issue #1096: Prevent a segfault from getting the repr of a very deeply nested + list by using the recursion counter. + +- Issue #1202533: Fix infinite recursion calls triggered by calls to + PyObject_Call() never calling back out to Python code to trigger recursion + depth updates/checks. Required the creation of a static RuntimeError + instance in case normalizing an exception put the recursion check value past + its limit. Fixes crashers infinite_rec_(1|2|4|5).py. + +- Patch #1031213: Decode source line in SyntaxErrors back to its original source + encoding. + +- Py_ssize_t fields work in structmember when HAVE_LONG_LONG is not defined. + +- PEP 3123: Provide forward compatibility with Python 3.0, while keeping + backwards compatibility. Add Py_Refcnt, Py_Type, Py_Size, and + PyVarObject_HEAD_INIT. + +- Patch #1673759: add a missing overflow check when formatting floats + with %G. + +- Patch #1733960: Allow T_LONGLONG to accept ints. + +- T_PYSSIZET can now be used in PyMemberDef lists for Py_ssize_t members. + +- Prevent expandtabs() on string and unicode objects from causing a segfault + when a large width is passed on 32-bit platforms. + +- Bug #1733488: Fix compilation of bufferobject.c on AIX. + +- Bug #1722485: remove docstrings again when running with -OO. + +- Add new attribute names for function objects. All the func_* become + __*__ attributes. (Some already existed, e.g., __doc__ and __name__.) + +- Add -3 option to the interpreter to warn about features that are + deprecated and will be changed/removed in Python 3.0. + +- Patch #1686487: you can now pass any mapping after '**' in function + calls. + +- except clauses may now be spelled either "except E, target:" or + "except E as target:". This is to provide forwards compatibility with + Python 3.0. + +- Deprecate BaseException.message as per PEP 352. + +- Bug #1303614: don't expose object's __dict__ when the dict is + inherited from a builtin base. + +- When __slots__ are set to a unicode string, make it work the same as + setting a plain string, ie don't expand to single letter identifiers. + +- Request #1191699: Slices can now be pickled. + +- Request #1193128: str.translate() now allows a None argument for + translations that only remove characters without re-mapping the + remaining characters. + +- Patch #1682205: a TypeError while unpacking an iterable is no longer + masked by a generic one with the message "unpack non-sequence". + +- Remove unused file Python/fmod.c. + +- Bug #1683368: The object.__init__() and object.__new__() methods are + now stricter in rejecting excess arguments. The only time when + either allows excess arguments is when it is not overridden and the + other one is. For backwards compatibility, when both are + overridden, it is a deprecation warning (for now; maybe a Py3k + warning later). Also, type.__init__() insists on the same signature + as supported by type.__new__(). + +- Patch #1675423: PyComplex_AsCComplex() now tries to convert an object + to complex using its __complex__() method before falling back to the + __float__() method. Therefore, the functions in the cmath module now + can operate on objects that define a __complex__() method. + +- Patch #1623563: allow __class__ assignment for classes with __slots__. + The old and the new class are still required to have the same slot names. + +- Patch #1642547: Fix an error/crash when encountering syntax errors in + complex if statements. + +- Patch #1462488: Python no longer segfaults when ``object.__reduce_ex__()`` + is called with an object that is faking its type. + +- Patch #1680015: Don't modify __slots__ tuple if it contains an unicode + name. + +- Patch #1444529: the builtin compile() now accepts keyword arguments. + +- Bug #1678647: write a newline after printing an exception in any + case, even when converting the value to a string failed. + +- The dir() function has been extended to call the __dir__() method on + its argument, if it exists. If not, it will work like before. This allows + customizing the output of dir() in the presence of a __getattr__(). + +- Patch #922167: Python no longer segfaults when faced with infinitely + self-recursive reload() calls (as reported by bug #742342). + +- Patch #1675981: remove unreachable code from ``type.__new__()`` method. + +- Patch #1491866: change the complex() constructor to allow parthensized + forms. This means complex(repr(x)) now works instead of raising a + ValueError. + +- Patch #703779: unset __file__ in __main__ after running a file. This + makes the filenames the warning module prints much more sensible when + a PYTHONSTARTUP file is used. + +- Variant of patch #697613: don't exit the interpreter on a SystemExit + exception if the -i command line option or PYTHONINSPECT environment + variable is given, but break into the interactive interpreter just like + on other exceptions or normal program exit. + +- Patch #1638879: don't accept strings with embedded NUL bytes in long(). + +- Bug #1674503: close the file opened by execfile() in an error condition. + +- Patch #1674228: when assigning a slice (old-style), check for the + sq_ass_slice instead of the sq_slice slot. + +- When printing an unraisable error, don't print exceptions. before the name. + This duplicates the behavior whening normally printing exceptions. + +- Bug #1653736: Properly discard third argument to slot_nb_inplace_power. + +- PEP 352: Raising a string exception now triggers a TypeError. Attempting to + catch a string exception raises DeprecationWarning. + +- Bug #1377858: Fix the segfaulting of the interpreter when an object created + a weakref on itself during a __del__ call for new-style classes (classic + classes still have the bug). + +- Bug #1579370: Make PyTraceBack_Here use the current thread, not the + frame's thread state. + +- patch #1630975: Fix crash when replacing sys.stdout in sitecustomize.py + +- Bug #1637022: Prefix AST symbols with _Py_. + +- Prevent seg fault on shutdown which could occur if an object + raised a warning. + +- Bug #1566280: Explicitly invoke threading._shutdown from Py_Main, + to avoid relying on atexit. + +- Bug #1590891: random.randrange don't return correct value for big number + +- Patch #1586791: Better exception messages for some operations on strings, + tuples and lists. + +- Bug #1067760: Deprecate passing floats to file.seek. + +- Bug #1591996: Correctly forward exception in instance_contains(). + +- Bug #1588287: fix invalid assertion for `1,2` in debug builds. + +- Bug #1576657: when setting a KeyError for a tuple key, make sure that + the tuple isn't used as the "exception arguments tuple". + +- Bug #1565514, SystemError not raised on too many nested blocks. + +- Bug #1576174: WindowsError now displays the windows error code + again, no longer the posix error code. + +- Patch #1549049: Support long values in structmember, issue warnings + if the assigned value for structmember fields gets truncated. + +- Update the peephole optimizer to remove more dead code (jumps after returns) + and inline unconditional jumps to returns. + +- Bug #1545497: when given an explicit base, int() did ignore NULs + embedded in the string to convert. + +- Bug #1569998: break inside a try statement (outside a loop) is now + recognized and rejected. + +- list.pop(x) accepts any object x following the __index__ protocol. + +- Fix some leftovers from the conversion from int to Py_ssize_t + (relevant to strings and sequences of more than 2**31 items). + +- A number of places, including integer negation and absolute value, + were fixed to not rely on undefined behaviour of the C compiler + anymore. + +- Bug #1566800: make sure that EnvironmentError can be called with any + number of arguments, as was the case in Python 2.4. + +- Patch #1567691: super() and new.instancemethod() now don't accept + keyword arguments any more (previously they accepted them, but didn't + use them). + +- Fix a bug in the parser's future statement handling that led to "with" + not being recognized as a keyword after, e.g., this statement: + from __future__ import division, with_statement + +- Bug #1557232: fix seg fault with def f((((x)))) and def f(((x),)). + +- Fix %zd string formatting on Mac OS X so it prints negative numbers. + +- Allow exception instances to be directly sliced again. + +- Bug #1551432: Exceptions do not define an explicit __unicode__ method. This + allows calling unicode() on exceptions classes directly to succeed. + +- Make _PyGILState_NoteThreadState() static, it was not used anywhere + outside of pystate.c and should not be necessary. + +- Bug #1542051: Exceptions now correctly call PyObject_GC_UnTrack. + Also make sure that every exception class has __module__ set to + 'exceptions'. + +- Bug #1550983: emit better error messages for erroneous relative + imports (if not in package and if beyond toplevel package). + +- Overflow checking code in integer division ran afoul of new gcc + optimizations. Changed to be more standard-conforming. + +- Patch #1542451: disallow continue anywhere under a finally. + +- Patch #1546288: fix seg fault in dict_equal due to ref counting bug. + +- The return tuple from str.rpartition(sep) is (tail, sep, head) where + head is the original string if sep was not found. + +- Bug #1520864: unpacking singleton tuples in list comprehensions and + generator expressions (x for x, in ... ) works again. Fixing this problem + required changing the .pyc magic number. This means that .pyc files + generated before 2.5c2 will be regenerated. + +- with and as are now keywords. + +- Bug #1664966: Fix crash in exec if Unicode filename can't be decoded. + +- Issue #1537: Changed GeneratorExit's base class from Exception to BaseException. + +Library +------- + +- Patch #467924: add ZipFile.extract() and ZipFile.extractall() in the + zipfile module. + +- Issue #1646: Make socket support the TIPC protocol. + +- Bug #1742: return os.curdir from os.path.relpath() if both arguments are + equal instead of raising an exception. + +- Patch #1637: fix urlparse for URLs like 'http://x.com?arg=/foo'. + +- Patch #1698: allow '@' in username parsed by urlparse.py. + +- Issue #1735: TarFile.extractall() now correctly sets directory permissions + and times. + +- Bug #1713: posixpath.ismount() claims symlink to a mountpoint is a mountpoint. + +- Bug #1687: Fxed plistlib.py restricts to Python int when writing + +- Issue #1700: Regular expression inline flags incorrectly handle certain + unicode characters. + +- Issue #1689: PEP 3141, numeric abstract base classes. + +- Tk issue #1851526: Return results from Python callbacks to Tcl as + Tcl objects. + +- Issue #1642: Fix segfault in ctypes when trying to delete attributes. + +- Issue #1727780: Support loading pickles of random.Random objects created + on 32-bit systems on 64-bit systems, and vice versa. As a consequence + of the change, Random pickles created by Python 2.6 cannot be loaded + in Python 2.5. + +- Issue #1455: The distutils package now supports VS 2005 and VS 2008 for + both the msvccompiler and cygwincompiler. + +- Issue #1531: tarfile.py: Read fileobj from the current offset, do not + seek to the start. + +- Issue #1534: Added a dictionary sys.float_info with information about the + internal floating point type to the sys module. + +- Issue 1429818: patch for trace and doctest modules so they play nicely + together. + +- doctest made a bad assumption that a package's __loader__.get_data() + method used universal newlines. + +- Issue #1705170: contextlib.contextmanager was still swallowing + StopIteration in some cases. This should no longer happen. + +- Issue #1292: On alpha, arm, ppc, and s390 linux systems the + --with-system-ffi configure option defaults to "yes". + +- IN module for FreeBSD 8 is added and preexisting FreeBSD 6 and 7 + files are updated. + +- Issues #1181, #1287: unsetenv() is now called when the os.environ.pop() + and os.environ.clear() methods are used. + +- ctypes will now work correctly on 32-bit systems when Python is + configured with --with-system-ffi. + +- Patch #1203: ctypes now does work on OS X when Python is built with + --disable-toolbox-glue. + +- collections.deque() now supports a "maxlen" argument. + +- itertools.count() is no longer bounded to LONG_MAX. Formerly, it raised + an OverflowError. Now, automatically shifts from ints to longs. + +- Patch #1541463: optimize performance of cgi.FieldStorage operations. + +- Decimal is fully updated to the latest Decimal Specification (v1.66). + +- Bug #1153: repr.repr() now doesn't require set and dictionary items + to be orderable to properly represent them. + +- A 'c_longdouble' type was added to the ctypes module. + +- Bug #1709599: Run test_1565150 only if the file system is NTFS. + +- When encountering a password-protected robots.txt file the RobotFileParser + no longer prompts interactively for a username and password (bug 813986). + +- TarFile.__init__() no longer fails if no name argument is passed and + the fileobj argument has no usable name attribute (e.g. StringIO). + +- The functools module now provides 'reduce', for forward compatibility + with Python 3000. + +- Server-side SSL support and cert verification added, by Bill Janssen. + +- socket.ssl deprecated; use new ssl module instead. + +- uuid creation is now threadsafe. + +- EUC-KR codec now handles the cheot-ga-keut composed make-up hangul + syllables. + +- GB18030 codec now can encode additional two-byte characters that + are missing in GBK. + +- Add new codecs for UTF-32, UTF-32-LE and UTF-32-BE. + +- Bug #1704793: Return UTF-16 pair if unicodedata.lookup cannot + represent the result in a single character. + +- Bug #978833: Close https sockets by releasing the _ssl object. + +- Change location of the package index to pypi.python.org/pypi + +- Bug #1701409: Fix a segfault in printing ctypes.c_char_p and + ctypes.c_wchar_p when they point to an invalid location. As a + sideeffect the representation of these instances has changed. + +- tarfile.py: Added "exclude" keyword argument to TarFile.add(). + +- Bug #1734723: Fix repr.Repr() so it doesn't ignore the maxtuple attribute. + +- The urlopen function of urllib2 now has an optional timeout parameter (note + that it actually works with HTTP, HTTPS, FTP and FTPS connections). + +- In ftplib, the FTP.ntransfercmd method, when in passive mode, now uses + the socket.create_connection function, using the timeout specified at + connection time. + +- Bug #1728403: Fix a bug that CJKCodecs StreamReader hangs when it + reads a file that ends with incomplete sequence and sizehint argument + for .read() is specified. + +- Bug #1730389: Change time.strptime() to use ``\s+`` instead of ``\s*`` when + matching spaces in the specified format argument. + +- SF 1668596/1720897: distutils now copies data files + even if package_dir is empty. + +- sha now raises a DeprecationWarning upon import. + +- md5 now raises a DeprecationWarning upon import. + +- Issue1385: The hmac module now computes the correct hmac when using hashes + with a block size other than 64 bytes (such as sha384 and sha512). + +- mimify now raises a DeprecationWarning upon import. + +- MimeWriter now raises a DeprecationWarning upon import. + +- tarfile.py: Improved unicode support. Unicode input names are now + officially supported. Added "errors" argument to the TarFile class. + +- urllib.ftpwrapper class now accepts an optional timeout. + +- shlex.split() now has an optional "posix" parameter. + +- The posixfile module now raises a DeprecationWarning. + +- Remove the gopherlib module. This also leads to the removal of gopher + support in urllib/urllib2. + +- Fix bug in marshal where bad data would cause a segfault due to + lack of an infinite recursion check. + +- Removed plat-freebsd2 and plat-freebsd3 directories (and IN.py in + the directories). + +- HTML-escape the plain traceback in cgitb's HTML output, to prevent + the traceback inadvertently or maliciously closing the comment and + injecting HTML into the error page. + +- The popen2 module and os.popen* are deprecated. Use the subprocess module. + +- Added an optional credentials argument to SMTPHandler, for use with SMTP + servers which require authentication. + +- Patch #1695948: Added optional timeout parameter to SocketHandler. + +- Bug #1652788: Minor fix for currentframe. + +- Patch #1598415: Added WatchedFileHandler to better support external + log file rotation using e.g. newsyslog or logrotate. This handler is + only useful in Unix/Linux environments. + +- Bug #1706381: Specifying the SWIG option "-c++" in the setup.py file + (as opposed to the command line) will now write file names ending in + ".cpp" too. + +- As specified in RFC 2616, an HTTP response like 2xx indicates that + the client's request was successfully received, understood, and accepted. + Now in these cases no error is raised in urllib (issue #1177) and urllib2. + +- Bug #1290505: time.strptime's internal cache of locale information is now + properly recreated when the locale is changed. + +- Patch #1685563: remove (don't add) duplicate paths in distutils.MSVCCompiler. + +- Added a timeout parameter to the constructor of other protocols + (telnetlib, ftplib, smtplib and poplib). This is second part of the + work started with create_connection() and timeout in httplib, and + closes patch #723312. + +- Patch #1676823: Added create_connection() to socket.py, which may be + called with a timeout, and use it from httplib (whose HTTPConnection + and HTTPSConnection now accept an optional timeout). + +- Bug #978833: Revert r50844, as it broke _socketobject.dup. + +- Bug #1675967: re patterns pickled with Python 2.4 and earlier can + now be unpickled with Python 2.5 and newer. + +- Patch #1630118: add a SpooledTemporaryFile class to tempfile.py. + +- Patch #1273829: os.walk() now has a "followlinks" parameter. If set to + True (which is not the default), it visits symlinks pointing to + directories. + +- Bug #1681228: the webbrowser module now correctly uses the default + GNOME or KDE browser, depending on whether there is a session of one + of those present. Also, it tries the Windows default browser before + trying Mozilla variants. + +- Patch #1339796: add a relpath() function to os.path. + +- Patch #1681153: the wave module now closes a file object it opened if + initialization failed. + +- Bug #767111: fix long-standing bug in urllib which caused an + AttributeError instead of an IOError when the server's response didn't + contain a valid HTTP status line. + +- Patch #957650: "%var%" environment variable references are now properly + expanded in ntpath.expandvars(), also "~user" home directory references + are recognized and handled on Windows. + +- Patch #1429539: pdb now correctly initializes the __main__ module for + the debugged script, which means that imports from __main__ work + correctly now. + +- The nonobvious commands.getstatus() function is now deprecated. + +- Patch #1393667: pdb now has a "run" command which restarts the debugged + Python program, optionally with different arguments. + +- Patch #1649190: Adding support for _Bool to ctypes as c_bool. + +- Patch #1530482: add pydoc.render_doc() which returns the documentation + for a thing instead of paging it to stdout, which pydoc.doc() does. + +- Patch #1533909: the timeit module now accepts callables in addition to + strings for the code to time and the setup code. Also added two + convenience functions for instantiating a Timer and calling its methods. + +- Patch #1537850: tempfile.NamedTemporaryFile now has a "delete" parameter + which can be set to False to prevent the default delete-on-close + behavior. + +- Patch #1581073: add a flag to textwrap that prevents the dropping of + whitespace while wrapping. + +- Patch #1603688: ConfigParser.SafeConfigParser now checks values that + are set for invalid interpolation sequences that would lead to errors + on reading back those values. + +- Added support for the POSIX.1-2001 (pax) format to tarfile.py. Extended + and cleaned up the test suite. Added a new testtar.tar. + +- Patch #1449244: Support Unicode strings in + email.message.Message.{set_charset,get_content_charset}. + +- Patch #1542681: add entries for "with", "as" and "CONTEXTMANAGERS" to + pydoc's help keywords. + +- Patch #1555098: use str.join() instead of repeated string + concatenation in robotparser. + +- Patch #1635454: the csv.DictWriter class now includes the offending + field names in its exception message if you try to write a record with + a dictionary containing fields not in the CSV field names list. + +- Patch #1668100: urllib2 now correctly raises URLError instead of + OSError if accessing a local file via the file:// protocol fails. + +- Patch #1677862: Require a space or tab after import in .pth files. + +- Patch #1192590: Fix pdb's "ignore" and "condition" commands so they trap + the IndexError caused by passing in an invalid breakpoint number. + +- Patch #1599845: Add an option to disable the implicit calls to server_bind() + and server_activate() in the constructors for TCPServer, SimpleXMLRPCServer + and DocXMLRPCServer. + +- Bug #1531963: Make SocketServer.TCPServer's server_address always + be equal to calling getsockname() on the server's socket. Fixed by + patch #1545011. + +- Bug #1651235: When a tuple was passed to a ctypes function call, + Python would crash instead of raising an error. + +- Bug #1646630: ctypes.string_at(buf, 0) and ctypes.wstring_at(buf, 0) + returned string up to the first NUL character. + +- Patch #957003: Implement smtplib.LMTP. + +- Patch #1481079: add support for HTTP_REFERER to CGIHTTPServer. + +- Patch #1675424: Added tests for uncovered code in the zipfile module. + The KeyError raised by Zipfile.getinfo for nonexistent names now has + a descriptive message. + +- Bug #1115886: os.path.splitext('.cshrc') gives now ('.cshrc', ''). + +- unittest now verifies more of its assumptions. In particular, TestCase + and TestSuite subclasses (not instances) are no longer accepted in + TestSuite.addTest(). This should cause no incompatibility since it + never made sense with ordinary subclasses -- the failure just occurred + later, with a more cumbersome exception. + +- Patch #787789: allow to pass custom TestRunner instances to unittest's + main() function. + +- Patches #1550273, #1550272: fix a few bugs in unittest and add a + comprehensive test suite for the module. + +- Patch #1001604: glob.glob() now returns unicode filenames if it was + given a unicode argument and os.listdir() returns unicode filenames. + +- Patch #1673619: setup.py identifies extension modules it doesn't know how + to build and those it knows how to build but that fail to build. + +- Patch #912410: Replace HTML entity references for attribute values + in HTMLParser. + +- Patch #1663234: you can now run doctest on test files and modules + using "python -m doctest [-v] filename ...". + +- Patch #1121142: Implement ZipFile.open. + +- Taught setup.py how to locate Berkeley DB on Macs using MacPorts. + +- Added heapq.merge() for merging sorted input streams. + +- Added collections.namedtuple() for assigning field names to tuples. + +- Added itertools.izip_longest(). + +- Have the encoding package's search function dynamically import using absolute + import semantics. + +- Patch #1647484: Renamed GzipFile's filename attribute to name. + +- Patch #1517891: Mode 'a' for ZipFile now creates the file if it + doesn't exist. + +- Patch #698833: Support file decryption in zipfile. + +- Patch #685268: Consider a package's __path__ in imputil. + +- Patch 1463026: Support default namespace in XMLGenerator. + +- Patch 1571379: Make trace's --ignore-dir facility work in the face of + relative directory names. + +- Bug #1600860: Search for shared python library in LIBDIR, + not lib/python/config, on "linux" and "gnu" systems. + +- Patch #1652681: tarfile.py: create nonexistent files in append mode and + allow appending to empty files. + +- Bug #1124861: Automatically create pipes if GetStdHandle fails in + subprocess. + +- Patch #1634778: add missing encoding aliases for iso8859_15 and + iso8859_16. + +- Patch #1638243: the compiler package is now able to correctly compile + a with statement; previously, executing code containing a with statement + compiled by the compiler package crashed the interpreter. + +- Bug #1643943: Fix time.strptime's support for the %U directive. + +- Patch #1507247: tarfile.py: use current umask for intermediate + directories. + +- Patch #1627441: close sockets properly in urllib2. + +- Bug #494589: make ntpath.expandvars behave according to its docstring. + +- Changed platform module API python_version_tuple() to actually + return a tuple (it used to return a list). + +- Added new platform module APIs python_branch(), python_revision(), + python_implementation() and linux_distribution(). + +- Added support for IronPython and Jython to the platform module. + +- The sets module has been deprecated. Use the built-in set/frozenset types + instead. + +- Bug #1610795: make ctypes.util.find_library work on BSD systems. + +- Fixes for 64-bit Windows: In ctypes.wintypes, correct the + definitions of HANDLE, WPARAM, LPARAM data types. Make + parameterless foreign function calls work. + +- The version number of the ctypes package changed to "1.1.0". + +- Bug #1627575: logging: Added _open() method to FileHandler which can + be used to reopen files. The FileHandler instance now saves the + encoding (which can be None) in an attribute called "encoding". + +- Bug #411881: logging.handlers: bare except clause removed from + SMTPHandler.emit. Now, only ImportError is trapped. + +- Bug #411881: logging.handlers: bare except clause removed from + SocketHandler.createSocket. Now, only socket.error is trapped. + +- Bug #411881: logging: bare except clause removed from LogRecord.__init__. + Now, only ValueError, TypeError and AttributeError are trapped. + +- Patch #1504073: Fix tarfile.open() for mode "r" with a fileobj argument. + +- Patch #1182394 from Shane Holloway: speed up HMAC.hexdigest. + +- Patch #1262036: Prevent TarFiles from being added to themselves under + certain conditions. + +- Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell() + work correctly together with readline(). + +- Patch #1484695: The tarfile module now raises a HeaderError exception + if a buffer given to frombuf() is invalid. + +- Bug #1503765: Fix a problem in logging.config with spaces in comma- + separated lists read from logging config files. + +- Patch #1604907: Fix problems in logging.handlers caused at logging shutdown + when syslog handlers fail to initialize because of syslogd problems. + +- Patch #1608267: fix a race condition in os.makedirs() if the directory + to be created is already there. + +- Patch #1610437: fix a tarfile bug with long filename headers. + +- Patch #1371075: Make ConfigParser accept optional dict type + for ordering, sorting, etc. + +- Bug #1563807: _ctypes built on AIX fails with ld ffi error. + +- Bug #1598620: A ctypes Structure cannot contain itself. + +- Patch #1070046: Marshal new-style objects like InstanceType + in xmlrpclib. + +- cStringIO.truncate(-1) now raises an IOError, like StringIO and + regular files. + +- Patch #1472877: Fix Tix subwidget name resolution. + +- Patch #1594554: Always close a tkSimpleDialog on ok(), even + if an exception occurs. + +- Patch #1538878: Don't make tkSimpleDialog dialogs transient if + the parent window is withdrawn. + +- Bug #1597824: return the registered function from atexit.register() + to facilitate usage as a decorator. + +- Patch #1360200: Use unmangled_version RPM spec field to deal with + file name mangling. + +- Patch #1359217: Process 2xx response in an ftplib transfer + that precedes an 1xx response. + +- Patch #1355023: support whence argument for GzipFile.seek. + +- Patch #1065257: Support passing open files as body in + HTTPConnection.request(). + +- Bug #1569790: mailbox.py: Maildir.get_folder() and MH.get_folder() + weren't passing the message factory on to newly created Maildir/MH + objects. + +- Patch #1514543: mailbox.py: In the Maildir class, report errors if there's + a filename clash instead of possibly losing a message. (Patch by David + Watson.) + +- Patch #1514544: Try to ensure that messages/indexes have been physically + written to disk after calling .flush() or .close(). (Patch by David + Watson.) + +- Patch #1592250: Add elidge argument to Tkinter.Text.search. + +- Patch #838546: Make terminal become controlling in pty.fork() + +- Patch #1351744: Add askyesnocancel helper for tkMessageBox. + +- Patch #1060577: Extract list of RPM files from spec file in + bdist_rpm + +- Bug #1586613: fix zlib and bz2 codecs' incremental en/decoders. + +- Patch #1583880: fix tarfile's problems with long names and posix/ + GNU modes. + +- Bug #1586448: the compiler module now emits the same bytecode for + list comprehensions as the builtin compiler, using the LIST_APPEND + opcode. + +- Fix codecs.EncodedFile which did not use file_encoding in 2.5.0, and + fix all codecs file wrappers to work correctly with the "with" + statement (bug #1586513). + +- Lib/modulefinder.py now handles absolute and relative imports + correctly. + +- Patch #1567274: Support SMTP over TLS. + +- Patch #1560695: Add .note.GNU-stack to ctypes' sysv.S so that + ctypes isn't considered as requiring executable stacks. + +- ctypes callback functions only support 'fundamental' data types as + result type. Raise an error when something else is used. This is a + partial fix for Bug #1574584. + +- Fix turtle so that time.sleep is imported for the entire library. Allows + the demo2 function to be executed on its own instead of only when the + module is run as a script. + +- Bug #813342: Start the IDLE subprocess with -Qnew if the parent + is started with that option. + +- Bug #1565150: Fix subsecond processing for os.utime on Windows. + +- Support for MSVC 8 was added to bdist_wininst. + +- Bug #1446043: correctly raise a LookupError if an encoding name given + to encodings.search_function() contains a dot. + +- Bug #1560617: in pyclbr, return full module name not only for classes, + but also for functions. + +- Bug #1457823: cgi.(Sv)FormContentDict's constructor now takes + keep_blank_values and strict_parsing keyword arguments. + +- Bug #1566602: correct failure of posixpath unittest when $HOME ends + with a slash. + +- Bug #1565661: in webbrowser, split() the command for the default + GNOME browser in case it is a command with args. + +- Made the error message for time.strptime when the data data and format do + match be more clear. + +- Fix a bug in traceback.format_exception_only() that led to an error + being raised when print_exc() was called without an exception set. + In version 2.4, this printed "None", restored that behavior. + +- Make webbrowser.BackgroundBrowser usable in Windows (it wasn't because + the close_fds arg to subprocess.Popen is not supported). + +- Reverted patch #1504333 to sgmllib because it introduced an infinite loop. + +- Patch #1553314: Fix the inspect.py slowdown that was hurting IPython & SAGE + by adding smarter caching in inspect.getmodule() + +- Fix missing import of the types module in logging.config. + +- Patch #1550886: Fix decimal module context management implementation + to match the localcontext() example from PEP 343. + +- Bug #1545341: The 'classifier' keyword argument to the Distutils setup() + function now accepts tuples as well as lists. + +- Bug #1541863: uuid.uuid1 failed to generate unique identifiers + on systems with low clock resolution. + +- Bug #1531862: Do not close standard file descriptors in subprocess. + +- idle: Honor the "Cancel" action in the save dialog (Debian bug #299092). + +- Fix utf-8-sig incremental decoder, which didn't recognise a BOM when the + first chunk fed to the decoder started with a BOM, but was longer than 3 bytes. + +- The implementation of UnicodeError objects has been simplified (start and end + attributes are now stored directly as Py_ssize_t members). + +>>>>>>> .merge-right.r59840 Extension Modules ----------------- Modified: python/branches/py3k/Modules/main.c ============================================================================== --- python/branches/py3k/Modules/main.c (original) +++ python/branches/py3k/Modules/main.c Mon Jan 7 22:14:23 2008 @@ -44,7 +44,7 @@ static int orig_argc; /* command line options */ -#define BASE_OPTS "bc:dEhim:OStuvVW:xX?" +#define BASE_OPTS "bBc:dEhim:OStuvVW:xX?" #define PROGRAM_OPTS BASE_OPTS @@ -57,9 +57,10 @@ Options and arguments (and corresponding environment variables):\n\ -b : issue warnings about str(bytes_instance), str(buffer_instance)\n\ and comparing bytes/buffer with str. (-bb: issue errors)\n\ +-B : don't write .py[co] files on import; also PYTHONDONTWRITEBYTECODE=x\n\ -c cmd : program passed in as string (terminates option list)\n\ -d : debug output from parser; also PYTHONDEBUG=x\n\ --E : ignore environment variables (such as PYTHONPATH)\n\ +-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\ -h : print this help message and exit (also --help)\n\ "; static char *usage_2 = "\ @@ -88,6 +89,8 @@ PYTHONSTARTUP: file executed on interactive startup (no default)\n\ PYTHONPATH : '%c'-separated list of directories prefixed to the\n\ default module search path. The result is sys.path.\n\ +"; +static char *usage_5 = "\ PYTHONHOME : alternate directory (or %c).\n\ The default module search path uses %s.\n\ PYTHONCASEOK : ignore case in 'import' statements (Windows).\n\ @@ -106,7 +109,8 @@ fprintf(f, usage_1); fprintf(f, usage_2); fprintf(f, usage_3); - fprintf(f, usage_4, DELIM, DELIM, PYTHONHOMEHELP); + fprintf(f, usage_4, DELIM); + fprintf(f, usage_5, DELIM, PYTHONHOMEHELP); } #if defined(__VMS) if (exitcode == 0) { @@ -313,6 +317,10 @@ Py_OptimizeFlag++; break; + case 'B': + Py_DontWriteBytecodeFlag++; + break; + case 'S': Py_NoSiteFlag++; break; Modified: python/branches/py3k/Python/import.c ============================================================================== --- python/branches/py3k/Python/import.c (original) +++ python/branches/py3k/Python/import.c Mon Jan 7 22:14:23 2008 @@ -954,8 +954,11 @@ if (Py_VerboseFlag) PySys_WriteStderr("import %s # from %s\n", name, pathname); - if (cpathname) - write_compiled_module(co, cpathname, mtime); + if (cpathname) { + PyObject *ro = PySys_GetObject("dont_write_bytecode"); + if (ro == NULL || !PyObject_IsTrue(ro)) + write_compiled_module(co, cpathname, mtime); + } } m = PyImport_ExecCodeModuleEx(name, (PyObject *)co, pathname); Py_DECREF(co); @@ -1604,7 +1607,7 @@ FILEFINDBUF3 ffbuf; APIRET rc; - if (getenv("PYTHONCASEOK") != NULL) + if (Py_GETENV("PYTHONCASEOK") != NULL) return 1; rc = DosFindFirst(buf, Modified: python/branches/py3k/Python/pythonrun.c ============================================================================== --- python/branches/py3k/Python/pythonrun.c (original) +++ python/branches/py3k/Python/pythonrun.c Mon Jan 7 22:14:23 2008 @@ -76,6 +76,7 @@ int Py_InspectFlag; /* Needed to determine whether to exit at SystemError */ int Py_NoSiteFlag; /* Suppress 'import site' */ int Py_BytesWarningFlag; /* Warn on str(bytes) and str(buffer) */ +int Py_DontWriteBytecodeFlag; /* Suppress writing bytecode files (*.py[co]) */ int Py_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c: deprecated */ int Py_FrozenFlag; /* Needed by getpath.c */ int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */ @@ -176,6 +177,8 @@ Py_VerboseFlag = add_flag(Py_VerboseFlag, p); if ((p = Py_GETENV("PYTHONOPTIMIZE")) && *p != '\0') Py_OptimizeFlag = add_flag(Py_OptimizeFlag, p); + if ((p = Py_GETENV("PYTHONDONTWRITEBYTECODE")) && *p != '\0') + Py_DontWriteBytecodeFlag = add_flag(Py_DontWriteBytecodeFlag, p); interp = PyInterpreterState_New(); if (interp == NULL) Modified: python/branches/py3k/Python/sysmodule.c ============================================================================== --- python/branches/py3k/Python/sysmodule.c (original) +++ python/branches/py3k/Python/sysmodule.c Mon Jan 7 22:14:23 2008 @@ -1041,6 +1041,9 @@ v = Py_BuildValue("(UUU)", "CPython", branch, svn_revision); PyDict_SetItemString(sysdict, "subversion", v); Py_XDECREF(v); + PyDict_SetItemString(sysdict, "dont_write_bytecode", + v = PyBool_FromLong(Py_DontWriteBytecodeFlag)); + Py_XDECREF(v); /* * These release level checks are mutually exclusive and cover * the field, so don't get too fancy with the pre-processor! Modified: python/branches/py3k/Python/thread.c ============================================================================== --- python/branches/py3k/Python/thread.c (original) +++ python/branches/py3k/Python/thread.c Mon Jan 7 22:14:23 2008 @@ -79,7 +79,7 @@ PyThread_init_thread(void) { #ifdef Py_DEBUG - char *p = getenv("THREADDEBUG"); + char *p = Py_GETENV("PYTHONTHREADDEBUG"); if (p) { if (*p) From python-3000-checkins at python.org Wed Jan 9 01:17:25 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Wed, 9 Jan 2008 01:17:25 +0100 (CET) Subject: [Python-3000-checkins] r59864 - in python/branches/py3k: Doc/library/_winreg.rst Doc/library/collections.rst Doc/library/pyexpat.rst Doc/using/windows.rst Doc/whatsnew/2.6.rst Lib/collections.py Lib/decimal.py Lib/test/test_decimal.py Lib/test/test_pyexpat.py Lib/test/test_socket.py Lib/test/test_winreg.py Misc/ACKS Modules/_ctypes/callbacks.c Modules/_ctypes/callproc.c Modules/_cursesmodule.c Modules/_sre.c Modules/pyexpat.c PC/_winreg.c Message-ID: <20080109001725.6ADEB1E4017@bag.python.org> Author: christian.heimes Date: Wed Jan 9 01:17:24 2008 New Revision: 59864 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/_winreg.rst python/branches/py3k/Doc/library/collections.rst python/branches/py3k/Doc/library/pyexpat.rst python/branches/py3k/Doc/using/windows.rst python/branches/py3k/Doc/whatsnew/2.6.rst python/branches/py3k/Lib/collections.py python/branches/py3k/Lib/decimal.py python/branches/py3k/Lib/test/test_decimal.py python/branches/py3k/Lib/test/test_pyexpat.py python/branches/py3k/Lib/test/test_socket.py python/branches/py3k/Lib/test/test_winreg.py python/branches/py3k/Misc/ACKS python/branches/py3k/Modules/_ctypes/callbacks.c python/branches/py3k/Modules/_ctypes/callproc.c python/branches/py3k/Modules/_cursesmodule.c python/branches/py3k/Modules/_sre.c python/branches/py3k/Modules/pyexpat.c python/branches/py3k/PC/_winreg.c Log: Merged revisions 59843-59863 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r59844 | raymond.hettinger | 2008-01-07 21:56:05 +0100 (Mon, 07 Jan 2008) | 1 line Use get() instead of pop() for the optimized version of _replace(). ........ r59847 | raymond.hettinger | 2008-01-07 22:33:51 +0100 (Mon, 07 Jan 2008) | 1 line Documentation nits. ........ r59849 | raymond.hettinger | 2008-01-08 03:02:05 +0100 (Tue, 08 Jan 2008) | 1 line Expand comment. ........ r59850 | raymond.hettinger | 2008-01-08 03:24:15 +0100 (Tue, 08 Jan 2008) | 1 line Docs on named tuple's naming conventions and limits of subclassing ........ r59851 | christian.heimes | 2008-01-08 04:40:04 +0100 (Tue, 08 Jan 2008) | 1 line It's verbose, not debug ........ r59852 | facundo.batista | 2008-01-08 13:25:20 +0100 (Tue, 08 Jan 2008) | 4 lines Issue #1757: The hash of a Decimal instance is no longer affected by the current context. Thanks Mark Dickinson. ........ r59853 | andrew.kuchling | 2008-01-08 15:30:55 +0100 (Tue, 08 Jan 2008) | 1 line Patch 1137: allow assigning to .buffer_size attribute of PyExpat.parser objects ........ r59854 | andrew.kuchling | 2008-01-08 15:56:02 +0100 (Tue, 08 Jan 2008) | 1 line Patch 1114: fix compilation of curses module on 64-bit AIX, and any other LP64 platforms where attr_t isn't a C long ........ r59856 | thomas.heller | 2008-01-08 16:15:09 +0100 (Tue, 08 Jan 2008) | 5 lines Use relative instead of absolute filenames in the C-level tracebacks. This prevents traceback prints pointing to files in this way: File "\loewis\25\python\Modules\_ctypes\callbacks.c", line 206, in 'calling callback function' ........ r59857 | christian.heimes | 2008-01-08 16:46:10 +0100 (Tue, 08 Jan 2008) | 2 lines Added __enter__ and __exit__ functions to HKEY object Added ExpandEnvironmentStrings to the _winreg module. ........ r59858 | georg.brandl | 2008-01-08 17:18:26 +0100 (Tue, 08 Jan 2008) | 2 lines Fix markup errors from r59857 and clarify key.__enter__/__exit__ docs ........ r59860 | georg.brandl | 2008-01-08 20:42:30 +0100 (Tue, 08 Jan 2008) | 2 lines Better method for associating .py files with the interpreter. ........ r59862 | facundo.batista | 2008-01-08 22:10:12 +0100 (Tue, 08 Jan 2008) | 9 lines Issue 846388. Adds a call to PyErr_CheckSignals to SRE_MATCH so that signal handlers can be invoked during long regular expression matches. It also adds a new error return value indicating that an exception occurred in a signal handler during the match, allowing exceptions in the signal handler to propagate up to the main loop. Thanks Josh Hoyt and Ralf Schmitt. ........ Modified: python/branches/py3k/Doc/library/_winreg.rst ============================================================================== --- python/branches/py3k/Doc/library/_winreg.rst (original) +++ python/branches/py3k/Doc/library/_winreg.rst Wed Jan 9 01:17:24 2008 @@ -131,6 +131,16 @@ +-------+--------------------------------------------+ +.. function:: ExpandEnvironmentStrings(unicode) + + Expands environment strings %NAME% in unicode string like const:`REG_EXPAND_SZ`:: + + >>> ExpandEnvironmentStrings(u"%windir%") + u"C:\\Windows" + + .. versionadded:: 2.6 + + .. function:: FlushKey(key) Writes all the attributes of a key to the registry. @@ -416,3 +426,16 @@ handle is not closed. You would call this function when you need the underlying Win32 handle to exist beyond the lifetime of the handle object. +.. method:: PyHKEY.__enter__() + PyHKEY.__exit__(\*exc_info) + + The HKEY object implements :meth:`__enter__` and :meth:`__exit__` and thus + supports the context protocol for the :keyword:`with` statement:: + + with OpenKey(HKEY_LOCAL_MACHINE, "foo") as key: + # ... work with key ... + + will automatically close *key* when control leaves the :keyword:`with` block. + + .. versionadded:: 2.6 + Modified: python/branches/py3k/Doc/library/collections.rst ============================================================================== --- python/branches/py3k/Doc/library/collections.rst (original) +++ python/branches/py3k/Doc/library/collections.rst Wed Jan 9 01:17:24 2008 @@ -397,8 +397,8 @@ method which lists the tuple contents in a ``name=value`` format. The *fieldnames* are a single string with each fieldname separated by whitespace - and/or commas (for example 'x y' or 'x, y'). Alternatively, the *fieldnames* - can be specified with a sequence of strings (such as ['x', 'y']). + and/or commas (for example 'x y' or 'x, y'). Alternatively, *fieldnames* + can be a sequence of strings (such as ['x', 'y']). Any valid Python identifier may be used for a fieldname except for names starting with an underscore. Valid identifiers consist of letters, digits, @@ -477,7 +477,8 @@ print emp.name, emp.title In addition to the methods inherited from tuples, named tuples support -three additional methods and one attribute. +three additional methods and one attribute. To prevent conflicts with +field names, the method and attribute names start with an underscore. .. method:: somenamedtuple._make(iterable) @@ -513,7 +514,7 @@ .. attribute:: somenamedtuple._fields - Tuple of strings listing the field names. This is useful for introspection + Tuple of strings listing the field names. Useful for introspection and for creating new named tuple types from existing named tuples. :: @@ -532,7 +533,7 @@ >>> getattr(p, 'x') 11 -When casting a dictionary to a named tuple, use the double-star-operator [#]_:: +To cast a dictionary to a named tuple, use the double-star-operator [#]_:: >>> d = {'x': 11, 'y': 22} >>> Point(**d) @@ -557,14 +558,20 @@ Point: x= 1.286 y= 6.000 hypot= 6.136 Another use for subclassing is to replace performance critcal methods with -faster versions that bypass error-checking and localize variable access:: +faster versions that bypass error-checking and that localize variable access:: >>> class Point(namedtuple('Point', 'x y')): _make = classmethod(tuple.__new__) def _replace(self, _map=map, **kwds): - return self._make(_map(kwds.pop, ('x', 'y'), self)) + return self._make(_map(kwds.get, ('x', 'y'), self)) -Default values can be implemented by using :meth:`_replace`:: to + +Subclassing is not useful for adding new, stored fields. Instead, simply +create a new named tuple type from the :attr:`_fields` attribute:: + + >>> Pixel = namedtuple('Pixel', Point._fields + Color._fields) + +Default values can be implemented by using :meth:`_replace` to customize a prototype instance:: >>> Account = namedtuple('Account', 'owner balance transaction_count') Modified: python/branches/py3k/Doc/library/pyexpat.rst ============================================================================== --- python/branches/py3k/Doc/library/pyexpat.rst (original) +++ python/branches/py3k/Doc/library/pyexpat.rst Wed Jan 9 01:17:24 2008 @@ -177,8 +177,13 @@ .. attribute:: xmlparser.buffer_size - The size of the buffer used when :attr:`buffer_text` is true. This value cannot - be changed at this time. + The size of the buffer used when :attr:`buffer_text` is true. + A new buffer size can be set by assigning a new integer value + to this attribute. + When the size is changed, the buffer will be flushed. + + .. versionchanged:: 2.6 + The buffer size can now be changed. .. attribute:: xmlparser.buffer_text Modified: python/branches/py3k/Doc/using/windows.rst ============================================================================== --- python/branches/py3k/Doc/using/windows.rst (original) +++ python/branches/py3k/Doc/using/windows.rst Wed Jan 9 01:17:24 2008 @@ -188,16 +188,17 @@ startup. You can also make all ``.py`` scripts execute with :program:`pythonw.exe`, -setting this through the usual facilites, for example (names might differ, -depending on your version of Windows): - -#. Open the context menu of a :file:`{*}.py` file. -#. Click :menuselection:`Open with...`. -#. Choose the interpreter of your choice (utilize :guilabel:`Other...` or - :guilabel:`Choose Program...` if it is not in the list of default programs). -#. Check :guilabel:`Always open files with this program`. -#. Click :guilabel:`OK`. +setting this through the usual facilites, for example (might require +administrative rights): +#. Launch a command prompt. +#. Associate the correct file group with ``.py`` scripts:: + + assoc .py=Python.File + +#. Redirect all Python files to the new executable:: + + ftype Python.File=C:\Path\to\pythonw.exe "%1" %* Additional modules Modified: python/branches/py3k/Doc/whatsnew/2.6.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/2.6.rst (original) +++ python/branches/py3k/Doc/whatsnew/2.6.rst Wed Jan 9 01:17:24 2008 @@ -875,6 +875,13 @@ changed and :const:`UF_APPEND` to indicate that data can only be appended to the file. (Contributed by M. Levinson.) +* The :mod:`pyexpat` module's :class:`Parser` objects now allow setting + their :attr:`buffer_size` attribute to change the size of the buffer + used to hold character data. + (Contributed by Achim Gaedke.) + + .. Patch 1137 + * The :mod:`random` module's :class:`Random` objects can now be pickled on a 32-bit system and unpickled on a 64-bit system, and vice versa. Unfortunately, this change also means Modified: python/branches/py3k/Lib/collections.py ============================================================================== --- python/branches/py3k/Lib/collections.py (original) +++ python/branches/py3k/Lib/collections.py Wed Jan 9 01:17:24 2008 @@ -34,7 +34,8 @@ """ - # Parse and validate the field names + # Parse and validate the field names. Validation serves two purposes, + # generating informative error messages and preventing template injection attacks. if isinstance(field_names, str): field_names = field_names.replace(',', ' ').split() # names separated by whitespace and/or commas field_names = tuple(field_names) @@ -129,7 +130,7 @@ 'Point class with optimized _make() and _replace() without error-checking' _make = classmethod(tuple.__new__) def _replace(self, _map=map, **kwds): - return self._make(_map(kwds.pop, ('x', 'y'), self)) + return self._make(_map(kwds.get, ('x', 'y'), self)) print(Point(11, 22)._replace(x=100)) Modified: python/branches/py3k/Lib/decimal.py ============================================================================== --- python/branches/py3k/Lib/decimal.py (original) +++ python/branches/py3k/Lib/decimal.py Wed Jan 9 01:17:24 2008 @@ -809,8 +809,10 @@ def __hash__(self): """x.__hash__() <==> hash(x)""" # Decimal integers must hash the same as the ints - # Non-integer decimals are normalized and hashed as strings - # Normalization assures that hash(100E-1) == hash(10) + # + # The hash of a nonspecial noninteger Decimal must depend only + # on the value of that Decimal, and not on its representation. + # For example: hash(Decimal("100E-1")) == hash(Decimal("10")). if self._is_special: if self._isnan(): raise TypeError('Cannot hash a NaN value.') @@ -826,7 +828,13 @@ # 2**64-1. So we can replace hash((-1)**s*c*10**e) with # hash((-1)**s*c*pow(10, e, 2**64-1). return hash((-1)**op.sign*op.int*pow(10, op.exp, 2**64-1)) - return hash(str(self.normalize())) + # The value of a nonzero nonspecial Decimal instance is + # faithfully represented by the triple consisting of its sign, + # its adjusted exponent, and its coefficient with trailing + # zeros removed. + return hash((self._sign, + self._exp+len(self._int), + self._int.rstrip('0'))) def as_tuple(self): """Represents the number as a triple tuple. Modified: python/branches/py3k/Lib/test/test_decimal.py ============================================================================== --- python/branches/py3k/Lib/test/test_decimal.py (original) +++ python/branches/py3k/Lib/test/test_decimal.py Wed Jan 9 01:17:24 2008 @@ -971,6 +971,23 @@ self.assert_(hash(Decimal('Inf'))) self.assert_(hash(Decimal('-Inf'))) + # check that the value of the hash doesn't depend on the + # current context (issue #1757) + c = getcontext() + old_precision = c.prec + x = Decimal("123456789.1") + + c.prec = 6 + h1 = hash(x) + c.prec = 10 + h2 = hash(x) + c.prec = 16 + h3 = hash(x) + + self.assertEqual(h1, h2) + self.assertEqual(h1, h3) + c.prec = old_precision + def test_min_and_max_methods(self): d1 = Decimal('15.32') Modified: python/branches/py3k/Lib/test/test_pyexpat.py ============================================================================== --- python/branches/py3k/Lib/test/test_pyexpat.py (original) +++ python/branches/py3k/Lib/test/test_pyexpat.py Wed Jan 9 01:17:24 2008 @@ -2,6 +2,7 @@ # handler, are obscure and unhelpful. from io import BytesIO +import sys import unittest import pyexpat @@ -385,6 +386,130 @@ self.assertRaises(Exception, parser.Parse, xml) +class ChardataBufferTest(unittest.TestCase): + """ + test setting of chardata buffer size + """ + + def test_1025_bytes(self): + self.assertEquals(self.small_buffer_test(1025), 2) + + def test_1000_bytes(self): + self.assertEquals(self.small_buffer_test(1000), 1) + + def test_wrong_size(self): + parser = expat.ParserCreate() + parser.buffer_text = 1 + def f(size): + parser.buffer_size = size + + self.assertRaises(ValueError, f, -1) + self.assertRaises(ValueError, f, 0) + + def test_unchanged_size(self): + xml1 = ("%s" % ('a' * 512)) + xml2 = 'a'*512 + '' + parser = expat.ParserCreate() + parser.CharacterDataHandler = self.counting_handler + parser.buffer_size = 512 + parser.buffer_text = 1 + + # Feed 512 bytes of character data: the handler should be called + # once. + self.n = 0 + parser.Parse(xml1) + self.assertEquals(self.n, 1) + + # Reassign to buffer_size, but assign the same size. + parser.buffer_size = parser.buffer_size + self.assertEquals(self.n, 1) + + # Try parsing rest of the document + parser.Parse(xml2) + self.assertEquals(self.n, 2) + + + def test_disabling_buffer(self): + xml1 = "%s" % ('a' * 512) + xml2 = ('b' * 1024) + xml3 = "%s" % ('c' * 1024) + parser = expat.ParserCreate() + parser.CharacterDataHandler = self.counting_handler + parser.buffer_text = 1 + parser.buffer_size = 1024 + self.assertEquals(parser.buffer_size, 1024) + + # Parse one chunk of XML + self.n = 0 + parser.Parse(xml1, 0) + self.assertEquals(parser.buffer_size, 1024) + self.assertEquals(self.n, 1) + + # Turn off buffering and parse the next chunk. + parser.buffer_text = 0 + self.assertFalse(parser.buffer_text) + self.assertEquals(parser.buffer_size, 1024) + for i in range(10): + parser.Parse(xml2, 0) + self.assertEquals(self.n, 11) + + parser.buffer_text = 1 + self.assertTrue(parser.buffer_text) + self.assertEquals(parser.buffer_size, 1024) + parser.Parse(xml3, 1) + self.assertEquals(self.n, 12) + + + + def make_document(self, bytes): + return ("" + bytes * 'a' + '') + + def counting_handler(self, text): + self.n += 1 + + def small_buffer_test(self, buffer_len): + xml = "%s" % ('a' * buffer_len) + parser = expat.ParserCreate() + parser.CharacterDataHandler = self.counting_handler + parser.buffer_size = 1024 + parser.buffer_text = 1 + + self.n = 0 + parser.Parse(xml) + return self.n + + def test_change_size_1(self): + xml1 = "%s" % ('a' * 1024) + xml2 = "aaa%s" % ('a' * 1025) + parser = expat.ParserCreate() + parser.CharacterDataHandler = self.counting_handler + parser.buffer_text = 1 + parser.buffer_size = 1024 + self.assertEquals(parser.buffer_size, 1024) + + self.n = 0 + parser.Parse(xml1, 0) + parser.buffer_size *= 2 + self.assertEquals(parser.buffer_size, 2048) + parser.Parse(xml2, 1) + self.assertEquals(self.n, 2) + + def test_change_size_2(self): + xml1 = "a%s" % ('a' * 1023) + xml2 = "aaa%s" % ('a' * 1025) + parser = expat.ParserCreate() + parser.CharacterDataHandler = self.counting_handler + parser.buffer_text = 1 + parser.buffer_size = 2048 + self.assertEquals(parser.buffer_size, 2048) + + self.n=0 + parser.Parse(xml1, 0) + parser.buffer_size = parser.buffer_size // 2 + self.assertEquals(parser.buffer_size, 1024) + parser.Parse(xml2, 1) + self.assertEquals(self.n, 4) + def test_main(): run_unittest(SetAttributeTest, @@ -394,7 +519,8 @@ BufferTextTest, HandlerExceptionTest, PositionTest, - sf1296433Test) + sf1296433Test, + ChardataBufferTest) if __name__ == "__main__": test_main() Modified: python/branches/py3k/Lib/test/test_socket.py ============================================================================== --- python/branches/py3k/Lib/test/test_socket.py (original) +++ python/branches/py3k/Lib/test/test_socket.py Wed Jan 9 01:17:24 2008 @@ -1133,7 +1133,7 @@ for line in f: if line.startswith("tipc "): return True - if test_support.debug: + if test_support.verbose: print("TIPC module is not loaded, please 'sudo modprobe tipc'") return False Modified: python/branches/py3k/Lib/test/test_winreg.py ============================================================================== --- python/branches/py3k/Lib/test/test_winreg.py (original) +++ python/branches/py3k/Lib/test/test_winreg.py Wed Jan 9 01:17:24 2008 @@ -73,26 +73,26 @@ key = OpenKey(root_key, test_key_name) # Read the sub-keys - sub_key = OpenKey(key, subkeystr) - # Check I can enumerate over the values. - index = 0 - while 1: - try: - data = EnumValue(sub_key, index) - except EnvironmentError: - break - self.assertEquals(data in test_data, True, - "Didn't read back the correct test data") - index = index + 1 - self.assertEquals(index, len(test_data), - "Didn't read the correct number of items") - # Check I can directly access each item - for value_name, value_data, value_type in test_data: - read_val, read_typ = QueryValueEx(sub_key, value_name) - self.assertEquals(read_val, value_data, - "Could not directly read the value") - self.assertEquals(read_typ, value_type, - "Could not directly read the value") + with OpenKey(key, "sub_key") as sub_key: + # Check I can enumerate over the values. + index = 0 + while 1: + try: + data = EnumValue(sub_key, index) + except EnvironmentError: + break + self.assertEquals(data in test_data, True, + "Didn't read back the correct test data") + index = index + 1 + self.assertEquals(index, len(test_data), + "Didn't read the correct number of items") + # Check I can directly access each item + for value_name, value_data, value_type in test_data: + read_val, read_typ = QueryValueEx(sub_key, value_name) + self.assertEquals(read_val, value_data, + "Could not directly read the value") + self.assertEquals(read_typ, value_type, + "Could not directly read the value") sub_key.Close() # Enumerate our main key. read_val = EnumKey(key, 0) @@ -155,6 +155,11 @@ remote_key = ConnectRegistry(self.remote_name, HKEY_CURRENT_USER) self.TestAll(remote_key) + def testExpandEnvironmentStrings(self): + r = ExpandEnvironmentStrings("%windir%\\test") + self.assertEqual(type(r), str) + self.assertEqual(r, os.environ["windir"] + "\\test") + def test_main(): test_support.run_unittest(WinregTests) Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Wed Jan 9 01:17:24 2008 @@ -227,6 +227,7 @@ Peter Funk Geoff Furnish Ulisses Furquim +Achim Gaedke Lele Gaifax Santiago Gala Yitzchak Gale Modified: python/branches/py3k/Modules/_ctypes/callbacks.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/callbacks.c (original) +++ python/branches/py3k/Modules/_ctypes/callbacks.c Wed Jan 9 01:17:24 2008 @@ -197,7 +197,7 @@ } #define CHECK(what, x) \ -if (x == NULL) _AddTraceback(what, __FILE__, __LINE__ - 1), PyErr_Print() +if (x == NULL) _AddTraceback(what, "_ctypes/callbacks.c", __LINE__ - 1), PyErr_Print() result = PyObject_CallObject(callable, arglist); CHECK("'calling callback function'", result); Modified: python/branches/py3k/Modules/_ctypes/callproc.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/callproc.c (original) +++ python/branches/py3k/Modules/_ctypes/callproc.c Wed Jan 9 01:17:24 2008 @@ -755,7 +755,7 @@ v = PyObject_CallFunctionObjArgs(checker, retval, NULL); if (v == NULL) - _AddTraceback("GetResult", __FILE__, __LINE__-2); + _AddTraceback("GetResult", "_ctypes/callproc.c", __LINE__-2); Py_DECREF(retval); return v; } Modified: python/branches/py3k/Modules/_cursesmodule.c ============================================================================== --- python/branches/py3k/Modules/_cursesmodule.c (original) +++ python/branches/py3k/Modules/_cursesmodule.c Wed Jan 9 01:17:24 2008 @@ -322,9 +322,6 @@ Window_NoArg2TupleReturnFunction(getmaxyx, int, "ii") Window_NoArg2TupleReturnFunction(getparyx, int, "ii") -Window_OneArgNoReturnFunction(wattron, attr_t, "l;attr") -Window_OneArgNoReturnFunction(wattroff, attr_t, "l;attr") -Window_OneArgNoReturnFunction(wattrset, attr_t, "l;attr") Window_OneArgNoReturnFunction(clearok, int, "i;True(1) or False(0)") Window_OneArgNoReturnFunction(idlok, int, "i;True(1) or False(0)") #if defined(__NetBSD__) @@ -379,6 +376,7 @@ PyObject *temp; chtype ch = 0; attr_t attr = A_NORMAL; + long lattr; switch (PyTuple_Size(args)) { case 1: @@ -386,8 +384,9 @@ return NULL; break; case 2: - if (!PyArg_ParseTuple(args, "Ol;ch or int,attr", &temp, &attr)) + if (!PyArg_ParseTuple(args, "Ol;ch or int,attr", &temp, &lattr)) return NULL; + attr = lattr; break; case 3: if (!PyArg_ParseTuple(args,"iiO;y,x,ch or int", &y, &x, &temp)) @@ -396,8 +395,9 @@ break; case 4: if (!PyArg_ParseTuple(args,"iiOl;y,x,ch or int, attr", - &y, &x, &temp, &attr)) + &y, &x, &temp, &lattr)) return NULL; + attr = lattr; use_xy = TRUE; break; default: @@ -425,6 +425,7 @@ int x, y; char *str; attr_t attr = A_NORMAL , attr_old = A_NORMAL; + long lattr; int use_xy = FALSE, use_attr = FALSE; switch (PyTuple_Size(args)) { @@ -433,8 +434,9 @@ return NULL; break; case 2: - if (!PyArg_ParseTuple(args,"sl;str,attr", &str, &attr)) + if (!PyArg_ParseTuple(args,"sl;str,attr", &str, &lattr)) return NULL; + attr = lattr; use_attr = TRUE; break; case 3: @@ -443,8 +445,9 @@ use_xy = TRUE; break; case 4: - if (!PyArg_ParseTuple(args,"iisl;int,int,str,attr", &y, &x, &str, &attr)) + if (!PyArg_ParseTuple(args,"iisl;int,int,str,attr", &y, &x, &str, &lattr)) return NULL; + attr = lattr; use_xy = use_attr = TRUE; break; default: @@ -471,6 +474,7 @@ int rtn, x, y, n; char *str; attr_t attr = A_NORMAL , attr_old = A_NORMAL; + long lattr; int use_xy = FALSE, use_attr = FALSE; switch (PyTuple_Size(args)) { @@ -479,8 +483,9 @@ return NULL; break; case 3: - if (!PyArg_ParseTuple(args,"sil;str,n,attr", &str, &n, &attr)) + if (!PyArg_ParseTuple(args,"sil;str,n,attr", &str, &n, &lattr)) return NULL; + attr = lattr; use_attr = TRUE; break; case 4: @@ -489,8 +494,9 @@ use_xy = TRUE; break; case 5: - if (!PyArg_ParseTuple(args,"iisil;y,x,str,n,attr", &y, &x, &str, &n, &attr)) + if (!PyArg_ParseTuple(args,"iisil;y,x,str,n,attr", &y, &x, &str, &n, &lattr)) return NULL; + attr = lattr; use_xy = use_attr = TRUE; break; default: @@ -517,6 +523,7 @@ PyObject *temp; chtype bkgd; attr_t attr = A_NORMAL; + long lattr; switch (PyTuple_Size(args)) { case 1: @@ -524,8 +531,9 @@ return NULL; break; case 2: - if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &attr)) + if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &lattr)) return NULL; + attr = lattr; break; default: PyErr_SetString(PyExc_TypeError, "bkgd requires 1 or 2 arguments"); @@ -541,11 +549,39 @@ } static PyObject * +PyCursesWindow_AttrOff(PyCursesWindowObject *self, PyObject *args) +{ + long lattr; + if (!PyArg_ParseTuple(args,"l;attr", &lattr)) + return NULL; + return PyCursesCheckERR(wattroff(self->win, (attr_t)lattr), "attroff"); +} + +static PyObject * +PyCursesWindow_AttrOn(PyCursesWindowObject *self, PyObject *args) +{ + long lattr; + if (!PyArg_ParseTuple(args,"l;attr", &lattr)) + return NULL; + return PyCursesCheckERR(wattron(self->win, (attr_t)lattr), "attron"); +} + +static PyObject * +PyCursesWindow_AttrSet(PyCursesWindowObject *self, PyObject *args) +{ + long lattr; + if (!PyArg_ParseTuple(args,"l;attr", &lattr)) + return NULL; + return PyCursesCheckERR(wattrset(self->win, (attr_t)lattr), "attrset"); +} + +static PyObject * PyCursesWindow_BkgdSet(PyCursesWindowObject *self, PyObject *args) { PyObject *temp; chtype bkgd; attr_t attr = A_NORMAL; + long lattr; switch (PyTuple_Size(args)) { case 1: @@ -553,8 +589,9 @@ return NULL; break; case 2: - if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &attr)) + if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &lattr)) return NULL; + attr = lattr; break; default: PyErr_SetString(PyExc_TypeError, "bkgdset requires 1 or 2 arguments"); @@ -742,6 +779,7 @@ PyObject *temp; chtype ch; attr_t attr = A_NORMAL; + long lattr; switch (PyTuple_Size(args)) { case 1: @@ -749,8 +787,9 @@ return NULL; break; case 2: - if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &attr)) + if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &lattr)) return NULL; + attr = lattr; break; default: PyErr_SetString(PyExc_TypeError, "echochar requires 1 or 2 arguments"); @@ -916,6 +955,7 @@ chtype ch; int n, x, y, code = OK; attr_t attr = A_NORMAL; + long lattr; switch (PyTuple_Size(args)) { case 2: @@ -923,8 +963,9 @@ return NULL; break; case 3: - if (!PyArg_ParseTuple(args, "Oil;ch or int,n,attr", &temp, &n, &attr)) + if (!PyArg_ParseTuple(args, "Oil;ch or int,n,attr", &temp, &n, &lattr)) return NULL; + attr = lattr; break; case 4: if (!PyArg_ParseTuple(args, "iiOi;y,x,ch or int,n", &y, &x, &temp, &n)) @@ -933,8 +974,9 @@ break; case 5: if (!PyArg_ParseTuple(args, "iiOil; y,x,ch or int,n,attr", - &y, &x, &temp, &n, &attr)) + &y, &x, &temp, &n, &lattr)) return NULL; + attr = lattr; code = wmove(self->win, y, x); break; default: @@ -960,6 +1002,7 @@ PyObject *temp; chtype ch = 0; attr_t attr = A_NORMAL; + long lattr; switch (PyTuple_Size(args)) { case 1: @@ -967,8 +1010,9 @@ return NULL; break; case 2: - if (!PyArg_ParseTuple(args, "Ol;ch or int,attr", &temp, &attr)) + if (!PyArg_ParseTuple(args, "Ol;ch or int,attr", &temp, &lattr)) return NULL; + attr = lattr; break; case 3: if (!PyArg_ParseTuple(args,"iiO;y,x,ch or int", &y, &x, &temp)) @@ -976,8 +1020,9 @@ use_xy = TRUE; break; case 4: - if (!PyArg_ParseTuple(args,"iiOl;y,x,ch or int, attr", &y, &x, &temp, &attr)) + if (!PyArg_ParseTuple(args,"iiOl;y,x,ch or int, attr", &y, &x, &temp, &lattr)) return NULL; + attr = lattr; use_xy = TRUE; break; default: @@ -1062,6 +1107,7 @@ int x, y; char *str; attr_t attr = A_NORMAL , attr_old = A_NORMAL; + long lattr; int use_xy = FALSE, use_attr = FALSE; switch (PyTuple_Size(args)) { @@ -1070,8 +1116,9 @@ return NULL; break; case 2: - if (!PyArg_ParseTuple(args,"sl;str,attr", &str, &attr)) + if (!PyArg_ParseTuple(args,"sl;str,attr", &str, &lattr)) return NULL; + attr = lattr; use_attr = TRUE; break; case 3: @@ -1080,8 +1127,9 @@ use_xy = TRUE; break; case 4: - if (!PyArg_ParseTuple(args,"iisl;y,x,str,attr", &y, &x, &str, &attr)) + if (!PyArg_ParseTuple(args,"iisl;y,x,str,attr", &y, &x, &str, &lattr)) return NULL; + attr = lattr; use_xy = use_attr = TRUE; break; default: @@ -1108,6 +1156,7 @@ int rtn, x, y, n; char *str; attr_t attr = A_NORMAL , attr_old = A_NORMAL; + long lattr; int use_xy = FALSE, use_attr = FALSE; switch (PyTuple_Size(args)) { @@ -1116,8 +1165,9 @@ return NULL; break; case 3: - if (!PyArg_ParseTuple(args,"sil;str,n,attr", &str, &n, &attr)) + if (!PyArg_ParseTuple(args,"sil;str,n,attr", &str, &n, &lattr)) return NULL; + attr = lattr; use_attr = TRUE; break; case 4: @@ -1126,8 +1176,9 @@ use_xy = TRUE; break; case 5: - if (!PyArg_ParseTuple(args,"iisil;y,x,str,n,attr", &y, &x, &str, &n, &attr)) + if (!PyArg_ParseTuple(args,"iisil;y,x,str,n,attr", &y, &x, &str, &n, &lattr)) return NULL; + attr = lattr; use_xy = use_attr = TRUE; break; default: @@ -1470,6 +1521,7 @@ chtype ch; int n, x, y, code = OK; attr_t attr = A_NORMAL; + long lattr; switch (PyTuple_Size(args)) { case 2: @@ -1477,8 +1529,9 @@ return NULL; break; case 3: - if (!PyArg_ParseTuple(args, "Oil;ch or int,n,attr", &temp, &n, &attr)) + if (!PyArg_ParseTuple(args, "Oil;ch or int,n,attr", &temp, &n, &lattr)) return NULL; + attr = lattr; break; case 4: if (!PyArg_ParseTuple(args, "iiOi;y,x,ch or int,n", &y, &x, &temp, &n)) @@ -1487,8 +1540,9 @@ break; case 5: if (!PyArg_ParseTuple(args, "iiOil; y,x,ch or int,n,attr", - &y, &x, &temp, &n, &attr)) + &y, &x, &temp, &n, &lattr)) return NULL; + attr = lattr; code = wmove(self->win, y, x); break; default: @@ -1511,9 +1565,9 @@ {"addch", (PyCFunction)PyCursesWindow_AddCh, METH_VARARGS}, {"addnstr", (PyCFunction)PyCursesWindow_AddNStr, METH_VARARGS}, {"addstr", (PyCFunction)PyCursesWindow_AddStr, METH_VARARGS}, - {"attroff", (PyCFunction)PyCursesWindow_wattroff, METH_VARARGS}, - {"attron", (PyCFunction)PyCursesWindow_wattron, METH_VARARGS}, - {"attrset", (PyCFunction)PyCursesWindow_wattrset, METH_VARARGS}, + {"attroff", (PyCFunction)PyCursesWindow_AttrOff, METH_VARARGS}, + {"attron", (PyCFunction)PyCursesWindow_AttrOn, METH_VARARGS}, + {"attrset", (PyCFunction)PyCursesWindow_AttrSet, METH_VARARGS}, {"bkgd", (PyCFunction)PyCursesWindow_Bkgd, METH_VARARGS}, {"chgat", (PyCFunction)PyCursesWindow_ChgAt, METH_VARARGS}, {"bkgdset", (PyCFunction)PyCursesWindow_BkgdSet, METH_VARARGS}, Modified: python/branches/py3k/Modules/_sre.c ============================================================================== --- python/branches/py3k/Modules/_sre.c (original) +++ python/branches/py3k/Modules/_sre.c Wed Jan 9 01:17:24 2008 @@ -95,6 +95,7 @@ #define SRE_ERROR_STATE -2 /* illegal state */ #define SRE_ERROR_RECURSION_LIMIT -3 /* runaway recursion */ #define SRE_ERROR_MEMORY -9 /* out of memory */ +#define SRE_ERROR_INTERRUPTED -10 /* signal handler raised exception */ #if defined(VERBOSE) #define TRACE(v) printf v @@ -805,6 +806,7 @@ Py_ssize_t alloc_pos, ctx_pos = -1; Py_ssize_t i, ret = 0; Py_ssize_t jump; + unsigned int sigcount=0; SRE_MATCH_CONTEXT* ctx; SRE_MATCH_CONTEXT* nextctx; @@ -833,6 +835,9 @@ } for (;;) { + ++sigcount; + if ((0 == (sigcount & 0xfff)) && PyErr_CheckSignals()) + RETURN_ERROR(SRE_ERROR_INTERRUPTED); switch (*ctx->pattern++) { @@ -1833,6 +1838,9 @@ case SRE_ERROR_MEMORY: PyErr_NoMemory(); break; + case SRE_ERROR_INTERRUPTED: + /* An exception has already been raised, so let it fly */ + break; default: /* other error codes indicate compiler/engine bugs */ PyErr_SetString( Modified: python/branches/py3k/Modules/pyexpat.c ============================================================================== --- python/branches/py3k/Modules/pyexpat.c (original) +++ python/branches/py3k/Modules/pyexpat.c Wed Jan 9 01:17:24 2008 @@ -1524,6 +1524,50 @@ self->specified_attributes = 0; return 0; } + + if (strcmp(name, "buffer_size") == 0) { + long new_buffer_size; + if (!PyLong_Check(v)) { + PyErr_SetString(PyExc_TypeError, "buffer_size must be an integer"); + return -1; + } + + new_buffer_size=PyLong_AS_LONG(v); + /* trivial case -- no change */ + if (new_buffer_size == self->buffer_size) { + return 0; + } + + if (new_buffer_size <= 0) { + PyErr_SetString(PyExc_ValueError, "buffer_size must be greater than zero"); + return -1; + } + + /* check maximum */ + if (new_buffer_size > INT_MAX) { + char errmsg[100]; + sprintf(errmsg, "buffer_size must not be greater than %i", INT_MAX); + PyErr_SetString(PyExc_ValueError, errmsg); + return -1; + } + + if (self->buffer != NULL) { + /* there is already a buffer */ + if (self->buffer_used != 0) { + flush_character_buffer(self); + } + /* free existing buffer */ + free(self->buffer); + } + self->buffer = malloc(new_buffer_size); + if (self->buffer == NULL) { + PyErr_NoMemory(); + return -1; + } + self->buffer_size = new_buffer_size; + return 0; + } + if (strcmp(name, "CharacterDataHandler") == 0) { /* If we're changing the character data handler, flush all * cached data with the old handler. Not sure there's a Modified: python/branches/py3k/PC/_winreg.c ============================================================================== --- python/branches/py3k/PC/_winreg.c (original) +++ python/branches/py3k/PC/_winreg.c Wed Jan 9 01:17:24 2008 @@ -46,6 +46,7 @@ "DeleteValue() - Removes a named value from the specified registry key.\n" "EnumKey() - Enumerates subkeys of the specified open registry key.\n" "EnumValue() - Enumerates values of the specified open registry key.\n" +"ExpandEnvironmentStrings() - Expand the env strings in a REG_EXPAND_SZ string.\n" "FlushKey() - Writes all the attributes of the specified key to the registry.\n" "LoadKey() - Creates a subkey under HKEY_USER or HKEY_LOCAL_MACHINE and stores\n" " registration information from a specified file into that subkey.\n" @@ -145,6 +146,9 @@ " on the underlying registry type.\n" "data_type is an integer that identifies the type of the value data."); +PyDoc_STRVAR(ExpandEnvironmentStrings_doc, +"string = ExpandEnvironmentStrings(string) - Expand environment vars.\n"); + PyDoc_STRVAR(FlushKey_doc, "FlushKey(key) - Writes all the attributes of a key to the registry.\n" "\n" @@ -503,9 +507,27 @@ return PyLong_FromVoidPtr(ret); } +static PyObject * +PyHKEY_Enter(PyObject *self) +{ + Py_XINCREF(self); + return self; +} + +static PyObject * +PyHKEY_Exit(PyObject *self, PyObject *args) +{ + if (!PyHKEY_Close(self)) + return NULL; + Py_RETURN_NONE; +} + + static struct PyMethodDef PyHKEY_methods[] = { {"Close", PyHKEY_CloseMethod, METH_VARARGS, PyHKEY_Close_doc}, {"Detach", PyHKEY_DetachMethod, METH_VARARGS, PyHKEY_Detach_doc}, + {"__enter__", (PyCFunction)PyHKEY_Enter, METH_NOARGS, NULL}, + {"__exit__", PyHKEY_Exit, METH_VARARGS, NULL}, {NULL} }; @@ -1062,6 +1084,39 @@ } static PyObject * +PyExpandEnvironmentStrings(PyObject *self, PyObject *args) +{ + Py_UNICODE *retValue = NULL; + Py_UNICODE *src; + DWORD retValueSize; + DWORD rc; + PyObject *o; + + if (!PyArg_ParseTuple(args, "u:ExpandEnvironmentStrings", &src)) + return NULL; + + retValueSize = ExpandEnvironmentStringsW(src, retValue, 0); + if (retValueSize == 0) { + return PyErr_SetFromWindowsErrWithFunction(retValueSize, + "ExpandEnvironmentStrings"); + } + retValue = (Py_UNICODE *)PyMem_Malloc(retValueSize * sizeof(Py_UNICODE)); + if (retValue == NULL) { + return PyErr_NoMemory(); + } + + rc = ExpandEnvironmentStringsW(src, retValue, retValueSize); + if (rc == 0) { + PyMem_Free(retValue); + return PyErr_SetFromWindowsErrWithFunction(retValueSize, + "ExpandEnvironmentStrings"); + } + o = PyUnicode_FromUnicode(retValue, wcslen(retValue)); + PyMem_Free(retValue); + return o; +} + +static PyObject * PyFlushKey(PyObject *self, PyObject *args) { HKEY hKey; @@ -1346,6 +1401,8 @@ {"DeleteValue", PyDeleteValue, METH_VARARGS, DeleteValue_doc}, {"EnumKey", PyEnumKey, METH_VARARGS, EnumKey_doc}, {"EnumValue", PyEnumValue, METH_VARARGS, EnumValue_doc}, + {"ExpandEnvironmentStrings", PyExpandEnvironmentStrings, METH_VARARGS, + ExpandEnvironmentStrings_doc }, {"FlushKey", PyFlushKey, METH_VARARGS, FlushKey_doc}, {"LoadKey", PyLoadKey, METH_VARARGS, LoadKey_doc}, {"OpenKey", PyOpenKey, METH_VARARGS, OpenKey_doc}, From python-3000-checkins at python.org Thu Jan 10 01:10:03 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Thu, 10 Jan 2008 01:10:03 +0100 (CET) Subject: [Python-3000-checkins] r59883 - in python/branches/py3k: Doc/library/collections.rst Lib/test/test_import.py Modules/_cursesmodule.c PC/VS8.0/_ctypes.vcproj PCbuild/_ctypes.vcproj Python/import.c Tools/buildbot/build-amd64.bat Tools/buildbot/clean-amd64.bat Tools/buildbot/external-amd64.bat Message-ID: <20080110001003.1A1A11E400E@bag.python.org> Author: christian.heimes Date: Thu Jan 10 01:10:02 2008 New Revision: 59883 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/collections.rst python/branches/py3k/Lib/test/test_import.py python/branches/py3k/Modules/_cursesmodule.c python/branches/py3k/PC/VS8.0/_ctypes.vcproj python/branches/py3k/PCbuild/_ctypes.vcproj python/branches/py3k/Python/import.c python/branches/py3k/Tools/buildbot/build-amd64.bat python/branches/py3k/Tools/buildbot/clean-amd64.bat python/branches/py3k/Tools/buildbot/external-amd64.bat Log: Merged revisions 59864-59882 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r59866 | raymond.hettinger | 2008-01-09 04:02:23 +0100 (Wed, 09 Jan 2008) | 1 line Syntax highlighting only works when >>> lines are accompanied by ... lines ........ r59867 | fred.drake | 2008-01-09 04:11:28 +0100 (Wed, 09 Jan 2008) | 2 lines minor cleaning ........ r59868 | raymond.hettinger | 2008-01-09 04:13:20 +0100 (Wed, 09 Jan 2008) | 1 line Fix typo ........ r59869 | thomas.heller | 2008-01-09 12:19:19 +0100 (Wed, 09 Jan 2008) | 1 line Set the output file in the _ctypes Debug|x64 configuration. ........ r59870 | andrew.kuchling | 2008-01-09 13:27:41 +0100 (Wed, 09 Jan 2008) | 1 line Related to patch #1114: fix another place where attr_t is assumed to be a long ........ r59873 | christian.heimes | 2008-01-09 15:46:10 +0100 (Wed, 09 Jan 2008) | 1 line vs9to8 sync ........ r59876 | christian.heimes | 2008-01-09 20:56:33 +0100 (Wed, 09 Jan 2008) | 1 line Fixed #1776. __import__() no longer imports modules by file name ........ r59879 | thomas.heller | 2008-01-09 22:35:04 +0100 (Wed, 09 Jan 2008) | 6 lines Change amd64 buildbot scripts to use Visual Studio 2008, and to use the required versions of external sources. External sources are not yet built, so the build-step fails to built some targets. ........ r59880 | thomas.heller | 2008-01-09 22:35:43 +0100 (Wed, 09 Jan 2008) | 6 lines Change amd64 buildbot scripts to use Visual Studio 2008, and to use the required versions of external sources. External sources are not yet built, so the build-step fails to built some targets. ........ Modified: python/branches/py3k/Doc/library/collections.rst ============================================================================== --- python/branches/py3k/Doc/library/collections.rst (original) +++ python/branches/py3k/Doc/library/collections.rst Thu Jan 10 01:10:02 2008 @@ -510,7 +510,7 @@ Point(x=33, y=22) >>> for partnum, record in inventory.items(): - inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now()) + ... inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now()) .. attribute:: somenamedtuple._fields @@ -525,7 +525,7 @@ >>> Color = namedtuple('Color', 'red green blue') >>> Pixel = namedtuple('Pixel', Point._fields + Color._fields) >>> Pixel(11, 22, 128, 255, 0) - Pixel(x=11, y=22, red=128, green=255, blue=0)' + Pixel(x=11, y=22, red=128, green=255, blue=0) To retrieve a field whose name is stored in a string, use the :func:`getattr` function:: @@ -544,14 +544,14 @@ a fixed-width print format:: >>> class Point(namedtuple('Point', 'x y')): - @property - def hypot(self): - return (self.x ** 2 + self.y ** 2) ** 0.5 - def __str__(self): - return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) + ... @property + ... def hypot(self): + ... return (self.x ** 2 + self.y ** 2) ** 0.5 + ... def __str__(self): + ... return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) >>> for p in Point(3,4), Point(14,5), Point(9./7,6): - print p + ... print p Point: x= 3.000 y= 4.000 hypot= 5.000 Point: x=14.000 y= 5.000 hypot=14.866 @@ -560,7 +560,7 @@ Another use for subclassing is to replace performance critcal methods with faster versions that bypass error-checking and that localize variable access:: - >>> class Point(namedtuple('Point', 'x y')): + class Point(namedtuple('Point', 'x y')): _make = classmethod(tuple.__new__) def _replace(self, _map=map, **kwds): return self._make(_map(kwds.get, ('x', 'y'), self)) Modified: python/branches/py3k/Lib/test/test_import.py ============================================================================== --- python/branches/py3k/Lib/test/test_import.py (original) +++ python/branches/py3k/Lib/test/test_import.py Thu Jan 10 01:10:02 2008 @@ -221,6 +221,16 @@ del sys.modules[TESTFN] + def test_importbyfilename(self): + path = os.path.abspath(TESTFN) + try: + __import__(path) + except ImportError as err: + self.assertEqual("Import by filename is not supported.", + err.args[0]) + else: + self.fail("import by path didn't raise an exception") + class PathsTests(unittest.TestCase): SAMPLES = ('test', 'test\u00e4\u00f6\u00fc\u00df', 'test\u00e9\u00e8', 'test\u00b0\u00b3\u00b2') Modified: python/branches/py3k/Modules/_cursesmodule.c ============================================================================== --- python/branches/py3k/Modules/_cursesmodule.c (original) +++ python/branches/py3k/Modules/_cursesmodule.c Thu Jan 10 01:10:02 2008 @@ -677,25 +677,30 @@ int num = -1; short color; attr_t attr = A_NORMAL; + long lattr; int use_xy = FALSE; switch (PyTuple_Size(args)) { case 1: - if (!PyArg_ParseTuple(args,"l;attr", &attr)) + if (!PyArg_ParseTuple(args,"l;attr", &lattr)) return NULL; + attr = lattr; break; case 2: - if (!PyArg_ParseTuple(args,"il;n,attr", &num, &attr)) + if (!PyArg_ParseTuple(args,"il;n,attr", &num, &lattr)) return NULL; + attr = lattr; break; case 3: - if (!PyArg_ParseTuple(args,"iil;int,int,attr", &y, &x, &attr)) + if (!PyArg_ParseTuple(args,"iil;int,int,attr", &y, &x, &lattr)) return NULL; + attr = lattr; use_xy = TRUE; break; case 4: - if (!PyArg_ParseTuple(args,"iiil;int,int,n,attr", &y, &x, &num, &attr)) + if (!PyArg_ParseTuple(args,"iiil;int,int,n,attr", &y, &x, &num, &lattr)) return NULL; + attr = lattr; use_xy = TRUE; break; default: Modified: python/branches/py3k/PC/VS8.0/_ctypes.vcproj ============================================================================== --- python/branches/py3k/PC/VS8.0/_ctypes.vcproj (original) +++ python/branches/py3k/PC/VS8.0/_ctypes.vcproj Thu Jan 10 01:10:02 2008 @@ -643,6 +643,7 @@ Author: christian.heimes Date: Thu Jan 10 01:51:10 2008 New Revision: 59884 Added: python/branches/py3k-importhook/ - copied from r59883, python/branches/py3k/ Log: Creating branch for my post import hook PEP From python-3000-checkins at python.org Thu Jan 10 01:52:56 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Thu, 10 Jan 2008 01:52:56 +0100 (CET) Subject: [Python-3000-checkins] r59885 - python/branches/py3k-importhook Message-ID: <20080110005256.802431E4010@bag.python.org> Author: christian.heimes Date: Thu Jan 10 01:52:56 2008 New Revision: 59885 Modified: python/branches/py3k-importhook/ (props changed) Log: svnmerge.py init From python-3000-checkins at python.org Thu Jan 10 02:49:44 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Thu, 10 Jan 2008 02:49:44 +0100 (CET) Subject: [Python-3000-checkins] r59886 - in python/branches/py3k-importhook: Include/import.h Lib/test/test_imp.py Python/import.c Message-ID: <20080110014944.83E761E400E@bag.python.org> Author: christian.heimes Date: Thu Jan 10 02:49:44 2008 New Revision: 59886 Modified: python/branches/py3k-importhook/Include/import.h python/branches/py3k-importhook/Lib/test/test_imp.py python/branches/py3k-importhook/Python/import.c Log: Post import hook implementation This implementation has been cleaned up a bit. Modified: python/branches/py3k-importhook/Include/import.h ============================================================================== --- python/branches/py3k-importhook/Include/import.h (original) +++ python/branches/py3k-importhook/Include/import.h Thu Jan 10 02:49:44 2008 @@ -35,6 +35,12 @@ PyAPI_FUNC(PyObject *)_PyImport_FindExtension(char *, char *); PyAPI_FUNC(PyObject *)_PyImport_FixupExtension(char *, char *); +/* post import hook API */ +PyAPI_FUNC(PyObject *) PyImport_GetPostImportHooks(void); +PyAPI_FUNC(PyObject *) PyImport_NotifyModuleLoaded(PyObject *module); +PyAPI_FUNC(PyObject *) PyImport_RegisterPostImportHook( + PyObject *callable, PyObject *mod_name); + struct _inittab { char *name; void (*initfunc)(void); Modified: python/branches/py3k-importhook/Lib/test/test_imp.py ============================================================================== --- python/branches/py3k-importhook/Lib/test/test_imp.py (original) +++ python/branches/py3k-importhook/Lib/test/test_imp.py Thu Jan 10 02:49:44 2008 @@ -1,4 +1,5 @@ import imp +import sys import thread import unittest from test import test_support @@ -68,12 +69,79 @@ ## import sys ## self.assertRaises(ImportError, reload, sys) +class CallBack: + def __init__(self): + self.mods = {} + + def __call__(self, mod): + self.mods[mod.__name__] = mod + +class PostImportHookTests(unittest.TestCase): + + def setUp(self): + if "telnetlib" in sys.modules: + del sys.modules["telnetlib"] + self.pihr = sys.post_import_hooks.copy() + + def tearDown(self): + if "telnetlib" in sys.modules: + del sys.modules["telnetlib"] + sys.post_import_hooks = self.pihr + + def test_registry(self): + reg = sys.post_import_hooks + self.assert_(isinstance(reg, dict)) + + def test_invalid_registry(self): + sys.post_import_hooks = [] + self.assertRaises(TypeError, imp.register_post_import_hook, + lambda mod: None, "sys") + sys.post_import_hooks = {} + imp.register_post_import_hook(lambda mod: None, "sys") + + sys.post_import_hooks["telnetlib"] = lambda mod: None + self.assertRaises(TypeError, __import__, "telnetlib") + sys.post_import_hooks = self.pihr + + def test_register_callback_existing(self): + callback = CallBack() + imp.register_post_import_hook(callback, "sys") + + # sys is already loaded and the callback is fired immediately + self.assert_("sys" in callback.mods, callback.mods) + self.assert_(callback.mods["sys"] is sys, callback.mods) + self.failIf("telnetlib" in callback.mods, callback.mods) + regc = sys.post_import_hooks.get("sys", False) + self.assert_(regc is False, regc) + + def test_register_callback_new(self): + callback = CallBack() + # an arbitrary module + if "telnetlib" in sys.modules: + del sys.modules["telnetlib"] + imp.register_post_import_hook(callback, "telnetlib") + + regc = sys.post_import_hooks.get("telnetlib") + self.assert_(regc is not None, regc) + self.assert_(isinstance(regc, list), regc) + self.assert_(callback in regc, regc) + + import telnetlib + self.assert_("telnetlib" in callback.mods, callback.mods) + self.assert_(callback.mods["telnetlib"] is telnetlib, callback.mods) + + def test_post_import_notify(self): + imp.notify_module_loaded(sys) + self.failUnlessRaises(TypeError, imp.notify_module_loaded, None) + self.failUnlessRaises(TypeError, imp.notify_module_loaded, object()) + def test_main(): test_support.run_unittest( - LockTests, - ImportTests, - ) + LockTests, + ImportTests, + PostImportHookTests, + ) if __name__ == "__main__": test_main() Modified: python/branches/py3k-importhook/Python/import.c ============================================================================== --- python/branches/py3k-importhook/Python/import.c (original) +++ python/branches/py3k-importhook/Python/import.c Thu Jan 10 02:49:44 2008 @@ -163,7 +163,7 @@ void _PyImportHooks_Init(void) { - PyObject *v, *path_hooks = NULL, *zimpimport; + PyObject *v, *path_hooks = NULL, *zimpimport, *pihr; int err = 0; /* adding sys.path_hooks and sys.path_importer_cache, setting up @@ -200,6 +200,14 @@ ); } + pihr = PyDict_New(); + if (pihr == NULL || + PySys_SetObject("post_import_hooks", pihr) != 0) { + PyErr_Print(); + Py_FatalError("initialization of post import hook registry " + "failed"); + } + zimpimport = PyImport_ImportModule("zipimport"); if (zimpimport == NULL) { PyErr_Clear(); /* No zip import module -- okay */ @@ -371,6 +379,7 @@ "path", "argv", "ps1", "ps2", "last_type", "last_value", "last_traceback", "path_hooks", "path_importer_cache", "meta_path", + "post_import_hooks", NULL }; @@ -625,6 +634,214 @@ "sys.modules failed"); } +/* post import hook API */ +PyObject * +PyImport_GetPostImportHooks(void) +{ + PyObject *pihr; + + pihr = PySys_GetObject("post_import_hooks"); + /* This should only happen during initialization */ + if (pihr == NULL) { + PyErr_Clear(); + return NULL; + } + + if (!PyDict_Check(pihr)) { + PyErr_SetString(PyExc_TypeError, + "post import registry is not a dict"); + return NULL; + } + return pihr; +} + +PyObject * +PyImport_NotifyModuleLoaded(PyObject *module) +{ + static PyObject *name = NULL; + PyObject *mod_name = NULL, *registry = NULL, *o; + PyObject *hooks = NULL, *hook, *it = NULL; + int status = -1; + + if (name == NULL) { + name = PyUnicode_InternFromString("__name__"); + if (name == NULL) { + return NULL; + } + } + + if (module == NULL) { + return NULL; + } + + /* Should I allow all kinds of objects ? */ + if (!PyModule_Check(module)) { + PyErr_Format(PyExc_TypeError, + "A module object was expected, got '%.200s'", + Py_TYPE(module)->tp_name); + goto error; + } + + /* XXX check if module is in sys.modules ? */ + registry = PyImport_GetPostImportHooks(); + if (registry == NULL) { + /* warn about invalid registry? */ + PyErr_Clear(); + return module; + } + + mod_name = PyObject_GetAttr(module, name); + if (mod_name == NULL) { + goto error; + } + if (!PyUnicode_Check(mod_name)) { + PyObject *repr; + char *name; + + repr = PyObject_Repr(module); + name = repr ? PyUnicode_AsString(repr) : ""; + PyErr_Format(PyExc_TypeError, + "Module __name__ attribute of '%.200s' is not " + "string", name); + Py_XDECREF(repr); + goto error; + } + + hooks = PyDict_GetItem(registry, mod_name); + if (hooks == NULL) { + /* Either no hooks are defined or they are already fired */ + PyErr_Clear(); + goto end; + } + if (!PyList_Check(hooks)) { + PyErr_Format(PyExc_TypeError, + "expected None or list of hooks, got '%.200s'", + Py_TYPE(hooks)->tp_name); + goto error; + } + + /* fire hooks */ + it = PyObject_GetIter(hooks); + if (it == NULL) { + goto error; + } + while ((hook = PyIter_Next(it)) != NULL) { + o = PyObject_CallFunctionObjArgs(hook, module, NULL); + Py_DECREF(hook); + if (o == NULL) { + goto error; + } + Py_DECREF(o); + } + + /* Mark hooks as fired */ + if (PyDict_DelItem(registry, mod_name) < 0) { + goto error; + } + + end: + status = 0; + error: + Py_XDECREF(mod_name); + Py_XDECREF(it); + if (status < 0) { + Py_XDECREF(module); + return NULL; + } + else { + return module; + } +} + +PyObject * +PyImport_RegisterPostImportHook(PyObject *callable, PyObject *mod_name) +{ + PyObject *registry = NULL, *hooks = NULL; + int status = -1, locked = 0; + + if (!PyCallable_Check(callable)) { + PyErr_SetString(PyExc_TypeError, "expected callable"); + goto error; + } + if (!PyUnicode_Check(mod_name)) { + PyErr_SetString(PyExc_TypeError, "expected string"); + goto error; + } + + registry = PyImport_GetPostImportHooks(); + if (registry == NULL) { + goto error; + } + + lock_import(); + locked = 1; + + hooks = PyDict_GetItem(registry, mod_name); + /* module may be already loaded, get the module object from sys */ + if (hooks == NULL) { + PyObject *o, *modules; + PyObject *module = NULL; + + modules = PyImport_GetModuleDict(); + if (modules == NULL) { + goto error; + } + module = PyDict_GetItem(modules, mod_name); + if (module != NULL) { + /* module is already loaded, fire hook immediately */ + o = PyObject_CallFunctionObjArgs(callable, module, NULL); + if (o == NULL) { + goto error; + } + Py_DECREF(o); + goto end; + } + } + /* no hook registered so far */ + if (hooks == NULL) { + PyErr_Clear(); + hooks = PyList_New(0); + if (hooks == NULL) { + goto error; + } + if (PyDict_SetItem(registry, mod_name, hooks) < 0) { + goto error; + } + } + else { + if (!PyList_Check(hooks)) { + PyErr_Format(PyExc_TypeError, + "expected list of hooks, got '%.200s'", + Py_TYPE(hooks)->tp_name); + goto error; + } + } + /* append a new callable */ + if (PyList_Append(hooks, callable) < 0) { + goto error; + } + + end: + status = 0; + error: + Py_XDECREF(callable); + Py_XDECREF(hooks); + Py_XDECREF(mod_name); + if (locked) { + if (unlock_import() < 0) { + PyErr_SetString(PyExc_RuntimeError, + "not holding the import lock"); + return NULL; + } + } + if (status < 0) { + return NULL; + } + else { + Py_RETURN_NONE; + } +} + static PyObject * get_sourcefile(const char *file); /* Execute a code object in a module and return the module object @@ -2066,6 +2283,7 @@ PyObject *result; lock_import(); result = import_module_level(name, globals, locals, fromlist, level); + result = PyImport_NotifyModuleLoaded(result); if (unlock_import() < 0) { Py_XDECREF(result); PyErr_SetString(PyExc_RuntimeError, @@ -2979,6 +3197,31 @@ } static PyObject * +imp_register_post_import_hook(PyObject *self, PyObject *args) +{ + PyObject *callable, *mod_name; + + if (!PyArg_ParseTuple(args, "OO:register_post_import_hook", + &callable, &mod_name)) + return NULL; + Py_INCREF(callable); + Py_INCREF(mod_name); + return PyImport_RegisterPostImportHook(callable, mod_name); +} + +static PyObject * +imp_notify_module_loaded(PyObject *self, PyObject *args) +{ + PyObject *mod; + + if (!PyArg_ParseTuple(args, "O:notify_module_loaded", &mod)) + return NULL; + + Py_INCREF(mod); + return PyImport_NotifyModuleLoaded(mod); +} + +static PyObject * imp_reload(PyObject *self, PyObject *v) { return PyImport_ReloadModule(v); @@ -3038,6 +3281,13 @@ Release the interpreter's import lock.\n\ On platforms without threads, this function does nothing."); +PyDoc_STRVAR(doc_register_post_import_hook, +"register_post_import_hook(callable, module_name) -> None"); + +PyDoc_STRVAR(doc_notify_module_loaded, +"notify_module_loaded(module) -> module"); + + static PyMethodDef imp_methods[] = { {"find_module", imp_find_module, METH_VARARGS, doc_find_module}, {"get_magic", imp_get_magic, METH_NOARGS, doc_get_magic}, @@ -3047,6 +3297,10 @@ {"lock_held", imp_lock_held, METH_NOARGS, doc_lock_held}, {"acquire_lock", imp_acquire_lock, METH_NOARGS, doc_acquire_lock}, {"release_lock", imp_release_lock, METH_NOARGS, doc_release_lock}, + {"register_post_import_hook", imp_register_post_import_hook, + METH_VARARGS, doc_register_post_import_hook}, + {"notify_module_loaded", imp_notify_module_loaded, METH_VARARGS, + doc_notify_module_loaded}, {"reload", imp_reload, METH_O, doc_reload}, /* The rest are obsolete */ {"get_frozen_object", imp_get_frozen_object, METH_VARARGS}, From nnorwitz at gmail.com Thu Jan 10 08:05:51 2008 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 9 Jan 2008 23:05:51 -0800 Subject: [Python-3000-checkins] r59883 - in python/branches/py3k: Doc/library/collections.rst Lib/test/test_import.py Modules/_cursesmodule.c PC/VS8.0/_ctypes.vcproj PCbuild/_ctypes.vcproj Python/import.c Tools/buildbot/build-amd64.bat Tools/buildbot/clea Message-ID: On Jan 9, 2008 4:10 PM, christian.heimes wrote: > Author: christian.heimes > Date: Thu Jan 10 01:10:02 2008 > New Revision: 59883 > > Log: > Merged revisions 59864-59882 via svnmerge from > svn+ssh://pythondev at svn.python.org/python/trunk > > ........ > --- python/branches/py3k/Doc/library/collections.rst (original) > +++ python/branches/py3k/Doc/library/collections.rst Thu Jan 10 01:10:02 2008 > @@ -510,7 +510,7 @@ > Point(x=33, y=22) > > >>> for partnum, record in inventory.items(): > - inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now()) > + ... inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now()) > > .. attribute:: somenamedtuple._fields > > @@ -525,7 +525,7 @@ > >>> Color = namedtuple('Color', 'red green blue') > >>> Pixel = namedtuple('Pixel', Point._fields + Color._fields) > >>> Pixel(11, 22, 128, 255, 0) > - Pixel(x=11, y=22, red=128, green=255, blue=0)' > + Pixel(x=11, y=22, red=128, green=255, blue=0) > > To retrieve a field whose name is stored in a string, use the :func:`getattr` > function:: > @@ -544,14 +544,14 @@ > a fixed-width print format:: > > >>> class Point(namedtuple('Point', 'x y')): > - @property > - def hypot(self): > - return (self.x ** 2 + self.y ** 2) ** 0.5 > - def __str__(self): > - return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) > + ... @property > + ... def hypot(self): > + ... return (self.x ** 2 + self.y ** 2) ** 0.5 > + ... def __str__(self): > + ... return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) > > >>> for p in Point(3,4), Point(14,5), Point(9./7,6): > - print p > + ... print p This print should be fixed so it works in 3k. n From python-3000-checkins at python.org Thu Jan 10 17:02:19 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Thu, 10 Jan 2008 17:02:19 +0100 (CET) Subject: [Python-3000-checkins] r59889 - python/branches/py3k/Doc/library/collections.rst Message-ID: <20080110160219.8982A1E4019@bag.python.org> Author: christian.heimes Date: Thu Jan 10 17:02:19 2008 New Revision: 59889 Modified: python/branches/py3k/Doc/library/collections.rst Log: Fixed print -> print() Modified: python/branches/py3k/Doc/library/collections.rst ============================================================================== --- python/branches/py3k/Doc/library/collections.rst (original) +++ python/branches/py3k/Doc/library/collections.rst Thu Jan 10 17:02:19 2008 @@ -474,7 +474,7 @@ cursor = conn.cursor() cursor.execute('SELECT name, age, title, department, paygrade FROM employees') for emp in map(EmployeeRecord._make, cursor.fetchall()): - print emp.name, emp.title + print(emp.name, emp.title) In addition to the methods inherited from tuples, named tuples support three additional methods and one attribute. To prevent conflicts with @@ -551,7 +551,7 @@ ... return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) >>> for p in Point(3,4), Point(14,5), Point(9./7,6): - ... print p + ... print(p) Point: x= 3.000 y= 4.000 hypot= 5.000 Point: x=14.000 y= 5.000 hypot=14.866 From lists at cheimes.de Thu Jan 10 17:05:15 2008 From: lists at cheimes.de (Christian Heimes) Date: Thu, 10 Jan 2008 17:05:15 +0100 Subject: [Python-3000-checkins] r59883 - in python/branches/py3k: Doc/library/collections.rst Lib/test/test_import.py Modules/_cursesmodule.c PC/VS8.0/_ctypes.vcproj PCbuild/_ctypes.vcproj Python/import.c Tools/buildbot/build-amd64.bat Tools/buildbot/clea In-Reply-To: References: Message-ID: <4786423B.1060404@cheimes.de> Neal Norwitz wrote: > This print should be fixed so it works in 3k. The py3k docs probably contain more print statements. Raymond, can you turn the docs into doc tests? Christian From python-3000-checkins at python.org Thu Jan 10 18:39:27 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Thu, 10 Jan 2008 18:39:27 +0100 (CET) Subject: [Python-3000-checkins] r59890 - in python/branches/py3k-importhook: Lib/test/test_imp.py Python/import.c Message-ID: <20080110173927.CD4F41E4010@bag.python.org> Author: christian.heimes Date: Thu Jan 10 18:39:27 2008 New Revision: 59890 Modified: python/branches/py3k-importhook/Lib/test/test_imp.py python/branches/py3k-importhook/Python/import.c Log: sys.post_import_hooks[name] is set to None during and after the callbacks are called (as proposed by PJE) imp_notify_module_loaded() is protected by the importer lock Modified: python/branches/py3k-importhook/Lib/test/test_imp.py ============================================================================== --- python/branches/py3k-importhook/Lib/test/test_imp.py (original) +++ python/branches/py3k-importhook/Lib/test/test_imp.py Thu Jan 10 18:39:27 2008 @@ -111,8 +111,7 @@ self.assert_("sys" in callback.mods, callback.mods) self.assert_(callback.mods["sys"] is sys, callback.mods) self.failIf("telnetlib" in callback.mods, callback.mods) - regc = sys.post_import_hooks.get("sys", False) - self.assert_(regc is False, regc) + self.assertEqual(sys.post_import_hooks["sys"], None) def test_register_callback_new(self): callback = CallBack() @@ -129,11 +128,15 @@ import telnetlib self.assert_("telnetlib" in callback.mods, callback.mods) self.assert_(callback.mods["telnetlib"] is telnetlib, callback.mods) + self.assertEqual(sys.post_import_hooks["telnetlib"], None) def test_post_import_notify(self): imp.notify_module_loaded(sys) self.failUnlessRaises(TypeError, imp.notify_module_loaded, None) self.failUnlessRaises(TypeError, imp.notify_module_loaded, object()) + # Should this fail? + mod = imp.new_module("post_import_test_module") + imp.notify_module_loaded(mod) def test_main(): Modified: python/branches/py3k-importhook/Python/import.c ============================================================================== --- python/branches/py3k-importhook/Python/import.c (original) +++ python/branches/py3k-importhook/Python/import.c Thu Jan 10 18:39:27 2008 @@ -655,6 +655,9 @@ return pihr; } +/* Notify that a module as been loaded + * Must be called with the import hook acquired + */ PyObject * PyImport_NotifyModuleLoaded(PyObject *module) { @@ -673,8 +676,7 @@ if (module == NULL) { return NULL; } - - /* Should I allow all kinds of objects ? */ + /* Should I allow all kinds of objects? */ if (!PyModule_Check(module)) { PyErr_Format(PyExc_TypeError, "A module object was expected, got '%.200s'", @@ -683,15 +685,12 @@ } /* XXX check if module is in sys.modules ? */ - registry = PyImport_GetPostImportHooks(); - if (registry == NULL) { + if ((registry = PyImport_GetPostImportHooks()) == NULL) { /* warn about invalid registry? */ PyErr_Clear(); return module; } - - mod_name = PyObject_GetAttr(module, name); - if (mod_name == NULL) { + if ((mod_name = PyObject_GetAttr(module, name)) == NULL) { goto error; } if (!PyUnicode_Check(mod_name)) { @@ -707,12 +706,15 @@ goto error; } - hooks = PyDict_GetItem(registry, mod_name); - if (hooks == NULL) { + if ((hooks = PyDict_GetItem(registry, mod_name)) == NULL) { /* Either no hooks are defined or they are already fired */ PyErr_Clear(); goto end; } + Py_INCREF(hooks); + if (PyDict_SetItem(registry, mod_name, Py_None) < 0) { + goto end; + } if (!PyList_Check(hooks)) { PyErr_Format(PyExc_TypeError, "expected None or list of hooks, got '%.200s'", @@ -721,8 +723,7 @@ } /* fire hooks */ - it = PyObject_GetIter(hooks); - if (it == NULL) { + if ((it = PyObject_GetIter(hooks)) == NULL) { goto error; } while ((hook = PyIter_Next(it)) != NULL) { @@ -734,16 +735,12 @@ Py_DECREF(o); } - /* Mark hooks as fired */ - if (PyDict_DelItem(registry, mod_name) < 0) { - goto error; - } - end: status = 0; error: Py_XDECREF(mod_name); Py_XDECREF(it); + Py_XDECREF(hooks); if (status < 0) { Py_XDECREF(module); return NULL; @@ -753,10 +750,13 @@ } } +/* register a new hook for a module + PyImport_RegisterPostImportHook acquires the global import look + */ PyObject * PyImport_RegisterPostImportHook(PyObject *callable, PyObject *mod_name) { - PyObject *registry = NULL, *hooks = NULL; + PyObject *registry = NULL, *hooks = NULL, *modules; int status = -1, locked = 0; if (!PyCallable_Check(callable)) { @@ -769,7 +769,8 @@ } registry = PyImport_GetPostImportHooks(); - if (registry == NULL) { + modules = PyImport_GetModuleDict(); + if (registry == NULL || modules == NULL) { goto error; } @@ -778,43 +779,43 @@ hooks = PyDict_GetItem(registry, mod_name); /* module may be already loaded, get the module object from sys */ - if (hooks == NULL) { - PyObject *o, *modules; + if (hooks == NULL || hooks == Py_None) { PyObject *module = NULL; - modules = PyImport_GetModuleDict(); - if (modules == NULL) { - goto error; - } - module = PyDict_GetItem(modules, mod_name); - if (module != NULL) { + if ((module = PyDict_GetItem(modules, mod_name)) != NULL) { /* module is already loaded, fire hook immediately */ + PyObject *o; + o = PyObject_CallFunctionObjArgs(callable, module, NULL); + Py_XDECREF(o); + if (hooks == NULL) { + if (PyDict_SetItem(registry, mod_name, Py_None) < 0) { + goto error; + } + } if (o == NULL) { goto error; } - Py_DECREF(o); goto end; } - } - /* no hook registered so far */ - if (hooks == NULL) { - PyErr_Clear(); - hooks = PyList_New(0); - if (hooks == NULL) { - goto error; - } - if (PyDict_SetItem(registry, mod_name, hooks) < 0) { - goto error; + else { + /* no hook has been registered so far */ + PyErr_Clear(); + assert(hooks != Py_None); + hooks = PyList_New(0); + if (hooks == NULL) { + goto error; + } + if (PyDict_SetItem(registry, mod_name, hooks) < 0) { + goto error; + } } } - else { - if (!PyList_Check(hooks)) { + if (!PyList_Check(hooks)) { PyErr_Format(PyExc_TypeError, "expected list of hooks, got '%.200s'", Py_TYPE(hooks)->tp_name); goto error; - } } /* append a new callable */ if (PyList_Append(hooks, callable) < 0) { @@ -3212,13 +3213,20 @@ static PyObject * imp_notify_module_loaded(PyObject *self, PyObject *args) { - PyObject *mod; + PyObject *mod, *o; if (!PyArg_ParseTuple(args, "O:notify_module_loaded", &mod)) return NULL; Py_INCREF(mod); - return PyImport_NotifyModuleLoaded(mod); + lock_import(); + o = PyImport_NotifyModuleLoaded(mod); + if (unlock_import() < 0) { + PyErr_SetString(PyExc_RuntimeError, + "not holding the import lock"); + return NULL; + } + return o; } static PyObject * @@ -3285,7 +3293,9 @@ "register_post_import_hook(callable, module_name) -> None"); PyDoc_STRVAR(doc_notify_module_loaded, -"notify_module_loaded(module) -> module"); +"notify_module_loaded(module) -> module\n\ +Notifies the system that a module has been loaded. The method is\n\ +with the global import locker."); static PyMethodDef imp_methods[] = { From python-3000-checkins at python.org Thu Jan 10 20:40:04 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Thu, 10 Jan 2008 20:40:04 +0100 (CET) Subject: [Python-3000-checkins] r59893 - in python/branches/py3k-importhook: Lib/test/test_imp.py Python/import.c Message-ID: <20080110194004.9C4981E400A@bag.python.org> Author: christian.heimes Date: Thu Jan 10 20:40:04 2008 New Revision: 59893 Modified: python/branches/py3k-importhook/Lib/test/test_imp.py python/branches/py3k-importhook/Python/import.c Log: Fixed a problem where the code didn't check for Py_None Added an unit test which reveals a design flaw. I've to hook in PyImport_NotifyModuleLoaded somewhere else Modified: python/branches/py3k-importhook/Lib/test/test_imp.py ============================================================================== --- python/branches/py3k-importhook/Lib/test/test_imp.py (original) +++ python/branches/py3k-importhook/Lib/test/test_imp.py Thu Jan 10 20:40:04 2008 @@ -1,7 +1,10 @@ +import os import imp import sys import thread import unittest +import shutil +import tempfile from test import test_support @@ -69,24 +72,49 @@ ## import sys ## self.assertRaises(ImportError, reload, sys) +# from test_pkg +def mkhier(descr): + root = tempfile.mkdtemp() + sys.path.insert(0, root) + if not os.path.isdir(root): + os.mkdir(root) + for name, contents in descr: + comps = name.split() + fullname = root + for c in comps: + fullname = os.path.join(fullname, c) + if contents is None: + os.mkdir(fullname) + else: + with open(fullname+".py", "w") as f: + f.write(contents) + if contents and contents[-1] != '\n': + f.write('\n') + return root + class CallBack: def __init__(self): self.mods = {} + self.names = [] def __call__(self, mod): self.mods[mod.__name__] = mod + self.names.append(mod.__name__) class PostImportHookTests(unittest.TestCase): def setUp(self): - if "telnetlib" in sys.modules: - del sys.modules["telnetlib"] - self.pihr = sys.post_import_hooks.copy() + self.sys_pih = sys.post_import_hooks.copy() + self.module_names = set(sys.modules) + self.tmpdir = None def tearDown(self): - if "telnetlib" in sys.modules: - del sys.modules["telnetlib"] - sys.post_import_hooks = self.pihr + sys.post_import_hooks = self.sys_pih + for name in list(sys.modules): + if name not in self.module_names: + del sys.modules[name] + if self.tmpdir: + shutil.rmtree(self.tmpdir) def test_registry(self): reg = sys.post_import_hooks @@ -99,9 +127,10 @@ sys.post_import_hooks = {} imp.register_post_import_hook(lambda mod: None, "sys") - sys.post_import_hooks["telnetlib"] = lambda mod: None - self.assertRaises(TypeError, __import__, "telnetlib") - sys.post_import_hooks = self.pihr + self.tmpdir = mkhier([("pih_test_module", "example = 23")]) + sys.post_import_hooks["pih_test_module"] = lambda mod: None + self.assertRaises(TypeError, __import__, "pih_test_module") + sys.post_import_hooks = self.sys_pih def test_register_callback_existing(self): callback = CallBack() @@ -110,25 +139,28 @@ # sys is already loaded and the callback is fired immediately self.assert_("sys" in callback.mods, callback.mods) self.assert_(callback.mods["sys"] is sys, callback.mods) - self.failIf("telnetlib" in callback.mods, callback.mods) + self.failIf("pih_test_module" in callback.mods, callback.mods) self.assertEqual(sys.post_import_hooks["sys"], None) def test_register_callback_new(self): + self.tmpdir = mkhier([("pih_test_module", "example = 23")]) + self.assert_("pih_test_module" not in sys.post_import_hooks) + self.assert_("pih_test_module" not in sys.modules) + callback = CallBack() - # an arbitrary module - if "telnetlib" in sys.modules: - del sys.modules["telnetlib"] - imp.register_post_import_hook(callback, "telnetlib") + imp.register_post_import_hook(callback, "pih_test_module") - regc = sys.post_import_hooks.get("telnetlib") - self.assert_(regc is not None, regc) + regc = sys.post_import_hooks.get("pih_test_module") + self.assertNotEqual(regc, None, (regc, callback.mods)) self.assert_(isinstance(regc, list), regc) self.assert_(callback in regc, regc) - import telnetlib - self.assert_("telnetlib" in callback.mods, callback.mods) - self.assert_(callback.mods["telnetlib"] is telnetlib, callback.mods) - self.assertEqual(sys.post_import_hooks["telnetlib"], None) + import pih_test_module + self.assertEqual(pih_test_module.example, 23) + self.assert_("pih_test_module" in callback.mods, callback.mods) + self.assert_(callback.mods["pih_test_module"] is pih_test_module, + callback.mods) + self.assertEqual(sys.post_import_hooks["pih_test_module"], None) def test_post_import_notify(self): imp.notify_module_loaded(sys) @@ -138,6 +170,34 @@ mod = imp.new_module("post_import_test_module") imp.notify_module_loaded(mod) + def test_hook_hirarchie(self): + hier = [ + ("pih_test", None), + ("pih_test __init__", "package = 0"), + ("pih_test a", None), + ("pih_test a __init__", "package = 1"), + ("pih_test a b", None), + ("pih_test a b __init__", "package = 2"), + ] + self.tmpdir = mkhier(hier) + callback = CallBack() + imp.register_post_import_hook(callback, "pih_test") + imp.register_post_import_hook(callback, "pih_test.a") + imp.register_post_import_hook(callback, "pih_test.a.b") + + import pih_test + self.assertEqual(callback.names, ["pih_test"]) + import pih_test.a + self.assertEqual(callback.names, ["pih_test", "pih_test.a"]) + from pih_test import a + self.assertEqual(callback.names, ["pih_test", "pih_test.a"]) + import pih_test.a.b + self.assertEqual(callback.names, + ["pih_test", "pih_test.a", "pih_test.a.b"]) + from pih_test.a import b + self.assertEqual(callback.names, + ["pih_test", "pih_test.a", "pih_test.a.b"]) + def test_main(): test_support.run_unittest( Modified: python/branches/py3k-importhook/Python/import.c ============================================================================== --- python/branches/py3k-importhook/Python/import.c (original) +++ python/branches/py3k-importhook/Python/import.c Thu Jan 10 20:40:04 2008 @@ -706,9 +706,11 @@ goto error; } - if ((hooks = PyDict_GetItem(registry, mod_name)) == NULL) { + hooks = PyDict_GetItem(registry, mod_name); + if (hooks == NULL || hooks == Py_None) { /* Either no hooks are defined or they are already fired */ - PyErr_Clear(); + if (hooks == NULL) + PyErr_Clear(); goto end; } Py_INCREF(hooks); From python-3000-checkins at python.org Thu Jan 10 20:48:40 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Thu, 10 Jan 2008 20:48:40 +0100 (CET) Subject: [Python-3000-checkins] r59894 - in python/branches/py3k-importhook: Lib/test/test_imp.py Python/import.c Message-ID: <20080110194840.68FF21E4009@bag.python.org> Author: christian.heimes Date: Thu Jan 10 20:48:40 2008 New Revision: 59894 Modified: python/branches/py3k-importhook/Lib/test/test_imp.py python/branches/py3k-importhook/Python/import.c Log: Moved the notification to import_submodule() import a.b.c now calls the callbacks in the right order (first a, then a.b, at last a.b.c) Modified: python/branches/py3k-importhook/Lib/test/test_imp.py ============================================================================== --- python/branches/py3k-importhook/Lib/test/test_imp.py (original) +++ python/branches/py3k-importhook/Lib/test/test_imp.py Thu Jan 10 20:48:40 2008 @@ -92,6 +92,15 @@ f.write('\n') return root +hier = [ + ("pih_test", None), + ("pih_test __init__", "package = 0"), + ("pih_test a", None), + ("pih_test a __init__", "package = 1"), + ("pih_test a b", None), + ("pih_test a b __init__", "package = 2"), +] + class CallBack: def __init__(self): self.mods = {} @@ -171,14 +180,6 @@ imp.notify_module_loaded(mod) def test_hook_hirarchie(self): - hier = [ - ("pih_test", None), - ("pih_test __init__", "package = 0"), - ("pih_test a", None), - ("pih_test a __init__", "package = 1"), - ("pih_test a b", None), - ("pih_test a b __init__", "package = 2"), - ] self.tmpdir = mkhier(hier) callback = CallBack() imp.register_post_import_hook(callback, "pih_test") @@ -198,6 +199,23 @@ self.assertEqual(callback.names, ["pih_test", "pih_test.a", "pih_test.a.b"]) + def test_hook_hirarchie_recursive(self): + self.tmpdir = mkhier(hier) + callback = CallBack() + imp.register_post_import_hook(callback, "pih_test") + imp.register_post_import_hook(callback, "pih_test.a") + imp.register_post_import_hook(callback, "pih_test.a.b") + + import pih_test.a.b + self.assertEqual(callback.names, + ["pih_test", "pih_test.a", "pih_test.a.b"]) + import pih_test + self.assertEqual(callback.names, + ["pih_test", "pih_test.a", "pih_test.a.b"]) + import pih_test.a + self.assertEqual(callback.names, + ["pih_test", "pih_test.a", "pih_test.a.b"]) + def test_main(): test_support.run_unittest( Modified: python/branches/py3k-importhook/Python/import.c ============================================================================== --- python/branches/py3k-importhook/Python/import.c (original) +++ python/branches/py3k-importhook/Python/import.c Thu Jan 10 20:48:40 2008 @@ -2286,7 +2286,7 @@ PyObject *result; lock_import(); result = import_module_level(name, globals, locals, fromlist, level); - result = PyImport_NotifyModuleLoaded(result); + /* result = PyImport_NotifyModuleLoaded(result); */ if (unlock_import() < 0) { Py_XDECREF(result); PyErr_SetString(PyExc_RuntimeError, @@ -2697,6 +2697,8 @@ Py_XDECREF(m); m = NULL; } + /* notify that the module was loaded */ + m = PyImport_NotifyModuleLoaded(m); } return m; From python-3000-checkins at python.org Thu Jan 10 23:10:03 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Thu, 10 Jan 2008 23:10:03 +0100 (CET) Subject: [Python-3000-checkins] r59897 - in python/branches/py3k-importhook: Lib/test/test_imp.py Python/import.c Message-ID: <20080110221003.D7C9C1E4009@bag.python.org> Author: christian.heimes Date: Thu Jan 10 23:10:03 2008 New Revision: 59897 Modified: python/branches/py3k-importhook/Lib/test/test_imp.py python/branches/py3k-importhook/Python/import.c Log: Added notify_byname as I proposed on the mailing list Added macro UNLOCK_IMPORT Modified: python/branches/py3k-importhook/Lib/test/test_imp.py ============================================================================== --- python/branches/py3k-importhook/Lib/test/test_imp.py (original) +++ python/branches/py3k-importhook/Lib/test/test_imp.py Thu Jan 10 23:10:03 2008 @@ -115,10 +115,12 @@ def setUp(self): self.sys_pih = sys.post_import_hooks.copy() self.module_names = set(sys.modules) + self.sys_path = list(sys.path) self.tmpdir = None def tearDown(self): sys.post_import_hooks = self.sys_pih + sys.path = self.sys_path for name in list(sys.modules): if name not in self.module_names: del sys.modules[name] @@ -216,6 +218,25 @@ self.assertEqual(callback.names, ["pih_test", "pih_test.a", "pih_test.a.b"]) + def test_notifyloaded_byname(self): + callback = CallBack() + + imp.register_post_import_hook(callback, "pih_test") + imp.register_post_import_hook(callback, "pih_test.a") + imp.register_post_import_hook(callback, "pih_test.a.b") + self.assertEqual(callback.names, []) + + for name in ("pih_test", "pih_test.a", "pih_test.a.b"): + mod = imp.new_module(name) + sys.modules[name] = mod + self.assertEqual(callback.names, []) + + mod2 = imp.notify_module_loaded("pih_test.a.b") + self.failUnless(mod is mod2, (mod, mod2)) + self.assertEqual(mod.__name__, "pih_test.a.b") + + self.assertEqual(callback.names, + ["pih_test", "pih_test.a", "pih_test.a.b"]) def test_main(): test_support.run_unittest( Modified: python/branches/py3k-importhook/Python/import.c ============================================================================== --- python/branches/py3k-importhook/Python/import.c (original) +++ python/branches/py3k-importhook/Python/import.c Thu Jan 10 23:10:03 2008 @@ -260,6 +260,14 @@ static long import_lock_thread = -1; static int import_lock_level = 0; +#define UNLOCK_IMPORT do { \ + if (unlock_import() < 0) { \ + PyErr_SetString(PyExc_RuntimeError, \ + "not holding the import lock"); \ + return NULL; \ + } \ + } while(0) + static void lock_import(void) { @@ -317,6 +325,7 @@ #define lock_import() #define unlock_import() 0 +#define UNLOCK_IMPORT #endif @@ -344,11 +353,7 @@ imp_release_lock(PyObject *self, PyObject *noargs) { #ifdef WITH_THREAD - if (unlock_import() < 0) { - PyErr_SetString(PyExc_RuntimeError, - "not holding the import lock"); - return NULL; - } + UNLOCK_IMPORT; #endif Py_INCREF(Py_None); return Py_None; @@ -657,6 +662,8 @@ /* Notify that a module as been loaded * Must be called with the import hook acquired + * The function *STEALS* a reference to module when an error occurs, otherwise + * it returns the module. */ PyObject * PyImport_NotifyModuleLoaded(PyObject *module) @@ -752,6 +759,57 @@ } } +/* notify by name + * notify_byname("a.b.c") calls PyImport_NotifyModuleLoaded() for "a", "a.b" + * and "a.b.c". The modules are taken from sys.modules. If a module can't be + * retrieved an exception is raised otherwise the module 'modname' is returned + */ +static PyObject * +notify_byname(const char *modname) +{ + PyObject *modules, *mod = NULL; + int status = -1; + const char *pmodname = modname; + char name[MAXPATHLEN+1]; + Py_ssize_t pos; + + modules = PyImport_GetModuleDict(); + if (modules == NULL) { + goto error; + } + for (; *pmodname != '\0'; pmodname++) { + if (*pmodname != '.') + continue; + pos = pmodname - modname; + if (pos == 0) { + PyErr_SetString(PyExc_ValueError, + "module name can't starts with a dot."); + return NULL; + } + strncpy(name, modname, pos); + name[pos] = '\0'; + mod = PyDict_GetItemString(modules, name); + Py_INCREF(mod); + mod = PyImport_NotifyModuleLoaded(mod); + if (mod == NULL) { + goto error; + } + Py_DECREF(mod); + } + mod = PyDict_GetItemString(modules, modname); + Py_INCREF(mod); + mod = PyImport_NotifyModuleLoaded(mod); + + status = 0; + error: + if (status == 0) { + return mod; + } + else { + return NULL; + } +} + /* register a new hook for a module PyImport_RegisterPostImportHook acquires the global import look */ @@ -831,12 +889,8 @@ Py_XDECREF(hooks); Py_XDECREF(mod_name); if (locked) { - if (unlock_import() < 0) { - PyErr_SetString(PyExc_RuntimeError, - "not holding the import lock"); - return NULL; - } - } + UNLOCK_IMPORT; + } if (status < 0) { return NULL; } @@ -2287,12 +2341,7 @@ lock_import(); result = import_module_level(name, globals, locals, fromlist, level); /* result = PyImport_NotifyModuleLoaded(result); */ - if (unlock_import() < 0) { - Py_XDECREF(result); - PyErr_SetString(PyExc_RuntimeError, - "not holding the import lock"); - return NULL; - } + UNLOCK_IMPORT; return result; } @@ -3218,18 +3267,19 @@ imp_notify_module_loaded(PyObject *self, PyObject *args) { PyObject *mod, *o; + char *name; + + if (PyArg_ParseTuple(args, "s:notify_module_loaded", &name)) { + return notify_byname(name); + } if (!PyArg_ParseTuple(args, "O:notify_module_loaded", &mod)) - return NULL; + return NULL; Py_INCREF(mod); lock_import(); o = PyImport_NotifyModuleLoaded(mod); - if (unlock_import() < 0) { - PyErr_SetString(PyExc_RuntimeError, - "not holding the import lock"); - return NULL; - } + UNLOCK_IMPORT; return o; } From python-3000-checkins at python.org Fri Jan 11 01:17:22 2008 From: python-3000-checkins at python.org (eric.smith) Date: Fri, 11 Jan 2008 01:17:22 +0100 (CET) Subject: [Python-3000-checkins] r59899 - in python/branches/py3k: Lib/test/test_builtin.py Objects/typeobject.c Message-ID: <20080111001722.BFFB81E4009@bag.python.org> Author: eric.smith Date: Fri Jan 11 01:17:22 2008 New Revision: 59899 Modified: python/branches/py3k/Lib/test/test_builtin.py python/branches/py3k/Objects/typeobject.c Log: Simplifed argument parsing in object.__format__, added test case. Modified: python/branches/py3k/Lib/test/test_builtin.py ============================================================================== --- python/branches/py3k/Lib/test/test_builtin.py (original) +++ python/branches/py3k/Lib/test/test_builtin.py Fri Jan 11 01:17:22 2008 @@ -558,6 +558,10 @@ # TypeError because self.__format__ returns the wrong type self.assertRaises(TypeError, format, B(), "") + # TypeError because format_spec is not unicode + self.assertRaises(TypeError, format, object(), 4) + self.assertRaises(TypeError, format, object(), object()) + # make sure we can take a subclass of str as a format spec self.assertEqual(format(0, C('10')), ' 0') Modified: python/branches/py3k/Objects/typeobject.c ============================================================================== --- python/branches/py3k/Objects/typeobject.c (original) +++ python/branches/py3k/Objects/typeobject.c Fri Jan 11 01:17:22 2008 @@ -2950,12 +2950,8 @@ PyObject *result = NULL; PyObject *format_meth = NULL; - if (!PyArg_ParseTuple(args, "O:__format__", &format_spec)) + if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) return NULL; - if (!PyUnicode_Check(format_spec)) { - PyErr_SetString(PyExc_TypeError, "Unicode object required"); - return NULL; - } self_as_str = PyObject_Str(self); if (self_as_str != NULL) { From python-3000-checkins at python.org Fri Jan 11 01:32:16 2008 From: python-3000-checkins at python.org (eric.smith) Date: Fri, 11 Jan 2008 01:32:16 +0100 (CET) Subject: [Python-3000-checkins] r59901 - python/branches/py3k/Lib/test/test_builtin.py Message-ID: <20080111003216.E5AFD1E4009@bag.python.org> Author: eric.smith Date: Fri Jan 11 01:32:16 2008 New Revision: 59901 Modified: python/branches/py3k/Lib/test/test_builtin.py Log: Added the test cases I actually meant to add. Modified: python/branches/py3k/Lib/test/test_builtin.py ============================================================================== --- python/branches/py3k/Lib/test/test_builtin.py (original) +++ python/branches/py3k/Lib/test/test_builtin.py Fri Jan 11 01:32:16 2008 @@ -562,6 +562,11 @@ self.assertRaises(TypeError, format, object(), 4) self.assertRaises(TypeError, format, object(), object()) + # first argument to object.__format__ must be string + self.assertRaises(TypeError, object().__format__, 3) + self.assertRaises(TypeError, object().__format__, object()) + self.assertRaises(TypeError, object().__format__, None) + # make sure we can take a subclass of str as a format spec self.assertEqual(format(0, C('10')), ' 0') From python-3000-checkins at python.org Fri Jan 11 01:41:34 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Fri, 11 Jan 2008 01:41:34 +0100 (CET) Subject: [Python-3000-checkins] r59902 - in python/branches/py3k-importhook: Lib/test/test_imp.py Python/import.c Message-ID: <20080111004134.64AB71E4009@bag.python.org> Author: christian.heimes Date: Fri Jan 11 01:41:34 2008 New Revision: 59902 Modified: python/branches/py3k-importhook/Lib/test/test_imp.py python/branches/py3k-importhook/Python/import.c Log: Changed an implementation detail that causes the hooks to be called in a more predictable order. If a hook for module is registered during the processing of the versy same module than the hook is called after the already registered hooks. Hooks for loaded modules are still executed ASAP. Modified: python/branches/py3k-importhook/Lib/test/test_imp.py ============================================================================== --- python/branches/py3k-importhook/Lib/test/test_imp.py (original) +++ python/branches/py3k-importhook/Lib/test/test_imp.py Fri Jan 11 01:41:34 2008 @@ -101,6 +101,26 @@ ("pih_test a b __init__", "package = 2"), ] +mod_callback = """ +import imp + +def callback(mod): + imp.test_callbacks.append(("pih_test%s", mod.__name__)) + +imp.register_post_import_hook(callback, "pih_test") +imp.register_post_import_hook(callback, "pih_test.a") +imp.register_post_import_hook(callback, "pih_test.a.b") +""" + +hier_withregister = [ + ("pih_test", None), + ("pih_test __init__", mod_callback % ''), + ("pih_test a", None), + ("pih_test a __init__", mod_callback % '.a'), + ("pih_test a b", None), + ("pih_test a b __init__", mod_callback % '.a.b'), +] + class CallBack: def __init__(self): self.mods = {} @@ -116,11 +136,13 @@ self.sys_pih = sys.post_import_hooks.copy() self.module_names = set(sys.modules) self.sys_path = list(sys.path) + imp.test_callbacks = [] self.tmpdir = None def tearDown(self): sys.post_import_hooks = self.sys_pih sys.path = self.sys_path + del imp.test_callbacks for name in list(sys.modules): if name not in self.module_names: del sys.modules[name] @@ -218,6 +240,40 @@ self.assertEqual(callback.names, ["pih_test", "pih_test.a", "pih_test.a.b"]) + def test_hook_hirarchie(self): + self.tmpdir = mkhier(hier_withregister) + + def callback(mod): + imp.test_callbacks.append(('', mod.__name__)) + + imp.register_post_import_hook(callback, "pih_test") + imp.register_post_import_hook(callback, "pih_test.a") + imp.register_post_import_hook(callback, "pih_test.a.b") + + expected = [] + self.assertEqual(imp.test_callbacks, expected) + + import pih_test + expected.append(("", "pih_test")) + expected.append(("pih_test", "pih_test")) + self.assertEqual(imp.test_callbacks, expected) + + import pih_test.a + expected.append(("pih_test.a", "pih_test")) + expected.append(("", "pih_test.a")) + expected.append(("pih_test", "pih_test.a")) + expected.append(("pih_test.a", "pih_test.a")) + self.assertEqual(imp.test_callbacks, expected) + + import pih_test.a.b + expected.append(("pih_test.a.b", "pih_test")) + expected.append(("pih_test.a.b", "pih_test.a")) + expected.append(("", "pih_test.a.b")) + expected.append(("pih_test", "pih_test.a.b")) + expected.append(("pih_test.a", "pih_test.a.b")) + expected.append(("pih_test.a.b", "pih_test.a.b")) + self.assertEqual(imp.test_callbacks, expected) + def test_notifyloaded_byname(self): callback = CallBack() Modified: python/branches/py3k-importhook/Python/import.c ============================================================================== --- python/branches/py3k-importhook/Python/import.c (original) +++ python/branches/py3k-importhook/Python/import.c Fri Jan 11 01:41:34 2008 @@ -718,12 +718,9 @@ /* Either no hooks are defined or they are already fired */ if (hooks == NULL) PyErr_Clear(); - goto end; + goto success; } Py_INCREF(hooks); - if (PyDict_SetItem(registry, mod_name, Py_None) < 0) { - goto end; - } if (!PyList_Check(hooks)) { PyErr_Format(PyExc_TypeError, "expected None or list of hooks, got '%.200s'", @@ -739,13 +736,20 @@ o = PyObject_CallFunctionObjArgs(hook, module, NULL); Py_DECREF(hook); if (o == NULL) { - goto error; + goto removehooks; } Py_DECREF(o); } + if (PyErr_Occurred()) { + return NULL; + } - end: + success: status = 0; + removehooks: + if (PyDict_SetItem(registry, mod_name, Py_None) < 0) { + status = -1; + } error: Py_XDECREF(mod_name); Py_XDECREF(it); @@ -838,6 +842,7 @@ locked = 1; hooks = PyDict_GetItem(registry, mod_name); + Py_XINCREF(hooks); /* module may be already loaded, get the module object from sys */ if (hooks == NULL || hooks == Py_None) { PyObject *module = NULL; @@ -856,7 +861,7 @@ if (o == NULL) { goto error; } - goto end; + goto success; } else { /* no hook has been registered so far */ @@ -882,7 +887,7 @@ goto error; } - end: + success: status = 0; error: Py_XDECREF(callable); From python-3000-checkins at python.org Fri Jan 11 08:03:06 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Fri, 11 Jan 2008 08:03:06 +0100 (CET) Subject: [Python-3000-checkins] r59908 - in python/branches/py3k: Lib/test/test_import.py Python/import.c Message-ID: <20080111070306.607E51E4026@bag.python.org> Author: christian.heimes Date: Fri Jan 11 08:03:05 2008 New Revision: 59908 Modified: python/branches/py3k/Lib/test/test_import.py python/branches/py3k/Python/import.c Log: Good catch Neal! I completely forgot about pyo files and the tests are usually not run with -O. The modified code checks for *.py? Modified: python/branches/py3k/Lib/test/test_import.py ============================================================================== --- python/branches/py3k/Lib/test/test_import.py (original) +++ python/branches/py3k/Lib/test/test_import.py Fri Jan 11 08:03:05 2008 @@ -213,7 +213,8 @@ os.remove(source) del sys.modules[TESTFN] mod = __import__(TESTFN) - self.failUnless(mod.__file__.endswith('.pyc')) + ext = mod.__file__[-4:] + self.failUnless(ext in ('.pyc', '.pyo'), ext) finally: sys.path.pop(0) remove_files(TESTFN) Modified: python/branches/py3k/Python/import.c ============================================================================== --- python/branches/py3k/Python/import.c (original) +++ python/branches/py3k/Python/import.c Fri Jan 11 08:03:05 2008 @@ -982,7 +982,8 @@ } len = strlen(file); - if (len > MAXPATHLEN || PyOS_stricmp(&file[len-4], ".pyc") != 0) { + /* match '*.py?' */ + if (len > MAXPATHLEN || PyOS_strnicmp(&file[len-4], ".py", 3) != 0) { return PyUnicode_DecodeFSDefault(file); } From python-3000-checkins at python.org Fri Jan 11 13:58:41 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Fri, 11 Jan 2008 13:58:41 +0100 (CET) Subject: [Python-3000-checkins] r59914 - python/branches/py3k/Doc/library/string.rst Message-ID: <20080111125841.47D5E1E400A@bag.python.org> Author: georg.brandl Date: Fri Jan 11 13:58:40 2008 New Revision: 59914 Modified: python/branches/py3k/Doc/library/string.rst Log: Fix markup. Modified: python/branches/py3k/Doc/library/string.rst ============================================================================== --- python/branches/py3k/Doc/library/string.rst (original) +++ python/branches/py3k/Doc/library/string.rst Fri Jan 11 13:58:40 2008 @@ -230,8 +230,8 @@ value to a string before calling :meth:`__format__`, the normal formatting logic is bypassed. -Two conversion flags are currently supported: ``'!s'`` which calls :func:`str()` -on the value, and ``'!r'`` which calls :func:`repr()`. +Two conversion flags are currently supported: ``'!s'`` which calls :func:`str` +on the value, and ``'!r'`` which calls :func:`repr`. Some examples:: @@ -289,7 +289,7 @@ although some of the formatting options are only supported by the numeric types. A general convention is that an empty format string (``""``) produces the same -result as if you had called :func:`str()` on the value. +result as if you had called :func:`str` on the value. The general form of a *standard format specifier* is: From python-3000-checkins at python.org Fri Jan 11 17:17:01 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Fri, 11 Jan 2008 17:17:01 +0100 (CET) Subject: [Python-3000-checkins] r59921 - in python/branches/py3k: Doc/glossary.rst Doc/library/collections.rst Doc/library/decimal.rst Doc/library/difflib.rst Doc/library/doctest.rst Doc/library/inspect.rst Doc/library/re.rst Lib/collections.py Lib/decimal.py Lib/difflib.py Lib/doctest.py Lib/inspect.py Lib/test/test_collections.py Lib/test/test_doctest.py Lib/test/test_pyclbr.py Lib/test/test_re.py Modules/mmapmodule.c Modules/socketmodule.c PCbuild/build_tkinter.py PCbuild/readme.txt Message-ID: <20080111161702.027781E4026@bag.python.org> Author: christian.heimes Date: Fri Jan 11 17:17:00 2008 New Revision: 59921 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/glossary.rst python/branches/py3k/Doc/library/collections.rst python/branches/py3k/Doc/library/decimal.rst python/branches/py3k/Doc/library/difflib.rst python/branches/py3k/Doc/library/doctest.rst python/branches/py3k/Doc/library/inspect.rst python/branches/py3k/Doc/library/re.rst python/branches/py3k/Lib/collections.py python/branches/py3k/Lib/decimal.py python/branches/py3k/Lib/difflib.py python/branches/py3k/Lib/doctest.py python/branches/py3k/Lib/inspect.py python/branches/py3k/Lib/test/test_collections.py python/branches/py3k/Lib/test/test_doctest.py python/branches/py3k/Lib/test/test_pyclbr.py python/branches/py3k/Lib/test/test_re.py python/branches/py3k/Modules/mmapmodule.c python/branches/py3k/Modules/socketmodule.c python/branches/py3k/PCbuild/build_tkinter.py python/branches/py3k/PCbuild/readme.txt Log: Merged revisions 59883-59920 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r59887 | neal.norwitz | 2008-01-10 06:42:58 +0100 (Thu, 10 Jan 2008) | 1 line Reword entry, not sure I made it much better though. ........ r59888 | andrew.kuchling | 2008-01-10 14:37:12 +0100 (Thu, 10 Jan 2008) | 1 line Check for fd of -1 to save fsync() and fstat() call ........ r59891 | thomas.heller | 2008-01-10 19:45:40 +0100 (Thu, 10 Jan 2008) | 1 line Reflow a paragraph, and fix a typo. ........ r59892 | raymond.hettinger | 2008-01-10 20:15:10 +0100 (Thu, 10 Jan 2008) | 1 line Examples for named tuple subclassing should include __slots__ ........ r59895 | raymond.hettinger | 2008-01-10 21:37:12 +0100 (Thu, 10 Jan 2008) | 1 line Clarify how to add a field to a named tuple. ........ r59896 | amaury.forgeotdarc | 2008-01-10 22:59:42 +0100 (Thu, 10 Jan 2008) | 12 lines Closing issue1761. Surprising behaviour of the "$" regexp: it matches the end of the string, AND just before the newline at the end of the string:: re.sub('$', '#', 'foo\n') == 'foo#\n#' Python is consistent with Perl and the pcre library, so we just document it. Guido prefers "\Z" to match only the end of the string. ........ r59898 | raymond.hettinger | 2008-01-11 00:00:01 +0100 (Fri, 11 Jan 2008) | 1 line Neaten-up the named tuple docs ........ r59900 | raymond.hettinger | 2008-01-11 01:23:13 +0100 (Fri, 11 Jan 2008) | 1 line Run doctests on the collections module ........ r59903 | raymond.hettinger | 2008-01-11 02:25:54 +0100 (Fri, 11 Jan 2008) | 1 line Doctest results return a named tuple for readability ........ r59904 | raymond.hettinger | 2008-01-11 03:12:33 +0100 (Fri, 11 Jan 2008) | 1 line Comment-out missing constant (from rev 59819) ........ r59905 | raymond.hettinger | 2008-01-11 03:24:13 +0100 (Fri, 11 Jan 2008) | 1 line Have Decimal.as_tuple return a named tuple. ........ r59906 | raymond.hettinger | 2008-01-11 04:04:50 +0100 (Fri, 11 Jan 2008) | 1 line Let most inspect functions return named tuples ........ r59907 | raymond.hettinger | 2008-01-11 04:20:54 +0100 (Fri, 11 Jan 2008) | 1 line Improve usability of the SequenceMatcher by returning named tuples describing match ranges. ........ r59909 | thomas.heller | 2008-01-11 09:04:03 +0100 (Fri, 11 Jan 2008) | 1 line Add an important missing blank. ........ r59910 | georg.brandl | 2008-01-11 10:19:11 +0100 (Fri, 11 Jan 2008) | 2 lines Guard definition of TIPC_SUB_CANCEL with an #ifdef. ........ r59911 | georg.brandl | 2008-01-11 10:20:58 +0100 (Fri, 11 Jan 2008) | 2 lines News entries for rev. 5990[567]. ........ r59912 | georg.brandl | 2008-01-11 10:55:53 +0100 (Fri, 11 Jan 2008) | 2 lines Documentation for r5990[3567]. ........ r59913 | thomas.heller | 2008-01-11 13:41:39 +0100 (Fri, 11 Jan 2008) | 4 lines The sqlite3 dll, when compiled in debug mode, must be linked with /MDd to use the debug runtime library. Further, the dll will be named sqlite3_d.dll. ........ r59919 | thomas.heller | 2008-01-11 16:38:46 +0100 (Fri, 11 Jan 2008) | 6 lines Revert revision 59913, because it was wrong: The sqlite3 dll, when compiled in debug mode, must be linked with /MDd to use the debug runtime library. Further, the dll will be named sqlite3_d.dll. ........ r59920 | christian.heimes | 2008-01-11 16:42:29 +0100 (Fri, 11 Jan 2008) | 1 line Removed unused variable ........ Modified: python/branches/py3k/Doc/glossary.rst ============================================================================== --- python/branches/py3k/Doc/glossary.rst (original) +++ python/branches/py3k/Doc/glossary.rst Fri Jan 11 17:17:00 2008 @@ -327,6 +327,13 @@ mutable Mutable objects can change their value but keep their :func:`id`. See also :term:`immutable`. + + named tuple + A tuple subclass whose elements also are accessible as attributes via + fixed names (the class name and field names are indicated in the + individual documentation of a named tuple type, like ``TestResults(failed, + attempted)``). Named tuple classes are created by + :func:`collections.namedtuple`. namespace The place where a variable is stored. Namespaces are implemented as Modified: python/branches/py3k/Doc/library/collections.rst ============================================================================== --- python/branches/py3k/Doc/library/collections.rst (original) +++ python/branches/py3k/Doc/library/collections.rst Fri Jan 11 17:17:00 2008 @@ -397,8 +397,8 @@ method which lists the tuple contents in a ``name=value`` format. The *fieldnames* are a single string with each fieldname separated by whitespace - and/or commas (for example 'x y' or 'x, y'). Alternatively, *fieldnames* - can be a sequence of strings (such as ['x', 'y']). + and/or commas, for example ``'x y'`` or ``'x, y'``. Alternatively, *fieldnames* + can be a sequence of strings such as ``['x', 'y']``. Any valid Python identifier may be used for a fieldname except for names starting with an underscore. Valid identifiers consist of letters, digits, @@ -406,7 +406,7 @@ a :mod:`keyword` such as *class*, *for*, *return*, *global*, *pass*, *print*, or *raise*. - If *verbose* is true, will print the class definition. + If *verbose* is true, the class definition is printed just before being built. Named tuple instances do not have per-instance dictionaries, so they are lightweight and require no more memory than regular tuples. @@ -533,7 +533,7 @@ >>> getattr(p, 'x') 11 -To cast a dictionary to a named tuple, use the double-star-operator [#]_:: +To convert a dictionary to a named tuple, use the double-star-operator [#]_:: >>> d = {'x': 11, 'y': 22} >>> Point(**d) @@ -544,23 +544,24 @@ a fixed-width print format:: >>> class Point(namedtuple('Point', 'x y')): + ... __slots__ = () ... @property ... def hypot(self): ... return (self.x ** 2 + self.y ** 2) ** 0.5 ... def __str__(self): - ... return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) + ... return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) - >>> for p in Point(3,4), Point(14,5), Point(9./7,6): + >>> for p in Point(3, 4), Point(14, 5/7.): ... print(p) - Point: x= 3.000 y= 4.000 hypot= 5.000 - Point: x=14.000 y= 5.000 hypot=14.866 - Point: x= 1.286 y= 6.000 hypot= 6.136 + Point: x= 3.000 y= 4.000 hypot= 5.000 + Point: x=14.000 y= 0.714 hypot=14.018 Another use for subclassing is to replace performance critcal methods with -faster versions that bypass error-checking and that localize variable access:: +faster versions that bypass error-checking:: class Point(namedtuple('Point', 'x y')): + __slots__ = () _make = classmethod(tuple.__new__) def _replace(self, _map=map, **kwds): return self._make(_map(kwds.get, ('x', 'y'), self)) @@ -569,7 +570,7 @@ Subclassing is not useful for adding new, stored fields. Instead, simply create a new named tuple type from the :attr:`_fields` attribute:: - >>> Pixel = namedtuple('Pixel', Point._fields + Color._fields) + >>> Point3D = namedtuple('Point3D', Point._fields + ('z',)) Default values can be implemented by using :meth:`_replace` to customize a prototype instance:: Modified: python/branches/py3k/Doc/library/decimal.rst ============================================================================== --- python/branches/py3k/Doc/library/decimal.rst (original) +++ python/branches/py3k/Doc/library/decimal.rst Fri Jan 11 17:17:00 2008 @@ -328,7 +328,11 @@ .. method:: Decimal.as_tuple() - Return a tuple representation of the number: ``(sign, digit_tuple, exponent)``. + Return a :term:`named tuple` representation of the number: + ``DecimalTuple(sign, digits, exponent)``. + + .. versionchanged:: 2.6 + Use a named tuple. .. method:: Decimal.canonical() Modified: python/branches/py3k/Doc/library/difflib.rst ============================================================================== --- python/branches/py3k/Doc/library/difflib.rst (original) +++ python/branches/py3k/Doc/library/difflib.rst Fri Jan 11 17:17:00 2008 @@ -336,7 +336,7 @@ Find longest matching block in ``a[alo:ahi]`` and ``b[blo:bhi]``. - If *isjunk* was omitted or ``None``, :meth:`get_longest_match` returns ``(i, j, + If *isjunk* was omitted or ``None``, :meth:`find_longest_match` returns ``(i, j, k)`` such that ``a[i:i+k]`` is equal to ``b[j:j+k]``, where ``alo <= i <= i+k <= ahi`` and ``blo <= j <= j+k <= bhi``. For all ``(i', j', k')`` meeting those conditions, the additional conditions ``k >= k'``, ``i <= i'``, and if ``i == @@ -365,6 +365,9 @@ If no blocks match, this returns ``(alo, blo, 0)``. + .. versionchanged:: 2.6 + This method returns a :term:`named tuple` ``Match(a, b, size)``. + .. method:: SequenceMatcher.get_matching_blocks() Modified: python/branches/py3k/Doc/library/doctest.rst ============================================================================== --- python/branches/py3k/Doc/library/doctest.rst (original) +++ python/branches/py3k/Doc/library/doctest.rst Fri Jan 11 17:17:00 2008 @@ -1436,11 +1436,14 @@ .. method:: DocTestRunner.summarize([verbose]) Print a summary of all the test cases that have been run by this DocTestRunner, - and return a tuple ``(failure_count, test_count)``. + and return a :term:`named tuple` ``TestResults(failed, attempted)``. The optional *verbose* argument controls how detailed the summary is. If the verbosity is not specified, then the :class:`DocTestRunner`'s verbosity is used. + .. versionchanged:: 2.6 + Use a named tuple. + .. _doctest-outputchecker: Modified: python/branches/py3k/Doc/library/inspect.rst ============================================================================== --- python/branches/py3k/Doc/library/inspect.rst (original) +++ python/branches/py3k/Doc/library/inspect.rst Fri Jan 11 17:17:00 2008 @@ -188,7 +188,8 @@ .. function:: getmoduleinfo(path) - Return a tuple of values that describe how Python will interpret the file + Returns a :term:`named tuple` ``ModuleInfo(name, suffix, mode, + module_type)`` of values that describe how Python will interpret the file identified by *path* if it is a module, or ``None`` if it would not be identified as a module. The return tuple is ``(name, suffix, mode, mtype)``, where *name* is the name of the module without the name of any enclosing @@ -377,8 +378,9 @@ .. function:: getargspec(func) - Get the names and default values of a function's arguments. A tuple of four - things is returned: ``(args, varargs, varkw, defaults)``. *args* is a list of + Get the names and default values of a function's arguments. A + :term:`named tuple` ``ArgSpec(args, varargs, keywords, + defaults)`` is returned. *args* is a list of the argument names. *varargs* and *varkw* are the names of the ``*`` and ``**`` arguments or ``None``. *defaults* is a tuple of default argument values or None if there are no default arguments; if this tuple has *n* @@ -391,10 +393,10 @@ .. function:: getfullargspec(func) - Get the names and default values of a function's arguments. A tuple of seven - things is returned: + Get the names and default values of a function's arguments. A :term:`named tuple` + is returned: - ``(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations)`` + ``FullArgSpec(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations)`` *args* is a list of the argument names. *varargs* and *varkw* are the names of the ``*`` and ``**`` arguments or ``None``. *defaults* is an n-tuple of @@ -408,8 +410,8 @@ .. function:: getargvalues(frame) - Get information about arguments passed into a particular frame. A tuple of four - things is returned: ``(args, varargs, varkw, locals)``. *args* is a list of the + Get information about arguments passed into a particular frame. A :term:`named tuple` + ``ArgInfo(args, varargs, keywords, locals)`` is returned. *args* is a list of the argument names (it may contain nested lists). *varargs* and *varkw* are the names of the ``*`` and ``**`` arguments or ``None``. *locals* is the locals dictionary of the given frame. @@ -476,8 +478,8 @@ .. function:: getframeinfo(frame[, context]) - Get information about a frame or traceback object. A 5-tuple is returned, the - last five elements of the frame's frame record. + Get information about a frame or traceback object. A :term:`named tuple` + ``Traceback(filename, lineno, function, code_context, index)`` is returned. .. function:: getouterframes(frame[, context]) Modified: python/branches/py3k/Doc/library/re.rst ============================================================================== --- python/branches/py3k/Doc/library/re.rst (original) +++ python/branches/py3k/Doc/library/re.rst Fri Jan 11 17:17:00 2008 @@ -98,7 +98,9 @@ string, and in :const:`MULTILINE` mode also matches before a newline. ``foo`` matches both 'foo' and 'foobar', while the regular expression ``foo$`` matches only 'foo'. More interestingly, searching for ``foo.$`` in ``'foo1\nfoo2\n'`` - matches 'foo2' normally, but 'foo1' in :const:`MULTILINE` mode. + matches 'foo2' normally, but 'foo1' in :const:`MULTILINE` mode; searching for + a single ``$`` in ``'foo\n'`` will find two (empty) matches: one just before + the newline, and one at the end of the string. ``'*'`` Causes the resulting RE to match 0 or more repetitions of the preceding RE, as Modified: python/branches/py3k/Lib/collections.py ============================================================================== --- python/branches/py3k/Lib/collections.py (original) +++ python/branches/py3k/Lib/collections.py Fri Jan 11 17:17:00 2008 @@ -117,23 +117,28 @@ # test and demonstrate ability to override methods class Point(namedtuple('Point', 'x y')): + __slots__ = () @property def hypot(self): return (self.x ** 2 + self.y ** 2) ** 0.5 def __str__(self): - return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) + return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) - for p in Point(3,4), Point(14,5), Point(9./7,6): + for p in Point(3, 4), Point(14, 5/7.): print (p) class Point(namedtuple('Point', 'x y')): 'Point class with optimized _make() and _replace() without error-checking' + __slots__ = () _make = classmethod(tuple.__new__) def _replace(self, _map=map, **kwds): return self._make(_map(kwds.get, ('x', 'y'), self)) print(Point(11, 22)._replace(x=100)) + Point3D = namedtuple('Point3D', Point._fields + ('z',)) + print(Point3D.__doc__) + import doctest TestResults = namedtuple('TestResults', 'failed attempted') print(TestResults(*doctest.testmod())) Modified: python/branches/py3k/Lib/decimal.py ============================================================================== --- python/branches/py3k/Lib/decimal.py (original) +++ python/branches/py3k/Lib/decimal.py Fri Jan 11 17:17:00 2008 @@ -137,6 +137,12 @@ import numbers as _numbers import copy as _copy +try: + from collections import namedtuple as _namedtuple + DecimalTuple = _namedtuple('DecimalTuple', 'sign digits exponent') +except ImportError: + DecimalTuple = lambda *args: args + # Rounding ROUND_DOWN = 'ROUND_DOWN' ROUND_HALF_UP = 'ROUND_HALF_UP' @@ -841,7 +847,7 @@ To show the internals exactly as they are. """ - return (self._sign, tuple(map(int, self._int)), self._exp) + return DecimalTuple(self._sign, tuple(map(int, self._int)), self._exp) def __repr__(self): """Represents the number as an instance of Decimal.""" Modified: python/branches/py3k/Lib/difflib.py ============================================================================== --- python/branches/py3k/Lib/difflib.py (original) +++ python/branches/py3k/Lib/difflib.py Fri Jan 11 17:17:00 2008 @@ -30,9 +30,12 @@ __all__ = ['get_close_matches', 'ndiff', 'restore', 'SequenceMatcher', 'Differ','IS_CHARACTER_JUNK', 'IS_LINE_JUNK', 'context_diff', - 'unified_diff', 'HtmlDiff'] + 'unified_diff', 'HtmlDiff', 'Match'] import heapq +from collections import namedtuple as _namedtuple + +Match = _namedtuple('Match', 'a b size') def _calculate_ratio(matches, length): if length: @@ -363,7 +366,7 @@ >>> s = SequenceMatcher(None, " abcd", "abcd abcd") >>> s.find_longest_match(0, 5, 0, 9) - (0, 4, 5) + Match(a=0, b=4, size=5) If isjunk is defined, first the longest matching block is determined as above, but with the additional restriction that no @@ -379,13 +382,13 @@ >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd") >>> s.find_longest_match(0, 5, 0, 9) - (1, 0, 4) + Match(a=1, b=0, size=4) If no blocks match, return (alo, blo, 0). >>> s = SequenceMatcher(None, "ab", "c") >>> s.find_longest_match(0, 2, 0, 1) - (0, 0, 0) + Match(a=0, b=0, size=0) """ # CAUTION: stripping common prefix or suffix would be incorrect. @@ -452,7 +455,7 @@ a[besti+bestsize] == b[bestj+bestsize]: bestsize = bestsize + 1 - return besti, bestj, bestsize + return Match(besti, bestj, bestsize) def get_matching_blocks(self): """Return list of triples describing matching subsequences. @@ -469,8 +472,8 @@ triple with n==0. >>> s = SequenceMatcher(None, "abxcd", "abcd") - >>> s.get_matching_blocks() - [(0, 0, 2), (3, 2, 2), (5, 4, 0)] + >>> list(s.get_matching_blocks()) + [Match(a=0, b=0, size=2), Match(a=3, b=2, size=2), Match(a=5, b=4, size=0)] """ if self.matching_blocks is not None: @@ -523,7 +526,7 @@ non_adjacent.append( (la, lb, 0) ) self.matching_blocks = non_adjacent - return self.matching_blocks + return map(Match._make, self.matching_blocks) def get_opcodes(self): """Return list of 5-tuples describing how to turn a into b. Modified: python/branches/py3k/Lib/doctest.py ============================================================================== --- python/branches/py3k/Lib/doctest.py (original) +++ python/branches/py3k/Lib/doctest.py Fri Jan 11 17:17:00 2008 @@ -99,6 +99,9 @@ import unittest, difflib, pdb, tempfile import warnings from io import StringIO +from collections import namedtuple + +TestResults = namedtuple('TestResults', 'failed attempted') # There are 4 basic classes: # - Example: a pair, plus an intra-docstring line number. @@ -1024,10 +1027,10 @@ >>> tests.sort(key = lambda test: test.name) >>> for test in tests: ... print(test.name, '->', runner.run(test)) - _TestClass -> (0, 2) - _TestClass.__init__ -> (0, 2) - _TestClass.get -> (0, 2) - _TestClass.square -> (0, 1) + _TestClass -> TestResults(failed=0, attempted=2) + _TestClass.__init__ -> TestResults(failed=0, attempted=2) + _TestClass.get -> TestResults(failed=0, attempted=2) + _TestClass.square -> TestResults(failed=0, attempted=1) The `summarize` method prints a summary of all the test cases that have been run by the runner, and returns an aggregated `(f, t)` @@ -1042,7 +1045,7 @@ 7 tests in 4 items. 7 passed and 0 failed. Test passed. - (0, 7) + TestResults(failed=0, attempted=7) The aggregated number of tried examples and failed examples is also available via the `tries` and `failures` attributes: @@ -1285,7 +1288,7 @@ # Record and return the number of failures and tries. self.__record_outcome(test, failures, tries) - return failures, tries + return TestResults(failures, tries) def __record_outcome(self, test, f, t): """ @@ -1417,7 +1420,7 @@ print("***Test Failed***", totalf, "failures.") elif verbose: print("Test passed.") - return totalf, totalt + return TestResults(totalf, totalt) #///////////////////////////////////////////////////////////////// # Backward compatibility cruft to maintain doctest.master. @@ -1688,7 +1691,7 @@ ... ''', {}, 'foo', 'foo.py', 0) >>> runner.run(test) - (0, 1) + TestResults(failed=0, attempted=1) >>> test.globs {} @@ -1818,7 +1821,7 @@ else: master.merge(runner) - return runner.failures, runner.tries + return TestResults(runner.failures, runner.tries) def testfile(filename, module_relative=True, name=None, package=None, globs=None, verbose=None, report=True, optionflags=0, @@ -1939,7 +1942,7 @@ else: master.merge(runner) - return runner.failures, runner.tries + return TestResults(runner.failures, runner.tries) def run_docstring_examples(f, globs, verbose=False, name="NoName", compileflags=None, optionflags=0): @@ -1998,7 +2001,7 @@ (f,t) = self.testrunner.run(test) if self.verbose: print(f, "of", t, "examples failed in string", name) - return (f,t) + return TestResults(f,t) def rundoc(self, object, name=None, module=None): f = t = 0 @@ -2007,7 +2010,7 @@ for test in tests: (f2, t2) = self.testrunner.run(test) (f,t) = (f+f2, t+t2) - return (f,t) + return TestResults(f,t) def rundict(self, d, name, module=None): import types Modified: python/branches/py3k/Lib/inspect.py ============================================================================== --- python/branches/py3k/Lib/inspect.py (original) +++ python/branches/py3k/Lib/inspect.py Fri Jan 11 17:17:00 2008 @@ -31,6 +31,7 @@ import sys, os, types, re, dis, imp, tokenize, linecache from operator import attrgetter +from collections import namedtuple # ----------------------------------------------------------- type-checking def ismodule(object): @@ -208,6 +209,8 @@ results.sort() return results +Attribute = namedtuple('Attribute', 'name kind defining_class object') + def classify_class_attrs(cls): """Return list of attribute-descriptor tuples. @@ -274,7 +277,7 @@ else: kind = "data" - result.append((name, kind, homecls, obj)) + result.append(Attribute(name, kind, homecls, obj)) return result @@ -362,6 +365,8 @@ raise TypeError('arg is not a module, class, method, ' 'function, traceback, frame, or code object') +ModuleInfo = namedtuple('ModuleInfo', 'name suffix mode module_type') + def getmoduleinfo(path): """Get the module name, suffix, mode, and module type for a given file.""" filename = os.path.basename(path) @@ -370,7 +375,7 @@ suffixes.sort() # try longest suffixes first, in case they overlap for neglen, suffix, mode, mtype in suffixes: if filename[neglen:] == suffix: - return filename[:neglen], suffix, mode, mtype + return ModuleInfo(filename[:neglen], suffix, mode, mtype) def getmodulename(path): """Return the module name for a given file, or None.""" @@ -668,6 +673,8 @@ # These constants are from Python's compile.h. CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 1, 2, 4, 8 +Arguments = namedtuple('Arguments', 'args, varargs, varkw') + def getargs(co): """Get information about the arguments accepted by a code object. @@ -676,7 +683,7 @@ lists. Keyword-only arguments are appended. 'varargs' and 'varkw' are the names of the * and ** arguments or None.""" args, varargs, kwonlyargs, varkw = _getfullargs(co) - return args + kwonlyargs, varargs, varkw + return Arguments(args + kwonlyargs, varargs, varkw) def _getfullargs(co): """Get information about the arguments accepted by a code object. @@ -706,6 +713,9 @@ varkw = co.co_varnames[nargs] return args, varargs, kwonlyargs, varkw + +ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults') + def getargspec(func): """Get the names and default values of a function's arguments. @@ -725,7 +735,10 @@ if kwonlyargs or ann: raise ValueError("Function has keyword-only arguments or annotations" ", use getfullargspec() API which can support them") - return (args, varargs, varkw, defaults) + return ArgSpec(args, varargs, varkw, defaults) + +FullArgSpec = namedtuple('FullArgSpec', + 'args, varargs, varkw, defaults, kwonlyargs, kwdefaults, annotations') def getfullargspec(func): """Get the names and default values of a function's arguments. @@ -747,9 +760,11 @@ if not isfunction(func): raise TypeError('arg is not a Python function') args, varargs, kwonlyargs, varkw = _getfullargs(func.__code__) - return (args, varargs, varkw, func.__defaults__, + return FullArgSpec(args, varargs, varkw, func.__defaults__, kwonlyargs, func.__kwdefaults__, func.__annotations__) +ArgInfo = namedtuple('ArgInfo', 'args varargs keywords locals') + def getargvalues(frame): """Get information about arguments passed into a particular frame. @@ -859,6 +874,9 @@ return '(' + ', '.join(specs) + ')' # -------------------------------------------------- stack frame extraction + +Traceback = namedtuple('Traceback', 'filename lineno function code_context index') + def getframeinfo(frame, context=1): """Get information about a frame or traceback object. @@ -890,7 +908,7 @@ else: lines = index = None - return (filename, lineno, frame.f_code.co_name, lines, index) + return Traceback(filename, lineno, frame.f_code.co_name, lines, index) def getlineno(frame): """Get the line number from a frame object, allowing for optimization.""" Modified: python/branches/py3k/Lib/test/test_collections.py ============================================================================== --- python/branches/py3k/Lib/test/test_collections.py (original) +++ python/branches/py3k/Lib/test/test_collections.py Fri Jan 11 17:17:00 2008 @@ -1,6 +1,6 @@ """Unit tests for collections.py.""" -import unittest +import unittest, doctest from test import test_support from collections import namedtuple from collections import Hashable, Iterable, Iterator @@ -316,10 +316,12 @@ self.failUnless(issubclass(sample, MutableSequence)) self.failIf(issubclass(str, MutableSequence)) +import doctest, collections +NamedTupleDocs = doctest.DocTestSuite(module=collections) def test_main(verbose=None): import collections as CollectionsModule - test_classes = [TestNamedTuple, TestOneTrickPonyABCs, TestCollectionABCs] + test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs, TestCollectionABCs] test_support.run_unittest(*test_classes) test_support.run_doctest(CollectionsModule, verbose) Modified: python/branches/py3k/Lib/test/test_doctest.py ============================================================================== --- python/branches/py3k/Lib/test/test_doctest.py (original) +++ python/branches/py3k/Lib/test/test_doctest.py Fri Jan 11 17:17:00 2008 @@ -658,7 +658,7 @@ of tried tests. >>> doctest.DocTestRunner(verbose=False).run(test) - (0, 3) + TestResults(failed=0, attempted=3) If any example produces incorrect output, then the test runner reports the failure and proceeds to the next example: @@ -695,7 +695,7 @@ Expecting: 6 ok - (1, 3) + TestResults(failed=1, attempted=3) """ def verbose_flag(): r""" The `verbose` flag makes the test runner generate more detailed @@ -726,7 +726,7 @@ Expecting: 6 ok - (0, 3) + TestResults(failed=0, attempted=3) If the `verbose` flag is unspecified, then the output will be verbose iff `-v` appears in sys.argv: @@ -737,7 +737,7 @@ >>> # If -v does not appear in sys.argv, then output isn't verbose. >>> sys.argv = ['test'] >>> doctest.DocTestRunner().run(test) - (0, 3) + TestResults(failed=0, attempted=3) >>> # If -v does appear in sys.argv, then output is verbose. >>> sys.argv = ['test', '-v'] @@ -756,7 +756,7 @@ Expecting: 6 ok - (0, 3) + TestResults(failed=0, attempted=3) >>> # Restore sys.argv >>> sys.argv = old_argv @@ -780,7 +780,7 @@ ... ''' >>> test = doctest.DocTestFinder().find(f)[0] >>> doctest.DocTestRunner(verbose=False).run(test) - (0, 2) + TestResults(failed=0, attempted=2) An example may not generate output before it raises an exception; if it does, then the traceback message will not be recognized as @@ -805,7 +805,7 @@ Exception raised: ... ZeroDivisionError: integer division or modulo by zero - (1, 2) + TestResults(failed=1, attempted=2) Exception messages may contain newlines: @@ -819,7 +819,7 @@ ... ''' >>> test = doctest.DocTestFinder().find(f)[0] >>> doctest.DocTestRunner(verbose=False).run(test) - (0, 1) + TestResults(failed=0, attempted=1) If an exception is expected, but an exception with the wrong type or message is raised, then it is reported as a failure: @@ -844,7 +844,7 @@ Traceback (most recent call last): ... ValueError: message - (1, 1) + TestResults(failed=1, attempted=1) However, IGNORE_EXCEPTION_DETAIL can be used to allow a mismatch in the detail: @@ -857,7 +857,7 @@ ... ''' >>> test = doctest.DocTestFinder().find(f)[0] >>> doctest.DocTestRunner(verbose=False).run(test) - (0, 1) + TestResults(failed=0, attempted=1) But IGNORE_EXCEPTION_DETAIL does not allow a mismatch in the exception type: @@ -881,7 +881,7 @@ Traceback (most recent call last): ... ValueError: message - (1, 1) + TestResults(failed=1, attempted=1) If an exception is raised but not expected, then it is reported as an unexpected exception: @@ -902,7 +902,7 @@ Traceback (most recent call last): ... ZeroDivisionError: integer division or modulo by zero - (1, 1) + TestResults(failed=1, attempted=1) """ def optionflags(): r""" Tests of `DocTestRunner`'s option flag handling. @@ -921,7 +921,7 @@ >>> # Without the flag: >>> test = doctest.DocTestFinder().find(f)[0] >>> doctest.DocTestRunner(verbose=False).run(test) - (0, 1) + TestResults(failed=0, attempted=1) >>> # With the flag: >>> test = doctest.DocTestFinder().find(f)[0] @@ -936,7 +936,7 @@ 1 Got: True - (1, 1) + TestResults(failed=1, attempted=1) The DONT_ACCEPT_BLANKLINE flag disables the match between blank lines and the '' marker: @@ -947,7 +947,7 @@ >>> # Without the flag: >>> test = doctest.DocTestFinder().find(f)[0] >>> doctest.DocTestRunner(verbose=False).run(test) - (0, 1) + TestResults(failed=0, attempted=1) >>> # With the flag: >>> test = doctest.DocTestFinder().find(f)[0] @@ -966,7 +966,7 @@ a b - (1, 1) + TestResults(failed=1, attempted=1) The NORMALIZE_WHITESPACE flag causes all sequences of whitespace to be treated as equal: @@ -987,13 +987,13 @@ 3 Got: 1 2 3 - (1, 1) + TestResults(failed=1, attempted=1) >>> # With the flag: >>> test = doctest.DocTestFinder().find(f)[0] >>> flags = doctest.NORMALIZE_WHITESPACE >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) - (0, 1) + TestResults(failed=0, attempted=1) An example from the docs: >>> print(list(range(20))) #doctest: +NORMALIZE_WHITESPACE @@ -1018,13 +1018,13 @@ [0, 1, 2, ..., 14] Got: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] - (1, 1) + TestResults(failed=1, attempted=1) >>> # With the flag: >>> test = doctest.DocTestFinder().find(f)[0] >>> flags = doctest.ELLIPSIS >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) - (0, 1) + TestResults(failed=0, attempted=1) ... also matches nothing: @@ -1109,7 +1109,7 @@ e f g - (1, 1) + TestResults(failed=1, attempted=1) >>> # With the flag: >>> test = doctest.DocTestFinder().find(f)[0] @@ -1131,7 +1131,7 @@ f g -h - (1, 1) + TestResults(failed=1, attempted=1) The REPORT_CDIFF flag causes failures that involve multi-line expected and actual outputs to be displayed using a context diff: @@ -1163,7 +1163,7 @@ + e f g - (1, 1) + TestResults(failed=1, attempted=1) The REPORT_NDIFF flag causes failures to use the difflib.Differ algorithm @@ -1188,7 +1188,7 @@ ? ^ + a b c d e f g h i j k l m ? + ++ ^ - (1, 1) + TestResults(failed=1, attempted=1) The REPORT_ONLY_FIRST_FAILURE supresses result output after the first failing example: @@ -1218,7 +1218,7 @@ 200 Got: 2 - (3, 5) + TestResults(failed=3, attempted=5) However, output from `report_start` is not supressed: @@ -1241,7 +1241,7 @@ 200 Got: 2 - (3, 5) + TestResults(failed=3, attempted=5) For the purposes of REPORT_ONLY_FIRST_FAILURE, unexpected exceptions count as failures: @@ -1270,7 +1270,7 @@ Exception raised: ... ValueError: 2 - (3, 5) + TestResults(failed=3, attempted=5) New option flags can also be registered, via register_optionflag(). Here we reach into doctest's internals a bit. @@ -1319,7 +1319,7 @@ [0, 1, ..., 9] Got: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - (1, 2) + TestResults(failed=1, attempted=2) To turn an option off for an example, follow that example with a comment of the form ``# doctest: -OPTION``: @@ -1344,7 +1344,7 @@ [0, 1, ..., 9] Got: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - (1, 2) + TestResults(failed=1, attempted=2) Option directives affect only the example that they appear with; they do not change the options for surrounding examples: @@ -1378,7 +1378,7 @@ [0, 1, ..., 9] Got: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - (2, 3) + TestResults(failed=2, attempted=3) Multiple options may be modified by a single option directive. They may be separated by whitespace, commas, or both: @@ -1401,7 +1401,7 @@ [0, 1, ..., 9] Got: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - (1, 2) + TestResults(failed=1, attempted=2) >>> def f(x): r''' ... >>> print(list(range(10))) # Should fail @@ -1421,7 +1421,7 @@ [0, 1, ..., 9] Got: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - (1, 2) + TestResults(failed=1, attempted=2) >>> def f(x): r''' ... >>> print(list(range(10))) # Should fail @@ -1441,7 +1441,7 @@ [0, 1, ..., 9] Got: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - (1, 2) + TestResults(failed=1, attempted=2) The option directive may be put on the line following the source, as long as a continuation prompt is used: @@ -1453,7 +1453,7 @@ ... ''' >>> test = doctest.DocTestFinder().find(f)[0] >>> doctest.DocTestRunner(verbose=False).run(test) - (0, 1) + TestResults(failed=0, attempted=1) For examples with multi-line source, the option directive may appear at the end of any line: @@ -1469,7 +1469,7 @@ ... ''' >>> test = doctest.DocTestFinder().find(f)[0] >>> doctest.DocTestRunner(verbose=False).run(test) - (0, 2) + TestResults(failed=0, attempted=2) If more than one line of an example with multi-line source has an option directive, then they are combined: @@ -1482,7 +1482,7 @@ ... ''' >>> test = doctest.DocTestFinder().find(f)[0] >>> doctest.DocTestRunner(verbose=False).run(test) - (0, 1) + TestResults(failed=0, attempted=1) It is an error to have a comment of the form ``# doctest:`` that is *not* followed by words of the form ``+OPTION`` or ``-OPTION``, where @@ -1616,7 +1616,7 @@ (Pdb) print(x) 42 (Pdb) continue - (0, 2) + TestResults(failed=0, attempted=2) You can also put pdb.set_trace in a function called from a test: @@ -1652,7 +1652,7 @@ (Pdb) print(x) 1 (Pdb) continue - (0, 2) + TestResults(failed=0, attempted=2) During interactive debugging, source code is shown, even for doctest examples: @@ -1709,7 +1709,7 @@ Expected nothing Got: 9 - (1, 3) + TestResults(failed=1, attempted=3) """ def test_pdb_set_trace_nested(): @@ -1795,7 +1795,7 @@ (Pdb) print(foo) *** NameError: NameError("name 'foo' is not defined",) (Pdb) continue - (0, 2) + TestResults(failed=0, attempted=2) """ def test_DocTestSuite(): @@ -2156,7 +2156,7 @@ 1 items had failures: 1 of 2 in test_doctest.txt ***Test Failed*** 1 failures. - (1, 2) + TestResults(failed=1, attempted=2) >>> doctest.master = None # Reset master. (Note: we'll be clearing doctest.master after each call to @@ -2167,7 +2167,7 @@ >>> globs = {'favorite_color': 'blue'} >>> doctest.testfile('test_doctest.txt', globs=globs) - (0, 2) + TestResults(failed=0, attempted=2) >>> doctest.master = None # Reset master. >>> extraglobs = {'favorite_color': 'red'} @@ -2185,7 +2185,7 @@ 1 items had failures: 1 of 2 in test_doctest.txt ***Test Failed*** 1 failures. - (1, 2) + TestResults(failed=1, attempted=2) >>> doctest.master = None # Reset master. The file may be made relative to a given module or package, using the @@ -2193,7 +2193,7 @@ >>> doctest.testfile('test_doctest.txt', globs=globs, ... module_relative='test') - (0, 2) + TestResults(failed=0, attempted=2) >>> doctest.master = None # Reset master. Verbosity can be increased with the optional `verbose` paremter: @@ -2219,7 +2219,7 @@ 2 tests in 1 items. 2 passed and 0 failed. Test passed. - (0, 2) + TestResults(failed=0, attempted=2) >>> doctest.master = None # Reset master. The name of the test may be specified with the optional `name` @@ -2230,7 +2230,7 @@ ********************************************************************** File "...", line 6, in newname ... - (1, 2) + TestResults(failed=1, attempted=2) >>> doctest.master = None # Reset master. The summary report may be supressed with the optional `report` @@ -2245,7 +2245,7 @@ Exception raised: ... NameError: name 'favorite_color' is not defined - (1, 2) + TestResults(failed=1, attempted=2) >>> doctest.master = None # Reset master. The optional keyword argument `raise_on_error` can be used to raise an @@ -2277,11 +2277,11 @@ 1 items had failures: 2 of 2 in test_doctest4.txt ***Test Failed*** 2 failures. - (2, 2) + TestResults(failed=2, attempted=2) >>> doctest.master = None # Reset master. >>> doctest.testfile('test_doctest4.txt', encoding='utf-8') - (0, 2) + TestResults(failed=0, attempted=2) >>> doctest.master = None # Reset master. """ @@ -2311,15 +2311,15 @@ 42 Got: 84 -(1, 2) +TestResults(failed=1, attempted=2) >>> t.runstring(">>> x = x * 2\n>>> print(x)\n84\n", 'example2') -(0, 2) +TestResults(failed=0, attempted=2) >>> t.summarize() ********************************************************************** 1 items had failures: 1 of 2 in XYZ ***Test Failed*** 1 failures. -(1, 4) +TestResults(failed=1, attempted=4) >>> t.summarize(verbose=1) 1 items passed all tests: 2 tests in example2 @@ -2329,7 +2329,7 @@ 4 tests in 2 items. 3 passed and 1 failed. ***Test Failed*** 1 failures. -(1, 4) +TestResults(failed=1, attempted=4) """ def old_test2(): r""" @@ -2353,7 +2353,7 @@ 3 ok 0 of 2 examples failed in string Example - (0, 2) + TestResults(failed=0, attempted=2) """ def old_test3(): r""" @@ -2366,7 +2366,7 @@ ... return 32 ... >>> t.rundoc(_f) # expect 0 failures in 1 example - (0, 1) + TestResults(failed=0, attempted=1) """ def old_test4(): """ @@ -2396,19 +2396,19 @@ >>> from doctest import Tester >>> t = Tester(globs={}, verbose=0) >>> t.rundict(m1.__dict__, "rundict_test", m1) # f2 and g2 and h2 skipped - (0, 4) + TestResults(failed=0, attempted=4) Once more, not excluding stuff outside m1: >>> t = Tester(globs={}, verbose=0) >>> t.rundict(m1.__dict__, "rundict_test_pvt") # None are skipped. - (0, 8) + TestResults(failed=0, attempted=8) The exclusion of objects from outside the designated module is meant to be invoked automagically by testmod. >>> doctest.testmod(m1, verbose=False) - (0, 4) + TestResults(failed=0, attempted=4) """ ###################################################################### Modified: python/branches/py3k/Lib/test/test_pyclbr.py ============================================================================== --- python/branches/py3k/Lib/test/test_pyclbr.py (original) +++ python/branches/py3k/Lib/test/test_pyclbr.py Fri Jan 11 17:17:00 2008 @@ -40,7 +40,7 @@ if key in ignore: return if key not in obj: print("***",key, file=sys.stderr) - self.failUnless(key in obj) + self.failUnless(key in obj, "%r in %r" % (key, obj)) def assertEqualsOrIgnored(self, a, b, ignore): ''' succeed iff a == b or a in ignore or b in ignore ''' @@ -140,9 +140,9 @@ def test_easy(self): self.checkModule('pyclbr') - self.checkModule('doctest') + self.checkModule('doctest', ignore=("TestResults",)) self.checkModule('rfc822') - self.checkModule('difflib') + self.checkModule('difflib', ignore=("Match",)) def test_decorators(self): # XXX: See comment in pyclbr_input.py for a test that would fail Modified: python/branches/py3k/Lib/test/test_re.py ============================================================================== --- python/branches/py3k/Lib/test/test_re.py (original) +++ python/branches/py3k/Lib/test/test_re.py Fri Jan 11 17:17:00 2008 @@ -661,6 +661,18 @@ q = p.match(upper_char) self.assertNotEqual(q, None) + def test_dollar_matches_twice(self): + "$ matches the end of string, and just before the terminating \n" + pattern = re.compile('$') + self.assertEqual(pattern.sub('#', 'a\nb\n'), 'a\nb#\n#') + self.assertEqual(pattern.sub('#', 'a\nb\nc'), 'a\nb\nc#') + self.assertEqual(pattern.sub('#', '\n'), '#\n#') + + pattern = re.compile('$', re.MULTILINE) + self.assertEqual(pattern.sub('#', 'a\nb\n' ), 'a#\nb#\n#' ) + self.assertEqual(pattern.sub('#', 'a\nb\nc'), 'a#\nb#\nc#') + self.assertEqual(pattern.sub('#', '\n'), '#\n#') + def run_re_tests(): from test.re_tests import benchmarks, tests, SUCCEED, FAIL, SYNTAX_ERROR Modified: python/branches/py3k/Modules/mmapmodule.c ============================================================================== --- python/branches/py3k/Modules/mmapmodule.c (original) +++ python/branches/py3k/Modules/mmapmodule.c Fri Jan 11 17:17:00 2008 @@ -980,9 +980,11 @@ #ifdef HAVE_FSTAT # ifdef __VMS /* on OpenVMS we must ensure that all bytes are written to the file */ - fsync(fd); + if (fd != -1) { + fsync(fd); + } # endif - if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) { + if (fd != -1 && fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) { if (map_size == 0) { map_size = st.st_size; } else if ((size_t)offset + (size_t)map_size > st.st_size) { Modified: python/branches/py3k/Modules/socketmodule.c ============================================================================== --- python/branches/py3k/Modules/socketmodule.c (original) +++ python/branches/py3k/Modules/socketmodule.c Fri Jan 11 17:17:00 2008 @@ -4097,7 +4097,7 @@ PyMODINIT_FUNC init_socket(void) { - PyObject *m, *has_ipv6, *tmp; + PyObject *m, *has_ipv6; if (!os_init()) return; @@ -4354,7 +4354,10 @@ /* for subscriptions */ PyModule_AddIntConstant(m, "TIPC_SUB_PORTS", TIPC_SUB_PORTS); PyModule_AddIntConstant(m, "TIPC_SUB_SERVICE", TIPC_SUB_SERVICE); +#ifdef TIPC_SUB_CANCEL + /* doesn't seem to be available everywhere */ PyModule_AddIntConstant(m, "TIPC_SUB_CANCEL", TIPC_SUB_CANCEL); +#endif PyModule_AddIntConstant(m, "TIPC_WAIT_FOREVER", TIPC_WAIT_FOREVER); PyModule_AddIntConstant(m, "TIPC_PUBLISHED", TIPC_PUBLISHED); PyModule_AddIntConstant(m, "TIPC_WITHDRAWN", TIPC_WITHDRAWN); Modified: python/branches/py3k/PCbuild/build_tkinter.py ============================================================================== --- python/branches/py3k/PCbuild/build_tkinter.py (original) +++ python/branches/py3k/PCbuild/build_tkinter.py Fri Jan 11 17:17:00 2008 @@ -25,7 +25,7 @@ # Windows 2000 compatibility: WINVER 0x0500 # http://msdn2.microsoft.com/en-us/library/aa383745.aspx NMAKE = ('nmake /nologo /f %s ' - 'COMPILERFLAGS=\"-DWINVER=0x0500 -D_WIN32_WINNT=0x0500 -DNTDDI_VERSION=NTDDI_WIN2KSP4\"' + 'COMPILERFLAGS=\"-DWINVER=0x0500 -D_WIN32_WINNT=0x0500 -DNTDDI_VERSION=NTDDI_WIN2KSP4\" ' '%s %s') def nmake(makefile, command="", **kw): Modified: python/branches/py3k/PCbuild/readme.txt ============================================================================== --- python/branches/py3k/PCbuild/readme.txt (original) +++ python/branches/py3k/PCbuild/readme.txt Fri Jan 11 17:17:00 2008 @@ -117,7 +117,7 @@ Build with build_tkinter.py --------------------------- The PCbuild directory contains a Python script which automates all - steps. Run the script in a Visual Studio 2009 command prompt with + steps. Run the script in a Visual Studio 2008 command prompt with python build_tkinter.py Win32 @@ -312,9 +312,11 @@ Profile Guided Optimization --------------------------- -The solution has two configurations for PGO. The PGInstrument configuration -must be build first. The PGInstrument binaries are lniked against a profiling -library and contain extra debug information. The PGUpdate configuration takes the profiling data and generates optimized binaries. +The solution has two configurations for PGO. The PGInstrument +configuration must be build first. The PGInstrument binaries are +lniked against a profiling library and contain extra debug +information. The PGUpdate configuration takes the profiling data and +generates optimized binaries. The build_pgo.bat script automates the creation of optimized binaries. It creates the PGI files, runs the unit test suite or PyBench with the PGI From python-3000-checkins at python.org Fri Jan 11 17:48:06 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Fri, 11 Jan 2008 17:48:06 +0100 (CET) Subject: [Python-3000-checkins] r59922 - in python/branches/py3k-importhook: Doc/glossary.rst Doc/library/collections.rst Doc/library/decimal.rst Doc/library/difflib.rst Doc/library/doctest.rst Doc/library/inspect.rst Doc/library/re.rst Doc/library/string.rst Lib/collections.py Lib/decimal.py Lib/difflib.py Lib/doctest.py Lib/inspect.py Lib/test/test_builtin.py Lib/test/test_collections.py Lib/test/test_doctest.py Lib/test/test_import.py Lib/test/test_pyclbr.py Lib/test/test_re.py Modules/mmapmodule.c Modules/socketmodule.c Objects/typeobject.c PCbuild/build_tkinter.py PCbuild/readme.txt Python/import.c Message-ID: <20080111164806.DD55E1E400C@bag.python.org> Author: christian.heimes Date: Fri Jan 11 17:48:05 2008 New Revision: 59922 Modified: python/branches/py3k-importhook/ (props changed) python/branches/py3k-importhook/Doc/glossary.rst python/branches/py3k-importhook/Doc/library/collections.rst python/branches/py3k-importhook/Doc/library/decimal.rst python/branches/py3k-importhook/Doc/library/difflib.rst python/branches/py3k-importhook/Doc/library/doctest.rst python/branches/py3k-importhook/Doc/library/inspect.rst python/branches/py3k-importhook/Doc/library/re.rst python/branches/py3k-importhook/Doc/library/string.rst python/branches/py3k-importhook/Lib/collections.py python/branches/py3k-importhook/Lib/decimal.py python/branches/py3k-importhook/Lib/difflib.py python/branches/py3k-importhook/Lib/doctest.py python/branches/py3k-importhook/Lib/inspect.py python/branches/py3k-importhook/Lib/test/test_builtin.py python/branches/py3k-importhook/Lib/test/test_collections.py python/branches/py3k-importhook/Lib/test/test_doctest.py python/branches/py3k-importhook/Lib/test/test_import.py python/branches/py3k-importhook/Lib/test/test_pyclbr.py python/branches/py3k-importhook/Lib/test/test_re.py python/branches/py3k-importhook/Modules/mmapmodule.c python/branches/py3k-importhook/Modules/socketmodule.c python/branches/py3k-importhook/Objects/typeobject.c python/branches/py3k-importhook/PCbuild/build_tkinter.py python/branches/py3k-importhook/PCbuild/readme.txt python/branches/py3k-importhook/Python/import.c Log: Merged revisions 59884-59921 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r59889 | christian.heimes | 2008-01-10 17:02:19 +0100 (Thu, 10 Jan 2008) | 1 line Fixed print -> print() ................ r59899 | eric.smith | 2008-01-11 01:17:22 +0100 (Fri, 11 Jan 2008) | 1 line Simplifed argument parsing in object.__format__, added test case. ................ r59901 | eric.smith | 2008-01-11 01:32:16 +0100 (Fri, 11 Jan 2008) | 1 line Added the test cases I actually meant to add. ................ r59908 | christian.heimes | 2008-01-11 08:03:05 +0100 (Fri, 11 Jan 2008) | 2 lines Good catch Neal! I completely forgot about pyo files and the tests are usually not run with -O. The modified code checks for *.py? ................ r59914 | georg.brandl | 2008-01-11 13:58:40 +0100 (Fri, 11 Jan 2008) | 2 lines Fix markup. ................ r59921 | christian.heimes | 2008-01-11 17:17:00 +0100 (Fri, 11 Jan 2008) | 100 lines Merged revisions 59883-59920 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r59887 | neal.norwitz | 2008-01-10 06:42:58 +0100 (Thu, 10 Jan 2008) | 1 line Reword entry, not sure I made it much better though. ........ r59888 | andrew.kuchling | 2008-01-10 14:37:12 +0100 (Thu, 10 Jan 2008) | 1 line Check for fd of -1 to save fsync() and fstat() call ........ r59891 | thomas.heller | 2008-01-10 19:45:40 +0100 (Thu, 10 Jan 2008) | 1 line Reflow a paragraph, and fix a typo. ........ r59892 | raymond.hettinger | 2008-01-10 20:15:10 +0100 (Thu, 10 Jan 2008) | 1 line Examples for named tuple subclassing should include __slots__ ........ r59895 | raymond.hettinger | 2008-01-10 21:37:12 +0100 (Thu, 10 Jan 2008) | 1 line Clarify how to add a field to a named tuple. ........ r59896 | amaury.forgeotdarc | 2008-01-10 22:59:42 +0100 (Thu, 10 Jan 2008) | 12 lines Closing issue1761. Surprising behaviour of the "$" regexp: it matches the end of the string, AND just before the newline at the end of the string:: re.sub('$', '#', 'foo\n') == 'foo#\n#' Python is consistent with Perl and the pcre library, so we just document it. Guido prefers "\Z" to match only the end of the string. ........ r59898 | raymond.hettinger | 2008-01-11 00:00:01 +0100 (Fri, 11 Jan 2008) | 1 line Neaten-up the named tuple docs ........ r59900 | raymond.hettinger | 2008-01-11 01:23:13 +0100 (Fri, 11 Jan 2008) | 1 line Run doctests on the collections module ........ r59903 | raymond.hettinger | 2008-01-11 02:25:54 +0100 (Fri, 11 Jan 2008) | 1 line Doctest results return a named tuple for readability ........ r59904 | raymond.hettinger | 2008-01-11 03:12:33 +0100 (Fri, 11 Jan 2008) | 1 line Comment-out missing constant (from rev 59819) ........ r59905 | raymond.hettinger | 2008-01-11 03:24:13 +0100 (Fri, 11 Jan 2008) | 1 line Have Decimal.as_tuple return a named tuple. ........ r59906 | raymond.hettinger | 2008-01-11 04:04:50 +0100 (Fri, 11 Jan 2008) | 1 line Let most inspect functions return named tuples ........ r59907 | raymond.hettinger | 2008-01-11 04:20:54 +0100 (Fri, 11 Jan 2008) | 1 line Improve usability of the SequenceMatcher by returning named tuples describing match ranges. ........ r59909 | thomas.heller | 2008-01-11 09:04:03 +0100 (Fri, 11 Jan 2008) | 1 line Add an important missing blank. ........ r59910 | georg.brandl | 2008-01-11 10:19:11 +0100 (Fri, 11 Jan 2008) | 2 lines Guard definition of TIPC_SUB_CANCEL with an #ifdef. ........ r59911 | georg.brandl | 2008-01-11 10:20:58 +0100 (Fri, 11 Jan 2008) | 2 lines News entries for rev. 5990[567]. ........ r59912 | georg.brandl | 2008-01-11 10:55:53 +0100 (Fri, 11 Jan 2008) | 2 lines Documentation for r5990[3567]. ........ r59913 | thomas.heller | 2008-01-11 13:41:39 +0100 (Fri, 11 Jan 2008) | 4 lines The sqlite3 dll, when compiled in debug mode, must be linked with /MDd to use the debug runtime library. Further, the dll will be named sqlite3_d.dll. ........ r59919 | thomas.heller | 2008-01-11 16:38:46 +0100 (Fri, 11 Jan 2008) | 6 lines Revert revision 59913, because it was wrong: The sqlite3 dll, when compiled in debug mode, must be linked with /MDd to use the debug runtime library. Further, the dll will be named sqlite3_d.dll. ........ r59920 | christian.heimes | 2008-01-11 16:42:29 +0100 (Fri, 11 Jan 2008) | 1 line Removed unused variable ........ ................ Modified: python/branches/py3k-importhook/Doc/glossary.rst ============================================================================== --- python/branches/py3k-importhook/Doc/glossary.rst (original) +++ python/branches/py3k-importhook/Doc/glossary.rst Fri Jan 11 17:48:05 2008 @@ -327,6 +327,13 @@ mutable Mutable objects can change their value but keep their :func:`id`. See also :term:`immutable`. + + named tuple + A tuple subclass whose elements also are accessible as attributes via + fixed names (the class name and field names are indicated in the + individual documentation of a named tuple type, like ``TestResults(failed, + attempted)``). Named tuple classes are created by + :func:`collections.namedtuple`. namespace The place where a variable is stored. Namespaces are implemented as Modified: python/branches/py3k-importhook/Doc/library/collections.rst ============================================================================== --- python/branches/py3k-importhook/Doc/library/collections.rst (original) +++ python/branches/py3k-importhook/Doc/library/collections.rst Fri Jan 11 17:48:05 2008 @@ -397,8 +397,8 @@ method which lists the tuple contents in a ``name=value`` format. The *fieldnames* are a single string with each fieldname separated by whitespace - and/or commas (for example 'x y' or 'x, y'). Alternatively, *fieldnames* - can be a sequence of strings (such as ['x', 'y']). + and/or commas, for example ``'x y'`` or ``'x, y'``. Alternatively, *fieldnames* + can be a sequence of strings such as ``['x', 'y']``. Any valid Python identifier may be used for a fieldname except for names starting with an underscore. Valid identifiers consist of letters, digits, @@ -406,7 +406,7 @@ a :mod:`keyword` such as *class*, *for*, *return*, *global*, *pass*, *print*, or *raise*. - If *verbose* is true, will print the class definition. + If *verbose* is true, the class definition is printed just before being built. Named tuple instances do not have per-instance dictionaries, so they are lightweight and require no more memory than regular tuples. @@ -474,7 +474,7 @@ cursor = conn.cursor() cursor.execute('SELECT name, age, title, department, paygrade FROM employees') for emp in map(EmployeeRecord._make, cursor.fetchall()): - print emp.name, emp.title + print(emp.name, emp.title) In addition to the methods inherited from tuples, named tuples support three additional methods and one attribute. To prevent conflicts with @@ -533,7 +533,7 @@ >>> getattr(p, 'x') 11 -To cast a dictionary to a named tuple, use the double-star-operator [#]_:: +To convert a dictionary to a named tuple, use the double-star-operator [#]_:: >>> d = {'x': 11, 'y': 22} >>> Point(**d) @@ -544,23 +544,24 @@ a fixed-width print format:: >>> class Point(namedtuple('Point', 'x y')): + ... __slots__ = () ... @property ... def hypot(self): ... return (self.x ** 2 + self.y ** 2) ** 0.5 ... def __str__(self): - ... return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) + ... return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) - >>> for p in Point(3,4), Point(14,5), Point(9./7,6): - ... print p + >>> for p in Point(3, 4), Point(14, 5/7.): + ... print(p) - Point: x= 3.000 y= 4.000 hypot= 5.000 - Point: x=14.000 y= 5.000 hypot=14.866 - Point: x= 1.286 y= 6.000 hypot= 6.136 + Point: x= 3.000 y= 4.000 hypot= 5.000 + Point: x=14.000 y= 0.714 hypot=14.018 Another use for subclassing is to replace performance critcal methods with -faster versions that bypass error-checking and that localize variable access:: +faster versions that bypass error-checking:: class Point(namedtuple('Point', 'x y')): + __slots__ = () _make = classmethod(tuple.__new__) def _replace(self, _map=map, **kwds): return self._make(_map(kwds.get, ('x', 'y'), self)) @@ -569,7 +570,7 @@ Subclassing is not useful for adding new, stored fields. Instead, simply create a new named tuple type from the :attr:`_fields` attribute:: - >>> Pixel = namedtuple('Pixel', Point._fields + Color._fields) + >>> Point3D = namedtuple('Point3D', Point._fields + ('z',)) Default values can be implemented by using :meth:`_replace` to customize a prototype instance:: Modified: python/branches/py3k-importhook/Doc/library/decimal.rst ============================================================================== --- python/branches/py3k-importhook/Doc/library/decimal.rst (original) +++ python/branches/py3k-importhook/Doc/library/decimal.rst Fri Jan 11 17:48:05 2008 @@ -328,7 +328,11 @@ .. method:: Decimal.as_tuple() - Return a tuple representation of the number: ``(sign, digit_tuple, exponent)``. + Return a :term:`named tuple` representation of the number: + ``DecimalTuple(sign, digits, exponent)``. + + .. versionchanged:: 2.6 + Use a named tuple. .. method:: Decimal.canonical() Modified: python/branches/py3k-importhook/Doc/library/difflib.rst ============================================================================== --- python/branches/py3k-importhook/Doc/library/difflib.rst (original) +++ python/branches/py3k-importhook/Doc/library/difflib.rst Fri Jan 11 17:48:05 2008 @@ -336,7 +336,7 @@ Find longest matching block in ``a[alo:ahi]`` and ``b[blo:bhi]``. - If *isjunk* was omitted or ``None``, :meth:`get_longest_match` returns ``(i, j, + If *isjunk* was omitted or ``None``, :meth:`find_longest_match` returns ``(i, j, k)`` such that ``a[i:i+k]`` is equal to ``b[j:j+k]``, where ``alo <= i <= i+k <= ahi`` and ``blo <= j <= j+k <= bhi``. For all ``(i', j', k')`` meeting those conditions, the additional conditions ``k >= k'``, ``i <= i'``, and if ``i == @@ -365,6 +365,9 @@ If no blocks match, this returns ``(alo, blo, 0)``. + .. versionchanged:: 2.6 + This method returns a :term:`named tuple` ``Match(a, b, size)``. + .. method:: SequenceMatcher.get_matching_blocks() Modified: python/branches/py3k-importhook/Doc/library/doctest.rst ============================================================================== --- python/branches/py3k-importhook/Doc/library/doctest.rst (original) +++ python/branches/py3k-importhook/Doc/library/doctest.rst Fri Jan 11 17:48:05 2008 @@ -1436,11 +1436,14 @@ .. method:: DocTestRunner.summarize([verbose]) Print a summary of all the test cases that have been run by this DocTestRunner, - and return a tuple ``(failure_count, test_count)``. + and return a :term:`named tuple` ``TestResults(failed, attempted)``. The optional *verbose* argument controls how detailed the summary is. If the verbosity is not specified, then the :class:`DocTestRunner`'s verbosity is used. + .. versionchanged:: 2.6 + Use a named tuple. + .. _doctest-outputchecker: Modified: python/branches/py3k-importhook/Doc/library/inspect.rst ============================================================================== --- python/branches/py3k-importhook/Doc/library/inspect.rst (original) +++ python/branches/py3k-importhook/Doc/library/inspect.rst Fri Jan 11 17:48:05 2008 @@ -188,7 +188,8 @@ .. function:: getmoduleinfo(path) - Return a tuple of values that describe how Python will interpret the file + Returns a :term:`named tuple` ``ModuleInfo(name, suffix, mode, + module_type)`` of values that describe how Python will interpret the file identified by *path* if it is a module, or ``None`` if it would not be identified as a module. The return tuple is ``(name, suffix, mode, mtype)``, where *name* is the name of the module without the name of any enclosing @@ -377,8 +378,9 @@ .. function:: getargspec(func) - Get the names and default values of a function's arguments. A tuple of four - things is returned: ``(args, varargs, varkw, defaults)``. *args* is a list of + Get the names and default values of a function's arguments. A + :term:`named tuple` ``ArgSpec(args, varargs, keywords, + defaults)`` is returned. *args* is a list of the argument names. *varargs* and *varkw* are the names of the ``*`` and ``**`` arguments or ``None``. *defaults* is a tuple of default argument values or None if there are no default arguments; if this tuple has *n* @@ -391,10 +393,10 @@ .. function:: getfullargspec(func) - Get the names and default values of a function's arguments. A tuple of seven - things is returned: + Get the names and default values of a function's arguments. A :term:`named tuple` + is returned: - ``(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations)`` + ``FullArgSpec(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations)`` *args* is a list of the argument names. *varargs* and *varkw* are the names of the ``*`` and ``**`` arguments or ``None``. *defaults* is an n-tuple of @@ -408,8 +410,8 @@ .. function:: getargvalues(frame) - Get information about arguments passed into a particular frame. A tuple of four - things is returned: ``(args, varargs, varkw, locals)``. *args* is a list of the + Get information about arguments passed into a particular frame. A :term:`named tuple` + ``ArgInfo(args, varargs, keywords, locals)`` is returned. *args* is a list of the argument names (it may contain nested lists). *varargs* and *varkw* are the names of the ``*`` and ``**`` arguments or ``None``. *locals* is the locals dictionary of the given frame. @@ -476,8 +478,8 @@ .. function:: getframeinfo(frame[, context]) - Get information about a frame or traceback object. A 5-tuple is returned, the - last five elements of the frame's frame record. + Get information about a frame or traceback object. A :term:`named tuple` + ``Traceback(filename, lineno, function, code_context, index)`` is returned. .. function:: getouterframes(frame[, context]) Modified: python/branches/py3k-importhook/Doc/library/re.rst ============================================================================== --- python/branches/py3k-importhook/Doc/library/re.rst (original) +++ python/branches/py3k-importhook/Doc/library/re.rst Fri Jan 11 17:48:05 2008 @@ -98,7 +98,9 @@ string, and in :const:`MULTILINE` mode also matches before a newline. ``foo`` matches both 'foo' and 'foobar', while the regular expression ``foo$`` matches only 'foo'. More interestingly, searching for ``foo.$`` in ``'foo1\nfoo2\n'`` - matches 'foo2' normally, but 'foo1' in :const:`MULTILINE` mode. + matches 'foo2' normally, but 'foo1' in :const:`MULTILINE` mode; searching for + a single ``$`` in ``'foo\n'`` will find two (empty) matches: one just before + the newline, and one at the end of the string. ``'*'`` Causes the resulting RE to match 0 or more repetitions of the preceding RE, as Modified: python/branches/py3k-importhook/Doc/library/string.rst ============================================================================== --- python/branches/py3k-importhook/Doc/library/string.rst (original) +++ python/branches/py3k-importhook/Doc/library/string.rst Fri Jan 11 17:48:05 2008 @@ -230,8 +230,8 @@ value to a string before calling :meth:`__format__`, the normal formatting logic is bypassed. -Two conversion flags are currently supported: ``'!s'`` which calls :func:`str()` -on the value, and ``'!r'`` which calls :func:`repr()`. +Two conversion flags are currently supported: ``'!s'`` which calls :func:`str` +on the value, and ``'!r'`` which calls :func:`repr`. Some examples:: @@ -289,7 +289,7 @@ although some of the formatting options are only supported by the numeric types. A general convention is that an empty format string (``""``) produces the same -result as if you had called :func:`str()` on the value. +result as if you had called :func:`str` on the value. The general form of a *standard format specifier* is: Modified: python/branches/py3k-importhook/Lib/collections.py ============================================================================== --- python/branches/py3k-importhook/Lib/collections.py (original) +++ python/branches/py3k-importhook/Lib/collections.py Fri Jan 11 17:48:05 2008 @@ -117,23 +117,28 @@ # test and demonstrate ability to override methods class Point(namedtuple('Point', 'x y')): + __slots__ = () @property def hypot(self): return (self.x ** 2 + self.y ** 2) ** 0.5 def __str__(self): - return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) + return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) - for p in Point(3,4), Point(14,5), Point(9./7,6): + for p in Point(3, 4), Point(14, 5/7.): print (p) class Point(namedtuple('Point', 'x y')): 'Point class with optimized _make() and _replace() without error-checking' + __slots__ = () _make = classmethod(tuple.__new__) def _replace(self, _map=map, **kwds): return self._make(_map(kwds.get, ('x', 'y'), self)) print(Point(11, 22)._replace(x=100)) + Point3D = namedtuple('Point3D', Point._fields + ('z',)) + print(Point3D.__doc__) + import doctest TestResults = namedtuple('TestResults', 'failed attempted') print(TestResults(*doctest.testmod())) Modified: python/branches/py3k-importhook/Lib/decimal.py ============================================================================== --- python/branches/py3k-importhook/Lib/decimal.py (original) +++ python/branches/py3k-importhook/Lib/decimal.py Fri Jan 11 17:48:05 2008 @@ -137,6 +137,12 @@ import numbers as _numbers import copy as _copy +try: + from collections import namedtuple as _namedtuple + DecimalTuple = _namedtuple('DecimalTuple', 'sign digits exponent') +except ImportError: + DecimalTuple = lambda *args: args + # Rounding ROUND_DOWN = 'ROUND_DOWN' ROUND_HALF_UP = 'ROUND_HALF_UP' @@ -841,7 +847,7 @@ To show the internals exactly as they are. """ - return (self._sign, tuple(map(int, self._int)), self._exp) + return DecimalTuple(self._sign, tuple(map(int, self._int)), self._exp) def __repr__(self): """Represents the number as an instance of Decimal.""" Modified: python/branches/py3k-importhook/Lib/difflib.py ============================================================================== --- python/branches/py3k-importhook/Lib/difflib.py (original) +++ python/branches/py3k-importhook/Lib/difflib.py Fri Jan 11 17:48:05 2008 @@ -30,9 +30,12 @@ __all__ = ['get_close_matches', 'ndiff', 'restore', 'SequenceMatcher', 'Differ','IS_CHARACTER_JUNK', 'IS_LINE_JUNK', 'context_diff', - 'unified_diff', 'HtmlDiff'] + 'unified_diff', 'HtmlDiff', 'Match'] import heapq +from collections import namedtuple as _namedtuple + +Match = _namedtuple('Match', 'a b size') def _calculate_ratio(matches, length): if length: @@ -363,7 +366,7 @@ >>> s = SequenceMatcher(None, " abcd", "abcd abcd") >>> s.find_longest_match(0, 5, 0, 9) - (0, 4, 5) + Match(a=0, b=4, size=5) If isjunk is defined, first the longest matching block is determined as above, but with the additional restriction that no @@ -379,13 +382,13 @@ >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd") >>> s.find_longest_match(0, 5, 0, 9) - (1, 0, 4) + Match(a=1, b=0, size=4) If no blocks match, return (alo, blo, 0). >>> s = SequenceMatcher(None, "ab", "c") >>> s.find_longest_match(0, 2, 0, 1) - (0, 0, 0) + Match(a=0, b=0, size=0) """ # CAUTION: stripping common prefix or suffix would be incorrect. @@ -452,7 +455,7 @@ a[besti+bestsize] == b[bestj+bestsize]: bestsize = bestsize + 1 - return besti, bestj, bestsize + return Match(besti, bestj, bestsize) def get_matching_blocks(self): """Return list of triples describing matching subsequences. @@ -469,8 +472,8 @@ triple with n==0. >>> s = SequenceMatcher(None, "abxcd", "abcd") - >>> s.get_matching_blocks() - [(0, 0, 2), (3, 2, 2), (5, 4, 0)] + >>> list(s.get_matching_blocks()) + [Match(a=0, b=0, size=2), Match(a=3, b=2, size=2), Match(a=5, b=4, size=0)] """ if self.matching_blocks is not None: @@ -523,7 +526,7 @@ non_adjacent.append( (la, lb, 0) ) self.matching_blocks = non_adjacent - return self.matching_blocks + return map(Match._make, self.matching_blocks) def get_opcodes(self): """Return list of 5-tuples describing how to turn a into b. Modified: python/branches/py3k-importhook/Lib/doctest.py ============================================================================== --- python/branches/py3k-importhook/Lib/doctest.py (original) +++ python/branches/py3k-importhook/Lib/doctest.py Fri Jan 11 17:48:05 2008 @@ -99,6 +99,9 @@ import unittest, difflib, pdb, tempfile import warnings from io import StringIO +from collections import namedtuple + +TestResults = namedtuple('TestResults', 'failed attempted') # There are 4 basic classes: # - Example: a pair, plus an intra-docstring line number. @@ -1024,10 +1027,10 @@ >>> tests.sort(key = lambda test: test.name) >>> for test in tests: ... print(test.name, '->', runner.run(test)) - _TestClass -> (0, 2) - _TestClass.__init__ -> (0, 2) - _TestClass.get -> (0, 2) - _TestClass.square -> (0, 1) + _TestClass -> TestResults(failed=0, attempted=2) + _TestClass.__init__ -> TestResults(failed=0, attempted=2) + _TestClass.get -> TestResults(failed=0, attempted=2) + _TestClass.square -> TestResults(failed=0, attempted=1) The `summarize` method prints a summary of all the test cases that have been run by the runner, and returns an aggregated `(f, t)` @@ -1042,7 +1045,7 @@ 7 tests in 4 items. 7 passed and 0 failed. Test passed. - (0, 7) + TestResults(failed=0, attempted=7) The aggregated number of tried examples and failed examples is also available via the `tries` and `failures` attributes: @@ -1285,7 +1288,7 @@ # Record and return the number of failures and tries. self.__record_outcome(test, failures, tries) - return failures, tries + return TestResults(failures, tries) def __record_outcome(self, test, f, t): """ @@ -1417,7 +1420,7 @@ print("***Test Failed***", totalf, "failures.") elif verbose: print("Test passed.") - return totalf, totalt + return TestResults(totalf, totalt) #///////////////////////////////////////////////////////////////// # Backward compatibility cruft to maintain doctest.master. @@ -1688,7 +1691,7 @@ ... ''', {}, 'foo', 'foo.py', 0) >>> runner.run(test) - (0, 1) + TestResults(failed=0, attempted=1) >>> test.globs {} @@ -1818,7 +1821,7 @@ else: master.merge(runner) - return runner.failures, runner.tries + return TestResults(runner.failures, runner.tries) def testfile(filename, module_relative=True, name=None, package=None, globs=None, verbose=None, report=True, optionflags=0, @@ -1939,7 +1942,7 @@ else: master.merge(runner) - return runner.failures, runner.tries + return TestResults(runner.failures, runner.tries) def run_docstring_examples(f, globs, verbose=False, name="NoName", compileflags=None, optionflags=0): @@ -1998,7 +2001,7 @@ (f,t) = self.testrunner.run(test) if self.verbose: print(f, "of", t, "examples failed in string", name) - return (f,t) + return TestResults(f,t) def rundoc(self, object, name=None, module=None): f = t = 0 @@ -2007,7 +2010,7 @@ for test in tests: (f2, t2) = self.testrunner.run(test) (f,t) = (f+f2, t+t2) - return (f,t) + return TestResults(f,t) def rundict(self, d, name, module=None): import types Modified: python/branches/py3k-importhook/Lib/inspect.py ============================================================================== --- python/branches/py3k-importhook/Lib/inspect.py (original) +++ python/branches/py3k-importhook/Lib/inspect.py Fri Jan 11 17:48:05 2008 @@ -31,6 +31,7 @@ import sys, os, types, re, dis, imp, tokenize, linecache from operator import attrgetter +from collections import namedtuple # ----------------------------------------------------------- type-checking def ismodule(object): @@ -208,6 +209,8 @@ results.sort() return results +Attribute = namedtuple('Attribute', 'name kind defining_class object') + def classify_class_attrs(cls): """Return list of attribute-descriptor tuples. @@ -274,7 +277,7 @@ else: kind = "data" - result.append((name, kind, homecls, obj)) + result.append(Attribute(name, kind, homecls, obj)) return result @@ -362,6 +365,8 @@ raise TypeError('arg is not a module, class, method, ' 'function, traceback, frame, or code object') +ModuleInfo = namedtuple('ModuleInfo', 'name suffix mode module_type') + def getmoduleinfo(path): """Get the module name, suffix, mode, and module type for a given file.""" filename = os.path.basename(path) @@ -370,7 +375,7 @@ suffixes.sort() # try longest suffixes first, in case they overlap for neglen, suffix, mode, mtype in suffixes: if filename[neglen:] == suffix: - return filename[:neglen], suffix, mode, mtype + return ModuleInfo(filename[:neglen], suffix, mode, mtype) def getmodulename(path): """Return the module name for a given file, or None.""" @@ -668,6 +673,8 @@ # These constants are from Python's compile.h. CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 1, 2, 4, 8 +Arguments = namedtuple('Arguments', 'args, varargs, varkw') + def getargs(co): """Get information about the arguments accepted by a code object. @@ -676,7 +683,7 @@ lists. Keyword-only arguments are appended. 'varargs' and 'varkw' are the names of the * and ** arguments or None.""" args, varargs, kwonlyargs, varkw = _getfullargs(co) - return args + kwonlyargs, varargs, varkw + return Arguments(args + kwonlyargs, varargs, varkw) def _getfullargs(co): """Get information about the arguments accepted by a code object. @@ -706,6 +713,9 @@ varkw = co.co_varnames[nargs] return args, varargs, kwonlyargs, varkw + +ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults') + def getargspec(func): """Get the names and default values of a function's arguments. @@ -725,7 +735,10 @@ if kwonlyargs or ann: raise ValueError("Function has keyword-only arguments or annotations" ", use getfullargspec() API which can support them") - return (args, varargs, varkw, defaults) + return ArgSpec(args, varargs, varkw, defaults) + +FullArgSpec = namedtuple('FullArgSpec', + 'args, varargs, varkw, defaults, kwonlyargs, kwdefaults, annotations') def getfullargspec(func): """Get the names and default values of a function's arguments. @@ -747,9 +760,11 @@ if not isfunction(func): raise TypeError('arg is not a Python function') args, varargs, kwonlyargs, varkw = _getfullargs(func.__code__) - return (args, varargs, varkw, func.__defaults__, + return FullArgSpec(args, varargs, varkw, func.__defaults__, kwonlyargs, func.__kwdefaults__, func.__annotations__) +ArgInfo = namedtuple('ArgInfo', 'args varargs keywords locals') + def getargvalues(frame): """Get information about arguments passed into a particular frame. @@ -859,6 +874,9 @@ return '(' + ', '.join(specs) + ')' # -------------------------------------------------- stack frame extraction + +Traceback = namedtuple('Traceback', 'filename lineno function code_context index') + def getframeinfo(frame, context=1): """Get information about a frame or traceback object. @@ -890,7 +908,7 @@ else: lines = index = None - return (filename, lineno, frame.f_code.co_name, lines, index) + return Traceback(filename, lineno, frame.f_code.co_name, lines, index) def getlineno(frame): """Get the line number from a frame object, allowing for optimization.""" Modified: python/branches/py3k-importhook/Lib/test/test_builtin.py ============================================================================== --- python/branches/py3k-importhook/Lib/test/test_builtin.py (original) +++ python/branches/py3k-importhook/Lib/test/test_builtin.py Fri Jan 11 17:48:05 2008 @@ -558,6 +558,15 @@ # TypeError because self.__format__ returns the wrong type self.assertRaises(TypeError, format, B(), "") + # TypeError because format_spec is not unicode + self.assertRaises(TypeError, format, object(), 4) + self.assertRaises(TypeError, format, object(), object()) + + # first argument to object.__format__ must be string + self.assertRaises(TypeError, object().__format__, 3) + self.assertRaises(TypeError, object().__format__, object()) + self.assertRaises(TypeError, object().__format__, None) + # make sure we can take a subclass of str as a format spec self.assertEqual(format(0, C('10')), ' 0') Modified: python/branches/py3k-importhook/Lib/test/test_collections.py ============================================================================== --- python/branches/py3k-importhook/Lib/test/test_collections.py (original) +++ python/branches/py3k-importhook/Lib/test/test_collections.py Fri Jan 11 17:48:05 2008 @@ -1,6 +1,6 @@ """Unit tests for collections.py.""" -import unittest +import unittest, doctest from test import test_support from collections import namedtuple from collections import Hashable, Iterable, Iterator @@ -316,10 +316,12 @@ self.failUnless(issubclass(sample, MutableSequence)) self.failIf(issubclass(str, MutableSequence)) +import doctest, collections +NamedTupleDocs = doctest.DocTestSuite(module=collections) def test_main(verbose=None): import collections as CollectionsModule - test_classes = [TestNamedTuple, TestOneTrickPonyABCs, TestCollectionABCs] + test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs, TestCollectionABCs] test_support.run_unittest(*test_classes) test_support.run_doctest(CollectionsModule, verbose) Modified: python/branches/py3k-importhook/Lib/test/test_doctest.py ============================================================================== --- python/branches/py3k-importhook/Lib/test/test_doctest.py (original) +++ python/branches/py3k-importhook/Lib/test/test_doctest.py Fri Jan 11 17:48:05 2008 @@ -658,7 +658,7 @@ of tried tests. >>> doctest.DocTestRunner(verbose=False).run(test) - (0, 3) + TestResults(failed=0, attempted=3) If any example produces incorrect output, then the test runner reports the failure and proceeds to the next example: @@ -695,7 +695,7 @@ Expecting: 6 ok - (1, 3) + TestResults(failed=1, attempted=3) """ def verbose_flag(): r""" The `verbose` flag makes the test runner generate more detailed @@ -726,7 +726,7 @@ Expecting: 6 ok - (0, 3) + TestResults(failed=0, attempted=3) If the `verbose` flag is unspecified, then the output will be verbose iff `-v` appears in sys.argv: @@ -737,7 +737,7 @@ >>> # If -v does not appear in sys.argv, then output isn't verbose. >>> sys.argv = ['test'] >>> doctest.DocTestRunner().run(test) - (0, 3) + TestResults(failed=0, attempted=3) >>> # If -v does appear in sys.argv, then output is verbose. >>> sys.argv = ['test', '-v'] @@ -756,7 +756,7 @@ Expecting: 6 ok - (0, 3) + TestResults(failed=0, attempted=3) >>> # Restore sys.argv >>> sys.argv = old_argv @@ -780,7 +780,7 @@ ... ''' >>> test = doctest.DocTestFinder().find(f)[0] >>> doctest.DocTestRunner(verbose=False).run(test) - (0, 2) + TestResults(failed=0, attempted=2) An example may not generate output before it raises an exception; if it does, then the traceback message will not be recognized as @@ -805,7 +805,7 @@ Exception raised: ... ZeroDivisionError: integer division or modulo by zero - (1, 2) + TestResults(failed=1, attempted=2) Exception messages may contain newlines: @@ -819,7 +819,7 @@ ... ''' >>> test = doctest.DocTestFinder().find(f)[0] >>> doctest.DocTestRunner(verbose=False).run(test) - (0, 1) + TestResults(failed=0, attempted=1) If an exception is expected, but an exception with the wrong type or message is raised, then it is reported as a failure: @@ -844,7 +844,7 @@ Traceback (most recent call last): ... ValueError: message - (1, 1) + TestResults(failed=1, attempted=1) However, IGNORE_EXCEPTION_DETAIL can be used to allow a mismatch in the detail: @@ -857,7 +857,7 @@ ... ''' >>> test = doctest.DocTestFinder().find(f)[0] >>> doctest.DocTestRunner(verbose=False).run(test) - (0, 1) + TestResults(failed=0, attempted=1) But IGNORE_EXCEPTION_DETAIL does not allow a mismatch in the exception type: @@ -881,7 +881,7 @@ Traceback (most recent call last): ... ValueError: message - (1, 1) + TestResults(failed=1, attempted=1) If an exception is raised but not expected, then it is reported as an unexpected exception: @@ -902,7 +902,7 @@ Traceback (most recent call last): ... ZeroDivisionError: integer division or modulo by zero - (1, 1) + TestResults(failed=1, attempted=1) """ def optionflags(): r""" Tests of `DocTestRunner`'s option flag handling. @@ -921,7 +921,7 @@ >>> # Without the flag: >>> test = doctest.DocTestFinder().find(f)[0] >>> doctest.DocTestRunner(verbose=False).run(test) - (0, 1) + TestResults(failed=0, attempted=1) >>> # With the flag: >>> test = doctest.DocTestFinder().find(f)[0] @@ -936,7 +936,7 @@ 1 Got: True - (1, 1) + TestResults(failed=1, attempted=1) The DONT_ACCEPT_BLANKLINE flag disables the match between blank lines and the '' marker: @@ -947,7 +947,7 @@ >>> # Without the flag: >>> test = doctest.DocTestFinder().find(f)[0] >>> doctest.DocTestRunner(verbose=False).run(test) - (0, 1) + TestResults(failed=0, attempted=1) >>> # With the flag: >>> test = doctest.DocTestFinder().find(f)[0] @@ -966,7 +966,7 @@ a b - (1, 1) + TestResults(failed=1, attempted=1) The NORMALIZE_WHITESPACE flag causes all sequences of whitespace to be treated as equal: @@ -987,13 +987,13 @@ 3 Got: 1 2 3 - (1, 1) + TestResults(failed=1, attempted=1) >>> # With the flag: >>> test = doctest.DocTestFinder().find(f)[0] >>> flags = doctest.NORMALIZE_WHITESPACE >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) - (0, 1) + TestResults(failed=0, attempted=1) An example from the docs: >>> print(list(range(20))) #doctest: +NORMALIZE_WHITESPACE @@ -1018,13 +1018,13 @@ [0, 1, 2, ..., 14] Got: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] - (1, 1) + TestResults(failed=1, attempted=1) >>> # With the flag: >>> test = doctest.DocTestFinder().find(f)[0] >>> flags = doctest.ELLIPSIS >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) - (0, 1) + TestResults(failed=0, attempted=1) ... also matches nothing: @@ -1109,7 +1109,7 @@ e f g - (1, 1) + TestResults(failed=1, attempted=1) >>> # With the flag: >>> test = doctest.DocTestFinder().find(f)[0] @@ -1131,7 +1131,7 @@ f g -h - (1, 1) + TestResults(failed=1, attempted=1) The REPORT_CDIFF flag causes failures that involve multi-line expected and actual outputs to be displayed using a context diff: @@ -1163,7 +1163,7 @@ + e f g - (1, 1) + TestResults(failed=1, attempted=1) The REPORT_NDIFF flag causes failures to use the difflib.Differ algorithm @@ -1188,7 +1188,7 @@ ? ^ + a b c d e f g h i j k l m ? + ++ ^ - (1, 1) + TestResults(failed=1, attempted=1) The REPORT_ONLY_FIRST_FAILURE supresses result output after the first failing example: @@ -1218,7 +1218,7 @@ 200 Got: 2 - (3, 5) + TestResults(failed=3, attempted=5) However, output from `report_start` is not supressed: @@ -1241,7 +1241,7 @@ 200 Got: 2 - (3, 5) + TestResults(failed=3, attempted=5) For the purposes of REPORT_ONLY_FIRST_FAILURE, unexpected exceptions count as failures: @@ -1270,7 +1270,7 @@ Exception raised: ... ValueError: 2 - (3, 5) + TestResults(failed=3, attempted=5) New option flags can also be registered, via register_optionflag(). Here we reach into doctest's internals a bit. @@ -1319,7 +1319,7 @@ [0, 1, ..., 9] Got: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - (1, 2) + TestResults(failed=1, attempted=2) To turn an option off for an example, follow that example with a comment of the form ``# doctest: -OPTION``: @@ -1344,7 +1344,7 @@ [0, 1, ..., 9] Got: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - (1, 2) + TestResults(failed=1, attempted=2) Option directives affect only the example that they appear with; they do not change the options for surrounding examples: @@ -1378,7 +1378,7 @@ [0, 1, ..., 9] Got: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - (2, 3) + TestResults(failed=2, attempted=3) Multiple options may be modified by a single option directive. They may be separated by whitespace, commas, or both: @@ -1401,7 +1401,7 @@ [0, 1, ..., 9] Got: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - (1, 2) + TestResults(failed=1, attempted=2) >>> def f(x): r''' ... >>> print(list(range(10))) # Should fail @@ -1421,7 +1421,7 @@ [0, 1, ..., 9] Got: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - (1, 2) + TestResults(failed=1, attempted=2) >>> def f(x): r''' ... >>> print(list(range(10))) # Should fail @@ -1441,7 +1441,7 @@ [0, 1, ..., 9] Got: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - (1, 2) + TestResults(failed=1, attempted=2) The option directive may be put on the line following the source, as long as a continuation prompt is used: @@ -1453,7 +1453,7 @@ ... ''' >>> test = doctest.DocTestFinder().find(f)[0] >>> doctest.DocTestRunner(verbose=False).run(test) - (0, 1) + TestResults(failed=0, attempted=1) For examples with multi-line source, the option directive may appear at the end of any line: @@ -1469,7 +1469,7 @@ ... ''' >>> test = doctest.DocTestFinder().find(f)[0] >>> doctest.DocTestRunner(verbose=False).run(test) - (0, 2) + TestResults(failed=0, attempted=2) If more than one line of an example with multi-line source has an option directive, then they are combined: @@ -1482,7 +1482,7 @@ ... ''' >>> test = doctest.DocTestFinder().find(f)[0] >>> doctest.DocTestRunner(verbose=False).run(test) - (0, 1) + TestResults(failed=0, attempted=1) It is an error to have a comment of the form ``# doctest:`` that is *not* followed by words of the form ``+OPTION`` or ``-OPTION``, where @@ -1616,7 +1616,7 @@ (Pdb) print(x) 42 (Pdb) continue - (0, 2) + TestResults(failed=0, attempted=2) You can also put pdb.set_trace in a function called from a test: @@ -1652,7 +1652,7 @@ (Pdb) print(x) 1 (Pdb) continue - (0, 2) + TestResults(failed=0, attempted=2) During interactive debugging, source code is shown, even for doctest examples: @@ -1709,7 +1709,7 @@ Expected nothing Got: 9 - (1, 3) + TestResults(failed=1, attempted=3) """ def test_pdb_set_trace_nested(): @@ -1795,7 +1795,7 @@ (Pdb) print(foo) *** NameError: NameError("name 'foo' is not defined",) (Pdb) continue - (0, 2) + TestResults(failed=0, attempted=2) """ def test_DocTestSuite(): @@ -2156,7 +2156,7 @@ 1 items had failures: 1 of 2 in test_doctest.txt ***Test Failed*** 1 failures. - (1, 2) + TestResults(failed=1, attempted=2) >>> doctest.master = None # Reset master. (Note: we'll be clearing doctest.master after each call to @@ -2167,7 +2167,7 @@ >>> globs = {'favorite_color': 'blue'} >>> doctest.testfile('test_doctest.txt', globs=globs) - (0, 2) + TestResults(failed=0, attempted=2) >>> doctest.master = None # Reset master. >>> extraglobs = {'favorite_color': 'red'} @@ -2185,7 +2185,7 @@ 1 items had failures: 1 of 2 in test_doctest.txt ***Test Failed*** 1 failures. - (1, 2) + TestResults(failed=1, attempted=2) >>> doctest.master = None # Reset master. The file may be made relative to a given module or package, using the @@ -2193,7 +2193,7 @@ >>> doctest.testfile('test_doctest.txt', globs=globs, ... module_relative='test') - (0, 2) + TestResults(failed=0, attempted=2) >>> doctest.master = None # Reset master. Verbosity can be increased with the optional `verbose` paremter: @@ -2219,7 +2219,7 @@ 2 tests in 1 items. 2 passed and 0 failed. Test passed. - (0, 2) + TestResults(failed=0, attempted=2) >>> doctest.master = None # Reset master. The name of the test may be specified with the optional `name` @@ -2230,7 +2230,7 @@ ********************************************************************** File "...", line 6, in newname ... - (1, 2) + TestResults(failed=1, attempted=2) >>> doctest.master = None # Reset master. The summary report may be supressed with the optional `report` @@ -2245,7 +2245,7 @@ Exception raised: ... NameError: name 'favorite_color' is not defined - (1, 2) + TestResults(failed=1, attempted=2) >>> doctest.master = None # Reset master. The optional keyword argument `raise_on_error` can be used to raise an @@ -2277,11 +2277,11 @@ 1 items had failures: 2 of 2 in test_doctest4.txt ***Test Failed*** 2 failures. - (2, 2) + TestResults(failed=2, attempted=2) >>> doctest.master = None # Reset master. >>> doctest.testfile('test_doctest4.txt', encoding='utf-8') - (0, 2) + TestResults(failed=0, attempted=2) >>> doctest.master = None # Reset master. """ @@ -2311,15 +2311,15 @@ 42 Got: 84 -(1, 2) +TestResults(failed=1, attempted=2) >>> t.runstring(">>> x = x * 2\n>>> print(x)\n84\n", 'example2') -(0, 2) +TestResults(failed=0, attempted=2) >>> t.summarize() ********************************************************************** 1 items had failures: 1 of 2 in XYZ ***Test Failed*** 1 failures. -(1, 4) +TestResults(failed=1, attempted=4) >>> t.summarize(verbose=1) 1 items passed all tests: 2 tests in example2 @@ -2329,7 +2329,7 @@ 4 tests in 2 items. 3 passed and 1 failed. ***Test Failed*** 1 failures. -(1, 4) +TestResults(failed=1, attempted=4) """ def old_test2(): r""" @@ -2353,7 +2353,7 @@ 3 ok 0 of 2 examples failed in string Example - (0, 2) + TestResults(failed=0, attempted=2) """ def old_test3(): r""" @@ -2366,7 +2366,7 @@ ... return 32 ... >>> t.rundoc(_f) # expect 0 failures in 1 example - (0, 1) + TestResults(failed=0, attempted=1) """ def old_test4(): """ @@ -2396,19 +2396,19 @@ >>> from doctest import Tester >>> t = Tester(globs={}, verbose=0) >>> t.rundict(m1.__dict__, "rundict_test", m1) # f2 and g2 and h2 skipped - (0, 4) + TestResults(failed=0, attempted=4) Once more, not excluding stuff outside m1: >>> t = Tester(globs={}, verbose=0) >>> t.rundict(m1.__dict__, "rundict_test_pvt") # None are skipped. - (0, 8) + TestResults(failed=0, attempted=8) The exclusion of objects from outside the designated module is meant to be invoked automagically by testmod. >>> doctest.testmod(m1, verbose=False) - (0, 4) + TestResults(failed=0, attempted=4) """ ###################################################################### Modified: python/branches/py3k-importhook/Lib/test/test_import.py ============================================================================== --- python/branches/py3k-importhook/Lib/test/test_import.py (original) +++ python/branches/py3k-importhook/Lib/test/test_import.py Fri Jan 11 17:48:05 2008 @@ -213,7 +213,8 @@ os.remove(source) del sys.modules[TESTFN] mod = __import__(TESTFN) - self.failUnless(mod.__file__.endswith('.pyc')) + ext = mod.__file__[-4:] + self.failUnless(ext in ('.pyc', '.pyo'), ext) finally: sys.path.pop(0) remove_files(TESTFN) Modified: python/branches/py3k-importhook/Lib/test/test_pyclbr.py ============================================================================== --- python/branches/py3k-importhook/Lib/test/test_pyclbr.py (original) +++ python/branches/py3k-importhook/Lib/test/test_pyclbr.py Fri Jan 11 17:48:05 2008 @@ -40,7 +40,7 @@ if key in ignore: return if key not in obj: print("***",key, file=sys.stderr) - self.failUnless(key in obj) + self.failUnless(key in obj, "%r in %r" % (key, obj)) def assertEqualsOrIgnored(self, a, b, ignore): ''' succeed iff a == b or a in ignore or b in ignore ''' @@ -140,9 +140,9 @@ def test_easy(self): self.checkModule('pyclbr') - self.checkModule('doctest') + self.checkModule('doctest', ignore=("TestResults",)) self.checkModule('rfc822') - self.checkModule('difflib') + self.checkModule('difflib', ignore=("Match",)) def test_decorators(self): # XXX: See comment in pyclbr_input.py for a test that would fail Modified: python/branches/py3k-importhook/Lib/test/test_re.py ============================================================================== --- python/branches/py3k-importhook/Lib/test/test_re.py (original) +++ python/branches/py3k-importhook/Lib/test/test_re.py Fri Jan 11 17:48:05 2008 @@ -661,6 +661,18 @@ q = p.match(upper_char) self.assertNotEqual(q, None) + def test_dollar_matches_twice(self): + "$ matches the end of string, and just before the terminating \n" + pattern = re.compile('$') + self.assertEqual(pattern.sub('#', 'a\nb\n'), 'a\nb#\n#') + self.assertEqual(pattern.sub('#', 'a\nb\nc'), 'a\nb\nc#') + self.assertEqual(pattern.sub('#', '\n'), '#\n#') + + pattern = re.compile('$', re.MULTILINE) + self.assertEqual(pattern.sub('#', 'a\nb\n' ), 'a#\nb#\n#' ) + self.assertEqual(pattern.sub('#', 'a\nb\nc'), 'a#\nb#\nc#') + self.assertEqual(pattern.sub('#', '\n'), '#\n#') + def run_re_tests(): from test.re_tests import benchmarks, tests, SUCCEED, FAIL, SYNTAX_ERROR Modified: python/branches/py3k-importhook/Modules/mmapmodule.c ============================================================================== --- python/branches/py3k-importhook/Modules/mmapmodule.c (original) +++ python/branches/py3k-importhook/Modules/mmapmodule.c Fri Jan 11 17:48:05 2008 @@ -980,9 +980,11 @@ #ifdef HAVE_FSTAT # ifdef __VMS /* on OpenVMS we must ensure that all bytes are written to the file */ - fsync(fd); + if (fd != -1) { + fsync(fd); + } # endif - if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) { + if (fd != -1 && fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) { if (map_size == 0) { map_size = st.st_size; } else if ((size_t)offset + (size_t)map_size > st.st_size) { Modified: python/branches/py3k-importhook/Modules/socketmodule.c ============================================================================== --- python/branches/py3k-importhook/Modules/socketmodule.c (original) +++ python/branches/py3k-importhook/Modules/socketmodule.c Fri Jan 11 17:48:05 2008 @@ -4097,7 +4097,7 @@ PyMODINIT_FUNC init_socket(void) { - PyObject *m, *has_ipv6, *tmp; + PyObject *m, *has_ipv6; if (!os_init()) return; @@ -4354,7 +4354,10 @@ /* for subscriptions */ PyModule_AddIntConstant(m, "TIPC_SUB_PORTS", TIPC_SUB_PORTS); PyModule_AddIntConstant(m, "TIPC_SUB_SERVICE", TIPC_SUB_SERVICE); +#ifdef TIPC_SUB_CANCEL + /* doesn't seem to be available everywhere */ PyModule_AddIntConstant(m, "TIPC_SUB_CANCEL", TIPC_SUB_CANCEL); +#endif PyModule_AddIntConstant(m, "TIPC_WAIT_FOREVER", TIPC_WAIT_FOREVER); PyModule_AddIntConstant(m, "TIPC_PUBLISHED", TIPC_PUBLISHED); PyModule_AddIntConstant(m, "TIPC_WITHDRAWN", TIPC_WITHDRAWN); Modified: python/branches/py3k-importhook/Objects/typeobject.c ============================================================================== --- python/branches/py3k-importhook/Objects/typeobject.c (original) +++ python/branches/py3k-importhook/Objects/typeobject.c Fri Jan 11 17:48:05 2008 @@ -2950,12 +2950,8 @@ PyObject *result = NULL; PyObject *format_meth = NULL; - if (!PyArg_ParseTuple(args, "O:__format__", &format_spec)) + if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) return NULL; - if (!PyUnicode_Check(format_spec)) { - PyErr_SetString(PyExc_TypeError, "Unicode object required"); - return NULL; - } self_as_str = PyObject_Str(self); if (self_as_str != NULL) { Modified: python/branches/py3k-importhook/PCbuild/build_tkinter.py ============================================================================== --- python/branches/py3k-importhook/PCbuild/build_tkinter.py (original) +++ python/branches/py3k-importhook/PCbuild/build_tkinter.py Fri Jan 11 17:48:05 2008 @@ -25,7 +25,7 @@ # Windows 2000 compatibility: WINVER 0x0500 # http://msdn2.microsoft.com/en-us/library/aa383745.aspx NMAKE = ('nmake /nologo /f %s ' - 'COMPILERFLAGS=\"-DWINVER=0x0500 -D_WIN32_WINNT=0x0500 -DNTDDI_VERSION=NTDDI_WIN2KSP4\"' + 'COMPILERFLAGS=\"-DWINVER=0x0500 -D_WIN32_WINNT=0x0500 -DNTDDI_VERSION=NTDDI_WIN2KSP4\" ' '%s %s') def nmake(makefile, command="", **kw): Modified: python/branches/py3k-importhook/PCbuild/readme.txt ============================================================================== --- python/branches/py3k-importhook/PCbuild/readme.txt (original) +++ python/branches/py3k-importhook/PCbuild/readme.txt Fri Jan 11 17:48:05 2008 @@ -117,7 +117,7 @@ Build with build_tkinter.py --------------------------- The PCbuild directory contains a Python script which automates all - steps. Run the script in a Visual Studio 2009 command prompt with + steps. Run the script in a Visual Studio 2008 command prompt with python build_tkinter.py Win32 @@ -312,9 +312,11 @@ Profile Guided Optimization --------------------------- -The solution has two configurations for PGO. The PGInstrument configuration -must be build first. The PGInstrument binaries are lniked against a profiling -library and contain extra debug information. The PGUpdate configuration takes the profiling data and generates optimized binaries. +The solution has two configurations for PGO. The PGInstrument +configuration must be build first. The PGInstrument binaries are +lniked against a profiling library and contain extra debug +information. The PGUpdate configuration takes the profiling data and +generates optimized binaries. The build_pgo.bat script automates the creation of optimized binaries. It creates the PGI files, runs the unit test suite or PyBench with the PGI Modified: python/branches/py3k-importhook/Python/import.c ============================================================================== --- python/branches/py3k-importhook/Python/import.c (original) +++ python/branches/py3k-importhook/Python/import.c Fri Jan 11 17:48:05 2008 @@ -1261,7 +1261,8 @@ } len = strlen(file); - if (len > MAXPATHLEN || PyOS_stricmp(&file[len-4], ".pyc") != 0) { + /* match '*.py?' */ + if (len > MAXPATHLEN || PyOS_strnicmp(&file[len-4], ".py", 3) != 0) { return PyUnicode_DecodeFSDefault(file); } From python-3000-checkins at python.org Sat Jan 12 20:39:11 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Sat, 12 Jan 2008 20:39:11 +0100 (CET) Subject: [Python-3000-checkins] r59933 - in python/branches/py3k: Doc/library/decimal.rst Doc/library/dis.rst Doc/library/exceptions.rst Doc/library/os.rst Doc/library/posix.rst Doc/library/xmlrpclib.rst Include/object.h Lib/ctypes/test/test_funcptr.py Lib/decimal.py Lib/test/test_decimal.py Lib/urlparse.py Modules/_ctypes/_ctypes.c Objects/object.c Objects/typeobject.c Message-ID: <20080112193911.CD1101E400F@bag.python.org> Author: christian.heimes Date: Sat Jan 12 20:39:10 2008 New Revision: 59933 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/decimal.rst python/branches/py3k/Doc/library/dis.rst python/branches/py3k/Doc/library/exceptions.rst python/branches/py3k/Doc/library/os.rst python/branches/py3k/Doc/library/posix.rst python/branches/py3k/Doc/library/xmlrpclib.rst python/branches/py3k/Include/object.h python/branches/py3k/Lib/ctypes/test/test_funcptr.py python/branches/py3k/Lib/decimal.py python/branches/py3k/Lib/test/test_decimal.py python/branches/py3k/Lib/urlparse.py python/branches/py3k/Modules/_ctypes/_ctypes.c python/branches/py3k/Objects/object.c python/branches/py3k/Objects/typeobject.c Log: Merged revisions 59921-59932 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r59923 | raymond.hettinger | 2008-01-11 19:04:55 +0100 (Fri, 11 Jan 2008) | 1 line Speed-up and simplify code urlparse's result objects. ........ r59924 | andrew.kuchling | 2008-01-11 20:33:24 +0100 (Fri, 11 Jan 2008) | 1 line Bug #1790: update link; remove outdated paragraph ........ r59925 | thomas.heller | 2008-01-11 20:34:06 +0100 (Fri, 11 Jan 2008) | 5 lines Raise an error instead of crashing with a segfault when a NULL function pointer is called. Will backport to release25-maint. ........ r59927 | thomas.heller | 2008-01-11 21:29:19 +0100 (Fri, 11 Jan 2008) | 4 lines Fix a potential 'SystemError: NULL result without error'. NULL may be a valid return value from PyLong_AsVoidPtr. Will backport to release25-maint. ........ r59928 | raymond.hettinger | 2008-01-12 00:25:18 +0100 (Sat, 12 Jan 2008) | 1 line Update the opcode docs for STORE_MAP and BUILD_MAP ........ r59929 | mark.dickinson | 2008-01-12 02:56:00 +0100 (Sat, 12 Jan 2008) | 4 lines Issue 1780: Allow leading and trailing whitespace in Decimal constructor, when constructing from a string. Disallow trailing newlines in Context.create_decimal. ........ r59930 | georg.brandl | 2008-01-12 11:53:29 +0100 (Sat, 12 Jan 2008) | 3 lines Move OSError docs to exceptions doc, remove obsolete descriptions from os docs, rework posix docs. ........ r59931 | georg.brandl | 2008-01-12 14:47:57 +0100 (Sat, 12 Jan 2008) | 3 lines Patch #1700288: Method cache optimization, by Armin Rigo, ported to 2.6 by Kevin Jacobs. ........ r59932 | georg.brandl | 2008-01-12 17:11:09 +0100 (Sat, 12 Jan 2008) | 2 lines Fix editing glitch. ........ Modified: python/branches/py3k/Doc/library/decimal.rst ============================================================================== --- python/branches/py3k/Doc/library/decimal.rst (original) +++ python/branches/py3k/Doc/library/decimal.rst Sat Jan 12 20:39:10 2008 @@ -276,9 +276,10 @@ Construct a new :class:`Decimal` object based from *value*. - *value* can be an integer, string, tuple, or another :class:`Decimal` object. If - no *value* is given, returns ``Decimal("0")``. If *value* is a string, it - should conform to the decimal numeric string syntax:: + *value* can be an integer, string, tuple, or another :class:`Decimal` + object. If no *value* is given, returns ``Decimal("0")``. If *value* is a + string, it should conform to the decimal numeric string syntax after leading + and trailing whitespace characters are removed:: sign ::= '+' | '-' digit ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' @@ -308,6 +309,10 @@ Once constructed, :class:`Decimal` objects are immutable. + .. versionchanged:: 2.6 + leading and trailing whitespace characters are permitted when + creating a Decimal instance from a string. + Decimal floating point objects share many properties with the other built-in numeric types such as :class:`float` and :class:`int`. All of the usual math operations and special methods apply. Likewise, decimal objects can be copied, @@ -925,6 +930,9 @@ >>> Decimal("3.4445") + Decimal(0) + Decimal("1.0023") Decimal("4.44") + This method implements the to-number operation of the IBM + specification. If the argument is a string, no leading or trailing + whitespace is permitted. .. method:: Context.Etiny() Modified: python/branches/py3k/Doc/library/dis.rst ============================================================================== --- python/branches/py3k/Doc/library/dis.rst (original) +++ python/branches/py3k/Doc/library/dis.rst Sat Jan 12 20:39:10 2008 @@ -506,10 +506,10 @@ Works as ``BUILD_TUPLE``, but creates a set. -.. opcode:: BUILD_MAP (zero) +.. opcode:: BUILD_MAP (count) - Pushes a new empty dictionary object onto the stack. The argument is ignored - and set to zero by the compiler. + Pushes a new dictionary object onto the stack. The dictionary is pre-sized + to hold *count* entries. .. opcode:: LOAD_ATTR (namei) @@ -589,6 +589,10 @@ Pushes a try block from a try-except clause onto the block stack. *delta* points to the finally block. +.. opcode:: STORE_MAP () + + Store a key and value pair in a dictionary. Pops the key and value while leaving + the dictionary on the stack. .. opcode:: LOAD_FAST (var_num) Modified: python/branches/py3k/Doc/library/exceptions.rst ============================================================================== --- python/branches/py3k/Doc/library/exceptions.rst (original) +++ python/branches/py3k/Doc/library/exceptions.rst Sat Jan 12 20:39:10 2008 @@ -207,9 +207,19 @@ .. exception:: OSError - This class is derived from :exc:`EnvironmentError` and is used primarily as the - :mod:`os` module's ``os.error`` exception. See :exc:`EnvironmentError` above for - a description of the possible associated values. + .. index:: module: errno + + This exception is derived from :exc:`EnvironmentError`. It is raised when a + function returns a system-related error (not for illegal argument types or + other incidental errors). The :attr:`errno` attribute is a numeric error + code from :cdata:`errno`, and the :attr:`strerror` attribute is the + corresponding string, as would be printed by the C function :cfunc:`perror`. + See the module :mod:`errno`, which contains names for the error codes defined + by the underlying operating system. + + For exceptions that involve a file system path (such as :func:`chdir` or + :func:`unlink`), the exception instance will contain a third attribute, + :attr:`filename`, which is the file name passed to the function. .. exception:: OverflowError Modified: python/branches/py3k/Doc/library/os.rst ============================================================================== --- python/branches/py3k/Doc/library/os.rst (original) +++ python/branches/py3k/Doc/library/os.rst Sat Jan 12 20:39:10 2008 @@ -1,4 +1,3 @@ - :mod:`os` --- Miscellaneous operating system interfaces ======================================================= @@ -6,53 +5,32 @@ :synopsis: Miscellaneous operating system interfaces. -This module provides a more portable way of using operating system dependent -functionality than importing an operating system dependent built-in module like -:mod:`posix` or :mod:`nt`. If you just want to read or write a file see -:func:`open`, if you want to manipulate paths, see the :mod:`os.path` -module, and if you want to read all the lines in all the files on the -command line see the :mod:`fileinput` module. For creating temporary -files and directories see the :mod:`tempfile` module, and for high-level -file and directory handling see the :mod:`shutil` module. - -This module searches for an operating system dependent built-in module like -:mod:`mac` or :mod:`posix` and exports the same functions and data as found -there. The design of all built-in operating system dependent modules of Python -is such that as long as the same functionality is available, it uses the same -interface; for example, the function ``os.stat(path)`` returns stat information -about *path* in the same format (which happens to have originated with the POSIX +This module provides a portable way of using operating system dependent +functionality. If you just want to read or write a file see :func:`open`, if +you want to manipulate paths, see the :mod:`os.path` module, and if you want to +read all the lines in all the files on the command line see the :mod:`fileinput` +module. For creating temporary files and directories see the :mod:`tempfile` +module, and for high-level file and directory handling see the :mod:`shutil` +module. + +The design of all built-in operating system dependent modules of Python is such +that as long as the same functionality is available, it uses the same interface; +for example, the function ``os.stat(path)`` returns stat information about +*path* in the same format (which happens to have originated with the POSIX interface). Extensions peculiar to a particular operating system are also available through the :mod:`os` module, but using them is of course a threat to portability! -Note that after the first time :mod:`os` is imported, there is *no* performance -penalty in using functions from :mod:`os` instead of directly from the operating -system dependent built-in module, so there should be *no* reason not to use -:mod:`os`! +.. note:: -The :mod:`os` module contains many functions and data values. The items below -and in the following sub-sections are all available directly from the :mod:`os` -module. + All functions in this module raise :exc:`OSError` in the case of invalid or + inaccessible file names and paths, or other arguments that have the correct + type, but are not accepted by the operating system. .. exception:: error - .. index:: module: errno - - This exception is raised when a function returns a system-related error (not for - illegal argument types or other incidental errors). This is also known as the - built-in exception :exc:`OSError`. The accompanying value is a pair containing - the numeric error code from :cdata:`errno` and the corresponding string, as - would be printed by the C function :cfunc:`perror`. See the module - :mod:`errno`, which contains names for the error codes defined by the underlying - operating system. - - When exceptions are classes, this exception carries two attributes, - :attr:`errno` and :attr:`strerror`. The first holds the value of the C - :cdata:`errno` variable, and the latter holds the corresponding error message - from :cfunc:`strerror`. For exceptions that involve a file system path (such as - :func:`chdir` or :func:`unlink`), the exception instance will contain a third - attribute, :attr:`filename`, which is the file name passed to the function. + An alias for the built-in :exc:`OSError` exception. .. data:: name @@ -645,7 +623,6 @@ Files and Directories --------------------- - .. function:: access(path, mode) Use the real uid/gid to test for access to *path*. Note that most operations @@ -1760,8 +1737,8 @@ .. function:: getloadavg() - Return the number of processes in the system run queue averaged over the last 1, - 5, and 15 minutes or raises :exc:`OSError` if the load average was + Return the number of processes in the system run queue averaged over the last + 1, 5, and 15 minutes or raises :exc:`OSError` if the load average was unobtainable. Modified: python/branches/py3k/Doc/library/posix.rst ============================================================================== --- python/branches/py3k/Doc/library/posix.rst (original) +++ python/branches/py3k/Doc/library/posix.rst Sat Jan 12 20:39:10 2008 @@ -1,4 +1,3 @@ - :mod:`posix` --- The most common POSIX system calls =================================================== @@ -22,13 +21,8 @@ :mod:`os` provides some additional functionality, such as automatically calling :func:`putenv` when an entry in ``os.environ`` is changed. -The descriptions below are very terse; refer to the corresponding Unix manual -(or POSIX documentation) entry for more information. Arguments called *path* -refer to a pathname given as a string. - Errors are reported as exceptions; the usual exceptions are given for type -errors, while errors reported by the system calls raise :exc:`error` (a synonym -for the standard exception :exc:`OSError`), described below. +errors, while errors reported by the system calls raise :exc:`OSError`. .. _posix-large-files: @@ -42,9 +36,8 @@ .. sectionauthor:: Steve Clift - -Several operating systems (including AIX, HPUX, Irix and Solaris) provide -support for files that are larger than 2 Gb from a C programming model where +Several operating systems (including AIX, HP-UX, Irix and Solaris) provide +support for files that are larger than 2 GB from a C programming model where :ctype:`int` and :ctype:`long` are 32-bit values. This is typically accomplished by defining the relevant size and offset types as 64-bit values. Such files are sometimes referred to as :dfn:`large files`. @@ -67,16 +60,16 @@ .. _posix-contents: -Module Contents ---------------- - -Module :mod:`posix` defines the following data item: +Notable Module Contents +----------------------- +In addition to many functions described in the :mod:`os` module documentation, +:mod:`posix` defines the following data item: .. data:: environ - A dictionary representing the string environment at the time the interpreter was - started. For example, ``environ['HOME']`` is the pathname of your home + A dictionary representing the string environment at the time the interpreter + was started. For example, ``environ['HOME']`` is the pathname of your home directory, equivalent to ``getenv("HOME")`` in C. Modifying this dictionary does not affect the string environment passed on by @@ -90,7 +83,3 @@ updates the environment on modification. Note also that updating ``os.environ`` will render this dictionary obsolete. Use of the :mod:`os` module version of this is recommended over direct access to the :mod:`posix` module. - -Additional contents of this module should only be accessed via the :mod:`os` -module; refer to the documentation for that module for further information. - Modified: python/branches/py3k/Doc/library/xmlrpclib.rst ============================================================================== --- python/branches/py3k/Doc/library/xmlrpclib.rst (original) +++ python/branches/py3k/Doc/library/xmlrpclib.rst Sat Jan 12 20:39:10 2008 @@ -110,12 +110,11 @@ .. seealso:: `XML-RPC HOWTO `_ - A good description of XML operation and client software in several languages. + A good description of XML-RPC operation and client software in several languages. Contains pretty much everything an XML-RPC client developer needs to know. - `XML-RPC Hacks page `_ - Extensions for various open-source libraries to support introspection and - multicall. + `XML-RPC Introspection `_ + Describes the XML-RPC protocol extension for introspection. .. _serverproxy-objects: @@ -167,11 +166,6 @@ no such string is available, an empty string is returned. The documentation string may contain HTML markup. -Introspection methods are currently supported by servers written in PHP, C and -Microsoft .NET. Partial introspection support is included in recent updates to -UserLand Frontier. Introspection support for Perl, Python and Java is available -at the `XML-RPC Hacks `_ page. - .. _boolean-objects: Modified: python/branches/py3k/Include/object.h ============================================================================== --- python/branches/py3k/Include/object.h (original) +++ python/branches/py3k/Include/object.h Sat Jan 12 20:39:10 2008 @@ -374,6 +374,9 @@ PyObject *tp_weaklist; destructor tp_del; + /* Type attribute cache version tag. Added in version 2.6 */ + unsigned int tp_version_tag; + #ifdef COUNT_ALLOCS /* these must be last and never explicitly initialized */ Py_ssize_t tp_allocs; @@ -525,6 +528,10 @@ #define Py_TPFLAGS_HAVE_STACKLESS_EXTENSION 0 #endif +/* Objects support type attribute cache */ +#define Py_TPFLAGS_HAVE_VERSION_TAG (1L<<18) +#define Py_TPFLAGS_VALID_VERSION_TAG (1L<<19) + /* These flags are used to determine if a type is a subclass. */ #define Py_TPFLAGS_INT_SUBCLASS (1L<<23) #define Py_TPFLAGS_LONG_SUBCLASS (1L<<24) @@ -538,6 +545,7 @@ #define Py_TPFLAGS_DEFAULT ( \ Py_TPFLAGS_HAVE_STACKLESS_EXTENSION | \ + Py_TPFLAGS_HAVE_VERSION_TAG | \ 0) #define PyType_HasFeature(t,f) (((t)->tp_flags & (f)) != 0) Modified: python/branches/py3k/Lib/ctypes/test/test_funcptr.py ============================================================================== --- python/branches/py3k/Lib/ctypes/test/test_funcptr.py (original) +++ python/branches/py3k/Lib/ctypes/test/test_funcptr.py Sat Jan 12 20:39:10 2008 @@ -123,5 +123,11 @@ self.failUnlessEqual(strtok(None, b"\n"), "c") self.failUnlessEqual(strtok(None, b"\n"), None) + def test_NULL_funcptr(self): + tp = CFUNCTYPE(c_int) + func = tp() # NULL function pointer + # raise a ValueError when we try to call it + self.assertRaises(ValueError, func) + if __name__ == '__main__': unittest.main() Modified: python/branches/py3k/Lib/decimal.py ============================================================================== --- python/branches/py3k/Lib/decimal.py (original) +++ python/branches/py3k/Lib/decimal.py Sat Jan 12 20:39:10 2008 @@ -524,6 +524,8 @@ Decimal("314") >>> Decimal(Decimal(314)) # another decimal instance Decimal("314") + >>> Decimal(' 3.14 \\n') # leading and trailing whitespace okay + Decimal("3.14") """ # Note that the coefficient, self._int, is actually stored as @@ -539,7 +541,7 @@ # From a string # REs insist on real strings, so we can too. if isinstance(value, str): - m = _parser(value) + m = _parser(value.strip()) if m is None: if context is None: context = getcontext() @@ -3542,7 +3544,16 @@ return rounding def create_decimal(self, num='0'): - """Creates a new Decimal instance but using self as context.""" + """Creates a new Decimal instance but using self as context. + + This method implements the to-number operation of the + IBM Decimal specification.""" + + if isinstance(num, str) and num != num.strip(): + return self._raise_error(ConversionSyntax, + "no trailing or leading whitespace is " + "permitted.") + d = Decimal(num, context=self) if d._isnan() and len(d._int) > self.prec - self._clamp: return self._raise_error(ConversionSyntax, @@ -5157,7 +5168,7 @@ (?P\d*) # with (possibly empty) diagnostic information. ) # \s* - $ + \Z """, re.VERBOSE | re.IGNORECASE).match _all_zeros = re.compile('0*$').match Modified: python/branches/py3k/Lib/test/test_decimal.py ============================================================================== --- python/branches/py3k/Lib/test/test_decimal.py (original) +++ python/branches/py3k/Lib/test/test_decimal.py Sat Jan 12 20:39:10 2008 @@ -429,6 +429,10 @@ #just not a number self.assertEqual(str(Decimal('ugly')), 'NaN') + #leading and trailing whitespace permitted + self.assertEqual(str(Decimal('1.3E4 \n')), '1.3E+4') + self.assertEqual(str(Decimal(' -7.89')), '-7.89') + def test_explicit_from_tuples(self): #zero @@ -517,6 +521,10 @@ self.assertEqual(str(d), '456789') d = nc.create_decimal('456789') self.assertEqual(str(d), '4.57E+5') + # leading and trailing whitespace should result in a NaN; + # spaces are already checked in Cowlishaw's test-suite, so + # here we just check that a trailing newline results in a NaN + self.assertEqual(str(nc.create_decimal('3.14\n')), 'NaN') # from tuples d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) ) Modified: python/branches/py3k/Lib/urlparse.py ============================================================================== --- python/branches/py3k/Lib/urlparse.py (original) +++ python/branches/py3k/Lib/urlparse.py Sat Jan 12 20:39:10 2008 @@ -37,46 +37,11 @@ def clear_cache(): """Clear the parse cache.""" - global _parse_cache - _parse_cache = {} + _parse_cache.clear() -class BaseResult(tuple): - """Base class for the parsed result objects. - - This provides the attributes shared by the two derived result - objects as read-only properties. The derived classes are - responsible for checking the right number of arguments were - supplied to the constructor. - - """ - - __slots__ = () - - # Attributes that access the basic components of the URL: - - @property - def scheme(self): - return self[0] - - @property - def netloc(self): - return self[1] - - @property - def path(self): - return self[2] - - @property - def query(self): - return self[-2] - - @property - def fragment(self): - return self[-1] - - # Additional attributes that provide access to parsed-out portions - # of the netloc: +class ResultMixin(object): + """Shared methods for the parsed result objects.""" @property def username(self): @@ -116,31 +81,20 @@ return int(port, 10) return None +from collections import namedtuple -class SplitResult(BaseResult): +class SplitResult(namedtuple('SplitResult', 'scheme netloc path query fragment'), ResultMixin): __slots__ = () - def __new__(cls, scheme, netloc, path, query, fragment): - return BaseResult.__new__( - cls, (scheme, netloc, path, query, fragment)) - def geturl(self): return urlunsplit(self) -class ParseResult(BaseResult): +class ParseResult(namedtuple('ParseResult', 'scheme netloc path params query fragment'), ResultMixin): __slots__ = () - def __new__(cls, scheme, netloc, path, params, query, fragment): - return BaseResult.__new__( - cls, (scheme, netloc, path, params, query, fragment)) - - @property - def params(self): - return self[3] - def geturl(self): return urlunparse(self) Modified: python/branches/py3k/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k/Modules/_ctypes/_ctypes.c Sat Jan 12 20:39:10 2008 @@ -2882,7 +2882,7 @@ && (PyLong_Check(PyTuple_GET_ITEM(args, 0)))) { CDataObject *ob; void *ptr = PyLong_AsVoidPtr(PyTuple_GET_ITEM(args, 0)); - if (ptr == NULL) + if (ptr == NULL && PyErr_Occurred()) return NULL; ob = (CDataObject *)GenericCData_new(type, args, kwds); if (ob == NULL) @@ -3291,6 +3291,11 @@ pProc = *(void **)self->b_ptr; + if (pProc == NULL) { + PyErr_SetString(PyExc_ValueError, + "attempt to call NULL function pointer"); + return NULL; + } #ifdef MS_WIN32 if (self->index) { /* It's a COM method */ Modified: python/branches/py3k/Objects/object.c ============================================================================== --- python/branches/py3k/Objects/object.c (original) +++ python/branches/py3k/Objects/object.c Sat Jan 12 20:39:10 2008 @@ -947,6 +947,7 @@ goto done; } +#if 0 /* XXX this is not quite _PyType_Lookup anymore */ /* Inline _PyType_Lookup */ { Py_ssize_t i, n; @@ -967,6 +968,9 @@ break; } } +#else + descr = _PyType_Lookup(tp, name); +#endif Py_XINCREF(descr); Modified: python/branches/py3k/Objects/typeobject.c ============================================================================== --- python/branches/py3k/Objects/typeobject.c (original) +++ python/branches/py3k/Objects/typeobject.c Sat Jan 12 20:39:10 2008 @@ -6,6 +6,171 @@ #include + +/* Support type attribute cache */ + +/* The cache can keep references to the names alive for longer than + they normally would. This is why the maximum size is limited to + MCACHE_MAX_ATTR_SIZE, since it might be a problem if very large + strings are used as attribute names. */ +#define MCACHE_MAX_ATTR_SIZE 100 +#define MCACHE_SIZE_EXP 10 +#define MCACHE_HASH(version, name_hash) \ + (((unsigned int)(version) * (unsigned int)(name_hash)) \ + >> (8*sizeof(unsigned int) - MCACHE_SIZE_EXP)) +#define MCACHE_HASH_METHOD(type, name) \ + MCACHE_HASH((type)->tp_version_tag, \ + ((PyStringObject *)(name))->ob_shash) +#define MCACHE_CACHEABLE_NAME(name) \ + PyString_CheckExact(name) && \ + PyString_GET_SIZE(name) <= MCACHE_MAX_ATTR_SIZE + +struct method_cache_entry { + unsigned int version; + PyObject *name; /* reference to exactly a str or None */ + PyObject *value; /* borrowed */ +}; + +static struct method_cache_entry method_cache[1 << MCACHE_SIZE_EXP]; +static unsigned int next_version_tag = 0; + +static void +type_modified(PyTypeObject *type) +{ + /* Invalidate any cached data for the specified type and all + subclasses. This function is called after the base + classes, mro, or attributes of the type are altered. + + Invariants: + + - Py_TPFLAGS_VALID_VERSION_TAG is never set if + Py_TPFLAGS_HAVE_VERSION_TAG is not set (e.g. on type + objects coming from non-recompiled extension modules) + + - before Py_TPFLAGS_VALID_VERSION_TAG can be set on a type, + it must first be set on all super types. + + This function clears the Py_TPFLAGS_VALID_VERSION_TAG of a + type (so it must first clear it on all subclasses). The + tp_version_tag value is meaningless unless this flag is set. + We don't assign new version tags eagerly, but only as + needed. + */ + PyObject *raw, *ref; + Py_ssize_t i, n; + + if(!PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)) + return; + + raw = type->tp_subclasses; + if (raw != NULL) { + n = PyList_GET_SIZE(raw); + for (i = 0; i < n; i++) { + ref = PyList_GET_ITEM(raw, i); + ref = PyWeakref_GET_OBJECT(ref); + if (ref != Py_None) { + type_modified((PyTypeObject *)ref); + } + } + } + type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG; +} + +static void +type_mro_modified(PyTypeObject *type, PyObject *bases) { + /* + Check that all base classes or elements of the mro of type are + able to be cached. This function is called after the base + classes or mro of the type are altered. + + Unset HAVE_VERSION_TAG and VALID_VERSION_TAG if the type + inherits from an old-style class, either directly or if it + appears in the MRO of a new-style class. No support either for + custom MROs that include types that are not officially super + types. + + Called from mro_internal, which will subsequently be called on + each subclass when their mro is recursively updated. + */ + Py_ssize_t i, n; + int clear = 0; + + if(!PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG)) + return; + + n = PyTuple_GET_SIZE(bases); + for (i = 0; i < n; i++) { + PyObject *b = PyTuple_GET_ITEM(bases, i); + PyTypeObject *cls; + + if (!PyType_Check(b) ) { + clear = 1; + break; + } + + cls = (PyTypeObject *)b; + + if (!PyType_HasFeature(cls, Py_TPFLAGS_HAVE_VERSION_TAG) || + !PyType_IsSubtype(type, cls)) { + clear = 1; + break; + } + } + + if (clear) + type->tp_flags &= ~(Py_TPFLAGS_HAVE_VERSION_TAG| + Py_TPFLAGS_VALID_VERSION_TAG); +} + +static int +assign_version_tag(PyTypeObject *type) +{ + /* Ensure that the tp_version_tag is valid and set + Py_TPFLAGS_VALID_VERSION_TAG. To respect the invariant, this + must first be done on all super classes. Return 0 if this + cannot be done, 1 if Py_TPFLAGS_VALID_VERSION_TAG. + */ + Py_ssize_t i, n; + PyObject *bases; + + if (PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)) + return 1; + if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG)) + return 0; + if (!PyType_HasFeature(type, Py_TPFLAGS_READY)) + return 0; + + type->tp_version_tag = next_version_tag++; + /* for stress-testing: next_version_tag &= 0xFF; */ + + if (type->tp_version_tag == 0) { + /* wrap-around or just starting Python - clear the whole + cache by filling names with references to Py_None. + Values are also set to NULL for added protection, as they + are borrowed reference */ + for (i = 0; i < (1 << MCACHE_SIZE_EXP); i++) { + method_cache[i].value = NULL; + Py_XDECREF(method_cache[i].name); + method_cache[i].name = Py_None; + Py_INCREF(Py_None); + } + /* mark all version tags as invalid */ + type_modified(&PyBaseObject_Type); + return 1; + } + bases = type->tp_bases; + n = PyTuple_GET_SIZE(bases); + for (i = 0; i < n; i++) { + PyObject *b = PyTuple_GET_ITEM(bases, i); + assert(PyType_Check(b)); + if (!assign_version_tag((PyTypeObject *)b)) + return 0; + } + type->tp_flags |= Py_TPFLAGS_VALID_VERSION_TAG; + return 1; +} + + static PyMemberDef type_members[] = { {"__basicsize__", T_INT, offsetof(PyTypeObject,tp_basicsize),READONLY}, {"__itemsize__", T_INT, offsetof(PyTypeObject, tp_itemsize), READONLY}, @@ -130,6 +295,8 @@ return -1; } + type_modified(type); + return PyDict_SetItemString(type->tp_dict, "__module__", value); } @@ -1299,6 +1466,14 @@ } } type->tp_mro = tuple; + + type_mro_modified(type, type->tp_mro); + /* corner case: the old-style super class might have been hidden + from the custom MRO */ + type_mro_modified(type, type->tp_bases); + + type_modified(type); + return 0; } @@ -2026,6 +2201,16 @@ { Py_ssize_t i, n; PyObject *mro, *res, *base, *dict; + unsigned int h; + + if (MCACHE_CACHEABLE_NAME(name) && + PyType_HasFeature(type,Py_TPFLAGS_VALID_VERSION_TAG)) { + /* fast path */ + h = MCACHE_HASH_METHOD(type, name); + if (method_cache[h].version == type->tp_version_tag && + method_cache[h].name == name) + return method_cache[h].value; + } /* Look in tp_dict of types in MRO */ mro = type->tp_mro; @@ -2036,6 +2221,7 @@ if (mro == NULL) return NULL; + res = NULL; assert(PyTuple_Check(mro)); n = PyTuple_GET_SIZE(mro); for (i = 0; i < n; i++) { @@ -2045,9 +2231,18 @@ assert(dict && PyDict_Check(dict)); res = PyDict_GetItem(dict, name); if (res != NULL) - return res; + break; } - return NULL; + + if (MCACHE_CACHEABLE_NAME(name) && assign_version_tag(type)) { + h = MCACHE_HASH_METHOD(type, name); + method_cache[h].version = type->tp_version_tag; + method_cache[h].value = res; /* borrowed */ + Py_INCREF(name); + Py_DECREF(method_cache[h].name); + method_cache[h].name = name; + } + return res; } /* This is similar to PyObject_GenericGetAttr(), @@ -2137,10 +2332,6 @@ type->tp_name); return -1; } - /* XXX Example of how I expect this to be used... - if (update_subclasses(type, name, invalidate_cache, NULL) < 0) - return -1; - */ if (PyObject_GenericSetAttr((PyObject *)type, name, value) < 0) return -1; return update_slot(type, name); @@ -5421,6 +5612,13 @@ slotdef **pp; int offset; + /* Clear the VALID_VERSION flag of 'type' and all its + subclasses. This could possibly be unified with the + update_subclasses() recursion below, but carefully: + they each have their own conditions on which to stop + recursing into subclasses. */ + type_modified(type); + init_slotdefs(); pp = ptrs; for (p = slotdefs; p->name; p++) { From python-3000-checkins at python.org Sat Jan 12 20:47:54 2008 From: python-3000-checkins at python.org (guido.van.rossum) Date: Sat, 12 Jan 2008 20:47:54 +0100 (CET) Subject: [Python-3000-checkins] r59934 - python/branches/py3k/runtests.sh Message-ID: <20080112194754.ED40C1E400F@bag.python.org> Author: guido.van.rossum Date: Sat Jan 12 20:47:54 2008 New Revision: 59934 Modified: python/branches/py3k/runtests.sh Log: Use bash, so echo -n will do the right thing. Modified: python/branches/py3k/runtests.sh ============================================================================== --- python/branches/py3k/runtests.sh (original) +++ python/branches/py3k/runtests.sh Sat Jan 12 20:47:54 2008 @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash HELP="Usage: ./runtests.py [-h] [-x] [flags] [tests] From python-3000-checkins at python.org Mon Jan 14 00:14:07 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Mon, 14 Jan 2008 00:14:07 +0100 (CET) Subject: [Python-3000-checkins] r59941 - in python/branches/py3k-importhook: Lib/test/test_imp.py Python/import.c Message-ID: <20080113231407.DFDA91E4023@bag.python.org> Author: christian.heimes Date: Mon Jan 14 00:14:07 2008 New Revision: 59941 Modified: python/branches/py3k-importhook/Lib/test/test_imp.py python/branches/py3k-importhook/Python/import.c Log: Implemented a queue for registrations. It's filled while hooks are processed Modified: python/branches/py3k-importhook/Lib/test/test_imp.py ============================================================================== --- python/branches/py3k-importhook/Lib/test/test_imp.py (original) +++ python/branches/py3k-importhook/Lib/test/test_imp.py Mon Jan 14 00:14:07 2008 @@ -105,20 +105,29 @@ import imp def callback(mod): - imp.test_callbacks.append(("pih_test%s", mod.__name__)) + info = ("pih_test%(info)s", mod.__name__) + imp.test_callbacks.append(info) + +def callback_added(mod): + info = ("ADDED in pih_test%(info)s", mod.__name__) + imp.test_callbacks.append(info) + +def callback_add(mod): + callback(mod) + imp.register_post_import_hook(callback_added, "pih_test.a") imp.register_post_import_hook(callback, "pih_test") -imp.register_post_import_hook(callback, "pih_test.a") +imp.register_post_import_hook(callback_add, "pih_test.a") imp.register_post_import_hook(callback, "pih_test.a.b") """ hier_withregister = [ ("pih_test", None), - ("pih_test __init__", mod_callback % ''), + ("pih_test __init__", mod_callback % {'info':''}), ("pih_test a", None), - ("pih_test a __init__", mod_callback % '.a'), + ("pih_test a __init__", mod_callback % {'info':'.a'}), ("pih_test a b", None), - ("pih_test a b __init__", mod_callback % '.a.b'), + ("pih_test a b __init__", mod_callback % {'info':'.a.b'}), ] class CallBack: @@ -240,11 +249,12 @@ self.assertEqual(callback.names, ["pih_test", "pih_test.a", "pih_test.a.b"]) - def test_hook_hirarchie(self): + def test_hook_hirarchie_withregister(self): self.tmpdir = mkhier(hier_withregister) def callback(mod): - imp.test_callbacks.append(('', mod.__name__)) + info = ('', mod.__name__) + imp.test_callbacks.append(info) imp.register_post_import_hook(callback, "pih_test") imp.register_post_import_hook(callback, "pih_test.a") @@ -263,11 +273,16 @@ expected.append(("", "pih_test.a")) expected.append(("pih_test", "pih_test.a")) expected.append(("pih_test.a", "pih_test.a")) + # delayed + expected.append(("ADDED in pih_test", "pih_test.a")) + expected.append(("ADDED in pih_test.a", "pih_test.a")) self.assertEqual(imp.test_callbacks, expected) import pih_test.a.b expected.append(("pih_test.a.b", "pih_test")) expected.append(("pih_test.a.b", "pih_test.a")) + # This one is called immediately because pih_test.a is already laoded + expected.append(("ADDED in pih_test.a.b", "pih_test.a")) expected.append(("", "pih_test.a.b")) expected.append(("pih_test", "pih_test.a.b")) expected.append(("pih_test.a", "pih_test.a.b")) Modified: python/branches/py3k-importhook/Python/import.c ============================================================================== --- python/branches/py3k-importhook/Python/import.c (original) +++ python/branches/py3k-importhook/Python/import.c Mon Jan 14 00:14:07 2008 @@ -111,6 +111,14 @@ {0, 0} }; +/* Queue for the post import hook system */ +static PyObject *register_queue = NULL; +static int notification_in_progress = 0; + +static PyObject *notify_byname(const char *); +static int queue_registration(PyObject *, PyObject *); +static int process_registration_queue(void); + /* Initialize things */ @@ -241,8 +249,8 @@ void _PyImport_Fini(void) { - Py_XDECREF(extensions); - extensions = NULL; + Py_CLEAR(extensions); + Py_CLEAR(register_queue); PyMem_DEL(_PyImport_Filetab); _PyImport_Filetab = NULL; } @@ -639,7 +647,10 @@ "sys.modules failed"); } -/* post import hook API */ +/* ************************************************************************** + * post import hook API + */ + PyObject * PyImport_GetPostImportHooks(void) { @@ -732,6 +743,8 @@ if ((it = PyObject_GetIter(hooks)) == NULL) { goto error; } + + notification_in_progress = 1; while ((hook = PyIter_Next(it)) != NULL) { o = PyObject_CallFunctionObjArgs(hook, module, NULL); Py_DECREF(hook); @@ -750,6 +763,11 @@ if (PyDict_SetItem(registry, mod_name, Py_None) < 0) { status = -1; } + notification_in_progress = 0; + /* register queued hooks */ + if (process_registration_queue()) { + goto removehooks; + } error: Py_XDECREF(mod_name); Py_XDECREF(it); @@ -832,6 +850,13 @@ goto error; } + if (notification_in_progress) { + if (queue_registration(callable, mod_name) != 0) { + return NULL; + } + Py_RETURN_NONE; + } + registry = PyImport_GetPostImportHooks(); modules = PyImport_GetModuleDict(); if (registry == NULL || modules == NULL) { @@ -846,8 +871,9 @@ /* module may be already loaded, get the module object from sys */ if (hooks == NULL || hooks == Py_None) { PyObject *module = NULL; - - if ((module = PyDict_GetItem(modules, mod_name)) != NULL) { + + module = PyDict_GetItem(modules, mod_name); + if (module != NULL) { /* module is already loaded, fire hook immediately */ PyObject *o; @@ -904,6 +930,84 @@ } } +static int +queue_registration(PyObject *callable, PyObject *mod_name) +{ + + PyObject *tup; + + if (register_queue == NULL) { + register_queue = PyList_New(0); + if (register_queue == NULL) + return -1; + } + assert(notification_in_progress); + tup = PyTuple_New(2); + if (tup == NULL) { + return -1; + } + Py_INCREF(callable); + Py_INCREF(mod_name); + PyTuple_SetItem(tup, 0, callable); + PyTuple_SetItem(tup, 1, mod_name); + if (PyList_Append(register_queue, tup)) { + Py_DECREF(tup); + return -1; + } + Py_DECREF(tup); + return 0; +} + +static int +process_registration_queue(void) +{ + PyObject *modules; + PyObject *mod_name, *hook, *module, *o; + PyObject *it = NULL, *tup = NULL; + int rc = -1; + + if (notification_in_progress) + return 0; + + if (register_queue == NULL || PyList_Size(register_queue) == 0) { + return 0; + } + + if ((modules = PyImport_GetModuleDict()) == NULL) { + goto error; + } + + while (Py_SIZE(register_queue)) { + tup = PyObject_CallMethod(register_queue, "pop", "i", 0); + if ((hook = PyTuple_GetItem(tup, 0)) == NULL) { + goto error; + } + if ((mod_name = PyTuple_GetItem(tup, 1)) == NULL) { + goto error; + } + if ((module = PyDict_GetItem(modules, mod_name)) == NULL) { + goto error; + } + o = PyImport_RegisterPostImportHook(hook, mod_name); + if (o == NULL) { + goto error; + } + Py_DECREF(o); + Py_CLEAR(tup); + } + if (PyErr_Occurred()) { + goto error; + } + + rc = 0; + error: + Py_XDECREF(it); + Py_XDECREF(tup); + return rc; +} + +/* end of post import hook */ + static PyObject * get_sourcefile(const char *file); /* Execute a code object in a module and return the module object From python-3000-checkins at python.org Mon Jan 14 00:40:32 2008 From: python-3000-checkins at python.org (raymond.hettinger) Date: Mon, 14 Jan 2008 00:40:32 +0100 (CET) Subject: [Python-3000-checkins] r59942 - in python/branches/py3k: Doc/library/random.rst Lib/random.py Lib/test/test_generators.py Lib/test/test_random.py Misc/NEWS Modules/_randommodule.c Message-ID: <20080113234032.17D7A1E4030@bag.python.org> Author: raymond.hettinger Date: Mon Jan 14 00:40:30 2008 New Revision: 59942 Modified: python/branches/py3k/Doc/library/random.rst python/branches/py3k/Lib/random.py python/branches/py3k/Lib/test/test_generators.py python/branches/py3k/Lib/test/test_random.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_randommodule.c Log: Remove defunct parts of the random module Modified: python/branches/py3k/Doc/library/random.rst ============================================================================== --- python/branches/py3k/Doc/library/random.rst (original) +++ python/branches/py3k/Doc/library/random.rst Mon Jan 14 00:40:30 2008 @@ -28,25 +28,14 @@ The functions supplied by this module are actually bound methods of a hidden instance of the :class:`random.Random` class. You can instantiate your own -instances of :class:`Random` to get generators that don't share state. This is -especially useful for multi-threaded programs, creating a different instance of -:class:`Random` for each thread, and using the :meth:`jumpahead` method to make -it likely that the generated sequences seen by each thread don't overlap. +instances of :class:`Random` to get generators that don't share state. Class :class:`Random` can also be subclassed if you want to use a different basic generator of your own devising: in that case, override the :meth:`random`, -:meth:`seed`, :meth:`getstate`, :meth:`setstate` and :meth:`jumpahead` methods. +:meth:`seed`, :meth:`getstate`, and :meth:`setstate`. Optionally, a new generator can supply a :meth:`getrandombits` method --- this allows :meth:`randrange` to produce selections over an arbitrarily large range. -As an example of subclassing, the :mod:`random` module provides the -:class:`WichmannHill` class that implements an alternative generator in pure -Python. The class provides a backward compatible way to reproduce results from -earlier versions of Python, which used the Wichmann-Hill algorithm as the core -generator. Note that this Wichmann-Hill generator can no longer be recommended: -its period is too short by contemporary standards, and the sequence generated is -known to fail some stringent randomness tests. See the references below for a -recent variant that repairs these flaws. Bookkeeping functions: @@ -79,17 +68,6 @@ the time :func:`setstate` was called. -.. function:: jumpahead(n) - - Change the internal state to one different from and likely far away from the - current state. *n* is a non-negative integer which is used to scramble the - current state vector. This is most useful in multi-threaded programs, in - conjuction with multiple instances of the :class:`Random` class: - :meth:`setstate` or :meth:`seed` can be used to force all instances into the - same internal state, and then :meth:`jumpahead` can be used to force the - instances' states far apart. - - .. function:: getrandbits(k) Returns a python integer with *k* random bits. This method is supplied with @@ -224,24 +202,6 @@ Alternative Generators: -.. class:: WichmannHill([seed]) - - Class that implements the Wichmann-Hill algorithm as the core generator. Has all - of the same methods as :class:`Random` plus the :meth:`whseed` method described - below. Because this class is implemented in pure Python, it is not threadsafe - and may require locks between calls. The period of the generator is - 6,953,607,871,644 which is small enough to require care that two independent - random sequences do not overlap. - - -.. function:: whseed([x]) - - This is obsolete, supplied for bit-level compatibility with versions of Python - prior to 2.1. See :func:`seed` for details. :func:`whseed` does not guarantee - that distinct integer arguments yield distinct internal states, and can yield no - more than about 2\*\*24 distinct internal states in all. - - .. class:: SystemRandom([seed]) Class that uses the :func:`os.urandom` function for generating random numbers @@ -281,6 +241,4 @@ equidistributed uniform pseudorandom number generator", ACM Transactions on Modeling and Computer Simulation Vol. 8, No. 1, January pp.3-30 1998. - Wichmann, B. A. & Hill, I. D., "Algorithm AS 183: An efficient and portable - pseudo-random number generator", Applied Statistics 31 (1982) 188-190. Modified: python/branches/py3k/Lib/random.py ============================================================================== --- python/branches/py3k/Lib/random.py (original) +++ python/branches/py3k/Lib/random.py Mon Jan 14 00:40:30 2008 @@ -30,9 +30,6 @@ * The period is 2**19937-1. * It is one of the most extensively tested generators in existence. -* Without a direct way to compute N steps forward, the semantics of - jumpahead(n) are weakened to simply jump to another distant state and rely - on the large period to avoid overlapping sequences. * The random() method is implemented in C, executes in a single Python step, and is, therefore, threadsafe. @@ -49,7 +46,7 @@ "randrange","shuffle","normalvariate","lognormvariate", "expovariate","vonmisesvariate","gammavariate", "gauss","betavariate","paretovariate","weibullvariate", - "getstate","setstate","jumpahead", "WichmannHill", "getrandbits", + "getstate","setstate", "getrandbits", "SystemRandom"] NV_MAGICCONST = 4 * _exp(-0.5)/_sqrt(2.0) @@ -70,14 +67,11 @@ """Random number generator base class used by bound module functions. Used to instantiate instances of Random to get generators that don't - share state. Especially useful for multi-threaded programs, creating - a different instance of Random for each thread, and using the jumpahead() - method to ensure that the generated sequences seen by each thread don't - overlap. + share state. Class Random can also be subclassed if you want to use a different basic generator of your own devising: in that case, override the following - methods: random(), seed(), getstate(), setstate() and jumpahead(). + methods: random(), seed(), getstate(), and setstate(). Optionally, implement a getrandombits() method so that randrange() can cover arbitrarily large ranges. @@ -615,156 +609,6 @@ u = 1.0 - self.random() return alpha * pow(-_log(u), 1.0/beta) -## -------------------- Wichmann-Hill ------------------- - -class WichmannHill(Random): - - VERSION = 1 # used by getstate/setstate - - def seed(self, a=None): - """Initialize internal state from hashable object. - - None or no argument seeds from current time or from an operating - system specific randomness source if available. - - If a is not None or an int or long, hash(a) is used instead. - - If a is an int or long, a is used directly. Distinct values between - 0 and 27814431486575L inclusive are guaranteed to yield distinct - internal states (this guarantee is specific to the default - Wichmann-Hill generator). - """ - - if a is None: - try: - a = int(_hexlify(_urandom(16)), 16) - except NotImplementedError: - import time - a = int(time.time() * 256) # use fractional seconds - - if not isinstance(a, int): - a = hash(a) - - a, x = divmod(a, 30268) - a, y = divmod(a, 30306) - a, z = divmod(a, 30322) - self._seed = int(x)+1, int(y)+1, int(z)+1 - - self.gauss_next = None - - def random(self): - """Get the next random number in the range [0.0, 1.0).""" - - # Wichman-Hill random number generator. - # - # Wichmann, B. A. & Hill, I. D. (1982) - # Algorithm AS 183: - # An efficient and portable pseudo-random number generator - # Applied Statistics 31 (1982) 188-190 - # - # see also: - # Correction to Algorithm AS 183 - # Applied Statistics 33 (1984) 123 - # - # McLeod, A. I. (1985) - # A remark on Algorithm AS 183 - # Applied Statistics 34 (1985),198-200 - - # This part is thread-unsafe: - # BEGIN CRITICAL SECTION - x, y, z = self._seed - x = (171 * x) % 30269 - y = (172 * y) % 30307 - z = (170 * z) % 30323 - self._seed = x, y, z - # END CRITICAL SECTION - - # Note: on a platform using IEEE-754 double arithmetic, this can - # never return 0.0 (asserted by Tim; proof too long for a comment). - return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0 - - def getstate(self): - """Return internal state; can be passed to setstate() later.""" - return self.VERSION, self._seed, self.gauss_next - - def setstate(self, state): - """Restore internal state from object returned by getstate().""" - version = state[0] - if version == 1: - version, self._seed, self.gauss_next = state - else: - raise ValueError("state with version %s passed to " - "Random.setstate() of version %s" % - (version, self.VERSION)) - - def jumpahead(self, n): - """Act as if n calls to random() were made, but quickly. - - n is an int, greater than or equal to 0. - - Example use: If you have 2 threads and know that each will - consume no more than a million random numbers, create two Random - objects r1 and r2, then do - r2.setstate(r1.getstate()) - r2.jumpahead(1000000) - Then r1 and r2 will use guaranteed-disjoint segments of the full - period. - """ - - if not n >= 0: - raise ValueError("n must be >= 0") - x, y, z = self._seed - x = int(x * pow(171, n, 30269)) % 30269 - y = int(y * pow(172, n, 30307)) % 30307 - z = int(z * pow(170, n, 30323)) % 30323 - self._seed = x, y, z - - def __whseed(self, x=0, y=0, z=0): - """Set the Wichmann-Hill seed from (x, y, z). - - These must be integers in the range [0, 256). - """ - - if not type(x) == type(y) == type(z) == int: - raise TypeError('seeds must be integers') - if not (0 <= x < 256 and 0 <= y < 256 and 0 <= z < 256): - raise ValueError('seeds must be in range(0, 256)') - if 0 == x == y == z: - # Initialize from current time - import time - t = int(time.time() * 256) - t = int((t&0xffffff) ^ (t>>24)) - t, x = divmod(t, 256) - t, y = divmod(t, 256) - t, z = divmod(t, 256) - # Zero is a poor seed, so substitute 1 - self._seed = (x or 1, y or 1, z or 1) - - self.gauss_next = None - - def whseed(self, a=None): - """Seed from hashable object's hash code. - - None or no argument seeds from current time. It is not guaranteed - that objects with distinct hash codes lead to distinct internal - states. - - This is obsolete, provided for compatibility with the seed routine - used prior to Python 2.1. Use the .seed() method instead. - """ - - if a is None: - self.__whseed() - return - a = hash(a) - a, x = divmod(a, 256) - a, y = divmod(a, 256) - a, z = divmod(a, 256) - x = (x + a) % 256 or 1 - y = (y + a) % 256 or 1 - z = (z + a) % 256 or 1 - self.__whseed(x, y, z) - ## --------------- Operating System Random Source ------------------ class SystemRandom(Random): @@ -789,10 +633,9 @@ x = int(_hexlify(_urandom(bytes)), 16) return x >> (bytes * 8 - k) # trim excess bits - def _stub(self, *args, **kwds): + def seed(self, *args, **kwds): "Stub method. Not used for a system random number generator." return None - seed = jumpahead = _stub def _notimplemented(self, *args, **kwds): "Method should not be called for a system random number generator." @@ -866,7 +709,6 @@ weibullvariate = _inst.weibullvariate getstate = _inst.getstate setstate = _inst.setstate -jumpahead = _inst.jumpahead getrandbits = _inst.getrandbits if __name__ == '__main__': Modified: python/branches/py3k/Lib/test/test_generators.py ============================================================================== --- python/branches/py3k/Lib/test/test_generators.py (original) +++ python/branches/py3k/Lib/test/test_generators.py Mon Jan 14 00:40:30 2008 @@ -444,7 +444,7 @@ >>> roots = sets[:] >>> import random ->>> gen = random.WichmannHill(42) +>>> gen = random.Random(42) >>> while 1: ... for s in sets: ... print(" %s->%s" % (s, s.find()), end='') @@ -458,29 +458,29 @@ ... else: ... break A->A B->B C->C D->D E->E F->F G->G H->H I->I J->J K->K L->L M->M -merged D into G - A->A B->B C->C D->G E->E F->F G->G H->H I->I J->J K->K L->L M->M -merged C into F - A->A B->B C->F D->G E->E F->F G->G H->H I->I J->J K->K L->L M->M +merged I into A + A->A B->B C->C D->D E->E F->F G->G H->H I->A J->J K->K L->L M->M +merged D into C + A->A B->B C->C D->C E->E F->F G->G H->H I->A J->J K->K L->L M->M +merged K into H + A->A B->B C->C D->C E->E F->F G->G H->H I->A J->J K->H L->L M->M merged L into A - A->A B->B C->F D->G E->E F->F G->G H->H I->I J->J K->K L->A M->M -merged H into E - A->A B->B C->F D->G E->E F->F G->G H->E I->I J->J K->K L->A M->M -merged B into E - A->A B->E C->F D->G E->E F->F G->G H->E I->I J->J K->K L->A M->M + A->A B->B C->C D->C E->E F->F G->G H->H I->A J->J K->H L->A M->M +merged E into A + A->A B->B C->C D->C E->A F->F G->G H->H I->A J->J K->H L->A M->M +merged B into G + A->A B->G C->C D->C E->A F->F G->G H->H I->A J->J K->H L->A M->M +merged A into F + A->F B->G C->C D->C E->F F->F G->G H->H I->F J->J K->H L->F M->M +merged H into G + A->F B->G C->C D->C E->F F->F G->G H->G I->F J->J K->G L->F M->M +merged F into J + A->J B->G C->C D->C E->J F->J G->G H->G I->J J->J K->G L->J M->M +merged M into C + A->J B->G C->C D->C E->J F->J G->G H->G I->J J->J K->G L->J M->C merged J into G - A->A B->E C->F D->G E->E F->F G->G H->E I->I J->G K->K L->A M->M -merged E into G - A->A B->G C->F D->G E->G F->F G->G H->G I->I J->G K->K L->A M->M -merged M into G - A->A B->G C->F D->G E->G F->F G->G H->G I->I J->G K->K L->A M->G -merged I into K - A->A B->G C->F D->G E->G F->F G->G H->G I->K J->G K->K L->A M->G -merged K into A - A->A B->G C->F D->G E->G F->F G->G H->G I->A J->G K->A L->A M->G -merged F into A - A->A B->G C->A D->G E->G F->A G->G H->G I->A J->G K->A L->A M->G -merged A into G + A->G B->G C->C D->C E->G F->G G->G H->G I->G J->G K->G L->G M->C +merged C into G A->G B->G C->G D->G E->G F->G G->G H->G I->G J->G K->G L->G M->G """ Modified: python/branches/py3k/Lib/test/test_random.py ============================================================================== --- python/branches/py3k/Lib/test/test_random.py (original) +++ python/branches/py3k/Lib/test/test_random.py Mon Jan 14 00:40:30 2008 @@ -42,21 +42,6 @@ self.assertRaises(TypeError, self.gen.seed, 1, 2) self.assertRaises(TypeError, type(self.gen), []) - def test_jumpahead(self): - self.gen.seed() - state1 = self.gen.getstate() - self.gen.jumpahead(100) - state2 = self.gen.getstate() # s/b distinct from state1 - self.assertNotEqual(state1, state2) - self.gen.jumpahead(100) - state3 = self.gen.getstate() # s/b distinct from state2 - self.assertNotEqual(state2, state3) - - self.assertRaises(TypeError, self.gen.jumpahead) # needs an arg - self.assertRaises(TypeError, self.gen.jumpahead, "ick") # wrong type - self.assertRaises(TypeError, self.gen.jumpahead, 2.3) # wrong type - self.assertRaises(TypeError, self.gen.jumpahead, 2, 3) # too many - def test_sample(self): # For the entire allowable range of 0 <= k <= N, validate that # the sample is of the correct length and contains only unique items @@ -157,48 +142,6 @@ f.close() self.assertEqual(r.randrange(1000), value) -class WichmannHill_TestBasicOps(TestBasicOps): - gen = random.WichmannHill() - - def test_setstate_first_arg(self): - self.assertRaises(ValueError, self.gen.setstate, (2, None, None)) - - def test_strong_jumpahead(self): - # tests that jumpahead(n) semantics correspond to n calls to random() - N = 1000 - s = self.gen.getstate() - self.gen.jumpahead(N) - r1 = self.gen.random() - # now do it the slow way - self.gen.setstate(s) - for i in range(N): - self.gen.random() - r2 = self.gen.random() - self.assertEqual(r1, r2) - - def test_gauss_with_whseed(self): - # Ensure that the seed() method initializes all the hidden state. In - # particular, through 2.2.1 it failed to reset a piece of state used - # by (and only by) the .gauss() method. - - for seed in 1, 12, 123, 1234, 12345, 123456, 654321: - self.gen.whseed(seed) - x1 = self.gen.random() - y1 = self.gen.gauss(0, 1) - - self.gen.whseed(seed) - x2 = self.gen.random() - y2 = self.gen.gauss(0, 1) - - self.assertEqual(x1, x2) - self.assertEqual(y1, y2) - - def test_bigrand(self): - # Verify warnings are raised when randrange is too large for random() - with test_support.catch_warning(): - warnings.filterwarnings("error", "Underlying random") - self.assertRaises(UserWarning, self.gen.randrange, 2**60) - class SystemRandom_TestBasicOps(TestBasicOps): gen = random.SystemRandom() @@ -214,10 +157,6 @@ # Doesn't need to do anything except not fail self.gen.seed(100) - def test_jumpahead(self): - # Doesn't need to do anything except not fail - self.gen.jumpahead(100) - def test_gauss(self): self.gen.gauss_next = None self.gen.seed(100) @@ -541,8 +480,7 @@ def test_main(verbose=None): - testclasses = [WichmannHill_TestBasicOps, - MersenneTwister_TestBasicOps, + testclasses = [MersenneTwister_TestBasicOps, TestDistributions, TestModule] Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Jan 14 00:40:30 2008 @@ -352,6 +352,9 @@ Library ------- +- Removed defunct parts of the random module (the Wichmann-Hill generator + and the jumpahead() method). + - Patch #467924: add ZipFile.extract() and ZipFile.extractall() in the zipfile module. Modified: python/branches/py3k/Modules/_randommodule.c ============================================================================== --- python/branches/py3k/Modules/_randommodule.c (original) +++ python/branches/py3k/Modules/_randommodule.c Mon Jan 14 00:40:30 2008 @@ -369,72 +369,6 @@ return Py_None; } -/* -Jumpahead should be a fast way advance the generator n-steps ahead, but -lacking a formula for that, the next best is to use n and the existing -state to create a new state far away from the original. - -The generator uses constant spaced additive feedback, so shuffling the -state elements ought to produce a state which would not be encountered -(in the near term) by calls to random(). Shuffling is normally -implemented by swapping the ith element with another element ranging -from 0 to i inclusive. That allows the element to have the possibility -of not being moved. Since the goal is to produce a new, different -state, the swap element is ranged from 0 to i-1 inclusive. This assures -that each element gets moved at least once. - -To make sure that consecutive calls to jumpahead(n) produce different -states (even in the rare case of involutory shuffles), i+1 is added to -each element at position i. Successive calls are then guaranteed to -have changing (growing) values as well as shuffled positions. - -Finally, the self->index value is set to N so that the generator itself -kicks in on the next call to random(). This assures that all results -have been through the generator and do not just reflect alterations to -the underlying state. -*/ - -static PyObject * -random_jumpahead(RandomObject *self, PyObject *n) -{ - long i, j; - PyObject *iobj; - PyObject *remobj; - unsigned long *mt, tmp; - - if (!PyLong_Check(n)) { - PyErr_Format(PyExc_TypeError, "jumpahead requires an " - "integer, not '%s'", - Py_TYPE(n)->tp_name); - return NULL; - } - - mt = self->state; - for (i = N-1; i > 1; i--) { - iobj = PyLong_FromLong(i); - if (iobj == NULL) - return NULL; - remobj = PyNumber_Remainder(n, iobj); - Py_DECREF(iobj); - if (remobj == NULL) - return NULL; - j = PyLong_AsLong(remobj); - Py_DECREF(remobj); - if (j == -1L && PyErr_Occurred()) - return NULL; - tmp = mt[i]; - mt[i] = mt[j]; - mt[j] = tmp; - } - - for (i = 0; i < N; i++) - mt[i] += i+1; - - self->index = N; - Py_INCREF(Py_None); - return Py_None; -} - static PyObject * random_getrandbits(RandomObject *self, PyObject *args) { @@ -506,9 +440,6 @@ PyDoc_STR("getstate() -> tuple containing the current state.")}, {"setstate", (PyCFunction)random_setstate, METH_O, PyDoc_STR("setstate(state) -> None. Restores generator state.")}, - {"jumpahead", (PyCFunction)random_jumpahead, METH_O, - PyDoc_STR("jumpahead(int) -> None. Create new state from " - "existing state and integer.")}, {"getrandbits", (PyCFunction)random_getrandbits, METH_VARARGS, PyDoc_STR("getrandbits(k) -> x. Generates a long int with " "k random bits.")}, From python-3000-checkins at python.org Mon Jan 14 02:00:54 2008 From: python-3000-checkins at python.org (raymond.hettinger) Date: Mon, 14 Jan 2008 02:00:54 +0100 (CET) Subject: [Python-3000-checkins] r59945 - in python/branches/py3k: Doc/library/random.rst Lib/random.py Lib/test/test_random.py Misc/NEWS Message-ID: <20080114010054.3A0201E4023@bag.python.org> Author: raymond.hettinger Date: Mon Jan 14 02:00:53 2008 New Revision: 59945 Modified: python/branches/py3k/Doc/library/random.rst python/branches/py3k/Lib/random.py python/branches/py3k/Lib/test/test_random.py python/branches/py3k/Misc/NEWS Log: Take Tim's advice and have random.sample() support only sequences and sets. Modified: python/branches/py3k/Doc/library/random.rst ============================================================================== --- python/branches/py3k/Doc/library/random.rst (original) +++ python/branches/py3k/Doc/library/random.rst Mon Jan 14 02:00:53 2008 @@ -111,8 +111,8 @@ .. function:: sample(population, k) - Return a *k* length list of unique elements chosen from the population sequence. - Used for random sampling without replacement. + Return a *k* length list of unique elements chosen from the population sequence + or set. Used for random sampling without replacement. Returns a new list containing elements from the population while leaving the original population unchanged. The resulting list is in selection order so that Modified: python/branches/py3k/Lib/random.py ============================================================================== --- python/branches/py3k/Lib/random.py (original) +++ python/branches/py3k/Lib/random.py Mon Jan 14 02:00:53 2008 @@ -267,7 +267,7 @@ x[i], x[j] = x[j], x[i] def sample(self, population, k): - """Chooses k unique random elements from a population sequence. + """Chooses k unique random elements from a population sequence or set. Returns a new list containing elements from the population while leaving the original population unchanged. The resulting list is @@ -284,15 +284,6 @@ large population: sample(range(10000000), 60) """ - # XXX Although the documentation says `population` is "a sequence", - # XXX attempts are made to cater to any iterable with a __len__ - # XXX method. This has had mixed success. Examples from both - # XXX sides: sets work fine, and should become officially supported; - # XXX dicts are much harder, and have failed in various subtle - # XXX ways across attempts. Support for mapping types should probably - # XXX be dropped (and users should pass mapping.keys() or .values() - # XXX explicitly). - # Sampling without replacement entails tracking either potential # selections (the pool) in a list or previous selections in a set. @@ -303,37 +294,35 @@ # preferred since the list takes less space than the # set and it doesn't suffer from frequent reselections. + if isinstance(population, (set, frozenset)): + population = tuple(population) + if not hasattr(population, '__getitem__') or hasattr(population, 'keys'): + raise TypeError("Population must be a sequence or set. For dicts, use dict.keys().") + random = self.random n = len(population) if not 0 <= k <= n: - raise ValueError("sample larger than population") - random = self.random + raise ValueError("Sample larger than population") _int = int result = [None] * k setsize = 21 # size of a small set minus size of an empty list if k > 5: setsize += 4 ** _ceil(_log(k * 3, 4)) # table size for big sets - if n <= setsize or hasattr(population, "keys"): - # An n-length list is smaller than a k-length set, or this is a - # mapping type so the other algorithm wouldn't work. + if n <= setsize: + # An n-length list is smaller than a k-length set pool = list(population) for i in range(k): # invariant: non-selected at [0,n-i) j = _int(random() * (n-i)) result[i] = pool[j] pool[j] = pool[n-i-1] # move non-selected item into vacancy else: - try: - selected = set() - selected_add = selected.add - for i in range(k): + selected = set() + selected_add = selected.add + for i in range(k): + j = _int(random() * n) + while j in selected: j = _int(random() * n) - while j in selected: - j = _int(random() * n) - selected_add(j) - result[i] = population[j] - except (TypeError, KeyError): # handle (at least) sets - if isinstance(population, list): - raise - return self.sample(tuple(population), k) + selected_add(j) + result[i] = population[j] return result ## -------------------- real-valued distributions ------------------- Modified: python/branches/py3k/Lib/test/test_random.py ============================================================================== --- python/branches/py3k/Lib/test/test_random.py (original) +++ python/branches/py3k/Lib/test/test_random.py Mon Jan 14 02:00:53 2008 @@ -84,26 +84,7 @@ self.gen.sample(tuple('abcdefghijklmnopqrst'), 2) def test_sample_on_dicts(self): - self.gen.sample(dict.fromkeys('abcdefghijklmnopqrst'), 2) - - # SF bug #1460340 -- random.sample can raise KeyError - a = dict.fromkeys(list(range(10)) + - list(range(10,100,2)) + - list(range(100,110))) - self.gen.sample(a, 3) - - # A followup to bug #1460340: sampling from a dict could return - # a subset of its keys or of its values, depending on the size of - # the subset requested. - N = 30 - d = dict((i, complex(i, i)) for i in range(N)) - for k in range(N+1): - samp = self.gen.sample(d, k) - # Verify that we got ints back (keys); the values are complex. - for x in samp: - self.assert_(type(x) is int) - samp.sort() - self.assertEqual(samp, list(range(N))) + self.assertRaises(TypeError, self.gen.sample, dict.fromkeys('abcdef'), 2) def test_gauss(self): # Ensure that the seed() method initializes all the hidden state. In Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Jan 14 02:00:53 2008 @@ -355,6 +355,9 @@ - Removed defunct parts of the random module (the Wichmann-Hill generator and the jumpahead() method). +- random.sample() now explicitly supports all sequences and sets while + explicitly excluding mappings. + - Patch #467924: add ZipFile.extract() and ZipFile.extractall() in the zipfile module. From python-3000-checkins at python.org Mon Jan 14 19:49:24 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Mon, 14 Jan 2008 19:49:24 +0100 (CET) Subject: [Python-3000-checkins] r59954 - in python/branches/py3k: Doc/c-api/concrete.rst Doc/glossary.rst Doc/library/functions.rst Doc/library/sys.rst Lib/pydoc.py Lib/test/test_structseq.py Lib/test/test_sys.py Modules/_ctypes/_ctypes.c Modules/_ctypes/stgdict.c Modules/socketmodule.c Objects/floatobject.c Objects/structseq.c Python/sysmodule.c Message-ID: <20080114184924.F05701E401F@bag.python.org> Author: christian.heimes Date: Mon Jan 14 19:49:24 2008 New Revision: 59954 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/c-api/concrete.rst python/branches/py3k/Doc/glossary.rst python/branches/py3k/Doc/library/functions.rst python/branches/py3k/Doc/library/sys.rst python/branches/py3k/Lib/pydoc.py python/branches/py3k/Lib/test/test_structseq.py python/branches/py3k/Lib/test/test_sys.py python/branches/py3k/Modules/_ctypes/_ctypes.c python/branches/py3k/Modules/_ctypes/stgdict.c python/branches/py3k/Modules/socketmodule.c python/branches/py3k/Objects/floatobject.c python/branches/py3k/Objects/structseq.c python/branches/py3k/Python/sysmodule.c Log: Merged revisions 59933-59951 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r59935 | raymond.hettinger | 2008-01-13 07:15:15 +0100 (Sun, 13 Jan 2008) | 1 line Named tuple is a concept, not a specific type. ........ r59936 | raymond.hettinger | 2008-01-13 07:18:07 +0100 (Sun, 13 Jan 2008) | 1 line Fix spelling. ........ r59937 | georg.brandl | 2008-01-13 10:36:18 +0100 (Sun, 13 Jan 2008) | 2 lines Clarify the effect of text mode. ........ r59938 | thomas.heller | 2008-01-13 12:19:43 +0100 (Sun, 13 Jan 2008) | 1 line Make Modules/socketobject.c compile for Windows again. ........ r59939 | ka-ping.yee | 2008-01-13 12:25:13 +0100 (Sun, 13 Jan 2008) | 9 lines Check in the patch proposed by Ben Hayden (benjhayden) for issue #1550: help('modules') broken by several 3rd party libraries. Tested with Python build: trunk:54235:59936M -- the reported error occurs with Django installed (or with any __init__.py present on the path that raises an exception), and such errors indeed go away when this change is applied. ........ r59940 | georg.brandl | 2008-01-13 16:04:05 +0100 (Sun, 13 Jan 2008) | 2 lines Back out r59931 - test_ctypes fails with it. ........ r59943 | amaury.forgeotdarc | 2008-01-14 01:22:44 +0100 (Mon, 14 Jan 2008) | 6 lines As discussed in issue 1700288: ctypes takes some liberties when creating python types: it modifies the types' __dict__ directly, bypassing all the machinery of type objects which deal with special methods. And this broke recent optimisations of method lookup. Now we try to modify the type with more "official" functions. ........ r59944 | amaury.forgeotdarc | 2008-01-14 01:29:41 +0100 (Mon, 14 Jan 2008) | 5 lines Re-apply patch #1700288 (first applied in r59931, rolled back in r59940) now that ctypes uses a more supported method to create types: Method cache optimization, by Armin Rigo, ported to 2.6 by Kevin Jacobs. ........ r59946 | amaury.forgeotdarc | 2008-01-14 02:07:27 +0100 (Mon, 14 Jan 2008) | 4 lines ?Why did my tests not notice this before? Slots inheritance is very different from OO inheritance. This code lead to infinite recursion on classes derived from StructType. ........ r59947 | christian.heimes | 2008-01-14 04:33:52 +0100 (Mon, 14 Jan 2008) | 1 line Added new an better structseq representation. E.g. repr(time.gmtime(0)) now returns 'time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0)' instead of '(1970, 1, 1, 0, 0, 0, 3, 1, 0)'. The feature is part of #1816: sys.flags ........ r59948 | christian.heimes | 2008-01-14 04:35:38 +0100 (Mon, 14 Jan 2008) | 1 line I missed the most important file ........ r59949 | christian.heimes | 2008-01-14 04:42:48 +0100 (Mon, 14 Jan 2008) | 1 line Applied patch #1816: sys.flags patch ........ r59950 | christian.heimes | 2008-01-14 05:13:37 +0100 (Mon, 14 Jan 2008) | 2 lines Now that I've learnt about structseq objects I felt like converting sys.float_info to a structseq. It's readonly and help(sys.float_info) explains the attributes nicely. ........ r59951 | christian.heimes | 2008-01-14 07:06:19 +0100 (Mon, 14 Jan 2008) | 1 line Added more comments to the new structseq repr code and implemented several of Neal's suggestions. ........ Modified: python/branches/py3k/Doc/c-api/concrete.rst ============================================================================== --- python/branches/py3k/Doc/c-api/concrete.rst (original) +++ python/branches/py3k/Doc/c-api/concrete.rst Mon Jan 14 19:49:24 2008 @@ -433,7 +433,7 @@ .. cfunction:: PyObject* PyFloat_GetInfo(void) - Return a :ctype:`PyDictObject` object which contains information about the + Return a structseq instance which contains information about the precision, minimum and maximum values of a float. It's a thin wrapper around the header file :file:`float.h`. Modified: python/branches/py3k/Doc/glossary.rst ============================================================================== --- python/branches/py3k/Doc/glossary.rst (original) +++ python/branches/py3k/Doc/glossary.rst Mon Jan 14 19:49:24 2008 @@ -329,11 +329,17 @@ also :term:`immutable`. named tuple - A tuple subclass whose elements also are accessible as attributes via - fixed names (the class name and field names are indicated in the - individual documentation of a named tuple type, like ``TestResults(failed, - attempted)``). Named tuple classes are created by - :func:`collections.namedtuple`. + Any tuple-like class whose indexable fields are also accessible with + named attributes (for example, :func:`time.localtime` returns a + tuple-like object where the *year* is accessible either with an + index such as ``t[0]`` or with a named attribute like ``t.tm_year``). + + A named tuple can be a built-in type such as :class:`time.struct_time`, + or it can be created with a regular class definition. A full featured + named tuple can also be created with the factory function + :func:`collections.namedtuple`. The latter approach automatically + provides extra features such as a self-documenting representation like + ``Employee(name='jones', title='programmer')``. namespace The place where a variable is stored. Namespaces are implemented as Modified: python/branches/py3k/Doc/library/functions.rst ============================================================================== --- python/branches/py3k/Doc/library/functions.rst (original) +++ python/branches/py3k/Doc/library/functions.rst Mon Jan 14 19:49:24 2008 @@ -743,10 +743,17 @@ * 'U' universal newline mode (for backwards compatibility; unnecessary in new code) - Combine ``'b'`` with ``'r'``, ``'w'``, or ``'a'``, for binary - mode, e.g., ``'rb'`` to open a file for reading in binary mode. - Modes ``'r+'``, ``'w+'`` and ``'a+'`` open the file for updating (note - that ``'w+'`` truncates the file). + The most commonly-used values of *mode* are ``'r'`` for reading, ``'w'`` for + writing (truncating the file if it already exists), and ``'a'`` for appending + (which on *some* Unix systems means that *all* writes append to the end of the + file regardless of the current seek position). If *mode* is omitted, it + defaults to ``'r'``. The default is to use text mode, which may convert + ``'\n'`` characters to a platform-specific representation on writing and back + on reading. Thus, when opening a binary file, you should append ``'b'`` to + the *mode* value to open the file in binary mode, which will improve + portability. (Appending ``'b'`` is useful even on systems that don't treat + binary and text files differently, where it serves as documentation.) See below + for more possible values of *mode*. Python distinguishes between files opened in binary and text modes, even when the underlying operating system doesn't. Files opened in binary Modified: python/branches/py3k/Doc/library/sys.rst ============================================================================== --- python/branches/py3k/Doc/library/sys.rst (original) +++ python/branches/py3k/Doc/library/sys.rst Mon Jan 14 19:49:24 2008 @@ -184,14 +184,52 @@ error occurs. +.. data:: flags + + The struct sequence *flags* exposes the status of command line flags. The + attributes are read only. + + +------------------------------+------------------------------------------+ + | attribute | flag | + +==============================+==========================================+ + | :const:`debug` | -d | + +------------------------------+------------------------------------------+ + | :const:`py3k_warning` | -3 | + +------------------------------+------------------------------------------+ + | :const:`division_warning` | -Q | + +------------------------------+------------------------------------------+ + | :const:`division_new` | -Qnew | + +------------------------------+------------------------------------------+ + | :const:`inspect` | -i | + +------------------------------+------------------------------------------+ + | :const:`interactive` | -i | + +------------------------------+------------------------------------------+ + | :const:`optimize` | -O or -OO | + +------------------------------+------------------------------------------+ + | :const:`dont_write_bytecode` | -B | + +------------------------------+------------------------------------------+ + | :const:`no_site` | -S | + +------------------------------+------------------------------------------+ + | :const:`ingnore_environment` | -E | + +------------------------------+------------------------------------------+ + | :const:`tabcheck` | -t or -tt | + +------------------------------+------------------------------------------+ + | :const:`verbose` | -v | + +------------------------------+------------------------------------------+ + | :const:`unicode` | -U | + +------------------------------+------------------------------------------+ + + .. versionadded:: 2.6 + + .. data:: float_info - A dict holding information about the float type. It contains low level + A structseq holding information about the float type. It contains low level information about the precision and internal representation. Please study your system's :file:`float.h` for more information. +---------------------+--------------------------------------------------+ - | key | explanation | + | attribute | explanation | +=====================+==================================================+ | :const:`epsilon` | Difference between 1 and the next representable | | | floating point number | Modified: python/branches/py3k/Lib/pydoc.py ============================================================================== --- python/branches/py3k/Lib/pydoc.py (original) +++ python/branches/py3k/Lib/pydoc.py Mon Jan 14 19:49:24 2008 @@ -1834,7 +1834,9 @@ modname = modname[:-9] + ' (package)' if modname.find('.') < 0: modules[modname] = 1 - ModuleScanner().run(callback) + def onerror(modname): + callback(None, modname, None) + ModuleScanner().run(callback, onerror=onerror) self.list(modules.keys()) self.output.write(''' Enter any module name to get more help. Or, type "modules spam" to search @@ -1870,7 +1872,7 @@ class ModuleScanner: """An interruptible scanner that searches module synopses.""" - def run(self, callback, key=None, completer=None): + def run(self, callback, key=None, completer=None, onerror=None): if key: key = key.lower() self.quit = False seen = {} @@ -1887,7 +1889,7 @@ if name.lower().find(key) >= 0: callback(None, modname, desc) - for importer, modname, ispkg in pkgutil.walk_packages(): + for importer, modname, ispkg in pkgutil.walk_packages(onerror=onerror): if self.quit: break if key is None: Modified: python/branches/py3k/Lib/test/test_structseq.py ============================================================================== --- python/branches/py3k/Lib/test/test_structseq.py (original) +++ python/branches/py3k/Lib/test/test_structseq.py Mon Jan 14 19:49:24 2008 @@ -28,7 +28,11 @@ def test_repr(self): t = time.gmtime() - repr(t) + self.assert_(repr(t)) + t = time.gmtime(0) + self.assertEqual(repr(t), + "time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, " + "tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0)") def test_concat(self): t1 = time.gmtime() Modified: python/branches/py3k/Lib/test/test_sys.py ============================================================================== --- python/branches/py3k/Lib/test/test_sys.py (original) +++ python/branches/py3k/Lib/test/test_sys.py Mon Jan 14 19:49:24 2008 @@ -279,8 +279,8 @@ self.assert_(isinstance(sys.copyright, str)) self.assert_(isinstance(sys.exec_prefix, str)) self.assert_(isinstance(sys.executable, str)) - self.assert_(isinstance(sys.float_info, dict)) self.assertEqual(len(sys.float_info), 11) + self.assertEqual(sys.float_info.radix, 2) self.assert_(isinstance(sys.hexversion, int)) self.assert_(isinstance(sys.maxsize, int)) self.assert_(isinstance(sys.maxunicode, int)) @@ -320,6 +320,17 @@ self.assertRaises(TypeError, sys.intern, S("abc")) + def test_sys_flags(self): + self.failUnless(sys.flags) + attrs = ("debug", "division_warning", + "inspect", "interactive", "optimize", "dont_write_bytecode", + "no_site", "ingnore_environment", "tabcheck", "verbose") + for attr in attrs: + self.assert_(hasattr(sys.flags, attr), attr) + self.assertEqual(type(getattr(sys.flags, attr)), int, attr) + self.assert_(repr(sys.flags)) + + def test_main(): test.test_support.run_unittest(SysModuleTest) Modified: python/branches/py3k/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k/Modules/_ctypes/_ctypes.c Mon Jan 14 19:49:24 2008 @@ -401,7 +401,7 @@ StructType_setattro(PyObject *self, PyObject *key, PyObject *value) { /* XXX Should we disallow deleting _fields_? */ - if (-1 == PyObject_GenericSetAttr(self, key, value)) + if (-1 == PyType_Type.tp_setattro(self, key, value)) return -1; if (value && PyUnicode_Check(key) && Modified: python/branches/py3k/Modules/_ctypes/stgdict.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/stgdict.c (original) +++ python/branches/py3k/Modules/_ctypes/stgdict.c Mon Jan 14 19:49:24 2008 @@ -458,7 +458,7 @@ Py_DECREF(pair); return -1; } - if (-1 == PyDict_SetItem(realdict, name, prop)) { + if (-1 == PyObject_SetAttr(type, name, prop)) { Py_DECREF(prop); Py_DECREF(pair); return -1; Modified: python/branches/py3k/Modules/socketmodule.c ============================================================================== --- python/branches/py3k/Modules/socketmodule.c (original) +++ python/branches/py3k/Modules/socketmodule.c Mon Jan 14 19:49:24 2008 @@ -4979,10 +4979,13 @@ #endif #ifdef SIO_RCVALL - tmp = PyLong_FromUnsignedLong(SIO_RCVALL); - if (tmp == NULL) - return; - PyModule_AddObject(m, "SIO_RCVALL", tmp); + { + PyObject *tmp; + tmp = PyLong_FromUnsignedLong(SIO_RCVALL); + if (tmp == NULL) + return; + PyModule_AddObject(m, "SIO_RCVALL", tmp); + } PyModule_AddIntConstant(m, "RCVALL_OFF", RCVALL_OFF); PyModule_AddIntConstant(m, "RCVALL_ON", RCVALL_ON); PyModule_AddIntConstant(m, "RCVALL_SOCKETLEVELONLY", RCVALL_SOCKETLEVELONLY); Modified: python/branches/py3k/Objects/floatobject.c ============================================================================== --- python/branches/py3k/Objects/floatobject.c (original) +++ python/branches/py3k/Objects/floatobject.c Mon Jan 14 19:49:24 2008 @@ -5,6 +5,7 @@ for any kind of float exception without losing portability. */ #include "Python.h" +#include "structseq.h" #include "formatter_unicode.h" @@ -61,39 +62,86 @@ return DBL_MIN; } +static PyTypeObject FloatInfoType; + +PyDoc_STRVAR(floatinfo__doc__, +"sys.floatinfo\n\ +\n\ +A structseq holding information about the float type. It contains low level\n\ +information about the precision and internal representation. Please study\n\ +your system's :file:`float.h` for more information."); + +static PyStructSequence_Field floatinfo_fields[] = { + {"max", "DBL_MAX -- maximum representable finite float"}, + {"max_exp", "DBL_MAX_EXP -- maximum int e such that radix**(e-1) " + "is representable"}, + {"max_10_exp", "DBL_MAX_10_EXP -- maximum int e such that 10**e " + "is representable"}, + {"min", "DBL_MIN -- Minimum positive normalizer float"}, + {"min_exp", "DBL_MIN_EXP -- minimum int e such that radix**(e-1) " + "is a normalized float"}, + {"min_10_exp", "DBL_MIN_10_EXP -- minimum int e such that 10**e is " + "a normalized"}, + {"dig", "DBL_DIG -- digits"}, + {"mant_dig", "DBL_MANT_DIG -- mantissa digits"}, + {"epsilon", "DBL_EPSILON -- Difference between 1 and the next " + "representable float"}, + {"radix", "FLT_RADIX -- radix of exponent"}, + {"rounds", "FLT_ROUNDS -- addition rounds"}, + {0} +}; + +static PyStructSequence_Desc floatinfo_desc = { + "sys.floatinfo", /* name */ + floatinfo__doc__, /* doc */ + floatinfo_fields, /* fields */ + 11 +}; + PyObject * PyFloat_GetInfo(void) { - PyObject *d, *tmp; + static PyObject* floatinfo; + int pos = 0; -#define SET_FLOAT_CONST(d, key, const) \ - tmp = PyFloat_FromDouble(const); \ - if (tmp == NULL) return NULL; \ - if (PyDict_SetItemString(d, key, tmp)) return NULL; \ - Py_DECREF(tmp) -#define SET_INT_CONST(d, key, const) \ - tmp = PyLong_FromLong(const); \ - if (tmp == NULL) return NULL; \ - if (PyDict_SetItemString(d, key, tmp)) return NULL; \ - Py_DECREF(tmp) - - d = PyDict_New(); - - SET_FLOAT_CONST(d, "max", DBL_MAX); - SET_INT_CONST(d, "max_exp", DBL_MAX_EXP); - SET_INT_CONST(d, "max_10_exp", DBL_MAX_10_EXP); - SET_FLOAT_CONST(d, "min", DBL_MIN); - SET_INT_CONST(d, "min_exp", DBL_MIN_EXP); - SET_INT_CONST(d, "min_10_exp", DBL_MIN_10_EXP); - SET_INT_CONST(d, "dig", DBL_DIG); - SET_INT_CONST(d, "mant_dig", DBL_MANT_DIG); - SET_FLOAT_CONST(d, "epsilon", DBL_EPSILON); - SET_INT_CONST(d, "radix", FLT_RADIX); - SET_INT_CONST(d, "rounds", FLT_ROUNDS); + if (floatinfo != NULL) { + Py_INCREF(floatinfo); + return floatinfo; + } + PyStructSequence_InitType(&FloatInfoType, &floatinfo_desc); + + floatinfo = PyStructSequence_New(&FloatInfoType); + if (floatinfo == NULL) { + return NULL; + } - return d; -} +#define SetIntFlag(flag) \ + PyStructSequence_SET_ITEM(floatinfo, pos++, PyLong_FromLong(flag)) +#define SetDblFlag(flag) \ + PyStructSequence_SET_ITEM(floatinfo, pos++, PyFloat_FromDouble(flag)) + + SetDblFlag(DBL_MAX); + SetIntFlag(DBL_MAX_EXP); + SetIntFlag(DBL_MAX_10_EXP); + SetDblFlag(DBL_MIN); + SetIntFlag(DBL_MIN_EXP); + SetIntFlag(DBL_MIN_10_EXP); + SetIntFlag(DBL_DIG); + SetIntFlag(DBL_MANT_DIG); + SetDblFlag(DBL_EPSILON); + SetIntFlag(FLT_RADIX); + SetIntFlag(FLT_ROUNDS); +#undef SetIntFlag +#undef SetDblFlag + + if (PyErr_Occurred()) { + Py_CLEAR(floatinfo); + return NULL; + } + Py_INCREF(floatinfo); + return floatinfo; +} PyObject * PyFloat_FromDouble(double fval) Modified: python/branches/py3k/Objects/structseq.c ============================================================================== --- python/branches/py3k/Objects/structseq.c (original) +++ python/branches/py3k/Objects/structseq.c Mon Jan 14 19:49:24 2008 @@ -30,7 +30,7 @@ PyStructSequence_New(PyTypeObject *type) { PyStructSequence *obj; - + obj = PyObject_New(PyStructSequence, type); Py_SIZE(obj) = VISIBLE_SIZE_TP(type); @@ -230,11 +230,83 @@ static PyObject * structseq_repr(PyStructSequence *obj) { - PyObject *tup, *str; - tup = make_tuple(obj); - str = PyObject_Repr(tup); + /* buffer and type size were chosen well considered. */ +#define REPR_BUFFER_SIZE 512 +#define TYPE_MAXSIZE 100 + + PyObject *tup; + PyTypeObject *typ = Py_TYPE(obj); + int i, removelast = 0; + Py_ssize_t len; + char buf[REPR_BUFFER_SIZE]; + char *endofbuf, *pbuf = buf; + + /* pointer to end of writeable buffer; safes space for "...)\0" */ + endofbuf= &buf[REPR_BUFFER_SIZE-5]; + + if ((tup = make_tuple(obj)) == NULL) { + return NULL; + } + + /* "typename(", limited to TYPE_MAXSIZE */ + len = strlen(typ->tp_name) > TYPE_MAXSIZE ? TYPE_MAXSIZE : + strlen(typ->tp_name); + strncpy(pbuf, typ->tp_name, len); + pbuf += len; + *pbuf++ = '('; + + for (i=0; i < VISIBLE_SIZE(obj); i++) { + PyObject *val, *repr; + char *cname, *crepr; + + cname = typ->tp_members[i].name; + + val = PyTuple_GetItem(tup, i); + if (cname == NULL || val == NULL) { + return NULL; + } + repr = PyObject_Repr(val); + if (repr == NULL) { + Py_DECREF(tup); + return NULL; + } + crepr = PyUnicode_AsString(repr); + if (crepr == NULL) { + Py_DECREF(tup); + Py_DECREF(repr); + return NULL; + } + + /* + 3: keep space for "=" and ", " */ + len = strlen(cname) + strlen(crepr) + 3; + if ((pbuf+len) <= endofbuf) { + strcpy(pbuf, cname); + pbuf += strlen(cname); + *pbuf++ = '='; + strcpy(pbuf, crepr); + pbuf += strlen(crepr); + *pbuf++ = ','; + *pbuf++ = ' '; + removelast = 1; + Py_DECREF(repr); + } + else { + strcpy(pbuf, "..."); + pbuf += 3; + removelast = 0; + Py_DECREF(repr); + break; + } + } Py_DECREF(tup); - return str; + if (removelast) { + /* overwrite last ", " */ + pbuf-=2; + } + *pbuf++ = ')'; + *pbuf = '\0'; + + return PyUnicode_FromString(buf); } static PyObject * Modified: python/branches/py3k/Python/sysmodule.c ============================================================================== --- python/branches/py3k/Python/sysmodule.c (original) +++ python/branches/py3k/Python/sysmodule.c Mon Jan 14 19:49:24 2008 @@ -15,6 +15,7 @@ */ #include "Python.h" +#include "structseq.h" #include "code.h" #include "frameobject.h" #include "eval.h" @@ -1002,6 +1003,84 @@ return shortbranch; } + +PyDoc_STRVAR(flags__doc__, +"sys.flags\n\ +\n\ +Flags provided through command line arguments or environment vars."); + +static PyTypeObject FlagsType; + +static PyStructSequence_Field flags_fields[] = { + {"debug", "-d"}, + {"division_warning", "-Q"}, + {"inspect", "-i"}, + {"interactive", "-i"}, + {"optimize", "-O or -OO"}, + {"dont_write_bytecode", "-B"}, + /* {"no_user_site", "-s"}, */ + {"no_site", "-S"}, + {"ingnore_environment", "-E"}, + {"tabcheck", "-t or -tt"}, + {"verbose", "-v"}, +#ifdef RISCOS + {"ricos_wimp", "???"}, +#endif + /* {"unbuffered", "-u"}, */ + /* {"skip_first", "-x"}, */ + {0} +}; + +static PyStructSequence_Desc flags_desc = { + "sys.flags", /* name */ + flags__doc__, /* doc */ + flags_fields, /* fields */ +#ifdef RISCOS + 11 +#else + 10 +#endif +}; + +static PyObject* +make_flags(void) +{ + int pos = 0; + PyObject *seq; + + seq = PyStructSequence_New(&FlagsType); + if (seq == NULL) + return NULL; + +#define SetFlag(flag) \ + PyStructSequence_SET_ITEM(seq, pos++, PyLong_FromLong(flag)) + + SetFlag(Py_DebugFlag); + SetFlag(Py_DivisionWarningFlag); + SetFlag(Py_InspectFlag); + SetFlag(Py_InteractiveFlag); + SetFlag(Py_OptimizeFlag); + SetFlag(Py_DontWriteBytecodeFlag); + /* SetFlag(Py_NoUserSiteDirectory); */ + SetFlag(Py_NoSiteFlag); + SetFlag(Py_IgnoreEnvironmentFlag); + SetFlag(Py_TabcheckFlag); + SetFlag(Py_VerboseFlag); +#ifdef RISCOS + SetFlag(Py_RISCOSWimpFlag); +#endif + /* SetFlag(saw_unbuffered_flag); */ + /* SetFlag(skipfirstline); */ +#undef SetFlag + + if (PyErr_Occurred()) { + return NULL; + } + + Py_INCREF(seq); + return seq; +} + PyObject * _PySys_Init(void) { @@ -1041,9 +1120,9 @@ v = Py_BuildValue("(UUU)", "CPython", branch, svn_revision); PyDict_SetItemString(sysdict, "subversion", v); Py_XDECREF(v); - PyDict_SetItemString(sysdict, "dont_write_bytecode", - v = PyBool_FromLong(Py_DontWriteBytecodeFlag)); - Py_XDECREF(v); + PyDict_SetItemString(sysdict, "dont_write_bytecode", + v = PyBool_FromLong(Py_DontWriteBytecodeFlag)); + Py_XDECREF(v); /* * These release level checks are mutually exclusive and cover * the field, so don't get too fancy with the pre-processor! @@ -1121,6 +1200,12 @@ PyDict_SetItemString(sysdict, "warnoptions", warnoptions); } + PyStructSequence_InitType(&FlagsType, &flags_desc); + PyDict_SetItemString(sysdict, "flags", make_flags()); + /* prevent user from creating new instances */ + FlagsType.tp_init = NULL; + FlagsType.tp_new = NULL; + if (PyErr_Occurred()) return NULL; return m; From python-3000-checkins at python.org Mon Jan 14 22:39:24 2008 From: python-3000-checkins at python.org (raymond.hettinger) Date: Mon, 14 Jan 2008 22:39:24 +0100 (CET) Subject: [Python-3000-checkins] r59958 - in python/branches/py3k: Doc/library/queue.rst Lib/Queue.py Lib/test/test_queue.py Lib/test/test_socket.py Misc/NEWS Message-ID: <20080114213924.B6A081E4028@bag.python.org> Author: raymond.hettinger Date: Mon Jan 14 22:39:24 2008 New Revision: 59958 Modified: python/branches/py3k/Doc/library/queue.rst python/branches/py3k/Lib/Queue.py python/branches/py3k/Lib/test/test_queue.py python/branches/py3k/Lib/test/test_socket.py python/branches/py3k/Misc/NEWS Log: Remove Queue.empty() and Queue.full() in favor of using qsize() or trapping the Empty and Full exceptions. Modified: python/branches/py3k/Doc/library/queue.rst ============================================================================== --- python/branches/py3k/Doc/library/queue.rst (original) +++ python/branches/py3k/Doc/library/queue.rst Mon Jan 14 22:39:24 2008 @@ -53,18 +53,6 @@ this number is not reliable. -.. method:: Queue.empty() - - Return ``True`` if the queue is empty, ``False`` otherwise. Because of - multithreading semantics, this is not reliable. - - -.. method:: Queue.full() - - Return ``True`` if the queue is full, ``False`` otherwise. Because of - multithreading semantics, this is not reliable. - - .. method:: Queue.put(item[, block[, timeout]]) Put *item* into the queue. If optional args *block* is true and *timeout* is Modified: python/branches/py3k/Lib/Queue.py ============================================================================== --- python/branches/py3k/Lib/Queue.py (original) +++ python/branches/py3k/Lib/Queue.py Mon Jan 14 22:39:24 2008 @@ -23,6 +23,7 @@ import threading except ImportError: import dummy_threading as threading + self.maxsize = maxsize self._init(maxsize) # mutex must be held whenever the queue is mutating. All methods # that acquire mutex must release it before returning. mutex @@ -88,20 +89,6 @@ self.mutex.release() return n - def empty(self): - """Return True if the queue is empty, False otherwise (not reliable!).""" - self.mutex.acquire() - n = self._empty() - self.mutex.release() - return n - - def full(self): - """Return True if the queue is full, False otherwise (not reliable!).""" - self.mutex.acquire() - n = self._full() - self.mutex.release() - return n - def put(self, item, block=True, timeout=None): """Put an item into the queue. @@ -116,20 +103,22 @@ self.not_full.acquire() try: if not block: - if self._full(): + if self.maxsize > 0 and self._qsize() == self.maxsize: raise Full elif timeout is None: - while self._full(): - self.not_full.wait() + if self.maxsize > 0: + while self._qsize() == self.maxsize: + self.not_full.wait() else: if timeout < 0: raise ValueError("'timeout' must be a positive number") endtime = _time() + timeout - while self._full(): - remaining = endtime - _time() - if remaining <= 0.0: - raise Full - self.not_full.wait(remaining) + if self.maxsize > 0: + while self._qsize() == self.maxsize: + remaining = endtime - _time() + if remaining <= 0.0: + raise Full + self.not_full.wait(remaining) self._put(item) self.unfinished_tasks += 1 self.not_empty.notify() @@ -158,16 +147,16 @@ self.not_empty.acquire() try: if not block: - if self._empty(): + if not self._qsize(): raise Empty elif timeout is None: - while self._empty(): + while not self._qsize(): self.not_empty.wait() else: if timeout < 0: raise ValueError("'timeout' must be a positive number") endtime = _time() + timeout - while self._empty(): + while not self._qsize(): remaining = endtime - _time() if remaining <= 0.0: raise Empty @@ -192,20 +181,11 @@ # Initialize the queue representation def _init(self, maxsize): - self.maxsize = maxsize self.queue = deque() def _qsize(self): return len(self.queue) - # Check whether the queue is empty - def _empty(self): - return not self.queue - - # Check whether the queue is full - def _full(self): - return self.maxsize > 0 and len(self.queue) == self.maxsize - # Put a new item in the queue def _put(self, item): self.queue.append(item) Modified: python/branches/py3k/Lib/test/test_queue.py ============================================================================== --- python/branches/py3k/Lib/test/test_queue.py (original) +++ python/branches/py3k/Lib/test/test_queue.py Mon Jan 14 22:39:24 2008 @@ -9,6 +9,9 @@ QUEUE_SIZE = 5 +def qfull(q): + return q.maxsize > 0 and q.qsize() == q.maxsize + # A thread to run a function that unclogs a blocked Queue. class _TriggerThread(threading.Thread): def __init__(self, fn, args): @@ -96,7 +99,7 @@ return Queue.Queue._get(self) def FailingQueueTest(q): - if not q.empty(): + if q.qsize(): raise RuntimeError("Call this function with an empty queue") for i in range(QUEUE_SIZE-1): q.put(i) @@ -114,7 +117,7 @@ except FailingQueueException: pass q.put("last") - verify(q.full(), "Queue should be full") + verify(qfull(q), "Queue should be full") # Test a failing blocking put q.fail_next_put = True try: @@ -136,17 +139,17 @@ # Check the Queue isn't damaged. # put failed, but get succeeded - re-add q.put("last") - verify(q.full(), "Queue should be full") + verify(qfull(q), "Queue should be full") q.get() - verify(not q.full(), "Queue should not be full") + verify(not qfull(q), "Queue should not be full") q.put("last") - verify(q.full(), "Queue should be full") + verify(qfull(q), "Queue should be full") # Test a blocking put _doBlockingTest( q.put, ("full",), q.get, ()) # Empty it for i in range(QUEUE_SIZE): q.get() - verify(q.empty(), "Queue should be empty") + verify(not q.qsize(), "Queue should be empty") q.put("first") q.fail_next_get = True try: @@ -154,16 +157,16 @@ raise TestFailed("The queue didn't fail when it should have") except FailingQueueException: pass - verify(not q.empty(), "Queue should not be empty") + verify(q.qsize(), "Queue should not be empty") q.fail_next_get = True try: q.get(timeout=0.1) raise TestFailed("The queue didn't fail when it should have") except FailingQueueException: pass - verify(not q.empty(), "Queue should not be empty") + verify(q.qsize(), "Queue should not be empty") q.get() - verify(q.empty(), "Queue should be empty") + verify(not q.qsize(), "Queue should be empty") q.fail_next_get = True try: _doExceptionalBlockingTest(q.get, (), q.put, ('empty',), @@ -172,12 +175,12 @@ except FailingQueueException: pass # put succeeded, but get failed. - verify(not q.empty(), "Queue should not be empty") + verify(q.qsize(), "Queue should not be empty") q.get() - verify(q.empty(), "Queue should be empty") + verify(not q.qsize(), "Queue should be empty") def SimpleQueueTest(q): - if not q.empty(): + if q.qsize(): raise RuntimeError("Call this function with an empty queue") # I guess we better check things actually queue correctly a little :) q.put(111) @@ -186,10 +189,10 @@ "Didn't seem to queue the correct data!") for i in range(QUEUE_SIZE-1): q.put(i) - verify(not q.empty(), "Queue should not be empty") - verify(not q.full(), "Queue should not be full") + verify(q.qsize(), "Queue should not be empty") + verify(not qfull(q), "Queue should not be full") q.put("last") - verify(q.full(), "Queue should be full") + verify(qfull(q), "Queue should be full") try: q.put("full", block=0) raise TestFailed("Didn't appear to block with a full queue") @@ -206,7 +209,7 @@ # Empty it for i in range(QUEUE_SIZE): q.get() - verify(q.empty(), "Queue should be empty") + verify(not q.qsize(), "Queue should be empty") try: q.get(block=0) raise TestFailed("Didn't appear to block with an empty queue") Modified: python/branches/py3k/Lib/test/test_socket.py ============================================================================== --- python/branches/py3k/Lib/test/test_socket.py (original) +++ python/branches/py3k/Lib/test/test_socket.py Mon Jan 14 22:39:24 2008 @@ -118,7 +118,7 @@ self.__tearDown() self.done.wait() - if not self.queue.empty(): + if self.queue.qsize(): msg = self.queue.get() self.fail(msg) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Jan 14 22:39:24 2008 @@ -352,6 +352,9 @@ Library ------- +- Removed Queue.empty() and Queue.full(). Instead use Queue.qsize() or + trap the Empty and Full exceptions. + - Removed defunct parts of the random module (the Wichmann-Hill generator and the jumpahead() method). From brett at python.org Mon Jan 14 23:13:06 2008 From: brett at python.org (Brett Cannon) Date: Mon, 14 Jan 2008 14:13:06 -0800 Subject: [Python-3000-checkins] r59958 - in python/branches/py3k: Doc/library/queue.rst Lib/Queue.py Lib/test/test_queue.py Lib/test/test_socket.py Misc/NEWS In-Reply-To: <20080114213924.B6A081E4028@bag.python.org> References: <20080114213924.B6A081E4028@bag.python.org> Message-ID: When are you going to go into the trunk and add Py3K warnings for 2.6? I normally would have waiting but I didn't see a commit email for your 'random' cleanup either, Raymond. If you are planning a batch update that's fine by me, but I just want to make sure you don't forget to go back and add the proper warnings. -Brett On Jan 14, 2008 1:39 PM, raymond.hettinger wrote: > Author: raymond.hettinger > Date: Mon Jan 14 22:39:24 2008 > New Revision: 59958 > > Modified: > python/branches/py3k/Doc/library/queue.rst > python/branches/py3k/Lib/Queue.py > python/branches/py3k/Lib/test/test_queue.py > python/branches/py3k/Lib/test/test_socket.py > python/branches/py3k/Misc/NEWS > Log: > Remove Queue.empty() and Queue.full() in favor of using qsize() or trapping the Empty and Full exceptions. > > Modified: python/branches/py3k/Doc/library/queue.rst > ============================================================================== > --- python/branches/py3k/Doc/library/queue.rst (original) > +++ python/branches/py3k/Doc/library/queue.rst Mon Jan 14 22:39:24 2008 > @@ -53,18 +53,6 @@ > this number is not reliable. > > > -.. method:: Queue.empty() > - > - Return ``True`` if the queue is empty, ``False`` otherwise. Because of > - multithreading semantics, this is not reliable. > - > - > -.. method:: Queue.full() > - > - Return ``True`` if the queue is full, ``False`` otherwise. Because of > - multithreading semantics, this is not reliable. > - > - > .. method:: Queue.put(item[, block[, timeout]]) > > Put *item* into the queue. If optional args *block* is true and *timeout* is > > Modified: python/branches/py3k/Lib/Queue.py > ============================================================================== > --- python/branches/py3k/Lib/Queue.py (original) > +++ python/branches/py3k/Lib/Queue.py Mon Jan 14 22:39:24 2008 > @@ -23,6 +23,7 @@ > import threading > except ImportError: > import dummy_threading as threading > + self.maxsize = maxsize > self._init(maxsize) > # mutex must be held whenever the queue is mutating. All methods > # that acquire mutex must release it before returning. mutex > @@ -88,20 +89,6 @@ > self.mutex.release() > return n > > - def empty(self): > - """Return True if the queue is empty, False otherwise (not reliable!).""" > - self.mutex.acquire() > - n = self._empty() > - self.mutex.release() > - return n > - > - def full(self): > - """Return True if the queue is full, False otherwise (not reliable!).""" > - self.mutex.acquire() > - n = self._full() > - self.mutex.release() > - return n > - > def put(self, item, block=True, timeout=None): > """Put an item into the queue. > > @@ -116,20 +103,22 @@ > self.not_full.acquire() > try: > if not block: > - if self._full(): > + if self.maxsize > 0 and self._qsize() == self.maxsize: > raise Full > elif timeout is None: > - while self._full(): > - self.not_full.wait() > + if self.maxsize > 0: > + while self._qsize() == self.maxsize: > + self.not_full.wait() > else: > if timeout < 0: > raise ValueError("'timeout' must be a positive number") > endtime = _time() + timeout > - while self._full(): > - remaining = endtime - _time() > - if remaining <= 0.0: > - raise Full > - self.not_full.wait(remaining) > + if self.maxsize > 0: > + while self._qsize() == self.maxsize: > + remaining = endtime - _time() > + if remaining <= 0.0: > + raise Full > + self.not_full.wait(remaining) > self._put(item) > self.unfinished_tasks += 1 > self.not_empty.notify() > @@ -158,16 +147,16 @@ > self.not_empty.acquire() > try: > if not block: > - if self._empty(): > + if not self._qsize(): > raise Empty > elif timeout is None: > - while self._empty(): > + while not self._qsize(): > self.not_empty.wait() > else: > if timeout < 0: > raise ValueError("'timeout' must be a positive number") > endtime = _time() + timeout > - while self._empty(): > + while not self._qsize(): > remaining = endtime - _time() > if remaining <= 0.0: > raise Empty > @@ -192,20 +181,11 @@ > > # Initialize the queue representation > def _init(self, maxsize): > - self.maxsize = maxsize > self.queue = deque() > > def _qsize(self): > return len(self.queue) > > - # Check whether the queue is empty > - def _empty(self): > - return not self.queue > - > - # Check whether the queue is full > - def _full(self): > - return self.maxsize > 0 and len(self.queue) == self.maxsize > - > # Put a new item in the queue > def _put(self, item): > self.queue.append(item) > > Modified: python/branches/py3k/Lib/test/test_queue.py > ============================================================================== > --- python/branches/py3k/Lib/test/test_queue.py (original) > +++ python/branches/py3k/Lib/test/test_queue.py Mon Jan 14 22:39:24 2008 > @@ -9,6 +9,9 @@ > > QUEUE_SIZE = 5 > > +def qfull(q): > + return q.maxsize > 0 and q.qsize() == q.maxsize > + > # A thread to run a function that unclogs a blocked Queue. > class _TriggerThread(threading.Thread): > def __init__(self, fn, args): > @@ -96,7 +99,7 @@ > return Queue.Queue._get(self) > > def FailingQueueTest(q): > - if not q.empty(): > + if q.qsize(): > raise RuntimeError("Call this function with an empty queue") > for i in range(QUEUE_SIZE-1): > q.put(i) > @@ -114,7 +117,7 @@ > except FailingQueueException: > pass > q.put("last") > - verify(q.full(), "Queue should be full") > + verify(qfull(q), "Queue should be full") > # Test a failing blocking put > q.fail_next_put = True > try: > @@ -136,17 +139,17 @@ > # Check the Queue isn't damaged. > # put failed, but get succeeded - re-add > q.put("last") > - verify(q.full(), "Queue should be full") > + verify(qfull(q), "Queue should be full") > q.get() > - verify(not q.full(), "Queue should not be full") > + verify(not qfull(q), "Queue should not be full") > q.put("last") > - verify(q.full(), "Queue should be full") > + verify(qfull(q), "Queue should be full") > # Test a blocking put > _doBlockingTest( q.put, ("full",), q.get, ()) > # Empty it > for i in range(QUEUE_SIZE): > q.get() > - verify(q.empty(), "Queue should be empty") > + verify(not q.qsize(), "Queue should be empty") > q.put("first") > q.fail_next_get = True > try: > @@ -154,16 +157,16 @@ > raise TestFailed("The queue didn't fail when it should have") > except FailingQueueException: > pass > - verify(not q.empty(), "Queue should not be empty") > + verify(q.qsize(), "Queue should not be empty") > q.fail_next_get = True > try: > q.get(timeout=0.1) > raise TestFailed("The queue didn't fail when it should have") > except FailingQueueException: > pass > - verify(not q.empty(), "Queue should not be empty") > + verify(q.qsize(), "Queue should not be empty") > q.get() > - verify(q.empty(), "Queue should be empty") > + verify(not q.qsize(), "Queue should be empty") > q.fail_next_get = True > try: > _doExceptionalBlockingTest(q.get, (), q.put, ('empty',), > @@ -172,12 +175,12 @@ > except FailingQueueException: > pass > # put succeeded, but get failed. > - verify(not q.empty(), "Queue should not be empty") > + verify(q.qsize(), "Queue should not be empty") > q.get() > - verify(q.empty(), "Queue should be empty") > + verify(not q.qsize(), "Queue should be empty") > > def SimpleQueueTest(q): > - if not q.empty(): > + if q.qsize(): > raise RuntimeError("Call this function with an empty queue") > # I guess we better check things actually queue correctly a little :) > q.put(111) > @@ -186,10 +189,10 @@ > "Didn't seem to queue the correct data!") > for i in range(QUEUE_SIZE-1): > q.put(i) > - verify(not q.empty(), "Queue should not be empty") > - verify(not q.full(), "Queue should not be full") > + verify(q.qsize(), "Queue should not be empty") > + verify(not qfull(q), "Queue should not be full") > q.put("last") > - verify(q.full(), "Queue should be full") > + verify(qfull(q), "Queue should be full") > try: > q.put("full", block=0) > raise TestFailed("Didn't appear to block with a full queue") > @@ -206,7 +209,7 @@ > # Empty it > for i in range(QUEUE_SIZE): > q.get() > - verify(q.empty(), "Queue should be empty") > + verify(not q.qsize(), "Queue should be empty") > try: > q.get(block=0) > raise TestFailed("Didn't appear to block with an empty queue") > > Modified: python/branches/py3k/Lib/test/test_socket.py > ============================================================================== > --- python/branches/py3k/Lib/test/test_socket.py (original) > +++ python/branches/py3k/Lib/test/test_socket.py Mon Jan 14 22:39:24 2008 > @@ -118,7 +118,7 @@ > self.__tearDown() > self.done.wait() > > - if not self.queue.empty(): > + if self.queue.qsize(): > msg = self.queue.get() > self.fail(msg) > > > Modified: python/branches/py3k/Misc/NEWS > ============================================================================== > --- python/branches/py3k/Misc/NEWS (original) > +++ python/branches/py3k/Misc/NEWS Mon Jan 14 22:39:24 2008 > @@ -352,6 +352,9 @@ > Library > ------- > > +- Removed Queue.empty() and Queue.full(). Instead use Queue.qsize() or > + trap the Empty and Full exceptions. > + > - Removed defunct parts of the random module (the Wichmann-Hill generator > and the jumpahead() method). > > _______________________________________________ > Python-3000-checkins mailing list > Python-3000-checkins at python.org > http://mail.python.org/mailman/listinfo/python-3000-checkins > From python-3000-checkins at python.org Tue Jan 15 02:58:48 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Tue, 15 Jan 2008 02:58:48 +0100 (CET) Subject: [Python-3000-checkins] r59965 - python/branches/py3k/Misc/NEWS Message-ID: <20080115015848.F247C1E4006@bag.python.org> Author: christian.heimes Date: Tue Jan 15 02:58:48 2008 New Revision: 59965 Modified: python/branches/py3k/Misc/NEWS Log: Fixed merge accident Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Tue Jan 15 02:58:48 2008 @@ -12,20 +12,8 @@ Core and Builtins ----------------- -<<<<<<< .working - Issue #1762972: __file__ points to the source file instead of the pyc/pyo file if the py file exists. -======= -- Patch #1668: renamed THREADDEBUG envvar to PYTHONTHREADDEBUG. - -- Patch #602345: Add -B command line option, PYTHONDONTWRITEBYTECODE envvar - and sys.dont_write_bytecode attribute. All these can be set to forbid Python - to attempt to write compiled bytecode files. - -- Improve some exception messages when Windows fails to load an extension - module. Now we get for example '%1 is not a valid Win32 application' instead - of 'error code 193'. ->>>>>>> .merge-right.r59840 - Issue #1393: object_richcompare() returns NotImplemented instead of False if the objects aren't equal, to give the other side a chance. @@ -56,899 +44,6 @@ of PyString. -<<<<<<< .working -======= -- Issue #1534: Added ``PyFloat_GetMax()``, ``PyFloat_GetMin()`` and - ``PyFloat_GetInfo()`` to the float API. - -- Issue #1521: On 64bit platforms, using PyArgs_ParseTuple with the t# of w# - format code incorrectly truncated the length to an int, even when - PY_SSIZE_T_CLEAN is set. The str.decode method used to return incorrect - results with huge strings. - -- Issue #1402: Fix a crash on exit, when another thread is still running, and - if the deallocation of its frames somehow calls the PyGILState_Ensure() / - PyGILState_Release() functions. - -- Expose the Py_Py3kWarningFlag as sys.py3kwarning. - -- Issue #1445: Fix a SystemError when accessing the ``cell_contents`` - attribute of an empty cell object. - -- Issue #1460: The utf-7 incremental decoder did not accept truncated input. - It now correctly saves its state between chunks of data. - -- Patch #1739468: Directories and zipfiles containing a __main__.py file can - now be directly executed by passing their name to the interpreter. The - directory/zipfile is automatically inserted as the first entry in sys.path. - -- Issue #1265: Fix a problem with sys.settrace, if the tracing function uses a - generator expression when at the same time the executed code is closing a - paused generator. - -- sets and frozensets now have an isdisjoint() method. - -- optimize the performance of builtin.sum(). - -- Fix warnings found by the new version of the Coverity checker. - -- The enumerate() builtin function is no longer bounded to sequences smaller - than LONG_MAX. Formerly, it raised an OverflowError. Now, automatically - shifts from ints to longs. - -- Issue #1686386: Tuple's tp_repr did not take into account the possibility of - having a self-referential tuple, which is possible from C code. Nor did - object's tp_str consider that a type's tp_str could do something that could - lead to an inifinite recursion. Py_ReprEnter() and Py_EnterRecursiveCall(), - respectively, fixed the issues. - -- Issue #1164: It was possible to trigger deadlock when using the 'print' - statement to write to a file since the GIL was not released as needed. Now - PyObject_Print() does the right thing along with various tp_print - implementations of the built-in types and those in the collections module. - -- Issue #1147: Exceptions were directly allowing string exceptions in their - throw() method even though string exceptions no longer allowed. - -- Issue #1096: Prevent a segfault from getting the repr of a very deeply nested - list by using the recursion counter. - -- Issue #1202533: Fix infinite recursion calls triggered by calls to - PyObject_Call() never calling back out to Python code to trigger recursion - depth updates/checks. Required the creation of a static RuntimeError - instance in case normalizing an exception put the recursion check value past - its limit. Fixes crashers infinite_rec_(1|2|4|5).py. - -- Patch #1031213: Decode source line in SyntaxErrors back to its original source - encoding. - -- Py_ssize_t fields work in structmember when HAVE_LONG_LONG is not defined. - -- PEP 3123: Provide forward compatibility with Python 3.0, while keeping - backwards compatibility. Add Py_Refcnt, Py_Type, Py_Size, and - PyVarObject_HEAD_INIT. - -- Patch #1673759: add a missing overflow check when formatting floats - with %G. - -- Patch #1733960: Allow T_LONGLONG to accept ints. - -- T_PYSSIZET can now be used in PyMemberDef lists for Py_ssize_t members. - -- Prevent expandtabs() on string and unicode objects from causing a segfault - when a large width is passed on 32-bit platforms. - -- Bug #1733488: Fix compilation of bufferobject.c on AIX. - -- Bug #1722485: remove docstrings again when running with -OO. - -- Add new attribute names for function objects. All the func_* become - __*__ attributes. (Some already existed, e.g., __doc__ and __name__.) - -- Add -3 option to the interpreter to warn about features that are - deprecated and will be changed/removed in Python 3.0. - -- Patch #1686487: you can now pass any mapping after '**' in function - calls. - -- except clauses may now be spelled either "except E, target:" or - "except E as target:". This is to provide forwards compatibility with - Python 3.0. - -- Deprecate BaseException.message as per PEP 352. - -- Bug #1303614: don't expose object's __dict__ when the dict is - inherited from a builtin base. - -- When __slots__ are set to a unicode string, make it work the same as - setting a plain string, ie don't expand to single letter identifiers. - -- Request #1191699: Slices can now be pickled. - -- Request #1193128: str.translate() now allows a None argument for - translations that only remove characters without re-mapping the - remaining characters. - -- Patch #1682205: a TypeError while unpacking an iterable is no longer - masked by a generic one with the message "unpack non-sequence". - -- Remove unused file Python/fmod.c. - -- Bug #1683368: The object.__init__() and object.__new__() methods are - now stricter in rejecting excess arguments. The only time when - either allows excess arguments is when it is not overridden and the - other one is. For backwards compatibility, when both are - overridden, it is a deprecation warning (for now; maybe a Py3k - warning later). Also, type.__init__() insists on the same signature - as supported by type.__new__(). - -- Patch #1675423: PyComplex_AsCComplex() now tries to convert an object - to complex using its __complex__() method before falling back to the - __float__() method. Therefore, the functions in the cmath module now - can operate on objects that define a __complex__() method. - -- Patch #1623563: allow __class__ assignment for classes with __slots__. - The old and the new class are still required to have the same slot names. - -- Patch #1642547: Fix an error/crash when encountering syntax errors in - complex if statements. - -- Patch #1462488: Python no longer segfaults when ``object.__reduce_ex__()`` - is called with an object that is faking its type. - -- Patch #1680015: Don't modify __slots__ tuple if it contains an unicode - name. - -- Patch #1444529: the builtin compile() now accepts keyword arguments. - -- Bug #1678647: write a newline after printing an exception in any - case, even when converting the value to a string failed. - -- The dir() function has been extended to call the __dir__() method on - its argument, if it exists. If not, it will work like before. This allows - customizing the output of dir() in the presence of a __getattr__(). - -- Patch #922167: Python no longer segfaults when faced with infinitely - self-recursive reload() calls (as reported by bug #742342). - -- Patch #1675981: remove unreachable code from ``type.__new__()`` method. - -- Patch #1491866: change the complex() constructor to allow parthensized - forms. This means complex(repr(x)) now works instead of raising a - ValueError. - -- Patch #703779: unset __file__ in __main__ after running a file. This - makes the filenames the warning module prints much more sensible when - a PYTHONSTARTUP file is used. - -- Variant of patch #697613: don't exit the interpreter on a SystemExit - exception if the -i command line option or PYTHONINSPECT environment - variable is given, but break into the interactive interpreter just like - on other exceptions or normal program exit. - -- Patch #1638879: don't accept strings with embedded NUL bytes in long(). - -- Bug #1674503: close the file opened by execfile() in an error condition. - -- Patch #1674228: when assigning a slice (old-style), check for the - sq_ass_slice instead of the sq_slice slot. - -- When printing an unraisable error, don't print exceptions. before the name. - This duplicates the behavior whening normally printing exceptions. - -- Bug #1653736: Properly discard third argument to slot_nb_inplace_power. - -- PEP 352: Raising a string exception now triggers a TypeError. Attempting to - catch a string exception raises DeprecationWarning. - -- Bug #1377858: Fix the segfaulting of the interpreter when an object created - a weakref on itself during a __del__ call for new-style classes (classic - classes still have the bug). - -- Bug #1579370: Make PyTraceBack_Here use the current thread, not the - frame's thread state. - -- patch #1630975: Fix crash when replacing sys.stdout in sitecustomize.py - -- Bug #1637022: Prefix AST symbols with _Py_. - -- Prevent seg fault on shutdown which could occur if an object - raised a warning. - -- Bug #1566280: Explicitly invoke threading._shutdown from Py_Main, - to avoid relying on atexit. - -- Bug #1590891: random.randrange don't return correct value for big number - -- Patch #1586791: Better exception messages for some operations on strings, - tuples and lists. - -- Bug #1067760: Deprecate passing floats to file.seek. - -- Bug #1591996: Correctly forward exception in instance_contains(). - -- Bug #1588287: fix invalid assertion for `1,2` in debug builds. - -- Bug #1576657: when setting a KeyError for a tuple key, make sure that - the tuple isn't used as the "exception arguments tuple". - -- Bug #1565514, SystemError not raised on too many nested blocks. - -- Bug #1576174: WindowsError now displays the windows error code - again, no longer the posix error code. - -- Patch #1549049: Support long values in structmember, issue warnings - if the assigned value for structmember fields gets truncated. - -- Update the peephole optimizer to remove more dead code (jumps after returns) - and inline unconditional jumps to returns. - -- Bug #1545497: when given an explicit base, int() did ignore NULs - embedded in the string to convert. - -- Bug #1569998: break inside a try statement (outside a loop) is now - recognized and rejected. - -- list.pop(x) accepts any object x following the __index__ protocol. - -- Fix some leftovers from the conversion from int to Py_ssize_t - (relevant to strings and sequences of more than 2**31 items). - -- A number of places, including integer negation and absolute value, - were fixed to not rely on undefined behaviour of the C compiler - anymore. - -- Bug #1566800: make sure that EnvironmentError can be called with any - number of arguments, as was the case in Python 2.4. - -- Patch #1567691: super() and new.instancemethod() now don't accept - keyword arguments any more (previously they accepted them, but didn't - use them). - -- Fix a bug in the parser's future statement handling that led to "with" - not being recognized as a keyword after, e.g., this statement: - from __future__ import division, with_statement - -- Bug #1557232: fix seg fault with def f((((x)))) and def f(((x),)). - -- Fix %zd string formatting on Mac OS X so it prints negative numbers. - -- Allow exception instances to be directly sliced again. - -- Bug #1551432: Exceptions do not define an explicit __unicode__ method. This - allows calling unicode() on exceptions classes directly to succeed. - -- Make _PyGILState_NoteThreadState() static, it was not used anywhere - outside of pystate.c and should not be necessary. - -- Bug #1542051: Exceptions now correctly call PyObject_GC_UnTrack. - Also make sure that every exception class has __module__ set to - 'exceptions'. - -- Bug #1550983: emit better error messages for erroneous relative - imports (if not in package and if beyond toplevel package). - -- Overflow checking code in integer division ran afoul of new gcc - optimizations. Changed to be more standard-conforming. - -- Patch #1542451: disallow continue anywhere under a finally. - -- Patch #1546288: fix seg fault in dict_equal due to ref counting bug. - -- The return tuple from str.rpartition(sep) is (tail, sep, head) where - head is the original string if sep was not found. - -- Bug #1520864: unpacking singleton tuples in list comprehensions and - generator expressions (x for x, in ... ) works again. Fixing this problem - required changing the .pyc magic number. This means that .pyc files - generated before 2.5c2 will be regenerated. - -- with and as are now keywords. - -- Bug #1664966: Fix crash in exec if Unicode filename can't be decoded. - -- Issue #1537: Changed GeneratorExit's base class from Exception to BaseException. - -Library -------- - -- Removed Queue.empty() and Queue.full(). Instead use Queue.qsize() or - trap the Empty and Full exceptions. - -- Removed defunct parts of the random module (the Wichmann-Hill generator - and the jumpahead() method). - -- random.sample() now explicitly supports all sequences and sets while - explicitly excluding mappings. - -- Patch #467924: add ZipFile.extract() and ZipFile.extractall() in the - zipfile module. - -- Issue #1646: Make socket support the TIPC protocol. - -- Bug #1742: return os.curdir from os.path.relpath() if both arguments are - equal instead of raising an exception. - -- Patch #1637: fix urlparse for URLs like 'http://x.com?arg=/foo'. - -- Patch #1698: allow '@' in username parsed by urlparse.py. - -- Issue #1735: TarFile.extractall() now correctly sets directory permissions - and times. - -- Bug #1713: posixpath.ismount() claims symlink to a mountpoint is a mountpoint. - -- Bug #1687: Fxed plistlib.py restricts to Python int when writing - -- Issue #1700: Regular expression inline flags incorrectly handle certain - unicode characters. - -- Issue #1689: PEP 3141, numeric abstract base classes. - -- Tk issue #1851526: Return results from Python callbacks to Tcl as - Tcl objects. - -- Issue #1642: Fix segfault in ctypes when trying to delete attributes. - -- Issue #1727780: Support loading pickles of random.Random objects created - on 32-bit systems on 64-bit systems, and vice versa. As a consequence - of the change, Random pickles created by Python 2.6 cannot be loaded - in Python 2.5. - -- Issue #1455: The distutils package now supports VS 2005 and VS 2008 for - both the msvccompiler and cygwincompiler. - -- Issue #1531: tarfile.py: Read fileobj from the current offset, do not - seek to the start. - -- Issue #1534: Added a dictionary sys.float_info with information about the - internal floating point type to the sys module. - -- Issue 1429818: patch for trace and doctest modules so they play nicely - together. - -- doctest made a bad assumption that a package's __loader__.get_data() - method used universal newlines. - -- Issue #1705170: contextlib.contextmanager was still swallowing - StopIteration in some cases. This should no longer happen. - -- Issue #1292: On alpha, arm, ppc, and s390 linux systems the - --with-system-ffi configure option defaults to "yes". - -- IN module for FreeBSD 8 is added and preexisting FreeBSD 6 and 7 - files are updated. - -- Issues #1181, #1287: unsetenv() is now called when the os.environ.pop() - and os.environ.clear() methods are used. - -- ctypes will now work correctly on 32-bit systems when Python is - configured with --with-system-ffi. - -- Patch #1203: ctypes now does work on OS X when Python is built with - --disable-toolbox-glue. - -- collections.deque() now supports a "maxlen" argument. - -- itertools.count() is no longer bounded to LONG_MAX. Formerly, it raised - an OverflowError. Now, automatically shifts from ints to longs. - -- Patch #1541463: optimize performance of cgi.FieldStorage operations. - -- Decimal is fully updated to the latest Decimal Specification (v1.66). - -- Bug #1153: repr.repr() now doesn't require set and dictionary items - to be orderable to properly represent them. - -- A 'c_longdouble' type was added to the ctypes module. - -- Bug #1709599: Run test_1565150 only if the file system is NTFS. - -- When encountering a password-protected robots.txt file the RobotFileParser - no longer prompts interactively for a username and password (bug 813986). - -- TarFile.__init__() no longer fails if no name argument is passed and - the fileobj argument has no usable name attribute (e.g. StringIO). - -- The functools module now provides 'reduce', for forward compatibility - with Python 3000. - -- Server-side SSL support and cert verification added, by Bill Janssen. - -- socket.ssl deprecated; use new ssl module instead. - -- uuid creation is now threadsafe. - -- EUC-KR codec now handles the cheot-ga-keut composed make-up hangul - syllables. - -- GB18030 codec now can encode additional two-byte characters that - are missing in GBK. - -- Add new codecs for UTF-32, UTF-32-LE and UTF-32-BE. - -- Bug #1704793: Return UTF-16 pair if unicodedata.lookup cannot - represent the result in a single character. - -- Bug #978833: Close https sockets by releasing the _ssl object. - -- Change location of the package index to pypi.python.org/pypi - -- Bug #1701409: Fix a segfault in printing ctypes.c_char_p and - ctypes.c_wchar_p when they point to an invalid location. As a - sideeffect the representation of these instances has changed. - -- tarfile.py: Added "exclude" keyword argument to TarFile.add(). - -- Bug #1734723: Fix repr.Repr() so it doesn't ignore the maxtuple attribute. - -- The urlopen function of urllib2 now has an optional timeout parameter (note - that it actually works with HTTP, HTTPS, FTP and FTPS connections). - -- In ftplib, the FTP.ntransfercmd method, when in passive mode, now uses - the socket.create_connection function, using the timeout specified at - connection time. - -- Bug #1728403: Fix a bug that CJKCodecs StreamReader hangs when it - reads a file that ends with incomplete sequence and sizehint argument - for .read() is specified. - -- Bug #1730389: Change time.strptime() to use ``\s+`` instead of ``\s*`` when - matching spaces in the specified format argument. - -- SF 1668596/1720897: distutils now copies data files - even if package_dir is empty. - -- sha now raises a DeprecationWarning upon import. - -- md5 now raises a DeprecationWarning upon import. - -- Issue1385: The hmac module now computes the correct hmac when using hashes - with a block size other than 64 bytes (such as sha384 and sha512). - -- mimify now raises a DeprecationWarning upon import. - -- MimeWriter now raises a DeprecationWarning upon import. - -- tarfile.py: Improved unicode support. Unicode input names are now - officially supported. Added "errors" argument to the TarFile class. - -- urllib.ftpwrapper class now accepts an optional timeout. - -- shlex.split() now has an optional "posix" parameter. - -- The posixfile module now raises a DeprecationWarning. - -- Remove the gopherlib module. This also leads to the removal of gopher - support in urllib/urllib2. - -- Fix bug in marshal where bad data would cause a segfault due to - lack of an infinite recursion check. - -- Removed plat-freebsd2 and plat-freebsd3 directories (and IN.py in - the directories). - -- HTML-escape the plain traceback in cgitb's HTML output, to prevent - the traceback inadvertently or maliciously closing the comment and - injecting HTML into the error page. - -- The popen2 module and os.popen* are deprecated. Use the subprocess module. - -- Added an optional credentials argument to SMTPHandler, for use with SMTP - servers which require authentication. - -- Patch #1695948: Added optional timeout parameter to SocketHandler. - -- Bug #1652788: Minor fix for currentframe. - -- Patch #1598415: Added WatchedFileHandler to better support external - log file rotation using e.g. newsyslog or logrotate. This handler is - only useful in Unix/Linux environments. - -- Bug #1706381: Specifying the SWIG option "-c++" in the setup.py file - (as opposed to the command line) will now write file names ending in - ".cpp" too. - -- As specified in RFC 2616, an HTTP response like 2xx indicates that - the client's request was successfully received, understood, and accepted. - Now in these cases no error is raised in urllib (issue #1177) and urllib2. - -- Bug #1290505: time.strptime's internal cache of locale information is now - properly recreated when the locale is changed. - -- Patch #1685563: remove (don't add) duplicate paths in distutils.MSVCCompiler. - -- Added a timeout parameter to the constructor of other protocols - (telnetlib, ftplib, smtplib and poplib). This is second part of the - work started with create_connection() and timeout in httplib, and - closes patch #723312. - -- Patch #1676823: Added create_connection() to socket.py, which may be - called with a timeout, and use it from httplib (whose HTTPConnection - and HTTPSConnection now accept an optional timeout). - -- Bug #978833: Revert r50844, as it broke _socketobject.dup. - -- Bug #1675967: re patterns pickled with Python 2.4 and earlier can - now be unpickled with Python 2.5 and newer. - -- Patch #1630118: add a SpooledTemporaryFile class to tempfile.py. - -- Patch #1273829: os.walk() now has a "followlinks" parameter. If set to - True (which is not the default), it visits symlinks pointing to - directories. - -- Bug #1681228: the webbrowser module now correctly uses the default - GNOME or KDE browser, depending on whether there is a session of one - of those present. Also, it tries the Windows default browser before - trying Mozilla variants. - -- Patch #1339796: add a relpath() function to os.path. - -- Patch #1681153: the wave module now closes a file object it opened if - initialization failed. - -- Bug #767111: fix long-standing bug in urllib which caused an - AttributeError instead of an IOError when the server's response didn't - contain a valid HTTP status line. - -- Patch #957650: "%var%" environment variable references are now properly - expanded in ntpath.expandvars(), also "~user" home directory references - are recognized and handled on Windows. - -- Patch #1429539: pdb now correctly initializes the __main__ module for - the debugged script, which means that imports from __main__ work - correctly now. - -- The nonobvious commands.getstatus() function is now deprecated. - -- Patch #1393667: pdb now has a "run" command which restarts the debugged - Python program, optionally with different arguments. - -- Patch #1649190: Adding support for _Bool to ctypes as c_bool. - -- Patch #1530482: add pydoc.render_doc() which returns the documentation - for a thing instead of paging it to stdout, which pydoc.doc() does. - -- Patch #1533909: the timeit module now accepts callables in addition to - strings for the code to time and the setup code. Also added two - convenience functions for instantiating a Timer and calling its methods. - -- Patch #1537850: tempfile.NamedTemporaryFile now has a "delete" parameter - which can be set to False to prevent the default delete-on-close - behavior. - -- Patch #1581073: add a flag to textwrap that prevents the dropping of - whitespace while wrapping. - -- Patch #1603688: ConfigParser.SafeConfigParser now checks values that - are set for invalid interpolation sequences that would lead to errors - on reading back those values. - -- Added support for the POSIX.1-2001 (pax) format to tarfile.py. Extended - and cleaned up the test suite. Added a new testtar.tar. - -- Patch #1449244: Support Unicode strings in - email.message.Message.{set_charset,get_content_charset}. - -- Patch #1542681: add entries for "with", "as" and "CONTEXTMANAGERS" to - pydoc's help keywords. - -- Patch #1555098: use str.join() instead of repeated string - concatenation in robotparser. - -- Patch #1635454: the csv.DictWriter class now includes the offending - field names in its exception message if you try to write a record with - a dictionary containing fields not in the CSV field names list. - -- Patch #1668100: urllib2 now correctly raises URLError instead of - OSError if accessing a local file via the file:// protocol fails. - -- Patch #1677862: Require a space or tab after import in .pth files. - -- Patch #1192590: Fix pdb's "ignore" and "condition" commands so they trap - the IndexError caused by passing in an invalid breakpoint number. - -- Patch #1599845: Add an option to disable the implicit calls to server_bind() - and server_activate() in the constructors for TCPServer, SimpleXMLRPCServer - and DocXMLRPCServer. - -- Bug #1531963: Make SocketServer.TCPServer's server_address always - be equal to calling getsockname() on the server's socket. Fixed by - patch #1545011. - -- Bug #1651235: When a tuple was passed to a ctypes function call, - Python would crash instead of raising an error. - -- Bug #1646630: ctypes.string_at(buf, 0) and ctypes.wstring_at(buf, 0) - returned string up to the first NUL character. - -- Patch #957003: Implement smtplib.LMTP. - -- Patch #1481079: add support for HTTP_REFERER to CGIHTTPServer. - -- Patch #1675424: Added tests for uncovered code in the zipfile module. - The KeyError raised by Zipfile.getinfo for nonexistent names now has - a descriptive message. - -- Bug #1115886: os.path.splitext('.cshrc') gives now ('.cshrc', ''). - -- unittest now verifies more of its assumptions. In particular, TestCase - and TestSuite subclasses (not instances) are no longer accepted in - TestSuite.addTest(). This should cause no incompatibility since it - never made sense with ordinary subclasses -- the failure just occurred - later, with a more cumbersome exception. - -- Patch #787789: allow to pass custom TestRunner instances to unittest's - main() function. - -- Patches #1550273, #1550272: fix a few bugs in unittest and add a - comprehensive test suite for the module. - -- Patch #1001604: glob.glob() now returns unicode filenames if it was - given a unicode argument and os.listdir() returns unicode filenames. - -- Patch #1673619: setup.py identifies extension modules it doesn't know how - to build and those it knows how to build but that fail to build. - -- Patch #912410: Replace HTML entity references for attribute values - in HTMLParser. - -- Patch #1663234: you can now run doctest on test files and modules - using "python -m doctest [-v] filename ...". - -- Patch #1121142: Implement ZipFile.open. - -- Taught setup.py how to locate Berkeley DB on Macs using MacPorts. - -- Added heapq.merge() for merging sorted input streams. - -- Added collections.namedtuple() for assigning field names to tuples. - -- Added itertools.izip_longest(). - -- Have the encoding package's search function dynamically import using absolute - import semantics. - -- Patch #1647484: Renamed GzipFile's filename attribute to name. - -- Patch #1517891: Mode 'a' for ZipFile now creates the file if it - doesn't exist. - -- Patch #698833: Support file decryption in zipfile. - -- Patch #685268: Consider a package's __path__ in imputil. - -- Patch 1463026: Support default namespace in XMLGenerator. - -- Patch 1571379: Make trace's --ignore-dir facility work in the face of - relative directory names. - -- Bug #1600860: Search for shared python library in LIBDIR, - not lib/python/config, on "linux" and "gnu" systems. - -- Patch #1652681: tarfile.py: create nonexistent files in append mode and - allow appending to empty files. - -- Bug #1124861: Automatically create pipes if GetStdHandle fails in - subprocess. - -- Patch #1634778: add missing encoding aliases for iso8859_15 and - iso8859_16. - -- Patch #1638243: the compiler package is now able to correctly compile - a with statement; previously, executing code containing a with statement - compiled by the compiler package crashed the interpreter. - -- Bug #1643943: Fix time.strptime's support for the %U directive. - -- Patch #1507247: tarfile.py: use current umask for intermediate - directories. - -- Patch #1627441: close sockets properly in urllib2. - -- Bug #494589: make ntpath.expandvars behave according to its docstring. - -- Changed platform module API python_version_tuple() to actually - return a tuple (it used to return a list). - -- Added new platform module APIs python_branch(), python_revision(), - python_implementation() and linux_distribution(). - -- Added support for IronPython and Jython to the platform module. - -- The sets module has been deprecated. Use the built-in set/frozenset types - instead. - -- Bug #1610795: make ctypes.util.find_library work on BSD systems. - -- Fixes for 64-bit Windows: In ctypes.wintypes, correct the - definitions of HANDLE, WPARAM, LPARAM data types. Make - parameterless foreign function calls work. - -- The version number of the ctypes package changed to "1.1.0". - -- Bug #1627575: logging: Added _open() method to FileHandler which can - be used to reopen files. The FileHandler instance now saves the - encoding (which can be None) in an attribute called "encoding". - -- Bug #411881: logging.handlers: bare except clause removed from - SMTPHandler.emit. Now, only ImportError is trapped. - -- Bug #411881: logging.handlers: bare except clause removed from - SocketHandler.createSocket. Now, only socket.error is trapped. - -- Bug #411881: logging: bare except clause removed from LogRecord.__init__. - Now, only ValueError, TypeError and AttributeError are trapped. - -- Patch #1504073: Fix tarfile.open() for mode "r" with a fileobj argument. - -- Patch #1182394 from Shane Holloway: speed up HMAC.hexdigest. - -- Patch #1262036: Prevent TarFiles from being added to themselves under - certain conditions. - -- Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell() - work correctly together with readline(). - -- Patch #1484695: The tarfile module now raises a HeaderError exception - if a buffer given to frombuf() is invalid. - -- Bug #1503765: Fix a problem in logging.config with spaces in comma- - separated lists read from logging config files. - -- Patch #1604907: Fix problems in logging.handlers caused at logging shutdown - when syslog handlers fail to initialize because of syslogd problems. - -- Patch #1608267: fix a race condition in os.makedirs() if the directory - to be created is already there. - -- Patch #1610437: fix a tarfile bug with long filename headers. - -- Patch #1371075: Make ConfigParser accept optional dict type - for ordering, sorting, etc. - -- Bug #1563807: _ctypes built on AIX fails with ld ffi error. - -- Bug #1598620: A ctypes Structure cannot contain itself. - -- Patch #1070046: Marshal new-style objects like InstanceType - in xmlrpclib. - -- cStringIO.truncate(-1) now raises an IOError, like StringIO and - regular files. - -- Patch #1472877: Fix Tix subwidget name resolution. - -- Patch #1594554: Always close a tkSimpleDialog on ok(), even - if an exception occurs. - -- Patch #1538878: Don't make tkSimpleDialog dialogs transient if - the parent window is withdrawn. - -- Bug #1597824: return the registered function from atexit.register() - to facilitate usage as a decorator. - -- Patch #1360200: Use unmangled_version RPM spec field to deal with - file name mangling. - -- Patch #1359217: Process 2xx response in an ftplib transfer - that precedes an 1xx response. - -- Patch #1355023: support whence argument for GzipFile.seek. - -- Patch #1065257: Support passing open files as body in - HTTPConnection.request(). - -- Bug #1569790: mailbox.py: Maildir.get_folder() and MH.get_folder() - weren't passing the message factory on to newly created Maildir/MH - objects. - -- Patch #1514543: mailbox.py: In the Maildir class, report errors if there's - a filename clash instead of possibly losing a message. (Patch by David - Watson.) - -- Patch #1514544: Try to ensure that messages/indexes have been physically - written to disk after calling .flush() or .close(). (Patch by David - Watson.) - -- Patch #1592250: Add elidge argument to Tkinter.Text.search. - -- Patch #838546: Make terminal become controlling in pty.fork() - -- Patch #1351744: Add askyesnocancel helper for tkMessageBox. - -- Patch #1060577: Extract list of RPM files from spec file in - bdist_rpm - -- Bug #1586613: fix zlib and bz2 codecs' incremental en/decoders. - -- Patch #1583880: fix tarfile's problems with long names and posix/ - GNU modes. - -- Bug #1586448: the compiler module now emits the same bytecode for - list comprehensions as the builtin compiler, using the LIST_APPEND - opcode. - -- Fix codecs.EncodedFile which did not use file_encoding in 2.5.0, and - fix all codecs file wrappers to work correctly with the "with" - statement (bug #1586513). - -- Lib/modulefinder.py now handles absolute and relative imports - correctly. - -- Patch #1567274: Support SMTP over TLS. - -- Patch #1560695: Add .note.GNU-stack to ctypes' sysv.S so that - ctypes isn't considered as requiring executable stacks. - -- ctypes callback functions only support 'fundamental' data types as - result type. Raise an error when something else is used. This is a - partial fix for Bug #1574584. - -- Fix turtle so that time.sleep is imported for the entire library. Allows - the demo2 function to be executed on its own instead of only when the - module is run as a script. - -- Bug #813342: Start the IDLE subprocess with -Qnew if the parent - is started with that option. - -- Bug #1565150: Fix subsecond processing for os.utime on Windows. - -- Support for MSVC 8 was added to bdist_wininst. - -- Bug #1446043: correctly raise a LookupError if an encoding name given - to encodings.search_function() contains a dot. - -- Bug #1560617: in pyclbr, return full module name not only for classes, - but also for functions. - -- Bug #1457823: cgi.(Sv)FormContentDict's constructor now takes - keep_blank_values and strict_parsing keyword arguments. - -- Bug #1566602: correct failure of posixpath unittest when $HOME ends - with a slash. - -- Bug #1565661: in webbrowser, split() the command for the default - GNOME browser in case it is a command with args. - -- Made the error message for time.strptime when the data data and format do - match be more clear. - -- Fix a bug in traceback.format_exception_only() that led to an error - being raised when print_exc() was called without an exception set. - In version 2.4, this printed "None", restored that behavior. - -- Make webbrowser.BackgroundBrowser usable in Windows (it wasn't because - the close_fds arg to subprocess.Popen is not supported). - -- Reverted patch #1504333 to sgmllib because it introduced an infinite loop. - -- Patch #1553314: Fix the inspect.py slowdown that was hurting IPython & SAGE - by adding smarter caching in inspect.getmodule() - -- Fix missing import of the types module in logging.config. - -- Patch #1550886: Fix decimal module context management implementation - to match the localcontext() example from PEP 343. - -- Bug #1545341: The 'classifier' keyword argument to the Distutils setup() - function now accepts tuples as well as lists. - -- Bug #1541863: uuid.uuid1 failed to generate unique identifiers - on systems with low clock resolution. - -- Bug #1531862: Do not close standard file descriptors in subprocess. - -- idle: Honor the "Cancel" action in the save dialog (Debian bug #299092). - -- Fix utf-8-sig incremental decoder, which didn't recognise a BOM when the - first chunk fed to the decoder started with a BOM, but was longer than 3 bytes. - -- The implementation of UnicodeError objects has been simplified (start and end - attributes are now stored directly as Py_ssize_t members). - ->>>>>>> .merge-right.r59840 Extension Modules ----------------- From python-3000-checkins at python.org Tue Jan 15 03:01:21 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Tue, 15 Jan 2008 03:01:21 +0100 (CET) Subject: [Python-3000-checkins] r59966 - in python/branches/py3k: Lib/test/test_long.py Misc/NEWS Objects/longobject.c Message-ID: <20080115020121.26AE51E4006@bag.python.org> Author: christian.heimes Date: Tue Jan 15 03:01:20 2008 New Revision: 59966 Modified: python/branches/py3k/Lib/test/test_long.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/longobject.c Log: long(float('nan')) raises an OverflowError as discussed on the mailing list a week ago Modified: python/branches/py3k/Lib/test/test_long.py ============================================================================== --- python/branches/py3k/Lib/test/test_long.py (original) +++ python/branches/py3k/Lib/test/test_long.py Tue Jan 15 03:01:20 2008 @@ -539,7 +539,7 @@ def test_nan_inf(self): self.assertRaises(OverflowError, int, float('inf')) - self.assertEqual(int(float('nan')), 0) + self.assertRaises(OverflowError, int, float('nan')) def test_main(): test_support.run_unittest(LongTest) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Tue Jan 15 03:01:20 2008 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Object/longobject.c: long(float('nan')) raises an OverflowError instead + of returning 0. + - Issue #1762972: __file__ points to the source file instead of the pyc/pyo file if the py file exists. Modified: python/branches/py3k/Objects/longobject.c ============================================================================== --- python/branches/py3k/Objects/longobject.c (original) +++ python/branches/py3k/Objects/longobject.c Tue Jan 15 03:01:20 2008 @@ -255,7 +255,9 @@ return NULL; } if (Py_IS_NAN(dval)) { - return PyLong_FromLong(0L); + PyErr_SetString(PyExc_OverflowError, + "cannot convert float NaN to int"); + return NULL; } if (dval < 0.0) { neg = 1; From python-3000-checkins at python.org Tue Jan 15 18:41:39 2008 From: python-3000-checkins at python.org (guido.van.rossum) Date: Tue, 15 Jan 2008 18:41:39 +0100 (CET) Subject: [Python-3000-checkins] r59979 - python/branches/py3k/Tools/i18n/pygettext.py Message-ID: <20080115174139.34C121E4029@bag.python.org> Author: guido.van.rossum Date: Tue Jan 15 18:41:38 2008 New Revision: 59979 Modified: python/branches/py3k/Tools/i18n/pygettext.py Log: Patch #1830 by Peter Harris, fix some 2.x-isms. Modified: python/branches/py3k/Tools/i18n/pygettext.py ============================================================================== --- python/branches/py3k/Tools/i18n/pygettext.py (original) +++ python/branches/py3k/Tools/i18n/pygettext.py Tue Jan 15 18:41:38 2008 @@ -453,11 +453,9 @@ # sort all the entries by their first item. reverse = {} for k, v in self.__messages.items(): - keys = v.keys() - keys.sort() + keys = sorted(v.keys()) reverse.setdefault(tuple(keys), []).append((k, v)) - rkeys = reverse.keys() - rkeys.sort() + rkeys = sorted(reverse.keys()) for rkey in rkeys: rentries = reverse[rkey] rentries.sort() @@ -469,8 +467,7 @@ # k is the message string, v is a dictionary-set of (filename, # lineno) tuples. We want to sort the entries in v first by # file name and then by line number. - v = v.keys() - v.sort() + v = sorted(v.keys()) if not options.writelocations: pass # location comments are different b/w Solaris and GNU: @@ -662,7 +659,6 @@ if __name__ == '__main__': main() # some more test strings - _(u'a unicode string') # this one creates a warning _('*** Seen unexpected token "%(token)s"') % {'token': 'test'} _('more' 'than' 'one' 'string') From python-3000-checkins at python.org Tue Jan 15 21:42:01 2008 From: python-3000-checkins at python.org (raymond.hettinger) Date: Tue, 15 Jan 2008 21:42:01 +0100 (CET) Subject: [Python-3000-checkins] r59986 - python/branches/py3k/Lib/Queue.py Message-ID: <20080115204201.0FC561E4010@bag.python.org> Author: raymond.hettinger Date: Tue Jan 15 21:42:00 2008 New Revision: 59986 Modified: python/branches/py3k/Lib/Queue.py Log: Refactor if/elif chain for clarity and speed Modified: python/branches/py3k/Lib/Queue.py ============================================================================== --- python/branches/py3k/Lib/Queue.py (original) +++ python/branches/py3k/Lib/Queue.py Tue Jan 15 21:42:00 2008 @@ -102,18 +102,17 @@ """ self.not_full.acquire() try: - if not block: - if self.maxsize > 0 and self._qsize() == self.maxsize: - raise Full - elif timeout is None: - if self.maxsize > 0: + if self.maxsize > 0: + if not block: + if self._qsize() == self.maxsize: + raise Full + elif timeout is None: while self._qsize() == self.maxsize: self.not_full.wait() - else: - if timeout < 0: + elif timeout < 0: raise ValueError("'timeout' must be a positive number") - endtime = _time() + timeout - if self.maxsize > 0: + else: + endtime = _time() + timeout while self._qsize() == self.maxsize: remaining = endtime - _time() if remaining <= 0.0: @@ -152,9 +151,9 @@ elif timeout is None: while not self._qsize(): self.not_empty.wait() + elif timeout < 0: + raise ValueError("'timeout' must be a positive number") else: - if timeout < 0: - raise ValueError("'timeout' must be a positive number") endtime = _time() + timeout while not self._qsize(): remaining = endtime - _time() From python-3000-checkins at python.org Tue Jan 15 22:44:54 2008 From: python-3000-checkins at python.org (guido.van.rossum) Date: Tue, 15 Jan 2008 22:44:54 +0100 (CET) Subject: [Python-3000-checkins] r59990 - in python/branches/py3k: Demo/classes/Rat.py Doc/glossary.rst Doc/library/numeric.rst Doc/library/queue.rst Doc/library/rational.rst Doc/library/sys.rst Doc/library/test.rst Doc/whatsnew/2.6.rst Lib/numbers.py Lib/pdb.py Lib/rational.py Lib/test/test_rational.py Lib/test/test_sys.py Lib/zipfile.py Modules/_ctypes/libffi/configure Modules/_ctypes/libffi/configure.ac Python/sysmodule.c Message-ID: <20080115214454.075071E4010@bag.python.org> Author: guido.van.rossum Date: Tue Jan 15 22:44:53 2008 New Revision: 59990 Added: python/branches/py3k/Doc/library/rational.rst - copied unchanged from r59984, python/trunk/Doc/library/rational.rst python/branches/py3k/Lib/rational.py - copied, changed from r59984, python/trunk/Lib/rational.py python/branches/py3k/Lib/test/test_rational.py - copied, changed from r59984, python/trunk/Lib/test/test_rational.py Removed: python/branches/py3k/Demo/classes/Rat.py Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/glossary.rst python/branches/py3k/Doc/library/numeric.rst python/branches/py3k/Doc/library/queue.rst python/branches/py3k/Doc/library/sys.rst python/branches/py3k/Doc/library/test.rst python/branches/py3k/Doc/whatsnew/2.6.rst python/branches/py3k/Lib/numbers.py python/branches/py3k/Lib/pdb.py python/branches/py3k/Lib/test/test_sys.py python/branches/py3k/Lib/zipfile.py python/branches/py3k/Modules/_ctypes/libffi/configure python/branches/py3k/Modules/_ctypes/libffi/configure.ac python/branches/py3k/Python/sysmodule.c Log: Merged revisions 59952-59984 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r59952 | thomas.heller | 2008-01-14 02:35:28 -0800 (Mon, 14 Jan 2008) | 1 line Issue 1821: configure libffi for amd64 on FreeeBSD. ........ r59953 | andrew.kuchling | 2008-01-14 06:48:43 -0800 (Mon, 14 Jan 2008) | 1 line Update description of float_info ........ r59959 | raymond.hettinger | 2008-01-14 14:58:05 -0800 (Mon, 14 Jan 2008) | 1 line Fix 1698398: Zipfile.printdir() crashed because the format string expected a tuple object of length six instead of a time.struct_time object. ........ r59961 | andrew.kuchling | 2008-01-14 17:29:16 -0800 (Mon, 14 Jan 2008) | 1 line Typo fixes ........ r59962 | andrew.kuchling | 2008-01-14 17:29:44 -0800 (Mon, 14 Jan 2008) | 1 line Markup fix ........ r59963 | andrew.kuchling | 2008-01-14 17:47:32 -0800 (Mon, 14 Jan 2008) | 1 line Add many items ........ r59964 | andrew.kuchling | 2008-01-14 17:55:32 -0800 (Mon, 14 Jan 2008) | 1 line Repair unfinished sentence ........ r59967 | raymond.hettinger | 2008-01-14 19:02:37 -0800 (Mon, 14 Jan 2008) | 5 lines Issue 1820: structseq objects did not work with the % formatting operator or isinstance(t, tuple). Orignal patch (without tests) by Leif Walsh. ........ r59968 | raymond.hettinger | 2008-01-14 19:07:42 -0800 (Mon, 14 Jan 2008) | 1 line Tighten the definition of a named tuple. ........ r59969 | skip.montanaro | 2008-01-14 19:40:20 -0800 (Mon, 14 Jan 2008) | 3 lines Better (?) text describing the lack of guarantees provided by qsize(), empty() and full(). ........ r59970 | raymond.hettinger | 2008-01-14 21:39:59 -0800 (Mon, 14 Jan 2008) | 1 line Temporarily revert 59967 until GC can be added. ........ r59971 | raymond.hettinger | 2008-01-14 21:46:43 -0800 (Mon, 14 Jan 2008) | 1 line Small grammar nit ........ r59972 | georg.brandl | 2008-01-14 22:55:56 -0800 (Mon, 14 Jan 2008) | 2 lines Typo. ........ r59973 | georg.brandl | 2008-01-14 22:58:15 -0800 (Mon, 14 Jan 2008) | 2 lines Remove duplicate entry. ........ r59974 | jeffrey.yasskin | 2008-01-14 23:46:24 -0800 (Mon, 14 Jan 2008) | 12 lines Add rational.Rational as an implementation of numbers.Rational with infinite precision. This has been discussed at http://bugs.python.org/issue1682. It's useful primarily for teaching, but it also demonstrates how to implement a member of the numeric tower, including fallbacks for mixed-mode arithmetic. I expect to write a couple more patches in this area: * Rational.from_decimal() * Rational.trim/approximate() (maybe with different names) * Maybe remove the parentheses from Rational.__str__() * Maybe rename one of the Rational classes * Maybe make Rational('3/2') work. ........ r59978 | andrew.kuchling | 2008-01-15 06:38:05 -0800 (Tue, 15 Jan 2008) | 8 lines Restore description of sys.dont_write_bytecode. The duplication is intentional -- this paragraph is in a section describing additions to the sys module, and there's a later section that mentions the switch. I think most people scan the what's-new and don't read it in detail, so a bit of duplication is OK. ........ r59984 | guido.van.rossum | 2008-01-15 09:59:29 -0800 (Tue, 15 Jan 2008) | 3 lines Issue #1786 (by myself): pdb should use its own stdin/stdout around an exec call and when creating a recursive instance. ........ Deleted: /python/branches/py3k/Demo/classes/Rat.py ============================================================================== --- /python/branches/py3k/Demo/classes/Rat.py Tue Jan 15 22:44:53 2008 +++ (empty file) @@ -1,306 +0,0 @@ -'''\ -This module implements rational numbers. - -The entry point of this module is the function - rat(numerator, denominator) -If either numerator or denominator is of an integral or rational type, -the result is a rational number, else, the result is the simplest of -the types float and complex which can hold numerator/denominator. -If denominator is omitted, it defaults to 1. -Rational numbers can be used in calculations with any other numeric -type. The result of the calculation will be rational if possible. - -There is also a test function with calling sequence - test() -The documentation string of the test function contains the expected -output. -''' - -# Contributed by Sjoerd Mullender - -from types import * - -def gcd(a, b): - '''Calculate the Greatest Common Divisor.''' - while b: - a, b = b, a%b - return a - -def rat(num, den = 1): - # must check complex before float - if isinstance(num, complex) or isinstance(den, complex): - # numerator or denominator is complex: return a complex - return complex(num) / complex(den) - if isinstance(num, float) or isinstance(den, float): - # numerator or denominator is float: return a float - return float(num) / float(den) - # otherwise return a rational - return Rat(num, den) - -class Rat: - '''This class implements rational numbers.''' - - def __init__(self, num, den = 1): - if den == 0: - raise ZeroDivisionError('rat(x, 0)') - - # normalize - - # must check complex before float - if (isinstance(num, complex) or - isinstance(den, complex)): - # numerator or denominator is complex: - # normalized form has denominator == 1+0j - self.__num = complex(num) / complex(den) - self.__den = complex(1) - return - if isinstance(num, float) or isinstance(den, float): - # numerator or denominator is float: - # normalized form has denominator == 1.0 - self.__num = float(num) / float(den) - self.__den = 1.0 - return - if (isinstance(num, self.__class__) or - isinstance(den, self.__class__)): - # numerator or denominator is rational - new = num / den - if not isinstance(new, self.__class__): - self.__num = new - if isinstance(new, complex): - self.__den = complex(1) - else: - self.__den = 1.0 - else: - self.__num = new.__num - self.__den = new.__den - else: - # make sure numerator and denominator don't - # have common factors - # this also makes sure that denominator > 0 - g = gcd(num, den) - self.__num = num / g - self.__den = den / g - # try making numerator and denominator of IntType if they fit - try: - numi = int(self.__num) - deni = int(self.__den) - except (OverflowError, TypeError): - pass - else: - if self.__num == numi and self.__den == deni: - self.__num = numi - self.__den = deni - - def __repr__(self): - return 'Rat(%s,%s)' % (self.__num, self.__den) - - def __str__(self): - if self.__den == 1: - return str(self.__num) - else: - return '(%s/%s)' % (str(self.__num), str(self.__den)) - - # a + b - def __add__(a, b): - try: - return rat(a.__num * b.__den + b.__num * a.__den, - a.__den * b.__den) - except OverflowError: - return rat(int(a.__num) * int(b.__den) + - int(b.__num) * int(a.__den), - int(a.__den) * int(b.__den)) - - def __radd__(b, a): - return Rat(a) + b - - # a - b - def __sub__(a, b): - try: - return rat(a.__num * b.__den - b.__num * a.__den, - a.__den * b.__den) - except OverflowError: - return rat(int(a.__num) * int(b.__den) - - int(b.__num) * int(a.__den), - int(a.__den) * int(b.__den)) - - def __rsub__(b, a): - return Rat(a) - b - - # a * b - def __mul__(a, b): - try: - return rat(a.__num * b.__num, a.__den * b.__den) - except OverflowError: - return rat(int(a.__num) * int(b.__num), - int(a.__den) * int(b.__den)) - - def __rmul__(b, a): - return Rat(a) * b - - # a / b - def __div__(a, b): - try: - return rat(a.__num * b.__den, a.__den * b.__num) - except OverflowError: - return rat(int(a.__num) * int(b.__den), - int(a.__den) * int(b.__num)) - - def __rdiv__(b, a): - return Rat(a) / b - - # a % b - def __mod__(a, b): - div = a / b - try: - div = int(div) - except OverflowError: - div = int(div) - return a - b * div - - def __rmod__(b, a): - return Rat(a) % b - - # a ** b - def __pow__(a, b): - if b.__den != 1: - if isinstance(a.__num, complex): - a = complex(a) - else: - a = float(a) - if isinstance(b.__num, complex): - b = complex(b) - else: - b = float(b) - return a ** b - try: - return rat(a.__num ** b.__num, a.__den ** b.__num) - except OverflowError: - return rat(int(a.__num) ** b.__num, - int(a.__den) ** b.__num) - - def __rpow__(b, a): - return Rat(a) ** b - - # -a - def __neg__(a): - try: - return rat(-a.__num, a.__den) - except OverflowError: - # a.__num == sys.maxint - return rat(-int(a.__num), a.__den) - - # abs(a) - def __abs__(a): - return rat(abs(a.__num), a.__den) - - # int(a) - def __int__(a): - return int(a.__num / a.__den) - - # long(a) - def __long__(a): - return int(a.__num) / int(a.__den) - - # float(a) - def __float__(a): - return float(a.__num) / float(a.__den) - - # complex(a) - def __complex__(a): - return complex(a.__num) / complex(a.__den) - - # cmp(a,b) - def __cmp__(a, b): - diff = Rat(a - b) - if diff.__num < 0: - return -1 - elif diff.__num > 0: - return 1 - else: - return 0 - - def __rcmp__(b, a): - return cmp(Rat(a), b) - - # a != 0 - def __bool__(a): - return a.__num != 0 - -def test(): - '''\ - Test function for rat module. - - The expected output is (module some differences in floating - precission): - -1 - -1 - 0 0L 0.1 (0.1+0j) - [Rat(1,2), Rat(-3,10), Rat(1,25), Rat(1,4)] - [Rat(-3,10), Rat(1,25), Rat(1,4), Rat(1,2)] - 0 - (11/10) - (11/10) - 1.1 - OK - 2 1.5 (3/2) (1.5+1.5j) (15707963/5000000) - 2 2 2.0 (2+0j) - - 4 0 4 1 4 0 - 3.5 0.5 3.0 1.33333333333 2.82842712475 1 - (7/2) (1/2) 3 (4/3) 2.82842712475 1 - (3.5+1.5j) (0.5-1.5j) (3+3j) (0.666666666667-0.666666666667j) (1.43248815986+2.43884761145j) 1 - 1.5 1 1.5 (1.5+0j) - - 3.5 -0.5 3.0 0.75 2.25 -1 - 3.0 0.0 2.25 1.0 1.83711730709 0 - 3.0 0.0 2.25 1.0 1.83711730709 1 - (3+1.5j) -1.5j (2.25+2.25j) (0.5-0.5j) (1.50768393746+1.04970907623j) -1 - (3/2) 1 1.5 (1.5+0j) - - (7/2) (-1/2) 3 (3/4) (9/4) -1 - 3.0 0.0 2.25 1.0 1.83711730709 -1 - 3 0 (9/4) 1 1.83711730709 0 - (3+1.5j) -1.5j (2.25+2.25j) (0.5-0.5j) (1.50768393746+1.04970907623j) -1 - (1.5+1.5j) (1.5+1.5j) - - (3.5+1.5j) (-0.5+1.5j) (3+3j) (0.75+0.75j) 4.5j -1 - (3+1.5j) 1.5j (2.25+2.25j) (1+1j) (1.18235814075+2.85446505899j) 1 - (3+1.5j) 1.5j (2.25+2.25j) (1+1j) (1.18235814075+2.85446505899j) 1 - (3+3j) 0j 4.5j (1+0j) (-0.638110484918+0.705394566962j) 0 - ''' - print(rat(-1, 1)) - print(rat(1, -1)) - a = rat(1, 10) - print(int(a), int(a), float(a), complex(a)) - b = rat(2, 5) - l = [a+b, a-b, a*b, a/b] - print(l) - l.sort() - print(l) - print(rat(0, 1)) - print(a+1) - print(a+1) - print(a+1.0) - try: - print(rat(1, 0)) - raise SystemError('should have been ZeroDivisionError') - except ZeroDivisionError: - print('OK') - print(rat(2), rat(1.5), rat(3, 2), rat(1.5+1.5j), rat(31415926,10000000)) - list = [2, 1.5, rat(3,2), 1.5+1.5j] - for i in list: - print(i, end=' ') - if not isinstance(i, complex): - print(int(i), float(i), end=' ') - print(complex(i)) - print() - for j in list: - print(i + j, i - j, i * j, i / j, i ** j, end=' ') - if not (isinstance(i, complex) or - isinstance(j, complex)): - print(cmp(i, j)) - print() - - -if __name__ == '__main__': - test() Modified: python/branches/py3k/Doc/glossary.rst ============================================================================== --- python/branches/py3k/Doc/glossary.rst (original) +++ python/branches/py3k/Doc/glossary.rst Tue Jan 15 22:44:53 2008 @@ -329,7 +329,7 @@ also :term:`immutable`. named tuple - Any tuple-like class whose indexable fields are also accessible with + Any tuple subclass whose indexable fields are also accessible with named attributes (for example, :func:`time.localtime` returns a tuple-like object where the *year* is accessible either with an index such as ``t[0]`` or with a named attribute like ``t.tm_year``). Modified: python/branches/py3k/Doc/library/numeric.rst ============================================================================== --- python/branches/py3k/Doc/library/numeric.rst (original) +++ python/branches/py3k/Doc/library/numeric.rst Tue Jan 15 22:44:53 2008 @@ -21,6 +21,7 @@ math.rst cmath.rst decimal.rst + rational.rst random.rst itertools.rst functools.rst Modified: python/branches/py3k/Doc/library/queue.rst ============================================================================== --- python/branches/py3k/Doc/library/queue.rst (original) +++ python/branches/py3k/Doc/library/queue.rst Tue Jan 15 22:44:53 2008 @@ -49,8 +49,9 @@ .. method:: Queue.qsize() - Return the approximate size of the queue. Because of multithreading semantics, - this number is not reliable. + Return the approximate size of the queue. Note, qsize() > 0 doesn't + guarantee that a subsequent get() will not block, nor will qsize() < maxsize + guarantee that put() will not block. .. method:: Queue.put(item[, block[, timeout]]) Modified: python/branches/py3k/Doc/library/sys.rst ============================================================================== --- python/branches/py3k/Doc/library/sys.rst (original) +++ python/branches/py3k/Doc/library/sys.rst Tue Jan 15 22:44:53 2008 @@ -210,7 +210,7 @@ +------------------------------+------------------------------------------+ | :const:`no_site` | -S | +------------------------------+------------------------------------------+ - | :const:`ingnore_environment` | -E | + | :const:`ignore_environment` | -E | +------------------------------+------------------------------------------+ | :const:`tabcheck` | -t or -tt | +------------------------------+------------------------------------------+ Modified: python/branches/py3k/Doc/library/test.rst ============================================================================== --- python/branches/py3k/Doc/library/test.rst (original) +++ python/branches/py3k/Doc/library/test.rst Tue Jan 15 22:44:53 2008 @@ -300,7 +300,7 @@ This is a context manager than runs the :keyword:`with` statement body using a :class:`StringIO.StringIO` object as sys.stdout. That object can be - retrieved using the ``as`` clause of the with statement. + retrieved using the ``as`` clause of the :keyword:`with` statement. Example use:: Modified: python/branches/py3k/Doc/whatsnew/2.6.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/2.6.rst (original) +++ python/branches/py3k/Doc/whatsnew/2.6.rst Tue Jan 15 22:44:53 2008 @@ -426,6 +426,29 @@ .. ====================================================================== +.. :: + + .. _pep-0370: + + PEP 370: XXX + ===================================================== + + When you run Python, the module search page ``sys.modules`` usually + includes a directory whose path ends in ``"site-packages"``. This + directory is intended to hold locally-installed packages available to + all users on a machine or using a particular site installation. + + Python 2.6 introduces a convention for user-specific site directories. + + .. seealso:: + + :pep:`370` - XXX + + PEP written by XXX; implemented by Christian Heimes. + + +.. ====================================================================== + .. _pep-3110: PEP 3110: Exception-Handling Changes @@ -650,6 +673,18 @@ Optimizations ------------- +* Type objects now have a cache of methods that can reduce + the amount of work required to find the correct method implementation + for a particular class; once cached, the interpreter doesn't need to + traverse base classes to figure out the right method to call. + The cache is cleared if a base class or the class itself is modified, + so the cache should remain correct even in the face of Python's dynamic + nature. + (Original optimization implemented by Armin Rigo, updated for + Python 2.6 by Kevin Jacobs.) + + .. % Patch 1700288 + * All of the functions in the :mod:`struct` module have been rewritten in C, thanks to work at the Need For Speed sprint. (Contributed by Raymond Hettinger.) @@ -700,6 +735,11 @@ >>> v2 variable(id=1, name='amplitude', type='int', size=4) + Where the new :class:`namedtuple` type proved suitable, the standard + library has been modified to return them. For example, + the :meth:`Decimal.as_tuple` method now returns a named tuple with + :attr:`sign`, :attr:`digits`, and :attr:`exponent` fields. + (Contributed by Raymond Hettinger.) * Another change to the :mod:`collections` module is that the @@ -758,7 +798,17 @@ >>> Decimal(1000).log10() Decimal("3") - (Implemented by Facundo Batista and Mark Dickinson.) + The :meth:`as_tuple` method of :class:`Decimal` objects now returns a + named tuple with :attr:`sign`, :attr:`digits`, and :attr:`exponent` fields. + + (Implemented by Facundo Batista and Mark Dickinson. Named tuple + support added by Raymond Hettinger.) + +* The :mod:`difflib` module's :class:`SequenceMatcher` class + now returns named tuples representing matches. + In addition to behaving like tuples, the returned values + also have :attr:`a`, :attr:`b`, and :attr:`size` attributes. + (Contributed by Raymond Hettinger.) * An optional ``timeout`` parameter was added to the :class:`ftplib.FTP` class constructor as well as the :meth:`connect` @@ -795,6 +845,12 @@ class constructors, specifying a timeout measured in seconds. (Added by Facundo Batista.) +* Most of the :mod:`inspect` module's functions, such as + :func:`getmoduleinfo` and :func:`getargs`, now return named tuples. + In addition to behaving like tuples, the elements of the return value + can also be accessed as attributes. + (Contributed by Raymond Hettinger.) + * A new function in the :mod:`itertools` module: ``izip_longest(iter1, iter2, ...[, fillvalue])`` makes tuples from each of the elements; if some of the iterables are shorter than others, the missing values are set to *fillvalue*. @@ -891,6 +947,13 @@ .. Issue 1727780 +* Long regular expression searches carried out by the :mod:`re` + module will now check for signals being delivered, so especially + long searches can now be interrupted. + (Contributed by Josh Hoyt and Ralf Schmitt.) + + .. % Patch 846388 + * The :mod:`rgbimg` module has been removed. * The :mod:`sets` module has been deprecated; it's better to @@ -934,17 +997,42 @@ .. Patch #957003 +* The :mod:`socket` module now supports TIPC (http://tipc.sf.net), + a high-performance non-IP-based protocol designed for use in clustered + environments. TIPC addresses are 4- or 5-tuples. + (Contributed by Alberto Bertogli.) + + .. Patch #1646 + * A new variable in the :mod:`sys` module, - :attr:`float_info`, is a dictionary + :attr:`float_info`, is an object containing information about the platform's floating-point support - derived from the :file:`float.h` file. Key/value pairs - in this dictionary include - ``"mant_dig"`` (number of digits in the mantissa), ``"epsilon"`` + derived from the :file:`float.h` file. Attributes of this object + include + :attr:`mant_dig` (number of digits in the mantissa), :attr:`epsilon` (smallest difference between 1.0 and the next largest value representable), and several others. (Contributed by Christian Heimes.) .. Patch 1534 + Another new variable, :attr:`dont_write_bytecode`, controls whether Python + writes any :file:`.pyc` or :file:`.pyo` files on importing a module. + If this variable is true, the compiled files are not written. The + variable is initially set on start-up by supplying the :option:`-B` + switch to the Python interpreter, or by setting the + :envvar:`PYTHONDONTWRITEBYTECODE` environment variable before + running the interpreter. Python code can subsequently + change the value of this variable to control whether bytecode files + are written or not. + (Contributed by Neal Norwitz and Georg Brandl.) + + Information about the command-line arguments supplied to the Python + interpreter are available as attributes of a ``sys.flags`` named + tuple. For example, the :attr:`verbose` attribute is true if Python + was executed in verbose mode, :attr:`debug` is true in debugging mode, etc. + These attributes are all read-only. + (Contributed by Christian Heimes.) + * The :mod:`tarfile` module now supports POSIX.1-2001 (pax) and POSIX.1-1988 (ustar) format tarfiles, in addition to the GNU tar format that was already supported. The default format @@ -1061,6 +1149,22 @@ information. (Contributed by Alan McIntyre as part of his project for Google's Summer of Code 2007.) +* The :mod:`zipfile` module's :class:`ZipFile` class now has + :meth:`extract` and :meth:`extractall` methods that will unpack + a single file or all the files in the archive to the current directory, or + to a specified directory:: + + z = zipfile.ZipFile('python-251.zip') + + # Unpack a single file, writing it relative to the /tmp directory. + z.extract('Python/sysmodule.c', '/tmp') + + # Unpack all the files in the archive. + z.extractall() + + (Contributed by Alan McIntyre.) + .. % Patch 467924 + .. ====================================================================== .. whole new modules get described in subsections here @@ -1143,7 +1247,12 @@ value, as does the :func:`getwche` function. The :func:`putwch` function takes a Unicode character and writes it to the console. -Platform-specific changes go here. +* The :mod:`_winreg` module now has a function, + :func:`ExpandEnvironmentStrings`, + that expands environment variable references such as ``%NAME%`` + in an input string. The handle objects provided by this + module now support the context protocol, so they can be used + in :keyword:`with` statements. .. ====================================================================== @@ -1153,14 +1262,21 @@ Other Changes and Fixes ======================= -As usual, there were a bunch of other improvements and bugfixes scattered -throughout the source tree. A search through the change logs finds there were -XXX patches applied and YYY bugs fixed between Python 2.5 and 2.6. Both figures -are likely to be underestimates. +As usual, there were a bunch of other improvements and bugfixes +scattered throughout the source tree. A search through the change +logs finds there were XXX patches applied and YYY bugs fixed between +Python 2.5 and 2.6. Both figures are likely to be underestimates. Some of the more notable changes are: -* Details will go here. +* It's now possible to prevent Python from writing any :file:`.pyc` + or :file:`.pyo` files by either supplying the :option:`-B` switch + or setting the :envvar:`PYTHONDONTWRITEBYTECODE` environment variable + to any non-empty string when running the Python interpreter. These + are also used to set the :data:`sys.dont_write_bytecode` attribute; + Python code can change this variable to control whether bytecode + files are subsequently written. + (Contributed by Neal Norwitz and Georg Brandl.) .. ====================================================================== @@ -1177,6 +1293,19 @@ before adding elements from the iterable. This change makes the behavior match that of ``list.__init__()``. +* The :class:`Decimal` constructor now accepts leading and trailing + whitespace when passed a string. Previously it would raise an + :exc:`InvalidOperation` exception. On the other hand, the + :meth:`create_decimal` method of :class:`Context` objects now + explicitly disallows extra whitespace, raising a + :exc:`ConversionSyntax` exception. + +* Due to an implementation accident, if you passed a file path to + the built-in :func:`__import__` function, it would actually import + the specified file. This was never intended to work, however, and + the implementation now explicitly checks for this case and raises + an :exc:`ImportError`. + * The :mod:`socket` module exception :exc:`socket.error` now inherits from :exc:`IOError`. Previously it wasn't a subclass of :exc:`StandardError` but now it is, through :exc:`IOError`. Modified: python/branches/py3k/Lib/numbers.py ============================================================================== --- python/branches/py3k/Lib/numbers.py (original) +++ python/branches/py3k/Lib/numbers.py Tue Jan 15 22:44:53 2008 @@ -5,6 +5,7 @@ TODO: Fill out more detailed documentation on the operators.""" +from __future__ import division from abc import ABCMeta, abstractmethod, abstractproperty __all__ = ["Number", "Exact", "Inexact", @@ -61,7 +62,8 @@ def __complex__(self): """Return a builtin complex instance. Called for complex(self).""" - def __bool__(self): + # Will be __bool__ in 3.0. + def __nonzero__(self): """True if self != 0. Called for bool(self).""" return self != 0 @@ -96,6 +98,7 @@ """-self""" raise NotImplementedError + @abstractmethod def __pos__(self): """+self""" raise NotImplementedError @@ -120,12 +123,28 @@ @abstractmethod def __div__(self, other): - """self / other; should promote to float or complex when necessary.""" + """self / other without __future__ division + + May promote to float. + """ raise NotImplementedError @abstractmethod def __rdiv__(self, other): - """other / self""" + """other / self without __future__ division""" + raise NotImplementedError + + @abstractmethod + def __truediv__(self, other): + """self / other with __future__ division. + + Should promote to float when necessary. + """ + raise NotImplementedError + + @abstractmethod + def __rtruediv__(self, other): + """other / self with __future__ division""" raise NotImplementedError @abstractmethod Modified: python/branches/py3k/Lib/pdb.py ============================================================================== --- python/branches/py3k/Lib/pdb.py (original) +++ python/branches/py3k/Lib/pdb.py Tue Jan 15 22:44:53 2008 @@ -198,7 +198,13 @@ globals = self.curframe.f_globals try: code = compile(line + '\n', '', 'single') - exec(code, globals, locals) + try: + sys.stdin = self.stdin + sys.stdout = self.stdout + exec(code, globals, locals) + finally: + sys.stdout = save_stdout + sys.stdin = save_stdin except: t, v = sys.exc_info()[:2] if type(t) == type(''): @@ -656,7 +662,7 @@ sys.settrace(None) globals = self.curframe.f_globals locals = self.curframe.f_locals - p = Pdb() + p = Pdb(self.completekey, self.stdin, self.stdout) p.prompt = "(%s) " % self.prompt.strip() print("ENTERING RECURSIVE DEBUGGER", file=self.stdout) sys.call_tracing(p.run, (arg, globals, locals)) Copied: python/branches/py3k/Lib/rational.py (from r59984, python/trunk/Lib/rational.py) ============================================================================== --- python/trunk/Lib/rational.py (original) +++ python/branches/py3k/Lib/rational.py Tue Jan 15 22:44:53 2008 @@ -203,7 +203,7 @@ a.denominator * b.numerator) __truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv) - __div__, __rdiv__ = _operator_fallbacks(_div, operator.div) + __div__, __rdiv__ = _operator_fallbacks(_div, operator.truediv) @classmethod def _floordiv(cls, a, b): @@ -405,6 +405,6 @@ """a >= b""" return a._subtractAndCompareToZero(b, operator.ge) - def __nonzero__(a): + def __bool__(a): """a != 0""" return a.numerator != 0 Copied: python/branches/py3k/Lib/test/test_rational.py (from r59984, python/trunk/Lib/test/test_rational.py) ============================================================================== --- python/trunk/Lib/test/test_rational.py (original) +++ python/branches/py3k/Lib/test/test_rational.py Tue Jan 15 22:44:53 2008 @@ -23,7 +23,7 @@ """Asserts that callable(*args, **kwargs) raises exc_type(message).""" try: callable(*args, **kwargs) - except exc_type, e: + except exc_type as e: self.assertEquals(message, str(e)) else: self.fail("%s not raised" % exc_type.__name__) @@ -89,9 +89,9 @@ # Check that __float__ isn't implemented by converting the # numerator and denominator to float before dividing. - self.assertRaises(OverflowError, float, long('2'*400+'7')) + self.assertRaises(OverflowError, float, int('2'*400+'7')) self.assertAlmostEquals(2.0/3, - float(R(long('2'*400+'7'), long('3'*400+'1')))) + float(R(int('2'*400+'7'), int('3'*400+'1')))) self.assertTypedEquals(0.1+0j, complex(R(1,10))) @@ -114,8 +114,9 @@ self.assertEquals(R(8, 27), R(2, 3) ** R(3)) self.assertEquals(R(27, 8), R(2, 3) ** R(-3)) self.assertTypedEquals(2.0, R(4) ** R(1, 2)) - # Will return 1j in 3.0: - self.assertRaises(ValueError, pow, R(-1), R(1, 2)) + z = pow(R(-1), R(1, 2)) + self.assertAlmostEquals(z.real, 0) + self.assertEquals(z.imag, 1) def testMixedArithmetic(self): self.assertTypedEquals(R(11, 10), R(1, 10) + 1) @@ -147,10 +148,12 @@ self.assertTypedEquals(10.0 + 0j, (1.0 + 0j) / R(1, 10)) self.assertTypedEquals(0, R(1, 10) // 1) - self.assertTypedEquals(0.0, R(1, 10) // 1.0) + # XXX Jeffrey: why does this fail? + ##self.assertTypedEquals(0.0, R(1, 10) // 1.0) self.assertTypedEquals(10, 1 // R(1, 10)) self.assertTypedEquals(10**23, 10**22 // R(1, 10)) - self.assertTypedEquals(10.0, 1.0 // R(1, 10)) + # XXX Jeffrey: why does this fail? + ##self.assertTypedEquals(10.0, 1.0 // R(1, 10)) self.assertTypedEquals(R(1, 10), R(1, 10) % 1) self.assertTypedEquals(0.1, R(1, 10) % 1.0) @@ -165,8 +168,9 @@ self.assertTypedEquals(0.1, R(1, 10) ** 1.0) self.assertTypedEquals(0.1 + 0j, R(1, 10) ** (1.0 + 0j)) self.assertTypedEquals(4 , 2 ** R(2, 1)) - # Will return 1j in 3.0: - self.assertRaises(ValueError, pow, (-1), R(1, 2)) + z = pow(-1, R(1, 2)) + self.assertAlmostEquals(0, z.real) + self.assertEquals(1, z.imag) self.assertTypedEquals(R(1, 4) , 2 ** R(-2, 1)) self.assertTypedEquals(2.0 , 4 ** R(1, 2)) self.assertTypedEquals(0.25, 2.0 ** R(-2, 1)) Modified: python/branches/py3k/Lib/test/test_sys.py ============================================================================== --- python/branches/py3k/Lib/test/test_sys.py (original) +++ python/branches/py3k/Lib/test/test_sys.py Tue Jan 15 22:44:53 2008 @@ -324,7 +324,7 @@ self.failUnless(sys.flags) attrs = ("debug", "division_warning", "inspect", "interactive", "optimize", "dont_write_bytecode", - "no_site", "ingnore_environment", "tabcheck", "verbose") + "no_site", "ignore_environment", "tabcheck", "verbose") for attr in attrs: self.assert_(hasattr(sys.flags, attr), attr) self.assertEqual(type(getattr(sys.flags, attr)), int, attr) Modified: python/branches/py3k/Lib/zipfile.py ============================================================================== --- python/branches/py3k/Lib/zipfile.py (original) +++ python/branches/py3k/Lib/zipfile.py Tue Jan 15 22:44:53 2008 @@ -718,7 +718,7 @@ print("%-46s %19s %12s" % ("File Name", "Modified ", "Size"), file=file) for zinfo in self.filelist: - date = "%d-%02d-%02d %02d:%02d:%02d" % zinfo.date_time + date = "%d-%02d-%02d %02d:%02d:%02d" % zinfo.date_time[:6] print("%-46s %s %12d" % (zinfo.filename, date, zinfo.file_size), file=file) @@ -975,7 +975,7 @@ data = data.encode("utf-8") if not isinstance(zinfo_or_arcname, ZipInfo): zinfo = ZipInfo(filename=zinfo_or_arcname, - date_time=time.localtime(time.time())) + date_time=time.localtime(time.time())[:6]) zinfo.compress_type = self.compression else: zinfo = zinfo_or_arcname Modified: python/branches/py3k/Modules/_ctypes/libffi/configure ============================================================================== --- python/branches/py3k/Modules/_ctypes/libffi/configure (original) +++ python/branches/py3k/Modules/_ctypes/libffi/configure Tue Jan 15 22:44:53 2008 @@ -934,7 +934,7 @@ else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi - cd $ac_popdir + cd "$ac_popdir" done fi @@ -1973,8 +1973,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2032,8 +2031,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2149,8 +2147,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2204,8 +2201,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2250,8 +2246,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2295,8 +2290,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2623,8 +2617,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2794,8 +2787,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2862,8 +2854,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3047,8 +3038,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3111,8 +3101,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3290,8 +3279,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3408,8 +3396,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3529,7 +3516,7 @@ cris-*-*) TARGET=LIBFFI_CRIS; TARGETDIR=cris;; s390-*-linux-*) TARGET=S390; TARGETDIR=s390;; s390x-*-linux-*) TARGET=S390; TARGETDIR=s390;; -x86_64-*-linux* | x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu) TARGET=X86_64; TARGETDIR=x86;; +amd64-*-freebsd* | x86_64-*-linux* | x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu) TARGET=X86_64; TARGETDIR=x86;; sh-*-linux* | sh[34]*-*-linux*) TARGET=SH; TARGETDIR=sh;; sh-*-rtems*) TARGET=SH; TARGETDIR=sh;; sh64-*-linux* | sh5*-*-linux*) TARGET=SH64; TARGETDIR=sh64;; @@ -3582,8 +3569,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3784,8 +3770,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3848,8 +3833,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3930,8 +3914,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4072,8 +4055,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4209,8 +4191,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4272,8 +4253,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4313,8 +4293,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4370,8 +4349,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4411,8 +4389,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4476,8 +4453,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4508,10 +4484,8 @@ esac else if test "$cross_compiling" = yes; then - { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot run test program while cross compiling -See \`config.log' for more details." >&2;} + { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5 +echo "$as_me: error: internal error: not reached in cross-compile" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF @@ -4623,8 +4597,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4686,8 +4659,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4727,8 +4699,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4784,8 +4755,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4825,8 +4795,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4890,8 +4859,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4922,10 +4890,8 @@ esac else if test "$cross_compiling" = yes; then - { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot run test program while cross compiling -See \`config.log' for more details." >&2;} + { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5 +echo "$as_me: error: internal error: not reached in cross-compile" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF @@ -5047,8 +5013,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5109,8 +5074,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5172,8 +5136,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5213,8 +5176,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5270,8 +5232,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5311,8 +5272,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5376,8 +5336,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5408,10 +5367,8 @@ esac else if test "$cross_compiling" = yes; then - { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot run test program while cross compiling -See \`config.log' for more details." >&2;} + { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5 +echo "$as_me: error: internal error: not reached in cross-compile" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF @@ -5528,8 +5485,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5571,8 +5527,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5629,8 +5584,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5762,8 +5716,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5829,8 +5782,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -6789,11 +6741,6 @@ - if test x"$ac_file" != x-; then - { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - rm -f "$ac_file" - fi # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ @@ -6832,6 +6779,12 @@ fi;; esac done` || { (exit 1); exit 1; } + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub Modified: python/branches/py3k/Modules/_ctypes/libffi/configure.ac ============================================================================== --- python/branches/py3k/Modules/_ctypes/libffi/configure.ac (original) +++ python/branches/py3k/Modules/_ctypes/libffi/configure.ac Tue Jan 15 22:44:53 2008 @@ -67,7 +67,7 @@ cris-*-*) TARGET=LIBFFI_CRIS; TARGETDIR=cris;; s390-*-linux-*) TARGET=S390; TARGETDIR=s390;; s390x-*-linux-*) TARGET=S390; TARGETDIR=s390;; -x86_64-*-linux* | x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu) TARGET=X86_64; TARGETDIR=x86;; +amd64-*-freebsd* | x86_64-*-linux* | x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu) TARGET=X86_64; TARGETDIR=x86;; sh-*-linux* | sh[[34]]*-*-linux*) TARGET=SH; TARGETDIR=sh;; sh-*-rtems*) TARGET=SH; TARGETDIR=sh;; sh64-*-linux* | sh5*-*-linux*) TARGET=SH64; TARGETDIR=sh64;; Modified: python/branches/py3k/Python/sysmodule.c ============================================================================== --- python/branches/py3k/Python/sysmodule.c (original) +++ python/branches/py3k/Python/sysmodule.c Tue Jan 15 22:44:53 2008 @@ -1020,11 +1020,11 @@ {"dont_write_bytecode", "-B"}, /* {"no_user_site", "-s"}, */ {"no_site", "-S"}, - {"ingnore_environment", "-E"}, + {"ignore_environment", "-E"}, {"tabcheck", "-t or -tt"}, {"verbose", "-v"}, #ifdef RISCOS - {"ricos_wimp", "???"}, + {"riscos_wimp", "???"}, #endif /* {"unbuffered", "-u"}, */ /* {"skip_first", "-x"}, */ From python-3000-checkins at python.org Wed Jan 16 01:20:32 2008 From: python-3000-checkins at python.org (jeffrey.yasskin) Date: Wed, 16 Jan 2008 01:20:32 +0100 (CET) Subject: [Python-3000-checkins] r59991 - python/branches/py3k/Lib/test/test_rational.py Message-ID: <20080116002032.92B381E4010@bag.python.org> Author: jeffrey.yasskin Date: Wed Jan 16 01:20:32 2008 New Revision: 59991 Modified: python/branches/py3k/Lib/test/test_rational.py Log: __floordiv__ returns an int in 3.0. Modified: python/branches/py3k/Lib/test/test_rational.py ============================================================================== --- python/branches/py3k/Lib/test/test_rational.py (original) +++ python/branches/py3k/Lib/test/test_rational.py Wed Jan 16 01:20:32 2008 @@ -148,12 +148,10 @@ self.assertTypedEquals(10.0 + 0j, (1.0 + 0j) / R(1, 10)) self.assertTypedEquals(0, R(1, 10) // 1) - # XXX Jeffrey: why does this fail? - ##self.assertTypedEquals(0.0, R(1, 10) // 1.0) + self.assertTypedEquals(0, R(1, 10) // 1.0) self.assertTypedEquals(10, 1 // R(1, 10)) self.assertTypedEquals(10**23, 10**22 // R(1, 10)) - # XXX Jeffrey: why does this fail? - ##self.assertTypedEquals(10.0, 1.0 // R(1, 10)) + self.assertTypedEquals(10, 1.0 // R(1, 10)) self.assertTypedEquals(R(1, 10), R(1, 10) % 1) self.assertTypedEquals(0.1, R(1, 10) % 1.0) From python-3000-checkins at python.org Wed Jan 16 04:38:24 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Wed, 16 Jan 2008 04:38:24 +0100 (CET) Subject: [Python-3000-checkins] r59994 - in python/branches/py3k-importhook: Include/import.h Include/moduleobject.h Lib/test/test_imp.py Modules/gcmodule.c Objects/moduleobject.c Python/import.c Message-ID: <20080116033824.16DF21E4019@bag.python.org> Author: christian.heimes Date: Wed Jan 16 04:38:23 2008 New Revision: 59994 Modified: python/branches/py3k-importhook/Include/import.h python/branches/py3k-importhook/Include/moduleobject.h python/branches/py3k-importhook/Lib/test/test_imp.py python/branches/py3k-importhook/Modules/gcmodule.c python/branches/py3k-importhook/Objects/moduleobject.c python/branches/py3k-importhook/Python/import.c Log: Implemented PJE's suggestion of a slightly different import algorithm with a __notified__ slot. Modified: python/branches/py3k-importhook/Include/import.h ============================================================================== --- python/branches/py3k-importhook/Include/import.h (original) +++ python/branches/py3k-importhook/Include/import.h Wed Jan 16 04:38:23 2008 @@ -37,7 +37,8 @@ /* post import hook API */ PyAPI_FUNC(PyObject *) PyImport_GetPostImportHooks(void); -PyAPI_FUNC(PyObject *) PyImport_NotifyModuleLoaded(PyObject *module); +PyAPI_FUNC(PyObject *) PyImport_NotifyLoadedByModule(PyObject *module); +PyAPI_FUNC(PyObject *) PyImport_NotifyLoadedByName(const char *modname); PyAPI_FUNC(PyObject *) PyImport_RegisterPostImportHook( PyObject *callable, PyObject *mod_name); Modified: python/branches/py3k-importhook/Include/moduleobject.h ============================================================================== --- python/branches/py3k-importhook/Include/moduleobject.h (original) +++ python/branches/py3k-importhook/Include/moduleobject.h Wed Jan 16 04:38:23 2008 @@ -7,15 +7,24 @@ extern "C" { #endif +typedef struct { + PyObject_HEAD + PyObject *md_dict; + int md_notified; +} PyModuleObject; + PyAPI_DATA(PyTypeObject) PyModule_Type; #define PyModule_Check(op) PyObject_TypeCheck(op, &PyModule_Type) #define PyModule_CheckExact(op) (Py_TYPE(op) == &PyModule_Type) +#define PyModule_NOTIFIED(op) (((PyModuleObject*)(op))->md_notified) PyAPI_FUNC(PyObject *) PyModule_New(const char *); PyAPI_FUNC(PyObject *) PyModule_GetDict(PyObject *); PyAPI_FUNC(const char *) PyModule_GetName(PyObject *); PyAPI_FUNC(const char *) PyModule_GetFilename(PyObject *); +PyAPI_FUNC(int) PyModule_GetNotified(PyObject *); +PyAPI_FUNC(int) PyModule_SetNotified(PyObject *, int); PyAPI_FUNC(void) _PyModule_Clear(PyObject *); #ifdef __cplusplus Modified: python/branches/py3k-importhook/Lib/test/test_imp.py ============================================================================== --- python/branches/py3k-importhook/Lib/test/test_imp.py (original) +++ python/branches/py3k-importhook/Lib/test/test_imp.py Wed Jan 16 04:38:23 2008 @@ -8,6 +8,12 @@ from test import test_support +def when_imported(name): + def register(hook): + imp.register_post_import_hook(hook, name) + return register + + class LockTests(unittest.TestCase): """Very basic test of import lock functions.""" @@ -15,7 +21,7 @@ def verify_lock_state(self, expected): self.failUnlessEqual(imp.lock_held(), expected, "expected imp.lock_held() to be %r" % expected) - def testLock(self): + def XtestLock(self): LOOPS = 50 # The import lock may already be held, e.g. if the test suite is run @@ -44,11 +50,11 @@ class ImportTests(unittest.TestCase): - def test_find_module_encoding(self): + def Xtest_find_module_encoding(self): fd = imp.find_module("heapq")[0] self.assertEqual(fd.encoding, "iso-8859-1") - def test_issue1267(self): + def Xtest_issue1267(self): fp, filename, info = imp.find_module("pydoc") self.assertNotEqual(fp, None) self.assertEqual(fp.encoding, "iso-8859-1") @@ -64,7 +70,7 @@ '"""Tokenization help for Python programs.\n') fp.close() - def test_reload(self): + def Xtest_reload(self): import marshal imp.reload(marshal) import string @@ -210,7 +216,17 @@ self.failUnlessRaises(TypeError, imp.notify_module_loaded, object()) # Should this fail? mod = imp.new_module("post_import_test_module") - imp.notify_module_loaded(mod) + self.failUnlessRaises(KeyError, imp.notify_module_loaded, mod) + sys.modules['pih_test'] = None + self.failUnlessRaises(TypeError, imp.notify_module_loaded, 'pih_test') + class Example(object): + __name__ = 'pih_test' + sys.modules['pih_test'] = Example + self.failUnlessRaises(TypeError, imp.notify_module_loaded, 'pih_test') + sys.modules['pih_test'] = Example() + self.failUnlessRaises(TypeError, imp.notify_module_loaded, 'pih_test') + del sys.modules['pih_test'] + self.failUnlessRaises(KeyError, imp.notify_module_loaded, 'pih_test') def test_hook_hirarchie(self): self.tmpdir = mkhier(hier) @@ -302,6 +318,7 @@ sys.modules[name] = mod self.assertEqual(callback.names, []) + self.assert_("pih_test.a.b" in sys.modules) mod2 = imp.notify_module_loaded("pih_test.a.b") self.failUnless(mod is mod2, (mod, mod2)) self.assertEqual(mod.__name__, "pih_test.a.b") @@ -309,10 +326,45 @@ self.assertEqual(callback.names, ["pih_test", "pih_test.a", "pih_test.a.b"]) + def test_tricky(self): + called = [] + def func_a2(mod): + called.append("func_a2") + def func_ab1(mod): + called.append("func_ab1") + def func_ab2(mod): + called.append("func_ab2") + def func_ab3(mod): + called.append("func_ab3") + + when_imported('a.b')(func_ab1) + when_imported('a.b')(func_ab2) + + @when_imported('a') + def func_a1(module_a): + called.append("func_a1") + when_imported('a.b')(func_ab3) + # this is here to foil trivial implementations + imp.notify_module_loaded('a.b') + + when_imported('a')(func_a2) + + # insert the modules into sys.modules to fake a 3rd party import + a = imp.new_module('a') + ab = imp.new_module('a.b') + a.b = ab + sys.modules["a"] = a + sys.modules["a.b"] = ab + # notify + imp.notify_module_loaded('a.b') + + expected = ["func_a1", "func_a2", "func_ab1", "func_ab2", "func_ab3"] + self.assertEqual(called, expected) + def test_main(): test_support.run_unittest( - LockTests, - ImportTests, + #LockTests, + #ImportTests, PostImportHookTests, ) Modified: python/branches/py3k-importhook/Modules/gcmodule.c ============================================================================== --- python/branches/py3k-importhook/Modules/gcmodule.c (original) +++ python/branches/py3k-importhook/Modules/gcmodule.c Wed Jan 16 04:38:23 2008 @@ -269,6 +269,11 @@ * generation being collected, which can be recognized * because only they have positive gc_refs. */ +#ifdef Py_DEBUG + if (gc->gc.gc_refs == 0) + _PyObject_Dump(op); +#endif + assert(gc->gc.gc_refs != 0); /* else refcount was too small */ if (gc->gc.gc_refs > 0) gc->gc.gc_refs--; Modified: python/branches/py3k-importhook/Objects/moduleobject.c ============================================================================== --- python/branches/py3k-importhook/Objects/moduleobject.c (original) +++ python/branches/py3k-importhook/Objects/moduleobject.c Wed Jan 16 04:38:23 2008 @@ -4,13 +4,12 @@ #include "Python.h" #include "structmember.h" -typedef struct { - PyObject_HEAD - PyObject *md_dict; -} PyModuleObject; +#define IS_NOTIFIED "__notified__" static PyMemberDef module_members[] = { {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY}, + {IS_NOTIFIED, T_INT, offsetof(PyModuleObject, md_notified), + READONLY}, {0} }; @@ -34,6 +33,7 @@ goto fail; Py_DECREF(nameobj); PyObject_GC_Track(m); + m->md_notified = 0; return (PyObject *)m; fail: @@ -96,6 +96,42 @@ return PyUnicode_AsString(fileobj); } +int +PyModule_GetNotified(PyObject *m) +{ + PyObject *o; + int status; + + if (PyModule_Check(m)) { + return PyModule_NOTIFIED(m); + } + o = PyObject_GetAttrString(m, IS_NOTIFIED); + if (o == NULL) { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { + return -1; + } + PyErr_Clear(); + return 0; + } + status = PyObject_IsTrue(o); + Py_DECREF(o); + return status; +} + +int +PyModule_SetNotified(PyObject *m, int status) +{ + PyObject *o; + + if (PyModule_Check(m)) { + PyModule_NOTIFIED(m) = status; + return 0; + } + o = status > 0 ? Py_True : Py_False; + Py_INCREF(o); + return PyObject_SetAttrString(m, IS_NOTIFIED, o); +} + void _PyModule_Clear(PyObject *m) { Modified: python/branches/py3k-importhook/Python/import.c ============================================================================== --- python/branches/py3k-importhook/Python/import.c (original) +++ python/branches/py3k-importhook/Python/import.c Wed Jan 16 04:38:23 2008 @@ -111,13 +111,14 @@ {0, 0} }; +#if 0 /* Queue for the post import hook system */ static PyObject *register_queue = NULL; static int notification_in_progress = 0; -static PyObject *notify_byname(const char *); static int queue_registration(PyObject *, PyObject *); static int process_registration_queue(void); +#endif /* Initialize things */ @@ -250,7 +251,7 @@ _PyImport_Fini(void) { Py_CLEAR(extensions); - Py_CLEAR(register_queue); + /* Py_CLEAR(register_queue); */ PyMem_DEL(_PyImport_Filetab); _PyImport_Filetab = NULL; } @@ -677,7 +678,7 @@ * it returns the module. */ PyObject * -PyImport_NotifyModuleLoaded(PyObject *module) +PyImport_NotifyLoadedByModule(PyObject *module) { static PyObject *name = NULL; PyObject *mod_name = NULL, *registry = NULL, *o; @@ -694,6 +695,7 @@ if (module == NULL) { return NULL; } + /* Should I allow all kinds of objects? */ if (!PyModule_Check(module)) { PyErr_Format(PyExc_TypeError, @@ -743,8 +745,8 @@ if ((it = PyObject_GetIter(hooks)) == NULL) { goto error; } - - notification_in_progress = 1; + //notification_in_progress = 1; + PyModule_SetNotified(module, 1); while ((hook = PyIter_Next(it)) != NULL) { o = PyObject_CallFunctionObjArgs(hook, module, NULL); Py_DECREF(hook); @@ -763,11 +765,13 @@ if (PyDict_SetItem(registry, mod_name, Py_None) < 0) { status = -1; } +#if 0 notification_in_progress = 0; /* register queued hooks */ if (process_registration_queue()) { goto removehooks; } +#endif error: Py_XDECREF(mod_name); Py_XDECREF(it); @@ -781,17 +785,22 @@ } } -/* notify by name - * notify_byname("a.b.c") calls PyImport_NotifyModuleLoaded() for "a", "a.b" - * and "a.b.c". The modules are taken from sys.modules. If a module can't be - * retrieved an exception is raised otherwise the module 'modname' is returned +/* PyImport_NotifyLoadedByName(modname) + * + * PyImport_NotifyLoadedByName("a.b.c") calls PyImport_NotifyModuleLoaded() + * the modules for "a", "a.b" and "a.b.c". The modules are taken from + * sys.modules. If a module can't be retrieved, an exception is raised + * otherwise the module 'modname' is returned. The hook calls always start + * with the prime parent module. + * The caller of PyImport_NotifyLoadedByName() must hold the import lock! + * It returns a BORROWED reference. */ -static PyObject * -notify_byname(const char *modname) +PyObject * +PyImport_NotifyLoadedByName(const char *modname) { PyObject *modules, *mod = NULL; int status = -1; - const char *pmodname = modname; + const char *pmodname = modname, *dot; char name[MAXPATHLEN+1]; Py_ssize_t pos; @@ -799,31 +808,41 @@ if (modules == NULL) { goto error; } - for (; *pmodname != '\0'; pmodname++) { - if (*pmodname != '.') - continue; - pos = pmodname - modname; - if (pos == 0) { - PyErr_SetString(PyExc_ValueError, - "module name can't starts with a dot."); - return NULL; - } + + //fprintf(stderr, "%s\n", modname); + if ((dot = strrchr(modname, '.')) != NULL) { + pos = dot-modname; strncpy(name, modname, pos); name[pos] = '\0'; - mod = PyDict_GetItemString(modules, name); - Py_INCREF(mod); - mod = PyImport_NotifyModuleLoaded(mod); - if (mod == NULL) { + //fprintf(stderr, "%s (%s at %d)\n", name, modname, pos); + if ((mod = PyDict_GetItemString(modules, name)) == NULL) { + PyErr_Format(PyExc_KeyError, + "Module '%.200s' is not in sys.modules", + modname + ); goto error; } - Py_DECREF(mod); + if (PyModule_GetNotified(mod)) { // ERRCHECK + return mod; + } + PyModule_SetNotified(mod, 1); // ERRCHECK + mod = PyImport_NotifyLoadedByName(name); + } + if ((mod = PyDict_GetItemString(modules, modname)) == NULL) { + PyErr_Format(PyExc_KeyError, + "Module '%.200s' is not in sys.modules", + modname + ); + goto error; } - mod = PyDict_GetItemString(modules, modname); + Py_INCREF(mod); - mod = PyImport_NotifyModuleLoaded(mod); + mod = PyImport_NotifyLoadedByModule(mod); + Py_XDECREF(mod); status = 0; error: + /*notification_in_progress = 0;*/ if (status == 0) { return mod; } @@ -833,7 +852,7 @@ } /* register a new hook for a module - PyImport_RegisterPostImportHook acquires the global import look + * PyImport_RegisterPostImportHook acquires the global import look */ PyObject * PyImport_RegisterPostImportHook(PyObject *callable, PyObject *mod_name) @@ -850,12 +869,14 @@ goto error; } +#if 0 if (notification_in_progress) { if (queue_registration(callable, mod_name) != 0) { return NULL; } Py_RETURN_NONE; } +#endif registry = PyImport_GetPostImportHooks(); modules = PyImport_GetModuleDict(); @@ -930,6 +951,7 @@ } } +#if 0 static int queue_registration(PyObject *callable, PyObject *mod_name) { @@ -1005,7 +1027,7 @@ Py_XDECREF(tup); return rc; } - +#endif /* end of post import hook */ static PyObject * get_sourcefile(const char *file); @@ -2450,7 +2472,6 @@ PyObject *result; lock_import(); result = import_module_level(name, globals, locals, fromlist, level); - /* result = PyImport_NotifyModuleLoaded(result); */ UNLOCK_IMPORT; return result; } @@ -2857,7 +2878,7 @@ m = NULL; } /* notify that the module was loaded */ - m = PyImport_NotifyModuleLoaded(m); + m = PyImport_NotifyLoadedByModule(m); } return m; @@ -3376,20 +3397,46 @@ static PyObject * imp_notify_module_loaded(PyObject *self, PyObject *args) { - PyObject *mod, *o; - char *name; + PyObject *mod, *o, *modname = NULL; + const char *name; if (PyArg_ParseTuple(args, "s:notify_module_loaded", &name)) { - return notify_byname(name); + lock_import(); + o = PyImport_NotifyLoadedByName(name); + Py_XINCREF(o); + UNLOCK_IMPORT; + return o; } + PyErr_Clear(); if (!PyArg_ParseTuple(args, "O:notify_module_loaded", &mod)) return NULL; - Py_INCREF(mod); + if (PyModule_Check(mod)) { + if ((name = PyModule_GetName(mod)) == NULL) { + return NULL; + } + } + else { + if ((modname = PyObject_GetAttrString(mod, "__name__")) + == NULL) { + PyErr_Format(PyExc_TypeError, + "A module instance or object with a __name__ " + "attribute was expected, got '%.200s'.", + Py_TYPE(mod)->tp_name + ); + return NULL; + } + if ((name = PyUnicode_AsString(modname)) == NULL) { + Py_DECREF(modname); + return NULL; + } + } lock_import(); - o = PyImport_NotifyModuleLoaded(mod); + o = PyImport_NotifyLoadedByName(name); + Py_XINCREF(o); UNLOCK_IMPORT; + Py_XDECREF(modname); return o; } From python-3000-checkins at python.org Wed Jan 16 04:44:58 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Wed, 16 Jan 2008 04:44:58 +0100 (CET) Subject: [Python-3000-checkins] r59995 - python/branches/py3k-importhook/Python/import.c Message-ID: <20080116034458.66F161E401C@bag.python.org> Author: christian.heimes Date: Wed Jan 16 04:44:58 2008 New Revision: 59995 Modified: python/branches/py3k-importhook/Python/import.c Log: Removed some unused code and added error checks to Get/SetNotified Modified: python/branches/py3k-importhook/Python/import.c ============================================================================== --- python/branches/py3k-importhook/Python/import.c (original) +++ python/branches/py3k-importhook/Python/import.c Wed Jan 16 04:44:58 2008 @@ -111,16 +111,6 @@ {0, 0} }; -#if 0 -/* Queue for the post import hook system */ -static PyObject *register_queue = NULL; -static int notification_in_progress = 0; - -static int queue_registration(PyObject *, PyObject *); -static int process_registration_queue(void); -#endif - - /* Initialize things */ void @@ -251,7 +241,6 @@ _PyImport_Fini(void) { Py_CLEAR(extensions); - /* Py_CLEAR(register_queue); */ PyMem_DEL(_PyImport_Filetab); _PyImport_Filetab = NULL; } @@ -745,7 +734,6 @@ if ((it = PyObject_GetIter(hooks)) == NULL) { goto error; } - //notification_in_progress = 1; PyModule_SetNotified(module, 1); while ((hook = PyIter_Next(it)) != NULL) { o = PyObject_CallFunctionObjArgs(hook, module, NULL); @@ -765,13 +753,6 @@ if (PyDict_SetItem(registry, mod_name, Py_None) < 0) { status = -1; } -#if 0 - notification_in_progress = 0; - /* register queued hooks */ - if (process_registration_queue()) { - goto removehooks; - } -#endif error: Py_XDECREF(mod_name); Py_XDECREF(it); @@ -800,21 +781,19 @@ { PyObject *modules, *mod = NULL; int status = -1; - const char *pmodname = modname, *dot; + const char *dot; char name[MAXPATHLEN+1]; - Py_ssize_t pos; + int pos, rc; modules = PyImport_GetModuleDict(); if (modules == NULL) { goto error; } - //fprintf(stderr, "%s\n", modname); if ((dot = strrchr(modname, '.')) != NULL) { pos = dot-modname; strncpy(name, modname, pos); name[pos] = '\0'; - //fprintf(stderr, "%s (%s at %d)\n", name, modname, pos); if ((mod = PyDict_GetItemString(modules, name)) == NULL) { PyErr_Format(PyExc_KeyError, "Module '%.200s' is not in sys.modules", @@ -822,10 +801,15 @@ ); goto error; } - if (PyModule_GetNotified(mod)) { // ERRCHECK + if ((rc = PyModule_GetNotified(mod)) == -1) { + goto error; + } + if (rc) { return mod; } - PyModule_SetNotified(mod, 1); // ERRCHECK + if (PyModule_SetNotified(mod, 1) == -1) { + goto error; + } mod = PyImport_NotifyLoadedByName(name); } if ((mod = PyDict_GetItemString(modules, modname)) == NULL) { @@ -842,7 +826,6 @@ status = 0; error: - /*notification_in_progress = 0;*/ if (status == 0) { return mod; } @@ -869,15 +852,6 @@ goto error; } -#if 0 - if (notification_in_progress) { - if (queue_registration(callable, mod_name) != 0) { - return NULL; - } - Py_RETURN_NONE; - } -#endif - registry = PyImport_GetPostImportHooks(); modules = PyImport_GetModuleDict(); if (registry == NULL || modules == NULL) { @@ -951,83 +925,6 @@ } } -#if 0 -static int -queue_registration(PyObject *callable, PyObject *mod_name) -{ - - PyObject *tup; - - if (register_queue == NULL) { - register_queue = PyList_New(0); - if (register_queue == NULL) - return -1; - } - assert(notification_in_progress); - tup = PyTuple_New(2); - if (tup == NULL) { - return -1; - } - Py_INCREF(callable); - Py_INCREF(mod_name); - PyTuple_SetItem(tup, 0, callable); - PyTuple_SetItem(tup, 1, mod_name); - if (PyList_Append(register_queue, tup)) { - Py_DECREF(tup); - return -1; - } - Py_DECREF(tup); - return 0; -} - -static int -process_registration_queue(void) -{ - PyObject *modules; - PyObject *mod_name, *hook, *module, *o; - PyObject *it = NULL, *tup = NULL; - int rc = -1; - - if (notification_in_progress) - return 0; - - if (register_queue == NULL || PyList_Size(register_queue) == 0) { - return 0; - } - - if ((modules = PyImport_GetModuleDict()) == NULL) { - goto error; - } - - while (Py_SIZE(register_queue)) { - tup = PyObject_CallMethod(register_queue, "pop", "i", 0); - if ((hook = PyTuple_GetItem(tup, 0)) == NULL) { - goto error; - } - if ((mod_name = PyTuple_GetItem(tup, 1)) == NULL) { - goto error; - } - if ((module = PyDict_GetItem(modules, mod_name)) == NULL) { - goto error; - } - o = PyImport_RegisterPostImportHook(hook, mod_name); - if (o == NULL) { - goto error; - } - Py_DECREF(o); - Py_CLEAR(tup); - } - if (PyErr_Occurred()) { - goto error; - } - - rc = 0; - error: - Py_XDECREF(it); - Py_XDECREF(tup); - return rc; -} -#endif /* end of post import hook */ static PyObject * get_sourcefile(const char *file); From g.brandl at gmx.net Wed Jan 16 18:14:25 2008 From: g.brandl at gmx.net (Georg Brandl) Date: Wed, 16 Jan 2008 18:14:25 +0100 Subject: [Python-3000-checkins] r59933 - in python/branches/py3k: Doc/library/decimal.rst Doc/library/dis.rst Doc/library/exceptions.rst Doc/library/os.rst Doc/library/posix.rst Doc/library/xmlrpclib.rst Include/object.h Lib/ctypes/test/test_funcptr.py Lib/decimal.py Lib/test/test_decimal.py Lib/urlparse.py Modules/_ctypes/_ctypes.c Objects/object.c Objects/typeobject.c In-Reply-To: <20080112193911.CD1101E400F@bag.python.org> References: <20080112193911.CD1101E400F@bag.python.org> Message-ID: christian.heimes schrieb: > Author: christian.heimes > Date: Sat Jan 12 20:39:10 2008 > New Revision: 59933 > > Modified: > python/branches/py3k/ (props changed) > python/branches/py3k/Doc/library/decimal.rst > python/branches/py3k/Doc/library/dis.rst > python/branches/py3k/Doc/library/exceptions.rst > python/branches/py3k/Doc/library/os.rst > python/branches/py3k/Doc/library/posix.rst > python/branches/py3k/Doc/library/xmlrpclib.rst > python/branches/py3k/Include/object.h > python/branches/py3k/Lib/ctypes/test/test_funcptr.py > python/branches/py3k/Lib/decimal.py > python/branches/py3k/Lib/test/test_decimal.py > python/branches/py3k/Lib/urlparse.py > python/branches/py3k/Modules/_ctypes/_ctypes.c > python/branches/py3k/Objects/object.c > python/branches/py3k/Objects/typeobject.c > Log: > Merged revisions 59921-59932 via svnmerge from > svn+ssh://pythondev at svn.python.org/python/trunk This merged the method cache to Py3k, for which there is an apparently simpler patch at http://bugs.python.org/issue1568. Somebody should look at the differences between the patches and apply them to Py3k. Georg From python-3000-checkins at python.org Thu Jan 17 01:13:27 2008 From: python-3000-checkins at python.org (raymond.hettinger) Date: Thu, 17 Jan 2008 01:13:27 +0100 (CET) Subject: [Python-3000-checkins] r60012 - in python/branches/py3k: Doc/library/queue.rst Lib/Queue.py Message-ID: <20080117001327.D92861E400A@bag.python.org> Author: raymond.hettinger Date: Thu Jan 17 01:13:27 2008 New Revision: 60012 Modified: python/branches/py3k/Doc/library/queue.rst python/branches/py3k/Lib/Queue.py Log: Sync-up Queue.py with Py2.6 Modified: python/branches/py3k/Doc/library/queue.rst ============================================================================== --- python/branches/py3k/Doc/library/queue.rst (original) +++ python/branches/py3k/Doc/library/queue.rst Thu Jan 17 01:13:27 2008 @@ -6,23 +6,46 @@ :synopsis: A synchronized queue class. -The :mod:`Queue` module implements a multi-producer, multi-consumer FIFO queue. +The :mod:`Queue` module implements multi-producer, multi-consumer queues. It is especially useful in threaded programming when information must be exchanged safely between multiple threads. The :class:`Queue` class in this module implements all the required locking semantics. It depends on the availability of thread support in Python; see the :mod:`threading` module. -The :mod:`Queue` module defines the following class and exception: +Implements three types of queue whose only difference is the order that +the entries are retrieved. In a FIFO queue, the first tasks added are +the first retrieved. In a LIFO queue, the most recently added entry is +the first retrieved (operating like a stack). With a priority queue, +the entries are kept sorted (using the :mod:`heapq` module) and the +lowest valued entry is retrieved first. +The :mod:`Queue` module defines the following classes and exceptions: .. class:: Queue(maxsize) - Constructor for the class. *maxsize* is an integer that sets the upperbound + Constructor for a FIFO queue. *maxsize* is an integer that sets the upperbound limit on the number of items that can be placed in the queue. Insertion will block once this size has been reached, until queue items are consumed. If *maxsize* is less than or equal to zero, the queue size is infinite. +.. class:: LifoQueue(maxsize) + + Constructor for a LIFO queue. *maxsize* is an integer that sets the upperbound + limit on the number of items that can be placed in the queue. Insertion will + block once this size has been reached, until queue items are consumed. If + *maxsize* is less than or equal to zero, the queue size is infinite. + +.. class:: PriorityQueue(maxsize) + + Constructor for a priority queue. *maxsize* is an integer that sets the upperbound + limit on the number of items that can be placed in the queue. Insertion will + block once this size has been reached, until queue items are consumed. If + *maxsize* is less than or equal to zero, the queue size is infinite. + + The lowest valued entries are retrieved first (the lowest valued entry is the + one returned by ``sorted(list(entries))[0]``). A typical pattern for entries + is a tuple in the form: ``(priority_number, data)``. .. exception:: Empty @@ -41,10 +64,8 @@ Queue Objects ------------- -Class :class:`Queue` implements queue objects and has the methods described -below. This class can be derived from in order to implement other queue -organizations (e.g. stack) but the inheritable interface is not described here. -See the source code for details. The public methods are: +Queue objects (:class:``Queue``, :class:``LifoQueue``, or :class:``PriorityQueue`` +provide the public methods described below. .. method:: Queue.qsize() Modified: python/branches/py3k/Lib/Queue.py ============================================================================== --- python/branches/py3k/Lib/Queue.py (original) +++ python/branches/py3k/Lib/Queue.py Thu Jan 17 01:13:27 2008 @@ -2,8 +2,9 @@ from time import time as _time from collections import deque +import heapq -__all__ = ['Empty', 'Full', 'Queue'] +__all__ = ['Empty', 'Full', 'Queue', 'PriorityQueue', 'LifoQueue'] class Empty(Exception): "Exception raised by Queue.get(block=0)/get_nowait()." @@ -182,7 +183,7 @@ def _init(self, maxsize): self.queue = deque() - def _qsize(self): + def _qsize(self, len=len): return len(self.queue) # Put a new item in the queue @@ -192,3 +193,38 @@ # Get an item from the queue def _get(self): return self.queue.popleft() + + +class PriorityQueue(Queue): + '''Variant of Queue that retrieves open entries in priority order (lowest first). + + Entries are typically tuples of the form: (priority number, data). + ''' + + def _init(self, maxsize): + self.queue = [] + + def _qsize(self, len=len): + return len(self.queue) + + def _put(self, item, heappush=heapq.heappush): + heappush(self.queue, item) + + def _get(self, heappop=heapq.heappop): + return heappop(self.queue) + + +class LifoQueue(Queue): + '''Variant of Queue that retrieves most recently added entries first.''' + + def _init(self, maxsize): + self.queue = [] + + def _qsize(self, len=len): + return len(self.queue) + + def _put(self, item): + self.queue.append(item) + + def _get(self): + return self.queue.pop() From python-3000-checkins at python.org Thu Jan 17 08:36:31 2008 From: python-3000-checkins at python.org (jeffrey.yasskin) Date: Thu, 17 Jan 2008 08:36:31 +0100 (CET) Subject: [Python-3000-checkins] r60014 - in python/branches/py3k/Lib: numbers.py rational.py test/test_rational.py Message-ID: <20080117073631.2178D1E401E@bag.python.org> Author: jeffrey.yasskin Date: Thu Jan 17 08:36:30 2008 New Revision: 60014 Modified: python/branches/py3k/Lib/numbers.py python/branches/py3k/Lib/rational.py python/branches/py3k/Lib/test/test_rational.py Log: Update the py3k version of the rational module to expose only methods needed by py3k (i.e., no __div__) and use py3k functions like math.floor(). Modified: python/branches/py3k/Lib/numbers.py ============================================================================== --- python/branches/py3k/Lib/numbers.py (original) +++ python/branches/py3k/Lib/numbers.py Thu Jan 17 08:36:30 2008 @@ -5,7 +5,6 @@ TODO: Fill out more detailed documentation on the operators.""" -from __future__ import division from abc import ABCMeta, abstractmethod, abstractproperty __all__ = ["Number", "Exact", "Inexact", @@ -62,8 +61,7 @@ def __complex__(self): """Return a builtin complex instance. Called for complex(self).""" - # Will be __bool__ in 3.0. - def __nonzero__(self): + def __bool__(self): """True if self != 0. Called for bool(self).""" return self != 0 @@ -122,29 +120,13 @@ raise NotImplementedError @abstractmethod - def __div__(self, other): - """self / other without __future__ division - - May promote to float. - """ - raise NotImplementedError - - @abstractmethod - def __rdiv__(self, other): - """other / self without __future__ division""" - raise NotImplementedError - - @abstractmethod def __truediv__(self, other): - """self / other with __future__ division. - - Should promote to float when necessary. - """ + """self / other: Should promote to float when necessary.""" raise NotImplementedError @abstractmethod def __rtruediv__(self, other): - """other / self with __future__ division""" + """other / self""" raise NotImplementedError @abstractmethod Modified: python/branches/py3k/Lib/rational.py ============================================================================== --- python/branches/py3k/Lib/rational.py (original) +++ python/branches/py3k/Lib/rational.py Thu Jan 17 08:36:30 2008 @@ -3,7 +3,6 @@ """Rational, infinite-precision, real numbers.""" -from __future__ import division import math import numbers import operator @@ -203,28 +202,14 @@ a.denominator * b.numerator) __truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv) - __div__, __rdiv__ = _operator_fallbacks(_div, operator.truediv) - - @classmethod - def _floordiv(cls, a, b): - div = a / b - if isinstance(div, RationalAbc): - # trunc(math.floor(div)) doesn't work if the rational is - # more precise than a float because the intermediate - # rounding may cross an integer boundary. - return div.numerator // div.denominator - else: - return math.floor(div) def __floordiv__(a, b): """a // b""" - # Will be math.floor(a / b) in 3.0. - return a._floordiv(a, b) + return math.floor(a / b) def __rfloordiv__(b, a): """a // b""" - # Will be math.floor(a / b) in 3.0. - return b._floordiv(a, b) + return math.floor(a / b) @classmethod def _mod(cls, a, b): @@ -324,11 +309,11 @@ shift = 10**abs(ndigits) # See _operator_fallbacks.forward to check that the results of # these operations will always be Rational and therefore have - # __round__(). + # round(). if ndigits > 0: - return Rational((self * shift).__round__(), shift) + return Rational(round(self * shift), shift) else: - return Rational((self / shift).__round__() * shift) + return Rational(round(self / shift) * shift) def __hash__(self): """hash(self) Modified: python/branches/py3k/Lib/test/test_rational.py ============================================================================== --- python/branches/py3k/Lib/test/test_rational.py (original) +++ python/branches/py3k/Lib/test/test_rational.py Thu Jan 17 08:36:30 2008 @@ -74,14 +74,14 @@ def testConversions(self): self.assertTypedEquals(-1, trunc(R(-11, 10))) - self.assertTypedEquals(-2, R(-11, 10).__floor__()) - self.assertTypedEquals(-1, R(-11, 10).__ceil__()) - self.assertTypedEquals(-1, R(-10, 10).__ceil__()) - - self.assertTypedEquals(0, R(-1, 10).__round__()) - self.assertTypedEquals(0, R(-5, 10).__round__()) - self.assertTypedEquals(-2, R(-15, 10).__round__()) - self.assertTypedEquals(-1, R(-7, 10).__round__()) + self.assertTypedEquals(-2, math.floor(R(-11, 10))) + self.assertTypedEquals(-1, math.ceil(R(-11, 10))) + self.assertTypedEquals(-1, math.ceil(R(-10, 10))) + + self.assertTypedEquals(0, round(R(-1, 10))) + self.assertTypedEquals(0, round(R(-5, 10))) + self.assertTypedEquals(-2, round(R(-15, 10))) + self.assertTypedEquals(-1, round(R(-7, 10))) self.assertEquals(False, bool(R(0, 1))) self.assertEquals(True, bool(R(3, 2))) @@ -96,11 +96,11 @@ self.assertTypedEquals(0.1+0j, complex(R(1,10))) def testRound(self): - self.assertTypedEquals(R(-200), R(-150).__round__(-2)) - self.assertTypedEquals(R(-200), R(-250).__round__(-2)) - self.assertTypedEquals(R(30), R(26).__round__(-1)) - self.assertTypedEquals(R(-2, 10), R(-15, 100).__round__(1)) - self.assertTypedEquals(R(-2, 10), R(-25, 100).__round__(1)) + self.assertTypedEquals(R(-200), round(R(-150), -2)) + self.assertTypedEquals(R(-200), round(R(-250), -2)) + self.assertTypedEquals(R(30), round(R(26), -1)) + self.assertTypedEquals(R(-2, 10), round(R(-15, 100), 1)) + self.assertTypedEquals(R(-2, 10), round(R(-25, 100), 1)) def testArithmetic(self): From python-3000-checkins at python.org Thu Jan 17 08:49:46 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Thu, 17 Jan 2008 08:49:46 +0100 (CET) Subject: [Python-3000-checkins] r60016 - in python/branches/py3k-importhook: Doc/library/imputil.rst Lib/imputil.py Lib/test/test_imp.py Message-ID: <20080117074946.2E1761E401E@bag.python.org> Author: christian.heimes Date: Thu Jan 17 08:49:45 2008 New Revision: 60016 Modified: python/branches/py3k-importhook/Doc/library/imputil.rst python/branches/py3k-importhook/Lib/imputil.py python/branches/py3k-importhook/Lib/test/test_imp.py Log: Implemented when_imported decorator. I've moved the decorator to imputils. Implementing the decorator in C is too complex and time consuming for a rather simple task. Modified: python/branches/py3k-importhook/Doc/library/imputil.rst ============================================================================== --- python/branches/py3k-importhook/Doc/library/imputil.rst (original) +++ python/branches/py3k-importhook/Doc/library/imputil.rst Thu Jan 17 08:49:45 2008 @@ -14,6 +14,17 @@ approach to custom :keyword:`import` functions. +.. function:: when_imported(name) + + When imported decorator for post import hooks. The *when_imported* + decorator provides a convenient way to register a post import + callback for a module:: + + @when_imported('name') + def callback(module): + do_something_with_module(module) + + .. class:: ImportManager([fs_imp]) Manage the import process. Modified: python/branches/py3k-importhook/Lib/imputil.py ============================================================================== --- python/branches/py3k-importhook/Lib/imputil.py (original) +++ python/branches/py3k-importhook/Lib/imputil.py Thu Jan 17 08:49:45 2008 @@ -19,10 +19,26 @@ import struct import marshal -__all__ = ["ImportManager","Importer","BuiltinImporter"] +__all__ = ["ImportManager","Importer","BuiltinImporter", "when_imported"] _ModuleType = type(sys) ### doesn't work in JPython... +def when_imported(name): + """When imported decorator for callbacks + + @when_imported('name') + def callback(module): + do_something_with_module(module) + + The callback is called with the module object as argument when the module + is loaded. If the module is already loaded the callback is called + immediately. + """ + def register(hook): + imp.register_post_import_hook(hook, name) + return register + + class ImportManager: "Manage the import process." Modified: python/branches/py3k-importhook/Lib/test/test_imp.py ============================================================================== --- python/branches/py3k-importhook/Lib/test/test_imp.py (original) +++ python/branches/py3k-importhook/Lib/test/test_imp.py Thu Jan 17 08:49:45 2008 @@ -1,5 +1,6 @@ import os import imp +from imputil import when_imported import sys import thread import unittest @@ -7,13 +8,6 @@ import tempfile from test import test_support - -def when_imported(name): - def register(hook): - imp.register_post_import_hook(hook, name) - return register - - class LockTests(unittest.TestCase): """Very basic test of import lock functions.""" From python-3000-checkins at python.org Thu Jan 17 19:46:56 2008 From: python-3000-checkins at python.org (thomas.heller) Date: Thu, 17 Jan 2008 19:46:56 +0100 (CET) Subject: [Python-3000-checkins] r60023 - in python/branches/py3k: Lib/ctypes/__init__.py Lib/ctypes/test/test_arrays.py Lib/ctypes/test/test_structures.py Modules/_ctypes/_ctypes.c Modules/_ctypes/cfield.c Message-ID: <20080117184656.129471E400D@bag.python.org> Author: thomas.heller Date: Thu Jan 17 19:46:55 2008 New Revision: 60023 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/ctypes/__init__.py python/branches/py3k/Lib/ctypes/test/test_arrays.py python/branches/py3k/Lib/ctypes/test/test_structures.py python/branches/py3k/Modules/_ctypes/_ctypes.c python/branches/py3k/Modules/_ctypes/cfield.c Log: Merged revisions 60001,60003-60004,60008 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60001 | thomas.heller | 2008-01-16 20:16:27 +0100 (Mi, 16 Jan 2008) | 3 lines Convert the internal ctypes array type cache to a WeakValueDict so that array types do not live longer than needed. ........ r60003 | thomas.heller | 2008-01-16 20:37:33 +0100 (Mi, 16 Jan 2008) | 3 lines Raise a TypeError if conflicting positional and named arguments are passed to a Structure or Union constructor. ........ r60004 | thomas.heller | 2008-01-16 20:45:51 +0100 (Mi, 16 Jan 2008) | 3 lines Raise a TypeError instead of a ValueError when too many initializers are used in a Structure or Union constructor. ........ r60008 | thomas.heller | 2008-01-16 21:34:37 +0100 (Mi, 16 Jan 2008) | 3 lines Use 'g' instead of 'D' as the ctypes typecode for c_longdouble, for compliance with PEP 3118. ........ Modified: python/branches/py3k/Lib/ctypes/__init__.py ============================================================================== --- python/branches/py3k/Lib/ctypes/__init__.py (original) +++ python/branches/py3k/Lib/ctypes/__init__.py Thu Jan 17 19:46:55 2008 @@ -182,7 +182,7 @@ _check_size(c_double) class c_longdouble(_SimpleCData): - _type_ = "D" + _type_ = "g" if sizeof(c_longdouble) == sizeof(c_double): c_longdouble = c_double Modified: python/branches/py3k/Lib/ctypes/test/test_arrays.py ============================================================================== --- python/branches/py3k/Lib/ctypes/test/test_arrays.py (original) +++ python/branches/py3k/Lib/ctypes/test/test_arrays.py Thu Jan 17 19:46:55 2008 @@ -116,5 +116,19 @@ self.failUnlessEqual(sz[1:4:2], "o") self.failUnlessEqual(sz.value, "foo") + def test_cache(self): + # Array types are cached internally in the _ctypes extension, + # in a WeakValueDictionary. Make sure the array type is + # removed from the cache when the itemtype goes away. This + # test will not fail, but will show a leak in the testsuite. + + # Create a new type: + class my_int(c_int): + pass + # Create a new array type based on it: + t1 = my_int * 1 + t2 = my_int * 1 + self.failUnless(t1 is t2) + if __name__ == '__main__': unittest.main() Modified: python/branches/py3k/Lib/ctypes/test/test_structures.py ============================================================================== --- python/branches/py3k/Lib/ctypes/test/test_structures.py (original) +++ python/branches/py3k/Lib/ctypes/test/test_structures.py Thu Jan 17 19:46:55 2008 @@ -215,6 +215,15 @@ # too long self.assertRaises(ValueError, Person, "1234567", 5) + def test_conflicting_initializers(self): + class POINT(Structure): + _fields_ = [("x", c_int), ("y", c_int)] + # conflicting positional and keyword args + self.assertRaises(TypeError, POINT, 2, 3, x=4) + self.assertRaises(TypeError, POINT, 2, 3, y=4) + + # too many initializers + self.assertRaises(TypeError, POINT, 2, 3, 4) def test_keyword_initializers(self): class POINT(Structure): @@ -305,9 +314,9 @@ self.failUnlessEqual(cls, RuntimeError) if issubclass(Exception, object): self.failUnlessEqual(msg, - "(Phone) : too many initializers") + "(Phone) : too many initializers") else: - self.failUnlessEqual(msg, "(Phone) ValueError: too many initializers") + self.failUnlessEqual(msg, "(Phone) TypeError: too many initializers") def get_except(self, func, *args): Modified: python/branches/py3k/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k/Modules/_ctypes/_ctypes.c Thu Jan 17 19:46:55 2008 @@ -122,6 +122,7 @@ PyObject *PyExc_ArgError; static PyTypeObject Simple_Type; +PyObject *array_types_cache; char *conversion_mode_encoding = NULL; char *conversion_mode_errors = NULL; @@ -1112,7 +1113,7 @@ */ -static char *SIMPLE_TYPE_CHARS = "cbBhHiIlLdfuzZqQPXOvtD"; +static char *SIMPLE_TYPE_CHARS = "cbBhHiIlLdfuzZqQPXOvtg"; static PyObject * c_wchar_p_from_param(PyObject *type, PyObject *value) @@ -3535,7 +3536,7 @@ if (PyTuple_GET_SIZE(args) > PySequence_Length(fields)) { Py_DECREF(fields); - PyErr_SetString(PyExc_ValueError, + PyErr_SetString(PyExc_TypeError, "too many initializers"); return -1; } @@ -3556,6 +3557,21 @@ return IBUG("_fields_[i][0] failed"); } + if (kwds && PyDict_GetItem(kwds, name)) { + char *field = PyString_AsString(name); + if (field == NULL) { + PyErr_Clear(); + field = "???"; + } + PyErr_Format(PyExc_TypeError, + "duplicate values for field %s", + field); + Py_DECREF(pair); + Py_DECREF(name); + Py_DECREF(fields); + return -1; + } + val = PyTuple_GET_ITEM(args, i); if (-1 == PyObject_SetAttr(self, name, val)) { Py_DECREF(pair); @@ -3977,25 +3993,19 @@ PyObject * CreateArrayType(PyObject *itemtype, Py_ssize_t length) { - static PyObject *cache; PyObject *key; PyObject *result; char name[256]; - if (cache == NULL) { - cache = PyDict_New(); - if (cache == NULL) - return NULL; - } key = Py_BuildValue("(On)", itemtype, length); if (!key) return NULL; - result = PyDict_GetItem(cache, key); + result = PyObject_GetItem(array_types_cache, key); if (result) { - Py_INCREF(result); Py_DECREF(key); return result; - } + } else + PyErr_Clear(); if (!PyType_Check(itemtype)) { PyErr_SetString(PyExc_TypeError, @@ -4021,7 +4031,11 @@ ); if (!result) return NULL; - PyDict_SetItem(cache, key, result); + if (-1 == PyObject_SetItem(array_types_cache, key, result)) { + Py_DECREF(key); + Py_DECREF(result); + return NULL; + } Py_DECREF(key); return result; } @@ -4778,6 +4792,7 @@ init_ctypes(void) { PyObject *m; + PyObject *weakref; /* Note: ob_type is the metatype (the 'type'), defaults to PyType_Type, @@ -4790,6 +4805,16 @@ if (!m) return; + weakref = PyImport_ImportModule("weakref"); + if (weakref == NULL) + return; + array_types_cache = PyObject_CallMethod(weakref, + "WeakValueDictionary", + NULL); + if (array_types_cache == NULL) + return; + Py_DECREF(weakref); + if (PyType_Ready(&PyCArg_Type) < 0) return; Modified: python/branches/py3k/Modules/_ctypes/cfield.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/cfield.c (original) +++ python/branches/py3k/Modules/_ctypes/cfield.c Thu Jan 17 19:46:55 2008 @@ -983,7 +983,7 @@ static PyObject * -D_set(void *ptr, PyObject *value, Py_ssize_t size) +g_set(void *ptr, PyObject *value, Py_ssize_t size) { long double x; @@ -999,7 +999,7 @@ } static PyObject * -D_get(void *ptr, Py_ssize_t size) +g_get(void *ptr, Py_ssize_t size) { long double val; memcpy(&val, ptr, sizeof(long double)); @@ -1630,7 +1630,7 @@ { 'B', B_set, B_get, &ffi_type_uchar}, { 'c', c_set, c_get, &ffi_type_schar}, { 'd', d_set, d_get, &ffi_type_double, d_set_sw, d_get_sw}, - { 'D', D_set, D_get, &ffi_type_longdouble}, + { 'g', g_set, g_get, &ffi_type_longdouble}, { 'f', f_set, f_get, &ffi_type_float, f_set_sw, f_get_sw}, { 'h', h_set, h_get, &ffi_type_sshort, h_set_sw, h_get_sw}, { 'H', H_set, H_get, &ffi_type_ushort, H_set_sw, H_get_sw}, From python-3000-checkins at python.org Fri Jan 18 10:56:23 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Fri, 18 Jan 2008 10:56:23 +0100 (CET) Subject: [Python-3000-checkins] r60044 - in python/branches/py3k: Doc/conf.py Doc/howto/curses.rst Doc/library/collections.rst Doc/library/itertools.rst Doc/library/msilib.rst Doc/library/queue.rst Doc/library/sched.rst Doc/library/smtplib.rst Doc/library/socket.rst Doc/tools/sphinx-build.py Doc/tools/sphinxext Doc/whatsnew/2.6.rst Lib/decimal.py Lib/pdb.py Lib/sched.py Lib/smtplib.py Lib/test/test_itertools.py Lib/test/test_queue.py Modules/_ctypes/libffi/src/x86/ffi_darwin.c Modules/_elementtree.c Modules/_struct.c Modules/itertoolsmodule.c Modules/main.c Modules/zipimport.c Parser/pgen.c Python/traceback.c setup.py Message-ID: <20080118095623.D2F911E4013@bag.python.org> Author: christian.heimes Date: Fri Jan 18 10:56:22 2008 New Revision: 60044 Added: python/branches/py3k/Doc/tools/sphinxext/ - copied from r60007, python/trunk/Doc/tools/sphinxext/ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/conf.py python/branches/py3k/Doc/howto/curses.rst python/branches/py3k/Doc/library/collections.rst python/branches/py3k/Doc/library/itertools.rst python/branches/py3k/Doc/library/msilib.rst python/branches/py3k/Doc/library/queue.rst python/branches/py3k/Doc/library/sched.rst python/branches/py3k/Doc/library/smtplib.rst python/branches/py3k/Doc/library/socket.rst python/branches/py3k/Doc/tools/sphinx-build.py python/branches/py3k/Doc/whatsnew/2.6.rst python/branches/py3k/Lib/decimal.py python/branches/py3k/Lib/pdb.py python/branches/py3k/Lib/sched.py python/branches/py3k/Lib/smtplib.py python/branches/py3k/Lib/test/test_itertools.py python/branches/py3k/Lib/test/test_queue.py python/branches/py3k/Modules/_ctypes/libffi/src/x86/ffi_darwin.c python/branches/py3k/Modules/_elementtree.c python/branches/py3k/Modules/_struct.c python/branches/py3k/Modules/itertoolsmodule.c python/branches/py3k/Modules/main.c python/branches/py3k/Modules/zipimport.c python/branches/py3k/Parser/pgen.c python/branches/py3k/Python/traceback.c python/branches/py3k/setup.py Log: Merged revisions 59985-60000,60002,60005-60007,60009-60042 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r59987 | raymond.hettinger | 2008-01-15 21:52:42 +0100 (Tue, 15 Jan 2008) | 1 line Refactor if/elif chain for clarity and speed. Remove dependency on subclasses having to implement _empty and _full. ........ r59988 | raymond.hettinger | 2008-01-15 22:22:47 +0100 (Tue, 15 Jan 2008) | 1 line Fix-up half-written paragraph in the docs ........ r59989 | amaury.forgeotdarc | 2008-01-15 22:25:11 +0100 (Tue, 15 Jan 2008) | 3 lines test_doctest fails since r59984. Not sure if these are the correct values, but save_stdout has to be set before its usage... ........ r59992 | andrew.kuchling | 2008-01-16 01:32:03 +0100 (Wed, 16 Jan 2008) | 1 line Docstring typos ........ r59993 | andrew.kuchling | 2008-01-16 04:17:25 +0100 (Wed, 16 Jan 2008) | 1 line Add PEP 3141 section ........ r59998 | andrew.kuchling | 2008-01-16 14:01:51 +0100 (Wed, 16 Jan 2008) | 1 line Markup fix ........ r59999 | georg.brandl | 2008-01-16 17:56:29 +0100 (Wed, 16 Jan 2008) | 2 lines Fix MSDN library URL. (#1854) ........ r60006 | georg.brandl | 2008-01-16 21:27:56 +0100 (Wed, 16 Jan 2008) | 3 lines Add Python-specific content to Doc dir. Update configuration file to work with the newest Sphinx. ........ r60007 | georg.brandl | 2008-01-16 21:29:00 +0100 (Wed, 16 Jan 2008) | 2 lines Doc build should work with 2.4 now. ........ r60009 | raymond.hettinger | 2008-01-17 00:38:16 +0100 (Thu, 17 Jan 2008) | 1 line Minor wordsmithing. ........ r60010 | raymond.hettinger | 2008-01-17 00:40:45 +0100 (Thu, 17 Jan 2008) | 1 line Add queues will alternative fetch orders (priority based and stack based). ........ r60011 | raymond.hettinger | 2008-01-17 00:49:35 +0100 (Thu, 17 Jan 2008) | 1 line Add news entry. ........ r60013 | raymond.hettinger | 2008-01-17 04:02:14 +0100 (Thu, 17 Jan 2008) | 1 line Make starmap() match its pure python definition and accept any itertable input (not just tuples). ........ r60015 | gregory.p.smith | 2008-01-17 08:43:20 +0100 (Thu, 17 Jan 2008) | 3 lines Comply with RFC 3207. Fixes issue 829951 - http://bugs.python.org/issue829951 ........ r60018 | gregory.p.smith | 2008-01-17 09:03:17 +0100 (Thu, 17 Jan 2008) | 2 lines entry for r60015 ........ r60019 | raymond.hettinger | 2008-01-17 09:07:05 +0100 (Thu, 17 Jan 2008) | 1 line Note versionadded. ........ r60020 | gregory.p.smith | 2008-01-17 09:35:49 +0100 (Thu, 17 Jan 2008) | 8 lines Fixes (accepts patch) issue1339 - http://bugs.python.org/issue1339 - Factor out the duplication of EHLO/HELO in login() and sendmail() to a new function, ehlo_or_helo_if_needed(). - Use ehlo_or_helo_if_needed() in starttls() - Check for the starttls exception in starttls() in the same way as login() checks for the auth extension. Contributed by Bill Fenner. ........ r60021 | andrew.kuchling | 2008-01-17 13:00:15 +0100 (Thu, 17 Jan 2008) | 1 line Revise 3141 section a bit; add some Windows items ........ r60022 | brett.cannon | 2008-01-17 19:45:10 +0100 (Thu, 17 Jan 2008) | 2 lines Fix a function pointer declaration to silence the compiler. ........ r60024 | raymond.hettinger | 2008-01-17 20:31:38 +0100 (Thu, 17 Jan 2008) | 1 line Issue #1861: Add read-only attribute listing upcoming events in the order they will be run. ........ r60025 | andrew.kuchling | 2008-01-17 20:49:24 +0100 (Thu, 17 Jan 2008) | 1 line Correction from Jordan Lewis: halfdelay() uses tenths of a second, not milliseconds ........ r60026 | raymond.hettinger | 2008-01-17 23:27:49 +0100 (Thu, 17 Jan 2008) | 1 line Add advice on choosing between scheduler and threading.Timer(). ........ r60028 | christian.heimes | 2008-01-18 00:01:44 +0100 (Fri, 18 Jan 2008) | 2 lines Updated new property syntax. An elaborate example for subclassing and the getter was missing. Added comment about VS 2008 and PGO builds. ........ r60029 | raymond.hettinger | 2008-01-18 00:32:01 +0100 (Fri, 18 Jan 2008) | 1 line Fix-up Timer() example. ........ r60030 | raymond.hettinger | 2008-01-18 00:56:56 +0100 (Fri, 18 Jan 2008) | 1 line Fix markup ........ r60031 | raymond.hettinger | 2008-01-18 01:10:42 +0100 (Fri, 18 Jan 2008) | 1 line clearcache() needs to remove the dict as well as clear it. ........ r60033 | andrew.kuchling | 2008-01-18 03:26:16 +0100 (Fri, 18 Jan 2008) | 1 line Bump verson ........ r60034 | andrew.kuchling | 2008-01-18 03:42:52 +0100 (Fri, 18 Jan 2008) | 1 line Typo fix ........ r60035 | christian.heimes | 2008-01-18 08:30:20 +0100 (Fri, 18 Jan 2008) | 3 lines Coverity issue CID #197 var_decl: Declared variable "stm" without initializer ninit_use_in_call: Using uninitialized value "stm" (field "stm".tm_zone uninitialized) in call to function "mktime" ........ r60036 | christian.heimes | 2008-01-18 08:45:30 +0100 (Fri, 18 Jan 2008) | 11 lines Coverity issue CID #167 Event alloc_fn: Called allocation function "metacompile" [model] Event var_assign: Assigned variable "gr" to storage returned from "metacompile" gr = metacompile(n); Event pass_arg: Variable "gr" not freed or pointed-to in function "maketables" [model] g = maketables(gr); translatelabels(g); addfirstsets(g); Event leaked_storage: Returned without freeing storage "gr" return g; ........ r60038 | christian.heimes | 2008-01-18 09:04:57 +0100 (Fri, 18 Jan 2008) | 3 lines Coverity issue CID #182 size_error: Allocating 1 bytes to pointer "children", which needs at least 4 bytes ........ r60041 | christian.heimes | 2008-01-18 09:47:59 +0100 (Fri, 18 Jan 2008) | 4 lines Coverity issue CID #169 local_ptr_assign_local: Assigning address of stack variable "namebuf" to pointer "filename" out_of_scope: Variable "namebuf" goes out of scope use_invalid: Used "filename" pointing to out-of-scope variable "namebuf" ........ r60042 | christian.heimes | 2008-01-18 09:53:45 +0100 (Fri, 18 Jan 2008) | 2 lines Coverity CID #168 leaked_storage: Returned without freeing storage "fp" ........ Modified: python/branches/py3k/Doc/conf.py ============================================================================== --- python/branches/py3k/Doc/conf.py (original) +++ python/branches/py3k/Doc/conf.py Fri Jan 18 10:56:22 2008 @@ -2,22 +2,28 @@ # # Python documentation build configuration file # +# This file is execfile()d with the current directory set to its containing dir. +# # The contents of this file are pickled, so don't put values in the namespace # that aren't pickleable (module imports are okay, they're removed automatically). # General configuration # --------------------- +# General substitutions. +project = 'Python' +copyright = '1990-2007, Python Software Foundation' + # The default replacements for |version| and |release|. -# If 'auto', Sphinx looks for the Include/patchlevel.h file in the current Python +# If '', Sphinx looks for the Include/patchlevel.h file in the current Python # source tree and replaces the values accordingly. # # The short X.Y version. # version = '2.6' -version = 'auto' +version = '' # The full version, including alpha/beta/rc tags. # release = '2.6a0' -release = 'auto' +release = '' # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: @@ -39,6 +45,9 @@ 'library/xml.etree.rst', ] +# Relative filename of the reference count data file. +refcount_file = 'data/refcounts.dat' + # If true, '()' will be appended to :func: etc. cross-reference text. add_function_parentheses = True @@ -50,9 +59,6 @@ # Options for HTML output # ----------------------- -# The base URL for download links. -html_download_base_url = 'http://docs.python.org/ftp/python/doc/' - # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. html_last_updated_fmt = '%b %d, %Y' @@ -61,12 +67,71 @@ # typographically correct entities. html_use_smartypants = True +# Content template for the index page, filename relative to this file. +html_index = 'tools/sphinxext/indexcontent.html' + +# Custom sidebar templates, filenames relative to this file. +html_sidebars = { + 'index': 'tools/sphinxext/indexsidebar.html', +} + +# Additional templates that should be rendered to pages. +html_additional_pages = { + 'download': 'tools/sphinxext/download.html', +} + +# Output file base name for HTML help builder. +htmlhelp_basename = 'pydoc' + # Options for LaTeX output # ------------------------ -# The paper size ("letter" or "a4"). -latex_paper_size = "a4" +# The paper size ('letter' or 'a4'). +latex_paper_size = 'a4' + +# The font size ('10pt', '11pt' or '12pt'). +latex_font_size = '10pt' + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, document class [howto/manual]). +_stdauthor = r'Guido van Rossum\\Fred L. Drake, Jr., editor' +latex_documents = [ + ('c-api/index.rst', 'c-api.tex', + 'The Python/C API', _stdauthor, 'manual'), + ('distutils/index.rst', 'distutils.tex', + 'Distributing Python Modules', _stdauthor, 'manual'), + ('documenting/index.rst', 'documenting.tex', + 'Documenting Python', 'Georg Brandl', 'manual'), + ('extending/index.rst', 'extending.tex', + 'Extending and Embedding Python', _stdauthor, 'manual'), + ('install/index.rst', 'install.tex', + 'Installing Python Modules', _stdauthor, 'manual'), + ('library/index.rst', 'library.tex', + 'The Python Library Reference', _stdauthor, 'manual'), + ('reference/index.rst', 'reference.tex', + 'The Python Language Reference', _stdauthor, 'manual'), + ('tutorial/index.rst', 'tutorial.tex', + 'Python Tutorial', _stdauthor, 'manual'), + ('using/index.rst', 'using.tex', + 'Using Python', _stdauthor, 'manual'), + ('whatsnew/' + version + '.rst', 'whatsnew.tex', + 'What\'s New in Python', 'A. M. Kuchling', 'howto'), +] +# Collect all HOWTOs individually +import os +latex_documents.extend(('howto/' + fn, 'howto-' + fn[:-4] + '.tex', + 'HOWTO', _stdauthor, 'howto') + for fn in os.listdir('howto') + if fn.endswith('.rst') and fn != 'index.rst') + +# Additional stuff for the LaTeX preamble. +latex_preamble = r''' +\authoraddress{ + \strong{Python Software Foundation}\\ + Email: \email{docs at python.org} +} +''' -# The font size ("10pt", "11pt" or "12pt"). -latex_font_size = "10pt" +# Documents to append as an appendix to all manuals. +latex_appendices = ['glossary.rst', 'about.rst', 'license.rst', 'copyright.rst'] Modified: python/branches/py3k/Doc/howto/curses.rst ============================================================================== --- python/branches/py3k/Doc/howto/curses.rst (original) +++ python/branches/py3k/Doc/howto/curses.rst Fri Jan 18 10:56:22 2008 @@ -3,7 +3,7 @@ ********************************** :Author: A.M. Kuchling, Eric S. Raymond -:Release: 2.02 +:Release: 2.03 .. topic:: Abstract @@ -367,8 +367,8 @@ ``nodelay(1)``, :meth:`getch` for the window becomes non-blocking and returns ``curses.ERR`` (a value of -1) when no input is ready. There's also a :func:`halfdelay` function, which can be used to (in effect) set a timer on each -:meth:`getch`; if no input becomes available within the number of milliseconds -specified as the argument to :func:`halfdelay`, curses raises an exception. +:meth:`getch`; if no input becomes available within a specified +delay (measured in tenths of a second), curses raises an exception. The :meth:`getch` method returns an integer; if it's between 0 and 255, it represents the ASCII code of the key pressed. Values greater than 255 are Modified: python/branches/py3k/Doc/library/collections.rst ============================================================================== --- python/branches/py3k/Doc/library/collections.rst (original) +++ python/branches/py3k/Doc/library/collections.rst Fri Jan 18 10:56:22 2008 @@ -566,6 +566,9 @@ def _replace(self, _map=map, **kwds): return self._make(_map(kwds.get, ('x', 'y'), self)) +The subclasses shown above set ``__slots__`` to an empty tuple. This keeps +keep memory requirements low by preventing the creation of instance dictionaries. + Subclassing is not useful for adding new, stored fields. Instead, simply create a new named tuple type from the :attr:`_fields` attribute:: Modified: python/branches/py3k/Doc/library/itertools.rst ============================================================================== --- python/branches/py3k/Doc/library/itertools.rst (original) +++ python/branches/py3k/Doc/library/itertools.rst Fri Jan 18 10:56:22 2008 @@ -319,16 +319,19 @@ .. function:: starmap(function, iterable) - Make an iterator that computes the function using arguments tuples obtained from + Make an iterator that computes the function using arguments obtained from the iterable. Used instead of :func:`imap` when argument parameters are already grouped in tuples from a single iterable (the data has been "pre-zipped"). The difference between :func:`imap` and :func:`starmap` parallels the distinction between ``function(a,b)`` and ``function(*c)``. Equivalent to:: def starmap(function, iterable): - iterable = iter(iterable) - while True: - yield function(*next(iterable)) + for args in iterable: + yield function(*args) + + .. versionchanged:: 2.6 + Previously, :func:`starmap` required the function arguments to be tuples. + Now, any iterable is allowed. .. function:: takewhile(predicate, iterable) Modified: python/branches/py3k/Doc/library/msilib.rst ============================================================================== --- python/branches/py3k/Doc/library/msilib.rst (original) +++ python/branches/py3k/Doc/library/msilib.rst Fri Jan 18 10:56:22 2008 @@ -146,7 +146,7 @@ .. seealso:: - `MSIOpenView `_ + `MSIDatabaseOpenView `_ `MSIDatabaseCommit `_ `MSIGetSummaryInformation `_ Modified: python/branches/py3k/Doc/library/queue.rst ============================================================================== --- python/branches/py3k/Doc/library/queue.rst (original) +++ python/branches/py3k/Doc/library/queue.rst Fri Jan 18 10:56:22 2008 @@ -29,6 +29,7 @@ block once this size has been reached, until queue items are consumed. If *maxsize* is less than or equal to zero, the queue size is infinite. + .. class:: LifoQueue(maxsize) Constructor for a LIFO queue. *maxsize* is an integer that sets the upperbound @@ -36,6 +37,9 @@ block once this size has been reached, until queue items are consumed. If *maxsize* is less than or equal to zero, the queue size is infinite. + .. versionadded:: 2.6 + + .. class:: PriorityQueue(maxsize) Constructor for a priority queue. *maxsize* is an integer that sets the upperbound @@ -47,6 +51,9 @@ one returned by ``sorted(list(entries))[0]``). A typical pattern for entries is a tuple in the form: ``(priority_number, data)``. + .. versionadded:: 2.6 + + .. exception:: Empty Exception raised when non-blocking :meth:`get` (or :meth:`get_nowait`) is called Modified: python/branches/py3k/Doc/library/sched.rst ============================================================================== --- python/branches/py3k/Doc/library/sched.rst (original) +++ python/branches/py3k/Doc/library/sched.rst Fri Jan 18 10:56:22 2008 @@ -41,13 +41,39 @@ From print_time 930343700.273 930343700.276 +In multi-threaded environments, the :class:`scheduler` class has limitations +with respect to thread-safety, inability to insert a new task before +the one currently pending in a running scheduler, and holding up the main +thread until the event queue is empty. Instead, the preferred approach +is to use the :class:`threading.Timer` class instead. + +Example:: + + >>> import time + >>> from threading import Timer + >>> def print_time(): + ... print "From print_time", time.time() + ... + >>> def print_some_times(): + ... print time.time() + ... Timer(5, print_time, ()).start() + ... Timer(10, print_time, ()).start() + ... time.sleep(11) # sleep while time-delay events execute + ... print time.time() + ... + >>> print_some_times() + 930343690.257 + From print_time 930343695.274 + From print_time 930343700.273 + 930343701.301 + .. _scheduler-objects: Scheduler Objects ----------------- -:class:`scheduler` instances have the following methods: +:class:`scheduler` instances have the following methods and attributes: .. method:: scheduler.enterabs(time, priority, action, argument) @@ -98,3 +124,10 @@ the calling code is responsible for canceling events which are no longer pertinent. +.. attribute:: scheduler.queue + + Read-only attribute returning a list of upcoming events in the order they + will be run. Each event is shown as a :term:`named tuple` with the + following fields: time, priority, action, argument. + + .. versionadded:: 2.6 Modified: python/branches/py3k/Doc/library/smtplib.rst ============================================================================== --- python/branches/py3k/Doc/library/smtplib.rst (original) +++ python/branches/py3k/Doc/library/smtplib.rst Fri Jan 18 10:56:22 2008 @@ -184,6 +184,16 @@ necessary to call this method explicitly. It will be implicitly called by :meth:`sendmail` when necessary. +.. method:: SMTP.ehlo_or_helo_if_needed() + + This method call :meth:`ehlo` and or :meth:`helo` if there has been no + previous ``EHLO`` or ``HELO`` command this session. It tries ESMTP ``EHLO`` + first. + + :exc:SMTPHeloError + The server didn't reply properly to the ``HELO`` greeting. + + .. versionadded:: 2.6 .. method:: SMTP.has_extn(name) @@ -230,6 +240,22 @@ If *keyfile* and *certfile* are provided, these are passed to the :mod:`socket` module's :func:`ssl` function. + If there has been no previous ``EHLO`` or ``HELO`` command this session, + this method tries ESMTP ``EHLO`` first. + + .. versionchanged:: 2.6 + + :exc:`SMTPHeloError` + The server didn't reply properly to the ``HELO`` greeting. + + :exc:`SMTPException` + The server does not support the STARTTLS extension. + + .. versionchanged:: 2.6 + + :exc:`RuntimeError` + SSL/TLS support is not available to your python interpreter. + .. method:: SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options]) Modified: python/branches/py3k/Doc/library/socket.rst ============================================================================== --- python/branches/py3k/Doc/library/socket.rst (original) +++ python/branches/py3k/Doc/library/socket.rst Fri Jan 18 10:56:22 2008 @@ -562,7 +562,7 @@ :platform: Windows - The `meth:ioctl` method is a limited interface to the WSAIoctl system + The :meth:`ioctl` method is a limited interface to the WSAIoctl system interface. Please refer to the MSDN documentation for more information. Modified: python/branches/py3k/Doc/tools/sphinx-build.py ============================================================================== --- python/branches/py3k/Doc/tools/sphinx-build.py (original) +++ python/branches/py3k/Doc/tools/sphinx-build.py Fri Jan 18 10:56:22 2008 @@ -11,12 +11,13 @@ if __name__ == '__main__': - if not (2, 5, 1) <= sys.version_info[:3] < (3, 0, 0): - sys.stderr.write("""\ -Error: Sphinx needs to be executed with Python 2.5.1 or newer (not 3.0 though). -If you run this from the Makefile, you can set the PYTHON variable to the path -of an alternative interpreter executable, e.g., ``make html PYTHON=python2.5``.) -""") + if sys.version_info[:3] < (2, 4, 0): + print("""\ +Error: Sphinx needs to be executed with Python 2.4 or newer (not 3.0 though). +(If you run this from the Makefile, you can set the PYTHON variable +to the path of an alternative interpreter executable, e.g., +``make html PYTHON=python2.5``). +""", file=sys.stderr) sys.exit(1) from sphinx import main Modified: python/branches/py3k/Doc/whatsnew/2.6.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/2.6.rst (original) +++ python/branches/py3k/Doc/whatsnew/2.6.rst Fri Jan 18 10:56:22 2008 @@ -541,6 +541,90 @@ Implemented by XXX. Backported to 2.6 by Benjamin Aranguren, with Alex Martelli. +.. ====================================================================== + +.. _pep-3141: + +PEP 3141: A Type Hierarchy for Numbers +===================================================== + +In Python 3.0, several abstract base classes for numeric types, +inspired by Scheme's numeric tower, are being added. +This change was backported to 2.6 as the :mod:`numbers` module. + +The most general ABC is :class:`Number`. It defines no operations at +all, and only exists to allow checking if an object is a number by +doing ``isinstance(obj, Number)``. + +Numbers are further divided into :class:`Exact` and :class:`Inexact`. +Exact numbers can represent values precisely and operations never +round off the results or introduce tiny errors that may break the +communtativity and associativity properties; inexact numbers may +perform such rounding or introduce small errors. Integers, long +integers, and rational numbers are exact, while floating-point +and complex numbers are inexact. + +:class:`Complex` is a subclass of :class:`Number`. Complex numbers +can undergo the basic operations of addition, subtraction, +multiplication, division, and exponentiation, and you can retrieve the +real and imaginary parts and obtain a number's conjugate. Python's built-in +complex type is an implementation of :class:`Complex`. + +:class:`Real` further derives from :class:`Complex`, and adds +operations that only work on real numbers: :func:`floor`, :func:`trunc`, +rounding, taking the remainder mod N, floor division, +and comparisons. + +:class:`Rational` numbers derive from :class:`Real`, have +:attr:`numerator` and :attr:`denominator` properties, and can be +converted to floats. Python 2.6 adds a simple rational-number class +in the :mod:`rational` module. + +:class:`Integral` numbers derive from :class:`Rational`, and +can be shifted left and right with ``<<`` and ``>>``, +combined using bitwise operations such as ``&`` and ``|``, +and can be used as array indexes and slice boundaries. + +In Python 3.0, the PEP slightly redefines the existing built-ins +:func:`math.floor`, :func:`math.ceil`, :func:`round`, and adds a new +one, :func:`trunc`, that's been backported to Python 2.6. +:func:`trunc` rounds toward zero, returning the closest +:class:`Integral` that's between the function's argument and zero. + +.. seealso:: + + XXX link: Discusses Scheme's numeric tower. + + + +The Rational Module +-------------------------------------------------- + +To fill out the hierarchy of numeric types, a rational-number class +has been added as the :mod:`rational` module. Rational numbers are +represented as a fraction; rational numbers can exactly represent +numbers such as two-thirds that floating-point numbers can only +approximate. + +The :class:`Rational` constructor takes two :class:`Integral` values +that will be the numerator and denominator of the resulting fraction. :: + + >>> from rational import Rational + >>> a = Rational(2, 3) + >>> b = Rational(2, 5) + >>> float(a), float(b) + (0.66666666666666663, 0.40000000000000002) + >>> a+b + rational.Rational(16,15) + >>> a/b + rational.Rational(5,3) + +The :mod:`rational` module is based upon an implementation by Sjoerd +Mullender that was in Python's :file:`Demo/classes/` directory for a +long time. This implementation was significantly updated by Jeffrey +Yaskin. + + Other Language Changes ====================== @@ -568,10 +652,10 @@ .. Revision 57619 -* Properties now have two attributes, +* Properties now have three attributes, :attr:`getter`, :attr:`setter` and :attr:`deleter`, that are useful shortcuts for - adding a setter or deleter function to an existing property. - You would use them like this:: + adding or modifying a getter, setter or deleter function to an + existing property. You would use them like this:: class C(object): @property @@ -586,6 +670,15 @@ def x(self): del self._x + class D(C): + @C.x.getter + def x(self): + return self._x * 2 + + @x.setter + def x(self, value): + self._x = value / 2 + * C functions and methods that use :cfunc:`PyComplex_AsCComplex` will now accept arguments that @@ -997,6 +1090,12 @@ .. Patch #957003 +* In the :mod:`smtplib` module, SMTP.starttls() now complies with :rfc:`3207` + and forgets any knowledge obtained from the server not obtained from + the TLS negotiation itself. Patch contributed by Bill Fenner. + + .. Issue 829951 + * The :mod:`socket` module now supports TIPC (http://tipc.sf.net), a high-performance non-IP-based protocol designed for use in clustered environments. TIPC addresses are 4- or 5-tuples. @@ -1246,13 +1345,30 @@ API. The :func:`getwch` function reads a keypress and returns a Unicode value, as does the :func:`getwche` function. The :func:`putwch` function takes a Unicode character and writes it to the console. + (Contributed by Christian Heimes.) + +* :func:`os.path.expandvars` will now expand environment variables + in the form "%var%", and "~user" will be expanded into the + user's home directory path. (Contributed by Josiah Carlson.) + +* The :mod:`socket` module's socket objects now have an + :meth:`ioctl` method that provides a limited interface to the + :cfunc:`WSAIoctl` system interface. * The :mod:`_winreg` module now has a function, :func:`ExpandEnvironmentStrings`, that expands environment variable references such as ``%NAME%`` in an input string. The handle objects provided by this module now support the context protocol, so they can be used - in :keyword:`with` statements. + in :keyword:`with` statements. (Contributed by Christian Heimes.) + +* The new default compiler on Windows is Visual Studio 2008 (VS 9.0). The + build directories for Visual Studio 2003 (VS7.1) and 2005 (VS8.0) + were moved into the PC/ directory. The new PCbuild directory supports + cross compilation for X64, debug builds and Profile Guided Optimization + (PGO). PGO builds are roughly 10% faster than normal builds. + (Contributed by Christian Heimes with help from Amaury Forgeot d'Arc and + Martin von Loewis.) .. ====================================================================== Modified: python/branches/py3k/Lib/decimal.py ============================================================================== --- python/branches/py3k/Lib/decimal.py (original) +++ python/branches/py3k/Lib/decimal.py Fri Jan 18 10:56:22 2008 @@ -2982,7 +2982,7 @@ def _islogical(self): """Return True if self is a logical operand. - For being logical, it must be a finite numbers with a sign of 0, + For being logical, it must be a finite number with a sign of 0, an exponent of 0, and a coefficient whose digits must all be either 0 or 1. """ @@ -4098,7 +4098,7 @@ """max compares two values numerically and returns the maximum. If either operand is a NaN then the general rules apply. - Otherwise, the operands are compared as as though by the compare + Otherwise, the operands are compared as though by the compare operation. If they are numerically equal then the left-hand operand is chosen as the result. Otherwise the maximum (closer to positive infinity) of the two operands is chosen as the result. @@ -4122,7 +4122,7 @@ """min compares two values numerically and returns the minimum. If either operand is a NaN then the general rules apply. - Otherwise, the operands are compared as as though by the compare + Otherwise, the operands are compared as though by the compare operation. If they are numerically equal then the left-hand operand is chosen as the result. Otherwise the minimum (closer to negative infinity) of the two operands is chosen as the result. Modified: python/branches/py3k/Lib/pdb.py ============================================================================== --- python/branches/py3k/Lib/pdb.py (original) +++ python/branches/py3k/Lib/pdb.py Fri Jan 18 10:56:22 2008 @@ -198,6 +198,8 @@ globals = self.curframe.f_globals try: code = compile(line + '\n', '', 'single') + save_stdout = sys.stdout + save_stdin = sys.stdin try: sys.stdin = self.stdin sys.stdout = self.stdout Modified: python/branches/py3k/Lib/sched.py ============================================================================== --- python/branches/py3k/Lib/sched.py (original) +++ python/branches/py3k/Lib/sched.py Fri Jan 18 10:56:22 2008 @@ -29,14 +29,17 @@ # XXX the global state of your particular time and delay functions. import heapq +from collections import namedtuple __all__ = ["scheduler"] +Event = namedtuple('Event', 'time, priority, action, argument') + class scheduler: def __init__(self, timefunc, delayfunc): """Initialize a new instance, passing the time and delay functions""" - self.queue = [] + self._queue = [] self.timefunc = timefunc self.delayfunc = delayfunc @@ -47,8 +50,8 @@ if necessary. """ - event = time, priority, action, argument - heapq.heappush(self.queue, event) + event = Event(time, priority, action, argument) + heapq.heappush(self._queue, event) return event # The ID def enter(self, delay, priority, action, argument): @@ -67,12 +70,12 @@ If the event is not in the queue, this raises RuntimeError. """ - self.queue.remove(event) - heapq.heapify(self.queue) + self._queue.remove(event) + heapq.heapify(self._queue) def empty(self): """Check whether the queue is empty.""" - return not self.queue + return not self._queue def run(self): """Execute events until the queue is empty. @@ -97,7 +100,7 @@ """ # localize variable access to minimize overhead # and to improve thread safety - q = self.queue + q = self._queue delayfunc = self.delayfunc timefunc = self.timefunc pop = heapq.heappop @@ -115,3 +118,17 @@ delayfunc(0) # Let other threads run else: heapq.heappush(event) + + @property + def queue(self): + """An ordered list of upcoming events. + + Events are named tuples with fields for: + time, priority, action, arguments + + """ + # Use heapq to sort the queue rather than using 'sorted(self._queue)'. + # With heapq, two events scheduled at the same time will show in + # the actual order they would be retrieved. + events = self._queue[:] + return map(heapq.heappop, [events]*len(events)) Modified: python/branches/py3k/Lib/smtplib.py ============================================================================== --- python/branches/py3k/Lib/smtplib.py (original) +++ python/branches/py3k/Lib/smtplib.py Fri Jan 18 10:56:22 2008 @@ -495,6 +495,23 @@ # some useful methods + def ehlo_or_helo_if_needed(self): + """Call self.ehlo() and/or self.helo() if needed. + + If there has been no previous EHLO or HELO command this session, this + method tries ESMTP EHLO first. + + This method may raise the following exceptions: + + SMTPHeloError The server didn't reply properly to + the helo greeting. + """ + if self.helo_resp is None and self.ehlo_resp is None: + if not (200 <= self.ehlo()[0] <= 299): + (code, resp) = self.helo() + if not (200 <= code <= 299): + raise SMTPHeloError(code, resp) + def login(self, user, password): """Log in on an SMTP server that requires authentication. @@ -530,11 +547,7 @@ AUTH_CRAM_MD5 = "CRAM-MD5" AUTH_LOGIN = "LOGIN" - if self.helo_resp is None and self.ehlo_resp is None: - if not (200 <= self.ehlo()[0] <= 299): - (code, resp) = self.helo() - if not (200 <= code <= 299): - raise SMTPHeloError(code, resp) + self.ehlo_or_helo_if_needed() if not self.has_extn("auth"): raise SMTPException("SMTP AUTH extension not supported by server.") @@ -580,18 +593,37 @@ def starttls(self, keyfile = None, certfile = None): """Puts the connection to the SMTP server into TLS mode. + If there has been no previous EHLO or HELO command this session, this + method tries ESMTP EHLO first. + If the server supports TLS, this will encrypt the rest of the SMTP session. If you provide the keyfile and certfile parameters, the identity of the SMTP server and client can be checked. This, however, depends on whether the socket module really checks the certificates. + + This method may raise the following exceptions: + + SMTPHeloError The server didn't reply properly to + the helo greeting. """ + self.ehlo_or_helo_if_needed() + if not self.has_extn("starttls"): + raise SMTPException("STARTTLS extension not supported by server.") (resp, reply) = self.docmd("STARTTLS") if resp == 220: if not _have_ssl: raise RuntimeError("No SSL support included in this Python") self.sock = ssl.wrap_socket(self.sock, keyfile, certfile) self.file = SSLFakeFile(self.sock) + # RFC 3207: + # The client MUST discard any knowledge obtained from + # the server, such as the list of SMTP service extensions, + # which was not obtained from the TLS negotiation itself. + self.helo_resp = None + self.ehlo_resp = None + self.esmtp_features = {} + self.does_esmtp = 0 return (resp, reply) def sendmail(self, from_addr, to_addrs, msg, mail_options=[], @@ -651,11 +683,7 @@ empty dictionary. """ - if self.helo_resp is None and self.ehlo_resp is None: - if not (200 <= self.ehlo()[0] <= 299): - (code,resp) = self.helo() - if not (200 <= code <= 299): - raise SMTPHeloError(code, resp) + self.ehlo_or_helo_if_needed() esmtp_opts = [] if self.does_esmtp: # Hmmm? what's this? -ddm Modified: python/branches/py3k/Lib/test/test_itertools.py ============================================================================== --- python/branches/py3k/Lib/test/test_itertools.py (original) +++ python/branches/py3k/Lib/test/test_itertools.py Fri Jan 18 10:56:22 2008 @@ -300,7 +300,8 @@ self.assertEqual(take(3, starmap(operator.pow, izip(count(), count(1)))), [0**1, 1**2, 2**3]) self.assertEqual(list(starmap(operator.pow, [])), []) - self.assertRaises(TypeError, list, starmap(operator.pow, [[4,5]])) + self.assertEqual(list(starmap(operator.pow, [iter([4,5])])), [4**5]) + self.assertRaises(TypeError, list, starmap(operator.pow, [None])) self.assertRaises(TypeError, starmap) self.assertRaises(TypeError, starmap, operator.pow, [(4,5)], 'extra') self.assertRaises(TypeError, next, starmap(10, [(4,5)])) Modified: python/branches/py3k/Lib/test/test_queue.py ============================================================================== --- python/branches/py3k/Lib/test/test_queue.py (original) +++ python/branches/py3k/Lib/test/test_queue.py Fri Jan 18 10:56:22 2008 @@ -184,28 +184,35 @@ raise RuntimeError("Call this function with an empty queue") # I guess we better check things actually queue correctly a little :) q.put(111) + q.put(333) q.put(222) - verify(q.get() == 111 and q.get() == 222, + target_order = dict(Queue = [111, 333, 222], + LifoQueue = [222, 333, 111], + PriorityQueue = [111, 222, 333]) + actual_order = [q.get(), q.get(), q.get()] + verify(actual_order == target_order[q.__class__.__name__], "Didn't seem to queue the correct data!") for i in range(QUEUE_SIZE-1): q.put(i) verify(q.qsize(), "Queue should not be empty") verify(not qfull(q), "Queue should not be full") - q.put("last") + last = 2*QUEUE_SIZE + full = 3*2*QUEUE_SIZE + q.put(last) verify(qfull(q), "Queue should be full") try: - q.put("full", block=0) + q.put(full, block=0) raise TestFailed("Didn't appear to block with a full queue") except Queue.Full: pass try: - q.put("full", timeout=0.01) + q.put(full, timeout=0.01) raise TestFailed("Didn't appear to time-out with a full queue") except Queue.Full: pass # Test a blocking put - _doBlockingTest(q.put, ("full",), q.get, ()) - _doBlockingTest(q.put, ("full", True, 10), q.get, ()) + _doBlockingTest(q.put, (full,), q.get, ()) + _doBlockingTest(q.put, (full, True, 10), q.get, ()) # Empty it for i in range(QUEUE_SIZE): q.get() @@ -250,8 +257,7 @@ q.put(i) q.join() verify(cum==sum(range(100)), "q.join() did not block until all tasks were done") - for i in (0,1): - q.put(None) # instruct the threads to close + q.put(None) # instruct the threads to close q.join() # verify that you can join twice def QueueTaskDoneTest(q): @@ -263,18 +269,20 @@ raise TestFailed("Did not detect task count going negative") def test(): - q = Queue.Queue() - QueueTaskDoneTest(q) - QueueJoinTest(q) - QueueJoinTest(q) - QueueTaskDoneTest(q) - - q = Queue.Queue(QUEUE_SIZE) - # Do it a couple of times on the same queue - SimpleQueueTest(q) - SimpleQueueTest(q) - if verbose: - print("Simple Queue tests seemed to work") + for Q in Queue.Queue, Queue.LifoQueue, Queue.PriorityQueue: + q = Q() + QueueTaskDoneTest(q) + QueueJoinTest(q) + QueueJoinTest(q) + QueueTaskDoneTest(q) + + q = Q(QUEUE_SIZE) + # Do it a couple of times on the same queue + SimpleQueueTest(q) + SimpleQueueTest(q) + if verbose: + print("Simple Queue tests seemed to work for", Q.__name__) + q = FailingQueue(QUEUE_SIZE) FailingQueueTest(q) FailingQueueTest(q) Modified: python/branches/py3k/Modules/_ctypes/libffi/src/x86/ffi_darwin.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/libffi/src/x86/ffi_darwin.c (original) +++ python/branches/py3k/Modules/_ctypes/libffi/src/x86/ffi_darwin.c Fri Jan 18 10:56:22 2008 @@ -217,7 +217,7 @@ #endif /* X86_WIN32 */ void ffi_call(/*@dependent@*/ ffi_cif *cif, - void (*fn)(), + void (*fn)(void), /*@out@*/ void *rvalue, /*@dependent@*/ void **avalue) { Modified: python/branches/py3k/Modules/_elementtree.c ============================================================================== --- python/branches/py3k/Modules/_elementtree.c (original) +++ python/branches/py3k/Modules/_elementtree.c Fri Jan 18 10:56:22 2008 @@ -348,7 +348,17 @@ if (size > self->extra->allocated) { /* use Python 2.4's list growth strategy */ size = (size >> 3) + (size < 9 ? 3 : 6) + size; + /* Coverity CID #182 size_error: Allocating 1 bytes to pointer "children" + * which needs at least 4 bytes. + * Although it's a false alarm always assume at least one child to + * be safe. + */ + size = size ? size : 1; if (self->extra->children != self->extra->_children) { + /* Coverity CID #182 size_error: Allocating 1 bytes to pointer + * "children", which needs at least 4 bytes. Although it's a + * false alarm always assume at least one child to be safe. + */ children = PyObject_Realloc(self->extra->children, size * sizeof(PyObject*)); if (!children) Modified: python/branches/py3k/Modules/_struct.c ============================================================================== --- python/branches/py3k/Modules/_struct.c (original) +++ python/branches/py3k/Modules/_struct.c Fri Jan 18 10:56:22 2008 @@ -1918,8 +1918,7 @@ static PyObject * clearcache(PyObject *self) { - if (cache != NULL) - PyDict_Clear(cache); + Py_CLEAR(cache); Py_RETURN_NONE; } Modified: python/branches/py3k/Modules/itertoolsmodule.c ============================================================================== --- python/branches/py3k/Modules/itertoolsmodule.c (original) +++ python/branches/py3k/Modules/itertoolsmodule.c Fri Jan 18 10:56:22 2008 @@ -1356,10 +1356,11 @@ if (args == NULL) return NULL; if (!PyTuple_CheckExact(args)) { + PyObject *newargs = PySequence_Tuple(args); Py_DECREF(args); - PyErr_SetString(PyExc_TypeError, - "iterator must return a tuple"); - return NULL; + if (newargs == NULL) + return NULL; + args = newargs; } result = PyObject_Call(lz->func, args, NULL); Py_DECREF(args); Modified: python/branches/py3k/Modules/main.c ============================================================================== --- python/branches/py3k/Modules/main.c (original) +++ python/branches/py3k/Modules/main.c Fri Jan 18 10:56:22 2008 @@ -533,6 +533,7 @@ if (fstat(fileno(fp), &sb) == 0 && S_ISDIR(sb.st_mode)) { fprintf(stderr, "%s: '%s' is a directory, cannot continue\n", argv[0], filename); + fclose(fp); return 1; } } Modified: python/branches/py3k/Modules/zipimport.c ============================================================================== --- python/branches/py3k/Modules/zipimport.c (original) +++ python/branches/py3k/Modules/zipimport.c Fri Jan 18 10:56:22 2008 @@ -1000,6 +1000,8 @@ { struct tm stm; + memset((void *) &stm, '\0', sizeof(stm)); + stm.tm_sec = (dostime & 0x1f) * 2; stm.tm_min = (dostime >> 5) & 0x3f; stm.tm_hour = (dostime >> 11) & 0x1f; Modified: python/branches/py3k/Parser/pgen.c ============================================================================== --- python/branches/py3k/Parser/pgen.c (original) +++ python/branches/py3k/Parser/pgen.c Fri Jan 18 10:56:22 2008 @@ -667,6 +667,7 @@ g = maketables(gr); translatelabels(g); addfirstsets(g); + PyObject_FREE(gr); return g; } Modified: python/branches/py3k/Python/traceback.c ============================================================================== --- python/branches/py3k/Python/traceback.c (original) +++ python/branches/py3k/Python/traceback.c Fri Jan 18 10:56:22 2008 @@ -135,6 +135,8 @@ FILE *xfp; char linebuf[2000]; int i; + char namebuf[MAXPATHLEN+1]; + if (filename == NULL || name == NULL) return -1; /* This is needed by Emacs' compile command */ @@ -153,7 +155,6 @@ Py_ssize_t _npath = PyList_Size(path); int npath = Py_SAFE_DOWNCAST(_npath, Py_ssize_t, int); size_t taillen = strlen(tail); - char namebuf[MAXPATHLEN+1]; for (i = 0; i < npath; i++) { PyObject *v = PyList_GetItem(path, i); if (v == NULL) { Modified: python/branches/py3k/setup.py ============================================================================== --- python/branches/py3k/setup.py (original) +++ python/branches/py3k/setup.py Fri Jan 18 10:56:22 2008 @@ -101,8 +101,14 @@ missing = self.detect_modules() # Remove modules that are present on the disabled list - self.extensions = [ext for ext in self.extensions - if ext.name not in disabled_module_list] + extensions = [ext for ext in self.extensions + if ext.name not in disabled_module_list] + # move ctypes to the end, it depends on other modules + ext_map = dict((ext.name, i) for i, ext in enumerate(extensions)) + if "_ctypes" in ext_map: + ctypes = extensions.pop(ext_map["_ctypes"]) + extensions.append(ctypes) + self.extensions = extensions # Fix up the autodetected modules, prefixing all the source files # with Modules/ and adding Python's include directory to the path. From python-3000-checkins at python.org Fri Jan 18 19:40:46 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Fri, 18 Jan 2008 19:40:46 +0100 (CET) Subject: [Python-3000-checkins] r60053 - in python/branches/py3k: Doc/builddoc.bat Doc/library/logging.rst Doc/reference/executionmodel.rst Lib/logging/__init__.py Tools/scripts/win_add2path.py Message-ID: <20080118184046.F190F1E401B@bag.python.org> Author: christian.heimes Date: Fri Jan 18 19:40:46 2008 New Revision: 60053 Added: python/branches/py3k/Doc/builddoc.bat - copied unchanged from r60052, python/trunk/Doc/builddoc.bat python/branches/py3k/Tools/scripts/win_add2path.py - copied unchanged from r60052, python/trunk/Tools/scripts/win_add2path.py Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/logging.rst python/branches/py3k/Doc/reference/executionmodel.rst python/branches/py3k/Lib/logging/__init__.py Log: Merged revisions 60043-60052 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60043 | christian.heimes | 2008-01-18 10:51:43 +0100 (Fri, 18 Jan 2008) | 2 lines Build _ctypes after the other extensions. Its build process depends on the _weakref extension (and maybe other modules, too) ........ r60048 | christian.heimes | 2008-01-18 12:58:50 +0100 (Fri, 18 Jan 2008) | 2 lines Added win_add2path.py to Tools/scripts/ Added builddoc.bat to Doc/ ........ r60049 | vinay.sajip | 2008-01-18 16:54:14 +0100 (Fri, 18 Jan 2008) | 1 line Added section on passing contextual information to logging and documentation for the LoggerAdapter class. ........ r60050 | vinay.sajip | 2008-01-18 16:55:57 +0100 (Fri, 18 Jan 2008) | 1 line Added LoggerAdapter class, changed copyright dates, made check for extra parameter passed to logging methods explicitly against None rather than a truth value. ........ r60051 | georg.brandl | 2008-01-18 17:42:57 +0100 (Fri, 18 Jan 2008) | 2 lines Note that genexps are function scopes too and therefore won't see class attributes. ........ r60052 | christian.heimes | 2008-01-18 19:24:07 +0100 (Fri, 18 Jan 2008) | 1 line Added bytes and b'' as aliases for str and '' ........ Modified: python/branches/py3k/Doc/library/logging.rst ============================================================================== --- python/branches/py3k/Doc/library/logging.rst (original) +++ python/branches/py3k/Doc/library/logging.rst Fri Jan 18 19:40:46 2008 @@ -1136,33 +1136,113 @@ be hard to manage if the number of :class:`Logger` instances becomes effectively unbounded. -There are a number of other ways you can pass contextual information to be -output along with logging event information. +An easy way in which you can pass contextual information to be output along +with logging event information is to use the :class:`LoggerAdapter` class. +This class is designed to look like a :class:`Logger`, so that you can call +:meth:`debug`, :meth:`info`, :meth:`warning`, :meth:`error`, +:meth:`exception`, :meth:`critical` and :meth:`log`. These methods have the +same signatures as their counterparts in :class:`Logger`, so you can use the +two types of instances interchangeably. + +When you create an instance of :class:`LoggerAdapter`, you pass it a +:class:`Logger` instance and a dict-like object which contains your contextual +information. When you call one of the logging methods on an instance of +:class:`LoggerAdapter`, it delegates the call to the underlying instance of +:class:`Logger` passed to its constructor, and arranges to pass the contextual +information in the delegated call. Here's a snippet from the code of +:class:`LoggerAdapter`:: + + def debug(self, msg, *args, **kwargs): + """ + Delegate a debug call to the underlying logger, after adding + contextual information from this adapter instance. + """ + msg, kwargs = self.process(msg, kwargs) + self.logger.debug(msg, *args, **kwargs) + +The :meth:`process` method of :class:`LoggerAdapter` is where the contextual +information is added to the logging output. It's passed the message and +keyword arguments of the logging call, and it passes back (potentially) +modified versions of these to use in the call to the underlying logger. The +default implementation of this method leaves the message alone, but inserts +an "extra" key in the keyword argument whose value is the dict-like object +passed to the constructor. Of course, if you had passed an "extra" keyword +argument in the call to the adapter, it will be silently overwritten. + +The advantage of using "extra" is that the values in the dict-like object are +merged into the :class:`LogRecord` instance's __dict__, allowing you to use +customized strings with your :class:`Formatter` instances which know about +the keys of the dict-like object. If you need a different method, e.g. if you +want to prepend or append the contextual information to the message string, +you just need to subclass :class:`LoggerAdapter` and override :meth:`process` +to do what you need. Here's an example script which uses this class, which +also illustrates what dict-like behaviour is needed from an arbitrary +"dict-like" object for use in the constructor:: + +import logging + +class ConnInfo: + """ + An example class which shows how an arbitrary class can be used as + the 'extra' context information repository passed to a LoggerAdapter. + """ + + def __getitem__(self, name): + """ + To allow this instance to look like a dict. + """ + from random import choice + if name == "ip": + result = choice(["127.0.0.1", "192.168.0.1"]) + elif name == "user": + result = choice(["jim", "fred", "sheila"]) + else: + result = self.__dict__.get(name, "?") + return result + + def __iter__(self): + """ + To allow iteration over keys, which will be merged into + the LogRecord dict before formatting and output. + """ + keys = ["ip", "user"] + keys.extend(self.__dict__.keys()) + return keys.__iter__() + +if __name__ == "__main__": + from random import choice + levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL) + a1 = logging.LoggerAdapter(logging.getLogger("a.b.c"), + { "ip" : "123.231.231.123", "user" : "sheila" }) + logging.basicConfig(level=logging.DEBUG, + format="%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s") + a1.debug("A debug message") + a1.info("An info message with %s", "some parameters") + a2 = logging.LoggerAdapter(logging.getLogger("d.e.f"), ConnInfo()) + for x in range(10): + lvl = choice(levels) + lvlname = logging.getLevelName(lvl) + a2.log(lvl, "A message at %s level with %d %s", lvlname, 2, "parameters") + +When this script is run, the output should look something like this:: + +2008-01-18 14:49:54,023 a.b.c DEBUG IP: 123.231.231.123 User: sheila A debug message +2008-01-18 14:49:54,023 a.b.c INFO IP: 123.231.231.123 User: sheila An info message with some parameters +2008-01-18 14:49:54,023 d.e.f CRITICAL IP: 192.168.0.1 User: jim A message at CRITICAL level with 2 parameters +2008-01-18 14:49:54,033 d.e.f INFO IP: 192.168.0.1 User: jim A message at INFO level with 2 parameters +2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: sheila A message at WARNING level with 2 parameters +2008-01-18 14:49:54,033 d.e.f ERROR IP: 127.0.0.1 User: fred A message at ERROR level with 2 parameters +2008-01-18 14:49:54,033 d.e.f ERROR IP: 127.0.0.1 User: sheila A message at ERROR level with 2 parameters +2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: sheila A message at WARNING level with 2 parameters +2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: jim A message at WARNING level with 2 parameters +2008-01-18 14:49:54,033 d.e.f INFO IP: 192.168.0.1 User: fred A message at INFO level with 2 parameters +2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: sheila A message at WARNING level with 2 parameters +2008-01-18 14:49:54,033 d.e.f WARNING IP: 127.0.0.1 User: jim A message at WARNING level with 2 parameters + +.. versionadded:: 2.6 + +The :class:`LoggerAdapter` class was not present in previous versions. -* Use an adapter class which has access to the contextual information and - which defines methods :meth:`debug`, :meth:`info` etc. with the same - signatures as used by :class:`Logger`. You instantiate the adapter with a - name, which will be used to create an underlying :class:`Logger` with that - name. In each adpater method, the passed-in message is modified to include - whatever contextual information you want. - -* Use something other than a string to pass the message. Although normally - the first argument to a logger method such as :meth:`debug`, :meth:`info` - etc. is usually a string, it can in fact be any object. This object is the - argument to a :func:`str()` call which is made, in - :meth:`LogRecord.getMessage`, to obtain the actual message string. You can - use this behavior to pass an instance which may be initialized with a - logging message, which redefines :meth:__str__ to return a modified version - of that message with the contextual information added. - -* Use a specialized :class:`Formatter` subclass to add additional information - to the formatted output. The subclass could, for instance, merge some thread - local contextual information (or contextual information obtained in some - other way) with the output generated by the base :class:`Formatter`. - -In each of these three approaches, thread locals can sometimes be a useful way -of passing contextual information without undue coupling between different -parts of your code. .. _network-logging: @@ -2047,6 +2127,33 @@ Returns the message for this :class:`LogRecord` instance after merging any user-supplied arguments with the message. +LoggerAdapter Objects +--------------------- + +.. versionadded:: 2.6 + +:class:`LoggerAdapter` instances are used to conveniently pass contextual +information into logging calls. For a usage example , see context-info_. + +.. class:: LoggerAdapter(logger, extra) + + Returns an instance of :class:`LoggerAdapter` initialized with an + underlying :class:`Logger` instance and a dict-like object. + +.. method:: LoggerAdapter.process(msg, kwargs) + + Modifies the message and/or keyword arguments passed to a logging call in + order to insert contextual information. This implementation takes the + object passed as *extra* to the constructor and adds it to *kwargs* using + key 'extra'. The return value is a (*msg*, *kwargs*) tuple which has the + (possibly modified) versions of the arguments passed in. + +In addition to the above, :class:`LoggerAdapter` supports all the logging +methods of :class:`Logger`, i.e. :meth:`debug`, :meth:`info`, :meth:`warning`, +:meth:`error`, :meth:`exception`, :meth:`critical` and :meth:`log`. These +methods have the same signatures as their counterparts in :class:`Logger`, so +you can use the two types of instances interchangeably. + Thread Safety ------------- Modified: python/branches/py3k/Doc/reference/executionmodel.rst ============================================================================== --- python/branches/py3k/Doc/reference/executionmodel.rst (original) +++ python/branches/py3k/Doc/reference/executionmodel.rst Fri Jan 18 19:40:46 2008 @@ -50,7 +50,13 @@ definition occurs in a function block, the scope extends to any blocks contained within the defining one, unless a contained block introduces a different binding for the name. The scope of names defined in a class block is limited to the -class block; it does not extend to the code blocks of methods. +class block; it does not extend to the code blocks of methods -- this includes +generator expressions since they are implemented using a function scope. This +means that the following will fail:: + + class A: + a = 42 + b = list(a + i for i in range(10)) .. index:: single: environment Modified: python/branches/py3k/Lib/logging/__init__.py ============================================================================== --- python/branches/py3k/Lib/logging/__init__.py (original) +++ python/branches/py3k/Lib/logging/__init__.py Fri Jan 18 19:40:46 2008 @@ -1,4 +1,4 @@ -# Copyright 2001-2007 by Vinay Sajip. All Rights Reserved. +# Copyright 2001-2008 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, @@ -18,7 +18,7 @@ Logging package for Python. Based on PEP 282 and comments thereto in comp.lang.python, and influenced by Apache's log4j system. -Copyright (C) 2001-2007 Vinay Sajip. All Rights Reserved. +Copyright (C) 2001-2008 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! """ @@ -38,8 +38,8 @@ __author__ = "Vinay Sajip " __status__ = "production" -__version__ = "0.5.0.3" -__date__ = "26 September 2007" +__version__ = "0.5.0.4" +__date__ = "18 January 2008" #--------------------------------------------------------------------------- # Miscellaneous module data @@ -1076,7 +1076,7 @@ specialized LogRecords. """ rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func) - if extra: + if extra is not None: for key in extra: if (key in ["message", "asctime"]) or (key in rv.__dict__): raise KeyError("Attempt to overwrite %r in LogRecord" % key) @@ -1189,6 +1189,96 @@ _loggerClass = Logger +class LoggerAdapter: + """ + An adapter for loggers which makes it easier to specify contextual + information in logging output. + """ + + def __init__(self, logger, extra): + """ + Initialize the adapter with a logger and a dict-like object which + provides contextual information. This constructor signature allows + easy stacking of LoggerAdapters, if so desired. + + You can effectively pass keyword arguments as shown in the + following example: + + adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2")) + """ + self.logger = logger + self.extra = extra + + def process(self, msg, kwargs): + """ + Process the logging message and keyword arguments passed in to + a logging call to insert contextual information. You can either + manipulate the message itself, the keyword args or both. Return + the message and kwargs modified (or not) to suit your needs. + + Normally, you'll only need to override this one method in a + LoggerAdapter subclass for your specific needs. + """ + kwargs["extra"] = self.extra + return msg, kwargs + + def debug(self, msg, *args, **kwargs): + """ + Delegate a debug call to the underlying logger, after adding + contextual information from this adapter instance. + """ + msg, kwargs = self.process(msg, kwargs) + self.logger.debug(msg, *args, **kwargs) + + def info(self, msg, *args, **kwargs): + """ + Delegate an info call to the underlying logger, after adding + contextual information from this adapter instance. + """ + msg, kwargs = self.process(msg, kwargs) + self.logger.info(msg, *args, **kwargs) + + def warning(self, msg, *args, **kwargs): + """ + Delegate a warning call to the underlying logger, after adding + contextual information from this adapter instance. + """ + msg, kwargs = self.process(msg, kwargs) + self.logger.warning(msg, *args, **kwargs) + + def error(self, msg, *args, **kwargs): + """ + Delegate an error call to the underlying logger, after adding + contextual information from this adapter instance. + """ + msg, kwargs = self.process(msg, kwargs) + self.logger.error(msg, *args, **kwargs) + + def exception(self, msg, *args, **kwargs): + """ + Delegate an exception call to the underlying logger, after adding + contextual information from this adapter instance. + """ + msg, kwargs = self.process(msg, kwargs) + kwargs["exc_info"] = 1 + self.logger.error(msg, *args, **kwargs) + + def critical(self, msg, *args, **kwargs): + """ + Delegate a critical call to the underlying logger, after adding + contextual information from this adapter instance. + """ + msg, kwargs = self.process(msg, kwargs) + self.logger.critical(msg, *args, **kwargs) + + def log(self, level, msg, *args, **kwargs): + """ + Delegate a log call to the underlying logger, after adding + contextual information from this adapter instance. + """ + msg, kwargs = self.process(msg, kwargs) + self.logger.log(level, msg, *args, **kwargs) + root = RootLogger(WARNING) Logger.root = root Logger.manager = Manager(Logger.root) From python-3000-checkins at python.org Fri Jan 18 21:06:02 2008 From: python-3000-checkins at python.org (thomas.heller) Date: Fri, 18 Jan 2008 21:06:02 +0100 (CET) Subject: [Python-3000-checkins] r60055 - python/branches/py3k-ctypes-pep3118 Message-ID: <20080118200602.CA3B41E4014@bag.python.org> Author: thomas.heller Date: Fri Jan 18 21:06:02 2008 New Revision: 60055 Added: python/branches/py3k-ctypes-pep3118/ - copied from r60054, python/branches/py3k/ Log: create branch to support pep3118 in ctypes From python-3000-checkins at python.org Fri Jan 18 22:17:05 2008 From: python-3000-checkins at python.org (thomas.heller) Date: Fri, 18 Jan 2008 22:17:05 +0100 (CET) Subject: [Python-3000-checkins] r60059 - python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c python/branches/py3k-ctypes-pep3118/Modules/_ctypes/ctypes.h python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c Message-ID: <20080118211705.AE9281E4035@bag.python.org> Author: thomas.heller Date: Fri Jan 18 22:17:05 2008 New Revision: 60059 Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c python/branches/py3k-ctypes-pep3118/Modules/_ctypes/ctypes.h python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c Log: Implement pep3118 format strings for SimpleCData types. Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c Fri Jan 18 22:17:05 2008 @@ -130,6 +130,46 @@ /******************************************************************/ /* + Allocate a memory block for a pep3118 format string, copy prefix (if + non-null) and suffix into it. Returns NULL on failure, with the error + indicator set. If called with a suffix of NULL the error indicator must + already be set. + */ +static char * +alloc_format_string(const char *prefix, const char *suffix) +{ + size_t len; + char *result; + +#if 1 +/* XXX fix later */ + if (suffix == NULL) { + if (PyErr_Occurred()) + return NULL; + /* use default format character if not set */ + suffix = "B"; + } +#else + if (suffix == NULL) { + assert(PyErr_Occurred()); + return NULL; + } +#endif + len = strlen(suffix); + if (prefix) + len += strlen(prefix); + result = PyMem_Malloc(len + 1); + if (result == NULL) + return NULL; + if (prefix) + strcpy(result, prefix); + else + result[0] = '\0'; + strcat(result, suffix); + return result; +} + +/* StructType_Type - a meta type/class. Creating a new class using this one as __metaclass__ will call the contructor StructUnionType_new. It replaces the tp_dict member with a new instance of StgDict, and initializes the C @@ -1556,6 +1596,12 @@ stgdict->size = fmt->pffi_type->size; stgdict->setfunc = fmt->setfunc; stgdict->getfunc = fmt->getfunc; + stgdict->format = alloc_format_string(NULL, proto_str); + if (stgdict->format == NULL) { + Py_DECREF(result); + Py_DECREF((PyObject *)stgdict); + return NULL; + } stgdict->paramfunc = SimpleType_paramfunc; /* @@ -1616,11 +1662,14 @@ if (type == &SimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) { PyObject *swapped = CreateSwappedType(type, args, kwds, proto, fmt); + StgDictObject *sw_dict; if (swapped == NULL) { Py_DECREF(result); return NULL; } + sw_dict = PyType_stgdict(swapped); #ifdef WORDS_BIGENDIAN + sw_dict->format = alloc_format_string("<", stgdict->format); PyObject_SetAttrString((PyObject *)result, "__ctype_le__", swapped); PyObject_SetAttrString((PyObject *)result, "__ctype_be__", (PyObject *)result); PyObject_SetAttrString(swapped, "__ctype_be__", (PyObject *)result); @@ -1631,7 +1680,12 @@ PyObject_SetAttrString(swapped, "__ctype_le__", (PyObject *)result); PyObject_SetAttrString(swapped, "__ctype_be__", swapped); #endif + sw_dict->format = alloc_format_string("<", stgdict->format); Py_DECREF(swapped); + if (PyErr_Occurred()) { + Py_DECREF(result); + return NULL; + } }; return (PyObject *)result; @@ -4167,6 +4221,42 @@ return result; } +static int Simple_GetBuffer(PyObject *_self, Py_buffer *view, int flags) +{ + CDataObject *self = (CDataObject *)_self; + StgDictObject *dict = PyObject_stgdict(_self); + + if (view == NULL) return 0; + if (((flags & PyBUF_LOCK) == PyBUF_LOCK)) { + PyErr_SetString(PyExc_BufferError, + "Cannot lock this object."); + return -1; + } + + view->buf = self->b_ptr; + view->len = self->b_size; + view->readonly = 0; + view->itemsize = self->b_size; +#if 1 + /* XXX fix later */ + /* use default format character if not set */ + view->format = dict->format ? dict->format : "B"; +#else + view->format = dict->format; +#endif + view->ndim = 0; + view->shape = NULL; + view->strides = NULL; + view->suboffsets = NULL; + view->internal = NULL; + return 0; +} + +static PyBufferProcs Simple_as_buffer = { + Simple_GetBuffer, + NULL, +}; + static PyTypeObject Simple_Type = { PyVarObject_HEAD_INIT(NULL, 0) "_ctypes._SimpleCData", @@ -4186,7 +4276,7 @@ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ - &CData_as_buffer, /* tp_as_buffer */ + &Simple_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ "XXX to be provided", /* tp_doc */ (traverseproc)CData_traverse, /* tp_traverse */ Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/ctypes.h ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_ctypes/ctypes.h (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_ctypes/ctypes.h Fri Jan 18 22:17:05 2008 @@ -200,6 +200,7 @@ PyObject *restype; /* CDataObject or NULL */ PyObject *checker; int flags; /* calling convention and such */ + char *format; /* pep3118 format string, needs PyMem_Free */ } StgDictObject; /**************************************************************** Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c Fri Jan 18 22:17:05 2008 @@ -20,6 +20,7 @@ { if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0) return -1; + self->format = NULL; return 0; } @@ -38,6 +39,7 @@ StgDict_dealloc(StgDictObject *self) { StgDict_clear(self); + PyMem_Free(self->format); PyMem_Free(self->ffi_type_pointer.elements); PyDict_Type.tp_dealloc((PyObject *)self); } From python-3000-checkins at python.org Sat Jan 19 10:24:19 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sat, 19 Jan 2008 10:24:19 +0100 (CET) Subject: [Python-3000-checkins] r60067 - python/branches/py3k/Doc/tools/sphinx-build.py Message-ID: <20080119092419.B0A131E4014@bag.python.org> Author: georg.brandl Date: Sat Jan 19 10:24:19 2008 New Revision: 60067 Modified: python/branches/py3k/Doc/tools/sphinx-build.py Log: Fix 3k's sphinx-build.py so that the version detection works with 2.x and 3.x. Modified: python/branches/py3k/Doc/tools/sphinx-build.py ============================================================================== --- python/branches/py3k/Doc/tools/sphinx-build.py (original) +++ python/branches/py3k/Doc/tools/sphinx-build.py Sat Jan 19 10:24:19 2008 @@ -12,12 +12,12 @@ if __name__ == '__main__': if sys.version_info[:3] < (2, 4, 0): - print("""\ + sys.stderr.write("""\ Error: Sphinx needs to be executed with Python 2.4 or newer (not 3.0 though). (If you run this from the Makefile, you can set the PYTHON variable to the path of an alternative interpreter executable, e.g., ``make html PYTHON=python2.5``). -""", file=sys.stderr) +""") sys.exit(1) from sphinx import main From python-3000-checkins at python.org Sat Jan 19 11:51:30 2008 From: python-3000-checkins at python.org (thomas.heller) Date: Sat, 19 Jan 2008 11:51:30 +0100 (CET) Subject: [Python-3000-checkins] r60072 - python/branches/py3k-ctypes-pep3118 Message-ID: <20080119105130.344901E4014@bag.python.org> Author: thomas.heller Date: Sat Jan 19 11:51:29 2008 New Revision: 60072 Modified: python/branches/py3k-ctypes-pep3118/ (props changed) Log: Initialized merge tracking via "svnmerge" with revisions "1-60054" from svn+ssh://pythondev at svn.python.org/python/branches/py3k From python-3000-checkins at python.org Sat Jan 19 17:21:03 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Sat, 19 Jan 2008 17:21:03 +0100 (CET) Subject: [Python-3000-checkins] r60079 - in python/branches/py3k: Doc/c-api/concrete.rst Doc/c-api/utilities.rst Doc/library/collections.rst Doc/library/curses.rst Doc/library/logging.rst Doc/library/rational.rst Lib/email/mime/multipart.py Lib/email/test/test_email.py Lib/rational.py Lib/test/crashers/weakref_in_del.py Lib/test/test_rational.py Lib/test/test_threading_local.py Modules/_sre.c Objects/complexobject.c Message-ID: <20080119162103.B46E21E4016@bag.python.org> Author: christian.heimes Date: Sat Jan 19 17:21:02 2008 New Revision: 60079 Removed: python/branches/py3k/Lib/test/crashers/weakref_in_del.py Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/c-api/concrete.rst python/branches/py3k/Doc/c-api/utilities.rst python/branches/py3k/Doc/library/collections.rst python/branches/py3k/Doc/library/curses.rst python/branches/py3k/Doc/library/logging.rst python/branches/py3k/Doc/library/rational.rst python/branches/py3k/Lib/email/mime/multipart.py python/branches/py3k/Lib/email/test/test_email.py python/branches/py3k/Lib/rational.py python/branches/py3k/Lib/test/test_rational.py python/branches/py3k/Lib/test/test_threading_local.py python/branches/py3k/Modules/_sre.c python/branches/py3k/Objects/complexobject.c Log: Merged revisions 60053-60078 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60054 | christian.heimes | 2008-01-18 20:12:56 +0100 (Fri, 18 Jan 2008) | 1 line Silence Coverity false alerts with CIDs #172, #183, #184 ........ r60057 | guido.van.rossum | 2008-01-18 21:56:30 +0100 (Fri, 18 Jan 2008) | 3 lines Fix an edge case whereby the __del__() method of a classic class could create a new weakref to the object. ........ r60058 | raymond.hettinger | 2008-01-18 22:14:58 +0100 (Fri, 18 Jan 2008) | 1 line Better variable name in an example. ........ r60063 | guido.van.rossum | 2008-01-19 00:05:40 +0100 (Sat, 19 Jan 2008) | 3 lines This got fixed for classic classes in r60057, and backported to 2.5.2 in 60056. ........ r60068 | jeffrey.yasskin | 2008-01-19 10:56:06 +0100 (Sat, 19 Jan 2008) | 4 lines Several tweaks: add construction from strings and .from_decimal(), change __init__ to __new__ to enforce immutability, and remove "rational." from repr and the parens from str. ........ r60069 | georg.brandl | 2008-01-19 11:11:27 +0100 (Sat, 19 Jan 2008) | 2 lines Fix markup. ........ r60070 | georg.brandl | 2008-01-19 11:16:09 +0100 (Sat, 19 Jan 2008) | 3 lines Amend curses docs by info how to write non-ascii characters. Thanks to Jeroen Ruigrok van der Werven. ........ r60071 | georg.brandl | 2008-01-19 11:18:07 +0100 (Sat, 19 Jan 2008) | 2 lines Indentation normalization. ........ r60073 | facundo.batista | 2008-01-19 13:32:27 +0100 (Sat, 19 Jan 2008) | 5 lines Fix issue #1822: MIMEMultipart.is_multipart() behaves correctly for a just-created (and empty) instance. Added tests for this. Thanks Jonathan Share. ........ r60074 | andrew.kuchling | 2008-01-19 14:33:20 +0100 (Sat, 19 Jan 2008) | 1 line Polish sentence ........ r60075 | christian.heimes | 2008-01-19 14:46:06 +0100 (Sat, 19 Jan 2008) | 1 line Added unit test to verify that threading.local doesn't cause ref leaks. It seems that the thread local storage always keeps the storage of the last stopped thread alive. Can anybody comment on it, please? ........ r60076 | christian.heimes | 2008-01-19 16:06:09 +0100 (Sat, 19 Jan 2008) | 1 line Update for threading.local test. ........ r60077 | andrew.kuchling | 2008-01-19 16:16:37 +0100 (Sat, 19 Jan 2008) | 1 line Polish sentence ........ r60078 | georg.brandl | 2008-01-19 16:22:16 +0100 (Sat, 19 Jan 2008) | 2 lines Fix typos. ........ Modified: python/branches/py3k/Doc/c-api/concrete.rst ============================================================================== --- python/branches/py3k/Doc/c-api/concrete.rst (original) +++ python/branches/py3k/Doc/c-api/concrete.rst Sat Jan 19 17:21:02 2008 @@ -1259,7 +1259,7 @@ .. cfunction:: PyObject* PyUnicode_AsUTF8String(PyObject *unicode) - Encode a Unicode objects using UTF-8 and return the result as Python string + Encode a Unicode object using UTF-8 and return the result as Python string object. Error handling is "strict". Return *NULL* if an exception was raised by the codec. @@ -1411,7 +1411,7 @@ .. cfunction:: PyObject* PyUnicode_AsUnicodeEscapeString(PyObject *unicode) - Encode a Unicode objects using Unicode-Escape and return the result as Python + Encode a Unicode object using Unicode-Escape and return the result as Python string object. Error handling is "strict". Return *NULL* if an exception was raised by the codec. @@ -1435,7 +1435,7 @@ .. cfunction:: PyObject* PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode) - Encode a Unicode objects using Raw-Unicode-Escape and return the result as + Encode a Unicode object using Raw-Unicode-Escape and return the result as Python string object. Error handling is "strict". Return *NULL* if an exception was raised by the codec. @@ -1459,7 +1459,7 @@ .. cfunction:: PyObject* PyUnicode_AsLatin1String(PyObject *unicode) - Encode a Unicode objects using Latin-1 and return the result as Python string + Encode a Unicode object using Latin-1 and return the result as Python string object. Error handling is "strict". Return *NULL* if an exception was raised by the codec. @@ -1483,7 +1483,7 @@ .. cfunction:: PyObject* PyUnicode_AsASCIIString(PyObject *unicode) - Encode a Unicode objects using ASCII and return the result as Python string + Encode a Unicode object using ASCII and return the result as Python string object. Error handling is "strict". Return *NULL* if an exception was raised by the codec. @@ -1532,7 +1532,7 @@ .. cfunction:: PyObject* PyUnicode_AsCharmapString(PyObject *unicode, PyObject *mapping) - Encode a Unicode objects using the given *mapping* object and return the result + Encode a Unicode object using the given *mapping* object and return the result as Python string object. Error handling is "strict". Return *NULL* if an exception was raised by the codec. @@ -1582,7 +1582,7 @@ .. cfunction:: PyObject* PyUnicode_AsMBCSString(PyObject *unicode) - Encode a Unicode objects using MBCS and return the result as Python string + Encode a Unicode object using MBCS and return the result as Python string object. Error handling is "strict". Return *NULL* if an exception was raised by the codec. Modified: python/branches/py3k/Doc/c-api/utilities.rst ============================================================================== --- python/branches/py3k/Doc/c-api/utilities.rst (original) +++ python/branches/py3k/Doc/c-api/utilities.rst Sat Jan 19 17:21:02 2008 @@ -201,12 +201,12 @@ .. cfunction:: PyObject* PyImport_ImportModuleNoBlock(const char *name) This version of :cfunc:`PyImport_ImportModule` does not block. It's intended - to be used in C function which import other modules to execute a function. + to be used in C functions that import other modules to execute a function. The import may block if another thread holds the import lock. The function - :cfunc:`PyImport_ImportModuleNoBlock` doesn't block. It first tries to fetch + :cfunc:`PyImport_ImportModuleNoBlock` never blocks. It first tries to fetch the module from sys.modules and falls back to :cfunc:`PyImport_ImportModule` - unless the the lock is hold. In the latter case the function raises an - ImportError. + unless the lock is held, in which case the function will raise an + :exc:`ImportError`. .. cfunction:: PyObject* PyImport_ImportModuleEx(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist) Modified: python/branches/py3k/Doc/library/collections.rst ============================================================================== --- python/branches/py3k/Doc/library/collections.rst (original) +++ python/branches/py3k/Doc/library/collections.rst Sat Jan 19 17:21:02 2008 @@ -579,8 +579,8 @@ customize a prototype instance:: >>> Account = namedtuple('Account', 'owner balance transaction_count') - >>> model_account = Account('', 0.0, 0) - >>> johns_account = model_account._replace(owner='John') + >>> default_account = Account('', 0.0, 0) + >>> johns_account = default_account._replace(owner='John') .. rubric:: Footnotes Modified: python/branches/py3k/Doc/library/curses.rst ============================================================================== --- python/branches/py3k/Doc/library/curses.rst (original) +++ python/branches/py3k/Doc/library/curses.rst Sat Jan 19 17:21:02 2008 @@ -16,6 +16,19 @@ designed to match the API of ncurses, an open-source curses library hosted on Linux and the BSD variants of Unix. +.. note:: + + Since version 5.4, the ncurses library decides how to interpret non-ASCII data + using the ``nl_langinfo`` function. That means that you have to call + :func:`locale.setlocale` in the application and encode Unicode strings + using one of the system's available encodings. This example uses the + system's default encoding:: + + import locale + locale.setlocale(locale.LC_ALL, '') + code = locale.getpreferredencoding() + + Then use *code* as the encoding for :meth:`str.encode` calls. .. seealso:: Modified: python/branches/py3k/Doc/library/logging.rst ============================================================================== --- python/branches/py3k/Doc/library/logging.rst (original) +++ python/branches/py3k/Doc/library/logging.rst Sat Jan 19 17:21:02 2008 @@ -1179,65 +1179,65 @@ also illustrates what dict-like behaviour is needed from an arbitrary "dict-like" object for use in the constructor:: -import logging - -class ConnInfo: - """ - An example class which shows how an arbitrary class can be used as - the 'extra' context information repository passed to a LoggerAdapter. - """ - - def __getitem__(self, name): - """ - To allow this instance to look like a dict. - """ - from random import choice - if name == "ip": - result = choice(["127.0.0.1", "192.168.0.1"]) - elif name == "user": - result = choice(["jim", "fred", "sheila"]) - else: - result = self.__dict__.get(name, "?") - return result - - def __iter__(self): - """ - To allow iteration over keys, which will be merged into - the LogRecord dict before formatting and output. - """ - keys = ["ip", "user"] - keys.extend(self.__dict__.keys()) - return keys.__iter__() - -if __name__ == "__main__": - from random import choice - levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL) - a1 = logging.LoggerAdapter(logging.getLogger("a.b.c"), - { "ip" : "123.231.231.123", "user" : "sheila" }) - logging.basicConfig(level=logging.DEBUG, - format="%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s") - a1.debug("A debug message") - a1.info("An info message with %s", "some parameters") - a2 = logging.LoggerAdapter(logging.getLogger("d.e.f"), ConnInfo()) - for x in range(10): - lvl = choice(levels) - lvlname = logging.getLevelName(lvl) - a2.log(lvl, "A message at %s level with %d %s", lvlname, 2, "parameters") + import logging + + class ConnInfo: + """ + An example class which shows how an arbitrary class can be used as + the 'extra' context information repository passed to a LoggerAdapter. + """ + + def __getitem__(self, name): + """ + To allow this instance to look like a dict. + """ + from random import choice + if name == "ip": + result = choice(["127.0.0.1", "192.168.0.1"]) + elif name == "user": + result = choice(["jim", "fred", "sheila"]) + else: + result = self.__dict__.get(name, "?") + return result + + def __iter__(self): + """ + To allow iteration over keys, which will be merged into + the LogRecord dict before formatting and output. + """ + keys = ["ip", "user"] + keys.extend(self.__dict__.keys()) + return keys.__iter__() + + if __name__ == "__main__": + from random import choice + levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL) + a1 = logging.LoggerAdapter(logging.getLogger("a.b.c"), + { "ip" : "123.231.231.123", "user" : "sheila" }) + logging.basicConfig(level=logging.DEBUG, + format="%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s") + a1.debug("A debug message") + a1.info("An info message with %s", "some parameters") + a2 = logging.LoggerAdapter(logging.getLogger("d.e.f"), ConnInfo()) + for x in range(10): + lvl = choice(levels) + lvlname = logging.getLevelName(lvl) + a2.log(lvl, "A message at %s level with %d %s", lvlname, 2, "parameters") When this script is run, the output should look something like this:: -2008-01-18 14:49:54,023 a.b.c DEBUG IP: 123.231.231.123 User: sheila A debug message -2008-01-18 14:49:54,023 a.b.c INFO IP: 123.231.231.123 User: sheila An info message with some parameters -2008-01-18 14:49:54,023 d.e.f CRITICAL IP: 192.168.0.1 User: jim A message at CRITICAL level with 2 parameters -2008-01-18 14:49:54,033 d.e.f INFO IP: 192.168.0.1 User: jim A message at INFO level with 2 parameters -2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: sheila A message at WARNING level with 2 parameters -2008-01-18 14:49:54,033 d.e.f ERROR IP: 127.0.0.1 User: fred A message at ERROR level with 2 parameters -2008-01-18 14:49:54,033 d.e.f ERROR IP: 127.0.0.1 User: sheila A message at ERROR level with 2 parameters -2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: sheila A message at WARNING level with 2 parameters -2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: jim A message at WARNING level with 2 parameters -2008-01-18 14:49:54,033 d.e.f INFO IP: 192.168.0.1 User: fred A message at INFO level with 2 parameters -2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: sheila A message at WARNING level with 2 parameters -2008-01-18 14:49:54,033 d.e.f WARNING IP: 127.0.0.1 User: jim A message at WARNING level with 2 parameters + 2008-01-18 14:49:54,023 a.b.c DEBUG IP: 123.231.231.123 User: sheila A debug message + 2008-01-18 14:49:54,023 a.b.c INFO IP: 123.231.231.123 User: sheila An info message with some parameters + 2008-01-18 14:49:54,023 d.e.f CRITICAL IP: 192.168.0.1 User: jim A message at CRITICAL level with 2 parameters + 2008-01-18 14:49:54,033 d.e.f INFO IP: 192.168.0.1 User: jim A message at INFO level with 2 parameters + 2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: sheila A message at WARNING level with 2 parameters + 2008-01-18 14:49:54,033 d.e.f ERROR IP: 127.0.0.1 User: fred A message at ERROR level with 2 parameters + 2008-01-18 14:49:54,033 d.e.f ERROR IP: 127.0.0.1 User: sheila A message at ERROR level with 2 parameters + 2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: sheila A message at WARNING level with 2 parameters + 2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: jim A message at WARNING level with 2 parameters + 2008-01-18 14:49:54,033 d.e.f INFO IP: 192.168.0.1 User: fred A message at INFO level with 2 parameters + 2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: sheila A message at WARNING level with 2 parameters + 2008-01-18 14:49:54,033 d.e.f WARNING IP: 127.0.0.1 User: jim A message at WARNING level with 2 parameters .. versionadded:: 2.6 Modified: python/branches/py3k/Doc/library/rational.rst ============================================================================== --- python/branches/py3k/Doc/library/rational.rst (original) +++ python/branches/py3k/Doc/library/rational.rst Sat Jan 19 17:21:02 2008 @@ -15,6 +15,7 @@ .. class:: Rational(numerator=0, denominator=1) Rational(other_rational) + Rational(string) The first version requires that *numerator* and *denominator* are instances of :class:`numbers.Integral` and returns a new @@ -22,10 +23,12 @@ *denominator* is :const:`0`, raises a :exc:`ZeroDivisionError`. The second version requires that *other_rational* is an instance of :class:`numbers.Rational` and returns an instance of - :class:`Rational` with the same value. + :class:`Rational` with the same value. The third version expects a + string of the form ``[-+]?[0-9]+(/[0-9]+)?``, optionally surrounded + by spaces. Implements all of the methods and operations from - :class:`numbers.Rational` and is hashable. + :class:`numbers.Rational` and is immutable and hashable. .. method:: Rational.from_float(flt) @@ -36,6 +39,13 @@ 10)`` +.. method:: Rational.from_decimal(dec) + + This classmethod constructs a :class:`Rational` representing the + exact value of *dec*, which must be a + :class:`decimal.Decimal`. + + .. method:: Rational.__floor__() Returns the greatest :class:`int` ``<= self``. Will be accessible Modified: python/branches/py3k/Lib/email/mime/multipart.py ============================================================================== --- python/branches/py3k/Lib/email/mime/multipart.py (original) +++ python/branches/py3k/Lib/email/mime/multipart.py Sat Jan 19 17:21:02 2008 @@ -34,6 +34,12 @@ keyword arguments (or passed into the _params argument). """ MIMEBase.__init__(self, 'multipart', _subtype, **_params) + + # Initialise _payload to an empty list as the Message superclass's + # implementation of is_multipart assumes that _payload is a list for + # multipart messages. + self._payload = [] + if _subparts: for p in _subparts: self.attach(p) Modified: python/branches/py3k/Lib/email/test/test_email.py ============================================================================== --- python/branches/py3k/Lib/email/test/test_email.py (original) +++ python/branches/py3k/Lib/email/test/test_email.py Sat Jan 19 17:21:02 2008 @@ -1892,6 +1892,9 @@ eq(msg.get_payload(0), text1) eq(msg.get_payload(1), text2) + def test_default_multipart_constructor(self): + msg = MIMEMultipart() + self.assertTrue(msg.is_multipart()) # A general test of parser->model->generator idempotency. IOW, read a message Modified: python/branches/py3k/Lib/rational.py ============================================================================== --- python/branches/py3k/Lib/rational.py (original) +++ python/branches/py3k/Lib/rational.py Sat Jan 19 17:21:02 2008 @@ -6,6 +6,7 @@ import math import numbers import operator +import re __all__ = ["Rational"] @@ -75,6 +76,10 @@ return (top, 2 ** -e) +_RATIONAL_FORMAT = re.compile( + r'^\s*(?P[-+]?)(?P\d+)(?:/(?P\d+))?\s*$') + + class Rational(RationalAbc): """This class implements rational numbers. @@ -83,18 +88,41 @@ and the denominator defaults to 1 so that Rational(3) == 3 and Rational() == 0. + Rationals can also be constructed from strings of the form + '[-+]?[0-9]+(/[0-9]+)?', optionally surrounded by spaces. + """ __slots__ = ('_numerator', '_denominator') - def __init__(self, numerator=0, denominator=1): - if (not isinstance(numerator, numbers.Integral) and - isinstance(numerator, RationalAbc) and - denominator == 1): - # Handle copies from other rationals. - other_rational = numerator - numerator = other_rational.numerator - denominator = other_rational.denominator + # We're immutable, so use __new__ not __init__ + def __new__(cls, numerator=0, denominator=1): + """Constructs a Rational. + + Takes a string, another Rational, or a numerator/denominator pair. + + """ + self = super(Rational, cls).__new__(cls) + + if denominator == 1: + if isinstance(numerator, str): + # Handle construction from strings. + input = numerator + m = _RATIONAL_FORMAT.match(input) + if m is None: + raise ValueError('Invalid literal for Rational: ' + input) + numerator = int(m.group('num')) + # Default denominator to 1. That's the only optional group. + denominator = int(m.group('denom') or 1) + if m.group('sign') == '-': + numerator = -numerator + + elif (not isinstance(numerator, numbers.Integral) and + isinstance(numerator, RationalAbc)): + # Handle copies from other rationals. + other_rational = numerator + numerator = other_rational.numerator + denominator = other_rational.denominator if (not isinstance(numerator, numbers.Integral) or not isinstance(denominator, numbers.Integral)): @@ -107,10 +135,15 @@ g = _gcd(numerator, denominator) self._numerator = int(numerator // g) self._denominator = int(denominator // g) + return self @classmethod def from_float(cls, f): - """Converts a float to a rational number, exactly.""" + """Converts a finite float to a rational number, exactly. + + Beware that Rational.from_float(0.3) != Rational(3, 10). + + """ if not isinstance(f, float): raise TypeError("%s.from_float() only takes floats, not %r (%s)" % (cls.__name__, f, type(f).__name__)) @@ -118,6 +151,26 @@ raise TypeError("Cannot convert %r to %s." % (f, cls.__name__)) return cls(*_binary_float_to_ratio(f)) + @classmethod + def from_decimal(cls, dec): + """Converts a finite Decimal instance to a rational number, exactly.""" + from decimal import Decimal + if not isinstance(dec, Decimal): + raise TypeError( + "%s.from_decimal() only takes Decimals, not %r (%s)" % + (cls.__name__, dec, type(dec).__name__)) + if not dec.is_finite(): + # Catches infinities and nans. + raise TypeError("Cannot convert %s to %s." % (dec, cls.__name__)) + sign, digits, exp = dec.as_tuple() + digits = int(''.join(map(str, digits))) + if sign: + digits = -digits + if exp >= 0: + return cls(digits * 10 ** exp) + else: + return cls(digits, 10 ** -exp) + @property def numerator(a): return a._numerator @@ -128,15 +181,14 @@ def __repr__(self): """repr(self)""" - return ('rational.Rational(%r,%r)' % - (self.numerator, self.denominator)) + return ('Rational(%r,%r)' % (self.numerator, self.denominator)) def __str__(self): """str(self)""" if self.denominator == 1: return str(self.numerator) else: - return '(%s/%s)' % (self.numerator, self.denominator) + return '%s/%s' % (self.numerator, self.denominator) def _operator_fallbacks(monomorphic_operator, fallback_operator): """Generates forward and reverse operators given a purely-rational Deleted: /python/branches/py3k/Lib/test/crashers/weakref_in_del.py ============================================================================== --- /python/branches/py3k/Lib/test/crashers/weakref_in_del.py Sat Jan 19 17:21:02 2008 +++ (empty file) @@ -1,17 +0,0 @@ -import weakref - -# http://python.org/sf/1377858 -# Fixed for new-style classes in 2.5c1. - -ref = None - -def test_weakref_in_del(): - class Target(): - def __del__(self): - global ref - ref = weakref.ref(self) - - w = Target() - -if __name__ == '__main__': - test_weakref_in_del() Modified: python/branches/py3k/Lib/test/test_rational.py ============================================================================== --- python/branches/py3k/Lib/test/test_rational.py (original) +++ python/branches/py3k/Lib/test/test_rational.py Sat Jan 19 17:21:02 2008 @@ -45,6 +45,44 @@ self.assertRaises(TypeError, R, 1.5) self.assertRaises(TypeError, R, 1.5 + 3j) + self.assertRaises(TypeError, R, R(1, 2), 3) + self.assertRaises(TypeError, R, "3/2", 3) + + def testFromString(self): + self.assertEquals((5, 1), _components(R("5"))) + self.assertEquals((3, 2), _components(R("3/2"))) + self.assertEquals((3, 2), _components(R(" \n +3/2"))) + self.assertEquals((-3, 2), _components(R("-3/2 "))) + self.assertEquals((3, 2), _components(R(" 03/02 \n "))) + self.assertEquals((3, 2), _components(R(" 03/02 \n "))) + + self.assertRaisesMessage( + ZeroDivisionError, "Rational(3, 0)", + R, "3/0") + self.assertRaisesMessage( + ValueError, "Invalid literal for Rational: 3/", + R, "3/") + self.assertRaisesMessage( + ValueError, "Invalid literal for Rational: 3 /2", + R, "3 /2") + self.assertRaisesMessage( + # Denominators don't need a sign. + ValueError, "Invalid literal for Rational: 3/+2", + R, "3/+2") + self.assertRaisesMessage( + # Imitate float's parsing. + ValueError, "Invalid literal for Rational: + 3/2", + R, "+ 3/2") + self.assertRaisesMessage( + # Only parse fractions, not decimals. + ValueError, "Invalid literal for Rational: 3.2", + R, "3.2") + + def testImmutable(self): + r = R(7, 3) + r.__init__(2, 15) + self.assertEquals((7, 3), _components(r)) + def testFromFloat(self): self.assertRaisesMessage( TypeError, "Rational.from_float() only takes floats, not 3 (int)", @@ -72,6 +110,31 @@ TypeError, "Cannot convert nan to Rational.", R.from_float, nan) + def testFromDecimal(self): + self.assertRaisesMessage( + TypeError, + "Rational.from_decimal() only takes Decimals, not 3 (int)", + R.from_decimal, 3) + self.assertEquals(R(0), R.from_decimal(Decimal("-0"))) + self.assertEquals(R(5, 10), R.from_decimal(Decimal("0.5"))) + self.assertEquals(R(5, 1000), R.from_decimal(Decimal("5e-3"))) + self.assertEquals(R(5000), R.from_decimal(Decimal("5e3"))) + self.assertEquals(1 - R(1, 10**30), + R.from_decimal(Decimal("0." + "9" * 30))) + + self.assertRaisesMessage( + TypeError, "Cannot convert Infinity to Rational.", + R.from_decimal, Decimal("inf")) + self.assertRaisesMessage( + TypeError, "Cannot convert -Infinity to Rational.", + R.from_decimal, Decimal("-inf")) + self.assertRaisesMessage( + TypeError, "Cannot convert NaN to Rational.", + R.from_decimal, Decimal("nan")) + self.assertRaisesMessage( + TypeError, "Cannot convert sNaN to Rational.", + R.from_decimal, Decimal("snan")) + def testConversions(self): self.assertTypedEquals(-1, trunc(R(-11, 10))) self.assertTypedEquals(-2, math.floor(R(-11, 10))) @@ -175,7 +238,7 @@ self.assertTypedEquals(1.0 + 0j, (1.0 + 0j) ** R(1, 10)) def testMixingWithDecimal(self): - """Decimal refuses mixed comparisons.""" + # Decimal refuses mixed comparisons. self.assertRaisesMessage( TypeError, "unsupported operand type(s) for +: 'Rational' and 'Decimal'", @@ -238,8 +301,8 @@ self.assertFalse(R(5, 2) == 2) def testStringification(self): - self.assertEquals("rational.Rational(7,3)", repr(R(7, 3))) - self.assertEquals("(7/3)", str(R(7, 3))) + self.assertEquals("Rational(7,3)", repr(R(7, 3))) + self.assertEquals("7/3", str(R(7, 3))) self.assertEquals("7", str(R(7, 1))) def testHash(self): Modified: python/branches/py3k/Lib/test/test_threading_local.py ============================================================================== --- python/branches/py3k/Lib/test/test_threading_local.py (original) +++ python/branches/py3k/Lib/test/test_threading_local.py Sat Jan 19 17:21:02 2008 @@ -1,9 +1,51 @@ import unittest from doctest import DocTestSuite from test import test_support +import threading +import weakref +import gc + +class Weak(object): + pass + +def target(local, weaklist): + weak = Weak() + local.weak = weak + weaklist.append(weakref.ref(weak)) + +class ThreadingLocalTest(unittest.TestCase): + + def test_local_refs(self): + self._local_refs(20) + self._local_refs(50) + self._local_refs(100) + + def _local_refs(self, n): + local = threading.local() + weaklist = [] + for i in range(n): + t = threading.Thread(target=target, args=(local, weaklist)) + t.start() + t.join() + del t + + gc.collect() + self.assertEqual(len(weaklist), n) + + # XXX threading.local keeps the local of the last stopped thread alive. + deadlist = [weak for weak in weaklist if weak() is None] + self.assertEqual(len(deadlist), n-1) + + # Assignment to the same thread local frees it sometimes (!) + local.someothervar = None + gc.collect() + deadlist = [weak for weak in weaklist if weak() is None] + self.assert_(len(deadlist) in (n-1, n), (n, len(deadlist))) def test_main(): - suite = DocTestSuite('_threading_local') + suite = unittest.TestSuite() + suite.addTest(DocTestSuite('_threading_local')) + suite.addTest(unittest.makeSuite(ThreadingLocalTest)) try: from thread import _local Modified: python/branches/py3k/Modules/_sre.c ============================================================================== --- python/branches/py3k/Modules/_sre.c (original) +++ python/branches/py3k/Modules/_sre.c Sat Jan 19 17:21:02 2008 @@ -2677,7 +2677,7 @@ return NULL; n = PyList_GET_SIZE(code); - + /* coverity[ampersand_in_size] */ self = PyObject_NEW_VAR(PatternObject, &Pattern_Type, n); if (!self) return NULL; @@ -3187,6 +3187,7 @@ if (status > 0) { /* create match object (with room for extra group marks) */ + /* coverity[ampersand_in_size] */ match = PyObject_NEW_VAR(MatchObject, &Match_Type, 2*(pattern->groups+1)); if (!match) Modified: python/branches/py3k/Objects/complexobject.c ============================================================================== --- python/branches/py3k/Objects/complexobject.c (original) +++ python/branches/py3k/Objects/complexobject.c Sat Jan 19 17:21:02 2008 @@ -375,24 +375,24 @@ static int to_complex(PyObject **pobj, Py_complex *pc) { - PyObject *obj = *pobj; + PyObject *obj = *pobj; - pc->real = pc->imag = 0.0; - if (PyLong_Check(obj)) { - pc->real = PyLong_AsDouble(obj); - if (pc->real == -1.0 && PyErr_Occurred()) { - *pobj = NULL; - return -1; - } - return 0; - } - if (PyFloat_Check(obj)) { - pc->real = PyFloat_AsDouble(obj); - return 0; - } - Py_INCREF(Py_NotImplemented); - *pobj = Py_NotImplemented; - return -1; + pc->real = pc->imag = 0.0; + if (PyLong_Check(obj)) { + pc->real = PyLong_AsDouble(obj); + if (pc->real == -1.0 && PyErr_Occurred()) { + *pobj = NULL; + return -1; + } + return 0; + } + if (PyFloat_Check(obj)) { + pc->real = PyFloat_AsDouble(obj); + return 0; + } + Py_INCREF(Py_NotImplemented); + *pobj = Py_NotImplemented; + return -1; } @@ -401,8 +401,8 @@ { Py_complex result; Py_complex a, b; - TO_COMPLEX(v, a); - TO_COMPLEX(w, b); + TO_COMPLEX(v, a); + TO_COMPLEX(w, b); PyFPE_START_PROTECT("complex_add", return 0) result = c_sum(a, b); PyFPE_END_PROTECT(result) @@ -414,8 +414,8 @@ { Py_complex result; Py_complex a, b; - TO_COMPLEX(v, a); - TO_COMPLEX(w, b); + TO_COMPLEX(v, a); + TO_COMPLEX(w, b); PyFPE_START_PROTECT("complex_sub", return 0) result = c_diff(a, b); PyFPE_END_PROTECT(result) @@ -427,8 +427,8 @@ { Py_complex result; Py_complex a, b; - TO_COMPLEX(v, a); - TO_COMPLEX(w, b); + TO_COMPLEX(v, a); + TO_COMPLEX(w, b); PyFPE_START_PROTECT("complex_mul", return 0) result = c_prod(a, b); PyFPE_END_PROTECT(result) @@ -440,8 +440,8 @@ { Py_complex quot; Py_complex a, b; - TO_COMPLEX(v, a); - TO_COMPLEX(w, b); + TO_COMPLEX(v, a); + TO_COMPLEX(w, b); PyFPE_START_PROTECT("complex_div", return 0) errno = 0; quot = c_quot(a, b); @@ -477,8 +477,8 @@ Py_complex exponent; long int_exponent; Py_complex a, b; - TO_COMPLEX(v, a); - TO_COMPLEX(w, b); + TO_COMPLEX(v, a); + TO_COMPLEX(w, b); if (z != Py_None) { PyErr_SetString(PyExc_ValueError, "complex modulo"); @@ -557,8 +557,8 @@ { PyObject *res; Py_complex i, j; - TO_COMPLEX(v, i); - TO_COMPLEX(w, j); + TO_COMPLEX(v, i); + TO_COMPLEX(w, j); if (op != Py_EQ && op != Py_NE) { /* XXX Should eventually return NotImplemented */ @@ -673,11 +673,11 @@ start = s; while (*s && isspace(Py_CHARMASK(*s))) s++; - if (s[0] == '\0') { + if (s[0] == '\0') { PyErr_SetString(PyExc_ValueError, "complex() arg is an empty string"); return NULL; - } + } if (s[0] == '(') { /* Skip over possible bracket from repr(). */ got_bracket = 1; @@ -837,7 +837,7 @@ "complex() can't take second arg" " if first is a string"); return NULL; - } + } return complex_subtype_from_string(type, r); } if (i != NULL && PyUnicode_Check(i)) { @@ -915,7 +915,7 @@ return NULL; } cr.real = PyFloat_AsDouble(tmp); - cr.imag = 0.0; /* Shut up compiler warning */ + cr.imag = 0.0; /* Shut up compiler warning */ Py_DECREF(tmp); } if (i == NULL) { From python-3000-checkins at python.org Sat Jan 19 20:12:02 2008 From: python-3000-checkins at python.org (facundo.batista) Date: Sat, 19 Jan 2008 20:12:02 +0100 (CET) Subject: [Python-3000-checkins] r60090 - in python/branches/py3k: Lib/test/test_builtin.py Misc/NEWS Objects/longobject.c Message-ID: <20080119191202.0F0C81E401A@bag.python.org> Author: facundo.batista Date: Sat Jan 19 20:12:01 2008 New Revision: 60090 Modified: python/branches/py3k/Lib/test/test_builtin.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/longobject.c Log: Fix Issue #1769: Now int('- 1') or int('+ 1') is not allowed any more. Thanks Juan Jose Conti. Also added tests. Modified: python/branches/py3k/Lib/test/test_builtin.py ============================================================================== --- python/branches/py3k/Lib/test/test_builtin.py (original) +++ python/branches/py3k/Lib/test/test_builtin.py Sat Jan 19 20:12:01 2008 @@ -49,7 +49,7 @@ def write(self, line): pass -L = [ +test_conv_no_sign = [ ('0', 0), ('1', 1), ('9', 9), @@ -71,6 +71,28 @@ (chr(0x200), ValueError), ] +test_conv_sign = [ + ('0', 0), + ('1', 1), + ('9', 9), + ('10', 10), + ('99', 99), + ('100', 100), + ('314', 314), + (' 314', ValueError), + ('314 ', 314), + (' \t\t 314 \t\t ', ValueError), + (repr(sys.maxsize), sys.maxsize), + (' 1x', ValueError), + (' 1 ', ValueError), + (' 1\02 ', ValueError), + ('', ValueError), + (' ', ValueError), + (' \t\t ', ValueError), + (str(b'\u0663\u0661\u0664 ','raw-unicode-escape'), 314), + (chr(0x200), ValueError), +] + class TestFailingBool: def __bool__(self): raise RuntimeError @@ -641,8 +663,18 @@ # Different base: self.assertEqual(int("10",16), 16) # Test conversion from strings and various anomalies - for s, v in L: - for sign in "", "+", "-": + # Testing with no sign at front + for s, v in test_conv_no_sign: + for prefix in "", " ", "\t", " \t\t ": + ss = prefix + s + vv = v + try: + self.assertEqual(int(ss), vv) + except v: + pass + # No whitespaces allowed between + or - sign and the number + for s, v in test_conv_sign: + for sign in "+", "-": for prefix in "", " ", "\t", " \t\t ": ss = prefix + sign + s vv = v Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Jan 19 20:12:01 2008 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #1769: Now int("- 1") is not allowed any more. + - Object/longobject.c: long(float('nan')) raises an OverflowError instead of returning 0. Modified: python/branches/py3k/Objects/longobject.c ============================================================================== --- python/branches/py3k/Objects/longobject.c (original) +++ python/branches/py3k/Objects/longobject.c Sat Jan 19 20:12:01 2008 @@ -1685,8 +1685,6 @@ ++str; sign = -1; } - while (*str != '\0' && isspace(Py_CHARMASK(*str))) - str++; if (base == 0) { if (str[0] != '0') base = 10; From python-3000-checkins at python.org Sat Jan 19 21:08:24 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sat, 19 Jan 2008 21:08:24 +0100 (CET) Subject: [Python-3000-checkins] r60094 - in python/branches/py3k: Doc/library/mmap.rst Doc/library/socketserver.rst Doc/library/threading.rst Doc/library/trace.rst Doc/whatsnew/2.6.rst Lib/SocketServer.py Lib/test/test_builtin.py Lib/test/test_grammar.py Lib/test/test_mmap.py Lib/test/test_socket.py Lib/test/test_ssl.py Lib/test/test_textwrap.py Lib/test/test_xmlrpc.py Lib/textwrap.py Lib/tokenize.py Lib/trace.py Misc/ACKS Modules/mmapmodule.c Parser/tokenizer.c Python/modsupport.c Python/mystrtoul.c Message-ID: <20080119200824.4C1DC1E401A@bag.python.org> Author: georg.brandl Date: Sat Jan 19 21:08:23 2008 New Revision: 60094 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/mmap.rst python/branches/py3k/Doc/library/socketserver.rst python/branches/py3k/Doc/library/threading.rst python/branches/py3k/Doc/library/trace.rst python/branches/py3k/Doc/whatsnew/2.6.rst python/branches/py3k/Lib/SocketServer.py python/branches/py3k/Lib/test/test_builtin.py python/branches/py3k/Lib/test/test_grammar.py python/branches/py3k/Lib/test/test_mmap.py python/branches/py3k/Lib/test/test_socket.py python/branches/py3k/Lib/test/test_ssl.py python/branches/py3k/Lib/test/test_textwrap.py python/branches/py3k/Lib/test/test_xmlrpc.py python/branches/py3k/Lib/textwrap.py python/branches/py3k/Lib/tokenize.py python/branches/py3k/Lib/trace.py python/branches/py3k/Misc/ACKS python/branches/py3k/Modules/mmapmodule.c python/branches/py3k/Parser/tokenizer.c python/branches/py3k/Python/modsupport.c python/branches/py3k/Python/mystrtoul.c Log: Merged revisions 60080-60089,60091-60093 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60080 | andrew.kuchling | 2008-01-19 17:26:13 +0100 (Sat, 19 Jan 2008) | 2 lines Patch #742598 from Michael Pomraning: add .timeout attribute to SocketServer that will call .handle_timeout() method when no requests are received within the timeout period. ........ r60081 | andrew.kuchling | 2008-01-19 17:34:09 +0100 (Sat, 19 Jan 2008) | 1 line Add item ........ r60082 | christian.heimes | 2008-01-19 17:39:27 +0100 (Sat, 19 Jan 2008) | 2 lines Disabled test_xmlrpc:test_404. It's causing lots of false alarms. I also disabled a test in test_ssl which requires network access to svn.python.org. This fixes a bug Skip has reported a while ago. ........ r60083 | georg.brandl | 2008-01-19 18:38:53 +0100 (Sat, 19 Jan 2008) | 2 lines Clarify thread.join() docs. #1873. ........ r60084 | georg.brandl | 2008-01-19 19:02:46 +0100 (Sat, 19 Jan 2008) | 2 lines #1782: don't leak in error case in PyModule_AddXxxConstant. Patch by Hrvoje Nik?\197?\161i?\196?\135. ........ r60085 | andrew.kuchling | 2008-01-19 19:08:52 +0100 (Sat, 19 Jan 2008) | 1 line Sort two names into position ........ r60086 | andrew.kuchling | 2008-01-19 19:18:41 +0100 (Sat, 19 Jan 2008) | 2 lines Patch #976880: add mmap .rfind() method, and 'end' paramter to .find(). Contributed by John Lenton. ........ r60087 | facundo.batista | 2008-01-19 19:38:19 +0100 (Sat, 19 Jan 2008) | 5 lines Fix #1693149. Now you can pass several modules separated by coma to trace.py in the same --ignore-module option. Thanks Raghuram Devarakonda. ........ r60088 | facundo.batista | 2008-01-19 19:45:46 +0100 (Sat, 19 Jan 2008) | 3 lines Comment in NEWS regarding the change in trace.py. ........ r60089 | skip.montanaro | 2008-01-19 19:47:24 +0100 (Sat, 19 Jan 2008) | 2 lines missing from r60088 checkin. ........ r60091 | andrew.kuchling | 2008-01-19 20:14:05 +0100 (Sat, 19 Jan 2008) | 1 line Add item ........ r60092 | georg.brandl | 2008-01-19 20:27:05 +0100 (Sat, 19 Jan 2008) | 4 lines Fix #1679: "0x" was taken as a valid integer literal. Fixes the tokenizer, tokenize.py and int() to reject this. Patches by Malte Helmert. ........ r60093 | georg.brandl | 2008-01-19 20:48:19 +0100 (Sat, 19 Jan 2008) | 3 lines Fix #1146: TextWrap vs words 1-character shorter than the width. Patch by Quentin Gallet-Gilles. ........ Modified: python/branches/py3k/Doc/library/mmap.rst ============================================================================== --- python/branches/py3k/Doc/library/mmap.rst (original) +++ python/branches/py3k/Doc/library/mmap.rst Sat Jan 19 21:08:23 2008 @@ -137,11 +137,12 @@ an exception being raised. -.. method:: mmap.find(string[, start]) +.. method:: mmap.find(string[, start[, end]]) - Returns the lowest index in the object where the substring *string* is found. - Returns ``-1`` on failure. *start* is the index at which the search begins, and - defaults to zero. + Returns the lowest index in the object where the substring *string* is found, + such that *string* is contained in the range [*start*, *end*]. Optional + arguments *start* and *end* are interpreted as in slice notation. + Returns ``-1`` on failure. .. method:: mmap.flush([offset, size]) @@ -186,6 +187,14 @@ :exc:`TypeError` exception. +.. method:: mmap.rfind(string[, start[, end]]) + + Returns the highest index in the object where the substring *string* is + found, such that *string* is contained in the range [*start*, + *end*]. Optional arguments *start* and *end* are interpreted as in slice + notation. Returns ``-1`` on failure. + + .. method:: mmap.seek(pos[, whence]) Set the file's current position. *whence* argument is optional and defaults to Modified: python/branches/py3k/Doc/library/socketserver.rst ============================================================================== --- python/branches/py3k/Doc/library/socketserver.rst (original) +++ python/branches/py3k/Doc/library/socketserver.rst Sat Jan 19 21:08:23 2008 @@ -44,7 +44,7 @@ not exit until all threads created by :class:`ThreadingMixIn` have exited. Server classes have the same external methods and attributes, no matter what -network protocol they use: +network protocol they use. Server Creation Notes @@ -193,6 +193,13 @@ The type of socket used by the server; :const:`socket.SOCK_STREAM` and :const:`socket.SOCK_DGRAM` are two possible values. +.. data:: timeout + + Timeout duration, measured in seconds, or :const:`None` if no timeout is desired. + If no incoming requests are received within the timeout period, + the :meth:`handle_timeout` method is called and then the server resumes waiting for + requests. + There are various server methods that can be overridden by subclasses of base server classes like :class:`TCPServer`; these methods aren't useful to external users of the server object. @@ -220,6 +227,13 @@ method raises an exception. The default action is to print the traceback to standard output and continue handling further requests. +.. function:: handle_timeout() + + This function is called when the :attr:`timeout` attribute has been set to a + value other than :const:`None` and the timeout period has passed with no + requests being received. The default action for forking servers is + to collect the status of any child processes that have exited, while + in threading servers this method does nothing. .. function:: process_request(request, client_address) Modified: python/branches/py3k/Doc/library/threading.rst ============================================================================== --- python/branches/py3k/Doc/library/threading.rst (original) +++ python/branches/py3k/Doc/library/threading.rst Sat Jan 19 21:08:23 2008 @@ -615,18 +615,19 @@ When the *timeout* argument is present and not ``None``, it should be a floating point number specifying a timeout for the operation in seconds (or fractions - thereof). As :meth:`join` always returns ``None``, you must call - :meth:`isAlive` to decide whether a timeout happened. + thereof). As :meth:`join` always returns ``None``, you must call :meth:`isAlive` + after :meth:`join` to decide whether a timeout happened -- if the thread is + still alive, the :meth:`join` call timed out. When the *timeout* argument is not present or ``None``, the operation will block until the thread terminates. A thread can be :meth:`join`\ ed many times. - :meth:`join` may throw a :exc:`RuntimeError`, if an attempt is made to join the - current thread as that would cause a deadlock. It is also an error to - :meth:`join` a thread before it has been started and attempts to do so raises - same exception. + :meth:`join` raises a :exc:`RuntimeError` if an attempt is made to join + the current thread as that would cause a deadlock. It is also an error to + :meth:`join` a thread before it has been started and attempts to do so + raises the same exception. .. method:: Thread.getName() Modified: python/branches/py3k/Doc/library/trace.rst ============================================================================== --- python/branches/py3k/Doc/library/trace.rst (original) +++ python/branches/py3k/Doc/library/trace.rst Sat Jan 19 21:08:23 2008 @@ -64,12 +64,14 @@ stdout for each file processed. :option:`--ignore-module` - Ignore the named module and its submodules (if it is a package). May be given + Accepts comma separated list of module names. Ignore each of the named + module and its submodules (if it is a package). May be given multiple times. :option:`--ignore-dir` - Ignore all modules and packages in the named directory and subdirectories. May - be given multiple times. + Ignore all modules and packages in the named directory and subdirectories + (multiple directories can be joined by os.pathsep). May be given multiple + times. .. _trace-api: Modified: python/branches/py3k/Doc/whatsnew/2.6.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/2.6.rst (original) +++ python/branches/py3k/Doc/whatsnew/2.6.rst Sat Jan 19 21:08:23 2008 @@ -960,6 +960,13 @@ .. Patch #1490190 +* :class:`mmap` objects now have a :meth:`rfind` method that finds + a substring, beginning at the end of the string and searching + backwards. The :meth:`find` method + also gained a *end* parameter containing the index at which to stop + the forward search. + (Contributed by John Lenton.) + * The :mod:`new` module has been removed from Python 3.0. Importing it therefore triggers a warning message when Python is running in 3.0-warning @@ -1102,6 +1109,13 @@ (Contributed by Alberto Bertogli.) .. Patch #1646 + +* The base classes in the :mod:`SocketServer` module now support + calling a :meth:`handle_timeout` method after a span of inactivity + specified by the server's :attr:`timeout` attribute. (Contributed + by Michael Pomraning.) + + .. Patch #742598 * A new variable in the :mod:`sys` module, :attr:`float_info`, is an object Modified: python/branches/py3k/Lib/SocketServer.py ============================================================================== --- python/branches/py3k/Lib/SocketServer.py (original) +++ python/branches/py3k/Lib/SocketServer.py Sat Jan 19 21:08:23 2008 @@ -158,6 +158,7 @@ - server_bind() - server_activate() - get_request() -> request, client_address + - handle_timeout() - verify_request(request, client_address) - server_close() - process_request(request, client_address) @@ -171,6 +172,7 @@ Class variables that may be overridden by derived classes or instances: + - timeout - address_family - socket_type - allow_reuse_address @@ -182,6 +184,8 @@ """ + timeout = None + def __init__(self, server_address, RequestHandlerClass): """Constructor. May be extended, do not override.""" self.server_address = server_address @@ -204,8 +208,9 @@ # finishing a request is fairly arbitrary. Remember: # # - handle_request() is the top-level call. It calls - # get_request(), verify_request() and process_request() - # - get_request() is different for stream or datagram sockets + # await_request(), verify_request() and process_request() + # - get_request(), called by await_request(), is different for + # stream or datagram sockets # - process_request() is the place that may fork a new process # or create a new thread to finish the request # - finish_request() instantiates the request handler class; @@ -214,7 +219,7 @@ def handle_request(self): """Handle one request, possibly blocking.""" try: - request, client_address = self.get_request() + request, client_address = self.await_request() except socket.error: return if self.verify_request(request, client_address): @@ -224,6 +229,28 @@ self.handle_error(request, client_address) self.close_request(request) + def await_request(self): + """Call get_request or handle_timeout, observing self.timeout. + + Returns value from get_request() or raises socket.timeout exception if + timeout was exceeded. + """ + if self.timeout is not None: + # If timeout == 0, you're responsible for your own fd magic. + import select + fd_sets = select.select([self], [], [], self.timeout) + if not fd_sets[0]: + self.handle_timeout() + raise socket.timeout("Listening timed out") + return self.get_request() + + def handle_timeout(self): + """Called if no new request arrives within self.timeout. + + Overridden by ForkingMixIn. + """ + pass + def verify_request(self, request, client_address): """Verify the request. May be overridden. @@ -289,6 +316,7 @@ - server_bind() - server_activate() - get_request() -> request, client_address + - handle_timeout() - verify_request(request, client_address) - process_request(request, client_address) - close_request(request) @@ -301,6 +329,7 @@ Class variables that may be overridden by derived classes or instances: + - timeout - address_family - socket_type - request_queue_size (only for stream sockets) @@ -405,11 +434,12 @@ """Mix-in class to handle each request in a new process.""" + timeout = 300 active_children = None max_children = 40 def collect_children(self): - """Internal routine to wait for died children.""" + """Internal routine to wait for children that have exited.""" while self.active_children: if len(self.active_children) < self.max_children: options = os.WNOHANG @@ -424,6 +454,13 @@ if not pid: break self.active_children.remove(pid) + def handle_timeout(self): + """Wait for zombies after self.timeout seconds of inactivity. + + May be extended, do not override. + """ + self.collect_children() + def process_request(self, request, client_address): """Fork a new subprocess to process the request.""" self.collect_children() Modified: python/branches/py3k/Lib/test/test_builtin.py ============================================================================== --- python/branches/py3k/Lib/test/test_builtin.py (original) +++ python/branches/py3k/Lib/test/test_builtin.py Sat Jan 19 21:08:23 2008 @@ -743,6 +743,11 @@ self.assertEqual(int('0O123', 8), 83) self.assertEqual(int('0B100', 2), 4) + # Bug 1679: "0x" is not a valid hex literal + self.assertRaises(ValueError, int, "0x", 16) + self.assertRaises(ValueError, int, "0x", 0) + + # SF bug 1334662: int(string, base) wrong answers # Various representations of 2**32 evaluated to 0 # rather than 2**32 in previous versions Modified: python/branches/py3k/Lib/test/test_grammar.py ============================================================================== --- python/branches/py3k/Lib/test/test_grammar.py (original) +++ python/branches/py3k/Lib/test/test_grammar.py Sat Jan 19 21:08:23 2008 @@ -32,6 +32,8 @@ self.assertEquals(0o377, 255) self.assertEquals(2147483647, 0o17777777777) self.assertEquals(0b1001, 9) + # "0x" is not a valid literal + self.assertRaises(SyntaxError, eval, "0x") from sys import maxsize if maxsize == 2147483647: self.assertEquals(-2147483647-1, -0o20000000000) Modified: python/branches/py3k/Lib/test/test_mmap.py ============================================================================== --- python/branches/py3k/Lib/test/test_mmap.py (original) +++ python/branches/py3k/Lib/test/test_mmap.py Sat Jan 19 21:08:23 2008 @@ -252,6 +252,42 @@ self.assertEqual(m.find(slice + b'x'), -1) m.close() + def test_find_end(self): + # test the new 'end' parameter works as expected + f = open(TESTFN, 'w+') + data = 'one two ones' + n = len(data) + f.write(data) + f.flush() + m = mmap.mmap(f.fileno(), n) + f.close() + + self.assertEqual(m.find('one'), 0) + self.assertEqual(m.find('ones'), 8) + self.assertEqual(m.find('one', 0, -1), 0) + self.assertEqual(m.find('one', 1), 8) + self.assertEqual(m.find('one', 1, -1), 8) + self.assertEqual(m.find('one', 1, -2), -1) + + + def test_rfind(self): + # test the new 'end' parameter works as expected + f = open(TESTFN, 'w+') + data = 'one two ones' + n = len(data) + f.write(data) + f.flush() + m = mmap.mmap(f.fileno(), n) + f.close() + + self.assertEqual(m.rfind('one'), 8) + self.assertEqual(m.rfind('one '), 0) + self.assertEqual(m.rfind('one', 0, -1), 8) + self.assertEqual(m.rfind('one', 0, -2), 0) + self.assertEqual(m.rfind('one', 1, -1), 8) + self.assertEqual(m.rfind('one', 1, -2), -1) + + def test_double_close(self): # make sure a double close doesn't crash on Solaris (Bug# 665913) f = open(TESTFN, 'wb+') Modified: python/branches/py3k/Lib/test/test_socket.py ============================================================================== --- python/branches/py3k/Lib/test/test_socket.py (original) +++ python/branches/py3k/Lib/test/test_socket.py Sat Jan 19 21:08:23 2008 @@ -288,7 +288,6 @@ def testRefCountGetNameInfo(self): # Testing reference count for getnameinfo - import sys if hasattr(sys, "getrefcount"): try: # On some versions, this loses a reference Modified: python/branches/py3k/Lib/test/test_ssl.py ============================================================================== --- python/branches/py3k/Lib/test/test_ssl.py (original) +++ python/branches/py3k/Lib/test/test_ssl.py Sat Jan 19 21:08:23 2008 @@ -38,6 +38,27 @@ class BasicTests(unittest.TestCase): + def testSSLconnect(self): + if not test_support.is_resource_enabled('network'): + return + s = ssl.wrap_socket(socket.socket(socket.AF_INET), + cert_reqs=ssl.CERT_NONE) + s.connect(("svn.python.org", 443)) + c = s.getpeercert() + if c: + raise test_support.TestFailed("Peer cert %s shouldn't be here!") + s.close() + + # this should fail because we have no verification certs + s = ssl.wrap_socket(socket.socket(socket.AF_INET), + cert_reqs=ssl.CERT_REQUIRED) + try: + s.connect(("svn.python.org", 443)) + except ssl.SSLError: + pass + finally: + s.close() + def testCrucialConstants(self): ssl.PROTOCOL_SSLv2 ssl.PROTOCOL_SSLv23 @@ -81,7 +102,6 @@ class NetworkedTests(unittest.TestCase): def testConnect(self): - s = ssl.wrap_socket(socket.socket(socket.AF_INET), cert_reqs=ssl.CERT_NONE) s.connect(("svn.python.org", 443)) Modified: python/branches/py3k/Lib/test/test_textwrap.py ============================================================================== --- python/branches/py3k/Lib/test/test_textwrap.py (original) +++ python/branches/py3k/Lib/test/test_textwrap.py Sat Jan 19 21:08:23 2008 @@ -385,6 +385,19 @@ ' o'], subsequent_indent = ' '*15) + # bug 1146. Prevent a long word to be wrongly wrapped when the + # preceding word is exactly one character shorter than the width + self.check_wrap(self.text, 12, + ['Did you say ', + '"supercalifr', + 'agilisticexp', + 'ialidocious?', + '" How *do*', + 'you spell', + 'that odd', + 'word,', + 'anyways?']) + def test_nobreak_long(self): # Test with break_long_words disabled self.wrapper.break_long_words = 0 Modified: python/branches/py3k/Lib/test/test_xmlrpc.py ============================================================================== --- python/branches/py3k/Lib/test/test_xmlrpc.py (original) +++ python/branches/py3k/Lib/test/test_xmlrpc.py Sat Jan 19 21:08:23 2008 @@ -347,7 +347,8 @@ # protocol error; provide additional information in test output self.fail("%s\n%s" % (e, e.headers)) - def test_404(self): + # [ch] The test 404 is causing lots of false alarms. + def XXXtest_404(self): # send POST with httplib, it should return 404 header and # 'Not Found' message. conn = httplib.HTTPConnection('localhost', PORT) Modified: python/branches/py3k/Lib/textwrap.py ============================================================================== --- python/branches/py3k/Lib/textwrap.py (original) +++ python/branches/py3k/Lib/textwrap.py Sat Jan 19 21:08:23 2008 @@ -159,7 +159,12 @@ Handle a chunk of text (most likely a word, not whitespace) that is too long to fit in any line. """ - space_left = max(width - cur_len, 1) + # Figure out when indent is larger than the specified width, and make + # sure at least one character is stripped off on every pass + if width < 1: + space_left = 1 + else: + space_left = width - cur_len # If we're allowed to break long words, then do so: put as much # of the next chunk onto the current line as will fit. Modified: python/branches/py3k/Lib/tokenize.py ============================================================================== --- python/branches/py3k/Lib/tokenize.py (original) +++ python/branches/py3k/Lib/tokenize.py Sat Jan 19 21:08:23 2008 @@ -49,9 +49,9 @@ Ignore = Whitespace + any(r'\\\r?\n' + Whitespace) + maybe(Comment) Name = r'[a-zA-Z_]\w*' -Hexnumber = r'0[xX][\da-fA-F]*' -Binnumber = r'0[bB][01]*' -Octnumber = r'0[oO][0-7]*' +Hexnumber = r'0[xX][\da-fA-F]+' +Binnumber = r'0[bB][01]+' +Octnumber = r'0[oO][0-7]+' Decnumber = r'(?:0+|[1-9]\d*)' Intnumber = group(Hexnumber, Binnumber, Octnumber, Decnumber) Exponent = r'[eE][-+]?\d+' Modified: python/branches/py3k/Lib/trace.py ============================================================================== --- python/branches/py3k/Lib/trace.py (original) +++ python/branches/py3k/Lib/trace.py Sat Jan 19 21:08:23 2008 @@ -96,8 +96,9 @@ (Can only be used with --count or --report.) Filters, may be repeated multiple times: ---ignore-module= Ignore the given module and its submodules - (if it is a package). +--ignore-module= Ignore the given module(s) and its submodules + (if it is a package). Accepts comma separated + list of module names --ignore-dir= Ignore files in the given directory (multiple directories can be joined by os.pathsep). """ % sys.argv[0]) @@ -725,7 +726,8 @@ continue if opt == "--ignore-module": - ignore_modules.append(val) + for mod in val.split(","): + ignore_modules.append(mod.strip()) continue if opt == "--ignore-dir": Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Sat Jan 19 21:08:23 2008 @@ -109,8 +109,6 @@ Brett Cannon Mike Carlton Terry Carroll -Brian Leair -Luke Kenneth Casson Leighton Donn Cave Per Cederqvist Octavian Cerna @@ -390,6 +388,7 @@ Ben Laurie Simon Law Chris Lawrence +Brian Leair Christopher Lee Inyeol Lee John J. Lee @@ -397,7 +396,9 @@ Luc Lefebvre Kip Lehman Joerg Lehmann +Luke Kenneth Casson Leighton Marc-Andre Lemburg +John Lenton Mark Levinson William Lewis Robert van Liere @@ -524,6 +525,7 @@ Fran?ois Pinard Zach Pincus Michael Piotrowski +Michael Pomraning Iustin Pop John Popplewell Amrit Prem Modified: python/branches/py3k/Modules/mmapmodule.c ============================================================================== --- python/branches/py3k/Modules/mmapmodule.c (original) +++ python/branches/py3k/Modules/mmapmodule.c Sat Jan 19 21:08:23 2008 @@ -254,19 +254,22 @@ } static PyObject * -mmap_find_method(mmap_object *self, - PyObject *args) +mmap_gfind(mmap_object *self, + PyObject *args, + int reverse) { Py_ssize_t start = self->pos; + Py_ssize_t end = self->size; char *needle; Py_ssize_t len; CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, "s#|n:find", &needle, &len, &start)) { + if (!PyArg_ParseTuple(args, reverse ? "s#|nn:rfind" : "s#|nn:find", + &needle, &len, &start, &end)) { return NULL; } else { char *p; - char *e = self->data + self->size; + char sign = reverse ? -1 : 1; if (start < 0) start += self->size; @@ -275,7 +278,18 @@ else if ((size_t)start > self->size) start = self->size; - for (p = self->data + start; p + len <= e; ++p) { + if (end < 0) + end += self->size; + if (end < 0) + end = 0; + else if ((size_t)end > self->size) + end = self->size; + + start += (Py_ssize_t)self->data; + end += (Py_ssize_t)self->data; + + for (p = (char *)(reverse ? end - len : start); + p >= (char *)start && p + len <= (char *)end; p+=sign) { Py_ssize_t i; for (i = 0; i < len && needle[i] == p[i]; ++i) /* nothing */; @@ -287,6 +301,20 @@ } } +static PyObject * +mmap_find_method(mmap_object *self, + PyObject *args) +{ + return mmap_gfind(self, args, 0); +} + +static PyObject * +mmap_rfind_method(mmap_object *self, + PyObject *args) +{ + return mmap_gfind(self, args, 1); +} + static int is_writable(mmap_object *self) { @@ -604,6 +632,7 @@ static struct PyMethodDef mmap_object_methods[] = { {"close", (PyCFunction) mmap_close_method, METH_NOARGS}, {"find", (PyCFunction) mmap_find_method, METH_VARARGS}, + {"rfind", (PyCFunction) mmap_rfind_method, METH_VARARGS}, {"flush", (PyCFunction) mmap_flush_method, METH_VARARGS}, {"move", (PyCFunction) mmap_move_method, METH_VARARGS}, {"read", (PyCFunction) mmap_read_method, METH_VARARGS}, Modified: python/branches/py3k/Parser/tokenizer.c ============================================================================== --- python/branches/py3k/Parser/tokenizer.c (original) +++ python/branches/py3k/Parser/tokenizer.c Sat Jan 19 21:08:23 2008 @@ -1352,19 +1352,38 @@ goto imaginary; #endif if (c == 'x' || c == 'X') { + /* Hex */ + c = tok_nextc(tok); + if (!isxdigit(c)) { + tok->done = E_TOKEN; + tok_backup(tok, c); + return ERRORTOKEN; + } do { c = tok_nextc(tok); } while (isxdigit(c)); } else if (c == 'o' || c == 'O') { /* Octal */ + c = tok_nextc(tok); + if (c < '0' || c > '8') { + tok->done = E_TOKEN; + tok_backup(tok, c); + return ERRORTOKEN; + } do { c = tok_nextc(tok); } while ('0' <= c && c < '8'); } else if (c == 'b' || c == 'B') { /* Binary */ + c = tok_nextc(tok); + if (c != '0' && c != '1') { + tok->done = E_TOKEN; + tok_backup(tok, c); + return ERRORTOKEN; + } do { c = tok_nextc(tok); } while (c == '0' || c == '1'); Modified: python/branches/py3k/Python/modsupport.c ============================================================================== --- python/branches/py3k/Python/modsupport.c (original) +++ python/branches/py3k/Python/modsupport.c Sat Jan 19 21:08:23 2008 @@ -696,11 +696,23 @@ int PyModule_AddIntConstant(PyObject *m, const char *name, long value) { - return PyModule_AddObject(m, name, PyLong_FromLong(value)); + PyObject *o = PyLong_FromLong(value); + if (!o) + return -1; + if (PyModule_AddObject(m, name, o) == 0) + return 0; + Py_DECREF(o); + return -1; } int PyModule_AddStringConstant(PyObject *m, const char *name, const char *value) { - return PyModule_AddObject(m, name, PyUnicode_FromString(value)); + PyObject *o = PyUnicode_FromString(value); + if (!o) + return -1; + if (PyModule_AddObject(m, name, o) == 0) + return 0; + Py_DECREF(o); + return -1; } Modified: python/branches/py3k/Python/mystrtoul.c ============================================================================== --- python/branches/py3k/Python/mystrtoul.c (original) +++ python/branches/py3k/Python/mystrtoul.c Sat Jan 19 21:08:23 2008 @@ -116,12 +116,30 @@ if (*str == '0') { ++str; if (*str == 'x' || *str == 'X') { + /* there must be at least one digit after 0x */ + if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 16) { + if (ptr) + *ptr = str; + return 0; + } ++str; base = 16; } else if (*str == 'o' || *str == 'O') { + /* there must be at least one digit after 0o */ + if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 8) { + if (ptr) + *ptr = str; + return 0; + } ++str; base = 8; } else if (*str == 'b' || *str == 'B') { + /* there must be at least one digit after 0b */ + if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 2) { + if (ptr) + *ptr = str; + return 0; + } ++str; base = 2; } else { @@ -143,22 +161,43 @@ case 16: if (*str == '0') { ++str; - if (*str == 'x' || *str == 'X') + if (*str == 'x' || *str == 'X') { + /* there must be at least one digit after 0x */ + if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 16) { + if (ptr) + *ptr = str; + return 0; + } ++str; + } } break; case 8: if (*str == '0') { ++str; - if (*str == 'o' || *str == 'O') + if (*str == 'o' || *str == 'O') { + /* there must be at least one digit after 0o */ + if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 8) { + if (ptr) + *ptr = str; + return 0; + } ++str; + } } break; case 2: if(*str == '0') { ++str; - if (*str == 'b' || *str == 'B') + if (*str == 'b' || *str == 'B') { + /* there must be at least one digit after 0b */ + if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 2) { + if (ptr) + *ptr = str; + return 0; + } ++str; + } } break; } From python-3000-checkins at python.org Sat Jan 19 21:44:32 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sat, 19 Jan 2008 21:44:32 +0100 (CET) Subject: [Python-3000-checkins] r60100 - python/branches/py3k/Lib/pydoc.py Message-ID: <20080119204432.694B41E4007@bag.python.org> Author: georg.brandl Date: Sat Jan 19 21:44:32 2008 New Revision: 60100 Modified: python/branches/py3k/Lib/pydoc.py Log: #1867: fix a few 3.0 incompatibilities in pydoc. Modified: python/branches/py3k/Lib/pydoc.py ============================================================================== --- python/branches/py3k/Lib/pydoc.py (original) +++ python/branches/py3k/Lib/pydoc.py Sat Jan 19 21:44:32 2008 @@ -1946,9 +1946,9 @@ def send_document(self, title, contents): try: self.send_response(200) - self.send_header('Content-Type', 'text/html') + self.send_header('Content-Type', 'text/html; charset=UTF-8') self.end_headers() - self.wfile.write(html.page(title, contents)) + self.wfile.write(html.page(title, contents).encode('utf-8')) except IOError: pass def do_GET(self): @@ -1974,7 +1974,7 @@ return '%s' % (name, name) names = filter(lambda x: x != '__main__', sys.builtin_module_names) - contents = html.multicolumn(names, bltinlink) + contents = html.multicolumn(list(names), bltinlink) indices = ['

' + html.bigsection( 'Built-in Modules', '#ffffff', '#ee77aa', contents)] From python-3000-checkins at python.org Sat Jan 19 22:56:12 2008 From: python-3000-checkins at python.org (thomas.heller) Date: Sat, 19 Jan 2008 22:56:12 +0100 (CET) Subject: [Python-3000-checkins] r60108 - in python/branches/py3k-ctypes-pep3118: Lib/ctypes/test/test_pep3118.py Modules/_ctypes/_ctypes.c Message-ID: <20080119215612.DA5381E4031@bag.python.org> Author: thomas.heller Date: Sat Jan 19 22:56:12 2008 New Revision: 60108 Added: python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py (contents, props changed) Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c Log: Always use explicit endian specifiers for simple types, and a bug fix too. Add unittest. Added: python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py ============================================================================== --- (empty file) +++ python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py Sat Jan 19 22:56:12 2008 @@ -0,0 +1,51 @@ +import unittest +from ctypes import * +import struct, sys + +if sys.byteorder == "little": + ENDIAN = "<" +else: + ENDIAN = ">" + +simple_types = [ + ("b", c_byte), + ("B", c_ubyte), + ("h", c_short), + ("H", c_ushort), +# c_int and c_uint may be aliases to c_long +## ("i", c_int), +## ("I", c_uint), + ("l", c_long), + ("L", c_ulong), + ("q", c_longlong), + ("Q", c_ulonglong), + ("f", c_float), + ("d", c_double), +# c_longdouble may be an alias to c_double +## ("g", c_longdouble), + ("t", c_bool), +# struct doesn't support this (yet) +## ("O", py_object), +] + +class Test(unittest.TestCase): + + def test_simpletypes(self): + # simple types in native byte order + for fmt, typ in simple_types: + v = memoryview(typ()) + + # check the PEP3118 format string + self.failUnlessEqual(v.format, ENDIAN + fmt) + + # shape and strides are None for integral types + self.failUnlessEqual((v.shape, v.strides), + (None, None)) + + # size and itemsize must be what struct.calcsize reports + struct_size = struct.calcsize(fmt) + self.failUnlessEqual((v.size, v.itemsize), + (struct_size, struct_size)) + +if __name__ == "__main__": + unittest.main() Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c Sat Jan 19 22:56:12 2008 @@ -1596,7 +1596,11 @@ stgdict->size = fmt->pffi_type->size; stgdict->setfunc = fmt->setfunc; stgdict->getfunc = fmt->getfunc; - stgdict->format = alloc_format_string(NULL, proto_str); +#ifdef WORDS_BIGENDIAN + stgdict->format = alloc_format_string(">", proto_str); +#else + stgdict->format = alloc_format_string("<", proto_str); +#endif if (stgdict->format == NULL) { Py_DECREF(result); Py_DECREF((PyObject *)stgdict); @@ -1669,18 +1673,20 @@ } sw_dict = PyType_stgdict(swapped); #ifdef WORDS_BIGENDIAN - sw_dict->format = alloc_format_string("<", stgdict->format); PyObject_SetAttrString((PyObject *)result, "__ctype_le__", swapped); PyObject_SetAttrString((PyObject *)result, "__ctype_be__", (PyObject *)result); PyObject_SetAttrString(swapped, "__ctype_be__", (PyObject *)result); PyObject_SetAttrString(swapped, "__ctype_le__", swapped); + /* We are creating the type for the OTHER endian */ + sw_dict->format = alloc_format_string("<", stgdict->format); #else PyObject_SetAttrString((PyObject *)result, "__ctype_be__", swapped); PyObject_SetAttrString((PyObject *)result, "__ctype_le__", (PyObject *)result); PyObject_SetAttrString(swapped, "__ctype_le__", (PyObject *)result); PyObject_SetAttrString(swapped, "__ctype_be__", swapped); + /* We are creating the type for the OTHER endian */ + sw_dict->format = alloc_format_string(">", stgdict->format); #endif - sw_dict->format = alloc_format_string("<", stgdict->format); Py_DECREF(swapped); if (PyErr_Occurred()) { Py_DECREF(result); From python-3000-checkins at python.org Sat Jan 19 23:25:14 2008 From: python-3000-checkins at python.org (thomas.heller) Date: Sat, 19 Jan 2008 23:25:14 +0100 (CET) Subject: [Python-3000-checkins] r60112 - in python/branches/py3k-ctypes-pep3118: Lib/ctypes/test/test_pep3118.py Modules/_ctypes/_ctypes.c Message-ID: <20080119222514.8F8A01E4023@bag.python.org> Author: thomas.heller Date: Sat Jan 19 23:25:14 2008 New Revision: 60112 Modified: python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c Log: Fully implement tp_asbuffer for pointer types. Modified: python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py Sat Jan 19 23:25:14 2008 @@ -47,5 +47,23 @@ self.failUnlessEqual((v.size, v.itemsize), (struct_size, struct_size)) + def test_pointertypes(self): + for fmt, typ in simple_types: + v = memoryview(POINTER(typ)()) + + # check the PEP3118 format string + self.failUnlessEqual(v.format, "&" + ENDIAN + fmt) + + # shape and strides are None for integral types + self.failUnlessEqual((v.shape, v.strides), + (None, None)) + + # size and itemsize must be what struct.calcsize reports + # for pointers + struct_size = struct.calcsize("P") + self.failUnlessEqual((v.size, v.itemsize), + (struct_size, struct_size)) + + if __name__ == "__main__": unittest.main() Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c Sat Jan 19 23:25:14 2008 @@ -635,6 +635,16 @@ return NULL; } + if (proto) { + StgDictObject *itemdict = PyType_stgdict(proto); + assert(itemdict); + stgdict->format = alloc_format_string("&", itemdict->format); + if (stgdict->format == NULL) { + Py_DECREF((PyObject *)stgdict); + return NULL; + } + } + /* create the new instance (which is a class, since we are a metatype!) */ result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds); @@ -4659,7 +4669,7 @@ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ - &CData_as_buffer, /* tp_as_buffer */ + &Simple_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ "XXX to be provided", /* tp_doc */ (traverseproc)CData_traverse, /* tp_traverse */ From python-3000-checkins at python.org Sun Jan 20 10:06:42 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Sun, 20 Jan 2008 10:06:42 +0100 (CET) Subject: [Python-3000-checkins] r60124 - in python/branches/py3k: Doc/c-api/newtypes.rst Doc/library/optparse.rst Doc/library/os.rst Doc/library/sqlite3.rst Doc/library/xml.sax.utils.rst Doc/library/zipfile.rst Doc/whatsnew/2.6.rst Lib/curses/textpad.py Lib/mailbox.py Lib/subprocess.py Lib/test/curses_tests.py Lib/test/test_mailbox.py Lib/test/test_os.py Lib/test/test_subprocess.py Lib/test/test_zipfile.py Lib/zipfile.py Misc/ACKS Modules/_sqlite/cursor.c Modules/posixmodule.c Modules/socketmodule.c Message-ID: <20080120090642.A4A931E401F@bag.python.org> Author: christian.heimes Date: Sun Jan 20 10:06:41 2008 New Revision: 60124 Added: python/branches/py3k/Lib/test/curses_tests.py - copied unchanged from r60123, python/trunk/Lib/test/curses_tests.py Removed: python/branches/py3k/Doc/c-api/newtypes.rst Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/optparse.rst python/branches/py3k/Doc/library/os.rst python/branches/py3k/Doc/library/sqlite3.rst python/branches/py3k/Doc/library/xml.sax.utils.rst python/branches/py3k/Doc/library/zipfile.rst python/branches/py3k/Doc/whatsnew/2.6.rst python/branches/py3k/Lib/curses/textpad.py python/branches/py3k/Lib/mailbox.py python/branches/py3k/Lib/subprocess.py python/branches/py3k/Lib/test/test_mailbox.py python/branches/py3k/Lib/test/test_os.py python/branches/py3k/Lib/test/test_subprocess.py python/branches/py3k/Lib/test/test_zipfile.py python/branches/py3k/Lib/zipfile.py python/branches/py3k/Misc/ACKS python/branches/py3k/Modules/_sqlite/cursor.c python/branches/py3k/Modules/posixmodule.c python/branches/py3k/Modules/socketmodule.c Log: Merged revisions 60094-60123 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk *** NOTE *** I haven't merged the files in Doc/c-api/. I got too many conflicts. Georg, please split them manually. ........ r60095 | andrew.kuchling | 2008-01-19 21:12:04 +0100 (Sat, 19 Jan 2008) | 2 lines Bug 1277: make Maildir use the user-provided factory instead of hard-wiring MaildirMessage. 2.5.2 bugfix candidate. ........ r60097 | georg.brandl | 2008-01-19 21:22:13 +0100 (Sat, 19 Jan 2008) | 4 lines #1663329: add os.closerange() to close a range of fds, ignoring errors, and use this in subprocess to speed up subprocess creation in close_fds mode. Patch by Mike Klaas. ........ r60099 | georg.brandl | 2008-01-19 21:40:24 +0100 (Sat, 19 Jan 2008) | 2 lines #1411695: clarify behavior of xml.sax.utils.[un]escape. ........ r60101 | andrew.kuchling | 2008-01-19 21:47:59 +0100 (Sat, 19 Jan 2008) | 7 lines Patch #1019808 from Federico Schwindt: Return correct socket error when a default timeout has been set, by using getsockopt() to get the error condition (instead of trying another connect() call, which seems to be a Linuxism). 2.5 bugfix candidate, assuming no one reports any problems with this change. ........ r60102 | gregory.p.smith | 2008-01-19 21:49:02 +0100 (Sat, 19 Jan 2008) | 3 lines fix comment typos, use not arg instead of arg == "", add test coverage for inside of the final if needquotes: within subprocess.list2cmdline(). ........ r60103 | georg.brandl | 2008-01-19 21:53:07 +0100 (Sat, 19 Jan 2008) | 2 lines #1509: fix sqlite3 docstrings and docs w.r.t. cursor.fetchXXX methods. ........ r60104 | gregory.p.smith | 2008-01-19 21:57:59 +0100 (Sat, 19 Jan 2008) | 6 lines Fixes issue1336 - a race condition could occur when forking if the gc kicked in during the critical section. solution: disable gc during that section. Patch contributed by jpa and updated by me to cover the race condition still existing what therve from twistedmatrix pointed out (already seen and fixed in twisted's own subprocess code). ........ r60105 | gregory.p.smith | 2008-01-19 22:00:37 +0100 (Sat, 19 Jan 2008) | 2 lines note about r60104 ........ r60106 | andrew.kuchling | 2008-01-19 22:00:38 +0100 (Sat, 19 Jan 2008) | 1 line Bug 1296: restore text describing OptionGroup ........ r60109 | georg.brandl | 2008-01-19 23:08:21 +0100 (Sat, 19 Jan 2008) | 2 lines Split the monstrous C API manual files in smaller parts. ........ r60110 | georg.brandl | 2008-01-19 23:14:27 +0100 (Sat, 19 Jan 2008) | 2 lines Missed one big file to split up. ........ r60111 | gregory.p.smith | 2008-01-19 23:23:56 +0100 (Sat, 19 Jan 2008) | 12 lines Undo an unnecessary else: and indentation that r60104 added. try: ... except: ... raise else: ... the else: is unecessary due to the blind except: with a raise. ........ r60115 | gregory.p.smith | 2008-01-19 23:49:37 +0100 (Sat, 19 Jan 2008) | 3 lines Fix issue 1300: Quote command line arguments that contain a '|' character in subprocess.list2cmdline (windows). ........ r60116 | gregory.p.smith | 2008-01-20 00:10:52 +0100 (Sun, 20 Jan 2008) | 3 lines Fixes/Accepts Patch for issue1189216 - Work properly with archives that have file headers past the 2**31 byte boundary. ........ r60119 | andrew.kuchling | 2008-01-20 01:00:38 +0100 (Sun, 20 Jan 2008) | 3 lines Patch #1048820 from Stefan Wehr: add insert-mode editing to Textbox. Fix an off-by-one error I noticed. ........ r60120 | andrew.kuchling | 2008-01-20 01:12:19 +0100 (Sun, 20 Jan 2008) | 1 line Add an interactive test script for exercising curses ........ r60121 | gregory.p.smith | 2008-01-20 02:21:03 +0100 (Sun, 20 Jan 2008) | 7 lines Fix zipfile decryption. The check for validity only worked on one type of encrypted zip files. Files using extended local headers needed to compare the check byte against different values. (according to reading the infozip unzip crypt.c source code) Fixes issue1003. ........ r60122 | gregory.p.smith | 2008-01-20 02:26:04 +0100 (Sun, 20 Jan 2008) | 2 lines note for r60121 ........ r60123 | gregory.p.smith | 2008-01-20 02:32:00 +0100 (Sun, 20 Jan 2008) | 4 lines Document that zipfile decryption is insanely slow and fix a typo and blatant lie in a docstring (it is not useful for security regardless of how you spell it). ........ Deleted: /python/branches/py3k/Doc/c-api/newtypes.rst ============================================================================== --- /python/branches/py3k/Doc/c-api/newtypes.rst Sun Jan 20 10:06:41 2008 +++ (empty file) @@ -1,1855 +0,0 @@ -.. highlightlang:: c - - -.. _newtypes: - -***************************** -Object Implementation Support -***************************** - -This chapter describes the functions, types, and macros used when defining new -object types. - - -.. _allocating-objects: - -Allocating Objects on the Heap -============================== - - -.. cfunction:: PyObject* _PyObject_New(PyTypeObject *type) - - -.. cfunction:: PyVarObject* _PyObject_NewVar(PyTypeObject *type, Py_ssize_t size) - - -.. cfunction:: PyObject* PyObject_Init(PyObject *op, PyTypeObject *type) - - Initialize a newly-allocated object *op* with its type and initial reference. - Returns the initialized object. If *type* indicates that the object - participates in the cyclic garbage detector, it is added to the detector's set - of observed objects. Other fields of the object are not affected. - - -.. cfunction:: PyVarObject* PyObject_InitVar(PyVarObject *op, PyTypeObject *type, Py_ssize_t size) - - This does everything :cfunc:`PyObject_Init` does, and also initializes the - length information for a variable-size object. - - -.. cfunction:: TYPE* PyObject_New(TYPE, PyTypeObject *type) - - Allocate a new Python object using the C structure type *TYPE* and the Python - type object *type*. Fields not defined by the Python object header are not - initialized; the object's reference count will be one. The size of the memory - allocation is determined from the :attr:`tp_basicsize` field of the type object. - - -.. cfunction:: TYPE* PyObject_NewVar(TYPE, PyTypeObject *type, Py_ssize_t size) - - Allocate a new Python object using the C structure type *TYPE* and the Python - type object *type*. Fields not defined by the Python object header are not - initialized. The allocated memory allows for the *TYPE* structure plus *size* - fields of the size given by the :attr:`tp_itemsize` field of *type*. This is - useful for implementing objects like tuples, which are able to determine their - size at construction time. Embedding the array of fields into the same - allocation decreases the number of allocations, improving the memory management - efficiency. - - -.. cfunction:: void PyObject_Del(PyObject *op) - - Releases memory allocated to an object using :cfunc:`PyObject_New` or - :cfunc:`PyObject_NewVar`. This is normally called from the :attr:`tp_dealloc` - handler specified in the object's type. The fields of the object should not be - accessed after this call as the memory is no longer a valid Python object. - - -.. cfunction:: PyObject* Py_InitModule(char *name, PyMethodDef *methods) - - Create a new module object based on a name and table of functions, returning - the new module object; the *methods* argument can be *NULL* if no methods are - to be defined for the module. - - -.. cfunction:: PyObject* Py_InitModule3(char *name, PyMethodDef *methods, char *doc) - - Create a new module object based on a name and table of functions, returning - the new module object. The *methods* argument can be *NULL* if no methods - are to be defined for the module. If *doc* is non-*NULL*, it will be used to - define the docstring for the module. - - -.. cfunction:: PyObject* Py_InitModule4(char *name, PyMethodDef *methods, char *doc, PyObject *self, int apiver) - - Create a new module object based on a name and table of functions, returning - the new module object. The *methods* argument can be *NULL* if no methods - are to be defined for the module. If *doc* is non-*NULL*, it will be used to - define the docstring for the module. If *self* is non-*NULL*, it will passed - to the functions of the module as their (otherwise *NULL*) first parameter. - (This was added as an experimental feature, and there are no known uses in - the current version of Python.) For *apiver*, the only value which should be - passed is defined by the constant :const:`PYTHON_API_VERSION`. - - .. note:: - - Most uses of this function should probably be using the :cfunc:`Py_InitModule3` - instead; only use this if you are sure you need it. - - -.. cvar:: PyObject _Py_NoneStruct - - Object which is visible in Python as ``None``. This should only be accessed - using the :cmacro:`Py_None` macro, which evaluates to a pointer to this - object. - - -.. _common-structs: - -Common Object Structures -======================== - -There are a large number of structures which are used in the definition of -object types for Python. This section describes these structures and how they -are used. - -All Python objects ultimately share a small number of fields at the beginning of -the object's representation in memory. These are represented by the -:ctype:`PyObject` and :ctype:`PyVarObject` types, which are defined, in turn, by -the expansions of some macros also used, whether directly or indirectly, in the -definition of all other Python objects. - - -.. ctype:: PyObject - - All object types are extensions of this type. This is a type which contains the - information Python needs to treat a pointer to an object as an object. In a - normal "release" build, it contains only the objects reference count and a - pointer to the corresponding type object. It corresponds to the fields defined - by the expansion of the ``PyObject_HEAD`` macro. - - -.. ctype:: PyVarObject - - This is an extension of :ctype:`PyObject` that adds the :attr:`ob_size` field. - This is only used for objects that have some notion of *length*. This type does - not often appear in the Python/C API. It corresponds to the fields defined by - the expansion of the ``PyObject_VAR_HEAD`` macro. - -These macros are used in the definition of :ctype:`PyObject` and -:ctype:`PyVarObject`: - -.. XXX need to document PEP 3123 changes here - -.. cmacro:: PyObject_HEAD - - This is a macro which expands to the declarations of the fields of the - :ctype:`PyObject` type; it is used when declaring new types which represent - objects without a varying length. The specific fields it expands to depend on - the definition of :cmacro:`Py_TRACE_REFS`. By default, that macro is not - defined, and :cmacro:`PyObject_HEAD` expands to:: - - Py_ssize_t ob_refcnt; - PyTypeObject *ob_type; - - When :cmacro:`Py_TRACE_REFS` is defined, it expands to:: - - PyObject *_ob_next, *_ob_prev; - Py_ssize_t ob_refcnt; - PyTypeObject *ob_type; - - -.. cmacro:: PyObject_VAR_HEAD - - This is a macro which expands to the declarations of the fields of the - :ctype:`PyVarObject` type; it is used when declaring new types which represent - objects with a length that varies from instance to instance. This macro always - expands to:: - - PyObject_HEAD - Py_ssize_t ob_size; - - Note that :cmacro:`PyObject_HEAD` is part of the expansion, and that its own - expansion varies depending on the definition of :cmacro:`Py_TRACE_REFS`. - -.. cmacro:: PyObject_HEAD_INIT - - -.. ctype:: PyCFunction - - Type of the functions used to implement most Python callables in C. Functions of - this type take two :ctype:`PyObject\*` parameters and return one such value. If - the return value is *NULL*, an exception shall have been set. If not *NULL*, - the return value is interpreted as the return value of the function as exposed - in Python. The function must return a new reference. - - -.. ctype:: PyCFunctionWithKeywords - - Type of the functions used to implement Python callables in C that take - keyword arguments: they take three :ctype:`PyObject\*` parameters and return - one such value. See :ctype:`PyCFunction` above for the meaning of the return - value. - - -.. ctype:: PyMethodDef - - Structure used to describe a method of an extension type. This structure has - four fields: - - +------------------+-------------+-------------------------------+ - | Field | C Type | Meaning | - +==================+=============+===============================+ - | :attr:`ml_name` | char \* | name of the method | - +------------------+-------------+-------------------------------+ - | :attr:`ml_meth` | PyCFunction | pointer to the C | - | | | implementation | - +------------------+-------------+-------------------------------+ - | :attr:`ml_flags` | int | flag bits indicating how the | - | | | call should be constructed | - +------------------+-------------+-------------------------------+ - | :attr:`ml_doc` | char \* | points to the contents of the | - | | | docstring | - +------------------+-------------+-------------------------------+ - -The :attr:`ml_meth` is a C function pointer. The functions may be of different -types, but they always return :ctype:`PyObject\*`. If the function is not of -the :ctype:`PyCFunction`, the compiler will require a cast in the method table. -Even though :ctype:`PyCFunction` defines the first parameter as -:ctype:`PyObject\*`, it is common that the method implementation uses a the -specific C type of the *self* object. - -The :attr:`ml_flags` field is a bitfield which can include the following flags. -The individual flags indicate either a calling convention or a binding -convention. Of the calling convention flags, only :const:`METH_VARARGS` and -:const:`METH_KEYWORDS` can be combined (but note that :const:`METH_KEYWORDS` -alone is equivalent to ``METH_VARARGS | METH_KEYWORDS``). Any of the calling -convention flags can be combined with a binding flag. - - -.. data:: METH_VARARGS - - This is the typical calling convention, where the methods have the type - :ctype:`PyCFunction`. The function expects two :ctype:`PyObject\*` values. The - first one is the *self* object for methods; for module functions, it has the - value given to :cfunc:`Py_InitModule4` (or *NULL* if :cfunc:`Py_InitModule` was - used). The second parameter (often called *args*) is a tuple object - representing all arguments. This parameter is typically processed using - :cfunc:`PyArg_ParseTuple` or :cfunc:`PyArg_UnpackTuple`. - - -.. data:: METH_KEYWORDS - - Methods with these flags must be of type :ctype:`PyCFunctionWithKeywords`. The - function expects three parameters: *self*, *args*, and a dictionary of all the - keyword arguments. The flag is typically combined with :const:`METH_VARARGS`, - and the parameters are typically processed using - :cfunc:`PyArg_ParseTupleAndKeywords`. - - -.. data:: METH_NOARGS - - Methods without parameters don't need to check whether arguments are given if - they are listed with the :const:`METH_NOARGS` flag. They need to be of type - :ctype:`PyCFunction`. When used with object methods, the first parameter is - typically named ``self`` and will hold a reference to the object instance. In - all cases the second parameter will be *NULL*. - - -.. data:: METH_O - - Methods with a single object argument can be listed with the :const:`METH_O` - flag, instead of invoking :cfunc:`PyArg_ParseTuple` with a ``"O"`` argument. - They have the type :ctype:`PyCFunction`, with the *self* parameter, and a - :ctype:`PyObject\*` parameter representing the single argument. - - -These two constants are not used to indicate the calling convention but the -binding when use with methods of classes. These may not be used for functions -defined for modules. At most one of these flags may be set for any given -method. - - -.. data:: METH_CLASS - - .. index:: builtin: classmethod - - The method will be passed the type object as the first parameter rather than an - instance of the type. This is used to create *class methods*, similar to what - is created when using the :func:`classmethod` built-in function. - - -.. data:: METH_STATIC - - .. index:: builtin: staticmethod - - The method will be passed *NULL* as the first parameter rather than an instance - of the type. This is used to create *static methods*, similar to what is - created when using the :func:`staticmethod` built-in function. - -One other constant controls whether a method is loaded in place of another -definition with the same method name. - - -.. data:: METH_COEXIST - - The method will be loaded in place of existing definitions. Without - *METH_COEXIST*, the default is to skip repeated definitions. Since slot - wrappers are loaded before the method table, the existence of a *sq_contains* - slot, for example, would generate a wrapped method named :meth:`__contains__` - and preclude the loading of a corresponding PyCFunction with the same name. - With the flag defined, the PyCFunction will be loaded in place of the wrapper - object and will co-exist with the slot. This is helpful because calls to - PyCFunctions are optimized more than wrapper object calls. - - -.. cfunction:: PyObject* Py_FindMethod(PyMethodDef table[], PyObject *ob, char *name) - - Return a bound method object for an extension type implemented in C. This can - be useful in the implementation of a :attr:`tp_getattro` or :attr:`tp_getattr` - handler that does not use the :cfunc:`PyObject_GenericGetAttr` function. - - -.. _type-structs: - -Type Objects -============ - -Perhaps one of the most important structures of the Python object system is the -structure that defines a new type: the :ctype:`PyTypeObject` structure. Type -objects can be handled using any of the :cfunc:`PyObject_\*` or -:cfunc:`PyType_\*` functions, but do not offer much that's interesting to most -Python applications. These objects are fundamental to how objects behave, so -they are very important to the interpreter itself and to any extension module -that implements new types. - -Type objects are fairly large compared to most of the standard types. The reason -for the size is that each type object stores a large number of values, mostly C -function pointers, each of which implements a small part of the type's -functionality. The fields of the type object are examined in detail in this -section. The fields will be described in the order in which they occur in the -structure. - -Typedefs: unaryfunc, binaryfunc, ternaryfunc, inquiry, intargfunc, -intintargfunc, intobjargproc, intintobjargproc, objobjargproc, destructor, -freefunc, printfunc, getattrfunc, getattrofunc, setattrfunc, setattrofunc, -cmpfunc, reprfunc, hashfunc - -The structure definition for :ctype:`PyTypeObject` can be found in -:file:`Include/object.h`. For convenience of reference, this repeats the -definition found there: - -.. literalinclude:: ../includes/typestruct.h - - -The type object structure extends the :ctype:`PyVarObject` structure. The -:attr:`ob_size` field is used for dynamic types (created by :func:`type_new`, -usually called from a class statement). Note that :cdata:`PyType_Type` (the -metatype) initializes :attr:`tp_itemsize`, which means that its instances (i.e. -type objects) *must* have the :attr:`ob_size` field. - - -.. cmember:: PyObject* PyObject._ob_next - PyObject* PyObject._ob_prev - - These fields are only present when the macro ``Py_TRACE_REFS`` is defined. - Their initialization to *NULL* is taken care of by the ``PyObject_HEAD_INIT`` - macro. For statically allocated objects, these fields always remain *NULL*. - For dynamically allocated objects, these two fields are used to link the object - into a doubly-linked list of *all* live objects on the heap. This could be used - for various debugging purposes; currently the only use is to print the objects - that are still alive at the end of a run when the environment variable - :envvar:`PYTHONDUMPREFS` is set. - - These fields are not inherited by subtypes. - - -.. cmember:: Py_ssize_t PyObject.ob_refcnt - - This is the type object's reference count, initialized to ``1`` by the - ``PyObject_HEAD_INIT`` macro. Note that for statically allocated type objects, - the type's instances (objects whose :attr:`ob_type` points back to the type) do - *not* count as references. But for dynamically allocated type objects, the - instances *do* count as references. - - This field is not inherited by subtypes. - - -.. cmember:: PyTypeObject* PyObject.ob_type - - This is the type's type, in other words its metatype. It is initialized by the - argument to the ``PyObject_HEAD_INIT`` macro, and its value should normally be - ``&PyType_Type``. However, for dynamically loadable extension modules that must - be usable on Windows (at least), the compiler complains that this is not a valid - initializer. Therefore, the convention is to pass *NULL* to the - ``PyObject_HEAD_INIT`` macro and to initialize this field explicitly at the - start of the module's initialization function, before doing anything else. This - is typically done like this:: - - Foo_Type.ob_type = &PyType_Type; - - This should be done before any instances of the type are created. - :cfunc:`PyType_Ready` checks if :attr:`ob_type` is *NULL*, and if so, - initializes it: in Python 2.2, it is set to ``&PyType_Type``; in Python 2.2.1 - and later it is initialized to the :attr:`ob_type` field of the base class. - :cfunc:`PyType_Ready` will not change this field if it is non-zero. - - In Python 2.2, this field is not inherited by subtypes. In 2.2.1, and in 2.3 - and beyond, it is inherited by subtypes. - - -.. cmember:: Py_ssize_t PyVarObject.ob_size - - For statically allocated type objects, this should be initialized to zero. For - dynamically allocated type objects, this field has a special internal meaning. - - This field is not inherited by subtypes. - - -.. cmember:: char* PyTypeObject.tp_name - - Pointer to a NUL-terminated string containing the name of the type. For types - that are accessible as module globals, the string should be the full module - name, followed by a dot, followed by the type name; for built-in types, it - should be just the type name. If the module is a submodule of a package, the - full package name is part of the full module name. For example, a type named - :class:`T` defined in module :mod:`M` in subpackage :mod:`Q` in package :mod:`P` - should have the :attr:`tp_name` initializer ``"P.Q.M.T"``. - - For dynamically allocated type objects, this should just be the type name, and - the module name explicitly stored in the type dict as the value for key - ``'__module__'``. - - For statically allocated type objects, the tp_name field should contain a dot. - Everything before the last dot is made accessible as the :attr:`__module__` - attribute, and everything after the last dot is made accessible as the - :attr:`__name__` attribute. - - If no dot is present, the entire :attr:`tp_name` field is made accessible as the - :attr:`__name__` attribute, and the :attr:`__module__` attribute is undefined - (unless explicitly set in the dictionary, as explained above). This means your - type will be impossible to pickle. - - This field is not inherited by subtypes. - - -.. cmember:: Py_ssize_t PyTypeObject.tp_basicsize - Py_ssize_t PyTypeObject.tp_itemsize - - These fields allow calculating the size in bytes of instances of the type. - - There are two kinds of types: types with fixed-length instances have a zero - :attr:`tp_itemsize` field, types with variable-length instances have a non-zero - :attr:`tp_itemsize` field. For a type with fixed-length instances, all - instances have the same size, given in :attr:`tp_basicsize`. - - For a type with variable-length instances, the instances must have an - :attr:`ob_size` field, and the instance size is :attr:`tp_basicsize` plus N - times :attr:`tp_itemsize`, where N is the "length" of the object. The value of - N is typically stored in the instance's :attr:`ob_size` field. There are - exceptions: for example, long ints use a negative :attr:`ob_size` to indicate a - negative number, and N is ``abs(ob_size)`` there. Also, the presence of an - :attr:`ob_size` field in the instance layout doesn't mean that the instance - structure is variable-length (for example, the structure for the list type has - fixed-length instances, yet those instances have a meaningful :attr:`ob_size` - field). - - The basic size includes the fields in the instance declared by the macro - :cmacro:`PyObject_HEAD` or :cmacro:`PyObject_VAR_HEAD` (whichever is used to - declare the instance struct) and this in turn includes the :attr:`_ob_prev` and - :attr:`_ob_next` fields if they are present. This means that the only correct - way to get an initializer for the :attr:`tp_basicsize` is to use the - ``sizeof`` operator on the struct used to declare the instance layout. - The basic size does not include the GC header size (this is new in Python 2.2; - in 2.1 and 2.0, the GC header size was included in :attr:`tp_basicsize`). - - These fields are inherited separately by subtypes. If the base type has a - non-zero :attr:`tp_itemsize`, it is generally not safe to set - :attr:`tp_itemsize` to a different non-zero value in a subtype (though this - depends on the implementation of the base type). - - A note about alignment: if the variable items require a particular alignment, - this should be taken care of by the value of :attr:`tp_basicsize`. Example: - suppose a type implements an array of ``double``. :attr:`tp_itemsize` is - ``sizeof(double)``. It is the programmer's responsibility that - :attr:`tp_basicsize` is a multiple of ``sizeof(double)`` (assuming this is the - alignment requirement for ``double``). - - -.. cmember:: destructor PyTypeObject.tp_dealloc - - A pointer to the instance destructor function. This function must be defined - unless the type guarantees that its instances will never be deallocated (as is - the case for the singletons ``None`` and ``Ellipsis``). - - The destructor function is called by the :cfunc:`Py_DECREF` and - :cfunc:`Py_XDECREF` macros when the new reference count is zero. At this point, - the instance is still in existence, but there are no references to it. The - destructor function should free all references which the instance owns, free all - memory buffers owned by the instance (using the freeing function corresponding - to the allocation function used to allocate the buffer), and finally (as its - last action) call the type's :attr:`tp_free` function. If the type is not - subtypable (doesn't have the :const:`Py_TPFLAGS_BASETYPE` flag bit set), it is - permissible to call the object deallocator directly instead of via - :attr:`tp_free`. The object deallocator should be the one used to allocate the - instance; this is normally :cfunc:`PyObject_Del` if the instance was allocated - using :cfunc:`PyObject_New` or :cfunc:`PyObject_VarNew`, or - :cfunc:`PyObject_GC_Del` if the instance was allocated using - :cfunc:`PyObject_GC_New` or :cfunc:`PyObject_GC_VarNew`. - - This field is inherited by subtypes. - - -.. cmember:: printfunc PyTypeObject.tp_print - - An optional pointer to the instance print function. - - The print function is only called when the instance is printed to a *real* file; - when it is printed to a pseudo-file (like a :class:`StringIO` instance), the - instance's :attr:`tp_repr` or :attr:`tp_str` function is called to convert it to - a string. These are also called when the type's :attr:`tp_print` field is - *NULL*. A type should never implement :attr:`tp_print` in a way that produces - different output than :attr:`tp_repr` or :attr:`tp_str` would. - - The print function is called with the same signature as :cfunc:`PyObject_Print`: - ``int tp_print(PyObject *self, FILE *file, int flags)``. The *self* argument is - the instance to be printed. The *file* argument is the stdio file to which it - is to be printed. The *flags* argument is composed of flag bits. The only flag - bit currently defined is :const:`Py_PRINT_RAW`. When the :const:`Py_PRINT_RAW` - flag bit is set, the instance should be printed the same way as :attr:`tp_str` - would format it; when the :const:`Py_PRINT_RAW` flag bit is clear, the instance - should be printed the same was as :attr:`tp_repr` would format it. It should - return ``-1`` and set an exception condition when an error occurred during the - comparison. - - It is possible that the :attr:`tp_print` field will be deprecated. In any case, - it is recommended not to define :attr:`tp_print`, but instead to rely on - :attr:`tp_repr` and :attr:`tp_str` for printing. - - This field is inherited by subtypes. - - -.. cmember:: getattrfunc PyTypeObject.tp_getattr - - An optional pointer to the get-attribute-string function. - - This field is deprecated. When it is defined, it should point to a function - that acts the same as the :attr:`tp_getattro` function, but taking a C string - instead of a Python string object to give the attribute name. The signature is - the same as for :cfunc:`PyObject_GetAttrString`. - - This field is inherited by subtypes together with :attr:`tp_getattro`: a subtype - inherits both :attr:`tp_getattr` and :attr:`tp_getattro` from its base type when - the subtype's :attr:`tp_getattr` and :attr:`tp_getattro` are both *NULL*. - - -.. cmember:: setattrfunc PyTypeObject.tp_setattr - - An optional pointer to the set-attribute-string function. - - This field is deprecated. When it is defined, it should point to a function - that acts the same as the :attr:`tp_setattro` function, but taking a C string - instead of a Python string object to give the attribute name. The signature is - the same as for :cfunc:`PyObject_SetAttrString`. - - This field is inherited by subtypes together with :attr:`tp_setattro`: a subtype - inherits both :attr:`tp_setattr` and :attr:`tp_setattro` from its base type when - the subtype's :attr:`tp_setattr` and :attr:`tp_setattro` are both *NULL*. - - -.. cmember:: cmpfunc PyTypeObject.tp_compare - - An optional pointer to the three-way comparison function. - - The signature is the same as for :cfunc:`PyObject_Compare`. The function should - return ``1`` if *self* greater than *other*, ``0`` if *self* is equal to - *other*, and ``-1`` if *self* less than *other*. It should return ``-1`` and - set an exception condition when an error occurred during the comparison. - - This field is inherited by subtypes together with :attr:`tp_richcompare` and - :attr:`tp_hash`: a subtypes inherits all three of :attr:`tp_compare`, - :attr:`tp_richcompare`, and :attr:`tp_hash` when the subtype's - :attr:`tp_compare`, :attr:`tp_richcompare`, and :attr:`tp_hash` are all *NULL*. - - -.. cmember:: reprfunc PyTypeObject.tp_repr - - .. index:: builtin: repr - - An optional pointer to a function that implements the built-in function - :func:`repr`. - - The signature is the same as for :cfunc:`PyObject_Repr`; it must return a string - or a Unicode object. Ideally, this function should return a string that, when - passed to :func:`eval`, given a suitable environment, returns an object with the - same value. If this is not feasible, it should return a string starting with - ``'<'`` and ending with ``'>'`` from which both the type and the value of the - object can be deduced. - - When this field is not set, a string of the form ``<%s object at %p>`` is - returned, where ``%s`` is replaced by the type name, and ``%p`` by the object's - memory address. - - This field is inherited by subtypes. - -.. cmember:: PyNumberMethods* tp_as_number - - Pointer to an additional structure that contains fields relevant only to - objects which implement the number protocol. These fields are documented in - :ref:`number-structs`. - - The :attr:`tp_as_number` field is not inherited, but the contained fields are - inherited individually. - - -.. cmember:: PySequenceMethods* tp_as_sequence - - Pointer to an additional structure that contains fields relevant only to - objects which implement the sequence protocol. These fields are documented - in :ref:`sequence-structs`. - - The :attr:`tp_as_sequence` field is not inherited, but the contained fields - are inherited individually. - - -.. cmember:: PyMappingMethods* tp_as_mapping - - Pointer to an additional structure that contains fields relevant only to - objects which implement the mapping protocol. These fields are documented in - :ref:`mapping-structs`. - - The :attr:`tp_as_mapping` field is not inherited, but the contained fields - are inherited individually. - - -.. cmember:: hashfunc PyTypeObject.tp_hash - - .. index:: builtin: hash - - An optional pointer to a function that implements the built-in function - :func:`hash`. - - The signature is the same as for :cfunc:`PyObject_Hash`; it must return a C - long. The value ``-1`` should not be returned as a normal return value; when an - error occurs during the computation of the hash value, the function should set - an exception and return ``-1``. - - When this field is not set, two possibilities exist: if the :attr:`tp_compare` - and :attr:`tp_richcompare` fields are both *NULL*, a default hash value based on - the object's address is returned; otherwise, a :exc:`TypeError` is raised. - - This field is inherited by subtypes together with :attr:`tp_richcompare` and - :attr:`tp_compare`: a subtypes inherits all three of :attr:`tp_compare`, - :attr:`tp_richcompare`, and :attr:`tp_hash`, when the subtype's - :attr:`tp_compare`, :attr:`tp_richcompare` and :attr:`tp_hash` are all *NULL*. - - -.. cmember:: ternaryfunc PyTypeObject.tp_call - - An optional pointer to a function that implements calling the object. This - should be *NULL* if the object is not callable. The signature is the same as - for :cfunc:`PyObject_Call`. - - This field is inherited by subtypes. - - -.. cmember:: reprfunc PyTypeObject.tp_str - - An optional pointer to a function that implements the built-in operation - :func:`str`. (Note that :class:`str` is a type now, and :func:`str` calls the - constructor for that type. This constructor calls :cfunc:`PyObject_Str` to do - the actual work, and :cfunc:`PyObject_Str` will call this handler.) - - The signature is the same as for :cfunc:`PyObject_Str`; it must return a string - or a Unicode object. This function should return a "friendly" string - representation of the object, as this is the representation that will be used, - among other things, by the :func:`print` function. - - When this field is not set, :cfunc:`PyObject_Repr` is called to return a string - representation. - - This field is inherited by subtypes. - - -.. cmember:: getattrofunc PyTypeObject.tp_getattro - - An optional pointer to the get-attribute function. - - The signature is the same as for :cfunc:`PyObject_GetAttr`. It is usually - convenient to set this field to :cfunc:`PyObject_GenericGetAttr`, which - implements the normal way of looking for object attributes. - - This field is inherited by subtypes together with :attr:`tp_getattr`: a subtype - inherits both :attr:`tp_getattr` and :attr:`tp_getattro` from its base type when - the subtype's :attr:`tp_getattr` and :attr:`tp_getattro` are both *NULL*. - - -.. cmember:: setattrofunc PyTypeObject.tp_setattro - - An optional pointer to the set-attribute function. - - The signature is the same as for :cfunc:`PyObject_SetAttr`. It is usually - convenient to set this field to :cfunc:`PyObject_GenericSetAttr`, which - implements the normal way of setting object attributes. - - This field is inherited by subtypes together with :attr:`tp_setattr`: a subtype - inherits both :attr:`tp_setattr` and :attr:`tp_setattro` from its base type when - the subtype's :attr:`tp_setattr` and :attr:`tp_setattro` are both *NULL*. - - -.. cmember:: PyBufferProcs* PyTypeObject.tp_as_buffer - - Pointer to an additional structure that contains fields relevant only to objects - which implement the buffer interface. These fields are documented in - :ref:`buffer-structs`. - - The :attr:`tp_as_buffer` field is not inherited, but the contained fields are - inherited individually. - - -.. cmember:: long PyTypeObject.tp_flags - - This field is a bit mask of various flags. Some flags indicate variant - semantics for certain situations; others are used to indicate that certain - fields in the type object (or in the extension structures referenced via - :attr:`tp_as_number`, :attr:`tp_as_sequence`, :attr:`tp_as_mapping`, and - :attr:`tp_as_buffer`) that were historically not always present are valid; if - such a flag bit is clear, the type fields it guards must not be accessed and - must be considered to have a zero or *NULL* value instead. - - Inheritance of this field is complicated. Most flag bits are inherited - individually, i.e. if the base type has a flag bit set, the subtype inherits - this flag bit. The flag bits that pertain to extension structures are strictly - inherited if the extension structure is inherited, i.e. the base type's value of - the flag bit is copied into the subtype together with a pointer to the extension - structure. The :const:`Py_TPFLAGS_HAVE_GC` flag bit is inherited together with - the :attr:`tp_traverse` and :attr:`tp_clear` fields, i.e. if the - :const:`Py_TPFLAGS_HAVE_GC` flag bit is clear in the subtype and the - :attr:`tp_traverse` and :attr:`tp_clear` fields in the subtype exist (as - indicated by the :const:`Py_TPFLAGS_HAVE_RICHCOMPARE` flag bit) and have *NULL* - values. - - The following bit masks are currently defined; these can be ORed together using - the ``|`` operator to form the value of the :attr:`tp_flags` field. The macro - :cfunc:`PyType_HasFeature` takes a type and a flags value, *tp* and *f*, and - checks whether ``tp->tp_flags & f`` is non-zero. - - - .. data:: Py_TPFLAGS_HAVE_GETCHARBUFFER - - If this bit is set, the :ctype:`PyBufferProcs` struct referenced by - :attr:`tp_as_buffer` has the :attr:`bf_getcharbuffer` field. - - - .. data:: Py_TPFLAGS_HAVE_SEQUENCE_IN - - If this bit is set, the :ctype:`PySequenceMethods` struct referenced by - :attr:`tp_as_sequence` has the :attr:`sq_contains` field. - - - .. data:: Py_TPFLAGS_GC - - This bit is obsolete. The bit it used to name is no longer in use. The symbol - is now defined as zero. - - - .. data:: Py_TPFLAGS_HAVE_INPLACEOPS - - If this bit is set, the :ctype:`PySequenceMethods` struct referenced by - :attr:`tp_as_sequence` and the :ctype:`PyNumberMethods` structure referenced by - :attr:`tp_as_number` contain the fields for in-place operators. In particular, - this means that the :ctype:`PyNumberMethods` structure has the fields - :attr:`nb_inplace_add`, :attr:`nb_inplace_subtract`, - :attr:`nb_inplace_multiply`, :attr:`nb_inplace_divide`, - :attr:`nb_inplace_remainder`, :attr:`nb_inplace_power`, - :attr:`nb_inplace_lshift`, :attr:`nb_inplace_rshift`, :attr:`nb_inplace_and`, - :attr:`nb_inplace_xor`, and :attr:`nb_inplace_or`; and the - :ctype:`PySequenceMethods` struct has the fields :attr:`sq_inplace_concat` and - :attr:`sq_inplace_repeat`. - - - .. data:: Py_TPFLAGS_HAVE_RICHCOMPARE - - If this bit is set, the type object has the :attr:`tp_richcompare` field, as - well as the :attr:`tp_traverse` and the :attr:`tp_clear` fields. - - - .. data:: Py_TPFLAGS_HAVE_WEAKREFS - - If this bit is set, the :attr:`tp_weaklistoffset` field is defined. Instances - of a type are weakly referenceable if the type's :attr:`tp_weaklistoffset` field - has a value greater than zero. - - - .. data:: Py_TPFLAGS_HAVE_ITER - - If this bit is set, the type object has the :attr:`tp_iter` and - :attr:`tp_iternext` fields. - - - .. data:: Py_TPFLAGS_HAVE_CLASS - - If this bit is set, the type object has several new fields defined starting in - Python 2.2: :attr:`tp_methods`, :attr:`tp_members`, :attr:`tp_getset`, - :attr:`tp_base`, :attr:`tp_dict`, :attr:`tp_descr_get`, :attr:`tp_descr_set`, - :attr:`tp_dictoffset`, :attr:`tp_init`, :attr:`tp_alloc`, :attr:`tp_new`, - :attr:`tp_free`, :attr:`tp_is_gc`, :attr:`tp_bases`, :attr:`tp_mro`, - :attr:`tp_cache`, :attr:`tp_subclasses`, and :attr:`tp_weaklist`. - - - .. data:: Py_TPFLAGS_HEAPTYPE - - This bit is set when the type object itself is allocated on the heap. In this - case, the :attr:`ob_type` field of its instances is considered a reference to - the type, and the type object is INCREF'ed when a new instance is created, and - DECREF'ed when an instance is destroyed (this does not apply to instances of - subtypes; only the type referenced by the instance's ob_type gets INCREF'ed or - DECREF'ed). - - - .. data:: Py_TPFLAGS_BASETYPE - - This bit is set when the type can be used as the base type of another type. If - this bit is clear, the type cannot be subtyped (similar to a "final" class in - Java). - - - .. data:: Py_TPFLAGS_READY - - This bit is set when the type object has been fully initialized by - :cfunc:`PyType_Ready`. - - - .. data:: Py_TPFLAGS_READYING - - This bit is set while :cfunc:`PyType_Ready` is in the process of initializing - the type object. - - - .. data:: Py_TPFLAGS_HAVE_GC - - This bit is set when the object supports garbage collection. If this bit - is set, instances must be created using :cfunc:`PyObject_GC_New` and - destroyed using :cfunc:`PyObject_GC_Del`. More information in section - :ref:`supporting-cycle-detection`. This bit also implies that the - GC-related fields :attr:`tp_traverse` and :attr:`tp_clear` are present in - the type object; but those fields also exist when - :const:`Py_TPFLAGS_HAVE_GC` is clear but - :const:`Py_TPFLAGS_HAVE_RICHCOMPARE` is set. - - - .. data:: Py_TPFLAGS_DEFAULT - - This is a bitmask of all the bits that pertain to the existence of certain - fields in the type object and its extension structures. Currently, it includes - the following bits: :const:`Py_TPFLAGS_HAVE_GETCHARBUFFER`, - :const:`Py_TPFLAGS_HAVE_SEQUENCE_IN`, :const:`Py_TPFLAGS_HAVE_INPLACEOPS`, - :const:`Py_TPFLAGS_HAVE_RICHCOMPARE`, :const:`Py_TPFLAGS_HAVE_WEAKREFS`, - :const:`Py_TPFLAGS_HAVE_ITER`, and :const:`Py_TPFLAGS_HAVE_CLASS`. - - -.. cmember:: char* PyTypeObject.tp_doc - - An optional pointer to a NUL-terminated C string giving the docstring for this - type object. This is exposed as the :attr:`__doc__` attribute on the type and - instances of the type. - - This field is *not* inherited by subtypes. - -The following three fields only exist if the -:const:`Py_TPFLAGS_HAVE_RICHCOMPARE` flag bit is set. - - -.. cmember:: traverseproc PyTypeObject.tp_traverse - - An optional pointer to a traversal function for the garbage collector. This is - only used if the :const:`Py_TPFLAGS_HAVE_GC` flag bit is set. More information - about Python's garbage collection scheme can be found in section - :ref:`supporting-cycle-detection`. - - The :attr:`tp_traverse` pointer is used by the garbage collector to detect - reference cycles. A typical implementation of a :attr:`tp_traverse` function - simply calls :cfunc:`Py_VISIT` on each of the instance's members that are Python - objects. For exampe, this is function :cfunc:`local_traverse` from the - :mod:`thread` extension module:: - - static int - local_traverse(localobject *self, visitproc visit, void *arg) - { - Py_VISIT(self->args); - Py_VISIT(self->kw); - Py_VISIT(self->dict); - return 0; - } - - Note that :cfunc:`Py_VISIT` is called only on those members that can participate - in reference cycles. Although there is also a ``self->key`` member, it can only - be *NULL* or a Python string and therefore cannot be part of a reference cycle. - - On the other hand, even if you know a member can never be part of a cycle, as a - debugging aid you may want to visit it anyway just so the :mod:`gc` module's - :func:`get_referents` function will include it. - - Note that :cfunc:`Py_VISIT` requires the *visit* and *arg* parameters to - :cfunc:`local_traverse` to have these specific names; don't name them just - anything. - - This field is inherited by subtypes together with :attr:`tp_clear` and the - :const:`Py_TPFLAGS_HAVE_GC` flag bit: the flag bit, :attr:`tp_traverse`, and - :attr:`tp_clear` are all inherited from the base type if they are all zero in - the subtype *and* the subtype has the :const:`Py_TPFLAGS_HAVE_RICHCOMPARE` flag - bit set. - - -.. cmember:: inquiry PyTypeObject.tp_clear - - An optional pointer to a clear function for the garbage collector. This is only - used if the :const:`Py_TPFLAGS_HAVE_GC` flag bit is set. - - The :attr:`tp_clear` member function is used to break reference cycles in cyclic - garbage detected by the garbage collector. Taken together, all :attr:`tp_clear` - functions in the system must combine to break all reference cycles. This is - subtle, and if in any doubt supply a :attr:`tp_clear` function. For example, - the tuple type does not implement a :attr:`tp_clear` function, because it's - possible to prove that no reference cycle can be composed entirely of tuples. - Therefore the :attr:`tp_clear` functions of other types must be sufficient to - break any cycle containing a tuple. This isn't immediately obvious, and there's - rarely a good reason to avoid implementing :attr:`tp_clear`. - - Implementations of :attr:`tp_clear` should drop the instance's references to - those of its members that may be Python objects, and set its pointers to those - members to *NULL*, as in the following example:: - - static int - local_clear(localobject *self) - { - Py_CLEAR(self->key); - Py_CLEAR(self->args); - Py_CLEAR(self->kw); - Py_CLEAR(self->dict); - return 0; - } - - The :cfunc:`Py_CLEAR` macro should be used, because clearing references is - delicate: the reference to the contained object must not be decremented until - after the pointer to the contained object is set to *NULL*. This is because - decrementing the reference count may cause the contained object to become trash, - triggering a chain of reclamation activity that may include invoking arbitrary - Python code (due to finalizers, or weakref callbacks, associated with the - contained object). If it's possible for such code to reference *self* again, - it's important that the pointer to the contained object be *NULL* at that time, - so that *self* knows the contained object can no longer be used. The - :cfunc:`Py_CLEAR` macro performs the operations in a safe order. - - Because the goal of :attr:`tp_clear` functions is to break reference cycles, - it's not necessary to clear contained objects like Python strings or Python - integers, which can't participate in reference cycles. On the other hand, it may - be convenient to clear all contained Python objects, and write the type's - :attr:`tp_dealloc` function to invoke :attr:`tp_clear`. - - More information about Python's garbage collection scheme can be found in - section :ref:`supporting-cycle-detection`. - - This field is inherited by subtypes together with :attr:`tp_traverse` and the - :const:`Py_TPFLAGS_HAVE_GC` flag bit: the flag bit, :attr:`tp_traverse`, and - :attr:`tp_clear` are all inherited from the base type if they are all zero in - the subtype *and* the subtype has the :const:`Py_TPFLAGS_HAVE_RICHCOMPARE` flag - bit set. - - -.. cmember:: richcmpfunc PyTypeObject.tp_richcompare - - An optional pointer to the rich comparison function. - - The signature is the same as for :cfunc:`PyObject_RichCompare`. The function - should return the result of the comparison (usually ``Py_True`` or - ``Py_False``). If the comparison is undefined, it must return - ``Py_NotImplemented``, if another error occurred it must return ``NULL`` and set - an exception condition. - - This field is inherited by subtypes together with :attr:`tp_compare` and - :attr:`tp_hash`: a subtype inherits all three of :attr:`tp_compare`, - :attr:`tp_richcompare`, and :attr:`tp_hash`, when the subtype's - :attr:`tp_compare`, :attr:`tp_richcompare`, and :attr:`tp_hash` are all *NULL*. - - The following constants are defined to be used as the third argument for - :attr:`tp_richcompare` and for :cfunc:`PyObject_RichCompare`: - - +----------------+------------+ - | Constant | Comparison | - +================+============+ - | :const:`Py_LT` | ``<`` | - +----------------+------------+ - | :const:`Py_LE` | ``<=`` | - +----------------+------------+ - | :const:`Py_EQ` | ``==`` | - +----------------+------------+ - | :const:`Py_NE` | ``!=`` | - +----------------+------------+ - | :const:`Py_GT` | ``>`` | - +----------------+------------+ - | :const:`Py_GE` | ``>=`` | - +----------------+------------+ - -The next field only exists if the :const:`Py_TPFLAGS_HAVE_WEAKREFS` flag bit is -set. - - -.. cmember:: long PyTypeObject.tp_weaklistoffset - - If the instances of this type are weakly referenceable, this field is greater - than zero and contains the offset in the instance structure of the weak - reference list head (ignoring the GC header, if present); this offset is used by - :cfunc:`PyObject_ClearWeakRefs` and the :cfunc:`PyWeakref_\*` functions. The - instance structure needs to include a field of type :ctype:`PyObject\*` which is - initialized to *NULL*. - - Do not confuse this field with :attr:`tp_weaklist`; that is the list head for - weak references to the type object itself. - - This field is inherited by subtypes, but see the rules listed below. A subtype - may override this offset; this means that the subtype uses a different weak - reference list head than the base type. Since the list head is always found via - :attr:`tp_weaklistoffset`, this should not be a problem. - - When a type defined by a class statement has no :attr:`__slots__` declaration, - and none of its base types are weakly referenceable, the type is made weakly - referenceable by adding a weak reference list head slot to the instance layout - and setting the :attr:`tp_weaklistoffset` of that slot's offset. - - When a type's :attr:`__slots__` declaration contains a slot named - :attr:`__weakref__`, that slot becomes the weak reference list head for - instances of the type, and the slot's offset is stored in the type's - :attr:`tp_weaklistoffset`. - - When a type's :attr:`__slots__` declaration does not contain a slot named - :attr:`__weakref__`, the type inherits its :attr:`tp_weaklistoffset` from its - base type. - -The next two fields only exist if the :const:`Py_TPFLAGS_HAVE_CLASS` flag bit is -set. - - -.. cmember:: getiterfunc PyTypeObject.tp_iter - - An optional pointer to a function that returns an iterator for the object. Its - presence normally signals that the instances of this type are iterable (although - sequences may be iterable without this function, and classic instances always - have this function, even if they don't define an :meth:`__iter__` method). - - This function has the same signature as :cfunc:`PyObject_GetIter`. - - This field is inherited by subtypes. - - -.. cmember:: iternextfunc PyTypeObject.tp_iternext - - An optional pointer to a function that returns the next item in an iterator, or - raises :exc:`StopIteration` when the iterator is exhausted. Its presence - normally signals that the instances of this type are iterators (although classic - instances always have this function, even if they don't define a - :meth:`__next__` method). - - Iterator types should also define the :attr:`tp_iter` function, and that - function should return the iterator instance itself (not a new iterator - instance). - - This function has the same signature as :cfunc:`PyIter_Next`. - - This field is inherited by subtypes. - -The next fields, up to and including :attr:`tp_weaklist`, only exist if the -:const:`Py_TPFLAGS_HAVE_CLASS` flag bit is set. - - -.. cmember:: struct PyMethodDef* PyTypeObject.tp_methods - - An optional pointer to a static *NULL*-terminated array of :ctype:`PyMethodDef` - structures, declaring regular methods of this type. - - For each entry in the array, an entry is added to the type's dictionary (see - :attr:`tp_dict` below) containing a method descriptor. - - This field is not inherited by subtypes (methods are inherited through a - different mechanism). - - -.. cmember:: struct PyMemberDef* PyTypeObject.tp_members - - An optional pointer to a static *NULL*-terminated array of :ctype:`PyMemberDef` - structures, declaring regular data members (fields or slots) of instances of - this type. - - For each entry in the array, an entry is added to the type's dictionary (see - :attr:`tp_dict` below) containing a member descriptor. - - This field is not inherited by subtypes (members are inherited through a - different mechanism). - - -.. cmember:: struct PyGetSetDef* PyTypeObject.tp_getset - - An optional pointer to a static *NULL*-terminated array of :ctype:`PyGetSetDef` - structures, declaring computed attributes of instances of this type. - - For each entry in the array, an entry is added to the type's dictionary (see - :attr:`tp_dict` below) containing a getset descriptor. - - This field is not inherited by subtypes (computed attributes are inherited - through a different mechanism). - - Docs for PyGetSetDef (XXX belong elsewhere):: - - typedef PyObject *(*getter)(PyObject *, void *); - typedef int (*setter)(PyObject *, PyObject *, void *); - - typedef struct PyGetSetDef { - char *name; /* attribute name */ - getter get; /* C function to get the attribute */ - setter set; /* C function to set the attribute */ - char *doc; /* optional doc string */ - void *closure; /* optional additional data for getter and setter */ - } PyGetSetDef; - - -.. cmember:: PyTypeObject* PyTypeObject.tp_base - - An optional pointer to a base type from which type properties are inherited. At - this level, only single inheritance is supported; multiple inheritance require - dynamically creating a type object by calling the metatype. - - This field is not inherited by subtypes (obviously), but it defaults to - ``&PyBaseObject_Type`` (which to Python programmers is known as the type - :class:`object`). - - -.. cmember:: PyObject* PyTypeObject.tp_dict - - The type's dictionary is stored here by :cfunc:`PyType_Ready`. - - This field should normally be initialized to *NULL* before PyType_Ready is - called; it may also be initialized to a dictionary containing initial attributes - for the type. Once :cfunc:`PyType_Ready` has initialized the type, extra - attributes for the type may be added to this dictionary only if they don't - correspond to overloaded operations (like :meth:`__add__`). - - This field is not inherited by subtypes (though the attributes defined in here - are inherited through a different mechanism). - - -.. cmember:: descrgetfunc PyTypeObject.tp_descr_get - - An optional pointer to a "descriptor get" function. - - The function signature is :: - - PyObject * tp_descr_get(PyObject *self, PyObject *obj, PyObject *type); - - XXX explain. - - This field is inherited by subtypes. - - -.. cmember:: descrsetfunc PyTypeObject.tp_descr_set - - An optional pointer to a "descriptor set" function. - - The function signature is :: - - int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value); - - This field is inherited by subtypes. - - XXX explain. - - -.. cmember:: long PyTypeObject.tp_dictoffset - - If the instances of this type have a dictionary containing instance variables, - this field is non-zero and contains the offset in the instances of the type of - the instance variable dictionary; this offset is used by - :cfunc:`PyObject_GenericGetAttr`. - - Do not confuse this field with :attr:`tp_dict`; that is the dictionary for - attributes of the type object itself. - - If the value of this field is greater than zero, it specifies the offset from - the start of the instance structure. If the value is less than zero, it - specifies the offset from the *end* of the instance structure. A negative - offset is more expensive to use, and should only be used when the instance - structure contains a variable-length part. This is used for example to add an - instance variable dictionary to subtypes of :class:`str` or :class:`tuple`. Note - that the :attr:`tp_basicsize` field should account for the dictionary added to - the end in that case, even though the dictionary is not included in the basic - object layout. On a system with a pointer size of 4 bytes, - :attr:`tp_dictoffset` should be set to ``-4`` to indicate that the dictionary is - at the very end of the structure. - - The real dictionary offset in an instance can be computed from a negative - :attr:`tp_dictoffset` as follows:: - - dictoffset = tp_basicsize + abs(ob_size)*tp_itemsize + tp_dictoffset - if dictoffset is not aligned on sizeof(void*): - round up to sizeof(void*) - - where :attr:`tp_basicsize`, :attr:`tp_itemsize` and :attr:`tp_dictoffset` are - taken from the type object, and :attr:`ob_size` is taken from the instance. The - absolute value is taken because long ints use the sign of :attr:`ob_size` to - store the sign of the number. (There's never a need to do this calculation - yourself; it is done for you by :cfunc:`_PyObject_GetDictPtr`.) - - This field is inherited by subtypes, but see the rules listed below. A subtype - may override this offset; this means that the subtype instances store the - dictionary at a difference offset than the base type. Since the dictionary is - always found via :attr:`tp_dictoffset`, this should not be a problem. - - When a type defined by a class statement has no :attr:`__slots__` declaration, - and none of its base types has an instance variable dictionary, a dictionary - slot is added to the instance layout and the :attr:`tp_dictoffset` is set to - that slot's offset. - - When a type defined by a class statement has a :attr:`__slots__` declaration, - the type inherits its :attr:`tp_dictoffset` from its base type. - - (Adding a slot named :attr:`__dict__` to the :attr:`__slots__` declaration does - not have the expected effect, it just causes confusion. Maybe this should be - added as a feature just like :attr:`__weakref__` though.) - - -.. cmember:: initproc PyTypeObject.tp_init - - An optional pointer to an instance initialization function. - - This function corresponds to the :meth:`__init__` method of classes. Like - :meth:`__init__`, it is possible to create an instance without calling - :meth:`__init__`, and it is possible to reinitialize an instance by calling its - :meth:`__init__` method again. - - The function signature is :: - - int tp_init(PyObject *self, PyObject *args, PyObject *kwds) - - The self argument is the instance to be initialized; the *args* and *kwds* - arguments represent positional and keyword arguments of the call to - :meth:`__init__`. - - The :attr:`tp_init` function, if not *NULL*, is called when an instance is - created normally by calling its type, after the type's :attr:`tp_new` function - has returned an instance of the type. If the :attr:`tp_new` function returns an - instance of some other type that is not a subtype of the original type, no - :attr:`tp_init` function is called; if :attr:`tp_new` returns an instance of a - subtype of the original type, the subtype's :attr:`tp_init` is called. (VERSION - NOTE: described here is what is implemented in Python 2.2.1 and later. In - Python 2.2, the :attr:`tp_init` of the type of the object returned by - :attr:`tp_new` was always called, if not *NULL*.) - - This field is inherited by subtypes. - - -.. cmember:: allocfunc PyTypeObject.tp_alloc - - An optional pointer to an instance allocation function. - - The function signature is :: - - PyObject *tp_alloc(PyTypeObject *self, Py_ssize_t nitems) - - The purpose of this function is to separate memory allocation from memory - initialization. It should return a pointer to a block of memory of adequate - length for the instance, suitably aligned, and initialized to zeros, but with - :attr:`ob_refcnt` set to ``1`` and :attr:`ob_type` set to the type argument. If - the type's :attr:`tp_itemsize` is non-zero, the object's :attr:`ob_size` field - should be initialized to *nitems* and the length of the allocated memory block - should be ``tp_basicsize + nitems*tp_itemsize``, rounded up to a multiple of - ``sizeof(void*)``; otherwise, *nitems* is not used and the length of the block - should be :attr:`tp_basicsize`. - - Do not use this function to do any other instance initialization, not even to - allocate additional memory; that should be done by :attr:`tp_new`. - - This field is inherited by static subtypes, but not by dynamic subtypes - (subtypes created by a class statement); in the latter, this field is always set - to :cfunc:`PyType_GenericAlloc`, to force a standard heap allocation strategy. - That is also the recommended value for statically defined types. - - -.. cmember:: newfunc PyTypeObject.tp_new - - An optional pointer to an instance creation function. - - If this function is *NULL* for a particular type, that type cannot be called to - create new instances; presumably there is some other way to create instances, - like a factory function. - - The function signature is :: - - PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) - - The subtype argument is the type of the object being created; the *args* and - *kwds* arguments represent positional and keyword arguments of the call to the - type. Note that subtype doesn't have to equal the type whose :attr:`tp_new` - function is called; it may be a subtype of that type (but not an unrelated - type). - - The :attr:`tp_new` function should call ``subtype->tp_alloc(subtype, nitems)`` - to allocate space for the object, and then do only as much further - initialization as is absolutely necessary. Initialization that can safely be - ignored or repeated should be placed in the :attr:`tp_init` handler. A good - rule of thumb is that for immutable types, all initialization should take place - in :attr:`tp_new`, while for mutable types, most initialization should be - deferred to :attr:`tp_init`. - - This field is inherited by subtypes, except it is not inherited by static types - whose :attr:`tp_base` is *NULL* or ``&PyBaseObject_Type``. The latter exception - is a precaution so that old extension types don't become callable simply by - being linked with Python 2.2. - - -.. cmember:: destructor PyTypeObject.tp_free - - An optional pointer to an instance deallocation function. - - The signature of this function has changed slightly: in Python 2.2 and 2.2.1, - its signature is :ctype:`destructor`:: - - void tp_free(PyObject *) - - In Python 2.3 and beyond, its signature is :ctype:`freefunc`:: - - void tp_free(void *) - - The only initializer that is compatible with both versions is ``PyObject_Free``, - whose definition has suitably adapted in Python 2.3. - - This field is inherited by static subtypes, but not by dynamic subtypes - (subtypes created by a class statement); in the latter, this field is set to a - deallocator suitable to match :cfunc:`PyType_GenericAlloc` and the value of the - :const:`Py_TPFLAGS_HAVE_GC` flag bit. - - -.. cmember:: inquiry PyTypeObject.tp_is_gc - - An optional pointer to a function called by the garbage collector. - - The garbage collector needs to know whether a particular object is collectible - or not. Normally, it is sufficient to look at the object's type's - :attr:`tp_flags` field, and check the :const:`Py_TPFLAGS_HAVE_GC` flag bit. But - some types have a mixture of statically and dynamically allocated instances, and - the statically allocated instances are not collectible. Such types should - define this function; it should return ``1`` for a collectible instance, and - ``0`` for a non-collectible instance. The signature is :: - - int tp_is_gc(PyObject *self) - - (The only example of this are types themselves. The metatype, - :cdata:`PyType_Type`, defines this function to distinguish between statically - and dynamically allocated types.) - - This field is inherited by subtypes. (VERSION NOTE: in Python 2.2, it was not - inherited. It is inherited in 2.2.1 and later versions.) - - -.. cmember:: PyObject* PyTypeObject.tp_bases - - Tuple of base types. - - This is set for types created by a class statement. It should be *NULL* for - statically defined types. - - This field is not inherited. - - -.. cmember:: PyObject* PyTypeObject.tp_mro - - Tuple containing the expanded set of base types, starting with the type itself - and ending with :class:`object`, in Method Resolution Order. - - This field is not inherited; it is calculated fresh by :cfunc:`PyType_Ready`. - - -.. cmember:: PyObject* PyTypeObject.tp_cache - - Unused. Not inherited. Internal use only. - - -.. cmember:: PyObject* PyTypeObject.tp_subclasses - - List of weak references to subclasses. Not inherited. Internal use only. - - -.. cmember:: PyObject* PyTypeObject.tp_weaklist - - Weak reference list head, for weak references to this type object. Not - inherited. Internal use only. - -The remaining fields are only defined if the feature test macro -:const:`COUNT_ALLOCS` is defined, and are for internal use only. They are -documented here for completeness. None of these fields are inherited by -subtypes. - - -.. cmember:: Py_ssize_t PyTypeObject.tp_allocs - - Number of allocations. - - -.. cmember:: Py_ssize_t PyTypeObject.tp_frees - - Number of frees. - - -.. cmember:: Py_ssize_t PyTypeObject.tp_maxalloc - - Maximum simultaneously allocated objects. - - -.. cmember:: PyTypeObject* PyTypeObject.tp_next - - Pointer to the next type object with a non-zero :attr:`tp_allocs` field. - -Also, note that, in a garbage collected Python, tp_dealloc may be called from -any Python thread, not just the thread which created the object (if the object -becomes part of a refcount cycle, that cycle might be collected by a garbage -collection on any thread). This is not a problem for Python API calls, since -the thread on which tp_dealloc is called will own the Global Interpreter Lock -(GIL). However, if the object being destroyed in turn destroys objects from some -other C or C++ library, care should be taken to ensure that destroying those -objects on the thread which called tp_dealloc will not violate any assumptions -of the library. - - -.. _number-structs: - -Number Object Structures -======================== - -.. sectionauthor:: Amaury Forgeot d'Arc - - -.. ctype:: PyNumberMethods - - This structure holds pointers to the functions which an object uses to - implement the number protocol. Each function is used by the function of - similar name documented in the :ref:`number` section. - - Here is the structure definition:: - - typedef struct { - binaryfunc nb_add; - binaryfunc nb_subtract; - binaryfunc nb_multiply; - binaryfunc nb_remainder; - binaryfunc nb_divmod; - ternaryfunc nb_power; - unaryfunc nb_negative; - unaryfunc nb_positive; - unaryfunc nb_absolute; - inquiry nb_bool; - unaryfunc nb_invert; - binaryfunc nb_lshift; - binaryfunc nb_rshift; - binaryfunc nb_and; - binaryfunc nb_xor; - binaryfunc nb_or; - int nb_reserved; /* unused, must be zero */ - unaryfunc nb_int; - unaryfunc nb_long; - unaryfunc nb_float; - - unaryfunc nb_oct; /* not used anymore, must be zero */ - unaryfunc nb_hex; /* not used anymore, must be zero */ - - binaryfunc nb_inplace_add; - binaryfunc nb_inplace_subtract; - binaryfunc nb_inplace_multiply; - binaryfunc nb_inplace_remainder; - ternaryfunc nb_inplace_power; - binaryfunc nb_inplace_lshift; - binaryfunc nb_inplace_rshift; - binaryfunc nb_inplace_and; - binaryfunc nb_inplace_xor; - binaryfunc nb_inplace_or; - - binaryfunc nb_floor_divide; - binaryfunc nb_true_divide; - binaryfunc nb_inplace_floor_divide; - binaryfunc nb_inplace_true_divide; - - unaryfunc nb_index; - } PyNumberMethods; - - .. note:: - - Binary and ternary functions must check the type of all their operands, - and implement the necessary conversions (at least one of the operands is - an instance of the defined type). If the operation is not defined for the - given operands, binary and ternary functions must return - ``Py_NotImplemented``, if another error occurred they must return ``NULL`` - and set an exception. - - -.. _mapping-structs: - -Mapping Object Structures -========================= - -.. sectionauthor:: Amaury Forgeot d'Arc - - -.. ctype:: PyMappingMethods - - This structure holds pointers to the functions which an object uses to - implement the mapping protocol. It has three members: - -.. cmember:: lenfunc PyMappingMethods.mp_length - - This function is used by :cfunc:`PyMapping_Length` and - :cfunc:`PyObject_Size`, and has the same signature. This slot may be set to - *NULL* if the object has no defined length. - -.. cmember:: binaryfunc PyMappingMethods.mp_subscript - - This function is used by :cfunc:`PyObject_GetItem` and has the same - signature. This slot must be filled for the :cfunc:`PyMapping_Check` - function to return ``1``, it can be *NULL* otherwise. - -.. cmember:: objobjargproc PyMappingMethods.mp_ass_subscript - - This function is used by :cfunc:`PyObject_SetItem` and has the same - signature. If this slot is *NULL*, the object does not support item - assignment. - - -.. _sequence-structs: - -Sequence Object Structures -========================== - -.. sectionauthor:: Amaury Forgeot d'Arc - - -.. ctype:: PySequenceMethods - - This structure holds pointers to the functions which an object uses to - implement the sequence protocol. - -.. cmember:: lenfunc PySequenceMethods.sq_length - - This function is used by :cfunc:`PySequence_Size` and :cfunc:`PyObject_Size`, - and has the same signature. - -.. cmember:: binaryfunc PySequenceMethods.sq_concat - - This function is used by :cfunc:`PySequence_Concat` and has the same - signature. It is also used by the ``+`` operator, after trying the numeric - addition via the :attr:`tp_as_number.nb_add` slot. - -.. cmember:: ssizeargfunc PySequenceMethods.sq_repeat - - This function is used by :cfunc:`PySequence_Repeat` and has the same - signature. It is also used by the ``*`` operator, after trying numeric - multiplication via the :attr:`tp_as_number.nb_mul` slot. - -.. cmember:: ssizeargfunc PySequenceMethods.sq_item - - This function is used by :cfunc:`PySequence_GetItem` and has the same - signature. This slot must be filled for the :cfunc:`PySequence_Check` - function to return ``1``, it can be *NULL* otherwise. - - Negative indexes are handled as follows: if the :attr:`sq_length` slot is - filled, it is called and the sequence length is used to compute a positive - index which is passed to :attr:`sq_item`. If :attr:`sq_length` is *NULL*, - the index is passed as is to the function. - -.. cmember:: ssizeobjargproc PySequenceMethods.sq_ass_item - - This function is used by :cfunc:`PySequence_SetItem` and has the same - signature. This slot may be left to *NULL* if the object does not support - item assignment. - -.. cmember:: objobjproc PySequenceMethods.sq_contains - - This function may be used by :cfunc:`PySequence_Contains` and has the same - signature. This slot may be left to *NULL*, in this case - :cfunc:`PySequence_Contains` simply traverses the sequence until it finds a - match. - -.. cmember:: binaryfunc PySequenceMethods.sq_inplace_concat - - This function is used by :cfunc:`PySequence_InPlaceConcat` and has the same - signature. It should modify its first operand, and return it. - -.. cmember:: ssizeargfunc PySequenceMethods.sq_inplace_repeat - - This function is used by :cfunc:`PySequence_InPlaceRepeat` and has the same - signature. It should modify its first operand, and return it. - -.. XXX need to explain precedence between mapping and sequence -.. XXX explains when to implement the sq_inplace_* slots - - -.. _buffer-structs: - -Buffer Object Structures -======================== - -.. sectionauthor:: Greg J. Stein - - -The buffer interface exports a model where an object can expose its internal -data as a set of chunks of data, where each chunk is specified as a -pointer/length pair. These chunks are called :dfn:`segments` and are presumed -to be non-contiguous in memory. - -If an object does not export the buffer interface, then its :attr:`tp_as_buffer` -member in the :ctype:`PyTypeObject` structure should be *NULL*. Otherwise, the -:attr:`tp_as_buffer` will point to a :ctype:`PyBufferProcs` structure. - -.. note:: - - It is very important that your :ctype:`PyTypeObject` structure uses - :const:`Py_TPFLAGS_DEFAULT` for the value of the :attr:`tp_flags` member rather - than ``0``. This tells the Python runtime that your :ctype:`PyBufferProcs` - structure contains the :attr:`bf_getcharbuffer` slot. Older versions of Python - did not have this member, so a new Python interpreter using an old extension - needs to be able to test for its presence before using it. - - -.. ctype:: PyBufferProcs - - Structure used to hold the function pointers which define an implementation of - the buffer protocol. - - The first slot is :attr:`bf_getreadbuffer`, of type :ctype:`getreadbufferproc`. - If this slot is *NULL*, then the object does not support reading from the - internal data. This is non-sensical, so implementors should fill this in, but - callers should test that the slot contains a non-*NULL* value. - - The next slot is :attr:`bf_getwritebuffer` having type - :ctype:`getwritebufferproc`. This slot may be *NULL* if the object does not - allow writing into its returned buffers. - - The third slot is :attr:`bf_getsegcount`, with type :ctype:`getsegcountproc`. - This slot must not be *NULL* and is used to inform the caller how many segments - the object contains. Simple objects such as :ctype:`PyString_Type` and - :ctype:`PyBuffer_Type` objects contain a single segment. - - .. index:: single: PyType_HasFeature() - - The last slot is :attr:`bf_getcharbuffer`, of type :ctype:`getcharbufferproc`. - This slot will only be present if the :const:`Py_TPFLAGS_HAVE_GETCHARBUFFER` - flag is present in the :attr:`tp_flags` field of the object's - :ctype:`PyTypeObject`. Before using this slot, the caller should test whether it - is present by using the :cfunc:`PyType_HasFeature` function. If the flag is - present, :attr:`bf_getcharbuffer` may be *NULL*, indicating that the object's - contents cannot be used as *8-bit characters*. The slot function may also raise - an error if the object's contents cannot be interpreted as 8-bit characters. - For example, if the object is an array which is configured to hold floating - point values, an exception may be raised if a caller attempts to use - :attr:`bf_getcharbuffer` to fetch a sequence of 8-bit characters. This notion of - exporting the internal buffers as "text" is used to distinguish between objects - that are binary in nature, and those which have character-based content. - - .. note:: - - The current policy seems to state that these characters may be multi-byte - characters. This implies that a buffer size of *N* does not mean there are *N* - characters present. - - -.. data:: Py_TPFLAGS_HAVE_GETCHARBUFFER - - Flag bit set in the type structure to indicate that the :attr:`bf_getcharbuffer` - slot is known. This being set does not indicate that the object supports the - buffer interface or that the :attr:`bf_getcharbuffer` slot is non-*NULL*. - - -.. ctype:: Py_ssize_t (*readbufferproc) (PyObject *self, Py_ssize_t segment, void **ptrptr) - - Return a pointer to a readable segment of the buffer in ``*ptrptr``. This - function is allowed to raise an exception, in which case it must return ``-1``. - The *segment* which is specified must be zero or positive, and strictly less - than the number of segments returned by the :attr:`bf_getsegcount` slot - function. On success, it returns the length of the segment, and sets - ``*ptrptr`` to a pointer to that memory. - - -.. ctype:: Py_ssize_t (*writebufferproc) (PyObject *self, Py_ssize_t segment, void **ptrptr) - - Return a pointer to a writable memory buffer in ``*ptrptr``, and the length of - that segment as the function return value. The memory buffer must correspond to - buffer segment *segment*. Must return ``-1`` and set an exception on error. - :exc:`TypeError` should be raised if the object only supports read-only buffers, - and :exc:`SystemError` should be raised when *segment* specifies a segment that - doesn't exist. - - .. Why doesn't it raise ValueError for this one? - GJS: because you shouldn't be calling it with an invalid - segment. That indicates a blatant programming error in the C code. - - -.. ctype:: Py_ssize_t (*segcountproc) (PyObject *self, Py_ssize_t *lenp) - - Return the number of memory segments which comprise the buffer. If *lenp* is - not *NULL*, the implementation must report the sum of the sizes (in bytes) of - all segments in ``*lenp``. The function cannot fail. - - -.. ctype:: Py_ssize_t (*charbufferproc) (PyObject *self, Py_ssize_t segment, const char **ptrptr) - - Return the size of the segment *segment* that *ptrptr* is set to. ``*ptrptr`` - is set to the memory buffer. Returns ``-1`` on error. - - -.. _supporting-iteration: - -Supporting the Iterator Protocol -================================ - - -.. _supporting-cycle-detection: - -Supporting Cyclic Garbage Collection -==================================== - -Python's support for detecting and collecting garbage which involves circular -references requires support from object types which are "containers" for other -objects which may also be containers. Types which do not store references to -other objects, or which only store references to atomic types (such as numbers -or strings), do not need to provide any explicit support for garbage collection. - -To create a container type, the :attr:`tp_flags` field of the type object must -include the :const:`Py_TPFLAGS_HAVE_GC` and provide an implementation of the -:attr:`tp_traverse` handler. If instances of the type are mutable, a -:attr:`tp_clear` implementation must also be provided. - - -.. data:: Py_TPFLAGS_HAVE_GC - - Objects with a type with this flag set must conform with the rules documented - here. For convenience these objects will be referred to as container objects. - -Constructors for container types must conform to two rules: - -#. The memory for the object must be allocated using :cfunc:`PyObject_GC_New` or - :cfunc:`PyObject_GC_VarNew`. - -#. Once all the fields which may contain references to other containers are - initialized, it must call :cfunc:`PyObject_GC_Track`. - - -.. cfunction:: TYPE* PyObject_GC_New(TYPE, PyTypeObject *type) - - Analogous to :cfunc:`PyObject_New` but for container objects with the - :const:`Py_TPFLAGS_HAVE_GC` flag set. - - -.. cfunction:: TYPE* PyObject_GC_NewVar(TYPE, PyTypeObject *type, Py_ssize_t size) - - Analogous to :cfunc:`PyObject_NewVar` but for container objects with the - :const:`Py_TPFLAGS_HAVE_GC` flag set. - - -.. cfunction:: PyVarObject * PyObject_GC_Resize(PyVarObject *op, Py_ssize_t) - - Resize an object allocated by :cfunc:`PyObject_NewVar`. Returns the resized - object or *NULL* on failure. - - -.. cfunction:: void PyObject_GC_Track(PyObject *op) - - Adds the object *op* to the set of container objects tracked by the collector. - The collector can run at unexpected times so objects must be valid while being - tracked. This should be called once all the fields followed by the - :attr:`tp_traverse` handler become valid, usually near the end of the - constructor. - - -.. cfunction:: void _PyObject_GC_TRACK(PyObject *op) - - A macro version of :cfunc:`PyObject_GC_Track`. It should not be used for - extension modules. - -Similarly, the deallocator for the object must conform to a similar pair of -rules: - -#. Before fields which refer to other containers are invalidated, - :cfunc:`PyObject_GC_UnTrack` must be called. - -#. The object's memory must be deallocated using :cfunc:`PyObject_GC_Del`. - - -.. cfunction:: void PyObject_GC_Del(void *op) - - Releases memory allocated to an object using :cfunc:`PyObject_GC_New` or - :cfunc:`PyObject_GC_NewVar`. - - -.. cfunction:: void PyObject_GC_UnTrack(void *op) - - Remove the object *op* from the set of container objects tracked by the - collector. Note that :cfunc:`PyObject_GC_Track` can be called again on this - object to add it back to the set of tracked objects. The deallocator - (:attr:`tp_dealloc` handler) should call this for the object before any of the - fields used by the :attr:`tp_traverse` handler become invalid. - - -.. cfunction:: void _PyObject_GC_UNTRACK(PyObject *op) - - A macro version of :cfunc:`PyObject_GC_UnTrack`. It should not be used for - extension modules. - -The :attr:`tp_traverse` handler accepts a function parameter of this type: - - -.. ctype:: int (*visitproc)(PyObject *object, void *arg) - - Type of the visitor function passed to the :attr:`tp_traverse` handler. The - function should be called with an object to traverse as *object* and the third - parameter to the :attr:`tp_traverse` handler as *arg*. The Python core uses - several visitor functions to implement cyclic garbage detection; it's not - expected that users will need to write their own visitor functions. - -The :attr:`tp_traverse` handler must have the following type: - - -.. ctype:: int (*traverseproc)(PyObject *self, visitproc visit, void *arg) - - Traversal function for a container object. Implementations must call the - *visit* function for each object directly contained by *self*, with the - parameters to *visit* being the contained object and the *arg* value passed to - the handler. The *visit* function must not be called with a *NULL* object - argument. If *visit* returns a non-zero value that value should be returned - immediately. - -To simplify writing :attr:`tp_traverse` handlers, a :cfunc:`Py_VISIT` macro is -provided. In order to use this macro, the :attr:`tp_traverse` implementation -must name its arguments exactly *visit* and *arg*: - - -.. cfunction:: void Py_VISIT(PyObject *o) - - Call the *visit* callback, with arguments *o* and *arg*. If *visit* returns a - non-zero value, then return it. Using this macro, :attr:`tp_traverse` handlers - look like:: - - static int - my_traverse(Noddy *self, visitproc visit, void *arg) - { - Py_VISIT(self->foo); - Py_VISIT(self->bar); - return 0; - } - -The :attr:`tp_clear` handler must be of the :ctype:`inquiry` type, or *NULL* if -the object is immutable. - - -.. ctype:: int (*inquiry)(PyObject *self) - - Drop references that may have created reference cycles. Immutable objects do - not have to define this method since they can never directly create reference - cycles. Note that the object must still be valid after calling this method - (don't just call :cfunc:`Py_DECREF` on a reference). The collector will call - this method if it detects that this object is involved in a reference cycle. - Modified: python/branches/py3k/Doc/library/optparse.rst ============================================================================== --- python/branches/py3k/Doc/library/optparse.rst (original) +++ python/branches/py3k/Doc/library/optparse.rst Sun Jan 20 10:06:41 2008 @@ -535,6 +535,35 @@ default value. If an option has no default value (or the default value is ``None``), ``%default`` expands to ``none``. +When dealing with many options, it is convenient to group these +options for better help output. An :class:`OptionParser` can contain +several option groups, each of which can contain several options. + +Continuing with the parser defined above, adding an +:class:`OptionGroup` to a parser is easy:: + + group = OptionGroup(parser, "Dangerous Options", + "Caution: use these options at your own risk. " + "It is believed that some of them bite.") + group.add_option("-g", action="store_true", help="Group option.") + parser.add_option_group(group) + +This would result in the following help output:: + + usage: [options] arg1 arg2 + + options: + -h, --help show this help message and exit + -v, --verbose make lots of noise [default] + -q, --quiet be vewwy quiet (I'm hunting wabbits) + -fFILE, --file=FILE write output to FILE + -mMODE, --mode=MODE interaction mode: one of 'novice', 'intermediate' + [default], 'expert' + + Dangerous Options: + Caution: use of these options is at your own risk. It is believed that + some of them bite. + -g Group option. .. _optparse-printing-version-string: Modified: python/branches/py3k/Doc/library/os.rst ============================================================================== --- python/branches/py3k/Doc/library/os.rst (original) +++ python/branches/py3k/Doc/library/os.rst Sun Jan 20 10:06:41 2008 @@ -378,6 +378,20 @@ :func:`fdopen`, use its :meth:`close` method. +.. function:: closerange(fd_low, fd_high) + + Close all file descriptors from *fd_low* (inclusive) to *fd_high* (exclusive), + ignoring errors. Availability: Macintosh, Unix, Windows. Equivalent to:: + + for fd in xrange(fd_low, fd_high): + try: + os.close(fd) + except OSError: + pass + + .. versionadded:: 2.6 + + .. function:: device_encoding(fd) Return a string describing the encoding of the device associated with *fd* Modified: python/branches/py3k/Doc/library/sqlite3.rst ============================================================================== --- python/branches/py3k/Doc/library/sqlite3.rst (original) +++ python/branches/py3k/Doc/library/sqlite3.rst Sun Jan 20 10:06:41 2008 @@ -1,4 +1,3 @@ - :mod:`sqlite3` --- DB-API 2.0 interface for SQLite databases ============================================================ @@ -387,7 +386,7 @@ .. method:: Cursor.execute(sql, [parameters]) - Executes a SQL statement. The SQL statement may be parametrized (i. e. + Executes an SQL statement. The SQL statement may be parametrized (i. e. placeholders instead of SQL literals). The :mod:`sqlite3` module supports two kinds of placeholders: question marks (qmark style) and named placeholders (named style). @@ -408,7 +407,7 @@ .. method:: Cursor.executemany(sql, seq_of_parameters) - Executes a SQL command against all parameter sequences or mappings found in + Executes an SQL command against all parameter sequences or mappings found in the sequence *sql*. The :mod:`sqlite3` module also allows using an :term:`iterator` yielding parameters instead of a sequence. @@ -432,6 +431,35 @@ .. literalinclude:: ../includes/sqlite3/executescript.py +.. method:: Cursor.fetchone() + + Fetches the next row of a query result set, returning a single sequence, + or ``None`` when no more data is available. + + +.. method:: Cursor.fetchmany([size=cursor.arraysize]) + + Fetches the next set of rows of a query result, returning a list. An empty + list is returned when no more rows are available. + + The number of rows to fetch per call is specified by the *size* parameter. + If it is not given, the cursor's arraysize determines the number of rows + to be fetched. The method should try to fetch as many rows as indicated by + the size parameter. If this is not possible due to the specified number of + rows not being available, fewer rows may be returned. + + Note there are performance considerations involved with the *size* parameter. + For optimal performance, it is usually best to use the arraysize attribute. + If the *size* parameter is used, then it is best for it to retain the same + value from one :meth:`fetchmany` call to the next. + +.. method:: Cursor.fetchall() + + Fetches all (remaining) rows of a query result, returning a list. Note that + the cursor's arraysize attribute can affect the performance of this operation. + An empty list is returned when no rows are available. + + .. attribute:: Cursor.rowcount Although the :class:`Cursor` class of the :mod:`sqlite3` module implements this Modified: python/branches/py3k/Doc/library/xml.sax.utils.rst ============================================================================== --- python/branches/py3k/Doc/library/xml.sax.utils.rst (original) +++ python/branches/py3k/Doc/library/xml.sax.utils.rst Sun Jan 20 10:06:41 2008 @@ -19,7 +19,8 @@ You can escape other strings of data by passing a dictionary as the optional *entities* parameter. The keys and values must all be strings; each key will be - replaced with its corresponding value. + replaced with its corresponding value. The characters ``'&'``, ``'<'`` and + ``'>'`` are always escaped, even if *entities* is provided. .. function:: unescape(data[, entities]) @@ -28,7 +29,8 @@ You can unescape other strings of data by passing a dictionary as the optional *entities* parameter. The keys and values must all be strings; each key will be - replaced with its corresponding value. + replaced with its corresponding value. ``'&'``, ``'<'``, and ``'>'`` + are always unescaped, even if *entities* is provided. .. function:: quoteattr(data[, entities]) Modified: python/branches/py3k/Doc/library/zipfile.rst ============================================================================== --- python/branches/py3k/Doc/library/zipfile.rst (original) +++ python/branches/py3k/Doc/library/zipfile.rst Sun Jan 20 10:06:41 2008 @@ -19,7 +19,8 @@ documentation). It can handle ZIP files that use the ZIP64 extensions (that is ZIP files that are more than 4 GByte in size). It supports decryption of encrypted files in ZIP archives, but it currently cannot -create an encrypted file. +create an encrypted file. Decryption is extremely slow as it is +implemented in native python rather than C. For other archive formats, see the :mod:`bz2`, :mod:`gzip`, and :mod:`tarfile` modules. Modified: python/branches/py3k/Doc/whatsnew/2.6.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/2.6.rst (original) +++ python/branches/py3k/Doc/whatsnew/2.6.rst Sun Jan 20 10:06:41 2008 @@ -868,16 +868,19 @@ .. Revision 57769 - * A new method in the :mod:`curses` module: for a window, :meth:`chgat` changes the display characters for a certain number of characters on a single line. + (Contributed by Fabian Kreutz.) :: # Boldface text starting at y=0,x=21 # and affecting the rest of the line. stdscr.chgat(0,21, curses.A_BOLD) - (Contributed by Fabian Kreutz.) + The :class:`Textbox` class in the :mod:`curses.textpad` module + now supports editing in insert mode as well as overwrite mode. + Insert mode is enabled by supplying a true value for the *insert_mode* + parameter when creating the :class:`Textbox` instance. * The :mod:`decimal` module was updated to version 1.66 of `the General Decimal Specification `__. New features Modified: python/branches/py3k/Lib/curses/textpad.py ============================================================================== --- python/branches/py3k/Lib/curses/textpad.py (original) +++ python/branches/py3k/Lib/curses/textpad.py Sun Jan 20 10:06:41 2008 @@ -39,8 +39,9 @@ KEY_LEFT = Ctrl-B, KEY_RIGHT = Ctrl-F, KEY_UP = Ctrl-P, KEY_DOWN = Ctrl-N KEY_BACKSPACE = Ctrl-h """ - def __init__(self, win): + def __init__(self, win, insert_mode=False): self.win = win + self.insert_mode = insert_mode (self.maxy, self.maxx) = win.getmaxyx() self.maxy = self.maxy - 1 self.maxx = self.maxx - 1 @@ -49,9 +50,10 @@ win.keypad(1) def _end_of_line(self, y): - "Go to the location of the first blank on the given line." + """Go to the location of the first blank on the given line, + returning the index of the last non-blank character.""" last = self.maxx - while 1: + while True: if ascii.ascii(self.win.inch(y, last)) != ascii.SP: last = min(self.maxx, last+1) break @@ -60,19 +62,31 @@ last = last - 1 return last + def _insert_printable_char(self, ch): + (y, x) = self.win.getyx() + if y < self.maxy or x < self.maxx: + if self.insert_mode: + oldch = self.win.inch() + # The try-catch ignores the error we trigger from some curses + # versions by trying to write into the lowest-rightmost spot + # in the window. + try: + self.win.addch(ch) + except curses.error: + pass + if self.insert_mode: + (backy, backx) = self.win.getyx() + if ascii.isprint(oldch): + self._insert_printable_char(oldch) + self.win.move(backy, backx) + def do_command(self, ch): "Process a single editing command." (y, x) = self.win.getyx() self.lastcmd = ch if ascii.isprint(ch): if y < self.maxy or x < self.maxx: - # The try-catch ignores the error we trigger from some curses - # versions by trying to write into the lowest-rightmost spot - # in the window. - try: - self.win.addch(ch) - except curses.error: - pass + self._insert_printable_char(ch) elif ch == ascii.SOH: # ^a self.win.move(y, 0) elif ch in (ascii.STX,curses.KEY_LEFT, ascii.BS,curses.KEY_BACKSPACE): @@ -139,7 +153,7 @@ if stop == 0 and self.stripspaces: continue for x in range(self.maxx+1): - if self.stripspaces and x == stop: + if self.stripspaces and x > stop: break result = result + chr(ascii.ascii(self.win.inch(y, x))) if self.maxy > 0: Modified: python/branches/py3k/Lib/mailbox.py ============================================================================== --- python/branches/py3k/Lib/mailbox.py (original) +++ python/branches/py3k/Lib/mailbox.py Sun Jan 20 10:06:41 2008 @@ -313,7 +313,10 @@ subpath = self._lookup(key) f = open(os.path.join(self._path, subpath), 'r') try: - msg = MaildirMessage(f) + if self._factory: + msg = self._factory(f) + else: + msg = MaildirMessage(f) finally: f.close() subdir, name = os.path.split(subpath) Modified: python/branches/py3k/Lib/subprocess.py ============================================================================== --- python/branches/py3k/Lib/subprocess.py (original) +++ python/branches/py3k/Lib/subprocess.py Sun Jan 20 10:06:41 2008 @@ -289,6 +289,7 @@ import io import os import traceback +import gc # Exception classes used by this module. class CalledProcessError(Exception): @@ -397,8 +398,8 @@ 2) A string surrounded by double quotation marks is interpreted as a single argument, regardless of white space - contained within. A quoted string can be embedded in an - argument. + or pipe characters contained within. A quoted string can be + embedded in an argument. 3) A double quotation mark preceded by a backslash is interpreted as a literal double quotation mark. @@ -424,7 +425,7 @@ if result: result.append(' ') - needquote = (" " in arg) or ("\t" in arg) or arg == "" + needquote = (" " in arg) or ("\t" in arg) or ("|" in arg) or not arg if needquote: result.append('"') @@ -433,7 +434,7 @@ # Don't know if we need to double yet. bs_buf.append(c) elif c == '"': - # Double backspaces. + # Double backslashes. result.append('\\' * len(bs_buf)*2) bs_buf = [] result.append('\\"') @@ -444,7 +445,7 @@ bs_buf = [] result.append(c) - # Add remaining backspaces, if any. + # Add remaining backslashes, if any. if bs_buf: result.extend(bs_buf) @@ -887,13 +888,8 @@ def _close_fds(self, but): - for i in range(3, MAXFD): - if i == but: - continue - try: - os.close(i) - except: - pass + os.closerange(3, but) + os.closerange(but + 1, MAXFD) def _execute_child(self, args, executable, preexec_fn, close_fds, @@ -921,7 +917,16 @@ errpipe_read, errpipe_write = os.pipe() self._set_cloexec_flag(errpipe_write) - self.pid = os.fork() + gc_was_enabled = gc.isenabled() + # Disable gc to avoid bug where gc -> file_dealloc -> + # write to stderr -> hang. http://bugs.python.org/issue1336 + gc.disable() + try: + self.pid = os.fork() + except: + if gc_was_enabled: + gc.enable() + raise self._child_created = True if self.pid == 0: # Child @@ -982,6 +987,8 @@ os._exit(255) # Parent + if gc_was_enabled: + gc.enable() os.close(errpipe_write) if p2cread is not None and p2cwrite is not None: os.close(p2cread) Modified: python/branches/py3k/Lib/test/test_mailbox.py ============================================================================== --- python/branches/py3k/Lib/test/test_mailbox.py (original) +++ python/branches/py3k/Lib/test/test_mailbox.py Sun Jan 20 10:06:41 2008 @@ -506,6 +506,20 @@ self.assertEqual(msg_returned.get_flags(), 'S') self.assertEqual(msg_returned.get_payload(), '3') + def test_consistent_factory(self): + # Add a message. + msg = mailbox.MaildirMessage(self._template % 0) + msg.set_subdir('cur') + msg.set_flags('RF') + key = self._box.add(msg) + + # Create new mailbox with + class FakeMessage(mailbox.MaildirMessage): + pass + box = mailbox.Maildir(self._path, factory=FakeMessage) + msg2 = box.get_message(key) + self.assert_(isinstance(msg2, FakeMessage)) + def test_initialize_new(self): # Initialize a non-existent mailbox self.tearDown() Modified: python/branches/py3k/Lib/test/test_os.py ============================================================================== --- python/branches/py3k/Lib/test/test_os.py (original) +++ python/branches/py3k/Lib/test/test_os.py Sun Jan 20 10:06:41 2008 @@ -20,6 +20,11 @@ os.close(f) self.assert_(os.access(test_support.TESTFN, os.W_OK)) + def test_closerange(self): + f = os.open(test_support.TESTFN, os.O_CREAT|os.O_RDWR) + # close a fd that is open, and one that isn't + os.closerange(f, f+2) + self.assertRaises(OSError, os.write, f, "a") # Test attributes on return values from os.*stat* family. class StatAttributeTests(unittest.TestCase): Modified: python/branches/py3k/Lib/test/test_subprocess.py ============================================================================== --- python/branches/py3k/Lib/test/test_subprocess.py (original) +++ python/branches/py3k/Lib/test/test_subprocess.py Sun Jan 20 10:06:41 2008 @@ -413,6 +413,8 @@ '"a b c" d e') self.assertEqual(subprocess.list2cmdline(['ab"c', '\\', 'd']), 'ab\\"c \\ d') + self.assertEqual(subprocess.list2cmdline(['ab"c', ' \\', 'd']), + 'ab\\"c " \\\\" d') self.assertEqual(subprocess.list2cmdline(['a\\\\\\b', 'de fg', 'h']), 'a\\\\\\b "de fg" h') self.assertEqual(subprocess.list2cmdline(['a\\"b', 'c', 'd']), @@ -423,6 +425,8 @@ '"a\\\\b\\ c" d e') self.assertEqual(subprocess.list2cmdline(['ab', '']), 'ab ""') + self.assertEqual(subprocess.list2cmdline(['echo', 'foo|bar']), + 'echo "foo|bar"') def test_poll(self): Modified: python/branches/py3k/Lib/test/test_zipfile.py ============================================================================== --- python/branches/py3k/Lib/test/test_zipfile.py (original) +++ python/branches/py3k/Lib/test/test_zipfile.py Sun Jan 20 10:06:41 2008 @@ -686,31 +686,52 @@ b'\x1a\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x01\x00 \x00\xb6\x81' b'\x00\x00\x00\x00test.txtPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x006\x00' b'\x00\x00L\x00\x00\x00\x00\x00' ) + data2 = ( + b'PK\x03\x04\x14\x00\t\x00\x08\x00\xcf}38xu\xaa\xb2\x14\x00\x00\x00\x00\x02' + b'\x00\x00\x04\x00\x15\x00zeroUT\t\x00\x03\xd6\x8b\x92G\xda\x8b\x92GUx\x04' + b'\x00\xe8\x03\xe8\x03\xc7>9)+1980, (d>>5)&0xF, d&0x1F, t>>11, (t>>5)&0x3F, (t&0x1F) * 2 ) @@ -800,11 +802,18 @@ # The first 12 bytes in the cypher stream is an encryption header # used to strengthen the algorithm. The first 11 bytes are # completely random, while the 12th contains the MSB of the CRC, + # or the MSB of the file time depending on the header type # and is used to check the correctness of the password. bytes = zef_file.read(12) h = list(map(zd, bytes[0:12])) - if h[11] != ((zinfo.CRC>>24) & 255): - raise RuntimeError("Bad password for file %s" % name) + if zinfo.flag_bits & 0x8: + # compare against the file type from extended local headers + check_byte = (zinfo._raw_time >> 8) & 0xff + else: + # compare against the CRC otherwise + check_byte = (zinfo.CRC >> 24) & 0xff + if h[11] != check_byte: + raise RuntimeError("Bad password for file", name) # build and return a ZipExtFile if zd is None: Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Sun Jan 20 10:06:41 2008 @@ -593,6 +593,7 @@ Sam Schulenburg Stefan Schwarzer Dietmar Schwertberger +Federico Schwindt Barry Scott Steven Scott Nick Seidenman @@ -701,6 +702,7 @@ Aaron Watters Henrik Weber Corran Webster +Stefan Wehr Zack Weinberg Edward Welbourne Cliff Wells Modified: python/branches/py3k/Modules/_sqlite/cursor.c ============================================================================== --- python/branches/py3k/Modules/_sqlite/cursor.c (original) +++ python/branches/py3k/Modules/_sqlite/cursor.c Sun Jan 20 10:06:41 2008 @@ -973,11 +973,11 @@ {"executescript", (PyCFunction)pysqlite_cursor_executescript, METH_VARARGS, PyDoc_STR("Executes a multiple SQL statements at once. Non-standard.")}, {"fetchone", (PyCFunction)pysqlite_cursor_fetchone, METH_NOARGS, - PyDoc_STR("Fetches several rows from the resultset.")}, + PyDoc_STR("Fetches one row from the resultset.")}, {"fetchmany", (PyCFunction)pysqlite_cursor_fetchmany, METH_VARARGS, - PyDoc_STR("Fetches all rows from the resultset.")}, + PyDoc_STR("Fetches several rows from the resultset.")}, {"fetchall", (PyCFunction)pysqlite_cursor_fetchall, METH_NOARGS, - PyDoc_STR("Fetches one row from the resultset.")}, + PyDoc_STR("Fetches all rows from the resultset.")}, {"close", (PyCFunction)pysqlite_cursor_close, METH_NOARGS, PyDoc_STR("Closes the cursor.")}, {"setinputsizes", (PyCFunction)pysqlite_noop, METH_VARARGS, Modified: python/branches/py3k/Modules/posixmodule.c ============================================================================== --- python/branches/py3k/Modules/posixmodule.c (original) +++ python/branches/py3k/Modules/posixmodule.c Sun Jan 20 10:06:41 2008 @@ -4716,6 +4716,24 @@ } +PyDoc_STRVAR(posix_closerange__doc__, +"closerange(fd_low, fd_high)\n\n\ +Closes all file descriptors in [fd_low, fd_high), ignoring errors."); + +static PyObject * +posix_closerange(PyObject *self, PyObject *args) +{ + int fd_from, fd_to, i; + if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to)) + return NULL; + Py_BEGIN_ALLOW_THREADS + for (i = fd_from; i < fd_to; i++) + close(i); + Py_END_ALLOW_THREADS + Py_RETURN_NONE; +} + + PyDoc_STRVAR(posix_dup__doc__, "dup(fd) -> fd2\n\n\ Return a duplicate of a file descriptor."); @@ -6919,6 +6937,7 @@ #endif /* HAVE_TCSETPGRP */ {"open", posix_open, METH_VARARGS, posix_open__doc__}, {"close", posix_close, METH_VARARGS, posix_close__doc__}, + {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__}, {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__}, {"dup", posix_dup, METH_VARARGS, posix_dup__doc__}, {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__}, Modified: python/branches/py3k/Modules/socketmodule.c ============================================================================== --- python/branches/py3k/Modules/socketmodule.c (original) +++ python/branches/py3k/Modules/socketmodule.c Sun Jan 20 10:06:41 2008 @@ -1904,15 +1904,22 @@ #else if (s->sock_timeout > 0.0) { - if (res < 0 && errno == EINPROGRESS && IS_SELECTABLE(s)) { - timeout = internal_select(s, 1); - if (timeout == 0) { - res = connect(s->sock_fd, addr, addrlen); - if (res < 0 && errno == EISCONN) - res = 0; - } - else if (timeout == -1) - res = errno; /* had error */ + if (res < 0 && errno == EINPROGRESS && IS_SELECTABLE(s)) { + timeout = internal_select(s, 1); + if (timeout == 0) { + /* Bug #1019808: in case of an EINPROGRESS, + use getsockopt(SO_ERROR) to get the real + error. */ + socklen_t res_size = sizeof res; + (void)getsockopt(s->sock_fd, SOL_SOCKET, + SO_ERROR, &res, &res_size); + if (res == EISCONN) + res = 0; + errno = res; + } + else if (timeout == -1) { + res = errno; /* had error */ + } else res = EWOULDBLOCK; /* timed out */ } From python-3000-checkins at python.org Sun Jan 20 10:11:31 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sun, 20 Jan 2008 10:11:31 +0100 (CET) Subject: [Python-3000-checkins] r60125 - python/branches/py3k/Doc/library/os.rst Message-ID: <20080120091131.3A08B1E401B@bag.python.org> Author: georg.brandl Date: Sun Jan 20 10:11:30 2008 New Revision: 60125 Modified: python/branches/py3k/Doc/library/os.rst Log: Remove versionadded tag. Modified: python/branches/py3k/Doc/library/os.rst ============================================================================== --- python/branches/py3k/Doc/library/os.rst (original) +++ python/branches/py3k/Doc/library/os.rst Sun Jan 20 10:11:30 2008 @@ -389,8 +389,6 @@ except OSError: pass - .. versionadded:: 2.6 - .. function:: device_encoding(fd) From python-3000-checkins at python.org Sun Jan 20 10:31:00 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sun, 20 Jan 2008 10:31:00 +0100 (CET) Subject: [Python-3000-checkins] r60126 - python/branches/py3k/Doc/c-api/abstract.rst python/branches/py3k/Doc/c-api/allocation.rst python/branches/py3k/Doc/c-api/arg.rst python/branches/py3k/Doc/c-api/bool.rst python/branches/py3k/Doc/c-api/buffer.rst python/branches/py3k/Doc/c-api/cell.rst python/branches/py3k/Doc/c-api/cobject.rst python/branches/py3k/Doc/c-api/complex.rst python/branches/py3k/Doc/c-api/concrete.rst python/branches/py3k/Doc/c-api/conversion.rst python/branches/py3k/Doc/c-api/datetime.rst python/branches/py3k/Doc/c-api/descriptor.rst python/branches/py3k/Doc/c-api/dict.rst python/branches/py3k/Doc/c-api/file.rst python/branches/py3k/Doc/c-api/float.rst python/branches/py3k/Doc/c-api/function.rst python/branches/py3k/Doc/c-api/gcsupport.rst python/branches/py3k/Doc/c-api/gen.rst python/branches/py3k/Doc/c-api/import.rst python/branches/py3k/Doc/c-api/iter.rst python/branches/py3k/Doc/c-api/iterator.rst python/branches/py3k/Doc/c-api/list.rst python/branches/py3k/Doc/c-api/long.rst python/branches/py3k/Doc/c-api/mapping.rst python/branches/py3k/Doc/c-api/marshal.rst python/branches/py3k/Doc/c-api/method.rst python/branches/py3k/Doc/c-api/module.rst python/branches/py3k/Doc/c-api/none.rst python/branches/py3k/Doc/c-api/number.rst python/branches/py3k/Doc/c-api/objbuffer.rst python/branches/py3k/Doc/c-api/object.rst python/branches/py3k/Doc/c-api/objimpl.rst python/branches/py3k/Doc/c-api/reflection.rst python/branches/py3k/Doc/c-api/sequence.rst python/branches/py3k/Doc/c-api/set.rst python/branches/py3k/Doc/c-api/slice.rst python/branches/py3k/Doc/c-api/string.rst python/branches/py3k/Doc/c-api/structures.rst python/branches/py3k/Doc/c-api/sys.rst python/branches/py3k/Doc/c-api/tuple.rst python/branches/py3k/Doc/c-api/type.rst python/branches/py3k/Doc/c-api/typeobj.rst python/branches/py3k/Doc/c-api/unicode.rst python/branches/py3k/Doc/c-api/utilities.rst python/branches/py3k/Doc/c-api/weakref.rst Message-ID: <20080120093100.0FA3A1E401B@bag.python.org> Author: georg.brandl Date: Sun Jan 20 10:30:57 2008 New Revision: 60126 Added: python/branches/py3k/Doc/c-api/allocation.rst python/branches/py3k/Doc/c-api/arg.rst python/branches/py3k/Doc/c-api/bool.rst python/branches/py3k/Doc/c-api/buffer.rst python/branches/py3k/Doc/c-api/cell.rst python/branches/py3k/Doc/c-api/cobject.rst python/branches/py3k/Doc/c-api/complex.rst python/branches/py3k/Doc/c-api/conversion.rst python/branches/py3k/Doc/c-api/datetime.rst python/branches/py3k/Doc/c-api/descriptor.rst python/branches/py3k/Doc/c-api/dict.rst python/branches/py3k/Doc/c-api/file.rst python/branches/py3k/Doc/c-api/float.rst python/branches/py3k/Doc/c-api/function.rst python/branches/py3k/Doc/c-api/gcsupport.rst python/branches/py3k/Doc/c-api/gen.rst python/branches/py3k/Doc/c-api/import.rst python/branches/py3k/Doc/c-api/iter.rst python/branches/py3k/Doc/c-api/iterator.rst python/branches/py3k/Doc/c-api/list.rst python/branches/py3k/Doc/c-api/long.rst python/branches/py3k/Doc/c-api/mapping.rst python/branches/py3k/Doc/c-api/marshal.rst python/branches/py3k/Doc/c-api/method.rst python/branches/py3k/Doc/c-api/module.rst python/branches/py3k/Doc/c-api/none.rst python/branches/py3k/Doc/c-api/number.rst python/branches/py3k/Doc/c-api/objbuffer.rst python/branches/py3k/Doc/c-api/object.rst python/branches/py3k/Doc/c-api/objimpl.rst python/branches/py3k/Doc/c-api/reflection.rst python/branches/py3k/Doc/c-api/sequence.rst python/branches/py3k/Doc/c-api/set.rst python/branches/py3k/Doc/c-api/slice.rst python/branches/py3k/Doc/c-api/string.rst python/branches/py3k/Doc/c-api/structures.rst python/branches/py3k/Doc/c-api/sys.rst python/branches/py3k/Doc/c-api/tuple.rst python/branches/py3k/Doc/c-api/type.rst python/branches/py3k/Doc/c-api/typeobj.rst python/branches/py3k/Doc/c-api/unicode.rst python/branches/py3k/Doc/c-api/weakref.rst Modified: python/branches/py3k/Doc/c-api/abstract.rst python/branches/py3k/Doc/c-api/concrete.rst python/branches/py3k/Doc/c-api/utilities.rst Log: Split C API docs in Py3k branch. Modified: python/branches/py3k/Doc/c-api/abstract.rst ============================================================================== --- python/branches/py3k/Doc/c-api/abstract.rst (original) +++ python/branches/py3k/Doc/c-api/abstract.rst Sun Jan 20 10:30:57 2008 @@ -1,6 +1,5 @@ .. highlightlang:: c - .. _abstract: ********************** @@ -16,928 +15,11 @@ initialized, such as a list object that has been created by :cfunc:`PyList_New`, but whose items have not been set to some non-\ ``NULL`` value yet. +.. toctree:: -.. _object: - -Object Protocol -=============== - - -.. cfunction:: int PyObject_Print(PyObject *o, FILE *fp, int flags) - - Print an object *o*, on file *fp*. Returns ``-1`` on error. The flags argument - is used to enable certain printing options. The only option currently supported - is :const:`Py_PRINT_RAW`; if given, the :func:`str` of the object is written - instead of the :func:`repr`. - - -.. cfunction:: int PyObject_HasAttr(PyObject *o, PyObject *attr_name) - - Returns ``1`` if *o* has the attribute *attr_name*, and ``0`` otherwise. This - is equivalent to the Python expression ``hasattr(o, attr_name)``. This function - always succeeds. - - -.. cfunction:: int PyObject_HasAttrString(PyObject *o, const char *attr_name) - - Returns ``1`` if *o* has the attribute *attr_name*, and ``0`` otherwise. This - is equivalent to the Python expression ``hasattr(o, attr_name)``. This function - always succeeds. - - -.. cfunction:: PyObject* PyObject_GetAttr(PyObject *o, PyObject *attr_name) - - Retrieve an attribute named *attr_name* from object *o*. Returns the attribute - value on success, or *NULL* on failure. This is the equivalent of the Python - expression ``o.attr_name``. - - -.. cfunction:: PyObject* PyObject_GetAttrString(PyObject *o, const char *attr_name) - - Retrieve an attribute named *attr_name* from object *o*. Returns the attribute - value on success, or *NULL* on failure. This is the equivalent of the Python - expression ``o.attr_name``. - - -.. cfunction:: int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v) - - Set the value of the attribute named *attr_name*, for object *o*, to the value - *v*. Returns ``-1`` on failure. This is the equivalent of the Python statement - ``o.attr_name = v``. - - -.. cfunction:: int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v) - - Set the value of the attribute named *attr_name*, for object *o*, to the value - *v*. Returns ``-1`` on failure. This is the equivalent of the Python statement - ``o.attr_name = v``. - - -.. cfunction:: int PyObject_DelAttr(PyObject *o, PyObject *attr_name) - - Delete attribute named *attr_name*, for object *o*. Returns ``-1`` on failure. - This is the equivalent of the Python statement ``del o.attr_name``. - - -.. cfunction:: int PyObject_DelAttrString(PyObject *o, const char *attr_name) - - Delete attribute named *attr_name*, for object *o*. Returns ``-1`` on failure. - This is the equivalent of the Python statement ``del o.attr_name``. - - -.. cfunction:: PyObject* PyObject_RichCompare(PyObject *o1, PyObject *o2, int opid) - - Compare the values of *o1* and *o2* using the operation specified by *opid*, - which must be one of :const:`Py_LT`, :const:`Py_LE`, :const:`Py_EQ`, - :const:`Py_NE`, :const:`Py_GT`, or :const:`Py_GE`, corresponding to ``<``, - ``<=``, ``==``, ``!=``, ``>``, or ``>=`` respectively. This is the equivalent of - the Python expression ``o1 op o2``, where ``op`` is the operator corresponding - to *opid*. Returns the value of the comparison on success, or *NULL* on failure. - - -.. cfunction:: int PyObject_RichCompareBool(PyObject *o1, PyObject *o2, int opid) - - Compare the values of *o1* and *o2* using the operation specified by *opid*, - which must be one of :const:`Py_LT`, :const:`Py_LE`, :const:`Py_EQ`, - :const:`Py_NE`, :const:`Py_GT`, or :const:`Py_GE`, corresponding to ``<``, - ``<=``, ``==``, ``!=``, ``>``, or ``>=`` respectively. Returns ``-1`` on error, - ``0`` if the result is false, ``1`` otherwise. This is the equivalent of the - Python expression ``o1 op o2``, where ``op`` is the operator corresponding to - *opid*. - - -.. cfunction:: int PyObject_Cmp(PyObject *o1, PyObject *o2, int *result) - - .. index:: builtin: cmp - - Compare the values of *o1* and *o2* using a routine provided by *o1*, if one - exists, otherwise with a routine provided by *o2*. The result of the comparison - is returned in *result*. Returns ``-1`` on failure. This is the equivalent of - the Python statement ``result = cmp(o1, o2)``. - - -.. cfunction:: int PyObject_Compare(PyObject *o1, PyObject *o2) - - .. index:: builtin: cmp - - Compare the values of *o1* and *o2* using a routine provided by *o1*, if one - exists, otherwise with a routine provided by *o2*. Returns the result of the - comparison on success. On error, the value returned is undefined; use - :cfunc:`PyErr_Occurred` to detect an error. This is equivalent to the Python - expression ``cmp(o1, o2)``. - - -.. cfunction:: PyObject* PyObject_Repr(PyObject *o) - - .. index:: builtin: repr - - Compute a string representation of object *o*. Returns the string - representation on success, *NULL* on failure. This is the equivalent of the - Python expression ``repr(o)``. Called by the :func:`repr` built-in function and - by reverse quotes. - - -.. cfunction:: PyObject* PyObject_Str(PyObject *o) - - .. index:: builtin: str - - Compute a string representation of object *o*. Returns the string - representation on success, *NULL* on failure. This is the equivalent of the - Python expression ``str(o)``. Called by the :func:`str` built-in function - and, therefore, by the :func:`print` function. - - -.. cfunction:: PyObject* PyObject_Unicode(PyObject *o) - - .. index:: builtin: unicode - - Compute a Unicode string representation of object *o*. Returns the Unicode - string representation on success, *NULL* on failure. This is the equivalent of - the Python expression ``unicode(o)``. Called by the :func:`unicode` built-in - function. - - -.. cfunction:: int PyObject_IsInstance(PyObject *inst, PyObject *cls) - - Returns ``1`` if *inst* is an instance of the class *cls* or a subclass of - *cls*, or ``0`` if not. On error, returns ``-1`` and sets an exception. If - *cls* is a type object rather than a class object, :cfunc:`PyObject_IsInstance` - returns ``1`` if *inst* is of type *cls*. If *cls* is a tuple, the check will - be done against every entry in *cls*. The result will be ``1`` when at least one - of the checks returns ``1``, otherwise it will be ``0``. If *inst* is not a - class instance and *cls* is neither a type object, nor a class object, nor a - tuple, *inst* must have a :attr:`__class__` attribute --- the class relationship - of the value of that attribute with *cls* will be used to determine the result - of this function. - - -Subclass determination is done in a fairly straightforward way, but includes a -wrinkle that implementors of extensions to the class system may want to be aware -of. If :class:`A` and :class:`B` are class objects, :class:`B` is a subclass of -:class:`A` if it inherits from :class:`A` either directly or indirectly. If -either is not a class object, a more general mechanism is used to determine the -class relationship of the two objects. When testing if *B* is a subclass of -*A*, if *A* is *B*, :cfunc:`PyObject_IsSubclass` returns true. If *A* and *B* -are different objects, *B*'s :attr:`__bases__` attribute is searched in a -depth-first fashion for *A* --- the presence of the :attr:`__bases__` attribute -is considered sufficient for this determination. - - -.. cfunction:: int PyObject_IsSubclass(PyObject *derived, PyObject *cls) - - Returns ``1`` if the class *derived* is identical to or derived from the class - *cls*, otherwise returns ``0``. In case of an error, returns ``-1``. If *cls* - is a tuple, the check will be done against every entry in *cls*. The result will - be ``1`` when at least one of the checks returns ``1``, otherwise it will be - ``0``. If either *derived* or *cls* is not an actual class object (or tuple), - this function uses the generic algorithm described above. - - -.. cfunction:: int PyCallable_Check(PyObject *o) - - Determine if the object *o* is callable. Return ``1`` if the object is callable - and ``0`` otherwise. This function always succeeds. - - -.. cfunction:: PyObject* PyObject_Call(PyObject *callable_object, PyObject *args, PyObject *kw) - - Call a callable Python object *callable_object*, with arguments given by the - tuple *args*, and named arguments given by the dictionary *kw*. If no named - arguments are needed, *kw* may be *NULL*. *args* must not be *NULL*, use an - empty tuple if no arguments are needed. Returns the result of the call on - success, or *NULL* on failure. This is the equivalent of the Python expression - ``callable_object(*args, **kw)``. - - -.. cfunction:: PyObject* PyObject_CallObject(PyObject *callable_object, PyObject *args) - - Call a callable Python object *callable_object*, with arguments given by the - tuple *args*. If no arguments are needed, then *args* may be *NULL*. Returns - the result of the call on success, or *NULL* on failure. This is the equivalent - of the Python expression ``callable_object(*args)``. - - -.. cfunction:: PyObject* PyObject_CallFunction(PyObject *callable, char *format, ...) - - Call a callable Python object *callable*, with a variable number of C arguments. - The C arguments are described using a :cfunc:`Py_BuildValue` style format - string. The format may be *NULL*, indicating that no arguments are provided. - Returns the result of the call on success, or *NULL* on failure. This is the - equivalent of the Python expression ``callable(*args)``. Note that if you only - pass :ctype:`PyObject \*` args, :cfunc:`PyObject_CallFunctionObjArgs` is a - faster alternative. - - -.. cfunction:: PyObject* PyObject_CallMethod(PyObject *o, char *method, char *format, ...) - - Call the method named *method* of object *o* with a variable number of C - arguments. The C arguments are described by a :cfunc:`Py_BuildValue` format - string that should produce a tuple. The format may be *NULL*, indicating that - no arguments are provided. Returns the result of the call on success, or *NULL* - on failure. This is the equivalent of the Python expression ``o.method(args)``. - Note that if you only pass :ctype:`PyObject \*` args, - :cfunc:`PyObject_CallMethodObjArgs` is a faster alternative. - - -.. cfunction:: PyObject* PyObject_CallFunctionObjArgs(PyObject *callable, ..., NULL) - - Call a callable Python object *callable*, with a variable number of - :ctype:`PyObject\*` arguments. The arguments are provided as a variable number - of parameters followed by *NULL*. Returns the result of the call on success, or - *NULL* on failure. - - -.. cfunction:: PyObject* PyObject_CallMethodObjArgs(PyObject *o, PyObject *name, ..., NULL) - - Calls a method of the object *o*, where the name of the method is given as a - Python string object in *name*. It is called with a variable number of - :ctype:`PyObject\*` arguments. The arguments are provided as a variable number - of parameters followed by *NULL*. Returns the result of the call on success, or - *NULL* on failure. - - -.. cfunction:: long PyObject_Hash(PyObject *o) - - .. index:: builtin: hash - - Compute and return the hash value of an object *o*. On failure, return ``-1``. - This is the equivalent of the Python expression ``hash(o)``. - - -.. cfunction:: int PyObject_IsTrue(PyObject *o) - - Returns ``1`` if the object *o* is considered to be true, and ``0`` otherwise. - This is equivalent to the Python expression ``not not o``. On failure, return - ``-1``. - - -.. cfunction:: int PyObject_Not(PyObject *o) - - Returns ``0`` if the object *o* is considered to be true, and ``1`` otherwise. - This is equivalent to the Python expression ``not o``. On failure, return - ``-1``. - - -.. cfunction:: PyObject* PyObject_Type(PyObject *o) - - .. index:: builtin: type - - When *o* is non-*NULL*, returns a type object corresponding to the object type - of object *o*. On failure, raises :exc:`SystemError` and returns *NULL*. This - is equivalent to the Python expression ``type(o)``. This function increments the - reference count of the return value. There's really no reason to use this - function instead of the common expression ``o->ob_type``, which returns a - pointer of type :ctype:`PyTypeObject\*`, except when the incremented reference - count is needed. - - -.. cfunction:: int PyObject_TypeCheck(PyObject *o, PyTypeObject *type) - - Return true if the object *o* is of type *type* or a subtype of *type*. Both - parameters must be non-*NULL*. - - -.. cfunction:: Py_ssize_t PyObject_Length(PyObject *o) - Py_ssize_t PyObject_Size(PyObject *o) - - .. index:: builtin: len - - Return the length of object *o*. If the object *o* provides either the sequence - and mapping protocols, the sequence length is returned. On error, ``-1`` is - returned. This is the equivalent to the Python expression ``len(o)``. - - -.. cfunction:: PyObject* PyObject_GetItem(PyObject *o, PyObject *key) - - Return element of *o* corresponding to the object *key* or *NULL* on failure. - This is the equivalent of the Python expression ``o[key]``. - - -.. cfunction:: int PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v) - - Map the object *key* to the value *v*. Returns ``-1`` on failure. This is the - equivalent of the Python statement ``o[key] = v``. - - -.. cfunction:: int PyObject_DelItem(PyObject *o, PyObject *key) - - Delete the mapping for *key* from *o*. Returns ``-1`` on failure. This is the - equivalent of the Python statement ``del o[key]``. - - -.. cfunction:: PyObject* PyObject_Dir(PyObject *o) - - This is equivalent to the Python expression ``dir(o)``, returning a (possibly - empty) list of strings appropriate for the object argument, or *NULL* if there - was an error. If the argument is *NULL*, this is like the Python ``dir()``, - returning the names of the current locals; in this case, if no execution frame - is active then *NULL* is returned but :cfunc:`PyErr_Occurred` will return false. - - -.. cfunction:: PyObject* PyObject_GetIter(PyObject *o) - - This is equivalent to the Python expression ``iter(o)``. It returns a new - iterator for the object argument, or the object itself if the object is already - an iterator. Raises :exc:`TypeError` and returns *NULL* if the object cannot be - iterated. - - -.. _number: - -Number Protocol -=============== - - -.. cfunction:: int PyNumber_Check(PyObject *o) - - Returns ``1`` if the object *o* provides numeric protocols, and false otherwise. - This function always succeeds. - - -.. cfunction:: PyObject* PyNumber_Add(PyObject *o1, PyObject *o2) - - Returns the result of adding *o1* and *o2*, or *NULL* on failure. This is the - equivalent of the Python expression ``o1 + o2``. - - -.. cfunction:: PyObject* PyNumber_Subtract(PyObject *o1, PyObject *o2) - - Returns the result of subtracting *o2* from *o1*, or *NULL* on failure. This is - the equivalent of the Python expression ``o1 - o2``. - - -.. cfunction:: PyObject* PyNumber_Multiply(PyObject *o1, PyObject *o2) - - Returns the result of multiplying *o1* and *o2*, or *NULL* on failure. This is - the equivalent of the Python expression ``o1 * o2``. - - -.. cfunction:: PyObject* PyNumber_Divide(PyObject *o1, PyObject *o2) - - Returns the result of dividing *o1* by *o2*, or *NULL* on failure. This is the - equivalent of the Python expression ``o1 / o2``. - - -.. cfunction:: PyObject* PyNumber_FloorDivide(PyObject *o1, PyObject *o2) - - Return the floor of *o1* divided by *o2*, or *NULL* on failure. This is - equivalent to the "classic" division of integers. - - -.. cfunction:: PyObject* PyNumber_TrueDivide(PyObject *o1, PyObject *o2) - - Return a reasonable approximation for the mathematical value of *o1* divided by - *o2*, or *NULL* on failure. The return value is "approximate" because binary - floating point numbers are approximate; it is not possible to represent all real - numbers in base two. This function can return a floating point value when - passed two integers. - - -.. cfunction:: PyObject* PyNumber_Remainder(PyObject *o1, PyObject *o2) - - Returns the remainder of dividing *o1* by *o2*, or *NULL* on failure. This is - the equivalent of the Python expression ``o1 % o2``. - - -.. cfunction:: PyObject* PyNumber_Divmod(PyObject *o1, PyObject *o2) - - .. index:: builtin: divmod - - See the built-in function :func:`divmod`. Returns *NULL* on failure. This is - the equivalent of the Python expression ``divmod(o1, o2)``. - - -.. cfunction:: PyObject* PyNumber_Power(PyObject *o1, PyObject *o2, PyObject *o3) - - .. index:: builtin: pow - - See the built-in function :func:`pow`. Returns *NULL* on failure. This is the - equivalent of the Python expression ``pow(o1, o2, o3)``, where *o3* is optional. - If *o3* is to be ignored, pass :cdata:`Py_None` in its place (passing *NULL* for - *o3* would cause an illegal memory access). - - -.. cfunction:: PyObject* PyNumber_Negative(PyObject *o) - - Returns the negation of *o* on success, or *NULL* on failure. This is the - equivalent of the Python expression ``-o``. - - -.. cfunction:: PyObject* PyNumber_Positive(PyObject *o) - - Returns *o* on success, or *NULL* on failure. This is the equivalent of the - Python expression ``+o``. - - -.. cfunction:: PyObject* PyNumber_Absolute(PyObject *o) - - .. index:: builtin: abs - - Returns the absolute value of *o*, or *NULL* on failure. This is the equivalent - of the Python expression ``abs(o)``. - - -.. cfunction:: PyObject* PyNumber_Invert(PyObject *o) - - Returns the bitwise negation of *o* on success, or *NULL* on failure. This is - the equivalent of the Python expression ``~o``. - - -.. cfunction:: PyObject* PyNumber_Lshift(PyObject *o1, PyObject *o2) - - Returns the result of left shifting *o1* by *o2* on success, or *NULL* on - failure. This is the equivalent of the Python expression ``o1 << o2``. - - -.. cfunction:: PyObject* PyNumber_Rshift(PyObject *o1, PyObject *o2) - - Returns the result of right shifting *o1* by *o2* on success, or *NULL* on - failure. This is the equivalent of the Python expression ``o1 >> o2``. - - -.. cfunction:: PyObject* PyNumber_And(PyObject *o1, PyObject *o2) - - Returns the "bitwise and" of *o1* and *o2* on success and *NULL* on failure. - This is the equivalent of the Python expression ``o1 & o2``. - - -.. cfunction:: PyObject* PyNumber_Xor(PyObject *o1, PyObject *o2) - - Returns the "bitwise exclusive or" of *o1* by *o2* on success, or *NULL* on - failure. This is the equivalent of the Python expression ``o1 ^ o2``. - - -.. cfunction:: PyObject* PyNumber_Or(PyObject *o1, PyObject *o2) - - Returns the "bitwise or" of *o1* and *o2* on success, or *NULL* on failure. - This is the equivalent of the Python expression ``o1 | o2``. - - -.. cfunction:: PyObject* PyNumber_InPlaceAdd(PyObject *o1, PyObject *o2) - - Returns the result of adding *o1* and *o2*, or *NULL* on failure. The operation - is done *in-place* when *o1* supports it. This is the equivalent of the Python - statement ``o1 += o2``. - - -.. cfunction:: PyObject* PyNumber_InPlaceSubtract(PyObject *o1, PyObject *o2) - - Returns the result of subtracting *o2* from *o1*, or *NULL* on failure. The - operation is done *in-place* when *o1* supports it. This is the equivalent of - the Python statement ``o1 -= o2``. - - -.. cfunction:: PyObject* PyNumber_InPlaceMultiply(PyObject *o1, PyObject *o2) - - Returns the result of multiplying *o1* and *o2*, or *NULL* on failure. The - operation is done *in-place* when *o1* supports it. This is the equivalent of - the Python statement ``o1 *= o2``. - - -.. cfunction:: PyObject* PyNumber_InPlaceDivide(PyObject *o1, PyObject *o2) - - Returns the result of dividing *o1* by *o2*, or *NULL* on failure. The - operation is done *in-place* when *o1* supports it. This is the equivalent of - the Python statement ``o1 /= o2``. - - -.. cfunction:: PyObject* PyNumber_InPlaceFloorDivide(PyObject *o1, PyObject *o2) - - Returns the mathematical floor of dividing *o1* by *o2*, or *NULL* on failure. - The operation is done *in-place* when *o1* supports it. This is the equivalent - of the Python statement ``o1 //= o2``. - - -.. cfunction:: PyObject* PyNumber_InPlaceTrueDivide(PyObject *o1, PyObject *o2) - - Return a reasonable approximation for the mathematical value of *o1* divided by - *o2*, or *NULL* on failure. The return value is "approximate" because binary - floating point numbers are approximate; it is not possible to represent all real - numbers in base two. This function can return a floating point value when - passed two integers. The operation is done *in-place* when *o1* supports it. - - -.. cfunction:: PyObject* PyNumber_InPlaceRemainder(PyObject *o1, PyObject *o2) - - Returns the remainder of dividing *o1* by *o2*, or *NULL* on failure. The - operation is done *in-place* when *o1* supports it. This is the equivalent of - the Python statement ``o1 %= o2``. - - -.. cfunction:: PyObject* PyNumber_InPlacePower(PyObject *o1, PyObject *o2, PyObject *o3) - - .. index:: builtin: pow - - See the built-in function :func:`pow`. Returns *NULL* on failure. The operation - is done *in-place* when *o1* supports it. This is the equivalent of the Python - statement ``o1 **= o2`` when o3 is :cdata:`Py_None`, or an in-place variant of - ``pow(o1, o2, o3)`` otherwise. If *o3* is to be ignored, pass :cdata:`Py_None` - in its place (passing *NULL* for *o3* would cause an illegal memory access). - - -.. cfunction:: PyObject* PyNumber_InPlaceLshift(PyObject *o1, PyObject *o2) - - Returns the result of left shifting *o1* by *o2* on success, or *NULL* on - failure. The operation is done *in-place* when *o1* supports it. This is the - equivalent of the Python statement ``o1 <<= o2``. - - -.. cfunction:: PyObject* PyNumber_InPlaceRshift(PyObject *o1, PyObject *o2) - - Returns the result of right shifting *o1* by *o2* on success, or *NULL* on - failure. The operation is done *in-place* when *o1* supports it. This is the - equivalent of the Python statement ``o1 >>= o2``. - - -.. cfunction:: PyObject* PyNumber_InPlaceAnd(PyObject *o1, PyObject *o2) - - Returns the "bitwise and" of *o1* and *o2* on success and *NULL* on failure. The - operation is done *in-place* when *o1* supports it. This is the equivalent of - the Python statement ``o1 &= o2``. - - -.. cfunction:: PyObject* PyNumber_InPlaceXor(PyObject *o1, PyObject *o2) - - Returns the "bitwise exclusive or" of *o1* by *o2* on success, or *NULL* on - failure. The operation is done *in-place* when *o1* supports it. This is the - equivalent of the Python statement ``o1 ^= o2``. - - -.. cfunction:: PyObject* PyNumber_InPlaceOr(PyObject *o1, PyObject *o2) - - Returns the "bitwise or" of *o1* and *o2* on success, or *NULL* on failure. The - operation is done *in-place* when *o1* supports it. This is the equivalent of - the Python statement ``o1 |= o2``. - - -.. cfunction:: PyObject* PyNumber_Int(PyObject *o) - - .. index:: builtin: int - - Returns the *o* converted to an integer object on success, or *NULL* on failure. - If the argument is outside the integer range a long object will be returned - instead. This is the equivalent of the Python expression ``int(o)``. - - -.. cfunction:: PyObject* PyNumber_Long(PyObject *o) - - .. index:: builtin: long - - Returns the *o* converted to an integer object on success, or *NULL* on - failure. This is the equivalent of the Python expression ``long(o)``. - - -.. cfunction:: PyObject* PyNumber_Float(PyObject *o) - - .. index:: builtin: float - - Returns the *o* converted to a float object on success, or *NULL* on failure. - This is the equivalent of the Python expression ``float(o)``. - - -.. cfunction:: PyObject* PyNumber_Index(PyObject *o) - - Returns the *o* converted to a Python int or long on success or *NULL* with a - TypeError exception raised on failure. - - -.. cfunction:: Py_ssize_t PyNumber_AsSsize_t(PyObject *o, PyObject *exc) - - Returns *o* converted to a Py_ssize_t value if *o* can be interpreted as an - integer. If *o* can be converted to a Python int or long but the attempt to - convert to a Py_ssize_t value would raise an :exc:`OverflowError`, then the - *exc* argument is the type of exception that will be raised (usually - :exc:`IndexError` or :exc:`OverflowError`). If *exc* is *NULL*, then the - exception is cleared and the value is clipped to *PY_SSIZE_T_MIN* for a negative - integer or *PY_SSIZE_T_MAX* for a positive integer. - - -.. cfunction:: int PyIndex_Check(PyObject *o) - - Returns True if *o* is an index integer (has the nb_index slot of the - tp_as_number structure filled in). - - -.. _sequence: - -Sequence Protocol -================= - - -.. cfunction:: int PySequence_Check(PyObject *o) - - Return ``1`` if the object provides sequence protocol, and ``0`` otherwise. - This function always succeeds. - - -.. cfunction:: Py_ssize_t PySequence_Size(PyObject *o) - - .. index:: builtin: len - - Returns the number of objects in sequence *o* on success, and ``-1`` on failure. - For objects that do not provide sequence protocol, this is equivalent to the - Python expression ``len(o)``. - - -.. cfunction:: Py_ssize_t PySequence_Length(PyObject *o) - - Alternate name for :cfunc:`PySequence_Size`. - - -.. cfunction:: PyObject* PySequence_Concat(PyObject *o1, PyObject *o2) - - Return the concatenation of *o1* and *o2* on success, and *NULL* on failure. - This is the equivalent of the Python expression ``o1 + o2``. - - -.. cfunction:: PyObject* PySequence_Repeat(PyObject *o, Py_ssize_t count) - - Return the result of repeating sequence object *o* *count* times, or *NULL* on - failure. This is the equivalent of the Python expression ``o * count``. - - -.. cfunction:: PyObject* PySequence_InPlaceConcat(PyObject *o1, PyObject *o2) - - Return the concatenation of *o1* and *o2* on success, and *NULL* on failure. - The operation is done *in-place* when *o1* supports it. This is the equivalent - of the Python expression ``o1 += o2``. - - -.. cfunction:: PyObject* PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count) - - Return the result of repeating sequence object *o* *count* times, or *NULL* on - failure. The operation is done *in-place* when *o* supports it. This is the - equivalent of the Python expression ``o *= count``. - - -.. cfunction:: PyObject* PySequence_GetItem(PyObject *o, Py_ssize_t i) - - Return the *i*th element of *o*, or *NULL* on failure. This is the equivalent of - the Python expression ``o[i]``. - - -.. cfunction:: PyObject* PySequence_GetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2) - - Return the slice of sequence object *o* between *i1* and *i2*, or *NULL* on - failure. This is the equivalent of the Python expression ``o[i1:i2]``. - - -.. cfunction:: int PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v) - - Assign object *v* to the *i*th element of *o*. Returns ``-1`` on failure. This - is the equivalent of the Python statement ``o[i] = v``. This function *does - not* steal a reference to *v*. - - -.. cfunction:: int PySequence_DelItem(PyObject *o, Py_ssize_t i) - - Delete the *i*th element of object *o*. Returns ``-1`` on failure. This is the - equivalent of the Python statement ``del o[i]``. - - -.. cfunction:: int PySequence_SetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2, PyObject *v) - - Assign the sequence object *v* to the slice in sequence object *o* from *i1* to - *i2*. This is the equivalent of the Python statement ``o[i1:i2] = v``. - - -.. cfunction:: int PySequence_DelSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2) - - Delete the slice in sequence object *o* from *i1* to *i2*. Returns ``-1`` on - failure. This is the equivalent of the Python statement ``del o[i1:i2]``. - - -.. cfunction:: Py_ssize_t PySequence_Count(PyObject *o, PyObject *value) - - Return the number of occurrences of *value* in *o*, that is, return the number - of keys for which ``o[key] == value``. On failure, return ``-1``. This is - equivalent to the Python expression ``o.count(value)``. - - -.. cfunction:: int PySequence_Contains(PyObject *o, PyObject *value) - - Determine if *o* contains *value*. If an item in *o* is equal to *value*, - return ``1``, otherwise return ``0``. On error, return ``-1``. This is - equivalent to the Python expression ``value in o``. - - -.. cfunction:: Py_ssize_t PySequence_Index(PyObject *o, PyObject *value) - - Return the first index *i* for which ``o[i] == value``. On error, return - ``-1``. This is equivalent to the Python expression ``o.index(value)``. - - -.. cfunction:: PyObject* PySequence_List(PyObject *o) - - Return a list object with the same contents as the arbitrary sequence *o*. The - returned list is guaranteed to be new. - - -.. cfunction:: PyObject* PySequence_Tuple(PyObject *o) - - .. index:: builtin: tuple - - Return a tuple object with the same contents as the arbitrary sequence *o* or - *NULL* on failure. If *o* is a tuple, a new reference will be returned, - otherwise a tuple will be constructed with the appropriate contents. This is - equivalent to the Python expression ``tuple(o)``. - - -.. cfunction:: PyObject* PySequence_Fast(PyObject *o, const char *m) - - Returns the sequence *o* as a tuple, unless it is already a tuple or list, in - which case *o* is returned. Use :cfunc:`PySequence_Fast_GET_ITEM` to access the - members of the result. Returns *NULL* on failure. If the object is not a - sequence, raises :exc:`TypeError` with *m* as the message text. - - -.. cfunction:: PyObject* PySequence_Fast_GET_ITEM(PyObject *o, Py_ssize_t i) - - Return the *i*th element of *o*, assuming that *o* was returned by - :cfunc:`PySequence_Fast`, *o* is not *NULL*, and that *i* is within bounds. - - -.. cfunction:: PyObject** PySequence_Fast_ITEMS(PyObject *o) - - Return the underlying array of PyObject pointers. Assumes that *o* was returned - by :cfunc:`PySequence_Fast` and *o* is not *NULL*. - - -.. cfunction:: PyObject* PySequence_ITEM(PyObject *o, Py_ssize_t i) - - Return the *i*th element of *o* or *NULL* on failure. Macro form of - :cfunc:`PySequence_GetItem` but without checking that - :cfunc:`PySequence_Check(o)` is true and without adjustment for negative - indices. - - -.. cfunction:: Py_ssize_t PySequence_Fast_GET_SIZE(PyObject *o) - - Returns the length of *o*, assuming that *o* was returned by - :cfunc:`PySequence_Fast` and that *o* is not *NULL*. The size can also be - gotten by calling :cfunc:`PySequence_Size` on *o*, but - :cfunc:`PySequence_Fast_GET_SIZE` is faster because it can assume *o* is a list - or tuple. - - -.. _mapping: - -Mapping Protocol -================ - - -.. cfunction:: int PyMapping_Check(PyObject *o) - - Return ``1`` if the object provides mapping protocol, and ``0`` otherwise. This - function always succeeds. - - -.. cfunction:: Py_ssize_t PyMapping_Length(PyObject *o) - - .. index:: builtin: len - - Returns the number of keys in object *o* on success, and ``-1`` on failure. For - objects that do not provide mapping protocol, this is equivalent to the Python - expression ``len(o)``. - - -.. cfunction:: int PyMapping_DelItemString(PyObject *o, char *key) - - Remove the mapping for object *key* from the object *o*. Return ``-1`` on - failure. This is equivalent to the Python statement ``del o[key]``. - - -.. cfunction:: int PyMapping_DelItem(PyObject *o, PyObject *key) - - Remove the mapping for object *key* from the object *o*. Return ``-1`` on - failure. This is equivalent to the Python statement ``del o[key]``. - - -.. cfunction:: int PyMapping_HasKeyString(PyObject *o, char *key) - - On success, return ``1`` if the mapping object has the key *key* and ``0`` - otherwise. This is equivalent to the Python expression ``key in o``. - This function always succeeds. - - -.. cfunction:: int PyMapping_HasKey(PyObject *o, PyObject *key) - - Return ``1`` if the mapping object has the key *key* and ``0`` otherwise. This - is equivalent to the Python expression ``key in o``. This function always - succeeds. - - -.. cfunction:: PyObject* PyMapping_Keys(PyObject *o) - - On success, return a list of the keys in object *o*. On failure, return *NULL*. - This is equivalent to the Python expression ``o.keys()``. - - -.. cfunction:: PyObject* PyMapping_Values(PyObject *o) - - On success, return a list of the values in object *o*. On failure, return - *NULL*. This is equivalent to the Python expression ``o.values()``. - - -.. cfunction:: PyObject* PyMapping_Items(PyObject *o) - - On success, return a list of the items in object *o*, where each item is a tuple - containing a key-value pair. On failure, return *NULL*. This is equivalent to - the Python expression ``o.items()``. - - -.. cfunction:: PyObject* PyMapping_GetItemString(PyObject *o, char *key) - - Return element of *o* corresponding to the object *key* or *NULL* on failure. - This is the equivalent of the Python expression ``o[key]``. - - -.. cfunction:: int PyMapping_SetItemString(PyObject *o, char *key, PyObject *v) - - Map the object *key* to the value *v* in object *o*. Returns ``-1`` on failure. - This is the equivalent of the Python statement ``o[key] = v``. - - -.. _iterator: - -Iterator Protocol -================= - -There are only a couple of functions specifically for working with iterators. - -.. cfunction:: int PyIter_Check(PyObject *o) - - Return true if the object *o* supports the iterator protocol. - - -.. cfunction:: PyObject* PyIter_Next(PyObject *o) - - Return the next value from the iteration *o*. If the object is an iterator, - this retrieves the next value from the iteration, and returns *NULL* with no - exception set if there are no remaining items. If the object is not an - iterator, :exc:`TypeError` is raised, or if there is an error in retrieving the - item, returns *NULL* and passes along the exception. - -To write a loop which iterates over an iterator, the C code should look -something like this:: - - PyObject *iterator = PyObject_GetIter(obj); - PyObject *item; - - if (iterator == NULL) { - /* propagate error */ - } - - while (item = PyIter_Next(iterator)) { - /* do something with item */ - ... - /* release reference when done */ - Py_DECREF(item); - } - - Py_DECREF(iterator); - - if (PyErr_Occurred()) { - /* propagate error */ - } - else { - /* continue doing useful work */ - } - - -.. _abstract-buffer: - -Buffer Protocol -=============== - - -.. cfunction:: int PyObject_AsCharBuffer(PyObject *obj, const char **buffer, Py_ssize_t *buffer_len) - - Returns a pointer to a read-only memory location useable as character- based - input. The *obj* argument must support the single-segment character buffer - interface. On success, returns ``0``, sets *buffer* to the memory location and - *buffer_len* to the buffer length. Returns ``-1`` and sets a :exc:`TypeError` - on error. - - -.. cfunction:: int PyObject_AsReadBuffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len) - - Returns a pointer to a read-only memory location containing arbitrary data. The - *obj* argument must support the single-segment readable buffer interface. On - success, returns ``0``, sets *buffer* to the memory location and *buffer_len* to - the buffer length. Returns ``-1`` and sets a :exc:`TypeError` on error. - - -.. cfunction:: int PyObject_CheckReadBuffer(PyObject *o) - - Returns ``1`` if *o* supports the single-segment readable buffer interface. - Otherwise returns ``0``. - - -.. cfunction:: int PyObject_AsWriteBuffer(PyObject *obj, void **buffer, Py_ssize_t *buffer_len) - - Returns a pointer to a writable memory location. The *obj* argument must - support the single-segment, character buffer interface. On success, returns - ``0``, sets *buffer* to the memory location and *buffer_len* to the buffer - length. Returns ``-1`` and sets a :exc:`TypeError` on error. - + object.rst + number.rst + sequence.rst + mapping.rst + iter.rst + objbuffer.rst Added: python/branches/py3k/Doc/c-api/allocation.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/allocation.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,93 @@ +.. highlightlang:: c + +.. _allocating-objects: + +Allocating Objects on the Heap +============================== + + +.. cfunction:: PyObject* _PyObject_New(PyTypeObject *type) + + +.. cfunction:: PyVarObject* _PyObject_NewVar(PyTypeObject *type, Py_ssize_t size) + + +.. cfunction:: PyObject* PyObject_Init(PyObject *op, PyTypeObject *type) + + Initialize a newly-allocated object *op* with its type and initial reference. + Returns the initialized object. If *type* indicates that the object + participates in the cyclic garbage detector, it is added to the detector's set + of observed objects. Other fields of the object are not affected. + + +.. cfunction:: PyVarObject* PyObject_InitVar(PyVarObject *op, PyTypeObject *type, Py_ssize_t size) + + This does everything :cfunc:`PyObject_Init` does, and also initializes the + length information for a variable-size object. + + +.. cfunction:: TYPE* PyObject_New(TYPE, PyTypeObject *type) + + Allocate a new Python object using the C structure type *TYPE* and the Python + type object *type*. Fields not defined by the Python object header are not + initialized; the object's reference count will be one. The size of the memory + allocation is determined from the :attr:`tp_basicsize` field of the type object. + + +.. cfunction:: TYPE* PyObject_NewVar(TYPE, PyTypeObject *type, Py_ssize_t size) + + Allocate a new Python object using the C structure type *TYPE* and the Python + type object *type*. Fields not defined by the Python object header are not + initialized. The allocated memory allows for the *TYPE* structure plus *size* + fields of the size given by the :attr:`tp_itemsize` field of *type*. This is + useful for implementing objects like tuples, which are able to determine their + size at construction time. Embedding the array of fields into the same + allocation decreases the number of allocations, improving the memory management + efficiency. + + +.. cfunction:: void PyObject_Del(PyObject *op) + + Releases memory allocated to an object using :cfunc:`PyObject_New` or + :cfunc:`PyObject_NewVar`. This is normally called from the :attr:`tp_dealloc` + handler specified in the object's type. The fields of the object should not be + accessed after this call as the memory is no longer a valid Python object. + + +.. cfunction:: PyObject* Py_InitModule(char *name, PyMethodDef *methods) + + Create a new module object based on a name and table of functions, returning + the new module object; the *methods* argument can be *NULL* if no methods are + to be defined for the module. + + +.. cfunction:: PyObject* Py_InitModule3(char *name, PyMethodDef *methods, char *doc) + + Create a new module object based on a name and table of functions, returning + the new module object. The *methods* argument can be *NULL* if no methods + are to be defined for the module. If *doc* is non-*NULL*, it will be used to + define the docstring for the module. + + +.. cfunction:: PyObject* Py_InitModule4(char *name, PyMethodDef *methods, char *doc, PyObject *self, int apiver) + + Create a new module object based on a name and table of functions, returning + the new module object. The *methods* argument can be *NULL* if no methods + are to be defined for the module. If *doc* is non-*NULL*, it will be used to + define the docstring for the module. If *self* is non-*NULL*, it will passed + to the functions of the module as their (otherwise *NULL*) first parameter. + (This was added as an experimental feature, and there are no known uses in + the current version of Python.) For *apiver*, the only value which should be + passed is defined by the constant :const:`PYTHON_API_VERSION`. + + .. note:: + + Most uses of this function should probably be using the :cfunc:`Py_InitModule3` + instead; only use this if you are sure you need it. + + +.. cvar:: PyObject _Py_NoneStruct + + Object which is visible in Python as ``None``. This should only be accessed + using the :cmacro:`Py_None` macro, which evaluates to a pointer to this + object. Added: python/branches/py3k/Doc/c-api/arg.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/arg.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,509 @@ +.. highlightlang:: c + +.. _arg-parsing: + +Parsing arguments and building values +===================================== + +These functions are useful when creating your own extensions functions and +methods. Additional information and examples are available in +:ref:`extending-index`. + +The first three of these functions described, :cfunc:`PyArg_ParseTuple`, +:cfunc:`PyArg_ParseTupleAndKeywords`, and :cfunc:`PyArg_Parse`, all use *format +strings* which are used to tell the function about the expected arguments. The +format strings use the same syntax for each of these functions. + +A format string consists of zero or more "format units." A format unit +describes one Python object; it is usually a single character or a parenthesized +sequence of format units. With a few exceptions, a format unit that is not a +parenthesized sequence normally corresponds to a single address argument to +these functions. In the following description, the quoted form is the format +unit; the entry in (round) parentheses is the Python object type that matches +the format unit; and the entry in [square] brackets is the type of the C +variable(s) whose address should be passed. + +``s`` (string or Unicode object) [const char \*] + Convert a Python string or Unicode object to a C pointer to a character string. + You must not provide storage for the string itself; a pointer to an existing + string is stored into the character pointer variable whose address you pass. + The C string is NUL-terminated. The Python string must not contain embedded NUL + bytes; if it does, a :exc:`TypeError` exception is raised. Unicode objects are + converted to C strings using the default encoding. If this conversion fails, a + :exc:`UnicodeError` is raised. + +``s#`` (string, Unicode or any read buffer compatible object) [const char \*, int] + This variant on ``s`` stores into two C variables, the first one a pointer to a + character string, the second one its length. In this case the Python string may + contain embedded null bytes. Unicode objects pass back a pointer to the default + encoded string version of the object if such a conversion is possible. All + other read-buffer compatible objects pass back a reference to the raw internal + data representation. + +``y`` (bytes object) [const char \*] + This variant on ``s`` convert a Python bytes object to a C pointer to a + character string. The bytes object must not contain embedded NUL bytes; if it + does, a :exc:`TypeError` exception is raised. + +``y#`` (bytes object) [const char \*, int] + This variant on ``s#`` stores into two C variables, the first one a pointer to a + character string, the second one its length. This only accepts bytes objects. + +``z`` (string or ``None``) [const char \*] + Like ``s``, but the Python object may also be ``None``, in which case the C + pointer is set to *NULL*. + +``z#`` (string or ``None`` or any read buffer compatible object) [const char \*, int] + This is to ``s#`` as ``z`` is to ``s``. + +``u`` (Unicode object) [Py_UNICODE \*] + Convert a Python Unicode object to a C pointer to a NUL-terminated buffer of + 16-bit Unicode (UTF-16) data. As with ``s``, there is no need to provide + storage for the Unicode data buffer; a pointer to the existing Unicode data is + stored into the :ctype:`Py_UNICODE` pointer variable whose address you pass. + +``u#`` (Unicode object) [Py_UNICODE \*, int] + This variant on ``u`` stores into two C variables, the first one a pointer to a + Unicode data buffer, the second one its length. Non-Unicode objects are handled + by interpreting their read-buffer pointer as pointer to a :ctype:`Py_UNICODE` + array. + +``Z`` (Unicode or ``None``) [Py_UNICODE \*] + Like ``s``, but the Python object may also be ``None``, in which case the C + pointer is set to *NULL*. + +``Z#`` (Unicode or ``None``) [Py_UNICODE \*, int] + This is to ``u#`` as ``Z`` is to ``u``. + +``es`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] + This variant on ``s`` is used for encoding Unicode and objects convertible to + Unicode into a character buffer. It only works for encoded data without embedded + NUL bytes. + + This format requires two arguments. The first is only used as input, and + must be a :ctype:`const char\*` which points to the name of an encoding as a + NUL-terminated string, or *NULL*, in which case the default encoding is used. + An exception is raised if the named encoding is not known to Python. The + second argument must be a :ctype:`char\*\*`; the value of the pointer it + references will be set to a buffer with the contents of the argument text. + The text will be encoded in the encoding specified by the first argument. + + :cfunc:`PyArg_ParseTuple` will allocate a buffer of the needed size, copy the + encoded data into this buffer and adjust *\*buffer* to reference the newly + allocated storage. The caller is responsible for calling :cfunc:`PyMem_Free` to + free the allocated buffer after use. + +``et`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] + Same as ``es`` except that 8-bit string objects are passed through without + recoding them. Instead, the implementation assumes that the string object uses + the encoding passed in as parameter. + +``es#`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer, int \*buffer_length] + This variant on ``s#`` is used for encoding Unicode and objects convertible to + Unicode into a character buffer. Unlike the ``es`` format, this variant allows + input data which contains NUL characters. + + It requires three arguments. The first is only used as input, and must be a + :ctype:`const char\*` which points to the name of an encoding as a + NUL-terminated string, or *NULL*, in which case the default encoding is used. + An exception is raised if the named encoding is not known to Python. The + second argument must be a :ctype:`char\*\*`; the value of the pointer it + references will be set to a buffer with the contents of the argument text. + The text will be encoded in the encoding specified by the first argument. + The third argument must be a pointer to an integer; the referenced integer + will be set to the number of bytes in the output buffer. + + There are two modes of operation: + + If *\*buffer* points a *NULL* pointer, the function will allocate a buffer of + the needed size, copy the encoded data into this buffer and set *\*buffer* to + reference the newly allocated storage. The caller is responsible for calling + :cfunc:`PyMem_Free` to free the allocated buffer after usage. + + If *\*buffer* points to a non-*NULL* pointer (an already allocated buffer), + :cfunc:`PyArg_ParseTuple` will use this location as the buffer and interpret the + initial value of *\*buffer_length* as the buffer size. It will then copy the + encoded data into the buffer and NUL-terminate it. If the buffer is not large + enough, a :exc:`ValueError` will be set. + + In both cases, *\*buffer_length* is set to the length of the encoded data + without the trailing NUL byte. + +``et#`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] + Same as ``es#`` except that string objects are passed through without recoding + them. Instead, the implementation assumes that the string object uses the + encoding passed in as parameter. + +``b`` (integer) [char] + Convert a Python integer to a tiny int, stored in a C :ctype:`char`. + +``B`` (integer) [unsigned char] + Convert a Python integer to a tiny int without overflow checking, stored in a C + :ctype:`unsigned char`. + +``h`` (integer) [short int] + Convert a Python integer to a C :ctype:`short int`. + +``H`` (integer) [unsigned short int] + Convert a Python integer to a C :ctype:`unsigned short int`, without overflow + checking. + +``i`` (integer) [int] + Convert a Python integer to a plain C :ctype:`int`. + +``I`` (integer) [unsigned int] + Convert a Python integer to a C :ctype:`unsigned int`, without overflow + checking. + +``l`` (integer) [long int] + Convert a Python integer to a C :ctype:`long int`. + +``k`` (integer) [unsigned long] + Convert a Python integer to a C :ctype:`unsigned long` without + overflow checking. + +``L`` (integer) [PY_LONG_LONG] + Convert a Python integer to a C :ctype:`long long`. This format is only + available on platforms that support :ctype:`long long` (or :ctype:`_int64` on + Windows). + +``K`` (integer) [unsigned PY_LONG_LONG] + Convert a Python integer to a C :ctype:`unsigned long long` + without overflow checking. This format is only available on platforms that + support :ctype:`unsigned long long` (or :ctype:`unsigned _int64` on Windows). + +``n`` (integer) [Py_ssize_t] + Convert a Python integer to a C :ctype:`Py_ssize_t`. + +``c`` (string of length 1) [char] + Convert a Python character, represented as a string of length 1, to a C + :ctype:`char`. + +``f`` (float) [float] + Convert a Python floating point number to a C :ctype:`float`. + +``d`` (float) [double] + Convert a Python floating point number to a C :ctype:`double`. + +``D`` (complex) [Py_complex] + Convert a Python complex number to a C :ctype:`Py_complex` structure. + +``O`` (object) [PyObject \*] + Store a Python object (without any conversion) in a C object pointer. The C + program thus receives the actual object that was passed. The object's reference + count is not increased. The pointer stored is not *NULL*. + +``O!`` (object) [*typeobject*, PyObject \*] + Store a Python object in a C object pointer. This is similar to ``O``, but + takes two C arguments: the first is the address of a Python type object, the + second is the address of the C variable (of type :ctype:`PyObject\*`) into which + the object pointer is stored. If the Python object does not have the required + type, :exc:`TypeError` is raised. + +``O&`` (object) [*converter*, *anything*] + Convert a Python object to a C variable through a *converter* function. This + takes two arguments: the first is a function, the second is the address of a C + variable (of arbitrary type), converted to :ctype:`void \*`. The *converter* + function in turn is called as follows:: + + status = converter(object, address); + + where *object* is the Python object to be converted and *address* is the + :ctype:`void\*` argument that was passed to the :cfunc:`PyArg_Parse\*` function. + The returned *status* should be ``1`` for a successful conversion and ``0`` if + the conversion has failed. When the conversion fails, the *converter* function + should raise an exception. + +``S`` (string) [PyStringObject \*] + Like ``O`` but requires that the Python object is a string object. Raises + :exc:`TypeError` if the object is not a string object. The C variable may also + be declared as :ctype:`PyObject\*`. + +``U`` (Unicode string) [PyUnicodeObject \*] + Like ``O`` but requires that the Python object is a Unicode object. Raises + :exc:`TypeError` if the object is not a Unicode object. The C variable may also + be declared as :ctype:`PyObject\*`. + +``t#`` (read-only character buffer) [char \*, int] + Like ``s#``, but accepts any object which implements the read-only buffer + interface. The :ctype:`char\*` variable is set to point to the first byte of + the buffer, and the :ctype:`int` is set to the length of the buffer. Only + single-segment buffer objects are accepted; :exc:`TypeError` is raised for all + others. + +``w`` (read-write character buffer) [char \*] + Similar to ``s``, but accepts any object which implements the read-write buffer + interface. The caller must determine the length of the buffer by other means, + or use ``w#`` instead. Only single-segment buffer objects are accepted; + :exc:`TypeError` is raised for all others. + +``w#`` (read-write character buffer) [char \*, int] + Like ``s#``, but accepts any object which implements the read-write buffer + interface. The :ctype:`char \*` variable is set to point to the first byte of + the buffer, and the :ctype:`int` is set to the length of the buffer. Only + single-segment buffer objects are accepted; :exc:`TypeError` is raised for all + others. + +``(items)`` (tuple) [*matching-items*] + The object must be a Python sequence whose length is the number of format units + in *items*. The C arguments must correspond to the individual format units in + *items*. Format units for sequences may be nested. + +It is possible to pass "long" integers (integers whose value exceeds the +platform's :const:`LONG_MAX`) however no proper range checking is done --- the +most significant bits are silently truncated when the receiving field is too +small to receive the value (actually, the semantics are inherited from downcasts +in C --- your mileage may vary). + +A few other characters have a meaning in a format string. These may not occur +inside nested parentheses. They are: + +``|`` + Indicates that the remaining arguments in the Python argument list are optional. + The C variables corresponding to optional arguments should be initialized to + their default value --- when an optional argument is not specified, + :cfunc:`PyArg_ParseTuple` does not touch the contents of the corresponding C + variable(s). + +``:`` + The list of format units ends here; the string after the colon is used as the + function name in error messages (the "associated value" of the exception that + :cfunc:`PyArg_ParseTuple` raises). + +``;`` + The list of format units ends here; the string after the semicolon is used as + the error message *instead* of the default error message. Clearly, ``:`` and + ``;`` mutually exclude each other. + +Note that any Python object references which are provided to the caller are +*borrowed* references; do not decrement their reference count! + +Additional arguments passed to these functions must be addresses of variables +whose type is determined by the format string; these are used to store values +from the input tuple. There are a few cases, as described in the list of format +units above, where these parameters are used as input values; they should match +what is specified for the corresponding format unit in that case. + +For the conversion to succeed, the *arg* object must match the format and the +format must be exhausted. On success, the :cfunc:`PyArg_Parse\*` functions +return true, otherwise they return false and raise an appropriate exception. + + +.. cfunction:: int PyArg_ParseTuple(PyObject *args, const char *format, ...) + + Parse the parameters of a function that takes only positional parameters into + local variables. Returns true on success; on failure, it returns false and + raises the appropriate exception. + + +.. cfunction:: int PyArg_VaParse(PyObject *args, const char *format, va_list vargs) + + Identical to :cfunc:`PyArg_ParseTuple`, except that it accepts a va_list rather + than a variable number of arguments. + + +.. cfunction:: int PyArg_ParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *keywords[], ...) + + Parse the parameters of a function that takes both positional and keyword + parameters into local variables. Returns true on success; on failure, it + returns false and raises the appropriate exception. + + +.. cfunction:: int PyArg_VaParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *keywords[], va_list vargs) + + Identical to :cfunc:`PyArg_ParseTupleAndKeywords`, except that it accepts a + va_list rather than a variable number of arguments. + + +.. XXX deprecated, will be removed +.. cfunction:: int PyArg_Parse(PyObject *args, const char *format, ...) + + Function used to deconstruct the argument lists of "old-style" functions --- + these are functions which use the :const:`METH_OLDARGS` parameter parsing + method. This is not recommended for use in parameter parsing in new code, and + most code in the standard interpreter has been modified to no longer use this + for that purpose. It does remain a convenient way to decompose other tuples, + however, and may continue to be used for that purpose. + + +.. cfunction:: int PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...) + + A simpler form of parameter retrieval which does not use a format string to + specify the types of the arguments. Functions which use this method to retrieve + their parameters should be declared as :const:`METH_VARARGS` in function or + method tables. The tuple containing the actual parameters should be passed as + *args*; it must actually be a tuple. The length of the tuple must be at least + *min* and no more than *max*; *min* and *max* may be equal. Additional + arguments must be passed to the function, each of which should be a pointer to a + :ctype:`PyObject\*` variable; these will be filled in with the values from + *args*; they will contain borrowed references. The variables which correspond + to optional parameters not given by *args* will not be filled in; these should + be initialized by the caller. This function returns true on success and false if + *args* is not a tuple or contains the wrong number of elements; an exception + will be set if there was a failure. + + This is an example of the use of this function, taken from the sources for the + :mod:`_weakref` helper module for weak references:: + + static PyObject * + weakref_ref(PyObject *self, PyObject *args) + { + PyObject *object; + PyObject *callback = NULL; + PyObject *result = NULL; + + if (PyArg_UnpackTuple(args, "ref", 1, 2, &object, &callback)) { + result = PyWeakref_NewRef(object, callback); + } + return result; + } + + The call to :cfunc:`PyArg_UnpackTuple` in this example is entirely equivalent to + this call to :cfunc:`PyArg_ParseTuple`:: + + PyArg_ParseTuple(args, "O|O:ref", &object, &callback) + + +.. cfunction:: PyObject* Py_BuildValue(const char *format, ...) + + Create a new value based on a format string similar to those accepted by the + :cfunc:`PyArg_Parse\*` family of functions and a sequence of values. Returns + the value or *NULL* in the case of an error; an exception will be raised if + *NULL* is returned. + + :cfunc:`Py_BuildValue` does not always build a tuple. It builds a tuple only if + its format string contains two or more format units. If the format string is + empty, it returns ``None``; if it contains exactly one format unit, it returns + whatever object is described by that format unit. To force it to return a tuple + of size 0 or one, parenthesize the format string. + + When memory buffers are passed as parameters to supply data to build objects, as + for the ``s`` and ``s#`` formats, the required data is copied. Buffers provided + by the caller are never referenced by the objects created by + :cfunc:`Py_BuildValue`. In other words, if your code invokes :cfunc:`malloc` + and passes the allocated memory to :cfunc:`Py_BuildValue`, your code is + responsible for calling :cfunc:`free` for that memory once + :cfunc:`Py_BuildValue` returns. + + In the following description, the quoted form is the format unit; the entry in + (round) parentheses is the Python object type that the format unit will return; + and the entry in [square] brackets is the type of the C value(s) to be passed. + + The characters space, tab, colon and comma are ignored in format strings (but + not within format units such as ``s#``). This can be used to make long format + strings a tad more readable. + + ``s`` (string) [char \*] + Convert a null-terminated C string to a Python object. If the C string pointer + is *NULL*, ``None`` is used. + + ``s#`` (string) [char \*, int] + Convert a C string and its length to a Python object. If the C string pointer + is *NULL*, the length is ignored and ``None`` is returned. + + ``z`` (string or ``None``) [char \*] + Same as ``s``. + + ``z#`` (string or ``None``) [char \*, int] + Same as ``s#``. + + ``u`` (Unicode string) [Py_UNICODE \*] + Convert a null-terminated buffer of Unicode (UCS-2 or UCS-4) data to a Python + Unicode object. If the Unicode buffer pointer is *NULL*, ``None`` is returned. + + ``u#`` (Unicode string) [Py_UNICODE \*, int] + Convert a Unicode (UCS-2 or UCS-4) data buffer and its length to a Python + Unicode object. If the Unicode buffer pointer is *NULL*, the length is ignored + and ``None`` is returned. + + ``U`` (string) [char \*] + Convert a null-terminated C string to a Python unicode object. If the C string + pointer is *NULL*, ``None`` is used. + + ``U#`` (string) [char \*, int] + Convert a C string and its length to a Python unicode object. If the C string + pointer is *NULL*, the length is ignored and ``None`` is returned. + + ``i`` (integer) [int] + Convert a plain C :ctype:`int` to a Python integer object. + + ``b`` (integer) [char] + Convert a plain C :ctype:`char` to a Python integer object. + + ``h`` (integer) [short int] + Convert a plain C :ctype:`short int` to a Python integer object. + + ``l`` (integer) [long int] + Convert a C :ctype:`long int` to a Python integer object. + + ``B`` (integer) [unsigned char] + Convert a C :ctype:`unsigned char` to a Python integer object. + + ``H`` (integer) [unsigned short int] + Convert a C :ctype:`unsigned short int` to a Python integer object. + + ``I`` (integer/long) [unsigned int] + Convert a C :ctype:`unsigned int` to a Python long integer object. + + ``k`` (integer/long) [unsigned long] + Convert a C :ctype:`unsigned long` to a Python long integer object. + + ``L`` (long) [PY_LONG_LONG] + Convert a C :ctype:`long long` to a Python integer object. Only available + on platforms that support :ctype:`long long`. + + ``K`` (long) [unsigned PY_LONG_LONG] + Convert a C :ctype:`unsigned long long` to a Python integer object. Only + available on platforms that support :ctype:`unsigned long long`. + + ``n`` (int) [Py_ssize_t] + Convert a C :ctype:`Py_ssize_t` to a Python integer. + + ``c`` (string of length 1) [char] + Convert a C :ctype:`int` representing a character to a Python string of length + 1. + + ``d`` (float) [double] + Convert a C :ctype:`double` to a Python floating point number. + + ``f`` (float) [float] + Same as ``d``. + + ``D`` (complex) [Py_complex \*] + Convert a C :ctype:`Py_complex` structure to a Python complex number. + + ``O`` (object) [PyObject \*] + Pass a Python object untouched (except for its reference count, which is + incremented by one). If the object passed in is a *NULL* pointer, it is assumed + that this was caused because the call producing the argument found an error and + set an exception. Therefore, :cfunc:`Py_BuildValue` will return *NULL* but won't + raise an exception. If no exception has been raised yet, :exc:`SystemError` is + set. + + ``S`` (object) [PyObject \*] + Same as ``O``. + + ``N`` (object) [PyObject \*] + Same as ``O``, except it doesn't increment the reference count on the object. + Useful when the object is created by a call to an object constructor in the + argument list. + + ``O&`` (object) [*converter*, *anything*] + Convert *anything* to a Python object through a *converter* function. The + function is called with *anything* (which should be compatible with :ctype:`void + \*`) as its argument and should return a "new" Python object, or *NULL* if an + error occurred. + + ``(items)`` (tuple) [*matching-items*] + Convert a sequence of C values to a Python tuple with the same number of items. + + ``[items]`` (list) [*matching-items*] + Convert a sequence of C values to a Python list with the same number of items. + + ``{items}`` (dictionary) [*matching-items*] + Convert a sequence of C values to a Python dictionary. Each pair of consecutive + C values adds one item to the dictionary, serving as key and value, + respectively. + + If there is an error in the format string, the :exc:`SystemError` exception is + set and *NULL* returned. Added: python/branches/py3k/Doc/c-api/bool.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/bool.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,46 @@ +.. highlightlang:: c + +.. _boolobjects: + +Boolean Objects +--------------- + +Booleans in Python are implemented as a subclass of integers. There are only +two booleans, :const:`Py_False` and :const:`Py_True`. As such, the normal +creation and deletion functions don't apply to booleans. The following macros +are available, however. + + +.. cfunction:: int PyBool_Check(PyObject *o) + + Return true if *o* is of type :cdata:`PyBool_Type`. + + +.. cvar:: PyObject* Py_False + + The Python ``False`` object. This object has no methods. It needs to be + treated just like any other object with respect to reference counts. + + +.. cvar:: PyObject* Py_True + + The Python ``True`` object. This object has no methods. It needs to be treated + just like any other object with respect to reference counts. + + +.. cmacro:: Py_RETURN_FALSE + + Return :const:`Py_False` from a function, properly incrementing its reference + count. + + +.. cmacro:: Py_RETURN_TRUE + + Return :const:`Py_True` from a function, properly incrementing its reference + count. + + +.. cfunction:: PyObject* PyBool_FromLong(long v) + + Return a new reference to :const:`Py_True` or :const:`Py_False` depending on the + truth value of *v*. Added: python/branches/py3k/Doc/c-api/buffer.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/buffer.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,119 @@ +.. highlightlang:: c + +.. _bufferobjects: + +Buffer Objects +-------------- + +.. sectionauthor:: Greg Stein + + +.. index:: + object: buffer + single: buffer interface + +Python objects implemented in C can export a group of functions called the +"buffer interface." These functions can be used by an object to expose its data +in a raw, byte-oriented format. Clients of the object can use the buffer +interface to access the object data directly, without needing to copy it first. + +Two examples of objects that support the buffer interface are strings and +arrays. The string object exposes the character contents in the buffer +interface's byte-oriented form. An array can also expose its contents, but it +should be noted that array elements may be multi-byte values. + +An example user of the buffer interface is the file object's :meth:`write` +method. Any object that can export a series of bytes through the buffer +interface can be written to a file. There are a number of format codes to +:cfunc:`PyArg_ParseTuple` that operate against an object's buffer interface, +returning data from the target object. + +.. index:: single: PyBufferProcs + +More information on the buffer interface is provided in the section +:ref:`buffer-structs`, under the description for :ctype:`PyBufferProcs`. + +A "buffer object" is defined in the :file:`bufferobject.h` header (included by +:file:`Python.h`). These objects look very similar to string objects at the +Python programming level: they support slicing, indexing, concatenation, and +some other standard string operations. However, their data can come from one of +two sources: from a block of memory, or from another object which exports the +buffer interface. + +Buffer objects are useful as a way to expose the data from another object's +buffer interface to the Python programmer. They can also be used as a zero-copy +slicing mechanism. Using their ability to reference a block of memory, it is +possible to expose any data to the Python programmer quite easily. The memory +could be a large, constant array in a C extension, it could be a raw block of +memory for manipulation before passing to an operating system library, or it +could be used to pass around structured data in its native, in-memory format. + + +.. ctype:: PyBufferObject + + This subtype of :ctype:`PyObject` represents a buffer object. + + +.. cvar:: PyTypeObject PyBuffer_Type + + .. index:: single: BufferType (in module types) + + The instance of :ctype:`PyTypeObject` which represents the Python buffer type; + it is the same object as ``buffer`` and ``types.BufferType`` in the Python + layer. . + + +.. cvar:: int Py_END_OF_BUFFER + + This constant may be passed as the *size* parameter to + :cfunc:`PyBuffer_FromObject` or :cfunc:`PyBuffer_FromReadWriteObject`. It + indicates that the new :ctype:`PyBufferObject` should refer to *base* object + from the specified *offset* to the end of its exported buffer. Using this + enables the caller to avoid querying the *base* object for its length. + + +.. cfunction:: int PyBuffer_Check(PyObject *p) + + Return true if the argument has type :cdata:`PyBuffer_Type`. + + +.. cfunction:: PyObject* PyBuffer_FromObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size) + + Return a new read-only buffer object. This raises :exc:`TypeError` if *base* + doesn't support the read-only buffer protocol or doesn't provide exactly one + buffer segment, or it raises :exc:`ValueError` if *offset* is less than zero. + The buffer will hold a reference to the *base* object, and the buffer's contents + will refer to the *base* object's buffer interface, starting as position + *offset* and extending for *size* bytes. If *size* is :const:`Py_END_OF_BUFFER`, + then the new buffer's contents extend to the length of the *base* object's + exported buffer data. + + +.. cfunction:: PyObject* PyBuffer_FromReadWriteObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size) + + Return a new writable buffer object. Parameters and exceptions are similar to + those for :cfunc:`PyBuffer_FromObject`. If the *base* object does not export + the writable buffer protocol, then :exc:`TypeError` is raised. + + +.. cfunction:: PyObject* PyBuffer_FromMemory(void *ptr, Py_ssize_t size) + + Return a new read-only buffer object that reads from a specified location in + memory, with a specified size. The caller is responsible for ensuring that the + memory buffer, passed in as *ptr*, is not deallocated while the returned buffer + object exists. Raises :exc:`ValueError` if *size* is less than zero. Note that + :const:`Py_END_OF_BUFFER` may *not* be passed for the *size* parameter; + :exc:`ValueError` will be raised in that case. + + +.. cfunction:: PyObject* PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size) + + Similar to :cfunc:`PyBuffer_FromMemory`, but the returned buffer is writable. + + +.. cfunction:: PyObject* PyBuffer_New(Py_ssize_t size) + + Return a new writable buffer object that maintains its own memory buffer of + *size* bytes. :exc:`ValueError` is returned if *size* is not zero or positive. + Note that the memory buffer (as returned by :cfunc:`PyObject_AsWriteBuffer`) is + not specifically aligned. Added: python/branches/py3k/Doc/c-api/cell.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/cell.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,62 @@ +.. highlightlang:: c + +.. _cell-objects: + +Cell Objects +------------ + +"Cell" objects are used to implement variables referenced by multiple scopes. +For each such variable, a cell object is created to store the value; the local +variables of each stack frame that references the value contains a reference to +the cells from outer scopes which also use that variable. When the value is +accessed, the value contained in the cell is used instead of the cell object +itself. This de-referencing of the cell object requires support from the +generated byte-code; these are not automatically de-referenced when accessed. +Cell objects are not likely to be useful elsewhere. + + +.. ctype:: PyCellObject + + The C structure used for cell objects. + + +.. cvar:: PyTypeObject PyCell_Type + + The type object corresponding to cell objects. + + +.. cfunction:: int PyCell_Check(ob) + + Return true if *ob* is a cell object; *ob* must not be *NULL*. + + +.. cfunction:: PyObject* PyCell_New(PyObject *ob) + + Create and return a new cell object containing the value *ob*. The parameter may + be *NULL*. + + +.. cfunction:: PyObject* PyCell_Get(PyObject *cell) + + Return the contents of the cell *cell*. + + +.. cfunction:: PyObject* PyCell_GET(PyObject *cell) + + Return the contents of the cell *cell*, but without checking that *cell* is + non-*NULL* and a cell object. + + +.. cfunction:: int PyCell_Set(PyObject *cell, PyObject *value) + + Set the contents of the cell object *cell* to *value*. This releases the + reference to any current content of the cell. *value* may be *NULL*. *cell* + must be non-*NULL*; if it is not a cell object, ``-1`` will be returned. On + success, ``0`` will be returned. + + +.. cfunction:: void PyCell_SET(PyObject *cell, PyObject *value) + + Sets the value of the cell object *cell* to *value*. No reference counts are + adjusted, and no checks are made for safety; *cell* must be non-*NULL* and must + be a cell object. Added: python/branches/py3k/Doc/c-api/cobject.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/cobject.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,56 @@ +.. highlightlang:: c + +.. _cobjects: + +CObjects +-------- + +.. index:: object: CObject + +Refer to :ref:`using-cobjects` for more information on using these objects. + + +.. ctype:: PyCObject + + This subtype of :ctype:`PyObject` represents an opaque value, useful for C + extension modules who need to pass an opaque value (as a :ctype:`void\*` + pointer) through Python code to other C code. It is often used to make a C + function pointer defined in one module available to other modules, so the + regular import mechanism can be used to access C APIs defined in dynamically + loaded modules. + + +.. cfunction:: int PyCObject_Check(PyObject *p) + + Return true if its argument is a :ctype:`PyCObject`. + + +.. cfunction:: PyObject* PyCObject_FromVoidPtr(void* cobj, void (*destr)(void *)) + + Create a :ctype:`PyCObject` from the ``void *`` *cobj*. The *destr* function + will be called when the object is reclaimed, unless it is *NULL*. + + +.. cfunction:: PyObject* PyCObject_FromVoidPtrAndDesc(void* cobj, void* desc, void (*destr)(void *, void *)) + + Create a :ctype:`PyCObject` from the :ctype:`void \*` *cobj*. The *destr* + function will be called when the object is reclaimed. The *desc* argument can + be used to pass extra callback data for the destructor function. + + +.. cfunction:: void* PyCObject_AsVoidPtr(PyObject* self) + + Return the object :ctype:`void \*` that the :ctype:`PyCObject` *self* was + created with. + + +.. cfunction:: void* PyCObject_GetDesc(PyObject* self) + + Return the description :ctype:`void \*` that the :ctype:`PyCObject` *self* was + created with. + + +.. cfunction:: int PyCObject_SetVoidPtr(PyObject* self, void* cobj) + + Set the void pointer inside *self* to *cobj*. The :ctype:`PyCObject` must not + have an associated destructor. Return true on success, false on failure. Added: python/branches/py3k/Doc/c-api/complex.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/complex.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,126 @@ +.. highlightlang:: c + +.. _complexobjects: + +Complex Number Objects +---------------------- + +.. index:: object: complex number + +Python's complex number objects are implemented as two distinct types when +viewed from the C API: one is the Python object exposed to Python programs, and +the other is a C structure which represents the actual complex number value. +The API provides functions for working with both. + + +Complex Numbers as C Structures +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Note that the functions which accept these structures as parameters and return +them as results do so *by value* rather than dereferencing them through +pointers. This is consistent throughout the API. + + +.. ctype:: Py_complex + + The C structure which corresponds to the value portion of a Python complex + number object. Most of the functions for dealing with complex number objects + use structures of this type as input or output values, as appropriate. It is + defined as:: + + typedef struct { + double real; + double imag; + } Py_complex; + + +.. cfunction:: Py_complex _Py_c_sum(Py_complex left, Py_complex right) + + Return the sum of two complex numbers, using the C :ctype:`Py_complex` + representation. + + +.. cfunction:: Py_complex _Py_c_diff(Py_complex left, Py_complex right) + + Return the difference between two complex numbers, using the C + :ctype:`Py_complex` representation. + + +.. cfunction:: Py_complex _Py_c_neg(Py_complex complex) + + Return the negation of the complex number *complex*, using the C + :ctype:`Py_complex` representation. + + +.. cfunction:: Py_complex _Py_c_prod(Py_complex left, Py_complex right) + + Return the product of two complex numbers, using the C :ctype:`Py_complex` + representation. + + +.. cfunction:: Py_complex _Py_c_quot(Py_complex dividend, Py_complex divisor) + + Return the quotient of two complex numbers, using the C :ctype:`Py_complex` + representation. + + +.. cfunction:: Py_complex _Py_c_pow(Py_complex num, Py_complex exp) + + Return the exponentiation of *num* by *exp*, using the C :ctype:`Py_complex` + representation. + + +Complex Numbers as Python Objects +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +.. ctype:: PyComplexObject + + This subtype of :ctype:`PyObject` represents a Python complex number object. + + +.. cvar:: PyTypeObject PyComplex_Type + + This instance of :ctype:`PyTypeObject` represents the Python complex number + type. It is the same object as ``complex`` and ``types.ComplexType``. + + +.. cfunction:: int PyComplex_Check(PyObject *p) + + Return true if its argument is a :ctype:`PyComplexObject` or a subtype of + :ctype:`PyComplexObject`. + + +.. cfunction:: int PyComplex_CheckExact(PyObject *p) + + Return true if its argument is a :ctype:`PyComplexObject`, but not a subtype of + :ctype:`PyComplexObject`. + + +.. cfunction:: PyObject* PyComplex_FromCComplex(Py_complex v) + + Create a new Python complex number object from a C :ctype:`Py_complex` value. + + +.. cfunction:: PyObject* PyComplex_FromDoubles(double real, double imag) + + Return a new :ctype:`PyComplexObject` object from *real* and *imag*. + + +.. cfunction:: double PyComplex_RealAsDouble(PyObject *op) + + Return the real part of *op* as a C :ctype:`double`. + + +.. cfunction:: double PyComplex_ImagAsDouble(PyObject *op) + + Return the imaginary part of *op* as a C :ctype:`double`. + + +.. cfunction:: Py_complex PyComplex_AsCComplex(PyObject *op) + + Return the :ctype:`Py_complex` value of the complex number *op*. + + If *op* is not a Python complex number object but has a :meth:`__complex__` + method, this method will first be called to convert *op* to a Python complex + number object. Modified: python/branches/py3k/Doc/c-api/concrete.rst ============================================================================== --- python/branches/py3k/Doc/c-api/concrete.rst (original) +++ python/branches/py3k/Doc/c-api/concrete.rst Sun Jan 20 10:30:57 2008 @@ -29,99 +29,10 @@ This section describes Python type objects and the singleton object ``None``. +.. toctree:: -.. _typeobjects: - -Type Objects ------------- - -.. index:: object: type - - -.. ctype:: PyTypeObject - - The C structure of the objects used to describe built-in types. - - -.. cvar:: PyObject* PyType_Type - - .. index:: single: TypeType (in module types) - - This is the type object for type objects; it is the same object as ``type`` and - ``types.TypeType`` in the Python layer. - - -.. cfunction:: int PyType_Check(PyObject *o) - - Return true if the object *o* is a type object, including instances of types - derived from the standard type object. Return false in all other cases. - - -.. cfunction:: int PyType_CheckExact(PyObject *o) - - Return true if the object *o* is a type object, but not a subtype of the - standard type object. Return false in all other cases. - - -.. cfunction:: int PyType_HasFeature(PyObject *o, int feature) - - Return true if the type object *o* sets the feature *feature*. Type features - are denoted by single bit flags. - - -.. cfunction:: int PyType_IS_GC(PyObject *o) - - Return true if the type object includes support for the cycle detector; this - tests the type flag :const:`Py_TPFLAGS_HAVE_GC`. - - -.. cfunction:: int PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b) - - Return true if *a* is a subtype of *b*. - - -.. cfunction:: PyObject* PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems) - - XXX: Document. - - -.. cfunction:: PyObject* PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds) - - XXX: Document. - - -.. cfunction:: int PyType_Ready(PyTypeObject *type) - - Finalize a type object. This should be called on all type objects to finish - their initialization. This function is responsible for adding inherited slots - from a type's base class. Return ``0`` on success, or return ``-1`` and sets an - exception on error. - - -.. _noneobject: - -The None Object ---------------- - -.. index:: object: None - -Note that the :ctype:`PyTypeObject` for ``None`` is not directly exposed in the -Python/C API. Since ``None`` is a singleton, testing for object identity (using -``==`` in C) is sufficient. There is no :cfunc:`PyNone_Check` function for the -same reason. - - -.. cvar:: PyObject* Py_None - - The Python ``None`` object, denoting lack of value. This object has no methods. - It needs to be treated just like any other object with respect to reference - counts. - - -.. cmacro:: Py_RETURN_NONE - - Properly handle returning :cdata:`Py_None` from within a C function (that is, - increment the reference count of None and return it.) + type.rst + none.rst .. _numericobjects: @@ -131,447 +42,12 @@ .. index:: object: numeric +.. toctree:: -.. _boolobjects: - -Boolean Objects ---------------- - -Booleans in Python are implemented as a subclass of integers. There are only -two booleans, :const:`Py_False` and :const:`Py_True`. As such, the normal -creation and deletion functions don't apply to booleans. The following macros -are available, however. - - -.. cfunction:: int PyBool_Check(PyObject *o) - - Return true if *o* is of type :cdata:`PyBool_Type`. - - -.. cvar:: PyObject* Py_False - - The Python ``False`` object. This object has no methods. It needs to be - treated just like any other object with respect to reference counts. - - -.. cvar:: PyObject* Py_True - - The Python ``True`` object. This object has no methods. It needs to be treated - just like any other object with respect to reference counts. - - -.. cmacro:: Py_RETURN_FALSE - - Return :const:`Py_False` from a function, properly incrementing its reference - count. - - -.. cmacro:: Py_RETURN_TRUE - - Return :const:`Py_True` from a function, properly incrementing its reference - count. - - -.. cfunction:: PyObject* PyBool_FromLong(long v) - - Return a new reference to :const:`Py_True` or :const:`Py_False` depending on the - truth value of *v*. - - -.. _longobjects: - -Integer Objects ---------------- - -.. index:: object: long integer - object: integer - -All integers are implemented as "long" integer objects of arbitrary size. - -.. ctype:: PyLongObject - - This subtype of :ctype:`PyObject` represents a Python integer object. - - -.. cvar:: PyTypeObject PyLong_Type - - This instance of :ctype:`PyTypeObject` represents the Python integer type. - This is the same object as ``int``. - - -.. cfunction:: int PyLong_Check(PyObject *p) - - Return true if its argument is a :ctype:`PyLongObject` or a subtype of - :ctype:`PyLongObject`. - - -.. cfunction:: int PyLong_CheckExact(PyObject *p) - - Return true if its argument is a :ctype:`PyLongObject`, but not a subtype of - :ctype:`PyLongObject`. - - -.. cfunction:: PyObject* PyLong_FromLong(long v) - - Return a new :ctype:`PyLongObject` object from *v*, or *NULL* on failure. - - The current implementation keeps an array of integer objects for all integers - between ``-5`` and ``256``, when you create an int in that range you actually - just get back a reference to the existing object. So it should be possible to - change the value of ``1``. I suspect the behaviour of Python in this case is - undefined. :-) - - -.. cfunction:: PyObject* PyLong_FromUnsignedLong(unsigned long v) - - Return a new :ctype:`PyLongObject` object from a C :ctype:`unsigned long`, or - *NULL* on failure. - - -.. cfunction:: PyObject* PyLong_FromSsize_t(Py_ssize_t v) - - Return a new :ctype:`PyLongObject` object with a value of *v*, or *NULL* - on failure. - - -.. cfunction:: PyObject* PyLong_FromSize_t(size_t v) - - Return a new :ctype:`PyLongObject` object with a value of *v*, or *NULL* - on failure. - - -.. cfunction:: PyObject* PyLong_FromLongLong(PY_LONG_LONG v) - - Return a new :ctype:`PyLongObject` object from a C :ctype:`long long`, or *NULL* - on failure. - - -.. cfunction:: PyObject* PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG v) - - Return a new :ctype:`PyLongObject` object from a C :ctype:`unsigned long long`, - or *NULL* on failure. - - -.. cfunction:: PyObject* PyLong_FromDouble(double v) - - Return a new :ctype:`PyLongObject` object from the integer part of *v*, or - *NULL* on failure. - - -.. cfunction:: PyObject* PyLong_FromString(char *str, char **pend, int base) - - Return a new :ctype:`PyLongObject` based on the string value in *str*, which - is interpreted according to the radix in *base*. If *pend* is non-*NULL*, - ``*pend`` will point to the first character in *str* which follows the - representation of the number. If *base* is ``0``, the radix will be - determined based on the leading characters of *str*: if *str* starts with - ``'0x'`` or ``'0X'``, radix 16 will be used; if *str* starts with ``'0o'`` or - ``'0O'``, radix 8 will be used; if *str* starts with ``'0b'`` or ``'0B'``, - radix 2 will be used; otherwise radix 10 will be used. If *base* is not - ``0``, it must be between ``2`` and ``36``, inclusive. Leading spaces are - ignored. If there are no digits, :exc:`ValueError` will be raised. - - -.. cfunction:: PyObject* PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base) - - Convert a sequence of Unicode digits to a Python integer value. The Unicode - string is first encoded to a byte string using :cfunc:`PyUnicode_EncodeDecimal` - and then converted using :cfunc:`PyLong_FromString`. - - -.. cfunction:: PyObject* PyLong_FromVoidPtr(void *p) - - Create a Python integer from the pointer *p*. The pointer value can be - retrieved from the resulting value using :cfunc:`PyLong_AsVoidPtr`. - - -.. XXX alias PyLong_AS_LONG (for now) -.. cfunction:: long PyLong_AsLong(PyObject *pylong) - - .. index:: - single: LONG_MAX - single: OverflowError (built-in exception) - - Return a C :ctype:`long` representation of the contents of *pylong*. If - *pylong* is greater than :const:`LONG_MAX`, raise an :exc:`OverflowError`, - and return -1. Convert non-long objects automatically to long first, - and return -1 if that raises exceptions. - -.. cfunction:: long PyLong_AsLongAndOverflow(PyObject *pylong, int* overflow) - - Return a C :ctype:`long` representation of the contents of *pylong*. If - *pylong* is greater than :const:`LONG_MAX`, return -1 and - set `*overflow` to 1 (for overflow) or -1 (for underflow). - If an exception is set because of type errors, also return -1. - - -.. cfunction:: unsigned long PyLong_AsUnsignedLong(PyObject *pylong) - - .. index:: - single: ULONG_MAX - single: OverflowError (built-in exception) - - Return a C :ctype:`unsigned long` representation of the contents of *pylong*. - If *pylong* is greater than :const:`ULONG_MAX`, an :exc:`OverflowError` is - raised. - - -.. cfunction:: Py_ssize_t PyLong_AsSsize_t(PyObject *pylong) - - .. index:: - single: PY_SSIZE_T_MAX - - Return a :ctype:`Py_ssize_t` representation of the contents of *pylong*. If - *pylong* is greater than :const:`PY_SSIZE_T_MAX`, an :exc:`OverflowError` is - raised. - - -.. cfunction:: size_t PyLong_AsSize_t(PyObject *pylong) - - Return a :ctype:`size_t` representation of the contents of *pylong*. If - *pylong* is greater than the maximum value for a :ctype:`size_t`, an - :exc:`OverflowError` is raised. - - -.. cfunction:: PY_LONG_LONG PyLong_AsLongLong(PyObject *pylong) - - Return a C :ctype:`long long` from a Python integer. If *pylong* cannot be - represented as a :ctype:`long long`, an :exc:`OverflowError` will be raised. - - -.. cfunction:: unsigned PY_LONG_LONG PyLong_AsUnsignedLongLong(PyObject *pylong) - - Return a C :ctype:`unsigned long long` from a Python integer. If *pylong* - cannot be represented as an :ctype:`unsigned long long`, an :exc:`OverflowError` - will be raised if the value is positive, or a :exc:`TypeError` will be raised if - the value is negative. - - -.. cfunction:: unsigned long PyLong_AsUnsignedLongMask(PyObject *io) - - Return a C :ctype:`unsigned long` from a Python integer, without checking for - overflow. - - -.. cfunction:: unsigned PY_LONG_LONG PyLong_AsUnsignedLongLongMask(PyObject *io) - - Return a C :ctype:`unsigned long long` from a Python integer, without - checking for overflow. - - -.. cfunction:: double PyLong_AsDouble(PyObject *pylong) - - Return a C :ctype:`double` representation of the contents of *pylong*. If - *pylong* cannot be approximately represented as a :ctype:`double`, an - :exc:`OverflowError` exception is raised and ``-1.0`` will be returned. - - -.. cfunction:: void* PyLong_AsVoidPtr(PyObject *pylong) - - Convert a Python integer *pylong* to a C :ctype:`void` pointer. If *pylong* - cannot be converted, an :exc:`OverflowError` will be raised. This is only - assured to produce a usable :ctype:`void` pointer for values created with - :cfunc:`PyLong_FromVoidPtr`. - - -.. _floatobjects: - -Floating Point Objects ----------------------- - -.. index:: object: floating point - - -.. ctype:: PyFloatObject - - This subtype of :ctype:`PyObject` represents a Python floating point object. - - -.. cvar:: PyTypeObject PyFloat_Type - - .. index:: single: FloatType (in modules types) - - This instance of :ctype:`PyTypeObject` represents the Python floating point - type. This is the same object as ``float`` and ``types.FloatType``. - - -.. cfunction:: int PyFloat_Check(PyObject *p) - - Return true if its argument is a :ctype:`PyFloatObject` or a subtype of - :ctype:`PyFloatObject`. - - -.. cfunction:: int PyFloat_CheckExact(PyObject *p) - - Return true if its argument is a :ctype:`PyFloatObject`, but not a subtype of - :ctype:`PyFloatObject`. - - -.. cfunction:: PyObject* PyFloat_FromString(PyObject *str) - - Create a :ctype:`PyFloatObject` object based on the string value in *str*, or - *NULL* on failure. - - -.. cfunction:: PyObject* PyFloat_FromDouble(double v) - - Create a :ctype:`PyFloatObject` object from *v*, or *NULL* on failure. - - -.. cfunction:: double PyFloat_AsDouble(PyObject *pyfloat) - - Return a C :ctype:`double` representation of the contents of *pyfloat*. If - *pyfloat* is not a Python floating point object but has a :meth:`__float__` - method, this method will first be called to convert *pyfloat* into a float. - - -.. cfunction:: double PyFloat_AS_DOUBLE(PyObject *pyfloat) - - Return a C :ctype:`double` representation of the contents of *pyfloat*, but - without error checking. - - -.. cfunction:: PyObject* PyFloat_GetInfo(void) - - Return a structseq instance which contains information about the - precision, minimum and maximum values of a float. It's a thin wrapper - around the header file :file:`float.h`. - - -.. cfunction:: double PyFloat_GetMax(void) - - Return the maximum representable finite float *DBL_MAX* as C :ctype:`double`. - - -.. cfunction:: double PyFloat_GetMin(void) - - Return the minimum normalized positive float *DBL_MIN* as C :ctype:`double`. - - -.. _complexobjects: - -Complex Number Objects ----------------------- - -.. index:: object: complex number - -Python's complex number objects are implemented as two distinct types when -viewed from the C API: one is the Python object exposed to Python programs, and -the other is a C structure which represents the actual complex number value. -The API provides functions for working with both. - - -Complex Numbers as C Structures -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Note that the functions which accept these structures as parameters and return -them as results do so *by value* rather than dereferencing them through -pointers. This is consistent throughout the API. - - -.. ctype:: Py_complex - - The C structure which corresponds to the value portion of a Python complex - number object. Most of the functions for dealing with complex number objects - use structures of this type as input or output values, as appropriate. It is - defined as:: - - typedef struct { - double real; - double imag; - } Py_complex; - - -.. cfunction:: Py_complex _Py_c_sum(Py_complex left, Py_complex right) - - Return the sum of two complex numbers, using the C :ctype:`Py_complex` - representation. - - -.. cfunction:: Py_complex _Py_c_diff(Py_complex left, Py_complex right) - - Return the difference between two complex numbers, using the C - :ctype:`Py_complex` representation. - - -.. cfunction:: Py_complex _Py_c_neg(Py_complex complex) - - Return the negation of the complex number *complex*, using the C - :ctype:`Py_complex` representation. - - -.. cfunction:: Py_complex _Py_c_prod(Py_complex left, Py_complex right) - - Return the product of two complex numbers, using the C :ctype:`Py_complex` - representation. - - -.. cfunction:: Py_complex _Py_c_quot(Py_complex dividend, Py_complex divisor) - - Return the quotient of two complex numbers, using the C :ctype:`Py_complex` - representation. - - -.. cfunction:: Py_complex _Py_c_pow(Py_complex num, Py_complex exp) - - Return the exponentiation of *num* by *exp*, using the C :ctype:`Py_complex` - representation. - - -Complex Numbers as Python Objects -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - -.. ctype:: PyComplexObject - - This subtype of :ctype:`PyObject` represents a Python complex number object. - - -.. cvar:: PyTypeObject PyComplex_Type - - This instance of :ctype:`PyTypeObject` represents the Python complex number - type. It is the same object as ``complex`` and ``types.ComplexType``. - - -.. cfunction:: int PyComplex_Check(PyObject *p) - - Return true if its argument is a :ctype:`PyComplexObject` or a subtype of - :ctype:`PyComplexObject`. - - -.. cfunction:: int PyComplex_CheckExact(PyObject *p) - - Return true if its argument is a :ctype:`PyComplexObject`, but not a subtype of - :ctype:`PyComplexObject`. - - -.. cfunction:: PyObject* PyComplex_FromCComplex(Py_complex v) - - Create a new Python complex number object from a C :ctype:`Py_complex` value. - - -.. cfunction:: PyObject* PyComplex_FromDoubles(double real, double imag) - - Return a new :ctype:`PyComplexObject` object from *real* and *imag*. - - -.. cfunction:: double PyComplex_RealAsDouble(PyObject *op) - - Return the real part of *op* as a C :ctype:`double`. - - -.. cfunction:: double PyComplex_ImagAsDouble(PyObject *op) - - Return the imaginary part of *op* as a C :ctype:`double`. - - -.. cfunction:: Py_complex PyComplex_AsCComplex(PyObject *op) - - Return the :ctype:`Py_complex` value of the complex number *op*. - - If *op* is not a Python complex number object but has a :meth:`__complex__` - method, this method will first be called to convert *op* to a Python complex - number object. + long.rst + bool.rst + float.rst + complex.rst .. _sequenceobjects: @@ -587,2819 +63,44 @@ .. XXX sort out unicode, str, bytes and bytearray -.. _stringobjects: - -String Objects --------------- - -These functions raise :exc:`TypeError` when expecting a string parameter and are -called with a non-string parameter. - -.. index:: object: string - +.. toctree:: -.. ctype:: PyStringObject + string.rst + unicode.rst + buffer.rst + tuple.rst + list.rst - This subtype of :ctype:`PyObject` represents a Python string object. +.. _mapobjects: -.. cvar:: PyTypeObject PyString_Type - - .. index:: single: StringType (in module types) - - This instance of :ctype:`PyTypeObject` represents the Python string type; it is - the same object as ``str`` and ``types.StringType`` in the Python layer. . - +Mapping Objects +=============== -.. cfunction:: int PyString_Check(PyObject *o) +.. index:: object: mapping - Return true if the object *o* is a string object or an instance of a subtype of - the string type. +.. toctree:: + dict.rst -.. cfunction:: int PyString_CheckExact(PyObject *o) - Return true if the object *o* is a string object, but not an instance of a - subtype of the string type. +.. _otherobjects: +Other Objects +============= -.. cfunction:: PyObject* PyString_FromString(const char *v) - - Return a new string object with a copy of the string *v* as value on success, - and *NULL* on failure. The parameter *v* must not be *NULL*; it will not be - checked. - - -.. cfunction:: PyObject* PyString_FromStringAndSize(const char *v, Py_ssize_t len) - - Return a new string object with a copy of the string *v* as value and length - *len* on success, and *NULL* on failure. If *v* is *NULL*, the contents of the - string are uninitialized. - - -.. cfunction:: PyObject* PyString_FromFormat(const char *format, ...) - - Take a C :cfunc:`printf`\ -style *format* string and a variable number of - arguments, calculate the size of the resulting Python string and return a string - with the values formatted into it. The variable arguments must be C types and - must correspond exactly to the format characters in the *format* string. The - following format characters are allowed: - - .. % XXX: This should be exactly the same as the table in PyErr_Format. - .. % One should just refer to the other. - .. % XXX: The descriptions for %zd and %zu are wrong, but the truth is complicated - .. % because not all compilers support the %z width modifier -- we fake it - .. % when necessary via interpolating PY_FORMAT_SIZE_T. - .. % %u, %lu, %zu should have "new in Python 2.5" blurbs. - - +-------------------+---------------+--------------------------------+ - | Format Characters | Type | Comment | - +===================+===============+================================+ - | :attr:`%%` | *n/a* | The literal % character. | - +-------------------+---------------+--------------------------------+ - | :attr:`%c` | int | A single character, | - | | | represented as an C int. | - +-------------------+---------------+--------------------------------+ - | :attr:`%d` | int | Exactly equivalent to | - | | | ``printf("%d")``. | - +-------------------+---------------+--------------------------------+ - | :attr:`%u` | unsigned int | Exactly equivalent to | - | | | ``printf("%u")``. | - +-------------------+---------------+--------------------------------+ - | :attr:`%ld` | long | Exactly equivalent to | - | | | ``printf("%ld")``. | - +-------------------+---------------+--------------------------------+ - | :attr:`%lu` | unsigned long | Exactly equivalent to | - | | | ``printf("%lu")``. | - +-------------------+---------------+--------------------------------+ - | :attr:`%zd` | Py_ssize_t | Exactly equivalent to | - | | | ``printf("%zd")``. | - +-------------------+---------------+--------------------------------+ - | :attr:`%zu` | size_t | Exactly equivalent to | - | | | ``printf("%zu")``. | - +-------------------+---------------+--------------------------------+ - | :attr:`%i` | int | Exactly equivalent to | - | | | ``printf("%i")``. | - +-------------------+---------------+--------------------------------+ - | :attr:`%x` | int | Exactly equivalent to | - | | | ``printf("%x")``. | - +-------------------+---------------+--------------------------------+ - | :attr:`%s` | char\* | A null-terminated C character | - | | | array. | - +-------------------+---------------+--------------------------------+ - | :attr:`%p` | void\* | The hex representation of a C | - | | | pointer. Mostly equivalent to | - | | | ``printf("%p")`` except that | - | | | it is guaranteed to start with | - | | | the literal ``0x`` regardless | - | | | of what the platform's | - | | | ``printf`` yields. | - +-------------------+---------------+--------------------------------+ - - 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. - - -.. cfunction:: PyObject* PyString_FromFormatV(const char *format, va_list vargs) - - Identical to :func:`PyString_FromFormat` except that it takes exactly two - arguments. - - -.. cfunction:: Py_ssize_t PyString_Size(PyObject *string) - - Return the length of the string in string object *string*. - - -.. cfunction:: Py_ssize_t PyString_GET_SIZE(PyObject *string) - - Macro form of :cfunc:`PyString_Size` but without error checking. - - -.. cfunction:: char* PyString_AsString(PyObject *string) - - Return a NUL-terminated representation of the contents of *string*. The pointer - refers to the internal buffer of *string*, not a copy. The data must not be - modified in any way, unless the string was just created using - ``PyString_FromStringAndSize(NULL, size)``. It must not be deallocated. If - *string* is a Unicode object, this function computes the default encoding of - *string* and operates on that. If *string* is not a string object at all, - :cfunc:`PyString_AsString` returns *NULL* and raises :exc:`TypeError`. - - -.. cfunction:: char* PyString_AS_STRING(PyObject *string) - - Macro form of :cfunc:`PyString_AsString` but without error checking. Only - string objects are supported; no Unicode objects should be passed. - - -.. cfunction:: int PyString_AsStringAndSize(PyObject *obj, char **buffer, Py_ssize_t *length) - - Return a NUL-terminated representation of the contents of the object *obj* - through the output variables *buffer* and *length*. - - The function accepts both string and Unicode objects as input. For Unicode - objects it returns the default encoded version of the object. If *length* is - *NULL*, the resulting buffer may not contain NUL characters; if it does, the - function returns ``-1`` and a :exc:`TypeError` is raised. - - The buffer refers to an internal string buffer of *obj*, not a copy. The data - must not be modified in any way, unless the string was just created using - ``PyString_FromStringAndSize(NULL, size)``. It must not be deallocated. If - *string* is a Unicode object, this function computes the default encoding of - *string* and operates on that. If *string* is not a string object at all, - :cfunc:`PyString_AsStringAndSize` returns ``-1`` and raises :exc:`TypeError`. - - -.. cfunction:: void PyString_Concat(PyObject **string, PyObject *newpart) - - Create a new string object in *\*string* containing the contents of *newpart* - appended to *string*; the caller will own the new reference. The reference to - the old value of *string* will be stolen. If the new string cannot be created, - the old reference to *string* will still be discarded and the value of - *\*string* will be set to *NULL*; the appropriate exception will be set. - - -.. cfunction:: void PyString_ConcatAndDel(PyObject **string, PyObject *newpart) - - Create a new string object in *\*string* containing the contents of *newpart* - appended to *string*. This version decrements the reference count of *newpart*. - - -.. cfunction:: int _PyString_Resize(PyObject **string, Py_ssize_t newsize) - - A way to resize a string object even though it is "immutable". Only use this to - build up a brand new string object; don't use this if the string may already be - known in other parts of the code. It is an error to call this function if the - refcount on the input string object is not one. Pass the address of an existing - string object as an lvalue (it may be written into), and the new size desired. - On success, *\*string* holds the resized string object and ``0`` is returned; - the address in *\*string* may differ from its input value. If the reallocation - fails, the original string object at *\*string* is deallocated, *\*string* is - set to *NULL*, a memory exception is set, and ``-1`` is returned. - - -.. cfunction:: PyObject* PyString_Format(PyObject *format, PyObject *args) - - Return a new string object from *format* and *args*. Analogous to ``format % - args``. The *args* argument must be a tuple. - - -.. cfunction:: void PyString_InternInPlace(PyObject **string) - - Intern the argument *\*string* in place. The argument must be the address of a - pointer variable pointing to a Python string object. If there is an existing - interned string that is the same as *\*string*, it sets *\*string* to it - (decrementing the reference count of the old string object and incrementing the - reference count of the interned string object), otherwise it leaves *\*string* - alone and interns it (incrementing its reference count). (Clarification: even - though there is a lot of talk about reference counts, think of this function as - reference-count-neutral; you own the object after the call if and only if you - owned it before the call.) - - -.. cfunction:: PyObject* PyString_InternFromString(const char *v) - - A combination of :cfunc:`PyString_FromString` and - :cfunc:`PyString_InternInPlace`, returning either a new string object that has - been interned, or a new ("owned") reference to an earlier interned string object - with the same value. - - -.. cfunction:: PyObject* PyString_Decode(const char *s, Py_ssize_t size, const char *encoding, const char *errors) - - Create an object by decoding *size* bytes of the encoded buffer *s* using the - codec registered for *encoding*. *encoding* and *errors* have the same meaning - as the parameters of the same name in the :func:`unicode` built-in function. - The codec to be used is looked up using the Python codec registry. Return - *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyString_AsDecodedObject(PyObject *str, const char *encoding, const char *errors) - - Decode a string object by passing it to the codec registered for *encoding* and - return the result as Python object. *encoding* and *errors* have the same - meaning as the parameters of the same name in the string :meth:`encode` method. - The codec to be used is looked up using the Python codec registry. Return *NULL* - if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyString_AsEncodedObject(PyObject *str, const char *encoding, const char *errors) - - Encode a string object using the codec registered for *encoding* and return the - result as Python object. *encoding* and *errors* have the same meaning as the - parameters of the same name in the string :meth:`encode` method. The codec to be - used is looked up using the Python codec registry. Return *NULL* if an exception - was raised by the codec. - - -.. _unicodeobjects: - -Unicode Objects ---------------- - -.. sectionauthor:: Marc-Andre Lemburg - - -These are the basic Unicode object types used for the Unicode implementation in -Python: - -.. % --- Unicode Type ------------------------------------------------------- - - -.. ctype:: Py_UNICODE - - This type represents the storage type which is used by Python internally as - basis for holding Unicode ordinals. Python's default builds use a 16-bit type - for :ctype:`Py_UNICODE` and store Unicode values internally as UCS2. It is also - possible to build a UCS4 version of Python (most recent Linux distributions come - with UCS4 builds of Python). These builds then use a 32-bit type for - :ctype:`Py_UNICODE` and store Unicode data internally as UCS4. On platforms - where :ctype:`wchar_t` is available and compatible with the chosen Python - Unicode build variant, :ctype:`Py_UNICODE` is a typedef alias for - :ctype:`wchar_t` to enhance native platform compatibility. On all other - platforms, :ctype:`Py_UNICODE` is a typedef alias for either :ctype:`unsigned - short` (UCS2) or :ctype:`unsigned long` (UCS4). - -Note that UCS2 and UCS4 Python builds are not binary compatible. Please keep -this in mind when writing extensions or interfaces. - - -.. ctype:: PyUnicodeObject - - This subtype of :ctype:`PyObject` represents a Python Unicode object. - - -.. cvar:: PyTypeObject PyUnicode_Type - - This instance of :ctype:`PyTypeObject` represents the Python Unicode type. It - is exposed to Python code as ``str``. - -The following APIs are really C macros and can be used to do fast checks and to -access internal read-only data of Unicode objects: - - -.. cfunction:: int PyUnicode_Check(PyObject *o) - - Return true if the object *o* is a Unicode object or an instance of a Unicode - subtype. - - -.. cfunction:: int PyUnicode_CheckExact(PyObject *o) - - Return true if the object *o* is a Unicode object, but not an instance of a - subtype. - - -.. cfunction:: Py_ssize_t PyUnicode_GET_SIZE(PyObject *o) - - Return the size of the object. *o* has to be a :ctype:`PyUnicodeObject` (not - checked). - - -.. cfunction:: Py_ssize_t PyUnicode_GET_DATA_SIZE(PyObject *o) - - Return the size of the object's internal buffer in bytes. *o* has to be a - :ctype:`PyUnicodeObject` (not checked). - - -.. cfunction:: Py_UNICODE* PyUnicode_AS_UNICODE(PyObject *o) - - Return a pointer to the internal :ctype:`Py_UNICODE` buffer of the object. *o* - has to be a :ctype:`PyUnicodeObject` (not checked). - - -.. cfunction:: const char* PyUnicode_AS_DATA(PyObject *o) - - Return a pointer to the internal buffer of the object. *o* has to be a - :ctype:`PyUnicodeObject` (not checked). - -Unicode provides many different character properties. The most often needed ones -are available through these macros which are mapped to C functions depending on -the Python configuration. - -.. % --- Unicode character properties --------------------------------------- - - -.. cfunction:: int Py_UNICODE_ISSPACE(Py_UNICODE ch) - - Return 1 or 0 depending on whether *ch* is a whitespace character. - - -.. cfunction:: int Py_UNICODE_ISLOWER(Py_UNICODE ch) - - Return 1 or 0 depending on whether *ch* is a lowercase character. - - -.. cfunction:: int Py_UNICODE_ISUPPER(Py_UNICODE ch) - - Return 1 or 0 depending on whether *ch* is an uppercase character. - - -.. cfunction:: int Py_UNICODE_ISTITLE(Py_UNICODE ch) - - Return 1 or 0 depending on whether *ch* is a titlecase character. - - -.. cfunction:: int Py_UNICODE_ISLINEBREAK(Py_UNICODE ch) - - Return 1 or 0 depending on whether *ch* is a linebreak character. - - -.. cfunction:: int Py_UNICODE_ISDECIMAL(Py_UNICODE ch) - - Return 1 or 0 depending on whether *ch* is a decimal character. - - -.. cfunction:: int Py_UNICODE_ISDIGIT(Py_UNICODE ch) - - Return 1 or 0 depending on whether *ch* is a digit character. - - -.. cfunction:: int Py_UNICODE_ISNUMERIC(Py_UNICODE ch) - - Return 1 or 0 depending on whether *ch* is a numeric character. - - -.. cfunction:: int Py_UNICODE_ISALPHA(Py_UNICODE ch) - - Return 1 or 0 depending on whether *ch* is an alphabetic character. - - -.. cfunction:: int Py_UNICODE_ISALNUM(Py_UNICODE ch) - - Return 1 or 0 depending on whether *ch* is an alphanumeric character. - -These APIs can be used for fast direct character conversions: - - -.. cfunction:: Py_UNICODE Py_UNICODE_TOLOWER(Py_UNICODE ch) - - Return the character *ch* converted to lower case. - - -.. cfunction:: Py_UNICODE Py_UNICODE_TOUPPER(Py_UNICODE ch) - - Return the character *ch* converted to upper case. - - -.. cfunction:: Py_UNICODE Py_UNICODE_TOTITLE(Py_UNICODE ch) - - Return the character *ch* converted to title case. - - -.. cfunction:: int Py_UNICODE_TODECIMAL(Py_UNICODE ch) - - Return the character *ch* converted to a decimal positive integer. Return - ``-1`` if this is not possible. This macro does not raise exceptions. - - -.. cfunction:: int Py_UNICODE_TODIGIT(Py_UNICODE ch) - - Return the character *ch* converted to a single digit integer. Return ``-1`` if - this is not possible. This macro does not raise exceptions. - - -.. cfunction:: double Py_UNICODE_TONUMERIC(Py_UNICODE ch) - - Return the character *ch* converted to a double. Return ``-1.0`` if this is not - possible. This macro does not raise exceptions. - -To create Unicode objects and access their basic sequence properties, use these -APIs: - -.. % --- Plain Py_UNICODE --------------------------------------------------- - - -.. cfunction:: PyObject* PyUnicode_FromUnicode(const Py_UNICODE *u, Py_ssize_t size) - - Create a Unicode Object from the Py_UNICODE buffer *u* of the given size. *u* - may be *NULL* which causes the contents to be undefined. It is the user's - responsibility to fill in the needed data. The buffer is copied into the new - object. If the buffer is not *NULL*, the return value might be a shared object. - Therefore, modification of the resulting Unicode object is only allowed when *u* - is *NULL*. - - -.. cfunction:: PyObject* PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size) - - Create a Unicode Object from the char buffer *u*. The bytes will be interpreted - as being UTF-8 encoded. *u* may also be *NULL* which - causes the contents to be undefined. It is the user's responsibility to fill in - the needed data. The buffer is copied into the new object. If the buffer is not - *NULL*, the return value might be a shared object. Therefore, modification of - the resulting Unicode object is only allowed when *u* is *NULL*. - - -.. cfunction:: PyObject *PyUnicode_FromString(const char *u) - - Create a Unicode object from an UTF-8 encoded null-terminated char buffer - *u*. - - -.. cfunction:: PyObject* PyUnicode_FromFormat(const char *format, ...) - - Take a C :cfunc:`printf`\ -style *format* string and a variable number of - arguments, calculate the size of the resulting Python unicode string and return - a string with the values formatted into it. The variable arguments must be C - types and must correspond exactly to the format characters in the *format* - string. The following format characters are allowed: - - .. % The descriptions for %zd and %zu are wrong, but the truth is complicated - .. % because not all compilers support the %z width modifier -- we fake it - .. % when necessary via interpolating PY_FORMAT_SIZE_T. - - +-------------------+---------------------+--------------------------------+ - | Format Characters | Type | Comment | - +===================+=====================+================================+ - | :attr:`%%` | *n/a* | The literal % character. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%c` | int | A single character, | - | | | represented as an C int. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%d` | int | Exactly equivalent to | - | | | ``printf("%d")``. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%u` | unsigned int | Exactly equivalent to | - | | | ``printf("%u")``. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%ld` | long | Exactly equivalent to | - | | | ``printf("%ld")``. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%lu` | unsigned long | Exactly equivalent to | - | | | ``printf("%lu")``. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%zd` | Py_ssize_t | Exactly equivalent to | - | | | ``printf("%zd")``. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%zu` | size_t | Exactly equivalent to | - | | | ``printf("%zu")``. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%i` | int | Exactly equivalent to | - | | | ``printf("%i")``. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%x` | int | Exactly equivalent to | - | | | ``printf("%x")``. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%s` | char\* | A null-terminated C character | - | | | array. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%p` | void\* | The hex representation of a C | - | | | pointer. Mostly equivalent to | - | | | ``printf("%p")`` except that | - | | | it is guaranteed to start with | - | | | the literal ``0x`` regardless | - | | | of what the platform's | - | | | ``printf`` yields. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%U` | PyObject\* | A unicode object. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%V` | PyObject\*, char \* | A unicode object (which may be | - | | | *NULL*) and a null-terminated | - | | | C character array as a second | - | | | parameter (which will be used, | - | | | if the first parameter is | - | | | *NULL*). | - +-------------------+---------------------+--------------------------------+ - | :attr:`%S` | PyObject\* | The result of calling | - | | | :func:`PyObject_Unicode`. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%R` | PyObject\* | The result of calling | - | | | :func:`PyObject_Repr`. | - +-------------------+---------------------+--------------------------------+ - - 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. - - -.. cfunction:: PyObject* PyUnicode_FromFormatV(const char *format, va_list vargs) - - Identical to :func:`PyUnicode_FromFormat` except that it takes exactly two - arguments. - - -.. cfunction:: Py_UNICODE* PyUnicode_AsUnicode(PyObject *unicode) - - Return a read-only pointer to the Unicode object's internal :ctype:`Py_UNICODE` - buffer, *NULL* if *unicode* is not a Unicode object. - - -.. cfunction:: Py_ssize_t PyUnicode_GetSize(PyObject *unicode) - - Return the length of the Unicode object. - - -.. cfunction:: PyObject* PyUnicode_FromEncodedObject(PyObject *obj, const char *encoding, const char *errors) - - Coerce an encoded object *obj* to an Unicode object and return a reference with - incremented refcount. - - String and other char buffer compatible objects are decoded according to the - given encoding and using the error handling defined by errors. Both can be - *NULL* to have the interface use the default values (see the next section for - details). - - All other objects, including Unicode objects, cause a :exc:`TypeError` to be - set. - - The API returns *NULL* if there was an error. The caller is responsible for - decref'ing the returned objects. - - -.. cfunction:: PyObject* PyUnicode_FromObject(PyObject *obj) - - Shortcut for ``PyUnicode_FromEncodedObject(obj, NULL, "strict")`` which is used - throughout the interpreter whenever coercion to Unicode is needed. - -If the platform supports :ctype:`wchar_t` and provides a header file wchar.h, -Python can interface directly to this type using the following functions. -Support is optimized if Python's own :ctype:`Py_UNICODE` type is identical to -the system's :ctype:`wchar_t`. - -.. % --- wchar_t support for platforms which support it --------------------- - - -.. cfunction:: PyObject* PyUnicode_FromWideChar(const wchar_t *w, Py_ssize_t size) - - Create a Unicode object from the :ctype:`wchar_t` buffer *w* of the given size. - Return *NULL* on failure. - - -.. cfunction:: Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode, wchar_t *w, Py_ssize_t size) - - Copy the Unicode object contents into the :ctype:`wchar_t` buffer *w*. At most - *size* :ctype:`wchar_t` characters are copied (excluding a possibly trailing - 0-termination character). Return the number of :ctype:`wchar_t` characters - copied or -1 in case of an error. Note that the resulting :ctype:`wchar_t` - string may or may not be 0-terminated. It is the responsibility of the caller - to make sure that the :ctype:`wchar_t` string is 0-terminated in case this is - required by the application. - - -.. _builtincodecs: - -Built-in Codecs -^^^^^^^^^^^^^^^ - -Python provides a set of builtin codecs which are written in C for speed. All of -these codecs are directly usable via the following functions. - -Many of the following APIs take two arguments encoding and errors. These -parameters encoding and errors have the same semantics as the ones of the -builtin unicode() Unicode object constructor. - -Setting encoding to *NULL* causes the default encoding to be used which is -ASCII. The file system calls should use :cdata:`Py_FileSystemDefaultEncoding` -as the encoding for file names. This variable should be treated as read-only: On -some systems, it will be a pointer to a static string, on others, it will change -at run-time (such as when the application invokes setlocale). - -Error handling is set by errors which may also be set to *NULL* meaning to use -the default handling defined for the codec. Default error handling for all -builtin codecs is "strict" (:exc:`ValueError` is raised). - -The codecs all use a similar interface. Only deviation from the following -generic ones are documented for simplicity. - -These are the generic codec APIs: - -.. % --- Generic Codecs ----------------------------------------------------- - - -.. cfunction:: PyObject* PyUnicode_Decode(const char *s, Py_ssize_t size, const char *encoding, const char *errors) - - Create a Unicode object by decoding *size* bytes of the encoded string *s*. - *encoding* and *errors* have the same meaning as the parameters of the same name - in the :func:`unicode` builtin function. The codec to be used is looked up - using the Python codec registry. Return *NULL* if an exception was raised by - the codec. - - -.. cfunction:: PyObject* PyUnicode_Encode(const Py_UNICODE *s, Py_ssize_t size, const char *encoding, const char *errors) - - Encode the :ctype:`Py_UNICODE` buffer of the given size and return a Python - string object. *encoding* and *errors* have the same meaning as the parameters - of the same name in the Unicode :meth:`encode` method. The codec to be used is - looked up using the Python codec registry. Return *NULL* if an exception was - raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_AsEncodedString(PyObject *unicode, const char *encoding, const char *errors) - - Encode a Unicode object and return the result as Python string object. - *encoding* and *errors* have the same meaning as the parameters of the same name - in the Unicode :meth:`encode` method. The codec to be used is looked up using - the Python codec registry. Return *NULL* if an exception was raised by the - codec. - -These are the UTF-8 codec APIs: - -.. % --- UTF-8 Codecs ------------------------------------------------------- - - -.. cfunction:: PyObject* PyUnicode_DecodeUTF8(const char *s, Py_ssize_t size, const char *errors) - - Create a Unicode object by decoding *size* bytes of the UTF-8 encoded string - *s*. Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_DecodeUTF8Stateful(const char *s, Py_ssize_t size, const char *errors, Py_ssize_t *consumed) - - If *consumed* is *NULL*, behave like :cfunc:`PyUnicode_DecodeUTF8`. If - *consumed* is not *NULL*, trailing incomplete UTF-8 byte sequences will not be - treated as an error. Those bytes will not be decoded and the number of bytes - that have been decoded will be stored in *consumed*. - - -.. cfunction:: PyObject* PyUnicode_EncodeUTF8(const Py_UNICODE *s, Py_ssize_t size, const char *errors) - - Encode the :ctype:`Py_UNICODE` buffer of the given size using UTF-8 and return a - Python string object. Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_AsUTF8String(PyObject *unicode) - - Encode a Unicode object using UTF-8 and return the result as Python string - object. Error handling is "strict". Return *NULL* if an exception was raised - by the codec. - -These are the UTF-32 codec APIs: - -.. % --- UTF-32 Codecs ------------------------------------------------------ */ - - -.. cfunction:: PyObject* PyUnicode_DecodeUTF32(const char *s, Py_ssize_t size, const char *errors, int *byteorder) - - Decode *length* bytes from a UTF-32 encoded buffer string and return the - corresponding Unicode object. *errors* (if non-*NULL*) defines the error - handling. It defaults to "strict". - - If *byteorder* is non-*NULL*, the decoder starts decoding using the given byte - order:: - - *byteorder == -1: little endian - *byteorder == 0: native order - *byteorder == 1: big endian - - and then switches if the first four bytes of the input data are a byte order mark - (BOM) and the specified byte order is native order. This BOM is not copied into - the resulting Unicode string. After completion, *\*byteorder* is set to the - current byte order at the end of input data. - - In a narrow build codepoints outside the BMP will be decoded as surrogate pairs. - - If *byteorder* is *NULL*, the codec starts in native order mode. - - Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_DecodeUTF32Stateful(const char *s, Py_ssize_t size, const char *errors, int *byteorder, Py_ssize_t *consumed) - - If *consumed* is *NULL*, behave like :cfunc:`PyUnicode_DecodeUTF32`. If - *consumed* is not *NULL*, :cfunc:`PyUnicode_DecodeUTF32Stateful` will not treat - trailing incomplete UTF-32 byte sequences (such as a number of bytes not divisible - by four) as an error. Those bytes will not be decoded and the number of bytes - that have been decoded will be stored in *consumed*. - - -.. cfunction:: PyObject* PyUnicode_EncodeUTF32(const Py_UNICODE *s, Py_ssize_t size, const char *errors, int byteorder) - - Return a Python bytes object holding the UTF-32 encoded value of the Unicode - data in *s*. If *byteorder* is not ``0``, output is written according to the - following byte order:: - - byteorder == -1: little endian - byteorder == 0: native byte order (writes a BOM mark) - byteorder == 1: big endian - - If byteorder is ``0``, the output string will always start with the Unicode BOM - mark (U+FEFF). In the other two modes, no BOM mark is prepended. - - If *Py_UNICODE_WIDE* is not defined, surrogate pairs will be output - as a single codepoint. - - Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_AsUTF32String(PyObject *unicode) - - Return a Python string using the UTF-32 encoding in native byte order. The - string always starts with a BOM mark. Error handling is "strict". Return - *NULL* if an exception was raised by the codec. - - -These are the UTF-16 codec APIs: - -.. % --- UTF-16 Codecs ------------------------------------------------------ */ - - -.. cfunction:: PyObject* PyUnicode_DecodeUTF16(const char *s, Py_ssize_t size, const char *errors, int *byteorder) - - Decode *length* bytes from a UTF-16 encoded buffer string and return the - corresponding Unicode object. *errors* (if non-*NULL*) defines the error - handling. It defaults to "strict". - - If *byteorder* is non-*NULL*, the decoder starts decoding using the given byte - order:: - - *byteorder == -1: little endian - *byteorder == 0: native order - *byteorder == 1: big endian - - and then switches if the first two bytes of the input data are a byte order mark - (BOM) and the specified byte order is native order. This BOM is not copied into - the resulting Unicode string. After completion, *\*byteorder* is set to the - current byte order at the end of input data. - - If *byteorder* is *NULL*, the codec starts in native order mode. - - Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_DecodeUTF16Stateful(const char *s, Py_ssize_t size, const char *errors, int *byteorder, Py_ssize_t *consumed) - - If *consumed* is *NULL*, behave like :cfunc:`PyUnicode_DecodeUTF16`. If - *consumed* is not *NULL*, :cfunc:`PyUnicode_DecodeUTF16Stateful` will not treat - trailing incomplete UTF-16 byte sequences (such as an odd number of bytes or a - split surrogate pair) as an error. Those bytes will not be decoded and the - number of bytes that have been decoded will be stored in *consumed*. - - -.. cfunction:: PyObject* PyUnicode_EncodeUTF16(const Py_UNICODE *s, Py_ssize_t size, const char *errors, int byteorder) - - Return a Python string object holding the UTF-16 encoded value of the Unicode - data in *s*. If *byteorder* is not ``0``, output is written according to the - following byte order:: - - byteorder == -1: little endian - byteorder == 0: native byte order (writes a BOM mark) - byteorder == 1: big endian - - If byteorder is ``0``, the output string will always start with the Unicode BOM - mark (U+FEFF). In the other two modes, no BOM mark is prepended. - - If *Py_UNICODE_WIDE* is defined, a single :ctype:`Py_UNICODE` value may get - represented as a surrogate pair. If it is not defined, each :ctype:`Py_UNICODE` - values is interpreted as an UCS-2 character. - - Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_AsUTF16String(PyObject *unicode) - - Return a Python string using the UTF-16 encoding in native byte order. The - string always starts with a BOM mark. Error handling is "strict". Return - *NULL* if an exception was raised by the codec. - -These are the "Unicode Escape" codec APIs: - -.. % --- Unicode-Escape Codecs ---------------------------------------------- - - -.. cfunction:: PyObject* PyUnicode_DecodeUnicodeEscape(const char *s, Py_ssize_t size, const char *errors) - - Create a Unicode object by decoding *size* bytes of the Unicode-Escape encoded - string *s*. Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size) - - Encode the :ctype:`Py_UNICODE` buffer of the given size using Unicode-Escape and - return a Python string object. Return *NULL* if an exception was raised by the - codec. - - -.. cfunction:: PyObject* PyUnicode_AsUnicodeEscapeString(PyObject *unicode) - - Encode a Unicode object using Unicode-Escape and return the result as Python - string object. Error handling is "strict". Return *NULL* if an exception was - raised by the codec. - -These are the "Raw Unicode Escape" codec APIs: - -.. % --- Raw-Unicode-Escape Codecs ------------------------------------------ - - -.. cfunction:: PyObject* PyUnicode_DecodeRawUnicodeEscape(const char *s, Py_ssize_t size, const char *errors) - - Create a Unicode object by decoding *size* bytes of the Raw-Unicode-Escape - encoded string *s*. Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size, const char *errors) - - Encode the :ctype:`Py_UNICODE` buffer of the given size using Raw-Unicode-Escape - and return a Python string object. Return *NULL* if an exception was raised by - the codec. - - -.. cfunction:: PyObject* PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode) - - Encode a Unicode object using Raw-Unicode-Escape and return the result as - Python string object. Error handling is "strict". Return *NULL* if an exception - was raised by the codec. - -These are the Latin-1 codec APIs: Latin-1 corresponds to the first 256 Unicode -ordinals and only these are accepted by the codecs during encoding. - -.. % --- Latin-1 Codecs ----------------------------------------------------- - - -.. cfunction:: PyObject* PyUnicode_DecodeLatin1(const char *s, Py_ssize_t size, const char *errors) - - Create a Unicode object by decoding *size* bytes of the Latin-1 encoded string - *s*. Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_EncodeLatin1(const Py_UNICODE *s, Py_ssize_t size, const char *errors) - - Encode the :ctype:`Py_UNICODE` buffer of the given size using Latin-1 and return - a Python string object. Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_AsLatin1String(PyObject *unicode) - - Encode a Unicode object using Latin-1 and return the result as Python string - object. Error handling is "strict". Return *NULL* if an exception was raised - by the codec. - -These are the ASCII codec APIs. Only 7-bit ASCII data is accepted. All other -codes generate errors. - -.. % --- ASCII Codecs ------------------------------------------------------- - - -.. cfunction:: PyObject* PyUnicode_DecodeASCII(const char *s, Py_ssize_t size, const char *errors) - - Create a Unicode object by decoding *size* bytes of the ASCII encoded string - *s*. Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_EncodeASCII(const Py_UNICODE *s, Py_ssize_t size, const char *errors) - - Encode the :ctype:`Py_UNICODE` buffer of the given size using ASCII and return a - Python string object. Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_AsASCIIString(PyObject *unicode) - - Encode a Unicode object using ASCII and return the result as Python string - object. Error handling is "strict". Return *NULL* if an exception was raised - by the codec. - -These are the mapping codec APIs: - -.. % --- Character Map Codecs ----------------------------------------------- - -This codec is special in that it can be used to implement many different codecs -(and this is in fact what was done to obtain most of the standard codecs -included in the :mod:`encodings` package). The codec uses mapping to encode and -decode characters. - -Decoding mappings must map single string characters to single Unicode -characters, integers (which are then interpreted as Unicode ordinals) or None -(meaning "undefined mapping" and causing an error). - -Encoding mappings must map single Unicode characters to single string -characters, integers (which are then interpreted as Latin-1 ordinals) or None -(meaning "undefined mapping" and causing an error). - -The mapping objects provided must only support the __getitem__ mapping -interface. - -If a character lookup fails with a LookupError, the character is copied as-is -meaning that its ordinal value will be interpreted as Unicode or Latin-1 ordinal -resp. Because of this, mappings only need to contain those mappings which map -characters to different code points. - - -.. cfunction:: PyObject* PyUnicode_DecodeCharmap(const char *s, Py_ssize_t size, PyObject *mapping, const char *errors) - - Create a Unicode object by decoding *size* bytes of the encoded string *s* using - the given *mapping* object. Return *NULL* if an exception was raised by the - codec. If *mapping* is *NULL* latin-1 decoding will be done. Else it can be a - dictionary mapping byte or a unicode string, which is treated as a lookup table. - Byte values greater that the length of the string and U+FFFE "characters" are - treated as "undefined mapping". - - -.. cfunction:: PyObject* PyUnicode_EncodeCharmap(const Py_UNICODE *s, Py_ssize_t size, PyObject *mapping, const char *errors) - - Encode the :ctype:`Py_UNICODE` buffer of the given size using the given - *mapping* object and return a Python string object. Return *NULL* if an - exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_AsCharmapString(PyObject *unicode, PyObject *mapping) - - Encode a Unicode object using the given *mapping* object and return the result - as Python string object. Error handling is "strict". Return *NULL* if an - exception was raised by the codec. - -The following codec API is special in that maps Unicode to Unicode. - - -.. cfunction:: PyObject* PyUnicode_TranslateCharmap(const Py_UNICODE *s, Py_ssize_t size, PyObject *table, const char *errors) - - Translate a :ctype:`Py_UNICODE` buffer of the given length by applying a - character mapping *table* to it and return the resulting Unicode object. Return - *NULL* when an exception was raised by the codec. - - The *mapping* table must map Unicode ordinal integers to Unicode ordinal - integers or None (causing deletion of the character). - - Mapping tables need only provide the :meth:`__getitem__` interface; dictionaries - and sequences work well. Unmapped character ordinals (ones which cause a - :exc:`LookupError`) are left untouched and are copied as-is. - -These are the MBCS codec APIs. They are currently only available on Windows and -use the Win32 MBCS converters to implement the conversions. Note that MBCS (or -DBCS) is a class of encodings, not just one. The target encoding is defined by -the user settings on the machine running the codec. - -.. % --- MBCS codecs for Windows -------------------------------------------- - - -.. cfunction:: PyObject* PyUnicode_DecodeMBCS(const char *s, Py_ssize_t size, const char *errors) - - Create a Unicode object by decoding *size* bytes of the MBCS encoded string *s*. - Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_DecodeMBCSStateful(const char *s, int size, const char *errors, int *consumed) - - If *consumed* is *NULL*, behave like :cfunc:`PyUnicode_DecodeMBCS`. If - *consumed* is not *NULL*, :cfunc:`PyUnicode_DecodeMBCSStateful` will not decode - trailing lead byte and the number of bytes that have been decoded will be stored - in *consumed*. - - -.. cfunction:: PyObject* PyUnicode_EncodeMBCS(const Py_UNICODE *s, Py_ssize_t size, const char *errors) - - Encode the :ctype:`Py_UNICODE` buffer of the given size using MBCS and return a - Python string object. Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_AsMBCSString(PyObject *unicode) - - Encode a Unicode object using MBCS and return the result as Python string - object. Error handling is "strict". Return *NULL* if an exception was raised - by the codec. - -.. % --- Methods & Slots ---------------------------------------------------- - - -.. _unicodemethodsandslots: - -Methods and Slot Functions -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The following APIs are capable of handling Unicode objects and strings on input -(we refer to them as strings in the descriptions) and return Unicode objects or -integers as appropriate. - -They all return *NULL* or ``-1`` if an exception occurs. - - -.. cfunction:: PyObject* PyUnicode_Concat(PyObject *left, PyObject *right) - - Concat two strings giving a new Unicode string. - - -.. cfunction:: PyObject* PyUnicode_Split(PyObject *s, PyObject *sep, Py_ssize_t maxsplit) - - Split a string giving a list of Unicode strings. If sep is *NULL*, splitting - will be done at all whitespace substrings. Otherwise, splits occur at the given - separator. At most *maxsplit* splits will be done. If negative, no limit is - set. Separators are not included in the resulting list. - - -.. cfunction:: PyObject* PyUnicode_Splitlines(PyObject *s, int keepend) - - Split a Unicode string at line breaks, returning a list of Unicode strings. - CRLF is considered to be one line break. If *keepend* is 0, the Line break - characters are not included in the resulting strings. - - -.. cfunction:: PyObject* PyUnicode_Translate(PyObject *str, PyObject *table, const char *errors) - - Translate a string by applying a character mapping table to it and return the - resulting Unicode object. - - The mapping table must map Unicode ordinal integers to Unicode ordinal integers - or None (causing deletion of the character). - - Mapping tables need only provide the :meth:`__getitem__` interface; dictionaries - and sequences work well. Unmapped character ordinals (ones which cause a - :exc:`LookupError`) are left untouched and are copied as-is. - - *errors* has the usual meaning for codecs. It may be *NULL* which indicates to - use the default error handling. - - -.. cfunction:: PyObject* PyUnicode_Join(PyObject *separator, PyObject *seq) - - Join a sequence of strings using the given separator and return the resulting - Unicode string. - - -.. cfunction:: int PyUnicode_Tailmatch(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction) - - Return 1 if *substr* matches *str*[*start*:*end*] at the given tail end - (*direction* == -1 means to do a prefix match, *direction* == 1 a suffix match), - 0 otherwise. Return ``-1`` if an error occurred. - - -.. cfunction:: Py_ssize_t PyUnicode_Find(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction) - - Return the first position of *substr* in *str*[*start*:*end*] using the given - *direction* (*direction* == 1 means to do a forward search, *direction* == -1 a - backward search). The return value is the index of the first match; a value of - ``-1`` indicates that no match was found, and ``-2`` indicates that an error - occurred and an exception has been set. - - -.. cfunction:: Py_ssize_t PyUnicode_Count(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end) - - Return the number of non-overlapping occurrences of *substr* in - ``str[start:end]``. Return ``-1`` if an error occurred. - - -.. cfunction:: PyObject* PyUnicode_Replace(PyObject *str, PyObject *substr, PyObject *replstr, Py_ssize_t maxcount) - - Replace at most *maxcount* occurrences of *substr* in *str* with *replstr* and - return the resulting Unicode object. *maxcount* == -1 means replace all - occurrences. - - -.. cfunction:: int PyUnicode_Compare(PyObject *left, PyObject *right) - - Compare two strings and return -1, 0, 1 for less than, equal, and greater than, - respectively. - - -.. cfunction:: int PyUnicode_RichCompare(PyObject *left, PyObject *right, int op) - - Rich compare two unicode strings and return one of the following: - - * ``NULL`` in case an exception was raised - * :const:`Py_True` or :const:`Py_False` for successful comparisons - * :const:`Py_NotImplemented` in case the type combination is unknown - - Note that :const:`Py_EQ` and :const:`Py_NE` comparisons can cause a - :exc:`UnicodeWarning` in case the conversion of the arguments to Unicode fails - with a :exc:`UnicodeDecodeError`. - - Possible values for *op* are :const:`Py_GT`, :const:`Py_GE`, :const:`Py_EQ`, - :const:`Py_NE`, :const:`Py_LT`, and :const:`Py_LE`. - - -.. cfunction:: PyObject* PyUnicode_Format(PyObject *format, PyObject *args) - - Return a new string object from *format* and *args*; this is analogous to - ``format % args``. The *args* argument must be a tuple. - - -.. cfunction:: int PyUnicode_Contains(PyObject *container, PyObject *element) - - Check whether *element* is contained in *container* and return true or false - accordingly. - - *element* has to coerce to a one element Unicode string. ``-1`` is returned if - there was an error. - - -.. cfunction:: void PyUnicode_InternInPlace(PyObject **string) - - Intern the argument *\*string* in place. The argument must be the address of a - pointer variable pointing to a Python unicode string object. If there is an - existing interned string that is the same as *\*string*, it sets *\*string* to - it (decrementing the reference count of the old string object and incrementing - the reference count of the interned string object), otherwise it leaves - *\*string* alone and interns it (incrementing its reference count). - (Clarification: even though there is a lot of talk about reference counts, think - of this function as reference-count-neutral; you own the object after the call - if and only if you owned it before the call.) - - -.. cfunction:: PyObject* PyUnicode_InternFromString(const char *v) - - A combination of :cfunc:`PyUnicode_FromString` and - :cfunc:`PyUnicode_InternInPlace`, returning either a new unicode string object - that has been interned, or a new ("owned") reference to an earlier interned - string object with the same value. - - -.. _bufferobjects: - -Buffer Objects --------------- - -.. sectionauthor:: Greg Stein - - -.. index:: - object: buffer - single: buffer interface - -Python objects implemented in C can export a group of functions called the -"buffer interface." These functions can be used by an object to expose its data -in a raw, byte-oriented format. Clients of the object can use the buffer -interface to access the object data directly, without needing to copy it first. - -Two examples of objects that support the buffer interface are strings and -arrays. The string object exposes the character contents in the buffer -interface's byte-oriented form. An array can also expose its contents, but it -should be noted that array elements may be multi-byte values. - -An example user of the buffer interface is the file object's :meth:`write` -method. Any object that can export a series of bytes through the buffer -interface can be written to a file. There are a number of format codes to -:cfunc:`PyArg_ParseTuple` that operate against an object's buffer interface, -returning data from the target object. - -.. index:: single: PyBufferProcs - -More information on the buffer interface is provided in the section -:ref:`buffer-structs`, under the description for :ctype:`PyBufferProcs`. - -A "buffer object" is defined in the :file:`bufferobject.h` header (included by -:file:`Python.h`). These objects look very similar to string objects at the -Python programming level: they support slicing, indexing, concatenation, and -some other standard string operations. However, their data can come from one of -two sources: from a block of memory, or from another object which exports the -buffer interface. - -Buffer objects are useful as a way to expose the data from another object's -buffer interface to the Python programmer. They can also be used as a zero-copy -slicing mechanism. Using their ability to reference a block of memory, it is -possible to expose any data to the Python programmer quite easily. The memory -could be a large, constant array in a C extension, it could be a raw block of -memory for manipulation before passing to an operating system library, or it -could be used to pass around structured data in its native, in-memory format. - - -.. ctype:: PyBufferObject - - This subtype of :ctype:`PyObject` represents a buffer object. - - -.. cvar:: PyTypeObject PyBuffer_Type - - .. index:: single: BufferType (in module types) - - The instance of :ctype:`PyTypeObject` which represents the Python buffer type; - it is the same object as ``buffer`` and ``types.BufferType`` in the Python - layer. . - - -.. cvar:: int Py_END_OF_BUFFER - - This constant may be passed as the *size* parameter to - :cfunc:`PyBuffer_FromObject` or :cfunc:`PyBuffer_FromReadWriteObject`. It - indicates that the new :ctype:`PyBufferObject` should refer to *base* object - from the specified *offset* to the end of its exported buffer. Using this - enables the caller to avoid querying the *base* object for its length. - - -.. cfunction:: int PyBuffer_Check(PyObject *p) - - Return true if the argument has type :cdata:`PyBuffer_Type`. - - -.. cfunction:: PyObject* PyBuffer_FromObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size) - - Return a new read-only buffer object. This raises :exc:`TypeError` if *base* - doesn't support the read-only buffer protocol or doesn't provide exactly one - buffer segment, or it raises :exc:`ValueError` if *offset* is less than zero. - The buffer will hold a reference to the *base* object, and the buffer's contents - will refer to the *base* object's buffer interface, starting as position - *offset* and extending for *size* bytes. If *size* is :const:`Py_END_OF_BUFFER`, - then the new buffer's contents extend to the length of the *base* object's - exported buffer data. - - -.. cfunction:: PyObject* PyBuffer_FromReadWriteObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size) - - Return a new writable buffer object. Parameters and exceptions are similar to - those for :cfunc:`PyBuffer_FromObject`. If the *base* object does not export - the writable buffer protocol, then :exc:`TypeError` is raised. - - -.. cfunction:: PyObject* PyBuffer_FromMemory(void *ptr, Py_ssize_t size) - - Return a new read-only buffer object that reads from a specified location in - memory, with a specified size. The caller is responsible for ensuring that the - memory buffer, passed in as *ptr*, is not deallocated while the returned buffer - object exists. Raises :exc:`ValueError` if *size* is less than zero. Note that - :const:`Py_END_OF_BUFFER` may *not* be passed for the *size* parameter; - :exc:`ValueError` will be raised in that case. - - -.. cfunction:: PyObject* PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size) - - Similar to :cfunc:`PyBuffer_FromMemory`, but the returned buffer is writable. - - -.. cfunction:: PyObject* PyBuffer_New(Py_ssize_t size) - - Return a new writable buffer object that maintains its own memory buffer of - *size* bytes. :exc:`ValueError` is returned if *size* is not zero or positive. - Note that the memory buffer (as returned by :cfunc:`PyObject_AsWriteBuffer`) is - not specifically aligned. - - -.. _tupleobjects: - -Tuple Objects -------------- - -.. index:: object: tuple - - -.. ctype:: PyTupleObject - - This subtype of :ctype:`PyObject` represents a Python tuple object. - - -.. cvar:: PyTypeObject PyTuple_Type - - .. index:: single: TupleType (in module types) - - This instance of :ctype:`PyTypeObject` represents the Python tuple type; it is - the same object as ``tuple`` and ``types.TupleType`` in the Python layer.. - - -.. cfunction:: int PyTuple_Check(PyObject *p) - - Return true if *p* is a tuple object or an instance of a subtype of the tuple - type. - - -.. cfunction:: int PyTuple_CheckExact(PyObject *p) - - Return true if *p* is a tuple object, but not an instance of a subtype of the - tuple type. - - -.. cfunction:: PyObject* PyTuple_New(Py_ssize_t len) - - Return a new tuple object of size *len*, or *NULL* on failure. - - -.. cfunction:: PyObject* PyTuple_Pack(Py_ssize_t n, ...) - - Return a new tuple object of size *n*, or *NULL* on failure. The tuple values - are initialized to the subsequent *n* C arguments pointing to Python objects. - ``PyTuple_Pack(2, a, b)`` is equivalent to ``Py_BuildValue("(OO)", a, b)``. - - -.. cfunction:: Py_ssize_t PyTuple_Size(PyObject *p) - - Take a pointer to a tuple object, and return the size of that tuple. - - -.. cfunction:: Py_ssize_t PyTuple_GET_SIZE(PyObject *p) - - Return the size of the tuple *p*, which must be non-*NULL* and point to a tuple; - no error checking is performed. - - -.. cfunction:: PyObject* PyTuple_GetItem(PyObject *p, Py_ssize_t pos) - - Return the object at position *pos* in the tuple pointed to by *p*. If *pos* is - out of bounds, return *NULL* and sets an :exc:`IndexError` exception. - - -.. cfunction:: PyObject* PyTuple_GET_ITEM(PyObject *p, Py_ssize_t pos) - - Like :cfunc:`PyTuple_GetItem`, but does no checking of its arguments. - - -.. cfunction:: PyObject* PyTuple_GetSlice(PyObject *p, Py_ssize_t low, Py_ssize_t high) - - Take a slice of the tuple pointed to by *p* from *low* to *high* and return it - as a new tuple. - - -.. cfunction:: int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o) - - Insert a reference to object *o* at position *pos* of the tuple pointed to by - *p*. Return ``0`` on success. - - .. note:: - - This function "steals" a reference to *o*. - - -.. cfunction:: void PyTuple_SET_ITEM(PyObject *p, Py_ssize_t pos, PyObject *o) - - Like :cfunc:`PyTuple_SetItem`, but does no error checking, and should *only* be - used to fill in brand new tuples. - - .. note:: - - This function "steals" a reference to *o*. - - -.. cfunction:: int _PyTuple_Resize(PyObject **p, Py_ssize_t newsize) - - Can be used to resize a tuple. *newsize* will be the new length of the tuple. - Because tuples are *supposed* to be immutable, this should only be used if there - is only one reference to the object. Do *not* use this if the tuple may already - be known to some other part of the code. The tuple will always grow or shrink - at the end. Think of this as destroying the old tuple and creating a new one, - only more efficiently. Returns ``0`` on success. Client code should never - assume that the resulting value of ``*p`` will be the same as before calling - this function. If the object referenced by ``*p`` is replaced, the original - ``*p`` is destroyed. On failure, returns ``-1`` and sets ``*p`` to *NULL*, and - raises :exc:`MemoryError` or :exc:`SystemError`. - - -.. _listobjects: - -List Objects ------------- - -.. index:: object: list - - -.. ctype:: PyListObject - - This subtype of :ctype:`PyObject` represents a Python list object. - - -.. cvar:: PyTypeObject PyList_Type - - .. index:: single: ListType (in module types) - - This instance of :ctype:`PyTypeObject` represents the Python list type. This is - the same object as ``list`` and ``types.ListType`` in the Python layer. - - -.. cfunction:: int PyList_Check(PyObject *p) - - Return true if *p* is a list object or an instance of a subtype of the list - type. - - -.. cfunction:: int PyList_CheckExact(PyObject *p) - - Return true if *p* is a list object, but not an instance of a subtype of the - list type. - - -.. cfunction:: PyObject* PyList_New(Py_ssize_t len) - - Return a new list of length *len* on success, or *NULL* on failure. - - .. note:: - - If *length* is greater than zero, the returned list object's items are set to - ``NULL``. Thus you cannot use abstract API functions such as - :cfunc:`PySequence_SetItem` or expose the object to Python code before setting - all items to a real object with :cfunc:`PyList_SetItem`. - - -.. cfunction:: Py_ssize_t PyList_Size(PyObject *list) - - .. index:: builtin: len - - Return the length of the list object in *list*; this is equivalent to - ``len(list)`` on a list object. - - -.. cfunction:: Py_ssize_t PyList_GET_SIZE(PyObject *list) - - Macro form of :cfunc:`PyList_Size` without error checking. - - -.. cfunction:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index) - - Return the object at position *pos* in the list pointed to by *p*. The position - must be positive, indexing from the end of the list is not supported. If *pos* - is out of bounds, return *NULL* and set an :exc:`IndexError` exception. - - -.. cfunction:: PyObject* PyList_GET_ITEM(PyObject *list, Py_ssize_t i) - - Macro form of :cfunc:`PyList_GetItem` without error checking. - - -.. cfunction:: int PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item) - - Set the item at index *index* in list to *item*. Return ``0`` on success or - ``-1`` on failure. - - .. note:: - - This function "steals" a reference to *item* and discards a reference to an item - already in the list at the affected position. - - -.. cfunction:: void PyList_SET_ITEM(PyObject *list, Py_ssize_t i, PyObject *o) - - Macro form of :cfunc:`PyList_SetItem` without error checking. This is normally - only used to fill in new lists where there is no previous content. - - .. note:: - - This function "steals" a reference to *item*, and, unlike - :cfunc:`PyList_SetItem`, does *not* discard a reference to any item that it - being replaced; any reference in *list* at position *i* will be leaked. - - -.. cfunction:: int PyList_Insert(PyObject *list, Py_ssize_t index, PyObject *item) - - Insert the item *item* into list *list* in front of index *index*. Return ``0`` - if successful; return ``-1`` and set an exception if unsuccessful. Analogous to - ``list.insert(index, item)``. - - -.. cfunction:: int PyList_Append(PyObject *list, PyObject *item) - - Append the object *item* at the end of list *list*. Return ``0`` if successful; - return ``-1`` and set an exception if unsuccessful. Analogous to - ``list.append(item)``. - - -.. cfunction:: PyObject* PyList_GetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high) - - Return a list of the objects in *list* containing the objects *between* *low* - and *high*. Return *NULL* and set an exception if unsuccessful. Analogous to - ``list[low:high]``. - - -.. cfunction:: int PyList_SetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high, PyObject *itemlist) - - Set the slice of *list* between *low* and *high* to the contents of *itemlist*. - Analogous to ``list[low:high] = itemlist``. The *itemlist* may be *NULL*, - indicating the assignment of an empty list (slice deletion). Return ``0`` on - success, ``-1`` on failure. - - -.. cfunction:: int PyList_Sort(PyObject *list) - - Sort the items of *list* in place. Return ``0`` on success, ``-1`` on failure. - This is equivalent to ``list.sort()``. - - -.. cfunction:: int PyList_Reverse(PyObject *list) - - Reverse the items of *list* in place. Return ``0`` on success, ``-1`` on - failure. This is the equivalent of ``list.reverse()``. - - -.. cfunction:: PyObject* PyList_AsTuple(PyObject *list) - - .. index:: builtin: tuple - - Return a new tuple object containing the contents of *list*; equivalent to - ``tuple(list)``. - - -.. _mapobjects: - -Mapping Objects -=============== - -.. index:: object: mapping - - -.. _dictobjects: - -Dictionary Objects ------------------- - -.. index:: object: dictionary - - -.. ctype:: PyDictObject - - This subtype of :ctype:`PyObject` represents a Python dictionary object. - - -.. cvar:: PyTypeObject PyDict_Type - - .. index:: - single: DictType (in module types) - single: DictionaryType (in module types) - - This instance of :ctype:`PyTypeObject` represents the Python dictionary type. - This is exposed to Python programs as ``dict`` and ``types.DictType``. - - -.. cfunction:: int PyDict_Check(PyObject *p) - - Return true if *p* is a dict object or an instance of a subtype of the dict - type. - - -.. cfunction:: int PyDict_CheckExact(PyObject *p) - - Return true if *p* is a dict object, but not an instance of a subtype of the - dict type. - - -.. cfunction:: PyObject* PyDict_New() - - Return a new empty dictionary, or *NULL* on failure. - - -.. cfunction:: PyObject* PyDictProxy_New(PyObject *dict) - - Return a proxy object for a mapping which enforces read-only behavior. This is - normally used to create a proxy to prevent modification of the dictionary for - non-dynamic class types. - - -.. cfunction:: void PyDict_Clear(PyObject *p) - - Empty an existing dictionary of all key-value pairs. - - -.. cfunction:: int PyDict_Contains(PyObject *p, PyObject *key) - - Determine if dictionary *p* contains *key*. If an item in *p* is matches *key*, - return ``1``, otherwise return ``0``. On error, return ``-1``. This is - equivalent to the Python expression ``key in p``. - - -.. cfunction:: PyObject* PyDict_Copy(PyObject *p) - - Return a new dictionary that contains the same key-value pairs as *p*. - - -.. cfunction:: int PyDict_SetItem(PyObject *p, PyObject *key, PyObject *val) - - Insert *value* into the dictionary *p* with a key of *key*. *key* must be - :term:`hashable`; if it isn't, :exc:`TypeError` will be raised. Return ``0`` - on success or ``-1`` on failure. - - -.. cfunction:: int PyDict_SetItemString(PyObject *p, const char *key, PyObject *val) - - .. index:: single: PyString_FromString() - - Insert *value* into the dictionary *p* using *key* as a key. *key* should be a - :ctype:`char\*`. The key object is created using ``PyString_FromString(key)``. - Return ``0`` on success or ``-1`` on failure. - - -.. cfunction:: int PyDict_DelItem(PyObject *p, PyObject *key) - - Remove the entry in dictionary *p* with key *key*. *key* must be hashable; if it - isn't, :exc:`TypeError` is raised. Return ``0`` on success or ``-1`` on - failure. - - -.. cfunction:: int PyDict_DelItemString(PyObject *p, char *key) - - Remove the entry in dictionary *p* which has a key specified by the string - *key*. Return ``0`` on success or ``-1`` on failure. - - -.. cfunction:: PyObject* PyDict_GetItem(PyObject *p, PyObject *key) - - Return the object from dictionary *p* which has a key *key*. Return *NULL* if - the key *key* is not present, but *without* setting an exception. - - -.. cfunction:: PyObject* PyDict_GetItemString(PyObject *p, const char *key) - - This is the same as :cfunc:`PyDict_GetItem`, but *key* is specified as a - :ctype:`char\*`, rather than a :ctype:`PyObject\*`. - - -.. cfunction:: PyObject* PyDict_Items(PyObject *p) - - Return a :ctype:`PyListObject` containing all the items from the dictionary, as - in the dictionary method :meth:`dict.items`. - - -.. cfunction:: PyObject* PyDict_Keys(PyObject *p) - - Return a :ctype:`PyListObject` containing all the keys from the dictionary, as - in the dictionary method :meth:`dict.keys`. - - -.. cfunction:: PyObject* PyDict_Values(PyObject *p) - - Return a :ctype:`PyListObject` containing all the values from the dictionary - *p*, as in the dictionary method :meth:`dict.values`. - - -.. cfunction:: Py_ssize_t PyDict_Size(PyObject *p) - - .. index:: builtin: len - - Return the number of items in the dictionary. This is equivalent to ``len(p)`` - on a dictionary. - - -.. cfunction:: int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue) - - Iterate over all key-value pairs in the dictionary *p*. The :ctype:`int` - referred to by *ppos* must be initialized to ``0`` prior to the first call to - this function to start the iteration; the function returns true for each pair in - the dictionary, and false once all pairs have been reported. The parameters - *pkey* and *pvalue* should either point to :ctype:`PyObject\*` variables that - will be filled in with each key and value, respectively, or may be *NULL*. Any - references returned through them are borrowed. *ppos* should not be altered - during iteration. Its value represents offsets within the internal dictionary - structure, and since the structure is sparse, the offsets are not consecutive. - - For example:: - - PyObject *key, *value; - Py_ssize_t pos = 0; - - while (PyDict_Next(self->dict, &pos, &key, &value)) { - /* do something interesting with the values... */ - ... - } - - The dictionary *p* should not be mutated during iteration. It is safe (since - Python 2.1) to modify the values of the keys as you iterate over the dictionary, - but only so long as the set of keys does not change. For example:: - - PyObject *key, *value; - Py_ssize_t pos = 0; - - while (PyDict_Next(self->dict, &pos, &key, &value)) { - long i = PyLong_AsLong(value); - if (i == -1 && PyErr_Occurred()) { - return -1; - } - PyObject *o = PyLong_FromLong(i + 1); - if (o == NULL) - return -1; - if (PyDict_SetItem(self->dict, key, o) < 0) { - Py_DECREF(o); - return -1; - } - Py_DECREF(o); - } - - -.. cfunction:: int PyDict_Merge(PyObject *a, PyObject *b, int override) - - Iterate over mapping object *b* adding key-value pairs to dictionary *a*. *b* - may be a dictionary, or any object supporting :func:`PyMapping_Keys` and - :func:`PyObject_GetItem`. If *override* is true, existing pairs in *a* will be - replaced if a matching key is found in *b*, otherwise pairs will only be added - if there is not a matching key in *a*. Return ``0`` on success or ``-1`` if an - exception was raised. - - -.. cfunction:: int PyDict_Update(PyObject *a, PyObject *b) - - This is the same as ``PyDict_Merge(a, b, 1)`` in C, or ``a.update(b)`` in - Python. Return ``0`` on success or ``-1`` if an exception was raised. - - -.. cfunction:: int PyDict_MergeFromSeq2(PyObject *a, PyObject *seq2, int override) - - Update or merge into dictionary *a*, from the key-value pairs in *seq2*. *seq2* - must be an iterable object producing iterable objects of length 2, viewed as - key-value pairs. In case of duplicate keys, the last wins if *override* is - true, else the first wins. Return ``0`` on success or ``-1`` if an exception was - raised. Equivalent Python (except for the return value):: - - def PyDict_MergeFromSeq2(a, seq2, override): - for key, value in seq2: - if override or key not in a: - a[key] = value - - -.. _otherobjects: - -Other Objects -============= - -.. _fileobjects: - -File Objects ------------- - -.. index:: object: file - -Python's built-in file objects are implemented entirely on the :ctype:`FILE\*` -support from the C standard library. This is an implementation detail and may -change in future releases of Python. - - -.. ctype:: PyFileObject - - This subtype of :ctype:`PyObject` represents a Python file object. - - -.. cvar:: PyTypeObject PyFile_Type - - .. index:: single: FileType (in module types) - - This instance of :ctype:`PyTypeObject` represents the Python file type. This is - exposed to Python programs as ``file`` and ``types.FileType``. - - -.. cfunction:: int PyFile_Check(PyObject *p) - - Return true if its argument is a :ctype:`PyFileObject` or a subtype of - :ctype:`PyFileObject`. - - -.. cfunction:: int PyFile_CheckExact(PyObject *p) - - Return true if its argument is a :ctype:`PyFileObject`, but not a subtype of - :ctype:`PyFileObject`. - - -.. cfunction:: PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding, char *newline, int closefd) - - Create a new :ctype:`PyFileObject` from the file descriptor of an already - opened file *fd*. The arguments *name*, *encoding* and *newline* can be - *NULL* to use the defaults; *buffering* can be *-1* to use the default. - Return *NULL* on failure. - - .. warning:: - - Take care when you are mixing streams and descriptors! For more - information, see `the GNU C Library docs - `_. - - -.. cfunction:: int PyObject_AsFileDescriptor(PyObject *p) - - Return the file descriptor associated with *p* as an :ctype:`int`. If the - object is an integer, its value is returned. If not, the - object's :meth:`fileno` method is called if it exists; the method must return - an integer, which is returned as the file descriptor value. Sets an - exception and returns ``-1`` on failure. - - -.. cfunction:: PyObject* PyFile_GetLine(PyObject *p, int n) - - .. index:: single: EOFError (built-in exception) - - Equivalent to ``p.readline([n])``, this function reads one line from the - object *p*. *p* may be a file object or any object with a :meth:`readline` - method. If *n* is ``0``, exactly one line is read, regardless of the length of - the line. If *n* is greater than ``0``, no more than *n* bytes will be read - from the file; a partial line can be returned. In both cases, an empty string - is returned if the end of the file is reached immediately. If *n* is less than - ``0``, however, one line is read regardless of length, but :exc:`EOFError` is - raised if the end of the file is reached immediately. - - -.. cfunction:: PyObject* PyFile_Name(PyObject *p) - - Return the name of the file specified by *p* as a string object. - - -.. cfunction:: void PyFile_SetBufSize(PyFileObject *p, int n) - - .. index:: single: setvbuf() - - Available on systems with :cfunc:`setvbuf` only. This should only be called - immediately after file object creation. - - -.. cfunction:: int PyFile_SetEncoding(PyFileObject *p, const char *enc) - - Set the file's encoding for Unicode output to *enc*. Return 1 on success and 0 - on failure. - - -.. cfunction:: int PyFile_SoftSpace(PyObject *p, int newflag) - - .. index:: single: softspace (file attribute) - - This function exists for internal use by the interpreter. Set the - :attr:`softspace` attribute of *p* to *newflag* and return the previous value. - *p* does not have to be a file object for this function to work properly; any - object is supported (thought its only interesting if the :attr:`softspace` - attribute can be set). This function clears any errors, and will return ``0`` - as the previous value if the attribute either does not exist or if there were - errors in retrieving it. There is no way to detect errors from this function, - but doing so should not be needed. - - -.. cfunction:: int PyFile_WriteObject(PyObject *obj, PyObject *p, int flags) - - .. index:: single: Py_PRINT_RAW - - Write object *obj* to file object *p*. The only supported flag for *flags* is - :const:`Py_PRINT_RAW`; if given, the :func:`str` of the object is written - instead of the :func:`repr`. Return ``0`` on success or ``-1`` on failure; the - appropriate exception will be set. - - -.. cfunction:: int PyFile_WriteString(const char *s, PyObject *p) - - Write string *s* to file object *p*. Return ``0`` on success or ``-1`` on - failure; the appropriate exception will be set. - - -.. _function-objects: - -Function Objects ----------------- - -.. index:: object: function - -There are a few functions specific to Python functions. - - -.. ctype:: PyFunctionObject - - The C structure used for functions. - - -.. cvar:: PyTypeObject PyFunction_Type - - .. index:: single: MethodType (in module types) - - This is an instance of :ctype:`PyTypeObject` and represents the Python function - type. It is exposed to Python programmers as ``types.FunctionType``. - - -.. cfunction:: int PyFunction_Check(PyObject *o) - - Return true if *o* is a function object (has type :cdata:`PyFunction_Type`). - The parameter must not be *NULL*. - - -.. cfunction:: PyObject* PyFunction_New(PyObject *code, PyObject *globals) - - Return a new function object associated with the code object *code*. *globals* - must be a dictionary with the global variables accessible to the function. - - The function's docstring, name and *__module__* are retrieved from the code - object, the argument defaults and closure are set to *NULL*. - - -.. cfunction:: PyObject* PyFunction_GetCode(PyObject *op) - - Return the code object associated with the function object *op*. - - -.. cfunction:: PyObject* PyFunction_GetGlobals(PyObject *op) - - Return the globals dictionary associated with the function object *op*. - - -.. cfunction:: PyObject* PyFunction_GetModule(PyObject *op) - - Return the *__module__* attribute of the function object *op*. This is normally - a string containing the module name, but can be set to any other object by - Python code. - - -.. cfunction:: PyObject* PyFunction_GetDefaults(PyObject *op) - - Return the argument default values of the function object *op*. This can be a - tuple of arguments or *NULL*. - - -.. cfunction:: int PyFunction_SetDefaults(PyObject *op, PyObject *defaults) - - Set the argument default values for the function object *op*. *defaults* must be - *Py_None* or a tuple. - - Raises :exc:`SystemError` and returns ``-1`` on failure. - - -.. cfunction:: PyObject* PyFunction_GetClosure(PyObject *op) - - Return the closure associated with the function object *op*. This can be *NULL* - or a tuple of cell objects. - - -.. cfunction:: int PyFunction_SetClosure(PyObject *op, PyObject *closure) - - Set the closure associated with the function object *op*. *closure* must be - *Py_None* or a tuple of cell objects. - - Raises :exc:`SystemError` and returns ``-1`` on failure. - - -.. _instancemethod-objects: - -Instance Method Objects ------------------------ - -.. index:: object: instancemethod - -An instance method is a wrapper for a :cdata:`PyCFunction` and the new way -to bind a :cdata:`PyCFunction` to a class object. It replaces the former call -``PyMethod_New(func, NULL, class)``. - - -.. cvar:: PyTypeObject PyInstanceMethod_Type - - This instance of :ctype:`PyTypeObject` represents the Python instance - method type. It is not exposed to Python programs. - - -.. cfunction:: int PyInstanceMethod_Check(PyObject *o) - - Return true if *o* is an instance method object (has type - :cdata:`PyInstanceMethod_Type`). The parameter must not be *NULL*. - - -.. cfunction:: PyObject* PyInstanceMethod_New(PyObject *func) - - Return a new instance method object, with *func* being any callable object - *func* is is the function that will be called when the instance method is - called. - - -.. cfunction:: PyObject* PyInstanceMethod_Function(PyObject *im) - - Return the function object associated with the instance method *im*. - - -.. cfunction:: PyObject* PyInstanceMethod_GET_FUNCTION(PyObject *im) - - Macro version of :cfunc:`PyInstanceMethod_Function` which avoids error checking. - - -.. _method-objects: - -Method Objects --------------- - -.. index:: object: method - -Methods are bound function objects. Methods are always bound to an instance of -an user-defined class. Unbound methods (methods bound to a class object) are -no longer available. - - -.. cvar:: PyTypeObject PyMethod_Type - - .. index:: single: MethodType (in module types) - - This instance of :ctype:`PyTypeObject` represents the Python method type. This - is exposed to Python programs as ``types.MethodType``. - - -.. cfunction:: int PyMethod_Check(PyObject *o) - - Return true if *o* is a method object (has type :cdata:`PyMethod_Type`). The - parameter must not be *NULL*. - - -.. cfunction:: PyObject* PyMethod_New(PyObject *func, PyObject *self) - - Return a new method object, with *func* being any callable object and *self* - the instance the method should be bound. *func* is is the function that will - be called when the method is called. *self* must not be *NULL*. - - -.. cfunction:: PyObject* PyMethod_Function(PyObject *meth) - - Return the function object associated with the method *meth*. - - -.. cfunction:: PyObject* PyMethod_GET_FUNCTION(PyObject *meth) - - Macro version of :cfunc:`PyMethod_Function` which avoids error checking. - - -.. cfunction:: PyObject* PyMethod_Self(PyObject *meth) - - Return the instance associated with the method *meth*. - - -.. cfunction:: PyObject* PyMethod_GET_SELF(PyObject *meth) - - Macro version of :cfunc:`PyMethod_Self` which avoids error checking. - - -.. _moduleobjects: - -Module Objects --------------- - -.. index:: object: module - -There are only a few functions special to module objects. - - -.. cvar:: PyTypeObject PyModule_Type - - .. index:: single: ModuleType (in module types) - - This instance of :ctype:`PyTypeObject` represents the Python module type. This - is exposed to Python programs as ``types.ModuleType``. - - -.. cfunction:: int PyModule_Check(PyObject *p) - - Return true if *p* is a module object, or a subtype of a module object. - - -.. cfunction:: int PyModule_CheckExact(PyObject *p) - - Return true if *p* is a module object, but not a subtype of - :cdata:`PyModule_Type`. - - -.. cfunction:: PyObject* PyModule_New(const char *name) - - .. index:: - single: __name__ (module attribute) - single: __doc__ (module attribute) - single: __file__ (module attribute) - - Return a new module object with the :attr:`__name__` attribute set to *name*. - Only the module's :attr:`__doc__` and :attr:`__name__` attributes are filled in; - the caller is responsible for providing a :attr:`__file__` attribute. - - -.. cfunction:: PyObject* PyModule_GetDict(PyObject *module) - - .. index:: single: __dict__ (module attribute) - - Return the dictionary object that implements *module*'s namespace; this object - is the same as the :attr:`__dict__` attribute of the module object. This - function never fails. It is recommended extensions use other - :cfunc:`PyModule_\*` and :cfunc:`PyObject_\*` functions rather than directly - manipulate a module's :attr:`__dict__`. - - -.. cfunction:: char* PyModule_GetName(PyObject *module) - - .. index:: - single: __name__ (module attribute) - single: SystemError (built-in exception) - - Return *module*'s :attr:`__name__` value. If the module does not provide one, - or if it is not a string, :exc:`SystemError` is raised and *NULL* is returned. - - -.. cfunction:: char* PyModule_GetFilename(PyObject *module) - - .. index:: - single: __file__ (module attribute) - single: SystemError (built-in exception) - - Return the name of the file from which *module* was loaded using *module*'s - :attr:`__file__` attribute. If this is not defined, or if it is not a string, - raise :exc:`SystemError` and return *NULL*. - - -.. cfunction:: int PyModule_AddObject(PyObject *module, const char *name, PyObject *value) - - Add an object to *module* as *name*. This is a convenience function which can - be used from the module's initialization function. This steals a reference to - *value*. Return ``-1`` on error, ``0`` on success. - - -.. cfunction:: int PyModule_AddIntConstant(PyObject *module, const char *name, long value) - - Add an integer constant to *module* as *name*. This convenience function can be - used from the module's initialization function. Return ``-1`` on error, ``0`` on - success. - - -.. cfunction:: int PyModule_AddStringConstant(PyObject *module, const char *name, const char *value) - - Add a string constant to *module* as *name*. This convenience function can be - used from the module's initialization function. The string *value* must be - null-terminated. Return ``-1`` on error, ``0`` on success. - - -.. _iterator-objects: - -Iterator Objects ----------------- - -Python provides two general-purpose iterator objects. The first, a sequence -iterator, works with an arbitrary sequence supporting the :meth:`__getitem__` -method. The second works with a callable object and a sentinel value, calling -the callable for each item in the sequence, and ending the iteration when the -sentinel value is returned. - - -.. cvar:: PyTypeObject PySeqIter_Type - - Type object for iterator objects returned by :cfunc:`PySeqIter_New` and the - one-argument form of the :func:`iter` built-in function for built-in sequence - types. - - -.. cfunction:: int PySeqIter_Check(op) - - Return true if the type of *op* is :cdata:`PySeqIter_Type`. - - -.. cfunction:: PyObject* PySeqIter_New(PyObject *seq) - - Return an iterator that works with a general sequence object, *seq*. The - iteration ends when the sequence raises :exc:`IndexError` for the subscripting - operation. - - -.. cvar:: PyTypeObject PyCallIter_Type - - Type object for iterator objects returned by :cfunc:`PyCallIter_New` and the - two-argument form of the :func:`iter` built-in function. - - -.. cfunction:: int PyCallIter_Check(op) - - Return true if the type of *op* is :cdata:`PyCallIter_Type`. - - -.. cfunction:: PyObject* PyCallIter_New(PyObject *callable, PyObject *sentinel) - - Return a new iterator. The first parameter, *callable*, can be any Python - callable object that can be called with no parameters; each call to it should - return the next item in the iteration. When *callable* returns a value equal to - *sentinel*, the iteration will be terminated. - - -.. _descriptor-objects: - -Descriptor Objects ------------------- - -"Descriptors" are objects that describe some attribute of an object. They are -found in the dictionary of type objects. - -.. XXX document these! - -.. cvar:: PyTypeObject PyProperty_Type - - The type object for the built-in descriptor types. - - -.. cfunction:: PyObject* PyDescr_NewGetSet(PyTypeObject *type, struct PyGetSetDef *getset) - - -.. cfunction:: PyObject* PyDescr_NewMember(PyTypeObject *type, struct PyMemberDef *meth) - - -.. cfunction:: PyObject* PyDescr_NewMethod(PyTypeObject *type, struct PyMethodDef *meth) - - -.. cfunction:: PyObject* PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *wrapper, void *wrapped) - - -.. cfunction:: PyObject* PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method) - - -.. cfunction:: int PyDescr_IsData(PyObject *descr) - - Return true if the descriptor objects *descr* describes a data attribute, or - false if it describes a method. *descr* must be a descriptor object; there is - no error checking. - - -.. cfunction:: PyObject* PyWrapper_New(PyObject *, PyObject *) - - -.. _slice-objects: - -Slice Objects -------------- - - -.. cvar:: PyTypeObject PySlice_Type - - .. index:: single: SliceType (in module types) - - The type object for slice objects. This is the same as ``slice`` and - ``types.SliceType``. - - -.. cfunction:: int PySlice_Check(PyObject *ob) - - Return true if *ob* is a slice object; *ob* must not be *NULL*. - - -.. cfunction:: PyObject* PySlice_New(PyObject *start, PyObject *stop, PyObject *step) - - Return a new slice object with the given values. The *start*, *stop*, and - *step* parameters are used as the values of the slice object attributes of the - same names. Any of the values may be *NULL*, in which case the ``None`` will be - used for the corresponding attribute. Return *NULL* if the new object could not - be allocated. - - -.. cfunction:: int PySlice_GetIndices(PySliceObject *slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step) - - Retrieve the start, stop and step indices from the slice object *slice*, - assuming a sequence of length *length*. Treats indices greater than *length* as - errors. - - Returns 0 on success and -1 on error with no exception set (unless one of the - indices was not :const:`None` and failed to be converted to an integer, in which - case -1 is returned with an exception set). - - You probably do not want to use this function. If you want to use slice objects - in versions of Python prior to 2.3, you would probably do well to incorporate - the source of :cfunc:`PySlice_GetIndicesEx`, suitably renamed, in the source of - your extension. - - -.. cfunction:: int PySlice_GetIndicesEx(PySliceObject *slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength) - - Usable replacement for :cfunc:`PySlice_GetIndices`. Retrieve the start, stop, - and step indices from the slice object *slice* assuming a sequence of length - *length*, and store the length of the slice in *slicelength*. Out of bounds - indices are clipped in a manner consistent with the handling of normal slices. - - Returns 0 on success and -1 on error with exception set. - - -.. _weakrefobjects: - -Weak Reference Objects ----------------------- - -Python supports *weak references* as first-class objects. There are two -specific object types which directly implement weak references. The first is a -simple reference object, and the second acts as a proxy for the original object -as much as it can. - - -.. cfunction:: int PyWeakref_Check(ob) - - Return true if *ob* is either a reference or proxy object. - - -.. cfunction:: int PyWeakref_CheckRef(ob) - - Return true if *ob* is a reference object. - - -.. cfunction:: int PyWeakref_CheckProxy(ob) - - Return true if *ob* is a proxy object. - - -.. cfunction:: PyObject* PyWeakref_NewRef(PyObject *ob, PyObject *callback) - - Return a weak reference object for the object *ob*. This will always return - a new reference, but is not guaranteed to create a new object; an existing - reference object may be returned. The second parameter, *callback*, can be a - callable object that receives notification when *ob* is garbage collected; it - should accept a single parameter, which will be the weak reference object - itself. *callback* may also be ``None`` or *NULL*. If *ob* is not a - weakly-referencable object, or if *callback* is not callable, ``None``, or - *NULL*, this will return *NULL* and raise :exc:`TypeError`. - - -.. cfunction:: PyObject* PyWeakref_NewProxy(PyObject *ob, PyObject *callback) - - Return a weak reference proxy object for the object *ob*. This will always - return a new reference, but is not guaranteed to create a new object; an - existing proxy object may be returned. The second parameter, *callback*, can - be a callable object that receives notification when *ob* is garbage - collected; it should accept a single parameter, which will be the weak - reference object itself. *callback* may also be ``None`` or *NULL*. If *ob* - is not a weakly-referencable object, or if *callback* is not callable, - ``None``, or *NULL*, this will return *NULL* and raise :exc:`TypeError`. - - -.. cfunction:: PyObject* PyWeakref_GetObject(PyObject *ref) - - Return the referenced object from a weak reference, *ref*. If the referent is - no longer live, returns ``None``. - - -.. cfunction:: PyObject* PyWeakref_GET_OBJECT(PyObject *ref) - - Similar to :cfunc:`PyWeakref_GetObject`, but implemented as a macro that does no - error checking. - - -.. _cobjects: - -CObjects --------- - -.. index:: object: CObject - -Refer to *Extending and Embedding the Python Interpreter*, section 1.12, -"Providing a C API for an Extension Module," for more information on using these -objects. - - -.. ctype:: PyCObject - - This subtype of :ctype:`PyObject` represents an opaque value, useful for C - extension modules who need to pass an opaque value (as a :ctype:`void\*` - pointer) through Python code to other C code. It is often used to make a C - function pointer defined in one module available to other modules, so the - regular import mechanism can be used to access C APIs defined in dynamically - loaded modules. - - -.. cfunction:: int PyCObject_Check(PyObject *p) - - Return true if its argument is a :ctype:`PyCObject`. - - -.. cfunction:: PyObject* PyCObject_FromVoidPtr(void* cobj, void (*destr)(void *)) - - Create a :ctype:`PyCObject` from the ``void *`` *cobj*. The *destr* function - will be called when the object is reclaimed, unless it is *NULL*. - - -.. cfunction:: PyObject* PyCObject_FromVoidPtrAndDesc(void* cobj, void* desc, void (*destr)(void *, void *)) - - Create a :ctype:`PyCObject` from the :ctype:`void \*` *cobj*. The *destr* - function will be called when the object is reclaimed. The *desc* argument can - be used to pass extra callback data for the destructor function. - - -.. cfunction:: void* PyCObject_AsVoidPtr(PyObject* self) - - Return the object :ctype:`void \*` that the :ctype:`PyCObject` *self* was - created with. - - -.. cfunction:: void* PyCObject_GetDesc(PyObject* self) - - Return the description :ctype:`void \*` that the :ctype:`PyCObject` *self* was - created with. - - -.. cfunction:: int PyCObject_SetVoidPtr(PyObject* self, void* cobj) - - Set the void pointer inside *self* to *cobj*. The :ctype:`PyCObject` must not - have an associated destructor. Return true on success, false on failure. - - -.. _cell-objects: - -Cell Objects ------------- - -"Cell" objects are used to implement variables referenced by multiple scopes. -For each such variable, a cell object is created to store the value; the local -variables of each stack frame that references the value contains a reference to -the cells from outer scopes which also use that variable. When the value is -accessed, the value contained in the cell is used instead of the cell object -itself. This de-referencing of the cell object requires support from the -generated byte-code; these are not automatically de-referenced when accessed. -Cell objects are not likely to be useful elsewhere. - - -.. ctype:: PyCellObject - - The C structure used for cell objects. - - -.. cvar:: PyTypeObject PyCell_Type - - The type object corresponding to cell objects. - - -.. cfunction:: int PyCell_Check(ob) - - Return true if *ob* is a cell object; *ob* must not be *NULL*. - - -.. cfunction:: PyObject* PyCell_New(PyObject *ob) - - Create and return a new cell object containing the value *ob*. The parameter may - be *NULL*. - - -.. cfunction:: PyObject* PyCell_Get(PyObject *cell) - - Return the contents of the cell *cell*. - - -.. cfunction:: PyObject* PyCell_GET(PyObject *cell) - - Return the contents of the cell *cell*, but without checking that *cell* is - non-*NULL* and a cell object. - - -.. cfunction:: int PyCell_Set(PyObject *cell, PyObject *value) - - Set the contents of the cell object *cell* to *value*. This releases the - reference to any current content of the cell. *value* may be *NULL*. *cell* - must be non-*NULL*; if it is not a cell object, ``-1`` will be returned. On - success, ``0`` will be returned. - - -.. cfunction:: void PyCell_SET(PyObject *cell, PyObject *value) - - Sets the value of the cell object *cell* to *value*. No reference counts are - adjusted, and no checks are made for safety; *cell* must be non-*NULL* and must - be a cell object. - - -.. _gen-objects: - -Generator Objects ------------------ - -Generator objects are what Python uses to implement generator iterators. They -are normally created by iterating over a function that yields values, rather -than explicitly calling :cfunc:`PyGen_New`. - - -.. ctype:: PyGenObject - - The C structure used for generator objects. - - -.. cvar:: PyTypeObject PyGen_Type - - The type object corresponding to generator objects - - -.. cfunction:: int PyGen_Check(ob) - - Return true if *ob* is a generator object; *ob* must not be *NULL*. - - -.. cfunction:: int PyGen_CheckExact(ob) - - Return true if *ob*'s type is *PyGen_Type* is a generator object; *ob* must not - be *NULL*. - - -.. cfunction:: PyObject* PyGen_New(PyFrameObject *frame) - - Create and return a new generator object based on the *frame* object. A - reference to *frame* is stolen by this function. The parameter must not be - *NULL*. - - -.. _datetimeobjects: - -DateTime Objects ----------------- - -Various date and time objects are supplied by the :mod:`datetime` module. -Before using any of these functions, the header file :file:`datetime.h` must be -included in your source (note that this is not included by :file:`Python.h`), -and the macro :cfunc:`PyDateTime_IMPORT` must be invoked. The macro puts a -pointer to a C structure into a static variable, ``PyDateTimeAPI``, that is -used by the following macros. - -Type-check macros: - -.. cfunction:: int PyDate_Check(PyObject *ob) - - Return true if *ob* is of type :cdata:`PyDateTime_DateType` or a subtype of - :cdata:`PyDateTime_DateType`. *ob* must not be *NULL*. - - -.. cfunction:: int PyDate_CheckExact(PyObject *ob) - - Return true if *ob* is of type :cdata:`PyDateTime_DateType`. *ob* must not be - *NULL*. - - -.. cfunction:: int PyDateTime_Check(PyObject *ob) - - Return true if *ob* is of type :cdata:`PyDateTime_DateTimeType` or a subtype of - :cdata:`PyDateTime_DateTimeType`. *ob* must not be *NULL*. - - -.. cfunction:: int PyDateTime_CheckExact(PyObject *ob) - - Return true if *ob* is of type :cdata:`PyDateTime_DateTimeType`. *ob* must not - be *NULL*. - - -.. cfunction:: int PyTime_Check(PyObject *ob) - - Return true if *ob* is of type :cdata:`PyDateTime_TimeType` or a subtype of - :cdata:`PyDateTime_TimeType`. *ob* must not be *NULL*. - - -.. cfunction:: int PyTime_CheckExact(PyObject *ob) - - Return true if *ob* is of type :cdata:`PyDateTime_TimeType`. *ob* must not be - *NULL*. - - -.. cfunction:: int PyDelta_Check(PyObject *ob) - - Return true if *ob* is of type :cdata:`PyDateTime_DeltaType` or a subtype of - :cdata:`PyDateTime_DeltaType`. *ob* must not be *NULL*. - - -.. cfunction:: int PyDelta_CheckExact(PyObject *ob) - - Return true if *ob* is of type :cdata:`PyDateTime_DeltaType`. *ob* must not be - *NULL*. - - -.. cfunction:: int PyTZInfo_Check(PyObject *ob) - - Return true if *ob* is of type :cdata:`PyDateTime_TZInfoType` or a subtype of - :cdata:`PyDateTime_TZInfoType`. *ob* must not be *NULL*. - - -.. cfunction:: int PyTZInfo_CheckExact(PyObject *ob) - - Return true if *ob* is of type :cdata:`PyDateTime_TZInfoType`. *ob* must not be - *NULL*. - - -Macros to create objects: - -.. cfunction:: PyObject* PyDate_FromDate(int year, int month, int day) - - Return a ``datetime.date`` object with the specified year, month and day. - - -.. cfunction:: PyObject* PyDateTime_FromDateAndTime(int year, int month, int day, int hour, int minute, int second, int usecond) - - Return a ``datetime.datetime`` object with the specified year, month, day, hour, - minute, second and microsecond. - - -.. cfunction:: PyObject* PyTime_FromTime(int hour, int minute, int second, int usecond) - - Return a ``datetime.time`` object with the specified hour, minute, second and - microsecond. - - -.. cfunction:: PyObject* PyDelta_FromDSU(int days, int seconds, int useconds) - - Return a ``datetime.timedelta`` object representing the given number of days, - seconds and microseconds. Normalization is performed so that the resulting - number of microseconds and seconds lie in the ranges documented for - ``datetime.timedelta`` objects. - - -Macros to extract fields from date objects. The argument must be an instance of -:cdata:`PyDateTime_Date`, including subclasses (such as -:cdata:`PyDateTime_DateTime`). The argument must not be *NULL*, and the type is -not checked: - -.. cfunction:: int PyDateTime_GET_YEAR(PyDateTime_Date *o) - - Return the year, as a positive int. - - -.. cfunction:: int PyDateTime_GET_MONTH(PyDateTime_Date *o) - - Return the month, as an int from 1 through 12. - - -.. cfunction:: int PyDateTime_GET_DAY(PyDateTime_Date *o) - - Return the day, as an int from 1 through 31. - - -Macros to extract fields from datetime objects. The argument must be an -instance of :cdata:`PyDateTime_DateTime`, including subclasses. The argument -must not be *NULL*, and the type is not checked: - -.. cfunction:: int PyDateTime_DATE_GET_HOUR(PyDateTime_DateTime *o) - - Return the hour, as an int from 0 through 23. - - -.. cfunction:: int PyDateTime_DATE_GET_MINUTE(PyDateTime_DateTime *o) - - Return the minute, as an int from 0 through 59. - - -.. cfunction:: int PyDateTime_DATE_GET_SECOND(PyDateTime_DateTime *o) - - Return the second, as an int from 0 through 59. - - -.. cfunction:: int PyDateTime_DATE_GET_MICROSECOND(PyDateTime_DateTime *o) - - Return the microsecond, as an int from 0 through 999999. - - -Macros to extract fields from time objects. The argument must be an instance of -:cdata:`PyDateTime_Time`, including subclasses. The argument must not be *NULL*, -and the type is not checked: - -.. cfunction:: int PyDateTime_TIME_GET_HOUR(PyDateTime_Time *o) - - Return the hour, as an int from 0 through 23. - - -.. cfunction:: int PyDateTime_TIME_GET_MINUTE(PyDateTime_Time *o) - - Return the minute, as an int from 0 through 59. - - -.. cfunction:: int PyDateTime_TIME_GET_SECOND(PyDateTime_Time *o) - - Return the second, as an int from 0 through 59. - - -.. cfunction:: int PyDateTime_TIME_GET_MICROSECOND(PyDateTime_Time *o) - - Return the microsecond, as an int from 0 through 999999. - - -Macros for the convenience of modules implementing the DB API: - -.. cfunction:: PyObject* PyDateTime_FromTimestamp(PyObject *args) - - Create and return a new ``datetime.datetime`` object given an argument tuple - suitable for passing to ``datetime.datetime.fromtimestamp()``. - - -.. cfunction:: PyObject* PyDate_FromTimestamp(PyObject *args) - - Create and return a new ``datetime.date`` object given an argument tuple - suitable for passing to ``datetime.date.fromtimestamp()``. - - -.. _setobjects: - -Set Objects ------------ - -.. sectionauthor:: Raymond D. Hettinger - - -.. index:: - object: set - object: frozenset - -This section details the public API for :class:`set` and :class:`frozenset` -objects. Any functionality not listed below is best accessed using the either -the abstract object protocol (including :cfunc:`PyObject_CallMethod`, -:cfunc:`PyObject_RichCompareBool`, :cfunc:`PyObject_Hash`, -:cfunc:`PyObject_Repr`, :cfunc:`PyObject_IsTrue`, :cfunc:`PyObject_Print`, and -:cfunc:`PyObject_GetIter`) or the abstract number protocol (including -:cfunc:`PyNumber_And`, :cfunc:`PyNumber_Subtract`, :cfunc:`PyNumber_Or`, -:cfunc:`PyNumber_Xor`, :cfunc:`PyNumber_InPlaceAnd`, -:cfunc:`PyNumber_InPlaceSubtract`, :cfunc:`PyNumber_InPlaceOr`, and -:cfunc:`PyNumber_InPlaceXor`). - - -.. ctype:: PySetObject - - This subtype of :ctype:`PyObject` is used to hold the internal data for both - :class:`set` and :class:`frozenset` objects. It is like a :ctype:`PyDictObject` - in that it is a fixed size for small sets (much like tuple storage) and will - point to a separate, variable sized block of memory for medium and large sized - sets (much like list storage). None of the fields of this structure should be - considered public and are subject to change. All access should be done through - the documented API rather than by manipulating the values in the structure. - - -.. cvar:: PyTypeObject PySet_Type - - This is an instance of :ctype:`PyTypeObject` representing the Python - :class:`set` type. - - -.. cvar:: PyTypeObject PyFrozenSet_Type - - This is an instance of :ctype:`PyTypeObject` representing the Python - :class:`frozenset` type. - -The following type check macros work on pointers to any Python object. Likewise, -the constructor functions work with any iterable Python object. - - -.. cfunction:: int PyAnySet_Check(PyObject *p) - - Return true if *p* is a :class:`set` object, a :class:`frozenset` object, or an - instance of a subtype. - - -.. cfunction:: int PyAnySet_CheckExact(PyObject *p) - - Return true if *p* is a :class:`set` object or a :class:`frozenset` object but - not an instance of a subtype. - - -.. cfunction:: int PyFrozenSet_CheckExact(PyObject *p) - - Return true if *p* is a :class:`frozenset` object but not an instance of a - subtype. - - -.. cfunction:: PyObject* PySet_New(PyObject *iterable) - - Return a new :class:`set` containing objects returned by the *iterable*. The - *iterable* may be *NULL* to create a new empty set. Return the new set on - success or *NULL* on failure. Raise :exc:`TypeError` if *iterable* is not - actually iterable. The constructor is also useful for copying a set - (``c=set(s)``). - - -.. cfunction:: PyObject* PyFrozenSet_New(PyObject *iterable) - - Return a new :class:`frozenset` containing objects returned by the *iterable*. - The *iterable* may be *NULL* to create a new empty frozenset. Return the new - set on success or *NULL* on failure. Raise :exc:`TypeError` if *iterable* is - not actually iterable. - -The following functions and macros are available for instances of :class:`set` -or :class:`frozenset` or instances of their subtypes. - - -.. cfunction:: Py_ssize_t PySet_Size(PyObject *anyset) - - .. index:: builtin: len - - Return the length of a :class:`set` or :class:`frozenset` object. Equivalent to - ``len(anyset)``. Raises a :exc:`PyExc_SystemError` if *anyset* is not a - :class:`set`, :class:`frozenset`, or an instance of a subtype. - - -.. cfunction:: Py_ssize_t PySet_GET_SIZE(PyObject *anyset) - - Macro form of :cfunc:`PySet_Size` without error checking. - - -.. cfunction:: int PySet_Contains(PyObject *anyset, PyObject *key) - - Return 1 if found, 0 if not found, and -1 if an error is encountered. Unlike - the Python :meth:`__contains__` method, this function does not automatically - convert unhashable sets into temporary frozensets. Raise a :exc:`TypeError` if - the *key* is unhashable. Raise :exc:`PyExc_SystemError` if *anyset* is not a - :class:`set`, :class:`frozenset`, or an instance of a subtype. - -The following functions are available for instances of :class:`set` or its -subtypes but not for instances of :class:`frozenset` or its subtypes. - - -.. cfunction:: int PySet_Add(PyObject *set, PyObject *key) - - Add *key* to a :class:`set` instance. Does not apply to :class:`frozenset` - instances. Return 0 on success or -1 on failure. Raise a :exc:`TypeError` if - the *key* is unhashable. Raise a :exc:`MemoryError` if there is no room to grow. - Raise a :exc:`SystemError` if *set* is an not an instance of :class:`set` or its - subtype. - - -.. cfunction:: int PySet_Discard(PyObject *set, PyObject *key) - - Return 1 if found and removed, 0 if not found (no action taken), and -1 if an - error is encountered. Does not raise :exc:`KeyError` for missing keys. Raise a - :exc:`TypeError` if the *key* is unhashable. Unlike the Python :meth:`discard` - method, this function does not automatically convert unhashable sets into - temporary frozensets. Raise :exc:`PyExc_SystemError` if *set* is an not an - instance of :class:`set` or its subtype. - - -.. cfunction:: PyObject* PySet_Pop(PyObject *set) - - Return a new reference to an arbitrary object in the *set*, and removes the - object from the *set*. Return *NULL* on failure. Raise :exc:`KeyError` if the - set is empty. Raise a :exc:`SystemError` if *set* is an not an instance of - :class:`set` or its subtype. - - -.. cfunction:: int PySet_Clear(PyObject *set) - - Empty an existing set of all elements. +.. toctree:: + set.rst + function.rst + method.rst + file.rst + module.rst + iterator.rst + descriptor.rst + slice.rst + weakref.rst + cobject.rst + cell.rst + gen.rst + datetime.rst Added: python/branches/py3k/Doc/c-api/conversion.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/conversion.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,93 @@ +.. highlightlang:: c + +.. _string-conversion: + +String conversion and formatting +================================ + +Functions for number conversion and formatted string output. + + +.. cfunction:: int PyOS_snprintf(char *str, size_t size, const char *format, ...) + + Output not more than *size* bytes to *str* according to the format string + *format* and the extra arguments. See the Unix man page :manpage:`snprintf(2)`. + + +.. cfunction:: int PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va) + + Output not more than *size* bytes to *str* according to the format string + *format* and the variable argument list *va*. Unix man page + :manpage:`vsnprintf(2)`. + +:cfunc:`PyOS_snprintf` and :cfunc:`PyOS_vsnprintf` wrap the Standard C library +functions :cfunc:`snprintf` and :cfunc:`vsnprintf`. Their purpose is to +guarantee consistent behavior in corner cases, which the Standard C functions do +not. + +The wrappers ensure that *str*[*size*-1] is always ``'\0'`` upon return. They +never write more than *size* bytes (including the trailing ``'\0'``) into str. +Both functions require that ``str != NULL``, ``size > 0`` and ``format != +NULL``. + +If the platform doesn't have :cfunc:`vsnprintf` and the buffer size needed to +avoid truncation exceeds *size* by more than 512 bytes, Python aborts with a +*Py_FatalError*. + +The return value (*rv*) for these functions should be interpreted as follows: + +* When ``0 <= rv < size``, the output conversion was successful and *rv* + characters were written to *str* (excluding the trailing ``'\0'`` byte at + *str*[*rv*]). + +* When ``rv >= size``, the output conversion was truncated and a buffer with + ``rv + 1`` bytes would have been needed to succeed. *str*[*size*-1] is ``'\0'`` + in this case. + +* When ``rv < 0``, "something bad happened." *str*[*size*-1] is ``'\0'`` in + this case too, but the rest of *str* is undefined. The exact cause of the error + depends on the underlying platform. + +The following functions provide locale-independent string to number conversions. + + +.. cfunction:: double PyOS_ascii_strtod(const char *nptr, char **endptr) + + Convert a string to a :ctype:`double`. This function behaves like the Standard C + function :cfunc:`strtod` does in the C locale. It does this without changing the + current locale, since that would not be thread-safe. + + :cfunc:`PyOS_ascii_strtod` should typically be used for reading configuration + files or other non-user input that should be locale independent. + + See the Unix man page :manpage:`strtod(2)` for details. + + +.. cfunction:: char * PyOS_ascii_formatd(char *buffer, size_t buf_len, const char *format, double d) + + Convert a :ctype:`double` to a string using the ``'.'`` as the decimal + separator. *format* is a :cfunc:`printf`\ -style format string specifying the + number format. Allowed conversion characters are ``'e'``, ``'E'``, ``'f'``, + ``'F'``, ``'g'`` and ``'G'``. + + The return value is a pointer to *buffer* with the converted string or NULL if + the conversion failed. + + +.. cfunction:: double PyOS_ascii_atof(const char *nptr) + + Convert a string to a :ctype:`double` in a locale-independent way. + + See the Unix man page :manpage:`atof(2)` for details. + + +.. cfunction:: char * PyOS_stricmp(char *s1, char *s2) + + Case insensitive comparsion of strings. The functions works almost + identical to :cfunc:`strcmp` except that it ignores the case. + + +.. cfunction:: char * PyOS_strnicmp(char *s1, char *s2, Py_ssize_t size) + + Case insensitive comparsion of strings. The functions works almost + identical to :cfunc:`strncmp` except that it ignores the case. Added: python/branches/py3k/Doc/c-api/datetime.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/datetime.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,183 @@ +.. highlightlang:: c + +.. _datetimeobjects: + +DateTime Objects +---------------- + +Various date and time objects are supplied by the :mod:`datetime` module. +Before using any of these functions, the header file :file:`datetime.h` must be +included in your source (note that this is not included by :file:`Python.h`), +and the macro :cfunc:`PyDateTime_IMPORT` must be invoked. The macro puts a +pointer to a C structure into a static variable, ``PyDateTimeAPI``, that is +used by the following macros. + +Type-check macros: + +.. cfunction:: int PyDate_Check(PyObject *ob) + + Return true if *ob* is of type :cdata:`PyDateTime_DateType` or a subtype of + :cdata:`PyDateTime_DateType`. *ob* must not be *NULL*. + + +.. cfunction:: int PyDate_CheckExact(PyObject *ob) + + Return true if *ob* is of type :cdata:`PyDateTime_DateType`. *ob* must not be + *NULL*. + + +.. cfunction:: int PyDateTime_Check(PyObject *ob) + + Return true if *ob* is of type :cdata:`PyDateTime_DateTimeType` or a subtype of + :cdata:`PyDateTime_DateTimeType`. *ob* must not be *NULL*. + + +.. cfunction:: int PyDateTime_CheckExact(PyObject *ob) + + Return true if *ob* is of type :cdata:`PyDateTime_DateTimeType`. *ob* must not + be *NULL*. + + +.. cfunction:: int PyTime_Check(PyObject *ob) + + Return true if *ob* is of type :cdata:`PyDateTime_TimeType` or a subtype of + :cdata:`PyDateTime_TimeType`. *ob* must not be *NULL*. + + +.. cfunction:: int PyTime_CheckExact(PyObject *ob) + + Return true if *ob* is of type :cdata:`PyDateTime_TimeType`. *ob* must not be + *NULL*. + + +.. cfunction:: int PyDelta_Check(PyObject *ob) + + Return true if *ob* is of type :cdata:`PyDateTime_DeltaType` or a subtype of + :cdata:`PyDateTime_DeltaType`. *ob* must not be *NULL*. + + +.. cfunction:: int PyDelta_CheckExact(PyObject *ob) + + Return true if *ob* is of type :cdata:`PyDateTime_DeltaType`. *ob* must not be + *NULL*. + + +.. cfunction:: int PyTZInfo_Check(PyObject *ob) + + Return true if *ob* is of type :cdata:`PyDateTime_TZInfoType` or a subtype of + :cdata:`PyDateTime_TZInfoType`. *ob* must not be *NULL*. + + +.. cfunction:: int PyTZInfo_CheckExact(PyObject *ob) + + Return true if *ob* is of type :cdata:`PyDateTime_TZInfoType`. *ob* must not be + *NULL*. + + +Macros to create objects: + +.. cfunction:: PyObject* PyDate_FromDate(int year, int month, int day) + + Return a ``datetime.date`` object with the specified year, month and day. + + +.. cfunction:: PyObject* PyDateTime_FromDateAndTime(int year, int month, int day, int hour, int minute, int second, int usecond) + + Return a ``datetime.datetime`` object with the specified year, month, day, hour, + minute, second and microsecond. + + +.. cfunction:: PyObject* PyTime_FromTime(int hour, int minute, int second, int usecond) + + Return a ``datetime.time`` object with the specified hour, minute, second and + microsecond. + + +.. cfunction:: PyObject* PyDelta_FromDSU(int days, int seconds, int useconds) + + Return a ``datetime.timedelta`` object representing the given number of days, + seconds and microseconds. Normalization is performed so that the resulting + number of microseconds and seconds lie in the ranges documented for + ``datetime.timedelta`` objects. + + +Macros to extract fields from date objects. The argument must be an instance of +:cdata:`PyDateTime_Date`, including subclasses (such as +:cdata:`PyDateTime_DateTime`). The argument must not be *NULL*, and the type is +not checked: + +.. cfunction:: int PyDateTime_GET_YEAR(PyDateTime_Date *o) + + Return the year, as a positive int. + + +.. cfunction:: int PyDateTime_GET_MONTH(PyDateTime_Date *o) + + Return the month, as an int from 1 through 12. + + +.. cfunction:: int PyDateTime_GET_DAY(PyDateTime_Date *o) + + Return the day, as an int from 1 through 31. + + +Macros to extract fields from datetime objects. The argument must be an +instance of :cdata:`PyDateTime_DateTime`, including subclasses. The argument +must not be *NULL*, and the type is not checked: + +.. cfunction:: int PyDateTime_DATE_GET_HOUR(PyDateTime_DateTime *o) + + Return the hour, as an int from 0 through 23. + + +.. cfunction:: int PyDateTime_DATE_GET_MINUTE(PyDateTime_DateTime *o) + + Return the minute, as an int from 0 through 59. + + +.. cfunction:: int PyDateTime_DATE_GET_SECOND(PyDateTime_DateTime *o) + + Return the second, as an int from 0 through 59. + + +.. cfunction:: int PyDateTime_DATE_GET_MICROSECOND(PyDateTime_DateTime *o) + + Return the microsecond, as an int from 0 through 999999. + + +Macros to extract fields from time objects. The argument must be an instance of +:cdata:`PyDateTime_Time`, including subclasses. The argument must not be *NULL*, +and the type is not checked: + +.. cfunction:: int PyDateTime_TIME_GET_HOUR(PyDateTime_Time *o) + + Return the hour, as an int from 0 through 23. + + +.. cfunction:: int PyDateTime_TIME_GET_MINUTE(PyDateTime_Time *o) + + Return the minute, as an int from 0 through 59. + + +.. cfunction:: int PyDateTime_TIME_GET_SECOND(PyDateTime_Time *o) + + Return the second, as an int from 0 through 59. + + +.. cfunction:: int PyDateTime_TIME_GET_MICROSECOND(PyDateTime_Time *o) + + Return the microsecond, as an int from 0 through 999999. + + +Macros for the convenience of modules implementing the DB API: + +.. cfunction:: PyObject* PyDateTime_FromTimestamp(PyObject *args) + + Create and return a new ``datetime.datetime`` object given an argument tuple + suitable for passing to ``datetime.datetime.fromtimestamp()``. + + +.. cfunction:: PyObject* PyDate_FromTimestamp(PyObject *args) + + Create and return a new ``datetime.date`` object given an argument tuple + suitable for passing to ``datetime.date.fromtimestamp()``. Added: python/branches/py3k/Doc/c-api/descriptor.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/descriptor.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,40 @@ +.. highlightlang:: c + +.. _descriptor-objects: + +Descriptor Objects +------------------ + +"Descriptors" are objects that describe some attribute of an object. They are +found in the dictionary of type objects. + +.. XXX document these! + +.. cvar:: PyTypeObject PyProperty_Type + + The type object for the built-in descriptor types. + + +.. cfunction:: PyObject* PyDescr_NewGetSet(PyTypeObject *type, struct PyGetSetDef *getset) + + +.. cfunction:: PyObject* PyDescr_NewMember(PyTypeObject *type, struct PyMemberDef *meth) + + +.. cfunction:: PyObject* PyDescr_NewMethod(PyTypeObject *type, struct PyMethodDef *meth) + + +.. cfunction:: PyObject* PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *wrapper, void *wrapped) + + +.. cfunction:: PyObject* PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method) + + +.. cfunction:: int PyDescr_IsData(PyObject *descr) + + Return true if the descriptor objects *descr* describes a data attribute, or + false if it describes a method. *descr* must be a descriptor object; there is + no error checking. + + +.. cfunction:: PyObject* PyWrapper_New(PyObject *, PyObject *) Added: python/branches/py3k/Doc/c-api/dict.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/dict.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,206 @@ +.. highlightlang:: c + +.. _dictobjects: + +Dictionary Objects +------------------ + +.. index:: object: dictionary + + +.. ctype:: PyDictObject + + This subtype of :ctype:`PyObject` represents a Python dictionary object. + + +.. cvar:: PyTypeObject PyDict_Type + + .. index:: + single: DictType (in module types) + single: DictionaryType (in module types) + + This instance of :ctype:`PyTypeObject` represents the Python dictionary type. + This is exposed to Python programs as ``dict`` and ``types.DictType``. + + +.. cfunction:: int PyDict_Check(PyObject *p) + + Return true if *p* is a dict object or an instance of a subtype of the dict + type. + + +.. cfunction:: int PyDict_CheckExact(PyObject *p) + + Return true if *p* is a dict object, but not an instance of a subtype of the + dict type. + + +.. cfunction:: PyObject* PyDict_New() + + Return a new empty dictionary, or *NULL* on failure. + + +.. cfunction:: PyObject* PyDictProxy_New(PyObject *dict) + + Return a proxy object for a mapping which enforces read-only behavior. This is + normally used to create a proxy to prevent modification of the dictionary for + non-dynamic class types. + + +.. cfunction:: void PyDict_Clear(PyObject *p) + + Empty an existing dictionary of all key-value pairs. + + +.. cfunction:: int PyDict_Contains(PyObject *p, PyObject *key) + + Determine if dictionary *p* contains *key*. If an item in *p* is matches *key*, + return ``1``, otherwise return ``0``. On error, return ``-1``. This is + equivalent to the Python expression ``key in p``. + + +.. cfunction:: PyObject* PyDict_Copy(PyObject *p) + + Return a new dictionary that contains the same key-value pairs as *p*. + + +.. cfunction:: int PyDict_SetItem(PyObject *p, PyObject *key, PyObject *val) + + Insert *value* into the dictionary *p* with a key of *key*. *key* must be + :term:`hashable`; if it isn't, :exc:`TypeError` will be raised. Return ``0`` + on success or ``-1`` on failure. + + +.. cfunction:: int PyDict_SetItemString(PyObject *p, const char *key, PyObject *val) + + .. index:: single: PyString_FromString() + + Insert *value* into the dictionary *p* using *key* as a key. *key* should be a + :ctype:`char\*`. The key object is created using ``PyString_FromString(key)``. + Return ``0`` on success or ``-1`` on failure. + + +.. cfunction:: int PyDict_DelItem(PyObject *p, PyObject *key) + + Remove the entry in dictionary *p* with key *key*. *key* must be hashable; if it + isn't, :exc:`TypeError` is raised. Return ``0`` on success or ``-1`` on + failure. + + +.. cfunction:: int PyDict_DelItemString(PyObject *p, char *key) + + Remove the entry in dictionary *p* which has a key specified by the string + *key*. Return ``0`` on success or ``-1`` on failure. + + +.. cfunction:: PyObject* PyDict_GetItem(PyObject *p, PyObject *key) + + Return the object from dictionary *p* which has a key *key*. Return *NULL* if + the key *key* is not present, but *without* setting an exception. + + +.. cfunction:: PyObject* PyDict_GetItemString(PyObject *p, const char *key) + + This is the same as :cfunc:`PyDict_GetItem`, but *key* is specified as a + :ctype:`char\*`, rather than a :ctype:`PyObject\*`. + + +.. cfunction:: PyObject* PyDict_Items(PyObject *p) + + Return a :ctype:`PyListObject` containing all the items from the dictionary, as + in the dictionary method :meth:`dict.items`. + + +.. cfunction:: PyObject* PyDict_Keys(PyObject *p) + + Return a :ctype:`PyListObject` containing all the keys from the dictionary, as + in the dictionary method :meth:`dict.keys`. + + +.. cfunction:: PyObject* PyDict_Values(PyObject *p) + + Return a :ctype:`PyListObject` containing all the values from the dictionary + *p*, as in the dictionary method :meth:`dict.values`. + + +.. cfunction:: Py_ssize_t PyDict_Size(PyObject *p) + + .. index:: builtin: len + + Return the number of items in the dictionary. This is equivalent to ``len(p)`` + on a dictionary. + + +.. cfunction:: int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue) + + Iterate over all key-value pairs in the dictionary *p*. The :ctype:`int` + referred to by *ppos* must be initialized to ``0`` prior to the first call to + this function to start the iteration; the function returns true for each pair in + the dictionary, and false once all pairs have been reported. The parameters + *pkey* and *pvalue* should either point to :ctype:`PyObject\*` variables that + will be filled in with each key and value, respectively, or may be *NULL*. Any + references returned through them are borrowed. *ppos* should not be altered + during iteration. Its value represents offsets within the internal dictionary + structure, and since the structure is sparse, the offsets are not consecutive. + + For example:: + + PyObject *key, *value; + Py_ssize_t pos = 0; + + while (PyDict_Next(self->dict, &pos, &key, &value)) { + /* do something interesting with the values... */ + ... + } + + The dictionary *p* should not be mutated during iteration. It is safe (since + Python 2.1) to modify the values of the keys as you iterate over the dictionary, + but only so long as the set of keys does not change. For example:: + + PyObject *key, *value; + Py_ssize_t pos = 0; + + while (PyDict_Next(self->dict, &pos, &key, &value)) { + long i = PyLong_AsLong(value); + if (i == -1 && PyErr_Occurred()) { + return -1; + } + PyObject *o = PyLong_FromLong(i + 1); + if (o == NULL) + return -1; + if (PyDict_SetItem(self->dict, key, o) < 0) { + Py_DECREF(o); + return -1; + } + Py_DECREF(o); + } + + +.. cfunction:: int PyDict_Merge(PyObject *a, PyObject *b, int override) + + Iterate over mapping object *b* adding key-value pairs to dictionary *a*. *b* + may be a dictionary, or any object supporting :func:`PyMapping_Keys` and + :func:`PyObject_GetItem`. If *override* is true, existing pairs in *a* will be + replaced if a matching key is found in *b*, otherwise pairs will only be added + if there is not a matching key in *a*. Return ``0`` on success or ``-1`` if an + exception was raised. + + +.. cfunction:: int PyDict_Update(PyObject *a, PyObject *b) + + This is the same as ``PyDict_Merge(a, b, 1)`` in C, or ``a.update(b)`` in + Python. Return ``0`` on success or ``-1`` if an exception was raised. + + +.. cfunction:: int PyDict_MergeFromSeq2(PyObject *a, PyObject *seq2, int override) + + Update or merge into dictionary *a*, from the key-value pairs in *seq2*. *seq2* + must be an iterable object producing iterable objects of length 2, viewed as + key-value pairs. In case of duplicate keys, the last wins if *override* is + true, else the first wins. Return ``0`` on success or ``-1`` if an exception was + raised. Equivalent Python (except for the return value):: + + def PyDict_MergeFromSeq2(a, seq2, override): + for key, value in seq2: + if override or key not in a: + a[key] = value Added: python/branches/py3k/Doc/c-api/file.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/file.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,123 @@ +.. highlightlang:: c + +.. _fileobjects: + +File Objects +------------ + +.. index:: object: file + +Python's built-in file objects are implemented entirely on the :ctype:`FILE\*` +support from the C standard library. This is an implementation detail and may +change in future releases of Python. + + +.. ctype:: PyFileObject + + This subtype of :ctype:`PyObject` represents a Python file object. + + +.. cvar:: PyTypeObject PyFile_Type + + .. index:: single: FileType (in module types) + + This instance of :ctype:`PyTypeObject` represents the Python file type. This is + exposed to Python programs as ``file`` and ``types.FileType``. + + +.. cfunction:: int PyFile_Check(PyObject *p) + + Return true if its argument is a :ctype:`PyFileObject` or a subtype of + :ctype:`PyFileObject`. + + +.. cfunction:: int PyFile_CheckExact(PyObject *p) + + Return true if its argument is a :ctype:`PyFileObject`, but not a subtype of + :ctype:`PyFileObject`. + + +.. cfunction:: PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding, char *newline, int closefd) + + Create a new :ctype:`PyFileObject` from the file descriptor of an already + opened file *fd*. The arguments *name*, *encoding* and *newline* can be + *NULL* to use the defaults; *buffering* can be *-1* to use the default. + Return *NULL* on failure. + + .. warning:: + + Take care when you are mixing streams and descriptors! For more + information, see `the GNU C Library docs + `_. + + +.. cfunction:: int PyObject_AsFileDescriptor(PyObject *p) + + Return the file descriptor associated with *p* as an :ctype:`int`. If the + object is an integer, its value is returned. If not, the + object's :meth:`fileno` method is called if it exists; the method must return + an integer, which is returned as the file descriptor value. Sets an + exception and returns ``-1`` on failure. + + +.. cfunction:: PyObject* PyFile_GetLine(PyObject *p, int n) + + .. index:: single: EOFError (built-in exception) + + Equivalent to ``p.readline([n])``, this function reads one line from the + object *p*. *p* may be a file object or any object with a :meth:`readline` + method. If *n* is ``0``, exactly one line is read, regardless of the length of + the line. If *n* is greater than ``0``, no more than *n* bytes will be read + from the file; a partial line can be returned. In both cases, an empty string + is returned if the end of the file is reached immediately. If *n* is less than + ``0``, however, one line is read regardless of length, but :exc:`EOFError` is + raised if the end of the file is reached immediately. + + +.. cfunction:: PyObject* PyFile_Name(PyObject *p) + + Return the name of the file specified by *p* as a string object. + + +.. cfunction:: void PyFile_SetBufSize(PyFileObject *p, int n) + + .. index:: single: setvbuf() + + Available on systems with :cfunc:`setvbuf` only. This should only be called + immediately after file object creation. + + +.. cfunction:: int PyFile_SetEncoding(PyFileObject *p, const char *enc) + + Set the file's encoding for Unicode output to *enc*. Return 1 on success and 0 + on failure. + + +.. cfunction:: int PyFile_SoftSpace(PyObject *p, int newflag) + + .. index:: single: softspace (file attribute) + + This function exists for internal use by the interpreter. Set the + :attr:`softspace` attribute of *p* to *newflag* and return the previous value. + *p* does not have to be a file object for this function to work properly; any + object is supported (thought its only interesting if the :attr:`softspace` + attribute can be set). This function clears any errors, and will return ``0`` + as the previous value if the attribute either does not exist or if there were + errors in retrieving it. There is no way to detect errors from this function, + but doing so should not be needed. + + +.. cfunction:: int PyFile_WriteObject(PyObject *obj, PyObject *p, int flags) + + .. index:: single: Py_PRINT_RAW + + Write object *obj* to file object *p*. The only supported flag for *flags* is + :const:`Py_PRINT_RAW`; if given, the :func:`str` of the object is written + instead of the :func:`repr`. Return ``0`` on success or ``-1`` on failure; the + appropriate exception will be set. + + +.. cfunction:: int PyFile_WriteString(const char *s, PyObject *p) + + Write string *s* to file object *p*. Return ``0`` on success or ``-1`` on + failure; the appropriate exception will be set. Added: python/branches/py3k/Doc/c-api/float.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/float.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,74 @@ +.. highlightlang:: c + +.. _floatobjects: + +Floating Point Objects +---------------------- + +.. index:: object: floating point + + +.. ctype:: PyFloatObject + + This subtype of :ctype:`PyObject` represents a Python floating point object. + + +.. cvar:: PyTypeObject PyFloat_Type + + .. index:: single: FloatType (in modules types) + + This instance of :ctype:`PyTypeObject` represents the Python floating point + type. This is the same object as ``float`` and ``types.FloatType``. + + +.. cfunction:: int PyFloat_Check(PyObject *p) + + Return true if its argument is a :ctype:`PyFloatObject` or a subtype of + :ctype:`PyFloatObject`. + + +.. cfunction:: int PyFloat_CheckExact(PyObject *p) + + Return true if its argument is a :ctype:`PyFloatObject`, but not a subtype of + :ctype:`PyFloatObject`. + + +.. cfunction:: PyObject* PyFloat_FromString(PyObject *str) + + Create a :ctype:`PyFloatObject` object based on the string value in *str*, or + *NULL* on failure. + + +.. cfunction:: PyObject* PyFloat_FromDouble(double v) + + Create a :ctype:`PyFloatObject` object from *v*, or *NULL* on failure. + + +.. cfunction:: double PyFloat_AsDouble(PyObject *pyfloat) + + Return a C :ctype:`double` representation of the contents of *pyfloat*. If + *pyfloat* is not a Python floating point object but has a :meth:`__float__` + method, this method will first be called to convert *pyfloat* into a float. + + +.. cfunction:: double PyFloat_AS_DOUBLE(PyObject *pyfloat) + + Return a C :ctype:`double` representation of the contents of *pyfloat*, but + without error checking. + + +.. cfunction:: PyObject* PyFloat_GetInfo(void) + + Return a structseq instance which contains information about the + precision, minimum and maximum values of a float. It's a thin wrapper + around the header file :file:`float.h`. + + +.. cfunction:: double PyFloat_GetMax(void) + + Return the maximum representable finite float *DBL_MAX* as C :ctype:`double`. + + +.. cfunction:: double PyFloat_GetMin(void) + + Return the minimum normalized positive float *DBL_MIN* as C :ctype:`double`. Added: python/branches/py3k/Doc/c-api/function.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/function.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,83 @@ +.. highlightlang:: c + +.. _function-objects: + +Function Objects +---------------- + +.. index:: object: function + +There are a few functions specific to Python functions. + + +.. ctype:: PyFunctionObject + + The C structure used for functions. + + +.. cvar:: PyTypeObject PyFunction_Type + + .. index:: single: MethodType (in module types) + + This is an instance of :ctype:`PyTypeObject` and represents the Python function + type. It is exposed to Python programmers as ``types.FunctionType``. + + +.. cfunction:: int PyFunction_Check(PyObject *o) + + Return true if *o* is a function object (has type :cdata:`PyFunction_Type`). + The parameter must not be *NULL*. + + +.. cfunction:: PyObject* PyFunction_New(PyObject *code, PyObject *globals) + + Return a new function object associated with the code object *code*. *globals* + must be a dictionary with the global variables accessible to the function. + + The function's docstring, name and *__module__* are retrieved from the code + object, the argument defaults and closure are set to *NULL*. + + +.. cfunction:: PyObject* PyFunction_GetCode(PyObject *op) + + Return the code object associated with the function object *op*. + + +.. cfunction:: PyObject* PyFunction_GetGlobals(PyObject *op) + + Return the globals dictionary associated with the function object *op*. + + +.. cfunction:: PyObject* PyFunction_GetModule(PyObject *op) + + Return the *__module__* attribute of the function object *op*. This is normally + a string containing the module name, but can be set to any other object by + Python code. + + +.. cfunction:: PyObject* PyFunction_GetDefaults(PyObject *op) + + Return the argument default values of the function object *op*. This can be a + tuple of arguments or *NULL*. + + +.. cfunction:: int PyFunction_SetDefaults(PyObject *op, PyObject *defaults) + + Set the argument default values for the function object *op*. *defaults* must be + *Py_None* or a tuple. + + Raises :exc:`SystemError` and returns ``-1`` on failure. + + +.. cfunction:: PyObject* PyFunction_GetClosure(PyObject *op) + + Return the closure associated with the function object *op*. This can be *NULL* + or a tuple of cell objects. + + +.. cfunction:: int PyFunction_SetClosure(PyObject *op, PyObject *closure) + + Set the closure associated with the function object *op*. *closure* must be + *Py_None* or a tuple of cell objects. + + Raises :exc:`SystemError` and returns ``-1`` on failure. Added: python/branches/py3k/Doc/c-api/gcsupport.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/gcsupport.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,147 @@ +.. highlightlang:: c + +.. _supporting-cycle-detection: + +Supporting Cyclic Garbage Collection +==================================== + +Python's support for detecting and collecting garbage which involves circular +references requires support from object types which are "containers" for other +objects which may also be containers. Types which do not store references to +other objects, or which only store references to atomic types (such as numbers +or strings), do not need to provide any explicit support for garbage collection. + +To create a container type, the :attr:`tp_flags` field of the type object must +include the :const:`Py_TPFLAGS_HAVE_GC` and provide an implementation of the +:attr:`tp_traverse` handler. If instances of the type are mutable, a +:attr:`tp_clear` implementation must also be provided. + + +.. data:: Py_TPFLAGS_HAVE_GC + + Objects with a type with this flag set must conform with the rules documented + here. For convenience these objects will be referred to as container objects. + +Constructors for container types must conform to two rules: + +#. The memory for the object must be allocated using :cfunc:`PyObject_GC_New` or + :cfunc:`PyObject_GC_VarNew`. + +#. Once all the fields which may contain references to other containers are + initialized, it must call :cfunc:`PyObject_GC_Track`. + + +.. cfunction:: TYPE* PyObject_GC_New(TYPE, PyTypeObject *type) + + Analogous to :cfunc:`PyObject_New` but for container objects with the + :const:`Py_TPFLAGS_HAVE_GC` flag set. + + +.. cfunction:: TYPE* PyObject_GC_NewVar(TYPE, PyTypeObject *type, Py_ssize_t size) + + Analogous to :cfunc:`PyObject_NewVar` but for container objects with the + :const:`Py_TPFLAGS_HAVE_GC` flag set. + + +.. cfunction:: PyVarObject * PyObject_GC_Resize(PyVarObject *op, Py_ssize_t) + + Resize an object allocated by :cfunc:`PyObject_NewVar`. Returns the resized + object or *NULL* on failure. + + +.. cfunction:: void PyObject_GC_Track(PyObject *op) + + Adds the object *op* to the set of container objects tracked by the collector. + The collector can run at unexpected times so objects must be valid while being + tracked. This should be called once all the fields followed by the + :attr:`tp_traverse` handler become valid, usually near the end of the + constructor. + + +.. cfunction:: void _PyObject_GC_TRACK(PyObject *op) + + A macro version of :cfunc:`PyObject_GC_Track`. It should not be used for + extension modules. + +Similarly, the deallocator for the object must conform to a similar pair of +rules: + +#. Before fields which refer to other containers are invalidated, + :cfunc:`PyObject_GC_UnTrack` must be called. + +#. The object's memory must be deallocated using :cfunc:`PyObject_GC_Del`. + + +.. cfunction:: void PyObject_GC_Del(void *op) + + Releases memory allocated to an object using :cfunc:`PyObject_GC_New` or + :cfunc:`PyObject_GC_NewVar`. + + +.. cfunction:: void PyObject_GC_UnTrack(void *op) + + Remove the object *op* from the set of container objects tracked by the + collector. Note that :cfunc:`PyObject_GC_Track` can be called again on this + object to add it back to the set of tracked objects. The deallocator + (:attr:`tp_dealloc` handler) should call this for the object before any of the + fields used by the :attr:`tp_traverse` handler become invalid. + + +.. cfunction:: void _PyObject_GC_UNTRACK(PyObject *op) + + A macro version of :cfunc:`PyObject_GC_UnTrack`. It should not be used for + extension modules. + +The :attr:`tp_traverse` handler accepts a function parameter of this type: + + +.. ctype:: int (*visitproc)(PyObject *object, void *arg) + + Type of the visitor function passed to the :attr:`tp_traverse` handler. The + function should be called with an object to traverse as *object* and the third + parameter to the :attr:`tp_traverse` handler as *arg*. The Python core uses + several visitor functions to implement cyclic garbage detection; it's not + expected that users will need to write their own visitor functions. + +The :attr:`tp_traverse` handler must have the following type: + + +.. ctype:: int (*traverseproc)(PyObject *self, visitproc visit, void *arg) + + Traversal function for a container object. Implementations must call the + *visit* function for each object directly contained by *self*, with the + parameters to *visit* being the contained object and the *arg* value passed to + the handler. The *visit* function must not be called with a *NULL* object + argument. If *visit* returns a non-zero value that value should be returned + immediately. + +To simplify writing :attr:`tp_traverse` handlers, a :cfunc:`Py_VISIT` macro is +provided. In order to use this macro, the :attr:`tp_traverse` implementation +must name its arguments exactly *visit* and *arg*: + + +.. cfunction:: void Py_VISIT(PyObject *o) + + Call the *visit* callback, with arguments *o* and *arg*. If *visit* returns a + non-zero value, then return it. Using this macro, :attr:`tp_traverse` handlers + look like:: + + static int + my_traverse(Noddy *self, visitproc visit, void *arg) + { + Py_VISIT(self->foo); + Py_VISIT(self->bar); + return 0; + } + +The :attr:`tp_clear` handler must be of the :ctype:`inquiry` type, or *NULL* if +the object is immutable. + + +.. ctype:: int (*inquiry)(PyObject *self) + + Drop references that may have created reference cycles. Immutable objects do + not have to define this method since they can never directly create reference + cycles. Note that the object must still be valid after calling this method + (don't just call :cfunc:`Py_DECREF` on a reference). The collector will call + this method if it detects that this object is involved in a reference cycle. Added: python/branches/py3k/Doc/c-api/gen.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/gen.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,38 @@ +.. highlightlang:: c + +.. _gen-objects: + +Generator Objects +----------------- + +Generator objects are what Python uses to implement generator iterators. They +are normally created by iterating over a function that yields values, rather +than explicitly calling :cfunc:`PyGen_New`. + + +.. ctype:: PyGenObject + + The C structure used for generator objects. + + +.. cvar:: PyTypeObject PyGen_Type + + The type object corresponding to generator objects + + +.. cfunction:: int PyGen_Check(ob) + + Return true if *ob* is a generator object; *ob* must not be *NULL*. + + +.. cfunction:: int PyGen_CheckExact(ob) + + Return true if *ob*'s type is *PyGen_Type* is a generator object; *ob* must not + be *NULL*. + + +.. cfunction:: PyObject* PyGen_New(PyFrameObject *frame) + + Create and return a new generator object based on the *frame* object. A + reference to *frame* is stolen by this function. The parameter must not be + *NULL*. Added: python/branches/py3k/Doc/c-api/import.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/import.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,227 @@ +.. highlightlang:: c + +.. _importing: + +Importing Modules +================= + + +.. cfunction:: PyObject* PyImport_ImportModule(const char *name) + + .. index:: + single: package variable; __all__ + single: __all__ (package variable) + single: modules (in module sys) + + This is a simplified interface to :cfunc:`PyImport_ImportModuleEx` below, + leaving the *globals* and *locals* arguments set to *NULL* and *level* set + to 0. When the *name* + argument contains a dot (when it specifies a submodule of a package), the + *fromlist* argument is set to the list ``['*']`` so that the return value is the + named module rather than the top-level package containing it as would otherwise + be the case. (Unfortunately, this has an additional side effect when *name* in + fact specifies a subpackage instead of a submodule: the submodules specified in + the package's ``__all__`` variable are loaded.) Return a new reference to the + imported module, or *NULL* with an exception set on failure. Before Python 2.4, + the module may still be created in the failure case --- examine ``sys.modules`` + to find out. Starting with Python 2.4, a failing import of a module no longer + leaves the module in ``sys.modules``. + + +.. cfunction:: PyObject* PyImport_ImportModuleNoBlock(const char *name) + + This version of :cfunc:`PyImport_ImportModule` does not block. It's intended + to be used in C functions that import other modules to execute a function. + The import may block if another thread holds the import lock. The function + :cfunc:`PyImport_ImportModuleNoBlock` never blocks. It first tries to fetch + the module from sys.modules and falls back to :cfunc:`PyImport_ImportModule` + unless the lock is held, in which case the function will raise an + :exc:`ImportError`. + + +.. cfunction:: PyObject* PyImport_ImportModuleEx(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist) + + .. index:: builtin: __import__ + + Import a module. This is best described by referring to the built-in Python + function :func:`__import__`, as the standard :func:`__import__` function calls + this function directly. + + The return value is a new reference to the imported module or top-level package, + or *NULL* with an exception set on failure (before Python 2.4, the module may + still be created in this case). Like for :func:`__import__`, the return value + when a submodule of a package was requested is normally the top-level package, + unless a non-empty *fromlist* was given. + + Failing imports remove incomplete module objects, like with + :cfunc:`PyImport_ImportModule`. + + +.. cfunction:: PyObject* PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level) + + Import a module. This is best described by referring to the built-in Python + function :func:`__import__`, as the standard :func:`__import__` function calls + this function directly. + + The return value is a new reference to the imported module or top-level package, + or *NULL* with an exception set on failure. Like for :func:`__import__`, + the return value when a submodule of a package was requested is normally the + top-level package, unless a non-empty *fromlist* was given. + + +.. cfunction:: PyObject* PyImport_Import(PyObject *name) + + This is a higher-level interface that calls the current "import hook + function" (with an explicit *level* of 0, meaning absolute import). It + invokes the :func:`__import__` function from the ``__builtins__`` of the + current globals. This means that the import is done using whatever import + hooks are installed in the current environment. + + +.. cfunction:: PyObject* PyImport_ReloadModule(PyObject *m) + + Reload a module. Return a new reference to the reloaded module, or *NULL* with + an exception set on failure (the module still exists in this case). + + +.. cfunction:: PyObject* PyImport_AddModule(const char *name) + + Return the module object corresponding to a module name. The *name* argument + may be of the form ``package.module``. First check the modules dictionary if + there's one there, and if not, create a new one and insert it in the modules + dictionary. Return *NULL* with an exception set on failure. + + .. note:: + + This function does not load or import the module; if the module wasn't already + loaded, you will get an empty module object. Use :cfunc:`PyImport_ImportModule` + or one of its variants to import a module. Package structures implied by a + dotted name for *name* are not created if not already present. + + +.. cfunction:: PyObject* PyImport_ExecCodeModule(char *name, PyObject *co) + + .. index:: builtin: compile + + Given a module name (possibly of the form ``package.module``) and a code object + read from a Python bytecode file or obtained from the built-in function + :func:`compile`, load the module. Return a new reference to the module object, + or *NULL* with an exception set if an error occurred. Before Python 2.4, the + module could still be created in error cases. Starting with Python 2.4, *name* + is removed from :attr:`sys.modules` in error cases, and even if *name* was already + in :attr:`sys.modules` on entry to :cfunc:`PyImport_ExecCodeModule`. Leaving + incompletely initialized modules in :attr:`sys.modules` is dangerous, as imports of + such modules have no way to know that the module object is an unknown (and + probably damaged with respect to the module author's intents) state. + + This function will reload the module if it was already imported. See + :cfunc:`PyImport_ReloadModule` for the intended way to reload a module. + + If *name* points to a dotted name of the form ``package.module``, any package + structures not already created will still not be created. + + +.. cfunction:: long PyImport_GetMagicNumber() + + Return the magic number for Python bytecode files (a.k.a. :file:`.pyc` and + :file:`.pyo` files). The magic number should be present in the first four bytes + of the bytecode file, in little-endian byte order. + + +.. cfunction:: PyObject* PyImport_GetModuleDict() + + Return the dictionary used for the module administration (a.k.a. + ``sys.modules``). Note that this is a per-interpreter variable. + + +.. cfunction:: void _PyImport_Init() + + Initialize the import mechanism. For internal use only. + + +.. cfunction:: void PyImport_Cleanup() + + Empty the module table. For internal use only. + + +.. cfunction:: void _PyImport_Fini() + + Finalize the import mechanism. For internal use only. + + +.. cfunction:: PyObject* _PyImport_FindExtension(char *, char *) + + For internal use only. + + +.. cfunction:: PyObject* _PyImport_FixupExtension(char *, char *) + + For internal use only. + + +.. cfunction:: int PyImport_ImportFrozenModule(char *name) + + Load a frozen module named *name*. Return ``1`` for success, ``0`` if the + module is not found, and ``-1`` with an exception set if the initialization + failed. To access the imported module on a successful load, use + :cfunc:`PyImport_ImportModule`. (Note the misnomer --- this function would + reload the module if it was already imported.) + + +.. ctype:: struct _frozen + + .. index:: single: freeze utility + + This is the structure type definition for frozen module descriptors, as + generated by the :program:`freeze` utility (see :file:`Tools/freeze/` in the + Python source distribution). Its definition, found in :file:`Include/import.h`, + is:: + + struct _frozen { + char *name; + unsigned char *code; + int size; + }; + + +.. cvar:: struct _frozen* PyImport_FrozenModules + + This pointer is initialized to point to an array of :ctype:`struct _frozen` + records, terminated by one whose members are all *NULL* or zero. When a frozen + module is imported, it is searched in this table. Third-party code could play + tricks with this to provide a dynamically created collection of frozen modules. + + +.. cfunction:: int PyImport_AppendInittab(char *name, void (*initfunc)(void)) + + Add a single module to the existing table of built-in modules. This is a + convenience wrapper around :cfunc:`PyImport_ExtendInittab`, returning ``-1`` if + the table could not be extended. The new module can be imported by the name + *name*, and uses the function *initfunc* as the initialization function called + on the first attempted import. This should be called before + :cfunc:`Py_Initialize`. + + +.. ctype:: struct _inittab + + Structure describing a single entry in the list of built-in modules. Each of + these structures gives the name and initialization function for a module built + into the interpreter. Programs which embed Python may use an array of these + structures in conjunction with :cfunc:`PyImport_ExtendInittab` to provide + additional built-in modules. The structure is defined in + :file:`Include/import.h` as:: + + struct _inittab { + char *name; + void (*initfunc)(void); + }; + + +.. cfunction:: int PyImport_ExtendInittab(struct _inittab *newtab) + + Add a collection of modules to the table of built-in modules. The *newtab* + array must end with a sentinel entry which contains *NULL* for the :attr:`name` + field; failure to provide the sentinel value can result in a memory fault. + Returns ``0`` on success or ``-1`` if insufficient memory could be allocated to + extend the internal table. In the event of failure, no modules are added to the + internal table. This should be called before :cfunc:`Py_Initialize`. Added: python/branches/py3k/Doc/c-api/iter.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/iter.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,47 @@ +.. highlightlang:: c + +.. _iterator: + +Iterator Protocol +================= + +There are only a couple of functions specifically for working with iterators. + +.. cfunction:: int PyIter_Check(PyObject *o) + + Return true if the object *o* supports the iterator protocol. + + +.. cfunction:: PyObject* PyIter_Next(PyObject *o) + + Return the next value from the iteration *o*. If the object is an iterator, + this retrieves the next value from the iteration, and returns *NULL* with no + exception set if there are no remaining items. If the object is not an + iterator, :exc:`TypeError` is raised, or if there is an error in retrieving the + item, returns *NULL* and passes along the exception. + +To write a loop which iterates over an iterator, the C code should look +something like this:: + + PyObject *iterator = PyObject_GetIter(obj); + PyObject *item; + + if (iterator == NULL) { + /* propagate error */ + } + + while (item = PyIter_Next(iterator)) { + /* do something with item */ + ... + /* release reference when done */ + Py_DECREF(item); + } + + Py_DECREF(iterator); + + if (PyErr_Occurred()) { + /* propagate error */ + } + else { + /* continue doing useful work */ + } Added: python/branches/py3k/Doc/c-api/iterator.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/iterator.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,50 @@ +.. highlightlang:: c + +.. _iterator-objects: + +Iterator Objects +---------------- + +Python provides two general-purpose iterator objects. The first, a sequence +iterator, works with an arbitrary sequence supporting the :meth:`__getitem__` +method. The second works with a callable object and a sentinel value, calling +the callable for each item in the sequence, and ending the iteration when the +sentinel value is returned. + + +.. cvar:: PyTypeObject PySeqIter_Type + + Type object for iterator objects returned by :cfunc:`PySeqIter_New` and the + one-argument form of the :func:`iter` built-in function for built-in sequence + types. + + +.. cfunction:: int PySeqIter_Check(op) + + Return true if the type of *op* is :cdata:`PySeqIter_Type`. + + +.. cfunction:: PyObject* PySeqIter_New(PyObject *seq) + + Return an iterator that works with a general sequence object, *seq*. The + iteration ends when the sequence raises :exc:`IndexError` for the subscripting + operation. + + +.. cvar:: PyTypeObject PyCallIter_Type + + Type object for iterator objects returned by :cfunc:`PyCallIter_New` and the + two-argument form of the :func:`iter` built-in function. + + +.. cfunction:: int PyCallIter_Check(op) + + Return true if the type of *op* is :cdata:`PyCallIter_Type`. + + +.. cfunction:: PyObject* PyCallIter_New(PyObject *callable, PyObject *sentinel) + + Return a new iterator. The first parameter, *callable*, can be any Python + callable object that can be called with no parameters; each call to it should + return the next item in the iteration. When *callable* returns a value equal to + *sentinel*, the iteration will be terminated. Added: python/branches/py3k/Doc/c-api/list.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/list.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,142 @@ +.. highlightlang:: c + +.. _listobjects: + +List Objects +------------ + +.. index:: object: list + + +.. ctype:: PyListObject + + This subtype of :ctype:`PyObject` represents a Python list object. + + +.. cvar:: PyTypeObject PyList_Type + + .. index:: single: ListType (in module types) + + This instance of :ctype:`PyTypeObject` represents the Python list type. This is + the same object as ``list`` and ``types.ListType`` in the Python layer. + + +.. cfunction:: int PyList_Check(PyObject *p) + + Return true if *p* is a list object or an instance of a subtype of the list + type. + + +.. cfunction:: int PyList_CheckExact(PyObject *p) + + Return true if *p* is a list object, but not an instance of a subtype of the + list type. + + +.. cfunction:: PyObject* PyList_New(Py_ssize_t len) + + Return a new list of length *len* on success, or *NULL* on failure. + + .. note:: + + If *length* is greater than zero, the returned list object's items are set to + ``NULL``. Thus you cannot use abstract API functions such as + :cfunc:`PySequence_SetItem` or expose the object to Python code before setting + all items to a real object with :cfunc:`PyList_SetItem`. + + +.. cfunction:: Py_ssize_t PyList_Size(PyObject *list) + + .. index:: builtin: len + + Return the length of the list object in *list*; this is equivalent to + ``len(list)`` on a list object. + + +.. cfunction:: Py_ssize_t PyList_GET_SIZE(PyObject *list) + + Macro form of :cfunc:`PyList_Size` without error checking. + + +.. cfunction:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index) + + Return the object at position *pos* in the list pointed to by *p*. The position + must be positive, indexing from the end of the list is not supported. If *pos* + is out of bounds, return *NULL* and set an :exc:`IndexError` exception. + + +.. cfunction:: PyObject* PyList_GET_ITEM(PyObject *list, Py_ssize_t i) + + Macro form of :cfunc:`PyList_GetItem` without error checking. + + +.. cfunction:: int PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item) + + Set the item at index *index* in list to *item*. Return ``0`` on success or + ``-1`` on failure. + + .. note:: + + This function "steals" a reference to *item* and discards a reference to an item + already in the list at the affected position. + + +.. cfunction:: void PyList_SET_ITEM(PyObject *list, Py_ssize_t i, PyObject *o) + + Macro form of :cfunc:`PyList_SetItem` without error checking. This is normally + only used to fill in new lists where there is no previous content. + + .. note:: + + This function "steals" a reference to *item*, and, unlike + :cfunc:`PyList_SetItem`, does *not* discard a reference to any item that it + being replaced; any reference in *list* at position *i* will be leaked. + + +.. cfunction:: int PyList_Insert(PyObject *list, Py_ssize_t index, PyObject *item) + + Insert the item *item* into list *list* in front of index *index*. Return ``0`` + if successful; return ``-1`` and set an exception if unsuccessful. Analogous to + ``list.insert(index, item)``. + + +.. cfunction:: int PyList_Append(PyObject *list, PyObject *item) + + Append the object *item* at the end of list *list*. Return ``0`` if successful; + return ``-1`` and set an exception if unsuccessful. Analogous to + ``list.append(item)``. + + +.. cfunction:: PyObject* PyList_GetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high) + + Return a list of the objects in *list* containing the objects *between* *low* + and *high*. Return *NULL* and set an exception if unsuccessful. Analogous to + ``list[low:high]``. + + +.. cfunction:: int PyList_SetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high, PyObject *itemlist) + + Set the slice of *list* between *low* and *high* to the contents of *itemlist*. + Analogous to ``list[low:high] = itemlist``. The *itemlist* may be *NULL*, + indicating the assignment of an empty list (slice deletion). Return ``0`` on + success, ``-1`` on failure. + + +.. cfunction:: int PyList_Sort(PyObject *list) + + Sort the items of *list* in place. Return ``0`` on success, ``-1`` on failure. + This is equivalent to ``list.sort()``. + + +.. cfunction:: int PyList_Reverse(PyObject *list) + + Reverse the items of *list* in place. Return ``0`` on success, ``-1`` on + failure. This is the equivalent of ``list.reverse()``. + + +.. cfunction:: PyObject* PyList_AsTuple(PyObject *list) + + .. index:: builtin: tuple + + Return a new tuple object containing the contents of *list*; equivalent to + ``tuple(list)``. Added: python/branches/py3k/Doc/c-api/long.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/long.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,196 @@ +.. highlightlang:: c + +.. _longobjects: + +Integer Objects +--------------- + +.. index:: object: long integer + object: integer + +All integers are implemented as "long" integer objects of arbitrary size. + +.. ctype:: PyLongObject + + This subtype of :ctype:`PyObject` represents a Python integer object. + + +.. cvar:: PyTypeObject PyLong_Type + + This instance of :ctype:`PyTypeObject` represents the Python integer type. + This is the same object as ``int``. + + +.. cfunction:: int PyLong_Check(PyObject *p) + + Return true if its argument is a :ctype:`PyLongObject` or a subtype of + :ctype:`PyLongObject`. + + +.. cfunction:: int PyLong_CheckExact(PyObject *p) + + Return true if its argument is a :ctype:`PyLongObject`, but not a subtype of + :ctype:`PyLongObject`. + + +.. cfunction:: PyObject* PyLong_FromLong(long v) + + Return a new :ctype:`PyLongObject` object from *v*, or *NULL* on failure. + + The current implementation keeps an array of integer objects for all integers + between ``-5`` and ``256``, when you create an int in that range you actually + just get back a reference to the existing object. So it should be possible to + change the value of ``1``. I suspect the behaviour of Python in this case is + undefined. :-) + + +.. cfunction:: PyObject* PyLong_FromUnsignedLong(unsigned long v) + + Return a new :ctype:`PyLongObject` object from a C :ctype:`unsigned long`, or + *NULL* on failure. + + +.. cfunction:: PyObject* PyLong_FromSsize_t(Py_ssize_t v) + + Return a new :ctype:`PyLongObject` object with a value of *v*, or *NULL* + on failure. + + +.. cfunction:: PyObject* PyLong_FromSize_t(size_t v) + + Return a new :ctype:`PyLongObject` object with a value of *v*, or *NULL* + on failure. + + +.. cfunction:: PyObject* PyLong_FromLongLong(PY_LONG_LONG v) + + Return a new :ctype:`PyLongObject` object from a C :ctype:`long long`, or *NULL* + on failure. + + +.. cfunction:: PyObject* PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG v) + + Return a new :ctype:`PyLongObject` object from a C :ctype:`unsigned long long`, + or *NULL* on failure. + + +.. cfunction:: PyObject* PyLong_FromDouble(double v) + + Return a new :ctype:`PyLongObject` object from the integer part of *v*, or + *NULL* on failure. + + +.. cfunction:: PyObject* PyLong_FromString(char *str, char **pend, int base) + + Return a new :ctype:`PyLongObject` based on the string value in *str*, which + is interpreted according to the radix in *base*. If *pend* is non-*NULL*, + ``*pend`` will point to the first character in *str* which follows the + representation of the number. If *base* is ``0``, the radix will be + determined based on the leading characters of *str*: if *str* starts with + ``'0x'`` or ``'0X'``, radix 16 will be used; if *str* starts with ``'0o'`` or + ``'0O'``, radix 8 will be used; if *str* starts with ``'0b'`` or ``'0B'``, + radix 2 will be used; otherwise radix 10 will be used. If *base* is not + ``0``, it must be between ``2`` and ``36``, inclusive. Leading spaces are + ignored. If there are no digits, :exc:`ValueError` will be raised. + + +.. cfunction:: PyObject* PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base) + + Convert a sequence of Unicode digits to a Python integer value. The Unicode + string is first encoded to a byte string using :cfunc:`PyUnicode_EncodeDecimal` + and then converted using :cfunc:`PyLong_FromString`. + + +.. cfunction:: PyObject* PyLong_FromVoidPtr(void *p) + + Create a Python integer from the pointer *p*. The pointer value can be + retrieved from the resulting value using :cfunc:`PyLong_AsVoidPtr`. + + +.. XXX alias PyLong_AS_LONG (for now) +.. cfunction:: long PyLong_AsLong(PyObject *pylong) + + .. index:: + single: LONG_MAX + single: OverflowError (built-in exception) + + Return a C :ctype:`long` representation of the contents of *pylong*. If + *pylong* is greater than :const:`LONG_MAX`, raise an :exc:`OverflowError`, + and return -1. Convert non-long objects automatically to long first, + and return -1 if that raises exceptions. + +.. cfunction:: long PyLong_AsLongAndOverflow(PyObject *pylong, int* overflow) + + Return a C :ctype:`long` representation of the contents of *pylong*. If + *pylong* is greater than :const:`LONG_MAX`, return -1 and + set `*overflow` to 1 (for overflow) or -1 (for underflow). + If an exception is set because of type errors, also return -1. + + +.. cfunction:: unsigned long PyLong_AsUnsignedLong(PyObject *pylong) + + .. index:: + single: ULONG_MAX + single: OverflowError (built-in exception) + + Return a C :ctype:`unsigned long` representation of the contents of *pylong*. + If *pylong* is greater than :const:`ULONG_MAX`, an :exc:`OverflowError` is + raised. + + +.. cfunction:: Py_ssize_t PyLong_AsSsize_t(PyObject *pylong) + + .. index:: + single: PY_SSIZE_T_MAX + + Return a :ctype:`Py_ssize_t` representation of the contents of *pylong*. If + *pylong* is greater than :const:`PY_SSIZE_T_MAX`, an :exc:`OverflowError` is + raised. + + +.. cfunction:: size_t PyLong_AsSize_t(PyObject *pylong) + + Return a :ctype:`size_t` representation of the contents of *pylong*. If + *pylong* is greater than the maximum value for a :ctype:`size_t`, an + :exc:`OverflowError` is raised. + + +.. cfunction:: PY_LONG_LONG PyLong_AsLongLong(PyObject *pylong) + + Return a C :ctype:`long long` from a Python integer. If *pylong* cannot be + represented as a :ctype:`long long`, an :exc:`OverflowError` will be raised. + + +.. cfunction:: unsigned PY_LONG_LONG PyLong_AsUnsignedLongLong(PyObject *pylong) + + Return a C :ctype:`unsigned long long` from a Python integer. If *pylong* + cannot be represented as an :ctype:`unsigned long long`, an :exc:`OverflowError` + will be raised if the value is positive, or a :exc:`TypeError` will be raised if + the value is negative. + + +.. cfunction:: unsigned long PyLong_AsUnsignedLongMask(PyObject *io) + + Return a C :ctype:`unsigned long` from a Python integer, without checking for + overflow. + + +.. cfunction:: unsigned PY_LONG_LONG PyLong_AsUnsignedLongLongMask(PyObject *io) + + Return a C :ctype:`unsigned long long` from a Python integer, without + checking for overflow. + + +.. cfunction:: double PyLong_AsDouble(PyObject *pylong) + + Return a C :ctype:`double` representation of the contents of *pylong*. If + *pylong* cannot be approximately represented as a :ctype:`double`, an + :exc:`OverflowError` exception is raised and ``-1.0`` will be returned. + + +.. cfunction:: void* PyLong_AsVoidPtr(PyObject *pylong) + + Convert a Python integer *pylong* to a C :ctype:`void` pointer. If *pylong* + cannot be converted, an :exc:`OverflowError` will be raised. This is only + assured to produce a usable :ctype:`void` pointer for values created with + :cfunc:`PyLong_FromVoidPtr`. Added: python/branches/py3k/Doc/c-api/mapping.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/mapping.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,78 @@ +.. highlightlang:: c + +.. _mapping: + +Mapping Protocol +================ + + +.. cfunction:: int PyMapping_Check(PyObject *o) + + Return ``1`` if the object provides mapping protocol, and ``0`` otherwise. This + function always succeeds. + + +.. cfunction:: Py_ssize_t PyMapping_Length(PyObject *o) + + .. index:: builtin: len + + Returns the number of keys in object *o* on success, and ``-1`` on failure. For + objects that do not provide mapping protocol, this is equivalent to the Python + expression ``len(o)``. + + +.. cfunction:: int PyMapping_DelItemString(PyObject *o, char *key) + + Remove the mapping for object *key* from the object *o*. Return ``-1`` on + failure. This is equivalent to the Python statement ``del o[key]``. + + +.. cfunction:: int PyMapping_DelItem(PyObject *o, PyObject *key) + + Remove the mapping for object *key* from the object *o*. Return ``-1`` on + failure. This is equivalent to the Python statement ``del o[key]``. + + +.. cfunction:: int PyMapping_HasKeyString(PyObject *o, char *key) + + On success, return ``1`` if the mapping object has the key *key* and ``0`` + otherwise. This is equivalent to the Python expression ``key in o``. + This function always succeeds. + + +.. cfunction:: int PyMapping_HasKey(PyObject *o, PyObject *key) + + Return ``1`` if the mapping object has the key *key* and ``0`` otherwise. This + is equivalent to the Python expression ``key in o``. This function always + succeeds. + + +.. cfunction:: PyObject* PyMapping_Keys(PyObject *o) + + On success, return a list of the keys in object *o*. On failure, return *NULL*. + This is equivalent to the Python expression ``o.keys()``. + + +.. cfunction:: PyObject* PyMapping_Values(PyObject *o) + + On success, return a list of the values in object *o*. On failure, return + *NULL*. This is equivalent to the Python expression ``o.values()``. + + +.. cfunction:: PyObject* PyMapping_Items(PyObject *o) + + On success, return a list of the items in object *o*, where each item is a tuple + containing a key-value pair. On failure, return *NULL*. This is equivalent to + the Python expression ``o.items()``. + + +.. cfunction:: PyObject* PyMapping_GetItemString(PyObject *o, char *key) + + Return element of *o* corresponding to the object *key* or *NULL* on failure. + This is the equivalent of the Python expression ``o[key]``. + + +.. cfunction:: int PyMapping_SetItemString(PyObject *o, char *key, PyObject *v) + + Map the object *key* to the value *v* in object *o*. Returns ``-1`` on failure. + This is the equivalent of the Python statement ``o[key] = v``. Added: python/branches/py3k/Doc/c-api/marshal.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/marshal.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,86 @@ +.. highlightlang:: c + +.. _marshalling-utils: + +Data marshalling support +======================== + +These routines allow C code to work with serialized objects using the same data +format as the :mod:`marshal` module. There are functions to write data into the +serialization format, and additional functions that can be used to read the data +back. Files used to store marshalled data must be opened in binary mode. + +Numeric values are stored with the least significant byte first. + +The module supports two versions of the data format: version 0 is the historical +version, version 1 (new in Python 2.4) shares interned strings in the file, and +upon unmarshalling. *Py_MARSHAL_VERSION* indicates the current file format +(currently 1). + + +.. cfunction:: void PyMarshal_WriteLongToFile(long value, FILE *file, int version) + + Marshal a :ctype:`long` integer, *value*, to *file*. This will only write the + least-significant 32 bits of *value*; regardless of the size of the native + :ctype:`long` type. *version* indicates the file format. + + +.. cfunction:: void PyMarshal_WriteObjectToFile(PyObject *value, FILE *file, int version) + + Marshal a Python object, *value*, to *file*. + *version* indicates the file format. + + +.. cfunction:: PyObject* PyMarshal_WriteObjectToString(PyObject *value, int version) + + Return a string object containing the marshalled representation of *value*. + *version* indicates the file format. + + +The following functions allow marshalled values to be read back in. + +XXX What about error detection? It appears that reading past the end of the +file will always result in a negative numeric value (where that's relevant), but +it's not clear that negative values won't be handled properly when there's no +error. What's the right way to tell? Should only non-negative values be written +using these routines? + + +.. cfunction:: long PyMarshal_ReadLongFromFile(FILE *file) + + Return a C :ctype:`long` from the data stream in a :ctype:`FILE\*` opened for + reading. Only a 32-bit value can be read in using this function, regardless of + the native size of :ctype:`long`. + + +.. cfunction:: int PyMarshal_ReadShortFromFile(FILE *file) + + Return a C :ctype:`short` from the data stream in a :ctype:`FILE\*` opened for + reading. Only a 16-bit value can be read in using this function, regardless of + the native size of :ctype:`short`. + + +.. cfunction:: PyObject* PyMarshal_ReadObjectFromFile(FILE *file) + + Return a Python object from the data stream in a :ctype:`FILE\*` opened for + reading. On error, sets the appropriate exception (:exc:`EOFError` or + :exc:`TypeError`) and returns *NULL*. + + +.. cfunction:: PyObject* PyMarshal_ReadLastObjectFromFile(FILE *file) + + Return a Python object from the data stream in a :ctype:`FILE\*` opened for + reading. Unlike :cfunc:`PyMarshal_ReadObjectFromFile`, this function assumes + that no further objects will be read from the file, allowing it to aggressively + load file data into memory so that the de-serialization can operate from data in + memory rather than reading a byte at a time from the file. Only use these + variant if you are certain that you won't be reading anything else from the + file. On error, sets the appropriate exception (:exc:`EOFError` or + :exc:`TypeError`) and returns *NULL*. + + +.. cfunction:: PyObject* PyMarshal_ReadObjectFromString(char *string, Py_ssize_t len) + + Return a Python object from the data stream in a character buffer containing + *len* bytes pointed to by *string*. On error, sets the appropriate exception + (:exc:`EOFError` or :exc:`TypeError`) and returns *NULL*. Added: python/branches/py3k/Doc/c-api/method.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/method.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,94 @@ +.. highlightlang:: c + +.. _instancemethod-objects: + +Instance Method Objects +----------------------- + +.. index:: object: instancemethod + +An instance method is a wrapper for a :cdata:`PyCFunction` and the new way +to bind a :cdata:`PyCFunction` to a class object. It replaces the former call +``PyMethod_New(func, NULL, class)``. + + +.. cvar:: PyTypeObject PyInstanceMethod_Type + + This instance of :ctype:`PyTypeObject` represents the Python instance + method type. It is not exposed to Python programs. + + +.. cfunction:: int PyInstanceMethod_Check(PyObject *o) + + Return true if *o* is an instance method object (has type + :cdata:`PyInstanceMethod_Type`). The parameter must not be *NULL*. + + +.. cfunction:: PyObject* PyInstanceMethod_New(PyObject *func) + + Return a new instance method object, with *func* being any callable object + *func* is is the function that will be called when the instance method is + called. + + +.. cfunction:: PyObject* PyInstanceMethod_Function(PyObject *im) + + Return the function object associated with the instance method *im*. + + +.. cfunction:: PyObject* PyInstanceMethod_GET_FUNCTION(PyObject *im) + + Macro version of :cfunc:`PyInstanceMethod_Function` which avoids error checking. + + +.. _method-objects: + +Method Objects +-------------- + +.. index:: object: method + +Methods are bound function objects. Methods are always bound to an instance of +an user-defined class. Unbound methods (methods bound to a class object) are +no longer available. + + +.. cvar:: PyTypeObject PyMethod_Type + + .. index:: single: MethodType (in module types) + + This instance of :ctype:`PyTypeObject` represents the Python method type. This + is exposed to Python programs as ``types.MethodType``. + + +.. cfunction:: int PyMethod_Check(PyObject *o) + + Return true if *o* is a method object (has type :cdata:`PyMethod_Type`). The + parameter must not be *NULL*. + + +.. cfunction:: PyObject* PyMethod_New(PyObject *func, PyObject *self) + + Return a new method object, with *func* being any callable object and *self* + the instance the method should be bound. *func* is is the function that will + be called when the method is called. *self* must not be *NULL*. + + +.. cfunction:: PyObject* PyMethod_Function(PyObject *meth) + + Return the function object associated with the method *meth*. + + +.. cfunction:: PyObject* PyMethod_GET_FUNCTION(PyObject *meth) + + Macro version of :cfunc:`PyMethod_Function` which avoids error checking. + + +.. cfunction:: PyObject* PyMethod_Self(PyObject *meth) + + Return the instance associated with the method *meth*. + + +.. cfunction:: PyObject* PyMethod_GET_SELF(PyObject *meth) + + Macro version of :cfunc:`PyMethod_Self` which avoids error checking. Added: python/branches/py3k/Doc/c-api/module.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/module.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,94 @@ +.. highlightlang:: c + +.. _moduleobjects: + +Module Objects +-------------- + +.. index:: object: module + +There are only a few functions special to module objects. + + +.. cvar:: PyTypeObject PyModule_Type + + .. index:: single: ModuleType (in module types) + + This instance of :ctype:`PyTypeObject` represents the Python module type. This + is exposed to Python programs as ``types.ModuleType``. + + +.. cfunction:: int PyModule_Check(PyObject *p) + + Return true if *p* is a module object, or a subtype of a module object. + + +.. cfunction:: int PyModule_CheckExact(PyObject *p) + + Return true if *p* is a module object, but not a subtype of + :cdata:`PyModule_Type`. + + +.. cfunction:: PyObject* PyModule_New(const char *name) + + .. index:: + single: __name__ (module attribute) + single: __doc__ (module attribute) + single: __file__ (module attribute) + + Return a new module object with the :attr:`__name__` attribute set to *name*. + Only the module's :attr:`__doc__` and :attr:`__name__` attributes are filled in; + the caller is responsible for providing a :attr:`__file__` attribute. + + +.. cfunction:: PyObject* PyModule_GetDict(PyObject *module) + + .. index:: single: __dict__ (module attribute) + + Return the dictionary object that implements *module*'s namespace; this object + is the same as the :attr:`__dict__` attribute of the module object. This + function never fails. It is recommended extensions use other + :cfunc:`PyModule_\*` and :cfunc:`PyObject_\*` functions rather than directly + manipulate a module's :attr:`__dict__`. + + +.. cfunction:: char* PyModule_GetName(PyObject *module) + + .. index:: + single: __name__ (module attribute) + single: SystemError (built-in exception) + + Return *module*'s :attr:`__name__` value. If the module does not provide one, + or if it is not a string, :exc:`SystemError` is raised and *NULL* is returned. + + +.. cfunction:: char* PyModule_GetFilename(PyObject *module) + + .. index:: + single: __file__ (module attribute) + single: SystemError (built-in exception) + + Return the name of the file from which *module* was loaded using *module*'s + :attr:`__file__` attribute. If this is not defined, or if it is not a string, + raise :exc:`SystemError` and return *NULL*. + + +.. cfunction:: int PyModule_AddObject(PyObject *module, const char *name, PyObject *value) + + Add an object to *module* as *name*. This is a convenience function which can + be used from the module's initialization function. This steals a reference to + *value*. Return ``-1`` on error, ``0`` on success. + + +.. cfunction:: int PyModule_AddIntConstant(PyObject *module, const char *name, long value) + + Add an integer constant to *module* as *name*. This convenience function can be + used from the module's initialization function. Return ``-1`` on error, ``0`` on + success. + + +.. cfunction:: int PyModule_AddStringConstant(PyObject *module, const char *name, const char *value) + + Add a string constant to *module* as *name*. This convenience function can be + used from the module's initialization function. The string *value* must be + null-terminated. Return ``-1`` on error, ``0`` on success. Added: python/branches/py3k/Doc/c-api/none.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/none.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,26 @@ +.. highlightlang:: c + +.. _noneobject: + +The None Object +--------------- + +.. index:: object: None + +Note that the :ctype:`PyTypeObject` for ``None`` is not directly exposed in the +Python/C API. Since ``None`` is a singleton, testing for object identity (using +``==`` in C) is sufficient. There is no :cfunc:`PyNone_Check` function for the +same reason. + + +.. cvar:: PyObject* Py_None + + The Python ``None`` object, denoting lack of value. This object has no methods. + It needs to be treated just like any other object with respect to reference + counts. + + +.. cmacro:: Py_RETURN_NONE + + Properly handle returning :cdata:`Py_None` from within a C function (that is, + increment the reference count of None and return it.) Added: python/branches/py3k/Doc/c-api/number.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/number.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,276 @@ +.. highlightlang:: c + +.. _number: + +Number Protocol +=============== + + +.. cfunction:: int PyNumber_Check(PyObject *o) + + Returns ``1`` if the object *o* provides numeric protocols, and false otherwise. + This function always succeeds. + + +.. cfunction:: PyObject* PyNumber_Add(PyObject *o1, PyObject *o2) + + Returns the result of adding *o1* and *o2*, or *NULL* on failure. This is the + equivalent of the Python expression ``o1 + o2``. + + +.. cfunction:: PyObject* PyNumber_Subtract(PyObject *o1, PyObject *o2) + + Returns the result of subtracting *o2* from *o1*, or *NULL* on failure. This is + the equivalent of the Python expression ``o1 - o2``. + + +.. cfunction:: PyObject* PyNumber_Multiply(PyObject *o1, PyObject *o2) + + Returns the result of multiplying *o1* and *o2*, or *NULL* on failure. This is + the equivalent of the Python expression ``o1 * o2``. + + +.. cfunction:: PyObject* PyNumber_Divide(PyObject *o1, PyObject *o2) + + Returns the result of dividing *o1* by *o2*, or *NULL* on failure. This is the + equivalent of the Python expression ``o1 / o2``. + + +.. cfunction:: PyObject* PyNumber_FloorDivide(PyObject *o1, PyObject *o2) + + Return the floor of *o1* divided by *o2*, or *NULL* on failure. This is + equivalent to the "classic" division of integers. + + +.. cfunction:: PyObject* PyNumber_TrueDivide(PyObject *o1, PyObject *o2) + + Return a reasonable approximation for the mathematical value of *o1* divided by + *o2*, or *NULL* on failure. The return value is "approximate" because binary + floating point numbers are approximate; it is not possible to represent all real + numbers in base two. This function can return a floating point value when + passed two integers. + + +.. cfunction:: PyObject* PyNumber_Remainder(PyObject *o1, PyObject *o2) + + Returns the remainder of dividing *o1* by *o2*, or *NULL* on failure. This is + the equivalent of the Python expression ``o1 % o2``. + + +.. cfunction:: PyObject* PyNumber_Divmod(PyObject *o1, PyObject *o2) + + .. index:: builtin: divmod + + See the built-in function :func:`divmod`. Returns *NULL* on failure. This is + the equivalent of the Python expression ``divmod(o1, o2)``. + + +.. cfunction:: PyObject* PyNumber_Power(PyObject *o1, PyObject *o2, PyObject *o3) + + .. index:: builtin: pow + + See the built-in function :func:`pow`. Returns *NULL* on failure. This is the + equivalent of the Python expression ``pow(o1, o2, o3)``, where *o3* is optional. + If *o3* is to be ignored, pass :cdata:`Py_None` in its place (passing *NULL* for + *o3* would cause an illegal memory access). + + +.. cfunction:: PyObject* PyNumber_Negative(PyObject *o) + + Returns the negation of *o* on success, or *NULL* on failure. This is the + equivalent of the Python expression ``-o``. + + +.. cfunction:: PyObject* PyNumber_Positive(PyObject *o) + + Returns *o* on success, or *NULL* on failure. This is the equivalent of the + Python expression ``+o``. + + +.. cfunction:: PyObject* PyNumber_Absolute(PyObject *o) + + .. index:: builtin: abs + + Returns the absolute value of *o*, or *NULL* on failure. This is the equivalent + of the Python expression ``abs(o)``. + + +.. cfunction:: PyObject* PyNumber_Invert(PyObject *o) + + Returns the bitwise negation of *o* on success, or *NULL* on failure. This is + the equivalent of the Python expression ``~o``. + + +.. cfunction:: PyObject* PyNumber_Lshift(PyObject *o1, PyObject *o2) + + Returns the result of left shifting *o1* by *o2* on success, or *NULL* on + failure. This is the equivalent of the Python expression ``o1 << o2``. + + +.. cfunction:: PyObject* PyNumber_Rshift(PyObject *o1, PyObject *o2) + + Returns the result of right shifting *o1* by *o2* on success, or *NULL* on + failure. This is the equivalent of the Python expression ``o1 >> o2``. + + +.. cfunction:: PyObject* PyNumber_And(PyObject *o1, PyObject *o2) + + Returns the "bitwise and" of *o1* and *o2* on success and *NULL* on failure. + This is the equivalent of the Python expression ``o1 & o2``. + + +.. cfunction:: PyObject* PyNumber_Xor(PyObject *o1, PyObject *o2) + + Returns the "bitwise exclusive or" of *o1* by *o2* on success, or *NULL* on + failure. This is the equivalent of the Python expression ``o1 ^ o2``. + + +.. cfunction:: PyObject* PyNumber_Or(PyObject *o1, PyObject *o2) + + Returns the "bitwise or" of *o1* and *o2* on success, or *NULL* on failure. + This is the equivalent of the Python expression ``o1 | o2``. + + +.. cfunction:: PyObject* PyNumber_InPlaceAdd(PyObject *o1, PyObject *o2) + + Returns the result of adding *o1* and *o2*, or *NULL* on failure. The operation + is done *in-place* when *o1* supports it. This is the equivalent of the Python + statement ``o1 += o2``. + + +.. cfunction:: PyObject* PyNumber_InPlaceSubtract(PyObject *o1, PyObject *o2) + + Returns the result of subtracting *o2* from *o1*, or *NULL* on failure. The + operation is done *in-place* when *o1* supports it. This is the equivalent of + the Python statement ``o1 -= o2``. + + +.. cfunction:: PyObject* PyNumber_InPlaceMultiply(PyObject *o1, PyObject *o2) + + Returns the result of multiplying *o1* and *o2*, or *NULL* on failure. The + operation is done *in-place* when *o1* supports it. This is the equivalent of + the Python statement ``o1 *= o2``. + + +.. cfunction:: PyObject* PyNumber_InPlaceDivide(PyObject *o1, PyObject *o2) + + Returns the result of dividing *o1* by *o2*, or *NULL* on failure. The + operation is done *in-place* when *o1* supports it. This is the equivalent of + the Python statement ``o1 /= o2``. + + +.. cfunction:: PyObject* PyNumber_InPlaceFloorDivide(PyObject *o1, PyObject *o2) + + Returns the mathematical floor of dividing *o1* by *o2*, or *NULL* on failure. + The operation is done *in-place* when *o1* supports it. This is the equivalent + of the Python statement ``o1 //= o2``. + + +.. cfunction:: PyObject* PyNumber_InPlaceTrueDivide(PyObject *o1, PyObject *o2) + + Return a reasonable approximation for the mathematical value of *o1* divided by + *o2*, or *NULL* on failure. The return value is "approximate" because binary + floating point numbers are approximate; it is not possible to represent all real + numbers in base two. This function can return a floating point value when + passed two integers. The operation is done *in-place* when *o1* supports it. + + +.. cfunction:: PyObject* PyNumber_InPlaceRemainder(PyObject *o1, PyObject *o2) + + Returns the remainder of dividing *o1* by *o2*, or *NULL* on failure. The + operation is done *in-place* when *o1* supports it. This is the equivalent of + the Python statement ``o1 %= o2``. + + +.. cfunction:: PyObject* PyNumber_InPlacePower(PyObject *o1, PyObject *o2, PyObject *o3) + + .. index:: builtin: pow + + See the built-in function :func:`pow`. Returns *NULL* on failure. The operation + is done *in-place* when *o1* supports it. This is the equivalent of the Python + statement ``o1 **= o2`` when o3 is :cdata:`Py_None`, or an in-place variant of + ``pow(o1, o2, o3)`` otherwise. If *o3* is to be ignored, pass :cdata:`Py_None` + in its place (passing *NULL* for *o3* would cause an illegal memory access). + + +.. cfunction:: PyObject* PyNumber_InPlaceLshift(PyObject *o1, PyObject *o2) + + Returns the result of left shifting *o1* by *o2* on success, or *NULL* on + failure. The operation is done *in-place* when *o1* supports it. This is the + equivalent of the Python statement ``o1 <<= o2``. + + +.. cfunction:: PyObject* PyNumber_InPlaceRshift(PyObject *o1, PyObject *o2) + + Returns the result of right shifting *o1* by *o2* on success, or *NULL* on + failure. The operation is done *in-place* when *o1* supports it. This is the + equivalent of the Python statement ``o1 >>= o2``. + + +.. cfunction:: PyObject* PyNumber_InPlaceAnd(PyObject *o1, PyObject *o2) + + Returns the "bitwise and" of *o1* and *o2* on success and *NULL* on failure. The + operation is done *in-place* when *o1* supports it. This is the equivalent of + the Python statement ``o1 &= o2``. + + +.. cfunction:: PyObject* PyNumber_InPlaceXor(PyObject *o1, PyObject *o2) + + Returns the "bitwise exclusive or" of *o1* by *o2* on success, or *NULL* on + failure. The operation is done *in-place* when *o1* supports it. This is the + equivalent of the Python statement ``o1 ^= o2``. + + +.. cfunction:: PyObject* PyNumber_InPlaceOr(PyObject *o1, PyObject *o2) + + Returns the "bitwise or" of *o1* and *o2* on success, or *NULL* on failure. The + operation is done *in-place* when *o1* supports it. This is the equivalent of + the Python statement ``o1 |= o2``. + + +.. cfunction:: PyObject* PyNumber_Int(PyObject *o) + + .. index:: builtin: int + + Returns the *o* converted to an integer object on success, or *NULL* on failure. + If the argument is outside the integer range a long object will be returned + instead. This is the equivalent of the Python expression ``int(o)``. + + +.. cfunction:: PyObject* PyNumber_Long(PyObject *o) + + .. index:: builtin: long + + Returns the *o* converted to an integer object on success, or *NULL* on + failure. This is the equivalent of the Python expression ``long(o)``. + + +.. cfunction:: PyObject* PyNumber_Float(PyObject *o) + + .. index:: builtin: float + + Returns the *o* converted to a float object on success, or *NULL* on failure. + This is the equivalent of the Python expression ``float(o)``. + + +.. cfunction:: PyObject* PyNumber_Index(PyObject *o) + + Returns the *o* converted to a Python int or long on success or *NULL* with a + TypeError exception raised on failure. + + +.. cfunction:: Py_ssize_t PyNumber_AsSsize_t(PyObject *o, PyObject *exc) + + Returns *o* converted to a Py_ssize_t value if *o* can be interpreted as an + integer. If *o* can be converted to a Python int or long but the attempt to + convert to a Py_ssize_t value would raise an :exc:`OverflowError`, then the + *exc* argument is the type of exception that will be raised (usually + :exc:`IndexError` or :exc:`OverflowError`). If *exc* is *NULL*, then the + exception is cleared and the value is clipped to *PY_SSIZE_T_MIN* for a negative + integer or *PY_SSIZE_T_MAX* for a positive integer. + + +.. cfunction:: int PyIndex_Check(PyObject *o) + + Returns True if *o* is an index integer (has the nb_index slot of the + tp_as_number structure filled in). Added: python/branches/py3k/Doc/c-api/objbuffer.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/objbuffer.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,37 @@ +.. highlightlang:: c + +.. _abstract-buffer: + +Buffer Protocol +=============== + + +.. cfunction:: int PyObject_AsCharBuffer(PyObject *obj, const char **buffer, Py_ssize_t *buffer_len) + + Returns a pointer to a read-only memory location useable as character- based + input. The *obj* argument must support the single-segment character buffer + interface. On success, returns ``0``, sets *buffer* to the memory location and + *buffer_len* to the buffer length. Returns ``-1`` and sets a :exc:`TypeError` + on error. + + +.. cfunction:: int PyObject_AsReadBuffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len) + + Returns a pointer to a read-only memory location containing arbitrary data. The + *obj* argument must support the single-segment readable buffer interface. On + success, returns ``0``, sets *buffer* to the memory location and *buffer_len* to + the buffer length. Returns ``-1`` and sets a :exc:`TypeError` on error. + + +.. cfunction:: int PyObject_CheckReadBuffer(PyObject *o) + + Returns ``1`` if *o* supports the single-segment readable buffer interface. + Otherwise returns ``0``. + + +.. cfunction:: int PyObject_AsWriteBuffer(PyObject *obj, void **buffer, Py_ssize_t *buffer_len) + + Returns a pointer to a writable memory location. The *obj* argument must + support the single-segment, character buffer interface. On success, returns + ``0``, sets *buffer* to the memory location and *buffer_len* to the buffer + length. Returns ``-1`` and sets a :exc:`TypeError` on error. Added: python/branches/py3k/Doc/c-api/object.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/object.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,325 @@ +.. highlightlang:: c + +.. _object: + +Object Protocol +=============== + + +.. cfunction:: int PyObject_Print(PyObject *o, FILE *fp, int flags) + + Print an object *o*, on file *fp*. Returns ``-1`` on error. The flags argument + is used to enable certain printing options. The only option currently supported + is :const:`Py_PRINT_RAW`; if given, the :func:`str` of the object is written + instead of the :func:`repr`. + + +.. cfunction:: int PyObject_HasAttr(PyObject *o, PyObject *attr_name) + + Returns ``1`` if *o* has the attribute *attr_name*, and ``0`` otherwise. This + is equivalent to the Python expression ``hasattr(o, attr_name)``. This function + always succeeds. + + +.. cfunction:: int PyObject_HasAttrString(PyObject *o, const char *attr_name) + + Returns ``1`` if *o* has the attribute *attr_name*, and ``0`` otherwise. This + is equivalent to the Python expression ``hasattr(o, attr_name)``. This function + always succeeds. + + +.. cfunction:: PyObject* PyObject_GetAttr(PyObject *o, PyObject *attr_name) + + Retrieve an attribute named *attr_name* from object *o*. Returns the attribute + value on success, or *NULL* on failure. This is the equivalent of the Python + expression ``o.attr_name``. + + +.. cfunction:: PyObject* PyObject_GetAttrString(PyObject *o, const char *attr_name) + + Retrieve an attribute named *attr_name* from object *o*. Returns the attribute + value on success, or *NULL* on failure. This is the equivalent of the Python + expression ``o.attr_name``. + + +.. cfunction:: int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v) + + Set the value of the attribute named *attr_name*, for object *o*, to the value + *v*. Returns ``-1`` on failure. This is the equivalent of the Python statement + ``o.attr_name = v``. + + +.. cfunction:: int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v) + + Set the value of the attribute named *attr_name*, for object *o*, to the value + *v*. Returns ``-1`` on failure. This is the equivalent of the Python statement + ``o.attr_name = v``. + + +.. cfunction:: int PyObject_DelAttr(PyObject *o, PyObject *attr_name) + + Delete attribute named *attr_name*, for object *o*. Returns ``-1`` on failure. + This is the equivalent of the Python statement ``del o.attr_name``. + + +.. cfunction:: int PyObject_DelAttrString(PyObject *o, const char *attr_name) + + Delete attribute named *attr_name*, for object *o*. Returns ``-1`` on failure. + This is the equivalent of the Python statement ``del o.attr_name``. + + +.. cfunction:: PyObject* PyObject_RichCompare(PyObject *o1, PyObject *o2, int opid) + + Compare the values of *o1* and *o2* using the operation specified by *opid*, + which must be one of :const:`Py_LT`, :const:`Py_LE`, :const:`Py_EQ`, + :const:`Py_NE`, :const:`Py_GT`, or :const:`Py_GE`, corresponding to ``<``, + ``<=``, ``==``, ``!=``, ``>``, or ``>=`` respectively. This is the equivalent of + the Python expression ``o1 op o2``, where ``op`` is the operator corresponding + to *opid*. Returns the value of the comparison on success, or *NULL* on failure. + + +.. cfunction:: int PyObject_RichCompareBool(PyObject *o1, PyObject *o2, int opid) + + Compare the values of *o1* and *o2* using the operation specified by *opid*, + which must be one of :const:`Py_LT`, :const:`Py_LE`, :const:`Py_EQ`, + :const:`Py_NE`, :const:`Py_GT`, or :const:`Py_GE`, corresponding to ``<``, + ``<=``, ``==``, ``!=``, ``>``, or ``>=`` respectively. Returns ``-1`` on error, + ``0`` if the result is false, ``1`` otherwise. This is the equivalent of the + Python expression ``o1 op o2``, where ``op`` is the operator corresponding to + *opid*. + + +.. cfunction:: int PyObject_Cmp(PyObject *o1, PyObject *o2, int *result) + + .. index:: builtin: cmp + + Compare the values of *o1* and *o2* using a routine provided by *o1*, if one + exists, otherwise with a routine provided by *o2*. The result of the comparison + is returned in *result*. Returns ``-1`` on failure. This is the equivalent of + the Python statement ``result = cmp(o1, o2)``. + + +.. cfunction:: int PyObject_Compare(PyObject *o1, PyObject *o2) + + .. index:: builtin: cmp + + Compare the values of *o1* and *o2* using a routine provided by *o1*, if one + exists, otherwise with a routine provided by *o2*. Returns the result of the + comparison on success. On error, the value returned is undefined; use + :cfunc:`PyErr_Occurred` to detect an error. This is equivalent to the Python + expression ``cmp(o1, o2)``. + + +.. cfunction:: PyObject* PyObject_Repr(PyObject *o) + + .. index:: builtin: repr + + Compute a string representation of object *o*. Returns the string + representation on success, *NULL* on failure. This is the equivalent of the + Python expression ``repr(o)``. Called by the :func:`repr` built-in function and + by reverse quotes. + + +.. cfunction:: PyObject* PyObject_Str(PyObject *o) + + .. index:: builtin: str + + Compute a string representation of object *o*. Returns the string + representation on success, *NULL* on failure. This is the equivalent of the + Python expression ``str(o)``. Called by the :func:`str` built-in function + and, therefore, by the :func:`print` function. + + +.. cfunction:: PyObject* PyObject_Unicode(PyObject *o) + + .. index:: builtin: unicode + + Compute a Unicode string representation of object *o*. Returns the Unicode + string representation on success, *NULL* on failure. This is the equivalent of + the Python expression ``unicode(o)``. Called by the :func:`unicode` built-in + function. + + +.. cfunction:: int PyObject_IsInstance(PyObject *inst, PyObject *cls) + + Returns ``1`` if *inst* is an instance of the class *cls* or a subclass of + *cls*, or ``0`` if not. On error, returns ``-1`` and sets an exception. If + *cls* is a type object rather than a class object, :cfunc:`PyObject_IsInstance` + returns ``1`` if *inst* is of type *cls*. If *cls* is a tuple, the check will + be done against every entry in *cls*. The result will be ``1`` when at least one + of the checks returns ``1``, otherwise it will be ``0``. If *inst* is not a + class instance and *cls* is neither a type object, nor a class object, nor a + tuple, *inst* must have a :attr:`__class__` attribute --- the class relationship + of the value of that attribute with *cls* will be used to determine the result + of this function. + + +Subclass determination is done in a fairly straightforward way, but includes a +wrinkle that implementors of extensions to the class system may want to be aware +of. If :class:`A` and :class:`B` are class objects, :class:`B` is a subclass of +:class:`A` if it inherits from :class:`A` either directly or indirectly. If +either is not a class object, a more general mechanism is used to determine the +class relationship of the two objects. When testing if *B* is a subclass of +*A*, if *A* is *B*, :cfunc:`PyObject_IsSubclass` returns true. If *A* and *B* +are different objects, *B*'s :attr:`__bases__` attribute is searched in a +depth-first fashion for *A* --- the presence of the :attr:`__bases__` attribute +is considered sufficient for this determination. + + +.. cfunction:: int PyObject_IsSubclass(PyObject *derived, PyObject *cls) + + Returns ``1`` if the class *derived* is identical to or derived from the class + *cls*, otherwise returns ``0``. In case of an error, returns ``-1``. If *cls* + is a tuple, the check will be done against every entry in *cls*. The result will + be ``1`` when at least one of the checks returns ``1``, otherwise it will be + ``0``. If either *derived* or *cls* is not an actual class object (or tuple), + this function uses the generic algorithm described above. + + +.. cfunction:: int PyCallable_Check(PyObject *o) + + Determine if the object *o* is callable. Return ``1`` if the object is callable + and ``0`` otherwise. This function always succeeds. + + +.. cfunction:: PyObject* PyObject_Call(PyObject *callable_object, PyObject *args, PyObject *kw) + + Call a callable Python object *callable_object*, with arguments given by the + tuple *args*, and named arguments given by the dictionary *kw*. If no named + arguments are needed, *kw* may be *NULL*. *args* must not be *NULL*, use an + empty tuple if no arguments are needed. Returns the result of the call on + success, or *NULL* on failure. This is the equivalent of the Python expression + ``callable_object(*args, **kw)``. + + +.. cfunction:: PyObject* PyObject_CallObject(PyObject *callable_object, PyObject *args) + + Call a callable Python object *callable_object*, with arguments given by the + tuple *args*. If no arguments are needed, then *args* may be *NULL*. Returns + the result of the call on success, or *NULL* on failure. This is the equivalent + of the Python expression ``callable_object(*args)``. + + +.. cfunction:: PyObject* PyObject_CallFunction(PyObject *callable, char *format, ...) + + Call a callable Python object *callable*, with a variable number of C arguments. + The C arguments are described using a :cfunc:`Py_BuildValue` style format + string. The format may be *NULL*, indicating that no arguments are provided. + Returns the result of the call on success, or *NULL* on failure. This is the + equivalent of the Python expression ``callable(*args)``. Note that if you only + pass :ctype:`PyObject \*` args, :cfunc:`PyObject_CallFunctionObjArgs` is a + faster alternative. + + +.. cfunction:: PyObject* PyObject_CallMethod(PyObject *o, char *method, char *format, ...) + + Call the method named *method* of object *o* with a variable number of C + arguments. The C arguments are described by a :cfunc:`Py_BuildValue` format + string that should produce a tuple. The format may be *NULL*, indicating that + no arguments are provided. Returns the result of the call on success, or *NULL* + on failure. This is the equivalent of the Python expression ``o.method(args)``. + Note that if you only pass :ctype:`PyObject \*` args, + :cfunc:`PyObject_CallMethodObjArgs` is a faster alternative. + + +.. cfunction:: PyObject* PyObject_CallFunctionObjArgs(PyObject *callable, ..., NULL) + + Call a callable Python object *callable*, with a variable number of + :ctype:`PyObject\*` arguments. The arguments are provided as a variable number + of parameters followed by *NULL*. Returns the result of the call on success, or + *NULL* on failure. + + +.. cfunction:: PyObject* PyObject_CallMethodObjArgs(PyObject *o, PyObject *name, ..., NULL) + + Calls a method of the object *o*, where the name of the method is given as a + Python string object in *name*. It is called with a variable number of + :ctype:`PyObject\*` arguments. The arguments are provided as a variable number + of parameters followed by *NULL*. Returns the result of the call on success, or + *NULL* on failure. + + +.. cfunction:: long PyObject_Hash(PyObject *o) + + .. index:: builtin: hash + + Compute and return the hash value of an object *o*. On failure, return ``-1``. + This is the equivalent of the Python expression ``hash(o)``. + + +.. cfunction:: int PyObject_IsTrue(PyObject *o) + + Returns ``1`` if the object *o* is considered to be true, and ``0`` otherwise. + This is equivalent to the Python expression ``not not o``. On failure, return + ``-1``. + + +.. cfunction:: int PyObject_Not(PyObject *o) + + Returns ``0`` if the object *o* is considered to be true, and ``1`` otherwise. + This is equivalent to the Python expression ``not o``. On failure, return + ``-1``. + + +.. cfunction:: PyObject* PyObject_Type(PyObject *o) + + .. index:: builtin: type + + When *o* is non-*NULL*, returns a type object corresponding to the object type + of object *o*. On failure, raises :exc:`SystemError` and returns *NULL*. This + is equivalent to the Python expression ``type(o)``. This function increments the + reference count of the return value. There's really no reason to use this + function instead of the common expression ``o->ob_type``, which returns a + pointer of type :ctype:`PyTypeObject\*`, except when the incremented reference + count is needed. + + +.. cfunction:: int PyObject_TypeCheck(PyObject *o, PyTypeObject *type) + + Return true if the object *o* is of type *type* or a subtype of *type*. Both + parameters must be non-*NULL*. + + +.. cfunction:: Py_ssize_t PyObject_Length(PyObject *o) + Py_ssize_t PyObject_Size(PyObject *o) + + .. index:: builtin: len + + Return the length of object *o*. If the object *o* provides either the sequence + and mapping protocols, the sequence length is returned. On error, ``-1`` is + returned. This is the equivalent to the Python expression ``len(o)``. + + +.. cfunction:: PyObject* PyObject_GetItem(PyObject *o, PyObject *key) + + Return element of *o* corresponding to the object *key* or *NULL* on failure. + This is the equivalent of the Python expression ``o[key]``. + + +.. cfunction:: int PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v) + + Map the object *key* to the value *v*. Returns ``-1`` on failure. This is the + equivalent of the Python statement ``o[key] = v``. + + +.. cfunction:: int PyObject_DelItem(PyObject *o, PyObject *key) + + Delete the mapping for *key* from *o*. Returns ``-1`` on failure. This is the + equivalent of the Python statement ``del o[key]``. + + +.. cfunction:: PyObject* PyObject_Dir(PyObject *o) + + This is equivalent to the Python expression ``dir(o)``, returning a (possibly + empty) list of strings appropriate for the object argument, or *NULL* if there + was an error. If the argument is *NULL*, this is like the Python ``dir()``, + returning the names of the current locals; in this case, if no execution frame + is active then *NULL* is returned but :cfunc:`PyErr_Occurred` will return false. + + +.. cfunction:: PyObject* PyObject_GetIter(PyObject *o) + + This is equivalent to the Python expression ``iter(o)``. It returns a new + iterator for the object argument, or the object itself if the object is already + an iterator. Raises :exc:`TypeError` and returns *NULL* if the object cannot be + iterated. Added: python/branches/py3k/Doc/c-api/objimpl.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/objimpl.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,17 @@ +.. highlightlang:: c + +.. _newtypes: + +***************************** +Object Implementation Support +***************************** + +This chapter describes the functions, types, and macros used when defining new +object types. + +.. toctree:: + + allocation.rst + structures.rst + typeobj.rst + gcsupport.rst Added: python/branches/py3k/Doc/c-api/reflection.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/reflection.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,50 @@ +.. highlightlang:: c + +.. _reflection: + +Reflection +========== + +.. cfunction:: PyObject* PyEval_GetBuiltins() + + Return a dictionary of the builtins in the current execution frame, + or the interpreter of the thread state if no frame is currently executing. + + +.. cfunction:: PyObject* PyEval_GetLocals() + + Return a dictionary of the local variables in the current execution frame, + or *NULL* if no frame is currently executing. + + +.. cfunction:: PyObject* PyEval_GetGlobals() + + Return a dictionary of the global variables in the current execution frame, + or *NULL* if no frame is currently executing. + + +.. cfunction:: PyFrameObject* PyEval_GetFrame() + + Return the current thread state's frame, which is *NULL* if no frame is + currently executing. + + +.. cfunction:: int PyEval_GetRestricted() + + If there is a current frame and it is executing in restricted mode, return true, + otherwise false. + + +.. cfunction:: const char* PyEval_GetFuncName(PyObject *func) + + Return the name of *func* if it is a function, class or instance object, else the + name of *func*\s type. + + +.. cfunction:: const char* PyEval_GetFuncDesc(PyObject *func) + + Return a description string, depending on the type of *func*. + Return values include "()" for functions and methods, " constructor", + " instance", and " object". Concatenated with the result of + :cfunc:`PyEval_GetFuncName`, the result will be a description of + *func*. Added: python/branches/py3k/Doc/c-api/sequence.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/sequence.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,162 @@ +.. highlightlang:: c + +.. _sequence: + +Sequence Protocol +================= + + +.. cfunction:: int PySequence_Check(PyObject *o) + + Return ``1`` if the object provides sequence protocol, and ``0`` otherwise. + This function always succeeds. + + +.. cfunction:: Py_ssize_t PySequence_Size(PyObject *o) + + .. index:: builtin: len + + Returns the number of objects in sequence *o* on success, and ``-1`` on failure. + For objects that do not provide sequence protocol, this is equivalent to the + Python expression ``len(o)``. + + +.. cfunction:: Py_ssize_t PySequence_Length(PyObject *o) + + Alternate name for :cfunc:`PySequence_Size`. + + +.. cfunction:: PyObject* PySequence_Concat(PyObject *o1, PyObject *o2) + + Return the concatenation of *o1* and *o2* on success, and *NULL* on failure. + This is the equivalent of the Python expression ``o1 + o2``. + + +.. cfunction:: PyObject* PySequence_Repeat(PyObject *o, Py_ssize_t count) + + Return the result of repeating sequence object *o* *count* times, or *NULL* on + failure. This is the equivalent of the Python expression ``o * count``. + + +.. cfunction:: PyObject* PySequence_InPlaceConcat(PyObject *o1, PyObject *o2) + + Return the concatenation of *o1* and *o2* on success, and *NULL* on failure. + The operation is done *in-place* when *o1* supports it. This is the equivalent + of the Python expression ``o1 += o2``. + + +.. cfunction:: PyObject* PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count) + + Return the result of repeating sequence object *o* *count* times, or *NULL* on + failure. The operation is done *in-place* when *o* supports it. This is the + equivalent of the Python expression ``o *= count``. + + +.. cfunction:: PyObject* PySequence_GetItem(PyObject *o, Py_ssize_t i) + + Return the *i*th element of *o*, or *NULL* on failure. This is the equivalent of + the Python expression ``o[i]``. + + +.. cfunction:: PyObject* PySequence_GetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2) + + Return the slice of sequence object *o* between *i1* and *i2*, or *NULL* on + failure. This is the equivalent of the Python expression ``o[i1:i2]``. + + +.. cfunction:: int PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v) + + Assign object *v* to the *i*th element of *o*. Returns ``-1`` on failure. This + is the equivalent of the Python statement ``o[i] = v``. This function *does + not* steal a reference to *v*. + + +.. cfunction:: int PySequence_DelItem(PyObject *o, Py_ssize_t i) + + Delete the *i*th element of object *o*. Returns ``-1`` on failure. This is the + equivalent of the Python statement ``del o[i]``. + + +.. cfunction:: int PySequence_SetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2, PyObject *v) + + Assign the sequence object *v* to the slice in sequence object *o* from *i1* to + *i2*. This is the equivalent of the Python statement ``o[i1:i2] = v``. + + +.. cfunction:: int PySequence_DelSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2) + + Delete the slice in sequence object *o* from *i1* to *i2*. Returns ``-1`` on + failure. This is the equivalent of the Python statement ``del o[i1:i2]``. + + +.. cfunction:: Py_ssize_t PySequence_Count(PyObject *o, PyObject *value) + + Return the number of occurrences of *value* in *o*, that is, return the number + of keys for which ``o[key] == value``. On failure, return ``-1``. This is + equivalent to the Python expression ``o.count(value)``. + + +.. cfunction:: int PySequence_Contains(PyObject *o, PyObject *value) + + Determine if *o* contains *value*. If an item in *o* is equal to *value*, + return ``1``, otherwise return ``0``. On error, return ``-1``. This is + equivalent to the Python expression ``value in o``. + + +.. cfunction:: Py_ssize_t PySequence_Index(PyObject *o, PyObject *value) + + Return the first index *i* for which ``o[i] == value``. On error, return + ``-1``. This is equivalent to the Python expression ``o.index(value)``. + + +.. cfunction:: PyObject* PySequence_List(PyObject *o) + + Return a list object with the same contents as the arbitrary sequence *o*. The + returned list is guaranteed to be new. + + +.. cfunction:: PyObject* PySequence_Tuple(PyObject *o) + + .. index:: builtin: tuple + + Return a tuple object with the same contents as the arbitrary sequence *o* or + *NULL* on failure. If *o* is a tuple, a new reference will be returned, + otherwise a tuple will be constructed with the appropriate contents. This is + equivalent to the Python expression ``tuple(o)``. + + +.. cfunction:: PyObject* PySequence_Fast(PyObject *o, const char *m) + + Returns the sequence *o* as a tuple, unless it is already a tuple or list, in + which case *o* is returned. Use :cfunc:`PySequence_Fast_GET_ITEM` to access the + members of the result. Returns *NULL* on failure. If the object is not a + sequence, raises :exc:`TypeError` with *m* as the message text. + + +.. cfunction:: PyObject* PySequence_Fast_GET_ITEM(PyObject *o, Py_ssize_t i) + + Return the *i*th element of *o*, assuming that *o* was returned by + :cfunc:`PySequence_Fast`, *o* is not *NULL*, and that *i* is within bounds. + + +.. cfunction:: PyObject** PySequence_Fast_ITEMS(PyObject *o) + + Return the underlying array of PyObject pointers. Assumes that *o* was returned + by :cfunc:`PySequence_Fast` and *o* is not *NULL*. + + +.. cfunction:: PyObject* PySequence_ITEM(PyObject *o, Py_ssize_t i) + + Return the *i*th element of *o* or *NULL* on failure. Macro form of + :cfunc:`PySequence_GetItem` but without checking that + :cfunc:`PySequence_Check(o)` is true and without adjustment for negative + indices. + + +.. cfunction:: Py_ssize_t PySequence_Fast_GET_SIZE(PyObject *o) + + Returns the length of *o*, assuming that *o* was returned by + :cfunc:`PySequence_Fast` and that *o* is not *NULL*. The size can also be + gotten by calling :cfunc:`PySequence_Size` on *o*, but + :cfunc:`PySequence_Fast_GET_SIZE` is faster because it can assume *o* is a list + or tuple. Added: python/branches/py3k/Doc/c-api/set.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/set.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,146 @@ +.. highlightlang:: c + +.. _setobjects: + +Set Objects +----------- + +.. sectionauthor:: Raymond D. Hettinger + + +.. index:: + object: set + object: frozenset + +This section details the public API for :class:`set` and :class:`frozenset` +objects. Any functionality not listed below is best accessed using the either +the abstract object protocol (including :cfunc:`PyObject_CallMethod`, +:cfunc:`PyObject_RichCompareBool`, :cfunc:`PyObject_Hash`, +:cfunc:`PyObject_Repr`, :cfunc:`PyObject_IsTrue`, :cfunc:`PyObject_Print`, and +:cfunc:`PyObject_GetIter`) or the abstract number protocol (including +:cfunc:`PyNumber_And`, :cfunc:`PyNumber_Subtract`, :cfunc:`PyNumber_Or`, +:cfunc:`PyNumber_Xor`, :cfunc:`PyNumber_InPlaceAnd`, +:cfunc:`PyNumber_InPlaceSubtract`, :cfunc:`PyNumber_InPlaceOr`, and +:cfunc:`PyNumber_InPlaceXor`). + + +.. ctype:: PySetObject + + This subtype of :ctype:`PyObject` is used to hold the internal data for both + :class:`set` and :class:`frozenset` objects. It is like a :ctype:`PyDictObject` + in that it is a fixed size for small sets (much like tuple storage) and will + point to a separate, variable sized block of memory for medium and large sized + sets (much like list storage). None of the fields of this structure should be + considered public and are subject to change. All access should be done through + the documented API rather than by manipulating the values in the structure. + + +.. cvar:: PyTypeObject PySet_Type + + This is an instance of :ctype:`PyTypeObject` representing the Python + :class:`set` type. + + +.. cvar:: PyTypeObject PyFrozenSet_Type + + This is an instance of :ctype:`PyTypeObject` representing the Python + :class:`frozenset` type. + +The following type check macros work on pointers to any Python object. Likewise, +the constructor functions work with any iterable Python object. + + +.. cfunction:: int PyAnySet_Check(PyObject *p) + + Return true if *p* is a :class:`set` object, a :class:`frozenset` object, or an + instance of a subtype. + + +.. cfunction:: int PyAnySet_CheckExact(PyObject *p) + + Return true if *p* is a :class:`set` object or a :class:`frozenset` object but + not an instance of a subtype. + + +.. cfunction:: int PyFrozenSet_CheckExact(PyObject *p) + + Return true if *p* is a :class:`frozenset` object but not an instance of a + subtype. + + +.. cfunction:: PyObject* PySet_New(PyObject *iterable) + + Return a new :class:`set` containing objects returned by the *iterable*. The + *iterable* may be *NULL* to create a new empty set. Return the new set on + success or *NULL* on failure. Raise :exc:`TypeError` if *iterable* is not + actually iterable. The constructor is also useful for copying a set + (``c=set(s)``). + + +.. cfunction:: PyObject* PyFrozenSet_New(PyObject *iterable) + + Return a new :class:`frozenset` containing objects returned by the *iterable*. + The *iterable* may be *NULL* to create a new empty frozenset. Return the new + set on success or *NULL* on failure. Raise :exc:`TypeError` if *iterable* is + not actually iterable. + +The following functions and macros are available for instances of :class:`set` +or :class:`frozenset` or instances of their subtypes. + + +.. cfunction:: Py_ssize_t PySet_Size(PyObject *anyset) + + .. index:: builtin: len + + Return the length of a :class:`set` or :class:`frozenset` object. Equivalent to + ``len(anyset)``. Raises a :exc:`PyExc_SystemError` if *anyset* is not a + :class:`set`, :class:`frozenset`, or an instance of a subtype. + + +.. cfunction:: Py_ssize_t PySet_GET_SIZE(PyObject *anyset) + + Macro form of :cfunc:`PySet_Size` without error checking. + + +.. cfunction:: int PySet_Contains(PyObject *anyset, PyObject *key) + + Return 1 if found, 0 if not found, and -1 if an error is encountered. Unlike + the Python :meth:`__contains__` method, this function does not automatically + convert unhashable sets into temporary frozensets. Raise a :exc:`TypeError` if + the *key* is unhashable. Raise :exc:`PyExc_SystemError` if *anyset* is not a + :class:`set`, :class:`frozenset`, or an instance of a subtype. + +The following functions are available for instances of :class:`set` or its +subtypes but not for instances of :class:`frozenset` or its subtypes. + + +.. cfunction:: int PySet_Add(PyObject *set, PyObject *key) + + Add *key* to a :class:`set` instance. Does not apply to :class:`frozenset` + instances. Return 0 on success or -1 on failure. Raise a :exc:`TypeError` if + the *key* is unhashable. Raise a :exc:`MemoryError` if there is no room to grow. + Raise a :exc:`SystemError` if *set* is an not an instance of :class:`set` or its + subtype. + + +.. cfunction:: int PySet_Discard(PyObject *set, PyObject *key) + + Return 1 if found and removed, 0 if not found (no action taken), and -1 if an + error is encountered. Does not raise :exc:`KeyError` for missing keys. Raise a + :exc:`TypeError` if the *key* is unhashable. Unlike the Python :meth:`discard` + method, this function does not automatically convert unhashable sets into + temporary frozensets. Raise :exc:`PyExc_SystemError` if *set* is an not an + instance of :class:`set` or its subtype. + + +.. cfunction:: PyObject* PySet_Pop(PyObject *set) + + Return a new reference to an arbitrary object in the *set*, and removes the + object from the *set*. Return *NULL* on failure. Raise :exc:`KeyError` if the + set is empty. Raise a :exc:`SystemError` if *set* is an not an instance of + :class:`set` or its subtype. + + +.. cfunction:: int PySet_Clear(PyObject *set) + + Empty an existing set of all elements. Added: python/branches/py3k/Doc/c-api/slice.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/slice.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,54 @@ +.. highlightlang:: c + +.. _slice-objects: + +Slice Objects +------------- + + +.. cvar:: PyTypeObject PySlice_Type + + .. index:: single: SliceType (in module types) + + The type object for slice objects. This is the same as ``slice`` and + ``types.SliceType``. + + +.. cfunction:: int PySlice_Check(PyObject *ob) + + Return true if *ob* is a slice object; *ob* must not be *NULL*. + + +.. cfunction:: PyObject* PySlice_New(PyObject *start, PyObject *stop, PyObject *step) + + Return a new slice object with the given values. The *start*, *stop*, and + *step* parameters are used as the values of the slice object attributes of the + same names. Any of the values may be *NULL*, in which case the ``None`` will be + used for the corresponding attribute. Return *NULL* if the new object could not + be allocated. + + +.. cfunction:: int PySlice_GetIndices(PySliceObject *slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step) + + Retrieve the start, stop and step indices from the slice object *slice*, + assuming a sequence of length *length*. Treats indices greater than *length* as + errors. + + Returns 0 on success and -1 on error with no exception set (unless one of the + indices was not :const:`None` and failed to be converted to an integer, in which + case -1 is returned with an exception set). + + You probably do not want to use this function. If you want to use slice objects + in versions of Python prior to 2.3, you would probably do well to incorporate + the source of :cfunc:`PySlice_GetIndicesEx`, suitably renamed, in the source of + your extension. + + +.. cfunction:: int PySlice_GetIndicesEx(PySliceObject *slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength) + + Usable replacement for :cfunc:`PySlice_GetIndices`. Retrieve the start, stop, + and step indices from the slice object *slice* assuming a sequence of length + *length*, and store the length of the slice in *slicelength*. Out of bounds + indices are clipped in a manner consistent with the handling of normal slices. + + Returns 0 on success and -1 on error with exception set. Added: python/branches/py3k/Doc/c-api/string.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/string.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,246 @@ +.. highlightlang:: c + +.. _stringobjects: + +String Objects +-------------- + +These functions raise :exc:`TypeError` when expecting a string parameter and are +called with a non-string parameter. + +.. index:: object: string + + +.. ctype:: PyStringObject + + This subtype of :ctype:`PyObject` represents a Python string object. + + +.. cvar:: PyTypeObject PyString_Type + + .. index:: single: StringType (in module types) + + This instance of :ctype:`PyTypeObject` represents the Python string type; it is + the same object as ``str`` and ``types.StringType`` in the Python layer. . + + +.. cfunction:: int PyString_Check(PyObject *o) + + Return true if the object *o* is a string object or an instance of a subtype of + the string type. + + +.. cfunction:: int PyString_CheckExact(PyObject *o) + + Return true if the object *o* is a string object, but not an instance of a + subtype of the string type. + + +.. cfunction:: PyObject* PyString_FromString(const char *v) + + Return a new string object with a copy of the string *v* as value on success, + and *NULL* on failure. The parameter *v* must not be *NULL*; it will not be + checked. + + +.. cfunction:: PyObject* PyString_FromStringAndSize(const char *v, Py_ssize_t len) + + Return a new string object with a copy of the string *v* as value and length + *len* on success, and *NULL* on failure. If *v* is *NULL*, the contents of the + string are uninitialized. + + +.. cfunction:: PyObject* PyString_FromFormat(const char *format, ...) + + Take a C :cfunc:`printf`\ -style *format* string and a variable number of + arguments, calculate the size of the resulting Python string and return a string + with the values formatted into it. The variable arguments must be C types and + must correspond exactly to the format characters in the *format* string. The + following format characters are allowed: + + .. % XXX: This should be exactly the same as the table in PyErr_Format. + .. % One should just refer to the other. + .. % XXX: The descriptions for %zd and %zu are wrong, but the truth is complicated + .. % because not all compilers support the %z width modifier -- we fake it + .. % when necessary via interpolating PY_FORMAT_SIZE_T. + .. % %u, %lu, %zu should have "new in Python 2.5" blurbs. + + +-------------------+---------------+--------------------------------+ + | Format Characters | Type | Comment | + +===================+===============+================================+ + | :attr:`%%` | *n/a* | The literal % character. | + +-------------------+---------------+--------------------------------+ + | :attr:`%c` | int | A single character, | + | | | represented as an C int. | + +-------------------+---------------+--------------------------------+ + | :attr:`%d` | int | Exactly equivalent to | + | | | ``printf("%d")``. | + +-------------------+---------------+--------------------------------+ + | :attr:`%u` | unsigned int | Exactly equivalent to | + | | | ``printf("%u")``. | + +-------------------+---------------+--------------------------------+ + | :attr:`%ld` | long | Exactly equivalent to | + | | | ``printf("%ld")``. | + +-------------------+---------------+--------------------------------+ + | :attr:`%lu` | unsigned long | Exactly equivalent to | + | | | ``printf("%lu")``. | + +-------------------+---------------+--------------------------------+ + | :attr:`%zd` | Py_ssize_t | Exactly equivalent to | + | | | ``printf("%zd")``. | + +-------------------+---------------+--------------------------------+ + | :attr:`%zu` | size_t | Exactly equivalent to | + | | | ``printf("%zu")``. | + +-------------------+---------------+--------------------------------+ + | :attr:`%i` | int | Exactly equivalent to | + | | | ``printf("%i")``. | + +-------------------+---------------+--------------------------------+ + | :attr:`%x` | int | Exactly equivalent to | + | | | ``printf("%x")``. | + +-------------------+---------------+--------------------------------+ + | :attr:`%s` | char\* | A null-terminated C character | + | | | array. | + +-------------------+---------------+--------------------------------+ + | :attr:`%p` | void\* | The hex representation of a C | + | | | pointer. Mostly equivalent to | + | | | ``printf("%p")`` except that | + | | | it is guaranteed to start with | + | | | the literal ``0x`` regardless | + | | | of what the platform's | + | | | ``printf`` yields. | + +-------------------+---------------+--------------------------------+ + + 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. + + +.. cfunction:: PyObject* PyString_FromFormatV(const char *format, va_list vargs) + + Identical to :func:`PyString_FromFormat` except that it takes exactly two + arguments. + + +.. cfunction:: Py_ssize_t PyString_Size(PyObject *string) + + Return the length of the string in string object *string*. + + +.. cfunction:: Py_ssize_t PyString_GET_SIZE(PyObject *string) + + Macro form of :cfunc:`PyString_Size` but without error checking. + + +.. cfunction:: char* PyString_AsString(PyObject *string) + + Return a NUL-terminated representation of the contents of *string*. The pointer + refers to the internal buffer of *string*, not a copy. The data must not be + modified in any way, unless the string was just created using + ``PyString_FromStringAndSize(NULL, size)``. It must not be deallocated. If + *string* is a Unicode object, this function computes the default encoding of + *string* and operates on that. If *string* is not a string object at all, + :cfunc:`PyString_AsString` returns *NULL* and raises :exc:`TypeError`. + + +.. cfunction:: char* PyString_AS_STRING(PyObject *string) + + Macro form of :cfunc:`PyString_AsString` but without error checking. Only + string objects are supported; no Unicode objects should be passed. + + +.. cfunction:: int PyString_AsStringAndSize(PyObject *obj, char **buffer, Py_ssize_t *length) + + Return a NUL-terminated representation of the contents of the object *obj* + through the output variables *buffer* and *length*. + + The function accepts both string and Unicode objects as input. For Unicode + objects it returns the default encoded version of the object. If *length* is + *NULL*, the resulting buffer may not contain NUL characters; if it does, the + function returns ``-1`` and a :exc:`TypeError` is raised. + + The buffer refers to an internal string buffer of *obj*, not a copy. The data + must not be modified in any way, unless the string was just created using + ``PyString_FromStringAndSize(NULL, size)``. It must not be deallocated. If + *string* is a Unicode object, this function computes the default encoding of + *string* and operates on that. If *string* is not a string object at all, + :cfunc:`PyString_AsStringAndSize` returns ``-1`` and raises :exc:`TypeError`. + + +.. cfunction:: void PyString_Concat(PyObject **string, PyObject *newpart) + + Create a new string object in *\*string* containing the contents of *newpart* + appended to *string*; the caller will own the new reference. The reference to + the old value of *string* will be stolen. If the new string cannot be created, + the old reference to *string* will still be discarded and the value of + *\*string* will be set to *NULL*; the appropriate exception will be set. + + +.. cfunction:: void PyString_ConcatAndDel(PyObject **string, PyObject *newpart) + + Create a new string object in *\*string* containing the contents of *newpart* + appended to *string*. This version decrements the reference count of *newpart*. + + +.. cfunction:: int _PyString_Resize(PyObject **string, Py_ssize_t newsize) + + A way to resize a string object even though it is "immutable". Only use this to + build up a brand new string object; don't use this if the string may already be + known in other parts of the code. It is an error to call this function if the + refcount on the input string object is not one. Pass the address of an existing + string object as an lvalue (it may be written into), and the new size desired. + On success, *\*string* holds the resized string object and ``0`` is returned; + the address in *\*string* may differ from its input value. If the reallocation + fails, the original string object at *\*string* is deallocated, *\*string* is + set to *NULL*, a memory exception is set, and ``-1`` is returned. + + +.. cfunction:: PyObject* PyString_Format(PyObject *format, PyObject *args) + + Return a new string object from *format* and *args*. Analogous to ``format % + args``. The *args* argument must be a tuple. + + +.. cfunction:: void PyString_InternInPlace(PyObject **string) + + Intern the argument *\*string* in place. The argument must be the address of a + pointer variable pointing to a Python string object. If there is an existing + interned string that is the same as *\*string*, it sets *\*string* to it + (decrementing the reference count of the old string object and incrementing the + reference count of the interned string object), otherwise it leaves *\*string* + alone and interns it (incrementing its reference count). (Clarification: even + though there is a lot of talk about reference counts, think of this function as + reference-count-neutral; you own the object after the call if and only if you + owned it before the call.) + + +.. cfunction:: PyObject* PyString_InternFromString(const char *v) + + A combination of :cfunc:`PyString_FromString` and + :cfunc:`PyString_InternInPlace`, returning either a new string object that has + been interned, or a new ("owned") reference to an earlier interned string object + with the same value. + + +.. cfunction:: PyObject* PyString_Decode(const char *s, Py_ssize_t size, const char *encoding, const char *errors) + + Create an object by decoding *size* bytes of the encoded buffer *s* using the + codec registered for *encoding*. *encoding* and *errors* have the same meaning + as the parameters of the same name in the :func:`unicode` built-in function. + The codec to be used is looked up using the Python codec registry. Return + *NULL* if an exception was raised by the codec. + + +.. cfunction:: PyObject* PyString_AsDecodedObject(PyObject *str, const char *encoding, const char *errors) + + Decode a string object by passing it to the codec registered for *encoding* and + return the result as Python object. *encoding* and *errors* have the same + meaning as the parameters of the same name in the string :meth:`encode` method. + The codec to be used is looked up using the Python codec registry. Return *NULL* + if an exception was raised by the codec. + + +.. cfunction:: PyObject* PyString_AsEncodedObject(PyObject *str, const char *encoding, const char *errors) + + Encode a string object using the codec registered for *encoding* and return the + result as Python object. *encoding* and *errors* have the same meaning as the + parameters of the same name in the string :meth:`encode` method. The codec to be + used is looked up using the Python codec registry. Return *NULL* if an exception + was raised by the codec. Added: python/branches/py3k/Doc/c-api/structures.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/structures.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,206 @@ +.. highlightlang:: c + +.. _common-structs: + +Common Object Structures +======================== + +There are a large number of structures which are used in the definition of +object types for Python. This section describes these structures and how they +are used. + +All Python objects ultimately share a small number of fields at the beginning of +the object's representation in memory. These are represented by the +:ctype:`PyObject` and :ctype:`PyVarObject` types, which are defined, in turn, by +the expansions of some macros also used, whether directly or indirectly, in the +definition of all other Python objects. + + +.. ctype:: PyObject + + All object types are extensions of this type. This is a type which contains the + information Python needs to treat a pointer to an object as an object. In a + normal "release" build, it contains only the objects reference count and a + pointer to the corresponding type object. It corresponds to the fields defined + by the expansion of the ``PyObject_HEAD`` macro. + + +.. ctype:: PyVarObject + + This is an extension of :ctype:`PyObject` that adds the :attr:`ob_size` field. + This is only used for objects that have some notion of *length*. This type does + not often appear in the Python/C API. It corresponds to the fields defined by + the expansion of the ``PyObject_VAR_HEAD`` macro. + +These macros are used in the definition of :ctype:`PyObject` and +:ctype:`PyVarObject`: + +.. XXX need to document PEP 3123 changes here + +.. cmacro:: PyObject_HEAD + + This is a macro which expands to the declarations of the fields of the + :ctype:`PyObject` type; it is used when declaring new types which represent + objects without a varying length. The specific fields it expands to depend on + the definition of :cmacro:`Py_TRACE_REFS`. By default, that macro is not + defined, and :cmacro:`PyObject_HEAD` expands to:: + + Py_ssize_t ob_refcnt; + PyTypeObject *ob_type; + + When :cmacro:`Py_TRACE_REFS` is defined, it expands to:: + + PyObject *_ob_next, *_ob_prev; + Py_ssize_t ob_refcnt; + PyTypeObject *ob_type; + + +.. cmacro:: PyObject_VAR_HEAD + + This is a macro which expands to the declarations of the fields of the + :ctype:`PyVarObject` type; it is used when declaring new types which represent + objects with a length that varies from instance to instance. This macro always + expands to:: + + PyObject_HEAD + Py_ssize_t ob_size; + + Note that :cmacro:`PyObject_HEAD` is part of the expansion, and that its own + expansion varies depending on the definition of :cmacro:`Py_TRACE_REFS`. + +.. cmacro:: PyObject_HEAD_INIT + + +.. ctype:: PyCFunction + + Type of the functions used to implement most Python callables in C. Functions of + this type take two :ctype:`PyObject\*` parameters and return one such value. If + the return value is *NULL*, an exception shall have been set. If not *NULL*, + the return value is interpreted as the return value of the function as exposed + in Python. The function must return a new reference. + + +.. ctype:: PyCFunctionWithKeywords + + Type of the functions used to implement Python callables in C that take + keyword arguments: they take three :ctype:`PyObject\*` parameters and return + one such value. See :ctype:`PyCFunction` above for the meaning of the return + value. + + +.. ctype:: PyMethodDef + + Structure used to describe a method of an extension type. This structure has + four fields: + + +------------------+-------------+-------------------------------+ + | Field | C Type | Meaning | + +==================+=============+===============================+ + | :attr:`ml_name` | char \* | name of the method | + +------------------+-------------+-------------------------------+ + | :attr:`ml_meth` | PyCFunction | pointer to the C | + | | | implementation | + +------------------+-------------+-------------------------------+ + | :attr:`ml_flags` | int | flag bits indicating how the | + | | | call should be constructed | + +------------------+-------------+-------------------------------+ + | :attr:`ml_doc` | char \* | points to the contents of the | + | | | docstring | + +------------------+-------------+-------------------------------+ + +The :attr:`ml_meth` is a C function pointer. The functions may be of different +types, but they always return :ctype:`PyObject\*`. If the function is not of +the :ctype:`PyCFunction`, the compiler will require a cast in the method table. +Even though :ctype:`PyCFunction` defines the first parameter as +:ctype:`PyObject\*`, it is common that the method implementation uses a the +specific C type of the *self* object. + +The :attr:`ml_flags` field is a bitfield which can include the following flags. +The individual flags indicate either a calling convention or a binding +convention. Of the calling convention flags, only :const:`METH_VARARGS` and +:const:`METH_KEYWORDS` can be combined (but note that :const:`METH_KEYWORDS` +alone is equivalent to ``METH_VARARGS | METH_KEYWORDS``). Any of the calling +convention flags can be combined with a binding flag. + + +.. data:: METH_VARARGS + + This is the typical calling convention, where the methods have the type + :ctype:`PyCFunction`. The function expects two :ctype:`PyObject\*` values. The + first one is the *self* object for methods; for module functions, it has the + value given to :cfunc:`Py_InitModule4` (or *NULL* if :cfunc:`Py_InitModule` was + used). The second parameter (often called *args*) is a tuple object + representing all arguments. This parameter is typically processed using + :cfunc:`PyArg_ParseTuple` or :cfunc:`PyArg_UnpackTuple`. + + +.. data:: METH_KEYWORDS + + Methods with these flags must be of type :ctype:`PyCFunctionWithKeywords`. The + function expects three parameters: *self*, *args*, and a dictionary of all the + keyword arguments. The flag is typically combined with :const:`METH_VARARGS`, + and the parameters are typically processed using + :cfunc:`PyArg_ParseTupleAndKeywords`. + + +.. data:: METH_NOARGS + + Methods without parameters don't need to check whether arguments are given if + they are listed with the :const:`METH_NOARGS` flag. They need to be of type + :ctype:`PyCFunction`. When used with object methods, the first parameter is + typically named ``self`` and will hold a reference to the object instance. In + all cases the second parameter will be *NULL*. + + +.. data:: METH_O + + Methods with a single object argument can be listed with the :const:`METH_O` + flag, instead of invoking :cfunc:`PyArg_ParseTuple` with a ``"O"`` argument. + They have the type :ctype:`PyCFunction`, with the *self* parameter, and a + :ctype:`PyObject\*` parameter representing the single argument. + + +These two constants are not used to indicate the calling convention but the +binding when use with methods of classes. These may not be used for functions +defined for modules. At most one of these flags may be set for any given +method. + + +.. data:: METH_CLASS + + .. index:: builtin: classmethod + + The method will be passed the type object as the first parameter rather than an + instance of the type. This is used to create *class methods*, similar to what + is created when using the :func:`classmethod` built-in function. + + +.. data:: METH_STATIC + + .. index:: builtin: staticmethod + + The method will be passed *NULL* as the first parameter rather than an instance + of the type. This is used to create *static methods*, similar to what is + created when using the :func:`staticmethod` built-in function. + +One other constant controls whether a method is loaded in place of another +definition with the same method name. + + +.. data:: METH_COEXIST + + The method will be loaded in place of existing definitions. Without + *METH_COEXIST*, the default is to skip repeated definitions. Since slot + wrappers are loaded before the method table, the existence of a *sq_contains* + slot, for example, would generate a wrapped method named :meth:`__contains__` + and preclude the loading of a corresponding PyCFunction with the same name. + With the flag defined, the PyCFunction will be loaded in place of the wrapper + object and will co-exist with the slot. This is helpful because calls to + PyCFunctions are optimized more than wrapper object calls. + + +.. cfunction:: PyObject* Py_FindMethod(PyMethodDef table[], PyObject *ob, char *name) + + Return a bound method object for an extension type implemented in C. This can + be useful in the implementation of a :attr:`tp_getattro` or :attr:`tp_getattr` + handler that does not use the :cfunc:`PyObject_GenericGetAttr` function. Added: python/branches/py3k/Doc/c-api/sys.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/sys.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,158 @@ +.. highlightlang:: c + +.. _os: + +Operating System Utilities +========================== + + +.. cfunction:: int Py_FdIsInteractive(FILE *fp, const char *filename) + + Return true (nonzero) if the standard I/O file *fp* with name *filename* is + deemed interactive. This is the case for files for which ``isatty(fileno(fp))`` + is true. If the global flag :cdata:`Py_InteractiveFlag` is true, this function + also returns true if the *filename* pointer is *NULL* or if the name is equal to + one of the strings ``''`` or ``'???'``. + + +.. cfunction:: long PyOS_GetLastModificationTime(char *filename) + + Return the time of last modification of the file *filename*. The result is + encoded in the same way as the timestamp returned by the standard C library + function :cfunc:`time`. + + +.. cfunction:: void PyOS_AfterFork() + + Function to update some internal state after a process fork; this should be + called in the new process if the Python interpreter will continue to be used. + If a new executable is loaded into the new process, this function does not need + to be called. + + +.. cfunction:: int PyOS_CheckStack() + + Return true when the interpreter runs out of stack space. This is a reliable + check, but is only available when :const:`USE_STACKCHECK` is defined (currently + on Windows using the Microsoft Visual C++ compiler). :const:`USE_STACKCHECK` + will be defined automatically; you should never change the definition in your + own code. + + +.. cfunction:: PyOS_sighandler_t PyOS_getsig(int i) + + Return the current signal handler for signal *i*. This is a thin wrapper around + either :cfunc:`sigaction` or :cfunc:`signal`. Do not call those functions + directly! :ctype:`PyOS_sighandler_t` is a typedef alias for :ctype:`void + (\*)(int)`. + + +.. cfunction:: PyOS_sighandler_t PyOS_setsig(int i, PyOS_sighandler_t h) + + Set the signal handler for signal *i* to be *h*; return the old signal handler. + This is a thin wrapper around either :cfunc:`sigaction` or :cfunc:`signal`. Do + not call those functions directly! :ctype:`PyOS_sighandler_t` is a typedef + alias for :ctype:`void (\*)(int)`. + +.. _systemfunctions: + +System Functions +================ + +These are utility functions that make functionality from the :mod:`sys` module +accessible to C code. They all work with the current interpreter thread's +:mod:`sys` module's dict, which is contained in the internal thread state structure. + +.. cfunction:: PyObject *PySys_GetObject(char *name) + + Return the object *name* from the :mod:`sys` module or *NULL* if it does + not exist, without setting an exception. + +.. cfunction:: FILE *PySys_GetFile(char *name, FILE *def) + + Return the :ctype:`FILE*` associated with the object *name* in the + :mod:`sys` module, or *def* if *name* is not in the module or is not associated + with a :ctype:`FILE*`. + +.. cfunction:: int PySys_SetObject(char *name, PyObject *v) + + Set *name* in the :mod:`sys` module to *v* unless *v* is *NULL*, in which + case *name* is deleted from the sys module. Returns ``0`` on success, ``-1`` + on error. + +.. cfunction:: void PySys_ResetWarnOptions(void) + + Reset :data:`sys.warnoptions` to an empty list. + +.. cfunction:: void PySys_AddWarnOption(char *s) + + Append *s* to :data:`sys.warnoptions`. + +.. cfunction:: void PySys_SetPath(char *path) + + Set :data:`sys.path` to a list object of paths found in *path* which should + be a list of paths separated with the platform's search path delimiter + (``:`` on Unix, ``;`` on Windows). + +.. cfunction:: void PySys_WriteStdout(const char *format, ...) + + Write the output string described by *format* to :data:`sys.stdout`. No + exceptions are raised, even if truncation occurs (see below). + + *format* should limit the total size of the formatted output string to + 1000 bytes or less -- after 1000 bytes, the output string is truncated. + In particular, this means that no unrestricted "%s" formats should occur; + these should be limited using "%.s" where is a decimal number + calculated so that plus the maximum size of other formatted text does not + exceed 1000 bytes. Also watch out for "%f", which can print hundreds of + digits for very large numbers. + + If a problem occurs, or :data:`sys.stdout` is unset, the formatted message + is written to the real (C level) *stdout*. + +.. cfunction:: void PySys_WriteStderr(const char *format, ...) + + As above, but write to :data:`sys.stderr` or *stderr* instead. + + +.. _processcontrol: + +Process Control +=============== + + +.. cfunction:: void Py_FatalError(const char *message) + + .. index:: single: abort() + + Print a fatal error message and kill the process. No cleanup is performed. + This function should only be invoked when a condition is detected that would + make it dangerous to continue using the Python interpreter; e.g., when the + object administration appears to be corrupted. On Unix, the standard C library + function :cfunc:`abort` is called which will attempt to produce a :file:`core` + file. + + +.. cfunction:: void Py_Exit(int status) + + .. index:: + single: Py_Finalize() + single: exit() + + Exit the current process. This calls :cfunc:`Py_Finalize` and then calls the + standard C library function ``exit(status)``. + + +.. cfunction:: int Py_AtExit(void (*func) ()) + + .. index:: + single: Py_Finalize() + single: cleanup functions + + Register a cleanup function to be called by :cfunc:`Py_Finalize`. The cleanup + function will be called with no arguments and should return no value. At most + 32 cleanup functions can be registered. When the registration is successful, + :cfunc:`Py_AtExit` returns ``0``; on failure, it returns ``-1``. The cleanup + function registered last is called first. Each cleanup function will be called + at most once. Since Python's internal finalization will have completed before + the cleanup function, no Python APIs should be called by *func*. Added: python/branches/py3k/Doc/c-api/tuple.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/tuple.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,107 @@ +.. highlightlang:: c + +.. _tupleobjects: + +Tuple Objects +------------- + +.. index:: object: tuple + + +.. ctype:: PyTupleObject + + This subtype of :ctype:`PyObject` represents a Python tuple object. + + +.. cvar:: PyTypeObject PyTuple_Type + + .. index:: single: TupleType (in module types) + + This instance of :ctype:`PyTypeObject` represents the Python tuple type; it is + the same object as ``tuple`` and ``types.TupleType`` in the Python layer.. + + +.. cfunction:: int PyTuple_Check(PyObject *p) + + Return true if *p* is a tuple object or an instance of a subtype of the tuple + type. + + +.. cfunction:: int PyTuple_CheckExact(PyObject *p) + + Return true if *p* is a tuple object, but not an instance of a subtype of the + tuple type. + + +.. cfunction:: PyObject* PyTuple_New(Py_ssize_t len) + + Return a new tuple object of size *len*, or *NULL* on failure. + + +.. cfunction:: PyObject* PyTuple_Pack(Py_ssize_t n, ...) + + Return a new tuple object of size *n*, or *NULL* on failure. The tuple values + are initialized to the subsequent *n* C arguments pointing to Python objects. + ``PyTuple_Pack(2, a, b)`` is equivalent to ``Py_BuildValue("(OO)", a, b)``. + + +.. cfunction:: Py_ssize_t PyTuple_Size(PyObject *p) + + Take a pointer to a tuple object, and return the size of that tuple. + + +.. cfunction:: Py_ssize_t PyTuple_GET_SIZE(PyObject *p) + + Return the size of the tuple *p*, which must be non-*NULL* and point to a tuple; + no error checking is performed. + + +.. cfunction:: PyObject* PyTuple_GetItem(PyObject *p, Py_ssize_t pos) + + Return the object at position *pos* in the tuple pointed to by *p*. If *pos* is + out of bounds, return *NULL* and sets an :exc:`IndexError` exception. + + +.. cfunction:: PyObject* PyTuple_GET_ITEM(PyObject *p, Py_ssize_t pos) + + Like :cfunc:`PyTuple_GetItem`, but does no checking of its arguments. + + +.. cfunction:: PyObject* PyTuple_GetSlice(PyObject *p, Py_ssize_t low, Py_ssize_t high) + + Take a slice of the tuple pointed to by *p* from *low* to *high* and return it + as a new tuple. + + +.. cfunction:: int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o) + + Insert a reference to object *o* at position *pos* of the tuple pointed to by + *p*. Return ``0`` on success. + + .. note:: + + This function "steals" a reference to *o*. + + +.. cfunction:: void PyTuple_SET_ITEM(PyObject *p, Py_ssize_t pos, PyObject *o) + + Like :cfunc:`PyTuple_SetItem`, but does no error checking, and should *only* be + used to fill in brand new tuples. + + .. note:: + + This function "steals" a reference to *o*. + + +.. cfunction:: int _PyTuple_Resize(PyObject **p, Py_ssize_t newsize) + + Can be used to resize a tuple. *newsize* will be the new length of the tuple. + Because tuples are *supposed* to be immutable, this should only be used if there + is only one reference to the object. Do *not* use this if the tuple may already + be known to some other part of the code. The tuple will always grow or shrink + at the end. Think of this as destroying the old tuple and creating a new one, + only more efficiently. Returns ``0`` on success. Client code should never + assume that the resulting value of ``*p`` will be the same as before calling + this function. If the object referenced by ``*p`` is replaced, the original + ``*p`` is destroyed. On failure, returns ``-1`` and sets ``*p`` to *NULL*, and + raises :exc:`MemoryError` or :exc:`SystemError`. Added: python/branches/py3k/Doc/c-api/type.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/type.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,68 @@ +.. highlightlang:: c + +.. _typeobjects: + +Type Objects +------------ + +.. index:: object: type + + +.. ctype:: PyTypeObject + + The C structure of the objects used to describe built-in types. + + +.. cvar:: PyObject* PyType_Type + + .. index:: single: TypeType (in module types) + + This is the type object for type objects; it is the same object as ``type`` and + ``types.TypeType`` in the Python layer. + + +.. cfunction:: int PyType_Check(PyObject *o) + + Return true if the object *o* is a type object, including instances of types + derived from the standard type object. Return false in all other cases. + + +.. cfunction:: int PyType_CheckExact(PyObject *o) + + Return true if the object *o* is a type object, but not a subtype of the + standard type object. Return false in all other cases. + + +.. cfunction:: int PyType_HasFeature(PyObject *o, int feature) + + Return true if the type object *o* sets the feature *feature*. Type features + are denoted by single bit flags. + + +.. cfunction:: int PyType_IS_GC(PyObject *o) + + Return true if the type object includes support for the cycle detector; this + tests the type flag :const:`Py_TPFLAGS_HAVE_GC`. + + +.. cfunction:: int PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b) + + Return true if *a* is a subtype of *b*. + + +.. cfunction:: PyObject* PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems) + + XXX: Document. + + +.. cfunction:: PyObject* PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds) + + XXX: Document. + + +.. cfunction:: int PyType_Ready(PyTypeObject *type) + + Finalize a type object. This should be called on all type objects to finish + their initialization. This function is responsible for adding inherited slots + from a type's base class. Return ``0`` on success, or return ``-1`` and sets an + exception on error. Added: python/branches/py3k/Doc/c-api/typeobj.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/typeobj.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,1391 @@ +.. highlightlang:: c + +.. _type-structs: + +Type Objects +============ + +Perhaps one of the most important structures of the Python object system is the +structure that defines a new type: the :ctype:`PyTypeObject` structure. Type +objects can be handled using any of the :cfunc:`PyObject_\*` or +:cfunc:`PyType_\*` functions, but do not offer much that's interesting to most +Python applications. These objects are fundamental to how objects behave, so +they are very important to the interpreter itself and to any extension module +that implements new types. + +Type objects are fairly large compared to most of the standard types. The reason +for the size is that each type object stores a large number of values, mostly C +function pointers, each of which implements a small part of the type's +functionality. The fields of the type object are examined in detail in this +section. The fields will be described in the order in which they occur in the +structure. + +Typedefs: unaryfunc, binaryfunc, ternaryfunc, inquiry, intargfunc, +intintargfunc, intobjargproc, intintobjargproc, objobjargproc, destructor, +freefunc, printfunc, getattrfunc, getattrofunc, setattrfunc, setattrofunc, +cmpfunc, reprfunc, hashfunc + +The structure definition for :ctype:`PyTypeObject` can be found in +:file:`Include/object.h`. For convenience of reference, this repeats the +definition found there: + +.. literalinclude:: ../includes/typestruct.h + + +The type object structure extends the :ctype:`PyVarObject` structure. The +:attr:`ob_size` field is used for dynamic types (created by :func:`type_new`, +usually called from a class statement). Note that :cdata:`PyType_Type` (the +metatype) initializes :attr:`tp_itemsize`, which means that its instances (i.e. +type objects) *must* have the :attr:`ob_size` field. + + +.. cmember:: PyObject* PyObject._ob_next + PyObject* PyObject._ob_prev + + These fields are only present when the macro ``Py_TRACE_REFS`` is defined. + Their initialization to *NULL* is taken care of by the ``PyObject_HEAD_INIT`` + macro. For statically allocated objects, these fields always remain *NULL*. + For dynamically allocated objects, these two fields are used to link the object + into a doubly-linked list of *all* live objects on the heap. This could be used + for various debugging purposes; currently the only use is to print the objects + that are still alive at the end of a run when the environment variable + :envvar:`PYTHONDUMPREFS` is set. + + These fields are not inherited by subtypes. + + +.. cmember:: Py_ssize_t PyObject.ob_refcnt + + This is the type object's reference count, initialized to ``1`` by the + ``PyObject_HEAD_INIT`` macro. Note that for statically allocated type objects, + the type's instances (objects whose :attr:`ob_type` points back to the type) do + *not* count as references. But for dynamically allocated type objects, the + instances *do* count as references. + + This field is not inherited by subtypes. + + +.. cmember:: PyTypeObject* PyObject.ob_type + + This is the type's type, in other words its metatype. It is initialized by the + argument to the ``PyObject_HEAD_INIT`` macro, and its value should normally be + ``&PyType_Type``. However, for dynamically loadable extension modules that must + be usable on Windows (at least), the compiler complains that this is not a valid + initializer. Therefore, the convention is to pass *NULL* to the + ``PyObject_HEAD_INIT`` macro and to initialize this field explicitly at the + start of the module's initialization function, before doing anything else. This + is typically done like this:: + + Foo_Type.ob_type = &PyType_Type; + + This should be done before any instances of the type are created. + :cfunc:`PyType_Ready` checks if :attr:`ob_type` is *NULL*, and if so, + initializes it: in Python 2.2, it is set to ``&PyType_Type``; in Python 2.2.1 + and later it is initialized to the :attr:`ob_type` field of the base class. + :cfunc:`PyType_Ready` will not change this field if it is non-zero. + + In Python 2.2, this field is not inherited by subtypes. In 2.2.1, and in 2.3 + and beyond, it is inherited by subtypes. + + +.. cmember:: Py_ssize_t PyVarObject.ob_size + + For statically allocated type objects, this should be initialized to zero. For + dynamically allocated type objects, this field has a special internal meaning. + + This field is not inherited by subtypes. + + +.. cmember:: char* PyTypeObject.tp_name + + Pointer to a NUL-terminated string containing the name of the type. For types + that are accessible as module globals, the string should be the full module + name, followed by a dot, followed by the type name; for built-in types, it + should be just the type name. If the module is a submodule of a package, the + full package name is part of the full module name. For example, a type named + :class:`T` defined in module :mod:`M` in subpackage :mod:`Q` in package :mod:`P` + should have the :attr:`tp_name` initializer ``"P.Q.M.T"``. + + For dynamically allocated type objects, this should just be the type name, and + the module name explicitly stored in the type dict as the value for key + ``'__module__'``. + + For statically allocated type objects, the tp_name field should contain a dot. + Everything before the last dot is made accessible as the :attr:`__module__` + attribute, and everything after the last dot is made accessible as the + :attr:`__name__` attribute. + + If no dot is present, the entire :attr:`tp_name` field is made accessible as the + :attr:`__name__` attribute, and the :attr:`__module__` attribute is undefined + (unless explicitly set in the dictionary, as explained above). This means your + type will be impossible to pickle. + + This field is not inherited by subtypes. + + +.. cmember:: Py_ssize_t PyTypeObject.tp_basicsize + Py_ssize_t PyTypeObject.tp_itemsize + + These fields allow calculating the size in bytes of instances of the type. + + There are two kinds of types: types with fixed-length instances have a zero + :attr:`tp_itemsize` field, types with variable-length instances have a non-zero + :attr:`tp_itemsize` field. For a type with fixed-length instances, all + instances have the same size, given in :attr:`tp_basicsize`. + + For a type with variable-length instances, the instances must have an + :attr:`ob_size` field, and the instance size is :attr:`tp_basicsize` plus N + times :attr:`tp_itemsize`, where N is the "length" of the object. The value of + N is typically stored in the instance's :attr:`ob_size` field. There are + exceptions: for example, long ints use a negative :attr:`ob_size` to indicate a + negative number, and N is ``abs(ob_size)`` there. Also, the presence of an + :attr:`ob_size` field in the instance layout doesn't mean that the instance + structure is variable-length (for example, the structure for the list type has + fixed-length instances, yet those instances have a meaningful :attr:`ob_size` + field). + + The basic size includes the fields in the instance declared by the macro + :cmacro:`PyObject_HEAD` or :cmacro:`PyObject_VAR_HEAD` (whichever is used to + declare the instance struct) and this in turn includes the :attr:`_ob_prev` and + :attr:`_ob_next` fields if they are present. This means that the only correct + way to get an initializer for the :attr:`tp_basicsize` is to use the + ``sizeof`` operator on the struct used to declare the instance layout. + The basic size does not include the GC header size (this is new in Python 2.2; + in 2.1 and 2.0, the GC header size was included in :attr:`tp_basicsize`). + + These fields are inherited separately by subtypes. If the base type has a + non-zero :attr:`tp_itemsize`, it is generally not safe to set + :attr:`tp_itemsize` to a different non-zero value in a subtype (though this + depends on the implementation of the base type). + + A note about alignment: if the variable items require a particular alignment, + this should be taken care of by the value of :attr:`tp_basicsize`. Example: + suppose a type implements an array of ``double``. :attr:`tp_itemsize` is + ``sizeof(double)``. It is the programmer's responsibility that + :attr:`tp_basicsize` is a multiple of ``sizeof(double)`` (assuming this is the + alignment requirement for ``double``). + + +.. cmember:: destructor PyTypeObject.tp_dealloc + + A pointer to the instance destructor function. This function must be defined + unless the type guarantees that its instances will never be deallocated (as is + the case for the singletons ``None`` and ``Ellipsis``). + + The destructor function is called by the :cfunc:`Py_DECREF` and + :cfunc:`Py_XDECREF` macros when the new reference count is zero. At this point, + the instance is still in existence, but there are no references to it. The + destructor function should free all references which the instance owns, free all + memory buffers owned by the instance (using the freeing function corresponding + to the allocation function used to allocate the buffer), and finally (as its + last action) call the type's :attr:`tp_free` function. If the type is not + subtypable (doesn't have the :const:`Py_TPFLAGS_BASETYPE` flag bit set), it is + permissible to call the object deallocator directly instead of via + :attr:`tp_free`. The object deallocator should be the one used to allocate the + instance; this is normally :cfunc:`PyObject_Del` if the instance was allocated + using :cfunc:`PyObject_New` or :cfunc:`PyObject_VarNew`, or + :cfunc:`PyObject_GC_Del` if the instance was allocated using + :cfunc:`PyObject_GC_New` or :cfunc:`PyObject_GC_VarNew`. + + This field is inherited by subtypes. + + +.. cmember:: printfunc PyTypeObject.tp_print + + An optional pointer to the instance print function. + + The print function is only called when the instance is printed to a *real* file; + when it is printed to a pseudo-file (like a :class:`StringIO` instance), the + instance's :attr:`tp_repr` or :attr:`tp_str` function is called to convert it to + a string. These are also called when the type's :attr:`tp_print` field is + *NULL*. A type should never implement :attr:`tp_print` in a way that produces + different output than :attr:`tp_repr` or :attr:`tp_str` would. + + The print function is called with the same signature as :cfunc:`PyObject_Print`: + ``int tp_print(PyObject *self, FILE *file, int flags)``. The *self* argument is + the instance to be printed. The *file* argument is the stdio file to which it + is to be printed. The *flags* argument is composed of flag bits. The only flag + bit currently defined is :const:`Py_PRINT_RAW`. When the :const:`Py_PRINT_RAW` + flag bit is set, the instance should be printed the same way as :attr:`tp_str` + would format it; when the :const:`Py_PRINT_RAW` flag bit is clear, the instance + should be printed the same was as :attr:`tp_repr` would format it. It should + return ``-1`` and set an exception condition when an error occurred during the + comparison. + + It is possible that the :attr:`tp_print` field will be deprecated. In any case, + it is recommended not to define :attr:`tp_print`, but instead to rely on + :attr:`tp_repr` and :attr:`tp_str` for printing. + + This field is inherited by subtypes. + + +.. cmember:: getattrfunc PyTypeObject.tp_getattr + + An optional pointer to the get-attribute-string function. + + This field is deprecated. When it is defined, it should point to a function + that acts the same as the :attr:`tp_getattro` function, but taking a C string + instead of a Python string object to give the attribute name. The signature is + the same as for :cfunc:`PyObject_GetAttrString`. + + This field is inherited by subtypes together with :attr:`tp_getattro`: a subtype + inherits both :attr:`tp_getattr` and :attr:`tp_getattro` from its base type when + the subtype's :attr:`tp_getattr` and :attr:`tp_getattro` are both *NULL*. + + +.. cmember:: setattrfunc PyTypeObject.tp_setattr + + An optional pointer to the set-attribute-string function. + + This field is deprecated. When it is defined, it should point to a function + that acts the same as the :attr:`tp_setattro` function, but taking a C string + instead of a Python string object to give the attribute name. The signature is + the same as for :cfunc:`PyObject_SetAttrString`. + + This field is inherited by subtypes together with :attr:`tp_setattro`: a subtype + inherits both :attr:`tp_setattr` and :attr:`tp_setattro` from its base type when + the subtype's :attr:`tp_setattr` and :attr:`tp_setattro` are both *NULL*. + + +.. cmember:: cmpfunc PyTypeObject.tp_compare + + An optional pointer to the three-way comparison function. + + The signature is the same as for :cfunc:`PyObject_Compare`. The function should + return ``1`` if *self* greater than *other*, ``0`` if *self* is equal to + *other*, and ``-1`` if *self* less than *other*. It should return ``-1`` and + set an exception condition when an error occurred during the comparison. + + This field is inherited by subtypes together with :attr:`tp_richcompare` and + :attr:`tp_hash`: a subtypes inherits all three of :attr:`tp_compare`, + :attr:`tp_richcompare`, and :attr:`tp_hash` when the subtype's + :attr:`tp_compare`, :attr:`tp_richcompare`, and :attr:`tp_hash` are all *NULL*. + + +.. cmember:: reprfunc PyTypeObject.tp_repr + + .. index:: builtin: repr + + An optional pointer to a function that implements the built-in function + :func:`repr`. + + The signature is the same as for :cfunc:`PyObject_Repr`; it must return a string + or a Unicode object. Ideally, this function should return a string that, when + passed to :func:`eval`, given a suitable environment, returns an object with the + same value. If this is not feasible, it should return a string starting with + ``'<'`` and ending with ``'>'`` from which both the type and the value of the + object can be deduced. + + When this field is not set, a string of the form ``<%s object at %p>`` is + returned, where ``%s`` is replaced by the type name, and ``%p`` by the object's + memory address. + + This field is inherited by subtypes. + +.. cmember:: PyNumberMethods* tp_as_number + + Pointer to an additional structure that contains fields relevant only to + objects which implement the number protocol. These fields are documented in + :ref:`number-structs`. + + The :attr:`tp_as_number` field is not inherited, but the contained fields are + inherited individually. + + +.. cmember:: PySequenceMethods* tp_as_sequence + + Pointer to an additional structure that contains fields relevant only to + objects which implement the sequence protocol. These fields are documented + in :ref:`sequence-structs`. + + The :attr:`tp_as_sequence` field is not inherited, but the contained fields + are inherited individually. + + +.. cmember:: PyMappingMethods* tp_as_mapping + + Pointer to an additional structure that contains fields relevant only to + objects which implement the mapping protocol. These fields are documented in + :ref:`mapping-structs`. + + The :attr:`tp_as_mapping` field is not inherited, but the contained fields + are inherited individually. + + +.. cmember:: hashfunc PyTypeObject.tp_hash + + .. index:: builtin: hash + + An optional pointer to a function that implements the built-in function + :func:`hash`. + + The signature is the same as for :cfunc:`PyObject_Hash`; it must return a C + long. The value ``-1`` should not be returned as a normal return value; when an + error occurs during the computation of the hash value, the function should set + an exception and return ``-1``. + + When this field is not set, two possibilities exist: if the :attr:`tp_compare` + and :attr:`tp_richcompare` fields are both *NULL*, a default hash value based on + the object's address is returned; otherwise, a :exc:`TypeError` is raised. + + This field is inherited by subtypes together with :attr:`tp_richcompare` and + :attr:`tp_compare`: a subtypes inherits all three of :attr:`tp_compare`, + :attr:`tp_richcompare`, and :attr:`tp_hash`, when the subtype's + :attr:`tp_compare`, :attr:`tp_richcompare` and :attr:`tp_hash` are all *NULL*. + + +.. cmember:: ternaryfunc PyTypeObject.tp_call + + An optional pointer to a function that implements calling the object. This + should be *NULL* if the object is not callable. The signature is the same as + for :cfunc:`PyObject_Call`. + + This field is inherited by subtypes. + + +.. cmember:: reprfunc PyTypeObject.tp_str + + An optional pointer to a function that implements the built-in operation + :func:`str`. (Note that :class:`str` is a type now, and :func:`str` calls the + constructor for that type. This constructor calls :cfunc:`PyObject_Str` to do + the actual work, and :cfunc:`PyObject_Str` will call this handler.) + + The signature is the same as for :cfunc:`PyObject_Str`; it must return a string + or a Unicode object. This function should return a "friendly" string + representation of the object, as this is the representation that will be used, + among other things, by the :func:`print` function. + + When this field is not set, :cfunc:`PyObject_Repr` is called to return a string + representation. + + This field is inherited by subtypes. + + +.. cmember:: getattrofunc PyTypeObject.tp_getattro + + An optional pointer to the get-attribute function. + + The signature is the same as for :cfunc:`PyObject_GetAttr`. It is usually + convenient to set this field to :cfunc:`PyObject_GenericGetAttr`, which + implements the normal way of looking for object attributes. + + This field is inherited by subtypes together with :attr:`tp_getattr`: a subtype + inherits both :attr:`tp_getattr` and :attr:`tp_getattro` from its base type when + the subtype's :attr:`tp_getattr` and :attr:`tp_getattro` are both *NULL*. + + +.. cmember:: setattrofunc PyTypeObject.tp_setattro + + An optional pointer to the set-attribute function. + + The signature is the same as for :cfunc:`PyObject_SetAttr`. It is usually + convenient to set this field to :cfunc:`PyObject_GenericSetAttr`, which + implements the normal way of setting object attributes. + + This field is inherited by subtypes together with :attr:`tp_setattr`: a subtype + inherits both :attr:`tp_setattr` and :attr:`tp_setattro` from its base type when + the subtype's :attr:`tp_setattr` and :attr:`tp_setattro` are both *NULL*. + + +.. cmember:: PyBufferProcs* PyTypeObject.tp_as_buffer + + Pointer to an additional structure that contains fields relevant only to objects + which implement the buffer interface. These fields are documented in + :ref:`buffer-structs`. + + The :attr:`tp_as_buffer` field is not inherited, but the contained fields are + inherited individually. + + +.. cmember:: long PyTypeObject.tp_flags + + This field is a bit mask of various flags. Some flags indicate variant + semantics for certain situations; others are used to indicate that certain + fields in the type object (or in the extension structures referenced via + :attr:`tp_as_number`, :attr:`tp_as_sequence`, :attr:`tp_as_mapping`, and + :attr:`tp_as_buffer`) that were historically not always present are valid; if + such a flag bit is clear, the type fields it guards must not be accessed and + must be considered to have a zero or *NULL* value instead. + + Inheritance of this field is complicated. Most flag bits are inherited + individually, i.e. if the base type has a flag bit set, the subtype inherits + this flag bit. The flag bits that pertain to extension structures are strictly + inherited if the extension structure is inherited, i.e. the base type's value of + the flag bit is copied into the subtype together with a pointer to the extension + structure. The :const:`Py_TPFLAGS_HAVE_GC` flag bit is inherited together with + the :attr:`tp_traverse` and :attr:`tp_clear` fields, i.e. if the + :const:`Py_TPFLAGS_HAVE_GC` flag bit is clear in the subtype and the + :attr:`tp_traverse` and :attr:`tp_clear` fields in the subtype exist (as + indicated by the :const:`Py_TPFLAGS_HAVE_RICHCOMPARE` flag bit) and have *NULL* + values. + + The following bit masks are currently defined; these can be ORed together using + the ``|`` operator to form the value of the :attr:`tp_flags` field. The macro + :cfunc:`PyType_HasFeature` takes a type and a flags value, *tp* and *f*, and + checks whether ``tp->tp_flags & f`` is non-zero. + + + .. data:: Py_TPFLAGS_HAVE_GETCHARBUFFER + + If this bit is set, the :ctype:`PyBufferProcs` struct referenced by + :attr:`tp_as_buffer` has the :attr:`bf_getcharbuffer` field. + + + .. data:: Py_TPFLAGS_HAVE_SEQUENCE_IN + + If this bit is set, the :ctype:`PySequenceMethods` struct referenced by + :attr:`tp_as_sequence` has the :attr:`sq_contains` field. + + + .. data:: Py_TPFLAGS_GC + + This bit is obsolete. The bit it used to name is no longer in use. The symbol + is now defined as zero. + + + .. data:: Py_TPFLAGS_HAVE_INPLACEOPS + + If this bit is set, the :ctype:`PySequenceMethods` struct referenced by + :attr:`tp_as_sequence` and the :ctype:`PyNumberMethods` structure referenced by + :attr:`tp_as_number` contain the fields for in-place operators. In particular, + this means that the :ctype:`PyNumberMethods` structure has the fields + :attr:`nb_inplace_add`, :attr:`nb_inplace_subtract`, + :attr:`nb_inplace_multiply`, :attr:`nb_inplace_divide`, + :attr:`nb_inplace_remainder`, :attr:`nb_inplace_power`, + :attr:`nb_inplace_lshift`, :attr:`nb_inplace_rshift`, :attr:`nb_inplace_and`, + :attr:`nb_inplace_xor`, and :attr:`nb_inplace_or`; and the + :ctype:`PySequenceMethods` struct has the fields :attr:`sq_inplace_concat` and + :attr:`sq_inplace_repeat`. + + + .. data:: Py_TPFLAGS_HAVE_RICHCOMPARE + + If this bit is set, the type object has the :attr:`tp_richcompare` field, as + well as the :attr:`tp_traverse` and the :attr:`tp_clear` fields. + + + .. data:: Py_TPFLAGS_HAVE_WEAKREFS + + If this bit is set, the :attr:`tp_weaklistoffset` field is defined. Instances + of a type are weakly referenceable if the type's :attr:`tp_weaklistoffset` field + has a value greater than zero. + + + .. data:: Py_TPFLAGS_HAVE_ITER + + If this bit is set, the type object has the :attr:`tp_iter` and + :attr:`tp_iternext` fields. + + + .. data:: Py_TPFLAGS_HAVE_CLASS + + If this bit is set, the type object has several new fields defined starting in + Python 2.2: :attr:`tp_methods`, :attr:`tp_members`, :attr:`tp_getset`, + :attr:`tp_base`, :attr:`tp_dict`, :attr:`tp_descr_get`, :attr:`tp_descr_set`, + :attr:`tp_dictoffset`, :attr:`tp_init`, :attr:`tp_alloc`, :attr:`tp_new`, + :attr:`tp_free`, :attr:`tp_is_gc`, :attr:`tp_bases`, :attr:`tp_mro`, + :attr:`tp_cache`, :attr:`tp_subclasses`, and :attr:`tp_weaklist`. + + + .. data:: Py_TPFLAGS_HEAPTYPE + + This bit is set when the type object itself is allocated on the heap. In this + case, the :attr:`ob_type` field of its instances is considered a reference to + the type, and the type object is INCREF'ed when a new instance is created, and + DECREF'ed when an instance is destroyed (this does not apply to instances of + subtypes; only the type referenced by the instance's ob_type gets INCREF'ed or + DECREF'ed). + + + .. data:: Py_TPFLAGS_BASETYPE + + This bit is set when the type can be used as the base type of another type. If + this bit is clear, the type cannot be subtyped (similar to a "final" class in + Java). + + + .. data:: Py_TPFLAGS_READY + + This bit is set when the type object has been fully initialized by + :cfunc:`PyType_Ready`. + + + .. data:: Py_TPFLAGS_READYING + + This bit is set while :cfunc:`PyType_Ready` is in the process of initializing + the type object. + + + .. data:: Py_TPFLAGS_HAVE_GC + + This bit is set when the object supports garbage collection. If this bit + is set, instances must be created using :cfunc:`PyObject_GC_New` and + destroyed using :cfunc:`PyObject_GC_Del`. More information in section + :ref:`supporting-cycle-detection`. This bit also implies that the + GC-related fields :attr:`tp_traverse` and :attr:`tp_clear` are present in + the type object; but those fields also exist when + :const:`Py_TPFLAGS_HAVE_GC` is clear but + :const:`Py_TPFLAGS_HAVE_RICHCOMPARE` is set. + + + .. data:: Py_TPFLAGS_DEFAULT + + This is a bitmask of all the bits that pertain to the existence of certain + fields in the type object and its extension structures. Currently, it includes + the following bits: :const:`Py_TPFLAGS_HAVE_GETCHARBUFFER`, + :const:`Py_TPFLAGS_HAVE_SEQUENCE_IN`, :const:`Py_TPFLAGS_HAVE_INPLACEOPS`, + :const:`Py_TPFLAGS_HAVE_RICHCOMPARE`, :const:`Py_TPFLAGS_HAVE_WEAKREFS`, + :const:`Py_TPFLAGS_HAVE_ITER`, and :const:`Py_TPFLAGS_HAVE_CLASS`. + + +.. cmember:: char* PyTypeObject.tp_doc + + An optional pointer to a NUL-terminated C string giving the docstring for this + type object. This is exposed as the :attr:`__doc__` attribute on the type and + instances of the type. + + This field is *not* inherited by subtypes. + +The following three fields only exist if the +:const:`Py_TPFLAGS_HAVE_RICHCOMPARE` flag bit is set. + + +.. cmember:: traverseproc PyTypeObject.tp_traverse + + An optional pointer to a traversal function for the garbage collector. This is + only used if the :const:`Py_TPFLAGS_HAVE_GC` flag bit is set. More information + about Python's garbage collection scheme can be found in section + :ref:`supporting-cycle-detection`. + + The :attr:`tp_traverse` pointer is used by the garbage collector to detect + reference cycles. A typical implementation of a :attr:`tp_traverse` function + simply calls :cfunc:`Py_VISIT` on each of the instance's members that are Python + objects. For exampe, this is function :cfunc:`local_traverse` from the + :mod:`thread` extension module:: + + static int + local_traverse(localobject *self, visitproc visit, void *arg) + { + Py_VISIT(self->args); + Py_VISIT(self->kw); + Py_VISIT(self->dict); + return 0; + } + + Note that :cfunc:`Py_VISIT` is called only on those members that can participate + in reference cycles. Although there is also a ``self->key`` member, it can only + be *NULL* or a Python string and therefore cannot be part of a reference cycle. + + On the other hand, even if you know a member can never be part of a cycle, as a + debugging aid you may want to visit it anyway just so the :mod:`gc` module's + :func:`get_referents` function will include it. + + Note that :cfunc:`Py_VISIT` requires the *visit* and *arg* parameters to + :cfunc:`local_traverse` to have these specific names; don't name them just + anything. + + This field is inherited by subtypes together with :attr:`tp_clear` and the + :const:`Py_TPFLAGS_HAVE_GC` flag bit: the flag bit, :attr:`tp_traverse`, and + :attr:`tp_clear` are all inherited from the base type if they are all zero in + the subtype *and* the subtype has the :const:`Py_TPFLAGS_HAVE_RICHCOMPARE` flag + bit set. + + +.. cmember:: inquiry PyTypeObject.tp_clear + + An optional pointer to a clear function for the garbage collector. This is only + used if the :const:`Py_TPFLAGS_HAVE_GC` flag bit is set. + + The :attr:`tp_clear` member function is used to break reference cycles in cyclic + garbage detected by the garbage collector. Taken together, all :attr:`tp_clear` + functions in the system must combine to break all reference cycles. This is + subtle, and if in any doubt supply a :attr:`tp_clear` function. For example, + the tuple type does not implement a :attr:`tp_clear` function, because it's + possible to prove that no reference cycle can be composed entirely of tuples. + Therefore the :attr:`tp_clear` functions of other types must be sufficient to + break any cycle containing a tuple. This isn't immediately obvious, and there's + rarely a good reason to avoid implementing :attr:`tp_clear`. + + Implementations of :attr:`tp_clear` should drop the instance's references to + those of its members that may be Python objects, and set its pointers to those + members to *NULL*, as in the following example:: + + static int + local_clear(localobject *self) + { + Py_CLEAR(self->key); + Py_CLEAR(self->args); + Py_CLEAR(self->kw); + Py_CLEAR(self->dict); + return 0; + } + + The :cfunc:`Py_CLEAR` macro should be used, because clearing references is + delicate: the reference to the contained object must not be decremented until + after the pointer to the contained object is set to *NULL*. This is because + decrementing the reference count may cause the contained object to become trash, + triggering a chain of reclamation activity that may include invoking arbitrary + Python code (due to finalizers, or weakref callbacks, associated with the + contained object). If it's possible for such code to reference *self* again, + it's important that the pointer to the contained object be *NULL* at that time, + so that *self* knows the contained object can no longer be used. The + :cfunc:`Py_CLEAR` macro performs the operations in a safe order. + + Because the goal of :attr:`tp_clear` functions is to break reference cycles, + it's not necessary to clear contained objects like Python strings or Python + integers, which can't participate in reference cycles. On the other hand, it may + be convenient to clear all contained Python objects, and write the type's + :attr:`tp_dealloc` function to invoke :attr:`tp_clear`. + + More information about Python's garbage collection scheme can be found in + section :ref:`supporting-cycle-detection`. + + This field is inherited by subtypes together with :attr:`tp_traverse` and the + :const:`Py_TPFLAGS_HAVE_GC` flag bit: the flag bit, :attr:`tp_traverse`, and + :attr:`tp_clear` are all inherited from the base type if they are all zero in + the subtype *and* the subtype has the :const:`Py_TPFLAGS_HAVE_RICHCOMPARE` flag + bit set. + + +.. cmember:: richcmpfunc PyTypeObject.tp_richcompare + + An optional pointer to the rich comparison function. + + The signature is the same as for :cfunc:`PyObject_RichCompare`. The function + should return the result of the comparison (usually ``Py_True`` or + ``Py_False``). If the comparison is undefined, it must return + ``Py_NotImplemented``, if another error occurred it must return ``NULL`` and set + an exception condition. + + This field is inherited by subtypes together with :attr:`tp_compare` and + :attr:`tp_hash`: a subtype inherits all three of :attr:`tp_compare`, + :attr:`tp_richcompare`, and :attr:`tp_hash`, when the subtype's + :attr:`tp_compare`, :attr:`tp_richcompare`, and :attr:`tp_hash` are all *NULL*. + + The following constants are defined to be used as the third argument for + :attr:`tp_richcompare` and for :cfunc:`PyObject_RichCompare`: + + +----------------+------------+ + | Constant | Comparison | + +================+============+ + | :const:`Py_LT` | ``<`` | + +----------------+------------+ + | :const:`Py_LE` | ``<=`` | + +----------------+------------+ + | :const:`Py_EQ` | ``==`` | + +----------------+------------+ + | :const:`Py_NE` | ``!=`` | + +----------------+------------+ + | :const:`Py_GT` | ``>`` | + +----------------+------------+ + | :const:`Py_GE` | ``>=`` | + +----------------+------------+ + +The next field only exists if the :const:`Py_TPFLAGS_HAVE_WEAKREFS` flag bit is +set. + + +.. cmember:: long PyTypeObject.tp_weaklistoffset + + If the instances of this type are weakly referenceable, this field is greater + than zero and contains the offset in the instance structure of the weak + reference list head (ignoring the GC header, if present); this offset is used by + :cfunc:`PyObject_ClearWeakRefs` and the :cfunc:`PyWeakref_\*` functions. The + instance structure needs to include a field of type :ctype:`PyObject\*` which is + initialized to *NULL*. + + Do not confuse this field with :attr:`tp_weaklist`; that is the list head for + weak references to the type object itself. + + This field is inherited by subtypes, but see the rules listed below. A subtype + may override this offset; this means that the subtype uses a different weak + reference list head than the base type. Since the list head is always found via + :attr:`tp_weaklistoffset`, this should not be a problem. + + When a type defined by a class statement has no :attr:`__slots__` declaration, + and none of its base types are weakly referenceable, the type is made weakly + referenceable by adding a weak reference list head slot to the instance layout + and setting the :attr:`tp_weaklistoffset` of that slot's offset. + + When a type's :attr:`__slots__` declaration contains a slot named + :attr:`__weakref__`, that slot becomes the weak reference list head for + instances of the type, and the slot's offset is stored in the type's + :attr:`tp_weaklistoffset`. + + When a type's :attr:`__slots__` declaration does not contain a slot named + :attr:`__weakref__`, the type inherits its :attr:`tp_weaklistoffset` from its + base type. + +The next two fields only exist if the :const:`Py_TPFLAGS_HAVE_CLASS` flag bit is +set. + + +.. cmember:: getiterfunc PyTypeObject.tp_iter + + An optional pointer to a function that returns an iterator for the object. Its + presence normally signals that the instances of this type are iterable (although + sequences may be iterable without this function, and classic instances always + have this function, even if they don't define an :meth:`__iter__` method). + + This function has the same signature as :cfunc:`PyObject_GetIter`. + + This field is inherited by subtypes. + + +.. cmember:: iternextfunc PyTypeObject.tp_iternext + + An optional pointer to a function that returns the next item in an iterator, or + raises :exc:`StopIteration` when the iterator is exhausted. Its presence + normally signals that the instances of this type are iterators (although classic + instances always have this function, even if they don't define a + :meth:`__next__` method). + + Iterator types should also define the :attr:`tp_iter` function, and that + function should return the iterator instance itself (not a new iterator + instance). + + This function has the same signature as :cfunc:`PyIter_Next`. + + This field is inherited by subtypes. + +The next fields, up to and including :attr:`tp_weaklist`, only exist if the +:const:`Py_TPFLAGS_HAVE_CLASS` flag bit is set. + + +.. cmember:: struct PyMethodDef* PyTypeObject.tp_methods + + An optional pointer to a static *NULL*-terminated array of :ctype:`PyMethodDef` + structures, declaring regular methods of this type. + + For each entry in the array, an entry is added to the type's dictionary (see + :attr:`tp_dict` below) containing a method descriptor. + + This field is not inherited by subtypes (methods are inherited through a + different mechanism). + + +.. cmember:: struct PyMemberDef* PyTypeObject.tp_members + + An optional pointer to a static *NULL*-terminated array of :ctype:`PyMemberDef` + structures, declaring regular data members (fields or slots) of instances of + this type. + + For each entry in the array, an entry is added to the type's dictionary (see + :attr:`tp_dict` below) containing a member descriptor. + + This field is not inherited by subtypes (members are inherited through a + different mechanism). + + +.. cmember:: struct PyGetSetDef* PyTypeObject.tp_getset + + An optional pointer to a static *NULL*-terminated array of :ctype:`PyGetSetDef` + structures, declaring computed attributes of instances of this type. + + For each entry in the array, an entry is added to the type's dictionary (see + :attr:`tp_dict` below) containing a getset descriptor. + + This field is not inherited by subtypes (computed attributes are inherited + through a different mechanism). + + Docs for PyGetSetDef (XXX belong elsewhere):: + + typedef PyObject *(*getter)(PyObject *, void *); + typedef int (*setter)(PyObject *, PyObject *, void *); + + typedef struct PyGetSetDef { + char *name; /* attribute name */ + getter get; /* C function to get the attribute */ + setter set; /* C function to set the attribute */ + char *doc; /* optional doc string */ + void *closure; /* optional additional data for getter and setter */ + } PyGetSetDef; + + +.. cmember:: PyTypeObject* PyTypeObject.tp_base + + An optional pointer to a base type from which type properties are inherited. At + this level, only single inheritance is supported; multiple inheritance require + dynamically creating a type object by calling the metatype. + + This field is not inherited by subtypes (obviously), but it defaults to + ``&PyBaseObject_Type`` (which to Python programmers is known as the type + :class:`object`). + + +.. cmember:: PyObject* PyTypeObject.tp_dict + + The type's dictionary is stored here by :cfunc:`PyType_Ready`. + + This field should normally be initialized to *NULL* before PyType_Ready is + called; it may also be initialized to a dictionary containing initial attributes + for the type. Once :cfunc:`PyType_Ready` has initialized the type, extra + attributes for the type may be added to this dictionary only if they don't + correspond to overloaded operations (like :meth:`__add__`). + + This field is not inherited by subtypes (though the attributes defined in here + are inherited through a different mechanism). + + +.. cmember:: descrgetfunc PyTypeObject.tp_descr_get + + An optional pointer to a "descriptor get" function. + + The function signature is :: + + PyObject * tp_descr_get(PyObject *self, PyObject *obj, PyObject *type); + + XXX explain. + + This field is inherited by subtypes. + + +.. cmember:: descrsetfunc PyTypeObject.tp_descr_set + + An optional pointer to a "descriptor set" function. + + The function signature is :: + + int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value); + + This field is inherited by subtypes. + + XXX explain. + + +.. cmember:: long PyTypeObject.tp_dictoffset + + If the instances of this type have a dictionary containing instance variables, + this field is non-zero and contains the offset in the instances of the type of + the instance variable dictionary; this offset is used by + :cfunc:`PyObject_GenericGetAttr`. + + Do not confuse this field with :attr:`tp_dict`; that is the dictionary for + attributes of the type object itself. + + If the value of this field is greater than zero, it specifies the offset from + the start of the instance structure. If the value is less than zero, it + specifies the offset from the *end* of the instance structure. A negative + offset is more expensive to use, and should only be used when the instance + structure contains a variable-length part. This is used for example to add an + instance variable dictionary to subtypes of :class:`str` or :class:`tuple`. Note + that the :attr:`tp_basicsize` field should account for the dictionary added to + the end in that case, even though the dictionary is not included in the basic + object layout. On a system with a pointer size of 4 bytes, + :attr:`tp_dictoffset` should be set to ``-4`` to indicate that the dictionary is + at the very end of the structure. + + The real dictionary offset in an instance can be computed from a negative + :attr:`tp_dictoffset` as follows:: + + dictoffset = tp_basicsize + abs(ob_size)*tp_itemsize + tp_dictoffset + if dictoffset is not aligned on sizeof(void*): + round up to sizeof(void*) + + where :attr:`tp_basicsize`, :attr:`tp_itemsize` and :attr:`tp_dictoffset` are + taken from the type object, and :attr:`ob_size` is taken from the instance. The + absolute value is taken because long ints use the sign of :attr:`ob_size` to + store the sign of the number. (There's never a need to do this calculation + yourself; it is done for you by :cfunc:`_PyObject_GetDictPtr`.) + + This field is inherited by subtypes, but see the rules listed below. A subtype + may override this offset; this means that the subtype instances store the + dictionary at a difference offset than the base type. Since the dictionary is + always found via :attr:`tp_dictoffset`, this should not be a problem. + + When a type defined by a class statement has no :attr:`__slots__` declaration, + and none of its base types has an instance variable dictionary, a dictionary + slot is added to the instance layout and the :attr:`tp_dictoffset` is set to + that slot's offset. + + When a type defined by a class statement has a :attr:`__slots__` declaration, + the type inherits its :attr:`tp_dictoffset` from its base type. + + (Adding a slot named :attr:`__dict__` to the :attr:`__slots__` declaration does + not have the expected effect, it just causes confusion. Maybe this should be + added as a feature just like :attr:`__weakref__` though.) + + +.. cmember:: initproc PyTypeObject.tp_init + + An optional pointer to an instance initialization function. + + This function corresponds to the :meth:`__init__` method of classes. Like + :meth:`__init__`, it is possible to create an instance without calling + :meth:`__init__`, and it is possible to reinitialize an instance by calling its + :meth:`__init__` method again. + + The function signature is :: + + int tp_init(PyObject *self, PyObject *args, PyObject *kwds) + + The self argument is the instance to be initialized; the *args* and *kwds* + arguments represent positional and keyword arguments of the call to + :meth:`__init__`. + + The :attr:`tp_init` function, if not *NULL*, is called when an instance is + created normally by calling its type, after the type's :attr:`tp_new` function + has returned an instance of the type. If the :attr:`tp_new` function returns an + instance of some other type that is not a subtype of the original type, no + :attr:`tp_init` function is called; if :attr:`tp_new` returns an instance of a + subtype of the original type, the subtype's :attr:`tp_init` is called. (VERSION + NOTE: described here is what is implemented in Python 2.2.1 and later. In + Python 2.2, the :attr:`tp_init` of the type of the object returned by + :attr:`tp_new` was always called, if not *NULL*.) + + This field is inherited by subtypes. + + +.. cmember:: allocfunc PyTypeObject.tp_alloc + + An optional pointer to an instance allocation function. + + The function signature is :: + + PyObject *tp_alloc(PyTypeObject *self, Py_ssize_t nitems) + + The purpose of this function is to separate memory allocation from memory + initialization. It should return a pointer to a block of memory of adequate + length for the instance, suitably aligned, and initialized to zeros, but with + :attr:`ob_refcnt` set to ``1`` and :attr:`ob_type` set to the type argument. If + the type's :attr:`tp_itemsize` is non-zero, the object's :attr:`ob_size` field + should be initialized to *nitems* and the length of the allocated memory block + should be ``tp_basicsize + nitems*tp_itemsize``, rounded up to a multiple of + ``sizeof(void*)``; otherwise, *nitems* is not used and the length of the block + should be :attr:`tp_basicsize`. + + Do not use this function to do any other instance initialization, not even to + allocate additional memory; that should be done by :attr:`tp_new`. + + This field is inherited by static subtypes, but not by dynamic subtypes + (subtypes created by a class statement); in the latter, this field is always set + to :cfunc:`PyType_GenericAlloc`, to force a standard heap allocation strategy. + That is also the recommended value for statically defined types. + + +.. cmember:: newfunc PyTypeObject.tp_new + + An optional pointer to an instance creation function. + + If this function is *NULL* for a particular type, that type cannot be called to + create new instances; presumably there is some other way to create instances, + like a factory function. + + The function signature is :: + + PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) + + The subtype argument is the type of the object being created; the *args* and + *kwds* arguments represent positional and keyword arguments of the call to the + type. Note that subtype doesn't have to equal the type whose :attr:`tp_new` + function is called; it may be a subtype of that type (but not an unrelated + type). + + The :attr:`tp_new` function should call ``subtype->tp_alloc(subtype, nitems)`` + to allocate space for the object, and then do only as much further + initialization as is absolutely necessary. Initialization that can safely be + ignored or repeated should be placed in the :attr:`tp_init` handler. A good + rule of thumb is that for immutable types, all initialization should take place + in :attr:`tp_new`, while for mutable types, most initialization should be + deferred to :attr:`tp_init`. + + This field is inherited by subtypes, except it is not inherited by static types + whose :attr:`tp_base` is *NULL* or ``&PyBaseObject_Type``. The latter exception + is a precaution so that old extension types don't become callable simply by + being linked with Python 2.2. + + +.. cmember:: destructor PyTypeObject.tp_free + + An optional pointer to an instance deallocation function. + + The signature of this function has changed slightly: in Python 2.2 and 2.2.1, + its signature is :ctype:`destructor`:: + + void tp_free(PyObject *) + + In Python 2.3 and beyond, its signature is :ctype:`freefunc`:: + + void tp_free(void *) + + The only initializer that is compatible with both versions is ``PyObject_Free``, + whose definition has suitably adapted in Python 2.3. + + This field is inherited by static subtypes, but not by dynamic subtypes + (subtypes created by a class statement); in the latter, this field is set to a + deallocator suitable to match :cfunc:`PyType_GenericAlloc` and the value of the + :const:`Py_TPFLAGS_HAVE_GC` flag bit. + + +.. cmember:: inquiry PyTypeObject.tp_is_gc + + An optional pointer to a function called by the garbage collector. + + The garbage collector needs to know whether a particular object is collectible + or not. Normally, it is sufficient to look at the object's type's + :attr:`tp_flags` field, and check the :const:`Py_TPFLAGS_HAVE_GC` flag bit. But + some types have a mixture of statically and dynamically allocated instances, and + the statically allocated instances are not collectible. Such types should + define this function; it should return ``1`` for a collectible instance, and + ``0`` for a non-collectible instance. The signature is :: + + int tp_is_gc(PyObject *self) + + (The only example of this are types themselves. The metatype, + :cdata:`PyType_Type`, defines this function to distinguish between statically + and dynamically allocated types.) + + This field is inherited by subtypes. (VERSION NOTE: in Python 2.2, it was not + inherited. It is inherited in 2.2.1 and later versions.) + + +.. cmember:: PyObject* PyTypeObject.tp_bases + + Tuple of base types. + + This is set for types created by a class statement. It should be *NULL* for + statically defined types. + + This field is not inherited. + + +.. cmember:: PyObject* PyTypeObject.tp_mro + + Tuple containing the expanded set of base types, starting with the type itself + and ending with :class:`object`, in Method Resolution Order. + + This field is not inherited; it is calculated fresh by :cfunc:`PyType_Ready`. + + +.. cmember:: PyObject* PyTypeObject.tp_cache + + Unused. Not inherited. Internal use only. + + +.. cmember:: PyObject* PyTypeObject.tp_subclasses + + List of weak references to subclasses. Not inherited. Internal use only. + + +.. cmember:: PyObject* PyTypeObject.tp_weaklist + + Weak reference list head, for weak references to this type object. Not + inherited. Internal use only. + +The remaining fields are only defined if the feature test macro +:const:`COUNT_ALLOCS` is defined, and are for internal use only. They are +documented here for completeness. None of these fields are inherited by +subtypes. + + +.. cmember:: Py_ssize_t PyTypeObject.tp_allocs + + Number of allocations. + + +.. cmember:: Py_ssize_t PyTypeObject.tp_frees + + Number of frees. + + +.. cmember:: Py_ssize_t PyTypeObject.tp_maxalloc + + Maximum simultaneously allocated objects. + + +.. cmember:: PyTypeObject* PyTypeObject.tp_next + + Pointer to the next type object with a non-zero :attr:`tp_allocs` field. + +Also, note that, in a garbage collected Python, tp_dealloc may be called from +any Python thread, not just the thread which created the object (if the object +becomes part of a refcount cycle, that cycle might be collected by a garbage +collection on any thread). This is not a problem for Python API calls, since +the thread on which tp_dealloc is called will own the Global Interpreter Lock +(GIL). However, if the object being destroyed in turn destroys objects from some +other C or C++ library, care should be taken to ensure that destroying those +objects on the thread which called tp_dealloc will not violate any assumptions +of the library. + + +.. _number-structs: + +Number Object Structures +======================== + +.. sectionauthor:: Amaury Forgeot d'Arc + + +.. ctype:: PyNumberMethods + + This structure holds pointers to the functions which an object uses to + implement the number protocol. Each function is used by the function of + similar name documented in the :ref:`number` section. + + Here is the structure definition:: + + typedef struct { + binaryfunc nb_add; + binaryfunc nb_subtract; + binaryfunc nb_multiply; + binaryfunc nb_remainder; + binaryfunc nb_divmod; + ternaryfunc nb_power; + unaryfunc nb_negative; + unaryfunc nb_positive; + unaryfunc nb_absolute; + inquiry nb_bool; + unaryfunc nb_invert; + binaryfunc nb_lshift; + binaryfunc nb_rshift; + binaryfunc nb_and; + binaryfunc nb_xor; + binaryfunc nb_or; + int nb_reserved; /* unused, must be zero */ + unaryfunc nb_int; + unaryfunc nb_long; + unaryfunc nb_float; + + unaryfunc nb_oct; /* not used anymore, must be zero */ + unaryfunc nb_hex; /* not used anymore, must be zero */ + + binaryfunc nb_inplace_add; + binaryfunc nb_inplace_subtract; + binaryfunc nb_inplace_multiply; + binaryfunc nb_inplace_remainder; + ternaryfunc nb_inplace_power; + binaryfunc nb_inplace_lshift; + binaryfunc nb_inplace_rshift; + binaryfunc nb_inplace_and; + binaryfunc nb_inplace_xor; + binaryfunc nb_inplace_or; + + binaryfunc nb_floor_divide; + binaryfunc nb_true_divide; + binaryfunc nb_inplace_floor_divide; + binaryfunc nb_inplace_true_divide; + + unaryfunc nb_index; + } PyNumberMethods; + + .. note:: + + Binary and ternary functions must check the type of all their operands, + and implement the necessary conversions (at least one of the operands is + an instance of the defined type). If the operation is not defined for the + given operands, binary and ternary functions must return + ``Py_NotImplemented``, if another error occurred they must return ``NULL`` + and set an exception. + + +.. _mapping-structs: + +Mapping Object Structures +========================= + +.. sectionauthor:: Amaury Forgeot d'Arc + + +.. ctype:: PyMappingMethods + + This structure holds pointers to the functions which an object uses to + implement the mapping protocol. It has three members: + +.. cmember:: lenfunc PyMappingMethods.mp_length + + This function is used by :cfunc:`PyMapping_Length` and + :cfunc:`PyObject_Size`, and has the same signature. This slot may be set to + *NULL* if the object has no defined length. + +.. cmember:: binaryfunc PyMappingMethods.mp_subscript + + This function is used by :cfunc:`PyObject_GetItem` and has the same + signature. This slot must be filled for the :cfunc:`PyMapping_Check` + function to return ``1``, it can be *NULL* otherwise. + +.. cmember:: objobjargproc PyMappingMethods.mp_ass_subscript + + This function is used by :cfunc:`PyObject_SetItem` and has the same + signature. If this slot is *NULL*, the object does not support item + assignment. + + +.. _sequence-structs: + +Sequence Object Structures +========================== + +.. sectionauthor:: Amaury Forgeot d'Arc + + +.. ctype:: PySequenceMethods + + This structure holds pointers to the functions which an object uses to + implement the sequence protocol. + +.. cmember:: lenfunc PySequenceMethods.sq_length + + This function is used by :cfunc:`PySequence_Size` and :cfunc:`PyObject_Size`, + and has the same signature. + +.. cmember:: binaryfunc PySequenceMethods.sq_concat + + This function is used by :cfunc:`PySequence_Concat` and has the same + signature. It is also used by the ``+`` operator, after trying the numeric + addition via the :attr:`tp_as_number.nb_add` slot. + +.. cmember:: ssizeargfunc PySequenceMethods.sq_repeat + + This function is used by :cfunc:`PySequence_Repeat` and has the same + signature. It is also used by the ``*`` operator, after trying numeric + multiplication via the :attr:`tp_as_number.nb_mul` slot. + +.. cmember:: ssizeargfunc PySequenceMethods.sq_item + + This function is used by :cfunc:`PySequence_GetItem` and has the same + signature. This slot must be filled for the :cfunc:`PySequence_Check` + function to return ``1``, it can be *NULL* otherwise. + + Negative indexes are handled as follows: if the :attr:`sq_length` slot is + filled, it is called and the sequence length is used to compute a positive + index which is passed to :attr:`sq_item`. If :attr:`sq_length` is *NULL*, + the index is passed as is to the function. + +.. cmember:: ssizeobjargproc PySequenceMethods.sq_ass_item + + This function is used by :cfunc:`PySequence_SetItem` and has the same + signature. This slot may be left to *NULL* if the object does not support + item assignment. + +.. cmember:: objobjproc PySequenceMethods.sq_contains + + This function may be used by :cfunc:`PySequence_Contains` and has the same + signature. This slot may be left to *NULL*, in this case + :cfunc:`PySequence_Contains` simply traverses the sequence until it finds a + match. + +.. cmember:: binaryfunc PySequenceMethods.sq_inplace_concat + + This function is used by :cfunc:`PySequence_InPlaceConcat` and has the same + signature. It should modify its first operand, and return it. + +.. cmember:: ssizeargfunc PySequenceMethods.sq_inplace_repeat + + This function is used by :cfunc:`PySequence_InPlaceRepeat` and has the same + signature. It should modify its first operand, and return it. + +.. XXX need to explain precedence between mapping and sequence +.. XXX explains when to implement the sq_inplace_* slots + + +.. _buffer-structs: + +Buffer Object Structures +======================== + +.. sectionauthor:: Greg J. Stein + + +The buffer interface exports a model where an object can expose its internal +data as a set of chunks of data, where each chunk is specified as a +pointer/length pair. These chunks are called :dfn:`segments` and are presumed +to be non-contiguous in memory. + +If an object does not export the buffer interface, then its :attr:`tp_as_buffer` +member in the :ctype:`PyTypeObject` structure should be *NULL*. Otherwise, the +:attr:`tp_as_buffer` will point to a :ctype:`PyBufferProcs` structure. + +.. note:: + + It is very important that your :ctype:`PyTypeObject` structure uses + :const:`Py_TPFLAGS_DEFAULT` for the value of the :attr:`tp_flags` member rather + than ``0``. This tells the Python runtime that your :ctype:`PyBufferProcs` + structure contains the :attr:`bf_getcharbuffer` slot. Older versions of Python + did not have this member, so a new Python interpreter using an old extension + needs to be able to test for its presence before using it. + + +.. ctype:: PyBufferProcs + + Structure used to hold the function pointers which define an implementation of + the buffer protocol. + + The first slot is :attr:`bf_getreadbuffer`, of type :ctype:`getreadbufferproc`. + If this slot is *NULL*, then the object does not support reading from the + internal data. This is non-sensical, so implementors should fill this in, but + callers should test that the slot contains a non-*NULL* value. + + The next slot is :attr:`bf_getwritebuffer` having type + :ctype:`getwritebufferproc`. This slot may be *NULL* if the object does not + allow writing into its returned buffers. + + The third slot is :attr:`bf_getsegcount`, with type :ctype:`getsegcountproc`. + This slot must not be *NULL* and is used to inform the caller how many segments + the object contains. Simple objects such as :ctype:`PyString_Type` and + :ctype:`PyBuffer_Type` objects contain a single segment. + + .. index:: single: PyType_HasFeature() + + The last slot is :attr:`bf_getcharbuffer`, of type :ctype:`getcharbufferproc`. + This slot will only be present if the :const:`Py_TPFLAGS_HAVE_GETCHARBUFFER` + flag is present in the :attr:`tp_flags` field of the object's + :ctype:`PyTypeObject`. Before using this slot, the caller should test whether it + is present by using the :cfunc:`PyType_HasFeature` function. If the flag is + present, :attr:`bf_getcharbuffer` may be *NULL*, indicating that the object's + contents cannot be used as *8-bit characters*. The slot function may also raise + an error if the object's contents cannot be interpreted as 8-bit characters. + For example, if the object is an array which is configured to hold floating + point values, an exception may be raised if a caller attempts to use + :attr:`bf_getcharbuffer` to fetch a sequence of 8-bit characters. This notion of + exporting the internal buffers as "text" is used to distinguish between objects + that are binary in nature, and those which have character-based content. + + .. note:: + + The current policy seems to state that these characters may be multi-byte + characters. This implies that a buffer size of *N* does not mean there are *N* + characters present. + + +.. data:: Py_TPFLAGS_HAVE_GETCHARBUFFER + + Flag bit set in the type structure to indicate that the :attr:`bf_getcharbuffer` + slot is known. This being set does not indicate that the object supports the + buffer interface or that the :attr:`bf_getcharbuffer` slot is non-*NULL*. + + +.. ctype:: Py_ssize_t (*readbufferproc) (PyObject *self, Py_ssize_t segment, void **ptrptr) + + Return a pointer to a readable segment of the buffer in ``*ptrptr``. This + function is allowed to raise an exception, in which case it must return ``-1``. + The *segment* which is specified must be zero or positive, and strictly less + than the number of segments returned by the :attr:`bf_getsegcount` slot + function. On success, it returns the length of the segment, and sets + ``*ptrptr`` to a pointer to that memory. + + +.. ctype:: Py_ssize_t (*writebufferproc) (PyObject *self, Py_ssize_t segment, void **ptrptr) + + Return a pointer to a writable memory buffer in ``*ptrptr``, and the length of + that segment as the function return value. The memory buffer must correspond to + buffer segment *segment*. Must return ``-1`` and set an exception on error. + :exc:`TypeError` should be raised if the object only supports read-only buffers, + and :exc:`SystemError` should be raised when *segment* specifies a segment that + doesn't exist. + + .. Why doesn't it raise ValueError for this one? + GJS: because you shouldn't be calling it with an invalid + segment. That indicates a blatant programming error in the C code. + + +.. ctype:: Py_ssize_t (*segcountproc) (PyObject *self, Py_ssize_t *lenp) + + Return the number of memory segments which comprise the buffer. If *lenp* is + not *NULL*, the implementation must report the sum of the sizes (in bytes) of + all segments in ``*lenp``. The function cannot fail. + + +.. ctype:: Py_ssize_t (*charbufferproc) (PyObject *self, Py_ssize_t segment, const char **ptrptr) + + Return the size of the segment *segment* that *ptrptr* is set to. ``*ptrptr`` + is set to the memory buffer. Returns ``-1`` on error. Added: python/branches/py3k/Doc/c-api/unicode.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/unicode.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,900 @@ +.. highlightlang:: c + +.. _unicodeobjects: + +Unicode Objects and Codecs +-------------------------- + +.. sectionauthor:: Marc-Andre Lemburg + +Unicode Objects +^^^^^^^^^^^^^^^ + +These are the basic Unicode object types used for the Unicode implementation in +Python: + +.. % --- Unicode Type ------------------------------------------------------- + + +.. ctype:: Py_UNICODE + + This type represents the storage type which is used by Python internally as + basis for holding Unicode ordinals. Python's default builds use a 16-bit type + for :ctype:`Py_UNICODE` and store Unicode values internally as UCS2. It is also + possible to build a UCS4 version of Python (most recent Linux distributions come + with UCS4 builds of Python). These builds then use a 32-bit type for + :ctype:`Py_UNICODE` and store Unicode data internally as UCS4. On platforms + where :ctype:`wchar_t` is available and compatible with the chosen Python + Unicode build variant, :ctype:`Py_UNICODE` is a typedef alias for + :ctype:`wchar_t` to enhance native platform compatibility. On all other + platforms, :ctype:`Py_UNICODE` is a typedef alias for either :ctype:`unsigned + short` (UCS2) or :ctype:`unsigned long` (UCS4). + +Note that UCS2 and UCS4 Python builds are not binary compatible. Please keep +this in mind when writing extensions or interfaces. + + +.. ctype:: PyUnicodeObject + + This subtype of :ctype:`PyObject` represents a Python Unicode object. + + +.. cvar:: PyTypeObject PyUnicode_Type + + This instance of :ctype:`PyTypeObject` represents the Python Unicode type. It + is exposed to Python code as ``str``. + +The following APIs are really C macros and can be used to do fast checks and to +access internal read-only data of Unicode objects: + + +.. cfunction:: int PyUnicode_Check(PyObject *o) + + Return true if the object *o* is a Unicode object or an instance of a Unicode + subtype. + + +.. cfunction:: int PyUnicode_CheckExact(PyObject *o) + + Return true if the object *o* is a Unicode object, but not an instance of a + subtype. + + +.. cfunction:: Py_ssize_t PyUnicode_GET_SIZE(PyObject *o) + + Return the size of the object. *o* has to be a :ctype:`PyUnicodeObject` (not + checked). + + +.. cfunction:: Py_ssize_t PyUnicode_GET_DATA_SIZE(PyObject *o) + + Return the size of the object's internal buffer in bytes. *o* has to be a + :ctype:`PyUnicodeObject` (not checked). + + +.. cfunction:: Py_UNICODE* PyUnicode_AS_UNICODE(PyObject *o) + + Return a pointer to the internal :ctype:`Py_UNICODE` buffer of the object. *o* + has to be a :ctype:`PyUnicodeObject` (not checked). + + +.. cfunction:: const char* PyUnicode_AS_DATA(PyObject *o) + + Return a pointer to the internal buffer of the object. *o* has to be a + :ctype:`PyUnicodeObject` (not checked). + +Unicode provides many different character properties. The most often needed ones +are available through these macros which are mapped to C functions depending on +the Python configuration. + +.. % --- Unicode character properties --------------------------------------- + + +.. cfunction:: int Py_UNICODE_ISSPACE(Py_UNICODE ch) + + Return 1 or 0 depending on whether *ch* is a whitespace character. + + +.. cfunction:: int Py_UNICODE_ISLOWER(Py_UNICODE ch) + + Return 1 or 0 depending on whether *ch* is a lowercase character. + + +.. cfunction:: int Py_UNICODE_ISUPPER(Py_UNICODE ch) + + Return 1 or 0 depending on whether *ch* is an uppercase character. + + +.. cfunction:: int Py_UNICODE_ISTITLE(Py_UNICODE ch) + + Return 1 or 0 depending on whether *ch* is a titlecase character. + + +.. cfunction:: int Py_UNICODE_ISLINEBREAK(Py_UNICODE ch) + + Return 1 or 0 depending on whether *ch* is a linebreak character. + + +.. cfunction:: int Py_UNICODE_ISDECIMAL(Py_UNICODE ch) + + Return 1 or 0 depending on whether *ch* is a decimal character. + + +.. cfunction:: int Py_UNICODE_ISDIGIT(Py_UNICODE ch) + + Return 1 or 0 depending on whether *ch* is a digit character. + + +.. cfunction:: int Py_UNICODE_ISNUMERIC(Py_UNICODE ch) + + Return 1 or 0 depending on whether *ch* is a numeric character. + + +.. cfunction:: int Py_UNICODE_ISALPHA(Py_UNICODE ch) + + Return 1 or 0 depending on whether *ch* is an alphabetic character. + + +.. cfunction:: int Py_UNICODE_ISALNUM(Py_UNICODE ch) + + Return 1 or 0 depending on whether *ch* is an alphanumeric character. + +These APIs can be used for fast direct character conversions: + + +.. cfunction:: Py_UNICODE Py_UNICODE_TOLOWER(Py_UNICODE ch) + + Return the character *ch* converted to lower case. + + +.. cfunction:: Py_UNICODE Py_UNICODE_TOUPPER(Py_UNICODE ch) + + Return the character *ch* converted to upper case. + + +.. cfunction:: Py_UNICODE Py_UNICODE_TOTITLE(Py_UNICODE ch) + + Return the character *ch* converted to title case. + + +.. cfunction:: int Py_UNICODE_TODECIMAL(Py_UNICODE ch) + + Return the character *ch* converted to a decimal positive integer. Return + ``-1`` if this is not possible. This macro does not raise exceptions. + + +.. cfunction:: int Py_UNICODE_TODIGIT(Py_UNICODE ch) + + Return the character *ch* converted to a single digit integer. Return ``-1`` if + this is not possible. This macro does not raise exceptions. + + +.. cfunction:: double Py_UNICODE_TONUMERIC(Py_UNICODE ch) + + Return the character *ch* converted to a double. Return ``-1.0`` if this is not + possible. This macro does not raise exceptions. + +To create Unicode objects and access their basic sequence properties, use these +APIs: + +.. % --- Plain Py_UNICODE --------------------------------------------------- + + +.. cfunction:: PyObject* PyUnicode_FromUnicode(const Py_UNICODE *u, Py_ssize_t size) + + Create a Unicode Object from the Py_UNICODE buffer *u* of the given size. *u* + may be *NULL* which causes the contents to be undefined. It is the user's + responsibility to fill in the needed data. The buffer is copied into the new + object. If the buffer is not *NULL*, the return value might be a shared object. + Therefore, modification of the resulting Unicode object is only allowed when *u* + is *NULL*. + + +.. cfunction:: PyObject* PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size) + + Create a Unicode Object from the char buffer *u*. The bytes will be interpreted + as being UTF-8 encoded. *u* may also be *NULL* which + causes the contents to be undefined. It is the user's responsibility to fill in + the needed data. The buffer is copied into the new object. If the buffer is not + *NULL*, the return value might be a shared object. Therefore, modification of + the resulting Unicode object is only allowed when *u* is *NULL*. + + +.. cfunction:: PyObject *PyUnicode_FromString(const char *u) + + Create a Unicode object from an UTF-8 encoded null-terminated char buffer + *u*. + + +.. cfunction:: PyObject* PyUnicode_FromFormat(const char *format, ...) + + Take a C :cfunc:`printf`\ -style *format* string and a variable number of + arguments, calculate the size of the resulting Python unicode string and return + a string with the values formatted into it. The variable arguments must be C + types and must correspond exactly to the format characters in the *format* + string. The following format characters are allowed: + + .. % The descriptions for %zd and %zu are wrong, but the truth is complicated + .. % because not all compilers support the %z width modifier -- we fake it + .. % when necessary via interpolating PY_FORMAT_SIZE_T. + + +-------------------+---------------------+--------------------------------+ + | Format Characters | Type | Comment | + +===================+=====================+================================+ + | :attr:`%%` | *n/a* | The literal % character. | + +-------------------+---------------------+--------------------------------+ + | :attr:`%c` | int | A single character, | + | | | represented as an C int. | + +-------------------+---------------------+--------------------------------+ + | :attr:`%d` | int | Exactly equivalent to | + | | | ``printf("%d")``. | + +-------------------+---------------------+--------------------------------+ + | :attr:`%u` | unsigned int | Exactly equivalent to | + | | | ``printf("%u")``. | + +-------------------+---------------------+--------------------------------+ + | :attr:`%ld` | long | Exactly equivalent to | + | | | ``printf("%ld")``. | + +-------------------+---------------------+--------------------------------+ + | :attr:`%lu` | unsigned long | Exactly equivalent to | + | | | ``printf("%lu")``. | + +-------------------+---------------------+--------------------------------+ + | :attr:`%zd` | Py_ssize_t | Exactly equivalent to | + | | | ``printf("%zd")``. | + +-------------------+---------------------+--------------------------------+ + | :attr:`%zu` | size_t | Exactly equivalent to | + | | | ``printf("%zu")``. | + +-------------------+---------------------+--------------------------------+ + | :attr:`%i` | int | Exactly equivalent to | + | | | ``printf("%i")``. | + +-------------------+---------------------+--------------------------------+ + | :attr:`%x` | int | Exactly equivalent to | + | | | ``printf("%x")``. | + +-------------------+---------------------+--------------------------------+ + | :attr:`%s` | char\* | A null-terminated C character | + | | | array. | + +-------------------+---------------------+--------------------------------+ + | :attr:`%p` | void\* | The hex representation of a C | + | | | pointer. Mostly equivalent to | + | | | ``printf("%p")`` except that | + | | | it is guaranteed to start with | + | | | the literal ``0x`` regardless | + | | | of what the platform's | + | | | ``printf`` yields. | + +-------------------+---------------------+--------------------------------+ + | :attr:`%U` | PyObject\* | A unicode object. | + +-------------------+---------------------+--------------------------------+ + | :attr:`%V` | PyObject\*, char \* | A unicode object (which may be | + | | | *NULL*) and a null-terminated | + | | | C character array as a second | + | | | parameter (which will be used, | + | | | if the first parameter is | + | | | *NULL*). | + +-------------------+---------------------+--------------------------------+ + | :attr:`%S` | PyObject\* | The result of calling | + | | | :func:`PyObject_Unicode`. | + +-------------------+---------------------+--------------------------------+ + | :attr:`%R` | PyObject\* | The result of calling | + | | | :func:`PyObject_Repr`. | + +-------------------+---------------------+--------------------------------+ + + 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. + + +.. cfunction:: PyObject* PyUnicode_FromFormatV(const char *format, va_list vargs) + + Identical to :func:`PyUnicode_FromFormat` except that it takes exactly two + arguments. + + +.. cfunction:: Py_UNICODE* PyUnicode_AsUnicode(PyObject *unicode) + + Return a read-only pointer to the Unicode object's internal :ctype:`Py_UNICODE` + buffer, *NULL* if *unicode* is not a Unicode object. + + +.. cfunction:: Py_ssize_t PyUnicode_GetSize(PyObject *unicode) + + Return the length of the Unicode object. + + +.. cfunction:: PyObject* PyUnicode_FromEncodedObject(PyObject *obj, const char *encoding, const char *errors) + + Coerce an encoded object *obj* to an Unicode object and return a reference with + incremented refcount. + + String and other char buffer compatible objects are decoded according to the + given encoding and using the error handling defined by errors. Both can be + *NULL* to have the interface use the default values (see the next section for + details). + + All other objects, including Unicode objects, cause a :exc:`TypeError` to be + set. + + The API returns *NULL* if there was an error. The caller is responsible for + decref'ing the returned objects. + + +.. cfunction:: PyObject* PyUnicode_FromObject(PyObject *obj) + + Shortcut for ``PyUnicode_FromEncodedObject(obj, NULL, "strict")`` which is used + throughout the interpreter whenever coercion to Unicode is needed. + +If the platform supports :ctype:`wchar_t` and provides a header file wchar.h, +Python can interface directly to this type using the following functions. +Support is optimized if Python's own :ctype:`Py_UNICODE` type is identical to +the system's :ctype:`wchar_t`. + +.. % --- wchar_t support for platforms which support it --------------------- + + +.. cfunction:: PyObject* PyUnicode_FromWideChar(const wchar_t *w, Py_ssize_t size) + + Create a Unicode object from the :ctype:`wchar_t` buffer *w* of the given size. + Return *NULL* on failure. + + +.. cfunction:: Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode, wchar_t *w, Py_ssize_t size) + + Copy the Unicode object contents into the :ctype:`wchar_t` buffer *w*. At most + *size* :ctype:`wchar_t` characters are copied (excluding a possibly trailing + 0-termination character). Return the number of :ctype:`wchar_t` characters + copied or -1 in case of an error. Note that the resulting :ctype:`wchar_t` + string may or may not be 0-terminated. It is the responsibility of the caller + to make sure that the :ctype:`wchar_t` string is 0-terminated in case this is + required by the application. + + +.. _builtincodecs: + +Built-in Codecs +^^^^^^^^^^^^^^^ + +Python provides a set of builtin codecs which are written in C for speed. All of +these codecs are directly usable via the following functions. + +Many of the following APIs take two arguments encoding and errors. These +parameters encoding and errors have the same semantics as the ones of the +builtin unicode() Unicode object constructor. + +Setting encoding to *NULL* causes the default encoding to be used which is +ASCII. The file system calls should use :cdata:`Py_FileSystemDefaultEncoding` +as the encoding for file names. This variable should be treated as read-only: On +some systems, it will be a pointer to a static string, on others, it will change +at run-time (such as when the application invokes setlocale). + +Error handling is set by errors which may also be set to *NULL* meaning to use +the default handling defined for the codec. Default error handling for all +builtin codecs is "strict" (:exc:`ValueError` is raised). + +The codecs all use a similar interface. Only deviation from the following +generic ones are documented for simplicity. + +These are the generic codec APIs: + +.. % --- Generic Codecs ----------------------------------------------------- + + +.. cfunction:: PyObject* PyUnicode_Decode(const char *s, Py_ssize_t size, const char *encoding, const char *errors) + + Create a Unicode object by decoding *size* bytes of the encoded string *s*. + *encoding* and *errors* have the same meaning as the parameters of the same name + in the :func:`unicode` builtin function. The codec to be used is looked up + using the Python codec registry. Return *NULL* if an exception was raised by + the codec. + + +.. cfunction:: PyObject* PyUnicode_Encode(const Py_UNICODE *s, Py_ssize_t size, const char *encoding, const char *errors) + + Encode the :ctype:`Py_UNICODE` buffer of the given size and return a Python + string object. *encoding* and *errors* have the same meaning as the parameters + of the same name in the Unicode :meth:`encode` method. The codec to be used is + looked up using the Python codec registry. Return *NULL* if an exception was + raised by the codec. + + +.. cfunction:: PyObject* PyUnicode_AsEncodedString(PyObject *unicode, const char *encoding, const char *errors) + + Encode a Unicode object and return the result as Python string object. + *encoding* and *errors* have the same meaning as the parameters of the same name + in the Unicode :meth:`encode` method. The codec to be used is looked up using + the Python codec registry. Return *NULL* if an exception was raised by the + codec. + +These are the UTF-8 codec APIs: + +.. % --- UTF-8 Codecs ------------------------------------------------------- + + +.. cfunction:: PyObject* PyUnicode_DecodeUTF8(const char *s, Py_ssize_t size, const char *errors) + + Create a Unicode object by decoding *size* bytes of the UTF-8 encoded string + *s*. Return *NULL* if an exception was raised by the codec. + + +.. cfunction:: PyObject* PyUnicode_DecodeUTF8Stateful(const char *s, Py_ssize_t size, const char *errors, Py_ssize_t *consumed) + + If *consumed* is *NULL*, behave like :cfunc:`PyUnicode_DecodeUTF8`. If + *consumed* is not *NULL*, trailing incomplete UTF-8 byte sequences will not be + treated as an error. Those bytes will not be decoded and the number of bytes + that have been decoded will be stored in *consumed*. + + +.. cfunction:: PyObject* PyUnicode_EncodeUTF8(const Py_UNICODE *s, Py_ssize_t size, const char *errors) + + Encode the :ctype:`Py_UNICODE` buffer of the given size using UTF-8 and return a + Python string object. Return *NULL* if an exception was raised by the codec. + + +.. cfunction:: PyObject* PyUnicode_AsUTF8String(PyObject *unicode) + + Encode a Unicode object using UTF-8 and return the result as Python string + object. Error handling is "strict". Return *NULL* if an exception was raised + by the codec. + +These are the UTF-32 codec APIs: + +.. % --- UTF-32 Codecs ------------------------------------------------------ */ + + +.. cfunction:: PyObject* PyUnicode_DecodeUTF32(const char *s, Py_ssize_t size, const char *errors, int *byteorder) + + Decode *length* bytes from a UTF-32 encoded buffer string and return the + corresponding Unicode object. *errors* (if non-*NULL*) defines the error + handling. It defaults to "strict". + + If *byteorder* is non-*NULL*, the decoder starts decoding using the given byte + order:: + + *byteorder == -1: little endian + *byteorder == 0: native order + *byteorder == 1: big endian + + and then switches if the first four bytes of the input data are a byte order mark + (BOM) and the specified byte order is native order. This BOM is not copied into + the resulting Unicode string. After completion, *\*byteorder* is set to the + current byte order at the end of input data. + + In a narrow build codepoints outside the BMP will be decoded as surrogate pairs. + + If *byteorder* is *NULL*, the codec starts in native order mode. + + Return *NULL* if an exception was raised by the codec. + + +.. cfunction:: PyObject* PyUnicode_DecodeUTF32Stateful(const char *s, Py_ssize_t size, const char *errors, int *byteorder, Py_ssize_t *consumed) + + If *consumed* is *NULL*, behave like :cfunc:`PyUnicode_DecodeUTF32`. If + *consumed* is not *NULL*, :cfunc:`PyUnicode_DecodeUTF32Stateful` will not treat + trailing incomplete UTF-32 byte sequences (such as a number of bytes not divisible + by four) as an error. Those bytes will not be decoded and the number of bytes + that have been decoded will be stored in *consumed*. + + +.. cfunction:: PyObject* PyUnicode_EncodeUTF32(const Py_UNICODE *s, Py_ssize_t size, const char *errors, int byteorder) + + Return a Python bytes object holding the UTF-32 encoded value of the Unicode + data in *s*. If *byteorder* is not ``0``, output is written according to the + following byte order:: + + byteorder == -1: little endian + byteorder == 0: native byte order (writes a BOM mark) + byteorder == 1: big endian + + If byteorder is ``0``, the output string will always start with the Unicode BOM + mark (U+FEFF). In the other two modes, no BOM mark is prepended. + + If *Py_UNICODE_WIDE* is not defined, surrogate pairs will be output + as a single codepoint. + + Return *NULL* if an exception was raised by the codec. + + +.. cfunction:: PyObject* PyUnicode_AsUTF32String(PyObject *unicode) + + Return a Python string using the UTF-32 encoding in native byte order. The + string always starts with a BOM mark. Error handling is "strict". Return + *NULL* if an exception was raised by the codec. + + +These are the UTF-16 codec APIs: + +.. % --- UTF-16 Codecs ------------------------------------------------------ */ + + +.. cfunction:: PyObject* PyUnicode_DecodeUTF16(const char *s, Py_ssize_t size, const char *errors, int *byteorder) + + Decode *length* bytes from a UTF-16 encoded buffer string and return the + corresponding Unicode object. *errors* (if non-*NULL*) defines the error + handling. It defaults to "strict". + + If *byteorder* is non-*NULL*, the decoder starts decoding using the given byte + order:: + + *byteorder == -1: little endian + *byteorder == 0: native order + *byteorder == 1: big endian + + and then switches if the first two bytes of the input data are a byte order mark + (BOM) and the specified byte order is native order. This BOM is not copied into + the resulting Unicode string. After completion, *\*byteorder* is set to the + current byte order at the end of input data. + + If *byteorder* is *NULL*, the codec starts in native order mode. + + Return *NULL* if an exception was raised by the codec. + + +.. cfunction:: PyObject* PyUnicode_DecodeUTF16Stateful(const char *s, Py_ssize_t size, const char *errors, int *byteorder, Py_ssize_t *consumed) + + If *consumed* is *NULL*, behave like :cfunc:`PyUnicode_DecodeUTF16`. If + *consumed* is not *NULL*, :cfunc:`PyUnicode_DecodeUTF16Stateful` will not treat + trailing incomplete UTF-16 byte sequences (such as an odd number of bytes or a + split surrogate pair) as an error. Those bytes will not be decoded and the + number of bytes that have been decoded will be stored in *consumed*. + + +.. cfunction:: PyObject* PyUnicode_EncodeUTF16(const Py_UNICODE *s, Py_ssize_t size, const char *errors, int byteorder) + + Return a Python string object holding the UTF-16 encoded value of the Unicode + data in *s*. If *byteorder* is not ``0``, output is written according to the + following byte order:: + + byteorder == -1: little endian + byteorder == 0: native byte order (writes a BOM mark) + byteorder == 1: big endian + + If byteorder is ``0``, the output string will always start with the Unicode BOM + mark (U+FEFF). In the other two modes, no BOM mark is prepended. + + If *Py_UNICODE_WIDE* is defined, a single :ctype:`Py_UNICODE` value may get + represented as a surrogate pair. If it is not defined, each :ctype:`Py_UNICODE` + values is interpreted as an UCS-2 character. + + Return *NULL* if an exception was raised by the codec. + + +.. cfunction:: PyObject* PyUnicode_AsUTF16String(PyObject *unicode) + + Return a Python string using the UTF-16 encoding in native byte order. The + string always starts with a BOM mark. Error handling is "strict". Return + *NULL* if an exception was raised by the codec. + +These are the "Unicode Escape" codec APIs: + +.. % --- Unicode-Escape Codecs ---------------------------------------------- + + +.. cfunction:: PyObject* PyUnicode_DecodeUnicodeEscape(const char *s, Py_ssize_t size, const char *errors) + + Create a Unicode object by decoding *size* bytes of the Unicode-Escape encoded + string *s*. Return *NULL* if an exception was raised by the codec. + + +.. cfunction:: PyObject* PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size) + + Encode the :ctype:`Py_UNICODE` buffer of the given size using Unicode-Escape and + return a Python string object. Return *NULL* if an exception was raised by the + codec. + + +.. cfunction:: PyObject* PyUnicode_AsUnicodeEscapeString(PyObject *unicode) + + Encode a Unicode object using Unicode-Escape and return the result as Python + string object. Error handling is "strict". Return *NULL* if an exception was + raised by the codec. + +These are the "Raw Unicode Escape" codec APIs: + +.. % --- Raw-Unicode-Escape Codecs ------------------------------------------ + + +.. cfunction:: PyObject* PyUnicode_DecodeRawUnicodeEscape(const char *s, Py_ssize_t size, const char *errors) + + Create a Unicode object by decoding *size* bytes of the Raw-Unicode-Escape + encoded string *s*. Return *NULL* if an exception was raised by the codec. + + +.. cfunction:: PyObject* PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size, const char *errors) + + Encode the :ctype:`Py_UNICODE` buffer of the given size using Raw-Unicode-Escape + and return a Python string object. Return *NULL* if an exception was raised by + the codec. + + +.. cfunction:: PyObject* PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode) + + Encode a Unicode object using Raw-Unicode-Escape and return the result as + Python string object. Error handling is "strict". Return *NULL* if an exception + was raised by the codec. + +These are the Latin-1 codec APIs: Latin-1 corresponds to the first 256 Unicode +ordinals and only these are accepted by the codecs during encoding. + +.. % --- Latin-1 Codecs ----------------------------------------------------- + + +.. cfunction:: PyObject* PyUnicode_DecodeLatin1(const char *s, Py_ssize_t size, const char *errors) + + Create a Unicode object by decoding *size* bytes of the Latin-1 encoded string + *s*. Return *NULL* if an exception was raised by the codec. + + +.. cfunction:: PyObject* PyUnicode_EncodeLatin1(const Py_UNICODE *s, Py_ssize_t size, const char *errors) + + Encode the :ctype:`Py_UNICODE` buffer of the given size using Latin-1 and return + a Python string object. Return *NULL* if an exception was raised by the codec. + + +.. cfunction:: PyObject* PyUnicode_AsLatin1String(PyObject *unicode) + + Encode a Unicode object using Latin-1 and return the result as Python string + object. Error handling is "strict". Return *NULL* if an exception was raised + by the codec. + +These are the ASCII codec APIs. Only 7-bit ASCII data is accepted. All other +codes generate errors. + +.. % --- ASCII Codecs ------------------------------------------------------- + + +.. cfunction:: PyObject* PyUnicode_DecodeASCII(const char *s, Py_ssize_t size, const char *errors) + + Create a Unicode object by decoding *size* bytes of the ASCII encoded string + *s*. Return *NULL* if an exception was raised by the codec. + + +.. cfunction:: PyObject* PyUnicode_EncodeASCII(const Py_UNICODE *s, Py_ssize_t size, const char *errors) + + Encode the :ctype:`Py_UNICODE` buffer of the given size using ASCII and return a + Python string object. Return *NULL* if an exception was raised by the codec. + + +.. cfunction:: PyObject* PyUnicode_AsASCIIString(PyObject *unicode) + + Encode a Unicode object using ASCII and return the result as Python string + object. Error handling is "strict". Return *NULL* if an exception was raised + by the codec. + +These are the mapping codec APIs: + +.. % --- Character Map Codecs ----------------------------------------------- + +This codec is special in that it can be used to implement many different codecs +(and this is in fact what was done to obtain most of the standard codecs +included in the :mod:`encodings` package). The codec uses mapping to encode and +decode characters. + +Decoding mappings must map single string characters to single Unicode +characters, integers (which are then interpreted as Unicode ordinals) or None +(meaning "undefined mapping" and causing an error). + +Encoding mappings must map single Unicode characters to single string +characters, integers (which are then interpreted as Latin-1 ordinals) or None +(meaning "undefined mapping" and causing an error). + +The mapping objects provided must only support the __getitem__ mapping +interface. + +If a character lookup fails with a LookupError, the character is copied as-is +meaning that its ordinal value will be interpreted as Unicode or Latin-1 ordinal +resp. Because of this, mappings only need to contain those mappings which map +characters to different code points. + + +.. cfunction:: PyObject* PyUnicode_DecodeCharmap(const char *s, Py_ssize_t size, PyObject *mapping, const char *errors) + + Create a Unicode object by decoding *size* bytes of the encoded string *s* using + the given *mapping* object. Return *NULL* if an exception was raised by the + codec. If *mapping* is *NULL* latin-1 decoding will be done. Else it can be a + dictionary mapping byte or a unicode string, which is treated as a lookup table. + Byte values greater that the length of the string and U+FFFE "characters" are + treated as "undefined mapping". + + +.. cfunction:: PyObject* PyUnicode_EncodeCharmap(const Py_UNICODE *s, Py_ssize_t size, PyObject *mapping, const char *errors) + + Encode the :ctype:`Py_UNICODE` buffer of the given size using the given + *mapping* object and return a Python string object. Return *NULL* if an + exception was raised by the codec. + + +.. cfunction:: PyObject* PyUnicode_AsCharmapString(PyObject *unicode, PyObject *mapping) + + Encode a Unicode object using the given *mapping* object and return the result + as Python string object. Error handling is "strict". Return *NULL* if an + exception was raised by the codec. + +The following codec API is special in that maps Unicode to Unicode. + + +.. cfunction:: PyObject* PyUnicode_TranslateCharmap(const Py_UNICODE *s, Py_ssize_t size, PyObject *table, const char *errors) + + Translate a :ctype:`Py_UNICODE` buffer of the given length by applying a + character mapping *table* to it and return the resulting Unicode object. Return + *NULL* when an exception was raised by the codec. + + The *mapping* table must map Unicode ordinal integers to Unicode ordinal + integers or None (causing deletion of the character). + + Mapping tables need only provide the :meth:`__getitem__` interface; dictionaries + and sequences work well. Unmapped character ordinals (ones which cause a + :exc:`LookupError`) are left untouched and are copied as-is. + +These are the MBCS codec APIs. They are currently only available on Windows and +use the Win32 MBCS converters to implement the conversions. Note that MBCS (or +DBCS) is a class of encodings, not just one. The target encoding is defined by +the user settings on the machine running the codec. + +.. % --- MBCS codecs for Windows -------------------------------------------- + + +.. cfunction:: PyObject* PyUnicode_DecodeMBCS(const char *s, Py_ssize_t size, const char *errors) + + Create a Unicode object by decoding *size* bytes of the MBCS encoded string *s*. + Return *NULL* if an exception was raised by the codec. + + +.. cfunction:: PyObject* PyUnicode_DecodeMBCSStateful(const char *s, int size, const char *errors, int *consumed) + + If *consumed* is *NULL*, behave like :cfunc:`PyUnicode_DecodeMBCS`. If + *consumed* is not *NULL*, :cfunc:`PyUnicode_DecodeMBCSStateful` will not decode + trailing lead byte and the number of bytes that have been decoded will be stored + in *consumed*. + + +.. cfunction:: PyObject* PyUnicode_EncodeMBCS(const Py_UNICODE *s, Py_ssize_t size, const char *errors) + + Encode the :ctype:`Py_UNICODE` buffer of the given size using MBCS and return a + Python string object. Return *NULL* if an exception was raised by the codec. + + +.. cfunction:: PyObject* PyUnicode_AsMBCSString(PyObject *unicode) + + Encode a Unicode object using MBCS and return the result as Python string + object. Error handling is "strict". Return *NULL* if an exception was raised + by the codec. + +.. % --- Methods & Slots ---------------------------------------------------- + + +.. _unicodemethodsandslots: + +Methods and Slot Functions +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The following APIs are capable of handling Unicode objects and strings on input +(we refer to them as strings in the descriptions) and return Unicode objects or +integers as appropriate. + +They all return *NULL* or ``-1`` if an exception occurs. + + +.. cfunction:: PyObject* PyUnicode_Concat(PyObject *left, PyObject *right) + + Concat two strings giving a new Unicode string. + + +.. cfunction:: PyObject* PyUnicode_Split(PyObject *s, PyObject *sep, Py_ssize_t maxsplit) + + Split a string giving a list of Unicode strings. If sep is *NULL*, splitting + will be done at all whitespace substrings. Otherwise, splits occur at the given + separator. At most *maxsplit* splits will be done. If negative, no limit is + set. Separators are not included in the resulting list. + + +.. cfunction:: PyObject* PyUnicode_Splitlines(PyObject *s, int keepend) + + Split a Unicode string at line breaks, returning a list of Unicode strings. + CRLF is considered to be one line break. If *keepend* is 0, the Line break + characters are not included in the resulting strings. + + +.. cfunction:: PyObject* PyUnicode_Translate(PyObject *str, PyObject *table, const char *errors) + + Translate a string by applying a character mapping table to it and return the + resulting Unicode object. + + The mapping table must map Unicode ordinal integers to Unicode ordinal integers + or None (causing deletion of the character). + + Mapping tables need only provide the :meth:`__getitem__` interface; dictionaries + and sequences work well. Unmapped character ordinals (ones which cause a + :exc:`LookupError`) are left untouched and are copied as-is. + + *errors* has the usual meaning for codecs. It may be *NULL* which indicates to + use the default error handling. + + +.. cfunction:: PyObject* PyUnicode_Join(PyObject *separator, PyObject *seq) + + Join a sequence of strings using the given separator and return the resulting + Unicode string. + + +.. cfunction:: int PyUnicode_Tailmatch(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction) + + Return 1 if *substr* matches *str*[*start*:*end*] at the given tail end + (*direction* == -1 means to do a prefix match, *direction* == 1 a suffix match), + 0 otherwise. Return ``-1`` if an error occurred. + + +.. cfunction:: Py_ssize_t PyUnicode_Find(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction) + + Return the first position of *substr* in *str*[*start*:*end*] using the given + *direction* (*direction* == 1 means to do a forward search, *direction* == -1 a + backward search). The return value is the index of the first match; a value of + ``-1`` indicates that no match was found, and ``-2`` indicates that an error + occurred and an exception has been set. + + +.. cfunction:: Py_ssize_t PyUnicode_Count(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end) + + Return the number of non-overlapping occurrences of *substr* in + ``str[start:end]``. Return ``-1`` if an error occurred. + + +.. cfunction:: PyObject* PyUnicode_Replace(PyObject *str, PyObject *substr, PyObject *replstr, Py_ssize_t maxcount) + + Replace at most *maxcount* occurrences of *substr* in *str* with *replstr* and + return the resulting Unicode object. *maxcount* == -1 means replace all + occurrences. + + +.. cfunction:: int PyUnicode_Compare(PyObject *left, PyObject *right) + + Compare two strings and return -1, 0, 1 for less than, equal, and greater than, + respectively. + + +.. cfunction:: int PyUnicode_RichCompare(PyObject *left, PyObject *right, int op) + + Rich compare two unicode strings and return one of the following: + + * ``NULL`` in case an exception was raised + * :const:`Py_True` or :const:`Py_False` for successful comparisons + * :const:`Py_NotImplemented` in case the type combination is unknown + + Note that :const:`Py_EQ` and :const:`Py_NE` comparisons can cause a + :exc:`UnicodeWarning` in case the conversion of the arguments to Unicode fails + with a :exc:`UnicodeDecodeError`. + + Possible values for *op* are :const:`Py_GT`, :const:`Py_GE`, :const:`Py_EQ`, + :const:`Py_NE`, :const:`Py_LT`, and :const:`Py_LE`. + + +.. cfunction:: PyObject* PyUnicode_Format(PyObject *format, PyObject *args) + + Return a new string object from *format* and *args*; this is analogous to + ``format % args``. The *args* argument must be a tuple. + + +.. cfunction:: int PyUnicode_Contains(PyObject *container, PyObject *element) + + Check whether *element* is contained in *container* and return true or false + accordingly. + + *element* has to coerce to a one element Unicode string. ``-1`` is returned if + there was an error. + + +.. cfunction:: void PyUnicode_InternInPlace(PyObject **string) + + Intern the argument *\*string* in place. The argument must be the address of a + pointer variable pointing to a Python unicode string object. If there is an + existing interned string that is the same as *\*string*, it sets *\*string* to + it (decrementing the reference count of the old string object and incrementing + the reference count of the interned string object), otherwise it leaves + *\*string* alone and interns it (incrementing its reference count). + (Clarification: even though there is a lot of talk about reference counts, think + of this function as reference-count-neutral; you own the object after the call + if and only if you owned it before the call.) + + +.. cfunction:: PyObject* PyUnicode_InternFromString(const char *v) + + A combination of :cfunc:`PyUnicode_FromString` and + :cfunc:`PyUnicode_InternInPlace`, returning either a new unicode string object + that has been interned, or a new ("owned") reference to an earlier interned + string object with the same value. + Modified: python/branches/py3k/Doc/c-api/utilities.rst ============================================================================== --- python/branches/py3k/Doc/c-api/utilities.rst (original) +++ python/branches/py3k/Doc/c-api/utilities.rst Sun Jan 20 10:30:57 2008 @@ -1,6 +1,5 @@ .. highlightlang:: c - .. _utilities: ********* @@ -11,1125 +10,11 @@ helping C code be more portable across platforms, using Python modules from C, and parsing function arguments and constructing Python values from C values. +.. toctree:: -.. _os: - -Operating System Utilities -========================== - - -.. cfunction:: int Py_FdIsInteractive(FILE *fp, const char *filename) - - Return true (nonzero) if the standard I/O file *fp* with name *filename* is - deemed interactive. This is the case for files for which ``isatty(fileno(fp))`` - is true. If the global flag :cdata:`Py_InteractiveFlag` is true, this function - also returns true if the *filename* pointer is *NULL* or if the name is equal to - one of the strings ``''`` or ``'???'``. - - -.. cfunction:: long PyOS_GetLastModificationTime(char *filename) - - Return the time of last modification of the file *filename*. The result is - encoded in the same way as the timestamp returned by the standard C library - function :cfunc:`time`. - - -.. cfunction:: void PyOS_AfterFork() - - Function to update some internal state after a process fork; this should be - called in the new process if the Python interpreter will continue to be used. - If a new executable is loaded into the new process, this function does not need - to be called. - - -.. cfunction:: int PyOS_CheckStack() - - Return true when the interpreter runs out of stack space. This is a reliable - check, but is only available when :const:`USE_STACKCHECK` is defined (currently - on Windows using the Microsoft Visual C++ compiler). :const:`USE_STACKCHECK` - will be defined automatically; you should never change the definition in your - own code. - - -.. cfunction:: PyOS_sighandler_t PyOS_getsig(int i) - - Return the current signal handler for signal *i*. This is a thin wrapper around - either :cfunc:`sigaction` or :cfunc:`signal`. Do not call those functions - directly! :ctype:`PyOS_sighandler_t` is a typedef alias for :ctype:`void - (\*)(int)`. - - -.. cfunction:: PyOS_sighandler_t PyOS_setsig(int i, PyOS_sighandler_t h) - - Set the signal handler for signal *i* to be *h*; return the old signal handler. - This is a thin wrapper around either :cfunc:`sigaction` or :cfunc:`signal`. Do - not call those functions directly! :ctype:`PyOS_sighandler_t` is a typedef - alias for :ctype:`void (\*)(int)`. - -.. _systemfunctions: - -System Functions -================ - -These are utility functions that make functionality from the :mod:`sys` module -accessible to C code. They all work with the current interpreter thread's -:mod:`sys` module's dict, which is contained in the internal thread state structure. - -.. cfunction:: PyObject *PySys_GetObject(char *name) - - Return the object *name* from the :mod:`sys` module or *NULL* if it does - not exist, without setting an exception. - -.. cfunction:: FILE *PySys_GetFile(char *name, FILE *def) - - Return the :ctype:`FILE*` associated with the object *name* in the - :mod:`sys` module, or *def* if *name* is not in the module or is not associated - with a :ctype:`FILE*`. - -.. cfunction:: int PySys_SetObject(char *name, PyObject *v) - - Set *name* in the :mod:`sys` module to *v* unless *v* is *NULL*, in which - case *name* is deleted from the sys module. Returns ``0`` on success, ``-1`` - on error. - -.. cfunction:: void PySys_ResetWarnOptions(void) - - Reset :data:`sys.warnoptions` to an empty list. - -.. cfunction:: void PySys_AddWarnOption(char *s) - - Append *s* to :data:`sys.warnoptions`. - -.. cfunction:: void PySys_SetPath(char *path) - - Set :data:`sys.path` to a list object of paths found in *path* which should - be a list of paths separated with the platform's search path delimiter - (``:`` on Unix, ``;`` on Windows). - -.. cfunction:: void PySys_WriteStdout(const char *format, ...) - - Write the output string described by *format* to :data:`sys.stdout`. No - exceptions are raised, even if truncation occurs (see below). - - *format* should limit the total size of the formatted output string to - 1000 bytes or less -- after 1000 bytes, the output string is truncated. - In particular, this means that no unrestricted "%s" formats should occur; - these should be limited using "%.s" where is a decimal number - calculated so that plus the maximum size of other formatted text does not - exceed 1000 bytes. Also watch out for "%f", which can print hundreds of - digits for very large numbers. - - If a problem occurs, or :data:`sys.stdout` is unset, the formatted message - is written to the real (C level) *stdout*. - -.. cfunction:: void PySys_WriteStderr(const char *format, ...) - - As above, but write to :data:`sys.stderr` or *stderr* instead. - - -.. _processcontrol: - -Process Control -=============== - - -.. cfunction:: void Py_FatalError(const char *message) - - .. index:: single: abort() - - Print a fatal error message and kill the process. No cleanup is performed. - This function should only be invoked when a condition is detected that would - make it dangerous to continue using the Python interpreter; e.g., when the - object administration appears to be corrupted. On Unix, the standard C library - function :cfunc:`abort` is called which will attempt to produce a :file:`core` - file. - - -.. cfunction:: void Py_Exit(int status) - - .. index:: - single: Py_Finalize() - single: exit() - - Exit the current process. This calls :cfunc:`Py_Finalize` and then calls the - standard C library function ``exit(status)``. - - -.. cfunction:: int Py_AtExit(void (*func) ()) - - .. index:: - single: Py_Finalize() - single: cleanup functions - - Register a cleanup function to be called by :cfunc:`Py_Finalize`. The cleanup - function will be called with no arguments and should return no value. At most - 32 cleanup functions can be registered. When the registration is successful, - :cfunc:`Py_AtExit` returns ``0``; on failure, it returns ``-1``. The cleanup - function registered last is called first. Each cleanup function will be called - at most once. Since Python's internal finalization will have completed before - the cleanup function, no Python APIs should be called by *func*. - - -.. _importing: - -Importing Modules -================= - - -.. cfunction:: PyObject* PyImport_ImportModule(const char *name) - - .. index:: - single: package variable; __all__ - single: __all__ (package variable) - single: modules (in module sys) - - This is a simplified interface to :cfunc:`PyImport_ImportModuleEx` below, - leaving the *globals* and *locals* arguments set to *NULL* and *level* set - to 0. When the *name* - argument contains a dot (when it specifies a submodule of a package), the - *fromlist* argument is set to the list ``['*']`` so that the return value is the - named module rather than the top-level package containing it as would otherwise - be the case. (Unfortunately, this has an additional side effect when *name* in - fact specifies a subpackage instead of a submodule: the submodules specified in - the package's ``__all__`` variable are loaded.) Return a new reference to the - imported module, or *NULL* with an exception set on failure. Before Python 2.4, - the module may still be created in the failure case --- examine ``sys.modules`` - to find out. Starting with Python 2.4, a failing import of a module no longer - leaves the module in ``sys.modules``. - - -.. cfunction:: PyObject* PyImport_ImportModuleNoBlock(const char *name) - - This version of :cfunc:`PyImport_ImportModule` does not block. It's intended - to be used in C functions that import other modules to execute a function. - The import may block if another thread holds the import lock. The function - :cfunc:`PyImport_ImportModuleNoBlock` never blocks. It first tries to fetch - the module from sys.modules and falls back to :cfunc:`PyImport_ImportModule` - unless the lock is held, in which case the function will raise an - :exc:`ImportError`. - - -.. cfunction:: PyObject* PyImport_ImportModuleEx(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist) - - .. index:: builtin: __import__ - - Import a module. This is best described by referring to the built-in Python - function :func:`__import__`, as the standard :func:`__import__` function calls - this function directly. - - The return value is a new reference to the imported module or top-level package, - or *NULL* with an exception set on failure (before Python 2.4, the module may - still be created in this case). Like for :func:`__import__`, the return value - when a submodule of a package was requested is normally the top-level package, - unless a non-empty *fromlist* was given. - - Failing imports remove incomplete module objects, like with - :cfunc:`PyImport_ImportModule`. - - -.. cfunction:: PyObject* PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level) - - Import a module. This is best described by referring to the built-in Python - function :func:`__import__`, as the standard :func:`__import__` function calls - this function directly. - - The return value is a new reference to the imported module or top-level package, - or *NULL* with an exception set on failure. Like for :func:`__import__`, - the return value when a submodule of a package was requested is normally the - top-level package, unless a non-empty *fromlist* was given. - - -.. cfunction:: PyObject* PyImport_Import(PyObject *name) - - This is a higher-level interface that calls the current "import hook - function" (with an explicit *level* of 0, meaning absolute import). It - invokes the :func:`__import__` function from the ``__builtins__`` of the - current globals. This means that the import is done using whatever import - hooks are installed in the current environment. - - -.. cfunction:: PyObject* PyImport_ReloadModule(PyObject *m) - - Reload a module. Return a new reference to the reloaded module, or *NULL* with - an exception set on failure (the module still exists in this case). - - -.. cfunction:: PyObject* PyImport_AddModule(const char *name) - - Return the module object corresponding to a module name. The *name* argument - may be of the form ``package.module``. First check the modules dictionary if - there's one there, and if not, create a new one and insert it in the modules - dictionary. Return *NULL* with an exception set on failure. - - .. note:: - - This function does not load or import the module; if the module wasn't already - loaded, you will get an empty module object. Use :cfunc:`PyImport_ImportModule` - or one of its variants to import a module. Package structures implied by a - dotted name for *name* are not created if not already present. - - -.. cfunction:: PyObject* PyImport_ExecCodeModule(char *name, PyObject *co) - - .. index:: builtin: compile - - Given a module name (possibly of the form ``package.module``) and a code object - read from a Python bytecode file or obtained from the built-in function - :func:`compile`, load the module. Return a new reference to the module object, - or *NULL* with an exception set if an error occurred. Before Python 2.4, the - module could still be created in error cases. Starting with Python 2.4, *name* - is removed from :attr:`sys.modules` in error cases, and even if *name* was already - in :attr:`sys.modules` on entry to :cfunc:`PyImport_ExecCodeModule`. Leaving - incompletely initialized modules in :attr:`sys.modules` is dangerous, as imports of - such modules have no way to know that the module object is an unknown (and - probably damaged with respect to the module author's intents) state. - - This function will reload the module if it was already imported. See - :cfunc:`PyImport_ReloadModule` for the intended way to reload a module. - - If *name* points to a dotted name of the form ``package.module``, any package - structures not already created will still not be created. - - -.. cfunction:: long PyImport_GetMagicNumber() - - Return the magic number for Python bytecode files (a.k.a. :file:`.pyc` and - :file:`.pyo` files). The magic number should be present in the first four bytes - of the bytecode file, in little-endian byte order. - - -.. cfunction:: PyObject* PyImport_GetModuleDict() - - Return the dictionary used for the module administration (a.k.a. - ``sys.modules``). Note that this is a per-interpreter variable. - - -.. cfunction:: void _PyImport_Init() - - Initialize the import mechanism. For internal use only. - - -.. cfunction:: void PyImport_Cleanup() - - Empty the module table. For internal use only. - - -.. cfunction:: void _PyImport_Fini() - - Finalize the import mechanism. For internal use only. - - -.. cfunction:: PyObject* _PyImport_FindExtension(char *, char *) - - For internal use only. - - -.. cfunction:: PyObject* _PyImport_FixupExtension(char *, char *) - - For internal use only. - - -.. cfunction:: int PyImport_ImportFrozenModule(char *name) - - Load a frozen module named *name*. Return ``1`` for success, ``0`` if the - module is not found, and ``-1`` with an exception set if the initialization - failed. To access the imported module on a successful load, use - :cfunc:`PyImport_ImportModule`. (Note the misnomer --- this function would - reload the module if it was already imported.) - - -.. ctype:: struct _frozen - - .. index:: single: freeze utility - - This is the structure type definition for frozen module descriptors, as - generated by the :program:`freeze` utility (see :file:`Tools/freeze/` in the - Python source distribution). Its definition, found in :file:`Include/import.h`, - is:: - - struct _frozen { - char *name; - unsigned char *code; - int size; - }; - - -.. cvar:: struct _frozen* PyImport_FrozenModules - - This pointer is initialized to point to an array of :ctype:`struct _frozen` - records, terminated by one whose members are all *NULL* or zero. When a frozen - module is imported, it is searched in this table. Third-party code could play - tricks with this to provide a dynamically created collection of frozen modules. - - -.. cfunction:: int PyImport_AppendInittab(char *name, void (*initfunc)(void)) - - Add a single module to the existing table of built-in modules. This is a - convenience wrapper around :cfunc:`PyImport_ExtendInittab`, returning ``-1`` if - the table could not be extended. The new module can be imported by the name - *name*, and uses the function *initfunc* as the initialization function called - on the first attempted import. This should be called before - :cfunc:`Py_Initialize`. - - -.. ctype:: struct _inittab - - Structure describing a single entry in the list of built-in modules. Each of - these structures gives the name and initialization function for a module built - into the interpreter. Programs which embed Python may use an array of these - structures in conjunction with :cfunc:`PyImport_ExtendInittab` to provide - additional built-in modules. The structure is defined in - :file:`Include/import.h` as:: - - struct _inittab { - char *name; - void (*initfunc)(void); - }; - - -.. cfunction:: int PyImport_ExtendInittab(struct _inittab *newtab) - - Add a collection of modules to the table of built-in modules. The *newtab* - array must end with a sentinel entry which contains *NULL* for the :attr:`name` - field; failure to provide the sentinel value can result in a memory fault. - Returns ``0`` on success or ``-1`` if insufficient memory could be allocated to - extend the internal table. In the event of failure, no modules are added to the - internal table. This should be called before :cfunc:`Py_Initialize`. - - -.. _marshalling-utils: - -Data marshalling support -======================== - -These routines allow C code to work with serialized objects using the same data -format as the :mod:`marshal` module. There are functions to write data into the -serialization format, and additional functions that can be used to read the data -back. Files used to store marshalled data must be opened in binary mode. - -Numeric values are stored with the least significant byte first. - -The module supports two versions of the data format: version 0 is the historical -version, version 1 (new in Python 2.4) shares interned strings in the file, and -upon unmarshalling. *Py_MARSHAL_VERSION* indicates the current file format -(currently 1). - - -.. cfunction:: void PyMarshal_WriteLongToFile(long value, FILE *file, int version) - - Marshal a :ctype:`long` integer, *value*, to *file*. This will only write the - least-significant 32 bits of *value*; regardless of the size of the native - :ctype:`long` type. *version* indicates the file format. - - -.. cfunction:: void PyMarshal_WriteObjectToFile(PyObject *value, FILE *file, int version) - - Marshal a Python object, *value*, to *file*. - *version* indicates the file format. - - -.. cfunction:: PyObject* PyMarshal_WriteObjectToString(PyObject *value, int version) - - Return a string object containing the marshalled representation of *value*. - *version* indicates the file format. - - -The following functions allow marshalled values to be read back in. - -XXX What about error detection? It appears that reading past the end of the -file will always result in a negative numeric value (where that's relevant), but -it's not clear that negative values won't be handled properly when there's no -error. What's the right way to tell? Should only non-negative values be written -using these routines? - - -.. cfunction:: long PyMarshal_ReadLongFromFile(FILE *file) - - Return a C :ctype:`long` from the data stream in a :ctype:`FILE\*` opened for - reading. Only a 32-bit value can be read in using this function, regardless of - the native size of :ctype:`long`. - - -.. cfunction:: int PyMarshal_ReadShortFromFile(FILE *file) - - Return a C :ctype:`short` from the data stream in a :ctype:`FILE\*` opened for - reading. Only a 16-bit value can be read in using this function, regardless of - the native size of :ctype:`short`. - - -.. cfunction:: PyObject* PyMarshal_ReadObjectFromFile(FILE *file) - - Return a Python object from the data stream in a :ctype:`FILE\*` opened for - reading. On error, sets the appropriate exception (:exc:`EOFError` or - :exc:`TypeError`) and returns *NULL*. - - -.. cfunction:: PyObject* PyMarshal_ReadLastObjectFromFile(FILE *file) - - Return a Python object from the data stream in a :ctype:`FILE\*` opened for - reading. Unlike :cfunc:`PyMarshal_ReadObjectFromFile`, this function assumes - that no further objects will be read from the file, allowing it to aggressively - load file data into memory so that the de-serialization can operate from data in - memory rather than reading a byte at a time from the file. Only use these - variant if you are certain that you won't be reading anything else from the - file. On error, sets the appropriate exception (:exc:`EOFError` or - :exc:`TypeError`) and returns *NULL*. - - -.. cfunction:: PyObject* PyMarshal_ReadObjectFromString(char *string, Py_ssize_t len) - - Return a Python object from the data stream in a character buffer containing - *len* bytes pointed to by *string*. On error, sets the appropriate exception - (:exc:`EOFError` or :exc:`TypeError`) and returns *NULL*. - - -.. _arg-parsing: - -Parsing arguments and building values -===================================== - -These functions are useful when creating your own extensions functions and -methods. Additional information and examples are available in -:ref:`extending-index`. - -The first three of these functions described, :cfunc:`PyArg_ParseTuple`, -:cfunc:`PyArg_ParseTupleAndKeywords`, and :cfunc:`PyArg_Parse`, all use *format -strings* which are used to tell the function about the expected arguments. The -format strings use the same syntax for each of these functions. - -A format string consists of zero or more "format units." A format unit -describes one Python object; it is usually a single character or a parenthesized -sequence of format units. With a few exceptions, a format unit that is not a -parenthesized sequence normally corresponds to a single address argument to -these functions. In the following description, the quoted form is the format -unit; the entry in (round) parentheses is the Python object type that matches -the format unit; and the entry in [square] brackets is the type of the C -variable(s) whose address should be passed. - -``s`` (string or Unicode object) [const char \*] - Convert a Python string or Unicode object to a C pointer to a character string. - You must not provide storage for the string itself; a pointer to an existing - string is stored into the character pointer variable whose address you pass. - The C string is NUL-terminated. The Python string must not contain embedded NUL - bytes; if it does, a :exc:`TypeError` exception is raised. Unicode objects are - converted to C strings using the default encoding. If this conversion fails, a - :exc:`UnicodeError` is raised. - -``s#`` (string, Unicode or any read buffer compatible object) [const char \*, int] - This variant on ``s`` stores into two C variables, the first one a pointer to a - character string, the second one its length. In this case the Python string may - contain embedded null bytes. Unicode objects pass back a pointer to the default - encoded string version of the object if such a conversion is possible. All - other read-buffer compatible objects pass back a reference to the raw internal - data representation. - -``y`` (bytes object) [const char \*] - This variant on ``s`` convert a Python bytes object to a C pointer to a - character string. The bytes object must not contain embedded NUL bytes; if it - does, a :exc:`TypeError` exception is raised. - -``y#`` (bytes object) [const char \*, int] - This variant on ``s#`` stores into two C variables, the first one a pointer to a - character string, the second one its length. This only accepts bytes objects. - -``z`` (string or ``None``) [const char \*] - Like ``s``, but the Python object may also be ``None``, in which case the C - pointer is set to *NULL*. - -``z#`` (string or ``None`` or any read buffer compatible object) [const char \*, int] - This is to ``s#`` as ``z`` is to ``s``. - -``u`` (Unicode object) [Py_UNICODE \*] - Convert a Python Unicode object to a C pointer to a NUL-terminated buffer of - 16-bit Unicode (UTF-16) data. As with ``s``, there is no need to provide - storage for the Unicode data buffer; a pointer to the existing Unicode data is - stored into the :ctype:`Py_UNICODE` pointer variable whose address you pass. - -``u#`` (Unicode object) [Py_UNICODE \*, int] - This variant on ``u`` stores into two C variables, the first one a pointer to a - Unicode data buffer, the second one its length. Non-Unicode objects are handled - by interpreting their read-buffer pointer as pointer to a :ctype:`Py_UNICODE` - array. - -``Z`` (Unicode or ``None``) [Py_UNICODE \*] - Like ``s``, but the Python object may also be ``None``, in which case the C - pointer is set to *NULL*. - -``Z#`` (Unicode or ``None``) [Py_UNICODE \*, int] - This is to ``u#`` as ``Z`` is to ``u``. - -``es`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] - This variant on ``s`` is used for encoding Unicode and objects convertible to - Unicode into a character buffer. It only works for encoded data without embedded - NUL bytes. - - This format requires two arguments. The first is only used as input, and - must be a :ctype:`const char\*` which points to the name of an encoding as a - NUL-terminated string, or *NULL*, in which case the default encoding is used. - An exception is raised if the named encoding is not known to Python. The - second argument must be a :ctype:`char\*\*`; the value of the pointer it - references will be set to a buffer with the contents of the argument text. - The text will be encoded in the encoding specified by the first argument. - - :cfunc:`PyArg_ParseTuple` will allocate a buffer of the needed size, copy the - encoded data into this buffer and adjust *\*buffer* to reference the newly - allocated storage. The caller is responsible for calling :cfunc:`PyMem_Free` to - free the allocated buffer after use. - -``et`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] - Same as ``es`` except that 8-bit string objects are passed through without - recoding them. Instead, the implementation assumes that the string object uses - the encoding passed in as parameter. - -``es#`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer, int \*buffer_length] - This variant on ``s#`` is used for encoding Unicode and objects convertible to - Unicode into a character buffer. Unlike the ``es`` format, this variant allows - input data which contains NUL characters. - - It requires three arguments. The first is only used as input, and must be a - :ctype:`const char\*` which points to the name of an encoding as a - NUL-terminated string, or *NULL*, in which case the default encoding is used. - An exception is raised if the named encoding is not known to Python. The - second argument must be a :ctype:`char\*\*`; the value of the pointer it - references will be set to a buffer with the contents of the argument text. - The text will be encoded in the encoding specified by the first argument. - The third argument must be a pointer to an integer; the referenced integer - will be set to the number of bytes in the output buffer. - - There are two modes of operation: - - If *\*buffer* points a *NULL* pointer, the function will allocate a buffer of - the needed size, copy the encoded data into this buffer and set *\*buffer* to - reference the newly allocated storage. The caller is responsible for calling - :cfunc:`PyMem_Free` to free the allocated buffer after usage. - - If *\*buffer* points to a non-*NULL* pointer (an already allocated buffer), - :cfunc:`PyArg_ParseTuple` will use this location as the buffer and interpret the - initial value of *\*buffer_length* as the buffer size. It will then copy the - encoded data into the buffer and NUL-terminate it. If the buffer is not large - enough, a :exc:`ValueError` will be set. - - In both cases, *\*buffer_length* is set to the length of the encoded data - without the trailing NUL byte. - -``et#`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] - Same as ``es#`` except that string objects are passed through without recoding - them. Instead, the implementation assumes that the string object uses the - encoding passed in as parameter. - -``b`` (integer) [char] - Convert a Python integer to a tiny int, stored in a C :ctype:`char`. - -``B`` (integer) [unsigned char] - Convert a Python integer to a tiny int without overflow checking, stored in a C - :ctype:`unsigned char`. - -``h`` (integer) [short int] - Convert a Python integer to a C :ctype:`short int`. - -``H`` (integer) [unsigned short int] - Convert a Python integer to a C :ctype:`unsigned short int`, without overflow - checking. - -``i`` (integer) [int] - Convert a Python integer to a plain C :ctype:`int`. - -``I`` (integer) [unsigned int] - Convert a Python integer to a C :ctype:`unsigned int`, without overflow - checking. - -``l`` (integer) [long int] - Convert a Python integer to a C :ctype:`long int`. - -``k`` (integer) [unsigned long] - Convert a Python integer to a C :ctype:`unsigned long` without - overflow checking. - -``L`` (integer) [PY_LONG_LONG] - Convert a Python integer to a C :ctype:`long long`. This format is only - available on platforms that support :ctype:`long long` (or :ctype:`_int64` on - Windows). - -``K`` (integer) [unsigned PY_LONG_LONG] - Convert a Python integer to a C :ctype:`unsigned long long` - without overflow checking. This format is only available on platforms that - support :ctype:`unsigned long long` (or :ctype:`unsigned _int64` on Windows). - -``n`` (integer) [Py_ssize_t] - Convert a Python integer to a C :ctype:`Py_ssize_t`. - -``c`` (string of length 1) [char] - Convert a Python character, represented as a string of length 1, to a C - :ctype:`char`. - -``f`` (float) [float] - Convert a Python floating point number to a C :ctype:`float`. - -``d`` (float) [double] - Convert a Python floating point number to a C :ctype:`double`. - -``D`` (complex) [Py_complex] - Convert a Python complex number to a C :ctype:`Py_complex` structure. - -``O`` (object) [PyObject \*] - Store a Python object (without any conversion) in a C object pointer. The C - program thus receives the actual object that was passed. The object's reference - count is not increased. The pointer stored is not *NULL*. - -``O!`` (object) [*typeobject*, PyObject \*] - Store a Python object in a C object pointer. This is similar to ``O``, but - takes two C arguments: the first is the address of a Python type object, the - second is the address of the C variable (of type :ctype:`PyObject\*`) into which - the object pointer is stored. If the Python object does not have the required - type, :exc:`TypeError` is raised. - -``O&`` (object) [*converter*, *anything*] - Convert a Python object to a C variable through a *converter* function. This - takes two arguments: the first is a function, the second is the address of a C - variable (of arbitrary type), converted to :ctype:`void \*`. The *converter* - function in turn is called as follows:: - - status = converter(object, address); - - where *object* is the Python object to be converted and *address* is the - :ctype:`void\*` argument that was passed to the :cfunc:`PyArg_Parse\*` function. - The returned *status* should be ``1`` for a successful conversion and ``0`` if - the conversion has failed. When the conversion fails, the *converter* function - should raise an exception. - -``S`` (string) [PyStringObject \*] - Like ``O`` but requires that the Python object is a string object. Raises - :exc:`TypeError` if the object is not a string object. The C variable may also - be declared as :ctype:`PyObject\*`. - -``U`` (Unicode string) [PyUnicodeObject \*] - Like ``O`` but requires that the Python object is a Unicode object. Raises - :exc:`TypeError` if the object is not a Unicode object. The C variable may also - be declared as :ctype:`PyObject\*`. - -``t#`` (read-only character buffer) [char \*, int] - Like ``s#``, but accepts any object which implements the read-only buffer - interface. The :ctype:`char\*` variable is set to point to the first byte of - the buffer, and the :ctype:`int` is set to the length of the buffer. Only - single-segment buffer objects are accepted; :exc:`TypeError` is raised for all - others. - -``w`` (read-write character buffer) [char \*] - Similar to ``s``, but accepts any object which implements the read-write buffer - interface. The caller must determine the length of the buffer by other means, - or use ``w#`` instead. Only single-segment buffer objects are accepted; - :exc:`TypeError` is raised for all others. - -``w#`` (read-write character buffer) [char \*, int] - Like ``s#``, but accepts any object which implements the read-write buffer - interface. The :ctype:`char \*` variable is set to point to the first byte of - the buffer, and the :ctype:`int` is set to the length of the buffer. Only - single-segment buffer objects are accepted; :exc:`TypeError` is raised for all - others. - -``(items)`` (tuple) [*matching-items*] - The object must be a Python sequence whose length is the number of format units - in *items*. The C arguments must correspond to the individual format units in - *items*. Format units for sequences may be nested. - -It is possible to pass "long" integers (integers whose value exceeds the -platform's :const:`LONG_MAX`) however no proper range checking is done --- the -most significant bits are silently truncated when the receiving field is too -small to receive the value (actually, the semantics are inherited from downcasts -in C --- your mileage may vary). - -A few other characters have a meaning in a format string. These may not occur -inside nested parentheses. They are: - -``|`` - Indicates that the remaining arguments in the Python argument list are optional. - The C variables corresponding to optional arguments should be initialized to - their default value --- when an optional argument is not specified, - :cfunc:`PyArg_ParseTuple` does not touch the contents of the corresponding C - variable(s). - -``:`` - The list of format units ends here; the string after the colon is used as the - function name in error messages (the "associated value" of the exception that - :cfunc:`PyArg_ParseTuple` raises). - -``;`` - The list of format units ends here; the string after the semicolon is used as - the error message *instead* of the default error message. Clearly, ``:`` and - ``;`` mutually exclude each other. - -Note that any Python object references which are provided to the caller are -*borrowed* references; do not decrement their reference count! - -Additional arguments passed to these functions must be addresses of variables -whose type is determined by the format string; these are used to store values -from the input tuple. There are a few cases, as described in the list of format -units above, where these parameters are used as input values; they should match -what is specified for the corresponding format unit in that case. - -For the conversion to succeed, the *arg* object must match the format and the -format must be exhausted. On success, the :cfunc:`PyArg_Parse\*` functions -return true, otherwise they return false and raise an appropriate exception. - - -.. cfunction:: int PyArg_ParseTuple(PyObject *args, const char *format, ...) - - Parse the parameters of a function that takes only positional parameters into - local variables. Returns true on success; on failure, it returns false and - raises the appropriate exception. - - -.. cfunction:: int PyArg_VaParse(PyObject *args, const char *format, va_list vargs) - - Identical to :cfunc:`PyArg_ParseTuple`, except that it accepts a va_list rather - than a variable number of arguments. - - -.. cfunction:: int PyArg_ParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *keywords[], ...) - - Parse the parameters of a function that takes both positional and keyword - parameters into local variables. Returns true on success; on failure, it - returns false and raises the appropriate exception. - - -.. cfunction:: int PyArg_VaParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *keywords[], va_list vargs) - - Identical to :cfunc:`PyArg_ParseTupleAndKeywords`, except that it accepts a - va_list rather than a variable number of arguments. - - -.. XXX deprecated, will be removed -.. cfunction:: int PyArg_Parse(PyObject *args, const char *format, ...) - - Function used to deconstruct the argument lists of "old-style" functions --- - these are functions which use the :const:`METH_OLDARGS` parameter parsing - method. This is not recommended for use in parameter parsing in new code, and - most code in the standard interpreter has been modified to no longer use this - for that purpose. It does remain a convenient way to decompose other tuples, - however, and may continue to be used for that purpose. - - -.. cfunction:: int PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...) - - A simpler form of parameter retrieval which does not use a format string to - specify the types of the arguments. Functions which use this method to retrieve - their parameters should be declared as :const:`METH_VARARGS` in function or - method tables. The tuple containing the actual parameters should be passed as - *args*; it must actually be a tuple. The length of the tuple must be at least - *min* and no more than *max*; *min* and *max* may be equal. Additional - arguments must be passed to the function, each of which should be a pointer to a - :ctype:`PyObject\*` variable; these will be filled in with the values from - *args*; they will contain borrowed references. The variables which correspond - to optional parameters not given by *args* will not be filled in; these should - be initialized by the caller. This function returns true on success and false if - *args* is not a tuple or contains the wrong number of elements; an exception - will be set if there was a failure. - - This is an example of the use of this function, taken from the sources for the - :mod:`_weakref` helper module for weak references:: - - static PyObject * - weakref_ref(PyObject *self, PyObject *args) - { - PyObject *object; - PyObject *callback = NULL; - PyObject *result = NULL; - - if (PyArg_UnpackTuple(args, "ref", 1, 2, &object, &callback)) { - result = PyWeakref_NewRef(object, callback); - } - return result; - } - - The call to :cfunc:`PyArg_UnpackTuple` in this example is entirely equivalent to - this call to :cfunc:`PyArg_ParseTuple`:: - - PyArg_ParseTuple(args, "O|O:ref", &object, &callback) - - -.. cfunction:: PyObject* Py_BuildValue(const char *format, ...) - - Create a new value based on a format string similar to those accepted by the - :cfunc:`PyArg_Parse\*` family of functions and a sequence of values. Returns - the value or *NULL* in the case of an error; an exception will be raised if - *NULL* is returned. - - :cfunc:`Py_BuildValue` does not always build a tuple. It builds a tuple only if - its format string contains two or more format units. If the format string is - empty, it returns ``None``; if it contains exactly one format unit, it returns - whatever object is described by that format unit. To force it to return a tuple - of size 0 or one, parenthesize the format string. - - When memory buffers are passed as parameters to supply data to build objects, as - for the ``s`` and ``s#`` formats, the required data is copied. Buffers provided - by the caller are never referenced by the objects created by - :cfunc:`Py_BuildValue`. In other words, if your code invokes :cfunc:`malloc` - and passes the allocated memory to :cfunc:`Py_BuildValue`, your code is - responsible for calling :cfunc:`free` for that memory once - :cfunc:`Py_BuildValue` returns. - - In the following description, the quoted form is the format unit; the entry in - (round) parentheses is the Python object type that the format unit will return; - and the entry in [square] brackets is the type of the C value(s) to be passed. - - The characters space, tab, colon and comma are ignored in format strings (but - not within format units such as ``s#``). This can be used to make long format - strings a tad more readable. - - ``s`` (string) [char \*] - Convert a null-terminated C string to a Python object. If the C string pointer - is *NULL*, ``None`` is used. - - ``s#`` (string) [char \*, int] - Convert a C string and its length to a Python object. If the C string pointer - is *NULL*, the length is ignored and ``None`` is returned. - - ``z`` (string or ``None``) [char \*] - Same as ``s``. - - ``z#`` (string or ``None``) [char \*, int] - Same as ``s#``. - - ``u`` (Unicode string) [Py_UNICODE \*] - Convert a null-terminated buffer of Unicode (UCS-2 or UCS-4) data to a Python - Unicode object. If the Unicode buffer pointer is *NULL*, ``None`` is returned. - - ``u#`` (Unicode string) [Py_UNICODE \*, int] - Convert a Unicode (UCS-2 or UCS-4) data buffer and its length to a Python - Unicode object. If the Unicode buffer pointer is *NULL*, the length is ignored - and ``None`` is returned. - - ``U`` (string) [char \*] - Convert a null-terminated C string to a Python unicode object. If the C string - pointer is *NULL*, ``None`` is used. - - ``U#`` (string) [char \*, int] - Convert a C string and its length to a Python unicode object. If the C string - pointer is *NULL*, the length is ignored and ``None`` is returned. - - ``i`` (integer) [int] - Convert a plain C :ctype:`int` to a Python integer object. - - ``b`` (integer) [char] - Convert a plain C :ctype:`char` to a Python integer object. - - ``h`` (integer) [short int] - Convert a plain C :ctype:`short int` to a Python integer object. - - ``l`` (integer) [long int] - Convert a C :ctype:`long int` to a Python integer object. - - ``B`` (integer) [unsigned char] - Convert a C :ctype:`unsigned char` to a Python integer object. - - ``H`` (integer) [unsigned short int] - Convert a C :ctype:`unsigned short int` to a Python integer object. - - ``I`` (integer/long) [unsigned int] - Convert a C :ctype:`unsigned int` to a Python long integer object. - - ``k`` (integer/long) [unsigned long] - Convert a C :ctype:`unsigned long` to a Python long integer object. - - ``L`` (long) [PY_LONG_LONG] - Convert a C :ctype:`long long` to a Python integer object. Only available - on platforms that support :ctype:`long long`. - - ``K`` (long) [unsigned PY_LONG_LONG] - Convert a C :ctype:`unsigned long long` to a Python integer object. Only - available on platforms that support :ctype:`unsigned long long`. - - ``n`` (int) [Py_ssize_t] - Convert a C :ctype:`Py_ssize_t` to a Python integer. - - ``c`` (string of length 1) [char] - Convert a C :ctype:`int` representing a character to a Python string of length - 1. - - ``d`` (float) [double] - Convert a C :ctype:`double` to a Python floating point number. - - ``f`` (float) [float] - Same as ``d``. - - ``D`` (complex) [Py_complex \*] - Convert a C :ctype:`Py_complex` structure to a Python complex number. - - ``O`` (object) [PyObject \*] - Pass a Python object untouched (except for its reference count, which is - incremented by one). If the object passed in is a *NULL* pointer, it is assumed - that this was caused because the call producing the argument found an error and - set an exception. Therefore, :cfunc:`Py_BuildValue` will return *NULL* but won't - raise an exception. If no exception has been raised yet, :exc:`SystemError` is - set. - - ``S`` (object) [PyObject \*] - Same as ``O``. - - ``N`` (object) [PyObject \*] - Same as ``O``, except it doesn't increment the reference count on the object. - Useful when the object is created by a call to an object constructor in the - argument list. - - ``O&`` (object) [*converter*, *anything*] - Convert *anything* to a Python object through a *converter* function. The - function is called with *anything* (which should be compatible with :ctype:`void - \*`) as its argument and should return a "new" Python object, or *NULL* if an - error occurred. - - ``(items)`` (tuple) [*matching-items*] - Convert a sequence of C values to a Python tuple with the same number of items. - - ``[items]`` (list) [*matching-items*] - Convert a sequence of C values to a Python list with the same number of items. - - ``{items}`` (dictionary) [*matching-items*] - Convert a sequence of C values to a Python dictionary. Each pair of consecutive - C values adds one item to the dictionary, serving as key and value, - respectively. - - If there is an error in the format string, the :exc:`SystemError` exception is - set and *NULL* returned. - - -.. _string-conversion: - -String conversion and formatting -================================ - -Functions for number conversion and formatted string output. - - -.. cfunction:: int PyOS_snprintf(char *str, size_t size, const char *format, ...) - - Output not more than *size* bytes to *str* according to the format string - *format* and the extra arguments. See the Unix man page :manpage:`snprintf(2)`. - - -.. cfunction:: int PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va) - - Output not more than *size* bytes to *str* according to the format string - *format* and the variable argument list *va*. Unix man page - :manpage:`vsnprintf(2)`. - -:cfunc:`PyOS_snprintf` and :cfunc:`PyOS_vsnprintf` wrap the Standard C library -functions :cfunc:`snprintf` and :cfunc:`vsnprintf`. Their purpose is to -guarantee consistent behavior in corner cases, which the Standard C functions do -not. - -The wrappers ensure that *str*[*size*-1] is always ``'\0'`` upon return. They -never write more than *size* bytes (including the trailing ``'\0'``) into str. -Both functions require that ``str != NULL``, ``size > 0`` and ``format != -NULL``. - -If the platform doesn't have :cfunc:`vsnprintf` and the buffer size needed to -avoid truncation exceeds *size* by more than 512 bytes, Python aborts with a -*Py_FatalError*. - -The return value (*rv*) for these functions should be interpreted as follows: - -* When ``0 <= rv < size``, the output conversion was successful and *rv* - characters were written to *str* (excluding the trailing ``'\0'`` byte at - *str*[*rv*]). - -* When ``rv >= size``, the output conversion was truncated and a buffer with - ``rv + 1`` bytes would have been needed to succeed. *str*[*size*-1] is ``'\0'`` - in this case. - -* When ``rv < 0``, "something bad happened." *str*[*size*-1] is ``'\0'`` in - this case too, but the rest of *str* is undefined. The exact cause of the error - depends on the underlying platform. - -The following functions provide locale-independent string to number conversions. - - -.. cfunction:: double PyOS_ascii_strtod(const char *nptr, char **endptr) - - Convert a string to a :ctype:`double`. This function behaves like the Standard C - function :cfunc:`strtod` does in the C locale. It does this without changing the - current locale, since that would not be thread-safe. - - :cfunc:`PyOS_ascii_strtod` should typically be used for reading configuration - files or other non-user input that should be locale independent. - - See the Unix man page :manpage:`strtod(2)` for details. - - -.. cfunction:: char * PyOS_ascii_formatd(char *buffer, size_t buf_len, const char *format, double d) - - Convert a :ctype:`double` to a string using the ``'.'`` as the decimal - separator. *format* is a :cfunc:`printf`\ -style format string specifying the - number format. Allowed conversion characters are ``'e'``, ``'E'``, ``'f'``, - ``'F'``, ``'g'`` and ``'G'``. - - The return value is a pointer to *buffer* with the converted string or NULL if - the conversion failed. - - -.. cfunction:: double PyOS_ascii_atof(const char *nptr) - - Convert a string to a :ctype:`double` in a locale-independent way. - - See the Unix man page :manpage:`atof(2)` for details. - - -.. cfunction:: char * PyOS_stricmp(char *s1, char *s2) - - Case insensitive comparsion of strings. The functions works almost - identical to :cfunc:`strcmp` except that it ignores the case. - - -.. cfunction:: char * PyOS_strnicmp(char *s1, char *s2, Py_ssize_t size) - - Case insensitive comparsion of strings. The functions works almost - identical to :cfunc:`strncmp` except that it ignores the case. - - -.. _reflection: - -Reflection -========== - -.. cfunction:: PyObject* PyEval_GetBuiltins() - - Return a dictionary of the builtins in the current execution frame, - or the interpreter of the thread state if no frame is currently executing. - - -.. cfunction:: PyObject* PyEval_GetLocals() - - Return a dictionary of the local variables in the current execution frame, - or *NULL* if no frame is currently executing. - - -.. cfunction:: PyObject* PyEval_GetGlobals() - - Return a dictionary of the global variables in the current execution frame, - or *NULL* if no frame is currently executing. - - -.. cfunction:: PyFrameObject* PyEval_GetFrame() - - Return the current thread state's frame, which is *NULL* if no frame is - currently executing. - - -.. cfunction:: int PyEval_GetRestricted() - - If there is a current frame and it is executing in restricted mode, return true, - otherwise false. - - -.. cfunction:: const char* PyEval_GetFuncName(PyObject *func) - - Return the name of *func* if it is a function, class or instance object, else the - name of *func*\s type. - - -.. cfunction:: const char* PyEval_GetFuncDesc(PyObject *func) - - Return a description string, depending on the type of *func*. - Return values include "()" for functions and methods, " constructor", - " instance", and " object". Concatenated with the result of - :cfunc:`PyEval_GetFuncName`, the result will be a description of - *func*. + sys.rst + import.rst + marshal.rst + arg.rst + conversion.rst + reflection.rst Added: python/branches/py3k/Doc/c-api/weakref.rst ============================================================================== --- (empty file) +++ python/branches/py3k/Doc/c-api/weakref.rst Sun Jan 20 10:30:57 2008 @@ -0,0 +1,62 @@ +.. highlightlang:: c + +.. _weakrefobjects: + +Weak Reference Objects +---------------------- + +Python supports *weak references* as first-class objects. There are two +specific object types which directly implement weak references. The first is a +simple reference object, and the second acts as a proxy for the original object +as much as it can. + + +.. cfunction:: int PyWeakref_Check(ob) + + Return true if *ob* is either a reference or proxy object. + + +.. cfunction:: int PyWeakref_CheckRef(ob) + + Return true if *ob* is a reference object. + + +.. cfunction:: int PyWeakref_CheckProxy(ob) + + Return true if *ob* is a proxy object. + + +.. cfunction:: PyObject* PyWeakref_NewRef(PyObject *ob, PyObject *callback) + + Return a weak reference object for the object *ob*. This will always return + a new reference, but is not guaranteed to create a new object; an existing + reference object may be returned. The second parameter, *callback*, can be a + callable object that receives notification when *ob* is garbage collected; it + should accept a single parameter, which will be the weak reference object + itself. *callback* may also be ``None`` or *NULL*. If *ob* is not a + weakly-referencable object, or if *callback* is not callable, ``None``, or + *NULL*, this will return *NULL* and raise :exc:`TypeError`. + + +.. cfunction:: PyObject* PyWeakref_NewProxy(PyObject *ob, PyObject *callback) + + Return a weak reference proxy object for the object *ob*. This will always + return a new reference, but is not guaranteed to create a new object; an + existing proxy object may be returned. The second parameter, *callback*, can + be a callable object that receives notification when *ob* is garbage + collected; it should accept a single parameter, which will be the weak + reference object itself. *callback* may also be ``None`` or *NULL*. If *ob* + is not a weakly-referencable object, or if *callback* is not callable, + ``None``, or *NULL*, this will return *NULL* and raise :exc:`TypeError`. + + +.. cfunction:: PyObject* PyWeakref_GetObject(PyObject *ref) + + Return the referenced object from a weak reference, *ref*. If the referent is + no longer live, returns ``None``. + + +.. cfunction:: PyObject* PyWeakref_GET_OBJECT(PyObject *ref) + + Similar to :cfunc:`PyWeakref_GetObject`, but implemented as a macro that does no + error checking. From python-3000-checkins at python.org Sun Jan 20 11:45:34 2008 From: python-3000-checkins at python.org (thomas.heller) Date: Sun, 20 Jan 2008 11:45:34 +0100 (CET) Subject: [Python-3000-checkins] r60128 - in python/branches/py3k-ctypes-pep3118: Doc/c-api/abstract.rst Doc/c-api/allocation.rst Doc/c-api/arg.rst Doc/c-api/bool.rst Doc/c-api/buffer.rst Doc/c-api/cell.rst Doc/c-api/cobject.rst Doc/c-api/complex.rst Doc/c-api/concrete.rst Doc/c-api/conversion.rst Doc/c-api/datetime.rst Doc/c-api/descriptor.rst Doc/c-api/dict.rst Doc/c-api/file.rst Doc/c-api/float.rst Doc/c-api/function.rst Doc/c-api/gcsupport.rst Doc/c-api/gen.rst Doc/c-api/import.rst Doc/c-api/iter.rst Doc/c-api/iterator.rst Doc/c-api/list.rst Doc/c-api/long.rst Doc/c-api/mapping.rst Doc/c-api/marshal.rst Doc/c-api/method.rst Doc/c-api/module.rst Doc/c-api/newtypes.rst Doc/c-api/none.rst Doc/c-api/number.rst Doc/c-api/objbuffer.rst Doc/c-api/object.rst Doc/c-api/objimpl.rst Doc/c-api/reflection.rst Doc/c-api/sequence.rst Doc/c-api/set.rst Doc/c-api/slice.rst Doc/c-api/string.rst Doc/c-api/structures.rst Doc/c-api/sys.rst Doc/c-api/tuple.rst Doc/c-api/type.rst Doc/c-api/typeobj.rst Doc/c-api/unicode.rst Doc/c-api/utilities.rst Doc/c-api/weakref.rst Doc/library/collections.rst Doc/library/curses.rst Doc/library/logging.rst Doc/library/mmap.rst Doc/library/optparse.rst Doc/library/os.rst Doc/library/rational.rst Doc/library/socketserver.rst Doc/library/sqlite3.rst Doc/library/threading.rst Doc/library/trace.rst Doc/library/xml.sax.utils.rst Doc/library/zipfile.rst Doc/tools/sphinx-build.py Doc/whatsnew/2.6.rst Lib/SocketServer.py Lib/curses/textpad.py Lib/email/mime/multipart.py Lib/email/test/test_email.py Lib/mailbox.py Lib/pydoc.py Lib/rational.py Lib/subprocess.py Lib/test/crashers/weakref_in_del.py Lib/test/curses_tests.py Lib/test/test_builtin.py Lib/test/test_grammar.py Lib/test/test_mailbox.py Lib/test/test_mmap.py Lib/test/test_os.py Lib/test/test_rational.py Lib/test/test_socket.py Lib/test/test_ssl.py Lib/test/test_subprocess.py Lib/test/test_textwrap.py Lib/test/test_threading_local.py Lib/test/test_xmlrpc.py Lib/test/test_zipfile.py Lib/textwrap.py Lib/tokenize.py Lib/trace.py Lib/zipfile.py Misc/ACKS Misc/NEWS Modules/_sqlite/cursor.c Modules/_sre.c Modules/mmapmodule.c Modules/posixmodule.c Modules/socketmodule.c Objects/complexobject.c Objects/longobject.c Parser/tokenizer.c Python/modsupport.c Python/mystrtoul.c Message-ID: <20080120104534.607201E401D@bag.python.org> Author: thomas.heller Date: Sun Jan 20 11:45:31 2008 New Revision: 60128 Added: python/branches/py3k-ctypes-pep3118/Doc/c-api/allocation.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/allocation.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/arg.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/arg.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/bool.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/bool.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/buffer.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/buffer.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/cell.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/cell.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/cobject.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/cobject.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/complex.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/complex.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/conversion.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/conversion.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/datetime.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/datetime.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/descriptor.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/descriptor.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/dict.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/dict.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/file.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/file.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/float.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/float.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/function.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/function.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/gcsupport.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/gcsupport.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/gen.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/gen.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/import.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/import.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/iter.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/iter.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/iterator.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/iterator.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/list.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/list.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/long.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/long.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/mapping.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/mapping.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/marshal.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/marshal.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/method.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/method.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/module.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/module.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/none.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/none.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/number.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/number.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/objbuffer.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/objbuffer.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/object.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/object.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/objimpl.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/objimpl.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/reflection.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/reflection.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/sequence.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/sequence.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/set.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/set.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/slice.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/slice.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/string.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/string.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/structures.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/structures.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/sys.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/sys.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/tuple.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/tuple.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/type.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/type.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/typeobj.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/typeobj.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/unicode.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/unicode.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/weakref.rst - copied unchanged from r60126, python/branches/py3k/Doc/c-api/weakref.rst python/branches/py3k-ctypes-pep3118/Lib/test/curses_tests.py - copied unchanged from r60126, python/branches/py3k/Lib/test/curses_tests.py Removed: python/branches/py3k-ctypes-pep3118/Doc/c-api/newtypes.rst python/branches/py3k-ctypes-pep3118/Lib/test/crashers/weakref_in_del.py Modified: python/branches/py3k-ctypes-pep3118/ (props changed) python/branches/py3k-ctypes-pep3118/Doc/c-api/abstract.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/concrete.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/utilities.rst python/branches/py3k-ctypes-pep3118/Doc/library/collections.rst python/branches/py3k-ctypes-pep3118/Doc/library/curses.rst python/branches/py3k-ctypes-pep3118/Doc/library/logging.rst python/branches/py3k-ctypes-pep3118/Doc/library/mmap.rst python/branches/py3k-ctypes-pep3118/Doc/library/optparse.rst python/branches/py3k-ctypes-pep3118/Doc/library/os.rst python/branches/py3k-ctypes-pep3118/Doc/library/rational.rst python/branches/py3k-ctypes-pep3118/Doc/library/socketserver.rst python/branches/py3k-ctypes-pep3118/Doc/library/sqlite3.rst python/branches/py3k-ctypes-pep3118/Doc/library/threading.rst python/branches/py3k-ctypes-pep3118/Doc/library/trace.rst python/branches/py3k-ctypes-pep3118/Doc/library/xml.sax.utils.rst python/branches/py3k-ctypes-pep3118/Doc/library/zipfile.rst python/branches/py3k-ctypes-pep3118/Doc/tools/sphinx-build.py python/branches/py3k-ctypes-pep3118/Doc/whatsnew/2.6.rst python/branches/py3k-ctypes-pep3118/Lib/SocketServer.py python/branches/py3k-ctypes-pep3118/Lib/curses/textpad.py python/branches/py3k-ctypes-pep3118/Lib/email/mime/multipart.py python/branches/py3k-ctypes-pep3118/Lib/email/test/test_email.py python/branches/py3k-ctypes-pep3118/Lib/mailbox.py python/branches/py3k-ctypes-pep3118/Lib/pydoc.py python/branches/py3k-ctypes-pep3118/Lib/rational.py python/branches/py3k-ctypes-pep3118/Lib/subprocess.py python/branches/py3k-ctypes-pep3118/Lib/test/test_builtin.py python/branches/py3k-ctypes-pep3118/Lib/test/test_grammar.py python/branches/py3k-ctypes-pep3118/Lib/test/test_mailbox.py python/branches/py3k-ctypes-pep3118/Lib/test/test_mmap.py python/branches/py3k-ctypes-pep3118/Lib/test/test_os.py python/branches/py3k-ctypes-pep3118/Lib/test/test_rational.py python/branches/py3k-ctypes-pep3118/Lib/test/test_socket.py python/branches/py3k-ctypes-pep3118/Lib/test/test_ssl.py python/branches/py3k-ctypes-pep3118/Lib/test/test_subprocess.py python/branches/py3k-ctypes-pep3118/Lib/test/test_textwrap.py python/branches/py3k-ctypes-pep3118/Lib/test/test_threading_local.py python/branches/py3k-ctypes-pep3118/Lib/test/test_xmlrpc.py python/branches/py3k-ctypes-pep3118/Lib/test/test_zipfile.py python/branches/py3k-ctypes-pep3118/Lib/textwrap.py python/branches/py3k-ctypes-pep3118/Lib/tokenize.py python/branches/py3k-ctypes-pep3118/Lib/trace.py python/branches/py3k-ctypes-pep3118/Lib/zipfile.py python/branches/py3k-ctypes-pep3118/Misc/ACKS python/branches/py3k-ctypes-pep3118/Misc/NEWS python/branches/py3k-ctypes-pep3118/Modules/_sqlite/cursor.c python/branches/py3k-ctypes-pep3118/Modules/_sre.c python/branches/py3k-ctypes-pep3118/Modules/mmapmodule.c python/branches/py3k-ctypes-pep3118/Modules/posixmodule.c python/branches/py3k-ctypes-pep3118/Modules/socketmodule.c python/branches/py3k-ctypes-pep3118/Objects/complexobject.c python/branches/py3k-ctypes-pep3118/Objects/longobject.c python/branches/py3k-ctypes-pep3118/Parser/tokenizer.c python/branches/py3k-ctypes-pep3118/Python/modsupport.c python/branches/py3k-ctypes-pep3118/Python/mystrtoul.c Log: Merged revisions 60067,60079,60090,60094,60100,60124-60126 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r60067 | georg.brandl | 2008-01-19 10:24:19 +0100 (Sa, 19 Jan 2008) | 2 lines Fix 3k's sphinx-build.py so that the version detection works with 2.x and 3.x. ................ r60079 | christian.heimes | 2008-01-19 17:21:02 +0100 (Sa, 19 Jan 2008) | 69 lines Merged revisions 60053-60078 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60054 | christian.heimes | 2008-01-18 20:12:56 +0100 (Fri, 18 Jan 2008) | 1 line Silence Coverity false alerts with CIDs #172, #183, #184 ........ r60057 | guido.van.rossum | 2008-01-18 21:56:30 +0100 (Fri, 18 Jan 2008) | 3 lines Fix an edge case whereby the __del__() method of a classic class could create a new weakref to the object. ........ r60058 | raymond.hettinger | 2008-01-18 22:14:58 +0100 (Fri, 18 Jan 2008) | 1 line Better variable name in an example. ........ r60063 | guido.van.rossum | 2008-01-19 00:05:40 +0100 (Sat, 19 Jan 2008) | 3 lines This got fixed for classic classes in r60057, and backported to 2.5.2 in 60056. ........ r60068 | jeffrey.yasskin | 2008-01-19 10:56:06 +0100 (Sat, 19 Jan 2008) | 4 lines Several tweaks: add construction from strings and .from_decimal(), change __init__ to __new__ to enforce immutability, and remove "rational." from repr and the parens from str. ........ r60069 | georg.brandl | 2008-01-19 11:11:27 +0100 (Sat, 19 Jan 2008) | 2 lines Fix markup. ........ r60070 | georg.brandl | 2008-01-19 11:16:09 +0100 (Sat, 19 Jan 2008) | 3 lines Amend curses docs by info how to write non-ascii characters. Thanks to Jeroen Ruigrok van der Werven. ........ r60071 | georg.brandl | 2008-01-19 11:18:07 +0100 (Sat, 19 Jan 2008) | 2 lines Indentation normalization. ........ r60073 | facundo.batista | 2008-01-19 13:32:27 +0100 (Sat, 19 Jan 2008) | 5 lines Fix issue #1822: MIMEMultipart.is_multipart() behaves correctly for a just-created (and empty) instance. Added tests for this. Thanks Jonathan Share. ........ r60074 | andrew.kuchling | 2008-01-19 14:33:20 +0100 (Sat, 19 Jan 2008) | 1 line Polish sentence ........ r60075 | christian.heimes | 2008-01-19 14:46:06 +0100 (Sat, 19 Jan 2008) | 1 line Added unit test to verify that threading.local doesn't cause ref leaks. It seems that the thread local storage always keeps the storage of the last stopped thread alive. Can anybody comment on it, please? ........ r60076 | christian.heimes | 2008-01-19 16:06:09 +0100 (Sat, 19 Jan 2008) | 1 line Update for threading.local test. ........ r60077 | andrew.kuchling | 2008-01-19 16:16:37 +0100 (Sat, 19 Jan 2008) | 1 line Polish sentence ........ r60078 | georg.brandl | 2008-01-19 16:22:16 +0100 (Sat, 19 Jan 2008) | 2 lines Fix typos. ........ ................ r60090 | facundo.batista | 2008-01-19 20:12:01 +0100 (Sa, 19 Jan 2008) | 4 lines Fix Issue #1769: Now int('- 1') or int('+ 1') is not allowed any more. Thanks Juan Jose Conti. Also added tests. ................ r60094 | georg.brandl | 2008-01-19 21:08:23 +0100 (Sa, 19 Jan 2008) | 67 lines Merged revisions 60080-60089,60091-60093 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60080 | andrew.kuchling | 2008-01-19 17:26:13 +0100 (Sat, 19 Jan 2008) | 2 lines Patch #742598 from Michael Pomraning: add .timeout attribute to SocketServer that will call .handle_timeout() method when no requests are received within the timeout period. ........ r60081 | andrew.kuchling | 2008-01-19 17:34:09 +0100 (Sat, 19 Jan 2008) | 1 line Add item ........ r60082 | christian.heimes | 2008-01-19 17:39:27 +0100 (Sat, 19 Jan 2008) | 2 lines Disabled test_xmlrpc:test_404. It's causing lots of false alarms. I also disabled a test in test_ssl which requires network access to svn.python.org. This fixes a bug Skip has reported a while ago. ........ r60083 | georg.brandl | 2008-01-19 18:38:53 +0100 (Sat, 19 Jan 2008) | 2 lines Clarify thread.join() docs. #1873. ........ r60084 | georg.brandl | 2008-01-19 19:02:46 +0100 (Sat, 19 Jan 2008) | 2 lines #1782: don't leak in error case in PyModule_AddXxxConstant. Patch by Hrvoje Nik?\197?\161i?\196?\135. ........ r60085 | andrew.kuchling | 2008-01-19 19:08:52 +0100 (Sat, 19 Jan 2008) | 1 line Sort two names into position ........ r60086 | andrew.kuchling | 2008-01-19 19:18:41 +0100 (Sat, 19 Jan 2008) | 2 lines Patch #976880: add mmap .rfind() method, and 'end' paramter to .find(). Contributed by John Lenton. ........ r60087 | facundo.batista | 2008-01-19 19:38:19 +0100 (Sat, 19 Jan 2008) | 5 lines Fix #1693149. Now you can pass several modules separated by coma to trace.py in the same --ignore-module option. Thanks Raghuram Devarakonda. ........ r60088 | facundo.batista | 2008-01-19 19:45:46 +0100 (Sat, 19 Jan 2008) | 3 lines Comment in NEWS regarding the change in trace.py. ........ r60089 | skip.montanaro | 2008-01-19 19:47:24 +0100 (Sat, 19 Jan 2008) | 2 lines missing from r60088 checkin. ........ r60091 | andrew.kuchling | 2008-01-19 20:14:05 +0100 (Sat, 19 Jan 2008) | 1 line Add item ........ r60092 | georg.brandl | 2008-01-19 20:27:05 +0100 (Sat, 19 Jan 2008) | 4 lines Fix #1679: "0x" was taken as a valid integer literal. Fixes the tokenizer, tokenize.py and int() to reject this. Patches by Malte Helmert. ........ r60093 | georg.brandl | 2008-01-19 20:48:19 +0100 (Sat, 19 Jan 2008) | 3 lines Fix #1146: TextWrap vs words 1-character shorter than the width. Patch by Quentin Gallet-Gilles. ........ ................ r60100 | georg.brandl | 2008-01-19 21:44:32 +0100 (Sa, 19 Jan 2008) | 2 lines #1867: fix a few 3.0 incompatibilities in pydoc. ................ r60124 | christian.heimes | 2008-01-20 10:06:41 +0100 (So, 20 Jan 2008) | 118 lines Merged revisions 60094-60123 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk *** NOTE *** I haven't merged the files in Doc/c-api/. I got too many conflicts. Georg, please split them manually. ........ r60095 | andrew.kuchling | 2008-01-19 21:12:04 +0100 (Sat, 19 Jan 2008) | 2 lines Bug 1277: make Maildir use the user-provided factory instead of hard-wiring MaildirMessage. 2.5.2 bugfix candidate. ........ r60097 | georg.brandl | 2008-01-19 21:22:13 +0100 (Sat, 19 Jan 2008) | 4 lines #1663329: add os.closerange() to close a range of fds, ignoring errors, and use this in subprocess to speed up subprocess creation in close_fds mode. Patch by Mike Klaas. ........ r60099 | georg.brandl | 2008-01-19 21:40:24 +0100 (Sat, 19 Jan 2008) | 2 lines #1411695: clarify behavior of xml.sax.utils.[un]escape. ........ r60101 | andrew.kuchling | 2008-01-19 21:47:59 +0100 (Sat, 19 Jan 2008) | 7 lines Patch #1019808 from Federico Schwindt: Return correct socket error when a default timeout has been set, by using getsockopt() to get the error condition (instead of trying another connect() call, which seems to be a Linuxism). 2.5 bugfix candidate, assuming no one reports any problems with this change. ........ r60102 | gregory.p.smith | 2008-01-19 21:49:02 +0100 (Sat, 19 Jan 2008) | 3 lines fix comment typos, use not arg instead of arg == "", add test coverage for inside of the final if needquotes: within subprocess.list2cmdline(). ........ r60103 | georg.brandl | 2008-01-19 21:53:07 +0100 (Sat, 19 Jan 2008) | 2 lines #1509: fix sqlite3 docstrings and docs w.r.t. cursor.fetchXXX methods. ........ r60104 | gregory.p.smith | 2008-01-19 21:57:59 +0100 (Sat, 19 Jan 2008) | 6 lines Fixes issue1336 - a race condition could occur when forking if the gc kicked in during the critical section. solution: disable gc during that section. Patch contributed by jpa and updated by me to cover the race condition still existing what therve from twistedmatrix pointed out (already seen and fixed in twisted's own subprocess code). ........ r60105 | gregory.p.smith | 2008-01-19 22:00:37 +0100 (Sat, 19 Jan 2008) | 2 lines note about r60104 ........ r60106 | andrew.kuchling | 2008-01-19 22:00:38 +0100 (Sat, 19 Jan 2008) | 1 line Bug 1296: restore text describing OptionGroup ........ r60109 | georg.brandl | 2008-01-19 23:08:21 +0100 (Sat, 19 Jan 2008) | 2 lines Split the monstrous C API manual files in smaller parts. ........ r60110 | georg.brandl | 2008-01-19 23:14:27 +0100 (Sat, 19 Jan 2008) | 2 lines Missed one big file to split up. ........ r60111 | gregory.p.smith | 2008-01-19 23:23:56 +0100 (Sat, 19 Jan 2008) | 12 lines Undo an unnecessary else: and indentation that r60104 added. try: ... except: ... raise else: ... the else: is unecessary due to the blind except: with a raise. ........ r60115 | gregory.p.smith | 2008-01-19 23:49:37 +0100 (Sat, 19 Jan 2008) | 3 lines Fix issue 1300: Quote command line arguments that contain a '|' character in subprocess.list2cmdline (windows). ........ r60116 | gregory.p.smith | 2008-01-20 00:10:52 +0100 (Sun, 20 Jan 2008) | 3 lines Fixes/Accepts Patch for issue1189216 - Work properly with archives that have file headers past the 2**31 byte boundary. ........ r60119 | andrew.kuchling | 2008-01-20 01:00:38 +0100 (Sun, 20 Jan 2008) | 3 lines Patch #1048820 from Stefan Wehr: add insert-mode editing to Textbox. Fix an off-by-one error I noticed. ........ r60120 | andrew.kuchling | 2008-01-20 01:12:19 +0100 (Sun, 20 Jan 2008) | 1 line Add an interactive test script for exercising curses ........ r60121 | gregory.p.smith | 2008-01-20 02:21:03 +0100 (Sun, 20 Jan 2008) | 7 lines Fix zipfile decryption. The check for validity only worked on one type of encrypted zip files. Files using extended local headers needed to compare the check byte against different values. (according to reading the infozip unzip crypt.c source code) Fixes issue1003. ........ r60122 | gregory.p.smith | 2008-01-20 02:26:04 +0100 (Sun, 20 Jan 2008) | 2 lines note for r60121 ........ r60123 | gregory.p.smith | 2008-01-20 02:32:00 +0100 (Sun, 20 Jan 2008) | 4 lines Document that zipfile decryption is insanely slow and fix a typo and blatant lie in a docstring (it is not useful for security regardless of how you spell it). ........ ................ r60125 | georg.brandl | 2008-01-20 10:11:30 +0100 (So, 20 Jan 2008) | 2 lines Remove versionadded tag. ................ r60126 | georg.brandl | 2008-01-20 10:30:57 +0100 (So, 20 Jan 2008) | 2 lines Split C API docs in Py3k branch. ................ Modified: python/branches/py3k-ctypes-pep3118/Doc/c-api/abstract.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/c-api/abstract.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/c-api/abstract.rst Sun Jan 20 11:45:31 2008 @@ -1,6 +1,5 @@ .. highlightlang:: c - .. _abstract: ********************** @@ -16,928 +15,11 @@ initialized, such as a list object that has been created by :cfunc:`PyList_New`, but whose items have not been set to some non-\ ``NULL`` value yet. +.. toctree:: -.. _object: - -Object Protocol -=============== - - -.. cfunction:: int PyObject_Print(PyObject *o, FILE *fp, int flags) - - Print an object *o*, on file *fp*. Returns ``-1`` on error. The flags argument - is used to enable certain printing options. The only option currently supported - is :const:`Py_PRINT_RAW`; if given, the :func:`str` of the object is written - instead of the :func:`repr`. - - -.. cfunction:: int PyObject_HasAttr(PyObject *o, PyObject *attr_name) - - Returns ``1`` if *o* has the attribute *attr_name*, and ``0`` otherwise. This - is equivalent to the Python expression ``hasattr(o, attr_name)``. This function - always succeeds. - - -.. cfunction:: int PyObject_HasAttrString(PyObject *o, const char *attr_name) - - Returns ``1`` if *o* has the attribute *attr_name*, and ``0`` otherwise. This - is equivalent to the Python expression ``hasattr(o, attr_name)``. This function - always succeeds. - - -.. cfunction:: PyObject* PyObject_GetAttr(PyObject *o, PyObject *attr_name) - - Retrieve an attribute named *attr_name* from object *o*. Returns the attribute - value on success, or *NULL* on failure. This is the equivalent of the Python - expression ``o.attr_name``. - - -.. cfunction:: PyObject* PyObject_GetAttrString(PyObject *o, const char *attr_name) - - Retrieve an attribute named *attr_name* from object *o*. Returns the attribute - value on success, or *NULL* on failure. This is the equivalent of the Python - expression ``o.attr_name``. - - -.. cfunction:: int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v) - - Set the value of the attribute named *attr_name*, for object *o*, to the value - *v*. Returns ``-1`` on failure. This is the equivalent of the Python statement - ``o.attr_name = v``. - - -.. cfunction:: int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v) - - Set the value of the attribute named *attr_name*, for object *o*, to the value - *v*. Returns ``-1`` on failure. This is the equivalent of the Python statement - ``o.attr_name = v``. - - -.. cfunction:: int PyObject_DelAttr(PyObject *o, PyObject *attr_name) - - Delete attribute named *attr_name*, for object *o*. Returns ``-1`` on failure. - This is the equivalent of the Python statement ``del o.attr_name``. - - -.. cfunction:: int PyObject_DelAttrString(PyObject *o, const char *attr_name) - - Delete attribute named *attr_name*, for object *o*. Returns ``-1`` on failure. - This is the equivalent of the Python statement ``del o.attr_name``. - - -.. cfunction:: PyObject* PyObject_RichCompare(PyObject *o1, PyObject *o2, int opid) - - Compare the values of *o1* and *o2* using the operation specified by *opid*, - which must be one of :const:`Py_LT`, :const:`Py_LE`, :const:`Py_EQ`, - :const:`Py_NE`, :const:`Py_GT`, or :const:`Py_GE`, corresponding to ``<``, - ``<=``, ``==``, ``!=``, ``>``, or ``>=`` respectively. This is the equivalent of - the Python expression ``o1 op o2``, where ``op`` is the operator corresponding - to *opid*. Returns the value of the comparison on success, or *NULL* on failure. - - -.. cfunction:: int PyObject_RichCompareBool(PyObject *o1, PyObject *o2, int opid) - - Compare the values of *o1* and *o2* using the operation specified by *opid*, - which must be one of :const:`Py_LT`, :const:`Py_LE`, :const:`Py_EQ`, - :const:`Py_NE`, :const:`Py_GT`, or :const:`Py_GE`, corresponding to ``<``, - ``<=``, ``==``, ``!=``, ``>``, or ``>=`` respectively. Returns ``-1`` on error, - ``0`` if the result is false, ``1`` otherwise. This is the equivalent of the - Python expression ``o1 op o2``, where ``op`` is the operator corresponding to - *opid*. - - -.. cfunction:: int PyObject_Cmp(PyObject *o1, PyObject *o2, int *result) - - .. index:: builtin: cmp - - Compare the values of *o1* and *o2* using a routine provided by *o1*, if one - exists, otherwise with a routine provided by *o2*. The result of the comparison - is returned in *result*. Returns ``-1`` on failure. This is the equivalent of - the Python statement ``result = cmp(o1, o2)``. - - -.. cfunction:: int PyObject_Compare(PyObject *o1, PyObject *o2) - - .. index:: builtin: cmp - - Compare the values of *o1* and *o2* using a routine provided by *o1*, if one - exists, otherwise with a routine provided by *o2*. Returns the result of the - comparison on success. On error, the value returned is undefined; use - :cfunc:`PyErr_Occurred` to detect an error. This is equivalent to the Python - expression ``cmp(o1, o2)``. - - -.. cfunction:: PyObject* PyObject_Repr(PyObject *o) - - .. index:: builtin: repr - - Compute a string representation of object *o*. Returns the string - representation on success, *NULL* on failure. This is the equivalent of the - Python expression ``repr(o)``. Called by the :func:`repr` built-in function and - by reverse quotes. - - -.. cfunction:: PyObject* PyObject_Str(PyObject *o) - - .. index:: builtin: str - - Compute a string representation of object *o*. Returns the string - representation on success, *NULL* on failure. This is the equivalent of the - Python expression ``str(o)``. Called by the :func:`str` built-in function - and, therefore, by the :func:`print` function. - - -.. cfunction:: PyObject* PyObject_Unicode(PyObject *o) - - .. index:: builtin: unicode - - Compute a Unicode string representation of object *o*. Returns the Unicode - string representation on success, *NULL* on failure. This is the equivalent of - the Python expression ``unicode(o)``. Called by the :func:`unicode` built-in - function. - - -.. cfunction:: int PyObject_IsInstance(PyObject *inst, PyObject *cls) - - Returns ``1`` if *inst* is an instance of the class *cls* or a subclass of - *cls*, or ``0`` if not. On error, returns ``-1`` and sets an exception. If - *cls* is a type object rather than a class object, :cfunc:`PyObject_IsInstance` - returns ``1`` if *inst* is of type *cls*. If *cls* is a tuple, the check will - be done against every entry in *cls*. The result will be ``1`` when at least one - of the checks returns ``1``, otherwise it will be ``0``. If *inst* is not a - class instance and *cls* is neither a type object, nor a class object, nor a - tuple, *inst* must have a :attr:`__class__` attribute --- the class relationship - of the value of that attribute with *cls* will be used to determine the result - of this function. - - -Subclass determination is done in a fairly straightforward way, but includes a -wrinkle that implementors of extensions to the class system may want to be aware -of. If :class:`A` and :class:`B` are class objects, :class:`B` is a subclass of -:class:`A` if it inherits from :class:`A` either directly or indirectly. If -either is not a class object, a more general mechanism is used to determine the -class relationship of the two objects. When testing if *B* is a subclass of -*A*, if *A* is *B*, :cfunc:`PyObject_IsSubclass` returns true. If *A* and *B* -are different objects, *B*'s :attr:`__bases__` attribute is searched in a -depth-first fashion for *A* --- the presence of the :attr:`__bases__` attribute -is considered sufficient for this determination. - - -.. cfunction:: int PyObject_IsSubclass(PyObject *derived, PyObject *cls) - - Returns ``1`` if the class *derived* is identical to or derived from the class - *cls*, otherwise returns ``0``. In case of an error, returns ``-1``. If *cls* - is a tuple, the check will be done against every entry in *cls*. The result will - be ``1`` when at least one of the checks returns ``1``, otherwise it will be - ``0``. If either *derived* or *cls* is not an actual class object (or tuple), - this function uses the generic algorithm described above. - - -.. cfunction:: int PyCallable_Check(PyObject *o) - - Determine if the object *o* is callable. Return ``1`` if the object is callable - and ``0`` otherwise. This function always succeeds. - - -.. cfunction:: PyObject* PyObject_Call(PyObject *callable_object, PyObject *args, PyObject *kw) - - Call a callable Python object *callable_object*, with arguments given by the - tuple *args*, and named arguments given by the dictionary *kw*. If no named - arguments are needed, *kw* may be *NULL*. *args* must not be *NULL*, use an - empty tuple if no arguments are needed. Returns the result of the call on - success, or *NULL* on failure. This is the equivalent of the Python expression - ``callable_object(*args, **kw)``. - - -.. cfunction:: PyObject* PyObject_CallObject(PyObject *callable_object, PyObject *args) - - Call a callable Python object *callable_object*, with arguments given by the - tuple *args*. If no arguments are needed, then *args* may be *NULL*. Returns - the result of the call on success, or *NULL* on failure. This is the equivalent - of the Python expression ``callable_object(*args)``. - - -.. cfunction:: PyObject* PyObject_CallFunction(PyObject *callable, char *format, ...) - - Call a callable Python object *callable*, with a variable number of C arguments. - The C arguments are described using a :cfunc:`Py_BuildValue` style format - string. The format may be *NULL*, indicating that no arguments are provided. - Returns the result of the call on success, or *NULL* on failure. This is the - equivalent of the Python expression ``callable(*args)``. Note that if you only - pass :ctype:`PyObject \*` args, :cfunc:`PyObject_CallFunctionObjArgs` is a - faster alternative. - - -.. cfunction:: PyObject* PyObject_CallMethod(PyObject *o, char *method, char *format, ...) - - Call the method named *method* of object *o* with a variable number of C - arguments. The C arguments are described by a :cfunc:`Py_BuildValue` format - string that should produce a tuple. The format may be *NULL*, indicating that - no arguments are provided. Returns the result of the call on success, or *NULL* - on failure. This is the equivalent of the Python expression ``o.method(args)``. - Note that if you only pass :ctype:`PyObject \*` args, - :cfunc:`PyObject_CallMethodObjArgs` is a faster alternative. - - -.. cfunction:: PyObject* PyObject_CallFunctionObjArgs(PyObject *callable, ..., NULL) - - Call a callable Python object *callable*, with a variable number of - :ctype:`PyObject\*` arguments. The arguments are provided as a variable number - of parameters followed by *NULL*. Returns the result of the call on success, or - *NULL* on failure. - - -.. cfunction:: PyObject* PyObject_CallMethodObjArgs(PyObject *o, PyObject *name, ..., NULL) - - Calls a method of the object *o*, where the name of the method is given as a - Python string object in *name*. It is called with a variable number of - :ctype:`PyObject\*` arguments. The arguments are provided as a variable number - of parameters followed by *NULL*. Returns the result of the call on success, or - *NULL* on failure. - - -.. cfunction:: long PyObject_Hash(PyObject *o) - - .. index:: builtin: hash - - Compute and return the hash value of an object *o*. On failure, return ``-1``. - This is the equivalent of the Python expression ``hash(o)``. - - -.. cfunction:: int PyObject_IsTrue(PyObject *o) - - Returns ``1`` if the object *o* is considered to be true, and ``0`` otherwise. - This is equivalent to the Python expression ``not not o``. On failure, return - ``-1``. - - -.. cfunction:: int PyObject_Not(PyObject *o) - - Returns ``0`` if the object *o* is considered to be true, and ``1`` otherwise. - This is equivalent to the Python expression ``not o``. On failure, return - ``-1``. - - -.. cfunction:: PyObject* PyObject_Type(PyObject *o) - - .. index:: builtin: type - - When *o* is non-*NULL*, returns a type object corresponding to the object type - of object *o*. On failure, raises :exc:`SystemError` and returns *NULL*. This - is equivalent to the Python expression ``type(o)``. This function increments the - reference count of the return value. There's really no reason to use this - function instead of the common expression ``o->ob_type``, which returns a - pointer of type :ctype:`PyTypeObject\*`, except when the incremented reference - count is needed. - - -.. cfunction:: int PyObject_TypeCheck(PyObject *o, PyTypeObject *type) - - Return true if the object *o* is of type *type* or a subtype of *type*. Both - parameters must be non-*NULL*. - - -.. cfunction:: Py_ssize_t PyObject_Length(PyObject *o) - Py_ssize_t PyObject_Size(PyObject *o) - - .. index:: builtin: len - - Return the length of object *o*. If the object *o* provides either the sequence - and mapping protocols, the sequence length is returned. On error, ``-1`` is - returned. This is the equivalent to the Python expression ``len(o)``. - - -.. cfunction:: PyObject* PyObject_GetItem(PyObject *o, PyObject *key) - - Return element of *o* corresponding to the object *key* or *NULL* on failure. - This is the equivalent of the Python expression ``o[key]``. - - -.. cfunction:: int PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v) - - Map the object *key* to the value *v*. Returns ``-1`` on failure. This is the - equivalent of the Python statement ``o[key] = v``. - - -.. cfunction:: int PyObject_DelItem(PyObject *o, PyObject *key) - - Delete the mapping for *key* from *o*. Returns ``-1`` on failure. This is the - equivalent of the Python statement ``del o[key]``. - - -.. cfunction:: PyObject* PyObject_Dir(PyObject *o) - - This is equivalent to the Python expression ``dir(o)``, returning a (possibly - empty) list of strings appropriate for the object argument, or *NULL* if there - was an error. If the argument is *NULL*, this is like the Python ``dir()``, - returning the names of the current locals; in this case, if no execution frame - is active then *NULL* is returned but :cfunc:`PyErr_Occurred` will return false. - - -.. cfunction:: PyObject* PyObject_GetIter(PyObject *o) - - This is equivalent to the Python expression ``iter(o)``. It returns a new - iterator for the object argument, or the object itself if the object is already - an iterator. Raises :exc:`TypeError` and returns *NULL* if the object cannot be - iterated. - - -.. _number: - -Number Protocol -=============== - - -.. cfunction:: int PyNumber_Check(PyObject *o) - - Returns ``1`` if the object *o* provides numeric protocols, and false otherwise. - This function always succeeds. - - -.. cfunction:: PyObject* PyNumber_Add(PyObject *o1, PyObject *o2) - - Returns the result of adding *o1* and *o2*, or *NULL* on failure. This is the - equivalent of the Python expression ``o1 + o2``. - - -.. cfunction:: PyObject* PyNumber_Subtract(PyObject *o1, PyObject *o2) - - Returns the result of subtracting *o2* from *o1*, or *NULL* on failure. This is - the equivalent of the Python expression ``o1 - o2``. - - -.. cfunction:: PyObject* PyNumber_Multiply(PyObject *o1, PyObject *o2) - - Returns the result of multiplying *o1* and *o2*, or *NULL* on failure. This is - the equivalent of the Python expression ``o1 * o2``. - - -.. cfunction:: PyObject* PyNumber_Divide(PyObject *o1, PyObject *o2) - - Returns the result of dividing *o1* by *o2*, or *NULL* on failure. This is the - equivalent of the Python expression ``o1 / o2``. - - -.. cfunction:: PyObject* PyNumber_FloorDivide(PyObject *o1, PyObject *o2) - - Return the floor of *o1* divided by *o2*, or *NULL* on failure. This is - equivalent to the "classic" division of integers. - - -.. cfunction:: PyObject* PyNumber_TrueDivide(PyObject *o1, PyObject *o2) - - Return a reasonable approximation for the mathematical value of *o1* divided by - *o2*, or *NULL* on failure. The return value is "approximate" because binary - floating point numbers are approximate; it is not possible to represent all real - numbers in base two. This function can return a floating point value when - passed two integers. - - -.. cfunction:: PyObject* PyNumber_Remainder(PyObject *o1, PyObject *o2) - - Returns the remainder of dividing *o1* by *o2*, or *NULL* on failure. This is - the equivalent of the Python expression ``o1 % o2``. - - -.. cfunction:: PyObject* PyNumber_Divmod(PyObject *o1, PyObject *o2) - - .. index:: builtin: divmod - - See the built-in function :func:`divmod`. Returns *NULL* on failure. This is - the equivalent of the Python expression ``divmod(o1, o2)``. - - -.. cfunction:: PyObject* PyNumber_Power(PyObject *o1, PyObject *o2, PyObject *o3) - - .. index:: builtin: pow - - See the built-in function :func:`pow`. Returns *NULL* on failure. This is the - equivalent of the Python expression ``pow(o1, o2, o3)``, where *o3* is optional. - If *o3* is to be ignored, pass :cdata:`Py_None` in its place (passing *NULL* for - *o3* would cause an illegal memory access). - - -.. cfunction:: PyObject* PyNumber_Negative(PyObject *o) - - Returns the negation of *o* on success, or *NULL* on failure. This is the - equivalent of the Python expression ``-o``. - - -.. cfunction:: PyObject* PyNumber_Positive(PyObject *o) - - Returns *o* on success, or *NULL* on failure. This is the equivalent of the - Python expression ``+o``. - - -.. cfunction:: PyObject* PyNumber_Absolute(PyObject *o) - - .. index:: builtin: abs - - Returns the absolute value of *o*, or *NULL* on failure. This is the equivalent - of the Python expression ``abs(o)``. - - -.. cfunction:: PyObject* PyNumber_Invert(PyObject *o) - - Returns the bitwise negation of *o* on success, or *NULL* on failure. This is - the equivalent of the Python expression ``~o``. - - -.. cfunction:: PyObject* PyNumber_Lshift(PyObject *o1, PyObject *o2) - - Returns the result of left shifting *o1* by *o2* on success, or *NULL* on - failure. This is the equivalent of the Python expression ``o1 << o2``. - - -.. cfunction:: PyObject* PyNumber_Rshift(PyObject *o1, PyObject *o2) - - Returns the result of right shifting *o1* by *o2* on success, or *NULL* on - failure. This is the equivalent of the Python expression ``o1 >> o2``. - - -.. cfunction:: PyObject* PyNumber_And(PyObject *o1, PyObject *o2) - - Returns the "bitwise and" of *o1* and *o2* on success and *NULL* on failure. - This is the equivalent of the Python expression ``o1 & o2``. - - -.. cfunction:: PyObject* PyNumber_Xor(PyObject *o1, PyObject *o2) - - Returns the "bitwise exclusive or" of *o1* by *o2* on success, or *NULL* on - failure. This is the equivalent of the Python expression ``o1 ^ o2``. - - -.. cfunction:: PyObject* PyNumber_Or(PyObject *o1, PyObject *o2) - - Returns the "bitwise or" of *o1* and *o2* on success, or *NULL* on failure. - This is the equivalent of the Python expression ``o1 | o2``. - - -.. cfunction:: PyObject* PyNumber_InPlaceAdd(PyObject *o1, PyObject *o2) - - Returns the result of adding *o1* and *o2*, or *NULL* on failure. The operation - is done *in-place* when *o1* supports it. This is the equivalent of the Python - statement ``o1 += o2``. - - -.. cfunction:: PyObject* PyNumber_InPlaceSubtract(PyObject *o1, PyObject *o2) - - Returns the result of subtracting *o2* from *o1*, or *NULL* on failure. The - operation is done *in-place* when *o1* supports it. This is the equivalent of - the Python statement ``o1 -= o2``. - - -.. cfunction:: PyObject* PyNumber_InPlaceMultiply(PyObject *o1, PyObject *o2) - - Returns the result of multiplying *o1* and *o2*, or *NULL* on failure. The - operation is done *in-place* when *o1* supports it. This is the equivalent of - the Python statement ``o1 *= o2``. - - -.. cfunction:: PyObject* PyNumber_InPlaceDivide(PyObject *o1, PyObject *o2) - - Returns the result of dividing *o1* by *o2*, or *NULL* on failure. The - operation is done *in-place* when *o1* supports it. This is the equivalent of - the Python statement ``o1 /= o2``. - - -.. cfunction:: PyObject* PyNumber_InPlaceFloorDivide(PyObject *o1, PyObject *o2) - - Returns the mathematical floor of dividing *o1* by *o2*, or *NULL* on failure. - The operation is done *in-place* when *o1* supports it. This is the equivalent - of the Python statement ``o1 //= o2``. - - -.. cfunction:: PyObject* PyNumber_InPlaceTrueDivide(PyObject *o1, PyObject *o2) - - Return a reasonable approximation for the mathematical value of *o1* divided by - *o2*, or *NULL* on failure. The return value is "approximate" because binary - floating point numbers are approximate; it is not possible to represent all real - numbers in base two. This function can return a floating point value when - passed two integers. The operation is done *in-place* when *o1* supports it. - - -.. cfunction:: PyObject* PyNumber_InPlaceRemainder(PyObject *o1, PyObject *o2) - - Returns the remainder of dividing *o1* by *o2*, or *NULL* on failure. The - operation is done *in-place* when *o1* supports it. This is the equivalent of - the Python statement ``o1 %= o2``. - - -.. cfunction:: PyObject* PyNumber_InPlacePower(PyObject *o1, PyObject *o2, PyObject *o3) - - .. index:: builtin: pow - - See the built-in function :func:`pow`. Returns *NULL* on failure. The operation - is done *in-place* when *o1* supports it. This is the equivalent of the Python - statement ``o1 **= o2`` when o3 is :cdata:`Py_None`, or an in-place variant of - ``pow(o1, o2, o3)`` otherwise. If *o3* is to be ignored, pass :cdata:`Py_None` - in its place (passing *NULL* for *o3* would cause an illegal memory access). - - -.. cfunction:: PyObject* PyNumber_InPlaceLshift(PyObject *o1, PyObject *o2) - - Returns the result of left shifting *o1* by *o2* on success, or *NULL* on - failure. The operation is done *in-place* when *o1* supports it. This is the - equivalent of the Python statement ``o1 <<= o2``. - - -.. cfunction:: PyObject* PyNumber_InPlaceRshift(PyObject *o1, PyObject *o2) - - Returns the result of right shifting *o1* by *o2* on success, or *NULL* on - failure. The operation is done *in-place* when *o1* supports it. This is the - equivalent of the Python statement ``o1 >>= o2``. - - -.. cfunction:: PyObject* PyNumber_InPlaceAnd(PyObject *o1, PyObject *o2) - - Returns the "bitwise and" of *o1* and *o2* on success and *NULL* on failure. The - operation is done *in-place* when *o1* supports it. This is the equivalent of - the Python statement ``o1 &= o2``. - - -.. cfunction:: PyObject* PyNumber_InPlaceXor(PyObject *o1, PyObject *o2) - - Returns the "bitwise exclusive or" of *o1* by *o2* on success, or *NULL* on - failure. The operation is done *in-place* when *o1* supports it. This is the - equivalent of the Python statement ``o1 ^= o2``. - - -.. cfunction:: PyObject* PyNumber_InPlaceOr(PyObject *o1, PyObject *o2) - - Returns the "bitwise or" of *o1* and *o2* on success, or *NULL* on failure. The - operation is done *in-place* when *o1* supports it. This is the equivalent of - the Python statement ``o1 |= o2``. - - -.. cfunction:: PyObject* PyNumber_Int(PyObject *o) - - .. index:: builtin: int - - Returns the *o* converted to an integer object on success, or *NULL* on failure. - If the argument is outside the integer range a long object will be returned - instead. This is the equivalent of the Python expression ``int(o)``. - - -.. cfunction:: PyObject* PyNumber_Long(PyObject *o) - - .. index:: builtin: long - - Returns the *o* converted to an integer object on success, or *NULL* on - failure. This is the equivalent of the Python expression ``long(o)``. - - -.. cfunction:: PyObject* PyNumber_Float(PyObject *o) - - .. index:: builtin: float - - Returns the *o* converted to a float object on success, or *NULL* on failure. - This is the equivalent of the Python expression ``float(o)``. - - -.. cfunction:: PyObject* PyNumber_Index(PyObject *o) - - Returns the *o* converted to a Python int or long on success or *NULL* with a - TypeError exception raised on failure. - - -.. cfunction:: Py_ssize_t PyNumber_AsSsize_t(PyObject *o, PyObject *exc) - - Returns *o* converted to a Py_ssize_t value if *o* can be interpreted as an - integer. If *o* can be converted to a Python int or long but the attempt to - convert to a Py_ssize_t value would raise an :exc:`OverflowError`, then the - *exc* argument is the type of exception that will be raised (usually - :exc:`IndexError` or :exc:`OverflowError`). If *exc* is *NULL*, then the - exception is cleared and the value is clipped to *PY_SSIZE_T_MIN* for a negative - integer or *PY_SSIZE_T_MAX* for a positive integer. - - -.. cfunction:: int PyIndex_Check(PyObject *o) - - Returns True if *o* is an index integer (has the nb_index slot of the - tp_as_number structure filled in). - - -.. _sequence: - -Sequence Protocol -================= - - -.. cfunction:: int PySequence_Check(PyObject *o) - - Return ``1`` if the object provides sequence protocol, and ``0`` otherwise. - This function always succeeds. - - -.. cfunction:: Py_ssize_t PySequence_Size(PyObject *o) - - .. index:: builtin: len - - Returns the number of objects in sequence *o* on success, and ``-1`` on failure. - For objects that do not provide sequence protocol, this is equivalent to the - Python expression ``len(o)``. - - -.. cfunction:: Py_ssize_t PySequence_Length(PyObject *o) - - Alternate name for :cfunc:`PySequence_Size`. - - -.. cfunction:: PyObject* PySequence_Concat(PyObject *o1, PyObject *o2) - - Return the concatenation of *o1* and *o2* on success, and *NULL* on failure. - This is the equivalent of the Python expression ``o1 + o2``. - - -.. cfunction:: PyObject* PySequence_Repeat(PyObject *o, Py_ssize_t count) - - Return the result of repeating sequence object *o* *count* times, or *NULL* on - failure. This is the equivalent of the Python expression ``o * count``. - - -.. cfunction:: PyObject* PySequence_InPlaceConcat(PyObject *o1, PyObject *o2) - - Return the concatenation of *o1* and *o2* on success, and *NULL* on failure. - The operation is done *in-place* when *o1* supports it. This is the equivalent - of the Python expression ``o1 += o2``. - - -.. cfunction:: PyObject* PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count) - - Return the result of repeating sequence object *o* *count* times, or *NULL* on - failure. The operation is done *in-place* when *o* supports it. This is the - equivalent of the Python expression ``o *= count``. - - -.. cfunction:: PyObject* PySequence_GetItem(PyObject *o, Py_ssize_t i) - - Return the *i*th element of *o*, or *NULL* on failure. This is the equivalent of - the Python expression ``o[i]``. - - -.. cfunction:: PyObject* PySequence_GetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2) - - Return the slice of sequence object *o* between *i1* and *i2*, or *NULL* on - failure. This is the equivalent of the Python expression ``o[i1:i2]``. - - -.. cfunction:: int PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v) - - Assign object *v* to the *i*th element of *o*. Returns ``-1`` on failure. This - is the equivalent of the Python statement ``o[i] = v``. This function *does - not* steal a reference to *v*. - - -.. cfunction:: int PySequence_DelItem(PyObject *o, Py_ssize_t i) - - Delete the *i*th element of object *o*. Returns ``-1`` on failure. This is the - equivalent of the Python statement ``del o[i]``. - - -.. cfunction:: int PySequence_SetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2, PyObject *v) - - Assign the sequence object *v* to the slice in sequence object *o* from *i1* to - *i2*. This is the equivalent of the Python statement ``o[i1:i2] = v``. - - -.. cfunction:: int PySequence_DelSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2) - - Delete the slice in sequence object *o* from *i1* to *i2*. Returns ``-1`` on - failure. This is the equivalent of the Python statement ``del o[i1:i2]``. - - -.. cfunction:: Py_ssize_t PySequence_Count(PyObject *o, PyObject *value) - - Return the number of occurrences of *value* in *o*, that is, return the number - of keys for which ``o[key] == value``. On failure, return ``-1``. This is - equivalent to the Python expression ``o.count(value)``. - - -.. cfunction:: int PySequence_Contains(PyObject *o, PyObject *value) - - Determine if *o* contains *value*. If an item in *o* is equal to *value*, - return ``1``, otherwise return ``0``. On error, return ``-1``. This is - equivalent to the Python expression ``value in o``. - - -.. cfunction:: Py_ssize_t PySequence_Index(PyObject *o, PyObject *value) - - Return the first index *i* for which ``o[i] == value``. On error, return - ``-1``. This is equivalent to the Python expression ``o.index(value)``. - - -.. cfunction:: PyObject* PySequence_List(PyObject *o) - - Return a list object with the same contents as the arbitrary sequence *o*. The - returned list is guaranteed to be new. - - -.. cfunction:: PyObject* PySequence_Tuple(PyObject *o) - - .. index:: builtin: tuple - - Return a tuple object with the same contents as the arbitrary sequence *o* or - *NULL* on failure. If *o* is a tuple, a new reference will be returned, - otherwise a tuple will be constructed with the appropriate contents. This is - equivalent to the Python expression ``tuple(o)``. - - -.. cfunction:: PyObject* PySequence_Fast(PyObject *o, const char *m) - - Returns the sequence *o* as a tuple, unless it is already a tuple or list, in - which case *o* is returned. Use :cfunc:`PySequence_Fast_GET_ITEM` to access the - members of the result. Returns *NULL* on failure. If the object is not a - sequence, raises :exc:`TypeError` with *m* as the message text. - - -.. cfunction:: PyObject* PySequence_Fast_GET_ITEM(PyObject *o, Py_ssize_t i) - - Return the *i*th element of *o*, assuming that *o* was returned by - :cfunc:`PySequence_Fast`, *o* is not *NULL*, and that *i* is within bounds. - - -.. cfunction:: PyObject** PySequence_Fast_ITEMS(PyObject *o) - - Return the underlying array of PyObject pointers. Assumes that *o* was returned - by :cfunc:`PySequence_Fast` and *o* is not *NULL*. - - -.. cfunction:: PyObject* PySequence_ITEM(PyObject *o, Py_ssize_t i) - - Return the *i*th element of *o* or *NULL* on failure. Macro form of - :cfunc:`PySequence_GetItem` but without checking that - :cfunc:`PySequence_Check(o)` is true and without adjustment for negative - indices. - - -.. cfunction:: Py_ssize_t PySequence_Fast_GET_SIZE(PyObject *o) - - Returns the length of *o*, assuming that *o* was returned by - :cfunc:`PySequence_Fast` and that *o* is not *NULL*. The size can also be - gotten by calling :cfunc:`PySequence_Size` on *o*, but - :cfunc:`PySequence_Fast_GET_SIZE` is faster because it can assume *o* is a list - or tuple. - - -.. _mapping: - -Mapping Protocol -================ - - -.. cfunction:: int PyMapping_Check(PyObject *o) - - Return ``1`` if the object provides mapping protocol, and ``0`` otherwise. This - function always succeeds. - - -.. cfunction:: Py_ssize_t PyMapping_Length(PyObject *o) - - .. index:: builtin: len - - Returns the number of keys in object *o* on success, and ``-1`` on failure. For - objects that do not provide mapping protocol, this is equivalent to the Python - expression ``len(o)``. - - -.. cfunction:: int PyMapping_DelItemString(PyObject *o, char *key) - - Remove the mapping for object *key* from the object *o*. Return ``-1`` on - failure. This is equivalent to the Python statement ``del o[key]``. - - -.. cfunction:: int PyMapping_DelItem(PyObject *o, PyObject *key) - - Remove the mapping for object *key* from the object *o*. Return ``-1`` on - failure. This is equivalent to the Python statement ``del o[key]``. - - -.. cfunction:: int PyMapping_HasKeyString(PyObject *o, char *key) - - On success, return ``1`` if the mapping object has the key *key* and ``0`` - otherwise. This is equivalent to the Python expression ``key in o``. - This function always succeeds. - - -.. cfunction:: int PyMapping_HasKey(PyObject *o, PyObject *key) - - Return ``1`` if the mapping object has the key *key* and ``0`` otherwise. This - is equivalent to the Python expression ``key in o``. This function always - succeeds. - - -.. cfunction:: PyObject* PyMapping_Keys(PyObject *o) - - On success, return a list of the keys in object *o*. On failure, return *NULL*. - This is equivalent to the Python expression ``o.keys()``. - - -.. cfunction:: PyObject* PyMapping_Values(PyObject *o) - - On success, return a list of the values in object *o*. On failure, return - *NULL*. This is equivalent to the Python expression ``o.values()``. - - -.. cfunction:: PyObject* PyMapping_Items(PyObject *o) - - On success, return a list of the items in object *o*, where each item is a tuple - containing a key-value pair. On failure, return *NULL*. This is equivalent to - the Python expression ``o.items()``. - - -.. cfunction:: PyObject* PyMapping_GetItemString(PyObject *o, char *key) - - Return element of *o* corresponding to the object *key* or *NULL* on failure. - This is the equivalent of the Python expression ``o[key]``. - - -.. cfunction:: int PyMapping_SetItemString(PyObject *o, char *key, PyObject *v) - - Map the object *key* to the value *v* in object *o*. Returns ``-1`` on failure. - This is the equivalent of the Python statement ``o[key] = v``. - - -.. _iterator: - -Iterator Protocol -================= - -There are only a couple of functions specifically for working with iterators. - -.. cfunction:: int PyIter_Check(PyObject *o) - - Return true if the object *o* supports the iterator protocol. - - -.. cfunction:: PyObject* PyIter_Next(PyObject *o) - - Return the next value from the iteration *o*. If the object is an iterator, - this retrieves the next value from the iteration, and returns *NULL* with no - exception set if there are no remaining items. If the object is not an - iterator, :exc:`TypeError` is raised, or if there is an error in retrieving the - item, returns *NULL* and passes along the exception. - -To write a loop which iterates over an iterator, the C code should look -something like this:: - - PyObject *iterator = PyObject_GetIter(obj); - PyObject *item; - - if (iterator == NULL) { - /* propagate error */ - } - - while (item = PyIter_Next(iterator)) { - /* do something with item */ - ... - /* release reference when done */ - Py_DECREF(item); - } - - Py_DECREF(iterator); - - if (PyErr_Occurred()) { - /* propagate error */ - } - else { - /* continue doing useful work */ - } - - -.. _abstract-buffer: - -Buffer Protocol -=============== - - -.. cfunction:: int PyObject_AsCharBuffer(PyObject *obj, const char **buffer, Py_ssize_t *buffer_len) - - Returns a pointer to a read-only memory location useable as character- based - input. The *obj* argument must support the single-segment character buffer - interface. On success, returns ``0``, sets *buffer* to the memory location and - *buffer_len* to the buffer length. Returns ``-1`` and sets a :exc:`TypeError` - on error. - - -.. cfunction:: int PyObject_AsReadBuffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len) - - Returns a pointer to a read-only memory location containing arbitrary data. The - *obj* argument must support the single-segment readable buffer interface. On - success, returns ``0``, sets *buffer* to the memory location and *buffer_len* to - the buffer length. Returns ``-1`` and sets a :exc:`TypeError` on error. - - -.. cfunction:: int PyObject_CheckReadBuffer(PyObject *o) - - Returns ``1`` if *o* supports the single-segment readable buffer interface. - Otherwise returns ``0``. - - -.. cfunction:: int PyObject_AsWriteBuffer(PyObject *obj, void **buffer, Py_ssize_t *buffer_len) - - Returns a pointer to a writable memory location. The *obj* argument must - support the single-segment, character buffer interface. On success, returns - ``0``, sets *buffer* to the memory location and *buffer_len* to the buffer - length. Returns ``-1`` and sets a :exc:`TypeError` on error. - + object.rst + number.rst + sequence.rst + mapping.rst + iter.rst + objbuffer.rst Modified: python/branches/py3k-ctypes-pep3118/Doc/c-api/concrete.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/c-api/concrete.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/c-api/concrete.rst Sun Jan 20 11:45:31 2008 @@ -29,99 +29,10 @@ This section describes Python type objects and the singleton object ``None``. +.. toctree:: -.. _typeobjects: - -Type Objects ------------- - -.. index:: object: type - - -.. ctype:: PyTypeObject - - The C structure of the objects used to describe built-in types. - - -.. cvar:: PyObject* PyType_Type - - .. index:: single: TypeType (in module types) - - This is the type object for type objects; it is the same object as ``type`` and - ``types.TypeType`` in the Python layer. - - -.. cfunction:: int PyType_Check(PyObject *o) - - Return true if the object *o* is a type object, including instances of types - derived from the standard type object. Return false in all other cases. - - -.. cfunction:: int PyType_CheckExact(PyObject *o) - - Return true if the object *o* is a type object, but not a subtype of the - standard type object. Return false in all other cases. - - -.. cfunction:: int PyType_HasFeature(PyObject *o, int feature) - - Return true if the type object *o* sets the feature *feature*. Type features - are denoted by single bit flags. - - -.. cfunction:: int PyType_IS_GC(PyObject *o) - - Return true if the type object includes support for the cycle detector; this - tests the type flag :const:`Py_TPFLAGS_HAVE_GC`. - - -.. cfunction:: int PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b) - - Return true if *a* is a subtype of *b*. - - -.. cfunction:: PyObject* PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems) - - XXX: Document. - - -.. cfunction:: PyObject* PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds) - - XXX: Document. - - -.. cfunction:: int PyType_Ready(PyTypeObject *type) - - Finalize a type object. This should be called on all type objects to finish - their initialization. This function is responsible for adding inherited slots - from a type's base class. Return ``0`` on success, or return ``-1`` and sets an - exception on error. - - -.. _noneobject: - -The None Object ---------------- - -.. index:: object: None - -Note that the :ctype:`PyTypeObject` for ``None`` is not directly exposed in the -Python/C API. Since ``None`` is a singleton, testing for object identity (using -``==`` in C) is sufficient. There is no :cfunc:`PyNone_Check` function for the -same reason. - - -.. cvar:: PyObject* Py_None - - The Python ``None`` object, denoting lack of value. This object has no methods. - It needs to be treated just like any other object with respect to reference - counts. - - -.. cmacro:: Py_RETURN_NONE - - Properly handle returning :cdata:`Py_None` from within a C function (that is, - increment the reference count of None and return it.) + type.rst + none.rst .. _numericobjects: @@ -131,447 +42,12 @@ .. index:: object: numeric +.. toctree:: -.. _boolobjects: - -Boolean Objects ---------------- - -Booleans in Python are implemented as a subclass of integers. There are only -two booleans, :const:`Py_False` and :const:`Py_True`. As such, the normal -creation and deletion functions don't apply to booleans. The following macros -are available, however. - - -.. cfunction:: int PyBool_Check(PyObject *o) - - Return true if *o* is of type :cdata:`PyBool_Type`. - - -.. cvar:: PyObject* Py_False - - The Python ``False`` object. This object has no methods. It needs to be - treated just like any other object with respect to reference counts. - - -.. cvar:: PyObject* Py_True - - The Python ``True`` object. This object has no methods. It needs to be treated - just like any other object with respect to reference counts. - - -.. cmacro:: Py_RETURN_FALSE - - Return :const:`Py_False` from a function, properly incrementing its reference - count. - - -.. cmacro:: Py_RETURN_TRUE - - Return :const:`Py_True` from a function, properly incrementing its reference - count. - - -.. cfunction:: PyObject* PyBool_FromLong(long v) - - Return a new reference to :const:`Py_True` or :const:`Py_False` depending on the - truth value of *v*. - - -.. _longobjects: - -Integer Objects ---------------- - -.. index:: object: long integer - object: integer - -All integers are implemented as "long" integer objects of arbitrary size. - -.. ctype:: PyLongObject - - This subtype of :ctype:`PyObject` represents a Python integer object. - - -.. cvar:: PyTypeObject PyLong_Type - - This instance of :ctype:`PyTypeObject` represents the Python integer type. - This is the same object as ``int``. - - -.. cfunction:: int PyLong_Check(PyObject *p) - - Return true if its argument is a :ctype:`PyLongObject` or a subtype of - :ctype:`PyLongObject`. - - -.. cfunction:: int PyLong_CheckExact(PyObject *p) - - Return true if its argument is a :ctype:`PyLongObject`, but not a subtype of - :ctype:`PyLongObject`. - - -.. cfunction:: PyObject* PyLong_FromLong(long v) - - Return a new :ctype:`PyLongObject` object from *v*, or *NULL* on failure. - - The current implementation keeps an array of integer objects for all integers - between ``-5`` and ``256``, when you create an int in that range you actually - just get back a reference to the existing object. So it should be possible to - change the value of ``1``. I suspect the behaviour of Python in this case is - undefined. :-) - - -.. cfunction:: PyObject* PyLong_FromUnsignedLong(unsigned long v) - - Return a new :ctype:`PyLongObject` object from a C :ctype:`unsigned long`, or - *NULL* on failure. - - -.. cfunction:: PyObject* PyLong_FromSsize_t(Py_ssize_t v) - - Return a new :ctype:`PyLongObject` object with a value of *v*, or *NULL* - on failure. - - -.. cfunction:: PyObject* PyLong_FromSize_t(size_t v) - - Return a new :ctype:`PyLongObject` object with a value of *v*, or *NULL* - on failure. - - -.. cfunction:: PyObject* PyLong_FromLongLong(PY_LONG_LONG v) - - Return a new :ctype:`PyLongObject` object from a C :ctype:`long long`, or *NULL* - on failure. - - -.. cfunction:: PyObject* PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG v) - - Return a new :ctype:`PyLongObject` object from a C :ctype:`unsigned long long`, - or *NULL* on failure. - - -.. cfunction:: PyObject* PyLong_FromDouble(double v) - - Return a new :ctype:`PyLongObject` object from the integer part of *v*, or - *NULL* on failure. - - -.. cfunction:: PyObject* PyLong_FromString(char *str, char **pend, int base) - - Return a new :ctype:`PyLongObject` based on the string value in *str*, which - is interpreted according to the radix in *base*. If *pend* is non-*NULL*, - ``*pend`` will point to the first character in *str* which follows the - representation of the number. If *base* is ``0``, the radix will be - determined based on the leading characters of *str*: if *str* starts with - ``'0x'`` or ``'0X'``, radix 16 will be used; if *str* starts with ``'0o'`` or - ``'0O'``, radix 8 will be used; if *str* starts with ``'0b'`` or ``'0B'``, - radix 2 will be used; otherwise radix 10 will be used. If *base* is not - ``0``, it must be between ``2`` and ``36``, inclusive. Leading spaces are - ignored. If there are no digits, :exc:`ValueError` will be raised. - - -.. cfunction:: PyObject* PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base) - - Convert a sequence of Unicode digits to a Python integer value. The Unicode - string is first encoded to a byte string using :cfunc:`PyUnicode_EncodeDecimal` - and then converted using :cfunc:`PyLong_FromString`. - - -.. cfunction:: PyObject* PyLong_FromVoidPtr(void *p) - - Create a Python integer from the pointer *p*. The pointer value can be - retrieved from the resulting value using :cfunc:`PyLong_AsVoidPtr`. - - -.. XXX alias PyLong_AS_LONG (for now) -.. cfunction:: long PyLong_AsLong(PyObject *pylong) - - .. index:: - single: LONG_MAX - single: OverflowError (built-in exception) - - Return a C :ctype:`long` representation of the contents of *pylong*. If - *pylong* is greater than :const:`LONG_MAX`, raise an :exc:`OverflowError`, - and return -1. Convert non-long objects automatically to long first, - and return -1 if that raises exceptions. - -.. cfunction:: long PyLong_AsLongAndOverflow(PyObject *pylong, int* overflow) - - Return a C :ctype:`long` representation of the contents of *pylong*. If - *pylong* is greater than :const:`LONG_MAX`, return -1 and - set `*overflow` to 1 (for overflow) or -1 (for underflow). - If an exception is set because of type errors, also return -1. - - -.. cfunction:: unsigned long PyLong_AsUnsignedLong(PyObject *pylong) - - .. index:: - single: ULONG_MAX - single: OverflowError (built-in exception) - - Return a C :ctype:`unsigned long` representation of the contents of *pylong*. - If *pylong* is greater than :const:`ULONG_MAX`, an :exc:`OverflowError` is - raised. - - -.. cfunction:: Py_ssize_t PyLong_AsSsize_t(PyObject *pylong) - - .. index:: - single: PY_SSIZE_T_MAX - - Return a :ctype:`Py_ssize_t` representation of the contents of *pylong*. If - *pylong* is greater than :const:`PY_SSIZE_T_MAX`, an :exc:`OverflowError` is - raised. - - -.. cfunction:: size_t PyLong_AsSize_t(PyObject *pylong) - - Return a :ctype:`size_t` representation of the contents of *pylong*. If - *pylong* is greater than the maximum value for a :ctype:`size_t`, an - :exc:`OverflowError` is raised. - - -.. cfunction:: PY_LONG_LONG PyLong_AsLongLong(PyObject *pylong) - - Return a C :ctype:`long long` from a Python integer. If *pylong* cannot be - represented as a :ctype:`long long`, an :exc:`OverflowError` will be raised. - - -.. cfunction:: unsigned PY_LONG_LONG PyLong_AsUnsignedLongLong(PyObject *pylong) - - Return a C :ctype:`unsigned long long` from a Python integer. If *pylong* - cannot be represented as an :ctype:`unsigned long long`, an :exc:`OverflowError` - will be raised if the value is positive, or a :exc:`TypeError` will be raised if - the value is negative. - - -.. cfunction:: unsigned long PyLong_AsUnsignedLongMask(PyObject *io) - - Return a C :ctype:`unsigned long` from a Python integer, without checking for - overflow. - - -.. cfunction:: unsigned PY_LONG_LONG PyLong_AsUnsignedLongLongMask(PyObject *io) - - Return a C :ctype:`unsigned long long` from a Python integer, without - checking for overflow. - - -.. cfunction:: double PyLong_AsDouble(PyObject *pylong) - - Return a C :ctype:`double` representation of the contents of *pylong*. If - *pylong* cannot be approximately represented as a :ctype:`double`, an - :exc:`OverflowError` exception is raised and ``-1.0`` will be returned. - - -.. cfunction:: void* PyLong_AsVoidPtr(PyObject *pylong) - - Convert a Python integer *pylong* to a C :ctype:`void` pointer. If *pylong* - cannot be converted, an :exc:`OverflowError` will be raised. This is only - assured to produce a usable :ctype:`void` pointer for values created with - :cfunc:`PyLong_FromVoidPtr`. - - -.. _floatobjects: - -Floating Point Objects ----------------------- - -.. index:: object: floating point - - -.. ctype:: PyFloatObject - - This subtype of :ctype:`PyObject` represents a Python floating point object. - - -.. cvar:: PyTypeObject PyFloat_Type - - .. index:: single: FloatType (in modules types) - - This instance of :ctype:`PyTypeObject` represents the Python floating point - type. This is the same object as ``float`` and ``types.FloatType``. - - -.. cfunction:: int PyFloat_Check(PyObject *p) - - Return true if its argument is a :ctype:`PyFloatObject` or a subtype of - :ctype:`PyFloatObject`. - - -.. cfunction:: int PyFloat_CheckExact(PyObject *p) - - Return true if its argument is a :ctype:`PyFloatObject`, but not a subtype of - :ctype:`PyFloatObject`. - - -.. cfunction:: PyObject* PyFloat_FromString(PyObject *str) - - Create a :ctype:`PyFloatObject` object based on the string value in *str*, or - *NULL* on failure. - - -.. cfunction:: PyObject* PyFloat_FromDouble(double v) - - Create a :ctype:`PyFloatObject` object from *v*, or *NULL* on failure. - - -.. cfunction:: double PyFloat_AsDouble(PyObject *pyfloat) - - Return a C :ctype:`double` representation of the contents of *pyfloat*. If - *pyfloat* is not a Python floating point object but has a :meth:`__float__` - method, this method will first be called to convert *pyfloat* into a float. - - -.. cfunction:: double PyFloat_AS_DOUBLE(PyObject *pyfloat) - - Return a C :ctype:`double` representation of the contents of *pyfloat*, but - without error checking. - - -.. cfunction:: PyObject* PyFloat_GetInfo(void) - - Return a structseq instance which contains information about the - precision, minimum and maximum values of a float. It's a thin wrapper - around the header file :file:`float.h`. - - -.. cfunction:: double PyFloat_GetMax(void) - - Return the maximum representable finite float *DBL_MAX* as C :ctype:`double`. - - -.. cfunction:: double PyFloat_GetMin(void) - - Return the minimum normalized positive float *DBL_MIN* as C :ctype:`double`. - - -.. _complexobjects: - -Complex Number Objects ----------------------- - -.. index:: object: complex number - -Python's complex number objects are implemented as two distinct types when -viewed from the C API: one is the Python object exposed to Python programs, and -the other is a C structure which represents the actual complex number value. -The API provides functions for working with both. - - -Complex Numbers as C Structures -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Note that the functions which accept these structures as parameters and return -them as results do so *by value* rather than dereferencing them through -pointers. This is consistent throughout the API. - - -.. ctype:: Py_complex - - The C structure which corresponds to the value portion of a Python complex - number object. Most of the functions for dealing with complex number objects - use structures of this type as input or output values, as appropriate. It is - defined as:: - - typedef struct { - double real; - double imag; - } Py_complex; - - -.. cfunction:: Py_complex _Py_c_sum(Py_complex left, Py_complex right) - - Return the sum of two complex numbers, using the C :ctype:`Py_complex` - representation. - - -.. cfunction:: Py_complex _Py_c_diff(Py_complex left, Py_complex right) - - Return the difference between two complex numbers, using the C - :ctype:`Py_complex` representation. - - -.. cfunction:: Py_complex _Py_c_neg(Py_complex complex) - - Return the negation of the complex number *complex*, using the C - :ctype:`Py_complex` representation. - - -.. cfunction:: Py_complex _Py_c_prod(Py_complex left, Py_complex right) - - Return the product of two complex numbers, using the C :ctype:`Py_complex` - representation. - - -.. cfunction:: Py_complex _Py_c_quot(Py_complex dividend, Py_complex divisor) - - Return the quotient of two complex numbers, using the C :ctype:`Py_complex` - representation. - - -.. cfunction:: Py_complex _Py_c_pow(Py_complex num, Py_complex exp) - - Return the exponentiation of *num* by *exp*, using the C :ctype:`Py_complex` - representation. - - -Complex Numbers as Python Objects -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - -.. ctype:: PyComplexObject - - This subtype of :ctype:`PyObject` represents a Python complex number object. - - -.. cvar:: PyTypeObject PyComplex_Type - - This instance of :ctype:`PyTypeObject` represents the Python complex number - type. It is the same object as ``complex`` and ``types.ComplexType``. - - -.. cfunction:: int PyComplex_Check(PyObject *p) - - Return true if its argument is a :ctype:`PyComplexObject` or a subtype of - :ctype:`PyComplexObject`. - - -.. cfunction:: int PyComplex_CheckExact(PyObject *p) - - Return true if its argument is a :ctype:`PyComplexObject`, but not a subtype of - :ctype:`PyComplexObject`. - - -.. cfunction:: PyObject* PyComplex_FromCComplex(Py_complex v) - - Create a new Python complex number object from a C :ctype:`Py_complex` value. - - -.. cfunction:: PyObject* PyComplex_FromDoubles(double real, double imag) - - Return a new :ctype:`PyComplexObject` object from *real* and *imag*. - - -.. cfunction:: double PyComplex_RealAsDouble(PyObject *op) - - Return the real part of *op* as a C :ctype:`double`. - - -.. cfunction:: double PyComplex_ImagAsDouble(PyObject *op) - - Return the imaginary part of *op* as a C :ctype:`double`. - - -.. cfunction:: Py_complex PyComplex_AsCComplex(PyObject *op) - - Return the :ctype:`Py_complex` value of the complex number *op*. - - If *op* is not a Python complex number object but has a :meth:`__complex__` - method, this method will first be called to convert *op* to a Python complex - number object. + long.rst + bool.rst + float.rst + complex.rst .. _sequenceobjects: @@ -587,2819 +63,44 @@ .. XXX sort out unicode, str, bytes and bytearray -.. _stringobjects: - -String Objects --------------- - -These functions raise :exc:`TypeError` when expecting a string parameter and are -called with a non-string parameter. - -.. index:: object: string - +.. toctree:: -.. ctype:: PyStringObject + string.rst + unicode.rst + buffer.rst + tuple.rst + list.rst - This subtype of :ctype:`PyObject` represents a Python string object. +.. _mapobjects: -.. cvar:: PyTypeObject PyString_Type - - .. index:: single: StringType (in module types) - - This instance of :ctype:`PyTypeObject` represents the Python string type; it is - the same object as ``str`` and ``types.StringType`` in the Python layer. . - +Mapping Objects +=============== -.. cfunction:: int PyString_Check(PyObject *o) +.. index:: object: mapping - Return true if the object *o* is a string object or an instance of a subtype of - the string type. +.. toctree:: + dict.rst -.. cfunction:: int PyString_CheckExact(PyObject *o) - Return true if the object *o* is a string object, but not an instance of a - subtype of the string type. +.. _otherobjects: +Other Objects +============= -.. cfunction:: PyObject* PyString_FromString(const char *v) - - Return a new string object with a copy of the string *v* as value on success, - and *NULL* on failure. The parameter *v* must not be *NULL*; it will not be - checked. - - -.. cfunction:: PyObject* PyString_FromStringAndSize(const char *v, Py_ssize_t len) - - Return a new string object with a copy of the string *v* as value and length - *len* on success, and *NULL* on failure. If *v* is *NULL*, the contents of the - string are uninitialized. - - -.. cfunction:: PyObject* PyString_FromFormat(const char *format, ...) - - Take a C :cfunc:`printf`\ -style *format* string and a variable number of - arguments, calculate the size of the resulting Python string and return a string - with the values formatted into it. The variable arguments must be C types and - must correspond exactly to the format characters in the *format* string. The - following format characters are allowed: - - .. % XXX: This should be exactly the same as the table in PyErr_Format. - .. % One should just refer to the other. - .. % XXX: The descriptions for %zd and %zu are wrong, but the truth is complicated - .. % because not all compilers support the %z width modifier -- we fake it - .. % when necessary via interpolating PY_FORMAT_SIZE_T. - .. % %u, %lu, %zu should have "new in Python 2.5" blurbs. - - +-------------------+---------------+--------------------------------+ - | Format Characters | Type | Comment | - +===================+===============+================================+ - | :attr:`%%` | *n/a* | The literal % character. | - +-------------------+---------------+--------------------------------+ - | :attr:`%c` | int | A single character, | - | | | represented as an C int. | - +-------------------+---------------+--------------------------------+ - | :attr:`%d` | int | Exactly equivalent to | - | | | ``printf("%d")``. | - +-------------------+---------------+--------------------------------+ - | :attr:`%u` | unsigned int | Exactly equivalent to | - | | | ``printf("%u")``. | - +-------------------+---------------+--------------------------------+ - | :attr:`%ld` | long | Exactly equivalent to | - | | | ``printf("%ld")``. | - +-------------------+---------------+--------------------------------+ - | :attr:`%lu` | unsigned long | Exactly equivalent to | - | | | ``printf("%lu")``. | - +-------------------+---------------+--------------------------------+ - | :attr:`%zd` | Py_ssize_t | Exactly equivalent to | - | | | ``printf("%zd")``. | - +-------------------+---------------+--------------------------------+ - | :attr:`%zu` | size_t | Exactly equivalent to | - | | | ``printf("%zu")``. | - +-------------------+---------------+--------------------------------+ - | :attr:`%i` | int | Exactly equivalent to | - | | | ``printf("%i")``. | - +-------------------+---------------+--------------------------------+ - | :attr:`%x` | int | Exactly equivalent to | - | | | ``printf("%x")``. | - +-------------------+---------------+--------------------------------+ - | :attr:`%s` | char\* | A null-terminated C character | - | | | array. | - +-------------------+---------------+--------------------------------+ - | :attr:`%p` | void\* | The hex representation of a C | - | | | pointer. Mostly equivalent to | - | | | ``printf("%p")`` except that | - | | | it is guaranteed to start with | - | | | the literal ``0x`` regardless | - | | | of what the platform's | - | | | ``printf`` yields. | - +-------------------+---------------+--------------------------------+ - - 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. - - -.. cfunction:: PyObject* PyString_FromFormatV(const char *format, va_list vargs) - - Identical to :func:`PyString_FromFormat` except that it takes exactly two - arguments. - - -.. cfunction:: Py_ssize_t PyString_Size(PyObject *string) - - Return the length of the string in string object *string*. - - -.. cfunction:: Py_ssize_t PyString_GET_SIZE(PyObject *string) - - Macro form of :cfunc:`PyString_Size` but without error checking. - - -.. cfunction:: char* PyString_AsString(PyObject *string) - - Return a NUL-terminated representation of the contents of *string*. The pointer - refers to the internal buffer of *string*, not a copy. The data must not be - modified in any way, unless the string was just created using - ``PyString_FromStringAndSize(NULL, size)``. It must not be deallocated. If - *string* is a Unicode object, this function computes the default encoding of - *string* and operates on that. If *string* is not a string object at all, - :cfunc:`PyString_AsString` returns *NULL* and raises :exc:`TypeError`. - - -.. cfunction:: char* PyString_AS_STRING(PyObject *string) - - Macro form of :cfunc:`PyString_AsString` but without error checking. Only - string objects are supported; no Unicode objects should be passed. - - -.. cfunction:: int PyString_AsStringAndSize(PyObject *obj, char **buffer, Py_ssize_t *length) - - Return a NUL-terminated representation of the contents of the object *obj* - through the output variables *buffer* and *length*. - - The function accepts both string and Unicode objects as input. For Unicode - objects it returns the default encoded version of the object. If *length* is - *NULL*, the resulting buffer may not contain NUL characters; if it does, the - function returns ``-1`` and a :exc:`TypeError` is raised. - - The buffer refers to an internal string buffer of *obj*, not a copy. The data - must not be modified in any way, unless the string was just created using - ``PyString_FromStringAndSize(NULL, size)``. It must not be deallocated. If - *string* is a Unicode object, this function computes the default encoding of - *string* and operates on that. If *string* is not a string object at all, - :cfunc:`PyString_AsStringAndSize` returns ``-1`` and raises :exc:`TypeError`. - - -.. cfunction:: void PyString_Concat(PyObject **string, PyObject *newpart) - - Create a new string object in *\*string* containing the contents of *newpart* - appended to *string*; the caller will own the new reference. The reference to - the old value of *string* will be stolen. If the new string cannot be created, - the old reference to *string* will still be discarded and the value of - *\*string* will be set to *NULL*; the appropriate exception will be set. - - -.. cfunction:: void PyString_ConcatAndDel(PyObject **string, PyObject *newpart) - - Create a new string object in *\*string* containing the contents of *newpart* - appended to *string*. This version decrements the reference count of *newpart*. - - -.. cfunction:: int _PyString_Resize(PyObject **string, Py_ssize_t newsize) - - A way to resize a string object even though it is "immutable". Only use this to - build up a brand new string object; don't use this if the string may already be - known in other parts of the code. It is an error to call this function if the - refcount on the input string object is not one. Pass the address of an existing - string object as an lvalue (it may be written into), and the new size desired. - On success, *\*string* holds the resized string object and ``0`` is returned; - the address in *\*string* may differ from its input value. If the reallocation - fails, the original string object at *\*string* is deallocated, *\*string* is - set to *NULL*, a memory exception is set, and ``-1`` is returned. - - -.. cfunction:: PyObject* PyString_Format(PyObject *format, PyObject *args) - - Return a new string object from *format* and *args*. Analogous to ``format % - args``. The *args* argument must be a tuple. - - -.. cfunction:: void PyString_InternInPlace(PyObject **string) - - Intern the argument *\*string* in place. The argument must be the address of a - pointer variable pointing to a Python string object. If there is an existing - interned string that is the same as *\*string*, it sets *\*string* to it - (decrementing the reference count of the old string object and incrementing the - reference count of the interned string object), otherwise it leaves *\*string* - alone and interns it (incrementing its reference count). (Clarification: even - though there is a lot of talk about reference counts, think of this function as - reference-count-neutral; you own the object after the call if and only if you - owned it before the call.) - - -.. cfunction:: PyObject* PyString_InternFromString(const char *v) - - A combination of :cfunc:`PyString_FromString` and - :cfunc:`PyString_InternInPlace`, returning either a new string object that has - been interned, or a new ("owned") reference to an earlier interned string object - with the same value. - - -.. cfunction:: PyObject* PyString_Decode(const char *s, Py_ssize_t size, const char *encoding, const char *errors) - - Create an object by decoding *size* bytes of the encoded buffer *s* using the - codec registered for *encoding*. *encoding* and *errors* have the same meaning - as the parameters of the same name in the :func:`unicode` built-in function. - The codec to be used is looked up using the Python codec registry. Return - *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyString_AsDecodedObject(PyObject *str, const char *encoding, const char *errors) - - Decode a string object by passing it to the codec registered for *encoding* and - return the result as Python object. *encoding* and *errors* have the same - meaning as the parameters of the same name in the string :meth:`encode` method. - The codec to be used is looked up using the Python codec registry. Return *NULL* - if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyString_AsEncodedObject(PyObject *str, const char *encoding, const char *errors) - - Encode a string object using the codec registered for *encoding* and return the - result as Python object. *encoding* and *errors* have the same meaning as the - parameters of the same name in the string :meth:`encode` method. The codec to be - used is looked up using the Python codec registry. Return *NULL* if an exception - was raised by the codec. - - -.. _unicodeobjects: - -Unicode Objects ---------------- - -.. sectionauthor:: Marc-Andre Lemburg - - -These are the basic Unicode object types used for the Unicode implementation in -Python: - -.. % --- Unicode Type ------------------------------------------------------- - - -.. ctype:: Py_UNICODE - - This type represents the storage type which is used by Python internally as - basis for holding Unicode ordinals. Python's default builds use a 16-bit type - for :ctype:`Py_UNICODE` and store Unicode values internally as UCS2. It is also - possible to build a UCS4 version of Python (most recent Linux distributions come - with UCS4 builds of Python). These builds then use a 32-bit type for - :ctype:`Py_UNICODE` and store Unicode data internally as UCS4. On platforms - where :ctype:`wchar_t` is available and compatible with the chosen Python - Unicode build variant, :ctype:`Py_UNICODE` is a typedef alias for - :ctype:`wchar_t` to enhance native platform compatibility. On all other - platforms, :ctype:`Py_UNICODE` is a typedef alias for either :ctype:`unsigned - short` (UCS2) or :ctype:`unsigned long` (UCS4). - -Note that UCS2 and UCS4 Python builds are not binary compatible. Please keep -this in mind when writing extensions or interfaces. - - -.. ctype:: PyUnicodeObject - - This subtype of :ctype:`PyObject` represents a Python Unicode object. - - -.. cvar:: PyTypeObject PyUnicode_Type - - This instance of :ctype:`PyTypeObject` represents the Python Unicode type. It - is exposed to Python code as ``str``. - -The following APIs are really C macros and can be used to do fast checks and to -access internal read-only data of Unicode objects: - - -.. cfunction:: int PyUnicode_Check(PyObject *o) - - Return true if the object *o* is a Unicode object or an instance of a Unicode - subtype. - - -.. cfunction:: int PyUnicode_CheckExact(PyObject *o) - - Return true if the object *o* is a Unicode object, but not an instance of a - subtype. - - -.. cfunction:: Py_ssize_t PyUnicode_GET_SIZE(PyObject *o) - - Return the size of the object. *o* has to be a :ctype:`PyUnicodeObject` (not - checked). - - -.. cfunction:: Py_ssize_t PyUnicode_GET_DATA_SIZE(PyObject *o) - - Return the size of the object's internal buffer in bytes. *o* has to be a - :ctype:`PyUnicodeObject` (not checked). - - -.. cfunction:: Py_UNICODE* PyUnicode_AS_UNICODE(PyObject *o) - - Return a pointer to the internal :ctype:`Py_UNICODE` buffer of the object. *o* - has to be a :ctype:`PyUnicodeObject` (not checked). - - -.. cfunction:: const char* PyUnicode_AS_DATA(PyObject *o) - - Return a pointer to the internal buffer of the object. *o* has to be a - :ctype:`PyUnicodeObject` (not checked). - -Unicode provides many different character properties. The most often needed ones -are available through these macros which are mapped to C functions depending on -the Python configuration. - -.. % --- Unicode character properties --------------------------------------- - - -.. cfunction:: int Py_UNICODE_ISSPACE(Py_UNICODE ch) - - Return 1 or 0 depending on whether *ch* is a whitespace character. - - -.. cfunction:: int Py_UNICODE_ISLOWER(Py_UNICODE ch) - - Return 1 or 0 depending on whether *ch* is a lowercase character. - - -.. cfunction:: int Py_UNICODE_ISUPPER(Py_UNICODE ch) - - Return 1 or 0 depending on whether *ch* is an uppercase character. - - -.. cfunction:: int Py_UNICODE_ISTITLE(Py_UNICODE ch) - - Return 1 or 0 depending on whether *ch* is a titlecase character. - - -.. cfunction:: int Py_UNICODE_ISLINEBREAK(Py_UNICODE ch) - - Return 1 or 0 depending on whether *ch* is a linebreak character. - - -.. cfunction:: int Py_UNICODE_ISDECIMAL(Py_UNICODE ch) - - Return 1 or 0 depending on whether *ch* is a decimal character. - - -.. cfunction:: int Py_UNICODE_ISDIGIT(Py_UNICODE ch) - - Return 1 or 0 depending on whether *ch* is a digit character. - - -.. cfunction:: int Py_UNICODE_ISNUMERIC(Py_UNICODE ch) - - Return 1 or 0 depending on whether *ch* is a numeric character. - - -.. cfunction:: int Py_UNICODE_ISALPHA(Py_UNICODE ch) - - Return 1 or 0 depending on whether *ch* is an alphabetic character. - - -.. cfunction:: int Py_UNICODE_ISALNUM(Py_UNICODE ch) - - Return 1 or 0 depending on whether *ch* is an alphanumeric character. - -These APIs can be used for fast direct character conversions: - - -.. cfunction:: Py_UNICODE Py_UNICODE_TOLOWER(Py_UNICODE ch) - - Return the character *ch* converted to lower case. - - -.. cfunction:: Py_UNICODE Py_UNICODE_TOUPPER(Py_UNICODE ch) - - Return the character *ch* converted to upper case. - - -.. cfunction:: Py_UNICODE Py_UNICODE_TOTITLE(Py_UNICODE ch) - - Return the character *ch* converted to title case. - - -.. cfunction:: int Py_UNICODE_TODECIMAL(Py_UNICODE ch) - - Return the character *ch* converted to a decimal positive integer. Return - ``-1`` if this is not possible. This macro does not raise exceptions. - - -.. cfunction:: int Py_UNICODE_TODIGIT(Py_UNICODE ch) - - Return the character *ch* converted to a single digit integer. Return ``-1`` if - this is not possible. This macro does not raise exceptions. - - -.. cfunction:: double Py_UNICODE_TONUMERIC(Py_UNICODE ch) - - Return the character *ch* converted to a double. Return ``-1.0`` if this is not - possible. This macro does not raise exceptions. - -To create Unicode objects and access their basic sequence properties, use these -APIs: - -.. % --- Plain Py_UNICODE --------------------------------------------------- - - -.. cfunction:: PyObject* PyUnicode_FromUnicode(const Py_UNICODE *u, Py_ssize_t size) - - Create a Unicode Object from the Py_UNICODE buffer *u* of the given size. *u* - may be *NULL* which causes the contents to be undefined. It is the user's - responsibility to fill in the needed data. The buffer is copied into the new - object. If the buffer is not *NULL*, the return value might be a shared object. - Therefore, modification of the resulting Unicode object is only allowed when *u* - is *NULL*. - - -.. cfunction:: PyObject* PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size) - - Create a Unicode Object from the char buffer *u*. The bytes will be interpreted - as being UTF-8 encoded. *u* may also be *NULL* which - causes the contents to be undefined. It is the user's responsibility to fill in - the needed data. The buffer is copied into the new object. If the buffer is not - *NULL*, the return value might be a shared object. Therefore, modification of - the resulting Unicode object is only allowed when *u* is *NULL*. - - -.. cfunction:: PyObject *PyUnicode_FromString(const char *u) - - Create a Unicode object from an UTF-8 encoded null-terminated char buffer - *u*. - - -.. cfunction:: PyObject* PyUnicode_FromFormat(const char *format, ...) - - Take a C :cfunc:`printf`\ -style *format* string and a variable number of - arguments, calculate the size of the resulting Python unicode string and return - a string with the values formatted into it. The variable arguments must be C - types and must correspond exactly to the format characters in the *format* - string. The following format characters are allowed: - - .. % The descriptions for %zd and %zu are wrong, but the truth is complicated - .. % because not all compilers support the %z width modifier -- we fake it - .. % when necessary via interpolating PY_FORMAT_SIZE_T. - - +-------------------+---------------------+--------------------------------+ - | Format Characters | Type | Comment | - +===================+=====================+================================+ - | :attr:`%%` | *n/a* | The literal % character. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%c` | int | A single character, | - | | | represented as an C int. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%d` | int | Exactly equivalent to | - | | | ``printf("%d")``. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%u` | unsigned int | Exactly equivalent to | - | | | ``printf("%u")``. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%ld` | long | Exactly equivalent to | - | | | ``printf("%ld")``. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%lu` | unsigned long | Exactly equivalent to | - | | | ``printf("%lu")``. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%zd` | Py_ssize_t | Exactly equivalent to | - | | | ``printf("%zd")``. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%zu` | size_t | Exactly equivalent to | - | | | ``printf("%zu")``. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%i` | int | Exactly equivalent to | - | | | ``printf("%i")``. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%x` | int | Exactly equivalent to | - | | | ``printf("%x")``. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%s` | char\* | A null-terminated C character | - | | | array. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%p` | void\* | The hex representation of a C | - | | | pointer. Mostly equivalent to | - | | | ``printf("%p")`` except that | - | | | it is guaranteed to start with | - | | | the literal ``0x`` regardless | - | | | of what the platform's | - | | | ``printf`` yields. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%U` | PyObject\* | A unicode object. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%V` | PyObject\*, char \* | A unicode object (which may be | - | | | *NULL*) and a null-terminated | - | | | C character array as a second | - | | | parameter (which will be used, | - | | | if the first parameter is | - | | | *NULL*). | - +-------------------+---------------------+--------------------------------+ - | :attr:`%S` | PyObject\* | The result of calling | - | | | :func:`PyObject_Unicode`. | - +-------------------+---------------------+--------------------------------+ - | :attr:`%R` | PyObject\* | The result of calling | - | | | :func:`PyObject_Repr`. | - +-------------------+---------------------+--------------------------------+ - - 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. - - -.. cfunction:: PyObject* PyUnicode_FromFormatV(const char *format, va_list vargs) - - Identical to :func:`PyUnicode_FromFormat` except that it takes exactly two - arguments. - - -.. cfunction:: Py_UNICODE* PyUnicode_AsUnicode(PyObject *unicode) - - Return a read-only pointer to the Unicode object's internal :ctype:`Py_UNICODE` - buffer, *NULL* if *unicode* is not a Unicode object. - - -.. cfunction:: Py_ssize_t PyUnicode_GetSize(PyObject *unicode) - - Return the length of the Unicode object. - - -.. cfunction:: PyObject* PyUnicode_FromEncodedObject(PyObject *obj, const char *encoding, const char *errors) - - Coerce an encoded object *obj* to an Unicode object and return a reference with - incremented refcount. - - String and other char buffer compatible objects are decoded according to the - given encoding and using the error handling defined by errors. Both can be - *NULL* to have the interface use the default values (see the next section for - details). - - All other objects, including Unicode objects, cause a :exc:`TypeError` to be - set. - - The API returns *NULL* if there was an error. The caller is responsible for - decref'ing the returned objects. - - -.. cfunction:: PyObject* PyUnicode_FromObject(PyObject *obj) - - Shortcut for ``PyUnicode_FromEncodedObject(obj, NULL, "strict")`` which is used - throughout the interpreter whenever coercion to Unicode is needed. - -If the platform supports :ctype:`wchar_t` and provides a header file wchar.h, -Python can interface directly to this type using the following functions. -Support is optimized if Python's own :ctype:`Py_UNICODE` type is identical to -the system's :ctype:`wchar_t`. - -.. % --- wchar_t support for platforms which support it --------------------- - - -.. cfunction:: PyObject* PyUnicode_FromWideChar(const wchar_t *w, Py_ssize_t size) - - Create a Unicode object from the :ctype:`wchar_t` buffer *w* of the given size. - Return *NULL* on failure. - - -.. cfunction:: Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode, wchar_t *w, Py_ssize_t size) - - Copy the Unicode object contents into the :ctype:`wchar_t` buffer *w*. At most - *size* :ctype:`wchar_t` characters are copied (excluding a possibly trailing - 0-termination character). Return the number of :ctype:`wchar_t` characters - copied or -1 in case of an error. Note that the resulting :ctype:`wchar_t` - string may or may not be 0-terminated. It is the responsibility of the caller - to make sure that the :ctype:`wchar_t` string is 0-terminated in case this is - required by the application. - - -.. _builtincodecs: - -Built-in Codecs -^^^^^^^^^^^^^^^ - -Python provides a set of builtin codecs which are written in C for speed. All of -these codecs are directly usable via the following functions. - -Many of the following APIs take two arguments encoding and errors. These -parameters encoding and errors have the same semantics as the ones of the -builtin unicode() Unicode object constructor. - -Setting encoding to *NULL* causes the default encoding to be used which is -ASCII. The file system calls should use :cdata:`Py_FileSystemDefaultEncoding` -as the encoding for file names. This variable should be treated as read-only: On -some systems, it will be a pointer to a static string, on others, it will change -at run-time (such as when the application invokes setlocale). - -Error handling is set by errors which may also be set to *NULL* meaning to use -the default handling defined for the codec. Default error handling for all -builtin codecs is "strict" (:exc:`ValueError` is raised). - -The codecs all use a similar interface. Only deviation from the following -generic ones are documented for simplicity. - -These are the generic codec APIs: - -.. % --- Generic Codecs ----------------------------------------------------- - - -.. cfunction:: PyObject* PyUnicode_Decode(const char *s, Py_ssize_t size, const char *encoding, const char *errors) - - Create a Unicode object by decoding *size* bytes of the encoded string *s*. - *encoding* and *errors* have the same meaning as the parameters of the same name - in the :func:`unicode` builtin function. The codec to be used is looked up - using the Python codec registry. Return *NULL* if an exception was raised by - the codec. - - -.. cfunction:: PyObject* PyUnicode_Encode(const Py_UNICODE *s, Py_ssize_t size, const char *encoding, const char *errors) - - Encode the :ctype:`Py_UNICODE` buffer of the given size and return a Python - string object. *encoding* and *errors* have the same meaning as the parameters - of the same name in the Unicode :meth:`encode` method. The codec to be used is - looked up using the Python codec registry. Return *NULL* if an exception was - raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_AsEncodedString(PyObject *unicode, const char *encoding, const char *errors) - - Encode a Unicode object and return the result as Python string object. - *encoding* and *errors* have the same meaning as the parameters of the same name - in the Unicode :meth:`encode` method. The codec to be used is looked up using - the Python codec registry. Return *NULL* if an exception was raised by the - codec. - -These are the UTF-8 codec APIs: - -.. % --- UTF-8 Codecs ------------------------------------------------------- - - -.. cfunction:: PyObject* PyUnicode_DecodeUTF8(const char *s, Py_ssize_t size, const char *errors) - - Create a Unicode object by decoding *size* bytes of the UTF-8 encoded string - *s*. Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_DecodeUTF8Stateful(const char *s, Py_ssize_t size, const char *errors, Py_ssize_t *consumed) - - If *consumed* is *NULL*, behave like :cfunc:`PyUnicode_DecodeUTF8`. If - *consumed* is not *NULL*, trailing incomplete UTF-8 byte sequences will not be - treated as an error. Those bytes will not be decoded and the number of bytes - that have been decoded will be stored in *consumed*. - - -.. cfunction:: PyObject* PyUnicode_EncodeUTF8(const Py_UNICODE *s, Py_ssize_t size, const char *errors) - - Encode the :ctype:`Py_UNICODE` buffer of the given size using UTF-8 and return a - Python string object. Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_AsUTF8String(PyObject *unicode) - - Encode a Unicode objects using UTF-8 and return the result as Python string - object. Error handling is "strict". Return *NULL* if an exception was raised - by the codec. - -These are the UTF-32 codec APIs: - -.. % --- UTF-32 Codecs ------------------------------------------------------ */ - - -.. cfunction:: PyObject* PyUnicode_DecodeUTF32(const char *s, Py_ssize_t size, const char *errors, int *byteorder) - - Decode *length* bytes from a UTF-32 encoded buffer string and return the - corresponding Unicode object. *errors* (if non-*NULL*) defines the error - handling. It defaults to "strict". - - If *byteorder* is non-*NULL*, the decoder starts decoding using the given byte - order:: - - *byteorder == -1: little endian - *byteorder == 0: native order - *byteorder == 1: big endian - - and then switches if the first four bytes of the input data are a byte order mark - (BOM) and the specified byte order is native order. This BOM is not copied into - the resulting Unicode string. After completion, *\*byteorder* is set to the - current byte order at the end of input data. - - In a narrow build codepoints outside the BMP will be decoded as surrogate pairs. - - If *byteorder* is *NULL*, the codec starts in native order mode. - - Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_DecodeUTF32Stateful(const char *s, Py_ssize_t size, const char *errors, int *byteorder, Py_ssize_t *consumed) - - If *consumed* is *NULL*, behave like :cfunc:`PyUnicode_DecodeUTF32`. If - *consumed* is not *NULL*, :cfunc:`PyUnicode_DecodeUTF32Stateful` will not treat - trailing incomplete UTF-32 byte sequences (such as a number of bytes not divisible - by four) as an error. Those bytes will not be decoded and the number of bytes - that have been decoded will be stored in *consumed*. - - -.. cfunction:: PyObject* PyUnicode_EncodeUTF32(const Py_UNICODE *s, Py_ssize_t size, const char *errors, int byteorder) - - Return a Python bytes object holding the UTF-32 encoded value of the Unicode - data in *s*. If *byteorder* is not ``0``, output is written according to the - following byte order:: - - byteorder == -1: little endian - byteorder == 0: native byte order (writes a BOM mark) - byteorder == 1: big endian - - If byteorder is ``0``, the output string will always start with the Unicode BOM - mark (U+FEFF). In the other two modes, no BOM mark is prepended. - - If *Py_UNICODE_WIDE* is not defined, surrogate pairs will be output - as a single codepoint. - - Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_AsUTF32String(PyObject *unicode) - - Return a Python string using the UTF-32 encoding in native byte order. The - string always starts with a BOM mark. Error handling is "strict". Return - *NULL* if an exception was raised by the codec. - - -These are the UTF-16 codec APIs: - -.. % --- UTF-16 Codecs ------------------------------------------------------ */ - - -.. cfunction:: PyObject* PyUnicode_DecodeUTF16(const char *s, Py_ssize_t size, const char *errors, int *byteorder) - - Decode *length* bytes from a UTF-16 encoded buffer string and return the - corresponding Unicode object. *errors* (if non-*NULL*) defines the error - handling. It defaults to "strict". - - If *byteorder* is non-*NULL*, the decoder starts decoding using the given byte - order:: - - *byteorder == -1: little endian - *byteorder == 0: native order - *byteorder == 1: big endian - - and then switches if the first two bytes of the input data are a byte order mark - (BOM) and the specified byte order is native order. This BOM is not copied into - the resulting Unicode string. After completion, *\*byteorder* is set to the - current byte order at the end of input data. - - If *byteorder* is *NULL*, the codec starts in native order mode. - - Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_DecodeUTF16Stateful(const char *s, Py_ssize_t size, const char *errors, int *byteorder, Py_ssize_t *consumed) - - If *consumed* is *NULL*, behave like :cfunc:`PyUnicode_DecodeUTF16`. If - *consumed* is not *NULL*, :cfunc:`PyUnicode_DecodeUTF16Stateful` will not treat - trailing incomplete UTF-16 byte sequences (such as an odd number of bytes or a - split surrogate pair) as an error. Those bytes will not be decoded and the - number of bytes that have been decoded will be stored in *consumed*. - - -.. cfunction:: PyObject* PyUnicode_EncodeUTF16(const Py_UNICODE *s, Py_ssize_t size, const char *errors, int byteorder) - - Return a Python string object holding the UTF-16 encoded value of the Unicode - data in *s*. If *byteorder* is not ``0``, output is written according to the - following byte order:: - - byteorder == -1: little endian - byteorder == 0: native byte order (writes a BOM mark) - byteorder == 1: big endian - - If byteorder is ``0``, the output string will always start with the Unicode BOM - mark (U+FEFF). In the other two modes, no BOM mark is prepended. - - If *Py_UNICODE_WIDE* is defined, a single :ctype:`Py_UNICODE` value may get - represented as a surrogate pair. If it is not defined, each :ctype:`Py_UNICODE` - values is interpreted as an UCS-2 character. - - Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_AsUTF16String(PyObject *unicode) - - Return a Python string using the UTF-16 encoding in native byte order. The - string always starts with a BOM mark. Error handling is "strict". Return - *NULL* if an exception was raised by the codec. - -These are the "Unicode Escape" codec APIs: - -.. % --- Unicode-Escape Codecs ---------------------------------------------- - - -.. cfunction:: PyObject* PyUnicode_DecodeUnicodeEscape(const char *s, Py_ssize_t size, const char *errors) - - Create a Unicode object by decoding *size* bytes of the Unicode-Escape encoded - string *s*. Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size) - - Encode the :ctype:`Py_UNICODE` buffer of the given size using Unicode-Escape and - return a Python string object. Return *NULL* if an exception was raised by the - codec. - - -.. cfunction:: PyObject* PyUnicode_AsUnicodeEscapeString(PyObject *unicode) - - Encode a Unicode objects using Unicode-Escape and return the result as Python - string object. Error handling is "strict". Return *NULL* if an exception was - raised by the codec. - -These are the "Raw Unicode Escape" codec APIs: - -.. % --- Raw-Unicode-Escape Codecs ------------------------------------------ - - -.. cfunction:: PyObject* PyUnicode_DecodeRawUnicodeEscape(const char *s, Py_ssize_t size, const char *errors) - - Create a Unicode object by decoding *size* bytes of the Raw-Unicode-Escape - encoded string *s*. Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size, const char *errors) - - Encode the :ctype:`Py_UNICODE` buffer of the given size using Raw-Unicode-Escape - and return a Python string object. Return *NULL* if an exception was raised by - the codec. - - -.. cfunction:: PyObject* PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode) - - Encode a Unicode objects using Raw-Unicode-Escape and return the result as - Python string object. Error handling is "strict". Return *NULL* if an exception - was raised by the codec. - -These are the Latin-1 codec APIs: Latin-1 corresponds to the first 256 Unicode -ordinals and only these are accepted by the codecs during encoding. - -.. % --- Latin-1 Codecs ----------------------------------------------------- - - -.. cfunction:: PyObject* PyUnicode_DecodeLatin1(const char *s, Py_ssize_t size, const char *errors) - - Create a Unicode object by decoding *size* bytes of the Latin-1 encoded string - *s*. Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_EncodeLatin1(const Py_UNICODE *s, Py_ssize_t size, const char *errors) - - Encode the :ctype:`Py_UNICODE` buffer of the given size using Latin-1 and return - a Python string object. Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_AsLatin1String(PyObject *unicode) - - Encode a Unicode objects using Latin-1 and return the result as Python string - object. Error handling is "strict". Return *NULL* if an exception was raised - by the codec. - -These are the ASCII codec APIs. Only 7-bit ASCII data is accepted. All other -codes generate errors. - -.. % --- ASCII Codecs ------------------------------------------------------- - - -.. cfunction:: PyObject* PyUnicode_DecodeASCII(const char *s, Py_ssize_t size, const char *errors) - - Create a Unicode object by decoding *size* bytes of the ASCII encoded string - *s*. Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_EncodeASCII(const Py_UNICODE *s, Py_ssize_t size, const char *errors) - - Encode the :ctype:`Py_UNICODE` buffer of the given size using ASCII and return a - Python string object. Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_AsASCIIString(PyObject *unicode) - - Encode a Unicode objects using ASCII and return the result as Python string - object. Error handling is "strict". Return *NULL* if an exception was raised - by the codec. - -These are the mapping codec APIs: - -.. % --- Character Map Codecs ----------------------------------------------- - -This codec is special in that it can be used to implement many different codecs -(and this is in fact what was done to obtain most of the standard codecs -included in the :mod:`encodings` package). The codec uses mapping to encode and -decode characters. - -Decoding mappings must map single string characters to single Unicode -characters, integers (which are then interpreted as Unicode ordinals) or None -(meaning "undefined mapping" and causing an error). - -Encoding mappings must map single Unicode characters to single string -characters, integers (which are then interpreted as Latin-1 ordinals) or None -(meaning "undefined mapping" and causing an error). - -The mapping objects provided must only support the __getitem__ mapping -interface. - -If a character lookup fails with a LookupError, the character is copied as-is -meaning that its ordinal value will be interpreted as Unicode or Latin-1 ordinal -resp. Because of this, mappings only need to contain those mappings which map -characters to different code points. - - -.. cfunction:: PyObject* PyUnicode_DecodeCharmap(const char *s, Py_ssize_t size, PyObject *mapping, const char *errors) - - Create a Unicode object by decoding *size* bytes of the encoded string *s* using - the given *mapping* object. Return *NULL* if an exception was raised by the - codec. If *mapping* is *NULL* latin-1 decoding will be done. Else it can be a - dictionary mapping byte or a unicode string, which is treated as a lookup table. - Byte values greater that the length of the string and U+FFFE "characters" are - treated as "undefined mapping". - - -.. cfunction:: PyObject* PyUnicode_EncodeCharmap(const Py_UNICODE *s, Py_ssize_t size, PyObject *mapping, const char *errors) - - Encode the :ctype:`Py_UNICODE` buffer of the given size using the given - *mapping* object and return a Python string object. Return *NULL* if an - exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_AsCharmapString(PyObject *unicode, PyObject *mapping) - - Encode a Unicode objects using the given *mapping* object and return the result - as Python string object. Error handling is "strict". Return *NULL* if an - exception was raised by the codec. - -The following codec API is special in that maps Unicode to Unicode. - - -.. cfunction:: PyObject* PyUnicode_TranslateCharmap(const Py_UNICODE *s, Py_ssize_t size, PyObject *table, const char *errors) - - Translate a :ctype:`Py_UNICODE` buffer of the given length by applying a - character mapping *table* to it and return the resulting Unicode object. Return - *NULL* when an exception was raised by the codec. - - The *mapping* table must map Unicode ordinal integers to Unicode ordinal - integers or None (causing deletion of the character). - - Mapping tables need only provide the :meth:`__getitem__` interface; dictionaries - and sequences work well. Unmapped character ordinals (ones which cause a - :exc:`LookupError`) are left untouched and are copied as-is. - -These are the MBCS codec APIs. They are currently only available on Windows and -use the Win32 MBCS converters to implement the conversions. Note that MBCS (or -DBCS) is a class of encodings, not just one. The target encoding is defined by -the user settings on the machine running the codec. - -.. % --- MBCS codecs for Windows -------------------------------------------- - - -.. cfunction:: PyObject* PyUnicode_DecodeMBCS(const char *s, Py_ssize_t size, const char *errors) - - Create a Unicode object by decoding *size* bytes of the MBCS encoded string *s*. - Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_DecodeMBCSStateful(const char *s, int size, const char *errors, int *consumed) - - If *consumed* is *NULL*, behave like :cfunc:`PyUnicode_DecodeMBCS`. If - *consumed* is not *NULL*, :cfunc:`PyUnicode_DecodeMBCSStateful` will not decode - trailing lead byte and the number of bytes that have been decoded will be stored - in *consumed*. - - -.. cfunction:: PyObject* PyUnicode_EncodeMBCS(const Py_UNICODE *s, Py_ssize_t size, const char *errors) - - Encode the :ctype:`Py_UNICODE` buffer of the given size using MBCS and return a - Python string object. Return *NULL* if an exception was raised by the codec. - - -.. cfunction:: PyObject* PyUnicode_AsMBCSString(PyObject *unicode) - - Encode a Unicode objects using MBCS and return the result as Python string - object. Error handling is "strict". Return *NULL* if an exception was raised - by the codec. - -.. % --- Methods & Slots ---------------------------------------------------- - - -.. _unicodemethodsandslots: - -Methods and Slot Functions -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The following APIs are capable of handling Unicode objects and strings on input -(we refer to them as strings in the descriptions) and return Unicode objects or -integers as appropriate. - -They all return *NULL* or ``-1`` if an exception occurs. - - -.. cfunction:: PyObject* PyUnicode_Concat(PyObject *left, PyObject *right) - - Concat two strings giving a new Unicode string. - - -.. cfunction:: PyObject* PyUnicode_Split(PyObject *s, PyObject *sep, Py_ssize_t maxsplit) - - Split a string giving a list of Unicode strings. If sep is *NULL*, splitting - will be done at all whitespace substrings. Otherwise, splits occur at the given - separator. At most *maxsplit* splits will be done. If negative, no limit is - set. Separators are not included in the resulting list. - - -.. cfunction:: PyObject* PyUnicode_Splitlines(PyObject *s, int keepend) - - Split a Unicode string at line breaks, returning a list of Unicode strings. - CRLF is considered to be one line break. If *keepend* is 0, the Line break - characters are not included in the resulting strings. - - -.. cfunction:: PyObject* PyUnicode_Translate(PyObject *str, PyObject *table, const char *errors) - - Translate a string by applying a character mapping table to it and return the - resulting Unicode object. - - The mapping table must map Unicode ordinal integers to Unicode ordinal integers - or None (causing deletion of the character). - - Mapping tables need only provide the :meth:`__getitem__` interface; dictionaries - and sequences work well. Unmapped character ordinals (ones which cause a - :exc:`LookupError`) are left untouched and are copied as-is. - - *errors* has the usual meaning for codecs. It may be *NULL* which indicates to - use the default error handling. - - -.. cfunction:: PyObject* PyUnicode_Join(PyObject *separator, PyObject *seq) - - Join a sequence of strings using the given separator and return the resulting - Unicode string. - - -.. cfunction:: int PyUnicode_Tailmatch(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction) - - Return 1 if *substr* matches *str*[*start*:*end*] at the given tail end - (*direction* == -1 means to do a prefix match, *direction* == 1 a suffix match), - 0 otherwise. Return ``-1`` if an error occurred. - - -.. cfunction:: Py_ssize_t PyUnicode_Find(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction) - - Return the first position of *substr* in *str*[*start*:*end*] using the given - *direction* (*direction* == 1 means to do a forward search, *direction* == -1 a - backward search). The return value is the index of the first match; a value of - ``-1`` indicates that no match was found, and ``-2`` indicates that an error - occurred and an exception has been set. - - -.. cfunction:: Py_ssize_t PyUnicode_Count(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end) - - Return the number of non-overlapping occurrences of *substr* in - ``str[start:end]``. Return ``-1`` if an error occurred. - - -.. cfunction:: PyObject* PyUnicode_Replace(PyObject *str, PyObject *substr, PyObject *replstr, Py_ssize_t maxcount) - - Replace at most *maxcount* occurrences of *substr* in *str* with *replstr* and - return the resulting Unicode object. *maxcount* == -1 means replace all - occurrences. - - -.. cfunction:: int PyUnicode_Compare(PyObject *left, PyObject *right) - - Compare two strings and return -1, 0, 1 for less than, equal, and greater than, - respectively. - - -.. cfunction:: int PyUnicode_RichCompare(PyObject *left, PyObject *right, int op) - - Rich compare two unicode strings and return one of the following: - - * ``NULL`` in case an exception was raised - * :const:`Py_True` or :const:`Py_False` for successful comparisons - * :const:`Py_NotImplemented` in case the type combination is unknown - - Note that :const:`Py_EQ` and :const:`Py_NE` comparisons can cause a - :exc:`UnicodeWarning` in case the conversion of the arguments to Unicode fails - with a :exc:`UnicodeDecodeError`. - - Possible values for *op* are :const:`Py_GT`, :const:`Py_GE`, :const:`Py_EQ`, - :const:`Py_NE`, :const:`Py_LT`, and :const:`Py_LE`. - - -.. cfunction:: PyObject* PyUnicode_Format(PyObject *format, PyObject *args) - - Return a new string object from *format* and *args*; this is analogous to - ``format % args``. The *args* argument must be a tuple. - - -.. cfunction:: int PyUnicode_Contains(PyObject *container, PyObject *element) - - Check whether *element* is contained in *container* and return true or false - accordingly. - - *element* has to coerce to a one element Unicode string. ``-1`` is returned if - there was an error. - - -.. cfunction:: void PyUnicode_InternInPlace(PyObject **string) - - Intern the argument *\*string* in place. The argument must be the address of a - pointer variable pointing to a Python unicode string object. If there is an - existing interned string that is the same as *\*string*, it sets *\*string* to - it (decrementing the reference count of the old string object and incrementing - the reference count of the interned string object), otherwise it leaves - *\*string* alone and interns it (incrementing its reference count). - (Clarification: even though there is a lot of talk about reference counts, think - of this function as reference-count-neutral; you own the object after the call - if and only if you owned it before the call.) - - -.. cfunction:: PyObject* PyUnicode_InternFromString(const char *v) - - A combination of :cfunc:`PyUnicode_FromString` and - :cfunc:`PyUnicode_InternInPlace`, returning either a new unicode string object - that has been interned, or a new ("owned") reference to an earlier interned - string object with the same value. - - -.. _bufferobjects: - -Buffer Objects --------------- - -.. sectionauthor:: Greg Stein - - -.. index:: - object: buffer - single: buffer interface - -Python objects implemented in C can export a group of functions called the -"buffer interface." These functions can be used by an object to expose its data -in a raw, byte-oriented format. Clients of the object can use the buffer -interface to access the object data directly, without needing to copy it first. - -Two examples of objects that support the buffer interface are strings and -arrays. The string object exposes the character contents in the buffer -interface's byte-oriented form. An array can also expose its contents, but it -should be noted that array elements may be multi-byte values. - -An example user of the buffer interface is the file object's :meth:`write` -method. Any object that can export a series of bytes through the buffer -interface can be written to a file. There are a number of format codes to -:cfunc:`PyArg_ParseTuple` that operate against an object's buffer interface, -returning data from the target object. - -.. index:: single: PyBufferProcs - -More information on the buffer interface is provided in the section -:ref:`buffer-structs`, under the description for :ctype:`PyBufferProcs`. - -A "buffer object" is defined in the :file:`bufferobject.h` header (included by -:file:`Python.h`). These objects look very similar to string objects at the -Python programming level: they support slicing, indexing, concatenation, and -some other standard string operations. However, their data can come from one of -two sources: from a block of memory, or from another object which exports the -buffer interface. - -Buffer objects are useful as a way to expose the data from another object's -buffer interface to the Python programmer. They can also be used as a zero-copy -slicing mechanism. Using their ability to reference a block of memory, it is -possible to expose any data to the Python programmer quite easily. The memory -could be a large, constant array in a C extension, it could be a raw block of -memory for manipulation before passing to an operating system library, or it -could be used to pass around structured data in its native, in-memory format. - - -.. ctype:: PyBufferObject - - This subtype of :ctype:`PyObject` represents a buffer object. - - -.. cvar:: PyTypeObject PyBuffer_Type - - .. index:: single: BufferType (in module types) - - The instance of :ctype:`PyTypeObject` which represents the Python buffer type; - it is the same object as ``buffer`` and ``types.BufferType`` in the Python - layer. . - - -.. cvar:: int Py_END_OF_BUFFER - - This constant may be passed as the *size* parameter to - :cfunc:`PyBuffer_FromObject` or :cfunc:`PyBuffer_FromReadWriteObject`. It - indicates that the new :ctype:`PyBufferObject` should refer to *base* object - from the specified *offset* to the end of its exported buffer. Using this - enables the caller to avoid querying the *base* object for its length. - - -.. cfunction:: int PyBuffer_Check(PyObject *p) - - Return true if the argument has type :cdata:`PyBuffer_Type`. - - -.. cfunction:: PyObject* PyBuffer_FromObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size) - - Return a new read-only buffer object. This raises :exc:`TypeError` if *base* - doesn't support the read-only buffer protocol or doesn't provide exactly one - buffer segment, or it raises :exc:`ValueError` if *offset* is less than zero. - The buffer will hold a reference to the *base* object, and the buffer's contents - will refer to the *base* object's buffer interface, starting as position - *offset* and extending for *size* bytes. If *size* is :const:`Py_END_OF_BUFFER`, - then the new buffer's contents extend to the length of the *base* object's - exported buffer data. - - -.. cfunction:: PyObject* PyBuffer_FromReadWriteObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size) - - Return a new writable buffer object. Parameters and exceptions are similar to - those for :cfunc:`PyBuffer_FromObject`. If the *base* object does not export - the writable buffer protocol, then :exc:`TypeError` is raised. - - -.. cfunction:: PyObject* PyBuffer_FromMemory(void *ptr, Py_ssize_t size) - - Return a new read-only buffer object that reads from a specified location in - memory, with a specified size. The caller is responsible for ensuring that the - memory buffer, passed in as *ptr*, is not deallocated while the returned buffer - object exists. Raises :exc:`ValueError` if *size* is less than zero. Note that - :const:`Py_END_OF_BUFFER` may *not* be passed for the *size* parameter; - :exc:`ValueError` will be raised in that case. - - -.. cfunction:: PyObject* PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size) - - Similar to :cfunc:`PyBuffer_FromMemory`, but the returned buffer is writable. - - -.. cfunction:: PyObject* PyBuffer_New(Py_ssize_t size) - - Return a new writable buffer object that maintains its own memory buffer of - *size* bytes. :exc:`ValueError` is returned if *size* is not zero or positive. - Note that the memory buffer (as returned by :cfunc:`PyObject_AsWriteBuffer`) is - not specifically aligned. - - -.. _tupleobjects: - -Tuple Objects -------------- - -.. index:: object: tuple - - -.. ctype:: PyTupleObject - - This subtype of :ctype:`PyObject` represents a Python tuple object. - - -.. cvar:: PyTypeObject PyTuple_Type - - .. index:: single: TupleType (in module types) - - This instance of :ctype:`PyTypeObject` represents the Python tuple type; it is - the same object as ``tuple`` and ``types.TupleType`` in the Python layer.. - - -.. cfunction:: int PyTuple_Check(PyObject *p) - - Return true if *p* is a tuple object or an instance of a subtype of the tuple - type. - - -.. cfunction:: int PyTuple_CheckExact(PyObject *p) - - Return true if *p* is a tuple object, but not an instance of a subtype of the - tuple type. - - -.. cfunction:: PyObject* PyTuple_New(Py_ssize_t len) - - Return a new tuple object of size *len*, or *NULL* on failure. - - -.. cfunction:: PyObject* PyTuple_Pack(Py_ssize_t n, ...) - - Return a new tuple object of size *n*, or *NULL* on failure. The tuple values - are initialized to the subsequent *n* C arguments pointing to Python objects. - ``PyTuple_Pack(2, a, b)`` is equivalent to ``Py_BuildValue("(OO)", a, b)``. - - -.. cfunction:: Py_ssize_t PyTuple_Size(PyObject *p) - - Take a pointer to a tuple object, and return the size of that tuple. - - -.. cfunction:: Py_ssize_t PyTuple_GET_SIZE(PyObject *p) - - Return the size of the tuple *p*, which must be non-*NULL* and point to a tuple; - no error checking is performed. - - -.. cfunction:: PyObject* PyTuple_GetItem(PyObject *p, Py_ssize_t pos) - - Return the object at position *pos* in the tuple pointed to by *p*. If *pos* is - out of bounds, return *NULL* and sets an :exc:`IndexError` exception. - - -.. cfunction:: PyObject* PyTuple_GET_ITEM(PyObject *p, Py_ssize_t pos) - - Like :cfunc:`PyTuple_GetItem`, but does no checking of its arguments. - - -.. cfunction:: PyObject* PyTuple_GetSlice(PyObject *p, Py_ssize_t low, Py_ssize_t high) - - Take a slice of the tuple pointed to by *p* from *low* to *high* and return it - as a new tuple. - - -.. cfunction:: int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o) - - Insert a reference to object *o* at position *pos* of the tuple pointed to by - *p*. Return ``0`` on success. - - .. note:: - - This function "steals" a reference to *o*. - - -.. cfunction:: void PyTuple_SET_ITEM(PyObject *p, Py_ssize_t pos, PyObject *o) - - Like :cfunc:`PyTuple_SetItem`, but does no error checking, and should *only* be - used to fill in brand new tuples. - - .. note:: - - This function "steals" a reference to *o*. - - -.. cfunction:: int _PyTuple_Resize(PyObject **p, Py_ssize_t newsize) - - Can be used to resize a tuple. *newsize* will be the new length of the tuple. - Because tuples are *supposed* to be immutable, this should only be used if there - is only one reference to the object. Do *not* use this if the tuple may already - be known to some other part of the code. The tuple will always grow or shrink - at the end. Think of this as destroying the old tuple and creating a new one, - only more efficiently. Returns ``0`` on success. Client code should never - assume that the resulting value of ``*p`` will be the same as before calling - this function. If the object referenced by ``*p`` is replaced, the original - ``*p`` is destroyed. On failure, returns ``-1`` and sets ``*p`` to *NULL*, and - raises :exc:`MemoryError` or :exc:`SystemError`. - - -.. _listobjects: - -List Objects ------------- - -.. index:: object: list - - -.. ctype:: PyListObject - - This subtype of :ctype:`PyObject` represents a Python list object. - - -.. cvar:: PyTypeObject PyList_Type - - .. index:: single: ListType (in module types) - - This instance of :ctype:`PyTypeObject` represents the Python list type. This is - the same object as ``list`` and ``types.ListType`` in the Python layer. - - -.. cfunction:: int PyList_Check(PyObject *p) - - Return true if *p* is a list object or an instance of a subtype of the list - type. - - -.. cfunction:: int PyList_CheckExact(PyObject *p) - - Return true if *p* is a list object, but not an instance of a subtype of the - list type. - - -.. cfunction:: PyObject* PyList_New(Py_ssize_t len) - - Return a new list of length *len* on success, or *NULL* on failure. - - .. note:: - - If *length* is greater than zero, the returned list object's items are set to - ``NULL``. Thus you cannot use abstract API functions such as - :cfunc:`PySequence_SetItem` or expose the object to Python code before setting - all items to a real object with :cfunc:`PyList_SetItem`. - - -.. cfunction:: Py_ssize_t PyList_Size(PyObject *list) - - .. index:: builtin: len - - Return the length of the list object in *list*; this is equivalent to - ``len(list)`` on a list object. - - -.. cfunction:: Py_ssize_t PyList_GET_SIZE(PyObject *list) - - Macro form of :cfunc:`PyList_Size` without error checking. - - -.. cfunction:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index) - - Return the object at position *pos* in the list pointed to by *p*. The position - must be positive, indexing from the end of the list is not supported. If *pos* - is out of bounds, return *NULL* and set an :exc:`IndexError` exception. - - -.. cfunction:: PyObject* PyList_GET_ITEM(PyObject *list, Py_ssize_t i) - - Macro form of :cfunc:`PyList_GetItem` without error checking. - - -.. cfunction:: int PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item) - - Set the item at index *index* in list to *item*. Return ``0`` on success or - ``-1`` on failure. - - .. note:: - - This function "steals" a reference to *item* and discards a reference to an item - already in the list at the affected position. - - -.. cfunction:: void PyList_SET_ITEM(PyObject *list, Py_ssize_t i, PyObject *o) - - Macro form of :cfunc:`PyList_SetItem` without error checking. This is normally - only used to fill in new lists where there is no previous content. - - .. note:: - - This function "steals" a reference to *item*, and, unlike - :cfunc:`PyList_SetItem`, does *not* discard a reference to any item that it - being replaced; any reference in *list* at position *i* will be leaked. - - -.. cfunction:: int PyList_Insert(PyObject *list, Py_ssize_t index, PyObject *item) - - Insert the item *item* into list *list* in front of index *index*. Return ``0`` - if successful; return ``-1`` and set an exception if unsuccessful. Analogous to - ``list.insert(index, item)``. - - -.. cfunction:: int PyList_Append(PyObject *list, PyObject *item) - - Append the object *item* at the end of list *list*. Return ``0`` if successful; - return ``-1`` and set an exception if unsuccessful. Analogous to - ``list.append(item)``. - - -.. cfunction:: PyObject* PyList_GetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high) - - Return a list of the objects in *list* containing the objects *between* *low* - and *high*. Return *NULL* and set an exception if unsuccessful. Analogous to - ``list[low:high]``. - - -.. cfunction:: int PyList_SetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high, PyObject *itemlist) - - Set the slice of *list* between *low* and *high* to the contents of *itemlist*. - Analogous to ``list[low:high] = itemlist``. The *itemlist* may be *NULL*, - indicating the assignment of an empty list (slice deletion). Return ``0`` on - success, ``-1`` on failure. - - -.. cfunction:: int PyList_Sort(PyObject *list) - - Sort the items of *list* in place. Return ``0`` on success, ``-1`` on failure. - This is equivalent to ``list.sort()``. - - -.. cfunction:: int PyList_Reverse(PyObject *list) - - Reverse the items of *list* in place. Return ``0`` on success, ``-1`` on - failure. This is the equivalent of ``list.reverse()``. - - -.. cfunction:: PyObject* PyList_AsTuple(PyObject *list) - - .. index:: builtin: tuple - - Return a new tuple object containing the contents of *list*; equivalent to - ``tuple(list)``. - - -.. _mapobjects: - -Mapping Objects -=============== - -.. index:: object: mapping - - -.. _dictobjects: - -Dictionary Objects ------------------- - -.. index:: object: dictionary - - -.. ctype:: PyDictObject - - This subtype of :ctype:`PyObject` represents a Python dictionary object. - - -.. cvar:: PyTypeObject PyDict_Type - - .. index:: - single: DictType (in module types) - single: DictionaryType (in module types) - - This instance of :ctype:`PyTypeObject` represents the Python dictionary type. - This is exposed to Python programs as ``dict`` and ``types.DictType``. - - -.. cfunction:: int PyDict_Check(PyObject *p) - - Return true if *p* is a dict object or an instance of a subtype of the dict - type. - - -.. cfunction:: int PyDict_CheckExact(PyObject *p) - - Return true if *p* is a dict object, but not an instance of a subtype of the - dict type. - - -.. cfunction:: PyObject* PyDict_New() - - Return a new empty dictionary, or *NULL* on failure. - - -.. cfunction:: PyObject* PyDictProxy_New(PyObject *dict) - - Return a proxy object for a mapping which enforces read-only behavior. This is - normally used to create a proxy to prevent modification of the dictionary for - non-dynamic class types. - - -.. cfunction:: void PyDict_Clear(PyObject *p) - - Empty an existing dictionary of all key-value pairs. - - -.. cfunction:: int PyDict_Contains(PyObject *p, PyObject *key) - - Determine if dictionary *p* contains *key*. If an item in *p* is matches *key*, - return ``1``, otherwise return ``0``. On error, return ``-1``. This is - equivalent to the Python expression ``key in p``. - - -.. cfunction:: PyObject* PyDict_Copy(PyObject *p) - - Return a new dictionary that contains the same key-value pairs as *p*. - - -.. cfunction:: int PyDict_SetItem(PyObject *p, PyObject *key, PyObject *val) - - Insert *value* into the dictionary *p* with a key of *key*. *key* must be - :term:`hashable`; if it isn't, :exc:`TypeError` will be raised. Return ``0`` - on success or ``-1`` on failure. - - -.. cfunction:: int PyDict_SetItemString(PyObject *p, const char *key, PyObject *val) - - .. index:: single: PyString_FromString() - - Insert *value* into the dictionary *p* using *key* as a key. *key* should be a - :ctype:`char\*`. The key object is created using ``PyString_FromString(key)``. - Return ``0`` on success or ``-1`` on failure. - - -.. cfunction:: int PyDict_DelItem(PyObject *p, PyObject *key) - - Remove the entry in dictionary *p* with key *key*. *key* must be hashable; if it - isn't, :exc:`TypeError` is raised. Return ``0`` on success or ``-1`` on - failure. - - -.. cfunction:: int PyDict_DelItemString(PyObject *p, char *key) - - Remove the entry in dictionary *p* which has a key specified by the string - *key*. Return ``0`` on success or ``-1`` on failure. - - -.. cfunction:: PyObject* PyDict_GetItem(PyObject *p, PyObject *key) - - Return the object from dictionary *p* which has a key *key*. Return *NULL* if - the key *key* is not present, but *without* setting an exception. - - -.. cfunction:: PyObject* PyDict_GetItemString(PyObject *p, const char *key) - - This is the same as :cfunc:`PyDict_GetItem`, but *key* is specified as a - :ctype:`char\*`, rather than a :ctype:`PyObject\*`. - - -.. cfunction:: PyObject* PyDict_Items(PyObject *p) - - Return a :ctype:`PyListObject` containing all the items from the dictionary, as - in the dictionary method :meth:`dict.items`. - - -.. cfunction:: PyObject* PyDict_Keys(PyObject *p) - - Return a :ctype:`PyListObject` containing all the keys from the dictionary, as - in the dictionary method :meth:`dict.keys`. - - -.. cfunction:: PyObject* PyDict_Values(PyObject *p) - - Return a :ctype:`PyListObject` containing all the values from the dictionary - *p*, as in the dictionary method :meth:`dict.values`. - - -.. cfunction:: Py_ssize_t PyDict_Size(PyObject *p) - - .. index:: builtin: len - - Return the number of items in the dictionary. This is equivalent to ``len(p)`` - on a dictionary. - - -.. cfunction:: int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue) - - Iterate over all key-value pairs in the dictionary *p*. The :ctype:`int` - referred to by *ppos* must be initialized to ``0`` prior to the first call to - this function to start the iteration; the function returns true for each pair in - the dictionary, and false once all pairs have been reported. The parameters - *pkey* and *pvalue* should either point to :ctype:`PyObject\*` variables that - will be filled in with each key and value, respectively, or may be *NULL*. Any - references returned through them are borrowed. *ppos* should not be altered - during iteration. Its value represents offsets within the internal dictionary - structure, and since the structure is sparse, the offsets are not consecutive. - - For example:: - - PyObject *key, *value; - Py_ssize_t pos = 0; - - while (PyDict_Next(self->dict, &pos, &key, &value)) { - /* do something interesting with the values... */ - ... - } - - The dictionary *p* should not be mutated during iteration. It is safe (since - Python 2.1) to modify the values of the keys as you iterate over the dictionary, - but only so long as the set of keys does not change. For example:: - - PyObject *key, *value; - Py_ssize_t pos = 0; - - while (PyDict_Next(self->dict, &pos, &key, &value)) { - long i = PyLong_AsLong(value); - if (i == -1 && PyErr_Occurred()) { - return -1; - } - PyObject *o = PyLong_FromLong(i + 1); - if (o == NULL) - return -1; - if (PyDict_SetItem(self->dict, key, o) < 0) { - Py_DECREF(o); - return -1; - } - Py_DECREF(o); - } - - -.. cfunction:: int PyDict_Merge(PyObject *a, PyObject *b, int override) - - Iterate over mapping object *b* adding key-value pairs to dictionary *a*. *b* - may be a dictionary, or any object supporting :func:`PyMapping_Keys` and - :func:`PyObject_GetItem`. If *override* is true, existing pairs in *a* will be - replaced if a matching key is found in *b*, otherwise pairs will only be added - if there is not a matching key in *a*. Return ``0`` on success or ``-1`` if an - exception was raised. - - -.. cfunction:: int PyDict_Update(PyObject *a, PyObject *b) - - This is the same as ``PyDict_Merge(a, b, 1)`` in C, or ``a.update(b)`` in - Python. Return ``0`` on success or ``-1`` if an exception was raised. - - -.. cfunction:: int PyDict_MergeFromSeq2(PyObject *a, PyObject *seq2, int override) - - Update or merge into dictionary *a*, from the key-value pairs in *seq2*. *seq2* - must be an iterable object producing iterable objects of length 2, viewed as - key-value pairs. In case of duplicate keys, the last wins if *override* is - true, else the first wins. Return ``0`` on success or ``-1`` if an exception was - raised. Equivalent Python (except for the return value):: - - def PyDict_MergeFromSeq2(a, seq2, override): - for key, value in seq2: - if override or key not in a: - a[key] = value - - -.. _otherobjects: - -Other Objects -============= - -.. _fileobjects: - -File Objects ------------- - -.. index:: object: file - -Python's built-in file objects are implemented entirely on the :ctype:`FILE\*` -support from the C standard library. This is an implementation detail and may -change in future releases of Python. - - -.. ctype:: PyFileObject - - This subtype of :ctype:`PyObject` represents a Python file object. - - -.. cvar:: PyTypeObject PyFile_Type - - .. index:: single: FileType (in module types) - - This instance of :ctype:`PyTypeObject` represents the Python file type. This is - exposed to Python programs as ``file`` and ``types.FileType``. - - -.. cfunction:: int PyFile_Check(PyObject *p) - - Return true if its argument is a :ctype:`PyFileObject` or a subtype of - :ctype:`PyFileObject`. - - -.. cfunction:: int PyFile_CheckExact(PyObject *p) - - Return true if its argument is a :ctype:`PyFileObject`, but not a subtype of - :ctype:`PyFileObject`. - - -.. cfunction:: PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding, char *newline, int closefd) - - Create a new :ctype:`PyFileObject` from the file descriptor of an already - opened file *fd*. The arguments *name*, *encoding* and *newline* can be - *NULL* to use the defaults; *buffering* can be *-1* to use the default. - Return *NULL* on failure. - - .. warning:: - - Take care when you are mixing streams and descriptors! For more - information, see `the GNU C Library docs - `_. - - -.. cfunction:: int PyObject_AsFileDescriptor(PyObject *p) - - Return the file descriptor associated with *p* as an :ctype:`int`. If the - object is an integer, its value is returned. If not, the - object's :meth:`fileno` method is called if it exists; the method must return - an integer, which is returned as the file descriptor value. Sets an - exception and returns ``-1`` on failure. - - -.. cfunction:: PyObject* PyFile_GetLine(PyObject *p, int n) - - .. index:: single: EOFError (built-in exception) - - Equivalent to ``p.readline([n])``, this function reads one line from the - object *p*. *p* may be a file object or any object with a :meth:`readline` - method. If *n* is ``0``, exactly one line is read, regardless of the length of - the line. If *n* is greater than ``0``, no more than *n* bytes will be read - from the file; a partial line can be returned. In both cases, an empty string - is returned if the end of the file is reached immediately. If *n* is less than - ``0``, however, one line is read regardless of length, but :exc:`EOFError` is - raised if the end of the file is reached immediately. - - -.. cfunction:: PyObject* PyFile_Name(PyObject *p) - - Return the name of the file specified by *p* as a string object. - - -.. cfunction:: void PyFile_SetBufSize(PyFileObject *p, int n) - - .. index:: single: setvbuf() - - Available on systems with :cfunc:`setvbuf` only. This should only be called - immediately after file object creation. - - -.. cfunction:: int PyFile_SetEncoding(PyFileObject *p, const char *enc) - - Set the file's encoding for Unicode output to *enc*. Return 1 on success and 0 - on failure. - - -.. cfunction:: int PyFile_SoftSpace(PyObject *p, int newflag) - - .. index:: single: softspace (file attribute) - - This function exists for internal use by the interpreter. Set the - :attr:`softspace` attribute of *p* to *newflag* and return the previous value. - *p* does not have to be a file object for this function to work properly; any - object is supported (thought its only interesting if the :attr:`softspace` - attribute can be set). This function clears any errors, and will return ``0`` - as the previous value if the attribute either does not exist or if there were - errors in retrieving it. There is no way to detect errors from this function, - but doing so should not be needed. - - -.. cfunction:: int PyFile_WriteObject(PyObject *obj, PyObject *p, int flags) - - .. index:: single: Py_PRINT_RAW - - Write object *obj* to file object *p*. The only supported flag for *flags* is - :const:`Py_PRINT_RAW`; if given, the :func:`str` of the object is written - instead of the :func:`repr`. Return ``0`` on success or ``-1`` on failure; the - appropriate exception will be set. - - -.. cfunction:: int PyFile_WriteString(const char *s, PyObject *p) - - Write string *s* to file object *p*. Return ``0`` on success or ``-1`` on - failure; the appropriate exception will be set. - - -.. _function-objects: - -Function Objects ----------------- - -.. index:: object: function - -There are a few functions specific to Python functions. - - -.. ctype:: PyFunctionObject - - The C structure used for functions. - - -.. cvar:: PyTypeObject PyFunction_Type - - .. index:: single: MethodType (in module types) - - This is an instance of :ctype:`PyTypeObject` and represents the Python function - type. It is exposed to Python programmers as ``types.FunctionType``. - - -.. cfunction:: int PyFunction_Check(PyObject *o) - - Return true if *o* is a function object (has type :cdata:`PyFunction_Type`). - The parameter must not be *NULL*. - - -.. cfunction:: PyObject* PyFunction_New(PyObject *code, PyObject *globals) - - Return a new function object associated with the code object *code*. *globals* - must be a dictionary with the global variables accessible to the function. - - The function's docstring, name and *__module__* are retrieved from the code - object, the argument defaults and closure are set to *NULL*. - - -.. cfunction:: PyObject* PyFunction_GetCode(PyObject *op) - - Return the code object associated with the function object *op*. - - -.. cfunction:: PyObject* PyFunction_GetGlobals(PyObject *op) - - Return the globals dictionary associated with the function object *op*. - - -.. cfunction:: PyObject* PyFunction_GetModule(PyObject *op) - - Return the *__module__* attribute of the function object *op*. This is normally - a string containing the module name, but can be set to any other object by - Python code. - - -.. cfunction:: PyObject* PyFunction_GetDefaults(PyObject *op) - - Return the argument default values of the function object *op*. This can be a - tuple of arguments or *NULL*. - - -.. cfunction:: int PyFunction_SetDefaults(PyObject *op, PyObject *defaults) - - Set the argument default values for the function object *op*. *defaults* must be - *Py_None* or a tuple. - - Raises :exc:`SystemError` and returns ``-1`` on failure. - - -.. cfunction:: PyObject* PyFunction_GetClosure(PyObject *op) - - Return the closure associated with the function object *op*. This can be *NULL* - or a tuple of cell objects. - - -.. cfunction:: int PyFunction_SetClosure(PyObject *op, PyObject *closure) - - Set the closure associated with the function object *op*. *closure* must be - *Py_None* or a tuple of cell objects. - - Raises :exc:`SystemError` and returns ``-1`` on failure. - - -.. _instancemethod-objects: - -Instance Method Objects ------------------------ - -.. index:: object: instancemethod - -An instance method is a wrapper for a :cdata:`PyCFunction` and the new way -to bind a :cdata:`PyCFunction` to a class object. It replaces the former call -``PyMethod_New(func, NULL, class)``. - - -.. cvar:: PyTypeObject PyInstanceMethod_Type - - This instance of :ctype:`PyTypeObject` represents the Python instance - method type. It is not exposed to Python programs. - - -.. cfunction:: int PyInstanceMethod_Check(PyObject *o) - - Return true if *o* is an instance method object (has type - :cdata:`PyInstanceMethod_Type`). The parameter must not be *NULL*. - - -.. cfunction:: PyObject* PyInstanceMethod_New(PyObject *func) - - Return a new instance method object, with *func* being any callable object - *func* is is the function that will be called when the instance method is - called. - - -.. cfunction:: PyObject* PyInstanceMethod_Function(PyObject *im) - - Return the function object associated with the instance method *im*. - - -.. cfunction:: PyObject* PyInstanceMethod_GET_FUNCTION(PyObject *im) - - Macro version of :cfunc:`PyInstanceMethod_Function` which avoids error checking. - - -.. _method-objects: - -Method Objects --------------- - -.. index:: object: method - -Methods are bound function objects. Methods are always bound to an instance of -an user-defined class. Unbound methods (methods bound to a class object) are -no longer available. - - -.. cvar:: PyTypeObject PyMethod_Type - - .. index:: single: MethodType (in module types) - - This instance of :ctype:`PyTypeObject` represents the Python method type. This - is exposed to Python programs as ``types.MethodType``. - - -.. cfunction:: int PyMethod_Check(PyObject *o) - - Return true if *o* is a method object (has type :cdata:`PyMethod_Type`). The - parameter must not be *NULL*. - - -.. cfunction:: PyObject* PyMethod_New(PyObject *func, PyObject *self) - - Return a new method object, with *func* being any callable object and *self* - the instance the method should be bound. *func* is is the function that will - be called when the method is called. *self* must not be *NULL*. - - -.. cfunction:: PyObject* PyMethod_Function(PyObject *meth) - - Return the function object associated with the method *meth*. - - -.. cfunction:: PyObject* PyMethod_GET_FUNCTION(PyObject *meth) - - Macro version of :cfunc:`PyMethod_Function` which avoids error checking. - - -.. cfunction:: PyObject* PyMethod_Self(PyObject *meth) - - Return the instance associated with the method *meth*. - - -.. cfunction:: PyObject* PyMethod_GET_SELF(PyObject *meth) - - Macro version of :cfunc:`PyMethod_Self` which avoids error checking. - - -.. _moduleobjects: - -Module Objects --------------- - -.. index:: object: module - -There are only a few functions special to module objects. - - -.. cvar:: PyTypeObject PyModule_Type - - .. index:: single: ModuleType (in module types) - - This instance of :ctype:`PyTypeObject` represents the Python module type. This - is exposed to Python programs as ``types.ModuleType``. - - -.. cfunction:: int PyModule_Check(PyObject *p) - - Return true if *p* is a module object, or a subtype of a module object. - - -.. cfunction:: int PyModule_CheckExact(PyObject *p) - - Return true if *p* is a module object, but not a subtype of - :cdata:`PyModule_Type`. - - -.. cfunction:: PyObject* PyModule_New(const char *name) - - .. index:: - single: __name__ (module attribute) - single: __doc__ (module attribute) - single: __file__ (module attribute) - - Return a new module object with the :attr:`__name__` attribute set to *name*. - Only the module's :attr:`__doc__` and :attr:`__name__` attributes are filled in; - the caller is responsible for providing a :attr:`__file__` attribute. - - -.. cfunction:: PyObject* PyModule_GetDict(PyObject *module) - - .. index:: single: __dict__ (module attribute) - - Return the dictionary object that implements *module*'s namespace; this object - is the same as the :attr:`__dict__` attribute of the module object. This - function never fails. It is recommended extensions use other - :cfunc:`PyModule_\*` and :cfunc:`PyObject_\*` functions rather than directly - manipulate a module's :attr:`__dict__`. - - -.. cfunction:: char* PyModule_GetName(PyObject *module) - - .. index:: - single: __name__ (module attribute) - single: SystemError (built-in exception) - - Return *module*'s :attr:`__name__` value. If the module does not provide one, - or if it is not a string, :exc:`SystemError` is raised and *NULL* is returned. - - -.. cfunction:: char* PyModule_GetFilename(PyObject *module) - - .. index:: - single: __file__ (module attribute) - single: SystemError (built-in exception) - - Return the name of the file from which *module* was loaded using *module*'s - :attr:`__file__` attribute. If this is not defined, or if it is not a string, - raise :exc:`SystemError` and return *NULL*. - - -.. cfunction:: int PyModule_AddObject(PyObject *module, const char *name, PyObject *value) - - Add an object to *module* as *name*. This is a convenience function which can - be used from the module's initialization function. This steals a reference to - *value*. Return ``-1`` on error, ``0`` on success. - - -.. cfunction:: int PyModule_AddIntConstant(PyObject *module, const char *name, long value) - - Add an integer constant to *module* as *name*. This convenience function can be - used from the module's initialization function. Return ``-1`` on error, ``0`` on - success. - - -.. cfunction:: int PyModule_AddStringConstant(PyObject *module, const char *name, const char *value) - - Add a string constant to *module* as *name*. This convenience function can be - used from the module's initialization function. The string *value* must be - null-terminated. Return ``-1`` on error, ``0`` on success. - - -.. _iterator-objects: - -Iterator Objects ----------------- - -Python provides two general-purpose iterator objects. The first, a sequence -iterator, works with an arbitrary sequence supporting the :meth:`__getitem__` -method. The second works with a callable object and a sentinel value, calling -the callable for each item in the sequence, and ending the iteration when the -sentinel value is returned. - - -.. cvar:: PyTypeObject PySeqIter_Type - - Type object for iterator objects returned by :cfunc:`PySeqIter_New` and the - one-argument form of the :func:`iter` built-in function for built-in sequence - types. - - -.. cfunction:: int PySeqIter_Check(op) - - Return true if the type of *op* is :cdata:`PySeqIter_Type`. - - -.. cfunction:: PyObject* PySeqIter_New(PyObject *seq) - - Return an iterator that works with a general sequence object, *seq*. The - iteration ends when the sequence raises :exc:`IndexError` for the subscripting - operation. - - -.. cvar:: PyTypeObject PyCallIter_Type - - Type object for iterator objects returned by :cfunc:`PyCallIter_New` and the - two-argument form of the :func:`iter` built-in function. - - -.. cfunction:: int PyCallIter_Check(op) - - Return true if the type of *op* is :cdata:`PyCallIter_Type`. - - -.. cfunction:: PyObject* PyCallIter_New(PyObject *callable, PyObject *sentinel) - - Return a new iterator. The first parameter, *callable*, can be any Python - callable object that can be called with no parameters; each call to it should - return the next item in the iteration. When *callable* returns a value equal to - *sentinel*, the iteration will be terminated. - - -.. _descriptor-objects: - -Descriptor Objects ------------------- - -"Descriptors" are objects that describe some attribute of an object. They are -found in the dictionary of type objects. - -.. XXX document these! - -.. cvar:: PyTypeObject PyProperty_Type - - The type object for the built-in descriptor types. - - -.. cfunction:: PyObject* PyDescr_NewGetSet(PyTypeObject *type, struct PyGetSetDef *getset) - - -.. cfunction:: PyObject* PyDescr_NewMember(PyTypeObject *type, struct PyMemberDef *meth) - - -.. cfunction:: PyObject* PyDescr_NewMethod(PyTypeObject *type, struct PyMethodDef *meth) - - -.. cfunction:: PyObject* PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *wrapper, void *wrapped) - - -.. cfunction:: PyObject* PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method) - - -.. cfunction:: int PyDescr_IsData(PyObject *descr) - - Return true if the descriptor objects *descr* describes a data attribute, or - false if it describes a method. *descr* must be a descriptor object; there is - no error checking. - - -.. cfunction:: PyObject* PyWrapper_New(PyObject *, PyObject *) - - -.. _slice-objects: - -Slice Objects -------------- - - -.. cvar:: PyTypeObject PySlice_Type - - .. index:: single: SliceType (in module types) - - The type object for slice objects. This is the same as ``slice`` and - ``types.SliceType``. - - -.. cfunction:: int PySlice_Check(PyObject *ob) - - Return true if *ob* is a slice object; *ob* must not be *NULL*. - - -.. cfunction:: PyObject* PySlice_New(PyObject *start, PyObject *stop, PyObject *step) - - Return a new slice object with the given values. The *start*, *stop*, and - *step* parameters are used as the values of the slice object attributes of the - same names. Any of the values may be *NULL*, in which case the ``None`` will be - used for the corresponding attribute. Return *NULL* if the new object could not - be allocated. - - -.. cfunction:: int PySlice_GetIndices(PySliceObject *slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step) - - Retrieve the start, stop and step indices from the slice object *slice*, - assuming a sequence of length *length*. Treats indices greater than *length* as - errors. - - Returns 0 on success and -1 on error with no exception set (unless one of the - indices was not :const:`None` and failed to be converted to an integer, in which - case -1 is returned with an exception set). - - You probably do not want to use this function. If you want to use slice objects - in versions of Python prior to 2.3, you would probably do well to incorporate - the source of :cfunc:`PySlice_GetIndicesEx`, suitably renamed, in the source of - your extension. - - -.. cfunction:: int PySlice_GetIndicesEx(PySliceObject *slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength) - - Usable replacement for :cfunc:`PySlice_GetIndices`. Retrieve the start, stop, - and step indices from the slice object *slice* assuming a sequence of length - *length*, and store the length of the slice in *slicelength*. Out of bounds - indices are clipped in a manner consistent with the handling of normal slices. - - Returns 0 on success and -1 on error with exception set. - - -.. _weakrefobjects: - -Weak Reference Objects ----------------------- - -Python supports *weak references* as first-class objects. There are two -specific object types which directly implement weak references. The first is a -simple reference object, and the second acts as a proxy for the original object -as much as it can. - - -.. cfunction:: int PyWeakref_Check(ob) - - Return true if *ob* is either a reference or proxy object. - - -.. cfunction:: int PyWeakref_CheckRef(ob) - - Return true if *ob* is a reference object. - - -.. cfunction:: int PyWeakref_CheckProxy(ob) - - Return true if *ob* is a proxy object. - - -.. cfunction:: PyObject* PyWeakref_NewRef(PyObject *ob, PyObject *callback) - - Return a weak reference object for the object *ob*. This will always return - a new reference, but is not guaranteed to create a new object; an existing - reference object may be returned. The second parameter, *callback*, can be a - callable object that receives notification when *ob* is garbage collected; it - should accept a single parameter, which will be the weak reference object - itself. *callback* may also be ``None`` or *NULL*. If *ob* is not a - weakly-referencable object, or if *callback* is not callable, ``None``, or - *NULL*, this will return *NULL* and raise :exc:`TypeError`. - - -.. cfunction:: PyObject* PyWeakref_NewProxy(PyObject *ob, PyObject *callback) - - Return a weak reference proxy object for the object *ob*. This will always - return a new reference, but is not guaranteed to create a new object; an - existing proxy object may be returned. The second parameter, *callback*, can - be a callable object that receives notification when *ob* is garbage - collected; it should accept a single parameter, which will be the weak - reference object itself. *callback* may also be ``None`` or *NULL*. If *ob* - is not a weakly-referencable object, or if *callback* is not callable, - ``None``, or *NULL*, this will return *NULL* and raise :exc:`TypeError`. - - -.. cfunction:: PyObject* PyWeakref_GetObject(PyObject *ref) - - Return the referenced object from a weak reference, *ref*. If the referent is - no longer live, returns ``None``. - - -.. cfunction:: PyObject* PyWeakref_GET_OBJECT(PyObject *ref) - - Similar to :cfunc:`PyWeakref_GetObject`, but implemented as a macro that does no - error checking. - - -.. _cobjects: - -CObjects --------- - -.. index:: object: CObject - -Refer to *Extending and Embedding the Python Interpreter*, section 1.12, -"Providing a C API for an Extension Module," for more information on using these -objects. - - -.. ctype:: PyCObject - - This subtype of :ctype:`PyObject` represents an opaque value, useful for C - extension modules who need to pass an opaque value (as a :ctype:`void\*` - pointer) through Python code to other C code. It is often used to make a C - function pointer defined in one module available to other modules, so the - regular import mechanism can be used to access C APIs defined in dynamically - loaded modules. - - -.. cfunction:: int PyCObject_Check(PyObject *p) - - Return true if its argument is a :ctype:`PyCObject`. - - -.. cfunction:: PyObject* PyCObject_FromVoidPtr(void* cobj, void (*destr)(void *)) - - Create a :ctype:`PyCObject` from the ``void *`` *cobj*. The *destr* function - will be called when the object is reclaimed, unless it is *NULL*. - - -.. cfunction:: PyObject* PyCObject_FromVoidPtrAndDesc(void* cobj, void* desc, void (*destr)(void *, void *)) - - Create a :ctype:`PyCObject` from the :ctype:`void \*` *cobj*. The *destr* - function will be called when the object is reclaimed. The *desc* argument can - be used to pass extra callback data for the destructor function. - - -.. cfunction:: void* PyCObject_AsVoidPtr(PyObject* self) - - Return the object :ctype:`void \*` that the :ctype:`PyCObject` *self* was - created with. - - -.. cfunction:: void* PyCObject_GetDesc(PyObject* self) - - Return the description :ctype:`void \*` that the :ctype:`PyCObject` *self* was - created with. - - -.. cfunction:: int PyCObject_SetVoidPtr(PyObject* self, void* cobj) - - Set the void pointer inside *self* to *cobj*. The :ctype:`PyCObject` must not - have an associated destructor. Return true on success, false on failure. - - -.. _cell-objects: - -Cell Objects ------------- - -"Cell" objects are used to implement variables referenced by multiple scopes. -For each such variable, a cell object is created to store the value; the local -variables of each stack frame that references the value contains a reference to -the cells from outer scopes which also use that variable. When the value is -accessed, the value contained in the cell is used instead of the cell object -itself. This de-referencing of the cell object requires support from the -generated byte-code; these are not automatically de-referenced when accessed. -Cell objects are not likely to be useful elsewhere. - - -.. ctype:: PyCellObject - - The C structure used for cell objects. - - -.. cvar:: PyTypeObject PyCell_Type - - The type object corresponding to cell objects. - - -.. cfunction:: int PyCell_Check(ob) - - Return true if *ob* is a cell object; *ob* must not be *NULL*. - - -.. cfunction:: PyObject* PyCell_New(PyObject *ob) - - Create and return a new cell object containing the value *ob*. The parameter may - be *NULL*. - - -.. cfunction:: PyObject* PyCell_Get(PyObject *cell) - - Return the contents of the cell *cell*. - - -.. cfunction:: PyObject* PyCell_GET(PyObject *cell) - - Return the contents of the cell *cell*, but without checking that *cell* is - non-*NULL* and a cell object. - - -.. cfunction:: int PyCell_Set(PyObject *cell, PyObject *value) - - Set the contents of the cell object *cell* to *value*. This releases the - reference to any current content of the cell. *value* may be *NULL*. *cell* - must be non-*NULL*; if it is not a cell object, ``-1`` will be returned. On - success, ``0`` will be returned. - - -.. cfunction:: void PyCell_SET(PyObject *cell, PyObject *value) - - Sets the value of the cell object *cell* to *value*. No reference counts are - adjusted, and no checks are made for safety; *cell* must be non-*NULL* and must - be a cell object. - - -.. _gen-objects: - -Generator Objects ------------------ - -Generator objects are what Python uses to implement generator iterators. They -are normally created by iterating over a function that yields values, rather -than explicitly calling :cfunc:`PyGen_New`. - - -.. ctype:: PyGenObject - - The C structure used for generator objects. - - -.. cvar:: PyTypeObject PyGen_Type - - The type object corresponding to generator objects - - -.. cfunction:: int PyGen_Check(ob) - - Return true if *ob* is a generator object; *ob* must not be *NULL*. - - -.. cfunction:: int PyGen_CheckExact(ob) - - Return true if *ob*'s type is *PyGen_Type* is a generator object; *ob* must not - be *NULL*. - - -.. cfunction:: PyObject* PyGen_New(PyFrameObject *frame) - - Create and return a new generator object based on the *frame* object. A - reference to *frame* is stolen by this function. The parameter must not be - *NULL*. - - -.. _datetimeobjects: - -DateTime Objects ----------------- - -Various date and time objects are supplied by the :mod:`datetime` module. -Before using any of these functions, the header file :file:`datetime.h` must be -included in your source (note that this is not included by :file:`Python.h`), -and the macro :cfunc:`PyDateTime_IMPORT` must be invoked. The macro puts a -pointer to a C structure into a static variable, ``PyDateTimeAPI``, that is -used by the following macros. - -Type-check macros: - -.. cfunction:: int PyDate_Check(PyObject *ob) - - Return true if *ob* is of type :cdata:`PyDateTime_DateType` or a subtype of - :cdata:`PyDateTime_DateType`. *ob* must not be *NULL*. - - -.. cfunction:: int PyDate_CheckExact(PyObject *ob) - - Return true if *ob* is of type :cdata:`PyDateTime_DateType`. *ob* must not be - *NULL*. - - -.. cfunction:: int PyDateTime_Check(PyObject *ob) - - Return true if *ob* is of type :cdata:`PyDateTime_DateTimeType` or a subtype of - :cdata:`PyDateTime_DateTimeType`. *ob* must not be *NULL*. - - -.. cfunction:: int PyDateTime_CheckExact(PyObject *ob) - - Return true if *ob* is of type :cdata:`PyDateTime_DateTimeType`. *ob* must not - be *NULL*. - - -.. cfunction:: int PyTime_Check(PyObject *ob) - - Return true if *ob* is of type :cdata:`PyDateTime_TimeType` or a subtype of - :cdata:`PyDateTime_TimeType`. *ob* must not be *NULL*. - - -.. cfunction:: int PyTime_CheckExact(PyObject *ob) - - Return true if *ob* is of type :cdata:`PyDateTime_TimeType`. *ob* must not be - *NULL*. - - -.. cfunction:: int PyDelta_Check(PyObject *ob) - - Return true if *ob* is of type :cdata:`PyDateTime_DeltaType` or a subtype of - :cdata:`PyDateTime_DeltaType`. *ob* must not be *NULL*. - - -.. cfunction:: int PyDelta_CheckExact(PyObject *ob) - - Return true if *ob* is of type :cdata:`PyDateTime_DeltaType`. *ob* must not be - *NULL*. - - -.. cfunction:: int PyTZInfo_Check(PyObject *ob) - - Return true if *ob* is of type :cdata:`PyDateTime_TZInfoType` or a subtype of - :cdata:`PyDateTime_TZInfoType`. *ob* must not be *NULL*. - - -.. cfunction:: int PyTZInfo_CheckExact(PyObject *ob) - - Return true if *ob* is of type :cdata:`PyDateTime_TZInfoType`. *ob* must not be - *NULL*. - - -Macros to create objects: - -.. cfunction:: PyObject* PyDate_FromDate(int year, int month, int day) - - Return a ``datetime.date`` object with the specified year, month and day. - - -.. cfunction:: PyObject* PyDateTime_FromDateAndTime(int year, int month, int day, int hour, int minute, int second, int usecond) - - Return a ``datetime.datetime`` object with the specified year, month, day, hour, - minute, second and microsecond. - - -.. cfunction:: PyObject* PyTime_FromTime(int hour, int minute, int second, int usecond) - - Return a ``datetime.time`` object with the specified hour, minute, second and - microsecond. - - -.. cfunction:: PyObject* PyDelta_FromDSU(int days, int seconds, int useconds) - - Return a ``datetime.timedelta`` object representing the given number of days, - seconds and microseconds. Normalization is performed so that the resulting - number of microseconds and seconds lie in the ranges documented for - ``datetime.timedelta`` objects. - - -Macros to extract fields from date objects. The argument must be an instance of -:cdata:`PyDateTime_Date`, including subclasses (such as -:cdata:`PyDateTime_DateTime`). The argument must not be *NULL*, and the type is -not checked: - -.. cfunction:: int PyDateTime_GET_YEAR(PyDateTime_Date *o) - - Return the year, as a positive int. - - -.. cfunction:: int PyDateTime_GET_MONTH(PyDateTime_Date *o) - - Return the month, as an int from 1 through 12. - - -.. cfunction:: int PyDateTime_GET_DAY(PyDateTime_Date *o) - - Return the day, as an int from 1 through 31. - - -Macros to extract fields from datetime objects. The argument must be an -instance of :cdata:`PyDateTime_DateTime`, including subclasses. The argument -must not be *NULL*, and the type is not checked: - -.. cfunction:: int PyDateTime_DATE_GET_HOUR(PyDateTime_DateTime *o) - - Return the hour, as an int from 0 through 23. - - -.. cfunction:: int PyDateTime_DATE_GET_MINUTE(PyDateTime_DateTime *o) - - Return the minute, as an int from 0 through 59. - - -.. cfunction:: int PyDateTime_DATE_GET_SECOND(PyDateTime_DateTime *o) - - Return the second, as an int from 0 through 59. - - -.. cfunction:: int PyDateTime_DATE_GET_MICROSECOND(PyDateTime_DateTime *o) - - Return the microsecond, as an int from 0 through 999999. - - -Macros to extract fields from time objects. The argument must be an instance of -:cdata:`PyDateTime_Time`, including subclasses. The argument must not be *NULL*, -and the type is not checked: - -.. cfunction:: int PyDateTime_TIME_GET_HOUR(PyDateTime_Time *o) - - Return the hour, as an int from 0 through 23. - - -.. cfunction:: int PyDateTime_TIME_GET_MINUTE(PyDateTime_Time *o) - - Return the minute, as an int from 0 through 59. - - -.. cfunction:: int PyDateTime_TIME_GET_SECOND(PyDateTime_Time *o) - - Return the second, as an int from 0 through 59. - - -.. cfunction:: int PyDateTime_TIME_GET_MICROSECOND(PyDateTime_Time *o) - - Return the microsecond, as an int from 0 through 999999. - - -Macros for the convenience of modules implementing the DB API: - -.. cfunction:: PyObject* PyDateTime_FromTimestamp(PyObject *args) - - Create and return a new ``datetime.datetime`` object given an argument tuple - suitable for passing to ``datetime.datetime.fromtimestamp()``. - - -.. cfunction:: PyObject* PyDate_FromTimestamp(PyObject *args) - - Create and return a new ``datetime.date`` object given an argument tuple - suitable for passing to ``datetime.date.fromtimestamp()``. - - -.. _setobjects: - -Set Objects ------------ - -.. sectionauthor:: Raymond D. Hettinger - - -.. index:: - object: set - object: frozenset - -This section details the public API for :class:`set` and :class:`frozenset` -objects. Any functionality not listed below is best accessed using the either -the abstract object protocol (including :cfunc:`PyObject_CallMethod`, -:cfunc:`PyObject_RichCompareBool`, :cfunc:`PyObject_Hash`, -:cfunc:`PyObject_Repr`, :cfunc:`PyObject_IsTrue`, :cfunc:`PyObject_Print`, and -:cfunc:`PyObject_GetIter`) or the abstract number protocol (including -:cfunc:`PyNumber_And`, :cfunc:`PyNumber_Subtract`, :cfunc:`PyNumber_Or`, -:cfunc:`PyNumber_Xor`, :cfunc:`PyNumber_InPlaceAnd`, -:cfunc:`PyNumber_InPlaceSubtract`, :cfunc:`PyNumber_InPlaceOr`, and -:cfunc:`PyNumber_InPlaceXor`). - - -.. ctype:: PySetObject - - This subtype of :ctype:`PyObject` is used to hold the internal data for both - :class:`set` and :class:`frozenset` objects. It is like a :ctype:`PyDictObject` - in that it is a fixed size for small sets (much like tuple storage) and will - point to a separate, variable sized block of memory for medium and large sized - sets (much like list storage). None of the fields of this structure should be - considered public and are subject to change. All access should be done through - the documented API rather than by manipulating the values in the structure. - - -.. cvar:: PyTypeObject PySet_Type - - This is an instance of :ctype:`PyTypeObject` representing the Python - :class:`set` type. - - -.. cvar:: PyTypeObject PyFrozenSet_Type - - This is an instance of :ctype:`PyTypeObject` representing the Python - :class:`frozenset` type. - -The following type check macros work on pointers to any Python object. Likewise, -the constructor functions work with any iterable Python object. - - -.. cfunction:: int PyAnySet_Check(PyObject *p) - - Return true if *p* is a :class:`set` object, a :class:`frozenset` object, or an - instance of a subtype. - - -.. cfunction:: int PyAnySet_CheckExact(PyObject *p) - - Return true if *p* is a :class:`set` object or a :class:`frozenset` object but - not an instance of a subtype. - - -.. cfunction:: int PyFrozenSet_CheckExact(PyObject *p) - - Return true if *p* is a :class:`frozenset` object but not an instance of a - subtype. - - -.. cfunction:: PyObject* PySet_New(PyObject *iterable) - - Return a new :class:`set` containing objects returned by the *iterable*. The - *iterable* may be *NULL* to create a new empty set. Return the new set on - success or *NULL* on failure. Raise :exc:`TypeError` if *iterable* is not - actually iterable. The constructor is also useful for copying a set - (``c=set(s)``). - - -.. cfunction:: PyObject* PyFrozenSet_New(PyObject *iterable) - - Return a new :class:`frozenset` containing objects returned by the *iterable*. - The *iterable* may be *NULL* to create a new empty frozenset. Return the new - set on success or *NULL* on failure. Raise :exc:`TypeError` if *iterable* is - not actually iterable. - -The following functions and macros are available for instances of :class:`set` -or :class:`frozenset` or instances of their subtypes. - - -.. cfunction:: Py_ssize_t PySet_Size(PyObject *anyset) - - .. index:: builtin: len - - Return the length of a :class:`set` or :class:`frozenset` object. Equivalent to - ``len(anyset)``. Raises a :exc:`PyExc_SystemError` if *anyset* is not a - :class:`set`, :class:`frozenset`, or an instance of a subtype. - - -.. cfunction:: Py_ssize_t PySet_GET_SIZE(PyObject *anyset) - - Macro form of :cfunc:`PySet_Size` without error checking. - - -.. cfunction:: int PySet_Contains(PyObject *anyset, PyObject *key) - - Return 1 if found, 0 if not found, and -1 if an error is encountered. Unlike - the Python :meth:`__contains__` method, this function does not automatically - convert unhashable sets into temporary frozensets. Raise a :exc:`TypeError` if - the *key* is unhashable. Raise :exc:`PyExc_SystemError` if *anyset* is not a - :class:`set`, :class:`frozenset`, or an instance of a subtype. - -The following functions are available for instances of :class:`set` or its -subtypes but not for instances of :class:`frozenset` or its subtypes. - - -.. cfunction:: int PySet_Add(PyObject *set, PyObject *key) - - Add *key* to a :class:`set` instance. Does not apply to :class:`frozenset` - instances. Return 0 on success or -1 on failure. Raise a :exc:`TypeError` if - the *key* is unhashable. Raise a :exc:`MemoryError` if there is no room to grow. - Raise a :exc:`SystemError` if *set* is an not an instance of :class:`set` or its - subtype. - - -.. cfunction:: int PySet_Discard(PyObject *set, PyObject *key) - - Return 1 if found and removed, 0 if not found (no action taken), and -1 if an - error is encountered. Does not raise :exc:`KeyError` for missing keys. Raise a - :exc:`TypeError` if the *key* is unhashable. Unlike the Python :meth:`discard` - method, this function does not automatically convert unhashable sets into - temporary frozensets. Raise :exc:`PyExc_SystemError` if *set* is an not an - instance of :class:`set` or its subtype. - - -.. cfunction:: PyObject* PySet_Pop(PyObject *set) - - Return a new reference to an arbitrary object in the *set*, and removes the - object from the *set*. Return *NULL* on failure. Raise :exc:`KeyError` if the - set is empty. Raise a :exc:`SystemError` if *set* is an not an instance of - :class:`set` or its subtype. - - -.. cfunction:: int PySet_Clear(PyObject *set) - - Empty an existing set of all elements. +.. toctree:: + set.rst + function.rst + method.rst + file.rst + module.rst + iterator.rst + descriptor.rst + slice.rst + weakref.rst + cobject.rst + cell.rst + gen.rst + datetime.rst Deleted: /python/branches/py3k-ctypes-pep3118/Doc/c-api/newtypes.rst ============================================================================== --- /python/branches/py3k-ctypes-pep3118/Doc/c-api/newtypes.rst Sun Jan 20 11:45:31 2008 +++ (empty file) @@ -1,1855 +0,0 @@ -.. highlightlang:: c - - -.. _newtypes: - -***************************** -Object Implementation Support -***************************** - -This chapter describes the functions, types, and macros used when defining new -object types. - - -.. _allocating-objects: - -Allocating Objects on the Heap -============================== - - -.. cfunction:: PyObject* _PyObject_New(PyTypeObject *type) - - -.. cfunction:: PyVarObject* _PyObject_NewVar(PyTypeObject *type, Py_ssize_t size) - - -.. cfunction:: PyObject* PyObject_Init(PyObject *op, PyTypeObject *type) - - Initialize a newly-allocated object *op* with its type and initial reference. - Returns the initialized object. If *type* indicates that the object - participates in the cyclic garbage detector, it is added to the detector's set - of observed objects. Other fields of the object are not affected. - - -.. cfunction:: PyVarObject* PyObject_InitVar(PyVarObject *op, PyTypeObject *type, Py_ssize_t size) - - This does everything :cfunc:`PyObject_Init` does, and also initializes the - length information for a variable-size object. - - -.. cfunction:: TYPE* PyObject_New(TYPE, PyTypeObject *type) - - Allocate a new Python object using the C structure type *TYPE* and the Python - type object *type*. Fields not defined by the Python object header are not - initialized; the object's reference count will be one. The size of the memory - allocation is determined from the :attr:`tp_basicsize` field of the type object. - - -.. cfunction:: TYPE* PyObject_NewVar(TYPE, PyTypeObject *type, Py_ssize_t size) - - Allocate a new Python object using the C structure type *TYPE* and the Python - type object *type*. Fields not defined by the Python object header are not - initialized. The allocated memory allows for the *TYPE* structure plus *size* - fields of the size given by the :attr:`tp_itemsize` field of *type*. This is - useful for implementing objects like tuples, which are able to determine their - size at construction time. Embedding the array of fields into the same - allocation decreases the number of allocations, improving the memory management - efficiency. - - -.. cfunction:: void PyObject_Del(PyObject *op) - - Releases memory allocated to an object using :cfunc:`PyObject_New` or - :cfunc:`PyObject_NewVar`. This is normally called from the :attr:`tp_dealloc` - handler specified in the object's type. The fields of the object should not be - accessed after this call as the memory is no longer a valid Python object. - - -.. cfunction:: PyObject* Py_InitModule(char *name, PyMethodDef *methods) - - Create a new module object based on a name and table of functions, returning - the new module object; the *methods* argument can be *NULL* if no methods are - to be defined for the module. - - -.. cfunction:: PyObject* Py_InitModule3(char *name, PyMethodDef *methods, char *doc) - - Create a new module object based on a name and table of functions, returning - the new module object. The *methods* argument can be *NULL* if no methods - are to be defined for the module. If *doc* is non-*NULL*, it will be used to - define the docstring for the module. - - -.. cfunction:: PyObject* Py_InitModule4(char *name, PyMethodDef *methods, char *doc, PyObject *self, int apiver) - - Create a new module object based on a name and table of functions, returning - the new module object. The *methods* argument can be *NULL* if no methods - are to be defined for the module. If *doc* is non-*NULL*, it will be used to - define the docstring for the module. If *self* is non-*NULL*, it will passed - to the functions of the module as their (otherwise *NULL*) first parameter. - (This was added as an experimental feature, and there are no known uses in - the current version of Python.) For *apiver*, the only value which should be - passed is defined by the constant :const:`PYTHON_API_VERSION`. - - .. note:: - - Most uses of this function should probably be using the :cfunc:`Py_InitModule3` - instead; only use this if you are sure you need it. - - -.. cvar:: PyObject _Py_NoneStruct - - Object which is visible in Python as ``None``. This should only be accessed - using the :cmacro:`Py_None` macro, which evaluates to a pointer to this - object. - - -.. _common-structs: - -Common Object Structures -======================== - -There are a large number of structures which are used in the definition of -object types for Python. This section describes these structures and how they -are used. - -All Python objects ultimately share a small number of fields at the beginning of -the object's representation in memory. These are represented by the -:ctype:`PyObject` and :ctype:`PyVarObject` types, which are defined, in turn, by -the expansions of some macros also used, whether directly or indirectly, in the -definition of all other Python objects. - - -.. ctype:: PyObject - - All object types are extensions of this type. This is a type which contains the - information Python needs to treat a pointer to an object as an object. In a - normal "release" build, it contains only the objects reference count and a - pointer to the corresponding type object. It corresponds to the fields defined - by the expansion of the ``PyObject_HEAD`` macro. - - -.. ctype:: PyVarObject - - This is an extension of :ctype:`PyObject` that adds the :attr:`ob_size` field. - This is only used for objects that have some notion of *length*. This type does - not often appear in the Python/C API. It corresponds to the fields defined by - the expansion of the ``PyObject_VAR_HEAD`` macro. - -These macros are used in the definition of :ctype:`PyObject` and -:ctype:`PyVarObject`: - -.. XXX need to document PEP 3123 changes here - -.. cmacro:: PyObject_HEAD - - This is a macro which expands to the declarations of the fields of the - :ctype:`PyObject` type; it is used when declaring new types which represent - objects without a varying length. The specific fields it expands to depend on - the definition of :cmacro:`Py_TRACE_REFS`. By default, that macro is not - defined, and :cmacro:`PyObject_HEAD` expands to:: - - Py_ssize_t ob_refcnt; - PyTypeObject *ob_type; - - When :cmacro:`Py_TRACE_REFS` is defined, it expands to:: - - PyObject *_ob_next, *_ob_prev; - Py_ssize_t ob_refcnt; - PyTypeObject *ob_type; - - -.. cmacro:: PyObject_VAR_HEAD - - This is a macro which expands to the declarations of the fields of the - :ctype:`PyVarObject` type; it is used when declaring new types which represent - objects with a length that varies from instance to instance. This macro always - expands to:: - - PyObject_HEAD - Py_ssize_t ob_size; - - Note that :cmacro:`PyObject_HEAD` is part of the expansion, and that its own - expansion varies depending on the definition of :cmacro:`Py_TRACE_REFS`. - -.. cmacro:: PyObject_HEAD_INIT - - -.. ctype:: PyCFunction - - Type of the functions used to implement most Python callables in C. Functions of - this type take two :ctype:`PyObject\*` parameters and return one such value. If - the return value is *NULL*, an exception shall have been set. If not *NULL*, - the return value is interpreted as the return value of the function as exposed - in Python. The function must return a new reference. - - -.. ctype:: PyCFunctionWithKeywords - - Type of the functions used to implement Python callables in C that take - keyword arguments: they take three :ctype:`PyObject\*` parameters and return - one such value. See :ctype:`PyCFunction` above for the meaning of the return - value. - - -.. ctype:: PyMethodDef - - Structure used to describe a method of an extension type. This structure has - four fields: - - +------------------+-------------+-------------------------------+ - | Field | C Type | Meaning | - +==================+=============+===============================+ - | :attr:`ml_name` | char \* | name of the method | - +------------------+-------------+-------------------------------+ - | :attr:`ml_meth` | PyCFunction | pointer to the C | - | | | implementation | - +------------------+-------------+-------------------------------+ - | :attr:`ml_flags` | int | flag bits indicating how the | - | | | call should be constructed | - +------------------+-------------+-------------------------------+ - | :attr:`ml_doc` | char \* | points to the contents of the | - | | | docstring | - +------------------+-------------+-------------------------------+ - -The :attr:`ml_meth` is a C function pointer. The functions may be of different -types, but they always return :ctype:`PyObject\*`. If the function is not of -the :ctype:`PyCFunction`, the compiler will require a cast in the method table. -Even though :ctype:`PyCFunction` defines the first parameter as -:ctype:`PyObject\*`, it is common that the method implementation uses a the -specific C type of the *self* object. - -The :attr:`ml_flags` field is a bitfield which can include the following flags. -The individual flags indicate either a calling convention or a binding -convention. Of the calling convention flags, only :const:`METH_VARARGS` and -:const:`METH_KEYWORDS` can be combined (but note that :const:`METH_KEYWORDS` -alone is equivalent to ``METH_VARARGS | METH_KEYWORDS``). Any of the calling -convention flags can be combined with a binding flag. - - -.. data:: METH_VARARGS - - This is the typical calling convention, where the methods have the type - :ctype:`PyCFunction`. The function expects two :ctype:`PyObject\*` values. The - first one is the *self* object for methods; for module functions, it has the - value given to :cfunc:`Py_InitModule4` (or *NULL* if :cfunc:`Py_InitModule` was - used). The second parameter (often called *args*) is a tuple object - representing all arguments. This parameter is typically processed using - :cfunc:`PyArg_ParseTuple` or :cfunc:`PyArg_UnpackTuple`. - - -.. data:: METH_KEYWORDS - - Methods with these flags must be of type :ctype:`PyCFunctionWithKeywords`. The - function expects three parameters: *self*, *args*, and a dictionary of all the - keyword arguments. The flag is typically combined with :const:`METH_VARARGS`, - and the parameters are typically processed using - :cfunc:`PyArg_ParseTupleAndKeywords`. - - -.. data:: METH_NOARGS - - Methods without parameters don't need to check whether arguments are given if - they are listed with the :const:`METH_NOARGS` flag. They need to be of type - :ctype:`PyCFunction`. When used with object methods, the first parameter is - typically named ``self`` and will hold a reference to the object instance. In - all cases the second parameter will be *NULL*. - - -.. data:: METH_O - - Methods with a single object argument can be listed with the :const:`METH_O` - flag, instead of invoking :cfunc:`PyArg_ParseTuple` with a ``"O"`` argument. - They have the type :ctype:`PyCFunction`, with the *self* parameter, and a - :ctype:`PyObject\*` parameter representing the single argument. - - -These two constants are not used to indicate the calling convention but the -binding when use with methods of classes. These may not be used for functions -defined for modules. At most one of these flags may be set for any given -method. - - -.. data:: METH_CLASS - - .. index:: builtin: classmethod - - The method will be passed the type object as the first parameter rather than an - instance of the type. This is used to create *class methods*, similar to what - is created when using the :func:`classmethod` built-in function. - - -.. data:: METH_STATIC - - .. index:: builtin: staticmethod - - The method will be passed *NULL* as the first parameter rather than an instance - of the type. This is used to create *static methods*, similar to what is - created when using the :func:`staticmethod` built-in function. - -One other constant controls whether a method is loaded in place of another -definition with the same method name. - - -.. data:: METH_COEXIST - - The method will be loaded in place of existing definitions. Without - *METH_COEXIST*, the default is to skip repeated definitions. Since slot - wrappers are loaded before the method table, the existence of a *sq_contains* - slot, for example, would generate a wrapped method named :meth:`__contains__` - and preclude the loading of a corresponding PyCFunction with the same name. - With the flag defined, the PyCFunction will be loaded in place of the wrapper - object and will co-exist with the slot. This is helpful because calls to - PyCFunctions are optimized more than wrapper object calls. - - -.. cfunction:: PyObject* Py_FindMethod(PyMethodDef table[], PyObject *ob, char *name) - - Return a bound method object for an extension type implemented in C. This can - be useful in the implementation of a :attr:`tp_getattro` or :attr:`tp_getattr` - handler that does not use the :cfunc:`PyObject_GenericGetAttr` function. - - -.. _type-structs: - -Type Objects -============ - -Perhaps one of the most important structures of the Python object system is the -structure that defines a new type: the :ctype:`PyTypeObject` structure. Type -objects can be handled using any of the :cfunc:`PyObject_\*` or -:cfunc:`PyType_\*` functions, but do not offer much that's interesting to most -Python applications. These objects are fundamental to how objects behave, so -they are very important to the interpreter itself and to any extension module -that implements new types. - -Type objects are fairly large compared to most of the standard types. The reason -for the size is that each type object stores a large number of values, mostly C -function pointers, each of which implements a small part of the type's -functionality. The fields of the type object are examined in detail in this -section. The fields will be described in the order in which they occur in the -structure. - -Typedefs: unaryfunc, binaryfunc, ternaryfunc, inquiry, intargfunc, -intintargfunc, intobjargproc, intintobjargproc, objobjargproc, destructor, -freefunc, printfunc, getattrfunc, getattrofunc, setattrfunc, setattrofunc, -cmpfunc, reprfunc, hashfunc - -The structure definition for :ctype:`PyTypeObject` can be found in -:file:`Include/object.h`. For convenience of reference, this repeats the -definition found there: - -.. literalinclude:: ../includes/typestruct.h - - -The type object structure extends the :ctype:`PyVarObject` structure. The -:attr:`ob_size` field is used for dynamic types (created by :func:`type_new`, -usually called from a class statement). Note that :cdata:`PyType_Type` (the -metatype) initializes :attr:`tp_itemsize`, which means that its instances (i.e. -type objects) *must* have the :attr:`ob_size` field. - - -.. cmember:: PyObject* PyObject._ob_next - PyObject* PyObject._ob_prev - - These fields are only present when the macro ``Py_TRACE_REFS`` is defined. - Their initialization to *NULL* is taken care of by the ``PyObject_HEAD_INIT`` - macro. For statically allocated objects, these fields always remain *NULL*. - For dynamically allocated objects, these two fields are used to link the object - into a doubly-linked list of *all* live objects on the heap. This could be used - for various debugging purposes; currently the only use is to print the objects - that are still alive at the end of a run when the environment variable - :envvar:`PYTHONDUMPREFS` is set. - - These fields are not inherited by subtypes. - - -.. cmember:: Py_ssize_t PyObject.ob_refcnt - - This is the type object's reference count, initialized to ``1`` by the - ``PyObject_HEAD_INIT`` macro. Note that for statically allocated type objects, - the type's instances (objects whose :attr:`ob_type` points back to the type) do - *not* count as references. But for dynamically allocated type objects, the - instances *do* count as references. - - This field is not inherited by subtypes. - - -.. cmember:: PyTypeObject* PyObject.ob_type - - This is the type's type, in other words its metatype. It is initialized by the - argument to the ``PyObject_HEAD_INIT`` macro, and its value should normally be - ``&PyType_Type``. However, for dynamically loadable extension modules that must - be usable on Windows (at least), the compiler complains that this is not a valid - initializer. Therefore, the convention is to pass *NULL* to the - ``PyObject_HEAD_INIT`` macro and to initialize this field explicitly at the - start of the module's initialization function, before doing anything else. This - is typically done like this:: - - Foo_Type.ob_type = &PyType_Type; - - This should be done before any instances of the type are created. - :cfunc:`PyType_Ready` checks if :attr:`ob_type` is *NULL*, and if so, - initializes it: in Python 2.2, it is set to ``&PyType_Type``; in Python 2.2.1 - and later it is initialized to the :attr:`ob_type` field of the base class. - :cfunc:`PyType_Ready` will not change this field if it is non-zero. - - In Python 2.2, this field is not inherited by subtypes. In 2.2.1, and in 2.3 - and beyond, it is inherited by subtypes. - - -.. cmember:: Py_ssize_t PyVarObject.ob_size - - For statically allocated type objects, this should be initialized to zero. For - dynamically allocated type objects, this field has a special internal meaning. - - This field is not inherited by subtypes. - - -.. cmember:: char* PyTypeObject.tp_name - - Pointer to a NUL-terminated string containing the name of the type. For types - that are accessible as module globals, the string should be the full module - name, followed by a dot, followed by the type name; for built-in types, it - should be just the type name. If the module is a submodule of a package, the - full package name is part of the full module name. For example, a type named - :class:`T` defined in module :mod:`M` in subpackage :mod:`Q` in package :mod:`P` - should have the :attr:`tp_name` initializer ``"P.Q.M.T"``. - - For dynamically allocated type objects, this should just be the type name, and - the module name explicitly stored in the type dict as the value for key - ``'__module__'``. - - For statically allocated type objects, the tp_name field should contain a dot. - Everything before the last dot is made accessible as the :attr:`__module__` - attribute, and everything after the last dot is made accessible as the - :attr:`__name__` attribute. - - If no dot is present, the entire :attr:`tp_name` field is made accessible as the - :attr:`__name__` attribute, and the :attr:`__module__` attribute is undefined - (unless explicitly set in the dictionary, as explained above). This means your - type will be impossible to pickle. - - This field is not inherited by subtypes. - - -.. cmember:: Py_ssize_t PyTypeObject.tp_basicsize - Py_ssize_t PyTypeObject.tp_itemsize - - These fields allow calculating the size in bytes of instances of the type. - - There are two kinds of types: types with fixed-length instances have a zero - :attr:`tp_itemsize` field, types with variable-length instances have a non-zero - :attr:`tp_itemsize` field. For a type with fixed-length instances, all - instances have the same size, given in :attr:`tp_basicsize`. - - For a type with variable-length instances, the instances must have an - :attr:`ob_size` field, and the instance size is :attr:`tp_basicsize` plus N - times :attr:`tp_itemsize`, where N is the "length" of the object. The value of - N is typically stored in the instance's :attr:`ob_size` field. There are - exceptions: for example, long ints use a negative :attr:`ob_size` to indicate a - negative number, and N is ``abs(ob_size)`` there. Also, the presence of an - :attr:`ob_size` field in the instance layout doesn't mean that the instance - structure is variable-length (for example, the structure for the list type has - fixed-length instances, yet those instances have a meaningful :attr:`ob_size` - field). - - The basic size includes the fields in the instance declared by the macro - :cmacro:`PyObject_HEAD` or :cmacro:`PyObject_VAR_HEAD` (whichever is used to - declare the instance struct) and this in turn includes the :attr:`_ob_prev` and - :attr:`_ob_next` fields if they are present. This means that the only correct - way to get an initializer for the :attr:`tp_basicsize` is to use the - ``sizeof`` operator on the struct used to declare the instance layout. - The basic size does not include the GC header size (this is new in Python 2.2; - in 2.1 and 2.0, the GC header size was included in :attr:`tp_basicsize`). - - These fields are inherited separately by subtypes. If the base type has a - non-zero :attr:`tp_itemsize`, it is generally not safe to set - :attr:`tp_itemsize` to a different non-zero value in a subtype (though this - depends on the implementation of the base type). - - A note about alignment: if the variable items require a particular alignment, - this should be taken care of by the value of :attr:`tp_basicsize`. Example: - suppose a type implements an array of ``double``. :attr:`tp_itemsize` is - ``sizeof(double)``. It is the programmer's responsibility that - :attr:`tp_basicsize` is a multiple of ``sizeof(double)`` (assuming this is the - alignment requirement for ``double``). - - -.. cmember:: destructor PyTypeObject.tp_dealloc - - A pointer to the instance destructor function. This function must be defined - unless the type guarantees that its instances will never be deallocated (as is - the case for the singletons ``None`` and ``Ellipsis``). - - The destructor function is called by the :cfunc:`Py_DECREF` and - :cfunc:`Py_XDECREF` macros when the new reference count is zero. At this point, - the instance is still in existence, but there are no references to it. The - destructor function should free all references which the instance owns, free all - memory buffers owned by the instance (using the freeing function corresponding - to the allocation function used to allocate the buffer), and finally (as its - last action) call the type's :attr:`tp_free` function. If the type is not - subtypable (doesn't have the :const:`Py_TPFLAGS_BASETYPE` flag bit set), it is - permissible to call the object deallocator directly instead of via - :attr:`tp_free`. The object deallocator should be the one used to allocate the - instance; this is normally :cfunc:`PyObject_Del` if the instance was allocated - using :cfunc:`PyObject_New` or :cfunc:`PyObject_VarNew`, or - :cfunc:`PyObject_GC_Del` if the instance was allocated using - :cfunc:`PyObject_GC_New` or :cfunc:`PyObject_GC_VarNew`. - - This field is inherited by subtypes. - - -.. cmember:: printfunc PyTypeObject.tp_print - - An optional pointer to the instance print function. - - The print function is only called when the instance is printed to a *real* file; - when it is printed to a pseudo-file (like a :class:`StringIO` instance), the - instance's :attr:`tp_repr` or :attr:`tp_str` function is called to convert it to - a string. These are also called when the type's :attr:`tp_print` field is - *NULL*. A type should never implement :attr:`tp_print` in a way that produces - different output than :attr:`tp_repr` or :attr:`tp_str` would. - - The print function is called with the same signature as :cfunc:`PyObject_Print`: - ``int tp_print(PyObject *self, FILE *file, int flags)``. The *self* argument is - the instance to be printed. The *file* argument is the stdio file to which it - is to be printed. The *flags* argument is composed of flag bits. The only flag - bit currently defined is :const:`Py_PRINT_RAW`. When the :const:`Py_PRINT_RAW` - flag bit is set, the instance should be printed the same way as :attr:`tp_str` - would format it; when the :const:`Py_PRINT_RAW` flag bit is clear, the instance - should be printed the same was as :attr:`tp_repr` would format it. It should - return ``-1`` and set an exception condition when an error occurred during the - comparison. - - It is possible that the :attr:`tp_print` field will be deprecated. In any case, - it is recommended not to define :attr:`tp_print`, but instead to rely on - :attr:`tp_repr` and :attr:`tp_str` for printing. - - This field is inherited by subtypes. - - -.. cmember:: getattrfunc PyTypeObject.tp_getattr - - An optional pointer to the get-attribute-string function. - - This field is deprecated. When it is defined, it should point to a function - that acts the same as the :attr:`tp_getattro` function, but taking a C string - instead of a Python string object to give the attribute name. The signature is - the same as for :cfunc:`PyObject_GetAttrString`. - - This field is inherited by subtypes together with :attr:`tp_getattro`: a subtype - inherits both :attr:`tp_getattr` and :attr:`tp_getattro` from its base type when - the subtype's :attr:`tp_getattr` and :attr:`tp_getattro` are both *NULL*. - - -.. cmember:: setattrfunc PyTypeObject.tp_setattr - - An optional pointer to the set-attribute-string function. - - This field is deprecated. When it is defined, it should point to a function - that acts the same as the :attr:`tp_setattro` function, but taking a C string - instead of a Python string object to give the attribute name. The signature is - the same as for :cfunc:`PyObject_SetAttrString`. - - This field is inherited by subtypes together with :attr:`tp_setattro`: a subtype - inherits both :attr:`tp_setattr` and :attr:`tp_setattro` from its base type when - the subtype's :attr:`tp_setattr` and :attr:`tp_setattro` are both *NULL*. - - -.. cmember:: cmpfunc PyTypeObject.tp_compare - - An optional pointer to the three-way comparison function. - - The signature is the same as for :cfunc:`PyObject_Compare`. The function should - return ``1`` if *self* greater than *other*, ``0`` if *self* is equal to - *other*, and ``-1`` if *self* less than *other*. It should return ``-1`` and - set an exception condition when an error occurred during the comparison. - - This field is inherited by subtypes together with :attr:`tp_richcompare` and - :attr:`tp_hash`: a subtypes inherits all three of :attr:`tp_compare`, - :attr:`tp_richcompare`, and :attr:`tp_hash` when the subtype's - :attr:`tp_compare`, :attr:`tp_richcompare`, and :attr:`tp_hash` are all *NULL*. - - -.. cmember:: reprfunc PyTypeObject.tp_repr - - .. index:: builtin: repr - - An optional pointer to a function that implements the built-in function - :func:`repr`. - - The signature is the same as for :cfunc:`PyObject_Repr`; it must return a string - or a Unicode object. Ideally, this function should return a string that, when - passed to :func:`eval`, given a suitable environment, returns an object with the - same value. If this is not feasible, it should return a string starting with - ``'<'`` and ending with ``'>'`` from which both the type and the value of the - object can be deduced. - - When this field is not set, a string of the form ``<%s object at %p>`` is - returned, where ``%s`` is replaced by the type name, and ``%p`` by the object's - memory address. - - This field is inherited by subtypes. - -.. cmember:: PyNumberMethods* tp_as_number - - Pointer to an additional structure that contains fields relevant only to - objects which implement the number protocol. These fields are documented in - :ref:`number-structs`. - - The :attr:`tp_as_number` field is not inherited, but the contained fields are - inherited individually. - - -.. cmember:: PySequenceMethods* tp_as_sequence - - Pointer to an additional structure that contains fields relevant only to - objects which implement the sequence protocol. These fields are documented - in :ref:`sequence-structs`. - - The :attr:`tp_as_sequence` field is not inherited, but the contained fields - are inherited individually. - - -.. cmember:: PyMappingMethods* tp_as_mapping - - Pointer to an additional structure that contains fields relevant only to - objects which implement the mapping protocol. These fields are documented in - :ref:`mapping-structs`. - - The :attr:`tp_as_mapping` field is not inherited, but the contained fields - are inherited individually. - - -.. cmember:: hashfunc PyTypeObject.tp_hash - - .. index:: builtin: hash - - An optional pointer to a function that implements the built-in function - :func:`hash`. - - The signature is the same as for :cfunc:`PyObject_Hash`; it must return a C - long. The value ``-1`` should not be returned as a normal return value; when an - error occurs during the computation of the hash value, the function should set - an exception and return ``-1``. - - When this field is not set, two possibilities exist: if the :attr:`tp_compare` - and :attr:`tp_richcompare` fields are both *NULL*, a default hash value based on - the object's address is returned; otherwise, a :exc:`TypeError` is raised. - - This field is inherited by subtypes together with :attr:`tp_richcompare` and - :attr:`tp_compare`: a subtypes inherits all three of :attr:`tp_compare`, - :attr:`tp_richcompare`, and :attr:`tp_hash`, when the subtype's - :attr:`tp_compare`, :attr:`tp_richcompare` and :attr:`tp_hash` are all *NULL*. - - -.. cmember:: ternaryfunc PyTypeObject.tp_call - - An optional pointer to a function that implements calling the object. This - should be *NULL* if the object is not callable. The signature is the same as - for :cfunc:`PyObject_Call`. - - This field is inherited by subtypes. - - -.. cmember:: reprfunc PyTypeObject.tp_str - - An optional pointer to a function that implements the built-in operation - :func:`str`. (Note that :class:`str` is a type now, and :func:`str` calls the - constructor for that type. This constructor calls :cfunc:`PyObject_Str` to do - the actual work, and :cfunc:`PyObject_Str` will call this handler.) - - The signature is the same as for :cfunc:`PyObject_Str`; it must return a string - or a Unicode object. This function should return a "friendly" string - representation of the object, as this is the representation that will be used, - among other things, by the :func:`print` function. - - When this field is not set, :cfunc:`PyObject_Repr` is called to return a string - representation. - - This field is inherited by subtypes. - - -.. cmember:: getattrofunc PyTypeObject.tp_getattro - - An optional pointer to the get-attribute function. - - The signature is the same as for :cfunc:`PyObject_GetAttr`. It is usually - convenient to set this field to :cfunc:`PyObject_GenericGetAttr`, which - implements the normal way of looking for object attributes. - - This field is inherited by subtypes together with :attr:`tp_getattr`: a subtype - inherits both :attr:`tp_getattr` and :attr:`tp_getattro` from its base type when - the subtype's :attr:`tp_getattr` and :attr:`tp_getattro` are both *NULL*. - - -.. cmember:: setattrofunc PyTypeObject.tp_setattro - - An optional pointer to the set-attribute function. - - The signature is the same as for :cfunc:`PyObject_SetAttr`. It is usually - convenient to set this field to :cfunc:`PyObject_GenericSetAttr`, which - implements the normal way of setting object attributes. - - This field is inherited by subtypes together with :attr:`tp_setattr`: a subtype - inherits both :attr:`tp_setattr` and :attr:`tp_setattro` from its base type when - the subtype's :attr:`tp_setattr` and :attr:`tp_setattro` are both *NULL*. - - -.. cmember:: PyBufferProcs* PyTypeObject.tp_as_buffer - - Pointer to an additional structure that contains fields relevant only to objects - which implement the buffer interface. These fields are documented in - :ref:`buffer-structs`. - - The :attr:`tp_as_buffer` field is not inherited, but the contained fields are - inherited individually. - - -.. cmember:: long PyTypeObject.tp_flags - - This field is a bit mask of various flags. Some flags indicate variant - semantics for certain situations; others are used to indicate that certain - fields in the type object (or in the extension structures referenced via - :attr:`tp_as_number`, :attr:`tp_as_sequence`, :attr:`tp_as_mapping`, and - :attr:`tp_as_buffer`) that were historically not always present are valid; if - such a flag bit is clear, the type fields it guards must not be accessed and - must be considered to have a zero or *NULL* value instead. - - Inheritance of this field is complicated. Most flag bits are inherited - individually, i.e. if the base type has a flag bit set, the subtype inherits - this flag bit. The flag bits that pertain to extension structures are strictly - inherited if the extension structure is inherited, i.e. the base type's value of - the flag bit is copied into the subtype together with a pointer to the extension - structure. The :const:`Py_TPFLAGS_HAVE_GC` flag bit is inherited together with - the :attr:`tp_traverse` and :attr:`tp_clear` fields, i.e. if the - :const:`Py_TPFLAGS_HAVE_GC` flag bit is clear in the subtype and the - :attr:`tp_traverse` and :attr:`tp_clear` fields in the subtype exist (as - indicated by the :const:`Py_TPFLAGS_HAVE_RICHCOMPARE` flag bit) and have *NULL* - values. - - The following bit masks are currently defined; these can be ORed together using - the ``|`` operator to form the value of the :attr:`tp_flags` field. The macro - :cfunc:`PyType_HasFeature` takes a type and a flags value, *tp* and *f*, and - checks whether ``tp->tp_flags & f`` is non-zero. - - - .. data:: Py_TPFLAGS_HAVE_GETCHARBUFFER - - If this bit is set, the :ctype:`PyBufferProcs` struct referenced by - :attr:`tp_as_buffer` has the :attr:`bf_getcharbuffer` field. - - - .. data:: Py_TPFLAGS_HAVE_SEQUENCE_IN - - If this bit is set, the :ctype:`PySequenceMethods` struct referenced by - :attr:`tp_as_sequence` has the :attr:`sq_contains` field. - - - .. data:: Py_TPFLAGS_GC - - This bit is obsolete. The bit it used to name is no longer in use. The symbol - is now defined as zero. - - - .. data:: Py_TPFLAGS_HAVE_INPLACEOPS - - If this bit is set, the :ctype:`PySequenceMethods` struct referenced by - :attr:`tp_as_sequence` and the :ctype:`PyNumberMethods` structure referenced by - :attr:`tp_as_number` contain the fields for in-place operators. In particular, - this means that the :ctype:`PyNumberMethods` structure has the fields - :attr:`nb_inplace_add`, :attr:`nb_inplace_subtract`, - :attr:`nb_inplace_multiply`, :attr:`nb_inplace_divide`, - :attr:`nb_inplace_remainder`, :attr:`nb_inplace_power`, - :attr:`nb_inplace_lshift`, :attr:`nb_inplace_rshift`, :attr:`nb_inplace_and`, - :attr:`nb_inplace_xor`, and :attr:`nb_inplace_or`; and the - :ctype:`PySequenceMethods` struct has the fields :attr:`sq_inplace_concat` and - :attr:`sq_inplace_repeat`. - - - .. data:: Py_TPFLAGS_HAVE_RICHCOMPARE - - If this bit is set, the type object has the :attr:`tp_richcompare` field, as - well as the :attr:`tp_traverse` and the :attr:`tp_clear` fields. - - - .. data:: Py_TPFLAGS_HAVE_WEAKREFS - - If this bit is set, the :attr:`tp_weaklistoffset` field is defined. Instances - of a type are weakly referenceable if the type's :attr:`tp_weaklistoffset` field - has a value greater than zero. - - - .. data:: Py_TPFLAGS_HAVE_ITER - - If this bit is set, the type object has the :attr:`tp_iter` and - :attr:`tp_iternext` fields. - - - .. data:: Py_TPFLAGS_HAVE_CLASS - - If this bit is set, the type object has several new fields defined starting in - Python 2.2: :attr:`tp_methods`, :attr:`tp_members`, :attr:`tp_getset`, - :attr:`tp_base`, :attr:`tp_dict`, :attr:`tp_descr_get`, :attr:`tp_descr_set`, - :attr:`tp_dictoffset`, :attr:`tp_init`, :attr:`tp_alloc`, :attr:`tp_new`, - :attr:`tp_free`, :attr:`tp_is_gc`, :attr:`tp_bases`, :attr:`tp_mro`, - :attr:`tp_cache`, :attr:`tp_subclasses`, and :attr:`tp_weaklist`. - - - .. data:: Py_TPFLAGS_HEAPTYPE - - This bit is set when the type object itself is allocated on the heap. In this - case, the :attr:`ob_type` field of its instances is considered a reference to - the type, and the type object is INCREF'ed when a new instance is created, and - DECREF'ed when an instance is destroyed (this does not apply to instances of - subtypes; only the type referenced by the instance's ob_type gets INCREF'ed or - DECREF'ed). - - - .. data:: Py_TPFLAGS_BASETYPE - - This bit is set when the type can be used as the base type of another type. If - this bit is clear, the type cannot be subtyped (similar to a "final" class in - Java). - - - .. data:: Py_TPFLAGS_READY - - This bit is set when the type object has been fully initialized by - :cfunc:`PyType_Ready`. - - - .. data:: Py_TPFLAGS_READYING - - This bit is set while :cfunc:`PyType_Ready` is in the process of initializing - the type object. - - - .. data:: Py_TPFLAGS_HAVE_GC - - This bit is set when the object supports garbage collection. If this bit - is set, instances must be created using :cfunc:`PyObject_GC_New` and - destroyed using :cfunc:`PyObject_GC_Del`. More information in section - :ref:`supporting-cycle-detection`. This bit also implies that the - GC-related fields :attr:`tp_traverse` and :attr:`tp_clear` are present in - the type object; but those fields also exist when - :const:`Py_TPFLAGS_HAVE_GC` is clear but - :const:`Py_TPFLAGS_HAVE_RICHCOMPARE` is set. - - - .. data:: Py_TPFLAGS_DEFAULT - - This is a bitmask of all the bits that pertain to the existence of certain - fields in the type object and its extension structures. Currently, it includes - the following bits: :const:`Py_TPFLAGS_HAVE_GETCHARBUFFER`, - :const:`Py_TPFLAGS_HAVE_SEQUENCE_IN`, :const:`Py_TPFLAGS_HAVE_INPLACEOPS`, - :const:`Py_TPFLAGS_HAVE_RICHCOMPARE`, :const:`Py_TPFLAGS_HAVE_WEAKREFS`, - :const:`Py_TPFLAGS_HAVE_ITER`, and :const:`Py_TPFLAGS_HAVE_CLASS`. - - -.. cmember:: char* PyTypeObject.tp_doc - - An optional pointer to a NUL-terminated C string giving the docstring for this - type object. This is exposed as the :attr:`__doc__` attribute on the type and - instances of the type. - - This field is *not* inherited by subtypes. - -The following three fields only exist if the -:const:`Py_TPFLAGS_HAVE_RICHCOMPARE` flag bit is set. - - -.. cmember:: traverseproc PyTypeObject.tp_traverse - - An optional pointer to a traversal function for the garbage collector. This is - only used if the :const:`Py_TPFLAGS_HAVE_GC` flag bit is set. More information - about Python's garbage collection scheme can be found in section - :ref:`supporting-cycle-detection`. - - The :attr:`tp_traverse` pointer is used by the garbage collector to detect - reference cycles. A typical implementation of a :attr:`tp_traverse` function - simply calls :cfunc:`Py_VISIT` on each of the instance's members that are Python - objects. For exampe, this is function :cfunc:`local_traverse` from the - :mod:`thread` extension module:: - - static int - local_traverse(localobject *self, visitproc visit, void *arg) - { - Py_VISIT(self->args); - Py_VISIT(self->kw); - Py_VISIT(self->dict); - return 0; - } - - Note that :cfunc:`Py_VISIT` is called only on those members that can participate - in reference cycles. Although there is also a ``self->key`` member, it can only - be *NULL* or a Python string and therefore cannot be part of a reference cycle. - - On the other hand, even if you know a member can never be part of a cycle, as a - debugging aid you may want to visit it anyway just so the :mod:`gc` module's - :func:`get_referents` function will include it. - - Note that :cfunc:`Py_VISIT` requires the *visit* and *arg* parameters to - :cfunc:`local_traverse` to have these specific names; don't name them just - anything. - - This field is inherited by subtypes together with :attr:`tp_clear` and the - :const:`Py_TPFLAGS_HAVE_GC` flag bit: the flag bit, :attr:`tp_traverse`, and - :attr:`tp_clear` are all inherited from the base type if they are all zero in - the subtype *and* the subtype has the :const:`Py_TPFLAGS_HAVE_RICHCOMPARE` flag - bit set. - - -.. cmember:: inquiry PyTypeObject.tp_clear - - An optional pointer to a clear function for the garbage collector. This is only - used if the :const:`Py_TPFLAGS_HAVE_GC` flag bit is set. - - The :attr:`tp_clear` member function is used to break reference cycles in cyclic - garbage detected by the garbage collector. Taken together, all :attr:`tp_clear` - functions in the system must combine to break all reference cycles. This is - subtle, and if in any doubt supply a :attr:`tp_clear` function. For example, - the tuple type does not implement a :attr:`tp_clear` function, because it's - possible to prove that no reference cycle can be composed entirely of tuples. - Therefore the :attr:`tp_clear` functions of other types must be sufficient to - break any cycle containing a tuple. This isn't immediately obvious, and there's - rarely a good reason to avoid implementing :attr:`tp_clear`. - - Implementations of :attr:`tp_clear` should drop the instance's references to - those of its members that may be Python objects, and set its pointers to those - members to *NULL*, as in the following example:: - - static int - local_clear(localobject *self) - { - Py_CLEAR(self->key); - Py_CLEAR(self->args); - Py_CLEAR(self->kw); - Py_CLEAR(self->dict); - return 0; - } - - The :cfunc:`Py_CLEAR` macro should be used, because clearing references is - delicate: the reference to the contained object must not be decremented until - after the pointer to the contained object is set to *NULL*. This is because - decrementing the reference count may cause the contained object to become trash, - triggering a chain of reclamation activity that may include invoking arbitrary - Python code (due to finalizers, or weakref callbacks, associated with the - contained object). If it's possible for such code to reference *self* again, - it's important that the pointer to the contained object be *NULL* at that time, - so that *self* knows the contained object can no longer be used. The - :cfunc:`Py_CLEAR` macro performs the operations in a safe order. - - Because the goal of :attr:`tp_clear` functions is to break reference cycles, - it's not necessary to clear contained objects like Python strings or Python - integers, which can't participate in reference cycles. On the other hand, it may - be convenient to clear all contained Python objects, and write the type's - :attr:`tp_dealloc` function to invoke :attr:`tp_clear`. - - More information about Python's garbage collection scheme can be found in - section :ref:`supporting-cycle-detection`. - - This field is inherited by subtypes together with :attr:`tp_traverse` and the - :const:`Py_TPFLAGS_HAVE_GC` flag bit: the flag bit, :attr:`tp_traverse`, and - :attr:`tp_clear` are all inherited from the base type if they are all zero in - the subtype *and* the subtype has the :const:`Py_TPFLAGS_HAVE_RICHCOMPARE` flag - bit set. - - -.. cmember:: richcmpfunc PyTypeObject.tp_richcompare - - An optional pointer to the rich comparison function. - - The signature is the same as for :cfunc:`PyObject_RichCompare`. The function - should return the result of the comparison (usually ``Py_True`` or - ``Py_False``). If the comparison is undefined, it must return - ``Py_NotImplemented``, if another error occurred it must return ``NULL`` and set - an exception condition. - - This field is inherited by subtypes together with :attr:`tp_compare` and - :attr:`tp_hash`: a subtype inherits all three of :attr:`tp_compare`, - :attr:`tp_richcompare`, and :attr:`tp_hash`, when the subtype's - :attr:`tp_compare`, :attr:`tp_richcompare`, and :attr:`tp_hash` are all *NULL*. - - The following constants are defined to be used as the third argument for - :attr:`tp_richcompare` and for :cfunc:`PyObject_RichCompare`: - - +----------------+------------+ - | Constant | Comparison | - +================+============+ - | :const:`Py_LT` | ``<`` | - +----------------+------------+ - | :const:`Py_LE` | ``<=`` | - +----------------+------------+ - | :const:`Py_EQ` | ``==`` | - +----------------+------------+ - | :const:`Py_NE` | ``!=`` | - +----------------+------------+ - | :const:`Py_GT` | ``>`` | - +----------------+------------+ - | :const:`Py_GE` | ``>=`` | - +----------------+------------+ - -The next field only exists if the :const:`Py_TPFLAGS_HAVE_WEAKREFS` flag bit is -set. - - -.. cmember:: long PyTypeObject.tp_weaklistoffset - - If the instances of this type are weakly referenceable, this field is greater - than zero and contains the offset in the instance structure of the weak - reference list head (ignoring the GC header, if present); this offset is used by - :cfunc:`PyObject_ClearWeakRefs` and the :cfunc:`PyWeakref_\*` functions. The - instance structure needs to include a field of type :ctype:`PyObject\*` which is - initialized to *NULL*. - - Do not confuse this field with :attr:`tp_weaklist`; that is the list head for - weak references to the type object itself. - - This field is inherited by subtypes, but see the rules listed below. A subtype - may override this offset; this means that the subtype uses a different weak - reference list head than the base type. Since the list head is always found via - :attr:`tp_weaklistoffset`, this should not be a problem. - - When a type defined by a class statement has no :attr:`__slots__` declaration, - and none of its base types are weakly referenceable, the type is made weakly - referenceable by adding a weak reference list head slot to the instance layout - and setting the :attr:`tp_weaklistoffset` of that slot's offset. - - When a type's :attr:`__slots__` declaration contains a slot named - :attr:`__weakref__`, that slot becomes the weak reference list head for - instances of the type, and the slot's offset is stored in the type's - :attr:`tp_weaklistoffset`. - - When a type's :attr:`__slots__` declaration does not contain a slot named - :attr:`__weakref__`, the type inherits its :attr:`tp_weaklistoffset` from its - base type. - -The next two fields only exist if the :const:`Py_TPFLAGS_HAVE_CLASS` flag bit is -set. - - -.. cmember:: getiterfunc PyTypeObject.tp_iter - - An optional pointer to a function that returns an iterator for the object. Its - presence normally signals that the instances of this type are iterable (although - sequences may be iterable without this function, and classic instances always - have this function, even if they don't define an :meth:`__iter__` method). - - This function has the same signature as :cfunc:`PyObject_GetIter`. - - This field is inherited by subtypes. - - -.. cmember:: iternextfunc PyTypeObject.tp_iternext - - An optional pointer to a function that returns the next item in an iterator, or - raises :exc:`StopIteration` when the iterator is exhausted. Its presence - normally signals that the instances of this type are iterators (although classic - instances always have this function, even if they don't define a - :meth:`__next__` method). - - Iterator types should also define the :attr:`tp_iter` function, and that - function should return the iterator instance itself (not a new iterator - instance). - - This function has the same signature as :cfunc:`PyIter_Next`. - - This field is inherited by subtypes. - -The next fields, up to and including :attr:`tp_weaklist`, only exist if the -:const:`Py_TPFLAGS_HAVE_CLASS` flag bit is set. - - -.. cmember:: struct PyMethodDef* PyTypeObject.tp_methods - - An optional pointer to a static *NULL*-terminated array of :ctype:`PyMethodDef` - structures, declaring regular methods of this type. - - For each entry in the array, an entry is added to the type's dictionary (see - :attr:`tp_dict` below) containing a method descriptor. - - This field is not inherited by subtypes (methods are inherited through a - different mechanism). - - -.. cmember:: struct PyMemberDef* PyTypeObject.tp_members - - An optional pointer to a static *NULL*-terminated array of :ctype:`PyMemberDef` - structures, declaring regular data members (fields or slots) of instances of - this type. - - For each entry in the array, an entry is added to the type's dictionary (see - :attr:`tp_dict` below) containing a member descriptor. - - This field is not inherited by subtypes (members are inherited through a - different mechanism). - - -.. cmember:: struct PyGetSetDef* PyTypeObject.tp_getset - - An optional pointer to a static *NULL*-terminated array of :ctype:`PyGetSetDef` - structures, declaring computed attributes of instances of this type. - - For each entry in the array, an entry is added to the type's dictionary (see - :attr:`tp_dict` below) containing a getset descriptor. - - This field is not inherited by subtypes (computed attributes are inherited - through a different mechanism). - - Docs for PyGetSetDef (XXX belong elsewhere):: - - typedef PyObject *(*getter)(PyObject *, void *); - typedef int (*setter)(PyObject *, PyObject *, void *); - - typedef struct PyGetSetDef { - char *name; /* attribute name */ - getter get; /* C function to get the attribute */ - setter set; /* C function to set the attribute */ - char *doc; /* optional doc string */ - void *closure; /* optional additional data for getter and setter */ - } PyGetSetDef; - - -.. cmember:: PyTypeObject* PyTypeObject.tp_base - - An optional pointer to a base type from which type properties are inherited. At - this level, only single inheritance is supported; multiple inheritance require - dynamically creating a type object by calling the metatype. - - This field is not inherited by subtypes (obviously), but it defaults to - ``&PyBaseObject_Type`` (which to Python programmers is known as the type - :class:`object`). - - -.. cmember:: PyObject* PyTypeObject.tp_dict - - The type's dictionary is stored here by :cfunc:`PyType_Ready`. - - This field should normally be initialized to *NULL* before PyType_Ready is - called; it may also be initialized to a dictionary containing initial attributes - for the type. Once :cfunc:`PyType_Ready` has initialized the type, extra - attributes for the type may be added to this dictionary only if they don't - correspond to overloaded operations (like :meth:`__add__`). - - This field is not inherited by subtypes (though the attributes defined in here - are inherited through a different mechanism). - - -.. cmember:: descrgetfunc PyTypeObject.tp_descr_get - - An optional pointer to a "descriptor get" function. - - The function signature is :: - - PyObject * tp_descr_get(PyObject *self, PyObject *obj, PyObject *type); - - XXX explain. - - This field is inherited by subtypes. - - -.. cmember:: descrsetfunc PyTypeObject.tp_descr_set - - An optional pointer to a "descriptor set" function. - - The function signature is :: - - int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value); - - This field is inherited by subtypes. - - XXX explain. - - -.. cmember:: long PyTypeObject.tp_dictoffset - - If the instances of this type have a dictionary containing instance variables, - this field is non-zero and contains the offset in the instances of the type of - the instance variable dictionary; this offset is used by - :cfunc:`PyObject_GenericGetAttr`. - - Do not confuse this field with :attr:`tp_dict`; that is the dictionary for - attributes of the type object itself. - - If the value of this field is greater than zero, it specifies the offset from - the start of the instance structure. If the value is less than zero, it - specifies the offset from the *end* of the instance structure. A negative - offset is more expensive to use, and should only be used when the instance - structure contains a variable-length part. This is used for example to add an - instance variable dictionary to subtypes of :class:`str` or :class:`tuple`. Note - that the :attr:`tp_basicsize` field should account for the dictionary added to - the end in that case, even though the dictionary is not included in the basic - object layout. On a system with a pointer size of 4 bytes, - :attr:`tp_dictoffset` should be set to ``-4`` to indicate that the dictionary is - at the very end of the structure. - - The real dictionary offset in an instance can be computed from a negative - :attr:`tp_dictoffset` as follows:: - - dictoffset = tp_basicsize + abs(ob_size)*tp_itemsize + tp_dictoffset - if dictoffset is not aligned on sizeof(void*): - round up to sizeof(void*) - - where :attr:`tp_basicsize`, :attr:`tp_itemsize` and :attr:`tp_dictoffset` are - taken from the type object, and :attr:`ob_size` is taken from the instance. The - absolute value is taken because long ints use the sign of :attr:`ob_size` to - store the sign of the number. (There's never a need to do this calculation - yourself; it is done for you by :cfunc:`_PyObject_GetDictPtr`.) - - This field is inherited by subtypes, but see the rules listed below. A subtype - may override this offset; this means that the subtype instances store the - dictionary at a difference offset than the base type. Since the dictionary is - always found via :attr:`tp_dictoffset`, this should not be a problem. - - When a type defined by a class statement has no :attr:`__slots__` declaration, - and none of its base types has an instance variable dictionary, a dictionary - slot is added to the instance layout and the :attr:`tp_dictoffset` is set to - that slot's offset. - - When a type defined by a class statement has a :attr:`__slots__` declaration, - the type inherits its :attr:`tp_dictoffset` from its base type. - - (Adding a slot named :attr:`__dict__` to the :attr:`__slots__` declaration does - not have the expected effect, it just causes confusion. Maybe this should be - added as a feature just like :attr:`__weakref__` though.) - - -.. cmember:: initproc PyTypeObject.tp_init - - An optional pointer to an instance initialization function. - - This function corresponds to the :meth:`__init__` method of classes. Like - :meth:`__init__`, it is possible to create an instance without calling - :meth:`__init__`, and it is possible to reinitialize an instance by calling its - :meth:`__init__` method again. - - The function signature is :: - - int tp_init(PyObject *self, PyObject *args, PyObject *kwds) - - The self argument is the instance to be initialized; the *args* and *kwds* - arguments represent positional and keyword arguments of the call to - :meth:`__init__`. - - The :attr:`tp_init` function, if not *NULL*, is called when an instance is - created normally by calling its type, after the type's :attr:`tp_new` function - has returned an instance of the type. If the :attr:`tp_new` function returns an - instance of some other type that is not a subtype of the original type, no - :attr:`tp_init` function is called; if :attr:`tp_new` returns an instance of a - subtype of the original type, the subtype's :attr:`tp_init` is called. (VERSION - NOTE: described here is what is implemented in Python 2.2.1 and later. In - Python 2.2, the :attr:`tp_init` of the type of the object returned by - :attr:`tp_new` was always called, if not *NULL*.) - - This field is inherited by subtypes. - - -.. cmember:: allocfunc PyTypeObject.tp_alloc - - An optional pointer to an instance allocation function. - - The function signature is :: - - PyObject *tp_alloc(PyTypeObject *self, Py_ssize_t nitems) - - The purpose of this function is to separate memory allocation from memory - initialization. It should return a pointer to a block of memory of adequate - length for the instance, suitably aligned, and initialized to zeros, but with - :attr:`ob_refcnt` set to ``1`` and :attr:`ob_type` set to the type argument. If - the type's :attr:`tp_itemsize` is non-zero, the object's :attr:`ob_size` field - should be initialized to *nitems* and the length of the allocated memory block - should be ``tp_basicsize + nitems*tp_itemsize``, rounded up to a multiple of - ``sizeof(void*)``; otherwise, *nitems* is not used and the length of the block - should be :attr:`tp_basicsize`. - - Do not use this function to do any other instance initialization, not even to - allocate additional memory; that should be done by :attr:`tp_new`. - - This field is inherited by static subtypes, but not by dynamic subtypes - (subtypes created by a class statement); in the latter, this field is always set - to :cfunc:`PyType_GenericAlloc`, to force a standard heap allocation strategy. - That is also the recommended value for statically defined types. - - -.. cmember:: newfunc PyTypeObject.tp_new - - An optional pointer to an instance creation function. - - If this function is *NULL* for a particular type, that type cannot be called to - create new instances; presumably there is some other way to create instances, - like a factory function. - - The function signature is :: - - PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) - - The subtype argument is the type of the object being created; the *args* and - *kwds* arguments represent positional and keyword arguments of the call to the - type. Note that subtype doesn't have to equal the type whose :attr:`tp_new` - function is called; it may be a subtype of that type (but not an unrelated - type). - - The :attr:`tp_new` function should call ``subtype->tp_alloc(subtype, nitems)`` - to allocate space for the object, and then do only as much further - initialization as is absolutely necessary. Initialization that can safely be - ignored or repeated should be placed in the :attr:`tp_init` handler. A good - rule of thumb is that for immutable types, all initialization should take place - in :attr:`tp_new`, while for mutable types, most initialization should be - deferred to :attr:`tp_init`. - - This field is inherited by subtypes, except it is not inherited by static types - whose :attr:`tp_base` is *NULL* or ``&PyBaseObject_Type``. The latter exception - is a precaution so that old extension types don't become callable simply by - being linked with Python 2.2. - - -.. cmember:: destructor PyTypeObject.tp_free - - An optional pointer to an instance deallocation function. - - The signature of this function has changed slightly: in Python 2.2 and 2.2.1, - its signature is :ctype:`destructor`:: - - void tp_free(PyObject *) - - In Python 2.3 and beyond, its signature is :ctype:`freefunc`:: - - void tp_free(void *) - - The only initializer that is compatible with both versions is ``PyObject_Free``, - whose definition has suitably adapted in Python 2.3. - - This field is inherited by static subtypes, but not by dynamic subtypes - (subtypes created by a class statement); in the latter, this field is set to a - deallocator suitable to match :cfunc:`PyType_GenericAlloc` and the value of the - :const:`Py_TPFLAGS_HAVE_GC` flag bit. - - -.. cmember:: inquiry PyTypeObject.tp_is_gc - - An optional pointer to a function called by the garbage collector. - - The garbage collector needs to know whether a particular object is collectible - or not. Normally, it is sufficient to look at the object's type's - :attr:`tp_flags` field, and check the :const:`Py_TPFLAGS_HAVE_GC` flag bit. But - some types have a mixture of statically and dynamically allocated instances, and - the statically allocated instances are not collectible. Such types should - define this function; it should return ``1`` for a collectible instance, and - ``0`` for a non-collectible instance. The signature is :: - - int tp_is_gc(PyObject *self) - - (The only example of this are types themselves. The metatype, - :cdata:`PyType_Type`, defines this function to distinguish between statically - and dynamically allocated types.) - - This field is inherited by subtypes. (VERSION NOTE: in Python 2.2, it was not - inherited. It is inherited in 2.2.1 and later versions.) - - -.. cmember:: PyObject* PyTypeObject.tp_bases - - Tuple of base types. - - This is set for types created by a class statement. It should be *NULL* for - statically defined types. - - This field is not inherited. - - -.. cmember:: PyObject* PyTypeObject.tp_mro - - Tuple containing the expanded set of base types, starting with the type itself - and ending with :class:`object`, in Method Resolution Order. - - This field is not inherited; it is calculated fresh by :cfunc:`PyType_Ready`. - - -.. cmember:: PyObject* PyTypeObject.tp_cache - - Unused. Not inherited. Internal use only. - - -.. cmember:: PyObject* PyTypeObject.tp_subclasses - - List of weak references to subclasses. Not inherited. Internal use only. - - -.. cmember:: PyObject* PyTypeObject.tp_weaklist - - Weak reference list head, for weak references to this type object. Not - inherited. Internal use only. - -The remaining fields are only defined if the feature test macro -:const:`COUNT_ALLOCS` is defined, and are for internal use only. They are -documented here for completeness. None of these fields are inherited by -subtypes. - - -.. cmember:: Py_ssize_t PyTypeObject.tp_allocs - - Number of allocations. - - -.. cmember:: Py_ssize_t PyTypeObject.tp_frees - - Number of frees. - - -.. cmember:: Py_ssize_t PyTypeObject.tp_maxalloc - - Maximum simultaneously allocated objects. - - -.. cmember:: PyTypeObject* PyTypeObject.tp_next - - Pointer to the next type object with a non-zero :attr:`tp_allocs` field. - -Also, note that, in a garbage collected Python, tp_dealloc may be called from -any Python thread, not just the thread which created the object (if the object -becomes part of a refcount cycle, that cycle might be collected by a garbage -collection on any thread). This is not a problem for Python API calls, since -the thread on which tp_dealloc is called will own the Global Interpreter Lock -(GIL). However, if the object being destroyed in turn destroys objects from some -other C or C++ library, care should be taken to ensure that destroying those -objects on the thread which called tp_dealloc will not violate any assumptions -of the library. - - -.. _number-structs: - -Number Object Structures -======================== - -.. sectionauthor:: Amaury Forgeot d'Arc - - -.. ctype:: PyNumberMethods - - This structure holds pointers to the functions which an object uses to - implement the number protocol. Each function is used by the function of - similar name documented in the :ref:`number` section. - - Here is the structure definition:: - - typedef struct { - binaryfunc nb_add; - binaryfunc nb_subtract; - binaryfunc nb_multiply; - binaryfunc nb_remainder; - binaryfunc nb_divmod; - ternaryfunc nb_power; - unaryfunc nb_negative; - unaryfunc nb_positive; - unaryfunc nb_absolute; - inquiry nb_bool; - unaryfunc nb_invert; - binaryfunc nb_lshift; - binaryfunc nb_rshift; - binaryfunc nb_and; - binaryfunc nb_xor; - binaryfunc nb_or; - int nb_reserved; /* unused, must be zero */ - unaryfunc nb_int; - unaryfunc nb_long; - unaryfunc nb_float; - - unaryfunc nb_oct; /* not used anymore, must be zero */ - unaryfunc nb_hex; /* not used anymore, must be zero */ - - binaryfunc nb_inplace_add; - binaryfunc nb_inplace_subtract; - binaryfunc nb_inplace_multiply; - binaryfunc nb_inplace_remainder; - ternaryfunc nb_inplace_power; - binaryfunc nb_inplace_lshift; - binaryfunc nb_inplace_rshift; - binaryfunc nb_inplace_and; - binaryfunc nb_inplace_xor; - binaryfunc nb_inplace_or; - - binaryfunc nb_floor_divide; - binaryfunc nb_true_divide; - binaryfunc nb_inplace_floor_divide; - binaryfunc nb_inplace_true_divide; - - unaryfunc nb_index; - } PyNumberMethods; - - .. note:: - - Binary and ternary functions must check the type of all their operands, - and implement the necessary conversions (at least one of the operands is - an instance of the defined type). If the operation is not defined for the - given operands, binary and ternary functions must return - ``Py_NotImplemented``, if another error occurred they must return ``NULL`` - and set an exception. - - -.. _mapping-structs: - -Mapping Object Structures -========================= - -.. sectionauthor:: Amaury Forgeot d'Arc - - -.. ctype:: PyMappingMethods - - This structure holds pointers to the functions which an object uses to - implement the mapping protocol. It has three members: - -.. cmember:: lenfunc PyMappingMethods.mp_length - - This function is used by :cfunc:`PyMapping_Length` and - :cfunc:`PyObject_Size`, and has the same signature. This slot may be set to - *NULL* if the object has no defined length. - -.. cmember:: binaryfunc PyMappingMethods.mp_subscript - - This function is used by :cfunc:`PyObject_GetItem` and has the same - signature. This slot must be filled for the :cfunc:`PyMapping_Check` - function to return ``1``, it can be *NULL* otherwise. - -.. cmember:: objobjargproc PyMappingMethods.mp_ass_subscript - - This function is used by :cfunc:`PyObject_SetItem` and has the same - signature. If this slot is *NULL*, the object does not support item - assignment. - - -.. _sequence-structs: - -Sequence Object Structures -========================== - -.. sectionauthor:: Amaury Forgeot d'Arc - - -.. ctype:: PySequenceMethods - - This structure holds pointers to the functions which an object uses to - implement the sequence protocol. - -.. cmember:: lenfunc PySequenceMethods.sq_length - - This function is used by :cfunc:`PySequence_Size` and :cfunc:`PyObject_Size`, - and has the same signature. - -.. cmember:: binaryfunc PySequenceMethods.sq_concat - - This function is used by :cfunc:`PySequence_Concat` and has the same - signature. It is also used by the ``+`` operator, after trying the numeric - addition via the :attr:`tp_as_number.nb_add` slot. - -.. cmember:: ssizeargfunc PySequenceMethods.sq_repeat - - This function is used by :cfunc:`PySequence_Repeat` and has the same - signature. It is also used by the ``*`` operator, after trying numeric - multiplication via the :attr:`tp_as_number.nb_mul` slot. - -.. cmember:: ssizeargfunc PySequenceMethods.sq_item - - This function is used by :cfunc:`PySequence_GetItem` and has the same - signature. This slot must be filled for the :cfunc:`PySequence_Check` - function to return ``1``, it can be *NULL* otherwise. - - Negative indexes are handled as follows: if the :attr:`sq_length` slot is - filled, it is called and the sequence length is used to compute a positive - index which is passed to :attr:`sq_item`. If :attr:`sq_length` is *NULL*, - the index is passed as is to the function. - -.. cmember:: ssizeobjargproc PySequenceMethods.sq_ass_item - - This function is used by :cfunc:`PySequence_SetItem` and has the same - signature. This slot may be left to *NULL* if the object does not support - item assignment. - -.. cmember:: objobjproc PySequenceMethods.sq_contains - - This function may be used by :cfunc:`PySequence_Contains` and has the same - signature. This slot may be left to *NULL*, in this case - :cfunc:`PySequence_Contains` simply traverses the sequence until it finds a - match. - -.. cmember:: binaryfunc PySequenceMethods.sq_inplace_concat - - This function is used by :cfunc:`PySequence_InPlaceConcat` and has the same - signature. It should modify its first operand, and return it. - -.. cmember:: ssizeargfunc PySequenceMethods.sq_inplace_repeat - - This function is used by :cfunc:`PySequence_InPlaceRepeat` and has the same - signature. It should modify its first operand, and return it. - -.. XXX need to explain precedence between mapping and sequence -.. XXX explains when to implement the sq_inplace_* slots - - -.. _buffer-structs: - -Buffer Object Structures -======================== - -.. sectionauthor:: Greg J. Stein - - -The buffer interface exports a model where an object can expose its internal -data as a set of chunks of data, where each chunk is specified as a -pointer/length pair. These chunks are called :dfn:`segments` and are presumed -to be non-contiguous in memory. - -If an object does not export the buffer interface, then its :attr:`tp_as_buffer` -member in the :ctype:`PyTypeObject` structure should be *NULL*. Otherwise, the -:attr:`tp_as_buffer` will point to a :ctype:`PyBufferProcs` structure. - -.. note:: - - It is very important that your :ctype:`PyTypeObject` structure uses - :const:`Py_TPFLAGS_DEFAULT` for the value of the :attr:`tp_flags` member rather - than ``0``. This tells the Python runtime that your :ctype:`PyBufferProcs` - structure contains the :attr:`bf_getcharbuffer` slot. Older versions of Python - did not have this member, so a new Python interpreter using an old extension - needs to be able to test for its presence before using it. - - -.. ctype:: PyBufferProcs - - Structure used to hold the function pointers which define an implementation of - the buffer protocol. - - The first slot is :attr:`bf_getreadbuffer`, of type :ctype:`getreadbufferproc`. - If this slot is *NULL*, then the object does not support reading from the - internal data. This is non-sensical, so implementors should fill this in, but - callers should test that the slot contains a non-*NULL* value. - - The next slot is :attr:`bf_getwritebuffer` having type - :ctype:`getwritebufferproc`. This slot may be *NULL* if the object does not - allow writing into its returned buffers. - - The third slot is :attr:`bf_getsegcount`, with type :ctype:`getsegcountproc`. - This slot must not be *NULL* and is used to inform the caller how many segments - the object contains. Simple objects such as :ctype:`PyString_Type` and - :ctype:`PyBuffer_Type` objects contain a single segment. - - .. index:: single: PyType_HasFeature() - - The last slot is :attr:`bf_getcharbuffer`, of type :ctype:`getcharbufferproc`. - This slot will only be present if the :const:`Py_TPFLAGS_HAVE_GETCHARBUFFER` - flag is present in the :attr:`tp_flags` field of the object's - :ctype:`PyTypeObject`. Before using this slot, the caller should test whether it - is present by using the :cfunc:`PyType_HasFeature` function. If the flag is - present, :attr:`bf_getcharbuffer` may be *NULL*, indicating that the object's - contents cannot be used as *8-bit characters*. The slot function may also raise - an error if the object's contents cannot be interpreted as 8-bit characters. - For example, if the object is an array which is configured to hold floating - point values, an exception may be raised if a caller attempts to use - :attr:`bf_getcharbuffer` to fetch a sequence of 8-bit characters. This notion of - exporting the internal buffers as "text" is used to distinguish between objects - that are binary in nature, and those which have character-based content. - - .. note:: - - The current policy seems to state that these characters may be multi-byte - characters. This implies that a buffer size of *N* does not mean there are *N* - characters present. - - -.. data:: Py_TPFLAGS_HAVE_GETCHARBUFFER - - Flag bit set in the type structure to indicate that the :attr:`bf_getcharbuffer` - slot is known. This being set does not indicate that the object supports the - buffer interface or that the :attr:`bf_getcharbuffer` slot is non-*NULL*. - - -.. ctype:: Py_ssize_t (*readbufferproc) (PyObject *self, Py_ssize_t segment, void **ptrptr) - - Return a pointer to a readable segment of the buffer in ``*ptrptr``. This - function is allowed to raise an exception, in which case it must return ``-1``. - The *segment* which is specified must be zero or positive, and strictly less - than the number of segments returned by the :attr:`bf_getsegcount` slot - function. On success, it returns the length of the segment, and sets - ``*ptrptr`` to a pointer to that memory. - - -.. ctype:: Py_ssize_t (*writebufferproc) (PyObject *self, Py_ssize_t segment, void **ptrptr) - - Return a pointer to a writable memory buffer in ``*ptrptr``, and the length of - that segment as the function return value. The memory buffer must correspond to - buffer segment *segment*. Must return ``-1`` and set an exception on error. - :exc:`TypeError` should be raised if the object only supports read-only buffers, - and :exc:`SystemError` should be raised when *segment* specifies a segment that - doesn't exist. - - .. Why doesn't it raise ValueError for this one? - GJS: because you shouldn't be calling it with an invalid - segment. That indicates a blatant programming error in the C code. - - -.. ctype:: Py_ssize_t (*segcountproc) (PyObject *self, Py_ssize_t *lenp) - - Return the number of memory segments which comprise the buffer. If *lenp* is - not *NULL*, the implementation must report the sum of the sizes (in bytes) of - all segments in ``*lenp``. The function cannot fail. - - -.. ctype:: Py_ssize_t (*charbufferproc) (PyObject *self, Py_ssize_t segment, const char **ptrptr) - - Return the size of the segment *segment* that *ptrptr* is set to. ``*ptrptr`` - is set to the memory buffer. Returns ``-1`` on error. - - -.. _supporting-iteration: - -Supporting the Iterator Protocol -================================ - - -.. _supporting-cycle-detection: - -Supporting Cyclic Garbage Collection -==================================== - -Python's support for detecting and collecting garbage which involves circular -references requires support from object types which are "containers" for other -objects which may also be containers. Types which do not store references to -other objects, or which only store references to atomic types (such as numbers -or strings), do not need to provide any explicit support for garbage collection. - -To create a container type, the :attr:`tp_flags` field of the type object must -include the :const:`Py_TPFLAGS_HAVE_GC` and provide an implementation of the -:attr:`tp_traverse` handler. If instances of the type are mutable, a -:attr:`tp_clear` implementation must also be provided. - - -.. data:: Py_TPFLAGS_HAVE_GC - - Objects with a type with this flag set must conform with the rules documented - here. For convenience these objects will be referred to as container objects. - -Constructors for container types must conform to two rules: - -#. The memory for the object must be allocated using :cfunc:`PyObject_GC_New` or - :cfunc:`PyObject_GC_VarNew`. - -#. Once all the fields which may contain references to other containers are - initialized, it must call :cfunc:`PyObject_GC_Track`. - - -.. cfunction:: TYPE* PyObject_GC_New(TYPE, PyTypeObject *type) - - Analogous to :cfunc:`PyObject_New` but for container objects with the - :const:`Py_TPFLAGS_HAVE_GC` flag set. - - -.. cfunction:: TYPE* PyObject_GC_NewVar(TYPE, PyTypeObject *type, Py_ssize_t size) - - Analogous to :cfunc:`PyObject_NewVar` but for container objects with the - :const:`Py_TPFLAGS_HAVE_GC` flag set. - - -.. cfunction:: PyVarObject * PyObject_GC_Resize(PyVarObject *op, Py_ssize_t) - - Resize an object allocated by :cfunc:`PyObject_NewVar`. Returns the resized - object or *NULL* on failure. - - -.. cfunction:: void PyObject_GC_Track(PyObject *op) - - Adds the object *op* to the set of container objects tracked by the collector. - The collector can run at unexpected times so objects must be valid while being - tracked. This should be called once all the fields followed by the - :attr:`tp_traverse` handler become valid, usually near the end of the - constructor. - - -.. cfunction:: void _PyObject_GC_TRACK(PyObject *op) - - A macro version of :cfunc:`PyObject_GC_Track`. It should not be used for - extension modules. - -Similarly, the deallocator for the object must conform to a similar pair of -rules: - -#. Before fields which refer to other containers are invalidated, - :cfunc:`PyObject_GC_UnTrack` must be called. - -#. The object's memory must be deallocated using :cfunc:`PyObject_GC_Del`. - - -.. cfunction:: void PyObject_GC_Del(void *op) - - Releases memory allocated to an object using :cfunc:`PyObject_GC_New` or - :cfunc:`PyObject_GC_NewVar`. - - -.. cfunction:: void PyObject_GC_UnTrack(void *op) - - Remove the object *op* from the set of container objects tracked by the - collector. Note that :cfunc:`PyObject_GC_Track` can be called again on this - object to add it back to the set of tracked objects. The deallocator - (:attr:`tp_dealloc` handler) should call this for the object before any of the - fields used by the :attr:`tp_traverse` handler become invalid. - - -.. cfunction:: void _PyObject_GC_UNTRACK(PyObject *op) - - A macro version of :cfunc:`PyObject_GC_UnTrack`. It should not be used for - extension modules. - -The :attr:`tp_traverse` handler accepts a function parameter of this type: - - -.. ctype:: int (*visitproc)(PyObject *object, void *arg) - - Type of the visitor function passed to the :attr:`tp_traverse` handler. The - function should be called with an object to traverse as *object* and the third - parameter to the :attr:`tp_traverse` handler as *arg*. The Python core uses - several visitor functions to implement cyclic garbage detection; it's not - expected that users will need to write their own visitor functions. - -The :attr:`tp_traverse` handler must have the following type: - - -.. ctype:: int (*traverseproc)(PyObject *self, visitproc visit, void *arg) - - Traversal function for a container object. Implementations must call the - *visit* function for each object directly contained by *self*, with the - parameters to *visit* being the contained object and the *arg* value passed to - the handler. The *visit* function must not be called with a *NULL* object - argument. If *visit* returns a non-zero value that value should be returned - immediately. - -To simplify writing :attr:`tp_traverse` handlers, a :cfunc:`Py_VISIT` macro is -provided. In order to use this macro, the :attr:`tp_traverse` implementation -must name its arguments exactly *visit* and *arg*: - - -.. cfunction:: void Py_VISIT(PyObject *o) - - Call the *visit* callback, with arguments *o* and *arg*. If *visit* returns a - non-zero value, then return it. Using this macro, :attr:`tp_traverse` handlers - look like:: - - static int - my_traverse(Noddy *self, visitproc visit, void *arg) - { - Py_VISIT(self->foo); - Py_VISIT(self->bar); - return 0; - } - -The :attr:`tp_clear` handler must be of the :ctype:`inquiry` type, or *NULL* if -the object is immutable. - - -.. ctype:: int (*inquiry)(PyObject *self) - - Drop references that may have created reference cycles. Immutable objects do - not have to define this method since they can never directly create reference - cycles. Note that the object must still be valid after calling this method - (don't just call :cfunc:`Py_DECREF` on a reference). The collector will call - this method if it detects that this object is involved in a reference cycle. - Modified: python/branches/py3k-ctypes-pep3118/Doc/c-api/utilities.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/c-api/utilities.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/c-api/utilities.rst Sun Jan 20 11:45:31 2008 @@ -1,6 +1,5 @@ .. highlightlang:: c - .. _utilities: ********* @@ -11,1125 +10,11 @@ helping C code be more portable across platforms, using Python modules from C, and parsing function arguments and constructing Python values from C values. +.. toctree:: -.. _os: - -Operating System Utilities -========================== - - -.. cfunction:: int Py_FdIsInteractive(FILE *fp, const char *filename) - - Return true (nonzero) if the standard I/O file *fp* with name *filename* is - deemed interactive. This is the case for files for which ``isatty(fileno(fp))`` - is true. If the global flag :cdata:`Py_InteractiveFlag` is true, this function - also returns true if the *filename* pointer is *NULL* or if the name is equal to - one of the strings ``''`` or ``'???'``. - - -.. cfunction:: long PyOS_GetLastModificationTime(char *filename) - - Return the time of last modification of the file *filename*. The result is - encoded in the same way as the timestamp returned by the standard C library - function :cfunc:`time`. - - -.. cfunction:: void PyOS_AfterFork() - - Function to update some internal state after a process fork; this should be - called in the new process if the Python interpreter will continue to be used. - If a new executable is loaded into the new process, this function does not need - to be called. - - -.. cfunction:: int PyOS_CheckStack() - - Return true when the interpreter runs out of stack space. This is a reliable - check, but is only available when :const:`USE_STACKCHECK` is defined (currently - on Windows using the Microsoft Visual C++ compiler). :const:`USE_STACKCHECK` - will be defined automatically; you should never change the definition in your - own code. - - -.. cfunction:: PyOS_sighandler_t PyOS_getsig(int i) - - Return the current signal handler for signal *i*. This is a thin wrapper around - either :cfunc:`sigaction` or :cfunc:`signal`. Do not call those functions - directly! :ctype:`PyOS_sighandler_t` is a typedef alias for :ctype:`void - (\*)(int)`. - - -.. cfunction:: PyOS_sighandler_t PyOS_setsig(int i, PyOS_sighandler_t h) - - Set the signal handler for signal *i* to be *h*; return the old signal handler. - This is a thin wrapper around either :cfunc:`sigaction` or :cfunc:`signal`. Do - not call those functions directly! :ctype:`PyOS_sighandler_t` is a typedef - alias for :ctype:`void (\*)(int)`. - -.. _systemfunctions: - -System Functions -================ - -These are utility functions that make functionality from the :mod:`sys` module -accessible to C code. They all work with the current interpreter thread's -:mod:`sys` module's dict, which is contained in the internal thread state structure. - -.. cfunction:: PyObject *PySys_GetObject(char *name) - - Return the object *name* from the :mod:`sys` module or *NULL* if it does - not exist, without setting an exception. - -.. cfunction:: FILE *PySys_GetFile(char *name, FILE *def) - - Return the :ctype:`FILE*` associated with the object *name* in the - :mod:`sys` module, or *def* if *name* is not in the module or is not associated - with a :ctype:`FILE*`. - -.. cfunction:: int PySys_SetObject(char *name, PyObject *v) - - Set *name* in the :mod:`sys` module to *v* unless *v* is *NULL*, in which - case *name* is deleted from the sys module. Returns ``0`` on success, ``-1`` - on error. - -.. cfunction:: void PySys_ResetWarnOptions(void) - - Reset :data:`sys.warnoptions` to an empty list. - -.. cfunction:: void PySys_AddWarnOption(char *s) - - Append *s* to :data:`sys.warnoptions`. - -.. cfunction:: void PySys_SetPath(char *path) - - Set :data:`sys.path` to a list object of paths found in *path* which should - be a list of paths separated with the platform's search path delimiter - (``:`` on Unix, ``;`` on Windows). - -.. cfunction:: void PySys_WriteStdout(const char *format, ...) - - Write the output string described by *format* to :data:`sys.stdout`. No - exceptions are raised, even if truncation occurs (see below). - - *format* should limit the total size of the formatted output string to - 1000 bytes or less -- after 1000 bytes, the output string is truncated. - In particular, this means that no unrestricted "%s" formats should occur; - these should be limited using "%.s" where is a decimal number - calculated so that plus the maximum size of other formatted text does not - exceed 1000 bytes. Also watch out for "%f", which can print hundreds of - digits for very large numbers. - - If a problem occurs, or :data:`sys.stdout` is unset, the formatted message - is written to the real (C level) *stdout*. - -.. cfunction:: void PySys_WriteStderr(const char *format, ...) - - As above, but write to :data:`sys.stderr` or *stderr* instead. - - -.. _processcontrol: - -Process Control -=============== - - -.. cfunction:: void Py_FatalError(const char *message) - - .. index:: single: abort() - - Print a fatal error message and kill the process. No cleanup is performed. - This function should only be invoked when a condition is detected that would - make it dangerous to continue using the Python interpreter; e.g., when the - object administration appears to be corrupted. On Unix, the standard C library - function :cfunc:`abort` is called which will attempt to produce a :file:`core` - file. - - -.. cfunction:: void Py_Exit(int status) - - .. index:: - single: Py_Finalize() - single: exit() - - Exit the current process. This calls :cfunc:`Py_Finalize` and then calls the - standard C library function ``exit(status)``. - - -.. cfunction:: int Py_AtExit(void (*func) ()) - - .. index:: - single: Py_Finalize() - single: cleanup functions - - Register a cleanup function to be called by :cfunc:`Py_Finalize`. The cleanup - function will be called with no arguments and should return no value. At most - 32 cleanup functions can be registered. When the registration is successful, - :cfunc:`Py_AtExit` returns ``0``; on failure, it returns ``-1``. The cleanup - function registered last is called first. Each cleanup function will be called - at most once. Since Python's internal finalization will have completed before - the cleanup function, no Python APIs should be called by *func*. - - -.. _importing: - -Importing Modules -================= - - -.. cfunction:: PyObject* PyImport_ImportModule(const char *name) - - .. index:: - single: package variable; __all__ - single: __all__ (package variable) - single: modules (in module sys) - - This is a simplified interface to :cfunc:`PyImport_ImportModuleEx` below, - leaving the *globals* and *locals* arguments set to *NULL* and *level* set - to 0. When the *name* - argument contains a dot (when it specifies a submodule of a package), the - *fromlist* argument is set to the list ``['*']`` so that the return value is the - named module rather than the top-level package containing it as would otherwise - be the case. (Unfortunately, this has an additional side effect when *name* in - fact specifies a subpackage instead of a submodule: the submodules specified in - the package's ``__all__`` variable are loaded.) Return a new reference to the - imported module, or *NULL* with an exception set on failure. Before Python 2.4, - the module may still be created in the failure case --- examine ``sys.modules`` - to find out. Starting with Python 2.4, a failing import of a module no longer - leaves the module in ``sys.modules``. - - -.. cfunction:: PyObject* PyImport_ImportModuleNoBlock(const char *name) - - This version of :cfunc:`PyImport_ImportModule` does not block. It's intended - to be used in C function which import other modules to execute a function. - The import may block if another thread holds the import lock. The function - :cfunc:`PyImport_ImportModuleNoBlock` doesn't block. It first tries to fetch - the module from sys.modules and falls back to :cfunc:`PyImport_ImportModule` - unless the the lock is hold. In the latter case the function raises an - ImportError. - - -.. cfunction:: PyObject* PyImport_ImportModuleEx(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist) - - .. index:: builtin: __import__ - - Import a module. This is best described by referring to the built-in Python - function :func:`__import__`, as the standard :func:`__import__` function calls - this function directly. - - The return value is a new reference to the imported module or top-level package, - or *NULL* with an exception set on failure (before Python 2.4, the module may - still be created in this case). Like for :func:`__import__`, the return value - when a submodule of a package was requested is normally the top-level package, - unless a non-empty *fromlist* was given. - - Failing imports remove incomplete module objects, like with - :cfunc:`PyImport_ImportModule`. - - -.. cfunction:: PyObject* PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level) - - Import a module. This is best described by referring to the built-in Python - function :func:`__import__`, as the standard :func:`__import__` function calls - this function directly. - - The return value is a new reference to the imported module or top-level package, - or *NULL* with an exception set on failure. Like for :func:`__import__`, - the return value when a submodule of a package was requested is normally the - top-level package, unless a non-empty *fromlist* was given. - - -.. cfunction:: PyObject* PyImport_Import(PyObject *name) - - This is a higher-level interface that calls the current "import hook - function" (with an explicit *level* of 0, meaning absolute import). It - invokes the :func:`__import__` function from the ``__builtins__`` of the - current globals. This means that the import is done using whatever import - hooks are installed in the current environment. - - -.. cfunction:: PyObject* PyImport_ReloadModule(PyObject *m) - - Reload a module. Return a new reference to the reloaded module, or *NULL* with - an exception set on failure (the module still exists in this case). - - -.. cfunction:: PyObject* PyImport_AddModule(const char *name) - - Return the module object corresponding to a module name. The *name* argument - may be of the form ``package.module``. First check the modules dictionary if - there's one there, and if not, create a new one and insert it in the modules - dictionary. Return *NULL* with an exception set on failure. - - .. note:: - - This function does not load or import the module; if the module wasn't already - loaded, you will get an empty module object. Use :cfunc:`PyImport_ImportModule` - or one of its variants to import a module. Package structures implied by a - dotted name for *name* are not created if not already present. - - -.. cfunction:: PyObject* PyImport_ExecCodeModule(char *name, PyObject *co) - - .. index:: builtin: compile - - Given a module name (possibly of the form ``package.module``) and a code object - read from a Python bytecode file or obtained from the built-in function - :func:`compile`, load the module. Return a new reference to the module object, - or *NULL* with an exception set if an error occurred. Before Python 2.4, the - module could still be created in error cases. Starting with Python 2.4, *name* - is removed from :attr:`sys.modules` in error cases, and even if *name* was already - in :attr:`sys.modules` on entry to :cfunc:`PyImport_ExecCodeModule`. Leaving - incompletely initialized modules in :attr:`sys.modules` is dangerous, as imports of - such modules have no way to know that the module object is an unknown (and - probably damaged with respect to the module author's intents) state. - - This function will reload the module if it was already imported. See - :cfunc:`PyImport_ReloadModule` for the intended way to reload a module. - - If *name* points to a dotted name of the form ``package.module``, any package - structures not already created will still not be created. - - -.. cfunction:: long PyImport_GetMagicNumber() - - Return the magic number for Python bytecode files (a.k.a. :file:`.pyc` and - :file:`.pyo` files). The magic number should be present in the first four bytes - of the bytecode file, in little-endian byte order. - - -.. cfunction:: PyObject* PyImport_GetModuleDict() - - Return the dictionary used for the module administration (a.k.a. - ``sys.modules``). Note that this is a per-interpreter variable. - - -.. cfunction:: void _PyImport_Init() - - Initialize the import mechanism. For internal use only. - - -.. cfunction:: void PyImport_Cleanup() - - Empty the module table. For internal use only. - - -.. cfunction:: void _PyImport_Fini() - - Finalize the import mechanism. For internal use only. - - -.. cfunction:: PyObject* _PyImport_FindExtension(char *, char *) - - For internal use only. - - -.. cfunction:: PyObject* _PyImport_FixupExtension(char *, char *) - - For internal use only. - - -.. cfunction:: int PyImport_ImportFrozenModule(char *name) - - Load a frozen module named *name*. Return ``1`` for success, ``0`` if the - module is not found, and ``-1`` with an exception set if the initialization - failed. To access the imported module on a successful load, use - :cfunc:`PyImport_ImportModule`. (Note the misnomer --- this function would - reload the module if it was already imported.) - - -.. ctype:: struct _frozen - - .. index:: single: freeze utility - - This is the structure type definition for frozen module descriptors, as - generated by the :program:`freeze` utility (see :file:`Tools/freeze/` in the - Python source distribution). Its definition, found in :file:`Include/import.h`, - is:: - - struct _frozen { - char *name; - unsigned char *code; - int size; - }; - - -.. cvar:: struct _frozen* PyImport_FrozenModules - - This pointer is initialized to point to an array of :ctype:`struct _frozen` - records, terminated by one whose members are all *NULL* or zero. When a frozen - module is imported, it is searched in this table. Third-party code could play - tricks with this to provide a dynamically created collection of frozen modules. - - -.. cfunction:: int PyImport_AppendInittab(char *name, void (*initfunc)(void)) - - Add a single module to the existing table of built-in modules. This is a - convenience wrapper around :cfunc:`PyImport_ExtendInittab`, returning ``-1`` if - the table could not be extended. The new module can be imported by the name - *name*, and uses the function *initfunc* as the initialization function called - on the first attempted import. This should be called before - :cfunc:`Py_Initialize`. - - -.. ctype:: struct _inittab - - Structure describing a single entry in the list of built-in modules. Each of - these structures gives the name and initialization function for a module built - into the interpreter. Programs which embed Python may use an array of these - structures in conjunction with :cfunc:`PyImport_ExtendInittab` to provide - additional built-in modules. The structure is defined in - :file:`Include/import.h` as:: - - struct _inittab { - char *name; - void (*initfunc)(void); - }; - - -.. cfunction:: int PyImport_ExtendInittab(struct _inittab *newtab) - - Add a collection of modules to the table of built-in modules. The *newtab* - array must end with a sentinel entry which contains *NULL* for the :attr:`name` - field; failure to provide the sentinel value can result in a memory fault. - Returns ``0`` on success or ``-1`` if insufficient memory could be allocated to - extend the internal table. In the event of failure, no modules are added to the - internal table. This should be called before :cfunc:`Py_Initialize`. - - -.. _marshalling-utils: - -Data marshalling support -======================== - -These routines allow C code to work with serialized objects using the same data -format as the :mod:`marshal` module. There are functions to write data into the -serialization format, and additional functions that can be used to read the data -back. Files used to store marshalled data must be opened in binary mode. - -Numeric values are stored with the least significant byte first. - -The module supports two versions of the data format: version 0 is the historical -version, version 1 (new in Python 2.4) shares interned strings in the file, and -upon unmarshalling. *Py_MARSHAL_VERSION* indicates the current file format -(currently 1). - - -.. cfunction:: void PyMarshal_WriteLongToFile(long value, FILE *file, int version) - - Marshal a :ctype:`long` integer, *value*, to *file*. This will only write the - least-significant 32 bits of *value*; regardless of the size of the native - :ctype:`long` type. *version* indicates the file format. - - -.. cfunction:: void PyMarshal_WriteObjectToFile(PyObject *value, FILE *file, int version) - - Marshal a Python object, *value*, to *file*. - *version* indicates the file format. - - -.. cfunction:: PyObject* PyMarshal_WriteObjectToString(PyObject *value, int version) - - Return a string object containing the marshalled representation of *value*. - *version* indicates the file format. - - -The following functions allow marshalled values to be read back in. - -XXX What about error detection? It appears that reading past the end of the -file will always result in a negative numeric value (where that's relevant), but -it's not clear that negative values won't be handled properly when there's no -error. What's the right way to tell? Should only non-negative values be written -using these routines? - - -.. cfunction:: long PyMarshal_ReadLongFromFile(FILE *file) - - Return a C :ctype:`long` from the data stream in a :ctype:`FILE\*` opened for - reading. Only a 32-bit value can be read in using this function, regardless of - the native size of :ctype:`long`. - - -.. cfunction:: int PyMarshal_ReadShortFromFile(FILE *file) - - Return a C :ctype:`short` from the data stream in a :ctype:`FILE\*` opened for - reading. Only a 16-bit value can be read in using this function, regardless of - the native size of :ctype:`short`. - - -.. cfunction:: PyObject* PyMarshal_ReadObjectFromFile(FILE *file) - - Return a Python object from the data stream in a :ctype:`FILE\*` opened for - reading. On error, sets the appropriate exception (:exc:`EOFError` or - :exc:`TypeError`) and returns *NULL*. - - -.. cfunction:: PyObject* PyMarshal_ReadLastObjectFromFile(FILE *file) - - Return a Python object from the data stream in a :ctype:`FILE\*` opened for - reading. Unlike :cfunc:`PyMarshal_ReadObjectFromFile`, this function assumes - that no further objects will be read from the file, allowing it to aggressively - load file data into memory so that the de-serialization can operate from data in - memory rather than reading a byte at a time from the file. Only use these - variant if you are certain that you won't be reading anything else from the - file. On error, sets the appropriate exception (:exc:`EOFError` or - :exc:`TypeError`) and returns *NULL*. - - -.. cfunction:: PyObject* PyMarshal_ReadObjectFromString(char *string, Py_ssize_t len) - - Return a Python object from the data stream in a character buffer containing - *len* bytes pointed to by *string*. On error, sets the appropriate exception - (:exc:`EOFError` or :exc:`TypeError`) and returns *NULL*. - - -.. _arg-parsing: - -Parsing arguments and building values -===================================== - -These functions are useful when creating your own extensions functions and -methods. Additional information and examples are available in -:ref:`extending-index`. - -The first three of these functions described, :cfunc:`PyArg_ParseTuple`, -:cfunc:`PyArg_ParseTupleAndKeywords`, and :cfunc:`PyArg_Parse`, all use *format -strings* which are used to tell the function about the expected arguments. The -format strings use the same syntax for each of these functions. - -A format string consists of zero or more "format units." A format unit -describes one Python object; it is usually a single character or a parenthesized -sequence of format units. With a few exceptions, a format unit that is not a -parenthesized sequence normally corresponds to a single address argument to -these functions. In the following description, the quoted form is the format -unit; the entry in (round) parentheses is the Python object type that matches -the format unit; and the entry in [square] brackets is the type of the C -variable(s) whose address should be passed. - -``s`` (string or Unicode object) [const char \*] - Convert a Python string or Unicode object to a C pointer to a character string. - You must not provide storage for the string itself; a pointer to an existing - string is stored into the character pointer variable whose address you pass. - The C string is NUL-terminated. The Python string must not contain embedded NUL - bytes; if it does, a :exc:`TypeError` exception is raised. Unicode objects are - converted to C strings using the default encoding. If this conversion fails, a - :exc:`UnicodeError` is raised. - -``s#`` (string, Unicode or any read buffer compatible object) [const char \*, int] - This variant on ``s`` stores into two C variables, the first one a pointer to a - character string, the second one its length. In this case the Python string may - contain embedded null bytes. Unicode objects pass back a pointer to the default - encoded string version of the object if such a conversion is possible. All - other read-buffer compatible objects pass back a reference to the raw internal - data representation. - -``y`` (bytes object) [const char \*] - This variant on ``s`` convert a Python bytes object to a C pointer to a - character string. The bytes object must not contain embedded NUL bytes; if it - does, a :exc:`TypeError` exception is raised. - -``y#`` (bytes object) [const char \*, int] - This variant on ``s#`` stores into two C variables, the first one a pointer to a - character string, the second one its length. This only accepts bytes objects. - -``z`` (string or ``None``) [const char \*] - Like ``s``, but the Python object may also be ``None``, in which case the C - pointer is set to *NULL*. - -``z#`` (string or ``None`` or any read buffer compatible object) [const char \*, int] - This is to ``s#`` as ``z`` is to ``s``. - -``u`` (Unicode object) [Py_UNICODE \*] - Convert a Python Unicode object to a C pointer to a NUL-terminated buffer of - 16-bit Unicode (UTF-16) data. As with ``s``, there is no need to provide - storage for the Unicode data buffer; a pointer to the existing Unicode data is - stored into the :ctype:`Py_UNICODE` pointer variable whose address you pass. - -``u#`` (Unicode object) [Py_UNICODE \*, int] - This variant on ``u`` stores into two C variables, the first one a pointer to a - Unicode data buffer, the second one its length. Non-Unicode objects are handled - by interpreting their read-buffer pointer as pointer to a :ctype:`Py_UNICODE` - array. - -``Z`` (Unicode or ``None``) [Py_UNICODE \*] - Like ``s``, but the Python object may also be ``None``, in which case the C - pointer is set to *NULL*. - -``Z#`` (Unicode or ``None``) [Py_UNICODE \*, int] - This is to ``u#`` as ``Z`` is to ``u``. - -``es`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] - This variant on ``s`` is used for encoding Unicode and objects convertible to - Unicode into a character buffer. It only works for encoded data without embedded - NUL bytes. - - This format requires two arguments. The first is only used as input, and - must be a :ctype:`const char\*` which points to the name of an encoding as a - NUL-terminated string, or *NULL*, in which case the default encoding is used. - An exception is raised if the named encoding is not known to Python. The - second argument must be a :ctype:`char\*\*`; the value of the pointer it - references will be set to a buffer with the contents of the argument text. - The text will be encoded in the encoding specified by the first argument. - - :cfunc:`PyArg_ParseTuple` will allocate a buffer of the needed size, copy the - encoded data into this buffer and adjust *\*buffer* to reference the newly - allocated storage. The caller is responsible for calling :cfunc:`PyMem_Free` to - free the allocated buffer after use. - -``et`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] - Same as ``es`` except that 8-bit string objects are passed through without - recoding them. Instead, the implementation assumes that the string object uses - the encoding passed in as parameter. - -``es#`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer, int \*buffer_length] - This variant on ``s#`` is used for encoding Unicode and objects convertible to - Unicode into a character buffer. Unlike the ``es`` format, this variant allows - input data which contains NUL characters. - - It requires three arguments. The first is only used as input, and must be a - :ctype:`const char\*` which points to the name of an encoding as a - NUL-terminated string, or *NULL*, in which case the default encoding is used. - An exception is raised if the named encoding is not known to Python. The - second argument must be a :ctype:`char\*\*`; the value of the pointer it - references will be set to a buffer with the contents of the argument text. - The text will be encoded in the encoding specified by the first argument. - The third argument must be a pointer to an integer; the referenced integer - will be set to the number of bytes in the output buffer. - - There are two modes of operation: - - If *\*buffer* points a *NULL* pointer, the function will allocate a buffer of - the needed size, copy the encoded data into this buffer and set *\*buffer* to - reference the newly allocated storage. The caller is responsible for calling - :cfunc:`PyMem_Free` to free the allocated buffer after usage. - - If *\*buffer* points to a non-*NULL* pointer (an already allocated buffer), - :cfunc:`PyArg_ParseTuple` will use this location as the buffer and interpret the - initial value of *\*buffer_length* as the buffer size. It will then copy the - encoded data into the buffer and NUL-terminate it. If the buffer is not large - enough, a :exc:`ValueError` will be set. - - In both cases, *\*buffer_length* is set to the length of the encoded data - without the trailing NUL byte. - -``et#`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] - Same as ``es#`` except that string objects are passed through without recoding - them. Instead, the implementation assumes that the string object uses the - encoding passed in as parameter. - -``b`` (integer) [char] - Convert a Python integer to a tiny int, stored in a C :ctype:`char`. - -``B`` (integer) [unsigned char] - Convert a Python integer to a tiny int without overflow checking, stored in a C - :ctype:`unsigned char`. - -``h`` (integer) [short int] - Convert a Python integer to a C :ctype:`short int`. - -``H`` (integer) [unsigned short int] - Convert a Python integer to a C :ctype:`unsigned short int`, without overflow - checking. - -``i`` (integer) [int] - Convert a Python integer to a plain C :ctype:`int`. - -``I`` (integer) [unsigned int] - Convert a Python integer to a C :ctype:`unsigned int`, without overflow - checking. - -``l`` (integer) [long int] - Convert a Python integer to a C :ctype:`long int`. - -``k`` (integer) [unsigned long] - Convert a Python integer to a C :ctype:`unsigned long` without - overflow checking. - -``L`` (integer) [PY_LONG_LONG] - Convert a Python integer to a C :ctype:`long long`. This format is only - available on platforms that support :ctype:`long long` (or :ctype:`_int64` on - Windows). - -``K`` (integer) [unsigned PY_LONG_LONG] - Convert a Python integer to a C :ctype:`unsigned long long` - without overflow checking. This format is only available on platforms that - support :ctype:`unsigned long long` (or :ctype:`unsigned _int64` on Windows). - -``n`` (integer) [Py_ssize_t] - Convert a Python integer to a C :ctype:`Py_ssize_t`. - -``c`` (string of length 1) [char] - Convert a Python character, represented as a string of length 1, to a C - :ctype:`char`. - -``f`` (float) [float] - Convert a Python floating point number to a C :ctype:`float`. - -``d`` (float) [double] - Convert a Python floating point number to a C :ctype:`double`. - -``D`` (complex) [Py_complex] - Convert a Python complex number to a C :ctype:`Py_complex` structure. - -``O`` (object) [PyObject \*] - Store a Python object (without any conversion) in a C object pointer. The C - program thus receives the actual object that was passed. The object's reference - count is not increased. The pointer stored is not *NULL*. - -``O!`` (object) [*typeobject*, PyObject \*] - Store a Python object in a C object pointer. This is similar to ``O``, but - takes two C arguments: the first is the address of a Python type object, the - second is the address of the C variable (of type :ctype:`PyObject\*`) into which - the object pointer is stored. If the Python object does not have the required - type, :exc:`TypeError` is raised. - -``O&`` (object) [*converter*, *anything*] - Convert a Python object to a C variable through a *converter* function. This - takes two arguments: the first is a function, the second is the address of a C - variable (of arbitrary type), converted to :ctype:`void \*`. The *converter* - function in turn is called as follows:: - - status = converter(object, address); - - where *object* is the Python object to be converted and *address* is the - :ctype:`void\*` argument that was passed to the :cfunc:`PyArg_Parse\*` function. - The returned *status* should be ``1`` for a successful conversion and ``0`` if - the conversion has failed. When the conversion fails, the *converter* function - should raise an exception. - -``S`` (string) [PyStringObject \*] - Like ``O`` but requires that the Python object is a string object. Raises - :exc:`TypeError` if the object is not a string object. The C variable may also - be declared as :ctype:`PyObject\*`. - -``U`` (Unicode string) [PyUnicodeObject \*] - Like ``O`` but requires that the Python object is a Unicode object. Raises - :exc:`TypeError` if the object is not a Unicode object. The C variable may also - be declared as :ctype:`PyObject\*`. - -``t#`` (read-only character buffer) [char \*, int] - Like ``s#``, but accepts any object which implements the read-only buffer - interface. The :ctype:`char\*` variable is set to point to the first byte of - the buffer, and the :ctype:`int` is set to the length of the buffer. Only - single-segment buffer objects are accepted; :exc:`TypeError` is raised for all - others. - -``w`` (read-write character buffer) [char \*] - Similar to ``s``, but accepts any object which implements the read-write buffer - interface. The caller must determine the length of the buffer by other means, - or use ``w#`` instead. Only single-segment buffer objects are accepted; - :exc:`TypeError` is raised for all others. - -``w#`` (read-write character buffer) [char \*, int] - Like ``s#``, but accepts any object which implements the read-write buffer - interface. The :ctype:`char \*` variable is set to point to the first byte of - the buffer, and the :ctype:`int` is set to the length of the buffer. Only - single-segment buffer objects are accepted; :exc:`TypeError` is raised for all - others. - -``(items)`` (tuple) [*matching-items*] - The object must be a Python sequence whose length is the number of format units - in *items*. The C arguments must correspond to the individual format units in - *items*. Format units for sequences may be nested. - -It is possible to pass "long" integers (integers whose value exceeds the -platform's :const:`LONG_MAX`) however no proper range checking is done --- the -most significant bits are silently truncated when the receiving field is too -small to receive the value (actually, the semantics are inherited from downcasts -in C --- your mileage may vary). - -A few other characters have a meaning in a format string. These may not occur -inside nested parentheses. They are: - -``|`` - Indicates that the remaining arguments in the Python argument list are optional. - The C variables corresponding to optional arguments should be initialized to - their default value --- when an optional argument is not specified, - :cfunc:`PyArg_ParseTuple` does not touch the contents of the corresponding C - variable(s). - -``:`` - The list of format units ends here; the string after the colon is used as the - function name in error messages (the "associated value" of the exception that - :cfunc:`PyArg_ParseTuple` raises). - -``;`` - The list of format units ends here; the string after the semicolon is used as - the error message *instead* of the default error message. Clearly, ``:`` and - ``;`` mutually exclude each other. - -Note that any Python object references which are provided to the caller are -*borrowed* references; do not decrement their reference count! - -Additional arguments passed to these functions must be addresses of variables -whose type is determined by the format string; these are used to store values -from the input tuple. There are a few cases, as described in the list of format -units above, where these parameters are used as input values; they should match -what is specified for the corresponding format unit in that case. - -For the conversion to succeed, the *arg* object must match the format and the -format must be exhausted. On success, the :cfunc:`PyArg_Parse\*` functions -return true, otherwise they return false and raise an appropriate exception. - - -.. cfunction:: int PyArg_ParseTuple(PyObject *args, const char *format, ...) - - Parse the parameters of a function that takes only positional parameters into - local variables. Returns true on success; on failure, it returns false and - raises the appropriate exception. - - -.. cfunction:: int PyArg_VaParse(PyObject *args, const char *format, va_list vargs) - - Identical to :cfunc:`PyArg_ParseTuple`, except that it accepts a va_list rather - than a variable number of arguments. - - -.. cfunction:: int PyArg_ParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *keywords[], ...) - - Parse the parameters of a function that takes both positional and keyword - parameters into local variables. Returns true on success; on failure, it - returns false and raises the appropriate exception. - - -.. cfunction:: int PyArg_VaParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *keywords[], va_list vargs) - - Identical to :cfunc:`PyArg_ParseTupleAndKeywords`, except that it accepts a - va_list rather than a variable number of arguments. - - -.. XXX deprecated, will be removed -.. cfunction:: int PyArg_Parse(PyObject *args, const char *format, ...) - - Function used to deconstruct the argument lists of "old-style" functions --- - these are functions which use the :const:`METH_OLDARGS` parameter parsing - method. This is not recommended for use in parameter parsing in new code, and - most code in the standard interpreter has been modified to no longer use this - for that purpose. It does remain a convenient way to decompose other tuples, - however, and may continue to be used for that purpose. - - -.. cfunction:: int PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...) - - A simpler form of parameter retrieval which does not use a format string to - specify the types of the arguments. Functions which use this method to retrieve - their parameters should be declared as :const:`METH_VARARGS` in function or - method tables. The tuple containing the actual parameters should be passed as - *args*; it must actually be a tuple. The length of the tuple must be at least - *min* and no more than *max*; *min* and *max* may be equal. Additional - arguments must be passed to the function, each of which should be a pointer to a - :ctype:`PyObject\*` variable; these will be filled in with the values from - *args*; they will contain borrowed references. The variables which correspond - to optional parameters not given by *args* will not be filled in; these should - be initialized by the caller. This function returns true on success and false if - *args* is not a tuple or contains the wrong number of elements; an exception - will be set if there was a failure. - - This is an example of the use of this function, taken from the sources for the - :mod:`_weakref` helper module for weak references:: - - static PyObject * - weakref_ref(PyObject *self, PyObject *args) - { - PyObject *object; - PyObject *callback = NULL; - PyObject *result = NULL; - - if (PyArg_UnpackTuple(args, "ref", 1, 2, &object, &callback)) { - result = PyWeakref_NewRef(object, callback); - } - return result; - } - - The call to :cfunc:`PyArg_UnpackTuple` in this example is entirely equivalent to - this call to :cfunc:`PyArg_ParseTuple`:: - - PyArg_ParseTuple(args, "O|O:ref", &object, &callback) - - -.. cfunction:: PyObject* Py_BuildValue(const char *format, ...) - - Create a new value based on a format string similar to those accepted by the - :cfunc:`PyArg_Parse\*` family of functions and a sequence of values. Returns - the value or *NULL* in the case of an error; an exception will be raised if - *NULL* is returned. - - :cfunc:`Py_BuildValue` does not always build a tuple. It builds a tuple only if - its format string contains two or more format units. If the format string is - empty, it returns ``None``; if it contains exactly one format unit, it returns - whatever object is described by that format unit. To force it to return a tuple - of size 0 or one, parenthesize the format string. - - When memory buffers are passed as parameters to supply data to build objects, as - for the ``s`` and ``s#`` formats, the required data is copied. Buffers provided - by the caller are never referenced by the objects created by - :cfunc:`Py_BuildValue`. In other words, if your code invokes :cfunc:`malloc` - and passes the allocated memory to :cfunc:`Py_BuildValue`, your code is - responsible for calling :cfunc:`free` for that memory once - :cfunc:`Py_BuildValue` returns. - - In the following description, the quoted form is the format unit; the entry in - (round) parentheses is the Python object type that the format unit will return; - and the entry in [square] brackets is the type of the C value(s) to be passed. - - The characters space, tab, colon and comma are ignored in format strings (but - not within format units such as ``s#``). This can be used to make long format - strings a tad more readable. - - ``s`` (string) [char \*] - Convert a null-terminated C string to a Python object. If the C string pointer - is *NULL*, ``None`` is used. - - ``s#`` (string) [char \*, int] - Convert a C string and its length to a Python object. If the C string pointer - is *NULL*, the length is ignored and ``None`` is returned. - - ``z`` (string or ``None``) [char \*] - Same as ``s``. - - ``z#`` (string or ``None``) [char \*, int] - Same as ``s#``. - - ``u`` (Unicode string) [Py_UNICODE \*] - Convert a null-terminated buffer of Unicode (UCS-2 or UCS-4) data to a Python - Unicode object. If the Unicode buffer pointer is *NULL*, ``None`` is returned. - - ``u#`` (Unicode string) [Py_UNICODE \*, int] - Convert a Unicode (UCS-2 or UCS-4) data buffer and its length to a Python - Unicode object. If the Unicode buffer pointer is *NULL*, the length is ignored - and ``None`` is returned. - - ``U`` (string) [char \*] - Convert a null-terminated C string to a Python unicode object. If the C string - pointer is *NULL*, ``None`` is used. - - ``U#`` (string) [char \*, int] - Convert a C string and its length to a Python unicode object. If the C string - pointer is *NULL*, the length is ignored and ``None`` is returned. - - ``i`` (integer) [int] - Convert a plain C :ctype:`int` to a Python integer object. - - ``b`` (integer) [char] - Convert a plain C :ctype:`char` to a Python integer object. - - ``h`` (integer) [short int] - Convert a plain C :ctype:`short int` to a Python integer object. - - ``l`` (integer) [long int] - Convert a C :ctype:`long int` to a Python integer object. - - ``B`` (integer) [unsigned char] - Convert a C :ctype:`unsigned char` to a Python integer object. - - ``H`` (integer) [unsigned short int] - Convert a C :ctype:`unsigned short int` to a Python integer object. - - ``I`` (integer/long) [unsigned int] - Convert a C :ctype:`unsigned int` to a Python long integer object. - - ``k`` (integer/long) [unsigned long] - Convert a C :ctype:`unsigned long` to a Python long integer object. - - ``L`` (long) [PY_LONG_LONG] - Convert a C :ctype:`long long` to a Python integer object. Only available - on platforms that support :ctype:`long long`. - - ``K`` (long) [unsigned PY_LONG_LONG] - Convert a C :ctype:`unsigned long long` to a Python integer object. Only - available on platforms that support :ctype:`unsigned long long`. - - ``n`` (int) [Py_ssize_t] - Convert a C :ctype:`Py_ssize_t` to a Python integer. - - ``c`` (string of length 1) [char] - Convert a C :ctype:`int` representing a character to a Python string of length - 1. - - ``d`` (float) [double] - Convert a C :ctype:`double` to a Python floating point number. - - ``f`` (float) [float] - Same as ``d``. - - ``D`` (complex) [Py_complex \*] - Convert a C :ctype:`Py_complex` structure to a Python complex number. - - ``O`` (object) [PyObject \*] - Pass a Python object untouched (except for its reference count, which is - incremented by one). If the object passed in is a *NULL* pointer, it is assumed - that this was caused because the call producing the argument found an error and - set an exception. Therefore, :cfunc:`Py_BuildValue` will return *NULL* but won't - raise an exception. If no exception has been raised yet, :exc:`SystemError` is - set. - - ``S`` (object) [PyObject \*] - Same as ``O``. - - ``N`` (object) [PyObject \*] - Same as ``O``, except it doesn't increment the reference count on the object. - Useful when the object is created by a call to an object constructor in the - argument list. - - ``O&`` (object) [*converter*, *anything*] - Convert *anything* to a Python object through a *converter* function. The - function is called with *anything* (which should be compatible with :ctype:`void - \*`) as its argument and should return a "new" Python object, or *NULL* if an - error occurred. - - ``(items)`` (tuple) [*matching-items*] - Convert a sequence of C values to a Python tuple with the same number of items. - - ``[items]`` (list) [*matching-items*] - Convert a sequence of C values to a Python list with the same number of items. - - ``{items}`` (dictionary) [*matching-items*] - Convert a sequence of C values to a Python dictionary. Each pair of consecutive - C values adds one item to the dictionary, serving as key and value, - respectively. - - If there is an error in the format string, the :exc:`SystemError` exception is - set and *NULL* returned. - - -.. _string-conversion: - -String conversion and formatting -================================ - -Functions for number conversion and formatted string output. - - -.. cfunction:: int PyOS_snprintf(char *str, size_t size, const char *format, ...) - - Output not more than *size* bytes to *str* according to the format string - *format* and the extra arguments. See the Unix man page :manpage:`snprintf(2)`. - - -.. cfunction:: int PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va) - - Output not more than *size* bytes to *str* according to the format string - *format* and the variable argument list *va*. Unix man page - :manpage:`vsnprintf(2)`. - -:cfunc:`PyOS_snprintf` and :cfunc:`PyOS_vsnprintf` wrap the Standard C library -functions :cfunc:`snprintf` and :cfunc:`vsnprintf`. Their purpose is to -guarantee consistent behavior in corner cases, which the Standard C functions do -not. - -The wrappers ensure that *str*[*size*-1] is always ``'\0'`` upon return. They -never write more than *size* bytes (including the trailing ``'\0'``) into str. -Both functions require that ``str != NULL``, ``size > 0`` and ``format != -NULL``. - -If the platform doesn't have :cfunc:`vsnprintf` and the buffer size needed to -avoid truncation exceeds *size* by more than 512 bytes, Python aborts with a -*Py_FatalError*. - -The return value (*rv*) for these functions should be interpreted as follows: - -* When ``0 <= rv < size``, the output conversion was successful and *rv* - characters were written to *str* (excluding the trailing ``'\0'`` byte at - *str*[*rv*]). - -* When ``rv >= size``, the output conversion was truncated and a buffer with - ``rv + 1`` bytes would have been needed to succeed. *str*[*size*-1] is ``'\0'`` - in this case. - -* When ``rv < 0``, "something bad happened." *str*[*size*-1] is ``'\0'`` in - this case too, but the rest of *str* is undefined. The exact cause of the error - depends on the underlying platform. - -The following functions provide locale-independent string to number conversions. - - -.. cfunction:: double PyOS_ascii_strtod(const char *nptr, char **endptr) - - Convert a string to a :ctype:`double`. This function behaves like the Standard C - function :cfunc:`strtod` does in the C locale. It does this without changing the - current locale, since that would not be thread-safe. - - :cfunc:`PyOS_ascii_strtod` should typically be used for reading configuration - files or other non-user input that should be locale independent. - - See the Unix man page :manpage:`strtod(2)` for details. - - -.. cfunction:: char * PyOS_ascii_formatd(char *buffer, size_t buf_len, const char *format, double d) - - Convert a :ctype:`double` to a string using the ``'.'`` as the decimal - separator. *format* is a :cfunc:`printf`\ -style format string specifying the - number format. Allowed conversion characters are ``'e'``, ``'E'``, ``'f'``, - ``'F'``, ``'g'`` and ``'G'``. - - The return value is a pointer to *buffer* with the converted string or NULL if - the conversion failed. - - -.. cfunction:: double PyOS_ascii_atof(const char *nptr) - - Convert a string to a :ctype:`double` in a locale-independent way. - - See the Unix man page :manpage:`atof(2)` for details. - - -.. cfunction:: char * PyOS_stricmp(char *s1, char *s2) - - Case insensitive comparsion of strings. The functions works almost - identical to :cfunc:`strcmp` except that it ignores the case. - - -.. cfunction:: char * PyOS_strnicmp(char *s1, char *s2, Py_ssize_t size) - - Case insensitive comparsion of strings. The functions works almost - identical to :cfunc:`strncmp` except that it ignores the case. - - -.. _reflection: - -Reflection -========== - -.. cfunction:: PyObject* PyEval_GetBuiltins() - - Return a dictionary of the builtins in the current execution frame, - or the interpreter of the thread state if no frame is currently executing. - - -.. cfunction:: PyObject* PyEval_GetLocals() - - Return a dictionary of the local variables in the current execution frame, - or *NULL* if no frame is currently executing. - - -.. cfunction:: PyObject* PyEval_GetGlobals() - - Return a dictionary of the global variables in the current execution frame, - or *NULL* if no frame is currently executing. - - -.. cfunction:: PyFrameObject* PyEval_GetFrame() - - Return the current thread state's frame, which is *NULL* if no frame is - currently executing. - - -.. cfunction:: int PyEval_GetRestricted() - - If there is a current frame and it is executing in restricted mode, return true, - otherwise false. - - -.. cfunction:: const char* PyEval_GetFuncName(PyObject *func) - - Return the name of *func* if it is a function, class or instance object, else the - name of *func*\s type. - - -.. cfunction:: const char* PyEval_GetFuncDesc(PyObject *func) - - Return a description string, depending on the type of *func*. - Return values include "()" for functions and methods, " constructor", - " instance", and " object". Concatenated with the result of - :cfunc:`PyEval_GetFuncName`, the result will be a description of - *func*. + sys.rst + import.rst + marshal.rst + arg.rst + conversion.rst + reflection.rst Modified: python/branches/py3k-ctypes-pep3118/Doc/library/collections.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/collections.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/collections.rst Sun Jan 20 11:45:31 2008 @@ -579,8 +579,8 @@ customize a prototype instance:: >>> Account = namedtuple('Account', 'owner balance transaction_count') - >>> model_account = Account('', 0.0, 0) - >>> johns_account = model_account._replace(owner='John') + >>> default_account = Account('', 0.0, 0) + >>> johns_account = default_account._replace(owner='John') .. rubric:: Footnotes Modified: python/branches/py3k-ctypes-pep3118/Doc/library/curses.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/curses.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/curses.rst Sun Jan 20 11:45:31 2008 @@ -16,6 +16,19 @@ designed to match the API of ncurses, an open-source curses library hosted on Linux and the BSD variants of Unix. +.. note:: + + Since version 5.4, the ncurses library decides how to interpret non-ASCII data + using the ``nl_langinfo`` function. That means that you have to call + :func:`locale.setlocale` in the application and encode Unicode strings + using one of the system's available encodings. This example uses the + system's default encoding:: + + import locale + locale.setlocale(locale.LC_ALL, '') + code = locale.getpreferredencoding() + + Then use *code* as the encoding for :meth:`str.encode` calls. .. seealso:: Modified: python/branches/py3k-ctypes-pep3118/Doc/library/logging.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/logging.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/logging.rst Sun Jan 20 11:45:31 2008 @@ -1179,65 +1179,65 @@ also illustrates what dict-like behaviour is needed from an arbitrary "dict-like" object for use in the constructor:: -import logging - -class ConnInfo: - """ - An example class which shows how an arbitrary class can be used as - the 'extra' context information repository passed to a LoggerAdapter. - """ - - def __getitem__(self, name): - """ - To allow this instance to look like a dict. - """ - from random import choice - if name == "ip": - result = choice(["127.0.0.1", "192.168.0.1"]) - elif name == "user": - result = choice(["jim", "fred", "sheila"]) - else: - result = self.__dict__.get(name, "?") - return result - - def __iter__(self): - """ - To allow iteration over keys, which will be merged into - the LogRecord dict before formatting and output. - """ - keys = ["ip", "user"] - keys.extend(self.__dict__.keys()) - return keys.__iter__() - -if __name__ == "__main__": - from random import choice - levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL) - a1 = logging.LoggerAdapter(logging.getLogger("a.b.c"), - { "ip" : "123.231.231.123", "user" : "sheila" }) - logging.basicConfig(level=logging.DEBUG, - format="%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s") - a1.debug("A debug message") - a1.info("An info message with %s", "some parameters") - a2 = logging.LoggerAdapter(logging.getLogger("d.e.f"), ConnInfo()) - for x in range(10): - lvl = choice(levels) - lvlname = logging.getLevelName(lvl) - a2.log(lvl, "A message at %s level with %d %s", lvlname, 2, "parameters") + import logging + + class ConnInfo: + """ + An example class which shows how an arbitrary class can be used as + the 'extra' context information repository passed to a LoggerAdapter. + """ + + def __getitem__(self, name): + """ + To allow this instance to look like a dict. + """ + from random import choice + if name == "ip": + result = choice(["127.0.0.1", "192.168.0.1"]) + elif name == "user": + result = choice(["jim", "fred", "sheila"]) + else: + result = self.__dict__.get(name, "?") + return result + + def __iter__(self): + """ + To allow iteration over keys, which will be merged into + the LogRecord dict before formatting and output. + """ + keys = ["ip", "user"] + keys.extend(self.__dict__.keys()) + return keys.__iter__() + + if __name__ == "__main__": + from random import choice + levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL) + a1 = logging.LoggerAdapter(logging.getLogger("a.b.c"), + { "ip" : "123.231.231.123", "user" : "sheila" }) + logging.basicConfig(level=logging.DEBUG, + format="%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s") + a1.debug("A debug message") + a1.info("An info message with %s", "some parameters") + a2 = logging.LoggerAdapter(logging.getLogger("d.e.f"), ConnInfo()) + for x in range(10): + lvl = choice(levels) + lvlname = logging.getLevelName(lvl) + a2.log(lvl, "A message at %s level with %d %s", lvlname, 2, "parameters") When this script is run, the output should look something like this:: -2008-01-18 14:49:54,023 a.b.c DEBUG IP: 123.231.231.123 User: sheila A debug message -2008-01-18 14:49:54,023 a.b.c INFO IP: 123.231.231.123 User: sheila An info message with some parameters -2008-01-18 14:49:54,023 d.e.f CRITICAL IP: 192.168.0.1 User: jim A message at CRITICAL level with 2 parameters -2008-01-18 14:49:54,033 d.e.f INFO IP: 192.168.0.1 User: jim A message at INFO level with 2 parameters -2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: sheila A message at WARNING level with 2 parameters -2008-01-18 14:49:54,033 d.e.f ERROR IP: 127.0.0.1 User: fred A message at ERROR level with 2 parameters -2008-01-18 14:49:54,033 d.e.f ERROR IP: 127.0.0.1 User: sheila A message at ERROR level with 2 parameters -2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: sheila A message at WARNING level with 2 parameters -2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: jim A message at WARNING level with 2 parameters -2008-01-18 14:49:54,033 d.e.f INFO IP: 192.168.0.1 User: fred A message at INFO level with 2 parameters -2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: sheila A message at WARNING level with 2 parameters -2008-01-18 14:49:54,033 d.e.f WARNING IP: 127.0.0.1 User: jim A message at WARNING level with 2 parameters + 2008-01-18 14:49:54,023 a.b.c DEBUG IP: 123.231.231.123 User: sheila A debug message + 2008-01-18 14:49:54,023 a.b.c INFO IP: 123.231.231.123 User: sheila An info message with some parameters + 2008-01-18 14:49:54,023 d.e.f CRITICAL IP: 192.168.0.1 User: jim A message at CRITICAL level with 2 parameters + 2008-01-18 14:49:54,033 d.e.f INFO IP: 192.168.0.1 User: jim A message at INFO level with 2 parameters + 2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: sheila A message at WARNING level with 2 parameters + 2008-01-18 14:49:54,033 d.e.f ERROR IP: 127.0.0.1 User: fred A message at ERROR level with 2 parameters + 2008-01-18 14:49:54,033 d.e.f ERROR IP: 127.0.0.1 User: sheila A message at ERROR level with 2 parameters + 2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: sheila A message at WARNING level with 2 parameters + 2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: jim A message at WARNING level with 2 parameters + 2008-01-18 14:49:54,033 d.e.f INFO IP: 192.168.0.1 User: fred A message at INFO level with 2 parameters + 2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: sheila A message at WARNING level with 2 parameters + 2008-01-18 14:49:54,033 d.e.f WARNING IP: 127.0.0.1 User: jim A message at WARNING level with 2 parameters .. versionadded:: 2.6 Modified: python/branches/py3k-ctypes-pep3118/Doc/library/mmap.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/mmap.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/mmap.rst Sun Jan 20 11:45:31 2008 @@ -137,11 +137,12 @@ an exception being raised. -.. method:: mmap.find(string[, start]) +.. method:: mmap.find(string[, start[, end]]) - Returns the lowest index in the object where the substring *string* is found. - Returns ``-1`` on failure. *start* is the index at which the search begins, and - defaults to zero. + Returns the lowest index in the object where the substring *string* is found, + such that *string* is contained in the range [*start*, *end*]. Optional + arguments *start* and *end* are interpreted as in slice notation. + Returns ``-1`` on failure. .. method:: mmap.flush([offset, size]) @@ -186,6 +187,14 @@ :exc:`TypeError` exception. +.. method:: mmap.rfind(string[, start[, end]]) + + Returns the highest index in the object where the substring *string* is + found, such that *string* is contained in the range [*start*, + *end*]. Optional arguments *start* and *end* are interpreted as in slice + notation. Returns ``-1`` on failure. + + .. method:: mmap.seek(pos[, whence]) Set the file's current position. *whence* argument is optional and defaults to Modified: python/branches/py3k-ctypes-pep3118/Doc/library/optparse.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/optparse.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/optparse.rst Sun Jan 20 11:45:31 2008 @@ -535,6 +535,35 @@ default value. If an option has no default value (or the default value is ``None``), ``%default`` expands to ``none``. +When dealing with many options, it is convenient to group these +options for better help output. An :class:`OptionParser` can contain +several option groups, each of which can contain several options. + +Continuing with the parser defined above, adding an +:class:`OptionGroup` to a parser is easy:: + + group = OptionGroup(parser, "Dangerous Options", + "Caution: use these options at your own risk. " + "It is believed that some of them bite.") + group.add_option("-g", action="store_true", help="Group option.") + parser.add_option_group(group) + +This would result in the following help output:: + + usage: [options] arg1 arg2 + + options: + -h, --help show this help message and exit + -v, --verbose make lots of noise [default] + -q, --quiet be vewwy quiet (I'm hunting wabbits) + -fFILE, --file=FILE write output to FILE + -mMODE, --mode=MODE interaction mode: one of 'novice', 'intermediate' + [default], 'expert' + + Dangerous Options: + Caution: use of these options is at your own risk. It is believed that + some of them bite. + -g Group option. .. _optparse-printing-version-string: Modified: python/branches/py3k-ctypes-pep3118/Doc/library/os.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/os.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/os.rst Sun Jan 20 11:45:31 2008 @@ -378,6 +378,18 @@ :func:`fdopen`, use its :meth:`close` method. +.. function:: closerange(fd_low, fd_high) + + Close all file descriptors from *fd_low* (inclusive) to *fd_high* (exclusive), + ignoring errors. Availability: Macintosh, Unix, Windows. Equivalent to:: + + for fd in xrange(fd_low, fd_high): + try: + os.close(fd) + except OSError: + pass + + .. function:: device_encoding(fd) Return a string describing the encoding of the device associated with *fd* Modified: python/branches/py3k-ctypes-pep3118/Doc/library/rational.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/rational.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/rational.rst Sun Jan 20 11:45:31 2008 @@ -15,6 +15,7 @@ .. class:: Rational(numerator=0, denominator=1) Rational(other_rational) + Rational(string) The first version requires that *numerator* and *denominator* are instances of :class:`numbers.Integral` and returns a new @@ -22,10 +23,12 @@ *denominator* is :const:`0`, raises a :exc:`ZeroDivisionError`. The second version requires that *other_rational* is an instance of :class:`numbers.Rational` and returns an instance of - :class:`Rational` with the same value. + :class:`Rational` with the same value. The third version expects a + string of the form ``[-+]?[0-9]+(/[0-9]+)?``, optionally surrounded + by spaces. Implements all of the methods and operations from - :class:`numbers.Rational` and is hashable. + :class:`numbers.Rational` and is immutable and hashable. .. method:: Rational.from_float(flt) @@ -36,6 +39,13 @@ 10)`` +.. method:: Rational.from_decimal(dec) + + This classmethod constructs a :class:`Rational` representing the + exact value of *dec*, which must be a + :class:`decimal.Decimal`. + + .. method:: Rational.__floor__() Returns the greatest :class:`int` ``<= self``. Will be accessible Modified: python/branches/py3k-ctypes-pep3118/Doc/library/socketserver.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/socketserver.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/socketserver.rst Sun Jan 20 11:45:31 2008 @@ -44,7 +44,7 @@ not exit until all threads created by :class:`ThreadingMixIn` have exited. Server classes have the same external methods and attributes, no matter what -network protocol they use: +network protocol they use. Server Creation Notes @@ -193,6 +193,13 @@ The type of socket used by the server; :const:`socket.SOCK_STREAM` and :const:`socket.SOCK_DGRAM` are two possible values. +.. data:: timeout + + Timeout duration, measured in seconds, or :const:`None` if no timeout is desired. + If no incoming requests are received within the timeout period, + the :meth:`handle_timeout` method is called and then the server resumes waiting for + requests. + There are various server methods that can be overridden by subclasses of base server classes like :class:`TCPServer`; these methods aren't useful to external users of the server object. @@ -220,6 +227,13 @@ method raises an exception. The default action is to print the traceback to standard output and continue handling further requests. +.. function:: handle_timeout() + + This function is called when the :attr:`timeout` attribute has been set to a + value other than :const:`None` and the timeout period has passed with no + requests being received. The default action for forking servers is + to collect the status of any child processes that have exited, while + in threading servers this method does nothing. .. function:: process_request(request, client_address) Modified: python/branches/py3k-ctypes-pep3118/Doc/library/sqlite3.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/sqlite3.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/sqlite3.rst Sun Jan 20 11:45:31 2008 @@ -1,4 +1,3 @@ - :mod:`sqlite3` --- DB-API 2.0 interface for SQLite databases ============================================================ @@ -387,7 +386,7 @@ .. method:: Cursor.execute(sql, [parameters]) - Executes a SQL statement. The SQL statement may be parametrized (i. e. + Executes an SQL statement. The SQL statement may be parametrized (i. e. placeholders instead of SQL literals). The :mod:`sqlite3` module supports two kinds of placeholders: question marks (qmark style) and named placeholders (named style). @@ -408,7 +407,7 @@ .. method:: Cursor.executemany(sql, seq_of_parameters) - Executes a SQL command against all parameter sequences or mappings found in + Executes an SQL command against all parameter sequences or mappings found in the sequence *sql*. The :mod:`sqlite3` module also allows using an :term:`iterator` yielding parameters instead of a sequence. @@ -432,6 +431,35 @@ .. literalinclude:: ../includes/sqlite3/executescript.py +.. method:: Cursor.fetchone() + + Fetches the next row of a query result set, returning a single sequence, + or ``None`` when no more data is available. + + +.. method:: Cursor.fetchmany([size=cursor.arraysize]) + + Fetches the next set of rows of a query result, returning a list. An empty + list is returned when no more rows are available. + + The number of rows to fetch per call is specified by the *size* parameter. + If it is not given, the cursor's arraysize determines the number of rows + to be fetched. The method should try to fetch as many rows as indicated by + the size parameter. If this is not possible due to the specified number of + rows not being available, fewer rows may be returned. + + Note there are performance considerations involved with the *size* parameter. + For optimal performance, it is usually best to use the arraysize attribute. + If the *size* parameter is used, then it is best for it to retain the same + value from one :meth:`fetchmany` call to the next. + +.. method:: Cursor.fetchall() + + Fetches all (remaining) rows of a query result, returning a list. Note that + the cursor's arraysize attribute can affect the performance of this operation. + An empty list is returned when no rows are available. + + .. attribute:: Cursor.rowcount Although the :class:`Cursor` class of the :mod:`sqlite3` module implements this Modified: python/branches/py3k-ctypes-pep3118/Doc/library/threading.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/threading.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/threading.rst Sun Jan 20 11:45:31 2008 @@ -615,18 +615,19 @@ When the *timeout* argument is present and not ``None``, it should be a floating point number specifying a timeout for the operation in seconds (or fractions - thereof). As :meth:`join` always returns ``None``, you must call - :meth:`isAlive` to decide whether a timeout happened. + thereof). As :meth:`join` always returns ``None``, you must call :meth:`isAlive` + after :meth:`join` to decide whether a timeout happened -- if the thread is + still alive, the :meth:`join` call timed out. When the *timeout* argument is not present or ``None``, the operation will block until the thread terminates. A thread can be :meth:`join`\ ed many times. - :meth:`join` may throw a :exc:`RuntimeError`, if an attempt is made to join the - current thread as that would cause a deadlock. It is also an error to - :meth:`join` a thread before it has been started and attempts to do so raises - same exception. + :meth:`join` raises a :exc:`RuntimeError` if an attempt is made to join + the current thread as that would cause a deadlock. It is also an error to + :meth:`join` a thread before it has been started and attempts to do so + raises the same exception. .. method:: Thread.getName() Modified: python/branches/py3k-ctypes-pep3118/Doc/library/trace.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/trace.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/trace.rst Sun Jan 20 11:45:31 2008 @@ -64,12 +64,14 @@ stdout for each file processed. :option:`--ignore-module` - Ignore the named module and its submodules (if it is a package). May be given + Accepts comma separated list of module names. Ignore each of the named + module and its submodules (if it is a package). May be given multiple times. :option:`--ignore-dir` - Ignore all modules and packages in the named directory and subdirectories. May - be given multiple times. + Ignore all modules and packages in the named directory and subdirectories + (multiple directories can be joined by os.pathsep). May be given multiple + times. .. _trace-api: Modified: python/branches/py3k-ctypes-pep3118/Doc/library/xml.sax.utils.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/xml.sax.utils.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/xml.sax.utils.rst Sun Jan 20 11:45:31 2008 @@ -19,7 +19,8 @@ You can escape other strings of data by passing a dictionary as the optional *entities* parameter. The keys and values must all be strings; each key will be - replaced with its corresponding value. + replaced with its corresponding value. The characters ``'&'``, ``'<'`` and + ``'>'`` are always escaped, even if *entities* is provided. .. function:: unescape(data[, entities]) @@ -28,7 +29,8 @@ You can unescape other strings of data by passing a dictionary as the optional *entities* parameter. The keys and values must all be strings; each key will be - replaced with its corresponding value. + replaced with its corresponding value. ``'&'``, ``'<'``, and ``'>'`` + are always unescaped, even if *entities* is provided. .. function:: quoteattr(data[, entities]) Modified: python/branches/py3k-ctypes-pep3118/Doc/library/zipfile.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/zipfile.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/zipfile.rst Sun Jan 20 11:45:31 2008 @@ -19,7 +19,8 @@ documentation). It can handle ZIP files that use the ZIP64 extensions (that is ZIP files that are more than 4 GByte in size). It supports decryption of encrypted files in ZIP archives, but it currently cannot -create an encrypted file. +create an encrypted file. Decryption is extremely slow as it is +implemented in native python rather than C. For other archive formats, see the :mod:`bz2`, :mod:`gzip`, and :mod:`tarfile` modules. Modified: python/branches/py3k-ctypes-pep3118/Doc/tools/sphinx-build.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/tools/sphinx-build.py (original) +++ python/branches/py3k-ctypes-pep3118/Doc/tools/sphinx-build.py Sun Jan 20 11:45:31 2008 @@ -12,12 +12,12 @@ if __name__ == '__main__': if sys.version_info[:3] < (2, 4, 0): - print("""\ + sys.stderr.write("""\ Error: Sphinx needs to be executed with Python 2.4 or newer (not 3.0 though). (If you run this from the Makefile, you can set the PYTHON variable to the path of an alternative interpreter executable, e.g., ``make html PYTHON=python2.5``). -""", file=sys.stderr) +""") sys.exit(1) from sphinx import main Modified: python/branches/py3k-ctypes-pep3118/Doc/whatsnew/2.6.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/whatsnew/2.6.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/whatsnew/2.6.rst Sun Jan 20 11:45:31 2008 @@ -868,16 +868,19 @@ .. Revision 57769 - * A new method in the :mod:`curses` module: for a window, :meth:`chgat` changes the display characters for a certain number of characters on a single line. + (Contributed by Fabian Kreutz.) :: # Boldface text starting at y=0,x=21 # and affecting the rest of the line. stdscr.chgat(0,21, curses.A_BOLD) - (Contributed by Fabian Kreutz.) + The :class:`Textbox` class in the :mod:`curses.textpad` module + now supports editing in insert mode as well as overwrite mode. + Insert mode is enabled by supplying a true value for the *insert_mode* + parameter when creating the :class:`Textbox` instance. * The :mod:`decimal` module was updated to version 1.66 of `the General Decimal Specification `__. New features @@ -960,6 +963,13 @@ .. Patch #1490190 +* :class:`mmap` objects now have a :meth:`rfind` method that finds + a substring, beginning at the end of the string and searching + backwards. The :meth:`find` method + also gained a *end* parameter containing the index at which to stop + the forward search. + (Contributed by John Lenton.) + * The :mod:`new` module has been removed from Python 3.0. Importing it therefore triggers a warning message when Python is running in 3.0-warning @@ -1102,6 +1112,13 @@ (Contributed by Alberto Bertogli.) .. Patch #1646 + +* The base classes in the :mod:`SocketServer` module now support + calling a :meth:`handle_timeout` method after a span of inactivity + specified by the server's :attr:`timeout` attribute. (Contributed + by Michael Pomraning.) + + .. Patch #742598 * A new variable in the :mod:`sys` module, :attr:`float_info`, is an object Modified: python/branches/py3k-ctypes-pep3118/Lib/SocketServer.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/SocketServer.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/SocketServer.py Sun Jan 20 11:45:31 2008 @@ -158,6 +158,7 @@ - server_bind() - server_activate() - get_request() -> request, client_address + - handle_timeout() - verify_request(request, client_address) - server_close() - process_request(request, client_address) @@ -171,6 +172,7 @@ Class variables that may be overridden by derived classes or instances: + - timeout - address_family - socket_type - allow_reuse_address @@ -182,6 +184,8 @@ """ + timeout = None + def __init__(self, server_address, RequestHandlerClass): """Constructor. May be extended, do not override.""" self.server_address = server_address @@ -204,8 +208,9 @@ # finishing a request is fairly arbitrary. Remember: # # - handle_request() is the top-level call. It calls - # get_request(), verify_request() and process_request() - # - get_request() is different for stream or datagram sockets + # await_request(), verify_request() and process_request() + # - get_request(), called by await_request(), is different for + # stream or datagram sockets # - process_request() is the place that may fork a new process # or create a new thread to finish the request # - finish_request() instantiates the request handler class; @@ -214,7 +219,7 @@ def handle_request(self): """Handle one request, possibly blocking.""" try: - request, client_address = self.get_request() + request, client_address = self.await_request() except socket.error: return if self.verify_request(request, client_address): @@ -224,6 +229,28 @@ self.handle_error(request, client_address) self.close_request(request) + def await_request(self): + """Call get_request or handle_timeout, observing self.timeout. + + Returns value from get_request() or raises socket.timeout exception if + timeout was exceeded. + """ + if self.timeout is not None: + # If timeout == 0, you're responsible for your own fd magic. + import select + fd_sets = select.select([self], [], [], self.timeout) + if not fd_sets[0]: + self.handle_timeout() + raise socket.timeout("Listening timed out") + return self.get_request() + + def handle_timeout(self): + """Called if no new request arrives within self.timeout. + + Overridden by ForkingMixIn. + """ + pass + def verify_request(self, request, client_address): """Verify the request. May be overridden. @@ -289,6 +316,7 @@ - server_bind() - server_activate() - get_request() -> request, client_address + - handle_timeout() - verify_request(request, client_address) - process_request(request, client_address) - close_request(request) @@ -301,6 +329,7 @@ Class variables that may be overridden by derived classes or instances: + - timeout - address_family - socket_type - request_queue_size (only for stream sockets) @@ -405,11 +434,12 @@ """Mix-in class to handle each request in a new process.""" + timeout = 300 active_children = None max_children = 40 def collect_children(self): - """Internal routine to wait for died children.""" + """Internal routine to wait for children that have exited.""" while self.active_children: if len(self.active_children) < self.max_children: options = os.WNOHANG @@ -424,6 +454,13 @@ if not pid: break self.active_children.remove(pid) + def handle_timeout(self): + """Wait for zombies after self.timeout seconds of inactivity. + + May be extended, do not override. + """ + self.collect_children() + def process_request(self, request, client_address): """Fork a new subprocess to process the request.""" self.collect_children() Modified: python/branches/py3k-ctypes-pep3118/Lib/curses/textpad.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/curses/textpad.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/curses/textpad.py Sun Jan 20 11:45:31 2008 @@ -39,8 +39,9 @@ KEY_LEFT = Ctrl-B, KEY_RIGHT = Ctrl-F, KEY_UP = Ctrl-P, KEY_DOWN = Ctrl-N KEY_BACKSPACE = Ctrl-h """ - def __init__(self, win): + def __init__(self, win, insert_mode=False): self.win = win + self.insert_mode = insert_mode (self.maxy, self.maxx) = win.getmaxyx() self.maxy = self.maxy - 1 self.maxx = self.maxx - 1 @@ -49,9 +50,10 @@ win.keypad(1) def _end_of_line(self, y): - "Go to the location of the first blank on the given line." + """Go to the location of the first blank on the given line, + returning the index of the last non-blank character.""" last = self.maxx - while 1: + while True: if ascii.ascii(self.win.inch(y, last)) != ascii.SP: last = min(self.maxx, last+1) break @@ -60,19 +62,31 @@ last = last - 1 return last + def _insert_printable_char(self, ch): + (y, x) = self.win.getyx() + if y < self.maxy or x < self.maxx: + if self.insert_mode: + oldch = self.win.inch() + # The try-catch ignores the error we trigger from some curses + # versions by trying to write into the lowest-rightmost spot + # in the window. + try: + self.win.addch(ch) + except curses.error: + pass + if self.insert_mode: + (backy, backx) = self.win.getyx() + if ascii.isprint(oldch): + self._insert_printable_char(oldch) + self.win.move(backy, backx) + def do_command(self, ch): "Process a single editing command." (y, x) = self.win.getyx() self.lastcmd = ch if ascii.isprint(ch): if y < self.maxy or x < self.maxx: - # The try-catch ignores the error we trigger from some curses - # versions by trying to write into the lowest-rightmost spot - # in the window. - try: - self.win.addch(ch) - except curses.error: - pass + self._insert_printable_char(ch) elif ch == ascii.SOH: # ^a self.win.move(y, 0) elif ch in (ascii.STX,curses.KEY_LEFT, ascii.BS,curses.KEY_BACKSPACE): @@ -139,7 +153,7 @@ if stop == 0 and self.stripspaces: continue for x in range(self.maxx+1): - if self.stripspaces and x == stop: + if self.stripspaces and x > stop: break result = result + chr(ascii.ascii(self.win.inch(y, x))) if self.maxy > 0: Modified: python/branches/py3k-ctypes-pep3118/Lib/email/mime/multipart.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/email/mime/multipart.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/email/mime/multipart.py Sun Jan 20 11:45:31 2008 @@ -34,6 +34,12 @@ keyword arguments (or passed into the _params argument). """ MIMEBase.__init__(self, 'multipart', _subtype, **_params) + + # Initialise _payload to an empty list as the Message superclass's + # implementation of is_multipart assumes that _payload is a list for + # multipart messages. + self._payload = [] + if _subparts: for p in _subparts: self.attach(p) Modified: python/branches/py3k-ctypes-pep3118/Lib/email/test/test_email.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/email/test/test_email.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/email/test/test_email.py Sun Jan 20 11:45:31 2008 @@ -1892,6 +1892,9 @@ eq(msg.get_payload(0), text1) eq(msg.get_payload(1), text2) + def test_default_multipart_constructor(self): + msg = MIMEMultipart() + self.assertTrue(msg.is_multipart()) # A general test of parser->model->generator idempotency. IOW, read a message Modified: python/branches/py3k-ctypes-pep3118/Lib/mailbox.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/mailbox.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/mailbox.py Sun Jan 20 11:45:31 2008 @@ -313,7 +313,10 @@ subpath = self._lookup(key) f = open(os.path.join(self._path, subpath), 'r') try: - msg = MaildirMessage(f) + if self._factory: + msg = self._factory(f) + else: + msg = MaildirMessage(f) finally: f.close() subdir, name = os.path.split(subpath) Modified: python/branches/py3k-ctypes-pep3118/Lib/pydoc.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/pydoc.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/pydoc.py Sun Jan 20 11:45:31 2008 @@ -1946,9 +1946,9 @@ def send_document(self, title, contents): try: self.send_response(200) - self.send_header('Content-Type', 'text/html') + self.send_header('Content-Type', 'text/html; charset=UTF-8') self.end_headers() - self.wfile.write(html.page(title, contents)) + self.wfile.write(html.page(title, contents).encode('utf-8')) except IOError: pass def do_GET(self): @@ -1974,7 +1974,7 @@ return '%s' % (name, name) names = filter(lambda x: x != '__main__', sys.builtin_module_names) - contents = html.multicolumn(names, bltinlink) + contents = html.multicolumn(list(names), bltinlink) indices = ['

' + html.bigsection( 'Built-in Modules', '#ffffff', '#ee77aa', contents)] Modified: python/branches/py3k-ctypes-pep3118/Lib/rational.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/rational.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/rational.py Sun Jan 20 11:45:31 2008 @@ -6,6 +6,7 @@ import math import numbers import operator +import re __all__ = ["Rational"] @@ -75,6 +76,10 @@ return (top, 2 ** -e) +_RATIONAL_FORMAT = re.compile( + r'^\s*(?P[-+]?)(?P\d+)(?:/(?P\d+))?\s*$') + + class Rational(RationalAbc): """This class implements rational numbers. @@ -83,18 +88,41 @@ and the denominator defaults to 1 so that Rational(3) == 3 and Rational() == 0. + Rationals can also be constructed from strings of the form + '[-+]?[0-9]+(/[0-9]+)?', optionally surrounded by spaces. + """ __slots__ = ('_numerator', '_denominator') - def __init__(self, numerator=0, denominator=1): - if (not isinstance(numerator, numbers.Integral) and - isinstance(numerator, RationalAbc) and - denominator == 1): - # Handle copies from other rationals. - other_rational = numerator - numerator = other_rational.numerator - denominator = other_rational.denominator + # We're immutable, so use __new__ not __init__ + def __new__(cls, numerator=0, denominator=1): + """Constructs a Rational. + + Takes a string, another Rational, or a numerator/denominator pair. + + """ + self = super(Rational, cls).__new__(cls) + + if denominator == 1: + if isinstance(numerator, str): + # Handle construction from strings. + input = numerator + m = _RATIONAL_FORMAT.match(input) + if m is None: + raise ValueError('Invalid literal for Rational: ' + input) + numerator = int(m.group('num')) + # Default denominator to 1. That's the only optional group. + denominator = int(m.group('denom') or 1) + if m.group('sign') == '-': + numerator = -numerator + + elif (not isinstance(numerator, numbers.Integral) and + isinstance(numerator, RationalAbc)): + # Handle copies from other rationals. + other_rational = numerator + numerator = other_rational.numerator + denominator = other_rational.denominator if (not isinstance(numerator, numbers.Integral) or not isinstance(denominator, numbers.Integral)): @@ -107,10 +135,15 @@ g = _gcd(numerator, denominator) self._numerator = int(numerator // g) self._denominator = int(denominator // g) + return self @classmethod def from_float(cls, f): - """Converts a float to a rational number, exactly.""" + """Converts a finite float to a rational number, exactly. + + Beware that Rational.from_float(0.3) != Rational(3, 10). + + """ if not isinstance(f, float): raise TypeError("%s.from_float() only takes floats, not %r (%s)" % (cls.__name__, f, type(f).__name__)) @@ -118,6 +151,26 @@ raise TypeError("Cannot convert %r to %s." % (f, cls.__name__)) return cls(*_binary_float_to_ratio(f)) + @classmethod + def from_decimal(cls, dec): + """Converts a finite Decimal instance to a rational number, exactly.""" + from decimal import Decimal + if not isinstance(dec, Decimal): + raise TypeError( + "%s.from_decimal() only takes Decimals, not %r (%s)" % + (cls.__name__, dec, type(dec).__name__)) + if not dec.is_finite(): + # Catches infinities and nans. + raise TypeError("Cannot convert %s to %s." % (dec, cls.__name__)) + sign, digits, exp = dec.as_tuple() + digits = int(''.join(map(str, digits))) + if sign: + digits = -digits + if exp >= 0: + return cls(digits * 10 ** exp) + else: + return cls(digits, 10 ** -exp) + @property def numerator(a): return a._numerator @@ -128,15 +181,14 @@ def __repr__(self): """repr(self)""" - return ('rational.Rational(%r,%r)' % - (self.numerator, self.denominator)) + return ('Rational(%r,%r)' % (self.numerator, self.denominator)) def __str__(self): """str(self)""" if self.denominator == 1: return str(self.numerator) else: - return '(%s/%s)' % (self.numerator, self.denominator) + return '%s/%s' % (self.numerator, self.denominator) def _operator_fallbacks(monomorphic_operator, fallback_operator): """Generates forward and reverse operators given a purely-rational Modified: python/branches/py3k-ctypes-pep3118/Lib/subprocess.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/subprocess.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/subprocess.py Sun Jan 20 11:45:31 2008 @@ -289,6 +289,7 @@ import io import os import traceback +import gc # Exception classes used by this module. class CalledProcessError(Exception): @@ -397,8 +398,8 @@ 2) A string surrounded by double quotation marks is interpreted as a single argument, regardless of white space - contained within. A quoted string can be embedded in an - argument. + or pipe characters contained within. A quoted string can be + embedded in an argument. 3) A double quotation mark preceded by a backslash is interpreted as a literal double quotation mark. @@ -424,7 +425,7 @@ if result: result.append(' ') - needquote = (" " in arg) or ("\t" in arg) or arg == "" + needquote = (" " in arg) or ("\t" in arg) or ("|" in arg) or not arg if needquote: result.append('"') @@ -433,7 +434,7 @@ # Don't know if we need to double yet. bs_buf.append(c) elif c == '"': - # Double backspaces. + # Double backslashes. result.append('\\' * len(bs_buf)*2) bs_buf = [] result.append('\\"') @@ -444,7 +445,7 @@ bs_buf = [] result.append(c) - # Add remaining backspaces, if any. + # Add remaining backslashes, if any. if bs_buf: result.extend(bs_buf) @@ -887,13 +888,8 @@ def _close_fds(self, but): - for i in range(3, MAXFD): - if i == but: - continue - try: - os.close(i) - except: - pass + os.closerange(3, but) + os.closerange(but + 1, MAXFD) def _execute_child(self, args, executable, preexec_fn, close_fds, @@ -921,7 +917,16 @@ errpipe_read, errpipe_write = os.pipe() self._set_cloexec_flag(errpipe_write) - self.pid = os.fork() + gc_was_enabled = gc.isenabled() + # Disable gc to avoid bug where gc -> file_dealloc -> + # write to stderr -> hang. http://bugs.python.org/issue1336 + gc.disable() + try: + self.pid = os.fork() + except: + if gc_was_enabled: + gc.enable() + raise self._child_created = True if self.pid == 0: # Child @@ -982,6 +987,8 @@ os._exit(255) # Parent + if gc_was_enabled: + gc.enable() os.close(errpipe_write) if p2cread is not None and p2cwrite is not None: os.close(p2cread) Deleted: /python/branches/py3k-ctypes-pep3118/Lib/test/crashers/weakref_in_del.py ============================================================================== --- /python/branches/py3k-ctypes-pep3118/Lib/test/crashers/weakref_in_del.py Sun Jan 20 11:45:31 2008 +++ (empty file) @@ -1,17 +0,0 @@ -import weakref - -# http://python.org/sf/1377858 -# Fixed for new-style classes in 2.5c1. - -ref = None - -def test_weakref_in_del(): - class Target(): - def __del__(self): - global ref - ref = weakref.ref(self) - - w = Target() - -if __name__ == '__main__': - test_weakref_in_del() Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_builtin.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_builtin.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_builtin.py Sun Jan 20 11:45:31 2008 @@ -49,7 +49,7 @@ def write(self, line): pass -L = [ +test_conv_no_sign = [ ('0', 0), ('1', 1), ('9', 9), @@ -71,6 +71,28 @@ (chr(0x200), ValueError), ] +test_conv_sign = [ + ('0', 0), + ('1', 1), + ('9', 9), + ('10', 10), + ('99', 99), + ('100', 100), + ('314', 314), + (' 314', ValueError), + ('314 ', 314), + (' \t\t 314 \t\t ', ValueError), + (repr(sys.maxsize), sys.maxsize), + (' 1x', ValueError), + (' 1 ', ValueError), + (' 1\02 ', ValueError), + ('', ValueError), + (' ', ValueError), + (' \t\t ', ValueError), + (str(b'\u0663\u0661\u0664 ','raw-unicode-escape'), 314), + (chr(0x200), ValueError), +] + class TestFailingBool: def __bool__(self): raise RuntimeError @@ -641,8 +663,18 @@ # Different base: self.assertEqual(int("10",16), 16) # Test conversion from strings and various anomalies - for s, v in L: - for sign in "", "+", "-": + # Testing with no sign at front + for s, v in test_conv_no_sign: + for prefix in "", " ", "\t", " \t\t ": + ss = prefix + s + vv = v + try: + self.assertEqual(int(ss), vv) + except v: + pass + # No whitespaces allowed between + or - sign and the number + for s, v in test_conv_sign: + for sign in "+", "-": for prefix in "", " ", "\t", " \t\t ": ss = prefix + sign + s vv = v @@ -711,6 +743,11 @@ self.assertEqual(int('0O123', 8), 83) self.assertEqual(int('0B100', 2), 4) + # Bug 1679: "0x" is not a valid hex literal + self.assertRaises(ValueError, int, "0x", 16) + self.assertRaises(ValueError, int, "0x", 0) + + # SF bug 1334662: int(string, base) wrong answers # Various representations of 2**32 evaluated to 0 # rather than 2**32 in previous versions Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_grammar.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_grammar.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_grammar.py Sun Jan 20 11:45:31 2008 @@ -32,6 +32,8 @@ self.assertEquals(0o377, 255) self.assertEquals(2147483647, 0o17777777777) self.assertEquals(0b1001, 9) + # "0x" is not a valid literal + self.assertRaises(SyntaxError, eval, "0x") from sys import maxsize if maxsize == 2147483647: self.assertEquals(-2147483647-1, -0o20000000000) Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_mailbox.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_mailbox.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_mailbox.py Sun Jan 20 11:45:31 2008 @@ -506,6 +506,20 @@ self.assertEqual(msg_returned.get_flags(), 'S') self.assertEqual(msg_returned.get_payload(), '3') + def test_consistent_factory(self): + # Add a message. + msg = mailbox.MaildirMessage(self._template % 0) + msg.set_subdir('cur') + msg.set_flags('RF') + key = self._box.add(msg) + + # Create new mailbox with + class FakeMessage(mailbox.MaildirMessage): + pass + box = mailbox.Maildir(self._path, factory=FakeMessage) + msg2 = box.get_message(key) + self.assert_(isinstance(msg2, FakeMessage)) + def test_initialize_new(self): # Initialize a non-existent mailbox self.tearDown() Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_mmap.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_mmap.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_mmap.py Sun Jan 20 11:45:31 2008 @@ -252,6 +252,42 @@ self.assertEqual(m.find(slice + b'x'), -1) m.close() + def test_find_end(self): + # test the new 'end' parameter works as expected + f = open(TESTFN, 'w+') + data = 'one two ones' + n = len(data) + f.write(data) + f.flush() + m = mmap.mmap(f.fileno(), n) + f.close() + + self.assertEqual(m.find('one'), 0) + self.assertEqual(m.find('ones'), 8) + self.assertEqual(m.find('one', 0, -1), 0) + self.assertEqual(m.find('one', 1), 8) + self.assertEqual(m.find('one', 1, -1), 8) + self.assertEqual(m.find('one', 1, -2), -1) + + + def test_rfind(self): + # test the new 'end' parameter works as expected + f = open(TESTFN, 'w+') + data = 'one two ones' + n = len(data) + f.write(data) + f.flush() + m = mmap.mmap(f.fileno(), n) + f.close() + + self.assertEqual(m.rfind('one'), 8) + self.assertEqual(m.rfind('one '), 0) + self.assertEqual(m.rfind('one', 0, -1), 8) + self.assertEqual(m.rfind('one', 0, -2), 0) + self.assertEqual(m.rfind('one', 1, -1), 8) + self.assertEqual(m.rfind('one', 1, -2), -1) + + def test_double_close(self): # make sure a double close doesn't crash on Solaris (Bug# 665913) f = open(TESTFN, 'wb+') Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_os.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_os.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_os.py Sun Jan 20 11:45:31 2008 @@ -20,6 +20,11 @@ os.close(f) self.assert_(os.access(test_support.TESTFN, os.W_OK)) + def test_closerange(self): + f = os.open(test_support.TESTFN, os.O_CREAT|os.O_RDWR) + # close a fd that is open, and one that isn't + os.closerange(f, f+2) + self.assertRaises(OSError, os.write, f, "a") # Test attributes on return values from os.*stat* family. class StatAttributeTests(unittest.TestCase): Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_rational.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_rational.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_rational.py Sun Jan 20 11:45:31 2008 @@ -45,6 +45,44 @@ self.assertRaises(TypeError, R, 1.5) self.assertRaises(TypeError, R, 1.5 + 3j) + self.assertRaises(TypeError, R, R(1, 2), 3) + self.assertRaises(TypeError, R, "3/2", 3) + + def testFromString(self): + self.assertEquals((5, 1), _components(R("5"))) + self.assertEquals((3, 2), _components(R("3/2"))) + self.assertEquals((3, 2), _components(R(" \n +3/2"))) + self.assertEquals((-3, 2), _components(R("-3/2 "))) + self.assertEquals((3, 2), _components(R(" 03/02 \n "))) + self.assertEquals((3, 2), _components(R(" 03/02 \n "))) + + self.assertRaisesMessage( + ZeroDivisionError, "Rational(3, 0)", + R, "3/0") + self.assertRaisesMessage( + ValueError, "Invalid literal for Rational: 3/", + R, "3/") + self.assertRaisesMessage( + ValueError, "Invalid literal for Rational: 3 /2", + R, "3 /2") + self.assertRaisesMessage( + # Denominators don't need a sign. + ValueError, "Invalid literal for Rational: 3/+2", + R, "3/+2") + self.assertRaisesMessage( + # Imitate float's parsing. + ValueError, "Invalid literal for Rational: + 3/2", + R, "+ 3/2") + self.assertRaisesMessage( + # Only parse fractions, not decimals. + ValueError, "Invalid literal for Rational: 3.2", + R, "3.2") + + def testImmutable(self): + r = R(7, 3) + r.__init__(2, 15) + self.assertEquals((7, 3), _components(r)) + def testFromFloat(self): self.assertRaisesMessage( TypeError, "Rational.from_float() only takes floats, not 3 (int)", @@ -72,6 +110,31 @@ TypeError, "Cannot convert nan to Rational.", R.from_float, nan) + def testFromDecimal(self): + self.assertRaisesMessage( + TypeError, + "Rational.from_decimal() only takes Decimals, not 3 (int)", + R.from_decimal, 3) + self.assertEquals(R(0), R.from_decimal(Decimal("-0"))) + self.assertEquals(R(5, 10), R.from_decimal(Decimal("0.5"))) + self.assertEquals(R(5, 1000), R.from_decimal(Decimal("5e-3"))) + self.assertEquals(R(5000), R.from_decimal(Decimal("5e3"))) + self.assertEquals(1 - R(1, 10**30), + R.from_decimal(Decimal("0." + "9" * 30))) + + self.assertRaisesMessage( + TypeError, "Cannot convert Infinity to Rational.", + R.from_decimal, Decimal("inf")) + self.assertRaisesMessage( + TypeError, "Cannot convert -Infinity to Rational.", + R.from_decimal, Decimal("-inf")) + self.assertRaisesMessage( + TypeError, "Cannot convert NaN to Rational.", + R.from_decimal, Decimal("nan")) + self.assertRaisesMessage( + TypeError, "Cannot convert sNaN to Rational.", + R.from_decimal, Decimal("snan")) + def testConversions(self): self.assertTypedEquals(-1, trunc(R(-11, 10))) self.assertTypedEquals(-2, math.floor(R(-11, 10))) @@ -175,7 +238,7 @@ self.assertTypedEquals(1.0 + 0j, (1.0 + 0j) ** R(1, 10)) def testMixingWithDecimal(self): - """Decimal refuses mixed comparisons.""" + # Decimal refuses mixed comparisons. self.assertRaisesMessage( TypeError, "unsupported operand type(s) for +: 'Rational' and 'Decimal'", @@ -238,8 +301,8 @@ self.assertFalse(R(5, 2) == 2) def testStringification(self): - self.assertEquals("rational.Rational(7,3)", repr(R(7, 3))) - self.assertEquals("(7/3)", str(R(7, 3))) + self.assertEquals("Rational(7,3)", repr(R(7, 3))) + self.assertEquals("7/3", str(R(7, 3))) self.assertEquals("7", str(R(7, 1))) def testHash(self): Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_socket.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_socket.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_socket.py Sun Jan 20 11:45:31 2008 @@ -288,7 +288,6 @@ def testRefCountGetNameInfo(self): # Testing reference count for getnameinfo - import sys if hasattr(sys, "getrefcount"): try: # On some versions, this loses a reference Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_ssl.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_ssl.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_ssl.py Sun Jan 20 11:45:31 2008 @@ -38,6 +38,27 @@ class BasicTests(unittest.TestCase): + def testSSLconnect(self): + if not test_support.is_resource_enabled('network'): + return + s = ssl.wrap_socket(socket.socket(socket.AF_INET), + cert_reqs=ssl.CERT_NONE) + s.connect(("svn.python.org", 443)) + c = s.getpeercert() + if c: + raise test_support.TestFailed("Peer cert %s shouldn't be here!") + s.close() + + # this should fail because we have no verification certs + s = ssl.wrap_socket(socket.socket(socket.AF_INET), + cert_reqs=ssl.CERT_REQUIRED) + try: + s.connect(("svn.python.org", 443)) + except ssl.SSLError: + pass + finally: + s.close() + def testCrucialConstants(self): ssl.PROTOCOL_SSLv2 ssl.PROTOCOL_SSLv23 @@ -81,7 +102,6 @@ class NetworkedTests(unittest.TestCase): def testConnect(self): - s = ssl.wrap_socket(socket.socket(socket.AF_INET), cert_reqs=ssl.CERT_NONE) s.connect(("svn.python.org", 443)) Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_subprocess.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_subprocess.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_subprocess.py Sun Jan 20 11:45:31 2008 @@ -413,6 +413,8 @@ '"a b c" d e') self.assertEqual(subprocess.list2cmdline(['ab"c', '\\', 'd']), 'ab\\"c \\ d') + self.assertEqual(subprocess.list2cmdline(['ab"c', ' \\', 'd']), + 'ab\\"c " \\\\" d') self.assertEqual(subprocess.list2cmdline(['a\\\\\\b', 'de fg', 'h']), 'a\\\\\\b "de fg" h') self.assertEqual(subprocess.list2cmdline(['a\\"b', 'c', 'd']), @@ -423,6 +425,8 @@ '"a\\\\b\\ c" d e') self.assertEqual(subprocess.list2cmdline(['ab', '']), 'ab ""') + self.assertEqual(subprocess.list2cmdline(['echo', 'foo|bar']), + 'echo "foo|bar"') def test_poll(self): Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_textwrap.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_textwrap.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_textwrap.py Sun Jan 20 11:45:31 2008 @@ -385,6 +385,19 @@ ' o'], subsequent_indent = ' '*15) + # bug 1146. Prevent a long word to be wrongly wrapped when the + # preceding word is exactly one character shorter than the width + self.check_wrap(self.text, 12, + ['Did you say ', + '"supercalifr', + 'agilisticexp', + 'ialidocious?', + '" How *do*', + 'you spell', + 'that odd', + 'word,', + 'anyways?']) + def test_nobreak_long(self): # Test with break_long_words disabled self.wrapper.break_long_words = 0 Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_threading_local.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_threading_local.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_threading_local.py Sun Jan 20 11:45:31 2008 @@ -1,9 +1,51 @@ import unittest from doctest import DocTestSuite from test import test_support +import threading +import weakref +import gc + +class Weak(object): + pass + +def target(local, weaklist): + weak = Weak() + local.weak = weak + weaklist.append(weakref.ref(weak)) + +class ThreadingLocalTest(unittest.TestCase): + + def test_local_refs(self): + self._local_refs(20) + self._local_refs(50) + self._local_refs(100) + + def _local_refs(self, n): + local = threading.local() + weaklist = [] + for i in range(n): + t = threading.Thread(target=target, args=(local, weaklist)) + t.start() + t.join() + del t + + gc.collect() + self.assertEqual(len(weaklist), n) + + # XXX threading.local keeps the local of the last stopped thread alive. + deadlist = [weak for weak in weaklist if weak() is None] + self.assertEqual(len(deadlist), n-1) + + # Assignment to the same thread local frees it sometimes (!) + local.someothervar = None + gc.collect() + deadlist = [weak for weak in weaklist if weak() is None] + self.assert_(len(deadlist) in (n-1, n), (n, len(deadlist))) def test_main(): - suite = DocTestSuite('_threading_local') + suite = unittest.TestSuite() + suite.addTest(DocTestSuite('_threading_local')) + suite.addTest(unittest.makeSuite(ThreadingLocalTest)) try: from thread import _local Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_xmlrpc.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_xmlrpc.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_xmlrpc.py Sun Jan 20 11:45:31 2008 @@ -347,7 +347,8 @@ # protocol error; provide additional information in test output self.fail("%s\n%s" % (e, e.headers)) - def test_404(self): + # [ch] The test 404 is causing lots of false alarms. + def XXXtest_404(self): # send POST with httplib, it should return 404 header and # 'Not Found' message. conn = httplib.HTTPConnection('localhost', PORT) Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_zipfile.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_zipfile.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_zipfile.py Sun Jan 20 11:45:31 2008 @@ -686,31 +686,52 @@ b'\x1a\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x01\x00 \x00\xb6\x81' b'\x00\x00\x00\x00test.txtPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x006\x00' b'\x00\x00L\x00\x00\x00\x00\x00' ) + data2 = ( + b'PK\x03\x04\x14\x00\t\x00\x08\x00\xcf}38xu\xaa\xb2\x14\x00\x00\x00\x00\x02' + b'\x00\x00\x04\x00\x15\x00zeroUT\t\x00\x03\xd6\x8b\x92G\xda\x8b\x92GUx\x04' + b'\x00\xe8\x03\xe8\x03\xc7 Ignore the given module and its submodules - (if it is a package). +--ignore-module= Ignore the given module(s) and its submodules + (if it is a package). Accepts comma separated + list of module names --ignore-dir=

Ignore files in the given directory (multiple directories can be joined by os.pathsep). """ % sys.argv[0]) @@ -725,7 +726,8 @@ continue if opt == "--ignore-module": - ignore_modules.append(val) + for mod in val.split(","): + ignore_modules.append(mod.strip()) continue if opt == "--ignore-dir": Modified: python/branches/py3k-ctypes-pep3118/Lib/zipfile.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/zipfile.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/zipfile.py Sun Jan 20 11:45:31 2008 @@ -34,9 +34,9 @@ # Other ZIP compression methods not supported # Here are some struct module formats for reading headers -structEndArchive = "<4s4H2lH" # 9 items, end of archive, 22 bytes +structEndArchive = "<4s4H2LH" # 9 items, end of archive, 22 bytes stringEndArchive = b"PK\005\006" # magic number for end of archive record -structCentralDir = "<4s4B4HlLL5HLl"# 19 items, central directory, 46 bytes +structCentralDir = "<4s4B4HlLL5HLL"# 19 items, central directory, 46 bytes stringCentralDir = b"PK\001\002" # magic number for central directory structFileHeader = "<4s2B4HlLL2H" # 12 items, file header record, 30 bytes stringFileHeader = b"PK\003\004" # magic number for file header @@ -188,6 +188,7 @@ 'CRC', 'compress_size', 'file_size', + '_raw_time', ) def __init__(self, filename="NoName", date_time=(1980,1,1,0,0,0)): @@ -303,7 +304,7 @@ ZIP supports a password-based form of encryption. Even though known plaintext attacks have been found against it, it is still useful - for low-level securicy. + to be able to get data out of such a file. Usage: zd = _ZipDecrypter(mypwd) @@ -690,6 +691,7 @@ x.CRC, x.compress_size, x.file_size) = centdir[1:12] x.volume, x.internal_attr, x.external_attr = centdir[15:18] # Convert date/time code to (year, month, day, hour, min, sec) + x._raw_time = t x.date_time = ( (d>>9)+1980, (d>>5)&0xF, d&0x1F, t>>11, (t>>5)&0x3F, (t&0x1F) * 2 ) @@ -800,11 +802,18 @@ # The first 12 bytes in the cypher stream is an encryption header # used to strengthen the algorithm. The first 11 bytes are # completely random, while the 12th contains the MSB of the CRC, + # or the MSB of the file time depending on the header type # and is used to check the correctness of the password. bytes = zef_file.read(12) h = list(map(zd, bytes[0:12])) - if h[11] != ((zinfo.CRC>>24) & 255): - raise RuntimeError("Bad password for file %s" % name) + if zinfo.flag_bits & 0x8: + # compare against the file type from extended local headers + check_byte = (zinfo._raw_time >> 8) & 0xff + else: + # compare against the CRC otherwise + check_byte = (zinfo.CRC >> 24) & 0xff + if h[11] != check_byte: + raise RuntimeError("Bad password for file", name) # build and return a ZipExtFile if zd is None: Modified: python/branches/py3k-ctypes-pep3118/Misc/ACKS ============================================================================== --- python/branches/py3k-ctypes-pep3118/Misc/ACKS (original) +++ python/branches/py3k-ctypes-pep3118/Misc/ACKS Sun Jan 20 11:45:31 2008 @@ -109,8 +109,6 @@ Brett Cannon Mike Carlton Terry Carroll -Brian Leair -Luke Kenneth Casson Leighton Donn Cave Per Cederqvist Octavian Cerna @@ -390,6 +388,7 @@ Ben Laurie Simon Law Chris Lawrence +Brian Leair Christopher Lee Inyeol Lee John J. Lee @@ -397,7 +396,9 @@ Luc Lefebvre Kip Lehman Joerg Lehmann +Luke Kenneth Casson Leighton Marc-Andre Lemburg +John Lenton Mark Levinson William Lewis Robert van Liere @@ -524,6 +525,7 @@ Fran?ois Pinard Zach Pincus Michael Piotrowski +Michael Pomraning Iustin Pop John Popplewell Amrit Prem @@ -591,6 +593,7 @@ Sam Schulenburg Stefan Schwarzer Dietmar Schwertberger +Federico Schwindt Barry Scott Steven Scott Nick Seidenman @@ -699,6 +702,7 @@ Aaron Watters Henrik Weber Corran Webster +Stefan Wehr Zack Weinberg Edward Welbourne Cliff Wells Modified: python/branches/py3k-ctypes-pep3118/Misc/NEWS ============================================================================== --- python/branches/py3k-ctypes-pep3118/Misc/NEWS (original) +++ python/branches/py3k-ctypes-pep3118/Misc/NEWS Sun Jan 20 11:45:31 2008 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #1769: Now int("- 1") is not allowed any more. + - Object/longobject.c: long(float('nan')) raises an OverflowError instead of returning 0. Modified: python/branches/py3k-ctypes-pep3118/Modules/_sqlite/cursor.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_sqlite/cursor.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_sqlite/cursor.c Sun Jan 20 11:45:31 2008 @@ -973,11 +973,11 @@ {"executescript", (PyCFunction)pysqlite_cursor_executescript, METH_VARARGS, PyDoc_STR("Executes a multiple SQL statements at once. Non-standard.")}, {"fetchone", (PyCFunction)pysqlite_cursor_fetchone, METH_NOARGS, - PyDoc_STR("Fetches several rows from the resultset.")}, + PyDoc_STR("Fetches one row from the resultset.")}, {"fetchmany", (PyCFunction)pysqlite_cursor_fetchmany, METH_VARARGS, - PyDoc_STR("Fetches all rows from the resultset.")}, + PyDoc_STR("Fetches several rows from the resultset.")}, {"fetchall", (PyCFunction)pysqlite_cursor_fetchall, METH_NOARGS, - PyDoc_STR("Fetches one row from the resultset.")}, + PyDoc_STR("Fetches all rows from the resultset.")}, {"close", (PyCFunction)pysqlite_cursor_close, METH_NOARGS, PyDoc_STR("Closes the cursor.")}, {"setinputsizes", (PyCFunction)pysqlite_noop, METH_VARARGS, Modified: python/branches/py3k-ctypes-pep3118/Modules/_sre.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_sre.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_sre.c Sun Jan 20 11:45:31 2008 @@ -2677,7 +2677,7 @@ return NULL; n = PyList_GET_SIZE(code); - + /* coverity[ampersand_in_size] */ self = PyObject_NEW_VAR(PatternObject, &Pattern_Type, n); if (!self) return NULL; @@ -3187,6 +3187,7 @@ if (status > 0) { /* create match object (with room for extra group marks) */ + /* coverity[ampersand_in_size] */ match = PyObject_NEW_VAR(MatchObject, &Match_Type, 2*(pattern->groups+1)); if (!match) Modified: python/branches/py3k-ctypes-pep3118/Modules/mmapmodule.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/mmapmodule.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/mmapmodule.c Sun Jan 20 11:45:31 2008 @@ -254,19 +254,22 @@ } static PyObject * -mmap_find_method(mmap_object *self, - PyObject *args) +mmap_gfind(mmap_object *self, + PyObject *args, + int reverse) { Py_ssize_t start = self->pos; + Py_ssize_t end = self->size; char *needle; Py_ssize_t len; CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, "s#|n:find", &needle, &len, &start)) { + if (!PyArg_ParseTuple(args, reverse ? "s#|nn:rfind" : "s#|nn:find", + &needle, &len, &start, &end)) { return NULL; } else { char *p; - char *e = self->data + self->size; + char sign = reverse ? -1 : 1; if (start < 0) start += self->size; @@ -275,7 +278,18 @@ else if ((size_t)start > self->size) start = self->size; - for (p = self->data + start; p + len <= e; ++p) { + if (end < 0) + end += self->size; + if (end < 0) + end = 0; + else if ((size_t)end > self->size) + end = self->size; + + start += (Py_ssize_t)self->data; + end += (Py_ssize_t)self->data; + + for (p = (char *)(reverse ? end - len : start); + p >= (char *)start && p + len <= (char *)end; p+=sign) { Py_ssize_t i; for (i = 0; i < len && needle[i] == p[i]; ++i) /* nothing */; @@ -287,6 +301,20 @@ } } +static PyObject * +mmap_find_method(mmap_object *self, + PyObject *args) +{ + return mmap_gfind(self, args, 0); +} + +static PyObject * +mmap_rfind_method(mmap_object *self, + PyObject *args) +{ + return mmap_gfind(self, args, 1); +} + static int is_writable(mmap_object *self) { @@ -604,6 +632,7 @@ static struct PyMethodDef mmap_object_methods[] = { {"close", (PyCFunction) mmap_close_method, METH_NOARGS}, {"find", (PyCFunction) mmap_find_method, METH_VARARGS}, + {"rfind", (PyCFunction) mmap_rfind_method, METH_VARARGS}, {"flush", (PyCFunction) mmap_flush_method, METH_VARARGS}, {"move", (PyCFunction) mmap_move_method, METH_VARARGS}, {"read", (PyCFunction) mmap_read_method, METH_VARARGS}, Modified: python/branches/py3k-ctypes-pep3118/Modules/posixmodule.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/posixmodule.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/posixmodule.c Sun Jan 20 11:45:31 2008 @@ -4716,6 +4716,24 @@ } +PyDoc_STRVAR(posix_closerange__doc__, +"closerange(fd_low, fd_high)\n\n\ +Closes all file descriptors in [fd_low, fd_high), ignoring errors."); + +static PyObject * +posix_closerange(PyObject *self, PyObject *args) +{ + int fd_from, fd_to, i; + if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to)) + return NULL; + Py_BEGIN_ALLOW_THREADS + for (i = fd_from; i < fd_to; i++) + close(i); + Py_END_ALLOW_THREADS + Py_RETURN_NONE; +} + + PyDoc_STRVAR(posix_dup__doc__, "dup(fd) -> fd2\n\n\ Return a duplicate of a file descriptor."); @@ -6919,6 +6937,7 @@ #endif /* HAVE_TCSETPGRP */ {"open", posix_open, METH_VARARGS, posix_open__doc__}, {"close", posix_close, METH_VARARGS, posix_close__doc__}, + {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__}, {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__}, {"dup", posix_dup, METH_VARARGS, posix_dup__doc__}, {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__}, Modified: python/branches/py3k-ctypes-pep3118/Modules/socketmodule.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/socketmodule.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/socketmodule.c Sun Jan 20 11:45:31 2008 @@ -1904,15 +1904,22 @@ #else if (s->sock_timeout > 0.0) { - if (res < 0 && errno == EINPROGRESS && IS_SELECTABLE(s)) { - timeout = internal_select(s, 1); - if (timeout == 0) { - res = connect(s->sock_fd, addr, addrlen); - if (res < 0 && errno == EISCONN) - res = 0; - } - else if (timeout == -1) - res = errno; /* had error */ + if (res < 0 && errno == EINPROGRESS && IS_SELECTABLE(s)) { + timeout = internal_select(s, 1); + if (timeout == 0) { + /* Bug #1019808: in case of an EINPROGRESS, + use getsockopt(SO_ERROR) to get the real + error. */ + socklen_t res_size = sizeof res; + (void)getsockopt(s->sock_fd, SOL_SOCKET, + SO_ERROR, &res, &res_size); + if (res == EISCONN) + res = 0; + errno = res; + } + else if (timeout == -1) { + res = errno; /* had error */ + } else res = EWOULDBLOCK; /* timed out */ } Modified: python/branches/py3k-ctypes-pep3118/Objects/complexobject.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Objects/complexobject.c (original) +++ python/branches/py3k-ctypes-pep3118/Objects/complexobject.c Sun Jan 20 11:45:31 2008 @@ -375,24 +375,24 @@ static int to_complex(PyObject **pobj, Py_complex *pc) { - PyObject *obj = *pobj; + PyObject *obj = *pobj; - pc->real = pc->imag = 0.0; - if (PyLong_Check(obj)) { - pc->real = PyLong_AsDouble(obj); - if (pc->real == -1.0 && PyErr_Occurred()) { - *pobj = NULL; - return -1; - } - return 0; - } - if (PyFloat_Check(obj)) { - pc->real = PyFloat_AsDouble(obj); - return 0; - } - Py_INCREF(Py_NotImplemented); - *pobj = Py_NotImplemented; - return -1; + pc->real = pc->imag = 0.0; + if (PyLong_Check(obj)) { + pc->real = PyLong_AsDouble(obj); + if (pc->real == -1.0 && PyErr_Occurred()) { + *pobj = NULL; + return -1; + } + return 0; + } + if (PyFloat_Check(obj)) { + pc->real = PyFloat_AsDouble(obj); + return 0; + } + Py_INCREF(Py_NotImplemented); + *pobj = Py_NotImplemented; + return -1; } @@ -401,8 +401,8 @@ { Py_complex result; Py_complex a, b; - TO_COMPLEX(v, a); - TO_COMPLEX(w, b); + TO_COMPLEX(v, a); + TO_COMPLEX(w, b); PyFPE_START_PROTECT("complex_add", return 0) result = c_sum(a, b); PyFPE_END_PROTECT(result) @@ -414,8 +414,8 @@ { Py_complex result; Py_complex a, b; - TO_COMPLEX(v, a); - TO_COMPLEX(w, b); + TO_COMPLEX(v, a); + TO_COMPLEX(w, b); PyFPE_START_PROTECT("complex_sub", return 0) result = c_diff(a, b); PyFPE_END_PROTECT(result) @@ -427,8 +427,8 @@ { Py_complex result; Py_complex a, b; - TO_COMPLEX(v, a); - TO_COMPLEX(w, b); + TO_COMPLEX(v, a); + TO_COMPLEX(w, b); PyFPE_START_PROTECT("complex_mul", return 0) result = c_prod(a, b); PyFPE_END_PROTECT(result) @@ -440,8 +440,8 @@ { Py_complex quot; Py_complex a, b; - TO_COMPLEX(v, a); - TO_COMPLEX(w, b); + TO_COMPLEX(v, a); + TO_COMPLEX(w, b); PyFPE_START_PROTECT("complex_div", return 0) errno = 0; quot = c_quot(a, b); @@ -477,8 +477,8 @@ Py_complex exponent; long int_exponent; Py_complex a, b; - TO_COMPLEX(v, a); - TO_COMPLEX(w, b); + TO_COMPLEX(v, a); + TO_COMPLEX(w, b); if (z != Py_None) { PyErr_SetString(PyExc_ValueError, "complex modulo"); @@ -557,8 +557,8 @@ { PyObject *res; Py_complex i, j; - TO_COMPLEX(v, i); - TO_COMPLEX(w, j); + TO_COMPLEX(v, i); + TO_COMPLEX(w, j); if (op != Py_EQ && op != Py_NE) { /* XXX Should eventually return NotImplemented */ @@ -673,11 +673,11 @@ start = s; while (*s && isspace(Py_CHARMASK(*s))) s++; - if (s[0] == '\0') { + if (s[0] == '\0') { PyErr_SetString(PyExc_ValueError, "complex() arg is an empty string"); return NULL; - } + } if (s[0] == '(') { /* Skip over possible bracket from repr(). */ got_bracket = 1; @@ -837,7 +837,7 @@ "complex() can't take second arg" " if first is a string"); return NULL; - } + } return complex_subtype_from_string(type, r); } if (i != NULL && PyUnicode_Check(i)) { @@ -915,7 +915,7 @@ return NULL; } cr.real = PyFloat_AsDouble(tmp); - cr.imag = 0.0; /* Shut up compiler warning */ + cr.imag = 0.0; /* Shut up compiler warning */ Py_DECREF(tmp); } if (i == NULL) { Modified: python/branches/py3k-ctypes-pep3118/Objects/longobject.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Objects/longobject.c (original) +++ python/branches/py3k-ctypes-pep3118/Objects/longobject.c Sun Jan 20 11:45:31 2008 @@ -1685,8 +1685,6 @@ ++str; sign = -1; } - while (*str != '\0' && isspace(Py_CHARMASK(*str))) - str++; if (base == 0) { if (str[0] != '0') base = 10; Modified: python/branches/py3k-ctypes-pep3118/Parser/tokenizer.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Parser/tokenizer.c (original) +++ python/branches/py3k-ctypes-pep3118/Parser/tokenizer.c Sun Jan 20 11:45:31 2008 @@ -1352,19 +1352,38 @@ goto imaginary; #endif if (c == 'x' || c == 'X') { + /* Hex */ + c = tok_nextc(tok); + if (!isxdigit(c)) { + tok->done = E_TOKEN; + tok_backup(tok, c); + return ERRORTOKEN; + } do { c = tok_nextc(tok); } while (isxdigit(c)); } else if (c == 'o' || c == 'O') { /* Octal */ + c = tok_nextc(tok); + if (c < '0' || c > '8') { + tok->done = E_TOKEN; + tok_backup(tok, c); + return ERRORTOKEN; + } do { c = tok_nextc(tok); } while ('0' <= c && c < '8'); } else if (c == 'b' || c == 'B') { /* Binary */ + c = tok_nextc(tok); + if (c != '0' && c != '1') { + tok->done = E_TOKEN; + tok_backup(tok, c); + return ERRORTOKEN; + } do { c = tok_nextc(tok); } while (c == '0' || c == '1'); Modified: python/branches/py3k-ctypes-pep3118/Python/modsupport.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Python/modsupport.c (original) +++ python/branches/py3k-ctypes-pep3118/Python/modsupport.c Sun Jan 20 11:45:31 2008 @@ -696,11 +696,23 @@ int PyModule_AddIntConstant(PyObject *m, const char *name, long value) { - return PyModule_AddObject(m, name, PyLong_FromLong(value)); + PyObject *o = PyLong_FromLong(value); + if (!o) + return -1; + if (PyModule_AddObject(m, name, o) == 0) + return 0; + Py_DECREF(o); + return -1; } int PyModule_AddStringConstant(PyObject *m, const char *name, const char *value) { - return PyModule_AddObject(m, name, PyUnicode_FromString(value)); + PyObject *o = PyUnicode_FromString(value); + if (!o) + return -1; + if (PyModule_AddObject(m, name, o) == 0) + return 0; + Py_DECREF(o); + return -1; } Modified: python/branches/py3k-ctypes-pep3118/Python/mystrtoul.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Python/mystrtoul.c (original) +++ python/branches/py3k-ctypes-pep3118/Python/mystrtoul.c Sun Jan 20 11:45:31 2008 @@ -116,12 +116,30 @@ if (*str == '0') { ++str; if (*str == 'x' || *str == 'X') { + /* there must be at least one digit after 0x */ + if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 16) { + if (ptr) + *ptr = str; + return 0; + } ++str; base = 16; } else if (*str == 'o' || *str == 'O') { + /* there must be at least one digit after 0o */ + if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 8) { + if (ptr) + *ptr = str; + return 0; + } ++str; base = 8; } else if (*str == 'b' || *str == 'B') { + /* there must be at least one digit after 0b */ + if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 2) { + if (ptr) + *ptr = str; + return 0; + } ++str; base = 2; } else { @@ -143,22 +161,43 @@ case 16: if (*str == '0') { ++str; - if (*str == 'x' || *str == 'X') + if (*str == 'x' || *str == 'X') { + /* there must be at least one digit after 0x */ + if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 16) { + if (ptr) + *ptr = str; + return 0; + } ++str; + } } break; case 8: if (*str == '0') { ++str; - if (*str == 'o' || *str == 'O') + if (*str == 'o' || *str == 'O') { + /* there must be at least one digit after 0o */ + if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 8) { + if (ptr) + *ptr = str; + return 0; + } ++str; + } } break; case 2: if(*str == '0') { ++str; - if (*str == 'b' || *str == 'B') + if (*str == 'b' || *str == 'B') { + /* there must be at least one digit after 0b */ + if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 2) { + if (ptr) + *ptr = str; + return 0; + } ++str; + } } break; } From python-3000-checkins at python.org Sun Jan 20 11:59:45 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sun, 20 Jan 2008 11:59:45 +0100 (CET) Subject: [Python-3000-checkins] r60129 - python/branches/py3k/Doc/whatsnew/3.0.rst Message-ID: <20080120105945.2CC6D1E401F@bag.python.org> Author: georg.brandl Date: Sun Jan 20 11:59:44 2008 New Revision: 60129 Modified: python/branches/py3k/Doc/whatsnew/3.0.rst Log: Fix markup. Modified: python/branches/py3k/Doc/whatsnew/3.0.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.0.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.0.rst Sun Jan 20 11:59:44 2008 @@ -389,7 +389,8 @@ * Everything is all in the details! -* Developers can include intobject.h after Python.h for some PyInt_ aliases. +* Developers can include :file:`intobject.h` after :file:`Python.h` for + some ``PyInt_`` aliases. .. ====================================================================== From python-3000-checkins at python.org Sun Jan 20 12:00:16 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sun, 20 Jan 2008 12:00:16 +0100 (CET) Subject: [Python-3000-checkins] r60130 - python/branches/py3k/Doc/c-api/gcsupport.rst python/branches/py3k/Doc/c-api/index.rst Message-ID: <20080120110016.55A171E4045@bag.python.org> Author: georg.brandl Date: Sun Jan 20 12:00:14 2008 New Revision: 60130 Modified: python/branches/py3k/Doc/c-api/gcsupport.rst python/branches/py3k/Doc/c-api/index.rst Log: Fix two oversights in C API split. Modified: python/branches/py3k/Doc/c-api/gcsupport.rst ============================================================================== --- python/branches/py3k/Doc/c-api/gcsupport.rst (original) +++ python/branches/py3k/Doc/c-api/gcsupport.rst Sun Jan 20 12:00:14 2008 @@ -18,6 +18,7 @@ .. data:: Py_TPFLAGS_HAVE_GC + :noindex: Objects with a type with this flag set must conform with the rules documented here. For convenience these objects will be referred to as container objects. Modified: python/branches/py3k/Doc/c-api/index.rst ============================================================================== --- python/branches/py3k/Doc/c-api/index.rst (original) +++ python/branches/py3k/Doc/c-api/index.rst Sun Jan 20 12:00:14 2008 @@ -24,4 +24,4 @@ concrete.rst init.rst memory.rst - newtypes.rst + objimpl.rst From python-3000-checkins at python.org Sun Jan 20 12:22:21 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sun, 20 Jan 2008 12:22:21 +0100 (CET) Subject: [Python-3000-checkins] r60132 - in python/branches/py3k/Doc: howto/doanddont.rst library/bdb.rst tutorial/controlflow.rst Message-ID: <20080120112221.F158B1E401F@bag.python.org> Author: georg.brandl Date: Sun Jan 20 12:22:21 2008 New Revision: 60132 Modified: python/branches/py3k/Doc/howto/doanddont.rst python/branches/py3k/Doc/library/bdb.rst python/branches/py3k/Doc/tutorial/controlflow.rst Log: Fix now-wrong :keyword: markup. Remove the section about "exec without namespace" from the "don't" howto since exec() can't overwrite names in the calling namespace anymore. Modified: python/branches/py3k/Doc/howto/doanddont.rst ============================================================================== --- python/branches/py3k/Doc/howto/doanddont.rst (original) +++ python/branches/py3k/Doc/howto/doanddont.rst Sun Jan 20 12:22:21 2008 @@ -75,39 +75,6 @@ * When the module advertises itself as ``from import *`` safe. -Unadorned :keyword:`exec` and friends -------------------------------------- - -The word "unadorned" refers to the use without an explicit dictionary, in which -case those constructs evaluate code in the *current* environment. This is -dangerous for the same reasons ``from import *`` is dangerous --- it might step -over variables you are counting on and mess up things for the rest of your code. -Simply do not do that. - -Bad examples:: - - >>> for name in sys.argv[1:]: - >>> exec "%s=1" % name - >>> def func(s, **kw): - >>> for var, val in kw.items(): - >>> exec "s.%s=val" % var # invalid! - >>> exec(open("handler.py").read()) - >>> handle() - -Good examples:: - - >>> d = {} - >>> for name in sys.argv[1:]: - >>> d[name] = 1 - >>> def func(s, **kw): - >>> for var, val in kw.items(): - >>> setattr(s, var, val) - >>> d={} - >>> exec(open("handle.py").read(), d, d) - >>> handle = d['handle'] - >>> handle() - - from module import name1, name2 ------------------------------- Modified: python/branches/py3k/Doc/library/bdb.rst ============================================================================== --- python/branches/py3k/Doc/library/bdb.rst (original) +++ python/branches/py3k/Doc/library/bdb.rst Sun Jan 20 12:22:21 2008 @@ -294,7 +294,7 @@ .. method:: Bdb.run(cmd, [globals, [locals]]) - Debug a statement executed via the :keyword:`exec` statement. *globals* + Debug a statement executed via the :func:`exec` function. *globals* defaults to :attr:`__main__.__dict__`, *locals* defaults to *globals*. .. method:: Bdb.runeval(expr, [globals, [locals]]) Modified: python/branches/py3k/Doc/tutorial/controlflow.rst ============================================================================== --- python/branches/py3k/Doc/tutorial/controlflow.rst (original) +++ python/branches/py3k/Doc/tutorial/controlflow.rst Sun Jan 20 12:22:21 2008 @@ -263,7 +263,7 @@ technically speaking, procedures do return a value, albeit a rather boring one. This value is called ``None`` (it's a built-in name). Writing the value ``None`` is normally suppressed by the interpreter if it would be the only value -written. You can see it if you really want to using :keyword:`print`:: +written. You can see it if you really want to using :func:`print`:: >>> fib(0) >>> print(fib(0)) From python-3000-checkins at python.org Sun Jan 20 16:14:12 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Sun, 20 Jan 2008 16:14:12 +0100 (CET) Subject: [Python-3000-checkins] r60144 - in python/branches/py3k: Doc/library/constants.rst Doc/library/functions.rst Doc/library/shutil.rst Doc/library/sys.rst Doc/library/urllib.rst Include/pyport.h Lib/shutil.py Lib/test/test_operator.py Lib/test/test_profilehooks.py Lib/test/test_pyclbr.py Lib/test/test_shutil.py Lib/test/test_trace.py Lib/test/test_urllib.py Lib/test/test_urllibnet.py Lib/urllib.py Python/hypot.c Python/sysmodule.c configure configure.in pyconfig.h.in Message-ID: <20080120151412.D93641E4008@bag.python.org> Author: christian.heimes Date: Sun Jan 20 16:14:11 2008 New Revision: 60144 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/constants.rst python/branches/py3k/Doc/library/functions.rst python/branches/py3k/Doc/library/shutil.rst python/branches/py3k/Doc/library/sys.rst python/branches/py3k/Doc/library/urllib.rst python/branches/py3k/Include/pyport.h python/branches/py3k/Lib/shutil.py python/branches/py3k/Lib/test/test_operator.py python/branches/py3k/Lib/test/test_profilehooks.py python/branches/py3k/Lib/test/test_pyclbr.py python/branches/py3k/Lib/test/test_shutil.py python/branches/py3k/Lib/test/test_trace.py python/branches/py3k/Lib/test/test_urllib.py python/branches/py3k/Lib/test/test_urllibnet.py python/branches/py3k/Lib/urllib.py python/branches/py3k/Python/hypot.c python/branches/py3k/Python/sysmodule.c python/branches/py3k/configure python/branches/py3k/configure.in python/branches/py3k/pyconfig.h.in Log: Merged revisions 60124-60142 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60131 | georg.brandl | 2008-01-20 12:13:29 +0100 (Sun, 20 Jan 2008) | 3 lines #1351692: in pprint, always call format() for dict and list items to enable custom formatting of contents via subclassing PrettyPrinter. ........ r60133 | georg.brandl | 2008-01-20 12:43:03 +0100 (Sun, 20 Jan 2008) | 2 lines #1178141: add addinfourl.code to get http status code from urllib. ........ r60134 | georg.brandl | 2008-01-20 13:05:43 +0100 (Sun, 20 Jan 2008) | 4 lines #856047: respect the ``no_proxy`` env var when checking for proxies in urllib and using the other ``_proxy`` env vars. Original patch by Donovan Baarda. ........ r60135 | georg.brandl | 2008-01-20 13:18:17 +0100 (Sun, 20 Jan 2008) | 4 lines #1664522: in urllib, don't read non-existing directories in ftp mode, returning a 0-byte file -- raise an IOError instead. Original patch from Phil Knirsch. ........ r60136 | georg.brandl | 2008-01-20 13:57:47 +0100 (Sun, 20 Jan 2008) | 2 lines #799369: document possible sys.platform values. ........ r60137 | georg.brandl | 2008-01-20 14:08:37 +0100 (Sun, 20 Jan 2008) | 2 lines #652749: document the constants added to the builtins by site.py. ........ r60138 | georg.brandl | 2008-01-20 14:59:46 +0100 (Sun, 20 Jan 2008) | 2 lines #1648: add sys.gettrace() and sys.getprofile(). ........ r60139 | georg.brandl | 2008-01-20 15:17:42 +0100 (Sun, 20 Jan 2008) | 2 lines #1669: don't allow shutil.rmtree() to be called on a symlink. ........ r60140 | georg.brandl | 2008-01-20 15:20:02 +0100 (Sun, 20 Jan 2008) | 2 lines Fix test_pyclbr after urllib change. ........ r60141 | christian.heimes | 2008-01-20 15:28:28 +0100 (Sun, 20 Jan 2008) | 1 line Fixed a wrong assumption in configure.in and Include/pyport.h. The is finite function is not called isfinite() but finite(). Sorry, my fault. :) ........ r60142 | georg.brandl | 2008-01-20 15:31:27 +0100 (Sun, 20 Jan 2008) | 2 lines #1876: fix typos in test_operator. ........ Modified: python/branches/py3k/Doc/library/constants.rst ============================================================================== --- python/branches/py3k/Doc/library/constants.rst (original) +++ python/branches/py3k/Doc/library/constants.rst Sun Jan 20 16:14:11 2008 @@ -1,4 +1,3 @@ - Built-in Constants ================== @@ -52,3 +51,28 @@ This constant is true if Python was not started with an :option:`-O` option. Assignments to :const:`__debug__` are illegal and raise a :exc:`SyntaxError`. See also the :keyword:`assert` statement. + + +Constants added by the :mod:`site` module +----------------------------------------- + +The :mod:`site` module (which is imported automatically during startup, except +if the :option:`-S` command-line option is given) adds several constants to the +built-in namespace. They are useful for the interactive interpreter shell and +should not be used in programs. + +.. data:: quit([code=None]) + exit([code=None]) + + Objects that when printed, print a message like "Use quit() or Ctrl-D + (i.e. EOF) to exit", and when called, raise :exc:`SystemExit` with the + specified exit code, and when . + +.. data:: copyright + license + credits + + Objects that when printed, print a message like "Type license() to see the + full license text", and when called, display the corresponding text in a + pager-like fashion (one screen at a time). + Modified: python/branches/py3k/Doc/library/functions.rst ============================================================================== --- python/branches/py3k/Doc/library/functions.rst (original) +++ python/branches/py3k/Doc/library/functions.rst Sun Jan 20 16:14:11 2008 @@ -526,6 +526,8 @@ topic, and a help page is printed on the console. If the argument is any other kind of object, a help page on the object is generated. + This function is added to the built-in namespace by the :mod:`site` module. + .. function:: hex(x) Modified: python/branches/py3k/Doc/library/shutil.rst ============================================================================== --- python/branches/py3k/Doc/library/shutil.rst (original) +++ python/branches/py3k/Doc/library/shutil.rst Sun Jan 20 16:14:11 2008 @@ -93,18 +93,24 @@ .. index:: single: directory; deleting - Delete an entire directory tree (*path* must point to a directory). If - *ignore_errors* is true, errors resulting from failed removals will be ignored; - if false or omitted, such errors are handled by calling a handler specified by - *onerror* or, if that is omitted, they raise an exception. - - If *onerror* is provided, it must be a callable that accepts three parameters: - *function*, *path*, and *excinfo*. The first parameter, *function*, is the - function which raised the exception; it will be :func:`os.listdir`, - :func:`os.remove` or :func:`os.rmdir`. The second parameter, *path*, will be - the path name passed to *function*. The third parameter, *excinfo*, will be the - exception information return by :func:`sys.exc_info`. Exceptions raised by - *onerror* will not be caught. + Delete an entire directory tree; *path* must point to a directory (but not a + symbolic link to a directory). If *ignore_errors* is true, errors resulting + from failed removals will be ignored; if false or omitted, such errors are + handled by calling a handler specified by *onerror* or, if that is omitted, + they raise an exception. + + If *onerror* is provided, it must be a callable that accepts three + parameters: *function*, *path*, and *excinfo*. The first parameter, + *function*, is the function which raised the exception; it will be + :func:`os.path.islink`, :func:`os.listdir`, :func:`os.remove` or + :func:`os.rmdir`. The second parameter, *path*, will be the path name passed + to *function*. The third parameter, *excinfo*, will be the exception + information return by :func:`sys.exc_info`. Exceptions raised by *onerror* + will not be caught. + + .. versionchanged:: 2.6 + Explicitly check for *path* being a symbolic link and raise :exc:`OSError` + in that case. .. function:: move(src, dst) Modified: python/branches/py3k/Doc/library/sys.rst ============================================================================== --- python/branches/py3k/Doc/library/sys.rst (original) +++ python/branches/py3k/Doc/library/sys.rst Sun Jan 20 16:14:11 2008 @@ -326,6 +326,35 @@ This function should be used for internal and specialized purposes only. +.. function:: getprofile() + + .. index:: + single: profile function + single: profiler + + Get the profiler function as set by :func:`setprofile`. + + .. versionadded:: 2.6 + + +.. function:: gettrace() + + .. index:: + single: trace function + single: debugger + + Get the trace function as set by :func:`settrace`. + + .. note:: + + The :func:`gettrace` function is intended only for implementing debuggers, + profilers, coverage tools and the like. Its behavior is part of the + implementation platform, rather than part of the language definition, + and thus may not be available in all Python implementations. + + .. versionadded:: 2.6 + + .. function:: getwindowsversion() Return a tuple containing five components, describing the Windows version @@ -444,9 +473,26 @@ .. data:: platform - This string contains a platform identifier, e.g. ``'sunos5'`` or ``'linux1'``. - This can be used to append platform-specific components to ``path``, for - instance. + This string contains a platform identifier that can be used to append + platform-specific components to :data:`sys.path`, for instance. + + For Unix systems, this is the lowercased OS name as returned by ``uname -s`` + with the first part of the version as returned by ``uname -r`` appended, + e.g. ``'sunos5'`` or ``'linux2'``, *at the time when Python was built*. + For other systems, the values are: + + ================ =========================== + System :data:`platform` value + ================ =========================== + Windows ``'win32'`` + Windows/Cygwin ``'cygwin'`` + MacOS X ``'darwin'`` + MacOS 9 ``'mac'`` + OS/2 ``'os2'`` + OS/2 EMX ``'os2emx'`` + RiscOS ``'riscos'`` + AtheOS ``'atheos'`` + ================ =========================== .. data:: prefix Modified: python/branches/py3k/Doc/library/urllib.rst ============================================================================== --- python/branches/py3k/Doc/library/urllib.rst (original) +++ python/branches/py3k/Doc/library/urllib.rst Sun Jan 20 16:14:11 2008 @@ -27,16 +27,17 @@ a server somewhere on the network. If the connection cannot be made the :exc:`IOError` exception is raised. If all went well, a file-like object is returned. This supports the following methods: :meth:`read`, :meth:`readline`, - :meth:`readlines`, :meth:`fileno`, :meth:`close`, :meth:`info` and + :meth:`readlines`, :meth:`fileno`, :meth:`close`, :meth:`info`, :meth:`getcode` and :meth:`geturl`. It also has proper support for the :term:`iterator` protocol. One caveat: the :meth:`read` method, if the size argument is omitted or negative, may not read until the end of the data stream; there is no good way to determine that the entire stream from a socket has been read in the general case. - Except for the :meth:`info` and :meth:`geturl` methods, these methods have the - same interface as for file objects --- see section :ref:`bltin-file-objects` in - this manual. (It is not a built-in file object, however, so it can't be used at - those few places where a true built-in file object is required.) + Except for the :meth:`info`, :meth:`getcode` and :meth:`geturl` methods, + these methods have the same interface as for file objects --- see section + :ref:`bltin-file-objects` in this manual. (It is not a built-in file object, + however, so it can't be used at those few places where a true built-in file + object is required.) .. index:: module: mimetools @@ -58,6 +59,9 @@ the client was redirected to. The :meth:`geturl` method can be used to get at this redirected URL. + The :meth:`getcode` method returns the HTTP status code that was sent with the + response, or ``None`` if the URL is no HTTP URL. + If the *url* uses the :file:`http:` scheme identifier, the optional *data* argument may be given to specify a ``POST`` request (normally the request type is ``GET``). The *data* argument must be in standard @@ -75,6 +79,11 @@ % python ... + The :envvar:`no_proxy` environment variable can be used to specify hosts which + shouldn't be reached via proxy; if set, it should be a comma-separated list + of hostname suffixes, optionally with ``:port`` appended, for example + ``cern.ch,ncsa.uiuc.edu,some.host:8080``. + In a Windows environment, if no proxy environment variables are set, proxy settings are obtained from the registry's Internet Settings section. Modified: python/branches/py3k/Include/pyport.h ============================================================================== --- python/branches/py3k/Include/pyport.h (original) +++ python/branches/py3k/Include/pyport.h Sun Jan 20 16:14:11 2008 @@ -388,8 +388,8 @@ * macro for this particular test is useful */ #ifndef Py_IS_FINITE -#ifdef HAVE_ISFINITE -#define Py_IS_FINITE(X) isfinite +#ifdef HAVE_FINITE +#define Py_IS_FINITE(X) finite #else #define Py_IS_FINITE(X) (!Py_IS_INFINITY(X) && !Py_IS_NAN(X)) #endif Modified: python/branches/py3k/Lib/shutil.py ============================================================================== --- python/branches/py3k/Lib/shutil.py (original) +++ python/branches/py3k/Lib/shutil.py Sun Jan 20 16:14:11 2008 @@ -156,6 +156,14 @@ elif onerror is None: def onerror(*args): raise + try: + if os.path.islink(path): + # symlinks to directories are forbidden, see bug #1669 + raise OSError("Cannot call rmtree on a symbolic link") + except OSError: + onerror(os.path.islink, path, sys.exc_info()) + # can't continue even if onerror hook returns + return names = [] try: names = os.listdir(path) Modified: python/branches/py3k/Lib/test/test_operator.py ============================================================================== --- python/branches/py3k/Lib/test/test_operator.py (original) +++ python/branches/py3k/Lib/test/test_operator.py Sun Jan 20 16:14:11 2008 @@ -364,9 +364,9 @@ self.assertRaises(TypeError, operator.attrgetter('x', (), 'y'), record) class C(object): - def __getattr(self, name): + def __getattr__(self, name): raise SyntaxError - self.failUnlessRaises(AttributeError, operator.attrgetter('foo'), C()) + self.failUnlessRaises(SyntaxError, operator.attrgetter('foo'), C()) def test_itemgetter(self): a = 'ABCDE' @@ -376,9 +376,9 @@ self.assertRaises(IndexError, f, a) class C(object): - def __getitem(self, name): + def __getitem__(self, name): raise SyntaxError - self.failUnlessRaises(TypeError, operator.itemgetter(42), C()) + self.failUnlessRaises(SyntaxError, operator.itemgetter(42), C()) f = operator.itemgetter('name') self.assertRaises(TypeError, f, a) Modified: python/branches/py3k/Lib/test/test_profilehooks.py ============================================================================== --- python/branches/py3k/Lib/test/test_profilehooks.py (original) +++ python/branches/py3k/Lib/test/test_profilehooks.py Sun Jan 20 16:14:11 2008 @@ -4,6 +4,22 @@ from test import test_support +class TestGetProfile(unittest.TestCase): + def setUp(self): + sys.setprofile(None) + + def tearDown(self): + sys.setprofile(None) + + def test_empty(self): + assert sys.getprofile() == None + + def test_setget(self): + def fn(*args): + pass + + sys.setprofile(fn) + assert sys.getprofile() == fn class HookWatcher: def __init__(self): @@ -359,6 +375,7 @@ def test_main(): test_support.run_unittest( + TestGetProfile, ProfileHookTestCase, ProfileSimulatorTestCase ) Modified: python/branches/py3k/Lib/test/test_pyclbr.py ============================================================================== --- python/branches/py3k/Lib/test/test_pyclbr.py (original) +++ python/branches/py3k/Lib/test/test_pyclbr.py Sun Jan 20 16:14:11 2008 @@ -158,6 +158,7 @@ cm('cgi', ignore=('log',)) # set with = in module cm('mhlib') cm('urllib', ignore=('getproxies_registry', + 'proxy_bypass_registry', 'open_https', '_https_connection', 'getproxies_internetconfig',)) # not on all platforms Modified: python/branches/py3k/Lib/test/test_shutil.py ============================================================================== --- python/branches/py3k/Lib/test/test_shutil.py (original) +++ python/branches/py3k/Lib/test/test_shutil.py Sun Jan 20 16:14:11 2008 @@ -149,6 +149,20 @@ except OSError: pass + def test_rmtree_on_symlink(self): + # bug 1669. + os.mkdir(TESTFN) + try: + src = os.path.join(TESTFN, 'cheese') + dst = os.path.join(TESTFN, 'shop') + os.mkdir(src) + os.symlink(src, dst) + self.assertRaises(OSError, shutil.rmtree, dst) + finally: + shutil.rmtree(TESTFN, ignore_errors=True) + + + def test_main(): test_support.run_unittest(TestShutil) Modified: python/branches/py3k/Lib/test/test_trace.py ============================================================================== --- python/branches/py3k/Lib/test/test_trace.py (original) +++ python/branches/py3k/Lib/test/test_trace.py Sun Jan 20 16:14:11 2008 @@ -268,6 +268,20 @@ self.compare_events(func.__code__.co_firstlineno, tracer.events, func.events) + def set_and_retrieve_none(self): + sys.settrace(None) + assert sys.gettrace() is None + + def set_and_retrieve_func(self): + def fn(*args): + pass + + sys.settrace(fn) + try: + assert sys.gettrace() is fn + finally: + sys.settrace(None) + def test_01_basic(self): self.run_test(basic) def test_02_arigo(self): Modified: python/branches/py3k/Lib/test/test_urllib.py ============================================================================== --- python/branches/py3k/Lib/test/test_urllib.py (original) +++ python/branches/py3k/Lib/test/test_urllib.py Sun Jan 20 16:14:11 2008 @@ -47,7 +47,7 @@ def test_interface(self): # Make sure object returned by urlopen() has the specified methods for attr in ("read", "readline", "readlines", "fileno", - "close", "info", "geturl", "__iter__"): + "close", "info", "geturl", "getcode", "__iter__"): self.assert_(hasattr(self.returned_obj, attr), "object returned by urlopen() lacks %s attribute" % attr) @@ -87,6 +87,9 @@ def test_geturl(self): self.assertEqual(self.returned_obj.geturl(), self.pathname) + def test_getcode(self): + self.assertEqual(self.returned_obj.getcode(), None) + def test_iter(self): # Test iterator # Don't need to count number of iterations since test would fail the @@ -123,6 +126,8 @@ fp = urllib.urlopen("http://python.org/") self.assertEqual(fp.readline(), b"Hello!") self.assertEqual(fp.readline(), b"") + self.assertEqual(fp.geturl(), 'http://python.org/') + self.assertEqual(fp.getcode(), 200) finally: self.unfakehttp() Modified: python/branches/py3k/Lib/test/test_urllibnet.py ============================================================================== --- python/branches/py3k/Lib/test/test_urllibnet.py (original) +++ python/branches/py3k/Lib/test/test_urllibnet.py Sun Jan 20 16:14:11 2008 @@ -83,6 +83,16 @@ open_url.close() self.assertEqual(gotten_url, URL) + def test_getcode(self): + # test getcode() with the fancy opener to get 404 error codes + URL = "http://www.python.org/XXXinvalidXXX" + open_url = urllib.FancyURLopener().open(URL) + try: + code = open_url.getcode() + finally: + open_url.close() + self.assertEqual(code, 404) + def test_fileno(self): if (sys.platform in ('win32',) or not hasattr(os, 'fdopen')): Modified: python/branches/py3k/Lib/urllib.py ============================================================================== --- python/branches/py3k/Lib/urllib.py (original) +++ python/branches/py3k/Lib/urllib.py Sun Jan 20 16:14:11 2008 @@ -557,7 +557,7 @@ def http_error_default(self, url, fp, errcode, errmsg, headers): """Default error handling -- don't raise an exception.""" - return addinfourl(fp, headers, "http:" + url) + return addinfourl(fp, headers, "http:" + url, errcode) def http_error_302(self, url, fp, errcode, errmsg, headers, data=None): """Error 302 -- relocated (temporarily).""" @@ -815,9 +815,19 @@ if not conn: # Set transfer mode to ASCII! self.ftp.voidcmd('TYPE A') - # Try a directory listing - if file: cmd = 'LIST ' + file - else: cmd = 'LIST' + # Try a directory listing. Verify that directory exists. + if file: + pwd = self.ftp.pwd() + try: + try: + self.ftp.cwd(file) + except ftplib.error_perm as reason: + raise IOError('ftp error', reason) from reason + finally: + self.ftp.cwd(pwd) + cmd = 'LIST ' + file + else: + cmd = 'LIST' conn = self.ftp.ntransfercmd(cmd) self.busy = 1 # Pass back both a suitably decorated object and a retrieval length @@ -898,14 +908,18 @@ class addinfourl(addbase): """class to add info() and geturl() methods to an open file.""" - def __init__(self, fp, headers, url): + def __init__(self, fp, headers, url, code=None): addbase.__init__(self, fp) self.headers = headers self.url = url + self.code = code def info(self): return self.headers + def getcode(self): + return self.code + def geturl(self): return self.url @@ -1228,10 +1242,33 @@ proxies = {} for name, value in os.environ.items(): name = name.lower() + if name == 'no_proxy': + # handled in proxy_bypass_environment + continue if value and name[-6:] == '_proxy': proxies[name[:-6]] = value return proxies +def proxy_bypass_environment(host): + """Test if proxies should not be used for a particular host. + + Checks the environment for a variable named no_proxy, which should + be a list of DNS suffixes separated by commas, or '*' for all hosts. + """ + no_proxy = os.environ.get('no_proxy', '') or os.environ.get('NO_PROXY', '') + # '*' is special case for always bypass + if no_proxy == '*': + return 1 + # strip port off host + hostonly, port = splitport(host) + # check if the host ends with any of the DNS suffixes + for name in no_proxy.split(','): + if name and (hostonly.endswith(name) or host.endswith(name)): + return 1 + # otherwise, don't bypass + return 0 + + if sys.platform == 'darwin': def getproxies_internetconfig(): """Return a dictionary of scheme -> proxy server URL mappings. @@ -1259,12 +1296,15 @@ pass else: proxies['http'] = 'http://%s' % value - # FTP: XXXX To be done. - # Gopher: XXXX To be done. + # FTP: XXX To be done. + # Gopher: XXX To be done. return proxies - def proxy_bypass(x): - return 0 + def proxy_bypass(host): + if getproxies_environment(): + return proxy_bypass_environment(host) + else: + return 0 def getproxies(): return getproxies_environment() or getproxies_internetconfig() @@ -1324,7 +1364,7 @@ """ return getproxies_environment() or getproxies_registry() - def proxy_bypass(host): + def proxy_bypass_registry(host): try: import _winreg import re @@ -1383,12 +1423,22 @@ return 1 return 0 + def proxy_bypass(host): + """Return a dictionary of scheme -> proxy server URL mappings. + + Returns settings gathered from the environment, if specified, + or the registry. + + """ + if getproxies_environment(): + return proxy_bypass_environment(host) + else: + return proxy_bypass_registry(host) + else: # By default use environment variables getproxies = getproxies_environment - - def proxy_bypass(host): - return 0 + proxy_bypass = proxy_bypass_environment # Test and time quote() and unquote() def test1(): Modified: python/branches/py3k/Python/hypot.c ============================================================================== --- python/branches/py3k/Python/hypot.c (original) +++ python/branches/py3k/Python/hypot.c Sun Jan 20 16:14:11 2008 @@ -2,6 +2,7 @@ #include "Python.h" +#ifndef HAVE_HYPOT double hypot(double x, double y) { double yx; @@ -20,3 +21,5 @@ return x*sqrt(1.+yx*yx); } } +#endif /* HAVE_HYPOT */ + Modified: python/branches/py3k/Python/sysmodule.c ============================================================================== --- python/branches/py3k/Python/sysmodule.c (original) +++ python/branches/py3k/Python/sysmodule.c Sun Jan 20 16:14:11 2008 @@ -374,6 +374,25 @@ ); static PyObject * +sys_gettrace(PyObject *self, PyObject *args) +{ + PyThreadState *tstate = PyThreadState_GET(); + PyObject *temp = tstate->c_traceobj; + + if (temp == NULL) + temp = Py_None; + Py_INCREF(temp); + return temp; +} + +PyDoc_STRVAR(gettrace_doc, +"gettrace()\n\ +\n\ +Return the global debug tracing function set with sys.settrace.\n\ +See the debugger chapter in the library manual." +); + +static PyObject * sys_setprofile(PyObject *self, PyObject *args) { if (trace_init() == -1) @@ -394,6 +413,25 @@ ); static PyObject * +sys_getprofile(PyObject *self, PyObject *args) +{ + PyThreadState *tstate = PyThreadState_GET(); + PyObject *temp = tstate->c_profileobj; + + if (temp == NULL) + temp = Py_None; + Py_INCREF(temp); + return temp; +} + +PyDoc_STRVAR(getprofile_doc, +"getprofile()\n\ +\n\ +Return the profiling function set with sys.setprofile.\n\ +See the profiler chapter in the library manual." +); + +static PyObject * sys_setcheckinterval(PyObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, "i:setcheckinterval", &_Py_CheckInterval)) @@ -763,12 +801,14 @@ setdlopenflags_doc}, #endif {"setprofile", sys_setprofile, METH_O, setprofile_doc}, + {"getprofile", sys_getprofile, METH_NOARGS, getprofile_doc}, {"setrecursionlimit", sys_setrecursionlimit, METH_VARARGS, setrecursionlimit_doc}, #ifdef WITH_TSC {"settscdump", sys_settscdump, METH_VARARGS, settscdump_doc}, #endif {"settrace", sys_settrace, METH_O, settrace_doc}, + {"gettrace", sys_gettrace, METH_NOARGS, gettrace_doc}, {"call_tracing", sys_call_tracing, METH_VARARGS, call_tracing_doc}, {NULL, NULL} /* sentinel */ }; @@ -903,8 +943,10 @@ exc_info() -- return thread-safe information about the current exception\n\ exit() -- exit the interpreter by raising SystemExit\n\ getdlopenflags() -- returns flags to be used for dlopen() calls\n\ +getprofile() -- get the global profiling function\n\ getrefcount() -- return the reference count for an object (plus one :-)\n\ getrecursionlimit() -- return the max recursion depth for the interpreter\n\ +gettrace() -- get the global debug tracing function\n\ setcheckinterval() -- control how often the interpreter checks for events\n\ setdlopenflags() -- set the flags to be used for dlopen() calls\n\ setprofile() -- set the global profiling function\n\ Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Sun Jan 20 16:14:11 2008 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 59826 . +# From configure.in Revision: 59829 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.0. # @@ -20584,7 +20584,6 @@ # ************************************ # * Check for mathematical functions * # ************************************ -# check for hypot() in math library LIBS_SAVE=$LIBS LIBS="$LIBS $LIBM" @@ -20694,7 +20693,12 @@ -for ac_func in copysign isfinite isnan isinf + + + + + +for ac_func in acosh asinh atanh copysign expm1 finite isinf isnan log1p do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Sun Jan 20 16:14:11 2008 @@ -2948,12 +2948,11 @@ # ************************************ # * Check for mathematical functions * # ************************************ -# check for hypot() in math library LIBS_SAVE=$LIBS LIBS="$LIBS $LIBM" AC_REPLACE_FUNCS(hypot) -AC_CHECK_FUNCS(copysign isfinite isnan isinf) +AC_CHECK_FUNCS(acosh asinh atanh copysign expm1 finite isinf isnan log1p) LIBS=$LIBS_SAVE Modified: python/branches/py3k/pyconfig.h.in ============================================================================== --- python/branches/py3k/pyconfig.h.in (original) +++ python/branches/py3k/pyconfig.h.in Sun Jan 20 16:14:11 2008 @@ -25,6 +25,9 @@ the case on Motorola V4 (R40V4.2) */ #undef GETTIMEOFDAY_NO_TZ +/* Define to 1 if you have the `acosh' function. */ +#undef HAVE_ACOSH + /* struct addrinfo (netdb.h) */ #undef HAVE_ADDRINFO @@ -34,9 +37,15 @@ /* Define this if your time.h defines altzone. */ #undef HAVE_ALTZONE +/* Define to 1 if you have the `asinh' function. */ +#undef HAVE_ASINH + /* Define to 1 if you have the header file. */ #undef HAVE_ASM_TYPES_H +/* Define to 1 if you have the `atanh' function. */ +#undef HAVE_ATANH + /* Define if GCC supports __attribute__((format(PyArg_ParseTuple, 2, 3))) */ #undef HAVE_ATTRIBUTE_FORMAT_PARSETUPLE @@ -141,6 +150,9 @@ /* Define to 1 if you have the `execv' function. */ #undef HAVE_EXECV +/* Define to 1 if you have the `expm1' function. */ +#undef HAVE_EXPM1 + /* Define if you have the 'fchdir' function. */ #undef HAVE_FCHDIR @@ -156,6 +168,9 @@ /* Define if you have the 'fdatasync' function. */ #undef HAVE_FDATASYNC +/* Define to 1 if you have the `finite' function. */ +#undef HAVE_FINITE + /* Define if you have the 'flock' function. */ #undef HAVE_FLOCK @@ -288,9 +303,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_IO_H -/* Define to 1 if you have the `isfinite' function. */ -#undef HAVE_ISFINITE - /* Define to 1 if you have the `isinf' function. */ #undef HAVE_ISINF @@ -354,6 +366,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_TIPC_H +/* Define to 1 if you have the `log1p' function. */ +#undef HAVE_LOG1P + /* Define this if you have the type long double. */ #undef HAVE_LONG_DOUBLE From python-3000-checkins at python.org Mon Jan 21 12:20:28 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Mon, 21 Jan 2008 12:20:28 +0100 (CET) Subject: [Python-3000-checkins] r60150 - in python/branches/py3k: Doc/c-api/typeobj.rst Doc/tutorial/interpreter.rst Doc/using/cmdline.rst Lib/pstats.py Lib/test/test_pstats.py Modules/mmapmodule.c Python/pystate.c Message-ID: <20080121112028.C9D431E4019@bag.python.org> Author: christian.heimes Date: Mon Jan 21 12:20:28 2008 New Revision: 60150 Added: python/branches/py3k/Lib/test/test_pstats.py - copied unchanged from r60149, python/trunk/Lib/test/test_pstats.py Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/c-api/typeobj.rst python/branches/py3k/Doc/tutorial/interpreter.rst python/branches/py3k/Doc/using/cmdline.rst python/branches/py3k/Lib/pstats.py python/branches/py3k/Modules/mmapmodule.c python/branches/py3k/Python/pystate.c Log: Merged revisions 60143-60149 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60143 | georg.brandl | 2008-01-20 15:50:05 +0100 (Sun, 20 Jan 2008) | 3 lines Switch mmap from old Py_FindMethod to new PyObject_GenericGetAttr attribute access. Fixes #1087735. ........ r60145 | georg.brandl | 2008-01-20 20:40:58 +0100 (Sun, 20 Jan 2008) | 2 lines Add blurb about executable scripts on Windows. #760657. ........ r60146 | georg.brandl | 2008-01-20 20:48:40 +0100 (Sun, 20 Jan 2008) | 2 lines #1219903: fix tp_richcompare docs. ........ r60147 | georg.brandl | 2008-01-20 22:10:08 +0100 (Sun, 20 Jan 2008) | 2 lines Fix markup. ........ r60148 | gregory.p.smith | 2008-01-21 08:11:11 +0100 (Mon, 21 Jan 2008) | 14 lines Provide a sanity check during PyThreadState_DeleteCurrent() and PyThreadState_Delete() to avoid an infinite loop when the tstate list is messed up and has somehow becomes circular and does not contain the current thread. I don't know how this happens but it does, *very* rarely. On more than one hardware platform. I have not been able to reproduce it manually. Attaching to a process where its happening: it has always been in an infinite loop over a single element tstate list that is not the tstate we're looking to delete. It has been in t_bootstrap()'s call to PyThreadState_DeleteCurrent() as a pthread is exiting. ........ r60149 | georg.brandl | 2008-01-21 11:24:59 +0100 (Mon, 21 Jan 2008) | 2 lines #1269: fix a bug in pstats.add_callers() and add a unit test file for pstats. ........ Modified: python/branches/py3k/Doc/c-api/typeobj.rst ============================================================================== --- python/branches/py3k/Doc/c-api/typeobj.rst (original) +++ python/branches/py3k/Doc/c-api/typeobj.rst Mon Jan 21 12:20:28 2008 @@ -649,13 +649,19 @@ .. cmember:: richcmpfunc PyTypeObject.tp_richcompare - An optional pointer to the rich comparison function. + An optional pointer to the rich comparison function, whose signature is + ``PyObject *tp_richcompare(PyObject *a, PyObject *b, int op)``. - The signature is the same as for :cfunc:`PyObject_RichCompare`. The function - should return the result of the comparison (usually ``Py_True`` or - ``Py_False``). If the comparison is undefined, it must return - ``Py_NotImplemented``, if another error occurred it must return ``NULL`` and set - an exception condition. + The function should return the result of the comparison (usually ``Py_True`` + or ``Py_False``). If the comparison is undefined, it must return + ``Py_NotImplemented``, if another error occurred it must return ``NULL`` and + set an exception condition. + + .. note:: + + If you want to implement a type for which only a limited set of + comparisons makes sense (e.g. ``==`` and ``!=``, but not ``<`` and + friends), directly raise :exc:`TypeError` in the rich comparison function. This field is inherited by subtypes together with :attr:`tp_compare` and :attr:`tp_hash`: a subtype inherits all three of :attr:`tp_compare`, @@ -681,10 +687,10 @@ | :const:`Py_GE` | ``>=`` | +----------------+------------+ + The next field only exists if the :const:`Py_TPFLAGS_HAVE_WEAKREFS` flag bit is set. - .. cmember:: long PyTypeObject.tp_weaklistoffset If the instances of this type are weakly referenceable, this field is greater Modified: python/branches/py3k/Doc/tutorial/interpreter.rst ============================================================================== --- python/branches/py3k/Doc/tutorial/interpreter.rst (original) +++ python/branches/py3k/Doc/tutorial/interpreter.rst Mon Jan 21 12:20:28 2008 @@ -169,6 +169,12 @@ $ chmod +x myscript.py +On Windows systems, there is no notion of an "executable mode". The Python +installer automatically associates ``.py`` files with ``python.exe`` so that +a double-click on a Python file will run it as a script. The extension can +also be ``.pyw``, in that case, the console window that normally appears is +suppressed. + Source Code Encoding -------------------- Modified: python/branches/py3k/Doc/using/cmdline.rst ============================================================================== --- python/branches/py3k/Doc/using/cmdline.rst (original) +++ python/branches/py3k/Doc/using/cmdline.rst Mon Jan 21 12:20:28 2008 @@ -297,14 +297,14 @@ .. envvar:: PYTHONHOME Change the location of the standard Python libraries. By default, the - libraries are searched in :file:`{prefix}/lib/python` and - :file:`{exec_prefix}/lib/python`, where :file:`{prefix}` and + libraries are searched in :file:`{prefix}/lib/python{version}` and + :file:`{exec_prefix}/lib/python{version}`, where :file:`{prefix}` and :file:`{exec_prefix}` are installation-dependent directories, both defaulting to :file:`/usr/local`. When :envvar:`PYTHONHOME` is set to a single directory, its value replaces both :file:`{prefix}` and :file:`{exec_prefix}`. To specify different values - for these, set :envvar:`PYTHONHOME` to :file:`{prefix}:{exec_prefix}``. + for these, set :envvar:`PYTHONHOME` to :file:`{prefix}:{exec_prefix}`. .. envvar:: PYTHONPATH @@ -314,7 +314,7 @@ colons. Non-existent directories are silently ignored. The default search path is installation dependent, but generally begins with - :file:`{prefix}/lib/python`` (see :envvar:`PYTHONHOME` above). It + :file:`{prefix}/lib/python{version}`` (see :envvar:`PYTHONHOME` above). It is *always* appended to :envvar:`PYTHONPATH`. If a script argument is given, the directory containing the script is Modified: python/branches/py3k/Lib/pstats.py ============================================================================== --- python/branches/py3k/Lib/pstats.py (original) +++ python/branches/py3k/Lib/pstats.py Mon Jan 21 12:20:28 2008 @@ -511,7 +511,8 @@ new_callers[func] = caller for func, caller in source.items(): if func in new_callers: - new_callers[func] = caller + new_callers[func] + new_callers[func] = tuple([i[0] + i[1] for i in + zip(caller, new_callers[func])]) else: new_callers[func] = caller return new_callers Modified: python/branches/py3k/Modules/mmapmodule.c ============================================================================== --- python/branches/py3k/Modules/mmapmodule.c (original) +++ python/branches/py3k/Modules/mmapmodule.c Mon Jan 21 12:20:28 2008 @@ -666,12 +666,6 @@ self->exports--; } -static PyObject * -mmap_object_getattr(mmap_object *self, char *name) -{ - return Py_FindMethod(mmap_object_methods, (PyObject *)self, name); -} - static Py_ssize_t mmap_length(mmap_object *self) { @@ -901,6 +895,30 @@ (releasebufferproc)mmap_buffer_releasebuf, }; +PyDoc_STRVAR(mmap_doc, +"Windows: mmap(fileno, length[, tagname[, access[, offset]]])\n\ +\n\ +Maps length bytes from the file specified by the file handle fileno,\n\ +and returns a mmap object. If length is larger than the current size\n\ +of the file, the file is extended to contain length bytes. If length\n\ +is 0, the maximum length of the map is the current size of the file,\n\ +except that if the file is empty Windows raises an exception (you cannot\n\ +create an empty mapping on Windows).\n\ +\n\ +Unix: mmap(fileno, length[, flags[, prot[, access[, offset]]]])\n\ +\n\ +Maps length bytes from the file specified by the file descriptor fileno,\n\ +and returns a mmap object. If length is 0, the maximum length of the map\n\ +will be the current size of the file when mmap is called.\n\ +flags specifies the nature of the mapping. MAP_PRIVATE creates a\n\ +private copy-on-write mapping, so changes to the contents of the mmap\n\ +object will be private to this process, and MAP_SHARED`creates a mapping\n\ +that's shared with all other processes mapping the same areas of the file.\n\ +The default value is MAP_SHARED.\n\ +\n\ +To map anonymous memory, pass -1 as the fileno (both versions)."); + + static PyTypeObject mmap_object_type = { PyVarObject_HEAD_INIT(0, 0) /* patched in module init */ "mmap.mmap", /* tp_name */ @@ -909,7 +927,7 @@ /* methods */ (destructor) mmap_object_dealloc, /* tp_dealloc */ 0, /* tp_print */ - (getattrfunc) mmap_object_getattr, /* tp_getattr */ + 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ @@ -919,11 +937,19 @@ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ - 0, /*tp_getattro*/ + PyObject_GenericGetAttr, /*tp_getattro*/ 0, /*tp_setattro*/ &mmap_as_buffer, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ + mmap_doc, /*tp_doc*/ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + mmap_object_methods, /* tp_methods */ + }; @@ -1265,7 +1291,7 @@ /* List of functions exported by this module */ static struct PyMethodDef mmap_functions[] = { {"mmap", (PyCFunction) new_mmap_object, - METH_VARARGS|METH_KEYWORDS}, + METH_VARARGS|METH_KEYWORDS, mmap_doc}, {NULL, NULL} /* Sentinel */ }; Modified: python/branches/py3k/Python/pystate.c ============================================================================== --- python/branches/py3k/Python/pystate.c (original) +++ python/branches/py3k/Python/pystate.c Mon Jan 21 12:20:28 2008 @@ -242,6 +242,7 @@ { PyInterpreterState *interp; PyThreadState **p; + PyThreadState *prev_p = NULL; if (tstate == NULL) Py_FatalError("PyThreadState_Delete: NULL tstate"); interp = tstate->interp; @@ -254,6 +255,15 @@ "PyThreadState_Delete: invalid tstate"); if (*p == tstate) break; + if (*p == prev_p) + Py_FatalError( + "PyThreadState_Delete: small circular list(!)" + " and tstate not found."); + prev_p = *p; + if ((*p)->next == interp->tstate_head) + Py_FatalError( + "PyThreadState_Delete: circular list(!) and" + " tstate not found."); } *p = tstate->next; HEAD_UNLOCK(); From python-3000-checkins at python.org Mon Jan 21 21:36:11 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Mon, 21 Jan 2008 21:36:11 +0100 (CET) Subject: [Python-3000-checkins] r60176 - in python/branches/py3k: Doc/bugs.rst Doc/conf.py Doc/extending/building.rst Doc/howto/regex.rst Doc/library/configparser.rst Doc/library/fileformats.rst Doc/library/logging.rst Doc/library/mmap.rst Doc/library/plistlib.rst Doc/library/pydoc.rst Doc/tools/sphinxext/patchlevel.py Doc/tutorial/controlflow.rst Lib/distutils/command/build.py Lib/formatter.py Lib/keyword.py Lib/logging/handlers.py Lib/plat-mac/plistlib.py Lib/plistlib.py Lib/pydoc.py Lib/re.py Lib/test/test_pep263.py Lib/urlparse.py Makefile.pre.in Modules/mmapmodule.c Parser/tokenizer.c Tools/pynche/ColorDB.py Message-ID: <20080121203611.B57C31E4033@bag.python.org> Author: georg.brandl Date: Mon Jan 21 21:36:10 2008 New Revision: 60176 Added: python/branches/py3k/Doc/library/plistlib.rst - copied unchanged from r60175, python/trunk/Doc/library/plistlib.rst python/branches/py3k/Doc/tools/sphinxext/patchlevel.py - copied unchanged from r60175, python/trunk/Doc/tools/sphinxext/patchlevel.py python/branches/py3k/Lib/plistlib.py - copied, changed from r60175, python/trunk/Lib/plistlib.py Removed: python/branches/py3k/Lib/plat-mac/plistlib.py Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/bugs.rst python/branches/py3k/Doc/conf.py python/branches/py3k/Doc/extending/building.rst python/branches/py3k/Doc/howto/regex.rst python/branches/py3k/Doc/library/configparser.rst python/branches/py3k/Doc/library/fileformats.rst python/branches/py3k/Doc/library/logging.rst python/branches/py3k/Doc/library/mmap.rst python/branches/py3k/Doc/library/pydoc.rst python/branches/py3k/Doc/tutorial/controlflow.rst python/branches/py3k/Lib/distutils/command/build.py python/branches/py3k/Lib/formatter.py python/branches/py3k/Lib/keyword.py python/branches/py3k/Lib/logging/handlers.py python/branches/py3k/Lib/pydoc.py python/branches/py3k/Lib/re.py python/branches/py3k/Lib/test/test_pep263.py python/branches/py3k/Lib/urlparse.py python/branches/py3k/Makefile.pre.in python/branches/py3k/Modules/mmapmodule.c python/branches/py3k/Parser/tokenizer.c python/branches/py3k/Tools/pynche/ColorDB.py Log: Merged revisions 60151-60159,60161-60168,60170,60172-60173,60175 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60151 | christian.heimes | 2008-01-21 14:11:15 +0100 (Mon, 21 Jan 2008) | 1 line A bunch of header files were not listed as dependencies for object files. Changes to files like Parser/parser.h weren't picked up by make. ........ r60152 | georg.brandl | 2008-01-21 15:16:46 +0100 (Mon, 21 Jan 2008) | 3 lines #1087741: make mmap.mmap the type of mmap objects, not a factory function. Allow it to be subclassed. ........ r60153 | georg.brandl | 2008-01-21 15:18:14 +0100 (Mon, 21 Jan 2008) | 2 lines mmap is an extension module. ........ r60154 | georg.brandl | 2008-01-21 17:28:13 +0100 (Mon, 21 Jan 2008) | 2 lines Fix example. ........ r60155 | georg.brandl | 2008-01-21 17:34:07 +0100 (Mon, 21 Jan 2008) | 2 lines #1555501: document plistlib and move it to the general library. ........ r60156 | georg.brandl | 2008-01-21 17:36:00 +0100 (Mon, 21 Jan 2008) | 2 lines Add a stub for bundlebuilder documentation. ........ r60157 | georg.brandl | 2008-01-21 17:46:58 +0100 (Mon, 21 Jan 2008) | 2 lines Removing bundlebuilder docs again -- it's not to be used anymore (see #779825). ........ r60158 | georg.brandl | 2008-01-21 17:51:51 +0100 (Mon, 21 Jan 2008) | 2 lines #997912: acknowledge nested scopes in tutorial. ........ r60159 | vinay.sajip | 2008-01-21 18:02:26 +0100 (Mon, 21 Jan 2008) | 1 line Fix: #1836: Off-by-one bug in TimedRotatingFileHandler rollover calculation. Patch thanks to Kathryn M. Kowalski. ........ r60161 | georg.brandl | 2008-01-21 18:13:03 +0100 (Mon, 21 Jan 2008) | 2 lines Adapt pydoc to new doc URLs. ........ r60162 | georg.brandl | 2008-01-21 18:17:00 +0100 (Mon, 21 Jan 2008) | 2 lines Fix old link. ........ r60163 | georg.brandl | 2008-01-21 18:22:06 +0100 (Mon, 21 Jan 2008) | 2 lines #1726198: replace while 1: fp.readline() with file iteration. ........ r60164 | georg.brandl | 2008-01-21 18:29:23 +0100 (Mon, 21 Jan 2008) | 2 lines Clarify $ behavior in re docstring. #1631394. ........ r60165 | vinay.sajip | 2008-01-21 18:39:22 +0100 (Mon, 21 Jan 2008) | 1 line Minor documentation change - hyperlink tidied up. ........ r60166 | georg.brandl | 2008-01-21 18:42:40 +0100 (Mon, 21 Jan 2008) | 2 lines #1530959: change distutils build dir for --with-pydebug python builds. ........ r60167 | vinay.sajip | 2008-01-21 19:16:05 +0100 (Mon, 21 Jan 2008) | 1 line Updated to include news on recent logging fixes and documentation changes. ........ r60168 | georg.brandl | 2008-01-21 19:35:49 +0100 (Mon, 21 Jan 2008) | 3 lines Issue #1882: when compiling code from a string, encoding cookies in the second line of code were not always recognized correctly. ........ r60170 | georg.brandl | 2008-01-21 19:36:51 +0100 (Mon, 21 Jan 2008) | 2 lines Add NEWS entry for #1882. ........ r60172 | georg.brandl | 2008-01-21 19:41:24 +0100 (Mon, 21 Jan 2008) | 2 lines Use original location of document, which has translations. ........ r60173 | walter.doerwald | 2008-01-21 21:18:04 +0100 (Mon, 21 Jan 2008) | 2 lines Follow PEP 8 in module docstring. ........ r60175 | georg.brandl | 2008-01-21 21:20:53 +0100 (Mon, 21 Jan 2008) | 2 lines Adapt to latest doctools refactoring. ........ Modified: python/branches/py3k/Doc/bugs.rst ============================================================================== --- python/branches/py3k/Doc/bugs.rst (original) +++ python/branches/py3k/Doc/bugs.rst Mon Jan 21 21:36:10 2008 @@ -49,7 +49,7 @@ .. seealso:: - `How to Report Bugs Effectively `_ + `How to Report Bugs Effectively `_ Article which goes into some detail about how to create a useful bug report. This describes what kind of information is useful and why it is useful. Modified: python/branches/py3k/Doc/conf.py ============================================================================== --- python/branches/py3k/Doc/conf.py (original) +++ python/branches/py3k/Doc/conf.py Mon Jan 21 21:36:10 2008 @@ -7,23 +7,27 @@ # The contents of this file are pickled, so don't put values in the namespace # that aren't pickleable (module imports are okay, they're removed automatically). +import sys, os, time +sys.path.append('tools/sphinxext') + # General configuration # --------------------- # General substitutions. project = 'Python' -copyright = '1990-2007, Python Software Foundation' +copyright = '1990-%s, Python Software Foundation' % time.strftime('%Y') # The default replacements for |version| and |release|. -# If '', Sphinx looks for the Include/patchlevel.h file in the current Python -# source tree and replaces the values accordingly. # # The short X.Y version. # version = '2.6' -version = '' # The full version, including alpha/beta/rc tags. # release = '2.6a0' -release = '' + +# We look for the Include/patchlevel.h file in the current Python source tree +# and replace the values accordingly. +import patchlevel +version, release = patchlevel.get_version_info() # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: @@ -119,7 +123,6 @@ 'What\'s New in Python', 'A. M. Kuchling', 'howto'), ] # Collect all HOWTOs individually -import os latex_documents.extend(('howto/' + fn, 'howto-' + fn[:-4] + '.tex', 'HOWTO', _stdauthor, 'howto') for fn in os.listdir('howto') Modified: python/branches/py3k/Doc/extending/building.rst ============================================================================== --- python/branches/py3k/Doc/extending/building.rst (original) +++ python/branches/py3k/Doc/extending/building.rst Mon Jan 21 21:36:10 2008 @@ -80,7 +80,7 @@ description = 'This is a demo package', author = 'Martin v. Loewis', author_email = 'martin at v.loewis.de', - url = 'http://www.python.org/doc/current/ext/building.html', + url = 'http://docs.python.org/extending/building', long_description = ''' This is really just a demo package. ''', Modified: python/branches/py3k/Doc/howto/regex.rst ============================================================================== --- python/branches/py3k/Doc/howto/regex.rst (original) +++ python/branches/py3k/Doc/howto/regex.rst Mon Jan 21 21:36:10 2008 @@ -335,9 +335,8 @@ Once you have an object representing a compiled regular expression, what do you do with it? :class:`RegexObject` instances have several methods and attributes. -Only the most significant ones will be covered here; consult `the Library -Reference `_ for a complete -listing. +Only the most significant ones will be covered here; consult the :mod:`re` docs +for a complete listing. +------------------+-----------------------------------------------+ | Method/Attribute | Purpose | Modified: python/branches/py3k/Doc/library/configparser.rst ============================================================================== --- python/branches/py3k/Doc/library/configparser.rst (original) +++ python/branches/py3k/Doc/library/configparser.rst Mon Jan 21 21:36:10 2008 @@ -420,3 +420,5 @@ # Create non-existent section config.add_section(section2) opt_move(config, section1, section2, option) + else: + config.remove_option(section1, option) Modified: python/branches/py3k/Doc/library/fileformats.rst ============================================================================== --- python/branches/py3k/Doc/library/fileformats.rst (original) +++ python/branches/py3k/Doc/library/fileformats.rst Mon Jan 21 21:36:10 2008 @@ -16,3 +16,4 @@ robotparser.rst netrc.rst xdrlib.rst + plistlib.rst Modified: python/branches/py3k/Doc/library/logging.rst ============================================================================== --- python/branches/py3k/Doc/library/logging.rst (original) +++ python/branches/py3k/Doc/library/logging.rst Mon Jan 21 21:36:10 2008 @@ -1180,13 +1180,13 @@ "dict-like" object for use in the constructor:: import logging - + class ConnInfo: """ An example class which shows how an arbitrary class can be used as the 'extra' context information repository passed to a LoggerAdapter. """ - + def __getitem__(self, name): """ To allow this instance to look like a dict. @@ -1199,7 +1199,7 @@ else: result = self.__dict__.get(name, "?") return result - + def __iter__(self): """ To allow iteration over keys, which will be merged into @@ -1208,7 +1208,7 @@ keys = ["ip", "user"] keys.extend(self.__dict__.keys()) return keys.__iter__() - + if __name__ == "__main__": from random import choice levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL) @@ -2133,7 +2133,10 @@ .. versionadded:: 2.6 :class:`LoggerAdapter` instances are used to conveniently pass contextual -information into logging calls. For a usage example , see context-info_. +information into logging calls. For a usage example , see the section on +`adding contextual information to your logging output`__. + +__ context-info_ .. class:: LoggerAdapter(logger, extra) Modified: python/branches/py3k/Doc/library/mmap.rst ============================================================================== --- python/branches/py3k/Doc/library/mmap.rst (original) +++ python/branches/py3k/Doc/library/mmap.rst Mon Jan 21 21:36:10 2008 @@ -15,7 +15,7 @@ and write data starting at the current file position, and :meth:`seek` through the file to different positions. -A memory-mapped file is created by the :func:`mmap` function, which is different +A memory-mapped file is created by the :class:`mmap` constructor, which is different on Unix and on Windows. In either case you must provide a file descriptor for a file opened for update. If you wish to map an existing Python file object, use its :meth:`fileno` method to obtain the correct value for the *fileno* @@ -23,7 +23,7 @@ which returns a file descriptor directly (the file still needs to be closed when done). -For both the Unix and Windows versions of the function, *access* may be +For both the Unix and Windows versions of the constructor, *access* may be specified as an optional keyword parameter. *access* accepts one of three values: :const:`ACCESS_READ`, :const:`ACCESS_WRITE`, or :const:`ACCESS_COPY` to specify readonly, write-through or copy-on-write memory respectively. *access* @@ -37,11 +37,10 @@ To map anonymous memory, -1 should be passed as the fileno along with the length. - -.. function:: mmap(fileno, length[, tagname[, access[, offset]]]) +.. class:: mmap(fileno, length[, tagname[, access[, offset]]]) **(Windows version)** Maps *length* bytes from the file specified by the file - handle *fileno*, and returns a mmap object. If *length* is larger than the + handle *fileno*, and creates a mmap object. If *length* is larger than the current size of the file, the file is extended to contain *length* bytes. If *length* is ``0``, the maximum length of the map is the current size of the file, except that if the file is empty Windows raises an exception (you cannot @@ -59,12 +58,12 @@ *offset* must be a multiple of the ALLOCATIONGRANULARITY. -.. function:: mmap(fileno, length[, flags[, prot[, access[, offset]]]]) +.. class:: mmap(fileno, length[, flags[, prot[, access[, offset]]]]) :noindex: **(Unix version)** Maps *length* bytes from the file specified by the file descriptor *fileno*, and returns a mmap object. If *length* is ``0``, the - maximum length of the map will be the current size of the file when :func:`mmap` + maximum length of the map will be the current size of the file when :class:`mmap` is called. *flags* specifies the nature of the mapping. :const:`MAP_PRIVATE` creates a @@ -85,7 +84,7 @@ be relative to the offset from the beginning of the file. *offset* defaults to 0. *offset* must be a multiple of the PAGESIZE or ALLOCATIONGRANULARITY. - This example shows a simple way of using :func:`mmap`:: + This example shows a simple way of using :class:`mmap`:: import mmap Modified: python/branches/py3k/Doc/library/pydoc.rst ============================================================================== --- python/branches/py3k/Doc/library/pydoc.rst (original) +++ python/branches/py3k/Doc/library/pydoc.rst Mon Jan 21 21:36:10 2008 @@ -57,7 +57,7 @@ Python interpreter and typed ``import spam``. Module docs for core modules are assumed to reside in -http://www.python.org/doc/current/lib/. This can be overridden by setting the +http://docs.python.org/library/. This can be overridden by setting the :envvar:`PYTHONDOCS` environment variable to a different URL or to a local directory containing the Library Reference Manual pages. Modified: python/branches/py3k/Doc/tutorial/controlflow.rst ============================================================================== --- python/branches/py3k/Doc/tutorial/controlflow.rst (original) +++ python/branches/py3k/Doc/tutorial/controlflow.rst Mon Jan 21 21:36:10 2008 @@ -235,10 +235,11 @@ The *execution* of a function introduces a new symbol table used for the local variables of the function. More precisely, all variable assignments in a function store the value in the local symbol table; whereas variable references -first look in the local symbol table, then in the global symbol table, and then -in the table of built-in names. Thus, global variables cannot be directly -assigned a value within a function (unless named in a :keyword:`global` -statement), although they may be referenced. +first look in the local symbol table, then in the local symbol tables of +enclosing functions, then in the global symbol table, and finally in the table +of built-in names. Thus, global variables cannot be directly assigned a value +within a function (unless named in a :keyword:`global` statement), although they +may be referenced. The actual parameters (arguments) to a function call are introduced in the local symbol table of the called function when it is called; thus, arguments are Modified: python/branches/py3k/Lib/distutils/command/build.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/build.py (original) +++ python/branches/py3k/Lib/distutils/command/build.py Mon Jan 21 21:36:10 2008 @@ -66,6 +66,12 @@ def finalize_options(self): plat_specifier = ".%s-%s" % (get_platform(), sys.version[0:3]) + # Make it so Python 2.x and Python 2.x with --with-pydebug don't + # share the same build directories. Doing so confuses the build + # process for C modules + if hasattr(sys, 'gettotalrefcount'): + plat_specifier += '-pydebug' + # 'build_purelib' and 'build_platlib' just default to 'lib' and # 'lib.' under the base build directory. We only use one of # them for a given distribution, though -- Modified: python/branches/py3k/Lib/formatter.py ============================================================================== --- python/branches/py3k/Lib/formatter.py (original) +++ python/branches/py3k/Lib/formatter.py Mon Jan 21 21:36:10 2008 @@ -433,10 +433,7 @@ fp = open(sys.argv[1]) else: fp = sys.stdin - while 1: - line = fp.readline() - if not line: - break + for line in fp: if line == '\n': f.end_paragraph(1) else: Modified: python/branches/py3k/Lib/keyword.py ============================================================================== --- python/branches/py3k/Lib/keyword.py (original) +++ python/branches/py3k/Lib/keyword.py Mon Jan 21 21:36:10 2008 @@ -64,9 +64,7 @@ fp = open(iptfile) strprog = re.compile('"([^"]+)"') lines = [] - while 1: - line = fp.readline() - if not line: break + for line in fp: if '{1, "' in line: match = strprog.search(line) if match: Modified: python/branches/py3k/Lib/logging/handlers.py ============================================================================== --- python/branches/py3k/Lib/logging/handlers.py (original) +++ python/branches/py3k/Lib/logging/handlers.py Mon Jan 21 21:36:10 2008 @@ -226,13 +226,16 @@ # Days to rollover is 6 - 5 + 3, or 4. In this case, it's the # number of days left in the current week (1) plus the number # of days in the next week until the rollover day (3). + # The calculations described in 2) and 3) above need to have a day added. + # This is because the above time calculation takes us to midnight on this + # day, i.e. the start of the next day. if when.startswith('W'): day = t[6] # 0 is Monday if day != self.dayOfWeek: if day < self.dayOfWeek: - daysToWait = self.dayOfWeek - day - 1 + daysToWait = self.dayOfWeek - day else: - daysToWait = 6 - day + self.dayOfWeek + daysToWait = 6 - day + self.dayOfWeek + 1 self.rolloverAt = self.rolloverAt + (daysToWait * (60 * 60 * 24)) #print "Will rollover at %d, %d seconds from now" % (self.rolloverAt, self.rolloverAt - currentTime) Deleted: /python/branches/py3k/Lib/plat-mac/plistlib.py ============================================================================== --- /python/branches/py3k/Lib/plat-mac/plistlib.py Mon Jan 21 21:36:10 2008 +++ (empty file) @@ -1,469 +0,0 @@ -"""plistlib.py -- a tool to generate and parse MacOSX .plist files. - -The PropertList (.plist) file format is a simple XML pickle supporting -basic object types, like dictionaries, lists, numbers and strings. -Usually the top level object is a dictionary. - -To write out a plist file, use the writePlist(rootObject, pathOrFile) -function. 'rootObject' is the top level object, 'pathOrFile' is a -filename or a (writable) file object. - -To parse a plist from a file, use the readPlist(pathOrFile) function, -with a file name or a (readable) file object as the only argument. It -returns the top level object (again, usually a dictionary). - -To work with plist data in bytes objects, you can use readPlistFromBytes() -and writePlistToBytes(). - -Values can be strings, integers, floats, booleans, tuples, lists, -dictionaries, Data or datetime.datetime objects. String values (including -dictionary keys) may be unicode strings -- they will be written out as -UTF-8. - -The plist type is supported through the Data class. This is a -thin wrapper around a Python bytes object. - -Generate Plist example: - - pl = dict( - aString="Doodah", - aList=["A", "B", 12, 32.1, [1, 2, 3]], - aFloat = 0.1, - anInt = 728, - aDict=dict( - anotherString="", - aUnicodeValue=u'M\xe4ssig, Ma\xdf', - aTrueValue=True, - aFalseValue=False, - ), - someData = Data(b""), - someMoreData = Data(b"" * 10), - aDate = datetime.datetime.fromtimestamp(time.mktime(time.gmtime())), - ) - # unicode keys are possible, but a little awkward to use: - pl[u'\xc5benraa'] = "That was a unicode key." - writePlist(pl, fileName) - -Parse Plist example: - - pl = readPlist(pathOrFile) - print pl["aKey"] -""" - - -__all__ = [ - "readPlist", "writePlist", "readPlistFromBytes", "writePlistToBytes", - "readPlistFromResource", "writePlistToResource", - "Plist", "Data", "Dict" -] -# Note: the Plist and Dict classes have been deprecated. - -import binascii -import datetime -from io import BytesIO -import re - - -def readPlist(pathOrFile): - """Read a .plist file. 'pathOrFile' may either be a file name or a - (readable) file object. Return the unpacked root object (which - usually is a dictionary). - """ - didOpen = False - if isinstance(pathOrFile, str): - pathOrFile = open(pathOrFile, 'rb') - didOpen = True - p = PlistParser() - rootObject = p.parse(pathOrFile) - if didOpen: - pathOrFile.close() - return rootObject - - -def writePlist(rootObject, pathOrFile): - """Write 'rootObject' to a .plist file. 'pathOrFile' may either be a - file name or a (writable) file object. - """ - didOpen = False - if isinstance(pathOrFile, str): - pathOrFile = open(pathOrFile, 'wb') - didOpen = True - writer = PlistWriter(pathOrFile) - writer.writeln("") - writer.writeValue(rootObject) - writer.writeln("") - if didOpen: - pathOrFile.close() - - -def readPlistFromBytes(data): - """Read a plist data from a bytes object. Return the root object. - """ - return readPlist(BytesIO(data)) - - -def writePlistToBytes(rootObject): - """Return 'rootObject' as a plist-formatted bytes object. - """ - f = BytesIO() - writePlist(rootObject, f) - return f.getvalue() - - -def readPlistFromResource(path, restype='plst', resid=0): - """Read plst resource from the resource fork of path. - """ - from Carbon.File import FSRef, FSGetResourceForkName - from Carbon.Files import fsRdPerm - from Carbon import Res - fsRef = FSRef(path) - resNum = Res.FSOpenResourceFile(fsRef, FSGetResourceForkName(), fsRdPerm) - Res.UseResFile(resNum) - plistData = Res.Get1Resource(restype, resid).data - Res.CloseResFile(resNum) - return readPlistFromString(plistData) - - -def writePlistToResource(rootObject, path, restype='plst', resid=0): - """Write 'rootObject' as a plst resource to the resource fork of path. - """ - from Carbon.File import FSRef, FSGetResourceForkName - from Carbon.Files import fsRdWrPerm - from Carbon import Res - plistData = writePlistToString(rootObject) - fsRef = FSRef(path) - resNum = Res.FSOpenResourceFile(fsRef, FSGetResourceForkName(), fsRdWrPerm) - Res.UseResFile(resNum) - try: - Res.Get1Resource(restype, resid).RemoveResource() - except Res.Error: - pass - res = Res.Resource(plistData) - res.AddResource(restype, resid, '') - res.WriteResource() - Res.CloseResFile(resNum) - - -class DumbXMLWriter: - def __init__(self, file, indentLevel=0, indent="\t"): - self.file = file - self.stack = [] - self.indentLevel = indentLevel - self.indent = indent - - def beginElement(self, element): - self.stack.append(element) - self.writeln("<%s>" % element) - self.indentLevel += 1 - - def endElement(self, element): - assert self.indentLevel > 0 - assert self.stack.pop() == element - self.indentLevel -= 1 - self.writeln("" % element) - - def simpleElement(self, element, value=None): - if value is not None: - value = _escape(value) - self.writeln("<%s>%s" % (element, value, element)) - else: - self.writeln("<%s/>" % element) - - def writeln(self, line): - if line: - # plist has fixed encoding of utf-8 - if isinstance(line, str): - line = line.encode('utf-8') - self.file.write(self.indentLevel * self.indent) - self.file.write(line) - self.file.write(b'\n') - - -# Contents should conform to a subset of ISO 8601 -# (in particular, YYYY '-' MM '-' DD 'T' HH ':' MM ':' SS 'Z'. Smaller units may be omitted with -# a loss of precision) -_dateParser = re.compile(r"(?P\d\d\d\d)(?:-(?P\d\d)(?:-(?P\d\d)(?:T(?P\d\d)(?::(?P\d\d)(?::(?P\d\d))?)?)?)?)?Z") - -def _dateFromString(s): - order = ('year', 'month', 'day', 'hour', 'minute', 'second') - gd = _dateParser.match(s).groupdict() - lst = [] - for key in order: - val = gd[key] - if val is None: - break - lst.append(int(val)) - return datetime.datetime(*lst) - -def _dateToString(d): - return '%04d-%02d-%02dT%02d:%02d:%02dZ' % ( - d.year, d.month, d.day, - d.hour, d.minute, d.second - ) - - -# Regex to find any control chars, except for \t \n and \r -_controlCharPat = re.compile( - r"[\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0b\x0c\x0e\x0f" - r"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f]") - -def _escape(text): - m = _controlCharPat.search(text) - if m is not None: - raise ValueError("strings can't contains control characters; " - "use plistlib.Data instead") - text = text.replace("\r\n", "\n") # convert DOS line endings - text = text.replace("\r", "\n") # convert Mac line endings - text = text.replace("&", "&") # escape '&' - text = text.replace("<", "<") # escape '<' - text = text.replace(">", ">") # escape '>' - return text - - -PLISTHEADER = b"""\ - - -""" - -class PlistWriter(DumbXMLWriter): - - def __init__(self, file, indentLevel=0, indent=b"\t", writeHeader=1): - if writeHeader: - file.write(PLISTHEADER) - DumbXMLWriter.__init__(self, file, indentLevel, indent) - - def writeValue(self, value): - if isinstance(value, str): - self.simpleElement("string", value) - elif isinstance(value, bool): - # must switch for bool before int, as bool is a - # subclass of int... - if value: - self.simpleElement("true") - else: - self.simpleElement("false") - elif isinstance(value, int): - self.simpleElement("integer", "%d" % value) - elif isinstance(value, float): - self.simpleElement("real", repr(value)) - elif isinstance(value, dict): - self.writeDict(value) - elif isinstance(value, Data): - self.writeData(value) - elif isinstance(value, datetime.datetime): - self.simpleElement("date", _dateToString(value)) - elif isinstance(value, (tuple, list)): - self.writeArray(value) - else: - raise TypeError("unsuported type: %s" % type(value)) - - def writeData(self, data): - self.beginElement("data") - self.indentLevel -= 1 - maxlinelength = 76 - len(self.indent.replace(b"\t", b" " * 8) * - self.indentLevel) - for line in data.asBase64(maxlinelength).split(b"\n"): - if line: - self.writeln(line) - self.indentLevel += 1 - self.endElement("data") - - def writeDict(self, d): - self.beginElement("dict") - items = sorted(d.items()) - for key, value in items: - if not isinstance(key, str): - raise TypeError("keys must be strings") - self.simpleElement("key", key) - self.writeValue(value) - self.endElement("dict") - - def writeArray(self, array): - self.beginElement("array") - for value in array: - self.writeValue(value) - self.endElement("array") - - -class _InternalDict(dict): - - # This class is needed while Dict is scheduled for deprecation: - # we only need to warn when a *user* instantiates Dict or when - # the "attribute notation for dict keys" is used. - - def __getattr__(self, attr): - try: - value = self[attr] - except KeyError: - raise AttributeError(attr) - from warnings import warn - warn("Attribute access from plist dicts is deprecated, use d[key] " - "notation instead", PendingDeprecationWarning) - return value - - def __setattr__(self, attr, value): - from warnings import warn - warn("Attribute access from plist dicts is deprecated, use d[key] " - "notation instead", PendingDeprecationWarning) - self[attr] = value - - def __delattr__(self, attr): - try: - del self[attr] - except KeyError: - raise AttributeError(attr) - from warnings import warn - warn("Attribute access from plist dicts is deprecated, use d[key] " - "notation instead", PendingDeprecationWarning) - -class Dict(_InternalDict): - - def __init__(self, **kwargs): - from warnings import warn - warn("The plistlib.Dict class is deprecated, use builtin dict instead", - PendingDeprecationWarning) - super().__init__(**kwargs) - - -class Plist(_InternalDict): - - """This class has been deprecated. Use readPlist() and writePlist() - functions instead, together with regular dict objects. - """ - - def __init__(self, **kwargs): - from warnings import warn - warn("The Plist class is deprecated, use the readPlist() and " - "writePlist() functions instead", PendingDeprecationWarning) - super().__init__(**kwargs) - - def fromFile(cls, pathOrFile): - """Deprecated. Use the readPlist() function instead.""" - rootObject = readPlist(pathOrFile) - plist = cls() - plist.update(rootObject) - return plist - fromFile = classmethod(fromFile) - - def write(self, pathOrFile): - """Deprecated. Use the writePlist() function instead.""" - writePlist(self, pathOrFile) - - -def _encodeBase64(s, maxlinelength=76): - # copied from base64.encodestring(), with added maxlinelength argument - maxbinsize = (maxlinelength//4)*3 - pieces = [] - for i in range(0, len(s), maxbinsize): - chunk = s[i : i + maxbinsize] - pieces.append(binascii.b2a_base64(chunk)) - return b''.join(pieces) - -class Data: - - """Wrapper for binary data.""" - - def __init__(self, data): - if not isinstance(data, bytes): - raise TypeError("data must be as bytes") - self.data = data - - @classmethod - def fromBase64(cls, data): - # base64.decodestring just calls binascii.a2b_base64; - # it seems overkill to use both base64 and binascii. - return cls(binascii.a2b_base64(data)) - - def asBase64(self, maxlinelength=76): - return _encodeBase64(self.data, maxlinelength) - - def __eq__(self, other): - if isinstance(other, self.__class__): - return self.data == other.data - elif isinstance(other, str): - return self.data == other - else: - return id(self) == id(other) - - def __repr__(self): - return "%s(%s)" % (self.__class__.__name__, repr(self.data)) - - -class PlistParser: - - def __init__(self): - self.stack = [] - self.currentKey = None - self.root = None - - def parse(self, fileobj): - from xml.parsers.expat import ParserCreate - parser = ParserCreate() - parser.StartElementHandler = self.handleBeginElement - parser.EndElementHandler = self.handleEndElement - parser.CharacterDataHandler = self.handleData - parser.ParseFile(fileobj) - return self.root - - def handleBeginElement(self, element, attrs): - self.data = [] - handler = getattr(self, "begin_" + element, None) - if handler is not None: - handler(attrs) - - def handleEndElement(self, element): - handler = getattr(self, "end_" + element, None) - if handler is not None: - handler() - - def handleData(self, data): - self.data.append(data) - - def addObject(self, value): - if self.currentKey is not None: - self.stack[-1][self.currentKey] = value - self.currentKey = None - elif not self.stack: - # this is the root object - self.root = value - else: - self.stack[-1].append(value) - - def getData(self): - data = ''.join(self.data) - self.data = [] - return data - - # element handlers - - def begin_dict(self, attrs): - d = _InternalDict() - self.addObject(d) - self.stack.append(d) - def end_dict(self): - self.stack.pop() - - def end_key(self): - self.currentKey = self.getData() - - def begin_array(self, attrs): - a = [] - self.addObject(a) - self.stack.append(a) - def end_array(self): - self.stack.pop() - - def end_true(self): - self.addObject(True) - def end_false(self): - self.addObject(False) - def end_integer(self): - self.addObject(int(self.getData())) - def end_real(self): - self.addObject(float(self.getData())) - def end_string(self): - self.addObject(self.getData()) - def end_data(self): - self.addObject(Data.fromBase64(self.getData().encode("utf-8"))) - def end_date(self): - self.addObject(_dateFromString(self.getData())) Copied: python/branches/py3k/Lib/plistlib.py (from r60175, python/trunk/Lib/plistlib.py) ============================================================================== --- python/trunk/Lib/plistlib.py (original) +++ python/branches/py3k/Lib/plistlib.py Mon Jan 21 21:36:10 2008 @@ -60,7 +60,7 @@ import binascii import datetime -from cStringIO import StringIO +from io import StringIO import re @@ -70,7 +70,7 @@ usually is a dictionary). """ didOpen = 0 - if isinstance(pathOrFile, (str, unicode)): + if isinstance(pathOrFile, str): pathOrFile = open(pathOrFile) didOpen = 1 p = PlistParser() @@ -85,7 +85,7 @@ file name or a (writable) file object. """ didOpen = 0 - if isinstance(pathOrFile, (str, unicode)): + if isinstance(pathOrFile, str): pathOrFile = open(pathOrFile, "w") didOpen = 1 writer = PlistWriter(pathOrFile) @@ -231,7 +231,7 @@ DumbXMLWriter.__init__(self, file, indentLevel, indent) def writeValue(self, value): - if isinstance(value, (str, unicode)): + if isinstance(value, str): self.simpleElement("string", value) elif isinstance(value, bool): # must switch for bool before int, as bool is a @@ -240,7 +240,7 @@ self.simpleElement("true") else: self.simpleElement("false") - elif isinstance(value, (int, long)): + elif isinstance(value, int): self.simpleElement("integer", "%d" % value) elif isinstance(value, float): self.simpleElement("real", repr(value)) @@ -268,10 +268,10 @@ def writeDict(self, d): self.beginElement("dict") - items = d.items() + items = list(d.items()) items.sort() for key, value in items: - if not isinstance(key, (str, unicode)): + if not isinstance(key, str): raise TypeError("keys must be strings") self.simpleElement("key", key) self.writeValue(value) @@ -294,7 +294,7 @@ try: value = self[attr] except KeyError: - raise AttributeError, attr + raise AttributeError(attr) from warnings import warn warn("Attribute access from plist dicts is deprecated, use d[key] " "notation instead", PendingDeprecationWarning) @@ -310,7 +310,7 @@ try: del self[attr] except KeyError: - raise AttributeError, attr + raise AttributeError(attr) from warnings import warn warn("Attribute access from plist dicts is deprecated, use d[key] " "notation instead", PendingDeprecationWarning) Modified: python/branches/py3k/Lib/pydoc.py ============================================================================== --- python/branches/py3k/Lib/pydoc.py (original) +++ python/branches/py3k/Lib/pydoc.py Mon Jan 21 21:36:10 2008 @@ -27,7 +27,7 @@ Module docs for core modules are assumed to be in - http://www.python.org/doc/current/lib/ + http://docs.python.org/library/ This can be overridden by setting the PYTHONDOCS environment variable to a different URL or to a local directory containing the Library @@ -341,7 +341,7 @@ file = '(built-in)' docloc = os.environ.get("PYTHONDOCS", - "http://www.python.org/doc/current/lib") + "http://docs.python.org/library") basedir = os.path.join(sys.exec_prefix, "lib", "python"+sys.version[0:3]) if (isinstance(object, type(os)) and @@ -350,11 +350,10 @@ 'thread', 'zipimport') or (file.startswith(basedir) and not file.startswith(os.path.join(basedir, 'site-packages'))))): - htmlfile = "module-%s.html" % object.__name__ if docloc.startswith("http://"): - docloc = "%s/%s" % (docloc.rstrip("/"), htmlfile) + docloc = "%s/%s" % (docloc.rstrip("/"), object.__name__) else: - docloc = os.path.join(docloc, htmlfile) + docloc = os.path.join(docloc, object.__name__ + ".html") else: docloc = None return docloc @@ -537,7 +536,7 @@ url = 'http://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc) results.append('%s' % (url, escape(all))) elif pep: - url = 'http://www.python.org/peps/pep-%04d.html' % int(pep) + url = 'http://www.python.org/peps/pep-%04d' % int(pep) results.append('%s' % (url, escape(all))) elif text[end:end+1] == '(': results.append(self.namelink(name, methods, funcs, classes)) @@ -1729,7 +1728,7 @@ Welcome to Python %s! This is the online help utility. If this is your first time using Python, you should definitely check out -the tutorial on the Internet at http://www.python.org/doc/tut/. +the tutorial on the Internet at http://docs.python.org/tutorial/. Enter the name of any module, keyword, or topic to get help on writing Python programs and using Python modules. To quit this help utility and Modified: python/branches/py3k/Lib/re.py ============================================================================== --- python/branches/py3k/Lib/re.py (original) +++ python/branches/py3k/Lib/re.py Mon Jan 21 21:36:10 2008 @@ -29,7 +29,8 @@ The special characters are: "." Matches any character except a newline. "^" Matches the start of the string. - "$" Matches the end of the string. + "$" Matches the end of the string or just before the newline at + the end of the string. "*" Matches 0 or more (greedy) repetitions of the preceding RE. Greedy means that it will match as many repetitions as possible. "+" Matches 1 or more (greedy) repetitions of the preceding RE. @@ -83,8 +84,10 @@ Some of the functions in this module takes flags as optional parameters: I IGNORECASE Perform case-insensitive matching. L LOCALE Make \w, \W, \b, \B, dependent on the current locale. - M MULTILINE "^" matches the beginning of lines as well as the string. - "$" matches the end of lines as well as the string. + M MULTILINE "^" matches the beginning of lines (after a newline) + as well as the string. + "$" matches the end of lines (before a newline) as well + as the end of the string. S DOTALL "." matches any character at all, including the newline. X VERBOSE Ignore whitespace and comments for nicer looking RE's. U UNICODE Make \w, \W, \b, \B, dependent on the Unicode locale. Modified: python/branches/py3k/Lib/test/test_pep263.py ============================================================================== Binary files. No diff available. Modified: python/branches/py3k/Lib/urlparse.py ============================================================================== --- python/branches/py3k/Lib/urlparse.py (original) +++ python/branches/py3k/Lib/urlparse.py Mon Jan 21 21:36:10 2008 @@ -305,9 +305,7 @@ else: from io import StringIO fp = StringIO(test_input) - while 1: - line = fp.readline() - if not line: break + for line in fp: words = line.split() if not words: continue Modified: python/branches/py3k/Makefile.pre.in ============================================================================== --- python/branches/py3k/Makefile.pre.in (original) +++ python/branches/py3k/Makefile.pre.in Mon Jan 21 21:36:10 2008 @@ -223,6 +223,10 @@ Parser/printgrammar.o \ Parser/pgenmain.o +PARSER_HEADERS= \ + Parser/parser.h \ + Parser/tokenizer.h + PGENOBJS= $(PGENMAIN) $(POBJS) $(PGOBJS) ########################################################################## @@ -542,13 +546,16 @@ # Header files PYTHON_HEADERS= \ - Include/Python.h \ Include/Python-ast.h \ - Include/asdl.h \ + Include/Python.h \ Include/abstract.h \ + Include/asdl.h \ + Include/ast.h \ + Include/bitset.h \ Include/boolobject.h \ Include/bytes_methods.h \ Include/bytesobject.h \ + Include/cellobject.h \ Include/ceval.h \ Include/classobject.h \ Include/cobject.h \ @@ -559,48 +566,62 @@ Include/descrobject.h \ Include/dictobject.h \ Include/enumobject.h \ - Include/genobject.h \ + Include/errcode.h \ + Include/eval.h \ Include/fileobject.h \ Include/floatobject.h \ Include/formatter_unicode.h \ + Include/frameobject.h \ Include/funcobject.h \ + Include/genobject.h \ Include/import.h \ Include/intrcheck.h \ Include/iterobject.h \ Include/listobject.h \ Include/longintrepr.h \ Include/longobject.h \ + Include/marshal.h \ Include/memoryobject.h \ + Include/metagrammar.h \ Include/methodobject.h \ Include/modsupport.h \ Include/moduleobject.h \ + Include/node.h \ Include/object.h \ Include/objimpl.h \ + Include/opcode.h \ + Include/osdefs.h \ Include/parsetok.h \ Include/patchlevel.h \ + Include/pgen.h \ + Include/pgenheaders.h \ Include/pyarena.h \ Include/pydebug.h \ Include/pyerrors.h \ Include/pyfpe.h \ + Include/pygetopt.h \ Include/pymem.h \ Include/pyport.h \ Include/pystate.h \ - Include/pystrtod.h \ Include/pystrcmp.h \ + Include/pystrtod.h \ Include/pythonrun.h \ + Include/pythread.h \ Include/rangeobject.h \ - Include/setobject.h \ + Include/setobject.h \ Include/sliceobject.h \ Include/stringobject.h \ - Include/structseq.h \ Include/structmember.h \ + Include/structseq.h \ Include/symtable.h \ Include/sysmodule.h \ Include/traceback.h \ Include/tupleobject.h \ + Include/ucnhash.h \ Include/unicodeobject.h \ Include/weakrefobject.h \ - pyconfig.h + pyconfig.h \ + $(PARSER_HEADERS) $(LIBRARY_OBJS) $(MODOBJS) Modules/python.o: $(PYTHON_HEADERS) Modified: python/branches/py3k/Modules/mmapmodule.c ============================================================================== --- python/branches/py3k/Modules/mmapmodule.c (original) +++ python/branches/py3k/Modules/mmapmodule.c Mon Jan 21 21:36:10 2008 @@ -895,6 +895,9 @@ (releasebufferproc)mmap_buffer_releasebuf, }; +static PyObject * +new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict); + PyDoc_STRVAR(mmap_doc, "Windows: mmap(fileno, length[, tagname[, access[, offset]]])\n\ \n\ @@ -920,7 +923,7 @@ static PyTypeObject mmap_object_type = { - PyVarObject_HEAD_INIT(0, 0) /* patched in module init */ + PyVarObject_HEAD_INIT(NULL, 0) "mmap.mmap", /* tp_name */ sizeof(mmap_object), /* tp_size */ 0, /* tp_itemsize */ @@ -940,16 +943,26 @@ PyObject_GenericGetAttr, /*tp_getattro*/ 0, /*tp_setattro*/ &mmap_as_buffer, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ mmap_doc, /*tp_doc*/ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ + 0, /* tp_iter */ + 0, /* tp_iternext */ mmap_object_methods, /* tp_methods */ - + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + new_mmap_object, /* tp_new */ + PyObject_Del, /* tp_free */ }; @@ -981,7 +994,7 @@ #ifdef UNIX static PyObject * -new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict) +new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) { #ifdef HAVE_FSTAT struct stat st; @@ -1049,7 +1062,7 @@ } } #endif - m_obj = PyObject_New(mmap_object, &mmap_object_type); + m_obj = (mmap_object *)type->tp_alloc(type, 0); if (m_obj == NULL) {return NULL;} m_obj->data = NULL; m_obj->size = (size_t) map_size; @@ -1104,7 +1117,7 @@ #ifdef MS_WINDOWS static PyObject * -new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict) +new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) { mmap_object *m_obj; PyObject *map_size_obj = NULL, *offset_obj = NULL; @@ -1173,7 +1186,7 @@ lseek(fileno, 0, SEEK_SET); } - m_obj = PyObject_New(mmap_object, &mmap_object_type); + m_obj = (mmap_object *)type->tp_alloc(type, 0); if (m_obj == NULL) return NULL; /* Set every field to an invalid marker, so we can safely @@ -1288,13 +1301,6 @@ } #endif /* MS_WINDOWS */ -/* List of functions exported by this module */ -static struct PyMethodDef mmap_functions[] = { - {"mmap", (PyCFunction) new_mmap_object, - METH_VARARGS|METH_KEYWORDS, mmap_doc}, - {NULL, NULL} /* Sentinel */ -}; - static void setint(PyObject *d, const char *name, long value) { @@ -1305,14 +1311,14 @@ } PyMODINIT_FUNC - initmmap(void) +initmmap(void) { PyObject *dict, *module; - /* Patch the object type */ - Py_TYPE(&mmap_object_type) = &PyType_Type; + if (PyType_Ready(&mmap_object_type) < 0) + return; - module = Py_InitModule("mmap", mmap_functions); + module = Py_InitModule("mmap", NULL); if (module == NULL) return; dict = PyModule_GetDict(module); @@ -1320,6 +1326,7 @@ return; mmap_module_error = PyExc_EnvironmentError; PyDict_SetItemString(dict, "error", mmap_module_error); + PyDict_SetItemString(dict, "mmap", (PyObject*) &mmap_object_type); #ifdef PROT_EXEC setint(dict, "PROT_EXEC", PROT_EXEC); #endif Modified: python/branches/py3k/Parser/tokenizer.c ============================================================================== --- python/branches/py3k/Parser/tokenizer.c (original) +++ python/branches/py3k/Parser/tokenizer.c Mon Jan 21 21:36:10 2008 @@ -640,6 +640,7 @@ { PyObject* utf8 = NULL; const char *s; + char *newl[2] = {NULL, NULL}; int lineno = 0; tok->enc = NULL; tok->str = str; @@ -656,13 +657,23 @@ for (s = str;; s++) { if (*s == '\0') break; else if (*s == '\n') { + newl[lineno] = s; lineno++; if (lineno == 2) break; } } tok->enc = NULL; - if (!check_coding_spec(str, s - str, tok, buf_setreadl)) - return error_ret(tok); + /* need to check line 1 and 2 separately since check_coding_spec + assumes a single line as input */ + if (newl[0]) { + if (!check_coding_spec(str, newl[0] - str, tok, buf_setreadl)) + return error_ret(tok); + if (tok->enc == NULL && newl[1]) { + if (!check_coding_spec(newl[0]+1, newl[1] - newl[0], + tok, buf_setreadl)) + return error_ret(tok); + } + } if (tok->enc != NULL) { assert(utf8 == NULL); utf8 = translate_into_utf8(str, tok->enc); Modified: python/branches/py3k/Tools/pynche/ColorDB.py ============================================================================== --- python/branches/py3k/Tools/pynche/ColorDB.py (original) +++ python/branches/py3k/Tools/pynche/ColorDB.py Mon Jan 21 21:36:10 2008 @@ -50,10 +50,7 @@ self.__byname = {} # all unique names (non-aliases). built-on demand self.__allnames = None - while 1: - line = fp.readline() - if not line: - break + for line in fp: # get this compiled regular expression from derived class mo = self._re.match(line) if not mo: From python-3000-checkins at python.org Wed Jan 23 00:25:36 2008 From: python-3000-checkins at python.org (raymond.hettinger) Date: Wed, 23 Jan 2008 00:25:36 +0100 (CET) Subject: [Python-3000-checkins] r60206 - in python/branches/py3k: Doc/library/functions.rst Doc/library/itertools.rst Lib/heapq.py Lib/test/test_builtin.py Lib/test/test_iter.py Lib/test/test_itertools.py Misc/NEWS Modules/itertoolsmodule.c Python/bltinmodule.c Message-ID: <20080122232536.859491E400D@bag.python.org> Author: raymond.hettinger Date: Wed Jan 23 00:25:35 2008 New Revision: 60206 Modified: python/branches/py3k/Doc/library/functions.rst python/branches/py3k/Doc/library/itertools.rst python/branches/py3k/Lib/heapq.py python/branches/py3k/Lib/test/test_builtin.py python/branches/py3k/Lib/test/test_iter.py python/branches/py3k/Lib/test/test_itertools.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/itertoolsmodule.c python/branches/py3k/Python/bltinmodule.c Log: Replace map(None, *iterables) with zip(*iterables). Modified: python/branches/py3k/Doc/library/functions.rst ============================================================================== --- python/branches/py3k/Doc/library/functions.rst (original) +++ python/branches/py3k/Doc/library/functions.rst Wed Jan 23 00:25:35 2008 @@ -648,17 +648,7 @@ Return an iterator that applies *function* to every item of *iterable*, yielding the results. If additional *iterable* arguments are passed, *function* must take that many arguments and is applied to the items from all - iterables in parallel. If one iterable is shorter than another it is assumed - to be extended with ``None`` items. If *function* is ``None``, the identity - function is assumed; if there are multiple arguments, :func:`map` returns a - list consisting of tuples containing the corresponding items from all - iterables (a kind of transpose operation). The *iterable* arguments may be a - sequence or any iterable object; the result is always a list. - - Note that for only one *iterable* argument, ``map(function, iterable)`` is - equivalent to the generator expression ``(function(item) for item in - iterable)`` if *function* is not ``None``. - + iterables in parallel. .. function:: max(iterable[, args...], *[, key]) Modified: python/branches/py3k/Doc/library/itertools.rst ============================================================================== --- python/branches/py3k/Doc/library/itertools.rst (original) +++ python/branches/py3k/Doc/library/itertools.rst Wed Jan 23 00:25:35 2008 @@ -204,21 +204,13 @@ .. function:: imap(function, *iterables) Make an iterator that computes the function using arguments from each of the - iterables. If *function* is set to ``None``, then :func:`imap` returns the - arguments as a tuple. Like :func:`map` but stops when the shortest iterable is - exhausted instead of filling in ``None`` for shorter iterables. The reason for - the difference is that infinite iterator arguments are typically an error for - :func:`map` (because the output is fully evaluated) but represent a common and - useful way of supplying arguments to :func:`imap`. Equivalent to:: + iterables. Equivalent to:: def imap(function, *iterables): - iterables = map(iter, iterables) + iterables = [iter(it) for it in iterables) while True: - args = [next(i) for i in iterables] - if function is None: - yield tuple(args) - else: - yield function(*args) + args = [next(it) for it in iterables] + yield function(*args) .. function:: islice(iterable, [start,] stop [, step]) Modified: python/branches/py3k/Lib/heapq.py ============================================================================== --- python/branches/py3k/Lib/heapq.py (original) +++ python/branches/py3k/Lib/heapq.py Wed Jan 23 00:25:35 2008 @@ -351,7 +351,8 @@ Equivalent to: sorted(iterable, key=key)[:n] """ in1, in2 = tee(iterable) - it = izip(map(key, in1), count(), in2) # decorate + keys = in1 if key is None else map(key, in1) + it = izip(keys, count(), in2) # decorate result = _nsmallest(n, it) return list(map(itemgetter(2), result)) # undecorate @@ -362,7 +363,8 @@ Equivalent to: sorted(iterable, key=key, reverse=True)[:n] """ in1, in2 = tee(iterable) - it = izip(map(key, in1), map(neg, count()), in2) # decorate + keys = in1 if key is None else map(key, in1) + it = izip(keys, map(neg, count()), in2) # decorate result = _nlargest(n, it) return list(map(itemgetter(2), result)) # undecorate Modified: python/branches/py3k/Lib/test/test_builtin.py ============================================================================== --- python/branches/py3k/Lib/test/test_builtin.py (original) +++ python/branches/py3k/Lib/test/test_builtin.py Wed Jan 23 00:25:35 2008 @@ -1100,18 +1100,6 @@ def test_map(self): self.assertEqual( - list(map(None, 'hello')), - [('h',), ('e',), ('l',), ('l',), ('o',)] - ) - self.assertEqual( - list(map(None, 'abcd', 'efg')), - [('a', 'e'), ('b', 'f'), ('c', 'g')] - ) - self.assertEqual( - list(map(None, range(3))), - [(0,), (1,), (2,)] - ) - self.assertEqual( list(map(lambda x: x*x, range(1,4))), [1, 4, 9] ) @@ -1146,17 +1134,9 @@ [1+4+1, 3+9+1, 7+2+0] ) self.assertEqual( - list(map(None, Squares(10))), - [(0,), (1,), (4,), (9,), (16,), (25,), (36,), (49,), (64,), (81,)] - ) - self.assertEqual( list(map(int, Squares(10))), [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] ) - self.assertEqual( - list(map(None, Squares(3), Squares(2))), - [(0,0), (1,1)] - ) def Max(a, b): if a is None: return b @@ -1169,7 +1149,6 @@ ) self.assertRaises(TypeError, map) self.assertRaises(TypeError, map, lambda x: x, 42) - self.assertEqual(list(map(None, [42])), [(42,)]) class BadSeq: def __iter__(self): raise ValueError Modified: python/branches/py3k/Lib/test/test_iter.py ============================================================================== --- python/branches/py3k/Lib/test/test_iter.py (original) +++ python/branches/py3k/Lib/test/test_iter.py Wed Jan 23 00:25:35 2008 @@ -382,13 +382,10 @@ # Test map()'s use of iterators. def test_builtin_map(self): - self.assertEqual(list(map(None, SequenceClass(5))), - [(0,), (1,), (2,), (3,), (4,)]) self.assertEqual(list(map(lambda x: x+1, SequenceClass(5))), list(range(1, 6))) d = {"one": 1, "two": 2, "three": 3} - self.assertEqual(list(map(None, d)), [(k,) for k in d]) self.assertEqual(list(map(lambda k, d=d: (k, d[k]), d)), list(d.items())) dkeys = list(d.keys()) @@ -396,11 +393,6 @@ i, i < len(d) and dkeys[i] or None) for i in range(3)] - self.assertEqual(list(map(None, - d, - SequenceClass(5), - iter(d.keys()))), - expected) f = open(TESTFN, "w") try: Modified: python/branches/py3k/Lib/test/test_itertools.py ============================================================================== --- python/branches/py3k/Lib/test/test_itertools.py (original) +++ python/branches/py3k/Lib/test/test_itertools.py Wed Jan 23 00:25:35 2008 @@ -236,7 +236,7 @@ self.assertEqual(list(izip_longest('abcdef')), list(zip('abcdef'))) self.assertEqual(list(izip_longest('abc', 'defg', **{})), - list(map(None, list('abc')+[None], 'defg'))) # empty keyword dict + list(izip(list('abc')+[None], 'defg'))) # empty keyword dict self.assertRaises(TypeError, izip_longest, 3) self.assertRaises(TypeError, izip_longest, range(3), 3) @@ -281,14 +281,17 @@ def test_imap(self): self.assertEqual(list(imap(operator.pow, range(3), range(1,7))), [0**1, 1**2, 2**3]) - self.assertEqual(list(imap(None, 'abc', range(5))), + def tupleize(*args): + return args + self.assertEqual(list(imap(tupleize, 'abc', range(5))), [('a',0),('b',1),('c',2)]) - self.assertEqual(list(imap(None, 'abc', count())), + self.assertEqual(list(imap(tupleize, 'abc', count())), [('a',0),('b',1),('c',2)]) - self.assertEqual(take(2,imap(None, 'abc', count())), + self.assertEqual(take(2,imap(tupleize, 'abc', count())), [('a',0),('b',1)]) self.assertEqual(list(imap(operator.pow, [])), []) self.assertRaises(TypeError, imap) + self.assertRaises(TypeError, list, imap(None, range(3), range(3))) self.assertRaises(TypeError, imap, operator.neg) self.assertRaises(TypeError, next, imap(10, range(5))) self.assertRaises(ValueError, next, imap(errfunc, [4], [5])) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Jan 23 00:25:35 2008 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- map() and itertools.imap() no longer accept None for the first argument. + Use zip() instead. + - Issue #1769: Now int("- 1") is not allowed any more. - Object/longobject.c: long(float('nan')) raises an OverflowError instead Modified: python/branches/py3k/Modules/itertoolsmodule.c ============================================================================== --- python/branches/py3k/Modules/itertoolsmodule.c (original) +++ python/branches/py3k/Modules/itertoolsmodule.c Wed Jan 23 00:25:35 2008 @@ -1490,31 +1490,6 @@ return 0; } -/* -imap() is an iterator version of __builtins__.map() except that it does -not have the None fill-in feature. That was intentionally left out for -the following reasons: - - 1) Itertools are designed to be easily combined and chained together. - Having all tools stop with the shortest input is a unifying principle - that makes it easier to combine finite iterators (supplying data) with - infinite iterators like count() and repeat() (for supplying sequential - or constant arguments to a function). - - 2) In typical use cases for combining itertools, having one finite data - supplier run out before another is likely to be an error condition which - should not pass silently by automatically supplying None. - - 3) The use cases for automatic None fill-in are rare -- not many functions - do something useful when a parameter suddenly switches type and becomes - None. - - 4) If a need does arise, it can be met by __builtins__.map() or by - writing: chain(iterable, repeat(None)). - - 5) Similar toolsets in Haskell and SML do not have automatic None fill-in. -*/ - static PyObject * imap_next(imapobject *lz) { @@ -1536,8 +1511,6 @@ } PyTuple_SET_ITEM(argtuple, i, val); } - if (lz->func == Py_None) - return argtuple; result = PyObject_Call(lz->func, argtuple, NULL); Py_DECREF(argtuple); return result; @@ -1547,10 +1520,7 @@ "imap(func, *iterables) --> imap object\n\ \n\ Make an iterator that computes the function using arguments from\n\ -each of the iterables. Like map() except that it returns\n\ -an iterator instead of a list and that it stops when the shortest\n\ -iterable is exhausted instead of filling in None for shorter\n\ -iterables."); +each of the iterables. Stops when the shortest iterable is exhausted."); static PyTypeObject imap_type = { PyVarObject_HEAD_INIT(NULL, 0) Modified: python/branches/py3k/Python/bltinmodule.c ============================================================================== --- python/branches/py3k/Python/bltinmodule.c (original) +++ python/branches/py3k/Python/bltinmodule.c Wed Jan 23 00:25:35 2008 @@ -815,7 +815,6 @@ items of the argument iterables(s). If more than one iterable is given,\n\ the function is called with an argument list consisting of the\n\ corresponding item of each iterable, until an iterable is exhausted.\n\ -If the function is None, 'lambda *a: a' is assumed.\n\ (This is identical to itertools.imap().)"); From guido at python.org Wed Jan 23 00:48:16 2008 From: guido at python.org (Guido van Rossum) Date: Tue, 22 Jan 2008 15:48:16 -0800 Subject: [Python-3000-checkins] r60206 - in python/branches/py3k: Doc/library/functions.rst Doc/library/itertools.rst Lib/heapq.py Lib/test/test_builtin.py Lib/test/test_iter.py Lib/test/test_itertools.py Misc/NEWS Modules/itertoolsmodule.c Python/bltinmo Message-ID: On Jan 22, 2008 3:25 PM, raymond.hettinger wrote: > Author: raymond.hettinger > Date: Wed Jan 23 00:25:35 2008 > New Revision: 60206 > > Modified: > python/branches/py3k/Doc/library/functions.rst > python/branches/py3k/Doc/library/itertools.rst > python/branches/py3k/Lib/heapq.py > python/branches/py3k/Lib/test/test_builtin.py > python/branches/py3k/Lib/test/test_iter.py > python/branches/py3k/Lib/test/test_itertools.py > python/branches/py3k/Misc/NEWS > python/branches/py3k/Modules/itertoolsmodule.c > python/branches/py3k/Python/bltinmodule.c > Log: > Replace map(None, *iterables) with zip(*iterables). Cool! (a) This should be easy to backport to 2.6 -- in -3 mode map() and imap() should warn if the func argument is None. (b) What about filter(None, ... )? (c) What about map(None, one_iterable)? This doesn't return the same thing as zip(one_iterable) -- it returns the same as list(one_iterable). -- --Guido van Rossum (home page: http://www.python.org/~guido/) From python-3000-checkins at python.org Wed Jan 23 09:24:24 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Wed, 23 Jan 2008 09:24:24 +0100 (CET) Subject: [Python-3000-checkins] r60210 - in python/branches/py3k: Doc/c-api/module.rst Doc/library/functions.rst Doc/library/itertools.rst Doc/library/pprint.rst Doc/reference/lexical_analysis.rst Include/modsupport.h Include/pyport.h Include/structmember.h Lib/ftplib.py Lib/pprint.py Lib/pydoc.py Lib/site.py Lib/test/pydocfodder.py Lib/test/test_grp.py Lib/test/test_mmap.py Lib/test/test_pwd.py Lib/test/test_structmembers.py Lib/test/test_threading.py Lib/threading.py Makefile.pre.in Modules/_testcapimodule.c Modules/mmapmodule.c Parser/tokenizer.c Python/structmember.c Message-ID: <20080123082424.D14B51E400F@bag.python.org> Author: christian.heimes Date: Wed Jan 23 09:24:23 2008 New Revision: 60210 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/c-api/module.rst python/branches/py3k/Doc/library/functions.rst python/branches/py3k/Doc/library/itertools.rst python/branches/py3k/Doc/library/pprint.rst python/branches/py3k/Doc/reference/lexical_analysis.rst python/branches/py3k/Include/modsupport.h python/branches/py3k/Include/pyport.h python/branches/py3k/Include/structmember.h python/branches/py3k/Lib/ftplib.py python/branches/py3k/Lib/pprint.py python/branches/py3k/Lib/pydoc.py python/branches/py3k/Lib/site.py python/branches/py3k/Lib/test/pydocfodder.py python/branches/py3k/Lib/test/test_grp.py python/branches/py3k/Lib/test/test_mmap.py python/branches/py3k/Lib/test/test_pwd.py python/branches/py3k/Lib/test/test_structmembers.py python/branches/py3k/Lib/test/test_threading.py python/branches/py3k/Lib/threading.py python/branches/py3k/Makefile.pre.in python/branches/py3k/Modules/_testcapimodule.c python/branches/py3k/Modules/mmapmodule.c python/branches/py3k/Parser/tokenizer.c python/branches/py3k/Python/structmember.c Log: Merged revisions 60176-60209 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60178 | georg.brandl | 2008-01-21 22:05:49 +0100 (Mon, 21 Jan 2008) | 2 lines #1715: include sub-extension modules in pydoc text output. ........ r60179 | georg.brandl | 2008-01-21 22:14:21 +0100 (Mon, 21 Jan 2008) | 2 lines Add a "const" to make gcc happy. ........ r60180 | georg.brandl | 2008-01-21 22:19:07 +0100 (Mon, 21 Jan 2008) | 2 lines Add the correct build dir when building with pydebug. ........ r60181 | georg.brandl | 2008-01-21 22:23:15 +0100 (Mon, 21 Jan 2008) | 3 lines Patch #1720595: add T_BOOL to the range of structmember types. Patch by Angelo Mottola, reviewed by MvL, tests by me. ........ r60182 | georg.brandl | 2008-01-21 22:28:32 +0100 (Mon, 21 Jan 2008) | 2 lines Reformat some ugly code. ........ r60187 | brett.cannon | 2008-01-22 00:50:16 +0100 (Tue, 22 Jan 2008) | 4 lines Make's MAKEFLAGS variable is set to a string containing the single-letter arguments to Make. This means there are no hyphens. Fix the '-s' check to silence distutils to now work. ........ r60188 | gregory.p.smith | 2008-01-22 01:19:41 +0100 (Tue, 22 Jan 2008) | 3 lines accepts and closes issue #1221598: adds an optional callback to ftplib.FTP storbinary() and storlines() methods. ........ r60189 | gregory.p.smith | 2008-01-22 02:12:02 +0100 (Tue, 22 Jan 2008) | 2 lines Replace spam.acquire() try: ... finally: spam.release() with "with spam:" ........ r60190 | gregory.p.smith | 2008-01-22 02:20:42 +0100 (Tue, 22 Jan 2008) | 4 lines - Fix Issue #1703448: A joined thread could show up in the threading.enumerate() list after the join() for a brief period until it actually exited. ........ r60193 | georg.brandl | 2008-01-22 08:53:31 +0100 (Tue, 22 Jan 2008) | 2 lines Fix \xhh specs, #1889. ........ r60198 | christian.heimes | 2008-01-22 16:01:25 +0100 (Tue, 22 Jan 2008) | 1 line Fixed a missing (X) in define ........ r60199 | christian.heimes | 2008-01-22 16:25:18 +0100 (Tue, 22 Jan 2008) | 2 lines Don't repeat yourself Added the macros PyModule_AddIntMacro and PyModule_AddStringMacro. They shorten PyModule_AddIntConstant(m, "AF_INET", AF_INET) to PyModule_AddIntMacro(m, AF_INET) ........ r60201 | raymond.hettinger | 2008-01-22 20:51:41 +0100 (Tue, 22 Jan 2008) | 1 line Document when to use izip_longest(). ........ r60202 | georg.brandl | 2008-01-22 20:56:03 +0100 (Tue, 22 Jan 2008) | 2 lines Fix for #1087741 patch. ........ r60203 | raymond.hettinger | 2008-01-22 21:18:53 +0100 (Tue, 22 Jan 2008) | 1 line Give zip() the same guarantee as izip() for left-to-right evaluation. ........ r60204 | raymond.hettinger | 2008-01-22 23:09:26 +0100 (Tue, 22 Jan 2008) | 1 line Improve variable name in sample code ........ r60205 | gregory.p.smith | 2008-01-23 00:15:34 +0100 (Wed, 23 Jan 2008) | 2 lines docstring and comment updates suggested by Giampaolo Rodola' ........ r60207 | raymond.hettinger | 2008-01-23 01:04:40 +0100 (Wed, 23 Jan 2008) | 1 line Let pprint() support sets and frozensets (suggested by David Mertz). ........ r60208 | guido.van.rossum | 2008-01-23 02:18:27 +0100 (Wed, 23 Jan 2008) | 4 lines I'm tired of these tests breaking at Google due to our large number of users and groups in LDAP/NIS. So I'm limiting the extra-heavy part of the tests to passwd/group files with at most 1000 entries. ........ Modified: python/branches/py3k/Doc/c-api/module.rst ============================================================================== --- python/branches/py3k/Doc/c-api/module.rst (original) +++ python/branches/py3k/Doc/c-api/module.rst Wed Jan 23 09:24:23 2008 @@ -18,12 +18,12 @@ is exposed to Python programs as ``types.ModuleType``. -.. cfunction:: int PyModule_Check(PyObject *p) +.. cmacro:: int PyModule_Check(PyObject *p) Return true if *p* is a module object, or a subtype of a module object. -.. cfunction:: int PyModule_CheckExact(PyObject *p) +.. cmacro:: int PyModule_CheckExact(PyObject *p) Return true if *p* is a module object, but not a subtype of :cdata:`PyModule_Type`. @@ -92,3 +92,17 @@ Add a string constant to *module* as *name*. This convenience function can be used from the module's initialization function. The string *value* must be null-terminated. Return ``-1`` on error, ``0`` on success. + + +.. cmacro:: int PyModule_AddIntMacro(PyObject *module, macro) + + Add an int constant to *module*. The name and the value are taken from + *macro*. For example ``PyModule_AddConstant(module, AF_INET)`` adds the int + constant *AF_INET* with the value of *AF_INET* to *module*. + Return ``-1`` on error, ``0`` on success. + + +.. cmacro:: int PyModule_AddStringMacro(PyObject *module, macro) + + Add a string constant to *module*. + Modified: python/branches/py3k/Doc/library/functions.rst ============================================================================== --- python/branches/py3k/Doc/library/functions.rst (original) +++ python/branches/py3k/Doc/library/functions.rst Wed Jan 23 09:24:23 2008 @@ -1140,6 +1140,10 @@ sequence argument, it returns an iterator of 1-tuples. With no arguments, it returns an empty iterator. + The left-to-right evaluation order of the iterables is guaranteed. This + makes possible an idiom for clustering a data series into n-length groups + using ``zip(*[iter(s)]*n)``. + .. rubric:: Footnotes Modified: python/branches/py3k/Doc/library/itertools.rst ============================================================================== --- python/branches/py3k/Doc/library/itertools.rst (original) +++ python/branches/py3k/Doc/library/itertools.rst Wed Jan 23 09:24:23 2008 @@ -210,7 +210,10 @@ iterables = [iter(it) for it in iterables) while True: args = [next(it) for it in iterables] - yield function(*args) + if function is None: + yield tuple(args) + else: + yield function(*args) .. function:: islice(iterable, [start,] stop [, step]) @@ -252,12 +255,11 @@ When no iterables are specified, return a zero length iterator. - Note, the left-to-right evaluation order of the iterables is guaranteed. This - makes possible an idiom for clustering a data series into n-length groups using - ``izip(*[iter(s)]*n)``. For data that doesn't fit n-length groups exactly, the - last tuple can be pre-padded with fill values using ``izip(*[chain(s, - [None]*(n-1))]*n)``. + The left-to-right evaluation order of the iterables is guaranteed. This + makes possible an idiom for clustering a data series into n-length groups + using ``izip(*[iter(s)]*n)``. +<<<<<<< .working Note, when :func:`izip` is used with unequal length inputs, subsequent iteration over the longer iterables cannot reliably be continued after :func:`izip` terminates. Potentially, up to one entry will be missing from @@ -268,6 +270,11 @@ the iterator for retrieval with ``next(it)``). In general, :func:`izip` should only be used with unequal length inputs when you don't care about trailing, unmatched values from the longer iterables. +======= + :func:`izip` should only be used with unequal length inputs when you don't + care about trailing, unmatched values from the longer iterables. If those + values are important, use :func:`izip_longest` instead. +>>>>>>> .merge-right.r60208 .. function:: izip_longest(*iterables[, fillvalue]) Modified: python/branches/py3k/Doc/library/pprint.rst ============================================================================== --- python/branches/py3k/Doc/library/pprint.rst (original) +++ python/branches/py3k/Doc/library/pprint.rst Wed Jan 23 09:24:23 2008 @@ -22,6 +22,9 @@ Dictionaries are sorted by key before the display is computed. +.. versionchanged:: 2.6 + Added support for :class:`set` and :class:`frozenset`. + The :mod:`pprint` module defines one class: .. First the implementation class: Modified: python/branches/py3k/Doc/reference/lexical_analysis.rst ============================================================================== --- python/branches/py3k/Doc/reference/lexical_analysis.rst (original) +++ python/branches/py3k/Doc/reference/lexical_analysis.rst Wed Jan 23 09:24:23 2008 @@ -502,7 +502,7 @@ (4) Individual code units which form parts of a surrogate pair can be encoded using - this escape sequence. + this escape sequence. Unlike in Standard C, exactly two hex digits are required. (5) Any Unicode character can be encoded this way, but characters outside the Basic Modified: python/branches/py3k/Include/modsupport.h ============================================================================== --- python/branches/py3k/Include/modsupport.h (original) +++ python/branches/py3k/Include/modsupport.h Wed Jan 23 09:24:23 2008 @@ -40,7 +40,8 @@ PyAPI_FUNC(int) PyModule_AddObject(PyObject *, const char *, PyObject *); PyAPI_FUNC(int) PyModule_AddIntConstant(PyObject *, const char *, long); PyAPI_FUNC(int) PyModule_AddStringConstant(PyObject *, const char *, const char *); - +#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant(m, #c, c) +#define PyModule_AddStringMacro(m, c) PyModule_AddStringConstant(m, #c, c) #define PYTHON_API_VERSION 1013 #define PYTHON_API_STRING "1013" Modified: python/branches/py3k/Include/pyport.h ============================================================================== --- python/branches/py3k/Include/pyport.h (original) +++ python/branches/py3k/Include/pyport.h Wed Jan 23 09:24:23 2008 @@ -389,7 +389,7 @@ */ #ifndef Py_IS_FINITE #ifdef HAVE_FINITE -#define Py_IS_FINITE(X) finite +#define Py_IS_FINITE(X) finite(X) #else #define Py_IS_FINITE(X) (!Py_IS_INFINITY(X) && !Py_IS_NAN(X)) #endif Modified: python/branches/py3k/Include/structmember.h ============================================================================== --- python/branches/py3k/Include/structmember.h (original) +++ python/branches/py3k/Include/structmember.h Wed Jan 23 09:24:23 2008 @@ -54,6 +54,9 @@ /* Added by Jack: strings contained in the structure */ #define T_STRING_INPLACE 13 +/* Added by Lillo: bools contained in the structure (assumed char) */ +#define T_BOOL 14 + #define T_OBJECT_EX 16 /* Like T_OBJECT, but raises AttributeError when the value is NULL, instead of converting to None. */ Modified: python/branches/py3k/Lib/ftplib.py ============================================================================== --- python/branches/py3k/Lib/ftplib.py (original) +++ python/branches/py3k/Lib/ftplib.py Wed Jan 23 09:24:23 2008 @@ -32,6 +32,7 @@ # Changes and improvements suggested by Steve Majewski. # Modified by Jack to work on the mac. # Modified by Siebren to support docstrings and PASV. +# Modified by Phil Schwartz to add storbinary and storlines callbacks. # import os @@ -313,7 +314,7 @@ expected size may be None if it could not be determined. Optional `rest' argument can be a string that is sent as the - argument to a RESTART command. This is essentially a server + argument to a REST command. This is essentially a server marker used to tell the server to skip over any data up to the given marker. """ @@ -376,14 +377,18 @@ return resp def retrbinary(self, cmd, callback, blocksize=8192, rest=None): - """Retrieve data in binary mode. + """Retrieve data in binary mode. A new port is created for you. - `cmd' is a RETR command. `callback' is a callback function is - called for each block. No more than `blocksize' number of - bytes will be read from the socket. Optional `rest' is passed - to transfercmd(). + Args: + cmd: A RETR command. + callback: A single parameter callable to be called on each + block of data read. + blocksize: The maximum number of bytes to read from the + socket at one time. [default: 8192] + rest: Passed to transfercmd(). [default: None] - A new port is created for you. Return the response code. + Returns: + The response code. """ self.voidcmd('TYPE I') conn = self.transfercmd(cmd, rest) @@ -396,11 +401,17 @@ return self.voidresp() def retrlines(self, cmd, callback = None): - '''Retrieve data in line mode. - The argument is a RETR or LIST command. - The callback function (2nd argument) is called for each line, - with trailing CRLF stripped. This creates a new port for you. - print_line() is the default callback.''' + """Retrieve data in line mode. A new port is created for you. + + Args: + cmd: A RETR, LIST, NLST, or MLSD command. + callback: An optional single parameter callable that is called + for each line with the trailing CRLF stripped. + [default: print_line()] + + Returns: + The response code. + """ if callback is None: callback = print_line resp = self.sendcmd('TYPE A') conn = self.transfercmd(cmd) @@ -419,19 +430,42 @@ conn.close() return self.voidresp() - def storbinary(self, cmd, fp, blocksize=8192): - '''Store a file in binary mode.''' + def storbinary(self, cmd, fp, blocksize=8192, callback=None): + """Store a file in binary mode. A new port is created for you. + + Args: + cmd: A STOR command. + fp: A file-like object with a read(num_bytes) method. + blocksize: The maximum data size to read from fp and send over + the connection at once. [default: 8192] + callback: An optional single parameter callable that is called on + on each block of data after it is sent. [default: None] + + Returns: + The response code. + """ self.voidcmd('TYPE I') conn = self.transfercmd(cmd) while 1: buf = fp.read(blocksize) if not buf: break conn.sendall(buf) + if callback: callback(buf) conn.close() return self.voidresp() - def storlines(self, cmd, fp): - '''Store a file in line mode.''' + def storlines(self, cmd, fp, callback=None): + """Store a file in line mode. A new port is created for you. + + Args: + cmd: A STOR command. + fp: A file-like object with a readline() method. + callback: An optional single parameter callable that is called on + on each line after it is sent. [default: None] + + Returns: + The response code. + """ self.voidcmd('TYPE A') conn = self.transfercmd(cmd) while 1: @@ -441,6 +475,7 @@ if buf[-1] in CRLF: buf = buf[:-1] buf = buf + CRLF conn.sendall(buf) + if callback: callback(buf) conn.close() return self.voidresp() @@ -505,7 +540,7 @@ def size(self, filename): '''Retrieve the size of a file.''' - # Note that the RFC doesn't say anything about 'SIZE' + # The SIZE command is defined in RFC-3659 resp = self.sendcmd('SIZE ' + filename) if resp[:3] == '213': s = resp[3:].strip() Modified: python/branches/py3k/Lib/pprint.py ============================================================================== --- python/branches/py3k/Lib/pprint.py (original) +++ python/branches/py3k/Lib/pprint.py Wed Jan 23 09:24:23 2008 @@ -159,11 +159,24 @@ write('}') return - if (issubclass(typ, list) and r is list.__repr__) or \ - (issubclass(typ, tuple) and r is tuple.__repr__): + if ((issubclass(typ, list) and r is list.__repr__) or + (issubclass(typ, tuple) and r is tuple.__repr__) or + (issubclass(typ, set) and r is set.__repr__) or + (issubclass(typ, frozenset) and r is frozenset.__repr__) + ): if issubclass(typ, list): write('[') endchar = ']' + elif issubclass(typ, set): + write('{') + endchar = '}' + object = sorted(object) + indent += 4 + elif issubclass(typ, frozenset): + write('frozenset([') + endchar = '])' + object = sorted(object) + indent += 9 else: write('(') endchar = ')' Modified: python/branches/py3k/Lib/pydoc.py ============================================================================== --- python/branches/py3k/Lib/pydoc.py (original) +++ python/branches/py3k/Lib/pydoc.py Wed Jan 23 09:24:23 2008 @@ -1055,9 +1055,11 @@ if visiblename(key, all): data.append((key, value)) + modpkgs = [] + modpkgs_names = set() if hasattr(object, '__path__'): - modpkgs = [] for importer, modname, ispkg in pkgutil.iter_modules(object.__path__): + modpkgs_names.add(modname) if ispkg: modpkgs.append(modname + ' (package)') else: @@ -1067,6 +1069,16 @@ result = result + self.section( 'PACKAGE CONTENTS', '\n'.join(modpkgs)) + # Detect submodules as sometimes created by C extensions + submodules = [] + for key, value in inspect.getmembers(object, inspect.ismodule): + if value.__name__.startswith(name + '.') and key not in modpkgs_names: + submodules.append(key) + if submodules: + submodules.sort() + result = result + self.section( + 'SUBMODULES', join(submodules, '\n')) + if classes: classlist = [value for key, value in classes] contents = [self.formattree( Modified: python/branches/py3k/Lib/site.py ============================================================================== --- python/branches/py3k/Lib/site.py (original) +++ python/branches/py3k/Lib/site.py Wed Jan 23 09:24:23 2008 @@ -96,6 +96,8 @@ (especially for Guido :-)""" from distutils.util import get_platform s = "build/lib.%s-%.3s" % (get_platform(), sys.version) + if hasattr(sys, 'gettotalrefcount'): + s += '-pydebug' s = os.path.join(os.path.dirname(sys.path[-1]), s) sys.path.append(s) Modified: python/branches/py3k/Lib/test/pydocfodder.py ============================================================================== --- python/branches/py3k/Lib/test/pydocfodder.py (original) +++ python/branches/py3k/Lib/test/pydocfodder.py Wed Jan 23 09:24:23 2008 @@ -1,5 +1,7 @@ """Something just to look at via pydoc.""" +import types + class A_classic: "A classic class." def A_method(self): @@ -208,3 +210,7 @@ del inst.desc[self.attr] x = property(get_desc('x'), set_desc('x'), del_desc('x'), 'prop x') + + +submodule = types.ModuleType(__name__ + '.submodule', + """A submodule, which should appear in its parent's summary""") Modified: python/branches/py3k/Lib/test/test_grp.py ============================================================================== --- python/branches/py3k/Lib/test/test_grp.py (original) +++ python/branches/py3k/Lib/test/test_grp.py Wed Jan 23 09:24:23 2008 @@ -25,6 +25,9 @@ for e in entries: self.check_value(e) + if len(entries) > 1000: # Huge group file (NIS?) -- skip the rest + return + for e in entries: e2 = grp.getgrgid(e.gr_gid) self.check_value(e2) Modified: python/branches/py3k/Lib/test/test_mmap.py ============================================================================== --- python/branches/py3k/Lib/test/test_mmap.py (original) +++ python/branches/py3k/Lib/test/test_mmap.py Wed Jan 23 09:24:23 2008 @@ -419,6 +419,13 @@ except OSError: pass + def test_subclass(self): + class anon_mmap(mmap.mmap): + def __new__(klass, *args, **kwargs): + return mmap.mmap.__new__(klass, -1, *args, **kwargs) + anon_mmap(PAGESIZE) + + def test_main(): run_unittest(MmapTests) Modified: python/branches/py3k/Lib/test/test_pwd.py ============================================================================== --- python/branches/py3k/Lib/test/test_pwd.py (original) +++ python/branches/py3k/Lib/test/test_pwd.py Wed Jan 23 09:24:23 2008 @@ -35,6 +35,9 @@ entriesbyname.setdefault(e.pw_name, []).append(e) entriesbyuid.setdefault(e.pw_uid, []).append(e) + if len(entries) > 1000: # Huge passwd file (NIS?) -- skip the rest + return + # check whether the entry returned by getpwuid() # for each uid is among those from getpwall() for this uid for e in entries: Modified: python/branches/py3k/Lib/test/test_structmembers.py ============================================================================== --- python/branches/py3k/Lib/test/test_structmembers.py (original) +++ python/branches/py3k/Lib/test/test_structmembers.py Wed Jan 23 09:24:23 2008 @@ -8,52 +8,59 @@ import warnings, unittest, sys from test import test_support -ts=test_structmembersType(1,2,3,4,5,6,7,8,9.99999,10.1010101010) +ts=test_structmembersType(False, 1, 2, 3, 4, 5, 6, 7, 8, + 9.99999, 10.1010101010) class ReadWriteTests(unittest.TestCase): def test_types(self): - ts.T_BYTE=CHAR_MAX + ts.T_BOOL = True + self.assertEquals(ts.T_BOOL, True) + ts.T_BOOL = False + self.assertEquals(ts.T_BOOL, False) + self.assertRaises(TypeError, setattr, ts, 'T_BOOL', 1) + + ts.T_BYTE = CHAR_MAX self.assertEquals(ts.T_BYTE, CHAR_MAX) - ts.T_BYTE=CHAR_MIN + ts.T_BYTE = CHAR_MIN self.assertEquals(ts.T_BYTE, CHAR_MIN) - ts.T_UBYTE=UCHAR_MAX + ts.T_UBYTE = UCHAR_MAX self.assertEquals(ts.T_UBYTE, UCHAR_MAX) - ts.T_SHORT=SHRT_MAX + ts.T_SHORT = SHRT_MAX self.assertEquals(ts.T_SHORT, SHRT_MAX) - ts.T_SHORT=SHRT_MIN + ts.T_SHORT = SHRT_MIN self.assertEquals(ts.T_SHORT, SHRT_MIN) - ts.T_USHORT=USHRT_MAX + ts.T_USHORT = USHRT_MAX self.assertEquals(ts.T_USHORT, USHRT_MAX) - ts.T_INT=INT_MAX + ts.T_INT = INT_MAX self.assertEquals(ts.T_INT, INT_MAX) - ts.T_INT=INT_MIN + ts.T_INT = INT_MIN self.assertEquals(ts.T_INT, INT_MIN) - ts.T_UINT=UINT_MAX + ts.T_UINT = UINT_MAX self.assertEquals(ts.T_UINT, UINT_MAX) - ts.T_LONG=LONG_MAX + ts.T_LONG = LONG_MAX self.assertEquals(ts.T_LONG, LONG_MAX) - ts.T_LONG=LONG_MIN + ts.T_LONG = LONG_MIN self.assertEquals(ts.T_LONG, LONG_MIN) - ts.T_ULONG=ULONG_MAX + ts.T_ULONG = ULONG_MAX self.assertEquals(ts.T_ULONG, ULONG_MAX) ## T_LONGLONG and T_ULONGLONG may not be present on some platforms if hasattr(ts, 'T_LONGLONG'): - ts.T_LONGLONG=LLONG_MAX + ts.T_LONGLONG = LLONG_MAX self.assertEquals(ts.T_LONGLONG, LLONG_MAX) - ts.T_LONGLONG=LLONG_MIN + ts.T_LONGLONG = LLONG_MIN self.assertEquals(ts.T_LONGLONG, LLONG_MIN) - ts.T_ULONGLONG=ULLONG_MAX + ts.T_ULONGLONG = ULLONG_MAX self.assertEquals(ts.T_ULONGLONG, ULLONG_MAX) ## make sure these will accept a plain int as well as a long - ts.T_LONGLONG=3 + ts.T_LONGLONG = 3 self.assertEquals(ts.T_LONGLONG, 3) - ts.T_ULONGLONG=4 + ts.T_ULONGLONG = 4 self.assertEquals(ts.T_ULONGLONG, 4) @@ -63,32 +70,32 @@ def test_byte_max(self): with test_support.catch_warning() as w: - ts.T_BYTE=CHAR_MAX+1 + ts.T_BYTE = CHAR_MAX+1 self.has_warned(w) def test_byte_min(self): with test_support.catch_warning() as w: - ts.T_BYTE=CHAR_MIN-1 + ts.T_BYTE = CHAR_MIN-1 self.has_warned(w) def test_ubyte_max(self): with test_support.catch_warning() as w: - ts.T_UBYTE=UCHAR_MAX+1 + ts.T_UBYTE = UCHAR_MAX+1 self.has_warned(w) def test_short_max(self): with test_support.catch_warning() as w: - ts.T_SHORT=SHRT_MAX+1 + ts.T_SHORT = SHRT_MAX+1 self.has_warned(w) def test_short_min(self): with test_support.catch_warning() as w: - ts.T_SHORT=SHRT_MIN-1 + ts.T_SHORT = SHRT_MIN-1 self.has_warned(w) def test_ushort_max(self): with test_support.catch_warning() as w: - ts.T_USHORT=USHRT_MAX+1 + ts.T_USHORT = USHRT_MAX+1 self.has_warned(w) Modified: python/branches/py3k/Lib/test/test_threading.py ============================================================================== --- python/branches/py3k/Lib/test/test_threading.py (original) +++ python/branches/py3k/Lib/test/test_threading.py Wed Jan 23 09:24:23 2008 @@ -236,6 +236,24 @@ """]) self.assertEqual(rc, 42) + def test_enumerate_after_join(self): + # Try hard to trigger #1703448: a thread is still returned in + # threading.enumerate() after it has been join()ed. + enum = threading.enumerate + old_interval = sys.getcheckinterval() + sys.setcheckinterval(1) + try: + for i in range(1, 1000): + t = threading.Thread(target=lambda: None) + t.start() + t.join() + l = enum() + self.assertFalse(t in l, + "#1703448 triggered after %d trials: %s" % (i, l)) + finally: + sys.setcheckinterval(old_interval) + + class ThreadingExceptionTests(unittest.TestCase): # A RuntimeError should be raised if Thread.start() is called # multiple times. Modified: python/branches/py3k/Lib/threading.py ============================================================================== --- python/branches/py3k/Lib/threading.py (original) +++ python/branches/py3k/Lib/threading.py Wed Jan 23 09:24:23 2008 @@ -346,27 +346,18 @@ return self._flag def set(self): - self._cond.acquire() - try: + with self._cond: self._flag = True self._cond.notifyAll() - finally: - self._cond.release() def clear(self): - self._cond.acquire() - try: + with self._cond: self._flag = False - finally: - self._cond.release() def wait(self, timeout=None): - self._cond.acquire() - try: + with self._cond: if not self._flag: self._cond.wait(timeout) - finally: - self._cond.release() # Helper to generate new thread names _counter = 0 @@ -523,17 +514,19 @@ if __debug__: self._note("%s.__bootstrap(): normal return", self) finally: - self._stop() - try: - self._delete() - except: - pass + with _active_limbo_lock: + self._stop() + try: + # We don't call self.__delete() because it also + # grabs _active_limbo_lock. + del _active[_get_ident()] + except: + pass def _stop(self): - self._block.acquire() - self._stopped = True - self._block.notifyAll() - self._block.release() + with self._block: + self._stopped = True + self._block.notifyAll() def _delete(self): "Remove current thread from the dict of currently running threads." @@ -559,15 +552,12 @@ # since it isn't if dummy_threading is *not* being used then don't # hide the exception. - _active_limbo_lock.acquire() - try: + with _active_limbo_lock: try: del _active[_get_ident()] except KeyError: if 'dummy_threading' not in _sys.modules: raise - finally: - _active_limbo_lock.release() def join(self, timeout=None): if not self._initialized: @@ -580,8 +570,7 @@ if __debug__: if not self._stopped: self._note("%s.join(): waiting until thread stops", self) - self._block.acquire() - try: + with self._block: if timeout is None: while not self._stopped: self._block.wait() @@ -599,8 +588,6 @@ else: if __debug__: self._note("%s.join(): thread stopped", self) - finally: - self._block.release() def getName(self): assert self._initialized, "Thread.__init__() not called" Modified: python/branches/py3k/Makefile.pre.in ============================================================================== --- python/branches/py3k/Makefile.pre.in (original) +++ python/branches/py3k/Makefile.pre.in Wed Jan 23 09:24:23 2008 @@ -360,7 +360,7 @@ # Build the shared modules sharedmods: $(BUILDPYTHON) @case $$MAKEFLAGS in \ - *-s*) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' ./$(BUILDPYTHON) -E $(srcdir)/setup.py -q build;; \ + *s*) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' ./$(BUILDPYTHON) -E $(srcdir)/setup.py -q build;; \ *) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' ./$(BUILDPYTHON) -E $(srcdir)/setup.py build;; \ esac Modified: python/branches/py3k/Modules/_testcapimodule.c ============================================================================== --- python/branches/py3k/Modules/_testcapimodule.c (original) +++ python/branches/py3k/Modules/_testcapimodule.c Wed Jan 23 09:24:23 2008 @@ -930,6 +930,7 @@ #define AddSym(d, n, f, v) {PyObject *o = f(v); PyDict_SetItemString(d, n, o); Py_DECREF(o);} typedef struct { + char bool_member; char byte_member; unsigned char ubyte_member; short short_member; @@ -952,6 +953,7 @@ } test_structmembers; static struct PyMemberDef test_members[] = { + {"T_BOOL", T_BOOL, offsetof(test_structmembers, structmembers.bool_member), 0, NULL}, {"T_BYTE", T_BYTE, offsetof(test_structmembers, structmembers.byte_member), 0, NULL}, {"T_UBYTE", T_UBYTE, offsetof(test_structmembers, structmembers.ubyte_member), 0, NULL}, {"T_SHORT", T_SHORT, offsetof(test_structmembers, structmembers.short_member), 0, NULL}, @@ -970,39 +972,53 @@ }; -static PyObject *test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs){ - static char *keywords[]={"T_BYTE", "T_UBYTE", "T_SHORT", "T_USHORT", "T_INT", "T_UINT", - "T_LONG", "T_ULONG", "T_FLOAT", "T_DOUBLE", - #ifdef HAVE_LONG_LONG +static PyObject * +test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + static char *keywords[] = { + "T_BOOL", "T_BYTE", "T_UBYTE", "T_SHORT", "T_USHORT", + "T_INT", "T_UINT", "T_LONG", "T_ULONG", + "T_FLOAT", "T_DOUBLE", +#ifdef HAVE_LONG_LONG "T_LONGLONG", "T_ULONGLONG", - #endif +#endif NULL}; - static char *fmt="|bBhHiIlkfd" - #ifdef HAVE_LONG_LONG + static char *fmt = "|bbBhHiIlkfd" +#ifdef HAVE_LONG_LONG "LK" - #endif +#endif ; - test_structmembers *ob=PyObject_New(test_structmembers, type); - if (ob==NULL) + test_structmembers *ob; + ob = PyObject_New(test_structmembers, type); + if (ob == NULL) return NULL; memset(&ob->structmembers, 0, sizeof(all_structmembers)); if (!PyArg_ParseTupleAndKeywords(args, kwargs, fmt, keywords, - &ob->structmembers.byte_member, &ob->structmembers.ubyte_member, - &ob->structmembers.short_member, &ob->structmembers.ushort_member, - &ob->structmembers.int_member, &ob->structmembers.uint_member, - &ob->structmembers.long_member, &ob->structmembers.ulong_member, - &ob->structmembers.float_member, &ob->structmembers.double_member - #ifdef HAVE_LONG_LONG - ,&ob->structmembers.longlong_member, &ob->structmembers.ulonglong_member - #endif - )){ + &ob->structmembers.bool_member, + &ob->structmembers.byte_member, + &ob->structmembers.ubyte_member, + &ob->structmembers.short_member, + &ob->structmembers.ushort_member, + &ob->structmembers.int_member, + &ob->structmembers.uint_member, + &ob->structmembers.long_member, + &ob->structmembers.ulong_member, + &ob->structmembers.float_member, + &ob->structmembers.double_member +#ifdef HAVE_LONG_LONG + , &ob->structmembers.longlong_member, + &ob->structmembers.ulonglong_member +#endif + )) { Py_DECREF(ob); return NULL; - } + } return (PyObject *)ob; } -static void test_structmembers_free(PyObject *ob){ +static void +test_structmembers_free(PyObject *ob) +{ PyObject_FREE(ob); } @@ -1023,8 +1039,8 @@ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ - PyObject_GenericGetAttr, - PyObject_GenericSetAttr, + PyObject_GenericGetAttr, /* tp_getattro */ + PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ 0, /* tp_flags */ "Type containing all structmember types", @@ -1035,7 +1051,7 @@ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ - test_members, /* tp_members */ + test_members, /* tp_members */ 0, 0, 0, @@ -1044,7 +1060,7 @@ 0, 0, 0, - test_structmembers_new, /* tp_new */ + test_structmembers_new, /* tp_new */ }; Modified: python/branches/py3k/Modules/mmapmodule.c ============================================================================== --- python/branches/py3k/Modules/mmapmodule.c (original) +++ python/branches/py3k/Modules/mmapmodule.c Wed Jan 23 09:24:23 2008 @@ -130,7 +130,7 @@ } #endif /* UNIX */ - PyObject_Del(m_obj); + Py_TYPE(m_obj)->tp_free((PyObject*)m_obj); } static PyObject * Modified: python/branches/py3k/Parser/tokenizer.c ============================================================================== --- python/branches/py3k/Parser/tokenizer.c (original) +++ python/branches/py3k/Parser/tokenizer.c Wed Jan 23 09:24:23 2008 @@ -640,7 +640,7 @@ { PyObject* utf8 = NULL; const char *s; - char *newl[2] = {NULL, NULL}; + const char *newl[2] = {NULL, NULL}; int lineno = 0; tok->enc = NULL; tok->str = str; Modified: python/branches/py3k/Python/structmember.c ============================================================================== --- python/branches/py3k/Python/structmember.c (original) +++ python/branches/py3k/Python/structmember.c Wed Jan 23 09:24:23 2008 @@ -12,6 +12,9 @@ addr += l->offset; switch (l->type) { + case T_BOOL: + v = PyBool_FromLong(*(char*)addr); + break; case T_BYTE: v = PyLong_FromLong(*(char*)addr); break; @@ -113,6 +116,18 @@ } addr += l->offset; switch (l->type) { + case T_BOOL:{ + if (!PyBool_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "attribute value type must be bool"); + return -1; + } + if (v == Py_True) + *(char*)addr = (char) 1; + else + *(char*)addr = (char) 0; + break; + } case T_BYTE:{ long long_val = PyLong_AsLong(v); if ((long_val == -1) && PyErr_Occurred()) From python-3000-checkins at python.org Wed Jan 23 18:10:38 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Wed, 23 Jan 2008 18:10:38 +0100 (CET) Subject: [Python-3000-checkins] r60220 - python/branches/py3k/Lib/test/test_pep263.py Message-ID: <20080123171038.975E61E400F@bag.python.org> Author: georg.brandl Date: Wed Jan 23 18:10:38 2008 New Revision: 60220 Modified: python/branches/py3k/Lib/test/test_pep263.py Log: Fix #1913. Modified: python/branches/py3k/Lib/test/test_pep263.py ============================================================================== Binary files. No diff available. From python-3000-checkins at python.org Thu Jan 24 10:42:52 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Thu, 24 Jan 2008 10:42:52 +0100 (CET) Subject: [Python-3000-checkins] r60235 - in python/branches/py3k: Lib/idlelib/NEWS.txt Lib/idlelib/configHandler.py Lib/rational.py Lib/test/test_descr.py Lib/test/test_rational.py Lib/urllib2.py Modules/config.c.in Modules/socketmodule.c Python/bltinmodule.c Python/ceval.c Python/dynload_win.c Message-ID: <20080124094252.C0AF71E400F@bag.python.org> Author: christian.heimes Date: Thu Jan 24 10:42:52 2008 New Revision: 60235 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/idlelib/NEWS.txt python/branches/py3k/Lib/idlelib/configHandler.py python/branches/py3k/Lib/rational.py python/branches/py3k/Lib/test/test_descr.py python/branches/py3k/Lib/test/test_rational.py python/branches/py3k/Lib/urllib2.py python/branches/py3k/Modules/config.c.in python/branches/py3k/Modules/socketmodule.c python/branches/py3k/Python/bltinmodule.c python/branches/py3k/Python/ceval.c python/branches/py3k/Python/dynload_win.c Log: Merged revisions 60210-60233 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60213 | christian.heimes | 2008-01-23 15:00:25 +0100 (Wed, 23 Jan 2008) | 1 line Use Py_TYPE() instead of ->ob_type ........ r60214 | armin.rigo | 2008-01-23 15:07:13 +0100 (Wed, 23 Jan 2008) | 3 lines patch 1754489 by vlahan: improve portability of address length calculation for AF_UNIX sockets ........ r60216 | christian.heimes | 2008-01-23 15:20:50 +0100 (Wed, 23 Jan 2008) | 1 line Fixed bug #1915: Python compiles with --enable-unicode=no again. However several extension methods and modules do not work without unicode support. ........ r60221 | christian.heimes | 2008-01-23 18:15:06 +0100 (Wed, 23 Jan 2008) | 2 lines Applied #1069410 The "can't load dll" message box on Windows is suppressed while an extension is loaded by calling SetErrorMode in dynload_win.c. The error is still reported properly. ........ r60224 | guido.van.rossum | 2008-01-23 21:19:01 +0100 (Wed, 23 Jan 2008) | 2 lines Fix two crashers. ........ r60225 | kurt.kaiser | 2008-01-23 23:19:23 +0100 (Wed, 23 Jan 2008) | 3 lines Could not open files in .idlerc directory if latter was hidden on Windows. Issue 1743, Issue 1862. ........ r60226 | guido.van.rossum | 2008-01-23 23:43:27 +0100 (Wed, 23 Jan 2008) | 2 lines Fix misleading comment reported in issue #1917. ........ r60227 | kurt.kaiser | 2008-01-23 23:55:26 +0100 (Wed, 23 Jan 2008) | 2 lines There was an error on exit if no sys.exitfunc was defined. Issue 1647. ........ r60228 | guido.van.rossum | 2008-01-24 00:23:43 +0100 (Thu, 24 Jan 2008) | 2 lines Turn three recently fixed crashers into regular tests. ........ r60229 | raymond.hettinger | 2008-01-24 01:54:21 +0100 (Thu, 24 Jan 2008) | 1 line Add first-cut at an approximation function (still needs rounding tweaks). Add continued fraction conversions. ........ r60230 | raymond.hettinger | 2008-01-24 03:00:25 +0100 (Thu, 24 Jan 2008) | 1 line Minor clean-up and more tests. ........ r60231 | raymond.hettinger | 2008-01-24 03:05:06 +0100 (Thu, 24 Jan 2008) | 1 line Cleanup ........ r60232 | neal.norwitz | 2008-01-24 05:14:50 +0100 (Thu, 24 Jan 2008) | 1 line Fix the tests by restoring __import__. I think the test is still valid. ........ r60233 | neal.norwitz | 2008-01-24 08:40:51 +0100 (Thu, 24 Jan 2008) | 4 lines Fix the test_urllib2net failures that were caused by r58067. I'm not sure this is the correct fix, but at least the test passes now and should be closer to correct. ........ Modified: python/branches/py3k/Lib/idlelib/NEWS.txt ============================================================================== --- python/branches/py3k/Lib/idlelib/NEWS.txt (original) +++ python/branches/py3k/Lib/idlelib/NEWS.txt Thu Jan 24 10:42:52 2008 @@ -45,6 +45,11 @@ *Release date: XX-XXX-200X* UNRELEASED, but merged into 3.0 +- There was an error on exit if no sys.exitfunc was defined. Issue 1647. + +- Could not open files in .idlerc directory if latter was hidden on Windows. + Issue 1743, Issue 1862. + - Configure Dialog: improved layout for keybinding. Patch 1457 Tal Einat. - tabpage.py updated: tabbedPages.py now supports multiple dynamic rows Modified: python/branches/py3k/Lib/idlelib/configHandler.py ============================================================================== --- python/branches/py3k/Lib/idlelib/configHandler.py (original) +++ python/branches/py3k/Lib/idlelib/configHandler.py Thu Jan 24 10:42:52 2008 @@ -139,7 +139,12 @@ """ if not self.IsEmpty(): - cfgFile=open(self.file,'w') + fname = self.file + try: + cfgFile = open(fname, 'w') + except IOError: + fname.unlink() + cfgFile = open(fname, 'w') self.write(cfgFile) else: self.RemoveFile() Modified: python/branches/py3k/Lib/rational.py ============================================================================== --- python/branches/py3k/Lib/rational.py (original) +++ python/branches/py3k/Lib/rational.py Thu Jan 24 10:42:52 2008 @@ -171,6 +171,42 @@ else: return cls(digits, 10 ** -exp) + @classmethod + def from_continued_fraction(cls, seq): + 'Build a Rational from a continued fraction expessed as a sequence' + n, d = 1, 0 + for e in reversed(seq): + n, d = d, n + n += e * d + return cls(n, d) if seq else cls(0) + + def as_continued_fraction(self): + 'Return continued fraction expressed as a list' + n = self.numerator + d = self.denominator + cf = [] + while d: + e = int(n // d) + cf.append(e) + n -= e * d + n, d = d, n + return cf + + @classmethod + def approximate_from_float(cls, f, max_denominator): + 'Best rational approximation to f with a denominator <= max_denominator' + # XXX First cut at algorithm + # Still needs rounding rules as specified at + # http://en.wikipedia.org/wiki/Continued_fraction + cf = cls.from_float(f).as_continued_fraction() + result = Rational(0) + for i in range(1, len(cf)): + new = cls.from_continued_fraction(cf[:i]) + if new.denominator > max_denominator: + break + result = new + return result + @property def numerator(a): return a._numerator Modified: python/branches/py3k/Lib/test/test_descr.py ============================================================================== --- python/branches/py3k/Lib/test/test_descr.py (original) +++ python/branches/py3k/Lib/test/test_descr.py Thu Jan 24 10:42:52 2008 @@ -1,7 +1,7 @@ # Test enhancements related to descriptors and new-style classes -from test.test_support import verify, vereq, verbose, TestFailed, TESTFN -from test.test_support import get_original_stdout +# XXX Please, please, please, someone convert this to unittest style! +from test.test_support import verify, vereq, verbose, TestFailed, TESTFN, get_original_stdout from copy import deepcopy import types @@ -4173,6 +4173,8 @@ # ceval.c's assign_slice used to check for # tp->tp_as_sequence->sq_slice instead of # tp->tp_as_sequence->sq_ass_slice + if verbose: + print("Testing assign_slice...") class C(object): def __setitem__(self, idx, value): @@ -4182,8 +4184,72 @@ c[1:2] = 3 vereq(c.value, 3) +def test_weakref_in_del_segfault(): + # This used to segfault until r60057 + if verbose: + print("Testing weakref in del segfault...") + + import weakref + global ref + + class Target(): + def __del__(self): + global ref + ref = weakref.ref(self) + + w = Target() + del w + del ref + +def test_borrowed_ref_3_segfault(): + # This used to segfault until r60224 + if verbose: + print("Testing borrowed ref 3 segfault...") + + class KeyFunc(object): + def __call__(self, n): + del d['key'] + return 1 + + d = {'key': KeyFunc()} + try: + min(range(10), **d) + except: + pass + +def test_borrowed_ref_4_segfault(): + # This used to segfault until r60224 + if verbose: + print("Testing borrowed ref 4 segfault...") + + import types + import builtins + + class X(object): + def __getattr__(self, name): + # this is called with name == '__bases__' by PyObject_IsInstance() + # during the unbound method call -- it frees the unbound method + # itself before it invokes its im_func. + del builtins.__import__ + return () + + pseudoclass = X() + + class Y(object): + def __call__(self, *args): + # 'self' was freed already + return (self, args) + + # make an unbound method + orig_import = __import__ + try: + builtins.__import__ = types.MethodType(Y(), (pseudoclass, str)) + import spam + finally: + builtins.__import__ = orig_import + def test_main(): - weakref_segfault() # Must be first, somehow + #XXXweakref_segfault() # Must be first, somehow wrapper_segfault() # NB This one is slow do_this_first() class_docstrings() @@ -4279,6 +4345,9 @@ methodwrapper() notimplemented() test_assign_slice() + test_weakref_in_del_segfault() + test_borrowed_ref_3_segfault() + test_borrowed_ref_4_segfault() if verbose: print("All OK") Modified: python/branches/py3k/Lib/test/test_rational.py ============================================================================== --- python/branches/py3k/Lib/test/test_rational.py (original) +++ python/branches/py3k/Lib/test/test_rational.py Thu Jan 24 10:42:52 2008 @@ -135,6 +135,29 @@ TypeError, "Cannot convert sNaN to Rational.", R.from_decimal, Decimal("snan")) + def testFromContinuedFraction(self): + self.assertRaises(TypeError, R.from_continued_fraction, None) + phi = R.from_continued_fraction([1]*100) + self.assertEquals(round(phi - (1 + 5 ** 0.5) / 2, 10), 0.0) + + minusphi = R.from_continued_fraction([-1]*100) + self.assertEquals(round(minusphi + (1 + 5 ** 0.5) / 2, 10), 0.0) + + self.assertEquals(R.from_continued_fraction([0]), R(0)) + self.assertEquals(R.from_continued_fraction([]), R(0)) + + def testAsContinuedFraction(self): + self.assertEqual(R.from_float(math.pi).as_continued_fraction()[:15], + [3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 3, 3]) + self.assertEqual(R.from_float(-math.pi).as_continued_fraction()[:16], + [-4, 1, 6, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 3, 3]) + self.assertEqual(R(0).as_continued_fraction(), [0]) + + def testApproximateFromFloat(self): + self.assertEqual(R.approximate_from_float(math.pi, 10000), R(355, 113)) + self.assertEqual(R.approximate_from_float(-math.pi, 10000), R(-355, 113)) + self.assertEqual(R.approximate_from_float(0.0, 10000), R(0)) + def testConversions(self): self.assertTypedEquals(-1, trunc(R(-11, 10))) self.assertTypedEquals(-2, math.floor(R(-11, 10))) Modified: python/branches/py3k/Lib/urllib2.py ============================================================================== --- python/branches/py3k/Lib/urllib2.py (original) +++ python/branches/py3k/Lib/urllib2.py Thu Jan 24 10:42:52 2008 @@ -1286,7 +1286,7 @@ headers = mimetools.Message(sf) return addinfourl(fp, headers, req.get_full_url()) except ftplib.all_errors as msg: - raise URLError('ftp error %s' % msg).with_traceback(sys.exc_info()[2]) + raise URLError('ftp error: %s' % msg).with_traceback(sys.exc_info()[2]) def connect_ftp(self, user, passwd, host, port, dirs, timeout): fw = ftpwrapper(user, passwd, host, port, dirs, timeout) Modified: python/branches/py3k/Modules/config.c.in ============================================================================== --- python/branches/py3k/Modules/config.c.in (original) +++ python/branches/py3k/Modules/config.c.in Thu Jan 24 10:42:52 2008 @@ -43,7 +43,7 @@ /* This lives in Python/Python-ast.c */ {"_ast", init_ast}, - /* This lives in Python/_types.c */ + /* This lives in Modules/_typesmodule.c */ {"_types", init_types}, /* These entries are here for sys.builtin_module_names */ Modified: python/branches/py3k/Modules/socketmodule.c ============================================================================== --- python/branches/py3k/Modules/socketmodule.c (original) +++ python/branches/py3k/Modules/socketmodule.c Thu Jan 24 10:42:52 2008 @@ -966,7 +966,7 @@ struct sockaddr_un *a = (struct sockaddr_un *) addr; #ifdef linux if (a->sun_path[0] == 0) { /* Linux abstract namespace */ - addrlen -= (sizeof(*a) - sizeof(a->sun_path)); + addrlen -= offsetof(struct sockaddr_un, sun_path); return PyString_FromStringAndSize(a->sun_path, addrlen); } else @@ -1171,7 +1171,7 @@ #if defined(PYOS_OS2) *len_ret = sizeof(*addr); #else - *len_ret = len + sizeof(*addr) - sizeof(addr->sun_path); + *len_ret = len + offsetof(struct sockaddr_un, sun_path); #endif return 1; } Modified: python/branches/py3k/Python/bltinmodule.c ============================================================================== --- python/branches/py3k/Python/bltinmodule.c (original) +++ python/branches/py3k/Python/bltinmodule.c Thu Jan 24 10:42:52 2008 @@ -1008,11 +1008,14 @@ "%s() got an unexpected keyword argument", name); return NULL; } + Py_INCREF(keyfunc); } it = PyObject_GetIter(v); - if (it == NULL) + if (it == NULL) { + Py_XDECREF(keyfunc); return NULL; + } maxitem = NULL; /* the result */ maxval = NULL; /* the value associated with the result */ @@ -1061,6 +1064,7 @@ else Py_DECREF(maxval); Py_DECREF(it); + Py_XDECREF(keyfunc); return maxitem; Fail_it_item_and_val: @@ -1071,6 +1075,7 @@ Py_XDECREF(maxval); Py_XDECREF(maxitem); Py_DECREF(it); + Py_XDECREF(keyfunc); return NULL; } Modified: python/branches/py3k/Python/ceval.c ============================================================================== --- python/branches/py3k/Python/ceval.c (original) +++ python/branches/py3k/Python/ceval.c Thu Jan 24 10:42:52 2008 @@ -1833,6 +1833,7 @@ "__import__ not found"); break; } + Py_INCREF(x); v = POP(); u = TOP(); if (PyLong_AsLong(u) != -1 || PyErr_Occurred()) @@ -1854,11 +1855,14 @@ Py_DECREF(u); if (w == NULL) { u = POP(); + Py_DECREF(x); x = NULL; break; } READ_TIMESTAMP(intr0); - x = PyEval_CallObject(x, w); + v = x; + x = PyEval_CallObject(v, w); + Py_DECREF(v); READ_TIMESTAMP(intr1); Py_DECREF(w); SET_TOP(x); Modified: python/branches/py3k/Python/dynload_win.c ============================================================================== --- python/branches/py3k/Python/dynload_win.c (original) +++ python/branches/py3k/Python/dynload_win.c Thu Jan 24 10:42:52 2008 @@ -171,11 +171,16 @@ HINSTANCE hDLL = NULL; char pathbuf[260]; LPTSTR dummy; + unsigned int old_mode; /* We use LoadLibraryEx so Windows looks for dependent DLLs in directory of pathname first. However, Windows95 can sometimes not work correctly unless the absolute path is used. If GetFullPathName() fails, the LoadLibrary will certainly fail too, so use its error code */ + + /* Don't display a message box when Python can't load a DLL */ + old_mode = SetErrorMode(SEM_FAILCRITICALERRORS); + if (GetFullPathName(pathname, sizeof(pathbuf), pathbuf, @@ -183,6 +188,10 @@ /* XXX This call doesn't exist in Windows CE */ hDLL = LoadLibraryEx(pathname, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); + + /* restore old error mode settings */ + SetErrorMode(old_mode); + if (hDLL==NULL){ PyObject *message; unsigned int errorCode; From python-3000-checkins at python.org Thu Jan 24 11:31:31 2008 From: python-3000-checkins at python.org (thomas.heller) Date: Thu, 24 Jan 2008 11:31:31 +0100 (CET) Subject: [Python-3000-checkins] r60236 - python/branches/py3k/Lib/test/test_winreg.py Message-ID: <20080124103131.A55221E400F@bag.python.org> Author: thomas.heller Date: Thu Jan 24 11:31:31 2008 New Revision: 60236 Modified: python/branches/py3k/Lib/test/test_winreg.py Log: Fix a bug in the test. Modified: python/branches/py3k/Lib/test/test_winreg.py ============================================================================== --- python/branches/py3k/Lib/test/test_winreg.py (original) +++ python/branches/py3k/Lib/test/test_winreg.py Thu Jan 24 11:31:31 2008 @@ -73,7 +73,7 @@ key = OpenKey(root_key, test_key_name) # Read the sub-keys - with OpenKey(key, "sub_key") as sub_key: + with OpenKey(key, subkeystr) as sub_key: # Check I can enumerate over the values. index = 0 while 1: From python-3000-checkins at python.org Thu Jan 24 17:21:46 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Thu, 24 Jan 2008 17:21:46 +0100 (CET) Subject: [Python-3000-checkins] r60245 - in python/branches/py3k: Doc/library/logging.rst Doc/tutorial/stdlib2.rst Lib/logging/__init__.py Lib/logging/handlers.py Lib/test/test_descr.py Lib/test/test_largefile.py Message-ID: <20080124162146.6EBE51E402B@bag.python.org> Author: christian.heimes Date: Thu Jan 24 17:21:45 2008 New Revision: 60245 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/logging.rst python/branches/py3k/Doc/tutorial/stdlib2.rst python/branches/py3k/Lib/logging/__init__.py python/branches/py3k/Lib/logging/handlers.py python/branches/py3k/Lib/test/test_descr.py python/branches/py3k/Lib/test/test_largefile.py Log: Merged revisions 60234-60244 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60234 | gregory.p.smith | 2008-01-24 10:38:26 +0100 (Thu, 24 Jan 2008) | 4 lines Fix issue1789: The tutorial contained a misuse of the struct module. (also remove an unneeded import struct from test_largefile) ........ r60237 | vinay.sajip | 2008-01-24 13:37:08 +0100 (Thu, 24 Jan 2008) | 1 line Added optional delay argument to FileHandler and subclasses. ........ r60238 | vinay.sajip | 2008-01-24 13:37:33 +0100 (Thu, 24 Jan 2008) | 1 line Added optional delay argument to FileHandler and subclasses. ........ r60239 | vinay.sajip | 2008-01-24 13:38:30 +0100 (Thu, 24 Jan 2008) | 1 line Added documentation for optional delay argument to FileHandler and subclasses. ........ r60240 | vinay.sajip | 2008-01-24 13:43:33 +0100 (Thu, 24 Jan 2008) | 1 line Updated for optional delay argument to FileHandler and subclasses. ........ r60243 | guido.van.rossum | 2008-01-24 16:53:22 +0100 (Thu, 24 Jan 2008) | 2 lines Fi debug turd -- a call accidentally left out. ........ Modified: python/branches/py3k/Doc/library/logging.rst ============================================================================== --- python/branches/py3k/Doc/library/logging.rst (original) +++ python/branches/py3k/Doc/library/logging.rst Thu Jan 24 17:21:45 2008 @@ -1517,12 +1517,13 @@ :class:`StreamHandler`. -.. class:: FileHandler(filename[, mode[, encoding]]) +.. class:: FileHandler(filename[, mode[, encoding[, delay]]]) Returns a new instance of the :class:`FileHandler` class. The specified file is opened and used as the stream for logging. If *mode* is not specified, :const:`'a'` is used. If *encoding* is not *None*, it is used to open the file - with that encoding. By default, the file grows indefinitely. + with that encoding. If *delay* is true, then file opening is deferred until the + first call to :meth:`emit`. By default, the file grows indefinitely. .. method:: FileHandler.close() @@ -1556,12 +1557,13 @@ this value. -.. class:: WatchedFileHandler(filename[,mode[, encoding]]) +.. class:: WatchedFileHandler(filename[,mode[, encoding[, delay]]]) Returns a new instance of the :class:`WatchedFileHandler` class. The specified file is opened and used as the stream for logging. If *mode* is not specified, :const:`'a'` is used. If *encoding* is not *None*, it is used to open the file - with that encoding. By default, the file grows indefinitely. + with that encoding. If *delay* is true, then file opening is deferred until the + first call to :meth:`emit`. By default, the file grows indefinitely. .. method:: WatchedFileHandler.emit(record) @@ -1578,11 +1580,13 @@ module, supports rotation of disk log files. -.. class:: RotatingFileHandler(filename[, mode[, maxBytes[, backupCount]]]) +.. class:: RotatingFileHandler(filename[, mode[, maxBytes[, backupCount[, encoding[, delay]]]]]) Returns a new instance of the :class:`RotatingFileHandler` class. The specified file is opened and used as the stream for logging. If *mode* is not specified, - ``'a'`` is used. By default, the file grows indefinitely. + ``'a'`` is used. If *encoding* is not *None*, it is used to open the file + with that encoding. If *delay* is true, then file opening is deferred until the + first call to :meth:`emit`. By default, the file grows indefinitely. You can use the *maxBytes* and *backupCount* values to allow the file to :dfn:`rollover` at a predetermined size. When the size is about to be exceeded, @@ -1616,7 +1620,7 @@ timed intervals. -.. class:: TimedRotatingFileHandler(filename [,when [,interval [,backupCount]]]) +.. class:: TimedRotatingFileHandler(filename [,when [,interval [,backupCount[, encoding[, delay]]]]]) Returns a new instance of the :class:`TimedRotatingFileHandler` class. The specified file is opened and used as the stream for logging. On rotating it also @@ -2053,7 +2057,13 @@ record is computed using *msg* % *args*. If the formatting string contains ``'(asctime)'``, :meth:`formatTime` is called to format the event time. If there is exception information, it is formatted using :meth:`formatException` and - appended to the message. + appended to the message. Note that the formatted exception information is cached + in attribute *exc_text*. This is useful because the exception information can + be pickled and sent across the wire, but you should be careful if you have more + than one :class:`Formatter` subclass which customizes the formatting of exception + information. In this case, you will have to clear the cached value after a + formatter has done its formatting, so that the next formatter to handle the event + doesn't use the cached value but recalculates it afresh. .. method:: Formatter.formatTime(record[, datefmt]) Modified: python/branches/py3k/Doc/tutorial/stdlib2.rst ============================================================================== --- python/branches/py3k/Doc/tutorial/stdlib2.rst (original) +++ python/branches/py3k/Doc/tutorial/stdlib2.rst Thu Jan 24 17:21:45 2008 @@ -134,8 +134,10 @@ The :mod:`struct` module provides :func:`pack` and :func:`unpack` functions for working with variable length binary record formats. The following example shows -how to loop through header information in a ZIP file (with pack codes ``"H"`` -and ``"L"`` representing two and four byte unsigned numbers respectively):: +how to loop through header information in a ZIP file without using the +:mod:`zipfile` module. Pack codes ``"H"`` and ``"I"`` represent two and four +byte unsigned numbers respectively. The ``"<"`` indicates that they are +standard size and in little-endian byte order:: import struct @@ -143,7 +145,7 @@ start = 0 for i in range(3): # show the first 3 file headers start += 14 - fields = struct.unpack('LLLHH', data[start:start+16]) + fields = struct.unpack(' 0: mode = 'a' # doesn't make sense otherwise! - BaseRotatingHandler.__init__(self, filename, mode, encoding) + BaseRotatingHandler.__init__(self, filename, mode, encoding, delay) self.maxBytes = maxBytes self.backupCount = backupCount @@ -154,8 +154,8 @@ If backupCount is > 0, when rollover is done, no more than backupCount files are kept - the oldest ones are deleted. """ - def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None): - BaseRotatingHandler.__init__(self, filename, 'a', encoding) + def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None, delay=0): + BaseRotatingHandler.__init__(self, filename, 'a', encoding, delay) self.when = when.upper() self.backupCount = backupCount # Calculate the real rollover interval, which is just the number of @@ -300,10 +300,13 @@ This handler is based on a suggestion and patch by Chad J. Schroeder. """ - def __init__(self, filename, mode='a', encoding=None): - logging.FileHandler.__init__(self, filename, mode, encoding) - stat = os.stat(self.baseFilename) - self.dev, self.ino = stat[ST_DEV], stat[ST_INO] + def __init__(self, filename, mode='a', encoding=None, delay=0): + logging.FileHandler.__init__(self, filename, mode, encoding, delay) + if not os.path.exists(self.baseFilename): + self.dev, self.ino = -1, -1 + else: + stat = os.stat(self.baseFilename) + self.dev, self.ino = stat[ST_DEV], stat[ST_INO] def emit(self, record): """ @@ -319,7 +322,7 @@ else: stat = os.stat(self.baseFilename) changed = (stat[ST_DEV] != self.dev) or (stat[ST_INO] != self.ino) - if changed: + if changed and self.stream is not None: self.stream.flush() self.stream.close() self.stream = self._open() Modified: python/branches/py3k/Lib/test/test_descr.py ============================================================================== --- python/branches/py3k/Lib/test/test_descr.py (original) +++ python/branches/py3k/Lib/test/test_descr.py Thu Jan 24 17:21:45 2008 @@ -4249,7 +4249,7 @@ builtins.__import__ = orig_import def test_main(): - #XXXweakref_segfault() # Must be first, somehow + weakref_segfault() # Must be first, somehow wrapper_segfault() # NB This one is slow do_this_first() class_docstrings() Modified: python/branches/py3k/Lib/test/test_largefile.py ============================================================================== --- python/branches/py3k/Lib/test/test_largefile.py (original) +++ python/branches/py3k/Lib/test/test_largefile.py Thu Jan 24 17:21:45 2008 @@ -6,7 +6,7 @@ #---------------------------------------------------------------------- from test import test_support -import os, struct, stat, sys +import os, stat, sys try: import signal From python-3000-checkins at python.org Thu Jan 24 22:01:29 2008 From: python-3000-checkins at python.org (thomas.heller) Date: Thu, 24 Jan 2008 22:01:29 +0100 (CET) Subject: [Python-3000-checkins] r60261 - python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c python/branches/py3k-ctypes-pep3118/Modules/_ctypes/callproc.c python/branches/py3k-ctypes-pep3118/Modules/_ctypes/ctypes.h python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c Message-ID: <20080124210130.024A31E4014@bag.python.org> Author: thomas.heller Date: Thu Jan 24 22:01:29 2008 New Revision: 60261 Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c python/branches/py3k-ctypes-pep3118/Modules/_ctypes/callproc.c python/branches/py3k-ctypes-pep3118/Modules/_ctypes/ctypes.h python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c Log: Added shape and ndim field to StgDictObject. Implemented pep3118 format string, ndim, and shape for array types. Added a buffer_info(type_or_object) for testing. Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c Thu Jan 24 22:01:29 2008 @@ -1019,6 +1019,7 @@ long length; int overflow; Py_ssize_t itemsize, itemalign; + char buf[32]; typedict = PyTuple_GetItem(args, 2); if (!typedict) @@ -1058,6 +1059,27 @@ return NULL; } + if (itemdict->format[0] == '(') { + sprintf(buf, "(%d,", length); + stgdict->format = alloc_format_string(buf, itemdict->format+1); + } else { + sprintf(buf, "(%d)", length); + stgdict->format = alloc_format_string(buf, itemdict->format); + } + if (stgdict->format == NULL) { + Py_DECREF((PyObject *)stgdict); + return NULL; + } + stgdict->ndim = itemdict->ndim + 1; + stgdict->shape = PyMem_Malloc(sizeof(Py_ssize_t *) * stgdict->ndim); + if (stgdict->shape == NULL) { + Py_DECREF((PyObject *)stgdict); + return NULL; + } + stgdict->shape[0] = length; + memmove(&stgdict->shape[1], itemdict->shape, + sizeof(Py_ssize_t) * (stgdict->ndim - 1)); + itemsize = itemdict->size; if (length * itemsize < 0) { PyErr_SetString(PyExc_OverflowError, Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/callproc.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_ctypes/callproc.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_ctypes/callproc.c Thu Jan 24 22:01:29 2008 @@ -1543,7 +1543,33 @@ return Py_None; } +static PyObject * +buffer_info(PyObject *self, PyObject *arg) +{ + StgDictObject *dict = PyType_stgdict(arg); + PyObject *shape; + Py_ssize_t i; + + if (dict == NULL) + dict = PyObject_stgdict(arg); + if (dict == NULL) { + PyErr_SetString(PyExc_TypeError, + "not a ctypes type or object"); + return NULL; + } + shape = PyTuple_New(dict->ndim); + for (i = 0; i < (int)dict->ndim; ++i) + PyTuple_SET_ITEM(shape, i, PyLong_FromSsize_t(dict->shape[i])); + + if (PyErr_Occurred()) { + Py_DECREF(shape); + return NULL; + } + return Py_BuildValue("siN", dict->format, dict->ndim, shape); +} + PyMethodDef module_methods[] = { + {"buffer_info", buffer_info, METH_O, "Return buffer interface information"}, {"resize", resize, METH_VARARGS, "Resize the memory buffer of a ctypes instance"}, #ifdef CTYPES_UNICODE {"set_conversion_mode", set_conversion_mode, METH_VARARGS, set_conversion_mode_doc}, Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/ctypes.h ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_ctypes/ctypes.h (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_ctypes/ctypes.h Thu Jan 24 22:01:29 2008 @@ -200,7 +200,14 @@ PyObject *restype; /* CDataObject or NULL */ PyObject *checker; int flags; /* calling convention and such */ - char *format; /* pep3118 format string, needs PyMem_Free */ + + /* pep3118 fields, pointers neeed PyMem_Free */ + char *format; + int ndim; + Py_ssize_t *shape; +/* Py_ssize_t *strides; /* unused in ctypes */ +/* Py_ssize_t *suboffsets; /* unused in ctypes */ + } StgDictObject; /**************************************************************** Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c Thu Jan 24 22:01:29 2008 @@ -21,6 +21,8 @@ if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0) return -1; self->format = NULL; + self->ndim = 0; + self->shape = NULL; return 0; } @@ -40,6 +42,7 @@ { StgDict_clear(self); PyMem_Free(self->format); + PyMem_Free(self->shape); PyMem_Free(self->ffi_type_pointer.elements); PyDict_Type.tp_dealloc((PyObject *)self); } From python-3000-checkins at python.org Thu Jan 24 22:12:28 2008 From: python-3000-checkins at python.org (thomas.heller) Date: Thu, 24 Jan 2008 22:12:28 +0100 (CET) Subject: [Python-3000-checkins] r60262 - in python/branches/py3k-ctypes-pep3118: Doc/bugs.rst Doc/c-api/gcsupport.rst Doc/c-api/index.rst Doc/c-api/module.rst Doc/c-api/typeobj.rst Doc/conf.py Doc/extending/building.rst Doc/howto/doanddont.rst Doc/howto/regex.rst Doc/library/bdb.rst Doc/library/configparser.rst Doc/library/constants.rst Doc/library/fileformats.rst Doc/library/functions.rst Doc/library/itertools.rst Doc/library/logging.rst Doc/library/mmap.rst Doc/library/plistlib.rst Doc/library/pprint.rst Doc/library/pydoc.rst Doc/library/shutil.rst Doc/library/sys.rst Doc/library/urllib.rst Doc/reference/lexical_analysis.rst Doc/tools/sphinxext/patchlevel.py Doc/tutorial/controlflow.rst Doc/tutorial/interpreter.rst Doc/tutorial/stdlib2.rst Doc/using/cmdline.rst Doc/whatsnew/3.0.rst Include/modsupport.h Include/pyport.h Include/structmember.h Lib/distutils/command/build.py Lib/formatter.py Lib/ftplib.py Lib/heapq.py Lib/idlelib/NEWS.txt Lib/idlelib/configHandler.py Lib/keyword.py Lib/logging/__init__.py Lib/logging/handlers.py Lib/plat-mac/plistlib.py Lib/plistlib.py Lib/pprint.py Lib/pstats.py Lib/pydoc.py Lib/rational.py Lib/re.py Lib/shutil.py Lib/site.py Lib/test/pydocfodder.py Lib/test/test_builtin.py Lib/test/test_descr.py Lib/test/test_grp.py Lib/test/test_iter.py Lib/test/test_itertools.py Lib/test/test_largefile.py Lib/test/test_mmap.py Lib/test/test_operator.py Lib/test/test_pep263.py Lib/test/test_profilehooks.py Lib/test/test_pstats.py Lib/test/test_pwd.py Lib/test/test_pyclbr.py Lib/test/test_rational.py Lib/test/test_shutil.py Lib/test/test_structmembers.py Lib/test/test_threading.py Lib/test/test_trace.py Lib/test/test_urllib.py Lib/test/test_urllibnet.py Lib/test/test_winreg.py Lib/threading.py Lib/urllib.py Lib/urllib2.py Lib/urlparse.py Makefile.pre.in Misc/NEWS Modules/_testcapimodule.c Modules/config.c.in Modules/itertoolsmodule.c Modules/mmapmodule.c Modules/socketmodule.c Parser/tokenizer.c Python/bltinmodule.c Python/ceval.c Python/dynload_win.c Python/hypot.c Python/pystate.c Python/structmember.c Python/sysmodule.c Tools/pynche/ColorDB.py configure configure.in pyconfig.h.in Message-ID: <20080124211228.623A81E4013@bag.python.org> Author: thomas.heller Date: Thu Jan 24 22:12:24 2008 New Revision: 60262 Added: python/branches/py3k-ctypes-pep3118/Doc/library/plistlib.rst - copied unchanged from r60245, python/branches/py3k/Doc/library/plistlib.rst python/branches/py3k-ctypes-pep3118/Doc/tools/sphinxext/patchlevel.py - copied unchanged from r60245, python/branches/py3k/Doc/tools/sphinxext/patchlevel.py python/branches/py3k-ctypes-pep3118/Lib/plistlib.py - copied unchanged from r60245, python/branches/py3k/Lib/plistlib.py python/branches/py3k-ctypes-pep3118/Lib/test/test_pstats.py - copied unchanged from r60245, python/branches/py3k/Lib/test/test_pstats.py Removed: python/branches/py3k-ctypes-pep3118/Lib/plat-mac/plistlib.py Modified: python/branches/py3k-ctypes-pep3118/ (props changed) python/branches/py3k-ctypes-pep3118/Doc/bugs.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/gcsupport.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/index.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/module.rst python/branches/py3k-ctypes-pep3118/Doc/c-api/typeobj.rst python/branches/py3k-ctypes-pep3118/Doc/conf.py python/branches/py3k-ctypes-pep3118/Doc/extending/building.rst python/branches/py3k-ctypes-pep3118/Doc/howto/doanddont.rst python/branches/py3k-ctypes-pep3118/Doc/howto/regex.rst python/branches/py3k-ctypes-pep3118/Doc/library/bdb.rst python/branches/py3k-ctypes-pep3118/Doc/library/configparser.rst python/branches/py3k-ctypes-pep3118/Doc/library/constants.rst python/branches/py3k-ctypes-pep3118/Doc/library/fileformats.rst python/branches/py3k-ctypes-pep3118/Doc/library/functions.rst python/branches/py3k-ctypes-pep3118/Doc/library/itertools.rst python/branches/py3k-ctypes-pep3118/Doc/library/logging.rst python/branches/py3k-ctypes-pep3118/Doc/library/mmap.rst python/branches/py3k-ctypes-pep3118/Doc/library/pprint.rst python/branches/py3k-ctypes-pep3118/Doc/library/pydoc.rst python/branches/py3k-ctypes-pep3118/Doc/library/shutil.rst python/branches/py3k-ctypes-pep3118/Doc/library/sys.rst python/branches/py3k-ctypes-pep3118/Doc/library/urllib.rst python/branches/py3k-ctypes-pep3118/Doc/reference/lexical_analysis.rst python/branches/py3k-ctypes-pep3118/Doc/tutorial/controlflow.rst python/branches/py3k-ctypes-pep3118/Doc/tutorial/interpreter.rst python/branches/py3k-ctypes-pep3118/Doc/tutorial/stdlib2.rst python/branches/py3k-ctypes-pep3118/Doc/using/cmdline.rst python/branches/py3k-ctypes-pep3118/Doc/whatsnew/3.0.rst python/branches/py3k-ctypes-pep3118/Include/modsupport.h python/branches/py3k-ctypes-pep3118/Include/pyport.h python/branches/py3k-ctypes-pep3118/Include/structmember.h python/branches/py3k-ctypes-pep3118/Lib/distutils/command/build.py python/branches/py3k-ctypes-pep3118/Lib/formatter.py python/branches/py3k-ctypes-pep3118/Lib/ftplib.py python/branches/py3k-ctypes-pep3118/Lib/heapq.py python/branches/py3k-ctypes-pep3118/Lib/idlelib/NEWS.txt python/branches/py3k-ctypes-pep3118/Lib/idlelib/configHandler.py python/branches/py3k-ctypes-pep3118/Lib/keyword.py python/branches/py3k-ctypes-pep3118/Lib/logging/__init__.py python/branches/py3k-ctypes-pep3118/Lib/logging/handlers.py python/branches/py3k-ctypes-pep3118/Lib/pprint.py python/branches/py3k-ctypes-pep3118/Lib/pstats.py python/branches/py3k-ctypes-pep3118/Lib/pydoc.py python/branches/py3k-ctypes-pep3118/Lib/rational.py python/branches/py3k-ctypes-pep3118/Lib/re.py python/branches/py3k-ctypes-pep3118/Lib/shutil.py python/branches/py3k-ctypes-pep3118/Lib/site.py python/branches/py3k-ctypes-pep3118/Lib/test/pydocfodder.py python/branches/py3k-ctypes-pep3118/Lib/test/test_builtin.py python/branches/py3k-ctypes-pep3118/Lib/test/test_descr.py python/branches/py3k-ctypes-pep3118/Lib/test/test_grp.py python/branches/py3k-ctypes-pep3118/Lib/test/test_iter.py python/branches/py3k-ctypes-pep3118/Lib/test/test_itertools.py python/branches/py3k-ctypes-pep3118/Lib/test/test_largefile.py python/branches/py3k-ctypes-pep3118/Lib/test/test_mmap.py python/branches/py3k-ctypes-pep3118/Lib/test/test_operator.py python/branches/py3k-ctypes-pep3118/Lib/test/test_pep263.py python/branches/py3k-ctypes-pep3118/Lib/test/test_profilehooks.py python/branches/py3k-ctypes-pep3118/Lib/test/test_pwd.py python/branches/py3k-ctypes-pep3118/Lib/test/test_pyclbr.py python/branches/py3k-ctypes-pep3118/Lib/test/test_rational.py python/branches/py3k-ctypes-pep3118/Lib/test/test_shutil.py python/branches/py3k-ctypes-pep3118/Lib/test/test_structmembers.py python/branches/py3k-ctypes-pep3118/Lib/test/test_threading.py python/branches/py3k-ctypes-pep3118/Lib/test/test_trace.py python/branches/py3k-ctypes-pep3118/Lib/test/test_urllib.py python/branches/py3k-ctypes-pep3118/Lib/test/test_urllibnet.py python/branches/py3k-ctypes-pep3118/Lib/test/test_winreg.py python/branches/py3k-ctypes-pep3118/Lib/threading.py python/branches/py3k-ctypes-pep3118/Lib/urllib.py python/branches/py3k-ctypes-pep3118/Lib/urllib2.py python/branches/py3k-ctypes-pep3118/Lib/urlparse.py python/branches/py3k-ctypes-pep3118/Makefile.pre.in python/branches/py3k-ctypes-pep3118/Misc/NEWS python/branches/py3k-ctypes-pep3118/Modules/_testcapimodule.c python/branches/py3k-ctypes-pep3118/Modules/config.c.in python/branches/py3k-ctypes-pep3118/Modules/itertoolsmodule.c python/branches/py3k-ctypes-pep3118/Modules/mmapmodule.c python/branches/py3k-ctypes-pep3118/Modules/socketmodule.c python/branches/py3k-ctypes-pep3118/Parser/tokenizer.c python/branches/py3k-ctypes-pep3118/Python/bltinmodule.c python/branches/py3k-ctypes-pep3118/Python/ceval.c python/branches/py3k-ctypes-pep3118/Python/dynload_win.c python/branches/py3k-ctypes-pep3118/Python/hypot.c python/branches/py3k-ctypes-pep3118/Python/pystate.c python/branches/py3k-ctypes-pep3118/Python/structmember.c python/branches/py3k-ctypes-pep3118/Python/sysmodule.c python/branches/py3k-ctypes-pep3118/Tools/pynche/ColorDB.py python/branches/py3k-ctypes-pep3118/configure python/branches/py3k-ctypes-pep3118/configure.in python/branches/py3k-ctypes-pep3118/pyconfig.h.in Log: Merged revisions 60129-60130,60132,60144,60150,60176,60206,60210,60220,60235-60236,60245 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r60129 | georg.brandl | 2008-01-20 11:59:44 +0100 (So, 20 Jan 2008) | 2 lines Fix markup. ................ r60130 | georg.brandl | 2008-01-20 12:00:14 +0100 (So, 20 Jan 2008) | 2 lines Fix two oversights in C API split. ................ r60132 | georg.brandl | 2008-01-20 12:22:21 +0100 (So, 20 Jan 2008) | 4 lines Fix now-wrong :keyword: markup. Remove the section about "exec without namespace" from the "don't" howto since exec() can't overwrite names in the calling namespace anymore. ................ r60144 | christian.heimes | 2008-01-20 16:14:11 +0100 (So, 20 Jan 2008) | 54 lines Merged revisions 60124-60142 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60131 | georg.brandl | 2008-01-20 12:13:29 +0100 (Sun, 20 Jan 2008) | 3 lines #1351692: in pprint, always call format() for dict and list items to enable custom formatting of contents via subclassing PrettyPrinter. ........ r60133 | georg.brandl | 2008-01-20 12:43:03 +0100 (Sun, 20 Jan 2008) | 2 lines #1178141: add addinfourl.code to get http status code from urllib. ........ r60134 | georg.brandl | 2008-01-20 13:05:43 +0100 (Sun, 20 Jan 2008) | 4 lines #856047: respect the ``no_proxy`` env var when checking for proxies in urllib and using the other ``_proxy`` env vars. Original patch by Donovan Baarda. ........ r60135 | georg.brandl | 2008-01-20 13:18:17 +0100 (Sun, 20 Jan 2008) | 4 lines #1664522: in urllib, don't read non-existing directories in ftp mode, returning a 0-byte file -- raise an IOError instead. Original patch from Phil Knirsch. ........ r60136 | georg.brandl | 2008-01-20 13:57:47 +0100 (Sun, 20 Jan 2008) | 2 lines #799369: document possible sys.platform values. ........ r60137 | georg.brandl | 2008-01-20 14:08:37 +0100 (Sun, 20 Jan 2008) | 2 lines #652749: document the constants added to the builtins by site.py. ........ r60138 | georg.brandl | 2008-01-20 14:59:46 +0100 (Sun, 20 Jan 2008) | 2 lines #1648: add sys.gettrace() and sys.getprofile(). ........ r60139 | georg.brandl | 2008-01-20 15:17:42 +0100 (Sun, 20 Jan 2008) | 2 lines #1669: don't allow shutil.rmtree() to be called on a symlink. ........ r60140 | georg.brandl | 2008-01-20 15:20:02 +0100 (Sun, 20 Jan 2008) | 2 lines Fix test_pyclbr after urllib change. ........ r60141 | christian.heimes | 2008-01-20 15:28:28 +0100 (Sun, 20 Jan 2008) | 1 line Fixed a wrong assumption in configure.in and Include/pyport.h. The is finite function is not called isfinite() but finite(). Sorry, my fault. :) ........ r60142 | georg.brandl | 2008-01-20 15:31:27 +0100 (Sun, 20 Jan 2008) | 2 lines #1876: fix typos in test_operator. ........ ................ r60150 | christian.heimes | 2008-01-21 12:20:28 +0100 (Mo, 21 Jan 2008) | 41 lines Merged revisions 60143-60149 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60143 | georg.brandl | 2008-01-20 15:50:05 +0100 (Sun, 20 Jan 2008) | 3 lines Switch mmap from old Py_FindMethod to new PyObject_GenericGetAttr attribute access. Fixes #1087735. ........ r60145 | georg.brandl | 2008-01-20 20:40:58 +0100 (Sun, 20 Jan 2008) | 2 lines Add blurb about executable scripts on Windows. #760657. ........ r60146 | georg.brandl | 2008-01-20 20:48:40 +0100 (Sun, 20 Jan 2008) | 2 lines #1219903: fix tp_richcompare docs. ........ r60147 | georg.brandl | 2008-01-20 22:10:08 +0100 (Sun, 20 Jan 2008) | 2 lines Fix markup. ........ r60148 | gregory.p.smith | 2008-01-21 08:11:11 +0100 (Mon, 21 Jan 2008) | 14 lines Provide a sanity check during PyThreadState_DeleteCurrent() and PyThreadState_Delete() to avoid an infinite loop when the tstate list is messed up and has somehow becomes circular and does not contain the current thread. I don't know how this happens but it does, *very* rarely. On more than one hardware platform. I have not been able to reproduce it manually. Attaching to a process where its happening: it has always been in an infinite loop over a single element tstate list that is not the tstate we're looking to delete. It has been in t_bootstrap()'s call to PyThreadState_DeleteCurrent() as a pthread is exiting. ........ r60149 | georg.brandl | 2008-01-21 11:24:59 +0100 (Mon, 21 Jan 2008) | 2 lines #1269: fix a bug in pstats.add_callers() and add a unit test file for pstats. ........ ................ r60176 | georg.brandl | 2008-01-21 21:36:10 +0100 (Mo, 21 Jan 2008) | 91 lines Merged revisions 60151-60159,60161-60168,60170,60172-60173,60175 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60151 | christian.heimes | 2008-01-21 14:11:15 +0100 (Mon, 21 Jan 2008) | 1 line A bunch of header files were not listed as dependencies for object files. Changes to files like Parser/parser.h weren't picked up by make. ........ r60152 | georg.brandl | 2008-01-21 15:16:46 +0100 (Mon, 21 Jan 2008) | 3 lines #1087741: make mmap.mmap the type of mmap objects, not a factory function. Allow it to be subclassed. ........ r60153 | georg.brandl | 2008-01-21 15:18:14 +0100 (Mon, 21 Jan 2008) | 2 lines mmap is an extension module. ........ r60154 | georg.brandl | 2008-01-21 17:28:13 +0100 (Mon, 21 Jan 2008) | 2 lines Fix example. ........ r60155 | georg.brandl | 2008-01-21 17:34:07 +0100 (Mon, 21 Jan 2008) | 2 lines #1555501: document plistlib and move it to the general library. ........ r60156 | georg.brandl | 2008-01-21 17:36:00 +0100 (Mon, 21 Jan 2008) | 2 lines Add a stub for bundlebuilder documentation. ........ r60157 | georg.brandl | 2008-01-21 17:46:58 +0100 (Mon, 21 Jan 2008) | 2 lines Removing bundlebuilder docs again -- it's not to be used anymore (see #779825). ........ r60158 | georg.brandl | 2008-01-21 17:51:51 +0100 (Mon, 21 Jan 2008) | 2 lines #997912: acknowledge nested scopes in tutorial. ........ r60159 | vinay.sajip | 2008-01-21 18:02:26 +0100 (Mon, 21 Jan 2008) | 1 line Fix: #1836: Off-by-one bug in TimedRotatingFileHandler rollover calculation. Patch thanks to Kathryn M. Kowalski. ........ r60161 | georg.brandl | 2008-01-21 18:13:03 +0100 (Mon, 21 Jan 2008) | 2 lines Adapt pydoc to new doc URLs. ........ r60162 | georg.brandl | 2008-01-21 18:17:00 +0100 (Mon, 21 Jan 2008) | 2 lines Fix old link. ........ r60163 | georg.brandl | 2008-01-21 18:22:06 +0100 (Mon, 21 Jan 2008) | 2 lines #1726198: replace while 1: fp.readline() with file iteration. ........ r60164 | georg.brandl | 2008-01-21 18:29:23 +0100 (Mon, 21 Jan 2008) | 2 lines Clarify $ behavior in re docstring. #1631394. ........ r60165 | vinay.sajip | 2008-01-21 18:39:22 +0100 (Mon, 21 Jan 2008) | 1 line Minor documentation change - hyperlink tidied up. ........ r60166 | georg.brandl | 2008-01-21 18:42:40 +0100 (Mon, 21 Jan 2008) | 2 lines #1530959: change distutils build dir for --with-pydebug python builds. ........ r60167 | vinay.sajip | 2008-01-21 19:16:05 +0100 (Mon, 21 Jan 2008) | 1 line Updated to include news on recent logging fixes and documentation changes. ........ r60168 | georg.brandl | 2008-01-21 19:35:49 +0100 (Mon, 21 Jan 2008) | 3 lines Issue #1882: when compiling code from a string, encoding cookies in the second line of code were not always recognized correctly. ........ r60170 | georg.brandl | 2008-01-21 19:36:51 +0100 (Mon, 21 Jan 2008) | 2 lines Add NEWS entry for #1882. ........ r60172 | georg.brandl | 2008-01-21 19:41:24 +0100 (Mon, 21 Jan 2008) | 2 lines Use original location of document, which has translations. ........ r60173 | walter.doerwald | 2008-01-21 21:18:04 +0100 (Mon, 21 Jan 2008) | 2 lines Follow PEP 8 in module docstring. ........ r60175 | georg.brandl | 2008-01-21 21:20:53 +0100 (Mon, 21 Jan 2008) | 2 lines Adapt to latest doctools refactoring. ........ ................ r60206 | raymond.hettinger | 2008-01-23 00:25:35 +0100 (Mi, 23 Jan 2008) | 1 line Replace map(None, *iterables) with zip(*iterables). ................ r60210 | christian.heimes | 2008-01-23 09:24:23 +0100 (Mi, 23 Jan 2008) | 90 lines Merged revisions 60176-60209 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60178 | georg.brandl | 2008-01-21 22:05:49 +0100 (Mon, 21 Jan 2008) | 2 lines #1715: include sub-extension modules in pydoc text output. ........ r60179 | georg.brandl | 2008-01-21 22:14:21 +0100 (Mon, 21 Jan 2008) | 2 lines Add a "const" to make gcc happy. ........ r60180 | georg.brandl | 2008-01-21 22:19:07 +0100 (Mon, 21 Jan 2008) | 2 lines Add the correct build dir when building with pydebug. ........ r60181 | georg.brandl | 2008-01-21 22:23:15 +0100 (Mon, 21 Jan 2008) | 3 lines Patch #1720595: add T_BOOL to the range of structmember types. Patch by Angelo Mottola, reviewed by MvL, tests by me. ........ r60182 | georg.brandl | 2008-01-21 22:28:32 +0100 (Mon, 21 Jan 2008) | 2 lines Reformat some ugly code. ........ r60187 | brett.cannon | 2008-01-22 00:50:16 +0100 (Tue, 22 Jan 2008) | 4 lines Make's MAKEFLAGS variable is set to a string containing the single-letter arguments to Make. This means there are no hyphens. Fix the '-s' check to silence distutils to now work. ........ r60188 | gregory.p.smith | 2008-01-22 01:19:41 +0100 (Tue, 22 Jan 2008) | 3 lines accepts and closes issue #1221598: adds an optional callback to ftplib.FTP storbinary() and storlines() methods. ........ r60189 | gregory.p.smith | 2008-01-22 02:12:02 +0100 (Tue, 22 Jan 2008) | 2 lines Replace spam.acquire() try: ... finally: spam.release() with "with spam:" ........ r60190 | gregory.p.smith | 2008-01-22 02:20:42 +0100 (Tue, 22 Jan 2008) | 4 lines - Fix Issue #1703448: A joined thread could show up in the threading.enumerate() list after the join() for a brief period until it actually exited. ........ r60193 | georg.brandl | 2008-01-22 08:53:31 +0100 (Tue, 22 Jan 2008) | 2 lines Fix \xhh specs, #1889. ........ r60198 | christian.heimes | 2008-01-22 16:01:25 +0100 (Tue, 22 Jan 2008) | 1 line Fixed a missing (X) in define ........ r60199 | christian.heimes | 2008-01-22 16:25:18 +0100 (Tue, 22 Jan 2008) | 2 lines Don't repeat yourself Added the macros PyModule_AddIntMacro and PyModule_AddStringMacro. They shorten PyModule_AddIntConstant(m, "AF_INET", AF_INET) to PyModule_AddIntMacro(m, AF_INET) ........ r60201 | raymond.hettinger | 2008-01-22 20:51:41 +0100 (Tue, 22 Jan 2008) | 1 line Document when to use izip_longest(). ........ r60202 | georg.brandl | 2008-01-22 20:56:03 +0100 (Tue, 22 Jan 2008) | 2 lines Fix for #1087741 patch. ........ r60203 | raymond.hettinger | 2008-01-22 21:18:53 +0100 (Tue, 22 Jan 2008) | 1 line Give zip() the same guarantee as izip() for left-to-right evaluation. ........ r60204 | raymond.hettinger | 2008-01-22 23:09:26 +0100 (Tue, 22 Jan 2008) | 1 line Improve variable name in sample code ........ r60205 | gregory.p.smith | 2008-01-23 00:15:34 +0100 (Wed, 23 Jan 2008) | 2 lines docstring and comment updates suggested by Giampaolo Rodola' ........ r60207 | raymond.hettinger | 2008-01-23 01:04:40 +0100 (Wed, 23 Jan 2008) | 1 line Let pprint() support sets and frozensets (suggested by David Mertz). ........ r60208 | guido.van.rossum | 2008-01-23 02:18:27 +0100 (Wed, 23 Jan 2008) | 4 lines I'm tired of these tests breaking at Google due to our large number of users and groups in LDAP/NIS. So I'm limiting the extra-heavy part of the tests to passwd/group files with at most 1000 entries. ........ ................ r60220 | georg.brandl | 2008-01-23 18:10:38 +0100 (Mi, 23 Jan 2008) | 2 lines Fix #1913. ................ r60235 | christian.heimes | 2008-01-24 10:42:52 +0100 (Do, 24 Jan 2008) | 66 lines Merged revisions 60210-60233 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60213 | christian.heimes | 2008-01-23 15:00:25 +0100 (Wed, 23 Jan 2008) | 1 line Use Py_TYPE() instead of ->ob_type ........ r60214 | armin.rigo | 2008-01-23 15:07:13 +0100 (Wed, 23 Jan 2008) | 3 lines patch 1754489 by vlahan: improve portability of address length calculation for AF_UNIX sockets ........ r60216 | christian.heimes | 2008-01-23 15:20:50 +0100 (Wed, 23 Jan 2008) | 1 line Fixed bug #1915: Python compiles with --enable-unicode=no again. However several extension methods and modules do not work without unicode support. ........ r60221 | christian.heimes | 2008-01-23 18:15:06 +0100 (Wed, 23 Jan 2008) | 2 lines Applied #1069410 The "can't load dll" message box on Windows is suppressed while an extension is loaded by calling SetErrorMode in dynload_win.c. The error is still reported properly. ........ r60224 | guido.van.rossum | 2008-01-23 21:19:01 +0100 (Wed, 23 Jan 2008) | 2 lines Fix two crashers. ........ r60225 | kurt.kaiser | 2008-01-23 23:19:23 +0100 (Wed, 23 Jan 2008) | 3 lines Could not open files in .idlerc directory if latter was hidden on Windows. Issue 1743, Issue 1862. ........ r60226 | guido.van.rossum | 2008-01-23 23:43:27 +0100 (Wed, 23 Jan 2008) | 2 lines Fix misleading comment reported in issue #1917. ........ r60227 | kurt.kaiser | 2008-01-23 23:55:26 +0100 (Wed, 23 Jan 2008) | 2 lines There was an error on exit if no sys.exitfunc was defined. Issue 1647. ........ r60228 | guido.van.rossum | 2008-01-24 00:23:43 +0100 (Thu, 24 Jan 2008) | 2 lines Turn three recently fixed crashers into regular tests. ........ r60229 | raymond.hettinger | 2008-01-24 01:54:21 +0100 (Thu, 24 Jan 2008) | 1 line Add first-cut at an approximation function (still needs rounding tweaks). Add continued fraction conversions. ........ r60230 | raymond.hettinger | 2008-01-24 03:00:25 +0100 (Thu, 24 Jan 2008) | 1 line Minor clean-up and more tests. ........ r60231 | raymond.hettinger | 2008-01-24 03:05:06 +0100 (Thu, 24 Jan 2008) | 1 line Cleanup ........ r60232 | neal.norwitz | 2008-01-24 05:14:50 +0100 (Thu, 24 Jan 2008) | 1 line Fix the tests by restoring __import__. I think the test is still valid. ........ r60233 | neal.norwitz | 2008-01-24 08:40:51 +0100 (Thu, 24 Jan 2008) | 4 lines Fix the test_urllib2net failures that were caused by r58067. I'm not sure this is the correct fix, but at least the test passes now and should be closer to correct. ........ ................ r60236 | thomas.heller | 2008-01-24 11:31:31 +0100 (Do, 24 Jan 2008) | 1 line Fix a bug in the test. ................ r60245 | christian.heimes | 2008-01-24 17:21:45 +0100 (Do, 24 Jan 2008) | 31 lines Merged revisions 60234-60244 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60234 | gregory.p.smith | 2008-01-24 10:38:26 +0100 (Thu, 24 Jan 2008) | 4 lines Fix issue1789: The tutorial contained a misuse of the struct module. (also remove an unneeded import struct from test_largefile) ........ r60237 | vinay.sajip | 2008-01-24 13:37:08 +0100 (Thu, 24 Jan 2008) | 1 line Added optional delay argument to FileHandler and subclasses. ........ r60238 | vinay.sajip | 2008-01-24 13:37:33 +0100 (Thu, 24 Jan 2008) | 1 line Added optional delay argument to FileHandler and subclasses. ........ r60239 | vinay.sajip | 2008-01-24 13:38:30 +0100 (Thu, 24 Jan 2008) | 1 line Added documentation for optional delay argument to FileHandler and subclasses. ........ r60240 | vinay.sajip | 2008-01-24 13:43:33 +0100 (Thu, 24 Jan 2008) | 1 line Updated for optional delay argument to FileHandler and subclasses. ........ r60243 | guido.van.rossum | 2008-01-24 16:53:22 +0100 (Thu, 24 Jan 2008) | 2 lines Fi debug turd -- a call accidentally left out. ........ ................ Modified: python/branches/py3k-ctypes-pep3118/Doc/bugs.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/bugs.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/bugs.rst Thu Jan 24 22:12:24 2008 @@ -49,7 +49,7 @@ .. seealso:: - `How to Report Bugs Effectively `_ + `How to Report Bugs Effectively `_ Article which goes into some detail about how to create a useful bug report. This describes what kind of information is useful and why it is useful. Modified: python/branches/py3k-ctypes-pep3118/Doc/c-api/gcsupport.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/c-api/gcsupport.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/c-api/gcsupport.rst Thu Jan 24 22:12:24 2008 @@ -18,6 +18,7 @@ .. data:: Py_TPFLAGS_HAVE_GC + :noindex: Objects with a type with this flag set must conform with the rules documented here. For convenience these objects will be referred to as container objects. Modified: python/branches/py3k-ctypes-pep3118/Doc/c-api/index.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/c-api/index.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/c-api/index.rst Thu Jan 24 22:12:24 2008 @@ -24,4 +24,4 @@ concrete.rst init.rst memory.rst - newtypes.rst + objimpl.rst Modified: python/branches/py3k-ctypes-pep3118/Doc/c-api/module.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/c-api/module.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/c-api/module.rst Thu Jan 24 22:12:24 2008 @@ -18,12 +18,12 @@ is exposed to Python programs as ``types.ModuleType``. -.. cfunction:: int PyModule_Check(PyObject *p) +.. cmacro:: int PyModule_Check(PyObject *p) Return true if *p* is a module object, or a subtype of a module object. -.. cfunction:: int PyModule_CheckExact(PyObject *p) +.. cmacro:: int PyModule_CheckExact(PyObject *p) Return true if *p* is a module object, but not a subtype of :cdata:`PyModule_Type`. @@ -92,3 +92,17 @@ Add a string constant to *module* as *name*. This convenience function can be used from the module's initialization function. The string *value* must be null-terminated. Return ``-1`` on error, ``0`` on success. + + +.. cmacro:: int PyModule_AddIntMacro(PyObject *module, macro) + + Add an int constant to *module*. The name and the value are taken from + *macro*. For example ``PyModule_AddConstant(module, AF_INET)`` adds the int + constant *AF_INET* with the value of *AF_INET* to *module*. + Return ``-1`` on error, ``0`` on success. + + +.. cmacro:: int PyModule_AddStringMacro(PyObject *module, macro) + + Add a string constant to *module*. + Modified: python/branches/py3k-ctypes-pep3118/Doc/c-api/typeobj.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/c-api/typeobj.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/c-api/typeobj.rst Thu Jan 24 22:12:24 2008 @@ -649,13 +649,19 @@ .. cmember:: richcmpfunc PyTypeObject.tp_richcompare - An optional pointer to the rich comparison function. + An optional pointer to the rich comparison function, whose signature is + ``PyObject *tp_richcompare(PyObject *a, PyObject *b, int op)``. - The signature is the same as for :cfunc:`PyObject_RichCompare`. The function - should return the result of the comparison (usually ``Py_True`` or - ``Py_False``). If the comparison is undefined, it must return - ``Py_NotImplemented``, if another error occurred it must return ``NULL`` and set - an exception condition. + The function should return the result of the comparison (usually ``Py_True`` + or ``Py_False``). If the comparison is undefined, it must return + ``Py_NotImplemented``, if another error occurred it must return ``NULL`` and + set an exception condition. + + .. note:: + + If you want to implement a type for which only a limited set of + comparisons makes sense (e.g. ``==`` and ``!=``, but not ``<`` and + friends), directly raise :exc:`TypeError` in the rich comparison function. This field is inherited by subtypes together with :attr:`tp_compare` and :attr:`tp_hash`: a subtype inherits all three of :attr:`tp_compare`, @@ -681,10 +687,10 @@ | :const:`Py_GE` | ``>=`` | +----------------+------------+ + The next field only exists if the :const:`Py_TPFLAGS_HAVE_WEAKREFS` flag bit is set. - .. cmember:: long PyTypeObject.tp_weaklistoffset If the instances of this type are weakly referenceable, this field is greater Modified: python/branches/py3k-ctypes-pep3118/Doc/conf.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/conf.py (original) +++ python/branches/py3k-ctypes-pep3118/Doc/conf.py Thu Jan 24 22:12:24 2008 @@ -7,23 +7,27 @@ # The contents of this file are pickled, so don't put values in the namespace # that aren't pickleable (module imports are okay, they're removed automatically). +import sys, os, time +sys.path.append('tools/sphinxext') + # General configuration # --------------------- # General substitutions. project = 'Python' -copyright = '1990-2007, Python Software Foundation' +copyright = '1990-%s, Python Software Foundation' % time.strftime('%Y') # The default replacements for |version| and |release|. -# If '', Sphinx looks for the Include/patchlevel.h file in the current Python -# source tree and replaces the values accordingly. # # The short X.Y version. # version = '2.6' -version = '' # The full version, including alpha/beta/rc tags. # release = '2.6a0' -release = '' + +# We look for the Include/patchlevel.h file in the current Python source tree +# and replace the values accordingly. +import patchlevel +version, release = patchlevel.get_version_info() # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: @@ -119,7 +123,6 @@ 'What\'s New in Python', 'A. M. Kuchling', 'howto'), ] # Collect all HOWTOs individually -import os latex_documents.extend(('howto/' + fn, 'howto-' + fn[:-4] + '.tex', 'HOWTO', _stdauthor, 'howto') for fn in os.listdir('howto') Modified: python/branches/py3k-ctypes-pep3118/Doc/extending/building.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/extending/building.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/extending/building.rst Thu Jan 24 22:12:24 2008 @@ -80,7 +80,7 @@ description = 'This is a demo package', author = 'Martin v. Loewis', author_email = 'martin at v.loewis.de', - url = 'http://www.python.org/doc/current/ext/building.html', + url = 'http://docs.python.org/extending/building', long_description = ''' This is really just a demo package. ''', Modified: python/branches/py3k-ctypes-pep3118/Doc/howto/doanddont.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/howto/doanddont.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/howto/doanddont.rst Thu Jan 24 22:12:24 2008 @@ -75,39 +75,6 @@ * When the module advertises itself as ``from import *`` safe. -Unadorned :keyword:`exec` and friends -------------------------------------- - -The word "unadorned" refers to the use without an explicit dictionary, in which -case those constructs evaluate code in the *current* environment. This is -dangerous for the same reasons ``from import *`` is dangerous --- it might step -over variables you are counting on and mess up things for the rest of your code. -Simply do not do that. - -Bad examples:: - - >>> for name in sys.argv[1:]: - >>> exec "%s=1" % name - >>> def func(s, **kw): - >>> for var, val in kw.items(): - >>> exec "s.%s=val" % var # invalid! - >>> exec(open("handler.py").read()) - >>> handle() - -Good examples:: - - >>> d = {} - >>> for name in sys.argv[1:]: - >>> d[name] = 1 - >>> def func(s, **kw): - >>> for var, val in kw.items(): - >>> setattr(s, var, val) - >>> d={} - >>> exec(open("handle.py").read(), d, d) - >>> handle = d['handle'] - >>> handle() - - from module import name1, name2 ------------------------------- Modified: python/branches/py3k-ctypes-pep3118/Doc/howto/regex.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/howto/regex.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/howto/regex.rst Thu Jan 24 22:12:24 2008 @@ -335,9 +335,8 @@ Once you have an object representing a compiled regular expression, what do you do with it? :class:`RegexObject` instances have several methods and attributes. -Only the most significant ones will be covered here; consult `the Library -Reference `_ for a complete -listing. +Only the most significant ones will be covered here; consult the :mod:`re` docs +for a complete listing. +------------------+-----------------------------------------------+ | Method/Attribute | Purpose | Modified: python/branches/py3k-ctypes-pep3118/Doc/library/bdb.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/bdb.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/bdb.rst Thu Jan 24 22:12:24 2008 @@ -294,7 +294,7 @@ .. method:: Bdb.run(cmd, [globals, [locals]]) - Debug a statement executed via the :keyword:`exec` statement. *globals* + Debug a statement executed via the :func:`exec` function. *globals* defaults to :attr:`__main__.__dict__`, *locals* defaults to *globals*. .. method:: Bdb.runeval(expr, [globals, [locals]]) Modified: python/branches/py3k-ctypes-pep3118/Doc/library/configparser.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/configparser.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/configparser.rst Thu Jan 24 22:12:24 2008 @@ -420,3 +420,5 @@ # Create non-existent section config.add_section(section2) opt_move(config, section1, section2, option) + else: + config.remove_option(section1, option) Modified: python/branches/py3k-ctypes-pep3118/Doc/library/constants.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/constants.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/constants.rst Thu Jan 24 22:12:24 2008 @@ -1,4 +1,3 @@ - Built-in Constants ================== @@ -52,3 +51,28 @@ This constant is true if Python was not started with an :option:`-O` option. Assignments to :const:`__debug__` are illegal and raise a :exc:`SyntaxError`. See also the :keyword:`assert` statement. + + +Constants added by the :mod:`site` module +----------------------------------------- + +The :mod:`site` module (which is imported automatically during startup, except +if the :option:`-S` command-line option is given) adds several constants to the +built-in namespace. They are useful for the interactive interpreter shell and +should not be used in programs. + +.. data:: quit([code=None]) + exit([code=None]) + + Objects that when printed, print a message like "Use quit() or Ctrl-D + (i.e. EOF) to exit", and when called, raise :exc:`SystemExit` with the + specified exit code, and when . + +.. data:: copyright + license + credits + + Objects that when printed, print a message like "Type license() to see the + full license text", and when called, display the corresponding text in a + pager-like fashion (one screen at a time). + Modified: python/branches/py3k-ctypes-pep3118/Doc/library/fileformats.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/fileformats.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/fileformats.rst Thu Jan 24 22:12:24 2008 @@ -16,3 +16,4 @@ robotparser.rst netrc.rst xdrlib.rst + plistlib.rst Modified: python/branches/py3k-ctypes-pep3118/Doc/library/functions.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/functions.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/functions.rst Thu Jan 24 22:12:24 2008 @@ -526,6 +526,8 @@ topic, and a help page is printed on the console. If the argument is any other kind of object, a help page on the object is generated. + This function is added to the built-in namespace by the :mod:`site` module. + .. function:: hex(x) @@ -646,17 +648,7 @@ Return an iterator that applies *function* to every item of *iterable*, yielding the results. If additional *iterable* arguments are passed, *function* must take that many arguments and is applied to the items from all - iterables in parallel. If one iterable is shorter than another it is assumed - to be extended with ``None`` items. If *function* is ``None``, the identity - function is assumed; if there are multiple arguments, :func:`map` returns a - list consisting of tuples containing the corresponding items from all - iterables (a kind of transpose operation). The *iterable* arguments may be a - sequence or any iterable object; the result is always a list. - - Note that for only one *iterable* argument, ``map(function, iterable)`` is - equivalent to the generator expression ``(function(item) for item in - iterable)`` if *function* is not ``None``. - + iterables in parallel. .. function:: max(iterable[, args...], *[, key]) @@ -1148,6 +1140,10 @@ sequence argument, it returns an iterator of 1-tuples. With no arguments, it returns an empty iterator. + The left-to-right evaluation order of the iterables is guaranteed. This + makes possible an idiom for clustering a data series into n-length groups + using ``zip(*[iter(s)]*n)``. + .. rubric:: Footnotes Modified: python/branches/py3k-ctypes-pep3118/Doc/library/itertools.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/itertools.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/itertools.rst Thu Jan 24 22:12:24 2008 @@ -204,17 +204,12 @@ .. function:: imap(function, *iterables) Make an iterator that computes the function using arguments from each of the - iterables. If *function* is set to ``None``, then :func:`imap` returns the - arguments as a tuple. Like :func:`map` but stops when the shortest iterable is - exhausted instead of filling in ``None`` for shorter iterables. The reason for - the difference is that infinite iterator arguments are typically an error for - :func:`map` (because the output is fully evaluated) but represent a common and - useful way of supplying arguments to :func:`imap`. Equivalent to:: + iterables. Equivalent to:: def imap(function, *iterables): - iterables = map(iter, iterables) + iterables = [iter(it) for it in iterables) while True: - args = [next(i) for i in iterables] + args = [next(it) for it in iterables] if function is None: yield tuple(args) else: @@ -260,12 +255,11 @@ When no iterables are specified, return a zero length iterator. - Note, the left-to-right evaluation order of the iterables is guaranteed. This - makes possible an idiom for clustering a data series into n-length groups using - ``izip(*[iter(s)]*n)``. For data that doesn't fit n-length groups exactly, the - last tuple can be pre-padded with fill values using ``izip(*[chain(s, - [None]*(n-1))]*n)``. + The left-to-right evaluation order of the iterables is guaranteed. This + makes possible an idiom for clustering a data series into n-length groups + using ``izip(*[iter(s)]*n)``. +<<<<<<< .working Note, when :func:`izip` is used with unequal length inputs, subsequent iteration over the longer iterables cannot reliably be continued after :func:`izip` terminates. Potentially, up to one entry will be missing from @@ -276,6 +270,11 @@ the iterator for retrieval with ``next(it)``). In general, :func:`izip` should only be used with unequal length inputs when you don't care about trailing, unmatched values from the longer iterables. +======= + :func:`izip` should only be used with unequal length inputs when you don't + care about trailing, unmatched values from the longer iterables. If those + values are important, use :func:`izip_longest` instead. +>>>>>>> .merge-right.r60208 .. function:: izip_longest(*iterables[, fillvalue]) Modified: python/branches/py3k-ctypes-pep3118/Doc/library/logging.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/logging.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/logging.rst Thu Jan 24 22:12:24 2008 @@ -1180,13 +1180,13 @@ "dict-like" object for use in the constructor:: import logging - + class ConnInfo: """ An example class which shows how an arbitrary class can be used as the 'extra' context information repository passed to a LoggerAdapter. """ - + def __getitem__(self, name): """ To allow this instance to look like a dict. @@ -1199,7 +1199,7 @@ else: result = self.__dict__.get(name, "?") return result - + def __iter__(self): """ To allow iteration over keys, which will be merged into @@ -1208,7 +1208,7 @@ keys = ["ip", "user"] keys.extend(self.__dict__.keys()) return keys.__iter__() - + if __name__ == "__main__": from random import choice levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL) @@ -1517,12 +1517,13 @@ :class:`StreamHandler`. -.. class:: FileHandler(filename[, mode[, encoding]]) +.. class:: FileHandler(filename[, mode[, encoding[, delay]]]) Returns a new instance of the :class:`FileHandler` class. The specified file is opened and used as the stream for logging. If *mode* is not specified, :const:`'a'` is used. If *encoding* is not *None*, it is used to open the file - with that encoding. By default, the file grows indefinitely. + with that encoding. If *delay* is true, then file opening is deferred until the + first call to :meth:`emit`. By default, the file grows indefinitely. .. method:: FileHandler.close() @@ -1556,12 +1557,13 @@ this value. -.. class:: WatchedFileHandler(filename[,mode[, encoding]]) +.. class:: WatchedFileHandler(filename[,mode[, encoding[, delay]]]) Returns a new instance of the :class:`WatchedFileHandler` class. The specified file is opened and used as the stream for logging. If *mode* is not specified, :const:`'a'` is used. If *encoding* is not *None*, it is used to open the file - with that encoding. By default, the file grows indefinitely. + with that encoding. If *delay* is true, then file opening is deferred until the + first call to :meth:`emit`. By default, the file grows indefinitely. .. method:: WatchedFileHandler.emit(record) @@ -1578,11 +1580,13 @@ module, supports rotation of disk log files. -.. class:: RotatingFileHandler(filename[, mode[, maxBytes[, backupCount]]]) +.. class:: RotatingFileHandler(filename[, mode[, maxBytes[, backupCount[, encoding[, delay]]]]]) Returns a new instance of the :class:`RotatingFileHandler` class. The specified file is opened and used as the stream for logging. If *mode* is not specified, - ``'a'`` is used. By default, the file grows indefinitely. + ``'a'`` is used. If *encoding* is not *None*, it is used to open the file + with that encoding. If *delay* is true, then file opening is deferred until the + first call to :meth:`emit`. By default, the file grows indefinitely. You can use the *maxBytes* and *backupCount* values to allow the file to :dfn:`rollover` at a predetermined size. When the size is about to be exceeded, @@ -1616,7 +1620,7 @@ timed intervals. -.. class:: TimedRotatingFileHandler(filename [,when [,interval [,backupCount]]]) +.. class:: TimedRotatingFileHandler(filename [,when [,interval [,backupCount[, encoding[, delay]]]]]) Returns a new instance of the :class:`TimedRotatingFileHandler` class. The specified file is opened and used as the stream for logging. On rotating it also @@ -2053,7 +2057,13 @@ record is computed using *msg* % *args*. If the formatting string contains ``'(asctime)'``, :meth:`formatTime` is called to format the event time. If there is exception information, it is formatted using :meth:`formatException` and - appended to the message. + appended to the message. Note that the formatted exception information is cached + in attribute *exc_text*. This is useful because the exception information can + be pickled and sent across the wire, but you should be careful if you have more + than one :class:`Formatter` subclass which customizes the formatting of exception + information. In this case, you will have to clear the cached value after a + formatter has done its formatting, so that the next formatter to handle the event + doesn't use the cached value but recalculates it afresh. .. method:: Formatter.formatTime(record[, datefmt]) @@ -2133,7 +2143,10 @@ .. versionadded:: 2.6 :class:`LoggerAdapter` instances are used to conveniently pass contextual -information into logging calls. For a usage example , see context-info_. +information into logging calls. For a usage example , see the section on +`adding contextual information to your logging output`__. + +__ context-info_ .. class:: LoggerAdapter(logger, extra) Modified: python/branches/py3k-ctypes-pep3118/Doc/library/mmap.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/mmap.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/mmap.rst Thu Jan 24 22:12:24 2008 @@ -15,7 +15,7 @@ and write data starting at the current file position, and :meth:`seek` through the file to different positions. -A memory-mapped file is created by the :func:`mmap` function, which is different +A memory-mapped file is created by the :class:`mmap` constructor, which is different on Unix and on Windows. In either case you must provide a file descriptor for a file opened for update. If you wish to map an existing Python file object, use its :meth:`fileno` method to obtain the correct value for the *fileno* @@ -23,7 +23,7 @@ which returns a file descriptor directly (the file still needs to be closed when done). -For both the Unix and Windows versions of the function, *access* may be +For both the Unix and Windows versions of the constructor, *access* may be specified as an optional keyword parameter. *access* accepts one of three values: :const:`ACCESS_READ`, :const:`ACCESS_WRITE`, or :const:`ACCESS_COPY` to specify readonly, write-through or copy-on-write memory respectively. *access* @@ -37,11 +37,10 @@ To map anonymous memory, -1 should be passed as the fileno along with the length. - -.. function:: mmap(fileno, length[, tagname[, access[, offset]]]) +.. class:: mmap(fileno, length[, tagname[, access[, offset]]]) **(Windows version)** Maps *length* bytes from the file specified by the file - handle *fileno*, and returns a mmap object. If *length* is larger than the + handle *fileno*, and creates a mmap object. If *length* is larger than the current size of the file, the file is extended to contain *length* bytes. If *length* is ``0``, the maximum length of the map is the current size of the file, except that if the file is empty Windows raises an exception (you cannot @@ -59,12 +58,12 @@ *offset* must be a multiple of the ALLOCATIONGRANULARITY. -.. function:: mmap(fileno, length[, flags[, prot[, access[, offset]]]]) +.. class:: mmap(fileno, length[, flags[, prot[, access[, offset]]]]) :noindex: **(Unix version)** Maps *length* bytes from the file specified by the file descriptor *fileno*, and returns a mmap object. If *length* is ``0``, the - maximum length of the map will be the current size of the file when :func:`mmap` + maximum length of the map will be the current size of the file when :class:`mmap` is called. *flags* specifies the nature of the mapping. :const:`MAP_PRIVATE` creates a @@ -85,7 +84,7 @@ be relative to the offset from the beginning of the file. *offset* defaults to 0. *offset* must be a multiple of the PAGESIZE or ALLOCATIONGRANULARITY. - This example shows a simple way of using :func:`mmap`:: + This example shows a simple way of using :class:`mmap`:: import mmap Modified: python/branches/py3k-ctypes-pep3118/Doc/library/pprint.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/pprint.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/pprint.rst Thu Jan 24 22:12:24 2008 @@ -22,6 +22,9 @@ Dictionaries are sorted by key before the display is computed. +.. versionchanged:: 2.6 + Added support for :class:`set` and :class:`frozenset`. + The :mod:`pprint` module defines one class: .. First the implementation class: Modified: python/branches/py3k-ctypes-pep3118/Doc/library/pydoc.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/pydoc.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/pydoc.rst Thu Jan 24 22:12:24 2008 @@ -57,7 +57,7 @@ Python interpreter and typed ``import spam``. Module docs for core modules are assumed to reside in -http://www.python.org/doc/current/lib/. This can be overridden by setting the +http://docs.python.org/library/. This can be overridden by setting the :envvar:`PYTHONDOCS` environment variable to a different URL or to a local directory containing the Library Reference Manual pages. Modified: python/branches/py3k-ctypes-pep3118/Doc/library/shutil.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/shutil.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/shutil.rst Thu Jan 24 22:12:24 2008 @@ -93,18 +93,24 @@ .. index:: single: directory; deleting - Delete an entire directory tree (*path* must point to a directory). If - *ignore_errors* is true, errors resulting from failed removals will be ignored; - if false or omitted, such errors are handled by calling a handler specified by - *onerror* or, if that is omitted, they raise an exception. - - If *onerror* is provided, it must be a callable that accepts three parameters: - *function*, *path*, and *excinfo*. The first parameter, *function*, is the - function which raised the exception; it will be :func:`os.listdir`, - :func:`os.remove` or :func:`os.rmdir`. The second parameter, *path*, will be - the path name passed to *function*. The third parameter, *excinfo*, will be the - exception information return by :func:`sys.exc_info`. Exceptions raised by - *onerror* will not be caught. + Delete an entire directory tree; *path* must point to a directory (but not a + symbolic link to a directory). If *ignore_errors* is true, errors resulting + from failed removals will be ignored; if false or omitted, such errors are + handled by calling a handler specified by *onerror* or, if that is omitted, + they raise an exception. + + If *onerror* is provided, it must be a callable that accepts three + parameters: *function*, *path*, and *excinfo*. The first parameter, + *function*, is the function which raised the exception; it will be + :func:`os.path.islink`, :func:`os.listdir`, :func:`os.remove` or + :func:`os.rmdir`. The second parameter, *path*, will be the path name passed + to *function*. The third parameter, *excinfo*, will be the exception + information return by :func:`sys.exc_info`. Exceptions raised by *onerror* + will not be caught. + + .. versionchanged:: 2.6 + Explicitly check for *path* being a symbolic link and raise :exc:`OSError` + in that case. .. function:: move(src, dst) Modified: python/branches/py3k-ctypes-pep3118/Doc/library/sys.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/sys.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/sys.rst Thu Jan 24 22:12:24 2008 @@ -326,6 +326,35 @@ This function should be used for internal and specialized purposes only. +.. function:: getprofile() + + .. index:: + single: profile function + single: profiler + + Get the profiler function as set by :func:`setprofile`. + + .. versionadded:: 2.6 + + +.. function:: gettrace() + + .. index:: + single: trace function + single: debugger + + Get the trace function as set by :func:`settrace`. + + .. note:: + + The :func:`gettrace` function is intended only for implementing debuggers, + profilers, coverage tools and the like. Its behavior is part of the + implementation platform, rather than part of the language definition, + and thus may not be available in all Python implementations. + + .. versionadded:: 2.6 + + .. function:: getwindowsversion() Return a tuple containing five components, describing the Windows version @@ -444,9 +473,26 @@ .. data:: platform - This string contains a platform identifier, e.g. ``'sunos5'`` or ``'linux1'``. - This can be used to append platform-specific components to ``path``, for - instance. + This string contains a platform identifier that can be used to append + platform-specific components to :data:`sys.path`, for instance. + + For Unix systems, this is the lowercased OS name as returned by ``uname -s`` + with the first part of the version as returned by ``uname -r`` appended, + e.g. ``'sunos5'`` or ``'linux2'``, *at the time when Python was built*. + For other systems, the values are: + + ================ =========================== + System :data:`platform` value + ================ =========================== + Windows ``'win32'`` + Windows/Cygwin ``'cygwin'`` + MacOS X ``'darwin'`` + MacOS 9 ``'mac'`` + OS/2 ``'os2'`` + OS/2 EMX ``'os2emx'`` + RiscOS ``'riscos'`` + AtheOS ``'atheos'`` + ================ =========================== .. data:: prefix Modified: python/branches/py3k-ctypes-pep3118/Doc/library/urllib.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/urllib.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/urllib.rst Thu Jan 24 22:12:24 2008 @@ -27,16 +27,17 @@ a server somewhere on the network. If the connection cannot be made the :exc:`IOError` exception is raised. If all went well, a file-like object is returned. This supports the following methods: :meth:`read`, :meth:`readline`, - :meth:`readlines`, :meth:`fileno`, :meth:`close`, :meth:`info` and + :meth:`readlines`, :meth:`fileno`, :meth:`close`, :meth:`info`, :meth:`getcode` and :meth:`geturl`. It also has proper support for the :term:`iterator` protocol. One caveat: the :meth:`read` method, if the size argument is omitted or negative, may not read until the end of the data stream; there is no good way to determine that the entire stream from a socket has been read in the general case. - Except for the :meth:`info` and :meth:`geturl` methods, these methods have the - same interface as for file objects --- see section :ref:`bltin-file-objects` in - this manual. (It is not a built-in file object, however, so it can't be used at - those few places where a true built-in file object is required.) + Except for the :meth:`info`, :meth:`getcode` and :meth:`geturl` methods, + these methods have the same interface as for file objects --- see section + :ref:`bltin-file-objects` in this manual. (It is not a built-in file object, + however, so it can't be used at those few places where a true built-in file + object is required.) .. index:: module: mimetools @@ -58,6 +59,9 @@ the client was redirected to. The :meth:`geturl` method can be used to get at this redirected URL. + The :meth:`getcode` method returns the HTTP status code that was sent with the + response, or ``None`` if the URL is no HTTP URL. + If the *url* uses the :file:`http:` scheme identifier, the optional *data* argument may be given to specify a ``POST`` request (normally the request type is ``GET``). The *data* argument must be in standard @@ -75,6 +79,11 @@ % python ... + The :envvar:`no_proxy` environment variable can be used to specify hosts which + shouldn't be reached via proxy; if set, it should be a comma-separated list + of hostname suffixes, optionally with ``:port`` appended, for example + ``cern.ch,ncsa.uiuc.edu,some.host:8080``. + In a Windows environment, if no proxy environment variables are set, proxy settings are obtained from the registry's Internet Settings section. Modified: python/branches/py3k-ctypes-pep3118/Doc/reference/lexical_analysis.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/reference/lexical_analysis.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/reference/lexical_analysis.rst Thu Jan 24 22:12:24 2008 @@ -502,7 +502,7 @@ (4) Individual code units which form parts of a surrogate pair can be encoded using - this escape sequence. + this escape sequence. Unlike in Standard C, exactly two hex digits are required. (5) Any Unicode character can be encoded this way, but characters outside the Basic Modified: python/branches/py3k-ctypes-pep3118/Doc/tutorial/controlflow.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/tutorial/controlflow.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/tutorial/controlflow.rst Thu Jan 24 22:12:24 2008 @@ -235,10 +235,11 @@ The *execution* of a function introduces a new symbol table used for the local variables of the function. More precisely, all variable assignments in a function store the value in the local symbol table; whereas variable references -first look in the local symbol table, then in the global symbol table, and then -in the table of built-in names. Thus, global variables cannot be directly -assigned a value within a function (unless named in a :keyword:`global` -statement), although they may be referenced. +first look in the local symbol table, then in the local symbol tables of +enclosing functions, then in the global symbol table, and finally in the table +of built-in names. Thus, global variables cannot be directly assigned a value +within a function (unless named in a :keyword:`global` statement), although they +may be referenced. The actual parameters (arguments) to a function call are introduced in the local symbol table of the called function when it is called; thus, arguments are @@ -263,7 +264,7 @@ technically speaking, procedures do return a value, albeit a rather boring one. This value is called ``None`` (it's a built-in name). Writing the value ``None`` is normally suppressed by the interpreter if it would be the only value -written. You can see it if you really want to using :keyword:`print`:: +written. You can see it if you really want to using :func:`print`:: >>> fib(0) >>> print(fib(0)) Modified: python/branches/py3k-ctypes-pep3118/Doc/tutorial/interpreter.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/tutorial/interpreter.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/tutorial/interpreter.rst Thu Jan 24 22:12:24 2008 @@ -169,6 +169,12 @@ $ chmod +x myscript.py +On Windows systems, there is no notion of an "executable mode". The Python +installer automatically associates ``.py`` files with ``python.exe`` so that +a double-click on a Python file will run it as a script. The extension can +also be ``.pyw``, in that case, the console window that normally appears is +suppressed. + Source Code Encoding -------------------- Modified: python/branches/py3k-ctypes-pep3118/Doc/tutorial/stdlib2.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/tutorial/stdlib2.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/tutorial/stdlib2.rst Thu Jan 24 22:12:24 2008 @@ -134,8 +134,10 @@ The :mod:`struct` module provides :func:`pack` and :func:`unpack` functions for working with variable length binary record formats. The following example shows -how to loop through header information in a ZIP file (with pack codes ``"H"`` -and ``"L"`` representing two and four byte unsigned numbers respectively):: +how to loop through header information in a ZIP file without using the +:mod:`zipfile` module. Pack codes ``"H"`` and ``"I"`` represent two and four +byte unsigned numbers respectively. The ``"<"`` indicates that they are +standard size and in little-endian byte order:: import struct @@ -143,7 +145,7 @@ start = 0 for i in range(3): # show the first 3 file headers start += 14 - fields = struct.unpack('LLLHH', data[start:start+16]) + fields = struct.unpack('` and - :file:`{exec_prefix}/lib/python`, where :file:`{prefix}` and + libraries are searched in :file:`{prefix}/lib/python{version}` and + :file:`{exec_prefix}/lib/python{version}`, where :file:`{prefix}` and :file:`{exec_prefix}` are installation-dependent directories, both defaulting to :file:`/usr/local`. When :envvar:`PYTHONHOME` is set to a single directory, its value replaces both :file:`{prefix}` and :file:`{exec_prefix}`. To specify different values - for these, set :envvar:`PYTHONHOME` to :file:`{prefix}:{exec_prefix}``. + for these, set :envvar:`PYTHONHOME` to :file:`{prefix}:{exec_prefix}`. .. envvar:: PYTHONPATH @@ -314,7 +314,7 @@ colons. Non-existent directories are silently ignored. The default search path is installation dependent, but generally begins with - :file:`{prefix}/lib/python`` (see :envvar:`PYTHONHOME` above). It + :file:`{prefix}/lib/python{version}`` (see :envvar:`PYTHONHOME` above). It is *always* appended to :envvar:`PYTHONPATH`. If a script argument is given, the directory containing the script is Modified: python/branches/py3k-ctypes-pep3118/Doc/whatsnew/3.0.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/whatsnew/3.0.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/whatsnew/3.0.rst Thu Jan 24 22:12:24 2008 @@ -389,7 +389,8 @@ * Everything is all in the details! -* Developers can include intobject.h after Python.h for some PyInt_ aliases. +* Developers can include :file:`intobject.h` after :file:`Python.h` for + some ``PyInt_`` aliases. .. ====================================================================== Modified: python/branches/py3k-ctypes-pep3118/Include/modsupport.h ============================================================================== --- python/branches/py3k-ctypes-pep3118/Include/modsupport.h (original) +++ python/branches/py3k-ctypes-pep3118/Include/modsupport.h Thu Jan 24 22:12:24 2008 @@ -40,7 +40,8 @@ PyAPI_FUNC(int) PyModule_AddObject(PyObject *, const char *, PyObject *); PyAPI_FUNC(int) PyModule_AddIntConstant(PyObject *, const char *, long); PyAPI_FUNC(int) PyModule_AddStringConstant(PyObject *, const char *, const char *); - +#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant(m, #c, c) +#define PyModule_AddStringMacro(m, c) PyModule_AddStringConstant(m, #c, c) #define PYTHON_API_VERSION 1013 #define PYTHON_API_STRING "1013" Modified: python/branches/py3k-ctypes-pep3118/Include/pyport.h ============================================================================== --- python/branches/py3k-ctypes-pep3118/Include/pyport.h (original) +++ python/branches/py3k-ctypes-pep3118/Include/pyport.h Thu Jan 24 22:12:24 2008 @@ -388,8 +388,8 @@ * macro for this particular test is useful */ #ifndef Py_IS_FINITE -#ifdef HAVE_ISFINITE -#define Py_IS_FINITE(X) isfinite +#ifdef HAVE_FINITE +#define Py_IS_FINITE(X) finite(X) #else #define Py_IS_FINITE(X) (!Py_IS_INFINITY(X) && !Py_IS_NAN(X)) #endif Modified: python/branches/py3k-ctypes-pep3118/Include/structmember.h ============================================================================== --- python/branches/py3k-ctypes-pep3118/Include/structmember.h (original) +++ python/branches/py3k-ctypes-pep3118/Include/structmember.h Thu Jan 24 22:12:24 2008 @@ -54,6 +54,9 @@ /* Added by Jack: strings contained in the structure */ #define T_STRING_INPLACE 13 +/* Added by Lillo: bools contained in the structure (assumed char) */ +#define T_BOOL 14 + #define T_OBJECT_EX 16 /* Like T_OBJECT, but raises AttributeError when the value is NULL, instead of converting to None. */ Modified: python/branches/py3k-ctypes-pep3118/Lib/distutils/command/build.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/distutils/command/build.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/distutils/command/build.py Thu Jan 24 22:12:24 2008 @@ -66,6 +66,12 @@ def finalize_options(self): plat_specifier = ".%s-%s" % (get_platform(), sys.version[0:3]) + # Make it so Python 2.x and Python 2.x with --with-pydebug don't + # share the same build directories. Doing so confuses the build + # process for C modules + if hasattr(sys, 'gettotalrefcount'): + plat_specifier += '-pydebug' + # 'build_purelib' and 'build_platlib' just default to 'lib' and # 'lib.' under the base build directory. We only use one of # them for a given distribution, though -- Modified: python/branches/py3k-ctypes-pep3118/Lib/formatter.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/formatter.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/formatter.py Thu Jan 24 22:12:24 2008 @@ -433,10 +433,7 @@ fp = open(sys.argv[1]) else: fp = sys.stdin - while 1: - line = fp.readline() - if not line: - break + for line in fp: if line == '\n': f.end_paragraph(1) else: Modified: python/branches/py3k-ctypes-pep3118/Lib/ftplib.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/ftplib.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/ftplib.py Thu Jan 24 22:12:24 2008 @@ -32,6 +32,7 @@ # Changes and improvements suggested by Steve Majewski. # Modified by Jack to work on the mac. # Modified by Siebren to support docstrings and PASV. +# Modified by Phil Schwartz to add storbinary and storlines callbacks. # import os @@ -313,7 +314,7 @@ expected size may be None if it could not be determined. Optional `rest' argument can be a string that is sent as the - argument to a RESTART command. This is essentially a server + argument to a REST command. This is essentially a server marker used to tell the server to skip over any data up to the given marker. """ @@ -376,14 +377,18 @@ return resp def retrbinary(self, cmd, callback, blocksize=8192, rest=None): - """Retrieve data in binary mode. + """Retrieve data in binary mode. A new port is created for you. - `cmd' is a RETR command. `callback' is a callback function is - called for each block. No more than `blocksize' number of - bytes will be read from the socket. Optional `rest' is passed - to transfercmd(). + Args: + cmd: A RETR command. + callback: A single parameter callable to be called on each + block of data read. + blocksize: The maximum number of bytes to read from the + socket at one time. [default: 8192] + rest: Passed to transfercmd(). [default: None] - A new port is created for you. Return the response code. + Returns: + The response code. """ self.voidcmd('TYPE I') conn = self.transfercmd(cmd, rest) @@ -396,11 +401,17 @@ return self.voidresp() def retrlines(self, cmd, callback = None): - '''Retrieve data in line mode. - The argument is a RETR or LIST command. - The callback function (2nd argument) is called for each line, - with trailing CRLF stripped. This creates a new port for you. - print_line() is the default callback.''' + """Retrieve data in line mode. A new port is created for you. + + Args: + cmd: A RETR, LIST, NLST, or MLSD command. + callback: An optional single parameter callable that is called + for each line with the trailing CRLF stripped. + [default: print_line()] + + Returns: + The response code. + """ if callback is None: callback = print_line resp = self.sendcmd('TYPE A') conn = self.transfercmd(cmd) @@ -419,19 +430,42 @@ conn.close() return self.voidresp() - def storbinary(self, cmd, fp, blocksize=8192): - '''Store a file in binary mode.''' + def storbinary(self, cmd, fp, blocksize=8192, callback=None): + """Store a file in binary mode. A new port is created for you. + + Args: + cmd: A STOR command. + fp: A file-like object with a read(num_bytes) method. + blocksize: The maximum data size to read from fp and send over + the connection at once. [default: 8192] + callback: An optional single parameter callable that is called on + on each block of data after it is sent. [default: None] + + Returns: + The response code. + """ self.voidcmd('TYPE I') conn = self.transfercmd(cmd) while 1: buf = fp.read(blocksize) if not buf: break conn.sendall(buf) + if callback: callback(buf) conn.close() return self.voidresp() - def storlines(self, cmd, fp): - '''Store a file in line mode.''' + def storlines(self, cmd, fp, callback=None): + """Store a file in line mode. A new port is created for you. + + Args: + cmd: A STOR command. + fp: A file-like object with a readline() method. + callback: An optional single parameter callable that is called on + on each line after it is sent. [default: None] + + Returns: + The response code. + """ self.voidcmd('TYPE A') conn = self.transfercmd(cmd) while 1: @@ -441,6 +475,7 @@ if buf[-1] in CRLF: buf = buf[:-1] buf = buf + CRLF conn.sendall(buf) + if callback: callback(buf) conn.close() return self.voidresp() @@ -505,7 +540,7 @@ def size(self, filename): '''Retrieve the size of a file.''' - # Note that the RFC doesn't say anything about 'SIZE' + # The SIZE command is defined in RFC-3659 resp = self.sendcmd('SIZE ' + filename) if resp[:3] == '213': s = resp[3:].strip() Modified: python/branches/py3k-ctypes-pep3118/Lib/heapq.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/heapq.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/heapq.py Thu Jan 24 22:12:24 2008 @@ -351,7 +351,8 @@ Equivalent to: sorted(iterable, key=key)[:n] """ in1, in2 = tee(iterable) - it = izip(map(key, in1), count(), in2) # decorate + keys = in1 if key is None else map(key, in1) + it = izip(keys, count(), in2) # decorate result = _nsmallest(n, it) return list(map(itemgetter(2), result)) # undecorate @@ -362,7 +363,8 @@ Equivalent to: sorted(iterable, key=key, reverse=True)[:n] """ in1, in2 = tee(iterable) - it = izip(map(key, in1), map(neg, count()), in2) # decorate + keys = in1 if key is None else map(key, in1) + it = izip(keys, map(neg, count()), in2) # decorate result = _nlargest(n, it) return list(map(itemgetter(2), result)) # undecorate Modified: python/branches/py3k-ctypes-pep3118/Lib/idlelib/NEWS.txt ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/idlelib/NEWS.txt (original) +++ python/branches/py3k-ctypes-pep3118/Lib/idlelib/NEWS.txt Thu Jan 24 22:12:24 2008 @@ -45,6 +45,11 @@ *Release date: XX-XXX-200X* UNRELEASED, but merged into 3.0 +- There was an error on exit if no sys.exitfunc was defined. Issue 1647. + +- Could not open files in .idlerc directory if latter was hidden on Windows. + Issue 1743, Issue 1862. + - Configure Dialog: improved layout for keybinding. Patch 1457 Tal Einat. - tabpage.py updated: tabbedPages.py now supports multiple dynamic rows Modified: python/branches/py3k-ctypes-pep3118/Lib/idlelib/configHandler.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/idlelib/configHandler.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/idlelib/configHandler.py Thu Jan 24 22:12:24 2008 @@ -139,7 +139,12 @@ """ if not self.IsEmpty(): - cfgFile=open(self.file,'w') + fname = self.file + try: + cfgFile = open(fname, 'w') + except IOError: + fname.unlink() + cfgFile = open(fname, 'w') self.write(cfgFile) else: self.RemoveFile() Modified: python/branches/py3k-ctypes-pep3118/Lib/keyword.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/keyword.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/keyword.py Thu Jan 24 22:12:24 2008 @@ -64,9 +64,7 @@ fp = open(iptfile) strprog = re.compile('"([^"]+)"') lines = [] - while 1: - line = fp.readline() - if not line: break + for line in fp: if '{1, "' in line: match = strprog.search(line) if match: Modified: python/branches/py3k-ctypes-pep3118/Lib/logging/__init__.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/logging/__init__.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/logging/__init__.py Thu Jan 24 22:12:24 2008 @@ -38,8 +38,8 @@ __author__ = "Vinay Sajip " __status__ = "production" -__version__ = "0.5.0.4" -__date__ = "18 January 2008" +__version__ = "0.5.0.5" +__date__ = "24 January 2008" #--------------------------------------------------------------------------- # Miscellaneous module data @@ -760,7 +760,7 @@ """ A handler class which writes formatted logging records to disk files. """ - def __init__(self, filename, mode='a', encoding=None): + def __init__(self, filename, mode='a', encoding=None, delay=0): """ Open the specified file and use it as the stream for logging. """ @@ -771,8 +771,11 @@ self.baseFilename = os.path.abspath(filename) self.mode = mode self.encoding = encoding - stream = self._open() - StreamHandler.__init__(self, stream) + if delay: + self.stream = None + else: + stream = self._open() + StreamHandler.__init__(self, stream) def close(self): """ @@ -795,6 +798,18 @@ stream = codecs.open(self.baseFilename, self.mode, self.encoding) return stream + def emit(self, record): + """ + Emit a record. + + If the stream was not opened because 'delay' was specified in the + constructor, open it before calling the superclass's emit. + """ + if self.stream is None: + stream = self._open() + StreamHandler.__init__(self, stream) + StreamHandler.emit(self, record) + #--------------------------------------------------------------------------- # Manager classes and functions #--------------------------------------------------------------------------- Modified: python/branches/py3k-ctypes-pep3118/Lib/logging/handlers.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/logging/handlers.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/logging/handlers.py Thu Jan 24 22:12:24 2008 @@ -51,13 +51,13 @@ Not meant to be instantiated directly. Instead, use RotatingFileHandler or TimedRotatingFileHandler. """ - def __init__(self, filename, mode, encoding=None): + def __init__(self, filename, mode, encoding=None, delay=0): """ Use the specified filename for streamed logging """ if codecs is None: encoding = None - logging.FileHandler.__init__(self, filename, mode, encoding) + logging.FileHandler.__init__(self, filename, mode, encoding, delay) self.mode = mode self.encoding = encoding @@ -82,7 +82,7 @@ Handler for logging to a set of files, which switches from one file to the next when the current file reaches a certain size. """ - def __init__(self, filename, mode='a', maxBytes=0, backupCount=0, encoding=None): + def __init__(self, filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=0): """ Open the specified file and use it as the stream for logging. @@ -105,7 +105,7 @@ """ if maxBytes > 0: mode = 'a' # doesn't make sense otherwise! - BaseRotatingHandler.__init__(self, filename, mode, encoding) + BaseRotatingHandler.__init__(self, filename, mode, encoding, delay) self.maxBytes = maxBytes self.backupCount = backupCount @@ -154,8 +154,8 @@ If backupCount is > 0, when rollover is done, no more than backupCount files are kept - the oldest ones are deleted. """ - def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None): - BaseRotatingHandler.__init__(self, filename, 'a', encoding) + def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None, delay=0): + BaseRotatingHandler.__init__(self, filename, 'a', encoding, delay) self.when = when.upper() self.backupCount = backupCount # Calculate the real rollover interval, which is just the number of @@ -226,13 +226,16 @@ # Days to rollover is 6 - 5 + 3, or 4. In this case, it's the # number of days left in the current week (1) plus the number # of days in the next week until the rollover day (3). + # The calculations described in 2) and 3) above need to have a day added. + # This is because the above time calculation takes us to midnight on this + # day, i.e. the start of the next day. if when.startswith('W'): day = t[6] # 0 is Monday if day != self.dayOfWeek: if day < self.dayOfWeek: - daysToWait = self.dayOfWeek - day - 1 + daysToWait = self.dayOfWeek - day else: - daysToWait = 6 - day + self.dayOfWeek + daysToWait = 6 - day + self.dayOfWeek + 1 self.rolloverAt = self.rolloverAt + (daysToWait * (60 * 60 * 24)) #print "Will rollover at %d, %d seconds from now" % (self.rolloverAt, self.rolloverAt - currentTime) @@ -297,10 +300,13 @@ This handler is based on a suggestion and patch by Chad J. Schroeder. """ - def __init__(self, filename, mode='a', encoding=None): - logging.FileHandler.__init__(self, filename, mode, encoding) - stat = os.stat(self.baseFilename) - self.dev, self.ino = stat[ST_DEV], stat[ST_INO] + def __init__(self, filename, mode='a', encoding=None, delay=0): + logging.FileHandler.__init__(self, filename, mode, encoding, delay) + if not os.path.exists(self.baseFilename): + self.dev, self.ino = -1, -1 + else: + stat = os.stat(self.baseFilename) + self.dev, self.ino = stat[ST_DEV], stat[ST_INO] def emit(self, record): """ @@ -316,7 +322,7 @@ else: stat = os.stat(self.baseFilename) changed = (stat[ST_DEV] != self.dev) or (stat[ST_INO] != self.ino) - if changed: + if changed and self.stream is not None: self.stream.flush() self.stream.close() self.stream = self._open() Deleted: /python/branches/py3k-ctypes-pep3118/Lib/plat-mac/plistlib.py ============================================================================== --- /python/branches/py3k-ctypes-pep3118/Lib/plat-mac/plistlib.py Thu Jan 24 22:12:24 2008 +++ (empty file) @@ -1,469 +0,0 @@ -"""plistlib.py -- a tool to generate and parse MacOSX .plist files. - -The PropertList (.plist) file format is a simple XML pickle supporting -basic object types, like dictionaries, lists, numbers and strings. -Usually the top level object is a dictionary. - -To write out a plist file, use the writePlist(rootObject, pathOrFile) -function. 'rootObject' is the top level object, 'pathOrFile' is a -filename or a (writable) file object. - -To parse a plist from a file, use the readPlist(pathOrFile) function, -with a file name or a (readable) file object as the only argument. It -returns the top level object (again, usually a dictionary). - -To work with plist data in bytes objects, you can use readPlistFromBytes() -and writePlistToBytes(). - -Values can be strings, integers, floats, booleans, tuples, lists, -dictionaries, Data or datetime.datetime objects. String values (including -dictionary keys) may be unicode strings -- they will be written out as -UTF-8. - -The plist type is supported through the Data class. This is a -thin wrapper around a Python bytes object. - -Generate Plist example: - - pl = dict( - aString="Doodah", - aList=["A", "B", 12, 32.1, [1, 2, 3]], - aFloat = 0.1, - anInt = 728, - aDict=dict( - anotherString="", - aUnicodeValue=u'M\xe4ssig, Ma\xdf', - aTrueValue=True, - aFalseValue=False, - ), - someData = Data(b""), - someMoreData = Data(b"" * 10), - aDate = datetime.datetime.fromtimestamp(time.mktime(time.gmtime())), - ) - # unicode keys are possible, but a little awkward to use: - pl[u'\xc5benraa'] = "That was a unicode key." - writePlist(pl, fileName) - -Parse Plist example: - - pl = readPlist(pathOrFile) - print pl["aKey"] -""" - - -__all__ = [ - "readPlist", "writePlist", "readPlistFromBytes", "writePlistToBytes", - "readPlistFromResource", "writePlistToResource", - "Plist", "Data", "Dict" -] -# Note: the Plist and Dict classes have been deprecated. - -import binascii -import datetime -from io import BytesIO -import re - - -def readPlist(pathOrFile): - """Read a .plist file. 'pathOrFile' may either be a file name or a - (readable) file object. Return the unpacked root object (which - usually is a dictionary). - """ - didOpen = False - if isinstance(pathOrFile, str): - pathOrFile = open(pathOrFile, 'rb') - didOpen = True - p = PlistParser() - rootObject = p.parse(pathOrFile) - if didOpen: - pathOrFile.close() - return rootObject - - -def writePlist(rootObject, pathOrFile): - """Write 'rootObject' to a .plist file. 'pathOrFile' may either be a - file name or a (writable) file object. - """ - didOpen = False - if isinstance(pathOrFile, str): - pathOrFile = open(pathOrFile, 'wb') - didOpen = True - writer = PlistWriter(pathOrFile) - writer.writeln("") - writer.writeValue(rootObject) - writer.writeln("") - if didOpen: - pathOrFile.close() - - -def readPlistFromBytes(data): - """Read a plist data from a bytes object. Return the root object. - """ - return readPlist(BytesIO(data)) - - -def writePlistToBytes(rootObject): - """Return 'rootObject' as a plist-formatted bytes object. - """ - f = BytesIO() - writePlist(rootObject, f) - return f.getvalue() - - -def readPlistFromResource(path, restype='plst', resid=0): - """Read plst resource from the resource fork of path. - """ - from Carbon.File import FSRef, FSGetResourceForkName - from Carbon.Files import fsRdPerm - from Carbon import Res - fsRef = FSRef(path) - resNum = Res.FSOpenResourceFile(fsRef, FSGetResourceForkName(), fsRdPerm) - Res.UseResFile(resNum) - plistData = Res.Get1Resource(restype, resid).data - Res.CloseResFile(resNum) - return readPlistFromString(plistData) - - -def writePlistToResource(rootObject, path, restype='plst', resid=0): - """Write 'rootObject' as a plst resource to the resource fork of path. - """ - from Carbon.File import FSRef, FSGetResourceForkName - from Carbon.Files import fsRdWrPerm - from Carbon import Res - plistData = writePlistToString(rootObject) - fsRef = FSRef(path) - resNum = Res.FSOpenResourceFile(fsRef, FSGetResourceForkName(), fsRdWrPerm) - Res.UseResFile(resNum) - try: - Res.Get1Resource(restype, resid).RemoveResource() - except Res.Error: - pass - res = Res.Resource(plistData) - res.AddResource(restype, resid, '') - res.WriteResource() - Res.CloseResFile(resNum) - - -class DumbXMLWriter: - def __init__(self, file, indentLevel=0, indent="\t"): - self.file = file - self.stack = [] - self.indentLevel = indentLevel - self.indent = indent - - def beginElement(self, element): - self.stack.append(element) - self.writeln("<%s>" % element) - self.indentLevel += 1 - - def endElement(self, element): - assert self.indentLevel > 0 - assert self.stack.pop() == element - self.indentLevel -= 1 - self.writeln("" % element) - - def simpleElement(self, element, value=None): - if value is not None: - value = _escape(value) - self.writeln("<%s>%s" % (element, value, element)) - else: - self.writeln("<%s/>" % element) - - def writeln(self, line): - if line: - # plist has fixed encoding of utf-8 - if isinstance(line, str): - line = line.encode('utf-8') - self.file.write(self.indentLevel * self.indent) - self.file.write(line) - self.file.write(b'\n') - - -# Contents should conform to a subset of ISO 8601 -# (in particular, YYYY '-' MM '-' DD 'T' HH ':' MM ':' SS 'Z'. Smaller units may be omitted with -# a loss of precision) -_dateParser = re.compile(r"(?P\d\d\d\d)(?:-(?P\d\d)(?:-(?P\d\d)(?:T(?P\d\d)(?::(?P\d\d)(?::(?P\d\d))?)?)?)?)?Z") - -def _dateFromString(s): - order = ('year', 'month', 'day', 'hour', 'minute', 'second') - gd = _dateParser.match(s).groupdict() - lst = [] - for key in order: - val = gd[key] - if val is None: - break - lst.append(int(val)) - return datetime.datetime(*lst) - -def _dateToString(d): - return '%04d-%02d-%02dT%02d:%02d:%02dZ' % ( - d.year, d.month, d.day, - d.hour, d.minute, d.second - ) - - -# Regex to find any control chars, except for \t \n and \r -_controlCharPat = re.compile( - r"[\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0b\x0c\x0e\x0f" - r"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f]") - -def _escape(text): - m = _controlCharPat.search(text) - if m is not None: - raise ValueError("strings can't contains control characters; " - "use plistlib.Data instead") - text = text.replace("\r\n", "\n") # convert DOS line endings - text = text.replace("\r", "\n") # convert Mac line endings - text = text.replace("&", "&") # escape '&' - text = text.replace("<", "<") # escape '<' - text = text.replace(">", ">") # escape '>' - return text - - -PLISTHEADER = b"""\ - - -""" - -class PlistWriter(DumbXMLWriter): - - def __init__(self, file, indentLevel=0, indent=b"\t", writeHeader=1): - if writeHeader: - file.write(PLISTHEADER) - DumbXMLWriter.__init__(self, file, indentLevel, indent) - - def writeValue(self, value): - if isinstance(value, str): - self.simpleElement("string", value) - elif isinstance(value, bool): - # must switch for bool before int, as bool is a - # subclass of int... - if value: - self.simpleElement("true") - else: - self.simpleElement("false") - elif isinstance(value, int): - self.simpleElement("integer", "%d" % value) - elif isinstance(value, float): - self.simpleElement("real", repr(value)) - elif isinstance(value, dict): - self.writeDict(value) - elif isinstance(value, Data): - self.writeData(value) - elif isinstance(value, datetime.datetime): - self.simpleElement("date", _dateToString(value)) - elif isinstance(value, (tuple, list)): - self.writeArray(value) - else: - raise TypeError("unsuported type: %s" % type(value)) - - def writeData(self, data): - self.beginElement("data") - self.indentLevel -= 1 - maxlinelength = 76 - len(self.indent.replace(b"\t", b" " * 8) * - self.indentLevel) - for line in data.asBase64(maxlinelength).split(b"\n"): - if line: - self.writeln(line) - self.indentLevel += 1 - self.endElement("data") - - def writeDict(self, d): - self.beginElement("dict") - items = sorted(d.items()) - for key, value in items: - if not isinstance(key, str): - raise TypeError("keys must be strings") - self.simpleElement("key", key) - self.writeValue(value) - self.endElement("dict") - - def writeArray(self, array): - self.beginElement("array") - for value in array: - self.writeValue(value) - self.endElement("array") - - -class _InternalDict(dict): - - # This class is needed while Dict is scheduled for deprecation: - # we only need to warn when a *user* instantiates Dict or when - # the "attribute notation for dict keys" is used. - - def __getattr__(self, attr): - try: - value = self[attr] - except KeyError: - raise AttributeError(attr) - from warnings import warn - warn("Attribute access from plist dicts is deprecated, use d[key] " - "notation instead", PendingDeprecationWarning) - return value - - def __setattr__(self, attr, value): - from warnings import warn - warn("Attribute access from plist dicts is deprecated, use d[key] " - "notation instead", PendingDeprecationWarning) - self[attr] = value - - def __delattr__(self, attr): - try: - del self[attr] - except KeyError: - raise AttributeError(attr) - from warnings import warn - warn("Attribute access from plist dicts is deprecated, use d[key] " - "notation instead", PendingDeprecationWarning) - -class Dict(_InternalDict): - - def __init__(self, **kwargs): - from warnings import warn - warn("The plistlib.Dict class is deprecated, use builtin dict instead", - PendingDeprecationWarning) - super().__init__(**kwargs) - - -class Plist(_InternalDict): - - """This class has been deprecated. Use readPlist() and writePlist() - functions instead, together with regular dict objects. - """ - - def __init__(self, **kwargs): - from warnings import warn - warn("The Plist class is deprecated, use the readPlist() and " - "writePlist() functions instead", PendingDeprecationWarning) - super().__init__(**kwargs) - - def fromFile(cls, pathOrFile): - """Deprecated. Use the readPlist() function instead.""" - rootObject = readPlist(pathOrFile) - plist = cls() - plist.update(rootObject) - return plist - fromFile = classmethod(fromFile) - - def write(self, pathOrFile): - """Deprecated. Use the writePlist() function instead.""" - writePlist(self, pathOrFile) - - -def _encodeBase64(s, maxlinelength=76): - # copied from base64.encodestring(), with added maxlinelength argument - maxbinsize = (maxlinelength//4)*3 - pieces = [] - for i in range(0, len(s), maxbinsize): - chunk = s[i : i + maxbinsize] - pieces.append(binascii.b2a_base64(chunk)) - return b''.join(pieces) - -class Data: - - """Wrapper for binary data.""" - - def __init__(self, data): - if not isinstance(data, bytes): - raise TypeError("data must be as bytes") - self.data = data - - @classmethod - def fromBase64(cls, data): - # base64.decodestring just calls binascii.a2b_base64; - # it seems overkill to use both base64 and binascii. - return cls(binascii.a2b_base64(data)) - - def asBase64(self, maxlinelength=76): - return _encodeBase64(self.data, maxlinelength) - - def __eq__(self, other): - if isinstance(other, self.__class__): - return self.data == other.data - elif isinstance(other, str): - return self.data == other - else: - return id(self) == id(other) - - def __repr__(self): - return "%s(%s)" % (self.__class__.__name__, repr(self.data)) - - -class PlistParser: - - def __init__(self): - self.stack = [] - self.currentKey = None - self.root = None - - def parse(self, fileobj): - from xml.parsers.expat import ParserCreate - parser = ParserCreate() - parser.StartElementHandler = self.handleBeginElement - parser.EndElementHandler = self.handleEndElement - parser.CharacterDataHandler = self.handleData - parser.ParseFile(fileobj) - return self.root - - def handleBeginElement(self, element, attrs): - self.data = [] - handler = getattr(self, "begin_" + element, None) - if handler is not None: - handler(attrs) - - def handleEndElement(self, element): - handler = getattr(self, "end_" + element, None) - if handler is not None: - handler() - - def handleData(self, data): - self.data.append(data) - - def addObject(self, value): - if self.currentKey is not None: - self.stack[-1][self.currentKey] = value - self.currentKey = None - elif not self.stack: - # this is the root object - self.root = value - else: - self.stack[-1].append(value) - - def getData(self): - data = ''.join(self.data) - self.data = [] - return data - - # element handlers - - def begin_dict(self, attrs): - d = _InternalDict() - self.addObject(d) - self.stack.append(d) - def end_dict(self): - self.stack.pop() - - def end_key(self): - self.currentKey = self.getData() - - def begin_array(self, attrs): - a = [] - self.addObject(a) - self.stack.append(a) - def end_array(self): - self.stack.pop() - - def end_true(self): - self.addObject(True) - def end_false(self): - self.addObject(False) - def end_integer(self): - self.addObject(int(self.getData())) - def end_real(self): - self.addObject(float(self.getData())) - def end_string(self): - self.addObject(self.getData()) - def end_data(self): - self.addObject(Data.fromBase64(self.getData().encode("utf-8"))) - def end_date(self): - self.addObject(_dateFromString(self.getData())) Modified: python/branches/py3k-ctypes-pep3118/Lib/pprint.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/pprint.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/pprint.py Thu Jan 24 22:12:24 2008 @@ -159,11 +159,24 @@ write('}') return - if (issubclass(typ, list) and r is list.__repr__) or \ - (issubclass(typ, tuple) and r is tuple.__repr__): + if ((issubclass(typ, list) and r is list.__repr__) or + (issubclass(typ, tuple) and r is tuple.__repr__) or + (issubclass(typ, set) and r is set.__repr__) or + (issubclass(typ, frozenset) and r is frozenset.__repr__) + ): if issubclass(typ, list): write('[') endchar = ']' + elif issubclass(typ, set): + write('{') + endchar = '}' + object = sorted(object) + indent += 4 + elif issubclass(typ, frozenset): + write('frozenset([') + endchar = '])' + object = sorted(object) + indent += 9 else: write('(') endchar = ')' Modified: python/branches/py3k-ctypes-pep3118/Lib/pstats.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/pstats.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/pstats.py Thu Jan 24 22:12:24 2008 @@ -511,7 +511,8 @@ new_callers[func] = caller for func, caller in source.items(): if func in new_callers: - new_callers[func] = caller + new_callers[func] + new_callers[func] = tuple([i[0] + i[1] for i in + zip(caller, new_callers[func])]) else: new_callers[func] = caller return new_callers Modified: python/branches/py3k-ctypes-pep3118/Lib/pydoc.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/pydoc.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/pydoc.py Thu Jan 24 22:12:24 2008 @@ -27,7 +27,7 @@ Module docs for core modules are assumed to be in - http://www.python.org/doc/current/lib/ + http://docs.python.org/library/ This can be overridden by setting the PYTHONDOCS environment variable to a different URL or to a local directory containing the Library @@ -341,7 +341,7 @@ file = '(built-in)' docloc = os.environ.get("PYTHONDOCS", - "http://www.python.org/doc/current/lib") + "http://docs.python.org/library") basedir = os.path.join(sys.exec_prefix, "lib", "python"+sys.version[0:3]) if (isinstance(object, type(os)) and @@ -350,11 +350,10 @@ 'thread', 'zipimport') or (file.startswith(basedir) and not file.startswith(os.path.join(basedir, 'site-packages'))))): - htmlfile = "module-%s.html" % object.__name__ if docloc.startswith("http://"): - docloc = "%s/%s" % (docloc.rstrip("/"), htmlfile) + docloc = "%s/%s" % (docloc.rstrip("/"), object.__name__) else: - docloc = os.path.join(docloc, htmlfile) + docloc = os.path.join(docloc, object.__name__ + ".html") else: docloc = None return docloc @@ -537,7 +536,7 @@ url = 'http://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc) results.append('%s' % (url, escape(all))) elif pep: - url = 'http://www.python.org/peps/pep-%04d.html' % int(pep) + url = 'http://www.python.org/peps/pep-%04d' % int(pep) results.append('%s' % (url, escape(all))) elif text[end:end+1] == '(': results.append(self.namelink(name, methods, funcs, classes)) @@ -1056,9 +1055,11 @@ if visiblename(key, all): data.append((key, value)) + modpkgs = [] + modpkgs_names = set() if hasattr(object, '__path__'): - modpkgs = [] for importer, modname, ispkg in pkgutil.iter_modules(object.__path__): + modpkgs_names.add(modname) if ispkg: modpkgs.append(modname + ' (package)') else: @@ -1068,6 +1069,16 @@ result = result + self.section( 'PACKAGE CONTENTS', '\n'.join(modpkgs)) + # Detect submodules as sometimes created by C extensions + submodules = [] + for key, value in inspect.getmembers(object, inspect.ismodule): + if value.__name__.startswith(name + '.') and key not in modpkgs_names: + submodules.append(key) + if submodules: + submodules.sort() + result = result + self.section( + 'SUBMODULES', join(submodules, '\n')) + if classes: classlist = [value for key, value in classes] contents = [self.formattree( @@ -1729,7 +1740,7 @@ Welcome to Python %s! This is the online help utility. If this is your first time using Python, you should definitely check out -the tutorial on the Internet at http://www.python.org/doc/tut/. +the tutorial on the Internet at http://docs.python.org/tutorial/. Enter the name of any module, keyword, or topic to get help on writing Python programs and using Python modules. To quit this help utility and Modified: python/branches/py3k-ctypes-pep3118/Lib/rational.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/rational.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/rational.py Thu Jan 24 22:12:24 2008 @@ -171,6 +171,42 @@ else: return cls(digits, 10 ** -exp) + @classmethod + def from_continued_fraction(cls, seq): + 'Build a Rational from a continued fraction expessed as a sequence' + n, d = 1, 0 + for e in reversed(seq): + n, d = d, n + n += e * d + return cls(n, d) if seq else cls(0) + + def as_continued_fraction(self): + 'Return continued fraction expressed as a list' + n = self.numerator + d = self.denominator + cf = [] + while d: + e = int(n // d) + cf.append(e) + n -= e * d + n, d = d, n + return cf + + @classmethod + def approximate_from_float(cls, f, max_denominator): + 'Best rational approximation to f with a denominator <= max_denominator' + # XXX First cut at algorithm + # Still needs rounding rules as specified at + # http://en.wikipedia.org/wiki/Continued_fraction + cf = cls.from_float(f).as_continued_fraction() + result = Rational(0) + for i in range(1, len(cf)): + new = cls.from_continued_fraction(cf[:i]) + if new.denominator > max_denominator: + break + result = new + return result + @property def numerator(a): return a._numerator Modified: python/branches/py3k-ctypes-pep3118/Lib/re.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/re.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/re.py Thu Jan 24 22:12:24 2008 @@ -29,7 +29,8 @@ The special characters are: "." Matches any character except a newline. "^" Matches the start of the string. - "$" Matches the end of the string. + "$" Matches the end of the string or just before the newline at + the end of the string. "*" Matches 0 or more (greedy) repetitions of the preceding RE. Greedy means that it will match as many repetitions as possible. "+" Matches 1 or more (greedy) repetitions of the preceding RE. @@ -83,8 +84,10 @@ Some of the functions in this module takes flags as optional parameters: I IGNORECASE Perform case-insensitive matching. L LOCALE Make \w, \W, \b, \B, dependent on the current locale. - M MULTILINE "^" matches the beginning of lines as well as the string. - "$" matches the end of lines as well as the string. + M MULTILINE "^" matches the beginning of lines (after a newline) + as well as the string. + "$" matches the end of lines (before a newline) as well + as the end of the string. S DOTALL "." matches any character at all, including the newline. X VERBOSE Ignore whitespace and comments for nicer looking RE's. U UNICODE Make \w, \W, \b, \B, dependent on the Unicode locale. Modified: python/branches/py3k-ctypes-pep3118/Lib/shutil.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/shutil.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/shutil.py Thu Jan 24 22:12:24 2008 @@ -156,6 +156,14 @@ elif onerror is None: def onerror(*args): raise + try: + if os.path.islink(path): + # symlinks to directories are forbidden, see bug #1669 + raise OSError("Cannot call rmtree on a symbolic link") + except OSError: + onerror(os.path.islink, path, sys.exc_info()) + # can't continue even if onerror hook returns + return names = [] try: names = os.listdir(path) Modified: python/branches/py3k-ctypes-pep3118/Lib/site.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/site.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/site.py Thu Jan 24 22:12:24 2008 @@ -96,6 +96,8 @@ (especially for Guido :-)""" from distutils.util import get_platform s = "build/lib.%s-%.3s" % (get_platform(), sys.version) + if hasattr(sys, 'gettotalrefcount'): + s += '-pydebug' s = os.path.join(os.path.dirname(sys.path[-1]), s) sys.path.append(s) Modified: python/branches/py3k-ctypes-pep3118/Lib/test/pydocfodder.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/pydocfodder.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/pydocfodder.py Thu Jan 24 22:12:24 2008 @@ -1,5 +1,7 @@ """Something just to look at via pydoc.""" +import types + class A_classic: "A classic class." def A_method(self): @@ -208,3 +210,7 @@ del inst.desc[self.attr] x = property(get_desc('x'), set_desc('x'), del_desc('x'), 'prop x') + + +submodule = types.ModuleType(__name__ + '.submodule', + """A submodule, which should appear in its parent's summary""") Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_builtin.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_builtin.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_builtin.py Thu Jan 24 22:12:24 2008 @@ -1100,18 +1100,6 @@ def test_map(self): self.assertEqual( - list(map(None, 'hello')), - [('h',), ('e',), ('l',), ('l',), ('o',)] - ) - self.assertEqual( - list(map(None, 'abcd', 'efg')), - [('a', 'e'), ('b', 'f'), ('c', 'g')] - ) - self.assertEqual( - list(map(None, range(3))), - [(0,), (1,), (2,)] - ) - self.assertEqual( list(map(lambda x: x*x, range(1,4))), [1, 4, 9] ) @@ -1146,17 +1134,9 @@ [1+4+1, 3+9+1, 7+2+0] ) self.assertEqual( - list(map(None, Squares(10))), - [(0,), (1,), (4,), (9,), (16,), (25,), (36,), (49,), (64,), (81,)] - ) - self.assertEqual( list(map(int, Squares(10))), [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] ) - self.assertEqual( - list(map(None, Squares(3), Squares(2))), - [(0,0), (1,1)] - ) def Max(a, b): if a is None: return b @@ -1169,7 +1149,6 @@ ) self.assertRaises(TypeError, map) self.assertRaises(TypeError, map, lambda x: x, 42) - self.assertEqual(list(map(None, [42])), [(42,)]) class BadSeq: def __iter__(self): raise ValueError Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_descr.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_descr.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_descr.py Thu Jan 24 22:12:24 2008 @@ -1,7 +1,7 @@ # Test enhancements related to descriptors and new-style classes -from test.test_support import verify, vereq, verbose, TestFailed, TESTFN -from test.test_support import get_original_stdout +# XXX Please, please, please, someone convert this to unittest style! +from test.test_support import verify, vereq, verbose, TestFailed, TESTFN, get_original_stdout from copy import deepcopy import types @@ -4173,6 +4173,8 @@ # ceval.c's assign_slice used to check for # tp->tp_as_sequence->sq_slice instead of # tp->tp_as_sequence->sq_ass_slice + if verbose: + print("Testing assign_slice...") class C(object): def __setitem__(self, idx, value): @@ -4182,6 +4184,70 @@ c[1:2] = 3 vereq(c.value, 3) +def test_weakref_in_del_segfault(): + # This used to segfault until r60057 + if verbose: + print("Testing weakref in del segfault...") + + import weakref + global ref + + class Target(): + def __del__(self): + global ref + ref = weakref.ref(self) + + w = Target() + del w + del ref + +def test_borrowed_ref_3_segfault(): + # This used to segfault until r60224 + if verbose: + print("Testing borrowed ref 3 segfault...") + + class KeyFunc(object): + def __call__(self, n): + del d['key'] + return 1 + + d = {'key': KeyFunc()} + try: + min(range(10), **d) + except: + pass + +def test_borrowed_ref_4_segfault(): + # This used to segfault until r60224 + if verbose: + print("Testing borrowed ref 4 segfault...") + + import types + import builtins + + class X(object): + def __getattr__(self, name): + # this is called with name == '__bases__' by PyObject_IsInstance() + # during the unbound method call -- it frees the unbound method + # itself before it invokes its im_func. + del builtins.__import__ + return () + + pseudoclass = X() + + class Y(object): + def __call__(self, *args): + # 'self' was freed already + return (self, args) + + # make an unbound method + orig_import = __import__ + try: + builtins.__import__ = types.MethodType(Y(), (pseudoclass, str)) + import spam + finally: + builtins.__import__ = orig_import + def test_main(): weakref_segfault() # Must be first, somehow wrapper_segfault() # NB This one is slow @@ -4279,6 +4345,9 @@ methodwrapper() notimplemented() test_assign_slice() + test_weakref_in_del_segfault() + test_borrowed_ref_3_segfault() + test_borrowed_ref_4_segfault() if verbose: print("All OK") Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_grp.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_grp.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_grp.py Thu Jan 24 22:12:24 2008 @@ -25,6 +25,9 @@ for e in entries: self.check_value(e) + if len(entries) > 1000: # Huge group file (NIS?) -- skip the rest + return + for e in entries: e2 = grp.getgrgid(e.gr_gid) self.check_value(e2) Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_iter.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_iter.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_iter.py Thu Jan 24 22:12:24 2008 @@ -382,13 +382,10 @@ # Test map()'s use of iterators. def test_builtin_map(self): - self.assertEqual(list(map(None, SequenceClass(5))), - [(0,), (1,), (2,), (3,), (4,)]) self.assertEqual(list(map(lambda x: x+1, SequenceClass(5))), list(range(1, 6))) d = {"one": 1, "two": 2, "three": 3} - self.assertEqual(list(map(None, d)), [(k,) for k in d]) self.assertEqual(list(map(lambda k, d=d: (k, d[k]), d)), list(d.items())) dkeys = list(d.keys()) @@ -396,11 +393,6 @@ i, i < len(d) and dkeys[i] or None) for i in range(3)] - self.assertEqual(list(map(None, - d, - SequenceClass(5), - iter(d.keys()))), - expected) f = open(TESTFN, "w") try: Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_itertools.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_itertools.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_itertools.py Thu Jan 24 22:12:24 2008 @@ -236,7 +236,7 @@ self.assertEqual(list(izip_longest('abcdef')), list(zip('abcdef'))) self.assertEqual(list(izip_longest('abc', 'defg', **{})), - list(map(None, list('abc')+[None], 'defg'))) # empty keyword dict + list(izip(list('abc')+[None], 'defg'))) # empty keyword dict self.assertRaises(TypeError, izip_longest, 3) self.assertRaises(TypeError, izip_longest, range(3), 3) @@ -281,14 +281,17 @@ def test_imap(self): self.assertEqual(list(imap(operator.pow, range(3), range(1,7))), [0**1, 1**2, 2**3]) - self.assertEqual(list(imap(None, 'abc', range(5))), + def tupleize(*args): + return args + self.assertEqual(list(imap(tupleize, 'abc', range(5))), [('a',0),('b',1),('c',2)]) - self.assertEqual(list(imap(None, 'abc', count())), + self.assertEqual(list(imap(tupleize, 'abc', count())), [('a',0),('b',1),('c',2)]) - self.assertEqual(take(2,imap(None, 'abc', count())), + self.assertEqual(take(2,imap(tupleize, 'abc', count())), [('a',0),('b',1)]) self.assertEqual(list(imap(operator.pow, [])), []) self.assertRaises(TypeError, imap) + self.assertRaises(TypeError, list, imap(None, range(3), range(3))) self.assertRaises(TypeError, imap, operator.neg) self.assertRaises(TypeError, next, imap(10, range(5))) self.assertRaises(ValueError, next, imap(errfunc, [4], [5])) Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_largefile.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_largefile.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_largefile.py Thu Jan 24 22:12:24 2008 @@ -6,7 +6,7 @@ #---------------------------------------------------------------------- from test import test_support -import os, struct, stat, sys +import os, stat, sys try: import signal Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_mmap.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_mmap.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_mmap.py Thu Jan 24 22:12:24 2008 @@ -419,6 +419,13 @@ except OSError: pass + def test_subclass(self): + class anon_mmap(mmap.mmap): + def __new__(klass, *args, **kwargs): + return mmap.mmap.__new__(klass, -1, *args, **kwargs) + anon_mmap(PAGESIZE) + + def test_main(): run_unittest(MmapTests) Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_operator.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_operator.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_operator.py Thu Jan 24 22:12:24 2008 @@ -364,9 +364,9 @@ self.assertRaises(TypeError, operator.attrgetter('x', (), 'y'), record) class C(object): - def __getattr(self, name): + def __getattr__(self, name): raise SyntaxError - self.failUnlessRaises(AttributeError, operator.attrgetter('foo'), C()) + self.failUnlessRaises(SyntaxError, operator.attrgetter('foo'), C()) def test_itemgetter(self): a = 'ABCDE' @@ -376,9 +376,9 @@ self.assertRaises(IndexError, f, a) class C(object): - def __getitem(self, name): + def __getitem__(self, name): raise SyntaxError - self.failUnlessRaises(TypeError, operator.itemgetter(42), C()) + self.failUnlessRaises(SyntaxError, operator.itemgetter(42), C()) f = operator.itemgetter('name') self.assertRaises(TypeError, f, a) Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_pep263.py ============================================================================== Binary files. No diff available. Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_profilehooks.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_profilehooks.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_profilehooks.py Thu Jan 24 22:12:24 2008 @@ -4,6 +4,22 @@ from test import test_support +class TestGetProfile(unittest.TestCase): + def setUp(self): + sys.setprofile(None) + + def tearDown(self): + sys.setprofile(None) + + def test_empty(self): + assert sys.getprofile() == None + + def test_setget(self): + def fn(*args): + pass + + sys.setprofile(fn) + assert sys.getprofile() == fn class HookWatcher: def __init__(self): @@ -359,6 +375,7 @@ def test_main(): test_support.run_unittest( + TestGetProfile, ProfileHookTestCase, ProfileSimulatorTestCase ) Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_pwd.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_pwd.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_pwd.py Thu Jan 24 22:12:24 2008 @@ -35,6 +35,9 @@ entriesbyname.setdefault(e.pw_name, []).append(e) entriesbyuid.setdefault(e.pw_uid, []).append(e) + if len(entries) > 1000: # Huge passwd file (NIS?) -- skip the rest + return + # check whether the entry returned by getpwuid() # for each uid is among those from getpwall() for this uid for e in entries: Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_pyclbr.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_pyclbr.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_pyclbr.py Thu Jan 24 22:12:24 2008 @@ -158,6 +158,7 @@ cm('cgi', ignore=('log',)) # set with = in module cm('mhlib') cm('urllib', ignore=('getproxies_registry', + 'proxy_bypass_registry', 'open_https', '_https_connection', 'getproxies_internetconfig',)) # not on all platforms Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_rational.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_rational.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_rational.py Thu Jan 24 22:12:24 2008 @@ -135,6 +135,29 @@ TypeError, "Cannot convert sNaN to Rational.", R.from_decimal, Decimal("snan")) + def testFromContinuedFraction(self): + self.assertRaises(TypeError, R.from_continued_fraction, None) + phi = R.from_continued_fraction([1]*100) + self.assertEquals(round(phi - (1 + 5 ** 0.5) / 2, 10), 0.0) + + minusphi = R.from_continued_fraction([-1]*100) + self.assertEquals(round(minusphi + (1 + 5 ** 0.5) / 2, 10), 0.0) + + self.assertEquals(R.from_continued_fraction([0]), R(0)) + self.assertEquals(R.from_continued_fraction([]), R(0)) + + def testAsContinuedFraction(self): + self.assertEqual(R.from_float(math.pi).as_continued_fraction()[:15], + [3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 3, 3]) + self.assertEqual(R.from_float(-math.pi).as_continued_fraction()[:16], + [-4, 1, 6, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 3, 3]) + self.assertEqual(R(0).as_continued_fraction(), [0]) + + def testApproximateFromFloat(self): + self.assertEqual(R.approximate_from_float(math.pi, 10000), R(355, 113)) + self.assertEqual(R.approximate_from_float(-math.pi, 10000), R(-355, 113)) + self.assertEqual(R.approximate_from_float(0.0, 10000), R(0)) + def testConversions(self): self.assertTypedEquals(-1, trunc(R(-11, 10))) self.assertTypedEquals(-2, math.floor(R(-11, 10))) Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_shutil.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_shutil.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_shutil.py Thu Jan 24 22:12:24 2008 @@ -149,6 +149,20 @@ except OSError: pass + def test_rmtree_on_symlink(self): + # bug 1669. + os.mkdir(TESTFN) + try: + src = os.path.join(TESTFN, 'cheese') + dst = os.path.join(TESTFN, 'shop') + os.mkdir(src) + os.symlink(src, dst) + self.assertRaises(OSError, shutil.rmtree, dst) + finally: + shutil.rmtree(TESTFN, ignore_errors=True) + + + def test_main(): test_support.run_unittest(TestShutil) Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_structmembers.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_structmembers.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_structmembers.py Thu Jan 24 22:12:24 2008 @@ -8,52 +8,59 @@ import warnings, unittest, sys from test import test_support -ts=test_structmembersType(1,2,3,4,5,6,7,8,9.99999,10.1010101010) +ts=test_structmembersType(False, 1, 2, 3, 4, 5, 6, 7, 8, + 9.99999, 10.1010101010) class ReadWriteTests(unittest.TestCase): def test_types(self): - ts.T_BYTE=CHAR_MAX + ts.T_BOOL = True + self.assertEquals(ts.T_BOOL, True) + ts.T_BOOL = False + self.assertEquals(ts.T_BOOL, False) + self.assertRaises(TypeError, setattr, ts, 'T_BOOL', 1) + + ts.T_BYTE = CHAR_MAX self.assertEquals(ts.T_BYTE, CHAR_MAX) - ts.T_BYTE=CHAR_MIN + ts.T_BYTE = CHAR_MIN self.assertEquals(ts.T_BYTE, CHAR_MIN) - ts.T_UBYTE=UCHAR_MAX + ts.T_UBYTE = UCHAR_MAX self.assertEquals(ts.T_UBYTE, UCHAR_MAX) - ts.T_SHORT=SHRT_MAX + ts.T_SHORT = SHRT_MAX self.assertEquals(ts.T_SHORT, SHRT_MAX) - ts.T_SHORT=SHRT_MIN + ts.T_SHORT = SHRT_MIN self.assertEquals(ts.T_SHORT, SHRT_MIN) - ts.T_USHORT=USHRT_MAX + ts.T_USHORT = USHRT_MAX self.assertEquals(ts.T_USHORT, USHRT_MAX) - ts.T_INT=INT_MAX + ts.T_INT = INT_MAX self.assertEquals(ts.T_INT, INT_MAX) - ts.T_INT=INT_MIN + ts.T_INT = INT_MIN self.assertEquals(ts.T_INT, INT_MIN) - ts.T_UINT=UINT_MAX + ts.T_UINT = UINT_MAX self.assertEquals(ts.T_UINT, UINT_MAX) - ts.T_LONG=LONG_MAX + ts.T_LONG = LONG_MAX self.assertEquals(ts.T_LONG, LONG_MAX) - ts.T_LONG=LONG_MIN + ts.T_LONG = LONG_MIN self.assertEquals(ts.T_LONG, LONG_MIN) - ts.T_ULONG=ULONG_MAX + ts.T_ULONG = ULONG_MAX self.assertEquals(ts.T_ULONG, ULONG_MAX) ## T_LONGLONG and T_ULONGLONG may not be present on some platforms if hasattr(ts, 'T_LONGLONG'): - ts.T_LONGLONG=LLONG_MAX + ts.T_LONGLONG = LLONG_MAX self.assertEquals(ts.T_LONGLONG, LLONG_MAX) - ts.T_LONGLONG=LLONG_MIN + ts.T_LONGLONG = LLONG_MIN self.assertEquals(ts.T_LONGLONG, LLONG_MIN) - ts.T_ULONGLONG=ULLONG_MAX + ts.T_ULONGLONG = ULLONG_MAX self.assertEquals(ts.T_ULONGLONG, ULLONG_MAX) ## make sure these will accept a plain int as well as a long - ts.T_LONGLONG=3 + ts.T_LONGLONG = 3 self.assertEquals(ts.T_LONGLONG, 3) - ts.T_ULONGLONG=4 + ts.T_ULONGLONG = 4 self.assertEquals(ts.T_ULONGLONG, 4) @@ -63,32 +70,32 @@ def test_byte_max(self): with test_support.catch_warning() as w: - ts.T_BYTE=CHAR_MAX+1 + ts.T_BYTE = CHAR_MAX+1 self.has_warned(w) def test_byte_min(self): with test_support.catch_warning() as w: - ts.T_BYTE=CHAR_MIN-1 + ts.T_BYTE = CHAR_MIN-1 self.has_warned(w) def test_ubyte_max(self): with test_support.catch_warning() as w: - ts.T_UBYTE=UCHAR_MAX+1 + ts.T_UBYTE = UCHAR_MAX+1 self.has_warned(w) def test_short_max(self): with test_support.catch_warning() as w: - ts.T_SHORT=SHRT_MAX+1 + ts.T_SHORT = SHRT_MAX+1 self.has_warned(w) def test_short_min(self): with test_support.catch_warning() as w: - ts.T_SHORT=SHRT_MIN-1 + ts.T_SHORT = SHRT_MIN-1 self.has_warned(w) def test_ushort_max(self): with test_support.catch_warning() as w: - ts.T_USHORT=USHRT_MAX+1 + ts.T_USHORT = USHRT_MAX+1 self.has_warned(w) Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_threading.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_threading.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_threading.py Thu Jan 24 22:12:24 2008 @@ -236,6 +236,24 @@ """]) self.assertEqual(rc, 42) + def test_enumerate_after_join(self): + # Try hard to trigger #1703448: a thread is still returned in + # threading.enumerate() after it has been join()ed. + enum = threading.enumerate + old_interval = sys.getcheckinterval() + sys.setcheckinterval(1) + try: + for i in range(1, 1000): + t = threading.Thread(target=lambda: None) + t.start() + t.join() + l = enum() + self.assertFalse(t in l, + "#1703448 triggered after %d trials: %s" % (i, l)) + finally: + sys.setcheckinterval(old_interval) + + class ThreadingExceptionTests(unittest.TestCase): # A RuntimeError should be raised if Thread.start() is called # multiple times. Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_trace.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_trace.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_trace.py Thu Jan 24 22:12:24 2008 @@ -268,6 +268,20 @@ self.compare_events(func.__code__.co_firstlineno, tracer.events, func.events) + def set_and_retrieve_none(self): + sys.settrace(None) + assert sys.gettrace() is None + + def set_and_retrieve_func(self): + def fn(*args): + pass + + sys.settrace(fn) + try: + assert sys.gettrace() is fn + finally: + sys.settrace(None) + def test_01_basic(self): self.run_test(basic) def test_02_arigo(self): Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_urllib.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_urllib.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_urllib.py Thu Jan 24 22:12:24 2008 @@ -47,7 +47,7 @@ def test_interface(self): # Make sure object returned by urlopen() has the specified methods for attr in ("read", "readline", "readlines", "fileno", - "close", "info", "geturl", "__iter__"): + "close", "info", "geturl", "getcode", "__iter__"): self.assert_(hasattr(self.returned_obj, attr), "object returned by urlopen() lacks %s attribute" % attr) @@ -87,6 +87,9 @@ def test_geturl(self): self.assertEqual(self.returned_obj.geturl(), self.pathname) + def test_getcode(self): + self.assertEqual(self.returned_obj.getcode(), None) + def test_iter(self): # Test iterator # Don't need to count number of iterations since test would fail the @@ -123,6 +126,8 @@ fp = urllib.urlopen("http://python.org/") self.assertEqual(fp.readline(), b"Hello!") self.assertEqual(fp.readline(), b"") + self.assertEqual(fp.geturl(), 'http://python.org/') + self.assertEqual(fp.getcode(), 200) finally: self.unfakehttp() Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_urllibnet.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_urllibnet.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_urllibnet.py Thu Jan 24 22:12:24 2008 @@ -83,6 +83,16 @@ open_url.close() self.assertEqual(gotten_url, URL) + def test_getcode(self): + # test getcode() with the fancy opener to get 404 error codes + URL = "http://www.python.org/XXXinvalidXXX" + open_url = urllib.FancyURLopener().open(URL) + try: + code = open_url.getcode() + finally: + open_url.close() + self.assertEqual(code, 404) + def test_fileno(self): if (sys.platform in ('win32',) or not hasattr(os, 'fdopen')): Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_winreg.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_winreg.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_winreg.py Thu Jan 24 22:12:24 2008 @@ -73,7 +73,7 @@ key = OpenKey(root_key, test_key_name) # Read the sub-keys - with OpenKey(key, "sub_key") as sub_key: + with OpenKey(key, subkeystr) as sub_key: # Check I can enumerate over the values. index = 0 while 1: Modified: python/branches/py3k-ctypes-pep3118/Lib/threading.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/threading.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/threading.py Thu Jan 24 22:12:24 2008 @@ -346,27 +346,18 @@ return self._flag def set(self): - self._cond.acquire() - try: + with self._cond: self._flag = True self._cond.notifyAll() - finally: - self._cond.release() def clear(self): - self._cond.acquire() - try: + with self._cond: self._flag = False - finally: - self._cond.release() def wait(self, timeout=None): - self._cond.acquire() - try: + with self._cond: if not self._flag: self._cond.wait(timeout) - finally: - self._cond.release() # Helper to generate new thread names _counter = 0 @@ -523,17 +514,19 @@ if __debug__: self._note("%s.__bootstrap(): normal return", self) finally: - self._stop() - try: - self._delete() - except: - pass + with _active_limbo_lock: + self._stop() + try: + # We don't call self.__delete() because it also + # grabs _active_limbo_lock. + del _active[_get_ident()] + except: + pass def _stop(self): - self._block.acquire() - self._stopped = True - self._block.notifyAll() - self._block.release() + with self._block: + self._stopped = True + self._block.notifyAll() def _delete(self): "Remove current thread from the dict of currently running threads." @@ -559,15 +552,12 @@ # since it isn't if dummy_threading is *not* being used then don't # hide the exception. - _active_limbo_lock.acquire() - try: + with _active_limbo_lock: try: del _active[_get_ident()] except KeyError: if 'dummy_threading' not in _sys.modules: raise - finally: - _active_limbo_lock.release() def join(self, timeout=None): if not self._initialized: @@ -580,8 +570,7 @@ if __debug__: if not self._stopped: self._note("%s.join(): waiting until thread stops", self) - self._block.acquire() - try: + with self._block: if timeout is None: while not self._stopped: self._block.wait() @@ -599,8 +588,6 @@ else: if __debug__: self._note("%s.join(): thread stopped", self) - finally: - self._block.release() def getName(self): assert self._initialized, "Thread.__init__() not called" Modified: python/branches/py3k-ctypes-pep3118/Lib/urllib.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/urllib.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/urllib.py Thu Jan 24 22:12:24 2008 @@ -557,7 +557,7 @@ def http_error_default(self, url, fp, errcode, errmsg, headers): """Default error handling -- don't raise an exception.""" - return addinfourl(fp, headers, "http:" + url) + return addinfourl(fp, headers, "http:" + url, errcode) def http_error_302(self, url, fp, errcode, errmsg, headers, data=None): """Error 302 -- relocated (temporarily).""" @@ -815,9 +815,19 @@ if not conn: # Set transfer mode to ASCII! self.ftp.voidcmd('TYPE A') - # Try a directory listing - if file: cmd = 'LIST ' + file - else: cmd = 'LIST' + # Try a directory listing. Verify that directory exists. + if file: + pwd = self.ftp.pwd() + try: + try: + self.ftp.cwd(file) + except ftplib.error_perm as reason: + raise IOError('ftp error', reason) from reason + finally: + self.ftp.cwd(pwd) + cmd = 'LIST ' + file + else: + cmd = 'LIST' conn = self.ftp.ntransfercmd(cmd) self.busy = 1 # Pass back both a suitably decorated object and a retrieval length @@ -898,14 +908,18 @@ class addinfourl(addbase): """class to add info() and geturl() methods to an open file.""" - def __init__(self, fp, headers, url): + def __init__(self, fp, headers, url, code=None): addbase.__init__(self, fp) self.headers = headers self.url = url + self.code = code def info(self): return self.headers + def getcode(self): + return self.code + def geturl(self): return self.url @@ -1228,10 +1242,33 @@ proxies = {} for name, value in os.environ.items(): name = name.lower() + if name == 'no_proxy': + # handled in proxy_bypass_environment + continue if value and name[-6:] == '_proxy': proxies[name[:-6]] = value return proxies +def proxy_bypass_environment(host): + """Test if proxies should not be used for a particular host. + + Checks the environment for a variable named no_proxy, which should + be a list of DNS suffixes separated by commas, or '*' for all hosts. + """ + no_proxy = os.environ.get('no_proxy', '') or os.environ.get('NO_PROXY', '') + # '*' is special case for always bypass + if no_proxy == '*': + return 1 + # strip port off host + hostonly, port = splitport(host) + # check if the host ends with any of the DNS suffixes + for name in no_proxy.split(','): + if name and (hostonly.endswith(name) or host.endswith(name)): + return 1 + # otherwise, don't bypass + return 0 + + if sys.platform == 'darwin': def getproxies_internetconfig(): """Return a dictionary of scheme -> proxy server URL mappings. @@ -1259,12 +1296,15 @@ pass else: proxies['http'] = 'http://%s' % value - # FTP: XXXX To be done. - # Gopher: XXXX To be done. + # FTP: XXX To be done. + # Gopher: XXX To be done. return proxies - def proxy_bypass(x): - return 0 + def proxy_bypass(host): + if getproxies_environment(): + return proxy_bypass_environment(host) + else: + return 0 def getproxies(): return getproxies_environment() or getproxies_internetconfig() @@ -1324,7 +1364,7 @@ """ return getproxies_environment() or getproxies_registry() - def proxy_bypass(host): + def proxy_bypass_registry(host): try: import _winreg import re @@ -1383,12 +1423,22 @@ return 1 return 0 + def proxy_bypass(host): + """Return a dictionary of scheme -> proxy server URL mappings. + + Returns settings gathered from the environment, if specified, + or the registry. + + """ + if getproxies_environment(): + return proxy_bypass_environment(host) + else: + return proxy_bypass_registry(host) + else: # By default use environment variables getproxies = getproxies_environment - - def proxy_bypass(host): - return 0 + proxy_bypass = proxy_bypass_environment # Test and time quote() and unquote() def test1(): Modified: python/branches/py3k-ctypes-pep3118/Lib/urllib2.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/urllib2.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/urllib2.py Thu Jan 24 22:12:24 2008 @@ -1286,7 +1286,7 @@ headers = mimetools.Message(sf) return addinfourl(fp, headers, req.get_full_url()) except ftplib.all_errors as msg: - raise URLError('ftp error %s' % msg).with_traceback(sys.exc_info()[2]) + raise URLError('ftp error: %s' % msg).with_traceback(sys.exc_info()[2]) def connect_ftp(self, user, passwd, host, port, dirs, timeout): fw = ftpwrapper(user, passwd, host, port, dirs, timeout) Modified: python/branches/py3k-ctypes-pep3118/Lib/urlparse.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/urlparse.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/urlparse.py Thu Jan 24 22:12:24 2008 @@ -305,9 +305,7 @@ else: from io import StringIO fp = StringIO(test_input) - while 1: - line = fp.readline() - if not line: break + for line in fp: words = line.split() if not words: continue Modified: python/branches/py3k-ctypes-pep3118/Makefile.pre.in ============================================================================== --- python/branches/py3k-ctypes-pep3118/Makefile.pre.in (original) +++ python/branches/py3k-ctypes-pep3118/Makefile.pre.in Thu Jan 24 22:12:24 2008 @@ -223,6 +223,10 @@ Parser/printgrammar.o \ Parser/pgenmain.o +PARSER_HEADERS= \ + Parser/parser.h \ + Parser/tokenizer.h + PGENOBJS= $(PGENMAIN) $(POBJS) $(PGOBJS) ########################################################################## @@ -356,7 +360,7 @@ # Build the shared modules sharedmods: $(BUILDPYTHON) @case $$MAKEFLAGS in \ - *-s*) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' ./$(BUILDPYTHON) -E $(srcdir)/setup.py -q build;; \ + *s*) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' ./$(BUILDPYTHON) -E $(srcdir)/setup.py -q build;; \ *) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' ./$(BUILDPYTHON) -E $(srcdir)/setup.py build;; \ esac @@ -542,13 +546,16 @@ # Header files PYTHON_HEADERS= \ - Include/Python.h \ Include/Python-ast.h \ - Include/asdl.h \ + Include/Python.h \ Include/abstract.h \ + Include/asdl.h \ + Include/ast.h \ + Include/bitset.h \ Include/boolobject.h \ Include/bytes_methods.h \ Include/bytesobject.h \ + Include/cellobject.h \ Include/ceval.h \ Include/classobject.h \ Include/cobject.h \ @@ -559,48 +566,62 @@ Include/descrobject.h \ Include/dictobject.h \ Include/enumobject.h \ - Include/genobject.h \ + Include/errcode.h \ + Include/eval.h \ Include/fileobject.h \ Include/floatobject.h \ Include/formatter_unicode.h \ + Include/frameobject.h \ Include/funcobject.h \ + Include/genobject.h \ Include/import.h \ Include/intrcheck.h \ Include/iterobject.h \ Include/listobject.h \ Include/longintrepr.h \ Include/longobject.h \ + Include/marshal.h \ Include/memoryobject.h \ + Include/metagrammar.h \ Include/methodobject.h \ Include/modsupport.h \ Include/moduleobject.h \ + Include/node.h \ Include/object.h \ Include/objimpl.h \ + Include/opcode.h \ + Include/osdefs.h \ Include/parsetok.h \ Include/patchlevel.h \ + Include/pgen.h \ + Include/pgenheaders.h \ Include/pyarena.h \ Include/pydebug.h \ Include/pyerrors.h \ Include/pyfpe.h \ + Include/pygetopt.h \ Include/pymem.h \ Include/pyport.h \ Include/pystate.h \ - Include/pystrtod.h \ Include/pystrcmp.h \ + Include/pystrtod.h \ Include/pythonrun.h \ + Include/pythread.h \ Include/rangeobject.h \ - Include/setobject.h \ + Include/setobject.h \ Include/sliceobject.h \ Include/stringobject.h \ - Include/structseq.h \ Include/structmember.h \ + Include/structseq.h \ Include/symtable.h \ Include/sysmodule.h \ Include/traceback.h \ Include/tupleobject.h \ + Include/ucnhash.h \ Include/unicodeobject.h \ Include/weakrefobject.h \ - pyconfig.h + pyconfig.h \ + $(PARSER_HEADERS) $(LIBRARY_OBJS) $(MODOBJS) Modules/python.o: $(PYTHON_HEADERS) Modified: python/branches/py3k-ctypes-pep3118/Misc/NEWS ============================================================================== --- python/branches/py3k-ctypes-pep3118/Misc/NEWS (original) +++ python/branches/py3k-ctypes-pep3118/Misc/NEWS Thu Jan 24 22:12:24 2008 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- map() and itertools.imap() no longer accept None for the first argument. + Use zip() instead. + - Issue #1769: Now int("- 1") is not allowed any more. - Object/longobject.c: long(float('nan')) raises an OverflowError instead Modified: python/branches/py3k-ctypes-pep3118/Modules/_testcapimodule.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_testcapimodule.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_testcapimodule.c Thu Jan 24 22:12:24 2008 @@ -930,6 +930,7 @@ #define AddSym(d, n, f, v) {PyObject *o = f(v); PyDict_SetItemString(d, n, o); Py_DECREF(o);} typedef struct { + char bool_member; char byte_member; unsigned char ubyte_member; short short_member; @@ -952,6 +953,7 @@ } test_structmembers; static struct PyMemberDef test_members[] = { + {"T_BOOL", T_BOOL, offsetof(test_structmembers, structmembers.bool_member), 0, NULL}, {"T_BYTE", T_BYTE, offsetof(test_structmembers, structmembers.byte_member), 0, NULL}, {"T_UBYTE", T_UBYTE, offsetof(test_structmembers, structmembers.ubyte_member), 0, NULL}, {"T_SHORT", T_SHORT, offsetof(test_structmembers, structmembers.short_member), 0, NULL}, @@ -970,39 +972,53 @@ }; -static PyObject *test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs){ - static char *keywords[]={"T_BYTE", "T_UBYTE", "T_SHORT", "T_USHORT", "T_INT", "T_UINT", - "T_LONG", "T_ULONG", "T_FLOAT", "T_DOUBLE", - #ifdef HAVE_LONG_LONG +static PyObject * +test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + static char *keywords[] = { + "T_BOOL", "T_BYTE", "T_UBYTE", "T_SHORT", "T_USHORT", + "T_INT", "T_UINT", "T_LONG", "T_ULONG", + "T_FLOAT", "T_DOUBLE", +#ifdef HAVE_LONG_LONG "T_LONGLONG", "T_ULONGLONG", - #endif +#endif NULL}; - static char *fmt="|bBhHiIlkfd" - #ifdef HAVE_LONG_LONG + static char *fmt = "|bbBhHiIlkfd" +#ifdef HAVE_LONG_LONG "LK" - #endif +#endif ; - test_structmembers *ob=PyObject_New(test_structmembers, type); - if (ob==NULL) + test_structmembers *ob; + ob = PyObject_New(test_structmembers, type); + if (ob == NULL) return NULL; memset(&ob->structmembers, 0, sizeof(all_structmembers)); if (!PyArg_ParseTupleAndKeywords(args, kwargs, fmt, keywords, - &ob->structmembers.byte_member, &ob->structmembers.ubyte_member, - &ob->structmembers.short_member, &ob->structmembers.ushort_member, - &ob->structmembers.int_member, &ob->structmembers.uint_member, - &ob->structmembers.long_member, &ob->structmembers.ulong_member, - &ob->structmembers.float_member, &ob->structmembers.double_member - #ifdef HAVE_LONG_LONG - ,&ob->structmembers.longlong_member, &ob->structmembers.ulonglong_member - #endif - )){ + &ob->structmembers.bool_member, + &ob->structmembers.byte_member, + &ob->structmembers.ubyte_member, + &ob->structmembers.short_member, + &ob->structmembers.ushort_member, + &ob->structmembers.int_member, + &ob->structmembers.uint_member, + &ob->structmembers.long_member, + &ob->structmembers.ulong_member, + &ob->structmembers.float_member, + &ob->structmembers.double_member +#ifdef HAVE_LONG_LONG + , &ob->structmembers.longlong_member, + &ob->structmembers.ulonglong_member +#endif + )) { Py_DECREF(ob); return NULL; - } + } return (PyObject *)ob; } -static void test_structmembers_free(PyObject *ob){ +static void +test_structmembers_free(PyObject *ob) +{ PyObject_FREE(ob); } @@ -1023,8 +1039,8 @@ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ - PyObject_GenericGetAttr, - PyObject_GenericSetAttr, + PyObject_GenericGetAttr, /* tp_getattro */ + PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ 0, /* tp_flags */ "Type containing all structmember types", @@ -1035,7 +1051,7 @@ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ - test_members, /* tp_members */ + test_members, /* tp_members */ 0, 0, 0, @@ -1044,7 +1060,7 @@ 0, 0, 0, - test_structmembers_new, /* tp_new */ + test_structmembers_new, /* tp_new */ }; Modified: python/branches/py3k-ctypes-pep3118/Modules/config.c.in ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/config.c.in (original) +++ python/branches/py3k-ctypes-pep3118/Modules/config.c.in Thu Jan 24 22:12:24 2008 @@ -43,7 +43,7 @@ /* This lives in Python/Python-ast.c */ {"_ast", init_ast}, - /* This lives in Python/_types.c */ + /* This lives in Modules/_typesmodule.c */ {"_types", init_types}, /* These entries are here for sys.builtin_module_names */ Modified: python/branches/py3k-ctypes-pep3118/Modules/itertoolsmodule.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/itertoolsmodule.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/itertoolsmodule.c Thu Jan 24 22:12:24 2008 @@ -1490,31 +1490,6 @@ return 0; } -/* -imap() is an iterator version of __builtins__.map() except that it does -not have the None fill-in feature. That was intentionally left out for -the following reasons: - - 1) Itertools are designed to be easily combined and chained together. - Having all tools stop with the shortest input is a unifying principle - that makes it easier to combine finite iterators (supplying data) with - infinite iterators like count() and repeat() (for supplying sequential - or constant arguments to a function). - - 2) In typical use cases for combining itertools, having one finite data - supplier run out before another is likely to be an error condition which - should not pass silently by automatically supplying None. - - 3) The use cases for automatic None fill-in are rare -- not many functions - do something useful when a parameter suddenly switches type and becomes - None. - - 4) If a need does arise, it can be met by __builtins__.map() or by - writing: chain(iterable, repeat(None)). - - 5) Similar toolsets in Haskell and SML do not have automatic None fill-in. -*/ - static PyObject * imap_next(imapobject *lz) { @@ -1536,8 +1511,6 @@ } PyTuple_SET_ITEM(argtuple, i, val); } - if (lz->func == Py_None) - return argtuple; result = PyObject_Call(lz->func, argtuple, NULL); Py_DECREF(argtuple); return result; @@ -1547,10 +1520,7 @@ "imap(func, *iterables) --> imap object\n\ \n\ Make an iterator that computes the function using arguments from\n\ -each of the iterables. Like map() except that it returns\n\ -an iterator instead of a list and that it stops when the shortest\n\ -iterable is exhausted instead of filling in None for shorter\n\ -iterables."); +each of the iterables. Stops when the shortest iterable is exhausted."); static PyTypeObject imap_type = { PyVarObject_HEAD_INIT(NULL, 0) Modified: python/branches/py3k-ctypes-pep3118/Modules/mmapmodule.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/mmapmodule.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/mmapmodule.c Thu Jan 24 22:12:24 2008 @@ -130,7 +130,7 @@ } #endif /* UNIX */ - PyObject_Del(m_obj); + Py_TYPE(m_obj)->tp_free((PyObject*)m_obj); } static PyObject * @@ -666,12 +666,6 @@ self->exports--; } -static PyObject * -mmap_object_getattr(mmap_object *self, char *name) -{ - return Py_FindMethod(mmap_object_methods, (PyObject *)self, name); -} - static Py_ssize_t mmap_length(mmap_object *self) { @@ -901,15 +895,42 @@ (releasebufferproc)mmap_buffer_releasebuf, }; +static PyObject * +new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict); + +PyDoc_STRVAR(mmap_doc, +"Windows: mmap(fileno, length[, tagname[, access[, offset]]])\n\ +\n\ +Maps length bytes from the file specified by the file handle fileno,\n\ +and returns a mmap object. If length is larger than the current size\n\ +of the file, the file is extended to contain length bytes. If length\n\ +is 0, the maximum length of the map is the current size of the file,\n\ +except that if the file is empty Windows raises an exception (you cannot\n\ +create an empty mapping on Windows).\n\ +\n\ +Unix: mmap(fileno, length[, flags[, prot[, access[, offset]]]])\n\ +\n\ +Maps length bytes from the file specified by the file descriptor fileno,\n\ +and returns a mmap object. If length is 0, the maximum length of the map\n\ +will be the current size of the file when mmap is called.\n\ +flags specifies the nature of the mapping. MAP_PRIVATE creates a\n\ +private copy-on-write mapping, so changes to the contents of the mmap\n\ +object will be private to this process, and MAP_SHARED`creates a mapping\n\ +that's shared with all other processes mapping the same areas of the file.\n\ +The default value is MAP_SHARED.\n\ +\n\ +To map anonymous memory, pass -1 as the fileno (both versions)."); + + static PyTypeObject mmap_object_type = { - PyVarObject_HEAD_INIT(0, 0) /* patched in module init */ + PyVarObject_HEAD_INIT(NULL, 0) "mmap.mmap", /* tp_name */ sizeof(mmap_object), /* tp_size */ 0, /* tp_itemsize */ /* methods */ (destructor) mmap_object_dealloc, /* tp_dealloc */ 0, /* tp_print */ - (getattrfunc) mmap_object_getattr, /* tp_getattr */ + 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ @@ -919,11 +940,29 @@ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ - 0, /*tp_getattro*/ + PyObject_GenericGetAttr, /*tp_getattro*/ 0, /*tp_setattro*/ &mmap_as_buffer, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + mmap_doc, /*tp_doc*/ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + mmap_object_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + new_mmap_object, /* tp_new */ + PyObject_Del, /* tp_free */ }; @@ -955,7 +994,7 @@ #ifdef UNIX static PyObject * -new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict) +new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) { #ifdef HAVE_FSTAT struct stat st; @@ -1023,7 +1062,7 @@ } } #endif - m_obj = PyObject_New(mmap_object, &mmap_object_type); + m_obj = (mmap_object *)type->tp_alloc(type, 0); if (m_obj == NULL) {return NULL;} m_obj->data = NULL; m_obj->size = (size_t) map_size; @@ -1078,7 +1117,7 @@ #ifdef MS_WINDOWS static PyObject * -new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict) +new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) { mmap_object *m_obj; PyObject *map_size_obj = NULL, *offset_obj = NULL; @@ -1147,7 +1186,7 @@ lseek(fileno, 0, SEEK_SET); } - m_obj = PyObject_New(mmap_object, &mmap_object_type); + m_obj = (mmap_object *)type->tp_alloc(type, 0); if (m_obj == NULL) return NULL; /* Set every field to an invalid marker, so we can safely @@ -1262,13 +1301,6 @@ } #endif /* MS_WINDOWS */ -/* List of functions exported by this module */ -static struct PyMethodDef mmap_functions[] = { - {"mmap", (PyCFunction) new_mmap_object, - METH_VARARGS|METH_KEYWORDS}, - {NULL, NULL} /* Sentinel */ -}; - static void setint(PyObject *d, const char *name, long value) { @@ -1279,14 +1311,14 @@ } PyMODINIT_FUNC - initmmap(void) +initmmap(void) { PyObject *dict, *module; - /* Patch the object type */ - Py_TYPE(&mmap_object_type) = &PyType_Type; + if (PyType_Ready(&mmap_object_type) < 0) + return; - module = Py_InitModule("mmap", mmap_functions); + module = Py_InitModule("mmap", NULL); if (module == NULL) return; dict = PyModule_GetDict(module); @@ -1294,6 +1326,7 @@ return; mmap_module_error = PyExc_EnvironmentError; PyDict_SetItemString(dict, "error", mmap_module_error); + PyDict_SetItemString(dict, "mmap", (PyObject*) &mmap_object_type); #ifdef PROT_EXEC setint(dict, "PROT_EXEC", PROT_EXEC); #endif Modified: python/branches/py3k-ctypes-pep3118/Modules/socketmodule.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/socketmodule.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/socketmodule.c Thu Jan 24 22:12:24 2008 @@ -966,7 +966,7 @@ struct sockaddr_un *a = (struct sockaddr_un *) addr; #ifdef linux if (a->sun_path[0] == 0) { /* Linux abstract namespace */ - addrlen -= (sizeof(*a) - sizeof(a->sun_path)); + addrlen -= offsetof(struct sockaddr_un, sun_path); return PyString_FromStringAndSize(a->sun_path, addrlen); } else @@ -1171,7 +1171,7 @@ #if defined(PYOS_OS2) *len_ret = sizeof(*addr); #else - *len_ret = len + sizeof(*addr) - sizeof(addr->sun_path); + *len_ret = len + offsetof(struct sockaddr_un, sun_path); #endif return 1; } Modified: python/branches/py3k-ctypes-pep3118/Parser/tokenizer.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Parser/tokenizer.c (original) +++ python/branches/py3k-ctypes-pep3118/Parser/tokenizer.c Thu Jan 24 22:12:24 2008 @@ -640,6 +640,7 @@ { PyObject* utf8 = NULL; const char *s; + const char *newl[2] = {NULL, NULL}; int lineno = 0; tok->enc = NULL; tok->str = str; @@ -656,13 +657,23 @@ for (s = str;; s++) { if (*s == '\0') break; else if (*s == '\n') { + newl[lineno] = s; lineno++; if (lineno == 2) break; } } tok->enc = NULL; - if (!check_coding_spec(str, s - str, tok, buf_setreadl)) - return error_ret(tok); + /* need to check line 1 and 2 separately since check_coding_spec + assumes a single line as input */ + if (newl[0]) { + if (!check_coding_spec(str, newl[0] - str, tok, buf_setreadl)) + return error_ret(tok); + if (tok->enc == NULL && newl[1]) { + if (!check_coding_spec(newl[0]+1, newl[1] - newl[0], + tok, buf_setreadl)) + return error_ret(tok); + } + } if (tok->enc != NULL) { assert(utf8 == NULL); utf8 = translate_into_utf8(str, tok->enc); Modified: python/branches/py3k-ctypes-pep3118/Python/bltinmodule.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Python/bltinmodule.c (original) +++ python/branches/py3k-ctypes-pep3118/Python/bltinmodule.c Thu Jan 24 22:12:24 2008 @@ -815,7 +815,6 @@ items of the argument iterables(s). If more than one iterable is given,\n\ the function is called with an argument list consisting of the\n\ corresponding item of each iterable, until an iterable is exhausted.\n\ -If the function is None, 'lambda *a: a' is assumed.\n\ (This is identical to itertools.imap().)"); @@ -1009,11 +1008,14 @@ "%s() got an unexpected keyword argument", name); return NULL; } + Py_INCREF(keyfunc); } it = PyObject_GetIter(v); - if (it == NULL) + if (it == NULL) { + Py_XDECREF(keyfunc); return NULL; + } maxitem = NULL; /* the result */ maxval = NULL; /* the value associated with the result */ @@ -1062,6 +1064,7 @@ else Py_DECREF(maxval); Py_DECREF(it); + Py_XDECREF(keyfunc); return maxitem; Fail_it_item_and_val: @@ -1072,6 +1075,7 @@ Py_XDECREF(maxval); Py_XDECREF(maxitem); Py_DECREF(it); + Py_XDECREF(keyfunc); return NULL; } Modified: python/branches/py3k-ctypes-pep3118/Python/ceval.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Python/ceval.c (original) +++ python/branches/py3k-ctypes-pep3118/Python/ceval.c Thu Jan 24 22:12:24 2008 @@ -1833,6 +1833,7 @@ "__import__ not found"); break; } + Py_INCREF(x); v = POP(); u = TOP(); if (PyLong_AsLong(u) != -1 || PyErr_Occurred()) @@ -1854,11 +1855,14 @@ Py_DECREF(u); if (w == NULL) { u = POP(); + Py_DECREF(x); x = NULL; break; } READ_TIMESTAMP(intr0); - x = PyEval_CallObject(x, w); + v = x; + x = PyEval_CallObject(v, w); + Py_DECREF(v); READ_TIMESTAMP(intr1); Py_DECREF(w); SET_TOP(x); Modified: python/branches/py3k-ctypes-pep3118/Python/dynload_win.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Python/dynload_win.c (original) +++ python/branches/py3k-ctypes-pep3118/Python/dynload_win.c Thu Jan 24 22:12:24 2008 @@ -171,11 +171,16 @@ HINSTANCE hDLL = NULL; char pathbuf[260]; LPTSTR dummy; + unsigned int old_mode; /* We use LoadLibraryEx so Windows looks for dependent DLLs in directory of pathname first. However, Windows95 can sometimes not work correctly unless the absolute path is used. If GetFullPathName() fails, the LoadLibrary will certainly fail too, so use its error code */ + + /* Don't display a message box when Python can't load a DLL */ + old_mode = SetErrorMode(SEM_FAILCRITICALERRORS); + if (GetFullPathName(pathname, sizeof(pathbuf), pathbuf, @@ -183,6 +188,10 @@ /* XXX This call doesn't exist in Windows CE */ hDLL = LoadLibraryEx(pathname, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); + + /* restore old error mode settings */ + SetErrorMode(old_mode); + if (hDLL==NULL){ PyObject *message; unsigned int errorCode; Modified: python/branches/py3k-ctypes-pep3118/Python/hypot.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Python/hypot.c (original) +++ python/branches/py3k-ctypes-pep3118/Python/hypot.c Thu Jan 24 22:12:24 2008 @@ -2,6 +2,7 @@ #include "Python.h" +#ifndef HAVE_HYPOT double hypot(double x, double y) { double yx; @@ -20,3 +21,5 @@ return x*sqrt(1.+yx*yx); } } +#endif /* HAVE_HYPOT */ + Modified: python/branches/py3k-ctypes-pep3118/Python/pystate.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Python/pystate.c (original) +++ python/branches/py3k-ctypes-pep3118/Python/pystate.c Thu Jan 24 22:12:24 2008 @@ -242,6 +242,7 @@ { PyInterpreterState *interp; PyThreadState **p; + PyThreadState *prev_p = NULL; if (tstate == NULL) Py_FatalError("PyThreadState_Delete: NULL tstate"); interp = tstate->interp; @@ -254,6 +255,15 @@ "PyThreadState_Delete: invalid tstate"); if (*p == tstate) break; + if (*p == prev_p) + Py_FatalError( + "PyThreadState_Delete: small circular list(!)" + " and tstate not found."); + prev_p = *p; + if ((*p)->next == interp->tstate_head) + Py_FatalError( + "PyThreadState_Delete: circular list(!) and" + " tstate not found."); } *p = tstate->next; HEAD_UNLOCK(); Modified: python/branches/py3k-ctypes-pep3118/Python/structmember.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Python/structmember.c (original) +++ python/branches/py3k-ctypes-pep3118/Python/structmember.c Thu Jan 24 22:12:24 2008 @@ -12,6 +12,9 @@ addr += l->offset; switch (l->type) { + case T_BOOL: + v = PyBool_FromLong(*(char*)addr); + break; case T_BYTE: v = PyLong_FromLong(*(char*)addr); break; @@ -113,6 +116,18 @@ } addr += l->offset; switch (l->type) { + case T_BOOL:{ + if (!PyBool_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "attribute value type must be bool"); + return -1; + } + if (v == Py_True) + *(char*)addr = (char) 1; + else + *(char*)addr = (char) 0; + break; + } case T_BYTE:{ long long_val = PyLong_AsLong(v); if ((long_val == -1) && PyErr_Occurred()) Modified: python/branches/py3k-ctypes-pep3118/Python/sysmodule.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Python/sysmodule.c (original) +++ python/branches/py3k-ctypes-pep3118/Python/sysmodule.c Thu Jan 24 22:12:24 2008 @@ -374,6 +374,25 @@ ); static PyObject * +sys_gettrace(PyObject *self, PyObject *args) +{ + PyThreadState *tstate = PyThreadState_GET(); + PyObject *temp = tstate->c_traceobj; + + if (temp == NULL) + temp = Py_None; + Py_INCREF(temp); + return temp; +} + +PyDoc_STRVAR(gettrace_doc, +"gettrace()\n\ +\n\ +Return the global debug tracing function set with sys.settrace.\n\ +See the debugger chapter in the library manual." +); + +static PyObject * sys_setprofile(PyObject *self, PyObject *args) { if (trace_init() == -1) @@ -394,6 +413,25 @@ ); static PyObject * +sys_getprofile(PyObject *self, PyObject *args) +{ + PyThreadState *tstate = PyThreadState_GET(); + PyObject *temp = tstate->c_profileobj; + + if (temp == NULL) + temp = Py_None; + Py_INCREF(temp); + return temp; +} + +PyDoc_STRVAR(getprofile_doc, +"getprofile()\n\ +\n\ +Return the profiling function set with sys.setprofile.\n\ +See the profiler chapter in the library manual." +); + +static PyObject * sys_setcheckinterval(PyObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, "i:setcheckinterval", &_Py_CheckInterval)) @@ -763,12 +801,14 @@ setdlopenflags_doc}, #endif {"setprofile", sys_setprofile, METH_O, setprofile_doc}, + {"getprofile", sys_getprofile, METH_NOARGS, getprofile_doc}, {"setrecursionlimit", sys_setrecursionlimit, METH_VARARGS, setrecursionlimit_doc}, #ifdef WITH_TSC {"settscdump", sys_settscdump, METH_VARARGS, settscdump_doc}, #endif {"settrace", sys_settrace, METH_O, settrace_doc}, + {"gettrace", sys_gettrace, METH_NOARGS, gettrace_doc}, {"call_tracing", sys_call_tracing, METH_VARARGS, call_tracing_doc}, {NULL, NULL} /* sentinel */ }; @@ -903,8 +943,10 @@ exc_info() -- return thread-safe information about the current exception\n\ exit() -- exit the interpreter by raising SystemExit\n\ getdlopenflags() -- returns flags to be used for dlopen() calls\n\ +getprofile() -- get the global profiling function\n\ getrefcount() -- return the reference count for an object (plus one :-)\n\ getrecursionlimit() -- return the max recursion depth for the interpreter\n\ +gettrace() -- get the global debug tracing function\n\ setcheckinterval() -- control how often the interpreter checks for events\n\ setdlopenflags() -- set the flags to be used for dlopen() calls\n\ setprofile() -- set the global profiling function\n\ Modified: python/branches/py3k-ctypes-pep3118/Tools/pynche/ColorDB.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Tools/pynche/ColorDB.py (original) +++ python/branches/py3k-ctypes-pep3118/Tools/pynche/ColorDB.py Thu Jan 24 22:12:24 2008 @@ -50,10 +50,7 @@ self.__byname = {} # all unique names (non-aliases). built-on demand self.__allnames = None - while 1: - line = fp.readline() - if not line: - break + for line in fp: # get this compiled regular expression from derived class mo = self._re.match(line) if not mo: Modified: python/branches/py3k-ctypes-pep3118/configure ============================================================================== --- python/branches/py3k-ctypes-pep3118/configure (original) +++ python/branches/py3k-ctypes-pep3118/configure Thu Jan 24 22:12:24 2008 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 59826 . +# From configure.in Revision: 59829 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.0. # @@ -20584,7 +20584,6 @@ # ************************************ # * Check for mathematical functions * # ************************************ -# check for hypot() in math library LIBS_SAVE=$LIBS LIBS="$LIBS $LIBM" @@ -20694,7 +20693,12 @@ -for ac_func in copysign isfinite isnan isinf + + + + + +for ac_func in acosh asinh atanh copysign expm1 finite isinf isnan log1p do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 Modified: python/branches/py3k-ctypes-pep3118/configure.in ============================================================================== --- python/branches/py3k-ctypes-pep3118/configure.in (original) +++ python/branches/py3k-ctypes-pep3118/configure.in Thu Jan 24 22:12:24 2008 @@ -2948,12 +2948,11 @@ # ************************************ # * Check for mathematical functions * # ************************************ -# check for hypot() in math library LIBS_SAVE=$LIBS LIBS="$LIBS $LIBM" AC_REPLACE_FUNCS(hypot) -AC_CHECK_FUNCS(copysign isfinite isnan isinf) +AC_CHECK_FUNCS(acosh asinh atanh copysign expm1 finite isinf isnan log1p) LIBS=$LIBS_SAVE Modified: python/branches/py3k-ctypes-pep3118/pyconfig.h.in ============================================================================== --- python/branches/py3k-ctypes-pep3118/pyconfig.h.in (original) +++ python/branches/py3k-ctypes-pep3118/pyconfig.h.in Thu Jan 24 22:12:24 2008 @@ -25,6 +25,9 @@ the case on Motorola V4 (R40V4.2) */ #undef GETTIMEOFDAY_NO_TZ +/* Define to 1 if you have the `acosh' function. */ +#undef HAVE_ACOSH + /* struct addrinfo (netdb.h) */ #undef HAVE_ADDRINFO @@ -34,9 +37,15 @@ /* Define this if your time.h defines altzone. */ #undef HAVE_ALTZONE +/* Define to 1 if you have the `asinh' function. */ +#undef HAVE_ASINH + /* Define to 1 if you have the header file. */ #undef HAVE_ASM_TYPES_H +/* Define to 1 if you have the `atanh' function. */ +#undef HAVE_ATANH + /* Define if GCC supports __attribute__((format(PyArg_ParseTuple, 2, 3))) */ #undef HAVE_ATTRIBUTE_FORMAT_PARSETUPLE @@ -141,6 +150,9 @@ /* Define to 1 if you have the `execv' function. */ #undef HAVE_EXECV +/* Define to 1 if you have the `expm1' function. */ +#undef HAVE_EXPM1 + /* Define if you have the 'fchdir' function. */ #undef HAVE_FCHDIR @@ -156,6 +168,9 @@ /* Define if you have the 'fdatasync' function. */ #undef HAVE_FDATASYNC +/* Define to 1 if you have the `finite' function. */ +#undef HAVE_FINITE + /* Define if you have the 'flock' function. */ #undef HAVE_FLOCK @@ -288,9 +303,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_IO_H -/* Define to 1 if you have the `isfinite' function. */ -#undef HAVE_ISFINITE - /* Define to 1 if you have the `isinf' function. */ #undef HAVE_ISINF @@ -354,6 +366,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_TIPC_H +/* Define to 1 if you have the `log1p' function. */ +#undef HAVE_LOG1P + /* Define this if you have the type long double. */ #undef HAVE_LONG_DOUBLE From python-3000-checkins at python.org Fri Jan 25 00:34:35 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Fri, 25 Jan 2008 00:34:35 +0100 (CET) Subject: [Python-3000-checkins] r60267 - python/branches/py3k/Doc/library/itertools.rst Message-ID: <20080124233435.2FC531E400F@bag.python.org> Author: georg.brandl Date: Fri Jan 25 00:34:34 2008 New Revision: 60267 Modified: python/branches/py3k/Doc/library/itertools.rst Log: Fix merge glitch. Modified: python/branches/py3k/Doc/library/itertools.rst ============================================================================== --- python/branches/py3k/Doc/library/itertools.rst (original) +++ python/branches/py3k/Doc/library/itertools.rst Fri Jan 25 00:34:34 2008 @@ -259,22 +259,9 @@ makes possible an idiom for clustering a data series into n-length groups using ``izip(*[iter(s)]*n)``. -<<<<<<< .working - Note, when :func:`izip` is used with unequal length inputs, subsequent - iteration over the longer iterables cannot reliably be continued after - :func:`izip` terminates. Potentially, up to one entry will be missing from - each of the left-over iterables. This occurs because a value is fetched from - each iterator in- turn, but the process ends when one of the iterators - terminates. This leaves the last fetched values in limbo (they cannot be - returned in a final, incomplete tuple and they are cannot be pushed back into - the iterator for retrieval with ``next(it)``). In general, :func:`izip` - should only be used with unequal length inputs when you don't care about - trailing, unmatched values from the longer iterables. -======= :func:`izip` should only be used with unequal length inputs when you don't care about trailing, unmatched values from the longer iterables. If those values are important, use :func:`izip_longest` instead. ->>>>>>> .merge-right.r60208 .. function:: izip_longest(*iterables[, fillvalue]) From python-3000-checkins at python.org Fri Jan 25 11:53:34 2008 From: python-3000-checkins at python.org (thomas.heller) Date: Fri, 25 Jan 2008 11:53:34 +0100 (CET) Subject: [Python-3000-checkins] r60278 - python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c python/branches/py3k-ctypes-pep3118/Modules/_ctypes/ctypes.h python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c Message-ID: <20080125105334.538C91E400F@bag.python.org> Author: thomas.heller Date: Fri Jan 25 11:53:33 2008 New Revision: 60278 Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c python/branches/py3k-ctypes-pep3118/Modules/_ctypes/ctypes.h python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c Log: Implement pep3118 format strings for ctypes.Structure and ctypes.Union. Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c Fri Jan 25 11:53:33 2008 @@ -135,7 +135,7 @@ indicator set. If called with a suffix of NULL the error indicator must already be set. */ -static char * +char * alloc_format_string(const char *prefix, const char *suffix) { size_t len; @@ -169,6 +169,14 @@ return result; } +char * +replace_format_string(const char *prefix, char *suffix) +{ + char *result = alloc_format_string(prefix, suffix); + PyMem_Free(suffix); + return result; +} + /* StructType_Type - a meta type/class. Creating a new class using this one as __metaclass__ will call the contructor StructUnionType_new. It replaces the @@ -1059,6 +1067,7 @@ return NULL; } + assert(itemdict->format); if (itemdict->format[0] == '(') { sprintf(buf, "(%d,", length); stgdict->format = alloc_format_string(buf, itemdict->format+1); Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/ctypes.h ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_ctypes/ctypes.h (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_ctypes/ctypes.h Fri Jan 25 11:53:33 2008 @@ -343,6 +343,8 @@ extern void _AddTraceback(char *, char *, int); extern PyObject *CData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr); +extern char *alloc_format_string(const char *prefix, const char *suffix); +extern char *replace_format_string(const char *prefix, char *suffix); /* XXX better name needed! */ extern int IsSimpleSubType(PyObject *obj); Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c Fri Jan 25 11:53:33 2008 @@ -2,6 +2,7 @@ #include #ifdef MS_WIN32 #include +#include #endif #include "ctypes.h" @@ -55,6 +56,10 @@ StgDict_clear(dst); PyMem_Free(dst->ffi_type_pointer.elements); + PyMem_Free(dst->format); + dst->format = NULL; + PyMem_Free(dst->shape); + dst->shape = NULL; dst->ffi_type_pointer.elements = NULL; d = (char *)dst; @@ -69,6 +74,20 @@ Py_XINCREF(dst->restype); Py_XINCREF(dst->checker); + if (src->format) { + dst->format = PyMem_Malloc(strlen(src->format) + 1); + if (dst->format == NULL) + return -1; + strcpy(dst->format, src->format); + } + if (src->shape) { + dst->shape = PyMem_Malloc(sizeof(Py_ssize_t) * src->ndim); + if (dst->shape == NULL) + return -1; + memcpy(dst->shape, src->shape, + sizeof(Py_ssize_t) * src->ndim); + } + if (src->ffi_type_pointer.elements == NULL) return 0; size = sizeof(ffi_type *) * (src->length + 1); @@ -346,6 +365,11 @@ return -1; } + if (stgdict->format) { + PyMem_Free(stgdict->format); + stgdict->format = NULL; + } + if (stgdict->ffi_type_pointer.elements) PyMem_Free(stgdict->ffi_type_pointer.elements); @@ -384,6 +408,10 @@ ffi_ofs = 0; } + stgdict->format = alloc_format_string(NULL, "}"); + if (stgdict->format == NULL) + return -1; + #define realdict ((PyObject *)&stgdict->dict) for (i = 0; i < len; ++i) { PyObject *name = NULL, *desc = NULL; @@ -442,6 +470,19 @@ } } else bitsize = 0; + { + int len = PyUnicode_GetSize(name); + char *buf = alloca(len); + sprintf(buf, ":%s:", PyUnicode_AsString(name)); +/* XXX FIXME */ +/* assert(dict->format); */ + strcat(buf, dict->format ? dict->format : "XXX"); + stgdict->format = replace_format_string(buf, stgdict->format); + if (stgdict->format == NULL) { + Py_DECREF(pair); + return -1; + } + } if (isStruct) { prop = CField_FromDesc(desc, i, &field_size, bitsize, &bitofs, @@ -472,6 +513,16 @@ Py_DECREF(prop); } #undef realdict + + if (isStruct) { + stgdict->format = replace_format_string("T{", stgdict->format); + } else { + /* PEP3118 doesn't support unions. Invent our own character... */ + stgdict->format = replace_format_string("#{", stgdict->format); + } + if (stgdict->format == NULL) + return -1; + if (!isStruct) size = union_size; From python-3000-checkins at python.org Fri Jan 25 12:02:28 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Fri, 25 Jan 2008 12:02:28 +0100 (CET) Subject: [Python-3000-checkins] r60279 - python/branches/py3k/Doc/whatsnew/3.0.rst Message-ID: <20080125110228.A87681E4032@bag.python.org> Author: christian.heimes Date: Fri Jan 25 12:02:28 2008 New Revision: 60279 Modified: python/branches/py3k/Doc/whatsnew/3.0.rst Log: Document that basestring has been replaced by str. Issue #1931. Modified: python/branches/py3k/Doc/whatsnew/3.0.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.0.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.0.rst Fri Jan 25 12:02:28 2008 @@ -154,6 +154,9 @@ * There is only one string type; its name is ``str`` but its behavior and implementation are more like ``unicode`` in 2.x. +* The ``basestring`` superclass has been removed. The ``2to3`` tool + replaces every occurence of ``basestring`` with ``str``. + * PEP 3137: There is a new type, ``bytes``, to represent binary data (and encoded text, which is treated as binary data until you decide to decode it). The ``str`` and ``bytes`` types cannot be mixed; you From python-3000-checkins at python.org Fri Jan 25 12:10:11 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Fri, 25 Jan 2008 12:10:11 +0100 (CET) Subject: [Python-3000-checkins] r60280 - python/branches/py3k/Doc/whatsnew/3.0.rst Message-ID: <20080125111011.7A3091E402B@bag.python.org> Author: christian.heimes Date: Fri Jan 25 12:10:11 2008 New Revision: 60280 Modified: python/branches/py3k/Doc/whatsnew/3.0.rst Log: Added comment about sys.maxint to whatsnew. Issue #1930 Modified: python/branches/py3k/Doc/whatsnew/3.0.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.0.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.0.rst Fri Jan 25 12:10:11 2008 @@ -248,6 +248,8 @@ built-in integral type, named ``int``; but it behaves like the old ``long`` type, with the exception that the literal suffix ``L`` is neither supported by the parser nor produced by ``repr()`` anymore. + ``sys.maxint`` was also removed since the int type has maximum + value anymore. * PEP 238: int division returns a float. From python-3000-checkins at python.org Fri Jan 25 12:23:12 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Fri, 25 Jan 2008 12:23:12 +0100 (CET) Subject: [Python-3000-checkins] r60281 - in python/branches/py3k: Lib/ctypes/test/test_numbers.py Lib/decimal.py Lib/pprint.py Lib/rational.py Lib/test/crashers/loosing_dict_ref.py Lib/test/test_decimal.py Lib/test/test_descr.py Lib/test/test_grammar.py Lib/test/test_pprint.py Lib/test/test_rational.py Lib/test/test_set.py Lib/test/test_urllib2net.py Lib/threading.py Modules/_ctypes/_ctypes.c Modules/_ctypes/cfield.c Modules/mathmodule.c Objects/floatobject.c Objects/object.c Python/compile.c Message-ID: <20080125112312.E1FC01E40A0@bag.python.org> Author: christian.heimes Date: Fri Jan 25 12:23:10 2008 New Revision: 60281 Removed: python/branches/py3k/Lib/test/crashers/loosing_dict_ref.py Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/ctypes/test/test_numbers.py python/branches/py3k/Lib/decimal.py python/branches/py3k/Lib/pprint.py python/branches/py3k/Lib/rational.py python/branches/py3k/Lib/test/test_decimal.py python/branches/py3k/Lib/test/test_descr.py python/branches/py3k/Lib/test/test_grammar.py python/branches/py3k/Lib/test/test_pprint.py python/branches/py3k/Lib/test/test_rational.py python/branches/py3k/Lib/test/test_set.py python/branches/py3k/Lib/test/test_urllib2net.py python/branches/py3k/Lib/threading.py python/branches/py3k/Modules/_ctypes/_ctypes.c python/branches/py3k/Modules/_ctypes/cfield.c python/branches/py3k/Modules/mathmodule.c python/branches/py3k/Objects/floatobject.c python/branches/py3k/Objects/object.c python/branches/py3k/Python/compile.c Log: Merged revisions 60245-60277 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60246 | guido.van.rossum | 2008-01-24 18:58:05 +0100 (Thu, 24 Jan 2008) | 2 lines Fix test67.py from issue #1303614. ........ r60248 | raymond.hettinger | 2008-01-24 19:05:54 +0100 (Thu, 24 Jan 2008) | 1 line Clean-up and speed-up code by accessing numerator/denominator directly. There's no reason to enforce readonliness ........ r60249 | raymond.hettinger | 2008-01-24 19:12:23 +0100 (Thu, 24 Jan 2008) | 1 line Revert 60189 and restore performance. ........ r60250 | guido.van.rossum | 2008-01-24 19:21:02 +0100 (Thu, 24 Jan 2008) | 5 lines News about recently fixed crashers: - A few crashers fixed: weakref_in_del.py (issue #1377858); loosing_dict_ref.py (issue #1303614, test67.py); borrowed_ref_[34].py (not in tracker). ........ r60252 | thomas.heller | 2008-01-24 19:36:27 +0100 (Thu, 24 Jan 2008) | 7 lines Use a PyDictObject again for the array type cache; retrieving items from the WeakValueDictionary was slower by nearly a factor of 3. To avoid leaks, weakref proxies for the array types are put into the cache dict, with weakref callbacks that removes the entries when the type goes away. ........ r60253 | thomas.heller | 2008-01-24 19:54:12 +0100 (Thu, 24 Jan 2008) | 2 lines Replace Py_BuildValue with PyTuple_Pack because it is faster. Also add a missing DECREF. ........ r60254 | raymond.hettinger | 2008-01-24 20:05:29 +0100 (Thu, 24 Jan 2008) | 1 line Add support for trunc(). ........ r60255 | thomas.heller | 2008-01-24 20:15:02 +0100 (Thu, 24 Jan 2008) | 5 lines Invert the checks in get_[u]long and get_[u]longlong. The intent was to not accept float types; the result was that integer-like objects were not accepted. Ported from release25-maint. ........ r60256 | raymond.hettinger | 2008-01-24 20:30:19 +0100 (Thu, 24 Jan 2008) | 1 line Add support for int(r) just like the other numeric classes. ........ r60263 | raymond.hettinger | 2008-01-24 22:23:58 +0100 (Thu, 24 Jan 2008) | 1 line Expand tests to include nested graph structures. ........ r60264 | raymond.hettinger | 2008-01-24 22:47:56 +0100 (Thu, 24 Jan 2008) | 1 line Shorter pprint's for empty sets and frozensets. Fix indentation of frozensets. Add tests including two complex data structures. ........ r60265 | amaury.forgeotdarc | 2008-01-24 23:51:18 +0100 (Thu, 24 Jan 2008) | 14 lines #1920: when considering a block starting by "while 0", the compiler optimized the whole construct away, even when an 'else' clause is present:: while 0: print("no") else: print("yes") did not generate any code at all. Now the compiler emits the 'else' block, like it already does for 'if' statements. Will backport. ........ r60266 | amaury.forgeotdarc | 2008-01-24 23:59:25 +0100 (Thu, 24 Jan 2008) | 2 lines News entry for r60265 (Issue 1920). ........ r60269 | raymond.hettinger | 2008-01-25 00:50:26 +0100 (Fri, 25 Jan 2008) | 1 line More code cleanup. Remove unnecessary indirection to useless class methods. ........ r60270 | raymond.hettinger | 2008-01-25 01:21:54 +0100 (Fri, 25 Jan 2008) | 1 line Add support for copy, deepcopy, and pickle. ........ r60271 | raymond.hettinger | 2008-01-25 01:33:45 +0100 (Fri, 25 Jan 2008) | 1 line Mark todos and review comments. ........ r60272 | raymond.hettinger | 2008-01-25 02:13:12 +0100 (Fri, 25 Jan 2008) | 1 line Add one other review comment. ........ r60273 | raymond.hettinger | 2008-01-25 02:23:38 +0100 (Fri, 25 Jan 2008) | 1 line Fix-up signature for approximation. ........ r60274 | raymond.hettinger | 2008-01-25 02:46:33 +0100 (Fri, 25 Jan 2008) | 1 line More design notes ........ r60276 | neal.norwitz | 2008-01-25 07:37:23 +0100 (Fri, 25 Jan 2008) | 6 lines Make the test more robust by trying to reconnect up to 3 times in case there were transient failures. This will hopefully silence the buildbots for this test. As we find other tests that have a problem, we can fix with a similar strategy assuming it is successful. It worked on my box in a loop for 10+ runs where it would have an exception otherwise. ........ r60277 | neal.norwitz | 2008-01-25 09:04:16 +0100 (Fri, 25 Jan 2008) | 4 lines Add prototypes to get the mathmodule.c to compile on OSF1 5.1 (Tru64) and eliminate a compiler warning in floatobject.c. There might be a better way to go about this, but it should be good enough for now. ........ Modified: python/branches/py3k/Lib/ctypes/test/test_numbers.py ============================================================================== --- python/branches/py3k/Lib/ctypes/test/test_numbers.py (original) +++ python/branches/py3k/Lib/ctypes/test/test_numbers.py Fri Jan 25 12:23:10 2008 @@ -105,15 +105,31 @@ def test_floats(self): # c_float and c_double can be created from # Python int, long and float + class FloatLike(object): + def __float__(self): + return 2.0 + f = FloatLike() for t in float_types: self.failUnlessEqual(t(2.0).value, 2.0) self.failUnlessEqual(t(2).value, 2.0) self.failUnlessEqual(t(2).value, 2.0) + self.failUnlessEqual(t(f).value, 2.0) def test_integers(self): - # integers cannot be constructed from floats + class FloatLike(object): + def __float__(self): + return 2.0 + f = FloatLike() + class IntLike(object): + def __int__(self): + return 2 + i = IntLike() + # integers cannot be constructed from floats, + # but from integer-like objects for t in signed_types + unsigned_types: self.assertRaises(TypeError, t, 3.14) + self.assertRaises(TypeError, t, f) + self.failUnlessEqual(t(i).value, 2) def test_sizes(self): for t in signed_types + unsigned_types + float_types + bool_types: Modified: python/branches/py3k/Lib/decimal.py ============================================================================== --- python/branches/py3k/Lib/decimal.py (original) +++ python/branches/py3k/Lib/decimal.py Fri Jan 25 12:23:10 2008 @@ -1451,6 +1451,8 @@ else: return s*int(self._int[:self._exp] or '0') + __trunc__ = __int__ + def _fix_nan(self, context): """Decapitate the payload of a NaN to fit the context""" payload = self._int Modified: python/branches/py3k/Lib/pprint.py ============================================================================== --- python/branches/py3k/Lib/pprint.py (original) +++ python/branches/py3k/Lib/pprint.py Fri Jan 25 12:23:10 2008 @@ -164,25 +164,31 @@ (issubclass(typ, set) and r is set.__repr__) or (issubclass(typ, frozenset) and r is frozenset.__repr__) ): + length = _len(object) if issubclass(typ, list): write('[') endchar = ']' elif issubclass(typ, set): + if not length: + write('set()') + return write('{') endchar = '}' object = sorted(object) indent += 4 elif issubclass(typ, frozenset): + if not length: + write('frozenset()') + return write('frozenset([') endchar = '])' object = sorted(object) - indent += 9 + indent += 10 else: write('(') endchar = ')' if self._indent_per_level > 1: write((self._indent_per_level - 1) * ' ') - length = _len(object) if length: context[objid] = 1 indent = indent + self._indent_per_level Modified: python/branches/py3k/Lib/rational.py ============================================================================== --- python/branches/py3k/Lib/rational.py (original) +++ python/branches/py3k/Lib/rational.py Fri Jan 25 12:23:10 2008 @@ -13,7 +13,7 @@ RationalAbc = numbers.Rational -def _gcd(a, b): +def _gcd(a, b): # XXX This is a useful function. Consider making it public. """Calculate the Greatest Common Divisor. Unless b==0, the result will have the same sign as b (so that when @@ -39,6 +39,8 @@ >>> _binary_float_to_ratio(-.25) (-1, 4) """ + # XXX Consider moving this to to floatobject.c + # with a name like float.as_intger_ratio() if x == 0: return 0, 1 @@ -79,6 +81,10 @@ _RATIONAL_FORMAT = re.compile( r'^\s*(?P[-+]?)(?P\d+)(?:/(?P\d+))?\s*$') +# XXX Consider accepting decimal strings as input since they are exact. +# Rational("2.01") --> s="2.01" ; Rational.from_decimal(Decimal(s)) --> Rational(201, 100)" +# If you want to avoid going through the decimal module, just parse the string directly: +# s.partition('.') --> ('2', '.', '01') --> Rational(int('2'+'01'), 10**len('01')) --> Rational(201, 100) class Rational(RationalAbc): """This class implements rational numbers. @@ -93,7 +99,7 @@ """ - __slots__ = ('_numerator', '_denominator') + __slots__ = ('numerator', 'denominator') # We're immutable, so use __new__ not __init__ def __new__(cls, numerator=0, denominator=1): @@ -133,8 +139,8 @@ raise ZeroDivisionError('Rational(%s, 0)' % numerator) g = _gcd(numerator, denominator) - self._numerator = int(numerator // g) - self._denominator = int(denominator // g) + self.numerator = int(numerator // g) + self.denominator = int(denominator // g) return self @classmethod @@ -192,29 +198,22 @@ n, d = d, n return cf - @classmethod - def approximate_from_float(cls, f, max_denominator): - 'Best rational approximation to f with a denominator <= max_denominator' + def approximate(self, max_denominator): + 'Best rational approximation with a denominator <= max_denominator' # XXX First cut at algorithm # Still needs rounding rules as specified at # http://en.wikipedia.org/wiki/Continued_fraction - cf = cls.from_float(f).as_continued_fraction() + if self.denominator <= max_denominator: + return self + cf = self.as_continued_fraction() result = Rational(0) for i in range(1, len(cf)): - new = cls.from_continued_fraction(cf[:i]) + new = self.from_continued_fraction(cf[:i]) if new.denominator > max_denominator: break result = new return result - @property - def numerator(a): - return a._numerator - - @property - def denominator(a): - return a._denominator - def __repr__(self): """repr(self)""" return ('Rational(%r,%r)' % (self.numerator, self.denominator)) @@ -226,6 +225,16 @@ else: return '%s/%s' % (self.numerator, self.denominator) + """ XXX This section needs a lot more commentary + + * Explain the typical sequence of checks, calls, and fallbacks. + * Explain the subtle reasons why this logic was needed. + * It is not clear how common cases are handled (for example, how + does the ratio of two huge integers get converted to a float + without overflowing the long-->float conversion. + + """ + def _operator_fallbacks(monomorphic_operator, fallback_operator): """Generates forward and reverse operators given a purely-rational operator and a function from the operator module. @@ -299,18 +308,15 @@ """a // b""" return math.floor(a / b) - @classmethod - def _mod(cls, a, b): - div = a // b - return a - b * div - def __mod__(a, b): """a % b""" - return a._mod(a, b) + div = a // b + return a - b * div def __rmod__(b, a): """a % b""" - return b._mod(a, b) + div = a // b + return a - b * div def __pow__(a, b): """a ** b @@ -369,6 +375,8 @@ else: return a.numerator // a.denominator + __int__ = __trunc__ + def __floor__(a): """Will be math.floor(a) in 3.0.""" return a.numerator // a.denominator @@ -410,6 +418,7 @@ float must have the same hash as that float. """ + # XXX since this method is expensive, consider caching the result if self.denominator == 1: # Get integers right. return hash(self.numerator) @@ -481,3 +490,18 @@ def __bool__(a): """a != 0""" return a.numerator != 0 + + # support for pickling, copy, and deepcopy + + def __reduce__(self): + return (self.__class__, (str(self),)) + + def __copy__(self): + if type(self) == Rational: + return self # I'm immutable; therefore I am my own clone + return self.__class__(self.numerator, self.denominator) + + def __deepcopy__(self, memo): + if type(self) == Rational: + return self # My components are also immutable + return self.__class__(self.numerator, self.denominator) Deleted: /python/branches/py3k/Lib/test/crashers/loosing_dict_ref.py ============================================================================== --- /python/branches/py3k/Lib/test/crashers/loosing_dict_ref.py Fri Jan 25 12:23:10 2008 +++ (empty file) @@ -1,21 +0,0 @@ - -# http://python.org/sf/1303614 - -class Strange(object): - def __hash__(self): - return hash('hello') - - def __eq__(self, other): - x.__dict__ = {} # the old x.__dict__ is deallocated - return False - - -class X(object): - pass - -if __name__ == '__main__': - v = 123 - x = X() - x.__dict__ = {Strange(): 42, - 'hello': v+456} - x.hello # segfault: the above dict is accessed after it's deallocated Modified: python/branches/py3k/Lib/test/test_decimal.py ============================================================================== --- python/branches/py3k/Lib/test/test_decimal.py (original) +++ python/branches/py3k/Lib/test/test_decimal.py Fri Jan 25 12:23:10 2008 @@ -1141,6 +1141,7 @@ checkSameDec("__floordiv__", True) checkSameDec("__hash__") checkSameDec("__int__") + checkSameDec("__trunc__") checkSameDec("__mod__", True) checkSameDec("__mul__", True) checkSameDec("__neg__") @@ -1204,6 +1205,16 @@ r = d.to_integral(ROUND_DOWN) self.assertEqual(Decimal(int(d)), r) + def test_trunc(self): + for x in range(-250, 250): + s = '%0.2f' % (x / 100.0) + # should work the same as for floats + self.assertEqual(int(Decimal(s)), int(float(s))) + # should work the same as to_integral in the ROUND_DOWN mode + d = Decimal(s) + r = d.to_integral(ROUND_DOWN) + self.assertEqual(Decimal(trunc(d)), r) + class ContextAPItests(unittest.TestCase): def test_pickle(self): Modified: python/branches/py3k/Lib/test/test_descr.py ============================================================================== --- python/branches/py3k/Lib/test/test_descr.py (original) +++ python/branches/py3k/Lib/test/test_descr.py Fri Jan 25 12:23:10 2008 @@ -4248,6 +4248,29 @@ finally: builtins.__import__ = orig_import +def test_losing_dict_ref_segfault(): + # This used to segfault; + # derived from issue #1303614, test67.py + if verbose: + print("Testing losing dict ref segfault...") + + class Strange(object): + def __hash__(self): + return hash('hello') + + def __eq__(self, other): + x.__dict__ = {} # the old x.__dict__ is deallocated + return False + + class X(object): + pass + + v = 123 + x = X() + x.__dict__ = {Strange(): 42, 'hello': v+456} + x.hello + + def test_main(): weakref_segfault() # Must be first, somehow wrapper_segfault() # NB This one is slow @@ -4348,6 +4371,7 @@ test_weakref_in_del_segfault() test_borrowed_ref_3_segfault() test_borrowed_ref_4_segfault() + test_losing_dict_ref_segfault() if verbose: print("All OK") Modified: python/branches/py3k/Lib/test/test_grammar.py ============================================================================== --- python/branches/py3k/Lib/test/test_grammar.py (original) +++ python/branches/py3k/Lib/test/test_grammar.py Fri Jan 25 12:23:10 2008 @@ -500,6 +500,15 @@ while 0: pass else: pass + # Issue1920: "while 0" is optimized away, + # ensure that the "else" clause is still present. + x = 0 + while 0: + x = 1 + else: + x = 2 + self.assertEquals(x, 2) + def testFor(self): # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] for i in 1, 2, 3: pass Modified: python/branches/py3k/Lib/test/test_pprint.py ============================================================================== --- python/branches/py3k/Lib/test/test_pprint.py (original) +++ python/branches/py3k/Lib/test/test_pprint.py Fri Jan 25 12:23:10 2008 @@ -1,6 +1,7 @@ import pprint import test.test_support import unittest +import test.test_set # list, tuple and dict subclasses that do or don't overwrite __repr__ class list2(list): @@ -189,6 +190,197 @@ others.should.not.be: like.this}""" self.assertEqual(DottedPrettyPrinter().pformat(o), exp) + def test_set_reprs(self): + self.assertEqual(pprint.pformat(set()), 'set()') + self.assertEqual(pprint.pformat(set(range(3))), '{0, 1, 2}') + self.assertEqual(pprint.pformat(frozenset()), 'frozenset()') + self.assertEqual(pprint.pformat(frozenset(range(3))), 'frozenset({0, 1, 2})') + cube_repr_tgt = """\ +{frozenset(): frozenset({frozenset({2}), frozenset({0}), frozenset({1})}), + frozenset({0}): frozenset([frozenset(), + frozenset({0, 2}), + frozenset({0, 1})]), + frozenset({1}): frozenset([frozenset(), + frozenset({1, 2}), + frozenset({0, 1})]), + frozenset({2}): frozenset([frozenset(), + frozenset({1, 2}), + frozenset({0, 2})]), + frozenset({1, 2}): frozenset([frozenset({2}), + frozenset({1}), + frozenset({0, 1, 2})]), + frozenset({0, 2}): frozenset([frozenset({2}), + frozenset({0}), + frozenset({0, 1, 2})]), + frozenset({0, 1}): frozenset([frozenset({0}), + frozenset({1}), + frozenset({0, 1, 2})]), + frozenset({0, 1, 2}): frozenset([frozenset({1, 2}), + frozenset({0, 2}), + frozenset({0, 1})])}""" + cube = test.test_set.cube(3) + self.assertEqual(pprint.pformat(cube), cube_repr_tgt) + cubo_repr_tgt = """\ +{frozenset({frozenset({0, 2}), frozenset({0})}): frozenset([frozenset([frozenset([0, + 2]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([0]), + frozenset([0, + 1])]), + frozenset([frozenset(), + frozenset([0])]), + frozenset([frozenset([2]), + frozenset([0, + 2])])]), + frozenset({frozenset({0, 1}), frozenset({1})}): frozenset([frozenset([frozenset([0, + 1]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([0]), + frozenset([0, + 1])]), + frozenset([frozenset([1]), + frozenset([1, + 2])]), + frozenset([frozenset(), + frozenset([1])])]), + frozenset({frozenset({1, 2}), frozenset({1})}): frozenset([frozenset([frozenset([1, + 2]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([2]), + frozenset([1, + 2])]), + frozenset([frozenset(), + frozenset([1])]), + frozenset([frozenset([1]), + frozenset([0, + 1])])]), + frozenset({frozenset({1, 2}), frozenset({2})}): frozenset([frozenset([frozenset([1, + 2]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([1]), + frozenset([1, + 2])]), + frozenset([frozenset([2]), + frozenset([0, + 2])]), + frozenset([frozenset(), + frozenset([2])])]), + frozenset({frozenset(), frozenset({0})}): frozenset([frozenset([frozenset([0]), + frozenset([0, + 1])]), + frozenset([frozenset([0]), + frozenset([0, + 2])]), + frozenset([frozenset(), + frozenset([1])]), + frozenset([frozenset(), + frozenset([2])])]), + frozenset({frozenset(), frozenset({1})}): frozenset([frozenset([frozenset(), + frozenset([0])]), + frozenset([frozenset([1]), + frozenset([1, + 2])]), + frozenset([frozenset(), + frozenset([2])]), + frozenset([frozenset([1]), + frozenset([0, + 1])])]), + frozenset({frozenset({2}), frozenset()}): frozenset([frozenset([frozenset([2]), + frozenset([1, + 2])]), + frozenset([frozenset(), + frozenset([0])]), + frozenset([frozenset(), + frozenset([1])]), + frozenset([frozenset([2]), + frozenset([0, + 2])])]), + frozenset({frozenset({0, 1, 2}), frozenset({0, 1})}): frozenset([frozenset([frozenset([1, + 2]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([0, + 2]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([0]), + frozenset([0, + 1])]), + frozenset([frozenset([1]), + frozenset([0, + 1])])]), + frozenset({frozenset({0}), frozenset({0, 1})}): frozenset([frozenset([frozenset(), + frozenset([0])]), + frozenset([frozenset([0, + 1]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([0]), + frozenset([0, + 2])]), + frozenset([frozenset([1]), + frozenset([0, + 1])])]), + frozenset({frozenset({2}), frozenset({0, 2})}): frozenset([frozenset([frozenset([0, + 2]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([2]), + frozenset([1, + 2])]), + frozenset([frozenset([0]), + frozenset([0, + 2])]), + frozenset([frozenset(), + frozenset([2])])]), + frozenset({frozenset({0, 1, 2}), frozenset({0, 2})}): frozenset([frozenset([frozenset([1, + 2]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([0, + 1]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([0]), + frozenset([0, + 2])]), + frozenset([frozenset([2]), + frozenset([0, + 2])])]), + frozenset({frozenset({1, 2}), frozenset({0, 1, 2})}): frozenset([frozenset([frozenset([0, + 2]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([0, + 1]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([2]), + frozenset([1, + 2])]), + frozenset([frozenset([1]), + frozenset([1, + 2])])])}""" + + cubo = test.test_set.linegraph(cube) + self.assertEqual(pprint.pformat(cubo), cubo_repr_tgt) + class DottedPrettyPrinter(pprint.PrettyPrinter): Modified: python/branches/py3k/Lib/test/test_rational.py ============================================================================== --- python/branches/py3k/Lib/test/test_rational.py (original) +++ python/branches/py3k/Lib/test/test_rational.py Fri Jan 25 12:23:10 2008 @@ -6,6 +6,8 @@ import operator import rational import unittest +from copy import copy, deepcopy +from cPickle import dumps, loads R = rational.Rational def _components(r): @@ -153,16 +155,17 @@ [-4, 1, 6, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 3, 3]) self.assertEqual(R(0).as_continued_fraction(), [0]) - def testApproximateFromFloat(self): - self.assertEqual(R.approximate_from_float(math.pi, 10000), R(355, 113)) - self.assertEqual(R.approximate_from_float(-math.pi, 10000), R(-355, 113)) - self.assertEqual(R.approximate_from_float(0.0, 10000), R(0)) + def testApproximateFrom(self): + self.assertEqual(R.from_float(math.pi).approximate(10000), R(355, 113)) + self.assertEqual(R.from_float(-math.pi).approximate(10000), R(-355, 113)) + self.assertEqual(R.from_float(0.0).approximate(10000), R(0)) def testConversions(self): self.assertTypedEquals(-1, trunc(R(-11, 10))) self.assertTypedEquals(-2, math.floor(R(-11, 10))) self.assertTypedEquals(-1, math.ceil(R(-11, 10))) self.assertTypedEquals(-1, math.ceil(R(-10, 10))) + self.assertTypedEquals(-1, int(R(-11, 10))) self.assertTypedEquals(0, round(R(-1, 10))) self.assertTypedEquals(0, round(R(-5, 10))) @@ -360,6 +363,12 @@ s += num / fact * sign self.assertAlmostEquals(math.cos(1), s) + def test_copy_deepcopy_pickle(self): + r = R(13, 7) + self.assertEqual(r, loads(dumps(r))) + self.assertEqual(id(r), id(copy(r))) + self.assertEqual(id(r), id(deepcopy(r))) + def test_main(): run_unittest(RationalTest) Modified: python/branches/py3k/Lib/test/test_set.py ============================================================================== --- python/branches/py3k/Lib/test/test_set.py (original) +++ python/branches/py3k/Lib/test/test_set.py Fri Jan 25 12:23:10 2008 @@ -8,6 +8,7 @@ from random import randrange, shuffle import sys import warnings +import collections class PassThru(Exception): pass @@ -1605,6 +1606,110 @@ self.assertRaises(TypeError, getattr(set('january'), methname), N(data)) self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data)) +# Application tests (based on David Eppstein's graph recipes ==================================== + +def powerset(U): + """Generates all subsets of a set or sequence U.""" + U = iter(U) + try: + x = frozenset([next(U)]) + for S in powerset(U): + yield S + yield S | x + except StopIteration: + yield frozenset() + +def cube(n): + """Graph of n-dimensional hypercube.""" + singletons = [frozenset([x]) for x in range(n)] + return dict([(x, frozenset([x^s for s in singletons])) + for x in powerset(range(n))]) + +def linegraph(G): + """Graph, the vertices of which are edges of G, + with two vertices being adjacent iff the corresponding + edges share a vertex.""" + L = {} + for x in G: + for y in G[x]: + nx = [frozenset([x,z]) for z in G[x] if z != y] + ny = [frozenset([y,z]) for z in G[y] if z != x] + L[frozenset([x,y])] = frozenset(nx+ny) + return L + +def faces(G): + 'Return a set of faces in G. Where a face is a set of vertices on that face' + # currently limited to triangles,squares, and pentagons + f = set() + for v1, edges in G.items(): + for v2 in edges: + for v3 in G[v2]: + if v1 == v3: + continue + if v1 in G[v3]: + f.add(frozenset([v1, v2, v3])) + else: + for v4 in G[v3]: + if v4 == v2: + continue + if v1 in G[v4]: + f.add(frozenset([v1, v2, v3, v4])) + else: + for v5 in G[v4]: + if v5 == v3 or v5 == v2: + continue + if v1 in G[v5]: + f.add(frozenset([v1, v2, v3, v4, v5])) + return f + + +class TestGraphs(unittest.TestCase): + + def test_cube(self): + + g = cube(3) # vert --> {v1, v2, v3} + vertices1 = set(g) + self.assertEqual(len(vertices1), 8) # eight vertices + for edge in g.values(): + self.assertEqual(len(edge), 3) # each vertex connects to three edges + vertices2 = set(v for edges in g.values() for v in edges) + self.assertEqual(vertices1, vertices2) # edge vertices in original set + + cubefaces = faces(g) + self.assertEqual(len(cubefaces), 6) # six faces + for face in cubefaces: + self.assertEqual(len(face), 4) # each face is a square + + def test_cuboctahedron(self): + + # http://en.wikipedia.org/wiki/Cuboctahedron + # 8 triangular faces and 6 square faces + # 12 indentical vertices each connecting a triangle and square + + g = cube(3) + cuboctahedron = linegraph(g) # V( --> {V1, V2, V3, V4} + self.assertEqual(len(cuboctahedron), 12)# twelve vertices + + vertices = set(cuboctahedron) + for edges in cuboctahedron.values(): + self.assertEqual(len(edges), 4) # each vertex connects to four other vertices + othervertices = set(edge for edges in cuboctahedron.values() for edge in edges) + self.assertEqual(vertices, othervertices) # edge vertices in original set + + cubofaces = faces(cuboctahedron) + facesizes = collections.defaultdict(int) + for face in cubofaces: + facesizes[len(face)] += 1 + self.assertEqual(facesizes[3], 8) # eight triangular faces + self.assertEqual(facesizes[4], 6) # six square faces + + for vertex in cuboctahedron: + edge = vertex # Cuboctahedron vertices are edges in Cube + self.assertEqual(len(edge), 2) # Two cube vertices define an edge + for cubevert in edge: + self.assert_(cubevert in g) + + #============================================================================== def test_main(verbose=None): @@ -1644,6 +1749,7 @@ TestCopyingNested, TestIdentities, TestVariousIteratorArgs, + TestGraphs, ) test_support.run_unittest(*test_classes) Modified: python/branches/py3k/Lib/test/test_urllib2net.py ============================================================================== --- python/branches/py3k/Lib/test/test_urllib2net.py (original) +++ python/branches/py3k/Lib/test/test_urllib2net.py Fri Jan 25 12:23:10 2008 @@ -10,6 +10,20 @@ import os import mimetools + +def _urlopen_with_retry(host, *args, **kwargs): + # Connecting to remote hosts is flaky. Make it more robust + # by retrying the connection several times. + for i in range(3): + try: + return urllib2.urlopen(host, *args, **kwargs) + except urllib2.URLError as last_exc: + continue + except: + raise + raise last_exc + + class URLTimeoutTest(unittest.TestCase): TIMEOUT = 10.0 @@ -21,7 +35,7 @@ socket.setdefaulttimeout(None) def testURLread(self): - f = urllib2.urlopen("http://www.python.org/") + f = _urlopen_with_retry("http://www.python.org/") x = f.read() @@ -42,7 +56,7 @@ # # # failure # try: -# urllib2.urlopen(test_url) +# _urlopen_with_retry(test_url) # except urllib2.HTTPError, exc: # self.assertEqual(exc.code, 401) # else: @@ -54,7 +68,7 @@ # test_user, test_password) # opener = urllib2.build_opener(auth_handler) # f = opener.open('http://localhost/') -# response = urllib2.urlopen("http://www.python.org/") +# response = _urlopen_with_retry("http://www.python.org/") # # # The 'userinfo' URL component is deprecated by RFC 3986 for security # # reasons, let's not implement it! (it's already implemented for proxy @@ -73,7 +87,7 @@ # underlying socket # delve deep into response to fetch socket._socketobject - response = urllib2.urlopen("http://www.python.org/") + response = _urlopen_with_retry("http://www.python.org/") abused_fileobject = response.fp httpresponse = abused_fileobject.raw self.assert_(httpresponse.__class__ is httplib.HTTPResponse) @@ -100,7 +114,7 @@ def test_basic(self): # Simple test expected to pass. - open_url = urllib2.urlopen("http://www.python.org/") + open_url = _urlopen_with_retry("http://www.python.org/") for attr in ("read", "close", "info", "geturl"): self.assert_(hasattr(open_url, attr), "object returned from " "urlopen lacks the %s attribute" % attr) @@ -111,7 +125,7 @@ def test_info(self): # Test 'info'. - open_url = urllib2.urlopen("http://www.python.org/") + open_url = _urlopen_with_retry("http://www.python.org/") try: info_obj = open_url.info() finally: @@ -124,7 +138,7 @@ def test_geturl(self): # Make sure same URL as opened is returned by geturl. URL = "http://www.python.org/" - open_url = urllib2.urlopen(URL) + open_url = _urlopen_with_retry(URL) try: gotten_url = open_url.geturl() finally: @@ -155,7 +169,7 @@ def test_range (self): req = urllib2.Request("http://www.python.org", headers={'Range': 'bytes=20-39'}) - result = urllib2.urlopen(req) + result = _urlopen_with_retry(req) data = result.read() self.assertEqual(len(data), 20) @@ -182,7 +196,7 @@ 'file:'+sanepathname2url(os.path.abspath(TESTFN)), ('file:///nonsensename/etc/passwd', None, urllib2.URLError), ] - self._test_urls(urls, self._extra_handlers()) + self._test_urls(urls, self._extra_handlers(), urllib2.urlopen) finally: os.remove(TESTFN) @@ -224,7 +238,7 @@ ## self._test_urls(urls, self._extra_handlers()+[bauth, dauth]) - def _test_urls(self, urls, handlers): + def _test_urls(self, urls, handlers, urlopen=_urlopen_with_retry): import socket import time import logging @@ -239,7 +253,7 @@ req = expected_err = None debug(url) try: - f = urllib2.urlopen(url, req) + f = urlopen(url, req) except EnvironmentError as err: debug(err) if expected_err: @@ -265,47 +279,47 @@ class TimeoutTest(unittest.TestCase): def test_http_basic(self): - u = urllib2.urlopen("http://www.python.org") + u = _urlopen_with_retry("http://www.python.org") self.assertTrue(u.fp.raw.fp._sock.gettimeout() is None) def test_http_NoneWithdefault(self): prev = socket.getdefaulttimeout() socket.setdefaulttimeout(60) try: - u = urllib2.urlopen("http://www.python.org", timeout=None) + u = _urlopen_with_retry("http://www.python.org", timeout=None) self.assertTrue(u.fp.raw.fp._sock.gettimeout(), 60) finally: socket.setdefaulttimeout(prev) def test_http_Value(self): - u = urllib2.urlopen("http://www.python.org", timeout=120) + u = _urlopen_with_retry("http://www.python.org", timeout=120) self.assertEqual(u.fp.raw.fp._sock.gettimeout(), 120) def test_http_NoneNodefault(self): - u = urllib2.urlopen("http://www.python.org", timeout=None) + u = _urlopen_with_retry("http://www.python.org", timeout=None) self.assertTrue(u.fp.raw.fp._sock.gettimeout() is None) + FTP_HOST = "ftp://ftp.mirror.nl/pub/mirror/gnu/" + def test_ftp_basic(self): - u = urllib2.urlopen("ftp://ftp.mirror.nl/pub/mirror/gnu/") + u = _urlopen_with_retry(self.FTP_HOST) self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None) def test_ftp_NoneWithdefault(self): prev = socket.getdefaulttimeout() socket.setdefaulttimeout(60) try: - u = urllib2.urlopen("ftp://ftp.mirror.nl/pub/mirror/gnu/", - timeout=None) - self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60) + u = _urlopen_with_retry(self.FTP_HOST, timeout=None) + self.assertEqual(u.fp.fp._sock.gettimeout(), 60) finally: socket.setdefaulttimeout(prev) def test_ftp_NoneNodefault(self): - u = urllib2.urlopen("ftp://ftp.mirror.nl/pub/mirror/gnu/", - timeout=None) - self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None) + u = _urlopen_with_retry(self.FTP_HOST, timeout=None) + self.assertTrue(u.fp.fp._sock.gettimeout() is None) def test_ftp_Value(self): - u = urllib2.urlopen("ftp://ftp.mirror.nl/pub/mirror/gnu/", timeout=60) + u = _urlopen_with_retry(self.FTP_HOST, timeout=60) self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60) Modified: python/branches/py3k/Lib/threading.py ============================================================================== --- python/branches/py3k/Lib/threading.py (original) +++ python/branches/py3k/Lib/threading.py Fri Jan 25 12:23:10 2008 @@ -346,18 +346,27 @@ return self._flag def set(self): - with self._cond: + self._cond.acquire() + try: self._flag = True self._cond.notifyAll() + finally: + self._cond.release() def clear(self): - with self._cond: + self._cond.acquire() + try: self._flag = False + finally: + self._cond.release() def wait(self, timeout=None): - with self._cond: + self._cond.acquire() + try: if not self._flag: self._cond.wait(timeout) + finally: + self._cond.release() # Helper to generate new thread names _counter = 0 @@ -524,9 +533,10 @@ pass def _stop(self): - with self._block: - self._stopped = True - self._block.notifyAll() + self._block.acquire() + self._stopped = True + self._block.notifyAll() + self._block.release() def _delete(self): "Remove current thread from the dict of currently running threads." @@ -552,12 +562,15 @@ # since it isn't if dummy_threading is *not* being used then don't # hide the exception. - with _active_limbo_lock: + _active_limbo_lock.acquire() + try: try: del _active[_get_ident()] except KeyError: if 'dummy_threading' not in _sys.modules: raise + finally: + _active_limbo_lock.release() def join(self, timeout=None): if not self._initialized: @@ -570,7 +583,9 @@ if __debug__: if not self._stopped: self._note("%s.join(): waiting until thread stops", self) - with self._block: + + self._block.acquire() + try: if timeout is None: while not self._stopped: self._block.wait() @@ -588,6 +603,8 @@ else: if __debug__: self._note("%s.join(): thread stopped", self) + finally: + self._block.release() def getName(self): assert self._initialized, "Thread.__init__() not called" Modified: python/branches/py3k/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k/Modules/_ctypes/_ctypes.c Fri Jan 25 12:23:10 2008 @@ -122,12 +122,134 @@ PyObject *PyExc_ArgError; static PyTypeObject Simple_Type; -PyObject *array_types_cache; char *conversion_mode_encoding = NULL; char *conversion_mode_errors = NULL; +/****************************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *key; + PyObject *dict; +} DictRemoverObject; + +static void +_DictRemover_dealloc(PyObject *_self) +{ + DictRemoverObject *self = (DictRemoverObject *)_self; + Py_XDECREF(self->key); + Py_XDECREF(self->dict); + Py_TYPE(self)->tp_free(_self); +} + +static PyObject * +_DictRemover_call(PyObject *_self, PyObject *args, PyObject *kw) +{ + DictRemoverObject *self = (DictRemoverObject *)_self; + if (self->key && self->dict) { + if (-1 == PyDict_DelItem(self->dict, self->key)) + /* XXX Error context */ + PyErr_WriteUnraisable(Py_None); + Py_DECREF(self->key); + self->key = NULL; + Py_DECREF(self->dict); + self->dict = NULL; + } + Py_INCREF(Py_None); + return Py_None; +} + +static PyTypeObject DictRemover_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ctypes.DictRemover", /* tp_name */ + sizeof(DictRemoverObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + _DictRemover_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + _DictRemover_call, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ +/* XXX should participate in GC? */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + "deletes a key from a dictionary", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + 0, /* tp_free */ +}; + +int +PyDict_SetItemProxy(PyObject *dict, PyObject *key, PyObject *item) +{ + PyObject *obj; + DictRemoverObject *remover; + PyObject *proxy; + int result; + + obj = PyObject_CallObject((PyObject *)&DictRemover_Type, NULL); + if (obj == NULL) + return -1; + + remover = (DictRemoverObject *)obj; + assert(remover->key == NULL); + assert(remover->dict == NULL); + Py_INCREF(key); + remover->key = key; + Py_INCREF(dict); + remover->dict = dict; + + proxy = PyWeakref_NewProxy(item, obj); + Py_DECREF(obj); + if (proxy == NULL) + return -1; + + result = PyDict_SetItem(dict, key, proxy); + Py_DECREF(proxy); + return result; +} + +PyObject * +PyDict_GetItemProxy(PyObject *dict, PyObject *key) +{ + PyObject *result; + PyObject *item = PyDict_GetItem(dict, key); + + if (item == NULL) + return NULL; + if (!PyWeakref_CheckProxy(item)) + return item; + result = PyWeakref_GET_OBJECT(item); + if (result == Py_None) + return NULL; + return result; +} + /******************************************************************/ /* StructType_Type - a meta type/class. Creating a new class using this one as @@ -2381,7 +2503,7 @@ only it's object list. So we create a tuple, containing b_objects list PLUS the array itself, and return that! */ - return Py_BuildValue("(OO)", keep, value); + return PyTuple_Pack(2, keep, value); } PyErr_Format(PyExc_TypeError, "incompatible types, %s instance instead of %s instance", @@ -3993,19 +4115,30 @@ PyObject * CreateArrayType(PyObject *itemtype, Py_ssize_t length) { + static PyObject *cache; PyObject *key; PyObject *result; char name[256]; + PyObject *len; - key = Py_BuildValue("(On)", itemtype, length); + if (cache == NULL) { + cache = PyDict_New(); + if (cache == NULL) + return NULL; + } + len = PyLong_FromSsize_t(length); + if (len == NULL) + return NULL; + key = PyTuple_Pack(2, itemtype, len); + Py_DECREF(len); if (!key) return NULL; - result = PyObject_GetItem(array_types_cache, key); + result = PyDict_GetItemProxy(cache, key); if (result) { + Py_INCREF(result); Py_DECREF(key); return result; - } else - PyErr_Clear(); + } if (!PyType_Check(itemtype)) { PyErr_SetString(PyExc_TypeError, @@ -4029,9 +4162,11 @@ "_type_", itemtype ); - if (!result) + if (result == NULL) { + Py_DECREF(key); return NULL; - if (-1 == PyObject_SetItem(array_types_cache, key, result)) { + } + if (-1 == PyDict_SetItemProxy(cache, key, result)) { Py_DECREF(key); Py_DECREF(result); return NULL; @@ -4792,7 +4927,6 @@ init_ctypes(void) { PyObject *m; - PyObject *weakref; /* Note: ob_type is the metatype (the 'type'), defaults to PyType_Type, @@ -4805,16 +4939,6 @@ if (!m) return; - weakref = PyImport_ImportModule("weakref"); - if (weakref == NULL) - return; - array_types_cache = PyObject_CallMethod(weakref, - "WeakValueDictionary", - NULL); - if (array_types_cache == NULL) - return; - Py_DECREF(weakref); - if (PyType_Ready(&PyCArg_Type) < 0) return; @@ -4910,6 +5034,10 @@ * Other stuff */ + DictRemover_Type.tp_new = PyType_GenericNew; + if (PyType_Ready(&DictRemover_Type) < 0) + return; + #ifdef MS_WIN32 if (create_comerror() < 0) return; Modified: python/branches/py3k/Modules/_ctypes/cfield.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/cfield.c (original) +++ python/branches/py3k/Modules/_ctypes/cfield.c Fri Jan 25 12:23:10 2008 @@ -334,10 +334,10 @@ get_long(PyObject *v, long *p) { long x; - if (!PyLong_Check(v)) { - PyErr_Format(PyExc_TypeError, - "int expected instead of %s instance", - v->ob_type->tp_name); + + if (PyFloat_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "int expected instead of float"); return -1; } x = PyLong_AsUnsignedLongMask(v); @@ -353,10 +353,10 @@ get_ulong(PyObject *v, unsigned long *p) { unsigned long x; - if (!PyLong_Check(v)) { - PyErr_Format(PyExc_TypeError, - "int expected instead of %s instance", - v->ob_type->tp_name); + + if (PyFloat_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "int expected instead of float"); return -1; } x = PyLong_AsUnsignedLongMask(v); @@ -374,11 +374,10 @@ get_longlong(PyObject *v, PY_LONG_LONG *p) { PY_LONG_LONG x; - if (!PyLong_Check(v)) { - PyErr_Format(PyExc_TypeError, - "int expected instead of %s instance", - v->ob_type->tp_name); - return -1; + if (PyFloat_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "int expected instead of float"); + return -1; } x = PyLong_AsUnsignedLongLongMask(v); if (x == -1 && PyErr_Occurred()) @@ -393,12 +392,11 @@ get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p) { unsigned PY_LONG_LONG x; - if (!PyLong_Check(v)) { - PyErr_Format(PyExc_TypeError, - "int expected instead of %s instance", - v->ob_type->tp_name); - return -1; - } + if (PyFloat_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "int expected instead of float"); + return -1; + } x = PyLong_AsUnsignedLongLongMask(v); if (x == -1 && PyErr_Occurred()) return -1; Modified: python/branches/py3k/Modules/mathmodule.c ============================================================================== --- python/branches/py3k/Modules/mathmodule.c (original) +++ python/branches/py3k/Modules/mathmodule.c Fri Jan 25 12:23:10 2008 @@ -12,6 +12,11 @@ #endif /* __STDC__ */ #endif /* _MSC_VER */ +#ifdef _OSF_SOURCE +/* OSF1 5.1 doesn't make this available with XOPEN_SOURCE_EXTENDED defined */ +extern double copysign(double, double); +#endif + /* Call is_error when errno != 0, and where x is the result libm * returned. is_error will usually set up an exception and return * true (1), but may return false (0) without setting up an exception. Modified: python/branches/py3k/Objects/floatobject.c ============================================================================== --- python/branches/py3k/Objects/floatobject.c (original) +++ python/branches/py3k/Objects/floatobject.c Fri Jan 25 12:23:10 2008 @@ -17,6 +17,11 @@ extern double pow(double, double); #endif +#ifdef _OSF_SOURCE +/* OSF1 5.1 doesn't make this available with XOPEN_SOURCE_EXTENDED defined */ +extern int finite(double); +#endif + /* Special free list -- see comments for same code in intobject.c. */ #define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */ #define BHEAD_SIZE 8 /* Enough for a 64-bit pointer */ Modified: python/branches/py3k/Objects/object.c ============================================================================== --- python/branches/py3k/Objects/object.c (original) +++ python/branches/py3k/Objects/object.c Fri Jan 25 12:23:10 2008 @@ -1004,12 +1004,15 @@ dictptr = (PyObject **) ((char *)obj + dictoffset); dict = *dictptr; if (dict != NULL) { + Py_INCREF(dict); res = PyDict_GetItem(dict, name); if (res != NULL) { Py_INCREF(res); Py_XDECREF(descr); + Py_DECREF(dict); goto done; } + Py_DECREF(dict); } } @@ -1076,12 +1079,14 @@ *dictptr = dict; } if (dict != NULL) { + Py_INCREF(dict); if (value == NULL) res = PyDict_DelItem(dict, name); else res = PyDict_SetItem(dict, name, value); if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) PyErr_SetObject(PyExc_AttributeError, name); + Py_DECREF(dict); goto done; } } Modified: python/branches/py3k/Python/compile.c ============================================================================== --- python/branches/py3k/Python/compile.c (original) +++ python/branches/py3k/Python/compile.c Fri Jan 25 12:23:10 2008 @@ -1737,8 +1737,11 @@ basicblock *loop, *orelse, *end, *anchor = NULL; int constant = expr_constant(s->v.While.test); - if (constant == 0) + if (constant == 0) { + if (s->v.While.orelse) + VISIT_SEQ(c, stmt, s->v.While.orelse); return 1; + } loop = compiler_new_block(c); end = compiler_new_block(c); if (constant == -1) { From python-3000-checkins at python.org Fri Jan 25 12:33:18 2008 From: python-3000-checkins at python.org (walter.doerwald) Date: Fri, 25 Jan 2008 12:33:18 +0100 (CET) Subject: [Python-3000-checkins] r60282 - python/branches/py3k/Doc/whatsnew/3.0.rst Message-ID: <20080125113318.5D8611E4023@bag.python.org> Author: walter.doerwald Date: Fri Jan 25 12:33:18 2008 New Revision: 60282 Modified: python/branches/py3k/Doc/whatsnew/3.0.rst Log: Fix typo. Modified: python/branches/py3k/Doc/whatsnew/3.0.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.0.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.0.rst Fri Jan 25 12:33:18 2008 @@ -248,7 +248,7 @@ built-in integral type, named ``int``; but it behaves like the old ``long`` type, with the exception that the literal suffix ``L`` is neither supported by the parser nor produced by ``repr()`` anymore. - ``sys.maxint`` was also removed since the int type has maximum + ``sys.maxint`` was also removed since the int type has no maximum value anymore. * PEP 238: int division returns a float. From python-3000-checkins at python.org Fri Jan 25 13:21:52 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Fri, 25 Jan 2008 13:21:52 +0100 (CET) Subject: [Python-3000-checkins] r60284 - python/branches/py3k Message-ID: <20080125122152.0DD6E1E400F@bag.python.org> Author: christian.heimes Date: Fri Jan 25 13:21:51 2008 New Revision: 60284 Modified: python/branches/py3k/ (props changed) Log: Bump up merge information to skip the backports From python-3000-checkins at python.org Fri Jan 25 14:18:22 2008 From: python-3000-checkins at python.org (thomas.heller) Date: Fri, 25 Jan 2008 14:18:22 +0100 (CET) Subject: [Python-3000-checkins] r60285 - in python/branches/py3k-ctypes-pep3118: Doc/library/itertools.rst Doc/whatsnew/3.0.rst Lib/ctypes/test/test_numbers.py Lib/decimal.py Lib/pprint.py Lib/rational.py Lib/test/crashers/loosing_dict_ref.py Lib/test/test_decimal.py Lib/test/test_descr.py Lib/test/test_grammar.py Lib/test/test_pprint.py Lib/test/test_rational.py Lib/test/test_set.py Lib/test/test_urllib2net.py Lib/threading.py Modules/_ctypes/_ctypes.c Modules/_ctypes/cfield.c Modules/mathmodule.c Objects/floatobject.c Objects/object.c Python/compile.c Message-ID: <20080125131822.729511E4013@bag.python.org> Author: thomas.heller Date: Fri Jan 25 14:18:20 2008 New Revision: 60285 Removed: python/branches/py3k-ctypes-pep3118/Lib/test/crashers/loosing_dict_ref.py Modified: python/branches/py3k-ctypes-pep3118/ (props changed) python/branches/py3k-ctypes-pep3118/Doc/library/itertools.rst python/branches/py3k-ctypes-pep3118/Doc/whatsnew/3.0.rst python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_numbers.py python/branches/py3k-ctypes-pep3118/Lib/decimal.py python/branches/py3k-ctypes-pep3118/Lib/pprint.py python/branches/py3k-ctypes-pep3118/Lib/rational.py python/branches/py3k-ctypes-pep3118/Lib/test/test_decimal.py python/branches/py3k-ctypes-pep3118/Lib/test/test_descr.py python/branches/py3k-ctypes-pep3118/Lib/test/test_grammar.py python/branches/py3k-ctypes-pep3118/Lib/test/test_pprint.py python/branches/py3k-ctypes-pep3118/Lib/test/test_rational.py python/branches/py3k-ctypes-pep3118/Lib/test/test_set.py python/branches/py3k-ctypes-pep3118/Lib/test/test_urllib2net.py python/branches/py3k-ctypes-pep3118/Lib/threading.py python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c python/branches/py3k-ctypes-pep3118/Modules/_ctypes/cfield.c python/branches/py3k-ctypes-pep3118/Modules/mathmodule.c python/branches/py3k-ctypes-pep3118/Objects/floatobject.c python/branches/py3k-ctypes-pep3118/Objects/object.c python/branches/py3k-ctypes-pep3118/Python/compile.c Log: Merged revisions 60267,60279-60282,60284 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r60267 | georg.brandl | 2008-01-25 00:34:34 +0100 (Fr, 25 Jan 2008) | 2 lines Fix merge glitch. ................ r60279 | christian.heimes | 2008-01-25 12:02:28 +0100 (Fr, 25 Jan 2008) | 1 line Document that basestring has been replaced by str. Issue #1931. ................ r60280 | christian.heimes | 2008-01-25 12:10:11 +0100 (Fr, 25 Jan 2008) | 1 line Added comment about sys.maxint to whatsnew. Issue #1930 ................ r60281 | christian.heimes | 2008-01-25 12:23:10 +0100 (Fr, 25 Jan 2008) | 120 lines Merged revisions 60245-60277 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60246 | guido.van.rossum | 2008-01-24 18:58:05 +0100 (Thu, 24 Jan 2008) | 2 lines Fix test67.py from issue #1303614. ........ r60248 | raymond.hettinger | 2008-01-24 19:05:54 +0100 (Thu, 24 Jan 2008) | 1 line Clean-up and speed-up code by accessing numerator/denominator directly. There's no reason to enforce readonliness ........ r60249 | raymond.hettinger | 2008-01-24 19:12:23 +0100 (Thu, 24 Jan 2008) | 1 line Revert 60189 and restore performance. ........ r60250 | guido.van.rossum | 2008-01-24 19:21:02 +0100 (Thu, 24 Jan 2008) | 5 lines News about recently fixed crashers: - A few crashers fixed: weakref_in_del.py (issue #1377858); loosing_dict_ref.py (issue #1303614, test67.py); borrowed_ref_[34].py (not in tracker). ........ r60252 | thomas.heller | 2008-01-24 19:36:27 +0100 (Thu, 24 Jan 2008) | 7 lines Use a PyDictObject again for the array type cache; retrieving items from the WeakValueDictionary was slower by nearly a factor of 3. To avoid leaks, weakref proxies for the array types are put into the cache dict, with weakref callbacks that removes the entries when the type goes away. ........ r60253 | thomas.heller | 2008-01-24 19:54:12 +0100 (Thu, 24 Jan 2008) | 2 lines Replace Py_BuildValue with PyTuple_Pack because it is faster. Also add a missing DECREF. ........ r60254 | raymond.hettinger | 2008-01-24 20:05:29 +0100 (Thu, 24 Jan 2008) | 1 line Add support for trunc(). ........ r60255 | thomas.heller | 2008-01-24 20:15:02 +0100 (Thu, 24 Jan 2008) | 5 lines Invert the checks in get_[u]long and get_[u]longlong. The intent was to not accept float types; the result was that integer-like objects were not accepted. Ported from release25-maint. ........ r60256 | raymond.hettinger | 2008-01-24 20:30:19 +0100 (Thu, 24 Jan 2008) | 1 line Add support for int(r) just like the other numeric classes. ........ r60263 | raymond.hettinger | 2008-01-24 22:23:58 +0100 (Thu, 24 Jan 2008) | 1 line Expand tests to include nested graph structures. ........ r60264 | raymond.hettinger | 2008-01-24 22:47:56 +0100 (Thu, 24 Jan 2008) | 1 line Shorter pprint's for empty sets and frozensets. Fix indentation of frozensets. Add tests including two complex data structures. ........ r60265 | amaury.forgeotdarc | 2008-01-24 23:51:18 +0100 (Thu, 24 Jan 2008) | 14 lines #1920: when considering a block starting by "while 0", the compiler optimized the whole construct away, even when an 'else' clause is present:: while 0: print("no") else: print("yes") did not generate any code at all. Now the compiler emits the 'else' block, like it already does for 'if' statements. Will backport. ........ r60266 | amaury.forgeotdarc | 2008-01-24 23:59:25 +0100 (Thu, 24 Jan 2008) | 2 lines News entry for r60265 (Issue 1920). ........ r60269 | raymond.hettinger | 2008-01-25 00:50:26 +0100 (Fri, 25 Jan 2008) | 1 line More code cleanup. Remove unnecessary indirection to useless class methods. ........ r60270 | raymond.hettinger | 2008-01-25 01:21:54 +0100 (Fri, 25 Jan 2008) | 1 line Add support for copy, deepcopy, and pickle. ........ r60271 | raymond.hettinger | 2008-01-25 01:33:45 +0100 (Fri, 25 Jan 2008) | 1 line Mark todos and review comments. ........ r60272 | raymond.hettinger | 2008-01-25 02:13:12 +0100 (Fri, 25 Jan 2008) | 1 line Add one other review comment. ........ r60273 | raymond.hettinger | 2008-01-25 02:23:38 +0100 (Fri, 25 Jan 2008) | 1 line Fix-up signature for approximation. ........ r60274 | raymond.hettinger | 2008-01-25 02:46:33 +0100 (Fri, 25 Jan 2008) | 1 line More design notes ........ r60276 | neal.norwitz | 2008-01-25 07:37:23 +0100 (Fri, 25 Jan 2008) | 6 lines Make the test more robust by trying to reconnect up to 3 times in case there were transient failures. This will hopefully silence the buildbots for this test. As we find other tests that have a problem, we can fix with a similar strategy assuming it is successful. It worked on my box in a loop for 10+ runs where it would have an exception otherwise. ........ r60277 | neal.norwitz | 2008-01-25 09:04:16 +0100 (Fri, 25 Jan 2008) | 4 lines Add prototypes to get the mathmodule.c to compile on OSF1 5.1 (Tru64) and eliminate a compiler warning in floatobject.c. There might be a better way to go about this, but it should be good enough for now. ........ ................ r60282 | walter.doerwald | 2008-01-25 12:33:18 +0100 (Fr, 25 Jan 2008) | 2 lines Fix typo. ................ r60284 | christian.heimes | 2008-01-25 13:21:51 +0100 (Fr, 25 Jan 2008) | 1 line Bump up merge information to skip the backports ................ Modified: python/branches/py3k-ctypes-pep3118/Doc/library/itertools.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/library/itertools.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/library/itertools.rst Fri Jan 25 14:18:20 2008 @@ -259,22 +259,9 @@ makes possible an idiom for clustering a data series into n-length groups using ``izip(*[iter(s)]*n)``. -<<<<<<< .working - Note, when :func:`izip` is used with unequal length inputs, subsequent - iteration over the longer iterables cannot reliably be continued after - :func:`izip` terminates. Potentially, up to one entry will be missing from - each of the left-over iterables. This occurs because a value is fetched from - each iterator in- turn, but the process ends when one of the iterators - terminates. This leaves the last fetched values in limbo (they cannot be - returned in a final, incomplete tuple and they are cannot be pushed back into - the iterator for retrieval with ``next(it)``). In general, :func:`izip` - should only be used with unequal length inputs when you don't care about - trailing, unmatched values from the longer iterables. -======= :func:`izip` should only be used with unequal length inputs when you don't care about trailing, unmatched values from the longer iterables. If those values are important, use :func:`izip_longest` instead. ->>>>>>> .merge-right.r60208 .. function:: izip_longest(*iterables[, fillvalue]) Modified: python/branches/py3k-ctypes-pep3118/Doc/whatsnew/3.0.rst ============================================================================== --- python/branches/py3k-ctypes-pep3118/Doc/whatsnew/3.0.rst (original) +++ python/branches/py3k-ctypes-pep3118/Doc/whatsnew/3.0.rst Fri Jan 25 14:18:20 2008 @@ -154,6 +154,9 @@ * There is only one string type; its name is ``str`` but its behavior and implementation are more like ``unicode`` in 2.x. +* The ``basestring`` superclass has been removed. The ``2to3`` tool + replaces every occurence of ``basestring`` with ``str``. + * PEP 3137: There is a new type, ``bytes``, to represent binary data (and encoded text, which is treated as binary data until you decide to decode it). The ``str`` and ``bytes`` types cannot be mixed; you @@ -245,6 +248,8 @@ built-in integral type, named ``int``; but it behaves like the old ``long`` type, with the exception that the literal suffix ``L`` is neither supported by the parser nor produced by ``repr()`` anymore. + ``sys.maxint`` was also removed since the int type has no maximum + value anymore. * PEP 238: int division returns a float. Modified: python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_numbers.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_numbers.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_numbers.py Fri Jan 25 14:18:20 2008 @@ -105,15 +105,31 @@ def test_floats(self): # c_float and c_double can be created from # Python int, long and float + class FloatLike(object): + def __float__(self): + return 2.0 + f = FloatLike() for t in float_types: self.failUnlessEqual(t(2.0).value, 2.0) self.failUnlessEqual(t(2).value, 2.0) self.failUnlessEqual(t(2).value, 2.0) + self.failUnlessEqual(t(f).value, 2.0) def test_integers(self): - # integers cannot be constructed from floats + class FloatLike(object): + def __float__(self): + return 2.0 + f = FloatLike() + class IntLike(object): + def __int__(self): + return 2 + i = IntLike() + # integers cannot be constructed from floats, + # but from integer-like objects for t in signed_types + unsigned_types: self.assertRaises(TypeError, t, 3.14) + self.assertRaises(TypeError, t, f) + self.failUnlessEqual(t(i).value, 2) def test_sizes(self): for t in signed_types + unsigned_types + float_types + bool_types: Modified: python/branches/py3k-ctypes-pep3118/Lib/decimal.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/decimal.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/decimal.py Fri Jan 25 14:18:20 2008 @@ -1451,6 +1451,8 @@ else: return s*int(self._int[:self._exp] or '0') + __trunc__ = __int__ + def _fix_nan(self, context): """Decapitate the payload of a NaN to fit the context""" payload = self._int Modified: python/branches/py3k-ctypes-pep3118/Lib/pprint.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/pprint.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/pprint.py Fri Jan 25 14:18:20 2008 @@ -164,25 +164,31 @@ (issubclass(typ, set) and r is set.__repr__) or (issubclass(typ, frozenset) and r is frozenset.__repr__) ): + length = _len(object) if issubclass(typ, list): write('[') endchar = ']' elif issubclass(typ, set): + if not length: + write('set()') + return write('{') endchar = '}' object = sorted(object) indent += 4 elif issubclass(typ, frozenset): + if not length: + write('frozenset()') + return write('frozenset([') endchar = '])' object = sorted(object) - indent += 9 + indent += 10 else: write('(') endchar = ')' if self._indent_per_level > 1: write((self._indent_per_level - 1) * ' ') - length = _len(object) if length: context[objid] = 1 indent = indent + self._indent_per_level Modified: python/branches/py3k-ctypes-pep3118/Lib/rational.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/rational.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/rational.py Fri Jan 25 14:18:20 2008 @@ -13,7 +13,7 @@ RationalAbc = numbers.Rational -def _gcd(a, b): +def _gcd(a, b): # XXX This is a useful function. Consider making it public. """Calculate the Greatest Common Divisor. Unless b==0, the result will have the same sign as b (so that when @@ -39,6 +39,8 @@ >>> _binary_float_to_ratio(-.25) (-1, 4) """ + # XXX Consider moving this to to floatobject.c + # with a name like float.as_intger_ratio() if x == 0: return 0, 1 @@ -79,6 +81,10 @@ _RATIONAL_FORMAT = re.compile( r'^\s*(?P[-+]?)(?P\d+)(?:/(?P\d+))?\s*$') +# XXX Consider accepting decimal strings as input since they are exact. +# Rational("2.01") --> s="2.01" ; Rational.from_decimal(Decimal(s)) --> Rational(201, 100)" +# If you want to avoid going through the decimal module, just parse the string directly: +# s.partition('.') --> ('2', '.', '01') --> Rational(int('2'+'01'), 10**len('01')) --> Rational(201, 100) class Rational(RationalAbc): """This class implements rational numbers. @@ -93,7 +99,7 @@ """ - __slots__ = ('_numerator', '_denominator') + __slots__ = ('numerator', 'denominator') # We're immutable, so use __new__ not __init__ def __new__(cls, numerator=0, denominator=1): @@ -133,8 +139,8 @@ raise ZeroDivisionError('Rational(%s, 0)' % numerator) g = _gcd(numerator, denominator) - self._numerator = int(numerator // g) - self._denominator = int(denominator // g) + self.numerator = int(numerator // g) + self.denominator = int(denominator // g) return self @classmethod @@ -192,29 +198,22 @@ n, d = d, n return cf - @classmethod - def approximate_from_float(cls, f, max_denominator): - 'Best rational approximation to f with a denominator <= max_denominator' + def approximate(self, max_denominator): + 'Best rational approximation with a denominator <= max_denominator' # XXX First cut at algorithm # Still needs rounding rules as specified at # http://en.wikipedia.org/wiki/Continued_fraction - cf = cls.from_float(f).as_continued_fraction() + if self.denominator <= max_denominator: + return self + cf = self.as_continued_fraction() result = Rational(0) for i in range(1, len(cf)): - new = cls.from_continued_fraction(cf[:i]) + new = self.from_continued_fraction(cf[:i]) if new.denominator > max_denominator: break result = new return result - @property - def numerator(a): - return a._numerator - - @property - def denominator(a): - return a._denominator - def __repr__(self): """repr(self)""" return ('Rational(%r,%r)' % (self.numerator, self.denominator)) @@ -226,6 +225,16 @@ else: return '%s/%s' % (self.numerator, self.denominator) + """ XXX This section needs a lot more commentary + + * Explain the typical sequence of checks, calls, and fallbacks. + * Explain the subtle reasons why this logic was needed. + * It is not clear how common cases are handled (for example, how + does the ratio of two huge integers get converted to a float + without overflowing the long-->float conversion. + + """ + def _operator_fallbacks(monomorphic_operator, fallback_operator): """Generates forward and reverse operators given a purely-rational operator and a function from the operator module. @@ -299,18 +308,15 @@ """a // b""" return math.floor(a / b) - @classmethod - def _mod(cls, a, b): - div = a // b - return a - b * div - def __mod__(a, b): """a % b""" - return a._mod(a, b) + div = a // b + return a - b * div def __rmod__(b, a): """a % b""" - return b._mod(a, b) + div = a // b + return a - b * div def __pow__(a, b): """a ** b @@ -369,6 +375,8 @@ else: return a.numerator // a.denominator + __int__ = __trunc__ + def __floor__(a): """Will be math.floor(a) in 3.0.""" return a.numerator // a.denominator @@ -410,6 +418,7 @@ float must have the same hash as that float. """ + # XXX since this method is expensive, consider caching the result if self.denominator == 1: # Get integers right. return hash(self.numerator) @@ -481,3 +490,18 @@ def __bool__(a): """a != 0""" return a.numerator != 0 + + # support for pickling, copy, and deepcopy + + def __reduce__(self): + return (self.__class__, (str(self),)) + + def __copy__(self): + if type(self) == Rational: + return self # I'm immutable; therefore I am my own clone + return self.__class__(self.numerator, self.denominator) + + def __deepcopy__(self, memo): + if type(self) == Rational: + return self # My components are also immutable + return self.__class__(self.numerator, self.denominator) Deleted: /python/branches/py3k-ctypes-pep3118/Lib/test/crashers/loosing_dict_ref.py ============================================================================== --- /python/branches/py3k-ctypes-pep3118/Lib/test/crashers/loosing_dict_ref.py Fri Jan 25 14:18:20 2008 +++ (empty file) @@ -1,21 +0,0 @@ - -# http://python.org/sf/1303614 - -class Strange(object): - def __hash__(self): - return hash('hello') - - def __eq__(self, other): - x.__dict__ = {} # the old x.__dict__ is deallocated - return False - - -class X(object): - pass - -if __name__ == '__main__': - v = 123 - x = X() - x.__dict__ = {Strange(): 42, - 'hello': v+456} - x.hello # segfault: the above dict is accessed after it's deallocated Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_decimal.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_decimal.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_decimal.py Fri Jan 25 14:18:20 2008 @@ -1141,6 +1141,7 @@ checkSameDec("__floordiv__", True) checkSameDec("__hash__") checkSameDec("__int__") + checkSameDec("__trunc__") checkSameDec("__mod__", True) checkSameDec("__mul__", True) checkSameDec("__neg__") @@ -1204,6 +1205,16 @@ r = d.to_integral(ROUND_DOWN) self.assertEqual(Decimal(int(d)), r) + def test_trunc(self): + for x in range(-250, 250): + s = '%0.2f' % (x / 100.0) + # should work the same as for floats + self.assertEqual(int(Decimal(s)), int(float(s))) + # should work the same as to_integral in the ROUND_DOWN mode + d = Decimal(s) + r = d.to_integral(ROUND_DOWN) + self.assertEqual(Decimal(trunc(d)), r) + class ContextAPItests(unittest.TestCase): def test_pickle(self): Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_descr.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_descr.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_descr.py Fri Jan 25 14:18:20 2008 @@ -4248,6 +4248,29 @@ finally: builtins.__import__ = orig_import +def test_losing_dict_ref_segfault(): + # This used to segfault; + # derived from issue #1303614, test67.py + if verbose: + print("Testing losing dict ref segfault...") + + class Strange(object): + def __hash__(self): + return hash('hello') + + def __eq__(self, other): + x.__dict__ = {} # the old x.__dict__ is deallocated + return False + + class X(object): + pass + + v = 123 + x = X() + x.__dict__ = {Strange(): 42, 'hello': v+456} + x.hello + + def test_main(): weakref_segfault() # Must be first, somehow wrapper_segfault() # NB This one is slow @@ -4348,6 +4371,7 @@ test_weakref_in_del_segfault() test_borrowed_ref_3_segfault() test_borrowed_ref_4_segfault() + test_losing_dict_ref_segfault() if verbose: print("All OK") Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_grammar.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_grammar.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_grammar.py Fri Jan 25 14:18:20 2008 @@ -500,6 +500,15 @@ while 0: pass else: pass + # Issue1920: "while 0" is optimized away, + # ensure that the "else" clause is still present. + x = 0 + while 0: + x = 1 + else: + x = 2 + self.assertEquals(x, 2) + def testFor(self): # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] for i in 1, 2, 3: pass Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_pprint.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_pprint.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_pprint.py Fri Jan 25 14:18:20 2008 @@ -1,6 +1,7 @@ import pprint import test.test_support import unittest +import test.test_set # list, tuple and dict subclasses that do or don't overwrite __repr__ class list2(list): @@ -189,6 +190,197 @@ others.should.not.be: like.this}""" self.assertEqual(DottedPrettyPrinter().pformat(o), exp) + def test_set_reprs(self): + self.assertEqual(pprint.pformat(set()), 'set()') + self.assertEqual(pprint.pformat(set(range(3))), '{0, 1, 2}') + self.assertEqual(pprint.pformat(frozenset()), 'frozenset()') + self.assertEqual(pprint.pformat(frozenset(range(3))), 'frozenset({0, 1, 2})') + cube_repr_tgt = """\ +{frozenset(): frozenset({frozenset({2}), frozenset({0}), frozenset({1})}), + frozenset({0}): frozenset([frozenset(), + frozenset({0, 2}), + frozenset({0, 1})]), + frozenset({1}): frozenset([frozenset(), + frozenset({1, 2}), + frozenset({0, 1})]), + frozenset({2}): frozenset([frozenset(), + frozenset({1, 2}), + frozenset({0, 2})]), + frozenset({1, 2}): frozenset([frozenset({2}), + frozenset({1}), + frozenset({0, 1, 2})]), + frozenset({0, 2}): frozenset([frozenset({2}), + frozenset({0}), + frozenset({0, 1, 2})]), + frozenset({0, 1}): frozenset([frozenset({0}), + frozenset({1}), + frozenset({0, 1, 2})]), + frozenset({0, 1, 2}): frozenset([frozenset({1, 2}), + frozenset({0, 2}), + frozenset({0, 1})])}""" + cube = test.test_set.cube(3) + self.assertEqual(pprint.pformat(cube), cube_repr_tgt) + cubo_repr_tgt = """\ +{frozenset({frozenset({0, 2}), frozenset({0})}): frozenset([frozenset([frozenset([0, + 2]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([0]), + frozenset([0, + 1])]), + frozenset([frozenset(), + frozenset([0])]), + frozenset([frozenset([2]), + frozenset([0, + 2])])]), + frozenset({frozenset({0, 1}), frozenset({1})}): frozenset([frozenset([frozenset([0, + 1]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([0]), + frozenset([0, + 1])]), + frozenset([frozenset([1]), + frozenset([1, + 2])]), + frozenset([frozenset(), + frozenset([1])])]), + frozenset({frozenset({1, 2}), frozenset({1})}): frozenset([frozenset([frozenset([1, + 2]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([2]), + frozenset([1, + 2])]), + frozenset([frozenset(), + frozenset([1])]), + frozenset([frozenset([1]), + frozenset([0, + 1])])]), + frozenset({frozenset({1, 2}), frozenset({2})}): frozenset([frozenset([frozenset([1, + 2]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([1]), + frozenset([1, + 2])]), + frozenset([frozenset([2]), + frozenset([0, + 2])]), + frozenset([frozenset(), + frozenset([2])])]), + frozenset({frozenset(), frozenset({0})}): frozenset([frozenset([frozenset([0]), + frozenset([0, + 1])]), + frozenset([frozenset([0]), + frozenset([0, + 2])]), + frozenset([frozenset(), + frozenset([1])]), + frozenset([frozenset(), + frozenset([2])])]), + frozenset({frozenset(), frozenset({1})}): frozenset([frozenset([frozenset(), + frozenset([0])]), + frozenset([frozenset([1]), + frozenset([1, + 2])]), + frozenset([frozenset(), + frozenset([2])]), + frozenset([frozenset([1]), + frozenset([0, + 1])])]), + frozenset({frozenset({2}), frozenset()}): frozenset([frozenset([frozenset([2]), + frozenset([1, + 2])]), + frozenset([frozenset(), + frozenset([0])]), + frozenset([frozenset(), + frozenset([1])]), + frozenset([frozenset([2]), + frozenset([0, + 2])])]), + frozenset({frozenset({0, 1, 2}), frozenset({0, 1})}): frozenset([frozenset([frozenset([1, + 2]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([0, + 2]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([0]), + frozenset([0, + 1])]), + frozenset([frozenset([1]), + frozenset([0, + 1])])]), + frozenset({frozenset({0}), frozenset({0, 1})}): frozenset([frozenset([frozenset(), + frozenset([0])]), + frozenset([frozenset([0, + 1]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([0]), + frozenset([0, + 2])]), + frozenset([frozenset([1]), + frozenset([0, + 1])])]), + frozenset({frozenset({2}), frozenset({0, 2})}): frozenset([frozenset([frozenset([0, + 2]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([2]), + frozenset([1, + 2])]), + frozenset([frozenset([0]), + frozenset([0, + 2])]), + frozenset([frozenset(), + frozenset([2])])]), + frozenset({frozenset({0, 1, 2}), frozenset({0, 2})}): frozenset([frozenset([frozenset([1, + 2]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([0, + 1]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([0]), + frozenset([0, + 2])]), + frozenset([frozenset([2]), + frozenset([0, + 2])])]), + frozenset({frozenset({1, 2}), frozenset({0, 1, 2})}): frozenset([frozenset([frozenset([0, + 2]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([0, + 1]), + frozenset([0, + 1, + 2])]), + frozenset([frozenset([2]), + frozenset([1, + 2])]), + frozenset([frozenset([1]), + frozenset([1, + 2])])])}""" + + cubo = test.test_set.linegraph(cube) + self.assertEqual(pprint.pformat(cubo), cubo_repr_tgt) + class DottedPrettyPrinter(pprint.PrettyPrinter): Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_rational.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_rational.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_rational.py Fri Jan 25 14:18:20 2008 @@ -6,6 +6,8 @@ import operator import rational import unittest +from copy import copy, deepcopy +from cPickle import dumps, loads R = rational.Rational def _components(r): @@ -153,16 +155,17 @@ [-4, 1, 6, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 3, 3]) self.assertEqual(R(0).as_continued_fraction(), [0]) - def testApproximateFromFloat(self): - self.assertEqual(R.approximate_from_float(math.pi, 10000), R(355, 113)) - self.assertEqual(R.approximate_from_float(-math.pi, 10000), R(-355, 113)) - self.assertEqual(R.approximate_from_float(0.0, 10000), R(0)) + def testApproximateFrom(self): + self.assertEqual(R.from_float(math.pi).approximate(10000), R(355, 113)) + self.assertEqual(R.from_float(-math.pi).approximate(10000), R(-355, 113)) + self.assertEqual(R.from_float(0.0).approximate(10000), R(0)) def testConversions(self): self.assertTypedEquals(-1, trunc(R(-11, 10))) self.assertTypedEquals(-2, math.floor(R(-11, 10))) self.assertTypedEquals(-1, math.ceil(R(-11, 10))) self.assertTypedEquals(-1, math.ceil(R(-10, 10))) + self.assertTypedEquals(-1, int(R(-11, 10))) self.assertTypedEquals(0, round(R(-1, 10))) self.assertTypedEquals(0, round(R(-5, 10))) @@ -360,6 +363,12 @@ s += num / fact * sign self.assertAlmostEquals(math.cos(1), s) + def test_copy_deepcopy_pickle(self): + r = R(13, 7) + self.assertEqual(r, loads(dumps(r))) + self.assertEqual(id(r), id(copy(r))) + self.assertEqual(id(r), id(deepcopy(r))) + def test_main(): run_unittest(RationalTest) Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_set.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_set.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_set.py Fri Jan 25 14:18:20 2008 @@ -8,6 +8,7 @@ from random import randrange, shuffle import sys import warnings +import collections class PassThru(Exception): pass @@ -1605,6 +1606,110 @@ self.assertRaises(TypeError, getattr(set('january'), methname), N(data)) self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data)) +# Application tests (based on David Eppstein's graph recipes ==================================== + +def powerset(U): + """Generates all subsets of a set or sequence U.""" + U = iter(U) + try: + x = frozenset([next(U)]) + for S in powerset(U): + yield S + yield S | x + except StopIteration: + yield frozenset() + +def cube(n): + """Graph of n-dimensional hypercube.""" + singletons = [frozenset([x]) for x in range(n)] + return dict([(x, frozenset([x^s for s in singletons])) + for x in powerset(range(n))]) + +def linegraph(G): + """Graph, the vertices of which are edges of G, + with two vertices being adjacent iff the corresponding + edges share a vertex.""" + L = {} + for x in G: + for y in G[x]: + nx = [frozenset([x,z]) for z in G[x] if z != y] + ny = [frozenset([y,z]) for z in G[y] if z != x] + L[frozenset([x,y])] = frozenset(nx+ny) + return L + +def faces(G): + 'Return a set of faces in G. Where a face is a set of vertices on that face' + # currently limited to triangles,squares, and pentagons + f = set() + for v1, edges in G.items(): + for v2 in edges: + for v3 in G[v2]: + if v1 == v3: + continue + if v1 in G[v3]: + f.add(frozenset([v1, v2, v3])) + else: + for v4 in G[v3]: + if v4 == v2: + continue + if v1 in G[v4]: + f.add(frozenset([v1, v2, v3, v4])) + else: + for v5 in G[v4]: + if v5 == v3 or v5 == v2: + continue + if v1 in G[v5]: + f.add(frozenset([v1, v2, v3, v4, v5])) + return f + + +class TestGraphs(unittest.TestCase): + + def test_cube(self): + + g = cube(3) # vert --> {v1, v2, v3} + vertices1 = set(g) + self.assertEqual(len(vertices1), 8) # eight vertices + for edge in g.values(): + self.assertEqual(len(edge), 3) # each vertex connects to three edges + vertices2 = set(v for edges in g.values() for v in edges) + self.assertEqual(vertices1, vertices2) # edge vertices in original set + + cubefaces = faces(g) + self.assertEqual(len(cubefaces), 6) # six faces + for face in cubefaces: + self.assertEqual(len(face), 4) # each face is a square + + def test_cuboctahedron(self): + + # http://en.wikipedia.org/wiki/Cuboctahedron + # 8 triangular faces and 6 square faces + # 12 indentical vertices each connecting a triangle and square + + g = cube(3) + cuboctahedron = linegraph(g) # V( --> {V1, V2, V3, V4} + self.assertEqual(len(cuboctahedron), 12)# twelve vertices + + vertices = set(cuboctahedron) + for edges in cuboctahedron.values(): + self.assertEqual(len(edges), 4) # each vertex connects to four other vertices + othervertices = set(edge for edges in cuboctahedron.values() for edge in edges) + self.assertEqual(vertices, othervertices) # edge vertices in original set + + cubofaces = faces(cuboctahedron) + facesizes = collections.defaultdict(int) + for face in cubofaces: + facesizes[len(face)] += 1 + self.assertEqual(facesizes[3], 8) # eight triangular faces + self.assertEqual(facesizes[4], 6) # six square faces + + for vertex in cuboctahedron: + edge = vertex # Cuboctahedron vertices are edges in Cube + self.assertEqual(len(edge), 2) # Two cube vertices define an edge + for cubevert in edge: + self.assert_(cubevert in g) + + #============================================================================== def test_main(verbose=None): @@ -1644,6 +1749,7 @@ TestCopyingNested, TestIdentities, TestVariousIteratorArgs, + TestGraphs, ) test_support.run_unittest(*test_classes) Modified: python/branches/py3k-ctypes-pep3118/Lib/test/test_urllib2net.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/test/test_urllib2net.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/test/test_urllib2net.py Fri Jan 25 14:18:20 2008 @@ -10,6 +10,20 @@ import os import mimetools + +def _urlopen_with_retry(host, *args, **kwargs): + # Connecting to remote hosts is flaky. Make it more robust + # by retrying the connection several times. + for i in range(3): + try: + return urllib2.urlopen(host, *args, **kwargs) + except urllib2.URLError as last_exc: + continue + except: + raise + raise last_exc + + class URLTimeoutTest(unittest.TestCase): TIMEOUT = 10.0 @@ -21,7 +35,7 @@ socket.setdefaulttimeout(None) def testURLread(self): - f = urllib2.urlopen("http://www.python.org/") + f = _urlopen_with_retry("http://www.python.org/") x = f.read() @@ -42,7 +56,7 @@ # # # failure # try: -# urllib2.urlopen(test_url) +# _urlopen_with_retry(test_url) # except urllib2.HTTPError, exc: # self.assertEqual(exc.code, 401) # else: @@ -54,7 +68,7 @@ # test_user, test_password) # opener = urllib2.build_opener(auth_handler) # f = opener.open('http://localhost/') -# response = urllib2.urlopen("http://www.python.org/") +# response = _urlopen_with_retry("http://www.python.org/") # # # The 'userinfo' URL component is deprecated by RFC 3986 for security # # reasons, let's not implement it! (it's already implemented for proxy @@ -73,7 +87,7 @@ # underlying socket # delve deep into response to fetch socket._socketobject - response = urllib2.urlopen("http://www.python.org/") + response = _urlopen_with_retry("http://www.python.org/") abused_fileobject = response.fp httpresponse = abused_fileobject.raw self.assert_(httpresponse.__class__ is httplib.HTTPResponse) @@ -100,7 +114,7 @@ def test_basic(self): # Simple test expected to pass. - open_url = urllib2.urlopen("http://www.python.org/") + open_url = _urlopen_with_retry("http://www.python.org/") for attr in ("read", "close", "info", "geturl"): self.assert_(hasattr(open_url, attr), "object returned from " "urlopen lacks the %s attribute" % attr) @@ -111,7 +125,7 @@ def test_info(self): # Test 'info'. - open_url = urllib2.urlopen("http://www.python.org/") + open_url = _urlopen_with_retry("http://www.python.org/") try: info_obj = open_url.info() finally: @@ -124,7 +138,7 @@ def test_geturl(self): # Make sure same URL as opened is returned by geturl. URL = "http://www.python.org/" - open_url = urllib2.urlopen(URL) + open_url = _urlopen_with_retry(URL) try: gotten_url = open_url.geturl() finally: @@ -155,7 +169,7 @@ def test_range (self): req = urllib2.Request("http://www.python.org", headers={'Range': 'bytes=20-39'}) - result = urllib2.urlopen(req) + result = _urlopen_with_retry(req) data = result.read() self.assertEqual(len(data), 20) @@ -182,7 +196,7 @@ 'file:'+sanepathname2url(os.path.abspath(TESTFN)), ('file:///nonsensename/etc/passwd', None, urllib2.URLError), ] - self._test_urls(urls, self._extra_handlers()) + self._test_urls(urls, self._extra_handlers(), urllib2.urlopen) finally: os.remove(TESTFN) @@ -224,7 +238,7 @@ ## self._test_urls(urls, self._extra_handlers()+[bauth, dauth]) - def _test_urls(self, urls, handlers): + def _test_urls(self, urls, handlers, urlopen=_urlopen_with_retry): import socket import time import logging @@ -239,7 +253,7 @@ req = expected_err = None debug(url) try: - f = urllib2.urlopen(url, req) + f = urlopen(url, req) except EnvironmentError as err: debug(err) if expected_err: @@ -265,47 +279,47 @@ class TimeoutTest(unittest.TestCase): def test_http_basic(self): - u = urllib2.urlopen("http://www.python.org") + u = _urlopen_with_retry("http://www.python.org") self.assertTrue(u.fp.raw.fp._sock.gettimeout() is None) def test_http_NoneWithdefault(self): prev = socket.getdefaulttimeout() socket.setdefaulttimeout(60) try: - u = urllib2.urlopen("http://www.python.org", timeout=None) + u = _urlopen_with_retry("http://www.python.org", timeout=None) self.assertTrue(u.fp.raw.fp._sock.gettimeout(), 60) finally: socket.setdefaulttimeout(prev) def test_http_Value(self): - u = urllib2.urlopen("http://www.python.org", timeout=120) + u = _urlopen_with_retry("http://www.python.org", timeout=120) self.assertEqual(u.fp.raw.fp._sock.gettimeout(), 120) def test_http_NoneNodefault(self): - u = urllib2.urlopen("http://www.python.org", timeout=None) + u = _urlopen_with_retry("http://www.python.org", timeout=None) self.assertTrue(u.fp.raw.fp._sock.gettimeout() is None) + FTP_HOST = "ftp://ftp.mirror.nl/pub/mirror/gnu/" + def test_ftp_basic(self): - u = urllib2.urlopen("ftp://ftp.mirror.nl/pub/mirror/gnu/") + u = _urlopen_with_retry(self.FTP_HOST) self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None) def test_ftp_NoneWithdefault(self): prev = socket.getdefaulttimeout() socket.setdefaulttimeout(60) try: - u = urllib2.urlopen("ftp://ftp.mirror.nl/pub/mirror/gnu/", - timeout=None) - self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60) + u = _urlopen_with_retry(self.FTP_HOST, timeout=None) + self.assertEqual(u.fp.fp._sock.gettimeout(), 60) finally: socket.setdefaulttimeout(prev) def test_ftp_NoneNodefault(self): - u = urllib2.urlopen("ftp://ftp.mirror.nl/pub/mirror/gnu/", - timeout=None) - self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None) + u = _urlopen_with_retry(self.FTP_HOST, timeout=None) + self.assertTrue(u.fp.fp._sock.gettimeout() is None) def test_ftp_Value(self): - u = urllib2.urlopen("ftp://ftp.mirror.nl/pub/mirror/gnu/", timeout=60) + u = _urlopen_with_retry(self.FTP_HOST, timeout=60) self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60) Modified: python/branches/py3k-ctypes-pep3118/Lib/threading.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/threading.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/threading.py Fri Jan 25 14:18:20 2008 @@ -346,18 +346,27 @@ return self._flag def set(self): - with self._cond: + self._cond.acquire() + try: self._flag = True self._cond.notifyAll() + finally: + self._cond.release() def clear(self): - with self._cond: + self._cond.acquire() + try: self._flag = False + finally: + self._cond.release() def wait(self, timeout=None): - with self._cond: + self._cond.acquire() + try: if not self._flag: self._cond.wait(timeout) + finally: + self._cond.release() # Helper to generate new thread names _counter = 0 @@ -524,9 +533,10 @@ pass def _stop(self): - with self._block: - self._stopped = True - self._block.notifyAll() + self._block.acquire() + self._stopped = True + self._block.notifyAll() + self._block.release() def _delete(self): "Remove current thread from the dict of currently running threads." @@ -552,12 +562,15 @@ # since it isn't if dummy_threading is *not* being used then don't # hide the exception. - with _active_limbo_lock: + _active_limbo_lock.acquire() + try: try: del _active[_get_ident()] except KeyError: if 'dummy_threading' not in _sys.modules: raise + finally: + _active_limbo_lock.release() def join(self, timeout=None): if not self._initialized: @@ -570,7 +583,9 @@ if __debug__: if not self._stopped: self._note("%s.join(): waiting until thread stops", self) - with self._block: + + self._block.acquire() + try: if timeout is None: while not self._stopped: self._block.wait() @@ -588,6 +603,8 @@ else: if __debug__: self._note("%s.join(): thread stopped", self) + finally: + self._block.release() def getName(self): assert self._initialized, "Thread.__init__() not called" Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c Fri Jan 25 14:18:20 2008 @@ -122,12 +122,134 @@ PyObject *PyExc_ArgError; static PyTypeObject Simple_Type; -PyObject *array_types_cache; char *conversion_mode_encoding = NULL; char *conversion_mode_errors = NULL; +/****************************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *key; + PyObject *dict; +} DictRemoverObject; + +static void +_DictRemover_dealloc(PyObject *_self) +{ + DictRemoverObject *self = (DictRemoverObject *)_self; + Py_XDECREF(self->key); + Py_XDECREF(self->dict); + Py_TYPE(self)->tp_free(_self); +} + +static PyObject * +_DictRemover_call(PyObject *_self, PyObject *args, PyObject *kw) +{ + DictRemoverObject *self = (DictRemoverObject *)_self; + if (self->key && self->dict) { + if (-1 == PyDict_DelItem(self->dict, self->key)) + /* XXX Error context */ + PyErr_WriteUnraisable(Py_None); + Py_DECREF(self->key); + self->key = NULL; + Py_DECREF(self->dict); + self->dict = NULL; + } + Py_INCREF(Py_None); + return Py_None; +} + +static PyTypeObject DictRemover_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ctypes.DictRemover", /* tp_name */ + sizeof(DictRemoverObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + _DictRemover_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + _DictRemover_call, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ +/* XXX should participate in GC? */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + "deletes a key from a dictionary", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + 0, /* tp_free */ +}; + +int +PyDict_SetItemProxy(PyObject *dict, PyObject *key, PyObject *item) +{ + PyObject *obj; + DictRemoverObject *remover; + PyObject *proxy; + int result; + + obj = PyObject_CallObject((PyObject *)&DictRemover_Type, NULL); + if (obj == NULL) + return -1; + + remover = (DictRemoverObject *)obj; + assert(remover->key == NULL); + assert(remover->dict == NULL); + Py_INCREF(key); + remover->key = key; + Py_INCREF(dict); + remover->dict = dict; + + proxy = PyWeakref_NewProxy(item, obj); + Py_DECREF(obj); + if (proxy == NULL) + return -1; + + result = PyDict_SetItem(dict, key, proxy); + Py_DECREF(proxy); + return result; +} + +PyObject * +PyDict_GetItemProxy(PyObject *dict, PyObject *key) +{ + PyObject *result; + PyObject *item = PyDict_GetItem(dict, key); + + if (item == NULL) + return NULL; + if (!PyWeakref_CheckProxy(item)) + return item; + result = PyWeakref_GET_OBJECT(item); + if (result == Py_None) + return NULL; + return result; +} + /******************************************************************/ /* Allocate a memory block for a pep3118 format string, copy prefix (if @@ -2482,7 +2604,7 @@ only it's object list. So we create a tuple, containing b_objects list PLUS the array itself, and return that! */ - return Py_BuildValue("(OO)", keep, value); + return PyTuple_Pack(2, keep, value); } PyErr_Format(PyExc_TypeError, "incompatible types, %s instance instead of %s instance", @@ -4094,19 +4216,30 @@ PyObject * CreateArrayType(PyObject *itemtype, Py_ssize_t length) { + static PyObject *cache; PyObject *key; PyObject *result; char name[256]; + PyObject *len; - key = Py_BuildValue("(On)", itemtype, length); + if (cache == NULL) { + cache = PyDict_New(); + if (cache == NULL) + return NULL; + } + len = PyLong_FromSsize_t(length); + if (len == NULL) + return NULL; + key = PyTuple_Pack(2, itemtype, len); + Py_DECREF(len); if (!key) return NULL; - result = PyObject_GetItem(array_types_cache, key); + result = PyDict_GetItemProxy(cache, key); if (result) { + Py_INCREF(result); Py_DECREF(key); return result; - } else - PyErr_Clear(); + } if (!PyType_Check(itemtype)) { PyErr_SetString(PyExc_TypeError, @@ -4130,9 +4263,11 @@ "_type_", itemtype ); - if (!result) + if (result == NULL) { + Py_DECREF(key); return NULL; - if (-1 == PyObject_SetItem(array_types_cache, key, result)) { + } + if (-1 == PyDict_SetItemProxy(cache, key, result)) { Py_DECREF(key); Py_DECREF(result); return NULL; @@ -4929,7 +5064,6 @@ init_ctypes(void) { PyObject *m; - PyObject *weakref; /* Note: ob_type is the metatype (the 'type'), defaults to PyType_Type, @@ -4942,16 +5076,6 @@ if (!m) return; - weakref = PyImport_ImportModule("weakref"); - if (weakref == NULL) - return; - array_types_cache = PyObject_CallMethod(weakref, - "WeakValueDictionary", - NULL); - if (array_types_cache == NULL) - return; - Py_DECREF(weakref); - if (PyType_Ready(&PyCArg_Type) < 0) return; @@ -5047,6 +5171,10 @@ * Other stuff */ + DictRemover_Type.tp_new = PyType_GenericNew; + if (PyType_Ready(&DictRemover_Type) < 0) + return; + #ifdef MS_WIN32 if (create_comerror() < 0) return; Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/cfield.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_ctypes/cfield.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_ctypes/cfield.c Fri Jan 25 14:18:20 2008 @@ -334,10 +334,10 @@ get_long(PyObject *v, long *p) { long x; - if (!PyLong_Check(v)) { - PyErr_Format(PyExc_TypeError, - "int expected instead of %s instance", - v->ob_type->tp_name); + + if (PyFloat_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "int expected instead of float"); return -1; } x = PyLong_AsUnsignedLongMask(v); @@ -353,10 +353,10 @@ get_ulong(PyObject *v, unsigned long *p) { unsigned long x; - if (!PyLong_Check(v)) { - PyErr_Format(PyExc_TypeError, - "int expected instead of %s instance", - v->ob_type->tp_name); + + if (PyFloat_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "int expected instead of float"); return -1; } x = PyLong_AsUnsignedLongMask(v); @@ -374,11 +374,10 @@ get_longlong(PyObject *v, PY_LONG_LONG *p) { PY_LONG_LONG x; - if (!PyLong_Check(v)) { - PyErr_Format(PyExc_TypeError, - "int expected instead of %s instance", - v->ob_type->tp_name); - return -1; + if (PyFloat_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "int expected instead of float"); + return -1; } x = PyLong_AsUnsignedLongLongMask(v); if (x == -1 && PyErr_Occurred()) @@ -393,12 +392,11 @@ get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p) { unsigned PY_LONG_LONG x; - if (!PyLong_Check(v)) { - PyErr_Format(PyExc_TypeError, - "int expected instead of %s instance", - v->ob_type->tp_name); - return -1; - } + if (PyFloat_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "int expected instead of float"); + return -1; + } x = PyLong_AsUnsignedLongLongMask(v); if (x == -1 && PyErr_Occurred()) return -1; Modified: python/branches/py3k-ctypes-pep3118/Modules/mathmodule.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/mathmodule.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/mathmodule.c Fri Jan 25 14:18:20 2008 @@ -12,6 +12,11 @@ #endif /* __STDC__ */ #endif /* _MSC_VER */ +#ifdef _OSF_SOURCE +/* OSF1 5.1 doesn't make this available with XOPEN_SOURCE_EXTENDED defined */ +extern double copysign(double, double); +#endif + /* Call is_error when errno != 0, and where x is the result libm * returned. is_error will usually set up an exception and return * true (1), but may return false (0) without setting up an exception. Modified: python/branches/py3k-ctypes-pep3118/Objects/floatobject.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Objects/floatobject.c (original) +++ python/branches/py3k-ctypes-pep3118/Objects/floatobject.c Fri Jan 25 14:18:20 2008 @@ -17,6 +17,11 @@ extern double pow(double, double); #endif +#ifdef _OSF_SOURCE +/* OSF1 5.1 doesn't make this available with XOPEN_SOURCE_EXTENDED defined */ +extern int finite(double); +#endif + /* Special free list -- see comments for same code in intobject.c. */ #define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */ #define BHEAD_SIZE 8 /* Enough for a 64-bit pointer */ Modified: python/branches/py3k-ctypes-pep3118/Objects/object.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Objects/object.c (original) +++ python/branches/py3k-ctypes-pep3118/Objects/object.c Fri Jan 25 14:18:20 2008 @@ -1004,12 +1004,15 @@ dictptr = (PyObject **) ((char *)obj + dictoffset); dict = *dictptr; if (dict != NULL) { + Py_INCREF(dict); res = PyDict_GetItem(dict, name); if (res != NULL) { Py_INCREF(res); Py_XDECREF(descr); + Py_DECREF(dict); goto done; } + Py_DECREF(dict); } } @@ -1076,12 +1079,14 @@ *dictptr = dict; } if (dict != NULL) { + Py_INCREF(dict); if (value == NULL) res = PyDict_DelItem(dict, name); else res = PyDict_SetItem(dict, name, value); if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) PyErr_SetObject(PyExc_AttributeError, name); + Py_DECREF(dict); goto done; } } Modified: python/branches/py3k-ctypes-pep3118/Python/compile.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Python/compile.c (original) +++ python/branches/py3k-ctypes-pep3118/Python/compile.c Fri Jan 25 14:18:20 2008 @@ -1737,8 +1737,11 @@ basicblock *loop, *orelse, *end, *anchor = NULL; int constant = expr_constant(s->v.While.test); - if (constant == 0) + if (constant == 0) { + if (s->v.While.orelse) + VISIT_SEQ(c, stmt, s->v.While.orelse); return 1; + } loop = compiler_new_block(c); end = compiler_new_block(c); if (constant == -1) { From python-3000-checkins at python.org Fri Jan 25 17:58:31 2008 From: python-3000-checkins at python.org (thomas.heller) Date: Fri, 25 Jan 2008 17:58:31 +0100 (CET) Subject: [Python-3000-checkins] r60288 - python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c Message-ID: <20080125165831.433B51E402B@bag.python.org> Author: thomas.heller Date: Fri Jan 25 17:58:30 2008 New Revision: 60288 Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c Log: All ctypes types now use the same CData_GetBuffer function. Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c Fri Jan 25 17:58:30 2008 @@ -2318,7 +2318,32 @@ static int CData_GetBuffer(PyObject *_self, Py_buffer *view, int flags) { CDataObject *self = (CDataObject *)_self; - return PyBuffer_FillInfo(view, self->b_ptr, self->b_size, 0, flags); + StgDictObject *dict = PyObject_stgdict(_self); + + if (view == NULL) return 0; + if (((flags & PyBUF_LOCK) == PyBUF_LOCK)) { + PyErr_SetString(PyExc_BufferError, + "Cannot lock this object."); + return -1; + } + + view->buf = self->b_ptr; + view->len = self->b_size; + view->readonly = 0; + view->itemsize = self->b_size; +#if 1 + /* XXX fix later */ + /* use default format character if not set */ + view->format = dict->format ? dict->format : "B"; +#else + view->format = dict->format; +#endif + view->ndim = dict->ndim; + view->shape = dict->shape; + view->strides = NULL; + view->suboffsets = NULL; + view->internal = NULL; + return 0; } static PyBufferProcs CData_as_buffer = { @@ -4403,42 +4428,6 @@ return result; } -static int Simple_GetBuffer(PyObject *_self, Py_buffer *view, int flags) -{ - CDataObject *self = (CDataObject *)_self; - StgDictObject *dict = PyObject_stgdict(_self); - - if (view == NULL) return 0; - if (((flags & PyBUF_LOCK) == PyBUF_LOCK)) { - PyErr_SetString(PyExc_BufferError, - "Cannot lock this object."); - return -1; - } - - view->buf = self->b_ptr; - view->len = self->b_size; - view->readonly = 0; - view->itemsize = self->b_size; -#if 1 - /* XXX fix later */ - /* use default format character if not set */ - view->format = dict->format ? dict->format : "B"; -#else - view->format = dict->format; -#endif - view->ndim = 0; - view->shape = NULL; - view->strides = NULL; - view->suboffsets = NULL; - view->internal = NULL; - return 0; -} - -static PyBufferProcs Simple_as_buffer = { - Simple_GetBuffer, - NULL, -}; - static PyTypeObject Simple_Type = { PyVarObject_HEAD_INIT(NULL, 0) "_ctypes._SimpleCData", @@ -4458,7 +4447,7 @@ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ - &Simple_as_buffer, /* tp_as_buffer */ + &CData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ "XXX to be provided", /* tp_doc */ (traverseproc)CData_traverse, /* tp_traverse */ From python-3000-checkins at python.org Fri Jan 25 19:59:45 2008 From: python-3000-checkins at python.org (thomas.heller) Date: Fri, 25 Jan 2008 19:59:45 +0100 (CET) Subject: [Python-3000-checkins] r60289 - python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c python/branches/py3k-ctypes-pep3118/Modules/_ctypes/ctypes.h python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c Message-ID: <20080125185945.E9E0D1E400E@bag.python.org> Author: thomas.heller Date: Fri Jan 25 19:59:45 2008 New Revision: 60289 Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c python/branches/py3k-ctypes-pep3118/Modules/_ctypes/ctypes.h python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c Log: Fix format string for structures, and itemsize for arrays. Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c Fri Jan 25 19:59:45 2008 @@ -291,14 +291,6 @@ return result; } -char * -replace_format_string(const char *prefix, char *suffix) -{ - char *result = alloc_format_string(prefix, suffix); - PyMem_Free(suffix); - return result; -} - /* StructType_Type - a meta type/class. Creating a new class using this one as __metaclass__ will call the contructor StructUnionType_new. It replaces the @@ -2319,6 +2311,7 @@ { CDataObject *self = (CDataObject *)_self; StgDictObject *dict = PyObject_stgdict(_self); + Py_ssize_t i; if (view == NULL) return 0; if (((flags & PyBUF_LOCK) == PyBUF_LOCK)) { @@ -2330,7 +2323,6 @@ view->buf = self->b_ptr; view->len = self->b_size; view->readonly = 0; - view->itemsize = self->b_size; #if 1 /* XXX fix later */ /* use default format character if not set */ @@ -2340,6 +2332,10 @@ #endif view->ndim = dict->ndim; view->shape = dict->shape; + view->itemsize = self->b_size; + for (i = 0; i < view->ndim; ++i) { + view->itemsize /= dict->shape[i]; + } view->strides = NULL; view->suboffsets = NULL; view->internal = NULL; @@ -4824,7 +4820,7 @@ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ - &Simple_as_buffer, /* tp_as_buffer */ + &CData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ "XXX to be provided", /* tp_doc */ (traverseproc)CData_traverse, /* tp_traverse */ Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/ctypes.h ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_ctypes/ctypes.h (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_ctypes/ctypes.h Fri Jan 25 19:59:45 2008 @@ -344,7 +344,6 @@ extern PyObject *CData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr); extern char *alloc_format_string(const char *prefix, const char *suffix); -extern char *replace_format_string(const char *prefix, char *suffix); /* XXX better name needed! */ extern int IsSimpleSubType(PyObject *obj); Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c Fri Jan 25 19:59:45 2008 @@ -408,9 +408,12 @@ ffi_ofs = 0; } - stgdict->format = alloc_format_string(NULL, "}"); - if (stgdict->format == NULL) - return -1; + if (isStruct) { + stgdict->format = alloc_format_string(NULL, "T{"); + } else { + /* PEP3118 doesn't support unions. Invent our own character... */ + stgdict->format = alloc_format_string(NULL, "#{"); + } #define realdict ((PyObject *)&stgdict->dict) for (i = 0; i < len; ++i) { @@ -471,13 +474,17 @@ } else bitsize = 0; { - int len = PyUnicode_GetSize(name); - char *buf = alloca(len); - sprintf(buf, ":%s:", PyUnicode_AsString(name)); -/* XXX FIXME */ -/* assert(dict->format); */ - strcat(buf, dict->format ? dict->format : "XXX"); - stgdict->format = replace_format_string(buf, stgdict->format); + char *fieldfmt = dict->format ? dict->format : "XXX"; + char *fieldname = PyUnicode_AsString(name); + char *ptr; + Py_ssize_t len = strlen(fieldname) + strlen(fieldfmt); + char *buf = alloca(len + 2 + 1); + sprintf(buf, "%s:%s:", fieldfmt, fieldname); + + ptr = stgdict->format; + stgdict->format = alloc_format_string(stgdict->format, buf); + PyMem_Free(ptr); + if (stgdict->format == NULL) { Py_DECREF(pair); return -1; @@ -514,12 +521,7 @@ } #undef realdict - if (isStruct) { - stgdict->format = replace_format_string("T{", stgdict->format); - } else { - /* PEP3118 doesn't support unions. Invent our own character... */ - stgdict->format = replace_format_string("#{", stgdict->format); - } + stgdict->format = alloc_format_string(stgdict->format, "}"); if (stgdict->format == NULL) return -1; From python-3000-checkins at python.org Fri Jan 25 20:09:04 2008 From: python-3000-checkins at python.org (thomas.heller) Date: Fri, 25 Jan 2008 20:09:04 +0100 (CET) Subject: [Python-3000-checkins] r60290 - python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c Message-ID: <20080125190904.1AFEE1E4025@bag.python.org> Author: thomas.heller Date: Fri Jan 25 20:09:03 2008 New Revision: 60290 Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c Log: Implement to format string for function pointers. Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c Fri Jan 25 20:09:03 2008 @@ -2096,6 +2096,13 @@ return NULL; stgdict->paramfunc = CFuncPtrType_paramfunc; + /* We do NOT expose the function signature in the format string. It + is impossible, generally, because the only requirement for the + argtypes items is that they have a .from_param method - we do not + know the types of the arguments (although, in practice, most + argtypes would be a ctypes type). + */ + stgdict->format = alloc_format_string(NULL, "X{}"); /* create the new instance (which is a class, since we are a metatype!) */ From python-3000-checkins at python.org Fri Jan 25 20:32:20 2008 From: python-3000-checkins at python.org (thomas.heller) Date: Fri, 25 Jan 2008 20:32:20 +0100 (CET) Subject: [Python-3000-checkins] r60292 - python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c Message-ID: <20080125193220.850CC1E400E@bag.python.org> Author: thomas.heller Date: Fri Jan 25 20:32:20 2008 New Revision: 60292 Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c Log: Only structures with native packing implement the pep. Unions, or packed structures do not. Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c Fri Jan 25 20:32:20 2008 @@ -408,11 +408,13 @@ ffi_ofs = 0; } - if (isStruct) { + if (isStruct && !isPacked) { stgdict->format = alloc_format_string(NULL, "T{"); } else { - /* PEP3118 doesn't support unions. Invent our own character... */ - stgdict->format = alloc_format_string(NULL, "#{"); + /* PEP3118 doesn't support union, or packed structures (well, + only standard packing, but we dont support the pep for + that). Use 'B' for bytes. */ + stgdict->format = alloc_format_string(NULL, "B"); } #define realdict ((PyObject *)&stgdict->dict) @@ -473,12 +475,13 @@ } } else bitsize = 0; - { + if (isStruct && !isPacked) { char *fieldfmt = dict->format ? dict->format : "XXX"; char *fieldname = PyUnicode_AsString(name); char *ptr; Py_ssize_t len = strlen(fieldname) + strlen(fieldfmt); char *buf = alloca(len + 2 + 1); + sprintf(buf, "%s:%s:", fieldfmt, fieldname); ptr = stgdict->format; @@ -521,9 +524,11 @@ } #undef realdict - stgdict->format = alloc_format_string(stgdict->format, "}"); - if (stgdict->format == NULL) - return -1; + if (isStruct && !isPacked) { + stgdict->format = alloc_format_string(stgdict->format, "}"); + if (stgdict->format == NULL) + return -1; + } if (!isStruct) size = union_size; From python-3000-checkins at python.org Fri Jan 25 20:34:31 2008 From: python-3000-checkins at python.org (thomas.heller) Date: Fri, 25 Jan 2008 20:34:31 +0100 (CET) Subject: [Python-3000-checkins] r60293 - python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py Message-ID: <20080125193431.903511E400E@bag.python.org> Author: thomas.heller Date: Fri Jan 25 20:34:31 2008 New Revision: 60293 Modified: python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py Log: Update the test. Modified: python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py Fri Jan 25 20:34:31 2008 @@ -1,69 +1,112 @@ import unittest from ctypes import * -import struct, sys +import re, struct, sys if sys.byteorder == "little": ENDIAN = "<" else: ENDIAN = ">" -simple_types = [ - ("b", c_byte), - ("B", c_ubyte), - ("h", c_short), - ("H", c_ushort), -# c_int and c_uint may be aliases to c_long -## ("i", c_int), -## ("I", c_uint), - ("l", c_long), - ("L", c_ulong), - ("q", c_longlong), - ("Q", c_ulonglong), - ("f", c_float), - ("d", c_double), -# c_longdouble may be an alias to c_double -## ("g", c_longdouble), - ("t", c_bool), -# struct doesn't support this (yet) -## ("O", py_object), -] +def normalize(format): + # Remove current endian specifier and white space from a format + # string + format = format.replace(ENDIAN, "") + format = format.replace("=", "") + return re.sub(r"\s", "", format) class Test(unittest.TestCase): - def test_simpletypes(self): - # simple types in native byte order - for fmt, typ in simple_types: - v = memoryview(typ()) - - # check the PEP3118 format string - self.failUnlessEqual(v.format, ENDIAN + fmt) - - # shape and strides are None for integral types - self.failUnlessEqual((v.shape, v.strides), - (None, None)) - - # size and itemsize must be what struct.calcsize reports - struct_size = struct.calcsize(fmt) - self.failUnlessEqual((v.size, v.itemsize), - (struct_size, struct_size)) - - def test_pointertypes(self): - for fmt, typ in simple_types: - v = memoryview(POINTER(typ)()) - - # check the PEP3118 format string - self.failUnlessEqual(v.format, "&" + ENDIAN + fmt) - - # shape and strides are None for integral types - self.failUnlessEqual((v.shape, v.strides), - (None, None)) - - # size and itemsize must be what struct.calcsize reports - # for pointers - struct_size = struct.calcsize("P") - self.failUnlessEqual((v.size, v.itemsize), - (struct_size, struct_size)) + def test_types(self): + for tp, fmt, shape, itemtp in types: + ob = tp() + v = memoryview(ob) + try: + self.failUnlessEqual(normalize(v.format), fmt) + self.failUnlessEqual(v.size, sizeof(ob)) + self.failUnlessEqual(v.itemsize, sizeof(itemtp)) + self.failUnlessEqual(v.shape, shape) + self.failUnlessEqual(v.strides, None) + if v.shape: + n = 1 + for dim in v.shape: + n = n * dim + self.failUnlessEqual(v.itemsize * n, v.size) + except: + # so that we can see the failing type + print(tp) + raise + +# define some structure classes + +class Point(Structure): + _fields_ = [("x", c_long), ("y", c_long)] + +class PackedPoint(Structure): + _pack_ = 2 + _fields_ = [("x", c_long), ("y", c_long)] + +class Point2(Structure): + pass +Point2._fields_ = [("x", c_long), ("y", c_long)] + +class EmptyStruct(Structure): + _fields_ = [] + +class aUnion(Union): + _fields_ = [("a", c_int)] + +types = [ + # type format shape calc itemsize + + ## simple types + + (c_char, "c", None, c_char), + (c_byte, "b", None, c_byte), + (c_ubyte, "B", None, c_ubyte), + (c_short, "h", None, c_short), + (c_ushort, "H", None, c_ushort), + # c_int and c_uint may be aliases to c_long + (c_long, "l", None, c_long), + (c_ulong, "L", None, c_ulong), + (c_longlong, "q", None, c_longlong), + (c_ulonglong, "Q", None, c_ulonglong), + + (c_float, "f", None, c_float), + (c_double, "d", None, c_double), + # c_longdouble may be an alias to c_double + + (c_bool, "t", None, c_bool), + (py_object, "O", None, py_object), + + ## pointers + + (POINTER(c_byte), "&b", None, POINTER(c_byte)), + (POINTER(POINTER(c_long)), "&&l", None, POINTER(POINTER(c_long))), + + ## arrays and pointers + + (c_double * 4, "(4)d", (4,), c_double), + (c_float * 4 * 3 * 2, "(2,3,4)f", (2,3,4), c_float), + (POINTER(c_short) * 2, "(2)&h", (2,), POINTER(c_short)), + (POINTER(c_short) * 2 * 3, "(3,2)&h", (3,2,), POINTER(c_short)), + (POINTER(c_short * 2), "&(2)h", None, POINTER(c_short)), + + ## structures and unions + + (Point, "T{l:x:l:y:}", None, Point), + # packed structures do not implement the pep + (PackedPoint, "B", None, PackedPoint), + (Point2, "T{l:x:l:y:}", None, Point2), + (EmptyStruct, "T{}", None, EmptyStruct), + # the pep does't support unions + (aUnion, "B", None, aUnion), + ## other + + # function signatures are not implemented + (CFUNCTYPE(None), "X{}", None, CFUNCTYPE(None)), + + ] if __name__ == "__main__": unittest.main() From python-3000-checkins at python.org Fri Jan 25 20:44:41 2008 From: python-3000-checkins at python.org (thomas.heller) Date: Fri, 25 Jan 2008 20:44:41 +0100 (CET) Subject: [Python-3000-checkins] r60295 - python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c Message-ID: <20080125194441.78E3A1E400E@bag.python.org> Author: thomas.heller Date: Fri Jan 25 20:44:41 2008 New Revision: 60295 Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c Log: Fixed a few XXX markers. Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c Fri Jan 25 20:44:41 2008 @@ -263,20 +263,10 @@ size_t len; char *result; -#if 1 -/* XXX fix later */ - if (suffix == NULL) { - if (PyErr_Occurred()) - return NULL; - /* use default format character if not set */ - suffix = "B"; - } -#else if (suffix == NULL) { assert(PyErr_Occurred()); return NULL; } -#endif len = strlen(suffix); if (prefix) len += strlen(prefix); @@ -2330,13 +2320,8 @@ view->buf = self->b_ptr; view->len = self->b_size; view->readonly = 0; -#if 1 - /* XXX fix later */ /* use default format character if not set */ view->format = dict->format ? dict->format : "B"; -#else - view->format = dict->format; -#endif view->ndim = dict->ndim; view->shape = dict->shape; view->itemsize = self->b_size; Modified: python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c ============================================================================== --- python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c (original) +++ python/branches/py3k-ctypes-pep3118/Modules/_ctypes/stgdict.c Fri Jan 25 20:44:41 2008 @@ -476,7 +476,7 @@ } else bitsize = 0; if (isStruct && !isPacked) { - char *fieldfmt = dict->format ? dict->format : "XXX"; + char *fieldfmt = dict->format ? dict->format : "B"; char *fieldname = PyUnicode_AsString(name); char *ptr; Py_ssize_t len = strlen(fieldname) + strlen(fieldfmt); From python-3000-checkins at python.org Fri Jan 25 21:11:08 2008 From: python-3000-checkins at python.org (thomas.heller) Date: Fri, 25 Jan 2008 21:11:08 +0100 (CET) Subject: [Python-3000-checkins] r60298 - python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py Message-ID: <20080125201108.714941E4022@bag.python.org> Author: thomas.heller Date: Fri Jan 25 21:11:08 2008 New Revision: 60298 Modified: python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py Log: Fix test for 64-bt platform. Modified: python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py Fri Jan 25 21:11:08 2008 @@ -65,11 +65,17 @@ (c_ubyte, "B", None, c_ubyte), (c_short, "h", None, c_short), (c_ushort, "H", None, c_ushort), + # c_int and c_uint may be aliases to c_long + #(c_int, "i", None, c_int), + #(c_uint, "I", None, c_uint), + (c_long, "l", None, c_long), (c_ulong, "L", None, c_ulong), - (c_longlong, "q", None, c_longlong), - (c_ulonglong, "Q", None, c_ulonglong), + + # c_longlong and c_ulonglong are aliases on 64-bit platforms + #(c_longlong, "q", None, c_longlong), + #(c_ulonglong, "Q", None, c_ulonglong), (c_float, "f", None, c_float), (c_double, "d", None, c_double), From python-3000-checkins at python.org Fri Jan 25 21:34:11 2008 From: python-3000-checkins at python.org (thomas.heller) Date: Fri, 25 Jan 2008 21:34:11 +0100 (CET) Subject: [Python-3000-checkins] r60299 - python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py Message-ID: <20080125203411.9D24F1E401D@bag.python.org> Author: thomas.heller Date: Fri Jan 25 21:34:11 2008 New Revision: 60299 Modified: python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py Log: Add test for the readonly bit. Modified: python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py Fri Jan 25 21:34:11 2008 @@ -25,7 +25,11 @@ self.failUnlessEqual(v.size, sizeof(ob)) self.failUnlessEqual(v.itemsize, sizeof(itemtp)) self.failUnlessEqual(v.shape, shape) + # ctypes object always have a non-strided memory block self.failUnlessEqual(v.strides, None) + # they are always read/write + self.failIf(v.readonly) + if v.shape: n = 1 for dim in v.shape: From python-3000-checkins at python.org Sat Jan 26 00:21:17 2008 From: python-3000-checkins at python.org (thomas.wouters) Date: Sat, 26 Jan 2008 00:21:17 +0100 (CET) Subject: [Python-3000-checkins] r60302 - python/branches/py3k/Makefile.pre.in Message-ID: <20080125232117.40B441E4026@bag.python.org> Author: thomas.wouters Date: Sat Jan 26 00:21:16 2008 New Revision: 60302 Modified: python/branches/py3k/Makefile.pre.in Log: Make the testall target work again when building in a separate directory (with '../path/to/source/configure') Modified: python/branches/py3k/Makefile.pre.in ============================================================================== --- python/branches/py3k/Makefile.pre.in (original) +++ python/branches/py3k/Makefile.pre.in Sat Jan 26 00:21:16 2008 @@ -646,7 +646,7 @@ testall: all platform -find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f - $(TESTPYTHON) Lib/compileall.py + $(TESTPYTHON) $(srcdir)/Lib/compileall.py -find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f -$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall $(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall From python-3000-checkins at python.org Sat Jan 26 10:39:23 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sat, 26 Jan 2008 10:39:23 +0100 (CET) Subject: [Python-3000-checkins] r60313 - python/branches/py3k/Objects/codeobject.c Message-ID: <20080126093923.C583C1E4010@bag.python.org> Author: georg.brandl Date: Sat Jan 26 10:39:23 2008 New Revision: 60313 Modified: python/branches/py3k/Objects/codeobject.c Log: #1939: update code object docstring. Modified: python/branches/py3k/Objects/codeobject.c ============================================================================== --- python/branches/py3k/Objects/codeobject.c (original) +++ python/branches/py3k/Objects/codeobject.c Sat Jan 26 10:39:23 2008 @@ -179,8 +179,9 @@ } PyDoc_STRVAR(code_doc, -"code(argcount, nlocals, stacksize, flags, codestring, constants, names,\n\ - varnames, filename, name, firstlineno, lnotab[, freevars[, cellvars]])\n\ +"code(argcount, kwonlyargcount nlocals, stacksize, flags, codestring,\n\ + constants, names, varnames, filename, name, firstlineno,\n\ + lnotab[, freevars[, cellvars]])\n\ \n\ Create a code object. Not for the faint of heart."); From python-3000-checkins at python.org Sat Jan 26 10:45:59 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sat, 26 Jan 2008 10:45:59 +0100 (CET) Subject: [Python-3000-checkins] r60315 - python/branches/py3k/Lib/httplib.py Message-ID: <20080126094559.062451E4010@bag.python.org> Author: georg.brandl Date: Sat Jan 26 10:45:58 2008 New Revision: 60315 Modified: python/branches/py3k/Lib/httplib.py Log: #1929: fix httplib _read_chunked (str/bytes confusion). Modified: python/branches/py3k/Lib/httplib.py ============================================================================== --- python/branches/py3k/Lib/httplib.py (original) +++ python/branches/py3k/Lib/httplib.py Sat Jan 26 10:45:58 2008 @@ -560,14 +560,14 @@ def _read_chunked(self, amt): assert self.chunked != _UNKNOWN chunk_left = self.chunk_left - value = "" + value = b"" # XXX This accumulates chunks by repeated string concatenation, # which is not efficient as the number or size of chunks gets big. while True: if chunk_left is None: line = self.fp.readline() - i = line.find(";") + i = line.find(b";") if i >= 0: line = line[:i] # strip chunk-extensions chunk_left = int(line, 16) From python-3000-checkins at python.org Sat Jan 26 12:23:13 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sat, 26 Jan 2008 12:23:13 +0100 (CET) Subject: [Python-3000-checkins] r60318 - python/branches/py3k/Lib/urllib.py Message-ID: <20080126112313.99D5E1E4010@bag.python.org> Author: georg.brandl Date: Sat Jan 26 12:23:13 2008 New Revision: 60318 Modified: python/branches/py3k/Lib/urllib.py Log: Fix merge glitch that let test_urllib fail. Modified: python/branches/py3k/Lib/urllib.py ============================================================================== --- python/branches/py3k/Lib/urllib.py (original) +++ python/branches/py3k/Lib/urllib.py Sat Jan 26 12:23:13 2008 @@ -360,7 +360,8 @@ # According to RFC 2616, "2xx" code indicates that the client's # request was successfully received, understood, and accepted. if (200 <= response.status < 300): - return addinfourl(response.fp, response.msg, "http:" + url) + return addinfourl(response.fp, response.msg, "http:" + url, + response.status) else: return self.http_error( url, response.fp, From python-3000-checkins at python.org Sat Jan 26 20:49:42 2008 From: python-3000-checkins at python.org (neal.norwitz) Date: Sat, 26 Jan 2008 20:49:42 +0100 (CET) Subject: [Python-3000-checkins] r60328 - python/branches/py3k/Lib/test/test_urllib2net.py Message-ID: <20080126194942.14F4F1E4018@bag.python.org> Author: neal.norwitz Date: Sat Jan 26 20:49:41 2008 New Revision: 60328 Modified: python/branches/py3k/Lib/test/test_urllib2net.py Log: Get this test to pass Modified: python/branches/py3k/Lib/test/test_urllib2net.py ============================================================================== --- python/branches/py3k/Lib/test/test_urllib2net.py (original) +++ python/branches/py3k/Lib/test/test_urllib2net.py Sat Jan 26 20:49:41 2008 @@ -17,7 +17,8 @@ for i in range(3): try: return urllib2.urlopen(host, *args, **kwargs) - except urllib2.URLError as last_exc: + except urllib2.URLError as e: + last_exc = e continue except: raise @@ -310,13 +311,13 @@ socket.setdefaulttimeout(60) try: u = _urlopen_with_retry(self.FTP_HOST, timeout=None) - self.assertEqual(u.fp.fp._sock.gettimeout(), 60) + self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60) finally: socket.setdefaulttimeout(prev) def test_ftp_NoneNodefault(self): u = _urlopen_with_retry(self.FTP_HOST, timeout=None) - self.assertTrue(u.fp.fp._sock.gettimeout() is None) + self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None) def test_ftp_Value(self): u = _urlopen_with_retry(self.FTP_HOST, timeout=60) From python-3000-checkins at python.org Sat Jan 26 22:52:30 2008 From: python-3000-checkins at python.org (neal.norwitz) Date: Sat, 26 Jan 2008 22:52:30 +0100 (CET) Subject: [Python-3000-checkins] r60332 - python/branches/py3k/Lib/test/test_rational.py Message-ID: <20080126215230.D7E691E4018@bag.python.org> Author: neal.norwitz Date: Sat Jan 26 22:52:30 2008 New Revision: 60332 Modified: python/branches/py3k/Lib/test/test_rational.py Log: Get this test to run Modified: python/branches/py3k/Lib/test/test_rational.py ============================================================================== --- python/branches/py3k/Lib/test/test_rational.py (original) +++ python/branches/py3k/Lib/test/test_rational.py Sat Jan 26 22:52:30 2008 @@ -7,7 +7,7 @@ import rational import unittest from copy import copy, deepcopy -from cPickle import dumps, loads +from pickle import dumps, loads R = rational.Rational def _components(r): From python-3000-checkins at python.org Sat Jan 26 23:09:42 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Sat, 26 Jan 2008 23:09:42 +0100 (CET) Subject: [Python-3000-checkins] r60333 - python/branches/py3k/Lib/plistlib.py Message-ID: <20080126220942.C62011E4018@bag.python.org> Author: christian.heimes Date: Sat Jan 26 23:09:42 2008 New Revision: 60333 Added: python/branches/py3k/Lib/plistlib.py - copied unchanged from r60150, python/branches/py3k/Lib/plat-mac/plistlib.py Log: Copied plistlib.py from r60150 Lib/plat-mac/plistlib.py to Lib/ From g.brandl at gmx.net Sat Jan 26 23:21:21 2008 From: g.brandl at gmx.net (Georg Brandl) Date: Sat, 26 Jan 2008 23:21:21 +0100 Subject: [Python-3000-checkins] r60333 - python/branches/py3k/Lib/plistlib.py In-Reply-To: <20080126220942.C62011E4018@bag.python.org> References: <20080126220942.C62011E4018@bag.python.org> Message-ID: christian.heimes schrieb: > Author: christian.heimes > Date: Sat Jan 26 23:09:42 2008 > New Revision: 60333 > > Added: > python/branches/py3k/Lib/plistlib.py > - copied unchanged from r60150, python/branches/py3k/Lib/plat-mac/plistlib.py > Log: > Copied plistlib.py from r60150 Lib/plat-mac/plistlib.py to Lib/ Thanks! Still new with svnmerge, I didn't realize the trunk move wasn't mirrored in 3k. Georg -- Thus spake the Lord: Thou shalt indent with four spaces. No more, no less. Four shall be the number of spaces thou shalt indent, and the number of thy indenting shall be four. Eight shalt thou not indent, nor either indent thou two, excepting that thou then proceed to four. Tabs are right out. From python-3000-checkins at python.org Sun Jan 27 16:18:20 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Sun, 27 Jan 2008 16:18:20 +0100 (CET) Subject: [Python-3000-checkins] r60350 - in python/branches/py3k: Doc/c-api/module.rst Doc/library/collections.rst Doc/library/ftplib.rst Doc/library/os.path.rst Doc/tutorial/inputoutput.rst Doc/whatsnew/2.6.rst Include/genobject.h Include/unicodeobject.h Lib/bsddb/test/test_associate.py Lib/bsddb/test/test_compare.py Lib/bsddb/test/test_cursor_pget_bug.py Lib/bsddb/test/test_pickle.py Lib/bsddb/test/test_sequence.py Lib/bsddb/test/test_thread.py Lib/rational.py Lib/re.py Lib/test/test_asynchat.py Lib/test/test_dict.py Lib/test/test_generators.py Lib/test/test_rational.py Lib/test/test_resource.py Lib/test/test_telnetlib.py Lib/test/test_urllibnet.py Lib/test/test_xmlrpc.py Lib/test/test_zipfile.py Modules/_cursesmodule.c Modules/mathmodule.c Modules/mmapmodule.c Objects/dictobject.c Objects/genobject.c Objects/listobject.c Objects/setobject.c setup.py Message-ID: <20080127151820.810011E4003@bag.python.org> Author: christian.heimes Date: Sun Jan 27 16:18:18 2008 New Revision: 60350 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/c-api/module.rst python/branches/py3k/Doc/library/collections.rst python/branches/py3k/Doc/library/ftplib.rst python/branches/py3k/Doc/library/os.path.rst python/branches/py3k/Doc/tutorial/inputoutput.rst python/branches/py3k/Doc/whatsnew/2.6.rst python/branches/py3k/Include/genobject.h python/branches/py3k/Include/unicodeobject.h python/branches/py3k/Lib/bsddb/test/test_associate.py python/branches/py3k/Lib/bsddb/test/test_compare.py python/branches/py3k/Lib/bsddb/test/test_cursor_pget_bug.py python/branches/py3k/Lib/bsddb/test/test_pickle.py python/branches/py3k/Lib/bsddb/test/test_sequence.py python/branches/py3k/Lib/bsddb/test/test_thread.py python/branches/py3k/Lib/rational.py python/branches/py3k/Lib/re.py python/branches/py3k/Lib/test/test_asynchat.py python/branches/py3k/Lib/test/test_dict.py python/branches/py3k/Lib/test/test_generators.py python/branches/py3k/Lib/test/test_rational.py python/branches/py3k/Lib/test/test_resource.py python/branches/py3k/Lib/test/test_telnetlib.py python/branches/py3k/Lib/test/test_urllibnet.py python/branches/py3k/Lib/test/test_xmlrpc.py python/branches/py3k/Lib/test/test_zipfile.py python/branches/py3k/Modules/_cursesmodule.c python/branches/py3k/Modules/mathmodule.c python/branches/py3k/Modules/mmapmodule.c python/branches/py3k/Objects/dictobject.c python/branches/py3k/Objects/genobject.c python/branches/py3k/Objects/listobject.c python/branches/py3k/Objects/setobject.c python/branches/py3k/setup.py Log: Merged revisions 60284-60349 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60286 | christian.heimes | 2008-01-25 15:54:23 +0100 (Fri, 25 Jan 2008) | 1 line setup.py doesn't pick up changes to a header file ........ r60287 | christian.heimes | 2008-01-25 16:52:11 +0100 (Fri, 25 Jan 2008) | 2 lines Added the Python core headers Include/*.h and pyconfig.h as dependencies for the extensions in Modules/ It forces a rebuild of all extensions when a header files has been modified ........ r60291 | raymond.hettinger | 2008-01-25 20:24:46 +0100 (Fri, 25 Jan 2008) | 4 lines Changes 54857 and 54840 broke code and were reverted in Py2.5 just before it was released, but that reversion never made it to the Py2.6 head. ........ r60296 | guido.van.rossum | 2008-01-25 20:50:26 +0100 (Fri, 25 Jan 2008) | 2 lines Rewrite the list_inline_repeat overflow check slightly differently. ........ r60301 | thomas.wouters | 2008-01-25 22:09:34 +0100 (Fri, 25 Jan 2008) | 4 lines Use the right (portable) definition of the max of a Py_ssize_t. ........ r60303 | thomas.wouters | 2008-01-26 02:47:05 +0100 (Sat, 26 Jan 2008) | 5 lines Make 'testall' work again when building in a separate directory. test_distutils still fails when doing that. ........ r60305 | neal.norwitz | 2008-01-26 06:54:48 +0100 (Sat, 26 Jan 2008) | 3 lines Prevent this test from failing if there are transient network problems by retrying the host for up to 3 times. ........ r60306 | neal.norwitz | 2008-01-26 08:26:12 +0100 (Sat, 26 Jan 2008) | 12 lines Use a condition variable (threading.Event) rather than sleeps and checking a global to determine when the server is ready to be used. This slows the test down, but should make it correct. There was a race condition before where the server could have assigned a port, yet it wasn't ready to serve requests. If the client sent a request before the server was completely ready, it would get an exception. There was machinery to try to handle this condition. All of that should be unnecessary and removed if this change works. A NOTE was added as a comment about what needs to be fixed. The buildbots will tell us if there are more errors or if this test is now stable. ........ r60307 | neal.norwitz | 2008-01-26 08:38:03 +0100 (Sat, 26 Jan 2008) | 3 lines Fix exception in tearDown on ppc buildbot. If there's no directory, that shouldn't cause the test to fail. Just like it setUp. ........ r60308 | raymond.hettinger | 2008-01-26 09:19:06 +0100 (Sat, 26 Jan 2008) | 3 lines Make PySet_Add() work with frozensets. Works like PyTuple_SetItem() to build-up values in a brand new frozenset. ........ r60309 | neal.norwitz | 2008-01-26 09:26:00 +0100 (Sat, 26 Jan 2008) | 1 line The OS X buildbot had errors with the unavailable exceptions disabled. Restore it. ........ r60310 | raymond.hettinger | 2008-01-26 09:37:28 +0100 (Sat, 26 Jan 2008) | 4 lines Let marshal build-up sets and frozensets one element at a time. Saves the unnecessary creation of a tuple as intermediate container. ........ r60311 | raymond.hettinger | 2008-01-26 09:41:13 +0100 (Sat, 26 Jan 2008) | 1 line Update test code for change to PySet_Add(). ........ r60312 | raymond.hettinger | 2008-01-26 10:31:11 +0100 (Sat, 26 Jan 2008) | 1 line Revert PySet_Add() changes. ........ r60314 | georg.brandl | 2008-01-26 10:43:35 +0100 (Sat, 26 Jan 2008) | 2 lines #1934: fix os.path.isabs docs. ........ r60316 | georg.brandl | 2008-01-26 12:00:18 +0100 (Sat, 26 Jan 2008) | 2 lines Add missing things in re docstring. ........ r60317 | georg.brandl | 2008-01-26 12:02:22 +0100 (Sat, 26 Jan 2008) | 2 lines Slashes allowed on Windows. ........ r60319 | georg.brandl | 2008-01-26 14:41:21 +0100 (Sat, 26 Jan 2008) | 2 lines Fix markup again. ........ r60320 | andrew.kuchling | 2008-01-26 14:50:51 +0100 (Sat, 26 Jan 2008) | 1 line Add some items ........ r60321 | georg.brandl | 2008-01-26 15:02:38 +0100 (Sat, 26 Jan 2008) | 2 lines Clarify "b" mode under Unix. ........ r60322 | georg.brandl | 2008-01-26 15:03:47 +0100 (Sat, 26 Jan 2008) | 3 lines #1940: make it possible to use curses.filter() before curses.initscr() as the documentation says. ........ r60324 | georg.brandl | 2008-01-26 15:14:20 +0100 (Sat, 26 Jan 2008) | 3 lines #1473257: add generator.gi_code attribute that refers to the original code object backing the generator. Patch by Collin Winter. ........ r60325 | georg.brandl | 2008-01-26 15:19:22 +0100 (Sat, 26 Jan 2008) | 2 lines Move C API entries to the corresponding section. ........ r60326 | christian.heimes | 2008-01-26 17:43:35 +0100 (Sat, 26 Jan 2008) | 1 line Unit test fix from Giampaolo Rodola, #1938 ........ r60327 | gregory.p.smith | 2008-01-26 19:51:05 +0100 (Sat, 26 Jan 2008) | 2 lines Update docs for new callpack params added in r60188 ........ r60329 | neal.norwitz | 2008-01-26 21:24:36 +0100 (Sat, 26 Jan 2008) | 3 lines Cleanup the code a bit. test_rfind is failing on PPC and PPC64 buildbots, this might fix the problem. ........ r60330 | neal.norwitz | 2008-01-26 22:02:45 +0100 (Sat, 26 Jan 2008) | 1 line Always try to remove the test file even if close raises an exception ........ r60331 | neal.norwitz | 2008-01-26 22:21:59 +0100 (Sat, 26 Jan 2008) | 3 lines Reduce the race condition by signalling when the server is ready and not trying to connect before. ........ r60334 | neal.norwitz | 2008-01-27 00:13:46 +0100 (Sun, 27 Jan 2008) | 5 lines On some systems (e.g., Ubuntu on hppa) the flush() doesn't cause the exception, but the close() does. Will backport. ........ r60335 | neal.norwitz | 2008-01-27 00:14:17 +0100 (Sun, 27 Jan 2008) | 2 lines Consistently use tempfile.tempdir for the db_home directory. ........ r60338 | neal.norwitz | 2008-01-27 02:44:05 +0100 (Sun, 27 Jan 2008) | 4 lines Eliminate the sleeps that assume the server will start in .5 seconds. This should make the test less flaky. It also speeds up the test by about 75% on my box (20+ seconds -> ~4 seconds). ........ r60342 | neal.norwitz | 2008-01-27 06:02:34 +0100 (Sun, 27 Jan 2008) | 6 lines Try to prevent this test from being flaky. We might need a sleep in here which isn't as bad as it sounds. The close() *should* raise an exception, so if it didn't we should give more time to sync and really raise it. Will backport. ........ r60344 | jeffrey.yasskin | 2008-01-27 06:40:35 +0100 (Sun, 27 Jan 2008) | 3 lines Make rational.gcd() public and allow Rational to take decimal strings, per Raymond's advice. ........ r60345 | neal.norwitz | 2008-01-27 08:36:03 +0100 (Sun, 27 Jan 2008) | 3 lines Mostly reformat. Also set an error and return NULL if neither MS_WINDOWS nor UNIX is defined. This may have caused problems on cygwin. ........ r60346 | neal.norwitz | 2008-01-27 08:37:38 +0100 (Sun, 27 Jan 2008) | 3 lines Use int for the sign rather than a char. char can be signed or unsigned. It's system dependent. This might fix the problem with test_rfind failing. ........ r60347 | neal.norwitz | 2008-01-27 08:41:33 +0100 (Sun, 27 Jan 2008) | 1 line Add stdarg include for va_list to get this to compile on cygwin ........ r60348 | raymond.hettinger | 2008-01-27 11:13:57 +0100 (Sun, 27 Jan 2008) | 1 line Docstring nit ........ r60349 | raymond.hettinger | 2008-01-27 11:47:55 +0100 (Sun, 27 Jan 2008) | 1 line Removed an unnecessary and confusing paragraph from the namedtuple docs. ........ Modified: python/branches/py3k/Doc/c-api/module.rst ============================================================================== --- python/branches/py3k/Doc/c-api/module.rst (original) +++ python/branches/py3k/Doc/c-api/module.rst Sun Jan 27 16:18:18 2008 @@ -18,12 +18,12 @@ is exposed to Python programs as ``types.ModuleType``. -.. cmacro:: int PyModule_Check(PyObject *p) +.. cfunction:: int PyModule_Check(PyObject *p) Return true if *p* is a module object, or a subtype of a module object. -.. cmacro:: int PyModule_CheckExact(PyObject *p) +.. cfunction:: int PyModule_CheckExact(PyObject *p) Return true if *p* is a module object, but not a subtype of :cdata:`PyModule_Type`. @@ -94,7 +94,7 @@ null-terminated. Return ``-1`` on error, ``0`` on success. -.. cmacro:: int PyModule_AddIntMacro(PyObject *module, macro) +.. cfunction:: int PyModule_AddIntMacro(PyObject *module, macro) Add an int constant to *module*. The name and the value are taken from *macro*. For example ``PyModule_AddConstant(module, AF_INET)`` adds the int @@ -102,7 +102,7 @@ Return ``-1`` on error, ``0`` on success. -.. cmacro:: int PyModule_AddStringMacro(PyObject *module, macro) +.. cfunction:: int PyModule_AddStringMacro(PyObject *module, macro) Add a string constant to *module*. Modified: python/branches/py3k/Doc/library/collections.rst ============================================================================== --- python/branches/py3k/Doc/library/collections.rst (original) +++ python/branches/py3k/Doc/library/collections.rst Sun Jan 27 16:18:18 2008 @@ -557,16 +557,7 @@ Point: x= 3.000 y= 4.000 hypot= 5.000 Point: x=14.000 y= 0.714 hypot=14.018 -Another use for subclassing is to replace performance critcal methods with -faster versions that bypass error-checking:: - - class Point(namedtuple('Point', 'x y')): - __slots__ = () - _make = classmethod(tuple.__new__) - def _replace(self, _map=map, **kwds): - return self._make(_map(kwds.get, ('x', 'y'), self)) - -The subclasses shown above set ``__slots__`` to an empty tuple. This keeps +The subclass shown above sets ``__slots__`` to an empty tuple. This keeps keep memory requirements low by preventing the creation of instance dictionaries. Modified: python/branches/py3k/Doc/library/ftplib.rst ============================================================================== --- python/branches/py3k/Doc/library/ftplib.rst (original) +++ python/branches/py3k/Doc/library/ftplib.rst Sun Jan 27 16:18:18 2008 @@ -176,11 +176,12 @@ .. method:: FTP.retrlines(command[, callback]) - Retrieve a file or directory listing in ASCII transfer mode. *command* should be - an appropriate ``RETR`` command (see :meth:`retrbinary`) or a ``LIST`` command - (usually just the string ``'LIST'``). The *callback* function is called for - each line, with the trailing CRLF stripped. The default *callback* prints the - line to ``sys.stdout``. + Retrieve a file or directory listing in ASCII transfer mode. *command* + should be an appropriate ``RETR`` command (see :meth:`retrbinary`) or a + command such as ``LIST``, ``NLST`` or ``MLSD`` (usually just the string + ``'LIST'``). The *callback* function is called for each line, with the + trailing CRLF stripped. The default *callback* prints the line to + ``sys.stdout``. .. method:: FTP.set_pasv(boolean) @@ -190,20 +191,23 @@ it is on by default.) -.. method:: FTP.storbinary(command, file[, blocksize]) +.. method:: FTP.storbinary(command, file[, blocksize, callback]) Store a file in binary transfer mode. *command* should be an appropriate ``STOR`` command: ``"STOR filename"``. *file* is an open file object which is read until EOF using its :meth:`read` method in blocks of size *blocksize* to provide the data to be stored. The *blocksize* argument defaults to 8192. + *callback* is an optional single parameter callable that is called + on each block of data after it is sent. -.. method:: FTP.storlines(command, file) +.. method:: FTP.storlines(command, file[, callback]) Store a file in ASCII transfer mode. *command* should be an appropriate ``STOR`` command (see :meth:`storbinary`). Lines are read until EOF from the open file object *file* using its :meth:`readline` method to provide the data to - be stored. + be stored. *callback* is an optional single parameter callable + that is called on each line after it is sent. .. method:: FTP.transfercmd(cmd[, rest]) Modified: python/branches/py3k/Doc/library/os.path.rst ============================================================================== --- python/branches/py3k/Doc/library/os.path.rst (original) +++ python/branches/py3k/Doc/library/os.path.rst Sun Jan 27 16:18:18 2008 @@ -130,7 +130,9 @@ .. function:: isabs(path) - Return ``True`` if *path* is an absolute pathname (begins with a slash). + Return ``True`` if *path* is an absolute pathname. On Unix, that means it + begins with a slash, on Windows that it begins with a (back)slash after chopping + off a potential drive letter. .. function:: isfile(path) Modified: python/branches/py3k/Doc/tutorial/inputoutput.rst ============================================================================== --- python/branches/py3k/Doc/tutorial/inputoutput.rst (original) +++ python/branches/py3k/Doc/tutorial/inputoutput.rst Sun Jan 27 16:18:18 2008 @@ -195,16 +195,15 @@ writing. The *mode* argument is optional; ``'r'`` will be assumed if it's omitted. -``'b'`` appended to the mode opens the file in binary mode, so there are -also modes like ``'rb'``, ``'wb'``, and ``'r+b'``. Python distinguishes -between text and binary files. Binary files are read and written without -any data transformation. In text mode, platform-specific newline -representations are automatically converted to newlines when read and -newline characters are automatically converted to the proper -platform-specific representation when written. This makes writing portable -code which reads or writes text files easier. In addition, when reading -from or writing to text files, the data are automatically decoded or -encoding, respectively, using the encoding associated with the file. +On Windows and the Macintosh, ``'b'`` appended to the mode opens the file in +binary mode, so there are also modes like ``'rb'``, ``'wb'``, and ``'r+b'``. +Windows makes a distinction between text and binary files; the end-of-line +characters in text files are automatically altered slightly when data is read or +written. This behind-the-scenes modification to file data is fine for ASCII +text files, but it'll corrupt binary data like that in :file:`JPEG` or +:file:`EXE` files. Be very careful to use binary mode when reading and writing +such files. On Unix, it doesn't hurt to append a ``'b'`` to the mode, so +you can use it platform-independently for all binary files. This behind-the-scenes modification to file data is fine for text files, but will corrupt binary data like that in :file:`JPEG` or :file:`EXE` files. Be Modified: python/branches/py3k/Doc/whatsnew/2.6.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/2.6.rst (original) +++ python/branches/py3k/Doc/whatsnew/2.6.rst Sun Jan 27 16:18:18 2008 @@ -3,6 +3,7 @@ **************************** .. XXX mention switch to Roundup for bug tracking +.. XXX add trademark info for Apple, Microsoft. :Author: A.M. Kuchling :Release: |release| @@ -909,7 +910,13 @@ * An optional ``timeout`` parameter was added to the :class:`ftplib.FTP` class constructor as well as the :meth:`connect` method, specifying a timeout measured in seconds. (Added by Facundo - Batista.) + Batista.) Also, the :class:`FTP` class's + :meth:`storbinary` and :meth:`storlines` + now take an optional *callback* parameter that will be called with + each block of data after the data has been sent. + (Contributed by Phil Schwartz.) + + .. Patch 1221598 * The :func:`reduce` built-in function is also available in the :mod:`functools` module. In Python 3.0, the built-in is dropped and it's @@ -1041,6 +1048,13 @@ .. Patch 1137 +* The :mod:`Queue` module now provides queue classes that retrieve entries + in different orders. The :class:`PriorityQueue` class stores + queued items in a heap and retrieves them in priority order, + and :class:`LifoQueue` retrieves the most recently added entries first, + meaning that it behaves like a stack. + (Contributed by Raymond Hettinger.) + * The :mod:`random` module's :class:`Random` objects can now be pickled on a 32-bit system and unpickled on a 64-bit system, and vice versa. Unfortunately, this change also means @@ -1304,6 +1318,47 @@ SSL module documentation. + +.. ====================================================================== + +plistlib: A Property-List Parser +-------------------------------------------------- + +A commonly-used format on MacOS X is the ``.plist`` format, +which stores basic data types (numbers, strings, lists, +and dictionaries) and serializes them into an XML-based format. +(It's a lot like the XML-RPC serialization of data types.) + +Despite being primarily used on MacOS X, the format +has nothing Mac-specific about it and the Python implementation works +on any platform that Python supports, so the :mod:`plistlib` module +has been promoted to the standard library. + +Using the module is simple:: + + import sys + import plistlib + import datetime + + # Create data structure + data_struct = dict(lastAccessed=datetime.datetime.now(), + version=1, + categories=('Personal', 'Shared', 'Private')) + + # Create string containing XML. + plist_str = plistlib.writePlistToString(data_struct) + new_struct = plistlib.readPlistFromString(plist_str) + print data_struct + print new_struct + + # Write data structure to a file and read it back. + plistlib.writePlist(data_struct, '/tmp/customizations.plist') + new_struct = plistlib.readPlist('/tmp/customizations.plist') + + # read/writePlist accepts file-like objects as well as paths. + plistlib.writePlist(data_struct, sys.stdout) + + .. ====================================================================== @@ -1351,6 +1406,13 @@ .. Issue 1629 +* Distutils now places C extensions it builds in a + different directory when running on a debug version of Python. + (Contributed by Collin Winter.) + + .. Patch 1530959 + + .. ====================================================================== Modified: python/branches/py3k/Include/genobject.h ============================================================================== --- python/branches/py3k/Include/genobject.h (original) +++ python/branches/py3k/Include/genobject.h Sun Jan 27 16:18:18 2008 @@ -18,6 +18,9 @@ /* True if generator is being executed. */ int gi_running; + + /* The code object backing the generator */ + PyObject *gi_code; /* List of weak reference. */ PyObject *gi_weakreflist; Modified: python/branches/py3k/Include/unicodeobject.h ============================================================================== --- python/branches/py3k/Include/unicodeobject.h (original) +++ python/branches/py3k/Include/unicodeobject.h Sun Jan 27 16:18:18 2008 @@ -1,6 +1,8 @@ #ifndef Py_UNICODEOBJECT_H #define Py_UNICODEOBJECT_H +#include + /* Unicode implementation based on original code by Fredrik Lundh, Modified: python/branches/py3k/Lib/bsddb/test/test_associate.py ============================================================================== --- python/branches/py3k/Lib/bsddb/test/test_associate.py (original) +++ python/branches/py3k/Lib/bsddb/test/test_associate.py Sun Jan 27 16:18:18 2008 @@ -141,7 +141,15 @@ def setUp(self): self.filename = self.__class__.__name__ + '.db' - self.homeDir = tempfile.mkdtemp() + homeDir = os.path.join(tempfile.gettempdir(), 'db_home') + self.homeDir = homeDir + try: + os.mkdir(homeDir) + except os.error: + import glob + files = glob.glob(os.path.join(self.homeDir, '*')) + for file in files: + os.remove(file) self.env = db.DBEnv() self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL | db.DB_INIT_LOCK | db.DB_THREAD | self.envFlags) Modified: python/branches/py3k/Lib/bsddb/test/test_compare.py ============================================================================== --- python/branches/py3k/Lib/bsddb/test/test_compare.py (original) +++ python/branches/py3k/Lib/bsddb/test/test_compare.py Sun Jan 27 16:18:18 2008 @@ -6,6 +6,7 @@ import sys, os, re from io import StringIO import tempfile +import test_all import unittest try: @@ -55,7 +56,12 @@ def setUp (self): self.filename = self.__class__.__name__ + '.db' - self.homeDir = tempfile.mkdtemp() + homeDir = os.path.join (tempfile.gettempdir(), 'db_home') + self.homeDir = homeDir + try: + os.mkdir (homeDir) + except os.error: + pass env = db.DBEnv () env.open (self.homeDir, Modified: python/branches/py3k/Lib/bsddb/test/test_cursor_pget_bug.py ============================================================================== --- python/branches/py3k/Lib/bsddb/test/test_cursor_pget_bug.py (original) +++ python/branches/py3k/Lib/bsddb/test/test_cursor_pget_bug.py Sun Jan 27 16:18:18 2008 @@ -1,4 +1,5 @@ import unittest +import tempfile import sys, os, glob import shutil import tempfile @@ -13,7 +14,11 @@ db_name = 'test-cursor_pget.db' def setUp(self): - self.homeDir = tempfile.mkdtemp() + self.homeDir = os.path.join(tempfile.gettempdir(), 'db_home') + try: + os.mkdir(self.homeDir) + except os.error: + pass self.env = db.DBEnv() self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL) self.primary_db = db.DB(self.env) Modified: python/branches/py3k/Lib/bsddb/test/test_pickle.py ============================================================================== --- python/branches/py3k/Lib/bsddb/test/test_pickle.py (original) +++ python/branches/py3k/Lib/bsddb/test/test_pickle.py Sun Jan 27 16:18:18 2008 @@ -4,6 +4,7 @@ import pickle import tempfile import unittest +import tempfile import glob try: @@ -21,7 +22,10 @@ db_name = 'test-dbobj.db' def setUp(self): - self.homeDir = tempfile.mkdtemp() + homeDir = os.path.join(tempfile.gettempdir(), 'db_home') + self.homeDir = homeDir + try: os.mkdir(homeDir) + except os.error: pass def tearDown(self): if hasattr(self, 'db'): Modified: python/branches/py3k/Lib/bsddb/test/test_sequence.py ============================================================================== --- python/branches/py3k/Lib/bsddb/test/test_sequence.py (original) +++ python/branches/py3k/Lib/bsddb/test/test_sequence.py Sun Jan 27 16:18:18 2008 @@ -17,8 +17,11 @@ class DBSequenceTest(unittest.TestCase): def setUp(self): self.int_32_max = 0x100000000 - self.homeDir = tempfile.mkdtemp() - old_tempfile_tempdir = tempfile.tempdir + self.homeDir = os.path.join(tempfile.gettempdir(), 'db_home') + try: + os.mkdir(self.homeDir) + except os.error: + pass tempfile.tempdir = self.homeDir self.filename = os.path.split(tempfile.mktemp())[1] tempfile.tempdir = old_tempfile_tempdir Modified: python/branches/py3k/Lib/bsddb/test/test_thread.py ============================================================================== --- python/branches/py3k/Lib/bsddb/test/test_thread.py (original) +++ python/branches/py3k/Lib/bsddb/test/test_thread.py Sun Jan 27 16:18:18 2008 @@ -47,7 +47,12 @@ if verbose: dbutils._deadlock_VerboseFile = sys.stdout - self.homeDir = tempfile.mkdtemp() + homeDir = os.path.join(tempfile.gettempdir(), 'db_home') + self.homeDir = homeDir + try: + os.mkdir(homeDir) + except OSError, e: + if e.errno != errno.EEXIST: raise self.env = db.DBEnv() self.setEnvOpts() self.env.open(self.homeDir, self.envflags | db.DB_CREATE) @@ -61,7 +66,10 @@ def tearDown(self): self.d.close() self.env.close() - shutil.rmtree(self.homeDir) + try: + shutil.rmtree(self.homeDir) + except OSError, e: + if e.errno != errno.EEXIST: raise def setEnvOpts(self): pass Modified: python/branches/py3k/Lib/rational.py ============================================================================== --- python/branches/py3k/Lib/rational.py (original) +++ python/branches/py3k/Lib/rational.py Sun Jan 27 16:18:18 2008 @@ -13,8 +13,8 @@ RationalAbc = numbers.Rational -def _gcd(a, b): # XXX This is a useful function. Consider making it public. - """Calculate the Greatest Common Divisor. +def gcd(a, b): + """Calculate the Greatest Common Divisor of a and b. Unless b==0, the result will have the same sign as b (so that when b is divided by it, the result comes out positive). @@ -39,8 +39,8 @@ >>> _binary_float_to_ratio(-.25) (-1, 4) """ - # XXX Consider moving this to to floatobject.c - # with a name like float.as_intger_ratio() + # XXX Move this to floatobject.c with a name like + # float.as_integer_ratio() if x == 0: return 0, 1 @@ -79,12 +79,9 @@ _RATIONAL_FORMAT = re.compile( - r'^\s*(?P[-+]?)(?P\d+)(?:/(?P\d+))?\s*$') + r'^\s*(?P[-+]?)(?P\d+)' + r'(?:/(?P\d+)|\.(?P\d+))?\s*$') -# XXX Consider accepting decimal strings as input since they are exact. -# Rational("2.01") --> s="2.01" ; Rational.from_decimal(Decimal(s)) --> Rational(201, 100)" -# If you want to avoid going through the decimal module, just parse the string directly: -# s.partition('.') --> ('2', '.', '01') --> Rational(int('2'+'01'), 10**len('01')) --> Rational(201, 100) class Rational(RationalAbc): """This class implements rational numbers. @@ -95,7 +92,7 @@ Rational() == 0. Rationals can also be constructed from strings of the form - '[-+]?[0-9]+(/[0-9]+)?', optionally surrounded by spaces. + '[-+]?[0-9]+((/|.)[0-9]+)?', optionally surrounded by spaces. """ @@ -105,7 +102,8 @@ def __new__(cls, numerator=0, denominator=1): """Constructs a Rational. - Takes a string, another Rational, or a numerator/denominator pair. + Takes a string like '3/2' or '1.5', another Rational, or a + numerator/denominator pair. """ self = super(Rational, cls).__new__(cls) @@ -117,9 +115,18 @@ m = _RATIONAL_FORMAT.match(input) if m is None: raise ValueError('Invalid literal for Rational: ' + input) - numerator = int(m.group('num')) - # Default denominator to 1. That's the only optional group. - denominator = int(m.group('denom') or 1) + numerator = m.group('num') + decimal = m.group('decimal') + if decimal: + # The literal is a decimal number. + numerator = int(numerator + decimal) + denominator = 10**len(decimal) + else: + # The literal is an integer or fraction. + numerator = int(numerator) + # Default denominator to 1. + denominator = int(m.group('denom') or 1) + if m.group('sign') == '-': numerator = -numerator @@ -138,7 +145,7 @@ if denominator == 0: raise ZeroDivisionError('Rational(%s, 0)' % numerator) - g = _gcd(numerator, denominator) + g = gcd(numerator, denominator) self.numerator = int(numerator // g) self.denominator = int(denominator // g) return self Modified: python/branches/py3k/Lib/re.py ============================================================================== --- python/branches/py3k/Lib/re.py (original) +++ python/branches/py3k/Lib/re.py Sun Jan 27 16:18:18 2008 @@ -38,7 +38,7 @@ *?,+?,?? Non-greedy versions of the previous three special characters. {m,n} Matches from m to n repetitions of the preceding RE. {m,n}? Non-greedy version of the above. - "\\" Either escapes special characters or signals a special sequence. + "\\" Either escapes special characters or signals a special sequence. [] Indicates a set of characters. A "^" as the first character indicates a complementing set. "|" A|B, creates an RE that will match either A or B. @@ -51,6 +51,10 @@ (?#...) A comment; ignored. (?=...) Matches if ... matches next, but doesn't consume the string. (?!...) Matches if ... doesn't match next. + (?<=...) Matches if preceded by ... (must be fixed length). + (?>> type(i) >>> [s for s in dir(i) if not s.startswith('_')] -['close', 'gi_frame', 'gi_running', 'send', 'throw'] +['close', 'gi_code', 'gi_frame', 'gi_running', 'send', 'throw'] >>> print(i.__next__.__doc__) x.__next__() <==> next(x) >>> iter(i) is i @@ -899,6 +899,24 @@ >>> print(next(g)) Traceback (most recent call last): StopIteration + + +Test the gi_code attribute + +>>> def f(): +... yield 5 +... +>>> g = f() +>>> g.gi_code is f.__code__ +True +>>> next(g) +5 +>>> next(g) +Traceback (most recent call last): +StopIteration +>>> g.gi_code is f.__code__ +True + """ # conjoin is a simple backtracking generator, named in honor of Icon's Modified: python/branches/py3k/Lib/test/test_rational.py ============================================================================== --- python/branches/py3k/Lib/test/test_rational.py (original) +++ python/branches/py3k/Lib/test/test_rational.py Sun Jan 27 16:18:18 2008 @@ -9,10 +9,28 @@ from copy import copy, deepcopy from pickle import dumps, loads R = rational.Rational +gcd = rational.gcd + + +class GcdTest(unittest.TestCase): + + def testMisc(self): + self.assertEquals(0, gcd(0, 0)) + self.assertEquals(1, gcd(1, 0)) + self.assertEquals(-1, gcd(-1, 0)) + self.assertEquals(1, gcd(0, 1)) + self.assertEquals(-1, gcd(0, -1)) + self.assertEquals(1, gcd(7, 1)) + self.assertEquals(-1, gcd(7, -1)) + self.assertEquals(1, gcd(-23, 15)) + self.assertEquals(12, gcd(120, 84)) + self.assertEquals(-12, gcd(84, -120)) + def _components(r): return (r.numerator, r.denominator) + class RationalTest(unittest.TestCase): def assertTypedEquals(self, expected, actual): @@ -57,6 +75,8 @@ self.assertEquals((-3, 2), _components(R("-3/2 "))) self.assertEquals((3, 2), _components(R(" 03/02 \n "))) self.assertEquals((3, 2), _components(R(" 03/02 \n "))) + self.assertEquals((16, 5), _components(R(" 3.2 "))) + self.assertEquals((-16, 5), _components(R(" -3.2 "))) self.assertRaisesMessage( ZeroDivisionError, "Rational(3, 0)", @@ -76,9 +96,21 @@ ValueError, "Invalid literal for Rational: + 3/2", R, "+ 3/2") self.assertRaisesMessage( - # Only parse fractions, not decimals. - ValueError, "Invalid literal for Rational: 3.2", - R, "3.2") + # Avoid treating '.' as a regex special character. + ValueError, "Invalid literal for Rational: 3a2", + R, "3a2") + self.assertRaisesMessage( + # Only parse ordinary decimals, not scientific form. + ValueError, "Invalid literal for Rational: 3.2e4", + R, "3.2e4") + self.assertRaisesMessage( + # Don't accept combinations of decimals and rationals. + ValueError, "Invalid literal for Rational: 3/7.2", + R, "3/7.2") + self.assertRaisesMessage( + # Don't accept combinations of decimals and rationals. + ValueError, "Invalid literal for Rational: 3.2/7", + R, "3.2/7") def testImmutable(self): r = R(7, 3) @@ -370,7 +402,7 @@ self.assertEqual(id(r), id(deepcopy(r))) def test_main(): - run_unittest(RationalTest) + run_unittest(RationalTest, GcdTest) if __name__ == '__main__': test_main() Modified: python/branches/py3k/Lib/test/test_resource.py ============================================================================== --- python/branches/py3k/Lib/test/test_resource.py (original) +++ python/branches/py3k/Lib/test/test_resource.py Sun Jan 27 16:18:18 2008 @@ -15,7 +15,6 @@ self.assertRaises(TypeError, resource.setrlimit, 42, 42, 42) def test_fsize_ismax(self): - try: (cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE) except AttributeError: @@ -54,6 +53,13 @@ try: f.write(b"Y") f.flush() + # On some systems (e.g., Ubuntu on hppa) the flush() + # doesn't always cause the exception, but the close() + # does eventually. Try closing several times in + # an attempt to ensure the file is really synced and + # the exception raised. + for i in range(5): + f.close() except IOError: if not limit_set: raise @@ -63,10 +69,10 @@ resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max)) finally: f.close() - os.unlink(test_support.TESTFN) finally: if limit_set: resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max)) + test_support.unlink(test_support.TESTFN) def test_fsize_toobig(self): # Be sure that setrlimit is checking for really large values Modified: python/branches/py3k/Lib/test/test_telnetlib.py ============================================================================== --- python/branches/py3k/Lib/test/test_telnetlib.py (original) +++ python/branches/py3k/Lib/test/test_telnetlib.py Sun Jan 27 16:18:18 2008 @@ -7,13 +7,13 @@ from test import test_support -def server(evt, ready): +def server(evt): serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) serv.settimeout(3) serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) serv.bind(("", 9091)) serv.listen(5) - ready.set() + evt.set() try: conn, addr = serv.accept() except socket.timeout: @@ -26,9 +26,10 @@ def setUp(self): self.evt = threading.Event() - ready = threading.Event() - threading.Thread(target=server, args=(self.evt, ready)).start() - ready.wait() + threading.Thread(target=server, args=(self.evt,)).start() + self.evt.wait() + self.evt.clear() + time.sleep(.1) def tearDown(self): self.evt.wait() Modified: python/branches/py3k/Lib/test/test_urllibnet.py ============================================================================== --- python/branches/py3k/Lib/test/test_urllibnet.py (original) +++ python/branches/py3k/Lib/test/test_urllibnet.py Sun Jan 27 16:18:18 2008 @@ -9,6 +9,20 @@ import os import mimetools + +def _open_with_retry(func, host, *args, **kwargs): + # Connecting to remote hosts is flaky. Make it more robust + # by retrying the connection several times. + for i in range(3): + try: + return func(host, *args, **kwargs) + except IOError, last_exc: + continue + except: + raise + raise last_exc + + class URLTimeoutTest(unittest.TestCase): TIMEOUT = 10.0 @@ -20,7 +34,7 @@ socket.setdefaulttimeout(None) def testURLread(self): - f = urllib.urlopen("http://www.python.org/") + f = _open_with_retry(urllib.urlopen, "http://www.python.org/") x = f.read() class urlopenNetworkTests(unittest.TestCase): @@ -38,9 +52,12 @@ """ + def urlopen(self, *args): + return _open_with_retry(urllib.urlopen, *args) + def test_basic(self): # Simple test expected to pass. - open_url = urllib.urlopen("http://www.python.org/") + open_url = self.urlopen("http://www.python.org/") for attr in ("read", "readline", "readlines", "fileno", "close", "info", "geturl"): self.assert_(hasattr(open_url, attr), "object returned from " @@ -52,7 +69,7 @@ def test_readlines(self): # Test both readline and readlines. - open_url = urllib.urlopen("http://www.python.org/") + open_url = self.urlopen("http://www.python.org/") try: self.assert_(isinstance(open_url.readline(), bytes), "readline did not return bytes") @@ -63,7 +80,7 @@ def test_info(self): # Test 'info'. - open_url = urllib.urlopen("http://www.python.org/") + open_url = self.urlopen("http://www.python.org/") try: info_obj = open_url.info() finally: @@ -76,7 +93,7 @@ def test_geturl(self): # Make sure same URL as opened is returned by geturl. URL = "http://www.python.org/" - open_url = urllib.urlopen(URL) + open_url = self.urlopen(URL) try: gotten_url = open_url.geturl() finally: @@ -100,7 +117,7 @@ # test can't pass on Windows. return # Make sure fd returned by fileno is valid. - open_url = urllib.urlopen("http://www.python.org/") + open_url = self.urlopen("http://www.python.org/") fd = open_url.fileno() FILE = os.fdopen(fd) try: @@ -125,9 +142,12 @@ class urlretrieveNetworkTests(unittest.TestCase): """Tests urllib.urlretrieve using the network.""" + def urlretrieve(self, *args): + return _open_with_retry(urllib.urlretrieve, *args) + def test_basic(self): # Test basic functionality. - file_location,info = urllib.urlretrieve("http://www.python.org/") + file_location,info = self.urlretrieve("http://www.python.org/") self.assert_(os.path.exists(file_location), "file location returned by" " urlretrieve is not a valid path") FILE = open(file_location) @@ -140,8 +160,8 @@ def test_specified_path(self): # Make sure that specifying the location of the file to write to works. - file_location,info = urllib.urlretrieve("http://www.python.org/", - test_support.TESTFN) + file_location,info = self.urlretrieve("http://www.python.org/", + test_support.TESTFN) self.assertEqual(file_location, test_support.TESTFN) self.assert_(os.path.exists(file_location)) FILE = open(file_location) @@ -153,7 +173,7 @@ def test_header(self): # Make sure header returned as 2nd value from urlretrieve is good. - file_location, header = urllib.urlretrieve("http://www.python.org/") + file_location, header = self.urlretrieve("http://www.python.org/") os.unlink(file_location) self.assert_(isinstance(header, mimetools.Message), "header is not an instance of mimetools.Message") Modified: python/branches/py3k/Lib/test/test_xmlrpc.py ============================================================================== --- python/branches/py3k/Lib/test/test_xmlrpc.py (original) +++ python/branches/py3k/Lib/test/test_xmlrpc.py Sun Jan 27 16:18:18 2008 @@ -261,6 +261,9 @@ PORT = None +# The evt is set twice. First when the server is ready to serve. +# Second when the server has been shutdown. The user must clear +# the event after it has been set the first time to catch the second set. def http_server(evt, numrequests): class TestInstanceClass: def div(self, x, y): @@ -287,6 +290,7 @@ serv.register_function(lambda x,y: x+y, 'add') serv.register_function(my_function) serv.register_instance(TestInstanceClass()) + evt.set() # handle up to 'numrequests' requests while numrequests > 0: @@ -300,14 +304,16 @@ PORT = None evt.set() -def stop_serving(): - global PORT - if PORT is None: - return - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.connect(('localhost', int(PORT))) - sock.send(b"") - sock.close() +# This function prevents errors like: +# +def is_unavailable_exception(e): + '''Returns True if the given ProtocolError is the product of a server-side + exception caused by the 'temporarily unavailable' response sometimes + given by operations on non-blocking sockets.''' + + # sometimes we get a -1 error code and/or empty headers + if e.errcode == -1 or e.headers is None: + return True class SimpleServerTestCase(unittest.TestCase): @@ -320,13 +326,9 @@ serv_args = (self.evt, 1) threading.Thread(target=http_server, args=serv_args).start() - # wait for port to be assigned to server - n = 1000 - while n > 0 and PORT is None: - time.sleep(0.001) - n -= 1 - - time.sleep(0.5) + # wait for the server to be ready + self.evt.wait() + self.evt.clear() def tearDown(self): # wait on the server thread to terminate @@ -457,13 +459,9 @@ serv_args = (self.evt, 1) threading.Thread(target=http_server, args=serv_args).start() - # wait for port to be assigned to server - n = 1000 - while n > 0 and PORT is None: - time.sleep(0.001) - n -= 1 - - time.sleep(0.5) + # wait for the server to be ready + self.evt.wait() + self.evt.clear() def tearDown(self): # wait on the server thread to terminate Modified: python/branches/py3k/Lib/test/test_zipfile.py ============================================================================== --- python/branches/py3k/Lib/test/test_zipfile.py (original) +++ python/branches/py3k/Lib/test/test_zipfile.py Sun Jan 27 16:18:18 2008 @@ -309,6 +309,7 @@ correctfile = os.path.join(os.getcwd(), fpath[1:]) else: correctfile = os.path.join(os.getcwd(), fpath) + correctfile = os.path.normpath(correctfile) self.assertEqual(writtenfile, correctfile) Modified: python/branches/py3k/Modules/_cursesmodule.c ============================================================================== --- python/branches/py3k/Modules/_cursesmodule.c (original) +++ python/branches/py3k/Modules/_cursesmodule.c Sun Jan 27 16:18:18 2008 @@ -1711,11 +1711,20 @@ NoArgTrueFalseFunction(has_ic) NoArgTrueFalseFunction(has_il) NoArgTrueFalseFunction(isendwin) -NoArgNoReturnVoidFunction(filter) NoArgNoReturnVoidFunction(flushinp) NoArgNoReturnVoidFunction(noqiflush) static PyObject * +PyCurses_filter(PyObject *self) +{ + /* not checking for PyCursesInitialised here since filter() must + be called before initscr() */ + filter(); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * PyCurses_Color_Content(PyObject *self, PyObject *args) { short color,r,g,b; Modified: python/branches/py3k/Modules/mathmodule.c ============================================================================== --- python/branches/py3k/Modules/mathmodule.c (original) +++ python/branches/py3k/Modules/mathmodule.c Sun Jan 27 16:18:18 2008 @@ -291,9 +291,9 @@ "math domain error"); return NULL; } - /* Value is ~= x * 2**(e*SHIFT), so the log ~= - log(x) + log(2) * e * SHIFT. - CAUTION: e*SHIFT may overflow using int arithmetic, + /* Value is ~= x * 2**(e*PyLong_SHIFT), so the log ~= + log(x) + log(2) * e * PyLong_SHIFT. + CAUTION: e*PyLong_SHIFT may overflow using int arithmetic, so force use of double. */ x = func(x) + (e * (double)PyLong_SHIFT) * func(2.0); return PyFloat_FromDouble(x); Modified: python/branches/py3k/Modules/mmapmodule.c ============================================================================== --- python/branches/py3k/Modules/mmapmodule.c (original) +++ python/branches/py3k/Modules/mmapmodule.c Sun Jan 27 16:18:18 2008 @@ -259,8 +259,8 @@ int reverse) { Py_ssize_t start = self->pos; - Py_ssize_t end = self->size; - char *needle; + Py_ssize_t end = self->size; + const char *needle; Py_ssize_t len; CHECK_VALID(NULL); @@ -268,8 +268,8 @@ &needle, &len, &start, &end)) { return NULL; } else { - char *p; - char sign = reverse ? -1 : 1; + const char *p, *start_p, *end_p; + int sign = reverse ? -1 : 1; if (start < 0) start += self->size; @@ -285,11 +285,11 @@ else if ((size_t)end > self->size) end = self->size; - start += (Py_ssize_t)self->data; - end += (Py_ssize_t)self->data; + start_p = self->data + start; + end_p = self->data + end; - for (p = (char *)(reverse ? end - len : start); - p >= (char *)start && p + len <= (char *)end; p+=sign) { + for (p = (reverse ? end_p - len : start_p); + (p >= start_p) && (p + len <= end_p); p += sign) { Py_ssize_t i; for (i = 0; i < len && needle[i] == p[i]; ++i) /* nothing */; @@ -543,23 +543,21 @@ if ((size_t)(offset + size) > self->size) { PyErr_SetString(PyExc_ValueError, "flush values out of range"); return NULL; - } else { + } #ifdef MS_WINDOWS - return PyLong_FromLong((long) - FlushViewOfFile(self->data+offset, size)); -#endif /* MS_WINDOWS */ -#ifdef UNIX - /* XXX semantics of return value? */ - /* XXX flags for msync? */ - if (-1 == msync(self->data + offset, size, - MS_SYNC)) - { - PyErr_SetFromErrno(mmap_module_error); - return NULL; - } - return PyLong_FromLong(0); -#endif /* UNIX */ + return PyLong_FromLong((long) FlushViewOfFile(self->data+offset, size)); +#elif defined(UNIX) + /* XXX semantics of return value? */ + /* XXX flags for msync? */ + if (-1 == msync(self->data + offset, size, MS_SYNC)) { + PyErr_SetFromErrno(mmap_module_error); + return NULL; } + return PyLong_FromLong(0); +#else + PyErr_SetString(PyExc_ValueError, "flush not supported on this system"); + return NULL; +#endif } static PyObject * Modified: python/branches/py3k/Objects/dictobject.c ============================================================================== --- python/branches/py3k/Objects/dictobject.c (original) +++ python/branches/py3k/Objects/dictobject.c Sun Jan 27 16:18:18 2008 @@ -1379,7 +1379,7 @@ return -1; } mp = (PyDictObject*)a; - if (PyDict_CheckExact(b)) { + if (PyDict_Check(b)) { other = (PyDictObject*)b; if (other == mp || other->ma_used == 0) /* a.update(a) or a.update({}); nothing to do */ Modified: python/branches/py3k/Objects/genobject.c ============================================================================== --- python/branches/py3k/Objects/genobject.c (original) +++ python/branches/py3k/Objects/genobject.c Sun Jan 27 16:18:18 2008 @@ -11,6 +11,7 @@ gen_traverse(PyGenObject *gen, visitproc visit, void *arg) { Py_VISIT((PyObject *)gen->gi_frame); + Py_VISIT(gen->gi_code); return 0; } @@ -35,6 +36,7 @@ _PyObject_GC_UNTRACK(self); Py_CLEAR(gen->gi_frame); + Py_CLEAR(gen->gi_code); PyObject_GC_Del(gen); } @@ -283,6 +285,7 @@ static PyMemberDef gen_memberlist[] = { {"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY}, {"gi_running", T_INT, offsetof(PyGenObject, gi_running), READONLY}, + {"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY}, {NULL} /* Sentinel */ }; @@ -353,6 +356,8 @@ return NULL; } gen->gi_frame = f; + Py_INCREF(f->f_code); + gen->gi_code = (PyObject *)(f->f_code); gen->gi_running = 0; gen->gi_weakreflist = NULL; _PyObject_GC_TRACK(gen); Modified: python/branches/py3k/Objects/listobject.c ============================================================================== --- python/branches/py3k/Objects/listobject.c (original) +++ python/branches/py3k/Objects/listobject.c Sun Jan 27 16:18:18 2008 @@ -466,7 +466,7 @@ if (n && size/n != Py_SIZE(a)) return PyErr_NoMemory(); if (size == 0) - return PyList_New(0); + return PyList_New(0); np = (PyListObject *) PyList_New(size); if (np == NULL) return NULL; @@ -633,11 +633,11 @@ list_inplace_repeat(PyListObject *self, Py_ssize_t n) { PyObject **items; - Py_ssize_t size, i, j, p, newsize; + Py_ssize_t size, i, j, p; size = PyList_GET_SIZE(self); - if (size == 0) { + if (size == 0 || n == 1) { Py_INCREF(self); return (PyObject *)self; } @@ -648,10 +648,11 @@ return (PyObject *)self; } - newsize = size * n; - if (newsize/n != size) + if (size > PY_SSIZE_T_MAX / n) { return PyErr_NoMemory(); - if (list_resize(self, newsize) == -1) + } + + if (list_resize(self, size*n) == -1) return NULL; p = size; Modified: python/branches/py3k/Objects/setobject.c ============================================================================== --- python/branches/py3k/Objects/setobject.c (original) +++ python/branches/py3k/Objects/setobject.c Sun Jan 27 16:18:18 2008 @@ -904,7 +904,7 @@ { PyObject *key, *it; - if (PyAnySet_CheckExact(other)) + if (PyAnySet_Check(other)) return set_merge(so, other); if (PyDict_CheckExact(other)) { @@ -1199,7 +1199,7 @@ if (result == NULL) return NULL; - if (PyAnySet_CheckExact(other)) { + if (PyAnySet_Check(other)) { Py_ssize_t pos = 0; setentry *entry; @@ -1390,7 +1390,7 @@ if ((PyObject *)so == other) return set_clear_internal(so); - if (PyAnySet_CheckExact(other)) { + if (PyAnySet_Check(other)) { setentry *entry; Py_ssize_t pos = 0; @@ -1439,7 +1439,7 @@ setentry *entry; Py_ssize_t pos = 0; - if (!PyAnySet_CheckExact(other) && !PyDict_CheckExact(other)) { + if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) { result = set_copy(so); if (result == NULL) return NULL; @@ -1546,7 +1546,7 @@ Py_RETURN_NONE; } - if (PyAnySet_CheckExact(other)) { + if (PyAnySet_Check(other)) { Py_INCREF(other); otherset = (PySetObject *)other; } else { @@ -1629,7 +1629,7 @@ setentry *entry; Py_ssize_t pos = 0; - if (!PyAnySet_CheckExact(other)) { + if (!PyAnySet_Check(other)) { PyObject *tmp, *result; tmp = make_new_set(&PySet_Type, other); if (tmp == NULL) @@ -1658,7 +1658,7 @@ { PyObject *tmp, *result; - if (!PyAnySet_CheckExact(other)) { + if (!PyAnySet_Check(other)) { tmp = make_new_set(&PySet_Type, other); if (tmp == NULL) return NULL; Modified: python/branches/py3k/setup.py ============================================================================== --- python/branches/py3k/setup.py (original) +++ python/branches/py3k/setup.py Sun Jan 27 16:18:18 2008 @@ -4,6 +4,7 @@ __version__ = "$Revision$" import sys, os, imp, re, optparse +from glob import glob from distutils import log from distutils import sysconfig @@ -142,12 +143,20 @@ self.distribution.scripts = [os.path.join(srcdir, filename) for filename in self.distribution.scripts] + # Python header files + headers = glob("Include/*.h") + ["pyconfig.h"] + for ext in self.extensions[:]: ext.sources = [ find_module_file(filename, moddirlist) for filename in ext.sources ] if ext.depends is not None: ext.depends = [find_module_file(filename, alldirlist) for filename in ext.depends] + else: + ext.depends = [] + # re-compile extensions if a header file has been changed + ext.depends.extend(headers) + ext.include_dirs.append( '.' ) # to get config.h for incdir in incdirlist: ext.include_dirs.append( os.path.join(srcdir, incdir) ) From python-3000-checkins at python.org Sun Jan 27 16:19:17 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Sun, 27 Jan 2008 16:19:17 +0100 (CET) Subject: [Python-3000-checkins] r60351 - python/branches/py3k/Lib/plistlib.py Message-ID: <20080127151917.9CBEE1E4003@bag.python.org> Author: christian.heimes Date: Sun Jan 27 16:19:17 2008 New Revision: 60351 Removed: python/branches/py3k/Lib/plistlib.py Log: Remove plistlib. Apparently svn chokes on svn rm + svn cp in the same revision Deleted: /python/branches/py3k/Lib/plistlib.py ============================================================================== --- /python/branches/py3k/Lib/plistlib.py Sun Jan 27 16:19:17 2008 +++ (empty file) @@ -1,469 +0,0 @@ -"""plistlib.py -- a tool to generate and parse MacOSX .plist files. - -The PropertList (.plist) file format is a simple XML pickle supporting -basic object types, like dictionaries, lists, numbers and strings. -Usually the top level object is a dictionary. - -To write out a plist file, use the writePlist(rootObject, pathOrFile) -function. 'rootObject' is the top level object, 'pathOrFile' is a -filename or a (writable) file object. - -To parse a plist from a file, use the readPlist(pathOrFile) function, -with a file name or a (readable) file object as the only argument. It -returns the top level object (again, usually a dictionary). - -To work with plist data in bytes objects, you can use readPlistFromBytes() -and writePlistToBytes(). - -Values can be strings, integers, floats, booleans, tuples, lists, -dictionaries, Data or datetime.datetime objects. String values (including -dictionary keys) may be unicode strings -- they will be written out as -UTF-8. - -The plist type is supported through the Data class. This is a -thin wrapper around a Python bytes object. - -Generate Plist example: - - pl = dict( - aString="Doodah", - aList=["A", "B", 12, 32.1, [1, 2, 3]], - aFloat = 0.1, - anInt = 728, - aDict=dict( - anotherString="", - aUnicodeValue=u'M\xe4ssig, Ma\xdf', - aTrueValue=True, - aFalseValue=False, - ), - someData = Data(b""), - someMoreData = Data(b"" * 10), - aDate = datetime.datetime.fromtimestamp(time.mktime(time.gmtime())), - ) - # unicode keys are possible, but a little awkward to use: - pl[u'\xc5benraa'] = "That was a unicode key." - writePlist(pl, fileName) - -Parse Plist example: - - pl = readPlist(pathOrFile) - print pl["aKey"] -""" - - -__all__ = [ - "readPlist", "writePlist", "readPlistFromBytes", "writePlistToBytes", - "readPlistFromResource", "writePlistToResource", - "Plist", "Data", "Dict" -] -# Note: the Plist and Dict classes have been deprecated. - -import binascii -import datetime -from io import BytesIO -import re - - -def readPlist(pathOrFile): - """Read a .plist file. 'pathOrFile' may either be a file name or a - (readable) file object. Return the unpacked root object (which - usually is a dictionary). - """ - didOpen = False - if isinstance(pathOrFile, str): - pathOrFile = open(pathOrFile, 'rb') - didOpen = True - p = PlistParser() - rootObject = p.parse(pathOrFile) - if didOpen: - pathOrFile.close() - return rootObject - - -def writePlist(rootObject, pathOrFile): - """Write 'rootObject' to a .plist file. 'pathOrFile' may either be a - file name or a (writable) file object. - """ - didOpen = False - if isinstance(pathOrFile, str): - pathOrFile = open(pathOrFile, 'wb') - didOpen = True - writer = PlistWriter(pathOrFile) - writer.writeln("") - writer.writeValue(rootObject) - writer.writeln("") - if didOpen: - pathOrFile.close() - - -def readPlistFromBytes(data): - """Read a plist data from a bytes object. Return the root object. - """ - return readPlist(BytesIO(data)) - - -def writePlistToBytes(rootObject): - """Return 'rootObject' as a plist-formatted bytes object. - """ - f = BytesIO() - writePlist(rootObject, f) - return f.getvalue() - - -def readPlistFromResource(path, restype='plst', resid=0): - """Read plst resource from the resource fork of path. - """ - from Carbon.File import FSRef, FSGetResourceForkName - from Carbon.Files import fsRdPerm - from Carbon import Res - fsRef = FSRef(path) - resNum = Res.FSOpenResourceFile(fsRef, FSGetResourceForkName(), fsRdPerm) - Res.UseResFile(resNum) - plistData = Res.Get1Resource(restype, resid).data - Res.CloseResFile(resNum) - return readPlistFromString(plistData) - - -def writePlistToResource(rootObject, path, restype='plst', resid=0): - """Write 'rootObject' as a plst resource to the resource fork of path. - """ - from Carbon.File import FSRef, FSGetResourceForkName - from Carbon.Files import fsRdWrPerm - from Carbon import Res - plistData = writePlistToString(rootObject) - fsRef = FSRef(path) - resNum = Res.FSOpenResourceFile(fsRef, FSGetResourceForkName(), fsRdWrPerm) - Res.UseResFile(resNum) - try: - Res.Get1Resource(restype, resid).RemoveResource() - except Res.Error: - pass - res = Res.Resource(plistData) - res.AddResource(restype, resid, '') - res.WriteResource() - Res.CloseResFile(resNum) - - -class DumbXMLWriter: - def __init__(self, file, indentLevel=0, indent="\t"): - self.file = file - self.stack = [] - self.indentLevel = indentLevel - self.indent = indent - - def beginElement(self, element): - self.stack.append(element) - self.writeln("<%s>" % element) - self.indentLevel += 1 - - def endElement(self, element): - assert self.indentLevel > 0 - assert self.stack.pop() == element - self.indentLevel -= 1 - self.writeln("" % element) - - def simpleElement(self, element, value=None): - if value is not None: - value = _escape(value) - self.writeln("<%s>%s" % (element, value, element)) - else: - self.writeln("<%s/>" % element) - - def writeln(self, line): - if line: - # plist has fixed encoding of utf-8 - if isinstance(line, str): - line = line.encode('utf-8') - self.file.write(self.indentLevel * self.indent) - self.file.write(line) - self.file.write(b'\n') - - -# Contents should conform to a subset of ISO 8601 -# (in particular, YYYY '-' MM '-' DD 'T' HH ':' MM ':' SS 'Z'. Smaller units may be omitted with -# a loss of precision) -_dateParser = re.compile(r"(?P\d\d\d\d)(?:-(?P\d\d)(?:-(?P\d\d)(?:T(?P\d\d)(?::(?P\d\d)(?::(?P\d\d))?)?)?)?)?Z") - -def _dateFromString(s): - order = ('year', 'month', 'day', 'hour', 'minute', 'second') - gd = _dateParser.match(s).groupdict() - lst = [] - for key in order: - val = gd[key] - if val is None: - break - lst.append(int(val)) - return datetime.datetime(*lst) - -def _dateToString(d): - return '%04d-%02d-%02dT%02d:%02d:%02dZ' % ( - d.year, d.month, d.day, - d.hour, d.minute, d.second - ) - - -# Regex to find any control chars, except for \t \n and \r -_controlCharPat = re.compile( - r"[\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0b\x0c\x0e\x0f" - r"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f]") - -def _escape(text): - m = _controlCharPat.search(text) - if m is not None: - raise ValueError("strings can't contains control characters; " - "use plistlib.Data instead") - text = text.replace("\r\n", "\n") # convert DOS line endings - text = text.replace("\r", "\n") # convert Mac line endings - text = text.replace("&", "&") # escape '&' - text = text.replace("<", "<") # escape '<' - text = text.replace(">", ">") # escape '>' - return text - - -PLISTHEADER = b"""\ - - -""" - -class PlistWriter(DumbXMLWriter): - - def __init__(self, file, indentLevel=0, indent=b"\t", writeHeader=1): - if writeHeader: - file.write(PLISTHEADER) - DumbXMLWriter.__init__(self, file, indentLevel, indent) - - def writeValue(self, value): - if isinstance(value, str): - self.simpleElement("string", value) - elif isinstance(value, bool): - # must switch for bool before int, as bool is a - # subclass of int... - if value: - self.simpleElement("true") - else: - self.simpleElement("false") - elif isinstance(value, int): - self.simpleElement("integer", "%d" % value) - elif isinstance(value, float): - self.simpleElement("real", repr(value)) - elif isinstance(value, dict): - self.writeDict(value) - elif isinstance(value, Data): - self.writeData(value) - elif isinstance(value, datetime.datetime): - self.simpleElement("date", _dateToString(value)) - elif isinstance(value, (tuple, list)): - self.writeArray(value) - else: - raise TypeError("unsuported type: %s" % type(value)) - - def writeData(self, data): - self.beginElement("data") - self.indentLevel -= 1 - maxlinelength = 76 - len(self.indent.replace(b"\t", b" " * 8) * - self.indentLevel) - for line in data.asBase64(maxlinelength).split(b"\n"): - if line: - self.writeln(line) - self.indentLevel += 1 - self.endElement("data") - - def writeDict(self, d): - self.beginElement("dict") - items = sorted(d.items()) - for key, value in items: - if not isinstance(key, str): - raise TypeError("keys must be strings") - self.simpleElement("key", key) - self.writeValue(value) - self.endElement("dict") - - def writeArray(self, array): - self.beginElement("array") - for value in array: - self.writeValue(value) - self.endElement("array") - - -class _InternalDict(dict): - - # This class is needed while Dict is scheduled for deprecation: - # we only need to warn when a *user* instantiates Dict or when - # the "attribute notation for dict keys" is used. - - def __getattr__(self, attr): - try: - value = self[attr] - except KeyError: - raise AttributeError(attr) - from warnings import warn - warn("Attribute access from plist dicts is deprecated, use d[key] " - "notation instead", PendingDeprecationWarning) - return value - - def __setattr__(self, attr, value): - from warnings import warn - warn("Attribute access from plist dicts is deprecated, use d[key] " - "notation instead", PendingDeprecationWarning) - self[attr] = value - - def __delattr__(self, attr): - try: - del self[attr] - except KeyError: - raise AttributeError(attr) - from warnings import warn - warn("Attribute access from plist dicts is deprecated, use d[key] " - "notation instead", PendingDeprecationWarning) - -class Dict(_InternalDict): - - def __init__(self, **kwargs): - from warnings import warn - warn("The plistlib.Dict class is deprecated, use builtin dict instead", - PendingDeprecationWarning) - super().__init__(**kwargs) - - -class Plist(_InternalDict): - - """This class has been deprecated. Use readPlist() and writePlist() - functions instead, together with regular dict objects. - """ - - def __init__(self, **kwargs): - from warnings import warn - warn("The Plist class is deprecated, use the readPlist() and " - "writePlist() functions instead", PendingDeprecationWarning) - super().__init__(**kwargs) - - def fromFile(cls, pathOrFile): - """Deprecated. Use the readPlist() function instead.""" - rootObject = readPlist(pathOrFile) - plist = cls() - plist.update(rootObject) - return plist - fromFile = classmethod(fromFile) - - def write(self, pathOrFile): - """Deprecated. Use the writePlist() function instead.""" - writePlist(self, pathOrFile) - - -def _encodeBase64(s, maxlinelength=76): - # copied from base64.encodestring(), with added maxlinelength argument - maxbinsize = (maxlinelength//4)*3 - pieces = [] - for i in range(0, len(s), maxbinsize): - chunk = s[i : i + maxbinsize] - pieces.append(binascii.b2a_base64(chunk)) - return b''.join(pieces) - -class Data: - - """Wrapper for binary data.""" - - def __init__(self, data): - if not isinstance(data, bytes): - raise TypeError("data must be as bytes") - self.data = data - - @classmethod - def fromBase64(cls, data): - # base64.decodestring just calls binascii.a2b_base64; - # it seems overkill to use both base64 and binascii. - return cls(binascii.a2b_base64(data)) - - def asBase64(self, maxlinelength=76): - return _encodeBase64(self.data, maxlinelength) - - def __eq__(self, other): - if isinstance(other, self.__class__): - return self.data == other.data - elif isinstance(other, str): - return self.data == other - else: - return id(self) == id(other) - - def __repr__(self): - return "%s(%s)" % (self.__class__.__name__, repr(self.data)) - - -class PlistParser: - - def __init__(self): - self.stack = [] - self.currentKey = None - self.root = None - - def parse(self, fileobj): - from xml.parsers.expat import ParserCreate - parser = ParserCreate() - parser.StartElementHandler = self.handleBeginElement - parser.EndElementHandler = self.handleEndElement - parser.CharacterDataHandler = self.handleData - parser.ParseFile(fileobj) - return self.root - - def handleBeginElement(self, element, attrs): - self.data = [] - handler = getattr(self, "begin_" + element, None) - if handler is not None: - handler(attrs) - - def handleEndElement(self, element): - handler = getattr(self, "end_" + element, None) - if handler is not None: - handler() - - def handleData(self, data): - self.data.append(data) - - def addObject(self, value): - if self.currentKey is not None: - self.stack[-1][self.currentKey] = value - self.currentKey = None - elif not self.stack: - # this is the root object - self.root = value - else: - self.stack[-1].append(value) - - def getData(self): - data = ''.join(self.data) - self.data = [] - return data - - # element handlers - - def begin_dict(self, attrs): - d = _InternalDict() - self.addObject(d) - self.stack.append(d) - def end_dict(self): - self.stack.pop() - - def end_key(self): - self.currentKey = self.getData() - - def begin_array(self, attrs): - a = [] - self.addObject(a) - self.stack.append(a) - def end_array(self): - self.stack.pop() - - def end_true(self): - self.addObject(True) - def end_false(self): - self.addObject(False) - def end_integer(self): - self.addObject(int(self.getData())) - def end_real(self): - self.addObject(float(self.getData())) - def end_string(self): - self.addObject(self.getData()) - def end_data(self): - self.addObject(Data.fromBase64(self.getData().encode("utf-8"))) - def end_date(self): - self.addObject(_dateFromString(self.getData())) From python-3000-checkins at python.org Sun Jan 27 16:20:13 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Sun, 27 Jan 2008 16:20:13 +0100 (CET) Subject: [Python-3000-checkins] r60352 - python/branches/py3k/Lib/plistlib.py Message-ID: <20080127152013.8D4E51E4003@bag.python.org> Author: christian.heimes Date: Sun Jan 27 16:20:13 2008 New Revision: 60352 Added: python/branches/py3k/Lib/plistlib.py - copied unchanged from r60150, python/branches/py3k/Lib/plat-mac/plistlib.py Log: svn cp -r60150 svn+ssh://pythondev at svn.python.org/python/branches/py3k/Lib/plat-mac/plistlib.py Lib/ From python-3000-checkins at python.org Sun Jan 27 16:45:24 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Sun, 27 Jan 2008 16:45:24 +0100 (CET) Subject: [Python-3000-checkins] r60353 - python/branches/py3k/Lib/test/test_urllibnet.py Message-ID: <20080127154524.8CD6A1E400A@bag.python.org> Author: christian.heimes Date: Sun Jan 27 16:45:24 2008 New Revision: 60353 Modified: python/branches/py3k/Lib/test/test_urllibnet.py Log: Fixed test_urllibnet Modified: python/branches/py3k/Lib/test/test_urllibnet.py ============================================================================== --- python/branches/py3k/Lib/test/test_urllibnet.py (original) +++ python/branches/py3k/Lib/test/test_urllibnet.py Sun Jan 27 16:45:24 2008 @@ -13,10 +13,12 @@ def _open_with_retry(func, host, *args, **kwargs): # Connecting to remote hosts is flaky. Make it more robust # by retrying the connection several times. + last_exc = None for i in range(3): try: return func(host, *args, **kwargs) - except IOError, last_exc: + except IOError as err: + last_exc = err continue except: raise From python-3000-checkins at python.org Sun Jan 27 17:16:19 2008 From: python-3000-checkins at python.org (alexandre.vassalotti) Date: Sun, 27 Jan 2008 17:16:19 +0100 (CET) Subject: [Python-3000-checkins] r60354 - python/branches/py3k/Lib/glob.py Message-ID: <20080127161619.7BED61E4018@bag.python.org> Author: alexandre.vassalotti Date: Sun Jan 27 17:16:19 2008 New Revision: 60354 Modified: python/branches/py3k/Lib/glob.py Log: Fix build error. Use a list comprehension instead of filter(), since filter() needs the itertools module which isn't available at build time. Modified: python/branches/py3k/Lib/glob.py ============================================================================== --- python/branches/py3k/Lib/glob.py (original) +++ python/branches/py3k/Lib/glob.py Sun Jan 27 17:16:19 2008 @@ -57,7 +57,7 @@ except os.error: return [] if pattern[0] != '.': - names = filter(lambda x: x[0] != '.', names) + names = [x for x in names if x[0] != '.'] return fnmatch.filter(names, pattern) def glob0(dirname, basename): From python-3000-checkins at python.org Sun Jan 27 19:16:00 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sun, 27 Jan 2008 19:16:00 +0100 (CET) Subject: [Python-3000-checkins] r60366 - python/branches/py3k/Lib/pydoc.py Message-ID: <20080127181600.D506E1E400B@bag.python.org> Author: georg.brandl Date: Sun Jan 27 19:16:00 2008 New Revision: 60366 Modified: python/branches/py3k/Lib/pydoc.py Log: Use a list comprehension instead of list(filter()). Modified: python/branches/py3k/Lib/pydoc.py ============================================================================== --- python/branches/py3k/Lib/pydoc.py (original) +++ python/branches/py3k/Lib/pydoc.py Sun Jan 27 19:16:00 2008 @@ -1983,9 +1983,8 @@ '#ffffff', '#7799ee') def bltinlink(name): return '%s' % (name, name) - names = filter(lambda x: x != '__main__', - sys.builtin_module_names) - contents = html.multicolumn(list(names), bltinlink) + names = [x for x in sys.builtin_module_names if x != '__main__'] + contents = html.multicolumn(names, bltinlink) indices = ['

' + html.bigsection( 'Built-in Modules', '#ffffff', '#ee77aa', contents)] From python-3000-checkins at python.org Sun Jan 27 19:55:54 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Sun, 27 Jan 2008 19:55:54 +0100 (CET) Subject: [Python-3000-checkins] r60369 - in python/branches/py3k: Lib/test/test_bsddb3.py Lib/test/test_resource.py Lib/test/test_xmlrpc.py Modules/_ctypes/libffi/src/alpha/ffi.c Modules/_ctypes/libffi/src/alpha/osf.S Modules/_ssl.c Objects/typeobject.c Parser/tokenizer.c Python/ceval.c Message-ID: <20080127185554.E1F181E4025@bag.python.org> Author: christian.heimes Date: Sun Jan 27 19:55:54 2008 New Revision: 60369 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_bsddb3.py python/branches/py3k/Lib/test/test_resource.py python/branches/py3k/Lib/test/test_xmlrpc.py python/branches/py3k/Modules/_ctypes/libffi/src/alpha/ffi.c python/branches/py3k/Modules/_ctypes/libffi/src/alpha/osf.S python/branches/py3k/Modules/_ssl.c python/branches/py3k/Objects/typeobject.c python/branches/py3k/Parser/tokenizer.c python/branches/py3k/Python/ceval.c Log: Merged revisions 60350-60363 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60355 | neal.norwitz | 2008-01-27 18:10:14 +0100 (Sun, 27 Jan 2008) | 1 line Whitespace cleanup ........ r60356 | neal.norwitz | 2008-01-27 18:10:29 +0100 (Sun, 27 Jan 2008) | 1 line Add assertion that we do not blow out newl ........ r60357 | neal.norwitz | 2008-01-27 18:10:35 +0100 (Sun, 27 Jan 2008) | 1 line Initialize variable to prevent warning on some platform/config. ........ r60358 | neal.norwitz | 2008-01-27 18:10:43 +0100 (Sun, 27 Jan 2008) | 1 line Update to newer version of ffi. Fixes crashes and test failures of longdouble ........ r60359 | neal.norwitz | 2008-01-27 18:10:50 +0100 (Sun, 27 Jan 2008) | 1 line Add a tiny sleep and additional flush to force the file to really be synced. ........ r60360 | neal.norwitz | 2008-01-27 18:10:58 +0100 (Sun, 27 Jan 2008) | 1 line Retry connection in case it fails to reduce flakiness ........ r60361 | neal.norwitz | 2008-01-27 18:11:11 +0100 (Sun, 27 Jan 2008) | 4 lines Catch socket errors that are often the cause of transient failures. Many of these exceptions are due to resource unavailable, so the existing code should be able to handle many more spurious errors. ........ r60362 | neal.norwitz | 2008-01-27 18:12:15 +0100 (Sun, 27 Jan 2008) | 1 line Reduce buffer size since we do not need 1k ........ r60363 | neal.norwitz | 2008-01-27 18:13:07 +0100 (Sun, 27 Jan 2008) | 1 line Print periodic "still working" messages since this suite is slow. ........ Modified: python/branches/py3k/Lib/test/test_bsddb3.py ============================================================================== --- python/branches/py3k/Lib/test/test_bsddb3.py (original) +++ python/branches/py3k/Lib/test/test_bsddb3.py Sun Jan 27 19:55:54 2008 @@ -3,6 +3,7 @@ Run all test cases. """ import sys +import time import unittest import test.test_support from test.test_support import requires, run_unittest, unlink @@ -22,6 +23,30 @@ sys.argv.remove('silent') +class TimingCheck(unittest.TestCase): + + """This class is not a real test. Its purpose is to print a message + periodically when the test runs slowly. This will prevent the buildbots + from timing out on slow machines.""" + + # How much time in seconds before printing a 'Still working' message. + # Since this is run at most once between each test module, use a smaller + # interval than other tests. + _PRINT_WORKING_MSG_INTERVAL = 4 * 60 + + # next_time is used as a global variable that survives each instance. + # This is necessary since a new instance will be created for each test. + next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL + + def testCheckElapsedTime(self): + # Print still working message since these tests can be really slow. + now = time.time() + if self.next_time <= now: + TimingCheck.next_time = now + self._PRINT_WORKING_MSG_INTERVAL + sys.__stdout__.write(' test_bsddb3 still working, be patient...\n') + sys.__stdout__.flush() + + def suite(): try: # this is special, it used to segfault the interpreter @@ -56,6 +81,7 @@ module = __import__("bsddb.test."+name, globals(), locals(), name) #print module,name alltests.addTest(module.test_suite()) + alltests.addTest(unittest.makeSuite(TimingCheck)) return alltests Modified: python/branches/py3k/Lib/test/test_resource.py ============================================================================== --- python/branches/py3k/Lib/test/test_resource.py (original) +++ python/branches/py3k/Lib/test/test_resource.py Sun Jan 27 19:55:54 2008 @@ -1,8 +1,9 @@ import unittest from test import test_support - -import os, resource +import os +import resource +import time # This test is checking a few specific problem spots with the resource module. @@ -59,6 +60,8 @@ # an attempt to ensure the file is really synced and # the exception raised. for i in range(5): + time.sleep(.1) + f.flush() f.close() except IOError: if not limit_set: Modified: python/branches/py3k/Lib/test/test_xmlrpc.py ============================================================================== --- python/branches/py3k/Lib/test/test_xmlrpc.py (original) +++ python/branches/py3k/Lib/test/test_xmlrpc.py Sun Jan 27 19:55:54 2008 @@ -345,9 +345,11 @@ try: p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT) self.assertEqual(p.pow(6,8), 6**8) - except xmlrpclib.ProtocolError as e: - # protocol error; provide additional information in test output - self.fail("%s\n%s" % (e, e.headers)) + except (xmlrpclib.ProtocolError, socket.error) as e: + # ignore failures due to non-blocking socket 'unavailable' errors + if not is_unavailable_exception(e): + # protocol error; provide additional information in test output + self.fail("%s\n%s" % (e, e.headers)) # [ch] The test 404 is causing lots of false alarms. def XXXtest_404(self): @@ -369,9 +371,12 @@ 'system.listMethods', 'system.methodHelp', 'system.methodSignature', 'system.multicall']) self.assertEqual(set(meth), expected_methods) - except xmlrpclib.ProtocolError as e: - # protocol error; provide additional information in test output - self.fail("%s\n%s" % (e, e.headers)) + except (xmlrpclib.ProtocolError, socket.error) as e: + # ignore failures due to non-blocking socket 'unavailable' errors + if not is_unavailable_exception(e): + # protocol error; provide additional information in test output + self.fail("%s\n%s" % (e, e.headers)) + def test_introspection2(self): try: @@ -379,9 +384,11 @@ p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT) divhelp = p.system.methodHelp('div') self.assertEqual(divhelp, 'This is the div function') - except xmlrpclib.ProtocolError as e: - # protocol error; provide additional information in test output - self.fail("%s\n%s" % (e, e.headers)) + except (xmlrpclib.ProtocolError, socket.error) as e: + # ignore failures due to non-blocking socket 'unavailable' errors + if not is_unavailable_exception(e): + # protocol error; provide additional information in test output + self.fail("%s\n%s" % (e, e.headers)) def test_introspection3(self): try: @@ -389,7 +396,7 @@ p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT) myfunction = p.system.methodHelp('my_function') self.assertEqual(myfunction, 'This is my function') - except xmlrpclib.ProtocolError as e: + except (xmlrpclib.ProtocolError, socket.error) as e: # ignore failures due to non-blocking socket 'unavailable' errors if not is_unavailable_exception(e): # protocol error; provide additional information in test output @@ -402,9 +409,11 @@ p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT) divsig = p.system.methodSignature('div') self.assertEqual(divsig, 'signatures not supported') - except xmlrpclib.ProtocolError as e: - # protocol error; provide additional information in test output - self.fail("%s\n%s" % (e, e.headers)) + except (xmlrpclib.ProtocolError, socket.error) as e: + # ignore failures due to non-blocking socket 'unavailable' errors + if not is_unavailable_exception(e): + # protocol error; provide additional information in test output + self.fail("%s\n%s" % (e, e.headers)) def test_multicall(self): try: @@ -417,9 +426,11 @@ self.assertEqual(add_result, 2+3) self.assertEqual(pow_result, 6**8) self.assertEqual(div_result, 127//42) - except xmlrpclib.ProtocolError as e: - # protocol error; provide additional information in test output - self.fail("%s\n%s" % (e, e.headers)) + except (xmlrpclib.ProtocolError, socket.error) as e: + # ignore failures due to non-blocking socket 'unavailable' errors + if not is_unavailable_exception(e): + # protocol error; provide additional information in test output + self.fail("%s\n%s" % (e, e.headers)) def test_non_existing_multicall(self): try: @@ -436,7 +447,7 @@ self.assertEqual(result.results[0]['faultString'], ':method "this_is_not_exists" ' 'is not supported') - except xmlrpclib.ProtocolError as e: + except (xmlrpclib.ProtocolError, socket.error) as e: # ignore failures due to non-blocking socket 'unavailable' errors if not is_unavailable_exception(e): # protocol error; provide additional information in test output @@ -483,9 +494,11 @@ try: p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT) self.assertEqual(p.pow(6,8), 6**8) - except xmlrpclib.ProtocolError as e: - # protocol error; provide additional information in test output - self.fail("%s\n%s" % (e, e.headers)) + except (xmlrpclib.ProtocolError, socket.error) as e: + # ignore failures due to non-blocking socket 'unavailable' errors + if not is_unavailable_exception(e): + # protocol error; provide additional information in test output + self.fail("%s\n%s" % (e, e.headers)) def test_fail_no_info(self): # use the broken message class @@ -494,10 +507,12 @@ try: p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT) p.pow(6,8) - except xmlrpclib.ProtocolError as e: - # The two server-side error headers shouldn't be sent back in this case - self.assertTrue(e.headers.get("X-exception") is None) - self.assertTrue(e.headers.get("X-traceback") is None) + except (xmlrpclib.ProtocolError, socket.error) as e: + # ignore failures due to non-blocking socket 'unavailable' errors + if not is_unavailable_exception(e): + # The two server-side error headers shouldn't be sent back in this case + self.assertTrue(e.headers.get("X-exception") is None) + self.assertTrue(e.headers.get("X-traceback") is None) else: self.fail('ProtocolError not raised') @@ -512,11 +527,13 @@ try: p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT) p.pow(6,8) - except xmlrpclib.ProtocolError as e: - # We should get error info in the response - expected_err = "invalid literal for int() with base 10: 'I am broken'" - self.assertEqual(e.headers.get("x-exception"), expected_err) - self.assertTrue(e.headers.get("x-traceback") is not None) + except (xmlrpclib.ProtocolError, socket.error) as e: + # ignore failures due to non-blocking socket 'unavailable' errors + if not is_unavailable_exception(e): + # We should get error info in the response + expected_err = "invalid literal for int() with base 10: 'I am broken'" + self.assertEqual(e.headers.get("x-exception"), expected_err) + self.assertTrue(e.headers.get("x-traceback") is not None) else: self.fail('ProtocolError not raised') Modified: python/branches/py3k/Modules/_ctypes/libffi/src/alpha/ffi.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/libffi/src/alpha/ffi.c (original) +++ python/branches/py3k/Modules/_ctypes/libffi/src/alpha/ffi.c Sun Jan 27 19:55:54 2008 @@ -25,11 +25,22 @@ #include #include - #include -extern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)(void)); -extern void ffi_closure_osf(void); +/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE; + all further uses in this file will refer to the 128-bit type. */ +#if defined(__LONG_DOUBLE_128__) +# if FFI_TYPE_LONGDOUBLE != 4 +# error FFI_TYPE_LONGDOUBLE out of date +# endif +#else +# undef FFI_TYPE_LONGDOUBLE +# define FFI_TYPE_LONGDOUBLE 4 +#endif + +extern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)(void)) + FFI_HIDDEN; +extern void ffi_closure_osf(void) FFI_HIDDEN; ffi_status @@ -49,6 +60,11 @@ cif->flags = cif->rtype->type; break; + case FFI_TYPE_LONGDOUBLE: + /* 128-bit long double is returned in memory, like a struct. */ + cif->flags = FFI_TYPE_STRUCT; + break; + default: cif->flags = FFI_TYPE_INT; break; @@ -57,6 +73,7 @@ return FFI_OK; } + void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) { @@ -64,8 +81,6 @@ long i, avn; ffi_type **arg_types; - FFI_ASSERT (cif->abi == FFI_OSF); - /* If the return value is a struct and we don't have a return value address then we need to make one. */ if (rvalue == NULL && cif->flags == FFI_TYPE_STRUCT) @@ -84,6 +99,8 @@ while (i < avn) { + size_t size = (*arg_types)->size; + switch ((*arg_types)->type) { case FFI_TYPE_SINT8: @@ -129,6 +146,12 @@ *(double *) argp = *(double *)(* avalue); break; + case FFI_TYPE_LONGDOUBLE: + /* 128-bit long double is passed by reference. */ + *(long double **) argp = (long double *)(* avalue); + size = sizeof (long double *); + break; + case FFI_TYPE_STRUCT: memcpy(argp, *avalue, (*arg_types)->size); break; @@ -137,7 +160,7 @@ FFI_ASSERT(0); } - argp += ALIGN((*arg_types)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; + argp += ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; i++, arg_types++, avalue++; } @@ -153,8 +176,6 @@ { unsigned int *tramp; - FFI_ASSERT (cif->abi == FFI_OSF); - tramp = (unsigned int *) &closure->tramp[0]; tramp[0] = 0x47fb0401; /* mov $27,$1 */ tramp[1] = 0xa77b0010; /* ldq $27,16($27) */ @@ -177,7 +198,8 @@ return FFI_OK; } -int + +long FFI_HIDDEN ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp) { ffi_cif *cif; @@ -205,6 +227,8 @@ /* Grab the addresses of the arguments from the stack frame. */ while (i < avn) { + size_t size = arg_types[i]->size; + switch (arg_types[i]->type) { case FFI_TYPE_SINT8: @@ -236,16 +260,22 @@ avalue[i] = &argp[argn - (argn < 6 ? 6 : 0)]; break; + case FFI_TYPE_LONGDOUBLE: + /* 128-bit long double is passed by reference. */ + avalue[i] = (long double *) argp[argn]; + size = sizeof (long double *); + break; + default: - FFI_ASSERT(0); + abort (); } - argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; + argn += ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; i++; } /* Invoke the closure. */ - (closure->fun) (cif, rvalue, avalue, closure->user_data); + closure->fun (cif, rvalue, avalue, closure->user_data); /* Tell ffi_closure_osf how to perform return type promotions. */ return cif->rtype->type; Modified: python/branches/py3k/Modules/_ctypes/libffi/src/alpha/osf.S ============================================================================== --- python/branches/py3k/Modules/_ctypes/libffi/src/alpha/osf.S (original) +++ python/branches/py3k/Modules/_ctypes/libffi/src/alpha/osf.S Sun Jan 27 19:55:54 2008 @@ -1,10 +1,8 @@ /* ----------------------------------------------------------------------- - osf.S - Copyright (c) 1998, 2001 Red Hat + osf.S - Copyright (c) 1998, 2001, 2007 Red Hat Alpha/OSF Foreign Function Interface - $Id: osf.S,v 1.2 2006/03/03 20:24:26 theller Exp $ - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including @@ -42,6 +40,8 @@ .align 3 .globl ffi_call_osf .ent ffi_call_osf + FFI_HIDDEN(ffi_call_osf) + ffi_call_osf: .frame $15, 32, $26, 0 .mask 0x4008000, -32 @@ -129,6 +129,8 @@ .align 3 .globl ffi_closure_osf .ent ffi_closure_osf + FFI_HIDDEN(ffi_closure_osf) + ffi_closure_osf: .frame $30, 16*8, $26, 0 .mask 0x4000000, -16*8 @@ -265,7 +267,7 @@ .gprel32 $load_32 # FFI_TYPE_INT .gprel32 $load_float # FFI_TYPE_FLOAT .gprel32 $load_double # FFI_TYPE_DOUBLE - .gprel32 $load_double # FFI_TYPE_LONGDOUBLE + .gprel32 $load_none # FFI_TYPE_LONGDOUBLE .gprel32 $load_u8 # FFI_TYPE_UINT8 .gprel32 $load_s8 # FFI_TYPE_SINT8 .gprel32 $load_u16 # FFI_TYPE_UINT16 Modified: python/branches/py3k/Modules/_ssl.c ============================================================================== --- python/branches/py3k/Modules/_ssl.c (original) +++ python/branches/py3k/Modules/_ssl.c Sun Jan 27 19:55:54 2008 @@ -684,7 +684,7 @@ } p = ext->value->data; - if(method->it) + if (method->it) names = (GENERAL_NAMES*) (ASN1_item_d2i(NULL, &p, Modified: python/branches/py3k/Objects/typeobject.c ============================================================================== --- python/branches/py3k/Objects/typeobject.c (original) +++ python/branches/py3k/Objects/typeobject.c Sun Jan 27 19:55:54 2008 @@ -59,7 +59,7 @@ PyObject *raw, *ref; Py_ssize_t i, n; - if(!PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)) + if (!PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)) return; raw = type->tp_subclasses; @@ -95,7 +95,7 @@ Py_ssize_t i, n; int clear = 0; - if(!PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG)) + if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG)) return; n = PyTuple_GET_SIZE(bases); @@ -1342,8 +1342,8 @@ PyObject *bases, *result; PyObject *to_merge, *bases_aslist; - if(type->tp_dict == NULL) { - if(PyType_Ready(type) < 0) + if (type->tp_dict == NULL) { + if (PyType_Ready(type) < 0) return NULL; } @@ -2204,7 +2204,7 @@ unsigned int h; if (MCACHE_CACHEABLE_NAME(name) && - PyType_HasFeature(type,Py_TPFLAGS_VALID_VERSION_TAG)) { + PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)) { /* fast path */ h = MCACHE_HASH_METHOD(type, name); if (method_cache[h].version == type->tp_version_tag && Modified: python/branches/py3k/Parser/tokenizer.c ============================================================================== --- python/branches/py3k/Parser/tokenizer.c (original) +++ python/branches/py3k/Parser/tokenizer.c Sun Jan 27 19:55:54 2008 @@ -657,6 +657,7 @@ for (s = str;; s++) { if (*s == '\0') break; else if (*s == '\n') { + assert(lineno < 2); newl[lineno] = s; lineno++; if (lineno == 2) break; Modified: python/branches/py3k/Python/ceval.c ============================================================================== --- python/branches/py3k/Python/ceval.c (original) +++ python/branches/py3k/Python/ceval.c Sun Jan 27 19:55:54 2008 @@ -2288,7 +2288,7 @@ else { /* This check is expensive! */ if (PyErr_Occurred()) { - char buf[1024]; + char buf[128]; sprintf(buf, "Stack unwind with exception " "set and why=%d", why); Py_FatalError(buf); From python-3000-checkins at python.org Sun Jan 27 22:07:59 2008 From: python-3000-checkins at python.org (eric.smith) Date: Sun, 27 Jan 2008 22:07:59 +0100 (CET) Subject: [Python-3000-checkins] r60376 - in python/branches/py3k: Lib/test/test_float.py Lib/test/test_long.py Objects/stringlib/formatter.h Message-ID: <20080127210759.A620F1E4014@bag.python.org> Author: eric.smith Date: Sun Jan 27 22:07:59 2008 New Revision: 60376 Modified: python/branches/py3k/Lib/test/test_float.py python/branches/py3k/Lib/test/test_long.py python/branches/py3k/Objects/stringlib/formatter.h Log: Restrict format presentation types to those specified in the 'Standard Format Specifiers' section of PEP 3101. Modified: python/branches/py3k/Lib/test/test_float.py ============================================================================== --- python/branches/py3k/Lib/test/test_float.py (original) +++ python/branches/py3k/Lib/test/test_float.py Sun Jan 27 22:07:59 2008 @@ -133,13 +133,10 @@ self.assertEqual(format(0.01, ''), '0.01') self.assertEqual(format(0.01, 'g'), '0.01') - self.assertEqual(format(0, 'f'), '0.000000') self.assertEqual(format(1.0, 'f'), '1.000000') - self.assertEqual(format(1, 'f'), '1.000000') self.assertEqual(format(-1.0, 'f'), '-1.000000') - self.assertEqual(format(-1, 'f'), '-1.000000') self.assertEqual(format( 1.0, ' f'), ' 1.000000') self.assertEqual(format(-1.0, ' f'), '-1.000000') @@ -152,6 +149,18 @@ # conversion to string should fail self.assertRaises(ValueError, format, 3.0, "s") + # other format specifiers shouldn't work on floats, + # in particular int specifiers + for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] + + [chr(x) for x in range(ord('A'), ord('Z')+1)]): + if not format_spec in 'eEfFgGn%': + self.assertRaises(ValueError, format, 0.0, format_spec) + self.assertRaises(ValueError, format, 1.0, format_spec) + self.assertRaises(ValueError, format, -1.0, format_spec) + self.assertRaises(ValueError, format, 1e100, format_spec) + self.assertRaises(ValueError, format, -1e100, format_spec) + self.assertRaises(ValueError, format, 1e-100, format_spec) + self.assertRaises(ValueError, format, -1e-100, format_spec) class ReprTestCase(unittest.TestCase): def test_repr(self): Modified: python/branches/py3k/Lib/test/test_long.py ============================================================================== --- python/branches/py3k/Lib/test/test_long.py (original) +++ python/branches/py3k/Lib/test/test_long.py Sun Jan 27 22:07:59 2008 @@ -526,16 +526,21 @@ self.assertEqual(format(1234, "+b"), "+10011010010") self.assertEqual(format(-1234, "+b"), "-10011010010") - # conversion to float - self.assertEqual(format(0, 'f'), '0.000000') - # make sure these are errors self.assertRaises(ValueError, format, 3, "1.3") # precision disallowed self.assertRaises(ValueError, format, 3, "+c") # sign not allowed # with 'c' - self.assertRaises(ValueError, format, 3, "R") # bogus format type - # conversion to string should fail - self.assertRaises(ValueError, format, 3, "s") + # other format specifiers shouldn't work on ints, + # in particular float and string specifiers + for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] + + [chr(x) for x in range(ord('A'), ord('Z')+1)]): + if not format_spec in 'bcdoxX': + self.assertRaises(ValueError, format, 0, format_spec) + self.assertRaises(ValueError, format, 1, format_spec) + self.assertRaises(ValueError, format, -1, format_spec) + self.assertRaises(ValueError, format, 2**100, format_spec) + self.assertRaises(ValueError, format, -(2**100), format_spec) + def test_nan_inf(self): self.assertRaises(OverflowError, int, float('inf')) Modified: python/branches/py3k/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k/Objects/stringlib/formatter.h (original) +++ python/branches/py3k/Objects/stringlib/formatter.h Sun Jan 27 22:07:59 2008 @@ -788,37 +788,6 @@ /* no type conversion needed, already a string. do the formatting */ result = format_string_internal(value, &format); break; -#if 0 - case 'b': - case 'c': - case 'd': - case 'o': - case 'x': - case 'X': - /* convert to integer */ - /* XXX: make a stringlib function to do this when backporting, - since FromUnicode differs from FromString */ - tmp = PyLong_FromUnicode(STRINGLIB_STR(value), STRINGLIB_LEN(value), 0); - if (tmp == NULL) - goto done; - result = format_long_internal(tmp, &format); - break; - - case 'e': - case 'E': - case 'f': - case 'F': - case 'g': - case 'G': - case 'n': - case '%': - /* convert to float */ - tmp = PyFloat_FromString(value); - if (tmp == NULL) - goto done; - result = format_float_internal(tmp, &format); - break; -#endif default: /* unknown */ PyErr_Format(PyExc_ValueError, "Unknown conversion type %c", @@ -855,15 +824,6 @@ /* type conversion? */ switch (format.type) { -#if 0 - case 's': - /* convert to string/unicode */ - tmp = STRINGLIB_TOSTR(value); - if (tmp == NULL) - goto done; - result = format_string_internal(tmp, &format); - break; -#endif case 'b': case 'c': case 'd': @@ -874,21 +834,6 @@ result = format_long_internal(value, &format); break; - case 'e': - case 'E': - case 'f': - case 'F': - case 'g': - case 'G': - case 'n': - case '%': - /* convert to float */ - tmp = PyNumber_Float(value); - if (tmp == NULL) - goto done; - result = format_float_internal(value, &format); - break; - default: /* unknown */ PyErr_Format(PyExc_ValueError, "Unknown conversion type %c", @@ -925,28 +870,6 @@ /* type conversion? */ switch (format.type) { -#if 0 - case 's': - /* convert to string/unicode */ - tmp = STRINGLIB_TOSTR(value); - if (tmp == NULL) - goto done; - result = format_string_internal(tmp, &format); - break; -#endif - case 'b': - case 'c': - case 'd': - case 'o': - case 'x': - case 'X': - /* convert to integer */ - tmp = PyNumber_Long(value); - if (tmp == NULL) - goto done; - result = format_long_internal(tmp, &format); - break; - case 'e': case 'E': case 'f': From python-3000-checkins at python.org Mon Jan 28 00:50:44 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Mon, 28 Jan 2008 00:50:44 +0100 (CET) Subject: [Python-3000-checkins] r60379 - in python/branches/py3k: Doc/c-api/type.rst Doc/conf.py Doc/library/sys.rst Include/object.h Lib/pydoc.py Lib/rational.py Lib/test/regrtest.py Lib/test/test_builtin.py Lib/test/test_resource.py Lib/test/test_xmlrpc.py Objects/floatobject.c Objects/typeobject.c Python/pythonrun.c Python/sysmodule.c Message-ID: <20080127235044.6341F1E400C@bag.python.org> Author: christian.heimes Date: Mon Jan 28 00:50:43 2008 New Revision: 60379 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/c-api/type.rst python/branches/py3k/Doc/conf.py python/branches/py3k/Doc/library/sys.rst python/branches/py3k/Include/object.h python/branches/py3k/Lib/pydoc.py python/branches/py3k/Lib/rational.py python/branches/py3k/Lib/test/regrtest.py python/branches/py3k/Lib/test/test_builtin.py python/branches/py3k/Lib/test/test_resource.py python/branches/py3k/Lib/test/test_xmlrpc.py python/branches/py3k/Objects/floatobject.c python/branches/py3k/Objects/typeobject.c python/branches/py3k/Python/pythonrun.c python/branches/py3k/Python/sysmodule.c Log: Merged revisions 60364-60378 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60364 | neal.norwitz | 2008-01-27 19:09:48 +0100 (Sun, 27 Jan 2008) | 4 lines Update the comment and remove the close. If we close we can't flush anymore. We might still need to close after the for loop if flushing 6! times still doesn't cause the signal/exception. ........ r60365 | georg.brandl | 2008-01-27 19:14:43 +0100 (Sun, 27 Jan 2008) | 2 lines Remove effectless expression statement. ........ r60367 | neal.norwitz | 2008-01-27 19:19:04 +0100 (Sun, 27 Jan 2008) | 1 line Try to handle socket.errors properly in is_unavailable ........ r60370 | christian.heimes | 2008-01-27 20:01:45 +0100 (Sun, 27 Jan 2008) | 1 line Change isbasestring function as discussed on the cvs list a while ago ........ r60372 | neal.norwitz | 2008-01-27 21:03:13 +0100 (Sun, 27 Jan 2008) | 3 lines socket.error doesn't have a headers attribute like ProtocolError. Handle that situation where we catch socket.errors. ........ r60375 | georg.brandl | 2008-01-27 21:25:12 +0100 (Sun, 27 Jan 2008) | 2 lines Add refcounting extension to build config. ........ r60377 | jeffrey.yasskin | 2008-01-28 00:08:46 +0100 (Mon, 28 Jan 2008) | 6 lines Moved Rational._binary_float_to_ratio() to float.as_integer_ratio() because it's useful outside of rational numbers. This is my first C code that had to do anything significant. Please be more careful when looking over it. ........ r60378 | christian.heimes | 2008-01-28 00:34:59 +0100 (Mon, 28 Jan 2008) | 1 line Added clear cache methods to clear the internal type lookup cache for ref leak test runs. ........ Modified: python/branches/py3k/Doc/c-api/type.rst ============================================================================== --- python/branches/py3k/Doc/c-api/type.rst (original) +++ python/branches/py3k/Doc/c-api/type.rst Mon Jan 28 00:50:43 2008 @@ -33,6 +33,13 @@ standard type object. Return false in all other cases. +.. cfunction:: unsigned int PyType_ClearCache(void) + + Clears the internal lookup cache. Return the current version tag. + + .. versionadded:: 2.6 + + .. cfunction:: int PyType_HasFeature(PyObject *o, int feature) Return true if the type object *o* sets the feature *feature*. Type features Modified: python/branches/py3k/Doc/conf.py ============================================================================== --- python/branches/py3k/Doc/conf.py (original) +++ python/branches/py3k/Doc/conf.py Mon Jan 28 00:50:43 2008 @@ -13,6 +13,8 @@ # General configuration # --------------------- +extensions = ['sphinx.addons.refcounting'] + # General substitutions. project = 'Python' copyright = '1990-%s, Python Software Foundation' % time.strftime('%Y') Modified: python/branches/py3k/Doc/library/sys.rst ============================================================================== --- python/branches/py3k/Doc/library/sys.rst (original) +++ python/branches/py3k/Doc/library/sys.rst Mon Jan 28 00:50:43 2008 @@ -54,6 +54,13 @@ A string containing the copyright pertaining to the Python interpreter. +.. function:: _cleartypecache() + + Clear the internal type lookup cache. + + .. versionadded:: 2.6 + + .. function:: _current_frames() Return a dictionary mapping each thread's identifier to the topmost stack frame Modified: python/branches/py3k/Include/object.h ============================================================================== --- python/branches/py3k/Include/object.h (original) +++ python/branches/py3k/Include/object.h Mon Jan 28 00:50:43 2008 @@ -428,6 +428,7 @@ PyAPI_FUNC(PyObject *) PyType_GenericNew(PyTypeObject *, PyObject *, PyObject *); PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *); +PyAPI_FUNC(unsigned int) PyType_ClearCache(void); /* Generic operations on objects */ PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int); Modified: python/branches/py3k/Lib/pydoc.py ============================================================================== --- python/branches/py3k/Lib/pydoc.py (original) +++ python/branches/py3k/Lib/pydoc.py Mon Jan 28 00:50:43 2008 @@ -1203,7 +1203,6 @@ else: tag = "inherited from %s" % classname(thisclass, object.__module__) - filter(lambda t: not t[0].startswith('_'), attrs) # Sort attrs by name. attrs.sort() Modified: python/branches/py3k/Lib/rational.py ============================================================================== --- python/branches/py3k/Lib/rational.py (original) +++ python/branches/py3k/Lib/rational.py Mon Jan 28 00:50:43 2008 @@ -24,60 +24,6 @@ return a -def _binary_float_to_ratio(x): - """x -> (top, bot), a pair of ints s.t. x = top/bot. - - The conversion is done exactly, without rounding. - bot > 0 guaranteed. - Some form of binary fp is assumed. - Pass NaNs or infinities at your own risk. - - >>> _binary_float_to_ratio(10.0) - (10, 1) - >>> _binary_float_to_ratio(0.0) - (0, 1) - >>> _binary_float_to_ratio(-.25) - (-1, 4) - """ - # XXX Move this to floatobject.c with a name like - # float.as_integer_ratio() - - if x == 0: - return 0, 1 - f, e = math.frexp(x) - signbit = 1 - if f < 0: - f = -f - signbit = -1 - assert 0.5 <= f < 1.0 - # x = signbit * f * 2**e exactly - - # Suck up CHUNK bits at a time; 28 is enough so that we suck - # up all bits in 2 iterations for all known binary double- - # precision formats, and small enough to fit in an int. - CHUNK = 28 - top = 0 - # invariant: x = signbit * (top + f) * 2**e exactly - while f: - f = math.ldexp(f, CHUNK) - digit = trunc(f) - assert digit >> CHUNK == 0 - top = (top << CHUNK) | digit - f = f - digit - assert 0.0 <= f < 1.0 - e = e - CHUNK - assert top - - # Add in the sign bit. - top = signbit * top - - # now x = top * 2**e exactly; fold in 2**e - if e>0: - return (top * 2**e, 1) - else: - return (top, 2 ** -e) - - _RATIONAL_FORMAT = re.compile( r'^\s*(?P[-+]?)(?P\d+)' r'(?:/(?P\d+)|\.(?P\d+))?\s*$') @@ -162,7 +108,7 @@ (cls.__name__, f, type(f).__name__)) if math.isnan(f) or math.isinf(f): raise TypeError("Cannot convert %r to %s." % (f, cls.__name__)) - return cls(*_binary_float_to_ratio(f)) + return cls(*f.as_integer_ratio()) @classmethod def from_decimal(cls, dec): Modified: python/branches/py3k/Lib/test/regrtest.py ============================================================================== --- python/branches/py3k/Lib/test/regrtest.py (original) +++ python/branches/py3k/Lib/test/regrtest.py Mon Jan 28 00:50:43 2008 @@ -752,6 +752,9 @@ sys.path_importer_cache.clear() sys.path_importer_cache.update(pic) + # clear type cache + sys._cleartypecache() + # Clear ABC registries, restoring previously saved ABC registries. for abc in [getattr(_abcoll, a) for a in _abcoll.__all__]: if not issubclass(abc, _Abstract): Modified: python/branches/py3k/Lib/test/test_builtin.py ============================================================================== --- python/branches/py3k/Lib/test/test_builtin.py (original) +++ python/branches/py3k/Lib/test/test_builtin.py Mon Jan 28 00:50:43 2008 @@ -5,7 +5,7 @@ run_with_locale from operator import neg -import sys, warnings, random, UserDict, io +import sys, warnings, random, UserDict, io, rational warnings.filterwarnings("ignore", "hex../oct.. of negative int", FutureWarning, __name__) warnings.filterwarnings("ignore", "integer argument expected", @@ -592,6 +592,25 @@ # make sure we can take a subclass of str as a format spec self.assertEqual(format(0, C('10')), ' 0') + def test_floatasratio(self): + R = rational.Rational + self.assertEqual(R(0, 1), + R(*float(0.0).as_integer_ratio())) + self.assertEqual(R(5, 2), + R(*float(2.5).as_integer_ratio())) + self.assertEqual(R(1, 2), + R(*float(0.5).as_integer_ratio())) + self.assertEqual(R(4728779608739021, 2251799813685248), + R(*float(2.1).as_integer_ratio())) + self.assertEqual(R(-4728779608739021, 2251799813685248), + R(*float(-2.1).as_integer_ratio())) + self.assertEqual(R(-2100, 1), + R(*float(-2100.0).as_integer_ratio())) + + self.assertRaises(OverflowError, float('inf').as_integer_ratio) + self.assertRaises(OverflowError, float('-inf').as_integer_ratio) + self.assertRaises(ValueError, float('nan').as_integer_ratio) + def test_getattr(self): import sys self.assert_(getattr(sys, 'stdout') is sys.stdout) Modified: python/branches/py3k/Lib/test/test_resource.py ============================================================================== --- python/branches/py3k/Lib/test/test_resource.py (original) +++ python/branches/py3k/Lib/test/test_resource.py Mon Jan 28 00:50:43 2008 @@ -56,13 +56,12 @@ f.flush() # On some systems (e.g., Ubuntu on hppa) the flush() # doesn't always cause the exception, but the close() - # does eventually. Try closing several times in + # does eventually. Try flushing several times in # an attempt to ensure the file is really synced and # the exception raised. for i in range(5): time.sleep(.1) f.flush() - f.close() except IOError: if not limit_set: raise Modified: python/branches/py3k/Lib/test/test_xmlrpc.py ============================================================================== --- python/branches/py3k/Lib/test/test_xmlrpc.py (original) +++ python/branches/py3k/Lib/test/test_xmlrpc.py Mon Jan 28 00:50:43 2008 @@ -312,9 +312,16 @@ given by operations on non-blocking sockets.''' # sometimes we get a -1 error code and/or empty headers - if e.errcode == -1 or e.headers is None: - return True + try: + if e.errcode == -1 or e.headers is None: + return True + exc_mess = e.headers.get('X-exception') + except AttributeError: + # Ignore socket.errors here. + exc_mess = str(e) + if exc_mess and 'temporarily unavailable' in exc_mess.lower(): + return True class SimpleServerTestCase(unittest.TestCase): def setUp(self): @@ -349,7 +356,7 @@ # ignore failures due to non-blocking socket 'unavailable' errors if not is_unavailable_exception(e): # protocol error; provide additional information in test output - self.fail("%s\n%s" % (e, e.headers)) + self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) # [ch] The test 404 is causing lots of false alarms. def XXXtest_404(self): @@ -375,7 +382,7 @@ # ignore failures due to non-blocking socket 'unavailable' errors if not is_unavailable_exception(e): # protocol error; provide additional information in test output - self.fail("%s\n%s" % (e, e.headers)) + self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) def test_introspection2(self): @@ -388,7 +395,7 @@ # ignore failures due to non-blocking socket 'unavailable' errors if not is_unavailable_exception(e): # protocol error; provide additional information in test output - self.fail("%s\n%s" % (e, e.headers)) + self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) def test_introspection3(self): try: @@ -400,7 +407,7 @@ # ignore failures due to non-blocking socket 'unavailable' errors if not is_unavailable_exception(e): # protocol error; provide additional information in test output - self.fail("%s\n%s" % (e, e.headers)) + self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) def test_introspection4(self): # the SimpleXMLRPCServer doesn't support signatures, but @@ -413,7 +420,7 @@ # ignore failures due to non-blocking socket 'unavailable' errors if not is_unavailable_exception(e): # protocol error; provide additional information in test output - self.fail("%s\n%s" % (e, e.headers)) + self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) def test_multicall(self): try: @@ -430,7 +437,7 @@ # ignore failures due to non-blocking socket 'unavailable' errors if not is_unavailable_exception(e): # protocol error; provide additional information in test output - self.fail("%s\n%s" % (e, e.headers)) + self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) def test_non_existing_multicall(self): try: @@ -451,7 +458,7 @@ # ignore failures due to non-blocking socket 'unavailable' errors if not is_unavailable_exception(e): # protocol error; provide additional information in test output - self.fail("%s\n%s" % (e, e.headers)) + self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) # This is a contrived way to make a failure occur on the server side # in order to test the _send_traceback_header flag on the server @@ -498,7 +505,7 @@ # ignore failures due to non-blocking socket 'unavailable' errors if not is_unavailable_exception(e): # protocol error; provide additional information in test output - self.fail("%s\n%s" % (e, e.headers)) + self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) def test_fail_no_info(self): # use the broken message class @@ -509,7 +516,7 @@ p.pow(6,8) except (xmlrpclib.ProtocolError, socket.error) as e: # ignore failures due to non-blocking socket 'unavailable' errors - if not is_unavailable_exception(e): + if not is_unavailable_exception(e) and hasattr(e, "headers"): # The two server-side error headers shouldn't be sent back in this case self.assertTrue(e.headers.get("X-exception") is None) self.assertTrue(e.headers.get("X-traceback") is None) @@ -529,7 +536,7 @@ p.pow(6,8) except (xmlrpclib.ProtocolError, socket.error) as e: # ignore failures due to non-blocking socket 'unavailable' errors - if not is_unavailable_exception(e): + if not is_unavailable_exception(e) and hasattr(e, "headers"): # We should get error info in the response expected_err = "invalid literal for int() with base 10: 'I am broken'" self.assertEqual(e.headers.get("x-exception"), expected_err) Modified: python/branches/py3k/Objects/floatobject.c ============================================================================== --- python/branches/py3k/Objects/floatobject.c (original) +++ python/branches/py3k/Objects/floatobject.c Mon Jan 28 00:50:43 2008 @@ -1073,6 +1073,163 @@ return v; } +static PyObject * +float_as_integer_ratio(PyObject *v) +{ + double self; + double float_part; + int exponent; + int is_negative; + const int chunk_size = 28; + PyObject *prev; + PyObject *py_chunk = NULL; + PyObject *py_exponent = NULL; + PyObject *numerator = NULL; + PyObject *denominator = NULL; + PyObject *result_pair = NULL; + PyNumberMethods *long_methods; + +#define INPLACE_UPDATE(obj, call) \ + prev = obj; \ + obj = call; \ + Py_DECREF(prev); \ + + CONVERT_TO_DOUBLE(v, self); + + if (Py_IS_INFINITY(self)) { + PyErr_SetString(PyExc_OverflowError, + "Cannot pass infinity to float.as_integer_ratio."); + return NULL; + } +#ifdef Py_NAN + if (Py_IS_NAN(self)) { + PyErr_SetString(PyExc_ValueError, + "Cannot pass nan to float.as_integer_ratio."); + return NULL; + } +#endif + + if (self == 0) { + numerator = PyLong_FromLong(0); + if (numerator == NULL) goto error; + denominator = PyLong_FromLong(1); + if (denominator == NULL) goto error; + result_pair = PyTuple_Pack(2, numerator, denominator); + /* Hand ownership over to the tuple. If the tuple + wasn't created successfully, we want to delete the + ints anyway. */ + Py_DECREF(numerator); + Py_DECREF(denominator); + return result_pair; + } + + /* XXX: Could perhaps handle FLT_RADIX!=2 by using ilogb and + scalbn, but those may not be in C89. */ + PyFPE_START_PROTECT("as_integer_ratio", goto error); + float_part = frexp(self, &exponent); + is_negative = 0; + if (float_part < 0) { + float_part = -float_part; + is_negative = 1; + /* 0.5 <= float_part < 1.0 */ + } + PyFPE_END_PROTECT(float_part); + /* abs(self) == float_part * 2**exponent exactly */ + + /* Suck up chunk_size bits at a time; 28 is enough so that we + suck up all bits in 2 iterations for all known binary + double-precision formats, and small enough to fit in a + long. */ + numerator = PyLong_FromLong(0); + if (numerator == NULL) goto error; + + long_methods = PyLong_Type.tp_as_number; + + py_chunk = PyLong_FromLong(chunk_size); + if (py_chunk == NULL) goto error; + + while (float_part != 0) { + /* invariant: abs(self) == + (numerator + float_part) * 2**exponent exactly */ + long digit; + PyObject *py_digit; + + PyFPE_START_PROTECT("as_integer_ratio", goto error); + /* Pull chunk_size bits out of float_part, into digits. */ + float_part = ldexp(float_part, chunk_size); + digit = (long)float_part; + float_part -= digit; + /* 0 <= float_part < 1 */ + exponent -= chunk_size; + PyFPE_END_PROTECT(float_part); + + /* Shift digits into numerator. */ + // numerator <<= chunk_size + INPLACE_UPDATE(numerator, + long_methods->nb_lshift(numerator, py_chunk)); + if (numerator == NULL) goto error; + + // numerator |= digit + py_digit = PyLong_FromLong(digit); + if (py_digit == NULL) goto error; + INPLACE_UPDATE(numerator, + long_methods->nb_or(numerator, py_digit)); + Py_DECREF(py_digit); + if (numerator == NULL) goto error; + } + + /* Add in the sign bit. */ + if (is_negative) { + INPLACE_UPDATE(numerator, + long_methods->nb_negative(numerator)); + if (numerator == NULL) goto error; + } + + /* now self = numerator * 2**exponent exactly; fold in 2**exponent */ + denominator = PyLong_FromLong(1); + py_exponent = PyLong_FromLong(labs(exponent)); + if (py_exponent == NULL) goto error; + INPLACE_UPDATE(py_exponent, + long_methods->nb_lshift(denominator, py_exponent)); + if (py_exponent == NULL) goto error; + if (exponent > 0) { + INPLACE_UPDATE(numerator, + long_methods->nb_multiply(numerator, + py_exponent)); + if (numerator == NULL) goto error; + } + else { + Py_DECREF(denominator); + denominator = py_exponent; + py_exponent = NULL; + } + + result_pair = PyTuple_Pack(2, numerator, denominator); + +#undef INPLACE_UPDATE +error: + Py_XDECREF(py_exponent); + Py_XDECREF(py_chunk); + Py_XDECREF(denominator); + Py_XDECREF(numerator); + return result_pair; +} + +PyDoc_STRVAR(float_as_integer_ratio_doc, +"float.as_integer_ratio() -> (int, int)\n" +"\n" +"Returns a pair of integers, not necessarily in lowest terms, whose\n" +"ratio is exactly equal to the original float. This method raises an\n" +"OverflowError on infinities and a ValueError on nans. The resulting\n" +"denominator will be positive.\n" +"\n" +">>> (10.0).as_integer_ratio()\n" +"(167772160L, 16777216L)\n" +">>> (0.0).as_integer_ratio()\n" +"(0, 1)\n" +">>> (-.25).as_integer_ratio()\n" +"(-134217728L, 536870912L)"); + static PyObject * float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds); @@ -1281,6 +1438,8 @@ {"__round__", (PyCFunction)float_round, METH_VARARGS, "Returns the Integral closest to x, rounding half toward even.\n" "When an argument is passed, works like built-in round(x, ndigits)."}, + {"as_integer_ratio", (PyCFunction)float_as_integer_ratio, METH_NOARGS, + float_as_integer_ratio_doc}, {"__getnewargs__", (PyCFunction)float_getnewargs, METH_NOARGS}, {"__getformat__", (PyCFunction)float_getformat, METH_O|METH_CLASS, float_getformat_doc}, Modified: python/branches/py3k/Objects/typeobject.c ============================================================================== --- python/branches/py3k/Objects/typeobject.c (original) +++ python/branches/py3k/Objects/typeobject.c Mon Jan 28 00:50:43 2008 @@ -33,6 +33,24 @@ static struct method_cache_entry method_cache[1 << MCACHE_SIZE_EXP]; static unsigned int next_version_tag = 0; +static void type_modified(PyTypeObject *); + +unsigned int +PyType_ClearCache(void) +{ + Py_ssize_t i; + unsigned int cur_version_tag = next_version_tag - 1; + + for (i = 0; i < (1 << MCACHE_SIZE_EXP); i++) { + method_cache[i].version = 0; + Py_CLEAR(method_cache[i].name); + method_cache[i].value = NULL; + } + next_version_tag = 0; + /* mark all version tags as invalid */ + type_modified(&PyBaseObject_Type); + return cur_version_tag; +} static void type_modified(PyTypeObject *type) Modified: python/branches/py3k/Python/pythonrun.c ============================================================================== --- python/branches/py3k/Python/pythonrun.c (original) +++ python/branches/py3k/Python/pythonrun.c Mon Jan 28 00:50:43 2008 @@ -404,6 +404,9 @@ Py_XDECREF(warnings_module); warnings_module = NULL; + /* Clear type lookup cache */ + PyType_ClearCache(); + /* Collect garbage. This may call finalizers; it's nice to call these * before all modules are destroyed. * XXX If a __del__ or weakref callback is triggered here, and tries to Modified: python/branches/py3k/Python/sysmodule.c ============================================================================== --- python/branches/py3k/Python/sysmodule.c (original) +++ python/branches/py3k/Python/sysmodule.c Mon Jan 28 00:50:43 2008 @@ -730,6 +730,17 @@ 10. Number of stack pops performed by call_function()" ); +static PyObject * +sys_cleartypecache(PyObject* self, PyObject* args) +{ + PyType_ClearCache(); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(cleartypecache_doc, +"_cleartypecache() -> None\n\ +Clear the internal type lookup cache."); + #ifdef __cplusplus extern "C" { #endif @@ -752,6 +763,8 @@ /* Might as well keep this in alphabetic order */ {"callstats", (PyCFunction)PyEval_GetCallStats, METH_NOARGS, callstats_doc}, + {"_cleartypecache", sys_cleartypecache, METH_NOARGS, + cleartypecache_doc}, {"_current_frames", sys_current_frames, METH_NOARGS, current_frames_doc}, {"displayhook", sys_displayhook, METH_O, displayhook_doc}, From python-3000-checkins at python.org Mon Jan 28 03:38:21 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Mon, 28 Jan 2008 03:38:21 +0100 (CET) Subject: [Python-3000-checkins] r60383 - in python/branches/py3k: Modules/_ctypes/_ctypes.c Modules/_ctypes/callbacks.c Modules/mathmodule.c Objects/abstract.c Objects/complexobject.c Python/bltinmodule.c Python/compile.c Message-ID: <20080128023821.0B6981E4002@bag.python.org> Author: christian.heimes Date: Mon Jan 28 03:38:20 2008 New Revision: 60383 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Modules/_ctypes/_ctypes.c python/branches/py3k/Modules/_ctypes/callbacks.c python/branches/py3k/Modules/mathmodule.c python/branches/py3k/Objects/abstract.c python/branches/py3k/Objects/complexobject.c python/branches/py3k/Python/bltinmodule.c python/branches/py3k/Python/compile.c Log: Merged revisions 60379-60382 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60381 | christian.heimes | 2008-01-28 03:07:53 +0100 (Mon, 28 Jan 2008) | 1 line static PyObject* variables should use PyString_InternFromString() instead of PyObject_FromString() to store a python string in a function level static var. ........ Modified: python/branches/py3k/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k/Modules/_ctypes/_ctypes.c Mon Jan 28 03:38:20 2008 @@ -1530,9 +1530,9 @@ if (suffix == NULL) #ifdef WORDS_BIGENDIAN - suffix = PyUnicode_FromString("_le"); + suffix = PyUnicode_InternFromString("_le"); #else - suffix = PyUnicode_FromString("_be"); + suffix = PyUnicode_InternFromString("_be"); #endif newname = PyUnicode_Concat(name, suffix); @@ -4276,7 +4276,7 @@ } if (format == NULL) { - format = PyUnicode_FromString("%s(%r)"); + format = PyUnicode_InternFromString("%s(%r)"); if (format == NULL) return NULL; } Modified: python/branches/py3k/Modules/_ctypes/callbacks.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/callbacks.c (original) +++ python/branches/py3k/Modules/_ctypes/callbacks.c Mon Jan 28 03:38:20 2008 @@ -365,7 +365,7 @@ static PyObject *context; if (context == NULL) - context = PyUnicode_FromString("_ctypes.DllGetClassObject"); + context = PyUnicode_InternFromString("_ctypes.DllGetClassObject"); mod = PyImport_ImportModuleNoBlock("ctypes"); if (!mod) { @@ -444,7 +444,7 @@ static PyObject *context; if (context == NULL) - context = PyUnicode_FromString("_ctypes.DllCanUnloadNow"); + context = PyUnicode_InternFromString("_ctypes.DllCanUnloadNow"); mod = PyImport_ImportModuleNoBlock("ctypes"); if (!mod) { Modified: python/branches/py3k/Modules/mathmodule.c ============================================================================== --- python/branches/py3k/Modules/mathmodule.c (original) +++ python/branches/py3k/Modules/mathmodule.c Mon Jan 28 03:38:20 2008 @@ -131,7 +131,7 @@ PyObject *method; if (ceil_str == NULL) { - ceil_str = PyUnicode_FromString("__ceil__"); + ceil_str = PyUnicode_InternFromString("__ceil__"); if (ceil_str == NULL) return NULL; } @@ -171,7 +171,7 @@ PyObject *method; if (floor_str == NULL) { - floor_str = PyUnicode_FromString("__floor__"); + floor_str = PyUnicode_InternFromString("__floor__"); if (floor_str == NULL) return NULL; } Modified: python/branches/py3k/Objects/abstract.c ============================================================================== --- python/branches/py3k/Objects/abstract.c (original) +++ python/branches/py3k/Objects/abstract.c Mon Jan 28 03:38:20 2008 @@ -2333,7 +2333,7 @@ PyObject *bases; if (__bases__ == NULL) { - __bases__ = PyUnicode_FromString("__bases__"); + __bases__ = PyUnicode_InternFromString("__bases__"); if (__bases__ == NULL) return NULL; } @@ -2413,7 +2413,7 @@ int retval = 0; if (__class__ == NULL) { - __class__ = PyUnicode_FromString("__class__"); + __class__ = PyUnicode_InternFromString("__class__"); if (__class__ == NULL) return -1; } Modified: python/branches/py3k/Objects/complexobject.c ============================================================================== --- python/branches/py3k/Objects/complexobject.c (original) +++ python/branches/py3k/Objects/complexobject.c Mon Jan 28 03:38:20 2008 @@ -265,13 +265,14 @@ /* return -1 on failure */ cv.real = -1.; cv.imag = 0.; - + + if (complex_str == NULL) { + if (!(complex_str = PyUnicode_FromString("__complex__"))) + return cv; + } + { PyObject *complexfunc; - if (!complex_str) { - if (!(complex_str = PyUnicode_FromString("__complex__"))) - return cv; - } complexfunc = _PyType_Lookup(op->ob_type, complex_str); /* complexfunc is a borrowed reference */ if (complexfunc) { Modified: python/branches/py3k/Python/bltinmodule.c ============================================================================== --- python/branches/py3k/Python/bltinmodule.c (original) +++ python/branches/py3k/Python/bltinmodule.c Mon Jan 28 03:38:20 2008 @@ -1463,7 +1463,7 @@ } if (round_str == NULL) { - round_str = PyUnicode_FromString("__round__"); + round_str = PyUnicode_InternFromString("__round__"); if (round_str == NULL) return NULL; } @@ -1582,7 +1582,7 @@ } if (trunc_str == NULL) { - trunc_str = PyUnicode_FromString("__trunc__"); + trunc_str = PyUnicode_InternFromString("__trunc__"); if (trunc_str == NULL) return NULL; } Modified: python/branches/py3k/Python/compile.c ============================================================================== --- python/branches/py3k/Python/compile.c (original) +++ python/branches/py3k/Python/compile.c Mon Jan 28 03:38:20 2008 @@ -1133,7 +1133,7 @@ int addNone = 1; static PyObject *module; if (!module) { - module = PyUnicode_FromString(""); + module = PyUnicode_InternFromString(""); if (!module) return NULL; } @@ -1477,7 +1477,7 @@ /* initialize statics */ if (locals == NULL) { - locals = PyUnicode_FromString("__locals__"); + locals = PyUnicode_InternFromString("__locals__"); if (locals == NULL) return 0; } @@ -2177,7 +2177,7 @@ if (Py_OptimizeFlag) return 1; if (assertion_error == NULL) { - assertion_error = PyUnicode_FromString("AssertionError"); + assertion_error = PyUnicode_InternFromString("AssertionError"); if (assertion_error == NULL) return 0; } From ncoghlan at gmail.com Mon Jan 28 05:16:54 2008 From: ncoghlan at gmail.com (Nick Coghlan) Date: Mon, 28 Jan 2008 14:16:54 +1000 Subject: [Python-3000-checkins] r60376 - in python/branches/py3k: Lib/test/test_float.py Lib/test/test_long.py Objects/stringlib/formatter.h In-Reply-To: <20080127210759.A620F1E4014@bag.python.org> References: <20080127210759.A620F1E4014@bag.python.org> Message-ID: <479D5736.2030403@gmail.com> eric.smith wrote: > Author: eric.smith > Date: Sun Jan 27 22:07:59 2008 > New Revision: 60376 > > Modified: > python/branches/py3k/Lib/test/test_float.py > python/branches/py3k/Lib/test/test_long.py > python/branches/py3k/Objects/stringlib/formatter.h > Log: > Restrict format presentation types to those specified in the 'Standard Format Specifiers' section of PEP 3101. I think this checkin goes too far in removing support for the floating point formatting codes from integers. Guido objected to %d working on floats last year, but expected %f and friends to continue to work on integers [1]. This makes sense when you consider that there is no data loss in displaying an integer as a floating point number, while there is a definite potential for data loss when going the other way. Perhaps the PEP needs a tweak (referencing Guido's email) to state explicitly that the builtin integers understand the floating point formatting codes, but the builtin and standard library floating point types don't understand the integer codes? That area of the PEP is slightly problematic anyway where it suggests that integers could handle the floating point codes by delegating to float() - that isn't quite true, since the maximum precision on floats is less than the maximum precision on integers. Cheers, Nick. [1] http://mail.python.org/pipermail/python-3000/2007-August/009066.html -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org From guido at python.org Mon Jan 28 05:23:29 2008 From: guido at python.org (Guido van Rossum) Date: Sun, 27 Jan 2008 20:23:29 -0800 Subject: [Python-3000-checkins] r60376 - in python/branches/py3k: Lib/test/test_float.py Lib/test/test_long.py Objects/stringlib/formatter.h In-Reply-To: <479D5736.2030403@gmail.com> References: <20080127210759.A620F1E4014@bag.python.org> <479D5736.2030403@gmail.com> Message-ID: On Jan 27, 2008 8:16 PM, Nick Coghlan wrote: > eric.smith wrote: > > Author: eric.smith > > Date: Sun Jan 27 22:07:59 2008 > > New Revision: 60376 > > > > Modified: > > python/branches/py3k/Lib/test/test_float.py > > python/branches/py3k/Lib/test/test_long.py > > python/branches/py3k/Objects/stringlib/formatter.h > > Log: > > Restrict format presentation types to those specified in the 'Standard Format Specifiers' section of PEP 3101. > > I think this checkin goes too far in removing support for the floating > point formatting codes from integers. Guido objected to %d working on > floats last year, but expected %f and friends to continue to work on > integers [1]. This makes sense when you consider that there is no data > loss in displaying an integer as a floating point number, while there is > a definite potential for data loss when going the other way. > > Perhaps the PEP needs a tweak (referencing Guido's email) to state > explicitly that the builtin integers understand the floating point > formatting codes, but the builtin and standard library floating point > types don't understand the integer codes? That area of the PEP is > slightly problematic anyway where it suggests that integers could handle > the floating point codes by delegating to float() - that isn't quite > true, since the maximum precision on floats is less than the maximum > precision on integers. > > Cheers, > Nick. > > [1] > http://mail.python.org/pipermail/python-3000/2007-August/009066.html Agreed with Nick -- in general, the idea is that ints should be allowed whenever floats are expected -- just not the other way around! Python 2.x broke this in one important place, division -- 2/3 and 2.0/3.0 had different meanings there. We are fixing this in 3.0. Please maintain this rule for formatting! -- --Guido van Rossum (home page: http://www.python.org/~guido/) From python-3000-checkins at python.org Mon Jan 28 08:45:05 2008 From: python-3000-checkins at python.org (thomas.heller) Date: Mon, 28 Jan 2008 08:45:05 +0100 (CET) Subject: [Python-3000-checkins] r60384 - python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py Message-ID: <20080128074505.3089C1E4002@bag.python.org> Author: thomas.heller Date: Mon Jan 28 08:45:04 2008 New Revision: 60384 Modified: python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py Log: Restructure the test so that it contains little endian format strings. On big endian machines, the format strings are converted by replacing '<' with '>'. Modified: python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py Mon Jan 28 08:45:04 2008 @@ -3,21 +3,22 @@ import re, struct, sys if sys.byteorder == "little": - ENDIAN = "<" + THIS_ENDIAN = "<" + OTHER_ENDIAN = ">" else: - ENDIAN = ">" + THIS_ENDIAN = ">" + OTHER_ENDIAN = "<" def normalize(format): # Remove current endian specifier and white space from a format # string - format = format.replace(ENDIAN, "") - format = format.replace("=", "") + format = format.replace(OTHER_ENDIAN, THIS_ENDIAN) return re.sub(r"\s", "", format) class Test(unittest.TestCase): - def test_types(self): - for tp, fmt, shape, itemtp in types: + def test_native_types(self): + for tp, fmt, shape, itemtp in native_types: ob = tp() v = memoryview(ob) try: @@ -59,62 +60,62 @@ class aUnion(Union): _fields_ = [("a", c_int)] -types = [ - # type format shape calc itemsize +native_types = [ + # type format shape calc itemsize ## simple types - (c_char, "c", None, c_char), - (c_byte, "b", None, c_byte), - (c_ubyte, "B", None, c_ubyte), - (c_short, "h", None, c_short), - (c_ushort, "H", None, c_ushort), + (c_char, " Author: thomas.heller Date: Mon Jan 28 08:58:46 2008 New Revision: 60385 Modified: python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py python/branches/py3k-ctypes-pep3118/Modules/_ctypes/_ctypes.c Log: Bugfix and test for explicit big and little endian types. Modified: python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py Mon Jan 28 08:58:46 2008 @@ -22,7 +22,31 @@ ob = tp() v = memoryview(ob) try: - self.failUnlessEqual(normalize(v.format), fmt) + self.failUnlessEqual(normalize(v.format), normalize(fmt)) + self.failUnlessEqual(v.size, sizeof(ob)) + self.failUnlessEqual(v.itemsize, sizeof(itemtp)) + self.failUnlessEqual(v.shape, shape) + # ctypes object always have a non-strided memory block + self.failUnlessEqual(v.strides, None) + # they are always read/write + self.failIf(v.readonly) + + if v.shape: + n = 1 + for dim in v.shape: + n = n * dim + self.failUnlessEqual(v.itemsize * n, v.size) + except: + # so that we can see the failing type + print(tp) + raise + + def test_endian_types(self): + for tp, fmt, shape, itemtp in endian_types: + ob = tp() + v = memoryview(ob) + try: + self.failUnlessEqual(v.format, fmt) self.failUnlessEqual(v.size, sizeof(ob)) self.failUnlessEqual(v.itemsize, sizeof(itemtp)) self.failUnlessEqual(v.shape, shape) @@ -119,5 +143,18 @@ ] +class BEPoint(BigEndianStructure): + _fields_ = [("x", c_long), ("y", c_long)] + +class LEPoint(LittleEndianStructure): + _fields_ = [("x", c_long), ("y", c_long)] + +endian_types = [ + (BEPoint, "T{>l:x:>l:y:}", None, BEPoint), + (LEPoint, "T{l:x:>l:y:}", None, POINTER(BEPoint)), + (POINTER(LEPoint), "&T{format = alloc_format_string("<", stgdict->format); + sw_dict->format = alloc_format_string("<", stgdict->format+1); #else PyObject_SetAttrString((PyObject *)result, "__ctype_be__", swapped); PyObject_SetAttrString((PyObject *)result, "__ctype_le__", (PyObject *)result); PyObject_SetAttrString(swapped, "__ctype_le__", (PyObject *)result); PyObject_SetAttrString(swapped, "__ctype_be__", swapped); /* We are creating the type for the OTHER endian */ - sw_dict->format = alloc_format_string(">", stgdict->format); + sw_dict->format = alloc_format_string(">", stgdict->format+1); #endif Py_DECREF(swapped); if (PyErr_Occurred()) { From python-3000-checkins at python.org Mon Jan 28 11:59:27 2008 From: python-3000-checkins at python.org (eric.smith) Date: Mon, 28 Jan 2008 11:59:27 +0100 (CET) Subject: [Python-3000-checkins] r60390 - in python/branches/py3k: Lib/test/test_long.py Objects/stringlib/formatter.h Message-ID: <20080128105927.8F2B01E400C@bag.python.org> Author: eric.smith Date: Mon Jan 28 11:59:27 2008 New Revision: 60390 Modified: python/branches/py3k/Lib/test/test_long.py python/branches/py3k/Objects/stringlib/formatter.h Log: Partially revert r60376: restore ability for ints to be automatically converted to floats, if a float type specifier is given to an int. PEP 3101 should be clarified on this point.Also, remove unused local variables left over from r60376. Modified: python/branches/py3k/Lib/test/test_long.py ============================================================================== --- python/branches/py3k/Lib/test/test_long.py (original) +++ python/branches/py3k/Lib/test/test_long.py Mon Jan 28 11:59:27 2008 @@ -530,17 +530,23 @@ self.assertRaises(ValueError, format, 3, "1.3") # precision disallowed self.assertRaises(ValueError, format, 3, "+c") # sign not allowed # with 'c' - # other format specifiers shouldn't work on ints, - # in particular float and string specifiers + + # ensure that only int and float type specifiers work for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] + [chr(x) for x in range(ord('A'), ord('Z')+1)]): - if not format_spec in 'bcdoxX': + if not format_spec in 'bcdoxXeEfFgGn%': self.assertRaises(ValueError, format, 0, format_spec) self.assertRaises(ValueError, format, 1, format_spec) self.assertRaises(ValueError, format, -1, format_spec) self.assertRaises(ValueError, format, 2**100, format_spec) self.assertRaises(ValueError, format, -(2**100), format_spec) + # ensure that float type specifiers work; format converts + # the int to a float + for format_spec in 'eEfFgGn%': + for value in [0, 1, -1, 100, -100, 1234567890, -1234567890]: + self.assertEqual(format(value, format_spec), + format(float(value), format_spec)) def test_nan_inf(self): self.assertRaises(OverflowError, int, float('inf')) Modified: python/branches/py3k/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k/Objects/stringlib/formatter.h (original) +++ python/branches/py3k/Objects/stringlib/formatter.h Mon Jan 28 11:59:27 2008 @@ -764,7 +764,6 @@ FORMAT_STRING(PyObject* value, PyObject* args) { PyObject *format_spec; - PyObject *tmp = NULL; PyObject *result = NULL; InternalFormatSpec format; @@ -796,7 +795,6 @@ } done: - Py_XDECREF(tmp); return result; } @@ -834,6 +832,21 @@ result = format_long_internal(value, &format); break; + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': + case 'n': + case '%': + /* convert to float */ + tmp = PyNumber_Float(value); + if (tmp == NULL) + goto done; + result = format_float_internal(value, &format); + break; + default: /* unknown */ PyErr_Format(PyExc_ValueError, "Unknown conversion type %c", @@ -851,7 +864,6 @@ { PyObject *format_spec; PyObject *result = NULL; - PyObject *tmp = NULL; InternalFormatSpec format; if (!PyArg_ParseTuple(args, STRINGLIB_PARSE_CODE ":__format__", &format_spec)) @@ -890,6 +902,5 @@ } done: - Py_XDECREF(tmp); return result; } From python-3000-checkins at python.org Mon Jan 28 19:36:44 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Mon, 28 Jan 2008 19:36:44 +0100 (CET) Subject: [Python-3000-checkins] r60394 - python/branches/py3k/Lib/bsddb/test/test_compare.py python/branches/py3k/Lib/bsddb/test/test_thread.py Message-ID: <20080128183644.C07421E401C@bag.python.org> Author: christian.heimes Date: Mon Jan 28 19:36:44 2008 New Revision: 60394 Modified: python/branches/py3k/Lib/bsddb/test/test_compare.py python/branches/py3k/Lib/bsddb/test/test_thread.py Log: Fixed two bugs in the bsddb tests. One was reported as #1956 Modified: python/branches/py3k/Lib/bsddb/test/test_compare.py ============================================================================== --- python/branches/py3k/Lib/bsddb/test/test_compare.py (original) +++ python/branches/py3k/Lib/bsddb/test/test_compare.py Mon Jan 28 19:36:44 2008 @@ -6,7 +6,7 @@ import sys, os, re from io import StringIO import tempfile -import test_all +from . import test_all import unittest try: Modified: python/branches/py3k/Lib/bsddb/test/test_thread.py ============================================================================== --- python/branches/py3k/Lib/bsddb/test/test_thread.py (original) +++ python/branches/py3k/Lib/bsddb/test/test_thread.py Mon Jan 28 19:36:44 2008 @@ -51,7 +51,7 @@ self.homeDir = homeDir try: os.mkdir(homeDir) - except OSError, e: + except OSError as e: if e.errno != errno.EEXIST: raise self.env = db.DBEnv() self.setEnvOpts() @@ -68,7 +68,7 @@ self.env.close() try: shutil.rmtree(self.homeDir) - except OSError, e: + except OSError as e: if e.errno != errno.EEXIST: raise def setEnvOpts(self): From python-3000-checkins at python.org Mon Jan 28 20:26:56 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Mon, 28 Jan 2008 20:26:56 +0100 (CET) Subject: [Python-3000-checkins] r60396 - python/branches/py3k/Lib/bsddb/test/test_sequence.py Message-ID: <20080128192656.48BFD1E400C@bag.python.org> Author: christian.heimes Date: Mon Jan 28 20:26:56 2008 New Revision: 60396 Modified: python/branches/py3k/Lib/bsddb/test/test_sequence.py Log: Another fix for the bsddb3 tests Modified: python/branches/py3k/Lib/bsddb/test/test_sequence.py ============================================================================== --- python/branches/py3k/Lib/bsddb/test/test_sequence.py (original) +++ python/branches/py3k/Lib/bsddb/test/test_sequence.py Mon Jan 28 20:26:56 2008 @@ -24,7 +24,7 @@ pass tempfile.tempdir = self.homeDir self.filename = os.path.split(tempfile.mktemp())[1] - tempfile.tempdir = old_tempfile_tempdir + tempfile.tempdir = None self.dbenv = db.DBEnv() self.dbenv.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL, 0o666) From python-3000-checkins at python.org Tue Jan 29 13:18:51 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Tue, 29 Jan 2008 13:18:51 +0100 (CET) Subject: [Python-3000-checkins] r60408 - in python/branches/py3k: Doc/c-api/set.rst Doc/tools/sphinxext Include/setobject.h Lib/ctypes/test/test_funcptr.py Makefile.pre.in Misc/Vim/python.vim Misc/Vim/syntax_test.py Misc/Vim/vim_syntax.py Modules/_ctypes/_ctypes.c Objects/setobject.c Python/marshal.c setup.py Message-ID: <20080129121851.80B9C1E43B6@bag.python.org> Author: christian.heimes Date: Tue Jan 29 13:18:50 2008 New Revision: 60408 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/c-api/set.rst python/branches/py3k/Doc/tools/sphinxext/ (props changed) python/branches/py3k/Include/setobject.h python/branches/py3k/Lib/ctypes/test/test_funcptr.py python/branches/py3k/Makefile.pre.in python/branches/py3k/Misc/Vim/python.vim python/branches/py3k/Misc/Vim/syntax_test.py python/branches/py3k/Misc/Vim/vim_syntax.py python/branches/py3k/Modules/_ctypes/_ctypes.c python/branches/py3k/Objects/setobject.c python/branches/py3k/Python/marshal.c python/branches/py3k/setup.py Log: Merged revisions 60383-60407 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60388 | thomas.heller | 2008-01-28 09:44:13 +0100 (Mon, 28 Jan 2008) | 1 line Revert rev. 59925, it breaks comtypes (I need to further examine this). ........ r60397 | raymond.hettinger | 2008-01-28 21:34:33 +0100 (Mon, 28 Jan 2008) | 5 lines Make PySet_Add() work with frozensets. Works like PyTuple_SetItem() to build-up values in a brand new frozenset. Also, PyFrozenSet_New() is now guaranteed to produce a distinct new frozenset. ........ r60398 | raymond.hettinger | 2008-01-28 22:34:30 +0100 (Mon, 28 Jan 2008) | 1 line Let marshal built-up sets and frozensets one element at a time (without creating an intermediate tuple). ........ r60399 | raymond.hettinger | 2008-01-28 22:47:42 +0100 (Mon, 28 Jan 2008) | 1 line Factor-out common code with a new macro ........ r60400 | raymond.hettinger | 2008-01-28 22:48:07 +0100 (Mon, 28 Jan 2008) | 1 line Factor-out common code with a new macro ........ r60401 | raymond.hettinger | 2008-01-28 22:51:25 +0100 (Mon, 28 Jan 2008) | 1 line Removed unnecessary conditional (spotted by Neal Norwitz). ........ r60403 | gregory.p.smith | 2008-01-29 00:21:00 +0100 (Tue, 29 Jan 2008) | 4 lines Disable use of BerkeleyDB 4.6.x to see what the odd platform buildbots think. In particular, neal norwitz has traced an Ubuntu sparc64 crash to the Lib/test/bsddb/test_basics.py test when opening a db with DB_THREAD. ........ r60405 | brett.cannon | 2008-01-29 05:13:07 +0100 (Tue, 29 Jan 2008) | 2 lines Fix the reindent rule to use $(BUILDPYTHON). ........ r60406 | brett.cannon | 2008-01-29 05:18:04 +0100 (Tue, 29 Jan 2008) | 3 lines Update Vim syntax highlighting to specify what revision was used to generate the file. ........ r60407 | brett.cannon | 2008-01-29 05:20:56 +0100 (Tue, 29 Jan 2008) | 2 lines Ignore .pyc and .pyo files. ........ Modified: python/branches/py3k/Doc/c-api/set.rst ============================================================================== --- python/branches/py3k/Doc/c-api/set.rst (original) +++ python/branches/py3k/Doc/c-api/set.rst Tue Jan 29 13:18:50 2008 @@ -50,6 +50,12 @@ the constructor functions work with any iterable Python object. +.. cfunction:: int PySet_Check(PyObject *p) + + Return true if *p* is a :class:`set` object or an instance of a subtype. + + .. versionadded:: 2.6 + .. cfunction:: int PyAnySet_Check(PyObject *p) Return true if *p* is a :class:`set` object, a :class:`frozenset` object, or an @@ -84,6 +90,11 @@ set on success or *NULL* on failure. Raise :exc:`TypeError` if *iterable* is not actually iterable. + .. versionchanged:: 2.6 + Now guaranteed to return a brand-new :class:`frozenset`. Formerly, + frozensets of zero-length were a singleton. This got in the way of + building-up new frozensets with :meth:`PySet_Add`. + The following functions and macros are available for instances of :class:`set` or :class:`frozenset` or instances of their subtypes. @@ -110,9 +121,6 @@ the *key* is unhashable. Raise :exc:`PyExc_SystemError` if *anyset* is not a :class:`set`, :class:`frozenset`, or an instance of a subtype. -The following functions are available for instances of :class:`set` or its -subtypes but not for instances of :class:`frozenset` or its subtypes. - .. cfunction:: int PySet_Add(PyObject *set, PyObject *key) @@ -122,6 +130,14 @@ Raise a :exc:`SystemError` if *set* is an not an instance of :class:`set` or its subtype. + .. versionchanged:: 2.6 + Now works with instances of :class:`frozenset` or its subtypes. + Like :cfunc:`PyTuple_SetItem` in that it can be used to fill-in the + values of brand new frozensets before they are exposed to other code. + +The following functions are available for instances of :class:`set` or its +subtypes but not for instances of :class:`frozenset` or its subtypes. + .. cfunction:: int PySet_Discard(PyObject *set, PyObject *key) Modified: python/branches/py3k/Include/setobject.h ============================================================================== --- python/branches/py3k/Include/setobject.h (original) +++ python/branches/py3k/Include/setobject.h Tue Jan 29 13:18:50 2008 @@ -74,6 +74,8 @@ (Py_TYPE(ob) == &PySet_Type || Py_TYPE(ob) == &PyFrozenSet_Type || \ PyType_IsSubtype(Py_TYPE(ob), &PySet_Type) || \ PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type)) +#define PySet_Check(ob) \ + (Py_TYPE(ob) == &PySet_Type || PyType_IsSubtype(Py_TYPE(ob), &PySet_Type)) PyAPI_FUNC(PyObject *) PySet_New(PyObject *); PyAPI_FUNC(PyObject *) PyFrozenSet_New(PyObject *); Modified: python/branches/py3k/Lib/ctypes/test/test_funcptr.py ============================================================================== --- python/branches/py3k/Lib/ctypes/test/test_funcptr.py (original) +++ python/branches/py3k/Lib/ctypes/test/test_funcptr.py Tue Jan 29 13:18:50 2008 @@ -123,11 +123,5 @@ self.failUnlessEqual(strtok(None, b"\n"), "c") self.failUnlessEqual(strtok(None, b"\n"), None) - def test_NULL_funcptr(self): - tp = CFUNCTYPE(c_int) - func = tp() # NULL function pointer - # raise a ValueError when we try to call it - self.assertRaises(ValueError, func) - if __name__ == '__main__': unittest.main() Modified: python/branches/py3k/Makefile.pre.in ============================================================================== --- python/branches/py3k/Makefile.pre.in (original) +++ python/branches/py3k/Makefile.pre.in Tue Jan 29 13:18:50 2008 @@ -1043,7 +1043,7 @@ # Run reindent on the library reindent: - ./python$(EXEEXT) $(srcdir)/Tools/scripts/reindent.py -r $(srcdir)/Lib + ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/reindent.py -r $(srcdir)/Lib # Rerun configure with the same options as it was run last time, # provided the config.status script exists Modified: python/branches/py3k/Misc/Vim/python.vim ============================================================================== --- python/branches/py3k/Misc/Vim/python.vim (original) +++ python/branches/py3k/Misc/Vim/python.vim Tue Jan 29 13:18:50 2008 @@ -1,4 +1,4 @@ -" Auto-generated Vim syntax file for Python +" Auto-generated Vim syntax file for Python (trunk: r60376M). " " To use: copy or symlink to ~/.vim/syntax/python.vim @@ -63,7 +63,7 @@ if exists("python_highlight_builtins") syn keyword pythonBuiltin Ellipsis False None NotImplemented True __debug__ - syn keyword pythonBuiltin __import__ abs all any basestring bool + syn keyword pythonBuiltin __import__ abs all any bool syn keyword pythonBuiltin buffer callable chr classmethod cmp syn keyword pythonBuiltin complex copyright credits delattr dict syn keyword pythonBuiltin dir divmod enumerate eval exec exit @@ -73,7 +73,8 @@ syn keyword pythonBuiltin max min object oct open ord pow property quit syn keyword pythonBuiltin range reload repr reversed round syn keyword pythonBuiltin set setattr slice sorted staticmethod str sum - syn keyword pythonBuiltin super tuple type unichr unicode vars zip + syn keyword pythonBuiltin super trunc tuple type unicode vars + syn keyword pythonBuiltin zip endif Modified: python/branches/py3k/Misc/Vim/syntax_test.py ============================================================================== --- python/branches/py3k/Misc/Vim/syntax_test.py (original) +++ python/branches/py3k/Misc/Vim/syntax_test.py Tue Jan 29 13:18:50 2008 @@ -4,9 +4,8 @@ Not necessarily sensical or comprehensive (assume that if one exception is highlighted that all are, for instance). -Highlighting extraneous whitespace at the end of the line is not represented -here as all trailing whitespace is automatically removed from .py files in the -repository. +Extraneous trailing whitespace can't be tested because of svn pre-commit hook +checks for such things. """ # Comment Modified: python/branches/py3k/Misc/Vim/vim_syntax.py ============================================================================== --- python/branches/py3k/Misc/Vim/vim_syntax.py (original) +++ python/branches/py3k/Misc/Vim/vim_syntax.py Tue Jan 29 13:18:50 2008 @@ -6,8 +6,9 @@ import exceptions import builtins from string import Template +from sys import subversion -comment_header = '''" Auto-generated Vim syntax file for Python. +comment_header = '''" Auto-generated Vim syntax file for Python (%s: r%s). " " To use: copy or symlink to ~/.vim/syntax/python.vim''' @@ -162,7 +163,7 @@ def main(file_path): with open(file_path, 'w') as FILE: # Comment for file - print>>FILE, comment_header + print>>FILE, comment_header % subversion[1:] print>>FILE, '' # Statements at start of file print>>FILE, statement_header Modified: python/branches/py3k/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k/Modules/_ctypes/_ctypes.c Tue Jan 29 13:18:50 2008 @@ -3414,11 +3414,6 @@ pProc = *(void **)self->b_ptr; - if (pProc == NULL) { - PyErr_SetString(PyExc_ValueError, - "attempt to call NULL function pointer"); - return NULL; - } #ifdef MS_WIN32 if (self->index) { /* It's a COM method */ Modified: python/branches/py3k/Objects/setobject.c ============================================================================== --- python/branches/py3k/Objects/setobject.c (original) +++ python/branches/py3k/Objects/setobject.c Tue Jan 29 13:18:50 2008 @@ -2127,17 +2127,7 @@ PyObject * PyFrozenSet_New(PyObject *iterable) { - PyObject *args, *result; - - if (iterable == NULL) - args = PyTuple_New(0); - else - args = PyTuple_Pack(1, iterable); - if (args == NULL) - return NULL; - result = frozenset_new(&PyFrozenSet_Type, args, NULL); - Py_DECREF(args); - return result; + return make_new_set(&PyFrozenSet_Type, iterable); } Py_ssize_t @@ -2153,7 +2143,7 @@ int PySet_Clear(PyObject *set) { - if (!PyType_IsSubtype(Py_TYPE(set), &PySet_Type)) { + if (!PySet_Check(set)) { PyErr_BadInternalCall(); return -1; } @@ -2173,7 +2163,7 @@ int PySet_Discard(PyObject *set, PyObject *key) { - if (!PyType_IsSubtype(Py_TYPE(set), &PySet_Type)) { + if (!PySet_Check(set)) { PyErr_BadInternalCall(); return -1; } @@ -2181,13 +2171,13 @@ } int -PySet_Add(PyObject *set, PyObject *key) +PySet_Add(PyObject *anyset, PyObject *key) { - if (!PyType_IsSubtype(Py_TYPE(set), &PySet_Type)) { + if (!PyAnySet_Check(anyset)) { PyErr_BadInternalCall(); return -1; } - return set_add_key((PySetObject *)set, key); + return set_add_key((PySetObject *)anyset, key); } int @@ -2224,7 +2214,7 @@ PyObject * PySet_Pop(PyObject *set) { - if (!PyType_IsSubtype(Py_TYPE(set), &PySet_Type)) { + if (!PySet_Check(set)) { PyErr_BadInternalCall(); return NULL; } @@ -2234,7 +2224,7 @@ int _PySet_Update(PyObject *set, PyObject *iterable) { - if (!PyType_IsSubtype(Py_TYPE(set), &PySet_Type)) { + if (!PySet_Check(set)) { PyErr_BadInternalCall(); return -1; } @@ -2330,7 +2320,6 @@ f = PyFrozenSet_New(dup); assert(PySet_Size(f) == 3); assert(PyFrozenSet_CheckExact(f)); - assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError); assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError); assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError); Py_DECREF(f); Modified: python/branches/py3k/Python/marshal.c ============================================================================== --- python/branches/py3k/Python/marshal.c (original) +++ python/branches/py3k/Python/marshal.c Tue Jan 29 13:18:50 2008 @@ -812,7 +812,7 @@ retval = NULL; break; } - v = PyTuple_New((int)n); + v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL); if (v == NULL) { retval = NULL; break; @@ -827,18 +827,14 @@ v = NULL; break; } - PyTuple_SET_ITEM(v, (int)i, v2); + if (PySet_Add(v, v2) == -1) { + Py_DECREF(v); + Py_DECREF(v2); + v = NULL; + break; + } } - if (v == NULL) { - retval = NULL; - break; - } - if (type == TYPE_SET) - v3 = PySet_New(v); - else - v3 = PyFrozenSet_New(v); - Py_DECREF(v); - retval = v3; + retval = v; break; case TYPE_CODE: Modified: python/branches/py3k/setup.py ============================================================================== --- python/branches/py3k/setup.py (original) +++ python/branches/py3k/setup.py Tue Jan 29 13:18:50 2008 @@ -652,7 +652,10 @@ # a release. Most open source OSes come with one or more # versions of BerkeleyDB already installed. - max_db_ver = (4, 6) + max_db_ver = (4, 5) # XXX(gregory.p.smith): 4.6 "works" but seems to + # have issues on many platforms. I've temporarily + # disabled 4.6 to see what the odd platform + # buildbots say. min_db_ver = (3, 3) db_setup_debug = False # verbose debug prints from this script? From nnorwitz at gmail.com Tue Jan 29 19:05:23 2008 From: nnorwitz at gmail.com (Neal Norwitz) Date: Tue, 29 Jan 2008 10:05:23 -0800 Subject: [Python-3000-checkins] r60408 - in python/branches/py3k: Doc/c-api/set.rst Doc/tools/sphinxext Include/setobject.h Lib/ctypes/test/test_funcptr.py Makefile.pre.in Misc/Vim/python.vim Misc/Vim/syntax_test.py Misc/Vim/vim_syntax.py Modules/_ctypes/ Message-ID: On Jan 29, 2008 4:18 AM, christian.heimes wrote: > Author: christian.heimes > Date: Tue Jan 29 13:18:50 2008 > New Revision: 60408 > > Modified: python/branches/py3k/Misc/Vim/vim_syntax.py > ============================================================================== > --- python/branches/py3k/Misc/Vim/vim_syntax.py (original) > +++ python/branches/py3k/Misc/Vim/vim_syntax.py Tue Jan 29 13:18:50 2008 > @@ -6,8 +6,9 @@ > import exceptions > import builtins > from string import Template > +from sys import subversion > > -comment_header = '''" Auto-generated Vim syntax file for Python. > +comment_header = '''" Auto-generated Vim syntax file for Python (%s: r%s). > " > " To use: copy or symlink to ~/.vim/syntax/python.vim''' > > @@ -162,7 +163,7 @@ > def main(file_path): > with open(file_path, 'w') as FILE: > # Comment for file > - print>>FILE, comment_header > + print>>FILE, comment_header % subversion[1:] > print>>FILE, '' > # Statements at start of file > print>>FILE, statement_header It seems we need to run 2to3 over the Misc/Vim directory. Looks like it has never been done. n From python-3000-checkins at python.org Tue Jan 29 22:00:37 2008 From: python-3000-checkins at python.org (thomas.heller) Date: Tue, 29 Jan 2008 22:00:37 +0100 (CET) Subject: [Python-3000-checkins] r60428 - python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py Message-ID: <20080129210037.6A2691E4011@bag.python.org> Author: thomas.heller Date: Tue Jan 29 22:00:37 2008 New Revision: 60428 Modified: python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py Log: Add comments to clarify the tests. Modified: python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py ============================================================================== --- python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py (original) +++ python/branches/py3k-ctypes-pep3118/Lib/ctypes/test/test_pep3118.py Tue Jan 29 22:00:37 2008 @@ -84,6 +84,11 @@ class aUnion(Union): _fields_ = [("a", c_int)] +################################################################ +# +# This table contains format strings as they look on little endian +# machines. The test replaces '<' with '>' on big endian machines. +# native_types = [ # type format shape calc itemsize @@ -149,6 +154,11 @@ class LEPoint(LittleEndianStructure): _fields_ = [("x", c_long), ("y", c_long)] +################################################################ +# +# This table contains format strings as they really look, on both big +# and little endian machines. +# endian_types = [ (BEPoint, "T{>l:x:>l:y:}", None, BEPoint), (LEPoint, "T{ Author: raymond.hettinger Date: Wed Jan 30 03:55:10 2008 New Revision: 60434 Modified: python/branches/py3k/Lib/bsddb/dbtables.py python/branches/py3k/Lib/bsddb/test/test_compare.py python/branches/py3k/Lib/ctypes/util.py python/branches/py3k/Lib/idlelib/MultiCall.py python/branches/py3k/Lib/idlelib/TreeWidget.py python/branches/py3k/Lib/pyclbr.py python/branches/py3k/Lib/pydoc.py python/branches/py3k/Lib/tarfile.py python/branches/py3k/Lib/unittest.py python/branches/py3k/Tools/pynche/ColorDB.py python/branches/py3k/Tools/scripts/finddiv.py python/branches/py3k/Tools/unicode/makeunicodedata.py Log: Convert some custom sort comparison functions to equivalent key functions. Modified: python/branches/py3k/Lib/bsddb/dbtables.py ============================================================================== --- python/branches/py3k/Lib/bsddb/dbtables.py (original) +++ python/branches/py3k/Lib/bsddb/dbtables.py Wed Jan 30 03:55:10 2008 @@ -88,6 +88,15 @@ def __call__(self, s): return self.re.match(s.decode(self.encoding)) +def CmpToKey(mycmp): + 'Convert a cmp= function into a key= function' + class K(object): + def __init__(self, obj, *args): + self.obj = obj + def __lt__(self, other): + return mycmp(self.obj, other.obj) == -1 + return K + # # keys used to store database metadata # @@ -587,7 +596,7 @@ return 0 conditionlist = list(conditions.items()) - conditionlist.sort(cmp_conditions) + conditionlist.sort(key=CmpToKey(cmp_conditions)) # Apply conditions to column data to find what we want cur = self.db.cursor() Modified: python/branches/py3k/Lib/bsddb/test/test_compare.py ============================================================================== --- python/branches/py3k/Lib/bsddb/test/test_compare.py (original) +++ python/branches/py3k/Lib/bsddb/test/test_compare.py Wed Jan 30 03:55:10 2008 @@ -32,10 +32,20 @@ _expected_lowercase_test_data = [s.encode('ascii') for s in ('', 'a', 'aaa', 'b', 'c', 'CC', 'cccce', 'ccccf', 'CCCP')] + +def CmpToKey(mycmp): + 'Convert a cmp= function into a key= function' + class K(object): + def __init__(self, obj, *args): + self.obj = obj + def __lt__(self, other): + return mycmp(self.obj, other.obj) == -1 + return K + class ComparatorTests (unittest.TestCase): def comparator_test_helper (self, comparator, expected_data): data = expected_data[:] - data.sort (comparator) + data.sort (key=CmpToKey(comparator)) self.failUnless (data == expected_data, "comparator `%s' is not right: %s vs. %s" % (comparator, expected_data, data)) Modified: python/branches/py3k/Lib/ctypes/util.py ============================================================================== --- python/branches/py3k/Lib/ctypes/util.py (original) +++ python/branches/py3k/Lib/ctypes/util.py Wed Jan 30 03:55:10 2008 @@ -123,7 +123,7 @@ res = re.findall(expr, data) if not res: return _get_soname(_findLib_gcc(name)) - res.sort(cmp= lambda x,y: cmp(_num_version(x), _num_version(y))) + res.sort(key=_num_version) return res[-1] else: Modified: python/branches/py3k/Lib/idlelib/MultiCall.py ============================================================================== --- python/branches/py3k/Lib/idlelib/MultiCall.py (original) +++ python/branches/py3k/Lib/idlelib/MultiCall.py Wed Jan 30 03:55:10 2008 @@ -125,7 +125,7 @@ statelist = [] for state in states: substates = list(set(state & x for x in states)) - substates.sort(lambda a,b: nbits(b) - nbits(a)) + substates.sort(key=nbits, reverse=True) statelist.append(substates) return statelist Modified: python/branches/py3k/Lib/idlelib/TreeWidget.py ============================================================================== --- python/branches/py3k/Lib/idlelib/TreeWidget.py (original) +++ python/branches/py3k/Lib/idlelib/TreeWidget.py Wed Jan 30 03:55:10 2008 @@ -398,7 +398,7 @@ names = os.listdir(self.path) except os.error: return [] - names.sort(lambda a, b: cmp(os.path.normcase(a), os.path.normcase(b))) + names.sort(key = os.path.normcase) sublist = [] for name in names: item = FileTreeItem(os.path.join(self.path, name)) Modified: python/branches/py3k/Lib/pyclbr.py ============================================================================== --- python/branches/py3k/Lib/pyclbr.py (original) +++ python/branches/py3k/Lib/pyclbr.py Wed Jan 30 03:55:10 2008 @@ -324,8 +324,7 @@ path = [] dict = readmodule_ex(mod, path) objs = dict.values() - objs.sort(lambda a, b: cmp(getattr(a, 'lineno', 0), - getattr(b, 'lineno', 0))) + objs.sort(key=lambda a: getattr(a, 'lineno', 0)) for obj in objs: if isinstance(obj, Class): print("class", obj.name, obj.super, obj.lineno) Modified: python/branches/py3k/Lib/pydoc.py ============================================================================== --- python/branches/py3k/Lib/pydoc.py (original) +++ python/branches/py3k/Lib/pydoc.py Wed Jan 30 03:55:10 2008 @@ -797,10 +797,7 @@ tag += ':
\n' # Sort attrs by name. - try: - attrs.sort(key=lambda t: t[0]) - except TypeError: - attrs.sort(lambda t1, t2: cmp(t1[0], t2[0])) # 2.3 compat + attrs.sort(key=lambda t: t[0]) # Pump out the attrs, segregated by kind. attrs = spill('Methods %s' % tag, attrs, Modified: python/branches/py3k/Lib/tarfile.py ============================================================================== --- python/branches/py3k/Lib/tarfile.py (original) +++ python/branches/py3k/Lib/tarfile.py Wed Jan 30 03:55:10 2008 @@ -2016,7 +2016,7 @@ self.extract(tarinfo, path) # Reverse sort directories. - directories.sort(lambda a, b: cmp(a.name, b.name)) + directories.sort(key=lambda a: a.name) directories.reverse() # Set correct owner, mtime and filemode on directories. Modified: python/branches/py3k/Lib/unittest.py ============================================================================== --- python/branches/py3k/Lib/unittest.py (original) +++ python/branches/py3k/Lib/unittest.py Wed Jan 30 03:55:10 2008 @@ -504,6 +504,15 @@ # Locating and loading tests ############################################################################## +def CmpToKey(mycmp): + 'Convert a cmp= function into a key= function' + class K(object): + def __init__(self, obj, *args): + self.obj = obj + def __lt__(self, other): + return mycmp(self.obj, other.obj) == -1 + return K + class TestLoader: """This class is responsible for loading tests according to various criteria and returning them wrapped in a TestSuite @@ -598,7 +607,7 @@ and hasattr(getattr(testCaseClass, attrname), '__call__') testFnNames = list(filter(isTestMethod, dir(testCaseClass))) if self.sortTestMethodsUsing: - testFnNames.sort(self.sortTestMethodsUsing) + testFnNames.sort(key=CmpToKey(self.sortTestMethodsUsing)) return testFnNames Modified: python/branches/py3k/Tools/pynche/ColorDB.py ============================================================================== --- python/branches/py3k/Tools/pynche/ColorDB.py (original) +++ python/branches/py3k/Tools/pynche/ColorDB.py Wed Jan 30 03:55:10 2008 @@ -122,10 +122,7 @@ self.__allnames = [] for name, aliases in self.__byrgb.values(): self.__allnames.append(name) - # sort irregardless of case - def nocase_cmp(n1, n2): - return cmp(n1.lower(), n2.lower()) - self.__allnames.sort(nocase_cmp) + self.__allnames.sort(key=unicode.lower) return self.__allnames def aliases_of(self, red, green, blue): Modified: python/branches/py3k/Tools/scripts/finddiv.py ============================================================================== --- python/branches/py3k/Tools/scripts/finddiv.py (original) +++ python/branches/py3k/Tools/scripts/finddiv.py Wed Jan 30 03:55:10 2008 @@ -78,7 +78,7 @@ fn = os.path.join(dir, name) if os.path.normcase(fn).endswith(".py") or os.path.isdir(fn): files.append(fn) - files.sort(lambda a, b: cmp(os.path.normcase(a), os.path.normcase(b))) + files.sort(key=os.path.normcase) exit = None for fn in files: x = process(fn, listnames) Modified: python/branches/py3k/Tools/unicode/makeunicodedata.py ============================================================================== --- python/branches/py3k/Tools/unicode/makeunicodedata.py (original) +++ python/branches/py3k/Tools/unicode/makeunicodedata.py Wed Jan 30 03:55:10 2008 @@ -441,6 +441,15 @@ # -------------------------------------------------------------------- # unicode name database +def CmpToKey(mycmp): + 'Convert a cmp= function into a key= function' + class K(object): + def __init__(self, obj, *args): + self.obj = obj + def __lt__(self, other): + return mycmp(self.obj, other.obj) == -1 + return K + def makeunicodename(unicode, trace): FILE = "Modules/unicodename_db.h" @@ -490,7 +499,7 @@ if r: return r return cmp(aword, bword) - wordlist.sort(cmpwords) + wordlist.sort(key=CmpToKey(cmpwords)) # figure out how many phrasebook escapes we need escapes = 0 @@ -514,7 +523,7 @@ # length (to maximize overlap) wordlist, wordtail = wordlist[:short], wordlist[short:] - wordtail.sort(lambda a, b: len(b[0])-len(a[0])) + wordtail.sort(key=lambda a: a[0], reverse=True) wordlist.extend(wordtail) # generate lexicon from words From python-3000-checkins at python.org Wed Jan 30 10:51:48 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Wed, 30 Jan 2008 10:51:48 +0100 (CET) Subject: [Python-3000-checkins] r60437 - in python/branches/py3k: Lib/test/test_bytes.py Misc/NEWS Objects/bytesobject.c Message-ID: <20080130095148.BD84D1E401C@bag.python.org> Author: christian.heimes Date: Wed Jan 30 10:51:48 2008 New Revision: 60437 Modified: python/branches/py3k/Lib/test/test_bytes.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/bytesobject.c Log: Fixed #1969: split and rsplit in bytearray are inconsistent Modified: python/branches/py3k/Lib/test/test_bytes.py ============================================================================== --- python/branches/py3k/Lib/test/test_bytes.py (original) +++ python/branches/py3k/Lib/test/test_bytes.py Wed Jan 30 10:51:48 2008 @@ -706,7 +706,7 @@ self.assertEqual(b.rsplit(None, 2), [b'arf', b'barf']) self.assertEqual(b' a bb c '.rsplit(None, 0), [b' a bb c']) self.assertEqual(b' a bb c '.rsplit(None, 1), [b' a bb', b'c']) - self.assertEqual(b' a bb c '.rsplit(None,2), [b' a', b'bb', b'c']) + self.assertEqual(b' a bb c '.rsplit(None, 2), [b' a', b'bb', b'c']) self.assertEqual(b' a bb c '.rsplit(None, 3), [b'a', b'bb', b'c']) def test_rsplit_bytearray(self): @@ -715,6 +715,15 @@ def test_rsplit_string_error(self): self.assertRaises(TypeError, b'a b'.rsplit, ' ') + def test_rsplit_unicodewhitespace(self): + b = b"\x09\x0A\x0B\x0C\x0D\x1C\x1D\x1E\x1F" + self.assertEqual(b.split(), [b'\x1c\x1d\x1e\x1f']) + self.assertEqual(b.rsplit(), [b'\x1c\x1d\x1e\x1f']) + ba = bytearray(b) + self.assertEqual(ba.split(), [bytearray(b'\x1c\x1d\x1e\x1f')]) + self.assertEqual(ba.rsplit(), [bytearray(b'\x1c\x1d\x1e\x1f')]) + + def test_partition(self): b = b'mississippi' self.assertEqual(b.partition(b'ss'), (b'mi', b'ss', b'issippi')) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Jan 30 10:51:48 2008 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #1969: split and rsplit in bytearray are inconsistent + - map() and itertools.imap() no longer accept None for the first argument. Use zip() instead. Modified: python/branches/py3k/Objects/bytesobject.c ============================================================================== --- python/branches/py3k/Objects/bytesobject.c (original) +++ python/branches/py3k/Objects/bytesobject.c Wed Jan 30 10:51:48 2008 @@ -2388,16 +2388,16 @@ for (i = j = len - 1; i >= 0; ) { /* find a token */ - while (i >= 0 && Py_UNICODE_ISSPACE(s[i])) + while (i >= 0 && ISSPACE(s[i])) i--; j = i; - while (i >= 0 && !Py_UNICODE_ISSPACE(s[i])) + while (i >= 0 && !ISSPACE(s[i])) i--; if (j > i) { if (maxcount-- <= 0) break; SPLIT_ADD(s, i + 1, j + 1); - while (i >= 0 && Py_UNICODE_ISSPACE(s[i])) + while (i >= 0 && ISSPACE(s[i])) i--; j = i; } From python-3000-checkins at python.org Wed Jan 30 12:27:58 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Wed, 30 Jan 2008 12:27:58 +0100 (CET) Subject: [Python-3000-checkins] r60438 - python/branches/py3k/Misc/NEWS Message-ID: <20080130112758.4BC201E4006@bag.python.org> Author: christian.heimes Date: Wed Jan 30 12:27:57 2008 New Revision: 60438 Modified: python/branches/py3k/Misc/NEWS Log: Fixed issue #1973: bytes.fromhex('') raises SystemError Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Jan 30 12:27:57 2008 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #1973: bytes.fromhex('') raises SystemError + - Issue #1969: split and rsplit in bytearray are inconsistent - map() and itertools.imap() no longer accept None for the first argument. From python-3000-checkins at python.org Wed Jan 30 12:28:29 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Wed, 30 Jan 2008 12:28:29 +0100 (CET) Subject: [Python-3000-checkins] r60439 - python/branches/py3k/Objects/stringobject.c Message-ID: <20080130112829.73F1F1E4006@bag.python.org> Author: christian.heimes Date: Wed Jan 30 12:28:29 2008 New Revision: 60439 Modified: python/branches/py3k/Objects/stringobject.c Log: Fixed issue #1973: bytes.fromhex('') raises SystemError Modified: python/branches/py3k/Objects/stringobject.c ============================================================================== --- python/branches/py3k/Objects/stringobject.c (original) +++ python/branches/py3k/Objects/stringobject.c Wed Jan 30 12:28:29 2008 @@ -2772,7 +2772,7 @@ } buf[j++] = (top << 4) + bot; } - if (_PyString_Resize(&newstring, j) < 0) + if (j != byteslen && _PyString_Resize(&newstring, j) < 0) goto error; return newstring; @@ -2788,7 +2788,7 @@ return Py_BuildValue("(s#)", v->ob_sval, Py_SIZE(v)); } - + static PyMethodDef string_methods[] = { {"__getnewargs__", (PyCFunction)string_getnewargs, METH_NOARGS}, From python-3000-checkins at python.org Wed Jan 30 12:57:59 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Wed, 30 Jan 2008 12:57:59 +0100 (CET) Subject: [Python-3000-checkins] r60442 - python/branches/py3k/Lib/test/test_bytes.py Message-ID: <20080130115759.414601E4011@bag.python.org> Author: christian.heimes Date: Wed Jan 30 12:57:58 2008 New Revision: 60442 Modified: python/branches/py3k/Lib/test/test_bytes.py Log: Patch #1972 by Antoine Pitrou: improve bytes and bytearray tests Modified: python/branches/py3k/Lib/test/test_bytes.py ============================================================================== --- python/branches/py3k/Lib/test/test_bytes.py (original) +++ python/branches/py3k/Lib/test/test_bytes.py Wed Jan 30 12:57:58 2008 @@ -13,12 +13,13 @@ import tempfile import unittest import warnings +import functools import test.test_support import test.string_tests import test.buffer_tests -class BytesTest(unittest.TestCase): +class BaseBytesTest(unittest.TestCase): def setUp(self): self.warning_filters = warnings.filters[:] @@ -27,12 +28,12 @@ warnings.filters = self.warning_filters def test_basics(self): - b = bytearray() - self.assertEqual(type(b), bytearray) - self.assertEqual(b.__class__, bytearray) + b = self.type2test() + self.assertEqual(type(b), self.type2test) + self.assertEqual(b.__class__, self.type2test) def test_empty_sequence(self): - b = bytearray() + b = self.type2test() self.assertEqual(len(b), 0) self.assertRaises(IndexError, lambda: b[0]) self.assertRaises(IndexError, lambda: b[1]) @@ -48,7 +49,7 @@ def test_from_list(self): ints = list(range(256)) - b = bytearray(i for i in ints) + b = self.type2test(i for i in ints) self.assertEqual(len(b), 256) self.assertEqual(list(b), ints) @@ -58,7 +59,7 @@ self.i = i def __index__(self): return self.i - b = bytearray([C(), C(1), C(254), C(255)]) + b = self.type2test([C(), C(1), C(254), C(255)]) self.assertEqual(list(b), [0, 1, 254, 255]) self.assertRaises(ValueError, bytearray, [C(-1)]) self.assertRaises(ValueError, bytearray, [C(256)]) @@ -73,42 +74,30 @@ self.assertEqual(bytearray(b'0'), b'0') def test_constructor_type_errors(self): - self.assertRaises(TypeError, bytearray, 0.0) + self.assertRaises(TypeError, self.type2test, 0.0) class C: pass - self.assertRaises(TypeError, bytearray, ["0"]) - self.assertRaises(TypeError, bytearray, [0.0]) - self.assertRaises(TypeError, bytearray, [None]) - self.assertRaises(TypeError, bytearray, [C()]) + self.assertRaises(TypeError, self.type2test, ["0"]) + self.assertRaises(TypeError, self.type2test, [0.0]) + self.assertRaises(TypeError, self.type2test, [None]) + self.assertRaises(TypeError, self.type2test, [C()]) def test_constructor_value_errors(self): - self.assertRaises(ValueError, bytearray, [-1]) - self.assertRaises(ValueError, bytearray, [-sys.maxsize]) - self.assertRaises(ValueError, bytearray, [-sys.maxsize-1]) - self.assertRaises(ValueError, bytearray, [-sys.maxsize-2]) - self.assertRaises(ValueError, bytearray, [-10**100]) - self.assertRaises(ValueError, bytearray, [256]) - self.assertRaises(ValueError, bytearray, [257]) - self.assertRaises(ValueError, bytearray, [sys.maxsize]) - self.assertRaises(ValueError, bytearray, [sys.maxsize+1]) - self.assertRaises(ValueError, bytearray, [10**100]) - - def test_repr_str(self): - warnings.simplefilter('ignore', BytesWarning) - for f in str, repr: - self.assertEqual(f(bytearray()), "bytearray(b'')") - self.assertEqual(f(bytearray([0])), "bytearray(b'\\x00')") - self.assertEqual(f(bytearray([0, 1, 254, 255])), - "bytearray(b'\\x00\\x01\\xfe\\xff')") - self.assertEqual(f(b"abc"), "b'abc'") - self.assertEqual(f(b"'"), '''b"'"''') - self.assertEqual(f(b"'\""), r"""b'\'"'""") - + self.assertRaises(ValueError, self.type2test, [-1]) + self.assertRaises(ValueError, self.type2test, [-sys.maxsize]) + self.assertRaises(ValueError, self.type2test, [-sys.maxsize-1]) + self.assertRaises(ValueError, self.type2test, [-sys.maxsize-2]) + self.assertRaises(ValueError, self.type2test, [-10**100]) + self.assertRaises(ValueError, self.type2test, [256]) + self.assertRaises(ValueError, self.type2test, [257]) + self.assertRaises(ValueError, self.type2test, [sys.maxsize]) + self.assertRaises(ValueError, self.type2test, [sys.maxsize+1]) + self.assertRaises(ValueError, self.type2test, [10**100]) def test_compare(self): - b1 = bytearray([1, 2, 3]) - b2 = bytearray([1, 2, 3]) - b3 = bytearray([1, 3]) + b1 = self.type2test([1, 2, 3]) + b2 = self.type2test([1, 2, 3]) + b3 = self.type2test([1, 3]) self.assertEqual(b1, b2) self.failUnless(b2 != b3) @@ -128,102 +117,27 @@ self.failIf(b3 < b2) self.failIf(b3 <= b2) - def test_compare_bytes_to_bytearray(self): - self.assertEqual(b"abc" == bytes(b"abc"), True) - self.assertEqual(b"ab" != bytes(b"abc"), True) - self.assertEqual(b"ab" <= bytes(b"abc"), True) - self.assertEqual(b"ab" < bytes(b"abc"), True) - self.assertEqual(b"abc" >= bytes(b"ab"), True) - self.assertEqual(b"abc" > bytes(b"ab"), True) - - self.assertEqual(b"abc" != bytes(b"abc"), False) - self.assertEqual(b"ab" == bytes(b"abc"), False) - self.assertEqual(b"ab" > bytes(b"abc"), False) - self.assertEqual(b"ab" >= bytes(b"abc"), False) - self.assertEqual(b"abc" < bytes(b"ab"), False) - self.assertEqual(b"abc" <= bytes(b"ab"), False) - - self.assertEqual(bytes(b"abc") == b"abc", True) - self.assertEqual(bytes(b"ab") != b"abc", True) - self.assertEqual(bytes(b"ab") <= b"abc", True) - self.assertEqual(bytes(b"ab") < b"abc", True) - self.assertEqual(bytes(b"abc") >= b"ab", True) - self.assertEqual(bytes(b"abc") > b"ab", True) - - self.assertEqual(bytes(b"abc") != b"abc", False) - self.assertEqual(bytes(b"ab") == b"abc", False) - self.assertEqual(bytes(b"ab") > b"abc", False) - self.assertEqual(bytes(b"ab") >= b"abc", False) - self.assertEqual(bytes(b"abc") < b"ab", False) - self.assertEqual(bytes(b"abc") <= b"ab", False) - def test_compare_to_str(self): warnings.simplefilter('ignore', BytesWarning) # Byte comparisons with unicode should always fail! # Test this for all expected byte orders and Unicode character sizes - self.assertEqual(b"\0a\0b\0c" == "abc", False) - self.assertEqual(b"\0\0\0a\0\0\0b\0\0\0c" == "abc", False) - self.assertEqual(b"a\0b\0c\0" == "abc", False) - self.assertEqual(b"a\0\0\0b\0\0\0c\0\0\0" == "abc", False) - self.assertEqual(bytearray() == str(), False) - self.assertEqual(bytearray() != str(), True) - - def test_nohash(self): - self.assertRaises(TypeError, hash, bytearray()) - - def test_doc(self): - self.failUnless(bytearray.__doc__ != None) - self.failUnless(bytearray.__doc__.startswith("bytearray("), bytearray.__doc__) - self.failUnless(bytes.__doc__ != None) - self.failUnless(bytes.__doc__.startswith("bytes("), bytes.__doc__) - - def test_bytearray_api(self): - short_sample = b"Hello world\n" - sample = short_sample + b"\0"*(20 - len(short_sample)) - tfn = tempfile.mktemp() - try: - # Prepare - with open(tfn, "wb") as f: - f.write(short_sample) - # Test readinto - with open(tfn, "rb") as f: - b = bytearray(20) - n = f.readinto(b) - self.assertEqual(n, len(short_sample)) - self.assertEqual(list(b), list(sample)) - # Test writing in binary mode - with open(tfn, "wb") as f: - f.write(b) - with open(tfn, "rb") as f: - self.assertEqual(f.read(), sample) - # Text mode is ambiguous; don't test - finally: - try: - os.remove(tfn) - except os.error: - pass + self.assertEqual(self.type2test(b"\0a\0b\0c") == "abc", False) + self.assertEqual(self.type2test(b"\0\0\0a\0\0\0b\0\0\0c") == "abc", False) + self.assertEqual(self.type2test(b"a\0b\0c\0") == "abc", False) + self.assertEqual(self.type2test(b"a\0\0\0b\0\0\0c\0\0\0") == "abc", False) + self.assertEqual(self.type2test() == str(), False) + self.assertEqual(self.type2test() != str(), True) def test_reversed(self): input = list(map(ord, "Hello")) - b = bytearray(input) + b = self.type2test(input) output = list(reversed(b)) input.reverse() self.assertEqual(output, input) - def test_reverse(self): - b = bytearray(b'hello') - self.assertEqual(b.reverse(), None) - self.assertEqual(b, b'olleh') - b = bytearray(b'hello1') # test even number of items - b.reverse() - self.assertEqual(b, b'1olleh') - b = bytearray() - b.reverse() - self.assertFalse(b) - def test_getslice(self): def by(s): - return bytearray(map(ord, s)) + return self.type2test(map(ord, s)) b = by("Hello, world") self.assertEqual(b[:5], by("Hello")) @@ -244,159 +158,44 @@ def test_extended_getslice(self): # Test extended slicing by comparing with list slicing. L = list(range(255)) - b = bytearray(L) + b = self.type2test(L) indices = (0, None, 1, 3, 19, 100, -1, -2, -31, -100) for start in indices: for stop in indices: # Skip step 0 (invalid) for step in indices[1:]: - self.assertEqual(b[start:stop:step], bytearray(L[start:stop:step])) - - def test_regexps(self): - def by(s): - return bytearray(map(ord, s)) - b = by("Hello, world") - self.assertEqual(re.findall(r"\w+", b), [by("Hello"), by("world")]) - - def test_setitem(self): - b = bytearray([1, 2, 3]) - b[1] = 100 - self.assertEqual(b, bytearray([1, 100, 3])) - b[-1] = 200 - self.assertEqual(b, bytearray([1, 100, 200])) - class C: - def __init__(self, i=0): - self.i = i - def __index__(self): - return self.i - b[0] = C(10) - self.assertEqual(b, bytearray([10, 100, 200])) - try: - b[3] = 0 - self.fail("Didn't raise IndexError") - except IndexError: - pass - try: - b[-10] = 0 - self.fail("Didn't raise IndexError") - except IndexError: - pass - try: - b[0] = 256 - self.fail("Didn't raise ValueError") - except ValueError: - pass - try: - b[0] = C(-1) - self.fail("Didn't raise ValueError") - except ValueError: - pass - try: - b[0] = None - self.fail("Didn't raise TypeError") - except TypeError: - pass - - def test_delitem(self): - b = bytearray(range(10)) - del b[0] - self.assertEqual(b, bytearray(range(1, 10))) - del b[-1] - self.assertEqual(b, bytearray(range(1, 9))) - del b[4] - self.assertEqual(b, bytearray([1, 2, 3, 4, 6, 7, 8])) - - def test_setslice(self): - b = bytearray(range(10)) - self.assertEqual(list(b), list(range(10))) - - b[0:5] = bytearray([1, 1, 1, 1, 1]) - self.assertEqual(b, bytearray([1, 1, 1, 1, 1, 5, 6, 7, 8, 9])) - - del b[0:-5] - self.assertEqual(b, bytearray([5, 6, 7, 8, 9])) - - b[0:0] = bytearray([0, 1, 2, 3, 4]) - self.assertEqual(b, bytearray(range(10))) - - b[-7:-3] = bytearray([100, 101]) - self.assertEqual(b, bytearray([0, 1, 2, 100, 101, 7, 8, 9])) - - b[3:5] = [3, 4, 5, 6] - self.assertEqual(b, bytearray(range(10))) - - b[3:0] = [42, 42, 42] - self.assertEqual(b, bytearray([0, 1, 2, 42, 42, 42, 3, 4, 5, 6, 7, 8, 9])) - - def test_extended_set_del_slice(self): - indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300) - for start in indices: - for stop in indices: - # Skip invalid step 0 - for step in indices[1:]: - L = list(range(255)) - b = bytearray(L) - # Make sure we have a slice of exactly the right length, - # but with different data. - data = L[start:stop:step] - data.reverse() - L[start:stop:step] = data - b[start:stop:step] = data - self.assertEquals(b, bytearray(L)) - - del L[start:stop:step] - del b[start:stop:step] - self.assertEquals(b, bytearray(L)) - - def test_setslice_trap(self): - # This test verifies that we correctly handle assigning self - # to a slice of self (the old Lambert Meertens trap). - b = bytearray(range(256)) - b[8:] = b - self.assertEqual(b, bytearray(list(range(8)) + list(range(256)))) + self.assertEqual(b[start:stop:step], self.type2test(L[start:stop:step])) def test_encoding(self): sample = "Hello world\n\u1234\u5678\u9abc\udef0" for enc in ("utf8", "utf16"): - b = bytearray(sample, enc) - self.assertEqual(b, bytearray(sample.encode(enc))) - self.assertRaises(UnicodeEncodeError, bytearray, sample, "latin1") - b = bytearray(sample, "latin1", "ignore") - self.assertEqual(b, bytearray(sample[:-4], "utf-8")) + b = self.type2test(sample, enc) + self.assertEqual(b, self.type2test(sample.encode(enc))) + self.assertRaises(UnicodeEncodeError, self.type2test, sample, "latin1") + b = self.type2test(sample, "latin1", "ignore") + self.assertEqual(b, self.type2test(sample[:-4], "utf-8")) def test_decode(self): sample = "Hello world\n\u1234\u5678\u9abc\def0\def0" for enc in ("utf8", "utf16"): - b = bytearray(sample, enc) + b = self.type2test(sample, enc) self.assertEqual(b.decode(enc), sample) sample = "Hello world\n\x80\x81\xfe\xff" - b = bytearray(sample, "latin1") + b = self.type2test(sample, "latin1") self.assertRaises(UnicodeDecodeError, b.decode, "utf8") self.assertEqual(b.decode("utf8", "ignore"), "Hello world\n") - def test_from_bytearray(self): - sample = bytes(b"Hello world\n\x80\x81\xfe\xff") - buf = memoryview(sample) - b = bytearray(buf) - self.assertEqual(b, bytearray(sample)) - - def test_to_str(self): - warnings.simplefilter('ignore', BytesWarning) - self.assertEqual(str(b''), "b''") - self.assertEqual(str(b'x'), "b'x'") - self.assertEqual(str(b'\x80'), "b'\\x80'") - def test_from_int(self): - b = bytearray(0) - self.assertEqual(b, bytearray()) - b = bytearray(10) - self.assertEqual(b, bytearray([0]*10)) - b = bytearray(10000) - self.assertEqual(b, bytearray([0]*10000)) + b = self.type2test(0) + self.assertEqual(b, self.type2test()) + b = self.type2test(10) + self.assertEqual(b, self.type2test([0]*10)) + b = self.type2test(10000) + self.assertEqual(b, self.type2test([0]*10000)) def test_concat(self): - b1 = b"abc" - b2 = b"def" + b1 = self.type2test(b"abc") + b2 = self.type2test(b"def") self.assertEqual(b1 + b2, b"abcdef") self.assertEqual(b1 + bytes(b"def"), b"abcdef") self.assertEqual(bytes(b"def") + b1, b"defabc") @@ -404,7 +203,7 @@ self.assertRaises(TypeError, lambda: "abc" + b2) def test_repeat(self): - for b in b"abc", bytearray(b"abc"): + for b in b"abc", self.type2test(b"abc"): self.assertEqual(b * 3, b"abcabcabc") self.assertEqual(b * 0, b"") self.assertEqual(b * -1, b"") @@ -415,200 +214,76 @@ lambda: b * sys.maxsize) def test_repeat_1char(self): - self.assertEqual(b'x'*100, bytearray([ord('x')]*100)) - - def test_iconcat(self): - b = bytearray(b"abc") - b1 = b - b += b"def" - self.assertEqual(b, b"abcdef") - self.assertEqual(b, b1) - self.failUnless(b is b1) - b += b"xyz" - self.assertEqual(b, b"abcdefxyz") - try: - b += "" - except TypeError: - pass - else: - self.fail("bytes += unicode didn't raise TypeError") - - def test_irepeat(self): - b = bytearray(b"abc") - b1 = b - b *= 3 - self.assertEqual(b, b"abcabcabc") - self.assertEqual(b, b1) - self.failUnless(b is b1) - - def test_irepeat_1char(self): - b = bytearray(b"x") - b1 = b - b *= 100 - self.assertEqual(b, b"x"*100) - self.assertEqual(b, b1) - self.failUnless(b is b1) + self.assertEqual(self.type2test(b'x')*100, self.type2test([ord('x')]*100)) def test_contains(self): - for b in b"abc", bytearray(b"abc"): - self.failUnless(ord('a') in b) - self.failUnless(int(ord('a')) in b) - self.failIf(200 in b) - self.failIf(200 in b) - self.assertRaises(ValueError, lambda: 300 in b) - self.assertRaises(ValueError, lambda: -1 in b) - self.assertRaises(TypeError, lambda: None in b) - self.assertRaises(TypeError, lambda: float(ord('a')) in b) - self.assertRaises(TypeError, lambda: "a" in b) - for f in bytes, bytearray: - self.failUnless(f(b"") in b) - self.failUnless(f(b"a") in b) - self.failUnless(f(b"b") in b) - self.failUnless(f(b"c") in b) - self.failUnless(f(b"ab") in b) - self.failUnless(f(b"bc") in b) - self.failUnless(f(b"abc") in b) - self.failIf(f(b"ac") in b) - self.failIf(f(b"d") in b) - self.failIf(f(b"dab") in b) - self.failIf(f(b"abd") in b) - - def test_alloc(self): - b = bytearray() - alloc = b.__alloc__() - self.assert_(alloc >= 0) - seq = [alloc] - for i in range(100): - b += b"x" - alloc = b.__alloc__() - self.assert_(alloc >= len(b)) - if alloc not in seq: - seq.append(alloc) + b = self.type2test(b"abc") + self.failUnless(ord('a') in b) + self.failUnless(int(ord('a')) in b) + self.failIf(200 in b) + self.failIf(200 in b) + self.assertRaises(ValueError, lambda: 300 in b) + self.assertRaises(ValueError, lambda: -1 in b) + self.assertRaises(TypeError, lambda: None in b) + self.assertRaises(TypeError, lambda: float(ord('a')) in b) + self.assertRaises(TypeError, lambda: "a" in b) + for f in bytes, bytearray: + self.failUnless(f(b"") in b) + self.failUnless(f(b"a") in b) + self.failUnless(f(b"b") in b) + self.failUnless(f(b"c") in b) + self.failUnless(f(b"ab") in b) + self.failUnless(f(b"bc") in b) + self.failUnless(f(b"abc") in b) + self.failIf(f(b"ac") in b) + self.failIf(f(b"d") in b) + self.failIf(f(b"dab") in b) + self.failIf(f(b"abd") in b) def test_fromhex(self): - self.assertRaises(TypeError, bytearray.fromhex) - self.assertRaises(TypeError, bytearray.fromhex, 1) - self.assertEquals(bytearray.fromhex(''), bytearray()) + self.assertRaises(TypeError, self.type2test.fromhex) + self.assertRaises(TypeError, self.type2test.fromhex, 1) + # To be fixed + if self.type2test != bytes: + self.assertEquals(self.type2test.fromhex(''), self.type2test()) b = bytearray([0x1a, 0x2b, 0x30]) - self.assertEquals(bytearray.fromhex('1a2B30'), b) - self.assertEquals(bytearray.fromhex(' 1A 2B 30 '), b) - self.assertEquals(bytearray.fromhex('0000'), b'\0\0') - self.assertRaises(TypeError, bytearray.fromhex, b'1B') - self.assertRaises(ValueError, bytearray.fromhex, 'a') - self.assertRaises(ValueError, bytearray.fromhex, 'rt') - self.assertRaises(ValueError, bytearray.fromhex, '1a b cd') - self.assertRaises(ValueError, bytearray.fromhex, '\x00') - self.assertRaises(ValueError, bytearray.fromhex, '12 \x00 34') + self.assertEquals(self.type2test.fromhex('1a2B30'), b) + self.assertEquals(self.type2test.fromhex(' 1A 2B 30 '), b) + self.assertEquals(self.type2test.fromhex('0000'), b'\0\0') + self.assertRaises(TypeError, self.type2test.fromhex, b'1B') + self.assertRaises(ValueError, self.type2test.fromhex, 'a') + self.assertRaises(ValueError, self.type2test.fromhex, 'rt') + self.assertRaises(ValueError, self.type2test.fromhex, '1a b cd') + self.assertRaises(ValueError, self.type2test.fromhex, '\x00') + self.assertRaises(ValueError, self.type2test.fromhex, '12 \x00 34') def test_join(self): - self.assertEqual(b"".join([]), b"") - self.assertEqual(b"".join([b""]), b"") + self.assertEqual(self.type2test(b"").join([]), b"") + self.assertEqual(self.type2test(b"").join([b""]), b"") for lst in [[b"abc"], [b"a", b"bc"], [b"ab", b"c"], [b"a", b"b", b"c"]]: - self.assertEqual(b"".join(lst), b"abc") - self.assertEqual(b"".join(tuple(lst)), b"abc") - self.assertEqual(b"".join(iter(lst)), b"abc") - self.assertEqual(b".".join([b"ab", b"cd"]), b"ab.cd") + lst = list(map(self.type2test, lst)) + self.assertEqual(self.type2test(b"").join(lst), b"abc") + self.assertEqual(self.type2test(b"").join(tuple(lst)), b"abc") + self.assertEqual(self.type2test(b"").join(iter(lst)), b"abc") + self.assertEqual(self.type2test(b".").join([b"ab", b"cd"]), b"ab.cd") # XXX more... - def test_literal(self): - tests = [ - (b"Wonderful spam", "Wonderful spam"), - (br"Wonderful spam too", "Wonderful spam too"), - (b"\xaa\x00\000\200", "\xaa\x00\000\200"), - (br"\xaa\x00\000\200", r"\xaa\x00\000\200"), - ] - for b, s in tests: - self.assertEqual(b, bytearray(s, 'latin-1')) - for c in range(128, 256): - self.assertRaises(SyntaxError, eval, - 'b"%s"' % chr(c)) - - def test_extend(self): - orig = b'hello' - a = bytearray(orig) - a.extend(a) - self.assertEqual(a, orig + orig) - self.assertEqual(a[5:], orig) - a = bytearray(b'') - # Test iterators that don't have a __length_hint__ - a.extend(map(int, orig * 25)) - a.extend(int(x) for x in orig * 25) - self.assertEqual(a, orig * 50) - self.assertEqual(a[-5:], orig) - a = bytearray(b'') - a.extend(iter(map(int, orig * 50))) - self.assertEqual(a, orig * 50) - self.assertEqual(a[-5:], orig) - a = bytearray(b'') - a.extend(list(map(int, orig * 50))) - self.assertEqual(a, orig * 50) - self.assertEqual(a[-5:], orig) - a = bytearray(b'') - self.assertRaises(ValueError, a.extend, [0, 1, 2, 256]) - self.assertRaises(ValueError, a.extend, [0, 1, 2, -1]) - self.assertEqual(len(a), 0) - - def test_remove(self): - b = bytearray(b'hello') - b.remove(ord('l')) - self.assertEqual(b, b'helo') - b.remove(ord('l')) - self.assertEqual(b, b'heo') - self.assertRaises(ValueError, lambda: b.remove(ord('l'))) - self.assertRaises(ValueError, lambda: b.remove(400)) - self.assertRaises(TypeError, lambda: b.remove('e')) - # remove first and last - b.remove(ord('o')) - b.remove(ord('h')) - self.assertEqual(b, b'e') - self.assertRaises(TypeError, lambda: b.remove(b'e')) - - def test_pop(self): - b = bytearray(b'world') - self.assertEqual(b.pop(), ord('d')) - self.assertEqual(b.pop(0), ord('w')) - self.assertEqual(b.pop(-2), ord('r')) - self.assertRaises(IndexError, lambda: b.pop(10)) - self.assertRaises(OverflowError, lambda: bytearray().pop()) - - def test_nosort(self): - self.assertRaises(AttributeError, lambda: bytearray().sort()) - def test_index(self): - b = b'parrot' + b = self.type2test(b'parrot') self.assertEqual(b.index('p'), 0) self.assertEqual(b.index('rr'), 2) self.assertEqual(b.index('t'), 5) self.assertRaises(ValueError, lambda: b.index('w')) def test_count(self): - b = b'mississippi' + b = self.type2test(b'mississippi') self.assertEqual(b.count(b'i'), 4) self.assertEqual(b.count(b'ss'), 2) self.assertEqual(b.count(b'w'), 0) - def test_append(self): - b = bytearray(b'hell') - b.append(ord('o')) - self.assertEqual(b, b'hello') - self.assertEqual(b.append(100), None) - b = bytearray() - b.append(ord('A')) - self.assertEqual(len(b), 1) - self.assertRaises(TypeError, lambda: b.append(b'o')) - - def test_insert(self): - b = bytearray(b'msssspp') - b.insert(1, ord('i')) - b.insert(4, ord('i')) - b.insert(-2, ord('i')) - b.insert(1000, ord('i')) - self.assertEqual(b, b'mississippi') - self.assertRaises(TypeError, lambda: b.insert(0, b'1')) - def test_startswith(self): - b = b'hello' - self.assertFalse(bytearray().startswith(b"anything")) + b = self.type2test(b'hello') + self.assertFalse(self.type2test().startswith(b"anything")) self.assertTrue(b.startswith(b"hello")) self.assertTrue(b.startswith(b"hel")) self.assertTrue(b.startswith(b"h")) @@ -616,7 +291,7 @@ self.assertFalse(b.startswith(b"ha")) def test_endswith(self): - b = b'hello' + b = self.type2test(b'hello') self.assertFalse(bytearray().endswith(b"anything")) self.assertTrue(b.endswith(b"hello")) self.assertTrue(b.endswith(b"llo")) @@ -625,7 +300,7 @@ self.assertFalse(b.endswith(b"no")) def test_find(self): - b = b'mississippi' + b = self.type2test(b'mississippi') self.assertEqual(b.find(b'ss'), 2) self.assertEqual(b.find(b'ss', 3), 5) self.assertEqual(b.find(b'ss', 1, 7), 2) @@ -634,7 +309,7 @@ self.assertEqual(b.find(b'mississippian'), -1) def test_rfind(self): - b = b'mississippi' + b = self.type2test(b'mississippi') self.assertEqual(b.rfind(b'ss'), 5) self.assertEqual(b.rfind(b'ss', 3), 5) self.assertEqual(b.rfind(b'ss', 0, 6), 2) @@ -642,7 +317,7 @@ self.assertEqual(b.rfind(b'mississippian'), -1) def test_index(self): - b = b'world' + b = self.type2test(b'world') self.assertEqual(b.index(b'w'), 0) self.assertEqual(b.index(b'orl'), 1) self.assertRaises(ValueError, b.index, b'worm') @@ -650,27 +325,19 @@ def test_rindex(self): # XXX could be more rigorous - b = b'world' + b = self.type2test(b'world') self.assertEqual(b.rindex(b'w'), 0) self.assertEqual(b.rindex(b'orl'), 1) self.assertRaises(ValueError, b.rindex, b'worm') self.assertRaises(ValueError, b.rindex, b'ldo') def test_replace(self): - b = b'mississippi' + b = self.type2test(b'mississippi') self.assertEqual(b.replace(b'i', b'a'), b'massassappa') self.assertEqual(b.replace(b'ss', b'x'), b'mixixippi') - def test_translate(self): - b = b'hello' - rosetta = bytearray(range(0, 256)) - rosetta[ord('o')] = ord('e') - c = b.translate(rosetta, b'l') - self.assertEqual(b, b'hello') - self.assertEqual(c, b'hee') - def test_split(self): - b = b'mississippi' + b = self.type2test(b'mississippi') self.assertEqual(b.split(b'i'), [b'm', b'ss', b'ss', b'pp', b'']) self.assertEqual(b.split(b'ss'), [b'mi', b'i', b'ippi']) self.assertEqual(b.split(b'w'), [b]) @@ -678,22 +345,23 @@ def test_split_whitespace(self): for b in (b' arf barf ', b'arf\tbarf', b'arf\nbarf', b'arf\rbarf', b'arf\fbarf', b'arf\vbarf'): + b = self.type2test(b) self.assertEqual(b.split(), [b'arf', b'barf']) self.assertEqual(b.split(None), [b'arf', b'barf']) self.assertEqual(b.split(None, 2), [b'arf', b'barf']) - self.assertEqual(b' a bb c '.split(None, 0), [b'a bb c ']) - self.assertEqual(b' a bb c '.split(None, 1), [b'a', b'bb c ']) - self.assertEqual(b' a bb c '.split(None, 2), [b'a', b'bb', b'c ']) - self.assertEqual(b' a bb c '.split(None, 3), [b'a', b'bb', b'c']) - - def test_split_bytearray(self): - self.assertEqual(b'a b'.split(memoryview(b' ')), [b'a', b'b']) + for b in (b'a\x1Cb', b'a\x1Db', b'a\x1Eb', b'a\x1Fb'): + b = self.type2test(b) + self.assertEqual(b.split(), [b]) + self.assertEqual(self.type2test(b' a bb c ').split(None, 0), [b'a bb c ']) + self.assertEqual(self.type2test(b' a bb c ').split(None, 1), [b'a', b'bb c ']) + self.assertEqual(self.type2test(b' a bb c ').split(None, 2), [b'a', b'bb', b'c ']) + self.assertEqual(self.type2test(b' a bb c ').split(None, 3), [b'a', b'bb', b'c']) def test_split_string_error(self): - self.assertRaises(TypeError, b'a b'.split, ' ') + self.assertRaises(TypeError, self.type2test(b'a b').split, ' ') def test_rsplit(self): - b = b'mississippi' + b = self.type2test(b'mississippi') self.assertEqual(b.rsplit(b'i'), [b'm', b'ss', b'ss', b'pp', b'']) self.assertEqual(b.rsplit(b'ss'), [b'mi', b'i', b'ippi']) self.assertEqual(b.rsplit(b'w'), [b]) @@ -701,48 +369,43 @@ def test_rsplit_whitespace(self): for b in (b' arf barf ', b'arf\tbarf', b'arf\nbarf', b'arf\rbarf', b'arf\fbarf', b'arf\vbarf'): + b = self.type2test(b) self.assertEqual(b.rsplit(), [b'arf', b'barf']) self.assertEqual(b.rsplit(None), [b'arf', b'barf']) self.assertEqual(b.rsplit(None, 2), [b'arf', b'barf']) - self.assertEqual(b' a bb c '.rsplit(None, 0), [b' a bb c']) - self.assertEqual(b' a bb c '.rsplit(None, 1), [b' a bb', b'c']) - self.assertEqual(b' a bb c '.rsplit(None, 2), [b' a', b'bb', b'c']) - self.assertEqual(b' a bb c '.rsplit(None, 3), [b'a', b'bb', b'c']) - - def test_rsplit_bytearray(self): - self.assertEqual(b'a b'.rsplit(memoryview(b' ')), [b'a', b'b']) + self.assertEqual(self.type2test(b' a bb c ').rsplit(None, 0), [b' a bb c']) + self.assertEqual(self.type2test(b' a bb c ').rsplit(None, 1), [b' a bb', b'c']) + self.assertEqual(self.type2test(b' a bb c ').rsplit(None, 2), [b' a', b'bb', b'c']) + self.assertEqual(self.type2test(b' a bb c ').rsplit(None, 3), [b'a', b'bb', b'c']) def test_rsplit_string_error(self): - self.assertRaises(TypeError, b'a b'.rsplit, ' ') + self.assertRaises(TypeError, self.type2test(b'a b').rsplit, ' ') def test_rsplit_unicodewhitespace(self): - b = b"\x09\x0A\x0B\x0C\x0D\x1C\x1D\x1E\x1F" + b = self.type2test(b"\x09\x0A\x0B\x0C\x0D\x1C\x1D\x1E\x1F") self.assertEqual(b.split(), [b'\x1c\x1d\x1e\x1f']) self.assertEqual(b.rsplit(), [b'\x1c\x1d\x1e\x1f']) - ba = bytearray(b) - self.assertEqual(ba.split(), [bytearray(b'\x1c\x1d\x1e\x1f')]) - self.assertEqual(ba.rsplit(), [bytearray(b'\x1c\x1d\x1e\x1f')]) - def test_partition(self): - b = b'mississippi' + b = self.type2test(b'mississippi') self.assertEqual(b.partition(b'ss'), (b'mi', b'ss', b'issippi')) self.assertEqual(b.rpartition(b'w'), (b'', b'', b'mississippi')) def test_rpartition(self): - b = b'mississippi' + b = self.type2test(b'mississippi') self.assertEqual(b.rpartition(b'ss'), (b'missi', b'ss', b'ippi')) self.assertEqual(b.rpartition(b'i'), (b'mississipp', b'i', b'')) def test_pickling(self): for proto in range(pickle.HIGHEST_PROTOCOL): for b in b"", b"a", b"abc", b"\xffab\x80", b"\0\0\377\0\0": + b = self.type2test(b) ps = pickle.dumps(b, proto) q = pickle.loads(ps) self.assertEqual(b, q) def test_strip(self): - b = b'mississippi' + b = self.type2test(b'mississippi') self.assertEqual(b.strip(b'i'), b'mississipp') self.assertEqual(b.strip(b'm'), b'ississippi') self.assertEqual(b.strip(b'pi'), b'mississ') @@ -751,7 +414,7 @@ self.assertEqual(b.strip(b), b'') def test_lstrip(self): - b = b'mississippi' + b = self.type2test(b'mississippi') self.assertEqual(b.lstrip(b'i'), b'mississippi') self.assertEqual(b.lstrip(b'm'), b'ississippi') self.assertEqual(b.lstrip(b'pi'), b'mississippi') @@ -759,7 +422,7 @@ self.assertEqual(b.lstrip(b'pim'), b'ssissippi') def test_rstrip(self): - b = b'mississippi' + b = self.type2test(b'mississippi') self.assertEqual(b.rstrip(b'i'), b'mississipp') self.assertEqual(b.rstrip(b'm'), b'mississippi') self.assertEqual(b.rstrip(b'pi'), b'mississ') @@ -767,26 +430,290 @@ self.assertEqual(b.rstrip(b'pim'), b'mississ') def test_strip_whitespace(self): - b = b' \t\n\r\f\vabc \t\n\r\f\v' + b = self.type2test(b' \t\n\r\f\vabc \t\n\r\f\v') self.assertEqual(b.strip(), b'abc') self.assertEqual(b.lstrip(), b'abc \t\n\r\f\v') self.assertEqual(b.rstrip(), b' \t\n\r\f\vabc') def test_strip_bytearray(self): - self.assertEqual(b'abc'.strip(memoryview(b'ac')), b'b') - self.assertEqual(b'abc'.lstrip(memoryview(b'ac')), b'bc') - self.assertEqual(b'abc'.rstrip(memoryview(b'ac')), b'ab') + self.assertEqual(self.type2test(b'abc').strip(memoryview(b'ac')), b'b') + self.assertEqual(self.type2test(b'abc').lstrip(memoryview(b'ac')), b'bc') + self.assertEqual(self.type2test(b'abc').rstrip(memoryview(b'ac')), b'ab') def test_strip_string_error(self): - self.assertRaises(TypeError, b'abc'.strip, 'b') - self.assertRaises(TypeError, b'abc'.lstrip, 'b') - self.assertRaises(TypeError, b'abc'.rstrip, 'b') + self.assertRaises(TypeError, self.type2test(b'abc').strip, 'b') + self.assertRaises(TypeError, self.type2test(b'abc').lstrip, 'b') + self.assertRaises(TypeError, self.type2test(b'abc').rstrip, 'b') def test_ord(self): - b = b'\0A\x7f\x80\xff' + b = self.type2test(b'\0A\x7f\x80\xff') self.assertEqual([ord(b[i:i+1]) for i in range(len(b))], [0, 65, 127, 128, 255]) + +class BytesTest(BaseBytesTest): + type2test = bytes + +class ByteArrayTest(BaseBytesTest): + type2test = bytearray + + def test_nohash(self): + self.assertRaises(TypeError, hash, bytearray()) + + def test_bytearray_api(self): + short_sample = b"Hello world\n" + sample = short_sample + b"\0"*(20 - len(short_sample)) + tfn = tempfile.mktemp() + try: + # Prepare + with open(tfn, "wb") as f: + f.write(short_sample) + # Test readinto + with open(tfn, "rb") as f: + b = bytearray(20) + n = f.readinto(b) + self.assertEqual(n, len(short_sample)) + self.assertEqual(list(b), list(sample)) + # Test writing in binary mode + with open(tfn, "wb") as f: + f.write(b) + with open(tfn, "rb") as f: + self.assertEqual(f.read(), sample) + # Text mode is ambiguous; don't test + finally: + try: + os.remove(tfn) + except os.error: + pass + + def test_reverse(self): + b = bytearray(b'hello') + self.assertEqual(b.reverse(), None) + self.assertEqual(b, b'olleh') + b = bytearray(b'hello1') # test even number of items + b.reverse() + self.assertEqual(b, b'1olleh') + b = bytearray() + b.reverse() + self.assertFalse(b) + + def test_regexps(self): + def by(s): + return bytearray(map(ord, s)) + b = by("Hello, world") + self.assertEqual(re.findall(r"\w+", b), [by("Hello"), by("world")]) + + def test_setitem(self): + b = bytearray([1, 2, 3]) + b[1] = 100 + self.assertEqual(b, bytearray([1, 100, 3])) + b[-1] = 200 + self.assertEqual(b, bytearray([1, 100, 200])) + class C: + def __init__(self, i=0): + self.i = i + def __index__(self): + return self.i + b[0] = C(10) + self.assertEqual(b, bytearray([10, 100, 200])) + try: + b[3] = 0 + self.fail("Didn't raise IndexError") + except IndexError: + pass + try: + b[-10] = 0 + self.fail("Didn't raise IndexError") + except IndexError: + pass + try: + b[0] = 256 + self.fail("Didn't raise ValueError") + except ValueError: + pass + try: + b[0] = C(-1) + self.fail("Didn't raise ValueError") + except ValueError: + pass + try: + b[0] = None + self.fail("Didn't raise TypeError") + except TypeError: + pass + + def test_delitem(self): + b = bytearray(range(10)) + del b[0] + self.assertEqual(b, bytearray(range(1, 10))) + del b[-1] + self.assertEqual(b, bytearray(range(1, 9))) + del b[4] + self.assertEqual(b, bytearray([1, 2, 3, 4, 6, 7, 8])) + + def test_setslice(self): + b = bytearray(range(10)) + self.assertEqual(list(b), list(range(10))) + + b[0:5] = bytearray([1, 1, 1, 1, 1]) + self.assertEqual(b, bytearray([1, 1, 1, 1, 1, 5, 6, 7, 8, 9])) + + del b[0:-5] + self.assertEqual(b, bytearray([5, 6, 7, 8, 9])) + + b[0:0] = bytearray([0, 1, 2, 3, 4]) + self.assertEqual(b, bytearray(range(10))) + + b[-7:-3] = bytearray([100, 101]) + self.assertEqual(b, bytearray([0, 1, 2, 100, 101, 7, 8, 9])) + + b[3:5] = [3, 4, 5, 6] + self.assertEqual(b, bytearray(range(10))) + + b[3:0] = [42, 42, 42] + self.assertEqual(b, bytearray([0, 1, 2, 42, 42, 42, 3, 4, 5, 6, 7, 8, 9])) + + def test_extended_set_del_slice(self): + indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300) + for start in indices: + for stop in indices: + # Skip invalid step 0 + for step in indices[1:]: + L = list(range(255)) + b = bytearray(L) + # Make sure we have a slice of exactly the right length, + # but with different data. + data = L[start:stop:step] + data.reverse() + L[start:stop:step] = data + b[start:stop:step] = data + self.assertEquals(b, bytearray(L)) + + del L[start:stop:step] + del b[start:stop:step] + self.assertEquals(b, bytearray(L)) + + def test_setslice_trap(self): + # This test verifies that we correctly handle assigning self + # to a slice of self (the old Lambert Meertens trap). + b = bytearray(range(256)) + b[8:] = b + self.assertEqual(b, bytearray(list(range(8)) + list(range(256)))) + + def test_iconcat(self): + b = bytearray(b"abc") + b1 = b + b += b"def" + self.assertEqual(b, b"abcdef") + self.assertEqual(b, b1) + self.failUnless(b is b1) + b += b"xyz" + self.assertEqual(b, b"abcdefxyz") + try: + b += "" + except TypeError: + pass + else: + self.fail("bytes += unicode didn't raise TypeError") + + def test_irepeat(self): + b = bytearray(b"abc") + b1 = b + b *= 3 + self.assertEqual(b, b"abcabcabc") + self.assertEqual(b, b1) + self.failUnless(b is b1) + + def test_irepeat_1char(self): + b = bytearray(b"x") + b1 = b + b *= 100 + self.assertEqual(b, b"x"*100) + self.assertEqual(b, b1) + self.failUnless(b is b1) + + def test_alloc(self): + b = bytearray() + alloc = b.__alloc__() + self.assert_(alloc >= 0) + seq = [alloc] + for i in range(100): + b += b"x" + alloc = b.__alloc__() + self.assert_(alloc >= len(b)) + if alloc not in seq: + seq.append(alloc) + + def test_extend(self): + orig = b'hello' + a = bytearray(orig) + a.extend(a) + self.assertEqual(a, orig + orig) + self.assertEqual(a[5:], orig) + a = bytearray(b'') + # Test iterators that don't have a __length_hint__ + a.extend(map(int, orig * 25)) + a.extend(int(x) for x in orig * 25) + self.assertEqual(a, orig * 50) + self.assertEqual(a[-5:], orig) + a = bytearray(b'') + a.extend(iter(map(int, orig * 50))) + self.assertEqual(a, orig * 50) + self.assertEqual(a[-5:], orig) + a = bytearray(b'') + a.extend(list(map(int, orig * 50))) + self.assertEqual(a, orig * 50) + self.assertEqual(a[-5:], orig) + a = bytearray(b'') + self.assertRaises(ValueError, a.extend, [0, 1, 2, 256]) + self.assertRaises(ValueError, a.extend, [0, 1, 2, -1]) + self.assertEqual(len(a), 0) + + def test_remove(self): + b = bytearray(b'hello') + b.remove(ord('l')) + self.assertEqual(b, b'helo') + b.remove(ord('l')) + self.assertEqual(b, b'heo') + self.assertRaises(ValueError, lambda: b.remove(ord('l'))) + self.assertRaises(ValueError, lambda: b.remove(400)) + self.assertRaises(TypeError, lambda: b.remove('e')) + # remove first and last + b.remove(ord('o')) + b.remove(ord('h')) + self.assertEqual(b, b'e') + self.assertRaises(TypeError, lambda: b.remove(b'e')) + + def test_pop(self): + b = bytearray(b'world') + self.assertEqual(b.pop(), ord('d')) + self.assertEqual(b.pop(0), ord('w')) + self.assertEqual(b.pop(-2), ord('r')) + self.assertRaises(IndexError, lambda: b.pop(10)) + self.assertRaises(OverflowError, lambda: bytearray().pop()) + + def test_nosort(self): + self.assertRaises(AttributeError, lambda: bytearray().sort()) + + def test_append(self): + b = bytearray(b'hell') + b.append(ord('o')) + self.assertEqual(b, b'hello') + self.assertEqual(b.append(100), None) + b = bytearray() + b.append(ord('A')) + self.assertEqual(len(b), 1) + self.assertRaises(TypeError, lambda: b.append(b'o')) + + def test_insert(self): + b = bytearray(b'msssspp') + b.insert(1, ord('i')) + b.insert(4, ord('i')) + b.insert(-2, ord('i')) + b.insert(1000, ord('i')) + self.assertEqual(b, b'mississippi') + self.assertRaises(TypeError, lambda: b.insert(0, b'1')) + def test_partition_bytearray_doesnt_share_nullstring(self): a, b, c = bytearray(b"x").partition(b"y") self.assertEqual(b, b"") @@ -809,6 +736,105 @@ self.assertEqual(c, b"") +class AssortedBytesTest(unittest.TestCase): + # + # Test various combinations of bytes and bytearray + # + + def setUp(self): + self.warning_filters = warnings.filters[:] + + def tearDown(self): + warnings.filters = self.warning_filters + + def test_repr_str(self): + warnings.simplefilter('ignore', BytesWarning) + for f in str, repr: + self.assertEqual(f(bytearray()), "bytearray(b'')") + self.assertEqual(f(bytearray([0])), "bytearray(b'\\x00')") + self.assertEqual(f(bytearray([0, 1, 254, 255])), + "bytearray(b'\\x00\\x01\\xfe\\xff')") + self.assertEqual(f(b"abc"), "b'abc'") + self.assertEqual(f(b"'"), '''b"'"''') # ''' + self.assertEqual(f(b"'\""), r"""b'\'"'""") # ' + + def test_compare_bytes_to_bytearray(self): + self.assertEqual(b"abc" == bytes(b"abc"), True) + self.assertEqual(b"ab" != bytes(b"abc"), True) + self.assertEqual(b"ab" <= bytes(b"abc"), True) + self.assertEqual(b"ab" < bytes(b"abc"), True) + self.assertEqual(b"abc" >= bytes(b"ab"), True) + self.assertEqual(b"abc" > bytes(b"ab"), True) + + self.assertEqual(b"abc" != bytes(b"abc"), False) + self.assertEqual(b"ab" == bytes(b"abc"), False) + self.assertEqual(b"ab" > bytes(b"abc"), False) + self.assertEqual(b"ab" >= bytes(b"abc"), False) + self.assertEqual(b"abc" < bytes(b"ab"), False) + self.assertEqual(b"abc" <= bytes(b"ab"), False) + + self.assertEqual(bytes(b"abc") == b"abc", True) + self.assertEqual(bytes(b"ab") != b"abc", True) + self.assertEqual(bytes(b"ab") <= b"abc", True) + self.assertEqual(bytes(b"ab") < b"abc", True) + self.assertEqual(bytes(b"abc") >= b"ab", True) + self.assertEqual(bytes(b"abc") > b"ab", True) + + self.assertEqual(bytes(b"abc") != b"abc", False) + self.assertEqual(bytes(b"ab") == b"abc", False) + self.assertEqual(bytes(b"ab") > b"abc", False) + self.assertEqual(bytes(b"ab") >= b"abc", False) + self.assertEqual(bytes(b"abc") < b"ab", False) + self.assertEqual(bytes(b"abc") <= b"ab", False) + + def test_doc(self): + self.failUnless(bytearray.__doc__ != None) + self.failUnless(bytearray.__doc__.startswith("bytearray("), bytearray.__doc__) + self.failUnless(bytes.__doc__ != None) + self.failUnless(bytes.__doc__.startswith("bytes("), bytes.__doc__) + + def test_from_bytearray(self): + sample = bytes(b"Hello world\n\x80\x81\xfe\xff") + buf = memoryview(sample) + b = bytearray(buf) + self.assertEqual(b, bytearray(sample)) + + def test_to_str(self): + warnings.simplefilter('ignore', BytesWarning) + self.assertEqual(str(b''), "b''") + self.assertEqual(str(b'x'), "b'x'") + self.assertEqual(str(b'\x80'), "b'\\x80'") + self.assertEqual(str(bytearray(b'')), "bytearray(b'')") + self.assertEqual(str(bytearray(b'x')), "bytearray(b'x')") + self.assertEqual(str(bytearray(b'\x80')), "bytearray(b'\\x80')") + + def test_literal(self): + tests = [ + (b"Wonderful spam", "Wonderful spam"), + (br"Wonderful spam too", "Wonderful spam too"), + (b"\xaa\x00\000\200", "\xaa\x00\000\200"), + (br"\xaa\x00\000\200", r"\xaa\x00\000\200"), + ] + for b, s in tests: + self.assertEqual(b, bytearray(s, 'latin-1')) + for c in range(128, 256): + self.assertRaises(SyntaxError, eval, + 'b"%s"' % chr(c)) + + def test_translate(self): + b = b'hello' + rosetta = bytearray(range(0, 256)) + rosetta[ord('o')] = ord('e') + c = b.translate(rosetta, b'l') + self.assertEqual(b, b'hello') + self.assertEqual(c, b'hee') + + def test_split_bytearray(self): + self.assertEqual(b'a b'.split(memoryview(b' ')), [b'a', b'b']) + + def test_rsplit_bytearray(self): + self.assertEqual(b'a b'.rsplit(memoryview(b' ')), [b'a', b'b']) + # Optimizations: # __iter__? (optimization) # __reversed__? (optimization) @@ -841,8 +867,7 @@ methname+' returned self on a mutable object') -class BytesAsStringTest(test.string_tests.BaseTest): - type2test = bytearray +class FixedStringTest(test.string_tests.BaseTest): def fixtype(self, obj): if isinstance(obj, str): @@ -861,6 +886,12 @@ def test_lower(self): pass +class ByteArrayAsStringTest(FixedStringTest): + type2test = bytearray + +class BytesAsStringTest(FixedStringTest): + type2test = bytes + class ByteArraySubclass(bytearray): pass @@ -942,7 +973,10 @@ def test_main(): test.test_support.run_unittest(BytesTest) + test.test_support.run_unittest(ByteArrayTest) + test.test_support.run_unittest(AssortedBytesTest) test.test_support.run_unittest(BytesAsStringTest) + test.test_support.run_unittest(ByteArrayAsStringTest) test.test_support.run_unittest(ByteArraySubclassTest) test.test_support.run_unittest(BytearrayPEP3137Test) From python-3000-checkins at python.org Wed Jan 30 12:58:23 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Wed, 30 Jan 2008 12:58:23 +0100 (CET) Subject: [Python-3000-checkins] r60443 - in python/branches/py3k: Doc/tutorial/errors.rst Include/unicodeobject.h Lib/_abcoll.py Objects/unicodeobject.c Message-ID: <20080130115823.643011E4006@bag.python.org> Author: christian.heimes Date: Wed Jan 30 12:58:22 2008 New Revision: 60443 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/tutorial/errors.rst python/branches/py3k/Include/unicodeobject.h python/branches/py3k/Lib/_abcoll.py python/branches/py3k/Objects/unicodeobject.c Log: Merged revisions 60408-60440 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60425 | raymond.hettinger | 2008-01-29 20:52:09 +0100 (Tue, 29 Jan 2008) | 1 line CallMethod is faster with a NULL third-argument than with an empty format string. ........ r60431 | raymond.hettinger | 2008-01-30 01:01:07 +0100 (Wed, 30 Jan 2008) | 1 line Add isdisjoint() to the Set/MutableSet ABCs. ........ r60432 | raymond.hettinger | 2008-01-30 01:08:31 +0100 (Wed, 30 Jan 2008) | 1 line MutableSets support a remove() method. ........ r60433 | raymond.hettinger | 2008-01-30 01:51:58 +0100 (Wed, 30 Jan 2008) | 1 line Demonstrate new except/as syntax. ........ r60440 | christian.heimes | 2008-01-30 12:32:37 +0100 (Wed, 30 Jan 2008) | 1 line Patch #1970 by Antoine Pitrou: Speedup unicode whitespace and linebreak detection. The speedup is about 25% for split() (571 / 457 usec) and 35% (175 / 127 usec )for splitlines() ........ Modified: python/branches/py3k/Doc/tutorial/errors.rst ============================================================================== --- python/branches/py3k/Doc/tutorial/errors.rst (original) +++ python/branches/py3k/Doc/tutorial/errors.rst Wed Jan 30 12:58:22 2008 @@ -131,8 +131,8 @@ f = open('myfile.txt') s = f.readline() i = int(s.strip()) - except IOError as e: - print("I/O error(%s): %s" % (e.errno, e.strerror)) + except IOError as (errno, strerror): + print "I/O error(%s): %s" % (errno, strerror) except ValueError: print("Could not convert data to an integer.") except: Modified: python/branches/py3k/Include/unicodeobject.h ============================================================================== --- python/branches/py3k/Include/unicodeobject.h (original) +++ python/branches/py3k/Include/unicodeobject.h Wed Jan 30 12:58:22 2008 @@ -358,7 +358,14 @@ #else -#define Py_UNICODE_ISSPACE(ch) _PyUnicode_IsWhitespace(ch) +/* Since splitting on whitespace is an important use case, and whitespace + in most situations is solely ASCII whitespace, we optimize for the common + case by using a quick look-up table with an inlined check. + */ +extern const unsigned char _Py_ascii_whitespace[]; + +#define Py_UNICODE_ISSPACE(ch) \ + ((ch) < 128U ? _Py_ascii_whitespace[(ch)] : _PyUnicode_IsWhitespace(ch)) #define Py_UNICODE_ISLOWER(ch) _PyUnicode_IsLowercase(ch) #define Py_UNICODE_ISUPPER(ch) _PyUnicode_IsUppercase(ch) Modified: python/branches/py3k/Lib/_abcoll.py ============================================================================== --- python/branches/py3k/Lib/_abcoll.py (original) +++ python/branches/py3k/Lib/_abcoll.py Wed Jan 30 12:58:22 2008 @@ -211,6 +211,12 @@ return NotImplemented return self._from_iterable(value for value in other if value in self) + def isdisjoint(self, other): + for value in other: + if value in self: + return False + return True + def __or__(self, other): if not isinstance(other, Iterable): return NotImplemented @@ -278,6 +284,12 @@ """Return True if it was deleted, False if not there.""" raise NotImplementedError + def remove(self, value): + """Remove an element. If not a member, raise a KeyError.""" + if value not in self: + raise KeyError(value) + self.discard(value) + def pop(self): """Return the popped value. Raise KeyError if empty.""" it = iter(self) Modified: python/branches/py3k/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k/Objects/unicodeobject.c (original) +++ python/branches/py3k/Objects/unicodeobject.c Wed Jan 30 12:58:22 2008 @@ -125,6 +125,64 @@ */ static const char unicode_default_encoding[] = "utf-8"; +/* Fast detection of the most frequent whitespace characters */ +const unsigned char _Py_ascii_whitespace[] = { + 0, 0, 0, 0, 0, 0, 0, 0, +// case 0x0009: /* HORIZONTAL TABULATION */ +// case 0x000A: /* LINE FEED */ +// case 0x000B: /* VERTICAL TABULATION */ +// case 0x000C: /* FORM FEED */ +// case 0x000D: /* CARRIAGE RETURN */ + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +// case 0x001C: /* FILE SEPARATOR */ +// case 0x001D: /* GROUP SEPARATOR */ +// case 0x001E: /* RECORD SEPARATOR */ +// case 0x001F: /* UNIT SEPARATOR */ + 0, 0, 0, 0, 1, 1, 1, 1, +// case 0x0020: /* SPACE */ + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* Same for linebreaks */ +static unsigned char ascii_linebreak[] = { + 0, 0, 0, 0, 0, 0, 0, 0, +// 0x000A, /* LINE FEED */ +// 0x000D, /* CARRIAGE RETURN */ + 0, 0, 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +// 0x001C, /* FILE SEPARATOR */ +// 0x001D, /* GROUP SEPARATOR */ +// 0x001E, /* RECORD SEPARATOR */ + 0, 0, 0, 0, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + + Py_UNICODE PyUnicode_GetMax(void) { @@ -151,8 +209,9 @@ #define BLOOM(mask, ch) ((mask & (1 << ((ch) & 0x1F)))) -#define BLOOM_LINEBREAK(ch)\ - (BLOOM(bloom_linebreak, (ch)) && Py_UNICODE_ISLINEBREAK((ch))) +#define BLOOM_LINEBREAK(ch) \ + ((ch) < 128U ? ascii_linebreak[(ch)] : \ + (BLOOM(bloom_linebreak, (ch)) && Py_UNICODE_ISLINEBREAK(ch))) Py_LOCAL_INLINE(BLOOM_MASK) make_bloom_mask(Py_UNICODE* ptr, Py_ssize_t len) { @@ -5602,25 +5661,26 @@ register Py_ssize_t j; Py_ssize_t len = self->length; PyObject *str; + register const Py_UNICODE *buf = self->str; for (i = j = 0; i < len; ) { /* find a token */ - while (i < len && Py_UNICODE_ISSPACE(self->str[i])) + while (i < len && Py_UNICODE_ISSPACE(buf[i])) i++; j = i; - while (i < len && !Py_UNICODE_ISSPACE(self->str[i])) + while (i < len && !Py_UNICODE_ISSPACE(buf[i])) i++; if (j < i) { if (maxcount-- <= 0) break; - SPLIT_APPEND(self->str, j, i); - while (i < len && Py_UNICODE_ISSPACE(self->str[i])) + SPLIT_APPEND(buf, j, i); + while (i < len && Py_UNICODE_ISSPACE(buf[i])) i++; j = i; } } if (j < len) { - SPLIT_APPEND(self->str, j, len); + SPLIT_APPEND(buf, j, len); } return list; @@ -5693,18 +5753,19 @@ register Py_ssize_t j; Py_ssize_t len = self->length; PyObject *str; + register const Py_UNICODE *buf = self->str; for (i = j = 0; i < len; ) { - if (self->str[i] == ch) { + if (buf[i] == ch) { if (maxcount-- <= 0) break; - SPLIT_APPEND(self->str, j, i); + SPLIT_APPEND(buf, j, i); i = j = i + 1; } else i++; } if (j <= len) { - SPLIT_APPEND(self->str, j, len); + SPLIT_APPEND(buf, j, len); } return list; @@ -5753,25 +5814,26 @@ register Py_ssize_t j; Py_ssize_t len = self->length; PyObject *str; + register const Py_UNICODE *buf = self->str; for (i = j = len - 1; i >= 0; ) { /* find a token */ - while (i >= 0 && Py_UNICODE_ISSPACE(self->str[i])) + while (i >= 0 && Py_UNICODE_ISSPACE(buf[i])) i--; j = i; - while (i >= 0 && !Py_UNICODE_ISSPACE(self->str[i])) + while (i >= 0 && !Py_UNICODE_ISSPACE(buf[i])) i--; if (j > i) { if (maxcount-- <= 0) break; - SPLIT_APPEND(self->str, i + 1, j + 1); - while (i >= 0 && Py_UNICODE_ISSPACE(self->str[i])) + SPLIT_APPEND(buf, i + 1, j + 1); + while (i >= 0 && Py_UNICODE_ISSPACE(buf[i])) i--; j = i; } } if (j >= 0) { - SPLIT_APPEND(self->str, 0, j + 1); + SPLIT_APPEND(buf, 0, j + 1); } if (PyList_Reverse(list) < 0) goto onError; @@ -5792,18 +5854,19 @@ register Py_ssize_t j; Py_ssize_t len = self->length; PyObject *str; + register const Py_UNICODE *buf = self->str; for (i = j = len - 1; i >= 0; ) { - if (self->str[i] == ch) { + if (buf[i] == ch) { if (maxcount-- <= 0) break; - SPLIT_APPEND(self->str, i + 1, j + 1); + SPLIT_APPEND(buf, i + 1, j + 1); j = i = i - 1; } else i--; } if (j >= -1) { - SPLIT_APPEND(self->str, 0, j + 1); + SPLIT_APPEND(buf, 0, j + 1); } if (PyList_Reverse(list) < 0) goto onError; From python-3000-checkins at python.org Wed Jan 30 13:01:19 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Wed, 30 Jan 2008 13:01:19 +0100 (CET) Subject: [Python-3000-checkins] r60444 - python/branches/py3k/Lib/test/test_bytes.py Message-ID: <20080130120119.99F611E401C@bag.python.org> Author: christian.heimes Date: Wed Jan 30 13:01:19 2008 New Revision: 60444 Modified: python/branches/py3k/Lib/test/test_bytes.py Log: Removed unused import Modified: python/branches/py3k/Lib/test/test_bytes.py ============================================================================== --- python/branches/py3k/Lib/test/test_bytes.py (original) +++ python/branches/py3k/Lib/test/test_bytes.py Wed Jan 30 13:01:19 2008 @@ -13,7 +13,6 @@ import tempfile import unittest import warnings -import functools import test.test_support import test.string_tests import test.buffer_tests From python-3000-checkins at python.org Wed Jan 30 16:02:52 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Wed, 30 Jan 2008 16:02:52 +0100 (CET) Subject: [Python-3000-checkins] r60447 - python/branches/py3k/Lib/test/test_bytes.py Message-ID: <20080130150252.4A21D1E4012@bag.python.org> Author: christian.heimes Date: Wed Jan 30 16:02:52 2008 New Revision: 60447 Modified: python/branches/py3k/Lib/test/test_bytes.py Log: Enabled fromhex('') test for bytes Modified: python/branches/py3k/Lib/test/test_bytes.py ============================================================================== --- python/branches/py3k/Lib/test/test_bytes.py (original) +++ python/branches/py3k/Lib/test/test_bytes.py Wed Jan 30 16:02:52 2008 @@ -242,9 +242,7 @@ def test_fromhex(self): self.assertRaises(TypeError, self.type2test.fromhex) self.assertRaises(TypeError, self.type2test.fromhex, 1) - # To be fixed - if self.type2test != bytes: - self.assertEquals(self.type2test.fromhex(''), self.type2test()) + self.assertEquals(self.type2test.fromhex(''), self.type2test()) b = bytearray([0x1a, 0x2b, 0x30]) self.assertEquals(self.type2test.fromhex('1a2B30'), b) self.assertEquals(self.type2test.fromhex(' 1A 2B 30 '), b) From python-3000-checkins at python.org Wed Jan 30 21:15:17 2008 From: python-3000-checkins at python.org (raymond.hettinger) Date: Wed, 30 Jan 2008 21:15:17 +0100 (CET) Subject: [Python-3000-checkins] r60453 - in python/branches/py3k: Doc/library/functions.rst Doc/library/stdtypes.rst Lib/cookielib.py Lib/pstats.py Lib/test/list_tests.py Lib/test/test_builtin.py Lib/test/test_sort.py Misc/NEWS Objects/listobject.c Python/bltinmodule.c Message-ID: <20080130201517.D42921E4008@bag.python.org> Author: raymond.hettinger Date: Wed Jan 30 21:15:17 2008 New Revision: 60453 Modified: python/branches/py3k/Doc/library/functions.rst python/branches/py3k/Doc/library/stdtypes.rst python/branches/py3k/Lib/cookielib.py python/branches/py3k/Lib/pstats.py python/branches/py3k/Lib/test/list_tests.py python/branches/py3k/Lib/test/test_builtin.py python/branches/py3k/Lib/test/test_sort.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/listobject.c python/branches/py3k/Python/bltinmodule.c Log: Issue #1771: Remove cmp parameter from list.sort() and builtin.sorted(). Modified: python/branches/py3k/Doc/library/functions.rst ============================================================================== --- python/branches/py3k/Doc/library/functions.rst (original) +++ python/branches/py3k/Doc/library/functions.rst Wed Jan 30 21:15:17 2008 @@ -959,31 +959,20 @@ ``a[start:stop:step]`` or ``a[start:stop, i]``. -.. function:: sorted(iterable[, cmp[, key[, reverse]]]) +.. function:: sorted(iterable[, key[, reverse]]) Return a new sorted list from the items in *iterable*. - The optional arguments *cmp*, *key*, and *reverse* have the same meaning as + The optional arguments *key* and *reverse* have the same meaning as those for the :meth:`list.sort` method (described in section :ref:`typesseq-mutable`). - *cmp* specifies a custom comparison function of two arguments (iterable - elements) which should return a negative, zero or positive number depending on - whether the first argument is considered smaller than, equal to, or larger than - the second argument: ``cmp=lambda x,y: cmp(x.lower(), y.lower())``. The default - value is ``None``. - *key* specifies a function of one argument that is used to extract a comparison key from each list element: ``key=str.lower``. The default value is ``None``. *reverse* is a boolean value. If set to ``True``, then the list elements are sorted as if each comparison were reversed. - In general, the *key* and *reverse* conversion processes are much faster than - specifying an equivalent *cmp* function. This is because *cmp* is called - multiple times for each list element while *key* and *reverse* touch each - element only once. - .. function:: staticmethod(function) Modified: python/branches/py3k/Doc/library/stdtypes.rst ============================================================================== --- python/branches/py3k/Doc/library/stdtypes.rst (original) +++ python/branches/py3k/Doc/library/stdtypes.rst Wed Jan 30 21:15:17 2008 @@ -1266,8 +1266,7 @@ | ``s.reverse()`` | reverses the items of *s* in | \(6) | | | place | | +------------------------------+--------------------------------+---------------------+ -| ``s.sort([cmp[, key[, | sort the items of *s* in place | (6), (7) | -| reverse]]])`` | | | +| ``s.sort([key[, reverse]])`` | sort the items of *s* in place | (6), (7) | +------------------------------+--------------------------------+---------------------+ .. index:: @@ -1321,23 +1320,12 @@ The :meth:`sort` method takes optional arguments for controlling the comparisons. - *cmp* specifies a custom comparison function of two arguments (list items) which - should return a negative, zero or positive number depending on whether the first - argument is considered smaller than, equal to, or larger than the second - argument: ``cmp=lambda x,y: cmp(x.lower(), y.lower())``. The default value - is ``None``. - *key* specifies a function of one argument that is used to extract a comparison key from each list element: ``key=str.lower``. The default value is ``None``. *reverse* is a boolean value. If set to ``True``, then the list elements are sorted as if each comparison were reversed. - In general, the *key* and *reverse* conversion processes are much faster than - specifying an equivalent *cmp* function. This is because *cmp* is called - multiple times for each list element while *key* and *reverse* touch each - element only once. - Starting with Python 2.3, the :meth:`sort` method is guaranteed to be stable. A sort is stable if it guarantees not to change the relative order of elements that compare equal --- this is helpful for sorting in multiple passes (for Modified: python/branches/py3k/Lib/cookielib.py ============================================================================== --- python/branches/py3k/Lib/cookielib.py (original) +++ python/branches/py3k/Lib/cookielib.py Wed Jan 30 21:15:17 2008 @@ -1255,8 +1255,7 @@ """ # add cookies in order of most specific (ie. longest) path first - def decreasing_size(a, b): return cmp(len(b.path), len(a.path)) - cookies.sort(decreasing_size) + cookies.sort(key=lambda a: len(a.path), reverse=True) version_set = False Modified: python/branches/py3k/Lib/pstats.py ============================================================================== --- python/branches/py3k/Lib/pstats.py (original) +++ python/branches/py3k/Lib/pstats.py Wed Jan 30 21:15:17 2008 @@ -238,7 +238,7 @@ stats_list.append((cc, nc, tt, ct) + func + (func_std_string(func), func)) - stats_list.sort(TupleComp(sort_tuple).compare) + stats_list.sort(key=CmpToKey(TupleComp(sort_tuple).compare)) self.fcn_list = fcn_list = [] for tuple in stats_list: @@ -470,6 +470,16 @@ return direction return 0 +def CmpToKey(mycmp): + 'Convert a cmp= function into a key= function' + class K(object): + def __init__(self, obj): + self.obj = obj + def __lt__(self, other): + return mycmp(self.obj, other.obj) == -1 + return K + + #************************************************************************** # func_name is a triple (file:string, line:int, name:string) Modified: python/branches/py3k/Lib/test/list_tests.py ============================================================================== --- python/branches/py3k/Lib/test/list_tests.py (original) +++ python/branches/py3k/Lib/test/list_tests.py Wed Jan 30 21:15:17 2008 @@ -8,6 +8,15 @@ import unittest from test import test_support, seq_tests +def CmpToKey(mycmp): + 'Convert a cmp= function into a key= function' + class K(object): + def __init__(self, obj): + self.obj = obj + def __lt__(self, other): + return mycmp(self.obj, other.obj) == -1 + return K + class CommonTest(seq_tests.CommonTest): def test_init(self): @@ -430,23 +439,21 @@ def revcmp(a, b): return cmp(b, a) - u.sort(revcmp) + u.sort(key=CmpToKey(revcmp)) self.assertEqual(u, self.type2test([2,1,0,-1,-2])) # The following dumps core in unpatched Python 1.5: def myComparison(x,y): return cmp(x%3, y%7) z = self.type2test(range(12)) - z.sort(myComparison) + z.sort(key=CmpToKey(myComparison)) self.assertRaises(TypeError, z.sort, 2) def selfmodifyingComparison(x,y): z.append(1) return cmp(x, y) - self.assertRaises(ValueError, z.sort, selfmodifyingComparison) - - self.assertRaises(TypeError, z.sort, lambda x, y: 's') + self.assertRaises(ValueError, z.sort, key=CmpToKey(selfmodifyingComparison)) self.assertRaises(TypeError, z.sort, 42, 42, 42, 42) Modified: python/branches/py3k/Lib/test/test_builtin.py ============================================================================== --- python/branches/py3k/Lib/test/test_builtin.py (original) +++ python/branches/py3k/Lib/test/test_builtin.py Wed Jan 30 21:15:17 2008 @@ -1764,9 +1764,6 @@ data.reverse() random.shuffle(copy) - self.assertEqual(data, sorted(copy, cmp=lambda x, y: (x < y) - (x > y))) - self.assertNotEqual(data, copy) - random.shuffle(copy) self.assertEqual(data, sorted(copy, key=lambda x: -x)) self.assertNotEqual(data, copy) random.shuffle(copy) Modified: python/branches/py3k/Lib/test/test_sort.py ============================================================================== --- python/branches/py3k/Lib/test/test_sort.py (original) +++ python/branches/py3k/Lib/test/test_sort.py Wed Jan 30 21:15:17 2008 @@ -6,6 +6,15 @@ verbose = test_support.verbose nerrors = 0 +def CmpToKey(mycmp): + 'Convert a cmp= function into a key= function' + class K(object): + def __init__(self, obj): + self.obj = obj + def __lt__(self, other): + return mycmp(self.obj, other.obj) == -1 + return K + def check(tag, expected, raw, compare=None): global nerrors @@ -14,7 +23,7 @@ orig = raw[:] # save input in case of error if compare: - raw.sort(compare) + raw.sort(key=CmpToKey(compare)) else: raw.sort() @@ -99,7 +108,7 @@ print(" Checking against an insane comparison function.") print(" If the implementation isn't careful, this may segfault.") s = x[:] - s.sort(lambda a, b: int(random.random() * 3) - 1) + s.sort(key=CmpToKey(lambda a, b: int(random.random() * 3) - 1)) check("an insane function left some permutation", x, s) x = [Complains(i) for i in x] @@ -141,14 +150,6 @@ L = [C() for i in range(50)] self.assertRaises(ValueError, L.sort) - def test_cmpNone(self): - # Testing None as a comparison function. - - L = list(range(50)) - random.shuffle(L) - L.sort(None) - self.assertEqual(L, list(range(50))) - def test_undetected_mutation(self): # Python 2.4a1 did not always detect mutation memorywaster = [] @@ -158,12 +159,12 @@ L.pop() return cmp(x, y) L = [1,2] - self.assertRaises(ValueError, L.sort, mutating_cmp) + self.assertRaises(ValueError, L.sort, key=CmpToKey(mutating_cmp)) def mutating_cmp(x, y): L.append(3) del L[:] return cmp(x, y) - self.assertRaises(ValueError, L.sort, mutating_cmp) + self.assertRaises(ValueError, L.sort, key=CmpToKey(mutating_cmp)) memorywaster = [memorywaster] #============================================================================== @@ -175,11 +176,11 @@ copy = data[:] random.shuffle(data) data.sort(key=str.lower) - copy.sort(cmp=lambda x,y: cmp(x.lower(), y.lower())) + copy.sort(key=CmpToKey(lambda x,y: cmp(x.lower(), y.lower()))) def test_baddecorator(self): data = 'The quick Brown fox Jumped over The lazy Dog'.split() - self.assertRaises(TypeError, data.sort, None, lambda x,y: 0) + self.assertRaises(TypeError, data.sort, key=lambda x,y: 0) def test_stability(self): data = [(random.randrange(100), i) for i in range(200)] @@ -188,25 +189,11 @@ copy.sort() # sort using both fields self.assertEqual(data, copy) # should get the same result - def test_cmp_and_key_combination(self): - # Verify that the wrapper has been removed - def compare(x, y): - self.assertEqual(type(x), str) - self.assertEqual(type(x), str) - return cmp(x, y) - data = 'The quick Brown fox Jumped over The lazy Dog'.split() - data.sort(cmp=compare, key=str.lower) - - def test_badcmp_with_key(self): - # Verify that the wrapper has been removed - data = 'The quick Brown fox Jumped over The lazy Dog'.split() - self.assertRaises(TypeError, data.sort, "bad", str.lower) - def test_key_with_exception(self): # Verify that the wrapper has been removed data = list(range(-2, 2)) dup = data[:] - self.assertRaises(ZeroDivisionError, data.sort, None, lambda x: 1/x) + self.assertRaises(ZeroDivisionError, data.sort, key=lambda x: 1/x) self.assertEqual(data, dup) def test_key_with_mutation(self): @@ -254,14 +241,13 @@ random.shuffle(data) data.sort(reverse=True) self.assertEqual(data, list(range(99,-1,-1))) - self.assertRaises(TypeError, data.sort, "wrong type") def test_reverse_stability(self): data = [(random.randrange(100), i) for i in range(200)] copy1 = data[:] copy2 = data[:] - data.sort(cmp=lambda x,y: cmp(x[0],y[0]), reverse=True) - copy1.sort(cmp=lambda x,y: cmp(y[0],x[0])) + data.sort(key=CmpToKey(lambda x,y: cmp(x[0],y[0])), reverse=True) + copy1.sort(key=CmpToKey(lambda x,y: cmp(y[0],x[0]))) self.assertEqual(data, copy1) copy2.sort(key=lambda x: x[0], reverse=True) self.assertEqual(data, copy2) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Jan 30 21:15:17 2008 @@ -14,6 +14,8 @@ - Issue #1973: bytes.fromhex('') raises SystemError +- Issue #1771: remove cmp parameter from sorted() and list.sort() + - Issue #1969: split and rsplit in bytearray are inconsistent - map() and itertools.imap() no longer accept None for the first argument. Modified: python/branches/py3k/Objects/listobject.c ============================================================================== --- python/branches/py3k/Objects/listobject.c (original) +++ python/branches/py3k/Objects/listobject.c Wed Jan 30 21:15:17 2008 @@ -888,64 +888,17 @@ * pieces to this algorithm; read listsort.txt for overviews and details. */ -/* Comparison function. Takes care of calling a user-supplied - * comparison function (any callable Python object), which must not be - * NULL (use the ISLT macro if you don't know, or call PyObject_RichCompareBool - * with Py_LT if you know it's NULL). +/* Comparison function: PyObject_RichCompareBool with Py_LT. * Returns -1 on error, 1 if x < y, 0 if x >= y. */ -static int -islt(PyObject *x, PyObject *y, PyObject *compare) -{ - PyObject *res; - PyObject *args; - Py_ssize_t i; - assert(compare != NULL); - /* Call the user's comparison function and translate the 3-way - * result into true or false (or error). - */ - args = PyTuple_New(2); - if (args == NULL) - return -1; - Py_INCREF(x); - Py_INCREF(y); - PyTuple_SET_ITEM(args, 0, x); - PyTuple_SET_ITEM(args, 1, y); - res = PyObject_Call(compare, args, NULL); - Py_DECREF(args); - if (res == NULL) - return -1; - if (!PyLong_CheckExact(res)) { - PyErr_Format(PyExc_TypeError, - "comparison function must return int, not %.200s", - res->ob_type->tp_name); - Py_DECREF(res); - return -1; - } - i = PyLong_AsLong(res); - Py_DECREF(res); - if (i == -1 && PyErr_Occurred()) { - /* Overflow in long conversion. */ - return -1; - } - return i < 0; -} - -/* If COMPARE is NULL, calls PyObject_RichCompareBool with Py_LT, else calls - * islt. This avoids a layer of function call in the usual case, and - * sorting does many comparisons. - * Returns -1 on error, 1 if x < y, 0 if x >= y. - */ -#define ISLT(X, Y, COMPARE) ((COMPARE) == NULL ? \ - PyObject_RichCompareBool(X, Y, Py_LT) : \ - islt(X, Y, COMPARE)) +#define ISLT(X, Y) (PyObject_RichCompareBool(X, Y, Py_LT)) /* Compare X to Y via "<". Goto "fail" if the comparison raises an error. Else "k" is set to true iff X. X and Y are PyObject*s. */ -#define IFLT(X, Y) if ((k = ISLT(X, Y, compare)) < 0) goto fail; \ +#define IFLT(X, Y) if ((k = ISLT(X, Y)) < 0) goto fail; \ if (k) /* binarysort is the best method for sorting small arrays: it does @@ -960,8 +913,7 @@ the input (nothing is lost or duplicated). */ static int -binarysort(PyObject **lo, PyObject **hi, PyObject **start, PyObject *compare) - /* compare -- comparison function object, or NULL for default */ +binarysort(PyObject **lo, PyObject **hi, PyObject **start) { register Py_ssize_t k; register PyObject **l, **p, **r; @@ -1026,7 +978,7 @@ Returns -1 in case of error. */ static Py_ssize_t -count_run(PyObject **lo, PyObject **hi, PyObject *compare, int *descending) +count_run(PyObject **lo, PyObject **hi, int *descending) { Py_ssize_t k; Py_ssize_t n; @@ -1081,7 +1033,7 @@ Returns -1 on error. See listsort.txt for info on the method. */ static Py_ssize_t -gallop_left(PyObject *key, PyObject **a, Py_ssize_t n, Py_ssize_t hint, PyObject *compare) +gallop_left(PyObject *key, PyObject **a, Py_ssize_t n, Py_ssize_t hint) { Py_ssize_t ofs; Py_ssize_t lastofs; @@ -1172,7 +1124,7 @@ written as one routine with yet another "left or right?" flag. */ static Py_ssize_t -gallop_right(PyObject *key, PyObject **a, Py_ssize_t n, Py_ssize_t hint, PyObject *compare) +gallop_right(PyObject *key, PyObject **a, Py_ssize_t n, Py_ssize_t hint) { Py_ssize_t ofs; Py_ssize_t lastofs; @@ -1273,9 +1225,6 @@ }; typedef struct s_MergeState { - /* The user-supplied comparison function. or NULL if none given. */ - PyObject *compare; - /* This controls when we get *into* galloping mode. It's initialized * to MIN_GALLOP. merge_lo and merge_hi tend to nudge it higher for * random data, and lower for highly structured data. @@ -1306,10 +1255,9 @@ /* Conceptually a MergeState's constructor. */ static void -merge_init(MergeState *ms, PyObject *compare) +merge_init(MergeState *ms) { assert(ms != NULL); - ms->compare = compare; ms->a = ms->temparray; ms->alloced = MERGESTATE_TEMP_SIZE; ms->n = 0; @@ -1366,7 +1314,6 @@ PyObject **pb, Py_ssize_t nb) { Py_ssize_t k; - PyObject *compare; PyObject **dest; int result = -1; /* guilty until proved innocent */ Py_ssize_t min_gallop; @@ -1386,7 +1333,6 @@ goto CopyB; min_gallop = ms->min_gallop; - compare = ms->compare; for (;;) { Py_ssize_t acount = 0; /* # of times A won in a row */ Py_ssize_t bcount = 0; /* # of times B won in a row */ @@ -1396,7 +1342,7 @@ */ for (;;) { assert(na > 1 && nb > 0); - k = ISLT(*pb, *pa, compare); + k = ISLT(*pb, *pa); if (k) { if (k < 0) goto Fail; @@ -1431,7 +1377,7 @@ assert(na > 1 && nb > 0); min_gallop -= min_gallop > 1; ms->min_gallop = min_gallop; - k = gallop_right(*pb, pa, na, 0, compare); + k = gallop_right(*pb, pa, na, 0); acount = k; if (k) { if (k < 0) @@ -1454,7 +1400,7 @@ if (nb == 0) goto Succeed; - k = gallop_left(*pa, pb, nb, 0, compare); + k = gallop_left(*pa, pb, nb, 0); bcount = k; if (k) { if (k < 0) @@ -1498,7 +1444,6 @@ merge_hi(MergeState *ms, PyObject **pa, Py_ssize_t na, PyObject **pb, Py_ssize_t nb) { Py_ssize_t k; - PyObject *compare; PyObject **dest; int result = -1; /* guilty until proved innocent */ PyObject **basea; @@ -1523,7 +1468,6 @@ goto CopyA; min_gallop = ms->min_gallop; - compare = ms->compare; for (;;) { Py_ssize_t acount = 0; /* # of times A won in a row */ Py_ssize_t bcount = 0; /* # of times B won in a row */ @@ -1533,7 +1477,7 @@ */ for (;;) { assert(na > 0 && nb > 1); - k = ISLT(*pb, *pa, compare); + k = ISLT(*pb, *pa); if (k) { if (k < 0) goto Fail; @@ -1568,7 +1512,7 @@ assert(na > 0 && nb > 1); min_gallop -= min_gallop > 1; ms->min_gallop = min_gallop; - k = gallop_right(*pb, basea, na, na-1, compare); + k = gallop_right(*pb, basea, na, na-1); if (k < 0) goto Fail; k = na - k; @@ -1586,7 +1530,7 @@ if (nb == 1) goto CopyA; - k = gallop_left(*pa, baseb, nb, nb-1, compare); + k = gallop_left(*pa, baseb, nb, nb-1); if (k < 0) goto Fail; k = nb - k; @@ -1638,7 +1582,6 @@ PyObject **pa, **pb; Py_ssize_t na, nb; Py_ssize_t k; - PyObject *compare; assert(ms != NULL); assert(ms->n >= 2); @@ -1664,8 +1607,7 @@ /* Where does b start in a? Elements in a before that can be * ignored (already in place). */ - compare = ms->compare; - k = gallop_right(*pb, pa, na, 0, compare); + k = gallop_right(*pb, pa, na, 0); if (k < 0) return -1; pa += k; @@ -1676,7 +1618,7 @@ /* Where does a end in b? Elements in b after that can be * ignored (already in place). */ - nb = gallop_left(pa[na-1], pb, nb, nb-1, compare); + nb = gallop_left(pa[na-1], pb, nb, nb-1); if (nb <= 0) return nb; @@ -1771,8 +1713,8 @@ pattern. Holds a key which is used for comparisons and the original record which is returned during the undecorate phase. By exposing only the key during comparisons, the underlying sort stability characteristics are left - unchanged. Also, if a custom comparison function is used, it will only see - the key instead of a full record. */ + unchanged. Also, the comparison function will only see the key instead of + a full record. */ typedef struct { PyObject_HEAD @@ -1866,104 +1808,6 @@ return value; } -/* Wrapper for user specified cmp functions in combination with a - specified key function. Makes sure the cmp function is presented - with the actual key instead of the sortwrapper */ - -typedef struct { - PyObject_HEAD - PyObject *func; -} cmpwrapperobject; - -static void -cmpwrapper_dealloc(cmpwrapperobject *co) -{ - Py_XDECREF(co->func); - PyObject_Del(co); -} - -static PyObject * -cmpwrapper_call(cmpwrapperobject *co, PyObject *args, PyObject *kwds) -{ - PyObject *x, *y, *xx, *yy; - - if (!PyArg_UnpackTuple(args, "", 2, 2, &x, &y)) - return NULL; - if (!PyObject_TypeCheck(x, &PySortWrapper_Type) || - !PyObject_TypeCheck(y, &PySortWrapper_Type)) { - PyErr_SetString(PyExc_TypeError, - "expected a sortwrapperobject"); - return NULL; - } - xx = ((sortwrapperobject *)x)->key; - yy = ((sortwrapperobject *)y)->key; - return PyObject_CallFunctionObjArgs(co->func, xx, yy, NULL); -} - -PyDoc_STRVAR(cmpwrapper_doc, "cmp() wrapper for sort with custom keys."); - -PyTypeObject PyCmpWrapper_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "cmpwrapper", /* tp_name */ - sizeof(cmpwrapperobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)cmpwrapper_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - (ternaryfunc)cmpwrapper_call, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - cmpwrapper_doc, /* tp_doc */ -}; - -static PyObject * -build_cmpwrapper(PyObject *cmpfunc) -{ - cmpwrapperobject *co; - - co = PyObject_New(cmpwrapperobject, &PyCmpWrapper_Type); - if (co == NULL) - return NULL; - Py_INCREF(cmpfunc); - co->func = cmpfunc; - return (PyObject *)co; -} - -static int -is_default_cmp(PyObject *cmpfunc) -{ - PyCFunctionObject *f; - const char *module; - if (cmpfunc == NULL || cmpfunc == Py_None) - return 1; - if (!PyCFunction_Check(cmpfunc)) - return 0; - f = (PyCFunctionObject *)cmpfunc; - if (f->m_self != NULL) - return 0; - if (!PyUnicode_Check(f->m_module)) - return 0; - module = PyUnicode_AsString(f->m_module); - if (module == NULL) - return 0; - if (strcmp(module, "builtins") != 0) - return 0; - if (strcmp(f->m_ml->ml_name, "cmp") != 0) - return 0; - return 1; -} - /* An adaptive, stable, natural mergesort. See listsort.txt. * Returns Py_None on success, NULL on error. Even in case of error, the * list will be some permutation of its input state (nothing is lost or @@ -1979,31 +1823,27 @@ Py_ssize_t saved_ob_size, saved_allocated; PyObject **saved_ob_item; PyObject **final_ob_item; - PyObject *compare = NULL; PyObject *result = NULL; /* guilty until proved innocent */ int reverse = 0; PyObject *keyfunc = NULL; Py_ssize_t i; PyObject *key, *value, *kvpair; - static char *kwlist[] = {"cmp", "key", "reverse", 0}; + static char *kwlist[] = {"key", "reverse", 0}; assert(self != NULL); assert (PyList_Check(self)); if (args != NULL) { - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOi:sort", - kwlist, &compare, &keyfunc, &reverse)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:sort", + kwlist, &keyfunc, &reverse)) + return NULL; + if (Py_SIZE(args) > 0) { + PyErr_SetString(PyExc_TypeError, + "must use keyword argument for key function"); return NULL; + } } - if (is_default_cmp(compare)) - compare = NULL; if (keyfunc == Py_None) keyfunc = NULL; - if (compare != NULL && keyfunc != NULL) { - compare = build_cmpwrapper(compare); - if (compare == NULL) - return NULL; - } else - Py_XINCREF(compare); /* The list is temporarily made empty, so that mutations performed * by comparison functions can't affect the slice of memory we're @@ -2043,7 +1883,7 @@ if (reverse && saved_ob_size > 1) reverse_slice(saved_ob_item, saved_ob_item + saved_ob_size); - merge_init(&ms, compare); + merge_init(&ms); nremaining = saved_ob_size; if (nremaining < 2) @@ -2060,7 +1900,7 @@ Py_ssize_t n; /* Identify next run. */ - n = count_run(lo, hi, compare, &descending); + n = count_run(lo, hi, &descending); if (n < 0) goto fail; if (descending) @@ -2069,7 +1909,7 @@ if (n < minrun) { const Py_ssize_t force = nremaining <= minrun ? nremaining : minrun; - if (binarysort(lo, lo + force, lo + n, compare) < 0) + if (binarysort(lo, lo + force, lo + n) < 0) goto fail; n = force; } @@ -2131,7 +1971,6 @@ } PyMem_FREE(final_ob_item); } - Py_XDECREF(compare); Py_XINCREF(result); return result; } Modified: python/branches/py3k/Python/bltinmodule.c ============================================================================== --- python/branches/py3k/Python/bltinmodule.c (original) +++ python/branches/py3k/Python/bltinmodule.c Wed Jan 30 21:15:17 2008 @@ -1494,14 +1494,14 @@ static PyObject * builtin_sorted(PyObject *self, PyObject *args, PyObject *kwds) { - PyObject *newlist, *v, *seq, *compare=NULL, *keyfunc=NULL, *newargs; + PyObject *newlist, *v, *seq, *keyfunc=NULL, *newargs; PyObject *callable; - static char *kwlist[] = {"iterable", "cmp", "key", "reverse", 0}; + static char *kwlist[] = {"iterable", "key", "reverse", 0}; int reverse; - /* args 1-4 should match listsort in Objects/listobject.c */ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OOi:sorted", - kwlist, &seq, &compare, &keyfunc, &reverse)) + /* args 1-3 should match listsort in Objects/listobject.c */ + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|Oi:sorted", + kwlist, &seq, &keyfunc, &reverse)) return NULL; newlist = PySequence_List(seq); @@ -1533,7 +1533,7 @@ } PyDoc_STRVAR(sorted_doc, -"sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list"); +"sorted(iterable, key=None, reverse=False) --> new sorted list"); static PyObject * builtin_vars(PyObject *self, PyObject *args) From python-3000-checkins at python.org Thu Jan 31 00:33:08 2008 From: python-3000-checkins at python.org (raymond.hettinger) Date: Thu, 31 Jan 2008 00:33:08 +0100 (CET) Subject: [Python-3000-checkins] r60466 - python/branches/py3k/Objects/setobject.c Message-ID: <20080130233308.ED40C1E4012@bag.python.org> Author: raymond.hettinger Date: Thu Jan 31 00:33:08 2008 New Revision: 60466 Modified: python/branches/py3k/Objects/setobject.c Log: Remove duplicate function. Modified: python/branches/py3k/Objects/setobject.c ============================================================================== --- python/branches/py3k/Objects/setobject.c (original) +++ python/branches/py3k/Objects/setobject.c Thu Jan 31 00:33:08 2008 @@ -2181,21 +2181,6 @@ } int -_PySet_Next(PyObject *set, Py_ssize_t *pos, PyObject **key) -{ - setentry *entry_ptr; - - if (!PyAnySet_Check(set)) { - PyErr_BadInternalCall(); - return -1; - } - if (set_next((PySetObject *)set, pos, &entry_ptr) == 0) - return 0; - *key = entry_ptr->key; - return 1; -} - -int _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash) { setentry *entry; From python-3000-checkins at python.org Thu Jan 31 02:08:33 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Thu, 31 Jan 2008 02:08:33 +0100 (CET) Subject: [Python-3000-checkins] r60467 - in python/branches/py3k: Include/setobject.h Objects/setobject.c Message-ID: <20080131010833.2919A1E401C@bag.python.org> Author: christian.heimes Date: Thu Jan 31 02:08:32 2008 New Revision: 60467 Modified: python/branches/py3k/Include/setobject.h python/branches/py3k/Objects/setobject.c Log: Fixed r60466 Modified: python/branches/py3k/Include/setobject.h ============================================================================== --- python/branches/py3k/Include/setobject.h (original) +++ python/branches/py3k/Include/setobject.h Thu Jan 31 02:08:32 2008 @@ -85,7 +85,6 @@ PyAPI_FUNC(int) PySet_Contains(PyObject *anyset, PyObject *key); PyAPI_FUNC(int) PySet_Discard(PyObject *set, PyObject *key); PyAPI_FUNC(int) PySet_Add(PyObject *set, PyObject *key); -PyAPI_FUNC(int) _PySet_Next(PyObject *set, Py_ssize_t *pos, PyObject **key); PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash); PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set); PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable); Modified: python/branches/py3k/Objects/setobject.c ============================================================================== --- python/branches/py3k/Objects/setobject.c (original) +++ python/branches/py3k/Objects/setobject.c Thu Jan 31 02:08:32 2008 @@ -2236,6 +2236,7 @@ Py_ssize_t i; PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x; PyObject *ob = (PyObject *)so; + long hash; /* Verify preconditions and exercise type/size checks */ assert(PyAnySet_Check(ob)); @@ -2280,7 +2281,7 @@ /* Exercise direct iteration */ i = 0, count = 0; - while (_PySet_Next((PyObject *)dup, &i, &x)) { + while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) { s = PyUnicode_AsString(x); assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c')); count++; From python-3000-checkins at python.org Thu Jan 31 02:10:03 2008 From: python-3000-checkins at python.org (raymond.hettinger) Date: Thu, 31 Jan 2008 02:10:03 +0100 (CET) Subject: [Python-3000-checkins] r60468 - in python/branches/py3k/Lib: pprint.py test/test_pprint.py Message-ID: <20080131011003.C36781E4018@bag.python.org> Author: raymond.hettinger Date: Thu Jan 31 02:10:03 2008 New Revision: 60468 Modified: python/branches/py3k/Lib/pprint.py python/branches/py3k/Lib/test/test_pprint.py Log: Update pprint() to match the new repr style for frozensets Modified: python/branches/py3k/Lib/pprint.py ============================================================================== --- python/branches/py3k/Lib/pprint.py (original) +++ python/branches/py3k/Lib/pprint.py Thu Jan 31 02:10:03 2008 @@ -175,13 +175,12 @@ write('{') endchar = '}' object = sorted(object) - indent += 4 elif issubclass(typ, frozenset): if not length: write('frozenset()') return - write('frozenset([') - endchar = '])' + write('frozenset({') + endchar = '})' object = sorted(object) indent += 10 else: Modified: python/branches/py3k/Lib/test/test_pprint.py ============================================================================== --- python/branches/py3k/Lib/test/test_pprint.py (original) +++ python/branches/py3k/Lib/test/test_pprint.py Thu Jan 31 02:10:03 2008 @@ -197,186 +197,186 @@ self.assertEqual(pprint.pformat(frozenset(range(3))), 'frozenset({0, 1, 2})') cube_repr_tgt = """\ {frozenset(): frozenset({frozenset({2}), frozenset({0}), frozenset({1})}), - frozenset({0}): frozenset([frozenset(), + frozenset({0}): frozenset({frozenset(), frozenset({0, 2}), - frozenset({0, 1})]), - frozenset({1}): frozenset([frozenset(), + frozenset({0, 1})}), + frozenset({1}): frozenset({frozenset(), frozenset({1, 2}), - frozenset({0, 1})]), - frozenset({2}): frozenset([frozenset(), + frozenset({0, 1})}), + frozenset({2}): frozenset({frozenset(), frozenset({1, 2}), - frozenset({0, 2})]), - frozenset({1, 2}): frozenset([frozenset({2}), + frozenset({0, 2})}), + frozenset({1, 2}): frozenset({frozenset({2}), frozenset({1}), - frozenset({0, 1, 2})]), - frozenset({0, 2}): frozenset([frozenset({2}), + frozenset({0, 1, 2})}), + frozenset({0, 2}): frozenset({frozenset({2}), frozenset({0}), - frozenset({0, 1, 2})]), - frozenset({0, 1}): frozenset([frozenset({0}), + frozenset({0, 1, 2})}), + frozenset({0, 1}): frozenset({frozenset({0}), frozenset({1}), - frozenset({0, 1, 2})]), - frozenset({0, 1, 2}): frozenset([frozenset({1, 2}), + frozenset({0, 1, 2})}), + frozenset({0, 1, 2}): frozenset({frozenset({1, 2}), frozenset({0, 2}), - frozenset({0, 1})])}""" + frozenset({0, 1})})}""" cube = test.test_set.cube(3) self.assertEqual(pprint.pformat(cube), cube_repr_tgt) cubo_repr_tgt = """\ -{frozenset({frozenset({0, 2}), frozenset({0})}): frozenset([frozenset([frozenset([0, - 2]), - frozenset([0, - 1, - 2])]), - frozenset([frozenset([0]), - frozenset([0, - 1])]), - frozenset([frozenset(), - frozenset([0])]), - frozenset([frozenset([2]), - frozenset([0, - 2])])]), - frozenset({frozenset({0, 1}), frozenset({1})}): frozenset([frozenset([frozenset([0, - 1]), - frozenset([0, - 1, - 2])]), - frozenset([frozenset([0]), - frozenset([0, - 1])]), - frozenset([frozenset([1]), - frozenset([1, - 2])]), - frozenset([frozenset(), - frozenset([1])])]), - frozenset({frozenset({1, 2}), frozenset({1})}): frozenset([frozenset([frozenset([1, - 2]), - frozenset([0, - 1, - 2])]), - frozenset([frozenset([2]), - frozenset([1, - 2])]), - frozenset([frozenset(), - frozenset([1])]), - frozenset([frozenset([1]), - frozenset([0, - 1])])]), - frozenset({frozenset({1, 2}), frozenset({2})}): frozenset([frozenset([frozenset([1, - 2]), - frozenset([0, - 1, - 2])]), - frozenset([frozenset([1]), - frozenset([1, - 2])]), - frozenset([frozenset([2]), - frozenset([0, - 2])]), - frozenset([frozenset(), - frozenset([2])])]), - frozenset({frozenset(), frozenset({0})}): frozenset([frozenset([frozenset([0]), - frozenset([0, - 1])]), - frozenset([frozenset([0]), - frozenset([0, - 2])]), - frozenset([frozenset(), - frozenset([1])]), - frozenset([frozenset(), - frozenset([2])])]), - frozenset({frozenset(), frozenset({1})}): frozenset([frozenset([frozenset(), - frozenset([0])]), - frozenset([frozenset([1]), - frozenset([1, - 2])]), - frozenset([frozenset(), - frozenset([2])]), - frozenset([frozenset([1]), - frozenset([0, - 1])])]), - frozenset({frozenset({2}), frozenset()}): frozenset([frozenset([frozenset([2]), - frozenset([1, - 2])]), - frozenset([frozenset(), - frozenset([0])]), - frozenset([frozenset(), - frozenset([1])]), - frozenset([frozenset([2]), - frozenset([0, - 2])])]), - frozenset({frozenset({0, 1, 2}), frozenset({0, 1})}): frozenset([frozenset([frozenset([1, - 2]), - frozenset([0, - 1, - 2])]), - frozenset([frozenset([0, - 2]), - frozenset([0, - 1, - 2])]), - frozenset([frozenset([0]), - frozenset([0, - 1])]), - frozenset([frozenset([1]), - frozenset([0, - 1])])]), - frozenset({frozenset({0}), frozenset({0, 1})}): frozenset([frozenset([frozenset(), - frozenset([0])]), - frozenset([frozenset([0, - 1]), - frozenset([0, - 1, - 2])]), - frozenset([frozenset([0]), - frozenset([0, - 2])]), - frozenset([frozenset([1]), - frozenset([0, - 1])])]), - frozenset({frozenset({2}), frozenset({0, 2})}): frozenset([frozenset([frozenset([0, - 2]), - frozenset([0, - 1, - 2])]), - frozenset([frozenset([2]), - frozenset([1, - 2])]), - frozenset([frozenset([0]), - frozenset([0, - 2])]), - frozenset([frozenset(), - frozenset([2])])]), - frozenset({frozenset({0, 1, 2}), frozenset({0, 2})}): frozenset([frozenset([frozenset([1, - 2]), - frozenset([0, - 1, - 2])]), - frozenset([frozenset([0, - 1]), - frozenset([0, - 1, - 2])]), - frozenset([frozenset([0]), - frozenset([0, - 2])]), - frozenset([frozenset([2]), - frozenset([0, - 2])])]), - frozenset({frozenset({1, 2}), frozenset({0, 1, 2})}): frozenset([frozenset([frozenset([0, - 2]), - frozenset([0, - 1, - 2])]), - frozenset([frozenset([0, - 1]), - frozenset([0, - 1, - 2])]), - frozenset([frozenset([2]), - frozenset([1, - 2])]), - frozenset([frozenset([1]), - frozenset([1, - 2])])])}""" +{frozenset({frozenset({0, 2}), frozenset({0})}): frozenset({frozenset({frozenset({0, + 2}), + frozenset({0, + 1, + 2})}), + frozenset({frozenset({0}), + frozenset({0, + 1})}), + frozenset({frozenset(), + frozenset({0})}), + frozenset({frozenset({2}), + frozenset({0, + 2})})}), + frozenset({frozenset({0, 1}), frozenset({1})}): frozenset({frozenset({frozenset({0, + 1}), + frozenset({0, + 1, + 2})}), + frozenset({frozenset({0}), + frozenset({0, + 1})}), + frozenset({frozenset({1}), + frozenset({1, + 2})}), + frozenset({frozenset(), + frozenset({1})})}), + frozenset({frozenset({1, 2}), frozenset({1})}): frozenset({frozenset({frozenset({1, + 2}), + frozenset({0, + 1, + 2})}), + frozenset({frozenset({2}), + frozenset({1, + 2})}), + frozenset({frozenset(), + frozenset({1})}), + frozenset({frozenset({1}), + frozenset({0, + 1})})}), + frozenset({frozenset({1, 2}), frozenset({2})}): frozenset({frozenset({frozenset({1, + 2}), + frozenset({0, + 1, + 2})}), + frozenset({frozenset({1}), + frozenset({1, + 2})}), + frozenset({frozenset({2}), + frozenset({0, + 2})}), + frozenset({frozenset(), + frozenset({2})})}), + frozenset({frozenset(), frozenset({0})}): frozenset({frozenset({frozenset({0}), + frozenset({0, + 1})}), + frozenset({frozenset({0}), + frozenset({0, + 2})}), + frozenset({frozenset(), + frozenset({1})}), + frozenset({frozenset(), + frozenset({2})})}), + frozenset({frozenset(), frozenset({1})}): frozenset({frozenset({frozenset(), + frozenset({0})}), + frozenset({frozenset({1}), + frozenset({1, + 2})}), + frozenset({frozenset(), + frozenset({2})}), + frozenset({frozenset({1}), + frozenset({0, + 1})})}), + frozenset({frozenset({2}), frozenset()}): frozenset({frozenset({frozenset({2}), + frozenset({1, + 2})}), + frozenset({frozenset(), + frozenset({0})}), + frozenset({frozenset(), + frozenset({1})}), + frozenset({frozenset({2}), + frozenset({0, + 2})})}), + frozenset({frozenset({0, 1, 2}), frozenset({0, 1})}): frozenset({frozenset({frozenset({1, + 2}), + frozenset({0, + 1, + 2})}), + frozenset({frozenset({0, + 2}), + frozenset({0, + 1, + 2})}), + frozenset({frozenset({0}), + frozenset({0, + 1})}), + frozenset({frozenset({1}), + frozenset({0, + 1})})}), + frozenset({frozenset({0}), frozenset({0, 1})}): frozenset({frozenset({frozenset(), + frozenset({0})}), + frozenset({frozenset({0, + 1}), + frozenset({0, + 1, + 2})}), + frozenset({frozenset({0}), + frozenset({0, + 2})}), + frozenset({frozenset({1}), + frozenset({0, + 1})})}), + frozenset({frozenset({2}), frozenset({0, 2})}): frozenset({frozenset({frozenset({0, + 2}), + frozenset({0, + 1, + 2})}), + frozenset({frozenset({2}), + frozenset({1, + 2})}), + frozenset({frozenset({0}), + frozenset({0, + 2})}), + frozenset({frozenset(), + frozenset({2})})}), + frozenset({frozenset({0, 1, 2}), frozenset({0, 2})}): frozenset({frozenset({frozenset({1, + 2}), + frozenset({0, + 1, + 2})}), + frozenset({frozenset({0, + 1}), + frozenset({0, + 1, + 2})}), + frozenset({frozenset({0}), + frozenset({0, + 2})}), + frozenset({frozenset({2}), + frozenset({0, + 2})})}), + frozenset({frozenset({1, 2}), frozenset({0, 1, 2})}): frozenset({frozenset({frozenset({0, + 2}), + frozenset({0, + 1, + 2})}), + frozenset({frozenset({0, + 1}), + frozenset({0, + 1, + 2})}), + frozenset({frozenset({2}), + frozenset({1, + 2})}), + frozenset({frozenset({1}), + frozenset({1, + 2})})})}""" cubo = test.test_set.linegraph(cube) self.assertEqual(pprint.pformat(cubo), cubo_repr_tgt) From python-3000-checkins at python.org Thu Jan 31 15:31:46 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Thu, 31 Jan 2008 15:31:46 +0100 (CET) Subject: [Python-3000-checkins] r60476 - in python/branches/py3k: Doc/library/itertools.rst Doc/library/numbers.rst Lib/_abcoll.py Lib/numbers.py Lib/rational.py Objects/floatobject.c Python/import.c Python/marshal.c Python/sysmodule.c configure configure.in Message-ID: <20080131143146.3C1BC1E4010@bag.python.org> Author: christian.heimes Date: Thu Jan 31 15:31:45 2008 New Revision: 60476 Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/itertools.rst python/branches/py3k/Doc/library/numbers.rst python/branches/py3k/Lib/_abcoll.py python/branches/py3k/Lib/numbers.py python/branches/py3k/Lib/rational.py python/branches/py3k/Objects/floatobject.c python/branches/py3k/Python/import.c python/branches/py3k/Python/marshal.c python/branches/py3k/Python/sysmodule.c python/branches/py3k/configure python/branches/py3k/configure.in Log: Merged revisions 60441-60474 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r60441 | christian.heimes | 2008-01-30 12:46:00 +0100 (Wed, 30 Jan 2008) | 1 line Removed unused var ........ r60448 | christian.heimes | 2008-01-30 18:21:22 +0100 (Wed, 30 Jan 2008) | 1 line Fixed some references leaks in sys. ........ r60450 | christian.heimes | 2008-01-30 19:58:29 +0100 (Wed, 30 Jan 2008) | 1 line The previous change was causing a segfault after multiple calls to Py_Initialize() and Py_Finalize(). ........ r60463 | raymond.hettinger | 2008-01-30 23:17:31 +0100 (Wed, 30 Jan 2008) | 1 line Update itertool recipes ........ r60464 | christian.heimes | 2008-01-30 23:54:18 +0100 (Wed, 30 Jan 2008) | 1 line Bug #1234: Fixed semaphore errors on AIX 5.2 ........ r60469 | raymond.hettinger | 2008-01-31 02:38:15 +0100 (Thu, 31 Jan 2008) | 6 lines Fix defect in __ixor__ which would get the wrong answer if the input iterable had a duplicate element (two calls to toggle() reverse each other). Borrow the correct code from sets.py. ........ r60470 | raymond.hettinger | 2008-01-31 02:42:11 +0100 (Thu, 31 Jan 2008) | 1 line Missing return ........ r60471 | jeffrey.yasskin | 2008-01-31 08:44:11 +0100 (Thu, 31 Jan 2008) | 4 lines Added more documentation on how mixed-mode arithmetic should be implemented. I also noticed and fixed a bug in Rational's forward operators (they were claiming all instances of numbers.Rational instead of just the concrete types). ........ Modified: python/branches/py3k/Doc/library/itertools.rst ============================================================================== --- python/branches/py3k/Doc/library/itertools.rst (original) +++ python/branches/py3k/Doc/library/itertools.rst Thu Jan 31 15:31:45 2008 @@ -511,5 +511,16 @@ "grouper(3, 'abcdefg', 'x') --> ('a','b','c'), ('d','e','f'), ('g','x','x')" return izip(*[chain(iterable, repeat(padvalue, n-1))]*n) - + def roundrobin(*iterables): + "roundrobin('abc', 'd', 'ef') --> 'a', 'd', 'e', 'b', 'f', 'c'" + # Recipe contributed by George Sakkis + pending = len(iterables) + nexts = cycle(iter(it).next for it in iterables) + while pending: + try: + for next in nexts: + yield next() + except StopIteration: + pending -= 1 + nexts = cycle(islice(nexts, pending)) Modified: python/branches/py3k/Doc/library/numbers.rst ============================================================================== --- python/branches/py3k/Doc/library/numbers.rst (original) +++ python/branches/py3k/Doc/library/numbers.rst Thu Jan 31 15:31:45 2008 @@ -97,3 +97,144 @@ 3-argument form of :func:`pow`, and the bit-string operations: ``<<``, ``>>``, ``&``, ``^``, ``|``, ``~``. Provides defaults for :func:`float`, :attr:`Rational.numerator`, and :attr:`Rational.denominator`. + + +Notes for type implementors +--------------------------- + +Implementors should be careful to make equal numbers equal and hash +them to the same values. This may be subtle if there are two different +extensions of the real numbers. For example, :class:`rational.Rational` +implements :func:`hash` as follows:: + + def __hash__(self): + if self.denominator == 1: + # Get integers right. + return hash(self.numerator) + # Expensive check, but definitely correct. + if self == float(self): + return hash(float(self)) + else: + # Use tuple's hash to avoid a high collision rate on + # simple fractions. + return hash((self.numerator, self.denominator)) + + +Adding More Numeric ABCs +~~~~~~~~~~~~~~~~~~~~~~~~ + +There are, of course, more possible ABCs for numbers, and this would +be a poor hierarchy if it precluded the possibility of adding +those. You can add ``MyFoo`` between :class:`Complex` and +:class:`Real` with:: + + class MyFoo(Complex): ... + MyFoo.register(Real) + + +Implementing the arithmetic operations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We want to implement the arithmetic operations so that mixed-mode +operations either call an implementation whose author knew about the +types of both arguments, or convert both to the nearest built in type +and do the operation there. For subtypes of :class:`Integral`, this +means that :meth:`__add__` and :meth:`__radd__` should be defined as:: + + class MyIntegral(Integral): + + def __add__(self, other): + if isinstance(other, MyIntegral): + return do_my_adding_stuff(self, other) + elif isinstance(other, OtherTypeIKnowAbout): + return do_my_other_adding_stuff(self, other) + else: + return NotImplemented + + def __radd__(self, other): + if isinstance(other, MyIntegral): + return do_my_adding_stuff(other, self) + elif isinstance(other, OtherTypeIKnowAbout): + return do_my_other_adding_stuff(other, self) + elif isinstance(other, Integral): + return int(other) + int(self) + elif isinstance(other, Real): + return float(other) + float(self) + elif isinstance(other, Complex): + return complex(other) + complex(self) + else: + return NotImplemented + + +There are 5 different cases for a mixed-type operation on subclasses +of :class:`Complex`. I'll refer to all of the above code that doesn't +refer to ``MyIntegral`` and ``OtherTypeIKnowAbout`` as +"boilerplate". ``a`` will be an instance of ``A``, which is a subtype +of :class:`Complex` (``a : A <: Complex``), and ``b : B <: +Complex``. I'll consider ``a + b``: + + 1. If ``A`` defines an :meth:`__add__` which accepts ``b``, all is + well. + 2. If ``A`` falls back to the boilerplate code, and it were to + return a value from :meth:`__add__`, we'd miss the possibility + that ``B`` defines a more intelligent :meth:`__radd__`, so the + boilerplate should return :const:`NotImplemented` from + :meth:`__add__`. (Or ``A`` may not implement :meth:`__add__` at + all.) + 3. Then ``B``'s :meth:`__radd__` gets a chance. If it accepts + ``a``, all is well. + 4. If it falls back to the boilerplate, there are no more possible + methods to try, so this is where the default implementation + should live. + 5. If ``B <: A``, Python tries ``B.__radd__`` before + ``A.__add__``. This is ok, because it was implemented with + knowledge of ``A``, so it can handle those instances before + delegating to :class:`Complex`. + +If ``A<:Complex`` and ``B<:Real`` without sharing any other knowledge, +then the appropriate shared operation is the one involving the built +in :class:`complex`, and both :meth:`__radd__` s land there, so ``a+b +== b+a``. + +Because most of the operations on any given type will be very similar, +it can be useful to define a helper function which generates the +forward and reverse instances of any given operator. For example, +:class:`rational.Rational` uses:: + + def _operator_fallbacks(monomorphic_operator, fallback_operator): + def forward(a, b): + if isinstance(b, (int, long, Rational)): + return monomorphic_operator(a, b) + elif isinstance(b, float): + return fallback_operator(float(a), b) + elif isinstance(b, complex): + return fallback_operator(complex(a), b) + else: + return NotImplemented + forward.__name__ = '__' + fallback_operator.__name__ + '__' + forward.__doc__ = monomorphic_operator.__doc__ + + def reverse(b, a): + if isinstance(a, RationalAbc): + # Includes ints. + return monomorphic_operator(a, b) + elif isinstance(a, numbers.Real): + return fallback_operator(float(a), float(b)) + elif isinstance(a, numbers.Complex): + return fallback_operator(complex(a), complex(b)) + else: + return NotImplemented + reverse.__name__ = '__r' + fallback_operator.__name__ + '__' + reverse.__doc__ = monomorphic_operator.__doc__ + + return forward, reverse + + def _add(a, b): + """a + b""" + return Rational(a.numerator * b.denominator + + b.numerator * a.denominator, + a.denominator * b.denominator) + + __add__, __radd__ = _operator_fallbacks(_add, operator.add) + + # ... \ No newline at end of file Modified: python/branches/py3k/Lib/_abcoll.py ============================================================================== --- python/branches/py3k/Lib/_abcoll.py (original) +++ python/branches/py3k/Lib/_abcoll.py Thu Jan 31 15:31:45 2008 @@ -300,16 +300,6 @@ self.discard(value) return value - def toggle(self, value): - """Return True if it was added, False if deleted.""" - # XXX This implementation is not thread-safe - if value in self: - self.discard(value) - return False - else: - self.add(value) - return True - def clear(self): """This is slow (creates N new iterators!) but effective.""" try: @@ -330,9 +320,13 @@ return self def __ixor__(self, it: Iterable): - # This calls toggle(), so if that is overridded, we call the override + if not isinstance(it, Set): + it = self._from_iterable(it) for value in it: - self.toggle(it) + if value in self: + self.discard(value) + else: + self.add(value) return self def __isub__(self, it: Iterable): Modified: python/branches/py3k/Lib/numbers.py ============================================================================== --- python/branches/py3k/Lib/numbers.py (original) +++ python/branches/py3k/Lib/numbers.py Thu Jan 31 15:31:45 2008 @@ -291,7 +291,13 @@ # Concrete implementation of Real's conversion to float. def __float__(self): - """float(self) = self.numerator / self.denominator""" + """float(self) = self.numerator / self.denominator + + It's important that this conversion use the integer's "true" + division rather than casting one side to float before dividing + so that ratios of huge integers convert without overflowing. + + """ return self.numerator / self.denominator Modified: python/branches/py3k/Lib/rational.py ============================================================================== --- python/branches/py3k/Lib/rational.py (original) +++ python/branches/py3k/Lib/rational.py Thu Jan 31 15:31:45 2008 @@ -178,16 +178,6 @@ else: return '%s/%s' % (self.numerator, self.denominator) - """ XXX This section needs a lot more commentary - - * Explain the typical sequence of checks, calls, and fallbacks. - * Explain the subtle reasons why this logic was needed. - * It is not clear how common cases are handled (for example, how - does the ratio of two huge integers get converted to a float - without overflowing the long-->float conversion. - - """ - def _operator_fallbacks(monomorphic_operator, fallback_operator): """Generates forward and reverse operators given a purely-rational operator and a function from the operator module. @@ -195,10 +185,82 @@ Use this like: __op__, __rop__ = _operator_fallbacks(just_rational_op, operator.op) + In general, we want to implement the arithmetic operations so + that mixed-mode operations either call an implementation whose + author knew about the types of both arguments, or convert both + to the nearest built in type and do the operation there. In + Rational, that means that we define __add__ and __radd__ as: + + def __add__(self, other): + if isinstance(other, (int, Rational)): + # Do the real operation. + return Rational(self.numerator * other.denominator + + other.numerator * self.denominator, + self.denominator * other.denominator) + # float and complex don't follow this protocol, and + # Rational knows about them, so special case them. + elif isinstance(other, float): + return float(self) + other + elif isinstance(other, complex): + return complex(self) + other + else: + # Let the other type take over. + return NotImplemented + + def __radd__(self, other): + # radd handles more types than add because there's + # nothing left to fall back to. + if isinstance(other, RationalAbc): + return Rational(self.numerator * other.denominator + + other.numerator * self.denominator, + self.denominator * other.denominator) + elif isinstance(other, Real): + return float(other) + float(self) + elif isinstance(other, Complex): + return complex(other) + complex(self) + else: + return NotImplemented + + + There are 5 different cases for a mixed-type addition on + Rational. I'll refer to all of the above code that doesn't + refer to Rational, float, or complex as "boilerplate". 'r' + will be an instance of Rational, which is a subtype of + RationalAbc (r : Rational <: RationalAbc), and b : B <: + Complex. The first three involve 'r + b': + + 1. If B <: Rational, int, float, or complex, we handle + that specially, and all is well. + 2. If Rational falls back to the boilerplate code, and it + were to return a value from __add__, we'd miss the + possibility that B defines a more intelligent __radd__, + so the boilerplate should return NotImplemented from + __add__. In particular, we don't handle RationalAbc + here, even though we could get an exact answer, in case + the other type wants to do something special. + 3. If B <: Rational, Python tries B.__radd__ before + Rational.__add__. This is ok, because it was + implemented with knowledge of Rational, so it can + handle those instances before delegating to Real or + Complex. + + The next two situations describe 'b + r'. We assume that b + didn't know about Rational in its implementation, and that it + uses similar boilerplate code: + + 4. If B <: RationalAbc, then __radd_ converts both to the + builtin rational type (hey look, that's us) and + proceeds. + 5. Otherwise, __radd__ tries to find the nearest common + base ABC, and fall back to its builtin type. Since this + class doesn't subclass a concrete type, there's no + implementation to fall back to, so we need to try as + hard as possible to return an actual value, or the user + will get a TypeError. + """ def forward(a, b): - if isinstance(b, RationalAbc): - # Includes ints. + if isinstance(b, (int, Rational)): return monomorphic_operator(a, b) elif isinstance(b, float): return fallback_operator(float(a), b) Modified: python/branches/py3k/Objects/floatobject.c ============================================================================== --- python/branches/py3k/Objects/floatobject.c (original) +++ python/branches/py3k/Objects/floatobject.c Thu Jan 31 15:31:45 2008 @@ -106,15 +106,9 @@ PyObject * PyFloat_GetInfo(void) { - static PyObject* floatinfo; + PyObject* floatinfo; int pos = 0; - if (floatinfo != NULL) { - Py_INCREF(floatinfo); - return floatinfo; - } - PyStructSequence_InitType(&FloatInfoType, &floatinfo_desc); - floatinfo = PyStructSequence_New(&FloatInfoType); if (floatinfo == NULL) { return NULL; @@ -143,8 +137,6 @@ Py_CLEAR(floatinfo); return NULL; } - - Py_INCREF(floatinfo); return floatinfo; } @@ -1601,6 +1593,9 @@ /* Initialize floating point repr */ _PyFloat_DigitsInit(); #endif + /* Init float info */ + if (FloatInfoType.tp_name == 0) + PyStructSequence_InitType(&FloatInfoType, &floatinfo_desc); } void Modified: python/branches/py3k/Python/import.c ============================================================================== --- python/branches/py3k/Python/import.c (original) +++ python/branches/py3k/Python/import.c Thu Jan 31 15:31:45 2008 @@ -371,6 +371,8 @@ "path", "argv", "ps1", "ps2", "last_type", "last_value", "last_traceback", "path_hooks", "path_importer_cache", "meta_path", + /* misc stuff */ + "flags", "float_info", NULL }; Modified: python/branches/py3k/Python/marshal.c ============================================================================== --- python/branches/py3k/Python/marshal.c (original) +++ python/branches/py3k/Python/marshal.c Thu Jan 31 15:31:45 2008 @@ -482,7 +482,7 @@ { /* NULL is a valid return value, it does not necessarily means that an exception is set. */ - PyObject *v, *v2, *v3; + PyObject *v, *v2; long i, n; int type = r_byte(p); PyObject *retval; Modified: python/branches/py3k/Python/sysmodule.c ============================================================================== --- python/branches/py3k/Python/sysmodule.c (original) +++ python/branches/py3k/Python/sysmodule.c Thu Jan 31 15:31:45 2008 @@ -1131,8 +1131,6 @@ if (PyErr_Occurred()) { return NULL; } - - Py_INCREF(seq); return seq; } @@ -1146,6 +1144,11 @@ if (m == NULL) return NULL; sysdict = PyModule_GetDict(m); +#define SET_SYS_FROM_STRING(key, value) \ + v = value; \ + if (v != NULL) \ + PyDict_SetItemString(sysdict, key, v); \ + Py_XDECREF(v) { /* XXX: does this work on Win/Win64? (see posix_fstat) */ @@ -1165,19 +1168,16 @@ PyDict_GetItemString(sysdict, "displayhook")); PyDict_SetItemString(sysdict, "__excepthook__", PyDict_GetItemString(sysdict, "excepthook")); - PyDict_SetItemString(sysdict, "version", - v = PyUnicode_FromString(Py_GetVersion())); - Py_XDECREF(v); - PyDict_SetItemString(sysdict, "hexversion", - v = PyLong_FromLong(PY_VERSION_HEX)); - Py_XDECREF(v); + SET_SYS_FROM_STRING("version", + PyUnicode_FromString(Py_GetVersion())); + SET_SYS_FROM_STRING("hexversion", + PyLong_FromLong(PY_VERSION_HEX)); svnversion_init(); - v = Py_BuildValue("(UUU)", "CPython", branch, svn_revision); - PyDict_SetItemString(sysdict, "subversion", v); - Py_XDECREF(v); - PyDict_SetItemString(sysdict, "dont_write_bytecode", - v = PyBool_FromLong(Py_DontWriteBytecodeFlag)); - Py_XDECREF(v); + SET_SYS_FROM_STRING("subversion", + Py_BuildValue("(UUU)", "CPython", branch, + svn_revision)); + SET_SYS_FROM_STRING("dont_write_bytecode", + PyBool_FromLong(Py_DontWriteBytecodeFlag)); /* * These release level checks are mutually exclusive and cover * the field, so don't get too fancy with the pre-processor! @@ -1192,12 +1192,6 @@ s = "final"; #endif -#define SET_SYS_FROM_STRING(key, value) \ - v = value; \ - if (v != NULL) \ - PyDict_SetItemString(sysdict, key, v); \ - Py_XDECREF(v) - SET_SYS_FROM_STRING("version_info", Py_BuildValue("iiiUi", PY_MAJOR_VERSION, PY_MINOR_VERSION, @@ -1244,7 +1238,6 @@ SET_SYS_FROM_STRING("winver", PyUnicode_FromString(PyWin_DLLVersionString)); #endif -#undef SET_SYS_FROM_STRING if (warnoptions == NULL) { warnoptions = PyList_New(0); } @@ -1255,12 +1248,14 @@ PyDict_SetItemString(sysdict, "warnoptions", warnoptions); } - PyStructSequence_InitType(&FlagsType, &flags_desc); - PyDict_SetItemString(sysdict, "flags", make_flags()); + if (FlagsType.tp_name == 0) + PyStructSequence_InitType(&FlagsType, &flags_desc); + SET_SYS_FROM_STRING("flags", make_flags()); /* prevent user from creating new instances */ FlagsType.tp_init = NULL; FlagsType.tp_new = NULL; +#undef SET_SYS_FROM_STRING if (PyErr_Occurred()) return NULL; return m; Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Thu Jan 31 15:31:45 2008 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 59829 . +# From configure.in Revision: 60144 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.0. # @@ -14603,6 +14603,12 @@ _ACEOF ;; + AIX/5) +cat >>confdefs.h <<\_ACEOF +#define HAVE_BROKEN_POSIX_SEMAPHORES 1 +_ACEOF + + ;; esac { echo "$as_me:$LINENO: checking if PTHREAD_SCOPE_SYSTEM is supported" >&5 Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Thu Jan 31 15:31:45 2008 @@ -1965,6 +1965,9 @@ SunOS/5.8) AC_DEFINE(HAVE_BROKEN_POSIX_SEMAPHORES, 1, Define if the Posix semaphores do not work on your system) ;; + AIX/5) AC_DEFINE(HAVE_BROKEN_POSIX_SEMAPHORES, 1, + Define if the Posix semaphores do not work on your system) + ;; esac AC_MSG_CHECKING(if PTHREAD_SCOPE_SYSTEM is supported) From python-3000-checkins at python.org Thu Jan 31 16:16:39 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Thu, 31 Jan 2008 16:16:39 +0100 (CET) Subject: [Python-3000-checkins] r60477 - in python/branches/py3k: Misc/NEWS Objects/longobject.c Message-ID: <20080131151639.315F11E4010@bag.python.org> Author: christian.heimes Date: Thu Jan 31 16:16:38 2008 New Revision: 60477 Modified: python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/longobject.c Log: Fixed multiple reinitialization of the Python interpreter. The small int list in longobject.c has caused a seg fault during the third finalization. Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Jan 31 16:16:38 2008 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Fixed multiple reinitialization of the Python interpreter. The small int + list in longobject.c has caused a seg fault during the third finalization. + - Issue #1973: bytes.fromhex('') raises SystemError - Issue #1771: remove cmp parameter from sorted() and list.sort() Modified: python/branches/py3k/Objects/longobject.c ============================================================================== --- python/branches/py3k/Objects/longobject.c (original) +++ python/branches/py3k/Objects/longobject.c Thu Jan 31 16:16:38 2008 @@ -3705,17 +3705,34 @@ _PyLong_Init(void) { #if NSMALLNEGINTS + NSMALLPOSINTS > 0 - int ival; + int ival, size; PyLongObject *v = small_ints; - for (ival = -NSMALLNEGINTS; ival < 0; ival++, v++) { - PyObject_INIT(v, &PyLong_Type); - Py_SIZE(v) = -1; - v->ob_digit[0] = -ival; - } - for (; ival < NSMALLPOSINTS; ival++, v++) { - PyObject_INIT(v, &PyLong_Type); - Py_SIZE(v) = ival ? 1 : 0; - v->ob_digit[0] = ival; + + for (ival = -NSMALLNEGINTS; ival < NSMALLPOSINTS; ival++, v++) { + size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1); + if (Py_TYPE(v) == &PyLong_Type) { + /* The element is already initialized, most likely + * the Python interpreter was initialized before. + */ + /* _Py_NewReference((PyObject*)v); + * XXX: It sets the ref count to 1 but it may be + * larger. Emulate new reference w/o setting refcnt + * to 1. + */ + PyObject* op = (PyObject*)v; + _Py_INC_REFTOTAL; + op->ob_refcnt = (op->ob_refcnt < 1) ? 1 : op->ob_refcnt; + _Py_AddToAllObjects(op, 1); + _Py_INC_TPALLOCS(op); + + assert(Py_SIZE(op) == size); + assert(v->ob_digit[0] == abs(ival)); + } + else { + PyObject_INIT(v, &PyLong_Type); + } + Py_SIZE(v) = size; + v->ob_digit[0] = abs(ival); } #endif return 1; @@ -3724,19 +3741,15 @@ void PyLong_Fini(void) { -#if 0 - int i; - /* This is currently not needed; the small integers - are statically allocated */ + /* Integers are currently statically allocated. Py_DECREF is not + needed, but Python must forget about the reference or multiple + reinitializations will fail. */ #if NSMALLNEGINTS + NSMALLPOSINTS > 0 - PyIntObject **q; - - i = NSMALLNEGINTS + NSMALLPOSINTS; - q = small_ints; - while (--i >= 0) { - Py_XDECREF(*q); - *q++ = NULL; - } -#endif + int i; + PyLongObject *v = small_ints; + for (i = 0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++, v++) { + _Py_DEC_REFTOTAL; + _Py_ForgetReference((PyObject*)v); + } #endif } From python-3000-checkins at python.org Thu Jan 31 19:04:10 2008 From: python-3000-checkins at python.org (christian.heimes) Date: Thu, 31 Jan 2008 19:04:10 +0100 (CET) Subject: [Python-3000-checkins] r60481 - python/branches/py3k Message-ID: <20080131180410.7E9751E4010@bag.python.org> Author: christian.heimes Date: Thu Jan 31 19:04:10 2008 New Revision: 60481 Modified: python/branches/py3k/ (props changed) Log: svnmerge.py block -r60480