From birkenfeld at users.sourceforge.net Sat Oct 1 18:32:34 2005 From: birkenfeld at users.sourceforge.net (birkenfeld@users.sourceforge.net) Date: Sat, 1 Oct 2005 18:32:34 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1381,1.1382 Message-ID: <20051001163234.DF5BB1E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1616/Misc Modified Files: NEWS Log Message: bug [ 729103 ] Cannot retrieve name of super object Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1381 retrieving revision 1.1382 diff -u -d -r1.1381 -r1.1382 --- NEWS 30 Sep 2005 04:46:49 -0000 1.1381 +++ NEWS 1 Oct 2005 16:32:31 -0000 1.1382 @@ -245,6 +245,9 @@ Library ------- +- Bug #729103: pydoc.py: Fix docother() method to accept additional + "parent" argument. + - Patch #1300515: xdrlib.py: Fix pack_fstring() to really use null bytes for padding. From birkenfeld at users.sourceforge.net Sat Oct 1 18:32:35 2005 From: birkenfeld at users.sourceforge.net (birkenfeld@users.sourceforge.net) Date: Sat, 1 Oct 2005 18:32:35 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib pydoc.py,1.106,1.107 Message-ID: <20051001163235.0AD511E4006@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1616/Lib Modified Files: pydoc.py Log Message: bug [ 729103 ] Cannot retrieve name of super object Index: pydoc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pydoc.py,v retrieving revision 1.106 retrieving revision 1.107 diff -u -d -r1.106 -r1.107 --- pydoc.py 22 Jul 2005 21:52:25 -0000 1.106 +++ pydoc.py 1 Oct 2005 16:32:31 -0000 1.107 @@ -1079,7 +1079,7 @@ if data: contents = [] for key, value in data: - contents.append(self.docother(value, key, name, 70)) + contents.append(self.docother(value, key, name, maxlen=70)) result = result + self.section('DATA', join(contents, '\n')) if hasattr(object, '__version__'): @@ -1164,7 +1164,7 @@ else: doc = None push(self.docother(getattr(object, name), - name, mod, 70, doc) + '\n') + name, mod, maxlen=70, doc=doc) + '\n') return attrs attrs = filter(lambda (name, kind, cls, value): visiblename(name), @@ -1272,7 +1272,7 @@ """Produce text documentation for a property.""" return self._docdescriptor(name, object, mod) - def docother(self, object, name=None, mod=None, maxlen=None, doc=None): + def docother(self, object, name=None, mod=None, parent=None, maxlen=None, doc=None): """Produce text documentation for a data object.""" repr = self.repr(object) if maxlen: From birkenfeld at users.sourceforge.net Sat Oct 1 18:32:43 2005 From: birkenfeld at users.sourceforge.net (birkenfeld@users.sourceforge.net) Date: Sat, 1 Oct 2005 18:32:43 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Misc NEWS, 1.1193.2.115, 1.1193.2.116 Message-ID: <20051001163243.BBFE11E4006@bag.python.org> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1642/Misc Modified Files: Tag: release24-maint NEWS Log Message: backport bug [ 729103 ] Cannot retrieve name of super object Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1193.2.115 retrieving revision 1.1193.2.116 diff -u -d -r1.1193.2.115 -r1.1193.2.116 --- NEWS 30 Sep 2005 04:58:23 -0000 1.1193.2.115 +++ NEWS 1 Oct 2005 16:32:40 -0000 1.1193.2.116 @@ -20,6 +20,9 @@ Library ------- +- Bug #729103: pydoc.py: Fix docother() method to accept additional + "parent" argument. + - Patch #1300515: xdrlib.py: Fix pack_fstring() to really use null bytes for padding. From birkenfeld at users.sourceforge.net Sat Oct 1 18:32:43 2005 From: birkenfeld at users.sourceforge.net (birkenfeld@users.sourceforge.net) Date: Sat, 1 Oct 2005 18:32:43 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib pydoc.py, 1.100.2.4, 1.100.2.5 Message-ID: <20051001163243.C6B651E4007@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1642/Lib Modified Files: Tag: release24-maint pydoc.py Log Message: backport bug [ 729103 ] Cannot retrieve name of super object Index: pydoc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pydoc.py,v retrieving revision 1.100.2.4 retrieving revision 1.100.2.5 diff -u -d -r1.100.2.4 -r1.100.2.5 --- pydoc.py 22 Jul 2005 21:52:33 -0000 1.100.2.4 +++ pydoc.py 1 Oct 2005 16:32:40 -0000 1.100.2.5 @@ -1078,7 +1078,7 @@ if data: contents = [] for key, value in data: - contents.append(self.docother(value, key, name, 70)) + contents.append(self.docother(value, key, name, maxlen=70)) result = result + self.section('DATA', join(contents, '\n')) if hasattr(object, '__version__'): @@ -1163,7 +1163,7 @@ else: doc = None push(self.docother(getattr(object, name), - name, mod, 70, doc) + '\n') + name, mod, maxlen=70, doc=doc) + '\n') return attrs attrs = filter(lambda (name, kind, cls, value): visiblename(name), @@ -1282,7 +1282,7 @@ """Produce text documentation for a property.""" return self._docproperty(name, object, mod) - def docother(self, object, name=None, mod=None, maxlen=None, doc=None): + def docother(self, object, name=None, mod=None, parent=None, maxlen=None, doc=None): """Produce text documentation for a data object.""" repr = self.repr(object) if maxlen: From birkenfeld at users.sourceforge.net Sat Oct 1 19:06:03 2005 From: birkenfeld at users.sourceforge.net (birkenfeld@users.sourceforge.net) Date: Sat, 1 Oct 2005 19:06:03 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Objects stringobject.c, 2.232, 2.233 Message-ID: <20051001170603.B916D1E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7536/Objects Modified Files: stringobject.c Log Message: Fix PyString_Format so that the "%s" format works again when Unicode is not enabled. Index: stringobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v retrieving revision 2.232 retrieving revision 2.233 diff -u -d -r2.232 -r2.233 --- stringobject.c 31 Aug 2005 23:02:05 -0000 2.232 +++ stringobject.c 1 Oct 2005 17:06:00 -0000 2.233 @@ -4083,7 +4083,9 @@ argidx = argidx_start; goto unicode; } +#endif temp = _PyObject_Str(v); +#ifdef Py_USING_UNICODE if (temp != NULL && PyUnicode_Check(temp)) { Py_DECREF(temp); fmt = fmt_start; From nnorwitz at users.sourceforge.net Sun Oct 2 03:48:54 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 2 Oct 2005 03:48:54 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1382,1.1383 Message-ID: <20051002014854.21CA51E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8132/Misc Modified Files: NEWS Log Message: - Fix segfault with invalid coding. - SF Bug #772896, unknown encoding results in MemoryError, which is not helpful I will only backport the segfault fix. I'll let Anthony decide if he wants the other changes backported. I will do the backport if asked. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1382 retrieving revision 1.1383 diff -u -d -r1.1382 -r1.1383 --- NEWS 1 Oct 2005 16:32:31 -0000 1.1382 +++ NEWS 2 Oct 2005 01:48:49 -0000 1.1383 @@ -12,6 +12,10 @@ Core and builtins ----------------- +- Fix segfault with invalid coding. + +- SF bug #772896: unknown encoding results in MemoryError. + - All iterators now have a Boolean value of true. Formerly, some iterators supported a __len__() method which evaluated to False when the iterator was empty. From nnorwitz at users.sourceforge.net Sun Oct 2 03:48:54 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 2 Oct 2005 03:48:54 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Parser parsetok.c, 2.36, 2.37 pgenmain.c, 2.31, 2.32 tokenizer.c, 2.78, 2.79 Message-ID: <20051002014854.2EC581E4006@bag.python.org> Update of /cvsroot/python/python/dist/src/Parser In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8132/Parser Modified Files: parsetok.c pgenmain.c tokenizer.c Log Message: - Fix segfault with invalid coding. - SF Bug #772896, unknown encoding results in MemoryError, which is not helpful I will only backport the segfault fix. I'll let Anthony decide if he wants the other changes backported. I will do the backport if asked. Index: parsetok.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Parser/parsetok.c,v retrieving revision 2.36 retrieving revision 2.37 diff -u -d -r2.36 -r2.37 --- parsetok.c 8 Jul 2004 01:54:07 -0000 2.36 +++ parsetok.c 2 Oct 2005 01:48:51 -0000 2.37 @@ -42,7 +42,7 @@ initerr(err_ret, filename); if ((tok = PyTokenizer_FromString(s)) == NULL) { - err_ret->error = E_NOMEM; + err_ret->error = PyErr_Occurred() ? E_DECODE : E_NOMEM; return NULL; } Index: pgenmain.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Parser/pgenmain.c,v retrieving revision 2.31 retrieving revision 2.32 diff -u -d -r2.31 -r2.32 --- pgenmain.c 7 Feb 2004 13:53:46 -0000 2.31 +++ pgenmain.c 2 Oct 2005 01:48:51 -0000 2.32 @@ -116,6 +116,13 @@ return g; } +/* Can't happen in pgen */ +PyObject* +PyErr_Occurred() +{ + return 0; +} + void Py_FatalError(const char *msg) { Index: tokenizer.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Parser/tokenizer.c,v retrieving revision 2.78 retrieving revision 2.79 diff -u -d -r2.78 -r2.79 --- tokenizer.c 12 Jul 2005 21:53:43 -0000 2.78 +++ tokenizer.c 2 Oct 2005 01:48:51 -0000 2.79 @@ -603,8 +603,11 @@ if (tok->enc != NULL) { assert(utf8 == NULL); utf8 = translate_into_utf8(str, tok->enc); - if (utf8 == NULL) + if (utf8 == NULL) { + PyErr_Format(PyExc_SyntaxError, + "unknown encoding: %s", tok->enc); return NULL; + } str = PyString_AsString(utf8); } #endif From nnorwitz at users.sourceforge.net Sun Oct 2 03:48:54 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 2 Oct 2005 03:48:54 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib/test bad_coding.py, NONE, 1.1 test_coding.py, NONE, 1.1 Message-ID: <20051002014854.371E21E4007@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8132/Lib/test Added Files: bad_coding.py test_coding.py Log Message: - Fix segfault with invalid coding. - SF Bug #772896, unknown encoding results in MemoryError, which is not helpful I will only backport the segfault fix. I'll let Anthony decide if he wants the other changes backported. I will do the backport if asked. --- NEW FILE: bad_coding.py --- # -*- coding: uft-8 -*- --- NEW FILE: test_coding.py --- import test.test_support, unittest import os class CodingTest(unittest.TestCase): def test_bad_coding(self): module_name = 'bad_coding' self.assertRaises(SyntaxError, __import__, 'test.' + module_name) path = os.path.dirname(__file__) filename = os.path.join(path, module_name + '.py') fp = open(filename) text = fp.read() fp.close() self.assertRaises(SyntaxError, compile, text, filename, 'exec') def test_main(): test.test_support.run_unittest(CodingTest) if __name__ == "__main__": test_main() From nnorwitz at users.sourceforge.net Sun Oct 2 03:48:54 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 2 Oct 2005 03:48:54 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Python pythonrun.c,2.216,2.217 Message-ID: <20051002014854.407DF1E4008@bag.python.org> Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8132/Python Modified Files: pythonrun.c Log Message: - Fix segfault with invalid coding. - SF Bug #772896, unknown encoding results in MemoryError, which is not helpful I will only backport the segfault fix. I'll let Anthony decide if he wants the other changes backported. I will do the backport if asked. Index: pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.216 retrieving revision 2.217 diff -u -d -r2.216 -r2.217 --- pythonrun.c 24 Aug 2005 08:39:24 -0000 2.216 +++ pythonrun.c 2 Oct 2005 01:48:50 -0000 2.217 @@ -1487,7 +1487,7 @@ msg = "unknown decode error"; Py_DECREF(type); Py_DECREF(value); - Py_DECREF(tb); + Py_XDECREF(tb); break; } case E_LINECONT: From nnorwitz at users.sourceforge.net Sun Oct 2 03:51:59 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 2 Oct 2005 03:51:59 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Python pythonrun.c, 2.211.2.2, 2.211.2.3 Message-ID: <20051002015159.D2C811E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8741/Python Modified Files: Tag: release24-maint pythonrun.c Log Message: Backported: Fix segfault with invalid coding. (See SF bug: 772896 for another fix) Index: pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.211.2.2 retrieving revision 2.211.2.3 diff -u -d -r2.211.2.2 -r2.211.2.3 --- pythonrun.c 24 Aug 2005 08:39:46 -0000 2.211.2.2 +++ pythonrun.c 2 Oct 2005 01:51:56 -0000 2.211.2.3 @@ -1484,7 +1484,7 @@ msg = "unknown decode error"; Py_DECREF(type); Py_DECREF(value); - Py_DECREF(tb); + Py_XDECREF(tb); break; } default: From nnorwitz at users.sourceforge.net Sun Oct 2 03:52:00 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 2 Oct 2005 03:52:00 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Misc NEWS, 1.1193.2.116, 1.1193.2.117 Message-ID: <20051002015200.1DDF21E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8741/Misc Modified Files: Tag: release24-maint NEWS Log Message: Backported: Fix segfault with invalid coding. (See SF bug: 772896 for another fix) Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1193.2.116 retrieving revision 1.1193.2.117 diff -u -d -r1.1193.2.116 -r1.1193.2.117 --- NEWS 1 Oct 2005 16:32:40 -0000 1.1193.2.116 +++ NEWS 2 Oct 2005 01:51:56 -0000 1.1193.2.117 @@ -9,6 +9,11 @@ *Release date: XX-XX-200X* +Core and builtins +----------------- + +- Fix segfault with invalid coding. + Extension Modules ----------------- From kbk at users.sourceforge.net Mon Oct 3 01:36:49 2005 From: kbk at users.sourceforge.net (kbk@users.sourceforge.net) Date: Mon, 3 Oct 2005 01:36:49 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib/idlelib CodeContext.py, 1.4, 1.5 NEWS.txt, 1.62, 1.63 Message-ID: <20051002233649.C85B11E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib/idlelib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32569 Modified Files: CodeContext.py NEWS.txt Log Message: Increased performance in CodeContext extension Patch 936169 Noam Raphael Index: CodeContext.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/idlelib/CodeContext.py,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- CodeContext.py 6 Jun 2004 01:29:21 -0000 1.4 +++ CodeContext.py 2 Oct 2005 23:36:46 -0000 1.5 @@ -14,10 +14,10 @@ from configHandler import idleConf from sets import Set import re +from sys import maxint as INFINITY BLOCKOPENERS = Set(["class", "def", "elif", "else", "except", "finally", "for", "if", "try", "while"]) -INFINITY = 1 << 30 UPDATEINTERVAL = 100 # millisec FONTUPDATEINTERVAL = 1000 # millisec @@ -37,8 +37,12 @@ self.text = editwin.text self.textfont = self.text["font"] self.label = None - # Dummy line, which starts the "block" of the whole document: - self.info = list(self.interesting_lines(1)) + # self.info holds information about the context lines of line number + # self.lastfirstline. The information is a tuple of the line's + # indentation, the line's text and the keyword at the beginning of the + # line, as returned by get_line_info. At the beginning of the list + # there's a dummy line, which starts the "block" of the whole document. + self.info = [(0, -1, "", False)] self.lastfirstline = 1 visible = idleConf.GetOption("extensions", "CodeContext", "visible", type="bool", default=False) @@ -73,14 +77,7 @@ If the line does not start a block, the keyword value is False. The indentation of empty lines (or comment lines) is INFINITY. - There is a dummy block start, with indentation -1 and text "". - - Return the indent level, text (including leading whitespace), - and the block opening keyword. - """ - if linenum == 0: - return -1, "", True text = self.text.get("%d.0" % linenum, "%d.end" % linenum) spaces, firstword = getspacesfirstword(text) opener = firstword in BLOCKOPENERS and firstword @@ -90,40 +87,59 @@ indent = len(spaces) return indent, text, opener - def interesting_lines(self, firstline): - """Generator which yields context lines, starting at firstline.""" + def interesting_lines(self, firstline, stopline=1, stopindent=0): + """ + Find the context lines, starting at firstline. + Will not return lines whose index is smaller than stopline or whose + indentation is smaller than stopindent. + stopline should always be >= 1, so the dummy block start will never + be returned (This function doesn't know what to do about it.) + Returns a list with the context lines, starting from the first (top), + and a number which all context lines above the inspected region should + have a smaller indentation than it. + """ + lines = [] # The indentation level we are currently in: lastindent = INFINITY # For a line to be interesting, it must begin with a block opening # keyword, and have less indentation than lastindent. - for line_index in xrange(firstline, -1, -1): + for line_index in xrange(firstline, stopline-1, -1): indent, text, opener = self.get_line_info(line_index) if indent < lastindent: lastindent = indent if opener in ("else", "elif"): # We also show the if statement lastindent += 1 - if opener and line_index < firstline: - yield line_index, text + if opener and line_index < firstline and indent >= stopindent: + lines.append((line_index, indent, text, opener)) + if lastindent <= stopindent: + break + lines.reverse() + return lines, lastindent def update_label(self): + """Update the CodeContext label, if needed. + """ firstline = int(self.text.index("@0,0").split('.')[0]) if self.lastfirstline == firstline: return - self.lastfirstline = firstline - tmpstack = [] - for line_index, text in self.interesting_lines(firstline): - # Remove irrelevant self.info items, and when we reach a relevant - # item (which must happen because of the dummy element), break. - while self.info[-1][0] > line_index: + if self.lastfirstline < firstline: + lines, lastindent = self.interesting_lines(firstline, + self.lastfirstline) + while self.info[-1][1] >= lastindent: del self.info[-1] - if self.info[-1][0] == line_index: - break - tmpstack.append((line_index, text)) - while tmpstack: - self.info.append(tmpstack.pop()) + self.info.extend(lines) + else: + stopindent = self.info[-1][1] + 1 + while self.info[-1][0] >= firstline: + stopindent = self.info[-1][1] + del self.info[-1] + lines, lastindent = self.interesting_lines( + firstline, self.info[-1][0]+1, stopindent) + self.info.extend(lines) + self.lastfirstline = firstline lines = [""] * max(0, self.numlines - len(self.info)) + \ - [x[1] for x in self.info[-self.numlines:]] + [x[2] for x in self.info[-self.numlines:]] self.label["text"] = '\n'.join(lines) def timer_event(self): Index: NEWS.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/idlelib/NEWS.txt,v retrieving revision 1.62 retrieving revision 1.63 diff -u -d -r1.62 -r1.63 --- NEWS.txt 23 Aug 2005 02:27:23 -0000 1.62 +++ NEWS.txt 2 Oct 2005 23:36:46 -0000 1.63 @@ -3,6 +3,8 @@ *Release date: XX-XXX-2005* +- Increased performance in CodeContext extension Patch 936169 Noam Raphael + - Mac line endings were incorrect when pasting code from some browsers when using X11 and the Fink distribution. Python Bug 1263656. @@ -148,12 +150,12 @@ - If nulls somehow got into the strings in recent-files.lst EditorWindow.update_recent_files_list() was failing. Python Bug 931336. -- If the normal background is changed via Configure/Highlighting, it will update - immediately, thanks to the previously mentioned patch by Nigel Rowe. +- If the normal background is changed via Configure/Highlighting, it will + update immediately, thanks to the previously mentioned patch by Nigel Rowe. - Add a highlight theme for builtin keywords. Python Patch 805830 Nigel Rowe - This also fixed IDLEfork bug [ 693418 ] Normal text background color not refreshed - and Python bug [897872 ] Unknown color name on HP-UX + This also fixed IDLEfork bug [ 693418 ] Normal text background color not + refreshed and Python bug [897872 ] Unknown color name on HP-UX - rpc.py:SocketIO - Large modules were generating large pickles when downloaded to the execution server. The return of the OK response from the subprocess From nnorwitz at users.sourceforge.net Mon Oct 3 02:36:19 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 3 Oct 2005 02:36:19 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/lib asttable.tex,1.2,1.3 Message-ID: <20051003003619.F11F81E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12751/lib Modified Files: asttable.tex Log Message: SF patch #1227568, bug #1219273, Expression AST node not documented. Backport candidate if anyone cares. Index: asttable.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/asttable.tex,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- asttable.tex 2 Aug 2004 06:09:52 -0000 1.2 +++ asttable.tex 3 Oct 2005 00:36:16 -0000 1.3 @@ -89,6 +89,8 @@ \lineiii{Ellipsis}{}{} \hline +\lineiii{Expression}{\member{node}}{} + \lineiii{Exec}{\member{expr}}{} \lineiii{}{\member{locals}}{} \lineiii{}{\member{globals}}{} From nnorwitz at users.sourceforge.net Mon Oct 3 02:38:49 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 3 Oct 2005 02:38:49 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Misc ACKS,1.297,1.298 Message-ID: <20051003003849.CFCE11E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13020/Misc Modified Files: ACKS Log Message: SF patch #1227568, Expression AST node not documented. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.297 retrieving revision 1.298 diff -u -d -r1.297 -r1.298 --- ACKS 30 Sep 2005 04:46:49 -0000 1.297 +++ ACKS 3 Oct 2005 00:38:46 -0000 1.298 @@ -316,6 +316,7 @@ Bob Kahn Kurt B. Kaiser Tamito Kajiyama +Peter van Kampen Jacob Kaplan-Moss Lou Kates Sebastien Keim From nnorwitz at users.sourceforge.net Mon Oct 3 02:44:10 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 3 Oct 2005 02:44:10 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/lib libsocket.tex,1.89,1.90 Message-ID: <20051003004410.080C91E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13761/Doc/lib Modified Files: libsocket.tex Log Message: SF Bug #1308042, platform dependent behaviour (Windoze of course) in UDP sockets. Will backport Index: libsocket.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsocket.tex,v retrieving revision 1.89 retrieving revision 1.90 diff -u -d -r1.89 -r1.90 --- libsocket.tex 11 Mar 2005 00:04:17 -0000 1.89 +++ libsocket.tex 3 Oct 2005 00:44:06 -0000 1.90 @@ -7,7 +7,8 @@ This module provides access to the BSD \emph{socket} interface. It is available on all modern \UNIX{} systems, Windows, MacOS, BeOS, -OS/2, and probably additional platforms. +OS/2, and probably additional platforms. \note{Some behavior may be +platform dependent, since calls are made to the operating system socket APIs.} For an introduction to socket programming (in C), see the following papers: \citetitle{An Introductory 4.3BSD Interprocess Communication From nnorwitz at users.sourceforge.net Mon Oct 3 02:44:48 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 3 Oct 2005 02:44:48 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/lib libsocket.tex, 1.88.2.1, 1.88.2.2 Message-ID: <20051003004448.9EE3C1E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13885/Doc/lib Modified Files: Tag: release24-maint libsocket.tex Log Message: Backport: SF Bug #1308042, platform dependent behaviour (Windoze of course) in UDP sockets. Index: libsocket.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsocket.tex,v retrieving revision 1.88.2.1 retrieving revision 1.88.2.2 diff -u -d -r1.88.2.1 -r1.88.2.2 --- libsocket.tex 12 Mar 2005 06:15:54 -0000 1.88.2.1 +++ libsocket.tex 3 Oct 2005 00:44:45 -0000 1.88.2.2 @@ -7,7 +7,8 @@ This module provides access to the BSD \emph{socket} interface. It is available on all modern \UNIX{} systems, Windows, MacOS, BeOS, -OS/2, and probably additional platforms. +OS/2, and probably additional platforms. \note{Some behavior may be +platform dependent, since calls are made to the operating system socket APIs.} For an introduction to socket programming (in C), see the following papers: \citetitle{An Introductory 4.3BSD Interprocess Communication From nnorwitz at users.sourceforge.net Mon Oct 3 02:55:00 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 3 Oct 2005 02:55:00 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib/test test_cmd_line.py, NONE, 1.1 Message-ID: <20051003005500.B7DBB1E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15556/Lib/test Added Files: test_cmd_line.py Log Message: SF bug #887946, segfault if redirecting directory Also provide a warning if a directory is passed on the command line. Add minimal command line test. Will backport. --- NEW FILE: test_cmd_line.py --- import test.test_support, unittest import sys import popen2 class CmdLineTest(unittest.TestCase): def start_python(self, cmd_line): outfp, infp = popen2.popen4('%s %s' % (sys.executable, cmd_line)) infp.close() data = outfp.read() outfp.close() return data def test_directories(self): self.assertTrue('is a directory' in self.start_python('.')) self.assertTrue('is a directory' in self.start_python('< .')) def verify_valid_flag(self, cmd_line): data = self.start_python(cmd_line) self.assertTrue(data.endswith('\n')) self.assertTrue('Traceback' not in data) def test_environment(self): self.verify_valid_flag('-E') def test_optimize(self): self.verify_valid_flag('-O') self.verify_valid_flag('-OO') def test_q(self): self.verify_valid_flag('-Qold') self.verify_valid_flag('-Qnew') self.verify_valid_flag('-Qwarn') self.verify_valid_flag('-Qwarnall') def test_site_flag(self): self.verify_valid_flag('-S') def test_usage(self): self.assertTrue('usage' in self.start_python('-h')) def test_version(self): version = 'Python %d.%d' % sys.version_info[:2] self.assertTrue(self.start_python('-V').startswith(version)) def test_main(): test.test_support.run_unittest(CmdLineTest) if __name__ == "__main__": test_main() From nnorwitz at users.sourceforge.net Mon Oct 3 02:55:00 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 3 Oct 2005 02:55:00 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1383,1.1384 Message-ID: <20051003005500.E100C1E4006@bag.python.org> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15556/Misc Modified Files: NEWS Log Message: SF bug #887946, segfault if redirecting directory Also provide a warning if a directory is passed on the command line. Add minimal command line test. Will backport. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1383 retrieving revision 1.1384 diff -u -d -r1.1383 -r1.1384 --- NEWS 2 Oct 2005 01:48:49 -0000 1.1383 +++ NEWS 3 Oct 2005 00:54:56 -0000 1.1384 @@ -12,6 +12,9 @@ Core and builtins ----------------- +- SF Bug #887946: fix segfault when redirecting stdin from a directory. + Provide a warning when a directory is passed on the command line. + - Fix segfault with invalid coding. - SF bug #772896: unknown encoding results in MemoryError. From nnorwitz at users.sourceforge.net Mon Oct 3 02:55:00 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 3 Oct 2005 02:55:00 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Modules main.c,1.84,1.85 Message-ID: <20051003005500.E2B1C1E4007@bag.python.org> Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15556/Modules Modified Files: main.c Log Message: SF bug #887946, segfault if redirecting directory Also provide a warning if a directory is passed on the command line. Add minimal command line test. Will backport. Index: main.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/main.c,v retrieving revision 1.84 retrieving revision 1.85 diff -u -d -r1.84 -r1.85 --- main.c 7 Oct 2004 06:46:25 -0000 1.84 +++ main.c 3 Oct 2005 00:54:57 -0000 1.85 @@ -359,6 +359,14 @@ } } } + { + /* XXX: does this work on Win/Win64? (see posix_fstat) */ + struct stat sb; + if (fstat(fileno(fp), &sb) == 0 && + S_ISDIR(sb.st_mode)) { + fprintf(stderr, "%s: warning '%s' is a directory\n", argv[0], filename); + } + } } } From nnorwitz at users.sourceforge.net Mon Oct 3 02:55:00 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 3 Oct 2005 02:55:00 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Python sysmodule.c,2.129,2.130 Message-ID: <20051003005500.EB2641E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15556/Python Modified Files: sysmodule.c Log Message: SF bug #887946, segfault if redirecting directory Also provide a warning if a directory is passed on the command line. Add minimal command line test. Will backport. Index: sysmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v retrieving revision 2.129 retrieving revision 2.130 diff -u -d -r2.129 -r2.130 --- sysmodule.c 15 Sep 2005 13:00:34 -0000 2.129 +++ sysmodule.c 3 Oct 2005 00:54:57 -0000 2.130 @@ -947,6 +947,15 @@ m = Py_InitModule3("sys", sys_methods, sys_doc); sysdict = PyModule_GetDict(m); + { + /* XXX: does this work on Win/Win64? (see posix_fstat) */ + struct stat sb; + if (fstat(fileno(stdin), &sb) == 0 && + S_ISDIR(sb.st_mode)) { + Py_FatalError(" is a directory"); + } + } + /* Closing the standard FILE* if sys.std* goes aways causes problems * for embedded Python usages. Closing them when somebody explicitly * invokes .close() might be possible, but the FAQ promises they get From nnorwitz at users.sourceforge.net Mon Oct 3 03:03:48 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 3 Oct 2005 03:03:48 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Misc NEWS, 1.1193.2.117, 1.1193.2.118 Message-ID: <20051003010348.6D0BC1E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17796/Misc Modified Files: Tag: release24-maint NEWS Log Message: Backport: SF bug #887946, segfault if redirecting directory Also provide a warning if a directory is passed on the command line. Add minimal command line test. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1193.2.117 retrieving revision 1.1193.2.118 diff -u -d -r1.1193.2.117 -r1.1193.2.118 --- NEWS 2 Oct 2005 01:51:56 -0000 1.1193.2.117 +++ NEWS 3 Oct 2005 01:03:44 -0000 1.1193.2.118 @@ -12,6 +12,9 @@ Core and builtins ----------------- +- SF Bug #887946: fix segfault when redirecting stdin from a directory. + Provide a warning when a directory is passed on the command line. + - Fix segfault with invalid coding. Extension Modules From nnorwitz at users.sourceforge.net Mon Oct 3 03:03:48 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 3 Oct 2005 03:03:48 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Modules main.c,1.84,1.84.2.1 Message-ID: <20051003010348.7BCA11E4006@bag.python.org> Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17796/Modules Modified Files: Tag: release24-maint main.c Log Message: Backport: SF bug #887946, segfault if redirecting directory Also provide a warning if a directory is passed on the command line. Add minimal command line test. Index: main.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/main.c,v retrieving revision 1.84 retrieving revision 1.84.2.1 diff -u -d -r1.84 -r1.84.2.1 --- main.c 7 Oct 2004 06:46:25 -0000 1.84 +++ main.c 3 Oct 2005 01:03:45 -0000 1.84.2.1 @@ -359,6 +359,14 @@ } } } + { + /* XXX: does this work on Win/Win64? (see posix_fstat) */ + struct stat sb; + if (fstat(fileno(fp), &sb) == 0 && + S_ISDIR(sb.st_mode)) { + fprintf(stderr, "%s: warning '%s' is a directory\n", argv[0], filename); + } + } } } From nnorwitz at users.sourceforge.net Mon Oct 3 03:03:48 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 3 Oct 2005 03:03:48 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Python sysmodule.c, 2.126.2.3, 2.126.2.4 Message-ID: <20051003010348.E0E771E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17796/Python Modified Files: Tag: release24-maint sysmodule.c Log Message: Backport: SF bug #887946, segfault if redirecting directory Also provide a warning if a directory is passed on the command line. Add minimal command line test. Index: sysmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v retrieving revision 2.126.2.3 retrieving revision 2.126.2.4 diff -u -d -r2.126.2.3 -r2.126.2.4 --- sysmodule.c 15 Sep 2005 13:00:25 -0000 2.126.2.3 +++ sysmodule.c 3 Oct 2005 01:03:45 -0000 2.126.2.4 @@ -947,6 +947,15 @@ m = Py_InitModule3("sys", sys_methods, sys_doc); sysdict = PyModule_GetDict(m); + { + /* XXX: does this work on Win/Win64? (see posix_fstat) */ + struct stat sb; + if (fstat(fileno(stdin), &sb) == 0 && + S_ISDIR(sb.st_mode)) { + Py_FatalError(" is a directory"); + } + } + /* Closing the standard FILE* if sys.std* goes aways causes problems * for embedded Python usages. Closing them when somebody explicitly * invokes .close() might be possible, but the FAQ promises they get From nnorwitz at users.sourceforge.net Mon Oct 3 03:03:48 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 3 Oct 2005 03:03:48 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib/test test_cmd_line.py, NONE, 1.1.2.2 Message-ID: <20051003010348.EF9E91E4006@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17796/Lib/test Added Files: Tag: release24-maint test_cmd_line.py Log Message: Backport: SF bug #887946, segfault if redirecting directory Also provide a warning if a directory is passed on the command line. Add minimal command line test. --- NEW FILE: test_cmd_line.py --- import test.test_support, unittest import sys import popen2 class CmdLineTest(unittest.TestCase): def start_python(self, cmd_line): outfp, infp = popen2.popen4('%s %s' % (sys.executable, cmd_line)) infp.close() data = outfp.read() outfp.close() return data def test_directories(self): self.assertTrue('is a directory' in self.start_python('.')) self.assertTrue('is a directory' in self.start_python('< .')) def verify_valid_flag(self, cmd_line): data = self.start_python(cmd_line) self.assertTrue(data.endswith('\n')) self.assertTrue('Traceback' not in data) def test_environment(self): self.verify_valid_flag('-E') def test_optimize(self): self.verify_valid_flag('-O') self.verify_valid_flag('-OO') def test_q(self): self.verify_valid_flag('-Qold') self.verify_valid_flag('-Qnew') self.verify_valid_flag('-Qwarn') self.verify_valid_flag('-Qwarnall') def test_site_flag(self): self.verify_valid_flag('-S') def test_usage(self): self.assertTrue('usage' in self.start_python('-h')) def test_version(self): version = 'Python %d.%d' % sys.version_info[:2] self.assertTrue(self.start_python('-V').startswith(version)) def test_main(): test.test_support.run_unittest(CmdLineTest) if __name__ == "__main__": test_main() From nnorwitz at users.sourceforge.net Mon Oct 3 05:57:12 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 3 Oct 2005 05:57:12 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Modules ld_so_aix,2.5,2.6 Message-ID: <20051003035712.9012A1E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13804/Modules Modified Files: ld_so_aix Log Message: SF Bug # 941346, AIX shared library fix Since I can't test this, I'm just adding a comment. If we get access to AIX boxes, we can test this and really resolve. Anyone from IBM want to offer help? Backport candidate I suppose. Index: ld_so_aix =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/ld_so_aix,v retrieving revision 2.5 retrieving revision 2.6 diff -u -d -r2.5 -r2.6 --- ld_so_aix 3 Sep 1997 00:45:30 -0000 2.5 +++ ld_so_aix 3 Oct 2005 03:57:09 -0000 2.6 @@ -168,6 +168,10 @@ CCOPT="-Wl,-e$entry -Wl,-bE:$expfile -Wl,-bI:$impfile -Wl,-bhalt:4" CCOPT="$CCOPT -Wl,-bM:SRE -Wl,-T512 -Wl,-H512 -lm -o $objfile" +# Note: to use dynamic libraries like libtcl8.4.so and libtk8.4.so +# you may need to replace the second CCOPT line above with the following: +# CCOPT="$CCOPT -Wl,-bM:SRE -Wl,-T512 -Wl,-H512 -brtl -bnortllib -lm -o $objfile" + CCARGS="$args" # Export list generation. From nnorwitz at users.sourceforge.net Mon Oct 3 06:48:18 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 3 Oct 2005 06:48:18 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Python import.c,2.244,2.245 Message-ID: <20051003044818.C20701E4006@bag.python.org> Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23608/Python Modified Files: import.c Log Message: Fix SF bug #976608, Unhelpful error message when mtime of a module is -1 Will backport. Index: import.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/import.c,v retrieving revision 2.244 retrieving revision 2.245 diff -u -d -r2.244 -r2.245 --- import.c 14 Sep 2005 18:09:42 -0000 2.244 +++ import.c 3 Oct 2005 04:48:15 -0000 2.245 @@ -868,8 +868,12 @@ PyObject *m; mtime = PyOS_GetLastModificationTime(pathname, fp); - if (mtime == (time_t)(-1)) + if (mtime == (time_t)(-1)) { + PyErr_Format(PyExc_RuntimeError, + "unable to get modification time from '%s'", + pathname); return NULL; + } #if SIZEOF_TIME_T > 4 /* Python's .pyc timestamp handling presumes that the timestamp fits in 4 bytes. This will be fine until sometime in the year 2038, From nnorwitz at users.sourceforge.net Mon Oct 3 06:48:18 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 3 Oct 2005 06:48:18 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1384,1.1385 Message-ID: <20051003044818.C19DA1E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23608/Misc Modified Files: NEWS Log Message: Fix SF bug #976608, Unhelpful error message when mtime of a module is -1 Will backport. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1384 retrieving revision 1.1385 diff -u -d -r1.1384 -r1.1385 --- NEWS 3 Oct 2005 00:54:56 -0000 1.1384 +++ NEWS 3 Oct 2005 04:48:14 -0000 1.1385 @@ -12,6 +12,8 @@ Core and builtins ----------------- +- SF Bug #976608: fix SystemError when mtime of an imported file is -1. + - SF Bug #887946: fix segfault when redirecting stdin from a directory. Provide a warning when a directory is passed on the command line. From nnorwitz at users.sourceforge.net Mon Oct 3 06:50:58 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 3 Oct 2005 06:50:58 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Misc NEWS, 1.1193.2.118, 1.1193.2.119 Message-ID: <20051003045058.B14A01E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24241/Misc Modified Files: Tag: release24-maint NEWS Log Message: Backport: Fix SF bug #976608, Unhelpful error message when mtime of a module is -1 Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1193.2.118 retrieving revision 1.1193.2.119 diff -u -d -r1.1193.2.118 -r1.1193.2.119 --- NEWS 3 Oct 2005 01:03:44 -0000 1.1193.2.118 +++ NEWS 3 Oct 2005 04:50:55 -0000 1.1193.2.119 @@ -12,6 +12,8 @@ Core and builtins ----------------- +- SF Bug #976608: fix SystemError when mtime of an imported file is -1. + - SF Bug #887946: fix segfault when redirecting stdin from a directory. Provide a warning when a directory is passed on the command line. From nnorwitz at users.sourceforge.net Mon Oct 3 06:50:58 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 3 Oct 2005 06:50:58 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Python import.c, 2.240.2.2, 2.240.2.3 Message-ID: <20051003045058.D69991E4006@bag.python.org> Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24241/Python Modified Files: Tag: release24-maint import.c Log Message: Backport: Fix SF bug #976608, Unhelpful error message when mtime of a module is -1 Index: import.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/import.c,v retrieving revision 2.240.2.2 retrieving revision 2.240.2.3 diff -u -d -r2.240.2.2 -r2.240.2.3 --- import.c 14 Sep 2005 18:15:03 -0000 2.240.2.2 +++ import.c 3 Oct 2005 04:50:55 -0000 2.240.2.3 @@ -867,8 +867,12 @@ PyObject *m; mtime = PyOS_GetLastModificationTime(pathname, fp); - if (mtime == (time_t)(-1)) + if (mtime == (time_t)(-1)) { + PyErr_Format(PyExc_RuntimeError, + "unable to get modification time from '%s'", + pathname); return NULL; + } #if SIZEOF_TIME_T > 4 /* Python's .pyc timestamp handling presumes that the timestamp fits in 4 bytes. This will be fine until sometime in the year 2038, From nnorwitz at users.sourceforge.net Mon Oct 3 07:13:49 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 3 Oct 2005 07:13:49 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/lib libos.tex,1.167,1.168 Message-ID: <20051003051349.E69591E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28640/lib Modified Files: libos.tex Log Message: Fix SF bug #991735, os.access reports true for read-only directories. Will backport Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.167 retrieving revision 1.168 diff -u -d -r1.167 -r1.168 --- libos.tex 31 Aug 2005 13:50:17 -0000 1.167 +++ libos.tex 3 Oct 2005 05:13:46 -0000 1.168 @@ -692,6 +692,11 @@ open a file before actually doing so using \function{open()} creates a security hole, because the user might exploit the short time interval between checking and opening the file to manipulate it.} + +\note{I/O operations may fail even when \function{access()} +indicates that they would succeed, particularly for operations +on network filesystems which may have permissions semantics +beyond the usual \POSIX{} permission-bit model.} \end{funcdesc} \begin{datadesc}{F_OK} From nnorwitz at users.sourceforge.net Mon Oct 3 07:14:28 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 3 Oct 2005 07:14:28 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/lib libos.tex, 1.146.2.10, 1.146.2.11 Message-ID: <20051003051428.ACF5C1E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28694/Doc/lib Modified Files: Tag: release24-maint libos.tex Log Message: Fix SF bug #991735, os.access reports true for read-only directories. Will backport Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.146.2.10 retrieving revision 1.146.2.11 diff -u -d -r1.146.2.10 -r1.146.2.11 --- libos.tex 18 Jul 2005 08:17:08 -0000 1.146.2.10 +++ libos.tex 3 Oct 2005 05:14:25 -0000 1.146.2.11 @@ -672,6 +672,11 @@ open a file before actually doing so using \function{open()} creates a security hole, because the user might exploit the short time interval between checking and opening the file to manipulate it.} + +\note{I/O operations may fail even when \function{access()} +indicates that they would succeed, particularly for operations +on network filesystems which may have permissions semantics +beyond the usual \POSIX{} permission-bit model.} \end{funcdesc} \begin{datadesc}{F_OK} From nnorwitz at users.sourceforge.net Mon Oct 3 07:47:41 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 3 Oct 2005 07:47:41 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/lib libos.tex,1.168,1.169 Message-ID: <20051003054741.B17FB1E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1602/lib Modified Files: libos.tex Log Message: SF Bug #1008310, os.major() os.minor() example and description change. Will backport. Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.168 retrieving revision 1.169 diff -u -d -r1.168 -r1.169 --- libos.tex 3 Oct 2005 05:13:46 -0000 1.168 +++ libos.tex 3 Oct 2005 05:47:38 -0000 1.169 @@ -843,12 +843,14 @@ \end{funcdesc} \begin{funcdesc}{major}{device} -Extracts a device major number from a raw device number. +Extracts the device major number from a raw device number (usually +the \member{st_dev} or \member{st_rdev} field from \ctype{stat}). \versionadded{2.3} \end{funcdesc} \begin{funcdesc}{minor}{device} -Extracts a device minor number from a raw device number. +Extracts the device minor number from a raw device number (usually +the \member{st_dev} or \member{st_rdev} field from \ctype{stat}). \versionadded{2.3} \end{funcdesc} From nnorwitz at users.sourceforge.net Mon Oct 3 07:48:22 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 3 Oct 2005 07:48:22 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/lib libos.tex, 1.146.2.11, 1.146.2.12 Message-ID: <20051003054822.2C5841E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1724/Doc/lib Modified Files: Tag: release24-maint libos.tex Log Message: Backport: SF Bug #1008310, os.major() os.minor() example and description change. Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.146.2.11 retrieving revision 1.146.2.12 diff -u -d -r1.146.2.11 -r1.146.2.12 --- libos.tex 3 Oct 2005 05:14:25 -0000 1.146.2.11 +++ libos.tex 3 Oct 2005 05:48:18 -0000 1.146.2.12 @@ -823,12 +823,14 @@ \end{funcdesc} \begin{funcdesc}{major}{device} -Extracts a device major number from a raw device number. +Extracts the device major number from a raw device number (usually +the \member{st_dev} or \member{st_rdev} field from \ctype{stat}). \versionadded{2.3} \end{funcdesc} \begin{funcdesc}{minor}{device} -Extracts a device minor number from a raw device number. +Extracts the device minor number from a raw device number (usually +the \member{st_dev} or \member{st_rdev} field from \ctype{stat}). \versionadded{2.3} \end{funcdesc} From nnorwitz at users.sourceforge.net Mon Oct 3 09:46:37 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 3 Oct 2005 09:46:37 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Misc valgrind-python.supp, 1.1, 1.2 Message-ID: <20051003074637.998B41E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26526/Misc Modified Files: valgrind-python.supp Log Message: suppress more errors on my box, most are gentoo specific. Py_ADDRESS_IN_RANGE is x86_64 specific and the readline memory leaks should be generally applicable Index: valgrind-python.supp =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/valgrind-python.supp,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- valgrind-python.supp 6 Jun 2004 19:58:40 -0000 1.1 +++ valgrind-python.supp 3 Oct 2005 07:46:34 -0000 1.2 @@ -29,6 +29,12 @@ } { + ADDRESS_IN_RANGE/Invalid read of size 8 (x86_64) + Memcheck:Value8 + fun:Py_ADDRESS_IN_RANGE +} + +{ ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value Memcheck:Cond fun:Py_ADDRESS_IN_RANGE @@ -84,6 +90,118 @@ } +{ + Avoid problem in libc on gentoo + Memcheck:Cond + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so +} + +{ + Avoid problem in glibc on gentoo + Memcheck:Addr8 + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/libc-2.3.4.so + obj:/lib/ld-2.3.4.so + fun:_dl_open + obj:/lib/libdl-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/libdl-2.3.4.so + fun:dlopen +} + +{ + Avoid problem in glibc on gentoo + Memcheck:Addr8 + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/libc-2.3.4.so + obj:/lib/ld-2.3.4.so + fun:_dl_open + obj:/lib/libdl-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/libdl-2.3.4.so + fun:dlopen +} + +{ + Avoid problem in glibc on gentoo + Memcheck:Cond + obj:/lib/ld-2.3.4.so + obj:/lib/libc-2.3.4.so + obj:/lib/ld-2.3.4.so + fun:_dl_open + obj:/lib/libdl-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/libdl-2.3.4.so + fun:dlopen +} + +{ + Avoid problem in glibc on gentoo + Memcheck:Cond + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/libc-2.3.4.so + obj:/lib/ld-2.3.4.so + fun:_dl_open + obj:/lib/libdl-2.3.4.so + obj:/lib/ld-2.3.4.so + obj:/lib/libdl-2.3.4.so + fun:dlopen +} + +{ + Avoid problems w/readline doing a putenv and leaking on exit + Memcheck:Leak + fun:malloc + fun:xmalloc + fun:sh_set_lines_and_columns + fun:_rl_get_screen_size + fun:_rl_init_terminal_io + obj:/lib/libreadline.so.4.3 + fun:rl_initialize + fun:setup_readline + fun:initreadline + fun:_PyImport_LoadDynamicModule + fun:load_module + fun:import_submodule + fun:load_next + fun:import_module_ex + fun:PyImport_ImportModuleEx +} + +{ + Mysterious leak that seems to deal w/pthreads + Memcheck:Leak + fun:calloc + obj:/lib/ld-2.3.4.so + obj:/lib/ld-2.3.4.so + fun:_dl_allocate_tls + fun:__pthread_initialize_minimal +} + +{ + Mysterious leak that seems to deal w/pthreads + Memcheck:Leak + fun:memalign + obj:/lib/ld-2.3.4.so + fun:_dl_allocate_tls + fun:__pthread_initialize_minimal +} + ### ### These occur from somewhere within the SSL, when running ### test_socket_sll. They are too general to leave on by default. From birkenfeld at users.sourceforge.net Mon Oct 3 16:16:47 2005 From: birkenfeld at users.sourceforge.net (birkenfeld@users.sourceforge.net) Date: Mon, 3 Oct 2005 16:16:47 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1385,1.1386 Message-ID: <20051003141647.D44371E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11970/Misc Modified Files: NEWS Log Message: Patch #754022: Greatly enhanced webbrowser.py. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1385 retrieving revision 1.1386 diff -u -d -r1.1385 -r1.1386 --- NEWS 3 Oct 2005 04:48:14 -0000 1.1385 +++ NEWS 3 Oct 2005 14:16:44 -0000 1.1386 @@ -254,6 +254,8 @@ Library ------- +- Patch #754022: Greatly enhanced webbrowser.py (by Oleg Broytmann). + - Bug #729103: pydoc.py: Fix docother() method to accept additional "parent" argument. From birkenfeld at users.sourceforge.net Mon Oct 3 16:16:48 2005 From: birkenfeld at users.sourceforge.net (birkenfeld@users.sourceforge.net) Date: Mon, 3 Oct 2005 16:16:48 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/lib libwebbrowser.tex, 1.10, 1.11 Message-ID: <20051003141648.14A361E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11970/Doc/lib Modified Files: libwebbrowser.tex Log Message: Patch #754022: Greatly enhanced webbrowser.py. Index: libwebbrowser.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libwebbrowser.tex,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- libwebbrowser.tex 19 Jul 2001 03:49:33 -0000 1.10 +++ libwebbrowser.tex 3 Oct 2005 14:16:44 -0000 1.11 @@ -6,9 +6,8 @@ \moduleauthor{Fred L. Drake, Jr.}{fdrake at acm.org} \sectionauthor{Fred L. Drake, Jr.}{fdrake at acm.org} -The \module{webbrowser} module provides a very high-level interface to -allow displaying Web-based documents to users. The controller objects -are easy to use and are platform-independent. Under most +The \module{webbrowser} module provides a high-level interface to +allow displaying Web-based documents to users. Under most circumstances, simply calling the \function{open()} function from this module will do the right thing. @@ -17,19 +16,26 @@ display isn't available. If text-mode browsers are used, the calling process will block until the user exits the browser. -Under \UNIX, if the environment variable \envvar{BROWSER} exists, it +If the environment variable \envvar{BROWSER} exists, it is interpreted to override the platform default list of browsers, as a -colon-separated list of browsers to try in order. When the value of +os.pathsep-separated list of browsers to try in order. When the value of a list part contains the string \code{\%s}, then it is interpreted as a literal browser command line to be used with the argument URL substituted for the \code{\%s}; if the part does not contain \code{\%s}, it is simply interpreted as the name of the browser to launch. -For non-\UNIX{} platforms, or when X11 browsers are available on +For non-\UNIX{} platforms, or when a remote browser is available on \UNIX, the controlling process will not wait for the user to finish -with the browser, but allow the browser to maintain its own window on -the display. +with the browser, but allow the remote browser to maintain its own +windows on the display. If remote browsers are not available on \UNIX, +the controlling process will launch a new browser and wait. + +The script \program{webbrowser} can be used as a command-line interface +for the module. It accepts an URL as the argument. It accepts the following +optional parameters: \programopt{-n} opens the URL in a new browser window, +if possible; \programopt{-t} opens the URL in a new browser page ("tab"). The +options are, naturally, mutually exclusive. The following exception is defined: @@ -40,15 +46,24 @@ The following functions are defined: \begin{funcdesc}{open}{url\optional{, new=0}\optional{, autoraise=1}} - Display \var{url} using the default browser. If \var{new} is true, - a new browser window is opened if possible. If \var{autoraise} is + Display \var{url} using the default browser. If \var{new} is 0, the + \var{url} is opened in the same browser window. If \var{new} is 1, + a new browser window is opened if possible. If \var{new} is 2, + a new browser page ("tab") is opened if possible. If \var{autoraise} is true, the window is raised if possible (note that under many window managers this will occur regardless of the setting of this variable). + \end{funcdesc} -\begin{funcdesc}{open_new}{url} +\begin{funcdesc}{open_new_win}{url} Open \var{url} in a new window of the default browser, if possible, - otherwise, open \var{url} in the only browser window. + otherwise, open \var{url} in the only browser window. Alias + \function{open_new}. +\end{funcdesc} + +\begin{funcdesc}{open_new_tab}{url} + Open \var{url} in a new page ("tab") of the default browser, if possible, + otherwise equivalent to \function{open_new_win}. \end{funcdesc} \begin{funcdesc}{get}{\optional{name}} @@ -67,7 +82,7 @@ This entry point is only useful if you plan to either set the \envvar{BROWSER} variable or call \function{get} with a nonempty - argument matching the name of a handler you declare. + argument matching the name of a handler you declare. \end{funcdesc} A number of browser types are predefined. This table gives the type @@ -76,16 +91,24 @@ in this module. \begin{tableiii}{l|l|c}{code}{Type Name}{Class Name}{Notes} - \lineiii{'mozilla'}{\class{Netscape('mozilla')}}{} - \lineiii{'netscape'}{\class{Netscape('netscape')}}{} - \lineiii{'mosaic'}{\class{GenericBrowser('mosaic \%s \&')}}{} + \lineiii{'mozilla'}{\class{Mozilla('mozilla')}}{} + \lineiii{'firefox'}{\class{Mozilla('mozilla')}}{} + \lineiii{'netscape'}{\class{Mozilla('netscape')}}{} + \lineiii{'galeon'}{\class{Galeon('galeon')}}{} + \lineiii{'epiphany'}{\class{Galeon('epiphany')}}{} + \lineiii{'skipstone'}{\class{GenericBrowser('skipstone \%s \&')}}{} + \lineiii{'konqueror'}{\class{Konqueror()}}{(1)} \lineiii{'kfm'}{\class{Konqueror()}}{(1)} + \lineiii{'mosaic'}{\class{GenericBrowser('mosaic \%s \&')}}{} + \lineiii{'opera'}{\class{Opera()}}{} \lineiii{'grail'}{\class{Grail()}}{} \lineiii{'links'}{\class{GenericBrowser('links \%s')}}{} + \lineiii{'elinks'}{\class{Elinks('elinks')}}{} \lineiii{'lynx'}{\class{GenericBrowser('lynx \%s')}}{} \lineiii{'w3m'}{\class{GenericBrowser('w3m \%s')}}{} \lineiii{'windows-default'}{\class{WindowsDefault}}{(2)} \lineiii{'internet-config'}{\class{InternetConfig}}{(3)} + \lineiii{'macosx'}{\class{MacOSX('default')}}{(4)} \end{tableiii} \noindent @@ -101,13 +124,15 @@ implementation selects the best strategy for running Konqueror. \item[(2)] -Only on Windows platforms; requires the common -extension modules \module{win32api} and \module{win32con}. +Only on Windows platforms. \item[(3)] Only on MacOS platforms; requires the standard MacPython \module{ic} module, described in the \citetitle[../mac/module-ic.html]{Macintosh Library Modules} manual. + +\item[(4)] +Only on MacOS X platform. \end{description} @@ -117,12 +142,18 @@ module-level convenience functions: \begin{funcdesc}{open}{url\optional{, new}} - Display \var{url} using the browser handled by this controller. If - \var{new} is true, a new browser window is opened if possible. + Display \var{url} using the browser handled by this controller. + If \var{new} is 1, a new browser window is opened if possible. + If \var{new} is 2, a new browser page ("tab") is opened if possible. \end{funcdesc} -\begin{funcdesc}{open_new}{url} +\begin{funcdesc}{open_new_win}{url} Open \var{url} in a new window of the browser handled by this controller, if possible, otherwise, open \var{url} in the only - browser window. + browser window. Alias \function{open_new}. +\end{funcdesc} + +\begin{funcdesc}{open_new_tab}{url} + Open \var{url} in a new page ("tab") of the browser handled by this + controller, if possible, otherwise equivalent to \function{open_new_win}. \end{funcdesc} From birkenfeld at users.sourceforge.net Mon Oct 3 16:16:48 2005 From: birkenfeld at users.sourceforge.net (birkenfeld@users.sourceforge.net) Date: Mon, 3 Oct 2005 16:16:48 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib webbrowser.py,1.37,1.38 Message-ID: <20051003141648.73D231E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11970/Lib Modified Files: webbrowser.py Log Message: Patch #754022: Greatly enhanced webbrowser.py. Index: webbrowser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/webbrowser.py,v retrieving revision 1.37 retrieving revision 1.38 diff -u -d -r1.37 -r1.38 --- webbrowser.py 10 Jul 2004 22:07:02 -0000 1.37 +++ webbrowser.py 3 Oct 2005 14:16:44 -0000 1.38 @@ -1,9 +1,11 @@ +#! /usr/bin/env python """Interfaces for launching and remotely controlling Web browsers.""" import os import sys +import stat -__all__ = ["Error", "open", "get", "register"] +__all__ = ["Error", "open", "open_new", "open_new_tab", "get", "register"] class Error(Exception): pass @@ -11,9 +13,13 @@ _browsers = {} # Dictionary of available browser controllers _tryorder = [] # Preference order of available browsers -def register(name, klass, instance=None): +def register(name, klass, instance=None, update_tryorder=1): """Register a browser connector and, optionally, connection.""" _browsers[name.lower()] = [klass, instance] + if update_tryorder > 0: + _tryorder.append(name) + elif update_tryorder < 0: + _tryorder.insert(0, name) def get(using=None): """Return a browser launcher instance appropriate for the environment.""" @@ -26,27 +32,36 @@ # User gave us a command line, don't mess with it. return GenericBrowser(browser) else: - # User gave us a browser name. + # User gave us a browser name or path. try: command = _browsers[browser.lower()] except KeyError: command = _synthesize(browser) - if command[1] is None: - return command[0]() - else: + if command[1] is not None: return command[1] + elif command[0] is not None: + return command[0]() raise Error("could not locate runnable browser") # Please note: the following definition hides a builtin function. +# It is recommended one does "import webbrowser" and uses webbrowser.open(url) +# instead of "from webbrowser import *". def open(url, new=0, autoraise=1): - get().open(url, new, autoraise) + for name in _tryorder: + browser = get(name) + if browser.open(url, new, autoraise): + return True + return False def open_new(url): - get().open(url, 1) + return open(url, 1) +def open_new_tab(url): + return open(url, 2) -def _synthesize(browser): + +def _synthesize(browser, update_tryorder=1): """Attempt to synthesize a controller base on existing controllers. This is useful to create a controller when a user specifies a path to @@ -58,9 +73,10 @@ executable for the requested browser, return [None, None]. """ - if not os.path.exists(browser): + cmd = browser.split()[0] + if not _iscommand(cmd): return [None, None] - name = os.path.basename(browser) + name = os.path.basename(cmd) try: command = _browsers[name.lower()] except KeyError: @@ -72,132 +88,199 @@ controller = copy.copy(controller) controller.name = browser controller.basename = os.path.basename(browser) - register(browser, None, controller) + register(browser, None, controller, update_tryorder) return [None, controller] return [None, None] +if sys.platform[:3] == "win": + def _isexecutable(cmd): + cmd = cmd.lower() + if os.path.isfile(cmd) and (cmd.endswith(".exe") or + cmd.endswith(".bat")): + return True + for ext in ".exe", ".bat": + if os.path.isfile(cmd + ext): + return True + return False +else: + def _isexecutable(cmd): + if os.path.isfile(cmd): + mode = os.stat(cmd)[stat.ST_MODE] + if mode & stat.S_IXUSR or mode & stat.S_IXGRP or mode & stat.S_IXOTH: + return True + return False + def _iscommand(cmd): - """Return True if cmd can be found on the executable search path.""" + """Return True if cmd is executable or can be found on the executable + search path.""" + if _isexecutable(cmd): + return True path = os.environ.get("PATH") if not path: return False for d in path.split(os.pathsep): exe = os.path.join(d, cmd) - if os.path.isfile(exe): + if _isexecutable(exe): return True return False -PROCESS_CREATION_DELAY = 4 +# General parent classes + +class BaseBrowser(object): + """Parent class for all browsers.""" + def __init__(self, name=""): + self.name = name + + def open_new(self, url): + return self.open(url, 1) + + def open_new_tab(self, url): + return self.open(url, 2) + + +class GenericBrowser(BaseBrowser): + """Class for all browsers started with a command + and without remote functionality.""" -class GenericBrowser: def __init__(self, cmd): self.name, self.args = cmd.split(None, 1) - self.basename = os.path.basename(self.name) def open(self, url, new=0, autoraise=1): assert "'" not in url command = "%s %s" % (self.name, self.args) - os.system(command % url) + rc = os.system(command % url) + return not rc - def open_new(self, url): - self.open(url) +class UnixBrowser(BaseBrowser): + """Parent class for all Unix browsers with remote functionality.""" -class Netscape: - "Launcher class for Netscape browsers." - def __init__(self, name): - self.name = name - self.basename = os.path.basename(name) + raise_opts = None - def _remote(self, action, autoraise): - raise_opt = ("-noraise", "-raise")[autoraise] - cmd = "%s %s -remote '%s' >/dev/null 2>&1" % (self.name, - raise_opt, - action) + remote_cmd = '' + remote_action = None + remote_action_newwin = None + remote_action_newtab = None + remote_background = False + + def _remote(self, url, action, autoraise): + autoraise = int(bool(autoraise)) # always 0/1 + raise_opt = self.raise_opts and self.raise_opts[autoraise] or '' + cmd = "%s %s %s '%s' >/dev/null 2>&1" % (self.name, raise_opt, + self.remote_cmd, action) + if remote_background: + cmd += ' &' rc = os.system(cmd) if rc: - import time - os.system("%s &" % self.name) - time.sleep(PROCESS_CREATION_DELAY) - rc = os.system(cmd) + # bad return status, try again with simpler command + rc = os.system("%s %s" % (self.name, url)) return not rc def open(self, url, new=0, autoraise=1): - if new: - self._remote("openURL(%s, new-window)"%url, autoraise) + assert "'" not in url + if new == 0: + action = self.remote_action + elif new == 1: + action = self.remote_action_newwin + elif new == 2: + if self.remote_action_newtab is None: + action = self.remote_action_newwin + else: + action = self.remote_action_newtab else: - self._remote("openURL(%s)" % url, autoraise) + raise Error("Bad 'new' parameter to open(); expected 0, 1, or 2, got %s" % new) + return self._remote(url, action % url, autoraise) - def open_new(self, url): - self.open(url, 1) +class Mozilla(UnixBrowser): + """Launcher class for Mozilla/Netscape browsers.""" -class Galeon: - """Launcher class for Galeon browsers.""" - def __init__(self, name): - self.name = name - self.basename = os.path.basename(name) + raise_opts = ("-noraise", "-raise") - def _remote(self, action, autoraise): - raise_opt = ("--noraise", "")[autoraise] - cmd = "%s %s %s >/dev/null 2>&1" % (self.name, raise_opt, action) - rc = os.system(cmd) - if rc: - import time - os.system("%s >/dev/null 2>&1 &" % self.name) - time.sleep(PROCESS_CREATION_DELAY) - rc = os.system(cmd) - return not rc + remote_cmd = '-remote' + remote_action = "openURL(%s)" + remote_action_newwin = "openURL(%s,new-window)" + remote_action_newtab = "openURL(%s,new-tab)" - def open(self, url, new=0, autoraise=1): - if new: - self._remote("-w '%s'" % url, autoraise) - else: - self._remote("-n '%s'" % url, autoraise) +Netscape = Mozilla - def open_new(self, url): - self.open(url, 1) +class Galeon(UnixBrowser): + """Launcher class for Galeon/Epiphany browsers.""" -class Konqueror: + raise_opts = ("-noraise", "") + remote_action = "-n '%s'" + remote_action_newwin = "-w '%s'" + + remote_background = True + + +class Konqueror(BaseBrowser): """Controller for the KDE File Manager (kfm, or Konqueror). See http://developer.kde.org/documentation/other/kfmclient.html for more information on the Konqueror remote-control interface. """ - def __init__(self): - if _iscommand("konqueror"): - self.name = self.basename = "konqueror" - else: - self.name = self.basename = "kfm" - def _remote(self, action): + def _remote(self, url, action): + # kfmclient is the new KDE way of opening URLs. cmd = "kfmclient %s >/dev/null 2>&1" % action rc = os.system(cmd) + # Fall back to other variants. if rc: - import time - if self.basename == "konqueror": - os.system(self.name + " --silent &") - else: - os.system(self.name + " -d &") - time.sleep(PROCESS_CREATION_DELAY) - rc = os.system(cmd) + if _iscommand("konqueror"): + rc = os.system(self.name + " --silent '%s' &" % url) + elif _iscommand("kfm"): + rc = os.system(self.name + " -d '%s'" % url) return not rc - def open(self, url, new=1, autoraise=1): + def open(self, url, new=0, autoraise=1): # XXX Currently I know no way to prevent KFM from # opening a new win. assert "'" not in url - self._remote("openURL '%s'" % url) + if new == 2: + action = "newTab '%s'" % url + else: + action = "openURL '%s'" % url + ok = self._remote(url, action) + return ok - open_new = open +class Opera(UnixBrowser): + "Launcher class for Opera browser." -class Grail: + raise_opts = ("", "-raise") + + remote_cmd = '-remote' + remote_action = "openURL(%s)" + remote_action_newwin = "openURL(%s,new-window)" + remote_action_newtab = "openURL(%s,new-page)" + + +class Elinks(UnixBrowser): + "Launcher class for Elinks browsers." + + remote_cmd = '-remote' + remote_action = "openURL(%s)" + remote_action_newwin = "openURL(%s,new-window)" + remote_action_newtab = "openURL(%s,new-tab)" + + def _remote(self, url, action, autoraise): + # elinks doesn't like its stdout to be redirected - + # it uses redirected stdout as a signal to do -dump + cmd = "%s %s '%s' 2>/dev/null" % (self.name, + self.remote_cmd, action) + rc = os.system(cmd) + if rc: + rc = os.system("%s %s" % (self.name, url)) + return not rc + + +class Grail(BaseBrowser): # There should be a way to maintain a connection to Grail, but the # Grail remote control protocol doesn't really allow that at this # point. It probably neverwill! @@ -237,93 +320,97 @@ def open(self, url, new=0, autoraise=1): if new: - self._remote("LOADNEW " + url) + ok = self._remote("LOADNEW " + url) else: - self._remote("LOAD " + url) - - def open_new(self, url): - self.open(url, 1) - - -class WindowsDefault: - def open(self, url, new=0, autoraise=1): - os.startfile(url) + ok = self._remote("LOAD " + url) + return ok - def open_new(self, url): - self.open(url) # # Platform support for Unix # -# This is the right test because all these Unix browsers require either -# a console terminal of an X display to run. Note that we cannot split -# the TERM and DISPLAY cases, because we might be running Python from inside -# an xterm. -if os.environ.get("TERM") or os.environ.get("DISPLAY"): - _tryorder = ["links", "lynx", "w3m"] - - # Easy cases first -- register console browsers if we have them. - if os.environ.get("TERM"): - # The Links browser - if _iscommand("links"): - register("links", None, GenericBrowser("links '%s'")) - # The Lynx browser - if _iscommand("lynx"): - register("lynx", None, GenericBrowser("lynx '%s'")) - # The w3m browser - if _iscommand("w3m"): - register("w3m", None, GenericBrowser("w3m '%s'")) +# These are the right tests because all these Unix browsers require either +# a console terminal or an X display to run. - # X browsers have more in the way of options - if os.environ.get("DISPLAY"): - _tryorder = ["galeon", "skipstone", - "mozilla-firefox", "mozilla-firebird", "mozilla", "netscape", - "kfm", "grail"] + _tryorder +# Prefer X browsers if present +if os.environ.get("DISPLAY"): - # First, the Netscape series - for browser in ("mozilla-firefox", "mozilla-firebird", - "mozilla", "netscape"): - if _iscommand(browser): - register(browser, None, Netscape(browser)) + # First, the Mozilla/Netscape browsers + for browser in ("mozilla-firefox", "firefox", + "mozilla-firebird", "firebird", + "mozilla", "netscape"): + if _iscommand(browser): + register(browser, None, Mozilla(browser)) - # Next, Mosaic -- old but still in use. - if _iscommand("mosaic"): - register("mosaic", None, GenericBrowser( - "mosaic '%s' >/dev/null &")) + # The default Gnome browser + if _iscommand("gconftool-2"): + # get the web browser string from gconftool + gc = 'gconftool-2 -g /desktop/gnome/url-handlers/http/command' + out = os.popen(gc) + commd = out.read().strip() + retncode = out.close() - # Gnome's Galeon - if _iscommand("galeon"): - register("galeon", None, Galeon("galeon")) + # if successful, register it + if retncode == None and len(commd) != 0: + register("gnome", None, GenericBrowser( + commd + " '%s' >/dev/null &")) - # Skipstone, another Gtk/Mozilla based browser - if _iscommand("skipstone"): - register("skipstone", None, GenericBrowser( - "skipstone '%s' >/dev/null &")) + # Konqueror/kfm, the KDE browser. + if _iscommand("kfm") or _iscommand("konqueror"): + register("kfm", Konqueror, Konqueror()) - # Konqueror/kfm, the KDE browser. - if _iscommand("kfm") or _iscommand("konqueror"): - register("kfm", Konqueror, Konqueror()) + # Gnome's Galeon and Epiphany + for browser in ("galeon", "epiphany"): + if _iscommand(browser): + register(browser, None, Galeon(browser)) - # Grail, the Python browser. - if _iscommand("grail"): - register("grail", Grail, None) + # Skipstone, another Gtk/Mozilla based browser + if _iscommand("skipstone"): + register("skipstone", None, GenericBrowser("skipstone '%s' &")) + # Opera, quite popular + if _iscommand("opera"): + register("opera", None, Opera("opera")) -class InternetConfig: - def open(self, url, new=0, autoraise=1): - ic.launchurl(url) + # Next, Mosaic -- old but still in use. + if _iscommand("mosaic"): + register("mosaic", None, GenericBrowser("mosaic '%s' &")) - def open_new(self, url): - self.open(url) + # Grail, the Python browser. Does anybody still use it? + if _iscommand("grail"): + register("grail", Grail, None) +# Also try console browsers +if os.environ.get("TERM"): + # The Links/elinks browsers + if _iscommand("links"): + register("links", None, GenericBrowser("links '%s'")) + if _iscommand("elinks"): + register("elinks", None, Elinks("elinks")) + # The Lynx browser , + if _iscommand("lynx"): + register("lynx", None, GenericBrowser("lynx '%s'")) + # The w3m browser + if _iscommand("w3m"): + register("w3m", None, GenericBrowser("w3m '%s'")) # # Platform support for Windows # if sys.platform[:3] == "win": - _tryorder = ["netscape", "windows-default"] + class WindowsDefault(BaseBrowser): + def open(self, url, new=0, autoraise=1): + os.startfile(url) + return True # Oh, my... + + _tryorder = [] + _browsers = {} + # Prefer mozilla/netscape/opera if present + for browser in ("firefox", "firebird", "mozilla", "netscape", "opera"): + if _iscommand(browser): + register(browser, None, GenericBrowser(browser + ' %s')) register("windows-default", WindowsDefault) # @@ -335,36 +422,112 @@ except ImportError: pass else: - # internet-config is the only supported controller on MacOS, - # so don't mess with the default! - _tryorder = ["internet-config"] - register("internet-config", InternetConfig) + class InternetConfig(BaseBrowser): + def open(self, url, new=0, autoraise=1): + ic.launchurl(url) + return True # Any way to get status? + + register("internet-config", InternetConfig, update_tryorder=-1) + +if sys.platform == 'darwin': + # Adapted from patch submitted to SourceForge by Steven J. Burr + class MacOSX(BaseBrowser): + """Launcher class for Aqua browsers on Mac OS X + + Optionally specify a browser name on instantiation. Note that this + will not work for Aqua browsers if the user has moved the application + package after installation. + + If no browser is specified, the default browser, as specified in the + Internet System Preferences panel, will be used. + """ + def __init__(self, name): + self.name = name + + def open(self, url, new=0, autoraise=1): + assert "'" not in url + # new must be 0 or 1 + new = int(bool(new)) + if self.name == "default": + # User called open, open_new or get without a browser parameter + script = _safequote('open location "%s"', url) # opens in default browser + else: + # User called get and chose a browser + if self.name == "OmniWeb": + toWindow = "" + else: + # Include toWindow parameter of OpenURL command for browsers + # that support it. 0 == new window; -1 == existing + toWindow = "toWindow %d" % (new - 1) + cmd = _safequote('OpenURL "%s"', url) + script = '''tell application "%s" + activate + %s %s + end tell''' % (self.name, cmd, toWindow) + # Open pipe to AppleScript through osascript command + osapipe = os.popen("osascript", "w") + if osapipe is None: + return False + # Write script to osascript's stdin + osapipe.write(script) + rc = osapipe.close() + return not rc + + # Don't clear _tryorder or _browsers since OS X can use above Unix support + # (but we prefer using the OS X specific stuff) + register("MacOSX", None, MacOSX('default'), -1) + # # Platform support for OS/2 # -if sys.platform[:3] == "os2" and _iscommand("netscape.exe"): - _tryorder = ["os2netscape"] +if sys.platform[:3] == "os2" and _iscommand("netscape"): + _tryorder = [] + _browsers = {} register("os2netscape", None, - GenericBrowser("start netscape.exe %s")) + GenericBrowser("start netscape %s"), -1) + # OK, now that we know what the default preference orders for each # platform are, allow user to override them with the BROWSER variable. -# if "BROWSER" in os.environ: - # It's the user's responsibility to register handlers for any unknown - # browser referenced by this value, before calling open(). - _tryorder = os.environ["BROWSER"].split(os.pathsep) + _userchoices = os.environ["BROWSER"].split(os.pathsep) + _userchoices.reverse() -for cmd in _tryorder: - if not cmd.lower() in _browsers: - if _iscommand(cmd.lower()): - register(cmd.lower(), None, GenericBrowser( - "%s '%%s'" % cmd.lower())) -cmd = None # to make del work if _tryorder was empty -del cmd + # Treat choices in same way as if passed into get() but do register + # and prepend to _tryorder + for cmdline in _userchoices: + if cmdline != '': + _synthesize(cmdline, -1) + cmdline = None # to make del work if _userchoices was empty + del cmdline + del _userchoices -_tryorder = filter(lambda x: x.lower() in _browsers - or x.find("%s") > -1, _tryorder) # what to do if _tryorder is now empty? + + +def main(): + import getopt + usage = """Usage: %s [-n | -t] url + -n: open new window + -t: open new tab""" % sys.argv[0] + try: + opts, args = getopt.getopt(sys.argv[1:], 'ntd') + except getopt.error, msg: + print >>sys.stderr, msg + print >>sys.stderr, usage + sys.exit(1) + new_win = 0 + for o, a in opts: + if o == '-n': new_win = 1 + elif o == '-t': new_win = 2 + if len(args) <> 1: + print >>sys.stderr, usage + sys.exit(1) + + url = args[0] + open(url, new_win) + +if __name__ == "__main__": + main() From fdrake at users.sourceforge.net Mon Oct 3 16:25:44 2005 From: fdrake at users.sourceforge.net (fdrake@users.sourceforge.net) Date: Mon, 3 Oct 2005 16:25:44 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/lib libstdtypes.tex, 1.185, 1.186 Message-ID: <20051003142544.A759D1E4010@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14325/lib Modified Files: libstdtypes.tex Log Message: fix link to subsection (SF bug #1311674) Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.185 retrieving revision 1.186 diff -u -d -r1.185 -r1.186 --- libstdtypes.tex 18 Aug 2005 21:27:11 -0000 1.185 +++ libstdtypes.tex 3 Oct 2005 14:25:40 -0000 1.186 @@ -1295,8 +1295,10 @@ \module{sets} module. \begin{seealso} - \seemodule[comparison-to-builtin-set]{sets}{Differences between - the \module{sets} module and the built-in set types.} + \seelink{comparison-to-builtin-set.html} + {Comparison to the built-in set types} + {Differences between the \module{sets} module and the + built-in set types.} \end{seealso} From fdrake at users.sourceforge.net Mon Oct 3 16:27:08 2005 From: fdrake at users.sourceforge.net (fdrake@users.sourceforge.net) Date: Mon, 3 Oct 2005 16:27:08 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/lib libstdtypes.tex, 1.170.2.13, 1.170.2.14 Message-ID: <20051003142708.43E941E400A@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14629/lib Modified Files: Tag: release24-maint libstdtypes.tex Log Message: fix link to subsection (SF bug #1311674) Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.170.2.13 retrieving revision 1.170.2.14 diff -u -d -r1.170.2.13 -r1.170.2.14 --- libstdtypes.tex 4 Jul 2005 14:18:20 -0000 1.170.2.13 +++ libstdtypes.tex 3 Oct 2005 14:27:04 -0000 1.170.2.14 @@ -1295,8 +1295,10 @@ \module{sets} module. \begin{seealso} - \seemodule[comparison-to-builtin-set]{sets}{Differences between - the \module{sets} module and the built-in set types.} + \seelink{comparison-to-builtin-set.html} + {Comparison to the built-in set types} + {Differences between the \module{sets} module and the + built-in set types.} \end{seealso} From rhettinger at users.sourceforge.net Mon Oct 3 18:39:56 2005 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 3 Oct 2005 18:39:56 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/ref ref6.tex,1.77,1.78 Message-ID: <20051003163956.8AB021E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/ref In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14427 Modified Files: ref6.tex Log Message: Correct docs for empty raise when no exception is active. Index: ref6.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref6.tex,v retrieving revision 1.77 retrieving revision 1.78 diff -u -d -r1.77 -r1.78 --- ref6.tex 7 Sep 2005 05:17:07 -0000 1.77 +++ ref6.tex 3 Oct 2005 16:39:51 -0000 1.78 @@ -524,8 +524,9 @@ 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 scope, a \exception{Queue.Empty} exception is -raised indicating this error. +active in the current scope, a \exception{TypeError} exception is +raised indicating that this is an error (if running under IDLE, a +\exception{Queue.Empty} exception is raised instead}. \index{exception} \indexii{raising}{exception} From rhettinger at users.sourceforge.net Mon Oct 3 18:40:39 2005 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 3 Oct 2005 18:40:39 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/ref ref6.tex, 1.73.2.4, 1.73.2.5 Message-ID: <20051003164039.923BE1E4119@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/ref In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14619 Modified Files: Tag: release24-maint ref6.tex Log Message: Correct docs for empty raise when no exception is active. Index: ref6.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref6.tex,v retrieving revision 1.73.2.4 retrieving revision 1.73.2.5 diff -u -d -r1.73.2.4 -r1.73.2.5 --- ref6.tex 7 Sep 2005 05:18:06 -0000 1.73.2.4 +++ ref6.tex 3 Oct 2005 16:40:36 -0000 1.73.2.5 @@ -524,8 +524,9 @@ 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 scope, a \exception{Queue.Empty} exception is -raised indicating this error. +active in the current scope, a \exception{TypeError} exception is +raised indicating that this is an error (if running under IDLE, a +\exception{Queue.Empty} exception is raised instead}. \index{exception} \indexii{raising}{exception} From kbk at users.sourceforge.net Mon Oct 3 21:26:07 2005 From: kbk at users.sourceforge.net (kbk@users.sourceforge.net) Date: Mon, 3 Oct 2005 21:26:07 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib/idlelib CodeContext.py, 1.5, 1.6 Message-ID: <20051003192607.7D5451E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib/idlelib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29701 Modified Files: CodeContext.py Log Message: Tweak CodeContext.py docstrings, comments, and names. Index: CodeContext.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/idlelib/CodeContext.py,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- CodeContext.py 2 Oct 2005 23:36:46 -0000 1.5 +++ CodeContext.py 3 Oct 2005 19:26:03 -0000 1.6 @@ -1,13 +1,12 @@ -"""CodeContext - Display the block context of code at top of edit window +"""CodeContext - Extension to display the block context above the edit window -Once code has scrolled off the top of the screen, it can be difficult -to determine which block you are in. This extension implements a pane -at the top of each IDLE edit window which provides block structure -hints. These hints are the lines which contain the block opening -keywords, e.g. 'if', for the enclosing block. The number of hint lines -is determined by the numlines variable in the CodeContext section of -config-extensions.def. Lines which do not open blocks are not shown in -the context hints pane. +Once code has scrolled off the top of a window, it can be difficult to +determine which block you are in. This extension implements a pane at the top +of each IDLE edit window which provides block structure hints. These hints are +the lines which contain the block opening keywords, e.g. 'if', for the +enclosing block. The number of hint lines is determined by the numlines +variable in the CodeContext section of config-extensions.def. Lines which do +not open blocks are not shown in the context hints pane. """ import Tkinter @@ -21,13 +20,14 @@ UPDATEINTERVAL = 100 # millisec FONTUPDATEINTERVAL = 1000 # millisec -getspacesfirstword = lambda s, c=re.compile(r"^(\s*)(\w*)"): c.match(s).groups() +getspacesfirstword =\ + lambda s, c=re.compile(r"^(\s*)(\w*)"): c.match(s).groups() class CodeContext: menudefs = [('options', [('!Code Conte_xt', '<>')])] - numlines = idleConf.GetOption("extensions", "CodeContext", - "numlines", type="int", default=3) + context_depth = idleConf.GetOption("extensions", "CodeContext", + "numlines", type="int", default=3) bgcolor = idleConf.GetOption("extensions", "CodeContext", "bgcolor", type="str", default="LightGray") fgcolor = idleConf.GetOption("extensions", "CodeContext", @@ -37,13 +37,13 @@ self.text = editwin.text self.textfont = self.text["font"] self.label = None - # self.info holds information about the context lines of line number - # self.lastfirstline. The information is a tuple of the line's - # indentation, the line's text and the keyword at the beginning of the - # line, as returned by get_line_info. At the beginning of the list - # there's a dummy line, which starts the "block" of the whole document. + # self.info is a list of (line number, indent level, line text, block + # keyword) tuples providing the block structure associated with + # self.topvisible (the linenumber of the line displayed at the top of + # the edit window). self.info[0] is initialized as a 'dummy' line which + # starts the toplevel 'block' of the module. self.info = [(0, -1, "", False)] - self.lastfirstline = 1 + self.topvisible = 1 visible = idleConf.GetOption("extensions", "CodeContext", "visible", type="bool", default=False) if visible: @@ -56,7 +56,7 @@ def toggle_code_context_event(self, event=None): if not self.label: self.label = Tkinter.Label(self.editwin.top, - text="\n" * (self.numlines - 1), + text="\n" * (self.context_depth - 1), anchor="w", justify="left", font=self.textfont, bg=self.bgcolor, fg=self.fgcolor, @@ -77,6 +77,7 @@ If the line does not start a block, the keyword value is False. The indentation of empty lines (or comment lines) is INFINITY. + """ text = self.text.get("%d.0" % linenum, "%d.end" % linenum) spaces, firstword = getspacesfirstword(text) @@ -87,64 +88,69 @@ indent = len(spaces) return indent, text, opener - def interesting_lines(self, firstline, stopline=1, stopindent=0): - """ - Find the context lines, starting at firstline. - Will not return lines whose index is smaller than stopline or whose - indentation is smaller than stopindent. - stopline should always be >= 1, so the dummy block start will never - be returned (This function doesn't know what to do about it.) - Returns a list with the context lines, starting from the first (top), - and a number which all context lines above the inspected region should - have a smaller indentation than it. + def get_context(self, new_topvisible, stopline=1, stopindent=0): + """Get context lines, starting at new_topvisible and working backwards. + + Stop when stopline or stopindent is reached. Return a tuple of context + data and the indent level at the top of the region inspected. + """ + assert stopline > 0 lines = [] # The indentation level we are currently in: lastindent = INFINITY # For a line to be interesting, it must begin with a block opening # keyword, and have less indentation than lastindent. - for line_index in xrange(firstline, stopline-1, -1): - indent, text, opener = self.get_line_info(line_index) + for linenum in xrange(new_topvisible, stopline-1, -1): + indent, text, opener = self.get_line_info(linenum) if indent < lastindent: lastindent = indent if opener in ("else", "elif"): # We also show the if statement lastindent += 1 - if opener and line_index < firstline and indent >= stopindent: - lines.append((line_index, indent, text, opener)) + if opener and linenum < new_topvisible and indent >= stopindent: + lines.append((linenum, indent, text, opener)) if lastindent <= stopindent: break lines.reverse() return lines, lastindent - def update_label(self): - """Update the CodeContext label, if needed. + def update_code_context(self): + """Update context information and lines visible in the context pane. + """ - firstline = int(self.text.index("@0,0").split('.')[0]) - if self.lastfirstline == firstline: + new_topvisible = int(self.text.index("@0,0").split('.')[0]) + if self.topvisible == new_topvisible: # haven't scrolled return - if self.lastfirstline < firstline: - lines, lastindent = self.interesting_lines(firstline, - self.lastfirstline) + if self.topvisible < new_topvisible: # scroll down + lines, lastindent = self.get_context(new_topvisible, + self.topvisible) + # retain only context info applicable to the region + # between topvisible and new_topvisible: while self.info[-1][1] >= lastindent: del self.info[-1] - self.info.extend(lines) - else: + elif self.topvisible > new_topvisible: # scroll up stopindent = self.info[-1][1] + 1 - while self.info[-1][0] >= firstline: + # retain only context info associated + # with lines above new_topvisible: + while self.info[-1][0] >= new_topvisible: stopindent = self.info[-1][1] del self.info[-1] - lines, lastindent = self.interesting_lines( - firstline, self.info[-1][0]+1, stopindent) - self.info.extend(lines) - self.lastfirstline = firstline - lines = [""] * max(0, self.numlines - len(self.info)) + \ - [x[2] for x in self.info[-self.numlines:]] - self.label["text"] = '\n'.join(lines) + lines, lastindent = self.get_context(new_topvisible, + self.info[-1][0]+1, + stopindent) + self.info.extend(lines) + self.topvisible = new_topvisible + + # empty lines in context pane: + context_strings = [""] * max(0, self.context_depth - len(self.info)) + # followed by the context hint lines: + context_strings += [x[2] for x in self.info[-self.context_depth:]] + self.label["text"] = '\n'.join(context_strings) def timer_event(self): if self.label: - self.update_label() + self.update_code_context() self.text.after(UPDATEINTERVAL, self.timer_event) def font_timer_event(self): From kbk at users.sourceforge.net Mon Oct 3 22:08:28 2005 From: kbk at users.sourceforge.net (kbk@users.sourceforge.net) Date: Mon, 3 Oct 2005 22:08:28 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib/idlelib CodeContext.py, 1.6, 1.7 NEWS.txt, 1.63, 1.64 Message-ID: <20051003200828.C52491E402C@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib/idlelib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7668 Modified Files: CodeContext.py NEWS.txt Log Message: Incorporate Tal Einat's comment on Patch 936169: Fixes alignment problem. Index: CodeContext.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/idlelib/CodeContext.py,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- CodeContext.py 3 Oct 2005 19:26:03 -0000 1.6 +++ CodeContext.py 3 Oct 2005 20:08:25 -0000 1.7 @@ -55,18 +55,25 @@ def toggle_code_context_event(self, event=None): if not self.label: - self.label = Tkinter.Label(self.editwin.top, + self.pad_frame = Tkinter.Frame(self.editwin.top, + bg=self.bgcolor, border=2, + relief="sunken") + self.label = Tkinter.Label(self.pad_frame, text="\n" * (self.context_depth - 1), anchor="w", justify="left", font=self.textfont, bg=self.bgcolor, fg=self.fgcolor, - relief="sunken", + border=0, width=1, # Don't request more than we get ) - self.label.pack(side="top", fill="x", expand=0, - after=self.editwin.status_bar) + self.label.pack(side="top", fill="x", expand=True, + padx=4, pady=0) + self.pad_frame.pack(side="top", fill="x", expand=False, + padx=0, pady=0, + after=self.editwin.status_bar) else: self.label.destroy() + self.pad_frame.destroy() self.label = None idleConf.SetOption("extensions", "CodeContext", "visible", str(self.label is not None)) Index: NEWS.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/idlelib/NEWS.txt,v retrieving revision 1.63 retrieving revision 1.64 diff -u -d -r1.63 -r1.64 --- NEWS.txt 2 Oct 2005 23:36:46 -0000 1.63 +++ NEWS.txt 3 Oct 2005 20:08:25 -0000 1.64 @@ -3,6 +3,8 @@ *Release date: XX-XXX-2005* +- Fixed CodeContext alignment problem, following suggestion from Tal Einat. + - Increased performance in CodeContext extension Patch 936169 Noam Raphael - Mac line endings were incorrect when pasting code from some browsers From nnorwitz at users.sourceforge.net Tue Oct 4 05:17:53 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Tue, 4 Oct 2005 05:17:53 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib webbrowser.py,1.38,1.39 Message-ID: <20051004031753.46F671E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2904/Lib Modified Files: webbrowser.py Log Message: Fix pychecker warnings Index: webbrowser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/webbrowser.py,v retrieving revision 1.38 retrieving revision 1.39 diff -u -d -r1.38 -r1.39 --- webbrowser.py 3 Oct 2005 14:16:44 -0000 1.38 +++ webbrowser.py 4 Oct 2005 03:17:49 -0000 1.39 @@ -134,6 +134,9 @@ def __init__(self, name=""): self.name = name + def open(self, url, new=0, autoraise=1): + raise NotImplementedError + def open_new(self, url): return self.open(url, 1) @@ -171,7 +174,7 @@ raise_opt = self.raise_opts and self.raise_opts[autoraise] or '' cmd = "%s %s %s '%s' >/dev/null 2>&1" % (self.name, raise_opt, self.remote_cmd, action) - if remote_background: + if self.remote_background: cmd += ' &' rc = os.system(cmd) if rc: @@ -333,9 +336,7 @@ # These are the right tests because all these Unix browsers require either # a console terminal or an X display to run. -# Prefer X browsers if present -if os.environ.get("DISPLAY"): - +def register_X_browsers(): # First, the Mozilla/Netscape browsers for browser in ("mozilla-firefox", "firefox", "mozilla-firebird", "firebird", @@ -381,6 +382,10 @@ if _iscommand("grail"): register("grail", Grail, None) +# Prefer X browsers if present +if os.environ.get("DISPLAY"): + register_X_browsers() + # Also try console browsers if os.environ.get("TERM"): # The Links/elinks browsers From nnorwitz at users.sourceforge.net Tue Oct 4 05:31:05 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Tue, 4 Oct 2005 05:31:05 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/lib libwebbrowser.tex, 1.11, 1.12 Message-ID: <20051004033105.295A31E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4770/lib Modified Files: libwebbrowser.tex Log Message: open_new_win does not exist. use UNIX consistently, add autoraise parameter to open(). add versionadded tags to open_new_tab Index: libwebbrowser.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libwebbrowser.tex,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- libwebbrowser.tex 3 Oct 2005 14:16:44 -0000 1.11 +++ libwebbrowser.tex 4 Oct 2005 03:31:01 -0000 1.12 @@ -11,7 +11,7 @@ circumstances, simply calling the \function{open()} function from this module will do the right thing. -Under \UNIX, graphical browsers are preferred under X11, but text-mode +Under \UNIX{}, graphical browsers are preferred under X11, but text-mode browsers will be used if graphical browsers are not available or an X11 display isn't available. If text-mode browsers are used, the calling process will block until the user exits the browser. @@ -26,9 +26,9 @@ launch. For non-\UNIX{} platforms, or when a remote browser is available on -\UNIX, the controlling process will not wait for the user to finish +\UNIX{}, the controlling process will not wait for the user to finish with the browser, but allow the remote browser to maintain its own -windows on the display. If remote browsers are not available on \UNIX, +windows on the display. If remote browsers are not available on \UNIX{}, the controlling process will launch a new browser and wait. The script \program{webbrowser} can be used as a command-line interface @@ -45,7 +45,7 @@ The following functions are defined: -\begin{funcdesc}{open}{url\optional{, new=0}\optional{, autoraise=1}} +\begin{funcdesc}{open}{url\optional{, new=0\optional{, autoraise=1}}} Display \var{url} using the default browser. If \var{new} is 0, the \var{url} is opened in the same browser window. If \var{new} is 1, a new browser window is opened if possible. If \var{new} is 2, @@ -55,15 +55,15 @@ \end{funcdesc} -\begin{funcdesc}{open_new_win}{url} +\begin{funcdesc}{open_new}{url} Open \var{url} in a new window of the default browser, if possible, - otherwise, open \var{url} in the only browser window. Alias - \function{open_new}. + otherwise, open \var{url} in the only browser window. \end{funcdesc} \begin{funcdesc}{open_new_tab}{url} Open \var{url} in a new page ("tab") of the default browser, if possible, - otherwise equivalent to \function{open_new_win}. + otherwise equivalent to \function{open_new}. +\versionadded{2.5} \end{funcdesc} \begin{funcdesc}{get}{\optional{name}} @@ -117,7 +117,7 @@ \begin{description} \item[(1)] ``Konqueror'' is the file manager for the KDE desktop environment for -UNIX, and only makes sense to use if KDE is running. Some way of +\UNIX{}, and only makes sense to use if KDE is running. Some way of reliably detecting KDE would be nice; the \envvar{KDEDIR} variable is not sufficient. Note also that the name ``kfm'' is used even when using the \program{konqueror} command with KDE 2 --- the @@ -141,13 +141,13 @@ Browser controllers provide two methods which parallel two of the module-level convenience functions: -\begin{funcdesc}{open}{url\optional{, new}} +\begin{funcdesc}{open}{url\optional{, new\optional{, autoraise=1}}} Display \var{url} using the browser handled by this controller. If \var{new} is 1, a new browser window is opened if possible. If \var{new} is 2, a new browser page ("tab") is opened if possible. \end{funcdesc} -\begin{funcdesc}{open_new_win}{url} +\begin{funcdesc}{open_new}{url} Open \var{url} in a new window of the browser handled by this controller, if possible, otherwise, open \var{url} in the only browser window. Alias \function{open_new}. @@ -155,5 +155,6 @@ \begin{funcdesc}{open_new_tab}{url} Open \var{url} in a new page ("tab") of the browser handled by this - controller, if possible, otherwise equivalent to \function{open_new_win}. + controller, if possible, otherwise equivalent to \function{open_new}. +\versionadded{2.5} \end{funcdesc} From nnorwitz at users.sourceforge.net Tue Oct 4 05:37:32 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Tue, 4 Oct 2005 05:37:32 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/ref ref6.tex,1.78,1.79 Message-ID: <20051004033732.BDD631E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/ref In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5523/Doc/ref Modified Files: ref6.tex Log Message: Armin caught this mistake in bug #973103. Index: ref6.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref6.tex,v retrieving revision 1.78 retrieving revision 1.79 diff -u -d -r1.78 -r1.79 --- ref6.tex 3 Oct 2005 16:39:51 -0000 1.78 +++ ref6.tex 4 Oct 2005 03:37:29 -0000 1.79 @@ -603,7 +603,7 @@ \keyword{continue} may only occur syntactically nested in a \keyword{for} or \keyword{while} loop, but not nested in a function or class definition or -\keyword{try} statement within that loop.\footnote{It may +\keyword{finally} statement within that loop.\footnote{It may occur within an \keyword{except} or \keyword{else} clause. The restriction on occurring in the \keyword{try} clause is implementor's laziness and will eventually be lifted.} From nnorwitz at users.sourceforge.net Tue Oct 4 05:38:04 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Tue, 4 Oct 2005 05:38:04 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/ref ref6.tex, 1.73.2.5, 1.73.2.6 Message-ID: <20051004033804.95FC71E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/ref In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5622/Doc/ref Modified Files: Tag: release24-maint ref6.tex Log Message: Armin caught this mistake in bug #973103. Index: ref6.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref6.tex,v retrieving revision 1.73.2.5 retrieving revision 1.73.2.6 diff -u -d -r1.73.2.5 -r1.73.2.6 --- ref6.tex 3 Oct 2005 16:40:36 -0000 1.73.2.5 +++ ref6.tex 4 Oct 2005 03:38:01 -0000 1.73.2.6 @@ -603,7 +603,7 @@ \keyword{continue} may only occur syntactically nested in a \keyword{for} or \keyword{while} loop, but not nested in a function or class definition or -\keyword{try} statement within that loop.\footnote{It may +\keyword{finally} statement within that loop.\footnote{It may occur within an \keyword{except} or \keyword{else} clause. The restriction on occurring in the \keyword{try} clause is implementor's laziness and will eventually be lifted.} From nnorwitz at users.sourceforge.net Tue Oct 4 05:43:36 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Tue, 4 Oct 2005 05:43:36 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/ref ref6.tex, 1.73.2.6, 1.73.2.7 Message-ID: <20051004034336.C070E1E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/ref In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6243/Doc/ref Modified Files: Tag: release24-maint ref6.tex Log Message: Make close brace a paren to match open. Index: ref6.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref6.tex,v retrieving revision 1.73.2.6 retrieving revision 1.73.2.7 diff -u -d -r1.73.2.6 -r1.73.2.7 --- ref6.tex 4 Oct 2005 03:38:01 -0000 1.73.2.6 +++ ref6.tex 4 Oct 2005 03:43:33 -0000 1.73.2.7 @@ -526,7 +526,7 @@ exception that was active in the current scope. If no exception is active in the current scope, a \exception{TypeError} exception is raised indicating that this is an error (if running under IDLE, a -\exception{Queue.Empty} exception is raised instead}. +\exception{Queue.Empty} exception is raised instead). \index{exception} \indexii{raising}{exception} From nnorwitz at users.sourceforge.net Tue Oct 4 05:43:46 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Tue, 4 Oct 2005 05:43:46 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/ref ref6.tex,1.79,1.80 Message-ID: <20051004034346.59BBD1E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/ref In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6267/Doc/ref Modified Files: ref6.tex Log Message: Make close brace a paren to match open. Index: ref6.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref6.tex,v retrieving revision 1.79 retrieving revision 1.80 diff -u -d -r1.79 -r1.80 --- ref6.tex 4 Oct 2005 03:37:29 -0000 1.79 +++ ref6.tex 4 Oct 2005 03:43:43 -0000 1.80 @@ -526,7 +526,7 @@ exception that was active in the current scope. If no exception is active in the current scope, a \exception{TypeError} exception is raised indicating that this is an error (if running under IDLE, a -\exception{Queue.Empty} exception is raised instead}. +\exception{Queue.Empty} exception is raised instead). \index{exception} \indexii{raising}{exception} From nnorwitz at users.sourceforge.net Tue Oct 4 06:32:45 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Tue, 4 Oct 2005 06:32:45 +0200 (CEST) Subject: [Python-checkins] python/dist/src Makefile.pre.in,1.152,1.153 Message-ID: <20051004043245.CD95C1E4005@bag.python.org> Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13504 Modified Files: Makefile.pre.in Log Message: Get "make install" working again after adding Lib/test/bad_coding.py which can't be compiled. Thanks to Mat Martineau for spotting the problem. Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.152 retrieving revision 1.153 diff -u -d -r1.152 -r1.153 --- Makefile.pre.in 24 Apr 2005 22:26:37 -0000 1.152 +++ Makefile.pre.in 4 Oct 2005 04:32:42 -0000 1.153 @@ -724,11 +724,11 @@ PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ ./$(BUILDPYTHON) -Wi -tt $(DESTDIR)$(LIBDEST)/compileall.py \ -d $(LIBDEST) -f \ - -x 'badsyntax|site-packages' $(DESTDIR)$(LIBDEST) + -x 'bad_coding|badsyntax|site-packages' $(DESTDIR)$(LIBDEST) PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ ./$(BUILDPYTHON) -Wi -tt -O $(DESTDIR)$(LIBDEST)/compileall.py \ -d $(LIBDEST) -f \ - -x 'badsyntax|site-packages' $(DESTDIR)$(LIBDEST) + -x 'bad_coding|badsyntax|site-packages' $(DESTDIR)$(LIBDEST) -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ ./$(BUILDPYTHON) -Wi -t $(DESTDIR)$(LIBDEST)/compileall.py \ -d $(LIBDEST)/site-packages -f \ From rhettinger at users.sourceforge.net Wed Oct 5 13:39:15 2005 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed, 5 Oct 2005 13:39:15 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib/test test_bisect.py, 1.13, 1.14 Message-ID: <20051005113915.EC71F1E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3838/Lib/test Modified Files: test_bisect.py Log Message: SF #1313496: bisect C replacement doesn't accept named args Index: test_bisect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_bisect.py,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- test_bisect.py 27 Sep 2004 23:11:35 -0000 1.13 +++ test_bisect.py 5 Oct 2005 11:39:12 -0000 1.14 @@ -130,6 +130,16 @@ def test_backcompatibility(self): self.assertEqual(bisect, bisect_right) + def test_keyword_args(self): + data = [10, 20, 30, 40, 50] + self.assertEqual(bisect_left(a=data, x=25, lo=1, hi=3), 2) + self.assertEqual(bisect_right(a=data, x=25, lo=1, hi=3), 2) + self.assertEqual(bisect(a=data, x=25, lo=1, hi=3), 2) + insort_left(a=data, x=25, lo=1, hi=3) + insort_right(a=data, x=25, lo=1, hi=3) + insort(a=data, x=25, lo=1, hi=3) + self.assertEqual(data, [10, 20, 25, 25, 25, 30, 40, 50]) + #============================================================================== class TestInsort(unittest.TestCase): From rhettinger at users.sourceforge.net Wed Oct 5 13:39:16 2005 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed, 5 Oct 2005 13:39:16 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Modules _bisectmodule.c,1.2,1.3 Message-ID: <20051005113916.3DBC91E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3838/Modules Modified Files: _bisectmodule.c Log Message: SF #1313496: bisect C replacement doesn't accept named args Index: _bisectmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_bisectmodule.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- _bisectmodule.c 2 Aug 2004 13:24:54 -0000 1.2 +++ _bisectmodule.c 5 Oct 2005 11:39:12 -0000 1.3 @@ -34,15 +34,16 @@ } static PyObject * -bisect_right(PyObject *self, PyObject *args) +bisect_right(PyObject *self, PyObject *args, PyObject *kw) { PyObject *list, *item; int lo = 0; int hi = -1; int index; + static char *keywords[] = {"a", "x", "lo", "hi", NULL}; - if (!PyArg_ParseTuple(args, "OO|ii:bisect_right", - &list, &item, &lo, &hi)) + if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:bisect_right", + keywords, &list, &item, &lo, &hi)) return NULL; index = internal_bisect_right(list, item, lo, hi); if (index < 0) @@ -51,7 +52,7 @@ } PyDoc_STRVAR(bisect_right_doc, -"bisect_right(list, item[, lo[, hi]]) -> index\n\ +"bisect_right(a, x[, lo[, hi]]) -> index\n\ \n\ Return the index where to insert item x in list a, assuming a is sorted.\n\ \n\ @@ -63,15 +64,16 @@ slice of a to be searched.\n"); static PyObject * -insort_right(PyObject *self, PyObject *args) +insort_right(PyObject *self, PyObject *args, PyObject *kw) { PyObject *list, *item, *result; int lo = 0; int hi = -1; int index; + static char *keywords[] = {"a", "x", "lo", "hi", NULL}; - if (!PyArg_ParseTuple(args, "OO|ii:insort_right", - &list, &item, &lo, &hi)) + if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:insort_right", + keywords, &list, &item, &lo, &hi)) return NULL; index = internal_bisect_right(list, item, lo, hi); if (index < 0) @@ -91,7 +93,7 @@ } PyDoc_STRVAR(insort_right_doc, -"insort_right(list, item[, lo[, hi]])\n\ +"insort_right(a, x[, lo[, hi]])\n\ \n\ Insert item x in list a, and keep it sorted assuming a is sorted.\n\ \n\ @@ -129,15 +131,16 @@ } static PyObject * -bisect_left(PyObject *self, PyObject *args) +bisect_left(PyObject *self, PyObject *args, PyObject *kw) { PyObject *list, *item; int lo = 0; int hi = -1; int index; + static char *keywords[] = {"a", "x", "lo", "hi", NULL}; - if (!PyArg_ParseTuple(args, "OO|ii:bisect_left", - &list, &item, &lo, &hi)) + if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:bisect_left", + keywords, &list, &item, &lo, &hi)) return NULL; index = internal_bisect_left(list, item, lo, hi); if (index < 0) @@ -146,7 +149,7 @@ } PyDoc_STRVAR(bisect_left_doc, -"bisect_left(list, item[, lo[, hi]]) -> index\n\ +"bisect_left(a, x[, lo[, hi]]) -> index\n\ \n\ Return the index where to insert item x in list a, assuming a is sorted.\n\ \n\ @@ -158,15 +161,16 @@ slice of a to be searched.\n"); static PyObject * -insort_left(PyObject *self, PyObject *args) +insort_left(PyObject *self, PyObject *args, PyObject *kw) { PyObject *list, *item, *result; int lo = 0; int hi = -1; int index; + static char *keywords[] = {"a", "x", "lo", "hi", NULL}; - if (!PyArg_ParseTuple(args, "OO|ii:insort_left", - &list, &item, &lo, &hi)) + if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:insort_left", + keywords, &list, &item, &lo, &hi)) return NULL; index = internal_bisect_left(list, item, lo, hi); if (index < 0) @@ -186,7 +190,7 @@ } PyDoc_STRVAR(insort_left_doc, -"insort_left(list, item[, lo[, hi]])\n\ +"insort_left(a, x[, lo[, hi]])\n\ \n\ Insert item x in list a, and keep it sorted assuming a is sorted.\n\ \n\ @@ -200,17 +204,17 @@ static PyMethodDef bisect_methods[] = { {"bisect_right", (PyCFunction)bisect_right, - METH_VARARGS, bisect_right_doc}, + METH_VARARGS|METH_KEYWORDS, bisect_right_doc}, {"bisect", (PyCFunction)bisect_right, - METH_VARARGS, bisect_doc}, + METH_VARARGS|METH_KEYWORDS, bisect_doc}, {"insort_right", (PyCFunction)insort_right, - METH_VARARGS, insort_right_doc}, + METH_VARARGS|METH_KEYWORDS, insort_right_doc}, {"insort", (PyCFunction)insort_right, - METH_VARARGS, insort_doc}, + METH_VARARGS|METH_KEYWORDS, insort_doc}, {"bisect_left", (PyCFunction)bisect_left, - METH_VARARGS, bisect_left_doc}, + METH_VARARGS|METH_KEYWORDS, bisect_left_doc}, {"insort_left", (PyCFunction)insort_left, - METH_VARARGS, insort_left_doc}, + METH_VARARGS|METH_KEYWORDS, insort_left_doc}, {NULL, NULL} /* sentinel */ }; From rhettinger at users.sourceforge.net Wed Oct 5 13:48:39 2005 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed, 5 Oct 2005 13:48:39 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib/test test_bisect.py, 1.13, 1.13.2.1 Message-ID: <20051005114839.8A9BE1E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5788/Lib/test Modified Files: Tag: release24-maint test_bisect.py Log Message: SF #1313496: bisect C replacement doesn't accept named args Index: test_bisect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_bisect.py,v retrieving revision 1.13 retrieving revision 1.13.2.1 diff -u -d -r1.13 -r1.13.2.1 --- test_bisect.py 27 Sep 2004 23:11:35 -0000 1.13 +++ test_bisect.py 5 Oct 2005 11:48:36 -0000 1.13.2.1 @@ -130,6 +130,16 @@ def test_backcompatibility(self): self.assertEqual(bisect, bisect_right) + def test_keyword_args(self): + data = [10, 20, 30, 40, 50] + self.assertEqual(bisect_left(a=data, x=25, lo=1, hi=3), 2) + self.assertEqual(bisect_right(a=data, x=25, lo=1, hi=3), 2) + self.assertEqual(bisect(a=data, x=25, lo=1, hi=3), 2) + insort_left(a=data, x=25, lo=1, hi=3) + insort_right(a=data, x=25, lo=1, hi=3) + insort(a=data, x=25, lo=1, hi=3) + self.assertEqual(data, [10, 20, 25, 25, 25, 30, 40, 50]) + #============================================================================== class TestInsort(unittest.TestCase): From rhettinger at users.sourceforge.net Wed Oct 5 13:48:39 2005 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed, 5 Oct 2005 13:48:39 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Modules _bisectmodule.c, 1.2, 1.2.4.1 Message-ID: <20051005114839.B6A091E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5788/Modules Modified Files: Tag: release24-maint _bisectmodule.c Log Message: SF #1313496: bisect C replacement doesn't accept named args Index: _bisectmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_bisectmodule.c,v retrieving revision 1.2 retrieving revision 1.2.4.1 diff -u -d -r1.2 -r1.2.4.1 --- _bisectmodule.c 2 Aug 2004 13:24:54 -0000 1.2 +++ _bisectmodule.c 5 Oct 2005 11:48:36 -0000 1.2.4.1 @@ -34,15 +34,16 @@ } static PyObject * -bisect_right(PyObject *self, PyObject *args) +bisect_right(PyObject *self, PyObject *args, PyObject *kw) { PyObject *list, *item; int lo = 0; int hi = -1; int index; + static char *keywords[] = {"a", "x", "lo", "hi", NULL}; - if (!PyArg_ParseTuple(args, "OO|ii:bisect_right", - &list, &item, &lo, &hi)) + if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:bisect_right", + keywords, &list, &item, &lo, &hi)) return NULL; index = internal_bisect_right(list, item, lo, hi); if (index < 0) @@ -51,7 +52,7 @@ } PyDoc_STRVAR(bisect_right_doc, -"bisect_right(list, item[, lo[, hi]]) -> index\n\ +"bisect_right(a, x[, lo[, hi]]) -> index\n\ \n\ Return the index where to insert item x in list a, assuming a is sorted.\n\ \n\ @@ -63,15 +64,16 @@ slice of a to be searched.\n"); static PyObject * -insort_right(PyObject *self, PyObject *args) +insort_right(PyObject *self, PyObject *args, PyObject *kw) { PyObject *list, *item, *result; int lo = 0; int hi = -1; int index; + static char *keywords[] = {"a", "x", "lo", "hi", NULL}; - if (!PyArg_ParseTuple(args, "OO|ii:insort_right", - &list, &item, &lo, &hi)) + if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:insort_right", + keywords, &list, &item, &lo, &hi)) return NULL; index = internal_bisect_right(list, item, lo, hi); if (index < 0) @@ -91,7 +93,7 @@ } PyDoc_STRVAR(insort_right_doc, -"insort_right(list, item[, lo[, hi]])\n\ +"insort_right(a, x[, lo[, hi]])\n\ \n\ Insert item x in list a, and keep it sorted assuming a is sorted.\n\ \n\ @@ -129,15 +131,16 @@ } static PyObject * -bisect_left(PyObject *self, PyObject *args) +bisect_left(PyObject *self, PyObject *args, PyObject *kw) { PyObject *list, *item; int lo = 0; int hi = -1; int index; + static char *keywords[] = {"a", "x", "lo", "hi", NULL}; - if (!PyArg_ParseTuple(args, "OO|ii:bisect_left", - &list, &item, &lo, &hi)) + if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:bisect_left", + keywords, &list, &item, &lo, &hi)) return NULL; index = internal_bisect_left(list, item, lo, hi); if (index < 0) @@ -146,7 +149,7 @@ } PyDoc_STRVAR(bisect_left_doc, -"bisect_left(list, item[, lo[, hi]]) -> index\n\ +"bisect_left(a, x[, lo[, hi]]) -> index\n\ \n\ Return the index where to insert item x in list a, assuming a is sorted.\n\ \n\ @@ -158,15 +161,16 @@ slice of a to be searched.\n"); static PyObject * -insort_left(PyObject *self, PyObject *args) +insort_left(PyObject *self, PyObject *args, PyObject *kw) { PyObject *list, *item, *result; int lo = 0; int hi = -1; int index; + static char *keywords[] = {"a", "x", "lo", "hi", NULL}; - if (!PyArg_ParseTuple(args, "OO|ii:insort_left", - &list, &item, &lo, &hi)) + if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:insort_left", + keywords, &list, &item, &lo, &hi)) return NULL; index = internal_bisect_left(list, item, lo, hi); if (index < 0) @@ -186,7 +190,7 @@ } PyDoc_STRVAR(insort_left_doc, -"insort_left(list, item[, lo[, hi]])\n\ +"insort_left(a, x[, lo[, hi]])\n\ \n\ Insert item x in list a, and keep it sorted assuming a is sorted.\n\ \n\ @@ -200,17 +204,17 @@ static PyMethodDef bisect_methods[] = { {"bisect_right", (PyCFunction)bisect_right, - METH_VARARGS, bisect_right_doc}, + METH_VARARGS|METH_KEYWORDS, bisect_right_doc}, {"bisect", (PyCFunction)bisect_right, - METH_VARARGS, bisect_doc}, + METH_VARARGS|METH_KEYWORDS, bisect_doc}, {"insort_right", (PyCFunction)insort_right, - METH_VARARGS, insort_right_doc}, + METH_VARARGS|METH_KEYWORDS, insort_right_doc}, {"insort", (PyCFunction)insort_right, - METH_VARARGS, insort_doc}, + METH_VARARGS|METH_KEYWORDS, insort_doc}, {"bisect_left", (PyCFunction)bisect_left, - METH_VARARGS, bisect_left_doc}, + METH_VARARGS|METH_KEYWORDS, bisect_left_doc}, {"insort_left", (PyCFunction)insort_left, - METH_VARARGS, insort_left_doc}, + METH_VARARGS|METH_KEYWORDS, insort_left_doc}, {NULL, NULL} /* sentinel */ }; From rhettinger at users.sourceforge.net Wed Oct 5 13:48:40 2005 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed, 5 Oct 2005 13:48:40 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Misc NEWS, 1.1193.2.119, 1.1193.2.120 Message-ID: <20051005114840.B77F21E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5788/Misc Modified Files: Tag: release24-maint NEWS Log Message: SF #1313496: bisect C replacement doesn't accept named args Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1193.2.119 retrieving revision 1.1193.2.120 diff -u -d -r1.1193.2.119 -r1.1193.2.120 --- NEWS 3 Oct 2005 04:50:55 -0000 1.1193.2.119 +++ NEWS 5 Oct 2005 11:48:36 -0000 1.1193.2.120 @@ -30,6 +30,8 @@ Library ------- +- SF #1313496: the bisect module now accepts named arguments. + - Bug #729103: pydoc.py: Fix docother() method to accept additional "parent" argument. From perky at users.sourceforge.net Thu Oct 6 17:52:04 2005 From: perky at users.sourceforge.net (perky@users.sourceforge.net) Date: Thu, 6 Oct 2005 17:52:04 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Modules/cjkcodecs cjkcodecs.h, 1.5, 1.6 Message-ID: <20051006155204.010FF1E4002@bag.python.org> Update of /cvsroot/python/python/dist/src/Modules/cjkcodecs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29224/Modules/cjkcodecs Modified Files: cjkcodecs.h Log Message: Change the internal "undefined codepoint" mark for CJKCodecs decoders from U+FFFD to U+FFFE which is considered more appropriate. (from MAL's comment) Index: cjkcodecs.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cjkcodecs/cjkcodecs.h,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- cjkcodecs.h 19 Aug 2004 17:49:56 -0000 1.5 +++ cjkcodecs.h 6 Oct 2005 15:51:59 -0000 1.6 @@ -12,7 +12,10 @@ #include "multibytecodec.h" -#define UNIINV Py_UNICODE_REPLACEMENT_CHARACTER +/* a unicode "undefined" codepoint */ +#define UNIINV 0xFFFE + +/* internal-use DBCS codepoints which aren't used by any charsets */ #define NOCHAR 0xFFFF #define MULTIC 0xFFFE #define DBCINV 0xFFFD From doerwalter at users.sourceforge.net Thu Oct 6 22:30:00 2005 From: doerwalter at users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Thu, 6 Oct 2005 22:30:00 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib/test test_codecs.py, 1.26, 1.27 Message-ID: <20051006203000.EC2D71E4003@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6122/Lib/test Modified Files: test_codecs.py Log Message: Part of SF patch #1313939: Speedup charmap decoding by extending PyUnicode_DecodeCharmap() the accept a unicode string as the mapping argument which is used as a mapping table. This code isn't used by any of the codecs yet. Index: test_codecs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_codecs.py,v retrieving revision 1.26 retrieving revision 1.27 diff -u -d -r1.26 -r1.27 --- test_codecs.py 30 Aug 2005 10:23:13 -0000 1.26 +++ test_codecs.py 6 Oct 2005 20:29:57 -0000 1.27 @@ -924,6 +924,40 @@ (chars, size) = codecs.getdecoder(encoding)(bytes) self.assertEqual(chars, s, "%r != %r (encoding=%r)" % (chars, s, encoding)) +class CharmapTest(unittest.TestCase): + def test_decode_with_string_map(self): + self.assertEquals( + codecs.charmap_decode("\x00\x01\x02", "strict", u"abc"), + (u"abc", 3) + ) + + self.assertEquals( + codecs.charmap_decode("\x00\x01\x02", "replace", u"ab"), + (u"ab\ufffd", 3) + ) + + self.assertEquals( + codecs.charmap_decode("\x00\x01\x02", "replace", u"ab\ufffe"), + (u"ab\ufffd", 3) + ) + + self.assertEquals( + codecs.charmap_decode("\x00\x01\x02", "ignore", u"ab"), + (u"ab", 3) + ) + + self.assertEquals( + codecs.charmap_decode("\x00\x01\x02", "ignore", u"ab\ufffe"), + (u"ab", 3) + ) + + allbytes = "".join(chr(i) for i in xrange(256)) + self.assertEquals( + codecs.charmap_decode(allbytes, "ignore", u""), + (u"", len(allbytes)) + ) + + def test_main(): test_support.run_unittest( UTF16Test, @@ -940,7 +974,8 @@ StreamReaderTest, Str2StrTest, BasicUnicodeTest, - BasicStrTest + BasicStrTest, + CharmapTest ) From doerwalter at users.sourceforge.net Thu Oct 6 22:30:01 2005 From: doerwalter at users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Thu, 6 Oct 2005 22:30:01 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Objects unicodeobject.c, 2.231, 2.232 Message-ID: <20051006203001.283881E4003@bag.python.org> Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6122/Objects Modified Files: unicodeobject.c Log Message: Part of SF patch #1313939: Speedup charmap decoding by extending PyUnicode_DecodeCharmap() the accept a unicode string as the mapping argument which is used as a mapping table. This code isn't used by any of the codecs yet. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.231 retrieving revision 2.232 diff -u -d -r2.231 -r2.232 --- unicodeobject.c 30 Aug 2005 10:23:14 -0000 2.231 +++ unicodeobject.c 6 Oct 2005 20:29:57 -0000 2.232 @@ -2833,6 +2833,8 @@ int extrachars = 0; PyObject *errorHandler = NULL; PyObject *exc = NULL; + Py_UNICODE *mapstring = NULL; + int maplen = 0; /* Default to Latin-1 */ if (mapping == NULL) @@ -2845,91 +2847,121 @@ return (PyObject *)v; p = PyUnicode_AS_UNICODE(v); e = s + size; - while (s < e) { - unsigned char ch = *s; - PyObject *w, *x; + if (PyUnicode_CheckExact(mapping)) { + mapstring = PyUnicode_AS_UNICODE(mapping); + maplen = PyUnicode_GET_SIZE(mapping); + while (s < e) { + unsigned char ch = *s; + Py_UNICODE x = 0xfffe; /* illegal value */ - /* Get mapping (char ordinal -> integer, Unicode char or None) */ - w = PyInt_FromLong((long)ch); - if (w == NULL) - goto onError; - x = PyObject_GetItem(mapping, w); - Py_DECREF(w); - if (x == NULL) { - if (PyErr_ExceptionMatches(PyExc_LookupError)) { - /* No mapping found means: mapping is undefined. */ - PyErr_Clear(); - x = Py_None; - Py_INCREF(x); - } else - goto onError; - } + if (ch < maplen) + x = mapstring[ch]; - /* Apply mapping */ - if (PyInt_Check(x)) { - long value = PyInt_AS_LONG(x); - if (value < 0 || value > 65535) { - PyErr_SetString(PyExc_TypeError, - "character mapping must be in range(65536)"); - Py_DECREF(x); - goto onError; + if (x == 0xfffe) { + /* undefined mapping */ + outpos = p-PyUnicode_AS_UNICODE(v); + startinpos = s-starts; + endinpos = startinpos+1; + if (unicode_decode_call_errorhandler( + errors, &errorHandler, + "charmap", "character maps to ", + starts, size, &startinpos, &endinpos, &exc, &s, + (PyObject **)&v, &outpos, &p)) { + goto onError; + } + continue; } - *p++ = (Py_UNICODE)value; + *p++ = x; + ++s; } - else if (x == Py_None) { - /* undefined mapping */ - outpos = p-PyUnicode_AS_UNICODE(v); - startinpos = s-starts; - endinpos = startinpos+1; - if (unicode_decode_call_errorhandler( - errors, &errorHandler, - "charmap", "character maps to ", - starts, size, &startinpos, &endinpos, &exc, &s, - (PyObject **)&v, &outpos, &p)) { - Py_DECREF(x); + } + else { + while (s < e) { + unsigned char ch = *s; + PyObject *w, *x; + + /* Get mapping (char ordinal -> integer, Unicode char or None) */ + w = PyInt_FromLong((long)ch); + if (w == NULL) goto onError; + x = PyObject_GetItem(mapping, w); + Py_DECREF(w); + if (x == NULL) { + if (PyErr_ExceptionMatches(PyExc_LookupError)) { + /* No mapping found means: mapping is undefined. */ + PyErr_Clear(); + x = Py_None; + Py_INCREF(x); + } else + goto onError; } - continue; - } - else if (PyUnicode_Check(x)) { - int targetsize = PyUnicode_GET_SIZE(x); - - if (targetsize == 1) - /* 1-1 mapping */ - *p++ = *PyUnicode_AS_UNICODE(x); - - else if (targetsize > 1) { - /* 1-n mapping */ - if (targetsize > extrachars) { - /* resize first */ - int oldpos = (int)(p - PyUnicode_AS_UNICODE(v)); - int needed = (targetsize - extrachars) + \ - (targetsize << 2); - extrachars += needed; - if (_PyUnicode_Resize(&v, - PyUnicode_GET_SIZE(v) + needed) < 0) { - Py_DECREF(x); - goto onError; + + /* Apply mapping */ + if (PyInt_Check(x)) { + long value = PyInt_AS_LONG(x); + if (value < 0 || value > 65535) { + PyErr_SetString(PyExc_TypeError, + "character mapping must be in range(65536)"); + Py_DECREF(x); + goto onError; + } + *p++ = (Py_UNICODE)value; + } + else if (x == Py_None) { + /* undefined mapping */ + outpos = p-PyUnicode_AS_UNICODE(v); + startinpos = s-starts; + endinpos = startinpos+1; + if (unicode_decode_call_errorhandler( + errors, &errorHandler, + "charmap", "character maps to ", + starts, size, &startinpos, &endinpos, &exc, &s, + (PyObject **)&v, &outpos, &p)) { + Py_DECREF(x); + goto onError; + } + continue; + } + else if (PyUnicode_Check(x)) { + int targetsize = PyUnicode_GET_SIZE(x); + + if (targetsize == 1) + /* 1-1 mapping */ + *p++ = *PyUnicode_AS_UNICODE(x); + + else if (targetsize > 1) { + /* 1-n mapping */ + if (targetsize > extrachars) { + /* resize first */ + int oldpos = (int)(p - PyUnicode_AS_UNICODE(v)); + int needed = (targetsize - extrachars) + \ + (targetsize << 2); + extrachars += needed; + if (_PyUnicode_Resize(&v, + PyUnicode_GET_SIZE(v) + needed) < 0) { + Py_DECREF(x); + goto onError; + } + p = PyUnicode_AS_UNICODE(v) + oldpos; } - p = PyUnicode_AS_UNICODE(v) + oldpos; + Py_UNICODE_COPY(p, + PyUnicode_AS_UNICODE(x), + targetsize); + p += targetsize; + extrachars -= targetsize; } - Py_UNICODE_COPY(p, - PyUnicode_AS_UNICODE(x), - targetsize); - p += targetsize; - extrachars -= targetsize; + /* 1-0 mapping: skip the character */ + } + else { + /* wrong return value */ + PyErr_SetString(PyExc_TypeError, + "character mapping must return integer, None or unicode"); + Py_DECREF(x); + goto onError; } - /* 1-0 mapping: skip the character */ - } - else { - /* wrong return value */ - PyErr_SetString(PyExc_TypeError, - "character mapping must return integer, None or unicode"); Py_DECREF(x); - goto onError; + ++s; } - Py_DECREF(x); - ++s; } if (p - PyUnicode_AS_UNICODE(v) < PyUnicode_GET_SIZE(v)) if (_PyUnicode_Resize(&v, (int)(p - PyUnicode_AS_UNICODE(v))) < 0) From doerwalter at users.sourceforge.net Thu Oct 6 22:30:01 2005 From: doerwalter at users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Thu, 6 Oct 2005 22:30:01 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/api concrete.tex,1.67,1.68 Message-ID: <20051006203001.700151E4003@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/api In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6122/Doc/api Modified Files: concrete.tex Log Message: Part of SF patch #1313939: Speedup charmap decoding by extending PyUnicode_DecodeCharmap() the accept a unicode string as the mapping argument which is used as a mapping table. This code isn't used by any of the codecs yet. Index: concrete.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/concrete.tex,v retrieving revision 1.67 retrieving revision 1.68 diff -u -d -r1.67 -r1.68 --- concrete.tex 28 Sep 2005 12:53:12 -0000 1.67 +++ concrete.tex 6 Oct 2005 20:29:57 -0000 1.68 @@ -1322,7 +1322,12 @@ const char *errors} Create a Unicode object by decoding \var{size} bytes of the encoded string \var{s} using the given \var{mapping} object. Return - \NULL{} if an exception was raised by the codec. + \NULL{} if an exception was raised by the codec. If \var{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". + \versionchanged[Allowed unicode string as mapping argument]{2.4} \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyUnicode_EncodeCharmap}{const Py_UNICODE *s, From doerwalter at users.sourceforge.net Thu Oct 6 22:30:01 2005 From: doerwalter at users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Thu, 6 Oct 2005 22:30:01 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1386,1.1387 Message-ID: <20051006203001.D61701E4007@bag.python.org> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6122/Misc Modified Files: NEWS Log Message: Part of SF patch #1313939: Speedup charmap decoding by extending PyUnicode_DecodeCharmap() the accept a unicode string as the mapping argument which is used as a mapping table. This code isn't used by any of the codecs yet. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1386 retrieving revision 1.1387 diff -u -d -r1.1386 -r1.1387 --- NEWS 3 Oct 2005 14:16:44 -0000 1.1386 +++ NEWS 6 Oct 2005 20:29:57 -0000 1.1387 @@ -563,6 +563,11 @@ - Removed PyRange_New(). +- Patch #1313939: PyUnicode_DecodeCharmap() accepts a unicode string as the + mapping argument now. This string is used as a mapping table. Byte values + greater than the length of the string and 0xFFFE are treated as undefined + mappings. + Tests ----- From nascheme at users.sourceforge.net Fri Oct 7 07:09:32 2005 From: nascheme at users.sourceforge.net (nascheme@users.sourceforge.net) Date: Fri, 7 Oct 2005 07:09:32 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Objects codeobject.c, 1.1.2.4, 1.1.2.5 Message-ID: <20051007050932.EB9C51E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16235/Objects Modified Files: Tag: ast-branch codeobject.c Log Message: Merge MWH's fix for new.code (r2.315) into ast-branch. Index: codeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/Attic/codeobject.c,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -u -d -r1.1.2.4 -r1.1.2.5 --- codeobject.c 11 Jul 2005 04:03:11 -0000 1.1.2.4 +++ codeobject.c 7 Oct 2005 05:09:29 -0000 1.1.2.5 @@ -25,29 +25,27 @@ return 1; } -static int +static void intern_strings(PyObject *tuple) { int i; for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) { PyObject *v = PyTuple_GET_ITEM(tuple, i); - if (v == NULL || !PyString_Check(v)) { + if (v == NULL || !PyString_CheckExact(v)) { Py_FatalError("non-string found in code slot"); - PyErr_BadInternalCall(); - return -1; } PyString_InternInPlace(&PyTuple_GET_ITEM(tuple, i)); } - return 0; } + PyCodeObject * PyCode_New(int argcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, - PyObject *lnotab) + PyObject *lnotab) { PyCodeObject *co; int i; @@ -129,6 +127,50 @@ {NULL} /* Sentinel */ }; +/* Helper for code_new: return a shallow copy of a tuple that is + guaranteed to contain exact strings, by converting string subclasses + to exact strings and complaining if a non-string is found. */ +static PyObject* +validate_and_copy_tuple(PyObject *tup) +{ + PyObject *newtuple; + PyObject *item; + int i, len; + + len = PyTuple_GET_SIZE(tup); + newtuple = PyTuple_New(len); + if (newtuple == NULL) + return NULL; + + for (i = 0; i < len; i++) { + item = PyTuple_GET_ITEM(tup, i); + if (PyString_CheckExact(item)) { + Py_INCREF(item); + } + else if (!PyString_Check(item)) { + PyErr_Format( + PyExc_TypeError, + "name tuples must contain only " + "strings, not '%.500s'", + item->ob_type->tp_name); + Py_DECREF(newtuple); + return NULL; + } + else { + item = PyString_FromStringAndSize( + PyString_AS_STRING(item), + PyString_GET_SIZE(item)); + if (item == NULL) { + Py_DECREF(newtuple); + return NULL; + } + } + PyTuple_SET_ITEM(newtuple, i, item); + } + + return newtuple; +} + PyDoc_STRVAR(code_doc, "code(argcount, nlocals, stacksize, flags, codestring, constants, names,\n\ varnames, filename, name, firstlineno, lnotab[, freevars[, cellvars]])\n\ @@ -142,12 +184,13 @@ int nlocals; int stacksize; int flags; + PyObject *co = NULL; PyObject *code; PyObject *consts; - PyObject *names; - PyObject *varnames; - PyObject *freevars = NULL; - PyObject *cellvars = NULL; + PyObject *names, *ournames = NULL; + PyObject *varnames, *ourvarnames = NULL; + PyObject *freevars = NULL, *ourfreevars = NULL; + PyObject *cellvars = NULL, *ourcellvars = NULL; PyObject *filename; PyObject *name; int firstlineno; @@ -165,31 +208,49 @@ &PyTuple_Type, &cellvars)) return NULL; - if (freevars == NULL || cellvars == NULL) { - PyObject *empty = PyTuple_New(0); - if (empty == NULL) - return NULL; - if (freevars == NULL) { - freevars = empty; - Py_INCREF(freevars); - } - if (cellvars == NULL) { - cellvars = empty; - Py_INCREF(cellvars); - } - Py_DECREF(empty); + if (argcount < 0) { + PyErr_SetString( + PyExc_ValueError, + "code: argcount must not be negative"); + goto cleanup; } - if (!PyObject_CheckReadBuffer(code)) { - PyErr_SetString(PyExc_TypeError, - "bytecode object must be a single-segment read-only buffer"); - return NULL; + if (nlocals < 0) { + PyErr_SetString( + PyExc_ValueError, + "code: nlocals must not be negative"); + goto cleanup; } - return (PyObject *)PyCode_New(argcount, nlocals, stacksize, flags, - code, consts, names, varnames, - freevars, cellvars, filename, name, - firstlineno, lnotab); + ournames = validate_and_copy_tuple(names); + if (ournames == NULL) + goto cleanup; + ourvarnames = validate_and_copy_tuple(varnames); + if (ourvarnames == NULL) + goto cleanup; + if (freevars) + ourfreevars = validate_and_copy_tuple(freevars); + else + ourfreevars = PyTuple_New(0); + if (ourfreevars == NULL) + goto cleanup; + if (cellvars) + ourcellvars = validate_and_copy_tuple(cellvars); + else + ourcellvars = PyTuple_New(0); + if (ourcellvars == NULL) + goto cleanup; + + co = (PyObject *)PyCode_New(argcount, nlocals, stacksize, flags, + code, consts, ournames, ourvarnames, + ourfreevars, ourcellvars, filename, + name, firstlineno, lnotab); + cleanup: + Py_XDECREF(ournames); + Py_XDECREF(ourvarnames); + Py_XDECREF(ourfreevars); + Py_XDECREF(ourcellvars); + return co; } static void From vsajip at users.sourceforge.net Fri Oct 7 10:35:42 2005 From: vsajip at users.sourceforge.net (vsajip@users.sourceforge.net) Date: Fri, 7 Oct 2005 10:35:42 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib/logging __init__.py, 1.30, 1.31 Message-ID: <20051007083542.9C0BE1E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib/logging In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17951 Modified Files: __init__.py Log Message: Fixed bug where the logging message was wrongly being demoted from Unicode to string (SF #1314107) Index: __init__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/logging/__init__.py,v retrieving revision 1.30 retrieving revision 1.31 diff -u -d -r1.30 -r1.31 --- __init__.py 16 Sep 2005 10:33:40 -0000 1.30 +++ __init__.py 7 Oct 2005 08:35:36 -0000 1.31 @@ -41,8 +41,8 @@ __author__ = "Vinay Sajip " __status__ = "beta" -__version__ = "0.4.9.6" -__date__ = "27 March 2005" +__version__ = "0.4.9.7" +__date__ = "07 October 2005" #--------------------------------------------------------------------------- # Miscellaneous module data @@ -266,10 +266,12 @@ if not hasattr(types, "UnicodeType"): #if no unicode support... msg = str(self.msg) else: - try: - msg = str(self.msg) - except UnicodeError: - msg = self.msg #Defer encoding till later + msg = self.msg + if type(msg) not in (types.UnicodeType, types.StringType): + try: + msg = str(self.msg) + except UnicodeError: + msg = self.msg #Defer encoding till later if self.args: msg = msg % self.args return msg From vsajip at users.sourceforge.net Fri Oct 7 10:36:36 2005 From: vsajip at users.sourceforge.net (vsajip@users.sourceforge.net) Date: Fri, 7 Oct 2005 10:36:36 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib/logging __init__.py, 1.24.2.2, 1.24.2.3 Message-ID: <20051007083636.20D071E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib/logging In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18262 Modified Files: Tag: release24-maint __init__.py Log Message: Fixed bug where the logging message was wrongly being demoted from Unicode to string (SF #1314107) Index: __init__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/logging/__init__.py,v retrieving revision 1.24.2.2 retrieving revision 1.24.2.3 diff -u -d -r1.24.2.2 -r1.24.2.3 --- __init__.py 16 Sep 2005 10:44:40 -0000 1.24.2.2 +++ __init__.py 7 Oct 2005 08:36:33 -0000 1.24.2.3 @@ -41,8 +41,8 @@ __author__ = "Vinay Sajip " __status__ = "beta" -__version__ = "0.4.9.6" -__date__ = "27 March 2005" +__version__ = "0.4.9.7" +__date__ = "07 October 2005" #--------------------------------------------------------------------------- # Miscellaneous module data @@ -266,10 +266,12 @@ if not hasattr(types, "UnicodeType"): #if no unicode support... msg = str(self.msg) else: - try: - msg = str(self.msg) - except UnicodeError: - msg = self.msg #Defer encoding till later + msg = self.msg + if type(msg) not in (types.UnicodeType, types.StringType): + try: + msg = str(self.msg) + except UnicodeError: + msg = self.msg #Defer encoding till later if self.args: msg = msg % self.args return msg From jhylton at users.sourceforge.net Fri Oct 7 20:42:54 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Fri, 7 Oct 2005 20:42:54 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Python newcompile.c, 1.1.2.110, 1.1.2.111 Message-ID: <20051007184254.666F51E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6237 Modified Files: Tag: ast-branch newcompile.c Log Message: Fix a small bug in test_dis and add some high-level comments. One failure in test_dis was shallow. test_dis() failed because the compiler generated a redundant LOAD_CONST None / RETURN_VALUE block. The assembler() now checks the b_return flag of the final block before emitting a new RETURN_VALUE opcode. Index: newcompile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/Attic/newcompile.c,v retrieving revision 1.1.2.110 retrieving revision 1.1.2.111 diff -u -d -r1.1.2.110 -r1.1.2.111 --- newcompile.c 28 Jul 2005 05:50:01 -0000 1.1.2.110 +++ newcompile.c 7 Oct 2005 18:42:50 -0000 1.1.2.111 @@ -1,3 +1,19 @@ +/* + * This file compiles an abstract syntax tree (AST) into Python bytecode. + * + * The primary entry point is PyAST_Compile(), which returns a + * PyCodeObject. The compiler makes several passes to build the code + * object: + * 1. Checks for future statements. See future.c + * 2. Builds a symbol table. See symtable.c. + * 3. Generate code for basic blocks. See compiler_mod() in this file. + * 4. Assemble the basic blocks into final code. See assemble() in + * this file. + * + * Note that compiler_mod() suggests module, but the module ast type + * (mod_ty) has cases for expressions and interactive statements. + */ + #include "Python.h" #include "Python-ast.h" @@ -134,6 +150,13 @@ has been generated with current lineno */ }; +/* This struct captures the global state of a compilation. + + The u pointer points to the current compilation unit, while units + for enclosing blocks are stored in c_stack. The u and c_stack are + managed by compiler_enter_scope() and compiler_exit_scope(). +*/ + struct compiler { const char *c_filename; struct symtable *c_st; @@ -143,9 +166,9 @@ int c_interactive; int c_nestlevel; - struct compiler_unit *u; - PyObject *c_stack; - char *c_encoding; /* source encoding (a borrowed reference) */ + struct compiler_unit *u; /* compiler state for current block */ + PyObject *c_stack; /* Python list holding compiler_unit ptrs */ + char *c_encoding; /* source encoding (a borrowed reference) */ }; struct assembler { @@ -3559,10 +3582,12 @@ XXX NEXT_BLOCK() isn't quite right, because if the last block ends with a jump or return b_next shouldn't set. */ - NEXT_BLOCK(c); - if (addNone) - ADDOP_O(c, LOAD_CONST, Py_None, consts); - ADDOP(c, RETURN_VALUE); + if (!c->u->u_curblock->b_return) { + NEXT_BLOCK(c); + if (addNone) + ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP(c, RETURN_VALUE); + } nblocks = 0; entryblock = NULL; From galvescarvalho at yahoo.com.br Sat Oct 8 17:21:55 2005 From: galvescarvalho at yahoo.com.br (Geraldo Alves C.) Date: Sat, 8 Oct 2005 12:21:55 -0300 Subject: [Python-checkins] 2.000 Modelos de Cartas Comerciais, Modelos de Propostas, contratos e Documentos Message-ID: <20051008152210.08BAE1E4006@bag.python.org> Os melhores Modelos de Contratos e Cartas Comerciais. Como escrever uma proposta, ducumento ou carta comercial: Visite agora: http://www.gueb.de/modelosdecartascomerciais Modelos de cartas de agradecimento, modelos de cartas de demiss?o, modelos de cartas com mensagem mensagens de p?sames, modelos de convites, modelos de declara??es, modelos de cartas de solicita??o de empregos, modelos de cartas de cobran?as, modelos de cartas de recomenda??o, modelos de cartas de recomenda??es, redigir cartas comerciais, modelos de propostas comerciais, modelos de respostas a propostas comerciais, dicas de como redigir, dicas de reda??o de cartas comerciais, modelos de pedidos, modelos de atestados m?dicos. Modelos de cartas em ingl?s, modelos de cartas de reclama??o, modelos de cartas de refer?ncias, dicas de como escrever cartas comerciais, dicas de como redigir cartas comerciais, modelos de convites para festas, modelos de convites para eventos, modelos de cartas de pedidos de demiss?o, modelos de cartas de felicita??es, modelos de cartas formais, modelos de recibos, proposta de presta??o de servi?os, Modelos de Contratos Como escrever um curr?culo, como redigir documentos: Visite agora: http://www.gueb.de/modelosdecartascomerciais Modelos de cartas Convites, Propostas, Atas, Contratos, Agradecimentos, Empregos, Solicita??o, Solicita??es, Apresenta??o, Apresenta??es, Demiss?o, Demiss?es, Cobran?as, Pedidos, Atestados, Declara??es, Declara??o, P?sames, Condol?ncias, Batizados, Fomal, Formais, Redigir, Escrever, Escritas, Textos, Mensagens, Mensagem, Ingl?s, Clientes, Fornecedores, Empresas, Neg?cios, Marketing, Comunicados, Comunica??o, Secret?rias, Amigos, Parentes, Vendedores, Vendedoras, Refer?ncias, Social, Sociais, Respostas, Dicas, M?dicos, Advogados, Duplicatas, Felicita??o, Felicita??es, Recomenda??o, Recomenda??es, Funcion?rios, Reclama??o, Reclama??es, Comunicar, Comunicados, Documentos, Viagens, Viagem, Solenidades, Confraterniza??o, Confraterniza??es, Resultados, Pre?os, Aumentos, Entregas, F?rias, Estudantes, Lan?amentos, Novos, Aviso Pr?vio, Est?gios, Escolares, Protestos, D?bitos, Exposi??o, Exposi??es, Feiras, Acordos, Recibos, Procura??es, Edital, Editais" modelos de cartas de demiss?o, modelos de cartas com mensagem mensagens de p?sames, modelos de convites, modelos de declara??es, modelos de cartas de solicita??o de empregos, modelos de cartas de cobran?as, modelos de cartas de recomenda??o, modelos de cartas de recomenda??es, redigir cartas comerciais, modelos de propostas comerciais, modelos de respostas a propostas comerciais, dicas de como redigir, dicas de reda??o de cartas comerciais, modelos de pedidos. Visite agora: http://www.gueb.de/modelosdecartascomerciais modelos de cartas de demiss?o, modelos de cartas com mensagem mensagens de p?sames, modelos de convites, modelos de declara??es, modelos de cartas de solicita??o de empregos, modelos de cartas de cobran?as, modelos de cartas de recomenda??o, modelos de cartas de recomenda??es, redigir cartas comerciais, modelos de propostas comerciais, modelos de respostas a propostas comerciais, dicas de como redigir, dicas de reda??o de cartas comerciais, modelos de pedidos, modelos de atestados m?dicos. Modelos de cartas em ingl?s, modelos de cartas de reclama??o, modelos de cartas de refer?ncias, dicas de como escrever cartas comerciais, dicas de como redigir cartas comerciais, modelos de convites para festas, modelos de convites para eventos, modelos de cartas de pedidos de demiss?o, modelos de cartas de felicita??es, modelos de cartas formais, modelos de recibos, proposta de presta??o de servi?os, Modelos de Contratos Cartas Comerciais, cartas, contartos, modelos, empresa, contabilidade, advocacia, advogado, direito, procura??o, memorando. http://www.gueb.de/modelosdecartascomerciais propostas comerciais, dicas de como redigir, dicas de reda??o de cartas comerciais, modelos de pedidos, modelos de atestados m?dicos. Modelos de cartas em ingl?s, modelos de cartas de reclama??o, modelos de cartas de refer?ncias, dicas de como escrever cartas comerciais, dicas de como redigir cartas comerciais, modelos de convites para From gvanrossum at users.sourceforge.net Sat Oct 8 22:04:40 2005 From: gvanrossum at users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Sat, 8 Oct 2005 22:04:40 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib/test test_cmd_line.py, 1.1, 1.2 Message-ID: <20051008200440.52F061E4006@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7933 Modified Files: test_cmd_line.py Log Message: Fix unit test failure -- the output received from Python can be empty, but verify_valid_flag() wasn't expecting that. Will backport. Index: test_cmd_line.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_cmd_line.py,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- test_cmd_line.py 3 Oct 2005 00:54:57 -0000 1.1 +++ test_cmd_line.py 8 Oct 2005 20:04:36 -0000 1.2 @@ -17,7 +17,7 @@ def verify_valid_flag(self, cmd_line): data = self.start_python(cmd_line) - self.assertTrue(data.endswith('\n')) + self.assertTrue(data == '' or data.endswith('\n')) self.assertTrue('Traceback' not in data) def test_environment(self): From gvanrossum at users.sourceforge.net Sat Oct 8 22:04:58 2005 From: gvanrossum at users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Sat, 8 Oct 2005 22:04:58 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib/test test_cmd_line.py, 1.1.2.2, 1.1.2.3 Message-ID: <20051008200458.854F11E4006@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7994 Modified Files: Tag: release24-maint test_cmd_line.py Log Message: Fix unit test failure -- the output received from Python can be empty, but verify_valid_flag() wasn't expecting that. (Backport.) Index: test_cmd_line.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_cmd_line.py,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.3 diff -u -d -r1.1.2.2 -r1.1.2.3 --- test_cmd_line.py 3 Oct 2005 01:03:46 -0000 1.1.2.2 +++ test_cmd_line.py 8 Oct 2005 20:04:55 -0000 1.1.2.3 @@ -17,7 +17,7 @@ def verify_valid_flag(self, cmd_line): data = self.start_python(cmd_line) - self.assertTrue(data.endswith('\n')) + self.assertTrue(data == '' or data.endswith('\n')) self.assertTrue('Traceback' not in data) def test_environment(self): From birkenfeld at users.sourceforge.net Sat Oct 8 22:47:41 2005 From: birkenfeld at users.sourceforge.net (birkenfeld@users.sourceforge.net) Date: Sat, 8 Oct 2005 22:47:41 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib webbrowser.py,1.39,1.40 Message-ID: <20051008204741.A93BB1E4007@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16413/Lib Modified Files: webbrowser.py Log Message: Fix errors in _synthesize because of missing basename attribute of browser controller classes. Index: webbrowser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/webbrowser.py,v retrieving revision 1.39 retrieving revision 1.40 diff -u -d -r1.39 -r1.40 --- webbrowser.py 4 Oct 2005 03:17:49 -0000 1.39 +++ webbrowser.py 8 Oct 2005 20:47:38 -0000 1.40 @@ -133,6 +133,7 @@ def __init__(self, name=""): self.name = name + self.basename = name def open(self, url, new=0, autoraise=1): raise NotImplementedError @@ -150,6 +151,7 @@ def __init__(self, cmd): self.name, self.args = cmd.split(None, 1) + self.basename = os.path.basename(self.name) def open(self, url, new=0, autoraise=1): assert "'" not in url @@ -358,8 +360,10 @@ commd + " '%s' >/dev/null &")) # Konqueror/kfm, the KDE browser. - if _iscommand("kfm") or _iscommand("konqueror"): - register("kfm", Konqueror, Konqueror()) + if _iscommand("kfm"): + register("kfm", Konqueror, Konqueror("kfm")) + elif _iscommand("konqueror"): + register("konqueror", Konqueror, Konqueror("konqueror")) # Gnome's Galeon and Epiphany for browser in ("galeon", "epiphany"): From doerwalter at users.sourceforge.net Sun Oct 9 21:28:40 2005 From: doerwalter at users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Sun, 9 Oct 2005 21:28:40 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1387,1.1388 Message-ID: <20051009192840.54D041E4009@bag.python.org> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv436/Misc Modified Files: NEWS Log Message: Fix indentation. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1387 retrieving revision 1.1388 diff -u -d -r1.1387 -r1.1388 --- NEWS 6 Oct 2005 20:29:57 -0000 1.1387 +++ NEWS 9 Oct 2005 19:28:35 -0000 1.1388 @@ -29,7 +29,7 @@ represented as a C int, raise OverflowError. - test__locale is skipped on OS X < 10.4 (only partial locale support is -present). + present). - SF bug #893549: parsing keyword arguments was broken with a few format codes. From doerwalter at users.sourceforge.net Sun Oct 9 21:38:24 2005 From: doerwalter at users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Sun, 9 Oct 2005 21:38:24 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1388,1.1389 Message-ID: <20051009193824.95A5A1E400A@bag.python.org> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3159/Misc Modified Files: NEWS Log Message: Remove trailing spaces. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1388 retrieving revision 1.1389 diff -u -d -r1.1388 -r1.1389 --- NEWS 9 Oct 2005 19:28:35 -0000 1.1388 +++ NEWS 9 Oct 2005 19:38:21 -0000 1.1389 @@ -194,7 +194,7 @@ - Bug #728515: mmap.resize() now resizes the file on Unix as it did on Windows. -- Patch #1180695: Add nanosecond stat resolution, and st_gen, +- Patch #1180695: Add nanosecond stat resolution, and st_gen, st_birthtime for FreeBSD. - Patch #1231069: The fcntl.ioctl function now uses the 'I' code for @@ -256,7 +256,7 @@ - Patch #754022: Greatly enhanced webbrowser.py (by Oleg Broytmann). -- Bug #729103: pydoc.py: Fix docother() method to accept additional +- Bug #729103: pydoc.py: Fix docother() method to accept additional "parent" argument. - Patch #1300515: xdrlib.py: Fix pack_fstring() to really use null bytes @@ -293,7 +293,7 @@ - Bug #1178484: Return complete lines from codec stream readers even if there is an exception in later lines, resulting in - correct line numbers for decoding errors in source code. + correct line numbers for decoding errors in source code. - Bug #1192315: Disallow negative arguments to clear() in pdb. From doerwalter at users.sourceforge.net Sun Oct 9 21:41:23 2005 From: doerwalter at users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Sun, 9 Oct 2005 21:41:23 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib/encodings aliases.py, 1.28, 1.29 Message-ID: <20051009194123.C0C361E4009@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib/encodings In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3739/Lib/encodings Modified Files: aliases.py Log Message: Bug #1245379: Add "unicode-1-1-utf-7" as an alias for "utf-7" as specified by RFC 1642. Index: aliases.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/aliases.py,v retrieving revision 1.28 retrieving revision 1.29 diff -u -d -r1.28 -r1.29 --- aliases.py 10 Dec 2004 21:54:35 -0000 1.28 +++ aliases.py 9 Oct 2005 19:41:19 -0000 1.29 @@ -482,6 +482,7 @@ # utf_7 codec 'u7' : 'utf_7', 'utf7' : 'utf_7', + 'unicode_1_1_utf_7' : 'utf_7', # utf_8 codec 'u8' : 'utf_8', From doerwalter at users.sourceforge.net Sun Oct 9 21:41:23 2005 From: doerwalter at users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Sun, 9 Oct 2005 21:41:23 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/lib libcodecs.tex,1.36,1.37 Message-ID: <20051009194123.C24891E400A@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3739/Doc/lib Modified Files: libcodecs.tex Log Message: Bug #1245379: Add "unicode-1-1-utf-7" as an alias for "utf-7" as specified by RFC 1642. Index: libcodecs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcodecs.tex,v retrieving revision 1.36 retrieving revision 1.37 diff -u -d -r1.36 -r1.37 --- libcodecs.tex 24 Aug 2005 07:38:12 -0000 1.36 +++ libcodecs.tex 9 Oct 2005 19:41:20 -0000 1.37 @@ -883,7 +883,7 @@ {all languages (BMP only)} \lineiii{utf_7} - {U7} + {U7, unicode-1-1-utf-7} {all languages} \lineiii{utf_8} From doerwalter at users.sourceforge.net Sun Oct 9 21:42:31 2005 From: doerwalter at users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Sun, 9 Oct 2005 21:42:31 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1389,1.1390 Message-ID: <20051009194231.68DE21E400A@bag.python.org> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4070/Misc Modified Files: NEWS Log Message: Bug #1245379: Add "unicode-1-1-utf-7" as an alias for "utf-7" as specified by RFC 1642. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1389 retrieving revision 1.1390 diff -u -d -r1.1389 -r1.1390 --- NEWS 9 Oct 2005 19:38:21 -0000 1.1389 +++ NEWS 9 Oct 2005 19:42:27 -0000 1.1390 @@ -517,6 +517,8 @@ - Bug #1202493: Fixing SRE parser to handle '{}' as perl does, rather than considering it exactly like a '*'. +- Bug #1245379: Add "unicode-1-1-utf-7" as an alias for "utf-7" to + ``encodings.aliases``. Build ----- From kbk at users.sourceforge.net Mon Oct 10 02:05:36 2005 From: kbk at users.sourceforge.net (kbk@users.sourceforge.net) Date: Mon, 10 Oct 2005 02:05:36 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib/idlelib CallTipWindow.py, 1.7, 1.7.14.1 CallTips.py, 1.12, 1.12.6.1 EditorWindow.py, 1.69, 1.69.2.1 ParenMatch.py, 1.8, 1.8.6.1 PyParse.py, 1.5, 1.5.14.1 PyShell.py, 1.99, 1.99.2.1 config-extensions.def, 1.15, 1.15.6.1 configDialog.py, 1.62, 1.62.2.1 run.py, 1.32, 1.32.2.1 Message-ID: <20051010000536.0E73E1E4074@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib/idlelib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22453 Modified Files: Tag: IDLE-syntax-branch CallTipWindow.py CallTips.py EditorWindow.py ParenMatch.py PyParse.py PyShell.py config-extensions.def configDialog.py run.py Log Message: Noam Raphael 'syntax' patch 10Jul05 Index: CallTipWindow.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/idlelib/CallTipWindow.py,v retrieving revision 1.7 retrieving revision 1.7.14.1 diff -u -d -r1.7 -r1.7.14.1 --- CallTipWindow.py 31 Dec 2002 15:59:14 -0000 1.7 +++ CallTipWindow.py 10 Oct 2005 00:05:30 -0000 1.7.14.1 @@ -6,33 +6,65 @@ """ from Tkinter import * +HIDE_VIRTUAL_EVENT_NAME = "<>" +HIDE_SEQUENCES = ("", "") +CHECKHIDE_VIRTUAL_EVENT_NAME = "<>" +CHECKHIDE_SEQUENCES = ("", "") +CHECKHIDE_TIME = 100 # miliseconds + +MARK_RIGHT = "calltipwindowregion_right" + class CallTip: def __init__(self, widget): self.widget = widget - self.tipwindow = None - self.id = None - self.x = self.y = 0 + self.tipwindow = self.label = None + self.parenline = self.parencol = None + self.lastline = None + self.hideid = self.checkhideid = None - def showtip(self, text): - " Display text in calltip window" + def position_window(self): + """Check if needs to reposition the window, and if so - do it.""" + curline = int(self.widget.index("insert").split('.')[0]) + if curline == self.lastline: + return + self.lastline = curline + self.widget.see("insert") + if curline == self.parenline: + box = self.widget.bbox("%d.%d" % (self.parenline, + self.parencol)) + else: + box = self.widget.bbox("%d.0" % curline) + if not box: + box = list(self.widget.bbox("insert")) + # align to left of window + box[0] = 0 + box[2] = 0 + x = box[0] + self.widget.winfo_rootx() + 2 + y = box[1] + box[3] + self.widget.winfo_rooty() + self.tipwindow.wm_geometry("+%d+%d" % (x, y)) + + def showtip(self, text, parenleft, parenright): + """Show the calltip, bind events which will close it and reposition it. + """ # truncate overly long calltip if len(text) >= 79: text = text[:75] + ' ...' self.text = text if self.tipwindow or not self.text: return - self.widget.see("insert") - x, y, cx, cy = self.widget.bbox("insert") - x = x + self.widget.winfo_rootx() + 2 - y = y + cy + self.widget.winfo_rooty() + + self.widget.mark_set(MARK_RIGHT, parenright) + self.parenline, self.parencol = map( + int, self.widget.index(parenleft).split(".")) + self.tipwindow = tw = Toplevel(self.widget) + self.position_window() # XXX 12 Dec 2002 KBK The following command has two effects: It removes # the calltip window border (good) but also causes (at least on # Linux) the calltip to show as a top level window, burning through # any other window dragged over it. Also, shows on all viewports! tw.wm_overrideredirect(1) - tw.wm_geometry("+%d+%d" % (x, y)) try: # This command is only needed and available on Tk >= 8.4.0 for OSX # Without it, call tips intrude on the typing process by grabbing @@ -41,16 +73,66 @@ "help", "noActivates") except TclError: pass - label = Label(tw, text=self.text, justify=LEFT, - background="#ffffe0", relief=SOLID, borderwidth=1, - font = self.widget['font']) - label.pack() + self.label = Label(tw, text=self.text, justify=LEFT, + background="#ffffe0", relief=SOLID, borderwidth=1, + font = self.widget['font']) + self.label.pack() + + self.checkhideid = self.widget.bind(CHECKHIDE_VIRTUAL_EVENT_NAME, + self.checkhide_event) + for seq in CHECKHIDE_SEQUENCES: + self.widget.event_add(CHECKHIDE_VIRTUAL_EVENT_NAME, seq) + self.widget.after(CHECKHIDE_TIME, self.checkhide_event) + self.hideid = self.widget.bind(HIDE_VIRTUAL_EVENT_NAME, + self.hide_event) + for seq in HIDE_SEQUENCES: + self.widget.event_add(HIDE_VIRTUAL_EVENT_NAME, seq) + + def checkhide_event(self, event=None): + if not self.tipwindow: + # If the event was triggered by the same event that unbinded + # this function, the function will be called nevertheless, + # so do nothing in this case. + return + curline, curcol = map(int, self.widget.index("insert").split('.')) + if curline < self.parenline or \ + (curline == self.parenline and curcol <= self.parencol) or \ + self.widget.compare("insert", ">", MARK_RIGHT): + self.hidetip() + else: + self.position_window() + self.widget.after(CHECKHIDE_TIME, self.checkhide_event) + + def hide_event(self, event): + if not self.tipwindow: + # See the explanation in checkhide_event. + return + self.hidetip() def hidetip(self): - tw = self.tipwindow + if not self.tipwindow: + return + + for seq in CHECKHIDE_SEQUENCES: + self.widget.event_delete(CHECKHIDE_VIRTUAL_EVENT_NAME, seq) + self.widget.unbind(CHECKHIDE_VIRTUAL_EVENT_NAME, self.checkhideid) + self.checkhideid = None + for seq in HIDE_SEQUENCES: + self.widget.event_delete(HIDE_VIRTUAL_EVENT_NAME, seq) + self.widget.unbind(HIDE_VIRTUAL_EVENT_NAME, self.hideid) + self.hideid = None + + self.label.destroy() + self.label = None + self.tipwindow.destroy() self.tipwindow = None - if tw: - tw.destroy() + + self.widget.mark_unset(MARK_RIGHT) + self.parenline = self.parencol = self.lastline = None + + def is_active(self): + return bool(self.tipwindow) + ############################### Index: CallTips.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/idlelib/CallTips.py,v retrieving revision 1.12 retrieving revision 1.12.6.1 diff -u -d -r1.12 -r1.12.6.1 --- CallTips.py 4 May 2004 08:34:56 -0000 1.12 +++ CallTips.py 10 Oct 2005 00:05:30 -0000 1.12.6.1 @@ -3,21 +3,21 @@ Call Tips are floating windows which display function, class, and method parameter and docstring information when you type an opening parenthesis, and which disappear when you type a closing parenthesis. - -Future plans include extending the functionality to include class attributes. - """ import sys -import string import types import CallTipWindow +from HyperParser import HyperParser import __main__ class CallTips: menudefs = [ + ('edit', [ + ("Show call tip", "<>"), + ]) ] def __init__(self, editwin=None): @@ -36,51 +36,47 @@ # See __init__ for usage return CallTipWindow.CallTip(self.text) - def _remove_calltip_window(self): + def _remove_calltip_window(self, event=None): if self.calltip: self.calltip.hidetip() self.calltip = None - def paren_open_event(self, event): - self._remove_calltip_window() - name = self.get_name_at_cursor() - arg_text = self.fetch_tip(name) - if arg_text: - self.calltip_start = self.text.index("insert") - self.calltip = self._make_calltip_window() - self.calltip.showtip(arg_text) - return "" #so the event is handled normally. + def force_open_calltip_event(self, event): + """Happens when the user really wants to open a CallTip, even if a + function call is needed. + """ + self.open_calltip(True) - def paren_close_event(self, event): - # Now just hides, but later we should check if other - # paren'd expressions remain open. - self._remove_calltip_window() - return "" #so the event is handled normally. + def try_open_calltip_event(self, event): + """Happens when it would be nice to open a CallTip, but not really + neccesary, for example after an opening bracket, so function calls + won't be made. + """ + self.open_calltip(False) - def check_calltip_cancel_event(self, event): - if self.calltip: - # If we have moved before the start of the calltip, - # or off the calltip line, then cancel the tip. - # (Later need to be smarter about multi-line, etc) - if self.text.compare("insert", "<=", self.calltip_start) or \ - self.text.compare("insert", ">", self.calltip_start - + " lineend"): - self._remove_calltip_window() - return "" #so the event is handled normally. + def refresh_calltip_event(self, event): + """If there is already a calltip window, check if it is still needed, + and if so, reload it. + """ + if self.calltip and self.calltip.is_active(): + self.open_calltip(False) - def calltip_cancel_event(self, event): + def open_calltip(self, evalfuncs): self._remove_calltip_window() - return "" #so the event is handled normally. - - __IDCHARS = "._" + string.ascii_letters + string.digits - def get_name_at_cursor(self): - idchars = self.__IDCHARS - str = self.text.get("insert linestart", "insert") - i = len(str) - while i and str[i-1] in idchars: - i -= 1 - return str[i:] + hp = HyperParser(self.editwin, "insert") + sur_paren = hp.get_surrounding_brackets('(') + if not sur_paren: + return + hp.set_index(sur_paren[0]) + name = hp.get_expression() + if not name or (not evalfuncs and name.find('(') != -1): + return + arg_text = self.fetch_tip(name) + if not arg_text: + return + self.calltip = self._make_calltip_window() + self.calltip.showtip(arg_text, sur_paren[0], sur_paren[1]) def fetch_tip(self, name): """Return the argument list and docstring of a function or class @@ -127,7 +123,7 @@ return None def get_arg_text(ob): - "Get a string describing the arguments for the given object" + """Get a string describing the arguments for the given object""" argText = "" if ob is not None: argOffset = 0 @@ -150,7 +146,7 @@ try: realArgs = fob.func_code.co_varnames[argOffset:fob.func_code.co_argcount] defaults = fob.func_defaults or [] - defaults = list(map(lambda name: "=%s" % name, defaults)) + defaults = list(map(lambda name: "=%s" % repr(name), defaults)) defaults = [""] * (len(realArgs)-len(defaults)) + defaults items = map(lambda arg, dflt: arg+dflt, realArgs, defaults) if fob.func_code.co_flags & 0x4: Index: EditorWindow.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/idlelib/EditorWindow.py,v retrieving revision 1.69 retrieving revision 1.69.2.1 diff -u -d -r1.69 -r1.69.2.1 --- EditorWindow.py 12 Jun 2005 05:19:23 -0000 1.69 +++ EditorWindow.py 10 Oct 2005 00:05:30 -0000 1.69.2.1 @@ -6,6 +6,7 @@ from Tkinter import * import tkSimpleDialog import tkMessageBox +from MultiCall import MultiCallCreator import webbrowser import idlever @@ -89,7 +90,8 @@ self.vbar = vbar = Scrollbar(top, name='vbar') self.text_frame = text_frame = Frame(top) self.width = idleConf.GetOption('main','EditorWindow','width') - self.text = text = Text(text_frame, name='text', padx=5, wrap='none', + self.text = text = MultiCallCreator(Text)( + text_frame, name='text', padx=5, wrap='none', foreground=idleConf.GetHighlight(currentTheme, 'normal',fgBg='fg'), background=idleConf.GetHighlight(currentTheme, @@ -264,8 +266,9 @@ self.status_bar.set_label('column', 'Col: ?', side=RIGHT) self.status_bar.set_label('line', 'Ln: ?', side=RIGHT) self.status_bar.pack(side=BOTTOM, fill=X) - self.text.bind('', self.set_line_and_column) - self.text.bind('', self.set_line_and_column) + self.text.bind("<>", self.set_line_and_column) + self.text.event_add("<>", + "", "") self.text.after_idle(self.set_line_and_column) def set_line_and_column(self, event=None): @@ -355,6 +358,9 @@ return "break" def copy(self,event): + if not self.text.tag_ranges("sel"): + # There is no selection, so do nothing and maybe interrupt. + return self.text.event_generate("<>") return "break" @@ -557,14 +563,28 @@ idleConf.GetOption('main','EditorWindow','font-size'), fontWeight)) - def ResetKeybindings(self): - "Update the keybindings if they are changed" + def RemoveKeybindings(self): + "Remove the keybindings before they are changed." # Called from configDialog.py self.Bindings.default_keydefs=idleConf.GetCurrentKeySet() keydefs = self.Bindings.default_keydefs for event, keylist in keydefs.items(): - self.text.event_delete(event) + self.text.event_delete(event, *keylist) + for extensionName in self.get_standard_extension_names(): + keydefs = idleConf.GetExtensionBindings(extensionName) + if keydefs: + for event, keylist in keydefs.items(): + self.text.event_delete(event, *keylist) + + def ApplyKeybindings(self): + "Update the keybindings after they are changed" + # Called from configDialog.py + self.Bindings.default_keydefs=idleConf.GetCurrentKeySet() self.apply_bindings() + for extensionName in self.get_standard_extension_names(): + keydefs = idleConf.GetExtensionBindings(extensionName) + if keydefs: + self.apply_bindings(keydefs) #update menu accelerators menuEventDict={} for menu in self.Bindings.menudefs: @@ -1064,17 +1084,28 @@ # open/close first need to find the last stmt lno = index2line(text.index('insert')) y = PyParse.Parser(self.indentwidth, self.tabwidth) - for context in self.num_context_lines: - startat = max(lno - context, 1) - startatindex = repr(startat) + ".0" + if not self.context_use_ps1: + for context in self.num_context_lines: + startat = max(lno - context, 1) + startatindex = `startat` + ".0" + rawtext = text.get(startatindex, "insert") + y.set_str(rawtext) + bod = y.find_good_parse_start( + self.context_use_ps1, + self._build_char_in_string_func(startatindex)) + if bod is not None or startat == 1: + break + y.set_lo(bod or 0) + else: + r = text.tag_prevrange("console", "insert") + if r: + startatindex = r[1] + else: + startatindex = "1.0" rawtext = text.get(startatindex, "insert") y.set_str(rawtext) - bod = y.find_good_parse_start( - self.context_use_ps1, - self._build_char_in_string_func(startatindex)) - if bod is not None or startat == 1: - break - y.set_lo(bod or 0) + y.set_lo(0) + c = y.get_continuation_type() if c != PyParse.C_NONE: # The current stmt hasn't ended yet. Index: ParenMatch.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/idlelib/ParenMatch.py,v retrieving revision 1.8 retrieving revision 1.8.6.1 diff -u -d -r1.8 -r1.8.6.1 --- ParenMatch.py 12 Feb 2004 17:35:09 -0000 1.8 +++ ParenMatch.py 10 Oct 2005 00:05:30 -0000 1.8.6.1 @@ -3,17 +3,14 @@ When you hit a right paren, the cursor should move briefly to the left paren. Paren here is used generically; the matching applies to parentheses, square brackets, and curly braces. - -WARNING: This extension will fight with the CallTips extension, -because they both are interested in the KeyRelease-parenright event. -We'll have to fix IDLE to do something reasonable when two or more -extensions what to capture the same event. """ -import PyParse -from EditorWindow import EditorWindow, index2line +from HyperParser import HyperParser from configHandler import idleConf +keysym_opener = {"parenright":'(', "bracketright":'[', "braceright":'{'} +CHECK_DELAY = 100 # miliseconds + class ParenMatch: """Highlight matching parentheses @@ -31,7 +28,6 @@ expression from the left paren to the right paren. TODO: - - fix interaction with CallTips - extend IDLE with configuration dialog to change options - implement rest of Emacs highlight styles (see below) - print mismatch warning in IDLE status window @@ -41,7 +37,11 @@ to the right of a right paren. I don't know how to do that in Tk, so I haven't bothered. """ - menudefs = [] + menudefs = [ + ('edit', [ + ("Show surrounding parens", "<>"), + ]) + ] STYLE = idleConf.GetOption('extensions','ParenMatch','style', default='expression') FLASH_DELAY = idleConf.GetOption('extensions','ParenMatch','flash-delay', @@ -50,14 +50,36 @@ BELL = idleConf.GetOption('extensions','ParenMatch','bell', type='bool',default=1) + RESTORE_VIRTUAL_EVENT_NAME = "<>" + # We want the restore event be called before the usual return and + # backspace events. + RESTORE_SEQUENCES = ("", "", + "", "") + def __init__(self, editwin): self.editwin = editwin self.text = editwin.text - self.finder = LastOpenBracketFinder(editwin) + # Bind the check-restore event to the function restore_event, + # so that we can then use activate_restore (which calls event_add) + # and deactivate_restore (which calls event_delete). + editwin.text.bind(self.RESTORE_VIRTUAL_EVENT_NAME, + self.restore_event) self.counter = 0 - self._restore = None + self.is_restore_active = 0 self.set_style(self.STYLE) + def activate_restore(self): + if not self.is_restore_active: + for seq in self.RESTORE_SEQUENCES: + self.text.event_add(self.RESTORE_VIRTUAL_EVENT_NAME, seq) + self.is_restore_active = True + + def deactivate_restore(self): + if self.is_restore_active: + for seq in self.RESTORE_SEQUENCES: + self.text.event_delete(self.RESTORE_VIRTUAL_EVENT_NAME, seq) + self.is_restore_active = False + def set_style(self, style): self.STYLE = style if style == "default": @@ -67,23 +89,38 @@ self.create_tag = self.create_tag_expression self.set_timeout = self.set_timeout_none - def flash_open_paren_event(self, event): - index = self.finder.find(keysym_type(event.keysym)) - if index is None: + def flash_paren_event(self, event): + indices = HyperParser(self.editwin, "insert").get_surrounding_brackets() + if indices is None: self.warn_mismatched() return - self._restore = 1 - self.create_tag(index) + self.activate_restore() + self.create_tag(indices) + self.set_timeout_last() + + def paren_closed_event(self, event): + # If it was a shortcut and not really a closing paren, quit. + if self.text.get("insert-1c") not in (')',']','}'): + return + hp = HyperParser(self.editwin, "insert-1c") + if not hp.is_in_code(): + return + indices = hp.get_surrounding_brackets(keysym_opener[event.keysym], True) + if indices is None: + self.warn_mismatched() + return + self.activate_restore() + self.create_tag(indices) self.set_timeout() - def check_restore_event(self, event=None): - if self._restore: - self.text.tag_delete("paren") - self._restore = None + def restore_event(self, event=None): + self.text.tag_delete("paren") + self.deactivate_restore() + self.counter += 1 # disable the last timer, if there is one. def handle_restore_timer(self, timer_count): - if timer_count + 1 == self.counter: - self.check_restore_event() + if timer_count == self.counter: + self.restore_event() def warn_mismatched(self): if self.BELL: @@ -92,87 +129,44 @@ # any one of the create_tag_XXX methods can be used depending on # the style - def create_tag_default(self, index): + def create_tag_default(self, indices): """Highlight the single paren that matches""" - self.text.tag_add("paren", index) + self.text.tag_add("paren", indices[0]) self.text.tag_config("paren", self.HILITE_CONFIG) - def create_tag_expression(self, index): + def create_tag_expression(self, indices): """Highlight the entire expression""" - self.text.tag_add("paren", index, "insert") + if self.text.get(indices[1]) in (')', ']', '}'): + rightindex = indices[1]+"+1c" + else: + rightindex = indices[1] + self.text.tag_add("paren", indices[0], rightindex) self.text.tag_config("paren", self.HILITE_CONFIG) # any one of the set_timeout_XXX methods can be used depending on # the style def set_timeout_none(self): - """Highlight will remain until user input turns it off""" - pass + """Highlight will remain until user input turns it off + or the insert has moved""" + # After CHECK_DELAY, call a function which disables the "paren" tag + # if the event is for the most recent timer and the insert has changed, + # or schedules another call for itself. + self.counter += 1 + def callme(callme, self=self, c=self.counter, + index=self.text.index("insert")): + if index != self.text.index("insert"): + self.handle_restore_timer(c) + else: + self.editwin.text_frame.after(CHECK_DELAY, callme, callme) + self.editwin.text_frame.after(CHECK_DELAY, callme, callme) def set_timeout_last(self): """The last highlight created will be removed after .5 sec""" # associate a counter with an event; only disable the "paren" # tag if the event is for the most recent timer. + self.counter += 1 self.editwin.text_frame.after(self.FLASH_DELAY, lambda self=self, c=self.counter: \ self.handle_restore_timer(c)) - self.counter = self.counter + 1 - -def keysym_type(ks): - # Not all possible chars or keysyms are checked because of the - # limited context in which the function is used. - if ks == "parenright" or ks == "(": - return "paren" - if ks == "bracketright" or ks == "[": - return "bracket" - if ks == "braceright" or ks == "{": - return "brace" - -class LastOpenBracketFinder: - num_context_lines = EditorWindow.num_context_lines - indentwidth = EditorWindow.indentwidth - tabwidth = EditorWindow.tabwidth - context_use_ps1 = EditorWindow.context_use_ps1 - def __init__(self, editwin): - self.editwin = editwin - self.text = editwin.text - - def _find_offset_in_buf(self, lno): - y = PyParse.Parser(self.indentwidth, self.tabwidth) - for context in self.num_context_lines: - startat = max(lno - context, 1) - startatindex = repr(startat) + ".0" - # rawtext needs to contain everything up to the last - # character, which was the close paren. the parser also - # requires that the last line ends with "\n" - rawtext = self.text.get(startatindex, "insert")[:-1] + "\n" - y.set_str(rawtext) - bod = y.find_good_parse_start( - self.context_use_ps1, - self._build_char_in_string_func(startatindex)) - if bod is not None or startat == 1: - break - y.set_lo(bod or 0) - i = y.get_last_open_bracket_pos() - return i, y.str - - def find(self, right_keysym_type): - """Return the location of the last open paren""" - lno = index2line(self.text.index("insert")) - i, buf = self._find_offset_in_buf(lno) - if i is None \ - or keysym_type(buf[i]) != right_keysym_type: - return None - lines_back = buf[i:].count("\n") - 1 - # subtract one for the "\n" added to please the parser - upto_open = buf[:i] - j = upto_open.rfind("\n") + 1 # offset of column 0 of line - offset = i - j - return "%d.%d" % (lno - lines_back, offset) - - def _build_char_in_string_func(self, startindex): - def inner(offset, startindex=startindex, - icis=self.editwin.is_char_in_string): - return icis(startindex + "%dc" % offset) - return inner Index: PyParse.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/idlelib/PyParse.py,v retrieving revision 1.5 retrieving revision 1.5.14.1 diff -u -d -r1.5 -r1.5.14.1 --- PyParse.py 17 Sep 2002 03:55:13 -0000 1.5 +++ PyParse.py 10 Oct 2005 00:05:30 -0000 1.5.14.1 @@ -13,9 +13,7 @@ _synchre = re.compile(r""" ^ [ \t]* - (?: if - | for - | while + (?: while | else | def | return @@ -144,29 +142,11 @@ # This will be reliable iff given a reliable is_char_in_string # function, meaning that when it says "no", it's absolutely # guaranteed that the char is not in a string. - # - # Ack, hack: in the shell window this kills us, because there's - # no way to tell the differences between output, >>> etc and - # user input. Indeed, IDLE's first output line makes the rest - # look like it's in an unclosed paren!: - # Python 1.5.2 (#0, Apr 13 1999, ... - def find_good_parse_start(self, use_ps1, is_char_in_string=None, + def find_good_parse_start(self, is_char_in_string=None, _synchre=_synchre): str, pos = self.str, None - if use_ps1: - # shell window - ps1 = '\n' + sys.ps1 - i = str.rfind(ps1) - if i >= 0: - pos = i + len(ps1) - # make it look like there's a newline instead - # of ps1 at the start -- hacking here once avoids - # repeated hackery later - self.str = str[:pos-1] + '\n' + str[pos:] - return pos - # File window -- real work. if not is_char_in_string: # no clue -- make the caller pass everything return None @@ -355,6 +335,11 @@ # Creates: # self.stmt_start, stmt_end # slice indices of last interesting stmt + # self.stmt_bracketing + # the bracketing structure of the last interesting stmt; + # for example, for the statement "say(boo) or die", stmt_bracketing + # will be [(0, 0), (3, 1), (8, 0)]. Strings and comments are + # treated as brackets, for the matter. # self.lastch # last non-whitespace character before optional trailing # comment @@ -396,6 +381,7 @@ lastch = "" stack = [] # stack of open bracket indices push_stack = stack.append + bracketing = [(p, 0)] while p < q: # suck up all except ()[]{}'"#\\ m = _chew_ordinaryre(str, p, q) @@ -416,6 +402,7 @@ if ch in "([{": push_stack(p) + bracketing.append((p, len(stack))) lastch = ch p = p+1 continue @@ -425,6 +412,7 @@ del stack[-1] lastch = ch p = p+1 + bracketing.append((p, len(stack))) continue if ch == '"' or ch == "'": @@ -435,14 +423,18 @@ # strings to a couple of characters per line. study1 # also needed to keep track of newlines, and we don't # have to. + bracketing.append((p, len(stack)+1)) lastch = ch p = _match_stringre(str, p, q).end() + bracketing.append((p, len(stack))) continue if ch == '#': # consume comment and trailing newline + bracketing.append((p, len(stack)+1)) p = str.find('\n', p, q) + 1 assert p > 0 + bracketing.append((p, len(stack))) continue assert ch == '\\' @@ -458,6 +450,7 @@ self.lastch = lastch if stack: self.lastopenbracketpos = stack[-1] + self.stmt_bracketing = tuple(bracketing) # Assuming continuation is C_BRACKET, return the number # of spaces the next line should be indented. @@ -582,3 +575,12 @@ def get_last_open_bracket_pos(self): self._study2() return self.lastopenbracketpos + + # the structure of the bracketing of the last interesting statement, + # in the format defined in _study2, or None if the text didn't contain + # anything + stmt_bracketing = None + + def get_last_stmt_bracketing(self): + self._study2() + return self.stmt_bracketing Index: PyShell.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/idlelib/PyShell.py,v retrieving revision 1.99 retrieving revision 1.99.2.1 diff -u -d -r1.99 -r1.99.2.1 --- PyShell.py 1 Sep 2005 00:39:02 -0000 1.99 +++ PyShell.py 10 Oct 2005 00:05:30 -0000 1.99.2.1 @@ -1091,11 +1091,12 @@ self.recall(self.text.get(next[0], next[1]), event) return "break" # No stdin mark -- just get the current line, less any prompt - line = self.text.get("insert linestart", "insert lineend") - last_line_of_prompt = sys.ps1.split('\n')[-1] - if line.startswith(last_line_of_prompt): - line = line[len(last_line_of_prompt):] - self.recall(line, event) + indices = self.text.tag_nextrange("console", "insert linestart") + if indices and \ + self.text.compare(indices[0], "<=", "insert linestart"): + self.recall(self.text.get(indices[1], "insert lineend"), event) + else: + self.recall(self.text.get("insert linestart", "insert lineend"), event) return "break" # If we're between the beginning of the line and the iomark, i.e. # in the prompt area, move to the end of the prompt Index: config-extensions.def =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/idlelib/config-extensions.def,v retrieving revision 1.15 retrieving revision 1.15.6.1 diff -u -d -r1.15 -r1.15.6.1 --- config-extensions.def 6 Jun 2004 01:29:22 -0000 1.15 +++ config-extensions.def 10 Oct 2005 00:05:30 -0000 1.15.6.1 @@ -52,22 +52,30 @@ [CallTips] enable=1 +[CallTips_cfgBindings] +force-open-calltip= [CallTips_bindings] -paren-open= -paren-close= -check-calltip-cancel= -calltip-cancel= +try-open-calltip= +refresh-calltip= [ParenMatch] -enable=0 +enable=1 style= expression flash-delay= 500 bell= 1 -hilite-foreground= black -hilite-background= #43cd80 +[ParenMatch_cfgBindings] +flash-paren= [ParenMatch_bindings] -flash-open-paren= -check-restore= +paren-closed= + +[AutoComplete] +enable=1 +popupwait=0 +[AutoComplete_cfgBindings] +force-open-completions= +[AutoComplete_bindings] +autocomplete= +try-open-completions= [CodeContext] enable=1 Index: configDialog.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/idlelib/configDialog.py,v retrieving revision 1.62 retrieving revision 1.62.2.1 diff -u -d -r1.62 -r1.62.2.1 --- configDialog.py 22 Jul 2005 21:49:29 -0000 1.62 +++ configDialog.py 10 Oct 2005 00:05:30 -0000 1.62.2.1 @@ -1106,6 +1106,13 @@ idleConf.userCfg[configType].Save() self.ResetChangedItems() #clear the changed items dict + def DeactivateCurrentConfig(self): + #Before a config is saved, some cleanup of current + #config must be done - remove the previous keybindings + winInstances=self.parent.instance_dict.keys() + for instance in winInstances: + instance.RemoveKeybindings() + def ActivateConfigChanges(self): "Dynamically apply configuration changes" winInstances=self.parent.instance_dict.keys() @@ -1113,7 +1120,7 @@ instance.ResetColorizer() instance.ResetFont() instance.set_notabs_indentwidth() - instance.ResetKeybindings() + instance.ApplyKeybindings() instance.reset_help_menu_entries() def Cancel(self): @@ -1124,6 +1131,7 @@ self.destroy() def Apply(self): + self.DeactivateCurrentConfig() self.SaveAllChangedConfigs() self.ActivateConfigChanges() Index: run.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/idlelib/run.py,v retrieving revision 1.32 retrieving revision 1.32.2.1 diff -u -d -r1.32 -r1.32.2.1 --- run.py 5 May 2005 23:29:54 -0000 1.32 +++ run.py 10 Oct 2005 00:05:31 -0000 1.32.2.1 @@ -9,6 +9,8 @@ import Queue import CallTips +import AutoComplete + import RemoteDebugger import RemoteObjectBrowser import StackViewer @@ -275,6 +277,7 @@ self.rpchandler = rpchandler self.locals = __main__.__dict__ self.calltip = CallTips.CallTips() + self.autocomplete = AutoComplete.AutoComplete() def runcode(self, code): try: @@ -305,6 +308,9 @@ def get_the_calltip(self, name): return self.calltip.fetch_tip(name) + def get_the_completion_list(self, what, mode): + return self.autocomplete.fetch_completions(what, mode) + def stackviewer(self, flist_oid=None): if self.usr_exc_info: typ, val, tb = self.usr_exc_info From jhylton at users.sourceforge.net Mon Oct 10 17:50:45 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Mon, 10 Oct 2005 17:50:45 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib/test test_doctest.py, 1.4.14.2, 1.4.14.3 Message-ID: <20051010155045.D9E271E4007@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20137 Modified Files: Tag: ast-branch test_doctest.py Log Message: Compiler now generates the name "" instead of "?" Index: test_doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_doctest.py,v retrieving revision 1.4.14.2 retrieving revision 1.4.14.3 diff -u -d -r1.4.14.2 -r1.4.14.3 --- test_doctest.py 7 Jan 2005 06:58:52 -0000 1.4.14.2 +++ test_doctest.py 10 Oct 2005 15:50:41 -0000 1.4.14.3 @@ -1556,11 +1556,11 @@ >>> try: doctest.debug_src(s) ... finally: sys.stdin = real_stdin - > (1)?() + > (1)() (Pdb) next 12 --Return-- - > (1)?()->None + > (1)()->None (Pdb) print x 12 (Pdb) continue @@ -1598,7 +1598,7 @@ >>> try: runner.run(test) ... finally: sys.stdin = real_stdin --Return-- - > (1)?()->None + > (1)()->None -> import pdb; pdb.set_trace() (Pdb) print x 42 @@ -1634,7 +1634,7 @@ (Pdb) print y 2 (Pdb) up - > (1)?() + > (1)() -> calls_set_trace() (Pdb) print x 1 @@ -1683,7 +1683,7 @@ [EOF] (Pdb) next --Return-- - > (1)?()->None + > (1)()->None -> f(3) (Pdb) list 1 -> f(3) @@ -1776,7 +1776,7 @@ (Pdb) print y 1 (Pdb) up - > (1)?() + > (1)() -> calls_set_trace() (Pdb) print foo *** NameError: name 'foo' is not defined From kbk at users.sourceforge.net Mon Oct 10 19:37:51 2005 From: kbk at users.sourceforge.net (kbk@users.sourceforge.net) Date: Mon, 10 Oct 2005 19:37:51 +0200 (CEST) Subject: [Python-checkins] python/nondist/peps pep-0227.txt,1.10,1.11 Message-ID: <20051010173751.011C91E400A@bag.python.org> Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21834 Modified Files: pep-0227.txt Log Message: Fix type and dead link Index: pep-0227.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0227.txt,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- pep-0227.txt 12 Jun 2003 13:54:00 -0000 1.10 +++ pep-0227.txt 10 Oct 2005 17:37:48 -0000 1.11 @@ -118,9 +118,9 @@ contained within a class definition, the name bindings that occur in the class block are not visible to enclosed functions.) - A class definition is an executable statement that may uses and - definitions of names. These references follow the normal rules - for name resolution. The namespace of the class definition + A class definition is an executable statement that may contain + uses and definitions of names. These references follow the normal + rules for name resolution. The namespace of the class definition becomes the attribute dictionary of the class. The following operations are name binding operations. If they @@ -489,7 +489,7 @@ [1] Luca Cardelli. Compiling a functional language. In Proc. of the 1984 ACM Conference on Lisp and Functional Programming, pp. 208-217, Aug. 1984 - http://citeseer.nj.nec.com/cardelli84compiling.html + http://citeseer.ist.psu.edu/cardelli84compiling.html Copyright From lemburg at users.sourceforge.net Mon Oct 10 21:08:45 2005 From: lemburg at users.sourceforge.net (lemburg@users.sourceforge.net) Date: Mon, 10 Oct 2005 21:08:45 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/api concrete.tex,1.68,1.69 Message-ID: <20051010190845.78DEA1E4007@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/api In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19085/Doc/api Modified Files: concrete.tex Log Message: Clarify the docs for Py_UNICODE. Index: concrete.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/concrete.tex,v retrieving revision 1.68 retrieving revision 1.69 diff -u -d -r1.68 -r1.69 --- concrete.tex 6 Oct 2005 20:29:57 -0000 1.68 +++ concrete.tex 10 Oct 2005 19:08:41 -0000 1.69 @@ -787,14 +787,24 @@ implementation in Python: \begin{ctypedesc}{Py_UNICODE} - This type represents a 16-bit unsigned storage type which is used by - Python internally as basis for holding Unicode ordinals. On - platforms where \ctype{wchar_t} is available and also has 16-bits, - \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 \ctype{unsigned short}. + 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). \end{ctypedesc} +Note that UCS2 and UCS4 Python builds are not binary compatible. +Please keep this in mind when writing extensions or interfaces. + \begin{ctypedesc}{PyUnicodeObject} This subtype of \ctype{PyObject} represents a Python Unicode object. \end{ctypedesc} From montanaro at users.sourceforge.net Tue Oct 11 00:03:17 2005 From: montanaro at users.sourceforge.net (montanaro@users.sourceforge.net) Date: Tue, 11 Oct 2005 00:03:17 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/api concrete.tex, 1.58.2.4, 1.58.2.5 Message-ID: <20051010220317.2AA7B1E400A@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/api In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4229 Modified Files: Tag: release24-maint concrete.tex Log Message: backport Py_UNICODE clarification Index: concrete.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/concrete.tex,v retrieving revision 1.58.2.4 retrieving revision 1.58.2.5 diff -u -d -r1.58.2.4 -r1.58.2.5 --- concrete.tex 28 Sep 2005 12:53:22 -0000 1.58.2.4 +++ concrete.tex 10 Oct 2005 22:03:12 -0000 1.58.2.5 @@ -787,14 +787,24 @@ implementation in Python: \begin{ctypedesc}{Py_UNICODE} - This type represents a 16-bit unsigned storage type which is used by - Python internally as basis for holding Unicode ordinals. On - platforms where \ctype{wchar_t} is available and also has 16-bits, - \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 \ctype{unsigned short}. + 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). \end{ctypedesc} +Note that UCS2 and UCS4 Python builds are not binary compatible. +Please keep this in mind when writing extensions or interfaces. + \begin{ctypedesc}{PyUnicodeObject} This subtype of \ctype{PyObject} represents a Python Unicode object. \end{ctypedesc} From nnorwitz at users.sourceforge.net Tue Oct 11 05:23:48 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Tue, 11 Oct 2005 05:23:48 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/lib libnew.tex,1.10,1.11 Message-ID: <20051011032348.6ED421E4007@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20449/lib Modified Files: libnew.tex Log Message: SF bug #1323294, Minor error in the Library Reference doc. Will backport Index: libnew.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libnew.tex,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- libnew.tex 17 Aug 2004 02:31:55 -0000 1.10 +++ libnew.tex 11 Oct 2005 03:23:45 -0000 1.11 @@ -47,9 +47,10 @@ %XXX This is still undocumented!!!!!!!!!!! \end{funcdesc} -\begin{funcdesc}{module}{name} +\begin{funcdesc}{module}{name[, doc]} This function returns a new module object with name \var{name}. \var{name} must be a string. +The optional \var{doc} argument can have any type. \end{funcdesc} \begin{funcdesc}{classobj}{name, baseclasses, dict} From nnorwitz at users.sourceforge.net Tue Oct 11 05:24:32 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Tue, 11 Oct 2005 05:24:32 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/lib libnew.tex, 1.10, 1.10.2.1 Message-ID: <20051011032432.1F4A71E4007@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20583/Doc/lib Modified Files: Tag: release24-maint libnew.tex Log Message: Backport: SF bug #1323294, Minor error in the Library Reference doc. Index: libnew.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libnew.tex,v retrieving revision 1.10 retrieving revision 1.10.2.1 diff -u -d -r1.10 -r1.10.2.1 --- libnew.tex 17 Aug 2004 02:31:55 -0000 1.10 +++ libnew.tex 11 Oct 2005 03:24:28 -0000 1.10.2.1 @@ -47,9 +47,10 @@ %XXX This is still undocumented!!!!!!!!!!! \end{funcdesc} -\begin{funcdesc}{module}{name} +\begin{funcdesc}{module}{name[, doc]} This function returns a new module object with name \var{name}. \var{name} must be a string. +The optional \var{doc} argument can have any type. \end{funcdesc} \begin{funcdesc}{classobj}{name, baseclasses, dict} From vsajip at users.sourceforge.net Tue Oct 11 15:15:34 2005 From: vsajip at users.sourceforge.net (vsajip@users.sourceforge.net) Date: Tue, 11 Oct 2005 15:15:34 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib/logging handlers.py, 1.21, 1.22 Message-ID: <20051011131534.A557A1E400B@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib/logging In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17965 Modified Files: handlers.py Log Message: Added Host and Content-type headers to requests sent by HTTPHandler (suggested by Steven Vereecken) Index: handlers.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/logging/handlers.py,v retrieving revision 1.21 retrieving revision 1.22 diff -u -d -r1.21 -r1.22 --- handlers.py 13 Mar 2005 09:56:36 -0000 1.21 +++ handlers.py 11 Oct 2005 13:15:31 -0000 1.22 @@ -854,7 +854,8 @@ """ try: import httplib, urllib - h = httplib.HTTP(self.host) + host = self.host + h = httplib.HTTP(host) url = self.url data = urllib.urlencode(self.mapLogRecord(record)) if self.method == "GET": @@ -864,7 +865,15 @@ sep = '?' url = url + "%c%s" % (sep, data) h.putrequest(self.method, url) + # support multiple hosts on one IP address... + # need to strip optional :port from host, if present + i = string.find(host, ":") + if i >= 0: + host = host[:i] + h.putheader("Host", host) if self.method == "POST": + h.putheader("Content-type", + "application/x-www-form-urlencoded") h.putheader("Content-length", str(len(data))) h.endheaders() if self.method == "POST": From vsajip at users.sourceforge.net Tue Oct 11 15:16:50 2005 From: vsajip at users.sourceforge.net (vsajip@users.sourceforge.net) Date: Tue, 11 Oct 2005 15:16:50 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib/logging handlers.py, 1.19.2.1, 1.19.2.2 Message-ID: <20051011131650.0174D1E400C@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib/logging In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18281 Modified Files: Tag: release24-maint handlers.py Log Message: Added Host and Content-type headers to requests sent by HTTPHandler (suggested by Steven Vereecken) Index: handlers.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/logging/handlers.py,v retrieving revision 1.19.2.1 retrieving revision 1.19.2.2 diff -u -d -r1.19.2.1 -r1.19.2.2 --- handlers.py 31 Mar 2005 20:12:55 -0000 1.19.2.1 +++ handlers.py 11 Oct 2005 13:16:46 -0000 1.19.2.2 @@ -854,7 +854,8 @@ """ try: import httplib, urllib - h = httplib.HTTP(self.host) + host = self.host + h = httplib.HTTP(host) url = self.url data = urllib.urlencode(self.mapLogRecord(record)) if self.method == "GET": @@ -864,7 +865,15 @@ sep = '?' url = url + "%c%s" % (sep, data) h.putrequest(self.method, url) + # support multiple hosts on one IP address... + # need to strip optional :port from host, if present + i = string.find(host, ":") + if i >= 0: + host = host[:i] + h.putheader("Host", host) if self.method == "POST": + h.putheader("Content-type", + "application/x-www-form-urlencoded") h.putheader("Content-length", str(len(data))) h.endheaders() if self.method == "POST": From jhylton at users.sourceforge.net Tue Oct 11 21:18:14 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Tue, 11 Oct 2005 21:18:14 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Include symtable.h, 2.9.18.12, 2.9.18.13 Message-ID: <20051011191814.F3C591E4002@bag.python.org> Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20508/Include Modified Files: Tag: ast-branch symtable.h Log Message: Fix symbol table to catch several scoping syntax errors. It's illegal to mix import * or bare exec with nested scopes, because there is no unambiguous way to decide whether to treat variables are free variables or globals. The symbol table change a bit to detect these errors. ste_optimized was renamed ste_unoptimized, to match its use: It contains a non-zero value with an unoptimized namespace (e.g. LOAD_NAME) will be used. Since the top-level uses LOAD_NAME, added OPT_TOPLEVEL along with the other OPT_ defines. Add an ste_free flag as a cheap way to tell if a block has free variables, including those inherited from children. Actually compute ste_free_child and ste_opt_lineno. Track rename of ste_optimized to ste_unoptimized in symbol table and compiler. Fixes test_scope. Index: symtable.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/symtable.h,v retrieving revision 2.9.18.12 retrieving revision 2.9.18.13 diff -u -d -r2.9.18.12 -r2.9.18.13 --- symtable.h 9 Jan 2005 18:49:43 -0000 2.9.18.12 +++ symtable.h 11 Oct 2005 19:18:11 -0000 2.9.18.13 @@ -30,8 +30,9 @@ PyObject *ste_varnames; /* list of variable names */ PyObject *ste_children; /* list of child ids */ block_ty ste_type; /* module, class, or function */ - int ste_optimized : 1; /* true if namespace can be optimized */ + int ste_unoptimized; /* false if namespace is optimized */ int ste_nested : 1; /* true if block is nested */ + int ste_free : 1; /* true if block has free variables */ int ste_child_free : 1; /* true if a child block has free variables, including free refs to globals */ int ste_generator : 1; /* true if namespace is a generator */ @@ -86,9 +87,11 @@ #define FREE 4 #define CELL 5 +/* The following three names are used for the ste_unoptimized bit field */ #define OPT_IMPORT_STAR 1 #define OPT_EXEC 2 #define OPT_BARE_EXEC 4 +#define OPT_TOPLEVEL 8 /* top-level names, including eval and exec */ #define GENERATOR 1 #define GENERATOR_EXPRESSION 2 From jhylton at users.sourceforge.net Tue Oct 11 21:18:15 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Tue, 11 Oct 2005 21:18:15 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Python symtable.c, 2.10.8.36, 2.10.8.37 newcompile.c, 1.1.2.111, 1.1.2.112 Message-ID: <20051011191815.719551E4002@bag.python.org> Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20508/Python Modified Files: Tag: ast-branch symtable.c newcompile.c Log Message: Fix symbol table to catch several scoping syntax errors. It's illegal to mix import * or bare exec with nested scopes, because there is no unambiguous way to decide whether to treat variables are free variables or globals. The symbol table change a bit to detect these errors. ste_optimized was renamed ste_unoptimized, to match its use: It contains a non-zero value with an unoptimized namespace (e.g. LOAD_NAME) will be used. Since the top-level uses LOAD_NAME, added OPT_TOPLEVEL along with the other OPT_ defines. Add an ste_free flag as a cheap way to tell if a block has free variables, including those inherited from children. Actually compute ste_free_child and ste_opt_lineno. Track rename of ste_optimized to ste_unoptimized in symbol table and compiler. Fixes test_scope. Index: symtable.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/symtable.c,v retrieving revision 2.10.8.36 retrieving revision 2.10.8.37 diff -u -d -r2.10.8.36 -r2.10.8.37 --- symtable.c 31 Aug 2005 01:48:41 -0000 2.10.8.36 +++ symtable.c 11 Oct 2005 19:18:11 -0000 2.10.8.37 @@ -47,14 +47,15 @@ ste->ste_children = v; ste->ste_type = block; - ste->ste_optimized = block == FunctionBlock; + ste->ste_unoptimized = 0; + ste->ste_nested = 0; + ste->ste_free = 0; ste->ste_varargs = 0; ste->ste_varkeywords = 0; ste->ste_opt_lineno = 0; ste->ste_tmpname = 0; ste->ste_lineno = lineno; - ste->ste_nested = 0; if (st->st_cur != NULL && (st->st_cur->ste_nested || st->st_cur->ste_type == FunctionBlock)) @@ -214,6 +215,7 @@ symtable_enter_block(st, GET_IDENTIFIER(top), ModuleBlock, (void *)mod, 0); st->st_top = st->st_cur; + st->st_cur->ste_unoptimized = OPT_TOPLEVEL; /* Any other top-level initialization? */ switch (mod->kind) { case Module_kind: @@ -222,7 +224,7 @@ if (!symtable_visit_stmt(st, asdl_seq_GET(seq, i))) goto error; break; - case Expression_kind: + case Expression_kind: if (!symtable_visit_expr(st, mod->v.Expression.body)) goto error; break; @@ -335,11 +337,13 @@ /* Decide on scope of name, given flags. The dicts passed in as arguments are modified as necessary. + ste is passed so that flags can be updated. */ static int -analyze_name(PyObject *dict, PyObject *name, int flags, PyObject *bound, - PyObject *local, PyObject *free, PyObject *global, int nested) +analyze_name(PySTEntryObject *ste, PyObject *dict, PyObject *name, int flags, + PyObject *bound, PyObject *local, PyObject *free, + PyObject *global) { if (flags & DEF_GLOBAL) { if (flags & DEF_PARAM) { @@ -374,6 +378,7 @@ */ if (bound && PyDict_GetItem(bound, name)) { SET_SCOPE(dict, name, FREE); + ste->ste_free = 1; if (PyDict_SetItem(free, name, Py_None) < 0) return 0; return 1; @@ -386,6 +391,8 @@ return 1; } else { + if (ste->ste_nested) + ste->ste_free = 1; SET_SCOPE(dict, name, GLOBAL_IMPLICIT); return 1; } @@ -433,7 +440,53 @@ return success; } -/* Enter the final scope information into the st_symbols dict. */ +/* Check for illegal statements in unoptimized namespaces */ +static int +check_unoptimized(const PySTEntryObject* ste) { + char buf[300]; + + if (ste->ste_type == ModuleBlock || !ste->ste_unoptimized + || !(ste->ste_free || ste->ste_child_free)) + return 1; + + const char* trailer = (ste->ste_child_free ? + "contains a nested function with free variables" : + "is a nested function"); + + switch (ste->ste_unoptimized) { + case OPT_TOPLEVEL: /* exec / import * at top-level is fine */ + case OPT_EXEC: /* qualified exec is fine */ + return 1; + case OPT_IMPORT_STAR: + PyOS_snprintf(buf, sizeof(buf), + "import * is not allowed in function '%.100s' " + "because it is %s", + PyString_AS_STRING(ste->ste_name), trailer); + break; + case OPT_BARE_EXEC: + PyOS_snprintf(buf, sizeof(buf), + "unqualified exec is not allowed in function " + "'%.100s' it %s", + PyString_AS_STRING(ste->ste_name), trailer); + break; + default: + PyOS_snprintf(buf, sizeof(buf), + "function '%.100s' uses import * and bare exec, " + "which are illegal because it %s", + PyString_AS_STRING(ste->ste_name), trailer); + break; + } + + PyErr_SetString(PyExc_SyntaxError, buf); + PyErr_SyntaxLocation(ste->ste_table->st_filename, + ste->ste_opt_lineno); + return 0; +} + +/* Enter the final scope information into the st_symbols dict. + * + * All arguments are dicts. Modifies symbols, others are read-only. +*/ static int update_symbols(PyObject *symbols, PyObject *scope, PyObject *bound, PyObject *free, int class) @@ -501,11 +554,11 @@ /* Make final symbol table decisions for block of ste. Arguments: + ste -- current symtable entry (input/output) bound -- set of variables bound in enclosing scopes (input) free -- set of free variables in enclosed scopes (output) globals -- set of declared global variables in enclosing scopes (input) */ - static int analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free, @@ -547,8 +600,8 @@ assert(PyDict_Check(ste->ste_symbols)); while (PyDict_Next(ste->ste_symbols, &pos, &name, &v)) { flags = PyInt_AS_LONG(v); - if (!analyze_name(scope, name, flags, bound, local, free, - global, ste->ste_nested)) + if (!analyze_name(ste, scope, name, flags, bound, local, free, + global)) goto error; } @@ -565,12 +618,15 @@ goto error; } + /* Recursively call analyze_block() on each child block */ for (i = 0; i < PyList_GET_SIZE(ste->ste_children); ++i) { PyObject *c = PyList_GET_ITEM(ste->ste_children, i); assert(c && PySTEntry_Check(c)); - if (!analyze_block((PySTEntryObject *)c, newbound, newfree, - newglobal)) + PySTEntryObject* entry = (PySTEntryObject*)c; + if (!analyze_block(entry, newbound, newfree, newglobal)) goto error; + if (entry->ste_free || entry->ste_child_free) + ste->ste_child_free = 1; } if (ste->ste_type == FunctionBlock && !analyze_cells(scope, newfree)) @@ -578,6 +634,8 @@ if (!update_symbols(ste->ste_symbols, scope, bound, newfree, ste->ste_type == ClassBlock)) goto error; + if (!check_unoptimized(ste)) + goto error; if (PyDict_Update(free, newfree) < 0) goto error; @@ -871,17 +929,29 @@ break; case Import_kind: VISIT_SEQ(st, alias, s->v.Import.names); + /* XXX Don't have the lineno available inside + visit_alias */ + if (st->st_cur->ste_unoptimized && !st->st_cur->ste_opt_lineno) + st->st_cur->ste_opt_lineno = s->lineno; break; case ImportFrom_kind: VISIT_SEQ(st, alias, s->v.ImportFrom.names); + /* XXX Don't have the lineno available inside + visit_alias */ + if (st->st_cur->ste_unoptimized && !st->st_cur->ste_opt_lineno) + st->st_cur->ste_opt_lineno = s->lineno; break; case Exec_kind: VISIT(st, expr, s->v.Exec.body); - st->st_cur->ste_optimized = 0; + if (!st->st_cur->ste_opt_lineno) + st->st_cur->ste_opt_lineno = s->lineno; if (s->v.Exec.globals) { + st->st_cur->ste_unoptimized |= OPT_EXEC; VISIT(st, expr, s->v.Exec.globals); if (s->v.Exec.locals) VISIT(st, expr, s->v.Exec.locals); + } else { + st->st_cur->ste_unoptimized |= OPT_BARE_EXEC; } break; case Global_kind: { @@ -1134,7 +1204,7 @@ "import * only allowed at module level")) return 0; } - st->st_cur->ste_optimized = 0; + st->st_cur->ste_unoptimized |= OPT_IMPORT_STAR; return 1; } } Index: newcompile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/Attic/newcompile.c,v retrieving revision 1.1.2.111 retrieving revision 1.1.2.112 diff -u -d -r1.1.2.111 -r1.1.2.112 --- newcompile.c 7 Oct 2005 18:42:50 -0000 1.1.2.111 +++ newcompile.c 11 Oct 2005 19:18:11 -0000 1.1.2.112 @@ -2289,7 +2289,7 @@ optype = OP_FAST; break; case GLOBAL_IMPLICIT: - if (c->u->u_ste->ste_optimized) + if (!c->u->u_ste->ste_unoptimized) optype = OP_GLOBAL; break; case GLOBAL_EXPLICIT: @@ -3490,7 +3490,7 @@ if (ste->ste_type != ModuleBlock) flags |= CO_NEWLOCALS; if (ste->ste_type == FunctionBlock) { - if (ste->ste_optimized) + if (!ste->ste_unoptimized) flags |= CO_OPTIMIZED; if (ste->ste_nested) flags |= CO_NESTED; From fdrake at users.sourceforge.net Tue Oct 11 22:25:25 2005 From: fdrake at users.sourceforge.net (fdrake@users.sourceforge.net) Date: Tue, 11 Oct 2005 22:25:25 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/ext run-func.c, 1.4.20.2, 1.4.20.3 Message-ID: <20051011202525.5AF6D1E4002@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/ext In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5488 Modified Files: Tag: release24-maint run-func.c Log Message: fix stupid typo Index: run-func.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ext/run-func.c,v retrieving revision 1.4.20.2 retrieving revision 1.4.20.3 diff -u -d -r1.4.20.2 -r1.4.20.3 --- run-func.c 12 Jul 2005 13:20:56 -0000 1.4.20.2 +++ run-func.c 11 Oct 2005 20:25:19 -0000 1.4.20.3 @@ -20,7 +20,7 @@ Py_DECREF(pName); if (pModule != NULL) { - pFunc = PyDict_GetAttrString(pModule, argv[2]); + pFunc = PyDict_GetItemString(pModule, argv[2]); /* pFunc is a new reference */ if (pFunc && PyCallable_Check(pFunc)) { From fdrake at users.sourceforge.net Tue Oct 11 22:26:09 2005 From: fdrake at users.sourceforge.net (fdrake@users.sourceforge.net) Date: Tue, 11 Oct 2005 22:26:09 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/ext run-func.c,1.6,1.7 Message-ID: <20051011202609.55DC81E4002@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/ext In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5726 Modified Files: run-func.c Log Message: fix stupid typo Index: run-func.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ext/run-func.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- run-func.c 12 Jul 2005 13:20:49 -0000 1.6 +++ run-func.c 11 Oct 2005 20:26:05 -0000 1.7 @@ -20,7 +20,7 @@ Py_DECREF(pName); if (pModule != NULL) { - pFunc = PyDict_GetAttrString(pModule, argv[2]); + pFunc = PyDict_GetItemString(pModule, argv[2]); /* pFunc is a new reference */ if (pFunc && PyCallable_Check(pFunc)) { From nascheme at users.sourceforge.net Tue Oct 11 23:37:32 2005 From: nascheme at users.sourceforge.net (nascheme@users.sourceforge.net) Date: Tue, 11 Oct 2005 23:37:32 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Python newcompile.c, 1.1.2.112, 1.1.2.113 Message-ID: <20051011213732.0CB421E4002@bag.python.org> Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22615/Python Modified Files: Tag: ast-branch newcompile.c Log Message: Implement PyNode_Compile() for the AST compiler. Add some minimal tests for parser.compilest(). Index: newcompile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/Attic/newcompile.c,v retrieving revision 1.1.2.112 retrieving revision 1.1.2.113 diff -u -d -r1.1.2.112 -r1.1.2.113 --- newcompile.c 11 Oct 2005 19:18:11 -0000 1.1.2.112 +++ newcompile.c 11 Oct 2005 21:37:28 -0000 1.1.2.113 @@ -474,6 +474,18 @@ return co; } +PyCodeObject * +PyNode_Compile(struct _node *n, const char *filename) +{ + PyCodeObject *co; + mod_ty mod = PyAST_FromNode(n, NULL, filename); + if (!mod) + return NULL; + co = PyAST_Compile(mod, filename, NULL); + free_mod(mod); + return co; +} + static void compiler_free(struct compiler *c) { From nascheme at users.sourceforge.net Tue Oct 11 23:37:32 2005 From: nascheme at users.sourceforge.net (nascheme@users.sourceforge.net) Date: Tue, 11 Oct 2005 23:37:32 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib/test test_parser.py, 1.11.2.2, 1.11.2.3 Message-ID: <20051011213732.163C11E400A@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22615/Lib/test Modified Files: Tag: ast-branch test_parser.py Log Message: Implement PyNode_Compile() for the AST compiler. Add some minimal tests for parser.compilest(). Index: test_parser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_parser.py,v retrieving revision 1.11.2.2 retrieving revision 1.11.2.3 diff -u -d -r1.11.2.2 -r1.11.2.3 --- test_parser.py 7 Jan 2005 06:59:10 -0000 1.11.2.2 +++ test_parser.py 11 Oct 2005 21:37:28 -0000 1.11.2.3 @@ -397,10 +397,33 @@ (0, '')) self.check_bad_tree(tree, "malformed global ast") + +class CompileTestCase(unittest.TestCase): + + # These tests are very minimal. :-( + + def test_compile_expr(self): + st = parser.expr('2 + 3') + code = parser.compilest(st) + self.assertEquals(eval(code), 5) + + def test_compile_suite(self): + st = parser.suite('x = 2; y = x + 3') + code = parser.compilest(st) + globs = {} + exec code in globs + self.assertEquals(globs['y'], 5) + + def test_compile_error(self): + st = parser.suite('1 = 3 + 4') + self.assertRaises(SyntaxError, parser.compilest, st) + + def test_main(): test_support.run_unittest( RoundtripLegalSyntaxTestCase, - IllegalSyntaxTestCase + IllegalSyntaxTestCase, + CompileTestCase, ) From jhylton at users.sourceforge.net Wed Oct 12 00:03:16 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Wed, 12 Oct 2005 00:03:16 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Include pythonrun.h, 2.49.2.7, 2.49.2.8 Message-ID: <20051011220316.547071E4002@bag.python.org> Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29290/Include Modified Files: Tag: ast-branch pythonrun.h Log Message: Fixer typos in PyParser_SimpleParseString and File. The #defines were wrong. Fixing them required twiddling the actual definitions, too. Index: pythonrun.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pythonrun.h,v retrieving revision 2.49.2.7 retrieving revision 2.49.2.8 diff -u -d -r2.49.2.7 -r2.49.2.8 --- pythonrun.h 7 Jan 2005 06:57:42 -0000 2.49.2.7 +++ pythonrun.h 11 Oct 2005 22:03:13 -0000 2.49.2.8 @@ -41,10 +41,10 @@ PyAPI_FUNC(struct _mod *) PyParser_ASTFromFile(FILE *, const char *, int, char *, char *, PyCompilerFlags *, int *); -#define PyParser_SimpleParserString(S, B) \ - PyParser_SimplerParserStringFlags(S, B, 0) -#define PyParser_SimpleParserFile(FP, S, B) \ - PyParser_SimplerParserFileFlags(FP, S, B, 0) +#define PyParser_SimpleParseString(S, B) \ + PyParser_SimpleParseStringFlags(S, B, 0) +#define PyParser_SimpleParseFile(FP, S, B) \ + PyParser_SimpleParseFileFlags(FP, S, B, 0) PyAPI_FUNC(struct _node *) PyParser_SimpleParseStringFlags(const char *, int, int); PyAPI_FUNC(struct _node *) PyParser_SimpleParseFileFlags(FILE *, const char *, From jhylton at users.sourceforge.net Wed Oct 12 00:03:16 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Wed, 12 Oct 2005 00:03:16 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Python pythonrun.c, 2.161.2.16, 2.161.2.17 Message-ID: <20051011220316.739D51E400A@bag.python.org> Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29290/Python Modified Files: Tag: ast-branch pythonrun.c Log Message: Fixer typos in PyParser_SimpleParseString and File. The #defines were wrong. Fixing them required twiddling the actual definitions, too. Index: pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.161.2.16 retrieving revision 2.161.2.17 diff -u -d -r2.161.2.16 -r2.161.2.17 --- pythonrun.c 7 Jan 2005 17:25:18 -0000 2.161.2.16 +++ pythonrun.c 11 Oct 2005 22:03:13 -0000 2.161.2.17 @@ -1312,12 +1312,6 @@ return n; } -node * -PyParser_SimpleParseFile(FILE *fp, const char *filename, int start) -{ - return PyParser_SimpleParseFileFlags(fp, filename, start, 0); -} - /* Simplified interface to parsestring -- return node or set exception */ node * @@ -1333,12 +1327,6 @@ } node * -PyParser_SimpleParseString(const char *str, int start) -{ - return PyParser_SimpleParseStringFlags(str, start, 0); -} - -node * PyParser_SimpleParseStringFlagsFilename(const char *str, const char *filename, int start, int flags) { @@ -1642,3 +1630,21 @@ return oldhandler; #endif } + +/* Deprecated C API functions still provided for binary compatiblity */ + +#undef PyParser_SimpleParseFile +#undef PyParser_SimpleParseString + +node * +PyParser_SimpleParseFile(FILE *fp, const char *filename, int start) +{ + return PyParser_SimpleParseFileFlags(fp, filename, start, 0); +} + +node * +PyParser_SimpleParseString(const char *str, int start) +{ + return PyParser_SimpleParseStringFlags(str, start, 0); +} + From jhylton at users.sourceforge.net Wed Oct 12 00:29:09 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Wed, 12 Oct 2005 00:29:09 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Python newcompile.c, 1.1.2.113, 1.1.2.114 Message-ID: <20051011222909.7EA541E4002@bag.python.org> Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5663/Python Modified Files: Tag: ast-branch newcompile.c Log Message: Get rid of compiler warning for PyAST_FromNode(). Index: newcompile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/Attic/newcompile.c,v retrieving revision 1.1.2.113 retrieving revision 1.1.2.114 diff -u -d -r1.1.2.113 -r1.1.2.114 --- newcompile.c 11 Oct 2005 21:37:28 -0000 1.1.2.113 +++ newcompile.c 11 Oct 2005 22:29:06 -0000 1.1.2.114 @@ -17,6 +17,8 @@ #include "Python.h" #include "Python-ast.h" +#include "node.h" +#include "ast.h" #include "code.h" #include "compile.h" #include "symtable.h" From nascheme at users.sourceforge.net Wed Oct 12 00:50:49 2005 From: nascheme at users.sourceforge.net (nascheme@users.sourceforge.net) Date: Wed, 12 Oct 2005 00:50:49 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib/test test_peepholer.py, 1.6.2.1, 1.6.2.2 Message-ID: <20051011225049.312A81E4002@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9954/Lib/test Modified Files: Tag: ast-branch test_peepholer.py Log Message: Merge changes from HEAD into test_peepholer.py. Index: test_peepholer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_peepholer.py,v retrieving revision 1.6.2.1 retrieving revision 1.6.2.2 diff -u -d -r1.6.2.1 -r1.6.2.2 --- test_peepholer.py 7 Jan 2005 06:59:10 -0000 1.6.2.1 +++ test_peepholer.py 11 Oct 2005 22:50:45 -0000 1.6.2.2 @@ -109,7 +109,6 @@ ('a="abc" + "def"', "('abcdef')"), # check string ops ('a = 3**4', '(81)'), # binary power ('a = 3*4', '(12)'), # binary multiply - ('a = 13/4.0', '(3.25)'), # binary divide ('a = 13//4', '(3)'), # binary floor divide ('a = 14%4', '(2)'), # binary modulo ('a = 2+3', '(5)'), # binary add @@ -130,6 +129,29 @@ self.assert_('(2)' in asm) self.assert_("('b')" in asm) + # Verify that large sequences do not result from folding + asm = dis_single('a="x"*1000') + self.assert_('(1000)' in asm) + + def test_folding_of_unaryops_on_constants(self): + for line, elem in ( + ('`1`', "('1')"), # unary convert + ('-0.5', '(-0.5)'), # unary negative + ('~-2', '(1)'), # unary invert + ): + asm = dis_single(line) + self.assert_(elem in asm, asm) + self.assert_('UNARY_' not in asm) + + # Verify that unfoldables are skipped + for line, elem in ( + ('-"abc"', "('abc')"), # unary negative + ('~"abc"', "('abc')"), # unary invert + ): + asm = dis_single(line) + self.assert_(elem in asm, asm) + self.assert_('UNARY_' in asm) + def test_elim_extra_return(self): # RETURN LOAD_CONST None RETURN --> RETURN def f(x): From nascheme at users.sourceforge.net Wed Oct 12 00:54:08 2005 From: nascheme at users.sourceforge.net (nascheme@users.sourceforge.net) Date: Wed, 12 Oct 2005 00:54:08 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Python newcompile.c, 1.1.2.114, 1.1.2.115 Message-ID: <20051011225408.3A67E1E4002@bag.python.org> Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10415/Python Modified Files: Tag: ast-branch newcompile.c Log Message: Integrate peephole optimizer from HEAD version of compiler.c. Index: newcompile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/Attic/newcompile.c,v retrieving revision 1.1.2.114 retrieving revision 1.1.2.115 diff -u -d -r1.1.2.114 -r1.1.2.115 --- newcompile.c 11 Oct 2005 22:29:06 -0000 1.1.2.114 +++ newcompile.c 11 Oct 2005 22:54:03 -0000 1.1.2.115 @@ -568,6 +568,598 @@ return dest; } +/* Begin: Peephole optimizations ----------------------------------------- */ + +#define GETARG(arr, i) ((int)((arr[i+2]<<8) + arr[i+1])) +#define UNCONDITIONAL_JUMP(op) (op==JUMP_ABSOLUTE || op==JUMP_FORWARD) +#define ABSOLUTE_JUMP(op) (op==JUMP_ABSOLUTE || op==CONTINUE_LOOP) +#define GETJUMPTGT(arr, i) (GETARG(arr,i) + (ABSOLUTE_JUMP(arr[i]) ? 0 : i+3)) +#define SETARG(arr, i, val) arr[i+2] = val>>8; arr[i+1] = val & 255 +#define CODESIZE(op) (HAS_ARG(op) ? 3 : 1) +#define ISBASICBLOCK(blocks, start, bytes) (blocks[start]==blocks[start+bytes-1]) + +/* Replace LOAD_CONST c1. LOAD_CONST c2 ... LOAD_CONST cn BUILD_TUPLE n + with LOAD_CONST (c1, c2, ... cn). + The consts table must still be in list form so that the + new constant (c1, c2, ... cn) can be appended. + Called with codestr pointing to the first LOAD_CONST. + Bails out with no change if one or more of the LOAD_CONSTs is missing. + Also works for BUILD_LIST when followed by an "in" or "not in" test. +*/ +static int +tuple_of_constants(unsigned char *codestr, int n, PyObject *consts) +{ + PyObject *newconst, *constant; + int i, arg, len_consts; + + /* Pre-conditions */ + assert(PyList_CheckExact(consts)); + assert(codestr[n*3] == BUILD_TUPLE || codestr[n*3] == BUILD_LIST); + assert(GETARG(codestr, (n*3)) == n); + for (i=0 ; i 20) { + Py_DECREF(newconst); + return 0; + } + + /* Append folded constant into consts table */ + len_consts = PyList_GET_SIZE(consts); + if (PyList_Append(consts, newconst)) { + Py_DECREF(newconst); + return 0; + } + Py_DECREF(newconst); + + /* Write NOP NOP NOP NOP LOAD_CONST newconst */ + memset(codestr, NOP, 4); + codestr[4] = LOAD_CONST; + SETARG(codestr, 4, len_consts); + return 1; +} + +static int +fold_unaryops_on_constants(unsigned char *codestr, PyObject *consts) +{ + PyObject *newconst=NULL, *v; + int len_consts, opcode; + + /* Pre-conditions */ + assert(PyList_CheckExact(consts)); + assert(codestr[0] == LOAD_CONST); + + /* Create new constant */ + v = PyList_GET_ITEM(consts, GETARG(codestr, 0)); + opcode = codestr[3]; + switch (opcode) { + case UNARY_NEGATIVE: + /* Preserve the sign of -0.0 */ + if (PyObject_IsTrue(v) == 1) + newconst = PyNumber_Negative(v); + break; + case UNARY_CONVERT: + newconst = PyObject_Repr(v); + break; + case UNARY_INVERT: + newconst = PyNumber_Invert(v); + break; + default: + /* Called with an unknown opcode */ + assert(0); + return 0; + } + if (newconst == NULL) { + PyErr_Clear(); + return 0; + } + + /* Append folded constant into consts table */ + len_consts = PyList_GET_SIZE(consts); + if (PyList_Append(consts, newconst)) { + Py_DECREF(newconst); + return 0; + } + Py_DECREF(newconst); + + /* Write NOP LOAD_CONST newconst */ + codestr[0] = NOP; + codestr[1] = LOAD_CONST; + SETARG(codestr, 1, len_consts); + return 1; +} + +static unsigned int * +markblocks(unsigned char *code, int len) +{ + unsigned int *blocks = PyMem_Malloc(len*sizeof(int)); + int i,j, opcode, blockcnt = 0; + + if (blocks == NULL) + return NULL; + memset(blocks, 0, len*sizeof(int)); + + /* Mark labels in the first pass */ + for (i=0 ; i= 255. + + Optimizations are restricted to simple transformations occuring within a + single basic block. All transformations keep the code size the same or + smaller. For those that reduce size, the gaps are initially filled with + NOPs. Later those NOPs are removed and the jump addresses retargeted in + a single pass. Line numbering is adjusted accordingly. */ + +static PyObject * +optimize_code(PyObject *code, PyObject* consts, PyObject *names, PyObject *lineno_obj) +{ + int i, j, codelen, nops, h, adj; + int tgt, tgttgt, opcode; + unsigned char *codestr = NULL; + unsigned char *lineno; + int *addrmap = NULL; + int new_line, cum_orig_line, last_line, tabsiz; + int cumlc=0, lastlc=0; /* Count runs of consecutive LOAD_CONST codes */ + unsigned int *blocks = NULL; + char *name; + + /* Bail out if an exception is set */ + if (PyErr_Occurred()) + 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); + if (memchr(lineno, 255, tabsiz) != NULL) + goto exitUnchanged; + + /* Avoid situations where jump retargeting could overflow */ + assert(PyString_Check(code)); + codelen = PyString_Size(code); + if (codelen > 32700) + goto exitUnchanged; + + /* Make a modifiable copy of the code string */ + codestr = PyMem_Malloc(codelen); + if (codestr == NULL) + goto exitUnchanged; + codestr = memcpy(codestr, PyString_AS_STRING(code), codelen); + + /* Verify that RETURN_VALUE terminates the codestring. This allows + the various transformation patterns to look ahead several + instructions without additional checks to make sure they are not + looking beyond the end of the code string. + */ + if (codestr[codelen-1] != RETURN_VALUE) + goto exitUnchanged; + + /* Mapping to new jump targets after NOPs are removed */ + addrmap = PyMem_Malloc(codelen * sizeof(int)); + if (addrmap == NULL) + goto exitUnchanged; + + blocks = markblocks(codestr, codelen); + if (blocks == NULL) + goto exitUnchanged; + assert(PyList_Check(consts)); + + for (i=0 ; i a is not b + not a in b --> a not in b + not a is not b --> a is b + not a not in b --> a in b + */ + case COMPARE_OP: + j = GETARG(codestr, i); + if (j < 6 || j > 9 || + codestr[i+3] != UNARY_NOT || + !ISBASICBLOCK(blocks,i,4)) + continue; + SETARG(codestr, i, (j^1)); + codestr[i+3] = NOP; + break; + + /* Replace LOAD_GLOBAL/LOAD_NAME None with LOAD_CONST None */ + case LOAD_NAME: + case LOAD_GLOBAL: + j = GETARG(codestr, i); + name = PyString_AsString(PyTuple_GET_ITEM(names, j)); + if (name == NULL || strcmp(name, "None") != 0) + continue; + for (j=0 ; j < PyList_GET_SIZE(consts) ; j++) { + if (PyList_GET_ITEM(consts, j) == Py_None) { + codestr[i] = LOAD_CONST; + SETARG(codestr, i, j); + cumlc = lastlc + 1; + break; + } + } + break; + + /* Skip over LOAD_CONST trueconst JUMP_IF_FALSE xx POP_TOP */ + case LOAD_CONST: + cumlc = lastlc + 1; + j = GETARG(codestr, i); + if (codestr[i+3] != JUMP_IF_FALSE || + codestr[i+6] != POP_TOP || + !ISBASICBLOCK(blocks,i,7) || + !PyObject_IsTrue(PyList_GET_ITEM(consts, j))) + continue; + memset(codestr+i, NOP, 7); + cumlc = 0; + break; + + /* Try to fold tuples of constants (includes a case for lists + which are only used for "in" and "not in" tests). + Skip over BUILD_SEQN 1 UNPACK_SEQN 1. + Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2. + Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */ + case BUILD_TUPLE: + case BUILD_LIST: + j = GETARG(codestr, i); + h = i - 3 * j; + if (h >= 0 && + j <= lastlc && + ((opcode == BUILD_TUPLE && + ISBASICBLOCK(blocks, h, 3*(j+1))) || + (opcode == BUILD_LIST && + codestr[i+3]==COMPARE_OP && + ISBASICBLOCK(blocks, h, 3*(j+2)) && + (GETARG(codestr,i+3)==6 || + GETARG(codestr,i+3)==7))) && + tuple_of_constants(&codestr[h], j, consts)) { + assert(codestr[i] == LOAD_CONST); + cumlc = 1; + break; + } + if (codestr[i+3] != UNPACK_SEQUENCE || + !ISBASICBLOCK(blocks,i,6) || + j != GETARG(codestr, i+3)) + continue; + if (j == 1) { + memset(codestr+i, NOP, 6); + } else if (j == 2) { + codestr[i] = ROT_TWO; + memset(codestr+i+1, NOP, 5); + } else if (j == 3) { + codestr[i] = ROT_THREE; + codestr[i+1] = ROT_TWO; + memset(codestr+i+2, NOP, 4); + } + break; + + /* Fold binary ops on constants. + LOAD_CONST c1 LOAD_CONST c2 BINOP --> LOAD_CONST binop(c1,c2) */ + case BINARY_POWER: + case BINARY_MULTIPLY: + case BINARY_TRUE_DIVIDE: + case BINARY_FLOOR_DIVIDE: + case BINARY_MODULO: + case BINARY_ADD: + case BINARY_SUBTRACT: + case BINARY_SUBSCR: + case BINARY_LSHIFT: + case BINARY_RSHIFT: + case BINARY_AND: + case BINARY_XOR: + case BINARY_OR: + if (lastlc >= 2 && + ISBASICBLOCK(blocks, i-6, 7) && + fold_binops_on_constants(&codestr[i-6], consts)) { + i -= 2; + assert(codestr[i] == LOAD_CONST); + cumlc = 1; + } + break; + + /* Fold unary ops on constants. + LOAD_CONST c1 UNARY_OP --> LOAD_CONST unary_op(c) */ + case UNARY_NEGATIVE: + case UNARY_CONVERT: + case UNARY_INVERT: + if (lastlc >= 1 && + ISBASICBLOCK(blocks, i-3, 4) && + fold_unaryops_on_constants(&codestr[i-3], consts)) { + i -= 2; + assert(codestr[i] == LOAD_CONST); + cumlc = 1; + } + break; + + /* Simplify conditional jump to conditional jump where the + result of the first test implies the success of a similar + test or the failure of the opposite test. + Arises in code like: + "if a and b:" + "if a or b:" + "a and b or c" + "(a and b) and c" + x:JUMP_IF_FALSE y y:JUMP_IF_FALSE z --> x:JUMP_IF_FALSE z + x:JUMP_IF_FALSE y y:JUMP_IF_TRUE z --> x:JUMP_IF_FALSE y+3 + where y+3 is the instruction following the second test. + */ + case JUMP_IF_FALSE: + case JUMP_IF_TRUE: + tgt = GETJUMPTGT(codestr, i); + j = codestr[tgt]; + if (j == JUMP_IF_FALSE || j == JUMP_IF_TRUE) { + if (j == opcode) { + tgttgt = GETJUMPTGT(codestr, tgt) - i - 3; + SETARG(codestr, i, tgttgt); + } else { + tgt -= i; + SETARG(codestr, i, tgt); + } + break; + } + /* Intentional fallthrough */ + + /* Replace jumps to unconditional jumps */ + case FOR_ITER: + case JUMP_FORWARD: + case JUMP_ABSOLUTE: + case CONTINUE_LOOP: + case SETUP_LOOP: + case SETUP_EXCEPT: + case SETUP_FINALLY: + tgt = GETJUMPTGT(codestr, i); + if (!UNCONDITIONAL_JUMP(codestr[tgt])) + continue; + tgttgt = GETJUMPTGT(codestr, tgt); + if (opcode == JUMP_FORWARD) /* JMP_ABS can go backwards */ + opcode = JUMP_ABSOLUTE; + if (!ABSOLUTE_JUMP(opcode)) + tgttgt -= i + 3; /* Calc relative jump addr */ + if (tgttgt < 0) /* No backward relative jumps */ + continue; + codestr[i] = opcode; + SETARG(codestr, i, tgttgt); + break; + + case EXTENDED_ARG: + goto exitUnchanged; + + /* Replace RETURN LOAD_CONST None RETURN with just RETURN */ + case RETURN_VALUE: + if (i+4 >= codelen || + codestr[i+4] != RETURN_VALUE || + !ISBASICBLOCK(blocks,i,5)) + continue; + memset(codestr+i+1, NOP, 4); + break; + } + } + + /* Fixup linenotab */ + for (i=0, nops=0 ; iu->u_consts, 0); + tmp = dict_keys_inorder(c->u->u_consts, 0); + if (!tmp) + goto error; + consts = PySequence_List(tmp); /* optimize_code requires a list */ + Py_DECREF(tmp); + names = dict_keys_inorder(c->u->u_names, 0); varnames = dict_keys_inorder(c->u->u_varnames, 0); if (!consts || !names || !varnames) @@ -3566,9 +4165,20 @@ nlocals = PyDict_Size(c->u->u_varnames); flags = compute_code_flags(c); if (flags < 0) - goto error; + goto error; + + bytecode = optimize_code(a->a_bytecode, consts, names, a->a_lnotab); + if (!bytecode) + goto error; + + tmp = PyList_AsTuple(consts); /* PyCode_New requires a tuple */ + if (!tmp) + goto error; + Py_DECREF(consts); + consts = tmp; + co = PyCode_New(c->u->u_argcount, nlocals, stackdepth(c), flags, - a->a_bytecode, consts, names, varnames, + bytecode, consts, names, varnames, freevars, cellvars, filename, c->u->u_name, c->u->u_firstlineno, @@ -3581,6 +4191,7 @@ Py_XDECREF(name); Py_XDECREF(freevars); Py_XDECREF(cellvars); + Py_XDECREF(bytecode); return co; } From jhylton at users.sourceforge.net Wed Oct 12 05:18:11 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Wed, 12 Oct 2005 05:18:11 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Include Python-ast.h, 1.1.2.12, 1.1.2.13 Message-ID: <20051012031811.20AEB1E4002@bag.python.org> Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12337/Include Modified Files: Tag: ast-branch Python-ast.h Log Message: Add line numbers to expressions. The line numbers aren't used yet, but should make it possible to generate correct line numbers (e.g. co_lnotab, co_firstlineno). Several tests fails because of the incorrect line numbers currently generated. Index: Python-ast.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/Attic/Python-ast.h,v retrieving revision 1.1.2.12 retrieving revision 1.1.2.13 diff -u -d -r1.1.2.12 -r1.1.2.13 --- Python-ast.h 13 Apr 2005 19:44:37 -0000 1.1.2.12 +++ Python-ast.h 12 Oct 2005 03:18:07 -0000 1.1.2.13 @@ -1,4 +1,4 @@ -/* File automatically generated by ./Parser/asdl_c.py */ +/* File automatically generated by ../Parser/asdl_c.py */ #include "asdl.h" @@ -273,6 +273,7 @@ } Tuple; } v; + int lineno; }; struct _slice { @@ -356,24 +357,27 @@ stmt_ty Pass(int lineno); stmt_ty Break(int lineno); stmt_ty Continue(int lineno); -expr_ty BoolOp(boolop_ty op, asdl_seq * values); -expr_ty BinOp(expr_ty left, operator_ty op, expr_ty right); -expr_ty UnaryOp(unaryop_ty op, expr_ty operand); -expr_ty Lambda(arguments_ty args, expr_ty body); -expr_ty Dict(asdl_seq * keys, asdl_seq * values); -expr_ty ListComp(expr_ty elt, asdl_seq * generators); -expr_ty GeneratorExp(expr_ty elt, asdl_seq * generators); -expr_ty Compare(expr_ty left, asdl_seq * ops, asdl_seq * comparators); +expr_ty BoolOp(boolop_ty op, asdl_seq * values, int lineno); +expr_ty BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno); +expr_ty UnaryOp(unaryop_ty op, expr_ty operand, int lineno); +expr_ty Lambda(arguments_ty args, expr_ty body, int lineno); +expr_ty Dict(asdl_seq * keys, asdl_seq * values, int lineno); +expr_ty ListComp(expr_ty elt, asdl_seq * generators, int lineno); +expr_ty GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno); +expr_ty Compare(expr_ty left, asdl_seq * ops, asdl_seq * comparators, int + lineno); expr_ty Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, expr_ty - starargs, expr_ty kwargs); -expr_ty Repr(expr_ty value); -expr_ty Num(object n); -expr_ty Str(string s); -expr_ty Attribute(expr_ty value, identifier attr, expr_context_ty ctx); -expr_ty Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx); -expr_ty Name(identifier id, expr_context_ty ctx); -expr_ty List(asdl_seq * elts, expr_context_ty ctx); -expr_ty Tuple(asdl_seq * elts, expr_context_ty ctx); + starargs, expr_ty kwargs, int lineno); +expr_ty Repr(expr_ty value, int lineno); +expr_ty Num(object n, int lineno); +expr_ty Str(string s, int lineno); +expr_ty Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int + lineno); +expr_ty Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int + lineno); +expr_ty Name(identifier id, expr_context_ty ctx, int lineno); +expr_ty List(asdl_seq * elts, expr_context_ty ctx, int lineno); +expr_ty Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno); slice_ty Ellipsis(void); slice_ty Slice(expr_ty lower, expr_ty upper, expr_ty step); slice_ty ExtSlice(asdl_seq * dims); From jhylton at users.sourceforge.net Wed Oct 12 05:18:11 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Wed, 12 Oct 2005 05:18:11 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Parser Python.asdl, 1.1.2.11, 1.1.2.12 Message-ID: <20051012031811.7BFD31E4002@bag.python.org> Update of /cvsroot/python/python/dist/src/Parser In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12337/Parser Modified Files: Tag: ast-branch Python.asdl Log Message: Add line numbers to expressions. The line numbers aren't used yet, but should make it possible to generate correct line numbers (e.g. co_lnotab, co_firstlineno). Several tests fails because of the incorrect line numbers currently generated. Index: Python.asdl =================================================================== RCS file: /cvsroot/python/python/dist/src/Parser/Attic/Python.asdl,v retrieving revision 1.1.2.11 retrieving revision 1.1.2.12 diff -u -d -r1.1.2.11 -r1.1.2.12 --- Python.asdl 13 Apr 2005 19:59:20 -0000 1.1.2.11 +++ Python.asdl 12 Oct 2005 03:18:07 -0000 1.1.2.12 @@ -72,6 +72,8 @@ | List(expr* elts, expr_context ctx) | Tuple(expr *elts, expr_context ctx) + attributes (int lineno) + expr_context = Load | Store | Del | AugLoad | AugStore | Param slice = Ellipsis | Slice(expr? lower, expr? upper, expr? step) From jhylton at users.sourceforge.net Wed Oct 12 05:18:11 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Wed, 12 Oct 2005 05:18:11 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Python ast.c, 1.1.2.65, 1.1.2.66 newcompile.c, 1.1.2.115, 1.1.2.116 Message-ID: <20051012031811.9DEF01E400A@bag.python.org> Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12337/Python Modified Files: Tag: ast-branch ast.c newcompile.c Log Message: Add line numbers to expressions. The line numbers aren't used yet, but should make it possible to generate correct line numbers (e.g. co_lnotab, co_firstlineno). Several tests fails because of the incorrect line numbers currently generated. Index: ast.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/Attic/ast.c,v retrieving revision 1.1.2.65 retrieving revision 1.1.2.66 diff -u -d -r1.1.2.65 -r1.1.2.66 --- ast.c 29 Sep 2005 19:27:58 -0000 1.1.2.65 +++ ast.c 12 Oct 2005 03:18:07 -0000 1.1.2.66 @@ -338,7 +338,8 @@ /* Set the context ctx for expr_ty e returning 0 on success, -1 on error. Only sets context for expr kinds that "can appear in assignment context" - (according to ../Parser/Python.asdl) + (according to ../Parser/Python.asdl). For other expr kinds, it sets + an appropriate syntax error and returns false. If e is a sequential type, items in sequence will also have their context set. @@ -373,6 +374,8 @@ s = e->v.List.elts; break; case Tuple_kind: + if (asdl_seq_LEN(e->v.Tuple.elts) == 0) + return ast_error(n, "can't assign to ()"); e->v.Tuple.ctx = ctx; s = e->v.Tuple.elts; break; @@ -384,6 +387,11 @@ else return ast_error(n, "unexpected operation on function call"); break; + case BinOp_kind: + return ast_error(n, "can't assign to operator"); + case GeneratorExp_kind: + return ast_error(n, "assignment to generator expression " + "not possible"); default: return ast_error(n, "unexpected node in assignment"); break; @@ -533,7 +541,7 @@ ast_error(child, "assignment to None"); return NULL; } - arg = Name(NEW_IDENTIFIER(child), Store); + arg = Name(NEW_IDENTIFIER(child), Store, LINENO(child)); } else arg = compiler_complex_args(CHILD(CHILD(n, 2*i), 1)); @@ -541,7 +549,7 @@ asdl_seq_SET(args, i, arg); } - result = Tuple(args, Store); + result = Tuple(args, Store, LINENO(n)); set_context(result, Store, n); return result; } @@ -620,8 +628,9 @@ goto error; } /* XXX check return value of Name call */ - asdl_seq_APPEND(args, Name(NEW_IDENTIFIER(CHILD(ch, 0)), - Param)); + asdl_seq_APPEND(args, + Name(NEW_IDENTIFIER(CHILD(ch, 0)), + Param, LINENO(ch))); } i += 2; /* the name and the comma */ break; @@ -672,7 +681,7 @@ id = NEW_IDENTIFIER(CHILD(n, 0)); if (!id) goto error; - e = Name(id, Load); + e = Name(id, Load, LINENO(n)); if (!e) goto error; id = NULL; @@ -681,7 +690,7 @@ id = NEW_IDENTIFIER(CHILD(n, i)); if (!id) goto error; - attrib = Attribute(e, id, Load); + attrib = Attribute(e, id, Load, LINENO(CHILD(n, i))); if (!attrib) goto error; e = attrib; @@ -720,7 +729,7 @@ name_expr = NULL; } else if (NCH(n) == 5) { /* Call with no arguments */ - d = Call(name_expr, NULL, NULL, NULL, NULL); + d = Call(name_expr, NULL, NULL, NULL, NULL, LINENO(n)); if (!d) goto error; name_expr = NULL; @@ -827,8 +836,6 @@ expression = ast_for_expr(c, CHILD(n, 2)); if (!expression) return NULL; - - return Lambda(args, expression); } else { args = ast_for_arguments(c, CHILD(n, 1)); @@ -837,9 +844,9 @@ expression = ast_for_expr(c, CHILD(n, 3)); if (!expression) return NULL; - - return Lambda(args, expression); } + + return Lambda(args, expression, LINENO(n)); } /* Count the number of 'for' loop in a list comprehension. @@ -958,7 +965,7 @@ if (asdl_seq_LEN(t) == 1) lc = comprehension(asdl_seq_GET(t, 0), expression, NULL); else - lc = comprehension(Tuple(t, Store), expression, NULL); + lc = comprehension(Tuple(t, Store, LINENO(ch)), expression, NULL); if (!lc) { asdl_seq_free(listcomps); @@ -1003,7 +1010,7 @@ asdl_seq_APPEND(listcomps, lc); } - return ListComp(elt, listcomps); + return ListComp(elt, listcomps, LINENO(n)); } /* @@ -1117,9 +1124,11 @@ } if (asdl_seq_LEN(t) == 1) - ge = comprehension(asdl_seq_GET(t, 0), expression, NULL); + ge = comprehension(asdl_seq_GET(t, 0), expression, + NULL); else - ge = comprehension(Tuple(t, Store), expression, NULL); + ge = comprehension(Tuple(t, Store, LINENO(ch)), + expression, NULL); if (!ge) { asdl_seq_free(genexps); @@ -1148,11 +1157,11 @@ for (j = 0; j < n_ifs; j++) { REQ(ch, gen_iter); - ch = CHILD(ch, 0); REQ(ch, gen_if); - asdl_seq_APPEND(ifs, ast_for_expr(c, CHILD(ch, 1))); + asdl_seq_APPEND(ifs, + ast_for_expr(c, CHILD(ch, 1))); if (NCH(ch) == 3) ch = CHILD(ch, 2); } @@ -1164,7 +1173,7 @@ asdl_seq_APPEND(genexps, ge); } - return GeneratorExp(elt, genexps); + return GeneratorExp(elt, genexps, LINENO(n)); } static expr_ty @@ -1179,14 +1188,14 @@ case NAME: /* All names start in Load context, but may later be changed. */ - return Name(NEW_IDENTIFIER(ch), Load); + return Name(NEW_IDENTIFIER(ch), Load, LINENO(n)); case STRING: { PyObject *str = parsestrplus(c, n); if (!str) return NULL; - return Str(str); + return Str(str, LINENO(n)); } case NUMBER: { PyObject *pynum = parsenumber(STR(ch)); @@ -1194,13 +1203,13 @@ if (!pynum) return NULL; - return Num(pynum); + return Num(pynum, LINENO(n)); } case LPAR: /* some parenthesized expressions */ ch = CHILD(n, 1); if (TYPE(ch) == RPAR) - return Tuple(NULL, Load); + return Tuple(NULL, Load, LINENO(n)); if ((NCH(ch) > 1) && (TYPE(CHILD(ch, 1)) == gen_for)) return ast_for_genexp(c, ch); @@ -1210,7 +1219,7 @@ ch = CHILD(n, 1); if (TYPE(ch) == RSQB) - return List(NULL, Load); + return List(NULL, Load, LINENO(n)); REQ(ch, listmaker); if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) { @@ -1219,7 +1228,7 @@ if (!elts) return NULL; - return List(elts, Load); + return List(elts, Load, LINENO(n)); } else return ast_for_listcomp(c, ch); @@ -1255,7 +1264,7 @@ asdl_seq_SET(values, i / 4, expression); } - return Dict(keys, values); + return Dict(keys, values, LINENO(n)); } case BACKQUOTE: { /* repr */ expr_ty expression = ast_for_testlist(c, CHILD(n, 1)); @@ -1263,7 +1272,7 @@ if (!expression) return NULL; - return Repr(expression); + return Repr(expression, LINENO(n)); } default: PyErr_Format(PyExc_Exception, "unhandled atom %d", @@ -1367,15 +1376,16 @@ if (!operator) return NULL; - result = BinOp(expr1, operator, expr2); + result = BinOp(expr1, operator, expr2, LINENO(n)); if (!result) return NULL; nops = (NCH(n) - 1) / 2; for (i = 1; i < nops; i++) { expr_ty tmp_result, tmp; + const node* next_oper = CHILD(n, i * 2 + 1); - operator = get_operator(CHILD(n, i * 2 + 1)); + operator = get_operator(next_oper); if (!operator) return NULL; @@ -1383,7 +1393,8 @@ if (!tmp) return NULL; - tmp_result = BinOp(result, operator, tmp); + tmp_result = BinOp(result, operator, tmp, + LINENO(next_oper)); if (!tmp) return NULL; result = tmp_result; @@ -1436,10 +1447,10 @@ asdl_seq_SET(seq, i / 2, e); } if (!strcmp(STR(CHILD(n, 1)), "and")) - return BoolOp(And, seq); + return BoolOp(And, seq, LINENO(n)); else { assert(!strcmp(STR(CHILD(n, 1)), "or")); - return BoolOp(Or, seq); + return BoolOp(Or, seq, LINENO(n)); } break; case not_test: @@ -1452,7 +1463,7 @@ if (!expression) return NULL; - return UnaryOp(Not, expression); + return UnaryOp(Not, expression, LINENO(n)); } case comparison: if (NCH(n) == 1) { @@ -1489,7 +1500,7 @@ if (!expression) return NULL; - return Compare(expression, ops, cmps); + return Compare(expression, ops, cmps, LINENO(n)); } break; @@ -1522,11 +1533,11 @@ switch (TYPE(CHILD(n, 0))) { case PLUS: - return UnaryOp(UAdd, expression); + return UnaryOp(UAdd, expression, LINENO(n)); case MINUS: - return UnaryOp(USub, expression); + return UnaryOp(USub, expression, LINENO(n)); case TILDE: - return UnaryOp(Invert, expression); + return UnaryOp(Invert, expression, LINENO(n)); } break; } @@ -1548,7 +1559,7 @@ break; if (TYPE(CHILD(ch, 0)) == LPAR) { if (NCH(ch) == 2) - new = Call(new, NULL, NULL, NULL, NULL); + new = Call(new, NULL, NULL, NULL, NULL, LINENO(ch)); else new = ast_for_call(c, CHILD(ch, 1), new); @@ -1567,7 +1578,7 @@ return NULL; } - new = Subscript(e, slc, Load); + new = Subscript(e, slc, Load, LINENO(ch)); if (!new) { /* XXX free(e); */ /* XXX free(slc); */ @@ -1592,7 +1603,7 @@ } asdl_seq_SET(slices, j / 2, slc); } - new = Subscript(e, ExtSlice(slices), Load); + new = Subscript(e, ExtSlice(slices), Load, LINENO(ch)); if (!new) { /* XXX free(e); */ asdl_seq_free(slices); @@ -1602,7 +1613,8 @@ } else { assert(TYPE(CHILD(ch, 0)) == DOT); - new = Attribute(e, NEW_IDENTIFIER(CHILD(ch, 1)), Load); + new = Attribute(e, NEW_IDENTIFIER(CHILD(ch, 1)), Load, + LINENO(ch)); if (!new) { /* XXX free(e); */ return NULL; @@ -1616,7 +1628,7 @@ /* XXX free(e); */ return NULL; } - return BinOp(e, Pow, f); + return BinOp(e, Pow, f, LINENO(n)); } return e; } @@ -1659,9 +1671,16 @@ } } if (ngens > 1 || (ngens && (nargs || nkeywords))) { - ast_error(n, "Generator expression must be parenthesised if not sole argument"); + ast_error(n, "Generator expression must be parenthesised " + "if not sole argument"); return NULL; } + + if (nargs + nkeywords + ngens > 255) { + ast_error(n, "more than 255 arguments"); + return NULL; + } + args = asdl_seq_new(nargs + ngens); if (!args) goto error; @@ -1727,8 +1746,7 @@ } } - /* XXX syntax error if more than 255 arguments */ - return Call(func, args, keywords, vararg, kwarg); + return Call(func, args, keywords, vararg, kwarg, LINENO(n)); error: if (args) @@ -1751,7 +1769,7 @@ if (!tmp) return NULL; - return Tuple(tmp, Load); + return Tuple(tmp, Load, LINENO(n)); } } @@ -1816,26 +1834,20 @@ for (i = 0; i < NCH(n) - 2; i += 2) { expr_ty e = ast_for_testlist(c, CHILD(n, i)); - if (e->kind == GeneratorExp_kind) { - ast_error(CHILD(n, i), - "assignment to generator expression not possible"); - asdl_seq_free(targets); - return NULL; - } - /* set context to assign */ - if (!e) { - asdl_seq_free(targets); - return NULL; - } - if (!set_context(e, Store, CHILD(n, i))) { - asdl_seq_free(targets); - return NULL; - } + if (!e) + goto error; + + if (!set_context(e, Store, CHILD(n, i))) + goto error; + asdl_seq_SET(targets, i / 2, e); } expression = ast_for_testlist(c, CHILD(n, NCH(n) - 1)); return Assign(targets, expression, LINENO(n)); + error: + asdl_seq_free(targets); + return NULL; } return NULL; } @@ -2499,7 +2511,7 @@ asdl_seq_free(_target); } else - target = Tuple(_target, Store); + target = Tuple(_target, Store, LINENO(n)); expression = ast_for_testlist(c, CHILD(n, 3)); if (!expression) Index: newcompile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/Attic/newcompile.c,v retrieving revision 1.1.2.115 retrieving revision 1.1.2.116 diff -u -d -r1.1.2.115 -r1.1.2.116 --- newcompile.c 11 Oct 2005 22:54:03 -0000 1.1.2.115 +++ newcompile.c 12 Oct 2005 03:18:07 -0000 1.1.2.116 @@ -3463,7 +3463,7 @@ switch (e->kind) { case Attribute_kind: auge = Attribute(e->v.Attribute.value, e->v.Attribute.attr, - AugLoad); + AugLoad, e->lineno); if (auge == NULL) return 0; VISIT(c, expr, auge); @@ -3475,7 +3475,7 @@ break; case Subscript_kind: auge = Subscript(e->v.Subscript.value, e->v.Subscript.slice, - AugLoad); + AugLoad, e->lineno); if (auge == NULL) return 0; VISIT(c, expr, auge); From nnorwitz at gmail.com Wed Oct 12 05:50:53 2005 From: nnorwitz at gmail.com (Neal Norwitz) Date: Tue, 11 Oct 2005 20:50:53 -0700 Subject: [Python-checkins] python/dist/src/Objects unicodeobject.c, 2.231, 2.232 In-Reply-To: <20051006203001.283881E4003@bag.python.org> References: <20051006203001.283881E4003@bag.python.org> Message-ID: I don't have a problem with this checkin, but in reviewing it I noticed something. It seems that the exceptionObject (exc) is returned from unicode_decode_call_errorhandler(), but it is never used other than calling Py_XDECREF(exc). It looked like goto onError always followed a failure of unicode_decode_call_errorhandler(). Is this the case? Can exceptionObject be removed? I didn't look at any other parameter to determine if each was necessary. I didn't study it long enough to be sure exc can be removed, but it sure looked like it from a moderate inspection. If we could simplify this code it would be nice. n -- On 10/6/05, doerwalter at users.sourceforge.net wrote: > Update of /cvsroot/python/python/dist/src/Objects > In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6122/Objects > > Modified Files: > unicodeobject.c > Log Message: > Part of SF patch #1313939: Speedup charmap decoding by extending > PyUnicode_DecodeCharmap() the accept a unicode string as the mapping > argument which is used as a mapping table. > > This code isn't used by any of the codecs yet. > > > Index: unicodeobject.c > =================================================================== > RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v > retrieving revision 2.231 > retrieving revision 2.232 > diff -u -d -r2.231 -r2.232 > --- unicodeobject.c 30 Aug 2005 10:23:14 -0000 2.231 > +++ unicodeobject.c 6 Oct 2005 20:29:57 -0000 2.232 > @@ -2833,6 +2833,8 @@ > int extrachars = 0; > PyObject *errorHandler = NULL; > PyObject *exc = NULL; > + Py_UNICODE *mapstring = NULL; > + int maplen = 0; > > /* Default to Latin-1 */ > if (mapping == NULL) > @@ -2845,91 +2847,121 @@ > return (PyObject *)v; > p = PyUnicode_AS_UNICODE(v); > e = s + size; > - while (s < e) { > - unsigned char ch = *s; > - PyObject *w, *x; > + if (PyUnicode_CheckExact(mapping)) { > + mapstring = PyUnicode_AS_UNICODE(mapping); > + maplen = PyUnicode_GET_SIZE(mapping); > + while (s < e) { > + unsigned char ch = *s; > + Py_UNICODE x = 0xfffe; /* illegal value */ > > - /* Get mapping (char ordinal -> integer, Unicode char or None) */ > - w = PyInt_FromLong((long)ch); > - if (w == NULL) > - goto onError; > - x = PyObject_GetItem(mapping, w); > - Py_DECREF(w); > - if (x == NULL) { > - if (PyErr_ExceptionMatches(PyExc_LookupError)) { > - /* No mapping found means: mapping is undefined. */ > - PyErr_Clear(); > - x = Py_None; > - Py_INCREF(x); > - } else > - goto onError; > - } > + if (ch < maplen) > + x = mapstring[ch]; > > - /* Apply mapping */ > - if (PyInt_Check(x)) { > - long value = PyInt_AS_LONG(x); > - if (value < 0 || value > 65535) { > - PyErr_SetString(PyExc_TypeError, > - "character mapping must be in range(65536)"); > - Py_DECREF(x); > - goto onError; > + if (x == 0xfffe) { > + /* undefined mapping */ > + outpos = p-PyUnicode_AS_UNICODE(v); > + startinpos = s-starts; > + endinpos = startinpos+1; > + if (unicode_decode_call_errorhandler( > + errors, &errorHandler, > + "charmap", "character maps to ", > + starts, size, &startinpos, &endinpos, &exc, &s, > + (PyObject **)&v, &outpos, &p)) { > + goto onError; > + } > + continue; > } > - *p++ = (Py_UNICODE)value; > + *p++ = x; > + ++s; > } > - else if (x == Py_None) { > - /* undefined mapping */ > - outpos = p-PyUnicode_AS_UNICODE(v); > - startinpos = s-starts; > - endinpos = startinpos+1; > - if (unicode_decode_call_errorhandler( > - errors, &errorHandler, > - "charmap", "character maps to ", > - starts, size, &startinpos, &endinpos, &exc, &s, > - (PyObject **)&v, &outpos, &p)) { > - Py_DECREF(x); > + } > + else { > + while (s < e) { > + unsigned char ch = *s; > + PyObject *w, *x; > + > + /* Get mapping (char ordinal -> integer, Unicode char or None) */ > + w = PyInt_FromLong((long)ch); > + if (w == NULL) > goto onError; > + x = PyObject_GetItem(mapping, w); > + Py_DECREF(w); > + if (x == NULL) { > + if (PyErr_ExceptionMatches(PyExc_LookupError)) { > + /* No mapping found means: mapping is undefined. */ > + PyErr_Clear(); > + x = Py_None; > + Py_INCREF(x); > + } else > + goto onError; > } > - continue; > - } > - else if (PyUnicode_Check(x)) { > - int targetsize = PyUnicode_GET_SIZE(x); > - > - if (targetsize == 1) > - /* 1-1 mapping */ > - *p++ = *PyUnicode_AS_UNICODE(x); > - > - else if (targetsize > 1) { > - /* 1-n mapping */ > - if (targetsize > extrachars) { > - /* resize first */ > - int oldpos = (int)(p - PyUnicode_AS_UNICODE(v)); > - int needed = (targetsize - extrachars) + \ > - (targetsize << 2); > - extrachars += needed; > - if (_PyUnicode_Resize(&v, > - PyUnicode_GET_SIZE(v) + needed) < 0) { > - Py_DECREF(x); > - goto onError; > + > + /* Apply mapping */ > + if (PyInt_Check(x)) { > + long value = PyInt_AS_LONG(x); > + if (value < 0 || value > 65535) { > + PyErr_SetString(PyExc_TypeError, > + "character mapping must be in range(65536)"); > + Py_DECREF(x); > + goto onError; > + } > + *p++ = (Py_UNICODE)value; > + } > + else if (x == Py_None) { > + /* undefined mapping */ > + outpos = p-PyUnicode_AS_UNICODE(v); > + startinpos = s-starts; > + endinpos = startinpos+1; > + if (unicode_decode_call_errorhandler( > + errors, &errorHandler, > + "charmap", "character maps to ", > + starts, size, &startinpos, &endinpos, &exc, &s, > + (PyObject **)&v, &outpos, &p)) { > + Py_DECREF(x); > + goto onError; > + } > + continue; > + } > + else if (PyUnicode_Check(x)) { > + int targetsize = PyUnicode_GET_SIZE(x); > + > + if (targetsize == 1) > + /* 1-1 mapping */ > + *p++ = *PyUnicode_AS_UNICODE(x); > + > + else if (targetsize > 1) { > + /* 1-n mapping */ > + if (targetsize > extrachars) { > + /* resize first */ > + int oldpos = (int)(p - PyUnicode_AS_UNICODE(v)); > + int needed = (targetsize - extrachars) + \ > + (targetsize << 2); > + extrachars += needed; > + if (_PyUnicode_Resize(&v, > + PyUnicode_GET_SIZE(v) + needed) < 0) { > + Py_DECREF(x); > + goto onError; > + } > + p = PyUnicode_AS_UNICODE(v) + oldpos; > } > - p = PyUnicode_AS_UNICODE(v) + oldpos; > + Py_UNICODE_COPY(p, > + PyUnicode_AS_UNICODE(x), > + targetsize); > + p += targetsize; > + extrachars -= targetsize; > } > - Py_UNICODE_COPY(p, > - PyUnicode_AS_UNICODE(x), > - targetsize); > - p += targetsize; > - extrachars -= targetsize; > + /* 1-0 mapping: skip the character */ > + } > + else { > + /* wrong return value */ > + PyErr_SetString(PyExc_TypeError, > + "character mapping must return integer, None or unicode"); > + Py_DECREF(x); > + goto onError; > } > - /* 1-0 mapping: skip the character */ > - } > - else { > - /* wrong return value */ > - PyErr_SetString(PyExc_TypeError, > - "character mapping must return integer, None or unicode"); > Py_DECREF(x); > - goto onError; > + ++s; > } > - Py_DECREF(x); > - ++s; > } > if (p - PyUnicode_AS_UNICODE(v) < PyUnicode_GET_SIZE(v)) > if (_PyUnicode_Resize(&v, (int)(p - PyUnicode_AS_UNICODE(v))) < 0) > > _______________________________________________ > Python-checkins mailing list > Python-checkins at python.org > http://mail.python.org/mailman/listinfo/python-checkins > From nnorwitz at users.sourceforge.net Wed Oct 12 05:58:17 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Wed, 12 Oct 2005 05:58:17 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/api abstract.tex,1.35,1.36 Message-ID: <20051012035817.956951E4002@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/api In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19550/Doc/api Modified Files: abstract.tex Log Message: SF bug #1323739, C API doc for PySequence_Tuple duplicated Index: abstract.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/abstract.tex,v retrieving revision 1.35 retrieving revision 1.36 diff -u -d -r1.35 -r1.36 --- abstract.tex 7 Aug 2004 17:53:05 -0000 1.35 +++ abstract.tex 12 Oct 2005 03:58:14 -0000 1.36 @@ -778,12 +778,6 @@ the Python statement \samp{del \var{o}[\var{i1}:\var{i2}]}. \end{cfuncdesc} -\begin{cfuncdesc}{PyObject*}{PySequence_Tuple}{PyObject *o} - Returns the \var{o} as a tuple on success, and \NULL{} on failure. - This is equivalent to the Python expression \samp{tuple(\var{o})}. - \bifuncindex{tuple} -\end{cfuncdesc} - \begin{cfuncdesc}{int}{PySequence_Count}{PyObject *o, PyObject *value} Return the number of occurrences of \var{value} in \var{o}, that is, return the number of keys for which \code{\var{o}[\var{key}] == @@ -811,9 +805,11 @@ \begin{cfuncdesc}{PyObject*}{PySequence_Tuple}{PyObject *o} Return a tuple object with the same contents as the arbitrary - sequence \var{o}. If \var{o} is a tuple, a new reference will be - returned, otherwise a tuple will be constructed with the appropriate - contents. + sequence \var{o} or \NULL{} on failure. If \var{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 \samp{tuple(\var{o})}. + \bifuncindex{tuple} \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PySequence_Fast}{PyObject *o, const char *m} From nnorwitz at users.sourceforge.net Wed Oct 12 06:00:00 2005 From: nnorwitz at users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Wed, 12 Oct 2005 06:00:00 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/api abstract.tex, 1.35, 1.35.2.1 Message-ID: <20051012040000.17F141E4002@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/api In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19923/Doc/api Modified Files: Tag: release24-maint abstract.tex Log Message: Backport: SF bug #1323739, C API doc for PySequence_Tuple duplicated Index: abstract.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/abstract.tex,v retrieving revision 1.35 retrieving revision 1.35.2.1 diff -u -d -r1.35 -r1.35.2.1 --- abstract.tex 7 Aug 2004 17:53:05 -0000 1.35 +++ abstract.tex 12 Oct 2005 03:59:56 -0000 1.35.2.1 @@ -778,12 +778,6 @@ the Python statement \samp{del \var{o}[\var{i1}:\var{i2}]}. \end{cfuncdesc} -\begin{cfuncdesc}{PyObject*}{PySequence_Tuple}{PyObject *o} - Returns the \var{o} as a tuple on success, and \NULL{} on failure. - This is equivalent to the Python expression \samp{tuple(\var{o})}. - \bifuncindex{tuple} -\end{cfuncdesc} - \begin{cfuncdesc}{int}{PySequence_Count}{PyObject *o, PyObject *value} Return the number of occurrences of \var{value} in \var{o}, that is, return the number of keys for which \code{\var{o}[\var{key}] == @@ -811,9 +805,11 @@ \begin{cfuncdesc}{PyObject*}{PySequence_Tuple}{PyObject *o} Return a tuple object with the same contents as the arbitrary - sequence \var{o}. If \var{o} is a tuple, a new reference will be - returned, otherwise a tuple will be constructed with the appropriate - contents. + sequence \var{o} or \NULL{} on failure. If \var{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 \samp{tuple(\var{o})}. + \bifuncindex{tuple} \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PySequence_Fast}{PyObject *o, const char *m} From walter at livinglogic.de Wed Oct 12 09:40:54 2005 From: walter at livinglogic.de (=?ISO-8859-1?Q?Walter_D=F6rwald?=) Date: Wed, 12 Oct 2005 09:40:54 +0200 Subject: [Python-checkins] python/dist/src/Objects unicodeobject.c, 2.231, 2.232 In-Reply-To: References: <20051006203001.283881E4003@bag.python.org> Message-ID: <3982ACF8-A08B-4EB0-97FA-C98367156530@livinglogic.de> Am 12.10.2005 um 05:50 schrieb Neal Norwitz: > I don't have a problem with this checkin, but in reviewing it I > noticed something. It seems that the exceptionObject (exc) is > returned from unicode_decode_call_errorhandler(), but it is never used > other than calling Py_XDECREF(exc). It looked like goto onError > always followed a failure of unicode_decode_call_errorhandler(). It does, but when unicode_decode_call_errorhandler() *doesn't* fail, it might be called a second time later on. For performance reasons unicode_decode_call_errorhandler() then doesn't create a new exception object to be passed to the error handler, but reuses the old one (the PEP explicitely allows this). > Is this the case? Can exceptionObject be removed? I didn't look at > any other parameter to determine if each was necessary. I didn't > study it long enough to be sure exc can be removed, but it sure looked > like it from a moderate inspection. > > If we could simplify this code it would be nice. Yes, but I don't see how. Bye, Walter D?rwald From marketing at omtel.co.za Wed Oct 12 16:07:40 2005 From: marketing at omtel.co.za (Omtel) Date: Wed, 12 Oct 2005 16:07:40 +0200 Subject: [Python-checkins] Your registration at OMTEL Message-ID: <614e80ac5bd11bb9831dd4271fca831e@www.mailerdemon.co.za> Many thanks for your inquiry on OMTEL You want to reduce considerable your phone costs with OMTEL. You want to phone free of charge? You want to open a callshop? You want to represent our company in your country? You get all information about on our homepage http://www.omtel.de Register yourselve on our registration area and you will get all further information. We are available for further inquiries under marketing at omtel.co.za Yours sincerely Your OMTEL team This is a automatic generated e-mail. Should this e-mail not be wished by you or by a mistake reached you, please inform us. From akuchling at users.sourceforge.net Wed Oct 12 18:08:32 2005 From: akuchling at users.sourceforge.net (akuchling@users.sourceforge.net) Date: Wed, 12 Oct 2005 18:08:32 +0200 (CEST) Subject: [Python-checkins] python/nondist/peps pep2html.py,1.53,1.54 Message-ID: <20051012160832.3993E1E4002@bag.python.org> Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24750 Modified Files: pep2html.py Log Message: Use new www server hostname Index: pep2html.py =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep2html.py,v retrieving revision 1.53 retrieving revision 1.54 diff -u -d -r1.53 -r1.54 --- pep2html.py 19 Jul 2004 19:05:01 -0000 1.53 +++ pep2html.py 12 Oct 2005 16:08:28 -0000 1.54 @@ -23,7 +23,7 @@ -l, --local Same as -i/--install, except install on the local machine. Use this - when logged in to the python.org machine (creosote). + when logged in to the python.org machine (dinsdale). -q, --quiet Turn off verbose messages. @@ -54,7 +54,7 @@ PEPDIRRUL = 'http://www.python.org/peps/' -HOST = "www.python.org" # host for update +HOST = "dinsdale.python.org" # host for update HDIR = "/ftp/ftp.python.org/pub/www.python.org/peps" # target host directory LOCALVARS = "Local Variables:" From nascheme at users.sourceforge.net Thu Oct 13 01:36:14 2005 From: nascheme at users.sourceforge.net (nascheme@users.sourceforge.net) Date: Thu, 13 Oct 2005 01:36:14 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Python newcompile.c, 1.1.2.116, 1.1.2.117 Message-ID: <20051012233614.9B4A81E4110@bag.python.org> Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16154/Python Modified Files: Tag: ast-branch newcompile.c Log Message: Update u_lineno when generating code for expressions. Index: newcompile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/Attic/newcompile.c,v retrieving revision 1.1.2.116 retrieving revision 1.1.2.117 diff -u -d -r1.1.2.116 -r1.1.2.117 --- newcompile.c 12 Oct 2005 03:18:07 -0000 1.1.2.116 +++ newcompile.c 12 Oct 2005 23:36:09 -0000 1.1.2.117 @@ -3344,6 +3344,11 @@ { int i, n; + fprintf(stderr, "compile expr %d lineno %d %d\n", e->kind, e->lineno); + if (e->lineno > c->u->u_lineno) { + c->u->u_lineno = e->lineno; + c->u->u_lineno_set = false; + } switch (e->kind) { case BoolOp_kind: return compiler_boolop(c, e); From nascheme at users.sourceforge.net Thu Oct 13 02:32:48 2005 From: nascheme at users.sourceforge.net (nascheme@users.sourceforge.net) Date: Thu, 13 Oct 2005 02:32:48 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Python newcompile.c, 1.1.2.117, 1.1.2.118 Message-ID: <20051013003248.37C7F1E4002@bag.python.org> Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30515/Python Modified Files: Tag: ast-branch newcompile.c Log Message: Move comment to correct location. Fix a bug in a debug print statement. Index: newcompile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/Attic/newcompile.c,v retrieving revision 1.1.2.117 retrieving revision 1.1.2.118 diff -u -d -r1.1.2.117 -r1.1.2.118 --- newcompile.c 12 Oct 2005 23:36:09 -0000 1.1.2.117 +++ newcompile.c 13 Oct 2005 00:32:45 -0000 1.1.2.118 @@ -1414,10 +1414,6 @@ return b->b_iused++; } -/* Add an opcode with no argument. - Returns 0 on failure, 1 on success. -*/ - static void compiler_set_lineno(struct compiler *c, int off) { @@ -1646,6 +1642,10 @@ return 0; /* not reachable */ } +/* Add an opcode with no argument. + Returns 0 on failure, 1 on success. +*/ + static int compiler_addop(struct compiler *c, int opcode) { @@ -3344,7 +3344,7 @@ { int i, n; - fprintf(stderr, "compile expr %d lineno %d %d\n", e->kind, e->lineno); + fprintf(stderr, "compile expr %d lineno %d\n", e->kind, e->lineno); if (e->lineno > c->u->u_lineno) { c->u->u_lineno = e->lineno; c->u->u_lineno_set = false; From nascheme at users.sourceforge.net Thu Oct 13 06:46:02 2005 From: nascheme at users.sourceforge.net (nascheme@users.sourceforge.net) Date: Thu, 13 Oct 2005 06:46:02 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Python newcompile.c, 1.1.2.118, 1.1.2.119 Message-ID: <20051013044602.28A711E4005@bag.python.org> Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12137/Python Modified Files: Tag: ast-branch newcompile.c Log Message: The line number for the first instruction of a unit may not be co_firstlineno. Fix that. Also, set firstlineno properly for Lambda and GenExpr nodes. Index: newcompile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/Attic/newcompile.c,v retrieving revision 1.1.2.118 retrieving revision 1.1.2.119 diff -u -d -r1.1.2.118 -r1.1.2.119 --- newcompile.c 13 Oct 2005 00:32:45 -0000 1.1.2.118 +++ newcompile.c 13 Oct 2005 04:45:58 -0000 1.1.2.119 @@ -2150,7 +2150,7 @@ if (args->defaults) VISIT_SEQ(c, expr, args->defaults); - if (!compiler_enter_scope(c, name, (void *)e, c->u->u_lineno)) + if (!compiler_enter_scope(c, name, (void *)e, e->lineno)) return 0; /* unpack nested arguments */ @@ -3293,7 +3293,7 @@ if (!name) return 0; - if (!compiler_enter_scope(c, name, (void *)e, c->u->u_lineno)) + if (!compiler_enter_scope(c, name, (void *)e, e->lineno)) return 0; compiler_genexp_generator(c, e->v.GeneratorExp.generators, 0, e->v.GeneratorExp.elt); @@ -3797,10 +3797,10 @@ } static int -assemble_init(struct assembler *a, int nblocks) +assemble_init(struct assembler *a, int nblocks, int firstlineno) { memset(a, 0, sizeof(struct assembler)); - a->a_lineno = 1; + a->a_lineno = firstlineno; a->a_bytecode = PyString_FromStringAndSize(NULL, DEFAULT_CODE_SIZE); if (!a->a_bytecode) return 0; @@ -3987,7 +3987,7 @@ } else { /* First line of a block; def stmt, etc. */ *lnotab++ = 0; - *lnotab++ = 1; + *lnotab++ = d_lineno; } a->a_lineno = i->i_lineno; a->a_lineno_off = a->a_offset; @@ -4226,7 +4226,7 @@ entryblock = b; } - if (!assemble_init(&a, nblocks)) + if (!assemble_init(&a, nblocks, c->u->u_firstlineno)) goto error; dfs(c, entryblock, &a); From kzl665544 at eyou.com Thu Oct 13 08:56:47 2005 From: kzl665544 at eyou.com (Paul) Date: Thu, 13 Oct 2005 14:56:47 +0800 Subject: [Python-checkins] Marketing for you Message-ID: <20051013065644.25D651E4002@bag.python.org> Dear python-checkins at python.org: We specializing in E-mail Marketing. 1. Targeted list We may provide targeted email list. We will customize the list according to your requirements. 2. Sending out Targeted Marketing for you We may send your email message to your target clients! We will customize your email list and send your message for you. * We offer BP web Hosting & mail server. Regards! Paul Marketing Team kezunli321 at yeah.net To Bye: PaulNo at hotmail.com From jhylton at users.sourceforge.net Thu Oct 13 17:42:44 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Thu, 13 Oct 2005 17:42:44 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Python ast.c,1.1.2.66,1.1.2.67 Message-ID: <20051013154244.790711E4002@bag.python.org> Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13934/Python Modified Files: Tag: ast-branch ast.c Log Message: Fix two separate problems. Generate expected error for assignments to literals, e.g. 1 = 1 or (1,) = 1. Fix assignment of lineno for FromImport statements: Use the line number of the module being imported, not of the names being bound from it. Fixes test_future. Index: ast.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/Attic/ast.c,v retrieving revision 1.1.2.66 retrieving revision 1.1.2.67 diff -u -d -r1.1.2.66 -r1.1.2.67 --- ast.c 12 Oct 2005 03:18:07 -0000 1.1.2.66 +++ ast.c 13 Oct 2005 15:42:40 -0000 1.1.2.67 @@ -392,10 +392,20 @@ case GeneratorExp_kind: return ast_error(n, "assignment to generator expression " "not possible"); - default: - return ast_error(n, "unexpected node in assignment"); - break; + case Num_kind: + case Str_kind: + return ast_error(n, "can't assign to literal"); + default: { + char buf[300]; + PyOS_snprintf(buf, sizeof(buf), + "unexpected expression in assignment %d (line %d)", + e->kind, e->lineno); + return ast_error(n, buf); + } } + /* If the LHS is a list or tuple, we need to set the assignment + context for all the tuple elements. + */ if (s) { int i; @@ -2112,6 +2122,7 @@ stmt_ty import; int n_children; const char *from_modules; + int lineno = LINENO(n); alias_ty mod = alias_for_import_name(CHILD(n, 1)); if (!mod) return NULL; @@ -2129,7 +2140,7 @@ } } else if (from_modules[0] == '*') { - n = CHILD(n,3); /* from ... import * */ + n = CHILD(n, 3); /* from ... import * */ } else if (from_modules[0] == '(') n = CHILD(n, 4); /* from ... import (x, y, z) */ @@ -2166,7 +2177,7 @@ } asdl_seq_APPEND(aliases, import_alias); } - import = ImportFrom(mod->name, aliases, LINENO(n)); + import = ImportFrom(mod->name, aliases, lineno); free(mod); return import; } From jhylton at users.sourceforge.net Thu Oct 13 18:11:19 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Thu, 13 Oct 2005 18:11:19 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib/test test_genexps.py, 1.7.4.1, 1.7.4.2 Message-ID: <20051013161119.128551E4002@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22475/Lib/test Modified Files: Tag: ast-branch test_genexps.py Log Message: Track change to genexp syntax error string. Index: test_genexps.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_genexps.py,v retrieving revision 1.7.4.1 retrieving revision 1.7.4.2 diff -u -d -r1.7.4.1 -r1.7.4.2 --- test_genexps.py 7 Jan 2005 06:59:09 -0000 1.7.4.1 +++ test_genexps.py 13 Oct 2005 16:11:15 -0000 1.7.4.2 @@ -125,12 +125,13 @@ >>> (y for y in (1,2)) = 10 Traceback (most recent call last): ... - SyntaxError: assign to generator expression not possible + SyntaxError: assignment to generator expression not possible (, line 1) >>> (y for y in (1,2)) += 10 Traceback (most recent call last): ... - SyntaxError: augmented assign to tuple literal or generator expression not possible + SyntaxError: augmented assignment to generator expression not possible (, line 1) + From nascheme at users.sourceforge.net Thu Oct 13 18:58:43 2005 From: nascheme at users.sourceforge.net (nascheme@users.sourceforge.net) Date: Thu, 13 Oct 2005 18:58:43 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Lib/test test_trace.py, 1.7.10.2, 1.7.10.3 Message-ID: <20051013165843.209021E4002@bag.python.org> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv679/Lib/test Modified Files: Tag: ast-branch test_trace.py Log Message: Disable tests that cause the interpreter to crash. I think frame_setlineno() needs to be fixed. Index: test_trace.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_trace.py,v retrieving revision 1.7.10.2 retrieving revision 1.7.10.3 diff -u -d -r1.7.10.2 -r1.7.10.3 --- test_trace.py 7 Jan 2005 06:59:13 -0000 1.7.10.2 +++ test_trace.py 13 Oct 2005 16:58:39 -0000 1.7.10.3 @@ -576,14 +576,17 @@ self.run_test(no_jump_too_far_forwards) def test_09_no_jump_too_far_backwards(self): self.run_test(no_jump_too_far_backwards) - def test_10_no_jump_to_except_1(self): - self.run_test(no_jump_to_except_1) - def test_11_no_jump_to_except_2(self): - self.run_test(no_jump_to_except_2) - def test_12_no_jump_to_except_3(self): - self.run_test(no_jump_to_except_3) - def test_13_no_jump_to_except_4(self): - self.run_test(no_jump_to_except_4) +# XXX: These tests cause the interpreter to crash. The frame_setlineno() +# function no longer works correctly because the lineno table generated by +# the AST compiler is slightly different than with the old compiler. +# def test_10_no_jump_to_except_1(self): +# self.run_test(no_jump_to_except_1) +# def test_11_no_jump_to_except_2(self): +# self.run_test(no_jump_to_except_2) +# def test_12_no_jump_to_except_3(self): +# self.run_test(no_jump_to_except_3) +# def test_13_no_jump_to_except_4(self): +# self.run_test(no_jump_to_except_4) def test_14_no_jump_forwards_into_block(self): self.run_test(no_jump_forwards_into_block) def test_15_no_jump_backwards_into_block(self): From gvanrossum at users.sourceforge.net Thu Oct 13 23:04:18 2005 From: gvanrossum at users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 13 Oct 2005 23:04:18 +0200 (CEST) Subject: [Python-checkins] python/nondist/peps pep2html.py,1.54,1.55 Message-ID: <20051013210418.888F81E4002@bag.python.org> Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27627 Modified Files: pep2html.py Log Message: The root of the tree on dinsdale is /data, not /ftp. Index: pep2html.py =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep2html.py,v retrieving revision 1.54 retrieving revision 1.55 diff -u -d -r1.54 -r1.55 --- pep2html.py 12 Oct 2005 16:08:28 -0000 1.54 +++ pep2html.py 13 Oct 2005 21:04:15 -0000 1.55 @@ -55,7 +55,7 @@ HOST = "dinsdale.python.org" # host for update -HDIR = "/ftp/ftp.python.org/pub/www.python.org/peps" # target host directory +HDIR = "/data/ftp.python.org/pub/www.python.org/peps" # target host directory LOCALVARS = "Local Variables:" COMMENT = """", self.name if self.condition: Output() @@ -50,6 +60,8 @@ OutRbrace() def reference(self, name = None): + if not self.checkgenerate(): + return if name is None: name = self.name docstring = self.docstring() @@ -175,17 +187,8 @@ arg.declare() def getargs(self): - fmt = "" - lst = "" sep = ",\n" + ' '*len("if (!PyArg_ParseTuple(") - for arg in self.argumentList: - if arg.flags == SelfMode: - continue - if arg.mode in (InMode, InOutMode): - fmt = fmt + arg.getargsFormat() - args = arg.getargsArgs() - if args: - lst = lst + sep + args + fmt, lst = self.getargsFormatArgs(sep) Output("if (!PyArg_ParseTuple(_args, \"%s\"%s))", fmt, lst) IndentLevel() Output("return NULL;") @@ -196,15 +199,32 @@ if arg.mode in (InMode, InOutMode): arg.getargsCheck() + def getargsFormatArgs(self, sep): + fmt = "" + lst = "" + for arg in self.argumentList: + if arg.flags == SelfMode: + continue + if arg.mode in (InMode, InOutMode): + arg.getargsPreCheck() + fmt = fmt + arg.getargsFormat() + args = arg.getargsArgs() + if args: + lst = lst + sep + args + return fmt, lst + def precheck(self): pass + def beginallowthreads(self): + pass + + def endallowthreads(self): + pass + def callit(self): args = "" - if self.rv: - s = "%s = %s(" % (self.rv.name, self.name) - else: - s = "%s(" % self.name + s = "%s%s(" % (self.getrvforcallit(), self.callname) sep = ",\n" + ' '*len(s) for arg in self.argumentList: if arg is self.rv: @@ -212,26 +232,24 @@ s = arg.passArgument() if args: s = sep + s args = args + s + self.beginallowthreads() + Output("%s%s(%s);", + self.getrvforcallit(), self.callname, args) + self.endallowthreads() + + def getrvforcallit(self): if self.rv: - Output("%s = %s(%s);", - self.rv.name, self.name, args) + return "%s = " % self.rv.name else: - Output("%s(%s);", self.name, args) + return "" def checkit(self): for arg in self.argumentList: arg.errorCheck() def returnvalue(self): - fmt = "" - lst = "" sep = ",\n" + ' '*len("return Py_BuildValue(") - for arg in self.argumentList: - if not arg: continue - if arg.flags == ErrorMode: continue - if arg.mode in (OutMode, InOutMode): - fmt = fmt + arg.mkvalueFormat() - lst = lst + sep + arg.mkvalueArgs() + fmt, lst = self.mkvalueFormatArgs(sep) if fmt == "": Output("Py_INCREF(Py_None);") Output("_res = Py_None;"); @@ -244,6 +262,17 @@ arg.cleanup() Output("return _res;") + def mkvalueFormatArgs(self, sep): + fmt = "" + lst = "" + for arg in self.argumentList: + if not arg: continue + if arg.flags == ErrorMode: continue + if arg.mode in (OutMode, InOutMode): + arg.mkvaluePreCheck() + fmt = fmt + arg.mkvalueFormat() + lst = lst + sep + arg.mkvalueArgs() + return fmt, lst class MethodGenerator(FunctionGenerator): @@ -256,7 +285,6 @@ self.argumentList.append(self.itself) FunctionGenerator.parseArgumentList(self, args) - def _test(): void = None eggs = FunctionGenerator(void, "eggs", Index: bgenHeapBuffer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenHeapBuffer.py,v retrieving revision 1.3.16.2 retrieving revision 1.3.16.3 diff -u -d -r1.3.16.2 -r1.3.16.3 --- bgenHeapBuffer.py 7 Jan 2005 07:05:04 -0000 1.3.16.2 +++ bgenHeapBuffer.py 16 Oct 2005 05:24:06 -0000 1.3.16.3 @@ -16,8 +16,10 @@ def __init__(self, datatype = 'char', sizetype = 'int', sizeformat = None): FixedInputOutputBufferType.__init__(self, "0", datatype, sizetype, sizeformat) - def declareOutputBuffer(self, name): - Output("%s *%s__out__;", self.datatype, name) + def getOutputBufferDeclarations(self, name, constmode=False): + if constmode: + raise RuntimeError, "Cannot use const output buffer" + return ["%s *%s__out__" % (self.datatype, name)] def getargsCheck(self, name): Output("if ((%s__out__ = malloc(%s__in_len__)) == NULL)", name, name) @@ -74,8 +76,8 @@ Call from Python with buffer size. """ - def declareInputBuffer(self, name): - pass + def getInputBufferDeclarations(self, name, constmode=False): + return [] def getargsFormat(self): return "i" @@ -109,3 +111,32 @@ def passOutput(self, name): return "%s__out__, %s__len__, &%s__len__" % (name, name, name) + +class MallocHeapOutputBufferType(HeapOutputBufferType): + """Output buffer allocated by the called function -- passed as (&buffer, &size). + + Instantiate without parameters. + Call from Python without parameters. + """ + + def getargsCheck(self, name): + Output("%s__out__ = NULL;", name) + + def getAuxDeclarations(self, name): + return [] + + def passOutput(self, name): + return "&%s__out__, &%s__len__" % (name, name) + + def getargsFormat(self): + return "" + + def getargsArgs(self, name): + return None + + def mkvalueFormat(self): + return "z#" + + def cleanup(self, name): + Output("if( %s__out__ ) free(%s__out__);", name, name) + Index: bgenObjectDefinition.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenObjectDefinition.py,v retrieving revision 1.16.2.2 retrieving revision 1.16.2.3 diff -u -d -r1.16.2.2 -r1.16.2.3 --- bgenObjectDefinition.py 7 Jan 2005 07:05:04 -0000 1.16.2.2 +++ bgenObjectDefinition.py 16 Oct 2005 05:24:06 -0000 1.16.2.3 @@ -6,6 +6,7 @@ basechain = "NULL" tp_flags = "Py_TPFLAGS_DEFAULT" basetype = None + argref = "" # set to "*" if arg to _New should be pointer def __init__(self, name, prefix, itselftype): """ObjectDefinition constructor. May be extended, but do not override. @@ -22,7 +23,6 @@ self.itselftype = itselftype self.objecttype = name + 'Object' self.typename = name + '_Type' - self.argref = "" # set to "*" if arg to _New should be pointer self.static = "static " # set to "" to make _New and _Convert public self.modulename = None if hasattr(self, "assertions"): @@ -44,12 +44,8 @@ OutHeader2("Object type " + self.name) - sf = self.static and "static " - Output("%sPyTypeObject %s;", sf, self.typename) - Output() - Output("#define %s_Check(x) ((x)->ob_type == &%s || PyObject_TypeCheck((x), &%s))", - self.prefix, self.typename, self.typename) - Output() + self.outputCheck() + Output("typedef struct %s {", self.objecttype) IndentLevel() Output("PyObject_HEAD") @@ -84,6 +80,14 @@ OutHeader2("End object type " + self.name) + def outputCheck(self): + sf = self.static and "static " + Output("%sPyTypeObject %s;", sf, self.typename) + Output() + Output("#define %s_Check(x) ((x)->ob_type == &%s || PyObject_TypeCheck((x), &%s))", + self.prefix, self.typename, self.typename) + Output() + def outputMethodChain(self): Output("%sPyMethodChain %s_chain = { %s_methods, %s };", self.static, self.prefix, self.prefix, self.basechain) @@ -113,6 +117,7 @@ "Override this method to apply additional checks/conversions" def outputConvert(self): + Output() Output("%sint %s_Convert(PyObject *v, %s *p_itself)", self.static, self.prefix, self.itselftype) OutLbrace() @@ -214,6 +219,9 @@ Output("if (PyType_Ready(&%s) < 0) return;", self.typename) Output("""Py_INCREF(&%s);""", self.typename) Output("PyModule_AddObject(m, \"%s\", (PyObject *)&%s);", self.name, self.typename); + self.outputTypeObjectInitializerCompat() + + def outputTypeObjectInitializerCompat(self): Output("/* Backward-compatible name */") Output("""Py_INCREF(&%s);""", self.typename); Output("PyModule_AddObject(m, \"%sType\", (PyObject *)&%s);", self.name, self.typename); @@ -377,7 +385,7 @@ def output_tp_init(self): if self.output_tp_initBody: - Output("static int %s_tp_init(PyObject *self, PyObject *args, PyObject *kwds)", self.prefix) + Output("static int %s_tp_init(PyObject *_self, PyObject *_args, PyObject *_kwds)", self.prefix) OutLbrace() self.output_tp_initBody() OutRbrace() @@ -399,19 +407,19 @@ Output() def output_tp_newBody(self): - Output("PyObject *self;"); + Output("PyObject *_self;"); Output("%s itself;", self.itselftype); Output("char *kw[] = {\"itself\", 0};") Output() - Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"O&\", kw, %s_Convert, &itself)) return NULL;", + Output("if (!PyArg_ParseTupleAndKeywords(_args, _kwds, \"O&\", kw, %s_Convert, &itself)) return NULL;", self.prefix); - Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;") - Output("((%s *)self)->ob_itself = itself;", self.objecttype) - Output("return self;") + Output("if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;") + Output("((%s *)_self)->ob_itself = itself;", self.objecttype) + Output("return _self;") def output_tp_new(self): if self.output_tp_newBody: - Output("static PyObject *%s_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)", self.prefix) + Output("static PyObject *%s_tp_new(PyTypeObject *type, PyObject *_args, PyObject *_kwds)", self.prefix) OutLbrace() self.output_tp_newBody() OutRbrace() Index: bgenStackBuffer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenStackBuffer.py,v retrieving revision 1.2.30.1 retrieving revision 1.2.30.2 diff -u -d -r1.2.30.1 -r1.2.30.2 --- bgenStackBuffer.py 28 Apr 2003 17:16:37 -0000 1.2.30.1 +++ bgenStackBuffer.py 16 Oct 2005 05:24:06 -0000 1.2.30.2 @@ -22,8 +22,11 @@ Instantiate with the buffer size as parameter. """ - def declareSize(self, name): - Output("int %s__len__ = %s;", name, self.size) + def getSizeDeclarations(self, name): + return [] + + def getAuxDeclarations(self, name): + return ["int %s__len__ = %s" % (name, self.size)] def passOutput(self, name): return "%s__out__, &%s__len__" % (name, name) Index: bgenStringBuffer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenStringBuffer.py,v retrieving revision 1.1.30.2 retrieving revision 1.1.30.3 diff -u -d -r1.1.30.2 -r1.1.30.3 --- bgenStringBuffer.py 7 Jan 2005 07:05:04 -0000 1.1.30.2 +++ bgenStringBuffer.py 16 Oct 2005 05:24:06 -0000 1.1.30.3 @@ -23,8 +23,11 @@ less common. I'll write the classes when there is demand.) """ - def declareSize(self, name): - pass + def getSizeDeclarations(self, name): + return [] + + def getAuxDeclarations(self, name): + return [] def getargsFormat(self): return "s" Index: bgenType.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenType.py,v retrieving revision 1.9.2.2 retrieving revision 1.9.2.3 diff -u -d -r1.9.2.2 -r1.9.2.3 --- bgenType.py 7 Jan 2005 07:05:05 -0000 1.9.2.2 +++ bgenType.py 16 Oct 2005 05:24:06 -0000 1.9.2.3 @@ -19,12 +19,34 @@ self.typeName = typeName self.fmt = fmt - def declare(self, name): + def declare(self, name, reference=False): """Declare a variable of the type with a given name. Example: int.declare('spam') prints "int spam;" """ - Output("%s %s;", self.typeName, name) + for decl in self.getArgDeclarations(name, reference): + Output("%s;", decl) + for decl in self.getAuxDeclarations(name): + Output("%s;", decl) + + def getArgDeclarations(self, name, reference=False, constmode=False): + """Return the main part of the declarations for this type: the items + that will be passed as arguments in the C/C++ function call.""" + if reference: + ref = "&" + else: + ref = "" + if constmode: + const = "const " + else: + const = "" + return ["%s%s%s %s" % (const, self.typeName, ref, name)] + + def getAuxDeclarations(self, name): + """Return any auxiliary declarations needed for implementing this + type, such as helper variables used to hold sizes, etc. These declarations + are not part of the C/C++ function call interface.""" + return [] def getargs(self): return self.getargsFormat(), self.getargsArgs() @@ -44,11 +66,18 @@ """ return "&" + name + def getargsPreCheck(self, name): + """Perform any actions needed before calling getargs(). + + This could include declaring temporary variables and such. + """ + def getargsCheck(self, name): """Perform any needed post-[new]getargs() checks. This is type-dependent; the default does not check for errors. - An example would be a check for a maximum string length.""" + An example would be a check for a maximum string length, or it + could do post-getargs() copying or conversion.""" def passInput(self, name): """Return an argument for passing a variable into a call. @@ -64,6 +93,12 @@ """ return "&" + name + def passReference(self, name): + """Return an argument for C++ pass-by-reference. + Default is to call passInput(). + """ + return self.passInput(name) + def errorCheck(self, name): """Check for an error returned in the variable. @@ -96,6 +131,12 @@ """ return name + def mkvaluePreCheck(self, name): + """Perform any actions needed before calling mkvalue(). + + This could include declaring temporary variables and such. + """ + def cleanup(self, name): """Clean up if necessary. @@ -172,8 +213,11 @@ self.substitute = substitute self.typeName = None # Don't show this argument in __doc__ string - def declare(self, name): - pass + def getArgDeclarations(self, name, reference=False, constmode=False): + return [] + + def getAuxDeclarations(self, name, reference=False): + return [] def getargsFormat(self): return "" @@ -237,6 +281,25 @@ def mkvalueArgs(self, name): return "%s, %s" % (self.new, name) +class OpaqueByRefType(OpaqueType): + """An opaque object type, passed by reference. + + Instantiate with the type name, and optionally an object type name whose + New/Convert functions will be used. + """ + + def passInput(self, name): + return name + +# def passOutput(self, name): +# return name + + def mkvalueFormat(self): + return "O" + + def mkvalueArgs(self, name): + return "%s(%s)" % (self.new, name) + class OpaqueByValueStructType(OpaqueByValueType): """Similar to OpaqueByValueType, but we also pass this to mkvalue by address, in stead of by value. Index: bgenVariable.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenVariable.py,v retrieving revision 1.1.30.1 retrieving revision 1.1.30.2 diff -u -d -r1.1.30.1 -r1.1.30.2 --- bgenVariable.py 28 Apr 2003 17:16:37 -0000 1.1.30.1 +++ bgenVariable.py 16 Oct 2005 05:24:06 -0000 1.1.30.2 @@ -13,7 +13,8 @@ SelfMode = 4+InMode # this is 'self' -- don't declare it ReturnMode = 8+OutMode # this is the function return value ErrorMode = 16+OutMode # this is an error status -- turn it into an exception - +RefMode = 32 +ConstMode = 64 class Variable: @@ -39,9 +40,21 @@ If it is "self", it is not declared. """ - if self.flags != SelfMode: + if self.flags == ReturnMode+RefMode: + self.type.declare(self.name, reference=True) + elif self.flags != SelfMode: self.type.declare(self.name) + def getArgDeclarations(self, constmode=False): + refmode = (self.flags & RefMode) + if constmode: + constmode = (self.flags & ConstMode) + return self.type.getArgDeclarations(self.name, + reference=refmode, constmode=constmode) + + def getAuxDeclarations(self): + return self.type.getAuxDeclarations(self.name) + def getargsFormat(self): """Call the type's getargsFormatmethod.""" return self.type.getargsFormat() @@ -53,6 +66,9 @@ def getargsCheck(self): return self.type.getargsCheck(self.name) + def getargsPreCheck(self): + return self.type.getargsPreCheck(self.name) + def passArgument(self): """Return the string required to pass the variable as argument. @@ -62,6 +78,8 @@ """ if self.mode == InMode: return self.type.passInput(self.name) + if self.mode & RefMode: + return self.type.passReference(self.name) if self.mode in (OutMode, InOutMode): return self.type.passOutput(self.name) # XXX Shouldn't get here @@ -83,6 +101,9 @@ """Call the type's mkvalueArgs method.""" return self.type.mkvalueArgs(self.name) + def mkvaluePreCheck(self): + return self.type.mkvaluePreCheck(self.name) + def cleanup(self): """Call the type's cleanup method.""" return self.type.cleanup(self.name) Index: scantools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/scantools.py,v retrieving revision 1.28.2.2 retrieving revision 1.28.2.3 diff -u -d -r1.28.2.2 -r1.28.2.3 --- scantools.py 7 Jan 2005 07:05:05 -0000 1.28.2.2 +++ scantools.py 16 Oct 2005 05:24:06 -0000 1.28.2.3 @@ -32,6 +32,76 @@ Error = "scantools.Error" +BEGINHTMLREPORT=""" + + + +Bgen scan report + + +

Bgen scan report

+

Legend

+

This scan report is intended to help you debug the regular expressions +used by the bgen scanner. It consists of the original ".h" header file(s) +marked up to show you what the regular expressions in the bgen parser matched +for each line. NOTE: comments in the original source files may or may not be +shown.

+

The typographic conventions of this file are as follows:

+
+
comment stripping
+
comment stripping is /* marked up */ and the line is repeated if needed
+

If anything here does not appear to happen correctly look at +comment1_pat and comment2_pat.

+
+
constant definitions
+
#define name value
+

Highlights name and value of the constant. Governed by sym_pat.

+
+
function declaration
+
char *rindex(const char *s, int c);
+

Highlights type, name and argument list. type_pat, +name_pat and args_pat are combined into whole_pat, which +is what is used here.

+ +
incomplete match for function declaration
+
char *foo;
+

The beginning of this looked promising, but it did not match a function declaration. +In other words, it matched head_pat but not whole_pat. If the next +declaration has also been gobbled up you need to look at end_pat.

+
+
unrecognized input
+
#include "type.h"
+

If there are function declarations the scanner has missed (i.e. things +are in this class but you want them to be declarations) you need to adapt +head_pat. +

+
+

Output

+
+
+"""
+ENDHTMLREPORT="""
+
+ + +""" + class Scanner: # Set to 1 in subclass to debug your scanner patterns. @@ -232,9 +302,11 @@ self.specmine = 0 self.defsmine = 0 self.scanmine = 0 + self.htmlmine = 0 self.specfile = sys.stdout self.defsfile = None self.scanfile = sys.stdin + self.htmlfile = None self.lineno = 0 self.line = "" @@ -286,6 +358,7 @@ self.closespec() self.closedefs() self.closescan() + self.closehtml() def closespec(self): tmp = self.specmine and self.specfile @@ -302,6 +375,12 @@ self.scanfile = None if tmp: tmp.close() + def closehtml(self): + if self.htmlfile: self.htmlfile.write(ENDHTMLREPORT) + tmp = self.htmlmine and self.htmlfile + self.htmlfile = None + if tmp: tmp.close() + def setoutput(self, spec, defs = None): self.closespec() self.closedefs() @@ -324,6 +403,19 @@ self.defsfile = file self.defsmine = mine + def sethtmloutput(self, htmlfile): + self.closehtml() + if htmlfile: + if type(htmlfile) == StringType: + file = self.openoutput(htmlfile) + mine = 1 + else: + file = htmlfile + mine = 0 + self.htmlfile = file + self.htmlmine = mine + self.htmlfile.write(BEGINHTMLREPORT) + def openoutput(self, filename): try: file = open(filename, 'w') @@ -408,11 +500,17 @@ self.report("LINE: %r" % (line,)) match = self.comment1.match(line) if match: + self.htmlreport(line, klass='commentstripping', ranges=[( + match.start('rest'), match.end('rest'), 'notcomment')]) line = match.group('rest') if self.debug: self.report("\tafter comment1: %r" % (line,)) match = self.comment2.match(line) while match: + if match: + self.htmlreport(line, klass='commentstripping', ranges=[ + (match.start('rest1'), match.end('rest1'), 'notcomment'), + (match.start('rest2'), match.end('rest2'), 'notcomment')]) line = match.group('rest1')+match.group('rest2') if self.debug: self.report("\tafter comment2: %r" % (line,)) @@ -422,7 +520,7 @@ if match: if self.debug: self.report("\tmatches sym.") - self.dosymdef(match) + self.dosymdef(match, line) continue match = self.head.match(line) if match: @@ -430,19 +528,26 @@ self.report("\tmatches head.") self.dofuncspec() continue + self.htmlreport(line, klass='unmatched') except EOFError: self.error("Uncaught EOF error") self.reportusedtypes() - def dosymdef(self, match): + def dosymdef(self, match, line): name, defn = match.group('name', 'defn') + self.htmlreport(line, klass='constant', ranges=[ + (match.start('name'), match.end('name'), 'name'), + (match.start('defn'), match.end('defn'), 'value')]) defn = escape8bit(defn) if self.debug: self.report("\tsym: name=%r, defn=%r" % (name, defn)) if not name in self.blacklistnames: - self.defsfile.write("%s = %s\n" % (name, defn)) + oline = "%s = %s\n" % (name, defn) + self.defsfile.write(oline) + self.htmlreport(oline, klass="pyconstant") else: self.defsfile.write("# %s = %s\n" % (name, defn)) + self.htmlreport("** no output: name is blacklisted", klass="blconstant") # XXXX No way to handle greylisted names def dofuncspec(self): @@ -466,25 +571,37 @@ if self.debug: self.report("* WHOLE LINE: %r" % (raw,)) self.processrawspec(raw) + return raw def processrawspec(self, raw): match = self.whole.search(raw) if not match: self.report("Bad raw spec: %r", raw) if self.debug: - if not self.type.search(raw): + match = self.type.search(raw) + if not match: self.report("(Type already doesn't match)") + self.htmlreport(raw, klass='incomplete', ranges=[( + match.start('type'), match.end('type'), 'type')]) else: self.report("(but type matched)") + self.htmlreport(raw, klass='incomplete') return type, name, args = match.group('type', 'name', 'args') - type = re.sub("\*", " ptr", type) - type = re.sub("[ \t]+", "_", type) - if name in self.alreadydone: - self.report("Name has already been defined: %r", name) + ranges=[ + (match.start('type'), match.end('type'), 'type'), + (match.start('name'), match.end('name'), 'name'), + (match.start('args'), match.end('args'), 'arglist')] + self.htmlreport(raw, klass='declaration', ranges=ranges) + modifiers = self.getmodifiers(match) + type = self.pythonizename(type) + name = self.pythonizename(name) + if self.checkduplicate(name): + self.htmlreport("*** no output generated: duplicate name", klass="blacklisted") return self.report("==> %s %s <==", type, name) if self.blacklisted(type, name): + self.htmlreport("*** no output generated: function name or return type blacklisted", klass="blacklisted") self.report("*** %s %s blacklisted", type, name) return returnlist = [(type, name, 'ReturnMode')] @@ -493,12 +610,31 @@ arglist = self.extractarglist(args) arglist = self.repairarglist(name, arglist) if self.unmanageable(type, name, arglist): + self.htmlreport("*** no output generated: some argument blacklisted", klass="blacklisted") ##for arg in arglist: ## self.report(" %r", arg) self.report("*** %s %s unmanageable", type, name) return + if modifiers: + self.generate(type, name, arglist, modifiers) + else: + self.generate(type, name, arglist) + + def getmodifiers(self, match): + return [] + + def checkduplicate(self, name): + if name in self.alreadydone: + self.report("Name has already been defined: %r", name) + return True self.alreadydone.append(name) - self.generate(type, name, arglist) + return False + + def pythonizename(self, name): + name = re.sub("\*", " ptr", name) + name = name.strip() + name = re.sub("[ \t]+", "_", name) + return name def extractarglist(self, args): args = args.strip() @@ -522,9 +658,7 @@ if array: # array matches an optional [] after the argument name type = type + " ptr " - type = re.sub("\*", " ptr ", type) - type = type.strip() - type = re.sub("[ \t]+", "_", type) + type = self.pythonizename(type) return self.modifyarg(type, name, mode) def modifyarg(self, type, name, mode): @@ -587,23 +721,42 @@ ##self.report("new: %r", new) return new - def generate(self, type, name, arglist): - self.typeused(type, 'return') - classname, listname = self.destination(type, name, arglist) - if not self.specfile: return - self.specfile.write("f = %s(%s, %r,\n" % (classname, type, name)) + def generate(self, tp, name, arglist, modifiers=[]): + + self.typeused(tp, 'return') + if modifiers: + classname, listname = self.destination(tp, name, arglist, modifiers) + else: + classname, listname = self.destination(tp, name, arglist) + if not classname or not listname: + self.htmlreport("*** no output generated: self.destination() returned None", klass="blacklisted") + return + if not self.specfile: + self.htmlreport("*** no output generated: no output file specified", klass="blacklisted") + return + self.specfile.write("f = %s(%s, %r,\n" % (classname, tp, name)) for atype, aname, amode in arglist: self.typeused(atype, amode) self.specfile.write(" (%s, %r, %s),\n" % (atype, aname, amode)) if self.greydictnames.has_key(name): self.specfile.write(" condition=%r,\n"%(self.greydictnames[name],)) + self.generatemodifiers(classname, name, modifiers) self.specfile.write(")\n") self.specfile.write("%s.append(f)\n\n" % listname) + if self.htmlfile: + oline = "Adding to %s:\n%s(returntype=%s, name=%r" % (listname, classname, tp, name) + for atype, aname, amode in arglist: + oline += ",\n (%s, %r, %s)" % (atype, aname, amode) + oline += ")\n" + self.htmlreport(oline, klass="pydeclaration") def destination(self, type, name, arglist): return "FunctionGenerator", "functions" + def generatemodifiers(self, classname, name, modifiers): + pass + def blacklisted(self, type, name): if type in self.blacklisttypes: ##self.report("return type %s is blacklisted", type) @@ -620,6 +773,34 @@ return 1 return 0 + def htmlreport(self, line, klass=None, ranges=None): + if not self.htmlfile: return + if ranges is None: + ranges = [] + if klass: + ranges.insert(0, (0, len(line), klass)) + oline = '' + i = 0 + for c in line: + for b, e, name in ranges: + if b == i: + oline += '' % name + if e == i: + oline += '' + i += 1 + + if c == '<': oline += '<' + elif c == '>': oline += '>' + else: oline += c + for b, e, name in ranges: + if b >= i: + oline += '' % name + if e >= i: + oline += '' + if not line or line[-1] != '\n': + oline += '\n' + self.htmlfile.write(oline) + class Scanner_PreUH3(Scanner): """Scanner for Universal Headers before release 3""" def initpatterns(self): From jhylton at users.sourceforge.net Sun Oct 16 07:24:11 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Sun, 16 Oct 2005 07:24:11 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Objects abstract.c, 2.103.2.2, 2.103.2.3 bufferobject.c, 2.19.2.2, 2.19.2.3 classobject.c, 2.158.2.2, 2.158.2.3 complexobject.c, 2.62.2.2, 2.62.2.3 descrobject.c, 2.27.2.2, 2.27.2.3 dictobject.c, 2.126.2.2, 2.126.2.3 enumobject.c, 1.2.2.2, 1.2.2.3 fileobject.c, 2.164.2.2, 2.164.2.3 floatobject.c, 2.113.2.2, 2.113.2.3 funcobject.c, 2.55.2.4, 2.55.2.5 genobject.c, 1.4.4.1, 1.4.4.2 intobject.c, 2.84.2.2, 2.84.2.3 iterobject.c, 1.10.2.2, 1.10.2.3 listobject.c, 2.114.2.2, 2.114.2.3 listsort.txt, 1.6.10.1, 1.6.10.2 longobject.c, 1.118.2.2, 1.118.2.3 object.c, 2.179.2.3, 2.179.2.4 obmalloc.c, 2.45.2.2, 2.45.2.3 rangeobject.c, 2.41.2.2, 2.41.2.3 setobject.c, 1.31.4.1, 1.31.4.2 sliceobject.c, 2.15.2.2, 2.15.2.3 stringobject.c, 2.168.2.2, 2.168.2.3 tupleobject.c, 2.68.2.2, 2.68.2.3 typeobject.c, 2.157.2.3, 2.157.2.4 unicodeobject.c, 2.155.2.2, 2.155.2.3 weakrefobject.c, 1.9.2.2, 1.9.2.3 Message-ID: <20051016052411.9EA361E4011@bag.python.org> Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27718/Objects Modified Files: Tag: ast-branch abstract.c bufferobject.c classobject.c complexobject.c descrobject.c dictobject.c enumobject.c fileobject.c floatobject.c funcobject.c genobject.c intobject.c iterobject.c listobject.c listsort.txt longobject.c object.c obmalloc.c rangeobject.c setobject.c sliceobject.c stringobject.c tupleobject.c typeobject.c unicodeobject.c weakrefobject.c Log Message: Merge head to branch (for the last time) Index: abstract.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v retrieving revision 2.103.2.2 retrieving revision 2.103.2.3 diff -u -d -r2.103.2.2 -r2.103.2.3 --- abstract.c 7 Jan 2005 07:03:43 -0000 2.103.2.2 +++ abstract.c 16 Oct 2005 05:24:04 -0000 2.103.2.3 @@ -81,6 +81,31 @@ } #define PyObject_Length PyObject_Size +int +_PyObject_LengthCue(PyObject *o) +{ + int rv = PyObject_Size(o); + if (rv != -1) + return rv; + if (PyErr_ExceptionMatches(PyExc_TypeError) || + PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyObject *err_type, *err_value, *err_tb, *ro; + + PyErr_Fetch(&err_type, &err_value, &err_tb); + ro = PyObject_CallMethod(o, "_length_cue", NULL); + if (ro != NULL) { + rv = (int)PyInt_AsLong(ro); + Py_DECREF(ro); + Py_XDECREF(err_type); + Py_XDECREF(err_value); + Py_XDECREF(err_tb); + return rv; + } + PyErr_Restore(err_type, err_value, err_tb); + } + return -1; +} + PyObject * PyObject_GetItem(PyObject *o, PyObject *key) { @@ -951,7 +976,19 @@ Py_INCREF(o); return o; } - if (PyInt_Check(o)) { + m = o->ob_type->tp_as_number; + if (m && m->nb_int) { /* This should include subclasses of int */ + PyObject *res = m->nb_int(o); + if (res && (!PyInt_Check(res) && !PyLong_Check(res))) { + PyErr_Format(PyExc_TypeError, + "__int__ returned non-int (type %.200s)", + res->ob_type->tp_name); + Py_DECREF(res); + return NULL; + } + return res; + } + if (PyInt_Check(o)) { /* A int subclass without nb_int */ PyIntObject *io = (PyIntObject*)o; return PyInt_FromLong(io->ob_ival); } @@ -964,18 +1001,6 @@ PyUnicode_GET_SIZE(o), 10); #endif - m = o->ob_type->tp_as_number; - if (m && m->nb_int) { - PyObject *res = m->nb_int(o); - if (res && (!PyInt_Check(res) && !PyLong_Check(res))) { - PyErr_Format(PyExc_TypeError, - "__int__ returned non-int (type %.200s)", - res->ob_type->tp_name); - Py_DECREF(res); - return NULL; - } - return res; - } if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len)) return int_from_string((char*)buffer, buffer_len); @@ -1010,11 +1035,19 @@ if (o == NULL) return null_error(); - if (PyLong_CheckExact(o)) { - Py_INCREF(o); - return o; + m = o->ob_type->tp_as_number; + if (m && m->nb_long) { /* This should include subclasses of long */ + PyObject *res = m->nb_long(o); + if (res && (!PyInt_Check(res) && !PyLong_Check(res))) { + PyErr_Format(PyExc_TypeError, + "__long__ returned non-long (type %.200s)", + res->ob_type->tp_name); + Py_DECREF(res); + return NULL; + } + return res; } - if (PyLong_Check(o)) + if (PyLong_Check(o)) /* A long subclass without nb_long */ return _PyLong_Copy((PyLongObject *)o); if (PyString_Check(o)) /* need to do extra error checking that PyLong_FromString() @@ -1030,18 +1063,6 @@ PyUnicode_GET_SIZE(o), 10); #endif - m = o->ob_type->tp_as_number; - if (m && m->nb_long) { - PyObject *res = m->nb_long(o); - if (res && (!PyInt_Check(res) && !PyLong_Check(res))) { - PyErr_Format(PyExc_TypeError, - "__long__ returned non-long (type %.200s)", - res->ob_type->tp_name); - Py_DECREF(res); - return NULL; - } - return res; - } if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len)) return long_from_string(buffer, buffer_len); @@ -1055,28 +1076,22 @@ if (o == NULL) return null_error(); - if (PyFloat_CheckExact(o)) { - Py_INCREF(o); - return o; + m = o->ob_type->tp_as_number; + if (m && m->nb_float) { /* This should include subclasses of float */ + PyObject *res = m->nb_float(o); + if (res && !PyFloat_Check(res)) { + PyErr_Format(PyExc_TypeError, + "__float__ returned non-float (type %.200s)", + res->ob_type->tp_name); + Py_DECREF(res); + return NULL; + } + return res; } - if (PyFloat_Check(o)) { + if (PyFloat_Check(o)) { /* A float subclass with nb_float == NULL */ PyFloatObject *po = (PyFloatObject *)o; return PyFloat_FromDouble(po->ob_fval); } - if (!PyString_Check(o)) { - m = o->ob_type->tp_as_number; - if (m && m->nb_float) { - PyObject *res = m->nb_float(o); - if (res && !PyFloat_Check(res)) { - PyErr_Format(PyExc_TypeError, - "__float__ returned non-float (type %.200s)", - res->ob_type->tp_name); - Py_DECREF(res); - return NULL; - } - return res; - } - } return PyFloat_FromString(o, NULL); } @@ -1409,8 +1424,13 @@ return NULL; /* Guess result size and allocate space. */ - n = PyObject_Size(v); + n = _PyObject_LengthCue(v); if (n < 0) { + if (!PyErr_ExceptionMatches(PyExc_TypeError) && + !PyErr_ExceptionMatches(PyExc_AttributeError)) { + Py_DECREF(it); + return NULL; + } PyErr_Clear(); n = 10; /* arbitrary */ } @@ -1807,7 +1827,9 @@ PyObject_CallMethod(PyObject *o, char *name, char *format, ...) { va_list va; - PyObject *args, *func = 0, *retval; + PyObject *args = NULL; + PyObject *func = NULL; + PyObject *retval = NULL; if (o == NULL || name == NULL) return null_error(); @@ -1818,8 +1840,10 @@ return 0; } - if (!PyCallable_Check(func)) - return type_error("call of non-callable attribute"); + if (!PyCallable_Check(func)) { + type_error("call of non-callable attribute"); + goto exit; + } if (format && *format) { va_start(va, format); @@ -1830,23 +1854,24 @@ args = PyTuple_New(0); if (!args) - return NULL; + goto exit; if (!PyTuple_Check(args)) { PyObject *a; a = PyTuple_New(1); if (a == NULL) - return NULL; + goto exit; if (PyTuple_SetItem(a, 0, args) < 0) - return NULL; + goto exit; args = a; } retval = PyObject_Call(func, args, NULL); - Py_DECREF(args); - Py_DECREF(func); + exit: + Py_XDECREF(args); + Py_XDECREF(func); return retval; } Index: bufferobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/bufferobject.c,v retrieving revision 2.19.2.2 retrieving revision 2.19.2.3 diff -u -d -r2.19.2.2 -r2.19.2.3 --- bufferobject.c 7 Jan 2005 07:03:44 -0000 2.19.2.2 +++ bufferobject.c 16 Oct 2005 05:24:04 -0000 2.19.2.3 @@ -192,7 +192,10 @@ int offset = 0; int size = Py_END_OF_BUFFER; - if ( !PyArg_ParseTuple(args, "O|ii:buffer", &ob, &offset, &size) ) + if (!_PyArg_NoKeywords("buffer()", kw)) + return NULL; + + if (!PyArg_ParseTuple(args, "O|ii:buffer", &ob, &offset, &size)) return NULL; return PyBuffer_FromObject(ob, offset, size); } Index: classobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v retrieving revision 2.158.2.2 retrieving revision 2.158.2.3 diff -u -d -r2.158.2.2 -r2.158.2.3 --- classobject.c 7 Jan 2005 07:03:44 -0000 2.158.2.2 +++ classobject.c 16 Oct 2005 05:24:04 -0000 2.158.2.3 @@ -1013,7 +1013,17 @@ if (res == NULL) return -1; if (PyInt_Check(res)) { - outcome = PyInt_AsLong(res); + long temp = PyInt_AsLong(res); + outcome = (int)temp; +#if SIZEOF_INT < SIZEOF_LONG + /* Overflow check -- range of PyInt is more than C int */ + if (outcome != temp) { + PyErr_SetString(PyExc_OverflowError, + "__len__() should return 0 <= outcome < 2**31"); + outcome = -1; + } + else +#endif if (outcome < 0) PyErr_SetString(PyExc_ValueError, "__len__() should return >= 0"); @@ -2208,6 +2218,12 @@ } if (self == Py_None) self = NULL; + if (self == NULL && classObj == NULL) { + PyErr_SetString(PyExc_TypeError, + "unbound methods must have non-NULL im_class"); + return NULL; + } + return PyMethod_New(func, self, classObj); } @@ -2480,7 +2496,7 @@ (getattrofunc)instancemethod_getattro, /* tp_getattro */ PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */ instancemethod_doc, /* tp_doc */ (traverseproc)instancemethod_traverse, /* tp_traverse */ 0, /* tp_clear */ Index: complexobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/complexobject.c,v retrieving revision 2.62.2.2 retrieving revision 2.62.2.3 diff -u -d -r2.62.2.2 -r2.62.2.3 --- complexobject.c 7 Jan 2005 07:03:44 -0000 2.62.2.2 +++ complexobject.c 16 Oct 2005 05:24:04 -0000 2.62.2.3 @@ -279,15 +279,12 @@ strncat(buf, "j", bufsz); } else { char re[64], im[64]; - char *fmt; + /* Format imaginary part with sign, real part without */ PyOS_snprintf(format, 32, "%%.%ig", precision); PyOS_ascii_formatd(re, 64, format, v->cval.real); + PyOS_snprintf(format, 32, "%%+.%ig", precision); PyOS_ascii_formatd(im, 64, format, v->cval.imag); - if (v->cval.imag < 0.) - fmt = "(%s%sj)"; - else - fmt = "(%s+%sj)"; - PyOS_snprintf(buf, bufsz, fmt, re, im); + PyOS_snprintf(buf, bufsz, "(%s%sj)", re, im); } } Index: descrobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/descrobject.c,v retrieving revision 2.27.2.2 retrieving revision 2.27.2.3 diff -u -d -r2.27.2.2 -r2.27.2.3 --- descrobject.c 7 Jan 2005 07:03:45 -0000 2.27.2.2 +++ descrobject.c 16 Oct 2005 05:24:04 -0000 2.27.2.3 @@ -144,7 +144,7 @@ return res; if (descr->d_getset->get != NULL) return descr->d_getset->get(obj, descr->d_getset->closure); - PyErr_Format(PyExc_TypeError, + PyErr_Format(PyExc_AttributeError, "attribute '%.300s' of '%.100s' objects is not readable", descr_name((PyDescrObject *)descr), descr->d_type->tp_name); @@ -199,7 +199,7 @@ if (descr->d_getset->set != NULL) return descr->d_getset->set(obj, value, descr->d_getset->closure); - PyErr_Format(PyExc_TypeError, + PyErr_Format(PyExc_AttributeError, "attribute '%.300s' of '%.100s' objects is not writable", descr_name((PyDescrObject *)descr), descr->d_type->tp_name); Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.126.2.2 retrieving revision 2.126.2.3 diff -u -d -r2.126.2.2 -r2.126.2.3 --- dictobject.c 7 Jan 2005 07:03:45 -0000 2.126.2.2 +++ dictobject.c 16 Oct 2005 05:24:04 -0000 2.126.2.3 @@ -113,7 +113,7 @@ */ /* Object used as dummy key to fill deleted entries */ -static PyObject *dummy; /* Initialized by first call to newdictobject() */ +static PyObject *dummy = NULL; /* Initialized by first call to newdictobject() */ /* forward declarations */ static dictentry * @@ -400,8 +400,10 @@ else { if (ep->me_key == NULL) mp->ma_fill++; - else - Py_DECREF(ep->me_key); + else { + assert(ep->me_key == dummy); + Py_DECREF(dummy); + } ep->me_key = key; ep->me_hash = hash; ep->me_value = value; @@ -565,7 +567,7 @@ */ if (!(mp->ma_used > n_used && mp->ma_fill*3 >= (mp->ma_mask+1)*2)) return 0; - return dictresize(mp, mp->ma_used*(mp->ma_used>50000 ? 2 : 4)); + return dictresize(mp, (mp->ma_used>50000 ? mp->ma_used*2 : mp->ma_used*4)); } int @@ -1201,6 +1203,12 @@ if (other == mp || other->ma_used == 0) /* a.update(a) or a.update({}); nothing to do */ return 0; + if (mp->ma_used == 0) + /* Since the target dict is empty, PyDict_GetItem() + * always returns NULL. Setting override to 1 + * skips the unnecessary test. + */ + override = 1; /* Do one big resize at the start, rather than * incrementally resizing as we insert new items. Expect * that there will be no (or few) overlapping keys. @@ -1289,7 +1297,7 @@ if (PyDict_Merge(copy, o, 1) == 0) return copy; Py_DECREF(copy); - return copy; + return NULL; } int @@ -2046,17 +2054,20 @@ PyObject_Del(di); } -static int +static PyObject * dictiter_len(dictiterobject *di) { + int len = 0; if (di->di_dict != NULL && di->di_used == di->di_dict->ma_used) - return di->len; - return 0; + len = di->len; + return PyInt_FromLong(len); } -static PySequenceMethods dictiter_as_sequence = { - (inquiry)dictiter_len, /* sq_length */ - 0, /* sq_concat */ +PyDoc_STRVAR(length_cue_doc, "Private method returning an estimate of len(list(it))."); + +static PyMethodDef dictiter_methods[] = { + {"_length_cue", (PyCFunction)dictiter_len, METH_NOARGS, length_cue_doc}, + {NULL, NULL} /* sentinel */ }; static PyObject *dictiter_iternextkey(dictiterobject *di) @@ -2112,7 +2123,7 @@ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ - &dictiter_as_sequence, /* tp_as_sequence */ + 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ @@ -2128,6 +2139,8 @@ 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ (iternextfunc)dictiter_iternextkey, /* tp_iternext */ + dictiter_methods, /* tp_methods */ + 0, }; static PyObject *dictiter_iternextvalue(dictiterobject *di) @@ -2183,7 +2196,7 @@ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ - &dictiter_as_sequence, /* tp_as_sequence */ + 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ @@ -2199,6 +2212,8 @@ 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ (iternextfunc)dictiter_iternextvalue, /* tp_iternext */ + dictiter_methods, /* tp_methods */ + 0, }; static PyObject *dictiter_iternextitem(dictiterobject *di) @@ -2268,7 +2283,7 @@ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ - &dictiter_as_sequence, /* tp_as_sequence */ + 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ @@ -2284,4 +2299,6 @@ 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ (iternextfunc)dictiter_iternextitem, /* tp_iternext */ + dictiter_methods, /* tp_methods */ + 0, }; Index: enumobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/enumobject.c,v retrieving revision 1.2.2.2 retrieving revision 1.2.2.3 diff -u -d -r1.2.2.2 -r1.2.2.3 --- enumobject.c 7 Jan 2005 07:04:00 -0000 1.2.2.2 +++ enumobject.c 16 Oct 2005 05:24:04 -0000 1.2.2.3 @@ -239,23 +239,25 @@ "\n" "Return a reverse iterator"); -static int +static PyObject * reversed_len(reversedobject *ro) { int position, seqsize; if (ro->seq == NULL) - return 0; + return PyInt_FromLong(0); seqsize = PySequence_Size(ro->seq); if (seqsize == -1) - return -1; + return NULL; position = ro->index + 1; - return (seqsize < position) ? 0 : position; + return PyInt_FromLong((seqsize < position) ? 0 : position); } -static PySequenceMethods reversed_as_sequence = { - (inquiry)reversed_len, /* sq_length */ - 0, /* sq_concat */ +PyDoc_STRVAR(length_cue_doc, "Private method returning an estimate of len(list(it))."); + +static PyMethodDef reversediter_methods[] = { + {"_length_cue", (PyCFunction)reversed_len, METH_NOARGS, length_cue_doc}, + {NULL, NULL} /* sentinel */ }; PyTypeObject PyReversed_Type = { @@ -272,7 +274,7 @@ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ - &reversed_as_sequence, /* tp_as_sequence */ + 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ @@ -289,7 +291,7 @@ 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ (iternextfunc)reversed_next, /* tp_iternext */ - 0, /* tp_methods */ + reversediter_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ Index: fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.164.2.2 retrieving revision 2.164.2.3 diff -u -d -r2.164.2.2 -r2.164.2.3 --- fileobject.c 7 Jan 2005 07:04:01 -0000 2.164.2.2 +++ fileobject.c 16 Oct 2005 05:24:04 -0000 2.164.2.3 @@ -128,6 +128,54 @@ return (PyObject *) f; } +/* check for known incorrect mode strings - problem is, platforms are + free to accept any mode characters they like and are supposed to + ignore stuff they don't understand... write or append mode with + universal newline support is expressly forbidden by PEP 278. */ +/* zero return is kewl - one is un-kewl */ +static int +check_the_mode(char *mode) +{ + unsigned int len = strlen(mode); + + switch (len) { + case 0: + PyErr_SetString(PyExc_ValueError, "empty mode string"); + return 1; + + /* reject wU, aU */ + case 2: + switch (mode[0]) { + case 'w': + case 'a': + if (mode[1] == 'U') { + PyErr_SetString(PyExc_ValueError, + "invalid mode string"); + return 1; + } + break; + } + break; + + /* reject w+U, a+U, wU+, aU+ */ + case 3: + switch (mode[0]) { + case 'w': + case 'a': + if ((mode[1] == '+' && mode[2] == 'U') || + (mode[1] == 'U' && mode[2] == '+')) { + PyErr_SetString(PyExc_ValueError, + "invalid mode string"); + return 1; + } + break; + } + break; + } + + return 0; +} + static PyObject * open_the_file(PyFileObject *f, char *name, char *mode) { @@ -142,6 +190,9 @@ assert(mode != NULL); assert(f->f_fp == NULL); + if (check_the_mode(mode)) + return NULL; + /* rexec.py can't stop a user from getting the file() constructor -- all they have to do is get *any* file object f, and then do type(f). Here we prevent them from doing damage with it. */ Index: floatobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v retrieving revision 2.113.2.2 retrieving revision 2.113.2.3 diff -u -d -r2.113.2.2 -r2.113.2.3 --- floatobject.c 7 Jan 2005 07:04:01 -0000 2.113.2.2 +++ floatobject.c 16 Oct 2005 05:24:04 -0000 2.113.2.3 @@ -926,7 +926,10 @@ static PyObject * float_float(PyObject *v) { - Py_INCREF(v); + if (PyFloat_CheckExact(v)) + Py_INCREF(v); + else + v = PyFloat_FromDouble(((PyFloatObject *)v)->ob_fval); return v; } @@ -980,8 +983,139 @@ return Py_BuildValue("(d)", v->ob_fval); } +/* this is for the benefit of the pack/unpack routines below */ + +typedef enum { + unknown_format, ieee_big_endian_format, ieee_little_endian_format +} float_format_type; + +static float_format_type double_format, float_format; +static float_format_type detected_double_format, detected_float_format; + +static PyObject * +float_getformat(PyTypeObject *v, PyObject* arg) +{ + char* s; + float_format_type r; + + if (!PyString_Check(arg)) { + PyErr_Format(PyExc_TypeError, + "__getformat__() argument must be string, not %.500s", + arg->ob_type->tp_name); + return NULL; + } + s = PyString_AS_STRING(arg); + if (strcmp(s, "double") == 0) { + r = double_format; + } + else if (strcmp(s, "float") == 0) { + r = float_format; + } + else { + PyErr_SetString(PyExc_ValueError, + "__getformat__() argument 1 must be " + "'double' or 'float'"); + return NULL; + } + + switch (r) { + case unknown_format: + return PyString_FromString("unknown"); + case ieee_little_endian_format: + return PyString_FromString("IEEE, little-endian"); + case ieee_big_endian_format: + return PyString_FromString("IEEE, big-endian"); + default: + Py_FatalError("insane float_format or double_format"); + return NULL; + } +} + +PyDoc_STRVAR(float_getformat_doc, +"float.__getformat__(typestr) -> string\n" +"\n" +"You probably don't want to use this function. It exists mainly to be\n" +"used in Python's test suite.\n" +"\n" +"typestr must be 'double' or 'float'. This function returns whichever of\n" +"'unknown', 'IEEE, big-endian' or 'IEEE, little-endian' best describes the\n" +"format of floating point numbers used by the C type named by typestr."); + +static PyObject * +float_setformat(PyTypeObject *v, PyObject* args) +{ + char* typestr; + char* format; + float_format_type f; + float_format_type detected; + float_format_type *p; + + if (!PyArg_ParseTuple(args, "ss:__setformat__", &typestr, &format)) + return NULL; + + if (strcmp(typestr, "double") == 0) { + p = &double_format; + detected = detected_double_format; + } + else if (strcmp(typestr, "float") == 0) { + p = &float_format; + detected = detected_float_format; + } + else { + PyErr_SetString(PyExc_ValueError, + "__setformat__() argument 1 must " + "be 'double' or 'float'"); + return NULL; + } + + if (strcmp(format, "unknown") == 0) { + f = unknown_format; + } + else if (strcmp(format, "IEEE, little-endian") == 0) { + f = ieee_little_endian_format; + } + else if (strcmp(format, "IEEE, big-endian") == 0) { + f = ieee_big_endian_format; + } + else { + PyErr_SetString(PyExc_ValueError, + "__setformat__() argument 2 must be " + "'unknown', 'IEEE, little-endian' or " + "'IEEE, big-endian'"); + return NULL; + + } + + if (f != unknown_format && f != detected) { + PyErr_Format(PyExc_ValueError, + "can only set %s format to 'unknown' or the " + "detected platform value", typestr); + return NULL; + } + + *p = f; + Py_RETURN_NONE; +} + +PyDoc_STRVAR(float_setformat_doc, +"float.__setformat__(typestr, fmt) -> None\n" +"\n" +"You probably don't want to use this function. It exists mainly to be\n" +"used in Python's test suite.\n" +"\n" +"typestr must be 'double' or 'float'. fmt must be one of 'unknown',\n" +"'IEEE, big-endian' or 'IEEE, little-endian', and in addition can only be\n" +"one of the latter two if it appears to match the underlying C reality.\n" +"\n" +"Overrides the automatic determination of C-level floating point type.\n" +"This affects how floats are converted to and from binary strings."); + static PyMethodDef float_methods[] = { {"__getnewargs__", (PyCFunction)float_getnewargs, METH_NOARGS}, + {"__getformat__", (PyCFunction)float_getformat, + METH_O|METH_CLASS, float_getformat_doc}, + {"__setformat__", (PyCFunction)float_setformat, + METH_VARARGS|METH_CLASS, float_setformat_doc}, {NULL, NULL} /* sentinel */ }; @@ -1076,6 +1210,56 @@ }; void +_PyFloat_Init(void) +{ + /* We attempt to determine if this machine is using IEEE + floating point formats by peering at the bits of some + carefully chosen values. If it looks like we are on an + IEEE platform, the float packing/unpacking routines can + just copy bits, if not they resort to arithmetic & shifts + and masks. The shifts & masks approach works on all finite + values, but what happens to infinities, NaNs and signed + zeroes on packing is an accident, and attempting to unpack + a NaN or an infinity will raise an exception. + + Note that if we're on some whacked-out platform which uses + IEEE formats but isn't strictly little-endian or big- + endian, we will fall back to the portable shifts & masks + method. */ + +#if SIZEOF_DOUBLE == 8 + { + double x = 9006104071832581.0; + if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0) + detected_double_format = ieee_big_endian_format; + else if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0) + detected_double_format = ieee_little_endian_format; + else + detected_double_format = unknown_format; + } +#else + detected_double_format = unknown_format; +#endif + +#if SIZEOF_FLOAT == 4 + { + float y = 16711938.0; + if (memcmp(&y, "\x4b\x7f\x01\x02", 4) == 0) + detected_float_format = ieee_big_endian_format; + else if (memcmp(&y, "\x02\x01\x7f\x4b", 4) == 0) + detected_float_format = ieee_little_endian_format; + else + detected_float_format = unknown_format; + } +#else + detected_float_format = unknown_format; +#endif + + double_format = detected_double_format; + float_format = detected_float_format; +} + +void PyFloat_Fini(void) { PyFloatObject *p; @@ -1162,306 +1346,395 @@ int _PyFloat_Pack4(double x, unsigned char *p, int le) { - unsigned char sign; - int e; - double f; - unsigned int fbits; - int incr = 1; - - if (le) { - p += 3; - incr = -1; - } + if (float_format == unknown_format) { + unsigned char sign; + int e; + double f; + unsigned int fbits; + int incr = 1; - if (x < 0) { - sign = 1; - x = -x; - } - else - sign = 0; + if (le) { + p += 3; + incr = -1; + } - f = frexp(x, &e); + if (x < 0) { + sign = 1; + x = -x; + } + else + sign = 0; - /* Normalize f to be in the range [1.0, 2.0) */ - if (0.5 <= f && f < 1.0) { - f *= 2.0; - e--; - } - else if (f == 0.0) - e = 0; - else { - PyErr_SetString(PyExc_SystemError, - "frexp() result out of range"); - return -1; - } + f = frexp(x, &e); - if (e >= 128) - goto Overflow; - else if (e < -126) { - /* Gradual underflow */ - f = ldexp(f, 126 + e); - e = 0; - } - else if (!(e == 0 && f == 0.0)) { - e += 127; - f -= 1.0; /* Get rid of leading 1 */ - } + /* Normalize f to be in the range [1.0, 2.0) */ + if (0.5 <= f && f < 1.0) { + f *= 2.0; + e--; + } + else if (f == 0.0) + e = 0; + else { + PyErr_SetString(PyExc_SystemError, + "frexp() result out of range"); + return -1; + } - f *= 8388608.0; /* 2**23 */ - fbits = (unsigned int)(f + 0.5); /* Round */ - assert(fbits <= 8388608); - if (fbits >> 23) { - /* The carry propagated out of a string of 23 1 bits. */ - fbits = 0; - ++e; - if (e >= 255) + if (e >= 128) goto Overflow; - } + else if (e < -126) { + /* Gradual underflow */ + f = ldexp(f, 126 + e); + e = 0; + } + else if (!(e == 0 && f == 0.0)) { + e += 127; + f -= 1.0; /* Get rid of leading 1 */ + } - /* First byte */ - *p = (sign << 7) | (e >> 1); - p += incr; + f *= 8388608.0; /* 2**23 */ + fbits = (unsigned int)(f + 0.5); /* Round */ + assert(fbits <= 8388608); + if (fbits >> 23) { + /* The carry propagated out of a string of 23 1 bits. */ + fbits = 0; + ++e; + if (e >= 255) + goto Overflow; + } - /* Second byte */ - *p = (char) (((e & 1) << 7) | (fbits >> 16)); - p += incr; + /* First byte */ + *p = (sign << 7) | (e >> 1); + p += incr; - /* Third byte */ - *p = (fbits >> 8) & 0xFF; - p += incr; + /* Second byte */ + *p = (char) (((e & 1) << 7) | (fbits >> 16)); + p += incr; - /* Fourth byte */ - *p = fbits & 0xFF; + /* Third byte */ + *p = (fbits >> 8) & 0xFF; + p += incr; - /* Done */ - return 0; + /* Fourth byte */ + *p = fbits & 0xFF; - Overflow: - PyErr_SetString(PyExc_OverflowError, - "float too large to pack with f format"); - return -1; + /* Done */ + return 0; + + Overflow: + PyErr_SetString(PyExc_OverflowError, + "float too large to pack with f format"); + return -1; + } + else { + float y = (float)x; + const char *s = (char*)&y; + int i, incr = 1; + + if ((float_format == ieee_little_endian_format && !le) + || (float_format == ieee_big_endian_format && le)) { + p += 3; + incr = -1; + } + + for (i = 0; i < 4; i++) { + *p = *s++; + p += incr; + } + return 0; + } } int _PyFloat_Pack8(double x, unsigned char *p, int le) { - unsigned char sign; - int e; - double f; - unsigned int fhi, flo; - int incr = 1; + if (double_format == unknown_format) { + unsigned char sign; + int e; + double f; + unsigned int fhi, flo; + int incr = 1; - if (le) { - p += 7; - incr = -1; - } + if (le) { + p += 7; + incr = -1; + } - if (x < 0) { - sign = 1; - x = -x; - } - else - sign = 0; + if (x < 0) { + sign = 1; + x = -x; + } + else + sign = 0; - f = frexp(x, &e); + f = frexp(x, &e); - /* Normalize f to be in the range [1.0, 2.0) */ - if (0.5 <= f && f < 1.0) { - f *= 2.0; - e--; - } - else if (f == 0.0) - e = 0; - else { - PyErr_SetString(PyExc_SystemError, - "frexp() result out of range"); - return -1; - } + /* Normalize f to be in the range [1.0, 2.0) */ + if (0.5 <= f && f < 1.0) { + f *= 2.0; + e--; + } + else if (f == 0.0) + e = 0; + else { + PyErr_SetString(PyExc_SystemError, + "frexp() result out of range"); + return -1; + } - if (e >= 1024) - goto Overflow; - else if (e < -1022) { - /* Gradual underflow */ - f = ldexp(f, 1022 + e); - e = 0; - } - else if (!(e == 0 && f == 0.0)) { - e += 1023; - f -= 1.0; /* Get rid of leading 1 */ - } + if (e >= 1024) + goto Overflow; + else if (e < -1022) { + /* Gradual underflow */ + f = ldexp(f, 1022 + e); + e = 0; + } + else if (!(e == 0 && f == 0.0)) { + e += 1023; + f -= 1.0; /* Get rid of leading 1 */ + } - /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */ - f *= 268435456.0; /* 2**28 */ - fhi = (unsigned int)f; /* Truncate */ - assert(fhi < 268435456); + /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */ + f *= 268435456.0; /* 2**28 */ + fhi = (unsigned int)f; /* Truncate */ + assert(fhi < 268435456); - f -= (double)fhi; - f *= 16777216.0; /* 2**24 */ - flo = (unsigned int)(f + 0.5); /* Round */ - assert(flo <= 16777216); - if (flo >> 24) { - /* The carry propagated out of a string of 24 1 bits. */ - flo = 0; - ++fhi; - if (fhi >> 28) { - /* And it also progagated out of the next 28 bits. */ - fhi = 0; - ++e; - if (e >= 2047) - goto Overflow; + f -= (double)fhi; + f *= 16777216.0; /* 2**24 */ + flo = (unsigned int)(f + 0.5); /* Round */ + assert(flo <= 16777216); + if (flo >> 24) { + /* The carry propagated out of a string of 24 1 bits. */ + flo = 0; + ++fhi; + if (fhi >> 28) { + /* And it also progagated out of the next 28 bits. */ + fhi = 0; + ++e; + if (e >= 2047) + goto Overflow; + } } - } - /* First byte */ - *p = (sign << 7) | (e >> 4); - p += incr; + /* First byte */ + *p = (sign << 7) | (e >> 4); + p += incr; - /* Second byte */ - *p = (unsigned char) (((e & 0xF) << 4) | (fhi >> 24)); - p += incr; + /* Second byte */ + *p = (unsigned char) (((e & 0xF) << 4) | (fhi >> 24)); + p += incr; - /* Third byte */ - *p = (fhi >> 16) & 0xFF; - p += incr; + /* Third byte */ + *p = (fhi >> 16) & 0xFF; + p += incr; - /* Fourth byte */ - *p = (fhi >> 8) & 0xFF; - p += incr; + /* Fourth byte */ + *p = (fhi >> 8) & 0xFF; + p += incr; - /* Fifth byte */ - *p = fhi & 0xFF; - p += incr; + /* Fifth byte */ + *p = fhi & 0xFF; + p += incr; - /* Sixth byte */ - *p = (flo >> 16) & 0xFF; - p += incr; + /* Sixth byte */ + *p = (flo >> 16) & 0xFF; + p += incr; - /* Seventh byte */ - *p = (flo >> 8) & 0xFF; - p += incr; + /* Seventh byte */ + *p = (flo >> 8) & 0xFF; + p += incr; - /* Eighth byte */ - *p = flo & 0xFF; - p += incr; + /* Eighth byte */ + *p = flo & 0xFF; + p += incr; - /* Done */ - return 0; + /* Done */ + return 0; - Overflow: - PyErr_SetString(PyExc_OverflowError, - "float too large to pack with d format"); - return -1; + Overflow: + PyErr_SetString(PyExc_OverflowError, + "float too large to pack with d format"); + return -1; + } + else { + const char *s = (char*)&x; + int i, incr = 1; + + if ((double_format == ieee_little_endian_format && !le) + || (double_format == ieee_big_endian_format && le)) { + p += 7; + incr = -1; + } + + for (i = 0; i < 8; i++) { + *p = *s++; + p += incr; + } + return 0; + } } double _PyFloat_Unpack4(const unsigned char *p, int le) { - unsigned char sign; - int e; - unsigned int f; - double x; - int incr = 1; + if (float_format == unknown_format) { + unsigned char sign; + int e; + unsigned int f; + double x; + int incr = 1; - if (le) { - p += 3; - incr = -1; - } + if (le) { + p += 3; + incr = -1; + } - /* First byte */ - sign = (*p >> 7) & 1; - e = (*p & 0x7F) << 1; - p += incr; + /* First byte */ + sign = (*p >> 7) & 1; + e = (*p & 0x7F) << 1; + p += incr; - /* Second byte */ - e |= (*p >> 7) & 1; - f = (*p & 0x7F) << 16; - p += incr; + /* Second byte */ + e |= (*p >> 7) & 1; + f = (*p & 0x7F) << 16; + p += incr; - /* Third byte */ - f |= *p << 8; - p += incr; + if (e == 255) { + PyErr_SetString( + PyExc_ValueError, + "can't unpack IEEE 754 special value " + "on non-IEEE platform"); + return -1; + } - /* Fourth byte */ - f |= *p; + /* Third byte */ + f |= *p << 8; + p += incr; - x = (double)f / 8388608.0; + /* Fourth byte */ + f |= *p; - /* XXX This sadly ignores Inf/NaN issues */ - if (e == 0) - e = -126; - else { - x += 1.0; - e -= 127; - } - x = ldexp(x, e); + x = (double)f / 8388608.0; - if (sign) - x = -x; + /* XXX This sadly ignores Inf/NaN issues */ + if (e == 0) + e = -126; + else { + x += 1.0; + e -= 127; + } + x = ldexp(x, e); - return x; + if (sign) + x = -x; + + return x; + } + else { + if ((float_format == ieee_little_endian_format && !le) + || (float_format == ieee_big_endian_format && le)) { + char buf[8]; + char *d = &buf[3]; + int i; + + for (i = 0; i < 4; i++) { + *d-- = *p++; + } + return *(float*)&buf[0]; + } + else { + return *(float*)p; + } + } } double _PyFloat_Unpack8(const unsigned char *p, int le) { - unsigned char sign; - int e; - unsigned int fhi, flo; - double x; - int incr = 1; + if (double_format == unknown_format) { + unsigned char sign; + int e; + unsigned int fhi, flo; + double x; + int incr = 1; - if (le) { - p += 7; - incr = -1; - } + if (le) { + p += 7; + incr = -1; + } - /* First byte */ - sign = (*p >> 7) & 1; - e = (*p & 0x7F) << 4; - p += incr; + /* First byte */ + sign = (*p >> 7) & 1; + e = (*p & 0x7F) << 4; + + p += incr; - /* Second byte */ - e |= (*p >> 4) & 0xF; - fhi = (*p & 0xF) << 24; - p += incr; + /* Second byte */ + e |= (*p >> 4) & 0xF; + fhi = (*p & 0xF) << 24; + p += incr; - /* Third byte */ - fhi |= *p << 16; - p += incr; + if (e == 2047) { + PyErr_SetString( + PyExc_ValueError, + "can't unpack IEEE 754 special value " + "on non-IEEE platform"); + return -1.0; + } - /* Fourth byte */ - fhi |= *p << 8; - p += incr; + /* Third byte */ + fhi |= *p << 16; + p += incr; - /* Fifth byte */ - fhi |= *p; - p += incr; + /* Fourth byte */ + fhi |= *p << 8; + p += incr; - /* Sixth byte */ - flo = *p << 16; - p += incr; + /* Fifth byte */ + fhi |= *p; + p += incr; - /* Seventh byte */ - flo |= *p << 8; - p += incr; + /* Sixth byte */ + flo = *p << 16; + p += incr; - /* Eighth byte */ - flo |= *p; + /* Seventh byte */ + flo |= *p << 8; + p += incr; - x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */ - x /= 268435456.0; /* 2**28 */ + /* Eighth byte */ + flo |= *p; - /* XXX This sadly ignores Inf/NaN */ - if (e == 0) - e = -1022; - else { - x += 1.0; - e -= 1023; - } - x = ldexp(x, e); + x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */ + x /= 268435456.0; /* 2**28 */ - if (sign) - x = -x; + if (e == 0) + e = -1022; + else { + x += 1.0; + e -= 1023; + } + x = ldexp(x, e); - return x; + if (sign) + x = -x; + + return x; + } + else { + if ((double_format == ieee_little_endian_format && !le) + || (double_format == ieee_big_endian_format && le)) { + char buf[8]; + char *d = &buf[7]; + int i; + + for (i = 0; i < 8; i++) { + *d-- = *p++; + } + return *(double*)&buf[0]; + } + else { + return *(double*)p; + } + } } Index: funcobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/funcobject.c,v retrieving revision 2.55.2.4 retrieving revision 2.55.2.5 diff -u -d -r2.55.2.4 -r2.55.2.5 --- funcobject.c 14 Oct 2005 20:09:47 -0000 2.55.2.4 +++ funcobject.c 16 Oct 2005 05:24:04 -0000 2.55.2.5 @@ -264,8 +264,6 @@ static PyObject * func_get_name(PyFunctionObject *op) { - if (restricted()) - return NULL; Py_INCREF(op->func_name); return op->func_name; } Index: genobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/genobject.c,v retrieving revision 1.4.4.1 retrieving revision 1.4.4.2 diff -u -d -r1.4.4.1 -r1.4.4.2 --- genobject.c 7 Jan 2005 07:04:02 -0000 1.4.4.1 +++ genobject.c 16 Oct 2005 05:24:04 -0000 1.4.4.2 @@ -15,15 +15,31 @@ static void gen_dealloc(PyGenObject *gen) { + PyObject *self = (PyObject *) gen; + _PyObject_GC_UNTRACK(gen); + if (gen->gi_weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) gen); - Py_DECREF(gen->gi_frame); + + + _PyObject_GC_TRACK(self); + + if (gen->gi_frame->f_stacktop!=NULL) { + /* Generator is paused, so we need to close */ + gen->ob_type->tp_del(self); + if (self->ob_refcnt > 0) + return; /* resurrected. :( */ + } + + _PyObject_GC_UNTRACK(self); + Py_XDECREF(gen->gi_frame); PyObject_GC_Del(gen); } + static PyObject * -gen_iternext(PyGenObject *gen) +gen_send_ex(PyGenObject *gen, PyObject *arg, int exc) { PyThreadState *tstate = PyThreadState_GET(); PyFrameObject *f = gen->gi_frame; @@ -34,8 +50,24 @@ "generator already executing"); return NULL; } - if (f->f_stacktop == NULL) + if ((PyObject *)f == Py_None || f->f_stacktop == NULL) { + /* Only set exception if called from send() */ + if (arg && !exc) PyErr_SetNone(PyExc_StopIteration); return NULL; + } + + if (f->f_lasti == -1) { + if (arg && arg != Py_None) { + PyErr_SetString(PyExc_TypeError, + "can't send non-None value to a just-started generator"); + return NULL; + } + } else { + /* Push arg onto the frame's value stack */ + result = arg ? arg : Py_None; + Py_INCREF(result); + *(f->f_stacktop++) = result; + } /* Generators always return to their most recent caller, not * necessarily their creator. */ @@ -44,13 +76,13 @@ f->f_back = tstate->frame; gen->gi_running = 1; - result = PyEval_EvalFrame(f); + result = PyEval_EvalFrameEx(f, exc); gen->gi_running = 0; /* Don't keep the reference to f_back any longer than necessary. It * may keep a chain of frames alive or it could create a reference * cycle. */ - assert(f->f_back != NULL); + assert(f->f_back == tstate->frame); Py_CLEAR(f->f_back); /* If the generator just returned (as opposed to yielding), signal @@ -58,17 +90,199 @@ if (result == Py_None && f->f_stacktop == NULL) { Py_DECREF(result); result = NULL; + /* Set exception if not called by gen_iternext() */ + if (arg) PyErr_SetNone(PyExc_StopIteration); + } + + if (!result || f->f_stacktop == NULL) { + /* generator can't be rerun, so release the frame */ + Py_DECREF(f); + gen->gi_frame = (PyFrameObject *)Py_None; + Py_INCREF(Py_None); } return result; } +PyDoc_STRVAR(send_doc, +"send(arg) -> send 'arg' into generator, return next yielded value or raise StopIteration."); + +static PyObject * +gen_send(PyGenObject *gen, PyObject *arg) +{ + return gen_send_ex(gen, arg, 0); +} + +PyDoc_STRVAR(close_doc, +"close(arg) -> raise GeneratorExit inside generator."); + +static PyObject * +gen_close(PyGenObject *gen, PyObject *args) +{ + PyObject *retval; + PyErr_SetNone(PyExc_GeneratorExit); + retval = gen_send_ex(gen, Py_None, 1); + if (retval) { + Py_DECREF(retval); + PyErr_SetString(PyExc_RuntimeError, + "generator ignored GeneratorExit"); + return NULL; + } + if ( PyErr_ExceptionMatches(PyExc_StopIteration) + || PyErr_ExceptionMatches(PyExc_GeneratorExit) ) + { + PyErr_Clear(); /* ignore these errors */ + Py_INCREF(Py_None); + return Py_None; + } + return NULL; +} + +static void +gen_del(PyObject *self) +{ + PyObject *res; + PyObject *error_type, *error_value, *error_traceback; + PyGenObject *gen = (PyGenObject *)self; + + if ((PyObject *)gen->gi_frame == Py_None || gen->gi_frame->f_stacktop==NULL) + /* Generator isn't paused, so no need to close */ + return; + + /* Temporarily resurrect the object. */ + assert(self->ob_refcnt == 0); + self->ob_refcnt = 1; + + /* Save the current exception, if any. */ + PyErr_Fetch(&error_type, &error_value, &error_traceback); + + res = gen_close((PyGenObject *)self, NULL); + + if (res == NULL) + PyErr_WriteUnraisable((PyObject *)self); + else + Py_DECREF(res); + + /* Restore the saved exception. */ + PyErr_Restore(error_type, error_value, error_traceback); + + /* Undo the temporary resurrection; can't use DECREF here, it would + * cause a recursive call. + */ + assert(self->ob_refcnt > 0); + if (--self->ob_refcnt == 0) + return; /* this is the normal path out */ + + /* close() resurrected it! Make it look like the original Py_DECREF + * never happened. + */ + { + int refcnt = self->ob_refcnt; + _Py_NewReference(self); + self->ob_refcnt = refcnt; + } + assert(!PyType_IS_GC(self->ob_type) || + _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED); + + /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so + * we need to undo that. */ + _Py_DEC_REFTOTAL; + /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object + * chain, so no more to do there. + * If COUNT_ALLOCS, the original decref bumped tp_frees, and + * _Py_NewReference bumped tp_allocs: both of those need to be + * undone. + */ +#ifdef COUNT_ALLOCS + --self->ob_type->tp_frees; + --self->ob_type->tp_allocs; +#endif +} + + + +PyDoc_STRVAR(throw_doc, +"throw(typ[,val[,tb]]) -> raise exception in generator, return next yielded value or raise StopIteration."); + +static PyObject * +gen_throw(PyGenObject *gen, PyObject *args) +{ + PyObject *typ; + PyObject *tb = NULL; + PyObject *val = NULL; + + if (!PyArg_ParseTuple(args, "O|OO:throw", &typ, &val, &tb)) + return NULL; + + if (tb && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "throw() third argument must be a traceback object"); + return NULL; + } + + Py_INCREF(typ); + Py_XINCREF(val); + Py_XINCREF(tb); + + if (PyClass_Check(typ)) { + PyErr_NormalizeException(&typ, &val, &tb); + } + + else if (PyInstance_Check(typ)) { + /* Raising an instance. The value should be a dummy. */ + if (val && val != Py_None) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto failed_throw; + } + else { + /* Normalize to raise , */ + val = typ; + typ = (PyObject*) ((PyInstanceObject*)typ)->in_class; + Py_INCREF(typ); + } + } + else { + /* Not something you can raise. You get an exception + anyway, just not what you specified :-) */ + PyErr_Format(PyExc_TypeError, + "exceptions must be classes, or instances, not %s", + typ->ob_type->tp_name); + goto failed_throw; + } + + PyErr_Restore(typ,val,tb); + return gen_send_ex(gen, Py_None, 1); + +failed_throw: + /* Didn't use our arguments, so restore their original refcounts */ + Py_DECREF(typ); + Py_XDECREF(val); + Py_XDECREF(tb); + return NULL; +} + + +static PyObject * +gen_iternext(PyGenObject *gen) +{ + return gen_send_ex(gen, NULL, 0); +} + + static PyMemberDef gen_memberlist[] = { {"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), RO}, {"gi_running", T_INT, offsetof(PyGenObject, gi_running), RO}, {NULL} /* Sentinel */ }; +static PyMethodDef gen_methods[] = { + {"send",(PyCFunction)gen_send, METH_O, send_doc}, + {"throw",(PyCFunction)gen_throw, METH_VARARGS, throw_doc}, + {"close",(PyCFunction)gen_close, METH_NOARGS, close_doc}, + {NULL, NULL} /* Sentinel */ +}; + PyTypeObject PyGen_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, /* ob_size */ @@ -99,11 +313,26 @@ offsetof(PyGenObject, gi_weakreflist), /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ (iternextfunc)gen_iternext, /* tp_iternext */ - 0, /* tp_methods */ + gen_methods, /* tp_methods */ gen_memberlist, /* 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 */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + gen_del, /* tp_del */ }; PyObject * Index: intobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v retrieving revision 2.84.2.2 retrieving revision 2.84.2.3 diff -u -d -r2.84.2.2 -r2.84.2.3 --- intobject.c 7 Jan 2005 07:04:02 -0000 2.84.2.2 +++ intobject.c 16 Oct 2005 05:24:04 -0000 2.84.2.3 @@ -826,7 +826,10 @@ static PyObject * int_int(PyIntObject *v) { - Py_INCREF(v); + if (PyInt_CheckExact(v)) + Py_INCREF(v); + else + v = (PyIntObject *)PyInt_FromLong(v->ob_ival); return (PyObject *)v; } Index: iterobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/iterobject.c,v retrieving revision 1.10.2.2 retrieving revision 1.10.2.3 diff -u -d -r1.10.2.2 -r1.10.2.3 --- iterobject.c 7 Jan 2005 07:04:02 -0000 1.10.2.2 +++ iterobject.c 16 Oct 2005 05:24:04 -0000 1.10.2.3 @@ -71,7 +71,7 @@ return NULL; } -static int +static PyObject * iter_len(seqiterobject *it) { int seqsize, len; @@ -79,17 +79,19 @@ if (it->it_seq) { seqsize = PySequence_Size(it->it_seq); if (seqsize == -1) - return -1; + return NULL; len = seqsize - it->it_index; if (len >= 0) - return len; + return PyInt_FromLong(len); } - return 0; + return PyInt_FromLong(0); } -static PySequenceMethods iter_as_sequence = { - (inquiry)iter_len, /* sq_length */ - 0, /* sq_concat */ +PyDoc_STRVAR(length_cue_doc, "Private method returning an estimate of len(list(it))."); + +static PyMethodDef seqiter_methods[] = { + {"_length_cue", (PyCFunction)iter_len, METH_NOARGS, length_cue_doc}, + {NULL, NULL} /* sentinel */ }; PyTypeObject PySeqIter_Type = { @@ -106,7 +108,7 @@ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ - &iter_as_sequence, /* tp_as_sequence */ + 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ @@ -122,13 +124,8 @@ 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ (iternextfunc)iter_iternext, /* tp_iternext */ - 0, /* tp_methods */ + seqiter_methods, /* tp_methods */ 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ }; /* -------------------------------------- */ @@ -236,10 +233,4 @@ PyObject_SelfIter, /* tp_iter */ (iternextfunc)calliter_iternext, /* 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 */ }; Index: listobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v retrieving revision 2.114.2.2 retrieving revision 2.114.2.3 diff -u -d -r2.114.2.2 -r2.114.2.3 --- listobject.c 7 Jan 2005 07:04:02 -0000 2.114.2.2 +++ listobject.c 16 Oct 2005 05:24:04 -0000 2.114.2.3 @@ -775,8 +775,13 @@ iternext = *it->ob_type->tp_iternext; /* Guess a result list size. */ - n = PyObject_Size(b); + n = _PyObject_LengthCue(b); if (n < 0) { + if (!PyErr_ExceptionMatches(PyExc_TypeError) && + !PyErr_ExceptionMatches(PyExc_AttributeError)) { + Py_DECREF(it); + return NULL; + } PyErr_Clear(); n = 8; /* arbitrary */ } @@ -2759,21 +2764,23 @@ return NULL; } -static int +static PyObject * listiter_len(listiterobject *it) { int len; if (it->it_seq) { len = PyList_GET_SIZE(it->it_seq) - it->it_index; if (len >= 0) - return len; + return PyInt_FromLong((long)len); } - return 0; + return PyInt_FromLong(0); } -static PySequenceMethods listiter_as_sequence = { - (inquiry)listiter_len, /* sq_length */ - 0, /* sq_concat */ +PyDoc_STRVAR(length_cue_doc, "Private method returning an estimate of len(list(it))."); + +static PyMethodDef listiter_methods[] = { + {"_length_cue", (PyCFunction)listiter_len, METH_NOARGS, length_cue_doc}, + {NULL, NULL} /* sentinel */ }; PyTypeObject PyListIter_Type = { @@ -2790,7 +2797,7 @@ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ - &listiter_as_sequence, /* tp_as_sequence */ + 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ @@ -2806,13 +2813,8 @@ 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ (iternextfunc)listiter_next, /* tp_iternext */ - 0, /* tp_methods */ + listiter_methods, /* tp_methods */ 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ }; /*********************** List Reverse Iterator **************************/ Index: listsort.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/listsort.txt,v retrieving revision 1.6.10.1 retrieving revision 1.6.10.2 diff -u -d -r1.6.10.1 -r1.6.10.2 --- listsort.txt 28 Apr 2003 17:18:16 -0000 1.6.10.1 +++ listsort.txt 16 Oct 2005 05:24:04 -0000 1.6.10.2 @@ -54,6 +54,16 @@ + Here are exact comparison counts across all the tests in sortperf.py, when run with arguments "15 20 1". + Column Key: + *sort: random data + \sort: descending data + /sort: ascending data + 3sort: ascending, then 3 random exchanges + +sort: ascending, then 10 random at the end + ~sort: many duplicates + =sort: all equal + !sort: worst case scenario + First the trivial cases, trivial for samplesort because it special-cased them, and trivial for timsort because it naturally works on runs. Within an "n" block, the first line gives the # of compares done by samplesort, Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.118.2.2 retrieving revision 1.118.2.3 diff -u -d -r1.118.2.2 -r1.118.2.3 --- longobject.c 7 Jan 2005 07:04:03 -0000 1.118.2.2 +++ longobject.c 16 Oct 2005 05:24:04 -0000 1.118.2.3 @@ -783,9 +783,30 @@ return -1; } if (!PyLong_Check(vv)) { + PyNumberMethods *nb; + PyObject *io; if (PyInt_Check(vv)) return (PY_LONG_LONG)PyInt_AsLong(vv); - PyErr_BadInternalCall(); + if ((nb = vv->ob_type->tp_as_number) == NULL || + nb->nb_int == NULL) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return -1; + } + io = (*nb->nb_int) (vv); + if (io == NULL) + return -1; + if (PyInt_Check(io)) { + bytes = PyInt_AsLong(io); + Py_DECREF(io); + return bytes; + } + if (PyLong_Check(io)) { + bytes = PyLong_AsLongLong(io); + Py_DECREF(io); + return bytes; + } + Py_DECREF(io); + PyErr_SetString(PyExc_TypeError, "integer conversion failed"); return -1; } @@ -1069,7 +1090,7 @@ assert(accumbits >= basebits); do { char cdigit = (char)(accum & (base - 1)); - cdigit += (cdigit < 10) ? '0' : 'A'-10; + cdigit += (cdigit < 10) ? '0' : 'a'-10; assert(p > PyString_AS_STRING(str)); *--p = cdigit; accumbits -= basebits; @@ -1123,7 +1144,7 @@ digit nextrem = (digit)(rem / base); char c = (char)(rem - nextrem * base); assert(p > PyString_AS_STRING(str)); - c += (c < 10) ? '0' : 'A'-10; + c += (c < 10) ? '0' : 'a'-10; *--p = c; rem = nextrem; --ntostore; @@ -2339,8 +2360,11 @@ c = (PyLongObject *)x; Py_INCREF(x); } - else if (PyInt_Check(x)) + else if (PyInt_Check(x)) { c = (PyLongObject *)PyLong_FromLong(PyInt_AS_LONG(x)); + if (c == NULL) + goto Error; + } else if (x == Py_None) c = NULL; else { @@ -2490,14 +2514,14 @@ } /* fall through */ Done: - Py_XDECREF(a); - Py_XDECREF(b); - Py_XDECREF(c); - Py_XDECREF(temp); if (b->ob_size > FIVEARY_CUTOFF) { for (i = 0; i < 32; ++i) Py_XDECREF(table[i]); } + Py_DECREF(a); + Py_DECREF(b); + Py_XDECREF(c); + Py_XDECREF(temp); return (PyObject *)z; } @@ -2840,7 +2864,10 @@ static PyObject * long_long(PyObject *v) { - Py_INCREF(v); + if (PyLong_CheckExact(v)) + Py_INCREF(v); + else + v = _PyLong_Copy((PyLongObject *)v); return v; } Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.179.2.3 retrieving revision 2.179.2.4 diff -u -d -r2.179.2.3 -r2.179.2.4 --- object.c 7 Jan 2005 07:04:04 -0000 2.179.2.3 +++ object.c 16 Oct 2005 05:24:04 -0000 2.179.2.4 @@ -331,22 +331,48 @@ } PyObject * -PyObject_Str(PyObject *v) +_PyObject_Str(PyObject *v) { PyObject *res; - + int type_ok; if (v == NULL) return PyString_FromString(""); if (PyString_CheckExact(v)) { Py_INCREF(v); return v; } +#ifdef Py_USING_UNICODE + if (PyUnicode_CheckExact(v)) { + Py_INCREF(v); + return v; + } +#endif if (v->ob_type->tp_str == NULL) return PyObject_Repr(v); res = (*v->ob_type->tp_str)(v); if (res == NULL) return NULL; + type_ok = PyString_Check(res); +#ifdef Py_USING_UNICODE + type_ok = type_ok || PyUnicode_Check(res); +#endif + if (!type_ok) { + PyErr_Format(PyExc_TypeError, + "__str__ returned non-string (type %.200s)", + res->ob_type->tp_name); + Py_DECREF(res); + return NULL; + } + return res; +} + +PyObject * +PyObject_Str(PyObject *v) +{ + PyObject *res = _PyObject_Str(v); + if (res == NULL) + return NULL; #ifdef Py_USING_UNICODE if (PyUnicode_Check(res)) { PyObject* str; @@ -358,13 +384,7 @@ return NULL; } #endif - if (!PyString_Check(res)) { - PyErr_Format(PyExc_TypeError, - "__str__ returned non-string (type %.200s)", - res->ob_type->tp_name); - Py_DECREF(res); - return NULL; - } + assert(PyString_Check(res)); return res; } @@ -373,6 +393,8 @@ PyObject_Unicode(PyObject *v) { PyObject *res; + PyObject *func; + static PyObject *unicodestr; if (v == NULL) res = PyString_FromString(""); @@ -380,35 +402,32 @@ Py_INCREF(v); return v; } - if (PyUnicode_Check(v)) { - /* For a Unicode subtype that's not a Unicode object, - return a true Unicode object with the same data. */ - return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(v), - PyUnicode_GET_SIZE(v)); + /* XXX As soon as we have a tp_unicode slot, we should + check this before trying the __unicode__ + method. */ + if (unicodestr == NULL) { + unicodestr= PyString_InternFromString("__unicode__"); + if (unicodestr == NULL) + return NULL; + } + func = PyObject_GetAttr(v, unicodestr); + if (func != NULL) { + res = PyEval_CallObject(func, (PyObject *)NULL); + Py_DECREF(func); } - if (PyString_Check(v)) { - Py_INCREF(v); - res = v; - } else { - PyObject *func; - static PyObject *unicodestr; - /* XXX As soon as we have a tp_unicode slot, we should - check this before trying the __unicode__ - method. */ - if (unicodestr == NULL) { - unicodestr= PyString_InternFromString( - "__unicode__"); - if (unicodestr == NULL) - return NULL; + PyErr_Clear(); + if (PyUnicode_Check(v)) { + /* For a Unicode subtype that's didn't overwrite __unicode__, + return a true Unicode object with the same data. */ + return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(v), + PyUnicode_GET_SIZE(v)); } - func = PyObject_GetAttr(v, unicodestr); - if (func != NULL) { - res = PyEval_CallObject(func, (PyObject *)NULL); - Py_DECREF(func); + if (PyString_CheckExact(v)) { + Py_INCREF(v); + res = v; } else { - PyErr_Clear(); if (v->ob_type->tp_str != NULL) res = (*v->ob_type->tp_str)(v); else @@ -424,7 +443,7 @@ if (str) res = str; else - return NULL; + return NULL; } return res; } Index: obmalloc.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/obmalloc.c,v retrieving revision 2.45.2.2 retrieving revision 2.45.2.3 diff -u -d -r2.45.2.2 -r2.45.2.3 --- obmalloc.c 7 Jan 2005 07:04:04 -0000 2.45.2.2 +++ obmalloc.c 16 Oct 2005 05:24:04 -0000 2.45.2.3 @@ -139,9 +139,9 @@ * getpagesize() call or deduced from various header files. To make * things simpler, we assume that it is 4K, which is OK for most systems. * It is probably better if this is the native page size, but it doesn't - * have to be. In theory, if SYSTEM_PAGE_SIZE is larger than the native page - * size, then `POOL_ADDR(p)->arenaindex' could rarely cause a segmentation - * violation fault. 4K is apparently OK for all the platforms that python + * have to be. In theory, if SYSTEM_PAGE_SIZE is larger than the native page + * size, then `POOL_ADDR(p)->arenaindex' could rarely cause a segmentation + * violation fault. 4K is apparently OK for all the platforms that python * currently targets. */ #define SYSTEM_PAGE_SIZE (4 * 1024) @@ -841,30 +841,26 @@ } return bp; } - /* We're not managing this block. */ - if (nbytes <= SMALL_REQUEST_THRESHOLD) { - /* Take over this block -- ask for at least one byte so - * we really do take it over (PyObject_Malloc(0) goes to - * the system malloc). - */ - bp = PyObject_Malloc(nbytes ? nbytes : 1); - if (bp != NULL) { - memcpy(bp, p, nbytes); - free(p); - } - else if (nbytes == 0) { - /* Meet the doc's promise that nbytes==0 will - * never return a NULL pointer when p isn't NULL. - */ - bp = p; - } - - } - else { - assert(nbytes != 0); - bp = realloc(p, nbytes); - } - return bp; + /* We're not managing this block. If nbytes <= + * SMALL_REQUEST_THRESHOLD, it's tempting to try to take over this + * block. However, if we do, we need to copy the valid data from + * the C-managed block to one of our blocks, and there's no portable + * way to know how much of the memory space starting at p is valid. + * As bug 1185883 pointed out the hard way, it's possible that the + * C-managed block is "at the end" of allocated VM space, so that + * a memory fault can occur if we try to copy nbytes bytes starting + * at p. Instead we punt: let C continue to manage this block. + */ + if (nbytes) + return realloc(p, nbytes); + /* C doesn't define the result of realloc(p, 0) (it may or may not + * return NULL then), but Python's docs promise that nbytes==0 never + * returns NULL. We don't pass 0 to realloc(), to avoid that endcase + * to begin with. Even then, we can't be sure that realloc() won't + * return NULL. + */ + bp = realloc(p, 1); + return bp ? bp : p; } #else /* ! WITH_PYMALLOC */ Index: rangeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/rangeobject.c,v retrieving revision 2.41.2.2 retrieving revision 2.41.2.3 diff -u -d -r2.41.2.2 -r2.41.2.3 --- rangeobject.c 7 Jan 2005 07:04:04 -0000 2.41.2.2 +++ rangeobject.c 16 Oct 2005 05:24:04 -0000 2.41.2.3 @@ -45,6 +45,9 @@ long ilow = 0, ihigh = 0, istep = 1; long n; + if (!_PyArg_NoKeywords("xrange()", kw)) + return NULL; + if (PyTuple_Size(args) <= 1) { if (!PyArg_ParseTuple(args, "l;xrange() requires 1-3 int arguments", @@ -259,17 +262,18 @@ return NULL; } -static int +static PyObject * rangeiter_len(rangeiterobject *r) { - return r->len - r->index; + return PyInt_FromLong(r->len - r->index); } -static PySequenceMethods rangeiter_as_sequence = { - (inquiry)rangeiter_len, /* sq_length */ - 0, /* sq_concat */ -}; +PyDoc_STRVAR(length_cue_doc, "Private method returning an estimate of len(list(it))."); +static PyMethodDef rangeiter_methods[] = { + {"_length_cue", (PyCFunction)rangeiter_len, METH_NOARGS, length_cue_doc}, + {NULL, NULL} /* sentinel */ +}; static PyTypeObject Pyrangeiter_Type = { PyObject_HEAD_INIT(&PyType_Type) @@ -285,7 +289,7 @@ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ - &rangeiter_as_sequence, /* tp_as_sequence */ + 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ @@ -301,5 +305,6 @@ 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ (iternextfunc)rangeiter_next, /* tp_iternext */ - 0, /* tp_methods */ + rangeiter_methods, /* tp_methods */ + 0, }; Index: setobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/setobject.c,v retrieving revision 1.31.4.1 retrieving revision 1.31.4.2 diff -u -d -r1.31.4.1 -r1.31.4.2 --- setobject.c 7 Jan 2005 07:04:04 -0000 1.31.4.1 +++ setobject.c 16 Oct 2005 05:24:04 -0000 1.31.4.2 @@ -1,41 +1,882 @@ -#include "Python.h" -#include "structmember.h" /* set object implementation - written and maintained by Raymond D. Hettinger - derived from sets.py written by Greg V. Wilson, Alex Martelli, - Guido van Rossum, Raymond Hettinger, and Tim Peters. + Written and maintained by Raymond D. Hettinger + Derived from Lib/sets.py and Objects/dictobject.c. - Copyright (c) 2003 Python Software Foundation. [...2120 lines suppressed...] + + /* Verify constructors accept NULL arguments */ + f = PySet_New(NULL); + assert(f != NULL); + assert(PySet_GET_SIZE(f) == 0); + Py_DECREF(f); + f = PyFrozenSet_New(NULL); + assert(f != NULL); + assert(PyFrozenSet_CheckExact(f)); + assert(PySet_GET_SIZE(f) == 0); + Py_DECREF(f); + + Py_DECREF(elem); + Py_DECREF(dup); + Py_RETURN_TRUE; +} + +#undef assertRaises + +#endif Index: sliceobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/sliceobject.c,v retrieving revision 2.15.2.2 retrieving revision 2.15.2.3 diff -u -d -r2.15.2.2 -r2.15.2.3 --- sliceobject.c 7 Jan 2005 07:04:05 -0000 2.15.2.2 +++ sliceobject.c 16 Oct 2005 05:24:04 -0000 2.15.2.3 @@ -174,6 +174,9 @@ start = stop = step = NULL; + if (!_PyArg_NoKeywords("slice()", kw)) + return NULL; + if (!PyArg_UnpackTuple(args, "slice", 1, 3, &start, &stop, &step)) return NULL; Index: stringobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v retrieving revision 2.168.2.2 retrieving revision 2.168.2.3 diff -u -d -r2.168.2.2 -r2.168.2.3 --- stringobject.c 7 Jan 2005 07:04:05 -0000 2.168.2.2 +++ stringobject.c 16 Oct 2005 05:24:04 -0000 2.168.2.3 @@ -52,6 +52,7 @@ PyString_FromStringAndSize(const char *str, int size) { register PyStringObject *op; + assert(size >= 0); if (size == 0 && (op = nullstring) != NULL) { #ifdef COUNT_ALLOCS null_strings++; @@ -1001,8 +1002,12 @@ static int string_contains(PyObject *a, PyObject *el) { - const char *lhs, *rhs, *end; - int size; + char *s = PyString_AS_STRING(a); + const char *sub = PyString_AS_STRING(el); + char *last; + int len_sub = PyString_GET_SIZE(el); + int shortsub; + char firstchar, lastchar; if (!PyString_CheckExact(el)) { #ifdef Py_USING_UNICODE @@ -1015,20 +1020,29 @@ return -1; } } - size = PyString_GET_SIZE(el); - rhs = PyString_AS_STRING(el); - lhs = PyString_AS_STRING(a); - - /* optimize for a single character */ - if (size == 1) - return memchr(lhs, *rhs, PyString_GET_SIZE(a)) != NULL; - end = lhs + (PyString_GET_SIZE(a) - size); - while (lhs <= end) { - if (memcmp(lhs++, rhs, size) == 0) + if (len_sub == 0) + return 1; + /* last points to one char beyond the start of the rightmost + substring. When s= m) + break; + t = memchr(s+i, sub[0], m-i); + if (t == NULL) + break; + i = t - s; } return PyInt_FromLong((long) r); } - PyDoc_STRVAR(swapcase__doc__, "S.swapcase() -> string\n\ \n\ @@ -3734,18 +3753,12 @@ } /* Fix up case for hex conversions. */ - switch (type) { - case 'x': - /* Need to convert all upper case letters to lower case. */ + if (type == 'X') { + /* Need to convert all lower case letters to upper case. + and need to convert 0x to 0X (and -0x to -0X). */ for (i = 0; i < len; i++) - if (buf[i] >= 'A' && buf[i] <= 'F') - buf[i] += 'a'-'A'; - break; - case 'X': - /* Need to convert 0x to 0X (and -0x to -0X). */ - if (buf[sign + 1] == 'x') - buf[sign + 1] = 'X'; - break; + if (buf[i] >= 'a' && buf[i] <= 'x') + buf[i] -= 'a'-'A'; } *pbuf = buf; *plen = len; @@ -3840,7 +3853,6 @@ return 1; } - /* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...) FORMATBUFLEN is the length of the buffer in which the floats, ints, & @@ -4072,18 +4084,22 @@ goto unicode; } #endif + temp = _PyObject_Str(v); +#ifdef Py_USING_UNICODE + if (temp != NULL && PyUnicode_Check(temp)) { + Py_DECREF(temp); + fmt = fmt_start; + argidx = argidx_start; + goto unicode; + } +#endif /* Fall through */ case 'r': - if (c == 's') - temp = PyObject_Str(v); - else + if (c == 'r') temp = PyObject_Repr(v); if (temp == NULL) goto error; if (!PyString_Check(temp)) { - /* XXX Note: this should never happen, - since PyObject_Repr() and - PyObject_Str() assure this */ PyErr_SetString(PyExc_TypeError, "%s argument has non-string str()"); Py_DECREF(temp); Index: tupleobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/tupleobject.c,v retrieving revision 2.68.2.2 retrieving revision 2.68.2.3 diff -u -d -r2.68.2.2 -r2.68.2.3 --- tupleobject.c 7 Jan 2005 07:04:06 -0000 2.68.2.2 +++ tupleobject.c 16 Oct 2005 05:24:04 -0000 2.68.2.3 @@ -851,17 +851,20 @@ return NULL; } -static int +static PyObject * tupleiter_len(tupleiterobject *it) { + int len = 0; if (it->it_seq) - return PyTuple_GET_SIZE(it->it_seq) - it->it_index; - return 0; + len = PyTuple_GET_SIZE(it->it_seq) - it->it_index; + return PyInt_FromLong(len); } -static PySequenceMethods tupleiter_as_sequence = { - (inquiry)tupleiter_len, /* sq_length */ - 0, /* sq_concat */ +PyDoc_STRVAR(length_cue_doc, "Private method returning an estimate of len(list(it))."); + +static PyMethodDef tupleiter_methods[] = { + {"_length_cue", (PyCFunction)tupleiter_len, METH_NOARGS, length_cue_doc}, + {NULL, NULL} /* sentinel */ }; PyTypeObject PyTupleIter_Type = { @@ -878,7 +881,7 @@ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ - &tupleiter_as_sequence, /* tp_as_sequence */ + 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ @@ -894,4 +897,6 @@ 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ (iternextfunc)tupleiter_next, /* tp_iternext */ + tupleiter_methods, /* tp_methods */ + 0, }; Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.157.2.3 retrieving revision 2.157.2.4 diff -u -d -r2.157.2.3 -r2.157.2.4 --- typeobject.c 7 Jan 2005 07:04:06 -0000 2.157.2.3 +++ typeobject.c 16 Oct 2005 05:24:04 -0000 2.157.2.4 @@ -2516,7 +2516,7 @@ clsdict = ((PyTypeObject *)cls)->tp_dict; slotnames = PyDict_GetItemString(clsdict, "__slotnames__"); - if (slotnames != NULL) { + if (slotnames != NULL && PyList_Check(slotnames)) { Py_INCREF(slotnames); return slotnames; } @@ -4065,14 +4065,24 @@ { static PyObject *len_str; PyObject *res = call_method(self, "__len__", &len_str, "()"); + long temp; int len; if (res == NULL) return -1; - len = (int)PyInt_AsLong(res); + temp = PyInt_AsLong(res); + len = (int)temp; Py_DECREF(res); if (len == -1 && PyErr_Occurred()) return -1; +#if SIZEOF_INT < SIZEOF_LONG + /* Overflow check -- range of PyInt is more than C int */ + if (len != temp) { + PyErr_SetString(PyExc_OverflowError, + "__len__() should return 0 <= outcome < 2**31"); + return -1; + } +#endif if (len < 0) { PyErr_SetString(PyExc_ValueError, "__len__() should return >= 0"); @@ -4747,6 +4757,12 @@ Py_DECREF(meth); if (res == NULL) return -1; + if (res != Py_None) { + PyErr_SetString(PyExc_TypeError, + "__init__() should return None"); + Py_DECREF(res); + return -1; + } Py_DECREF(res); return 0; } @@ -4896,6 +4912,12 @@ #define RBINSLOT(NAME, SLOT, FUNCTION, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \ "x." NAME "(y) <==> y" DOC "x") +#define BINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \ + ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \ + "x." NAME "(y) <==> " DOC) +#define RBINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \ + ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \ + "x." NAME "(y) <==> " DOC) static slotdef slotdefs[] = { SQSLOT("__len__", sq_length, slot_sq_length, wrap_inquiry, @@ -4964,9 +4986,9 @@ "%"), RBINSLOT("__rmod__", nb_remainder, slot_nb_remainder, "%"), - BINSLOT("__divmod__", nb_divmod, slot_nb_divmod, + BINSLOTNOTINFIX("__divmod__", nb_divmod, slot_nb_divmod, "divmod(x, y)"), - RBINSLOT("__rdivmod__", nb_divmod, slot_nb_divmod, + RBINSLOTNOTINFIX("__rdivmod__", nb_divmod, slot_nb_divmod, "divmod(y, x)"), NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc, "x.__pow__(y[, z]) <==> pow(x, y[, z])"), @@ -5636,7 +5658,7 @@ return self; } if (su->ob_type != &PySuper_Type) - /* If su is not an instance of a subclass of super, + /* If su is an instance of a (strict) subclass of super, call its type */ return PyObject_CallFunction((PyObject *)su->ob_type, "OO", su->type, obj); Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.155.2.2 retrieving revision 2.155.2.3 diff -u -d -r2.155.2.2 -r2.155.2.3 --- unicodeobject.c 7 Jan 2005 07:04:09 -0000 2.155.2.2 +++ unicodeobject.c 16 Oct 2005 05:24:04 -0000 2.155.2.3 @@ -2273,6 +2273,81 @@ PyUnicode_GET_SIZE(unicode)); } +/* --- Unicode Internal Codec ------------------------------------------- */ + +PyObject *_PyUnicode_DecodeUnicodeInternal(const char *s, + int size, + const char *errors) +{ + const char *starts = s; + int startinpos; + int endinpos; + int outpos; + Py_UNICODE unimax; + PyUnicodeObject *v; + Py_UNICODE *p; + const char *end; + const char *reason; + PyObject *errorHandler = NULL; + PyObject *exc = NULL; + + unimax = PyUnicode_GetMax(); + v = _PyUnicode_New((size+Py_UNICODE_SIZE-1)/ Py_UNICODE_SIZE); + if (v == NULL) + goto onError; + if (PyUnicode_GetSize((PyObject *)v) == 0) + return (PyObject *)v; + p = PyUnicode_AS_UNICODE(v); + end = s + size; + + while (s < end) { + *p = *(Py_UNICODE *)s; + /* We have to sanity check the raw data, otherwise doom looms for + some malformed UCS-4 data. */ + if ( + #ifdef Py_UNICODE_WIDE + *p > unimax || *p < 0 || + #endif + end-s < Py_UNICODE_SIZE + ) + { + startinpos = s - starts; + if (end-s < Py_UNICODE_SIZE) { + endinpos = end-starts; + reason = "truncated input"; + } + else { + endinpos = s - starts + Py_UNICODE_SIZE; + reason = "illegal code point (> 0x10FFFF)"; + } + outpos = p - PyUnicode_AS_UNICODE(v); + if (unicode_decode_call_errorhandler( + errors, &errorHandler, + "unicode_internal", reason, + starts, size, &startinpos, &endinpos, &exc, &s, + (PyObject **)&v, &outpos, &p)) { + goto onError; + } + } + else { + p++; + s += Py_UNICODE_SIZE; + } + } + + if (_PyUnicode_Resize(&v, (int)(p - PyUnicode_AS_UNICODE(v))) < 0) + goto onError; + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + return (PyObject *)v; + + onError: + Py_XDECREF(v); + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + return NULL; +} + /* --- Latin-1 Codec ------------------------------------------------------ */ PyObject *PyUnicode_DecodeLatin1(const char *s, @@ -2758,6 +2833,8 @@ int extrachars = 0; PyObject *errorHandler = NULL; PyObject *exc = NULL; + Py_UNICODE *mapstring = NULL; + int maplen = 0; /* Default to Latin-1 */ if (mapping == NULL) @@ -2770,91 +2847,121 @@ return (PyObject *)v; p = PyUnicode_AS_UNICODE(v); e = s + size; - while (s < e) { - unsigned char ch = *s; - PyObject *w, *x; + if (PyUnicode_CheckExact(mapping)) { + mapstring = PyUnicode_AS_UNICODE(mapping); + maplen = PyUnicode_GET_SIZE(mapping); + while (s < e) { + unsigned char ch = *s; + Py_UNICODE x = 0xfffe; /* illegal value */ - /* Get mapping (char ordinal -> integer, Unicode char or None) */ - w = PyInt_FromLong((long)ch); - if (w == NULL) - goto onError; - x = PyObject_GetItem(mapping, w); - Py_DECREF(w); - if (x == NULL) { - if (PyErr_ExceptionMatches(PyExc_LookupError)) { - /* No mapping found means: mapping is undefined. */ - PyErr_Clear(); - x = Py_None; - Py_INCREF(x); - } else - goto onError; - } + if (ch < maplen) + x = mapstring[ch]; - /* Apply mapping */ - if (PyInt_Check(x)) { - long value = PyInt_AS_LONG(x); - if (value < 0 || value > 65535) { - PyErr_SetString(PyExc_TypeError, - "character mapping must be in range(65536)"); - Py_DECREF(x); - goto onError; + if (x == 0xfffe) { + /* undefined mapping */ + outpos = p-PyUnicode_AS_UNICODE(v); + startinpos = s-starts; + endinpos = startinpos+1; + if (unicode_decode_call_errorhandler( + errors, &errorHandler, + "charmap", "character maps to ", + starts, size, &startinpos, &endinpos, &exc, &s, + (PyObject **)&v, &outpos, &p)) { + goto onError; + } + continue; } - *p++ = (Py_UNICODE)value; + *p++ = x; + ++s; } - else if (x == Py_None) { - /* undefined mapping */ - outpos = p-PyUnicode_AS_UNICODE(v); - startinpos = s-starts; - endinpos = startinpos+1; - if (unicode_decode_call_errorhandler( - errors, &errorHandler, - "charmap", "character maps to ", - starts, size, &startinpos, &endinpos, &exc, &s, - (PyObject **)&v, &outpos, &p)) { - Py_DECREF(x); + } + else { + while (s < e) { + unsigned char ch = *s; + PyObject *w, *x; + + /* Get mapping (char ordinal -> integer, Unicode char or None) */ + w = PyInt_FromLong((long)ch); + if (w == NULL) goto onError; + x = PyObject_GetItem(mapping, w); + Py_DECREF(w); + if (x == NULL) { + if (PyErr_ExceptionMatches(PyExc_LookupError)) { + /* No mapping found means: mapping is undefined. */ + PyErr_Clear(); + x = Py_None; + Py_INCREF(x); + } else + goto onError; } - continue; - } - else if (PyUnicode_Check(x)) { - int targetsize = PyUnicode_GET_SIZE(x); - - if (targetsize == 1) - /* 1-1 mapping */ - *p++ = *PyUnicode_AS_UNICODE(x); - - else if (targetsize > 1) { - /* 1-n mapping */ - if (targetsize > extrachars) { - /* resize first */ - int oldpos = (int)(p - PyUnicode_AS_UNICODE(v)); - int needed = (targetsize - extrachars) + \ - (targetsize << 2); - extrachars += needed; - if (_PyUnicode_Resize(&v, - PyUnicode_GET_SIZE(v) + needed) < 0) { - Py_DECREF(x); - goto onError; + + /* Apply mapping */ + if (PyInt_Check(x)) { + long value = PyInt_AS_LONG(x); + if (value < 0 || value > 65535) { + PyErr_SetString(PyExc_TypeError, + "character mapping must be in range(65536)"); + Py_DECREF(x); + goto onError; + } + *p++ = (Py_UNICODE)value; + } + else if (x == Py_None) { + /* undefined mapping */ + outpos = p-PyUnicode_AS_UNICODE(v); + startinpos = s-starts; + endinpos = startinpos+1; + if (unicode_decode_call_errorhandler( + errors, &errorHandler, + "charmap", "character maps to ", + starts, size, &startinpos, &endinpos, &exc, &s, + (PyObject **)&v, &outpos, &p)) { + Py_DECREF(x); + goto onError; + } + continue; + } + else if (PyUnicode_Check(x)) { + int targetsize = PyUnicode_GET_SIZE(x); + + if (targetsize == 1) + /* 1-1 mapping */ + *p++ = *PyUnicode_AS_UNICODE(x); + + else if (targetsize > 1) { + /* 1-n mapping */ + if (targetsize > extrachars) { + /* resize first */ + int oldpos = (int)(p - PyUnicode_AS_UNICODE(v)); + int needed = (targetsize - extrachars) + \ + (targetsize << 2); + extrachars += needed; + if (_PyUnicode_Resize(&v, + PyUnicode_GET_SIZE(v) + needed) < 0) { + Py_DECREF(x); + goto onError; + } + p = PyUnicode_AS_UNICODE(v) + oldpos; } - p = PyUnicode_AS_UNICODE(v) + oldpos; + Py_UNICODE_COPY(p, + PyUnicode_AS_UNICODE(x), + targetsize); + p += targetsize; + extrachars -= targetsize; } - Py_UNICODE_COPY(p, - PyUnicode_AS_UNICODE(x), - targetsize); - p += targetsize; - extrachars -= targetsize; + /* 1-0 mapping: skip the character */ + } + else { + /* wrong return value */ + PyErr_SetString(PyExc_TypeError, + "character mapping must return integer, None or unicode"); + Py_DECREF(x); + goto onError; } - /* 1-0 mapping: skip the character */ - } - else { - /* wrong return value */ - PyErr_SetString(PyExc_TypeError, - "character mapping must return integer, None or unicode"); Py_DECREF(x); - goto onError; + ++s; } - Py_DECREF(x); - ++s; } if (p - PyUnicode_AS_UNICODE(v) < PyUnicode_GET_SIZE(v)) if (_PyUnicode_Resize(&v, (int)(p - PyUnicode_AS_UNICODE(v))) < 0) Index: weakrefobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/weakrefobject.c,v retrieving revision 1.9.2.2 retrieving revision 1.9.2.3 diff -u -d -r1.9.2.2 -r1.9.2.3 --- weakrefobject.c 7 Jan 2005 07:04:10 -0000 1.9.2.2 +++ weakrefobject.c 16 Oct 2005 05:24:05 -0000 1.9.2.3 @@ -505,11 +505,7 @@ PyObject *o = PyWeakref_GET_OBJECT(proxy); if (!proxy_checkref(proxy)) return -1; - if (o->ob_type->tp_as_number && - o->ob_type->tp_as_number->nb_nonzero) - return (*o->ob_type->tp_as_number->nb_nonzero)(o); - else - return 1; + return PyObject_IsTrue(o); } static void From jhylton at users.sourceforge.net Sun Oct 16 07:24:12 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Sun, 16 Oct 2005 07:24:12 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Python bltinmodule.c, 2.261.2.4, 2.261.2.5 ceval.c, 2.314.2.6, 2.314.2.7 compile.c, 2.247.2.3, 2.247.2.4 errors.c, 2.70.2.3, 2.70.2.4 exceptions.c, 1.32.2.2, 1.32.2.3 future.c, 2.12.2.7, 2.12.2.8 getargs.c, 2.92.2.2, 2.92.2.3 getcopyright.c, 1.16.2.2, 1.16.2.3 graminit.c, 2.33.2.3, 2.33.2.4 import.c, 2.208.2.6, 2.208.2.7 marshal.c, 1.72.2.3, 1.72.2.4 pystate.c, 2.20.18.2, 2.20.18.3 pythonrun.c, 2.161.2.18, 2.161.2.19 structmember.c, 2.23.8.1, 2.23.8.2 sysmodule.c, 2.107.2.3, 2.107.2.4 thread.c, 2.44.2.2, 2.44.2.3 thread_nt.h, 2.22.2.1, 2.22.2.2 thread_os2.h, 2.14.2.1, 2.14.2.2 thread_pthread.h, 2.40.2.2, 2.40.2.3 thread_wince.h, 2.7, 2.7.12.1 Message-ID: <20051016052412.159FC1E4013@bag.python.org> Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27718/Python Modified Files: Tag: ast-branch bltinmodule.c ceval.c compile.c errors.c exceptions.c future.c getargs.c getcopyright.c graminit.c import.c marshal.c pystate.c pythonrun.c structmember.c sysmodule.c thread.c thread_nt.h thread_os2.h thread_pthread.h thread_wince.h Log Message: Merge head to branch (for the last time) Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.261.2.4 retrieving revision 2.261.2.5 diff -u -d -r2.261.2.4 -r2.261.2.5 --- bltinmodule.c 7 Jan 2005 07:04:35 -0000 2.261.2.4 +++ bltinmodule.c 16 Oct 2005 05:24:05 -0000 2.261.2.5 @@ -68,6 +68,69 @@ \n\ Return the absolute value of the argument."); +static PyObject * +builtin_all(PyObject *self, PyObject *v) +{ + PyObject *it, *item; + + it = PyObject_GetIter(v); + if (it == NULL) + return NULL; + + while ((item = PyIter_Next(it)) != NULL) { + int cmp = PyObject_IsTrue(item); + Py_DECREF(item); + if (cmp < 0) { + Py_DECREF(it); + return NULL; + } + if (cmp == 0) { + Py_DECREF(it); + Py_RETURN_FALSE; + } + } + Py_DECREF(it); + if (PyErr_Occurred()) + return NULL; + Py_RETURN_TRUE; +} + +PyDoc_STRVAR(all_doc, +"all(iterable) -> bool\n\ +\n\ +Return True if bool(x) is True for all values x in the iterable."); + +static PyObject * +builtin_any(PyObject *self, PyObject *v) +{ + PyObject *it, *item; + + it = PyObject_GetIter(v); + if (it == NULL) + return NULL; + + while ((item = PyIter_Next(it)) != NULL) { + int cmp = PyObject_IsTrue(item); + Py_DECREF(item); + if (cmp < 0) { + Py_DECREF(it); + return NULL; + } + if (cmp == 1) { + Py_DECREF(it); + Py_RETURN_TRUE; + } + } + Py_DECREF(it); + if (PyErr_Occurred()) + return NULL; + Py_RETURN_FALSE; +} + +PyDoc_STRVAR(any_doc, +"any(iterable) -> bool\n\ +\n\ +Return True if bool(x) is True for any x in the iterable."); static PyObject * builtin_apply(PyObject *self, PyObject *args) @@ -147,23 +210,27 @@ if (PyTuple_Check(seq)) return filtertuple(func, seq); + /* Pre-allocate argument list tuple. */ + arg = PyTuple_New(1); + if (arg == NULL) + return NULL; + /* Get iterator. */ it = PyObject_GetIter(seq); if (it == NULL) - return NULL; + goto Fail_arg; /* Guess a result list size. */ - len = PyObject_Size(seq); + len = _PyObject_LengthCue(seq); if (len < 0) { + if (!PyErr_ExceptionMatches(PyExc_TypeError) && + !PyErr_ExceptionMatches(PyExc_AttributeError)) { + goto Fail_it; + } PyErr_Clear(); len = 8; /* arbitrary */ } - /* Pre-allocate argument list tuple. */ - arg = PyTuple_New(1); - if (arg == NULL) - goto Fail_arg; - /* Get a result list. */ if (PyList_Check(seq) && seq->ob_refcnt == 1) { /* Eww - can modify the list in-place. */ @@ -462,7 +529,7 @@ return NULL; } if (globals != Py_None && !PyDict_Check(globals)) { - PyErr_SetString(PyExc_TypeError, PyMapping_Check(globals) ? + PyErr_SetString(PyExc_TypeError, PyMapping_Check(globals) ? "globals must be a real dict; try eval(expr, {}, mapping)" : "globals must be a dict"); return NULL; @@ -475,6 +542,13 @@ else if (locals == Py_None) locals = globals; + if (globals == NULL || locals == NULL) { + PyErr_SetString(PyExc_TypeError, + "eval must be given globals and locals " + "when called without a frame"); + return NULL; + } + if (PyDict_GetItemString(globals, "__builtins__") == NULL) { if (PyDict_SetItemString(globals, "__builtins__", PyEval_GetBuiltins()) != 0) @@ -799,8 +873,12 @@ } /* Update len. */ - curlen = PyObject_Size(curseq); + curlen = _PyObject_LengthCue(curseq); if (curlen < 0) { + if (!PyErr_ExceptionMatches(PyExc_TypeError) && + !PyErr_ExceptionMatches(PyExc_AttributeError)) { + goto Fail_2; + } PyErr_Clear(); curlen = 8; /* arbitrary */ } @@ -1127,11 +1205,11 @@ if (kwds != NULL && PyDict_Check(kwds) && PyDict_Size(kwds)) { keyfunc = PyDict_GetItemString(kwds, "key"); if (PyDict_Size(kwds)!=1 || keyfunc == NULL) { - PyErr_Format(PyExc_TypeError, + PyErr_Format(PyExc_TypeError, "%s() got an unexpected keyword argument", name); return NULL; } - } + } it = PyObject_GetIter(v); if (it == NULL) @@ -1830,11 +1908,9 @@ static char *kwlist[] = {"iterable", "cmp", "key", "reverse", 0}; long reverse; - if (args != NULL) { - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OOi:sorted", - kwlist, &seq, &compare, &keyfunc, &reverse)) - return NULL; - } + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OOi:sorted", + kwlist, &seq, &compare, &keyfunc, &reverse)) + return NULL; newlist = PySequence_List(seq); if (newlist == NULL) @@ -1845,7 +1921,7 @@ Py_DECREF(newlist); return NULL; } - + newargs = PyTuple_GetSlice(args, 1, 4); if (newargs == NULL) { Py_DECREF(newlist); @@ -2032,8 +2108,12 @@ len = -1; /* unknown */ for (i = 0; i < itemsize; ++i) { PyObject *item = PyTuple_GET_ITEM(args, i); - int thislen = PyObject_Size(item); + int thislen = _PyObject_LengthCue(item); if (thislen < 0) { + if (!PyErr_ExceptionMatches(PyExc_TypeError) && + !PyErr_ExceptionMatches(PyExc_AttributeError)) { + return NULL; + } PyErr_Clear(); len = -1; break; @@ -2125,6 +2205,8 @@ static PyMethodDef builtin_methods[] = { {"__import__", builtin___import__, METH_VARARGS, import_doc}, {"abs", builtin_abs, METH_O, abs_doc}, + {"all", builtin_all, METH_O, all_doc}, + {"any", builtin_any, METH_O, any_doc}, {"apply", builtin_apply, METH_VARARGS, apply_doc}, {"callable", builtin_callable, METH_O, callable_doc}, {"chr", builtin_chr, METH_VARARGS, chr_doc}, @@ -2471,21 +2553,21 @@ if (ok) { int reslen; if (!PyUnicode_Check(item)) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_TypeError, "can't filter unicode to unicode:" " __getitem__ returned different type"); Py_DECREF(item); goto Fail_1; } reslen = PyUnicode_GET_SIZE(item); - if (reslen == 1) + if (reslen == 1) PyUnicode_AS_UNICODE(result)[j++] = PyUnicode_AS_UNICODE(item)[0]; else { /* do we need more space? */ int need = j + reslen + len - i - 1; if (need > outlen) { - /* overallocate, + /* overallocate, to avoid reallocations */ if (need < 2 * outlen) need = 2 * outlen; Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.314.2.6 retrieving revision 2.314.2.7 diff -u -d -r2.314.2.6 -r2.314.2.7 --- ceval.c 7 Jan 2005 07:04:36 -0000 2.314.2.6 +++ ceval.c 16 Oct 2005 05:24:05 -0000 2.314.2.7 @@ -17,8 +17,10 @@ #include #ifndef WITH_TSC -#define rdtscll(var) -#else /*WITH_TSC defined*/ + +#define READ_TIMESTAMP(var) + +#else typedef unsigned long long uint64; @@ -26,7 +28,7 @@ section should work for GCC on any PowerPC platform, irrespective of OS. POWER? Who knows :-) */ -#define rdtscll(var) ppc_getcounter(&var) +#define READ_TIMESTAMP(var) ppc_getcounter(&var) static void ppc_getcounter(uint64 *v) @@ -45,9 +47,10 @@ ((long*)(v))[1] = tb; } -#else /* this section is for linux/x86 */ +#else /* this is for linux/x86 (and probably any other GCC/x86 combo) */ -#include +#define READ_TIMESTAMP(val) \ + __asm__ __volatile__("rdtsc" : "=A" (val)) #endif @@ -99,7 +102,7 @@ static int call_trace(Py_tracefunc, PyObject *, PyFrameObject *, int, PyObject *); static void call_trace_protected(Py_tracefunc, PyObject *, - PyFrameObject *, int); + PyFrameObject *, int, PyObject *); static void call_exc_trace(Py_tracefunc, PyObject *, PyFrameObject *); static int maybe_call_line_trace(Py_tracefunc, PyObject *, PyFrameObject *, int *, int *, int *); @@ -414,8 +417,11 @@ /* The interpreter's recursion limit */ -static int recursion_limit = 1000; -int _Py_CheckRecursionLimit = 1000; +#ifndef Py_DEFAULT_RECURSION_LIMIT +#define Py_DEFAULT_RECURSION_LIMIT 1000 +#endif +static int recursion_limit = Py_DEFAULT_RECURSION_LIMIT; +int _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT; int Py_GetRecursionLimit(void) @@ -493,7 +499,14 @@ /* Interpreter main loop */ PyObject * -PyEval_EvalFrame(PyFrameObject *f) +PyEval_EvalFrame(PyFrameObject *f) { + /* This is for backward compatibility with extension modules that + used this API; core interpreter code should call PyEval_EvalFrameEx() */ + return PyEval_EvalFrameEx(f, 0); +} + +PyObject * +PyEval_EvalFrameEx(PyFrameObject *f, int throw) { #ifdef DXPAIRS int lastopcode = 0; @@ -575,10 +588,10 @@ uint64 inst0, inst1, loop0, loop1, intr0 = 0, intr1 = 0; int ticked = 0; - rdtscll(inst0); - rdtscll(inst1); - rdtscll(loop0); - rdtscll(loop1); + READ_TIMESTAMP(inst0); + READ_TIMESTAMP(inst1); + READ_TIMESTAMP(loop0); + READ_TIMESTAMP(loop1); /* shut up the compiler */ opcode = 0; @@ -715,7 +728,7 @@ consts = co->co_consts; fastlocals = f->f_localsplus; freevars = f->f_localsplus + f->f_nlocals; - first_instr = PyString_AS_STRING(co->co_code); + first_instr = (unsigned char*) PyString_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 @@ -741,6 +754,11 @@ x = Py_None; /* Not a reference, just anything non-NULL */ w = NULL; + if (throw) { /* support for generator.throw() */ + why = WHY_EXCEPTION; + goto on_error; + } + for (;;) { #ifdef WITH_TSC if (inst1 == 0) { @@ -748,7 +766,7 @@ or a continue, preventing inst1 from being set on the way out of the loop. */ - rdtscll(inst1); + READ_TIMESTAMP(inst1); loop1 = inst1; } dump_tsc(opcode, ticked, inst0, inst1, loop0, loop1, @@ -757,7 +775,7 @@ inst1 = 0; intr0 = 0; intr1 = 0; - rdtscll(loop0); + READ_TIMESTAMP(loop0); #endif assert(stack_pointer >= f->f_valuestack); /* else underflow */ assert(STACK_LEVEL() <= f->f_stacksize); /* else overflow */ @@ -883,7 +901,7 @@ #endif /* Main switch on opcode */ - rdtscll(inst0); + READ_TIMESTAMP(inst0); switch (opcode) { @@ -1642,9 +1660,9 @@ v = SECOND(); u = THIRD(); STACKADJ(-3); - rdtscll(intr0); + READ_TIMESTAMP(intr0); err = exec_statement(f, u, v, w); - rdtscll(intr1); + READ_TIMESTAMP(intr1); Py_DECREF(u); Py_DECREF(v); Py_DECREF(w); @@ -2020,9 +2038,9 @@ x = NULL; break; } - rdtscll(intr0); + READ_TIMESTAMP(intr0); x = PyEval_CallObject(x, w); - rdtscll(intr1); + READ_TIMESTAMP(intr1); Py_DECREF(w); SET_TOP(x); if (x != NULL) continue; @@ -2036,9 +2054,9 @@ "no locals found during 'import *'"); break; } - rdtscll(intr0); + READ_TIMESTAMP(intr0); err = import_all_from(x, v); - rdtscll(intr1); + READ_TIMESTAMP(intr1); PyFrame_LocalsToFast(f, 0); Py_DECREF(v); if (err == 0) continue; @@ -2047,9 +2065,9 @@ case IMPORT_FROM: w = GETITEM(names, oparg); v = TOP(); - rdtscll(intr0); + READ_TIMESTAMP(intr0); x = import_from(v, w); - rdtscll(intr1); + READ_TIMESTAMP(intr1); PUSH(x); if (x != NULL) continue; break; @@ -2203,9 +2221,9 @@ } else Py_INCREF(func); sp = stack_pointer; - rdtscll(intr0); + READ_TIMESTAMP(intr0); x = ext_do_call(func, &sp, flags, na, nk); - rdtscll(intr1); + READ_TIMESTAMP(intr1); stack_pointer = sp; Py_DECREF(func); @@ -2306,7 +2324,7 @@ on_error: - rdtscll(inst1); + READ_TIMESTAMP(inst1); /* Quickly continue if no error occurred */ @@ -2319,7 +2337,7 @@ "XXX undetected error\n"); else { #endif - rdtscll(loop1); + READ_TIMESTAMP(loop1); continue; /* Normal, fast path */ #ifdef CHECKEXC } @@ -2438,7 +2456,7 @@ if (why != WHY_NOT) break; - rdtscll(loop1); + READ_TIMESTAMP(loop1); } /* main loop */ @@ -2454,21 +2472,27 @@ fast_yield: if (tstate->use_tracing) { - if (tstate->c_tracefunc - && (why == WHY_RETURN || why == WHY_YIELD)) { - if (call_trace(tstate->c_tracefunc, - tstate->c_traceobj, f, - PyTrace_RETURN, retval)) { - Py_XDECREF(retval); - retval = NULL; - why = WHY_EXCEPTION; + if (tstate->c_tracefunc) { + if (why == WHY_RETURN || why == WHY_YIELD) { + if (call_trace(tstate->c_tracefunc, + tstate->c_traceobj, f, + PyTrace_RETURN, retval)) { + Py_XDECREF(retval); + retval = NULL; + why = WHY_EXCEPTION; + } + } + else if (why == WHY_EXCEPTION) { + call_trace_protected(tstate->c_tracefunc, + tstate->c_traceobj, f, + PyTrace_RETURN, NULL); } } if (tstate->c_profilefunc) { if (why == WHY_EXCEPTION) call_trace_protected(tstate->c_profilefunc, tstate->c_profileobj, f, - PyTrace_RETURN); + PyTrace_RETURN, NULL); else if (call_trace(tstate->c_profilefunc, tstate->c_profileobj, f, PyTrace_RETURN, retval)) { @@ -2491,7 +2515,7 @@ /* this is gonna seem *real weird*, but if you put some other code between PyEval_EvalFrame() and PyEval_EvalCodeEx() you will need to adjust - the test in the if statement in Misc/gdbinit:ppystack */ + the test in the if statement in Misc/gdbinit:pystack* */ PyObject * PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals, @@ -2716,7 +2740,7 @@ return PyGen_New(f); } - retval = PyEval_EvalFrame(f); + retval = PyEval_EvalFrameEx(f,0); fail: /* Jump here from prelude on failure */ @@ -3073,12 +3097,12 @@ static void call_trace_protected(Py_tracefunc func, PyObject *obj, PyFrameObject *frame, - int what) + int what, PyObject *arg) { PyObject *type, *value, *traceback; int err; PyErr_Fetch(&type, &value, &traceback); - err = call_trace(func, obj, frame, what, NULL); + err = call_trace(func, obj, frame, what, arg); if (err == 0) PyErr_Restore(type, value, traceback); else { @@ -3267,10 +3291,12 @@ Py_XINCREF(arg); tstate->c_profilefunc = NULL; tstate->c_profileobj = NULL; + /* Must make sure that tracing is not ignored if 'temp' is freed */ tstate->use_tracing = tstate->c_tracefunc != NULL; Py_XDECREF(temp); tstate->c_profilefunc = func; tstate->c_profileobj = arg; + /* Flag that tracing or profiling is turned on */ tstate->use_tracing = (func != NULL) || (tstate->c_tracefunc != NULL); } @@ -3282,10 +3308,12 @@ Py_XINCREF(arg); tstate->c_tracefunc = NULL; tstate->c_traceobj = NULL; + /* Must make sure that profiling is not ignored if 'temp' is freed */ tstate->use_tracing = tstate->c_profilefunc != NULL; Py_XDECREF(temp); tstate->c_tracefunc = func; tstate->c_traceobj = arg; + /* Flag that tracing or profiling is turned on */ tstate->use_tracing = ((func != NULL) || (tstate->c_profilefunc != NULL)); } @@ -3464,31 +3492,36 @@ nargs); } -#define C_TRACE(call) \ +#define C_TRACE(x, call) \ if (tstate->use_tracing && tstate->c_profilefunc) { \ if (call_trace(tstate->c_profilefunc, \ tstate->c_profileobj, \ tstate->frame, PyTrace_C_CALL, \ - func)) \ - { return NULL; } \ - call; \ - if (tstate->c_profilefunc != NULL) { \ - if (x == NULL) { \ - if (call_trace (tstate->c_profilefunc, \ - tstate->c_profileobj, \ - tstate->frame, PyTrace_C_EXCEPTION, \ - func)) \ - { return NULL; } \ - } else { \ - if (call_trace(tstate->c_profilefunc, \ - tstate->c_profileobj, \ - tstate->frame, PyTrace_C_RETURN, \ - func)) \ - { return NULL; } \ + func)) { \ + x = NULL; \ + } \ + else { \ + x = call; \ + if (tstate->c_profilefunc != NULL) { \ + if (x == NULL) { \ + call_trace_protected(tstate->c_profilefunc, \ + tstate->c_profileobj, \ + tstate->frame, PyTrace_C_EXCEPTION, \ + func); \ + /* XXX should pass (type, value, tb) */ \ + } else { \ + if (call_trace(tstate->c_profilefunc, \ + tstate->c_profileobj, \ + tstate->frame, PyTrace_C_RETURN, \ + func)) { \ + Py_DECREF(x); \ + x = NULL; \ + } \ + } \ } \ } \ } else { \ - call; \ + x = call; \ } static PyObject * @@ -3517,11 +3550,11 @@ PyCFunction meth = PyCFunction_GET_FUNCTION(func); PyObject *self = PyCFunction_GET_SELF(func); if (flags & METH_NOARGS && na == 0) { - C_TRACE(x=(*meth)(self,NULL)); + C_TRACE(x, (*meth)(self,NULL)); } else if (flags & METH_O && na == 1) { PyObject *arg = EXT_POP(*pp_stack); - C_TRACE(x=(*meth)(self,arg)); + C_TRACE(x, (*meth)(self,arg)); Py_DECREF(arg); } else { @@ -3532,9 +3565,9 @@ else { PyObject *callargs; callargs = load_args(pp_stack, na); - rdtscll(*pintr0); - C_TRACE(x=PyCFunction_Call(func,callargs,NULL)); - rdtscll(*pintr1); + READ_TIMESTAMP(*pintr0); + C_TRACE(x, PyCFunction_Call(func,callargs,NULL)); + READ_TIMESTAMP(*pintr1); Py_XDECREF(callargs); } } else { @@ -3552,12 +3585,12 @@ n++; } else Py_INCREF(func); - rdtscll(*pintr0); + READ_TIMESTAMP(*pintr0); if (PyFunction_Check(func)) x = fast_function(func, pp_stack, n, na, nk); else x = do_call(func, pp_stack, na, nk); - rdtscll(*pintr1); + READ_TIMESTAMP(*pintr1); Py_DECREF(func); } @@ -3615,7 +3648,7 @@ Py_INCREF(*stack); fastlocals[i] = *stack++; } - retval = PyEval_EvalFrame(f); + retval = PyEval_EvalFrameEx(f,0); assert(tstate != NULL); ++tstate->recursion_depth; Py_DECREF(f); Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.247.2.3 retrieving revision 2.247.2.4 diff -u -d -r2.247.2.3 -r2.247.2.4 --- compile.c 13 Apr 2005 19:44:38 -0000 2.247.2.3 +++ compile.c 16 Oct 2005 05:24:05 -0000 2.247.2.4 @@ -325,6 +325,598 @@ return 0; } +/* Begin: Peephole optimizations ----------------------------------------- */ + +#define GETARG(arr, i) ((int)((arr[i+2]<<8) + arr[i+1])) +#define UNCONDITIONAL_JUMP(op) (op==JUMP_ABSOLUTE || op==JUMP_FORWARD) +#define ABSOLUTE_JUMP(op) (op==JUMP_ABSOLUTE || op==CONTINUE_LOOP) +#define GETJUMPTGT(arr, i) (GETARG(arr,i) + (ABSOLUTE_JUMP(arr[i]) ? 0 : i+3)) +#define SETARG(arr, i, val) arr[i+2] = val>>8; arr[i+1] = val & 255 +#define CODESIZE(op) (HAS_ARG(op) ? 3 : 1) +#define ISBASICBLOCK(blocks, start, bytes) (blocks[start]==blocks[start+bytes-1]) + +/* Replace LOAD_CONST c1. LOAD_CONST c2 ... LOAD_CONST cn BUILD_TUPLE n + with LOAD_CONST (c1, c2, ... cn). + The consts table must still be in list form so that the + new constant (c1, c2, ... cn) can be appended. + Called with codestr pointing to the first LOAD_CONST. + Bails out with no change if one or more of the LOAD_CONSTs is missing. + Also works for BUILD_LIST when followed by an "in" or "not in" test. +*/ +static int +tuple_of_constants(unsigned char *codestr, int n, PyObject *consts) +{ + PyObject *newconst, *constant; + int i, arg, len_consts; + + /* Pre-conditions */ + assert(PyList_CheckExact(consts)); + assert(codestr[n*3] == BUILD_TUPLE || codestr[n*3] == BUILD_LIST); + assert(GETARG(codestr, (n*3)) == n); + for (i=0 ; i 20) { + Py_DECREF(newconst); + return 0; + } + + /* Append folded constant into consts table */ + len_consts = PyList_GET_SIZE(consts); + if (PyList_Append(consts, newconst)) { + Py_DECREF(newconst); + return 0; + } + Py_DECREF(newconst); + + /* Write NOP NOP NOP NOP LOAD_CONST newconst */ + memset(codestr, NOP, 4); + codestr[4] = LOAD_CONST; + SETARG(codestr, 4, len_consts); + return 1; +} + +static int +fold_unaryops_on_constants(unsigned char *codestr, PyObject *consts) +{ + PyObject *newconst=NULL, *v; + int len_consts, opcode; + + /* Pre-conditions */ + assert(PyList_CheckExact(consts)); + assert(codestr[0] == LOAD_CONST); + + /* Create new constant */ + v = PyList_GET_ITEM(consts, GETARG(codestr, 0)); + opcode = codestr[3]; + switch (opcode) { + case UNARY_NEGATIVE: + /* Preserve the sign of -0.0 */ + if (PyObject_IsTrue(v) == 1) + newconst = PyNumber_Negative(v); + break; + case UNARY_CONVERT: + newconst = PyObject_Repr(v); + break; + case UNARY_INVERT: + newconst = PyNumber_Invert(v); + break; + default: + /* Called with an unknown opcode */ + assert(0); + return 0; + } + if (newconst == NULL) { + PyErr_Clear(); + return 0; + } + + /* Append folded constant into consts table */ + len_consts = PyList_GET_SIZE(consts); + if (PyList_Append(consts, newconst)) { + Py_DECREF(newconst); + return 0; + } + Py_DECREF(newconst); + + /* Write NOP LOAD_CONST newconst */ + codestr[0] = NOP; + codestr[1] = LOAD_CONST; + SETARG(codestr, 1, len_consts); + return 1; +} + +static unsigned int * +markblocks(unsigned char *code, int len) +{ + unsigned int *blocks = PyMem_Malloc(len*sizeof(int)); + int i,j, opcode, blockcnt = 0; + + if (blocks == NULL) + return NULL; + memset(blocks, 0, len*sizeof(int)); + + /* Mark labels in the first pass */ + for (i=0 ; i= 255. + + Optimizations are restricted to simple transformations occuring within a + single basic block. All transformations keep the code size the same or + smaller. For those that reduce size, the gaps are initially filled with + NOPs. Later those NOPs are removed and the jump addresses retargeted in + a single pass. Line numbering is adjusted accordingly. */ + +static PyObject * +optimize_code(PyObject *code, PyObject* consts, PyObject *names, PyObject *lineno_obj) +{ + int i, j, codelen, nops, h, adj; + int tgt, tgttgt, opcode; + unsigned char *codestr = NULL; + unsigned char *lineno; + int *addrmap = NULL; + int new_line, cum_orig_line, last_line, tabsiz; + int cumlc=0, lastlc=0; /* Count runs of consecutive LOAD_CONST codes */ + unsigned int *blocks = NULL; + char *name; + + /* Bail out if an exception is set */ + if (PyErr_Occurred()) + 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); + if (memchr(lineno, 255, tabsiz) != NULL) + goto exitUnchanged; + + /* Avoid situations where jump retargeting could overflow */ + assert(PyString_Check(code)); + codelen = PyString_Size(code); + if (codelen > 32700) + goto exitUnchanged; + + /* Make a modifiable copy of the code string */ + codestr = PyMem_Malloc(codelen); + if (codestr == NULL) + goto exitUnchanged; + codestr = memcpy(codestr, PyString_AS_STRING(code), codelen); + + /* Verify that RETURN_VALUE terminates the codestring. This allows + the various transformation patterns to look ahead several + instructions without additional checks to make sure they are not + looking beyond the end of the code string. + */ + if (codestr[codelen-1] != RETURN_VALUE) + goto exitUnchanged; + + /* Mapping to new jump targets after NOPs are removed */ + addrmap = PyMem_Malloc(codelen * sizeof(int)); + if (addrmap == NULL) + goto exitUnchanged; + + blocks = markblocks(codestr, codelen); + if (blocks == NULL) + goto exitUnchanged; + assert(PyList_Check(consts)); + + for (i=0 ; i a is not b + not a in b --> a not in b + not a is not b --> a is b + not a not in b --> a in b + */ + case COMPARE_OP: + j = GETARG(codestr, i); + if (j < 6 || j > 9 || + codestr[i+3] != UNARY_NOT || + !ISBASICBLOCK(blocks,i,4)) + continue; + SETARG(codestr, i, (j^1)); + codestr[i+3] = NOP; + break; + + /* Replace LOAD_GLOBAL/LOAD_NAME None with LOAD_CONST None */ + case LOAD_NAME: + case LOAD_GLOBAL: + j = GETARG(codestr, i); + name = PyString_AsString(PyTuple_GET_ITEM(names, j)); + if (name == NULL || strcmp(name, "None") != 0) + continue; + for (j=0 ; j < PyList_GET_SIZE(consts) ; j++) { + if (PyList_GET_ITEM(consts, j) == Py_None) { + codestr[i] = LOAD_CONST; + SETARG(codestr, i, j); + cumlc = lastlc + 1; + break; + } + } + break; + + /* Skip over LOAD_CONST trueconst JUMP_IF_FALSE xx POP_TOP */ + case LOAD_CONST: + cumlc = lastlc + 1; + j = GETARG(codestr, i); + if (codestr[i+3] != JUMP_IF_FALSE || + codestr[i+6] != POP_TOP || + !ISBASICBLOCK(blocks,i,7) || + !PyObject_IsTrue(PyList_GET_ITEM(consts, j))) + continue; + memset(codestr+i, NOP, 7); + cumlc = 0; + break; + + /* Try to fold tuples of constants (includes a case for lists + which are only used for "in" and "not in" tests). + Skip over BUILD_SEQN 1 UNPACK_SEQN 1. + Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2. + Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */ + case BUILD_TUPLE: + case BUILD_LIST: + j = GETARG(codestr, i); + h = i - 3 * j; + if (h >= 0 && + j <= lastlc && + ((opcode == BUILD_TUPLE && + ISBASICBLOCK(blocks, h, 3*(j+1))) || + (opcode == BUILD_LIST && + codestr[i+3]==COMPARE_OP && + ISBASICBLOCK(blocks, h, 3*(j+2)) && + (GETARG(codestr,i+3)==6 || + GETARG(codestr,i+3)==7))) && + tuple_of_constants(&codestr[h], j, consts)) { + assert(codestr[i] == LOAD_CONST); + cumlc = 1; + break; + } + if (codestr[i+3] != UNPACK_SEQUENCE || + !ISBASICBLOCK(blocks,i,6) || + j != GETARG(codestr, i+3)) + continue; + if (j == 1) { + memset(codestr+i, NOP, 6); + } else if (j == 2) { + codestr[i] = ROT_TWO; + memset(codestr+i+1, NOP, 5); + } else if (j == 3) { + codestr[i] = ROT_THREE; + codestr[i+1] = ROT_TWO; + memset(codestr+i+2, NOP, 4); + } + break; + + /* Fold binary ops on constants. + LOAD_CONST c1 LOAD_CONST c2 BINOP --> LOAD_CONST binop(c1,c2) */ + case BINARY_POWER: + case BINARY_MULTIPLY: + case BINARY_TRUE_DIVIDE: + case BINARY_FLOOR_DIVIDE: + case BINARY_MODULO: + case BINARY_ADD: + case BINARY_SUBTRACT: + case BINARY_SUBSCR: + case BINARY_LSHIFT: + case BINARY_RSHIFT: + case BINARY_AND: + case BINARY_XOR: + case BINARY_OR: + if (lastlc >= 2 && + ISBASICBLOCK(blocks, i-6, 7) && + fold_binops_on_constants(&codestr[i-6], consts)) { + i -= 2; + assert(codestr[i] == LOAD_CONST); + cumlc = 1; + } + break; + + /* Fold unary ops on constants. + LOAD_CONST c1 UNARY_OP --> LOAD_CONST unary_op(c) */ + case UNARY_NEGATIVE: + case UNARY_CONVERT: + case UNARY_INVERT: + if (lastlc >= 1 && + ISBASICBLOCK(blocks, i-3, 4) && + fold_unaryops_on_constants(&codestr[i-3], consts)) { + i -= 2; + assert(codestr[i] == LOAD_CONST); + cumlc = 1; + } + break; + + /* Simplify conditional jump to conditional jump where the + result of the first test implies the success of a similar + test or the failure of the opposite test. + Arises in code like: + "if a and b:" + "if a or b:" + "a and b or c" + "(a and b) and c" + x:JUMP_IF_FALSE y y:JUMP_IF_FALSE z --> x:JUMP_IF_FALSE z + x:JUMP_IF_FALSE y y:JUMP_IF_TRUE z --> x:JUMP_IF_FALSE y+3 + where y+3 is the instruction following the second test. + */ + case JUMP_IF_FALSE: + case JUMP_IF_TRUE: + tgt = GETJUMPTGT(codestr, i); + j = codestr[tgt]; + if (j == JUMP_IF_FALSE || j == JUMP_IF_TRUE) { + if (j == opcode) { + tgttgt = GETJUMPTGT(codestr, tgt) - i - 3; + SETARG(codestr, i, tgttgt); + } else { + tgt -= i; + SETARG(codestr, i, tgt); + } + break; + } + /* Intentional fallthrough */ + + /* Replace jumps to unconditional jumps */ + case FOR_ITER: + case JUMP_FORWARD: + case JUMP_ABSOLUTE: + case CONTINUE_LOOP: + case SETUP_LOOP: + case SETUP_EXCEPT: + case SETUP_FINALLY: + tgt = GETJUMPTGT(codestr, i); + if (!UNCONDITIONAL_JUMP(codestr[tgt])) + continue; + tgttgt = GETJUMPTGT(codestr, tgt); + if (opcode == JUMP_FORWARD) /* JMP_ABS can go backwards */ + opcode = JUMP_ABSOLUTE; + if (!ABSOLUTE_JUMP(opcode)) + tgttgt -= i + 3; /* Calc relative jump addr */ + if (tgttgt < 0) /* No backward relative jumps */ + continue; + codestr[i] = opcode; + SETARG(codestr, i, tgttgt); + break; + + case EXTENDED_ARG: + goto exitUnchanged; + + /* Replace RETURN LOAD_CONST None RETURN with just RETURN */ + case RETURN_VALUE: + if (i+4 >= codelen || + codestr[i+4] != RETURN_VALUE || + !ISBASICBLOCK(blocks,i,5)) + continue; + memset(codestr+i+1, NOP, 4); + break; + } + } + + /* Fixup linenotab */ + for (i=0, nops=0 ; ic_begin; + + REQ(n, gen_for); + /* gen_for: for v in test [gen_iter] */ + + com_addfwref(c, SETUP_LOOP, &break_anchor); + block_push(c, SETUP_LOOP); + + if (is_outmost) { + com_addop_varname(c, VAR_LOAD, "[outmost-iterable]"); + com_push(c, 1); + } + else { + com_node(c, CHILD(n, 3)); + com_addbyte(c, GET_ITER); + } + + c->c_begin = c->c_nexti; + com_set_lineno(c, c->c_last_line); + com_addfwref(c, FOR_ITER, &anchor); + com_push(c, 1); + com_assign(c, CHILD(n, 1), OP_ASSIGN, NULL); + + if (NCH(n) == 5) + com_gen_iter(c, CHILD(n, 4), t); + else { + com_test(c, t); + com_addbyte(c, YIELD_VALUE); + com_addbyte(c, POP_TOP); + com_pop(c, 1); + } + + com_addoparg(c, JUMP_ABSOLUTE, c->c_begin); + c->c_begin = save_begin; + + com_backpatch(c, anchor); + com_pop(c, 1); /* FOR_ITER has popped this */ + com_addbyte(c, POP_BLOCK); + block_pop(c, SETUP_LOOP); + com_backpatch(c, break_anchor); +} + +static void com_list_if(struct compiling *c, node *n, node *e, char *t) { int anchor = 0; @@ -1413,6 +2052,33 @@ } static void +com_gen_if(struct compiling *c, node *n, node *t) +{ + /* gen_if: 'if' test [gen_iter] */ + int anchor = 0; + int a=0; + + com_node(c, CHILD(n, 1)); + com_addfwref(c, JUMP_IF_FALSE, &a); + com_addbyte(c, POP_TOP); + com_pop(c, 1); + + if (NCH(n) == 3) + com_gen_iter(c, CHILD(n, 2), t); + else { + com_test(c, t); + com_addbyte(c, YIELD_VALUE); + com_addbyte(c, POP_TOP); + com_pop(c, 1); + } + com_addfwref(c, JUMP_FORWARD, &anchor); + com_backpatch(c, a); + /* We jump here with an extra entry which we now pop */ + com_addbyte(c, POP_TOP); + com_backpatch(c, anchor); +} + +static void com_list_iter(struct compiling *c, node *p, /* parent of list_iter node */ node *e, /* element expression node */ @@ -1495,6 +2161,10 @@ } } + +/* forward reference */ +static void com_yield_expr(struct compiling *c, node *n); + static void com_atom(struct compiling *c, node *n) { @@ -1510,7 +2180,10 @@ com_push(c, 1); } else - com_node(c, CHILD(n, 1)); + if (TYPE(CHILD(n, 1)) == yield_expr) + com_yield_expr(c, CHILD(n, 1)); + else + com_testlist_gexp(c, CHILD(n, 1)); break; case LSQB: /* '[' [listmaker] ']' */ if (TYPE(CHILD(n, 1)) == RSQB) { @@ -2562,7 +3235,11 @@ } n = CHILD(n, 0); break; - + case yield_expr: + com_error(c, PyExc_SyntaxError, + "assignment to yield expression not possible"); + return; + case test: case and_test: case not_test: @@ -2619,7 +3296,7 @@ } if (assigning > OP_APPLY) { com_error(c, PyExc_SyntaxError, - "augmented assign to tuple not possible"); + "augmented assign to tuple literal, yield, or generator expression not possible"); return; } break; @@ -2855,27 +3532,41 @@ } static void -com_yield_stmt(struct compiling *c, node *n) +com_yield_expr(struct compiling *c, node *n) { - int i; - REQ(n, yield_stmt); /* 'yield' testlist */ + REQ(n, yield_expr); /* 'yield' testlist */ if (!c->c_infunction) { com_error(c, PyExc_SyntaxError, "'yield' outside function"); } - for (i = 0; i < c->c_nblocks; ++i) { + /* for (i = 0; i < c->c_nblocks; ++i) { if (c->c_block[i] == SETUP_FINALLY) { com_error(c, PyExc_SyntaxError, "'yield' not allowed in a 'try' block " "with a 'finally' clause"); return; } + } */ + + if (NCH(n) < 2) { + com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None)); + com_push(c, 1); } - com_node(c, CHILD(n, 1)); + else + com_node(c, CHILD(n, 1)); com_addbyte(c, YIELD_VALUE); +} + +static void +com_yield_stmt(struct compiling *c, node *n) +{ + REQ(n, yield_stmt); /* yield_expr */ + com_node(c, CHILD(n, 0)); + com_addbyte(c, POP_TOP); com_pop(c, 1); } + static void com_raise_stmt(struct compiling *c, node *n) { @@ -3639,7 +4330,7 @@ char *name; REQ(n, classdef); - /* classdef: class NAME ['(' testlist ')'] ':' suite */ + /* classdef: class NAME ['(' [testlist] ')'] ':' suite */ if ((v = PyString_InternFromString(STR(CHILD(n, 1)))) == NULL) { c->c_errors++; return; @@ -3650,7 +4341,8 @@ com_push(c, 1); Py_DECREF(v); /* Push the tuple of base classes on the stack */ - if (TYPE(CHILD(n, 2)) != LPAR) { + if (TYPE(CHILD(n, 2)) != LPAR || + TYPE(CHILD(n, 3)) == RPAR) { com_addoparg(c, BUILD_TUPLE, 0); com_push(c, 1); } @@ -3782,6 +4474,10 @@ /* Expression nodes */ + case yield_expr: + com_yield_expr(c, n); + break; + case testlist: case testlist1: case testlist_safe: @@ -4029,6 +4725,25 @@ } static void +compile_generator_expression(struct compiling *c, node *n) +{ + /* testlist_gexp: test gen_for */ + /* argument: test gen_for */ + REQ(CHILD(n, 0), test); + REQ(CHILD(n, 1), gen_for); + + c->c_name = ""; + c->c_infunction = 1; + com_gen_for(c, CHILD(n, 1), CHILD(n, 0), 1); + c->c_infunction = 0; + + com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None)); + com_push(c, 1); + com_addbyte(c, RETURN_VALUE); + com_pop(c, 1); +} + +static void compile_node(struct compiling *c, node *n) { com_addoparg(c, SET_LINENO, n->n_lineno); @@ -4979,7 +5694,7 @@ #define symtable_add_use(ST, NAME) symtable_add_def((ST), (NAME), USE) -/* Look for a yield stmt under n. Return 1 if found, else 0. +/* Look for a yield stmt or expr under n. Return 1 if found, else 0. This hack is used to look inside "if 0:" blocks (which are normally ignored) in case those are the only places a yield occurs (so that this function is a generator). */ @@ -5001,7 +5716,8 @@ return 0; case yield_stmt: - return 1; + case yield_expr: + return GENERATOR; default: if (look_for_yield(kid)) @@ -5108,8 +5824,10 @@ case del_stmt: symtable_assign(st, CHILD(n, 1), 0); break; - case yield_stmt: + case yield_expr: st->st_cur->ste_generator = 1; + if (NCH(n)==1) + break; n = CHILD(n, 1); goto loop; case expr_stmt: @@ -5170,9 +5888,15 @@ } /* fall through */ case atom: - if (TYPE(n) == atom && TYPE(CHILD(n, 0)) == NAME) { - symtable_add_use(st, STR(CHILD(n, 0))); - break; + if (TYPE(n) == atom) { + if (TYPE(CHILD(n, 0)) == NAME) { + symtable_add_use(st, STR(CHILD(n, 0))); + break; + } + else if (TYPE(CHILD(n,0)) == LPAR) { + n = CHILD(n,1); + goto loop; + } } /* fall through */ default: @@ -5492,6 +6216,15 @@ symtable_add_def(st, STR(tmp), DEF_LOCAL | def_flag); } return; + + case yield_expr: + st->st_cur->ste_generator = 1; + if (NCH(n)==2) { + n = CHILD(n, 1); + goto loop; + } + return; + case dotted_as_name: if (NCH(n) == 3) symtable_add_def(st, STR(CHILD(n, 2)), Index: errors.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/errors.c,v retrieving revision 2.70.2.3 retrieving revision 2.70.2.4 diff -u -d -r2.70.2.3 -r2.70.2.4 --- errors.c 7 Jan 2005 07:04:38 -0000 2.70.2.3 +++ errors.c 16 Oct 2005 05:24:05 -0000 2.70.2.4 @@ -535,10 +535,6 @@ } if (base == NULL) base = PyExc_Exception; - if (!PyClass_Check(base)) { - /* Must be using string-based standard exceptions (-X) */ - return PyString_FromString(name); - } if (dict == NULL) { dict = mydict = PyDict_New(); if (dict == NULL) Index: exceptions.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/exceptions.c,v retrieving revision 1.32.2.2 retrieving revision 1.32.2.3 diff -u -d -r1.32.2.2 -r1.32.2.3 --- exceptions.c 7 Jan 2005 07:04:38 -0000 1.32.2.2 +++ exceptions.c 16 Oct 2005 05:24:05 -0000 1.32.2.3 @@ -57,6 +57,7 @@ |\n\ +-- SystemExit\n\ +-- StopIteration\n\ + +-- GeneratorExit\n\ +-- StandardError\n\ | |\n\ | +-- KeyboardInterrupt\n\ @@ -394,6 +395,7 @@ PyDoc_STRVAR(TypeError__doc__, "Inappropriate argument type."); PyDoc_STRVAR(StopIteration__doc__, "Signal the end from iterator.next()."); +PyDoc_STRVAR(GeneratorExit__doc__, "Request that a generator exit."); @@ -1583,6 +1585,7 @@ PyObject *PyExc_Exception; PyObject *PyExc_StopIteration; +PyObject *PyExc_GeneratorExit; PyObject *PyExc_StandardError; PyObject *PyExc_ArithmeticError; PyObject *PyExc_LookupError; @@ -1657,6 +1660,8 @@ {"Exception", &PyExc_Exception}, {"StopIteration", &PyExc_StopIteration, &PyExc_Exception, StopIteration__doc__}, + {"GeneratorExit", &PyExc_GeneratorExit, &PyExc_Exception, + GeneratorExit__doc__}, {"StandardError", &PyExc_StandardError, &PyExc_Exception, StandardError__doc__}, {"TypeError", &PyExc_TypeError, 0, TypeError__doc__}, Index: future.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/future.c,v retrieving revision 2.12.2.7 retrieving revision 2.12.2.8 diff -u -d -r2.12.2.7 -r2.12.2.8 --- future.c 21 Apr 2004 14:41:49 -0000 2.12.2.7 +++ future.c 16 Oct 2005 05:24:05 -0000 2.12.2.8 @@ -130,4 +130,3 @@ } return ff; } - Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.92.2.2 retrieving revision 2.92.2.3 diff -u -d -r2.92.2.2 -r2.92.2.3 --- getargs.c 7 Jan 2005 07:04:39 -0000 2.92.2.2 +++ getargs.c 16 Oct 2005 05:24:05 -0000 2.92.2.3 @@ -453,7 +453,9 @@ or a string with a message describing the failure. The message is formatted as "must be , not ". When failing, an exception may or may not have been raised. - Don't call if a tuple is expected. + Don't call if a tuple is expected. + + When you add new format codes, please don't forget poor skipitem() below. */ static char * @@ -1299,7 +1301,8 @@ /* make sure we got an acceptable number of arguments; the message is a little confusing with keywords since keyword arguments which are supplied, but don't match the required arguments - are not included in the "%d given" part of the message */ + are not included in the "%d given" part of the message + XXX and this isn't a bug!? */ if (len < min || max < len) { if (message == NULL) { PyOS_snprintf(msgbuf, sizeof(msgbuf), @@ -1405,83 +1408,52 @@ char c = *format++; switch (c) { - + + /* simple codes + * The individual types (second arg of va_arg) are irrelevant */ + case 'b': /* byte -- very short int */ case 'B': /* byte as bitfield */ - { - (void) va_arg(*p_va, char *); - break; - } - case 'h': /* short int */ - { - (void) va_arg(*p_va, short *); - break; - } - case 'H': /* short int as bitfield */ - { - (void) va_arg(*p_va, unsigned short *); - break; - } - case 'i': /* int */ - { - (void) va_arg(*p_va, int *); - break; - } - + case 'I': /* int sized bitfield */ case 'l': /* long int */ - { - (void) va_arg(*p_va, long *); - break; - } - + case 'k': /* long int sized bitfield */ #ifdef HAVE_LONG_LONG - case 'L': /* PY_LONG_LONG int */ - { - (void) va_arg(*p_va, PY_LONG_LONG *); - break; - } + case 'L': /* PY_LONG_LONG */ + case 'K': /* PY_LONG_LONG sized bitfield */ #endif - case 'f': /* float */ - { - (void) va_arg(*p_va, float *); - break; - } - case 'd': /* double */ - { - (void) va_arg(*p_va, double *); - break; - } - #ifndef WITHOUT_COMPLEX case 'D': /* complex double */ - { - (void) va_arg(*p_va, Py_complex *); - break; - } -#endif /* WITHOUT_COMPLEX */ - +#endif case 'c': /* char */ { - (void) va_arg(*p_va, char *); + (void) va_arg(*p_va, void *); break; } - case 's': /* string */ + /* string codes */ + + case 'e': /* string with encoding */ { - (void) va_arg(*p_va, char **); - if (*format == '#') { - (void) va_arg(*p_va, int *); - format++; - } - break; + (void) va_arg(*p_va, const char *); + if (!(*format == 's' || *format == 't')) + /* after 'e', only 's' and 't' is allowed */ + goto err; + format++; + /* explicit fallthrough to string cases */ } - case 'z': /* string */ + case 's': /* string */ + case 'z': /* string or None */ +#ifdef Py_USING_UNICODE + case 'u': /* unicode string */ +#endif + case 't': /* buffer, read-only */ + case 'w': /* buffer, read-write */ { (void) va_arg(*p_va, char **); if (*format == '#') { @@ -1490,8 +1462,13 @@ } break; } - + + /* object codes */ + case 'S': /* string object */ +#ifdef Py_USING_UNICODE + case 'U': /* unicode string object */ +#endif { (void) va_arg(*p_va, PyObject **); break; @@ -1527,9 +1504,13 @@ } default: +err: return "impossible"; } + + /* The "(...)" format code for tuples is not handled here because + * it is not allowed with keyword args. */ *p_format = format; return NULL; @@ -1594,3 +1575,29 @@ va_end(vargs); return 1; } + + +/* For type constructors that don't take keyword args + * + * Sets a TypeError and returns 0 if the kwds dict is + * not emtpy, returns 1 otherwise + */ +int +_PyArg_NoKeywords(char *funcname, PyObject *kw) +{ + if (kw == NULL) + return 1; + if (!PyDict_CheckExact(kw)) { + PyErr_BadInternalCall(); + return 0; + } + if (PyDict_Size(kw) == 0) + return 1; + + PyErr_Format(PyExc_TypeError, "%s does not take keyword arguments", + funcname); + return 0; +} + + + Index: getcopyright.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getcopyright.c,v retrieving revision 1.16.2.2 retrieving revision 1.16.2.3 diff -u -d -r1.16.2.2 -r1.16.2.3 --- getcopyright.c 7 Jan 2005 07:04:39 -0000 1.16.2.2 +++ getcopyright.c 16 Oct 2005 05:24:05 -0000 1.16.2.3 @@ -4,7 +4,7 @@ static char cprt[] = "\ -Copyright (c) 2001-2004 Python Software Foundation.\n\ +Copyright (c) 2001-2005 Python Software Foundation.\n\ All Rights Reserved.\n\ \n\ Copyright (c) 2000 BeOpen.com.\n\ Index: graminit.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/graminit.c,v retrieving revision 2.33.2.3 retrieving revision 2.33.2.4 diff -u -d -r2.33.2.3 -r2.33.2.4 --- graminit.c 15 Apr 2005 02:18:23 -0000 2.33.2.3 +++ graminit.c 16 Oct 2005 05:24:05 -0000 2.33.2.4 @@ -279,10 +279,12 @@ {25, 3}, {0, 1}, }; -static arc arcs_13_2[1] = { +static arc arcs_13_2[2] = { + {43, 4}, {9, 4}, }; -static arc arcs_13_3[1] = { +static arc arcs_13_3[2] = { + {43, 5}, {9, 5}, }; static arc arcs_13_4[1] = { @@ -295,13 +297,12 @@ static state states_13[6] = { {1, arcs_13_0}, {3, arcs_13_1}, - {1, arcs_13_2}, - {1, arcs_13_3}, + {2, arcs_13_2}, + {2, arcs_13_3}, {1, arcs_13_4}, {2, arcs_13_5}, }; static arc arcs_14_0[12] = { - {43, 1}, {44, 1}, {45, 1}, {46, 1}, @@ -313,6 +314,7 @@ {52, 1}, {53, 1}, {54, 1}, + {55, 1}, }; static arc arcs_14_1[1] = { {0, 1}, @@ -322,11 +324,11 @@ {1, arcs_14_1}, }; static arc arcs_15_0[1] = { - {55, 1}, + {56, 1}, }; static arc arcs_15_1[3] = { {26, 2}, - {56, 3}, + {57, 3}, {0, 1}, }; static arc arcs_15_2[2] = { @@ -367,10 +369,10 @@ {2, arcs_15_8}, }; static arc arcs_16_0[1] = { - {57, 1}, + {58, 1}, }; static arc arcs_16_1[1] = { - {58, 2}, + {59, 2}, }; static arc arcs_16_2[1] = { {0, 2}, @@ -381,7 +383,7 @@ {1, arcs_16_2}, }; static arc arcs_17_0[1] = { - {59, 1}, + {60, 1}, }; static arc arcs_17_1[1] = { {0, 1}, @@ -391,11 +393,11 @@ {1, arcs_17_1}, }; static arc arcs_18_0[5] = { - {60, 1}, {61, 1}, {62, 1}, {63, 1}, {64, 1}, + {65, 1}, }; static arc arcs_18_1[1] = { {0, 1}, @@ -405,7 +407,7 @@ {1, arcs_18_1}, }; static arc arcs_19_0[1] = { - {65, 1}, + {66, 1}, }; static arc arcs_19_1[1] = { {0, 1}, @@ -415,7 +417,7 @@ {1, arcs_19_1}, }; static arc arcs_20_0[1] = { - {66, 1}, + {67, 1}, }; static arc arcs_20_1[1] = { {0, 1}, @@ -425,7 +427,7 @@ {1, arcs_20_1}, }; static arc arcs_21_0[1] = { - {67, 1}, + {68, 1}, }; static arc arcs_21_1[2] = { {9, 2}, @@ -440,18 +442,14 @@ {1, arcs_21_2}, }; static arc arcs_22_0[1] = { - {68, 1}, + {43, 1}, }; static arc arcs_22_1[1] = { - {9, 2}, -}; -static arc arcs_22_2[1] = { - {0, 2}, + {0, 1}, }; -static state states_22[3] = { +static state states_22[2] = { {1, arcs_22_0}, {1, arcs_22_1}, - {1, arcs_22_2}, }; static arc arcs_23_0[1] = { {69, 1}, @@ -779,7 +777,7 @@ {93, 1}, }; static arc arcs_38_1[1] = { - {58, 2}, + {59, 2}, }; static arc arcs_38_2[1] = { {82, 3}, @@ -1034,7 +1032,7 @@ }; static arc arcs_50_1[3] = { {123, 0}, - {56, 0}, + {57, 0}, {0, 1}, }; static state states_50[2] = { @@ -1113,7 +1111,8 @@ {144, 5}, {145, 6}, }; -static arc arcs_55_1[2] = { +static arc arcs_55_1[3] = { + {43, 7}, {135, 7}, {15, 5}, }; @@ -1149,7 +1148,7 @@ }; static state states_55[11] = { {7, arcs_55_0}, - {2, arcs_55_1}, + {3, arcs_55_1}, {2, arcs_55_2}, {2, arcs_55_3}, {1, arcs_55_4}, @@ -1533,7 +1532,7 @@ {93, 1}, }; static arc arcs_71_1[1] = { - {58, 2}, + {59, 2}, }; static arc arcs_71_2[1] = { {82, 3}, @@ -1590,7 +1589,7 @@ {93, 1}, }; static arc arcs_74_1[1] = { - {58, 2}, + {59, 2}, }; static arc arcs_74_2[1] = { {82, 3}, @@ -1653,165 +1652,182 @@ {1, arcs_77_0}, {1, arcs_77_1}, }; -static dfa dfas[78] = { +static arc arcs_78_0[1] = { + {160, 1}, +}; +static arc arcs_78_1[2] = { + {9, 2}, + {0, 1}, +}; +static arc arcs_78_2[1] = { + {0, 2}, +}; +static state states_78[3] = { + {1, arcs_78_0}, + {2, arcs_78_1}, + {1, arcs_78_2}, +}; +static dfa dfas[79] = { {256, "single_input", 0, 3, states_0, - "\004\050\014\000\000\000\200\012\076\205\011\162\000\002\000\140\010\111\023\002"}, + "\004\050\014\000\000\000\000\025\074\205\011\162\000\002\000\140\010\111\023\002\001"}, {257, "file_input", 0, 2, states_1, - "\204\050\014\000\000\000\200\012\076\205\011\162\000\002\000\140\010\111\023\002"}, + "\204\050\014\000\000\000\000\025\074\205\011\162\000\002\000\140\010\111\023\002\001"}, {258, "eval_input", 0, 3, states_2, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000\000"}, {259, "decorator", 0, 7, states_3, - "\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {260, "decorators", 0, 2, states_4, - "\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {261, "funcdef", 0, 7, states_5, - "\000\010\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\010\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {262, "parameters", 0, 4, states_6, - "\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {263, "varargslist", 0, 10, states_7, - "\000\040\010\060\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\040\010\060\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {264, "fpdef", 0, 4, states_8, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {265, "fplist", 0, 3, states_9, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {266, "stmt", 0, 2, states_10, - "\000\050\014\000\000\000\200\012\076\205\011\162\000\002\000\140\010\111\023\002"}, + "\000\050\014\000\000\000\000\025\074\205\011\162\000\002\000\140\010\111\023\002\001"}, {267, "simple_stmt", 0, 4, states_11, - "\000\040\010\000\000\000\200\012\076\205\011\000\000\002\000\140\010\111\023\000"}, + "\000\040\010\000\000\000\000\025\074\205\011\000\000\002\000\140\010\111\023\000\001"}, {268, "small_stmt", 0, 2, states_12, - "\000\040\010\000\000\000\200\012\076\205\011\000\000\002\000\140\010\111\023\000"}, + "\000\040\010\000\000\000\000\025\074\205\011\000\000\002\000\140\010\111\023\000\001"}, {269, "expr_stmt", 0, 6, states_13, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000\000"}, {270, "augassign", 0, 2, states_14, - "\000\000\000\000\000\370\177\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\360\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {271, "print_stmt", 0, 9, states_15, - "\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {272, "del_stmt", 0, 3, states_16, - "\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {273, "pass_stmt", 0, 2, states_17, - "\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {274, "flow_stmt", 0, 2, states_18, - "\000\000\000\000\000\000\000\000\076\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\074\000\000\000\000\000\000\000\000\000\000\000\001"}, {275, "break_stmt", 0, 2, states_19, - "\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000"}, {276, "continue_stmt", 0, 2, states_20, - "\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000"}, {277, "return_stmt", 0, 3, states_21, - "\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000"}, - {278, "yield_stmt", 0, 3, states_22, - "\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000"}, + {278, "yield_stmt", 0, 2, states_22, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001"}, {279, "raise_stmt", 0, 7, states_23, - "\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000"}, {280, "import_stmt", 0, 2, states_24, - "\000\000\000\000\000\000\000\000\000\005\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\005\000\000\000\000\000\000\000\000\000\000\000"}, {281, "import_name", 0, 3, states_25, - "\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000"}, {282, "import_from", 0, 7, states_26, - "\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000"}, {283, "import_as_name", 0, 4, states_27, - "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {284, "dotted_as_name", 0, 4, states_28, - "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {285, "import_as_names", 0, 3, states_29, - "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {286, "dotted_as_names", 0, 2, states_30, - "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {287, "dotted_name", 0, 2, states_31, - "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {288, "global_stmt", 0, 3, states_32, - "\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000"}, {289, "exec_stmt", 0, 7, states_33, - "\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000"}, {290, "assert_stmt", 0, 5, states_34, - "\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000\000"}, {291, "compound_stmt", 0, 2, states_35, - "\000\010\004\000\000\000\000\000\000\000\000\162\000\000\000\000\000\000\000\002"}, + "\000\010\004\000\000\000\000\000\000\000\000\162\000\000\000\000\000\000\000\002\000"}, {292, "if_stmt", 0, 8, states_36, - "\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000"}, {293, "while_stmt", 0, 8, states_37, - "\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000"}, {294, "for_stmt", 0, 10, states_38, - "\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000"}, {295, "try_stmt", 0, 10, states_39, - "\000\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000"}, {296, "except_clause", 0, 5, states_40, - "\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000"}, {297, "suite", 0, 5, states_41, - "\004\040\010\000\000\000\200\012\076\205\011\000\000\002\000\140\010\111\023\000"}, + "\004\040\010\000\000\000\000\025\074\205\011\000\000\002\000\140\010\111\023\000\001"}, {298, "test", 0, 4, states_42, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000\000"}, {299, "and_test", 0, 2, states_43, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\003\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\003\000\000"}, {300, "not_test", 0, 3, states_44, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\003\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\003\000\000"}, {301, "comparison", 0, 2, states_45, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000\000"}, {302, "comp_op", 0, 4, states_46, - "\000\000\000\000\000\000\000\000\000\000\004\000\000\362\017\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\004\000\000\362\017\000\000\000\000\000\000"}, {303, "expr", 0, 2, states_47, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000\000"}, {304, "xor_expr", 0, 2, states_48, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000\000"}, {305, "and_expr", 0, 2, states_49, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000\000"}, {306, "shift_expr", 0, 2, states_50, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000\000"}, {307, "arith_expr", 0, 2, states_51, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000\000"}, {308, "term", 0, 2, states_52, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000\000"}, {309, "factor", 0, 3, states_53, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000\000"}, {310, "power", 0, 4, states_54, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\111\003\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\111\003\000\000"}, {311, "atom", 0, 11, states_55, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\111\003\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\111\003\000\000"}, {312, "listmaker", 0, 5, states_56, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000\000"}, {313, "testlist_gexp", 0, 5, states_57, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000\000"}, {314, "lambdef", 0, 5, states_58, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\000\000"}, {315, "trailer", 0, 7, states_59, - "\000\040\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\001\000\000"}, + "\000\040\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\001\000\000\000"}, {316, "subscriptlist", 0, 3, states_60, - "\000\040\050\000\000\000\000\000\000\100\000\000\000\002\000\140\010\111\023\000"}, + "\000\040\050\000\000\000\000\000\000\100\000\000\000\002\000\140\010\111\023\000\000"}, {317, "subscript", 0, 7, states_61, - "\000\040\050\000\000\000\000\000\000\100\000\000\000\002\000\140\010\111\023\000"}, + "\000\040\050\000\000\000\000\000\000\100\000\000\000\002\000\140\010\111\023\000\000"}, {318, "sliceop", 0, 3, states_62, - "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {319, "exprlist", 0, 3, states_63, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000\000"}, {320, "testlist", 0, 3, states_64, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000\000"}, {321, "testlist_safe", 0, 5, states_65, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000\000"}, {322, "dictmaker", 0, 5, states_66, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000\000"}, {323, "classdef", 0, 8, states_67, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002"}, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000"}, {324, "arglist", 0, 8, states_68, - "\000\040\010\060\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000"}, + "\000\040\010\060\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000\000"}, {325, "argument", 0, 5, states_69, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000\000"}, {326, "list_iter", 0, 2, states_70, - "\000\000\000\000\000\000\000\000\000\000\000\042\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\042\000\000\000\000\000\000\000\000\000"}, {327, "list_for", 0, 6, states_71, - "\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000"}, {328, "list_if", 0, 4, states_72, - "\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000"}, {329, "gen_iter", 0, 2, states_73, - "\000\000\000\000\000\000\000\000\000\000\000\042\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\042\000\000\000\000\000\000\000\000\000"}, {330, "gen_for", 0, 6, states_74, - "\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000"}, {331, "gen_if", 0, 4, states_75, - "\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000"}, {332, "testlist1", 0, 2, states_76, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000\000"}, {333, "encoding_decl", 0, 2, states_77, - "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {334, "yield_expr", 0, 3, states_78, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001"}, }; -static label labels[160] = { +static label labels[161] = { {0, "EMPTY"}, {256, 0}, {4, 0}, @@ -1855,6 +1871,7 @@ {289, 0}, {290, 0}, {270, 0}, + {334, 0}, {37, 0}, {38, 0}, {39, 0}, @@ -1880,7 +1897,6 @@ {1, "break"}, {1, "continue"}, {1, "return"}, - {1, "yield"}, {1, "raise"}, {281, 0}, {282, 0}, @@ -1972,10 +1988,11 @@ {329, 0}, {331, 0}, {333, 0}, + {1, "yield"}, }; grammar _PyParser_Grammar = { - 78, + 79, dfas, - {160, labels}, + {161, labels}, 256 }; Index: import.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/import.c,v retrieving revision 2.208.2.6 retrieving revision 2.208.2.7 diff -u -d -r2.208.2.6 -r2.208.2.7 --- import.c 14 Oct 2005 07:21:26 -0000 2.208.2.6 +++ import.c 16 Oct 2005 05:24:05 -0000 2.208.2.7 @@ -51,8 +51,9 @@ Python 2.4a0: 62041 Python 2.4a3: 62051 Python 2.4b1: 62061 + Python 2.5a0: 62071 */ -#define MAGIC (62061 | ((long)'\r'<<16) | ((long)'\n'<<24)) +#define MAGIC (62071 | ((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 @@ -260,6 +261,18 @@ return 1; } +/* This function is called from PyOS_AfterFork to ensure that newly + created child processes do not share locks with the parent. */ + +void +_PyImport_ReInitLock(void) +{ +#ifdef _AIX + if (import_lock != NULL) + import_lock = PyThread_allocate_lock(); +#endif +} + #else #define lock_import() @@ -856,8 +869,12 @@ PyObject *m; mtime = PyOS_GetLastModificationTime(pathname, fp); - if (mtime == (time_t)(-1)) + if (mtime == (time_t)(-1)) { + PyErr_Format(PyExc_RuntimeError, + "unable to get modification time from '%s'", + pathname); return NULL; + } #if SIZEOF_TIME_T > 4 /* Python's .pyc timestamp handling presumes that the timestamp fits in 4 bytes. This will be fine until sometime in the year 2038, @@ -1378,16 +1395,13 @@ /* First we may need a pile of platform-specific header files; the sequence * of #if's here should match the sequence in the body of case_ok(). */ -#if defined(MS_WINDOWS) || defined(__CYGWIN__) +#if defined(MS_WINDOWS) #include -#ifdef __CYGWIN__ -#include -#endif #elif defined(DJGPP) #include -#elif defined(__MACH__) && defined(__APPLE__) && defined(HAVE_DIRENT_H) +#elif (defined(__MACH__) && defined(__APPLE__) || defined(__CYGWIN__)) && defined(HAVE_DIRENT_H) #include #include @@ -1408,23 +1422,15 @@ * match the sequence just above. */ -/* MS_WINDOWS || __CYGWIN__ */ -#if defined(MS_WINDOWS) || defined(__CYGWIN__) +/* MS_WINDOWS */ +#if defined(MS_WINDOWS) WIN32_FIND_DATA data; HANDLE h; -#ifdef __CYGWIN__ - char tempbuf[MAX_PATH]; -#endif if (Py_GETENV("PYTHONCASEOK") != NULL) return 1; -#ifdef __CYGWIN__ - cygwin32_conv_to_win32_path(buf, tempbuf); - h = FindFirstFile(tempbuf, &data); -#else h = FindFirstFile(buf, &data); -#endif if (h == INVALID_HANDLE_VALUE) { PyErr_Format(PyExc_NameError, "Can't find file for module %.100s\n(filename %.300s)", @@ -1451,8 +1457,8 @@ } return strncmp(ffblk.ff_name, name, namelen) == 0; -/* new-fangled macintosh (macosx) */ -#elif defined(__MACH__) && defined(__APPLE__) && defined(HAVE_DIRENT_H) +/* new-fangled macintosh (macosx) or Cygwin */ +#elif (defined(__MACH__) && defined(__APPLE__) || defined(__CYGWIN__)) && defined(HAVE_DIRENT_H) DIR *dirp; struct dirent *dp; char dirname[MAXPATHLEN + 1]; @@ -2299,13 +2305,14 @@ if (parentname == NULL) return NULL; parent = PyDict_GetItem(modules, parentname); - Py_DECREF(parentname); if (parent == NULL) { PyErr_Format(PyExc_ImportError, "reload(): parent %.200s not in sys.modules", - name); + PyString_AS_STRING(parentname)); + Py_DECREF(parentname); return NULL; } + Py_DECREF(parentname); subname++; path = PyObject_GetAttrString(parent, "__path__"); if (path == NULL) Index: marshal.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/marshal.c,v retrieving revision 1.72.2.3 retrieving revision 1.72.2.4 diff -u -d -r1.72.2.3 -r1.72.2.4 --- marshal.c 7 Jan 2005 07:04:56 -0000 1.72.2.3 +++ marshal.c 16 Oct 2005 05:24:05 -0000 1.72.2.4 @@ -16,26 +16,30 @@ */ #define MAX_MARSHAL_STACK_DEPTH 5000 -#define TYPE_NULL '0' -#define TYPE_NONE 'N' -#define TYPE_FALSE 'F' -#define TYPE_TRUE 'T' -#define TYPE_STOPITER 'S' -#define TYPE_ELLIPSIS '.' -#define TYPE_INT 'i' -#define TYPE_INT64 'I' -#define TYPE_FLOAT 'f' -#define TYPE_COMPLEX 'x' -#define TYPE_LONG 'l' -#define TYPE_STRING 's' -#define TYPE_INTERNED 't' -#define TYPE_STRINGREF 'R' -#define TYPE_TUPLE '(' -#define TYPE_LIST '[' -#define TYPE_DICT '{' -#define TYPE_CODE 'c' -#define TYPE_UNICODE 'u' -#define TYPE_UNKNOWN '?' +#define TYPE_NULL '0' +#define TYPE_NONE 'N' +#define TYPE_FALSE 'F' +#define TYPE_TRUE 'T' +#define TYPE_STOPITER 'S' +#define TYPE_ELLIPSIS '.' +#define TYPE_INT 'i' +#define TYPE_INT64 'I' +#define TYPE_FLOAT 'f' +#define TYPE_BINARY_FLOAT 'g' +#define TYPE_COMPLEX 'x' +#define TYPE_BINARY_COMPLEX 'y' +#define TYPE_LONG 'l' +#define TYPE_STRING 's' +#define TYPE_INTERNED 't' +#define TYPE_STRINGREF 'R' +#define TYPE_TUPLE '(' +#define TYPE_LIST '[' +#define TYPE_DICT '{' +#define TYPE_CODE 'c' +#define TYPE_UNICODE 'u' +#define TYPE_UNKNOWN '?' +#define TYPE_SET '<' +#define TYPE_FROZENSET '>' typedef struct { FILE *fp; @@ -46,6 +50,7 @@ char *ptr; char *end; PyObject *strings; /* dict on marshal, list on unmarshal */ + int version; } WFILE; #define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \ @@ -164,32 +169,62 @@ w_short(ob->ob_digit[i], p); } else if (PyFloat_Check(v)) { - char buf[256]; /* Plenty to format any double */ - PyFloat_AsReprString(buf, (PyFloatObject *)v); - n = strlen(buf); - w_byte(TYPE_FLOAT, p); - w_byte(n, p); - w_string(buf, n, p); + if (p->version > 1) { + unsigned char buf[8]; + if (_PyFloat_Pack8(PyFloat_AsDouble(v), + buf, 1) < 0) { + p->error = 1; + return; + } + w_byte(TYPE_BINARY_FLOAT, p); + w_string((char*)buf, 8, p); + } + else { + char buf[256]; /* Plenty to format any double */ + PyFloat_AsReprString(buf, (PyFloatObject *)v); + n = strlen(buf); + w_byte(TYPE_FLOAT, p); + w_byte(n, p); + w_string(buf, n, p); + } } #ifndef WITHOUT_COMPLEX else if (PyComplex_Check(v)) { - char buf[256]; /* Plenty to format any double */ - PyFloatObject *temp; - w_byte(TYPE_COMPLEX, p); - temp = (PyFloatObject*)PyFloat_FromDouble( - PyComplex_RealAsDouble(v)); - PyFloat_AsReprString(buf, temp); - Py_DECREF(temp); - n = strlen(buf); - w_byte(n, p); - w_string(buf, n, p); - temp = (PyFloatObject*)PyFloat_FromDouble( - PyComplex_ImagAsDouble(v)); - PyFloat_AsReprString(buf, temp); - Py_DECREF(temp); - n = strlen(buf); - w_byte(n, p); - w_string(buf, n, p); + if (p->version > 1) { + unsigned char buf[8]; + if (_PyFloat_Pack8(PyComplex_RealAsDouble(v), + buf, 1) < 0) { + p->error = 1; + return; + } + w_byte(TYPE_BINARY_COMPLEX, p); + w_string((char*)buf, 8, p); + if (_PyFloat_Pack8(PyComplex_ImagAsDouble(v), + buf, 1) < 0) { + p->error = 1; + return; + } + w_string((char*)buf, 8, p); + } + else { + char buf[256]; /* Plenty to format any double */ + PyFloatObject *temp; + w_byte(TYPE_COMPLEX, p); + temp = (PyFloatObject*)PyFloat_FromDouble( + PyComplex_RealAsDouble(v)); + PyFloat_AsReprString(buf, temp); + Py_DECREF(temp); + n = strlen(buf); + w_byte(n, p); + w_string(buf, n, p); + temp = (PyFloatObject*)PyFloat_FromDouble( + PyComplex_ImagAsDouble(v)); + PyFloat_AsReprString(buf, temp); + Py_DECREF(temp); + n = strlen(buf); + w_byte(n, p); + w_string(buf, n, p); + } } #endif else if (PyString_Check(v)) { @@ -259,6 +294,37 @@ } w_object((PyObject *)NULL, p); } + else if (PyAnySet_Check(v)) { + PyObject *value, *it; + + if (PyObject_TypeCheck(v, &PySet_Type)) + w_byte(TYPE_SET, p); + else + w_byte(TYPE_FROZENSET, p); + n = PyObject_Size(v); + if (n == -1) { + p->depth--; + p->error = 1; + return; + } + w_long((long)n, p); + it = PyObject_GetIter(v); + if (it == NULL) { + p->depth--; + p->error = 1; + return; + } + while ((value = PyIter_Next(it)) != NULL) { + w_object(value, p); + Py_DECREF(value); + } + Py_DECREF(it); + if (PyErr_Occurred()) { + p->depth--; + p->error = 1; + return; + } + } else if (PyCode_Check(v)) { PyCodeObject *co = (PyCodeObject *)v; w_byte(TYPE_CODE, p); @@ -303,6 +369,7 @@ wf.error = 0; wf.depth = 0; wf.strings = NULL; + wf.version = version; w_long(x, &wf); } @@ -314,6 +381,7 @@ wf.error = 0; wf.depth = 0; wf.strings = (version > 0) ? PyDict_New() : NULL; + wf.version = version; w_object(x, &wf); Py_XDECREF(wf.strings); } @@ -407,7 +475,7 @@ { /* NULL is a valid return value, it does not necessarily means that an exception is set. */ - PyObject *v, *v2; + PyObject *v, *v2, *v3; long i, n; int type = r_byte(p); @@ -487,6 +555,22 @@ return PyFloat_FromDouble(dx); } + case TYPE_BINARY_FLOAT: + { + unsigned char buf[8]; + double x; + if (r_string((char*)buf, 8, p) != 8) { + PyErr_SetString(PyExc_EOFError, + "EOF read where object expected"); + return NULL; + } + x = _PyFloat_Unpack8(buf, 1); + if (x == -1.0 && PyErr_Occurred()) { + return NULL; + } + return PyFloat_FromDouble(x); + } + #ifndef WITHOUT_COMPLEX case TYPE_COMPLEX: { @@ -514,6 +598,31 @@ PyFPE_END_PROTECT(c) return PyComplex_FromCComplex(c); } + + case TYPE_BINARY_COMPLEX: + { + unsigned char buf[8]; + Py_complex c; + if (r_string((char*)buf, 8, p) != 8) { + PyErr_SetString(PyExc_EOFError, + "EOF read where object expected"); + return NULL; + } + c.real = _PyFloat_Unpack8(buf, 1); + if (c.real == -1.0 && PyErr_Occurred()) { + return NULL; + } + if (r_string((char*)buf, 8, p) != 8) { + PyErr_SetString(PyExc_EOFError, + "EOF read where object expected"); + return NULL; + } + c.imag = _PyFloat_Unpack8(buf, 1); + if (c.imag == -1.0 && PyErr_Occurred()) { + return NULL; + } + return PyComplex_FromCComplex(c); + } #endif case TYPE_INTERNED: @@ -524,13 +633,13 @@ return NULL; } v = PyString_FromStringAndSize((char *)NULL, n); - if (v != NULL) { - if (r_string(PyString_AS_STRING(v), (int)n, p) != n) { - Py_DECREF(v); - v = NULL; - PyErr_SetString(PyExc_EOFError, + if (v == NULL) + return v; + if (r_string(PyString_AS_STRING(v), (int)n, p) != n) { + Py_DECREF(v); + PyErr_SetString(PyExc_EOFError, "EOF read where object expected"); - } + return NULL; } if (type == TYPE_INTERNED) { PyString_InternInPlace(&v); @@ -540,6 +649,10 @@ case TYPE_STRINGREF: n = r_long(p); + if (n < 0 || n >= PyList_GET_SIZE(p->strings)) { + PyErr_SetString(PyExc_ValueError, "bad marshal data"); + return NULL; + } v = PyList_GET_ITEM(p->strings, n); Py_INCREF(v); return v; @@ -636,6 +749,37 @@ } return v; + case TYPE_SET: + case TYPE_FROZENSET: + n = r_long(p); + if (n < 0) { + PyErr_SetString(PyExc_ValueError, "bad marshal data"); + return NULL; + } + v = PyTuple_New((int)n); + if (v == NULL) + return v; + for (i = 0; i < n; i++) { + v2 = r_object(p); + if ( v2 == NULL ) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_TypeError, + "NULL object in marshal data"); + Py_DECREF(v); + v = NULL; + break; + } + PyTuple_SET_ITEM(v, (int)i, v2); + } + if (v == NULL) + return v; + if (type == TYPE_SET) + v3 = PySet_New(v); + else + v3 = PyFrozenSet_New(v); + Py_DECREF(v); + return v3; + case TYPE_CODE: if (PyEval_GetRestricted()) { PyErr_SetString(PyExc_RuntimeError, @@ -644,30 +788,63 @@ return NULL; } else { - int argcount = r_long(p); - int nlocals = r_long(p); - int stacksize = r_long(p); - int flags = r_long(p); - PyObject *code = r_object(p); - PyObject *consts = r_object(p); - PyObject *names = r_object(p); - PyObject *varnames = r_object(p); - PyObject *freevars = r_object(p); - PyObject *cellvars = r_object(p); - PyObject *filename = r_object(p); - PyObject *name = r_object(p); - int firstlineno = r_long(p); - PyObject *lnotab = r_object(p); + int argcount; + int nlocals; + int stacksize; + int flags; + PyObject *code = NULL; + PyObject *consts = NULL; + PyObject *names = NULL; + PyObject *varnames = NULL; + PyObject *freevars = NULL; + PyObject *cellvars = NULL; + PyObject *filename = NULL; + PyObject *name = NULL; + int firstlineno; + PyObject *lnotab = NULL; + + v = NULL; - if (!PyErr_Occurred()) { - v = (PyObject *) PyCode_New( + argcount = r_long(p); + nlocals = r_long(p); + stacksize = r_long(p); + flags = r_long(p); + code = r_object(p); + if (code == NULL) + goto code_error; + consts = r_object(p); + if (consts == NULL) + goto code_error; + names = r_object(p); + if (names == NULL) + goto code_error; + varnames = r_object(p); + if (varnames == NULL) + goto code_error; + freevars = r_object(p); + if (freevars == NULL) + goto code_error; + cellvars = r_object(p); + if (cellvars == NULL) + goto code_error; + filename = r_object(p); + if (filename == NULL) + goto code_error; + name = r_object(p); + if (name == NULL) + goto code_error; + firstlineno = r_long(p); + lnotab = r_object(p); + if (lnotab == NULL) + goto code_error; + + v = (PyObject *) PyCode_New( argcount, nlocals, stacksize, flags, code, consts, names, varnames, freevars, cellvars, filename, name, firstlineno, lnotab); - } - else - v = NULL; + + code_error: Py_XDECREF(code); Py_XDECREF(consts); Py_XDECREF(names); @@ -819,6 +996,7 @@ wf.end = wf.ptr + PyString_Size(wf.str); wf.error = 0; wf.depth = 0; + wf.version = version; wf.strings = (version > 0) ? PyDict_New() : NULL; w_object(x, &wf); Py_XDECREF(wf.strings); @@ -906,7 +1084,7 @@ char *s; int n; PyObject* result; - if (!PyArg_ParseTuple(args, "s#|i:loads", &s, &n)) + if (!PyArg_ParseTuple(args, "s#:loads", &s, &n)) return NULL; rf.fp = NULL; rf.ptr = s; Index: pystate.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pystate.c,v retrieving revision 2.20.18.2 retrieving revision 2.20.18.3 diff -u -d -r2.20.18.2 -r2.20.18.3 --- pystate.c 7 Jan 2005 07:04:57 -0000 2.20.18.2 +++ pystate.c 16 Oct 2005 05:24:05 -0000 2.20.18.3 @@ -36,6 +36,12 @@ #define HEAD_INIT() (void)(head_mutex || (head_mutex = PyThread_allocate_lock())) #define HEAD_LOCK() PyThread_acquire_lock(head_mutex, WAIT_LOCK) #define HEAD_UNLOCK() PyThread_release_lock(head_mutex) + +/* The single PyInterpreterState used by this process' + GILState implementation +*/ +static PyInterpreterState *autoInterpreterState = NULL; +static int autoTLSkey = 0; #else #define HEAD_INIT() /* Nothing */ #define HEAD_LOCK() /* Nothing */ @@ -47,6 +53,10 @@ PyThreadState *_PyThreadState_Current = NULL; PyThreadFrameGetter _PyThreadState_GetFrame = NULL; +#ifdef WITH_THREAD +static void _PyGILState_NoteThreadState(PyThreadState* tstate); +#endif + PyInterpreterState * PyInterpreterState_New(void) @@ -180,6 +190,10 @@ tstate->c_profileobj = NULL; tstate->c_traceobj = NULL; +#ifdef WITH_THREAD + _PyGILState_NoteThreadState(tstate); +#endif + HEAD_LOCK(); tstate->next = interp->tstate_head; interp->tstate_head = tstate; @@ -261,6 +275,8 @@ "PyThreadState_DeleteCurrent: no current tstate"); _PyThreadState_Current = NULL; tstate_delete_common(tstate); + if (autoTLSkey && PyThread_get_key_value(autoTLSkey) == tstate) + PyThread_delete_key_value(autoTLSkey); PyEval_ReleaseLock(); } #endif /* WITH_THREAD */ @@ -289,7 +305,7 @@ #if defined(Py_DEBUG) && defined(WITH_THREAD) if (new) { PyThreadState *check = PyGILState_GetThisThreadState(); - if (check && check != new) + if (check && check->interp == new->interp && check != new) Py_FatalError("Invalid thread state for this thread"); } #endif @@ -320,7 +336,7 @@ /* Asynchronously raise an exception in a thread. Requested by Just van Rossum and Alex Martelli. - To prevent naive misuse, you must write your own exception + To prevent naive misuse, you must write your own extension to call this. Must be called with the GIL held. Returns the number of tstates modified; if it returns a number greater than one, you're in trouble, and you should call it again @@ -332,6 +348,7 @@ PyInterpreterState *interp = tstate->interp; PyThreadState *p; int count = 0; + HEAD_LOCK(); for (p = interp->tstate_head; p != NULL; p = p->next) { if (p->thread_id != id) continue; @@ -340,6 +357,7 @@ p->async_exc = exc; count += 1; } + HEAD_UNLOCK(); return count; } @@ -391,12 +409,6 @@ return tstate == _PyThreadState_Current; } -/* The single PyInterpreterState used by this process' - GILState implementation -*/ -static PyInterpreterState *autoInterpreterState = NULL; -static int autoTLSkey = 0; - /* Internal initialization/finalization functions called by Py_Initialize/Py_Finalize */ @@ -406,12 +418,10 @@ assert(i && t); /* must init with valid states */ autoTLSkey = PyThread_create_key(); autoInterpreterState = i; - /* Now stash the thread state for this thread in TLS */ assert(PyThread_get_key_value(autoTLSkey) == NULL); - if (PyThread_set_key_value(autoTLSkey, (void *)t) < 0) - Py_FatalError("Couldn't create autoTLSkey mapping"); - assert(t->gilstate_counter == 0); /* must be a new thread state */ - t->gilstate_counter = 1; + assert(t->gilstate_counter == 0); + + _PyGILState_NoteThreadState(t); } void @@ -422,6 +432,41 @@ autoInterpreterState = NULL;; } +/* When a thread state is created for a thread by some mechanism other than + PyGILState_Ensure, it's important that the GILState machinery knows about + it so it doesn't try to create another thread state for the thread (this is + a better fix for SF bug #1010677 than the first one attempted). +*/ +void +_PyGILState_NoteThreadState(PyThreadState* tstate) +{ + /* If autoTLSkey is 0, this must be the very first threadstate created + in Py_Initialize(). Don't do anything for now (we'll be back here + when _PyGILState_Init is called). */ + if (!autoTLSkey) + return; + + /* Stick the thread state for this thread in thread local storage. + + The only situation where you can legitimately have more than one + thread state for an OS level thread is when there are multiple + interpreters, when: + + a) You shouldn't really be using the PyGILState_ APIs anyway, + and: + + b) The slightly odd way PyThread_set_key_value works (see + comments by its implementation) means that the first thread + state created for that given OS level thread will "win", + which seems reasonable behaviour. + */ + if (PyThread_set_key_value(autoTLSkey, (void *)tstate) < 0) + Py_FatalError("Couldn't create autoTLSkey mapping"); + + /* PyGILState_Release must not try to delete this thread state. */ + tstate->gilstate_counter = 1; +} + /* The public functions */ PyThreadState * PyGILState_GetThisThreadState(void) @@ -448,8 +493,9 @@ tcur = PyThreadState_New(autoInterpreterState); if (tcur == NULL) Py_FatalError("Couldn't create thread-state for new thread"); - if (PyThread_set_key_value(autoTLSkey, (void *)tcur) < 0) - Py_FatalError("Couldn't create autoTLSkey mapping"); + /* This is our thread state! We'll need to delete it in the + matching call to PyGILState_Release(). */ + tcur->gilstate_counter = 0; current = 0; /* new thread state is never current */ } else @@ -496,11 +542,9 @@ * habit of coming back). */ PyThreadState_DeleteCurrent(); - /* Delete this thread from our TLS. */ - PyThread_delete_key_value(autoTLSkey); } /* Release the lock if necessary */ else if (oldstate == PyGILState_UNLOCKED) - PyEval_ReleaseThread(tcur); + PyEval_SaveThread(); } #endif /* WITH_THREAD */ Index: pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.161.2.18 retrieving revision 2.161.2.19 diff -u -d -r2.161.2.18 -r2.161.2.19 --- pythonrun.c 14 Oct 2005 07:21:27 -0000 2.161.2.18 +++ pythonrun.c 16 Oct 2005 05:24:05 -0000 2.161.2.19 @@ -175,6 +175,8 @@ if (!_PyInt_Init()) Py_FatalError("Py_Initialize: can't init ints"); + _PyFloat_Init(); + interp->modules = PyDict_New(); if (interp->modules == NULL) Py_FatalError("Py_Initialize: can't make modules dictionary"); @@ -395,13 +397,6 @@ _Py_PrintReferences(stderr); #endif /* Py_TRACE_REFS */ - /* Now we decref the exception classes. After this point nothing - can raise an exception. That's okay, because each Fini() method - below has been checked to make sure no exceptions are ever - raised. - */ - _PyExc_Fini(); - /* Cleanup auto-thread-state */ #ifdef WITH_THREAD _PyGILState_Fini(); @@ -410,6 +405,14 @@ /* Clear interpreter state */ PyInterpreterState_Clear(interp); + /* Now we decref the exception classes. After this point nothing + can raise an exception. That's okay, because each Fini() method + below has been checked to make sure no exceptions are ever + raised. + */ + + _PyExc_Fini(); + /* Delete current thread */ PyThreadState_Swap(NULL); PyInterpreterState_Delete(interp); @@ -420,6 +423,7 @@ PyCFunction_Fini(); PyTuple_Fini(); PyList_Fini(); + PySet_Fini(); PyString_Fini(); PyInt_Fini(); PyFloat_Fini(); @@ -1417,20 +1421,25 @@ errtype = PyExc_IndentationError; msg = "too many levels of indentation"; break; - case E_DECODE: { /* XXX */ - PyThreadState* tstate = PyThreadState_GET(); - PyObject* value = tstate->curexc_value; + case E_DECODE: { + PyObject *type, *value, *tb; + PyErr_Fetch(&type, &value, &tb); if (value != NULL) { - u = PyObject_Repr(value); + u = PyObject_Str(value); if (u != NULL) { msg = PyString_AsString(u); - break; } } if (msg == NULL) msg = "unknown decode error"; + Py_DECREF(type); + Py_DECREF(value); + Py_XDECREF(tb); break; } + case E_LINECONT: + msg = "unexpected character after line continuation character"; + break; default: fprintf(stderr, "error=%d\n", err->error); msg = "unknown parsing error"; Index: structmember.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/structmember.c,v retrieving revision 2.23.8.1 retrieving revision 2.23.8.2 diff -u -d -r2.23.8.1 -r2.23.8.2 --- structmember.c 7 Jan 2005 07:04:58 -0000 2.23.8.1 +++ structmember.c 16 Oct 2005 05:24:06 -0000 2.23.8.2 @@ -118,6 +118,14 @@ PyErr_SetString(PyExc_AttributeError, l->name); Py_XINCREF(v); break; +#ifdef HAVE_LONG_LONG + case T_LONGLONG: + v = PyLong_FromLongLong(*(PY_LONG_LONG *)addr); + break; + case T_ULONGLONG: + v = PyLong_FromUnsignedLongLong(*(unsigned PY_LONG_LONG *)addr); + break; +#endif /* HAVE_LONG_LONG */ default: PyErr_SetString(PyExc_SystemError, "bad memberdescr type"); v = NULL; @@ -246,6 +254,30 @@ return -1; } break; +#ifdef HAVE_LONG_LONG + case T_LONGLONG: + if (!PyLong_Check(v)) { + PyErr_BadArgument(); + return -1; + } else { + *(PY_LONG_LONG*)addr = PyLong_AsLongLong(v); + if ((*addr == -1) && PyErr_Occurred()) { + return -1; + } + } + break; + case T_ULONGLONG: + if (!PyLong_Check(v)) { + PyErr_BadArgument(); + return -1; + } else { + *(unsigned PY_LONG_LONG*)addr = PyLong_AsUnsignedLongLong(v); + if ((*addr == -1) && PyErr_Occurred()) { + return -1; + } + } + break; +#endif /* HAVE_LONG_LONG */ default: PyErr_Format(PyExc_SystemError, "bad memberdescr type for %s", l->name); Index: sysmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v retrieving revision 2.107.2.3 retrieving revision 2.107.2.4 diff -u -d -r2.107.2.3 -r2.107.2.4 --- sysmodule.c 7 Jan 2005 07:04:59 -0000 2.107.2.3 +++ sysmodule.c 16 Oct 2005 05:24:06 -0000 2.107.2.4 @@ -927,6 +927,13 @@ ) /* end of sys_doc */ ; +static int +_check_and_flush (FILE *stream) +{ + int prev_fail = ferror (stream); + return fflush (stream) || prev_fail ? EOF : 0; +} + PyObject * _PySys_Init(void) { @@ -940,9 +947,27 @@ m = Py_InitModule3("sys", sys_methods, sys_doc); sysdict = PyModule_GetDict(m); + { + /* XXX: does this work on Win/Win64? (see posix_fstat) */ + struct stat sb; + if (fstat(fileno(stdin), &sb) == 0 && + S_ISDIR(sb.st_mode)) { + Py_FatalError(" is a directory"); + } + } + + /* Closing the standard FILE* if sys.std* goes aways causes problems + * for embedded Python usages. Closing them when somebody explicitly + * invokes .close() might be possible, but the FAQ promises they get + * never closed. However, we still need to get write errors when + * writing fails (e.g. because stdout is redirected), so we flush the + * streams and check for errors before the file objects are deleted. + * On OS X, fflush()ing stdin causes an error, so we exempt stdin + * from that procedure. + */ sysin = PyFile_FromFile(stdin, "", "r", NULL); - sysout = PyFile_FromFile(stdout, "", "w", NULL); - syserr = PyFile_FromFile(stderr, "", "w", NULL); + sysout = PyFile_FromFile(stdout, "", "w", _check_and_flush); + syserr = PyFile_FromFile(stderr, "", "w", _check_and_flush); if (PyErr_Occurred()) return NULL; #ifdef MS_WINDOWS @@ -1172,7 +1197,7 @@ char link[MAXPATHLEN+1]; char argv0copy[2*MAXPATHLEN+1]; int nr = 0; - if (argc > 0 && argv0 != NULL) + if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) nr = readlink(argv0, link, MAXPATHLEN); if (nr > 0) { /* It's a symlink */ @@ -1197,7 +1222,7 @@ } #endif /* HAVE_READLINK */ #if SEP == '\\' /* Special case for MS filename syntax */ - if (argc > 0 && argv0 != NULL) { + if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) { char *q; #ifdef MS_WINDOWS char *ptemp; @@ -1220,7 +1245,7 @@ } } #else /* All other filename syntaxes */ - if (argc > 0 && argv0 != NULL) { + if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) { #if defined(HAVE_REALPATH) if (realpath(argv0, fullpath)) { argv0 = fullpath; Index: thread.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/thread.c,v retrieving revision 2.44.2.2 retrieving revision 2.44.2.3 diff -u -d -r2.44.2.2 -r2.44.2.3 --- thread.c 7 Jan 2005 07:04:59 -0000 2.44.2.2 +++ thread.c 16 Oct 2005 05:24:06 -0000 2.44.2.3 @@ -45,6 +45,20 @@ #define SUN_LWP #endif +/* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then + enough of the Posix threads package is implimented to support python + threads. + + This is valid for HP-UX 11.23 running on an ia64 system. If needed, add + a check of __ia64 to verify that we're running on a ia64 system instead + of a pa-risc system. +*/ +#ifdef __hpux +#ifdef _SC_THREADS +#define _POSIX_THREADS +#endif +#endif + #endif /* _POSIX_THREADS */ Index: thread_nt.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/thread_nt.h,v retrieving revision 2.22.2.1 retrieving revision 2.22.2.2 diff -u -d -r2.22.2.1 -r2.22.2.2 --- thread_nt.h 7 Jan 2005 07:05:00 -0000 2.22.2.1 +++ thread_nt.h 16 Oct 2005 05:24:06 -0000 2.22.2.2 @@ -299,7 +299,7 @@ dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n", PyThread_get_thread_ident(),aLock, waitflag)); - success = aLock && EnterNonRecursiveMutex((PNRMUTEX) aLock, (waitflag == 1 ? INFINITE : 0)) == WAIT_OBJECT_0 ; + success = aLock && EnterNonRecursiveMutex((PNRMUTEX) aLock, (waitflag ? INFINITE : 0)) == WAIT_OBJECT_0 ; dprintf(("%ld: PyThread_acquire_lock(%p, %d) -> %d\n", PyThread_get_thread_ident(),aLock, waitflag, success)); Index: thread_os2.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/thread_os2.h,v retrieving revision 2.14.2.1 retrieving revision 2.14.2.2 diff -u -d -r2.14.2.1 -r2.14.2.2 --- thread_os2.h 28 Apr 2003 17:16:44 -0000 2.14.2.1 +++ thread_os2.h 16 Oct 2005 05:24:06 -0000 2.14.2.2 @@ -14,6 +14,10 @@ long PyThread_get_thread_ident(void); #endif +#if !defined(THREAD_STACK_SIZE) +#define THREAD_STACK_SIZE 0x10000 +#endif + /* * Initialization of the C package, should not be needed. */ @@ -31,7 +35,7 @@ int aThread; int success = 0; - aThread = _beginthread(func,NULL,65536,arg); + aThread = _beginthread(func, NULL, THREAD_STACK_SIZE, arg); if (aThread == -1) { success = -1; Index: thread_pthread.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/thread_pthread.h,v retrieving revision 2.40.2.2 retrieving revision 2.40.2.3 diff -u -d -r2.40.2.2 -r2.40.2.3 --- thread_pthread.h 7 Jan 2005 07:05:00 -0000 2.40.2.2 +++ thread_pthread.h 16 Oct 2005 05:24:06 -0000 2.40.2.3 @@ -16,9 +16,15 @@ family of functions must indicate this by defining _POSIX_SEMAPHORES. */ #ifdef _POSIX_SEMAPHORES +/* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so + we need to add 0 to make it work there as well. */ +#if (_POSIX_SEMAPHORES+0) == -1 +#define HAVE_BROKEN_POSIX_SEMAPHORES +#else #include #include #endif +#endif #if !defined(pthread_attr_default) # define pthread_attr_default ((pthread_attr_t *)NULL) @@ -349,8 +355,8 @@ PyThread_init_thread(); lock = (pthread_lock *) malloc(sizeof(pthread_lock)); - memset((void *)lock, '\0', sizeof(pthread_lock)); if (lock) { + memset((void *)lock, '\0', sizeof(pthread_lock)); lock->locked = 0; status = pthread_mutex_init(&lock->mut, Index: thread_wince.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/thread_wince.h,v retrieving revision 2.7 retrieving revision 2.7.12.1 diff -u -d -r2.7 -r2.7.12.1 --- thread_wince.h 16 Oct 2001 21:13:49 -0000 2.7 +++ thread_wince.h 16 Oct 2005 05:24:06 -0000 2.7.12.1 @@ -140,13 +140,13 @@ dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n", PyThread_get_thread_ident(),aLock, waitflag)); #ifndef DEBUG - waitResult = WaitForSingleObject(aLock, (waitflag == 1 ? INFINITE : 0)); + waitResult = WaitForSingleObject(aLock, (waitflag ? INFINITE : 0)); #else /* To aid in debugging, we regularly wake up. This allows us to break into the debugger */ while (TRUE) { waitResult = WaitForSingleObject(aLock, waitflag ? 3000 : 0); - if (waitflag==0 || (waitflag==1 && waitResult == WAIT_OBJECT_0)) + if (waitflag==0 || (waitflag && waitResult == WAIT_OBJECT_0)) break; } #endif From jhylton at users.sourceforge.net Sun Oct 16 07:24:29 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Sun, 16 Oct 2005 07:24:29 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Demo/embed Makefile, 1.11.8.1, 1.11.8.2 Message-ID: <20051016052429.7D6BF1E4002@bag.python.org> Update of /cvsroot/python/python/dist/src/Demo/embed In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27718/Demo/embed Modified Files: Tag: ast-branch Makefile Log Message: Merge head to branch (for the last time) Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/Demo/embed/Makefile,v retrieving revision 1.11.8.1 retrieving revision 1.11.8.2 diff -u -d -r1.11.8.1 -r1.11.8.2 --- Makefile 28 Apr 2003 17:39:04 -0000 1.11.8.1 +++ Makefile 16 Oct 2005 05:23:56 -0000 1.11.8.2 @@ -10,7 +10,7 @@ srcdir= ../.. # Python version -VERSION= 2.3 +VERSION= 2.5 # Compiler flags OPT= -g From jhylton at users.sourceforge.net Sun Oct 16 07:24:29 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Sun, 16 Oct 2005 07:24:29 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Demo/parser README,1.4,1.4.24.1 Message-ID: <20051016052429.9B3A01E4008@bag.python.org> Update of /cvsroot/python/python/dist/src/Demo/parser In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27718/Demo/parser Modified Files: Tag: ast-branch README Log Message: Merge head to branch (for the last time) Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/Demo/parser/README,v retrieving revision 1.4 retrieving revision 1.4.24.1 diff -u -d -r1.4 -r1.4.24.1 --- README 23 Oct 2000 20:50:23 -0000 1.4 +++ README 16 Oct 2005 05:23:56 -0000 1.4.24.1 @@ -20,6 +20,6 @@ handle nested constructs easily using the functions and classes in example.py. - test_parser.py program to put the parser module through it's paces. + test_parser.py program to put the parser module through its paces. Enjoy! From jhylton at users.sourceforge.net Sun Oct 16 07:24:29 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Sun, 16 Oct 2005 07:24:29 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Demo/classes Complex.py, 1.5.30.2, 1.5.30.3 Message-ID: <20051016052429.A351B1E4009@bag.python.org> Update of /cvsroot/python/python/dist/src/Demo/classes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27718/Demo/classes Modified Files: Tag: ast-branch Complex.py Log Message: Merge head to branch (for the last time) Index: Complex.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Demo/classes/Complex.py,v retrieving revision 1.5.30.2 retrieving revision 1.5.30.3 diff -u -d -r1.5.30.2 -r1.5.30.3 --- Complex.py 7 Jan 2005 06:56:44 -0000 1.5.30.2 +++ Complex.py 16 Oct 2005 05:23:56 -0000 1.5.30.3 @@ -54,7 +54,7 @@ # nor are shift and mask operations. # # The standard module math does not support complex numbers. -# (I suppose it would be easy to implement a cmath module.) +# The cmath modules should be used instead. # # Idea: # add a class Polar(r, phi) and mixed-mode arithmetic which @@ -62,8 +62,8 @@ # Complex for +,-,cmp # Polar for *,/,pow - -import types, math +import math +import sys twopi = math.pi*2.0 halfpi = math.pi/2.0 @@ -74,8 +74,8 @@ def ToComplex(obj): if IsComplex(obj): return obj - elif type(obj) == types.TupleType: - return apply(Complex, obj) + elif isinstance(obj, tuple): + return Complex(*obj) else: return Complex(obj) @@ -86,34 +86,40 @@ def Re(obj): if IsComplex(obj): return obj.re - else: - return obj + return obj def Im(obj): if IsComplex(obj): return obj.im - else: - return obj + return 0 class Complex: def __init__(self, re=0, im=0): + _re = 0 + _im = 0 if IsComplex(re): - im = i + Complex(0, re.im) - re = re.re + _re = re.re + _im = re.im + else: + _re = re if IsComplex(im): - re = re - im.im - im = im.re - self.__dict__['re'] = re - self.__dict__['im'] = im + _re = _re - im.im + _im = _im + im.re + else: + _im = _im + im + # this class is immutable, so setting self.re directly is + # not possible. + self.__dict__['re'] = _re + self.__dict__['im'] = _im def __setattr__(self, name, value): raise TypeError, 'Complex numbers are immutable' def __hash__(self): - if not self.im: return hash(self.re) - mod = sys.maxint + 1L - return int((hash(self.re) + 2L*hash(self.im) + mod) % (2L*mod) - mod) + if not self.im: + return hash(self.re) + return hash((self.re, self.im)) def __repr__(self): if not self.im: @@ -134,8 +140,7 @@ return self def __abs__(self): - # XXX could be done differently to avoid overflow! - return math.sqrt(self.re*self.re + self.im*self.im) + return math.hypot(self.re, self.im) def __int__(self): if self.im: @@ -224,22 +229,41 @@ def checkop(expr, a, b, value, fuzz = 1e-6): - import sys print ' ', a, 'and', b, try: result = eval(expr) except: result = sys.exc_type print '->', result - if (type(result) == type('') or type(value) == type('')): - ok = result == value + if isinstance(result, str) or isinstance(value, str): + ok = (result == value) else: ok = abs(result - value) <= fuzz if not ok: print '!!\t!!\t!! should be', value, 'diff', abs(result - value) - def test(): + print 'test constructors' + constructor_test = ( + # "expect" is an array [re,im] "got" the Complex. + ( (0,0), Complex() ), + ( (0,0), Complex() ), + ( (1,0), Complex(1) ), + ( (0,1), Complex(0,1) ), + ( (1,2), Complex(Complex(1,2)) ), + ( (1,3), Complex(Complex(1,2),1) ), + ( (0,0), Complex(0,Complex(0,0)) ), + ( (3,4), Complex(3,Complex(4)) ), + ( (-1,3), Complex(1,Complex(3,2)) ), + ( (-7,6), Complex(Complex(1,2),Complex(4,8)) ) ) + cnt = [0,0] + for t in constructor_test: + cnt[0] += 1 + if ((t[0][0]!=t[1].re)or(t[0][1]!=t[1].im)): + print " expected", t[0], "got", t[1] + cnt[1] += 1 + print " ", cnt[1], "of", cnt[0], "tests failed" + # test operators testsuite = { 'a+b': [ (1, 10, 11), @@ -285,13 +309,11 @@ (Complex(1), Complex(0,10), 1), ], } - exprs = testsuite.keys() - exprs.sort() - for expr in exprs: + for expr in sorted(testsuite): print expr + ':' t = (expr,) for item in testsuite[expr]: - apply(checkop, t+item) + checkop(*(t+item)) if __name__ == '__main__': From jhylton at users.sourceforge.net Sun Oct 16 07:24:29 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Sun, 16 Oct 2005 07:24:29 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Demo/xmlrpc xmlrpc_handler.py, 1.2, 1.2.2.1 Message-ID: <20051016052429.C435B1E4002@bag.python.org> Update of /cvsroot/python/python/dist/src/Demo/xmlrpc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27718/Demo/xmlrpc Modified Files: Tag: ast-branch xmlrpc_handler.py Log Message: Merge head to branch (for the last time) Index: xmlrpc_handler.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Demo/xmlrpc/xmlrpc_handler.py,v retrieving revision 1.2 retrieving revision 1.2.2.1 diff -u -d -r1.2 -r1.2.2.1 --- xmlrpc_handler.py 3 Apr 2002 21:47:47 -0000 1.2 +++ xmlrpc_handler.py 16 Oct 2005 05:23:56 -0000 1.2.2.1 @@ -26,7 +26,7 @@ def handle_request (self, request): [path, params, query, fragment] = request.split_uri() - if request.command in ('post', 'put'): + if request.command.lower() in ('post', 'put'): request.collector = collector (self, request) else: request.error (400) From jhylton at users.sourceforge.net Sun Oct 16 07:24:29 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Sun, 16 Oct 2005 07:24:29 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Demo/rpc rpc.py, 1.11.30.1, 1.11.30.2 Message-ID: <20051016052429.E3B951E4008@bag.python.org> Update of /cvsroot/python/python/dist/src/Demo/rpc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27718/Demo/rpc Modified Files: Tag: ast-branch rpc.py Log Message: Merge head to branch (for the last time) Index: rpc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Demo/rpc/rpc.py,v retrieving revision 1.11.30.1 retrieving revision 1.11.30.2 diff -u -d -r1.11.30.1 -r1.11.30.2 --- rpc.py 7 Jan 2005 06:56:46 -0000 1.11.30.1 +++ rpc.py 16 Oct 2005 05:23:56 -0000 1.11.30.2 @@ -3,6 +3,8 @@ # XXX There should be separate exceptions for the various reasons why # XXX an RPC can fail, rather than using RuntimeError for everything +# XXX Need to use class based exceptions rather than string exceptions + # XXX The UDP version of the protocol resends requests when it does # XXX not receive a timely reply -- use only for idempotent calls! @@ -90,13 +92,13 @@ return (flavor, stuff) def unpack_callheader(self): - xid = self.unpack_uint(xid) + xid = self.unpack_uint() temp = self.unpack_enum() - if temp <> CALL: + if temp != CALL: raise BadRPCFormat, 'no CALL but %r' % (temp,) temp = self.unpack_uint() - if temp <> RPCVERSION: - raise BadRPCVerspion, 'bad RPC version %r' % (temp,) + if temp != RPCVERSION: + raise BadRPCVersion, 'bad RPC version %r' % (temp,) prog = self.unpack_uint() vers = self.unpack_uint() proc = self.unpack_uint() @@ -108,7 +110,7 @@ def unpack_replyheader(self): xid = self.unpack_uint() mtype = self.unpack_enum() - if mtype <> REPLY: + if mtype != REPLY: raise RuntimeError, 'no REPLY but %r' % (mtype,) stat = self.unpack_enum() if stat == MSG_DENIED: @@ -123,7 +125,7 @@ raise RuntimeError, \ 'MSG_DENIED: AUTH_ERROR: %r' % (stat,) raise RuntimeError, 'MSG_DENIED: %r' % (stat,) - if stat <> MSG_ACCEPTED: + if stat != MSG_ACCEPTED: raise RuntimeError, \ 'Neither MSG_DENIED nor MSG_ACCEPTED: %r' % (stat,) verf = self.unpack_auth() @@ -139,7 +141,7 @@ raise RuntimeError, 'call failed: PROC_UNAVAIL' if stat == GARBAGE_ARGS: raise RuntimeError, 'call failed: GARBAGE_ARGS' - if stat <> SUCCESS: + if stat != SUCCESS: raise RuntimeError, 'call failed: %r' % (stat,) return xid, verf # Caller must get procedure-specific part of reply @@ -329,7 +331,7 @@ sock.bind((host, i)) return last_resv_port_tried except socket.error, (errno, msg): - if errno <> 114: + if errno != 114: raise socket.error, (errno, msg) raise RuntimeError, 'can\'t assign reserved port' @@ -348,7 +350,7 @@ u = self.unpacker u.reset(reply) xid, verf = u.unpack_replyheader() - if xid <> self.lastxid: + if xid != self.lastxid: # Can't really happen since this is TCP... raise RuntimeError, 'wrong xid in reply %r instead of %r' % ( xid, self.lastxid) @@ -387,7 +389,7 @@ u = self.unpacker u.reset(reply) xid, verf = u.unpack_replyheader() - if xid <> self.lastxid: + if xid != self.lastxid: ## print 'BAD xid' continue break @@ -443,7 +445,7 @@ u = self.unpacker u.reset(reply) xid, verf = u.unpack_replyheader() - if xid <> self.lastxid: + if xid != self.lastxid: ## print 'BAD xid' continue reply = unpack_func() @@ -678,11 +680,11 @@ xid = self.unpacker.unpack_uint() self.packer.pack_uint(xid) temp = self.unpacker.unpack_enum() - if temp <> CALL: + if temp != CALL: return None # Not worthy of a reply self.packer.pack_uint(REPLY) temp = self.unpacker.unpack_uint() - if temp <> RPCVERSION: + if temp != RPCVERSION: self.packer.pack_uint(MSG_DENIED) self.packer.pack_uint(RPC_MISMATCH) self.packer.pack_uint(RPCVERSION) @@ -691,11 +693,11 @@ self.packer.pack_uint(MSG_ACCEPTED) self.packer.pack_auth((AUTH_NULL, make_auth_null())) prog = self.unpacker.unpack_uint() - if prog <> self.prog: + if prog != self.prog: self.packer.pack_uint(PROG_UNAVAIL) return self.packer.get_buf() vers = self.unpacker.unpack_uint() - if vers <> self.vers: + if vers != self.vers: self.packer.pack_uint(PROG_MISMATCH) self.packer.pack_uint(self.vers) self.packer.pack_uint(self.vers) @@ -812,7 +814,7 @@ def session(self): call, host_port = self.sock.recvfrom(8192) reply = self.handle(call) - if reply <> None: + if reply != None: self.sock.sendto(reply, host_port) From jhylton at users.sourceforge.net Sun Oct 16 07:24:30 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Sun, 16 Oct 2005 07:24:30 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/commontex license.tex, 1.6.4.1, 1.6.4.2 Message-ID: <20051016052430.16A0A1E4009@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/commontex In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27718/Doc/commontex Modified Files: Tag: ast-branch license.tex Log Message: Merge head to branch (for the last time) Index: license.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/commontex/license.tex,v retrieving revision 1.6.4.1 retrieving revision 1.6.4.2 diff -u -d -r1.6.4.1 -r1.6.4.2 --- license.tex 7 Jan 2005 06:56:53 -0000 1.6.4.1 +++ license.tex 16 Oct 2005 05:23:57 -0000 1.6.4.2 @@ -45,6 +45,9 @@ \linev{2.3.2}{2.3.1}{2003}{PSF}{yes} \linev{2.3.3}{2.3.2}{2003}{PSF}{yes} \linev{2.3.4}{2.3.3}{2004}{PSF}{yes} + \linev{2.3.5}{2.3.4}{2005}{PSF}{yes} + \linev{2.4}{2.3}{2004}{PSF}{yes} + \linev{2.4.1}{2.4}{2005}{PSF}{yes} \end{tablev} \note{GPL-compatible doesn't mean that we're distributing From jhylton at users.sourceforge.net Sun Oct 16 07:24:30 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Sun, 16 Oct 2005 07:24:30 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc ACKS, 1.37.2.2, 1.37.2.3 Makefile, 1.244.2.2, 1.244.2.3 Makefile.deps, 1.87.2.2, 1.87.2.3 Message-ID: <20051016052430.162801E4002@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27718/Doc Modified Files: Tag: ast-branch ACKS Makefile Makefile.deps Log Message: Merge head to branch (for the last time) Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ACKS,v retrieving revision 1.37.2.2 retrieving revision 1.37.2.3 diff -u -d -r1.37.2.2 -r1.37.2.3 --- ACKS 7 Jan 2005 06:56:51 -0000 1.37.2.2 +++ ACKS 16 Oct 2005 05:23:56 -0000 1.37.2.3 @@ -23,7 +23,7 @@ A. Amoroso Pehr Anderson Oliver Andrich -Jesús Cea Avión +Jesús Cea Avión Daniel Barclay Chris Barker Don Bashford @@ -54,7 +54,7 @@ Carey Evans Martijn Faassen Carl Feynman -Hernán Martínez Foffani +Hernán Martínez Foffani Stefan Franke Jim Fulton Peter Funk @@ -71,7 +71,7 @@ Mark Hammond Harald Hanche-Olsen Manus Hand -Gerhard Häring +Gerhard Häring Travis B. Hartwell Janko Hauser Bernhard Herzog @@ -108,11 +108,11 @@ Detlef Lannert Piers Lauder Glyph Lefkowitz -Marc-André Lemburg +Marc-André Lemburg Ulf A. Lindgren Everett Lipman Mirko Liss -Martin von Löwis +Martin von Löwis Fredrik Lundh Jeff MacDonald John Machin @@ -136,11 +136,12 @@ William Park Joonas Paalasmaa Harri Pasanen +Bo Peng Tim Peters Christopher Petrilli Justin D. Pettit Chris Phoenix -François Pinard +François Pinard Paul Prescod Eric S. Raymond Edward K. Ream @@ -163,6 +164,7 @@ Justin Sheehy Michael Simcich Ionel Simionescu +Gregory P. Smith Roy Smith Clay Spence Nicholas Spies Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile,v retrieving revision 1.244.2.2 retrieving revision 1.244.2.3 diff -u -d -r1.244.2.2 -r1.244.2.3 --- Makefile 7 Jan 2005 06:56:51 -0000 1.244.2.2 +++ Makefile 16 Oct 2005 05:23:56 -0000 1.244.2.3 @@ -87,7 +87,7 @@ # (e.g. OpenBSD needs package gmake installed; use gmake instead of make) PWD=$(shell pwd) -# (The trailing colon in the value is needed; TeX places it's default +# (The trailing colon in the value is needed; TeX places its default # set of paths at the location of the empty string in the path list.) TEXINPUTS=$(PWD)/commontex: Index: Makefile.deps =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile.deps,v retrieving revision 1.87.2.2 retrieving revision 1.87.2.3 diff -u -d -r1.87.2.2 -r1.87.2.3 --- Makefile.deps 7 Jan 2005 06:56:52 -0000 1.87.2.2 +++ Makefile.deps 16 Oct 2005 05:23:56 -0000 1.87.2.3 @@ -125,6 +125,7 @@ lib/libmarshal.tex \ lib/libwarnings.tex \ lib/libimp.tex \ + lib/libzipimport.tex \ lib/libpkgutil.tex \ lib/libparser.tex \ lib/libbltin.tex \ @@ -163,6 +164,7 @@ lib/libposix.tex \ lib/libposixpath.tex \ lib/libpwd.tex \ + lib/libspwd.tex \ lib/libgrp.tex \ lib/libcrypt.tex \ lib/libdbm.tex \ @@ -200,6 +202,7 @@ lib/librgbimg.tex \ lib/libossaudiodev.tex \ lib/libcrypto.tex \ + lib/libhashlib.tex \ lib/libmd5.tex \ lib/libsha.tex \ lib/libhmac.tex \ From jhylton at users.sourceforge.net Sun Oct 16 07:24:30 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Sun, 16 Oct 2005 07:24:30 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/doc doc.tex, 1.67.2.2, 1.67.2.3 Message-ID: <20051016052430.8E8681E4002@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/doc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27718/Doc/doc Modified Files: Tag: ast-branch doc.tex Log Message: Merge head to branch (for the last time) Index: doc.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/doc/doc.tex,v retrieving revision 1.67.2.2 retrieving revision 1.67.2.3 diff -u -d -r1.67.2.2 -r1.67.2.3 --- doc.tex 7 Jan 2005 06:56:54 -0000 1.67.2.2 +++ doc.tex 16 Oct 2005 05:23:57 -0000 1.67.2.3 @@ -617,7 +617,7 @@ Documentation for a ``simple'' macro. Simple macros are macros which are used for code expansion, but which do not take arguments so cannot be described as functions. This is not to - be used for simple constant definitions. Examples of it's use + be used for simple constant definitions. Examples of its use in the Python documentation include \csimplemacro{PyObject_HEAD} and \csimplemacro{Py_BEGIN_ALLOW_THREADS}. @@ -812,7 +812,7 @@ The name of a ``simple'' macro. Simple macros are macros which are used for code expansion, but which do not take arguments so cannot be described as functions. This is not to - be used for simple constant definitions. Examples of it's use + be used for simple constant definitions. Examples of its use in the Python documentation include \csimplemacro{PyObject_HEAD} and \csimplemacro{Py_BEGIN_ALLOW_THREADS}. @@ -1134,9 +1134,9 @@ \subsection{Module-specific Markup \label{module-markup}} The markup described in this section is used to provide information - about a module being documented. A typical use of this markup - appears at the top of the section used to document a module. A - typical example might look like this: + about a module being documented. Each module should be documented + in its own \macro{section}. A typical use of this markup + appears at the top of that section and might look like this: \begin{verbatim} \section{\module{spam} --- @@ -1878,31 +1878,42 @@ \subsection{Working on Cygwin \label{cygwin}} Installing the required tools under Cygwin under Cygwin can be a - little tedious, if only because many packages are more difficult - to install under Cygwin. + little tedious. Most of the required packages can be installed + using Cygwin's graphical installer, while netpbm and \LaTeX2HTML + must be installed from source. + + Start with a reasonably modern version of Cygwin. If you haven't + upgraded for a few years, now would be a good time. Using the Cygwin installer, make sure your Cygwin installation includes Perl, Python, and the \TeX{} packages. Perl and Python - are located under \menuselection{Interpreters} in the installer. - The \TeX{} packages are located in the \menuselection{Text} - section; installing the \code{tetex-beta}, \code{texmf}, - \code{texmf-base}, and \code{texmf-extra} ensures that all the - required packages are available. (There may be a more minimal - set, but I've not spent time trying to minimize the installation.) + are located under the \menuselection{Interpreters} heading. The + \TeX{} packages are located under the \menuselection{Text} + heading, and are named \code{tetex-*}. To ensure that all + required packages are available, install every \code{tetex} + package, except \code{tetex-x11}. (There may be a more minimal + set, but I've not spent time trying to minimize the installation.) The netpbm package is used by \LaTeX2HTML, and \emph{must} be installed before \LaTeX2HTML can be successfully installed, even - though they will never be used for most Python documentation. - References to download locations are located in the \ulink{netpbm - README}{http://netpbm.sourceforge.net/README}. Install according - to the instructions. + though its features will not be used for most Python + documentation. References to download locations are located in + the \ulink{netpbm README}{http://netpbm.sourceforge.net/README}. + Install from the latest stable source distribution according to + the instructions. (Note that binary packages of netpbm are + sometimes available, but these may not work correctly with + \LaTeX2HTML.) \LaTeX2HTML can be installed from the source archive, but only - after munging one of the files in the distribution. Edit the file - \file{L2hos.pm} in the top level of the unpacked distribution; - near the bottom of the file, change the text - \code{\$\textasciicircum{}O} with the text \code{'unix'}. Proceed - using this command to build and install the software: + after munging one of the files in the distribution. Download the + source archive from the \LaTeX2HTML website + \url{http://www.latex2html.org/} (or one of the many alternate + sites) and unpack it to a build directory. In the top level of + this build directory there will be a file named \file{L2hos.pm}. + Open \file{L2hos.pm} in an editor, and near the bottom of the file + replace the text \code{\$\textasciicircum{}O} with the text + \code{'unix'}. Proceed using this command to build and install + the software: \begin{verbatim} % ./configure && make install From jhylton at users.sourceforge.net Sun Oct 16 07:24:30 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Sun, 16 Oct 2005 07:24:30 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/api abstract.tex, 1.17.2.2, 1.17.2.3 concrete.tex, 1.17.2.2, 1.17.2.3 init.tex, 1.3.2.2, 1.3.2.3 newtypes.tex, 1.13.2.2, 1.13.2.3 refcounts.dat, 1.43.2.1, 1.43.2.2 utilities.tex, 1.5.2.2, 1.5.2.3 Message-ID: <20051016052430.8EF031E4008@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/api In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27718/Doc/api Modified Files: Tag: ast-branch abstract.tex concrete.tex init.tex newtypes.tex refcounts.dat utilities.tex Log Message: Merge head to branch (for the last time) Index: abstract.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/abstract.tex,v retrieving revision 1.17.2.2 retrieving revision 1.17.2.3 diff -u -d -r1.17.2.2 -r1.17.2.3 --- abstract.tex 7 Jan 2005 06:56:52 -0000 1.17.2.2 +++ abstract.tex 16 Oct 2005 05:23:56 -0000 1.17.2.3 @@ -778,12 +778,6 @@ the Python statement \samp{del \var{o}[\var{i1}:\var{i2}]}. \end{cfuncdesc} -\begin{cfuncdesc}{PyObject*}{PySequence_Tuple}{PyObject *o} - Returns the \var{o} as a tuple on success, and \NULL{} on failure. - This is equivalent to the Python expression \samp{tuple(\var{o})}. - \bifuncindex{tuple} -\end{cfuncdesc} - \begin{cfuncdesc}{int}{PySequence_Count}{PyObject *o, PyObject *value} Return the number of occurrences of \var{value} in \var{o}, that is, return the number of keys for which \code{\var{o}[\var{key}] == @@ -811,9 +805,11 @@ \begin{cfuncdesc}{PyObject*}{PySequence_Tuple}{PyObject *o} Return a tuple object with the same contents as the arbitrary - sequence \var{o}. If \var{o} is a tuple, a new reference will be - returned, otherwise a tuple will be constructed with the appropriate - contents. + sequence \var{o} or \NULL{} on failure. If \var{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 \samp{tuple(\var{o})}. + \bifuncindex{tuple} \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PySequence_Fast}{PyObject *o, const char *m} Index: concrete.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/concrete.tex,v retrieving revision 1.17.2.2 retrieving revision 1.17.2.3 diff -u -d -r1.17.2.2 -r1.17.2.3 --- concrete.tex 7 Jan 2005 06:56:52 -0000 1.17.2.2 +++ concrete.tex 16 Oct 2005 05:23:56 -0000 1.17.2.3 @@ -36,20 +36,20 @@ \end{cvardesc} \begin{cfuncdesc}{int}{PyType_Check}{PyObject *o} - Returns true if the object \var{o} is a type object, including - instances of types derived from the standard type object. Returns + Return true if the object \var{o} is a type object, including + instances of types derived from the standard type object. Return false in all other cases. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyType_CheckExact}{PyObject *o} [...1572 lines suppressed...] + +\begin{cfuncdesc}{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 \exception{KeyError} + for missing keys. Raise a \exception{TypeError} if the \var{key} is + unhashable. Unlike the Python \method{discard()} method, this function + does not automatically convert unhashable sets into temporary frozensets. + Raise \exception{PyExc_SystemError} if \var{set} is an not an instance + of \class{set} or its subtype. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PySet_Pop}{PyObject *set} + Return a new reference to an arbitrary object in the \var{set}, + and removes the object from the \var{set}. Return \NULL{} on + failure. Raise \exception{KeyError} if the set is empty. + Raise a \exception{SystemError} if \var{set} is an not an instance + of \class{set} or its subtype. +\end{cfuncdesc} + + Index: init.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/init.tex,v retrieving revision 1.3.2.2 retrieving revision 1.3.2.3 diff -u -d -r1.3.2.2 -r1.3.2.3 --- init.tex 7 Jan 2005 06:56:53 -0000 1.3.2.2 +++ init.tex 16 Oct 2005 05:23:56 -0000 1.3.2.3 @@ -131,6 +131,12 @@ objects may affect the wrong (sub-)interpreter's dictionary of loaded modules. (XXX This is a hard-to-fix bug that will be addressed in a future release.) + + Also note that the use of this functionality is incompatible with + extension modules such as PyObjC and ctypes that use the + \cfunction{PyGILState_*} APIs (and this is inherent in the way the + \cfunction{PyGILState_*} functions work). Simple things may work, + but confusing behavior will always be near. \end{cfuncdesc} \begin{cfuncdesc}{void}{Py_EndInterpreter}{PyThreadState *tstate} @@ -239,9 +245,8 @@ program name (set by \cfunction{Py_SetProgramName()} above) and some environment variables. The returned string consists of a series of directory names separated by a platform dependent delimiter - character. The delimiter character is \character{:} on \UNIX, - \character{;} on Windows, and \character{\e n} (the \ASCII{} - newline character) on Macintosh. The returned string points into + character. The delimiter character is \character{:} on \UNIX and Mac OS X, + \character{;} on Windows. The returned string points into static storage; the caller should not modify its value. The value is available to Python code as the list \code{sys.path}\withsubitem{(in module sys)}{\ttindex{path}}, which @@ -272,7 +277,7 @@ this is formed from the ``official'' name of the operating system, converted to lower case, followed by the major revision number; e.g., for Solaris 2.x, which is also known as SunOS 5.x, the value - is \code{'sunos5'}. On Macintosh, it is \code{'mac'}. On Windows, + is \code{'sunos5'}. On Mac OS X, it is \code{'darwin'}. On Windows, it is \code{'win'}. The returned string points into static storage; the caller should not modify its value. The value is available to Python code as \code{sys.platform}. @@ -455,19 +460,10 @@ pointer, release the lock, and finally free their thread state data structure. -When creating a thread data structure, you need to provide an -interpreter state data structure. The interpreter state data -structure holds global data that is shared by all threads in an -interpreter, for example the module administration -(\code{sys.modules}). Depending on your needs, you can either create -a new interpreter state data structure, or share the interpreter state -data structure used by the Python main thread (to access the latter, -you must obtain the thread state and access its \member{interp} member; -this must be done by a thread that is created by Python or by the main -thread after Python is initialized). - -Assuming you have access to an interpreter object, the typical idiom -for calling into Python from a C thread is +Beginning with version 2.3, threads can now take advantage of the +\cfunction{PyGILState_*()} functions to do all of the above +automatically. The typical idiom for calling into Python from a C +thread is now: \begin{verbatim} PyGILState_STATE gstate; @@ -481,6 +477,13 @@ PyGILState_Release(gstate); \end{verbatim} +Note that the \cfunction{PyGILState_*()} functions assume there is +only one global interpreter (created automatically by +\cfunction{Py_Initialize()}). Python still supports the creation of +additional interpreters (using \cfunction{Py_NewInterpreter()}), but +mixing multiple interpreters and the \cfunction{PyGILState_*()} API is +unsupported. + \begin{ctypedesc}{PyInterpreterState} This data structure represents the state shared by a number of cooperating threads. Threads belonging to the same interpreter @@ -700,16 +703,16 @@ \end{cfuncdesc} \begin{cfuncdesc}{PyGILState_STATE}{PyGILState_Ensure}{} -Ensure that the current thread is ready to call the Python -C API regardless of the current state of Python, or of its -thread lock. This may be called as many times as desired -by a thread as long as each call is matched with a call to -\cfunction{PyGILState_Release()}. -In general, other thread-related APIs may -be used between \cfunction{PyGILState_Ensure()} and \cfunction{PyGILState_Release()} calls as long as the -thread state is restored to its previous state before the Release(). -For example, normal usage of the \csimplemacro{Py_BEGIN_ALLOW_THREADS} -and \csimplemacro{Py_END_ALLOW_THREADS} macros is acceptable. +Ensure that the current thread is ready to call the Python C API +regardless of the current state of Python, or of its thread lock. +This may be called as many times as desired by a thread as long as +each call is matched with a call to \cfunction{PyGILState_Release()}. +In general, other thread-related APIs may be used between +\cfunction{PyGILState_Ensure()} and \cfunction{PyGILState_Release()} +calls as long as the thread state is restored to its previous state +before the Release(). For example, normal usage of the +\csimplemacro{Py_BEGIN_ALLOW_THREADS} and +\csimplemacro{Py_END_ALLOW_THREADS} macros is acceptable. The return value is an opaque "handle" to the thread state when \cfunction{PyGILState_Acquire()} was called, and must be passed to Index: newtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/newtypes.tex,v retrieving revision 1.13.2.2 retrieving revision 1.13.2.3 diff -u -d -r1.13.2.2 -r1.13.2.3 --- newtypes.tex 7 Jan 2005 06:56:53 -0000 1.13.2.2 +++ newtypes.tex 16 Oct 2005 05:23:56 -0000 1.13.2.3 @@ -191,7 +191,7 @@ int ob_size; \end{verbatim} Note that \csimplemacro{PyObject_HEAD} is part of the expansion, and - that it's own expansion varies depending on the definition of + that its own expansion varies depending on the definition of \csimplemacro{Py_TRACE_REFS}. \end{csimplemacrodesc} @@ -1106,6 +1106,13 @@ \begin{cmemberdesc}{PyTypeObject}{descrgetfunc}{tp_descr_get} An optional pointer to a "descriptor get" function. + + The function signature is + +\begin{verbatim} +PyObject * tp_descr_get(PyObject *self, PyObject *obj, PyObject *type); +\end{verbatim} + XXX blah, blah. This field is inherited by subtypes. @@ -1114,9 +1121,16 @@ \begin{cmemberdesc}{PyTypeObject}{descrsetfunc}{tp_descr_set} An optional pointer to a "descriptor set" function. - XXX blah, blah. + The function signature is + +\begin{verbatim} +int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value); +\end{verbatim} This field is inherited by subtypes. + + XXX blah, blah. + \end{cmemberdesc} \begin{cmemberdesc}{PyTypeObject}{long}{tp_dictoffset} Index: refcounts.dat =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/refcounts.dat,v retrieving revision 1.43.2.1 retrieving revision 1.43.2.2 diff -u -d -r1.43.2.1 -r1.43.2.2 --- refcounts.dat 28 Apr 2003 17:38:11 -0000 1.43.2.1 +++ refcounts.dat 16 Oct 2005 05:23:57 -0000 1.43.2.2 @@ -1009,6 +1009,24 @@ PySequence_Tuple:PyObject*::+1: PySequence_Tuple:PyObject*:o:0: +PySet_Append:int::: +PySet_Append:PyObject*:set:0: +PySet_Append:PyObject*:key:+1: + +PySet_Contains:int::: +PySet_Contains:PyObject*:anyset:0: +PySet_Contains:PyObject*:key:0: + +PySet_Discard:int::: +PySet_Discard:PyObject*:set:0: +PySet_Discard:PyObject*:key:-1:no effect if key not found + +PySet_Pop:PyObject*::0:or returns NULL and raises KeyError if set is empty +PySet_Pop:PyObject*:set:0: + +PySet_Size:int::: +PySet_Size:PyObject*:anyset:0: + PySlice_Check:int::: PySlice_Check:PyObject*:ob:0: Index: utilities.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/utilities.tex,v retrieving revision 1.5.2.2 retrieving revision 1.5.2.3 diff -u -d -r1.5.2.2 -r1.5.2.3 --- utilities.tex 7 Jan 2005 06:56:53 -0000 1.5.2.2 +++ utilities.tex 16 Oct 2005 05:23:57 -0000 1.5.2.3 @@ -34,7 +34,7 @@ Return true when the interpreter runs out of stack space. This is a reliable check, but is only available when \constant{USE_STACKCHECK} is defined (currently on Windows using the Microsoft Visual \Cpp{} - compiler and on the Macintosh). \constant{USE_CHECKSTACK} will be + compiler). \constant{USE_STACKCHECK} will be defined automatically; you should never change the definition in your own code. \end{cfuncdesc} @@ -539,7 +539,7 @@ Convert a Python integer to a C \ctype{long int}. \item[\samp{k} (integer) {[unsigned long]}] - Convert a Python integer to a C \ctype{unsigned long} without + Convert a Python integer or long integer to a C \ctype{unsigned long} without overflow checking. \versionadded{2.3} \item[\samp{L} (integer) {[PY_LONG_LONG]}] @@ -548,7 +548,7 @@ \ctype{_int64} on Windows). \item[\samp{K} (integer) {[unsigned PY_LONG_LONG]}] - Convert a Python integer to a C \ctype{unsigned long long} + Convert a Python integer or long 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). \versionadded{2.3} From jhylton at users.sourceforge.net Sun Oct 16 07:24:30 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Sun, 16 Oct 2005 07:24:30 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/ext extending.tex, 1.21.2.2, 1.21.2.3 noddy2.c, 1.5.6.1, 1.5.6.2 run-func.c, 1.2.16.1, 1.2.16.2 Message-ID: <20051016052430.A3A0A1E4009@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/ext In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27718/Doc/ext Modified Files: Tag: ast-branch extending.tex noddy2.c run-func.c Log Message: Merge head to branch (for the last time) Index: extending.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ext/extending.tex,v retrieving revision 1.21.2.2 retrieving revision 1.21.2.3 diff -u -d -r1.21.2.2 -r1.21.2.3 --- extending.tex 7 Jan 2005 06:57:02 -0000 1.21.2.2 +++ extending.tex 16 Oct 2005 05:23:57 -0000 1.21.2.3 @@ -374,7 +374,7 @@ \cdata{_PyImport_Inittab} table. The easiest way to handle this is to statically initialize your statically-linked modules by directly calling \cfunction{initspam()} after the call to -\cfunction{Py_Initialize()} or \cfunction{PyMac_Initialize()}: +\cfunction{Py_Initialize()}: \begin{verbatim} int @@ -426,7 +426,6 @@ (chapter \ref{building}) and additional information that pertains only to building on Windows (chapter \ref{building-on-windows}) for more information about this. -% XXX Add information about Mac OS If you can't use dynamic loading, or if you want to make your module a permanent part of the Python interpreter, you will have to change the @@ -1307,7 +1306,7 @@ /* C API functions */ #define PySpam_System_NUM 0 #define PySpam_System_RETURN int -#define PySpam_System_PROTO (char *command) +#define PySpam_System_PROTO (const char *command) /* Total number of C API pointers */ #define PySpam_API_pointers 1 Index: noddy2.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ext/noddy2.c,v retrieving revision 1.5.6.1 retrieving revision 1.5.6.2 diff -u -d -r1.5.6.1 -r1.5.6.2 --- noddy2.c 7 Jan 2005 06:57:02 -0000 1.5.6.1 +++ noddy2.c 16 Oct 2005 05:23:57 -0000 1.5.6.2 @@ -3,8 +3,8 @@ typedef struct { PyObject_HEAD - PyObject *first; - PyObject *last; + PyObject *first; /* first name */ + PyObject *last; /* last name */ int number; } Noddy; Index: run-func.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ext/run-func.c,v retrieving revision 1.2.16.1 retrieving revision 1.2.16.2 diff -u -d -r1.2.16.1 -r1.2.16.2 --- run-func.c 28 Apr 2003 17:38:05 -0000 1.2.16.1 +++ run-func.c 16 Oct 2005 05:23:57 -0000 1.2.16.2 @@ -20,11 +20,8 @@ Py_DECREF(pName); if (pModule != NULL) { - pDict = PyModule_GetDict(pModule); - /* pDict is a borrowed reference */ - - pFunc = PyDict_GetItemString(pDict, argv[2]); - /* pFun: Borrowed reference */ + pFunc = PyDict_GetItemString(pModule, argv[2]); + /* pFunc is a new reference */ if (pFunc && PyCallable_Check(pFunc)) { pArgs = PyTuple_New(argc - 3); @@ -46,18 +43,19 @@ Py_DECREF(pValue); } else { + Py_DECREF(pFunc); Py_DECREF(pModule); PyErr_Print(); fprintf(stderr,"Call failed\n"); return 1; } - /* pDict and pFunc are borrowed and must not be Py_DECREF-ed */ } else { if (PyErr_Occurred()) PyErr_Print(); fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]); } + Py_XDECREF(pFunc); Py_DECREF(pModule); } else { From jhylton at users.sourceforge.net Sun Oct 16 07:24:30 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Sun, 16 Oct 2005 07:24:30 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/dist dist.tex, 1.42.2.2, 1.42.2.3 Message-ID: <20051016052430.B2E8C1E400C@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/dist In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27718/Doc/dist Modified Files: Tag: ast-branch dist.tex Log Message: Merge head to branch (for the last time) Index: dist.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/dist/dist.tex,v retrieving revision 1.42.2.2 retrieving revision 1.42.2.3 diff -u -d -r1.42.2.2 -r1.42.2.3 --- dist.tex 7 Jan 2005 06:56:53 -0000 1.42.2.2 +++ dist.tex 16 Oct 2005 05:23:57 -0000 1.42.2.3 @@ -25,6 +25,9 @@ \begin{document} \maketitle + +\input{copyright} + \begin{abstract} \noindent This document describes the Python Distribution Utilities @@ -298,7 +301,7 @@ current platform before actually using the pathname. This makes your setup script portable across operating systems, which of course is one of the major goals of the Distutils. In this spirit, all pathnames in -this document are slash-separated. (Mac OS programmers should keep in +this document are slash-separated. (Mac OS 9 programmers should keep in mind that the \emph{absence} of a leading slash indicates a relative path, the opposite of the Mac OS convention with colons.) @@ -403,7 +406,7 @@ with, etc.). All of this is done through another keyword argument to -\function{setup()}, the \option{extensions} option. \option{extensions} +\function{setup()}, the \option{ext_modules} option. \option{ext_modules} is just a list of \class{Extension} instances, each of which describes a single extension module. Suppose your distribution includes a single extension, called \module{foo} and implemented by \file{foo.c}. If no @@ -631,7 +634,83 @@ will automatically add \code{initmodule} to the list of exported symbols. +\section{Relationships between Distributions and Packages} + +A distribution may relate to packages in three specific ways: + +\begin{enumerate} + \item It can require packages or modules. + + \item It can provide packages or modules. + + \item It can obsolete packages or modules. +\end{enumerate} + +These relationships can be specified using keyword arguments to the +\function{distutils.core.setup()} function. + +Dependencies on other Python modules and packages can be specified by +supplying the \var{requires} keyword argument to \function{setup()}. +The value must be a list of strings. Each string specifies a package +that is required, and optionally what versions are sufficient. + +To specify that any version of a module or package is required, the +string should consist entirely of the module or package name. +Examples include \code{'mymodule'} and \code{'xml.parsers.expat'}. + +If specific versions are required, a sequence of qualifiers can be +supplied in parentheses. Each qualifier may consist of a comparison +operator and a version number. The accepted comparison operators are: + +\begin{verbatim} +< > == +<= >= != +\end{verbatim} + +These can be combined by using multiple qualifiers separated by commas +(and optional whitespace). In this case, all of the qualifiers must +be matched; a logical AND is used to combine the evaluations. + +Let's look at a bunch of examples: + +\begin{tableii}{l|l}{code}{Requires Expression}{Explanation} + \lineii{==1.0} {Only version \code{1.0} is compatible} + \lineii{>1.0, !=1.5.1, <2.0} {Any version after \code{1.0} and before + \code{2.0} is compatible, except + \code{1.5.1}} +\end{tableii} + +Now that we can specify dependencies, we also need to be able to +specify what we provide that other distributions can require. This is +done using the \var{provides} keyword argument to \function{setup()}. +The value for this keyword is a list of strings, each of which names a +Python module or package, and optionally identifies the version. If +the version is not specified, it is assumed to match that of the +distribution. + +Some examples: + +\begin{tableii}{l|l}{code}{Provides Expression}{Explanation} + \lineii{mypkg} {Provide \code{mypkg}, using the distribution version} + \lineii{mypkg (1.1} {Provide \code{mypkg} version 1.1, regardless of the + distribution version} +\end{tableii} + +A package can declare that it obsoletes other packages using the +\var{obsoletes} keyword argument. The value for this is similar to +that of the \var{requires} keyword: a list of strings giving module or +package specifiers. Each specifier consists of a module or package +name optionally followed by one or more version qualifiers. Version +qualifiers are given in parentheses after the module or package name. + +The versions identified by the qualifiers are those that are obsoleted +by the distribution being described. If no qualifiers are given, all +versions of the named module or package are understood to be +obsoleted. + + \section{Installing Scripts} + So far we have been dealing with pure and non-pure Python modules, which are usually not run by themselves but imported by scripts. @@ -1021,7 +1100,6 @@ script or config file), \command{sdist} creates the archive of the default format for the current platform. The default format is a gzip'ed tar file (\file{.tar.gz}) on \UNIX, and ZIP file on Windows. -\XXX{no Mac OS support here} You can specify as many formats as you like using the \longprogramopt{formats} option, for example: @@ -1579,7 +1657,7 @@ iconpath\optional{, iconindex}}}}} This function creates a shortcut. \var{target} is the path to the program to be started by the shortcut. - \var{description} is the description of the sortcut. + \var{description} is the description of the shortcut. \var{filename} is the title of the shortcut that the user will see. \var{arguments} specifies the command line arguments, if any. \var{workdir} is the working directory for the program. @@ -1640,7 +1718,43 @@ versions, the Hidden property should be set to yes. This must be edited through the web interface. +\section{The .pypirc file} +\label{pypirc} + +The format of the \file{.pypirc} file is formated as follows: + +\begin{verbatim} +[server-login] +repository: +username: +password: +\end{verbatim} + +\var{repository} can be ommitted and defaults to +\code{http://www.python.org/pypi}. + +\chapter{Uploading Packages to the Package Index} +\label{package-upload} + +The Python Package Index (PyPI) not only stores the package info, but also +the package data if the author of the package wishes to. The distutils +command \command{upload} pushes the distribution files to PyPI. + +The command is invoked immediately after building one or more distribution +files. For example, the command +\begin{verbatim} +python setup.py sdist bdist_wininst upload +\end{verbatim} + +will cause the source distribution and the Windows installer to be +uploaded to PyPI. Note that these will be uploaded even if they are +built using an earlier invocation of \file{setup.py}, but that only +distributions named on the command line for the invocation including +the \command{upload} command are uploaded. + +The \command{upload} command uses the username and password stored in +the file \file{\$HOME/.pypirc}, see section~\ref{pypirc}. \chapter{Examples} \label{examples} @@ -1980,6 +2094,14 @@ implemented by the class \class{distcmds.bdist_openpkg.bdist_openpkg} or \class{buildcmds.bdist_openpkg.bdist_openpkg}. +\section{Adding new distribution types} + +Commands that create distributions (files in the \file{dist/} +directory) need to add \code{(\var{command}, \var{filename})} pairs to +\code{self.distribution.dist_files} so that \command{upload} can +upload it to PyPI. The \var{filename} in the pair contains no path +information, only the name of the file itself. In dry-run mode, pairs +should still be added to represent what would have been created. \chapter{Command Reference} \label{reference} @@ -2059,9 +2181,9 @@ characters in \var{range} (e.g., \code{a-z}, \code{a-zA-Z}, \code{a-f0-9\_.}). The definition of ``regular filename character'' is platform-specific: on \UNIX{} it is anything except slash; on Windows -anything except backslash or colon; on Mac OS anything except colon. +anything except backslash or colon; on Mac OS 9 anything except colon. -\XXX{Windows and Mac OS support not there yet} +\XXX{Windows support not there yet} %\section{Creating a built distribution: the @@ -2135,9 +2257,9 @@ the contents of the config files or command-line. \var{script_name} is a file that will be run with \function{execfile()} -\var{sys.argv[0]} will be replaced with \var{script} for the duration of the +\code{sys.argv[0]} will be replaced with \var{script} for the duration of the call. \var{script_args} is a list of strings; if supplied, -\var{sys.argv[1:]} will be replaced by \var{script_args} for the duration +\code{sys.argv[1:]} will be replaced by \var{script_args} for the duration of the call. \var{stop_after} tells \function{setup()} when to stop processing; possible @@ -2172,7 +2294,7 @@ \begin{classdesc*}{Extension} The Extension class describes a single C or \Cpp extension module in a -setup script. It accepts the following keyword arguments in it's +setup script. It accepts the following keyword arguments in its constructor \begin{tableiii}{c|l|l}{argument name}{argument name}{value}{type} @@ -2232,7 +2354,7 @@ \end{classdesc*} \begin{classdesc*}{Command} -A \class{Command} class (or rather, an instance of one of it's subclasses) +A \class{Command} class (or rather, an instance of one of its subclasses) implement a single distutils command. \end{classdesc*} @@ -2258,22 +2380,24 @@ \end{funcdesc} \begin{funcdesc}{gen_preprocess_options}{macros, include_dirs} -Generate C pre-processor options (-D, -U, -I) as used by at least +Generate C pre-processor options (\programopt{-D}, \programopt{-U}, +\programopt{-I}) as used by at least two types of compilers: the typical \UNIX{} compiler and Visual \Cpp. -\var{macros} is the usual thing, a list of 1- or 2-tuples, where \var{(name,)} -means undefine (-U) macro \var{name}, and \var{(name,value)} means define (-D) -macro \var{name} to \var{value}. \var{include_dirs} is just a list of directory -names to be added to the header file search path (-I). Returns a list -of command-line options suitable for either \UNIX{} compilers or Visual -\Cpp. +\var{macros} is the usual thing, a list of 1- or 2-tuples, where +\code{(\var{name},)} means undefine (\programopt{-U}) macro \var{name}, +and \code{(\var{name}, \var{value})} means define (\programopt{-D}) +macro \var{name} to \var{value}. \var{include_dirs} is just a list of +directory names to be added to the header file search path (\programopt{-I}). +Returns a list of command-line options suitable for either \UNIX{} compilers +or Visual \Cpp. \end{funcdesc} \begin{funcdesc}{get_default_compiler}{osname, platform} Determine the default compiler to use for the given platform. -\var{osname} should be one of the standard Python OS names (i.e. the -ones returned by \var{os.name}) and \var{platform} the common value -returned by \var{sys.platform} for the platform in question. +\var{osname} should be one of the standard Python OS names (i.e.\ the +ones returned by \code{os.name}) and \var{platform} the common value +returned by \code{sys.platform} for the platform in question. The default values are \code{os.name} and \code{sys.platform} in case the parameters are not given. @@ -2319,7 +2443,7 @@ (don't actually execute the steps) and \var{force} (rebuild everything, regardless of dependencies). All of these flags default to \code{0} (off). Note that you probably don't want to instantiate -\class{CCompiler} or one of it's subclasses directly - use the +\class{CCompiler} or one of its subclasses directly - use the \function{distutils.CCompiler.new_compiler()} factory function instead. @@ -2505,7 +2629,8 @@ \file{build/foo/bar.o}. \var{macros}, if given, must be a list of macro definitions. A macro -definition is either a \var{(name, value)} 2-tuple or a \var{(name,)} 1-tuple. +definition is either a \code{(\var{name}, \var{value})} 2-tuple or a +\code{(\var{name},)} 1-tuple. The former defines a macro; if the value is \code{None}, the macro is defined without an explicit value. The 1-tuple case undefines a macro. Later definitions/redefinitions/undefinitions take @@ -2518,7 +2643,7 @@ \var{debug} is a boolean; if true, the compiler will be instructed to output debug symbols in (or alongside) the object file(s). -\var{extra_preargs} and \var{extra_postargs} are implementation- dependent. +\var{extra_preargs} and \var{extra_postargs} are implementation-dependent. On platforms that have the notion of a command-line (e.g. \UNIX, DOS/Windows), they are most likely lists of strings: extra command-line arguments to prepend/append to the compiler command @@ -2759,7 +2884,8 @@ \modulesynopsis{Metrowerks CodeWarrior support} Contains \class{MWerksCompiler}, an implementation of the abstract -\class{CCompiler} class for MetroWerks CodeWarrior on the Macintosh. Needs work to support CW on Windows. +\class{CCompiler} class for MetroWerks CodeWarrior on the pre-Mac OS X Macintosh. +Needs work to support CW on Windows or Mac OS X. %\subsection{Utility modules} @@ -2791,8 +2917,8 @@ \end{funcdesc} \begin{funcdesc}{make_tarball}{base_name, base_dir\optional{, compress=\code{'gzip'}, verbose=\code{0}, dry_run=\code{0}}}'Create an (optional compressed) archive as a tar file from all files in and under \var{base_dir}. \var{compress} must be \code{'gzip'} (the default), -\code{'compress'}, \code{'bzip2'}, or \code{None}. Both \code{'tar'} -and the compression utility named by \var{'compress'} must be on the +\code{'compress'}, \code{'bzip2'}, or \code{None}. Both \program{tar} +and the compression utility named by \var{compress} must be on the default program search path, so this is probably \UNIX-specific. The output tar file will be named \file{\var{base_dir}.tar}, possibly plus the appropriate compression extension (\file{.gz}, \file{.bz2} or @@ -2881,7 +3007,7 @@ Copy an entire directory tree \var{src} to a new location \var{dst}. Both \var{src} and \var{dst} must be directory names. If \var{src} is not a directory, raise \exception{DistutilsFileError}. If \var{dst} does -not exist, it is created with \var{mkpath()}. The end result of the +not exist, it is created with \function{mkpath()}. The end result of the copy is that every file in \var{src} is copied to \var{dst}, and directories under \var{src} are recursively copied to \var{dst}. Return the list of files that were copied or might have been copied, @@ -2901,7 +3027,7 @@ \begin{funcdesc}{remove_tree}{directory\optional{verbose=\code{0}, dry_run=\code{0}}} Recursively remove \var{directory} and all files and directories underneath -it. Any errors are ignored (apart from being reported to \code{stdout} if +it. Any errors are ignored (apart from being reported to \code{sys.stdout} if \var{verbose} is true). \end{funcdesc} @@ -2929,7 +3055,7 @@ to \code{'hard'} or \code{'sym'}; if it is \code{None} (the default), files are copied. Don't set \var{link} on systems that don't support it: \function{copy_file()} doesn't check if hard or symbolic linking is -available. It uses \var{_copy_file_contents()} to copy file contents. +available. It uses \function{_copy_file_contents()} to copy file contents. Return a tuple \samp{(dest_name, copied)}: \var{dest_name} is the actual name of the output file, and \var{copied} is true if the file was copied @@ -2999,7 +3125,7 @@ Return \var{pathname} with \var{new_root} prepended. If \var{pathname} is relative, this is equivalent to \samp{os.path.join(new_root,pathname)} Otherwise, it requires making \var{pathname} relative and then joining the -two, which is tricky on DOS/Windows and Mac OS. +two, which is tricky on DOS/Windows. \end{funcdesc} \begin{funcdesc}{check_environ}{} @@ -3197,7 +3323,7 @@ The option_table is a list of 3-tuples: \samp{(long_option, short_option, help_string)} -If an option takes an argument, it's \var{long_option} should have \code{'='} +If an option takes an argument, its \var{long_option} should have \code{'='} appended; \var{short_option} should just be a single character, no \code{':'} in any case. \var{short_option} should be \code{None} if a \var{long_option} doesn't have a corresponding \var{short_option}. All option tuples must have @@ -3294,11 +3420,11 @@ something that provides \method{readline()} and \method{close()} methods). It is recommended that you supply at least \var{filename}, so that \class{TextFile} can include it in warning messages. If -\var{file} is not supplied, TextFile creates its own using the -\var{open()} builtin. +\var{file} is not supplied, \class{TextFile} creates its own using the +\function{open()} built-in function. The options are all boolean, and affect the values returned by -\var{readline()} +\method{readline()} \begin{tableiii}{c|l|l}{option name}{option name}{description}{default} \lineiii{strip_comments}{ From jhylton at users.sourceforge.net Sun Oct 16 07:24:30 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Sun, 16 Oct 2005 07:24:30 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/inst inst.tex, 1.40.2.2, 1.40.2.3 Message-ID: <20051016052430.D17D61E4010@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/inst In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27718/Doc/inst Modified Files: Tag: ast-branch inst.tex Log Message: Merge head to branch (for the last time) Index: inst.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/inst/inst.tex,v retrieving revision 1.40.2.2 retrieving revision 1.40.2.3 diff -u -d -r1.40.2.2 -r1.40.2.3 --- inst.tex 7 Jan 2005 06:57:03 -0000 1.40.2.2 +++ inst.tex 16 Oct 2005 05:23:57 -0000 1.40.2.3 @@ -142,7 +142,7 @@ On \UNIX, you'd run this command from a shell prompt; on Windows, you have to open a command prompt window (``DOS box'') and do it there; on -Mac OS, things are a tad more complicated (see below). +Mac OS X, you open a \command{Terminal} window to get a shell prompt. \subsection{Platform variations} @@ -262,7 +262,8 @@ \code{setup.py install}---then the \command{install} command installs to the standard location for third-party Python modules. This location varies by platform and by how you built/installed Python itself. On -\UNIX{} and Mac OS, it also depends on whether the module distribution +\UNIX{} (and Mac OS X, which is also Unix-based), +it also depends on whether the module distribution being installed is pure Python or contains extensions (``non-pure''): \begin{tableiv}{l|l|l|c}{textrm}% {Platform}{Standard installation location}{Default value}{Notes} @@ -278,14 +279,6 @@ {\filenq{\filevar{prefix}}} {\filenq{C:\textbackslash{}Python}} {(2)} - \lineiv{Mac OS (pure)} - {\filenq{\filevar{prefix}:Lib:site-packages}} - {\filenq{Python:Lib:site-packages}} - {} - \lineiv{Mac OS (non-pure)} - {\filenq{\filevar{prefix}:Lib:site-packages}} - {\filenq{Python:Lib:site-packages}} - {} \end{tableiv} \noindent Notes: @@ -302,8 +295,8 @@ \filevar{prefix} and \filevar{exec-prefix} stand for the directories that Python is installed to, and where it finds its libraries at -run-time. They are always the same under Windows and Mac OS, and very -often the same under \UNIX. You can find out what your Python +run-time. They are always the same under Windows, and very +often the same under \UNIX and Mac OS X. You can find out what your Python installation uses for \filevar{prefix} and \filevar{exec-prefix} by running Python in interactive mode and typing a few simple commands. Under \UNIX, just type \code{python} at the shell prompt. Under @@ -658,7 +651,7 @@ variables supplied by the Distutils are the only ones you can use.) See section~\ref{config-files} for details. -% XXX need some Windows and Mac OS examples---when would custom +% XXX need some Windows examples---when would custom % installation schemes be needed on those platforms? @@ -764,8 +757,8 @@ \label{config-filenames} The names and locations of the configuration files vary slightly across -platforms. On \UNIX, the three configuration files (in the order they -are processed) are: +platforms. On \UNIX{} and Mac OS X, the three configuration files (in +the order they are processed) are: \begin{tableiii}{l|l|c}{textrm} {Type of file}{Location and filename}{Notes} \lineiii{system}{\filenq{\filevar{prefix}/lib/python\filevar{ver}/distutils/distutils.cfg}}{(1)} @@ -773,7 +766,7 @@ \lineiii{local}{\filenq{setup.cfg}}{(3)} \end{tableiii} -On Windows, the configuration files are: +And on Windows, the configuration files are: \begin{tableiii}{l|l|c}{textrm} {Type of file}{Location and filename}{Notes} \lineiii{system}{\filenq{\filevar{prefix}\textbackslash{}Lib\textbackslash{}distutils\textbackslash{}distutils.cfg}}{(4)} @@ -781,14 +774,6 @@ \lineiii{local}{\filenq{setup.cfg}}{(3)} \end{tableiii} -And on Mac OS, they are: -\begin{tableiii}{l|l|c}{textrm} - {Type of file}{Location and filename}{Notes} - \lineiii{system}{\filenq{\filevar{prefix}:Lib:distutils:distutils.cfg}}{(6)} - \lineiii{personal}{N/A}{} - \lineiii{local}{\filenq{setup.cfg}}{(3)} -\end{tableiii} - \noindent Notes: \begin{description} \item[(1)] Strictly speaking, the system-wide configuration file lives @@ -818,9 +803,6 @@ defined, no personal configuration file will be found or used. (In other words, the Distutils make no attempt to guess your home directory on Windows.) -\item[(6)] (See also notes (1) and (4).) The default installation - prefix is just \file{Python:}, so under Python 1.6 and later this is - normally\file{Python:Lib:distutils:distutils.cfg}. \end{description} From jhylton at users.sourceforge.net Sun Oct 16 07:24:31 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Sun, 16 Oct 2005 07:24:31 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/perl l2hinit.perl, 1.63.2.2, 1.63.2.3 Message-ID: <20051016052431.525A91E4008@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/perl In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27718/Doc/perl Modified Files: Tag: ast-branch l2hinit.perl Log Message: Merge head to branch (for the last time) Index: l2hinit.perl =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/perl/l2hinit.perl,v retrieving revision 1.63.2.2 retrieving revision 1.63.2.3 diff -u -d -r1.63.2.2 -r1.63.2.3 --- l2hinit.perl 7 Jan 2005 06:57:32 -0000 1.63.2.2 +++ l2hinit.perl 16 Oct 2005 05:23:58 -0000 1.63.2.3 @@ -98,7 +98,7 @@ $dir =~ s/$dd$//; $TEXINPUTS = "$dir$envkey$mytexinputs"; # Push everything into $TEXINPUTS since LaTeX2HTML doesn't pick - # this up on it's own; we clear $ENV{'TEXINPUTS'} so the value set + # this up on its own; we clear $ENV{'TEXINPUTS'} so the value set # for this by the main LaTeX2HTML script doesn't contain duplicate # directories. if ($ENV{'TEXINPUTS'}) { From jhylton at users.sourceforge.net Sun Oct 16 07:24:31 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Sun, 16 Oct 2005 07:24:31 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/tools getpagecounts, 1.8.2.1, 1.8.2.2 mkpkglist, 1.1.8.2, 1.1.8.3 py2texi.el, 1.2.2.2, 1.2.2.3 Message-ID: <20051016052431.035AC1E4015@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27718/Doc/tools Modified Files: Tag: ast-branch getpagecounts mkpkglist py2texi.el Log Message: Merge head to branch (for the last time) Index: getpagecounts =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/getpagecounts,v retrieving revision 1.8.2.1 retrieving revision 1.8.2.2 diff -u -d -r1.8.2.1 -r1.8.2.2 --- getpagecounts 7 Jan 2005 06:57:36 -0000 1.8.2.1 +++ getpagecounts 16 Oct 2005 05:23:58 -0000 1.8.2.2 @@ -65,7 +65,7 @@ of it! To locate published copies of the larger manuals, or other Python reference material, consult the Python Bookstore at: - http://www.python.org/cgi-bin/moinmoin/PythonBooks + http://wiki.python.org/moin/PythonBooks The following manuals are included in this package: """ Index: mkpkglist =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/mkpkglist,v retrieving revision 1.1.8.2 retrieving revision 1.1.8.3 diff -u -d -r1.1.8.2 -r1.1.8.3 --- mkpkglist 7 Jan 2005 06:57:37 -0000 1.1.8.2 +++ mkpkglist 16 Oct 2005 05:23:58 -0000 1.1.8.3 @@ -67,14 +67,17 @@ have_tgz = isfile(tgz_fn) have_bz2 = isfile(bz2_fn) - if have_zip or have_tgz or have_bz2: - print " %s" % name - - print get_file_cell(prefix, ".zip", have_zip) - print get_file_cell(prefix, ".tgz", have_tgz) - print get_file_cell(prefix, ".tar.bz2", have_bz2) + have_some = have_zip or have_tgz or have_bz2 - print " " + if not have_some: + print " " print '''\ Index: py2texi.el =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/py2texi.el,v retrieving revision 1.2.2.2 retrieving revision 1.2.2.3 diff -u -d -r1.2.2.2 -r1.2.2.3 --- py2texi.el 7 Jan 2005 06:57:37 -0000 1.2.2.2 +++ py2texi.el 16 Oct 2005 05:23:58 -0000 1.2.2.3 @@ -238,7 +238,7 @@ ("dataline" 1 (progn (setq findex t) "@item \\1\n at findex \\1\n")) ("date" 1 "\\1") ("declaremodule" 2 (progn (setq cindex t) "@label{\\2}@cindex{\\2}")) - ("deprecated" 2 "@emph{This is deprecated in Python \\1. \\2}") + ("deprecated" 2 "@emph{This is deprecated in Python \\1. \\2}\n\n") ("dfn" 1 "@dfn{\\1}") ("documentclass" 1 py2texi-magic) ("e" 0 "@backslash{}") @@ -260,6 +260,7 @@ ("funclineni" 2 "@item \\1 \\2") ("function" 1 "@code{\\1}") ("grammartoken" 1 "@code{\\1}") + ("guilabel" 1 "@strong{\\1}") ("hline" 0 "") ("ifhtml" 0 (concat "@" (setq last-if "ifinfo"))) ("iftexi" 0 (concat "@" (setq last-if "ifinfo"))) @@ -278,6 +279,7 @@ ("large" 0 "") ("ldots" 0 "@dots{}") ("leftline" 1 "\\1") + ("leq" 0 "<=") ("lineii" 2 "@item \\1 @tab \\2") ("lineiii" 3 "@item \\1 @tab \\2 @tab \\3") ("lineiv" 4 "@item \\1 @tab \\2 @tab \\3 @tab \\4") @@ -353,6 +355,7 @@ (py2texi-backslash-quote (match-string 2 str))) "@node \\1\n at section \\1\n")))) ("sectionauthor" 2 "") + ("seelink" 3 "\n at table @url\n at item @strong{\\1}\n(\\2)\n\\3\n at end table\n") ("seemodule" 2 "@ref{\\1} \\2") ("seepep" 3 "\n at table @strong\n at item PEP\\1 \\2\n\\3\n at end table\n") ("seerfc" 3 "\n at table @strong\n at item RFC\\1 \\2\n\\3\n at end table\n") @@ -378,7 +381,15 @@ ("textasciitilde" 0 "~") ("textasciicircum" 0 "^") ("textbackslash" 0 "@backslash{}") + ("textbar" 0 "|") + ; Some common versions of Texinfo don't support @euro yet: + ; ("texteuro" 0 "@euro{}") + ; Unfortunately, this alternate spelling doesn't actually apply to + ; the usage found in Python Tutorial, which actually requires a + ; Euro symbol to make sense, so this is commented out as well. + ; ("texteuro" 0 "Euro ") ("textgreater" 0 ">") + ("textit" 1 "@i{\\1}") ("textless" 0 "<") ("textrm" 1 "\\1") ("texttt" 1 "@code{\\1}") From jhylton at users.sourceforge.net Sun Oct 16 07:24:31 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Sun, 16 Oct 2005 07:24:31 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Grammar Grammar, 1.47.2.3, 1.47.2.4 Message-ID: <20051016052431.E980A1E4014@bag.python.org> Update of /cvsroot/python/python/dist/src/Grammar In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27718/Grammar Modified Files: Tag: ast-branch Grammar Log Message: Merge head to branch (for the last time) Index: Grammar =================================================================== RCS file: /cvsroot/python/python/dist/src/Grammar/Grammar,v retrieving revision 1.47.2.3 retrieving revision 1.47.2.4 diff -u -d -r1.47.2.3 -r1.47.2.4 --- Grammar 15 Apr 2005 02:18:25 -0000 1.47.2.3 +++ Grammar 16 Oct 2005 05:23:58 -0000 1.47.2.4 @@ -39,7 +39,7 @@ stmt: simple_stmt | compound_stmt simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE small_stmt: expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | exec_stmt | assert_stmt -expr_stmt: testlist (augassign testlist | ('=' testlist)*) +expr_stmt: testlist (augassign (yield_expr|testlist) | ('=' (yield_expr|testlist))*) augassign: '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//=' # For normal assignments, additional restrictions enforced by the interpreter print_stmt: 'print' ( [ test (',' test)* [','] ] | '>>' test [ (',' test)+ [','] ] ) @@ -49,7 +49,7 @@ break_stmt: 'break' continue_stmt: 'continue' return_stmt: 'return' [testlist] -yield_stmt: 'yield' testlist +yield_stmt: yield_expr raise_stmt: 'raise' [test [',' test [',' test]]] import_stmt: import_name | import_from import_name: 'import' dotted_as_names @@ -86,7 +86,7 @@ term: factor (('*'|'/'|'%'|'//') factor)* factor: ('+'|'-'|'~') factor | power power: atom trailer* ['**' factor] -atom: '(' [testlist_gexp] ')' | '[' [listmaker] ']' | '{' [dictmaker] '}' | '`' testlist1 '`' | NAME | NUMBER | STRING+ +atom: '(' [yield_expr|testlist_gexp] ')' | '[' [listmaker] ']' | '{' [dictmaker] '}' | '`' testlist1 '`' | NAME | NUMBER | STRING+ listmaker: test ( list_for | (',' test)* [','] ) testlist_gexp: test ( gen_for | (',' test)* [','] ) lambdef: 'lambda' [varargslist] ':' test @@ -116,3 +116,6 @@ # not used in grammar, but may appear in "node" passed from Parser to Compiler encoding_decl: NAME + +yield_expr: 'yield' [testlist] + From jhylton at users.sourceforge.net Sun Oct 16 07:24:32 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Sun, 16 Oct 2005 07:24:32 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/texinputs underscore.sty, NONE, 1.1.2.2 howto.cls, 1.13.2.1, 1.13.2.2 manual.cls, 1.18.2.1, 1.18.2.2 python.sty, 1.96.2.2, 1.96.2.3 Message-ID: <20051016052432.404201E400D@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27718/Doc/texinputs Modified Files: Tag: ast-branch howto.cls manual.cls python.sty Added Files: Tag: ast-branch underscore.sty Log Message: Merge head to branch (for the last time) --- NEW FILE: underscore.sty --- % underscore.sty 12-Oct-2001 Donald Arseneau asnd at triumf.ca % Make the "_" character print as "\textunderscore" in text. % Copyright 1998,2001 Donald Arseneau; Distribute freely if unchanged. % Instructions follow after the definitions. \ProvidesPackage{underscore}[2001/10/12] \begingroup \catcode`\_=\active \gdef_{% \relax % No relax gives a small vulnerability in alignments \ifx\if at safe@actives\iftrue % must be outermost test! \string_% \else \ifx\protect\@typeset at protect \ifmmode \sb \else \BreakableUnderscore \fi \else \ifx\protect\@unexpandable at protect \noexpand_% \else \protect_% \fi\fi \fi} \endgroup % At begin: set catcode; fix \long \ttdefault so I can use it in comparisons; \AtBeginDocument{% {\immediate\write\@auxout{\catcode\number\string`\_ \string\active}}% \catcode\string`\_\string=\active \edef\ttdefault{\ttdefault}% } \newcommand{\BreakableUnderscore}{\leavevmode\nobreak\hskip\z at skip \ifx\f at family\ttdefault \string_\else \textunderscore\fi \usc at dischyph\nobreak\hskip\z at skip} \DeclareRobustCommand{\_}{% \ifmmode \nfss at text{\textunderscore}\else \BreakableUnderscore \fi} \let\usc at dischyph\@dischyph \DeclareOption{nohyphen}{\def\usc at dischyph{\discretionary{}{}{}}} \DeclareOption{strings}{\catcode`\_=\active} \ProcessOptions \ifnum\catcode`\_=\active\else \endinput \fi %%%%%%%% Redefine commands that use character strings %%%%%%%% \@ifundefined{UnderscoreCommands}{\let\UnderscoreCommands\@empty}{} \expandafter\def\expandafter\UnderscoreCommands\expandafter{% \UnderscoreCommands \do\include \do\includeonly \do\@input \do\@iinput \do\InputIfFileExists \do\ref \do\pageref \do\newlabel \do\bibitem \do\@bibitem \do\cite \do\nocite \do\bibcite } % Macro to redefine a macro to pre-process its string argument % with \protect -> \string. \def\do#1{% Avoid double processing if user includes command twice! \@ifundefined{US\string_\expandafter\@gobble\string#1}{% \edef\@tempb{\meaning#1}% Check if macro is just a protection shell... \def\@tempc{\protect}% \edef\@tempc{\meaning\@tempc\string#1\space\space}% \ifx\@tempb\@tempc % just a shell: hook into the protected inner command \expandafter\do \csname \expandafter\@gobble\string#1 \expandafter\endcsname \else % Check if macro takes an optional argument \def\@tempc{\@ifnextchar[}% \edef\@tempa{\def\noexpand\@tempa####1\meaning\@tempc}% \@tempa##2##3\@tempa{##2\relax}% \edef\@tempb{\meaning#1\meaning\@tempc}% \edef\@tempc{\noexpand\@tempd \csname US\string_\expandafter\@gobble\string#1\endcsname}% \if \expandafter\@tempa\@tempb \relax 12\@tempa % then no optional arg \@tempc #1\US at prot \else % There is optional arg \@tempc #1\US at protopt \fi \fi }{}} \def\@tempd#1#2#3{\let#1#2\def#2{#3#1}} \def\US at prot#1#2{\let\@@protect\protect \let\protect\string \edef\US at temp##1{##1{#2}}\restore at protect\US at temp#1} \def\US at protopt#1{\@ifnextchar[{\US at protarg#1}{\US at prot#1}} \def\US at protarg #1[#2]{\US at prot{{#1[#2]}}} \UnderscoreCommands \let\do\relax \let\@tempd\relax % un-do %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \endinput underscore.sty 12-Oct-2001 Donald Arseneau Features: ~~~~~~~~~ \_ prints an underscore so that the hyphenation of constituent words is not affected and hyphenation is permitted after the underscore. For example, "compound\_fracture" hyphenates as com- pound_- frac- ture. If you prefer the underscore to break without a hyphen (but still with the same rules for explicit hyphen-breaks) then use the [nohyphen] package option. A simple _ acts just like \_ in text mode, but makes a subscript in math mode: activation_energy $E_a$ Both forms use an underscore character if the font encoding contains one (e.g., "\usepackage[T1]{fontenc}" or typewriter fonts in any encoding), but they use a rule if the there is no proper character. Deficiencies: ~~~~~~~~~~~~~ The skips and penalties ruin any kerning with the underscore character (when a character is used). However, there doesn't seem to be much, if any, such kerning in the ec fonts, and there is never any kerning with a rule. You must avoid "_" in file names and in cite or ref tags, or you must use the babel package, with its active-character controls, or you must give the [strings] option, which attempts to redefine several commands (and may not work perfectly). Even without the [strings] option or babel, you can use occasional underscores like: "\include{file\string_name}". Option: [strings] ~~~~~~~~~~~~~~~~~ The default operation is quite simple and needs no customization; but you must avoid using "_" in any place where LaTeX uses an argument as a string of characters for some control function or as a name. These include the tags for \cite and \ref, file names for \input, \include, and \includegraphics, environment names, counter names, and placement parameters (like "[t]"). The problem with these contexts is that they are `moving arguments' but LaTeX does not `switch on' the \protect mechanism for them. If you need to use the underscore character in these places, the package option [strings] is provided to redefine commands taking a string argument so that the argument is protected (with \protect -> \string). The list of commands is given in "\UnderscoreCommands", with "\do" before each, covering \cite, \ref, \input, and their variants. Not included are many commands regarding font names, everything with counter names, environment names, page styles, and versions of \ref and \cite defined by external packages (e.g. \vref and \citeyear). You can add to the list of supported commands by defining \UnderscoreCommands before loading this package; e.g. \usepackage{chicago} \newcommand{\UnderscoreCommands}{% (\cite already done) \do\citeNP \do\citeA \do\citeANP \do\citeN \do\shortcite \do\shortciteNP \do\shortciteA \do\shortciteANP \do\shortciteN \do\citeyear \do\citeyearNP } \usepackage[strings]{underscore} Not all commands can be supported this way! Only commands that take a string argument *first* can be protected. One optional argument before the string argument is also permitted, as exemplified by \cite: both \cite{tags} and \cite[text]{tags} are allowed. A command like \@addtoreset which takes two counter names as arguments could not be protected by adding it to \UnderscoreCommands. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! When you use the [strings] option, you must load this package !! !! last (or nearly last). !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! There are two reasons: 1) The redefinitions done for protection must come after other packages define their customized versions of those commands. 2) The [strings] option requires the _ character to be activated immediately in order for the cite and ref tags to be read properly from the .aux file as plain strings, and this catcode setting might disrupt other packages. The babel package implements a protection mechanism for many commands, and will be a complete fix for most documents without the [strings] option. Many add-on packages are compatible with babel, so they will get the strings protection also. However, there are several commands that are not covered by babel, but can easily be supported by the [strings] and \UnderscoreCommands mechanism. Beware that using both [strings] and babel may lead to conflicts, but does appear to work (load babel last). Implementation Notes: ~~~~~~~~~~~~~~~~~~~~~ The first setting of "_" to be an active character is performed in a local group so as to not interfere with other packages. The catcode setting is repeated with \AtBeginDocument so the definition is in effect for the text. However, the catcode setting is repeated immediately when the [strings] option is detected. The definition of the active "_" is essentially: \ifmmode \sb \else \BreakableUnderscore \fi where "\sb" retains the normal subscript meaning of "_" and where "\BreakableUnderscore" is essentially "\_". The rest of the definition handles the "\protect"ion without causing \relax to be inserted before the character. \BreakableUnderscore uses "\nobreak\hskip\z at skip" to separate the underscore from surrounding words, thus allowing TeX to hyphenate them, but preventing free breaks around the underscore. Next, it checks the current font family, and uses the underscore character from tt fonts or otherwise \textunderscore (which is a character or rule depending on the font encoding). After the underscore, it inserts a discretionary hyphenation point as "\usc at dischyph", which is usually just "\-" except that it still works in the tabbing environment, although it will give "\discretionary{}{}{}" under the [nohyphen] option. After that, another piece of non-breaking interword glue is inserted. Ordinarily, the comparison "\ifx\f at family\ttdefault" will always fail because \ttdefault is `long' where \f at family is not (boooo hisss), but \ttdefault is redefined to be non-long by "\AtBeginDocument". The "\_" command is then defined to use "\BreakableUnderscore". If the [strings] option is not given, then that is all! Under the [strings] option, the list of special commands is processed to: - retain the original command as \US_command (\US_ref) - redefine the command as \US at prot\US_command for ordinary commands (\ref -> \US at prot\US_ref) or as \US at protopt\US_command when an optional argument is possible (\bibitem -> \US at protopt\US_bibitem). - self-protecting commands (\cite) retain their self-protection. Diagnosing the state of the pre-existing command is done by painful contortions involving \meaning. \US at prot and \US at protopt read the argument, process it with \protect enabled, then invoke the saved \US_command. Modifications: ~~~~~~~~~~~~~~ 12-Oct-2001 Babel (safe at actives) compatibility and [nohyphen] option. Test file integrity: ASCII 32-57, 58-126: !"#$%&'()*+,-./0123456789 :;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ Index: howto.cls =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/howto.cls,v retrieving revision 1.13.2.1 retrieving revision 1.13.2.2 diff -u -d -r1.13.2.1 -r1.13.2.2 --- howto.cls 7 Jan 2005 06:57:36 -0000 1.13.2.1 +++ howto.cls 16 Oct 2005 05:23:58 -0000 1.13.2.2 @@ -50,7 +50,8 @@ % \renewcommand{\maketitle}{ \py at doHorizontalRule - \@ifundefined{pdfinfo}{}{{ + \ifpdf + \begingroup % This \def is required to deal with multi-line authors; it % changes \\ to ', ' (comma-space), making it pass muster for % generating document info in the PDF file. @@ -59,7 +60,8 @@ /Author (\@author) /Title (\@title) } - }} + \endgroup + \fi \begin{flushright} {\rm\Huge\py at HeaderFamily \@title} \par {\em\large\py at HeaderFamily \py at release\releaseinfo} \par Index: manual.cls =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/manual.cls,v retrieving revision 1.18.2.1 retrieving revision 1.18.2.2 diff -u -d -r1.18.2.1 -r1.18.2.2 --- manual.cls 7 Jan 2005 06:57:36 -0000 1.18.2.1 +++ manual.cls 16 Oct 2005 05:23:58 -0000 1.18.2.2 @@ -64,7 +64,8 @@ \let\footnotesize\small \let\footnoterule\relax \py at doHorizontalRule% - \@ifundefined{pdfinfo}{}{{ + \ifpdf + \begingroup % This \def is required to deal with multi-line authors; it % changes \\ to ', ' (comma-space), making it pass muster for % generating document info in the PDF file. @@ -73,7 +74,8 @@ /Author (\@author) /Title (\@title) } - }} + \endgroup + \fi \begin{flushright}% {\rm\Huge\py at HeaderFamily \@title \par}% {\em\LARGE\py at HeaderFamily \py at release\releaseinfo \par} Index: python.sty =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/python.sty,v retrieving revision 1.96.2.2 retrieving revision 1.96.2.3 diff -u -d -r1.96.2.2 -r1.96.2.3 --- python.sty 7 Jan 2005 06:57:36 -0000 1.96.2.2 +++ python.sty 16 Oct 2005 05:23:58 -0000 1.96.2.3 @@ -7,6 +7,7 @@ [1998/01/11 LaTeX package (Python markup)] \RequirePackage{longtable} +\RequirePackage{underscore} % Uncomment these two lines to ignore the paper size and make the page % size more like a typical published manual. @@ -541,28 +542,6 @@ {\reset at font\normalsize\py at HeaderFamily}} -% This gets the underscores closer to the right width; the only change -% from standard LaTeX is the width specified. - -\DeclareTextCommandDefault{\textunderscore}{% - \leavevmode \kern.06em\vbox{\hrule\@width.55em}} - -% Underscore hack (only act like subscript operator if in math mode) -% -% The following is due to Mark Wooding (the old version didn't work with -% Latex 2e. - -\DeclareRobustCommand\hackscore{% - \ifmmode_\else\textunderscore\fi% -} -\begingroup -\catcode`\_\active -\def\next{% - \AtBeginDocument{\catcode`\_\active\def_{\hackscore{}}}% -} -\expandafter\endgroup\next - - % Now for a lot of semantically-loaded environments that do a ton of magical % things to get the right formatting and index entries for the stuff in % Python modules and C API. @@ -1202,7 +1181,7 @@ } \fi -% \seelink{url}{link text} +% \seelink{url}{link text}{why it's interesting} \newcommand{\py at seelink}[3]{% \par \begin{fulllineitems} From jhylton at users.sourceforge.net Sun Oct 16 07:24:32 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Sun, 16 Oct 2005 07:24:32 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/ref ref1.tex, 1.14, 1.14.8.1 ref2.tex, 1.37.2.2, 1.37.2.3 ref3.tex, 1.92.2.2, 1.92.2.3 ref4.tex, 1.33.2.2, 1.33.2.3 ref5.tex, 1.64.2.2, 1.64.2.3 ref6.tex, 1.55.2.2, 1.55.2.3 ref7.tex, 1.34.2.2, 1.34.2.3 Message-ID: <20051016052432.812151E400E@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/ref In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27718/Doc/ref Modified Files: Tag: ast-branch ref1.tex ref2.tex ref3.tex ref4.tex ref5.tex ref6.tex ref7.tex Log Message: Merge head to branch (for the last time) Index: ref1.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref1.tex,v retrieving revision 1.14 retrieving revision 1.14.8.1 diff -u -d -r1.14 -r1.14.8.1 --- ref1.tex 28 Nov 2001 07:26:15 -0000 1.14 +++ ref1.tex 16 Oct 2005 05:23:58 -0000 1.14.8.1 @@ -21,7 +21,7 @@ reference document --- the implementation may change, and other implementations of the same language may work differently. On the other hand, there is currently only one Python implementation in -widespread use (although a second one now exists!), and +widespread use (although alternate implementations exist), and its particular quirks are sometimes worth being mentioned, especially where the implementation imposes additional limitations. Therefore, you'll find short ``implementation notes'' sprinkled throughout the @@ -34,6 +34,56 @@ with the language definition. +\section{Alternate Implementations\label{implementations}} + +Though there is one Python implementation which is by far the most +popular, there are some alternate implementations which are of +particular interest to different audiences. + +Known implementations include: + +\begin{itemize} +\item[CPython] +This is the original and most-maintained implementation of Python, +written in C. New language features generally appear here first. + +\item[Jython] +Python implemented in Java. This implementation can be used as a +scripting language for Java applications, or can be used to create +applications using the Java class libraries. It is also often used to +create tests for Java libraries. More information can be found at +\ulink{the Jython website}{http://www.jython.org/}. + +\item[Python for .NET] +This implementation actually uses the CPython implementation, but is a +managed .NET application and makes .NET libraries available. This was +created by Brian Lloyd. For more information, see the \ulink{Python +for .NET home page}{http://www.zope.org/Members/Brian/PythonNet}. + +\item[IronPython] +An alternate Python for\ .NET. Unlike Python.NET, this is a complete +Python implementation that generates IL, and compiles Python code +directly to\ .NET assemblies. It was created by Jim Hugunin, the +original creator of Jython. For more information, see \ulink{the +IronPython website}{http://workspaces.gotdotnet.com/ironpython}. + +\item[PyPy] +An implementation of Python written in Python; even the bytecode +interpreter is written in Python. This is executed using CPython as +the underlying interpreter. One of the goals of the project is to +encourage experimentation with the language itself by making it easier +to modify the interpreter (since it is written in Python). Additional +information is available on \ulink{the PyPy project's home +page}{http://codespeak.net/pypy/}. +\end{itemize} + +Each of these implementations varies in some way from the language as +documented in this manual, or introduces specific information beyond +what's covered in the standard Python documentation. Please refer to +the implementation-specific documentation to determine what else you +need to know about the specific implementation you're using. + + \section{Notation\label{notation}} The descriptions of lexical analysis and syntax use a modified BNF @@ -43,10 +93,10 @@ \index{syntax} \index{notation} -\begin{verbatim} -name: lc_letter (lc_letter | "_")* -lc_letter: "a"..."z" -\end{verbatim} +\begin{productionlist} + \production{name}{\token{lc_letter} (\token{lc_letter} | "_")*} + \production{lc_letter}{"a"..."z"} +\end{productionlist} The first line says that a \code{name} is an \code{lc_letter} followed by a sequence of zero or more \code{lc_letter}s and underscores. An @@ -55,7 +105,7 @@ names defined in lexical and grammar rules in this document.) Each rule begins with a name (which is the name defined by the rule) -and a colon. A vertical bar (\code{|}) is used to separate +and \code{::=}. A vertical bar (\code{|}) is used to separate alternatives; it is the least binding operator in this notation. A star (\code{*}) means zero or more repetitions of the preceding item; likewise, a plus (\code{+}) means one or more repetitions, and a Index: ref2.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref2.tex,v retrieving revision 1.37.2.2 retrieving revision 1.37.2.3 diff -u -d -r1.37.2.2 -r1.37.2.3 --- ref2.tex 7 Jan 2005 06:57:33 -0000 1.37.2.2 +++ ref2.tex 16 Oct 2005 05:23:58 -0000 1.37.2.3 @@ -54,11 +54,18 @@ \subsection{Physical lines\label{physical}} -A physical line ends in whatever the current platform's convention is -for terminating lines. On \UNIX, this is the \ASCII{} LF (linefeed) -character. On Windows, it is the \ASCII{} sequence CR LF (return -followed by linefeed). On Macintosh, it is the \ASCII{} CR (return) -character. +A physical line is a sequence of characters terminated by an end-of-line +sequence. In source files, any of the standard platform line +termination sequences can be used - the \UNIX form using \ASCII{} LF +(linefeed), the Windows form using the \ASCII{} sequence CR LF (return +followed by linefeed), or the Macintosh form using the \ASCII{} CR +(return) character. All of these forms can be used equally, regardless +of platform. + +When embedding Python, source code strings should be passed to Python +APIs using the standard C conventions for newline characters (the +\code{\e n} character, representing \ASCII{} LF, is the line +terminator). \subsection{Comments\label{comments}} @@ -342,7 +349,7 @@ \item[\code{__*__}] System-defined names. These names are defined by the interpreter - and it's implementation (including the standard library); + and its implementation (including the standard library); applications should not expect to define additional names using this convention. The set of names of this class defined by Python may be extended in future versions. Index: ref3.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref3.tex,v retrieving revision 1.92.2.2 retrieving revision 1.92.2.3 diff -u -d -r1.92.2.2 -r1.92.2.3 --- ref3.tex 7 Jan 2005 06:57:33 -0000 1.92.2.2 +++ ref3.tex 16 Oct 2005 05:23:58 -0000 1.92.2.3 @@ -165,7 +165,8 @@ \begin{description} \item[Integers] -These represent elements from the mathematical set of whole numbers. +These represent elements from the mathematical set of integers +(positive and negative). \obindex{integer} There are three types of integers: @@ -325,7 +326,7 @@ \function{ord()}\bifuncindex{ord} convert between code units and nonnegative integers representing the Unicode ordinals as defined in the Unicode Standard 3.0. Conversion from and to other encodings are -possible through the Unicode method \method{encode} and the built-in +possible through the Unicode method \method{encode()} and the built-in function \function{unicode()}.\bifuncindex{unicode} \obindex{unicode} \index{character} @@ -450,7 +451,7 @@ \lineiii{__module__}{The name of the module the function was defined in, or \code{None} if unavailable.}{Writable} - \lineiii{func_defaults}{Atuple containing default argument values + \lineiii{func_defaults}{A tuple containing default argument values for those arguments that have defaults, or \code{None} if no arguments have a default value}{Writable} @@ -604,7 +605,7 @@ have reached the end of the set of values to be returned. \item[Built-in functions] -A built-in function object is a wrapper around a \C{} function. Examples +A built-in function object is a wrapper around a C function. Examples of built-in functions are \function{len()} and \function{math.sin()} (\module{math} is a standard built-in module). The number and type of the arguments are @@ -917,14 +918,16 @@ \ttindex{f_builtins} \ttindex{f_restricted}} -Special writable attributes: \member{f_trace}, if not \code{None}, is a -function called at the start of each source code line (this is used by -the debugger); \member{f_exc_type}, \member{f_exc_value}, -\member{f_exc_traceback} represent the most recent exception caught in -this frame; \member{f_lineno} is the current line number of the frame ---- writing to this from within a trace function jumps to the given line -(only for the bottom-most frame). A debugger can implement a Jump -command (aka Set Next Statement) by writing to f_lineno. +Special writable attributes: \member{f_trace}, if not \code{None}, is +a function called at the start of each source code line (this is used +by the debugger); \member{f_exc_type}, \member{f_exc_value}, +\member{f_exc_traceback} represent the last exception raised in the +parent frame provided another exception was ever raised in the current +frame (in all other cases they are None); \member{f_lineno} is the +current line number of the frame --- writing to this from within a +trace function jumps to the given line (only for the bottom-most +frame). A debugger can implement a Jump command (aka Set Next +Statement) by writing to f_lineno. \withsubitem{(frame attribute)}{ \ttindex{f_trace} \ttindex{f_exc_type} @@ -1052,6 +1055,35 @@ \subsection{Basic customization\label{customization}} +\begin{methoddesc}[object]{__new__}{cls\optional{, \moreargs}} +Called to create a new instance of class \var{cls}. \method{__new__()} +is a static method (special-cased so you need not declare it as such) +that takes the class of which an instance was requested as its first +argument. The remaining arguments are those passed to the object +constructor expression (the call to the class). The return value of +\method{__new__()} should be the new object instance (usually an +instance of \var{cls}). + +Typical implementations create a new instance of the class by invoking +the superclass's \method{__new__()} method using +\samp{super(\var{currentclass}, \var{cls}).__new__(\var{cls}[, ...])} +with appropriate arguments and then modifying the newly-created instance +as necessary before returning it. + +If \method{__new__()} returns an instance of \var{cls}, then the new +instance's \method{__init__()} method will be invoked like +\samp{__init__(\var{self}[, ...])}, where \var{self} is the new instance +and the remaining arguments are the same as were passed to +\method{__new__()}. + +If \method{__new__()} does not return an instance of \var{cls}, then the +new instance's \method{__init__()} method will not be invoked. + +\method{__new__()} is intended mainly to allow subclasses of +immutable types (like int, str, or tuple) to customize instance +creation. +\end{methoddesc} + \begin{methoddesc}[object]{__init__}{self\optional{, \moreargs}} Called\indexii{class}{constructor} when the instance is created. The arguments are those passed to the class constructor expression. If a @@ -1176,8 +1208,8 @@ There are no implied relationships among the comparison operators. The truth of \code{\var{x}==\var{y}} does not imply that \code{\var{x}!=\var{y}} -is false. Accordingly, when defining \method{__eq__}, one should also -define \method{__ne__} so that the operators will behave as expected. +is false. Accordingly, when defining \method{__eq__()}, one should also +define \method{__ne__()} so that the operators will behave as expected. There are no reflected (swapped-argument) versions of these methods (to be used when the left argument does not support the operation but @@ -1306,8 +1338,9 @@ \begin{methoddesc}[object]{__getattribute__}{self, name} Called unconditionally to implement attribute accesses for instances -of the class. If the class also defines \method{__getattr__}, it will -never be called (unless called explicitly). +of the class. If the class also defines \method{__getattr__()}, the latter +will not be called unless \method{__getattribute__()} either calls it +explicitly or raises an \exception{AttributeError}. This method should return the (computed) attribute value or raise an \exception{AttributeError} exception. In order to avoid infinite recursion in this method, its @@ -1626,6 +1659,8 @@ raised; if of a value outside the set of indexes for the sequence (after any special interpretation of negative values), \exception{IndexError} should be raised. +For mapping types, if \var{key} is missing (not in the container), +\exception{KeyError} should be raised. \note{\keyword{for} loops expect that an \exception{IndexError} will be raised for illegal indexes to allow proper detection of the end of the sequence.} @@ -1870,7 +1905,7 @@ \var{x}\code{+=}\var{y}, where \var{x} is an instance of a class that has an \method{__iadd__()} method, \code{\var{x}.__iadd__(\var{y})} is called. If \var{x} is an instance of a class that does not define a -\method{__iadd()} method, \code{\var{x}.__add__(\var{y})} and +\method{__iadd__()} method, \code{\var{x}.__add__(\var{y})} and \code{\var{y}.__radd__(\var{x})} are considered, as with the evaluation of \var{x}\code{+}\var{y}. \end{methoddesc} @@ -1953,10 +1988,10 @@ Below, \method{__op__()} and \method{__rop__()} are used to signify the generic method names corresponding to an operator; -\method{__iop__} is used for the corresponding in-place operator. For +\method{__iop__()} is used for the corresponding in-place operator. For example, for the operator `\code{+}', \method{__add__()} and \method{__radd__()} are used for the left and right variant of the -binary operator, and \method{__iadd__} for the in-place variant. +binary operator, and \method{__iadd__()} for the in-place variant. \item Index: ref4.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref4.tex,v retrieving revision 1.33.2.2 retrieving revision 1.33.2.3 diff -u -d -r1.33.2.2 -r1.33.2.3 --- ref4.tex 7 Jan 2005 06:57:34 -0000 1.33.2.2 +++ ref4.tex 16 Oct 2005 05:23:58 -0000 1.33.2.3 @@ -182,16 +182,20 @@ \exception{SystemExit}\withsubitem{(built-in exception)}{\ttindex{SystemExit}}. -Exceptions are identified by class instances. -Selection of a matching except clause is based on object identity. -The \keyword{except} clause must reference the same class or a base -class of it. +Exceptions are identified by class instances. The \keyword{except} +clause is selected depending on the class of the instance: it must +reference the class of the instance or a base class thereof. The +instance can be received by the handler and can carry additional +information about the exceptional condition. -When an exception is raised, an object (maybe \code{None}) is passed -as the exception's \emph{value}; this object does not affect the -selection of an exception handler, but is passed to the selected -exception handler as additional information. For class exceptions, -this object must be an instance of the exception class being raised. +Exceptions can also be identified by strings, in which case the +\keyword{except} clause is selected by object identity. An arbitrary +value can be raised along with the identifying string which can be +passed to the handler. + +\deprecated{2.5}{String exceptions should not be used in new code. +They will not be supported in a future version of Python. Old code +should be rewritten to use class exceptions instead.} \begin{notice}[warning] Messages to exceptions are not part of the Python API. Their contents may Index: ref5.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref5.tex,v retrieving revision 1.64.2.2 retrieving revision 1.64.2.3 diff -u -d -r1.64.2.2 -r1.64.2.3 --- ref5.tex 7 Jan 2005 06:57:34 -0000 1.64.2.2 +++ ref5.tex 16 Oct 2005 05:23:58 -0000 1.64.2.3 @@ -960,7 +960,7 @@ object is a member of a set if the set is a sequence and contains an element equal to that object. However, it is possible for an object to support membership tests without being a sequence. In particular, -dictionaries support memership testing as a nicer way of spelling +dictionaries support membership testing as a nicer way of spelling \code{\var{key} in \var{dict}}; other mapping types may follow suit. For the list and tuple types, \code{\var{x} in \var{y}} is true if and @@ -1021,9 +1021,9 @@ In the context of Boolean operations, and also when expressions are used by control flow statements, the following values are interpreted -as false: \code{None}, numeric zero of all types, empty sequences -(strings, tuples and lists), and empty mappings (dictionaries). All -other values are interpreted as true. +as false: \code{False}, \code{None}, numeric zero of all types, and empty +strings and containers (including strings, tuples, lists, dictionaries, +sets and frozensets). All other values are interpreted as true. The operator \keyword{not} yields \code{True} if its argument is false, \code{False} otherwise. Index: ref6.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref6.tex,v retrieving revision 1.55.2.2 retrieving revision 1.55.2.3 diff -u -d -r1.55.2.2 -r1.55.2.3 --- ref6.tex 7 Jan 2005 06:57:34 -0000 1.55.2.2 +++ ref6.tex 16 Oct 2005 05:23:58 -0000 1.55.2.3 @@ -204,12 +204,12 @@ \item If the target is a subscription: The primary expression in the reference is evaluated. It should yield either a mutable sequence -object (e.g., a list) or a mapping object (e.g., a dictionary). Next, +object (such as a list) or a mapping object (such as a dictionary). Next, the subscript expression is evaluated. \indexii{subscription}{assignment} \obindex{mutable} -If the primary is a mutable sequence object (e.g., a list), the subscript +If the primary is a mutable sequence object (such as a list), the subscript must yield a plain integer. If it is negative, the sequence's length is added to it. The resulting value must be a nonnegative integer less than the sequence's length, and the sequence is asked to assign @@ -219,7 +219,7 @@ \obindex{sequence} \obindex{list} -If the primary is a mapping object (e.g., a dictionary), the subscript must +If the primary is a mapping object (such as a dictionary), the subscript must have a type compatible with the mapping's key type, and the mapping is then asked to create a key/datum pair which maps the subscript to the assigned object. This can either replace an existing key/value @@ -230,7 +230,7 @@ \item If the target is a slicing: The primary expression in the reference is -evaluated. It should yield a mutable sequence object (e.g., a list). The +evaluated. It should yield a mutable sequence object (such as a list). The assigned object should be a sequence object of the same type. Next, the lower and upper bound expressions are evaluated, insofar they are present; defaults are zero and the sequence's length. The bounds @@ -251,7 +251,7 @@ messages.) WARNING: Although the definition of assignment implies that overlaps -between the left-hand side and the right-hand side are `safe' (e.g., +between the left-hand side and the right-hand side are `safe' (for example \samp{a, b = b, a} swaps two variables), overlaps \emph{within} the collection of assigned-to variables are not safe! For instance, the following program prints \samp{[0, 2]}: @@ -523,8 +523,10 @@ \end{productionlist} If no expressions are present, \keyword{raise} re-raises the last -expression that was active in the current scope. If no exception is -active in the current scope, an exception is raised indicating this error. +exception that was active in the current scope. If no exception is +active in the current scope, a \exception{TypeError} exception is +raised indicating that this is an error (if running under IDLE, a +\exception{Queue.Empty} exception is raised instead). \index{exception} \indexii{raising}{exception} @@ -601,7 +603,7 @@ \keyword{continue} may only occur syntactically nested in a \keyword{for} or \keyword{while} loop, but not nested in a function or class definition or -\keyword{try} statement within that loop.\footnote{It may +\keyword{finally} statement within that loop.\footnote{It may occur within an \keyword{except} or \keyword{else} clause. The restriction on occurring in the \keyword{try} clause is implementor's laziness and will eventually be lifted.} @@ -872,7 +874,12 @@ a code object. If it is a string, the string is parsed as a suite of Python statements which is then executed (unless a syntax error occurs). If it is an open file, the file is parsed until \EOF{} and -executed. If it is a code object, it is simply executed. +executed. If it is a code object, it is simply executed. In all +cases, the code that's executed is expected to be be valid as file +input (see section~\ref{file-input}, ``File input''). Be aware that +the \keyword{return} and \keyword{yield} statements may not be used +outside of function definitions even within the context of code passed +to the \keyword{exec} statement. In all cases, if the optional parts are omitted, the code is executed in the current scope. If only the first expression after \keyword{in} Index: ref7.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref7.tex,v retrieving revision 1.34.2.2 retrieving revision 1.34.2.3 diff -u -d -r1.34.2.2 -r1.34.2.3 --- ref7.tex 7 Jan 2005 06:57:34 -0000 1.34.2.2 +++ ref7.tex 16 Oct 2005 05:23:58 -0000 1.34.2.3 @@ -223,11 +223,11 @@ except clause with an expression, that expression is evaluated, and the clause matches the exception if the resulting object is ``compatible'' with the exception. An object is compatible with an exception if it -is either the object that identifies the exception, or (for exceptions -that are classes) it is a base class of the exception, or it is a -tuple containing an item that is compatible with the exception. Note -that the object identities must match, i.e. it must be the same -object, not just an object with the same value. +is the class or a base class of the exception object, a tuple +containing an item compatible with the exception, or, in the +(deprecated) case of string exceptions, is the raised string itself +(note that the object identities must match, i.e. it must be the same +string object, not just a string with the same value). \kwindex{except} If no except clause matches the exception, the search for an exception @@ -239,14 +239,14 @@ on the call stack (it is treated as if the entire \keyword{try} statement raised the exception). -When a matching except clause is found, the exception's parameter is -assigned to the target specified in that except clause, if present, -and the except clause's suite is executed. All except clauses must -have an executable block. When the end of this block -is reached, execution continues normally after the entire try -statement. (This means that if two nested handlers exist for the same -exception, and the exception occurs in the try clause of the inner -handler, the outer handler will not handle the exception.) +When a matching except clause is found, the exception is assigned to +the target specified in that except clause, if present, and the except +clause's suite is executed. All except clauses must have an +executable block. When the end of this block is reached, execution +continues normally after the entire try statement. (This means that +if two nested handlers exist for the same exception, and the exception +occurs in the try clause of the inner handler, the outer handler will +not handle the exception.) Before an except clause's suite is executed, details about the exception are assigned to three variables in the @@ -323,6 +323,8 @@ {\token{decorator}+} \production{decorator} {"@" \token{dotted_name} ["(" [\token{argument_list} [","]] ")"] NEWLINE} + \production{dotted_name} + {\token{identifier} ("." \token{identifier})*} \production{parameter_list} {(\token{defparameter} ",")*} \productioncont{(~~"*" \token{identifier} [, "**" \token{identifier}]} @@ -439,7 +441,7 @@ {"class" \token{classname} [\token{inheritance}] ":" \token{suite}} \production{inheritance} - {"(" \token{expression_list} ")"} + {"(" [\token{expression_list}] ")"} \production{classname} {\token{identifier}} \end{productionlist} From jhylton at users.sourceforge.net Sun Oct 16 07:24:32 2005 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Sun, 16 Oct 2005 07:24:32 +0200 (CEST) Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew24.tex, 1.127.2.1, 1.127.2.2 whatsnew25.tex, 1.4.2.1, 1.4.2.2 Message-ID: <20051016052432.9BCE61E400A@bag.python.org> Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27718/Doc/whatsnew Modified Files: Tag: ast-branch whatsnew24.tex whatsnew25.tex Log Message: Merge head to branch (for the last time) Index: whatsnew24.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew24.tex,v retrieving revision 1.127.2.1 retrieving revision 1.127.2.2 diff -u -d -r1.127.2.1 -r1.127.2.2 --- whatsnew24.tex 7 Jan 2005 06:57:40 -0000 1.127.2.1 +++ whatsnew24.tex 16 Oct 2005 05:23:58 -0000 1.127.2.2 @@ -18,8 +18,8 @@ \maketitle \tableofcontents -This article explains the new features in Python 2.4, released on -November~30, 2004. +This article explains the new features in Python 2.4.1, released on +March~30, 2005. Python 2.4 is a medium-sized release. It doesn't introduce as many changes as the radical Python 2.2, but introduces more features than @@ -379,9 +379,11 @@ by Kevin D. Smith, Jim Jewett, and Skip Montanaro. Several people wrote patches implementing function decorators, but the one that was actually checked in was patch \#979728, written by Mark Russell.} -\end{seealso} -% XXX add link to decorators module in Wiki +\seeurl{http://www.python.org/moin/PythonDecoratorLibrary} +{This Wiki page contains several examples of decorators.} + +\end{seealso} %====================================================================== @@ -1039,7 +1041,7 @@ \item The inner loops for list and tuple slicing were optimized and now run about one-third faster. The inner loops - for dictionaries were also optimized , resulting in performance boosts for + for dictionaries were also optimized, resulting in performance boosts for \method{keys()}, \method{values()}, \method{items()}, \method{iterkeys()}, \method{itervalues()}, and \method{iteritems()}. (Contributed by Raymond Hettinger.) @@ -1426,6 +1428,12 @@ Python 2.4's regular expression engine can match this pattern without problems. +\item The \module{signal} module now performs tighter error-checking +on the parameters to the \function{signal.signal()} function. For +example, you can't set a handler on the \constant{SIGKILL} signal; +previous versions of Python would quietly accept this, but 2.4 will +raise a \exception{RuntimeError} exception. + \item Two new functions were added to the \module{socket} module. \function{socketpair()} returns a pair of connected sockets and \function{getservbyport(\var{port})} looks up the service name for a @@ -1705,6 +1713,11 @@ now return an empty list instead of raising a \exception{TypeError} exception if called with no arguments. +\item You can no longer compare the \class{date} and \class{datetime} + instances provided by the \module{datetime} module. Two + instances of different classes will now always be unequal, and + relative comparisons (\code{<}, \code{>}) will raise a \exception{TypeError}. + \item \function{dircache.listdir()} now passes exceptions to the caller instead of returning empty lists. @@ -1724,8 +1737,10 @@ \item \constant{None} is now a constant; code that binds a new value to the name \samp{None} is now a syntax error. -% signal module now raises a RuntimeError on insane calls - e.g. setting a -% handler on SIGKILL +\item The \function{signals.signal()} function now raises a +\exception{RuntimeError} exception for certain illegal values; +previously these errors would pass silently. For example, you can no +longer set a handler on the \constant{SIGKILL} signal. \end{itemize} @@ -1735,7 +1750,8 @@ The author would like to thank the following people for offering suggestions, corrections and assistance with various drafts of this -article: Koray Can, Hye-Shik Chang, Michael Dyck, Raymond Hettinger, -Brian Hurt, Hamish Lawson, Fredrik Lundh, Sean Reifschneider. +article: Koray Can, Hye-Shik Chang, Michael Dyck, Raymond Hettinger, +Brian Hurt, Hamish Lawson, Fredrik Lundh, Sean Reifschneider, +Sadruddin Rejeb. \end{document} Index: whatsnew25.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew25.tex,v retrieving revision 1.4.2.1 retrieving revision 1.4.2.2 diff -u -d -r1.4.2.1 -r1.4.2.2 --- whatsnew25.tex 7 Jan 2005 06:57:41 -0000 1.4.2.1 +++ whatsnew25.tex 16 Oct 2005 05:23:58 -0000 1.4.2.2 @@ -1,5 +1,6 @@ \documentclass{howto} \usepackage{distutils} + % $Id$ @@ -26,8 +27,229 @@ %====================================================================== +\section{PEP 309: Partial Function Application} -% Large, PEP-level features and changes should be described here. +The \module{functional} module is intended to contain tools for +functional-style programming. Currently it only contains +\class{partial}, but new functions will probably be added in future +versions of Python. + +For programs written in a functional style, it can be useful to +construct variants of existing functions that have some of the +parameters filled in. Consider a Python function \code{f(a, b, c)}; +you could create a new function \code{g(b, c)} that was equivalent to +\code{f(1, b, c)}. This is called ``partial function application'', +and is provided by the \class{partial} class in the new +\module{functional} module. + +The constructor for \class{partial} takes the arguments +\code{(\var{function}, \var{arg1}, \var{arg2}, ... +\var{kwarg1}=\var{value1}, \var{kwarg2}=\var{value2})}. The resulting +object is callable, so you can just call it to invoke \var{function} +with the filled-in arguments. + +Here's a small but realistic example: + +\begin{verbatim} +import functional + +def log (message, subsystem): + "Write the contents of 'message' to the specified subsystem." + print '%s: %s' % (subsystem, message) + ... + +server_log = functional.partial(log, subsystem='server') +\end{verbatim} + +Here's another example, from a program that uses PyGTk. Here a +context-sensitive pop-up menu is being constructed dynamically. The +callback provided for the menu option is a partially applied version +of the \method{open_item()} method, where the first argument has been +provided. + +\begin{verbatim} +... +class Application: + def open_item(self, path): + ... + def init (self): + open_func = functional.partial(self.open_item, item_path) + popup_menu.append( ("Open", open_func, 1) ) +\end{verbatim} + + +\begin{seealso} + +\seepep{309}{Partial Function Application}{PEP proposed and written by +Peter Harris; implemented by Hye-Shik Chang, with adaptations by +Raymond Hettinger.} + +\end{seealso} + + +%====================================================================== +\section{PEP 314: Metadata for Python Software Packages v1.1} + +Some simple dependency support was added to Distutils. The +\function{setup()} function now has \code{requires},\code{provides}, +and \code{obsoletes}. When you build a source distribution using the +\code{sdist} command, the dependency information will be recorded in +the \file{PKG-INFO} file. + +Another new keyword is \code{download_url}, which should be set to a +URL for the package's source code. This means it's now possible to +look up an entry in the package index, determine the dependencies for +a package, and download the required packages. + +% XXX put example here + +\begin{seealso} + +\seepep{314}{Metadata for Python Software Packages v1.1}{PEP proposed +and written by A.M. Kuchling, Richard Jones, and Fred Drake; +implemented by Richard Jones and Fred Drake.} + +\end{seealso} + + +%====================================================================== +\section{PEP 342: New Generator Features} + +As introduced in Python 2.3, generators only produce output; once a +generator's code was invoked to create an iterator, there's no way to +pass new parameters into the function when its execution is resumed. +Hackish solutions to this include making the generator's code look at +a global variable and then changing the global variable's value, or +passing in some mutable object that callers then modify. Python +2.5 adds the ability to pass values \emph{into} a generator. + +To refresh your memory of basic generators, here's a simple example: + +\begin{verbatim} +def counter (maximum): + i = 0 + while i < maximum: + yield i + i += 1 +\end{verbatim} + +When you call \code{counter(10)}, the result is an iterator that +returns the values from 0 up to 9. On encountering the +\keyword{yield} statement, the iterator returns the provided value and +suspends the function's execution, preserving the local variables. +Execution resumes on the following call to the iterator's +\method{next()} method, picking up after the \keyword{yield}. + +In Python 2.3, \keyword{yield} was a statement; it didn't return any +value. In 2.5, \keyword{yield} is now an expression, returning a +value that can be assigned to a variable or otherwise operated on: + +\begin{verbatim} +val = (yield i) +\end{verbatim} + +I recommend that you always put parentheses around a \keyword{yield} +expression when you're doing something with the returned value, as in +the above example. The parentheses aren't always necessary, but it's +easier to always add them instead of having to remember when they're +needed. The exact rules are that a \keyword{yield}-expression must +always be parenthesized except when it occurs at the top-level +expression on the right-hand side of an assignment, meaning +you can to write \code{val = yield i} but \code{val = (yield i) + 12}. + +Values are sent into a generator by calling its +\method{send(\var{value})} method. The generator's code is then +resumed and the \keyword{yield} expression produces \var{value}. +If the regular \method{next()} method is called, the \keyword{yield} +returns \constant{None}. + +Here's the previous example, modified to allow changing the value of +the internal counter. + +\begin{verbatim} +def counter (maximum): + i = 0 + while i < maximum: + val = (yield i) + # If value provided, change counter + if val is not None: + i = val + else: + i += 1 +\end{verbatim} + +And here's an example of changing the counter: + +\begin{verbatim} +>>> it = counter(10) +>>> print it.next() +0 +>>> print it.next() +1 +>>> print it.send(8) +8 +>>> print it.next() +9 +>>> print it.next() +Traceback (most recent call last): + File ``t.py'', line 15, in ? + print it.next() +StopIteration +\end{verbatim} + +Because \keyword{yield} will often be returning \constant{None}, +you shouldn't just use its value in expressions unless you're sure +that only the \method{send()} method will be used. + +There are two other new methods on generators in addition to +\method{send()}: + +\begin{itemize} + + \item \method{throw(\var{type}, \var{value}=None, + \var{traceback}=None)} is used to raise an exception inside the + generator; the exception is raised by the \keyword{yield} expression + where the generator's execution is paused. + + \item \method{close()} raises a new \exception{GeneratorExit} + exception inside the generator to terminate the iteration. + On receiving this + exception, the generator's code must either raise + \exception{GeneratorExit} or \exception{StopIteration}; catching the + exception and doing anything else is illegal and will trigger + a \exception{RuntimeError}. \method{close()} will also be called by + Python's garbage collection when the generator is garbage-collected. + + If you need to run cleanup code in case of a \exception{GeneratorExit}, + I suggest using a \code{try: ... finally:} suite instead of + catching \exception{GeneratorExit}. + +\end{itemize} + +The cumulative effect of these changes is to turn generators from +one-way producers of information into both producers and consumers. +Generators also become \emph{coroutines}, a more generalized form of +subroutines; subroutines are entered at one point and exited at +another point (the top of the function, and a \keyword{return +statement}), but coroutines can be entered, exited, and resumed at +many different points (the \keyword{yield} statements).science term + + +\begin{seealso} + +\seepep{342}{Coroutines via Enhanced Generators}{PEP written by +Guido van Rossum and Phillip J. Eby; +implemented by Phillip J. Eby. Includes examples of +some fancier uses of generators as coroutines.} + +\seeurl{http://en.wikipedia.org/wiki/Coroutine}{The Wikipedia entry for +coroutines.} + +\seeurl{http://www.sidhe.org/~dan/blog/archives/000178.html}{An +explanation of coroutines from a Perl point of view, written by Dan +Sugalski.} + +\end{seealso} %====================================================================== @@ -40,7 +262,7 @@ \item The \function{min()} and \function{max()} built-in functions gained a \code{key} keyword argument analogous to the \code{key} -argument for \function{sort()}. This argument supplies a function +argument for \method{sort()}. This argument supplies a function that takes a single argument and is